zidane 7.0.15 → 7.0.17

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 (123) hide show
  1. package/README.md +21 -14
  2. package/dist/{acp-Bw2b_kka.js → acp-DTnq3bda.js} +4 -4
  3. package/dist/{acp-Bw2b_kka.js.map → acp-DTnq3bda.js.map} +1 -1
  4. package/dist/acp-cli.js +5 -5
  5. package/dist/acp.d.ts +1 -1
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-B_uQo4f1.js → agent-C5xr7lqh.js} +170 -22
  8. package/dist/agent-C5xr7lqh.js.map +1 -0
  9. package/dist/agent.d.ts +1 -1
  10. package/dist/agent.js +1 -1
  11. package/dist/{anthropic-QbHqqTkV.js → anthropic-D_aMBEj8.js} +88 -5
  12. package/dist/anthropic-D_aMBEj8.js.map +1 -0
  13. package/dist/{approvals-B9aIQJRQ.js → approvals-D3P3Wz58.js} +48 -72
  14. package/dist/approvals-D3P3Wz58.js.map +1 -0
  15. package/dist/{auth-plw6npda.js → auth-893jSFew.js} +5 -5
  16. package/dist/auth-893jSFew.js.map +1 -0
  17. package/dist/chat/pure.d.ts +4 -4
  18. package/dist/chat/pure.js +2 -2
  19. package/dist/chat.d.ts +6 -6
  20. package/dist/chat.js +5 -5
  21. package/dist/contexts/daytona.d.ts +1 -1
  22. package/dist/contexts/e2b.d.ts +1 -1
  23. package/dist/daemon-cli.js +1 -1
  24. package/dist/eval.d.ts +1 -1
  25. package/dist/eval.js +1 -1
  26. package/dist/extensions.d.ts +1 -1
  27. package/dist/extensions.js +1 -1
  28. package/dist/headless.d.ts +1 -1
  29. package/dist/headless.js +3 -3
  30. package/dist/{index-Df2CH6bn.d.ts → index-CyOGLSQN.d.ts} +27 -16
  31. package/dist/index-CyOGLSQN.d.ts.map +1 -0
  32. package/dist/{index-Dc_zYpEu.d.ts → index-D7H81_kd.d.ts} +125 -4
  33. package/dist/index-D7H81_kd.d.ts.map +1 -0
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js +6 -6
  36. package/dist/{ipc-T_pPnHkp.js → ipc-DY40IbcP.js} +2 -2
  37. package/dist/{ipc-T_pPnHkp.js.map → ipc-DY40IbcP.js.map} +1 -1
  38. package/dist/ipc.d.ts +5 -5
  39. package/dist/ipc.js +3 -3
  40. package/dist/mcp.d.ts +1 -1
  41. package/dist/{messages-21XfHxyF.js → messages-aORUmIKe.js} +2 -2
  42. package/dist/{messages-21XfHxyF.js.map → messages-aORUmIKe.js.map} +1 -1
  43. package/dist/{openai-compat-DY-AKxCg.js → openai-compat-cIeLSED_.js} +23 -25
  44. package/dist/openai-compat-cIeLSED_.js.map +1 -0
  45. package/dist/output/stream-json.d.ts +1 -1
  46. package/dist/output/terminal.d.ts +1 -1
  47. package/dist/plugins.d.ts +1 -1
  48. package/dist/presets.d.ts +1 -1
  49. package/dist/presets.js +1 -1
  50. package/dist/providers/anthropic.d.ts +2 -2
  51. package/dist/providers/anthropic.js +2 -2
  52. package/dist/providers/arcee.d.ts +1 -1
  53. package/dist/providers/arcee.js +1 -1
  54. package/dist/providers/baseten.d.ts +1 -1
  55. package/dist/providers/baseten.js +1 -1
  56. package/dist/providers/cerebras.d.ts +1 -1
  57. package/dist/providers/cerebras.js +1 -1
  58. package/dist/providers/local.d.ts +1 -1
  59. package/dist/providers/local.js +1 -1
  60. package/dist/providers/openai-compat.d.ts +1 -1
  61. package/dist/providers/openai-compat.js +1 -1
  62. package/dist/providers/openai.d.ts +1 -1
  63. package/dist/providers/openai.js +2 -2
  64. package/dist/providers/openrouter.d.ts +1 -1
  65. package/dist/providers/openrouter.js +1 -1
  66. package/dist/providers/xai.d.ts +1 -1
  67. package/dist/providers/xai.js +1 -1
  68. package/dist/{providers-CoK1rZ1p.js → providers-CTkZSxvp.js} +2 -2
  69. package/dist/{providers-CoK1rZ1p.js.map → providers-CTkZSxvp.js.map} +1 -1
  70. package/dist/providers.d.ts +1 -1
  71. package/dist/providers.js +3 -3
  72. package/dist/restate.d.ts +1 -1
  73. package/dist/restate.js +2 -2
  74. package/dist/{server-DXM8ZbGi.js → server-DaZqNd61.js} +5 -5
  75. package/dist/{server-DXM8ZbGi.js.map → server-DaZqNd61.js.map} +1 -1
  76. package/dist/session/sqlite.d.ts +1 -1
  77. package/dist/{session-DPZnncaQ.js → session-23Stp71-.js} +2 -2
  78. package/dist/{session-DPZnncaQ.js.map → session-23Stp71-.js.map} +1 -1
  79. package/dist/session.d.ts +1 -1
  80. package/dist/session.js +2 -2
  81. package/dist/skills.d.ts +1 -1
  82. package/dist/{tool-formatters-BgdOYAy9.d.ts → tool-formatters-9_ABHXRG.d.ts} +2 -2
  83. package/dist/{tool-formatters-BgdOYAy9.d.ts.map → tool-formatters-9_ABHXRG.d.ts.map} +1 -1
  84. package/dist/tools/fetch-url.d.ts +1 -1
  85. package/dist/tools/web-search.d.ts +1 -1
  86. package/dist/tools.d.ts +1 -1
  87. package/dist/tools.js +1 -1
  88. package/dist/{transcript-anchors-CtnwuQJM.d.ts → transcript-anchors-CbZkEMIN.d.ts} +11 -5
  89. package/dist/transcript-anchors-CbZkEMIN.d.ts.map +1 -0
  90. package/dist/tui.d.ts +67 -11
  91. package/dist/tui.d.ts.map +1 -1
  92. package/dist/tui.js +2930 -2596
  93. package/dist/tui.js.map +1 -1
  94. package/dist/{turn-operations-khAvr7KJ.d.ts → turn-operations-DsVjoO3S.d.ts} +30 -4
  95. package/dist/{turn-operations-khAvr7KJ.d.ts.map → turn-operations-DsVjoO3S.d.ts.map} +1 -1
  96. package/dist/{turn-operations-DkJ1R0p8.js → turn-operations-Dt5L8smX.js} +31 -2
  97. package/dist/{turn-operations-DkJ1R0p8.js.map → turn-operations-Dt5L8smX.js.map} +1 -1
  98. package/dist/types-CWgENVLY.js.map +1 -1
  99. package/dist/types.d.ts +1 -1
  100. package/docs/ACP.md +6 -0
  101. package/docs/ARCHITECTURE.md +179 -356
  102. package/docs/ARTIFACTS.md +145 -0
  103. package/docs/CHAT.md +426 -1312
  104. package/docs/EXECUTION_CONTEXT.md +46 -19
  105. package/docs/EXTENSIONS.md +215 -623
  106. package/docs/HEADLESS.md +5 -0
  107. package/docs/INTERACTIONS.md +21 -22
  108. package/docs/IPC.md +319 -344
  109. package/docs/PLUGINS.md +2 -0
  110. package/docs/README.md +57 -0
  111. package/docs/RESTATE.md +199 -491
  112. package/docs/RUN_IN_BACKGROUND.md +107 -558
  113. package/docs/SKILL.md +172 -238
  114. package/docs/TUI.md +216 -591
  115. package/package.json +1 -1
  116. package/dist/agent-B_uQo4f1.js.map +0 -1
  117. package/dist/anthropic-QbHqqTkV.js.map +0 -1
  118. package/dist/approvals-B9aIQJRQ.js.map +0 -1
  119. package/dist/auth-plw6npda.js.map +0 -1
  120. package/dist/index-Dc_zYpEu.d.ts.map +0 -1
  121. package/dist/index-Df2CH6bn.d.ts.map +0 -1
  122. package/dist/openai-compat-DY-AKxCg.js.map +0 -1
  123. package/dist/transcript-anchors-CtnwuQJM.d.ts.map +0 -1
