Merge remote-tracking branch 'origin/master' into codex/project-instruction-files

# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	packages/README.md
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/tools/README.md
#	packages/core/tools/src/index.ts
#	packages/ui/stdio-agent/tests/built-bin.e2e.ts
This commit is contained in:
Yichen Jiang
2026-07-15 13:25:44 +08:00
62 changed files with 708 additions and 514 deletions

View File

@@ -150,7 +150,6 @@ type ToolGuard = (execution: Readonly<ToolExecution>) => string | undefined
```ts type-equiv
interface ToolExecutionResult {
callId: CallId
content: ContentBlock[]
isError: boolean
/**
@@ -178,6 +177,8 @@ interface ToolExecutionResult {
}
```
The result carries only the outcome. Call identity remains on the immutable `ToolExecution` that accompanies it through every hook and on the durable `tool/call` / `tool/result` session events, so wrappers cannot create a second, disagreeing identity.
The registry materializes and freezes the final accepted result immediately before `tools/result`. Its content, structured error, additional context, and presentation metadata must round-trip losslessly through JSON; an invalid outcome becomes a JSON-safe `isError` result, so the observed live outcome is safe for the later durable `tool/result` append.
Each interception waterfall returns a typed **Decision** (the idiom shared with the `agent/*` seams). `tools/pre-execute` listeners receive `(exec, next)` and return a `PreToolDecision`; `tools/execute` wrappers return a `ToolExecutionResult`; `tools/post-execute` listeners receive `(exec, result, next)` and return a `PostToolDecision`: