@zaly/agent 0.0.12 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/{agent-Dp4LZDSo.mjs → agent-BRENvuvx.mjs} +8 -11
  2. package/dist/{agent-Dp4LZDSo.mjs.map → agent-BRENvuvx.mjs.map} +1 -1
  3. package/dist/{agent-B7cQOuMZ.mjs → agent-sHtwQDAk.mjs} +2 -3
  4. package/dist/{agent-B7cQOuMZ.mjs.map → agent-sHtwQDAk.mjs.map} +1 -1
  5. package/dist/{bash-COgq4W7U.mjs → bash-DSy03sAj.mjs} +8 -9
  6. package/dist/bash-DSy03sAj.mjs.map +1 -0
  7. package/dist/compactions-HFjEgrv3.mjs +150 -0
  8. package/dist/compactions-HFjEgrv3.mjs.map +1 -0
  9. package/dist/{edit-D4yaBK1K.mjs → edit-DT672zIy.mjs} +2 -3
  10. package/dist/edit-DT672zIy.mjs.map +1 -0
  11. package/dist/{env-UUFv5Mye.mjs → env-C8p8i1E0.mjs} +2 -3
  12. package/dist/{env-UUFv5Mye.mjs.map → env-C8p8i1E0.mjs.map} +1 -1
  13. package/dist/fetch-BrtIqrid.mjs +158 -0
  14. package/dist/fetch-BrtIqrid.mjs.map +1 -0
  15. package/dist/{find-CimUGn-L.mjs → find-B-vvdlHu.mjs} +30 -13
  16. package/dist/find-B-vvdlHu.mjs.map +1 -0
  17. package/dist/{grep-6O3mjSvV.mjs → grep-rvZ5S319.mjs} +19 -10
  18. package/dist/grep-rvZ5S319.mjs.map +1 -0
  19. package/dist/html-VrAsoGBK.mjs +32950 -0
  20. package/dist/html-VrAsoGBK.mjs.map +1 -0
  21. package/dist/{index-node-esm-CJsN8G51.mjs → index-node-esm-BwaOzhXB.mjs} +2 -3
  22. package/dist/{index-node-esm-CJsN8G51.mjs.map → index-node-esm-BwaOzhXB.mjs.map} +1 -1
  23. package/dist/index.d.mts +72 -100
  24. package/dist/index.d.mts.map +1 -1
  25. package/dist/index.mjs +3 -3
  26. package/dist/{jsonl-CvgEOakL.mjs → jsonl-BGt7eqPK.mjs} +2 -3
  27. package/dist/{jsonl-CvgEOakL.mjs.map → jsonl-BGt7eqPK.mjs.map} +1 -1
  28. package/dist/{manager-BqlbCGYV.mjs → manager-1zEE5WiA.mjs} +4 -6
  29. package/dist/{manager-BqlbCGYV.mjs.map → manager-1zEE5WiA.mjs.map} +1 -1
  30. package/dist/{markdown-Bv4J8cg3.mjs → markdown-8ICz5aFw.mjs} +2 -3
  31. package/dist/{markdown-Bv4J8cg3.mjs.map → markdown-8ICz5aFw.mjs.map} +1 -1
  32. package/dist/{masker-ZoP381jN.mjs → masker-DEgR_ntk.mjs} +4 -6
  33. package/dist/{masker-ZoP381jN.mjs.map → masker-DEgR_ntk.mjs.map} +1 -1
  34. package/dist/{model-_3ZA2xqm.mjs → model-DqGqxfAc.mjs} +2 -3
  35. package/dist/{model-_3ZA2xqm.mjs.map → model-DqGqxfAc.mjs.map} +1 -1
  36. package/dist/{notify-DpG_m9iP.mjs → notify-Ds0-4BeI.mjs} +2 -3
  37. package/dist/{notify-DpG_m9iP.mjs.map → notify-Ds0-4BeI.mjs.map} +1 -1
  38. package/dist/{read-B-hwcc2Q.mjs → read-C5keKntU.mjs} +4 -44
  39. package/dist/read-C5keKntU.mjs.map +1 -0
  40. package/dist/{registry-L9GDccS0.mjs → registry-CntkeXlo.mjs} +45 -45
  41. package/dist/registry-CntkeXlo.mjs.map +1 -0
  42. package/dist/rolldown-runtime-DYf_mQCB.mjs +34 -0
  43. package/dist/{search-CRw247ES.mjs → search-B-89W3SM.mjs} +20 -17
  44. package/dist/search-B-89W3SM.mjs.map +1 -0
  45. package/dist/session/claude.d.mts +0 -2
  46. package/dist/session/claude.d.mts.map +1 -1
  47. package/dist/session/claude.mjs +4 -6
  48. package/dist/session/claude.mjs.map +1 -1
  49. package/dist/{session-BSvUrr12.mjs → session-C8zqqbPE.mjs} +6 -8
  50. package/dist/{session-BSvUrr12.mjs.map → session-C8zqqbPE.mjs.map} +1 -1
  51. package/dist/{session-Ds5nJz5A.d.mts → session-Cq52cam5.d.mts} +1 -11
  52. package/dist/session-Cq52cam5.d.mts.map +1 -0
  53. package/dist/session.d.mts +1 -3
  54. package/dist/session.d.mts.map +1 -1
  55. package/dist/session.mjs +4 -5
  56. package/dist/{src-C852Q6gy.mjs → src-C04Qk9KE.mjs} +35 -39
  57. package/dist/{src-C852Q6gy.mjs.map → src-C04Qk9KE.mjs.map} +1 -1
  58. package/dist/{subagent-C8XCEecM.mjs → subagent-BbcxLzgC.mjs} +4 -5
  59. package/dist/{subagent-C8XCEecM.mjs.map → subagent-BbcxLzgC.mjs.map} +1 -1
  60. package/dist/{swarm-BJ3gQA1Z.mjs → swarm-B_s9Qpbt.mjs} +2 -3
  61. package/dist/{swarm-BJ3gQA1Z.mjs.map → swarm-B_s9Qpbt.mjs.map} +1 -1
  62. package/dist/{swarm-BuFx_xeY.mjs → swarm-D823Yumk.mjs} +2 -3
  63. package/dist/{swarm-BuFx_xeY.mjs.map → swarm-D823Yumk.mjs.map} +1 -1
  64. package/dist/{tasks-WdRAHsOL.mjs → tasks-D76WXWr2.mjs} +3 -4
  65. package/dist/{tasks-WdRAHsOL.mjs.map → tasks-D76WXWr2.mjs.map} +1 -1
  66. package/dist/{tasks-BA-PCeGa.mjs → tasks-Dgsiuh0Q.mjs} +3 -4
  67. package/dist/{tasks-BA-PCeGa.mjs.map → tasks-Dgsiuh0Q.mjs.map} +1 -1
  68. package/dist/{tools-wvkkuXWH.mjs → tools-DmoUYORG.mjs} +7 -42
  69. package/dist/{tools-wvkkuXWH.mjs.map → tools-DmoUYORG.mjs.map} +1 -1
  70. package/dist/{truncate-BSMXgiXj.mjs → truncate-CChlZ113.mjs} +2 -3
  71. package/dist/{truncate-BSMXgiXj.mjs.map → truncate-CChlZ113.mjs.map} +1 -1
  72. package/dist/{uuid-CAdJg4l8.mjs → uuid-rfbQ9ad2.mjs} +2 -3
  73. package/dist/{uuid-CAdJg4l8.mjs.map → uuid-rfbQ9ad2.mjs.map} +1 -1
  74. package/dist/{wakeup-BYqTnfSp.mjs → wakeup-CFr1nu_L.mjs} +2 -3
  75. package/dist/{wakeup-BYqTnfSp.mjs.map → wakeup-CFr1nu_L.mjs.map} +1 -1
  76. package/dist/{write-DwGiDNeG.mjs → write-BRQFfWAn.mjs} +2 -3
  77. package/dist/write-BRQFfWAn.mjs.map +1 -0
  78. package/package.json +46 -8
  79. package/dist/bash-COgq4W7U.mjs.map +0 -1
  80. package/dist/compactions-CvQs64fS.mjs +0 -191
  81. package/dist/compactions-CvQs64fS.mjs.map +0 -1
  82. package/dist/edit-D4yaBK1K.mjs.map +0 -1
  83. package/dist/fetch-VKhSWdEh.mjs +0 -111
  84. package/dist/fetch-VKhSWdEh.mjs.map +0 -1
  85. package/dist/find-CimUGn-L.mjs.map +0 -1
  86. package/dist/grep-6O3mjSvV.mjs.map +0 -1
  87. package/dist/read-B-hwcc2Q.mjs.map +0 -1
  88. package/dist/registry-L9GDccS0.mjs.map +0 -1
  89. package/dist/search-CRw247ES.mjs.map +0 -1
  90. package/dist/session-Ds5nJz5A.d.mts.map +0 -1
  91. package/dist/write-DwGiDNeG.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tasks-WdRAHsOL.mjs","names":[],"sources":["../src/tasks.ts"],"sourcesContent":["import type {\n ContentPart,\n Message,\n MetaPart,\n TextPart,\n Tool,\n ToolCallPart,\n ToolContext,\n ToolResult,\n ToolResultPart,\n Streamable as TStreamable,\n} from \"@zaly/ai\"\n\nimport { AiError, isStreamable, runTool, stringifyContent, toErrorResult } from \"@zaly/ai\"\nimport { Emitter, safeStringify } from \"@zaly/shared\"\nimport { uuidv7 } from \"./utils/uuid.ts\"\n\nconst DEFAULT_GRACE_MS = 10_000\n\n/** Status of a task. `pending` = queued behind a dependency, not yet\n * started. `running` = work in progress (a Streamable is being polled).\n * `done` = result captured, no longer mutating. */\nexport type TaskStatus = \"pending\" | \"running\" | \"done\"\n\n/** Public projection of a registered task. Status-discriminated so the\n * fields visible at any moment are exactly the ones that make sense\n * for that lifecycle stage:\n *\n * - `running`: `elapsedMs` since start; `hasNewOutput` when the\n * streamable signals that `task_poll` would yield bytes.\n * - `pending`: queued behind another task (`waitingFor`); `elapsedMs`\n * counts time-since-registration.\n * - `done`: settled. Carries `durationMs` and the captured `result`.\n *\n * This is the only public task type — the registry exposes it via\n * `running()` / `finished()` / `get()`, events carry it (`task-done`\n * is narrowed to `status: \"done\"` so listeners get `result` typed\n * without checks), and `task_list` JSON-stringifies it directly. */\nexport type TaskInfo = {\n id: string\n type: string\n desc: string\n} & (\n | { status: \"running\"; elapsedMs: number; hasNewOutput?: boolean }\n | { status: \"pending\"; waitingFor: string; elapsedMs: number }\n | { status: \"done\"; durationMs: number; result: ToolResult }\n)\n\n/** A `TaskInfo` known to be in the `done` state. `task-done` event\n * payloads use this so listeners get `result` and `durationMs` typed\n * without manual narrowing. */\nexport type DoneTaskInfo = Extract<TaskInfo, { status: \"done\" }>\n\n/** Events emitted by a `Tasks` instance. `task-done` only fires for\n * completions that happen *outside* an in-flight `run()` round —\n * round-internal completions are folded into the `run()` return value\n * instead. `heartbeat` fires periodically (when `heartbeatMs` is set\n * and at least one task is active), giving the agent a hook to keep\n * the model engaged on long-running work. */\nexport type TasksEvents = {\n \"task-added\": { task: TaskInfo }\n \"task-removed\": { task: TaskInfo }\n \"task-done\": { task: DoneTaskInfo }\n heartbeat: { running: readonly TaskInfo[] }\n}\n\n/** Augment ToolMeta so tools and consumers can read freshness/state info\n * off `ToolResultPart.meta.task`. The registry stamps this on every\n * result it produces so the model can correlate placeholders to their\n * eventual completion. */\nexport interface TaskMeta {\n task?: {\n id: string\n status: TaskStatus\n type: string\n desc: string\n dependsOn?: string\n durationMs?: number\n }\n}\n\n/** Internal storage record. Not exposed — `toTaskInfo` projects it to\n * `TaskInfo` for any caller that crosses the boundary (events,\n * registry methods, the `task_*` tools). Carries everything the\n * registry needs to drive lifecycle transitions, plus the raw\n * timestamps `TaskInfo` derives elapsed/duration from. */\ninterface InternalTask {\n id: string\n type: string\n desc: string\n status: TaskStatus\n /** Wallclock at registration. */\n startedAt: number\n /** Wallclock at completion; set once status is `done`. */\n finishedAt?: number\n /** Captured result when status is `done`. */\n result?: ToolResult\n /** When set, this task is queued behind another and won't start until\n * the named task transitions to `done`. */\n waitingFor?: string\n /** Streamable returned by the tool, if any — held so we can `abort()`\n * on cancellation and call `poll()` for partial snapshots. */\n streamable?: TStreamable\n /** Resolves when the task transitions to `done`. Used by the round\n * race in `run()`. */\n donePromise: Promise<void>\n resolveDone: () => void\n /** When set, the task belongs to an in-flight `run()` round — its\n * completion does *not* fire `task-done` (the round folds it into the\n * returned parts instead). Cleared once the round ends. */\n ownerRound?: symbol\n /** Stashed call so a pending task can be restarted once its\n * dependency completes. */\n pending?: { tool: Tool; call: ToolCallPart; ctx: ToolContext }\n}\n\n/**\n * Tool registry + execution machinery + long-running task bookkeeping.\n * One Tasks instance per Agent. Owns the tool list (the agent delegates\n * `agent.tools` to it) and runs every assistant tool batch through\n * `run()`, which:\n *\n * - validates each call's params,\n * - dispatches to the named tool (sync results land immediately),\n * - races `Streamable` returns against a grace window,\n * - chains `parallel: false` calls behind their predecessors,\n * - returns `ToolResultPart[]` 1:1 with the assistant's calls,\n * surfacing partial results / placeholders for anything still running\n * when the grace expires.\n *\n * Completions during a round are folded into the returned parts and do\n * NOT fire `task-done`. Completions afterward fire normally — the agent\n * listens and injects a system message into the next step.\n */\nexport class Tasks extends Emitter<TasksEvents> {\n readonly #map = new Map<string, InternalTask>()\n graceMs = DEFAULT_GRACE_MS\n\n #tools: (() => Promise<readonly Tool[]>) | Tool[] = []\n\n /** Heartbeat interval in ms. When set, fires `heartbeat` events while\n * at least one task is pending or running. Self-managing: starts on\n * the first active task, stops when the last one finishes. Set to\n * `undefined` to disable. */\n #heartbeatMs?: number\n #heartbeatTimer?: ReturnType<typeof setInterval>\n\n get heartbeatMs(): number | undefined {\n return this.#heartbeatMs\n }\n set heartbeatMs(value: number | undefined) {\n this.#heartbeatMs = value\n this.#syncHeartbeat()\n }\n\n // ── Public registry surface ─────────────────────────────────────────\n\n /** Snapshot of every active task (pending or running). */\n running(): readonly TaskInfo[] {\n return [...this.#map.values()].filter((t) => t.status !== \"done\").map((t) => toTaskInfo(t))\n }\n\n /** Snapshot of every task that has completed. Drops are by `remove()`\n * or implicit retention; this list grows unless the caller prunes. */\n finished(): readonly DoneTaskInfo[] {\n return [...this.#map.values()]\n .filter((t): t is InternalTask & { status: \"done\" } => t.status === \"done\")\n .map((t) => toTaskInfo(t) as DoneTaskInfo)\n }\n\n /** Look up a task by id. Useful for `task_stop` / `task_poll`. */\n get(id: string): TaskInfo | undefined {\n const t = this.#map.get(id)\n return t ? toTaskInfo(t) : undefined\n }\n\n /** Snapshot of every task in the registry — running, pending, and done. */\n info(): readonly TaskInfo[] {\n return [...this.#map.values()].map(toTaskInfo)\n }\n\n async tools(): Promise<readonly Tool[]> {\n return typeof this.#tools === \"function\" ? this.#tools() : this.#tools\n }\n\n set $tools(tools: (() => Promise<readonly Tool[]>) | Tool[]) {\n this.#tools = tools\n }\n\n /** Non-consuming check: does the underlying streamable have output\n * the model hasn't seen since the last `poll()`? Returns false for\n * tasks without a streamable, completed tasks, or streamables that\n * don't implement the optional `hasNew` hook (no signal to give).\n * Used by heartbeats to flag tasks worth polling. */\n hasNewOutput(id: string): boolean {\n const t = this.#map.get(id)\n if (t?.status !== \"running\" || !t.streamable) return false\n return t.streamable.hasNew?.() ?? false\n }\n\n /** Poll a task's streamable for incremental output without changing\n * its lifecycle state. Advances the streamable's cursor — the next\n * call returns only what arrived since *this* one. Returns the same\n * `ToolResult` shape the original tool produces (parts + meta).\n * Errors when the task is unknown, already done, or has no streamable\n * (the latter is the case for plain-Promise tools — there's no\n * partial state to read). */\n pollOutput(id: string): ToolResult & { running: boolean } {\n const t = this.#map.get(id)\n if (!t) {\n throw new AiError({\n code: \"NOT_FOUND\",\n data: { id },\n message: `no task with id \"${id}\"`,\n })\n }\n if (t.status === \"done\") {\n throw new AiError({\n code: \"TASK_DONE\",\n data: { id },\n message: `task \"${id}\" has already completed; its result was injected as a system message`,\n })\n }\n if (!t.streamable) {\n throw new AiError({\n code: \"NOT_STREAMABLE\",\n data: { id },\n message:\n `task \"${id}\" has no incremental output — it's a plain-Promise tool ` +\n `whose result is delivered all-at-once when complete`,\n })\n }\n return t.streamable.poll()\n }\n\n /** Drop a task from the registry — does not abort. Caller is\n * responsible for `abort()`-ing if the task is still running. */\n remove(id: string): boolean {\n const task = this.#map.get(id)\n if (!task) return false\n this.#map.delete(id)\n void this.emit(\"task-removed\", { task: toTaskInfo(task) })\n return true\n }\n\n /** Mark a task done with a final result. Fires `task-done` UNLESS the\n * task is currently owned by an in-flight `run()` round — in that\n * case the round folds the completion into its returned parts and\n * the event is suppressed. Starts any pending dependents. */\n done(id: string, result: ToolResult): void {\n const task = this.#map.get(id)\n if (!task || task.status === \"done\") return\n task.status = \"done\"\n task.result = result\n task.finishedAt = Date.now()\n task.resolveDone()\n if (!task.ownerRound) {\n void this.emit(\"task-done\", { task: toTaskInfo(task) as DoneTaskInfo })\n }\n this.#startReadyDependents(id, result)\n this.#syncHeartbeat()\n }\n\n /** Abort a running task. Calls the streamable's `abort()` if present;\n * pending tasks transition straight to `done` with a cancelled\n * result. Idempotent. */\n abort(id: string, reason = \"aborted by request\"): void {\n const task = this.#map.get(id)\n if (!task || task.status === \"done\") return\n if (task.streamable) task.streamable.abort()\n if (task.status === \"pending\") {\n this.done(id, toErrorResult(new AiError({ code: \"TASK_ABORTED\", message: reason })))\n }\n // Running tasks: the streamable will eventually settle and call done()\n // via its watcher. We could force a synchronous \"done\" here, but\n // letting the streamable's natural completion path run keeps the\n // final snapshot accurate (output that arrived before abort lands).\n }\n\n /** Abort every active task. Used on agent dispose. Awaits each\n * task's `donePromise` so the registry is fully drained before\n * resolving — so callers can rely on no pending I/O after `dispose`. */\n async killAll(): Promise<void> {\n const active = [...this.#map.values()].filter((t) => t.status !== \"done\")\n for (const t of active) {\n if (t.streamable) t.streamable.abort()\n if (t.status === \"pending\") {\n this.done(\n t.id,\n toErrorResult(new AiError({ code: \"TASK_ABORTED\", message: \"agent disposed\" }))\n )\n }\n }\n await Promise.all(active.map((t) => t.donePromise.catch(() => undefined)))\n this.#syncHeartbeat()\n }\n\n /** Start or stop the heartbeat timer based on whether any task is\n * active and whether `heartbeatMs` is configured. Idempotent — called\n * after every state transition (`add` / `done` / `killAll`). The\n * timer is `unref`'d so it never holds the process open. */\n #syncHeartbeat(): void {\n const hasActive = [...this.#map.values()].some((t) => t.status !== \"done\")\n const want = hasActive && this.#heartbeatMs !== undefined\n if (want && !this.#heartbeatTimer) {\n this.#heartbeatTimer = setInterval(() => {\n void this.emit(\"heartbeat\", { running: this.info().filter((t) => t.status !== \"done\") })\n }, this.#heartbeatMs)\n this.#heartbeatTimer.unref()\n } else if (!want && this.#heartbeatTimer) {\n clearInterval(this.#heartbeatTimer)\n this.#heartbeatTimer = undefined\n }\n }\n\n // ── Batch execution ─────────────────────────────────────────────────\n\n /**\n * Execute a batch of assistant tool calls. Returns ToolResultPart[]\n * mapped 1:1 with `calls`. Sync completions land in the result array\n * immediately; long-running ones return a placeholder and the eventual\n * completion fires `task-done` post-round (the agent injects a system\n * message in response).\n *\n * The `messages` snapshot is what tools see on `ctx.messages` — pass\n * the conversation up to (and including) the assistant message that\n * produced these calls, so freshness checks can scan back through\n * prior tool results.\n */\n async run(\n calls: readonly ToolCallPart[],\n ctx: ToolContext,\n opts: { onResult?: (call: ToolCallPart, result: ToolResultPart, idx: number) => void } = {}\n ): Promise<ToolResultPart[]> {\n const round = Symbol(\"round\")\n const tasks: InternalTask[] = []\n let chainHead: string | undefined\n\n const tools = await this.tools()\n\n for (const call of calls) {\n const tool = tools.find((t) => t.name === call.name)\n if (!tool) {\n tasks.push(this.#startSyncResult(call, unknownToolResult(call.name), round))\n continue\n }\n\n const parallel = tool.parallel ?? false\n\n if (chainHead && !parallel) {\n // Queue behind the chain head — won't start until that finishes.\n tasks.push(\n this.#registerPending({ call, ctxBase: ctx, round, tool, waitingFor: chainHead })\n )\n chainHead = tasks[tasks.length - 1].id\n continue\n }\n\n if (this.#needsPreflight(tool, ctx)) {\n // Preflight is intentionally sequential: permission prompts should\n // appear one at a time and should not register/background a task while\n // waiting for the user's answer.\n // oxlint-disable-next-line no-await-in-loop\n const preflight = await this.#preflight(tool, call, ctx)\n if (preflight) {\n tasks.push(this.#startSyncResult(call, preflight, round))\n continue\n }\n }\n\n const task = this.#start({ call, ctxBase: ctx, round, tool })\n tasks.push(task)\n // If this call promoted to a long-running task and `parallel: false`,\n // subsequent serial calls chain behind it.\n if (task.status === \"running\" && !parallel) chainHead = task.id\n }\n\n const parts: ToolResultPart[] = []\n\n const resultPart = (idx: number): ToolResultPart => {\n if (parts[idx]) return parts[idx]\n const task = tasks[idx]\n if (task.status !== \"done\") task.ownerRound = undefined\n const call = calls[idx]\n const part = this.#buildPart(call, task)\n parts[idx] = part\n return part\n }\n\n let onResult = opts.onResult\n\n // Race: every task done, OR grace expires, OR ctx.signal aborts.\n const allDone = Promise.all(\n tasks.map(async (t, ti) => {\n await t.donePromise\n onResult?.(calls[ti], resultPart(ti), ti)\n })\n )\n const grace = sleep(this.graceMs)\n const aborted = ctx.signal\n ? new Promise<void>((resolve) => {\n if (ctx.signal!.aborted) resolve()\n else ctx.signal!.addEventListener(\"abort\", () => resolve(), { once: true })\n })\n : new Promise<void>(() => undefined) // never resolves\n await Promise.race([allDone, grace, aborted])\n onResult = undefined\n\n // Release ownership on still-active tasks BEFORE building the result\n // array, so the post-round listener sees them as free-floating if\n // they happen to settle in the same tick.\n return tasks.map((_, i) => resultPart(i))\n }\n\n // ── Internals ──────────────────────────────────────────────────────\n\n /** Build a \"done\" task synchronously from a precomputed result.\n * Used for unknown-tool errors and validation failures. */\n #startSyncResult(call: ToolCallPart, result: ToolResult, round: symbol): InternalTask {\n // oxlint-disable-next-line sort-keys -- semantic field order\n const task = this.#allocate({ id: uuidv7(), type: call.name, desc: call.name, round })\n task.status = \"done\"\n task.result = result\n task.finishedAt = task.startedAt\n task.resolveDone()\n return task\n }\n\n /** Allocate an internal task record, register it, and emit `task-added`. */\n #allocate(opts: {\n id: string\n type: string\n desc: string\n waitingFor?: string\n round: symbol\n }): InternalTask {\n let resolveDone!: () => void\n const donePromise = new Promise<void>((r) => {\n resolveDone = r\n })\n const task: InternalTask = {\n desc: opts.desc,\n donePromise,\n id: opts.id,\n ownerRound: opts.round,\n resolveDone,\n startedAt: Date.now(),\n status: \"pending\",\n type: opts.type,\n waitingFor: opts.waitingFor,\n }\n this.#map.set(task.id, task)\n void this.emit(\"task-added\", { task: toTaskInfo(task) })\n this.#syncHeartbeat()\n return task\n }\n\n /** Register a pending task (chained behind `dependsOn`). Does not\n * invoke the tool — that happens once the dependency completes. */\n #registerPending(opts: {\n call: ToolCallPart\n tool: Tool\n ctxBase: ToolContext\n waitingFor: string\n round: symbol\n }): InternalTask {\n // oxlint-disable-next-line sort-keys -- semantic field order\n const task = this.#allocate({\n id: uuidv7(),\n type: opts.tool.name,\n desc: descOfCall(opts.call),\n waitingFor: opts.waitingFor,\n round: opts.round,\n })\n task.pending = { call: opts.call, ctx: opts.ctxBase, tool: opts.tool }\n return task\n }\n\n /** Start a tool call. Allocates a task record, validates params,\n * invokes `tool.call`, detects `Streamable`, and wires completion\n * back to `done()`. Returns the task in its post-launch state\n * (`done` for sync failures or already-resolved sync calls,\n * `running` for everything else). */\n #start(opts: {\n call: ToolCallPart\n tool: Tool\n ctxBase: ToolContext\n round: symbol\n }): InternalTask {\n // oxlint-disable-next-line sort-keys -- semantic field order\n const task = this.#allocate({\n id: uuidv7(),\n type: opts.tool.name,\n desc: descOfCall(opts.call),\n round: opts.round,\n })\n this.#dispatch(task, opts.tool, opts.call, opts.ctxBase)\n return task\n }\n\n #needsPreflight(tool: Tool, ctx: ToolContext): boolean {\n return ctx.need !== undefined || tool.preflight !== undefined\n }\n\n /** Run schema validation and semantic/tool permission checks before a\n * public task is allocated. Returns a formatted tool error when the\n * call should short-circuit, otherwise undefined. */\n async #preflight(\n tool: Tool,\n call: ToolCallPart,\n ctxBase: ToolContext\n ): Promise<ToolResult | undefined> {\n const ctx: ToolContext = { ...ctxBase, tasks: this }\n let params: unknown\n try {\n params = await tool.validator.validateParams(call.params)\n await ctx.need?.(\"tool\", tool.name)\n await tool.preflight?.(params, ctx)\n } catch (error) {\n return toErrorResult(error)\n }\n }\n\n /** Validate / call / wire up completion for an existing task record.\n * Used both for fresh tasks (`#start`) and pending-becoming-ready\n * (`#startReadyDependents`). The task's id and registry entry are\n * reused so identifiers stay stable across the pending → running\n * transition.\n *\n * Delegates the validate/call/error machinery to `runTool` (in\n * streaming mode) so there's one source of truth. The task's status\n * is flipped to `running` synchronously — the round loop reads it\n * right after `#start` returns to decide chain heads, and we want\n * that read to see the post-launch state, not the allocation default.\n * Async resolution either keeps it `running` (streamable returned)\n * or transitions to `done` (sync result or error). */\n #dispatch(task: InternalTask, tool: Tool, call: ToolCallPart, ctxBase: ToolContext): void {\n const ctx: ToolContext = { ...ctxBase, tasks: this }\n task.status = \"running\"\n\n const dispatchPromise = runTool(tool, call.params, ctx, { preflight: false, streaming: true })\n\n void dispatchPromise.then(\n (settled) => {\n if (isStreamable(settled)) {\n // Long-running — hold the streamable for partial snapshots /\n // abort, wire its completion back through done().\n task.streamable = settled\n settled.done.then(\n () => {\n const snap = settled.poll()\n this.done(task.id, {\n content: snap.content,\n error: snap.error,\n isError: snap.isError,\n meta: snap.meta,\n })\n },\n // `done` shouldn't reject by contract; treat as internal bug.\n (error: unknown) => this.done(task.id, toErrorResult(error))\n )\n return\n }\n // Sync path: validation error, sync return, or thrown error —\n // runTool has already formatted everything into a ToolResult.\n this.done(task.id, settled)\n },\n // The permission gate threw (or AiError leaked from runTool).\n // Either way, format and settle the task.\n (error: unknown) => this.done(task.id, toErrorResult(error))\n )\n }\n\n /** Walk pending tasks; start any whose `dependsOn` just completed.\n * If the dependency failed, propagate cancellation: dependents land\n * in `done` with an `UPSTREAM_FAILED` result. */\n #startReadyDependents(completedId: string, completedResult: ToolResult): void {\n for (const t of this.#map.values()) {\n if (t.status !== \"pending\" || t.waitingFor !== completedId) continue\n if (completedResult.isError) {\n // Skip dependent — its predecessor failed.\n this.done(\n t.id,\n toErrorResult(\n new AiError({\n code: \"UPSTREAM_FAILED\",\n data: { dependsOn: completedId },\n message: `skipped: upstream task ${completedId} failed`,\n })\n )\n )\n continue\n }\n void this.#startPending(t)\n }\n }\n\n async #startPending(task: InternalTask): Promise<void> {\n const pending = task.pending\n if (!pending) return\n if (!this.#needsPreflight(pending.tool, pending.ctx)) {\n task.pending = undefined\n task.waitingFor = undefined\n task.ownerRound = undefined\n this.#dispatch(task, pending.tool, pending.call, pending.ctx)\n return\n }\n\n const preflight = await this.#preflight(pending.tool, pending.call, pending.ctx)\n if (preflight) {\n this.done(task.id, preflight)\n return\n }\n\n // Restart as a regular task. The round that originally registered\n // this task has already returned its placeholder, so whatever happens\n // now flows through normal `task-done`.\n task.pending = undefined\n task.waitingFor = undefined\n task.ownerRound = undefined\n this.#dispatch(task, pending.tool, pending.call, pending.ctx)\n }\n\n /** Build a `ToolResultPart` for a task at round-end. Done tasks pass\n * through their captured result; still-running tasks get a snapshot\n * from the streamable (if any) plus a placeholder note for the model. */\n #buildPart(call: ToolCallPart, task: InternalTask): ToolResultPart {\n if (task.status === \"done\" && task.result) {\n return {\n content: task.result.content,\n error: task.result.error,\n id: call.id,\n isError: task.result.isError,\n meta: stampTaskMeta(task.result.meta, task),\n name: call.name,\n type: \"tool-result\",\n }\n }\n\n // Pending: never started, will run when its dependency completes.\n // Placeholder uses the standard TaskInfo shape so it's parseable\n // the same way as task_list / heartbeat entries.\n if (task.status === \"pending\") {\n return {\n content: [{ data: toTaskInfo(task), tag: \"task\", type: \"meta\" }],\n id: call.id,\n isError: false,\n meta: stampTaskMeta(undefined, task),\n name: call.name,\n type: \"tool-result\",\n }\n }\n\n // Running: capture whatever the streamable has so far (partial output)\n // and append a `<task>` MetaPart with an explicit \"still running\"\n // hint. Without the hint, models tend to treat partial output as a\n // final answer and respond prematurely; with it they see the state\n // structurally and know the final result will arrive as a later\n // system message. Tagged `<task>` for symmetry with the pending /\n // task_list / heartbeat / task-done entries — same shape everywhere\n // a task surfaces.\n const snap = task.streamable?.poll()\n const baseContent = partialContentFrom(snap)\n const trailer: MetaPart = {\n content:\n \"Task is still running. Partial output above. The final result \" +\n \"will arrive as a system message when the task completes; you \" +\n \"do not need to poll. Continue with other work or wait.\",\n data: {\n ...toTaskInfo(task),\n },\n tag: \"task\",\n type: \"meta\",\n }\n const parts: ContentPart[] = []\n if (typeof baseContent === \"string\") {\n if (baseContent !== \"\") parts.push({ text: baseContent, type: \"text\" })\n } else {\n parts.push(...baseContent)\n }\n parts.push(trailer)\n return {\n content: parts,\n id: call.id,\n isError: false,\n meta: stampTaskMeta(snap?.meta, task),\n name: call.name,\n type: \"tool-result\",\n }\n }\n}\n\n/** Stamp `meta.task` with the current task state. Preserves any\n * tool-attached `meta` fields. Used both on done results (so the\n * model can correlate completion to the original call) and on\n * partial / pending placeholders. */\nfunction stampTaskMeta(\n base: ToolResult[\"meta\"] | undefined,\n task: InternalTask\n): ToolResult[\"meta\"] & TaskMeta {\n return {\n ...base,\n task: {\n dependsOn: task.waitingFor,\n desc: task.desc,\n durationMs: task.finishedAt ? task.finishedAt - task.startedAt : undefined,\n id: task.id,\n status: task.status,\n type: task.type,\n },\n }\n}\n\n/** Build the \"running\" placeholder content from a streamable snapshot.\n * Empty string when there's nothing yet to show; copies the parts\n * array so downstream mutation of the result message can't reach back\n * into the streamable's accumulator. */\nfunction partialContentFrom(\n snap: { content: ToolResult[\"content\"] } | undefined\n): ToolResultPart[\"content\"] {\n if (!snap) return \"\"\n if (typeof snap.content === \"string\") return snap.content\n return [...snap.content]\n}\n\n/** Best-effort human-readable label for a tool call. Reads a\n * `description` field from params if the tool defined one (bash does);\n * otherwise falls back to the tool name. Kept short so log lines stay\n * scannable. */\nfunction descOfCall(call: ToolCallPart): string {\n const params = call.params as { description?: unknown } | null | undefined\n if (params && typeof params === \"object\" && typeof params.description === \"string\") {\n return params.description\n }\n return call.name\n}\n\n/** Synthesize the tool-result payload returned when the model calls a\n * tool that wasn't registered for this turn. Same shape the previous\n * `unknownToolResult` helper produced; inlined here to keep `tasks.ts`\n * self-contained. */\nfunction unknownToolResult(name: string): ToolResult {\n const err = new AiError({\n code: \"UNKNOWN_TOOL\",\n message: `no tool named \"${name}\" is registered for this turn`,\n })\n return toErrorResult(err)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => {\n const t = setTimeout(r, ms)\n t.unref()\n })\n}\n\n/** Render an array of `TaskInfo` as a `<tasks>` MetaPart for the model\n * (heartbeat pulses and `task_list`). Each task lands as one line of\n * JSON. The `result` field on done tasks is stripped — listing should\n * give an inventory, not historical output (the result was already\n * injected as a system message at task-done time, and re-shipping it\n * on every heartbeat / list call would be a token bomb). */\nexport function taskInfoPart(info: readonly TaskInfo[]): MetaPart {\n if (info.length === 0) return { data: \"no active tasks\", tag: \"tasks\", type: \"meta\" }\n const data = info.map((t) => safeStringify(t, omitResult)).join(\"\\n\")\n return { data, tag: \"tasks\", type: \"meta\" }\n}\n\n/** JSON.stringify replacer that drops the `result` field. Used by\n * `taskInfoPart` to keep listing payloads bounded. */\nfunction omitResult(key: string, value: unknown): unknown {\n return key === \"result\" ? undefined : value\n}\n\nfunction toTaskInfo(task: InternalTask): TaskInfo {\n const { id, status, type, desc } = task\n const ms = (task.finishedAt ?? Date.now()) - task.startedAt\n if (status === \"running\") {\n return { desc, elapsedMs: ms, hasNewOutput: task.streamable?.hasNew?.(), id, status, type }\n }\n if (status === \"pending\") {\n return { desc, elapsedMs: ms, id, status, type, waitingFor: task.waitingFor ?? \"\" }\n }\n // status === \"done\" — `result` is set by `done()` before status flips,\n // so the `?? toErrorResult(...)` is just a defensive fallback for\n // a malformed record (shouldn't happen in practice).\n return {\n desc,\n durationMs: ms,\n id,\n result:\n task.result ??\n toErrorResult(\n new AiError({\n code: \"INTERNAL\",\n message: `task \"${task.id}\" completed without a result`,\n })\n ),\n status,\n type,\n }\n}\n\n/** Format a finished task as the parts of a system inject. Layout:\n *\n * <task>{id, type, desc, status: \"done\", durationMs}</task>\n * {result body}\n *\n * The header is the standard `TaskInfo`-shaped JSON so consumers\n * (model, TUI) can parse it the same way they parse `task_list` and\n * heartbeat output — same shape everywhere a task surfaces.\n *\n * The body comes straight from `result.content`. For errors, that\n * already includes the `<error>{code, message, ...}</error>` MetaPart\n * + the formatted `❌ CODE: message` block (baked in by\n * `toErrorResult`), so this function doesn't need to special-case\n * errors — the structured tag and human body ride along with the\n * result content for any tool failure, anywhere.\n *\n * System messages can't carry attachments, so any image/pdf/etc. in\n * the result degrades to a `[image]` placeholder via\n * `stringifyContent` — best-effort, model still sees *something* was\n * there. */\nfunction formatTaskCompletion(task: DoneTaskInfo): (TextPart | MetaPart)[] {\n const { result, ...header } = task\n const parts: (TextPart | MetaPart)[] = [{ data: header, tag: \"task\", type: \"meta\" }]\n const bodyText = stringifyContent(result.content)\n if (bodyText !== \"\") parts.push({ text: bodyText, type: \"text\" })\n return parts\n}\n\n/** Build an `inject`-ready system message for a finished task. */\nexport function taskCompletionMessage(task: DoneTaskInfo): Message<\"system\"> {\n return {\n content: formatTaskCompletion(task),\n meta: { kind: \"task\", taskId: task.id },\n role: \"system\",\n }\n}\n"],"mappings":";;;;AAiBA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;AAqHzB,IAAa,QAAb,cAA2B,QAAqB;CAC9C,uBAAgB,IAAI,IAA0B;CAC9C,UAAU;CAEV,SAAoD,CAAC;;;;;CAMrD;CACA;CAEA,IAAI,cAAkC;EACpC,OAAO,KAAK;CACd;CACA,IAAI,YAAY,OAA2B;EACzC,KAAK,eAAe;EACpB,KAAK,eAAe;CACtB;;CAKA,UAA+B;EAC7B,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,WAAW,MAAM,CAAC,CAAC,KAAK,MAAM,WAAW,CAAC,CAAC;CAC5F;;;CAIA,WAAoC;EAClC,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAC3B,QAAQ,MAA8C,EAAE,WAAW,MAAM,CAAC,CAC1E,KAAK,MAAM,WAAW,CAAC,CAAiB;CAC7C;;CAGA,IAAI,IAAkC;EACpC,MAAM,IAAI,KAAK,KAAK,IAAI,EAAE;EAC1B,OAAO,IAAI,WAAW,CAAC,IAAI,KAAA;CAC7B;;CAGA,OAA4B;EAC1B,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU;CAC/C;CAEA,MAAM,QAAkC;EACtC,OAAO,OAAO,KAAK,WAAW,aAAa,KAAK,OAAO,IAAI,KAAK;CAClE;CAEA,IAAI,OAAO,OAAkD;EAC3D,KAAK,SAAS;CAChB;;;;;;CAOA,aAAa,IAAqB;EAChC,MAAM,IAAI,KAAK,KAAK,IAAI,EAAE;EAC1B,IAAI,GAAG,WAAW,aAAa,CAAC,EAAE,YAAY,OAAO;EACrD,OAAO,EAAE,WAAW,SAAS,KAAK;CACpC;;;;;;;;CASA,WAAW,IAA+C;EACxD,MAAM,IAAI,KAAK,KAAK,IAAI,EAAE;EAC1B,IAAI,CAAC,GACH,MAAM,IAAI,QAAQ;GAChB,MAAM;GACN,MAAM,EAAE,GAAG;GACX,SAAS,oBAAoB,GAAG;EAClC,CAAC;EAEH,IAAI,EAAE,WAAW,QACf,MAAM,IAAI,QAAQ;GAChB,MAAM;GACN,MAAM,EAAE,GAAG;GACX,SAAS,SAAS,GAAG;EACvB,CAAC;EAEH,IAAI,CAAC,EAAE,YACL,MAAM,IAAI,QAAQ;GAChB,MAAM;GACN,MAAM,EAAE,GAAG;GACX,SACE,SAAS,GAAG;EAEhB,CAAC;EAEH,OAAO,EAAE,WAAW,KAAK;CAC3B;;;CAIA,OAAO,IAAqB;EAC1B,MAAM,OAAO,KAAK,KAAK,IAAI,EAAE;EAC7B,IAAI,CAAC,MAAM,OAAO;EAClB,KAAK,KAAK,OAAO,EAAE;EACnB,KAAU,KAAK,gBAAgB,EAAE,MAAM,WAAW,IAAI,EAAE,CAAC;EACzD,OAAO;CACT;;;;;CAMA,KAAK,IAAY,QAA0B;EACzC,MAAM,OAAO,KAAK,KAAK,IAAI,EAAE;EAC7B,IAAI,CAAC,QAAQ,KAAK,WAAW,QAAQ;EACrC,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,aAAa,KAAK,IAAI;EAC3B,KAAK,YAAY;EACjB,IAAI,CAAC,KAAK,YACR,KAAU,KAAK,aAAa,EAAE,MAAM,WAAW,IAAI,EAAkB,CAAC;EAExE,KAAK,sBAAsB,IAAI,MAAM;EACrC,KAAK,eAAe;CACtB;;;;CAKA,MAAM,IAAY,SAAS,sBAA4B;EACrD,MAAM,OAAO,KAAK,KAAK,IAAI,EAAE;EAC7B,IAAI,CAAC,QAAQ,KAAK,WAAW,QAAQ;EACrC,IAAI,KAAK,YAAY,KAAK,WAAW,MAAM;EAC3C,IAAI,KAAK,WAAW,WAClB,KAAK,KAAK,IAAI,cAAc,IAAI,QAAQ;GAAE,MAAM;GAAgB,SAAS;EAAO,CAAC,CAAC,CAAC;CAMvF;;;;CAKA,MAAM,UAAyB;EAC7B,MAAM,SAAS,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,WAAW,MAAM;EACxE,KAAK,MAAM,KAAK,QAAQ;GACtB,IAAI,EAAE,YAAY,EAAE,WAAW,MAAM;GACrC,IAAI,EAAE,WAAW,WACf,KAAK,KACH,EAAE,IACF,cAAc,IAAI,QAAQ;IAAE,MAAM;IAAgB,SAAS;GAAiB,CAAC,CAAC,CAChF;EAEJ;EACA,MAAM,QAAQ,IAAI,OAAO,KAAK,MAAM,EAAE,YAAY,YAAY,KAAA,CAAS,CAAC,CAAC;EACzE,KAAK,eAAe;CACtB;;;;;CAMA,iBAAuB;EAErB,MAAM,OADY,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,WAAW,MAC9C,KAAK,KAAK,iBAAiB,KAAA;EAChD,IAAI,QAAQ,CAAC,KAAK,iBAAiB;GACjC,KAAK,kBAAkB,kBAAkB;IACvC,KAAU,KAAK,aAAa,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,QAAQ,MAAM,EAAE,WAAW,MAAM,EAAE,CAAC;GACzF,GAAG,KAAK,YAAY;GACpB,KAAK,gBAAgB,MAAM;EAC7B,OAAO,IAAI,CAAC,QAAQ,KAAK,iBAAiB;GACxC,cAAc,KAAK,eAAe;GAClC,KAAK,kBAAkB,KAAA;EACzB;CACF;;;;;;;;;;;;;CAgBA,MAAM,IACJ,OACA,KACA,OAAyF,CAAC,GAC/D;EAC3B,MAAM,QAAQ,OAAO,OAAO;EAC5B,MAAM,QAAwB,CAAC;EAC/B,IAAI;EAEJ,MAAM,QAAQ,MAAM,KAAK,MAAM;EAE/B,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,OAAO,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK,IAAI;GACnD,IAAI,CAAC,MAAM;IACT,MAAM,KAAK,KAAK,iBAAiB,MAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,CAAC;IAC3E;GACF;GAEA,MAAM,WAAW,KAAK,YAAY;GAElC,IAAI,aAAa,CAAC,UAAU;IAE1B,MAAM,KACJ,KAAK,iBAAiB;KAAE;KAAM,SAAS;KAAK;KAAO;KAAM,YAAY;IAAU,CAAC,CAClF;IACA,YAAY,MAAM,MAAM,SAAS,EAAE,CAAC;IACpC;GACF;GAEA,IAAI,KAAK,gBAAgB,MAAM,GAAG,GAAG;IAKnC,MAAM,YAAY,MAAM,KAAK,WAAW,MAAM,MAAM,GAAG;IACvD,IAAI,WAAW;KACb,MAAM,KAAK,KAAK,iBAAiB,MAAM,WAAW,KAAK,CAAC;KACxD;IACF;GACF;GAEA,MAAM,OAAO,KAAK,OAAO;IAAE;IAAM,SAAS;IAAK;IAAO;GAAK,CAAC;GAC5D,MAAM,KAAK,IAAI;GAGf,IAAI,KAAK,WAAW,aAAa,CAAC,UAAU,YAAY,KAAK;EAC/D;EAEA,MAAM,QAA0B,CAAC;EAEjC,MAAM,cAAc,QAAgC;GAClD,IAAI,MAAM,MAAM,OAAO,MAAM;GAC7B,MAAM,OAAO,MAAM;GACnB,IAAI,KAAK,WAAW,QAAQ,KAAK,aAAa,KAAA;GAC9C,MAAM,OAAO,MAAM;GACnB,MAAM,OAAO,KAAK,WAAW,MAAM,IAAI;GACvC,MAAM,OAAO;GACb,OAAO;EACT;EAEA,IAAI,WAAW,KAAK;EAGpB,MAAM,UAAU,QAAQ,IACtB,MAAM,IAAI,OAAO,GAAG,OAAO;GACzB,MAAM,EAAE;GACR,WAAW,MAAM,KAAK,WAAW,EAAE,GAAG,EAAE;EAC1C,CAAC,CACH;EACA,MAAM,QAAQ,MAAM,KAAK,OAAO;EAChC,MAAM,UAAU,IAAI,SAChB,IAAI,SAAe,YAAY;GAC7B,IAAI,IAAI,OAAQ,SAAS,QAAQ;QAC5B,IAAI,OAAQ,iBAAiB,eAAe,QAAQ,GAAG,EAAE,MAAM,KAAK,CAAC;EAC5E,CAAC,IACD,IAAI,cAAoB,KAAA,CAAS;EACrC,MAAM,QAAQ,KAAK;GAAC;GAAS;GAAO;EAAO,CAAC;EAC5C,WAAW,KAAA;EAKX,OAAO,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,CAAC;CAC1C;;;CAMA,iBAAiB,MAAoB,QAAoB,OAA6B;EAEpF,MAAM,OAAO,KAAK,UAAU;GAAE,IAAI,OAAO;GAAG,MAAM,KAAK;GAAM,MAAM,KAAK;GAAM;EAAM,CAAC;EACrF,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,aAAa,KAAK;EACvB,KAAK,YAAY;EACjB,OAAO;CACT;;CAGA,UAAU,MAMO;EACf,IAAI;EACJ,MAAM,cAAc,IAAI,SAAe,MAAM;GAC3C,cAAc;EAChB,CAAC;EACD,MAAM,OAAqB;GACzB,MAAM,KAAK;GACX;GACA,IAAI,KAAK;GACT,YAAY,KAAK;GACjB;GACA,WAAW,KAAK,IAAI;GACpB,QAAQ;GACR,MAAM,KAAK;GACX,YAAY,KAAK;EACnB;EACA,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI;EAC3B,KAAU,KAAK,cAAc,EAAE,MAAM,WAAW,IAAI,EAAE,CAAC;EACvD,KAAK,eAAe;EACpB,OAAO;CACT;;;CAIA,iBAAiB,MAMA;EAEf,MAAM,OAAO,KAAK,UAAU;GAC1B,IAAI,OAAO;GACX,MAAM,KAAK,KAAK;GAChB,MAAM,WAAW,KAAK,IAAI;GAC1B,YAAY,KAAK;GACjB,OAAO,KAAK;EACd,CAAC;EACD,KAAK,UAAU;GAAE,MAAM,KAAK;GAAM,KAAK,KAAK;GAAS,MAAM,KAAK;EAAK;EACrE,OAAO;CACT;;;;;;CAOA,OAAO,MAKU;EAEf,MAAM,OAAO,KAAK,UAAU;GAC1B,IAAI,OAAO;GACX,MAAM,KAAK,KAAK;GAChB,MAAM,WAAW,KAAK,IAAI;GAC1B,OAAO,KAAK;EACd,CAAC;EACD,KAAK,UAAU,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO;EACvD,OAAO;CACT;CAEA,gBAAgB,MAAY,KAA2B;EACrD,OAAO,IAAI,SAAS,KAAA,KAAa,KAAK,cAAc,KAAA;CACtD;;;;CAKA,MAAM,WACJ,MACA,MACA,SACiC;EACjC,MAAM,MAAmB;GAAE,GAAG;GAAS,OAAO;EAAK;EACnD,IAAI;EACJ,IAAI;GACF,SAAS,MAAM,KAAK,UAAU,eAAe,KAAK,MAAM;GACxD,MAAM,IAAI,OAAO,QAAQ,KAAK,IAAI;GAClC,MAAM,KAAK,YAAY,QAAQ,GAAG;EACpC,SAAS,OAAO;GACd,OAAO,cAAc,KAAK;EAC5B;CACF;;;;;;;;;;;;;;CAeA,UAAU,MAAoB,MAAY,MAAoB,SAA4B;EACxF,MAAM,MAAmB;GAAE,GAAG;GAAS,OAAO;EAAK;EACnD,KAAK,SAAS;EAId,QAFgC,MAAM,KAAK,QAAQ,KAAK;GAAE,WAAW;GAAO,WAAW;EAAK,CAEzE,CAAC,CAAC,MAClB,YAAY;GACX,IAAI,aAAa,OAAO,GAAG;IAGzB,KAAK,aAAa;IAClB,QAAQ,KAAK,WACL;KACJ,MAAM,OAAO,QAAQ,KAAK;KAC1B,KAAK,KAAK,KAAK,IAAI;MACjB,SAAS,KAAK;MACd,OAAO,KAAK;MACZ,SAAS,KAAK;MACd,MAAM,KAAK;KACb,CAAC;IACH,IAEC,UAAmB,KAAK,KAAK,KAAK,IAAI,cAAc,KAAK,CAAC,CAC7D;IACA;GACF;GAGA,KAAK,KAAK,KAAK,IAAI,OAAO;EAC5B,IAGC,UAAmB,KAAK,KAAK,KAAK,IAAI,cAAc,KAAK,CAAC,CAC7D;CACF;;;;CAKA,sBAAsB,aAAqB,iBAAmC;EAC5E,KAAK,MAAM,KAAK,KAAK,KAAK,OAAO,GAAG;GAClC,IAAI,EAAE,WAAW,aAAa,EAAE,eAAe,aAAa;GAC5D,IAAI,gBAAgB,SAAS;IAE3B,KAAK,KACH,EAAE,IACF,cACE,IAAI,QAAQ;KACV,MAAM;KACN,MAAM,EAAE,WAAW,YAAY;KAC/B,SAAS,0BAA0B,YAAY;IACjD,CAAC,CACH,CACF;IACA;GACF;GACA,KAAU,cAAc,CAAC;EAC3B;CACF;CAEA,MAAM,cAAc,MAAmC;EACrD,MAAM,UAAU,KAAK;EACrB,IAAI,CAAC,SAAS;EACd,IAAI,CAAC,KAAK,gBAAgB,QAAQ,MAAM,QAAQ,GAAG,GAAG;GACpD,KAAK,UAAU,KAAA;GACf,KAAK,aAAa,KAAA;GAClB,KAAK,aAAa,KAAA;GAClB,KAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,GAAG;GAC5D;EACF;EAEA,MAAM,YAAY,MAAM,KAAK,WAAW,QAAQ,MAAM,QAAQ,MAAM,QAAQ,GAAG;EAC/E,IAAI,WAAW;GACb,KAAK,KAAK,KAAK,IAAI,SAAS;GAC5B;EACF;EAKA,KAAK,UAAU,KAAA;EACf,KAAK,aAAa,KAAA;EAClB,KAAK,aAAa,KAAA;EAClB,KAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,GAAG;CAC9D;;;;CAKA,WAAW,MAAoB,MAAoC;EACjE,IAAI,KAAK,WAAW,UAAU,KAAK,QACjC,OAAO;GACL,SAAS,KAAK,OAAO;GACrB,OAAO,KAAK,OAAO;GACnB,IAAI,KAAK;GACT,SAAS,KAAK,OAAO;GACrB,MAAM,cAAc,KAAK,OAAO,MAAM,IAAI;GAC1C,MAAM,KAAK;GACX,MAAM;EACR;EAMF,IAAI,KAAK,WAAW,WAClB,OAAO;GACL,SAAS,CAAC;IAAE,MAAM,WAAW,IAAI;IAAG,KAAK;IAAQ,MAAM;GAAO,CAAC;GAC/D,IAAI,KAAK;GACT,SAAS;GACT,MAAM,cAAc,KAAA,GAAW,IAAI;GACnC,MAAM,KAAK;GACX,MAAM;EACR;EAWF,MAAM,OAAO,KAAK,YAAY,KAAK;EACnC,MAAM,cAAc,mBAAmB,IAAI;EAC3C,MAAM,UAAoB;GACxB,SACE;GAGF,MAAM,EACJ,GAAG,WAAW,IAAI,EACpB;GACA,KAAK;GACL,MAAM;EACR;EACA,MAAM,QAAuB,CAAC;EAC9B,IAAI,OAAO,gBAAgB,UACrB;OAAA,gBAAgB,IAAI,MAAM,KAAK;IAAE,MAAM;IAAa,MAAM;GAAO,CAAC;EAAA,OAEtE,MAAM,KAAK,GAAG,WAAW;EAE3B,MAAM,KAAK,OAAO;EAClB,OAAO;GACL,SAAS;GACT,IAAI,KAAK;GACT,SAAS;GACT,MAAM,cAAc,MAAM,MAAM,IAAI;GACpC,MAAM,KAAK;GACX,MAAM;EACR;CACF;AACF;;;;;AAMA,SAAS,cACP,MACA,MAC+B;CAC/B,OAAO;EACL,GAAG;EACH,MAAM;GACJ,WAAW,KAAK;GAChB,MAAM,KAAK;GACX,YAAY,KAAK,aAAa,KAAK,aAAa,KAAK,YAAY,KAAA;GACjE,IAAI,KAAK;GACT,QAAQ,KAAK;GACb,MAAM,KAAK;EACb;CACF;AACF;;;;;AAMA,SAAS,mBACP,MAC2B;CAC3B,IAAI,CAAC,MAAM,OAAO;CAClB,IAAI,OAAO,KAAK,YAAY,UAAU,OAAO,KAAK;CAClD,OAAO,CAAC,GAAG,KAAK,OAAO;AACzB;;;;;AAMA,SAAS,WAAW,MAA4B;CAC9C,MAAM,SAAS,KAAK;CACpB,IAAI,UAAU,OAAO,WAAW,YAAY,OAAO,OAAO,gBAAgB,UACxE,OAAO,OAAO;CAEhB,OAAO,KAAK;AACd;;;;;AAMA,SAAS,kBAAkB,MAA0B;CACnD,MAAM,MAAM,IAAI,QAAQ;EACtB,MAAM;EACN,SAAS,kBAAkB,KAAK;CAClC,CAAC;CACD,OAAO,cAAc,GAAG;AAC1B;AAEA,SAAS,MAAM,IAA2B;CACxC,OAAO,IAAI,SAAS,MAAM;EAExB,WADqB,GAAG,EACxB,CAAC,CAAC,MAAM;CACV,CAAC;AACH;;;;;;;AAQA,SAAgB,aAAa,MAAqC;CAChE,IAAI,KAAK,WAAW,GAAG,OAAO;EAAE,MAAM;EAAmB,KAAK;EAAS,MAAM;CAAO;CAEpF,OAAO;EAAE,MADI,KAAK,KAAK,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,IACpD;EAAG,KAAK;EAAS,MAAM;CAAO;AAC5C;;;AAIA,SAAS,WAAW,KAAa,OAAyB;CACxD,OAAO,QAAQ,WAAW,KAAA,IAAY;AACxC;AAEA,SAAS,WAAW,MAA8B;CAChD,MAAM,EAAE,IAAI,QAAQ,MAAM,SAAS;CACnC,MAAM,MAAM,KAAK,cAAc,KAAK,IAAI,KAAK,KAAK;CAClD,IAAI,WAAW,WACb,OAAO;EAAE;EAAM,WAAW;EAAI,cAAc,KAAK,YAAY,SAAS;EAAG;EAAI;EAAQ;CAAK;CAE5F,IAAI,WAAW,WACb,OAAO;EAAE;EAAM,WAAW;EAAI;EAAI;EAAQ;EAAM,YAAY,KAAK,cAAc;CAAG;CAKpF,OAAO;EACL;EACA,YAAY;EACZ;EACA,QACE,KAAK,UACL,cACE,IAAI,QAAQ;GACV,MAAM;GACN,SAAS,SAAS,KAAK,GAAG;EAC5B,CAAC,CACH;EACF;EACA;CACF;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAS,qBAAqB,MAA6C;CACzE,MAAM,EAAE,QAAQ,GAAG,WAAW;CAC9B,MAAM,QAAiC,CAAC;EAAE,MAAM;EAAQ,KAAK;EAAQ,MAAM;CAAO,CAAC;CACnF,MAAM,WAAW,iBAAiB,OAAO,OAAO;CAChD,IAAI,aAAa,IAAI,MAAM,KAAK;EAAE,MAAM;EAAU,MAAM;CAAO,CAAC;CAChE,OAAO;AACT;;AAGA,SAAgB,sBAAsB,MAAuC;CAC3E,OAAO;EACL,SAAS,qBAAqB,IAAI;EAClC,MAAM;GAAE,MAAM;GAAQ,QAAQ,KAAK;EAAG;EACtC,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"tasks-D76WXWr2.mjs","names":[],"sources":["../src/tasks.ts"],"sourcesContent":["import type {\n ContentPart,\n Message,\n MetaPart,\n TextPart,\n Tool,\n ToolCallPart,\n ToolContext,\n ToolResult,\n ToolResultPart,\n Streamable as TStreamable,\n} from \"@zaly/ai\"\n\nimport { AiError, isStreamable, runTool, stringifyContent, toErrorResult } from \"@zaly/ai\"\nimport { Emitter, safeStringify } from \"@zaly/shared\"\nimport { uuidv7 } from \"./utils/uuid.ts\"\n\nconst DEFAULT_GRACE_MS = 10_000\n\n/** Status of a task. `pending` = queued behind a dependency, not yet\n * started. `running` = work in progress (a Streamable is being polled).\n * `done` = result captured, no longer mutating. */\nexport type TaskStatus = \"pending\" | \"running\" | \"done\"\n\n/** Public projection of a registered task. Status-discriminated so the\n * fields visible at any moment are exactly the ones that make sense\n * for that lifecycle stage:\n *\n * - `running`: `elapsedMs` since start; `hasNewOutput` when the\n * streamable signals that `task_poll` would yield bytes.\n * - `pending`: queued behind another task (`waitingFor`); `elapsedMs`\n * counts time-since-registration.\n * - `done`: settled. Carries `durationMs` and the captured `result`.\n *\n * This is the only public task type — the registry exposes it via\n * `running()` / `finished()` / `get()`, events carry it (`task-done`\n * is narrowed to `status: \"done\"` so listeners get `result` typed\n * without checks), and `task_list` JSON-stringifies it directly. */\nexport type TaskInfo = {\n id: string\n type: string\n desc: string\n} & (\n | { status: \"running\"; elapsedMs: number; hasNewOutput?: boolean }\n | { status: \"pending\"; waitingFor: string; elapsedMs: number }\n | { status: \"done\"; durationMs: number; result: ToolResult }\n)\n\n/** A `TaskInfo` known to be in the `done` state. `task-done` event\n * payloads use this so listeners get `result` and `durationMs` typed\n * without manual narrowing. */\nexport type DoneTaskInfo = Extract<TaskInfo, { status: \"done\" }>\n\n/** Events emitted by a `Tasks` instance. `task-done` only fires for\n * completions that happen *outside* an in-flight `run()` round —\n * round-internal completions are folded into the `run()` return value\n * instead. `heartbeat` fires periodically (when `heartbeatMs` is set\n * and at least one task is active), giving the agent a hook to keep\n * the model engaged on long-running work. */\nexport type TasksEvents = {\n \"task-added\": { task: TaskInfo }\n \"task-removed\": { task: TaskInfo }\n \"task-done\": { task: DoneTaskInfo }\n heartbeat: { running: readonly TaskInfo[] }\n}\n\n/** Augment ToolMeta so tools and consumers can read freshness/state info\n * off `ToolResultPart.meta.task`. The registry stamps this on every\n * result it produces so the model can correlate placeholders to their\n * eventual completion. */\nexport interface TaskMeta {\n task?: {\n id: string\n status: TaskStatus\n type: string\n desc: string\n dependsOn?: string\n durationMs?: number\n }\n}\n\n/** Internal storage record. Not exposed — `toTaskInfo` projects it to\n * `TaskInfo` for any caller that crosses the boundary (events,\n * registry methods, the `task_*` tools). Carries everything the\n * registry needs to drive lifecycle transitions, plus the raw\n * timestamps `TaskInfo` derives elapsed/duration from. */\ninterface InternalTask {\n id: string\n type: string\n desc: string\n status: TaskStatus\n /** Wallclock at registration. */\n startedAt: number\n /** Wallclock at completion; set once status is `done`. */\n finishedAt?: number\n /** Captured result when status is `done`. */\n result?: ToolResult\n /** When set, this task is queued behind another and won't start until\n * the named task transitions to `done`. */\n waitingFor?: string\n /** Streamable returned by the tool, if any — held so we can `abort()`\n * on cancellation and call `poll()` for partial snapshots. */\n streamable?: TStreamable\n /** Resolves when the task transitions to `done`. Used by the round\n * race in `run()`. */\n donePromise: Promise<void>\n resolveDone: () => void\n /** When set, the task belongs to an in-flight `run()` round — its\n * completion does *not* fire `task-done` (the round folds it into the\n * returned parts instead). Cleared once the round ends. */\n ownerRound?: symbol\n /** Stashed call so a pending task can be restarted once its\n * dependency completes. */\n pending?: { tool: Tool; call: ToolCallPart; ctx: ToolContext }\n}\n\n/**\n * Tool registry + execution machinery + long-running task bookkeeping.\n * One Tasks instance per Agent. Owns the tool list (the agent delegates\n * `agent.tools` to it) and runs every assistant tool batch through\n * `run()`, which:\n *\n * - validates each call's params,\n * - dispatches to the named tool (sync results land immediately),\n * - races `Streamable` returns against a grace window,\n * - chains `parallel: false` calls behind their predecessors,\n * - returns `ToolResultPart[]` 1:1 with the assistant's calls,\n * surfacing partial results / placeholders for anything still running\n * when the grace expires.\n *\n * Completions during a round are folded into the returned parts and do\n * NOT fire `task-done`. Completions afterward fire normally — the agent\n * listens and injects a system message into the next step.\n */\nexport class Tasks extends Emitter<TasksEvents> {\n readonly #map = new Map<string, InternalTask>()\n graceMs = DEFAULT_GRACE_MS\n\n #tools: (() => Promise<readonly Tool[]>) | Tool[] = []\n\n /** Heartbeat interval in ms. When set, fires `heartbeat` events while\n * at least one task is pending or running. Self-managing: starts on\n * the first active task, stops when the last one finishes. Set to\n * `undefined` to disable. */\n #heartbeatMs?: number\n #heartbeatTimer?: ReturnType<typeof setInterval>\n\n get heartbeatMs(): number | undefined {\n return this.#heartbeatMs\n }\n set heartbeatMs(value: number | undefined) {\n this.#heartbeatMs = value\n this.#syncHeartbeat()\n }\n\n // ── Public registry surface ─────────────────────────────────────────\n\n /** Snapshot of every active task (pending or running). */\n running(): readonly TaskInfo[] {\n return [...this.#map.values()].filter((t) => t.status !== \"done\").map((t) => toTaskInfo(t))\n }\n\n /** Snapshot of every task that has completed. Drops are by `remove()`\n * or implicit retention; this list grows unless the caller prunes. */\n finished(): readonly DoneTaskInfo[] {\n return [...this.#map.values()]\n .filter((t): t is InternalTask & { status: \"done\" } => t.status === \"done\")\n .map((t) => toTaskInfo(t) as DoneTaskInfo)\n }\n\n /** Look up a task by id. Useful for `task_stop` / `task_poll`. */\n get(id: string): TaskInfo | undefined {\n const t = this.#map.get(id)\n return t ? toTaskInfo(t) : undefined\n }\n\n /** Snapshot of every task in the registry — running, pending, and done. */\n info(): readonly TaskInfo[] {\n return [...this.#map.values()].map(toTaskInfo)\n }\n\n async tools(): Promise<readonly Tool[]> {\n return typeof this.#tools === \"function\" ? this.#tools() : this.#tools\n }\n\n set $tools(tools: (() => Promise<readonly Tool[]>) | Tool[]) {\n this.#tools = tools\n }\n\n /** Non-consuming check: does the underlying streamable have output\n * the model hasn't seen since the last `poll()`? Returns false for\n * tasks without a streamable, completed tasks, or streamables that\n * don't implement the optional `hasNew` hook (no signal to give).\n * Used by heartbeats to flag tasks worth polling. */\n hasNewOutput(id: string): boolean {\n const t = this.#map.get(id)\n if (t?.status !== \"running\" || !t.streamable) return false\n return t.streamable.hasNew?.() ?? false\n }\n\n /** Poll a task's streamable for incremental output without changing\n * its lifecycle state. Advances the streamable's cursor — the next\n * call returns only what arrived since *this* one. Returns the same\n * `ToolResult` shape the original tool produces (parts + meta).\n * Errors when the task is unknown, already done, or has no streamable\n * (the latter is the case for plain-Promise tools — there's no\n * partial state to read). */\n pollOutput(id: string): ToolResult & { running: boolean } {\n const t = this.#map.get(id)\n if (!t) {\n throw new AiError({\n code: \"NOT_FOUND\",\n data: { id },\n message: `no task with id \"${id}\"`,\n })\n }\n if (t.status === \"done\") {\n throw new AiError({\n code: \"TASK_DONE\",\n data: { id },\n message: `task \"${id}\" has already completed; its result was injected as a system message`,\n })\n }\n if (!t.streamable) {\n throw new AiError({\n code: \"NOT_STREAMABLE\",\n data: { id },\n message:\n `task \"${id}\" has no incremental output — it's a plain-Promise tool ` +\n `whose result is delivered all-at-once when complete`,\n })\n }\n return t.streamable.poll()\n }\n\n /** Drop a task from the registry — does not abort. Caller is\n * responsible for `abort()`-ing if the task is still running. */\n remove(id: string): boolean {\n const task = this.#map.get(id)\n if (!task) return false\n this.#map.delete(id)\n void this.emit(\"task-removed\", { task: toTaskInfo(task) })\n return true\n }\n\n /** Mark a task done with a final result. Fires `task-done` UNLESS the\n * task is currently owned by an in-flight `run()` round — in that\n * case the round folds the completion into its returned parts and\n * the event is suppressed. Starts any pending dependents. */\n done(id: string, result: ToolResult): void {\n const task = this.#map.get(id)\n if (!task || task.status === \"done\") return\n task.status = \"done\"\n task.result = result\n task.finishedAt = Date.now()\n task.resolveDone()\n if (!task.ownerRound) {\n void this.emit(\"task-done\", { task: toTaskInfo(task) as DoneTaskInfo })\n }\n this.#startReadyDependents(id, result)\n this.#syncHeartbeat()\n }\n\n /** Abort a running task. Calls the streamable's `abort()` if present;\n * pending tasks transition straight to `done` with a cancelled\n * result. Idempotent. */\n abort(id: string, reason = \"aborted by request\"): void {\n const task = this.#map.get(id)\n if (!task || task.status === \"done\") return\n if (task.streamable) task.streamable.abort()\n if (task.status === \"pending\") {\n this.done(id, toErrorResult(new AiError({ code: \"TASK_ABORTED\", message: reason })))\n }\n // Running tasks: the streamable will eventually settle and call done()\n // via its watcher. We could force a synchronous \"done\" here, but\n // letting the streamable's natural completion path run keeps the\n // final snapshot accurate (output that arrived before abort lands).\n }\n\n /** Abort every active task. Used on agent dispose. Awaits each\n * task's `donePromise` so the registry is fully drained before\n * resolving — so callers can rely on no pending I/O after `dispose`. */\n async killAll(): Promise<void> {\n const active = [...this.#map.values()].filter((t) => t.status !== \"done\")\n for (const t of active) {\n if (t.streamable) t.streamable.abort()\n if (t.status === \"pending\") {\n this.done(\n t.id,\n toErrorResult(new AiError({ code: \"TASK_ABORTED\", message: \"agent disposed\" }))\n )\n }\n }\n await Promise.all(active.map((t) => t.donePromise.catch(() => undefined)))\n this.#syncHeartbeat()\n }\n\n /** Start or stop the heartbeat timer based on whether any task is\n * active and whether `heartbeatMs` is configured. Idempotent — called\n * after every state transition (`add` / `done` / `killAll`). The\n * timer is `unref`'d so it never holds the process open. */\n #syncHeartbeat(): void {\n const hasActive = [...this.#map.values()].some((t) => t.status !== \"done\")\n const want = hasActive && this.#heartbeatMs !== undefined\n if (want && !this.#heartbeatTimer) {\n this.#heartbeatTimer = setInterval(() => {\n void this.emit(\"heartbeat\", { running: this.info().filter((t) => t.status !== \"done\") })\n }, this.#heartbeatMs)\n this.#heartbeatTimer.unref()\n } else if (!want && this.#heartbeatTimer) {\n clearInterval(this.#heartbeatTimer)\n this.#heartbeatTimer = undefined\n }\n }\n\n // ── Batch execution ─────────────────────────────────────────────────\n\n /**\n * Execute a batch of assistant tool calls. Returns ToolResultPart[]\n * mapped 1:1 with `calls`. Sync completions land in the result array\n * immediately; long-running ones return a placeholder and the eventual\n * completion fires `task-done` post-round (the agent injects a system\n * message in response).\n *\n * The `messages` snapshot is what tools see on `ctx.messages` — pass\n * the conversation up to (and including) the assistant message that\n * produced these calls, so freshness checks can scan back through\n * prior tool results.\n */\n async run(\n calls: readonly ToolCallPart[],\n ctx: ToolContext,\n opts: { onResult?: (call: ToolCallPart, result: ToolResultPart, idx: number) => void } = {}\n ): Promise<ToolResultPart[]> {\n const round = Symbol(\"round\")\n const tasks: InternalTask[] = []\n let chainHead: string | undefined\n\n const tools = await this.tools()\n\n for (const call of calls) {\n const tool = tools.find((t) => t.name === call.name)\n if (!tool) {\n tasks.push(this.#startSyncResult(call, unknownToolResult(call.name), round))\n continue\n }\n\n const parallel = tool.parallel ?? false\n\n if (chainHead && !parallel) {\n // Queue behind the chain head — won't start until that finishes.\n tasks.push(\n this.#registerPending({ call, ctxBase: ctx, round, tool, waitingFor: chainHead })\n )\n chainHead = tasks[tasks.length - 1].id\n continue\n }\n\n if (this.#needsPreflight(tool, ctx)) {\n // Preflight is intentionally sequential: permission prompts should\n // appear one at a time and should not register/background a task while\n // waiting for the user's answer.\n // oxlint-disable-next-line no-await-in-loop\n const preflight = await this.#preflight(tool, call, ctx)\n if (preflight) {\n tasks.push(this.#startSyncResult(call, preflight, round))\n continue\n }\n }\n\n const task = this.#start({ call, ctxBase: ctx, round, tool })\n tasks.push(task)\n // If this call promoted to a long-running task and `parallel: false`,\n // subsequent serial calls chain behind it.\n if (task.status === \"running\" && !parallel) chainHead = task.id\n }\n\n const parts: ToolResultPart[] = []\n\n const resultPart = (idx: number): ToolResultPart => {\n if (parts[idx]) return parts[idx]\n const task = tasks[idx]\n if (task.status !== \"done\") task.ownerRound = undefined\n const call = calls[idx]\n const part = this.#buildPart(call, task)\n parts[idx] = part\n return part\n }\n\n let onResult = opts.onResult\n\n // Race: every task done, OR grace expires, OR ctx.signal aborts.\n const allDone = Promise.all(\n tasks.map(async (t, ti) => {\n await t.donePromise\n onResult?.(calls[ti], resultPart(ti), ti)\n })\n )\n const grace = sleep(this.graceMs)\n const aborted = ctx.signal\n ? new Promise<void>((resolve) => {\n if (ctx.signal!.aborted) resolve()\n else ctx.signal!.addEventListener(\"abort\", () => resolve(), { once: true })\n })\n : new Promise<void>(() => undefined) // never resolves\n await Promise.race([allDone, grace, aborted])\n onResult = undefined\n\n // Release ownership on still-active tasks BEFORE building the result\n // array, so the post-round listener sees them as free-floating if\n // they happen to settle in the same tick.\n return tasks.map((_, i) => resultPart(i))\n }\n\n // ── Internals ──────────────────────────────────────────────────────\n\n /** Build a \"done\" task synchronously from a precomputed result.\n * Used for unknown-tool errors and validation failures. */\n #startSyncResult(call: ToolCallPart, result: ToolResult, round: symbol): InternalTask {\n // oxlint-disable-next-line sort-keys -- semantic field order\n const task = this.#allocate({ id: uuidv7(), type: call.name, desc: call.name, round })\n task.status = \"done\"\n task.result = result\n task.finishedAt = task.startedAt\n task.resolveDone()\n return task\n }\n\n /** Allocate an internal task record, register it, and emit `task-added`. */\n #allocate(opts: {\n id: string\n type: string\n desc: string\n waitingFor?: string\n round: symbol\n }): InternalTask {\n let resolveDone!: () => void\n const donePromise = new Promise<void>((r) => {\n resolveDone = r\n })\n const task: InternalTask = {\n desc: opts.desc,\n donePromise,\n id: opts.id,\n ownerRound: opts.round,\n resolveDone,\n startedAt: Date.now(),\n status: \"pending\",\n type: opts.type,\n waitingFor: opts.waitingFor,\n }\n this.#map.set(task.id, task)\n void this.emit(\"task-added\", { task: toTaskInfo(task) })\n this.#syncHeartbeat()\n return task\n }\n\n /** Register a pending task (chained behind `dependsOn`). Does not\n * invoke the tool — that happens once the dependency completes. */\n #registerPending(opts: {\n call: ToolCallPart\n tool: Tool\n ctxBase: ToolContext\n waitingFor: string\n round: symbol\n }): InternalTask {\n // oxlint-disable-next-line sort-keys -- semantic field order\n const task = this.#allocate({\n id: uuidv7(),\n type: opts.tool.name,\n desc: descOfCall(opts.call),\n waitingFor: opts.waitingFor,\n round: opts.round,\n })\n task.pending = { call: opts.call, ctx: opts.ctxBase, tool: opts.tool }\n return task\n }\n\n /** Start a tool call. Allocates a task record, validates params,\n * invokes `tool.call`, detects `Streamable`, and wires completion\n * back to `done()`. Returns the task in its post-launch state\n * (`done` for sync failures or already-resolved sync calls,\n * `running` for everything else). */\n #start(opts: {\n call: ToolCallPart\n tool: Tool\n ctxBase: ToolContext\n round: symbol\n }): InternalTask {\n // oxlint-disable-next-line sort-keys -- semantic field order\n const task = this.#allocate({\n id: uuidv7(),\n type: opts.tool.name,\n desc: descOfCall(opts.call),\n round: opts.round,\n })\n this.#dispatch(task, opts.tool, opts.call, opts.ctxBase)\n return task\n }\n\n #needsPreflight(tool: Tool, ctx: ToolContext): boolean {\n return ctx.need !== undefined || tool.preflight !== undefined\n }\n\n /** Run schema validation and semantic/tool permission checks before a\n * public task is allocated. Returns a formatted tool error when the\n * call should short-circuit, otherwise undefined. */\n async #preflight(\n tool: Tool,\n call: ToolCallPart,\n ctxBase: ToolContext\n ): Promise<ToolResult | undefined> {\n const ctx: ToolContext = { ...ctxBase, tasks: this }\n let params: unknown\n try {\n params = await tool.validator.validateParams(call.params)\n await ctx.need?.(\"tool\", tool.name)\n await tool.preflight?.(params, ctx)\n } catch (error) {\n return toErrorResult(error)\n }\n }\n\n /** Validate / call / wire up completion for an existing task record.\n * Used both for fresh tasks (`#start`) and pending-becoming-ready\n * (`#startReadyDependents`). The task's id and registry entry are\n * reused so identifiers stay stable across the pending → running\n * transition.\n *\n * Delegates the validate/call/error machinery to `runTool` (in\n * streaming mode) so there's one source of truth. The task's status\n * is flipped to `running` synchronously — the round loop reads it\n * right after `#start` returns to decide chain heads, and we want\n * that read to see the post-launch state, not the allocation default.\n * Async resolution either keeps it `running` (streamable returned)\n * or transitions to `done` (sync result or error). */\n #dispatch(task: InternalTask, tool: Tool, call: ToolCallPart, ctxBase: ToolContext): void {\n const ctx: ToolContext = { ...ctxBase, tasks: this }\n task.status = \"running\"\n\n const dispatchPromise = runTool(tool, call.params, ctx, { preflight: false, streaming: true })\n\n void dispatchPromise.then(\n (settled) => {\n if (isStreamable(settled)) {\n // Long-running — hold the streamable for partial snapshots /\n // abort, wire its completion back through done().\n task.streamable = settled\n settled.done.then(\n () => {\n const snap = settled.poll()\n this.done(task.id, {\n content: snap.content,\n error: snap.error,\n isError: snap.isError,\n meta: snap.meta,\n })\n },\n // `done` shouldn't reject by contract; treat as internal bug.\n (error: unknown) => this.done(task.id, toErrorResult(error))\n )\n return\n }\n // Sync path: validation error, sync return, or thrown error —\n // runTool has already formatted everything into a ToolResult.\n this.done(task.id, settled)\n },\n // The permission gate threw (or AiError leaked from runTool).\n // Either way, format and settle the task.\n (error: unknown) => this.done(task.id, toErrorResult(error))\n )\n }\n\n /** Walk pending tasks; start any whose `dependsOn` just completed.\n * If the dependency failed, propagate cancellation: dependents land\n * in `done` with an `UPSTREAM_FAILED` result. */\n #startReadyDependents(completedId: string, completedResult: ToolResult): void {\n for (const t of this.#map.values()) {\n if (t.status !== \"pending\" || t.waitingFor !== completedId) continue\n if (completedResult.isError) {\n // Skip dependent — its predecessor failed.\n this.done(\n t.id,\n toErrorResult(\n new AiError({\n code: \"UPSTREAM_FAILED\",\n data: { dependsOn: completedId },\n message: `skipped: upstream task ${completedId} failed`,\n })\n )\n )\n continue\n }\n void this.#startPending(t)\n }\n }\n\n async #startPending(task: InternalTask): Promise<void> {\n const pending = task.pending\n if (!pending) return\n if (!this.#needsPreflight(pending.tool, pending.ctx)) {\n task.pending = undefined\n task.waitingFor = undefined\n task.ownerRound = undefined\n this.#dispatch(task, pending.tool, pending.call, pending.ctx)\n return\n }\n\n const preflight = await this.#preflight(pending.tool, pending.call, pending.ctx)\n if (preflight) {\n this.done(task.id, preflight)\n return\n }\n\n // Restart as a regular task. The round that originally registered\n // this task has already returned its placeholder, so whatever happens\n // now flows through normal `task-done`.\n task.pending = undefined\n task.waitingFor = undefined\n task.ownerRound = undefined\n this.#dispatch(task, pending.tool, pending.call, pending.ctx)\n }\n\n /** Build a `ToolResultPart` for a task at round-end. Done tasks pass\n * through their captured result; still-running tasks get a snapshot\n * from the streamable (if any) plus a placeholder note for the model. */\n #buildPart(call: ToolCallPart, task: InternalTask): ToolResultPart {\n if (task.status === \"done\" && task.result) {\n return {\n content: task.result.content,\n error: task.result.error,\n id: call.id,\n isError: task.result.isError,\n meta: stampTaskMeta(task.result.meta, task),\n name: call.name,\n type: \"tool-result\",\n }\n }\n\n // Pending: never started, will run when its dependency completes.\n // Placeholder uses the standard TaskInfo shape so it's parseable\n // the same way as task_list / heartbeat entries.\n if (task.status === \"pending\") {\n return {\n content: [{ data: toTaskInfo(task), tag: \"task\", type: \"meta\" }],\n id: call.id,\n isError: false,\n meta: stampTaskMeta(undefined, task),\n name: call.name,\n type: \"tool-result\",\n }\n }\n\n // Running: capture whatever the streamable has so far (partial output)\n // and append a `<task>` MetaPart with an explicit \"still running\"\n // hint. Without the hint, models tend to treat partial output as a\n // final answer and respond prematurely; with it they see the state\n // structurally and know the final result will arrive as a later\n // system message. Tagged `<task>` for symmetry with the pending /\n // task_list / heartbeat / task-done entries — same shape everywhere\n // a task surfaces.\n const snap = task.streamable?.poll()\n const baseContent = partialContentFrom(snap)\n const trailer: MetaPart = {\n content:\n \"Task is still running. Partial output above. The final result \" +\n \"will arrive as a system message when the task completes; you \" +\n \"do not need to poll. Continue with other work or wait.\",\n data: {\n ...toTaskInfo(task),\n },\n tag: \"task\",\n type: \"meta\",\n }\n const parts: ContentPart[] = []\n if (typeof baseContent === \"string\") {\n if (baseContent !== \"\") parts.push({ text: baseContent, type: \"text\" })\n } else {\n parts.push(...baseContent)\n }\n parts.push(trailer)\n return {\n content: parts,\n id: call.id,\n isError: false,\n meta: stampTaskMeta(snap?.meta, task),\n name: call.name,\n type: \"tool-result\",\n }\n }\n}\n\n/** Stamp `meta.task` with the current task state. Preserves any\n * tool-attached `meta` fields. Used both on done results (so the\n * model can correlate completion to the original call) and on\n * partial / pending placeholders. */\nfunction stampTaskMeta(\n base: ToolResult[\"meta\"] | undefined,\n task: InternalTask\n): ToolResult[\"meta\"] & TaskMeta {\n return {\n ...base,\n task: {\n dependsOn: task.waitingFor,\n desc: task.desc,\n durationMs: task.finishedAt ? task.finishedAt - task.startedAt : undefined,\n id: task.id,\n status: task.status,\n type: task.type,\n },\n }\n}\n\n/** Build the \"running\" placeholder content from a streamable snapshot.\n * Empty string when there's nothing yet to show; copies the parts\n * array so downstream mutation of the result message can't reach back\n * into the streamable's accumulator. */\nfunction partialContentFrom(\n snap: { content: ToolResult[\"content\"] } | undefined\n): ToolResultPart[\"content\"] {\n if (!snap) return \"\"\n if (typeof snap.content === \"string\") return snap.content\n return [...snap.content]\n}\n\n/** Best-effort human-readable label for a tool call. Reads a\n * `description` field from params if the tool defined one (bash does);\n * otherwise falls back to the tool name. Kept short so log lines stay\n * scannable. */\nfunction descOfCall(call: ToolCallPart): string {\n const params = call.params as { description?: unknown } | null | undefined\n if (params && typeof params === \"object\" && typeof params.description === \"string\") {\n return params.description\n }\n return call.name\n}\n\n/** Synthesize the tool-result payload returned when the model calls a\n * tool that wasn't registered for this turn. Same shape the previous\n * `unknownToolResult` helper produced; inlined here to keep `tasks.ts`\n * self-contained. */\nfunction unknownToolResult(name: string): ToolResult {\n const err = new AiError({\n code: \"UNKNOWN_TOOL\",\n message: `no tool named \"${name}\" is registered for this turn`,\n })\n return toErrorResult(err)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => {\n const t = setTimeout(r, ms)\n t.unref()\n })\n}\n\n/** Render an array of `TaskInfo` as a `<tasks>` MetaPart for the model\n * (heartbeat pulses and `task_list`). Each task lands as one line of\n * JSON. The `result` field on done tasks is stripped — listing should\n * give an inventory, not historical output (the result was already\n * injected as a system message at task-done time, and re-shipping it\n * on every heartbeat / list call would be a token bomb). */\nexport function taskInfoPart(info: readonly TaskInfo[]): MetaPart {\n if (info.length === 0) return { data: \"no active tasks\", tag: \"tasks\", type: \"meta\" }\n const data = info.map((t) => safeStringify(t, omitResult)).join(\"\\n\")\n return { data, tag: \"tasks\", type: \"meta\" }\n}\n\n/** JSON.stringify replacer that drops the `result` field. Used by\n * `taskInfoPart` to keep listing payloads bounded. */\nfunction omitResult(key: string, value: unknown): unknown {\n return key === \"result\" ? undefined : value\n}\n\nfunction toTaskInfo(task: InternalTask): TaskInfo {\n const { id, status, type, desc } = task\n const ms = (task.finishedAt ?? Date.now()) - task.startedAt\n if (status === \"running\") {\n return { desc, elapsedMs: ms, hasNewOutput: task.streamable?.hasNew?.(), id, status, type }\n }\n if (status === \"pending\") {\n return { desc, elapsedMs: ms, id, status, type, waitingFor: task.waitingFor ?? \"\" }\n }\n // status === \"done\" — `result` is set by `done()` before status flips,\n // so the `?? toErrorResult(...)` is just a defensive fallback for\n // a malformed record (shouldn't happen in practice).\n return {\n desc,\n durationMs: ms,\n id,\n result:\n task.result ??\n toErrorResult(\n new AiError({\n code: \"INTERNAL\",\n message: `task \"${task.id}\" completed without a result`,\n })\n ),\n status,\n type,\n }\n}\n\n/** Format a finished task as the parts of a system inject. Layout:\n *\n * <task>{id, type, desc, status: \"done\", durationMs}</task>\n * {result body}\n *\n * The header is the standard `TaskInfo`-shaped JSON so consumers\n * (model, TUI) can parse it the same way they parse `task_list` and\n * heartbeat output — same shape everywhere a task surfaces.\n *\n * The body comes straight from `result.content`. For errors, that\n * already includes the `<error>{code, message, ...}</error>` MetaPart\n * + the formatted `❌ CODE: message` block (baked in by\n * `toErrorResult`), so this function doesn't need to special-case\n * errors — the structured tag and human body ride along with the\n * result content for any tool failure, anywhere.\n *\n * System messages can't carry attachments, so any image/pdf/etc. in\n * the result degrades to a `[image]` placeholder via\n * `stringifyContent` — best-effort, model still sees *something* was\n * there. */\nfunction formatTaskCompletion(task: DoneTaskInfo): (TextPart | MetaPart)[] {\n const { result, ...header } = task\n const parts: (TextPart | MetaPart)[] = [{ data: header, tag: \"task\", type: \"meta\" }]\n const bodyText = stringifyContent(result.content)\n if (bodyText !== \"\") parts.push({ text: bodyText, type: \"text\" })\n return parts\n}\n\n/** Build an `inject`-ready system message for a finished task. */\nexport function taskCompletionMessage(task: DoneTaskInfo): Message<\"system\"> {\n return {\n content: formatTaskCompletion(task),\n meta: { kind: \"task\", taskId: task.id },\n role: \"system\",\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { r as taskInfoPart } from "./tasks-WdRAHsOL.mjs";
