| name | scope |
| description | Plan, track, and report on multi-step work using the Scope kanban (local CLI + web UI). Use when the user asks you to scope/plan a project, list open work, mark a ticket done, link a branch/PR, or coordinate with other agents on shared state. Don't use for one-off questions or trivial single-edit requests. |
Using Scope
Scope is a local-first kanban for epics, stories, and bugs. It ships as a
CLI, a GitHub-Projects-style web UI, and a scope serve hub daemon. Use it
to plan, track, and report on multi-step work without leaving the terminal.
When to use
Reach for Scope when:
- The user describes a multi-step task ("rebuild auth", "ship feature X") that
spans more than a single tool call. Create an epic plus child stories
and walk through them.
- The user starts a session and wants context. List open tickets in the
current workspace before diving in.
- You finish a discrete piece of work. Mark the relevant ticket done and
attach the branch / PR if there was one.
- You discover a real bug worth tracking (not a fix you just made). Create a
bug ticket with enough description that someone else could reproduce it.
Don't use Scope for one-off questions or trivial single-edit requests — the
overhead isn't worth it.
How to access
Shell out to the scope CLI. Every command supports --json for parseable
output:
scope --json ticket list
scope --json ticket show MA-3
scope --json meta
If the CLI isn't installed:
brew install briannadoubt/tap/scope
Data model
- Hub — the
scope serve daemon. Brokers traffic across workspaces.
- Workspace — a
.scope/ directory. Owns the key prefix (MA), name,
description, overview, and all tickets in that repo. One SQLite DB per
workspace.
- Epic — high-level body of work. Holds stories and bugs as children.
- Story — a unit of work toward an epic.
- Bug — a defect; can also live under an epic.
- Relation —
blocks, blocked_by, relates_to, duplicates,
duplicate_of. The inverse is created automatically.
- Status —
backlog → todo → in_progress → in_review → done
(+ cancelled). The board has one column per status.
- Priority —
low / medium / high / urgent.
Ticket IDs look like MA-3 (workspace key + number) and are immutable.
Branches and PR URLs can be attached to any ticket and are surfaced in the UI.
Common operations
scope init --key MA --name "My App"
scope workspace set --description "Short description"
scope auth login
scope connect
scope workspace show
scope ticket create "Auth refactor" -t epic -p high
scope ticket create "OAuth login" -t story --parent MA-1
scope ticket create "Password reset broken on Safari" -t bug --parent MA-1 -p high
scope branch MA-2 feat/oauth --in-progress
scope pr MA-2 https://github.com/owner/repo/pull/42 --in-review
scope status MA-2 done --by you
scope board
scope --json ticket show MA-2
scope comment MA-2 "Token expiry was 5min; bumped to 1h" --by you
scope link add MA-2 blocked_by MA-7
Bulk & structural changes — never edit scope.db directly
scope.db is a rebuildable cache of the event log. Editing it with sqlite3
writes no event, so the change is silently lost on the next cache rebuild (and
corrupts merges). Every mutation has a command — use them:
scope workspace set --name "New Name"
scope workspace rekey APP
scope ticket edit MA-7 --parent MA-1
scope status MA-2,MA-3 done --by you
scope ticket edit MA-2,MA-3 --priority high
echo '[
{"op":"create","ref":"e","type":"epic","title":"Billing"},
{"op":"create","type":"story","title":"Invoices","parent":"$e"},
{"op":"status","id":"MA-9","status":"done"}
]' | scope batch --by you
Batch ops: create (optional ref), update {id,fields}, status {id,status},
delete {id}, comment {id,body}, link/unlink {from,type,to}, workspace {fields}. If a command for what you need seems missing, ask for it to be added —
never fall back to SQL.
Version control and storage
Scope is event-sourced. New workspaces default to quiet machine-local storage:
the append-only event log and scope.db cache live under
~/.scope/workspaces/<id>/, while the repo carries .scope/workspace.json and
optional .scope/remote.json. Commit those marker/config files; credentials
stay machine-local.
Git-carried events are an explicit advanced mode (scope init --git-events or
scope events move-to-git). Only in that mode should .scope/events/ be
committed. scope.db* is always a rebuildable cache and must never be
committed. Use scope events status, scope events move-to-local, and
scope remote show when storage or cloud sync is unclear.
In git-events mode, verify with
git check-ignore -v .scope/events/ .scope/scope.db — events/ should be NOT
ignored and scope.db should be ignored. In quiet local mode, events/ is
intentionally ignored because the authoritative log is under ~/.scope/.
Guardrails
- Don't change a workspace's key without an explicit human request. When
asked, use
scope workspace rekey <KEY> (reprefixes every ticket atomically
via the log); avoid set --key, which strands existing tickets under the old
prefix. Adding tickets, comments, and statuses is always fine.
- Don't delete tickets to "clean up." Set status to
cancelled so history
is preserved and the audit log makes sense.
- Keep titles human-readable. A title is what shows up on the kanban card
and in stand-ups. Implementation details go in the description.
- Update status as work happens, not all at once at the end. The point of
this thing is for the user (and other agents) to see live progress.
- Use
--by <name> on status changes / edits so the history shows who
touched what. For agents, your own name or "agent" is fine.
Realtime + multi-agent
If the user runs scope serve somewhere, the web UI comes up at
https://localhost:4321 and every scope CLI call (yours, the user's,
another agent's) pushes to all viewers via SSE within ~100ms. Never pass
--port unless you're explicitly told to — concurrent scope serve
invocations auto-discover the running hub and register their workspace with
it.
If multiple agents are working in parallel, always read state before writing
state — there is no merge logic for conflicting ticket edit calls, last
write wins.
Claude Code preview pane setup
For Claude Code's preview pane, .claude/launch.json must use
scope preview --port <unique>, not scope serve. preview_start
enforces one tracked server per port — if two projects both register
port: 4321 (the hub), opening the preview in the second pane stops the
first pane's tracked process and the iframe shows "The preview server
stopped." scope preview is a tiny per-pane reverse proxy: each project
picks its own port (4322, 4323, ...) and forwards to the shared hub on 4321.
{
"version": "0.0.1",
"configurations": [
{
"name": "scope-myproject",
"runtimeExecutable": "scope",
"runtimeArgs": ["preview", "--port", "4322"],
"port": 4322,
"autoPort": false
}
]
}
Useful follow-ups
scope --json epic list to see epic progress at a glance.
scope --json ticket list --status todo to find the next thing to do.
scope --json board returns columns + buckets for rendering.
scope history MA-2 is the change log for a single ticket.
Repo