zidane 6.1.13 → 6.2.6

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 (88) hide show
  1. package/dist/{acp-BqfKqQ9x.js → acp-CYJvnqPa.js} +2 -2
  2. package/dist/{acp-BqfKqQ9x.js.map → acp-CYJvnqPa.js.map} +1 -1
  3. package/dist/acp-cli.js +4 -4
  4. package/dist/acp.d.ts +1 -1
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-CZ3WSWqR.js → agent-D11SxCvA.js} +155 -75
  7. package/dist/agent-D11SxCvA.js.map +1 -0
  8. package/dist/agent.d.ts +1 -1
  9. package/dist/agent.js +2 -2
  10. package/dist/{anthropic-CV_OSYVD.js → anthropic-DdlSgT6K.js} +47 -25
  11. package/dist/anthropic-DdlSgT6K.js.map +1 -0
  12. package/dist/{auth-D5FfJtLf.js → auth-Ys_7TmRj.js} +2 -2
  13. package/dist/{auth-D5FfJtLf.js.map → auth-Ys_7TmRj.js.map} +1 -1
  14. package/dist/{cache-telemetry-BKAwsNxm.js → cache-telemetry-KJ7B-_Gh.js} +8 -3
  15. package/dist/cache-telemetry-KJ7B-_Gh.js.map +1 -0
  16. package/dist/chat/pure.d.ts +3 -3
  17. package/dist/chat/pure.js +2 -2
  18. package/dist/chat.d.ts +12 -5
  19. package/dist/chat.d.ts.map +1 -1
  20. package/dist/chat.js +7 -7
  21. package/dist/{completion-core-CXYSVhZo.js → completion-core-BRo86R_L.js} +23 -10
  22. package/dist/completion-core-BRo86R_L.js.map +1 -0
  23. package/dist/contexts/daytona.d.ts +1 -1
  24. package/dist/contexts/e2b.d.ts +1 -1
  25. package/dist/eval.d.ts +1 -1
  26. package/dist/extensions.d.ts +2 -2
  27. package/dist/extensions.js +2 -2
  28. package/dist/headless.d.ts +1 -1
  29. package/dist/headless.js +1 -1
  30. package/dist/{index-X02SI0nt.d.ts → index-CNyYEOy0.d.ts} +351 -42
  31. package/dist/index-CNyYEOy0.d.ts.map +1 -0
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +6 -6
  34. package/dist/{generate-data-WL_yGVL6.js → inline-autocomplete-BAwBcZtD.js} +191 -6
  35. package/dist/inline-autocomplete-BAwBcZtD.js.map +1 -0
  36. package/dist/mcp.d.ts +1 -1
  37. package/dist/output/stream-json.d.ts +1 -1
  38. package/dist/output/terminal.d.ts +1 -1
  39. package/dist/presets.d.ts +1 -1
  40. package/dist/presets.js +1 -1
  41. package/dist/providers/anthropic.d.ts +1 -1
  42. package/dist/providers/anthropic.js +1 -1
  43. package/dist/providers/arcee.d.ts +1 -1
  44. package/dist/providers/baseten.d.ts +1 -1
  45. package/dist/providers/cerebras.d.ts +1 -1
  46. package/dist/providers/local.d.ts +1 -1
  47. package/dist/providers/openai-compat.d.ts +1 -1
  48. package/dist/providers/openai.d.ts +1 -1
  49. package/dist/providers/openrouter.d.ts +1 -1
  50. package/dist/providers/xai.d.ts +1 -1
  51. package/dist/providers.d.ts +1 -1
  52. package/dist/providers.js +1 -1
  53. package/dist/restate.d.ts +1 -1
  54. package/dist/session/sqlite.d.ts +1 -1
  55. package/dist/session.d.ts +1 -1
  56. package/dist/skills.d.ts +1 -1
  57. package/dist/{tool-formatters-kg8O6wHZ.d.ts → tool-formatters-B7oWiy5m.d.ts} +2 -2
  58. package/dist/tool-formatters-B7oWiy5m.d.ts.map +1 -0
  59. package/dist/tools/fetch-url.d.ts +1 -1
  60. package/dist/tools/web-search.d.ts +1 -1
  61. package/dist/tools.d.ts +1 -1
  62. package/dist/tools.js +1 -1
  63. package/dist/{transcript-anchors-DAF4RbyU.d.ts → transcript-anchors-BUZ915pM.d.ts} +2 -2
  64. package/dist/{transcript-anchors-DAF4RbyU.d.ts.map → transcript-anchors-BUZ915pM.d.ts.map} +1 -1
  65. package/dist/{transcript-anchors-DAf0Mr_9.js → transcript-anchors-cc4gsU-j.js} +23 -8
  66. package/dist/transcript-anchors-cc4gsU-j.js.map +1 -0
  67. package/dist/tui.d.ts +25 -15
  68. package/dist/tui.d.ts.map +1 -1
  69. package/dist/tui.js +539 -57
  70. package/dist/tui.js.map +1 -1
  71. package/dist/{turn-operations-zkZ1L0eb.d.ts → turn-operations-2Ou_DkbC.d.ts} +3 -3
  72. package/dist/{turn-operations-zkZ1L0eb.d.ts.map → turn-operations-2Ou_DkbC.d.ts.map} +1 -1
  73. package/dist/{turn-operations-D9p-y9EC.js → turn-operations-CXjRaltC.js} +72 -2
  74. package/dist/{turn-operations-D9p-y9EC.js.map → turn-operations-CXjRaltC.js.map} +1 -1
  75. package/dist/types-BIarq1qE.js.map +1 -1
  76. package/dist/types.d.ts +1 -1
  77. package/docs/ARCHITECTURE.md +1 -1
  78. package/docs/EXTENSIONS.md +43 -6
  79. package/package.json +2 -1
  80. package/scripts/eval.ts +21 -3
  81. package/dist/agent-CZ3WSWqR.js.map +0 -1
  82. package/dist/anthropic-CV_OSYVD.js.map +0 -1
  83. package/dist/cache-telemetry-BKAwsNxm.js.map +0 -1
  84. package/dist/completion-core-CXYSVhZo.js.map +0 -1
  85. package/dist/generate-data-WL_yGVL6.js.map +0 -1
  86. package/dist/index-X02SI0nt.d.ts.map +0 -1
  87. package/dist/tool-formatters-kg8O6wHZ.d.ts.map +0 -1
  88. package/dist/transcript-anchors-DAf0Mr_9.js.map +0 -1
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as AgentProviderError, c as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, f as matchesContextExceeded, i as AgentContextExceededError, l as ClassifiedError, n as AgentAbortedError, o as AgentToolNotAllowedError, r as AgentBudgetExceededError, u as ClassifiedErrorKind } from "./timeout-8vSIRjzl.js";
2
- import { $d as PromptPart, $f as SessionData, $p as OpenRouterParams, Ad as AgentStats, Af as toolOutputBudgetByteLength, Bm as AnthropicParams, Bp as StreamOptions, Cf as ToolResultImageContent, Cm as OpenAIParams, Dd as AgentBehavior, Df as ToolResultVideoContent, Ef as ToolResultTextContent, Ff as ToolMap, Fi as AgentHookMap, Gp as TurnResult, Hd as McpServerConfig, Hp as ToolCall, Ii as AgentHooks, Jd as ProgressNudgeKind, Jf as SkillResource, Kf as SkillConfig, Lf as ReadStateEntry, Li as AgentOptions, Lp as Provider, Mf as toolResultToText, Mm as CerebrasParams, Nd as ChildRunStats, Nf as ToolContext, Od as AgentClock, Of as TurnFinishReason, Pf as ToolDef, Pi as Agent, Qd as PromptImagePart, Qf as Session, Rd as DEFAULT_AGENT_CLOCK, Rf as ReadStateMap, Rp as ProviderCapabilities, Sf as ToolResultDocumentRefContent, Tf as ToolResultMetadata, Ud as McpToolHookContext, Up as ToolResult, Wp as ToolSpec, Xd as PromptAudioPart, Xf as SkillsConfig, Yd as ProgressNudgeMessage, Zd as PromptDocumentPart, Zf as CreateSessionOptions, _ as MutationValidationFailure, _f as ToolHookContext, af as ResolveContentRefBlock, b as MutationValidationResult, bf as ToolResultContent, br as InteractionToolOptions, cf as SessionContentBlock, df as SessionMessage, dp as RemoteStoreOptions, ef as PromptTextPart, er as ValidationResult, ff as SessionTurn, g as MutationValidationBatch, gs as SpawnToolState, h as statsByModel, hc as McpConnection, hf as ThinkingLevel, hs as SpawnToolOptions, if as ResolveContentRef, jf as toolOutputByteLength, kd as AgentRunOptions, kf as TurnUsage, lf as SessionEndStatus, m as flattenTurns, mf as StreamHookContext, nf as RepeatGuardConfig, np as SessionStore, of as RetryConfig, p as ModelUsage, pf as SpawnHookContext, qd as OAuthRefreshHookContext, rf as RepeatGuardToolMatcher, sf as RunHookMap, t as Preset, tf as PromptVideoPart, tp as SessionRun, uf as SessionHookContext, us as ChildAgent, v as MutationValidationHooksOptions, vf as ToolOutcome, wf as ToolResultImageRefContent, x as SuccessfulMutationOutcome, xf as ToolResultDocumentContent, y as MutationValidationMutation, yf as ToolResultAudioContent, zp as StreamCallbacks } from "./index-X02SI0nt.js";
2
+ import { Af as ToolOutcome, Bd as AgentClock, Bf as TurnFinishReason, Cf as SessionMessage, Cp as RemoteStoreOptions, Df as ThinkingLevel, Ef as StreamHookContext, Ff as ToolResultImageContent, Fi as AgentHookMap, Fm as OpenAIParams, Gd as ChildRunStats, Gf as ToolContext, Hd as AgentStats, Hf as toolOutputBudgetByteLength, If as ToolResultImageRefContent, Ii as AgentHooks, Kf as ToolDef, Lf as ToolResultMetadata, Li as AgentOptions, Mf as ToolResultContent, Nf as ToolResultDocumentContent, Pf as ToolResultDocumentRefContent, Pi as Agent, Qm as AnthropicParams, Qp as StreamOptions, Rf as ToolResultTextContent, Sf as SessionHookContext, Tf as SpawnHookContext, Uf as toolOutputByteLength, Vd as AgentRunOptions, Vf as TurnUsage, Wf as toolResultToText, Wm as CerebrasParams, Xd as DEFAULT_AGENT_CLOCK, Xf as ReadStateMap, Xp as ProviderCapabilities, Yf as ReadStateEntry, Yp as Provider, Zp as StreamCallbacks, _ as MutationValidationFailure, _f as ResolveContentRefBlock, af as OAuthRefreshHookContext, b as MutationValidationResult, bc as McpConnection, bf as SessionContentBlock, br as InteractionToolOptions, bs as SpawnToolOptions, cf as PromptAudioPart, cp as SkillsConfig, df as PromptPart, dm as OpenRouterParams, dp as SessionData, ef as McpServerConfig, em as ToolCall, er as ValidationResult, ff as PromptTextPart, g as MutationValidationBatch, gf as ResolveContentRef, h as statsByModel, hf as RepeatGuardToolMatcher, hs as ChildAgent, ip as SkillConfig, jf as ToolResultAudioContent, kf as ToolHookContext, lf as PromptDocumentPart, lp as CreateSessionOptions, m as flattenTurns, mf as RepeatGuardConfig, mp as SessionStore, nm as ToolSpec, of as ProgressNudgeKind, op as SkillResource, p as ModelUsage, pf as PromptVideoPart, pp as SessionRun, qf as ToolMap, rm as TurnResult, sf as ProgressNudgeMessage, t as Preset, tf as McpToolHookContext, tm as ToolResult, uf as PromptImagePart, up as Session, v as MutationValidationHooksOptions, vf as RetryConfig, wf as SessionTurn, x as SuccessfulMutationOutcome, xf as SessionEndStatus, xs as SpawnToolState, y as MutationValidationMutation, yf as RunHookMap, zd as AgentBehavior, zf as ToolResultVideoContent } from "./index-CNyYEOy0.js";
3
3
  import { _ as TaskStallInfo, a as ContextType, c as ExecutionContext, g as TaskHandle, h as TaskExitInfo, l as ExecutionHandle, m as TaskEntry, n as ContextCapabilities, o as DetachedTasksCapability, p as SpawnConfig, r as ContextHardening, s as ExecResult, t as BackgroundTaskStatus } from "./types-BDccavwj.js";
