zidane 5.14.4 → 6.0.0

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 (202) hide show
  1. package/dist/{acp-24uU2WDs.js → acp-Irby04Us.js} +7 -8
  2. package/dist/{acp-24uU2WDs.js.map → acp-Irby04Us.js.map} +1 -1
  3. package/dist/acp-cli.js +7 -7
  4. package/dist/acp.d.ts +2 -3
  5. package/dist/acp.d.ts.map +1 -1
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-Cch2ayTt.js → agent-DkSmGkDM.js} +10871 -5411
  8. package/dist/agent-DkSmGkDM.js.map +1 -0
  9. package/dist/agent.d.ts +1 -2
  10. package/dist/agent.js +2 -2
  11. package/dist/{anthropic-RGqsJlC8.js → anthropic-CTHsdFG9.js} +46 -6
  12. package/dist/anthropic-CTHsdFG9.js.map +1 -0
  13. package/dist/{auth-C-ms5N2x.js → auth-BDSu_0t3.js} +13 -86
  14. package/dist/auth-BDSu_0t3.js.map +1 -0
  15. package/dist/chat/pure.d.ts +4 -4
  16. package/dist/chat/pure.js +4 -3
  17. package/dist/chat.d.ts +45 -8
  18. package/dist/chat.d.ts.map +1 -1
  19. package/dist/chat.js +9 -6
  20. package/dist/chat.js.map +1 -1
  21. package/dist/completion-core-CXYSVhZo.js +147 -0
  22. package/dist/completion-core-CXYSVhZo.js.map +1 -0
  23. package/dist/{context-breakdown-kO-pDsay.js → context-breakdown-Dzo25N45.js} +2 -23
  24. package/dist/context-breakdown-Dzo25N45.js.map +1 -0
  25. package/dist/contexts/daytona.d.ts +3 -3
  26. package/dist/contexts/daytona.js +1 -1
  27. package/dist/contexts/docker.d.ts +10 -2
  28. package/dist/contexts/docker.d.ts.map +1 -1
  29. package/dist/contexts/docker.js +142 -103
  30. package/dist/contexts/docker.js.map +1 -1
  31. package/dist/contexts/e2b.d.ts +2 -2
  32. package/dist/contexts/e2b.js +1 -1
  33. package/dist/contexts/sandbox.d.ts +1 -1
  34. package/dist/contexts/sandbox.js +4 -1
  35. package/dist/contexts/sandbox.js.map +1 -1
  36. package/dist/{contexts-Lzf5huID.js → contexts-Vone3qQQ.js} +26 -37
  37. package/dist/contexts-Vone3qQQ.js.map +1 -0
  38. package/dist/contexts.d.ts +3 -3
  39. package/dist/contexts.js +1 -1
  40. package/dist/errors.d.ts +1 -2
  41. package/dist/errors.js +1 -1
  42. package/dist/eval.d.ts +1 -1
  43. package/dist/eval.js +3 -3
  44. package/dist/exec-file-size-PXkr-MGA.js +63 -0
  45. package/dist/exec-file-size-PXkr-MGA.js.map +1 -0
  46. package/dist/extensions.d.ts +2 -0
  47. package/dist/extensions.js +2 -0
  48. package/dist/generate-data-WL_yGVL6.js +324 -0
  49. package/dist/generate-data-WL_yGVL6.js.map +1 -0
  50. package/dist/headless.d.ts +1 -1
  51. package/dist/headless.js +15 -10
  52. package/dist/headless.js.map +1 -1
  53. package/dist/index-B8UtiZy7.d.ts +14967 -0
  54. package/dist/index-B8UtiZy7.d.ts.map +1 -0
  55. package/dist/{index-B3ciFUZx.d.ts → index-DsPQbyUn.d.ts} +2 -2
  56. package/dist/index-DsPQbyUn.d.ts.map +1 -0
  57. package/dist/index.d.ts +6 -12
  58. package/dist/index.js +20 -43
  59. package/dist/index.js.map +1 -1
  60. package/dist/{logger-Ktm-lj1s.js → logger-DBX9uYOw.js} +108 -5
  61. package/dist/logger-DBX9uYOw.js.map +1 -0
  62. package/dist/login-DOF8pMVM.js +539 -0
  63. package/dist/login-DOF8pMVM.js.map +1 -0
  64. package/dist/{mcp-Dn5W65Lv.js → mcp-CcvuVXB9.js} +2 -2
  65. package/dist/{mcp-Dn5W65Lv.js.map → mcp-CcvuVXB9.js.map} +1 -1
  66. package/dist/mcp.d.ts +1 -1
  67. package/dist/mcp.js +1 -1
  68. package/dist/{messages-YZQLKaz2.js → messages-CwujiS74.js} +4 -4
  69. package/dist/messages-CwujiS74.js.map +1 -0
  70. package/dist/{openai-compat-0Y7jcncn.js → openai-compat-BvgYGSR1.js} +7 -6
  71. package/dist/{openai-compat-0Y7jcncn.js.map → openai-compat-BvgYGSR1.js.map} +1 -1
  72. package/dist/output/stream-json.d.ts +1 -2
  73. package/dist/output/stream-json.d.ts.map +1 -1
  74. package/dist/output/terminal.d.ts +1 -2
  75. package/dist/output/terminal.d.ts.map +1 -1
  76. package/dist/{glob-DluQFSw1.js → output-cap-kBUHBlnq.js} +50 -2
  77. package/dist/output-cap-kBUHBlnq.js.map +1 -0
  78. package/dist/presets.d.ts +1 -2
  79. package/dist/presets.js +1 -1
  80. package/dist/providers/anthropic.d.ts +2 -2
  81. package/dist/providers/anthropic.js +2 -2
  82. package/dist/providers/arcee.d.ts +1 -1
  83. package/dist/providers/arcee.js +1 -1
  84. package/dist/providers/baseten.d.ts +1 -1
  85. package/dist/providers/baseten.js +1 -1
  86. package/dist/providers/cerebras.d.ts +1 -1
  87. package/dist/providers/cerebras.js +1 -1
  88. package/dist/providers/local.d.ts +1 -1
  89. package/dist/providers/local.js +1 -1
  90. package/dist/providers/openai-compat.d.ts +1 -1
  91. package/dist/providers/openai-compat.js +1 -1
  92. package/dist/providers/openai.d.ts +1 -1
  93. package/dist/providers/openai.js +4 -4
  94. package/dist/providers/openai.js.map +1 -1
  95. package/dist/providers/openrouter.d.ts +1 -1
  96. package/dist/providers/openrouter.js +1 -1
  97. package/dist/providers/xai.d.ts +1 -1
  98. package/dist/providers/xai.js +1 -1
  99. package/dist/{providers-DgmdYGKm.js → providers-z6LDMAr3.js} +3 -3
  100. package/dist/{providers-DgmdYGKm.js.map → providers-z6LDMAr3.js.map} +1 -1
  101. package/dist/providers.d.ts +1 -1
  102. package/dist/providers.js +4 -4
  103. package/dist/{read-state-BymF41Jb.js → read-state-Dq_TXUX1.js} +2 -2
  104. package/dist/{read-state-BymF41Jb.js.map → read-state-Dq_TXUX1.js.map} +1 -1
  105. package/dist/{interpolate-BtIgcCuz.js → resolve-Cr8JSL_O.js} +562 -136
  106. package/dist/resolve-Cr8JSL_O.js.map +1 -0
  107. package/dist/restate.d.ts +2 -2
  108. package/dist/restate.js +2 -2
  109. package/dist/{sandbox-Dgy-m6UF.d.ts → sandbox-CgjG2VvQ.d.ts} +2 -2
  110. package/dist/{sandbox-Dgy-m6UF.d.ts.map → sandbox-CgjG2VvQ.d.ts.map} +1 -1
  111. package/dist/session/sqlite.d.ts +1 -1
  112. package/dist/{session-CqrAFAKJ.js → session-CsdDIPY8.js} +108 -3
  113. package/dist/session-CsdDIPY8.js.map +1 -0
  114. package/dist/session.d.ts +2 -2
  115. package/dist/session.js +3 -3
  116. package/dist/skills-Bsb0rvWI.js +295 -0
  117. package/dist/skills-Bsb0rvWI.js.map +1 -0
  118. package/dist/skills.d.ts +2 -3
  119. package/dist/skills.js +3 -24
  120. package/dist/{errors-CkTvg97v.d.ts → timeout-8vSIRjzl.d.ts} +10 -2
  121. package/dist/timeout-8vSIRjzl.d.ts.map +1 -0
  122. package/dist/{timeout-kGGSXagK.js → timeout-BDetbuN6.js} +59 -2
  123. package/dist/timeout-BDetbuN6.js.map +1 -0
  124. package/dist/tool-formatters-DY0TDb1r.d.ts +378 -0
  125. package/dist/tool-formatters-DY0TDb1r.d.ts.map +1 -0
  126. package/dist/tools/fetch-url.d.ts +1 -1
  127. package/dist/tools/web-search.d.ts +1 -1
  128. package/dist/tools.d.ts +2 -3
  129. package/dist/tools.js +3 -4
  130. package/dist/{transcript-anchors-BHIgMlPq.d.ts → transcript-anchors-Cb-bDbNH.d.ts} +233 -640
  131. package/dist/transcript-anchors-Cb-bDbNH.d.ts.map +1 -0
  132. package/dist/{transcript-anchors-DsoBHg43.js → transcript-anchors-DSRPWjiH.js} +391 -961
  133. package/dist/transcript-anchors-DSRPWjiH.js.map +1 -0
  134. package/dist/tui.d.ts +335 -11
  135. package/dist/tui.d.ts.map +1 -1
  136. package/dist/tui.js +6375 -1892
  137. package/dist/tui.js.map +1 -1
  138. package/dist/{turn-operations-Dw02ZoSQ.d.ts → turn-operations-CgMROLsr.d.ts} +29 -4
  139. package/dist/turn-operations-CgMROLsr.d.ts.map +1 -0
  140. package/dist/{turn-operations-tG0vuBNc.js → turn-operations-Dq9Kx7m2.js} +321 -81
  141. package/dist/turn-operations-Dq9Kx7m2.js.map +1 -0
  142. package/dist/{types-BqdTeBaC.d.ts → types-BDccavwj.d.ts} +42 -1
  143. package/dist/types-BDccavwj.d.ts.map +1 -0
  144. package/dist/{types-CyVGdbia.js → types-BIarq1qE.js} +90 -2
  145. package/dist/types-BIarq1qE.js.map +1 -0
  146. package/dist/types.d.ts +5 -6
  147. package/dist/types.js +1 -1
  148. package/dist/{xai-tPdbAGkq.js → xai-B_e6TOA8.js} +2 -2
  149. package/dist/{xai-tPdbAGkq.js.map → xai-B_e6TOA8.js.map} +1 -1
  150. package/docs/ARCHITECTURE.md +1 -1
  151. package/docs/CHAT.md +7 -6
  152. package/docs/EXECUTION_CONTEXT.md +16 -0
  153. package/docs/EXTENSIONS.md +1063 -0
  154. package/docs/SKILL.md +16 -0
  155. package/docs/TUI.md +10 -3
  156. package/package.json +12 -3
  157. package/dist/agent-Cch2ayTt.js.map +0 -1
  158. package/dist/agent-EFWt6uQ_.d.ts +0 -6914
  159. package/dist/agent-EFWt6uQ_.d.ts.map +0 -1
  160. package/dist/anthropic-RGqsJlC8.js.map +0 -1
  161. package/dist/auth-C-ms5N2x.js.map +0 -1
  162. package/dist/context-breakdown-kO-pDsay.js.map +0 -1
  163. package/dist/contexts-Lzf5huID.js.map +0 -1
  164. package/dist/errors-CkTvg97v.d.ts.map +0 -1
  165. package/dist/glob-DluQFSw1.js.map +0 -1
  166. package/dist/glob-shell-rJMoCIGb.js +0 -21
  167. package/dist/glob-shell-rJMoCIGb.js.map +0 -1
  168. package/dist/index-B3ciFUZx.d.ts.map +0 -1
  169. package/dist/index-BtzE3Uaq.d.ts +0 -2738
  170. package/dist/index-BtzE3Uaq.d.ts.map +0 -1
  171. package/dist/index-tSzOaWNt.d.ts +0 -316
  172. package/dist/index-tSzOaWNt.d.ts.map +0 -1
  173. package/dist/interpolate-BtIgcCuz.js.map +0 -1
  174. package/dist/logger-DGiGf7DW.d.ts +0 -102
  175. package/dist/logger-DGiGf7DW.d.ts.map +0 -1
  176. package/dist/logger-Ktm-lj1s.js.map +0 -1
  177. package/dist/login-CCA-1lgK.js +0 -267
  178. package/dist/login-CCA-1lgK.js.map +0 -1
  179. package/dist/messages-YZQLKaz2.js.map +0 -1
  180. package/dist/policy-DcGlpaNs.d.ts +0 -129
  181. package/dist/policy-DcGlpaNs.d.ts.map +0 -1
  182. package/dist/presets-BQWYMHdd.js +0 -114
  183. package/dist/presets-BQWYMHdd.js.map +0 -1
  184. package/dist/run-summary-DkN8KsHM.d.ts +0 -249
  185. package/dist/run-summary-DkN8KsHM.d.ts.map +0 -1
  186. package/dist/session-CqrAFAKJ.js.map +0 -1
  187. package/dist/shell-quote-BmnhZmdM.js +0 -33
  188. package/dist/shell-quote-BmnhZmdM.js.map +0 -1
  189. package/dist/skills.js.map +0 -1
  190. package/dist/timeout-CpFm0jJ6.d.ts +0 -10
  191. package/dist/timeout-CpFm0jJ6.d.ts.map +0 -1
  192. package/dist/timeout-kGGSXagK.js.map +0 -1
  193. package/dist/tool-formatters-C6iLgc9f.d.ts +0 -1454
  194. package/dist/tool-formatters-C6iLgc9f.d.ts.map +0 -1
  195. package/dist/tools-CCd8e-HT.js +0 -1739
  196. package/dist/tools-CCd8e-HT.js.map +0 -1
  197. package/dist/transcript-anchors-BHIgMlPq.d.ts.map +0 -1
  198. package/dist/transcript-anchors-DsoBHg43.js.map +0 -1
  199. package/dist/turn-operations-Dw02ZoSQ.d.ts.map +0 -1
  200. package/dist/turn-operations-tG0vuBNc.js.map +0 -1
  201. package/dist/types-BqdTeBaC.d.ts.map +0 -1
  202. package/dist/types-CyVGdbia.js.map +0 -1