package/dist/acp-cli.js CHANGED
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { m as openaiCompat } from "./openai-compat-DY-AKxCg.js";
3
- import { xt as basic_default } from "./agent-B_uQo4f1.js";
2
+ import { m as openaiCompat } from "./openai-compat-cIeLSED_.js";
3
+ import { xt as basic_default } from "./agent-C5xr7lqh.js";
4
4
  import { r as createProcessContext } from "./contexts-BSFQVclW.js";
5
5
  import { createSandboxContext } from "./contexts/sandbox.js";
6
6
  import { p as resolveStorageDirs } from "./plugins-B531Tz5b.js";
7
- import { n as anthropic } from "./anthropic-QbHqqTkV.js";
7
+ import { n as anthropic } from "./anthropic-D_aMBEj8.js";
8
8
  import { arcee } from "./providers/arcee.js";
9
9
  import { baseten } from "./providers/baseten.js";
10
10
  import { cerebras } from "./providers/cerebras.js";
11
11
  import { openai } from "./providers/openai.js";
12
12
  import { openrouter } from "./providers/openrouter.js";
13
13
  import { xai } from "./providers/xai.js";
14
- import { d as StartUsageError, f as buildStartLocalOptions, h as startProviderNames, i as withAcpDefaultTools, m as startLocalArgOptions, p as parseStartArgValues, t as runAcpStdioServer } from "./acp-Bw2b_kka.js";
15
- import { d as BUILTIN_PROVIDERS, i as readCredentials, m as credKeyOf, r as credentialsPath, t as detectAuth, x as modelsForDescriptor } from "./auth-plw6npda.js";
14
+ import { d as StartUsageError, f as buildStartLocalOptions, h as startProviderNames, i as withAcpDefaultTools, m as startLocalArgOptions, p as parseStartArgValues, t as runAcpStdioServer } from "./acp-DTnq3bda.js";
15
+ import { d as BUILTIN_PROVIDERS, i as readCredentials, m as credKeyOf, r as credentialsPath, t as detectAuth, x as modelsForDescriptor } from "./auth-893jSFew.js";
16
16
  import { createDaytonaProvider } from "./contexts/daytona.js";
