zidane 7.0.30 → 7.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +2 -2
  2. package/dist/{acp-Cu879kus.js → acp-bBDF-dhy.js} +2 -2
  3. package/dist/{acp-Cu879kus.js.map → acp-bBDF-dhy.js.map} +1 -1
  4. package/dist/acp-cli.js +3 -3
  5. package/dist/acp.d.ts +1 -1
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-BipX4BBj.js → agent-BCG9JcZl.js} +199 -31
  8. package/dist/agent-BCG9JcZl.js.map +1 -0
  9. package/dist/agent.d.ts +1 -1
  10. package/dist/agent.js +1 -1
  11. package/dist/{approvals-staFZZ5o.js → approvals-DkwGBMZ9.js} +372 -19
  12. package/dist/approvals-DkwGBMZ9.js.map +1 -0
  13. package/dist/{auth-D4MpTfvF.js → auth-D0BHBb02.js} +2 -2
  14. package/dist/{auth-D4MpTfvF.js.map → auth-D0BHBb02.js.map} +1 -1
  15. package/dist/chat/pure.d.ts +3 -3
  16. package/dist/chat/pure.js +1 -1
  17. package/dist/chat.d.ts +6 -6
  18. package/dist/chat.js +6 -6
  19. package/dist/{context-transport-BqYwzJYE.js → context-transport-T_6AYIvy.js} +2 -2
  20. package/dist/{context-transport-BqYwzJYE.js.map → context-transport-T_6AYIvy.js.map} +1 -1
  21. package/dist/contexts/daytona.d.ts +1 -1
  22. package/dist/contexts/e2b.d.ts +1 -1
  23. package/dist/daemon-cli.js +1 -1
  24. package/dist/eval.d.ts +1 -1
  25. package/dist/extensions.d.ts +2 -2
  26. package/dist/extensions.js +2 -2
  27. package/dist/headless.d.ts +1 -1
  28. package/dist/headless.js +1 -1
  29. package/dist/{index-C0y2tSgk.d.ts → index-CCB05-JZ.d.ts} +104 -10
  30. package/dist/index-CCB05-JZ.d.ts.map +1 -0
  31. package/dist/{index-CnXKeZ8p.d.ts → index-Ogi2CeHf.d.ts} +179 -6
  32. package/dist/index-Ogi2CeHf.d.ts.map +1 -0
  33. package/dist/index.d.ts +2 -2
  34. package/dist/index.js +3 -3
  35. package/dist/{ipc-CbkrpfkI.js → ipc-C10lnS-a.js} +2 -2
  36. package/dist/{ipc-CbkrpfkI.js.map → ipc-C10lnS-a.js.map} +1 -1
  37. package/dist/ipc.d.ts +5 -5
  38. package/dist/ipc.js +3 -3
  39. package/dist/{mcp-BIWa57eY.js → mcp-CgNd-f3F.js} +3 -3
  40. package/dist/{mcp-BIWa57eY.js.map → mcp-CgNd-f3F.js.map} +1 -1
  41. package/dist/mcp.d.ts +1 -1
  42. package/dist/mcp.js +1 -1
  43. package/dist/output/stream-json.d.ts +1 -1
  44. package/dist/output/terminal.d.ts +1 -1
  45. package/dist/plugins.d.ts +1 -1
  46. package/dist/presets.d.ts +1 -1
  47. package/dist/presets.js +1 -1
  48. package/dist/providers/anthropic.d.ts +1 -1
  49. package/dist/providers/arcee.d.ts +1 -1
  50. package/dist/providers/baseten.d.ts +1 -1
  51. package/dist/providers/cerebras.d.ts +1 -1
  52. package/dist/providers/local.d.ts +1 -1
  53. package/dist/providers/openai-compat.d.ts +1 -1
  54. package/dist/providers/openai.d.ts +1 -1
  55. package/dist/providers/openrouter.d.ts +1 -1
  56. package/dist/providers/xai.d.ts +1 -1
  57. package/dist/providers.d.ts +1 -1
  58. package/dist/restate.d.ts +1 -1
  59. package/dist/restate.js +1 -1
  60. package/dist/{server-GJ2gNRt_.js → server--mwNA7oC.js} +7 -7
  61. package/dist/{server-GJ2gNRt_.js.map → server--mwNA7oC.js.map} +1 -1
  62. package/dist/session/sqlite.d.ts +1 -1
  63. package/dist/session.d.ts +1 -1
  64. package/dist/skills.d.ts +1 -1
  65. package/dist/{src-DzzhE2YO.js → src-CjkY6fBj.js} +2 -2
  66. package/dist/{src-DzzhE2YO.js.map → src-CjkY6fBj.js.map} +1 -1
  67. package/dist/{stdio-loader-CI4sPFve.js → stdio-loader-Bbx19dMZ.js} +2 -2
  68. package/dist/{stdio-loader-CI4sPFve.js.map → stdio-loader-Bbx19dMZ.js.map} +1 -1
  69. package/dist/{tool-formatters-bbgUM3zI.d.ts → tool-formatters-Bu4repDJ.d.ts} +2 -2
  70. package/dist/{tool-formatters-bbgUM3zI.d.ts.map → tool-formatters-Bu4repDJ.d.ts.map} +1 -1
  71. package/dist/tools/fetch-url.d.ts +1 -1
  72. package/dist/tools/web-search.d.ts +1 -1
  73. package/dist/tools.d.ts +1 -1
  74. package/dist/tools.js +1 -1
  75. package/dist/{transcript-anchors-BHyrChoO.d.ts → transcript-anchors-CJCxyVE-.d.ts} +8 -2
  76. package/dist/transcript-anchors-CJCxyVE-.d.ts.map +1 -0
  77. package/dist/tui.d.ts +3 -3
  78. package/dist/tui.d.ts.map +1 -1
  79. package/dist/tui.js +69 -14
  80. package/dist/tui.js.map +1 -1
  81. package/dist/{turn-operations-BgqpLlOG.js → turn-operations-HX3g3XIc.js} +11 -1
  82. package/dist/{turn-operations-BgqpLlOG.js.map → turn-operations-HX3g3XIc.js.map} +1 -1
  83. package/dist/{turn-operations-ZP5-2OWi.d.ts → turn-operations-qcv9UFcL.d.ts} +3 -3
  84. package/dist/{turn-operations-ZP5-2OWi.d.ts.map → turn-operations-qcv9UFcL.d.ts.map} +1 -1
  85. package/dist/types-CWgENVLY.js.map +1 -1
  86. package/dist/types.d.ts +2 -2
  87. package/docs/ARCHITECTURE.md +11 -2
  88. package/docs/CHAT.md +1 -0
  89. package/docs/INTERACTIONS.md +14 -2
  90. package/docs/SKILL.md +3 -1
  91. package/docs/TUI.md +5 -3
  92. package/package.json +1 -1
  93. package/dist/agent-BipX4BBj.js.map +0 -1
  94. package/dist/approvals-staFZZ5o.js.map +0 -1
  95. package/dist/index-C0y2tSgk.d.ts.map +0 -1
  96. package/dist/index-CnXKeZ8p.d.ts.map +0 -1
  97. package/dist/transcript-anchors-BHyrChoO.d.ts.map +0 -1
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { $_ as SessionRun, $g as StreamHookContext, Ag as OAuthRefreshHookContext, Bg as RepeatGuardToolMatcher, Br as InteractionToolOptions, C as SuccessfulMutationOutcome, C_ as ToolMap, Cm as ToolResult, Dh as AnthropicParams, E_ as ReadStateMap, Eg as McpToolHookContext, F_ as ToolStateController, Fg as PromptImagePart, G_ as SkillResource, Gg as SessionContentBlock, Hg as ResolveContentRefBlock, I_ as ToolStateOp, Ig as PromptPart, Im as OpenRouterParams, J_ as CreateSessionOptions, Jg as SessionMessage, Ji as AgentHookMap, Kg as SessionEndStatus, L_ as ToolStateStore, Lg as PromptTextPart, Mg as ProgressNudgeMessage, Ng as PromptAudioPart, P_ as StagedToolState, Pg as PromptDocumentPart, R_ as ToolStateView, Rg as PromptVideoPart, S as MutationValidationResult, S_ as ToolDef, Sm as ToolCall, T_ as ReadStateEntry, Tg as McpServerConfig, Tm as TurnResult, U_ as SkillConfig, Ug as RetryConfig, Vg as ResolveContentRef, Wg as RunHookMap, X_ as Session, Xg as SpawnHookContext, Xi as AgentOptions, Yg as SessionTurn, Yi as AgentHooks, Z_ as SessionData, _ as statsByModel, __ as TurnUsage, _m as ProviderCapabilities, a_ as ToolHookContext, b as MutationValidationHooksOptions, b_ as toolResultToText, bg as DEFAULT_AGENT_CLOCK, bm as StreamOptions, c_ as ToolResultContent, cc as ChildAgent, cg as AgentBehavior, d_ as ToolResultImageContent, dg as AgentStats, ev as SessionStore, f_ as ToolResultImageRefContent, g_ as TurnFinishReason, gm as Provider, h as flattenTurns, h_ as ToolResultVideoContent, hg as ChildRunStats, jg as ProgressNudgeKind, l_ as ToolResultDocumentContent, lg as AgentClock, m_ as ToolResultTextContent, mc as SpawnToolState, o_ as ToolOutcome, oh as OpenAIParams, p as ModelUsage, p_ as ToolResultMetadata, pc as SpawnToolOptions, q_ as SkillsConfig, qg as SessionHookContext, qi as Agent, r_ as ThinkingLevel, s_ as ToolResultAudioContent, t as Preset, ty as McpConnection, u_ as ToolResultDocumentRefContent, ug as AgentRunOptions, uv as RemoteStoreOptions, v as MutationValidationBatch, v_ as toolOutputBudgetByteLength, vh as CerebrasParams, vr as ValidationResult, wm as ToolSpec, x as MutationValidationMutation, x_ as ToolContext, y as MutationValidationFailure, y_ as toolOutputByteLength, ym as StreamCallbacks, zg as RepeatGuardConfig } from "./index-C0y2tSgk.js";
1
+ import { $_ as SessionData, B_ as ToolStateView, Bg as PromptVideoPart, Br as InteractionToolOptions, C as SuccessfulMutationOutcome, C_ as ToolContext, D_ as ReadStateEntry, Dg as McpServerConfig, Dm as TurnResult, Em as ToolSpec, Fg as PromptAudioPart, G_ as SkillConfig, Gg as RetryConfig, Hg as RepeatGuardToolMatcher, I_ as StagedToolState, Ig as PromptDocumentPart, Jg as SessionEndStatus, Ji as AgentHookMap, Kg as RunHookMap, L_ as ToolStateController, Lg as PromptImagePart, Mg as OAuthRefreshHookContext, Ng as ProgressNudgeKind, O_ as ReadStateMap, Og as McpToolHookContext, Pg as ProgressNudgeMessage, Q_ as Session, Qg as SpawnHookContext, R_ as ToolStateOp, Rg as PromptPart, Rm as OpenRouterParams, S as MutationValidationResult, S_ as toolResultToText, Sg as DEFAULT_AGENT_CLOCK, Sm as StreamOptions, T_ as ToolMap, Tm as ToolResult, Ug as ResolveContentRef, Vg as RepeatGuardConfig, Wg as ResolveContentRefBlock, X_ as CreateSessionOptions, Xg as SessionMessage, Xi as AgentOptions, Y_ as SkillsConfig, Yg as SessionHookContext, Yi as AgentHooks, Zg as SessionTurn, Zi as AgentToolState, _ as statsByModel, __ as ToolResultVideoContent, _g as ChildRunStats, a_ as ThinkingLevel, b as MutationValidationHooksOptions, b_ as toolOutputBudgetByteLength, bh as CerebrasParams, c_ as ToolOutcome, ch as OpenAIParams, d_ as ToolResultDocumentContent, dg as AgentClock, f_ as ToolResultDocumentRefContent, fg as AgentRunOptions, fv as RemoteStoreOptions, g_ as ToolResultTextContent, gc as SpawnToolState, h as flattenTurns, h_ as ToolResultMetadata, hc as SpawnToolOptions, kh as AnthropicParams, l_ as ToolResultAudioContent, m_ as ToolResultImageRefContent, nv as SessionStore, p as ModelUsage, p_ as ToolResultImageContent, pg as AgentStats, q_ as SkillResource, qg as SessionContentBlock, qi as Agent, ry as McpConnection, s_ as ToolHookContext, t as Preset, t_ as StreamHookContext, tv as SessionRun, u_ as ToolResultContent, uc as ChildAgent, ug as AgentBehavior, v as MutationValidationBatch, v_ as TurnFinishReason, vm as Provider, vr as ValidationResult, w_ as ToolDef, wm as ToolCall, x as MutationValidationMutation, x_ as toolOutputByteLength, xm as StreamCallbacks, y as MutationValidationFailure, y_ as TurnUsage, ym as ProviderCapabilities, z_ as ToolStateStore, zg as PromptTextPart } from "./index-CCB05-JZ.js";
2
2
  import { d as ClassifiedErrorKind, i as AgentContextExceededError, l as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, n as AgentAbortedError, o as AgentProviderError, p as matchesContextExceeded, r as AgentBudgetExceededError, s as AgentToolNotAllowedError, u as ClassifiedError } from "./timeout-DEaqslLO.js";