@@ -1,130 +1,4 @@
1
- import { G as SessionRun, K as SessionStore, Kn as McpServerConfig, Sr as ToolResultContent, T as ToolDef, W as SessionData, _r as ThinkingLevel, mr as SessionTurn, ur as SessionContentBlock } from "./agent-EFWt6uQ_.js";
2
- import { t as Preset } from "./index-BtzE3Uaq.js";
3
- import { A as SessionMeta, G as ProviderKey, I as CompletionItem, L as CompletionProvider, M as StreamEvent, O as Picked, P as ActiveTrigger, R as CompletionReference, W as ProviderAuth, Y as ModelInfo, Z as ProviderDescriptor, j as Settings, w as EditOutcome } from "./tool-formatters-C6iLgc9f.js";
4
- import { ReactNode } from "react";
5
-
6
- //#region src/chat/agents.d.ts
7
- /**
8
- * Theme color token used to accent the active profile in the UI (footer
9
- * badge, picker highlight). Resolved against `ThemeColors` via
10
- * `useColors()`; falls back to `accent` when omitted.
11
- */
12
- type AgentAccent = 'brand' | 'accent' | 'warn' | 'model';
13
- /**
14
- * Resolve a profile's `accent` token to a concrete hex color via the
15
- * caller's color palette. Renderer-agnostic — accepts the four-role
16
- * subset of `ThemeColors` that's relevant to accent surfaces, so this
17
- * helper composes against either `useColors()` (TUI) or a CSS-variable
18
- * lookup (GUI). Omitted / unknown tokens fall back to `accent`.
19
- */
20
- declare function accentColor(accent: AgentAccent | undefined, COLOR: {
21
- brand: string;
22
- accent: string;
23
- warn: string;
24
- model: string;
25
- }): string;
26
- interface AgentProfile {
27
- /** Stable identifier persisted in `TuiState.lastAgent` and shown in keybindings. */
28
- id: string;
29
- /** Human-readable label rendered in the picker and footer badge. */
30
- label: string;
31
- /** One-line description shown next to the label in the picker. */
32
- description: string;
33
- /**
34
- * Preset applied to `createAgent()` when this profile is active. Profiles
35
- * are self-contained: the host's chat-level `preset` (if any) is NOT
36
- * merged underneath. Hosts that want a shared base across profiles
37
- * should compose it explicitly in each profile's preset.
38
- */
39
- preset: Preset;
40
- /** Theme token used by the picker / footer badge. Defaults to `'accent'`. */
41
- accent?: AgentAccent;
42
- }
43
- type AgentRegistry = Readonly<Record<string, AgentProfile>>;
44
- /**
45
- * Tools the chat layer never persists to disk, regardless of output size.
46
- *
47
- * Rationale per entry:
48
- * - `read_file` — our reader is already paginated (`offset` + `limit`).
49
- * Persisting the slice the model asked for and pointing it at the
50
- * persisted path is circular; if the model wants more, it pages.
51
- * - `tool_search` — short metadata envelope. Never large.
52
- * - `skills_use` / `skills_read` — the `<skill_content>` body is
53
- * intentionally part of the prompt; persisting it defeats the purpose.
54
- * - `read_chat_turns` — previous-chat excerpts are explicitly loaded
55
- * conversation context; persisting them defeats the purpose.
56
- * - `present_plan` / `ask_user` — short JSON envelopes (decision +
57
- * answers). Never large.
58
- * - `spawn` — the subagent's final report IS the value of the call;
59
- * stubbing it out would defeat the orchestration pattern.
60
- *
61
- * Exported so SDK consumers building custom profiles can extend the list
62
- * (e.g. host-defined `screenshot` tool whose base64 payload should stay
63
- * inline). Set `behavior.persistExcludeTools` to your own list to fully
64
- * override.
65
- */
66
- declare const DEFAULT_PERSIST_EXCLUDE_TOOLS: readonly string[];
67
- /**
68
- * Tools whose output is exempt from the per-turn `toolOutputBudget` accounting.
69
- *
70
- * These tools exist to LOAD context into the conversation — their text output
71
- * IS the value of the call. Counting it against the budget steers the model
72
- * away from the very tool it needs to make progress (e.g. a 78 KiB
73
- * `tool_search` response for a 20-tool Notion MCP server would trigger the
74
- * "summarize before calling more tools" nudge on the very turn that
75
- * unlocked those tools, making them effectively unusable).
76
- *
77
- * Note this list is intentionally narrower than {@link DEFAULT_PERSIST_EXCLUDE_TOOLS}:
78
- * `read_file` is NOT exempt — a 200 KiB file load is exactly the case the
79
- * budget should steer against. Same for `spawn` (a sprawling subagent
80
- * report should still nudge a consolidation pass).
81
- *
82
- * Exported so SDK consumers building custom profiles can extend the list
83
- * for host-defined context-loading tools.
84
- */
85
- declare const DEFAULT_BUDGET_EXCLUDE_TOOLS: readonly string[];
86
- /**
87
- * Build agent — the default profile. Full read/write/shell access plus
88
- * subagent spawning. Mirrors the legacy `basic` preset so existing TUI
89
- * behavior is preserved when `agents` is omitted.
90
- *
91
- * The system prompt is the cwd-less variant of {@link buildBuildSystem};
92
- * the TUI overrides it per-session with an env-anchored composition so
93
- * the prompt carries the current project root + date. SDK consumers
94
- * calling `createAgent({ ...BUILD_AGENT.preset })` directly get the
95
- * cwd-less prompt and can wrap their own env section.
96
- */
97
- declare const BUILD_AGENT: AgentProfile;
98
- /**
99
- * Plan agent — read-only exploration mode. Locked down to file reading and
100
- * codebase search; no shell, no edits, no spawning. The system prompt
101
- * frames the conversation as planning rather than execution so the model
102
- * outputs proposals instead of attempting mutations.
103
- */
104
- declare const PLAN_AGENT: AgentProfile;
105
- /**
106
- * Default registry shipped with `zidane/tui`. Insertion order = picker order.
107
- * Hosts that want only one profile can pass `{ agents: { build: BUILD_AGENT } }`,
108
- * or a fully custom registry of their own profiles.
109
- */
110
- declare const BUILTIN_AGENTS: AgentRegistry;
111
- /** Id of the profile activated on first launch when nothing is persisted. */
112
- declare const DEFAULT_AGENT_ID = "build";
113
- /**
114
- * Resolve an agent id against a registry with sensible fallbacks: the
115
- * requested id wins when present, then `defaultId`, then the first key.
116
- * Returns `null` when the registry is empty (host misconfiguration —
117
- * the caller should surface this rather than silently failing).
118
- */
119
- declare function resolveAgentId(registry: AgentRegistry, requestedId: string | undefined, defaultId: string | undefined): string | null;
120
- /**
121
- * Wrap a legacy single `Preset` into a single-profile registry. Used by
122
- * `resolveConfig` when the host passed `preset` without `agents`, so older
123
- * call sites keep working — they get a one-entry registry whose picker is
124
- * a no-op (only one option).
125
- */
126
- declare function singleAgentRegistry(preset: Preset): AgentRegistry;
127
- //#endregion
1
+ import { Af as SessionStore, Cu as ProviderDescriptor, Ld as SessionContentBlock, Of as SessionData, Vd as SessionTurn, Wd as ThinkingLevel, Yd as ToolResultContent, _u as ProviderKey, au as EditOutcome, du as SessionMeta, fs as SubagentOverride, fu as Settings, gu as ProviderAuth, ka as ExtensionConfigCategory, kf as SessionRun, lu as Picked, ps as SubagentRegistry, pu as StreamEvent, ql as AgentRegistry, t as Preset, xu as ModelInfo, yd as McpServerConfig, yo as ExtensionRegistry, za as StoredExtensionConfigItem } from "./index-B8UtiZy7.js";
128
2
  //#region src/chat/hints.d.ts
