feat(xcode-ide): Persist bridge response artifacts#396
Conversation
Make final tool rendering depend on explicit structured results instead of streaming fragments. This keeps live progress transient and gives CLI, daemon, and MCP output paths the same source of truth for final success, errors, and text rendering. Add a shared structured error shape and schema coverage so failures can be rendered consistently without scraping fragment text.
commit: |
Update simulator, device, and macOS build-and-run flows to populate final structured results directly. This removes the need to infer final status or artifact paths from progress fragments while preserving live progress for interactive renderers. Adjust resource and test helpers around the new result contract.
Expand workspace filesystem cleanup so transient XcodeBuildMCP-owned files are removed with ownership checks and bounded retention. This keeps generated artifacts from accumulating while preserving files that belong to active processes or other workspaces. Add regression coverage for cleanup ownership and retention behavior.
Save raw Xcode IDE bridge call results as transient workspace artifacts and return concise structured summaries from the public tools. This prevents large relayed payloads from being embedded in final text output while preserving the full remote response for callers that need it. Route Xcode IDE CLI commands through the generic output pipeline so text, JSON, and JSONL modes share the same behavior as other tool commands.
Add snapshot coverage for Xcode IDE list-tools and documentation-search output across CLI text, MCP text, and CLI JSON modes. Normalize transient artifact paths so the fixtures verify the public contract without depending on local workspace directories.
Update agent guidance for structured output terminology, streaming boundaries, and workspace filesystem cleanup. Add the corresponding changelog entries for the Xcode IDE artifact output and fragment-state removal.
7eb6999 to
a1ac92c
Compare
Avoid asserting an exact wall-clock duration for swift_package_run progress. CI can legitimately report a small nonzero duration even when local runs finish within the same millisecond.
There was a problem hiding this comment.
createBaseRenderSession.finalize discards all collected fragments (src/rendering/render.ts:82)
The base session collects emitted fragments into the fragments array, but finalize() now passes items: [] to the hook instead of fragments. For the text and raw strategies, whose finalize hooks render input.items, this means every fragment emitted via session.emit(...) is silently dropped at finalization. Callers that build a render session, emit fragments, and then call finalize() will get output that omits all transcript content (compiler diagnostics, status messages, process lines accumulated for non-streaming consumers, etc.), leaving only structured output and next-steps in the rendered text.
Daemon runtime no longer receives thrown error from failed direct handler (src/runtime/tool-invoker.ts:599)
Previously, when opts.runtime === 'daemon' and the direct tool handler threw, the error was re-thrown so the daemon could propagate it to the client. The new code removes that throw and instead only calls emitExplicitRuntimeError. If the daemon relies on a thrown exception to mark the invocation as failed (e.g. for status/exit codes or RPC error responses), this is a silent behavioral/backwards-compatibility change that could cause failed daemon-internal invocations to appear successful to callers.
Identified by Warden code-review
|
Addressed the Warden review summary findings as no-change after auditing the branch:
No code changes were needed. |
Remove fragment caching from render sessions and test results so streamed fragments cannot be reused as final response state. Normalize xcode-ide tool counts in snapshots to avoid environment-specific fixture churn. Refs GH-360 Co-Authored-By: Codex <noreply@openai.com>
Make final tool output come from explicit structured results instead of transient streaming fragments, then apply that path to Xcode IDE bridge calls.
Previously, some final CLI/daemon/MCP output depended on progress fragments that were meant only for live rendering. That made non-streaming output harder to reason about and risked leaking large relayed bridge payloads into final text. This change keeps streaming fragments transient and moves final status, errors, summaries, and artifact references into structured results.
For Xcode IDE bridge calls, raw remote responses are now saved as transient workspace-state JSON artifacts. The public output stays concise, while callers that need the full Xcode bridge response can follow the returned artifact path. The Xcode IDE CLI commands now use the same text, JSON, and JSONL rendering path as the rest of the tool catalog.
The branch is intentionally split into reviewable commits:
I considered preserving fragment-derived final state as a compatibility fallback, but that would keep two sources of truth. The structured result is now the canonical final output path, and fragments remain live progress only.
Validated locally with
npm run lint,npm run typecheck,npm run format:check,npm run build, andnpm test.