3
3
  import { _ as TaskHandle, a as ContextType, c as ExecutionContext, g as TaskExitInfo, h as TaskEntry, l as ExecutionHandle, n as ContextCapabilities, o as DetachedTasksCapability, p as SpawnConfig, r as ContextHardening, s as ExecResult, t as BackgroundTaskStatus, v as TaskStallInfo } from "./types-U-rIVUDw.js";
4
4
  import { t as SandboxProvider } from "./sandbox-CDl9tfTo.js";
5
- export { type Agent, AgentAbortedError, type AgentBehavior, AgentBudgetExceededError, type AgentClock, AgentContextExceededError, type AgentHookMap, type AgentHooks, type AgentOptions, AgentProviderError, type AgentRunOptions, type AgentStats, AgentToolNotAllowedError, type AnthropicParams, type BackgroundTaskStatus, CONTEXT_EXCEEDED_MESSAGE_PATTERNS, type CerebrasParams, type ChildAgent, type ChildRunStats, type ClassifiedError, type ClassifiedErrorKind, type ContextCapabilities, type ContextHardening, type ContextType, type CreateSessionOptions, DEFAULT_AGENT_CLOCK, type DetachedTasksCapability, type ExecResult, type ExecutionContext, type ExecutionHandle, type InteractionToolOptions, type McpConnection, type McpServerConfig, type McpToolHookContext, type ModelUsage, type MutationValidationBatch, type MutationValidationFailure, type MutationValidationHooksOptions, type MutationValidationMutation, type MutationValidationResult, type OAuthRefreshHookContext, type OpenAIParams, type OpenRouterParams, type Preset, type ProgressNudgeKind, type ProgressNudgeMessage, type PromptAudioPart, type PromptDocumentPart, type PromptImagePart, type PromptPart, type PromptTextPart, type PromptVideoPart, type Provider, type ProviderCapabilities, type ReadStateEntry, type ReadStateMap, type RemoteStoreOptions, type RepeatGuardConfig, type RepeatGuardToolMatcher, type ResolveContentRef, type ResolveContentRefBlock, type RetryConfig, type RunHookMap, type SandboxProvider, type Session, type SessionContentBlock, type SessionData, type SessionEndStatus, type SessionHookContext, type SessionMessage, type SessionRun, type SessionStore, type SessionTurn, type SkillConfig, type SkillResource, type SkillsConfig, type SpawnConfig, type SpawnHookContext, type SpawnToolOptions, type SpawnToolState, type StagedToolState, type StreamCallbacks, type StreamHookContext, type StreamOptions, type SuccessfulMutationOutcome, type TaskEntry, type TaskExitInfo, type TaskHandle, type TaskStallInfo, type ThinkingLevel, type ToolCall, type ToolContext, type ToolDef, type ToolHookContext, type ToolMap, type ToolOutcome, type ToolResult, type ToolResultAudioContent, type ToolResultContent, type ToolResultDocumentContent, type ToolResultDocumentRefContent, type ToolResultImageContent, type ToolResultImageRefContent, type ToolResultMetadata, type ToolResultTextContent, type ToolResultVideoContent, type ToolSpec, type ToolStateController, type ToolStateOp, type ToolStateStore, type ToolStateView, type TurnFinishReason, type TurnResult, type TurnUsage, type ValidationResult, flattenTurns, matchesContextExceeded, statsByModel, toolOutputBudgetByteLength, toolOutputByteLength, toolResultToText };
5
+ export { type Agent, AgentAbortedError, type AgentBehavior, AgentBudgetExceededError, type AgentClock, AgentContextExceededError, type AgentHookMap, type AgentHooks, type AgentOptions, AgentProviderError, type AgentRunOptions, type AgentStats, AgentToolNotAllowedError, type AgentToolState, type AnthropicParams, type BackgroundTaskStatus, CONTEXT_EXCEEDED_MESSAGE_PATTERNS, type CerebrasParams, type ChildAgent, type ChildRunStats, type ClassifiedError, type ClassifiedErrorKind, type ContextCapabilities, type ContextHardening, type ContextType, type CreateSessionOptions, DEFAULT_AGENT_CLOCK, type DetachedTasksCapability, type ExecResult, type ExecutionContext, type ExecutionHandle, type InteractionToolOptions, type McpConnection, type McpServerConfig, type McpToolHookContext, type ModelUsage, type MutationValidationBatch, type MutationValidationFailure, type MutationValidationHooksOptions, type MutationValidationMutation, type MutationValidationResult, type OAuthRefreshHookContext, type OpenAIParams, type OpenRouterParams, type Preset, type ProgressNudgeKind, type ProgressNudgeMessage, type PromptAudioPart, type PromptDocumentPart, type PromptImagePart, type PromptPart, type PromptTextPart, type PromptVideoPart, type Provider, type ProviderCapabilities, type ReadStateEntry, type ReadStateMap, type RemoteStoreOptions, type RepeatGuardConfig, type RepeatGuardToolMatcher, type ResolveContentRef, type ResolveContentRefBlock, type RetryConfig, type RunHookMap, type SandboxProvider, type Session, type SessionContentBlock, type SessionData, type SessionEndStatus, type SessionHookContext, type SessionMessage, type SessionRun, type SessionStore, type SessionTurn, type SkillConfig, type SkillResource, type SkillsConfig, type SpawnConfig, type SpawnHookContext, type SpawnToolOptions, type SpawnToolState, type StagedToolState, type StreamCallbacks, type StreamHookContext, type StreamOptions, type SuccessfulMutationOutcome, type TaskEntry, type TaskExitInfo, type TaskHandle, type TaskStallInfo, type ThinkingLevel, type ToolCall, type ToolContext, type ToolDef, type ToolHookContext, type ToolMap, type ToolOutcome, type ToolResult, type ToolResultAudioContent, type ToolResultContent, type ToolResultDocumentContent, type ToolResultDocumentRefContent, type ToolResultImageContent, type ToolResultImageRefContent, type ToolResultMetadata, type ToolResultTextContent, type ToolResultVideoContent, type ToolSpec, type ToolStateController, type ToolStateOp, type ToolStateStore, type ToolStateView, type TurnFinishReason, type TurnResult, type TurnUsage, type ValidationResult, flattenTurns, matchesContextExceeded, statsByModel, toolOutputBudgetByteLength, toolOutputByteLength, toolResultToText };
@@ -439,16 +439,25 @@ installLazyDisclosureGate // tool:gate refuses lazy ∉ u
439
439
 
