@tekmidian/pai 0.60.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/{chain-DFlzAfDE.mjs → chain-C5oeyUg4.mjs} +4 -4
  2. package/dist/{chain-DFlzAfDE.mjs.map → chain-C5oeyUg4.mjs.map} +1 -1
  3. package/dist/cli/index.mjs +12 -12
  4. package/dist/cli/program.mjs +12 -12
  5. package/dist/{config-msER8xj_.mjs → config-CQCmH_gV.mjs} +2 -1
  6. package/dist/config-CQCmH_gV.mjs.map +1 -0
  7. package/dist/{config-GceCMUxa.mjs → config-DjXq_W42.mjs} +1 -1
  8. package/dist/{context-handover-cache-DF0xWVB0.mjs → context-handover-cache-BdtJZpgv.mjs} +4 -4
  9. package/dist/{context-handover-cache-DF0xWVB0.mjs.map → context-handover-cache-BdtJZpgv.mjs.map} +1 -1
  10. package/dist/daemon/index.mjs +11 -11
  11. package/dist/{daemon-DArRKBlk.mjs → daemon-DSsIEqzW.mjs} +26 -19
  12. package/dist/{daemon-DArRKBlk.mjs.map → daemon-DSsIEqzW.mjs.map} +1 -1
  13. package/dist/daemon-MoFF4oeg.mjs +19 -0
  14. package/dist/daemon-mcp/index.mjs +9 -11
  15. package/dist/daemon-mcp/index.mjs.map +1 -1
  16. package/dist/{factory-D6I2jmjQ.mjs → factory-DW7BCJJT.mjs} +1 -1
  17. package/dist/{factory-ChfAvCzO.mjs → factory-EUUhSSoq.mjs} +5 -6
  18. package/dist/factory-EUUhSSoq.mjs.map +1 -0
  19. package/dist/{fallback-B7VEMMRn.mjs → fallback-DDbJVaR8.mjs} +12 -14
  20. package/dist/{fallback-B7VEMMRn.mjs.map → fallback-DDbJVaR8.mjs.map} +1 -1
  21. package/dist/hooks/block-sleep-poll.mjs.map +2 -2
  22. package/dist/hooks/context-compression-hook.mjs.map +1 -1
  23. package/dist/hooks/post-compact-inject.mjs.map +1 -1
  24. package/dist/hooks/route-agents-to-worker.mjs +5 -5
  25. package/dist/hooks/route-agents-to-worker.mjs.map +3 -3
  26. package/dist/hooks/security-validator.mjs +60 -60
  27. package/dist/hooks/security-validator.mjs.map +3 -3
  28. package/dist/hooks/stop-hook.mjs +15 -15
  29. package/dist/hooks/stop-hook.mjs.map +3 -3
  30. package/dist/hooks/update-tab-on-action.mjs +14 -12
  31. package/dist/hooks/update-tab-on-action.mjs.map +3 -3
  32. package/dist/hooks/update-tab-titles.mjs +13 -9
  33. package/dist/hooks/update-tab-titles.mjs.map +3 -3
  34. package/dist/hooks/whisper-rules.mjs +2 -2
  35. package/dist/hooks/whisper-rules.mjs.map +3 -3
  36. package/dist/hooks/worker-proxy.mjs +5 -5
  37. package/dist/hooks/worker-proxy.mjs.map +3 -3
  38. package/dist/hooks/worker-status-line.mjs +5 -5
  39. package/dist/hooks/worker-status-line.mjs.map +3 -3
  40. package/dist/hooks/worker-supervision.mjs +5 -5
  41. package/dist/hooks/worker-supervision.mjs.map +3 -3
  42. package/dist/main-resolver-CxOsxtOr.mjs +7 -0
  43. package/dist/{main-resolver-BqTjt-GL.mjs → main-resolver-DIQ6m_RA.mjs} +4 -4
  44. package/dist/{main-resolver-BqTjt-GL.mjs.map → main-resolver-DIQ6m_RA.mjs.map} +1 -1
  45. package/dist/{planner-DbpsMZqY.mjs → planner-D8jAr_sx.mjs} +7 -7
  46. package/dist/{planner-DbpsMZqY.mjs.map → planner-D8jAr_sx.mjs.map} +1 -1
  47. package/dist/{program-QSuci3RH.mjs → program-BTdspOOa.mjs} +131 -81
  48. package/dist/program-BTdspOOa.mjs.map +1 -0
  49. package/dist/{run-BFxuNnIJ.mjs → run-CxxZKEZw.mjs} +336 -174
  50. package/dist/run-CxxZKEZw.mjs.map +1 -0
  51. package/dist/{run-env-kbWVwUvU.mjs → run-env-BE5xyCwy.mjs} +26 -7
  52. package/dist/run-env-BE5xyCwy.mjs.map +1 -0
  53. package/dist/{server-B0vBmfJt.mjs → server-BY6AedmC.mjs} +2 -2
  54. package/dist/{server-B0vBmfJt.mjs.map → server-BY6AedmC.mjs.map} +1 -1
  55. package/dist/{session-keepalive-CUcFa8ld.mjs → session-keepalive-urk--pfa.mjs} +5 -5
  56. package/dist/{session-keepalive-CUcFa8ld.mjs.map → session-keepalive-urk--pfa.mjs.map} +1 -1
  57. package/dist/{tools-CaTZnIau.mjs → tools-qXyHFwNj.mjs} +2 -2
  58. package/dist/{tools-CaTZnIau.mjs.map → tools-qXyHFwNj.mjs.map} +1 -1
  59. package/dist/{tools-_7MF8Ebb.mjs → tools-r-7ZG8B5.mjs} +3 -3
  60. package/dist/{wakeup-CTX3rlz-.mjs → wakeup-C48hcN6O.mjs} +2 -2
  61. package/dist/{wakeup-CTX3rlz-.mjs.map → wakeup-C48hcN6O.mjs.map} +1 -1
  62. package/dist/work-queue-worker-1_VBfI_k.mjs +11 -0
  63. package/dist/{work-queue-worker-B4eZGy5n.mjs → work-queue-worker-DUvPiwGO.mjs} +2 -2
  64. package/dist/{work-queue-worker-B4eZGy5n.mjs.map → work-queue-worker-DUvPiwGO.mjs.map} +1 -1
  65. package/docs/commands/worker.md +1 -0
  66. package/package.json +1 -1
  67. package/src/hooks/ts/lib/tab-title.ts +18 -0
  68. package/src/hooks/ts/post-tool-use/update-tab-on-action.ts +3 -20
  69. package/src/hooks/ts/stop/stop-hook.ts +4 -15
  70. package/src/hooks/ts/user-prompt/update-tab-titles.ts +2 -10
  71. package/dist/config-msER8xj_.mjs.map +0 -1
  72. package/dist/daemon-BppwJtrH.mjs +0 -19
  73. package/dist/factory-ChfAvCzO.mjs.map +0 -1
  74. package/dist/main-resolver-CCojcYr2.mjs +0 -7
  75. package/dist/program-QSuci3RH.mjs.map +0 -1
  76. package/dist/run-BFxuNnIJ.mjs.map +0 -1
  77. package/dist/run-env-kbWVwUvU.mjs.map +0 -1
  78. package/dist/work-queue-worker-DuhZmfDB.mjs +0 -11
