Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config.sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down
236 changes: 236 additions & 0 deletions docs/beads.md
Original file line number Diff line number Diff line change
@@ -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 `<workspace>/.env`:

```bash
BEADS_DIR=<workspace>/.beads
BEADS_ACTOR={{botName}}
```
Comment on lines +41 to +43
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .env parser used by the bridge does not expand $PATH/${PATH} in .env values (they’re treated literally). As written, PATH=/home/<user>/.local/bin:$PATH will likely break PATH for the session/MCP servers instead of prepending. Consider removing this line and instead ensure Dolt is on the real system PATH, or document a supported approach (e.g., set PATH in the hook script, or use mcp-config.json env with ${PATH} expansion).

Copilot uses AI. Check for mistakes.

> **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 <workspace>/.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 `<workspace>/.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
}
]
}
Comment on lines +92 to +112
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook scripts rely on bd finding the workspace’s Beads state via env/cwd, but hooks run as separate processes spawned by the bridge and do not automatically inherit workspace .env vars. With cwd set to .github/hooks, bd may not find .beads/ unless BEADS_DIR is set explicitly for the hook command (via hooks.json env) or the script sets cwd/BEADS_DIR itself. Please adjust the example to be self-contained (e.g., run from workspace root and/or pass BEADS_DIR via hook env).

Copilot uses AI. Check for mistakes.
}
```

> **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/<user>/.local/bin:$PATH" # ensure dolt is on PATH
export BEADS_DIR="<workspace>/.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 '{}'
```
Comment on lines +122 to +138
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Workspace hook commands must write a single JSON object to stdout (the hooks loader parses stdout as JSON); emitting plain bd prime output will be treated as invalid JSON and ignored. Update this example to wrap the bd prime output in a JSON response (e.g., as an additionalContext field) if the intent is to inject it into the session context.

This issue also appears on line 130 of the same file.

Copilot uses AI. Check for mistakes.

### session-end.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

input=$(cat) # JSON from copilot-bridge: { "sessionId": "...", "channelId": "..." }

export PATH="/home/<user>/.local/bin:$PATH" # ensure dolt is on PATH
export BEADS_DIR="<workspace>/.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 `<workspace>/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/<user>/.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
10 changes: 10 additions & 0 deletions templates/agents/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
118 changes: 118 additions & 0 deletions templates/agents/beads.agent.md
Original file line number Diff line number Diff line change
@@ -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)

Comment on lines +1 to +22
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is named *.agent.md, which the bridge treats as an agent definition (discoverable via /agents in <workspace>/.github/agents/ or <workspace>/agents/), not a skill. If the intent is a skill (as referenced by AGENTS.md/docs), it should be provided in the skill directory format (.github/skills/<skillName>/SKILL.md). If the intent is an agent definition, the surrounding docs/templates should be updated to describe it as an agent and how to enable it, and the copy instructions should point at the bridge’s template path (~/.copilot-bridge/templates/...) rather than templates/... inside this repo.

Copilot uses AI. Check for mistakes.
## 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 <id> --claim # Atomically claim a task (sets assignee + in_progress)
bd update <id> --status=done # Update status without closing
bd update <id> --notes="..." # Add notes inline
```

### Closing tasks

```bash
bd close <id> --reason="What was done"
bd close <id1> <id2> <id3> # Close multiple at once
```

### Viewing and searching

```bash
bd show <id> # 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-id> <parent-id> # 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 <id1> <id2> ... # 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
```