-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Design 2
Seth Ford edited this page Feb 8, 2026
·
3 revisions
The ADR is ready. Here's the complete Architecture Decision Record:
The shipwright status command (scripts/cct-status.sh, ~170 lines) currently produces a human-readable dashboard with ANSI colors and Unicode box-drawing characters. It collects three categories of data:
- Tmux windows — finds Claude-related tmux windows, their pane counts, and active/idle status
-
Team configs — reads
~/.claude/teams/*.jsonfor member counts and names -
Task lists — iterates
~/.claude/tasks/, counts statuses, calculates progress percentages
There is no machine-readable output option. Other commands already implement --json flags (cct-cost.sh lines 253-389, cct-daemon.sh lines 2876-3095), establishing a clear pattern. The project enforces Bash 3.2 compatibility — no associative arrays, readarray, or ${var,,}.
Follow the established --json pattern from cct-cost.sh and cct-daemon.sh:
-
Argument parsing: Add
json_output=falseboolean and awhile [[ $# -gt 0 ]]/caseloop at top ofmain() -
Data collection: Refactor the three collection sections to store results in shell variables. Build JSON arrays incrementally using
jqper entry -
Output routing: After collection, check
if [[ "$json_output" == "true" ]]— assemble final JSON withjq -nusing--argjsonfor arrays and--argfor scalars, thenreturn 0 -
JSON construction: Use
jq --arg/--argjsonexclusively (never string interpolation). Accumulate array elements, combine withjq -s '.'
{
"timestamp": "2026-02-08T20:58:32Z",
"version": "0.15.0",
"tmux_windows": [
{ "session": "main", "window": "claude-myteam", "panes": 4, "active": true, "status": "active" }
],
"teams": [
{ "name": "myteam", "members_count": 3, "members": ["lead", "builder", "tester"] }
],
"task_lists": [
{ "team": "myteam", "total": 10, "completed": 7, "in_progress": 2, "pending": 1, "completion_pct": 70 }
],
"summary": {
"total_windows": 2, "total_teams": 1, "total_tasks": 10, "overall_completion_pct": 70
}
}main("--json")
→ parse_args() sets json_output=true
→ collect_tmux_windows() → $windows_json
→ collect_team_configs() → $teams_json
→ collect_task_lists() → $tasks_json
→ if json_output: jq -n assembles final object → stdout → return 0
→ else: existing dashboard rendering (unchanged)
-
No tmux running:
tmux_windows= empty array[] -
No
~/.claude/teams/:teams= empty array[] -
No
~/.claude/tasks/:task_lists= empty array[] -
No jq installed:
error "jq is required for --json output"→ exit 1 - All JSON to stdout; all errors to stderr (pipe-safe)
- Structured text (key=value) — Pros: No jq dependency, simpler / Cons: Can't represent nested data (members list, task breakdowns), no codebase precedent, fragile for consumers
-
Separate
status-jsonsubcommand — Pros: Clean separation / Cons: Code duplication, inconsistent withcost --jsonanddaemon metrics --jsonpatterns, more surface area -
YAML output — Pros: Human-readable / Cons: No
yqguarantee, no precedent, quoting edge cases in bash
-
Files to modify:
-
scripts/cct-status.sh— Add--jsonflag parsing, refactor data collection into variables, add JSON output branch withjq -n
-
-
Files to create:
-
scripts/cct-status-test.sh— Tests followingcct-daemon-test.shpatterns (valid JSON, key presence, empty-state, human output unchanged)
-
-
package.json — Add status test to
npm testrunner -
Dependencies:
jq(already used by cost, daemon, pipeline scripts) -
Risk areas:
- Bash 3.2: no associative arrays — use string concat or
jq -s '.' - Existing code mixes computation with display (progress bars built inline) — refactoring must not break human output
-
pipefail+grep -creturning 0 matches → use|| trueguard per project conventions
- Bash 3.2: no associative arrays — use string concat or
-
shipwright status --jsonproduces valid JSON (passesjq empty) -
shipwright status --json | jq '.tmux_windows'returns an array -
shipwright status --json | jq '.teams'returns an array -
shipwright status --json | jq '.task_lists'returns an array -
shipwright status --json | jq '.summary'returns an object with totals -
shipwright status --jsoncontains no ANSI escape codes -
shipwright status(without --json) produces identical output to before - Empty state: JSON has empty arrays, not null or error
- Missing jq + --json: clear error to stderr, exit 1
-
npm testpasses including new status tests - All JSON values use correct types (numbers for counts/percentages, not strings)