1
+ import { r as taskInfoPart } from "./tasks-D76WXWr2.mjs";
2
2
  import { AiError, defineTool } from "@zaly/ai";
3
3
  import { Type } from "typebox";
4
- //#region src/tools/tasks.ts
4
+ // src/tools/tasks.ts
5
5
  /**
6
6
  * Generic task management surface for the model.
7
7
  *
@@ -60,7 +60,6 @@ function requireTasks(ctx) {
60
60
  });
61
61
  return ctx.tasks;
62
62
  }
63
- //#endregion
64
63
  export { taskListTool, taskPollTool, taskStopTool };
65
64
 
66
- //# sourceMappingURL=tasks-BA-PCeGa.mjs.map
65
+ //# sourceMappingURL=tasks-Dgsiuh0Q.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks-BA-PCeGa.mjs","names":[],"sources":["../src/tools/tasks.ts"],"sourcesContent":["import type { ToolContext } from \"@zaly/ai\"\nimport type { Tasks } from \"../tasks.ts\"\n\nimport { defineTool, AiError } from \"@zaly/ai\"\nimport { Type } from \"typebox\"\nimport { taskInfoPart } from \"../tasks.ts\"\n\n/**\n * Generic task management surface for the model.\n *\n * - `task_list`: enumerate running and recently-finished tasks.\n * - `task_stop`: abort a running task. Idempotent.\n *\n * \"Wait for a task\" is intentionally absent — heartbeats keep the loop\n * alive while tasks run, and `task-done` injects the final result as a\n * system message automatically. If the model wants explicit polling\n * cadence on something specific, it schedules a `wakeup` instead.\n *\n * Permission gating, when wired up, is the harness's concern; these\n * tools are intentionally thin so the policy lives one layer up.\n */\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const taskListTool = defineTool({\n name: \"task_list\",\n desc:\n \"List active and recently-finished tasks (running shells, subagents, \" +\n \"any other long-running work the model has kicked off). Use this when \" +\n \"you've lost track of an id, or to check which background work is \" +\n \"still in flight.\",\n parallel: true,\n params: Type.Object({\n includeFinished: Type.Optional(\n Type.Boolean({\n default: false,\n description: \"When true, also include tasks that have already completed in this session.\",\n })\n ),\n }),\n\n call(args, ctx) {\n const tasks = requireTasks(ctx)\n // Routes through `taskInfoPart` so the `result` strip + line-per-task\n // JSON format stays consistent with heartbeat output. Done tasks\n // surface only their identity / timing, not their (potentially huge)\n // captured body.\n const info = tasks\n .info()\n .filter((task) => (args.includeFinished ?? false) || task.status !== \"done\")\n return taskInfoPart(info)\n },\n})\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const taskPollTool = defineTool({\n name: \"task_poll\",\n desc:\n \"Read the latest incremental output from a running task. Returns \" +\n \"only what's arrived since the previous `task_poll` (or since the \" +\n \"task's running placeholder was first surfaced). Use when a heartbeat \" +\n \"flagged a task with `*new*`, or to peek at progress on a long \" +\n \"command (build, test run, tail -f). Errors if the task is already \" +\n \"done (its result was injected as a system message) or has no \" +\n \"streaming output.\",\n parallel: true,\n params: Type.Object({\n id: Type.String({ description: \"Task id to poll.\" }),\n }),\n\n call(args, ctx) {\n const tasks = requireTasks(ctx)\n const snap = tasks.pollOutput(args.id)\n // The snapshot's `content` already carries any streamable-emitted\n // MetaParts (bash's `<shell>`, etc.), so the model sees status +\n // incremental output in one go. Returning content directly avoids\n // the JSON-stringify path normalize would take on a ToolResult shape.\n return snap.content\n },\n})\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const taskStopTool = defineTool({\n name: \"task_stop\",\n desc:\n \"Stop a running task. Aborts the underlying work (e.g. SIGTERM \" +\n \"→ SIGKILL for bash); pending tasks chained behind a stopped task get \" +\n \"auto-cancelled. Idempotent — safe to call on an already-finished task.\",\n params: Type.Object({\n id: Type.String({ description: \"Task id to stop.\" }),\n }),\n\n call(args, ctx) {\n const tasks = requireTasks(ctx)\n const task = tasks.get(args.id)\n if (!task) {\n throw new AiError({\n code: \"NOT_FOUND\",\n data: { id: args.id },\n message: `no task with id \"${args.id}\"`,\n })\n }\n tasks.abort(args.id, \"stopped via task_stop\")\n return `task ${args.id} stopped`\n },\n})\n\n// ── Internals ──────────────────────────────────────────────────────────\n\nfunction requireTasks(ctx: ToolContext): Tasks {\n if (!ctx.tasks) {\n throw new AiError({\n code: \"MISSING_TOOL_CONTEXT\",\n message: \"task tools require a Tasks registry on the context (set up by the agent harness).\",\n })\n }\n return ctx.tasks\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuBA,MAAa,eAAe,WAAW;CACrC,MAAM;CACN,MACE;CAIF,UAAU;CACV,QAAQ,KAAK,OAAO,EAClB,iBAAiB,KAAK,SACpB,KAAK,QAAQ;EACX,SAAS;EACT,aAAa;CACf,CAAC,CACH,EACF,CAAC;CAED,KAAK,MAAM,KAAK;EAMd,MAAM,OALQ,aAAa,GAKV,CAAC,CACf,KAAK,CAAC,CACN,QAAQ,UAAU,KAAK,mBAAmB,UAAU,KAAK,WAAW,MAAM;EAC7E,OAAO,aAAa,IAAI;CAC1B;AACF,CAAC;AAGD,MAAa,eAAe,WAAW;CACrC,MAAM;CACN,MACE;CAOF,UAAU;CACV,QAAQ,KAAK,OAAO,EAClB,IAAI,KAAK,OAAO,EAAE,aAAa,mBAAmB,CAAC,EACrD,CAAC;CAED,KAAK,MAAM,KAAK;EAOd,OANc,aAAa,GACV,CAAC,CAAC,WAAW,KAAK,EAKzB,CAAC,CAAC;CACd;AACF,CAAC;AAGD,MAAa,eAAe,WAAW;CACrC,MAAM;CACN,MACE;CAGF,QAAQ,KAAK,OAAO,EAClB,IAAI,KAAK,OAAO,EAAE,aAAa,mBAAmB,CAAC,EACrD,CAAC;CAED,KAAK,MAAM,KAAK;EACd,MAAM,QAAQ,aAAa,GAAG;EAE9B,IAAI,CADS,MAAM,IAAI,KAAK,EACpB,GACN,MAAM,IAAI,QAAQ;GAChB,MAAM;GACN,MAAM,EAAE,IAAI,KAAK,GAAG;GACpB,SAAS,oBAAoB,KAAK,GAAG;EACvC,CAAC;EAEH,MAAM,MAAM,KAAK,IAAI,uBAAuB;EAC5C,OAAO,QAAQ,KAAK,GAAG;CACzB;AACF,CAAC;AAID,SAAS,aAAa,KAAyB;CAC7C,IAAI,CAAC,IAAI,OACP,MAAM,IAAI,QAAQ;EAChB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,OAAO,IAAI;AACb"}
1
+ {"version":3,"file":"tasks-Dgsiuh0Q.mjs","names":[],"sources":["../src/tools/tasks.ts"],"sourcesContent":["import type { ToolContext } from \"@zaly/ai\"\nimport type { Tasks } from \"../tasks.ts\"\n\nimport { defineTool, AiError } from \"@zaly/ai\"\nimport { Type } from \"typebox\"\nimport { taskInfoPart } from \"../tasks.ts\"\n\n/**\n * Generic task management surface for the model.\n *\n * - `task_list`: enumerate running and recently-finished tasks.\n * - `task_stop`: abort a running task. Idempotent.\n *\n * \"Wait for a task\" is intentionally absent — heartbeats keep the loop\n * alive while tasks run, and `task-done` injects the final result as a\n * system message automatically. If the model wants explicit polling\n * cadence on something specific, it schedules a `wakeup` instead.\n *\n * Permission gating, when wired up, is the harness's concern; these\n * tools are intentionally thin so the policy lives one layer up.\n */\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const taskListTool = defineTool({\n name: \"task_list\",\n desc:\n \"List active and recently-finished tasks (running shells, subagents, \" +\n \"any other long-running work the model has kicked off). Use this when \" +\n \"you've lost track of an id, or to check which background work is \" +\n \"still in flight.\",\n parallel: true,\n params: Type.Object({\n includeFinished: Type.Optional(\n Type.Boolean({\n default: false,\n description: \"When true, also include tasks that have already completed in this session.\",\n })\n ),\n }),\n\n call(args, ctx) {\n const tasks = requireTasks(ctx)\n // Routes through `taskInfoPart` so the `result` strip + line-per-task\n // JSON format stays consistent with heartbeat output. Done tasks\n // surface only their identity / timing, not their (potentially huge)\n // captured body.\n const info = tasks\n .info()\n .filter((task) => (args.includeFinished ?? false) || task.status !== \"done\")\n return taskInfoPart(info)\n },\n})\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const taskPollTool = defineTool({\n name: \"task_poll\",\n desc:\n \"Read the latest incremental output from a running task. Returns \" +\n \"only what's arrived since the previous `task_poll` (or since the \" +\n \"task's running placeholder was first surfaced). Use when a heartbeat \" +\n \"flagged a task with `*new*`, or to peek at progress on a long \" +\n \"command (build, test run, tail -f). Errors if the task is already \" +\n \"done (its result was injected as a system message) or has no \" +\n \"streaming output.\",\n parallel: true,\n params: Type.Object({\n id: Type.String({ description: \"Task id to poll.\" }),\n }),\n\n call(args, ctx) {\n const tasks = requireTasks(ctx)\n const snap = tasks.pollOutput(args.id)\n // The snapshot's `content` already carries any streamable-emitted\n // MetaParts (bash's `<shell>`, etc.), so the model sees status +\n // incremental output in one go. Returning content directly avoids\n // the JSON-stringify path normalize would take on a ToolResult shape.\n return snap.content\n },\n})\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const taskStopTool = defineTool({\n name: \"task_stop\",\n desc:\n \"Stop a running task. Aborts the underlying work (e.g. SIGTERM \" +\n \"→ SIGKILL for bash); pending tasks chained behind a stopped task get \" +\n \"auto-cancelled. Idempotent — safe to call on an already-finished task.\",\n params: Type.Object({\n id: Type.String({ description: \"Task id to stop.\" }),\n }),\n\n call(args, ctx) {\n const tasks = requireTasks(ctx)\n const task = tasks.get(args.id)\n if (!task) {\n throw new AiError({\n code: \"NOT_FOUND\",\n data: { id: args.id },\n message: `no task with id \"${args.id}\"`,\n })\n }\n tasks.abort(args.id, \"stopped via task_stop\")\n return `task ${args.id} stopped`\n },\n})\n\n// ── Internals ──────────────────────────────────────────────────────────\n\nfunction requireTasks(ctx: ToolContext): Tasks {\n if (!ctx.tasks) {\n throw new AiError({\n code: \"MISSING_TOOL_CONTEXT\",\n message: \"task tools require a Tasks registry on the context (set up by the agent harness).\",\n })\n }\n return ctx.tasks\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuBA,MAAa,eAAe,WAAW;CACrC,MAAM;CACN,MACE;CAIF,UAAU;CACV,QAAQ,KAAK,OAAO,EAClB,iBAAiB,KAAK,SACpB,KAAK,QAAQ;EACX,SAAS;EACT,aAAa;CACf,CAAC,CACH,EACF,CAAC;CAED,KAAK,MAAM,KAAK;EAMd,MAAM,OALQ,aAAa,GAKV,CAAC,CACf,KAAK,CAAC,CACN,QAAQ,UAAU,KAAK,mBAAmB,UAAU,KAAK,WAAW,MAAM;EAC7E,OAAO,aAAa,IAAI;CAC1B;AACF,CAAC;AAGD,MAAa,eAAe,WAAW;CACrC,MAAM;CACN,MACE;CAOF,UAAU;CACV,QAAQ,KAAK,OAAO,EAClB,IAAI,KAAK,OAAO,EAAE,aAAa,mBAAmB,CAAC,EACrD,CAAC;CAED,KAAK,MAAM,KAAK;EAOd,OANc,aAAa,GACV,CAAC,CAAC,WAAW,KAAK,EAKzB,CAAC,CAAC;CACd;AACF,CAAC;AAGD,MAAa,eAAe,WAAW;CACrC,MAAM;CACN,MACE;CAGF,QAAQ,KAAK,OAAO,EAClB,IAAI,KAAK,OAAO,EAAE,aAAa,mBAAmB,CAAC,EACrD,CAAC;CAED,KAAK,MAAM,KAAK;EACd,MAAM,QAAQ,aAAa,GAAG;EAE9B,IAAI,CADS,MAAM,IAAI,KAAK,EACpB,GACN,MAAM,IAAI,QAAQ;GAChB,MAAM;GACN,MAAM,EAAE,IAAI,KAAK,GAAG;GACpB,SAAS,oBAAoB,KAAK,GAAG;EACvC,CAAC;EAEH,MAAM,MAAM,KAAK,IAAI,uBAAuB;EAC5C,OAAO,QAAQ,KAAK,GAAG;CACzB;AACF,CAAC;AAID,SAAS,aAAa,KAAyB;CAC7C,IAAI,CAAC,IAAI,OACP,MAAM,IAAI,QAAQ;EAChB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,OAAO,IAAI;AACb"}
@@ -1,37 +1,6 @@
1
+ import { t as __commonJSMin } from "./rolldown-runtime-DYf_mQCB.mjs";
1
2
  import { safeStringify } from "@zaly/shared";
2
- //#region \0rolldown/runtime.js
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
10
- var __exportAll = (all, no_symbols) => {
11
- let target = {};
12
- for (var name in all) __defProp(target, name, {
13
- get: all[name],
14
- enumerable: true
15
- });
16
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
- return target;
18
- };
19
- var __copyProps = (to, from, except, desc) => {
20
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
21
- key = keys[i];
22
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
23
- get: ((k) => from[k]).bind(null, key),
24
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
25
- });
26
- }
27
- return to;
28
- };
29
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
30
- value: mod,
31
- enumerable: true
32
- }) : target, mod));
33
- //#endregion
34
- //#region ../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/quote.js
3
+ // ../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/quote.js
35
4
  var require_quote = /* @__PURE__ */ __commonJSMin(((exports, module) => {
36
5
  /** @import { ControlOperator } from './parse' */
37
6
  /** @type {ControlOperator['op'][]} */
@@ -95,8 +64,7 @@ var require_quote = /* @__PURE__ */ __commonJSMin(((exports, module) => {
95
64
  }).join(" ");
96
65
  };
97
66
  }));