17
17
  import { createDockerContext } from "./contexts/docker.js";
18
18
  import { createE2BProvider } from "./contexts/e2b.js";
package/dist/acp.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { J_ as SessionStore, Mg as PromptPart, Vg as SessionContentBlock, W_ as Session, Xi as AgentOptions, d_ as TurnUsage, g_ as ToolDef, ig as AgentBehavior, mm as Provider, n_ as ToolResultContent, qi as Agent, t as Preset, xg as McpServerConfig } from "./index-Dc_zYpEu.js";
1
+ import { Hg as SessionContentBlock, Ng as PromptPart, Sg as McpServerConfig, Xi as AgentOptions, Z_ as SessionStore, a_ as ToolResultContent, ag as AgentBehavior, m_ as TurnUsage, mm as Provider, q_ as Session, qi as Agent, t as Preset, y_ as ToolDef } from "./index-D7H81_kd.js";
2
2
  import { c as ExecutionContext } from "./types-U-rIVUDw.js";
3
3
  import { Readable, Writable } from "node:stream";
4
4
 
package/dist/acp.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { n as JsonRpcRemoteError, r as createJsonRpcConnection } from "./json-rpc-rSWMUh9b.js";
2
- import { a as wrapToolsForAcpClient, c as sessionBlocksToAcp, i as withAcpDefaultTools, l as stopReasonFromRun, n as AcpProtocolError, o as acpMcpServersToZidane, r as createAcpServer, s as acpPromptToPromptParts, t as runAcpStdioServer, u as toolResultToAcpContent } from "./acp-Bw2b_kka.js";
2
+ import { a as wrapToolsForAcpClient, c as sessionBlocksToAcp, i as withAcpDefaultTools, l as stopReasonFromRun, n as AcpProtocolError, o as acpMcpServersToZidane, r as createAcpServer, s as acpPromptToPromptParts, t as runAcpStdioServer, u as toolResultToAcpContent } from "./acp-DTnq3bda.js";
3
3
  export { AcpProtocolError, JsonRpcRemoteError, acpMcpServersToZidane, acpPromptToPromptParts, createAcpServer, createJsonRpcConnection, runAcpStdioServer, sessionBlocksToAcp, stopReasonFromRun, toolResultToAcpContent, withAcpDefaultTools, wrapToolsForAcpClient };
@@ -1,4 +1,4 @@
1
- import { B as rewriteMessagesToWire, H as toWireName, I as augmentMcpDoubleUnderscoreAliases, L as buildAliasMaps, M as buildPromptMessage, N as canonicalizePrompt, R as buildSanitizedWireAliases, V as toCanonicalName, z as rewriteContentToCanonical } from "./openai-compat-DY-AKxCg.js";
1
+ import { B as rewriteMessagesToWire, H as toWireName, I as augmentMcpDoubleUnderscoreAliases, L as buildAliasMaps, M as buildPromptMessage, N as canonicalizePrompt, R as buildSanitizedWireAliases, V as toCanonicalName, w as fillEstimatedCost, z as rewriteContentToCanonical } from "./openai-compat-cIeLSED_.js";
2
2
  import { a as documentBlockMarker, c as toolOutputBudgetByteLength, l as toolOutputByteLength, o as isWireTurn, s as sanitizeToolResultMetadata, t as DEFAULT_AGENT_CLOCK, u as toolResultToText } from "./types-CWgENVLY.js";
3
3
  import { a as stripLineNumberPrefixes, i as resolveOldString, n as buildContextBreakdown, o as styleReplacementForVia, r as describeVia, t as buildContextSegments } from "./context-segments-CJCtJ9sU.js";
4
4
  import { n as estimateTokens, r as utf8ByteLength } from "./utils-ngQzYzZD.js";
@@ -17,8 +17,8 @@ import { t as escapeXml } from "./xml-D5HBhJle.js";
17
17
  import { n as reconcileImageMediaType } from "./media-sniff-UKijEaiQ.js";
18
18
  import { f as wrapDiscoveredMcpTools, i as deriveMcpToolMeta, n as connectMcpServers, s as nonOwningMcpView } from "./mcp-BIWa57eY.js";
19
19
  import { appendStaticSection, renderSystemForWire } from "./prompt.js";
