@tekmidian/pai 1.0.2 → 1.0.4

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 (96) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/{auto-route-B4azPk4l.mjs → auto-route-21GdHL70.mjs} +2 -2
  3. package/dist/auto-route-C3S2W3Bc.mjs +11 -0
  4. package/dist/{budget-Dod6rnA9.mjs → budget-BrloTOZW.mjs} +1 -1
  5. package/dist/{chain-D-yvET_y.mjs → chain-D7PFur8Y.mjs} +2 -2
  6. package/dist/cli/index.mjs +82 -198
  7. package/dist/{cockpit-actions-BWunx3rY.mjs → cockpit-actions-BfRMr2sm.mjs} +6 -6
  8. package/dist/{cockpit-actions-C8GlTzts.mjs → cockpit-actions-OodH_vx_.mjs} +20 -18
  9. package/dist/{cockpit-memory-vTlFWV7F.mjs → cockpit-memory-teG9M8bG.mjs} +6 -6
  10. package/dist/config/defaults/config.yaml +6 -0
  11. package/dist/{controls-BcKFHeG1.mjs → controls-JLm6g0yP.mjs} +7 -5
  12. package/dist/daemon/index.mjs +23 -23
  13. package/dist/daemon-DeYImF1F.mjs +45 -0
  14. package/dist/daemon-mcp/index.mjs +21 -21
  15. package/dist/{daemon-ColVHwGZ.mjs → daemon-nXanenDM.mjs} +23 -19
  16. package/dist/{detect-9CZNO0yf.mjs → detect-BLKsUOgG.mjs} +2 -2
  17. package/dist/{detect-D1ziFFfA.mjs → detect-Rrimh0xc.mjs} +3 -3
  18. package/dist/{embed-pass-DIWjA68P.mjs → embed-pass-e64AwDCa.mjs} +1 -1
  19. package/dist/{endreason-C577xIQz.mjs → endreason-BC-v05H_.mjs} +17 -3
  20. package/dist/{factory-DjAAsqr_.mjs → factory-B7nv75rC.mjs} +2 -2
  21. package/dist/{factory-Bsib-qDG.mjs → factory-Bs9imVMq.mjs} +2 -2
  22. package/dist/{fallback-DFlItw1Z.mjs → fallback-CBWpp2F2.mjs} +227 -5
  23. package/dist/{health-Dnym-qcT.mjs → health-C4FQmkJn.mjs} +2 -2
  24. package/dist/{helpers-BD6V-p9w.mjs → helpers-DSNK_1KP.mjs} +2 -2
  25. package/dist/{helpers-CMGjy_0N.mjs → helpers-Dz7mjTSw.mjs} +3 -3
  26. package/dist/hooks/capture-all-events.mjs +21 -2
  27. package/dist/hooks/capture-tool-output.mjs +21 -2
  28. package/dist/hooks/worker-pool-host.mjs +167 -124
  29. package/dist/hooks/worker-status-line.mjs +34 -6
  30. package/dist/index.mjs +4 -4
  31. package/dist/{indexer-backend-_a6UNhXJ.mjs → indexer-backend-BdjeL4P8.mjs} +32 -229
  32. package/dist/{ipc-client-CaiGJnSM.mjs → ipc-client-CnYEF31R.mjs} +1 -1
  33. package/dist/{ipc-client-ZRmDKd5Z.mjs → ipc-client-DN7EvoVo.mjs} +1 -1
  34. package/dist/{kill-tree-EWYaEk5v.mjs → kill-tree-DleMNZX3.mjs} +2 -2
  35. package/dist/{kill-tree-BG7dRVtp.mjs → kill-tree-SV6hrIa3.mjs} +2 -2
  36. package/dist/{launch-Jh5NVeNe.mjs → launch-Di7N-J5X.mjs} +2 -2
  37. package/dist/{launch-CXVlZjHt.mjs → launch-DlZTKE3u.mjs} +2 -2
  38. package/dist/{main-config-ops-BEMpuhDz.mjs → main-config-ops-kTXR8Pyv.mjs} +1 -1
  39. package/dist/{main-resolver-3Ns1HPmS.mjs → main-resolver-yp_puSSb.mjs} +5 -5
  40. package/dist/{model-inventory-BFVSNFT3.mjs → model-inventory-h6Z9fN_o.mjs} +1 -1
  41. package/dist/{models-add-BtB3Se6f.mjs → models-add-TVni3A7V.mjs} +22 -22
  42. package/dist/{pai-marker-DurzIbw8.mjs → pai-marker-BcZyJguM.mjs} +2 -2
  43. package/dist/{pane-audit-BQytYa60.mjs → pane-audit-Lqy9N_Ki.mjs} +23 -5
  44. package/dist/{planner-BM27GBfC.mjs → planner-j77ndkBf.mjs} +14 -14
  45. package/dist/{pool-BRvoOkv6.mjs → pool-Dh-q3iJi.mjs} +43 -4
  46. package/dist/{pool-cli-B_YR8_Gl.mjs → pool-cli-BggU8GRp.mjs} +2 -2
  47. package/dist/{pool-cli-DkZTAlSW.mjs → pool-cli-DQ6OzRy2.mjs} +2 -2
  48. package/dist/{postgres-BdBNkL_l.mjs → postgres-BK4FP9Zg.mjs} +1 -1
  49. package/dist/{postgres-C6ti4haA.mjs → postgres-DNIOQijl.mjs} +17 -7
  50. package/dist/{project-setup-CfpApz5o.mjs → project-setup-CBRtFFh0.mjs} +16 -236
  51. package/dist/{providers-CblTFrhz.mjs → providers-C9QC0TtO.mjs} +2 -2
  52. package/dist/{providers-BeDiVEb-.mjs → providers-FvCLzFge.mjs} +2 -2
  53. package/dist/{query-feedback-BRfPtqki.mjs → query-feedback-DN52N9C5.mjs} +1 -1
  54. package/dist/{registrable-C7b6givx.mjs → registrable-BzH4TObg.mjs} +3 -3
  55. package/dist/{registrable-Uzgmfyhz.mjs → registrable-DpyTtajg.mjs} +2 -2
  56. package/dist/{render-Cc2j5QG9.mjs → render-B35bQTE-.mjs} +4 -4
  57. package/dist/{render-CwIrgxLi.mjs → render-C84BqQRC.mjs} +3 -3
  58. package/dist/{root-BWy0c2Lq.mjs → root-C4oXlXS_.mjs} +7 -7
  59. package/dist/{root-wC_6Fx0B.mjs → root-DD1xx_Vu.mjs} +16 -16
  60. package/dist/route-table-FEfDuhIV.mjs +15 -0
  61. package/dist/{routing-BAAST9vT.mjs → routing-DmkheCRH.mjs} +126 -8
  62. package/dist/{routing-CENt4HH1.mjs → routing-f2zulGwD.mjs} +1 -1
  63. package/dist/{run-6Q9kCPem.mjs → run-BwZKBJZZ.mjs} +28 -14
  64. package/dist/{scan-ZQWm-_se.mjs → scan-BBGvU5EB.mjs} +4 -4
  65. package/dist/{session-Bok2PqRS.mjs → session-BAhtXdxj.mjs} +15 -15
  66. package/dist/{session-DVUExUnX.mjs → session-Dn5OJXlg.mjs} +23 -23
  67. package/dist/{session-scan-BJI_ZO8M.mjs → session-scan-B57dNuA4.mjs} +1 -1
  68. package/dist/{session-scan-W-gbwJHM.mjs → session-scan-DUn10MBd.mjs} +2 -2
  69. package/dist/session-usage-CPvXvSkw.mjs +222 -0
  70. package/dist/{sources-ESUkZaWv.mjs → sources-CiE3rZek.mjs} +1 -1
  71. package/dist/{viewer-MWBVJP3u.mjs → viewer-DEySE4c_.mjs} +8 -8
  72. package/dist/{viewer-DcpJwGKE.mjs → viewer-wfKnvnrI.mjs} +6 -6
  73. package/dist/{worker-config-gmAq_-rI.mjs → worker-config-CO5FXLAT.mjs} +21 -21
  74. package/dist/{worker-config-BDYNxbYz.mjs → worker-config-eY5Qy4vl.mjs} +322 -25
  75. package/dist/{worktree-CrnOqTBW.mjs → worktree-CRs2gyg0.mjs} +2 -2
  76. package/dist/{zettelkasten-BzMm8REH.mjs → zettelkasten-_h_tUm2T.mjs} +1 -1
  77. package/dist/{zettelkasten-B_rRRRvD.mjs → zettelkasten-tpCRBYvH.mjs} +2 -2
  78. package/docs/cockpit.md +1 -0
  79. package/docs/images/architecture.png +0 -0
  80. package/gemini-extension.json +1 -1
  81. package/package.json +1 -1
  82. package/pai-plugin.json +1 -1
  83. package/plugins/context-preservation/plugin.json +1 -1
  84. package/plugins/core/plugin.json +1 -1
  85. package/plugins/creative/plugin.json +1 -1
  86. package/plugins/observability/plugin.json +1 -1
  87. package/plugins/productivity/plugin.json +1 -1
  88. package/plugins/semantic-search/plugin.json +1 -1
  89. package/plugins/ui/plugin.json +1 -1
  90. package/plugins/zettelkasten/plugin.json +1 -1
  91. package/src/hooks/ts/capture-all-events.ts +15 -3
  92. package/src/hooks/ts/lib/raw-capture.ts +7 -0
  93. package/src/hooks/ts/post-tool-use/capture-tool-output.ts +13 -3
  94. package/dist/auto-route-BjoMHKyI.mjs +0 -11
  95. package/dist/daemon-N7WhYi6I.mjs +0 -45
  96. package/dist/route-table-B7zpoypi.mjs +0 -15