129
3
  /**
130
4
  * Single hint entry — `<key> <label>`, optionally followed by an inline
@@ -196,52 +70,6 @@ declare const EMPTY_HINTS: readonly Hint[];
196
70
  */
197
71
  declare function clipHintsToWidth(hints: readonly Hint[], budget: number): readonly Hint[];
198
72
  //#endregion
199
- //#region src/chat/completion.d.ts
200
- /** State surface returned by `useCompletion()`. */
201
- interface CompletionState<TItem = unknown> {
202
- /** Active trigger, or null when the cursor doesn't sit in a completable span. */
203
- active: ActiveTrigger<TItem> | null;
204
- /** Items for the active query. Empty when no trigger is active. */
205
- items: readonly CompletionItem<TItem>[];
206
- /** True while the provider's `suggest` promise is pending. */
207
- loading: boolean;
208
- /** Index of the highlighted item inside `items`. */
209
- selectedIndex: number;
210
- /** Move the highlight. Wraps at the ends. No-op when `items` is empty. */
211
- selectNext: () => void;
212
- selectPrev: () => void;
213
- /**
214
- * Commit the highlighted item. Returns the new text + cursor pair, or
215
- * `null` when there's nothing to commit (no active trigger, empty list).
216
- */
217
- commit: () => {
218
- text: string;
219
- cursor: number;
220
- } | null;
221
- /** Force-close the popover until the user types again. */
222
- dismiss: () => void;
223
- /** All references in the current buffer, regardless of provider. */
224
- references: readonly CompletionReference<TItem>[];
225
- }
226
- /**
227
- * Drive a prompt-completion popover from React state.
228
- *
229
- * Inputs are pull-style — the caller owns `text` + `cursor` (typically
230
- * mirroring an `OpenTUI TextareaRenderable` or a `<textarea>` element) and
231
- * passes them in each render. Providers are matched by their `trigger`
232
- * character; the engine picks at most one active provider per cursor
233
- * position.
234
- *
235
- * Asynchronous suggest calls are aborted when the query changes or the
236
- * popover closes, so providers that hit a backend don't leak.
237
- */
238
- declare function useCompletion<TItem = unknown>(input: {
239
- text: string;
240
- cursor: number;
241
- }, providers: readonly CompletionProvider<TItem>[], options?: {
242
- maxQueryLength?: number;
243
- }): CompletionState<TItem>;
244
- //#endregion
245
73
  //#region src/start/shared-options.d.ts
246
74
  declare const startProviderNames: readonly ["anthropic", "openai", "openrouter", "cerebras", "xai", "arcee", "baseten", "local", "openai-compat"];
247
75
  type StartProviderName = typeof startProviderNames[number];
