@tekmidian/pai 1.0.3 → 1.0.5

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 (147) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/{auto-route-B7Yu6Uam.mjs → auto-route-DUYr57rs.mjs} +2 -2
  3. package/dist/auto-route-DWYK_0i0.mjs +11 -0
  4. package/dist/budget-DX-VIWGf.mjs +15 -0
  5. package/dist/{caller-identity-yLFb7CKq.mjs → caller-identity-Bim8JT-D.mjs} +3 -3
  6. package/dist/{capacity-DEveQdFV.mjs → capacity-CsZMkVyg.mjs} +7 -4
  7. package/dist/{chain-7n9Gx56r.mjs → chain-Dzz6xcKH.mjs} +5 -5
  8. package/dist/cli/index.mjs +114 -208
  9. package/dist/{cockpit-actions-BBHeyEZI.mjs → cockpit-actions-BTA1njMO.mjs} +31 -25
  10. package/dist/{cockpit-actions-DR9X514g.mjs → cockpit-actions-BgsiNcUY.mjs} +18 -18
  11. package/dist/cockpit-memory-DIrNs4xr.mjs +20 -0
  12. package/dist/config/defaults/config.yaml +9 -0
  13. package/dist/{config-XpZWOYOG.mjs → config-CST2uq1v.mjs} +29 -4
  14. package/dist/{config-Bu1_vbY8.mjs → config-DYbyEe4-.mjs} +2 -2
  15. package/dist/{config-DtENJ6cL.mjs → config-Dv3t7xnT.mjs} +1 -1
  16. package/dist/config-h5qK3fst.mjs +4 -0
  17. package/dist/{controls-CPoeudou.mjs → controls-OiVVbe-f.mjs} +18 -16
  18. package/dist/daemon/index.mjs +38 -37
  19. package/dist/{daemon-DPAo6WTa.mjs → daemon-C1dycZ3W.mjs} +35 -29
  20. package/dist/daemon-ieo0lnpq.mjs +46 -0
  21. package/dist/daemon-mcp/index.mjs +35 -35
  22. package/dist/detect-C0ZBXqDL.mjs +10 -0
  23. package/dist/{detect-9CZNO0yf.mjs → detect-CHuxFrLy.mjs} +2 -2
  24. package/dist/{embed-pass-DIWjA68P.mjs → embed-pass-DtVF2fOV.mjs} +4 -4
  25. package/dist/{embedding-gate-Cnk4YCyX.mjs → embedding-gate-B98PK_wz.mjs} +2 -2
  26. package/dist/{embedding-gate-6rZrWRXa.mjs → embedding-gate-CTAk8STe.mjs} +2 -2
  27. package/dist/{endreason-C577xIQz.mjs → endreason-BqyyU7BH.mjs} +20 -6
  28. package/dist/{factory-DjAAsqr_.mjs → factory-BV0MQA3T.mjs} +4 -4
  29. package/dist/{factory-Bsib-qDG.mjs → factory-DeASMV7Z.mjs} +4 -4
  30. package/dist/{fallback-DFlItw1Z.mjs → fallback-Bj2cyVk_.mjs} +230 -8
  31. package/dist/{health-Dnym-qcT.mjs → health-kufVIf6i.mjs} +4 -4
  32. package/dist/{helpers-BD6V-p9w.mjs → helpers-CvbYEKoD.mjs} +2 -2
  33. package/dist/{helpers-CMGjy_0N.mjs → helpers-WV8tdQHM.mjs} +5 -5
  34. package/dist/hooks/block-sleep-poll.mjs +1 -1
  35. package/dist/hooks/capture-all-events.mjs +21 -2
  36. package/dist/hooks/capture-tool-output.mjs +21 -2
  37. package/dist/hooks/load-project-context.mjs +7 -7
  38. package/dist/hooks/local-model-hint.mjs +1 -1
  39. package/dist/hooks/route-agents-to-worker.mjs +1 -1
  40. package/dist/hooks/security-validator.mjs +2 -2
  41. package/dist/hooks/worker-edit-repair.mjs +2 -2
  42. package/dist/hooks/worker-guard.mjs +8 -8
  43. package/dist/hooks/worker-note.mjs +2 -2
  44. package/dist/hooks/worker-pool-host.mjs +158 -55
  45. package/dist/hooks/worker-proxy.mjs +1 -1
  46. package/dist/hooks/worker-status-line.mjs +50 -22
  47. package/dist/hooks/worker-supervision.mjs +1 -1
  48. package/dist/hooks/worker-tool-name-repair.mjs +2 -2
  49. package/dist/index.mjs +8 -8
  50. package/dist/{indexer-backend-Cll7le4P.mjs → indexer-backend-B2vtFl38.mjs} +37 -234
  51. package/dist/{ipc-client-CaiGJnSM.mjs → ipc-client-CnYEF31R.mjs} +1 -1
  52. package/dist/{ipc-client-ZRmDKd5Z.mjs → ipc-client-DN7EvoVo.mjs} +1 -1
  53. package/dist/kill-tree-CXZ0WfVf.mjs +10 -0
  54. package/dist/{kill-tree-EWYaEk5v.mjs → kill-tree-CcpsRLCZ.mjs} +7 -7
  55. package/dist/{launch-Jh5NVeNe.mjs → launch-DpQPZGsT.mjs} +3 -3
  56. package/dist/{launch-CXVlZjHt.mjs → launch-UPQBoW2q.mjs} +3 -3
  57. package/dist/{local-candidate-DLdwQt0s.mjs → local-candidate-Cp_bw4kK.mjs} +3 -3
  58. package/dist/{local-instances-ZeRkkuS5.mjs → local-instances-B-c-CxzP.mjs} +4 -4
  59. package/dist/{local-instances-DOxSgT_L.mjs → local-instances-bdCNNSsL.mjs} +2 -2
  60. package/dist/{local-tiers-BE4jGaMa.mjs → local-tiers-BtdEEe5n.mjs} +2 -2
  61. package/dist/{local-tiers-DNMI5W86.mjs → local-tiers-OBqAAfOg.mjs} +3 -3
  62. package/dist/{main-config-ops-BEMpuhDz.mjs → main-config-ops-BYsK3BxM.mjs} +3 -3
  63. package/dist/{main-resolver-3Ns1HPmS.mjs → main-resolver-CAC3xfZM.mjs} +17 -17
  64. package/dist/{model-inventory-BFVSNFT3.mjs → model-inventory-BuTpi9a6.mjs} +13 -13
  65. package/dist/{models-add-C1QIc1DA.mjs → models-add-CJx2YAwh.mjs} +37 -36
  66. package/dist/operator-Bpxq_WB5.mjs +7 -0
  67. package/dist/{operator-CyuB3aVw.mjs → operator-DrwWItVt.mjs} +2 -2
  68. package/dist/{pai-marker-BcZyJguM.mjs → pai-marker-DLKJ9Yr5.mjs} +2 -2
  69. package/dist/{pane-audit-DKQt71s4.mjs → pane-audit-wv9UkyCe.mjs} +27 -9
  70. package/dist/{paths-CFHTloSe.mjs → paths-DBd78I7Z.mjs} +3 -3
  71. package/dist/{paths-CHifubDh.mjs → paths-DS5VQKoR.mjs} +3 -3
  72. package/dist/{planner-BmFACdLa.mjs → planner-K0mFrCpL.mjs} +28 -28
  73. package/dist/{pool-Dh-q3iJi.mjs → pool-BZ94nFuq.mjs} +2 -2
  74. package/dist/{pool-cli-BggU8GRp.mjs → pool-cli-B1eKySeN.mjs} +5 -5
  75. package/dist/{pool-cli-DQ6OzRy2.mjs → pool-cli-BjYQDfx6.mjs} +6 -6
  76. package/dist/{postgres-C6ti4haA.mjs → postgres-C-T5OWer.mjs} +19 -9
  77. package/dist/{postgres-BdBNkL_l.mjs → postgres-CBHY5PIi.mjs} +3 -3
  78. package/dist/{project-setup-jvfONJTQ.mjs → project-setup-pIPHZaXf.mjs} +26 -246
  79. package/dist/{providers-CblTFrhz.mjs → providers-Dzx5GAUI.mjs} +6 -6
  80. package/dist/providers-QJzpaNhX.mjs +16 -0
  81. package/dist/{query-feedback-BRfPtqki.mjs → query-feedback-DN52N9C5.mjs} +1 -1
  82. package/dist/{registrable-DpyTtajg.mjs → registrable-CXBBpUcz.mjs} +4 -4
  83. package/dist/registrable-Drn8wIDO.mjs +9 -0
  84. package/dist/render-C4KR8qQ8.mjs +13 -0
  85. package/dist/{render-BYmQkuLd.mjs → render-Cz3BWIBO.mjs} +8 -8
  86. package/dist/root-Bfb1zgwE.mjs +36 -0
  87. package/dist/{root-Xglu0OPD.mjs → root-bG48WVpW.mjs} +10 -10
  88. package/dist/route-table-ZVMNBsy7.mjs +15 -0
  89. package/dist/{routing-BAAST9vT.mjs → routing-BlD_tKjW.mjs} +136 -18
  90. package/dist/{routing-CENt4HH1.mjs → routing-D27jxj9x.mjs} +13 -13
  91. package/dist/{run-CSC7mgPf.mjs → run-AZVwceiU.mjs} +49 -27
  92. package/dist/{scan-C_Y5W9py.mjs → scan-C3uotg_f.mjs} +5 -5
  93. package/dist/{scope-D-h6F6DN.mjs → scope-D8HK6vU7.mjs} +4 -4
  94. package/dist/{session-8iqQDkqb.mjs → session-BAfypQb9.mjs} +26 -26
  95. package/dist/session-BcnhepLZ.mjs +35 -0
  96. package/dist/{session-scan-W-gbwJHM.mjs → session-scan-BmnjSReu.mjs} +5 -5
  97. package/dist/session-scan-CqUQdCac.mjs +9 -0
  98. package/dist/session-usage-oycSdiD3.mjs +337 -0
  99. package/dist/{sources-ESUkZaWv.mjs → sources-CiE3rZek.mjs} +1 -1
  100. package/dist/{status-ggJ7lgVg.mjs → status-COtzewKV.mjs} +3 -3
  101. package/dist/{status-Dm4dYciN.mjs → status-D_SWmOlH.mjs} +4 -4
  102. package/dist/{tool-errors-CJWODvlo.mjs → tool-errors-B2LnIqR0.mjs} +6 -6
  103. package/dist/{tool-errors-7E13StWd.mjs → tool-errors-DXJ70-sr.mjs} +2 -2
  104. package/dist/{viewer-mDXUNHNy.mjs → viewer-BgGRqXfD.mjs} +14 -14
  105. package/dist/viewer-CbGN2Ri4.mjs +22 -0
  106. package/dist/{wait-ByV0OyMZ.mjs → wait-ChpHKJZV.mjs} +3 -3
  107. package/dist/worker-config-D1KVAMp4.mjs +42 -0
  108. package/dist/{worker-config-CJhEMk19.mjs → worker-config-DgdT0iTB.mjs} +443 -40
  109. package/dist/workers-config-BhZBrR-Q.mjs +4 -0
  110. package/dist/{worktree-CRs2gyg0.mjs → worktree-BY--Rgmy.mjs} +5 -5
  111. package/dist/{zettelkasten-B_rRRRvD.mjs → zettelkasten-BHVx5zj-.mjs} +4 -4
  112. package/dist/{zettelkasten-BzMm8REH.mjs → zettelkasten-LoH9RBiN.mjs} +2 -2
  113. package/docs/cockpit.md +1 -0
  114. package/docs/commands/README.md +1 -0
  115. package/docs/commands/config.md +20 -0
  116. package/gemini-extension.json +1 -1
  117. package/package.json +1 -1
  118. package/pai-plugin.json +1 -1
  119. package/plugins/context-preservation/plugin.json +1 -1
  120. package/plugins/core/plugin.json +1 -1
  121. package/plugins/creative/plugin.json +1 -1
  122. package/plugins/observability/plugin.json +1 -1
  123. package/plugins/productivity/plugin.json +1 -1
  124. package/plugins/semantic-search/plugin.json +1 -1
  125. package/plugins/ui/plugin.json +1 -1
  126. package/plugins/zettelkasten/plugin.json +1 -1
  127. package/src/hooks/ts/capture-all-events.ts +15 -3
  128. package/src/hooks/ts/lib/raw-capture.ts +7 -0
  129. package/src/hooks/ts/post-tool-use/capture-tool-output.ts +13 -3
  130. package/dist/auto-route-CjjQqU1o.mjs +0 -11
  131. package/dist/budget-Dod6rnA9.mjs +0 -15
  132. package/dist/cockpit-memory--dnShXBA.mjs +0 -20
  133. package/dist/config-Cxi-aBf4.mjs +0 -4
  134. package/dist/daemon-DKdBNKfa.mjs +0 -45
  135. package/dist/detect-D1ziFFfA.mjs +0 -10
  136. package/dist/kill-tree-BG7dRVtp.mjs +0 -10
  137. package/dist/operator-BTqvTIc8.mjs +0 -7
  138. package/dist/providers-BeDiVEb-.mjs +0 -16
  139. package/dist/registrable-BzH4TObg.mjs +0 -9
  140. package/dist/render-CoMvwMPs.mjs +0 -13
  141. package/dist/root-FtJsxYnm.mjs +0 -36
  142. package/dist/route-table-B7zpoypi.mjs +0 -15
  143. package/dist/session-BeqAbNPd.mjs +0 -35
  144. package/dist/session-scan-BJI_ZO8M.mjs +0 -9
  145. package/dist/viewer-CqozWW39.mjs +0 -22
  146. package/dist/worker-config-DESkIjMF.mjs +0 -41
  147. package/dist/workers-config-f8KrkY4L.mjs +0 -4
