Skip to content

Add --json option to --once snapshot for scripts and status bars - #5

Merged
phalladar merged 3 commits into
phalladar:mainfrom
thanvish21:feat/once-json
Oct 11, 2026
Merged

phalladar merged 3 commits into
phalladar:mainfrom
thanvish21:feat/once-json

Conversation

@thanvish21

@thanvish21 thanvish21 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds --json to tracon --once to emit a structured JSON payload for scripts and status bars.
  • Enforces --json needs --once via parser.error() to cleanly protect command invariants.
  • Wraps output in top-level metadata {"session": ..., "lane": ..., "as_of": ..., "agents": [...]}.
  • Agents are sorted by urgency matching --once and TUI table ordering.
  • Agent fields include id, description, state, severity, flags (list of {"code", "severity", "detail"} dicts matching web.py), quiet_s, and judge ({"verdict": ..., "dismissed": ...} or null).
  • Updates documentation (README.md and CLAUDE.md) and adds unit tests in tests/test_cli.py.

Closes #1

Test plan

  • Run uv run pytest (88/88 passing, including 7 tests in tests/test_cli.py)
  • Verify uv run tracon --demo --once --json outputs valid JSON with schema {"session", "lane", "as_of", "agents"}
  • Verify status bar filtering: uv run tracon --demo --once --json | jq '[.agents[] | select(.state=="BLOCKED")] | length' correctly outputs 1
  • Verify uv run tracon --demo --json exits with code 2 and outputs --json needs --once
  • Verify uv run tracon --demo --once --json --no-judge sets "judge": null across all agents
  • Verify uv run tracon --demo --once continues to emit standard formatted terminal output
  • Verify formatting and linting pass with uv run ruff check

🤖 Generated with Claude Code

Adds `--json` to `tracon --once` (or standalone `tracon --json`) to emit
a structured JSON array of agent objects with id, description, state,
flags, quiet seconds, and judge verdict, sorted by urgency. This enables
integrations with status bars (tmux, sketchybar, Waybar) and external
scripts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@phalladar phalladar left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up @thanvish21! It's what #1 asked for and it's nicely contained: it builds on assess_all() and only reads cached judge verdicts, so polling it from a status bar every few seconds is free. Tests pass for me.

A few things before I merge, mostly about making the output useful to the status bar it's meant for. Details are inline.

Also, heads up: I have a commit on main I haven't pushed yet (the Ghostty split / session picker). It touches the imports and adds _write right above print_snapshot, so this will conflict in cli.py once it lands. It's an easy conflict; I'll ping you when it's up so you can rebase.

Comment thread tracon/cli.py Resolved
Comment thread tracon/cli.py Resolved
Comment thread tracon/cli.py Resolved
Comment thread tracon/cli.py Resolved
Comment thread tracon/cli.py Resolved
Comment thread tests/test_cli.py Resolved
- Require `--once` when using `--json` via parser.error.
- Nest flag objects with `code`, `severity`, and `detail` matching web view.
- Add `severity` to each agent object for direct status bar styling.
- Nest `judge` with `verdict` and `dismissed` flag.
- Wrap output in top-level object containing `session`, `lane`, `as_of`,
  and `agents` list.
- Keep `print_snapshot` definition on a single line.
- Use `pytest.raises` for JSONDecodeError in tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@thanvish21

Copy link
Copy Markdown
Contributor Author

All requested changes have been implemented and verified in commit ea2427a:

  1. Top-level metadata wrapper: Output now wraps agents under {"session": ..., "lane": ..., "as_of": ..., "agents": [...]}.
  2. Flag and agent severity: Added severity to each flag ({"code", "severity", "detail"}) and top-level agent object.
  3. Judge structure: Nested as {"verdict": ..., "dismissed": ...} (or null) to distinguish dismissed verdicts.
  4. Validation invariant: Enforced parser.error("--json needs --once") in main() when --json is passed without --once.
  5. Code style & tests: Preserved single-line function signature in cli.py and updated tests/test_cli.py with pytest.raises(json.JSONDecodeError).

All 88 unit tests and lint checks pass cleanly. Ready for re-review whenever convenient!

Resolve conflict in tracon/cli.py by combining ghostty chooser initialization
with --json flag parsing, schema serialization, and parser error validation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@phalladar
phalladar merged commit 7089f93 into phalladar:main Oct 11, 2026
4 checks passed
@phalladar

Copy link
Copy Markdown
Owner

Good to go. Thank you @thanvish21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--once --json for scripts and status bars

2 participants