440
440
  per turn — buildFormattedTools() emits in two phases:
441
441
  1. registry-order walk filtered by initialUnlocked ← byte-stable cached prefix
442
- 2. dynamicUnlockOrder, in unlock order ← append-only tail
442
+ 2. dynamicUnlockOrder, in unlock order ← append-only tail (omitted in dispatch mode)
443
443
 
444
444
  tool_search({ names | query | server, limit? }): unlocks matches, returns inlined input_schema JSON
445
445
 
446
+ dispatch mode (toolSearch.mode: 'dispatch'):
447
+ tools.call_tool = createCallToolTool() ← eager, fixed { name, arguments } envelope
448
+ model: call_tool({ name: 'mcp_srv_a', arguments })
449
+ loop (after wire→canonical rewrite): unwrapDispatchCalls()
450
+ → ToolCall { id, name: 'mcp_srv_a', input: arguments } for gate / validation / hooks / events
451
+ persisted assistant turn keeps the call_tool block ← wire-valid history
452
+ store.eventsFromTurns: unwrapCallTool() on replay ← reload matches the live transcript
453
+
446
454
  run end: uninstallLazyDisclosureGate; per-run state GC-eligible on next run()
447
455
  ```
448
456
 
449
457
  - **Aliasing.** `LazyToolEntry.name` is the wire name; `.canonicalName` keys `unlocked` and dispatches `ctx.tools[name]`. `session.turns` / `ToolHookContext.name` stay canonical throughout.
450
458
  - **Hard gate vs. provider validation.** Anthropic/OpenAI already refuse `tool_use` blocks for tools absent from the request; the gate exists for lenient/custom/mock providers and makes the lazy boundary observable via `tool:gate`.
451
- - **Cache-stable injection.** Every `tool_search` call invalidates only the wire tools array's SUFFIX starting at the first new schema — the eager + `tool_search` prefix never moves.
459
+ - **Cache cost of unlock mode.** The eager + `tool_search` prefix of the wire array never moves, but providers hash the request as `tools → system → messages`: a grown tail still re-bills the system prompt and every message on that turn. That is one full prompt-cache rewrite per discovery wave.
460
+ - **Dispatch mode.** `toolSearch.mode: 'dispatch'` keeps the tools array byte-stable: surfaced tools are invoked through `call_tool` (`src/tools/call-tool.ts`). The unwrap happens once, in `runTurn` right after the alias rewrite, so the whole downstream pipeline (lazy gate, MCP gates, `validateToolArgs` against the INNER schema, `tool:before/after`, tracing, run counts, both dispatch paths) is unchanged and sees the inner tool. Only lazy catalog tools are unwrapped: an envelope around an eager tool stays a `call_tool` call and its `execute` says to call the tool directly (history scanners keyed on `block.name`, read-state seeding, task tracking, keep seeing eager tools under their own names). A malformed envelope is left as `call_tool` so its own schema validation reports the shape error. A host-defined `call_tool` disables dispatch mode (the run falls back to unlock). The chat hosts expose this as `Settings.stableToolList`.
452
461
  - **Host-defined `tool_search`.** A host tool named `tool_search` shadows auto-injection; it must call `createToolSearchTool({ catalog, unlocked, addUnlock? })` to drive unlocks, or use `toolSearch.tool: false` for a fully custom flow.
453
462
 
454
463
  ## Hook Firing Order
package/docs/CHAT.md CHANGED
@@ -247,6 +247,7 @@ Both join `[...doctrine, userInstructions]` as the **static** half and `[envSect
247
247
  | `showAllProjects` | `boolean` | `false` | Sessions list scope. |
248
248
  | `resumeLastSession` | `boolean` | `true` | |
249
249
  | `persistToolResults` | `boolean` | `true` | See **Tool-result persistence**. |
250
+ | `stableToolList` | `boolean` | `false` | Lazy MCP tools surfaced by `tool_search` are invoked through `call_tool` instead of growing the model's tool list (`behavior.toolSearch.mode: 'dispatch'`), so discovery never rewrites the prompt cache. Transcript shows the inner tool as with a direct call. |
250
251
  | `autoCompact` | `boolean` | `true` | See **Auto-compaction**. |
251
252
  | `autoCompactThreshold` | `number` | `0.8` | Cycles 0.6/0.7/0.8/0.9 in the settings modal. |
252
253
  | `resumeOnMaxTokens`, `maxOutputTokens`, `maxTurns`, `retryMaxAttempts`, `maxCostUsd`, `maxTotalTokens`, `maxWallMinutes` | mixed | off/`0` | Runaway ceilings; all off by default (model-driven, uncapped). |
@@ -87,7 +87,10 @@ user's own selection rather than resetting it.
87
87
  Response shape:
88
88
 
89
89
  ```json
90
- { "answers": { "name": "Jane", "notes": "...", "fw": "react", "go": true } }
90
+ {
91
+ "answers": { "name": "Jane", "notes": "...", "fw": "react", "go": true },
92
+ "instructions": "Also keep the old endpoint alive until the migration lands."
93
+ }
91
94
  ```
92
95
 
93
96
  Missing keys = question was skipped (only possible when `required:
@@ -95,12 +98,21 @@ false`). Empty-string answers and empty multi-select picks are dropped
95
98
  at serialization; a multi-select (`type: 'select'`, `multi: true`)
96
99
  answers as an array of choice ids.
97
100
 
101
+ `instructions` is free text the user attached to the whole form. Every
102
+ surface offers it unconditionally (the TUI wizard ends on an "additional
103
+ instructions" step, the GUI modal has a permanent textarea under the
104
+ questions), so the user can always refine or override the questions
105
+ instead of being boxed into the model's choices. Omitted when left empty.
106
+ The tool description tells the model it is authoritative.
107
+
98
108
  ## Keyboard
99
109
 
100
110
  In the question wizard (multi-question batches):
101
111
 
102
112
  - `↑/↓` (or `j/k`) — navigate options
103
- - `↵` — submit the active question / pick the focused option
113
+ - `↵` — submit the active question / pick the focused option. The last
114
+ step is always "additional instructions" (optional textarea): `↵` on an
115
+ empty box sends the answers as they are.
104
116
  - `space` — toggle the focused option (multi-selects only; `↵` submits
105
117
  the whole selection, at least one pick required unless `required: false`)
106
118
  - `shift+↹` — back one question (preserves your answers, pre-fills the
package/docs/SKILL.md CHANGED
@@ -688,7 +688,9 @@ createAgent({
688
688
 
689
689
  The system prompt gains a `<searchable_tools>` block. `tool_search({ query, names, server, limit })` returns matching schemas and unlocks them for the rest of the run. A `tool:gate` middleware refuses un-surfaced lazy tools. Catalog + search results show the **wire** name; the unlock set keys on canonical so dispatch / `session.turns` stay alias-stable.
690
690
 
691
- `behavior.toolSearch` knobs (no-op in eager mode): `tool: false` opts out of auto-injection; `limit: 20` caps default results. Per-server `disclosure: 'eager' | 'lazy'` overrides the agent default; run-level overrides agent-level. Cost: one cache miss per discovery wave; subsequent turns hit cache normally.
691
+ `behavior.toolSearch` knobs (no-op in eager mode): `tool: false` opts out of auto-injection; `limit: 20` caps default results; `mode: 'unlock' | 'dispatch'` picks how a surfaced tool becomes callable. Per-server `disclosure: 'eager' | 'lazy'` overrides the agent default; run-level overrides agent-level.
692
+
693
+ Cost: in `'unlock'` mode (default) every discovery wave grows the tools array, and since providers hash `tools → system → messages` that is a **full** prompt-cache rewrite each time. `'dispatch'` mode keeps the tools array byte-stable: a fixed `call_tool { name, arguments }` native tool is added, surfaced tools are invoked through it, and the loop unwraps the envelope before dispatch so gating, schema validation (against the inner tool), hooks and transcript events see the inner tool exactly as a direct call. Chat hosts expose it as `Settings.stableToolList`.
692
694
 
693
695
  ## Skills
694
696
 
package/docs/TUI.md CHANGED
@@ -305,7 +305,7 @@ createRoot(renderer).render(<App config={config} />)
305
305
 
306
306
  ## Auto-update
307
307
 
308
- The footer polls npm once a day for a newer `zidane-tui` release and shows a passive `↑ vX.Y.Z` chip (cache-driven, 3s timeout, never blocks boot). Opt out via `Settings.checkForUpdates` or `ZIDANE_NO_UPDATE`/`NO_UPDATE_NOTIFIER`/`CI`. It also shows a transient prompt-cache toast (`⚡ cache break · <culprit> · +Nk tok · ~$0.48` warn-colored, or dim `⚡ cache expired · …` for TTL-only breaks) for ~8s after a `'cache:break'` hook fires.
308
+ The footer polls npm once a day for a newer `zidane-tui` release and shows a passive `↑ vX.Y.Z` chip (cache-driven, 3s timeout, never blocks boot). Opt out via `Settings.checkForUpdates` or `ZIDANE_NO_UPDATE`/`NO_UPDATE_NOTIFIER`/`CI`. Once a newer build is actually **on disk** — `zidane upgrade` in another terminal, or the GUI's in-app update — the chip flips to `↻ vX.Y.Z` and a one-time info line says `zidane vX.Y.Z is installed — restart to update`. That probe (`useRestartRequired` / `watchInstalledVersion`) resolves the installed version from the `zidane` bin on PATH, wakes on the `<cacheDir>/update-applied.json` marker every installer writes, and re-polls every 5 min; it is independent of `checkForUpdates` since it costs no network. It also shows a transient prompt-cache toast (`⚡ cache break · <culprit> · +Nk tok · ~$0.48` warn-colored, or dim `⚡ cache expired · …` for TTL-only breaks) for ~8s after a `'cache:break'` hook fires.
309
309
 
310
310
  ```bash
311
311
  zidane upgrade # check + run the host package manager
@@ -326,10 +326,12 @@ if (process.argv[2] === 'upgrade') {
326
326
  const result = await runUpdateCommand({ packageName: 'my-cli', currentVersion: pkg.version, argv: process.argv.slice(3) })
327
327
  process.exit(result.exitCode)
328
328
  }
329
- await runTui({ autoUpdate: { packageName: 'my-cli', currentVersion: pkg.version } })
329
+ await runTui({ autoUpdate: { packageName: 'my-cli', currentVersion: pkg.version, binName: 'my-cli' } })
330
330
  ```
331
331
 
332
- `checkForUpdate`, `useUpdateCheck`, `buildUpdateHint`, `performSelfUpdate`, `performInPlaceSelfUpdate`, `detectPackageManager`, `resolvePlatformPackage`, `runUpdateCommand`, `compareSemver` all live in `zidane/chat` — no React-DOM/OpenTUI dependency.
332
+ A GUI (or any host whose `process.execPath` is not the package's bin) uses `upgradeInstalledPackages({ targets: [{ packageName: 'zidane-gui' }, { packageName: 'zidane-tui', binName: 'zidane' }] })` instead: every installed target is located by its bin, upgraded through the package manager that owns it, verified on disk, and reported as a structured `UpgradeReport` with `onProgress` events for a live status line. This is what the zidane GUI's footer `↑ vX.Y.Z` button runs; it then offers `↻ vX.Y.Z` → relaunch.
333
+
334
+ `checkForUpdate`, `useUpdateCheck`, `buildUpdateHint`, `buildRestartHint`, `useRestartRequired`, `watchInstalledVersion`, `upgradeInstalledPackages`, `performSelfUpdate`, `performInPlaceSelfUpdate`, `detectPackageManager`, `resolvePlatformPackage`, `runUpdateCommand`, `compareSemver` all live in `zidane/chat` — no React-DOM/OpenTUI dependency.
333
335
 
334
336
  ## File layout
335
337
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zidane",
3
- "version": "7.0.30",
3
+ "version": "7.0.32",
4
4
  "description": "an agent that goes straight to the goal",
5
5
  "type": "module",
6
6
  "private": false,