zidane 6.5.0 → 6.5.1

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 (75) hide show
  1. package/dist/acp-cli.js +6 -6
  2. package/dist/{acp-B-AOovHz.js → acp-o-LQAjFw.js} +4 -5
  3. package/dist/{acp-B-AOovHz.js.map → acp-o-LQAjFw.js.map} +1 -1
  4. package/dist/acp.js +1 -1
  5. package/dist/{agent-SQ6rxfpT.js → agent-BVNkC1h4.js} +658 -10
  6. package/dist/agent-BVNkC1h4.js.map +1 -0
  7. package/dist/agent.js +1 -2
  8. package/dist/{anthropic-D3lkw5mv.js → anthropic-Dov2mC5e.js} +3 -3
  9. package/dist/{anthropic-D3lkw5mv.js.map → anthropic-Dov2mC5e.js.map} +1 -1
  10. package/dist/{auth-BzYbbdN_.js → auth-B8ZuBcKC.js} +5 -5
  11. package/dist/{auth-BzYbbdN_.js.map → auth-B8ZuBcKC.js.map} +1 -1
  12. package/dist/chat/pure.js +2 -2
  13. package/dist/chat.js +5 -5
  14. package/dist/{edit-utils-EGosADZq.js → context-breakdown-BLF10tOO.js} +154 -2
  15. package/dist/context-breakdown-BLF10tOO.js.map +1 -0
  16. package/dist/{context-transport-CDBatvQc.js → context-transport-D-daWOmp.js} +3 -3
  17. package/dist/{context-transport-CDBatvQc.js.map → context-transport-D-daWOmp.js.map} +1 -1
  18. package/dist/eval.js +1 -1
  19. package/dist/extensions.js +1 -1
  20. package/dist/headless.js +3 -3
  21. package/dist/index-CWBSrqI6.d.ts.map +1 -1
  22. package/dist/index.js +9 -10
  23. package/dist/index.js.map +1 -1
  24. package/dist/{login-XZDS4K2o.js → login-CR3fDHXh.js} +2 -2
  25. package/dist/{login-XZDS4K2o.js.map → login-CR3fDHXh.js.map} +1 -1
  26. package/dist/{mcp-D27rP47I.js → mcp-C6IkXNOS.js} +3 -3
  27. package/dist/{mcp-D27rP47I.js.map → mcp-C6IkXNOS.js.map} +1 -1
  28. package/dist/mcp.js +1 -1
  29. package/dist/{messages-C01kKGj0.js → messages-C_H9soi5.js} +2 -3
  30. package/dist/{messages-C01kKGj0.js.map → messages-C_H9soi5.js.map} +1 -1
  31. package/dist/{openai-compat-B3c_hzwf.js → openai-compat-CnHeo4Lz.js} +216 -3
  32. package/dist/openai-compat-CnHeo4Lz.js.map +1 -0
  33. package/dist/presets.js +1 -1
  34. package/dist/providers/anthropic.js +1 -1
  35. package/dist/providers/arcee.js +1 -1
  36. package/dist/providers/baseten.js +1 -1
  37. package/dist/providers/cerebras.js +1 -1
  38. package/dist/providers/local.js +1 -1
  39. package/dist/providers/openai-compat.js +1 -1
  40. package/dist/providers/openai.js +2 -2
  41. package/dist/providers/openrouter.js +1 -1
  42. package/dist/providers/xai.js +1 -1
  43. package/dist/{providers-z1vU0b2Q.js → providers-B6mFe7OD.js} +3 -3
  44. package/dist/{providers-z1vU0b2Q.js.map → providers-B6mFe7OD.js.map} +1 -1
  45. package/dist/providers.js +4 -4
  46. package/dist/restate.d.ts +178 -2
  47. package/dist/restate.d.ts.map +1 -1
  48. package/dist/restate.js +458 -4
  49. package/dist/restate.js.map +1 -1
  50. package/dist/{session-cr9VdoEO.js → session-VpLrNaFQ.js} +2 -2
  51. package/dist/{session-cr9VdoEO.js.map → session-VpLrNaFQ.js.map} +1 -1
  52. package/dist/session.js +2 -2
  53. package/dist/{stdio-O-m9WVkE.js → stdio-DzUUkkhS.js} +2 -2
  54. package/dist/{stdio-O-m9WVkE.js.map → stdio-DzUUkkhS.js.map} +1 -1
  55. package/dist/{stdio-loader-BSGQmG4L.js → stdio-loader-BILyUGmi.js} +2 -2
  56. package/dist/{stdio-loader-BSGQmG4L.js.map → stdio-loader-BILyUGmi.js.map} +1 -1
  57. package/dist/tools.js +1 -2
  58. package/dist/{transcript-anchors-D4IxJifV.js → transcript-anchors-DEIr0tJC.js} +5 -5
  59. package/dist/{transcript-anchors-D4IxJifV.js.map → transcript-anchors-DEIr0tJC.js.map} +1 -1
  60. package/dist/tui.js +8 -8
  61. package/dist/{turn-operations-CAvi8NYt.js → turn-operations-C3IijXMW.js} +2 -2
  62. package/dist/{turn-operations-CAvi8NYt.js.map → turn-operations-C3IijXMW.js.map} +1 -1
  63. package/dist/{xai-BPwMQSuF.js → xai-Du6Wfnlb.js} +2 -2
  64. package/dist/{xai-BPwMQSuF.js.map → xai-Du6Wfnlb.js.map} +1 -1
  65. package/docs/RESTATE.md +102 -3
  66. package/package.json +1 -1
  67. package/dist/agent-SQ6rxfpT.js.map +0 -1
  68. package/dist/aliasing-lVFbm81n.js +0 -217
  69. package/dist/aliasing-lVFbm81n.js.map +0 -1
  70. package/dist/context-breakdown-Dzo25N45.js +0 -155
  71. package/dist/context-breakdown-Dzo25N45.js.map +0 -1
  72. package/dist/edit-utils-EGosADZq.js.map +0 -1
  73. package/dist/openai-compat-B3c_hzwf.js.map +0 -1
  74. package/dist/tool-state-DTs-3ZHH.js +0 -653
  75. package/dist/tool-state-DTs-3ZHH.js.map +0 -1
@@ -1,9 +1,7 @@
1
- import { a as rewriteMessagesToWire, i as rewriteContentToCanonical, n as buildAliasMaps, o as toCanonicalName, r as buildSanitizedWireAliases, s as toWireName, t as augmentMcpDoubleUnderscoreAliases } from "./aliasing-lVFbm81n.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, z as rewriteContentToCanonical } from "./openai-compat-CnHeo4Lz.js";
2
2
  import { a as isWireTurn, c as toolOutputByteLength, i as documentBlockMarker, l as toolResultToText, o as sanitizeToolResultMetadata, s as toolOutputBudgetByteLength, t as DEFAULT_AGENT_CLOCK } from "./types-BIarq1qE.js";