@@ -317,9 +145,22 @@ interface StartLocalOptions {
317
145
  * here forces every consumer (TUI keyboard handler, hint rows, settings
318
146
  * UI) to handle it, and ships a default that the user can override.
319
147
  */
320
- type KeyAction = 'openSettings' | 'openSessionDetails' | 'newSession' | 'openModelPicker' | 'openEffortPicker' | 'openTodos' | 'openContextPanel' | 'openKeybindings' | 'cycleAgent' | 'enterSelectTurnMode' | 'cancelToolCall' | 'changeCwd' | 'attachClipboardImage' | 'enterQueueSelection' | 'pushQueuedMessage' | 'dropQueuedMessage' | 'turnFork' | 'turnDelete' | 'turnCopy' | 'turnEdit' | 'sessionDelete' | 'sessionCopyId' | 'sessionGenerateTitle' | 'sessionExportMarkdown' | 'sessionExportJson' | 'sessionCompact';
148
+ type KeyAction = 'openSettings' | 'openSessionDetails' | 'newSession' | 'openModelPicker' | 'openEffortPicker' | 'openTodos' | 'openContextPanel' | 'openKeybindings' | 'cycleAgent' | 'enterSelectTurnMode' | 'cancelToolCall' | 'changeCwd' | 'attachClipboardImage' | 'openExternalEditor' | 'enterQueueSelection' | 'pushQueuedMessage' | 'dropQueuedMessage' | 'turnFork' | 'turnDelete' | 'turnCopy' | 'turnEdit' | 'sessionDelete' | 'sessionCopyId' | 'sessionGenerateTitle' | 'sessionExportMarkdown' | 'sessionExportJson' | 'sessionCompact';
321
149
  /** Resolved keybindings — every action has a current spec string. */
322
150
  type KeyBindings = Record<KeyAction, string>;
151
+ /**
152
+ * Resolved spec string for one extension-contributed keybinding. Same
153
+ * shape as a built-in {@link KeyBindings} entry but the `id` is
154
+ * extension-owned (no `KeyAction` union member). The TUI dispatcher
155
+ * iterates these alongside the built-ins; user overrides flow through
156
+ * the same `keybindings.json` file by matching on `id`.
157
+ */
158
+ interface ResolvedExtensionKeybinding {
159
+ /** Extension-owned id (matches `ExtensionKeybinding.id`). */
160
+ id: string;
161
+ /** Active spec string — user override when present, default otherwise. May be empty (= unbound). */
162
+ spec: string;
163
+ }
323
164
  /**
324
165
  * Logical grouping for one action — used by the keybindings panel to
325
166
  * render section headers. Stable strings (not an enum) so future
@@ -421,21 +262,49 @@ declare function keybindingsPath(userDir: string): string;
421
262
  * `group` rendered together with the section header inserted once.
422
263
  * Adjacent sections with the same group are NOT merged: catalog order
423
264
  * wins so the on-screen story matches the on-disk file.
265
+ *
266
+ * `rows` may carry built-in `KeyBindingDef`s (the common case) or
267
+ * extension-owned ones (when an extension contributes a keybinding).
268
+ * Both share label / description / spec — see {@link KeyBindingRow}.
424
269
  */
425
270
  interface KeyBindingSection {
426
- group: KeyBindingDef['group'];
427
- rows: ReadonlyArray<{
428
- def: KeyBindingDef;
429
- spec: string;
430
- }>;
271
+ group: string;
272
+ rows: ReadonlyArray<KeyBindingRow>;
431
273
  }
274
+ /**
275
+ * One row in the keybindings catalog. Either a built-in action (with
276
+ * its `def`) or an extension-contributed one (with `id` instead). The
277
+ * renderer reads `label` / `description` / `spec` uniformly and only
278
+ * needs the `kind` discriminator when offering action-specific UI
279
+ * (e.g. "edit in keybindings.json" by action name).
280
+ */
281
+ type KeyBindingRow = {
282
+ kind: 'builtin';
283
+ def: KeyBindingDef;
284
+ spec: string;
285
+ } | {
286
+ kind: 'extension';
287
+ id: string;
288
+ label: string;
289
+ description: string;
290
+ spec: string;
291
+ };
432
292
  /**
433
293
  * Walk {@link KEYBINDING_DEFS} in order and bucket rows into contiguous
434
294
  * sections by `group`. Shared between the standalone `KeybindingsModal`
435
295
  * and the `Keybindings` tab inside `SettingsModal` so both surfaces
436
296
  * render the same catalog with the same ordering rules.
297
+ *
298
+ * Pass `extensionRows` (resolved extension keybindings paired with
299
+ * their definitions) to append an "Extensions" section at the end so
300
+ * extension-contributed shortcuts are discoverable in the same UI.
437
301
  */
438
- declare function groupBindings(bindings: KeyBindings): readonly KeyBindingSection[];
302
+ declare function groupBindings(bindings: KeyBindings, extensionRows?: readonly {
303
+ id: string;
304
+ label: string;
305
+ description: string;
306
+ spec: string;
307
+ }[]): readonly KeyBindingSection[];
439
308
  /**
440
309
  * Width (in cells) of the fixed key column used by every binding-row
441
310
  * renderer. Derived once from {@link KEYBINDING_DEFS} so a new action
@@ -464,6 +333,36 @@ declare function readKeybindings(userDir: string): KeyBindings;
464
333
  * sacred.
465
334
  */
466
335
  declare function ensureKeybindingsFile(userDir: string): string;
336
+ /**
337
+ * Read the raw on-disk JSON object from `keybindings.json` after the
338
+ * JSONC stripper. Used by extension-keybinding resolution so the
339
+ * user's overrides for extension-owned ids flow through the same file
340
+ * the built-in actions use.
341
+ *
342
+ * Returns an empty object on missing / malformed / non-object files
343
+ * — same fault-tolerance contract as {@link readKeybindings}.
344
+ */
345
+ declare function readKeybindingsRaw(userDir: string): Readonly<Record<string, unknown>>;
346
+ /**
347
+ * Resolve the live spec string for each extension-contributed
348
+ * keybinding. The user's `keybindings.json` is consulted for an
349
+ * override on the binding's `id`; absent / invalid entries fall back
350
+ * to the binding's `default`.
351
+ *
352
+ * Pass the raw object (from {@link readKeybindingsRaw}) — passing
353
+ * `KeyBindings` here wouldn't help because the typed map only carries
354
+ * built-in `KeyAction` entries.
355
+ *
356
+ * Returns one entry per input binding, in source order. Empty `spec`
357
+ * (binding declared `default: ''` and the user didn't bind it) is a
358
+ * legitimate "unbound" state — the dispatcher never matches an empty
359
+ * spec, so the action stays accessible via re-binding through
360
+ * `keybindings.json`.
361
+ */
362
+ declare function resolveExtensionKeybindings(bindings: readonly {
363
+ id: string;
364
+ default: string;
365
+ }[], raw: Readonly<Record<string, unknown>>): ResolvedExtensionKeybinding[];
467
366
  /**
468
367
  * Strip `//` line comments and `/* … *\/` block comments from a JSONC
469
368
  * source string. Stays out of string literals so a `"foo // bar"` value
@@ -540,7 +439,7 @@ declare function titleFromTurns(turns: SessionTurn[]): string | null;
540
439
  * 1. `metadata.title` if it's a non-empty string (typically set by
541
440
  * the session-details modal's "generate title" action).
542
441
  * 2. {@link titleFromTurns} — the first user message, one-line + clipped.
543
- * 3. The literal `'untitled'`.
442
+ * 3. {@link DEFAULT_SESSION_TITLE} (`'New session'`).
544
443
  *
545
444
  * Total / pure / defensive on non-string metadata values.
546
445
  */
@@ -886,6 +785,51 @@ interface ChatOptions {
886
785
  * no chip.
887
786
  */
888
787
  autoUpdate?: AutoUpdateConfig | null;
788
+ /**
789
+ * Pre-built {@link ExtensionRegistry}. The `resolveConfig` surface is
790
+ * synchronous; extension `setup()` can be async, so the host must
791
+ * build the registry ahead of time and pass it here verbatim.
792
+ *
793
+ * Typical wiring (matches `runTui`):
794
+ *
795
+ * ```ts
796
+ * import {
797
+ * buildExtensionRegistry,
798
+ * discoverExtensions,
799
+ * inlineLoadedExtension,
800
+ * resolveConfig,
801
+ * } from 'zidane'
802
+ *
803
+ * const registry = await buildExtensionRegistry([
804
+ * // Project-scoped extensions run arbitrary local code — they stay
805
+ * // off unless the host establishes trust explicitly (or the user
806
+ * // sets ZIDANE_TRUST_PROJECT_EXTENSIONS=1).
807
+ * ...await discoverExtensions({ cwd, prefix, trustProjectExtensions: hostTrustsProject }),
808
+ * ...inlineDefinitions.map(inlineLoadedExtension),
809
+ * ])
810
+ * const config = resolveConfig({ ...opts, extensionRegistry: registry })
811
+ * ```
812
+ *
813
+ * Omitted → empty registry (no contributions).
814
+ */
815
+ extensionRegistry?: ExtensionRegistry;
816
+ /**
817
+ * Extra extension scan roots the host used (or wants runtime re-discovery
818
+ * to use). Each path is a root containing extension dirs/packages:
819
+ * `<root>/<name>/index.ts`. `runTui` wires this from
820
+ * `ZIDANE_EXTENSION_DIRS` when omitted.
821
+ */
822
+ extensionScanPaths?: readonly string[];
823
+ /**
824
+ * Whether project-scoped extensions are trusted to run their (arbitrary,
825
+ * local) code. Off by default unless the embedding host has established
826
+ * project trust; falls back to `ZIDANE_TRUST_PROJECT_EXTENSIONS=1`.
827
+ *
828
+ * Surfaced on {@link ResolvedConfig.trustProjectExtensions} so a host
829
+ * that re-discovers extensions at runtime (e.g. the TUI on a working-
830
+ * directory change) reuses the same trust decision as boot.
831
+ */
832
+ trustProjectExtensions?: boolean;
889
833
  }
890
834
  /**
891
835
  * Host-supplied auto-update settings. The check itself is gated on
@@ -1008,6 +952,16 @@ interface ResolvedConfig {
1008
952
  * for the action catalog + spec format.
1009
953
  */
1010
954
  keybindings: KeyBindings;
955
+ /**
956
+ * Resolved extension-contributed keybindings. Each entry pairs the
957
+ * extension's binding definition with the user's effective spec
958
+ * (override from `keybindings.json` when present, default
959
+ * otherwise). The TUI dispatcher iterates these alongside the
960
+ * built-in action catalog; the GUI host can do the same.
961
+ *
962
+ * Empty when no extension contributed a keybinding.
963
+ */
964
+ extensionKeybindings: readonly ResolvedExtensionKeybinding[];
1011
965
  /**
1012
966
  * Resolved auto-update knobs (forwarded verbatim from `ChatOptions.autoUpdate`)
1013
967
  * — `null` when the host didn't wire one. The TUI feeds this into
@@ -1015,6 +969,94 @@ interface ResolvedConfig {
1015
969
  * share a single source of truth.
1016
970
  */
1017
971
  autoUpdate: AutoUpdateConfig | null;
972
+ /**
973
+ * Merged extension contributions — the registry passed via
974
+ * {@link ChatOptions.extensionRegistry}, returned verbatim, or
975
+ * {@link EMPTY_EXTENSION_REGISTRY} when the host didn't pass one.
976
+ * `resolveConfig` is synchronous, so it never runs `setup()` itself;
977
+ * the host pre-builds the registry with `buildExtensionRegistry`.
978
+ *
979
+ * Renderer-side wiring reads `tuiContributions` / `guiContributions`
980
+ * to mount keybindings / footer hints / modals / panels. The
981
+ * `extensionPreset` field below carries the agent-side surface
982
+ * (tools / hooks / mcpServers / skills) ready to spread.
983
+ */
984
+ extensions: ExtensionRegistry;
985
+ /**
986
+ * Extra extension scan roots used at boot. Runtime re-discovery (TUI cwd
987
+ * changes, future hosts) feeds these back into the shared discovery helper so
988
+ * local/dev package roots stay active after the initial launch.
989
+ */
990
+ extensionScanPaths: readonly string[];
991
+ /**
992
+ * Single {@link Preset} folded together from every extension's
993
+ * agent-side contributions. Hosts spread it into `createAgent()`
994
+ * alongside the active profile's preset:
995
+ *
996
+ * ```ts
997
+ * const profile = composePresets(extensionPreset, agentProfile.preset)
998
+ * const agent = createAgent({ ...profile, provider })
999
+ * ```
1000
+ *
1001
+ * Extension hooks are bucketed per event so every handler fires;
1002
+ * tools and mcpServers compose with profile contributions via the
1003
+ * usual `composePresets` rules. System-prompt fragments land as a
1004
+ * trailing block on `preset.system` (host profiles that re-derive
1005
+ * `system` per session — Build / Plan — append the fragments via
1006
+ * the `system:transform` hook so the live system always carries
1007
+ * them).
1008
+ */
1009
+ extensionPreset: Preset;
1010
+ /**
1011
+ * System-prompt fragments contributed by extensions, in registration
1012
+ * order. Surfaced separately from {@link extensionPreset} so hosts
1013
+ * that re-derive `system` per session (Build / Plan in the TUI) can
1014
+ * append them on `system:transform` instead of trying to merge two
1015
+ * `preset.system` strings.
1016
+ */
1017
+ extensionSystemFragments: readonly string[];
1018
+ /**
1019
+ * Spawnable subagents (adds) contributed by extensions, keyed by name.
1020
+ * Surfaced separately from {@link extensionPreset} (like
1021
+ * {@link extensionSystemFragments}) because subagents don't ride the
1022
+ * preset path — the host merges them onto the spawn tool's base
1023
+ * registry via `spawn.withSubagents(...)` at agent build time.
1024
+ */
1025
+ extensionSubagents: SubagentRegistry;
1026
+ /**
1027
+ * Subagent edits contributed by extensions, keyed by target name and
1028
+ * composed in registration order. Applied (after the adds above) by
1029
+ * the host's `spawn.withSubagents(...)` call so extensions can edit or
1030
+ * delete host- / extension-provided subagents by name.
1031
+ */
1032
+ extensionSubagentOverrides: Record<string, SubagentOverride>;
1033
+ /**
1034
+ * Merged extension-contributed config categories, keyed by category id.
1035
+ * Surfaced (alongside {@link extensionConfigItems}) so the TUI can read
1036
+ * the schema in-process — same way it reads `extensions.themes` — and
1037
+ * the GUI's `extensions:configSchema` IPC can serialize it.
1038
+ */
1039
+ extensionConfigCategories: Readonly<Record<string, ExtensionConfigCategory>>;
1040
+ /**
1041
+ * Merged extension-contributed config items, namespaced
1042
+ * `extName → itemKey → item`. Each item carries its resolved
1043
+ * `category`; values are read default-first via the core resolver.
1044
+ */
1045
+ extensionConfigItems: Readonly<Record<string, Readonly<Record<string, StoredExtensionConfigItem>>>>;
1046
+ /**
1047
+ * Resolved project-extension trust decision (option + env fallback).
1048
+ * Hosts that re-discover extensions at runtime feed this back into
1049
+ * {@link discoverAndBuildExtensionRegistry} so the rebuild trusts the
1050
+ * same scopes boot did.
1051
+ */
1052
+ trustProjectExtensions: boolean;
1053
+ /**
1054
+ * Raw user `keybindings.json` object (post-JSONC-strip). Surfaced so a
1055
+ * host re-resolving {@link extensionKeybindings} at runtime (after an
1056
+ * extension registry rebuild) can reuse the same override source
1057
+ * without a second disk read.
1058
+ */
1059
+ rawKeybindings: Readonly<Record<string, unknown>>;
1018
1060
  /** One-shot launch request forwarded from {@link ChatOptions.launch}. */
1019
1061
  launch: StartLocalOptions | null;
1020
1062
  }