@@ -8852,13 +8852,15 @@ __export(config_exports, {
8852
8852
  providerCostTier: () => providerCostTier,
8853
8853
  providerKeyPath: () => providerKeyPath,
8854
8854
  providerQuotaSkipAt: () => providerQuotaSkipAt,
8855
+ readWorkersCached: () => readWorkersCached,
8855
8856
  readWorkersSection: () => readWorkersSection,
8856
8857
  resolveCapability: () => resolveCapability,
8857
8858
  resolveModelCapability: () => resolveModelCapability,
8858
8859
  resolveProviderKey: () => resolveProviderKey,
8860
+ workersConfigStamp: () => workersConfigStamp,
8859
8861
  writeWorkersSection: () => writeWorkersSection
8860
8862
  });
8861
- import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
8863
+ import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync2 } from "node:fs";
8862
8864
  function nativeAnthropicModels() {
8863
8865
  const d = shippedWorkersDefaults();
8864
8866
  const providers = d.providers;
@@ -9742,6 +9744,22 @@ function readWorkersSection(path = paiConfigFilePath(), onWarn = (msg) => proces
9742
9744
  onWarn(`legacy routing migrated into the tier lists: ${[...folded, ...moved].join(", ")} (pai worker route)`);
9743
9745
  return { raw, workers };
9744
9746
  }
9747
+ function mtimeOf(path) {
9748
+ try {
9749
+ return statSync2(path).mtimeMs;
9750
+ } catch {
9751
+ return 0;
9752
+ }
9753
+ }
9754
+ function workersConfigStamp(path = paiConfigFilePath()) {
9755
+ return `${path}:${mtimeOf(path)}:${mtimeOf(workersYamlPath())}`;
9756
+ }
9757
+ function readWorkersCached(path = paiConfigFilePath()) {
9758
+ const key = workersConfigStamp(path);
9759
+ if (cachedWorkers?.key !== key) cachedWorkers = { key, workers: readWorkersSection(path, () => {
9760
+ }).workers };
9761
+ return cachedWorkers.workers;
9762
+ }
9745
9763
  function writeWorkersSection(raw, workers, path = CONFIG_FILE) {
9746
9764
  const yamlPath = workersYamlPath();
9747
9765
  const usingYaml = existsSync8(yamlPath);
@@ -9879,7 +9897,7 @@ function escalationCloud() {
9879
9897
  return DEFAULT_ESCALATE.cloud;
9880
9898
  }
9881
9899
  }
9882
- var ANTHROPIC_NATIVE, DEFAULT_POOL_PORT, MODEL_TIERS, DEFAULT_COST_TIER, PROVIDER_TAGS, WORKER_CLASSES, MODEL_CAPABILITIES, CAPABILITY_NAME_RE, WorkersConfigError;
9900
+ var ANTHROPIC_NATIVE, DEFAULT_POOL_PORT, MODEL_TIERS, DEFAULT_COST_TIER, PROVIDER_TAGS, WORKER_CLASSES, MODEL_CAPABILITIES, CAPABILITY_NAME_RE, WorkersConfigError, cachedWorkers;
9883
9901
  var init_config3 = __esm({
9884
9902
  "src/workers/config.ts"() {
9885
9903
  "use strict";
@@ -9919,6 +9937,7 @@ var init_config3 = __esm({
9919
9937
  CAPABILITY_NAME_RE = /^[a-z][a-z0-9-]*$/;
9920
9938
  WorkersConfigError = class extends Error {
9921
9939
  };
9940
+ cachedWorkers = null;
9922
9941
  }
9923
9942
  });
9924
9943
 
@@ -10104,7 +10123,7 @@ var init_input_side_tokens = __esm({
10104
10123
  });
10105
10124
 
10106
10125
  // src/workers/pool.ts
10107
- import { existsSync as existsSync11, mkdirSync as mkdirSync7, appendFileSync as appendFileSync2, readFileSync as readFileSync10, writeFileSync as writeFileSync6, statSync as statSync2, unlinkSync as unlinkSync3 } from "node:fs";
10126
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, appendFileSync as appendFileSync2, readFileSync as readFileSync10, writeFileSync as writeFileSync6, statSync as statSync3, unlinkSync as unlinkSync3 } from "node:fs";
10108
10127
  import { request as httpRequest } from "node:http";
10109
10128
  import { dirname as dirname9, join as join10 } from "node:path";
10110
10129
  function poolSettings(config) {
@@ -10149,7 +10168,7 @@ function clearReloadMarker(logDir2) {
10149
10168
  }
10150
10169
  function reloadInProgress(logDir2, maxAgeMs = 3e4) {
10151
10170
  try {
10152
- return Date.now() - statSync2(poolReloadMarkerPath(logDir2)).mtimeMs < maxAgeMs;
10171
+ return Date.now() - statSync3(poolReloadMarkerPath(logDir2)).mtimeMs < maxAgeMs;
10153
10172
  } catch {
10154
10173
  return false;
10155
10174
  }
@@ -10817,7 +10836,7 @@ var init_render_decision = __esm({
10817
10836
  // src/workers/preamble.ts
10818
10837
  import { execFileSync as execFileSync3 } from "node:child_process";
10819
10838
  import { createHash } from "node:crypto";
10820
- import { existsSync as existsSync12, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
10839
+ import { existsSync as existsSync12, readFileSync as readFileSync11, statSync as statSync4 } from "node:fs";
10821
10840
  import { join as join11 } from "node:path";
10822
10841
  function projectRoot(cwd) {
10823
10842
  try {
@@ -10833,7 +10852,7 @@ function projectRoot(cwd) {
10833
10852
  function loadPreamble(cwd) {
10834
10853
  const path = join11(projectRoot(cwd), PREAMBLE_REL);
10835
10854
  if (!existsSync12(path)) return { preamble: null };
10836
- const size = statSync3(path).size;
10855
+ const size = statSync4(path).size;
10837
10856
  if (size > PREAMBLE_MAX_BYTES) {
10838
10857
  return { refused: `${path} is ${size} bytes, over the ${PREAMBLE_MAX_BYTES} byte limit \u2014 shorten it` };
10839
10858
  }
@@ -11022,7 +11041,7 @@ import {
11022
11041
  readdirSync as readdirSync2,
11023
11042
  renameSync as renameSync5,
11024
11043
  rmSync,
11025
- statSync as statSync4,
11044
+ statSync as statSync5,
11026
11045
  writeFileSync as writeFileSync7
11027
11046
  } from "node:fs";
11028
11047
  import { join as join13 } from "node:path";
@@ -11282,7 +11301,7 @@ var init_wait_on = __esm({
11282
11301
 
11283
11302
  // src/workers/report.ts
11284
11303
  import { execFileSync as execFileSync7 } from "node:child_process";
11285
- import { statSync as statSync5 } from "node:fs";
11304
+ import { statSync as statSync6 } from "node:fs";
11286
11305
  import { isAbsolute, relative, resolve as resolve4 } from "node:path";
11287
11306
  function ag2ReportBlock() {
11288
11307
  const spec = ag2Spec();
@@ -11449,7 +11468,7 @@ function verifyReportChanges(changed, cwd, startMs) {
11449
11468
  const abs = isAbsolute(raw) ? raw : resolve4(cwd, raw);
11450
11469
  let mtimeMs;
11451
11470
  try {
11452
- mtimeMs = statSync5(abs).mtimeMs;
11471
+ mtimeMs = statSync6(abs).mtimeMs;
11453
11472
  } catch {
11454
11473
  mtimeMs = null;
11455
11474
  }
@@ -11565,7 +11584,7 @@ var init_wait = __esm({
11565
11584
  });
11566
11585
 
11567
11586
  // src/workers/tool-errors.ts
11568
- import { appendFileSync as appendFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync14, statSync as statSync6, openSync, readSync, closeSync } from "node:fs";
11587
+ import { appendFileSync as appendFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync14, statSync as statSync7, openSync, readSync, closeSync } from "node:fs";
11569
11588
  import { join as join14 } from "node:path";
11570
11589
  function wrongCaseTool(raw) {
11571
11590
  const name = raw.match(/No such tool available:?\s*(\S+)/i)?.[1]?.replace(/[.,;:"'`]+$/, "");
@@ -11671,7 +11690,7 @@ function readToolErrors(logDir2, sinceMs = 0) {
11671
11690
  const path = toolErrorsPath(logDir2);
11672
11691
  if (!existsSync15(path)) return [];
11673
11692
  let text;
11674
- const size = statSync6(path).size;
11693
+ const size = statSync7(path).size;
11675
11694
  if (size > TAIL_BYTES) {
11676
11695
  const fd = openSync(path, "r");
11677
11696
  const buf = Buffer.alloc(TAIL_BYTES);
@@ -11992,7 +12011,7 @@ var init_config4 = __esm({
11992
12011
  });
11993
12012
 
11994
12013
  // src/builds/queue.ts
11995
- import { existsSync as existsSync17, mkdirSync as mkdirSync10, readdirSync as readdirSync4, readFileSync as readFileSync16, renameSync as renameSync6, rmSync as rmSync2, rmdirSync, statSync as statSync7, writeFileSync as writeFileSync8 } from "node:fs";
12014
+ import { existsSync as existsSync17, mkdirSync as mkdirSync10, readdirSync as readdirSync4, readFileSync as readFileSync16, renameSync as renameSync6, rmSync as rmSync2, rmdirSync, statSync as statSync8, writeFileSync as writeFileSync8 } from "node:fs";
11996
12015
  import { join as join16 } from "node:path";
11997
12016
  function buildsDir(env = process.env) {
11998
12017
  if (env.PAI_BUILD_DIR) return env.PAI_BUILD_DIR;
@@ -12004,13 +12023,13 @@ function breakStaleMutex(m, staleMs = 5e3) {
12004
12023
  mkdirSync10(guard);
12005
12024
  } catch {
12006
12025
  try {
12007
- if (Date.now() - statSync7(guard).mtimeMs > staleMs) rmdirSync(guard);
12026
+ if (Date.now() - statSync8(guard).mtimeMs > staleMs) rmdirSync(guard);
12008
12027
  } catch {
12009
12028
  }
12010
12029
  return;
12011
12030
  }
12012
12031
  try {
12013
- if (Date.now() - statSync7(m).mtimeMs > staleMs) rmdirSync(m);
12032
+ if (Date.now() - statSync8(m).mtimeMs > staleMs) rmdirSync(m);
12014
12033
  } catch {
12015
12034
  } finally {
12016
12035
  try {
@@ -12349,7 +12368,8 @@ function queuedText(q) {
12349
12368
  async function capacityGate(o) {
12350
12369
  const cfg = capacityOf(o.config);
12351
12370
  if (o.disabled || !cfg.enabled || o.cap === void 0 || o.cap <= 0) return null;
12352
- const { logDir: logDir2, self, cap } = o;
12371
+ const { logDir: logDir2, self } = o;
12372
+ let cap = o.cap;
12353
12373
  const load2 = o.load ?? ((dir2) => (reconcileStatuses(dir2, /* @__PURE__ */ new Date(), 0), loadStatuses(dir2)));
12354
12374
  const now = o.now ?? Date.now;
12355
12375
  const isAlive = o.isAlive ?? alive;
@@ -12398,6 +12418,8 @@ async function capacityGate(o) {
12398
12418
  o.onWait?.(info());
12399
12419
  for (let n = 0; ; n++) {
12400
12420
  await sleep(backoffMs(n));
12421
+ const fresh = o.capOf?.();
12422
+ if (fresh !== void 0 && fresh > 0) cap = fresh;
12401
12423
  c = check();
12402
12424
  if (c.position === 1 && c.holding < cap) break;
12403
12425
  o.onWait?.(info());
@@ -20438,7 +20460,7 @@ var init_retry = __esm({
20438
20460
  });
20439
20461
 
20440
20462
  // src/memory/indexer/async.ts
20441
- import { readFileSync as readFileSync29, statSync as statSync8, existsSync as existsSync29 } from "node:fs";
20463
+ import { readFileSync as readFileSync29, statSync as statSync9, existsSync as existsSync29 } from "node:fs";
20442
20464
  import { join as join26, relative as relative2, basename as basename4 } from "node:path";
20443
20465
  async function indexFileWithBackend(backend, projectId, rootPath, relativePath, source, tier, pathPrefix = "") {
20444
20466
  const absPath = join26(rootPath, relativePath);
@@ -20447,7 +20469,7 @@ async function indexFileWithBackend(backend, projectId, rootPath, relativePath,
20447
20469
  let stat;
20448
20470
  try {
20449
20471
  content = readFileSync29(absPath, "utf8");
20450
- stat = statSync8(absPath);
20472
+ stat = statSync9(absPath);
20451
20473
  } catch {
20452
20474
  return false;
20453
20475
  }
@@ -20935,6 +20957,17 @@ var init_kg_triples = __esm({
20935
20957
  async function ensureObservationTables(pool) {
20936
20958
  if (_tablesEnsured) return;
20937
20959
  await pool.query(SCHEMA_SQL);
20960
+ const colCheck = await pool.query(
20961
+ `SELECT column_name FROM information_schema.columns
20962
+ WHERE table_name = 'pai_observations' AND column_name IN ('source', 'fidelity')`
20963
+ );
20964
+ const existing = new Set(colCheck.rows.map((r) => r.column_name));
20965
+ if (!existing.has("source")) {
20966
+ await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS source TEXT");
20967
+ }
20968
+ if (!existing.has("fidelity")) {
20969
+ await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS fidelity TEXT");
20970
+ }
20938
20971
  _tablesEnsured = true;
20939
20972
  }
20940
20973
  async function ensureSkillTelemetryTable(pool) {
@@ -20962,8 +20995,9 @@ async function storeObservation(pool, obs) {
20962
20995
  const result = await pool.query(
20963
20996
  `INSERT INTO pai_observations
20964
20997
  (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)
20998
+ tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash,
20999
+ source, fidelity)
21000
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb, $10::jsonb, $11::jsonb, $12, $13, $14)
20967
21001
  RETURNING id`,
20968
21002
  [
20969
21003
  obs.session_id,
@@ -20977,7 +21011,9 @@ async function storeObservation(pool, obs) {
20977
21011
  JSON.stringify(obs.files_read),
20978
21012
  JSON.stringify(obs.files_modified),
20979
21013
  JSON.stringify(obs.concepts),
20980
- hash
21014
+ hash,
21015
+ obs.source ?? null,
21016
+ obs.fidelity ?? null
20981
21017
  ]
20982
21018
  );
20983
21019
  return result.rows[0]?.id ?? null;
@@ -21019,7 +21055,7 @@ async function queryObservations(pool, opts = {}) {
21019
21055
  `SELECT id, session_id, project_id, project_slug, type, title, narrative,
21020
21056
  tool_name, tool_input_summary,
21021
21057
  files_read, files_modified, concepts,
21022
- content_hash, created_at
21058
+ content_hash, source, fidelity, created_at
21023
21059
  FROM pai_observations
21024
21060
  ${where}
21025
21061
  ORDER BY created_at DESC
@@ -21034,7 +21070,7 @@ async function queryRecentObservations(pool, projectId, limit) {
21034
21070
  `SELECT id, session_id, project_id, project_slug, type, title, narrative,
21035
21071
  tool_name, tool_input_summary,
21036
21072
  files_read, files_modified, concepts,
21037
- content_hash, created_at
21073
+ content_hash, source, fidelity, created_at
21038
21074
  FROM pai_observations
21039
21075
  WHERE project_id = $1
21040
21076
  ORDER BY created_at DESC
@@ -21049,7 +21085,7 @@ async function querySessionObservations(pool, sessionId) {
21049
21085
  `SELECT id, session_id, project_id, project_slug, type, title, narrative,
21050
21086
  tool_name, tool_input_summary,
21051
21087
  files_read, files_modified, concepts,
21052
- content_hash, created_at
21088
+ content_hash, source, fidelity, created_at
21053
21089
  FROM pai_observations
21054
21090
  WHERE session_id = $1
21055
21091
  ORDER BY created_at ASC`,
@@ -21219,6 +21255,8 @@ CREATE TABLE IF NOT EXISTS pai_observations (
21219
21255
  files_modified JSONB DEFAULT '[]'::jsonb,
21220
21256
  concepts JSONB DEFAULT '[]'::jsonb,
21221
21257
  content_hash TEXT,
21258
+ source TEXT,
21259
+ fidelity TEXT,
21222
21260
  created_at TIMESTAMPTZ DEFAULT NOW()
21223
21261
  );
21224
21262
 
@@ -23309,7 +23347,7 @@ var init_federation_db = __esm({
23309
23347
  });
23310
23348
 
23311
23349
  // src/storage/sqlite/indexer.ts
23312
- import { readFileSync as readFileSync31, statSync as statSync9, existsSync as existsSync30 } from "node:fs";
23350
+ import { readFileSync as readFileSync31, statSync as statSync10, existsSync as existsSync30 } from "node:fs";
23313
23351
  import { join as join28, relative as relative3, basename as basename5 } from "node:path";
23314
23352
  function indexFile(db, projectId, rootPath, relativePath, source, tier) {
23315
23353
  const absPath = join28(rootPath, relativePath);
@@ -23317,7 +23355,7 @@ function indexFile(db, projectId, rootPath, relativePath, source, tier) {
23317
23355
  let stat;
23318
23356
  try {
23319
23357
  content = readFileSync31(absPath, "utf8");
23320
- stat = statSync9(absPath);
23358
+ stat = statSync10(absPath);
23321
23359
  } catch {
23322
23360
  return false;
23323
23361
  }
@@ -26633,7 +26671,7 @@ var init_detect = __esm({
26633
26671
 
26634
26672
  // src/cli/lib/utils.ts
26635
26673
  import { resolve as resolve6, basename as basename6, join as join30 } from "node:path";
26636
- import { mkdirSync as mkdirSync21, existsSync as existsSync31, writeFileSync as writeFileSync18, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
26674
+ import { mkdirSync as mkdirSync21, existsSync as existsSync31, writeFileSync as writeFileSync18, readdirSync as readdirSync8, statSync as statSync11 } from "node:fs";
26637
26675
  function encIndex(entries) {
26638
26676
  let idx = indexes.get(entries);
26639
26677
  if (!idx) {
@@ -26682,7 +26720,7 @@ function smartDecodeDir(encoded, listings) {
26682
26720
  return nextPath;
26683
26721
  }
26684
26722
  try {
26685
- if (statSync10(nextPath).isDirectory()) {
26723
+ if (statSync11(nextPath).isDirectory()) {
26686
26724
  current2 = nextPath;
26687
26725
  remaining = nextRemaining;
26688
26726
  matched = true;
@@ -26780,7 +26818,7 @@ __export(session_scan_exports, {
26780
26818
  });
26781
26819
  import {
26782
26820
  readdirSync as readdirSync10,
26783
- statSync as statSync11,
26821
+ statSync as statSync12,
26784
26822
  readFileSync as readFileSync33,
26785
26823
  openSync as openSync3,
26786
26824
  readSync as readSync3,
@@ -26887,7 +26925,7 @@ function flushScanCache(prune) {
26887
26925
  function parseTopLevel(filePath) {
26888
26926
  let st;
26889
26927
  try {
26890
- st = statSync11(filePath);
26928
+ st = statSync12(filePath);
26891
26929
  } catch {
26892
26930
  return { systemLines: 0, size: 0, mtime: 0 };
26893
26931
  }
@@ -26959,7 +26997,7 @@ function resolveFriendlyName(p) {
26959
26997
  function parseTranscript(filePath) {
26960
26998
  let mtime = 0;
26961
26999
  try {
26962
- const st = statSync11(filePath);
27000
+ const st = statSync12(filePath);
26963
27001
  mtime = st.mtimeMs;
26964
27002
  const hit = loadScanCache().tr[filePath];
26965
27003
  if (hit && hit.m === st.mtimeMs && hit.s === st.size) {
@@ -27055,7 +27093,7 @@ async function scanSessions(opts = {}) {
27055
27093
  for (const encodedDir of encodedDirs) {
27056
27094
  const projectDir = join32(CLAUDE_PROJECTS_DIR, encodedDir);
27057
27095
  try {
27058
- if (!statSync11(projectDir).isDirectory()) continue;
27096
+ if (!statSync12(projectDir).isDirectory()) continue;
27059
27097
  } catch {
27060
27098
  continue;
27061
27099
  }
@@ -27317,7 +27355,7 @@ function scanFilesystemForUuidPrefix(prefix) {
27317
27355
  for (const encodedDir of encodedDirs) {
27318
27356
  const projectDir = join32(CLAUDE_PROJECTS_DIR, encodedDir);
27319
27357
  try {
27320
- if (!statSync11(projectDir).isDirectory()) continue;
27358
+ if (!statSync12(projectDir).isDirectory()) continue;
27321
27359
  } catch {
27322
27360
  continue;
27323
27361
  }
@@ -27711,6 +27749,16 @@ var init_route_table = __esm({
27711
27749
  }
27712
27750
  });
27713
27751
 
27752
+ // src/router/cockpit-auth.ts
27753
+ var init_cockpit_auth = __esm({
27754
+ "src/router/cockpit-auth.ts"() {
27755
+ "use strict";
27756
+ init_pai_home();
27757
+ init_loopback();
27758
+ init_timeouts();
27759
+ }
27760
+ });
27761
+
27714
27762
  // src/router/router.ts
27715
27763
  var routerPort;
27716
27764
  var init_router2 = __esm({
@@ -27730,12 +27778,13 @@ var init_router2 = __esm({
27730
27778
  init_local_instances();
27731
27779
  init_route_table();
27732
27780
  init_loopback_guard();
27781
+ init_cockpit_auth();
27733
27782
  routerPort = () => loadConfig().router.port;
27734
27783
  }
27735
27784
  });
27736
27785
 
27737
27786
  // src/workers/settings-file.ts
27738
- import { chmodSync as chmodSync5, existsSync as existsSync34, mkdirSync as mkdirSync23, readdirSync as readdirSync11, rmSync as rmSync6, statSync as statSync12, writeFileSync as writeFileSync21 } from "node:fs";
27787
+ import { chmodSync as chmodSync5, existsSync as existsSync34, mkdirSync as mkdirSync23, readdirSync as readdirSync11, rmSync as rmSync6, statSync as statSync13, writeFileSync as writeFileSync21 } from "node:fs";
27739
27788
  import { join as join34 } from "node:path";
27740
27789
  import { createHash as createHash5 } from "node:crypto";
27741
27790
  function writePrivateFile(path, text) {
@@ -27780,7 +27829,7 @@ var init_settings_file = __esm({
27780
27829
  });
27781
27830
 
27782
27831
  // src/workers/run-env.ts
27783
- import { chmodSync as chmodSync6, existsSync as existsSync35, mkdirSync as mkdirSync24, mkdtempSync, readdirSync as readdirSync12, readFileSync as readFileSync35, rmSync as rmSync7, statSync as statSync13, writeFileSync as writeFileSync22 } from "node:fs";
27832
+ import { chmodSync as chmodSync6, existsSync as existsSync35, mkdirSync as mkdirSync24, mkdtempSync, readdirSync as readdirSync12, readFileSync as readFileSync35, rmSync as rmSync7, statSync as statSync14, writeFileSync as writeFileSync22 } from "node:fs";
27784
27833
  import { tmpdir } from "node:os";
27785
27834
  import { delimiter, join as join35 } from "node:path";
27786
27835
  function workerShell(env) {
@@ -27795,7 +27844,7 @@ function pinWorkersYamlCopy(env, root = WORKER_CONFIG_COPY_ROOT) {
27795
27844
  for (const d of readdirSync12(root)) {
27796
27845
  const dp = join35(root, d);
27797
27846
  try {
27798
- if (Date.now() - statSync13(dp).mtimeMs > COPY_MAX_AGE_MS) rmSync7(dp, { recursive: true, force: true });
27847
+ if (Date.now() - statSync14(dp).mtimeMs > COPY_MAX_AGE_MS) rmSync7(dp, { recursive: true, force: true });
27799
27848
  } catch {
27800
27849
  }
27801
27850
  }
@@ -28014,6 +28063,13 @@ function requestKill(logDir2, ledger, id, by = callerDescription(), forced = fal
28014
28063
  writeFileAtomic(killMarkerPath(logDir2, id), JSON.stringify(req));
28015
28064
  appendLedger(ledger, "WORKER-KILL", { id, by, pid: req.pid, ppid: req.ppid, cwd: req.cwd, ...forced ? { forced: 1 } : {}, ...reason ? { reason } : {} });
28016
28065
  }
28066
+ function peekMarker(logDir2, id) {
28067
+ try {
28068
+ return JSON.parse(readFileSync36(killMarkerPath(logDir2, id), "utf8"));
28069
+ } catch {
28070
+ return null;
28071
+ }
28072
+ }
28017
28073
  function readMarker(logDir2, id) {
28018
28074
  const p = killMarkerPath(logDir2, id);
28019
28075
  if (!existsSync36(p)) return null;
@@ -28047,8 +28103,11 @@ function parentInfo() {
28047
28103
  function decideEndReason(a) {
28048
28104
  if (a.timedOut) return { reason: "deadline" };
28049
28105
  if (a.loopStopped) return { reason: "loop-stopped" };
28050
- if (!a.signal) return { reason: "exit" };
28051
- const marker = readMarker(a.logDir, a.id);
28106
+ const marker = a.signal || peekMarker(a.logDir, a.id)?.by === "pane audit" ? readMarker(a.logDir, a.id) : null;
28107
+ if (!a.signal && !marker) return { reason: "exit" };
28108
+ if (!a.signal && marker) {
28109
+ return { reason: "pai-worker-kill", by: marker.by, note: `killed by ${marker.by}${marker.reason ? `: ${marker.reason}` : ""}`, ...marker.reason ? { killReason: marker.reason } : {}, forced: true };
28110
+ }
28052
28111
  if (marker) {
28053
28112
  return {
28054
28113
  reason: "pai-worker-kill",
@@ -28619,7 +28678,7 @@ var init_scratch = __esm({
28619
28678
  });
28620
28679
 
28621
28680
  // src/workers/pending.ts
28622
- import { existsSync as existsSync43, readFileSync as readFileSync42, statSync as statSync14 } from "node:fs";
28681
+ import { existsSync as existsSync43, readFileSync as readFileSync42, statSync as statSync15 } from "node:fs";
28623
28682
  import { join as join42 } from "node:path";
28624
28683
  function invalidatePendingCache(logDir2, repoRoot) {
28625
28684
  const file = join42(logDir2, "pending-cache.json");
@@ -28656,7 +28715,7 @@ var init_pending = __esm({
28656
28715
 
28657
28716
  // src/workers/worktree.ts
28658
28717
  import { execFile as execFile2, execFileSync as execFileSync11, spawnSync as spawnSync3 } from "node:child_process";
28659
- 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";
28718
+ 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 statSync16 } from "node:fs";
28660
28719
  import { basename as basename8, dirname as dirname22, isAbsolute as isAbsolute2, join as join43, resolve as resolve7, sep as sep2 } from "node:path";
28661
28720
  import { tmpdir as tmpdir3, platform } from "node:os";
28662
28721
  function isSlotWorktree(dir) {
@@ -29922,7 +29981,7 @@ function gcWorktrees(logDir2, olderThanHours = 24, dryRun = false, now = Date.no
29922
29981
  if (!tree || !existsSync44(tree.dir) || isLive(st) || isSlotWorktree(tree.dir) || landed.has(realpathOr(tree.dir))) continue;
29923
29982
  let end = 0;
29924
29983
  try {
29925
- end = Math.floor(statSync15(statusPath(logDir2, st.id)).mtimeMs);
29984
+ end = Math.floor(statSync16(statusPath(logDir2, st.id)).mtimeMs);
29926
29985
  } catch {
29927
29986
  continue;
29928
29987
  }
@@ -29958,7 +30017,7 @@ function gcWorktrees(logDir2, olderThanHours = 24, dryRun = false, now = Date.no
29958
30017
  if (!tree || st.merged || st.archived || isLive(st) || !isSlotWorktree(tree.dir)) continue;
29959
30018
  let end = 0;
29960
30019
  try {
29961
- end = Math.floor(statSync15(statusPath(logDir2, st.id)).mtimeMs);
30020
+ end = Math.floor(statSync16(statusPath(logDir2, st.id)).mtimeMs);
29962
30021
  } catch {
29963
30022
  continue;
29964
30023
  }
@@ -29970,7 +30029,7 @@ function gcWorktrees(logDir2, olderThanHours = 24, dryRun = false, now = Date.no
29970
30029
  const dir = join43(root, ent.name);
29971
30030
  if (!ent.isDirectory() || owned.has(resolve7(dir)) || isSlotWorktree(dir) || ent.name.startsWith("spare-") || landed.has(realpathOr(dir))) continue;
29972
30031
  try {
29973
- if (Math.floor(statSync15(dir).mtimeMs) > cutoff) continue;
30032
+ if (Math.floor(statSync16(dir).mtimeMs) > cutoff) continue;
29974
30033
  } catch {
29975
30034
  continue;
29976
30035
  }
@@ -29999,7 +30058,7 @@ function gcWorktrees(logDir2, olderThanHours = 24, dryRun = false, now = Date.no
29999
30058
  function gcWorktreesThrottled(logDir2, everyMin = 60, now = Date.now(), opts = {}) {
30000
30059
  const stamp = join43(logDir2, GC_STAMP);
30001
30060
  try {
30002
- if (now - statSync15(stamp).mtimeMs < everyMin * 6e4) return null;
30061
+ if (now - statSync16(stamp).mtimeMs < everyMin * 6e4) return null;
30003
30062
  } catch {
30004
30063
  }
30005
30064
  mkdirSync28(logDir2, { recursive: true });
@@ -30571,7 +30630,7 @@ var init_reap = __esm({
30571
30630
  });
30572
30631
 
30573
30632
  // src/workers/active-time.ts
30574
- import { mkdirSync as mkdirSync29, readFileSync as readFileSync45, statSync as statSync16, writeFileSync as writeFileSync24 } from "node:fs";
30633
+ import { mkdirSync as mkdirSync29, readFileSync as readFileSync45, statSync as statSync17, writeFileSync as writeFileSync24 } from "node:fs";
30575
30634
  import { join as join46 } from "node:path";
30576
30635
  function read(logDir2, id) {
30577
30636
  try {
@@ -30588,7 +30647,7 @@ function buildWaitMs(logDir2, id, now = Date.now()) {
30588
30647
  function routerAcct(logDir2, id) {
30589
30648
  const p = join46(logDir2, "router-sched.json");
30590
30649
  try {
30591
- const mtimeMs = statSync16(p).mtimeMs;
30650
+ const mtimeMs = statSync17(p).mtimeMs;
30592
30651
  let c = schedCache.get(p);
30593
30652
  if (!c || c.mtimeMs !== mtimeMs) {
30594
30653
  const j = JSON.parse(readFileSync45(p, "utf8"));
@@ -30957,6 +31016,7 @@ function fireDeadline(logDir2, status, ledger, limit) {
30957
31016
  status.last = what;
30958
31017
  saveStatus(logDir2, status);
30959
31018
  appendLedger(ledger, "WORKER-DEADLINE", { id: status.id, minutes: limit.minutes, waitedMin: waited });
31019
+ appendStopEvent(logDir2, status.id, { killed_by: "deadline", forced: false, reason: `${what} (timer: --max-minutes/--deadline, armed at spawn)` });
30960
31020
  void killTree(logDir2, status.id, { skipRoot: true, by: "deadline", reason: `parent worker ${what}` }).catch(() => void 0);
30961
31021
  }
30962
31022
  function trackBlocked(logDir2, status, limit) {
@@ -31032,6 +31092,10 @@ async function finaliseRun(f) {
31032
31092
  }
31033
31093
  const end = decideEndReason({ logDir: logDir2, id: wid, timedOut: f.timedOut !== void 0, loopStopped: !!loopStop });
31034
31094
  status.endReason = end.reason;
31095
+ if (end.reason === "pai-worker-kill" && !f.timedOut && end.killReason && !succeeded) {
31096
+ status.last = shortText(end.killReason, 90);
31097
+ report = { ...report ?? {}, result: report?.result ?? "-", why: end.killReason, notes: [end.killReason, report?.notes ?? f.fallbackText].filter(Boolean).join("\n") };
31098
+ }
31035
31099
  status.claimsContinue = report?.result === "~";
31036
31100
  saveStatus(logDir2, status);
31037
31101
  appendLedger(ledger, "WORKER-END", { id: wid, ...f.end, rc, secs: f.secs, ...endFields(end) });
@@ -31658,7 +31722,8 @@ async function openOwnedPane(o) {
31658
31722
  let pidWaiter = null;
31659
31723
  let ended = false;
31660
31724
  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 });
31725
+ const openedAt = Date.now();
31726
+ 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
31727
  const settle = (code, signal) => {
31663
31728
  if (ended) return;
31664
31729
  ended = true;
@@ -34080,7 +34145,7 @@ var init_local_idle = __esm({
34080
34145
  });
34081
34146
 
34082
34147
  // src/workers/pool-host-run.ts
34083
- import { existsSync as existsSync51, mkdirSync as mkdirSync36, openSync as openSync5, renameSync as renameSync19, statSync as statSync17 } from "node:fs";
34148
+ import { existsSync as existsSync51, mkdirSync as mkdirSync36, openSync as openSync5, renameSync as renameSync19, statSync as statSync18 } from "node:fs";
34084
34149
  import { join as join51 } from "node:path";
34085
34150
  function poolHostLogPath(logDir2) {
34086
34151
  return join51(poolDir(logDir2), "host.log");
@@ -34089,7 +34154,7 @@ function openHostLog(logDir2, capBytes = LOG_CAP_BYTES) {
34089
34154
  mkdirSync36(poolDir(logDir2), { recursive: true });
34090
34155
  const path = poolHostLogPath(logDir2);
34091
34156
  try {
34092
- if (existsSync51(path) && statSync17(path).size > capBytes) renameSync19(path, `${path}.1`);
34157
+ if (existsSync51(path) && statSync18(path).size > capBytes) renameSync19(path, `${path}.1`);
34093
34158
  } catch {
34094
34159
  }
34095
34160
  return openSync5(path, "a");
@@ -34143,7 +34208,7 @@ var init_pool_host_run = __esm({
34143
34208
 
34144
34209
  // src/workers/pool-cli.ts
34145
34210
  import { spawn as spawn7 } from "node:child_process";
34146
- import { closeSync as closeSync4, existsSync as existsSync52, mkdirSync as mkdirSync37, statSync as statSync18, unlinkSync as unlinkSync11, writeFileSync as writeFileSync31, readFileSync as readFileSync52 } from "node:fs";
34211
+ import { closeSync as closeSync4, existsSync as existsSync52, mkdirSync as mkdirSync37, statSync as statSync19, unlinkSync as unlinkSync11, writeFileSync as writeFileSync31, readFileSync as readFileSync52 } from "node:fs";
34147
34212
  import { dirname as dirname26, join as join52 } from "node:path";
34148
34213
  import { fileURLToPath as fileURLToPath5 } from "node:url";
34149
34214
  function standalonePoolHostPath() {
@@ -34432,6 +34497,15 @@ async function runGates(a, wid, status) {
34432
34497
  logDir: logDir2,
34433
34498
  self: { id: wid, provider: target.providerName },
34434
34499
  cap: admitCap(target.provider.maxConcurrent, target.provider.conversationSlots, isLocalProvider(target.provider.baseUrl)),
34500
+ // a saved config change reaches a run that is already waiting
34501
+ capOf: () => {
34502
+ try {
34503
+ const p = readWorkersCached().providers[target.providerName] ?? target.provider;
34504
+ return admitCap(p.maxConcurrent, p.conversationSlots, isLocalProvider(p.baseUrl), capacityOf(config.capacity));
34505
+ } catch {
34506
+ return void 0;
34507
+ }
34508
+ },
34435
34509
  config: config.capacity,
34436
34510
  disabled: a.noQueue,
34437
34511
  priority: a.priority,
@@ -36277,7 +36351,7 @@ import { createServer as createServer3 } from "node:http";
36277
36351
  import { spawn as spawn9 } from "node:child_process";
36278
36352
  import { basename as basename9, dirname as dirname28, join as join57 } from "node:path";
36279
36353
  import { createInterface as createInterface3 } from "node:readline";
36280
- import { openSync as openSync8, closeSync as closeSync7, writeSync as writeSync3, mkdirSync as mkdirSync41, statSync as statSync19, readSync as readSync4, readFileSync as readFileSync55, existsSync as existsSync56, rmSync as rmSync11 } from "node:fs";
36354
+ import { openSync as openSync8, closeSync as closeSync7, writeSync as writeSync3, mkdirSync as mkdirSync41, statSync as statSync20, readSync as readSync4, readFileSync as readFileSync55, existsSync as existsSync56, rmSync as rmSync11 } from "node:fs";
36281
36355
 
36282
36356
  // src/workers/slots.ts
36283
36357
  init_pai_home();
@@ -36550,7 +36624,7 @@ var PoolSlotSession = class {
36550
36624
  };
36551
36625
  function routerUsageTail(file) {
36552
36626
  try {
36553
- const size = statSync19(file).size;
36627
+ const size = statSync20(file).size;
36554
36628
  const len = Math.min(size, 4e5);
36555
36629
  const buf = Buffer.alloc(len);
36556
36630
  const fd = openSync8(file, "r");
@@ -36591,7 +36665,27 @@ function sendJson(res, status, body) {
36591
36665
  function createPoolHost(opts = {}) {
36592
36666
  const { workers: config } = opts.config ? { workers: opts.config } : readWorkersSection();
36593
36667
  const logDir2 = opts.logDir ?? workersLogDir(config);
36594
- const settings = poolSettings(config);
36668
+ let settings = poolSettings(config);
36669
+ const configStamp = opts.configStamp ?? (opts.config ? null : () => workersConfigStamp());
36670
+ const readConfig = opts.readConfig ?? (() => readWorkersSection(void 0, () => {
36671
+ }).workers);
36672
+ let seenStamp = configStamp ? configStamp() : "";
36673
+ let lastStampCheck = 0;
36674
+ const reloadSettings = (force = false) => {
36675
+ if (!configStamp) return false;
36676
+ const t = now().getTime();
36677
+ if (!force && t - lastStampCheck < 5e3) return false;
36678
+ lastStampCheck = t;
36679
+ const stamp = configStamp();
36680
+ if (stamp === seenStamp) return false;
36681
+ seenStamp = stamp;
36682
+ try {
36683
+ settings = poolSettings(readConfig());
36684
+ return true;
36685
+ } catch {
36686
+ return false;
36687
+ }
36688
+ };
36595
36689
  const port2 = opts.port ?? poolPort(config);
36596
36690
  const spawner = opts.spawner ?? realSpawner;
36597
36691
  const routerOn = opts.routerEnabled ?? loadConfig().router.enabled;
@@ -36618,7 +36712,7 @@ function createPoolHost(opts = {}) {
36618
36712
  };
36619
36713
  const fileMtime = opts.fileMtime ?? ((p) => {
36620
36714
  try {
36621
- return statSync19(p).mtimeMs;
36715
+ return statSync20(p).mtimeMs;
36622
36716
  } catch {
36623
36717
  return null;
36624
36718
  }
@@ -36734,6 +36828,7 @@ function createPoolHost(opts = {}) {
36734
36828
  };
36735
36829
  const acquire = async (providerName, provider, model, cwd, shared) => {
36736
36830
  const key = slotKey(providerName, model, cwd);
36831
+ reloadSettings();
36737
36832
  reapSlots();
36738
36833
  const pick = pickSlot(
36739
36834
  [...slots.values()].map((s) => s.record),
@@ -36754,6 +36849,7 @@ function createPoolHost(opts = {}) {
36754
36849
  };
36755
36850
  const claimed = /* @__PURE__ */ new Set();
36756
36851
  const acquireSlotWorktree = async (providerName, provider, model, repo, wid, shared) => {
36852
+ reloadSettings();
36757
36853
  for (let n = 1; n <= settings.maxSlots; n++) {
36758
36854
  if (!slotServesRepo(logDir2, providerName, n, repo)) continue;
36759
36855
  const dir = slotPath(logDir2, providerName, n);
@@ -37350,6 +37446,7 @@ function createPoolHost(opts = {}) {
37350
37446
  await new Promise((resolve12) => server.close(() => resolve12()));
37351
37447
  };
37352
37448
  const reapSlots = () => {
37449
+ reloadSettings();
37353
37450
  let n = 0;
37354
37451
  for (const [k, s] of slots) {
37355
37452
  if (slotShouldReap(s.record, now().getTime(), settings.idleSecs)) {
@@ -37424,11 +37521,15 @@ function createPoolHost(opts = {}) {
37424
37521
  const timer = setInterval(() => void checkReload(), 3e4);
37425
37522
  timer.unref?.();
37426
37523
  }
37427
- if (!opts.noReaper && settings.idleSecs > 0) {
37524
+ if (!opts.noReaper) {
37525
+ const timer = setInterval(() => reloadSettings(), 5e3);
37526
+ timer.unref?.();
37527
+ }
37528
+ if (!opts.noReaper) {
37428
37529
  const timer = setInterval(reapSlots, 3e4);
37429
37530
  timer.unref?.();
37430
37531
  }
37431
- if (!opts.noReaper && settings.idleKillSec > 0) {
37532
+ if (!opts.noReaper) {
37432
37533
  const timer = setInterval(() => {
37433
37534
  reapSpares();
37434
37535
  refreshSpares();
@@ -37484,6 +37585,8 @@ function createPoolHost(opts = {}) {
37484
37585
  runTask,
37485
37586
  shutdown,
37486
37587
  reapSlots,
37588
+ settings: () => settings,
37589
+ reloadSettings,
37487
37590
  reapSpares,
37488
37591
  refreshSpares,
37489
37592
  checkReload,
@@ -7408,7 +7408,7 @@ function parseEscalate(v, bad2) {
7408
7408
  }
7409
7409
 
7410
7410
  // src/workers/config.ts
7411
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
7411
+ import { existsSync as existsSync6, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
7412
7412
 
7413
7413
  // src/daemon/config.ts
7414
7414
  import { homedir as homedir2, userInfo } from "node:os";