-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Design 2
Now I have complete context. Here's the ADR:
shipwright status (scripts/cct-status.sh, 169 lines) is a read-only dashboard that displays three sections: tmux windows, team configurations, and task progress. It currently accepts no arguments — it runs straight through with ANSI-colored output only.
Machine-readable output is needed for scripting, CI dashboards, and programmatic consumption. The project already has an established --json pattern in scripts/cct-daemon.sh (line 2884) where daemon_metrics uses jq -n with --arg/--argjson to build structured JSON, gated behind a json_output boolean flag.
Constraints:
- Bash 3.2 compatible (no associative arrays, no
${var,,}) -
set -euo pipefailrequired -
jqis available as a dependency (already used in daemon, fleet, cost scripts) - Script currently has no argument parsing loop — one must be added
- The three data sections (windows, teams, tasks) each gather data inline while rendering — data collection and rendering are interleaved
Add a --json flag to cct-status.sh following the exact pattern from daemon_metrics:
-
Argument parsing: Add a
while [[ $# -gt 0 ]]loop at the top (before the header) with--jsonand--helpflags. -
Separate data collection from rendering: Refactor each of the three sections to first collect data into shell variables, then conditionally output either ANSI-formatted text (default) or JSON. This is the key structural change — the current code interleaves
echostatements with data parsing. -
JSON structure (via
jq -n):
{
"timestamp": "2026-02-08T22:15:00Z",
"windows": [
{ "name": "claude-build", "session": "main:2", "panes": 3, "active": true }
],
"teams": [
{ "name": "build-team", "members": ["lead", "dev", "tester"], "member_count": 3, "status": "configured" }
],
"tasks": [
{
"team": "build-team",
"total": 10,
"completed": 7,
"in_progress": 2,
"pending": 1,
"progress_pct": 70
}
]
}-
Build JSON with
jq: Usejq -n --argjsonto compose the output. Collect windows/teams/tasks as JSON arrays in variables, then merge them into the final object. This avoids string interpolation of user data into JSON (per Common Pitfalls in CLAUDE.md). -
--helpflag: Add ashow_usage()function consistent with other scripts (e.g.,cct-logs.sh). -
Exit early: When
--jsonis set, output the JSON andexit 0— don't fall through to the ANSI rendering.
-
Separate script (
cct-status-json.sh) — Pros: no refactoring of existing script, zero risk to current behavior / Cons: code duplication, two scripts to maintain in sync, inconsistent with project patterns (daemon metrics uses a flag, not a separate script) -
Tab-separated / CSV output (
--tsv) — Pros: simpler to implement, no jq dependency / Cons: harder to parse nested data (teams with member lists), not as useful for dashboards,jqis already a project dependency and used extensively -
Keep data collection interleaved, capture ANSI output and strip/parse it — Pros: minimal refactoring / Cons: fragile, regex-dependent, can't produce structured nested JSON from flat text, bad engineering practice
-
Files to create:
scripts/cct-status-test.sh(new test harness for status command) -
Files to modify:
-
scripts/cct-status.sh— add argument parsing, refactor data collection, add JSON output path -
package.json— addcct-status-test.shto thetestscript chain
-
-
Dependencies: None new (
jqis already required by daemon, fleet, cost scripts) -
Risk areas:
- The tmux data collection (
tmux list-windows) depends on a live tmux server. In--jsonmode when no tmux is running, the script should output an emptywindowsarray rather than erroring. The existing2>/dev/null || truehandles this, but the refactored code must preserve that behavior. - The
find+while readloops for teams/tasks currently setHAS_TEAMS/HAS_TASKSbooleans — these must work both for the ANSI path (unchanged behavior) and the JSON path (populating arrays). - The
grep -cin team member counting (line 78) is a known pipefail hazard — must use|| truepattern (already does, but verify during refactor). - The task status parsing with
grep -o+sed(line 122) is brittle — for JSON mode, consider usingjqdirectly on task files if available, with fallback to existing grep approach for ANSI mode.
- The tmux data collection (
-
shipwright status --jsonoutputs valid JSON (parseable byjq .) -
shipwright status --json | jq '.windows'returns an array (possibly empty) -
shipwright status --json | jq '.teams'returns an array withname,members,member_countfields -
shipwright status --json | jq '.tasks'returns an array withtotal,completed,in_progress,pending,progress_pctfields -
shipwright status(no flag) produces identical ANSI output to current behavior — zero regression -
shipwright status --helpprints usage information and exits 0 -
shipwright status --jsonwith no tmux server running outputs{"windows": [], ...}without error -
shipwright status --jsonwith no teams/tasks directories outputs empty arrays - All numeric fields in JSON are numbers (not strings) — validated with
jq 'type' -
npm testpasses with newcct-status-test.shincluded - Test harness covers:
--jsonoutput structure, empty state,--helpflag, unknown flag error