feat(responses): Add next-step runtime responses#420
Conversation
Add next-step instructions to runtime responses while keeping the structured output envelope intact. The runtime now decides between minimal and normal response detail without directly owning CLI verbosity policy. Expose CLI control so regular CLI output can default to normal detail while agent-oriented CLI usage can request minimal output matching MCP. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Restructure snapshot fixtures so CLI and MCP each have text and JSON coverage. Add parity tests for both JSON fixture sets and update harness parsing to keep runtime/output expectations explicit. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Record the runtime response and snapshot coverage changes in the unreleased changelog. Co-Authored-By: OpenAI Codex <noreply@openai.com>
commit: |
Use the runtime option as the default text output style only when callers do not pass an explicit output style. This keeps MCP resource rendering minimal while still allowing CLI callers to opt into minimal output. Co-Authored-By: OpenAI Codex <noreply@openai.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Global test filter silently skips device snapshot tests
- Split the command into two separate vitest runs: one for device.snapshot.test.ts without filter to run all tests, and another for parity files with the filter to run only device workflow tests.
Or push these changes by commenting:
@cursor push 51cb64f1df
Preview (51cb64f1df)
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"test:schema-fixtures": "vitest run --config vitest.snapshot.config.ts src/snapshot-tests/__tests__/json-fixture-schema.test.ts",
"test:snapshot": "npm run build && node build/cli.js daemon stop 2>/dev/null; vitest run --config vitest.snapshot.config.ts",
"test:snapshots": "npm run test:snapshot",
- "test:snapshot:device": "npm run build && node build/cli.js daemon stop 2>/dev/null; vitest run --config vitest.snapshot.config.ts src/snapshot-tests/__tests__/device.snapshot.test.ts src/snapshot-tests/__tests__/cli-json-fixture-parity.snapshot.test.ts src/snapshot-tests/__tests__/mcp-json-fixture-parity.snapshot.test.ts -t 'device workflow'",
+ "test:snapshot:device": "npm run build && node build/cli.js daemon stop 2>/dev/null; vitest run --config vitest.snapshot.config.ts src/snapshot-tests/__tests__/device.snapshot.test.ts && vitest run --config vitest.snapshot.config.ts src/snapshot-tests/__tests__/cli-json-fixture-parity.snapshot.test.ts src/snapshot-tests/__tests__/mcp-json-fixture-parity.snapshot.test.ts -t 'device workflow'",
"test:snapshot:update": "npm run build && node build/cli.js daemon stop 2>/dev/null; UPDATE_SNAPSHOTS=1 vitest run --config vitest.snapshot.config.ts",
"test:snapshots:update": "npm run test:snapshot:update",
"test:smoke": "npm run build && vitest run --config vitest.smoke.config.ts",You can send follow-ups to the cloud agent here.
Run the device snapshot file separately from the JSON parity files so the package script does not rely on a global Vitest name filter for every file. Keep the device workflow filter scoped to the parity files where it selects only the device suites. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Respect configured file path rendering before applying runtime verbosity defaults. Append next steps to an existing text content item even when a later non-text item is present, so mixed-content responses do not silently drop guidance. Co-Authored-By: OpenAI Codex <codex@openai.com>
Return the current xcode bridge call-result schema version from daemon routed invocations and update the JSON fixtures that exercise that contract. Co-Authored-By: OpenAI Codex <codex@openai.com>
Cover additional CLI and MCP snapshot surfaces by normalizing volatile process, device, Xcode, cache, and user values. Add the missing MCP text fixture for session profile persistence so the runtime mode matrix stays complete. Co-Authored-By: OpenAI Codex <codex@openai.com>
Reuse the filtered failed test case list instead of repeating the same predicate for both detection and filtering. Co-Authored-By: OpenAI Codex <codex@openai.com>
|
Validated the Cursor Bugbot autofix note for the device snapshot test filter. This was already fixed in 34fd3c7 by splitting |
Require Xcode IDE bridge helpers to receive an explicit schema version and pass version 2 from status, sync, and disconnect callers.
Add the missing swift_package_run manifest next-step template so daemon-routed CLI invocations can render the stop instruction from handler-provided nextStepParams. Normalize PID string values in snapshot output so text and JSON fixtures use the same <PID> sentinel as numeric processId fields.
There was a problem hiding this comment.
stopAllRunningSwiftPackageProcesses parses normalized fixture text for real process IDs, always getting 99999 (src/snapshot-tests/suites/swift-package-suite.ts:17)
JSON.parse(text) on line 22 operates on formatStructuredEnvelopeFixture output, which replaces every processId with 99999 (see json-normalize.ts line 53). The loop will always try to stop PID 99999, fail silently (no such process), then loop forever since activeProcesses still holds the real PIDs. Use structuredEnvelope.data.processes instead — it carries the unnormalized envelope.
Verification
Traced full call chain: createMcpJsonSnapshotHarness (json-harness.ts) wraps createMcpSnapshotHarness and returns text: formatStructuredEnvelopeFixture(envelope). formatStructuredEnvelopeFixture calls normalizeStructuredEnvelope → normalizeValue → normalizeNumber, which maps any key named processId to the literal number 99999 (json-normalize.ts lines 53-55). The structuredEnvelope field in the same return value is the original unmodified envelope. swift_package_stop (swift_package_stop.ts lines 101-104) does a processManager.getProcess(params.pid) lookup — pid 99999 is never found, returns didError: true without throwing. Because the caller discards isError from the stop invocation, the while-true loop spins indefinitely until the test framework hits its timeout.
Identified by Warden find-bugs
Normalize MAC_OS_X SDK build setting values, handle y-before-x UI frame objects, and keep Swift package run JSON fixtures aligned with next-step output.
Keep fixture-specific Warden coverage focused on snapshot and structured output contracts, but stop general test-boundary and PII checks from reviewing generated snapshot fixture artifacts one file at a time. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Avoid running Warden over generated snapshot fixture artifacts one file at a time. Snapshot and schema tests validate generated fixture output; Warden now reviews the fixture contracts, normalizers, and schema tests that control the fixture contract. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Normalize volatile SDK_DIR build-setting keys in structured and text snapshot fixtures, and include video-recording captures in the v2 capture-result schema. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Replace nested and duplicate response-helper branches with clearer direct control flow. This addresses locally reproduced Warden simplifier feedback without changing output behavior. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Allow snapshot normalization to handle the standard /Applications/Xcode.app install path as well as versioned Xcode bundle names. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Normalize LLDB breakpoint byte offsets in snapshot output and update the affected CLI/MCP JSON/text fixtures. Also avoid retaining stale MCP tool registrations when a previously registered tool fails to import during workflow re-selection. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Add an explicit text-content guard when appending next-step text and reset persisted session defaults profile state after MCP snapshot tests that exercise persist:true. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Tighten snapshot harness error-state checks, keep error envelopes compatible with the error schema, and simplify the response helper cleanup Warden flagged. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Inline trivial test-runtime helper calls in typed-tool-factory while preserving the MCP runtime branch for minimal output and MCP next-step formatting.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue. You can view the agent here.
Reviewed by Cursor Bugbot for commit 48c9078. Configure here.
Require tool handlers to receive an explicit ToolHandlerContext instead of supporting a no-context test response path. Update unit tests to use the shared callHandler helper so tests provide context explicitly. Remove the env-driven MCP next-step fallback test because MCP output should be verified through the MCP boundary, not by forcing runtime state in handler scaffolding. Document the no-fallback rule in AGENTS.md and CLAUDE.md. Co-Authored-By: Codex <codex@openai.com>


Add next-step instructions to CLI and MCP runtime responses across structured JSON and text output modes.
The motivation is to make runtime responses more useful for both people and agents without baking transport-specific verbosity policy into the runtime. Runtime now decides whether a response is minimal or normal, while CLI can expose that as an override: CLI defaults to normal, MCP defaults to minimal, and CLI callers can request the MCP-style minimal output when using the CLI from AI agents to save tokens.
This also refactors snapshot fixtures so coverage is explicit across the four supported output surfaces: MCP JSON, MCP text, CLI JSON, and CLI text. That makes future response contract changes easier to review because fixture expectations are grouped by runtime and output mode instead of being inferred from older shared fixture paths.
Reviewers should pay close attention to the structured-output envelope and schema version changes. The intent is to add/compact data inside the structured payload while preserving the standard envelope fields.