98
- //#endregion
99
- //#region ../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/parse.js
67
+ // ../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/parse.js
100
68
  var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
101
69
  /**
102
70
  * @import {
@@ -363,8 +331,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
363
331
  }, []);
364
332
  };
365
333
  }));
366
- //#endregion
367
- //#region src/utils/bash/parser.ts
334
+ // src/utils/bash/parser.ts
368
335
  var import_shell_quote = (/* @__PURE__ */ __commonJSMin(((exports) => {
369
336
  exports.quote = require_quote();
370
337
  exports.parse = require_parse();
@@ -628,8 +595,7 @@ function flattenParens(tokens) {
628
595
  tokens: out
629
596
  };
630
597
  }
631
- //#endregion
632
- //#region src/utils/bash/tools.ts
598
+ // src/utils/bash/tools.ts
633
599
  /** All bare positional args (no leading dash). Default for many
634
600
  * read-only utilities. */
635
601
  function positionals(args) {
@@ -795,7 +761,6 @@ const TOOLS = {
795
761
  wc: { reads: positionals },
796
762
  xxd: { reads: positionals }
797
763
  };
798
- //#endregion
799
- export { __toESM as a, __exportAll as i, parseBash as n, __commonJSMin as r, TOOLS as t };
764
+ export { parseBash as n, TOOLS as t };
800
765
 
801
- //# sourceMappingURL=tools-wvkkuXWH.mjs.map
766
+ //# sourceMappingURL=tools-DmoUYORG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools-wvkkuXWH.mjs","names":["shellParse"],"sources":["../../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/quote.js","../../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/parse.js","../../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/index.js","../src/utils/bash/parser.ts","../src/utils/bash/tools.ts"],"sourcesContent":["'use strict';\n\n/** @import { ControlOperator } from './parse' */\n\n/** @type {ControlOperator['op'][]} */\nvar OPS = /** @type {const} */ ([\n\t'||',\n\t'&&',\n\t';;&',\n\t';;',\n\t';&',\n\t'|&',\n\t'<(',\n\t'>(',\n\t'<<<',\n\t'<<-',\n\t'<<',\n\t'>>',\n\t'>&',\n\t'>|',\n\t'&>>',\n\t'&>',\n\t'<&',\n\t'<>',\n\t'&',\n\t';',\n\t'(',\n\t')',\n\t'|',\n\t'<',\n\t'>'\n]);\nvar LINE_TERMINATORS = /[\\n\\r\\u2028\\u2029]/;\nvar GLOB_SHELL_SPECIAL = /[\\s#!\"$&'():;<=>@\\\\^`|~]/g;\n\n/** @type {typeof import('./quote')} */\nmodule.exports = function quote(xs) {\n\tvar sawComment = false;\n\treturn xs.map(function (s) {\n\t\tif (sawComment && typeof s === 'string' && LINE_TERMINATORS.test(s)) {\n\t\t\tthrow new TypeError('a token after a `comment` must not contain line terminators');\n\t\t}\n\t\tif (s === '') {\n\t\t\treturn /** @type {const} */ ('\\'\\'');\n\t\t}\n\t\tif (s && typeof s === 'object') {\n\t\t\tif ('op' in s && s.op === 'glob') {\n\t\t\t\tif (typeof s.pattern !== 'string') {\n\t\t\t\t\tthrow new TypeError('glob token requires a string `pattern`');\n\t\t\t\t}\n\t\t\t\tif (LINE_TERMINATORS.test(s.pattern)) {\n\t\t\t\t\tthrow new TypeError('glob `pattern` must not contain line terminators');\n\t\t\t\t}\n\t\t\t\tif (s.pattern === '') {\n\t\t\t\t\treturn /** @type {const} */ ('\\'\\'');\n\t\t\t\t}\n\t\t\t\treturn s.pattern.replace(GLOB_SHELL_SPECIAL, '\\\\$&');\n\t\t\t}\n\t\t\tif ('op' in s && typeof s.op === 'string') {\n\t\t\t\tif (OPS.indexOf(s.op) < 0) {\n\t\t\t\t\tthrow new TypeError('invalid `op` value: ' + JSON.stringify(s.op));\n\t\t\t\t}\n\t\t\t\treturn s.op.replace(/[\\s\\S]/g, '\\\\$&');\n\t\t\t}\n\t\t\tif ('comment' in s && typeof s.comment === 'string') {\n\t\t\t\tif (LINE_TERMINATORS.test(s.comment)) {\n\t\t\t\t\tthrow new TypeError('`comment` must not contain line terminators');\n\t\t\t\t}\n\t\t\t\tsawComment = true;\n\t\t\t\treturn '#' + s.comment;\n\t\t\t}\n\t\t\tthrow new TypeError('unrecognized object token shape');\n\t\t}\n\t\tif ((/'/).test(s) && (/!/).test(s)) {\n\t\t\treturn \"'\" + s.replace(/'/g, \"'\\\"'\\\"'\") + \"'\";\n\t\t}\n\t\tif ((/[\"\\s\\\\]/).test(s) && !(/'/).test(s)) {\n\t\t\treturn \"'\" + s + \"'\";\n\t\t}\n\t\tif ((/[\"'\\s]/).test(s)) {\n\t\t\treturn '\"' + s.replace(/([\"\\\\$`])/g, '\\\\$1') + '\"';\n\t\t}\n\t\treturn String(s).replace(/([A-Za-z]:)?([#!\"$&'()*,:;<=>?@[\\\\\\]^`{|}~])/g, '$1\\\\$2');\n\t}).join(' ');\n};\n","'use strict';\n\n/**\n * @import {\n * \tControlOperator,\n * \tEnv,\n * \tGlobPattern,\n * \tParseEntry,\n * } from './parse' */\n\n// '<(' and '>(' are process substitution operators and\n// can be parsed the same as control operator\nvar CONTROL = /** @type {const} */ ('(?:') + /** @type {const} */ ([\n\t'\\\\|\\\\|',\n\t'\\\\&(?:\\\\&|>>?)', // `&&`, `&>`, and `&>>`\n\t';;\\\\&?', // `;;` and `;;&`\n\t'[;|]\\\\&', // `;&` and `|&`\n\t'\\\\<\\\\(',\n\t'\\\\<\\\\<\\\\<',\n\t'\\\\<\\\\<-',\n\t'\\\\<\\\\<(?!\\\\()', // `<<(` stays `<` and `<(`, as zsh reads it; other shells reject it\n\t'>>',\n\t'>[&|(]', // `>&`, `>|`, and `>(`\n\t'<[&>]', // `<&` and `<>`\n\t'[&;()|<>]'\n]).join(/** @type {const} */ ('|')) + /** @type {const} */ (')');\nvar controlRE = new RegExp('^' + CONTROL + '$');\nvar META = /** @type {const} */ ('|&;()<> \\\\t');\nvar SINGLE_QUOTE = /** @type {const} */ ('\\'([^\\']*?)\\'');\n// bash ANSI-C quoting, `$'...'`: a backslash escapes the next character, including `'`\nvar ANSI_C_BODY = '(?:\\\\\\\\[\\\\s\\\\S]|[^\\\\\\\\\\'])*?';\nvar ANSI_C_QUOTE = '\\\\$\\'' + ANSI_C_BODY + '\\'';\nvar ansiCAt = new RegExp('\\\\$\\'' + ANSI_C_BODY + '(?:(\\')|\\\\\\\\?$)', 'g');\nvar ANSI_C_LETTERS = 'abeEfnrtv';\nvar ANSI_C_CHARS = '\\x07\\b\\x1B\\x1B\\f\\n\\r\\t\\v';\nvar hash = /^#$/;\n\nvar SQ = /** @type {const} */ (\"'\");\nvar DQ = /** @type {const} */ ('\"');\nvar DS = /** @type {const} */ ('$');\n\nvar TOKEN = '';\nvar mult = /** @type {const} */ (0x100000000); // Math.pow(16, 8);\nfor (var i = 0; i < 4; i++) {\n\tTOKEN += (mult * Math.random()).toString(16);\n}\nvar startsWithToken = new RegExp('^' + TOKEN);\n\n/**\n * @param {string} s\n * @param {RegExp} r\n */\nfunction matchAll(s, r) {\n\tvar origIndex = r.lastIndex;\n\n\tvar matches = [];\n\tvar matchObj;\n\n\twhile ((matchObj = r.exec(s))) {\n\t\tmatches[matches.length] = matchObj;\n\t\tif (r.lastIndex === matchObj.index) {\n\t\t\tr.lastIndex += 1;\n\t\t}\n\t}\n\n\tr.lastIndex = origIndex;\n\n\treturn matches;\n}\n\n/**\n * @param {Env} env\n * @param {string} pre\n * @param {string} key\n */\nfunction getVar(env, pre, key) {\n\tvar r = typeof env === 'function' ? env(key) : env[key];\n\tif (typeof r === 'undefined' && key != '') {\n\t\tr = '';\n\t} else if (typeof r === 'undefined') {\n\t\tr = '$';\n\t}\n\n\tif (typeof r === 'object') {\n\t\treturn pre + TOKEN + JSON.stringify(r) + TOKEN;\n\t}\n\treturn pre + r;\n}\n\nvar ansiCEscape = /\\\\([0-7]{1,3}|x[\\dA-Fa-f]{1,2}|u[\\dA-Fa-f]{1,4}|U[\\dA-Fa-f]{1,8}|c(?:\\\\\\\\|[\\s\\S])|[abeEfnrtv\\\\'\"?])/g;\n\n/**\n * @param {string} m\n * @param {string} escape\n */\nfunction expandAnsiCEscape(m, escape) {\n\tvar kind = escape.charAt(0);\n\tif (kind === 'c') {\n\t\tvar ctrl = escape.charAt(1);\n\t\treturn ctrl === '?' ? '\\x7F' : String.fromCharCode(ctrl.charCodeAt(0) & 0x1F);\n\t}\n\tif (kind === 'x' || kind === 'u' || kind === 'U') {\n\t\tvar cp = parseInt(escape.slice(1), 16);\n\t\tif (cp > 0x10FFFF) {\n\t\t\treturn m;\n\t\t}\n\t\treturn String.fromCharCode.apply(null, cp > 0xFFFF ? [0xD7C0 + (cp >> 10), 0xDC00 + (cp & 0x3FF)] : [cp]);\n\t}\n\tif (kind >= '0' && kind <= '7') {\n\t\treturn String.fromCharCode(parseInt(escape, 8) & 0xFF);\n\t}\n\tvar letter = ANSI_C_LETTERS.indexOf(escape);\n\treturn letter < 0 ? escape : ANSI_C_CHARS.charAt(letter);\n}\n\n/** @param {string} body */\nfunction expandAnsiC(body) {\n\treturn body.replace(ansiCEscape, expandAnsiCEscape).split('\\0')[0]; // like bash, a NUL ends the string\n}\n\n/**\n * @param {string} s\n * @param {number} i\n */\nfunction closesAnsiC(s, i) {\n\tansiCAt.lastIndex = i;\n\treturn !!(/** @type {RegExpExecArray} */ (ansiCAt.exec(s)))[1];\n}\n\n/**\n * @param {string} string\n * @param {Env} [env]\n * @param {{ escape?: string, splitUnquoted?: boolean | string }} [opts]\n * @returns {ParseEntry[]}\n */\nfunction parseInternal(string, env, opts) {\n\tif (!opts) {\n\t\topts = {};\n\t}\n\tvar BS = opts.escape || '\\\\';\n\tvar ifs = opts.splitUnquoted === true ? ' \\t\\n' : (typeof opts.splitUnquoted === 'string' ? opts.splitUnquoted : '');\n\tvar BAREWORD = '(\\\\' + BS + '[\\'\"$\\\\' + BS + META + ']|\\\\$\\\\$|\\\\$(?!' + ANSI_C_QUOTE.slice(2) + ')|[^\\\\s\\'\"$' + META + '])+';\n\tvar DOUBLE_QUOTE = '\"(?:\\\\' + BS + '[\\\\s\\\\S]|[^\"\\\\' + BS + '])*\"';\n\n\tvar chunker = new RegExp([\n\t\t'(' + CONTROL + ')', // control chars\n\t\t'(' + ANSI_C_QUOTE + '|' + BAREWORD + '|' + DOUBLE_QUOTE + '|' + SINGLE_QUOTE + ')+'\n\t].join('|'), 'g');\n\n\tvar matches = matchAll(string, chunker);\n\n\tif (matches.length === 0) {\n\t\treturn [];\n\t}\n\tif (!env) {\n\t\tenv = {};\n\t}\n\n\tvar commented = false;\n\n\treturn matches.map(function (match) {\n\t\tvar s = match[0];\n\t\tif (!s || commented) {\n\t\t\treturn void undefined;\n\t\t}\n\t\tif (controlRE.test(s)) {\n\t\t\treturn /** @type {ControlOperator} */ ({ op: s });\n\t\t}\n\n\t\t// Hand-written scanner/parser for Bash quoting rules:\n\t\t//\n\t\t// 1. inside single quotes, all characters are printed literally.\n\t\t// 2. inside double quotes, all characters are printed literally\n\t\t// except variables prefixed by '$' and backslashes followed by\n\t\t// either a double quote or another backslash.\n\t\t// 3. outside of any quotes, backslashes are treated as escape\n\t\t// characters and not printed (unless they are themselves escaped)\n\t\t// 4. quote context can switch mid-token if there is no whitespace\n\t\t// between the two quote contexts (e.g. all'one'\"token\" parses as\n\t\t// \"allonetoken\")\n\t\t/** @type {string | boolean} */\n\t\tvar quote = false;\n\t\tvar esc = false;\n\t\tvar out = '';\n\t\t/** @type {string[]} */\n\t\tvar words = [];\n\t\tvar sawQuote = false;\n\t\t/** @type {number | null} */\n\t\tvar pendingNw = null;\n\t\tvar isGlob = false;\n\t\t/** @type {number} */\n\t\tvar i;\n\n\t\tfunction parseEnvVar() {\n\t\t\ti += 1;\n\t\t\t/** @type {number | RegExpMatchArray | null} */\n\t\t\tvar varend;\n\t\t\t/** @type {string} */\n\t\t\tvar varname;\n\t\t\tvar char = s.charAt(i);\n\n\t\t\tif (char === '{') {\n\t\t\t\ti += 1;\n\t\t\t\tif (s.charAt(i) === '}') {\n\t\t\t\t\tthrow new Error('Bad substitution: ' + s.slice(i - 2, i + 1));\n\t\t\t\t}\n\t\t\t\t// match braces by depth so a nested `${` keeps its inner `}` from ending the outer substitution\n\t\t\t\tvar depth = 1;\n\t\t\t\tvarend = i;\n\t\t\t\twhile (depth > 0 && varend < s.length) {\n\t\t\t\t\tif (s.charAt(varend) === '{' && s.charAt(varend - 1) === '$') {\n\t\t\t\t\t\tdepth += 1;\n\t\t\t\t\t} else if (s.charAt(varend) === '}') {\n\t\t\t\t\t\tdepth -= 1;\n\t\t\t\t\t}\n\t\t\t\t\tvarend += 1;\n\t\t\t\t}\n\t\t\t\tif (depth !== 0) {\n\t\t\t\t\tthrow new Error('Bad substitution: ' + s.slice(i));\n\t\t\t\t}\n\t\t\t\tvarend -= 1;\n\t\t\t\tvarname = s.slice(i, varend);\n\t\t\t\ti = varend;\n\t\t\t} else if ((/[*@#?$!-]/).test(char)) {\n\t\t\t\tvarname = char;\n\t\t\t} else {\n\t\t\t\tvar slicedFromI = s.slice(i);\n\t\t\t\tvarend = slicedFromI.match(/[^\\w\\d_]/);\n\t\t\t\tif (!varend) {\n\t\t\t\t\tvarname = slicedFromI;\n\t\t\t\t\ti = s.length;\n\t\t\t\t} else {\n\t\t\t\t\tvarname = slicedFromI.slice(0, varend.index);\n\t\t\t\t\ti += /** @type {number} */ (varend.index) - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn getVar(/** @type {NonNullable<typeof env>} */ (env), '', varname);\n\t\t}\n\n\t\tfunction flushRun() {\n\t\t\tif (pendingNw === null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (pendingNw === 0) {\n\t\t\t\tif (out !== '') {\n\t\t\t\t\twords[words.length] = out;\n\t\t\t\t\tout = '';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twords[words.length] = out;\n\t\t\t\tout = '';\n\t\t\t\tfor (var fe = 1; fe < pendingNw; fe += 1) {\n\t\t\t\t\twords[words.length] = '';\n\t\t\t\t}\n\t\t\t}\n\t\t\tpendingNw = null;\n\t\t}\n\n\t\tfor (i = 0; i < s.length; i++) {\n\t\t\tvar c = s.charAt(i);\n\t\t\tif (ifs && c !== DS) {\n\t\t\t\tflushRun();\n\t\t\t}\n\t\t\tisGlob = isGlob || (!quote && (c === '*' || c === '?'));\n\t\t\tif (esc) {\n\t\t\t\tout += c;\n\t\t\t\tesc = false;\n\t\t\t} else if (quote) {\n\t\t\t\tif (c === quote) {\n\t\t\t\t\tquote = false;\n\t\t\t\t} else if (quote == SQ) {\n\t\t\t\t\tout += c;\n\t\t\t\t} else { // Double quote\n\t\t\t\t\tif (c === BS) {\n\t\t\t\t\t\ti += 1;\n\t\t\t\t\t\tc = s.charAt(i);\n\t\t\t\t\t\tif (c === DQ || c === BS || c === DS) {\n\t\t\t\t\t\t\tout += c;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tout += BS + c;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (c === DS) {\n\t\t\t\t\t\tout += parseEnvVar();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tout += c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (c === DQ || c === SQ) {\n\t\t\t\tquote = c;\n\t\t\t\tsawQuote = true;\n\t\t\t} else if (controlRE.test(c)) {\n\t\t\t\treturn /** @type {ControlOperator} */ ({ op: s });\n\t\t\t} else if (hash.test(c)) {\n\t\t\t\tcommented = true;\n\t\t\t\tvar commentObj = { comment: string.slice(match.index + i + 1) };\n\t\t\t\tif (out.length) {\n\t\t\t\t\treturn /** @type {const} */ ([out, commentObj]);\n\t\t\t\t}\n\t\t\t\treturn /** @type {const} */ ([commentObj]);\n\t\t\t} else if (c === BS) {\n\t\t\t\tesc = true;\n\t\t\t} else if (c === DS && s.charAt(i + 1) === SQ && closesAnsiC(s, i)) {\n\t\t\t\tflushRun();\n\t\t\t\tsawQuote = true;\n\t\t\t\tout += expandAnsiC(s.slice(i + 2, ansiCAt.lastIndex - 1));\n\t\t\t\ti = ansiCAt.lastIndex - 1;\n\t\t\t} else if (c === DS) {\n\t\t\t\tvar value = parseEnvVar();\n\t\t\t\tif (!ifs) {\n\t\t\t\t\tout += value;\n\t\t\t\t} else {\n\t\t\t\t\tfor (var vi = 0; vi < value.length; vi += 1) {\n\t\t\t\t\t\tvar vc = value.charAt(vi);\n\t\t\t\t\t\tif (ifs.indexOf(vc) < 0) {\n\t\t\t\t\t\t\tflushRun();\n\t\t\t\t\t\t\tout += vc;\n\t\t\t\t\t\t} else if (pendingNw === null) {\n\t\t\t\t\t\t\tpendingNw = vc === ' ' || vc === '\\t' || vc === '\\n' ? 0 : 1;\n\t\t\t\t\t\t} else if (vc !== ' ' && vc !== '\\t' && vc !== '\\n') {\n\t\t\t\t\t\t\tpendingNw += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tout += c;\n\t\t\t}\n\t\t}\n\n\t\tif (isGlob) {\n\t\t\treturn /** @type {GlobPattern} */ ({ op: 'glob', pattern: out });\n\t\t}\n\n\t\tif (ifs) {\n\t\t\tif (pendingNw !== null && pendingNw > 0) {\n\t\t\t\twords[words.length] = out;\n\t\t\t\tout = '';\n\t\t\t\tfor (var te = 1; te < pendingNw; te += 1) {\n\t\t\t\t\twords[words.length] = '';\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (out !== '' || (sawQuote && words.length === 0)) {\n\t\t\t\twords[words.length] = out;\n\t\t\t}\n\t\t\treturn words;\n\t\t}\n\n\t\treturn out;\n\t}).reduce(function (prev, arg) { // finalize parsed arguments\n\t\tif (typeof arg === 'undefined') {\n\t\t\treturn prev;\n\t\t}\n\t\t/** @type {ParseEntry[]} */ ([]).concat(arg).forEach(function (entry) {\n\t\t\tprev[prev.length] = entry;\n\t\t});\n\t\treturn prev;\n\t}, /** @type {ParseEntry[]} */ ([]));\n}\n\n/** @type {typeof import('./parse')} */\nmodule.exports = function parse(s, env, opts) {\n\tvar mapped = parseInternal(s, env, opts);\n\tif (typeof env !== 'function') {\n\t\treturn mapped;\n\t}\n\treturn mapped.reduce(function (acc, s) {\n\t\tif (typeof s === 'object') {\n\t\t\tacc[acc.length] = s;\n\t\t\treturn acc;\n\t\t}\n\t\tvar xs = s.split(RegExp('(' + TOKEN + '.*?' + TOKEN + ')', 'g'));\n\t\tif (xs.length === 1) {\n\t\t\tacc[acc.length] = xs[0];\n\t\t\treturn acc;\n\t\t}\n\t\txs.filter(Boolean).forEach(function (x) {\n\t\t\tacc[acc.length] = startsWithToken.test(x)\n\t\t\t\t? JSON.parse(x.split(TOKEN)[1])\n\t\t\t\t: x;\n\t\t});\n\t\treturn acc;\n\t}, /** @type {ParseEntry[]} */ ([]));\n};\n","'use strict';\n\nexports.quote = require('./quote');\nexports.parse = require('./parse');\n","import { safeStringify } from \"@zaly/shared\"\nimport { parse as shellParse } from \"shell-quote\"\n\n/** A shell command broken down into its structural parts. One bash\n * input may parse to multiple segments (joined by `|`, `&&`, `||`, `;`).\n * Each segment is evaluated independently by the policy. */\nexport interface Segment {\n cmd: string\n args: string[]\n dyn?: Set<string>\n /** File paths the segment reads from (`< file` redirects). Built-in\n * tools may add inferred reads in the policy layer. */\n reads: string[]\n /** File paths the segment writes to (`> file` / `>> file`). */\n writes: { path: string; mode: \"trunc\" | \"append\" }[]\n /** True if the input contains command substitution (`$()` or backticks)\n * or any other dynamic-evaluation construct. Forces ask. */\n hasCommandSubst: boolean\n}\n\nexport type ParseResult = { ok: true; segments: Segment[] } | { ok: false; reason: string }\n\n/** Targets a redirect can write to without filesystem implications.\n * Anything else is treated as a file write and goes through fileWrite\n * policy. */\nconst SAFE_REDIRECT_TARGETS = new Set([\"/dev/null\", \"/dev/stderr\", \"/dev/stdout\"])\n\n/** A redirect target like `&1`, `&2`, `&-` — duplicates an existing fd,\n * no filesystem effect. */\nfunction isFdRedirect(target: string): boolean {\n return /^&(?:\\d+|-)$/.test(target)\n}\n\ntype Op = { op: string }\ntype Glob = { op: \"glob\"; pattern: string }\ntype Comment = { comment: string }\ntype Token = string | Op | Glob | Comment\n\nconst COMMAND_SEPS = new Set([\"|\", \"&&\", \"||\", \";\"])\nconst REDIRECT_OPS = new Set([\">\", \">>\", \"<\", \">&\", \"<&\"])\nconst DYN_SENTINEL = \"\\u{E000}\"\n\n/** Parse a bash command line. Returns segments with a flag for\n * unsupported constructs that force \"ask\" downstream. Heredocs,\n * subshells, command substitution, and backticks all surface as\n * `hasCommandSubst: true` (the umbrella \"we can't reason about this\"\n * signal) rather than parse failures, so the policy can still decide. */\nexport function parseBash(input: string): ParseResult {\n // Heredocs derail shell-quote (the body bleeds into surrounding tokens),\n // so we bail to ok:false here. checkBash maps that to ask.\n if (/<<-?\\s*['\"]?\\w+/.test(input)) {\n return { ok: false, reason: \"heredoc not supported\" }\n }\n // Backticks command-substitute in bash unless inside single quotes\n // (single quotes preserve everything literally; double quotes don't\n // suppress substitution). Flag only the unquoted form so embedded\n // template literals in `bun -e '... ${x} `tpl` ...'` don't trip us.\n const hasBackticks = hasUnquotedBacktick(input)\n\n let rawTokens: Token[]\n try {\n rawTokens = shellParse(input, (e) =>\n e === \"\" ? undefined : `${DYN_SENTINEL}\\${${e}}`\n ) as Token[]\n } catch (error) {\n return { ok: false, reason: `tokenize: ${(error as Error).message}` }\n }\n\n // Inline plain `(subshell)` contents as separate segments; strip\n // `$(...)` regions and flag as command substitution. Backticks\n // already detected via the pre-scan above.\n const flat = flattenParens(rawTokens)\n const hasCommandSubst = hasBackticks || flat.hasCommandSubst\n\n const segmentTokens: Token[][] = [[]]\n for (const t of flat.tokens) {\n if (typeof t === \"object\" && \"comment\" in t) continue\n\n if (typeof t === \"object\" && \"op\" in t && COMMAND_SEPS.has(t.op)) {\n if (segmentTokens.at(-1)!.length > 0) segmentTokens.push([])\n continue\n }\n\n segmentTokens.at(-1)!.push(t)\n }\n\n if (segmentTokens.at(-1)!.length === 0) segmentTokens.pop()\n\n const segments: Segment[] = []\n for (const segToks of segmentTokens) {\n const seg = parseSegment(segToks)\n if (!seg.ok) return seg\n if (seg.segment) segments.push({ ...seg.segment, hasCommandSubst })\n }\n\n if (segments.length === 0) {\n return { ok: false, reason: \"empty input\" }\n }\n return { ok: true, segments }\n}\n\nfunction parseSegment(\n tokens: Token[]\n):\n | { ok: true; segment: Omit<Segment, \"hasCommandSubst\"> | undefined }\n | { ok: false; reason: string } {\n let args: string[] = []\n let reads: string[] = []\n let writes: { path: string; mode: \"trunc\" | \"append\" }[] = []\n const dyn = new Set<string>()\n\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i]\n\n if (typeof t === \"string\") {\n // FD prefix on a redirect (`2>&1`, `2>file`, `1<&-`) — shell-quote\n // splits the leading digit off as its own token. Don't treat it\n // as a regular arg; the redirect handler below picks up the op.\n if (/^\\d+$/.test(t)) {\n const next = tokens[i + 1]\n if (typeof next === \"object\" && \"op\" in next && REDIRECT_OPS.has(next.op)) {\n continue\n }\n }\n args.push(t)\n continue\n }\n\n if (\"comment\" in t) continue\n\n if (\"pattern\" in t) {\n // Pass globs through as their pattern — policy layer decides.\n args.push(t.pattern)\n dyn.add(t.pattern)\n continue\n }\n\n if (!(\"op\" in t)) {\n return { ok: false, reason: `unsupported token: ${safeStringify(t)}` }\n }\n\n if (REDIRECT_OPS.has(t.op)) {\n const next = tokens[i + 1]\n if (typeof next !== \"string\") {\n return { ok: false, reason: `redirect target missing after ${t.op}` }\n }\n i++ // consume target\n\n if (t.op === \">\" || t.op === \">>\") {\n // Skip safe targets (/dev/null etc.) and fd redirects entirely.\n if (SAFE_REDIRECT_TARGETS.has(next) || isFdRedirect(next)) continue\n writes.push({ mode: t.op === \">>\" ? \"append\" : \"trunc\", path: next })\n } else if (t.op === \"<\") {\n if (SAFE_REDIRECT_TARGETS.has(next) || isFdRedirect(next)) continue\n reads.push(next)\n }\n // `>&` / `<&` are fd-duplicating (`2>&1`-style) — no fs impact.\n continue\n }\n\n return { ok: false, reason: `unsupported op: ${t.op}` }\n }\n\n const dynPath = (p: string) => {\n if (!p.includes(DYN_SENTINEL)) return p\n p = p.replaceAll(DYN_SENTINEL, \"\")\n dyn.add(p)\n return p\n }\n\n args = args.map((a) => dynPath(a))\n writes = writes.map((w) => ({ ...w, path: dynPath(w.path) }))\n reads = reads.map(dynPath)\n\n // Strip leading wrapper commands (`time`, `nohup`, `nice`, …) so the\n // policy sees the real command being run. `time bun test` evaluates\n // as `bun test`; a bare `time` (or `time (subshell)` after flatten)\n // leaves nothing and signals the caller to drop the segment.\n const unwrapped = unwrapWrappers(args)\n if (unwrapped.length === 0) {\n return { ok: true, segment: undefined }\n }\n\n return {\n ok: true,\n segment: {\n args: unwrapped.slice(1),\n cmd: unwrapped[0],\n dyn,\n reads,\n writes,\n },\n }\n}\n\ninterface WrapperSpec {\n /** Flags that consume the next arg as their value. */\n valueFlags?: Set<string>\n}\n\n/** Commands that wrap another command — they're transparent for\n * permission purposes, since the security-relevant action is whatever\n * they run. `sudo` is intentionally absent: it changes the effective\n * user and must always be flagged. */\nconst WRAPPERS: Partial<Record<string, WrapperSpec>> = {\n command: {}, // bash builtin, bypasses aliases\n ionice: { valueFlags: new Set([\"-c\", \"-n\", \"-p\", \"-P\", \"-u\"]) },\n nice: { valueFlags: new Set([\"-n\", \"--adjustment\"]) },\n nohup: {},\n time: {}, // bash reserved word, also GNU /usr/bin/time\n}\n\n/** Detect backticks outside single-quoted regions. Single quotes in\n * bash can't be escaped from within, so the toggle is a simple state\n * flip on every `'`. Double quotes do not suppress backtick\n * substitution and are ignored here. */\nfunction hasUnquotedBacktick(input: string): boolean {\n let inSingle = false\n for (const c of input) {\n if (c === \"'\") {\n inSingle = !inSingle\n continue\n }\n if (c === \"`\" && !inSingle) return true\n }\n return false\n}\n\n/** Strip leading wrapper-command prefixes from an arg list. Repeats\n * while the head is a wrapper (so `time nice -n 5 cmd` → `cmd`).\n * Wrapper-flags (and their values, where applicable) are consumed\n * along with the wrapper itself. */\nfunction unwrapWrappers(args: string[]): string[] {\n let current = args\n while (current.length > 0) {\n const spec = WRAPPERS[current[0]]\n if (!spec) break\n const valueFlags = spec.valueFlags ?? new Set()\n let i = 1\n while (i < current.length && current[i].startsWith(\"-\")) {\n const flag = current[i]\n i++\n if (valueFlags.has(flag) && i < current.length) i++ // consume flag value\n }\n current = current.slice(i)\n }\n return current\n}\n\n/** Walk a token list and resolve paren constructs:\n * - Plain `(subshell)` → tokens inlined with `;` boundaries on each\n * side, so the contents become independent segments evaluated by\n * the same policy. The subshell's own scope (cwd changes etc.) is\n * irrelevant to permissions — each command is checked individually.\n * - `$(...)` (command substitution) → stripped entirely, with the\n * `hasCommandSubst` flag raised. The dynamic value can't be\n * statically reasoned about. Detected by the leading `$` token\n * that shell-quote emits before the `(`.\n *\n * Recurses into subshell contents to handle nesting and to catch\n * `$(...)` constructs nested inside subshells. */\nfunction flattenParens(tokens: Token[]): { tokens: Token[]; hasCommandSubst: boolean } {\n const out: Token[] = []\n let hasCommandSubst = false\n let i = 0\n while (i < tokens.length) {\n const t = tokens[i]\n if (typeof t === \"object\" && \"op\" in t && t.op === \"(\") {\n const isSubst = out.at(-1) === \"$\"\n if (isSubst) out.pop()\n\n // Find matching `)`, accounting for nesting.\n let depth = 1\n let j = i + 1\n while (j < tokens.length && depth > 0) {\n const tj = tokens[j]\n if (typeof tj === \"object\" && \"op\" in tj) {\n if (tj.op === \"(\") depth++\n else if (tj.op === \")\") depth--\n }\n if (depth > 0) j++\n }\n const inner = tokens.slice(i + 1, j)\n\n if (isSubst) {\n hasCommandSubst = true\n // Drop the entire $(...) — its value is dynamic.\n } else {\n const sub = flattenParens(inner)\n if (sub.hasCommandSubst) hasCommandSubst = true\n // Surround with separators so subshell contents form their own\n // segments regardless of what's adjacent in the outer chain.\n out.push({ op: \";\" }, ...sub.tokens, { op: \";\" })\n }\n i = j + 1\n continue\n }\n\n if (typeof t === \"object\" && \"op\" in t && t.op === \")\") {\n // Stray closing paren (unbalanced input). Skip — the parser's\n // overall result will likely fail downstream on a malformed segment.\n i++\n continue\n }\n\n out.push(t)\n i++\n }\n return { hasCommandSubst, tokens: out }\n}\n","/**\n * Built-in tool registry — per-command knowledge of which args are\n * input files, output files, and which invocation modes are too\n * complex to safely model.\n *\n * The policy engine consults this registry alongside explicit redirect\n * info from the parser to determine per-command file I/O for the\n * fileRead/fileWrite policy hooks.\n */\nexport interface ToolSpec {\n /** File paths the command will read from, derived from args. */\n reads?: (args: string[]) => string[]\n /** File paths the command will write to. */\n writes?: (args: string[]) => string[]\n /** Returns true if the args invoke a mode the parser can't safely\n * reason about (e.g. `sed -e 'w out'`, `find -exec`). Forces ask. */\n unsafe?: (args: string[]) => boolean\n}\n\n/** All bare positional args (no leading dash). Default for many\n * read-only utilities. */\nfunction positionals(args: string[]): string[] {\n return args.filter((a) => !a.startsWith(\"-\") && a !== \"\")\n}\n\n/** All positionals after the first one (e.g. `grep PATTERN file...`). */\nfunction positionalsAfterFirst(args: string[]): string[] {\n const out: string[] = []\n let seenFirst = false\n for (const a of args) {\n if (a.startsWith(\"-\") || a === \"\") continue\n if (!seenFirst) {\n seenFirst = true\n continue\n }\n out.push(a)\n }\n return out\n}\n\n// ── sed ──────────────────────────────────────────────────────────────────\n\n/** Flags whose value is the *next* arg, not part of the script. */\nconst SED_VALUE_FLAGS = new Set([\"-e\", \"--expression\", \"-f\", \"--file\"])\n\n/** Walk sed args, returning [scripts, positionalsAfterScript]. The\n * \"script\" is everything passed via `-e` plus the first bare arg\n * (the implicit script when no `-e` is given). Positionals after\n * that are input files. */\nfunction sedSplit(args: string[]): { scripts: string[]; files: string[] } {\n const scripts: string[] = []\n const files: string[] = []\n let needsImplicitScript = !args.some(\n (a) => a === \"-e\" || a === \"--expression\" || a === \"-f\" || a === \"--file\"\n )\n\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a.startsWith(\"-\")) {\n if (SED_VALUE_FLAGS.has(a) && i + 1 < args.length) {\n if (a === \"-e\" || a === \"--expression\") scripts.push(args[i + 1])\n i++ // consume value\n }\n continue\n }\n if (needsImplicitScript) {\n scripts.push(a)\n needsImplicitScript = false\n continue\n }\n files.push(a)\n }\n return { files, scripts }\n}\n\nconst SED_INPLACE = new Set([\"-i\", \"--in-place\"])\n\nfunction sedReads(args: string[]): string[] {\n return sedSplit(args).files\n}\n\nfunction sedWrites(args: string[]): string[] {\n // `-i` rewrites positional input files; also supports `-i.bak` form.\n const inPlace = args.some((a) => SED_INPLACE.has(a) || a.startsWith(\"-i.\"))\n return inPlace ? sedSplit(args).files : []\n}\n\nfunction sedUnsafe(args: string[]): boolean {\n // `w` / `W` write commands and `r` / `R` read commands inside the\n // script can do file I/O the parser can't see. Bail to ask.\n for (const script of sedSplit(args).scripts) {\n if (/(?:^|;|\\n)\\s*[wWrR]\\s+\\S/.test(script)) return true\n }\n return false\n}\n\n// ── awk ──────────────────────────────────────────────────────────────────\n\nfunction awkReads(args: string[]): string[] {\n // awk usage: `awk [opts] 'script' [files...]` or `awk [opts] -f file [files...]`\n // Files come after the script. Skip flags + their values.\n let sawScript = false\n let usingFFlag = false\n const files: string[] = []\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a === \"-f\" || a === \"--file\") {\n if (i + 1 < args.length) files.push(args[i + 1]) // script file is read too\n i++\n sawScript = true\n usingFFlag = true\n continue\n }\n if (a.startsWith(\"-\")) {\n // Some awk flags take a value (-v, -F)\n if (a === \"-v\" || a === \"-F\") i++\n continue\n }\n if (!sawScript) {\n sawScript = true\n continue\n }\n files.push(a)\n }\n return usingFFlag ? files : files\n}\n\nfunction awkUnsafe(args: string[]): boolean {\n // awk's `print > file` and `printf > file` inside a script write to\n // files. Detecting reliably without parsing the script is hard, so\n // bail to ask if the script (or any -e value) contains a `>` operator.\n // Conservative — false positives are fine for \"ask\".\n let sawScript = false\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a === \"-f\" || a === \"--file\" || a === \"-v\" || a === \"-F\") {\n i++\n continue\n }\n if (a.startsWith(\"-\")) continue\n if (!sawScript) {\n sawScript = true\n if (/[>|]/.test(a)) return true\n }\n }\n return false\n}\n\n// ── find ─────────────────────────────────────────────────────────────────\n\nfunction findReads(args: string[]): string[] {\n // First positional (or `.`) is the path. Multiple paths possible\n // before the first `-action` flag.\n const out: string[] = []\n for (const a of args) {\n if (a.startsWith(\"-\")) break\n out.push(a)\n }\n return out.length > 0 ? out : [\".\"]\n}\n\nfunction findUnsafe(args: string[]): boolean {\n // `-delete`, `-exec`, `-execdir`, `-ok`, `-okdir` all do work we\n // can't trace.\n return args.some(\n (a) => a === \"-delete\" || a === \"-exec\" || a === \"-execdir\" || a === \"-ok\" || a === \"-okdir\"\n )\n}\n\n// ── dynamic execution ────────────────────────────────────────────────────\n//\n// These commands run arbitrary code passed as arguments or sourced from\n// files. We can't reason about their effects from the parser; force ask.\n\nconst dynamicExec = (): boolean => true\n\n// ── registry ─────────────────────────────────────────────────────────────\n\nexport const TOOLS: Partial<Record<string, ToolSpec>> = {\n \".\": { unsafe: dynamicExec }, // sh: source alias\n awk: { reads: awkReads, unsafe: awkUnsafe },\n basename: {},\n cat: { reads: positionals },\n cd: {},\n cut: { reads: positionals },\n diff: { reads: positionals },\n dirname: {},\n echo: {},\n eval: { unsafe: dynamicExec }, // runs its argument as shell input\n exec: { unsafe: dynamicExec }, // replaces the shell process\n file: { reads: positionals },\n find: { reads: findReads, unsafe: findUnsafe },\n grep: { reads: positionalsAfterFirst },\n head: { reads: positionals },\n hexdump: { reads: positionals },\n less: { reads: positionals },\n ls: { reads: positionals },\n more: { reads: positionals },\n od: { reads: positionals },\n printf: {},\n pwd: {},\n readlink: { reads: positionals },\n realpath: { reads: positionals },\n rg: { reads: positionalsAfterFirst },\n sed: { reads: sedReads, unsafe: sedUnsafe, writes: sedWrites },\n sort: { reads: positionals },\n source: { unsafe: dynamicExec }, // bash: runs the file in current shell\n stat: { reads: positionals },\n tail: { reads: positionals },\n tree: { reads: positionals },\n uniq: { reads: positionals },\n wc: { reads: positionals },\n xxd: { reads: positionals },\n}\n"],"ignoreList":[0,1,2],"mappings":"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"}
1
+ {"version":3,"file":"tools-DmoUYORG.mjs","names":["shellParse"],"sources":["../../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/quote.js","../../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/parse.js","../../../node_modules/.bun/shell-quote@1.12.0/node_modules/shell-quote/index.js","../src/utils/bash/parser.ts","../src/utils/bash/tools.ts"],"sourcesContent":["'use strict';\n\n/** @import { ControlOperator } from './parse' */\n\n/** @type {ControlOperator['op'][]} */\nvar OPS = /** @type {const} */ ([\n\t'||',\n\t'&&',\n\t';;&',\n\t';;',\n\t';&',\n\t'|&',\n\t'<(',\n\t'>(',\n\t'<<<',\n\t'<<-',\n\t'<<',\n\t'>>',\n\t'>&',\n\t'>|',\n\t'&>>',\n\t'&>',\n\t'<&',\n\t'<>',\n\t'&',\n\t';',\n\t'(',\n\t')',\n\t'|',\n\t'<',\n\t'>'\n]);\nvar LINE_TERMINATORS = /[\\n\\r\\u2028\\u2029]/;\nvar GLOB_SHELL_SPECIAL = /[\\s#!\"$&'():;<=>@\\\\^`|~]/g;\n\n/** @type {typeof import('./quote')} */\nmodule.exports = function quote(xs) {\n\tvar sawComment = false;\n\treturn xs.map(function (s) {\n\t\tif (sawComment && typeof s === 'string' && LINE_TERMINATORS.test(s)) {\n\t\t\tthrow new TypeError('a token after a `comment` must not contain line terminators');\n\t\t}\n\t\tif (s === '') {\n\t\t\treturn /** @type {const} */ ('\\'\\'');\n\t\t}\n\t\tif (s && typeof s === 'object') {\n\t\t\tif ('op' in s && s.op === 'glob') {\n\t\t\t\tif (typeof s.pattern !== 'string') {\n\t\t\t\t\tthrow new TypeError('glob token requires a string `pattern`');\n\t\t\t\t}\n\t\t\t\tif (LINE_TERMINATORS.test(s.pattern)) {\n\t\t\t\t\tthrow new TypeError('glob `pattern` must not contain line terminators');\n\t\t\t\t}\n\t\t\t\tif (s.pattern === '') {\n\t\t\t\t\treturn /** @type {const} */ ('\\'\\'');\n\t\t\t\t}\n\t\t\t\treturn s.pattern.replace(GLOB_SHELL_SPECIAL, '\\\\$&');\n\t\t\t}\n\t\t\tif ('op' in s && typeof s.op === 'string') {\n\t\t\t\tif (OPS.indexOf(s.op) < 0) {\n\t\t\t\t\tthrow new TypeError('invalid `op` value: ' + JSON.stringify(s.op));\n\t\t\t\t}\n\t\t\t\treturn s.op.replace(/[\\s\\S]/g, '\\\\$&');\n\t\t\t}\n\t\t\tif ('comment' in s && typeof s.comment === 'string') {\n\t\t\t\tif (LINE_TERMINATORS.test(s.comment)) {\n\t\t\t\t\tthrow new TypeError('`comment` must not contain line terminators');\n\t\t\t\t}\n\t\t\t\tsawComment = true;\n\t\t\t\treturn '#' + s.comment;\n\t\t\t}\n\t\t\tthrow new TypeError('unrecognized object token shape');\n\t\t}\n\t\tif ((/'/).test(s) && (/!/).test(s)) {\n\t\t\treturn \"'\" + s.replace(/'/g, \"'\\\"'\\\"'\") + \"'\";\n\t\t}\n\t\tif ((/[\"\\s\\\\]/).test(s) && !(/'/).test(s)) {\n\t\t\treturn \"'\" + s + \"'\";\n\t\t}\n\t\tif ((/[\"'\\s]/).test(s)) {\n\t\t\treturn '\"' + s.replace(/([\"\\\\$`])/g, '\\\\$1') + '\"';\n\t\t}\n\t\treturn String(s).replace(/([A-Za-z]:)?([#!\"$&'()*,:;<=>?@[\\\\\\]^`{|}~])/g, '$1\\\\$2');\n\t}).join(' ');\n};\n","'use strict';\n\n/**\n * @import {\n * \tControlOperator,\n * \tEnv,\n * \tGlobPattern,\n * \tParseEntry,\n * } from './parse' */\n\n// '<(' and '>(' are process substitution operators and\n// can be parsed the same as control operator\nvar CONTROL = /** @type {const} */ ('(?:') + /** @type {const} */ ([\n\t'\\\\|\\\\|',\n\t'\\\\&(?:\\\\&|>>?)', // `&&`, `&>`, and `&>>`\n\t';;\\\\&?', // `;;` and `;;&`\n\t'[;|]\\\\&', // `;&` and `|&`\n\t'\\\\<\\\\(',\n\t'\\\\<\\\\<\\\\<',\n\t'\\\\<\\\\<-',\n\t'\\\\<\\\\<(?!\\\\()', // `<<(` stays `<` and `<(`, as zsh reads it; other shells reject it\n\t'>>',\n\t'>[&|(]', // `>&`, `>|`, and `>(`\n\t'<[&>]', // `<&` and `<>`\n\t'[&;()|<>]'\n]).join(/** @type {const} */ ('|')) + /** @type {const} */ (')');\nvar controlRE = new RegExp('^' + CONTROL + '$');\nvar META = /** @type {const} */ ('|&;()<> \\\\t');\nvar SINGLE_QUOTE = /** @type {const} */ ('\\'([^\\']*?)\\'');\n// bash ANSI-C quoting, `$'...'`: a backslash escapes the next character, including `'`\nvar ANSI_C_BODY = '(?:\\\\\\\\[\\\\s\\\\S]|[^\\\\\\\\\\'])*?';\nvar ANSI_C_QUOTE = '\\\\$\\'' + ANSI_C_BODY + '\\'';\nvar ansiCAt = new RegExp('\\\\$\\'' + ANSI_C_BODY + '(?:(\\')|\\\\\\\\?$)', 'g');\nvar ANSI_C_LETTERS = 'abeEfnrtv';\nvar ANSI_C_CHARS = '\\x07\\b\\x1B\\x1B\\f\\n\\r\\t\\v';\nvar hash = /^#$/;\n\nvar SQ = /** @type {const} */ (\"'\");\nvar DQ = /** @type {const} */ ('\"');\nvar DS = /** @type {const} */ ('$');\n\nvar TOKEN = '';\nvar mult = /** @type {const} */ (0x100000000); // Math.pow(16, 8);\nfor (var i = 0; i < 4; i++) {\n\tTOKEN += (mult * Math.random()).toString(16);\n}\nvar startsWithToken = new RegExp('^' + TOKEN);\n\n/**\n * @param {string} s\n * @param {RegExp} r\n */\nfunction matchAll(s, r) {\n\tvar origIndex = r.lastIndex;\n\n\tvar matches = [];\n\tvar matchObj;\n\n\twhile ((matchObj = r.exec(s))) {\n\t\tmatches[matches.length] = matchObj;\n\t\tif (r.lastIndex === matchObj.index) {\n\t\t\tr.lastIndex += 1;\n\t\t}\n\t}\n\n\tr.lastIndex = origIndex;\n\n\treturn matches;\n}\n\n/**\n * @param {Env} env\n * @param {string} pre\n * @param {string} key\n */\nfunction getVar(env, pre, key) {\n\tvar r = typeof env === 'function' ? env(key) : env[key];\n\tif (typeof r === 'undefined' && key != '') {\n\t\tr = '';\n\t} else if (typeof r === 'undefined') {\n\t\tr = '$';\n\t}\n\n\tif (typeof r === 'object') {\n\t\treturn pre + TOKEN + JSON.stringify(r) + TOKEN;\n\t}\n\treturn pre + r;\n}\n\nvar ansiCEscape = /\\\\([0-7]{1,3}|x[\\dA-Fa-f]{1,2}|u[\\dA-Fa-f]{1,4}|U[\\dA-Fa-f]{1,8}|c(?:\\\\\\\\|[\\s\\S])|[abeEfnrtv\\\\'\"?])/g;\n\n/**\n * @param {string} m\n * @param {string} escape\n */\nfunction expandAnsiCEscape(m, escape) {\n\tvar kind = escape.charAt(0);\n\tif (kind === 'c') {\n\t\tvar ctrl = escape.charAt(1);\n\t\treturn ctrl === '?' ? '\\x7F' : String.fromCharCode(ctrl.charCodeAt(0) & 0x1F);\n\t}\n\tif (kind === 'x' || kind === 'u' || kind === 'U') {\n\t\tvar cp = parseInt(escape.slice(1), 16);\n\t\tif (cp > 0x10FFFF) {\n\t\t\treturn m;\n\t\t}\n\t\treturn String.fromCharCode.apply(null, cp > 0xFFFF ? [0xD7C0 + (cp >> 10), 0xDC00 + (cp & 0x3FF)] : [cp]);\n\t}\n\tif (kind >= '0' && kind <= '7') {\n\t\treturn String.fromCharCode(parseInt(escape, 8) & 0xFF);\n\t}\n\tvar letter = ANSI_C_LETTERS.indexOf(escape);\n\treturn letter < 0 ? escape : ANSI_C_CHARS.charAt(letter);\n}\n\n/** @param {string} body */\nfunction expandAnsiC(body) {\n\treturn body.replace(ansiCEscape, expandAnsiCEscape).split('\\0')[0]; // like bash, a NUL ends the string\n}\n\n/**\n * @param {string} s\n * @param {number} i\n */\nfunction closesAnsiC(s, i) {\n\tansiCAt.lastIndex = i;\n\treturn !!(/** @type {RegExpExecArray} */ (ansiCAt.exec(s)))[1];\n}\n\n/**\n * @param {string} string\n * @param {Env} [env]\n * @param {{ escape?: string, splitUnquoted?: boolean | string }} [opts]\n * @returns {ParseEntry[]}\n */\nfunction parseInternal(string, env, opts) {\n\tif (!opts) {\n\t\topts = {};\n\t}\n\tvar BS = opts.escape || '\\\\';\n\tvar ifs = opts.splitUnquoted === true ? ' \\t\\n' : (typeof opts.splitUnquoted === 'string' ? opts.splitUnquoted : '');\n\tvar BAREWORD = '(\\\\' + BS + '[\\'\"$\\\\' + BS + META + ']|\\\\$\\\\$|\\\\$(?!' + ANSI_C_QUOTE.slice(2) + ')|[^\\\\s\\'\"$' + META + '])+';\n\tvar DOUBLE_QUOTE = '\"(?:\\\\' + BS + '[\\\\s\\\\S]|[^\"\\\\' + BS + '])*\"';\n\n\tvar chunker = new RegExp([\n\t\t'(' + CONTROL + ')', // control chars\n\t\t'(' + ANSI_C_QUOTE + '|' + BAREWORD + '|' + DOUBLE_QUOTE + '|' + SINGLE_QUOTE + ')+'\n\t].join('|'), 'g');\n\n\tvar matches = matchAll(string, chunker);\n\n\tif (matches.length === 0) {\n\t\treturn [];\n\t}\n\tif (!env) {\n\t\tenv = {};\n\t}\n\n\tvar commented = false;\n\n\treturn matches.map(function (match) {\n\t\tvar s = match[0];\n\t\tif (!s || commented) {\n\t\t\treturn void undefined;\n\t\t}\n\t\tif (controlRE.test(s)) {\n\t\t\treturn /** @type {ControlOperator} */ ({ op: s });\n\t\t}\n\n\t\t// Hand-written scanner/parser for Bash quoting rules:\n\t\t//\n\t\t// 1. inside single quotes, all characters are printed literally.\n\t\t// 2. inside double quotes, all characters are printed literally\n\t\t// except variables prefixed by '$' and backslashes followed by\n\t\t// either a double quote or another backslash.\n\t\t// 3. outside of any quotes, backslashes are treated as escape\n\t\t// characters and not printed (unless they are themselves escaped)\n\t\t// 4. quote context can switch mid-token if there is no whitespace\n\t\t// between the two quote contexts (e.g. all'one'\"token\" parses as\n\t\t// \"allonetoken\")\n\t\t/** @type {string | boolean} */\n\t\tvar quote = false;\n\t\tvar esc = false;\n\t\tvar out = '';\n\t\t/** @type {string[]} */\n\t\tvar words = [];\n\t\tvar sawQuote = false;\n\t\t/** @type {number | null} */\n\t\tvar pendingNw = null;\n\t\tvar isGlob = false;\n\t\t/** @type {number} */\n\t\tvar i;\n\n\t\tfunction parseEnvVar() {\n\t\t\ti += 1;\n\t\t\t/** @type {number | RegExpMatchArray | null} */\n\t\t\tvar varend;\n\t\t\t/** @type {string} */\n\t\t\tvar varname;\n\t\t\tvar char = s.charAt(i);\n\n\t\t\tif (char === '{') {\n\t\t\t\ti += 1;\n\t\t\t\tif (s.charAt(i) === '}') {\n\t\t\t\t\tthrow new Error('Bad substitution: ' + s.slice(i - 2, i + 1));\n\t\t\t\t}\n\t\t\t\t// match braces by depth so a nested `${` keeps its inner `}` from ending the outer substitution\n\t\t\t\tvar depth = 1;\n\t\t\t\tvarend = i;\n\t\t\t\twhile (depth > 0 && varend < s.length) {\n\t\t\t\t\tif (s.charAt(varend) === '{' && s.charAt(varend - 1) === '$') {\n\t\t\t\t\t\tdepth += 1;\n\t\t\t\t\t} else if (s.charAt(varend) === '}') {\n\t\t\t\t\t\tdepth -= 1;\n\t\t\t\t\t}\n\t\t\t\t\tvarend += 1;\n\t\t\t\t}\n\t\t\t\tif (depth !== 0) {\n\t\t\t\t\tthrow new Error('Bad substitution: ' + s.slice(i));\n\t\t\t\t}\n\t\t\t\tvarend -= 1;\n\t\t\t\tvarname = s.slice(i, varend);\n\t\t\t\ti = varend;\n\t\t\t} else if ((/[*@#?$!-]/).test(char)) {\n\t\t\t\tvarname = char;\n\t\t\t} else {\n\t\t\t\tvar slicedFromI = s.slice(i);\n\t\t\t\tvarend = slicedFromI.match(/[^\\w\\d_]/);\n\t\t\t\tif (!varend) {\n\t\t\t\t\tvarname = slicedFromI;\n\t\t\t\t\ti = s.length;\n\t\t\t\t} else {\n\t\t\t\t\tvarname = slicedFromI.slice(0, varend.index);\n\t\t\t\t\ti += /** @type {number} */ (varend.index) - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn getVar(/** @type {NonNullable<typeof env>} */ (env), '', varname);\n\t\t}\n\n\t\tfunction flushRun() {\n\t\t\tif (pendingNw === null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (pendingNw === 0) {\n\t\t\t\tif (out !== '') {\n\t\t\t\t\twords[words.length] = out;\n\t\t\t\t\tout = '';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twords[words.length] = out;\n\t\t\t\tout = '';\n\t\t\t\tfor (var fe = 1; fe < pendingNw; fe += 1) {\n\t\t\t\t\twords[words.length] = '';\n\t\t\t\t}\n\t\t\t}\n\t\t\tpendingNw = null;\n\t\t}\n\n\t\tfor (i = 0; i < s.length; i++) {\n\t\t\tvar c = s.charAt(i);\n\t\t\tif (ifs && c !== DS) {\n\t\t\t\tflushRun();\n\t\t\t}\n\t\t\tisGlob = isGlob || (!quote && (c === '*' || c === '?'));\n\t\t\tif (esc) {\n\t\t\t\tout += c;\n\t\t\t\tesc = false;\n\t\t\t} else if (quote) {\n\t\t\t\tif (c === quote) {\n\t\t\t\t\tquote = false;\n\t\t\t\t} else if (quote == SQ) {\n\t\t\t\t\tout += c;\n\t\t\t\t} else { // Double quote\n\t\t\t\t\tif (c === BS) {\n\t\t\t\t\t\ti += 1;\n\t\t\t\t\t\tc = s.charAt(i);\n\t\t\t\t\t\tif (c === DQ || c === BS || c === DS) {\n\t\t\t\t\t\t\tout += c;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tout += BS + c;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (c === DS) {\n\t\t\t\t\t\tout += parseEnvVar();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tout += c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (c === DQ || c === SQ) {\n\t\t\t\tquote = c;\n\t\t\t\tsawQuote = true;\n\t\t\t} else if (controlRE.test(c)) {\n\t\t\t\treturn /** @type {ControlOperator} */ ({ op: s });\n\t\t\t} else if (hash.test(c)) {\n\t\t\t\tcommented = true;\n\t\t\t\tvar commentObj = { comment: string.slice(match.index + i + 1) };\n\t\t\t\tif (out.length) {\n\t\t\t\t\treturn /** @type {const} */ ([out, commentObj]);\n\t\t\t\t}\n\t\t\t\treturn /** @type {const} */ ([commentObj]);\n\t\t\t} else if (c === BS) {\n\t\t\t\tesc = true;\n\t\t\t} else if (c === DS && s.charAt(i + 1) === SQ && closesAnsiC(s, i)) {\n\t\t\t\tflushRun();\n\t\t\t\tsawQuote = true;\n\t\t\t\tout += expandAnsiC(s.slice(i + 2, ansiCAt.lastIndex - 1));\n\t\t\t\ti = ansiCAt.lastIndex - 1;\n\t\t\t} else if (c === DS) {\n\t\t\t\tvar value = parseEnvVar();\n\t\t\t\tif (!ifs) {\n\t\t\t\t\tout += value;\n\t\t\t\t} else {\n\t\t\t\t\tfor (var vi = 0; vi < value.length; vi += 1) {\n\t\t\t\t\t\tvar vc = value.charAt(vi);\n\t\t\t\t\t\tif (ifs.indexOf(vc) < 0) {\n\t\t\t\t\t\t\tflushRun();\n\t\t\t\t\t\t\tout += vc;\n\t\t\t\t\t\t} else if (pendingNw === null) {\n\t\t\t\t\t\t\tpendingNw = vc === ' ' || vc === '\\t' || vc === '\\n' ? 0 : 1;\n\t\t\t\t\t\t} else if (vc !== ' ' && vc !== '\\t' && vc !== '\\n') {\n\t\t\t\t\t\t\tpendingNw += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tout += c;\n\t\t\t}\n\t\t}\n\n\t\tif (isGlob) {\n\t\t\treturn /** @type {GlobPattern} */ ({ op: 'glob', pattern: out });\n\t\t}\n\n\t\tif (ifs) {\n\t\t\tif (pendingNw !== null && pendingNw > 0) {\n\t\t\t\twords[words.length] = out;\n\t\t\t\tout = '';\n\t\t\t\tfor (var te = 1; te < pendingNw; te += 1) {\n\t\t\t\t\twords[words.length] = '';\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (out !== '' || (sawQuote && words.length === 0)) {\n\t\t\t\twords[words.length] = out;\n\t\t\t}\n\t\t\treturn words;\n\t\t}\n\n\t\treturn out;\n\t}).reduce(function (prev, arg) { // finalize parsed arguments\n\t\tif (typeof arg === 'undefined') {\n\t\t\treturn prev;\n\t\t}\n\t\t/** @type {ParseEntry[]} */ ([]).concat(arg).forEach(function (entry) {\n\t\t\tprev[prev.length] = entry;\n\t\t});\n\t\treturn prev;\n\t}, /** @type {ParseEntry[]} */ ([]));\n}\n\n/** @type {typeof import('./parse')} */\nmodule.exports = function parse(s, env, opts) {\n\tvar mapped = parseInternal(s, env, opts);\n\tif (typeof env !== 'function') {\n\t\treturn mapped;\n\t}\n\treturn mapped.reduce(function (acc, s) {\n\t\tif (typeof s === 'object') {\n\t\t\tacc[acc.length] = s;\n\t\t\treturn acc;\n\t\t}\n\t\tvar xs = s.split(RegExp('(' + TOKEN + '.*?' + TOKEN + ')', 'g'));\n\t\tif (xs.length === 1) {\n\t\t\tacc[acc.length] = xs[0];\n\t\t\treturn acc;\n\t\t}\n\t\txs.filter(Boolean).forEach(function (x) {\n\t\t\tacc[acc.length] = startsWithToken.test(x)\n\t\t\t\t? JSON.parse(x.split(TOKEN)[1])\n\t\t\t\t: x;\n\t\t});\n\t\treturn acc;\n\t}, /** @type {ParseEntry[]} */ ([]));\n};\n","'use strict';\n\nexports.quote = require('./quote');\nexports.parse = require('./parse');\n","import { safeStringify } from \"@zaly/shared\"\nimport { parse as shellParse } from \"shell-quote\"\n\n/** A shell command broken down into its structural parts. One bash\n * input may parse to multiple segments (joined by `|`, `&&`, `||`, `;`).\n * Each segment is evaluated independently by the policy. */\nexport interface Segment {\n cmd: string\n args: string[]\n dyn?: Set<string>\n /** File paths the segment reads from (`< file` redirects). Built-in\n * tools may add inferred reads in the policy layer. */\n reads: string[]\n /** File paths the segment writes to (`> file` / `>> file`). */\n writes: { path: string; mode: \"trunc\" | \"append\" }[]\n /** True if the input contains command substitution (`$()` or backticks)\n * or any other dynamic-evaluation construct. Forces ask. */\n hasCommandSubst: boolean\n}\n\nexport type ParseResult = { ok: true; segments: Segment[] } | { ok: false; reason: string }\n\n/** Targets a redirect can write to without filesystem implications.\n * Anything else is treated as a file write and goes through fileWrite\n * policy. */\nconst SAFE_REDIRECT_TARGETS = new Set([\"/dev/null\", \"/dev/stderr\", \"/dev/stdout\"])\n\n/** A redirect target like `&1`, `&2`, `&-` — duplicates an existing fd,\n * no filesystem effect. */\nfunction isFdRedirect(target: string): boolean {\n return /^&(?:\\d+|-)$/.test(target)\n}\n\ntype Op = { op: string }\ntype Glob = { op: \"glob\"; pattern: string }\ntype Comment = { comment: string }\ntype Token = string | Op | Glob | Comment\n\nconst COMMAND_SEPS = new Set([\"|\", \"&&\", \"||\", \";\"])\nconst REDIRECT_OPS = new Set([\">\", \">>\", \"<\", \">&\", \"<&\"])\nconst DYN_SENTINEL = \"\\u{E000}\"\n\n/** Parse a bash command line. Returns segments with a flag for\n * unsupported constructs that force \"ask\" downstream. Heredocs,\n * subshells, command substitution, and backticks all surface as\n * `hasCommandSubst: true` (the umbrella \"we can't reason about this\"\n * signal) rather than parse failures, so the policy can still decide. */\nexport function parseBash(input: string): ParseResult {\n // Heredocs derail shell-quote (the body bleeds into surrounding tokens),\n // so we bail to ok:false here. checkBash maps that to ask.\n if (/<<-?\\s*['\"]?\\w+/.test(input)) {\n return { ok: false, reason: \"heredoc not supported\" }\n }\n // Backticks command-substitute in bash unless inside single quotes\n // (single quotes preserve everything literally; double quotes don't\n // suppress substitution). Flag only the unquoted form so embedded\n // template literals in `bun -e '... ${x} `tpl` ...'` don't trip us.\n const hasBackticks = hasUnquotedBacktick(input)\n\n let rawTokens: Token[]\n try {\n rawTokens = shellParse(input, (e) =>\n e === \"\" ? undefined : `${DYN_SENTINEL}\\${${e}}`\n ) as Token[]\n } catch (error) {\n return { ok: false, reason: `tokenize: ${(error as Error).message}` }\n }\n\n // Inline plain `(subshell)` contents as separate segments; strip\n // `$(...)` regions and flag as command substitution. Backticks\n // already detected via the pre-scan above.\n const flat = flattenParens(rawTokens)\n const hasCommandSubst = hasBackticks || flat.hasCommandSubst\n\n const segmentTokens: Token[][] = [[]]\n for (const t of flat.tokens) {\n if (typeof t === \"object\" && \"comment\" in t) continue\n\n if (typeof t === \"object\" && \"op\" in t && COMMAND_SEPS.has(t.op)) {\n if (segmentTokens.at(-1)!.length > 0) segmentTokens.push([])\n continue\n }\n\n segmentTokens.at(-1)!.push(t)\n }\n\n if (segmentTokens.at(-1)!.length === 0) segmentTokens.pop()\n\n const segments: Segment[] = []\n for (const segToks of segmentTokens) {\n const seg = parseSegment(segToks)\n if (!seg.ok) return seg\n if (seg.segment) segments.push({ ...seg.segment, hasCommandSubst })\n }\n\n if (segments.length === 0) {\n return { ok: false, reason: \"empty input\" }\n }\n return { ok: true, segments }\n}\n\nfunction parseSegment(\n tokens: Token[]\n):\n | { ok: true; segment: Omit<Segment, \"hasCommandSubst\"> | undefined }\n | { ok: false; reason: string } {\n let args: string[] = []\n let reads: string[] = []\n let writes: { path: string; mode: \"trunc\" | \"append\" }[] = []\n const dyn = new Set<string>()\n\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i]\n\n if (typeof t === \"string\") {\n // FD prefix on a redirect (`2>&1`, `2>file`, `1<&-`) — shell-quote\n // splits the leading digit off as its own token. Don't treat it\n // as a regular arg; the redirect handler below picks up the op.\n if (/^\\d+$/.test(t)) {\n const next = tokens[i + 1]\n if (typeof next === \"object\" && \"op\" in next && REDIRECT_OPS.has(next.op)) {\n continue\n }\n }\n args.push(t)\n continue\n }\n\n if (\"comment\" in t) continue\n\n if (\"pattern\" in t) {\n // Pass globs through as their pattern — policy layer decides.\n args.push(t.pattern)\n dyn.add(t.pattern)\n continue\n }\n\n if (!(\"op\" in t)) {\n return { ok: false, reason: `unsupported token: ${safeStringify(t)}` }\n }\n\n if (REDIRECT_OPS.has(t.op)) {\n const next = tokens[i + 1]\n if (typeof next !== \"string\") {\n return { ok: false, reason: `redirect target missing after ${t.op}` }\n }\n i++ // consume target\n\n if (t.op === \">\" || t.op === \">>\") {\n // Skip safe targets (/dev/null etc.) and fd redirects entirely.\n if (SAFE_REDIRECT_TARGETS.has(next) || isFdRedirect(next)) continue\n writes.push({ mode: t.op === \">>\" ? \"append\" : \"trunc\", path: next })\n } else if (t.op === \"<\") {\n if (SAFE_REDIRECT_TARGETS.has(next) || isFdRedirect(next)) continue\n reads.push(next)\n }\n // `>&` / `<&` are fd-duplicating (`2>&1`-style) — no fs impact.\n continue\n }\n\n return { ok: false, reason: `unsupported op: ${t.op}` }\n }\n\n const dynPath = (p: string) => {\n if (!p.includes(DYN_SENTINEL)) return p\n p = p.replaceAll(DYN_SENTINEL, \"\")\n dyn.add(p)\n return p\n }\n\n args = args.map((a) => dynPath(a))\n writes = writes.map((w) => ({ ...w, path: dynPath(w.path) }))\n reads = reads.map(dynPath)\n\n // Strip leading wrapper commands (`time`, `nohup`, `nice`, …) so the\n // policy sees the real command being run. `time bun test` evaluates\n // as `bun test`; a bare `time` (or `time (subshell)` after flatten)\n // leaves nothing and signals the caller to drop the segment.\n const unwrapped = unwrapWrappers(args)\n if (unwrapped.length === 0) {\n return { ok: true, segment: undefined }\n }\n\n return {\n ok: true,\n segment: {\n args: unwrapped.slice(1),\n cmd: unwrapped[0],\n dyn,\n reads,\n writes,\n },\n }\n}\n\ninterface WrapperSpec {\n /** Flags that consume the next arg as their value. */\n valueFlags?: Set<string>\n}\n\n/** Commands that wrap another command — they're transparent for\n * permission purposes, since the security-relevant action is whatever\n * they run. `sudo` is intentionally absent: it changes the effective\n * user and must always be flagged. */\nconst WRAPPERS: Partial<Record<string, WrapperSpec>> = {\n command: {}, // bash builtin, bypasses aliases\n ionice: { valueFlags: new Set([\"-c\", \"-n\", \"-p\", \"-P\", \"-u\"]) },\n nice: { valueFlags: new Set([\"-n\", \"--adjustment\"]) },\n nohup: {},\n time: {}, // bash reserved word, also GNU /usr/bin/time\n}\n\n/** Detect backticks outside single-quoted regions. Single quotes in\n * bash can't be escaped from within, so the toggle is a simple state\n * flip on every `'`. Double quotes do not suppress backtick\n * substitution and are ignored here. */\nfunction hasUnquotedBacktick(input: string): boolean {\n let inSingle = false\n for (const c of input) {\n if (c === \"'\") {\n inSingle = !inSingle\n continue\n }\n if (c === \"`\" && !inSingle) return true\n }\n return false\n}\n\n/** Strip leading wrapper-command prefixes from an arg list. Repeats\n * while the head is a wrapper (so `time nice -n 5 cmd` → `cmd`).\n * Wrapper-flags (and their values, where applicable) are consumed\n * along with the wrapper itself. */\nfunction unwrapWrappers(args: string[]): string[] {\n let current = args\n while (current.length > 0) {\n const spec = WRAPPERS[current[0]]\n if (!spec) break\n const valueFlags = spec.valueFlags ?? new Set()\n let i = 1\n while (i < current.length && current[i].startsWith(\"-\")) {\n const flag = current[i]\n i++\n if (valueFlags.has(flag) && i < current.length) i++ // consume flag value\n }\n current = current.slice(i)\n }\n return current\n}\n\n/** Walk a token list and resolve paren constructs:\n * - Plain `(subshell)` → tokens inlined with `;` boundaries on each\n * side, so the contents become independent segments evaluated by\n * the same policy. The subshell's own scope (cwd changes etc.) is\n * irrelevant to permissions — each command is checked individually.\n * - `$(...)` (command substitution) → stripped entirely, with the\n * `hasCommandSubst` flag raised. The dynamic value can't be\n * statically reasoned about. Detected by the leading `$` token\n * that shell-quote emits before the `(`.\n *\n * Recurses into subshell contents to handle nesting and to catch\n * `$(...)` constructs nested inside subshells. */\nfunction flattenParens(tokens: Token[]): { tokens: Token[]; hasCommandSubst: boolean } {\n const out: Token[] = []\n let hasCommandSubst = false\n let i = 0\n while (i < tokens.length) {\n const t = tokens[i]\n if (typeof t === \"object\" && \"op\" in t && t.op === \"(\") {\n const isSubst = out.at(-1) === \"$\"\n if (isSubst) out.pop()\n\n // Find matching `)`, accounting for nesting.\n let depth = 1\n let j = i + 1\n while (j < tokens.length && depth > 0) {\n const tj = tokens[j]\n if (typeof tj === \"object\" && \"op\" in tj) {\n if (tj.op === \"(\") depth++\n else if (tj.op === \")\") depth--\n }\n if (depth > 0) j++\n }\n const inner = tokens.slice(i + 1, j)\n\n if (isSubst) {\n hasCommandSubst = true\n // Drop the entire $(...) — its value is dynamic.\n } else {\n const sub = flattenParens(inner)\n if (sub.hasCommandSubst) hasCommandSubst = true\n // Surround with separators so subshell contents form their own\n // segments regardless of what's adjacent in the outer chain.\n out.push({ op: \";\" }, ...sub.tokens, { op: \";\" })\n }\n i = j + 1\n continue\n }\n\n if (typeof t === \"object\" && \"op\" in t && t.op === \")\") {\n // Stray closing paren (unbalanced input). Skip — the parser's\n // overall result will likely fail downstream on a malformed segment.\n i++\n continue\n }\n\n out.push(t)\n i++\n }\n return { hasCommandSubst, tokens: out }\n}\n","/**\n * Built-in tool registry — per-command knowledge of which args are\n * input files, output files, and which invocation modes are too\n * complex to safely model.\n *\n * The policy engine consults this registry alongside explicit redirect\n * info from the parser to determine per-command file I/O for the\n * fileRead/fileWrite policy hooks.\n */\nexport interface ToolSpec {\n /** File paths the command will read from, derived from args. */\n reads?: (args: string[]) => string[]\n /** File paths the command will write to. */\n writes?: (args: string[]) => string[]\n /** Returns true if the args invoke a mode the parser can't safely\n * reason about (e.g. `sed -e 'w out'`, `find -exec`). Forces ask. */\n unsafe?: (args: string[]) => boolean\n}\n\n/** All bare positional args (no leading dash). Default for many\n * read-only utilities. */\nfunction positionals(args: string[]): string[] {\n return args.filter((a) => !a.startsWith(\"-\") && a !== \"\")\n}\n\n/** All positionals after the first one (e.g. `grep PATTERN file...`). */\nfunction positionalsAfterFirst(args: string[]): string[] {\n const out: string[] = []\n let seenFirst = false\n for (const a of args) {\n if (a.startsWith(\"-\") || a === \"\") continue\n if (!seenFirst) {\n seenFirst = true\n continue\n }\n out.push(a)\n }\n return out\n}\n\n// ── sed ──────────────────────────────────────────────────────────────────\n\n/** Flags whose value is the *next* arg, not part of the script. */\nconst SED_VALUE_FLAGS = new Set([\"-e\", \"--expression\", \"-f\", \"--file\"])\n\n/** Walk sed args, returning [scripts, positionalsAfterScript]. The\n * \"script\" is everything passed via `-e` plus the first bare arg\n * (the implicit script when no `-e` is given). Positionals after\n * that are input files. */\nfunction sedSplit(args: string[]): { scripts: string[]; files: string[] } {\n const scripts: string[] = []\n const files: string[] = []\n let needsImplicitScript = !args.some(\n (a) => a === \"-e\" || a === \"--expression\" || a === \"-f\" || a === \"--file\"\n )\n\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a.startsWith(\"-\")) {\n if (SED_VALUE_FLAGS.has(a) && i + 1 < args.length) {\n if (a === \"-e\" || a === \"--expression\") scripts.push(args[i + 1])\n i++ // consume value\n }\n continue\n }\n if (needsImplicitScript) {\n scripts.push(a)\n needsImplicitScript = false\n continue\n }\n files.push(a)\n }\n return { files, scripts }\n}\n\nconst SED_INPLACE = new Set([\"-i\", \"--in-place\"])\n\nfunction sedReads(args: string[]): string[] {\n return sedSplit(args).files\n}\n\nfunction sedWrites(args: string[]): string[] {\n // `-i` rewrites positional input files; also supports `-i.bak` form.\n const inPlace = args.some((a) => SED_INPLACE.has(a) || a.startsWith(\"-i.\"))\n return inPlace ? sedSplit(args).files : []\n}\n\nfunction sedUnsafe(args: string[]): boolean {\n // `w` / `W` write commands and `r` / `R` read commands inside the\n // script can do file I/O the parser can't see. Bail to ask.\n for (const script of sedSplit(args).scripts) {\n if (/(?:^|;|\\n)\\s*[wWrR]\\s+\\S/.test(script)) return true\n }\n return false\n}\n\n// ── awk ──────────────────────────────────────────────────────────────────\n\nfunction awkReads(args: string[]): string[] {\n // awk usage: `awk [opts] 'script' [files...]` or `awk [opts] -f file [files...]`\n // Files come after the script. Skip flags + their values.\n let sawScript = false\n let usingFFlag = false\n const files: string[] = []\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a === \"-f\" || a === \"--file\") {\n if (i + 1 < args.length) files.push(args[i + 1]) // script file is read too\n i++\n sawScript = true\n usingFFlag = true\n continue\n }\n if (a.startsWith(\"-\")) {\n // Some awk flags take a value (-v, -F)\n if (a === \"-v\" || a === \"-F\") i++\n continue\n }\n if (!sawScript) {\n sawScript = true\n continue\n }\n files.push(a)\n }\n return usingFFlag ? files : files\n}\n\nfunction awkUnsafe(args: string[]): boolean {\n // awk's `print > file` and `printf > file` inside a script write to\n // files. Detecting reliably without parsing the script is hard, so\n // bail to ask if the script (or any -e value) contains a `>` operator.\n // Conservative — false positives are fine for \"ask\".\n let sawScript = false\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a === \"-f\" || a === \"--file\" || a === \"-v\" || a === \"-F\") {\n i++\n continue\n }\n if (a.startsWith(\"-\")) continue\n if (!sawScript) {\n sawScript = true\n if (/[>|]/.test(a)) return true\n }\n }\n return false\n}\n\n// ── find ─────────────────────────────────────────────────────────────────\n\nfunction findReads(args: string[]): string[] {\n // First positional (or `.`) is the path. Multiple paths possible\n // before the first `-action` flag.\n const out: string[] = []\n for (const a of args) {\n if (a.startsWith(\"-\")) break\n out.push(a)\n }\n return out.length > 0 ? out : [\".\"]\n}\n\nfunction findUnsafe(args: string[]): boolean {\n // `-delete`, `-exec`, `-execdir`, `-ok`, `-okdir` all do work we\n // can't trace.\n return args.some(\n (a) => a === \"-delete\" || a === \"-exec\" || a === \"-execdir\" || a === \"-ok\" || a === \"-okdir\"\n )\n}\n\n// ── dynamic execution ────────────────────────────────────────────────────\n//\n// These commands run arbitrary code passed as arguments or sourced from\n// files. We can't reason about their effects from the parser; force ask.\n\nconst dynamicExec = (): boolean => true\n\n// ── registry ─────────────────────────────────────────────────────────────\n\nexport const TOOLS: Partial<Record<string, ToolSpec>> = {\n \".\": { unsafe: dynamicExec }, // sh: source alias\n awk: { reads: awkReads, unsafe: awkUnsafe },\n basename: {},\n cat: { reads: positionals },\n cd: {},\n cut: { reads: positionals },\n diff: { reads: positionals },\n dirname: {},\n echo: {},\n eval: { unsafe: dynamicExec }, // runs its argument as shell input\n exec: { unsafe: dynamicExec }, // replaces the shell process\n file: { reads: positionals },\n find: { reads: findReads, unsafe: findUnsafe },\n grep: { reads: positionalsAfterFirst },\n head: { reads: positionals },\n hexdump: { reads: positionals },\n less: { reads: positionals },\n ls: { reads: positionals },\n more: { reads: positionals },\n od: { reads: positionals },\n printf: {},\n pwd: {},\n readlink: { reads: positionals },\n realpath: { reads: positionals },\n rg: { reads: positionalsAfterFirst },\n sed: { reads: sedReads, unsafe: sedUnsafe, writes: sedWrites },\n sort: { reads: positionals },\n source: { unsafe: dynamicExec }, // bash: runs the file in current shell\n stat: { reads: positionals },\n tail: { reads: positionals },\n tree: { reads: positionals },\n uniq: { reads: positionals },\n wc: { reads: positionals },\n xxd: { reads: positionals },\n}\n"],"ignoreList":[0,1,2],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { sliceAnsi, splitAnsi, stringWidth } from "@zaly/shared/ansi";
2
- //#region src/utils/truncate.ts
2
+ // src/utils/truncate.ts
3
3
  const MAX_CHARS = 5e4;
4
4
  const MAX_LINES = 2e3;
5
5
  const MAX_LINE_CHARS = 1e3;
@@ -96,7 +96,6 @@ function truncate(data, opts = {}) {
96
96
  ret.text = lines.join("\n");
97
97
  return ret;
98
98
  }
99
- //#endregion
100
99
  export { truncate as t };
101
100
 
102
- //# sourceMappingURL=truncate-BSMXgiXj.mjs.map
101
+ //# sourceMappingURL=truncate-CChlZ113.mjs.map