4
4
  import { t as SandboxProvider } from "./sandbox-CgjG2VvQ.js";
5
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 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 TurnFinishReason, type TurnResult, type TurnUsage, type ValidationResult, flattenTurns, matchesContextExceeded, statsByModel, toolOutputBudgetByteLength, toolOutputByteLength, toolResultToText };
@@ -743,7 +743,7 @@ Tools with side effects or non-deterministic outputs MUST NOT be listed (no safe
743
743
 
744
744
  **`toolBudgets`** caps per-tool calls per run. When `runToolCounts[name] >= max`, fires `onExceed`: `'block'` refuses with `Blocked: <message>`, `'steer'` enqueues a synthetic user message (one per tool per run, deduped). Function form returns `{ mode, message }` dynamically. Fires `tool-budget:exceeded` (distinct from byte-level `budget:exceeded`). Counts include dedup substitutes by design.
745
745
 
746
- **`thinkingDecay`** tapers `thinkingBudget` per run-relative turn. `applyThinkingDecay(base, decay, turn)` runs at `runTurn` start. Struct form `{ afterTurn, factor, floor }` does geometric decay; function form `(turn, base) => number` accepts arbitrary curves. Result clamped to `[0, base]` so buggy curves can't exceed the caller's opt-in.
746
+ **`thinkingDecay`** tapers `thinkingBudget` per run-relative turn (1-indexed). `applyThinkingDecay(base, decay, turn)` runs at `runTurn` start. Struct form `{ afterTurn, factor, floor }` does geometric decay; function form `(turn, base) => number` accepts arbitrary curves. Result clamped to `[0, base]` so buggy curves can't exceed the caller's opt-in. Skipped for `thinking: 'adaptive'` only on providers with `adaptiveBudgetIsEnvelope` (Anthropic), where `thinkingBudget` caps the whole response envelope (`max_tokens`) and decaying it would strangle text/tool output; providers where adaptive `thinkingBudget` is a genuine per-turn thinking budget (openai-compat `reasoning.max_tokens`) still decay. `taskBudget` (Anthropic adaptive-only whole-task cap, emitted as `output_config.task_budget`) never decays.
747
747
 
748
748
  **Reliability levers** are opt-in and live in `src/behaviors/`. `writeFileExistingPolicy` blocks full-file rewrites of existing files and points the model at `read_file` + `edit` / `multi_edit`; `readFileDefaults` sets omitted `read_file` slice defaults without overriding explicit tool-call args; `thinkingOverrunPolicy` queues a non-interrupting next-turn nudge when streamed thinking crosses a threshold; `textToolCallRescue` steers after a model writes a tool call as text; `unknownToolRecovery` queues closest currently-advertised tool-name suggestions without changing the unknown-tool error result; `progressNudges` emits bounded non-interrupting pivot nudges for broad stalls that exact repeat guards do not cover; `maxTurnsWarningMessage` customizes the existing max-turn proximity nudge.
749
749
 
@@ -127,6 +127,7 @@ ctx.registerHook(event, handler)
127
127
  ctx.registerMcpServer(serverConfig)
128
128
  ctx.registerSkill(skillConfig)
129
129
  ctx.registerCompletionProvider(provider)
130
+ ctx.registerInlineAutocompleteProvider(provider)
130
131
  ctx.registerCommand(command)
131
132
  ctx.registerTheme(theme)
132
133
  ctx.registerAgent(profile)
@@ -152,6 +153,7 @@ ctx.registerConfigItem(categoryId?, item)
152
153
  | `registerMcpServer(McpServerConfig)` | Programmatic MCP server (no `mcps.json` edit) | Discovered `mcps.json` wins on `name` collision. |
153
154
  | `registerSkill(SkillConfig)` | Programmatic `defineSkill()` injection | Force-included in the user's `enabledSkills` allowlist so an existing allowlist doesn't silently hide the extension's skill. |
154
155
  | `registerCompletionProvider(provider)` | New `/` `@` `!` triggers in the prompt | One-character trigger; collides with built-ins (`/` `@` `#`) → ignored. |
156
+ | `registerInlineAutocompleteProvider({ id, suggest })` | Ghost-text autocomplete in the prompt (no trigger — runs on every keystroke pause) | `suggest(ctx)` returns a suffix string, a candidate list (user rotates with up/down, Tab accepts), or null. Gated by the user's `inlineAutocomplete` setting (default off). Built-in path provider runs first; first non-empty answer wins; dedupe by `id`, first registration wins; 150 ms per-provider deadline. |
155
157
  | `registerCommand(Command)` | A `/<name>` workflow — ordered handler steps (or a bare `run`) that `emit` local output (full markdown, or collapsed diff-colorable `detail` blocks), call `ctx.runAgent` for interactive sub-runs, `ctx.generateData` for silent schema-pinned JSON (no turns, no transcript; takes a zod v4 schema — result type inferred — or a plain JSON Schema object; optional `model` pins a catalog model), or `ctx.spawnAgents?` for parallel ISOLATED child agents (own context windows, full tool set, per-task `model` pinning — rendered like `spawn`-tool children); `ctx.appendContext?` persists a compact model-visible context note; `ctx.session?` exposes a read-only live view of the surrounding session (`id`/`turns`/`runs`/`metadata`) and `ctx.interaction?` offers user interaction (`confirm` yes/no, `askUser` forms — selects support `multi: true` — `presentPlan` approval) — the optional surfaces are host-dependent, so guard for bare hosts | `emit` output is display-only (persisted, never sent to the model); `appendContext` is the sanctioned model-visible escape hatch. Names dedupe first-registration-wins. Extensions extend `/` here rather than via a raw completion provider. |
156
158
  | `registerTheme(Theme)` | New `Settings → Theme` option | The picker's option list folds extension themes in at render time; built-in theme ids (`default`, `catppuccin-mocha`, …) shadow extension ids on collision. |
157
159
  | `registerAgent(AgentProfile)` | A complete agent (preset = tools + system + behavior + hooks + mcpServers + skills) added to the registry. Appears in the `shift+tab` cycle alongside Build / Plan. | Built-in profiles (`build`, `plan`) win on id collision; host-supplied profiles win over extensions too. |
@@ -404,7 +406,7 @@ flowchart TD
404
406
 
405
407
  Key invariants:
406
408
 
407
- 1. **State first.** `runTui` reads `state.json` before discovery so a previously-disabled extension's `setup()` never runs — side effects (file handles, child processes) don't fire for toggled-off extensions.
409
+ 1. **State first.** `runTui` reads `state.json` before discovery so the registry knows the enable allowlist as it builds. The allowlist gates **contributions, not execution**: a disabled-but-trusted extension is still imported and its `setup()` still runs — but only to declare its config schema (so its settings are browsable before you enable it). It runs with `ctx.disabled === true` and with the runtime bridges (`tui.*`, `submitPrompt`, `runtime`, `sessions`, `workspace`) withheld as inert no-ops, and it classifies as `inactive` so none of its behavioral contributions reach the active surface. Extensions that do side-effecting setup work (network probes, spawning processes, warming caches) must gate it on `!ctx.disabled`.
408
410
  2. **Setup-then-merge.** Each extension's contributions are captured per-extension on `LoadedExtension.contributions`. The host can re-merge any subset via `mergeContributions(active, inactive)` to flip toggles without re-running `setup`.
409
411
  3. **Sync `resolveConfig`.** Setup can be async; `resolveConfig` can't. The host pre-builds the registry, then passes it via `ChatOptions.extensionRegistry`. `runTui` does this internally; SDK / GUI hosts do the same:
410
412
 
@@ -430,11 +432,11 @@ Each extension shows up in `Settings → Extensions` with a checkbox. Toggling w
430
432
  - `[names]` — explicit allowlist.
431
433
 
432
434
  Disabled extensions:
433
- - Have `setup()` skipped at boot (no side effects).
434
- - Land on `registry.inactive` so the toggle UI still lists them.
435
+ - Still run `setup()` at boot with `ctx.disabled === true` — schema-declaration only. Runtime bridges are withheld (`ctx.tui.*` / `ctx.submitPrompt` / `ctx.runtime` are inert), so an inactive extension can't paint status, inject prompts, or touch the session. Author-level side effects must be gated on `!ctx.disabled`.
436
+ - Land on `registry.inactive` so the toggle UI still lists them, and expose their **config schema** (categories + items) so their settings render before you enable them.
435
437
  - Don't contribute tools / hooks / mcps / skills / themes / agents / providers / keybindings / footer hints / modals.
436
438
 
437
- **Toggle = live filter; `/reload` = full re-apply.** Toggling live-filters tools / hooks / mcpServers / skills / completion providers / keybindings / footer hints (re-applied at the next session activation) and hides the extension's HUD paint + notifications immediately — but `setup()` isn't re-run and agent profiles + providers + themes stay visible in their pickers. Run `/reload` (or restart) to fully apply a toggle: the registry rebuilds against the current allowlist, so disabled extensions skip `setup()` entirely and their picker entries disappear. Picking an extension-contributed profile after toggling its extension off — without reloading — activates a half-functional state: the profile's own preset works, but the extension's hooks / tools are suppressed.
439
+ **Toggle = live filter; `/reload` = full re-apply.** Toggling live-filters tools / hooks / mcpServers / skills / completion providers / keybindings / footer hints (re-applied at the next session activation) and hides the extension's HUD paint + notifications immediately — but `setup()` isn't re-run and agent profiles + providers + themes stay visible in their pickers. Run `/reload` (or restart) to fully apply a toggle: the registry rebuilds against the current allowlist, so disabled extensions re-run `setup()` in schema-only mode (`ctx.disabled`, no behavioral contributions) and their picker entries disappear. Picking an extension-contributed profile after toggling its extension off — without reloading — activates a half-functional state: the profile's own preset works, but the extension's hooks / tools are suppressed.
438
440
 
439
441
  ## Installing from GitHub / npm
440
442
 
@@ -489,9 +491,10 @@ subdir syntax — paste either source into the `ctrl+g` input):
489
491
  ```
490
492
  Tahul/zidane:extensions/git-flow # /commit — agent-written commit messages + one-tap push
491
493
  Tahul/zidane:extensions/headroom # compress large tool outputs via a local Headroom proxy
494
+ Tahul/zidane:extensions/pxpipe # image tool outputs in-process + optional pxpipe proxy routing
492
495
  ```