3
- import { i as styleReplacementForVia, n as resolveOldString, r as stripLineNumberPrefixes, t as describeVia } from "./edit-utils-EGosADZq.js";
4
- import { a as getReadState, d as noteStaleRejection, f as readStateKey, l as hydrateReadStateFromSessionAsync, m as staleRefusalHint, n as createToolStateController, o as getToolDedupState, p as resolveReadStateMap, s as hashContent, u as markReadStateElided } from "./tool-state-DTs-3ZHH.js";
3
+ import { a as styleReplacementForVia, i as stripLineNumberPrefixes, n as describeVia, r as resolveOldString, t as buildContextBreakdown } from "./context-breakdown-BLF10tOO.js";
5
4
  import { n as estimateTokens, r as utf8ByteLength } from "./utils-ngQzYzZD.js";
6
- import { t as buildContextBreakdown } from "./context-breakdown-Dzo25N45.js";
7
5
  import { a as formatDuration, c as previewLine, o as formatTaskStatus, s as formatTaskSummary } from "./format-BF745pLL.js";
8
6
  import { i as parseGitLsFiles, r as GIT_LS_FILES_COMMAND } from "./glob-DluQFSw1.js";
9
7
  import { i as isOutputExceededMessage } from "./output-cap-C9zukcCj.js";
@@ -15,11 +13,10 @@ import { n as writeFileAtomicAsync, t as writeFileAtomic } from "./atomic-write-
15
13
  import { p as resolveStorageDirs, r as loadAgentPlugin } from "./plugins-2PMTVcp-.js";
16
14
  import { r as createLogger, t as consoleSink } from "./logger-DBX9uYOw.js";
17
15
  import { n as reconcileImageMediaType } from "./media-sniff-UKijEaiQ.js";
18
- import { f as wrapDiscoveredMcpTools, i as deriveMcpToolMeta, n as connectMcpServers, s as nonOwningMcpView } from "./mcp-D27rP47I.js";
19
- import { M as buildPromptMessage, N as canonicalizePrompt } from "./openai-compat-B3c_hzwf.js";
16
+ import { f as wrapDiscoveredMcpTools, i as deriveMcpToolMeta, n as connectMcpServers, s as nonOwningMcpView } from "./mcp-C6IkXNOS.js";
20
17
  import { appendStaticSection, renderSystemForWire } from "./prompt.js";
