diff --git a/config.sample.json b/config.sample.json index 5db2bba..dc008e2 100644 --- a/config.sample.json +++ b/config.sample.json @@ -51,6 +51,7 @@ "shell(grep)", "shell(wc)" ], + "_comment_beads": "Uncomment to allow Beads task memory (bd writes to .beads/ and may start a Dolt server — opt-in only)", "deny": [ "shell(rm)", "shell(git push)", diff --git a/docs/beads.md b/docs/beads.md new file mode 100644 index 0000000..4b8d3de --- /dev/null +++ b/docs/beads.md @@ -0,0 +1,236 @@ +# Beads Integration Guide + +[Beads](https://github.com/steveyegge/beads) (`bd`) is a distributed, Dolt-backed graph issue tracker designed for AI agent memory. This guide covers integrating Beads into a copilot-bridge workspace so agents can persist task context across session restarts. + +## Why Beads Instead of MEMORY.md + +`MEMORY.md` is a flat markdown file — simple, but limited: + +| | `MEMORY.md` | Beads | +|---|---|---| +| Queryable | ❌ | ✅ `bd search`, `bd ready`, `bd blocked` | +| Dependency tracking | ❌ | ✅ `bd dep add` | +| Concurrency-safe | ❌ | ✅ Dolt atomic commits | +| Versioned / auditable | ❌ | ✅ Full Dolt history | +| Cross-session recovery | Manual | ✅ `bd prime` | +| Multi-bot coordination | ❌ | ✅ Shared Dolt server or remote sync | + +## Prerequisites + +- **`bd` CLI**: `npm install -g @beads/bd` or `brew install beads` +- **Dolt**: installed automatically when `bd` first runs — no manual setup needed +- Node.js 18+ (for `bd` CLI) + +## Workspace Setup + +### 1. Initialize Beads + +Run from inside the workspace directory: + +```bash +bd init --quiet --stealth +``` + +`--stealth` disables git hooks and git operations from Beads — required for copilot-bridge workspaces where the bot should not push git changes autonomously. + +### 2. Configure the workspace `.env` + +Add to `/.env`: + +```bash +BEADS_DIR=/.beads +BEADS_ACTOR={{botName}} +``` + +> **Note:** copilot-bridge's `.env` parser does not expand shell variables like `$PATH`. If Dolt is not on the system PATH, set it in the hook scripts directly (see Session Hook Automation below) rather than in `.env`. + +copilot-bridge auto-injects `.env` variables into all MCP server environments. The `BEADS_ACTOR` variable sets the actor name in the Beads audit trail — use the bot name for clear attribution. + +### 3. Add the Beads agent definition + +Copy `templates/agents/beads.agent.md` to the workspace's agents directory (`.github/agents/`): + +```bash +cp templates/agents/beads.agent.md /.github/agents/beads.agent.md +``` + +This adds a `beads` agent definition that agents can switch to with `/agent beads`. It provides the full `bd` workflow and is automatically discovered by copilot-bridge from `.github/agents/`. + +### 4. Update AGENTS.md (optional) + +Add a brief Beads section to the workspace `AGENTS.md` so the default agent knows to use `bd` when available: + +```markdown +## Task Memory (Beads) + +This workspace uses Beads (`bd`) for persistent task tracking. Use `/agent beads` for the full workflow, or see `docs/beads.md` for setup. Use `bd prime` at session start and `bd backup export-git` at session end. +``` + +### 5. Add `bd` to workspace permissions (opt-in) + +`bd` writes to `.beads/` and may start a Dolt server — it is intentionally **not** in the default allow list. Add it explicitly if you want agents to run it without interactive prompts: + +```json +"permissions": { + "allow": ["shell(bd)"] +} +``` + +## Session Hook Automation (Recommended) + +Rather than relying on the agent to remember to run `bd prime` and `bd backup export-git`, use copilot-bridge session hooks to automate them. + +> **Note:** Session hooks require `allowWorkspaceHooks: true` under `defaults` in `~/.copilot-bridge/config.json`: +> ```json +> "defaults": { "allowWorkspaceHooks": true } +> ``` + +### hooks.json + +Create `/.github/hooks/hooks.json`: + +```json +{ + "version": 1, + "hooks": { + "sessionStart": [ + { + "type": "command", + "bash": "./session-start.sh", + "cwd": ".", + "timeoutSec": 15 + } + ], + "sessionEnd": [ + { + "type": "command", + "bash": "./session-end.sh", + "cwd": ".", + "timeoutSec": 30 + } + ] + } +} +``` + +> **Note:** `cwd` is relative to the directory containing `hooks.json`. Use `"."` — do not repeat the hooks directory path. + +### session-start.sh + +Hook scripts run as separate processes and do not inherit workspace `.env`. Set `BEADS_DIR` and `PATH` explicitly: + +```bash +#!/usr/bin/env bash +set -euo pipefail + +input=$(cat) # JSON from copilot-bridge: { "sessionId": "...", "channelId": "..." } + +export PATH="/home//.local/bin:$PATH" # ensure dolt is on PATH +export BEADS_DIR="/.beads" +export BEADS_ACTOR="{{botName}}" + +if command -v bd &>/dev/null; then + bd prime >/dev/null 2>&1 || true +fi + +# hooks-loader expects JSON output — return empty object +echo '{}' +``` + +### session-end.sh + +```bash +#!/usr/bin/env bash +set -euo pipefail + +input=$(cat) # JSON from copilot-bridge: { "sessionId": "...", "channelId": "..." } + +export PATH="/home//.local/bin:$PATH" # ensure dolt is on PATH +export BEADS_DIR="/.beads" +export BEADS_ACTOR="{{botName}}" + +if command -v bd &>/dev/null; then + bd backup export-git >/dev/null 2>&1 || true +fi + +# hooks-loader expects JSON output — return empty object +echo '{}' +``` + +Make both scripts executable: `chmod +x session-start.sh session-end.sh` + +## Sync Strategy + +Beads provides three tiers of persistence: + +| Tier | Command | Use case | +|------|---------|----------| +| **Local (automatic)** | *(none)* | Every write auto-commits to local Dolt history — always on | +| **Git branch backup** | `bd backup export-git` | JSONL snapshot to a git branch in the workspace repo — zero new infrastructure | +| **Full Dolt sync** | `bd dolt push` | Push to DoltHub, S3, GCS, or `git+ssh://` remote — multi-machine access | + +**Recommended per scenario:** + +- **Single bot, single machine**: `bd backup export-git` in `sessionEnd` hook — JSONL snapshots stored in the existing workspace git repo +- **Multi-machine / disaster recovery**: `bd dolt remote add origin git+ssh://git@github.com/org/repo.git` + `bd dolt push` in hook. Dolt stores its data under `refs/dolt/data` — invisible to normal git, compatible with any existing GitHub repo +- **Multiple bots on the same host**: set `BEADS_DOLT_SHARED_SERVER=1` in workspace `.env` — single shared Dolt server, each bot isolated in its own database + +## MCP Alternative + +For environments where the agent does not have shell access, `beads-mcp` provides the same functionality as a stdio MCP server: + +```bash +uv tool install beads-mcp +``` + +Add to `/mcp-config.json`: + +```json +{ + "mcpServers": { + "beads": { + "command": "beads-mcp", + "env": { + "BEADS_WORKING_DIR": "{{workspacePath}}", + "BEADS_ACTOR": "{{botName}}" + } + } + } +} +``` + +> **Token cost**: `beads-mcp` exposes tool schemas that consume 10–50k tokens per session. The CLI approach via skill file is preferred for shell-capable agents. + +## Troubleshooting + +**`bd` can't find `dolt`** +Dolt installs to `~/.local/bin/` by default. Ensure this is on `PATH` in the workspace `.env`: +```bash +PATH=/home//.local/bin:$PATH +``` + +**Dolt server not starting** +```bash +bd doctor # Check server health +bd dolt start # Start manually +``` + +**`.beads/` not tracked by git** +`bd init --stealth` adds `.beads/` to `.git/info/exclude`. To commit Beads config files (e.g., `.beads/config.yaml`), remove that line: +```bash +grep -v "^\.beads" .git/info/exclude > /tmp/exclude && mv /tmp/exclude .git/info/exclude +``` + +Add Dolt binary data to `.gitignore` to avoid committing large files: +``` +.beads/dolt/ +.beads/*.db +``` + +## References + +- [Beads GitHub](https://github.com/steveyegge/beads) +- [Beads ARCHITECTURE.md](https://github.com/steveyegge/beads/blob/main/docs/ARCHITECTURE.md) +- [Beads DOLT-BACKEND.md](https://github.com/steveyegge/beads/blob/main/docs/DOLT-BACKEND.md) +- [beads-mcp on PyPI](https://pypi.org/project/beads-mcp/) +- copilot-bridge issue [#157](https://github.com/ChrisRomp/copilot-bridge/issues/157) — integration tracking diff --git a/templates/agents/AGENTS.md b/templates/agents/AGENTS.md index 9c4e094..d0dddda 100644 --- a/templates/agents/AGENTS.md +++ b/templates/agents/AGENTS.md @@ -34,6 +34,16 @@ Maintain a `MEMORY.md` file in your workspace to persist important details acros Read `MEMORY.md` at the start of each session if it exists. Update it when you learn something worth remembering. Keep it concise and organized — this is your long-term memory. +## Task Memory (Beads) + +If this workspace has Beads configured (`.beads/` directory exists and `bd` is on PATH), use it for structured task tracking instead of `MEMORY.md`: + +- **Session start**: run `bd prime` to recover task context, then `bd ready --json` to see what to work on +- **During work**: `bd create`, `bd update --claim`, `bd close` — switch to the Beads agent (`/agent beads`) for the full workflow +- **Session end**: run `bd backup export-git` to snapshot progress to git + +Prefer `bd remember` over `MEMORY.md` for persistent knowledge when Beads is available. See `docs/beads.md` for setup instructions. + ## Constraints - File system access is sandboxed to this workspace{{#allowPaths}} + additional folders listed above{{/allowPaths}} diff --git a/templates/agents/beads.agent.md b/templates/agents/beads.agent.md new file mode 100644 index 0000000..f286516 --- /dev/null +++ b/templates/agents/beads.agent.md @@ -0,0 +1,118 @@ +--- +name: Beads Task Memory +description: Persistent task tracking for this workspace using bd (Beads). Invoke with /agent beads to use this workflow for creating, tracking, and closing tasks across sessions. +--- + +# Beads Task Memory + +This workspace uses [Beads](https://github.com/steveyegge/beads) (`bd`) for persistent, structured task memory backed by [Dolt](https://github.com/dolthub/dolt). Tasks survive session restarts and can be shared across multiple bots via Dolt sync. + +## How to use this agent + +Switch to this agent with `/agent beads` when you want to: +- Recover task context at the start of a session (`bd prime`) +- Create, update, claim, or close Beads tasks +- Interpret `bd` output and decide what to work on next + +## Prerequisites + +- `bd` CLI installed: `npm install -g @beads/bd` or `brew install beads` +- `bd init --quiet --stealth` run in the workspace directory +- `BEADS_DIR` and `BEADS_ACTOR` set in workspace `.env` (auto-injected by copilot-bridge) + +## Session Start Workflow + +Run at the beginning of every session to recover context: + +```bash +bd prime # Print workflow context and pending work +bd ready --json # List tasks with no open blockers (what to work on next) +``` + +## Task Operations + +### Creating tasks + +```bash +bd create --title="Short descriptive title" --description="Why this exists and what done looks like" --type=task --priority=2 +``` + +- Types: `task`, `feature`, `bug`, `epic`, `chore`, `decision` +- Priority: `0` (critical) → `4` (backlog). Use numbers, not words. +- For descriptions with special chars, pipe via stdin: `echo "description" | bd create --title="Title" --stdin` +- **NEVER** use `bd edit` — it opens `$EDITOR` and blocks the agent. + +### Claiming and progressing work + +```bash +bd update --claim # Atomically claim a task (sets assignee + in_progress) +bd update --status=done # Update status without closing +bd update --notes="..." # Add notes inline +``` + +### Closing tasks + +```bash +bd close --reason="What was done" +bd close # Close multiple at once +``` + +### Viewing and searching + +```bash +bd show # Full task details + audit trail +bd list # All open issues +bd list --status=in_progress # Active work +bd search "keyword" # Full-text search +bd stats # Project health summary +``` + +### Dependencies + +```bash +bd dep add # child depends on parent (parent blocks child) +bd blocked # Show all blocked issues +``` + +### Persistent knowledge + +```bash +bd remember "key insight or decision" # Store cross-session knowledge +bd memories "keyword" # Search stored knowledge +``` + +**Call `bd remember` at the moment of discovery — not at the end of the session.** Dolt commits immediately on every write, so memories survive any shutdown. Batching to the end risks losing them if the session is interrupted. + +Trigger `bd remember` whenever: +- A non-obvious decision is made (e.g. "use X not Y because Z") +- A gotcha, failure mode, or workaround is found +- A config value or path turns out to be critical or surprising +- Any fact that would take >5 minutes to re-discover next session + +Format: a concise, self-contained sentence — include the *why*, not just the *what*. + +## Session End Workflow + +Close completed tasks and back up before ending a session: + +```bash +bd close ... # Close all completed work +bd backup export-git # Snapshot to git branch (zero-infrastructure backup) +``` + +## When to Use Beads + +- Any task that spans multiple tool calls or may be interrupted mid-session +- Multi-step work with subtasks (use epics + child tasks) +- Decisions that should be recorded for future sessions +- Anything you'd otherwise write to `MEMORY.md` + +When Beads is available, prefer `bd remember` over `MEMORY.md` for persistent knowledge — Beads is queryable, versioned, and concurrency-safe. + +## Troubleshooting + +```bash +bd doctor # Check Dolt server health +bd dolt start # Manually start Dolt server if needed +bd dolt status # Check server status +```