mirror of
https://github.com/runbear-io/beardrive.git
synced 2026-08-25 08:08:08 +02:00
One paste-able URL onboards any agent: INSTALL_FOR_AGENTS.md (#57)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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
+16
-17
File diff suppressed because one or more lines are too long
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user