21
- 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-C01kKGj0.js";
22
- import { a as getExtensionSessionState, c as setExtensionSessionState, l as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as resumeChainRunIds } from "./session-cr9VdoEO.js";
18
+ 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-C_H9soi5.js";
19
+ import { a as getExtensionSessionState, c as setExtensionSessionState, l as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as resumeChainRunIds } from "./session-VpLrNaFQ.js";
23
20
  import { n as flattenTurns, r as formatTokenUsage, t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
24
21
  import { a as withInactivityTimeout, i as settleWithinTimeout, n as linkAbortSignal, o as withTimeout$1, r as resolveTimeoutMs, t as OperationTimeoutError } from "./timeout-BDetbuN6.js";
25
22
  import { createRequire } from "node:module";
@@ -31,6 +28,436 @@ import { copyFile, mkdir, readdir, rm, stat, unlink } from "node:fs/promises";
31
28
  import { pathToFileURL } from "node:url";
32
29
  import { homedir, tmpdir } from "node:os";
33
30
  import { createHash } from "node:crypto";
31
+ //#region src/tools/read-state.ts
32
+ const STATE = /* @__PURE__ */ new WeakMap();
33
+ /**
34
+ * Get or lazily create the per-session read-state map. Returns `undefined`
35
+ * when no session is provided.
36
+ *
37
+ * Most tool callers should prefer {@link resolveReadStateMap}, which
38
+ * additionally honors an explicit `ctx.readState` (the path
39
+ * `spawn`'s `shareReadState: true` uses to forward the parent's map
40
+ * into a sessionless child). Use this helper directly only when the
41
+ * Session-keyed map is exactly what you want and you don't need to
42
+ * accept an override.
43
+ */
44
+ function getReadState(session) {
45
+ if (!session) return void 0;
46
+ let map = STATE.get(session);
47
+ if (!map) {
48
+ map = /* @__PURE__ */ new Map();
49
+ STATE.set(session, map);
50
+ }
51
+ return map;
52
+ }
53
+ /**
54
+ * Resolve the active read-state map from a tool context. An explicit
55
+ * `ctx.readState` wins (used by `spawn`'s `shareReadState` opt-in to
56
+ * forward the parent's map into a sessionless child); otherwise the
57
+ * usual `Session`-keyed lookup applies.
58
+ *
59
+ * Tools should call this helper instead of `getReadState(ctx.session)`
60
+ * directly so the `shareReadState` plumbing is honored uniformly.
61
+ */
62
+ function resolveReadStateMap(ctx) {
63
+ return ctx.readState ?? getReadState(ctx.session);
64
+ }
65
+ /**
66
+ * Mark a read-state entry as elided from the on-wire history WITHOUT
67
+ * un-registering it.
68
+ *
69
+ * Used by the loop's `elideStaleReads` pass. The entry must survive —
70
+ * deleting it made the `requireReadBeforeEdit` gate reject the very next
71
+ * edit on a file the model had demonstrably read and just edited (the
72
+ * gate's failure mode then defeats the gate: models degrade to raw shell
73
+ * edits that bypass the guard entirely). The `elided` flag instead
74
+ * defeats only the dedup stub: the next identical re-read returns the
75
+ * full body again, and `rememberRead` clears the flag.
76
+ *
77
+ * No-op when the path has no entry in the resolved map(s).
78
+ */
79
+ function markReadStateElided(ctx, cwd, path) {
80
+ const key = readStateKey(cwd, path);
81
+ for (const map of [ctx.readState, ctx.session ? STATE.get(ctx.session) : void 0]) {
82
+ const entry = map?.get(key);
83
+ if (entry && entry.elided !== true) map.set(key, {
84
+ ...entry,
85
+ elided: true
86
+ });
87
+ }
88
+ }
89
+ /**
90
+ * Record one `requireReadBeforeEdit` drift refusal against `entry` and
91
+ * return the consecutive count (1 for the first). The caller composes the
92
+ * refusal message with {@link staleRefusalHint}.
93
+ */
94
+ function noteStaleRejection(map, key, entry) {
95
+ const count = (entry.staleRejections ?? 0) + 1;
96
+ map.set(key, {
97
+ ...entry,
98
+ staleRejections: count
99
+ });
100
+ return count;
101
+ }
102
+ /**
103
+ * Escalating suffix for a drift refusal. Empty on the first refusal — the
104
+ * base "re-read the file" advice is correct and sufficient. From the second
105
+ * consecutive refusal on, the model has demonstrably re-read and been
106
+ * refused again, so repeating the same advice reads as a broken tool;
107
+ * name the real hypothesis (an external writer) instead.
108
+ */
109
+ function staleRefusalHint(count) {
110
+ if (count < 2) return "";
111
+ return ` This is refusal #${count} since your last read — a process outside this session (editor auto-save, formatter, codegen watcher) may be rewriting the file between your reads.`;
112
+ }
113
+ /**
114
+ * Canonical read-state key for a `(cwd, path)` pair.
115
+ *
116
+ * `ctx.execution.readFile(handle, path)` resolves the model-provided
117
+ * path against `handle.cwd` before touching disk — so `src/App.tsx`,
118
+ * `./src/App.tsx`, and `/abs/cwd/src/App.tsx` all read the **same**
119
+ * bytes. The read-state map MUST mirror that resolution: without it,
120
+ * a model that reads `src/App.tsx` and then edits `./src/App.tsx`
121
+ * trips the `requireReadBeforeEdit` gate for a file it demonstrably
122
+ * already saw (the gate's "has not been read in this session" message
123
+ * fires on a stale key).
124
+ *
125
+ * `node:path`'s `resolve(cwd, path)` short-circuits when `path` is
126
+ * already absolute, so absolute and relative shapes converge on the
127
+ * same canonical form. We don't `realpath()` symlinks — the file IS
128
+ * the path the model addressed, not the realpath behind it; the host's
129
+ * execution context decides how to dereference.
130
+ */
131
+ function readStateKey(cwd, path) {
132
+ return resolve(cwd, path);
133
+ }
134
+ /**
135
+ * 64-bit content hash: two independent 32-bit FNV-1a-style lanes (different
136
+ * offset bases + multipliers) concatenated as 16 hex chars. Fast,
137
+ * non-cryptographic — but wide enough that the `requireReadBeforeEdit`
138
+ * drift gate, which silently corrupts a file on a false "unchanged"
139
+ * verdict, isn't betting on a 32-bit birthday bound (~1 in 4 billion per
140
+ * pair; uncomfortably reachable over many files × many sessions). Entries
141
+ * live only in per-session in-memory maps, so widening needs no
142
+ * stored-format migration. Still cheaper than allocating a Buffer and
143
+ * pulling in `crypto`.
144
+ */
145
+ function hashContent(text) {
146
+ let h1 = 2166136261;
147
+ let h2 = 2128831031;
148
+ for (let i = 0; i < text.length; i++) {
149
+ const c = text.charCodeAt(i);
150
+ h1 = Math.imul(h1 ^ c, 16777619) >>> 0;
151
+ h2 = Math.imul(h2 ^ c, 2246822507) >>> 0;
152
+ }
153
+ return h1.toString(16).padStart(8, "0") + h2.toString(16).padStart(8, "0");
154
+ }
155
+ const READ_FILE_DEFAULT_OFFSET = 1;
156
+ const READ_FILE_DEFAULT_LIMIT = 2e3;
157
+ const READ_FILE_DEFAULT_MAX_BYTES = 262144;
158
+ const READ_FILE_FOOTER_RE = /\n\n…(?:read lines|truncated)/;
159
+ const READ_FILE_LINE_RE = /^\d{1,9}\t(.*)$/;
160
+ /**
161
+ * Rebuild the per-session read-state map from durable session turns.
162
+ *
163
+ * Durable replay runtimes may return recorded tool results without re-running
164
+ * the tool body, so in-memory side effects like `readState.set(...)` can be
165
+ * missing even though the transcript contains the successful `read_file`.
166
+ * This helper is intentionally opt-in: live hosts keep the normal side-effect
167
+ * behavior unless they call it themselves.
168
+ *
169
+ * Hydration only fills missing keys. Live in-memory state may already reflect a
170
+ * newer read or edit from the current run, and durable history cannot prove it
171
+ * is fresher. Relative paths are resolved against the current execution cwd,
172
+ * matching replay hosts that run sessions from a stable workspace.
173
+ */
174
+ function hydrateReadStateFromSession(session, cwd, options = {}) {
175
+ if (!session) return 0;
176
+ const readState = getReadState(session);
177
+ if (!readState) return 0;
178
+ const normalized = normalizeHydrateReadStateOptions(options);
179
+ const pending = /* @__PURE__ */ new Map();
180
+ const known = /* @__PURE__ */ new Map();
181
+ const preexistingKeys = new Set(readState.keys());
182
+ let hydrated = 0;
183
+ for (const turn of session.turns) for (const block of turn.content) {
184
+ if (block.type === "tool_call") {
185
+ const canonicalName = canonicalToolCallName(block.name, normalized);
186
+ if (canonicalName === normalized.readFileToolName || canonicalName === normalized.writeFileToolName || canonicalName === normalized.editToolName || canonicalName === normalized.multiEditToolName) pending.set(block.id, {
187
+ name: canonicalName,
188
+ input: block.input
189
+ });
190
+ continue;
191
+ }
192
+ if (block.type !== "tool_result") continue;
193
+ const call = pending.get(block.callId);
194
+ if (!call) continue;
195
+ pending.delete(block.callId);
196
+ if (block.isError === true) continue;
197
+ const next = stateFromToolResult(call, toolResultToText(block.output), turn, cwd, normalized, known);
198
+ if (!next) continue;
199
+ if (!preexistingKeys.has(next.key)) {
200
+ readState.set(next.key, next.file.entry);
201
+ hydrated += 1;
202
+ }
203
+ known.set(next.key, next.file);
204
+ }
205
+ return hydrated;
206
+ }
207
+ /**
208
+ * Async replay hydrator for durable hosts that can cheaply read the current
209
+ * full file through their execution context. Transcript-only reconstruction is
210
+ * still preferred for full reads; partial/truncated read_file entries fall back
211
+ * to `readFileForHash` and hash those full current bytes.
212
+ */
213
+ async function hydrateReadStateFromSessionAsync(session, cwd, options = {}) {
214
+ if (!session) return 0;
215
+ const readState = getReadState(session);
216
+ if (!readState) return 0;
217
+ const normalized = normalizeHydrateReadStateOptions(options);
218
+ const pending = /* @__PURE__ */ new Map();
219
+ const known = /* @__PURE__ */ new Map();
220
+ const preexistingKeys = new Set(readState.keys());
221
+ let hydrated = 0;
222
+ for (const turn of session.turns) for (const block of turn.content) {
223
+ if (block.type === "tool_call") {
224
+ const canonicalName = canonicalToolCallName(block.name, normalized);
225
+ if (canonicalName === normalized.readFileToolName || canonicalName === normalized.writeFileToolName || canonicalName === normalized.editToolName || canonicalName === normalized.multiEditToolName) pending.set(block.id, {
226
+ name: canonicalName,
227
+ input: block.input
228
+ });
229
+ continue;
230
+ }
231
+ if (block.type !== "tool_result") continue;
232
+ const call = pending.get(block.callId);
233
+ if (!call) continue;
234
+ pending.delete(block.callId);
235
+ if (block.isError === true) continue;
236
+ const next = await stateFromToolResultAsync(call, toolResultToText(block.output), turn, cwd, normalized, known);
237
+ if (!next) continue;
238
+ if (!preexistingKeys.has(next.key)) {
239
+ readState.set(next.key, next.file.entry);
240
+ hydrated += 1;
241
+ }
242
+ known.set(next.key, next.file);
243
+ }
244
+ return hydrated;
245
+ }
246
+ function normalizeHydrateReadStateOptions(options) {
247
+ return {
248
+ readFileToolName: options.readFileToolName ?? "read_file",
249
+ writeFileToolName: options.writeFileToolName ?? "write_file",
250
+ editToolName: options.editToolName ?? "edit",
251
+ multiEditToolName: options.multiEditToolName ?? "multi_edit",
252
+ defaultLineNumbers: options.defaultLineNumbers ?? true,
253
+ ...options.readFileForHash ? { readFileForHash: options.readFileForHash } : {},
254
+ ...options.aliasMaps ? { aliasMaps: options.aliasMaps } : {}
255
+ };
256
+ }
257
+ /**
258
+ * Resolve a transcript tool-call name to its canonical form for matching.
259
+ * Honors `aliasMaps` (wire → canonical) when present; otherwise the name is
260
+ * already canonical (zidane persists canonical names) and passes through.
261
+ */
262
+ function canonicalToolCallName(name, options) {
263
+ return options.aliasMaps ? toCanonicalName(name, options.aliasMaps) : name;
264
+ }
265
+ function stateFromToolResult(call, output, resultTurn, cwd, options, known) {
266
+ if (call.name === options.readFileToolName) return readFileStateFromResult(call.input, output, resultTurn, cwd, options.defaultLineNumbers);
267
+ if (call.name === options.writeFileToolName) return writeFileStateFromResult(call.input, output, resultTurn, cwd);
268
+ if (call.name === options.editToolName) return editStateFromResult(call.input, output, resultTurn, cwd, known);
269
+ if (call.name === options.multiEditToolName) return multiEditStateFromResult(call.input, output, resultTurn, cwd, known);
270
+ }
271
+ async function stateFromToolResultAsync(call, output, resultTurn, cwd, options, known) {
272
+ if (call.name === options.readFileToolName) return await readFileStateFromResultAsync(call.input, output, resultTurn, cwd, {
273
+ defaultLineNumbers: options.defaultLineNumbers,
274
+ readFileForHash: options.readFileForHash
275
+ });
276
+ return stateFromToolResult(call, output, resultTurn, cwd, options, known);
277
+ }
278
+ function readFileStateFromResult(input, output, resultTurn, cwd, defaultLineNumbers) {
279
+ const path = typeof input.path === "string" ? input.path : void 0;
280
+ if (!path || !isSuccessfulFullReadOutput(output)) return void 0;
281
+ const lineNumbers = typeof input.lineNumbers === "boolean" ? input.lineNumbers : defaultLineNumbers;
282
+ const content = lineNumbers ? stripReadFileLineNumbers(output) : output;
283
+ if (content === void 0) return void 0;
284
+ const entry = {
285
+ contentHash: hashContent(content),
286
+ offset: normalizeReadInteger(input.offset, READ_FILE_DEFAULT_OFFSET),
287
+ limit: normalizeReadInteger(input.limit, READ_FILE_DEFAULT_LIMIT),
288
+ maxBytes: normalizeReadInteger(input.maxBytes, READ_FILE_DEFAULT_MAX_BYTES),
289
+ lineNumbers,
290
+ mtimeMs: resultTurn.createdAt
291
+ };
292
+ return {
293
+ key: readStateKey(cwd, path),
294
+ file: {
295
+ content,
296
+ entry
297
+ }
298
+ };
299
+ }
300
+ async function readFileStateFromResultAsync(input, output, resultTurn, cwd, options) {
301
+ const reconstructed = readFileStateFromResult(input, output, resultTurn, cwd, options.defaultLineNumbers);
302
+ if (reconstructed) return reconstructed;
303
+ const path = typeof input.path === "string" ? input.path : void 0;
304
+ if (!path || !options.readFileForHash || !isSuccessfulReadOutput(output)) return void 0;
305
+ let content;
306
+ try {
307
+ content = await options.readFileForHash(path);
308
+ } catch {
309
+ return;
310
+ }
311
+ if (typeof content !== "string") return void 0;
312
+ const lineNumbers = typeof input.lineNumbers === "boolean" ? input.lineNumbers : options.defaultLineNumbers;
313
+ const entry = {
314
+ contentHash: hashContent(content),
315
+ offset: normalizeReadInteger(input.offset, READ_FILE_DEFAULT_OFFSET),
316
+ limit: normalizeReadInteger(input.limit, READ_FILE_DEFAULT_LIMIT),
317
+ maxBytes: normalizeReadInteger(input.maxBytes, READ_FILE_DEFAULT_MAX_BYTES),
318
+ lineNumbers,
319
+ mtimeMs: resultTurn.createdAt
320
+ };
321
+ return {
322
+ key: readStateKey(cwd, path),
323
+ file: {
324
+ content,
325
+ entry
326
+ }
327
+ };
328
+ }
329
+ function writeFileStateFromResult(input, output, resultTurn, cwd) {
330
+ const path = typeof input.path === "string" ? input.path : void 0;
331
+ const content = typeof input.content === "string" ? input.content : void 0;
332
+ if (!path || content === void 0) return void 0;
333
+ if (!output.startsWith(`Created ${path} (`) && !output.startsWith(`Updated ${path} (`)) return void 0;
334
+ return {
335
+ key: readStateKey(cwd, path),
336
+ file: {
337
+ content,
338
+ entry: {
339
+ contentHash: hashContent(content),
340
+ offset: 0,
341
+ limit: Number.POSITIVE_INFINITY,
342
+ maxBytes: Number.POSITIVE_INFINITY,
343
+ mtimeMs: resultTurn.createdAt,
344
+ elided: true
345
+ }
346
+ }
347
+ };
348
+ }
349
+ function editStateFromResult(input, output, resultTurn, cwd, known) {
350
+ const path = typeof input.path === "string" ? input.path : void 0;
351
+ const oldString = typeof input.old_string === "string" ? input.old_string : void 0;
352
+ const newString = typeof input.new_string === "string" ? input.new_string : void 0;
353
+ if (!path || oldString === void 0 || newString === void 0) return void 0;
354
+ if (!output.startsWith(`Edited ${path}: replaced `)) return void 0;
355
+ const key = readStateKey(cwd, path);
356
+ const prior = known.get(key);
357
+ if (!prior) return void 0;
358
+ const nextContent = applyEdit(prior.content, oldString, newString, input.replace_all === true);
359
+ if (nextContent === void 0) return void 0;
360
+ return {
361
+ key,
362
+ file: {
363
+ content: nextContent,
364
+ entry: {
365
+ ...prior.entry,
366
+ contentHash: hashContent(nextContent),
367
+ mtimeMs: resultTurn.createdAt,
368
+ elided: true
369
+ }
370
+ }
371
+ };
372
+ }
373
+ function multiEditStateFromResult(input, output, resultTurn, cwd, known) {
374
+ const path = typeof input.path === "string" ? input.path : void 0;
375
+ const edits = Array.isArray(input.edits) ? input.edits : void 0;
376
+ if (!path || !edits) return void 0;
377
+ if (!output.startsWith(`Edited ${path}: applied `)) return void 0;
378
+ const key = readStateKey(cwd, path);
379
+ const prior = known.get(key);
380
+ if (!prior) return void 0;
381
+ const applied = parseMultiEditAppliedSteps(output, edits.length);
382
+ let current = prior.content;
383
+ for (let i = 0; i < edits.length; i++) {
384
+ if (!applied.has(i)) continue;
385
+ const step = edits[i];
386
+ if (typeof step.old_string !== "string" || typeof step.new_string !== "string") return void 0;
387
+ const next = applyEdit(current, step.old_string, step.new_string, step.replace_all === true);
388
+ if (next === void 0) return void 0;
389
+ current = next;
390
+ }
391
+ return {
392
+ key,
393
+ file: {
394
+ content: current,
395
+ entry: {
396
+ ...prior.entry,
397
+ contentHash: hashContent(current),
398
+ mtimeMs: resultTurn.createdAt,
399
+ elided: true
400
+ }
401
+ }
402
+ };
403
+ }
404
+ function applyEdit(content, oldString, newString, replaceAll) {
405
+ const match = resolveOldString(content, oldString);
406
+ if (!match) return void 0;
407
+ if (match.occurrences > 1 && !replaceAll) return void 0;
408
+ const styledReplacement = styleReplacementForVia(newString, match.via, match.actual);
409
+ return replaceAll ? content.split(match.actual).join(styledReplacement) : content.replace(match.actual, styledReplacement);
410
+ }
411
+ function parseMultiEditAppliedSteps(output, editCount) {
412
+ const annotationMatch = /<edit-outcomes>\n([\s\S]*?)\n<\/edit-outcomes>/.exec(output);
413
+ if (!annotationMatch) return new Set(Array.from({ length: editCount }, (_, i) => i));
414
+ const applied = /* @__PURE__ */ new Set();
415
+ for (const line of annotationMatch[1].split("\n")) {
416
+ const match = /^#(\d+) applied$/.exec(line.trim());
417
+ if (!match) continue;
418
+ const index = Number(match[1]) - 1;
419
+ if (index >= 0 && index < editCount) applied.add(index);
420
+ }
421
+ return applied;
422
+ }
423
+ function isSuccessfulFullReadOutput(output) {
424
+ if (!isSuccessfulReadOutput(output) || READ_FILE_FOOTER_RE.test(output)) return false;
425
+ return true;
426
+ }
427
+ function isSuccessfulReadOutput(output) {
428
+ if (output.length === 0) return true;
429
+ if (output.startsWith("File not found:") || output.startsWith("[binary file:") || output.startsWith("Image:") || output.startsWith("Document:") || output.startsWith("[image too large to inline:") || output.startsWith("[document:") || output.startsWith("[document too large to attach:") || output.startsWith("Image read failed:") || output.startsWith("Document read failed:") || output.includes(" unchanged since the previous read in this session ")) return false;
430
+ return true;
431
+ }
432
+ function stripReadFileLineNumbers(output) {
433
+ const lines = output.split("\n");
434
+ const stripped = [];
435
+ for (const line of lines) {
436
+ const match = READ_FILE_LINE_RE.exec(line);
437
+ if (!match) return void 0;
438
+ stripped.push(match[1]);
439
+ }
440
+ return stripped.join("\n");
441
+ }
442
+ function normalizeReadInteger(value, fallback) {
443
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return fallback;
444
+ return Math.floor(value);
445
+ }
446
+ const TOOL_DEDUP_STATE = /* @__PURE__ */ new WeakMap();
447
+ /**
448
+ * Get or lazily create the per-session tool-dedup map. Returns `undefined`
449
+ * when no session is provided — middleware should treat that as "no dedup".
450
+ */
451
+ function getToolDedupState(session) {
452
+ if (!session) return void 0;
453
+ let map = TOOL_DEDUP_STATE.get(session);
454
+ if (!map) {
455
+ map = /* @__PURE__ */ new Map();
456
+ TOOL_DEDUP_STATE.set(session, map);
457
+ }
458
+ return map;
459
+ }
460
+ //#endregion
34
461
  //#region src/behaviors/dedup-tools.ts
35
462
  /**
36
463
  * Install the per-tool argument-dedup middleware on a hook bus.
@@ -5028,6 +5455,12 @@ function describeChildRuns(session) {
5028
5455
  if (childRuns.length === 0) return "No child runs exist in this session.";
5029
5456
  return childRuns.map((r, i) => `- ${r.label ?? `child-${i + 1}`} · ${r.status} · ${r.prompt.slice(0, 80)}`).join("\n");
5030
5457
  }
5458
+ /**
5459
+ * Reserve the next `child-N` label for this session. Exported so the durable
5460
+ * (child-as-invocation) spawn tool in `src/restate/spawn.ts` allocates labels
5461
+ * from the same session-anchored counter — otherwise the two tools would number
5462
+ * children independently and a session that used both would collide.
5463
+ */
5031
5464
  function reserveChildLabel(session) {
5032
5465
  let counter = sessionChildCounters.get(session);
5033
5466
  if (counter === void 0) {
@@ -13827,6 +14260,221 @@ function createToolCancelRegistry(options = {}) {
13827
14260
  };
13828
14261
  }
13829
14262
  //#endregion
14263
+ //#region src/tool-state.ts
14264
+ /**
14265
+ * Durable key/value state for tools.
14266
+ *
14267
+ * A tool reaches this through {@link ToolContext.state} — a plain,
14268
+ * SYNCHRONOUS map view. Synchronous is not a convenience choice: under a
14269
+ * durable-execution runtime the tool body runs inside a journaled action
14270
+ * (Restate's `ctx.run`), and a durable read (`ctx.get`) is illegal in
14271
+ * there. So the flow is split into three phases the runtime can journal
14272
+ * independently:
14273
+ *
14274
+ * 1. **hydrate** — load the snapshot ONCE per agent, outside any
14275
+ * journaled action, before the first tool dispatch.
14276
+ * 2. **stage** — the tool mutates its per-call view. Mutations are
14277
+ * recorded as an ordered {@link ToolStateOp} list, NOT written
14278
+ * through: they're plain data, so a durable adapter can journal them
14279
+ * alongside the tool result.
14280
+ * 3. **commit** — the loop applies the staged ops through
14281
+ * {@link ToolStateStore.commit} after the call settles, outside the
14282
+ * journaled action.
14283
+ *
14284
+ * The invariant that makes this replay-safe:
14285
+ *
14286
+ * > A staged mutation is committed only if it came back OUT of a journal
14287
+ * > entry.
14288
+ *
14289
+ * A durable adapter (see `restateTool`) reads {@link StagedToolState.pending}
14290
+ * from inside its journaled closure, ships the ops out as part of the
14291
+ * journaled value, and calls {@link StagedToolState.restore} outside it. On
14292
+ * replay the tool body never runs, so nothing is staged live — `restore`
14293
+ * re-seeds the exact same ops from the journal and the commit re-issues an
14294
+ * identical write. Paths that produced no journal entry (a fatal error, a
14295
+ * control abort, a dead attempt) call {@link StagedToolState.clear} so live
14296
+ * mutations from an attempt nobody recorded can never reach the store.
14297
+ *
14298
+ * The store seam is deliberately runtime-agnostic: `zidane/restate` ships
14299
+ * `restateToolStateStore`, but a Redis / Postgres / file-backed
14300
+ * implementation is the same two methods. With no store configured the
14301
+ * controller is in-memory only — `ctx.state` still works everywhere
14302
+ * (local CLI, tests, subagents), it just doesn't outlive the process.
14303
+ */
14304
+ /**
14305
+ * Default per-value size budget: 64 KiB of JSON.
14306
+ *
14307
+ * Deliberately far below any backend's hard ceiling (Restate's journal-entry
14308
+ * limit is 32 MiB) because this is a design guard, not a protocol limit.
14309
+ * Durable tool state is for flags, ids, counters, and cursors; a value that
14310
+ * doesn't fit in 64 KiB is a payload, and payloads belong in the tool result
14311
+ * or in storage the tool owns. Raise it on the store if you disagree — but
14312
+ * know that everything here is rewritten on every commit.
14313
+ */
14314
+ const DEFAULT_MAX_VALUE_BYTES = 64 * 1024;
14315
+ /** Brand so {@link stagedToolState} can recognise views this module made. */
14316
+ const STAGED = Symbol("zidane.toolState.staged");
14317
+ /**
14318
+ * Resolve the staging handle behind a view. Returns `undefined` for a
14319
+ * missing view or a foreign implementation (a host that supplied its own
14320
+ * `ToolStateView`), which lets adapters degrade to "no durable staging"
14321
+ * instead of throwing.
14322
+ */
14323
+ function stagedToolState(view) {
14324
+ if (!view) return void 0;
14325
+ return view[STAGED] ?? void 0;
14326
+ }
14327
+ function createToolStateController(store) {
14328
+ const snapshot = /* @__PURE__ */ new Map();
14329
+ const views = /* @__PURE__ */ new Map();
14330
+ const maxValueBytes = store?.maxValueBytes ?? 65536;
14331
+ let hydrated;
14332
+ const hydrate = () => {
14333
+ if (hydrated) return hydrated;
14334
+ hydrated = (async () => {
14335
+ if (!store) return;
14336
+ const loaded = await store.load();
14337
+ for (const [key, value] of Object.entries(loaded ?? {})) if (!snapshot.has(key)) snapshot.set(key, value);
14338
+ })().catch((err) => {
14339
+ hydrated = void 0;
14340
+ throw err;
14341
+ });
14342
+ return hydrated;
14343
+ };
14344
+ const begin = (callId) => {
14345
+ const existing = views.get(callId);
14346
+ if (existing) return existing;
14347
+ const view = createStagingView(snapshot, maxValueBytes);
14348
+ views.set(callId, view);
14349
+ return view;
14350
+ };
14351
+ const commit = async (callId) => {
14352
+ const view = views.get(callId);
14353
+ if (!view) return;
14354
+ views.delete(callId);
14355
+ const ops = view[STAGED].pending();
14356
+ if (ops.length === 0) return;
14357
+ await store?.commit(ops);
14358
+ applyOps(snapshot, ops);
14359
+ };
14360
+ return {
14361
+ hydrate,
14362
+ begin,
14363
+ commit,
14364
+ discard: (callId) => {
14365
+ views.delete(callId);
14366
+ },
14367
+ pending: (callId) => views.get(callId)?.[STAGED].pending() ?? [],
14368
+ snapshot: () => Object.fromEntries(snapshot)
14369
+ };
14370
+ }
14371
+ /**
14372
+ * Build a view over `snapshot` that records writes instead of applying
14373
+ * them. Reads layer staged ops on top of the snapshot so a tool sees its
14374
+ * own writes back — including deletions, which read as absent.
14375
+ */
14376
+ function createStagingView(snapshot, maxValueBytes) {
14377
+ let ops = [];
14378
+ const latest = /* @__PURE__ */ new Map();
14379
+ const stage = (op) => {
14380
+ ops.push(op);
14381
+ latest.set(op.key, op);
14382
+ };
14383
+ const resolve = (key) => {
14384
+ const staged = latest.get(key);
14385
+ if (staged) return staged.delete === true ? { present: false } : {
14386
+ present: true,
14387
+ value: staged.value
14388
+ };
14389
+ return snapshot.has(key) ? {
14390
+ present: true,
14391
+ value: snapshot.get(key)
14392
+ } : { present: false };
14393
+ };
14394
+ const view = {
14395
+ get: (key) => {
14396
+ const resolved = resolve(key);
14397
+ return resolved.present ? resolved.value : void 0;
14398
+ },
14399
+ set: (key, value) => {
14400
+ assertStorable(key, value, maxValueBytes);
14401
+ if (value === void 0) stage({
14402
+ key,
14403
+ delete: true
14404
+ });
14405
+ else stage({
14406
+ key,
14407
+ value
14408
+ });
14409
+ },
14410
+ delete: (key) => {
14411
+ stage({
14412
+ key,
14413
+ delete: true
14414
+ });
14415
+ },
14416
+ has: (key) => resolve(key).present,
14417
+ keys: () => {
14418
+ const keys = new Set(snapshot.keys());
14419
+ for (const [key, op] of latest) if (op.delete === true) keys.delete(key);
14420
+ else keys.add(key);
14421
+ return [...keys].sort();
14422
+ },
14423
+ [STAGED]: {
14424
+ pending: () => [...ops],
14425
+ restore: (restored) => {
14426
+ ops = [...restored];
14427
+ latest.clear();
14428
+ for (const op of ops) latest.set(op.key, op);
14429
+ },
14430
+ clear: () => {
14431
+ ops = [];
14432
+ latest.clear();
14433
+ }
14434
+ }
14435
+ };
14436
+ Object.defineProperty(view, STAGED, {
14437
+ value: view[STAGED],
14438
+ enumerable: false
14439
+ });
14440
+ return view;
14441
+ }
14442
+ /**
14443
+ * Reject a value that can't survive the trip to the store, at the moment the
14444
+ * tool stages it.
14445
+ *
14446
+ * Scalars are skipped: they're bounded, and paying a `JSON.stringify` per
14447
+ * `set` on a hot tool would be a real cost for no signal. Strings and objects
14448
+ * are measured in UTF-8 bytes, which is what both the journal and the store
14449
+ * actually spend.
14450
+ */
14451
+ function assertStorable(key, value, maxValueBytes) {
14452
+ if (value === void 0 || value === null || typeof value === "boolean" || typeof value === "number") return;
14453
+ if (typeof value === "function" || typeof value === "symbol" || typeof value === "bigint") throw new TypeError(`tool state value for "${key}" is a ${typeof value}, which cannot cross a durable store — use a JSON-serializable value.`);
14454
+ let json;
14455
+ try {
14456
+ json = typeof value === "string" ? value : JSON.stringify(value) ?? "";
14457
+ } catch (err) {
14458
+ throw new TypeError(`tool state value for "${key}" is not JSON-serializable (${err instanceof Error ? err.message : String(err)}) — durable tool state crosses a journal, so cycles and exotic values can't be stored.`);
14459
+ }
14460
+ const bytes = Buffer.byteLength(json, "utf8");
14461
+ if (bytes > maxValueBytes) throw new RangeError(`tool state value for "${key}" is ${formatBytes(bytes)}, over the ${formatBytes(maxValueBytes)} limit. Durable tool state is for flags, ids, counters, and cursors — it is rewritten on every commit and crosses a journal entry. Keep the payload in the tool result or in storage the tool owns, and store a reference here.`);
14462
+ }
14463
+ function formatBytes(bytes) {
14464
+ if (bytes < 1024) return `${bytes} B`;
14465
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
14466
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
14467
+ }
14468
+ /** Apply ops to a snapshot map in order — last write per key wins. */
14469
+ function applyOps(snapshot, ops) {
14470
+ for (const op of ops) if (op.delete === true) snapshot.delete(op.key);
14471
+ else snapshot.set(op.key, op.value);
14472
+ }
14473
+ /** Runtime guard for a journaled op list — adapters validate before restoring. */
14474
+ function isToolStateOps(value) {
14475
+ return Array.isArray(value) && value.every((op) => typeof op === "object" && op !== null && typeof op.key === "string" && (op.delete === true || "value" in op));
14476
+ }
14477
+ //#endregion
13830
14478
  //#region src/agent.ts
13831
14479
  /**
13832
14480
  * Single builder for a {@link ContextAssembly}, shared by the per-run snapshot
@@ -16149,6 +16797,6 @@ function createAgent(rawOptions) {
16149
16797
  };
16150
16798
  }
16151
16799
  //#endregion
16152
- export { removeInstalledExtension as $, readKeybindings as $t, NO_TOOLS_PREAMBLE as A, readFile$1 as At, stripImagesFromTurns as B, edit as Bt, resolveTasksDir as C, effectiveContextWindow as Cn, createSkillsUseTool as Ct, selectRecentFiles as D, normalizeShellCommand as Dn, createShellTool as Dt, selectFilesFromSession as E, defaultRepeatGuardTracked as En, shellKill as Et, buildTailCompactPrompt as F, matchModelEntries as Ft, EMPTY_EXTENSION_REGISTRY as G, KEYBINDING_KEY_COL_WIDTH as Gt, truncateHeadForPtlRetry as H, DEFAULT_KEYBINDINGS as Ht, buildUpToCompactPrompt as I, listFiles as It, fetchExtensionSource as J, groupBindings as Jt, createExtensionPromptBridge as K, ensureKeybindingsFile as Kt, ANCHOR_PREVIEW_MAX_CHARS as L, createInteractionTool as Lt, buildCompactPrompt as M, multiEdit as Mt, buildFromCompactPrompt as N, createModelSearchTool as Nt, compactConversation as O, stableStringify as On, shell as Ot, buildFullCompactPrompt as P, formatModelLine as Pt, readExtensionInstallProvenance as Q, parseBindingSpec as Qt, anchorPreviewFor as R, grep as Rt, resolveSessionDir as S, OUTPUT_RESERVE_TOKENS as Sn, isSpawnTool as St, selectFilesFromReadState as T, defaultRepeatGuardNormalize as Tn, createSkillsReadTool as Tt, CompactInvalidInputError as U, KEYBINDING_DEFS as Ut, summaryToTurn as V, validateToolArgs as Vt, CompactPromptTooLongError as W, KEYBINDING_DEF_BY_ACTION as Wt, listExtensionCandidates as X, matchesBinding as Xt, installExtensionFromSpec as Y, keybindingsPath as Yt, parseExtensionInstallSource as Z, mergeKeybindings as Zt, rehomePersistedStubs as _, resolveExtensionConfig as _n, writeFile$1 as _t, SHELL_CASCADE_CANCEL_MESSAGE as a, defaultExtensionScanPaths as an, composeExtensionPreset as at, resolveMcpWarningsDir as b, toWireConfigSchema as bn, createToolSearchTool as bt, applyCompactSummaryCutoff as c, isExtensionDefinition as cn, filterRegistryPlugins as ct, PERSISTED_STUB_PREFIX as d, createDebugLog as dn, createExtensionHostRuntimeBridge as dt, readKeybindingsRaw as en, updateInstalledExtension as et, PERSISTENCE_PREVIEW_BYTES as f, defineExtension as fn, createWorkspaceSurface as ft, migrateSessionArtifactDirs as g, isValidExtensionConfigValue as gn, basic_default as gt, maybePersistToolResult as h, isValidExtensionConfigItem as hn, basicTools as ht, INTERRUPT_MESSAGE_FOR_TOOL_USE as i, ENTRY_CANDIDATES as in, buildExtensionRegistry as it, TRAILER as j, looksBinary as jt, BASE_INSTRUCTIONS as k, tailTruncate as kt, collectNewlyStaleReadPaths as l, parseExtensionScanPathEnv as ln, mergeContributions as lt, cleanupPersistedSession as m, coerceExtensionConfigInput as mn, definePreset as mt, normalizeProviders as n, stripJsonComments as nn, discoverAndBuildExtensionRegistry as nt, TOOL_USE_CANCELLED_MESSAGE as o, discoverExtensions as on, disposeExtensionRegistry as ot, buildPersistedStub as p, clampExtensionConfigNumber as pn, composePresets as pt, ExtensionInstallError as q, formatBindingForDisplay as qt, resolveModelTargets as r, registerExtensionHostModules as rn, buildExtensionPreset as rt, TOOL_USE_SKIPPED_MESSAGE as s, inlineLoadedExtension as sn, filterExtensionRegistry as st, createAgent as t, resolveExtensionKeybindings as tn, createExtensionHud as tt, renderStaleReadNotice as u, scanExtensionDirectories as un, partitionExtensionCatalog as ut, resolveLegacyPersistDir as v, resolveExtensionConfigValue as vn, WAIT_TASK_TIMED_OUT_PREFIX as vt, buildPostCompactAttachments as w, shouldAutoCompact as wn, createSkillsRunScriptTool as wt, resolvePersistDir as x, AUTO_COMPACT_MIN_GROWTH_FRACTION as xn, createSpawnTool as xt, resolveLegacySessionDir as y, sanitizeExtensionConfigActionPatch as yn, waitTask as yt, sliceForCompaction as z, glob as zt };
16800
+ export { installExtensionFromSpec as $, groupBindings as $t, selectFilesFromSession as A, defaultRepeatGuardNormalize as An, createSkillsReadTool as At, buildUpToCompactPrompt as B, matchModelEntries as Bt, resolveLegacySessionDir as C, resolveExtensionConfigValue as Cn, waitTask as Ct, resolveTasksDir as D, OUTPUT_RESERVE_TOKENS as Dn, reserveChildLabel as Dt, resolveSessionDir as E, AUTO_COMPACT_MIN_GROWTH_FRACTION as En, isSpawnTool as Et, TRAILER as F, hashContent as Fn, readFile$1 as Ft, summaryToTurn as G, edit as Gt, anchorPreviewFor as H, createInteractionTool as Ht, buildCompactPrompt as I, hydrateReadStateFromSession as In, looksBinary as It, CompactPromptTooLongError as J, KEYBINDING_DEFS as Jt, truncateHeadForPtlRetry as K, validateToolArgs as Kt, buildFromCompactPrompt as L, hydrateReadStateFromSessionAsync as Ln, multiEdit as Lt, compactConversation as M, normalizeShellCommand as Mn, createShellTool as Mt, BASE_INSTRUCTIONS as N, stableStringify as Nn, shell as Nt, buildPostCompactAttachments as O, effectiveContextWindow as On, createSkillsUseTool as Ot, NO_TOOLS_PREAMBLE as P, getReadState as Pn, tailTruncate as Pt, fetchExtensionSource as Q, formatBindingForDisplay as Qt, buildFullCompactPrompt as R, readStateKey as Rn, createModelSearchTool as Rt, resolveLegacyPersistDir as S, resolveExtensionConfig as Sn, WAIT_TASK_TIMED_OUT_PREFIX as St, resolvePersistDir as T, toWireConfigSchema as Tn, createSpawnTool as Tt, sliceForCompaction as U, grep as Ut, ANCHOR_PREVIEW_MAX_CHARS as V, listFiles as Vt, stripImagesFromTurns as W, glob as Wt, createExtensionPromptBridge as X, KEYBINDING_KEY_COL_WIDTH as Xt, EMPTY_EXTENSION_REGISTRY as Y, KEYBINDING_DEF_BY_ACTION as Yt, ExtensionInstallError as Z, ensureKeybindingsFile as Zt, buildPersistedStub as _, defineExtension as _n, composePresets as _t, stagedToolState as a, readKeybindingsRaw as an, createExtensionHud as at, migrateSessionArtifactDirs as b, isValidExtensionConfigItem as bn, basic_default as bt, INTERRUPT_MESSAGE_FOR_TOOL_USE as c, registerExtensionHostModules as cn, buildExtensionRegistry as ct, TOOL_USE_SKIPPED_MESSAGE as d, discoverExtensions as dn, filterExtensionRegistry as dt, keybindingsPath as en, listExtensionCandidates as et, applyCompactSummaryCutoff as f, inlineLoadedExtension as fn, filterRegistryPlugins as ft, PERSISTENCE_PREVIEW_BYTES as g, createDebugLog as gn, createWorkspaceSurface as gt, PERSISTED_STUB_PREFIX as h, scanExtensionDirectories as hn, createExtensionHostRuntimeBridge as ht, isToolStateOps as i, readKeybindings as in, updateInstalledExtension as it, selectRecentFiles as j, defaultRepeatGuardTracked as jn, shellKill as jt, selectFilesFromReadState as k, shouldAutoCompact as kn, createSkillsRunScriptTool as kt, SHELL_CASCADE_CANCEL_MESSAGE as l, ENTRY_CANDIDATES as ln, composeExtensionPreset as lt, renderStaleReadNotice as m, parseExtensionScanPathEnv as mn, partitionExtensionCatalog as mt, DEFAULT_MAX_VALUE_BYTES as n, mergeKeybindings as nn, readExtensionInstallProvenance as nt, normalizeProviders as o, resolveExtensionKeybindings as on, discoverAndBuildExtensionRegistry as ot, collectNewlyStaleReadPaths as p, isExtensionDefinition as pn, mergeContributions as pt, CompactInvalidInputError as q, DEFAULT_KEYBINDINGS as qt, createToolStateController as r, parseBindingSpec as rn, removeInstalledExtension as rt, resolveModelTargets as s, stripJsonComments as sn, buildExtensionPreset as st, createAgent as t, matchesBinding as tn, parseExtensionInstallSource as tt, TOOL_USE_CANCELLED_MESSAGE as u, defaultExtensionScanPaths as un, disposeExtensionRegistry as ut, cleanupPersistedSession as v, clampExtensionConfigNumber as vn, definePreset as vt, resolveMcpWarningsDir as w, sanitizeExtensionConfigActionPatch as wn, createToolSearchTool as wt, rehomePersistedStubs as x, isValidExtensionConfigValue as xn, writeFile$1 as xt, maybePersistToolResult as y, coerceExtensionConfigInput as yn, basicTools as yt, buildTailCompactPrompt as z, resolveReadStateMap as zn, formatModelLine as zt };
16153
16801
 
16154
- //# sourceMappingURL=agent-SQ6rxfpT.js.map
16802
+ //# sourceMappingURL=agent-BVNkC1h4.js.map