zidane 5.14.4 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/{acp-24uU2WDs.js → acp-Irby04Us.js} +7 -8
  2. package/dist/{acp-24uU2WDs.js.map → acp-Irby04Us.js.map} +1 -1
  3. package/dist/acp-cli.js +7 -7
  4. package/dist/acp.d.ts +2 -3
  5. package/dist/acp.d.ts.map +1 -1
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-Cch2ayTt.js → agent-DkSmGkDM.js} +10871 -5411
  8. package/dist/agent-DkSmGkDM.js.map +1 -0
  9. package/dist/agent.d.ts +1 -2
  10. package/dist/agent.js +2 -2
  11. package/dist/{anthropic-RGqsJlC8.js → anthropic-CTHsdFG9.js} +46 -6
  12. package/dist/anthropic-CTHsdFG9.js.map +1 -0
  13. package/dist/{auth-C-ms5N2x.js → auth-BDSu_0t3.js} +13 -86
  14. package/dist/auth-BDSu_0t3.js.map +1 -0
  15. package/dist/chat/pure.d.ts +4 -4
  16. package/dist/chat/pure.js +4 -3
  17. package/dist/chat.d.ts +45 -8
  18. package/dist/chat.d.ts.map +1 -1
  19. package/dist/chat.js +9 -6
  20. package/dist/chat.js.map +1 -1
  21. package/dist/completion-core-CXYSVhZo.js +147 -0
  22. package/dist/completion-core-CXYSVhZo.js.map +1 -0
  23. package/dist/{context-breakdown-kO-pDsay.js → context-breakdown-Dzo25N45.js} +2 -23
  24. package/dist/context-breakdown-Dzo25N45.js.map +1 -0
  25. package/dist/contexts/daytona.d.ts +3 -3
  26. package/dist/contexts/daytona.js +1 -1
  27. package/dist/contexts/docker.d.ts +10 -2
  28. package/dist/contexts/docker.d.ts.map +1 -1
  29. package/dist/contexts/docker.js +142 -103
  30. package/dist/contexts/docker.js.map +1 -1
  31. package/dist/contexts/e2b.d.ts +2 -2
  32. package/dist/contexts/e2b.js +1 -1
  33. package/dist/contexts/sandbox.d.ts +1 -1
  34. package/dist/contexts/sandbox.js +4 -1
  35. package/dist/contexts/sandbox.js.map +1 -1
  36. package/dist/{contexts-Lzf5huID.js → contexts-Vone3qQQ.js} +26 -37
  37. package/dist/contexts-Vone3qQQ.js.map +1 -0
  38. package/dist/contexts.d.ts +3 -3
  39. package/dist/contexts.js +1 -1
  40. package/dist/errors.d.ts +1 -2
  41. package/dist/errors.js +1 -1
  42. package/dist/eval.d.ts +1 -1
  43. package/dist/eval.js +3 -3
  44. package/dist/exec-file-size-PXkr-MGA.js +63 -0
  45. package/dist/exec-file-size-PXkr-MGA.js.map +1 -0
  46. package/dist/extensions.d.ts +2 -0
  47. package/dist/extensions.js +2 -0
  48. package/dist/generate-data-WL_yGVL6.js +324 -0
  49. package/dist/generate-data-WL_yGVL6.js.map +1 -0
  50. package/dist/headless.d.ts +1 -1
  51. package/dist/headless.js +15 -10
  52. package/dist/headless.js.map +1 -1
  53. package/dist/index-B8UtiZy7.d.ts +14967 -0
  54. package/dist/index-B8UtiZy7.d.ts.map +1 -0
  55. package/dist/{index-B3ciFUZx.d.ts → index-DsPQbyUn.d.ts} +2 -2
  56. package/dist/index-DsPQbyUn.d.ts.map +1 -0
  57. package/dist/index.d.ts +6 -12
  58. package/dist/index.js +20 -43
  59. package/dist/index.js.map +1 -1
  60. package/dist/{logger-Ktm-lj1s.js → logger-DBX9uYOw.js} +108 -5
  61. package/dist/logger-DBX9uYOw.js.map +1 -0
  62. package/dist/login-DOF8pMVM.js +539 -0
  63. package/dist/login-DOF8pMVM.js.map +1 -0
  64. package/dist/{mcp-Dn5W65Lv.js → mcp-CcvuVXB9.js} +2 -2
  65. package/dist/{mcp-Dn5W65Lv.js.map → mcp-CcvuVXB9.js.map} +1 -1
  66. package/dist/mcp.d.ts +1 -1
  67. package/dist/mcp.js +1 -1
  68. package/dist/{messages-YZQLKaz2.js → messages-CwujiS74.js} +4 -4
  69. package/dist/messages-CwujiS74.js.map +1 -0
  70. package/dist/{openai-compat-0Y7jcncn.js → openai-compat-BvgYGSR1.js} +7 -6
  71. package/dist/{openai-compat-0Y7jcncn.js.map → openai-compat-BvgYGSR1.js.map} +1 -1
  72. package/dist/output/stream-json.d.ts +1 -2
  73. package/dist/output/stream-json.d.ts.map +1 -1
  74. package/dist/output/terminal.d.ts +1 -2
  75. package/dist/output/terminal.d.ts.map +1 -1
  76. package/dist/{glob-DluQFSw1.js → output-cap-kBUHBlnq.js} +50 -2
  77. package/dist/output-cap-kBUHBlnq.js.map +1 -0
  78. package/dist/presets.d.ts +1 -2
  79. package/dist/presets.js +1 -1
  80. package/dist/providers/anthropic.d.ts +2 -2
  81. package/dist/providers/anthropic.js +2 -2
  82. package/dist/providers/arcee.d.ts +1 -1
  83. package/dist/providers/arcee.js +1 -1
  84. package/dist/providers/baseten.d.ts +1 -1
  85. package/dist/providers/baseten.js +1 -1
  86. package/dist/providers/cerebras.d.ts +1 -1
  87. package/dist/providers/cerebras.js +1 -1
  88. package/dist/providers/local.d.ts +1 -1
  89. package/dist/providers/local.js +1 -1
  90. package/dist/providers/openai-compat.d.ts +1 -1
  91. package/dist/providers/openai-compat.js +1 -1
  92. package/dist/providers/openai.d.ts +1 -1
  93. package/dist/providers/openai.js +4 -4
  94. package/dist/providers/openai.js.map +1 -1
  95. package/dist/providers/openrouter.d.ts +1 -1
  96. package/dist/providers/openrouter.js +1 -1
  97. package/dist/providers/xai.d.ts +1 -1
  98. package/dist/providers/xai.js +1 -1
  99. package/dist/{providers-DgmdYGKm.js → providers-z6LDMAr3.js} +3 -3
  100. package/dist/{providers-DgmdYGKm.js.map → providers-z6LDMAr3.js.map} +1 -1
  101. package/dist/providers.d.ts +1 -1
  102. package/dist/providers.js +4 -4
  103. package/dist/{read-state-BymF41Jb.js → read-state-Dq_TXUX1.js} +2 -2
  104. package/dist/{read-state-BymF41Jb.js.map → read-state-Dq_TXUX1.js.map} +1 -1
  105. package/dist/{interpolate-BtIgcCuz.js → resolve-Cr8JSL_O.js} +562 -136
  106. package/dist/resolve-Cr8JSL_O.js.map +1 -0
  107. package/dist/restate.d.ts +2 -2
  108. package/dist/restate.js +2 -2
  109. package/dist/{sandbox-Dgy-m6UF.d.ts → sandbox-CgjG2VvQ.d.ts} +2 -2
  110. package/dist/{sandbox-Dgy-m6UF.d.ts.map → sandbox-CgjG2VvQ.d.ts.map} +1 -1
  111. package/dist/session/sqlite.d.ts +1 -1
  112. package/dist/{session-CqrAFAKJ.js → session-CsdDIPY8.js} +108 -3
  113. package/dist/session-CsdDIPY8.js.map +1 -0
  114. package/dist/session.d.ts +2 -2
  115. package/dist/session.js +3 -3
  116. package/dist/skills-Bsb0rvWI.js +295 -0
  117. package/dist/skills-Bsb0rvWI.js.map +1 -0
  118. package/dist/skills.d.ts +2 -3
  119. package/dist/skills.js +3 -24
  120. package/dist/{errors-CkTvg97v.d.ts → timeout-8vSIRjzl.d.ts} +10 -2
  121. package/dist/timeout-8vSIRjzl.d.ts.map +1 -0
  122. package/dist/{timeout-kGGSXagK.js → timeout-BDetbuN6.js} +59 -2
  123. package/dist/timeout-BDetbuN6.js.map +1 -0
  124. package/dist/tool-formatters-DY0TDb1r.d.ts +378 -0
  125. package/dist/tool-formatters-DY0TDb1r.d.ts.map +1 -0
  126. package/dist/tools/fetch-url.d.ts +1 -1
  127. package/dist/tools/web-search.d.ts +1 -1
  128. package/dist/tools.d.ts +2 -3
  129. package/dist/tools.js +3 -4
  130. package/dist/{transcript-anchors-BHIgMlPq.d.ts → transcript-anchors-Cb-bDbNH.d.ts} +233 -640
  131. package/dist/transcript-anchors-Cb-bDbNH.d.ts.map +1 -0
  132. package/dist/{transcript-anchors-DsoBHg43.js → transcript-anchors-DSRPWjiH.js} +391 -961
  133. package/dist/transcript-anchors-DSRPWjiH.js.map +1 -0
  134. package/dist/tui.d.ts +335 -11
  135. package/dist/tui.d.ts.map +1 -1
  136. package/dist/tui.js +6375 -1892
  137. package/dist/tui.js.map +1 -1
  138. package/dist/{turn-operations-Dw02ZoSQ.d.ts → turn-operations-CgMROLsr.d.ts} +29 -4
  139. package/dist/turn-operations-CgMROLsr.d.ts.map +1 -0
  140. package/dist/{turn-operations-tG0vuBNc.js → turn-operations-Dq9Kx7m2.js} +321 -81
  141. package/dist/turn-operations-Dq9Kx7m2.js.map +1 -0
  142. package/dist/{types-BqdTeBaC.d.ts → types-BDccavwj.d.ts} +42 -1
  143. package/dist/types-BDccavwj.d.ts.map +1 -0
  144. package/dist/{types-CyVGdbia.js → types-BIarq1qE.js} +90 -2
  145. package/dist/types-BIarq1qE.js.map +1 -0
  146. package/dist/types.d.ts +5 -6
  147. package/dist/types.js +1 -1
  148. package/dist/{xai-tPdbAGkq.js → xai-B_e6TOA8.js} +2 -2
  149. package/dist/{xai-tPdbAGkq.js.map → xai-B_e6TOA8.js.map} +1 -1
  150. package/docs/ARCHITECTURE.md +1 -1
  151. package/docs/CHAT.md +7 -6
  152. package/docs/EXECUTION_CONTEXT.md +16 -0
  153. package/docs/EXTENSIONS.md +1063 -0
  154. package/docs/SKILL.md +16 -0
  155. package/docs/TUI.md +10 -3
  156. package/package.json +12 -3
  157. package/dist/agent-Cch2ayTt.js.map +0 -1
  158. package/dist/agent-EFWt6uQ_.d.ts +0 -6914
  159. package/dist/agent-EFWt6uQ_.d.ts.map +0 -1
  160. package/dist/anthropic-RGqsJlC8.js.map +0 -1
  161. package/dist/auth-C-ms5N2x.js.map +0 -1
  162. package/dist/context-breakdown-kO-pDsay.js.map +0 -1
  163. package/dist/contexts-Lzf5huID.js.map +0 -1
  164. package/dist/errors-CkTvg97v.d.ts.map +0 -1
  165. package/dist/glob-DluQFSw1.js.map +0 -1
  166. package/dist/glob-shell-rJMoCIGb.js +0 -21
  167. package/dist/glob-shell-rJMoCIGb.js.map +0 -1
  168. package/dist/index-B3ciFUZx.d.ts.map +0 -1
  169. package/dist/index-BtzE3Uaq.d.ts +0 -2738
  170. package/dist/index-BtzE3Uaq.d.ts.map +0 -1
  171. package/dist/index-tSzOaWNt.d.ts +0 -316
  172. package/dist/index-tSzOaWNt.d.ts.map +0 -1
  173. package/dist/interpolate-BtIgcCuz.js.map +0 -1
  174. package/dist/logger-DGiGf7DW.d.ts +0 -102
  175. package/dist/logger-DGiGf7DW.d.ts.map +0 -1
  176. package/dist/logger-Ktm-lj1s.js.map +0 -1
  177. package/dist/login-CCA-1lgK.js +0 -267
  178. package/dist/login-CCA-1lgK.js.map +0 -1
  179. package/dist/messages-YZQLKaz2.js.map +0 -1
  180. package/dist/policy-DcGlpaNs.d.ts +0 -129
  181. package/dist/policy-DcGlpaNs.d.ts.map +0 -1
  182. package/dist/presets-BQWYMHdd.js +0 -114
  183. package/dist/presets-BQWYMHdd.js.map +0 -1
  184. package/dist/run-summary-DkN8KsHM.d.ts +0 -249
  185. package/dist/run-summary-DkN8KsHM.d.ts.map +0 -1
  186. package/dist/session-CqrAFAKJ.js.map +0 -1
  187. package/dist/shell-quote-BmnhZmdM.js +0 -33
  188. package/dist/shell-quote-BmnhZmdM.js.map +0 -1
  189. package/dist/skills.js.map +0 -1
  190. package/dist/timeout-CpFm0jJ6.d.ts +0 -10
  191. package/dist/timeout-CpFm0jJ6.d.ts.map +0 -1
  192. package/dist/timeout-kGGSXagK.js.map +0 -1
  193. package/dist/tool-formatters-C6iLgc9f.d.ts +0 -1454
  194. package/dist/tool-formatters-C6iLgc9f.d.ts.map +0 -1
  195. package/dist/tools-CCd8e-HT.js +0 -1739
  196. package/dist/tools-CCd8e-HT.js.map +0 -1
  197. package/dist/transcript-anchors-BHIgMlPq.d.ts.map +0 -1
  198. package/dist/transcript-anchors-DsoBHg43.js.map +0 -1
  199. package/dist/turn-operations-Dw02ZoSQ.d.ts.map +0 -1
  200. package/dist/turn-operations-tG0vuBNc.js.map +0 -1
  201. package/dist/types-BqdTeBaC.d.ts.map +0 -1
  202. package/dist/types-CyVGdbia.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools-CCd8e-HT.js","names":["entryPath","entryPath"],"sources":["../src/behaviors/read-file-defaults.ts","../src/tools/path-suggest.ts","../src/tools/edit.ts","../src/tools/glob.ts","../src/tools/grep.ts","../src/tools/interaction.ts","../src/tools/list-files.ts","../src/tools/multi-edit.ts","../src/tools/binary-read.ts","../src/tools/read-file.ts","../src/tools/shell-kill.ts","../src/tools/spawn.ts","../src/tools/write-file.ts"],"sourcesContent":["import type { AgentBehavior } from '../types'\n\nexport interface ReadFileDefaultFallbacks {\n lineLimit: number\n textMaxBytes: number\n attachmentMaxBytes: number\n}\n\n// Resolved defaults are structurally the fallbacks with every field filled in.\nexport type ResolvedReadFileDefaults = ReadFileDefaultFallbacks\n\nexport function normalizeReadFileInteger(value: unknown, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n return fallback\n // Validation auto-coerces strings to numbers, so by the time we get here\n // a non-finite value means the caller passed something garbled.\n if (value < 0)\n return fallback\n return Math.floor(value)\n}\n\nexport function resolveReadFileDefaults(\n behavior: AgentBehavior | undefined,\n fallbacks: ReadFileDefaultFallbacks,\n): ResolvedReadFileDefaults {\n return {\n lineLimit: normalizeReadFileInteger(behavior?.readFileDefaults?.limit, fallbacks.lineLimit),\n textMaxBytes: normalizeReadFileInteger(behavior?.readFileDefaults?.maxBytes, fallbacks.textMaxBytes),\n attachmentMaxBytes: normalizeReadFileInteger(behavior?.readFileDefaults?.maxBytes, fallbacks.attachmentMaxBytes),\n }\n}\n","/**\n * Path-suggestion helper for file-not-found errors.\n *\n * When `read_file` / `edit` / `multi_edit` get a missing-file error, walk the\n * parent directory in the agent's execution context for files sharing the\n * same basename (sans extension) — common cause: model picked the wrong\n * extension (`.js` vs `.ts`, `.md` vs `.mdx`). Returns the closest sibling\n * filename so the tool can append `Did you mean X?` to the error.\n *\n * Mirrors `claude-code/utils/file.ts` `findSimilarFile`. Goes through the\n * `ExecutionContext.listFiles` seam so it works in process / docker / sandbox.\n */\n\nimport type { ExecutionContext, ExecutionHandle, ListFilesEntry } from '../contexts'\n\nfunction entryPath(entry: ListFilesEntry): string {\n return typeof entry === 'string' ? entry : entry.path\n}\n\n/**\n * Find a sibling file in the same directory sharing `path`'s basename\n * (sans extension), excluding the missing path itself. Returns just the\n * filename (not the full path) when found, otherwise `null`.\n *\n * Silent on errors — a missing parent directory or a `listFiles` failure\n * means we have no suggestion, not that anything is wrong.\n */\nexport async function findSimilarFile(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n path: string,\n): Promise<string | null> {\n const slash = path.lastIndexOf('/')\n const dir = slash === -1 ? '.' : (path.slice(0, slash) || '/')\n const target = slash === -1 ? path : path.slice(slash + 1)\n const dot = target.lastIndexOf('.')\n const targetBase = dot === -1 ? target : target.slice(0, dot)\n\n if (targetBase.length === 0)\n return null\n\n let entries: ListFilesEntry[]\n try {\n entries = await execution.listFiles(handle, dir)\n }\n catch {\n return null\n }\n\n for (const item of entries) {\n const entry = entryPath(item)\n if (entry === target)\n continue\n const entryDot = entry.lastIndexOf('.')\n const entryBase = entryDot === -1 ? entry : entry.slice(0, entryDot)\n if (entryBase === targetBase)\n return entry\n }\n return null\n}\n\n/**\n * Format a `Did you mean X?` suffix for missing-file errors. Returns an empty\n * string when no suggestion is available so callers can string-concat\n * unconditionally.\n */\nexport async function suggestionFor(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n path: string,\n): Promise<string> {\n const sibling = await findSimilarFile(execution, handle, path)\n return sibling ? ` Did you mean ${sibling}?` : ''\n}\n","import type { ToolContext, ToolDef } from './types'\nimport { describeVia, resolveOldString, stripLineNumberPrefixes, styleReplacementForVia } from './edit-utils'\nimport { suggestionFor } from './path-suggest'\nimport { hashContent, readStateKey, resolveReadStateMap } from './read-state'\nimport { pathArgError } from './validation'\n\n/**\n * Surgical edit — replace `old_string` with `new_string` in a single file.\n *\n * Mirrors Claude Code's `Edit` semantics so models post-trained on Anthropic's\n * tool surface need no relearning. Fails clearly when `old_string` isn't unique\n * (unless `replace_all: true`) and when not found, with a nearest-match preview\n * so the model can recover without a separate `read_file` round-trip.\n */\n\nexport const edit: ToolDef = {\n spec: {\n name: 'edit',\n description: 'Replace exact `old_string` with `new_string` in a file. Fails if `old_string` is not unique unless `replace_all: true`. Prefer over `write_file` for surgical changes — preserves the rest of the file. Tolerates `read_file` line-number prefixes (`<N>\\\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string` — they are stripped before matching/writing, so you can paste a numbered chunk verbatim.',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path (relative to the execution-context cwd, or absolute).' },\n old_string: { type: 'string', description: 'Exact substring to find.' },\n new_string: { type: 'string', description: 'Replacement substring.' },\n replace_all: { type: 'boolean', description: 'Replace every occurrence. Default: false.' },\n },\n required: ['path', 'old_string', 'new_string'],\n },\n },\n async execute({ path, old_string, new_string, replace_all }, ctx: ToolContext) {\n const target = path as string\n const find = old_string as string\n const replacement = new_string as string\n const replaceAll = replace_all === true\n\n const pathErr = pathArgError(target)\n if (pathErr) {\n ctx.reportOutcome?.('failed')\n return `Edit error: ${pathErr}`\n }\n\n if (find === replacement)\n return `Edit error: old_string and new_string are identical — nothing to change in ${target}.`\n\n if (find.length === 0)\n return `Edit error: old_string is empty. Use write_file to create or fully overwrite a file.`\n\n let original: string\n try {\n original = await ctx.execution.readFile(ctx.handle, target)\n }\n catch {\n const hint = await suggestionFor(ctx.execution, ctx.handle, target)\n ctx.reportOutcome?.('failed')\n return `Edit error: file not found: ${target}.${hint}`\n }\n\n // Read-before-edit guard. When `behavior.requireReadBeforeEdit` is on\n // and a read-state map is available (session-keyed or forwarded via\n // `ctx.readState` from a spawn `shareReadState` parent), refuse edits\n // against files the model hasn't read this session, and against files\n // whose on-disk content has drifted from what the model last saw —\n // both produce silent corruption when an edit applies a substring\n // against bytes the model \"remembers\" but no longer reflect reality.\n //\n // Without any read-state map (no session, no explicit forward) the\n // guard is skipped: tracking has nowhere to live, so the gate has\n // nothing to check against.\n if (ctx.behavior?.requireReadBeforeEdit) {\n const readState = resolveReadStateMap(ctx)\n if (readState) {\n const absKey = readStateKey(ctx.handle.cwd, target)\n const prior = readState.get(absKey)\n if (!prior)\n return `Edit error: ${target} has not been read in this session. Call read_file first so the edit applies against the current contents.`\n if (prior.contentHash !== hashContent(original))\n return `Edit error: ${target} has changed on disk since the last read. Re-read the file before editing.`\n }\n }\n\n // Resolve `old_string` against the file content with the recovery\n // cascade in `resolveOldString` (exact → quotes → desanitize → combined\n // → line-number-strip → strip+quotes). On a non-exact hit, `match.actual`\n // is the file-side substring (preserves the file's typography) and the\n // replacement is re-styled below to match.\n const match = resolveOldString(original, find)\n\n if (!match) {\n const preview = nearestMatchPreview(original, find)\n ctx.reportOutcome?.('failed')\n return preview\n ? `Edit error: old_string not found in ${target}. Closest match in the file: ${preview}`\n : `Edit error: old_string not found in ${target}.`\n }\n\n const { actual, occurrences, via } = match\n\n if (occurrences > 1 && !replaceAll)\n return `Edit error: old_string appears ${occurrences} times in ${target}. Pass replace_all=true or expand old_string for uniqueness.`\n\n const styledReplacement = styleReplacementForVia(replacement, via, actual)\n\n const updated = replaceAll\n ? original.split(actual).join(styledReplacement)\n : original.replace(actual, styledReplacement)\n\n if (updated === original) {\n ctx.reportOutcome?.('noop')\n return `Edit error: replacement produced no change in ${target}.`\n }\n\n await ctx.execution.writeFile(ctx.handle, target, updated)\n\n // Keep read-state coherent — after a successful edit, the model\n // knows the post-edit content (it produced new_string), so we\n // record the new hash against the same slice. This lets a chain\n // of edits proceed without re-reading between each one even with\n // `requireReadBeforeEdit` on.\n const readState = resolveReadStateMap(ctx)\n if (readState) {\n const absKey = readStateKey(ctx.handle.cwd, target)\n const prior = readState.get(absKey)\n if (prior)\n readState.set(absKey, { ...prior, contentHash: hashContent(updated), mtimeMs: Date.now() })\n }\n\n ctx.reportOutcome?.('edited')\n // Flag non-exact recoveries so a mistargeted fallback is visible in the\n // transcript instead of silently passing as a verbatim match.\n const viaNote = via === 'exact' ? '' : ` (old_string was not found verbatim; matched via ${describeVia(via)})`\n return `Edited ${target}: replaced ${occurrences} occurrence${occurrences === 1 ? '' : 's'}.${viaNote}`\n },\n}\n\n/**\n * Find the line that shares the longest common prefix with the needle's first\n * line. Cheap heuristic — better than nothing for the common \"model has a typo\"\n * case (off-by-one indent, trailing whitespace, escape mismatch).\n *\n * Returns a \"line N: <preview>\" snippet or null when no line shares a useful\n * prefix. Strips line-number prefixes from the needle first so a model that\n * pasted a numbered `read_file` chunk verbatim still gets a useful diagnostic.\n */\nfunction nearestMatchPreview(haystack: string, needle: string): string | null {\n // If the model included `<N>\\t` (or `<N>|` / `<N>→`) prefixes from a\n // numbered read, strip them before scoring — otherwise the prefix\n // dominates and we never match real file lines.\n const normalizedNeedle = stripLineNumberPrefixes(needle)\n const needleFirstLine = normalizedNeedle.split('\\n')[0]\n if (needleFirstLine.length < 3)\n return null\n\n const lines = haystack.split('\\n')\n let bestScore = 0\n let bestIdx = -1\n for (let i = 0; i < lines.length; i++) {\n const score = sharedPrefixLength(lines[i], needleFirstLine)\n if (score > bestScore) {\n bestScore = score\n bestIdx = i\n }\n }\n if (bestIdx < 0 || bestScore < Math.min(8, Math.floor(needleFirstLine.length / 2)))\n return null\n\n const snippet = lines[bestIdx].slice(0, 80)\n return `line ${bestIdx + 1}: ${JSON.stringify(snippet)}`\n}\n\nfunction sharedPrefixLength(a: string, b: string): number {\n const max = Math.min(a.length, b.length)\n let i = 0\n while (i < max && a.charCodeAt(i) === b.charCodeAt(i))\n i++\n return i\n}\n","import type { ListFileMetadata, ListFilesEntry } from '../contexts'\nimport type { ToolContext, ToolDef } from './types'\nimport { errorMessage } from '../errors'\n\n/**\n * Glob-pattern file matching.\n *\n * Delegates matching to {@link ExecutionContext.listFiles} with `{ glob:\n * true }`. This keeps filesystem semantics inside the execution context\n * (process / docker / sandbox) instead of reaching around it from the tool.\n *\n * Results are capped at 1000 entries to keep model input bounded. The\n * cap applies after the directory filter, so dirs don't consume the\n * file budget.\n *\n * Patterns are deliberately NOT confined to the workspace: like\n * `read_file`, `../`-prefixed patterns may match outside the cwd — the\n * execution context is the sandbox boundary, not this tool.\n *\n * By default, contexts that can cheaply provide metadata return\n * `<path>\\t<size>\\t<mtime>` rows. Contexts without cheap metadata support return\n * paths only. Pass `metadata: false` to request plain newline-separated paths.\n */\nconst DEFAULT_LIMIT = 1000\n\n/** Backstop so a pathological walk can never hang the agent's turn. */\nconst GLOB_TIMEOUT_MS = 20_000\n\nfunction entryPath(entry: ListFilesEntry): string {\n return typeof entry === 'string' ? entry : entry.path\n}\n\nfunction entryMetadata(entry: ListFilesEntry): ListFileMetadata | undefined {\n return typeof entry === 'string' ? undefined : entry\n}\n\nfunction renderEntry(entry: ListFilesEntry, wantMetadata: boolean): string {\n const path = entryPath(entry)\n const meta = entryMetadata(entry)\n if (!wantMetadata || typeof meta?.size !== 'number' || typeof meta.mtimeMs !== 'number')\n return path\n return `${path}\\t${meta.size}\\t${new Date(meta.mtimeMs).toISOString()}`\n}\n\nexport const glob: ToolDef = {\n // Filesystem listing only — safe to fan out alongside other reads.\n isConcurrencySafe: true,\n spec: {\n name: 'glob',\n description: 'Match files by glob pattern (supports **, *, ?). Relative to the execution context cwd; patterns may reach outside the workspace (e.g. \"../shared/**/*.ts\"). By default each row is `<path>\\\\t<size-bytes>\\\\t<mtime-iso>`; set `metadata: false` for a plain newline-separated list of paths. Always sorted.',\n inputSchema: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: 'Glob pattern (e.g. \"src/**/*.ts\", \"*.md\", \"test/**/fixtures/*\").',\n },\n limit: {\n type: 'number',\n description: `Maximum number of matches to return. Default: ${DEFAULT_LIMIT}.`,\n },\n metadata: {\n type: 'boolean',\n description: 'Append size (bytes) and mtime (ISO) per row, tab-separated. Default: true. In-process only — non-process execution contexts always return paths.',\n },\n gitignore: {\n type: 'boolean',\n description: 'Skip files git ignores (.gitignore, .git/info/exclude, global excludes). Default: true. Set false to include ignored files like node_modules. Honored where git is available; a no-op otherwise.',\n },\n },\n required: ['pattern'],\n },\n },\n async execute({ pattern, limit, metadata, gitignore }, ctx: ToolContext) {\n const pat = pattern as string\n const max = typeof limit === 'number' && limit > 0 ? limit : DEFAULT_LIMIT\n const wantMetadata = metadata !== false\n\n try {\n if (ctx.execution.capabilities.glob !== true)\n throw new Error(`The active execution context (${ctx.execution.type}) does not support glob matching.`)\n\n // Backstop: a pathological walk must never hang the turn. Abort the\n // listing and return a steer after GLOB_TIMEOUT_MS — raced so the tool\n // settles on time even if a streaming matcher is slow to yield control.\n // The controller is also linked to the caller's signal.\n const controller = new AbortController()\n const onAbort = () => controller.abort()\n ctx.signal.addEventListener('abort', onAbort, { once: true })\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<'timeout'>((resolve) => {\n timer = setTimeout(() => {\n controller.abort()\n resolve('timeout')\n }, GLOB_TIMEOUT_MS)\n })\n try {\n const outcome = await Promise.race([\n ctx.execution.listFiles(ctx.handle, pat, {\n glob: true,\n limit: max,\n metadata: wantMetadata,\n gitignore: gitignore as boolean | undefined,\n signal: controller.signal,\n }),\n timeout,\n ])\n if (outcome === 'timeout')\n return `Glob timed out after ${GLOB_TIMEOUT_MS}ms — narrow the pattern (anchor a literal prefix like \\`src/**\\`) or scope it to a subdirectory.`\n if (outcome.length === 0)\n return '(no matches)'\n return outcome.map(entry => renderEntry(entry, wantMetadata)).join('\\n')\n }\n finally {\n clearTimeout(timer)\n ctx.signal.removeEventListener('abort', onAbort)\n }\n }\n catch (err) {\n return `Glob error: ${errorMessage(err)}`\n }\n },\n}\n","import type { ToolContext, ToolDef } from './types'\nimport { Buffer } from 'node:buffer'\nimport { GIT_LS_FILES_COMMAND, parseGitLsFiles } from '../contexts/git-ls-files'\nimport { errorMessage, isAbortLikeError } from '../errors'\nimport { shellQuote } from './shell-quote'\n\n/**\n * Search file contents by regex.\n *\n * Wraps ripgrep (`rg`) when available; when it's not, falls back to a\n * regex search that enumerates files via the execution context's shell\n * (`find` over `exec`) and reads them via `ctx.execution.readFile`. Both\n * legs go through the {@link ToolContext.execution} seam, so the search\n * runs wherever the context's files actually live — in-process, a\n * container, or a remote sandbox — without the tool ever touching the host\n * filesystem directly.\n *\n * The tool surface mirrors Claude Code's `Grep` so models authored against the\n * Anthropic tool surface need no relearning. Output modes:\n * - `files_with_matches` (default) — newline-separated paths.\n * - `content` — `path:line:match` (line numbers on by default).\n * - `count` — `path:N` per matching file.\n *\n * Results are capped via `head_limit` (default 250) to keep model input\n * bounded; `offset` lets the caller page through. Pagination operates on\n * OUTPUT LINES, not match groups — in content mode, context lines and `--`\n * separators consume the budget too (documented in the schema).\n *\n * A line cap is not enough on its own: ripgrep is line-oriented, so a minified\n * / single-line file collapses to ONE match line that is the entire file, and\n * `head_limit` would happily return megabytes — enough to blow the model's\n * context window. Output is therefore ALSO byte-bounded: each line is clipped\n * to `MAX_LINE_BYTES` and the total to `OUTPUT_BYTE_CAP`, mirroring the byte\n * discipline `read_file` already enforces.\n *\n * `path` is deliberately NOT confined to the workspace: like `read_file`,\n * absolute paths and `../` traversal are allowed — the execution context is\n * the sandbox boundary, not this tool.\n */\n\nconst DEFAULT_HEAD_LIMIT = 250\n\n/**\n * Per-line byte cap. ripgrep reports a match as the whole matching LINE, so a\n * minified / single-line file (one line = the entire file) would otherwise be\n * returned in full. Clip each line so a single line can't dump unbounded bytes\n * into the model context.\n */\nconst MAX_LINE_BYTES = 2000\n\n/** Total output byte cap, mirroring read_file's `DEFAULT_BYTE_CAP`. */\nconst OUTPUT_BYTE_CAP = 262_144\n\nconst DEFAULT_OUTPUT_MODE: OutputMode = 'files_with_matches'\n\ntype OutputMode = 'content' | 'files_with_matches' | 'count'\n\ninterface GrepInput {\n 'pattern': string\n 'path'?: string\n 'glob'?: string\n 'type'?: string\n 'output_mode'?: OutputMode\n '-i'?: boolean\n '-n'?: boolean\n '-A'?: number\n '-B'?: number\n '-C'?: number\n 'multiline'?: boolean\n 'head_limit'?: number\n 'offset'?: number\n 'gitignore'?: boolean\n}\n\nexport const grep: ToolDef = {\n // Searches files without touching them — concurrency-safe.\n isConcurrencySafe: true,\n spec: {\n name: 'grep',\n description: 'Search file contents by regex. Returns matching paths (default), match content, or per-file counts. Backed by ripgrep when available, with a portable shell-listing + regex fallback when `rg` is absent.',\n inputSchema: {\n type: 'object',\n properties: {\n 'pattern': { type: 'string', description: 'Regex (PCRE-flavored via ripgrep, JS regex via fallback).' },\n 'path': { type: 'string', description: 'File or directory to search. Default: \".\". May be absolute or outside the workspace (no confinement — consistent with read_file).' },\n 'glob': { type: 'string', description: 'Restrict to files matching this glob, e.g. \"**/*.ts\".' },\n 'type': { type: 'string', description: 'rg file type filter, e.g. \"ts\", \"py\", \"rust\". Ignored by the fallback.' },\n 'output_mode': { type: 'string', enum: ['content', 'files_with_matches', 'count'], description: 'Default: \"files_with_matches\".' },\n '-i': { type: 'boolean', description: 'Case-insensitive match.' },\n '-n': { type: 'boolean', description: 'Show line numbers (content mode). Default: true.' },\n '-A': { type: 'integer', description: 'Lines of trailing context (content mode).' },\n '-B': { type: 'integer', description: 'Lines of leading context (content mode).' },\n '-C': { type: 'integer', description: 'Lines of surrounding context (content mode). Overridden by -A/-B if set.' },\n 'multiline': { type: 'boolean', description: 'Allow patterns to match across line boundaries.' },\n 'gitignore': { type: 'boolean', description: 'Skip files git ignores (.gitignore, .git/info/exclude, global excludes). Default: true. Set false to also search ignored files like node_modules.' },\n 'head_limit': { type: 'integer', description: `Cap output lines. Default: 250. Set 0 for unlimited lines. In content mode, context lines (-A/-B/-C) and \"--\" separators count toward the cap, so the number of matches shown may be lower. Output is independently byte-bounded: each line is clipped to ${MAX_LINE_BYTES} bytes and the total to ${OUTPUT_BYTE_CAP} bytes, so long (e.g. minified) lines never overflow the context window.` },\n 'offset': { type: 'integer', description: 'Skip first N output lines. Default: 0.' },\n },\n required: ['pattern'],\n },\n },\n async execute(rawInput, ctx: ToolContext) {\n const input = rawInput as unknown as GrepInput\n\n try {\n if (await isRipgrepAvailable(ctx))\n return await runViaRipgrep(input, ctx)\n return await runFallback(input, ctx)\n }\n catch (err) {\n // grep must never leak a raw exception to the model. An abort is the\n // sole exception we re-throw — the loop renders its canonical\n // interrupt/cascade marker; everything else (a broken `exec`, an\n // unreadable tree, a remote transport error) becomes a `grep error:`.\n if (isAbortLikeError(err))\n throw err\n return `grep error: ${errorMessage(err)}`\n }\n },\n}\n\n// ---------------------------------------------------------------------------\n// ripgrep path\n// ---------------------------------------------------------------------------\n\n/**\n * Probe ripgrep availability **per call**. The probe is intentionally not\n * cached: caching at module scope would leak across execution contexts (an\n * orchestrator running an in-process agent and a docker agent in the same\n * Node process must be able to differ on whether `rg` exists), and caching\n * per handle adds bookkeeping for negligible savings — `rg --version` is\n * ~5 ms, and grep is invoked at most a few times per turn.\n */\nasync function isRipgrepAvailable(ctx: ToolContext): Promise<boolean> {\n const result = await ctx.execution.exec(ctx.handle, 'rg --version', { signal: ctx.signal })\n return result.exitCode === 0\n}\n\nasync function runViaRipgrep(input: GrepInput, ctx: ToolContext): Promise<string> {\n const args = ['rg']\n const mode = (input.output_mode ?? DEFAULT_OUTPUT_MODE) as OutputMode\n\n if (mode === 'files_with_matches')\n args.push('--files-with-matches')\n else if (mode === 'count')\n args.push('--count')\n else\n args.push((input['-n'] ?? true) ? '--line-number' : '--no-line-number')\n\n if (input['-i'])\n args.push('-i')\n\n if (mode === 'content') {\n if (typeof input['-A'] === 'number')\n args.push('-A', String(input['-A']))\n if (typeof input['-B'] === 'number')\n args.push('-B', String(input['-B']))\n if (typeof input['-C'] === 'number' && typeof input['-A'] !== 'number' && typeof input['-B'] !== 'number')\n args.push('-C', String(input['-C']))\n }\n\n if (input.multiline)\n args.push('--multiline', '--multiline-dotall')\n\n // ripgrep respects .gitignore by default; only disable it on explicit opt-out.\n if (input.gitignore === false)\n args.push('--no-ignore')\n\n if (input.glob)\n args.push('--glob', input.glob)\n\n if (input.type)\n args.push('--type', input.type)\n\n args.push('--', input.pattern)\n\n // Always pass a path — rg reads from stdin when invoked from a non-TTY child\n // process without a path argument, which hangs forever waiting for input.\n args.push(input.path ?? '.')\n\n const command = args.map(shellQuote).join(' ')\n const result = await ctx.execution.exec(ctx.handle, command, { signal: ctx.signal })\n\n // ripgrep exits 1 when there are no matches — that's not an error here.\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n return `grep error: ${result.stderr.trim() || `rg exited with code ${result.exitCode}`}`\n }\n\n return formatPaginated(result.stdout, input)\n}\n\n// ---------------------------------------------------------------------------\n// Fallback path (context-routed `find` enumeration + readFile + JS regex)\n// ---------------------------------------------------------------------------\n\nasync function runFallback(input: GrepInput, ctx: ToolContext): Promise<string> {\n const mode = (input.output_mode ?? DEFAULT_OUTPUT_MODE) as OutputMode\n const flags = `${input['-i'] ? 'i' : ''}${input.multiline ? 's' : ''}${mode !== 'content' ? '' : 'g'}`\n\n let regex: RegExp\n try {\n regex = new RegExp(input.pattern, flags || undefined)\n }\n catch (err) {\n return `grep error: invalid regex: ${errorMessage(err)}`\n }\n\n const files = await enumerateFiles(input, ctx)\n const showLineNumbers = input['-n'] ?? true\n const before = (input['-B'] ?? input['-C'] ?? 0)\n const after = (input['-A'] ?? input['-C'] ?? 0)\n\n const lines: string[] = []\n for (const path of files) {\n let content: string\n try {\n content = await ctx.execution.readFile(ctx.handle, path)\n }\n catch (err) {\n // Skip unreadable / binary / vanished files — but let an abort\n // propagate (a remote readFile may reject with AbortError on cancel).\n if (isAbortLikeError(err))\n throw err\n continue\n }\n if (input.multiline) {\n // Multiline mode: scan the whole buffer with /g semantics.\n const allMatches = [...content.matchAll(new RegExp(regex.source, `${flags.replace(/g/, '')}g`))]\n if (allMatches.length === 0)\n continue\n if (mode === 'files_with_matches') {\n lines.push(path)\n continue\n }\n if (mode === 'count') {\n lines.push(`${path}:${allMatches.length}`)\n continue\n }\n // content mode — emit each match's surrounding line context.\n for (const m of allMatches) {\n const lineStart = content.lastIndexOf('\\n', m.index! - 1) + 1\n const lineEnd = content.indexOf('\\n', m.index!)\n const snippet = content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd)\n const lineNo = content.slice(0, m.index!).split('\\n').length\n lines.push(formatContentLine(path, lineNo, snippet, showLineNumbers))\n }\n continue\n }\n\n const fileLines = content.split('\\n')\n const matched: number[] = []\n for (let i = 0; i < fileLines.length; i++) {\n regex.lastIndex = 0\n if (regex.test(fileLines[i]))\n matched.push(i)\n }\n if (matched.length === 0)\n continue\n\n if (mode === 'files_with_matches') {\n lines.push(path)\n continue\n }\n if (mode === 'count') {\n lines.push(`${path}:${matched.length}`)\n continue\n }\n\n const includeLineNos = new Set<number>()\n for (const m of matched) {\n for (let i = Math.max(0, m - before); i <= Math.min(fileLines.length - 1, m + after); i++)\n includeLineNos.add(i)\n }\n const sorted = [...includeLineNos].sort((a, b) => a - b)\n let prev = -2\n for (const lineNo of sorted) {\n if (lineNo > prev + 1 && lines.length > 0)\n lines.push('--')\n const snippet = fileLines[lineNo]\n lines.push(formatContentLine(path, lineNo + 1, snippet, showLineNumbers))\n prev = lineNo\n }\n }\n\n return formatPaginated(lines.join('\\n'), input)\n}\n\nfunction formatContentLine(path: string, lineNo: number, snippet: string, showLineNumbers: boolean): string {\n return showLineNumbers ? `${path}:${lineNo}:${snippet}` : `${path}:${snippet}`\n}\n\nasync function enumerateFiles(input: GrepInput, ctx: ToolContext): Promise<string[]> {\n const root = input.path ?? '.'\n\n // Single-file fast path: if `path` names a file, search just it. Routed\n // through `exec` so the check runs inside the context, not on the host.\n if (input.path && !input.path.includes('*') && !input.path.includes('?')) {\n const probe = await ctx.execution.exec(ctx.handle, `test -f ${shellQuote(input.path)} && echo file || echo dir`, { signal: ctx.signal })\n if (probe.stdout.trim() === 'file')\n return [input.path]\n }\n\n // Enumerate through the execution context's shell so the listing comes from\n // wherever the context's files live — never the host filesystem. `find` is\n // the same primitive the `glob` tool's portable path uses.\n const result = await ctx.execution.exec(ctx.handle, buildFindCommand(root, input.glob), { signal: ctx.signal })\n\n // A non-zero exit with NO output is a real failure (find unavailable, bad\n // root) — surface it like ripgrep would for a bad path. A non-zero exit WITH\n // output is a partial walk (e.g. an unreadable subdir): keep what we got,\n // matching the previous skip-on-error behavior. `find` writes diagnostics to\n // stderr, so stdout stays a clean newline-separated path list either way.\n if (result.exitCode !== 0 && !result.stdout.trim())\n throw new Error(result.stderr.trim() || `find exited with code ${result.exitCode}`)\n\n const files = result.stdout\n .split('\\n')\n .map(line => line.replace(/^\\.\\//, ''))\n .filter(line => line.length > 0)\n .sort()\n\n // `find` honors no ignore rules, so the no-`rg` fallback would otherwise\n // walk `node_modules` etc. — inconsistent with the ripgrep path. Restrict to\n // git's non-ignored set by default; `gitignore: false` keeps everything.\n if (input.gitignore === false)\n return files\n return filterByGitignore(files, root, ctx)\n}\n\n/**\n * Best-effort intersection of `files` with `git ls-files` (non-ignored set).\n * Returns `files` unchanged when git is unavailable, the dir isn't a repo, or\n * `root` escapes the repo (absolute / `..`) — the filter can only fail open.\n */\nasync function filterByGitignore(files: string[], root: string, ctx: ToolContext): Promise<string[]> {\n if (files.length === 0)\n return files\n if (root !== '.' && (root.startsWith('/') || root.split('/').includes('..')))\n return files\n try {\n const res = await ctx.execution.exec(ctx.handle, GIT_LS_FILES_COMMAND, { signal: ctx.signal })\n if (res.exitCode !== 0)\n return files\n const allowed = new Set(parseGitLsFiles(res.stdout))\n if (allowed.size === 0)\n return files\n return files.filter(file => allowed.has(file))\n }\n catch {\n return files\n }\n}\n\n/**\n * Build a `find` command listing files under `root`, optionally filtered by\n * `glob`. Mirrors `glob`'s shell fallback:\n * - a bare basename, or one behind a leading recursive-wildcard segment,\n * with no inner slash → `-name` (matches at any depth, including the top\n * level — preserving the recursive-glob semantics).\n * - anything with a slash → `-path` against the full relative path. `find`'s\n * `*` spans `/`, so the single- and double-star forms collapse to the\n * same matcher; close enough for the no-`rg` fallback.\n */\nfunction buildFindCommand(root: string, glob?: string): string {\n const findRoot = normalizeFindRoot(root)\n const base = shellQuote(findRoot)\n if (!glob)\n return `find ${base} -type f`\n const anyDepth = glob.match(/^(?:\\*\\*\\/)?([^/]+)$/)\n if (anyDepth)\n return `find ${base} -type f -name ${shellQuote(anyDepth[1])}`\n const normRoot = findRoot.replace(/\\/$/, '')\n const pathPattern = root === '.' ? `./${glob}` : `${normRoot}/${glob}`\n return `find ${base} -type f -path ${shellQuote(pathPattern)}`\n}\n\nfunction normalizeFindRoot(root: string): string {\n // POSIX `find` parses a leading-dash first operand as an expression/option.\n // Prefix relative paths like `-fixtures` so they remain path operands.\n return root.startsWith('-') ? `./${root}` : root\n}\n\nfunction formatPaginated(text: string, input: GrepInput): string {\n const headLimit = typeof input.head_limit === 'number' && input.head_limit >= 0\n ? input.head_limit\n : DEFAULT_HEAD_LIMIT\n const offset = typeof input.offset === 'number' && input.offset > 0\n ? Math.floor(input.offset)\n : 0\n\n if (!text.trim())\n return '(no matches)'\n\n const lines = text.split('\\n').filter(l => l.length > 0)\n const total = lines.length\n\n const sliced = headLimit === 0\n ? lines.slice(offset)\n : lines.slice(offset, offset + headLimit)\n\n if (sliced.length === 0)\n return '(no matches in this slice)'\n\n // Byte budget. `head_limit` caps the LINE count, but a single line can be\n // arbitrarily large (a minified / one-line file is one match line = the whole\n // file), so a line cap alone leaves byte output unbounded and can overflow the\n // model context. Clip each line, then stop once the total crosses the cap.\n const capped: string[] = []\n let bytesUsed = 0\n let byteCut = false\n for (const line of sliced) {\n const clipped = clipLine(line)\n const lineBytes = Buffer.byteLength(clipped) + 1 // +1 for the rejoining '\\n'\n if (bytesUsed + lineBytes > OUTPUT_BYTE_CAP && capped.length > 0) {\n byteCut = true\n break\n }\n capped.push(clipped)\n bytesUsed += lineBytes\n }\n\n const shown = capped.length\n const truncatedHead = offset > 0\n // Lines withheld by the line-count window, independent of the byte cut.\n const lineCutTail = headLimit > 0 && offset + headLimit < total\n\n // Markers say \"lines\", not \"matches\" — in content mode the pagination\n // unit includes context lines and `--` separators.\n let out = capped.join('\\n')\n if (truncatedHead)\n out = `…(${offset} earlier lines skipped)…\\n${out}`\n if (byteCut)\n out = `${out}\\n…(output truncated at ${OUTPUT_BYTE_CAP} bytes after ${shown} of ${total - offset} matching lines; narrow the pattern or page with offset=${offset + shown})`\n else if (lineCutTail)\n out = `${out}\\n…(${total - offset - headLimit} more lines; re-run with offset=${offset + headLimit} or larger head_limit)`\n return out\n}\n\n/**\n * Clip one output line to `MAX_LINE_BYTES` at a UTF-8-safe boundary, appending\n * a marker that reports how many bytes were withheld. Lines within budget pass\n * through untouched.\n */\nfunction clipLine(line: string): string {\n if (Buffer.byteLength(line) <= MAX_LINE_BYTES)\n return line\n let cut = Math.min(line.length, MAX_LINE_BYTES)\n while (cut > 0 && Buffer.byteLength(line.slice(0, cut)) > MAX_LINE_BYTES)\n cut--\n const omitted = Buffer.byteLength(line) - Buffer.byteLength(line.slice(0, cut))\n return `${line.slice(0, cut)}… [line clipped, ${omitted} more bytes]`\n}\n","/**\n * Interaction tool — lets the agent request structured input from the outside world.\n *\n * Not included in any preset by default. Add it explicitly:\n *\n * import { createInteractionTool } from 'zidane'\n *\n * const askUser = createInteractionTool({\n * schema: { type: 'object', properties: { question: { type: 'string' } }, required: ['question'] },\n * onRequest: async (payload) => {\n * const answer = await promptUser(payload.question)\n * return { answer }\n * },\n * })\n *\n * const preset = definePreset({ name: 'interactive', tools: { ...basicTools, ask_user: askUser } })\n */\n\nimport type { ToolContext, ToolDef } from './types'\n\nfunction abortReason(signal: AbortSignal): string {\n return typeof signal.reason === 'string' && signal.reason.length > 0\n ? signal.reason\n : 'Interaction aborted'\n}\n\nexport interface InteractionToolOptions {\n /** JSON Schema for the request payload the model sends */\n schema: Record<string, unknown>\n /** Tool name (default: 'interaction') */\n name?: string\n /** Tool description shown to the model */\n description?: string\n /** Called when the model invokes this tool. Receives the validated payload and tool context, returns data for the model. */\n onRequest: (payload: Record<string, unknown>, ctx: ToolContext) => Promise<Record<string, unknown> | string>\n}\n\n/**\n * Create an interaction tool that lets the agent request structured input.\n *\n * The model calls this tool with a payload matching the schema.\n * `onRequest` is called with the payload and should return the response\n * (string or object) that gets sent back to the model as the tool result.\n */\nexport function createInteractionTool(options: InteractionToolOptions): ToolDef {\n const name = options.name ?? 'interaction'\n const description = options.description ?? 'Request structured input from the user or external system.'\n\n return {\n spec: {\n name,\n description,\n inputSchema: options.schema,\n },\n async execute(input, ctx) {\n // Race the host resolver against the run's abort signal. `onRequest`\n // settles only on external (human/system) action, so without this an\n // `agent.abort()` / `agent.destroy()` — every teardown/cancel path —\n // would leave the tool body (and the run) hanging on a promise that can\n // never settle. On abort we reject so the loop unwinds cleanly.\n const { signal } = ctx\n if (signal?.aborted)\n throw new Error(abortReason(signal))\n\n let onAbort: (() => void) | undefined\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n onAbort = () => reject(new Error(abortReason(signal)))\n signal.addEventListener('abort', onAbort, { once: true })\n })\n : undefined\n\n try {\n const result = abortPromise\n ? await Promise.race([options.onRequest(input, ctx), abortPromise])\n : await options.onRequest(input, ctx)\n return typeof result === 'string' ? result : JSON.stringify(result)\n }\n finally {\n if (signal && onAbort)\n signal.removeEventListener('abort', onAbort)\n }\n },\n }\n}\n","import type { ListFilesEntry } from '../contexts'\nimport type { ToolContext, ToolDef } from './types'\n\nfunction entryPath(entry: ListFilesEntry): string {\n return typeof entry === 'string' ? entry : entry.path\n}\n\nexport const listFiles: ToolDef = {\n // Directory listing only — safe to parallelize alongside other reads.\n isConcurrencySafe: true,\n spec: {\n name: 'list_files',\n description: 'List the immediate entries (files and subdirectories) at literal directory `path`. Returns a newline-separated list, or `(empty directory)` when the directory exists but is empty. Returns `Directory not found: <path>` for a missing path. Non-recursive: use `glob` for pattern matching across nested directories.',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'Directory path (relative to the execution-context cwd, or absolute). Defaults to `.`.' },\n },\n required: [],\n },\n },\n async execute({ path }, ctx: ToolContext) {\n try {\n const entries = await ctx.execution.listFiles(ctx.handle, (path as string) || '.')\n return entries.map(entryPath).join('\\n') || '(empty directory)'\n }\n catch {\n return `Directory not found: ${path}`\n }\n },\n}\n","import type { ToolContext, ToolDef } from './types'\nimport { describeVia, resolveOldString, styleReplacementForVia } from './edit-utils'\nimport { suggestionFor } from './path-suggest'\nimport { hashContent, readStateKey, resolveReadStateMap } from './read-state'\nimport { pathArgError } from './validation'\n\n/**\n * Multi-edit on a single file — best-effort, per-hunk semantics.\n *\n * Each step replaces `old_string` with `new_string` against the file\n * contents *as left by the previous applied edit*. A per-step failure\n * (`old_string` not found, ambiguous match without `replace_all`,\n * identical strings, malformed input) is recorded against THAT step\n * only — the remaining steps still run. The file is written iff at\n * least one step applied. The result text reports per-hunk outcomes\n * inline and (when any step failed) carries an\n * `<edit-outcomes>…</edit-outcomes>` annotation block so the chat layer\n * + replay can paint per-hunk badges via `parseEditOutcomesFromResult`.\n *\n * Per-hunk approval is a TUI/host concern. When the user partially\n * denies a `multi_edit` from the file-edit modal, the gate handler\n * rebinds `ctx.input.edits` to the approved subset before this tool\n * runs — so the body sees a smaller all-approved batch and reports\n * outcomes keyed against THAT subset. The host's `tool:transform`\n * hook merges this subset-keyed result with the approval-side denied\n * entries (1:1 with the model's ORIGINAL `edits` list) before the\n * canonical `<edit-outcomes>` block lands on the wire — see\n * `mergeApprovalAndBodyOutcomes` in `chat/edit-approval.ts`.\n *\n * Wire / replay format (see `parseEditOutcomesFromResult`):\n *\n * Edited <path>: applied N of M edits (R replacements).\n * edit #2 failed: old_string not found in <path>.\n *\n * <edit-outcomes>\n * #1 applied\n * #2 failed: old_string not found in <path>\n * #3 applied\n * </edit-outcomes>\n *\n * The annotation is omitted entirely on the all-applied path — the\n * renderer's `isEditErrorResult` check then suppresses the paired\n * `tool-result` so the diff stands alone (existing behavior).\n */\n\ninterface EditStep {\n old_string: string\n new_string: string\n replace_all?: boolean\n}\n\ninterface StepOutcome {\n kind: 'applied' | 'failed'\n reason?: string\n}\n\n/**\n * Inline annotation builder — kept local to avoid importing from\n * `chat/edit-approval.ts` (that's a renderer-side module; tools live\n * one layer below). Line shape matches `parseEditOutcomesFromResult`'s\n * regex so the round-trip is lossless.\n *\n * Newlines in `reason` are folded to spaces because the parser is line-\n * scoped (`body.split('\\n')`); a multi-line reason would split into a\n * \"trailing prose\" line and trip the malformed-block guard, losing every\n * outcome below it. Static reasons in this file are single-line; the\n * sanitize is a guard against a pathological `target` (file path\n * containing a newline) leaking into `old_string not found in <target>`.\n */\nfunction annotationFor(outcomes: readonly StepOutcome[]): string {\n const lines = ['<edit-outcomes>']\n for (let i = 0; i < outcomes.length; i++) {\n const o = outcomes[i]\n const reason = o.reason ? `: ${o.reason.replace(/\\r?\\n/g, ' ')}` : ''\n lines.push(`#${i + 1} ${o.kind}${reason}`)\n }\n lines.push('</edit-outcomes>')\n return lines.join('\\n')\n}\n\nexport const multiEdit: ToolDef = {\n spec: {\n name: 'multi_edit',\n description: 'Apply a sequential list of edits to a file. Each edit operates on the result of the previous APPLIED edit. Prefer this over multiple `edit` calls when several non-overlapping changes are needed in the same file. Edits run **best-effort**: a per-step failure (`old_string` not found, ambiguous match without `replace_all`, identical strings) is reported in the result but does NOT block the remaining steps. The file is written iff at least one step applied. The result lists per-hunk outcomes (`applied` / `failed`) so the model can re-issue just the failures without resending the whole batch. Each step tolerates `read_file` line-number prefixes (`<N>\\\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`.',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path (relative to the execution-context cwd, or absolute).' },\n edits: {\n type: 'array',\n description: 'List of edits applied in order; each operates on the previous applied edit\\'s output.',\n items: {\n type: 'object',\n properties: {\n old_string: { type: 'string' },\n new_string: { type: 'string' },\n replace_all: { type: 'boolean' },\n },\n required: ['old_string', 'new_string'],\n },\n },\n },\n required: ['path', 'edits'],\n },\n },\n async execute({ path, edits }, ctx: ToolContext) {\n const target = path as string\n const steps = edits as EditStep[]\n\n const pathErr = pathArgError(target)\n if (pathErr) {\n ctx.reportOutcome?.('failed')\n return `multi_edit error: ${pathErr}`\n }\n\n if (!Array.isArray(steps) || steps.length === 0) {\n ctx.reportOutcome?.('failed')\n return `multi_edit error: edits must be a non-empty array.`\n }\n\n let current: string\n try {\n current = await ctx.execution.readFile(ctx.handle, target)\n }\n catch {\n const hint = await suggestionFor(ctx.execution, ctx.handle, target)\n ctx.reportOutcome?.('failed')\n return `multi_edit error: file not found: ${target}.${hint}`\n }\n\n // Read-before-edit guard — see the matching block in `src/tools/\n // edit.ts` for the rationale and the no-read-state-map fall-through.\n if (ctx.behavior?.requireReadBeforeEdit) {\n const readState = resolveReadStateMap(ctx)\n if (readState) {\n const absKey = readStateKey(ctx.handle.cwd, target)\n const prior = readState.get(absKey)\n if (!prior) {\n ctx.reportOutcome?.('failed')\n return `multi_edit error: ${target} has not been read in this session. Call read_file first so the edits apply against the current contents.`\n }\n if (prior.contentHash !== hashContent(current)) {\n ctx.reportOutcome?.('failed')\n return `multi_edit error: ${target} has changed on disk since the last read. Re-read the file before editing.`\n }\n }\n }\n\n const outcomes: StepOutcome[] = []\n // Non-exact recovery notes (one per step that matched via a fallback) —\n // kept OUT of the `<edit-outcomes>` annotation block, whose line format\n // is parsed strictly by `parseEditOutcomesFromResult`.\n const viaNotes: string[] = []\n let totalReplacements = 0\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const find = step.old_string\n const replacement = step.new_string\n const replaceAll = step.replace_all === true\n\n if (typeof find !== 'string' || typeof replacement !== 'string') {\n outcomes.push({ kind: 'failed', reason: 'missing old_string or new_string' })\n continue\n }\n\n if (find.length === 0) {\n outcomes.push({ kind: 'failed', reason: 'empty old_string (use write_file to fully replace a file)' })\n continue\n }\n\n if (find === replacement) {\n outcomes.push({ kind: 'failed', reason: 'old_string and new_string are identical' })\n continue\n }\n\n const match = resolveOldString(current, find)\n if (!match) {\n outcomes.push({ kind: 'failed', reason: `old_string not found in ${target}` })\n continue\n }\n\n const { actual, occurrences, via } = match\n if (occurrences > 1 && !replaceAll) {\n outcomes.push({\n kind: 'failed',\n reason: `old_string appears ${occurrences} times — pass replace_all=true on this edit or expand old_string for uniqueness`,\n })\n continue\n }\n\n const styledReplacement = styleReplacementForVia(replacement, via, actual)\n current = replaceAll\n ? current.split(actual).join(styledReplacement)\n : current.replace(actual, styledReplacement)\n totalReplacements += occurrences\n if (via !== 'exact')\n viaNotes.push(`edit #${i + 1}: old_string was not found verbatim; matched via ${describeVia(via)}`)\n outcomes.push({ kind: 'applied' })\n }\n\n const appliedCount = outcomes.reduce((n, o) => o.kind === 'applied' ? n + 1 : n, 0)\n const failedCount = outcomes.length - appliedCount\n\n // Skip the write when nothing changed. Preserves mtime so a partner\n // process watching the file doesn't see a phantom touch on a fully-\n // failed batch.\n if (appliedCount > 0) {\n await ctx.execution.writeFile(ctx.handle, target, current)\n // Reported only AFTER the write lands — a throwing `writeFile` falls\n // through to the loop's error path, which must not see a stale `edited`.\n ctx.reportOutcome?.('edited')\n\n // Bring the tracked hash forward so a follow-up edit on the same\n // file doesn't trip the drift branch on freshly-rewritten bytes.\n const readState = resolveReadStateMap(ctx)\n if (readState) {\n const absKey = readStateKey(ctx.handle.cwd, target)\n const prior = readState.get(absKey)\n if (prior)\n readState.set(absKey, { ...prior, contentHash: hashContent(current), mtimeMs: Date.now() })\n }\n }\n else {\n // No edit applied — nothing reached disk.\n ctx.reportOutcome?.('failed')\n }\n\n const n = steps.length\n\n // Header shape — three branches, each chosen for renderer + model\n // legibility:\n //\n // - All applied → legacy \"Edited X: applied N edits (R replacements).\"\n // so the renderer's `isEditErrorResult` keeps suppressing the\n // paired tool-result (the diff stands alone on a clean success).\n // - Mixed → \"Edited X: applied N of M edits (R replacements).\"\n // plus per-failure lines + `<edit-outcomes>` block.\n // - All failed → \"multi_edit error: no edits applied to X (M attempted).\"\n // keeps the legacy \"multi_edit error:\" prefix so anything that\n // pattern-matched on it (renderer visibility branch, status\n // ribbons, log filters) keeps working.\n let header: string\n if (appliedCount === n) {\n header = `Edited ${target}: applied ${n} edit${n === 1 ? '' : 's'} (${totalReplacements} replacement${totalReplacements === 1 ? '' : 's'}).`\n }\n else if (appliedCount > 0) {\n header = `Edited ${target}: applied ${appliedCount} of ${n} edits (${totalReplacements} replacement${totalReplacements === 1 ? '' : 's'}).`\n }\n else {\n header = `multi_edit error: no edits applied to ${target} (${n} attempted).`\n }\n\n const failureLines: string[] = []\n for (let i = 0; i < outcomes.length; i++) {\n const o = outcomes[i]\n if (o.kind === 'failed')\n failureLines.push(`edit #${i + 1} failed: ${o.reason}`)\n }\n\n // Annotation is the body's side-channel for replay + chat-layer\n // merge. Omit on the all-applied happy path so the renderer can\n // continue to hide the paired tool-result; emit whenever any step\n // failed so the chat layer + replay can paint per-hunk badges.\n const parts = [header]\n if (viaNotes.length > 0)\n parts.push(viaNotes.join('\\n'))\n if (failureLines.length > 0)\n parts.push(failureLines.join('\\n'))\n if (failedCount > 0)\n parts.push(annotationFor(outcomes))\n return parts.join('\\n\\n')\n },\n}\n","/**\n * Binary-aware file read for the `read_file` tool.\n *\n * Dispatches to `ExecutionContext.readFileBinary` when implemented; otherwise\n * shells out via `base64 < path` so docker / sandbox contexts don't have to\n * implement a custom primitive. The shell fallback is portable (busybox /\n * coreutils / macOS all ship `base64`) and only fires when the native path\n * is unavailable.\n *\n * Returns a base64 string ready to drop into a `ToolResultContent` image\n * block. Raises on read failure — caller is responsible for catching and\n * formatting the error message.\n */\n\nimport type { ExecutionContext, ExecutionHandle } from '../contexts'\nimport { Buffer } from 'node:buffer'\nimport { alwaysQuote } from './shell-quote'\n\n/**\n * Best-effort guess at IANA media type from a file extension. Covers the\n * extensions Zidane's `read_file` actually dispatches to image blocks\n * (png/jpg/jpeg/gif/webp). Other extensions return `undefined` and the\n * caller short-circuits the binary route.\n */\nexport function imageMediaTypeFor(path: string): string | undefined {\n const dot = path.lastIndexOf('.')\n if (dot === -1)\n return undefined\n const ext = path.slice(dot + 1).toLowerCase()\n switch (ext) {\n case 'png':\n return 'image/png'\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg'\n case 'gif':\n return 'image/gif'\n case 'webp':\n return 'image/webp'\n default:\n return undefined\n }\n}\n\n/**\n * Read a file as base64. Prefers `ExecutionContext.readFileBinary` (zero\n * subprocess overhead in-process) and falls back to `base64 < path` via\n * the shell seam — works on docker / sandbox without an interface change.\n *\n * Returns `{ base64, byteLength }`. `byteLength` is the *decoded* byte count\n * so callers can size-budget against the original file, not the inflated\n * base64 representation (which is ~4/3× larger).\n */\nexport async function readFileAsBase64(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n path: string,\n): Promise<{ base64: string, byteLength: number }> {\n if (execution.readFileBinary) {\n const bytes = await execution.readFileBinary(handle, path)\n const b64 = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64')\n return { base64: b64, byteLength: bytes.byteLength }\n }\n\n // Shell fallback. Use `base64 -i` on macOS-style implementations; the\n // GNU/coreutils form just takes the path positionally. Try both.\n // `2>/dev/null` swallows the macOS warning when the GNU form is used on\n // a system without `-i`.\n const cmd = `base64 < ${alwaysQuote(path)}`\n const result = await execution.exec(handle, cmd)\n if (result.exitCode !== 0)\n throw new Error(`base64 read failed: ${result.stderr || `exit ${result.exitCode}`}`)\n // `base64` may emit line-wrapped output (76-col default); strip whitespace.\n const b64 = result.stdout.replace(/\\s+/g, '')\n return { base64: b64, byteLength: decodedBase64ByteLength(b64) }\n}\n\n/**\n * Decoded byte length of a (whitespace-stripped) base64 string. Accounts for\n * `=` padding so the value matches the original file size to the byte —\n * `Math.floor(len * 3 / 4)` over-reports by 1–2 bytes on padded payloads.\n */\nfunction decodedBase64ByteLength(b64: string): number {\n if (b64.length === 0)\n return 0\n let pad = 0\n if (b64.endsWith('=='))\n pad = 2\n else if (b64.endsWith('='))\n pad = 1\n return Math.max(0, (b64.length * 3) / 4 - pad)\n}\n","import type { ToolResultContent } from '../types'\nimport type { ToolContext, ToolDef } from './types'\nimport { Buffer } from 'node:buffer'\nimport { parseAttachmentHandle, resolveAttachmentFromTurns } from '../attachment-handle'\nimport { normalizeReadFileInteger, resolveReadFileDefaults } from '../behaviors/read-file-defaults'\nimport { errorMessage } from '../errors'\nimport { looksBinary } from './binary-detect'\nimport { imageMediaTypeFor, readFileAsBase64 } from './binary-read'\nimport { reconcileImageMediaType } from './media-sniff'\nimport { suggestionFor } from './path-suggest'\nimport { hashContent, readStateKey, resolveReadStateMap } from './read-state'\nimport { pathArgError } from './validation'\n\n/**\n * Read a file with line-based offset/limit and a hard byte cap.\n *\n * Defaults are tuned for source code: 2000 lines / 256 KiB. A typical source\n * file, lockfile, or large config fits in one read; logs and very large\n * fixtures get truncated with a footer that documents how to fetch the\n * remainder.\n *\n * Binary files are detected on the leading bytes — if the buffer contains a\n * NUL or has an unreasonable proportion of non-printable bytes, we skip text\n * decoding and return a marker so the model doesn't drown in mojibake.\n */\n\nconst DEFAULT_LINE_LIMIT = 2000\nconst DEFAULT_BYTE_CAP = 262_144\n\n/**\n * Hard upper bound on raw attachment bytes we'll inline as a base64 block.\n * Above this, we return a marker instead — the model won't get useful\n * information from a 10 MB+ screenshot rendered as one tool result, and\n * the wire bill gets ugly. Override via the `maxBytes` parameter on the\n * tool call.\n */\nconst DEFAULT_ATTACHMENT_BYTE_CAP = 5 * 1024 * 1024\n\nfunction attachmentByteLength(data: string, encoding?: 'base64' | 'text'): number {\n if (encoding === 'text')\n return Buffer.byteLength(data)\n if (data.length === 0)\n return 0\n const pad = data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0\n return Math.max(0, Math.floor((data.length * 3) / 4) - pad)\n}\n\nexport const readFile: ToolDef = {\n // Pure read — fans out in parallel with other concurrency-safe siblings\n // up to `behavior.maxConcurrentTools`.\n isConcurrencySafe: true,\n spec: {\n name: 'read_file',\n description: 'Read a file by path. Text files return lines [offset..offset+limit). Default offset=1, limit=2000. Each line is prefixed with its 1-indexed line number followed by a tab (e.g. `42\\\\tconst foo = bar`); the prefix is metadata, not part of the file. Mirrors Claude Code\\'s `cat -n`-style compact output for token efficiency. A trailing footer explains how to read the rest when truncated. Images (png/jpg/gif/webp) and PDFs return structured attachments for capable models; other binary files return a short marker rather than mojibake.',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path (relative to the execution-context cwd, or absolute).' },\n offset: { type: 'integer', description: '1-indexed line number to start from. Default: 1.' },\n limit: { type: 'integer', description: 'Max lines to return. Default: 2000. Set 0 for unlimited.' },\n maxBytes: { type: 'integer', description: 'Hard byte cap on file content read, regardless of line count. Default: 262144 for text, 5242880 for image/PDF attachments. Set 0 for unlimited. The rendered output may be slightly larger than this cap when `lineNumbers` is on (each line carries a `<N>\\\\t` prefix).' },\n lineNumbers: { type: 'boolean', description: 'Prefix each line with its 1-indexed line number. Default: true. Override the agent-wide `behavior.readLineNumbers` for this call.' },\n },\n required: ['path'],\n },\n },\n async execute({ path, offset, limit, maxBytes, lineNumbers }, ctx: ToolContext) {\n const defaults = resolveReadFileDefaults(ctx.behavior, {\n lineLimit: DEFAULT_LINE_LIMIT,\n textMaxBytes: DEFAULT_BYTE_CAP,\n attachmentMaxBytes: DEFAULT_ATTACHMENT_BYTE_CAP,\n })\n // Attachment re-resolve: `read_file path=\"attachment://<hash>\"` pulls an\n // aged-out image/document back from session history (see media age-out in\n // the loop). Branch before the filesystem-path checks — the handle is not a\n // real path. Re-inlines the bytes for THIS turn only; they age out again on\n // the natural schedule.\n const handleHash = typeof path === 'string' ? parseAttachmentHandle(path) : null\n if (handleHash) {\n const turns = ctx.session?.turns\n if (!turns)\n return `Attachment ${path} cannot be resolved: no session is bound to this run.`\n const found = resolveAttachmentFromTurns(turns, handleHash)\n if (!found)\n return `Attachment ${path} not found in this session's history (it may predate this session, or only ever lived as a host-offloaded reference).`\n const sizeCap = normalizeReadFileInteger(maxBytes, defaults.attachmentMaxBytes)\n const byteLength = attachmentByteLength(found.data, found.encoding)\n if (sizeCap > 0 && byteLength > sizeCap)\n return `[attachment too large to re-inline: ${path}, ${byteLength} bytes (cap ${sizeCap}). Raise maxBytes if you need the original bytes.]`\n const label = found.kind === 'image' ? 'Image' : 'Document'\n const content: ToolResultContent[] = [\n { type: 'text', text: `${label} re-resolved from session history (${found.mediaType}${found.name ? `, \"${found.name}\"` : ''}).` },\n found.kind === 'image'\n ? { type: 'image', mediaType: found.mediaType, data: found.data, ...(found.name ? { name: found.name } : {}) }\n : { type: 'document', mediaType: found.mediaType, data: found.data, encoding: found.encoding ?? 'base64', ...(found.name ? { name: found.name } : {}) },\n ]\n return content\n }\n\n // Reasoning-leak backstop — see `pathArgError`.\n const pathErr = pathArgError(path as string)\n if (pathErr)\n return `Read error: ${pathErr}`\n\n // Image dispatch — vision-aware models can answer questions directly\n // against the image bytes; non-vision models get the marker substitution\n // applied later in the loop (`stripImagesForNonVision`). Skips the line-\n // based read entirely. Gated on extension first (cheap), then reconciled\n // against magic bytes — Anthropic rejects the whole request when the\n // declared `media_type` disagrees with the actual bytes (e.g. a JPEG\n // saved with a `.webp` extension).\n const extMedia = imageMediaTypeFor(path as string)\n if (extMedia) {\n const sizeCap = normalizeReadFileInteger(maxBytes, defaults.attachmentMaxBytes)\n try {\n const { base64, byteLength } = await readFileAsBase64(ctx.execution, ctx.handle, path as string)\n if (sizeCap > 0 && byteLength > sizeCap) {\n return `[image too large to inline: ${path}, ${byteLength} bytes (cap ${sizeCap}). Raise maxBytes, or use shell to inspect.]`\n }\n const imgMedia = reconcileImageMediaType(extMedia, base64)\n const content: ToolResultContent[] = [\n { type: 'text', text: `Image: ${path} (${byteLength} bytes, ${imgMedia})` },\n { type: 'image', mediaType: imgMedia, data: base64 },\n ]\n return content\n }\n catch (err) {\n const hint = await suggestionFor(ctx.execution, ctx.handle, path as string)\n return `Image read failed: ${path} — ${errorMessage(err)}.${hint}`\n }\n }\n\n const docMedia = documentMediaTypeFor(path as string)\n if (docMedia) {\n const sizeCap = normalizeReadFileInteger(maxBytes, defaults.attachmentMaxBytes)\n try {\n const { base64, byteLength } = await readFileAsBase64(ctx.execution, ctx.handle, path as string)\n if (sizeCap > 0 && byteLength > sizeCap) {\n return `[document too large to attach: ${path}, ${byteLength} bytes (cap ${sizeCap}). Raise maxBytes, or use shell/read text extraction to inspect.]`\n }\n if (docMedia === 'application/pdf' && !isPdfBase64(base64)) {\n return `[binary file: ${path}, ${byteLength} bytes; extension suggests PDF but file header does not start with %PDF-]`\n }\n const content: ToolResultContent[] = [\n { type: 'text', text: `Document: ${path} (${byteLength} bytes, ${docMedia})` },\n { type: 'document', mediaType: docMedia, data: base64, encoding: 'base64', name: fileNameForPath(path as string) },\n ]\n return content\n }\n catch (err) {\n const hint = await suggestionFor(ctx.execution, ctx.handle, path as string)\n return `Document read failed: ${path} — ${errorMessage(err)}.${hint}`\n }\n }\n\n let raw: string\n try {\n raw = await ctx.execution.readFile(ctx.handle, path as string)\n }\n catch {\n const hint = await suggestionFor(ctx.execution, ctx.handle, path as string)\n return `File not found: ${path}.${hint}`\n }\n\n const totalBytes = Buffer.byteLength(raw)\n\n // Read-state tracking + per-session dedup. Tracking populates the\n // map so `requireReadBeforeEdit` can confirm the model has seen\n // the file; dedup decides whether identical re-reads should\n // short-circuit to a \"still current\" stub. The two are\n // INDEPENDENT — turning off dedup must NOT also break the gate.\n //\n // Tracking runs whenever either feature is enabled (or by default,\n // since dedup defaults on); dedup short-circuit only fires when\n // `dedupReads` is explicitly on. Costs nothing when no session is\n // bound (direct/standalone tool invocations).\n //\n // The hash is taken on the *raw* file before any truncation so a\n // future read with a wider slice still invalidates the prior\n // stub-eligible entry — re-emitting the freshly-included bytes.\n const dedupEnabled = ctx.behavior?.dedupReads !== false\n const gateEnabled = ctx.behavior?.requireReadBeforeEdit === true\n const trackingEnabled = dedupEnabled || gateEnabled\n const readState = trackingEnabled ? resolveReadStateMap(ctx) : undefined\n const absKey = readStateKey(ctx.handle.cwd, path as string)\n const offsetForKey = normalizeReadFileInteger(offset, 1)\n const limitForKey = normalizeReadFileInteger(limit, defaults.lineLimit)\n const maxBytesForKey = normalizeReadFileInteger(maxBytes, defaults.textMaxBytes)\n const showLineNumbers = typeof lineNumbers === 'boolean'\n ? lineNumbers\n : (ctx.behavior?.readLineNumbers ?? true)\n const currentHash = readState ? hashContent(raw) : ''\n const rememberRead = () => {\n if (!readState)\n return\n readState.set(absKey, {\n contentHash: currentHash,\n offset: offsetForKey,\n limit: limitForKey,\n maxBytes: maxBytesForKey,\n lineNumbers: showLineNumbers,\n mtimeMs: Date.now(),\n })\n }\n if (dedupEnabled && readState) {\n const prior = readState.get(absKey)\n if (\n prior\n && prior.contentHash === currentHash\n && prior.offset === offsetForKey\n && prior.limit === limitForKey\n && prior.maxBytes === maxBytesForKey\n // Toggling `lineNumbers` between reads must miss dedup: the stub\n // claims \"the prior result is still current\", but the prior\n // output was a different shape — the model would draw bogus\n // conclusions if we replayed it.\n && prior.lineNumbers === showLineNumbers\n // Stale-read elision removed the prior output from the on-wire\n // history — the stub would point at content the model can no\n // longer see. Serve the full body; `rememberRead` clears the flag.\n && prior.elided !== true\n ) {\n // A dedup hit still represents an intentional re-read. Refresh the\n // tracking entry so `requireReadBeforeEdit` sees the re-read even\n // though we keep the token-saving stub output.\n //\n // This stub only fires when the prior output is still on the wire:\n // every elision path (stale-read elision, tail compaction) flips the\n // entry's `elided` flag, which the guard above checks so a re-read of\n // compacted-away content MISSES dedup and re-serves the full body.\n // So we deliberately do NOT tell the model to \"re-read with a\n // different offset/limit\" — that advice, when the content was already\n // gone, drove an infinite offset-cycling re-read loop.\n rememberRead()\n return `File ${path} unchanged since the previous read in this session — the prior result above is still current, so this duplicate read was skipped to save tokens.`\n }\n }\n\n // Cheap binary detection on a leading sample. ExecutionContext.readFile\n // returns UTF-8-decoded text already — but if the underlying file was\n // binary, the decode replaces invalid sequences with U+FFFD. Use a NUL\n // byte and replacement-char ratio in the sample as a heuristic.\n if (looksBinary(raw)) {\n return `[binary file: ${path}, ${totalBytes} bytes; use shell with hexdump | xxd | od to inspect]`\n }\n\n const offsetN = offsetForKey\n const limitN = limitForKey\n const maxBytesN = maxBytesForKey\n\n const lines = raw.split('\\n')\n const totalLines = lines.length\n\n // 1-indexed offset → 0-indexed slice start.\n const startIdx = Math.max(0, offsetN - 1)\n const endIdx = limitN > 0 ? Math.min(totalLines, startIdx + limitN) : totalLines\n let slice = lines.slice(startIdx, endIdx)\n\n // Apply byte cap at the line boundary. Walk lines, accumulating bytes; cut\n // just below the cap. The \"truncatedSlice.length > 0\" guard ensures we\n // always emit at least one line — files with a single oversized line would\n // otherwise return empty. The single-line overflow gets handled by the\n // hard-cap pass below.\n let bytesCut = false\n if (maxBytesN > 0) {\n const truncatedSlice: string[] = []\n let bytesUsed = 0\n for (const line of slice) {\n const lineBytes = Buffer.byteLength(line) + 1 // +1 for the '\\n' rejoin\n if (bytesUsed + lineBytes > maxBytesN && truncatedSlice.length > 0) {\n bytesCut = true\n break\n }\n truncatedSlice.push(line)\n bytesUsed += lineBytes\n if (bytesUsed >= maxBytesN) {\n // Budget consumed — keep this line, stop here.\n break\n }\n }\n if (truncatedSlice.length < slice.length)\n bytesCut = true\n slice = truncatedSlice\n }\n\n // Hard-cap pass: when the line-boundary loop had to admit an oversized line\n // (single huge line, or first line ≥ maxBytes), the body still exceeds the\n // budget. Truncate the last line at a UTF-8-safe boundary and flag it as a\n // mid-line cut so the footer can warn the reader that offset+1 won't pick\n // up where this read left off.\n let midLineCut = false\n if (maxBytesN > 0 && slice.length > 0) {\n const bodyBytes = Buffer.byteLength(slice.join('\\n'))\n if (bodyBytes > maxBytesN) {\n const lastIdx = slice.length - 1\n const lastLine = slice[lastIdx]\n const otherBytes = lastIdx > 0\n ? Buffer.byteLength(slice.slice(0, lastIdx).join('\\n')) + 1 // +1 for the joining '\\n'\n : 0\n const budgetForLast = Math.max(0, maxBytesN - otherBytes)\n // Estimate cut at char count = byte budget (correct for ASCII), then\n // walk back if the resulting prefix still overflows because of multi-\n // byte codepoints. Worst case ~3 iterations (max UTF-8 width is 4).\n let cut = Math.min(lastLine.length, budgetForLast)\n while (cut > 0 && Buffer.byteLength(lastLine.slice(0, cut)) > budgetForLast)\n cut--\n slice[lastIdx] = lastLine.slice(0, cut)\n midLineCut = true\n bytesCut = true\n }\n }\n\n const linesReturned = slice.length\n const lastLineRead = startIdx + linesReturned\n\n // Line numbers default on. Format: `<line-no>\\t<content>` — bare digit,\n // tab separator, no padding. Matches Claude Code's compact `cat -n`\n // output for token efficiency (~5 chars saved per line vs. padded\n // forms). Models treat the prefix as metadata; `edit` strips it from\n // `old_string` when the model pastes a numbered chunk back, and also\n // accepts `<N>|<content>` / `<N>→<content>` for cross-stack tolerance.\n const body = showLineNumbers\n ? slice.map((line, i) => `${startIdx + i + 1}\\t${line}`).join('\\n')\n : slice.join('\\n')\n\n rememberRead()\n\n const linesTruncated = endIdx < totalLines || bytesCut\n if (!linesTruncated && offsetN === 1)\n return body\n\n if (!linesTruncated) {\n // Reading from a non-1 offset; tell the model where the read started.\n return `${body}\\n\\n…read lines ${offsetN}-${lastLineRead} of ${totalLines}.`\n }\n\n if (midLineCut) {\n // Line N was only partially read, so offset=N+1 would skip the unread\n // portion — we don't suggest it. Raising maxBytes is the only lossless\n // way forward. Avoid suggesting shell+sed/awk slicing here: that primes\n // a debugging anti-pattern where the model loops on narrow shell probes\n // instead of using paginated read_file calls.\n return `${body}\\n\\n…truncated mid-line at line ${lastLineRead} (byte cap ${maxBytesN} reached). File has ${totalLines} lines, ${totalBytes} bytes total. Raise maxBytes to read the full line.`\n }\n\n const reason = bytesCut ? `byte cap (${maxBytesN}) reached` : `line limit (${limitN}) reached`\n return `${body}\\n\\n…truncated at line ${lastLineRead} (${reason}). File has ${totalLines} lines, ${totalBytes} bytes total — re-read with offset=${lastLineRead + 1} to continue.`\n },\n}\n\nfunction documentMediaTypeFor(path: string): string | undefined {\n const dot = path.lastIndexOf('.')\n if (dot === -1)\n return undefined\n const ext = path.slice(dot + 1).toLowerCase()\n return ext === 'pdf' ? 'application/pdf' : undefined\n}\n\nfunction fileNameForPath(path: string): string {\n const normalized = path.replace(/\\\\/g, '/')\n const slash = normalized.lastIndexOf('/')\n return slash === -1 ? normalized : normalized.slice(slash + 1)\n}\n\nfunction isPdfBase64(base64: string): boolean {\n return Buffer.from(base64.slice(0, 16), 'base64').toString('ascii').startsWith('%PDF-')\n}\n","/**\n * `shell_kill` — terminate a running background task by id.\n *\n * Companion to the `shell` tool's `run_in_background: true` mode. The\n * model receives a `task_id` when it spawns a background task; this\n * tool routes a kill request through `ExecutionContext.killBackground`,\n * which SIGTERMs the whole process group (the foreground `exec`\n * implementation already documents the kill-tree rationale).\n *\n * The successful kill ALSO suppresses the would-be `<task-notification>`\n * on the next turn — the agent's `tool:after` listener (see\n * `src/agent.ts`'s notification-suppression block) deletes the pending\n * entry by `task_id`. Without that, the model would get the kill result\n * inline AND a redundant notification on its next prompt.\n */\n\nimport type { ToolContext, ToolDef } from './types'\nimport { formatDuration, formatTaskStatus, previewLine } from '../chat/format'\n\nexport const shellKill: ToolDef = {\n // Concurrency-safe — pure SIGTERM dispatch, no shared mutable state\n // beyond the per-context registry which is atomic.\n isConcurrencySafe: true,\n spec: {\n name: 'shell_kill',\n description: [\n 'Terminate a running background task started by `shell({ run_in_background: true })`.',\n 'Sends SIGTERM to the whole process group so the shell wrapper AND its child commands die together.',\n 'Returns the final exit info (status, exit code, output path) or a \"no such task\" message when the id is unknown / already cleaned up.',\n 'Idempotent — calling on a task that has already terminated returns the cached exit info without re-killing.',\n ].join('\\n'),\n inputSchema: {\n type: 'object',\n properties: {\n task_id: { type: 'string', description: 'The task id returned by a prior `shell({ run_in_background: true })` call.' },\n },\n required: ['task_id'],\n additionalProperties: false,\n },\n },\n async execute(input, ctx: ToolContext): Promise<string> {\n const taskId = input.task_id as string\n\n if (!ctx.execution.killBackground) {\n return `shell_kill error: the active execution context (${ctx.execution.type}) does not support background tasks.`\n }\n\n const info = await ctx.execution.killBackground(ctx.handle, taskId)\n if (!info) {\n return `shell_kill: no such task \"${taskId}\". It may have already exited and been cleaned up, or it was never started in this session.`\n }\n\n return [\n `Killed ${info.taskId} — ${formatTaskStatus(info)} after ${formatDuration(info.durationMs)}.`,\n ` command: ${previewLine(info.command, 60)}`,\n ` output: ${info.outputPath}`,\n ].join('\\n')\n },\n}\n","/**\n * Spawn tool — create sub-agents from a parent agent.\n *\n * A configurable factory that reads the parent's preset-y fields from ToolContext.\n *\n * Usage:\n * ```ts\n * import { createSpawnTool } from 'zidane'\n * import { definePreset, basicTools } from 'zidane/presets'\n *\n * const preset = definePreset({\n * name: 'orchestrator',\n * tools: { ...basicTools, spawn: createSpawnTool({ maxConcurrent: 5 }) },\n * })\n * ```\n *\n * Each `createSpawnTool()` call returns a fresh instance with its own\n * concurrency counter, depth cap, and child-stats accumulator — never\n * share an instance across unrelated parent agents.\n *\n * Key guarantees:\n * - **Depth-capped** to `maxDepth` (default 3) to prevent infinite recursion.\n * - **Concurrency slot is reserved synchronously** before any `await`, so a\n * parent running tools in parallel cannot exceed `maxConcurrent`.\n * - **Pre-aborted signals short-circuit** without paying agent-spawn cost.\n * - **Abort / timeout / error are surfaced distinctly** in the returned text\n * and via `ChildRunStats.status` on `spawn:complete`.\n * - **`agent.destroy()` errors never mask the original run error** (captured\n * and emitted via `spawn:error` but the primary error wins).\n * - **Child hooks bubble** to the parent as `child:*` events when\n * `forwardHooks` is set (default `true`).\n * - **Persistence** via `persist: true` — child runs get appended to the\n * parent's session with `parentRunId` wired, so the run tree is\n * reconstructible from a stored `SessionData`.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { AgentHooks } from '../agent'\nimport type { Preset } from '../presets'\nimport type { Session } from '../session'\nimport type { AgentStats, ChildRunStats } from '../types'\nimport type { ToolContext, ToolDef } from './types'\nimport { createAgent } from '../agent'\nimport { flattenTurns, formatTokenUsage } from '../stats'\nimport { resolveReadStateMap } from './read-state'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ChildAgent {\n id: string\n task: string\n startedAt: number\n /** Subagent depth — 1 for a direct child of a top-level agent. */\n depth: number\n}\n\nexport interface SpawnToolState {\n /** Currently running children. */\n readonly children: ReadonlyMap<string, ChildAgent>\n /**\n * Cumulative stats across every completed direct child of this spawn-tool\n * instance (returns a copy). Each child's contribution is the cumulative\n * `AgentStats` returned by its `agent.run()` — so\n * `totalIn`/`totalOut`/`totalCacheRead`/`totalCacheCreation` cover the\n * entire subtree (children + grandchildren + …), while `turns` and\n * `elapsed` stay parent-loop-only per child and are summed across direct\n * children. `elapsed` over-counts when children ran in parallel.\n *\n * Lives across multiple parent runs that share this instance.\n */\n readonly totalChildStats: Readonly<AgentStats>\n}\n\n// ---------------------------------------------------------------------------\n// Events to bubble from child → parent. Keep these lists small: the goal is\n// to give the parent a usable live-tail (and a place to gate child calls)\n// without drowning it in telemetry.\n//\n// Two kinds:\n// - {@link BUBBLED_EVENTS} — observational. Forwarded as a spread copy so\n// the parent's listeners can't accidentally mutate the child's ctx.\n// - {@link BUBBLED_GATE_EVENTS} — gates. Forwarded with the SAME ctx\n// reference so parent listeners can set `block` / `reason` / `result`\n// and have those mutations land on the gate the child's loop is\n// awaiting on.\n// ---------------------------------------------------------------------------\n\nconst BUBBLED_EVENTS = [\n 'stream:text',\n 'stream:thinking',\n 'stream:end',\n 'stream:error',\n 'stream:server_tool_use',\n 'stream:server_tool_result',\n 'tool:dispatched',\n 'tool:before',\n 'tool:after',\n 'tool:error',\n 'tool:cancelled',\n 'background:start',\n 'background:exit',\n 'background:reassign',\n 'turn:after',\n] as const\n\n// Same-ref bubble — parent listener mutations propagate back into the\n// child's loop. Content-ref resolution (`data`), gate hooks (`block` /\n// `result`), and `tool:transform` (`result` rewrite) need this so parent\n// policy lands on the child's wire-level request/result.\nconst BUBBLED_MUTABLE_EVENTS = [\n 'content-ref:resolve',\n 'tool:gate',\n 'mcp:tool:gate',\n 'tool:transform',\n] as const\n\ntype BubbledEvent = typeof BUBBLED_EVENTS[number]\ntype BubbledMutableEvent = typeof BUBBLED_MUTABLE_EVENTS[number]\n\n// Mapping from a bubbled event to its corresponding `child:*` event. Kept as\n// an explicit table (rather than a computed `child:${evt}` template literal)\n// so AgentHooks can type each entry independently.\nconst CHILD_EVENT_NAME: Record<BubbledEvent, keyof AgentHooks> = {\n 'stream:text': 'child:stream:text',\n 'stream:thinking': 'child:stream:thinking',\n 'stream:end': 'child:stream:end',\n 'stream:error': 'child:stream:error',\n 'stream:server_tool_use': 'child:stream:server_tool_use',\n 'stream:server_tool_result': 'child:stream:server_tool_result',\n 'tool:dispatched': 'child:tool:dispatched',\n 'tool:before': 'child:tool:before',\n 'tool:after': 'child:tool:after',\n 'tool:error': 'child:tool:error',\n 'tool:cancelled': 'child:tool:cancelled',\n 'background:start': 'child:background:start',\n 'background:exit': 'child:background:exit',\n 'background:reassign': 'child:background:reassign',\n 'turn:after': 'child:turn:after',\n}\n\nconst CHILD_MUTABLE_EVENT_NAME: Record<BubbledMutableEvent, keyof AgentHooks> = {\n 'content-ref:resolve': 'content-ref:resolve',\n 'tool:gate': 'child:tool:gate',\n 'mcp:tool:gate': 'child:mcp:tool:gate',\n 'tool:transform': 'child:tool:transform',\n}\n\n// ---------------------------------------------------------------------------\n// Session-scoped child label counter\n//\n// The `child-N` label that surfaces in transcripts (and in the spawn tool's\n// return string) is allocated per-session — *seeded* from the persisted\n// run tree — rather than from a closure-local counter on the spawn-tool\n// instance. The reason: closure counters don't survive process restarts,\n// so a fresh CLI launch that reopens a session with two prior children\n// (`child-1`, `child-2`) would start its next spawn at `child-1` and\n// collide with the persisted labels. Anchoring on `session.runs.filter(\n// depth > 0).length` makes the live counter pick up exactly where the\n// reloaded transcript's labels left off — matching `eventsFromTurns`'s\n// chronological numbering on the read side.\n//\n// The WeakMap caches the counter for the lifetime of the `Session` object\n// after the first call so the read of `session.runs.length` only happens\n// once per session, even though spawns mutate `session.runs` mid-run.\n//\n// Sessionless agents (no `ctx.session`) fall back to `localCounter` — the\n// closure is the best we can do without a shared anchor.\n// ---------------------------------------------------------------------------\n\nconst sessionChildCounters = new WeakMap<Session, number>()\n\nfunction reserveChildLabel(session: Session): string {\n let counter = sessionChildCounters.get(session)\n if (counter === undefined)\n counter = session.runs.filter(r => (r.depth ?? 0) > 0).length\n counter += 1\n sessionChildCounters.set(session, counter)\n return `child-${counter}`\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction extractText(message: unknown): string {\n if (!message || typeof message !== 'object')\n return ''\n\n const msg = message as Record<string, unknown>\n\n if (typeof msg.content === 'string')\n return msg.content\n\n if (Array.isArray(msg.content)) {\n return msg.content\n .filter((block): block is Record<string, unknown> => !!block && typeof block === 'object' && (block as Record<string, unknown>).type === 'text')\n .map(block => block.text)\n .join('\\n')\n }\n\n return ''\n}\n\n/**\n * Read-only tool whitelist applied when a subagent preset has\n * `readonly: true` and no explicit `tools` list. Intentionally narrow —\n * only obviously non-mutating built-ins. Hosts wanting a different\n * read-only profile (e.g. include `glob` for a code-search agent) should\n * pass an explicit `tools` array on the subagent def.\n */\nconst READONLY_TOOL_DEFAULTS = ['read_file', 'grep', 'glob', 'list_files'] as const\n\n/**\n * Apply a subagent preset's tool filter to the parent's tool registry.\n * Always a strict subset of the input — the child agent never gains\n * tools the parent doesn't have. Names that don't match a parent tool\n * are silently dropped (matches MCP's lenient `enabledTools` behavior).\n *\n * Precedence: `def.tools` (explicit list) > `def.readonly: true`\n * (built-in read-only set) > unfiltered.\n */\nfunction filterToolsForSubagent(\n parentTools: Record<string, ToolDef> | undefined,\n def: SubagentDef,\n): Record<string, ToolDef> | undefined {\n if (!parentTools)\n return parentTools\n const explicit = def.tools\n // Match on `tool.spec.name` rather than the parent registry's object\n // key — registry keys are an implementation detail of the host\n // (`basicTools = { readFile, listFiles, ... }` uses camelCase JS\n // keys), but `spec.name` (`'read_file'`, `'list_files'`) is the\n // stable, documented, model-visible identifier hosts reason about.\n if (explicit && explicit.length > 0) {\n const wanted = new Set(explicit)\n const filtered: Record<string, ToolDef> = {}\n for (const [registryKey, t] of Object.entries(parentTools)) {\n if (wanted.has(t.spec.name))\n filtered[registryKey] = t\n }\n return filtered\n }\n if (def.readonly) {\n const wanted = new Set<string>(READONLY_TOOL_DEFAULTS)\n const filtered: Record<string, ToolDef> = {}\n for (const [registryKey, t] of Object.entries(parentTools)) {\n if (wanted.has(t.spec.name))\n filtered[registryKey] = t\n }\n return filtered\n }\n return parentTools\n}\n\n/**\n * Render the per-type descriptions into a single schema-field\n * description string the model reads when choosing a `subagent_type`.\n * Falls back to a generic line when the host didn't supply any per-type\n * descriptions.\n */\nfunction buildSubagentTypeDescription(registry: SubagentRegistry): string {\n const lines: string[] = []\n let hasAny = false\n for (const [key, def] of Object.entries(registry)) {\n if (def.description) {\n lines.push(`- \"${key}\": ${def.description}`)\n hasAny = true\n }\n else {\n lines.push(`- \"${key}\"`)\n }\n }\n lines.push('- \"general-purpose\": no specialization; uses the spawn tool\\'s default config.')\n if (!hasAny) {\n return `Optional subagent preset. One of: ${lines.map(l => l.replace(/^- /, '').replace(/:.*$/, '')).join(', ')}.`\n }\n return `Optional subagent preset that overlays the spawn tool's defaults.\\n${lines.join('\\n')}`\n}\n\n/**\n * Race `task` (an already-running child `agent.run()` promise) against a\n * timer. Does NOT race against the parent abort signal — the child agent\n * already observes the same signal internally and handles its own aborted\n * bookkeeping, so racing here would detach the spawn from the child's\n * session-persisting finally block.\n *\n * On timeout: rejects with `SpawnTimeoutError`; caller is expected to call\n * `agent.abort()` and subsequently `await` the original `task` so the\n * child's session state (runs, turns, status) gets flushed before the\n * parent moves on.\n */\nasync function raceWithTimeout<T>(\n task: Promise<T>,\n timeoutMs: number | undefined,\n): Promise<T> {\n if (!timeoutMs || timeoutMs <= 0)\n return task\n\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await new Promise<T>((resolve, reject) => {\n timer = setTimeout(() => reject(new SpawnTimeoutError(timeoutMs)), timeoutMs)\n task.then(resolve, reject)\n })\n }\n finally {\n if (timer)\n clearTimeout(timer)\n }\n}\n\nclass SpawnTimeoutError extends Error {\n readonly timeoutMs: number\n constructor(timeoutMs: number) {\n super(`Child agent timed out after ${timeoutMs}ms`)\n this.name = 'SpawnTimeoutError'\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Wire child's hooks to bubble into `parentHooks` as `child:*` events.\n *\n * Three kinds of forwarding:\n *\n * 1. **Originating observational events** (`stream:text`, `tool:before`, …)\n * → rewrite to the matching `child:*` event, inject `{ childId, depth }`,\n * fire on the parent's hook bus as a **spread copy** (so parent listeners\n * can't accidentally mutate the child's ctx).\n * 2. **Originating gate events** (`tool:gate`, `mcp:tool:gate`) → forward\n * the **same ctx reference**, augmented with `childId` / `depth`, so a\n * parent listener writing `ctx.block = true` lands on the gate the\n * child's loop is awaiting on. The bubble itself `await`s the parent's\n * callHook so any async approval (e.g. a TUI picker) completes before\n * the child's loop sees the decision.\n * 3. **Re-bubbled `child:*` events** from a grandchild already carry the\n * originating `childId` + `depth`. Forward verbatim so a top-level\n * listener sees true ancestry, not the immediate parent's.\n *\n * Returns a function that unregisters every listener registered here.\n * Called before `agent.run()` starts, torn down in a finally block — so\n * nothing leaks even if the child throws mid-run.\n */\n/**\n * Surface a thrown observational-bubble listener without killing the\n * process. Observational events (`child:stream:text`, `child:tool:after`,\n * `child:turn:after`, …) are fire-and-forget — a rejected promise here\n * has no caller. Without this handler, a buggy parent listener bubbles\n * up to an unhandled-rejection, and Node/Bun under\n * `--unhandled-rejections=strict` terminates the host.\n *\n * Gated on `ZIDANE_DEBUG` so production logs stay quiet; debug builds\n * still get the tagged line.\n */\nfunction swallowBubbleError(eventName: string, err: unknown): void {\n if (!process.env.ZIDANE_DEBUG)\n return\n const message = err instanceof Error ? (err.stack ?? err.message) : String(err)\n process.stderr.write(`[zidane/spawn] parent listener for \"${eventName}\" rejected: ${message}\\n`)\n}\n\nfunction bubbleHooks(\n childHooks: Hookable<AgentHooks>,\n parentHooks: Hookable<AgentHooks>,\n childId: string,\n depth: number,\n): () => void {\n const unregisters: Array<() => void> = []\n\n // Cast the callHook surface once — it accepts any (name, ctx) at runtime\n // but the typed overload is too narrow to satisfy across the map.\n const fire = parentHooks.callHook as unknown as (\n name: keyof AgentHooks,\n ctx: Record<string, unknown>,\n ) => Promise<unknown>\n\n // Observational events — fire-and-forget so a slow parent listener never\n // backpressures child emission (the child has already moved on by then).\n // `Promise.resolve(...).catch(swallowBubbleError)` instead of `void` so a\n // rejected listener surfaces as a tagged stderr line rather than an\n // unhandled rejection — which would terminate the process under\n // `--unhandled-rejections=strict`. `Promise.resolve` because hookable's\n // `callHook` returns `undefined` when no listeners are registered (rather\n // than a resolved promise), and we still want a uniform `.catch` surface.\n for (const evt of BUBBLED_EVENTS) {\n const parentEvt = CHILD_EVENT_NAME[evt]\n const unregister = childHooks.hook(evt, (ctx: object) => {\n Promise.resolve(fire(parentEvt, { ...(ctx as Record<string, unknown>), childId, depth }))\n .catch(err => swallowBubbleError(parentEvt, err))\n })\n unregisters.push(unregister)\n }\n\n // Same-ref bubble — `await` so the parent's decision lands before the\n // child's loop reads back the mutable slot (`ctx.block` / `ctx.result`\n // for gates, `ctx.result` for `tool:transform`). The bubble only adds\n // `childId` + `depth` for routing; the ctx reference itself is the\n // one the child's loop is awaiting on.\n const tagOnCtx = (ctx: Record<string, unknown>) => {\n ctx.childId ??= childId\n ctx.depth ??= depth\n }\n for (const evt of BUBBLED_MUTABLE_EVENTS) {\n const parentEvt = CHILD_MUTABLE_EVENT_NAME[evt]\n const unregister = childHooks.hook(evt, async (ctx: object) => {\n tagOnCtx(ctx as Record<string, unknown>)\n await fire(parentEvt, ctx as Record<string, unknown>)\n })\n unregisters.push(unregister)\n }\n\n // Chain bubbling: forward already-tagged `child:*` events from a grandchild\n // through to the parent, preserving the originating spawn's `childId` +\n // `depth`. Without this, only direct children would surface.\n const chainHook = childHooks.hook as unknown as (\n name: keyof AgentHooks,\n handler: (ctx: object) => void | Promise<void>,\n ) => () => void\n for (const evt of BUBBLED_EVENTS) {\n const parentEvt = CHILD_EVENT_NAME[evt]\n unregisters.push(chainHook(parentEvt, (ctx) => {\n Promise.resolve(fire(parentEvt, ctx as Record<string, unknown>))\n .catch(err => swallowBubbleError(parentEvt, err))\n }))\n }\n for (const evt of BUBBLED_MUTABLE_EVENTS) {\n const parentEvt = CHILD_MUTABLE_EVENT_NAME[evt]\n // Self-mapped events (parentEvt === evt, e.g. `content-ref:resolve`) already\n // have an originating-bubble listener on this same event (registered above).\n // A second listener here would fire the parent twice for a direct child.\n // Grandchild propagation still works without it: the child→grandchild\n // bubble fires the child's own `content-ref:resolve`, which this child's\n // originating listener forwards upward.\n if (parentEvt === evt)\n continue\n unregisters.push(chainHook(parentEvt, async (ctx) => {\n // Same-ref forwards need the await chain to remain serial up to\n // the top-level listener — otherwise the deepest child's loop\n // resumes before the root's decision / result mutation lands.\n await fire(parentEvt, ctx as Record<string, unknown>)\n }))\n }\n\n return () => {\n for (const u of unregisters) u()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport interface SpawnToolOptions {\n /** Maximum concurrent sub-agents (default: 3). */\n maxConcurrent?: number\n /**\n * Maximum subagent depth. 0 disables spawning entirely; 1 allows top-level\n * spawns but forbids grandchildren; 3 (default) allows three levels of\n * recursion — enough for most orchestration patterns, a sharp ceiling\n * against runaway loops.\n */\n maxDepth?: number\n /**\n * Child model override. When unset, the child inherits the parent run's\n * resolved model (`ToolContext.model`), falling back to\n * `provider.meta.defaultModel` only when the parent didn't expose one.\n */\n model?: string\n /** Child system prompt override. Per-spawn `input.system` takes precedence. */\n system?: string\n /** Child thinking level. */\n thinking?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n /** Preset override for children. Shallow-merged over the parent's preset (parent fields still win for anything left unset). */\n preset?: Preset\n /**\n * Per-child timeout, in milliseconds. When the child exceeds it the spawn\n * tool returns a timeout marker, fires `spawn:error`, and destroys the\n * child agent. Default: none.\n */\n timeoutMs?: number\n /**\n * When `true` and the parent has a session, the child reuses the parent's\n * session — child turns are appended with the child's own `runId`, and the\n * resulting `SessionRun` carries `parentRunId` so the tree is\n * reconstructible. Default: `false` (child is in-memory only).\n *\n * **Read-state isolation.** Sharing the session also shares the\n * `read_file` / `requireReadBeforeEdit` tracking map (it's keyed\n * by `Session`). With `persist: false` the child gets no session,\n * so reads inside the subagent populate nothing the parent can see —\n * a follow-up `edit` / `multi_edit` in the parent will trip the\n * gate with `\"has not been read\"` even though the model just\n * read the file in the child. Use {@link shareReadState} when\n * you want the parent's gate to honor the child's reads WITHOUT\n * also persisting child turns to the parent's session.\n */\n persist?: boolean\n /**\n * Forward the parent's read-state map to the child agent so the\n * `requireReadBeforeEdit` gate and `dedupReads` cache see reads\n * across the parent/child boundary. Orthogonal to {@link persist} —\n * use this when you want shared read tracking without sharing the\n * session's turn history. Default: `false`.\n *\n * Has no effect when the parent has no read-state to share (no\n * session and no explicit `readState` on the parent agent's\n * options). Implementation: passes the parent's resolved\n * `ReadStateMap` to the child via `AgentOptions.readState`, which\n * tools resolve via `ctx.readState ?? getReadState(ctx.session)`.\n */\n shareReadState?: boolean\n /**\n * Forward a curated subset of child hook events (`stream:*`, `tool:*`,\n * `turn:after`) onto the parent's hook bus as `child:*` events. Default:\n * `true`. Grandchildren bubble through their child transparently.\n */\n forwardHooks?: boolean\n /** Called when a child agent starts. */\n onSpawn?: (child: ChildAgent) => void\n /** Called when a child agent completes (success, abort, timeout, or error). */\n onComplete?: (child: ChildAgent, stats: AgentStats, status: NonNullable<ChildRunStats['status']>) => void\n /**\n * Named subagent presets the model can select via the `subagent_type`\n * input field. Mirrors the Claude Code SDK's surface — models trained\n * on it routinely emit `subagent_type: 'Explore' | 'Plan' |\n * 'Verification' | 'general-purpose'`, and without a registry the\n * field is silently dropped, so hosts wanting type-specialized\n * subagents have to invent their own dispatch layer.\n *\n * Each entry overlays the base spawn config for that particular\n * dispatch. Per-call `input.system` still wins over `subagents[type].system`\n * so the model can always specialize further.\n *\n * When the registry is non-empty:\n * - `subagent_type` appears in the spawn input schema as a `string`\n * enum of the registered keys (plus the always-available\n * `'general-purpose'` fallback).\n * - Models that pass an unregistered type are routed to\n * `'general-purpose'` (no error — degrade gracefully so trained\n * models keep working even on hosts that haven't wired every\n * type Claude Code uses).\n *\n * When the registry is empty / unset, the field is omitted entirely\n * (preserves the historical schema for hosts that never use this).\n *\n * Default: `undefined` (no subagent types; `subagent_type` schema\n * field hidden).\n */\n subagents?: SubagentRegistry\n}\n\n/**\n * Per-type subagent override applied when the model calls\n * `spawn({ subagent_type: '…' })`. All fields are optional; absent\n * fields fall back to the parent's resolved configuration (see\n * {@link SpawnToolOptions} comments for the merge order).\n */\nexport interface SubagentDef {\n /**\n * System prompt override for this subagent type. Per-call\n * `input.system` still wins — model-supplied specialization beats\n * preset defaults.\n */\n system?: string\n /**\n * Restrict the child agent's tool registry to this list of canonical\n * tool names. Operates as a filter over the parent's tools (the\n * parent's selection is the upper bound — a subagent can never gain\n * tools the parent doesn't have). When unset, the child inherits the\n * parent's full tool list.\n *\n * Tool names are canonical (registry-key) not wire/alias names — the\n * filter runs before aliases are applied. Names that don't match a\n * parent tool are silently dropped (matches the lenient behaviour of\n * `enabledTools` on MCP configs).\n */\n tools?: readonly string[]\n /**\n * Mark this subagent as read-only — equivalent to listing only\n * obviously-non-mutating tools (`read_file`, `grep`, `glob`,\n * `list_files`) in {@link SubagentDef.tools}. Convenience for the\n * common \"Plan\" / \"Explore\" subagent shape Claude Code ships.\n *\n * When both `readonly: true` and `tools` are set, `tools` wins\n * (explicit beats implicit).\n */\n readonly?: boolean\n /**\n * Short description rendered into the spawn tool's schema (the\n * `subagent_type` field's description) so the model can pick a type\n * that matches the task without round-tripping through docs.\n */\n description?: string\n}\n\n/**\n * Map of subagent-type key → preset. Keys are case-sensitive and\n * appear verbatim in the spawn input schema's enum so the model emits\n * them with the same casing. Common conventions: `'Explore'`,\n * `'Plan'`, `'Verification'`, `'general-purpose'` (Claude Code SDK's\n * built-in set).\n */\nexport type SubagentRegistry = Record<string, SubagentDef>\n\n/**\n * Create a configured spawn tool.\n *\n * State (`children`, `totalChildStats`, counters, active count) is scoped to\n * the returned instance. Multiple parent agents using the same instance will\n * share counters + stats + concurrency slots — call `createSpawnTool()` per\n * agent (or use the stateless default `spawn`) to keep them isolated.\n */\nexport function createSpawnTool(options: SpawnToolOptions = {}): ToolDef & SpawnToolState {\n const localChildren = new Map<string, ChildAgent>()\n let localCounter = 0\n let localActiveCount = 0\n const maxConcurrent = options.maxConcurrent ?? 3\n const maxDepth = options.maxDepth ?? 3\n const forwardHooks = options.forwardHooks ?? true\n\n const localStats: AgentStats = {\n totalIn: 0,\n totalOut: 0,\n totalCacheRead: 0,\n totalCacheCreation: 0,\n turns: 0,\n elapsed: 0,\n }\n\n // Pre-compute the subagent_type schema piece once. Including the\n // enum keys (plus the canonical `general-purpose` fallback) saves\n // the host from re-typing them in their preset description. Empty\n // registry — or one passed as `{}` with no entries — drops the field\n // entirely, preserving the historical schema. We don't surface\n // `subagent_type` with only `general-purpose` in the enum (a\n // single-value enum is noise to the model with no decision to make).\n const subagentRegistry = options.subagents\n const hasSubagentEntries = !!subagentRegistry && Object.keys(subagentRegistry).length > 0\n const subagentTypeKeys = hasSubagentEntries\n ? [...new Set([...Object.keys(subagentRegistry!), 'general-purpose'])]\n : []\n const subagentTypeProperty = subagentTypeKeys.length > 0\n ? {\n subagent_type: {\n type: 'string' as const,\n enum: subagentTypeKeys,\n description: buildSubagentTypeDescription(subagentRegistry!),\n },\n }\n : {}\n\n return {\n get children() { return localChildren },\n get totalChildStats() { return { ...localStats } },\n\n // Sub-agents fan out by design — multiple spawn calls in a single\n // batch run in parallel (each child has its own context window,\n // its own retry budget, and its own session linkage). The internal\n // `maxConcurrent` here is the spawn-tool-level cap on simultaneous\n // children; `behavior.maxConcurrentTools` is the loop-level cap on\n // all concurrent tools regardless of kind.\n isConcurrencySafe: true,\n\n spec: {\n name: 'spawn',\n description: 'Spawn a sub-agent for a self-contained task that benefits from isolation (separate context window, separate retries) — for example, a deep research dive or a long codegen pass on a specific file. The sub-agent runs independently with its own tool access and returns its final response. Do NOT spawn for sequential steps you could do yourself.',\n inputSchema: {\n type: 'object',\n properties: {\n task: {\n type: 'string',\n description: 'The task prompt for the sub-agent. Be specific about what you want it to accomplish.',\n },\n system: {\n type: 'string',\n description: 'Optional system prompt override for this specific sub-agent.',\n },\n ...subagentTypeProperty,\n },\n required: ['task'],\n },\n },\n\n async execute(input: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const task = input.task as string\n const systemOverride = input.system as string | undefined\n const requestedSubagentType = typeof input.subagent_type === 'string'\n ? input.subagent_type\n : undefined\n // Resolve the subagent preset. Unknown types degrade to\n // `general-purpose` (i.e. no overlay) so Claude-Code-trained\n // models that emit `subagent_type: 'Verification'` against hosts\n // that never wired that type don't get silently broken — the\n // call still runs, just with the parent's default config.\n const subagentDef = requestedSubagentType && subagentRegistry\n ? (subagentRegistry[requestedSubagentType] ?? undefined)\n : undefined\n const parentDepth = ctx.depth ?? 0\n const childDepth = parentDepth + 1\n\n // Reject before any await so the parent-level LLM sees the failure\n // immediately, and the concurrency slot below is reserved atomically\n // with the cap check.\n if (childDepth > maxDepth) {\n return `Cannot spawn: maxDepth=${maxDepth} reached (parent depth=${parentDepth}). Deepen the cap with createSpawnTool({ maxDepth }).`\n }\n\n if (localActiveCount >= maxConcurrent) {\n return `Cannot spawn: ${localActiveCount}/${maxConcurrent} sub-agents already running. Wait for one to complete.`\n }\n\n // Signal short-circuit: a pre-aborted parent means the child would\n // immediately no-op on its first `signal.aborted` check. Skip the\n // agent/handle/session setup cost entirely.\n if (ctx.signal.aborted) {\n return `[sub-agent pre-aborted] Parent signal was already aborted — skipped \"${task.slice(0, 80)}\"`\n }\n\n // Reserve the slot + id SYNCHRONOUSLY — this block must not contain\n // any `await`, so (a) two parallel spawns can't both pass the cap\n // check, and (b) the session-scoped child counter (see\n // `reserveChildLabel`) sees a consistent `session.runs` snapshot\n // between concurrent spawns sharing this session.\n const id = ctx.session\n ? reserveChildLabel(ctx.session)\n : `child-${++localCounter}`\n localActiveCount++\n const child: ChildAgent = { id, task, startedAt: Date.now(), depth: childDepth }\n localChildren.set(id, child)\n\n let destroyError: Error | undefined\n let childRunStatus: NonNullable<ChildRunStats['status']> = 'completed'\n let finalStats: AgentStats | undefined\n let result = ''\n\n // Bubble child hook events to parent if requested. Wired BEFORE\n // `agent.run()` so even the very first `turn:before` is observable.\n let unbubble: (() => void) | undefined\n\n try {\n // Apply the subagent-type tool filter on top of the parent's\n // tool registry. `tools` wins over `readonly` when both are\n // set (explicit beats implicit). The filter is a strict subset\n // — a subagent can never gain tools the parent doesn't have.\n const filteredTools = subagentDef\n ? filterToolsForSubagent(ctx.tools, subagentDef)\n : ctx.tools\n\n const parentPreset: Preset = {\n ...(ctx.name !== undefined ? { name: ctx.name } : {}),\n ...(ctx.system !== undefined ? { system: ctx.system } : {}),\n tools: filteredTools,\n ...(ctx.toolAliases !== undefined ? { toolAliases: ctx.toolAliases } : {}),\n ...(ctx.mcpServers !== undefined ? { mcpServers: ctx.mcpServers } : {}),\n ...(ctx.skills !== undefined ? { skills: ctx.skills } : {}),\n ...(ctx.behavior !== undefined ? { behavior: ctx.behavior } : {}),\n }\n // Resolve the parent's read-state map for cross-context\n // sharing. `shareReadState: true` forwards it to the child via\n // `AgentOptions.readState`, which tools resolve through\n // `resolveReadStateMap(ctx)`. Skips when the parent has\n // nothing to share (no session, no explicit map). Orthogonal\n // to `persist` — turn-history and read-state are independent.\n // Reading via `resolveReadStateMap` here ensures we forward\n // the same map a grandparent might already have forwarded\n // into us (chained `shareReadState` across the tree).\n const sharedReadState = options.shareReadState\n ? resolveReadStateMap(ctx)\n : undefined\n const agent = createAgent({\n ...parentPreset,\n ...options.preset,\n provider: ctx.provider,\n execution: ctx.execution,\n // Share the parent's session on opt-in. Child turns get appended to\n // the same session.turns stream with the child's runId; the child\n // run itself is tagged with parentRunId below, via AgentRunOptions.\n ...(options.persist && ctx.session ? { session: ctx.session } : {}),\n ...(sharedReadState ? { readState: sharedReadState } : {}),\n })\n\n if (forwardHooks) {\n // Enrich `tool:before` ctx with `priorContent` for the three\n // edit tools BEFORE bubbleHooks fires the parent's\n // `child:tool:before`. Hookable runs listeners serially in\n // registration order, so registering this enricher first\n // guarantees the bubble's ctx-spread captures the field.\n // Hosts that listen on `child:tool:before` (the TUI's\n // edit-diff feature) read `priorContent` to:\n // - render a true `old → new` diff for `write_file` instead\n // of an all-add view, and\n // - paint real-file line numbers in the gutter / compact\n // summary for all three edit tools (via the renderer's\n // `buildContextualDiff` path).\n //\n // Note: `tool:before` is awaited by the child's loop, so this\n // pre-read blocks the child's tool execution by the read\n // latency. Acceptable — edit calls are cheap relative to the\n // model round-trip, and the read is skipped entirely for\n // non-edit tools.\n const unregisterEnricher = agent.hooks.hook('tool:before', async (toolCtx) => {\n if (toolCtx.name !== 'write_file' && toolCtx.name !== 'edit' && toolCtx.name !== 'multi_edit')\n return\n if (!agent.handle)\n return\n const inputPath = toolCtx.input?.path\n if (typeof inputPath !== 'string')\n return\n try {\n toolCtx.priorContent = await agent.execution.readFile(agent.handle, inputPath)\n }\n catch {\n // File doesn't exist (fresh create for `write_file`, or\n // a model-side mistake for `edit` / `multi_edit`) — leave\n // priorContent unset; downstream renderers treat the\n // absence as \"no real-file positions available\" and fall\n // back to synthetic line numbers.\n }\n })\n const unbubbleInner = bubbleHooks(agent.hooks, ctx.hooks, id, childDepth)\n unbubble = () => {\n unregisterEnricher()\n unbubbleInner()\n }\n }\n\n options.onSpawn?.(child)\n // Mutable tracingContext carrier — empty by default; parent tracer\n // listeners on `spawn:before` write a W3C `traceparent` (plus\n // optional `tracestate`) into it. We forward whatever it contains\n // to the child's `agent.run()` so the child tracer can re-parent\n // its root span. Empty / absent for parents that don't run a\n // tracer (no-op, no key gets set, child sees `undefined`).\n const spawnHookCtx: { id: string, task: string, depth: number, tracingContext: Record<string, string> } = {\n id,\n task,\n depth: childDepth,\n tracingContext: {},\n }\n await ctx.hooks.callHook('spawn:before', spawnHookCtx)\n\n // `agent.run()` is started here and we hold onto its promise so we\n // can always `await` it before destroying. Even on a timeout we\n // re-await the run — that lets the child's internal `finally`\n // (session.abortRun, finalizeSession, hooks) flush its state to the\n // store before the parent hands the outcome back to the LLM.\n const propagatedTracing = Object.keys(spawnHookCtx.tracingContext).length > 0\n ? Object.freeze({ ...spawnHookCtx.tracingContext })\n : undefined\n // System prompt precedence (highest first):\n // 1. per-call `input.system` — model-supplied specialization.\n // 2. `subagents[type].system` — host preset for this type.\n // 3. `options.system` — spawn-tool default.\n // The previous logic skipped (2). Subagent-type system\n // overrides matter for Plan/Explore-style presets where the\n // type IS the contract (e.g. \"you are a research subagent…\").\n const effectiveSystem\n = systemOverride\n ?? subagentDef?.system\n ?? options.system\n // Model precedence: explicit spawn-tool override > parent run's\n // resolved model > provider default (inside `agent.run`). Without\n // the `ctx.model` fallback, a parent running on a per-run model\n // would silently spawn children on `provider.meta.defaultModel`\n // (e.g. a sonnet run spawning opus subagents).\n const runPromise = agent.run({\n prompt: task,\n model: options.model ?? ctx.model,\n system: effectiveSystem,\n thinking: options.thinking,\n signal: ctx.signal,\n depth: childDepth,\n ...(options.persist && ctx.runId ? { parentRunId: ctx.runId } : {}),\n ...(propagatedTracing ? { tracingContext: propagatedTracing } : {}),\n })\n\n try {\n finalStats = await raceWithTimeout(runPromise, options.timeoutMs)\n\n // Tree-wide turn count keeps the model-facing line internally\n // consistent with the cumulative token numbers — otherwise a\n // 2-turn child that spawned a 50-turn grandchild would print\n // \"2 turns ... 5000 tokens\" and look broken. Equals\n // `finalStats.turns` when the child has no descendants of its own.\n const treeTurns = flattenTurns(finalStats).length\n // `formatTokenUsage` reports the effective input (including\n // cached reads / cache creations) with the cached portion broken\n // out — see the helper's docstring.\n const usage = formatTokenUsage(finalStats)\n if (ctx.signal.aborted) {\n childRunStatus = 'aborted'\n result = [\n `[sub-agent ${id}] Aborted after ${treeTurns} turns (${finalStats.elapsed}ms)`,\n `Tokens: ${usage}`,\n ].join('\\n')\n }\n else {\n const response = extractText(agent.turns.at(-1))\n result = [\n `[sub-agent ${id}] Completed in ${treeTurns} turns (${finalStats.elapsed}ms)`,\n `Tokens: ${usage}`,\n '',\n response || '(no text response)',\n ].join('\\n')\n }\n }\n catch (err) {\n if (err instanceof SpawnTimeoutError) {\n childRunStatus = 'timeout'\n agent.abort() // triggers child's internal abort path\n // Await the run so its finally block persists aborted state\n // before we move on. Swallow any error from the awaited promise\n // — we've already classified the outcome as 'timeout'.\n try {\n finalStats = await runPromise\n }\n catch {\n finalStats = {\n totalIn: 0,\n totalOut: 0,\n totalCacheRead: 0,\n totalCacheCreation: 0,\n turns: 0,\n elapsed: err.timeoutMs,\n }\n }\n result = `[sub-agent ${id}] Timed out after ${err.timeoutMs}ms`\n }\n else {\n const error = err instanceof Error ? err : new Error(String(err))\n childRunStatus = 'error'\n finalStats = {\n totalIn: 0,\n totalOut: 0,\n totalCacheRead: 0,\n totalCacheCreation: 0,\n turns: 0,\n elapsed: 0,\n }\n result = `[sub-agent ${id}] Error: ${error.message}`\n await ctx.hooks.callHook('spawn:error', { id, task, depth: childDepth, error })\n }\n }\n finally {\n // Promote the subagent's still-running background tasks up\n // to the parent's handle BEFORE destroying the child.\n // Without this, `agent.destroy()` would SIGTERM every task\n // the subagent started (per-handle scoping is what makes\n // sibling subagents isolated, but it also kills `&`-shell\n // semantics where backgrounded work outlives the spawning\n // process). With it, the user can `ctrl+k` a long-running\n // task the subagent started even after the subagent returns,\n // and `killBackgroundTask` from the parent agent actually\n // finds it.\n //\n // The reassignment also REPLACES the task's `onExit`\n // callback — the original closed over the child's hook bus,\n // which is about to be torn down. The new callback fires\n // `background:exit` on the PARENT's bus so the TUI's\n // existing listener drains the entry when the task\n // eventually terminates.\n //\n // Optional in the contract — sandboxes that don't expose\n // `reassignBackgroundTasks` fall through to the previous\n // behavior (destroy kills the subagent's tasks). Same for\n // a child agent that minted no execution handle (no runs\n // ever executed).\n const childHandle = agent.handle\n if (childHandle && ctx.execution.reassignBackgroundTasks) {\n try {\n const reassigned = await ctx.execution.reassignBackgroundTasks(\n childHandle,\n ctx.handle,\n (info) => {\n void Promise.resolve(ctx.hooks.callHook('background:exit', info)).catch(() => {})\n },\n )\n for (const entry of reassigned) {\n await ctx.hooks.callHook('background:reassign', {\n taskId: entry.taskId,\n fromHandleId: childHandle.id,\n toHandleId: ctx.handle.id,\n childId: id,\n pid: entry.pid,\n command: entry.command,\n outputPath: entry.outputPath,\n startedAt: entry.startedAt,\n })\n }\n }\n catch (err) {\n // Non-fatal — destroy will still kill the tasks. Log\n // under ZIDANE_DEBUG so a misconfigured sandbox surfaces\n // visibly. We don't promote this into `spawn:error`\n // because it doesn't affect the subagent's own outcome.\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/spawn] reassignBackgroundTasks failed: ${err instanceof Error ? err.message : String(err)}\\n`)\n }\n }\n\n // Always attempt to destroy. Capture any destroy error so it can be\n // surfaced via spawn:error without masking the primary outcome.\n try {\n await agent.destroy()\n }\n catch (err) {\n destroyError = err instanceof Error ? err : new Error(String(err))\n }\n }\n\n // Aggregate after run finalization so in-flight totalIn/Out/turns\n // counters are stable.\n if (finalStats) {\n localStats.totalIn += finalStats.totalIn\n localStats.totalOut += finalStats.totalOut\n localStats.totalCacheRead += finalStats.totalCacheRead\n localStats.totalCacheCreation += finalStats.totalCacheCreation\n localStats.turns += finalStats.turns\n // `elapsed` is a cumulative sum across children — documented as such.\n // Over-counts when children run in parallel; reflects \"total CPU-ish\n // time burned on children\" rather than wall-clock parallelism.\n localStats.elapsed += finalStats.elapsed\n }\n\n // Build ChildRunStats + emit completion hook. Emitted for every\n // terminal state (success/abort/timeout/error) so consumers can\n // reconcile local state without also listening on spawn:error.\n const childRunStats: ChildRunStats = {\n id,\n task,\n stats: finalStats!,\n depth: childDepth,\n status: childRunStatus,\n ...(finalStats!.output ? { output: finalStats!.output } : {}),\n }\n options.onComplete?.(child, finalStats!, childRunStatus)\n await ctx.hooks.callHook('spawn:complete', childRunStats)\n\n if (destroyError) {\n // Non-fatal but worth surfacing: a destroy failure leaves an\n // execution-handle / MCP connection in a weird state.\n await ctx.hooks.callHook('spawn:error', {\n id,\n task,\n depth: childDepth,\n error: destroyError,\n })\n }\n\n return result\n }\n finally {\n unbubble?.()\n localActiveCount--\n localChildren.delete(id)\n }\n },\n }\n}\n","import type { ToolContext, ToolDef } from './types'\nimport { Buffer } from 'node:buffer'\nimport { hashContent, readStateKey, resolveReadStateMap } from './read-state'\nimport { pathArgError } from './validation'\n\n/**\n * Write a file, with an idempotency signal when the content is unchanged.\n *\n * Three return shapes — chosen so the model can recognize a no-op without a\n * separate read:\n * - `Created path (N bytes)` — file did not exist\n * - `Updated path (N bytes)` — content differed from on-disk\n * - `No change needed: path already at target state (N bytes)` — equal\n *\n * Race window: in non-process execution contexts (docker, sandbox) shared by\n * multiple agents, another writer can mutate the file between our read and\n * our write. Local process context is single-writer per agent so the race is\n * a non-issue there. Documented rather than locked because the cost of\n * cross-context locking outweighs the cost of a stale \"No change\" message.\n */\n\nexport const writeFile: ToolDef = {\n spec: {\n name: 'write_file',\n description: 'Write `content` to `path`, creating any missing parent directories. Overwrites existing files in full; prefer `edit` / `multi_edit` for surgical changes when you only want to alter part of a file. Returns one of: `Created <path> (N bytes)` (file did not exist), `Updated <path> (N bytes)` (content differed), or `No change needed: <path> already at target state (N bytes)` — so the model can detect no-ops without a separate `read_file`.',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path (relative to the execution-context cwd, or absolute).' },\n content: { type: 'string', description: 'Complete file content. Overwrites any existing file at `path`.' },\n },\n required: ['path', 'content'],\n },\n },\n async execute({ path, content }, ctx: ToolContext) {\n const targetPath = path as string\n const targetContent = content as string\n\n // Reasoning-leak backstop — reject pathologically-shaped paths with a\n // steering message instead of letting the fs surface ENAMETOOLONG.\n const pathErr = pathArgError(targetPath)\n if (pathErr) {\n ctx.reportOutcome?.('failed')\n return `Write error: ${pathErr}`\n }\n\n let existing: string | undefined\n try {\n existing = await ctx.execution.readFile(ctx.handle, targetPath)\n }\n catch {\n // File does not exist (or read failed for unrelated reasons — we'll let\n // writeFile surface that error). Either way: treat as a fresh write.\n }\n\n const bytes = Buffer.byteLength(targetContent)\n\n if (existing === targetContent) {\n ctx.reportOutcome?.('noop')\n return `No change needed: ${targetPath} already at target state (${bytes} bytes).`\n }\n\n await ctx.execution.writeFile(ctx.handle, targetPath, targetContent)\n\n // Seed read-state with the just-written bytes so a follow-up `edit` /\n // `multi_edit` on this path passes the `requireReadBeforeEdit` gate and\n // compares against current content — the model demonstrably knows the\n // file's bytes (it just authored them), so forcing a redundant `read_file`\n // would be pure overhead. Slice params mirror a full read (offset 0, no\n // limit) so a later partial re-read still invalidates cleanly. No-op\n // without a read-state map (sessionless, no shared map).\n const readState = resolveReadStateMap(ctx)\n if (readState) {\n readState.set(readStateKey(ctx.handle.cwd, targetPath), {\n contentHash: hashContent(targetContent),\n offset: 0,\n limit: Number.POSITIVE_INFINITY,\n maxBytes: Number.POSITIVE_INFINITY,\n mtimeMs: Date.now(),\n })\n }\n\n ctx.reportOutcome?.(existing === undefined ? 'created' : 'updated')\n return existing === undefined\n ? `Created ${targetPath} (${bytes} bytes).`\n : `Updated ${targetPath} (${bytes} bytes).`\n },\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,yBAAyB,OAAgB,UAA0B;CACjF,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACrD,OAAO;CAGT,IAAI,QAAQ,GACV,OAAO;CACT,OAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAAgB,wBACd,UACA,WAC0B;CAC1B,OAAO;EACL,WAAW,yBAAyB,UAAU,kBAAkB,OAAO,UAAU,SAAS;EAC1F,cAAc,yBAAyB,UAAU,kBAAkB,UAAU,UAAU,YAAY;EACnG,oBAAoB,yBAAyB,UAAU,kBAAkB,UAAU,UAAU,kBAAkB;CACjH;AACF;;;ACfA,SAASA,YAAU,OAA+B;CAChD,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM;AACnD;;;;;;;;;AAUA,eAAsB,gBACpB,WACA,QACA,MACwB;CACxB,MAAM,QAAQ,KAAK,YAAY,GAAG;CAClC,MAAM,MAAM,UAAU,KAAK,MAAO,KAAK,MAAM,GAAG,KAAK,KAAK;CAC1D,MAAM,SAAS,UAAU,KAAK,OAAO,KAAK,MAAM,QAAQ,CAAC;CACzD,MAAM,MAAM,OAAO,YAAY,GAAG;CAClC,MAAM,aAAa,QAAQ,KAAK,SAAS,OAAO,MAAM,GAAG,GAAG;CAE5D,IAAI,WAAW,WAAW,GACxB,OAAO;CAET,IAAI;CACJ,IAAI;EACF,UAAU,MAAM,UAAU,UAAU,QAAQ,GAAG;CACjD,QACM;EACJ,OAAO;CACT;CAEA,KAAK,MAAM,QAAQ,SAAS;EAC1B,MAAM,QAAQA,YAAU,IAAI;EAC5B,IAAI,UAAU,QACZ;EACF,MAAM,WAAW,MAAM,YAAY,GAAG;EAEtC,KADkB,aAAa,KAAK,QAAQ,MAAM,MAAM,GAAG,QAAQ,OACjD,YAChB,OAAO;CACX;CACA,OAAO;AACT;;;;;;AAOA,eAAsB,cACpB,WACA,QACA,MACiB;CACjB,MAAM,UAAU,MAAM,gBAAgB,WAAW,QAAQ,IAAI;CAC7D,OAAO,UAAU,iBAAiB,QAAQ,KAAK;AACjD;;;;;;;;;;;AC1DA,MAAa,OAAgB;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY;IACV,MAAM;KAAE,MAAM;KAAU,aAAa;IAAkE;IACvG,YAAY;KAAE,MAAM;KAAU,aAAa;IAA2B;IACtE,YAAY;KAAE,MAAM;KAAU,aAAa;IAAyB;IACpE,aAAa;KAAE,MAAM;KAAW,aAAa;IAA4C;GAC3F;GACA,UAAU;IAAC;IAAQ;IAAc;GAAY;EAC/C;CACF;CACA,MAAM,QAAQ,EAAE,MAAM,YAAY,YAAY,eAAe,KAAkB;EAC7E,MAAM,SAAS;EACf,MAAM,OAAO;EACb,MAAM,cAAc;EACpB,MAAM,aAAa,gBAAgB;EAEnC,MAAM,UAAU,aAAa,MAAM;EACnC,IAAI,SAAS;GACX,IAAI,gBAAgB,QAAQ;GAC5B,OAAO,eAAe;EACxB;EAEA,IAAI,SAAS,aACX,OAAO,8EAA8E,OAAO;EAE9F,IAAI,KAAK,WAAW,GAClB,OAAO;EAET,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,IAAI,UAAU,SAAS,IAAI,QAAQ,MAAM;EAC5D,QACM;GACJ,MAAM,OAAO,MAAM,cAAc,IAAI,WAAW,IAAI,QAAQ,MAAM;GAClE,IAAI,gBAAgB,QAAQ;GAC5B,OAAO,+BAA+B,OAAO,GAAG;EAClD;EAaA,IAAI,IAAI,UAAU,uBAAuB;GACvC,MAAM,YAAY,oBAAoB,GAAG;GACzC,IAAI,WAAW;IACb,MAAM,SAAS,aAAa,IAAI,OAAO,KAAK,MAAM;IAClD,MAAM,QAAQ,UAAU,IAAI,MAAM;IAClC,IAAI,CAAC,OACH,OAAO,eAAe,OAAO;IAC/B,IAAI,MAAM,gBAAgB,YAAY,QAAQ,GAC5C,OAAO,eAAe,OAAO;GACjC;EACF;EAOA,MAAM,QAAQ,iBAAiB,UAAU,IAAI;EAE7C,IAAI,CAAC,OAAO;GACV,MAAM,UAAU,oBAAoB,UAAU,IAAI;GAClD,IAAI,gBAAgB,QAAQ;GAC5B,OAAO,UACH,uCAAuC,OAAO,+BAA+B,YAC7E,uCAAuC,OAAO;EACpD;EAEA,MAAM,EAAE,QAAQ,aAAa,QAAQ;EAErC,IAAI,cAAc,KAAK,CAAC,YACtB,OAAO,kCAAkC,YAAY,YAAY,OAAO;EAE1E,MAAM,oBAAoB,uBAAuB,aAAa,KAAK,MAAM;EAEzE,MAAM,UAAU,aACZ,SAAS,MAAM,MAAM,EAAE,KAAK,iBAAiB,IAC7C,SAAS,QAAQ,QAAQ,iBAAiB;EAE9C,IAAI,YAAY,UAAU;GACxB,IAAI,gBAAgB,MAAM;GAC1B,OAAO,iDAAiD,OAAO;EACjE;EAEA,MAAM,IAAI,UAAU,UAAU,IAAI,QAAQ,QAAQ,OAAO;EAOzD,MAAM,YAAY,oBAAoB,GAAG;EACzC,IAAI,WAAW;GACb,MAAM,SAAS,aAAa,IAAI,OAAO,KAAK,MAAM;GAClD,MAAM,QAAQ,UAAU,IAAI,MAAM;GAClC,IAAI,OACF,UAAU,IAAI,QAAQ;IAAE,GAAG;IAAO,aAAa,YAAY,OAAO;IAAG,SAAS,KAAK,IAAI;GAAE,CAAC;EAC9F;EAEA,IAAI,gBAAgB,QAAQ;EAG5B,MAAM,UAAU,QAAQ,UAAU,KAAK,oDAAoD,YAAY,GAAG,EAAE;EAC5G,OAAO,UAAU,OAAO,aAAa,YAAY,aAAa,gBAAgB,IAAI,KAAK,IAAI,GAAG;CAChG;AACF;;;;;;;;;;AAWA,SAAS,oBAAoB,UAAkB,QAA+B;CAK5E,MAAM,kBADmB,wBAAwB,MACV,EAAE,MAAM,IAAI,EAAE;CACrD,IAAI,gBAAgB,SAAS,GAC3B,OAAO;CAET,MAAM,QAAQ,SAAS,MAAM,IAAI;CACjC,IAAI,YAAY;CAChB,IAAI,UAAU;CACd,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,QAAQ,mBAAmB,MAAM,IAAI,eAAe;EAC1D,IAAI,QAAQ,WAAW;GACrB,YAAY;GACZ,UAAU;EACZ;CACF;CACA,IAAI,UAAU,KAAK,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,gBAAgB,SAAS,CAAC,CAAC,GAC/E,OAAO;CAET,MAAM,UAAU,MAAM,SAAS,MAAM,GAAG,EAAE;CAC1C,OAAO,QAAQ,UAAU,EAAE,IAAI,KAAK,UAAU,OAAO;AACvD;AAEA,SAAS,mBAAmB,GAAW,GAAmB;CACxD,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;CACvC,IAAI,IAAI;CACR,OAAO,IAAI,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,GAClD;CACF,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;ACzJA,MAAM,gBAAgB;;AAGtB,MAAM,kBAAkB;AAExB,SAASC,YAAU,OAA+B;CAChD,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM;AACnD;AAEA,SAAS,cAAc,OAAqD;CAC1E,OAAO,OAAO,UAAU,WAAW,KAAA,IAAY;AACjD;AAEA,SAAS,YAAY,OAAuB,cAA+B;CACzE,MAAM,OAAOA,YAAU,KAAK;CAC5B,MAAM,OAAO,cAAc,KAAK;CAChC,IAAI,CAAC,gBAAgB,OAAO,MAAM,SAAS,YAAY,OAAO,KAAK,YAAY,UAC7E,OAAO;CACT,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO,EAAE,YAAY;AACtE;AAEA,MAAa,OAAgB;CAE3B,mBAAmB;CACnB,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY;IACV,SAAS;KACP,MAAM;KACN,aAAa;IACf;IACA,OAAO;KACL,MAAM;KACN,aAAa,iDAAiD,cAAc;IAC9E;IACA,UAAU;KACR,MAAM;KACN,aAAa;IACf;IACA,WAAW;KACT,MAAM;KACN,aAAa;IACf;GACF;GACA,UAAU,CAAC,SAAS;EACtB;CACF;CACA,MAAM,QAAQ,EAAE,SAAS,OAAO,UAAU,aAAa,KAAkB;EACvE,MAAM,MAAM;EACZ,MAAM,MAAM,OAAO,UAAU,YAAY,QAAQ,IAAI,QAAQ;EAC7D,MAAM,eAAe,aAAa;EAElC,IAAI;GACF,IAAI,IAAI,UAAU,aAAa,SAAS,MACtC,MAAM,IAAI,MAAM,iCAAiC,IAAI,UAAU,KAAK,kCAAkC;GAMxG,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,gBAAgB,WAAW,MAAM;GACvC,IAAI,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;GAC5D,IAAI;GACJ,MAAM,UAAU,IAAI,SAAoB,YAAY;IAClD,QAAQ,iBAAiB;KACvB,WAAW,MAAM;KACjB,QAAQ,SAAS;IACnB,GAAG,eAAe;GACpB,CAAC;GACD,IAAI;IACF,MAAM,UAAU,MAAM,QAAQ,KAAK,CACjC,IAAI,UAAU,UAAU,IAAI,QAAQ,KAAK;KACvC,MAAM;KACN,OAAO;KACP,UAAU;KACC;KACX,QAAQ,WAAW;IACrB,CAAC,GACD,OACF,CAAC;IACD,IAAI,YAAY,WACd,OAAO,wBAAwB,gBAAgB;IACjD,IAAI,QAAQ,WAAW,GACrB,OAAO;IACT,OAAO,QAAQ,KAAI,UAAS,YAAY,OAAO,YAAY,CAAC,EAAE,KAAK,IAAI;GACzE,UACQ;IACN,aAAa,KAAK;IAClB,IAAI,OAAO,oBAAoB,SAAS,OAAO;GACjD;EACF,SACO,KAAK;GACV,OAAO,eAAe,aAAa,GAAG;EACxC;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClFA,MAAM,qBAAqB;;;;;;;AAQ3B,MAAM,iBAAiB;;AAGvB,MAAM,kBAAkB;AAExB,MAAM,sBAAkC;AAqBxC,MAAa,OAAgB;CAE3B,mBAAmB;CACnB,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY;IACV,WAAW;KAAE,MAAM;KAAU,aAAa;IAA4D;IACtG,QAAQ;KAAE,MAAM;KAAU,aAAa;IAAoI;IAC3K,QAAQ;KAAE,MAAM;KAAU,aAAa;IAAwD;IAC/F,QAAQ;KAAE,MAAM;KAAU,aAAa;IAAyE;IAChH,eAAe;KAAE,MAAM;KAAU,MAAM;MAAC;MAAW;MAAsB;KAAO;KAAG,aAAa;IAAiC;IACjI,MAAM;KAAE,MAAM;KAAW,aAAa;IAA0B;IAChE,MAAM;KAAE,MAAM;KAAW,aAAa;IAAmD;IACzF,MAAM;KAAE,MAAM;KAAW,aAAa;IAA4C;IAClF,MAAM;KAAE,MAAM;KAAW,aAAa;IAA2C;IACjF,MAAM;KAAE,MAAM;KAAW,aAAa;IAA2E;IACjH,aAAa;KAAE,MAAM;KAAW,aAAa;IAAkD;IAC/F,aAAa;KAAE,MAAM;KAAW,aAAa;IAAoJ;IACjM,cAAc;KAAE,MAAM;KAAW,aAAa,6PAA6P,eAAe,0BAA0B,gBAAgB;IAA0E;IAC9a,UAAU;KAAE,MAAM;KAAW,aAAa;IAAyC;GACrF;GACA,UAAU,CAAC,SAAS;EACtB;CACF;CACA,MAAM,QAAQ,UAAU,KAAkB;EACxC,MAAM,QAAQ;EAEd,IAAI;GACF,IAAI,MAAM,mBAAmB,GAAG,GAC9B,OAAO,MAAM,cAAc,OAAO,GAAG;GACvC,OAAO,MAAM,YAAY,OAAO,GAAG;EACrC,SACO,KAAK;GAKV,IAAI,iBAAiB,GAAG,GACtB,MAAM;GACR,OAAO,eAAe,aAAa,GAAG;EACxC;CACF;AACF;;;;;;;;;AAcA,eAAe,mBAAmB,KAAoC;CAEpE,QAAO,MADc,IAAI,UAAU,KAAK,IAAI,QAAQ,gBAAgB,EAAE,QAAQ,IAAI,OAAO,CAAC,GAC5E,aAAa;AAC7B;AAEA,eAAe,cAAc,OAAkB,KAAmC;CAChF,MAAM,OAAO,CAAC,IAAI;CAClB,MAAM,OAAQ,MAAM,eAAe;CAEnC,IAAI,SAAS,sBACX,KAAK,KAAK,sBAAsB;MAC7B,IAAI,SAAS,SAChB,KAAK,KAAK,SAAS;MAEnB,KAAK,KAAM,MAAM,SAAS,OAAQ,kBAAkB,kBAAkB;CAExE,IAAI,MAAM,OACR,KAAK,KAAK,IAAI;CAEhB,IAAI,SAAS,WAAW;EACtB,IAAI,OAAO,MAAM,UAAU,UACzB,KAAK,KAAK,MAAM,OAAO,MAAM,KAAK,CAAC;EACrC,IAAI,OAAO,MAAM,UAAU,UACzB,KAAK,KAAK,MAAM,OAAO,MAAM,KAAK,CAAC;EACrC,IAAI,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,UAAU,UAC/F,KAAK,KAAK,MAAM,OAAO,MAAM,KAAK,CAAC;CACvC;CAEA,IAAI,MAAM,WACR,KAAK,KAAK,eAAe,oBAAoB;CAG/C,IAAI,MAAM,cAAc,OACtB,KAAK,KAAK,aAAa;CAEzB,IAAI,MAAM,MACR,KAAK,KAAK,UAAU,MAAM,IAAI;CAEhC,IAAI,MAAM,MACR,KAAK,KAAK,UAAU,MAAM,IAAI;CAEhC,KAAK,KAAK,MAAM,MAAM,OAAO;CAI7B,KAAK,KAAK,MAAM,QAAQ,GAAG;CAE3B,MAAM,UAAU,KAAK,IAAI,UAAU,EAAE,KAAK,GAAG;CAC7C,MAAM,SAAS,MAAM,IAAI,UAAU,KAAK,IAAI,QAAQ,SAAS,EAAE,QAAQ,IAAI,OAAO,CAAC;CAGnF,IAAI,OAAO,aAAa,KAAK,OAAO,aAAa,GAC/C,OAAO,eAAe,OAAO,OAAO,KAAK,KAAK,uBAAuB,OAAO;CAG9E,OAAO,gBAAgB,OAAO,QAAQ,KAAK;AAC7C;AAMA,eAAe,YAAY,OAAkB,KAAmC;CAC9E,MAAM,OAAQ,MAAM,eAAe;CACnC,MAAM,QAAQ,GAAG,MAAM,QAAQ,MAAM,KAAK,MAAM,YAAY,MAAM,KAAK,SAAS,YAAY,KAAK;CAEjG,IAAI;CACJ,IAAI;EACF,QAAQ,IAAI,OAAO,MAAM,SAAS,SAAS,KAAA,CAAS;CACtD,SACO,KAAK;EACV,OAAO,8BAA8B,aAAa,GAAG;CACvD;CAEA,MAAM,QAAQ,MAAM,eAAe,OAAO,GAAG;CAC7C,MAAM,kBAAkB,MAAM,SAAS;CACvC,MAAM,SAAU,MAAM,SAAS,MAAM,SAAS;CAC9C,MAAM,QAAS,MAAM,SAAS,MAAM,SAAS;CAE7C,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,IAAI,UAAU,SAAS,IAAI,QAAQ,IAAI;EACzD,SACO,KAAK;GAGV,IAAI,iBAAiB,GAAG,GACtB,MAAM;GACR;EACF;EACA,IAAI,MAAM,WAAW;GAEnB,MAAM,aAAa,CAAC,GAAG,QAAQ,SAAS,IAAI,OAAO,MAAM,QAAQ,GAAG,MAAM,QAAQ,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;GAC/F,IAAI,WAAW,WAAW,GACxB;GACF,IAAI,SAAS,sBAAsB;IACjC,MAAM,KAAK,IAAI;IACf;GACF;GACA,IAAI,SAAS,SAAS;IACpB,MAAM,KAAK,GAAG,KAAK,GAAG,WAAW,QAAQ;IACzC;GACF;GAEA,KAAK,MAAM,KAAK,YAAY;IAC1B,MAAM,YAAY,QAAQ,YAAY,MAAM,EAAE,QAAS,CAAC,IAAI;IAC5D,MAAM,UAAU,QAAQ,QAAQ,MAAM,EAAE,KAAM;IAC9C,MAAM,UAAU,QAAQ,MAAM,WAAW,YAAY,KAAK,KAAA,IAAY,OAAO;IAC7E,MAAM,SAAS,QAAQ,MAAM,GAAG,EAAE,KAAM,EAAE,MAAM,IAAI,EAAE;IACtD,MAAM,KAAK,kBAAkB,MAAM,QAAQ,SAAS,eAAe,CAAC;GACtE;GACA;EACF;EAEA,MAAM,YAAY,QAAQ,MAAM,IAAI;EACpC,MAAM,UAAoB,CAAC;EAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;GACzC,MAAM,YAAY;GAClB,IAAI,MAAM,KAAK,UAAU,EAAE,GACzB,QAAQ,KAAK,CAAC;EAClB;EACA,IAAI,QAAQ,WAAW,GACrB;EAEF,IAAI,SAAS,sBAAsB;GACjC,MAAM,KAAK,IAAI;GACf;EACF;EACA,IAAI,SAAS,SAAS;GACpB,MAAM,KAAK,GAAG,KAAK,GAAG,QAAQ,QAAQ;GACtC;EACF;EAEA,MAAM,iCAAiB,IAAI,IAAY;EACvC,KAAK,MAAM,KAAK,SACd,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK,KAAK,IAAI,UAAU,SAAS,GAAG,IAAI,KAAK,GAAG,KACpF,eAAe,IAAI,CAAC;EAExB,MAAM,SAAS,CAAC,GAAG,cAAc,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;EACvD,IAAI,OAAO;EACX,KAAK,MAAM,UAAU,QAAQ;GAC3B,IAAI,SAAS,OAAO,KAAK,MAAM,SAAS,GACtC,MAAM,KAAK,IAAI;GACjB,MAAM,UAAU,UAAU;GAC1B,MAAM,KAAK,kBAAkB,MAAM,SAAS,GAAG,SAAS,eAAe,CAAC;GACxE,OAAO;EACT;CACF;CAEA,OAAO,gBAAgB,MAAM,KAAK,IAAI,GAAG,KAAK;AAChD;AAEA,SAAS,kBAAkB,MAAc,QAAgB,SAAiB,iBAAkC;CAC1G,OAAO,kBAAkB,GAAG,KAAK,GAAG,OAAO,GAAG,YAAY,GAAG,KAAK,GAAG;AACvE;AAEA,eAAe,eAAe,OAAkB,KAAqC;CACnF,MAAM,OAAO,MAAM,QAAQ;CAI3B,IAAI,MAAM,QAAQ,CAAC,MAAM,KAAK,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,GAAG;OAEjE,MADgB,IAAI,UAAU,KAAK,IAAI,QAAQ,WAAW,WAAW,MAAM,IAAI,EAAE,4BAA4B,EAAE,QAAQ,IAAI,OAAO,CAAC,GAC7H,OAAO,KAAK,MAAM,QAC1B,OAAO,CAAC,MAAM,IAAI;CAAA;CAMtB,MAAM,SAAS,MAAM,IAAI,UAAU,KAAK,IAAI,QAAQ,iBAAiB,MAAM,MAAM,IAAI,GAAG,EAAE,QAAQ,IAAI,OAAO,CAAC;CAO9G,IAAI,OAAO,aAAa,KAAK,CAAC,OAAO,OAAO,KAAK,GAC/C,MAAM,IAAI,MAAM,OAAO,OAAO,KAAK,KAAK,yBAAyB,OAAO,UAAU;CAEpF,MAAM,QAAQ,OAAO,OAClB,MAAM,IAAI,EACV,KAAI,SAAQ,KAAK,QAAQ,SAAS,EAAE,CAAC,EACrC,QAAO,SAAQ,KAAK,SAAS,CAAC,EAC9B,KAAK;CAKR,IAAI,MAAM,cAAc,OACtB,OAAO;CACT,OAAO,kBAAkB,OAAO,MAAM,GAAG;AAC3C;;;;;;AAOA,eAAe,kBAAkB,OAAiB,MAAc,KAAqC;CACnG,IAAI,MAAM,WAAW,GACnB,OAAO;CACT,IAAI,SAAS,QAAQ,KAAK,WAAW,GAAG,KAAK,KAAK,MAAM,GAAG,EAAE,SAAS,IAAI,IACxE,OAAO;CACT,IAAI;EACF,MAAM,MAAM,MAAM,IAAI,UAAU,KAAK,IAAI,QAAQ,sBAAsB,EAAE,QAAQ,IAAI,OAAO,CAAC;EAC7F,IAAI,IAAI,aAAa,GACnB,OAAO;EACT,MAAM,UAAU,IAAI,IAAI,gBAAgB,IAAI,MAAM,CAAC;EACnD,IAAI,QAAQ,SAAS,GACnB,OAAO;EACT,OAAO,MAAM,QAAO,SAAQ,QAAQ,IAAI,IAAI,CAAC;CAC/C,QACM;EACJ,OAAO;CACT;AACF;;;;;;;;;;;AAYA,SAAS,iBAAiB,MAAc,MAAuB;CAC7D,MAAM,WAAW,kBAAkB,IAAI;CACvC,MAAM,OAAO,WAAW,QAAQ;CAChC,IAAI,CAAC,MACH,OAAO,QAAQ,KAAK;CACtB,MAAM,WAAW,KAAK,MAAM,sBAAsB;CAClD,IAAI,UACF,OAAO,QAAQ,KAAK,iBAAiB,WAAW,SAAS,EAAE;CAC7D,MAAM,WAAW,SAAS,QAAQ,OAAO,EAAE;CAE3C,OAAO,QAAQ,KAAK,iBAAiB,WADjB,SAAS,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,MACL;AAC7D;AAEA,SAAS,kBAAkB,MAAsB;CAG/C,OAAO,KAAK,WAAW,GAAG,IAAI,KAAK,SAAS;AAC9C;AAEA,SAAS,gBAAgB,MAAc,OAA0B;CAC/D,MAAM,YAAY,OAAO,MAAM,eAAe,YAAY,MAAM,cAAc,IAC1E,MAAM,aACN;CACJ,MAAM,SAAS,OAAO,MAAM,WAAW,YAAY,MAAM,SAAS,IAC9D,KAAK,MAAM,MAAM,MAAM,IACvB;CAEJ,IAAI,CAAC,KAAK,KAAK,GACb,OAAO;CAET,MAAM,QAAQ,KAAK,MAAM,IAAI,EAAE,QAAO,MAAK,EAAE,SAAS,CAAC;CACvD,MAAM,QAAQ,MAAM;CAEpB,MAAM,SAAS,cAAc,IACzB,MAAM,MAAM,MAAM,IAClB,MAAM,MAAM,QAAQ,SAAS,SAAS;CAE1C,IAAI,OAAO,WAAW,GACpB,OAAO;CAMT,MAAM,SAAmB,CAAC;CAC1B,IAAI,YAAY;CAChB,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,QAAQ;EACzB,MAAM,UAAU,SAAS,IAAI;EAC7B,MAAM,YAAY,OAAO,WAAW,OAAO,IAAI;EAC/C,IAAI,YAAY,YAAY,mBAAmB,OAAO,SAAS,GAAG;GAChE,UAAU;GACV;EACF;EACA,OAAO,KAAK,OAAO;EACnB,aAAa;CACf;CAEA,MAAM,QAAQ,OAAO;CACrB,MAAM,gBAAgB,SAAS;CAE/B,MAAM,cAAc,YAAY,KAAK,SAAS,YAAY;CAI1D,IAAI,MAAM,OAAO,KAAK,IAAI;CAC1B,IAAI,eACF,MAAM,KAAK,OAAO,4BAA4B;CAChD,IAAI,SACF,MAAM,GAAG,IAAI,0BAA0B,gBAAgB,eAAe,MAAM,MAAM,QAAQ,OAAO,0DAA0D,SAAS,MAAM;MACvK,IAAI,aACP,MAAM,GAAG,IAAI,MAAM,QAAQ,SAAS,UAAU,kCAAkC,SAAS,UAAU;CACrG,OAAO;AACT;;;;;;AAOA,SAAS,SAAS,MAAsB;CACtC,IAAI,OAAO,WAAW,IAAI,KAAK,gBAC7B,OAAO;CACT,IAAI,MAAM,KAAK,IAAI,KAAK,QAAQ,cAAc;CAC9C,OAAO,MAAM,KAAK,OAAO,WAAW,KAAK,MAAM,GAAG,GAAG,CAAC,IAAI,gBACxD;CACF,MAAM,UAAU,OAAO,WAAW,IAAI,IAAI,OAAO,WAAW,KAAK,MAAM,GAAG,GAAG,CAAC;CAC9E,OAAO,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE,mBAAmB,QAAQ;AAC1D;;;AC/aA,SAAS,YAAY,QAA6B;CAChD,OAAO,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,SAAS,IAC/D,OAAO,SACP;AACN;;;;;;;;AAoBA,SAAgB,sBAAsB,SAA0C;CAI9E,OAAO;EACL,MAAM;GACJ,MALS,QAAQ,QAAQ;GAMzB,aALgB,QAAQ,eAAe;GAMvC,aAAa,QAAQ;EACvB;EACA,MAAM,QAAQ,OAAO,KAAK;GAMxB,MAAM,EAAE,WAAW;GACnB,IAAI,QAAQ,SACV,MAAM,IAAI,MAAM,YAAY,MAAM,CAAC;GAErC,IAAI;GACJ,MAAM,eAAe,SACjB,IAAI,SAAgB,GAAG,WAAW;IAChC,gBAAgB,OAAO,IAAI,MAAM,YAAY,MAAM,CAAC,CAAC;IACrD,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;GAC1D,CAAC,IACD,KAAA;GAEJ,IAAI;IACF,MAAM,SAAS,eACX,MAAM,QAAQ,KAAK,CAAC,QAAQ,UAAU,OAAO,GAAG,GAAG,YAAY,CAAC,IAChE,MAAM,QAAQ,UAAU,OAAO,GAAG;IACtC,OAAO,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,MAAM;GACpE,UACQ;IACN,IAAI,UAAU,SACZ,OAAO,oBAAoB,SAAS,OAAO;GAC/C;EACF;CACF;AACF;;;ACjFA,SAAS,UAAU,OAA+B;CAChD,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM;AACnD;AAEA,MAAa,YAAqB;CAEhC,mBAAmB;CACnB,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY,EACV,MAAM;IAAE,MAAM;IAAU,aAAa;GAAwF,EAC/H;GACA,UAAU,CAAC;EACb;CACF;CACA,MAAM,QAAQ,EAAE,QAAQ,KAAkB;EACxC,IAAI;GAEF,QAAO,MADe,IAAI,UAAU,UAAU,IAAI,QAAS,QAAmB,GAAG,GAClE,IAAI,SAAS,EAAE,KAAK,IAAI,KAAK;EAC9C,QACM;GACJ,OAAO,wBAAwB;EACjC;CACF;AACF;;;;;;;;;;;;;;;;ACuCA,SAAS,cAAc,UAA0C;CAC/D,MAAM,QAAQ,CAAC,iBAAiB;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACxC,MAAM,IAAI,SAAS;EACnB,MAAM,SAAS,EAAE,SAAS,KAAK,EAAE,OAAO,QAAQ,UAAU,GAAG,MAAM;EACnE,MAAM,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE,OAAO,QAAQ;CAC3C;CACA,MAAM,KAAK,kBAAkB;CAC7B,OAAO,MAAM,KAAK,IAAI;AACxB;AAEA,MAAa,YAAqB;CAChC,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY;IACV,MAAM;KAAE,MAAM;KAAU,aAAa;IAAkE;IACvG,OAAO;KACL,MAAM;KACN,aAAa;KACb,OAAO;MACL,MAAM;MACN,YAAY;OACV,YAAY,EAAE,MAAM,SAAS;OAC7B,YAAY,EAAE,MAAM,SAAS;OAC7B,aAAa,EAAE,MAAM,UAAU;MACjC;MACA,UAAU,CAAC,cAAc,YAAY;KACvC;IACF;GACF;GACA,UAAU,CAAC,QAAQ,OAAO;EAC5B;CACF;CACA,MAAM,QAAQ,EAAE,MAAM,SAAS,KAAkB;EAC/C,MAAM,SAAS;EACf,MAAM,QAAQ;EAEd,MAAM,UAAU,aAAa,MAAM;EACnC,IAAI,SAAS;GACX,IAAI,gBAAgB,QAAQ;GAC5B,OAAO,qBAAqB;EAC9B;EAEA,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG;GAC/C,IAAI,gBAAgB,QAAQ;GAC5B,OAAO;EACT;EAEA,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,IAAI,UAAU,SAAS,IAAI,QAAQ,MAAM;EAC3D,QACM;GACJ,MAAM,OAAO,MAAM,cAAc,IAAI,WAAW,IAAI,QAAQ,MAAM;GAClE,IAAI,gBAAgB,QAAQ;GAC5B,OAAO,qCAAqC,OAAO,GAAG;EACxD;EAIA,IAAI,IAAI,UAAU,uBAAuB;GACvC,MAAM,YAAY,oBAAoB,GAAG;GACzC,IAAI,WAAW;IACb,MAAM,SAAS,aAAa,IAAI,OAAO,KAAK,MAAM;IAClD,MAAM,QAAQ,UAAU,IAAI,MAAM;IAClC,IAAI,CAAC,OAAO;KACV,IAAI,gBAAgB,QAAQ;KAC5B,OAAO,qBAAqB,OAAO;IACrC;IACA,IAAI,MAAM,gBAAgB,YAAY,OAAO,GAAG;KAC9C,IAAI,gBAAgB,QAAQ;KAC5B,OAAO,qBAAqB,OAAO;IACrC;GACF;EACF;EAEA,MAAM,WAA0B,CAAC;EAIjC,MAAM,WAAqB,CAAC;EAC5B,IAAI,oBAAoB;EAExB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,OAAO,MAAM;GACnB,MAAM,OAAO,KAAK;GAClB,MAAM,cAAc,KAAK;GACzB,MAAM,aAAa,KAAK,gBAAgB;GAExC,IAAI,OAAO,SAAS,YAAY,OAAO,gBAAgB,UAAU;IAC/D,SAAS,KAAK;KAAE,MAAM;KAAU,QAAQ;IAAmC,CAAC;IAC5E;GACF;GAEA,IAAI,KAAK,WAAW,GAAG;IACrB,SAAS,KAAK;KAAE,MAAM;KAAU,QAAQ;IAA4D,CAAC;IACrG;GACF;GAEA,IAAI,SAAS,aAAa;IACxB,SAAS,KAAK;KAAE,MAAM;KAAU,QAAQ;IAA0C,CAAC;IACnF;GACF;GAEA,MAAM,QAAQ,iBAAiB,SAAS,IAAI;GAC5C,IAAI,CAAC,OAAO;IACV,SAAS,KAAK;KAAE,MAAM;KAAU,QAAQ,2BAA2B;IAAS,CAAC;IAC7E;GACF;GAEA,MAAM,EAAE,QAAQ,aAAa,QAAQ;GACrC,IAAI,cAAc,KAAK,CAAC,YAAY;IAClC,SAAS,KAAK;KACZ,MAAM;KACN,QAAQ,sBAAsB,YAAY;IAC5C,CAAC;IACD;GACF;GAEA,MAAM,oBAAoB,uBAAuB,aAAa,KAAK,MAAM;GACzE,UAAU,aACN,QAAQ,MAAM,MAAM,EAAE,KAAK,iBAAiB,IAC5C,QAAQ,QAAQ,QAAQ,iBAAiB;GAC7C,qBAAqB;GACrB,IAAI,QAAQ,SACV,SAAS,KAAK,SAAS,IAAI,EAAE,mDAAmD,YAAY,GAAG,GAAG;GACpG,SAAS,KAAK,EAAE,MAAM,UAAU,CAAC;EACnC;EAEA,MAAM,eAAe,SAAS,QAAQ,GAAG,MAAM,EAAE,SAAS,YAAY,IAAI,IAAI,GAAG,CAAC;EAClF,MAAM,cAAc,SAAS,SAAS;EAKtC,IAAI,eAAe,GAAG;GACpB,MAAM,IAAI,UAAU,UAAU,IAAI,QAAQ,QAAQ,OAAO;GAGzD,IAAI,gBAAgB,QAAQ;GAI5B,MAAM,YAAY,oBAAoB,GAAG;GACzC,IAAI,WAAW;IACb,MAAM,SAAS,aAAa,IAAI,OAAO,KAAK,MAAM;IAClD,MAAM,QAAQ,UAAU,IAAI,MAAM;IAClC,IAAI,OACF,UAAU,IAAI,QAAQ;KAAE,GAAG;KAAO,aAAa,YAAY,OAAO;KAAG,SAAS,KAAK,IAAI;IAAE,CAAC;GAC9F;EACF,OAGE,IAAI,gBAAgB,QAAQ;EAG9B,MAAM,IAAI,MAAM;EAchB,IAAI;EACJ,IAAI,iBAAiB,GACnB,SAAS,UAAU,OAAO,YAAY,EAAE,OAAO,MAAM,IAAI,KAAK,IAAI,IAAI,kBAAkB,cAAc,sBAAsB,IAAI,KAAK,IAAI;OAEtI,IAAI,eAAe,GACtB,SAAS,UAAU,OAAO,YAAY,aAAa,MAAM,EAAE,UAAU,kBAAkB,cAAc,sBAAsB,IAAI,KAAK,IAAI;OAGxI,SAAS,yCAAyC,OAAO,IAAI,EAAE;EAGjE,MAAM,eAAyB,CAAC;EAChC,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;GACxC,MAAM,IAAI,SAAS;GACnB,IAAI,EAAE,SAAS,UACb,aAAa,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,QAAQ;EAC1D;EAMA,MAAM,QAAQ,CAAC,MAAM;EACrB,IAAI,SAAS,SAAS,GACpB,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC;EAChC,IAAI,aAAa,SAAS,GACxB,MAAM,KAAK,aAAa,KAAK,IAAI,CAAC;EACpC,IAAI,cAAc,GAChB,MAAM,KAAK,cAAc,QAAQ,CAAC;EACpC,OAAO,MAAM,KAAK,MAAM;CAC1B;AACF;;;;;;;;;ACzPA,SAAgB,kBAAkB,MAAkC;CAClE,MAAM,MAAM,KAAK,YAAY,GAAG;CAChC,IAAI,QAAQ,IACV,OAAO,KAAA;CAET,QADY,KAAK,MAAM,MAAM,CAAC,EAAE,YACtB,GAAV;EACE,KAAK,OACH,OAAO;EACT,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,SACE;CACJ;AACF;;;;;;;;;;AAWA,eAAsB,iBACpB,WACA,QACA,MACiD;CACjD,IAAI,UAAU,gBAAgB;EAC5B,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI;EAEzD,OAAO;GAAE,QADG,OAAO,KAAK,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU,EAAE,SAAS,QAChE;GAAG,YAAY,MAAM;EAAW;CACrD;CAMA,MAAM,MAAM,YAAY,YAAY,IAAI;CACxC,MAAM,SAAS,MAAM,UAAU,KAAK,QAAQ,GAAG;CAC/C,IAAI,OAAO,aAAa,GACtB,MAAM,IAAI,MAAM,uBAAuB,OAAO,UAAU,QAAQ,OAAO,YAAY;CAErF,MAAM,MAAM,OAAO,OAAO,QAAQ,QAAQ,EAAE;CAC5C,OAAO;EAAE,QAAQ;EAAK,YAAY,wBAAwB,GAAG;CAAE;AACjE;;;;;;AAOA,SAAS,wBAAwB,KAAqB;CACpD,IAAI,IAAI,WAAW,GACjB,OAAO;CACT,IAAI,MAAM;CACV,IAAI,IAAI,SAAS,IAAI,GACnB,MAAM;MACH,IAAI,IAAI,SAAS,GAAG,GACvB,MAAM;CACR,OAAO,KAAK,IAAI,GAAI,IAAI,SAAS,IAAK,IAAI,GAAG;AAC/C;;;;;;;;;;;;;;;ACjEA,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;;;;;;;;AASzB,MAAM,8BAA8B,IAAI,OAAO;AAE/C,SAAS,qBAAqB,MAAc,UAAsC;CAChF,IAAI,aAAa,QACf,OAAO,OAAO,WAAW,IAAI;CAC/B,IAAI,KAAK,WAAW,GAClB,OAAO;CACT,MAAM,MAAM,KAAK,SAAS,IAAI,IAAI,IAAI,KAAK,SAAS,GAAG,IAAI,IAAI;CAC/D,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,KAAK,SAAS,IAAK,CAAC,IAAI,GAAG;AAC5D;AAEA,MAAa,WAAoB;CAG/B,mBAAmB;CACnB,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY;IACV,MAAM;KAAE,MAAM;KAAU,aAAa;IAAkE;IACvG,QAAQ;KAAE,MAAM;KAAW,aAAa;IAAmD;IAC3F,OAAO;KAAE,MAAM;KAAW,aAAa;IAA2D;IAClG,UAAU;KAAE,MAAM;KAAW,aAAa;IAA2Q;IACrT,aAAa;KAAE,MAAM;KAAW,aAAa;IAAoI;GACnL;GACA,UAAU,CAAC,MAAM;EACnB;CACF;CACA,MAAM,QAAQ,EAAE,MAAM,QAAQ,OAAO,UAAU,eAAe,KAAkB;EAC9E,MAAM,WAAW,wBAAwB,IAAI,UAAU;GACrD,WAAW;GACX,cAAc;GACd,oBAAoB;EACtB,CAAC;EAMD,MAAM,aAAa,OAAO,SAAS,WAAW,sBAAsB,IAAI,IAAI;EAC5E,IAAI,YAAY;GACd,MAAM,QAAQ,IAAI,SAAS;GAC3B,IAAI,CAAC,OACH,OAAO,cAAc,KAAK;GAC5B,MAAM,QAAQ,2BAA2B,OAAO,UAAU;GAC1D,IAAI,CAAC,OACH,OAAO,cAAc,KAAK;GAC5B,MAAM,UAAU,yBAAyB,UAAU,SAAS,kBAAkB;GAC9E,MAAM,aAAa,qBAAqB,MAAM,MAAM,MAAM,QAAQ;GAClE,IAAI,UAAU,KAAK,aAAa,SAC9B,OAAO,uCAAuC,KAAK,IAAI,WAAW,cAAc,QAAQ;GAQ1F,OAAO,CALL;IAAE,MAAM;IAAQ,MAAM,GAFV,MAAM,SAAS,UAAU,UAAU,WAEhB,qCAAqC,MAAM,YAAY,MAAM,OAAO,MAAM,MAAM,KAAK,KAAK,GAAG;GAAI,GAChI,MAAM,SAAS,UACX;IAAE,MAAM;IAAS,WAAW,MAAM;IAAW,MAAM,MAAM;IAAM,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;GAAG,IAC3G;IAAE,MAAM;IAAY,WAAW,MAAM;IAAW,MAAM,MAAM;IAAM,UAAU,MAAM,YAAY;IAAU,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;GAAG,CAE7I;EACf;EAGA,MAAM,UAAU,aAAa,IAAc;EAC3C,IAAI,SACF,OAAO,eAAe;EASxB,MAAM,WAAW,kBAAkB,IAAc;EACjD,IAAI,UAAU;GACZ,MAAM,UAAU,yBAAyB,UAAU,SAAS,kBAAkB;GAC9E,IAAI;IACF,MAAM,EAAE,QAAQ,eAAe,MAAM,iBAAiB,IAAI,WAAW,IAAI,QAAQ,IAAc;IAC/F,IAAI,UAAU,KAAK,aAAa,SAC9B,OAAO,+BAA+B,KAAK,IAAI,WAAW,cAAc,QAAQ;IAElF,MAAM,WAAW,wBAAwB,UAAU,MAAM;IAKzD,OAAO,CAHL;KAAE,MAAM;KAAQ,MAAM,UAAU,KAAK,IAAI,WAAW,UAAU,SAAS;IAAG,GAC1E;KAAE,MAAM;KAAS,WAAW;KAAU,MAAM;IAAO,CAExC;GACf,SACO,KAAK;IACV,MAAM,OAAO,MAAM,cAAc,IAAI,WAAW,IAAI,QAAQ,IAAc;IAC1E,OAAO,sBAAsB,KAAK,KAAK,aAAa,GAAG,EAAE,GAAG;GAC9D;EACF;EAEA,MAAM,WAAW,qBAAqB,IAAc;EACpD,IAAI,UAAU;GACZ,MAAM,UAAU,yBAAyB,UAAU,SAAS,kBAAkB;GAC9E,IAAI;IACF,MAAM,EAAE,QAAQ,eAAe,MAAM,iBAAiB,IAAI,WAAW,IAAI,QAAQ,IAAc;IAC/F,IAAI,UAAU,KAAK,aAAa,SAC9B,OAAO,kCAAkC,KAAK,IAAI,WAAW,cAAc,QAAQ;IAErF,IAAI,aAAa,qBAAqB,CAAC,YAAY,MAAM,GACvD,OAAO,iBAAiB,KAAK,IAAI,WAAW;IAM9C,OAAO,CAHL;KAAE,MAAM;KAAQ,MAAM,aAAa,KAAK,IAAI,WAAW,UAAU,SAAS;IAAG,GAC7E;KAAE,MAAM;KAAY,WAAW;KAAU,MAAM;KAAQ,UAAU;KAAU,MAAM,gBAAgB,IAAc;IAAE,CAEtG;GACf,SACO,KAAK;IACV,MAAM,OAAO,MAAM,cAAc,IAAI,WAAW,IAAI,QAAQ,IAAc;IAC1E,OAAO,yBAAyB,KAAK,KAAK,aAAa,GAAG,EAAE,GAAG;GACjE;EACF;EAEA,IAAI;EACJ,IAAI;GACF,MAAM,MAAM,IAAI,UAAU,SAAS,IAAI,QAAQ,IAAc;EAC/D,QACM;GAEJ,OAAO,mBAAmB,KAAK,GAAG,MADf,cAAc,IAAI,WAAW,IAAI,QAAQ,IAAc;EAE5E;EAEA,MAAM,aAAa,OAAO,WAAW,GAAG;EAgBxC,MAAM,eAAe,IAAI,UAAU,eAAe;EAClD,MAAM,cAAc,IAAI,UAAU,0BAA0B;EAE5D,MAAM,YADkB,gBAAgB,cACJ,oBAAoB,GAAG,IAAI,KAAA;EAC/D,MAAM,SAAS,aAAa,IAAI,OAAO,KAAK,IAAc;EAC1D,MAAM,eAAe,yBAAyB,QAAQ,CAAC;EACvD,MAAM,cAAc,yBAAyB,OAAO,SAAS,SAAS;EACtE,MAAM,iBAAiB,yBAAyB,UAAU,SAAS,YAAY;EAC/E,MAAM,kBAAkB,OAAO,gBAAgB,YAC3C,cACC,IAAI,UAAU,mBAAmB;EACtC,MAAM,cAAc,YAAY,YAAY,GAAG,IAAI;EACnD,MAAM,qBAAqB;GACzB,IAAI,CAAC,WACH;GACF,UAAU,IAAI,QAAQ;IACpB,aAAa;IACb,QAAQ;IACR,OAAO;IACP,UAAU;IACV,aAAa;IACb,SAAS,KAAK,IAAI;GACpB,CAAC;EACH;EACA,IAAI,gBAAgB,WAAW;GAC7B,MAAM,QAAQ,UAAU,IAAI,MAAM;GAClC,IACE,SACG,MAAM,gBAAgB,eACtB,MAAM,WAAW,gBACjB,MAAM,UAAU,eAChB,MAAM,aAAa,kBAKnB,MAAM,gBAAgB,mBAItB,MAAM,WAAW,MACpB;IAYA,aAAa;IACb,OAAO,QAAQ,KAAK;GACtB;EACF;EAMA,IAAI,YAAY,GAAG,GACjB,OAAO,iBAAiB,KAAK,IAAI,WAAW;EAG9C,MAAM,UAAU;EAChB,MAAM,SAAS;EACf,MAAM,YAAY;EAElB,MAAM,QAAQ,IAAI,MAAM,IAAI;EAC5B,MAAM,aAAa,MAAM;EAGzB,MAAM,WAAW,KAAK,IAAI,GAAG,UAAU,CAAC;EACxC,MAAM,SAAS,SAAS,IAAI,KAAK,IAAI,YAAY,WAAW,MAAM,IAAI;EACtE,IAAI,QAAQ,MAAM,MAAM,UAAU,MAAM;EAOxC,IAAI,WAAW;EACf,IAAI,YAAY,GAAG;GACjB,MAAM,iBAA2B,CAAC;GAClC,IAAI,YAAY;GAChB,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,YAAY,OAAO,WAAW,IAAI,IAAI;IAC5C,IAAI,YAAY,YAAY,aAAa,eAAe,SAAS,GAAG;KAClE,WAAW;KACX;IACF;IACA,eAAe,KAAK,IAAI;IACxB,aAAa;IACb,IAAI,aAAa,WAEf;GAEJ;GACA,IAAI,eAAe,SAAS,MAAM,QAChC,WAAW;GACb,QAAQ;EACV;EAOA,IAAI,aAAa;EACjB,IAAI,YAAY,KAAK,MAAM,SAAS;OAChB,OAAO,WAAW,MAAM,KAAK,IAAI,CACvC,IAAI,WAAW;IACzB,MAAM,UAAU,MAAM,SAAS;IAC/B,MAAM,WAAW,MAAM;IACvB,MAAM,aAAa,UAAU,IACzB,OAAO,WAAW,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,IAAI,IACxD;IACJ,MAAM,gBAAgB,KAAK,IAAI,GAAG,YAAY,UAAU;IAIxD,IAAI,MAAM,KAAK,IAAI,SAAS,QAAQ,aAAa;IACjD,OAAO,MAAM,KAAK,OAAO,WAAW,SAAS,MAAM,GAAG,GAAG,CAAC,IAAI,eAC5D;IACF,MAAM,WAAW,SAAS,MAAM,GAAG,GAAG;IACtC,aAAa;IACb,WAAW;GACb;;EAIF,MAAM,eAAe,WADC,MAAM;EAS5B,MAAM,OAAO,kBACT,MAAM,KAAK,MAAM,MAAM,GAAG,WAAW,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK,IAAI,IAChE,MAAM,KAAK,IAAI;EAEnB,aAAa;EAEb,MAAM,iBAAiB,SAAS,cAAc;EAC9C,IAAI,CAAC,kBAAkB,YAAY,GACjC,OAAO;EAET,IAAI,CAAC,gBAEH,OAAO,GAAG,KAAK,kBAAkB,QAAQ,GAAG,aAAa,MAAM,WAAW;EAG5E,IAAI,YAMF,OAAO,GAAG,KAAK,kCAAkC,aAAa,aAAa,UAAU,sBAAsB,WAAW,UAAU,WAAW;EAI7I,OAAO,GAAG,KAAK,yBAAyB,aAAa,IADtC,WAAW,aAAa,UAAU,aAAa,eAAe,OAAO,WACpB,cAAc,WAAW,UAAU,WAAW,qCAAqC,eAAe,EAAE;CACtK;AACF;AAEA,SAAS,qBAAqB,MAAkC;CAC9D,MAAM,MAAM,KAAK,YAAY,GAAG;CAChC,IAAI,QAAQ,IACV,OAAO,KAAA;CAET,OADY,KAAK,MAAM,MAAM,CAAC,EAAE,YACvB,MAAM,QAAQ,oBAAoB,KAAA;AAC7C;AAEA,SAAS,gBAAgB,MAAsB;CAC7C,MAAM,aAAa,KAAK,QAAQ,OAAO,GAAG;CAC1C,MAAM,QAAQ,WAAW,YAAY,GAAG;CACxC,OAAO,UAAU,KAAK,aAAa,WAAW,MAAM,QAAQ,CAAC;AAC/D;AAEA,SAAS,YAAY,QAAyB;CAC5C,OAAO,OAAO,KAAK,OAAO,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,SAAS,OAAO,EAAE,WAAW,OAAO;AACxF;;;AC3VA,MAAa,YAAqB;CAGhC,mBAAmB;CACnB,MAAM;EACJ,MAAM;EACN,aAAa;GACX;GACA;GACA;GACA;EACF,EAAE,KAAK,IAAI;EACX,aAAa;GACX,MAAM;GACN,YAAY,EACV,SAAS;IAAE,MAAM;IAAU,aAAa;GAA6E,EACvH;GACA,UAAU,CAAC,SAAS;GACpB,sBAAsB;EACxB;CACF;CACA,MAAM,QAAQ,OAAO,KAAmC;EACtD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,IAAI,UAAU,gBACjB,OAAO,mDAAmD,IAAI,UAAU,KAAK;EAG/E,MAAM,OAAO,MAAM,IAAI,UAAU,eAAe,IAAI,QAAQ,MAAM;EAClE,IAAI,CAAC,MACH,OAAO,6BAA6B,OAAO;EAG7C,OAAO;GACL,UAAU,KAAK,OAAO,KAAK,iBAAiB,IAAI,EAAE,SAAS,eAAe,KAAK,UAAU,EAAE;GAC3F,cAAc,YAAY,KAAK,SAAS,EAAE;GAC1C,cAAc,KAAK;EACrB,EAAE,KAAK,IAAI;CACb;AACF;;;AC+BA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAMA,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;AACF;AAQA,MAAM,mBAA2D;CAC/D,eAAe;CACf,mBAAmB;CACnB,cAAc;CACd,gBAAgB;CAChB,0BAA0B;CAC1B,6BAA6B;CAC7B,mBAAmB;CACnB,eAAe;CACf,cAAc;CACd,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,mBAAmB;CACnB,uBAAuB;CACvB,cAAc;AAChB;AAEA,MAAM,2BAA0E;CAC9E,uBAAuB;CACvB,aAAa;CACb,iBAAiB;CACjB,kBAAkB;AACpB;AAwBA,MAAM,uCAAuB,IAAI,QAAyB;AAE1D,SAAS,kBAAkB,SAA0B;CACnD,IAAI,UAAU,qBAAqB,IAAI,OAAO;CAC9C,IAAI,YAAY,KAAA,GACd,UAAU,QAAQ,KAAK,QAAO,OAAM,EAAE,SAAS,KAAK,CAAC,EAAE;CACzD,WAAW;CACX,qBAAqB,IAAI,SAAS,OAAO;CACzC,OAAO,SAAS;AAClB;AAMA,SAAS,YAAY,SAA0B;CAC7C,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAET,MAAM,MAAM;CAEZ,IAAI,OAAO,IAAI,YAAY,UACzB,OAAO,IAAI;CAEb,IAAI,MAAM,QAAQ,IAAI,OAAO,GAC3B,OAAO,IAAI,QACR,QAAQ,UAA4C,CAAC,CAAC,SAAS,OAAO,UAAU,YAAa,MAAkC,SAAS,MAAM,EAC9I,KAAI,UAAS,MAAM,IAAI,EACvB,KAAK,IAAI;CAGd,OAAO;AACT;;;;;;;;AASA,MAAM,yBAAyB;CAAC;CAAa;CAAQ;CAAQ;AAAY;;;;;;;;;;AAWzE,SAAS,uBACP,aACA,KACqC;CACrC,IAAI,CAAC,aACH,OAAO;CACT,MAAM,WAAW,IAAI;CAMrB,IAAI,YAAY,SAAS,SAAS,GAAG;EACnC,MAAM,SAAS,IAAI,IAAI,QAAQ;EAC/B,MAAM,WAAoC,CAAC;EAC3C,KAAK,MAAM,CAAC,aAAa,MAAM,OAAO,QAAQ,WAAW,GACvD,IAAI,OAAO,IAAI,EAAE,KAAK,IAAI,GACxB,SAAS,eAAe;EAE5B,OAAO;CACT;CACA,IAAI,IAAI,UAAU;EAChB,MAAM,SAAS,IAAI,IAAY,sBAAsB;EACrD,MAAM,WAAoC,CAAC;EAC3C,KAAK,MAAM,CAAC,aAAa,MAAM,OAAO,QAAQ,WAAW,GACvD,IAAI,OAAO,IAAI,EAAE,KAAK,IAAI,GACxB,SAAS,eAAe;EAE5B,OAAO;CACT;CACA,OAAO;AACT;;;;;;;AAQA,SAAS,6BAA6B,UAAoC;CACxE,MAAM,QAAkB,CAAC;CACzB,IAAI,SAAS;CACb,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,QAAQ,GAC9C,IAAI,IAAI,aAAa;EACnB,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI,aAAa;EAC3C,SAAS;CACX,OAEE,MAAM,KAAK,MAAM,IAAI,EAAE;CAG3B,MAAM,KAAK,iFAAgF;CAC3F,IAAI,CAAC,QACH,OAAO,qCAAqC,MAAM,KAAI,MAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,QAAQ,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;CAElH,OAAO,sEAAsE,MAAM,KAAK,IAAI;AAC9F;;;;;;;;;;;;;AAcA,eAAe,gBACb,MACA,WACY;CACZ,IAAI,CAAC,aAAa,aAAa,GAC7B,OAAO;CAET,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,IAAI,SAAY,SAAS,WAAW;GAC/C,QAAQ,iBAAiB,OAAO,IAAI,kBAAkB,SAAS,CAAC,GAAG,SAAS;GAC5E,KAAK,KAAK,SAAS,MAAM;EAC3B,CAAC;CACH,UACQ;EACN,IAAI,OACF,aAAa,KAAK;CACtB;AACF;AAEA,IAAM,oBAAN,cAAgC,MAAM;CACpC;CACA,YAAY,WAAmB;EAC7B,MAAM,+BAA+B,UAAU,GAAG;EAClD,KAAK,OAAO;EACZ,KAAK,YAAY;CACnB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAS,mBAAmB,WAAmB,KAAoB;CACjE,IAAI,CAAC,QAAQ,IAAI,cACf;CACF,MAAM,UAAU,eAAe,QAAS,IAAI,SAAS,IAAI,UAAW,OAAO,GAAG;CAC9E,QAAQ,OAAO,MAAM,uCAAuC,UAAU,cAAc,QAAQ,GAAG;AACjG;AAEA,SAAS,YACP,YACA,aACA,SACA,OACY;CACZ,MAAM,cAAiC,CAAC;CAIxC,MAAM,OAAO,YAAY;CAazB,KAAK,MAAM,OAAO,gBAAgB;EAChC,MAAM,YAAY,iBAAiB;EACnC,MAAM,aAAa,WAAW,KAAK,MAAM,QAAgB;GACvD,QAAQ,QAAQ,KAAK,WAAW;IAAE,GAAI;IAAiC;IAAS;GAAM,CAAC,CAAC,EACrF,OAAM,QAAO,mBAAmB,WAAW,GAAG,CAAC;EACpD,CAAC;EACD,YAAY,KAAK,UAAU;CAC7B;CAOA,MAAM,YAAY,QAAiC;EACjD,IAAI,YAAY;EAChB,IAAI,UAAU;CAChB;CACA,KAAK,MAAM,OAAO,wBAAwB;EACxC,MAAM,YAAY,yBAAyB;EAC3C,MAAM,aAAa,WAAW,KAAK,KAAK,OAAO,QAAgB;GAC7D,SAAS,GAA8B;GACvC,MAAM,KAAK,WAAW,GAA8B;EACtD,CAAC;EACD,YAAY,KAAK,UAAU;CAC7B;CAKA,MAAM,YAAY,WAAW;CAI7B,KAAK,MAAM,OAAO,gBAAgB;EAChC,MAAM,YAAY,iBAAiB;EACnC,YAAY,KAAK,UAAU,YAAY,QAAQ;GAC7C,QAAQ,QAAQ,KAAK,WAAW,GAA8B,CAAC,EAC5D,OAAM,QAAO,mBAAmB,WAAW,GAAG,CAAC;EACpD,CAAC,CAAC;CACJ;CACA,KAAK,MAAM,OAAO,wBAAwB;EACxC,MAAM,YAAY,yBAAyB;EAO3C,IAAI,cAAc,KAChB;EACF,YAAY,KAAK,UAAU,WAAW,OAAO,QAAQ;GAInD,MAAM,KAAK,WAAW,GAA8B;EACtD,CAAC,CAAC;CACJ;CAEA,aAAa;EACX,KAAK,MAAM,KAAK,aAAa,EAAE;CACjC;AACF;;;;;;;;;AAsKA,SAAgB,gBAAgB,UAA4B,CAAC,GAA6B;CACxF,MAAM,gCAAgB,IAAI,IAAwB;CAClD,IAAI,eAAe;CACnB,IAAI,mBAAmB;CACvB,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,eAAe,QAAQ,gBAAgB;CAE7C,MAAM,aAAyB;EAC7B,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,oBAAoB;EACpB,OAAO;EACP,SAAS;CACX;CASA,MAAM,mBAAmB,QAAQ;CAEjC,MAAM,mBADqB,CAAC,CAAC,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,SAAS,IAEpF,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,gBAAiB,GAAG,iBAAiB,CAAC,CAAC,IACnE,CAAC;CAWL,OAAO;EACL,IAAI,WAAW;GAAE,OAAO;EAAc;EACtC,IAAI,kBAAkB;GAAE,OAAO,EAAE,GAAG,WAAW;EAAE;EAQjD,mBAAmB;EAEnB,MAAM;GACJ,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY;KACV,MAAM;MACJ,MAAM;MACN,aAAa;KACf;KACA,QAAQ;MACN,MAAM;MACN,aAAa;KACf;KACA,GApCqB,iBAAiB,SAAS,IACnD,EACE,eAAe;MACb,MAAM;MACN,MAAM;MACN,aAAa,6BAA6B,gBAAiB;KAC7D,EACF,IACA,CAAC;IA6BC;IACA,UAAU,CAAC,MAAM;GACnB;EACF;EAEA,MAAM,QAAQ,OAAgC,KAAmC;GAC/E,MAAM,OAAO,MAAM;GACnB,MAAM,iBAAiB,MAAM;GAC7B,MAAM,wBAAwB,OAAO,MAAM,kBAAkB,WACzD,MAAM,gBACN,KAAA;GAMJ,MAAM,cAAc,yBAAyB,mBACxC,iBAAiB,0BAA0B,KAAA,IAC5C,KAAA;GACJ,MAAM,cAAc,IAAI,SAAS;GACjC,MAAM,aAAa,cAAc;GAKjC,IAAI,aAAa,UACf,OAAO,0BAA0B,SAAS,yBAAyB,YAAY;GAGjF,IAAI,oBAAoB,eACtB,OAAO,iBAAiB,iBAAiB,GAAG,cAAc;GAM5D,IAAI,IAAI,OAAO,SACb,OAAO,wEAAwE,KAAK,MAAM,GAAG,EAAE,EAAE;GAQnG,MAAM,KAAK,IAAI,UACX,kBAAkB,IAAI,OAAO,IAC7B,SAAS,EAAE;GACf;GACA,MAAM,QAAoB;IAAE;IAAI;IAAM,WAAW,KAAK,IAAI;IAAG,OAAO;GAAW;GAC/E,cAAc,IAAI,IAAI,KAAK;GAE3B,IAAI;GACJ,IAAI,iBAAuD;GAC3D,IAAI;GACJ,IAAI,SAAS;GAIb,IAAI;GAEJ,IAAI;IAKF,MAAM,gBAAgB,cAClB,uBAAuB,IAAI,OAAO,WAAW,IAC7C,IAAI;IAER,MAAM,eAAuB;KAC3B,GAAI,IAAI,SAAS,KAAA,IAAY,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KACnD,GAAI,IAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;KACzD,OAAO;KACP,GAAI,IAAI,gBAAgB,KAAA,IAAY,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;KACxE,GAAI,IAAI,eAAe,KAAA,IAAY,EAAE,YAAY,IAAI,WAAW,IAAI,CAAC;KACrE,GAAI,IAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;KACzD,GAAI,IAAI,aAAa,KAAA,IAAY,EAAE,UAAU,IAAI,SAAS,IAAI,CAAC;IACjE;IAUA,MAAM,kBAAkB,QAAQ,iBAC5B,oBAAoB,GAAG,IACvB,KAAA;IACJ,MAAM,QAAQ,YAAY;KACxB,GAAG;KACH,GAAG,QAAQ;KACX,UAAU,IAAI;KACd,WAAW,IAAI;KAIf,GAAI,QAAQ,WAAW,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;KACjE,GAAI,kBAAkB,EAAE,WAAW,gBAAgB,IAAI,CAAC;IAC1D,CAAC;IAED,IAAI,cAAc;KAmBhB,MAAM,qBAAqB,MAAM,MAAM,KAAK,eAAe,OAAO,YAAY;MAC5E,IAAI,QAAQ,SAAS,gBAAgB,QAAQ,SAAS,UAAU,QAAQ,SAAS,cAC/E;MACF,IAAI,CAAC,MAAM,QACT;MACF,MAAM,YAAY,QAAQ,OAAO;MACjC,IAAI,OAAO,cAAc,UACvB;MACF,IAAI;OACF,QAAQ,eAAe,MAAM,MAAM,UAAU,SAAS,MAAM,QAAQ,SAAS;MAC/E,QACM,CAMN;KACF,CAAC;KACD,MAAM,gBAAgB,YAAY,MAAM,OAAO,IAAI,OAAO,IAAI,UAAU;KACxE,iBAAiB;MACf,mBAAmB;MACnB,cAAc;KAChB;IACF;IAEA,QAAQ,UAAU,KAAK;IAOvB,MAAM,eAAoG;KACxG;KACA;KACA,OAAO;KACP,gBAAgB,CAAC;IACnB;IACA,MAAM,IAAI,MAAM,SAAS,gBAAgB,YAAY;IAOrD,MAAM,oBAAoB,OAAO,KAAK,aAAa,cAAc,EAAE,SAAS,IACxE,OAAO,OAAO,EAAE,GAAG,aAAa,eAAe,CAAC,IAChD,KAAA;IAQJ,MAAM,kBACF,kBACG,aAAa,UACb,QAAQ;IAMf,MAAM,aAAa,MAAM,IAAI;KAC3B,QAAQ;KACR,OAAO,QAAQ,SAAS,IAAI;KAC5B,QAAQ;KACR,UAAU,QAAQ;KAClB,QAAQ,IAAI;KACZ,OAAO;KACP,GAAI,QAAQ,WAAW,IAAI,QAAQ,EAAE,aAAa,IAAI,MAAM,IAAI,CAAC;KACjE,GAAI,oBAAoB,EAAE,gBAAgB,kBAAkB,IAAI,CAAC;IACnE,CAAC;IAED,IAAI;KACF,aAAa,MAAM,gBAAgB,YAAY,QAAQ,SAAS;KAOhE,MAAM,YAAY,aAAa,UAAU,EAAE;KAI3C,MAAM,QAAQ,iBAAiB,UAAU;KACzC,IAAI,IAAI,OAAO,SAAS;MACtB,iBAAiB;MACjB,SAAS,CACP,cAAc,GAAG,kBAAkB,UAAU,UAAU,WAAW,QAAQ,MAC1E,WAAW,OACb,EAAE,KAAK,IAAI;KACb,OACK;MACH,MAAM,WAAW,YAAY,MAAM,MAAM,GAAG,EAAE,CAAC;MAC/C,SAAS;OACP,cAAc,GAAG,iBAAiB,UAAU,UAAU,WAAW,QAAQ;OACzE,WAAW;OACX;OACA,YAAY;MACd,EAAE,KAAK,IAAI;KACb;IACF,SACO,KAAK;KACV,IAAI,eAAe,mBAAmB;MACpC,iBAAiB;MACjB,MAAM,MAAM;MAIZ,IAAI;OACF,aAAa,MAAM;MACrB,QACM;OACJ,aAAa;QACX,SAAS;QACT,UAAU;QACV,gBAAgB;QAChB,oBAAoB;QACpB,OAAO;QACP,SAAS,IAAI;OACf;MACF;MACA,SAAS,cAAc,GAAG,oBAAoB,IAAI,UAAU;KAC9D,OACK;MACH,MAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;MAChE,iBAAiB;MACjB,aAAa;OACX,SAAS;OACT,UAAU;OACV,gBAAgB;OAChB,oBAAoB;OACpB,OAAO;OACP,SAAS;MACX;MACA,SAAS,cAAc,GAAG,WAAW,MAAM;MAC3C,MAAM,IAAI,MAAM,SAAS,eAAe;OAAE;OAAI;OAAM,OAAO;OAAY;MAAM,CAAC;KAChF;IACF,UACQ;KAwBN,MAAM,cAAc,MAAM;KAC1B,IAAI,eAAe,IAAI,UAAU,yBAC/B,IAAI;MACF,MAAM,aAAa,MAAM,IAAI,UAAU,wBACrC,aACA,IAAI,SACH,SAAS;OACR,QAAa,QAAQ,IAAI,MAAM,SAAS,mBAAmB,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;MAClF,CACF;MACA,KAAK,MAAM,SAAS,YAClB,MAAM,IAAI,MAAM,SAAS,uBAAuB;OAC9C,QAAQ,MAAM;OACd,cAAc,YAAY;OAC1B,YAAY,IAAI,OAAO;OACvB,SAAS;OACT,KAAK,MAAM;OACX,SAAS,MAAM;OACf,YAAY,MAAM;OAClB,WAAW,MAAM;MACnB,CAAC;KAEL,SACO,KAAK;MAKV,IAAI,QAAQ,IAAI,cACd,QAAQ,OAAO,MAAM,kDAAkD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,GAAG;KAC/H;KAKF,IAAI;MACF,MAAM,MAAM,QAAQ;KACtB,SACO,KAAK;MACV,eAAe,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;KACnE;IACF;IAIA,IAAI,YAAY;KACd,WAAW,WAAW,WAAW;KACjC,WAAW,YAAY,WAAW;KAClC,WAAW,kBAAkB,WAAW;KACxC,WAAW,sBAAsB,WAAW;KAC5C,WAAW,SAAS,WAAW;KAI/B,WAAW,WAAW,WAAW;IACnC;IAKA,MAAM,gBAA+B;KACnC;KACA;KACA,OAAO;KACP,OAAO;KACP,QAAQ;KACR,GAAI,WAAY,SAAS,EAAE,QAAQ,WAAY,OAAO,IAAI,CAAC;IAC7D;IACA,QAAQ,aAAa,OAAO,YAAa,cAAc;IACvD,MAAM,IAAI,MAAM,SAAS,kBAAkB,aAAa;IAExD,IAAI,cAGF,MAAM,IAAI,MAAM,SAAS,eAAe;KACtC;KACA;KACA,OAAO;KACP,OAAO;IACT,CAAC;IAGH,OAAO;GACT,UACQ;IACN,WAAW;IACX;IACA,cAAc,OAAO,EAAE;GACzB;EACF;CACF;AACF;;;;;;;;;;;;;;;;;;AC/gCA,MAAa,YAAqB;CAChC,MAAM;EACJ,MAAM;EACN,aAAa;EACb,aAAa;GACX,MAAM;GACN,YAAY;IACV,MAAM;KAAE,MAAM;KAAU,aAAa;IAAkE;IACvG,SAAS;KAAE,MAAM;KAAU,aAAa;IAAiE;GAC3G;GACA,UAAU,CAAC,QAAQ,SAAS;EAC9B;CACF;CACA,MAAM,QAAQ,EAAE,MAAM,WAAW,KAAkB;EACjD,MAAM,aAAa;EACnB,MAAM,gBAAgB;EAItB,MAAM,UAAU,aAAa,UAAU;EACvC,IAAI,SAAS;GACX,IAAI,gBAAgB,QAAQ;GAC5B,OAAO,gBAAgB;EACzB;EAEA,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,IAAI,UAAU,SAAS,IAAI,QAAQ,UAAU;EAChE,QACM,CAGN;EAEA,MAAM,QAAQ,OAAO,WAAW,aAAa;EAE7C,IAAI,aAAa,eAAe;GAC9B,IAAI,gBAAgB,MAAM;GAC1B,OAAO,qBAAqB,WAAW,4BAA4B,MAAM;EAC3E;EAEA,MAAM,IAAI,UAAU,UAAU,IAAI,QAAQ,YAAY,aAAa;EASnE,MAAM,YAAY,oBAAoB,GAAG;EACzC,IAAI,WACF,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK,UAAU,GAAG;GACtD,aAAa,YAAY,aAAa;GACtC,QAAQ;GACR,OAAO,OAAO;GACd,UAAU,OAAO;GACjB,SAAS,KAAK,IAAI;EACpB,CAAC;EAGH,IAAI,gBAAgB,aAAa,KAAA,IAAY,YAAY,SAAS;EAClE,OAAO,aAAa,KAAA,IAChB,WAAW,WAAW,IAAI,MAAM,YAChC,WAAW,WAAW,IAAI,MAAM;CACtC;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcript-anchors-BHIgMlPq.d.ts","names":[],"sources":["../src/chat/agents.ts","../src/chat/hints.ts","../src/chat/completion.ts","../src/start/shared-options.ts","../src/chat/keybindings.ts","../src/chat/store.ts","../src/chat/xdg.ts","../src/chat/config.ts","../src/chat/mcps-discovery.ts","../src/chat/enabled-toggle-set.ts","../src/chat/interactions.tsx","../src/chat/markdown-segments.ts","../src/chat/session-export.ts","../src/chat/theme.ts","../src/chat/transcript-anchors.ts"],"mappings":"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"}