### Install Development Tools
Source: https://github.com/mrclrchtr/tandem/blob/main/README.md
Installs all necessary development tools managed by 'mise'. Ensure 'mise' is installed and configured.
```sh
mise install
```
--------------------------------
### Install and Run Development Tools
Source: https://github.com/mrclrchtr/tandem/blob/main/CLAUDE.md
Installs necessary development tools using mise and then runs a pre-commit hook installation. Use this to set up your environment.
```sh
mise install
mise run hooks-install
```
--------------------------------
### Install Tandem CLI (Prebuilt Binaries)
Source: https://github.com/mrclrchtr/tandem/blob/main/README.md
Installs the tandem CLI using a script from GitHub Releases. Ensure you have curl installed.
```sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mrclrchtr/tandem/releases/latest/download/tndm-installer.sh | sh
```
--------------------------------
### Repository Configuration Example
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/references/command-reference.md
Example TOML configuration for a Tandem repository, including schema version and template settings.
```toml
schema_version = 1
[id]
prefix = "TNDM"
[templates]
content = """
## Context
## Goal
## Open Questions
- [ ] Question or ambiguity 1
- [ ] Question or ambiguity 2
## Acceptance
- [ ] Observable outcome 1
- [ ] Observable outcome 2
## Ready When
- [ ] Scope is clear
- [ ] Dependencies are known
- [ ] Open questions are resolved or explicitly deferred
- [ ] Acceptance is specific enough for implementation
"""
```
--------------------------------
### Awareness MVP Command Examples
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-07-awareness-mvp-design.md
Examples of how to invoke the awareness MVP command with different Git references.
```sh
tndm awareness --against main
```
```sh
tndm awareness --against origin/main
```
--------------------------------
### Example meta.toml File Content
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Provides an example of the content for a ticket's `meta.toml` file, including stable metadata.
```toml
schema_version = 1
id = "TNDM-A1B2C3"
title = "Implement rate limiting"
type = "feature"
priority = "p1"
effort = "l"
depends_on = ["TNDM-B2C3D4"]
tags = ["auth", "backend", "definition:ready"]
```
--------------------------------
### Example state.toml File Content
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Provides an example of the content for a ticket's `state.toml` file, showing volatile state information.
```toml
schema_version = 1
status = "in_progress"
updated_at = "2026-03-09T10:00:00Z"
revision = 3
```
--------------------------------
### Install Tandem CLI (Development)
Source: https://github.com/mrclrchtr/tandem/blob/main/README.md
Installs the tandem CLI from the local source code for development purposes. Requires Rust and Cargo.
```sh
cargo install --path crates/tandem-cli
```
--------------------------------
### Test Bash Completion Setup Script
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-27-shell-completion.md
This test verifies that the `tndm` binary, when configured with `COMPLETE=bash`, generates a valid bash setup script. It checks for the binary name and the presence of the 'complete' builtin command in the output.
```rust
#![allow(clippy::disallowed_types)]
use std::process::Command;
#[test]
fn complete_env_produces_bash_setup_script() {
let output = Command::new(env!("CARGO_BIN_EXE_tndm"))
.env("COMPLETE", "bash")
.output()
.expect("run tndm with COMPLETE=bash");
assert!(
output.status.success(),
"expected success, stderr was: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout).expect("stdout should be UTF-8");
assert!(
stdout.contains("tndm"),
"bash setup script should reference the binary name, got: {stdout:?}"
);
assert!(
stdout.contains("complete"),
"bash setup script should contain a 'complete' builtin call, got: {stdout:?}"
);
}
```
--------------------------------
### Tandem Repository Configuration Example
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Example TOML configuration file for Tandem. Customize ticket ID prefixes and default content templates.
```toml
# .tndm/config.toml
schema_version = 1
[id]
prefix = "PROJ" # Ticket IDs will be PROJ-XXXXXX instead of TNDM-XXXXXX
[templates]
content = """
## Context
## Goal
## Open Questions
- [ ] Question or ambiguity 1
## Acceptance
- [ ] Observable outcome 1
## Ready When
- [ ] Scope is clear
- [ ] Dependencies are known
- [ ] Open questions are resolved or explicitly deferred
- [ ] Acceptance is specific enough for implementation
"""
```
--------------------------------
### Ticket File Structure Example
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/references/command-reference.md
Illustrates the directory structure for a single ticket, including meta.toml, state.toml, and content.md.
```text
.tndm/tickets/TNDM-XXXXXX/
├── meta.toml # stable metadata: id, title, type, priority, effort (optional), tags, depends_on
├── state.toml # volatile state: status, revision, updated_at
└── content.md # freeform markdown body (optional — set via heredoc, --content, or --content-file)
```
--------------------------------
### Example Canonical meta.toml Structure
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Illustrates the expected structure and fields for a canonical `meta.toml` file.
```toml
schema_version = 1
id = "TNDM-A1B2C3"
title = "Refactor auth module"
type = "task"
priority = "p2"
effort = "m"
depends_on = ["TNDM-B2C3D4"]
tags = ["auth", "backend"]
```
--------------------------------
### Example Canonical state.toml Structure
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Illustrates the expected structure and fields for a canonical `state.toml` file.
```toml
schema_version = 1
status = "in_progress"
updated_at = "2026-03-09T10:00:00Z"
revision = 2
```
--------------------------------
### Install Git Hooks
Source: https://github.com/mrclrchtr/tandem/blob/main/README.md
Installs git hooks managed by 'hk'. This ensures hooks run within the 'mise'-managed tool environment.
```sh
mise run hooks-install
```
--------------------------------
### Example Awareness Checks
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/awareness/SKILL.md
Demonstrates running awareness checks against a local branch and a remote feature branch. These commands help in understanding the state of work before branching or merging.
```sh
# Check what the main branch has before branching off
tndm awareness --against main --json
# Check a remote feature branch
tndm awareness --against origin/feature-payments --json
```
--------------------------------
### Agent: Pick Next Ready Ticket
Source: https://context7.com/mrclrchtr/tandem/llms.txt
An example of how an agent can use `tndm ticket list --definition ready --json` piped to `jq` to select the first 'todo' ticket.
```sh
tndm ticket list --definition ready --json \
| jq 'first(.tickets[] | select(.status == "todo"))'
```
--------------------------------
### Update SKILL.md Create Section
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-create-metadata-flags.md
Shows examples of creating tickets with various metadata flags like priority, type, tags, and dependencies. Also demonstrates creating tickets with an optional content body using a heredoc.
```sh
# Minimal — auto-generates ID, defaults to todo/p2/task
tndm ticket create "
"
# With metadata flags (set priority, type, tags, deps at creation)
tndm ticket create "Fix login timeout" \
--priority p1 --type bug --tags auth,security \
--depends-on TNDM-AAAAAA,TNDM-BBBBBB
# Start as in_progress in one command (no separate update needed)
tndm ticket create "Urgent hotfix" \
--status in_progress --priority p0 --type bug
```
```sh
tndm ticket create "Implement OAuth flow" <<'EOF'
## Description
Add OAuth 2.0 authorization code flow.
## Acceptance
- Users can sign in with Google
EOF
```
--------------------------------
### Example `tndm ticket list` output format
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
Demonstrates the expected tab-separated output format for the `tndm ticket list` command, including ticket ID, status, and title.
```text
TNDM-4K7D9Q todo Add foo
```
--------------------------------
### Update command-reference.md Create Section
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-create-metadata-flags.md
Documents the `tndm ticket create` command, detailing its options for setting ID, status, priority, type, tags, dependencies, and content. Includes examples for minimal creation, with metadata, explicit ID, and content via heredoc or file.
```sh
tndm ticket create [OPTIONS]
Options:
--id Explicit ticket ID (e.g. TNDM-A1B2C3). Auto-generated if omitted.
-s, --status Initial status. Values: todo | in_progress | blocked | done
-p, --priority Initial priority. Values: p0 | p1 | p2 | p3 | p4
-T, --type Initial type. Values: task | bug | feature | chore | epic
-g, --tags Comma-separated tags.
-d, --depends-on Comma-separated ticket IDs for dependencies.
--content Inline content body.
--content-file Load ticket body from a markdown file.
--json Output the created ticket as JSON.
Content can also be piped via stdin (heredoc recommended for agents).
--content, --content-file, and stdin are mutually exclusive.
```
```sh
# Minimal — auto-generates ID
tndm ticket create "Refactor auth module"
# With metadata — set everything at creation
tndm ticket create "Fix login timeout" \
--priority p1 --type bug --tags auth,security \
--depends-on TNDM-B2C3D4 --status in_progress
# With explicit ID
tndm ticket create "Fix login redirect" --id TNDM-FIX001
# With content via heredoc (preferred for agents — no temp files needed)
tndm ticket create "Implement OAuth flow" --type feature <<'EOF'
## Description
Add OAuth 2.0 authorization code flow.
EOF
# With content from file (when content already exists on disk)
tndm ticket create "Implement OAuth flow" --content-file /tmp/ticket-body.md
```
--------------------------------
### Single Ticket JSON Output Example
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-17-json-output-design.md
This is the JSON structure used for single ticket output by commands like `show`, `create`, and `update`. It includes metadata and a content path.
```json
{
"schema_version": 1,
"id": "TNDM-ABC123",
"title": "Refactor auth module",
"type": "task",
"priority": "p2",
"status": "todo",
"updated_at": "2026-03-17T13:32:22Z",
"revision": 1,
"depends_on": [],
"tags": [],
"content_path": ".tndm/tickets/TNDM-ABC123/content.md"
}
```
--------------------------------
### Example Ticket List Plain Text Output
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-04-01-effort-and-dependencies-in-ticket-list-design.md
Illustrates the plain text output format for the `tndm ticket list` command, including the new `EFFORT` and `DEPS` columns. Effort is shown as a lowercase string or a hyphen, and dependencies are comma-separated.
```text
TNDM-A1B2C3 todo p1 m TNDM-X1, TNDM-Y2 Fix login timeout
TNDM-D4E5F6 in_progress p2 - Refactor auth module
```
--------------------------------
### Filter Tickets by Priority using jq
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/SKILL.md
This example demonstrates how to use `jq` to filter tickets based on their priority. It selects tickets with either 'p0' or 'p1' priority.
```bash
tndm ticket list --json | jq '[.tickets[] | select(.priority == "p0" or .priority == "p1")]'
```
--------------------------------
### Awareness MVP Diverged Ticket Example
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-07-awareness-mvp-design.md
An example of a 'diverged' ticket in the awareness MVP output, showing differences in specific fields like 'status' and 'depends_on'.
```json
{
"id": "TNDM-AAAAAA",
"change": "diverged",
"fields": {
"status": {
"current": "in_progress",
"against": "todo"
},
"depends_on": {
"current": ["TNDM-000001"],
"against": []
}
}
}
```
--------------------------------
### Run Full Test Suite
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-17-json-output.md
Execute the complete test suite to verify all functionalities. Ensure all tests pass.
```bash
cargo test
```
--------------------------------
### Check for Diverged Tickets in Agent Workflow
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Use this to identify tickets that have diverged between branches before starting work. It requires jq to parse JSON output.
```bash
AWARENESS=$(tndm awareness --against main --json)
CONFLICTS=$(echo "$AWARENESS" | jq '[.tickets[] | select(.change == "diverged")]')
echo "Diverged tickets: $(echo "$CONFLICTS" | jq length)"
```
--------------------------------
### Check awareness of changes on another branch
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/vision.md
Before starting work, query for tickets and changes made on a specific branch to avoid conflicts. The output is in JSON format.
```bash
tndm awareness --against branch-a
```
--------------------------------
### Run Tandem CLI in Development
Source: https://github.com/mrclrchtr/tandem/blob/main/README.md
Executes the tandem CLI binary generated during development. Use '--help' for command options.
```sh
./tndm-dev --help
```
```sh
./tndm-dev ticket list
```
```sh
./tndm-dev ticket list --definition ready
```
--------------------------------
### Update CLI Arguments for Awareness Tests
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-17-json-output.md
These examples show how to modify existing test cases in `awareness_cli_tests.rs` to include the `--json` flag when calling the `awareness` command.
```bash
// Change:
.args(["awareness", "--against", "HEAD"])
// To:
.args(["awareness", "--against", "HEAD", "--json"])
```
```bash
// Change:
.args(["awareness", "--against", "HEAD"])
// To:
.args(["awareness", "--against", "HEAD", "--json"])
```
--------------------------------
### Configure Shell Completion Script (Fish)
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-27-shell-completion-design.md
Add this line to your ~/.config/fish/config.fish to enable tndm shell completion for Fish.
```fish
source (COMPLETE=fish tndm | psub)
```
--------------------------------
### Run full repository checks
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Execute a comprehensive suite of checks from the repository root, including formatting, compilation, architecture, clippy, and tests.
```bash
cd "$(git rev-parse --show-toplevel)" && mise run check
```
--------------------------------
### Verify Version Sync with Grep
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-version-sync.md
Use `grep` to confirm that the `plugin.json` and `marketplace.json` files have been updated with the correct workspace version.
```bash
grep '"version"' plugin/tndm/.claude-plugin/plugin.json .claude-plugin/marketplace.json
```
--------------------------------
### Ticket List JSON Output Example
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-17-json-output-design.md
This JSON structure is used for the output of the `list` command when the `--json` flag is used. It contains an array of ticket objects.
```json
{
"schema_version": 1,
"tickets": [
{
"id": "TNDM-1",
"title": "...",
"type": "task",
"priority": "p2",
"status": "todo",
"updated_at": "...",
"revision": 1,
"depends_on": [],
"tags": [],
"content_path": ".tndm/tickets/TNDM-1/content.md"
}
]
}
```
--------------------------------
### Example Ticket ID Format
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-storage-design.md
V1 generates ticket IDs using a default prefix and a 6-character Crockford Base32 suffix. This format is designed to be offline and worktree-safe.
```text
TNDM-4K7D9Q
```
--------------------------------
### Verify TNDM Plugin Loading in Claude Code
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/README.md
After loading the plugin, run the `/help` command in Claude Code to verify that the tndm skills (`/tndm:awareness` and `/tndm:ticket`) are available.
```sh
/help
```
--------------------------------
### Scan for Awareness Data Between Branches
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Scans for changes on a target branch relative to the current branch. Useful for detecting conflicts or new work before starting a task. Requires jq.
```bash
# Before starting, scan what changed on feature-auth
AWARENESS=$(tndm awareness --against feature-auth --json)
ADDED=$(echo "$AWARENESS" | jq '[.tickets[] | select(.change == "added_against")]')
DIVERGED=$(echo "$AWARENESS" | jq '[.tickets[] | select(.change == "diverged")]')
echo "Tickets added on feature-auth: $(echo "$ADDED" | jq length)"
echo "Tickets diverged: $(echo "$DIVERGED" | jq length)"
```
--------------------------------
### Add `clap_complete::engine` Import
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-27-shell-completion.md
Imports necessary components from `clap_complete` for implementing custom argument value completers.
```rust
use clap_complete::engine::{ArgValueCompleter, CompletionCandidate};
```
--------------------------------
### Build and Execute Tandem CLI
Source: https://github.com/mrclrchtr/tandem/blob/main/CLAUDE.md
Builds the project and provides commands to interact with the tandem CLI. Use `./tndm-dev --help` for available options and `./tndm-dev ticket list` to list tickets.
```sh
cargo build
./tndm-dev --help
./tndm-dev ticket list
```
--------------------------------
### Run Formatting Check
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-17-json-output.md
Verify that the code adheres to the project's formatting standards. Expected output is no formatting issues.
```bash
mise run fmt
```
--------------------------------
### Filter Tickets by Status using jq
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/SKILL.md
Use `tndm ticket list --all --json` combined with `jq` to filter tickets based on their status. This example shows how to select tickets with the status 'done'.
```bash
tndm ticket list --all --json | jq '[.tickets[] | select(.status == "done")]'
```
```bash
tndm ticket list --json | jq '[.tickets[] | select(.status == "in_progress")]'
```
```bash
tndm ticket list --json | jq '[.tickets[] | select(.status == "blocked")]'
```
--------------------------------
### Create ticket with content body
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/SKILL.md
Create a ticket and include a detailed content body using a heredoc. Avoid creating temporary files for content.
```sh
tndm ticket create "Implement OAuth flow" <<'EOF'
## Context
Users need to sign in with Google.
## Goal
Support OAuth 2.0 authorization code flow.
## Acceptance
- Users can sign in with Google
EOF
```
--------------------------------
### Test FileTicketStore::create_ticket
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
This test verifies that `create_ticket` correctly writes meta, state, and content files to the specified directory structure. It sets up a temporary directory, initializes the `FileTicketStore`, creates a new ticket, and asserts the existence of the expected files.
```rust
#[test]
fn create_ticket_writes_expected_files() {
let dir = tempfile::tempdir().unwrap();
std::fs::create_dir_all(dir.path().join(".git")).unwrap();
let store = tandem_storage::FileTicketStore::new(dir.path().to_path_buf());
let id = tandem_core::ticket::TicketId::parse("TNDM-4K7D9Q").unwrap();
let meta = tandem_core::ticket::TicketMeta::new(id.clone(), "Add foo").unwrap();
let created = store
.create_ticket(tandem_core::ticket::NewTicket {
meta,
content: "Hello\n".to_string(),
})
.unwrap();
assert_eq!(created.meta.id.as_str(), "TNDM-4K7D9Q");
let base = dir
.path()
.join(".tndm/tickets/TNDM-4K7D9Q");
assert!(base.join("meta.toml").exists());
assert!(base.join("state.toml").exists());
assert!(base.join("content.md").exists());
}
```
--------------------------------
### Minimal TOML Parsing Struct
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
Example of a Rust struct for deserializing ticket metadata from a TOML file. It includes fields for schema version, ID, title, and optional metadata like type, priority, dependencies, and tags. Note the use of `#[serde(rename = "type")]` to handle the reserved keyword 'type'.
```rust
#[derive(serde::Deserialize)]
struct MetaFile {
schema_version: u32,
id: String,
title: String,
#[serde(rename = "type")]
kind: Option,
priority: Option,
#[serde(default)]
depends_on: Vec,
#[serde(default)]
tags: Vec,
}
```
--------------------------------
### Run Awareness MVP Command
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-07-awareness-mvp-design.md
Use this command to compare the current checkout's ticket state against a specified Git ref. The output is a deterministic JSON document.
```sh
tndm awareness --against [
```
--------------------------------
### Create ticket with metadata flags
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-30-create-metadata-flags-design.md
Use this command to create a new ticket and set its metadata, including priority, type, tags, dependencies, and status, in a single operation.
```sh
tndm ticket create "Fix login timeout" \
--priority p1 --type bug --tags auth,security \
--depends-on TNDM-AAAAAA,TNDM-BBBBBB --status in_progress
```
--------------------------------
### Annotate `Create` Command's `content_file` with `ValueHint::FilePath`
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-27-shell-completion.md
Adds `value_hint = ValueHint::FilePath` to the `content_file` argument in the `Create` ticket command, signaling to the shell that this argument expects a file path.
```rust
#[arg(long, conflicts_with = "content", value_hint = ValueHint::FilePath)]
content_file: Option,
```
--------------------------------
### Implement GitAwarenessProvider
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Implements the `GitAwarenessProvider` struct and its `new` constructor. This provider will handle materializing awareness snapshots from Git references.
```rust
pub struct GitAwarenessProvider { repo_root: PathBuf }
impl GitAwarenessProvider { pub fn new(repo_root: PathBuf) -> Self }
```
--------------------------------
### Repository Configuration File (.tndm/config.toml)
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-storage-design.md
This TOML file defines repository-local defaults, including the ID prefix and default content templates for new tickets. The `templates.content` field is treated as literal text in V1.
```toml
schema_version = 1
[id]
prefix = "TNDM"
[templates]
content = '''
## Description
## Design
## Acceptance
## Notes
'''
```
--------------------------------
### Build and Test Tandem CLI
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-04-01-effort-and-dependencies-in-ticket-list.md
Commands to build the project, run tests, and check for errors. Expected output for tests is 'ok. N passed; 0 failed'.
```bash
./tndm-dev ticket list
```
```bash
cargo build 2>&1 | tail -10
```
```bash
cargo test 2>&1 | tail -5
```
--------------------------------
### Create Temporary Workspace for Tests
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-version-sync.md
Helper function to set up a temporary directory with a Cargo.toml and JSON files for testing version synchronization logic.
```rust
#[cfg(test)]
mod sync_version_tests {
use std::fs;
use super::*;
fn create_temp_workspace(dir: &std::path::Path, version: &str) {
let cargo_toml = format!(
"[workspace.package]\nversion = \"{version}\"\n"
);
fs::write(dir.join("Cargo.toml"), cargo_toml).unwrap();
let plugin_json = format!(
"{{\n \"name\": \"tndm\",\n \"version\": \"0.0.0\"\n}}"
);
fs::write(dir.join("plugin.json"), plugin_json).unwrap();
let marketplace_json = format!(
"{{\n \"plugins\": [\n {{\n \"version\": \"0.0.0\"\n }}\n ]\n}}"
);
fs::write(dir.join("marketplace.json"), marketplace_json).unwrap();
}
#[test]
fn read_workspace_version_parses_version() {
let dir = tempfile::tempdir().unwrap();
create_temp_workspace(dir.path(), "1.2.3");
let version = read_workspace_version(dir.path().join("Cargo.toml")).unwrap();
assert_eq!(version, "1.2.3");
}
#[test]
fn sync_json_field_updates_matching_version() {
let dir = tempfile::tempdir().unwrap();
create_temp_workspace(dir.path(), "1.2.3");
sync_json_field(dir.path().join("plugin.json"), "version", "1.2.3").unwrap();
let updated: serde_json::Value =
serde_json::from_str(&fs::read_to_string(dir.path().join("plugin.json")).unwrap()).unwrap();
assert_eq!(updated["version"], "1.2.3");
}
#[test]
fn check_json_field_returns_true_when_matching() {
let dir = tempfile::tempdir().unwrap();
create_temp_workspace(dir.path(), "0.0.0");
assert!(check_json_field(dir.path().join("plugin.json"), "version", "0.0.0").unwrap());
}
#[test]
fn check_json_field_returns_false_when_mismatched() {
let dir = tempfile::tempdir().unwrap();
create_temp_workspace(dir.path(), "0.0.0");
assert!(!check_json_field(dir.path().join("plugin.json"), "version", "9.9.9").unwrap());
}
}
```
--------------------------------
### Commit Changes
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-create-metadata-flags.md
Commands to stage and commit the documentation and plugin configuration file updates.
```bash
git add plugin/tndm/skills/ticket/SKILL.md plugin/tndm/skills/ticket/references/command-reference.md plugin/tndm/.claude-plugin/plugin.json
git commit -m "docs(plugin): update create command docs with metadata flags"
```
--------------------------------
### Create a new ticket
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/SKILL.md
Use this command to create a new ticket. It defaults to 'todo' status and 'p2' priority. You can specify the status and priority at creation.
```sh
tndm ticket create "Brief title describing the task" --status in_progress
```
```sh
tndm ticket create "Brief title describing the task"
```
```sh
tndm ticket update --status in_progress
```
--------------------------------
### Create ticket with metadata
Source: https://github.com/mrclrchtr/tandem/blob/main/plugins/tndm/skills/ticket/SKILL.md
Create a ticket with a title and specify metadata such as priority, type, and tags. Dependencies can also be set.
```sh
# Minimal — auto-generates ID, defaults to todo/p2/task
tndm ticket create ""
```
```sh
# With metadata flags (set priority, type, tags, deps at creation)
tndm ticket create "Fix login timeout" \
--priority p1 --type bug --tags auth,security \
--depends-on TNDM-AAAAAA,TNDM-BBBBBB
```
```sh
# Start as in_progress in one command (no separate update needed)
tndm ticket create "Urgent hotfix" \
--status in_progress --priority p0 --type bug
```
--------------------------------
### Implement handle_awareness function
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Provides the core logic for the `awareness` command, including discovering the repository root, loading snapshots, comparing them, and printing a pretty-printed JSON report.
```rust
fn handle_awareness(against: String) -> anyhow::Result<()> {
let current_dir = env::current_dir().map_err(|error| anyhow::anyhow!("{error}"))?;
let repo_root = discover_repo_root(¤t_dir).map_err(|error| anyhow::anyhow!("{error}"))?;
let current = load_ticket_snapshot(&repo_root).map_err(|error| anyhow::anyhow!("{error}"))?;
let provider = GitAwarenessProvider::new(repo_root.clone());
let against_snapshot = match provider
.materialize_ref_snapshot(&against)
.map_err(|error| anyhow::anyhow!("{error}"))?
{
None => tandem_core::awareness::TicketSnapshot::default(),
Some(snapshot_root) => load_ticket_snapshot(&snapshot_root).map_err(|error| {
anyhow::anyhow!(
"failed to load materialized snapshot for ref `{}`: {}",
against,
error.to_string().replace(snapshot_root.to_string_lossy().as_ref(), "")
)
})?,
};
let report = compare_snapshots(&against, ¤t, &against_snapshot);
println!("{}", serde_json::to_string_pretty(&report)?);
Ok(())
}
```
--------------------------------
### Create a new Tandem ticket with content from a file
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Creates a new ticket using content from a specified file path.
```sh
# Content from file
tndm ticket create "Write ADR" --content-file /tmp/adr-draft.md
```
--------------------------------
### Commit Initial Sync Changes
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-version-sync.md
Stage and commit the updated JSON files after performing the initial version synchronization.
```bash
git add plugin/tndm/.claude-plugin/plugin.json .claude-plugin/marketplace.json
git commit -m "chore: sync plugin and marketplace versions to 0.1.0"
```
--------------------------------
### Create a new Tandem ticket with content via stdin
Source: https://context7.com/mrclrchtr/tandem/llms.txt
Creates a new ticket using content provided via stdin heredoc, suitable for agents to avoid temporary files and escaping issues.
```sh
# Content via stdin heredoc (preferred for agents — no temp files, no escaping)
tndm ticket create "Implement rate limiting" --type feature <<'EOF'
## Context
API endpoints have no rate limits.
## Goal
Add per-IP rate limiting using a token bucket algorithm.
## Open Questions
- [ ] What should the default limit be (req/min)?
## Acceptance
- [ ] 429 is returned when limit exceeded
- [ ] Limit is configurable per route
## Ready When
- [ ] Scope is clear
- [ ] Acceptance is specific enough for implementation
EOF
```
--------------------------------
### Configure Shell Completion Script (Zsh)
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-27-shell-completion-design.md
Add this line to your ~/.zshrc to enable tndm shell completion for Zsh.
```zsh
source <(COMPLETE=zsh tndm)
```
--------------------------------
### Stage and commit dependency changes
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
Commands to stage the modified `Cargo.toml` files and the new test file, followed by committing the changes with a descriptive message.
```bash
git add Cargo.toml crates/tandem-storage/Cargo.toml crates/tandem-cli/Cargo.toml crates/tandem-storage/tests/config_tests.rs
git commit -m "chore(deps): add toml/serde/rand/time test deps"
```
--------------------------------
### Test Ticket Creation with All Metadata Flags
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-create-metadata-flags.md
Verifies that a ticket can be created successfully using all available metadata flags. It also checks if the created ticket's details are correctly displayed.
```rust
#[test]
#[allow(clippy::disallowed_methods)]
fn ticket_create_with_all_metadata_flags() {
let repo_root = tempfile::tempdir().expect("tempdir");
fs::create_dir_all(repo_root.path().join(".git")).expect("create .git dir");
// Create prerequisite tickets for depends_on
for id in ["TNDM-A1", "TNDM-A2"] {
Command::new(env!("CARGO_BIN_EXE_tndm"))
.args(["ticket", "create", "prereq", "--id", id])
.current_dir(repo_root.path())
.output()
.expect("create prereq ticket")
.status
.success()
.then_some(())
.expect("create should succeed");
}
let output = Command::new(env!("CARGO_BIN_EXE_tndm"))
.args([
"ticket",
"create",
"Full flags test",
"--id",
"TNDM-FL01",
"--priority",
"p0",
"--type",
"bug",
"--tags",
"auth,security",
"--depends-on",
"TNDM-A1,TNDM-A2",
"--status",
"in_progress",
])
.current_dir(repo_root.path())
.output()
.expect("run tndm ticket create with all flags");
assert!(
output.status.success(),
"expected success, stderr was: {}",
String::from_utf8_lossy(&output.stderr)
);
let show = Command::new(env!("CARGO_BIN_EXE_tndm"))
.args(["ticket", "show", "TNDM-FL01"])
.current_dir(repo_root.path())
.output()
.expect("run tndm ticket show");
let show_stdout = String::from_utf8(show.stdout).expect("stdout should be UTF-8");
assert!(
show_stdout.contains("priority = \"p0\""),
"show output was: {show_stdout}"
);
assert!(
show_stdout.contains("type = \"bug\""),
"show output was: {show_stdout}"
);
assert!(
show_stdout.contains("tags = [\"auth\", \"security\"]"),
"show output was: {show_stdout}"
);
assert!(
show_stdout.contains("depends_on = [\"TNDM-A1\", \"TNDM-A2\"]"),
"show output was: {show_stdout}"
);
assert!(
show_stdout.contains("status = \"in_progress\""),
"show output was: {show_stdout}"
);
}
```
--------------------------------
### Integrate `CompleteEnv` into `main()`
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-27-shell-completion.md
This code snippet integrates `CompleteEnv` into the `main` function to handle dynamic shell completion before parsing CLI arguments.
```rust
CompleteEnv::with_factory(Cli::command)
.complete();
let cli = Cli::parse();
```
--------------------------------
### Test Loading Config Reads Prefix and Template
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
This test verifies that the `load_config` function correctly reads the `id_prefix` and `content_template` from the `.tndm/config.toml` file. Ensure the file exists and is correctly formatted before running.
```rust
#[test]
fn load_config_reads_prefix_and_template() {
let dir = tempfile::tempdir().unwrap();
std::fs::create_dir_all(dir.path().join(".tndm")).unwrap();
std::fs::write(
dir.path().join(".tndm/config.toml"),
"schema_version = 1\n\n[id]\nprefix = \"FOO\"\n\n[templates]\ncontent = \'\'\'\nHello\n'''\n",
)
.unwrap();
let cfg = tandem_storage::load_config(dir.path()).unwrap();
assert_eq!(cfg.id_prefix, "FOO");
assert_eq!(cfg.content_template, "Hello\n");
}
```
--------------------------------
### Add clap_complete Dependency
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-27-shell-completion-design.md
Add the clap_complete crate with the unstable-dynamic feature to your Cargo.toml to enable dynamic completion.
```toml
clap_complete = { version = "4.5", features = ["unstable-dynamic"] }
```
--------------------------------
### Add dependencies to tandem-storage Cargo.toml
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
Configuration snippet for `crates/tandem-storage/Cargo.toml`, specifying dependencies and dev-dependencies, utilizing workspace versions.
```toml
[dependencies]
serde.workspace = true
time.workspace = true
toml.workspace = true
tandem-core.workspace = true
[dev-dependencies]
tempfile.workspace = true
```
--------------------------------
### Manual Smoke Test for Shell Completion
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-27-shell-completion.md
Provides instructions for manually testing the implemented shell completion features, including building the binary, sourcing the completion script, and testing command and argument completion interactively.
```bash
# Build the binary
cargo build
# Set up completion for current shell session (bash example)
source <(COMPLETE=bash ./target/debug/tndm)
# Try completing:
# ./target/debug/tndm → should show: fmt, ticket, awareness
# ./target/debug/tndm ticket → should show: create, show, list, update
# ./target/debug/tndm ticket show → should show ticket IDs from .tndm/
```
--------------------------------
### Run Tandem Core Tests
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Execute tests for the tandem-core crate to verify awareness module functionality. This command is used both to confirm failing tests before implementation and passing tests after.
```bash
cargo test -p tandem-core --locked
```
--------------------------------
### Wire clap_complete Dependency in Workspace
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-27-shell-completion-design.md
Ensure the clap_complete dependency is correctly wired within your workspace's Cargo.toml.
```toml
clap_complete.workspace = true
```
--------------------------------
### Integrate CompleteEnv in main()
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/specs/2026-03-27-shell-completion-design.md
Call `CompleteEnv::with_factory` before `Cli::parse()` to intercept shell completion requests and exit early. Ensure no stdout output occurs before this call.
```rust
use clap::CommandFactory;
use clap_complete::env::CompleteEnv;
fn main() -> anyhow::Result<()> {
CompleteEnv::with_factory(Cli::command)
.complete();
let cli = Cli::parse();
// ... rest unchanged
}
```
--------------------------------
### Run targeted workspace tests
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Execute tests for individual crates (`tandem-core`, `tandem-storage`, `tandem-repo`, `tandem-cli`) to ensure each component functions correctly.
```bash
cargo test -p tandem-core --locked
cargo test -p tandem-storage --locked
cargo test -p tandem-repo --locked
cargo test -p tandem-cli --locked
```
--------------------------------
### Update Cargo.toml for clap_complete
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-27-shell-completion.md
Modify the root `Cargo.toml` to include `clap_complete` as a workspace dependency and enable the `unstable-ext` feature for `clap`. The `unstable-ext` feature is necessary for using the `#[arg(add = ...)]` syntax.
```toml
clap = { version = "4.5.23", features = ["derive", "unstable-ext"] }
clap_complete = { version = "4.5", features = ["unstable-dynamic"] }
```
--------------------------------
### Stage and Commit Changes
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-version-sync.md
Bash commands to stage modified Rust source and TOML files, followed by a commit with a descriptive message for the new sync-version subcommand.
```bash
git add crates/xtask/src/main.rs crates/xtask/Cargo.toml
git commit -m "feat(xtask): add sync-version subcommand with --check flag"
```
--------------------------------
### Initial attempt at sync_json_at_pointer
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-version-sync.md
An early attempt to create a function for synchronizing JSON fields using a pointer. This version had an issue with `as_string_mut()` not existing.
```rust
fn sync_json_at_pointer(path: std::path::PathBuf, pointer: &str, version: &str) -> Result<(), Vec> {
let content = std::fs::read_to_string(&path)
.map_err(|e| vec![format!("failed to read {}: {e}", path.display())])?;
let mut doc: serde_json::Value = serde_json::from_str(&content)
.map_err(|e| vec![format!("failed to parse {}: {e}", path.display())])?;
doc.pointer_mut(pointer)
.ok_or_else(|| vec![format!("JSON pointer {pointer} not found in {}", path.display())])?
.as_string_mut() // This doesn't exist; use a different approach
.map(|_| ())
}
```
--------------------------------
### Implement Ticket Snapshot Loading
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Implement the `load_ticket_snapshot` function in tandem-storage to load all tickets into a `TicketSnapshot`. This function reuses `FileTicketStore` and ensures stable ordering using `BTreeMap`.
```rust
use std::collections::BTreeMap;
use tandem_core::awareness::TicketSnapshot;
pub fn load_ticket_snapshot(repo_root: &Path) -> Result {
let store = FileTicketStore::new(repo_root.to_path_buf());
let mut tickets = BTreeMap::new();
for id in store.list_ticket_ids()? {
let ticket = store.load_ticket(&id)?;
tickets.insert(id, ticket);
}
Ok(TicketSnapshot { tickets })
}
```
--------------------------------
### Run Tandem Storage Tests
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-08-awareness-mvp-implementation-plan.md
Execute tests for the tandem-storage crate to verify the ticket snapshot loading functionality. This command is used to confirm failing tests before implementation and passing tests after.
```bash
cargo test -p tandem-storage --locked
```
--------------------------------
### Add Mise Tasks for Version Sync and Bumping
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-03-30-version-sync.md
Define mise tasks in `mise.toml` for syncing versions, bumping the workspace version, and checking version consistency. The `bump` task requires a version argument.
```toml
[tasks.sync-version]
description = "Sync plugin/marketplace versions from Cargo.toml"
run = "cargo xtask sync-version"
[tasks.bump]
description = "Bump workspace version and sync derived files"
run = """
version="${@}"
if [ -z "$version" ]; then
echo "usage: mise run bump -- " >&2; exit 1
fi
sed -i '' -e "s/^version = \".*\"/version = \"${version}\"" Cargo.toml
mise run sync-version
"""
[tasks.check]
description = "Run all checks"
depends = ["fmt", "compile", "arch", "clippy", "test"]
run = "cargo xtask sync-version --check"
```
```toml
[tasks.sync-version-check]
description = "Check plugin/marketplace versions match Cargo.toml"
run = "cargo xtask sync-version --check"
[tasks.check]
description = "Run all checks"
depends = ["fmt", "compile", "arch", "clippy", "test", "sync-version-check"]
```
--------------------------------
### Run tandem-storage tests
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/superpowers/plans/2026-04-01-effort-and-dependencies-in-ticket-list.md
Execute the tests specifically for the tandem-storage crate to verify the deserialization of the effort field. This command filters the output to show the last 5 lines.
```bash
cargo test -p tandem-storage 2>&1 | tail -5
```
--------------------------------
### Test Discover Repo Root Finds Git Dir
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
This test verifies that the `discover_repo_root` function correctly identifies the repository root when a `.git` directory is present. It creates a temporary directory structure and asserts that the function returns the correct root path.
```rust
#[test]
fn discover_repo_root_finds_git_dir() {
let dir = tempfile::tempdir().unwrap();
std::fs::create_dir_all(dir.path().join(".git")).unwrap();
let nested = dir.path().join("a/b/c");
std::fs::create_dir_all(&nested).unwrap();
let root = tandem_storage::discover_repo_root(&nested).unwrap();
assert_eq!(root, dir.path());
}
```
--------------------------------
### Commit Ticket Load Implementation
Source: https://github.com/mrclrchtr/tandem/blob/main/docs/plans/2026-03-03-ticket-commands-implementation-plan.md
Command to stage and commit the implementation of `FileTicketStore::load_ticket`. This includes changes to the storage library and its tests.
```bash
git add crates/tandem-storage/src/lib.rs crates/tandem-storage/tests/ticket_store_tests.rs
git commit -m "feat(storage): implement FileTicketStore load_ticket"
```]