Skip to content

CLI AI: Add --json flag for headless NDJSON output#2913

Open
wesleyfantinel wants to merge 6 commits intoAutomattic:trunkfrom
wesleyfantinel:add/cli-studio-ai-json-flag
Open

CLI AI: Add --json flag for headless NDJSON output#2913
wesleyfantinel wants to merge 6 commits intoAutomattic:trunkfrom
wesleyfantinel:add/cli-studio-ai-json-flag

Conversation

@wesleyfantinel
Copy link
Copy Markdown

Related issues

  • Related to sandboxed/Docker deployment of Studio AI agent

How AI was used in this PR

Claude was used to brainstorm the design, write the implementation plan, and implement the changes. All code was reviewed and validated by the author.

Proposed Changes

  • Add --json flag and positional message argument to studio ai command for headless mode
  • Introduce AiOutputAdapter interface with two implementations:
    • InteractiveAdapter — wraps existing AiChatUI (zero changes to TUI code)
    • JsonAdapter — streams typed NDJSON events to stdout
  • Add autoApprove option to AiAgentConfig — in JSON mode, all tool permissions are auto-approved (sandbox is trusted)
  • In JSON mode, agent questions are emitted as question.asked events and the process exits (service resumes via session)
  • Define NDJSON event schema: message, progress, info, error, question.asked, turn.started, turn.completed
  • Add 4 new tests for JSON mode (single turn, SDK message streaming, error handling, autoApprove flag)

Usage

# Single turn, streams NDJSON events to stdout
studio ai "create a theme for my site" --json

# Validation: --json requires a message
studio ai --json  # Error: --json requires an initial message argument

Files changed

File Change
apps/cli/ai/json-events.ts (new) NDJSON event types and emitEvent() helper
apps/cli/ai/output-adapter.ts (new) AiOutputAdapter interface, InteractiveAdapter, JsonAdapter
apps/cli/ai/agent.ts Add autoApprove field to AiAgentConfig, short-circuit canUseTool
apps/cli/commands/ai/index.ts Positional message, --json flag, adapter pattern, single-turn path
apps/cli/commands/ai/sessions/resume.ts Pass InteractiveAdapter to updated runCommand signature
apps/cli/commands/ai/tests/ai.test.ts 4 new JSON mode tests

Testing Instructions

  1. Build the CLI: npm run cli:build
  2. Run in JSON mode:
    node apps/cli/dist/cli/main.js ai "hello, what can you do?" --json
  3. Verify NDJSON events are streamed to stdout (one JSON object per line)
  4. Verify turn.started is the first event and turn.completed is the last
  5. Run in interactive mode (no --json flag) and verify the TUI works as before:
    node apps/cli/dist/cli/main.js ai
  6. Verify --json without a message shows an error:
    node apps/cli/dist/cli/main.js ai --json
  7. Run tests: npm test -- apps/cli/commands/ai/tests/ai.test.ts

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

- Introduced `JsonAdapter` for emitting NDJSON events to stdout.
- Enhanced `runCommand` to support headless mode.
- Updated AI agent to handle `autoApprove` for non-interactive prompts.
- Added tests to validate NDJSON output behavior and error handling.
…andling, so that the type is conformant to zod
@wesleyfantinel wesleyfantinel force-pushed the add/cli-studio-ai-json-flag branch from 2d3ca2e to 21c2375 Compare March 25, 2026 21:08
@wojtekn wojtekn requested a review from a team March 26, 2026 13:42
Copy link
Copy Markdown

@draganescu draganescu left a comment

Choose a reason for hiding this comment

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

Edited

@wojtekn wojtekn mentioned this pull request Mar 30, 2026
wesleyfantinel and others added 2 commits April 1, 2026 09:11
Make costUsd optional since only JsonAdapter provides it, guard
replaySessionHistory behind InteractiveAdapter instanceof check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants