|
| 1 | +# AGENTS.md — bd-console |
| 2 | + |
| 3 | +Context for any coding agent working on **bd-console**. Read this first. |
| 4 | + |
| 5 | +## What this is |
| 6 | + |
| 7 | +A standalone, **project-agnostic** web tool to view and lightly edit |
| 8 | +[beads](https://github.com/gastownhall/beads) (`bd`) issues and a project's |
| 9 | +markdown docs. It runs locally against *any* repo that has beads installed. |
| 10 | +It started as an in-repo console and was then generalized into its own public |
| 11 | +repository. |
| 12 | + |
| 13 | +**Hard constraints (do not break these):** |
| 14 | +- **Zero npm dependencies.** Node built-ins only (`http`, `fs`, `child_process`, |
| 15 | + `path`, `url`). No framework, no bundler, **no build step**. Keep it that way — |
| 16 | + the whole point is "drop in and run." |
| 17 | +- **Writes shell out to `bd` via `execFile` with an args array — never a shell |
| 18 | + string.** This is the injection defense (verified: a comment containing |
| 19 | + `$(touch /tmp/PWNED)` is stored as literal text). Any new write must follow |
| 20 | + this pattern and validate the issue id against `ID_RE`. |
| 21 | +- Frontend is **vanilla JS, no transpile.** `node --check public/app.js` is the |
| 22 | + syntax gate; there's no tsc. |
| 23 | + |
| 24 | +## Run |
| 25 | + |
| 26 | +```bash |
| 27 | +node serve.mjs # auto-detects .beads/ from cwd, port 4180 |
| 28 | +node serve.mjs --repo ~/proj --port 4181 --host 127.0.0.1 |
| 29 | +node scripts/init.mjs --repo ~/proj --apply-agent-docs |
| 30 | +``` |
| 31 | +`package.json` exposes a `bd-console` bin, so once published it's `npx bd-console`. |
| 32 | +The repo also ships `bd-console-init` for first-run setup. |
| 33 | + |
| 34 | +## Layout |
| 35 | + |
| 36 | +``` |
| 37 | +serve.mjs zero-dep Node server (the only backend) |
| 38 | +public/ |
| 39 | + index.html shell + topbar + quick-capture modal + theme <head> script |
| 40 | + app.js all client logic (state, render, comments, quick, themes, md) |
| 41 | + styles.css CSS custom-property theme tokens + components |
| 42 | +package.json bin: bd-console -> serve.mjs ; "files" whitelist |
| 43 | +bd-console.json.example optional per-project config |
| 44 | +README.md user-facing docs |
| 45 | +``` |
| 46 | + |
| 47 | +## Server (serve.mjs) |
| 48 | + |
| 49 | +- **Workspace detection:** `--repo` / `$BD_CONSOLE_REPO` / walk up from cwd to the |
| 50 | + nearest `.beads/`. Exits if none found. |
| 51 | +- **Config:** optional `bd-console.json` at the workspace root — |
| 52 | + `{ port, host, docRoots, token }`. Default host is `127.0.0.1`. Env overrides: |
| 53 | + `BD_CONSOLE_{PORT,HOST,TOKEN,REPO}`. |
| 54 | +- **Endpoints:** |
| 55 | + - `GET /api/meta` → `{ workspace, name, writable, tokenRequired }` |
| 56 | + - `GET /api/issues` → parses `.beads/issues.jsonl` (full records **incl. |
| 57 | + dependencies** — that's why we read the JSONL, not `bd list --json` which |
| 58 | + omits deps). |
| 59 | + - `GET /api/docs` → discovered markdown (see below). |
| 60 | + - `GET /api/doc?path=` → raw markdown; path validated against traversal + allowed roots. |
| 61 | + - `GET /api/comments?id=` → `bd comments <id> --json`. |
| 62 | + - `POST /api/comment {id,text}` → `bd comment <id> <text>`, returns refreshed comments. |
| 63 | + - `POST /api/quick {title,description?,label?,priority?}` → `bd create --silent …`, |
| 64 | + then **`bd export -o .beads/issues.jsonl`** to refresh the list (the bare |
| 65 | + `bd export` goes to stdout — must pass `-o`). |
| 66 | +- **Docs discovery:** if `docRoots` is configured, use it; else auto-discover all |
| 67 | + `*.md` under the workspace, grouped by top-level dir (skipping `node_modules`, |
| 68 | + `.git`, `.next`, `db`, etc.). The `.planning` dir is allowed despite the leading dot. |
| 69 | +- **Security:** writes are token-gated **only when** a `token` is configured (env or |
| 70 | + config); otherwise open. Default host is `127.0.0.1`; opening it to LAN/tailnet |
| 71 | + should be explicit and should usually be paired with a token. Static responses |
| 72 | + send `cache-control: no-cache` so edits show on refresh. |
| 73 | + |
| 74 | +## Frontend (public/app.js) |
| 75 | + |
| 76 | +- Reads the three GET endpoints; renders the **Beads** view (filter/sort by |
| 77 | + status/priority/type/label, search, group-by-epic, ready-only) and **Docs** view. |
| 78 | +- **Derived issue state** is computed client-side from `dependencies[]`: |
| 79 | + `parent-child` → parent/children; other types → blocked-by/blocks; an open issue |
| 80 | + with unresolved blockers shows as **blocked**; open + none = **ready**. |
| 81 | +- **Comments + quick capture** call the POST endpoints (`apiPost`, token-aware via |
| 82 | + `localStorage` `bd_token`). Quick capture is bound to the `i` key. |
| 83 | +- **Themes:** 10 palettes via `[data-theme]` (Dark default + Light, GitHub Light, |
| 84 | + Solarized L/D, Nord, Dracula, Gruvbox, Tokyo Night, Catppuccin). A `<head>` |
| 85 | + script applies the saved/`prefers-color-scheme` theme before paint. Badges derive |
| 86 | + fills from theme hues via `color-mix()` so they adapt to light + dark — **do not |
| 87 | + reintroduce hardcoded badge hex.** |
| 88 | +- **Docs tree:** plain block list (single scroll container = `.filters`; a nested |
| 89 | + flex+overflow collapsed it before — keep it block). Root-level docs render bare at |
| 90 | + the top; other folders are collapsible (`state.collapsedGroups`, persisted). |
| 91 | +- Compact inline markdown renderer (headings/code/lists/tables/blockquote/inline) — |
| 92 | + no external markdown lib (keeps zero-dep). |
| 93 | +- Responsive: below 820px the multi-pane layout collapses to one pane with an |
| 94 | + off-canvas filters drawer and back buttons. |
| 95 | + |
| 96 | +## Current state (2026-06-13) |
| 97 | + |
| 98 | +Shipped: viewer + relationships, comments (read/add), quick capture, 10-theme |
| 99 | +engine + switcher, collapsible/top-anchored docs tree, responsive, injection-safe |
| 100 | +writes, optional token. Verified against real beads-backed repos. |
| 101 | + |
| 102 | +## Natural next steps (not built) |
| 103 | + |
| 104 | +- **Inline edits** from the detail panel: status (claim/close/reopen/defer), |
| 105 | + priority, labels, dependencies — via `bd update`/`dep`/`label`. This is the |
| 106 | + highest-value next feature (turns it into full triage). |
| 107 | +- **Planning board** (kanban by status/epic, add child issues). |
| 108 | +- **Doc-anchored ideas** (select text in a doc → `bd q` with a `doc:<path>` label). |
| 109 | +- **Distribution:** publish to npm / a public GitHub repo; optional Docker image |
| 110 | + (would need `bd` in the image + the target repo mounted). |
| 111 | +- A reboot-durable service wrapper (systemd / compose) — currently a backgrounded |
| 112 | + process. |
| 113 | + |
| 114 | +## Gotchas |
| 115 | + |
| 116 | +- `bd export` defaults to **stdout**; use `-o <file>` to write `issues.jsonl`. |
| 117 | +- Comments are read **live** via `bd comments --json` (always fresh); the issue |
| 118 | + list is the JSONL export (refreshed after quick-capture). |
| 119 | +- This tool is the successor to an earlier in-repo console (unthemed, no |
| 120 | + interactivity); this standalone repo is now the maintained version. |
| 121 | +- For release or packaging work, run `npm run check`, `npm run smoke`, and |
| 122 | + `npm_config_cache=/tmp/bd-console-npm-cache npm pack --dry-run`. |
| 123 | + |
| 124 | +## Agent workflow for bd-console |
| 125 | + |
| 126 | +When working on this repo, assume other repos may eventually install and rely on |
| 127 | +the patterns established here. |
| 128 | + |
| 129 | +- If you change beads issue data through raw `bd` commands outside the |
| 130 | + dashboard, refresh the export with `bd export -o .beads/issues.jsonl`. |
| 131 | +- The dashboard currently refreshes export after quick capture, but not every |
| 132 | + future write path exists yet. Keep export freshness explicit in any new beads |
| 133 | + mutation you add. |
| 134 | +- Treat `triage` as the default inbox label for captured ideas. |
| 135 | +- If an idea comes from a specific document, preserve provenance with a |
| 136 | + `doc:<path>` label until the UI grows first-class doc-anchored capture. |
| 137 | +- For setup work, prefer localhost binding and explicit tokens before telling |
| 138 | + users to expose the dashboard to a network. |
| 139 | +- Before telling a user the tool is ready, verify both: |
| 140 | + - `bd-console` starts against the intended repo |
| 141 | + - `http://localhost:<port>` or the configured host/port actually loads |
| 142 | +- If you update install or agent conventions here, mirror the same operational |
| 143 | + guidance in `README.md`, `AGENTS.md`, and `CLAUDE.md` together. |
| 144 | +- Keep the beginner path working: clone or global install, run `bd-console-init`, |
| 145 | + then start `bd-console` without requiring the user to infer missing steps. |
| 146 | + |
| 147 | +<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:7510c1e2 --> |
| 148 | +## Beads Issue Tracker |
| 149 | + |
| 150 | +This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands. |
| 151 | + |
| 152 | +### Quick Reference |
| 153 | + |
| 154 | +```bash |
| 155 | +bd ready # Find available work |
| 156 | +bd show <id> # View issue details |
| 157 | +bd update <id> --claim # Claim work |
| 158 | +bd close <id> # Complete work |
| 159 | +``` |
| 160 | + |
| 161 | +### Rules |
| 162 | + |
| 163 | +- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists |
| 164 | +- Run `bd prime` for detailed command reference and session close protocol |
| 165 | +- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files |
| 166 | + |
| 167 | +**Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns. |
| 168 | + |
| 169 | +## Session Completion |
| 170 | + |
| 171 | +**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds. |
| 172 | + |
| 173 | +**MANDATORY WORKFLOW:** |
| 174 | + |
| 175 | +1. **File issues for remaining work** - Create issues for anything that needs follow-up |
| 176 | +2. **Run quality gates** (if code changed) - Tests, linters, builds |
| 177 | +3. **Update issue status** - Close finished work, update in-progress items |
| 178 | +4. **PUSH TO REMOTE** - This is MANDATORY: |
| 179 | + ```bash |
| 180 | + git pull --rebase |
| 181 | + git push |
| 182 | + git status # MUST show "up to date with origin" |
| 183 | + ``` |
| 184 | +5. **Clean up** - Clear stashes, prune remote branches |
| 185 | +6. **Verify** - All changes committed AND pushed |
| 186 | +7. **Hand off** - Provide context for next session |
| 187 | + |
| 188 | +**CRITICAL RULES:** |
| 189 | +- Work is NOT complete until `git push` succeeds |
| 190 | +- NEVER stop before pushing - that leaves work stranded locally |
| 191 | +- NEVER say "ready to push when you are" - YOU must push |
| 192 | +- If push fails, resolve and retry until it succeeds |
| 193 | +<!-- END BEADS INTEGRATION --> |
0 commit comments