@@ -9985,7 +9985,7 @@ var init_paths = __esm({
9985
9985
 
9986
9986
  // src/config/claude-json.ts
9987
9987
  import { homedir as homedir3 } from "node:os";
9988
- import { join as join8 } from "node:path";
9988
+ import { join as join8, resolve as resolve3 } from "node:path";
9989
9989
  function claudeJsonPath() {
9990
9990
  return join8(homedir3(), ".claude.json");
9991
9991
  }
@@ -10260,9 +10260,9 @@ function poolPort(config) {
10260
10260
  return config.pool?.port ?? DEFAULT_POOL_PORT;
10261
10261
  }
10262
10262
  function postTaskToPool(port2, task, timeoutMs, path = "/task", handover, handoverWaitMs = 2e4) {
10263
- return new Promise((resolve11) => {
10263
+ return new Promise((resolve12) => {
10264
10264
  let connected = false;
10265
- const fail = (detail) => resolve11({ error: connected ? "claim-error" : "unreachable", detail });
10265
+ const fail = (detail) => resolve12({ error: connected ? "claim-error" : "unreachable", detail });
10266
10266
  const body = JSON.stringify(task);
10267
10267
  const req = httpRequest(
10268
10268
  {
@@ -10279,7 +10279,7 @@ function postTaskToPool(port2, task, timeoutMs, path = "/task", handover, handov
10279
10279
  res.on("end", () => {
10280
10280
  try {
10281
10281
  const resp = JSON.parse(Buffer.concat(chunks).toString("utf8"));
10282
- resolve11(resp.pooled ? { ok: resp } : { miss: resp.reason ?? "refused" });
10282
+ resolve12(resp.pooled ? { ok: resp } : { miss: resp.reason ?? "refused" });
10283
10283
  } catch (e) {
10284
10284
  fail(`unreadable answer: ${e instanceof Error ? e.message : String(e)}`);
10285
10285
  }
@@ -10289,12 +10289,12 @@ function postTaskToPool(port2, task, timeoutMs, path = "/task", handover, handov
10289
10289
  );
10290
10290
  req.setTimeout(timeoutMs, () => {
10291
10291
  req.destroy();
10292
- resolve11({ error: "timeout", detail: `no answer within ${timeoutMs} ms` });
10292
+ resolve12({ error: "timeout", detail: `no answer within ${timeoutMs} ms` });
10293
10293
  });
10294
10294
  req.on("socket", (s) => s.on("connect", () => connected = true));
10295
10295
  req.on("error", (e) => {
10296
10296
  if (e.code === "ECONNREFUSED" && handover?.() && handoverWaitMs > 0) {
10297
- setTimeout(() => void postTaskToPool(port2, task, timeoutMs, path, handover, handoverWaitMs - 300).then(resolve11), 300);
10297
+ setTimeout(() => void postTaskToPool(port2, task, timeoutMs, path, handover, handoverWaitMs - 300).then(resolve12), 300);
10298
10298
  return;
10299
10299
  }
10300
10300
  fail(e.message);
@@ -10303,33 +10303,33 @@ function postTaskToPool(port2, task, timeoutMs, path = "/task", handover, handov
10303
10303
  });
10304
10304
  }
10305
10305
  function poolHostProbe(port2, timeoutMs = 500) {
10306
- return new Promise((resolve11) => {
10306
+ return new Promise((resolve12) => {
10307
10307
  const req = httpRequest({ host: LOOPBACK_HOST, port: port2, path: "/healthz", method: "GET", timeout: timeoutMs }, (res) => {
10308
10308
  res.resume();
10309
- res.on("end", () => resolve11(res.statusCode === 200 ? "up" : "down"));
10310
- res.on("error", () => resolve11("down"));
10309
+ res.on("end", () => resolve12(res.statusCode === 200 ? "up" : "down"));
10310
+ res.on("error", () => resolve12("down"));
10311
10311
  });
10312
10312
  req.on("timeout", () => {
10313
10313
  req.destroy();
10314
- resolve11("timeout");
10314
+ resolve12("timeout");
10315
10315
  });
10316
- req.on("error", () => resolve11("down"));
10316
+ req.on("error", () => resolve12("down"));
10317
10317
  req.end();
10318
10318
  });
10319
10319
  }
10320
10320
  function poolHostPid(port2, timeoutMs = 500) {
10321
- return new Promise((resolve11) => {
10321
+ return new Promise((resolve12) => {
10322
10322
  const req = httpRequest({ host: LOOPBACK_HOST, port: port2, path: "/healthz", method: "GET", timeout: timeoutMs }, (res) => {
10323
10323
  res.resume();
10324
10324
  const pid = parseInt(String(res.headers["x-pool-host-pid"] ?? ""), 10);
10325
- res.on("end", () => resolve11(res.statusCode === 200 ? Number.isFinite(pid) ? pid : 0 : null));
10326
- res.on("error", () => resolve11(null));
10325
+ res.on("end", () => resolve12(res.statusCode === 200 ? Number.isFinite(pid) ? pid : 0 : null));
10326
+ res.on("error", () => resolve12(null));
10327
10327
  });
10328
10328
  req.on("timeout", () => {
10329
10329
  req.destroy();
10330
- resolve11(null);
10330
+ resolve12(null);
10331
10331
  });
10332
- req.on("error", () => resolve11(null));
10332
+ req.on("error", () => resolve12(null));
10333
10333
  req.end();
10334
10334
  });
10335
10335
  }
@@ -11283,7 +11283,7 @@ var init_wait_on = __esm({
11283
11283
  // src/workers/report.ts
11284
11284
  import { execFileSync as execFileSync7 } from "node:child_process";
11285
11285
  import { statSync as statSync5 } from "node:fs";
11286
- import { isAbsolute, relative, resolve as resolve3 } from "node:path";
11286
+ import { isAbsolute, relative, resolve as resolve4 } from "node:path";
11287
11287
  function ag2ReportBlock() {
11288
11288
  const spec = ag2Spec();
11289
11289
  return [
@@ -11446,7 +11446,7 @@ function verifyReportChanges(changed, cwd, startMs) {
11446
11446
  const raw = (ch.path ?? "").trim();
11447
11447
  if (!raw) continue;
11448
11448
  if (/^delete:/i.test(raw)) continue;
11449
- const abs = isAbsolute(raw) ? raw : resolve3(cwd, raw);
11449
+ const abs = isAbsolute(raw) ? raw : resolve4(cwd, raw);
11450
11450
  let mtimeMs;
11451
11451
  try {
11452
11452
  mtimeMs = statSync5(abs).mtimeMs;
@@ -12867,14 +12867,14 @@ function anthropicUsageUrl() {
12867
12867
  return new URL("/api/oauth/usage", loadConfig().router.claudeUpstream);
12868
12868
  }
12869
12869
  function getJson(url, headers, timeoutMs = 5e3) {
12870
- return new Promise((resolve11, reject) => {
12870
+ return new Promise((resolve12, reject) => {
12871
12871
  const mod = url.protocol === "https:" ? https : http;
12872
12872
  const rq = mod.get(url, { headers, timeout: timeoutMs }, (res) => {
12873
12873
  let t = "";
12874
12874
  res.on("data", (c) => t += c);
12875
12875
  res.on(
12876
12876
  "end",
12877
- () => res.statusCode === 200 ? resolve11(t) : reject(new HttpError(res.statusCode ?? 0, res.statusCode === 429 ? parseRetryAfter(res.headers["retry-after"]) : void 0))
12877
+ () => res.statusCode === 200 ? resolve12(t) : reject(new HttpError(res.statusCode ?? 0, res.statusCode === 429 ? parseRetryAfter(res.headers["retry-after"]) : void 0))
12878
12878
  );
12879
12879
  });
12880
12880
  rq.on("timeout", () => rq.destroy(new Error("timeout")));
@@ -12882,7 +12882,7 @@ function getJson(url, headers, timeoutMs = 5e3) {
12882
12882
  });
12883
12883
  }
12884
12884
  function sh(cmd, args) {
12885
- return new Promise((resolve11) => execFile(cmd, args, { timeout: 4e3 }, (_e, out) => resolve11(String(out ?? "").trim())));
12885
+ return new Promise((resolve12) => execFile(cmd, args, { timeout: 4e3 }, (_e, out) => resolve12(String(out ?? "").trim())));
12886
12886
  }
12887
12887
  async function anthropicToken() {
12888
12888
  for (const args of [["-a", process.env.USER ?? ""], []]) {
@@ -16965,7 +16965,7 @@ var require_dist2 = __commonJS({
16965
16965
  function parse4(stream, callback) {
16966
16966
  const parser = new parser_1.Parser();
16967
16967
  stream.on("data", (buffer) => parser.parse(buffer, callback));
16968
- return new Promise((resolve11) => stream.on("end", () => resolve11()));
16968
+ return new Promise((resolve12) => stream.on("end", () => resolve12()));
16969
16969
  }
16970
16970
  exports.parse = parse4;
16971
16971
  }
@@ -17692,12 +17692,12 @@ var require_client = __commonJS({
17692
17692
  this._connect(callback);
17693
17693
  return;
17694
17694
  }
17695
- return new this._Promise((resolve11, reject) => {
17695
+ return new this._Promise((resolve12, reject) => {
17696
17696
  this._connect((error) => {
17697
17697
  if (error) {
17698
17698
  reject(error);
17699
17699
  } else {
17700
- resolve11(this);
17700
+ resolve12(this);
17701
17701
  }
17702
17702
  });
17703
17703
  });
@@ -18039,8 +18039,8 @@ var require_client = __commonJS({
18039
18039
  readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
18040
18040
  query = new Query2(config, values, callback);
18041
18041
  if (!query.callback) {
18042
- result = new this._Promise((resolve11, reject) => {
18043
- query.callback = (err, res) => err ? reject(err) : resolve11(res);
18042
+ result = new this._Promise((resolve12, reject) => {
18043
+ query.callback = (err, res) => err ? reject(err) : resolve12(res);
18044
18044
  }).catch((err) => {
18045
18045
  Error.captureStackTrace(err);
18046
18046
  throw err;
@@ -18113,8 +18113,8 @@ var require_client = __commonJS({
18113
18113
  if (cb) {
18114
18114
  this.connection.once("end", cb);
18115
18115
  } else {
18116
- return new this._Promise((resolve11) => {
18117
- this.connection.once("end", resolve11);
18116
+ return new this._Promise((resolve12) => {
18117
+ this.connection.once("end", resolve12);
18118
18118
  });
18119
18119
  }
18120
18120
  }
@@ -18163,8 +18163,8 @@ var require_pg_pool = __commonJS({
18163
18163
  const cb = function(err, client) {
18164
18164
  err ? rej(err) : res(client);
18165
18165
  };
18166
- const result = new Promise2(function(resolve11, reject) {
18167
- res = resolve11;
18166
+ const result = new Promise2(function(resolve12, reject) {
18167
+ res = resolve12;
18168
18168
  rej = reject;
18169
18169
  }).catch((err) => {
18170
18170
  Error.captureStackTrace(err);
@@ -18585,8 +18585,8 @@ var require_query2 = __commonJS({
18585
18585
  NativeQuery.prototype._getPromise = function() {
18586
18586
  if (this._promise) return this._promise;
18587
18587
  this._promise = new Promise(
18588
- function(resolve11, reject) {
18589
- this._once("end", resolve11);
18588
+ function(resolve12, reject) {
18589
+ this._once("end", resolve12);
18590
18590
  this._once("error", reject);
18591
18591
  }.bind(this)
18592
18592
  );
@@ -18758,12 +18758,12 @@ var require_client2 = __commonJS({
18758
18758
  this._connect(callback);
18759
18759
  return;
18760
18760
  }
18761
- return new this._Promise((resolve11, reject) => {
18761
+ return new this._Promise((resolve12, reject) => {
18762
18762
  this._connect((error) => {
18763
18763
  if (error) {
18764
18764
  reject(error);
18765
18765
  } else {
18766
- resolve11(this);
18766
+ resolve12(this);
18767
18767
  }
18768
18768
  });
18769
18769
  });
@@ -18787,8 +18787,8 @@ var require_client2 = __commonJS({
18787
18787
  query = new NativeQuery(config, values, callback);
18788
18788
  if (!query.callback) {
18789
18789
  let resolveOut, rejectOut;
18790
- result = new this._Promise((resolve11, reject) => {
18791
- resolveOut = resolve11;
18790
+ result = new this._Promise((resolve12, reject) => {
18791
+ resolveOut = resolve12;
18792
18792
  rejectOut = reject;
18793
18793
  }).catch((err) => {
18794
18794
  Error.captureStackTrace(err);
@@ -18844,8 +18844,8 @@ var require_client2 = __commonJS({
18844
18844
  }
18845
18845
  let result;
18846
18846
  if (!cb) {
18847
- result = new this._Promise(function(resolve11, reject) {
18848
- cb = (err) => err ? reject(err) : resolve11();
18847
+ result = new this._Promise(function(resolve12, reject) {
18848
+ cb = (err) => err ? reject(err) : resolve12();
18849
18849
  });
18850
18850
  }
18851
18851
  this.native.end(function() {
@@ -20294,7 +20294,7 @@ function chunkId(projectId, path, chunkIndex, startLine, endLine) {
20294
20294
  return createHash4("sha256").update(`${projectId}:${path}:${chunkIndex}:${startLine}:${endLine}`).digest("hex");
20295
20295
  }
20296
20296
  function yieldToEventLoop() {
20297
- return new Promise((resolve11) => setTimeout(resolve11, 10));
20297
+ return new Promise((resolve12) => setTimeout(resolve12, 10));
20298
20298
  }
20299
20299
  function walkMdFiles(dir, acc, cap = MAX_FILES_PER_PROJECT, depth = 0) {
20300
20300
  const results = acc ?? [];
@@ -20935,6 +20935,17 @@ var init_kg_triples = __esm({
20935
20935
  async function ensureObservationTables(pool) {
20936
20936
  if (_tablesEnsured) return;
20937
20937
  await pool.query(SCHEMA_SQL);
20938
+ const colCheck = await pool.query(
20939
+ `SELECT column_name FROM information_schema.columns
20940
+ WHERE table_name = 'pai_observations' AND column_name IN ('source', 'fidelity')`
20941
+ );
20942
+ const existing = new Set(colCheck.rows.map((r) => r.column_name));
20943
+ if (!existing.has("source")) {
20944
+ await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS source TEXT");
20945
+ }
20946
+ if (!existing.has("fidelity")) {
20947
+ await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS fidelity TEXT");
20948
+ }
20938
20949
  _tablesEnsured = true;
20939
20950
  }
20940
20951
  async function ensureSkillTelemetryTable(pool) {
@@ -20962,8 +20973,9 @@ async function storeObservation(pool, obs) {
20962
20973
  const result = await pool.query(
20963
20974
  `INSERT INTO pai_observations
20964
20975
  (session_id, project_id, project_slug, type, title, narrative,
20965
- tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash)
20966
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb, $10::jsonb, $11::jsonb, $12)
20976
+ tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash,
20977
+ source, fidelity)
20978
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb, $10::jsonb, $11::jsonb, $12, $13, $14)
20967
20979
  RETURNING id`,
20968
20980
  [
20969
20981
  obs.session_id,
@@ -20977,7 +20989,9 @@ async function storeObservation(pool, obs) {
20977
20989
  JSON.stringify(obs.files_read),
20978
20990
  JSON.stringify(obs.files_modified),
20979
20991
  JSON.stringify(obs.concepts),
20980
- hash
20992
+ hash,
20993
+ obs.source ?? null,
20994
+ obs.fidelity ?? null
20981
20995
  ]
20982
20996
  );
20983
20997
  return result.rows[0]?.id ?? null;
@@ -21019,7 +21033,7 @@ async function queryObservations(pool, opts = {}) {
21019
21033
  `SELECT id, session_id, project_id, project_slug, type, title, narrative,
21020
21034
  tool_name, tool_input_summary,
21021
21035
  files_read, files_modified, concepts,
21022
- content_hash, created_at
21036
+ content_hash, source, fidelity, created_at
21023
21037
  FROM pai_observations
21024
21038
  ${where}
21025
21039
  ORDER BY created_at DESC
@@ -21034,7 +21048,7 @@ async function queryRecentObservations(pool, projectId, limit) {
21034
21048
  `SELECT id, session_id, project_id, project_slug, type, title, narrative,
21035
21049
  tool_name, tool_input_summary,
21036
21050
  files_read, files_modified, concepts,
21037
- content_hash, created_at
21051
+ content_hash, source, fidelity, created_at
21038
21052
  FROM pai_observations
21039
21053
  WHERE project_id = $1
21040
21054
  ORDER BY created_at DESC
@@ -21049,7 +21063,7 @@ async function querySessionObservations(pool, sessionId) {
21049
21063
  `SELECT id, session_id, project_id, project_slug, type, title, narrative,
21050
21064
  tool_name, tool_input_summary,
21051
21065
  files_read, files_modified, concepts,
21052
- content_hash, created_at
21066
+ content_hash, source, fidelity, created_at
21053
21067
  FROM pai_observations
21054
21068
  WHERE session_id = $1
21055
21069
  ORDER BY created_at ASC`,
@@ -21219,6 +21233,8 @@ CREATE TABLE IF NOT EXISTS pai_observations (
21219
21233
  files_modified JSONB DEFAULT '[]'::jsonb,
21220
21234
  concepts JSONB DEFAULT '[]'::jsonb,
21221
21235
  content_hash TEXT,
21236
+ source TEXT,
21237
+ fidelity TEXT,
21222
21238
  created_at TIMESTAMPTZ DEFAULT NOW()
21223
21239
  );
21224
21240
 
@@ -22182,7 +22198,7 @@ var init_ntfy = __esm({
22182
22198
  import { connect } from "node:net";
22183
22199
  import { randomUUID } from "node:crypto";
22184
22200
  function callHub(method, params) {
22185
- return new Promise((resolve11) => {
22201
+ return new Promise((resolve12) => {
22186
22202
  let done = false;
22187
22203
  let buffer = "";
22188
22204
  let timer = null;
@@ -22197,7 +22213,7 @@ function callHub(method, params) {
22197
22213
  socket?.destroy();
22198
22214
  } catch {
22199
22215
  }
22200
- resolve11(ok);
22216
+ resolve12(ok);
22201
22217
  }
22202
22218
  const socket = connect(hubSocket(), () => {
22203
22219
  const request = {
@@ -22277,14 +22293,14 @@ var init_macos = __esm({
22277
22293
  payload.message,
22278
22294
  title
22279
22295
  ];
22280
- return new Promise((resolve11) => {
22296
+ return new Promise((resolve12) => {
22281
22297
  const child = spawn("osascript", args, {
22282
22298
  detached: true,
22283
22299
  stdio: "ignore"
22284
22300
  });
22285
22301
  child.unref();
22286
- child.on("error", () => resolve11(false));
22287
- setTimeout(() => resolve11(true), 200);
22302
+ child.on("error", () => resolve12(false));
22303
+ setTimeout(() => resolve12(true), 200);
22288
22304
  });
22289
22305
  } catch {
22290
22306
  return false;
@@ -22802,13 +22818,13 @@ var require_backup = __commonJS({
22802
22818
  var runBackup = (backup, handler) => {
22803
22819
  let rate = 0;
22804
22820
  let useDefault = true;
22805
- return new Promise((resolve11, reject) => {
22821
+ return new Promise((resolve12, reject) => {
22806
22822
  setImmediate(function step() {
22807
22823
  try {
22808
22824
  const progress = backup.transfer(rate);
22809
22825
  if (!progress.remainingPages) {
22810
22826
  backup.close();
22811
- resolve11(progress);
22827
+ resolve12(progress);
22812
22828
  return;
22813
22829
  }
22814
22830
  if (useDefault) {
@@ -26553,15 +26569,15 @@ __export(detect_exports, {
26553
26569
  formatDetection: () => formatDetection,
26554
26570
  formatDetectionJson: () => formatDetectionJson
26555
26571
  });
26556
- import { resolve as resolve4 } from "node:path";
26572
+ import { resolve as resolve5 } from "node:path";
26557
26573
  async function detectProject(cwd) {
26558
- const target = resolve4(cwd ?? process.cwd());
26574
+ const target = resolve5(cwd ?? process.cwd());
26559
26575
  const backend = await getRegistryBackend();
26560
26576
  const projects = await backend.listProjectsByPathLengthDesc({ excludeArchived: true });
26561
26577
  let matched = null;
26562
26578
  let matchType = "exact";
26563
26579
  for (const p of projects) {
26564
- const root = resolve4(p.root_path);
26580
+ const root = resolve5(p.root_path);
26565
26581
  if (target === root) {
26566
26582
  matched = p;
26567
26583
  matchType = "exact";
@@ -26576,7 +26592,7 @@ async function detectProject(cwd) {
26576
26592
  if (!matched) return null;
26577
26593
  const sessionCount = await backend.countSessionsForProject(matched.id);
26578
26594
  const lastDate = await backend.getMostRecentSessionDate(matched.id);
26579
- const relative4 = matchType === "parent" ? target.slice(resolve4(matched.root_path).length + 1) : null;
26595
+ const relative4 = matchType === "parent" ? target.slice(resolve5(matched.root_path).length + 1) : null;
26580
26596
  return {
26581
26597
  id: matched.id,
26582
26598
  slug: matched.slug,
@@ -26632,7 +26648,7 @@ var init_detect = __esm({
26632
26648
  });
26633
26649
 
26634
26650
  // src/cli/lib/utils.ts
26635
- import { resolve as resolve5, basename as basename6, join as join30 } from "node:path";
26651
+ import { resolve as resolve6, basename as basename6, join as join30 } from "node:path";
26636
26652
  import { mkdirSync as mkdirSync21, existsSync as existsSync31, writeFileSync as writeFileSync18, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
26637
26653
  function encIndex(entries) {
26638
26654
  let idx = indexes.get(entries);
@@ -27711,6 +27727,16 @@ var init_route_table = __esm({
27711
27727
  }
27712
27728
  });
27713
27729
 
27730
+ // src/router/cockpit-auth.ts
27731
+ var init_cockpit_auth = __esm({
27732
+ "src/router/cockpit-auth.ts"() {
27733
+ "use strict";
27734
+ init_pai_home();
27735
+ init_loopback();
27736
+ init_timeouts();
27737
+ }
27738
+ });
27739
+
27714
27740
  // src/router/router.ts
27715
27741
  var routerPort;
27716
27742
  var init_router2 = __esm({
@@ -27730,6 +27756,7 @@ var init_router2 = __esm({
27730
27756
  init_local_instances();
27731
27757
  init_route_table();
27732
27758
  init_loopback_guard();
27759
+ init_cockpit_auth();
27733
27760
  routerPort = () => loadConfig().router.port;
27734
27761
  }
27735
27762
  });
@@ -27968,11 +27995,11 @@ var init_run_env = __esm({
27968
27995
  // src/router/supervisor.ts
27969
27996
  import { connect as connect2 } from "node:net";
27970
27997
  function probeRouter(port2 = routerPort(), timeoutMs = LOCAL_PROBE_TIMEOUT_MS) {
27971
- return new Promise((resolve11) => {
27998
+ return new Promise((resolve12) => {
27972
27999
  const sock = connect2({ host: LOOPBACK_HOST, port: port2 });
27973
28000
  const done = (up) => {
27974
28001
  sock.destroy();
27975
- resolve11(up);
28002
+ resolve12(up);
27976
28003
  };
27977
28004
  sock.setTimeout(timeoutMs, () => done(false));
27978
28005
  sock.once("connect", () => done(true));
@@ -28014,6 +28041,13 @@ function requestKill(logDir2, ledger, id, by = callerDescription(), forced = fal
28014
28041
  writeFileAtomic(killMarkerPath(logDir2, id), JSON.stringify(req));
28015
28042
  appendLedger(ledger, "WORKER-KILL", { id, by, pid: req.pid, ppid: req.ppid, cwd: req.cwd, ...forced ? { forced: 1 } : {}, ...reason ? { reason } : {} });
28016
28043
  }
28044
+ function peekMarker(logDir2, id) {
28045
+ try {
28046
+ return JSON.parse(readFileSync36(killMarkerPath(logDir2, id), "utf8"));
28047
+ } catch {
28048
+ return null;
28049
+ }
28050
+ }
28017
28051
  function readMarker(logDir2, id) {
28018
28052
  const p = killMarkerPath(logDir2, id);
28019
28053
  if (!existsSync36(p)) return null;
@@ -28047,8 +28081,11 @@ function parentInfo() {
28047
28081
  function decideEndReason(a) {
28048
28082
  if (a.timedOut) return { reason: "deadline" };
28049
28083
  if (a.loopStopped) return { reason: "loop-stopped" };
28050
- if (!a.signal) return { reason: "exit" };
28051
- const marker = readMarker(a.logDir, a.id);
28084
+ const marker = a.signal || peekMarker(a.logDir, a.id)?.by === "pane audit" ? readMarker(a.logDir, a.id) : null;
28085
+ if (!a.signal && !marker) return { reason: "exit" };
28086
+ if (!a.signal && marker) {
28087
+ return { reason: "pai-worker-kill", by: marker.by, note: `killed by ${marker.by}${marker.reason ? `: ${marker.reason}` : ""}`, ...marker.reason ? { killReason: marker.reason } : {}, forced: true };
28088
+ }
28052
28089
  if (marker) {
28053
28090
  return {
28054
28091
  reason: "pai-worker-kill",
@@ -28525,7 +28562,7 @@ function sayToWorker(logDir2, id, text, timeoutMs = 4e3) {
28525
28562
  new Error(`worker ${id} has no operator socket (${path}) \u2014 it may predate this PAI version`)
28526
28563
  );
28527
28564
  }
28528
- return new Promise((resolve11, reject) => {
28565
+ return new Promise((resolve12, reject) => {
28529
28566
  const sock = connect3(path);
28530
28567
  const fail = (e) => {
28531
28568
  sock.destroy();
@@ -28539,7 +28576,7 @@ function sayToWorker(logDir2, id, text, timeoutMs = 4e3) {
28539
28576
  sock.once("data", (d) => {
28540
28577
  sock.end();
28541
28578
  const reply = d.toString("utf8").trim();
28542
- if (reply === "ok") resolve11("ok");
28579
+ if (reply === "ok") resolve12("ok");
28543
28580
  else reject(new Error(`worker ${id} did not take the message: ${reply.replace(/^err /, "") || "no acknowledgement"}`));
28544
28581
  });
28545
28582
  sock.once("close", () => fail(new Error("connection closed before the worker acknowledged")));
@@ -28657,10 +28694,10 @@ var init_pending = __esm({
28657
28694
  // src/workers/worktree.ts
28658
28695
  import { execFile as execFile2, execFileSync as execFileSync11, spawnSync as spawnSync3 } from "node:child_process";
28659
28696
  import { existsSync as existsSync44, lstatSync, mkdirSync as mkdirSync28, readFileSync as readFileSync43, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync23, readdirSync as readdirSync13, readlinkSync, realpathSync as realpathSync2, rmSync as rmSync9, statSync as statSync15 } from "node:fs";
28660
- import { basename as basename8, dirname as dirname22, isAbsolute as isAbsolute2, join as join43, resolve as resolve6, sep as sep2 } from "node:path";
28697
+ import { basename as basename8, dirname as dirname22, isAbsolute as isAbsolute2, join as join43, resolve as resolve7, sep as sep2 } from "node:path";
28661
28698
  import { tmpdir as tmpdir3, platform } from "node:os";
28662
28699
  function isSlotWorktree(dir) {
28663
- return basename8(dirname22(resolve6(dir))) === "slots";
28700
+ return basename8(dirname22(resolve7(dir))) === "slots";
28664
28701
  }
28665
28702
  function worktreesDir(logDir2) {
28666
28703
  return join43(logDir2, "worktrees");
@@ -28783,7 +28820,7 @@ function isPaiBookkeepingPath(path) {
28783
28820
  function ensureScratchExcluded(cwd) {
28784
28821
  try {
28785
28822
  const rel = git(cwd, ["rev-parse", "--git-path", "info/exclude"]);
28786
- const file = isAbsolute2(rel) ? rel : resolve6(cwd, rel);
28823
+ const file = isAbsolute2(rel) ? rel : resolve7(cwd, rel);
28787
28824
  const cur = existsSync44(file) ? readFileSync43(file, "utf8") : "";
28788
28825
  if (cur.split("\n").some((l) => l.trim() === ".pai-scratch/")) return;
28789
28826
  mkdirSync28(dirname22(file), { recursive: true });
@@ -28981,7 +29018,7 @@ function transcriptWrites(logDir2, id, dir) {
28981
29018
  } catch {
28982
29019
  return [];
28983
29020
  }
28984
- const roots = [resolve6(dir)];
29021
+ const roots = [resolve7(dir)];
28985
29022
  try {
28986
29023
  roots.push(realpathSync2(dir));
28987
29024
  } catch {
@@ -28996,7 +29033,7 @@ function transcriptWrites(logDir2, id, dir) {
28996
29033
  if (b?.type !== "tool_use" || !["Write", "Edit", "MultiEdit", "NotebookEdit"].includes(b.name ?? "")) continue;
28997
29034
  const fp = b.input?.file_path;
28998
29035
  if (typeof fp !== "string") continue;
28999
- const abs = resolve6(fp);
29036
+ const abs = resolve7(fp);
29000
29037
  if (roots.some((r) => abs.startsWith(r + sep2))) out.add(abs);
29001
29038
  }
29002
29039
  } catch {
@@ -29025,7 +29062,7 @@ function worktreeKnowledge(logDir2, id, dir, base) {
29025
29062
  } catch {
29026
29063
  }
29027
29064
  k.ignored = ignoredKnowledge(dir);
29028
- const root = resolve6(dir);
29065
+ const root = resolve7(dir);
29029
29066
  for (const abs of transcriptWrites(logDir2, id, dir)) {
29030
29067
  if (existsSync44(abs)) continue;
29031
29068
  const rel = abs.startsWith(root + sep2) ? abs.slice(root.length + 1) : abs;
@@ -29066,7 +29103,7 @@ function symlinkEscapesWorktree(wtDir, relPath) {
29066
29103
  }
29067
29104
  if (!stat.isSymbolicLink()) return false;
29068
29105
  const target = readlinkSync(full);
29069
- const resolvedTarget = isAbsolute2(target) ? target : resolve6(dirname22(full), target);
29106
+ const resolvedTarget = isAbsolute2(target) ? target : resolve7(dirname22(full), target);
29070
29107
  const realTarget = existsSync44(resolvedTarget) ? realpathSync2(resolvedTarget) : resolvedTarget;
29071
29108
  const realWtDir = realpathSync2(wtDir);
29072
29109
  return realTarget !== realWtDir && !realTarget.startsWith(realWtDir + sep2);
@@ -29321,7 +29358,7 @@ function mergeWorker(logDir2, id, opts = {}) {
29321
29358
  let files = [];
29322
29359
  let inProgress = false;
29323
29360
  try {
29324
- inProgress = existsSync44(resolve6(st.cwd, git(st.cwd, ["rev-parse", "--git-path", "MERGE_HEAD"])));
29361
+ inProgress = existsSync44(resolve7(st.cwd, git(st.cwd, ["rev-parse", "--git-path", "MERGE_HEAD"])));
29325
29362
  if (inProgress) files = git(st.cwd, ["diff", "--name-only", "--diff-filter=U"]).split("\n").filter(Boolean);
29326
29363
  } catch {
29327
29364
  }
@@ -29521,7 +29558,7 @@ function branchArchived(repo, branchRef, refs) {
29521
29558
  function commonDir(dir) {
29522
29559
  try {
29523
29560
  const raw = git(dir, ["rev-parse", "--git-common-dir"]);
29524
- return isAbsolute2(raw) ? raw : resolve6(dir, raw);
29561
+ return isAbsolute2(raw) ? raw : resolve7(dir, raw);
29525
29562
  } catch {
29526
29563
  return null;
29527
29564
  }
@@ -29613,7 +29650,7 @@ function archiveWorktree(logDir2, id, dir, branch) {
29613
29650
  let repo;
29614
29651
  try {
29615
29652
  const raw = git(dir, ["rev-parse", "--git-common-dir"]);
29616
- repo = isAbsolute2(raw) ? raw : resolve6(dir, raw);
29653
+ repo = isAbsolute2(raw) ? raw : resolve7(dir, raw);
29617
29654
  } catch {
29618
29655
  throw new Error("not a git worktree");
29619
29656
  }
@@ -29713,7 +29750,7 @@ function archiveSlotBranch(logDir2, st, tree, dryRun, report, out) {
29713
29750
  let repo;
29714
29751
  try {
29715
29752
  const raw = git(st.cwd, ["rev-parse", "--git-common-dir"]);
29716
- repo = isAbsolute2(raw) ? raw : resolve6(st.cwd, raw);
29753
+ repo = isAbsolute2(raw) ? raw : resolve7(st.cwd, raw);
29717
29754
  git(repo, ["rev-parse", "--verify", "-q", `refs/heads/${tree.branch}`]);
29718
29755
  } catch {
29719
29756
  return;
@@ -29762,13 +29799,13 @@ function gcForeign(logDir2, repo, owned, dryRun, report, out, archive) {
29762
29799
  } catch {
29763
29800
  return;
29764
29801
  }
29765
- const pai2 = resolve6(logDir2);
29802
+ const pai2 = resolve7(logDir2);
29766
29803
  const blocks = raw.split("\n\n").map((b) => b.trim()).filter(Boolean);
29767
29804
  blocks.slice(1).forEach((block) => {
29768
29805
  const field = (k) => block.split("\n").find((l) => l.startsWith(k + " "))?.slice(k.length + 1);
29769
29806
  const dir = field("worktree");
29770
29807
  if (!dir || !existsSync44(dir) || block.includes("\nprunable")) return;
29771
- const real = resolve6(dir);
29808
+ const real = resolve7(dir);
29772
29809
  if (owned.has(real) || real === pai2 || real.startsWith(pai2 + sep2) || isSlotWorktree(real)) return;
29773
29810
  const ref = field("branch");
29774
29811
  const branch = ref?.replace(/^refs\/heads\//, "");
@@ -29788,7 +29825,7 @@ function realpathOr(p) {
29788
29825
  try {
29789
29826
  return realpathSync2(p);
29790
29827
  } catch {
29791
- return resolve6(p);
29828
+ return resolve7(p);
29792
29829
  }
29793
29830
  }
29794
29831
  function gcScratchTrees(statuses, owned, extraRepos, out, archive) {
@@ -29894,7 +29931,7 @@ function gcWorktrees(logDir2, olderThanHours = 24, dryRun = false, now = Date.no
29894
29931
  const out = [];
29895
29932
  const root = worktreesDir(logDir2);
29896
29933
  const statuses = loadStatuses(logDir2);
29897
- const owned = new Set(statuses.map((s) => ownedTree(s)?.dir).filter((d) => !!d).map((d) => resolve6(d)));
29934
+ const owned = new Set(statuses.map((s) => ownedTree(s)?.dir).filter((d) => !!d).map((d) => resolve7(d)));
29898
29935
  const archive = (id, dir, branch, st) => {
29899
29936
  const target = `refs/pai-archive/${id}`;
29900
29937
  if (!isRealWorktree(dir)) return void out.push({ id, skipped: "not a worktree" });
@@ -29968,7 +30005,7 @@ function gcWorktrees(logDir2, olderThanHours = 24, dryRun = false, now = Date.no
29968
30005
  if (existsSync44(root)) {
29969
30006
  for (const ent of readdirSync13(root, { withFileTypes: true })) {
29970
30007
  const dir = join43(root, ent.name);
29971
- if (!ent.isDirectory() || owned.has(resolve6(dir)) || isSlotWorktree(dir) || ent.name.startsWith("spare-") || landed.has(realpathOr(dir))) continue;
30008
+ if (!ent.isDirectory() || owned.has(resolve7(dir)) || isSlotWorktree(dir) || ent.name.startsWith("spare-") || landed.has(realpathOr(dir))) continue;
29972
30009
  try {
29973
30010
  if (Math.floor(statSync15(dir).mtimeMs) > cutoff) continue;
29974
30011
  } catch {
@@ -30050,7 +30087,7 @@ __export(aibroker_client_exports, {
30050
30087
  import { connect as connect4 } from "node:net";
30051
30088
  import { randomUUID as randomUUID2 } from "node:crypto";
30052
30089
  function callAiBroker(method, params = {}, timeoutMs = 8e3, caller = {}) {
30053
- return new Promise((resolve11, reject) => {
30090
+ return new Promise((resolve12, reject) => {
30054
30091
  const socketPath = brokerSocket();
30055
30092
  let done = false;
30056
30093
  let buffer = "";
@@ -30067,7 +30104,7 @@ function callAiBroker(method, params = {}, timeoutMs = 8e3, caller = {}) {
30067
30104
  } catch {
30068
30105
  }
30069
30106
  if (err) reject(err);
30070
- else resolve11(value);
30107
+ else resolve12(value);
30071
30108
  }
30072
30109
  const socket = connect4(socketPath, () => {
30073
30110
  const request = {
@@ -30443,7 +30480,7 @@ var init_kill_tree = __esm({
30443
30480
  // src/workers/reap.ts
30444
30481
  import { execFileSync as execFileSync13 } from "node:child_process";
30445
30482
  import { existsSync as existsSync45, readdirSync as readdirSync14, realpathSync as realpathSync3 } from "node:fs";
30446
- import { join as join45, resolve as resolve7, sep as sep3 } from "node:path";
30483
+ import { join as join45, resolve as resolve8, sep as sep3 } from "node:path";
30447
30484
  function commandOf(pid) {
30448
30485
  try {
30449
30486
  return execFileSync13("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
@@ -30775,12 +30812,12 @@ function proxyPidPath(logDir2) {
30775
30812
  return join47(logDir2, "proxy.pid");
30776
30813
  }
30777
30814
  function proxyListening(port2 = proxyPort(), timeoutMs = 400) {
30778
- return new Promise((resolve11) => {
30815
+ return new Promise((resolve12) => {
30779
30816
  const sock = connect5({ port: port2, host: HOST });
30780
30817
  const done = (ok) => {
30781
30818
  sock.removeAllListeners();
30782
30819
  sock.destroy();
30783
- resolve11(ok);
30820
+ resolve12(ok);
30784
30821
  };
30785
30822
  sock.setTimeout(timeoutMs, () => done(false));
30786
30823
  sock.once("connect", () => done(true));
@@ -30957,6 +30994,7 @@ function fireDeadline(logDir2, status, ledger, limit) {
30957
30994
  status.last = what;
30958
30995
  saveStatus(logDir2, status);
30959
30996
  appendLedger(ledger, "WORKER-DEADLINE", { id: status.id, minutes: limit.minutes, waitedMin: waited });
30997
+ appendStopEvent(logDir2, status.id, { killed_by: "deadline", forced: false, reason: `${what} (timer: --max-minutes/--deadline, armed at spawn)` });
30960
30998
  void killTree(logDir2, status.id, { skipRoot: true, by: "deadline", reason: `parent worker ${what}` }).catch(() => void 0);
30961
30999
  }
30962
31000
  function trackBlocked(logDir2, status, limit) {
@@ -31032,6 +31070,10 @@ async function finaliseRun(f) {
31032
31070
  }
31033
31071
  const end = decideEndReason({ logDir: logDir2, id: wid, timedOut: f.timedOut !== void 0, loopStopped: !!loopStop });
31034
31072
  status.endReason = end.reason;
31073
+ if (end.reason === "pai-worker-kill" && !f.timedOut && end.killReason && !succeeded) {
31074
+ status.last = shortText(end.killReason, 90);
31075
+ report = { ...report ?? {}, result: report?.result ?? "-", why: end.killReason, notes: [end.killReason, report?.notes ?? f.fallbackText].filter(Boolean).join("\n") };
31076
+ }
31035
31077
  status.claimsContinue = report?.result === "~";
31036
31078
  saveStatus(logDir2, status);
31037
31079
  appendLedger(ledger, "WORKER-END", { id: wid, ...f.end, rc, secs: f.secs, ...endFields(end) });
@@ -31092,9 +31134,9 @@ async function reaskAg2Report(a) {
31092
31134
  proc.stdout.on("data", (chunk) => {
31093
31135
  out += chunk.toString("utf8");
31094
31136
  });
31095
- await new Promise((resolve11) => {
31096
- proc.on("error", () => resolve11());
31097
- proc.on("close", () => resolve11());
31137
+ await new Promise((resolve12) => {
31138
+ proc.on("error", () => resolve12());
31139
+ proc.on("close", () => resolve12());
31098
31140
  });
31099
31141
  clearTimeout(timer);
31100
31142
  return resultFromOutput(out);
@@ -31623,16 +31665,16 @@ async function openOwnedPane(o) {
31623
31665
  let session;
31624
31666
  let sock = null;
31625
31667
  let server;
31626
- const connected = new Promise((resolve11) => {
31668
+ const connected = new Promise((resolve12) => {
31627
31669
  server = createServer2((s2) => {
31628
31670
  sock = s2;
31629
31671
  server.close();
31630
- resolve11(s2);
31672
+ resolve12(s2);
31631
31673
  });
31632
31674
  });
31633
- await new Promise((resolve11, reject) => {
31675
+ await new Promise((resolve12, reject) => {
31634
31676
  server.once("error", reject);
31635
- server.listen(sockPath(o.id), resolve11);
31677
+ server.listen(sockPath(o.id), resolve12);
31636
31678
  });
31637
31679
  const fail = async (e) => {
31638
31680
  server.close();
@@ -31658,7 +31700,8 @@ async function openOwnedPane(o) {
31658
31700
  let pidWaiter = null;
31659
31701
  let ended = false;
31660
31702
  let startedAt = 0;
31661
- const record = (extra = {}) => writeJson(recordPath(o.id), { id: o.id, kind: o.kind, caller: process.pid, wrapper: wrapper || void 0, session, startedMs: startedAt || Date.now(), ...extra });
31703
+ const openedAt = Date.now();
31704
+ const record = (extra = {}) => writeJson(recordPath(o.id), { id: o.id, kind: o.kind, caller: process.pid, wrapper: wrapper || void 0, session, openedMs: openedAt, startedMs: startedAt || openedAt, ...extra });
31662
31705
  const settle = (code, signal) => {
31663
31706
  if (ended) return;
31664
31707
  ended = true;
@@ -31911,14 +31954,14 @@ function pickSplit(panes, hostId) {
31911
31954
  return best ? { id: best.id, dir: best.dir, cols: best.cols, rows: best.rows, small: true } : null;
31912
31955
  }
31913
31956
  function osascript(script, args) {
31914
- return new Promise((resolve11, reject) => {
31957
+ return new Promise((resolve12, reject) => {
31915
31958
  const proc = spawn4("osascript", ["-l", "JavaScript", "-", ...args], { stdio: ["pipe", "pipe", "pipe"] });
31916
31959
  let out = "";
31917
31960
  let err = "";
31918
31961
  proc.stdout.on("data", (c) => out += c.toString("utf8"));
31919
31962
  proc.stderr.on("data", (c) => err += c.toString("utf8"));
31920
31963
  proc.on("error", reject);
31921
- proc.on("close", () => resolve11({ stdout: out, stderr: err }));
31964
+ proc.on("close", () => resolve12({ stdout: out, stderr: err }));
31922
31965
  proc.stdin.write(script);
31923
31966
  proc.stdin.end();
31924
31967
  });
@@ -33155,18 +33198,18 @@ var init_browser_tools = __esm({
33155
33198
  });
33156
33199
 
33157
33200
  // src/workers/project-config.ts
33158
- import { resolve as resolve8 } from "node:path";
33201
+ import { resolve as resolve9 } from "node:path";
33159
33202
  function asStringArray(v) {
33160
33203
  if (!Array.isArray(v)) return void 0;
33161
33204
  const out = v.filter((x) => typeof x === "string");
33162
33205
  return out.length ? out : void 0;
33163
33206
  }
33164
33207
  async function projectLaunchConfig(cwd, registry) {
33165
- const target = resolve8(cwd);
33208
+ const target = resolve9(cwd);
33166
33209
  const backend = registry ?? await getRegistryBackend();
33167
33210
  const rows = await backend.listProjectsByPathLengthDesc({ excludeArchived: true });
33168
33211
  for (const row of rows) {
33169
- const root = resolve8(row.root_path);
33212
+ const root = resolve9(row.root_path);
33170
33213
  if (target !== root && !target.startsWith(root + "/")) continue;
33171
33214
  if (!row.session_config) return null;
33172
33215
  let parsed;
@@ -33441,7 +33484,7 @@ var init_execute_prepare = __esm({
33441
33484
 
33442
33485
  // src/workers/edit-assist.ts
33443
33486
  import { readFileSync as readFileSync49 } from "node:fs";
33444
- import { resolve as resolve9 } from "node:path";
33487
+ import { resolve as resolve10 } from "node:path";
33445
33488
  function editAssist(i) {
33446
33489
  if (i.errorText.includes("No changes to make: old_string and new_string are exactly the same")) {
33447
33490
  return "old_string and new_string are identical: the file already contains your intended text; check whether this step is done (grep for it) before editing again.";
@@ -33549,7 +33592,7 @@ function editHintFor(input, errorText, cwd) {
33549
33592
  let fileText = null;
33550
33593
  if (typeof i.file_path === "string") {
33551
33594
  try {
33552
- fileText = readFileSync49(resolve9(cwd, i.file_path), "utf8");
33595
+ fileText = readFileSync49(resolve10(cwd, i.file_path), "utf8");
33553
33596
  } catch {
33554
33597
  fileText = null;
33555
33598
  }
@@ -34811,14 +34854,14 @@ async function foldRun(a, p) {
34811
34854
  state.closeTimer = null;
34812
34855
  }
34813
34856
  writeEvent({ type: "operator", text, handoff: isHandoffMessage(text) });
34814
- return new Promise((resolve11) => {
34857
+ return new Promise((resolve12) => {
34815
34858
  try {
34816
34859
  stdin.write(
34817
34860
  stdinUserMessage(operatorUserText(text)) + "\n",
34818
- (e) => resolve11(e ? `write to the worker failed: ${e.message}` : void 0)
34861
+ (e) => resolve12(e ? `write to the worker failed: ${e.message}` : void 0)
34819
34862
  );
34820
34863
  } catch (e) {
34821
- resolve11(`write to the worker failed: ${e.message}`);
34864
+ resolve12(`write to the worker failed: ${e.message}`);
34822
34865
  }
34823
34866
  });
34824
34867
  }) : null;
@@ -34942,11 +34985,11 @@ async function foldRun(a, p) {
34942
34985
  }
34943
34986
  });
34944
34987
  }
34945
- let rc = await new Promise((resolve11, reject) => {
34988
+ let rc = await new Promise((resolve12, reject) => {
34946
34989
  const onError = (e) => void failRun(e).then(() => reject(e), () => reject(e));
34947
34990
  if (earlyError) onError(earlyError);
34948
34991
  else proc.on("error", onError);
34949
- proc.on("close", (code) => resolve11(code ?? (state.killed ? 143 : 1)));
34992
+ proc.on("close", (code) => resolve12(code ?? (state.killed ? 143 : 1)));
34950
34993
  });
34951
34994
  if (state.troubleTimer) clearInterval(state.troubleTimer);
34952
34995
  if (state.trouble) {
@@ -35475,11 +35518,11 @@ async function executeCodexRun(a) {
35475
35518
  saveStatus(logDir2, status);
35476
35519
  for (const ev of fold.events.splice(0)) writeEvent(ev);
35477
35520
  });
35478
- const rc = await new Promise((resolve11, reject) => {
35521
+ const rc = await new Promise((resolve12, reject) => {
35479
35522
  const onError = (e) => void failRun(e).then(() => reject(e), () => reject(e));
35480
35523
  if (earlyError) onError(earlyError);
35481
35524
  else proc.on("error", onError);
35482
- proc.on("close", (code) => resolve11(code ?? (killed ? 143 : 1)));
35525
+ proc.on("close", (code) => resolve12(code ?? (killed ? 143 : 1)));
35483
35526
  });
35484
35527
  const secs = Math.floor((Date.now() - t0) / 1e3);
35485
35528
  const finalText = fold.finalText ?? "";
@@ -35577,12 +35620,12 @@ async function returnControlsIfHeld(logDir2, id) {
35577
35620
  if (!id) return;
35578
35621
  const status = loadStatus(logDir2, id);
35579
35622
  if (!status?.controlsHeld) return;
35580
- await new Promise((resolve11) => {
35623
+ await new Promise((resolve12) => {
35581
35624
  let done = false;
35582
35625
  const finish = () => {
35583
35626
  if (done) return;
35584
35627
  done = true;
35585
- resolve11();
35628
+ resolve12();
35586
35629
  };
35587
35630
  try {
35588
35631
  const proc = spawn8("clickr", clickrControlsReturnArgv(id), { stdio: "ignore" });
@@ -36283,7 +36326,7 @@ import { openSync as openSync8, closeSync as closeSync7, writeSync as writeSync3
36283
36326
  init_pai_home();
36284
36327
  init_worktree();
36285
36328
  import { existsSync as existsSync55, mkdirSync as mkdirSync40, writeFileSync as writeFileSync32, realpathSync as realpathSync4 } from "node:fs";
36286
- import { dirname as dirname27, join as join56, resolve as resolve10, isAbsolute as isAbsolute3 } from "node:path";
36329
+ import { dirname as dirname27, join as join56, resolve as resolve11, isAbsolute as isAbsolute3 } from "node:path";
36287
36330
  function slotsDir(logDir2) {
36288
36331
  return join56(logDir2, "slots");
36289
36332
  }
@@ -36293,7 +36336,7 @@ function slotPath(logDir2, provider, n) {
36293
36336
  function slotRepo(dir) {
36294
36337
  try {
36295
36338
  const raw = git(dir, ["rev-parse", "--git-common-dir"]);
36296
- const resolved = isAbsolute3(raw) ? raw : resolve10(dir, raw);
36339
+ const resolved = isAbsolute3(raw) ? raw : resolve11(dir, raw);
36297
36340
  return realpathSync4(resolved);
36298
36341
  } catch {
36299
36342
  return null;
@@ -36306,7 +36349,7 @@ function slotServesRepo(logDir2, provider, n, repo) {
36306
36349
  if (!slotRepoPath) return false;
36307
36350
  try {
36308
36351
  const repoCommon = git(repo, ["rev-parse", "--git-common-dir"]);
36309
- const resolvedRepo = isAbsolute3(repoCommon) ? repoCommon : resolve10(repo, repoCommon);
36352
+ const resolvedRepo = isAbsolute3(repoCommon) ? repoCommon : resolve11(repo, repoCommon);
36310
36353
  return slotRepoPath === realpathSync4(resolvedRepo);
36311
36354
  } catch {
36312
36355
  return false;
@@ -36477,8 +36520,8 @@ var PoolSlotSession = class {
36477
36520
  this.feeding = true;
36478
36521
  let result = null;
36479
36522
  let resolveFeed = null;
36480
- const done = new Promise((resolve11) => {
36481
- resolveFeed = () => resolve11(result);
36523
+ const done = new Promise((resolve12) => {
36524
+ resolveFeed = () => resolve12(result);
36482
36525
  });
36483
36526
  const listener = (e) => {
36484
36527
  if (e.type === "slot-exit") {
@@ -36513,7 +36556,7 @@ var PoolSlotSession = class {
36513
36556
  /** Resolves when the process exits (immediately when it already has). */
36514
36557
  waitExit() {
36515
36558
  if (this.exited) return Promise.resolve(this.exitCode);
36516
- return new Promise((resolve11) => this.exitWaiters.push(resolve11));
36559
+ return new Promise((resolve12) => this.exitWaiters.push(resolve12));
36517
36560
  }
36518
36561
  /**
36519
36562
  * Resolves on the slot's init event (or its exit, or the timeout). The
@@ -36522,7 +36565,7 @@ var PoolSlotSession = class {
36522
36565
  */
36523
36566
  waitInit(timeoutMs) {
36524
36567
  if (this.exited) return Promise.resolve(null);
36525
- return new Promise((resolve11) => {
36568
+ return new Promise((resolve12) => {
36526
36569
  let timer = setTimeout(done, timeoutMs);
36527
36570
  const listener = (e) => {
36528
36571
  if (e.type === "system" && e.subtype === "init") {
@@ -36536,7 +36579,7 @@ var PoolSlotSession = class {
36536
36579
  if (!timer) return;
36537
36580
  clearTimeout(timer);
36538
36581
  timer = null;
36539
- resolve11(e ?? null);
36582
+ resolve12(e ?? null);
36540
36583
  }
36541
36584
  this.listeners.add(listener);
36542
36585
  });
@@ -36565,20 +36608,20 @@ function routerUsageTail(file) {
36565
36608
  }
36566
36609
  }
36567
36610
  function readBody(req, max = 8 * 1024 * 1024) {
36568
- return new Promise((resolve11) => {
36611
+ return new Promise((resolve12) => {
36569
36612
  const chunks = [];
36570
36613
  let size = 0;
36571
36614
  req.on("data", (c) => {
36572
36615
  size += c.length;
36573
36616
  if (size > max) {
36574
- resolve11(null);
36617
+ resolve12(null);
36575
36618
  req.destroy();
36576
36619
  return;
36577
36620
  }
36578
36621
  chunks.push(c);
36579
36622
  });
36580
- req.on("end", () => resolve11(Buffer.concat(chunks).toString("utf8")));
36581
- req.on("error", () => resolve11(null));
36623
+ req.on("end", () => resolve12(Buffer.concat(chunks).toString("utf8")));
36624
+ req.on("error", () => resolve12(null));
36582
36625
  });
36583
36626
  }
36584
36627
  function sendJson(res, status, body) {
@@ -37347,7 +37390,7 @@ function createPoolHost(opts = {}) {
37347
37390
  }
37348
37391
  for (const list of [...spares.values()]) for (const e of [...list]) discardSpare(e, "host shutdown");
37349
37392
  persist();
37350
- await new Promise((resolve11) => server.close(() => resolve11()));
37393
+ await new Promise((resolve12) => server.close(() => resolve12()));
37351
37394
  };
37352
37395
  const reapSlots = () => {
37353
37396
  let n = 0;
@@ -37411,9 +37454,9 @@ function createPoolHost(opts = {}) {
37411
37454
  return true;
37412
37455
  }
37413
37456
  clearReloadMarker(logDir2);
37414
- await new Promise((resolve11) => {
37415
- server.once("error", () => resolve11());
37416
- server.listen(port2, LOOPBACK_HOST, () => resolve11());
37457
+ await new Promise((resolve12) => {
37458
+ server.once("error", () => resolve12());
37459
+ server.listen(port2, LOOPBACK_HOST, () => resolve12());
37417
37460
  });
37418
37461
  appendLedger(ledger, "POOL-HOST-RELOAD-FAILED", { pid: process.pid, bundle: opts.bundlePath, note: why });
37419
37462
  reloading = false;