@@ -1224,7 +1266,7 @@ declare function buildMcpServers(opts: {
1224
1266
  * suite; the rendering layer is tested where it lives.
1225
1267
  */
1226
1268
  /** Settings keys whose value type is `readonly string[] | undefined`. */
1227
- type EnabledAllowlistKey = 'enabledSkills' | 'enabledMcps';
1269
+ type EnabledAllowlistKey = 'enabledSkills' | 'enabledMcps' | 'enabledExtensions';
1228
1270
  interface EnabledToggleSet {
1229
1271
  /** Live set of enabled names — `Set` for O(1) `has`. */
1230
1272
  enabledSet: ReadonlySet<string>;
@@ -1242,264 +1284,15 @@ declare function useEnabledToggleSet<T>(opts: {
1242
1284
  catalog: readonly T[];
1243
1285
  keyOf: (entry: T) => string;
1244
1286
  settingKey: EnabledAllowlistKey;
1245
- }): EnabledToggleSet;
1246
- //#endregion
1247
- //#region src/chat/interactions.d.ts
1248
- declare const PRESENT_PLAN_TOOL = "present_plan";
1249
- declare const ASK_USER_TOOL = "ask_user";
1250
- /** True when `name` is one of the interaction tool canonical names. */
1251
- declare function isInteractionTool(name: string): boolean;
1252
- interface PlanStep {
1253
- id: string;
1254
- title: string;
1255
- description?: string;
1256
- }
1257
- interface PlanPayload {
1258
- /** Short headline summary — used as the modal title. */
1259
- title: string;
1260
- /** Full plan body. Markdown. */
1261
- plan: string;
1262
- /** Optional structured step list — surfaced as a checklist preview. */
1263
- steps?: readonly PlanStep[];
1264
- }
1265
- interface QuestionChoice {
1266
- id: string;
1267
- label: string;
1268
- description?: string;
1269
- }
1270
- /**
1271
- * One question in an `ask_user` batch. Discriminated by `type`:
1272
- *
1273
- * - `text` — single-line free-text answer (rendered via `<input>`).
1274
- * - `textarea` — multi-line free-text answer (rendered via `<textarea>`).
1275
- * - `select` — single pick from a fixed set of `choices`.
1276
- * - `confirm` — yes/no boolean (rendered as a 2-option select).
1277
- *
1278
- * The model batches related clarifications into one tool call instead of
1279
- * pinging the user N times with N round-trips.
1280
- */
1281
- type QuestionType = 'text' | 'textarea' | 'select' | 'confirm';
1282
- interface BaseQuestion {
1283
- /** Stable id — keys the response back to the model. */
1284
- id: string;
1285
- /** Question text shown above the input (Markdown allowed). */
1286
- prompt: string;
1287
- /** Optional helper text under the prompt. */
1288
- description?: string;
1289
- /**
1290
- * Whether the answer is required (non-empty). Default: `true` for
1291
- * `select` / `confirm` (no sensible empty), `false` for free-text
1292
- * (skipping = empty string). Free-text questions still accept an
1293
- * answer; the flag only gates submission.
1294
- */
1295
- required?: boolean;
1296
- }
1297
- interface TextQuestion extends BaseQuestion {
1298
- type: 'text' | 'textarea';
1299
- /** Placeholder shown when the input is empty. */
1300
- placeholder?: string;
1301
- /** Pre-fill the input with this value (still editable). */
1302
- default?: string;
1303
- }
1304
- interface SelectQuestion extends BaseQuestion {
1305
- type: 'select';
1306
- choices: readonly QuestionChoice[];
1307
- }
1308
- interface ConfirmQuestion extends BaseQuestion {
1309
- type: 'confirm';
1310
- /** Label for the affirmative option. Default: `'yes'`. */
1311
- affirmLabel?: string;
1312
- /** Label for the negative option. Default: `'no'`. */
1313
- denyLabel?: string;
1314
- }
1315
- type Question = TextQuestion | SelectQuestion | ConfirmQuestion;
1316
- interface QuestionPayload {
1317
- /** Optional intro / context shown above every question (Markdown). */
1318
- intro?: string;
1319
- /** One or more questions for the user to answer in one form. */
1320
- questions: readonly Question[];
1321
- }
1322
- /** Per-question answer value — `string` for text/textarea/select, `boolean` for confirm. */
1323
- type AnswerValue = string | boolean;
1324
- interface BaseRequest {
1325
- /** Stable id — the `tool_call.id` from the model. */
1326
- id: string;
1327
- /** Tool canonical name. */
1328
- tool: string;
1329
- /** Run that emitted the call, when known. */
1330
- runId?: string;
1331
- /** Turn id the call lives in. */
1332
- turnId?: string;
1333
- /** Unix ms when the request was raised. */
1334
- createdAt: number;
1335
- }
1336
- interface PlanRequest extends BaseRequest {
1337
- kind: 'plan';
1338
- tool: typeof PRESENT_PLAN_TOOL;
1339
- payload: PlanPayload;
1340
- }
1341
- interface QuestionRequest extends BaseRequest {
1342
- kind: 'question';
1343
- tool: typeof ASK_USER_TOOL;
1344
- payload: QuestionPayload;
1345
- }
1346
- type InteractionRequest = PlanRequest | QuestionRequest;
1347
- type PlanDecision = 'approve' | 'reject' | 'revise';
1348
- interface PlanResponse {
1349
- kind: 'plan';
1350
- decision: PlanDecision;
1351
- /** Optional free-text feedback — shown to the model verbatim. */
1352
- comment?: string;
1353
- }
1354
- interface QuestionResponse {
1355
- kind: 'question';
1356
1287
  /**
1357
- * Map of `Question.id AnswerValue` for every question the user
1358
- * answered. Missing keys = question skipped (only possible when
1359
- * `required: false`).
1288
+ * Names that survive the persisted-allowlist GC even when absent from
1289
+ * `catalog`. Use when the catalog deliberately hides entries that are
1290
+ * still known to exist — e.g. errored / untrusted extensions are kept
1291
+ * out of the toggle list but must not be dropped from the allowlist
1292
+ * by an unrelated toggle. Defaults to the catalog keys.
1360
1293
  */
1361
- answers: Readonly<Record<string, AnswerValue>>;
1362
- }
1363
- type InteractionResponse = PlanResponse | QuestionResponse;
1364
- /**
1365
- * Format an {@link InteractionResponse} as the tool_result content. JSON
1366
- * keeps the envelope parseable and explicit. Empty fields are stripped so
1367
- * the model doesn't waste tokens reading absent values.
1368
- */
1369
- declare function serializeInteractionResponse(response: InteractionResponse): string;
1370
- /**
1371
- * Build a protocol-valid user `SessionTurn` that closes a batch of
1372
- * resumed pending interactions.
1373
- *
1374
- * - `requests` MUST be the same list returned by
1375
- * {@link pendingInteractionsFromTurns} for the session, in order.
1376
- * - `responses` MUST contain an entry for every request id; throws
1377
- * otherwise (caller bug — flush before all answers collected).
1378
- *
1379
- * Pure / total. Tested in isolation so the batching invariant doesn't
1380
- * regress without the resumed-flow integration noticing.
1381
- */
1382
- declare function buildResumedToolResultsTurn(requests: readonly InteractionRequest[], responses: ReadonlyMap<string, InteractionResponse>, options: {
1383
- /** Turn id minted by the session store. */turnId: string;
1384
- /**
1385
- * Run id that emitted the pending tool calls — when known, attaching
1386
- * it ties the resumed turn back to the originating `SessionRun` row
1387
- * so consumers grouping turns by run keep clean ancestry across the
1388
- * close/reopen boundary.
1389
- */
1390
- runId?: string; /** `createdAt` timestamp. Defaults to `Date.now()`. */
1391
- createdAt?: number;
1392
- }): SessionTurn;
1393
- /**
1394
- * Scan `turns` and return every interaction tool call without a matching
1395
- * `tool_result`, ordered by turn appearance. Works equally for live mid-run
1396
- * inspection and reload-from-disk.
1397
- *
1398
- * Malformed payloads (input that doesn't match the tool's schema) are
1399
- * skipped silently — the call still lives in the persisted history, but
1400
- * the renderer wouldn't know how to display it. The next `agent.run()` on
1401
- * the session will see the orphan and synthesize an error tool_result via
1402
- * the loop's normal recovery path.
1403
- */
1404
- declare function pendingInteractionsFromTurns(turns: readonly SessionTurn[]): InteractionRequest[];
1405
- interface CreateInteractionToolsOptions {
1406
- /**
1407
- * Called when the agent invokes one of the interaction tools. Resolves
1408
- * with the user's response (forwarded to the model as the tool_result);
1409
- * reject to signal denial / abort (the model receives
1410
- * `Tool error: <message>` as the result).
1411
- */
1412
- requestInteraction: (request: InteractionRequest) => Promise<InteractionResponse>;
1413
- }
1414
- /**
1415
- * Create the `present_plan` and `ask_user` tools as a record, ready to
1416
- * spread into `createAgent({ tools })` or composed into a {@link Preset}.
1417
- */
1418
- declare function createInteractionTools(opts: CreateInteractionToolsOptions): Record<string, ToolDef>;
1419
- interface PendingInteractionEntry {
1420
- request: InteractionRequest;
1421
- /** The user picked something — forward to the live tool Promise or the resumed tool_result writer. */
1422
- resolve: (response: InteractionResponse) => void;
1423
- /**
1424
- * The user / system cancelled — distinct from `resolve` so renderers can
1425
- * differentiate "user picked something" from "user gave up / aborted".
1426
- * Live entries reject the tool's Promise; resumed entries decide what
1427
- * to persist as the cancelled tool_result.
1428
- */
1429
- cancel: (reason?: string) => void;
1430
- }
1431
- interface InteractionsActions {
1432
- /** Add a request to the FIFO queue. */
1433
- enqueue: (entry: PendingInteractionEntry) => void;
1434
- /** Resolve the head request with `response`. */
1435
- resolveHead: (response: InteractionResponse) => void;
1436
- /**
1437
- * Cancel the head request. Reserved for future per-call cancel
1438
- * affordances (a "skip this" button, a GUI's close-modal-X) — the
1439
- * built-in TUI currently cancels via the run-level `cancelAll` path
1440
- * only. Kept on the public API so consumer renderers can wire it
1441
- * without a follow-up surface change.
1442
- */
1443
- cancelHead: (reason?: string) => void;
1444
- /** Cancel every queued request. Used by abort / session teardown. */
1445
- cancelAll: (reason?: string) => void;
1446
- }
1447
- declare function InteractionsProvider({
1448
- children
1449
- }: {
1450
- children: ReactNode;
1451
- }): import("react/jsx-runtime").JSX.Element;
1452
- /** Read the live queue (re-renders on every push/pop). */
1453
- declare function useInteractionsQueue(): readonly PendingInteractionEntry[];
1454
- /** Read the stable actions object. */
1455
- declare function useInteractionsActions(): InteractionsActions;
1456
- /**
1457
- * Build the `requestInteraction` callback for `createInteractionTools` from
1458
- * the React-side {@link InteractionsActions}. Each call adds a fresh entry
1459
- * to the queue whose `resolve` / `cancel` route back to one Promise that
1460
- * the tool's `execute` awaits.
1461
- */
1462
- declare function makeRequestInteraction(actions: InteractionsActions): CreateInteractionToolsOptions['requestInteraction'];
1463
- //#endregion
1464
- //#region src/chat/markdown-segments.d.ts
1465
- /**
1466
- * One block returned by {@link splitMarkdownCodeBlocks}. Prose segments
1467
- * carry their original markdown (including blank lines that bracketed
1468
- * the fence) so the surrounding paragraph spacing stays faithful to the
1469
- * original input. Code segments carry the raw body — fence markers and
1470
- * info-string stripped — so a "copy code" action lands what the user
1471
- * actually sees, byte-for-byte.
1472
- */
1473
- interface MarkdownSegment {
1474
- kind: 'prose' | 'code';
1475
- content: string;
1476
- /** Info-string (e.g. `ts`, `python`). Empty when the fence had none. */
1477
- lang?: string;
1478
- /**
1479
- * `true` on a code segment whose closing fence hasn't arrived yet —
1480
- * i.e. the trailing block during streaming. Consumers can render this
1481
- * in "streaming" mode (no copy affordance, partial-highlight pipeline)
1482
- * until the closer lands and it flips to a regular closed segment.
1483
- */
1484
- open?: boolean;
1485
- }
1486
- /**
1487
- * Split markdown text into alternating prose / fenced-code segments.
1488
- *
1489
- * Recognizes both ` ``` ` and `~~~` fences, with arbitrary length ≥ 3,
1490
- * matching CommonMark's "fence indicator must be at least as long to
1491
- * close" rule. Info-strings (the bit after the opening fence) are kept
1492
- * as the `lang` hint; any trailing whitespace is trimmed. Closing
1493
- * fences are detected on a line of their own (whitespace tolerated).
1494
- *
1495
- * Unclosed fences fall back to emitting the would-be-code body as a
1496
- * trailing prose segment so no content is dropped — finalized markdown
1497
- * isn't expected to ship one, but the fallback keeps the renderer
1498
- * truthful when the model produces malformed output.
1499
- *
1500
- * Exported for unit tests.
1501
- */
1502
- declare function splitMarkdownCodeBlocks(text: string): MarkdownSegment[];
1294
+ gcKeys?: readonly string[];
1295
+ }): EnabledToggleSet;
1503
1296
  //#endregion
1504
1297
  //#region src/chat/session-export.d.ts
1505
1298
  /** File format supported by the exporter. */
@@ -1575,206 +1368,6 @@ declare function writeSessionExport(opts: {
1575
1368
  format: SessionExportFormat;
1576
1369
  } & ResolveOptions): Promise<SessionExportTarget>;
1577
1370
  //#endregion
1578
- //#region src/chat/theme.d.ts
1579
- /**
1580
- * Renderer-agnostic theme system.
1581
- *
1582
- * A `Theme` bundles every variable that can change visually between
1583
- * "themes" — colors, select-row styling, code/markdown syntax highlight
1584
- * tokens, panel backgrounds. Plain JSON: no OpenTUI dependency, no React,
1585
- * no functions. The TUI consumes the theme by reading from `useTheme()`
1586
- * and converting hex strings into OpenTUI's `RGBA`/`SyntaxStyle`; a future
1587
- * GUI consumes the same theme by converting into CSS variables or Tailwind
1588
- * tokens.
1589
- *
1590
- * Components should always read theme values through `useTheme()` /
1591
- * `useColors()` so a runtime theme switch (Settings → Theme) re-paints
1592
- * the whole tree. Importing a raw theme object directly bypasses the
1593
- * context and pins the component to a single look.
1594
- *
1595
- * Built-in flavors (Catppuccin, Vaporwave) live in `./themes/`. This file
1596
- * just defines the shape + the default theme + the registry.
1597
- */
1598
- /** Role-named color palette. Reused throughout the UI for text, borders, accents. */
1599
- interface ThemeColors {
1600
- /** Primary accent — selected text, brand emphasis (e.g. `▶` markers). */
1601
- brand: string;
1602
- /** Success / progress accent — used sparingly. */
1603
- accent: string;
1604
- /** Model badge accent (provider/model name in the footer, links). */
1605
- model: string;
1606
- /** Warnings — busy spinner, approval picker border, esc hints. */
1607
- warn: string;
1608
- /** Errors — `✗` prefix on error events, validation messages. */
1609
- error: string;
1610
- /** Secondary text — captions, helper text, dim transcript lines. */
1611
- dim: string;
1612
- /** Tertiary text — separators, descriptions, the `┃` tool-result bar. */
1613
- mute: string;
1614
- /** Resting border color. */
1615
- border: string;
1616
- /** Border color on focused / active elements. */
1617
- borderActive: string;
1618
- /**
1619
- * Optional gradient endpoints for the in-chat working throbber
1620
- * (`<CrushThrobber>`). Falls back to `[brand, accent]` when unset.
1621
- * Themes can pin a richer pair here — e.g. Crush's `Charple` →
1622
- * `Dolly` purple-to-pink — without having to repurpose `accent`.
1623
- */
1624
- throbber?: {
1625
- from: string;
1626
- to: string;
1627
- };
1628
- /**
1629
- * Optional tone for the footer's session-cost indicator. Falls back
1630
- * to `warn` when unset. Carved out as its own role because some
1631
- * themes (e.g. Crush) intentionally bind `warn` to a non-yellow tone
1632
- * and a separate "money" color reads more naturally on the footer.
1633
- */
1634
- money?: string;
1635
- }
1636
- /** Select-component styling. Plain prop shape; both OpenTUI's `<select>` and any GUI equivalent can consume this. */
1637
- interface ThemeSelect {
1638
- backgroundColor: string;
1639
- focusedBackgroundColor: string;
1640
- selectedBackgroundColor: string;
1641
- selectedTextColor: string;
1642
- textColor: string;
1643
- descriptionColor: string;
1644
- selectedDescriptionColor: string;
1645
- }
1646
- /** Background + foreground pair for a completion-reference chip pill. */
1647
- interface ChipColor {
1648
- /** Background paint — the pill itself. High-saturation by convention. */
1649
- bg: string;
1650
- /** Foreground paint — the chip text. Pre-paired with {@link ChipColor.bg} for legibility. */
1651
- fg: string;
1652
- }
1653
- /**
1654
- * Chip colors keyed by completion-provider id (`'skills'`, `'files'`, …).
1655
- * `default` is the required fallback used by any provider id without an
1656
- * explicit entry — keeps host-registered providers themable out of the
1657
- * box. Use {@link resolveChipColor} to perform the kind-specific → default
1658
- * lookup rather than indexing the map directly.
1659
- */
1660
- /**
1661
- * Map of provider id → chip color pair. `default` is required so callers
1662
- * always have a fallback; every other key is optional so direct indexing
1663
- * (`chips['unknown']`) surfaces as `ChipColor | undefined` and nudges
1664
- * consumers toward {@link resolveChipColor}, which encodes the fallback.
1665
- */
1666
- type ChipColorMap = {
1667
- default: ChipColor;
1668
- } & Partial<Record<string, ChipColor>>;
1669
- /**
1670
- * Look up the chip color pair for a provider id, falling back to
1671
- * `chips.default` when the theme has no kind-specific entry. Mirrors
1672
- * `resolveChipStyleId` so both rendering surfaces (submitted echo +
1673
- * live textarea) share one canonical lookup rule.
1674
- */
1675
- declare function resolveChipColor(chips: ChipColorMap, providerId: string): ChipColor;
1676
- /** Panel / surface backgrounds. */
1677
- interface ThemeSurfaces {
1678
- /**
1679
- * Solid paint for the app's root surface. Covers the whole TUI viewport
1680
- * so transparent / translucent terminals don't show desktop windows
1681
- * underneath. Conventionally one tier deeper than {@link modal} so
1682
- * modal panels still read as elevated above the body.
1683
- */
1684
- background: string;
1685
- /** Background of an overlaid modal panel (settings, model picker, …). */
1686
- modal: string;
1687
- /**
1688
- * Completion-chip color pairs keyed by provider id. Built-in themes
1689
- * ship distinct `skills` + `files` tones so the two reference kinds
1690
- * read differently in both the submitted echo and the live textarea.
1691
- */
1692
- chips: ChipColorMap;
1693
- /**
1694
- * Background paint for the selected turn's events in select-turn mode.
1695
- * Subtle, low-saturation lift from the terminal default so the whole
1696
- * span of the selected turn reads as one continuous highlighted block
1697
- * without overpowering the foreground text. Inverse-tinted on the
1698
- * light flavor (Latte) so the same visual role works there.
1699
- */
1700
- selection: string;
1701
- /**
1702
- * Edit-diff color block. Drives the native `<diff>` renderable used
1703
- * by {@link Settings.showEditDiffs}. Pre-mixed against each theme's
1704
- * primary surface so terminals without true alpha-blend get a
1705
- * legible "subtle red / subtle green" effect rather than a flat
1706
- * saturated band.
1707
- *
1708
- * - `*Bg` row-level paint (gutter + content)
1709
- * - `*ContentBg` content-only paint (overrides `*Bg` on the text
1710
- * column). Set when a deeper hue should punch
1711
- * through behind the syntax-highlighted code; omit
1712
- * to let `*Bg` carry the full row.
1713
- * - `*Fg` color for the `+` / `-` glyph in the sign gutter.
1714
- */
1715
- diff: DiffSurfaces;
1716
- }
1717
- /** Per-row paints used by the native `<diff>` renderable. */
1718
- interface DiffSurfaces {
1719
- addBg: string;
1720
- removeBg: string;
1721
- contextBg?: string;
1722
- addContentBg?: string;
1723
- removeContentBg?: string;
1724
- addFg: string;
1725
- removeFg: string;
1726
- }
1727
- /**
1728
- * One entry in a `SyntaxStyles` map — what OpenTUI's `SyntaxStyle.fromStyles`
1729
- * accepts, minus the `RGBA` conversion. Renderer-agnostic JSON.
1730
- */
1731
- interface SyntaxTokenStyle {
1732
- fg?: string;
1733
- bg?: string;
1734
- bold?: boolean;
1735
- italic?: boolean;
1736
- underline?: boolean;
1737
- dim?: boolean;
1738
- }
1739
- /**
1740
- * Map of Tree-sitter / markdown capture group → token style.
1741
- *
1742
- * Two flavours of keys live in the same table:
1743
- * - `markup.*` — the markdown structure captures (heading, bold, italic,
1744
- * list, quote, raw inline + block, link). OpenTUI's markdown parser
1745
- * emits these for the markdown text itself.
1746
- * - bare token names (`keyword`, `string`, `function`, …) — emitted by
1747
- * the embedded language Tree-sitter grammars when a code fence
1748
- * declares a language. OpenTUI passes the same `SyntaxStyle` down to
1749
- * the fenced-code renderable, so this map drives both surfaces.
1750
- */
1751
- type SyntaxStyles = Record<string, SyntaxTokenStyle>;
1752
- /** Full theme bundle. */
1753
- interface Theme {
1754
- /** Stable identifier, used as the key in `BUILTIN_THEMES` and `Settings.theme`. */
1755
- id: string;
1756
- /** Human-readable label shown in the settings picker. */
1757
- label: string;
1758
- colors: ThemeColors;
1759
- select: ThemeSelect;
1760
- surfaces: ThemeSurfaces;
1761
- syntax: SyntaxStyles;
1762
- }
1763
- declare const DEFAULT_THEME: Theme;
1764
- /**
1765
- * Built-in theme registry, keyed by `theme.id`. The TUI looks up the active
1766
- * theme here using `Settings.theme`; unknown ids fall back to
1767
- * `DEFAULT_THEME`. Hosts can extend this by passing additional themes to a
1768
- * future `runTui({ themes })` option (not yet wired).
1769
- *
1770
- * Insertion order is the picker cycle order — keep `default` first so a
1771
- * fresh install (no `theme` in `state.json`) sees the familiar yellow theme
1772
- * before the others.
1773
- */
1774
- declare const BUILTIN_THEMES: Readonly<Record<string, Theme>>;
1775
- /** Resolve a theme id to its full `Theme`, falling back to default on unknown ids. */
1776
- declare function resolveTheme(id: string | undefined): Theme;
1777
- //#endregion
1778
1371
  //#region src/chat/transcript-anchors.d.ts
1779
1372
  /**
1780
1373
  * One entry in the partitioned transcript-row list. Single events
@@ -1818,5 +1411,5 @@ declare function computeTurnAnchors(items: readonly TranscriptItem[]): {
1818
1411
  lastTurnId: string | undefined;
1819
1412
  };
1820
1413
  //#endregion
1821
- export { useInteractionsQueue as $, mergeKeybindings as $t, InteractionsProvider as A, loadState as At, QuestionPayload as B, KEYBINDING_DEFS as Bt, ASK_USER_TOOL as C, TuiState as Ct, InteractionRequest as D, eventsFromTurns as Dt, CreateInteractionToolsOptions as E, deriveSessionTitle as Et, PlanRequest as F, titleFromTurns as Ft, TextQuestion as G, KeyBindingSection as Gt, QuestionResponse as H, KEYBINDING_KEY_COL_WIDTH as Ht, PlanResponse as I, toolCallPreview as It, isInteractionTool as J, ensureKeybindingsFile as Jt, buildResumedToolResultsTurn as K, KeyBindings as Kt, PlanStep as L, toolResultText as Lt, PendingInteractionEntry as M, saveState as Mt, PlanDecision as N, stripSpawnTokensLine as Nt, InteractionResponse as O, lastContextSizeFromTurns as Ot, PlanPayload as P, sumRunCosts as Pt, useInteractionsActions as Q, matchesBinding as Qt, Question as R, updateToolEventOutcomes as Rt, splitMarkdownCodeBlocks as S, StateStoreApi as St, ConfirmQuestion as T, createStateStore as Tt, QuestionType as U, KeyAction as Ut, QuestionRequest as V, KEYBINDING_DEF_BY_ACTION as Vt, SelectQuestion as W, KeyBindingDef as Wt, pendingInteractionsFromTurns as X, groupBindings as Xt, makeRequestInteraction as Y, formatBindingForDisplay as Yt, serializeInteractionResponse as Z, keybindingsPath as Zt, SessionExportTarget as _, DEFAULT_PERSIST_EXCLUDE_TOOLS as _n, ResolveStorageDirsOptions as _t, ChipColorMap as a, EMPTY_HINTS as an, DiscoveryResult as at, writeSessionExport as b, resolveAgentId as bn, StorageSlot as bt, SyntaxTokenStyle as c, hintsLength as cn, discoverProjectMcps as ct, ThemeSelect as d, AgentProfile as dn, ChatOptions as dt, parseBindingSpec as en, EnabledAllowlistKey as et, ThemeSurfaces as f, AgentRegistry as fn, ProviderRegistry as ft, SessionExportFormat as g, DEFAULT_BUDGET_EXCLUDE_TOOLS as gn, resolveStoragePaths as gt, SessionExportAnchor as h, DEFAULT_AGENT_ID as hn, resolveConfig as ht, ChipColor as i, useCompletion as in, DiscoveryError as it, PRESENT_PLAN_TOOL as j, marginTopFor as jt, InteractionsActions as k, listSessionMeta as kt, Theme as l, truncateTrailing as ln, parseMcpsFile as lt, resolveTheme as m, BUILTIN_AGENTS as mn, ResolvedPaths as mt, computeTurnAnchors as n, stripJsonComments as nn, useEnabledToggleSet as nt, DEFAULT_THEME as o, Hint as on, buildMcpServers as ot, resolveChipColor as p, BUILD_AGENT as pn, ResolvedConfig as pt, createInteractionTools as q, ParsedBinding as qt, BUILTIN_THEMES as r, CompletionState as rn, DiscoveredMcp as rt, SyntaxStyles as s, clipHintsToWidth as sn, defaultMcpsConfigPaths as st, TranscriptItem as t, readKeybindings as tn, EnabledToggleSet as tt, ThemeColors as u, AgentAccent as un, AutoUpdateConfig as ut, renderSession as v, PLAN_AGENT as vn, StorageDirs as vt, AnswerValue as w, compactSummaryEvent as wt, MarkdownSegment as x, singleAgentRegistry as xn, resolveStorageDirs as xt, resolveSessionExportTarget as y, accentColor as yn, StorageMode as yt, QuestionChoice as z, DEFAULT_KEYBINDINGS as zt };
1822
- //# sourceMappingURL=transcript-anchors-BHIgMlPq.d.ts.map
1414
+ export { KeyBindingDef as $, resolveStorageDirs as A, marginTopFor as B, ResolvedPaths as C, StorageDirs as D, ResolveStorageDirsOptions as E, deriveSessionTitle as F, toolCallPreview as G, stripSpawnTokensLine as H, eventsFromTurns as I, DEFAULT_KEYBINDINGS as J, toolResultText as K, lastContextSizeFromTurns as L, TuiState as M, compactSummaryEvent as N, StorageMode as O, createStateStore as P, KeyAction as Q, listSessionMeta as R, ResolvedConfig as S, resolveStoragePaths as T, sumRunCosts as U, saveState as V, titleFromTurns as W, KEYBINDING_DEF_BY_ACTION as X, KEYBINDING_DEFS as Y, KEYBINDING_KEY_COL_WIDTH as Z, discoverProjectMcps as _, clipHintsToWidth as _t, SessionExportTarget as a, formatBindingForDisplay as at, ChatOptions as b, writeSessionExport as c, matchesBinding as ct, useEnabledToggleSet as d, readKeybindings as dt, KeyBindingSection as et, DiscoveredMcp as f, readKeybindingsRaw as ft, defaultMcpsConfigPaths as g, Hint as gt, buildMcpServers as h, EMPTY_HINTS as ht, SessionExportFormat as i, ensureKeybindingsFile as it, StateStoreApi as j, StorageSlot as k, EnabledAllowlistKey as l, mergeKeybindings as lt, DiscoveryResult as m, stripJsonComments as mt, computeTurnAnchors as n, ParsedBinding as nt, renderSession as o, groupBindings as ot, DiscoveryError as p, resolveExtensionKeybindings as pt, updateToolEventOutcomes as q, SessionExportAnchor as r, ResolvedExtensionKeybinding as rt, resolveSessionExportTarget as s, keybindingsPath as st, TranscriptItem as t, KeyBindings as tt, EnabledToggleSet as u, parseBindingSpec as ut, parseMcpsFile as v, hintsLength as vt, resolveConfig as w, ProviderRegistry as x, AutoUpdateConfig as y, truncateTrailing as yt, loadState as z };
1415
+ //# sourceMappingURL=transcript-anchors-Cb-bDbNH.d.ts.map