原始内容
tandem (tndm)
Git-aware ticket coordination for AI agents in a monorepo.
Store ticket state in your repository. Coordinate work across branches and git worktrees.
No central service. No background process. Just tndm.
- Why tandem?
- Core capabilities
- Quick install
- CLI design
- On-disk ticket model
- Quick tour
- JSON / API design
- Architecture at a glance
- PI extension
- Project status
- Documentation
- Getting help
- Contributing
- License
Why tandem?
When multiple AI agents work in the same repo, they step on each other.
tandem gives every agent a shared, deterministic view of what tickets exist,
what each ticket contains, and how work has diverged across branches or worktrees
without leaving Git.
The public interface today is the tndm CLI plus its structured JSON output.
The Rust workspace crates are layered internal implementation modules, not a separate
stable end-user API.
Core capabilities
tandem currently provides:
- Repo-local ticket lifecycle — create, list, show, update, and organize tickets under
.tndm/. - Structured ticket metadata — status, priority, type, effort, dependencies, tags, revision, and timestamps.
- Document registry — tickets own registered markdown documents, not just one blob of inline text.
- Freshness verification — SHA-256 document fingerprints in
state.toml;tndm ticket syncandtndm fmt --checkcatch stale ticket docs. - Task manifests — store ordered tasks directly in
state.tomlwith per-task files, verification notes, and optional linked detail docs. - Task detail docs —
tndm ticket task detail ensurecreates and links canonicaltasks/task-XX.mddocs for existing tasks. - Git-aware awareness — compare the current working tree against another ref or worktree with
tndm awareness --against <ref>. - Deterministic CLI + JSON — human-readable terminal output for oversight and schema-versioned JSON for agents.
- Low operational overhead — no database, no daemon, no web service, no LLM dependency.
- Repo-local defaults — optional
.tndm/config.tomlconfig for ID prefix generation and default ticket content templates.
Quick install
# Prebuilt binary (macOS / Linux)
curl -LsSf \
https://github.com/mrclrchtr/tandem/releases/latest/download/tndm-installer.sh | sh
# Homebrew
brew install mrclrchtr/tap/tandem-cli
# From source
cargo install --path crates/tandem-cli
CLI design
Top-level commands:
| Command | Purpose |
|---|---|
tndm fmt |
Canonicalize .tndm/ files; use --check in CI or pre-commit style workflows |
tndm ticket ... |
Create, inspect, update, sync, and organize tickets |
tndm awareness --against <ref> |
Compare the current ticket snapshot against another git ref |
Ticket subcommands:
| Command | Purpose |
|---|---|
tndm ticket create |
Create a ticket with optional --status, --priority, --type, --effort, --tags, --depends-on, --content, or --content-file |
tndm ticket show |
Render a formatted ticket for humans or emit JSON with --json |
tndm ticket list |
List active tickets; supports --all and --definition ready|questions|unknown |
tndm ticket update |
Update metadata, content, tags, dependencies, and effort |
tndm ticket doc create |
Create and register a new ticket-local markdown document |
tndm ticket sync |
Recompute registered document fingerprints after file edits |
tndm ticket task ... |
Manage task manifests stored in state.toml |
Task subcommands:
| Command | Purpose |
|---|---|
tndm ticket task add |
Add a numbered task with optional linked detail doc |
tndm ticket task list |
List tasks in table form or as JSON |
tndm ticket task complete |
Mark a task as done |
tndm ticket task remove |
Remove a task |
tndm ticket task edit |
Change task title or detail linkage |
tndm ticket task set |
Bulk-replace the entire task list from a JSON array |
tndm ticket task detail ensure |
Ensure the canonical tasks/task-XX.md detail doc exists and is linked |
Design notes from the current source:
- Most end-user commands support
--jsonfor deterministic machine consumption. - New ticket content can come from
--content-file,--content, stdin, or the configured/default markdown template. .tndm/config.tomlcan set[id].prefix, which drives generated IDs and bare-ID normalization for several commands.tndm ticket showis human-first in a TTY: it renders Markdown content, colors status, and syntax-highlights fenced code blocks when possible.
On-disk ticket model
Each ticket lives in its own directory:
.tndm/
├── config.toml # optional repo-wide tandem config
└── tickets/
└── TNDM-A1B2C3/
├── meta.toml # stable metadata
├── state.toml # volatile state + task manifest
├── content.md # default ticket body (registered as document "content")
├── plan.md # optional registered document
└── tasks/
└── task-01.md # optional canonical task detail doc
The source splits ticket data deliberately:
meta.tomlstores relatively stable metadata such asid,title,type,priority,effort,depends_on,tags, and the registereddocumentslist.state.tomlstores more volatile state such asstatus,updated_at,revision,document_fingerprints, andtasks.content.mdis the default markdown document for a ticket and is automatically registered as documentcontent.
Example optional config:
[id]
prefix = "TNDM"
[templates]
content = """
## Context
...
"""
Document registry rules that matter in practice:
- Additional docs should be created through
tndm ticket doc create, not by inventing unregistered files by hand. - Registered doc paths are ticket-relative and validated; absolute paths and
..traversal are rejected. - After editing any registered document on disk, run
tndm ticket sync <ID>. tndm fmt --checkfails when canonical formatting or document fingerprints drift.- Task detail docs are manifest-first: tasks live in
state.toml, and detail docs are optional attachments linked to existing tasks.
Quick tour
# Create a ticket with structured metadata
tndm ticket create "Refresh README overview" \
--type chore \
--priority p2 \
--status in_progress \
--tags docs,definition:ready \
--effort s
# → TNDM-A1B2C3
# Add a registered plan document and edit it with your normal editor
tndm ticket doc create TNDM-A1B2C3 plan
# → .tndm/tickets/TNDM-A1B2C3/plan.md
# Add an executable task manifest entry (rich metadata goes in the detail doc)
tndm ticket task add TNDM-A1B2C3 \
--title "Rewrite README capabilities section"
# If the task needs its own attachment, ensure the canonical detail doc exists
tndm ticket task detail ensure TNDM-A1B2C3 1
# → .tndm/tickets/TNDM-A1B2C3/tasks/task-01.md
# After editing any registered doc file on disk, refresh fingerprints
tndm ticket sync TNDM-A1B2C3
# Review the ticket for humans or machines
tndm ticket show TNDM-A1B2C3
tndm ticket show TNDM-A1B2C3 --json
# Filter list output by current definition state
tndm ticket list --definition ready
# Compare ticket changes against another branch or worktree
tndm awareness --against branch-a --json
# Keep canonical formatting and fingerprints clean in CI
tndm fmt --check
JSON / API design
The current machine-facing API is the CLI's JSON output.
tndm ticket show --jsonreturns a schema-versioned ticket envelope that flattens metadata and state and includescontent_path.tndm ticket list --jsonreturns{ "schema_version": 1, "tickets": [...] }.tndm ticket task list --jsonreturns a bare JSON array of tasks.tndm awareness --jsonreturns a schema-versioned change report keyed byagainstandtickets.
Example ticket show --json shape:
{
"schema_version": 1,
"id": "TNDM-A1B2C3",
"title": "Refresh README overview",
"type": "chore",
"priority": "p2",
"effort": "s",
"depends_on": [],
"tags": ["definition:ready", "docs"],
"documents": [
{ "name": "content", "path": "content.md" },
{ "name": "task-01", "path": "tasks/task-01.md" }
],
"status": "in_progress",
"updated_at": "2026-05-20T22:02:43.273163Z",
"revision": 3,
"document_fingerprints": {
"content": "sha256:...",
"task-01": "sha256:..."
},
"tasks": [
{
"number": 1,
"title": "Rewrite README capabilities section",
"status": "todo"
}
],
"content_path": ".tndm/tickets/TNDM-A1B2C3/content.md"
}
Example awareness diff shape:
{
"schema_version": 1,
"against": "HEAD",
"tickets": [
{
"id": "TNDM-A1B2C3",
"change": "diverged",
"fields": {
"status": { "current": "in_progress", "against": "todo" },
"tags": {
"current": ["definition:ready", "docs"],
"against": []
},
"documents": [
{ "name": "task-01", "current": "sha256:...", "against": "" }
],
"tasks": {
"current": [
{
"number": 1,
"title": "Rewrite README capabilities section",
"status": "todo"
}
],
"against": []
}
}
}
]
}
Awareness diffs currently report field-level changes for:
- status
- priority
- effort
- title
- type
- depends_on
- tags
- document fingerprints
- tasks
Architecture at a glance
This repo is a Rust workspace with strict dependency boundaries:
crates/tandem-core— domain types, validation, and ports; must remain IO-freecrates/tandem-storage— filesystem-backed ticket storage and fingerprint handlingcrates/tandem-repo— git/worktree awareness adaptercrates/tandem-cli— the only CLI crate; producestndmcrates/xtask— developer tooling and architecture checksplugins/supi-flow— PI extension for spec-driven workflows built on top of TNDM tickets
See docs/architecture.md for the enforced dependency rules.
PI extension
plugins/supi-flow/ is a PI extension that layers a spec-driven
workflow on top of tandem tickets: brainstorm → plan → apply → archive.
It ships with:
- 6 custom PI tools:
supi_tndm_cli,supi_flow_start,supi_flow_plan,supi_flow_task,supi_flow_complete_task,supi_flow_close - 5 auto-discovered skills
- 1 prompt template
Install from npm:
pi install npm:@mrclrchtr/supi-flow
Project status
tandem is pre-1.0 and under active development.
- The CLI, document registry, task workflow, and awareness features work today.
- The on-disk format and JSON surface are intentionally deterministic.
- The user-facing contract is still centered on the CLI; deeper library APIs may continue to evolve before 1.0.
Documentation
| Doc | What you'll find |
|---|---|
docs/vision.md |
Product goals, workflows, and V1 scope |
docs/architecture.md |
Workspace structure and enforced dependency rules |
docs/decisions.md |
Design rationale and storage / awareness decisions |
docs/references.md |
Competitive analysis and related projects |
docs/releasing.md |
Release process and automation |
CHANGELOG.md |
Release history |
Getting help
- Bug reports / feature requests — open a GitHub issue
- Questions / discussion — start a GitHub discussion
- CLI help —
tndm --helpfor the full command reference
Contributing
tandem is a Rust workspace managed with mise.
mise install # install toolchains
mise run test # run the test suite
mise run check # fmt + compile + arch + clippy
See docs/architecture.md for development conventions and
docs/releasing.md for the release process.
License
tandem is licensed under Apache 2.0.