493
496
 
494
- Both are zero-dependency and mirror the packaging conventions to copy for
497
+ All mirror the packaging conventions to copy for
495
498
  your own extensions (`package.json` with `zidane-extension` keyword, entry
496
499
  `index.ts`, `zidane` as a peer).
497
500
 
@@ -889,7 +892,41 @@ ctx.registerConfigItem('limits', {
889
892
 
890
893
  `scope` is currently host metadata; existing stores still persist values in the per-extension settings bag unless a host implements scoped writes. `onChange` is likewise advisory for hosts/UIs (`'live'`, `'agent-rebuild'`, or `'restart'`). `requiresRestart` remains accepted as a compatibility hint.
891
894
 
892
- Item types: `boolean` (toggle), `number` (input with `min`/`max`/`step`), `string` (input, optional `pattern`/`multiline`), `enum` (cycling choice over static `options`), and `model` — an inline searchable picker over the host's credentialed model catalog (the ctrl+m interaction: type to filter, `↵` picks; with `multi: true`, `↵` toggles and `esc` applies). `model` persists a plain id — or a comma-separated id list when `multi` — and degrades to the free string input on hosts without a catalog, so read it with a tolerant parser and validate ids against `ctx.runtime.models()` yourself.
895
+ Item types: `boolean` (toggle), `number` (input with `min`/`max`/`step`), `string` (input, optional `pattern`/`multiline`), `enum` (cycling choice over static `options`), `model` — an inline searchable picker over the host's credentialed model catalog (the ctrl+m interaction: type to filter, `↵` picks; with `multi: true`, `↵` toggles and `esc` applies) — and `action` (imperative row, below). `model` persists a plain id — or a comma-separated id list when `multi` — and degrades to the free string input on hosts without a catalog, so read it with a tolerant parser and validate ids against `ctx.runtime.models()` yourself.
896
+
897
+ ### Config actions (`type: 'action'`)
898
+
899
+ An `action` item renders as a **press ↵ to run** row instead of a value editor — use it for imperative setup steps that belong next to the settings they configure (start a service, log in, run a migration):
900
+
901
+ ```ts
902
+ ctx.registerConfigItem('headroom', {
903
+ type: 'action',
904
+ key: 'runContainer',
905
+ label: 'Run container',
906
+ description: 'Start the Headroom proxy in Docker and set Base URL to it.',
907
+ run: async () => {
908
+ const baseUrl = await startMyService() // throw on failure — the message lands on the row
909
+ return { message: `proxy running at ${baseUrl}`, config: { baseUrl } }
910
+ },
911
+ // Optional passive probe — no ↵ needed: called when the settings panel
912
+ // surfaces the row (and re-called after any action settles), so the row
913
+ // shows live state. Return undefined to stay quiet (e.g. tool missing).
914
+ status: async () => {
915
+ const url = await findMyService()
916
+ return url ? { state: 'ok', message: `running at ${url}` } : { state: 'off', message: 'not running' }
917
+ },
918
+ })
919
+ ```
920
+
921
+ The contract:
922
+
923
+ - **Success** — resolve with `{ message?, config? }` (or nothing). `message` becomes the row's feedback line; `config` names THIS extension's config keys to persist. Actions can't write settings directly — the host validates each returned entry against the registered item's schema (`sanitizeExtensionConfigActionPatch`) and drops anything unknown or invalid, so a buggy action degrades instead of corrupting settings.
924
+ - **Failure** — throw / reject; the error message renders on the row in the error color.
925
+ - **Runtime** — the host serializes actions (one in flight per settings panel) but imposes no timeout: bound your own work (`AbortSignal.timeout`, CLI timeouts) or the row shows `running…` until you settle.
926
+ - **No value** — action keys hold nothing: `ctx.config.get('runContainer')` is `undefined`, and action items are omitted from the GUI wire schema (`toWireConfigSchema`) because `run` can't cross IPC — today actions are TUI-only.
927
+ - **Status probe** — the optional `status` callback is passive decoration: it must be fast (the host caps each probe at ~3s and drops late results), must not mutate anything, and a throw is treated as "no status". `state` drives the row color: `ok` (accent), `off` (mute), `error` (error).
928
+
929
+ The bundled `headroom` extension uses this for a **Run container** / **Stop container** pair managing a `zidane-headroom` container (`ghcr.io/chopratejas/headroom`) on the host: run reuses/starts/creates the container published on an ephemeral loopback port and returns `config: { baseUrl }` so the proxy URL is re-synced on every run; its `status` probe shows `running at …` / `container stopped` when you open Settings; stop leaves `baseUrl` untouched so a later run picks up where you left off. Run also forwards any provider credentials present in the host environment (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, AWS / Google) into the container via `docker run -e KEY` (value read from the host env, never placed in argv), and warns in the result message when none are found — a proxy without credentials boots and answers `/stats` but fails open on compression.
893
930
 
894
931
  ## Limitations + gotchas (v1)
895
932
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zidane",
3
- "version": "6.1.13",
3
+ "version": "6.2.6",
4
4
  "description": "an agent that goes straight to the goal",
5
5
  "type": "module",
6
6
  "private": false,
@@ -251,6 +251,7 @@
251
251
  "typecheck:extensions": "for d in extensions/*/; do tsc --noEmit -p \"$d\" || exit 1; done",
252
252
  "test:inference": "cd test-inference && bun test",
253
253
  "test:eval": "bun run scripts/eval.ts",
254
+ "evals": "bun run scripts/eval.ts",
254
255
  "restate:fixture:up": "docker compose -f test/fixtures/restate-docker/docker-compose.yml up --build -d",
255
256
  "restate:fixture:down": "docker compose -f test/fixtures/restate-docker/docker-compose.yml down -v",
256
257
  "restate:fixture:service": "PORT=19080 bun run test/fixtures/restate-docker/service.ts",
package/scripts/eval.ts CHANGED
@@ -22,6 +22,10 @@
22
22
  * --concurrency | --jobs <n> max eval cases to run in parallel (default 4)
23
23
  * --report-dir <dir> write per-case + run-summary JSON here
24
24
  * --artifact-dir <dir> write per-case result/events/transcript/workspace here
25
+ * --baseline [path] write a settings+measurements snapshot after the run
26
+ * (default path: benchmarks/evals/baseline.json)
27
+ * --extensions <names> enable repo extensions for the run, comma-separated
28
+ * (e.g. pxpipe,headroom — see benchmarks/evals/_extensions.ts)
25
29
  * --timeout <ms> per-test timeout (default 180000)
26
30
  */
27
31
 
@@ -30,6 +34,7 @@ import { resolve } from 'node:path'
30
34
 
31
35
  const DEFAULT_TIMEOUT_MS = '180000'
32
36
  const EVAL_TEST_FILE = 'test/eval-real.ts'
37
+ const DEFAULT_BASELINE_PATH = 'benchmarks/evals/baseline.json'
33
38
 
34
39
  const FLAG_TO_ENV: Record<string, string> = {
35
40
  'provider': 'ZIDANE_EVAL_PROVIDER',
@@ -45,6 +50,13 @@ const FLAG_TO_ENV: Record<string, string> = {
45
50
  'jobs': 'ZIDANE_EVAL_CONCURRENCY',
46
51
  'report-dir': 'ZIDANE_EVAL_REPORT_DIR',
47
52
  'artifact-dir': 'ZIDANE_EVAL_ARTIFACT_DIR',
53
+ 'baseline': 'ZIDANE_EVAL_BASELINE',
54
+ 'extensions': 'ZIDANE_EVAL_EXTENSIONS',
55
+ }
56
+
57
+ /** Flags whose value may be omitted, falling back to a default. */
58
+ const OPTIONAL_VALUE_FLAGS: Record<string, string> = {
59
+ baseline: DEFAULT_BASELINE_PATH,
48
60
  }
49
61
 
50
62
  const NUMERIC_FLAGS = new Set(['repeat', 'concurrency', 'jobs', 'timeout'])
@@ -79,9 +91,13 @@ export function parseEvalCliArgs(argv: string[], options: EvalCliParseOptions =
79
91
  const eq = key.indexOf('=')
80
92
  const rawKey = eq === -1 ? key : key.slice(0, eq)
81
93
  const inlineVal = eq === -1 ? undefined : key.slice(eq + 1)
82
- const value = inlineVal ?? (argv[i + 1] && !argv[i + 1].startsWith('-') ? argv[++i] : undefined)
83
- if (!value)
84
- throw new EvalCliError(`Missing value for eval flag: --${rawKey}`)
94
+ let value = inlineVal ?? (argv[i + 1] && !argv[i + 1].startsWith('-') ? argv[++i] : undefined)
95
+ if (!value) {
96
+ const fallback = OPTIONAL_VALUE_FLAGS[rawKey]
97
+ if (!fallback)
98
+ throw new EvalCliError(`Missing value for eval flag: --${rawKey}`)
99
+ value = fallback
100
+ }
85
101
  if (NUMERIC_FLAGS.has(rawKey))
86
102
  assertPositiveInteger(rawKey, value)
87
103
  if (rawKey === 'timeout') {
@@ -108,6 +124,8 @@ export function parseEvalCliArgs(argv: string[], options: EvalCliParseOptions =
108
124
 
109
125
  const cwd = options.cwd ?? process.cwd()
110
126
  const existingEnv = options.existingEnv ?? process.env
127
+ if (env.ZIDANE_EVAL_BASELINE)
128
+ env.ZIDANE_EVAL_BASELINE = resolve(cwd, env.ZIDANE_EVAL_BASELINE)
111
129
  // Default a run-scoped artifact dir so the summary can render clickable links
112
130
  // to each case's output. Overridable via --artifact-dir / ZIDANE_EVAL_ARTIFACT_DIR.
113
131
  if (!env.ZIDANE_EVAL_ARTIFACT_DIR && !existingEnv.ZIDANE_EVAL_ARTIFACT_DIR) {