@@ -1,9 +1,9 @@
1
- import { i as getRegistryBackend } from "./factory-ChfAvCzO.mjs";
2
- import { D as resolveModelCapability, O as resolveProviderKey, T as readWorkersSection, h as classModelCapability, m as assertProviderRunnable, n as claudeCommand, p as WorkersConfigError, t as buildRunEnv, w as providerKeyPath, y as isModelCapability } from "./run-env-kbWVwUvU.mjs";
3
- import { _ as statusPath, d as resolveTarget, f as setCooldown, g as panesDir, h as ledgerPath, i as capabilityForRun, m as eventsPath, n as ensureProxyRunning, o as isQuotaFailure, p as ensureNoMcpConfig, s as nextAutoProvider, t as DEFAULT_PROXY_PORT, u as resolveCapabilityRun, v as workersLogDir } from "./server-B0vBmfJt.mjs";
4
- import { appendFileSync, closeSync, existsSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
1
+ import { i as getRegistryBackend } from "./factory-EUUhSSoq.mjs";
2
+ import { E as readWorkersSection, O as resolveModelCapability, T as providerKeyPath, b as isModelCapability, d as NATIVE_ANTHROPIC_MODELS, g as classModelCapability, h as assertProviderRunnable, k as resolveProviderKey, m as WorkersConfigError, n as claudeCommand, t as buildRunEnv } from "./run-env-BE5xyCwy.mjs";
3
+ import { _ as statusPath, d as resolveTarget, f as setCooldown, g as panesDir, h as ledgerPath, i as capabilityForRun, m as eventsPath, n as ensureProxyRunning, o as isQuotaFailure, p as ensureNoMcpConfig, s as nextAutoProvider, t as DEFAULT_PROXY_PORT, u as resolveCapabilityRun, v as workersLogDir } from "./server-BY6AedmC.mjs";
4
+ import { appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
5
5
  import { homedir, tmpdir } from "node:os";
6
- import { dirname, isAbsolute, join, relative, resolve } from "node:path";
6
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
7
  import { execFileSync, spawn } from "node:child_process";
8
8
  import { connect, createServer } from "node:net";
9
9
  import { createInterface } from "node:readline";
@@ -336,9 +336,10 @@ function saveStatus(logDir, status, d = /* @__PURE__ */ new Date()) {
336
336
  const path = statusPath(logDir, status.id);
337
337
  const baseline = firstWrittenLabel.get(status.id);
338
338
  if (baseline === void 0) firstWrittenLabel.set(status.id, status.label);
339
- else if (status.label === baseline) {
340
- const onDisk = loadStatus(logDir, status.id);
341
- if (onDisk && onDisk.label !== status.label) status.label = onDisk.label;
339
+ const onDisk = baseline === void 0 ? void 0 : loadStatus(logDir, status.id);
340
+ if (onDisk) {
341
+ if (status.label === baseline && onDisk.label !== status.label) status.label = onDisk.label;
342
+ if (onDisk.controlsHeld) status.controlsHeld = true;
342
343
  }
343
344
  const tmp = statusTmpPath(logDir, status.id);
344
345
  if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });
@@ -639,7 +640,8 @@ function isGitRepo(cwd) {
639
640
  function promptLooksReadonly(prompt) {
640
641
  const p = prompt.trim();
641
642
  if (!p) return true;
642
- if (/\b(read[- ]only|do not (modify|change|edit|write)|don'?t (modify|change|edit|write)|no changes)\b/i.test(p)) return true;
643
+ const firstLine = p.split("\n", 1)[0];
644
+ if (/\b(read[- ]only|do not (modify|change|edit|write)|don'?t (modify|change|edit|write)|no changes)\b/i.test(firstLine)) return true;
643
645
  return /^(review|read|analy[sz]e|research|summar[iy]|inspect|investigate|spotcheck|report|find|list|check|verify|describe|explain|show)\b/i.test(p);
644
646
  }
645
647
  /** The classes whose runs write files and therefore default to a worktree. */
@@ -843,18 +845,58 @@ function uncommittedPaths(wtDir) {
843
845
  return [...tracked, ...untracked];
844
846
  }
845
847
  /**
848
+ * True when `wtDir`/`relPath` is a symlink whose target resolves outside
849
+ * `wtDir` — e.g. a worker's `node_modules -> <main checkout>/node_modules`
850
+ * convenience link. A `.gitignore` using `dir/` (directories only) does not
851
+ * ignore such a link, so it turns up as untracked; staging and merging it
852
+ * lets git replace the real directory on the other side with a symlink to
853
+ * itself. Never a candidate for salvage.
854
+ */
855
+ function symlinkEscapesWorktree(wtDir, relPath) {
856
+ const full = join(wtDir, relPath);
857
+ let stat;
858
+ try {
859
+ stat = lstatSync(full);
860
+ } catch {
861
+ return false;
862
+ }
863
+ if (!stat.isSymbolicLink()) return false;
864
+ const target = readlinkSync(full);
865
+ const resolvedTarget = isAbsolute(target) ? target : resolve(dirname(full), target);
866
+ const realTarget = existsSync(resolvedTarget) ? realpathSync(resolvedTarget) : resolvedTarget;
867
+ const realWtDir = realpathSync(wtDir);
868
+ return realTarget !== realWtDir && !realTarget.startsWith(realWtDir + sep);
869
+ }
870
+ /**
846
871
  * Commit a worktree's uncommitted changes to its branch so the merge carries
847
872
  * them. `git merge` only moves committed work, so a worker that stopped
848
873
  * without committing would lose its edits to `worktree remove` — exactly
849
- * what happened live on 2026-09-17. Returns the salvaged paths, [] when the
850
- * worktree is clean. A failed commit throws with the worktree untouched:
874
+ * what happened live on 2026-09-17. Returns the salvaged paths, empty when
875
+ * the worktree is clean. A symlink pointing outside the worktree (see
876
+ * `symlinkEscapesWorktree`) is never staged; it is left on disk and reported
877
+ * as skipped instead. A failed commit throws with the worktree untouched:
851
878
  * its edits are still on disk, so nothing is lost.
852
879
  */
853
880
  function salvageUncommitted(wtDir, label) {
854
881
  const paths = uncommittedPaths(wtDir);
855
- if (!paths.length) return [];
882
+ if (!paths.length) return {
883
+ committed: [],
884
+ skipped: []
885
+ };
886
+ const skipped = [];
887
+ const toStage = [];
888
+ for (const p of paths) if (symlinkEscapesWorktree(wtDir, p)) skipped.push(`symlink ${p} -> ${readlinkSync(join(wtDir, p))} (points outside the worktree)`);
889
+ else toStage.push(p);
890
+ if (!toStage.length) return {
891
+ committed: [],
892
+ skipped
893
+ };
856
894
  try {
857
- git(wtDir, ["add", "-A"]);
895
+ git(wtDir, [
896
+ "add",
897
+ "--",
898
+ ...toStage
899
+ ]);
858
900
  git(wtDir, [
859
901
  "commit",
860
902
  "-m",
@@ -863,7 +905,10 @@ function salvageUncommitted(wtDir, label) {
863
905
  } catch (e) {
864
906
  throw new Error(`cannot salvage the uncommitted changes in ${wtDir} — ${e.message}; nothing was lost: commit them there by hand, then re-run merge`);
865
907
  }
866
- return paths;
908
+ return {
909
+ committed: toStage,
910
+ skipped
911
+ };
867
912
  }
868
913
  /**
869
914
  * The dirty paths of a checkout, parsed from `git status --porcelain -z`:
@@ -914,9 +959,14 @@ function assertNoDirtyOverlap(cwd, incoming, id, branch) {
914
959
  if (!overlap.length) return;
915
960
  throw new Error(`worker ${id}: the checkout ${cwd} has uncommitted changes in paths ${branch} touches: ${overlap.join(", ")}. Commit or stash them in the checkout, then re-run: pai worker merge ${id}. No merge was made; the worktree was kept.`);
916
961
  }
917
- /** Never remove a worktree that still holds uncommitted changes. */
962
+ /**
963
+ * Never remove a worktree that still holds uncommitted changes — except a
964
+ * symlink escaping the worktree (see `symlinkEscapesWorktree`): it was
965
+ * deliberately left uncommitted by `salvageUncommitted`, and deleting the
966
+ * link itself touches nothing outside the worktree.
967
+ */
918
968
  function assertWorktreeClean(wtDir, id) {
919
- const leftover = uncommittedPaths(wtDir);
969
+ const leftover = uncommittedPaths(wtDir).filter((p) => !symlinkEscapesWorktree(wtDir, p));
920
970
  if (leftover.length) throw new Error(`worker ${id}: the worktree ${wtDir} still holds uncommitted changes (${leftover.join(", ")}) — it was NOT removed; commit or copy them by hand, then re-run merge`);
921
971
  }
922
972
  /** Blob sha of `path` at `rev` in `cwd`, or null when it does not exist there. */
@@ -970,7 +1020,10 @@ function mergeSnapshotWorker(logDir, id, st) {
970
1020
  const snapshot = st.worktreeBase;
971
1021
  const branch = st.branch;
972
1022
  const worktreeDir = st.worktreeDir;
973
- const salvaged = existsSync(worktreeDir) ? salvageUncommitted(worktreeDir, st.label || UNLABELED) : [];
1023
+ const salvage = existsSync(worktreeDir) ? salvageUncommitted(worktreeDir, st.label || UNLABELED) : {
1024
+ committed: [],
1025
+ skipped: []
1026
+ };
974
1027
  if ((parseInt(git(st.cwd, [
975
1028
  "rev-list",
976
1029
  "--count",
@@ -1029,7 +1082,10 @@ function mergeSnapshotWorker(logDir, id, st) {
1029
1082
  merged: true
1030
1083
  });
1031
1084
  const base = `applied worker ${id}'s changes (branch ${branch}) to ${st.cwd} as uncommitted changes: ${changedPaths.join(", ")} (worktree removed, branch deleted)`;
1032
- return salvaged.length ? `${base}; salvaged ${salvaged.length} uncommitted change(s) onto the branch first: ${salvaged.join(", ")}` : base;
1085
+ const notes = [];
1086
+ if (salvage.committed.length) notes.push(`salvaged ${salvage.committed.length} uncommitted change(s) onto the branch first: ${salvage.committed.join(", ")}`);
1087
+ if (salvage.skipped.length) notes.push(`skipped ${salvage.skipped.join(", ")}`);
1088
+ return notes.length ? `${base}; ${notes.join("; ")}` : base;
1033
1089
  }
1034
1090
  /**
1035
1091
  * `pai worker merge <id>`: salvage whatever the worker left uncommitted onto
@@ -1044,7 +1100,10 @@ function mergeWorker(logDir, id) {
1044
1100
  const st = mustHaveBranch(logDir, id);
1045
1101
  if (st.merged) return `worker ${id}: branch ${st.branch} already merged`;
1046
1102
  if (st.worktreeSnapshot) return mergeSnapshotWorker(logDir, id, st);
1047
- const salvaged = existsSync(st.worktreeDir) ? salvageUncommitted(st.worktreeDir, st.label || UNLABELED) : [];
1103
+ const salvage = existsSync(st.worktreeDir) ? salvageUncommitted(st.worktreeDir, st.label || UNLABELED) : {
1104
+ committed: [],
1105
+ skipped: []
1106
+ };
1048
1107
  if ((parseInt(git(st.cwd, [
1049
1108
  "rev-list",
1050
1109
  "--count",
@@ -1074,7 +1133,7 @@ function mergeWorker(logDir, id) {
1074
1133
  throw new Error(`worker ${id}: git refused the merge of ${st.branch} — ${e.message}. The worktree ${st.worktreeDir} was kept: resolve the conflict, then re-run merge`);
1075
1134
  }
1076
1135
  if (existsSync(st.worktreeDir)) assertWorktreeClean(st.worktreeDir, id);
1077
- removeWorktree(st.cwd, st.worktreeDir, false);
1136
+ removeWorktree(st.cwd, st.worktreeDir, true);
1078
1137
  let branchGone = true;
1079
1138
  try {
1080
1139
  git(st.cwd, [
@@ -1090,7 +1149,10 @@ function mergeWorker(logDir, id) {
1090
1149
  merged: true
1091
1150
  });
1092
1151
  const base = `merged ${st.branch} into ${st.cwd} (worktree removed${branchGone ? ", branch deleted" : "; branch kept: git refused -d"})`;
1093
- return salvaged.length ? `${base}; salvaged ${salvaged.length} uncommitted change(s): ${salvaged.join(", ")}` : base;
1152
+ const notes = [];
1153
+ if (salvage.committed.length) notes.push(`salvaged ${salvage.committed.length} uncommitted change(s): ${salvage.committed.join(", ")}`);
1154
+ if (salvage.skipped.length) notes.push(`skipped ${salvage.skipped.join(", ")}`);
1155
+ return notes.length ? `${base}; ${notes.join("; ")}` : base;
1094
1156
  }
1095
1157
  /** `pai worker discard <id>`: drop worktree and branch, keep nothing. */
1096
1158
  function discardWorker(logDir, id) {
@@ -1172,9 +1234,10 @@ function inPlaceSystemPrompt() {
1172
1234
  * If neither is available, viewers fall back to "all workers".
1173
1235
  *
1174
1236
  * A third case: workers spawned from a Claude Code Bash tool (the
1175
- * orchestrator pattern) have neither — Claude Code exports no terminal or
1176
- * session identity to its Bash children. Those record `spawnerSession`, the
1177
- * orchestrator's claude session id bridged through the status line's
1237
+ * orchestrator pattern) inherit the orchestrator's `ITERM_SESSION_ID`, which
1238
+ * identifies the orchestrator's own pane, not a pane for the sub-worker —
1239
+ * so it does not key the sub-worker's tab. Those record `spawnerSession`,
1240
+ * the orchestrator's claude session id bridged through the status line's
1178
1241
  * session map (see below), so their tab still claims them.
1179
1242
  */
1180
1243
  const AIBROKER_REGISTRY = join(homedir(), ".aibroker", "session-names.json");
@@ -1896,7 +1959,10 @@ function absoluteCliPath() {
1896
1959
  }
1897
1960
  /** Open (or only report on) the stacked follow pane of one worker. */
1898
1961
  async function openPaneForWorker(logDir, config, wid, term) {
1899
- if (workerPaneOpen(wid)) return `pane for ${wid} already open`;
1962
+ if (workerPaneOpen(wid)) return {
1963
+ message: `pane for ${wid} already open`,
1964
+ session: null
1965
+ };
1900
1966
  const uid = itermUuid(term);
1901
1967
  const regPath = join(panesDir(logDir), `${scopeKey(term)}.json`);
1902
1968
  const reg = loadRegistry(regPath);
@@ -1920,7 +1986,10 @@ async function openPaneForWorker(logDir, config, wid, term) {
1920
1986
  opened: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
1921
1987
  });
1922
1988
  saveRegistry(regPath, pruned);
1923
- return `pane opened for ${wid}`;
1989
+ return {
1990
+ message: `pane opened for ${wid}`,
1991
+ session: out.slice(bar + 1)
1992
+ };
1924
1993
  }
1925
1994
  /**
1926
1995
  * One `--check` line with the bounds of the window hosting `term`'s iTerm
@@ -2040,6 +2109,34 @@ function launchParent(explicit, env = process.env) {
2040
2109
  function isWorkerId(logDir, id) {
2041
2110
  return loadStatus(logDir, id) !== null;
2042
2111
  }
2112
+ /**
2113
+ * A worker owns its children's results (the worker contract says so): if
2114
+ * `parent` exits leaving sub-workers unaccounted for, its own run must not
2115
+ * report success. Two shapes count, both read off `runningChildren` and the
2116
+ * raw statuses, never a second live-child lookup:
2117
+ *
2118
+ * - still live: left running untouched (killing another process's work
2119
+ * here would be its own bug) but named in the reason.
2120
+ * - marked "running" with a dead pid (the child never got to write its own
2121
+ * terminal state before its parent vanished from under it): finalised
2122
+ * here as failed, so `ps` stops showing a corpse as live.
2123
+ *
2124
+ * Returns the reason string for the parent's own report, or null when every
2125
+ * child it started is accounted for.
2126
+ */
2127
+ function checkOrphanedChildren(logDir, parent) {
2128
+ const statuses = loadStatuses(logDir);
2129
+ const live = runningChildren(statuses, parent);
2130
+ const abandoned = statuses.filter((s) => s.parent === parent && s.state === "running" && !isLive(s));
2131
+ for (const child of abandoned) saveStatus(logDir, {
2132
+ ...child,
2133
+ state: "failed",
2134
+ last: `parent ${parent} exited`
2135
+ });
2136
+ const ids = [...live, ...abandoned].map((s) => s.id);
2137
+ if (!ids.length) return null;
2138
+ return `exited with ${ids.length} sub-worker${ids.length === 1 ? "" : "s"} still running (${ids.join(", ")}); they were not waited for — run children in the foreground or wait for them before finishing`;
2139
+ }
2043
2140
 
2044
2141
  //#endregion
2045
2142
  //#region src/workers/operator.ts
@@ -2282,6 +2379,16 @@ function ag2Spec() {
2282
2379
  return cachedSpec;
2283
2380
  }
2284
2381
  /**
2382
+ * Strip what workers wrap around a report: one surrounding ``` fence (opening
2383
+ * line may carry a language tag) and a leading `[YYYY-MM-DD HH:MM]` stamp line.
2384
+ */
2385
+ function unwrapAg2(text) {
2386
+ let t = (text ?? "").trim();
2387
+ const fenced = t.match(/^```[^\n]*\n([\s\S]*?)\n?```$/);
2388
+ if (fenced) t = fenced[1].trim();
2389
+ return t.replace(/^\[\d{4}-\d{2}-\d{2}[^\]\n]*\][ \t]*\n/, "").trim();
2390
+ }
2391
+ /**
2285
2392
  * Parse one AG2 message: first non-empty line is the kind (T R S Q A X,
2286
2393
  * optionally followed by trailing text — only the first character is the
2287
2394
  * kind), later lines are `key=value` or `@n=path` symbol declarations.
@@ -2297,7 +2404,7 @@ function parseAg2Report(text) {
2297
2404
  "A",
2298
2405
  "X"
2299
2406
  ]);
2300
- const lines = (text ?? "").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("```"));
2407
+ const lines = unwrapAg2(text).split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("```"));
2301
2408
  if (!lines.length) return null;
2302
2409
  const kind = lines[0][0];
2303
2410
  if (!kinds.has(kind)) return null;
@@ -2341,11 +2448,17 @@ function ag2ToWorkerReport(parsed) {
2341
2448
  summary: entry.slice(cut + 1).trim()
2342
2449
  };
2343
2450
  });
2344
- if (f.t) out.checks = f.t.split(/\s+/).filter(Boolean).map((entry) => ({
2345
- name: entry.slice(0, -1),
2346
- ok: passed(entry),
2347
- detail: entry.slice(-1)
2348
- }));
2451
+ if (f.t) {
2452
+ const tokens = f.t.split(/\s+/).filter(Boolean);
2453
+ out.checks = tokens.length > 0 && tokens.every((tok) => /^\S+[+\-~?!]$/.test(tok)) ? tokens.map((entry) => ({
2454
+ name: entry.slice(0, -1),
2455
+ ok: passed(entry),
2456
+ detail: entry.slice(-1)
2457
+ })) : [{
2458
+ name: "tests",
2459
+ detail: f.t
2460
+ }];
2461
+ }
2349
2462
  if (f.p) out.commands = f.p.split("|").map((s) => s.trim()).filter(Boolean);
2350
2463
  const open = [];
2351
2464
  if (f.x) open.push(f.x);
@@ -2371,7 +2484,7 @@ function validateAg2(text) {
2371
2484
  "-",
2372
2485
  "--json"
2373
2486
  ], {
2374
- input: text,
2487
+ input: unwrapAg2(text),
2375
2488
  timeout: 5e3,
2376
2489
  stdio: [
2377
2490
  "pipe",
@@ -2599,7 +2712,7 @@ function renderReport(c, prefix, r, cwd = "") {
2599
2712
  if (has(r.checks)) {
2600
2713
  out.push(`${prefix}${c("bold", "checks")}`);
2601
2714
  for (const ck of r.checks) {
2602
- const mark = ck.ok === false ? c("red", "✗") : c("green", "✓");
2715
+ const mark = ck.ok === false ? c("red", "✗") : ck.ok === true ? c("green", "✓") : c("dim", "·");
2603
2716
  const detail = ck.detail ? c("dim", ` · ${shortText(ck.detail, 80)}`) : "";
2604
2717
  out.push(`${prefix} ${mark} ${ck.name ?? "?"}${detail}`);
2605
2718
  }
@@ -3011,16 +3124,22 @@ function toolResultFailed(block) {
3011
3124
  const m = toolResultText(block.content).match(/Exit code (\d+)/);
3012
3125
  return m !== null && Number(m[1]) !== 0;
3013
3126
  }
3127
+ /** CLI aliases the built-in provider hands to `--model` (NATIVE_ANTHROPIC_MODELS'
3128
+ * values): a bare name like "sonnet", not a concrete id, so the init event's
3129
+ * resolved id is always the more useful thing to display. */
3130
+ const NATIVE_MODEL_ALIASES = new Set(Object.values(NATIVE_ANTHROPIC_MODELS));
3014
3131
  /**
3015
3132
  * The model the init event announces, adopted into the status when the spawn
3016
3133
  * could not name one (a caller that passed `--model` itself in the claude
3017
- * args, or a provider whose table has no entry for the capability). The run's
3018
- * real model is then only knowable from the first event it sends. Never
3019
- * overwrites an explicit model — a resolved or pinned model stays the
3134
+ * args, or a provider whose table has no entry for the capability) or named
3135
+ * only a CLI alias (the built-in provider's "sonnet"/"haiku", which tracks
3136
+ * whatever release is current — the init event says which one actually ran).
3137
+ * The run's real model is then only knowable from the first event it sends.
3138
+ * Never overwrites a concrete resolved or pinned model — that stays the
3020
3139
  * recorded truth.
3021
3140
  */
3022
3141
  function adoptInitModel(status, e) {
3023
- if (status.model) return;
3142
+ if (status.model && !NATIVE_MODEL_ALIASES.has(status.model)) return;
3024
3143
  const m = (e.model ?? "").trim();
3025
3144
  if (m) status.model = m;
3026
3145
  }
@@ -3115,7 +3234,7 @@ async function runWorker(opts) {
3115
3234
  const logDir = workersLogDir(config);
3116
3235
  mkdirSync(logDir, { recursive: true });
3117
3236
  if (opts.className === "plan" && !opts._planner) {
3118
- const { runPlanner } = await import("./planner-DbpsMZqY.mjs");
3237
+ const { runPlanner } = await import("./planner-D8jAr_sx.mjs");
3119
3238
  return runPlanner(opts);
3120
3239
  }
3121
3240
  const parent = launchParent(opts.parent);
@@ -3319,6 +3438,64 @@ function interactiveMcpTools(explicitMcp, callerTools, projectLaunch) {
3319
3438
  tools: !callerTools && projectLaunch?.tools?.length ? projectLaunch.tools : []
3320
3439
  };
3321
3440
  }
3441
+ /**
3442
+ * The finalisation every engine shares: orphaned-children check, state, the
3443
+ * WORKER-END ledger line, worktree outcome, parent handoff, final rc. A worker
3444
+ * owns its children's results (the worker contract says so): if it
3445
+ * backgrounded a sub-worker and exited without waiting, the run must not
3446
+ * report success, whatever the process returned.
3447
+ */
3448
+ async function finaliseRun(f) {
3449
+ const { logDir, ledger, ok, rc } = f;
3450
+ let { status, report } = f;
3451
+ const wid = status.id;
3452
+ const orphanReason = checkOrphanedChildren(logDir, wid);
3453
+ const succeeded = ok && !orphanReason;
3454
+ status.state = succeeded ? "done" : "failed";
3455
+ status.rc = rc;
3456
+ status.secs = f.secs;
3457
+ if (orphanReason) {
3458
+ status.last = shortText(orphanReason, 90);
3459
+ report = {
3460
+ ...report ?? {},
3461
+ notes: orphanReason,
3462
+ result: "-"
3463
+ };
3464
+ appendLedger(ledger, "WORKER-ORPHAN-CHILDREN", {
3465
+ id: wid,
3466
+ reason: orphanReason
3467
+ });
3468
+ }
3469
+ saveStatus(logDir, status);
3470
+ appendLedger(ledger, "WORKER-END", {
3471
+ id: wid,
3472
+ ...f.end,
3473
+ rc,
3474
+ secs: f.secs
3475
+ });
3476
+ if (f.worktree) status = recordWorktree(logDir, status, f.worktree, ok);
3477
+ const early = await f.beforeHandoff?.(status, report);
3478
+ if (typeof early === "number") return early;
3479
+ const finalRc = rc !== 0 ? rc : succeeded ? 0 : 1;
3480
+ if (status.parent && isWorkerId(logDir, status.parent)) try {
3481
+ await deliverHandoff(logDir, {
3482
+ from: wid,
3483
+ to: status.parent,
3484
+ kind: "result",
3485
+ text: shortText(report?.notes ?? f.fallbackText ?? (succeeded ? "done" : "failed"), 400),
3486
+ data: {
3487
+ rc: finalRc,
3488
+ ok: succeeded,
3489
+ ...status.branch ? {
3490
+ branch: status.branch,
3491
+ commits: status.commits ?? 0
3492
+ } : {},
3493
+ ...report ? { report } : {}
3494
+ }
3495
+ });
3496
+ } catch {}
3497
+ return finalRc;
3498
+ }
3322
3499
  async function executeImageRun(a) {
3323
3500
  const { logDir, target, model, label, parsed } = a;
3324
3501
  if (!parsed.headless || parsed.prompt === null) throw new Error(`provider "${target.providerName}" (engine image) supports headless runs only: pass the task with -p '<prompt>'`);
@@ -3365,6 +3542,14 @@ async function executeImageRun(a) {
3365
3542
  capability: a.capability,
3366
3543
  ...a.specPath ? { spec: a.specPath } : {}
3367
3544
  });
3545
+ const imageEnd = {
3546
+ provider: target.providerName,
3547
+ mode: "headless",
3548
+ engine: "image",
3549
+ model,
3550
+ label,
3551
+ capability: a.capability
3552
+ };
3368
3553
  const t0 = Date.now();
3369
3554
  try {
3370
3555
  const result = await runImageCapability({
@@ -3377,46 +3562,61 @@ async function executeImageRun(a) {
3377
3562
  timeoutMs: a.timeoutMs
3378
3563
  });
3379
3564
  const secs = Math.round((Date.now() - t0) / 1e3);
3380
- status.state = "done";
3381
- status.rc = 0;
3382
- status.secs = secs;
3383
3565
  status.last = `wrote ${result.path}`;
3384
- saveStatus(logDir, status);
3385
- appendLedger(ledger, "WORKER-END", {
3386
- id: wid,
3387
- provider: target.providerName,
3388
- mode: "headless",
3389
- engine: "image",
3390
- model,
3566
+ return await finaliseRun({
3567
+ logDir,
3568
+ ledger,
3569
+ status,
3570
+ ok: true,
3391
3571
  rc: 0,
3392
3572
  secs,
3393
- label,
3394
- capability: a.capability
3573
+ end: imageEnd,
3574
+ report: null,
3575
+ beforeHandoff: () => {
3576
+ if (!a.quiet) process.stdout.write(JSON.stringify(result) + "\n");
3577
+ }
3395
3578
  });
3396
- if (!a.quiet) process.stdout.write(JSON.stringify(result) + "\n");
3397
- return 0;
3398
3579
  } catch (e) {
3399
3580
  const secs = Math.round((Date.now() - t0) / 1e3);
3400
- const message = e instanceof Error ? e.message : String(e);
3401
- status.state = "failed";
3402
- status.rc = 1;
3403
- status.secs = secs;
3404
- status.last = message;
3405
- saveStatus(logDir, status);
3406
- appendLedger(ledger, "WORKER-END", {
3407
- id: wid,
3408
- provider: target.providerName,
3409
- mode: "headless",
3410
- engine: "image",
3411
- model,
3581
+ status.last = e instanceof Error ? e.message : String(e);
3582
+ await finaliseRun({
3583
+ logDir,
3584
+ ledger,
3585
+ status,
3586
+ ok: false,
3412
3587
  rc: 1,
3413
3588
  secs,
3414
- label,
3415
- capability: a.capability
3589
+ end: imageEnd,
3590
+ report: null
3416
3591
  });
3417
3592
  throw e;
3418
3593
  }
3419
3594
  }
3595
+ /**
3596
+ * Follow pane, made observable on stderr (stdout stays pure JSON for
3597
+ * `--output-format json`): one line naming the outcome — opened, skipped
3598
+ * (with reason), or failed (with reason, alongside the existing PANE-FAIL
3599
+ * ledger line). Fire-and-forget, never blocks the worker.
3600
+ */
3601
+ async function announcePane(logDir, config, wid, term, noPane, ledger) {
3602
+ const skip = !noPane ? !config.pane.enabled ? "workers.pane.enabled is false" : process.env.PAI_WORKER_AUTOPANE === "0" ? "PAI_WORKER_AUTOPANE=0" : !term ? "not in iTerm2 (no ITERM_SESSION_ID)" : null : "--no-pane";
3603
+ if (skip) {
3604
+ process.stderr.write(`[pai worker] no pane for ${wid}: ${skip}\n`);
3605
+ return;
3606
+ }
3607
+ try {
3608
+ const r = await openPaneForWorker(logDir, config, wid, term);
3609
+ const suffix = r.session ? ` (iTerm session ${r.session})` : "";
3610
+ process.stderr.write(`[pai worker] pane opened for ${wid}${suffix}\n`);
3611
+ } catch (e) {
3612
+ const message = e instanceof Error ? e.message : String(e);
3613
+ process.stderr.write(`[pai worker] no pane for ${wid}: ${message.slice(0, 200)}\n`);
3614
+ appendLedger(ledger, "PANE-FAIL", {
3615
+ id: wid,
3616
+ error: message.slice(0, 200)
3617
+ });
3618
+ }
3619
+ }
3420
3620
  async function executeRun(a) {
3421
3621
  const { config, logDir, target, model, label, parsed, noPane } = a;
3422
3622
  const headless = parsed.headless;
@@ -3548,12 +3748,7 @@ async function executeRun(a) {
3548
3748
  ...a.capability ? { capability: a.capability } : {},
3549
3749
  ...a.specPath ? { spec: a.specPath } : {}
3550
3750
  });
3551
- if (headless && !noPane && config.pane.enabled && term && process.env.PAI_WORKER_AUTOPANE !== "0") openPaneForWorker(logDir, config, wid, term).catch((e) => {
3552
- appendLedger(ledger, "PANE-FAIL", {
3553
- id: wid,
3554
- error: (e instanceof Error ? e.message : String(e)).slice(0, 200)
3555
- });
3556
- });
3751
+ if (headless) announcePane(logDir, config, wid, term, noPane, ledger);
3557
3752
  const t0 = Date.now();
3558
3753
  const proc = spawn(cmd[0], cmd.slice(1), {
3559
3754
  env,
@@ -3706,9 +3901,6 @@ async function executeRun(a) {
3706
3901
  const secs = Math.floor((Date.now() - t0) / 1e3);
3707
3902
  const resultEvent = ctx.resultEvent;
3708
3903
  const ok = runSucceeded(headless, rc, resultEvent);
3709
- status.state = ok ? "done" : "failed";
3710
- status.rc = rc;
3711
- status.secs = secs;
3712
3904
  if (resultEvent) status.last = shortText(resultEvent.result ?? "", 90);
3713
3905
  if (ctx.resultReport?.notes) status.last = shortText(ctx.resultReport.notes, 90);
3714
3906
  if (headless && a.reportFormat === "ag2" && resultEvent?.result) {
@@ -3760,66 +3952,55 @@ async function executeRun(a) {
3760
3952
  });
3761
3953
  }
3762
3954
  }
3763
- saveStatus(logDir, status);
3764
- appendLedger(ledger, "WORKER-END", {
3765
- id: wid,
3766
- provider: target.providerName,
3767
- mode: headless ? "headless" : "interactive",
3768
- model,
3955
+ return finaliseRun({
3956
+ logDir,
3957
+ ledger,
3958
+ status,
3959
+ ok,
3769
3960
  rc,
3770
3961
  secs,
3771
- turns: status.turns,
3772
- tools: status.tools,
3773
- label
3774
- });
3775
- if (worktree) status = recordWorktree(logDir, status, worktree, ok);
3776
- if (headless && !a.quiet) printResult(parsed.outputFormat, resultEvent, rc, logDir, wid, ctx.resultReport, worktreeExtras(status));
3777
- const resultText = resultEvent?.result ?? "";
3778
- if (!ok && headless && a.target.via === "auto" && config.routing.retryOnQuota && status.turns <= 1 && status.tools === 0 && isQuotaFailure(resultText)) {
3779
- setCooldown(logDir, target.providerName, config.routing.cooldownMinutes);
3780
- const next = nextAutoProvider(config, logDir, target.providerName);
3781
- if (next && a.reroutes < config.routing.order.length) {
3782
- appendLedger(ledger, "WORKER-REROUTE", {
3783
- from: target.providerName,
3784
- to: next,
3785
- reason: "quota"
3786
- });
3787
- return runWorker({
3788
- providerFlag: next,
3789
- label,
3790
- noPane: a.noPane,
3791
- mcpFlag: a.mcpFlag,
3792
- cwd: a.cwd,
3793
- specPath: a.specPath,
3794
- parent: a.parent,
3795
- stage: a.stage,
3796
- claudeArgs: a.claudeArgs,
3797
- onWorkerStart: a.onWorkerStart,
3798
- worktreeFlag: a.worktreeFlag,
3799
- className: a.className,
3800
- _reroutes: a.reroutes + 1
3801
- });
3802
- }
3803
- }
3804
- const finalRc = rc !== 0 ? rc : ok ? 0 : 1;
3805
- if (status.parent && isWorkerId(logDir, status.parent)) try {
3806
- await deliverHandoff(logDir, {
3807
- from: wid,
3808
- to: status.parent,
3809
- kind: "result",
3810
- text: shortText(ctx.resultReport?.notes ?? resultEvent?.result ?? (ok ? "done" : "failed"), 400),
3811
- data: {
3812
- rc: finalRc,
3813
- ok,
3814
- ...status.branch ? {
3815
- branch: status.branch,
3816
- commits: status.commits ?? 0
3817
- } : {},
3818
- ...ctx.resultReport ? { report: ctx.resultReport } : {}
3962
+ end: {
3963
+ provider: target.providerName,
3964
+ mode: headless ? "headless" : "interactive",
3965
+ model,
3966
+ turns: status.turns,
3967
+ tools: status.tools,
3968
+ label
3969
+ },
3970
+ report: ctx.resultReport,
3971
+ fallbackText: resultEvent?.result,
3972
+ worktree,
3973
+ beforeHandoff: async (st, rep) => {
3974
+ if (headless && !a.quiet) printResult(parsed.outputFormat, resultEvent, rc, logDir, wid, rep, worktreeExtras(st));
3975
+ const resultText = resultEvent?.result ?? "";
3976
+ if (!ok && headless && a.target.via === "auto" && config.routing.retryOnQuota && status.turns <= 1 && status.tools === 0 && isQuotaFailure(resultText)) {
3977
+ setCooldown(logDir, target.providerName, config.routing.cooldownMinutes);
3978
+ const next = nextAutoProvider(config, logDir, target.providerName);
3979
+ if (next && a.reroutes < config.routing.order.length) {
3980
+ appendLedger(ledger, "WORKER-REROUTE", {
3981
+ from: target.providerName,
3982
+ to: next,
3983
+ reason: "quota"
3984
+ });
3985
+ return runWorker({
3986
+ providerFlag: next,
3987
+ label,
3988
+ noPane: a.noPane,
3989
+ mcpFlag: a.mcpFlag,
3990
+ cwd: a.cwd,
3991
+ specPath: a.specPath,
3992
+ parent: a.parent,
3993
+ stage: a.stage,
3994
+ claudeArgs: a.claudeArgs,
3995
+ onWorkerStart: a.onWorkerStart,
3996
+ worktreeFlag: a.worktreeFlag,
3997
+ className: a.className,
3998
+ _reroutes: a.reroutes + 1
3999
+ });
4000
+ }
3819
4001
  }
3820
- });
3821
- } catch {}
3822
- return finalRc;
4002
+ }
4003
+ });
3823
4004
  }
3824
4005
  /** The worktree fields printResult adds to a json payload, when there is one. */
3825
4006
  function worktreeExtras(s) {
@@ -3944,12 +4125,7 @@ async function executeCodexRun(a) {
3944
4125
  id: wid,
3945
4126
  note: `dropped for codex: ${dropped.join(", ")}`
3946
4127
  });
3947
- if (!noPane && config.pane.enabled && term && process.env.PAI_WORKER_AUTOPANE !== "0") openPaneForWorker(logDir, config, wid, term).catch((e) => {
3948
- appendLedger(ledger, "PANE-FAIL", {
3949
- id: wid,
3950
- error: (e instanceof Error ? e.message : String(e)).slice(0, 200)
3951
- });
3952
- });
4128
+ announcePane(logDir, config, wid, term, noPane, ledger);
3953
4129
  const t0 = Date.now();
3954
4130
  const proc = spawn("codex", buildCodexArgs(prompt, parsed.callerModel ? void 0 : model), {
3955
4131
  env,
@@ -4028,9 +4204,6 @@ async function executeCodexRun(a) {
4028
4204
  };
4029
4205
  writeEvent(resultEvent);
4030
4206
  const ok = rc === 0 && !fold.isError;
4031
- status.state = ok ? "done" : "failed";
4032
- status.rc = rc;
4033
- status.secs = secs;
4034
4207
  status.last = shortText(report?.notes ?? finalText, 90) || (ok ? "done" : "failed");
4035
4208
  if (report?.changed?.length) {
4036
4209
  const verify = verifyReportChanges(report.changed, worktree?.dir ?? cwd, t0);
@@ -4046,40 +4219,29 @@ async function executeCodexRun(a) {
4046
4219
  });
4047
4220
  }
4048
4221
  }
4049
- saveStatus(logDir, status);
4050
- appendLedger(ledger, "WORKER-END", {
4051
- id: wid,
4052
- provider: target.providerName,
4053
- mode: "headless",
4054
- engine: "codex",
4055
- model,
4222
+ return finaliseRun({
4223
+ logDir,
4224
+ ledger,
4225
+ status,
4226
+ ok,
4056
4227
  rc,
4057
4228
  secs,
4058
- turns: status.turns,
4059
- tools: status.tools,
4060
- label
4229
+ end: {
4230
+ provider: target.providerName,
4231
+ mode: "headless",
4232
+ engine: "codex",
4233
+ model,
4234
+ turns: status.turns,
4235
+ tools: status.tools,
4236
+ label
4237
+ },
4238
+ report,
4239
+ fallbackText: finalText,
4240
+ worktree,
4241
+ beforeHandoff: (st, rep) => {
4242
+ if (!a.quiet) printResult(parsed.outputFormat, resultEvent, rc, logDir, wid, rep, worktreeExtras(st));
4243
+ }
4061
4244
  });
4062
- if (worktree) status = recordWorktree(logDir, status, worktree, ok);
4063
- if (!a.quiet) printResult(parsed.outputFormat, resultEvent, rc, logDir, wid, report, worktreeExtras(status));
4064
- const finalRc = rc !== 0 ? rc : ok ? 0 : 1;
4065
- if (status.parent && isWorkerId(logDir, status.parent)) try {
4066
- await deliverHandoff(logDir, {
4067
- from: wid,
4068
- to: status.parent,
4069
- kind: "result",
4070
- text: shortText(report?.notes ?? finalText ?? (ok ? "done" : "failed"), 400),
4071
- data: {
4072
- rc: finalRc,
4073
- ok,
4074
- ...status.branch ? {
4075
- branch: status.branch,
4076
- commits: status.commits ?? 0
4077
- } : {},
4078
- ...report ? { report } : {}
4079
- }
4080
- });
4081
- } catch {}
4082
- return finalRc;
4083
4245
  }
4084
4246
  function printResult(fmt, resultEvent, rc, logDir, wid, report, extras) {
4085
4247
  if (fmt === "stream-json") return;
@@ -4213,4 +4375,4 @@ function resultFromOutput(out) {
4213
4375
 
4214
4376
  //#endregion
4215
4377
  export { UNLABELED as A, newWorkerId as B, workerInScope as C, worktreesDir as D, mergeWorker as E, elapsedOf as F, waitForTerminalStatus as G, ownsPid as H, isChatPane as I, shortText as J, longInlinePromptHint as K, isLive as L, alive as M, contextLabel as N, appendLedger as O, contextPercent as P, loadStatus as R, sessionTag as S, git as T, saveStatus as U, nowStamp as V, setWorkerLabel as W, expandMcpNames as X, describeMcp as Y, currentTabKey as _, projectLaunchConfig as a, resolveSession as b, handoffFromInside as c, workerDepth as d, checkPaneForWorker as f, markControlsHeld as g, clickrControlsArgv as h, usageContextTokens as i, ageOf as j, ledgerSummary as k, readInbox as l, openPaneForWorker as m, runWorker as n, parseWorkerReport as o, openFollowPane as p, parseRunnerArgs as q, testProvider as r, renderReport as s, printResult as t, sayToWorker as u, itermForClaudeSession as v, discardWorker as w, sessionMapPath as x, itermUuid as y, loadStatuses as z };
4216
- //# sourceMappingURL=run-BFxuNnIJ.mjs.map
4378
+ //# sourceMappingURL=run-CxxZKEZw.mjs.map