feat: command.execute returns the lifecycle pairing id ({matched, commandId?})

CommandService.execute now returns a CommandExecution — the normalized
result plus the commandId minted for its command/run/command/done records —
and the wire admission value carries commandId exactly when matched, so the
issuing client can correlate its RPC acknowledgment with the flow node the
lifecycle events produce. apiproxy api/schema/handler, the connection
fixture, and the TUI/plan/goal consumers follow the new shape.
This commit is contained in:
imccyu
2026-07-27 23:07:13 +08:00
parent 2ebaa30c6d
commit 6d2e5a7cd7
21 files changed
+85 -55

No files matched your search

+7 -3
View File
@@ -921,9 +921,13 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
try {
// Pure admission: the executor's durable command/run + command/done
// pair (broadcast on the mux stream) carries the outcome; the
// response only reports whether the line resolved to a handler.
const result = await commands.execute(found.agent, line, signal)
return ok(request, { matched: result !== undefined })
// response reports whether the line resolved to a handler, plus the
// minted pairing id so the issuing client can correlate its request
// with the flow node the lifecycle events produce.
const execution = await commands.execute(found.agent, line, signal)
return ok(request, execution === undefined
? { matched: false }
: { matched: true, commandId: execution.commandId })
} catch (error: unknown) {
if (signal.aborted) return err(request, { code: 'cancelled', message: 'command execution was aborted', details: {} })
return err(request, { code: 'internal', message: `command failed: ${String(error)}`, details: {} })