20
- import { a as detectTurnInterruption, c as ensureToolResultPairing, l as filterUnresolvedToolUses, m as resolveContentRefsInMessages, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, p as remintDuplicateToolCallIds, s as ensureEndsWithUserMessage } from "./messages-21XfHxyF.js";
21
- import { a as getExtensionSessionState, c as setExtensionSessionState, l as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as resumeChainRunIds } from "./session-DPZnncaQ.js";
20
+ import { a as detectTurnInterruption, c as ensureToolResultPairing, l as filterUnresolvedToolUses, m as resolveContentRefsInMessages, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, p as remintDuplicateToolCallIds, s as ensureEndsWithUserMessage } from "./messages-aORUmIKe.js";
21
+ import { a as getExtensionSessionState, c as setExtensionSessionState, l as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as resumeChainRunIds } from "./session-23Stp71-.js";
22
22
  import { n as flattenTurns, r as formatTokenUsage, t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
23
23
  import { a as settleWithinTimeout, i as resolveTimeoutMs, n as abortableSleep, o as withInactivityTimeout, r as linkAbortSignal, s as withTimeout$1, t as OperationTimeoutError } from "./timeout-CjOG2mea.js";
24
24
  import { createRequire } from "node:module";
@@ -1530,6 +1530,8 @@ function createArtifactDetectHook(registration, options = {}) {
1530
1530
  //#endregion
1531
1531
  //#region src/extensions/builtin-artifact-kinds.ts
1532
1532
  const GITHUB_PR_URL = /https:\/\/github\.com\/([\w.-]+)\/([\w.-]+)\/pull\/(\d+)/g;
1533
+ /** A single GitHub path segment (owner / repo), as the detector captures it. */
1534
+ const GITHUB_SEGMENT = /^[\w.-]+$/;
1533
1535
  const GITLAB_MR_URL = /https?:\/\/[\w.-]+\/([\w./-]+?)\/-\/merge_requests\/(\d+)/g;
1534
1536
  const GIT_COMMIT_LINE = /^\[([^\s\]]+)(?: \(root-commit\))? ([0-9a-f]{7,40})\] (.*)$/m;
1535
1537
  /** Don't re-resolve an open PR more often than this. */
@@ -1605,17 +1607,28 @@ const pullRequestKind = {
1605
1607
  * and a fresh `resolvedAt` (within {@link PR_RESOLVE_TTL_MS}) is reused, so
1606
1608
  * reopening the modal and arrowing through a dozen PRs doesn't spend a
1607
1609
  * dozen anonymous API calls each time.
1610
+ *
1611
+ * `meta` is NOT trusted here: the detector regex-captures these fields, but
1612
+ * `record_artifact` and `ctx.artifacts.record` let a model or an extension
1613
+ * write anything. Path segments are re-validated to the shape a real repo
1614
+ * has — rejecting is clearer than escaping, since nothing else is a repo —
1615
+ * so a crafted `owner` can't steer this token-bearing request at another
1616
+ * endpoint.
1608
1617
  */
1609
1618
  async resolve(artifact) {
1610
1619
  const meta = metaRecord(artifact);
1611
- if (meta.provider !== "github" || typeof meta.owner !== "string" || typeof meta.repo !== "string" || typeof meta.number !== "number") return void 0;
1620
+ if (meta.provider !== "github") return void 0;
1621
+ const { owner, repo, number } = meta;
1622
+ if (typeof owner !== "string" || !GITHUB_SEGMENT.test(owner)) return void 0;
1623
+ if (typeof repo !== "string" || !GITHUB_SEGMENT.test(repo)) return void 0;
1624
+ if (typeof number !== "number" || !Number.isInteger(number) || number <= 0) return void 0;
1612
1625
  if (meta.state === "merged" || meta.state === "closed") return void 0;
1613
1626
  if (typeof meta.resolvedAt === "number" && Date.now() - meta.resolvedAt < PR_RESOLVE_TTL_MS) return void 0;
1614
1627
  const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
1615
1628
  const controller = new AbortController();
1616
1629
  const timer = setTimeout(() => controller.abort(), 4e3);
1617
1630
  try {
1618
- const res = await fetch(`https://api.github.com/repos/${meta.owner}/${meta.repo}/pulls/${meta.number}`, {
1631
+ const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/pulls/${number}`, {
1619
1632
  headers: {
1620
1633
  "Accept": "application/vnd.github+json",
1621
1634
  "User-Agent": "zidane",
@@ -1702,18 +1715,18 @@ const branchKind = {
1702
1715
  },
1703
1716
  render: (artifact) => ({ title: artifact.label })
1704
1717
  };
1718
+ /**
1719
+ * `file` has NO automatic detector on purpose. Every `write_file` becoming
1720
+ * an artifact is noise — a refactor would produce dozens of rows that are
1721
+ * really just the diff and go stale on the next rename. A file is an
1722
+ * artifact only when something deliberately says so: the model via
1723
+ * `record_artifact` (a generated report, an export) or an extension via
1724
+ * `ctx.artifacts.record` (a build output). The kind keeps its rendering
1725
+ * and `file:` URI canonicalization for those paths.
1726
+ */
1705
1727
  const fileKind = {
1706
1728
  kind: ARTIFACT_KINDS.file,
1707
1729
  label: "File",
1708
- detect({ tool, input, result, isError }) {
1709
- if (isError || tool !== "write_file") return void 0;
1710
- const path = typeof input.path === "string" ? input.path : void 0;
1711
- if (!path || !resultText(result).startsWith(`Created ${path} (`)) return void 0;
1712
- return {
1713
- uri: `file:${path}`,
1714
- label: path
1715
- };
1716
- },
1717
1730
  render(artifact) {
1718
1731
  const path = artifact.uri.startsWith("file://") ? artifact.uri.slice(7) : artifact.uri;
1719
1732
  return {
@@ -2787,7 +2800,7 @@ const KEYBINDING_DEFS = [
2787
2800
  action: "openArtifacts",
2788
2801
  default: "ctrl+shift+a",
2789
2802
  label: "artifacts",
2790
- description: "open the session's artifacts (pull requests, branches, commits, files). Same as /artifacts",
2803
+ description: "toggle the artifacts rail (pull requests, branches, commits, recorded files) — same as clicking the ▢ chip on the title bar",
2791
2804
  group: "Global"
2792
2805
  },
2793
2806
  {
@@ -3360,8 +3373,10 @@ const recordArtifact = {
3360
3373
  spec: {
3361
3374
  name: RECORD_ARTIFACT_TOOL,
3362
3375
  description: [
3363
- "Record an artifact this session produced so it is tracked on the session (visible via /artifacts).",
3364
- "Pull requests from `gh pr create`, commits, branches and files created with `write_file` are detected automatically — call this only for outputs the automatic detection cannot see: a PR opened from a background shell task, a deployment, an issue, a release, a file created by a script.",
3376
+ "Record a deliverable this session produced so the user can find it later in the artifacts panel. An artifact is an OUTPUT the user would want a link to — not a step of the work.",
3377
+ "Worth recording: a pull request or merge request URL, a deployment / preview URL, an issue or ticket you filed, a release or tag, a generated report / export / dataset the user asked for, a build output they will pick up.",
3378
+ "Not worth recording: source files you edited or created as part of implementing a change, scratch files, logs, intermediate results, anything already implied by the diff.",
3379
+ "Pull requests from `gh pr create`, `git commit` commits and newly created branches are detected automatically — record those only when the automatic path could not see them (e.g. a PR opened from a background shell task).",
3365
3380
  "Idempotent per (kind, uri): recording the same artifact again refreshes its label/meta."
3366
3381
  ].join("\n"),
3367
3382
  inputSchema: {
@@ -3369,7 +3384,7 @@ const recordArtifact = {
3369
3384
  properties: {
3370
3385
  kind: {
3371
3386
  type: "string",
3372
- description: "Artifact kind: `pull_request`, `branch`, `commit`, `file`, or a custom kind such as `deployment` / `issue` (`[\\w.:-]+`)."
3387
+ description: "Artifact kind: `pull_request`, `branch`, `commit`, `file` (a deliverable file, not a source edit), or a custom kind such as `deployment`, `issue`, `release` (`[\\w.:-]+`)."
3373
3388
  },
3374
3389
  uri: {
3375
3390
  type: "string",
@@ -3403,7 +3418,7 @@ const recordArtifact = {
3403
3418
  //#region src/presets/artifacts.ts
3404
3419
  /**
3405
3420
  * Built-in artifact detection — records pull requests, branches, commits
3406
- * and created files a session produces (see `session/artifacts.ts`).
3421
+ * a session produces — never files automatically (see `session/artifacts.ts`).
3407
3422
  *
3408
3423
  * Opt-in by composition, not baked into `basic`: SDK consumers who never
3409
3424
  * spread this preset see zero behavior change, while the TUI / daemon
@@ -7299,6 +7314,32 @@ function createArtifactsSurface(resolve) {
7299
7314
  kind,
7300
7315
  uri
7301
7316
  });
7317
+ },
7318
+ record: async (input) => {
7319
+ const scope = resolve();
7320
+ if (!scope?.sessionId) return void 0;
7321
+ const write = scope.record ?? scope.store.upsertArtifact?.bind(scope.store);
7322
+ if (!write) return void 0;
7323
+ const normalized = normalizeArtifactInput(input);
7324
+ if (!normalized) return void 0;
7325
+ const now = Date.now();
7326
+ const projectRoot = normalized.projectRoot ?? scope.projectRoot;
7327
+ try {
7328
+ return await write({
7329
+ id: crypto.randomUUID(),
7330
+ sessionId: scope.sessionId,
7331
+ ...scope.runId ? { runId: scope.runId } : {},
7332
+ kind: normalized.kind,
7333
+ uri: normalized.uri,
7334
+ label: normalized.label,
7335
+ ...projectRoot ? { projectRoot } : {},
7336
+ ...normalized.meta !== void 0 ? { meta: normalized.meta } : {},
7337
+ createdAt: now,
7338
+ updatedAt: now
7339
+ }) ?? void 0;
7340
+ } catch {
7341
+ return;
7342
+ }
7302
7343
  }
7303
7344
  };
7304
7345
  }
@@ -13116,6 +13157,26 @@ const DEFAULT_AUTO_COMPACT_MAX_FAILURES = 2;
13116
13157
  */
13117
13158
  const COMPACT_PROGRESS_THROTTLE_MS = 250;
13118
13159
  /**
13160
+ * Minimum gap between `stream:progress` dispatches during a parent turn. Same
13161
+ * cadence as compaction progress: fast enough to read as live, slow enough
13162
+ * that the (possibly async, catalog-priced) hook never becomes a hot path.
13163
+ */
13164
+ const STREAM_PROGRESS_THROTTLE_MS = 250;
13165
+ /**
13166
+ * Prompt-side proxy for a live cost estimate when the provider hasn't reported
13167
+ * mid-stream usage: the previous assistant turn's split. Consecutive turns
13168
+ * ride nearly the same prefix, so its fresh/cached/written breakdown is a far
13169
+ * better guess than "all fresh input" (which would overprice a cached prompt
13170
+ * ten-fold). `undefined` on the first turn of a session — the estimate then
13171
+ * prices output only until `turn:after` settles it.
13172
+ */
13173
+ function lastAssistantUsage(turns) {
13174
+ for (let i = turns.length - 1; i >= 0; i--) {
13175
+ const t = turns[i];
13176
+ if (t.role === "assistant" && t.usage && t.usage.input + (t.usage.cacheRead ?? 0) + (t.usage.cacheCreation ?? 0) > 0) return t.usage;
13177
+ }
13178
+ }
13179
+ /**
13119
13180
  * Normalize `behavior.autoCompact` into the loop's {@link ResolvedAutoCompact}
13120
13181
  * shape, or `undefined` when disabled (`false` / unset). Applies the
13121
13182
  * `provider.meta.contextWindow` fallback and inherits `compactKeepTurns` for
@@ -13460,6 +13521,71 @@ async function executeTurn(ctx, turn, priorUsage) {
13460
13521
  if (process.env.ZIDANE_DEBUG) process.stderr.write(`[zidane/loop] stream hook handler threw: ${errorMessage(err)}\n`);
13461
13522
  });
13462
13523
  };
13524
+ let liveUsage;
13525
+ let lastProgressAt = 0;
13526
+ let progressTimer;
13527
+ let progressEnded = false;
13528
+ const priorTurnUsage = lastAssistantUsage(ctx.turns);
13529
+ const emitProgress = async () => {
13530
+ if (progressEnded) return;
13531
+ const providerOutput = liveUsage?.outputTokens;
13532
+ const outputTokens = providerOutput ?? estimateTokens(currentText + currentThinking);
13533
+ const promptSide = liveUsage?.inputTokens !== void 0 ? {
13534
+ input: liveUsage.inputTokens,
13535
+ cacheRead: liveUsage.cacheRead,
13536
+ cacheCreation: liveUsage.cacheCreation
13537
+ } : priorTurnUsage ? {
13538
+ input: priorTurnUsage.input,
13539
+ cacheRead: priorTurnUsage.cacheRead,
13540
+ cacheCreation: priorTurnUsage.cacheCreation
13541
+ } : { input: 0 };
13542
+ let estCostUsd;
13543
+ if (liveUsage?.billable !== false) estCostUsd = (await fillEstimatedCost({
13544
+ ...promptSide,
13545
+ output: outputTokens,
13546
+ modelId: streamOptions.model
13547
+ }, ctx.provider.name, void 0, ctx.behavior.modelCatalog)).cost;
13548
+ if (progressEnded) return;
13549
+ await ctx.hooks.callHook("stream:progress", {
13550
+ turnId,
13551
+ elapsedMs: Date.now() - streamStartedAt,
13552
+ outputTokens,
13553
+ ...liveUsage?.inputTokens !== void 0 ? { inputTokens: liveUsage.inputTokens } : {},
13554
+ ...liveUsage?.cacheRead !== void 0 ? { cacheRead: liveUsage.cacheRead } : {},
13555
+ ...liveUsage?.cacheCreation !== void 0 ? { cacheCreation: liveUsage.cacheCreation } : {},
13556
+ estimated: providerOutput === void 0,
13557
+ ...estCostUsd !== void 0 ? { estCostUsd } : {}
13558
+ });
13559
+ };
13560
+ const fireProgress = () => {
13561
+ lastProgressAt = Date.now();
13562
+ emitProgress().catch((err) => {
13563
+ if (process.env.ZIDANE_DEBUG) process.stderr.write(`[zidane/loop] stream:progress handler threw: ${errorMessage(err)}\n`);
13564
+ });
13565
+ };
13566
+ const scheduleProgress = () => {
13567
+ if (progressEnded) return;
13568
+ const wait = STREAM_PROGRESS_THROTTLE_MS - (Date.now() - lastProgressAt);
13569
+ if (wait <= 0) {
13570
+ if (progressTimer) {
13571
+ clearTimeout(progressTimer);
13572
+ progressTimer = void 0;
13573
+ }
13574
+ fireProgress();
13575
+ return;
13576
+ }
13577
+ if (!progressTimer) progressTimer = setTimeout(() => {
13578
+ progressTimer = void 0;
13579
+ fireProgress();
13580
+ }, wait);
13581
+ };
13582
+ const endProgress = () => {
13583
+ progressEnded = true;
13584
+ if (progressTimer) {
13585
+ clearTimeout(progressTimer);
13586
+ progressTimer = void 0;
13587
+ }
13588
+ };
13463
13589
  const retryCfg = resolveRetryConfig(ctx.behavior.retry);
13464
13590
  let result;
13465
13591
  let attempt = 0;
@@ -13477,6 +13603,7 @@ async function executeTurn(ctx, turn, priorUsage) {
13477
13603
  text,
13478
13604
  turnId
13479
13605
  }));
13606
+ scheduleProgress();
13480
13607
  },
13481
13608
  onThinking(delta) {
13482
13609
  markTurnTtft();
@@ -13487,6 +13614,11 @@ async function executeTurn(ctx, turn, priorUsage) {
13487
13614
  thinking,
13488
13615
  turnId
13489
13616
  }));
13617
+ scheduleProgress();
13618
+ },
13619
+ onUsage(usage) {
13620
+ liveUsage = usage;
13621
+ scheduleProgress();
13490
13622
  },
13491
13623
  onServerToolUse({ id, name, input }) {
13492
13624
  enqueueStreamHook(() => ctx.hooks.callHook("stream:server_tool_use", {
@@ -13516,6 +13648,11 @@ async function executeTurn(ctx, turn, priorUsage) {
13516
13648
  break;
13517
13649
  } catch (caught) {
13518
13650
  let terminalErr = caught;
13651
+ liveUsage = void 0;
13652
+ if (progressTimer) {
13653
+ clearTimeout(progressTimer);
13654
+ progressTimer = void 0;
13655
+ }
13519
13656
  const failure = assessStreamFailure({
13520
13657
  err: caught,
13521
13658
  runAborted: ctx.signal.aborted,
@@ -13633,10 +13770,19 @@ async function executeTurn(ctx, turn, priorUsage) {
13633
13770
  },
13634
13771
  cumulativeUsage: buildCumulativeUsage(priorUsage, errorUsage)
13635
13772
  }));
13773
+ endProgress();
13636
13774
  throw wrapProviderError(terminalErr, ctx);
13637
13775
  }
13638
13776
  }
13639
13777
  await streamHookChain;
13778
+ if (progressTimer || currentText || currentThinking || liveUsage) {
13779
+ if (progressTimer) {
13780
+ clearTimeout(progressTimer);
13781
+ progressTimer = void 0;
13782
+ }
13783
+ await settledHook(ctx, "hook stream:progress", emitProgress());
13784
+ }
13785
+ endProgress();
13640
13786
  if (currentText) await settledHook(ctx, "hook stream:end", ctx.hooks.callHook("stream:end", {
13641
13787
  text: currentText,
13642
13788
  turnId
@@ -14385,7 +14531,7 @@ async function emitToolResult(ctx, params) {
14385
14531
  const MAX_ARTIFACTS_PER_TOOL_RESULT = 50;
14386
14532
  async function recordArtifactsFromMetadata(ctx, params) {
14387
14533
  const raw = params.metadata?.[ARTIFACTS_METADATA_KEY];
14388
- if (!Array.isArray(raw) || raw.length === 0 || !ctx.session) return;
14534
+ if (ctx.artifactsDisabled || !Array.isArray(raw) || raw.length === 0 || !ctx.session) return;
14389
14535
  const inputs = [];
14390
14536
  for (const entry of raw.slice(0, MAX_ARTIFACTS_PER_TOOL_RESULT)) {
14391
14537
  const normalized = normalizeArtifactInput(entry);
@@ -15551,6 +15697,7 @@ const HOOK_EVENT_SET = /* @__PURE__ */ new Set([
15551
15697
  "stream:text",
15552
15698
  "stream:end",
15553
15699
  "stream:thinking",
15700
+ "stream:progress",
15554
15701
  "stream:server_tool_use",
15555
15702
  "stream:server_tool_result",
15556
15703
  "stream:error",
@@ -16640,7 +16787,7 @@ function warnContextContributorFailureOnce(contributor, err) {
16640
16787
  process.stderr.write(`[zidane/agent] context breakdown contributor failed${owner}: ${errorMessage(err)}\n`);
16641
16788
  }
16642
16789
  function createAgent(rawOptions) {
16643
- const { provider: providerOption, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, handle: injectedHandle, mcpServers, session, readState: agentReadState, toolState: toolStateStore, skills: agentSkills, mcpConnector, mcpToolWrap, eager, hooks: initialHooks, clock: agentClock, toolKill, contextBreakdownSections, runTransforms, behaviorTransforms, toolCatalogTransforms, mcpConfigTransforms, skillPolicies, toolResultMetadata } = foldExtensionRegistry(rawOptions);
16790
+ const { provider: providerOption, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, handle: injectedHandle, mcpServers, session, readState: agentReadState, toolState: toolStateStore, skills: agentSkills, mcpConnector, mcpToolWrap, eager, hooks: initialHooks, clock: agentClock, toolKill, contextBreakdownSections, runTransforms, behaviorTransforms, toolCatalogTransforms, mcpConfigTransforms, skillPolicies, toolResultMetadata, artifacts: artifactsOption } = foldExtensionRegistry(rawOptions);
16644
16791
  const providers = normalizeProviders(providerOption);
16645
16792
  const provider = providers[0];
16646
16793
  const hooks = createHooks();
@@ -17290,6 +17437,7 @@ function createAgent(rawOptions) {
17290
17437
  ...modelOptions ? { modelOptions } : {},
17291
17438
  ...resolvedAutoCompact ? { autoCompact: resolvedAutoCompact } : {},
17292
17439
  ...session ? { session } : {},
17440
+ ...artifactsOption === false ? { artifactsDisabled: true } : {},
17293
17441
  ...agentReadState ? { readState: agentReadState } : {},
17294
17442
  toolState: toolStateController,
17295
17443
  ...options.parentRunId ? { parentRunId: options.parentRunId } : {},
@@ -17819,4 +17967,4 @@ function createAgent(rawOptions) {
17819
17967
  //#endregion
17820
17968
  export { installExtensionFromSpec as $, normalizeShellCommand as $n, KEYBINDING_DEF_BY_ACTION as $t, selectFilesFromSession as A, resolveExtensionConfig as An, createSkillsRunScriptTool as At, buildUpToCompactPrompt as B, commitKind as Bn, formatModelLine as Bt, resolveLegacySessionDir as C, createDebugLog as Cn, WAIT_TASK_TIMED_OUT_PREFIX as Ct, resolveTasksDir as D, coerceExtensionConfigInput as Dn, isSpawnTool as Dt, resolveSessionDir as E, clampExtensionConfigNumber as En, createSpawnTool as Et, TRAILER as F, createExtensionBus as Fn, tailTruncate as Ft, summaryToTurn as G, resolveArtifactKind as Gn, glob as Gt, anchorPreviewFor as H, pullRequestKind as Hn, listFiles as Ht, buildCompactPrompt as I, serializedPayloadBytes as In, readFile$1 as It, CompactPromptTooLongError as J, OUTPUT_RESERVE_TOKENS as Jn, artifacts_default as Jt, truncateHeadForPtlRetry as K, createArtifactDetectHook as Kn, edit as Kt, buildFromCompactPrompt as L, BUILTIN_ARTIFACT_KINDS as Ln, looksBinary as Lt, compactConversation as M, sanitizeExtensionConfigActionPatch as Mn, shellKill as Mt, BASE_INSTRUCTIONS as N, toWireConfigSchema as Nn, createShellTool as Nt, buildPostCompactAttachments as O, isValidExtensionConfigItem as On, reserveChildLabel as Ot, NO_TOOLS_PREAMBLE as P, EXTENSION_BUS_MAX_PAYLOAD_BYTES as Pn, shell as Pt, fetchExtensionSource as Q, defaultRepeatGuardTracked as Qn, KEYBINDING_DEFS as Qt, buildFullCompactPrompt as R, artifactKindLabel as Rn, multiEdit as Rt, resolveLegacyPersistDir as S, scanExtensionDirectories as Sn, writeFile$1 as St, resolvePersistDir as T, defineExtension as Tn, createToolSearchTool as Tt, sliceForCompaction as U, refreshArtifact as Un, createInteractionTool as Ut, ANCHOR_PREVIEW_MAX_CHARS as V, fileKind as Vn, matchModelEntries as Vt, stripImagesFromTurns as W, renderArtifactRow as Wn, grep as Wt, createExtensionPromptBridge as X, shouldAutoCompact as Xn, recordArtifact as Xt, EMPTY_EXTENSION_REGISTRY as Y, effectiveContextWindow as Yn, RECORD_ARTIFACT_TOOL as Yt, ExtensionInstallError as Z, defaultRepeatGuardNormalize as Zn, DEFAULT_KEYBINDINGS as Zt, buildPersistedStub as _, defaultExtensionScanPaths as _n, createWorkspaceSurface as _t, stagedToolState as a, matchesBinding as an, readStateKey as ar, createExtensionHud as at, migrateSessionArtifactDirs as b, isExtensionDefinition as bn, basicTools as bt, INTERRUPT_MESSAGE_FOR_TOOL_USE as c, readKeybindings as cn, buildExtensionRegistry as ct, TOOL_USE_SKIPPED_MESSAGE as d, stripJsonComments as dn, filterExtensionRegistry as dt, KEYBINDING_KEY_COL_WIDTH as en, stableStringify as er, listExtensionCandidates as et, applyCompactSummaryCutoff as f, ALTERNATE_CRED_KEY_SUFFIX as fn, filterRegistryPlugins as ft, PERSISTENCE_PREVIEW_BYTES as g, ENTRY_CANDIDATES as gn, createExtensionHostRuntimeBridge as gt, PERSISTED_STUB_PREFIX as h, registerExtensionHostModules as hn, createArtifactsSurface as ht, isToolStateOps as i, keybindingsPath as in, hydrateReadStateFromSessionAsync as ir, updateInstalledExtension as it, selectRecentFiles as j, resolveExtensionConfigValue as jn, createSkillsReadTool as jt, selectFilesFromReadState as k, isValidExtensionConfigValue as kn, createSkillsUseTool as kt, SHELL_CASCADE_CANCEL_MESSAGE as l, readKeybindingsRaw as ln, composeExtensionPreset as lt, renderStaleReadNotice as m, isReservedCredKey as mn, partitionExtensionCatalog as mt, DEFAULT_MAX_VALUE_BYTES as n, formatBindingForDisplay as nn, hashContent as nr, readExtensionInstallProvenance as nt, normalizeProviders as o, mergeKeybindings as on, resolveReadStateMap as or, discoverAndBuildExtensionRegistry as ot, collectNewlyStaleReadPaths as p, alternateCredKey as pn, mergeContributions as pt, CompactInvalidInputError as q, AUTO_COMPACT_MIN_GROWTH_FRACTION as qn, validateToolArgs as qt, createToolStateController as r, groupBindings as rn, hydrateReadStateFromSession as rr, removeInstalledExtension as rt, resolveModelTargets as s, parseBindingSpec as sn, buildExtensionPreset as st, createAgent as t, ensureKeybindingsFile as tn, getReadState as tr, parseExtensionInstallSource as tt, TOOL_USE_CANCELLED_MESSAGE as u, resolveExtensionKeybindings as un, disposeExtensionRegistry as ut, cleanupPersistedSession as v, discoverExtensions as vn, composePresets as vt, resolveMcpWarningsDir as w, setDebugLogSink as wn, waitTask as wt, rehomePersistedStubs as x, parseExtensionScanPathEnv as xn, basic_default as xt, maybePersistToolResult as y, inlineLoadedExtension as yn, definePreset as yt, buildTailCompactPrompt as z, branchKind as zn, createModelSearchTool as zt };
17821
17969
 
17822
- //# sourceMappingURL=agent-B_uQo4f1.js.map
17970
+ //# sourceMappingURL=agent-C5xr7lqh.js.map