One paste-able URL onboards any agent: INSTALL_FOR_AGENTS.md (#57)

This commit is contained in:
Snow W. Lee (Sungwon)
2026-07-27 20:23:42 +09:00
committed by GitHub
parent 7768f1cf51
commit 65d4df5a84
13 changed files with 294 additions and 325 deletions
+1
View File
@@ -84,4 +84,5 @@ Every PR body starts with a `## TL;DR` section: at most 5 bullet points, one sho
## Docs to keep in sync
- `README.md` and `plugin/skills/beardrive/SKILL.md` both document CLI behavior, flags, output formats, and the on-disk layout. When changing CLI commands, flags, output, or layout, update both — the skill is what makes Claude Code beardrive-aware for end users and must match the actual binary.
- `INSTALL_FOR_AGENTS.md` (repo root) is the URL-addressable agent onboarding runbook — the canonical two-line paste prompt (README, docs, SKILL.md, `plugin/commands/install.md`, and the hub's `ConnectGuide.tsx` all point at its raw URL) tells any agent to fetch and follow it. It condenses `plugin/commands/install.md`; when that flow or the CLI steps it names change, update it too.
- `web/docs/src/content/docs/` is the third surface: it restates the same CLI reference, hub config, and self-hosting knobs for end users. A CLI or config change lands there too — `reference/cli.md`, `reference/hub-config.md`, `reference/project-files.md`, and the `self-hosting/` pages are the ones that go stale.
+139
View File
@@ -0,0 +1,139 @@
# BearDrive — install instructions for AI agents
You are an AI agent (Claude Code, Codex, Gemini CLI, Hermes, or similar) and
your user asked you to set up BearDrive by following this document. Work
through the steps in order, telling the user what you're doing at each one.
Steps marked **ask first** require the user's explicit answer — do not guess
or skip them.
BearDrive syncs a folder across a team and their agents through a hub, with
per-file history and share links. Setting it up means: install the CLI, sign
in, pick what to sync, and register turn-boundary sync hooks for your
platform. Full documentation: https://docs.beardrive.ai (agent-readable
index at https://docs.beardrive.ai/llms.txt).
> Maintainers: this is a condensed, URL-addressable version of
> `plugin/commands/install.md` — that file is the source of truth. If the
> two disagree, update this one.
## 1. Install the CLI
Check `command -v bdrive`. If missing:
```sh
brew install runbear-io/tap/beardrive # macOS / Linuxbrew
```
No Homebrew? Grab the release binary for this OS/arch from
https://github.com/runbear-io/beardrive/releases, or with a Go toolchain:
`go install github.com/runbear-io/beardrive/cmd/bdrive@latest`. If nothing
works, stop and tell the user.
## 2. Teach yourself the CLI for future sessions
```sh
bdrive skill install
```
This detects your platform and installs the beardrive skill into its skills
directory, so your later sessions understand `bdrive` conversationally.
## 3. Sign in
Check `bdrive login --status`. If there's no valid session:
- **Default (BearDrive Cloud):** run `bdrive login` — a browser opens
beardrive.ai where the user signs in or signs up. A new account gets a free
personal workspace automatically; a pending team invite lands them in that
team. Warn the user a browser window is coming.
- **Self-hosted hub:** if the user's team runs its own hub, ask for the URL
and run `bdrive login https://their-hub`.
- **Headless (no browser):** `bdrive login --device <hub-url>` — show the
user the code and URL it prints.
## 4. Initialize the project — **ask first**
Two questions (or infer from what the user already told you):
1. **Create a new project or connect an existing one?**
`bdrive init --name <name>` creates-or-joins by name;
`bdrive init --project <p-id>` connects by id.
2. **Whole folder, or shared subfolders?** Hard rule: **never sync a repo
root.** Inside a repo, sync scoped subfolders via `--shared`. Scan for
knowledge folders (`wiki/`, `docs/`, `notes/`, an Obsidian vault —
markdown-heavy, not source code) and propose candidates for confirmation.
Whole-folder is only for a dedicated knowledge folder that is the mount
itself.
If the chosen folder is git-tracked, git and BearDrive would both write it
(silent-revert hazard). Get consent, then `git rm -r --cached <dir>` and add
`<dir>/` to `.gitignore`; stage but let the user commit.
Then run non-interactively:
```sh
bdrive init --name <project> --yes # dedicated knowledge folder
bdrive init --name <project> --shared wiki,docs # in a repo: only these sync
```
After init: add `.bdrive/` to `.gitignore` (per-machine state, never
committed). Re-running `bdrive init --yes` later is always safe. To change
the scope later use `bdrive scope add/rm <dir>`, never hand-edit
`.bdrive/config.json`.
## 5. Register sync hooks — don't skip
```sh
bdrive hooks install
```
This detects the agent platforms in use and idempotently merges BearDrive's
hooks into each one's config: pull before every turn, push right after
edits, stamp changes with the agent session. Project-level hook files ride
the repo, so teammates get them too. Run `bdrive hooks` to show the status
table and tell the user which platforms got hooks. (Codex users must run
`/hooks` once inside Codex to trust the project layer; Hermes hooks are
per-user — mention that, and skip Hermes unless the user uses it.)
## 6. Claude Code only: install the plugin
If you are Claude Code, also register the marketplace and plugin so future
sessions get the skill, `/beardrive:*` commands, and hooks built in:
```sh
claude plugin marketplace add runbear-io/beardrive
claude plugin install beardrive@beardrive
```
Tell the user the plugin loads on their next session (current session keeps
working via the hooks from step 5). Other platforms: step 2 already covered
you — skip this.
## 7. Verify, then show the payoff
Run `bdrive status` — confirm the daemon is running and pending is 0.
Summarize what was set up, then pick a representative synced file (the
wiki's index/README), run `bdrive url <file>`, and hand the user the link —
seeing the folder rendered in the browser is the moment the setup clicks.
Teammate links require sign-in; `bdrive share <file>` exists for fully
public URLs.
## Optional: teach agents about the folder — **ask first**
Offer (never do silently) the two-file orientation from
`plugin/commands/install.md` step 4: a synced `<shared>/AGENTS.md` mapping
the folder for the whole team (if one exists already, follow it — don't
rewrite it), and a short pointer section in the repo root's `AGENTS.md` /
`CLAUDE.md` so agents know the folder matters.
## Onboarding teammates
Teammates on any agent paste one prompt into it (the hub's project home
page shows it pre-filled):
```
Follow https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md
to connect this folder to BearDrive project <project-id> on <hub-url>.
```
On BearDrive Cloud, drop `on <hub-url>` — login defaults to beardrive.ai.
+14 -18
View File
@@ -476,26 +476,22 @@ No terminal needed here either — the setup is one paste. Start the agent in
the folder you want the files and give it:
```
Set up BearDrive in this folder.
1. If `bdrive` is missing, install it: brew install runbear-io/tap/beardrive
(no Homebrew? grab the release binary for this OS/arch from
https://github.com/runbear-io/beardrive/releases)
2. bdrive skill install # so you know the CLI next time
3. bdrive login --device https://your-hub # show me the code and the URL
4. bdrive init --project <project-id>
5. bdrive hooks install # don't skip this - it's what syncs every turn
Then tell me what got set up.
Follow https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md
to connect this folder to BearDrive project <project-id> on <hub-url>.
```
The commands ride inside the prompt because these agents ship no BearDrive
knowledge — but the user copies one thing, and the agent handles every
deviation (already installed, no Homebrew, sign-in, wrong folder). Step 2 is
the durable part: `SKILL.md` is a cross-agent format, and `bdrive skill
install` writes the very skill the Claude plugin ships to each detected
platform's user-level skills directory (`~/.codex/skills/beardrive/SKILL.md`,
`~/.gemini/…`, `~/.hermes/…`, `~/.claude/…`), so from then on "share this
file" or "what changed?" just works. Step 5 is the one people skip when they
copy commands by hand, which is exactly why the agent runs it.
The agent fetches [INSTALL_FOR_AGENTS.md](INSTALL_FOR_AGENTS.md) and follows
it: install the CLI, `bdrive skill install`, device-code sign-in, `bdrive
init`, `bdrive hooks install`. The instructions live at that URL rather than
inside the prompt so they never go stale in someone's copy — and the agent
handles every deviation (already installed, no Homebrew, sign-in, wrong
folder). The skill step is the durable part: `SKILL.md` is a cross-agent
format, and `bdrive skill install` writes the very skill the Claude plugin
ships to each detected platform's user-level skills directory
(`~/.codex/skills/beardrive/SKILL.md`, `~/.gemini/…`, `~/.hermes/…`,
`~/.claude/…`), so from then on "share this file" or "what changed?" just
works. The hooks step is the one people skip when they copy commands by
hand, which is exactly why the agent runs it.
A project's home page in the web UI shows this with the hub URL and project
id already filled in (plus the plain-terminal version). `bdrive skill` and
+28 -45
View File
@@ -13,59 +13,42 @@ test("landing is the project home (guide), not an insights redirect", async ({ p
await expect(page.locator("#crumb")).toHaveText("wiki");
});
test("guide: three agent tabs, one active, choice persisted", async ({ page }) => {
test("guide: one paste for every agent, one line of prose, details collapsed", async ({ page }) => {
await login(page);
const pid = await wikiId(page);
await page.waitForSelector(".guide");
await expect(page.locator(".gd-tab")).toHaveText(["Claude Code & Cowork", "Hermes", "Codex"]);
await expect(page.locator(".gd-tab.active")).toHaveCount(1);
await page.click('.gd-tab[data-key="codex"]');
expect(await page.evaluate(() => localStorage.getItem("bdrive-guide-agent"))).toBe("codex");
await page.click('.gd-tab[data-key="claude"]');
});
test("claude tab: plugin flow with real hub origin and project id, no raw CLI", async ({ page }) => {
await login(page);
const pid = await wikiId(page);
await page.click('.gd-tab[data-key="claude"]');
const codes = await page.$$eval(".gd-code code", (els) => els.map((e) => e.textContent).join("\n"));
expect(codes).toContain("/plugin marketplace add runbear-io/beardrive");
expect(codes).toContain("/plugin install beardrive@beardrive");
expect(codes).toContain(`/beardrive:install connect to http://localhost:8993, project ${pid}`);
expect(codes).not.toContain("brew install");
expect(codes).not.toContain("hooks install");
await expect(page.locator(".gd-body")).toContainText("Cowork");
});
test("codex tab is one paste that hands the whole setup to the agent", async ({ page }) => {
await login(page);
const pid = await wikiId(page);
await page.click('.gd-tab[data-key="codex"]');
await expect(page.locator(".gd-step")).toHaveCount(1);
const prompt = await page.$$eval(".gd-step .gd-code code", (els) =>
// No agent tabs anymore — the prompt is identical for every agent.
await expect(page.locator(".gd-tab")).toHaveCount(0);
const prompt = await page.$$eval(".gd-body > .gd-code code", (els) =>
els.map((e) => e.textContent).join("\n"),
);
// Everything the agent needs rides inside the pasted prompt.
expect(prompt).toContain("brew install runbear-io/tap/beardrive");
expect(prompt).toContain("bdrive skill install --agent codex");
expect(prompt).toContain("bdrive login --device http://localhost:8993");
expect(prompt).toContain(`bdrive init --project ${pid}`);
expect(prompt).toContain("bdrive hooks install");
// The prompt points at the canonical instructions with the project id and
// hub URL filled in; the agent fetches the doc for the actual steps.
expect(prompt).toContain(
"Follow https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md",
);
expect(prompt).toContain(`project ${pid} on http://localhost:8993`);
expect(prompt).not.toContain("brew install");
// Detail lives behind the two collapsed sections.
await expect(page.locator(".gd-manual > summary")).toHaveText([
"What exactly happens",
"Or run it yourself",
]);
await expect(page.locator(".gd-manual[open]")).toHaveCount(0);
});
test("guide: manual fallback has the full command list and the docs link", async ({ page }) => {
await login(page);
const pid = await wikiId(page);
await page.waitForSelector(".guide");
const manual = await page.$$eval(".gd-manual .gd-code code", (els) =>
els.map((e) => e.textContent).join("\n"),
);
expect(manual).toContain("brew install runbear-io/tap/beardrive");
expect(manual).toContain("bdrive login http://localhost:8993");
expect(manual).toContain("bdrive hooks install --agent codex");
await page.click('.gd-tab[data-key="claude"]');
});
test("a stale saved tab choice falls back to the first tab", async ({ page }) => {
await login(page);
await page.waitForSelector(".guide");
await page.evaluate(() => localStorage.setItem("bdrive-guide-agent", "cowork"));
await page.reload();
await page.waitForSelector(".guide");
await expect(page.locator(".gd-tab.active")).toHaveText("Claude Code & Cowork");
await page.evaluate(() => localStorage.setItem("bdrive-guide-agent", "claude"));
expect(manual).toContain(`bdrive init --project ${pid}`);
expect(manual).toContain("bdrive hooks install");
await expect(page.locator('.gd-manual a[href="https://docs.beardrive.ai/manual/install/"]')).toHaveCount(1);
});
test("admin home embeds insights below the guide; member home does not", async ({ page, browser }) => {
@@ -5,149 +5,26 @@ import { ProjectIcon } from "./shell";
import { projColor } from "./ProjectNav";
/* ---- project home guide ----
How to mount the project as a local folder and connect a coding agent,
with real, copyable commands: this hub's URL and this project's id
filled in. */
One paste sets up any coding agent: the prompt points at the canonical
INSTALL_FOR_AGENTS.md with this hub's URL and this project's id filled
in. The agent fetches the doc and handles every deviation — already
installed, no Homebrew, sign-in, wrong folder — so the page itself
stays to one line of prose; detail lives in the collapsed sections. */
interface GuideAgent {
key: string;
label: string;
agent?: string; // --agent value for `bdrive skill install`
skillDir?: string; // where that agent reads the skill from
extra?: string; // platform-specific caveat after the last step
}
const GUIDE_AGENTS: GuideAgent[] = [
{ key: "claude", label: "Claude Code & Cowork" },
{
key: "hermes",
label: "Hermes",
agent: "hermes",
skillDir: "~/.hermes/skills/beardrive/",
},
{
key: "codex",
label: "Codex",
agent: "codex",
skillDir: "~/.codex/skills/beardrive/",
extra:
"Codex asks once to trust the project's .codex hooks layer — answer yes (or run /hooks) and " +
"from then on every turn pulls, edits push automatically, and reads are reported to Insights.",
},
];
interface Step {
title: string;
desc?: string;
code?: string;
extra?: string;
}
function guideSteps(agent: GuideAgent, project: Project): Step[] {
const origin = window.location.origin;
const pid = project.id;
// Claude Code and Claude Cowork share one plugin: install it once, then
// /beardrive:install does the whole setup conversationally.
if (agent.key === "claude") {
return [
{
title: "Add the BearDrive plugin",
desc:
"One time, in any Claude Code session. The plugin ships the beardrive skill, the /beardrive " +
"commands, and turn-boundary sync hooks — and Claude Cowork shares the same plugins, so " +
"installing it once covers both.",
code: "/plugin marketplace add runbear-io/beardrive\n/plugin install beardrive@beardrive",
},
{
title: "Set up this project conversationally",
desc: "In a Claude Code or Cowork session in the folder where you want the files, run:",
code: "/beardrive:install connect to " + origin + ", project " + pid,
extra:
"Claude installs the CLI, signs this machine in, mounts the project, and registers the " +
"sync hooks — pull the latest before every turn, push after edits (stamped with the session " +
"that made them), and report file reads to Insights. It asks before anything it changes.",
},
];
}
// Every other agent: one paste, no terminal — the same shape as the Claude
// tab. The commands ride INSIDE the prompt because these agents ship no
// BearDrive knowledge (Claude's tab can be terse only because the plugin
// carries it); the user still copies one thing, and the agent handles every
// deviation — already installed, no Homebrew, sign-in, wrong folder. Step 2
// of the prompt installs the skill, so every later session is conversational.
return [
{
title: "Paste this into " + agent.label,
desc:
"Start " +
agent.label +
" in the folder where you want the files (an existing folder works too — contents merge), " +
"then paste:",
code: setupPrompt(agent, project),
extra:
"Approve the shell commands when it asks. It installs the CLI, signs this machine in (it " +
"hands you a code and a URL — the folder itself never holds credentials), mounts the " +
"project, and registers the sync hooks: pull before every turn, push after edits stamped " +
"with the session that made them, file reads into Insights. It also keeps the beardrive " +
"skill in " +
agent.skillDir +
", so from here on you can just ask." + (agent.extra ? " " + agent.extra : ""),
},
];
}
// The prompt the user pastes. Numbered, exact commands: an agent with no
// BearDrive knowledge follows this reliably, and knows what to do when a step
// is already done. `login --device` on purpose — a browser-callback sign-in is
// invisible to an agent mid-turn, while the device flow gives it a code and a
// URL it can hand back in chat.
function setupPrompt(agent: GuideAgent, project: Project): string {
return [
"Set up BearDrive in this folder.",
"1. If `bdrive` is missing, install it: brew install runbear-io/tap/beardrive",
" (no Homebrew? grab the release binary for this OS/arch from",
" https://github.com/runbear-io/beardrive/releases)",
"2. bdrive skill install --agent " + agent.agent + " # so you know the CLI next time",
"3. bdrive login --device " + window.location.origin + " # show me the code and the URL",
"4. bdrive init --project " + project.id,
"5. bdrive hooks install # don't skip this - it's what syncs every turn",
"Then tell me what got set up.",
].join("\n");
}
// For anyone who would rather not hand the setup to an agent. Skipping
// `hooks install` is the one thing that silently costs you turn-boundary
// syncing, so it is spelled out here.
function manualCommands(agent: GuideAgent, project: Project): string {
return (
"brew install runbear-io/tap/beardrive" +
"\nbdrive skill install --agent " +
agent.agent +
"\nbdrive login " +
window.location.origin +
"\nbdrive init --project " +
project.id +
"\nbdrive hooks install --agent " +
agent.agent
);
}
function savedAgent(): string {
try {
return localStorage.getItem("bdrive-guide-agent") || "claude";
} catch {
return "claude"; // private mode
}
}
const INSTALL_DOC = "https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md";
export function ConnectGuide({ project }: { project: Project }) {
const [agentKey, setAgentKey] = useState(savedAgent);
// A stale saved key (e.g. a tab that no longer exists) falls back to the
// first tab rather than rendering nothing.
const agent = GUIDE_AGENTS.find((a) => a.key === agentKey) || GUIDE_AGENTS[0];
const steps = guideSteps(agent, project);
const origin = window.location.origin;
const prompt =
"Follow " + INSTALL_DOC + "\nto connect this folder to BearDrive project " + project.id + " on " + origin + ".";
const manual =
"brew install runbear-io/tap/beardrive" +
"\nbdrive skill install" +
"\nbdrive login " +
origin +
"\nbdrive init --project " +
project.id +
"\nbdrive hooks install";
return (
<div className="guide">
@@ -162,58 +39,48 @@ export function ConnectGuide({ project }: { project: Project }) {
{project.name}
</h1>
{project.description && <p className="in-desc">{project.description}</p>}
<p className="dl-sub">
Mount this project as a folder on any machine and connect your coding agent: files sync both
ways in the background, every change is journaled with who made it, and agent reads feed
Insights.
</p>
<div className="gd-tabs">
{GUIDE_AGENTS.map((a) => (
<button
key={a.key}
className={"gd-tab" + (a.key === agent.key ? " active" : "")}
data-key={a.key}
onClick={() => {
setAgentKey(a.key);
try {
localStorage.setItem("bdrive-guide-agent", a.key);
} catch {
/* private mode */
}
}}
>
{a.label}
</button>
))}
</div>
<div className="gd-body">
{steps.map((s, i) => (
<div className={"gd-step" + (steps.length > 1 ? "" : " gd-solo")} key={i}>
<div className="gd-step-head">
{/* A lone step is not a sequence — no "1." badge for it. */}
{steps.length > 1 && <span className="gd-num">{i + 1}</span>}
<span className="gd-step-title">{s.title}</span>
</div>
{s.desc && <p className="gd-desc">{s.desc}</p>}
{s.code && <GuideCode code={s.code} />}
{s.extra && <p className="gd-desc gd-extra">{s.extra}</p>}
</div>
))}
{agent.agent && (
<details className="gd-manual">
<summary>Or run it yourself</summary>
<p className="gd-desc">
Same result, in the folder you want the files. Don't skip the last line — the hooks
are what keep every turn starting from the latest state.
</p>
<GuideCode code={manualCommands(agent, project)} />
</details>
)}
<p className="gd-done">
That's it the folder now syncs on its own. Every agent turn starts from the latest
state, edits appear here (and on every teammate's mount) within seconds, and what your
agents read shows up in Insights.
<p className="gd-desc">
Paste into your coding agent Claude Code, Cowork, Codex, Gemini CLI, Hermes in the
folder where you want the files:
</p>
<GuideCode code={prompt} />
<p className="gd-desc">
The agent installs the CLI, signs this machine in, and registers the sync hooks asking
before anything it changes.
</p>
<details className="gd-manual">
<summary>What exactly happens</summary>
<ul className="gd-desc gd-list">
<li>
Sign-in uses a device code you approve in this browser the folder itself never
holds credentials.
</li>
<li>
Sync hooks pull the latest before every agent turn, push edits seconds after they
happen, and stamp each change with the session that made it; agent reads feed
Insights.
</li>
<li>
The beardrive skill (and on Claude Code, the plugin shared with Cowork) is
installed for later sessions, so from then on you can just ask.
</li>
<li>Codex asks once to trust the project's hooks layer — answer yes, or run /hooks.</li>
</ul>
</details>
<details className="gd-manual">
<summary>Or run it yourself</summary>
<p className="gd-desc">
Same result, in the folder you want the files. Don't skip the last line the hooks are
what keep every turn starting from the latest state.
</p>
<GuideCode code={manual} />
<p className="gd-desc">
<a href="https://docs.beardrive.ai/manual/install/" target="_blank" rel="noreferrer">
Full manual setup guide
</a>
</p>
</details>
</div>
</div>
);
+6 -15
View File
@@ -525,29 +525,20 @@ a.ai-main:hover { color: var(--accent); }
#vault-name.vault-link { cursor: pointer; }
#vault-name.vault-link:hover { color: var(--accent-bright); }
/* .guide width comes from .page (app) */
.gd-tabs { display: flex; gap: 2px; margin: 20px 0 16px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.gd-tab { font: inherit; font-size: 13px; font-weight: 600; padding: 7px 12px 9px; background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--text-faint); cursor: pointer; white-space: nowrap; }
.gd-tab:hover { color: var(--text); }
#account-btn.active { background: var(--glow); }
#account-btn.active .acct b { color: var(--accent-bright); }
.gd-tab.active { color: var(--accent-bright); border-bottom-color: var(--accent); }
.gd-step { margin: 0 0 18px; }
.gd-step-head { display: flex; align-items: center; gap: 10px; margin-bottom: 3px; }
.gd-num { flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--glow); color: var(--accent-bright); font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.gd-step-title { font-weight: 600; font-size: 14px; color: var(--text); }
.gd-desc { margin: 2px 0 8px 32px; color: var(--text-faint); font-size: 13px; line-height: 1.5; }
.gd-extra { font-size: 12.5px; margin-top: 6px; }
.gd-code { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 10px; margin: 6px 0 6px 32px; padding: 10px 12px; background: var(--bg-raise); border: 1px solid var(--border); border-radius: var(--r-card); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.6; color: var(--text); }
.gd-body { margin-top: 18px; }
.gd-desc { margin: 2px 0 8px; color: var(--text-faint); font-size: 13px; line-height: 1.5; }
.gd-list { margin: 4px 0 8px; padding-left: 18px; display: grid; gap: 6px; }
.gd-code { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 10px; margin: 6px 0 10px; padding: 10px 12px; background: var(--bg-raise); border: 1px solid var(--border); border-radius: var(--r-card); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.6; color: var(--text); }
.gd-code > code { display: block; min-width: 0; overflow-x: auto; white-space: pre; }
.gd-copy { align-self: start; font: inherit; font-family: inherit; font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 6px; border: 1px solid var(--border-2); background: var(--bg-raise); color: var(--text-faint); cursor: pointer; }
.gd-copy:hover { color: var(--accent-bright); border-color: var(--accent-dim); }
/* A single unnumbered step has no badge to indent under. */
.gd-solo .gd-desc, .gd-solo .gd-code { margin-left: 0; }
.gd-manual { margin: 10px 0 0; }
.gd-manual > summary { display: inline-block; font-size: 12.5px; font-weight: 600; color: var(--text-faint); cursor: pointer; padding: 4px 0; }
.gd-manual > summary::before { content: "▸ "; color: var(--text-ghost); }
.gd-manual[open] > summary::before { content: "▾ "; }
.gd-manual > summary:hover { color: var(--text); }
.gd-manual .gd-desc, .gd-manual .gd-code { margin-left: 0; }
.gd-done { margin: 22px 0 8px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--r-card); background: var(--bg-side); color: var(--text-faint); font-size: 13px; line-height: 1.5; }
.home-insights { margin-top: 30px; padding-top: 22px; border-top: 1px solid var(--border); }
/* ---- insights (read×write matrix) ---- */
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BearDrive</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='%23f5a623'><rect x='4' y='4' width='5.6' height='24'/><rect x='11.2' y='4' width='14.4' height='11.2'/><rect x='11.2' y='16.8' width='16.8' height='11.2'/></svg>">
<script type="module" crossorigin src="/assets/index-89AlIPy9.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C_qEQ9NO.css">
<script type="module" crossorigin src="/assets/index-DWHDxV9i.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BztPAPur.css">
</head>
<body>
<div id="root"></div>
+7 -10
View File
@@ -144,18 +144,15 @@ tell them those teammates need no terminal either — they paste one prompt
into their own agent (the hub's project home page shows it filled in):
```
Set up BearDrive in this folder.
1. If `bdrive` is missing, install it: brew install runbear-io/tap/beardrive
2. bdrive skill install # so you know the CLI next time
3. bdrive login --device <hub-url> # show me the code and the URL
4. bdrive init --project <project-id>
5. bdrive hooks install # don't skip this - it's what syncs every turn
Follow https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md
to connect this folder to BearDrive project <project-id> on <hub-url>.
```
Step 2 leaves the beardrive skill in that agent's skills dir
(`~/.codex/skills/beardrive/` and friends) so their later sessions are
conversational. Handing teammates loose commands is how the hooks step gets
skipped.
The fetched instructions run install, skill install (which leaves the
beardrive skill in that agent's skills dir — `~/.codex/skills/beardrive/`
and friends — so later sessions are conversational), device-code login,
init, and hooks install. Handing teammates loose commands instead is how
the hooks step gets skipped.
## 6. Verify and summarize
+10 -11
View File
@@ -179,22 +179,21 @@ a CLI upgrade refreshes an outdated copy (idempotent otherwise). Installs
are user-level on purpose — the skill is about the CLI, not one folder, and
a synced project folder should never carry it.
The intended flow for a new machine is one paste into that agent — the
commands ride inside the prompt because it has no BearDrive knowledge yet:
The intended flow for a new machine is one paste into that agent — it points
at the canonical instructions (repo-root `INSTALL_FOR_AGENTS.md`) since the
agent has no BearDrive knowledge yet:
```
Set up BearDrive in this folder.
1. If `bdrive` is missing, install it: brew install runbear-io/tap/beardrive
2. bdrive skill install # so you know the CLI next time
3. bdrive login --device <hub-url> # show me the code and the URL
4. bdrive init --project <project-id>
5. bdrive hooks install # don't skip this - it's what syncs every turn
Follow https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md
to connect this folder to BearDrive project <project-id> on <hub-url>.
```
Use `login --device` when an agent is driving: a browser-callback sign-in is
The fetched instructions cover install, `bdrive skill install`, sign-in,
`bdrive init --project`, and `bdrive hooks install`. They use `login
--device` because an agent is driving: a browser-callback sign-in is
invisible to it mid-turn, while the device flow yields a code and URL it can
hand back in chat. The hub's project home page renders this with the URL and
id filled in.
hand back in chat. The hub's project home page renders this prompt with the
URL and id filled in.
### Read heat (who actually reads what)
+13 -16
View File
@@ -43,27 +43,24 @@ installed the plugin**.
## Codex, Gemini CLI, and Hermes
These agents ship no BearDrive knowledge yet, so the instructions travel in the
message. Start the agent in the folder you want synced and paste:
These agents ship no BearDrive knowledge yet, so the prompt points them at the
canonical instructions instead. Start the agent in the folder you want synced
and paste:
```
Set up BearDrive in this folder.
1. If `bdrive` is missing, install it: brew install runbear-io/tap/beardrive
(no Homebrew? grab the release binary for this OS/arch from
https://github.com/runbear-io/beardrive/releases)
2. bdrive skill install # so you know the CLI next time
3. bdrive login --device https://your-hub # show me the code and the URL
4. bdrive init --project <project-id>
5. bdrive hooks install # don't skip this - it's what syncs every turn
Then tell me what got set up.
Follow https://raw.githubusercontent.com/runbear-io/beardrive/main/INSTALL_FOR_AGENTS.md
to connect this folder to BearDrive project <project-id> on <hub-url>.
```
You copy one thing; the agent handles every deviation — already installed, no
Homebrew, browser sign-in, wrong folder.
The agent fetches that page and works through it — install the CLI, sign in
with a device code, connect the project, register the sync hooks. You copy one
thing; the agent handles every deviation — already installed, no Homebrew,
browser sign-in, wrong folder. On BearDrive Cloud, drop `on <hub-url>`
sign-in defaults to beardrive.ai.
Step 2 is the durable part. Once the skill is installed the agent knows the CLI
from then on, so "share this file" or "what changed?" work without you
explaining anything again.
The skill step in those instructions is the durable part. Once the skill is
installed the agent knows the CLI from then on, so "share this file" or "what
changed?" work without you explaining anything again.
:::tip[Don't retype this for teammates]
A project's home page in the hub shows this same paste with your hub URL and