-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
1. Why Do You NEED This Feature?
I'm building an orchestration layer that runs Forge as a subprocess via forge -p "...". Right now I have to scrape the terminal output to figure out what's happening, which tools got called, whether something failed. It's fragile and breaks whenever the TUI formatting changes.
I need a way to get structured events out of a running Forge session. Not static config info, but the actual execution stream: tool calls, their outputs, text deltas, errors, token counts. Basically a machine-readable version of what the TUI shows.
2. What Is NOT Possible Right Now?
- There's no machine-readable mode for
forge -p "..."or interactive sessions. The only output is the human-facing TUI. FORGE_DEBUG_REQUESTSwrites raw HTTP request data, which is debug-level stuff, not structured execution events.- Can't reliably extract tool call boundaries, durations, or token usage from the rendered terminal output. Regex parsing of ANSI-formatted text is not a real solution.
--verbosegives more info but it's still unstructured text meant for a person reading a terminal.
I've tried parsing the TUI output with a combination of ANSI stripping and regex. It works until it doesn't.
3. What WILL Be Possible With This Feature?
- CI/CD pipelines that run
forge -p "..."and parse tool results and token usage without scraping - Editor plugins and TUI wrappers that react to events in real time (tool starts, errors, text streaming)
- Cost tracking and failure detection via structured logs instead of eyeballing terminal output
- Multi-agent setups where a parent process orchestrates Forge as a subprocess with actual structured communication, not screen-scraping
Proposed Solution (User Experience)
A flag like --output-format stream-json that switches stdout from the TUI to NDJSON (one JSON object per line).
forge -p "fix the bug in auth.rs" --output-format stream-jsonOutput would look roughly like:
{"type":"tool_call_start","tool":"Read","input":{"path":"src/auth.rs"},"timestamp_ms":1711382400000}
{"type":"tool_output","tool_call_id":"tc_01","duration_ms":487}
{"type":"text_delta","content":"Based on the file..."}
{"type":"turn_complete","input_tokens":12450,"output_tokens":892}NDJSON because it's the simplest streaming format. Works with jq, standard unix pipes, any language's line reader. Same approach Claude Code uses with its --output-format stream-json. No server, no extra dependencies.
When this flag is active the TUI doesn't render. Stdout is just the event stream. Stderr could still be used for fatal errors or diagnostics if needed.
I could take a crack at the PR if you're open to the general direction.
Alternatives Considered
- Parsing terminal output: fragile. Any TUI change breaks the parser and you're back to debugging regex.
- WebSocket or gRPC server: too heavy for this use case. NDJSON on stdout keeps it simple and composable.
- Extending FORGE_DEBUG_REQUESTS: aimed at HTTP-level debugging, not execution-level events. Different abstraction layer.
Feature Category
Multi-Agent Workflows
Priority/Impact
High - Would significantly improve my workflow
Examples from Other Tools
Claude Code has --output-format stream-json that does basically this. NDJSON events for tool calls, text, system messages, token usage. It's the main way people build orchestration and CI pipelines on top of it.
gh (GitHub CLI) uses --json flags on most commands. docker events --format '{{json .}}' streams container events as JSON lines. Same pattern, well established.
Additional Context
--porcelain already shows the project values machine-readable output for static queries (model info, tool lists, config). This would extend that same philosophy to the execution stream, which is where the real data lives for automation use cases.
Pre-submission Checklist
- I have searched existing issues and confirmed this is not a duplicate
- I am willing to submit a PR to implement this feature