@tekmidian/pai 0.66.6 → 0.66.7

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 (118) hide show
  1. package/dist/{aibroker-client-WCZi_tn-.mjs → aibroker-client-BevXY1Zz.mjs} +3 -3
  2. package/dist/{aibroker-client-WCZi_tn-.mjs.map → aibroker-client-BevXY1Zz.mjs.map} +1 -1
  3. package/dist/{aibroker-client-Ck3p3k_-.mjs → aibroker-client-CxTpL_u7.mjs} +1 -1
  4. package/dist/{auto-route-BnizyALK.mjs → auto-route-BVeAp0fl.mjs} +1 -1
  5. package/dist/{auto-route-BnizyALK.mjs.map → auto-route-BVeAp0fl.mjs.map} +1 -1
  6. package/dist/{auto-route-D6fW1Q8z.mjs → auto-route-CboBqsN3.mjs} +1 -1
  7. package/dist/{chain-2_uoiEdD.mjs → chain-8hFKr23C.mjs} +3 -3
  8. package/dist/{chain-2_uoiEdD.mjs.map → chain-8hFKr23C.mjs.map} +1 -1
  9. package/dist/cli/index.mjs +16 -15
  10. package/dist/cli/index.mjs.map +1 -1
  11. package/dist/cli/program.mjs +15 -14
  12. package/dist/{config-CnsDMETf.mjs → config-UWtzLpXi.mjs} +1 -1
  13. package/dist/{config-Ddc4DIPk.mjs → config-sfaArCsl.mjs} +12 -3
  14. package/dist/config-sfaArCsl.mjs.map +1 -0
  15. package/dist/{context-handover-cache-SFkWucuT.mjs → context-handover-cache-Bb-H_mTa.mjs} +7 -8
  16. package/dist/{context-handover-cache-SFkWucuT.mjs.map → context-handover-cache-Bb-H_mTa.mjs.map} +1 -1
  17. package/dist/daemon/index.mjs +14 -13
  18. package/dist/daemon/index.mjs.map +1 -1
  19. package/dist/daemon-BXTn2EgV.mjs +19 -0
  20. package/dist/{daemon-vLtT3yaI.mjs → daemon-CkbX-hV7.mjs} +757 -20
  21. package/dist/daemon-CkbX-hV7.mjs.map +1 -0
  22. package/dist/daemon-mcp/index.mjs +12 -11
  23. package/dist/daemon-mcp/index.mjs.map +1 -1
  24. package/dist/embedding-gate-BVrr0BgS.mjs +378 -0
  25. package/dist/embedding-gate-BVrr0BgS.mjs.map +1 -0
  26. package/dist/embedding-gate-Crj8awk7.mjs +5 -0
  27. package/dist/embeddings-BuA7v4lk.mjs +3 -0
  28. package/dist/{embeddings-DMVzpvRZ.mjs → embeddings-DFl88_y-.mjs} +16 -2
  29. package/dist/{embeddings-DMVzpvRZ.mjs.map → embeddings-DFl88_y-.mjs.map} +1 -1
  30. package/dist/{env-DiolswKQ.mjs → env-DqTjeKoA.mjs} +1 -1
  31. package/dist/{env-DiolswKQ.mjs.map → env-DqTjeKoA.mjs.map} +1 -1
  32. package/dist/factory-XrH66erA.mjs +9 -0
  33. package/dist/{factory-CXFHwvcv.mjs → factory-mNBitkL_.mjs} +28 -6
  34. package/dist/factory-mNBitkL_.mjs.map +1 -0
  35. package/dist/{fallback-DNzd3jJc.mjs → fallback-DdC1_s2d.mjs} +4 -4
  36. package/dist/{fallback-DNzd3jJc.mjs.map → fallback-DdC1_s2d.mjs.map} +1 -1
  37. package/dist/hooks/block-sleep-poll.mjs +7 -2
  38. package/dist/hooks/block-sleep-poll.mjs.map +3 -3
  39. package/dist/hooks/context-compression-hook.mjs +2 -0
  40. package/dist/hooks/context-compression-hook.mjs.map +2 -2
  41. package/dist/hooks/load-core-context.mjs +5 -5
  42. package/dist/hooks/load-core-context.mjs.map +2 -2
  43. package/dist/hooks/load-project-context.mjs +2 -0
  44. package/dist/hooks/load-project-context.mjs.map +2 -2
  45. package/dist/hooks/post-compact-inject.mjs +2 -0
  46. package/dist/hooks/post-compact-inject.mjs.map +2 -2
  47. package/dist/hooks/route-agents-to-worker.mjs +2 -0
  48. package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
  49. package/dist/hooks/security-validator.mjs +2 -0
  50. package/dist/hooks/security-validator.mjs.map +2 -2
  51. package/dist/hooks/whisper-rules.mjs +2 -0
  52. package/dist/hooks/whisper-rules.mjs.map +2 -2
  53. package/dist/hooks/worker-guard.mjs +82 -5
  54. package/dist/hooks/worker-guard.mjs.map +4 -4
  55. package/dist/hooks/worker-proxy.mjs +2 -0
  56. package/dist/hooks/worker-proxy.mjs.map +2 -2
  57. package/dist/hooks/worker-status-line.mjs +7 -2
  58. package/dist/hooks/worker-status-line.mjs.map +3 -3
  59. package/dist/hooks/worker-supervision.mjs +2 -0
  60. package/dist/hooks/worker-supervision.mjs.map +2 -2
  61. package/dist/{ipc-client-DkxRay-o.mjs → ipc-client-BgSzY9QJ.mjs} +2 -2
  62. package/dist/{ipc-client-DkxRay-o.mjs.map → ipc-client-BgSzY9QJ.mjs.map} +1 -1
  63. package/dist/main-resolver-CobQGm2B.mjs +7 -0
  64. package/dist/{main-resolver-SfGGg1DB.mjs → main-resolver-DEXky_Km.mjs} +6 -6
  65. package/dist/{main-resolver-SfGGg1DB.mjs.map → main-resolver-DEXky_Km.mjs.map} +1 -1
  66. package/dist/{planner-C-gzg7ye.mjs → planner-DBoB5GtC.mjs} +10 -9
  67. package/dist/{planner-C-gzg7ye.mjs.map → planner-DBoB5GtC.mjs.map} +1 -1
  68. package/dist/{postgres-BxmyQHoA.mjs → postgres-D-96lgE1.mjs} +84 -3
  69. package/dist/postgres-D-96lgE1.mjs.map +1 -0
  70. package/dist/postgres-TedJP3yF.mjs +7 -0
  71. package/dist/{program-CfG1T_ko.mjs → program-BXns_5kO.mjs} +211 -63
  72. package/dist/program-BXns_5kO.mjs.map +1 -0
  73. package/dist/{query-feedback-BPdapXKd.mjs → query-feedback-VI7Cl-Lr.mjs} +2 -2
  74. package/dist/{query-feedback-BPdapXKd.mjs.map → query-feedback-VI7Cl-Lr.mjs.map} +1 -1
  75. package/dist/router-CKn9e0fo.mjs +3 -0
  76. package/dist/{router-BaTbc9VX.mjs → router-dfjlaOMI.mjs} +2 -2
  77. package/dist/{router-BaTbc9VX.mjs.map → router-dfjlaOMI.mjs.map} +1 -1
  78. package/dist/{run-ChlIbDJ0.mjs → run-DPwQkRwh.mjs} +107 -9
  79. package/dist/run-DPwQkRwh.mjs.map +1 -0
  80. package/dist/{run-env-CQRnxNht.mjs → run-env-CkAmx3lb.mjs} +3 -3
  81. package/dist/{run-env-CQRnxNht.mjs.map → run-env-CkAmx3lb.mjs.map} +1 -1
  82. package/dist/{pai-home-UncxWxlX.mjs → runtime-paths-BiEi_gaG.mjs} +50 -2
  83. package/dist/runtime-paths-BiEi_gaG.mjs.map +1 -0
  84. package/dist/{sources-CM2g-CLT.mjs → sources-BxXbzpAJ.mjs} +1 -1
  85. package/dist/{sources-CM2g-CLT.mjs.map → sources-BxXbzpAJ.mjs.map} +1 -1
  86. package/dist/{zettelkasten-G0-ZTybr.mjs → zettelkasten-CzcPzEsL.mjs} +5 -3
  87. package/dist/{zettelkasten-BRIaHzFm.mjs → zettelkasten-wh2Yy1nS.mjs} +5 -4
  88. package/dist/zettelkasten-wh2Yy1nS.mjs.map +1 -0
  89. package/docker/docker-compose.yml +4 -0
  90. package/docs/commands/README.md +6 -0
  91. package/docs/commands/memory.md +52 -0
  92. package/docs/commands/worker.md +22 -0
  93. package/docs/install-linux.md +1 -0
  94. package/docs/memory.md +69 -0
  95. package/package.json +1 -1
  96. package/src/hooks/ts/lib/sleep-poll-gate.test.ts +2 -2
  97. package/src/hooks/ts/lib/sleep-poll-gate.ts +4 -4
  98. package/src/hooks/ts/lib/worker-guard-longwait.test.ts +48 -0
  99. package/src/hooks/ts/lib/worker-guard.ts +50 -6
  100. package/src/hooks/ts/pre-tool-use/block-sleep-poll.test.ts +1 -1
  101. package/src/hooks/ts/session-start/load-core-context.ts +11 -8
  102. package/src/hooks/ts/session-start/session-start-worker-guard.test.ts +34 -2
  103. package/dist/config-Ddc4DIPk.mjs.map +0 -1
  104. package/dist/daemon-BHQoEjt0.mjs +0 -18
  105. package/dist/daemon-vLtT3yaI.mjs.map +0 -1
  106. package/dist/embeddings-D0WOQpYR.mjs +0 -3
  107. package/dist/factory-CXFHwvcv.mjs.map +0 -1
  108. package/dist/factory-CnKsU6zX.mjs +0 -8
  109. package/dist/main-resolver-DrHtx8iW.mjs +0 -7
  110. package/dist/pai-home-UncxWxlX.mjs.map +0 -1
  111. package/dist/postgres-B2BEBT-J.mjs +0 -5
  112. package/dist/postgres-BxmyQHoA.mjs.map +0 -1
  113. package/dist/program-CfG1T_ko.mjs.map +0 -1
  114. package/dist/router-BK-hFeQ6.mjs +0 -3
  115. package/dist/run-ChlIbDJ0.mjs.map +0 -1
  116. package/dist/runtime-paths-Bw3Jk8qJ.mjs +0 -52
  117. package/dist/runtime-paths-Bw3Jk8qJ.mjs.map +0 -1
  118. package/dist/zettelkasten-BRIaHzFm.mjs.map +0 -1
@@ -3,20 +3,20 @@ import { a as slugify$1, i as parseSessionFilename } from "./migrate-Bq0esMOa.mj
3
3
  import { n as ensurePaiMarker } from "./pai-marker-DXVpFsYz.mjs";
4
4
  import { t as STOP_WORDS } from "./stop-words-DtxaTWU_.mjs";
5
5
  import { t as applyRecencyBoost } from "./search-CNAGTiJP.mjs";
6
- import { c as resolveFromModule, i as retryTransient, n as embedChunksWithBackend, r as indexProjectWithBackend, s as packageRoot } from "./postgres-BxmyQHoA.mjs";
7
- import { a as getStorageBackend, c as MergeError, f as humanDuration, i as getRegistryBackend, l as federationDbPath, o as oldRegistryPath, r as createStorageBackend, s as registryDbPath, u as oldFederationPath } from "./factory-CXFHwvcv.mjs";
8
- import { b as OWNER_LABEL_PREFIX, c as migrateConfigFile, d as readMainConfigRaw, f as writeMainConfigRaw, h as resolvedMainConfigPath, l as paiConfigFilePath, m as migrateMainConfigToYaml, n as CONFIG_FILE$2, o as expandHome, p as MainConfigError, s as loadConfig, t as CONFIG_DIR, u as paiConfigYamlFilePath, v as readJsonStrict, x as UNROUTED, y as writeJsonAtomic } from "./config-Ddc4DIPk.mjs";
9
- import { a as paiHomePath, i as paiHomeDir, n as migratePaiDir, o as resolvePaiFile, r as migratePaiFile, t as PaiFileMigrationError } from "./pai-home-UncxWxlX.mjs";
10
- import { a as schedulerLogPath, i as paiSocketPath, n as daemonLogPath } from "./runtime-paths-Bw3Jk8qJ.mjs";
11
- import { At as claudeProjectsDir, Ct as loadScanConfig, Dt as saveScanConfig, Et as resolveHome, Ft as formatDetection, It as formatDetectionJson, Mt as scanTranscriptFolders, Nt as transcriptFiles, Ot as upsertProject, Pt as detectProject, St as cmdScan, a as sessionKeepaliveLedgerSummary, bt as reexecBackground, ct as findLatestNote, jt as findMovedProjects, kt as upsertSession, l as resolveDaemonPid, lt as findNotesDir$1, o as parseSessionUsage, ot as appendCheckpointToNote, r as loadSessionKeepaliveState, rt as extractAndStoreTriples, s as totalUsageTokens, st as applyContinue, t as readContextHandoverCache, ut as readBodyFile, vt as migrateIdentityFile, w as migrateSummaryCooldowns, wt as migrateScanConfig, y as migrateWorkQueue } from "./context-handover-cache-SFkWucuT.mjs";
12
- import { B as DEFAULT_CONTEXT_WINDOW, C as maskKey, D as readWorkersSection, F as needsWorkersYamlRelocation, H as stripModelVariant, I as parseWorkersYamlDocument, L as relocateWorkersYaml, M as initWorkersYaml, N as inlineWorkersYamlKeys, P as migrateWorkersToYaml, R as workersYamlLegacyNotice, V as contextWindowFromModelId, b as getProviderOrNative, d as MODEL_CAPABILITIES, h as WorkersConfigError, p as PROVIDER_TAGS, r as ANTHROPIC_NATIVE, t as buildRunEnv, w as nativeAnthropicProvider, x as isModelCapability, y as expandHome$1, z as workersYamlPath } from "./run-env-CQRnxNht.mjs";
13
- import { $ as setWorkerLabel, F as pendingGate, G as isChatPane, I as pendingResults, J as loadStatuses, K as isLive, L as appendLedger, M as verifyWorker, O as discardWorker, P as formatPending, Q as saveStatus, Z as ownsPid, _ as markControlsHeld, _t as describeMcp, at as ensureProxyRunning, b as requestKill, c as handoffFromInside, dt as ensureNoMcpConfig, et as waitForTerminalStatus, f as checkPaneForWorker, ft as eventsPath, g as clickrControlsArgv, gt as projectLaunchConfig, h as openPaneForWorker, ht as pinNotices, i as usageContextTokens, it as DEFAULT_PROXY_PORT, j as mergeWorker, k as gcWorktrees, m as openFollowPane, mt as workersLogDir, n as runWorker, nt as parseRunnerArgs, o as parseWorkerReport, ot as stopProxy, p as closeEndedPanes, pt as ledgerPath, q as loadStatus, r as testProvider, tt as longInlinePromptHint, u as sayToWorker, v as callerDescription, vt as expandMcpNames, z as UNLABELED } from "./run-ChlIbDJ0.mjs";
14
- import { t as PaiClient } from "./ipc-client-DkxRay-o.mjs";
15
- import { A as getConfigValueOp, C as setWorkersEnabled, D as useProvider, E as updateProvider, M as setConfigValueOp, N as unsetConfigValueOp, O as MainConfigOpsError, S as setProviderModel, T as unsetClass, _ as removeProvider, a as followWorkers, b as setClass, c as statusLineOutput, d as addProvider, f as classTargetText, g as modelPrefsText, h as describeProviders, i as fallbackStatusText, j as listConfigOp, k as formatConfigGetOutput, l as readSpecPrompt, m as describeModels, n as fallbackOn, o as psOutput, p as describeCapabilities, r as fallbackStatus, s as replayOutput, t as fallbackOff, u as resolveSpecPath, v as resolveProviderName, w as unsetCapabilityPreference, x as setProviderEnabled, y as setCapabilityPreference } from "./fallback-DNzd3jJc.mjs";
16
- import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-SfGGg1DB.mjs";
17
- import { n as queriesDirPath, t as migrateQueriesDir } from "./query-feedback-BPdapXKd.mjs";
18
- import { i as sendToSession, n as fetchLiveSessions, r as revealItermSession, t as callAiBroker } from "./aibroker-client-WCZi_tn-.mjs";
19
- import { t as runChain } from "./chain-2_uoiEdD.mjs";
6
+ import { c as resolveFromModule, i as retryTransient, n as embedChunksWithBackend, r as indexProjectWithBackend, s as packageRoot } from "./postgres-D-96lgE1.mjs";
7
+ import { a as getStorageBackend, c as MergeError, f as humanDuration, i as getRegistryBackend, l as federationDbPath, o as oldRegistryPath, r as createStorageBackend, s as registryDbPath, u as oldFederationPath } from "./factory-mNBitkL_.mjs";
8
+ import { c as detectBackends, d as OLLAMA_DEFAULT_MODEL, f as OLLAMA_DEFAULT_URL, i as measureThroughput, o as BACKEND_IDS, p as OLLAMA_ID, s as createBackend, u as provisionOllama } from "./embedding-gate-BVrr0BgS.mjs";
9
+ import { b as OWNER_LABEL_PREFIX, c as migrateConfigFile, d as readMainConfigRaw, f as writeMainConfigRaw, h as resolvedMainConfigPath, l as paiConfigFilePath, m as migrateMainConfigToYaml, n as CONFIG_FILE$2, o as expandHome, p as MainConfigError, s as loadConfig, t as CONFIG_DIR, u as paiConfigYamlFilePath, v as readJsonStrict, x as UNROUTED, y as writeJsonAtomic } from "./config-sfaArCsl.mjs";
10
+ import { a as schedulerLogPath, c as migratePaiFile, d as resolvePaiFile, i as paiSocketPath, l as paiHomeDir, n as daemonLogPath, o as PaiFileMigrationError, s as migratePaiDir, u as paiHomePath } from "./runtime-paths-BiEi_gaG.mjs";
11
+ import { At as claudeProjectsDir, Ct as loadScanConfig, Dt as saveScanConfig, Et as resolveHome, Ft as formatDetection, It as formatDetectionJson, Mt as scanTranscriptFolders, Nt as transcriptFiles, Ot as upsertProject, Pt as detectProject, St as cmdScan, a as sessionKeepaliveLedgerSummary, bt as reexecBackground, ct as findLatestNote, jt as findMovedProjects, kt as upsertSession, l as resolveDaemonPid, lt as findNotesDir$1, o as parseSessionUsage, ot as appendCheckpointToNote, r as loadSessionKeepaliveState, rt as extractAndStoreTriples, s as totalUsageTokens, st as applyContinue, t as readContextHandoverCache, ut as readBodyFile, vt as migrateIdentityFile, w as migrateSummaryCooldowns, wt as migrateScanConfig, y as migrateWorkQueue } from "./context-handover-cache-Bb-H_mTa.mjs";
12
+ import { B as DEFAULT_CONTEXT_WINDOW, C as maskKey, D as readWorkersSection, F as needsWorkersYamlRelocation, H as stripModelVariant, I as parseWorkersYamlDocument, L as relocateWorkersYaml, M as initWorkersYaml, N as inlineWorkersYamlKeys, P as migrateWorkersToYaml, R as workersYamlLegacyNotice, V as contextWindowFromModelId, b as getProviderOrNative, d as MODEL_CAPABILITIES, h as WorkersConfigError, p as PROVIDER_TAGS, r as ANTHROPIC_NATIVE, t as buildRunEnv, w as nativeAnthropicProvider, x as isModelCapability, y as expandHome$1, z as workersYamlPath } from "./run-env-CkAmx3lb.mjs";
13
+ import { $ as saveStatus, A as gcWorktrees, B as UNLABELED, F as formatPending, I as pendingGate, J as loadStatus, K as isChatPane, L as pendingResults, M as mergeWorker, N as verifyWorker, Q as ownsPid, R as appendLedger, Y as loadStatuses, _ as clickrControlsArgv, _t as projectLaunchConfig, at as DEFAULT_PROXY_PORT, c as waitOn, d as sayToWorker, et as setWorkerLabel, ft as ensureNoMcpConfig, g as openPaneForWorker, gt as pinNotices, h as openFollowPane, ht as workersLogDir, i as usageContextTokens, k as discardWorker, l as handoffFromInside, m as closeEndedPanes, mt as ledgerPath, n as runWorker, nt as longInlinePromptHint, o as parseWorkerReport, ot as ensureProxyRunning, p as checkPaneForWorker, pt as eventsPath, q as isLive, r as testProvider, rt as parseRunnerArgs, st as stopProxy, tt as waitForTerminalStatus, v as markControlsHeld, vt as describeMcp, x as requestKill, y as callerDescription, yt as expandMcpNames } from "./run-DPwQkRwh.mjs";
14
+ import { t as PaiClient } from "./ipc-client-BgSzY9QJ.mjs";
15
+ import { A as getConfigValueOp, C as setWorkersEnabled, D as useProvider, E as updateProvider, M as setConfigValueOp, N as unsetConfigValueOp, O as MainConfigOpsError, S as setProviderModel, T as unsetClass, _ as removeProvider, a as followWorkers, b as setClass, c as statusLineOutput, d as addProvider, f as classTargetText, g as modelPrefsText, h as describeProviders, i as fallbackStatusText, j as listConfigOp, k as formatConfigGetOutput, l as readSpecPrompt, m as describeModels, n as fallbackOn, o as psOutput, p as describeCapabilities, r as fallbackStatus, s as replayOutput, t as fallbackOff, u as resolveSpecPath, v as resolveProviderName, w as unsetCapabilityPreference, x as setProviderEnabled, y as setCapabilityPreference } from "./fallback-DdC1_s2d.mjs";
16
+ import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-DEXky_Km.mjs";
17
+ import { n as queriesDirPath, t as migrateQueriesDir } from "./query-feedback-VI7Cl-Lr.mjs";
18
+ import { i as sendToSession, n as fetchLiveSessions, r as revealItermSession, t as callAiBroker } from "./aibroker-client-BevXY1Zz.mjs";
19
+ import { t as runChain } from "./chain-8hFKr23C.mjs";
20
20
  import { appendFileSync, chmodSync, closeSync, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
21
21
  import { homedir, platform, tmpdir, userInfo } from "node:os";
22
22
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
@@ -155,7 +155,7 @@ async function cmdPromote(opts) {
155
155
  console.error(dim$1(` Pick a durable location for the new project.`));
156
156
  process.exit(1);
157
157
  }
158
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
158
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
159
159
  const registryBackend = await getRegistryBackend();
160
160
  const encodedDir = encodeDir(targetPath);
161
161
  if (await registryBackend.getProjectBySlug(slug) ?? await registryBackend.getProjectByRootPath(targetPath) ?? await registryBackend.getProjectByEncodedDir(encodedDir)) {
@@ -2039,7 +2039,7 @@ async function cmdUnregister(slug, opts = {}) {
2039
2039
  //#region src/cli/commands/project/projects-index.ts
2040
2040
  function registerProjectsCommands(projectsCmd) {
2041
2041
  projectsCmd.command("list", { isDefault: true }).description("Show the unified deduped listing (same as `pai`).\nUse --all to include cold / zero-session / archived projects.").option("--all", "Show all entries including cold / zero-session / archived projects").option("-n, --n <count>", "Max rows to show", "20").action(async (opts) => {
2042
- const { cmdMain } = await import("./main-resolver-DrHtx8iW.mjs");
2042
+ const { cmdMain } = await import("./main-resolver-CobQGm2B.mjs");
2043
2043
  await cmdMain(void 0, void 0, opts);
2044
2044
  });
2045
2045
  projectsCmd.command("list-raw").description("Raw registry listing with slug, path, status, last_active columns").option("--all", "Include archived projects (default: active only)").option("--status <status>", "Filter by status: active | archived").option("--tag <tag>", "Filter by tag").option("--type <type>", "Filter by type").action(async (opts) => {
@@ -2905,7 +2905,15 @@ const DEFAULT_PAGE_SIZE = 500;
2905
2905
  async function runEmbed(backend, projectId, projectSlug, batchSize = 50, pageSize = DEFAULT_PAGE_SIZE) {
2906
2906
  const label = projectSlug ? `project ${projectSlug}` : "all projects";
2907
2907
  console.log(dim$1(`Generating embeddings for ${label} (this may take a while on first run)...`));
2908
- const { generateEmbeddings, serializeEmbedding } = await import("./embeddings-D0WOQpYR.mjs");
2908
+ const { serializeEmbedding } = await import("./embeddings-BuA7v4lk.mjs");
2909
+ const { gateBackend } = await import("./embedding-gate-Crj8awk7.mjs");
2910
+ const gate = await gateBackend(backend, { record: true });
2911
+ if (!gate.ok) {
2912
+ console.error(err(gate.reason));
2913
+ process.exitCode = 1;
2914
+ return;
2915
+ }
2916
+ const embedder = gate.backend;
2909
2917
  const { chunks: totalEstimate } = projectId !== void 0 ? await backend.getProjectStats(projectId) : await backend.getStats();
2910
2918
  let done = 0;
2911
2919
  let after = null;
@@ -2914,7 +2922,7 @@ async function runEmbed(backend, projectId, projectSlug, batchSize = 50, pageSiz
2914
2922
  if (page.length === 0) break;
2915
2923
  for (let i = 0; i < page.length; i += batchSize) {
2916
2924
  const batch = page.slice(i, i + batchSize);
2917
- const vecs = await generateEmbeddings(batch.map((r) => r.text));
2925
+ const vecs = await retryTransient(() => embedder.embed(batch.map((r) => r.text)));
2918
2926
  await Promise.all(batch.map((row, j) => retryTransient(() => backend.updateEmbedding(row.id, serializeEmbedding(vecs[j])))));
2919
2927
  done += batch.length;
2920
2928
  process.stdout.write(`\r ${done} / ~${totalEstimate} chunks embedded...`);
@@ -3074,10 +3082,14 @@ function registerSearchCommand(memoryCmd) {
3074
3082
  let results;
3075
3083
  if (mode === "keyword") results = await backend.searchKeyword(query, searchOpts);
3076
3084
  else {
3077
- const { generateEmbedding } = await import("./embeddings-D0WOQpYR.mjs");
3085
+ const { embedQuery } = await import("./embedding-gate-Crj8awk7.mjs");
3078
3086
  console.log(dim$1("Generating query embedding..."));
3079
- const queryEmbedding = await generateEmbedding(query, true);
3080
- if (mode === "semantic") results = await backend.searchSemantic(queryEmbedding, searchOpts);
3087
+ const q = await embedQuery(backend, query);
3088
+ const queryEmbedding = q.vec;
3089
+ if (!queryEmbedding) {
3090
+ console.log(dim$1(` ${q.note}`));
3091
+ results = await backend.searchKeyword(query, searchOpts);
3092
+ } else if (mode === "semantic") results = await backend.searchSemantic(queryEmbedding, searchOpts);
3081
3093
  else {
3082
3094
  const [keywordResults, semanticResults] = await Promise.all([backend.searchKeyword(query, {
3083
3095
  ...searchOpts,
@@ -3259,9 +3271,9 @@ function registerStatsCommands(memoryCmd) {
3259
3271
  //#region src/cli/commands/memory/sources-cmd.ts
3260
3272
  function registerSourcesCommand(memoryCmd) {
3261
3273
  memoryCmd.command("sources").description("Show what the indexer has taken in: composition by source, which roots\ncontent enters from, the heaviest single files, and how many chunks are\nrewritten per day (which distinguishes a finite backlog from a treadmill).").option("--limit <n>", "Rows per section (default 8)", "8").action(async (opts) => {
3262
- const { createStorageBackend } = await import("./factory-CnKsU6zX.mjs");
3263
- const { loadConfig } = await import("./config-CnsDMETf.mjs");
3264
- const { cmdMemorySources } = await import("./sources-CM2g-CLT.mjs");
3274
+ const { createStorageBackend } = await import("./factory-XrH66erA.mjs");
3275
+ const { loadConfig } = await import("./config-UWtzLpXi.mjs");
3276
+ const { cmdMemorySources } = await import("./sources-BxXbzpAJ.mjs");
3265
3277
  let backend;
3266
3278
  try {
3267
3279
  backend = await createStorageBackend(loadConfig());
@@ -3318,6 +3330,99 @@ function registerPassCommand(memoryCmd) {
3318
3330
  });
3319
3331
  }
3320
3332
 
3333
+ //#endregion
3334
+ //#region src/memory/reembed.ts
3335
+ async function reembedIndex(storage, target, opts = {}) {
3336
+ const batch = opts.batchSize ?? 5e3;
3337
+ let total = 0;
3338
+ for (;;) {
3339
+ const n = await storage.clearEmbeddingsBatch(batch);
3340
+ if (n === 0) break;
3341
+ total += n;
3342
+ opts.onBatch?.(total);
3343
+ }
3344
+ await storage.setEmbeddingBinding({
3345
+ backend: target.id,
3346
+ model: target.model,
3347
+ dims: target.dims
3348
+ });
3349
+ return total;
3350
+ }
3351
+
3352
+ //#endregion
3353
+ //#region src/cli/commands/memory/backend.ts
3354
+ function fail$5(e) {
3355
+ console.error(err(e instanceof Error ? e.message : String(e)));
3356
+ process.exitCode = 1;
3357
+ }
3358
+ function registerBackendCommands(memoryCmd) {
3359
+ const backendCmd = memoryCmd.command("backend").description("Embedding backends: detect, use, provision (an index is bound to the backend that embedded it)");
3360
+ backendCmd.command("detect").description("Probe the available embedding backends (ollama, then transformers-cpu) and recommend the fastest").action(async () => {
3361
+ try {
3362
+ const cfg = loadConfig();
3363
+ const { results, recommended } = await detectBackends(cfg);
3364
+ for (const r of results) console.log(` ${r.ok ? ok$1(r.id) : dim$1(r.id)} ${r.ok ? "available" : "unavailable"}: ${r.reason}`);
3365
+ console.log(`\nConfigured: ${bold$1(cfg.embedding?.backend ?? "transformers-cpu-q8")}`);
3366
+ console.log(recommended ? `Recommended: ${bold$1(recommended)}` : "Recommended: none available");
3367
+ if (recommended && recommended !== cfg.embedding?.backend) console.log(dim$1(` Switch with \`pai memory backend use ${recommended}\` (an existing index also needs \`pai memory reembed\`).`));
3368
+ } catch (e) {
3369
+ fail$5(e);
3370
+ }
3371
+ });
3372
+ backendCmd.command("use <id>").description(`Write the embedding backend to config (${BACKEND_IDS.join(" | ")}); does not touch the index`).option("--model <name>", "Model name on the backend (ollama: server-side model name)").action(async (id, opts) => {
3373
+ try {
3374
+ const b = createBackend(id, loadConfig(), opts.model);
3375
+ setConfigValueOp("embedding.backend", id);
3376
+ if (opts.model) setConfigValueOp("embedding.model", opts.model, { force: true });
3377
+ console.log(ok$1(`embedding.backend = ${id}`) + (opts.model ? ` (model ${b.model})` : ""));
3378
+ const avail = await b.available();
3379
+ if (!avail.ok) console.log(dim$1(` Note: not available right now: ${avail.reason}`));
3380
+ console.log(dim$1(" If the index already holds vectors from another backend, run `pai memory reembed`."));
3381
+ } catch (e) {
3382
+ fail$5(e);
3383
+ }
3384
+ });
3385
+ backendCmd.command("provision <backend>").description("Provision a backend's model. ollama: download the F16 GGUF of arctic-embed-m-v1.5 and `ollama create` it").action(async (name) => {
3386
+ try {
3387
+ if (name !== "ollama") throw new Error(`Cannot provision "${name}"; only "ollama" needs provisioning`);
3388
+ const cfg = loadConfig();
3389
+ await provisionOllama({
3390
+ baseUrl: cfg.embedding?.ollama?.baseUrl ?? OLLAMA_DEFAULT_URL,
3391
+ model: cfg.embedding?.model ?? OLLAMA_DEFAULT_MODEL
3392
+ });
3393
+ console.log(ok$1("Done.") + dim$1(` Use it with \`pai memory backend use ${OLLAMA_ID}\`.`));
3394
+ } catch (e) {
3395
+ fail$5(e);
3396
+ }
3397
+ });
3398
+ memoryCmd.command("reembed").description("Switch the index to an embedding backend: clears all vectors (batched, resumable); `pai memory embed` refills").option("--backend <id>", "Target backend (default: the configured one); also written to config").option("--yes", "Confirm; without it only the plan is printed").action(async (opts) => {
3399
+ try {
3400
+ const cfg = loadConfig();
3401
+ const id = opts.backend ?? cfg.embedding?.backend ?? "transformers-cpu-q8";
3402
+ const target = createBackend(id, cfg);
3403
+ const avail = await target.available();
3404
+ if (!avail.ok) throw new Error(`${id} is not available: ${avail.reason}`);
3405
+ const storage = await getStorageBackend();
3406
+ const { chunks } = await storage.getStats();
3407
+ const cps = await measureThroughput(target, Array.from({ length: 32 }, () => "memory index chunk embedding vector query ".repeat(40)));
3408
+ const eta = cps > 0 ? Math.round(chunks / cps / 60) : NaN;
3409
+ console.log(`Index: ${bold$1(String(chunks))} chunks. Backend ${bold$1(id)} runs ~${cps.toFixed(1)} chunks/s: ETA ~${eta} min.`);
3410
+ if (!opts.yes) {
3411
+ console.error(err("Refusing without --yes: this clears every stored vector (keyword search keeps working while it refills)."));
3412
+ process.exitCode = 1;
3413
+ return;
3414
+ }
3415
+ const cleared = await reembedIndex(storage, target, { onBatch: (n) => process.stdout.write(`\r ${n} vectors cleared...`) });
3416
+ process.stdout.write("\r");
3417
+ if (opts.backend && opts.backend !== cfg.embedding?.backend) setConfigValueOp("embedding.backend", id);
3418
+ console.log(ok$1(`Cleared ${cleared} vectors; index bound to ${id} (${target.model}).`));
3419
+ console.log(dim$1(" Refill with `pai memory embed --background` (the daemon pass also does it)."));
3420
+ } catch (e) {
3421
+ fail$5(e);
3422
+ }
3423
+ });
3424
+ }
3425
+
3321
3426
  //#endregion
3322
3427
  //#region src/cli/commands/memory/index.ts
3323
3428
  function registerMemoryCommands(memoryCmd) {
@@ -3327,6 +3432,7 @@ function registerMemoryCommands(memoryCmd) {
3327
3432
  registerStatsCommands(memoryCmd);
3328
3433
  registerSourcesCommand(memoryCmd);
3329
3434
  registerPassCommand(memoryCmd);
3435
+ registerBackendCommands(memoryCmd);
3330
3436
  }
3331
3437
 
3332
3438
  //#endregion
@@ -4001,8 +4107,8 @@ async function escalate(task, headline, detail, state, now, opts) {
4001
4107
  state.alarmedAt[task.id] = now;
4002
4108
  let delivered = false;
4003
4109
  try {
4004
- const { routeNotification } = await import("./router-BK-hFeQ6.mjs");
4005
- const { loadConfig } = await import("./config-CnsDMETf.mjs");
4110
+ const { routeNotification } = await import("./router-CKn9e0fo.mjs");
4111
+ const { loadConfig } = await import("./config-UWtzLpXi.mjs");
4006
4112
  delivered = (await routeNotification({
4007
4113
  event: "error",
4008
4114
  title: `PAI: ${headline}`,
@@ -4037,7 +4143,7 @@ async function escalate(task, headline, detail, state, now, opts) {
4037
4143
  async function alertParked(task, reason) {
4038
4144
  const text = `PAI parked "${task.title}" (${task.id}) — the scheduler will not retry it.\nReason: ${reason}\nTo release it: fix the cause, then move the due date — due_string, natural language only (e.g. "tomorrow 9am").`;
4039
4145
  try {
4040
- const { callAiBroker } = await import("./aibroker-client-Ck3p3k_-.mjs");
4146
+ const { callAiBroker } = await import("./aibroker-client-CxTpL_u7.mjs");
4041
4147
  await callAiBroker("pailot_send", { text }, 8e3);
4042
4148
  } catch (e) {
4043
4149
  console.error(`[pai-poller] parked-task alert not delivered to PAILot (${e instanceof Error ? e.message : String(e)}): ${text}`);
@@ -6826,6 +6932,7 @@ async function cmdStatus$1() {
6826
6932
  console.log(dim$1(` PID: ${resolveDaemonPid() ?? "unknown"}`));
6827
6933
  console.log(dim$1(` Uptime: ${s["uptime"]}s`));
6828
6934
  console.log(dim$1(` Socket: ${s["socketPath"]}`));
6935
+ if (s["dashboard"]) console.log(dim$1(` Dashboard: ${s["dashboard"]}`));
6829
6936
  const health = formatStorageHealth(s);
6830
6937
  if (health.length > 0) {
6831
6938
  console.log();
@@ -7132,8 +7239,8 @@ function cmdLogs(opts) {
7132
7239
  }
7133
7240
  function registerDaemonCommands(daemonCmd) {
7134
7241
  daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
7135
- const { serve } = await import("./daemon-BHQoEjt0.mjs");
7136
- const { loadConfig: lc, ensureConfigDir } = await import("./config-CnsDMETf.mjs");
7242
+ const { serve } = await import("./daemon-BXTn2EgV.mjs");
7243
+ const { loadConfig: lc, ensureConfigDir } = await import("./config-UWtzLpXi.mjs");
7137
7244
  ensureConfigDir();
7138
7245
  await serve(lc());
7139
7246
  });
@@ -7742,12 +7849,36 @@ async function stepStorage(rl) {
7742
7849
  //#endregion
7743
7850
  //#region src/cli/commands/setup/steps/03-embedding.ts
7744
7851
  /** Step 3: Embedding model selection for semantic search. */
7852
+ /**
7853
+ * Probe the embedding backends (also under --yes). A fresh install adopts the
7854
+ * fastest available one; an existing install (embeddingModel already set) may
7855
+ * hold vectors from the current backend, so it is only told what is available.
7856
+ */
7857
+ async function stepBackend(rl, fresh) {
7858
+ const { results, recommended } = await detectBackends();
7859
+ line$1();
7860
+ for (const r of results) console.log(` ${r.ok ? c.ok(r.id) : c.dim(r.id)}: ${r.reason}`);
7861
+ if (!recommended) return {};
7862
+ if (!fresh) {
7863
+ console.log(c.dim(` Recommended: ${recommended}. Switch with \`pai memory backend use ${recommended}\` + \`pai memory reembed\`.`));
7864
+ return {};
7865
+ }
7866
+ if (recommended === OLLAMA_ID && await promptYesNo(rl, "Use Ollama (GPU, several times faster)?", true)) return { embedding: {
7867
+ backend: OLLAMA_ID,
7868
+ model: OLLAMA_DEFAULT_MODEL,
7869
+ ollama: { baseUrl: OLLAMA_DEFAULT_URL }
7870
+ } };
7871
+ return {};
7872
+ }
7745
7873
  async function stepEmbedding(rl) {
7746
7874
  section("Step 3: Embedding Model");
7747
7875
  const existing = readConfigRaw();
7748
7876
  if (existing.embeddingModel) {
7749
7877
  console.log(c.ok(`Embedding model: ${existing.embeddingModel}. Skipping.`));
7750
- return { embeddingModel: existing.embeddingModel };
7878
+ return {
7879
+ embeddingModel: existing.embeddingModel,
7880
+ ...await stepBackend(rl, false)
7881
+ };
7751
7882
  }
7752
7883
  line$1();
7753
7884
  line$1(" An embedding model converts your text into vectors for semantic search.");
@@ -7771,12 +7902,13 @@ async function stepEmbedding(rl) {
7771
7902
  description: "BM25/keyword search only. No model download needed. You can add embeddings later by running `pai memory embed` after selecting a model."
7772
7903
  }
7773
7904
  ]);
7774
- const selectedModel = {
7905
+ const models = {
7775
7906
  0: "Snowflake/snowflake-arctic-embed-m-v1.5",
7776
7907
  1: "BAAI/bge-small-en-v1.5",
7777
7908
  2: "nomic-ai/nomic-embed-text-v1.5",
7778
7909
  3: null
7779
- }[choice];
7910
+ };
7911
+ const selectedModel = models[choice];
7780
7912
  line$1();
7781
7913
  if (selectedModel) {
7782
7914
  console.log(c.ok(`Model selected: ${selectedModel}`));
@@ -7785,7 +7917,11 @@ async function stepEmbedding(rl) {
7785
7917
  console.log(c.ok("Skipping embeddings. Keyword search will still work."));
7786
7918
  console.log(c.dim(` Add later: update embeddingModel in ${CONFIG_FILE$2}`));
7787
7919
  }
7788
- return { embeddingModel: selectedModel ?? "none" };
7920
+ const backendUpdate = selectedModel === models[0] ? await stepBackend(rl, true) : {};
7921
+ return {
7922
+ embeddingModel: selectedModel ?? "none",
7923
+ ...backendUpdate
7924
+ };
7789
7925
  }
7790
7926
 
7791
7927
  //#endregion
@@ -9759,7 +9895,7 @@ async function cmdExplore(note, opts) {
9759
9895
  const depth = parseInt(opts.depth ?? "3", 10);
9760
9896
  const direction = opts.direction ?? "both";
9761
9897
  const mode = opts.mode ?? "all";
9762
- const { zettelExplore } = await import("./zettelkasten-G0-ZTybr.mjs");
9898
+ const { zettelExplore } = await import("./zettelkasten-CzcPzEsL.mjs");
9763
9899
  const result = await zettelExplore(await getFedBackend(), {
9764
9900
  startNote: note,
9765
9901
  depth,
@@ -9824,7 +9960,7 @@ async function cmdHealth(opts) {
9824
9960
  const projectPath = opts.project;
9825
9961
  const recentDays = parseInt(opts.days ?? "30", 10);
9826
9962
  const includeTypes = opts.include ? opts.include.split(",").map((s) => s.trim()) : void 0;
9827
- const { zettelHealth } = await import("./zettelkasten-G0-ZTybr.mjs");
9963
+ const { zettelHealth } = await import("./zettelkasten-CzcPzEsL.mjs");
9828
9964
  const result = await zettelHealth(await getFedBackend(), {
9829
9965
  scope,
9830
9966
  projectPath,
@@ -9895,7 +10031,7 @@ async function cmdSurprise(note, opts) {
9895
10031
  const limit = parseInt(opts.limit ?? "10", 10);
9896
10032
  const minSimilarity = parseFloat(opts.minSimilarity ?? "0.3");
9897
10033
  const minGraphDistance = parseInt(opts.minDistance ?? "3", 10);
9898
- const { zettelSurprise } = await import("./zettelkasten-G0-ZTybr.mjs");
10034
+ const { zettelSurprise } = await import("./zettelkasten-CzcPzEsL.mjs");
9899
10035
  const backend = await getFedBackend();
9900
10036
  console.log();
9901
10037
  console.log(header(" PAI Zettel Surprise"));
@@ -9950,7 +10086,7 @@ async function cmdSuggest(note, opts) {
9950
10086
  const vaultProjectId = parseInt(opts.vaultProjectId, 10);
9951
10087
  const limit = parseInt(opts.limit ?? "5", 10);
9952
10088
  const excludeLinked = opts.excludeLinked !== false;
9953
- const { zettelSuggest } = await import("./zettelkasten-G0-ZTybr.mjs");
10089
+ const { zettelSuggest } = await import("./zettelkasten-CzcPzEsL.mjs");
9954
10090
  const backend = await getFedBackend();
9955
10091
  console.log();
9956
10092
  console.log(header(" PAI Zettel Suggest"));
@@ -10003,7 +10139,7 @@ async function cmdConverse(question, opts) {
10003
10139
  const vaultProjectId = parseInt(opts.vaultProjectId, 10);
10004
10140
  const depth = parseInt(opts.depth ?? "2", 10);
10005
10141
  const limit = parseInt(opts.limit ?? "15", 10);
10006
- const { zettelConverse } = await import("./zettelkasten-G0-ZTybr.mjs");
10142
+ const { zettelConverse } = await import("./zettelkasten-CzcPzEsL.mjs");
10007
10143
  const backend = await getFedBackend();
10008
10144
  console.log();
10009
10145
  console.log(header(" PAI Zettel Converse"));
@@ -10066,7 +10202,7 @@ async function cmdThemes(opts) {
10066
10202
  const minClusterSize = parseInt(opts.minSize ?? "3", 10);
10067
10203
  const maxThemes = parseInt(opts.maxThemes ?? "10", 10);
10068
10204
  const similarityThreshold = parseFloat(opts.threshold ?? "0.65");
10069
- const { zettelThemes } = await import("./zettelkasten-G0-ZTybr.mjs");
10205
+ const { zettelThemes } = await import("./zettelkasten-CzcPzEsL.mjs");
10070
10206
  const backend = await getFedBackend();
10071
10207
  console.log();
10072
10208
  console.log(header(" PAI Zettel Themes"));
@@ -16138,7 +16274,7 @@ async function migrateToPostgres(opts = {}) {
16138
16274
  const dump = pgDump(container, pgConfig, dumpPath);
16139
16275
  if (!dump.ok) return refused(dump.reason, dryRun);
16140
16276
  }
16141
- const { PostgresBackend } = await import("./postgres-B2BEBT-J.mjs");
16277
+ const { PostgresBackend } = await import("./postgres-TedJP3yF.mjs");
16142
16278
  await PostgresBackend.ensureDatabase(pgConfig);
16143
16279
  const sqlite = new BetterSqlite3(sqliteFederationPath, { readonly: true });
16144
16280
  const registrySqlite = sqliteRegistryPath === sqliteFederationPath ? sqlite : new BetterSqlite3(sqliteRegistryPath, { readonly: true });
@@ -16709,7 +16845,7 @@ async function getSessionTags(registryBackend, sessionId) {
16709
16845
  * Session CRUD commands: list, info, rename, slug, tag, route, active, auto-route.
16710
16846
  */
16711
16847
  async function cmdList(projectSlug, opts) {
16712
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
16848
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16713
16849
  const registryBackend = await getRegistryBackend();
16714
16850
  const limit = parseInt(opts.limit ?? "20", 10);
16715
16851
  let project;
@@ -16774,7 +16910,7 @@ async function cmdList(projectSlug, opts) {
16774
16910
  console.log(dim$1(` ${rows.length} session(s) shown (limit: ${limit})`));
16775
16911
  }
16776
16912
  async function cmdInfo(projectSlug, sessionNumber) {
16777
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
16913
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16778
16914
  const registryBackend = await getRegistryBackend();
16779
16915
  const project = await getProject$1(registryBackend, projectSlug);
16780
16916
  if (!project) {
@@ -16798,7 +16934,7 @@ async function cmdInfo(projectSlug, sessionNumber) {
16798
16934
  console.log();
16799
16935
  }
16800
16936
  async function cmdRename(projectSlug, numberOrLatest, newSlug) {
16801
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
16937
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16802
16938
  await cmdRenameWith(await getRegistryBackend(), projectSlug, numberOrLatest, newSlug);
16803
16939
  }
16804
16940
  async function cmdRenameWith(registryBackend, projectSlug, numberOrLatest, newSlug) {
@@ -16861,7 +16997,7 @@ async function cmdRenameWith(registryBackend, projectSlug, numberOrLatest, newSl
16861
16997
  console.log();
16862
16998
  }
16863
16999
  async function cmdSlug(projectSlug, numberOrLatest, opts) {
16864
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
17000
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16865
17001
  const registryBackend = await getRegistryBackend();
16866
17002
  const project = await getProject$1(registryBackend, projectSlug);
16867
17003
  if (!project) {
@@ -16891,7 +17027,7 @@ async function cmdSlug(projectSlug, numberOrLatest, opts) {
16891
17027
  }
16892
17028
  }
16893
17029
  async function cmdTag(projectSlug, sessionNumber, rawTags) {
16894
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
17030
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16895
17031
  const registryBackend = await getRegistryBackend();
16896
17032
  const project = await getProject$1(registryBackend, projectSlug);
16897
17033
  if (!project) {
@@ -16931,7 +17067,7 @@ async function cmdTag(projectSlug, sessionNumber, rawTags) {
16931
17067
  console.log();
16932
17068
  }
16933
17069
  async function cmdRoute(projectSlug, sessionNumber, targetProjectSlug, opts) {
16934
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
17070
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16935
17071
  const registryBackend = await getRegistryBackend();
16936
17072
  const project = await getProject$1(registryBackend, projectSlug);
16937
17073
  if (!project) {
@@ -16973,7 +17109,7 @@ async function cmdRoute(projectSlug, sessionNumber, targetProjectSlug, opts) {
16973
17109
  console.log();
16974
17110
  }
16975
17111
  async function cmdActive(opts) {
16976
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
17112
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
16977
17113
  const registryBackend = await getRegistryBackend();
16978
17114
  const minutes = parseInt(opts.minutes ?? "60", 10);
16979
17115
  const cutoff = Date.now() - minutes * 60 * 1e3;
@@ -17060,9 +17196,9 @@ async function cmdActive(opts) {
17060
17196
  ], rows));
17061
17197
  }
17062
17198
  async function cmdAutoRoute(opts) {
17063
- const { autoRoute, formatAutoRouteJson } = await import("./auto-route-D6fW1Q8z.mjs");
17064
- const { getRegistryBackend, createStorageBackend } = await import("./factory-CnKsU6zX.mjs");
17065
- const { loadConfig } = await import("./config-CnsDMETf.mjs");
17199
+ const { autoRoute, formatAutoRouteJson } = await import("./auto-route-CboBqsN3.mjs");
17200
+ const { getRegistryBackend, createStorageBackend } = await import("./factory-XrH66erA.mjs");
17201
+ const { loadConfig } = await import("./config-UWtzLpXi.mjs");
17066
17202
  const config = loadConfig();
17067
17203
  const registryBackend = await getRegistryBackend();
17068
17204
  const federation = await createStorageBackend(config);
@@ -17298,7 +17434,7 @@ async function cmdPause(opts) {
17298
17434
  process.exitCode = 1;
17299
17435
  return;
17300
17436
  }
17301
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
17437
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
17302
17438
  const registryBackend = await getRegistryBackend();
17303
17439
  const cwd = process.cwd();
17304
17440
  const project = await resolveProjectByCwd(registryBackend, cwd);
@@ -17693,7 +17829,7 @@ function buildStopBody(project, sessionId) {
17693
17829
  }
17694
17830
  }
17695
17831
  async function cmdHandover(projectSlug, numberOrLatest, sessionId) {
17696
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
17832
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
17697
17833
  const registryBackend = await getRegistryBackend();
17698
17834
  let project;
17699
17835
  if (projectSlug) {
@@ -17989,7 +18125,7 @@ function touchSentinel(rootPath) {
17989
18125
  async function cmdAutosave(opts) {
17990
18126
  const minGap = parseInt(opts.minGap ?? String(DEFAULT_MIN_GAP), 10);
17991
18127
  const cwd = process.cwd();
17992
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
18128
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
17993
18129
  const registryBackend = await getRegistryBackend();
17994
18130
  const project = await resolveProjectByCwd(registryBackend, cwd);
17995
18131
  if (!project) return;
@@ -19429,6 +19565,18 @@ function registerWorkerCommands(workerCmd) {
19429
19565
  fail(e);
19430
19566
  }
19431
19567
  });
19568
+ workerCmd.command("wait-on <pid>").description("Wait at most --max seconds (default 110, cap 115) for a detached job's pid; exit 0 gone, 3 still running, 2 never existed.\nRecipe: nohup sh -c 'CMD; echo $? > /tmp/job.rc' > /tmp/job.log 2>&1 & echo $! > /tmp/job.pid ; then repeat `pai worker wait-on $(cat /tmp/job.pid) --log /tmp/job.log` until exit 0.").option("--log <file>", "Log file whose last lines are printed on return; <file>.rc holds the exit code").option("--max <secs>", "Maximum seconds to block (default 110, hard cap 115)", parseIntArg).option("--tail <n>", "Log lines printed on return (default 20)", parseIntArg).action(async (pid, opts) => {
19569
+ try {
19570
+ process.exitCode = await waitOn({
19571
+ pid: Number(pid),
19572
+ log: opts.log,
19573
+ maxSecs: opts.max,
19574
+ tail: opts.tail
19575
+ });
19576
+ } catch (e) {
19577
+ fail(e);
19578
+ }
19579
+ });
19432
19580
  workerCmd.command("wait <ids...>").description("Poll workers until they finish; prints each result as one JSON line, exit 1 on failure or timeout\nNever busy-wait for a worker: no sleep loops, no sleep-then-`pai worker ps` polling, no manual retry loops. Two sanctioned waits: run workers as background Bash tasks (the harness notifies on completion), or call `pai worker wait`, which blocks until they finish and prints each result. If you catch yourself sleeping to re-check a worker, stop — you already get notified. Supervision events arrive automatically — no polling, no sleeps: the daemon watches your workers and tells you when one finishes, fails or stalls (docs/worker.md, Supervision).").option("--timeout <secs>", "Give up after this many seconds (default 900)", parseIntArg).action(async (ids, opts) => {
19433
19581
  try {
19434
19582
  const { results, timedOut } = await waitWorkers(currentLogDir(), ids, { timeoutMs: (opts.timeout ?? 900) * 1e3 });
@@ -20353,8 +20501,8 @@ async function analyzeProject(registryBackend, project) {
20353
20501
  async function countVectorDbPaths(oldPaths) {
20354
20502
  if (oldPaths.length === 0) return 0;
20355
20503
  try {
20356
- const { loadConfig } = await import("./config-CnsDMETf.mjs");
20357
- const { createStorageBackend } = await import("./factory-CnKsU6zX.mjs");
20504
+ const { loadConfig } = await import("./config-UWtzLpXi.mjs");
20505
+ const { createStorageBackend } = await import("./factory-XrH66erA.mjs");
20358
20506
  const config = loadConfig();
20359
20507
  if (config.storageBackend !== "postgres") return 0;
20360
20508
  const backend = await createStorageBackend(config);
@@ -20371,8 +20519,8 @@ async function countVectorDbPaths(oldPaths) {
20371
20519
  async function updateVectorDbPaths(moves) {
20372
20520
  if (moves.length === 0) return 0;
20373
20521
  try {
20374
- const { loadConfig } = await import("./config-CnsDMETf.mjs");
20375
- const { createStorageBackend } = await import("./factory-CnKsU6zX.mjs");
20522
+ const { loadConfig } = await import("./config-UWtzLpXi.mjs");
20523
+ const { createStorageBackend } = await import("./factory-XrH66erA.mjs");
20376
20524
  const config = loadConfig();
20377
20525
  if (config.storageBackend !== "postgres") return 0;
20378
20526
  const backend = await createStorageBackend(config);
@@ -20459,7 +20607,7 @@ async function displayDryRun(plans) {
20459
20607
  console.log();
20460
20608
  }
20461
20609
  async function executeCleanup(plans, skipReindex) {
20462
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
20610
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
20463
20611
  const registryBackend = await getRegistryBackend();
20464
20612
  let deleted = 0;
20465
20613
  let renamed = 0;
@@ -20656,7 +20804,7 @@ async function executeCleanup(plans, skipReindex) {
20656
20804
  //#region src/cli/commands/session-cleanup/index.ts
20657
20805
  function registerSessionCleanupCommand(sessionCmd) {
20658
20806
  sessionCmd.command("cleanup [project-slug]").description("Clean up session notes: delete empties, auto-name unnamed, move into YYYY/MM/ hierarchy, renumber").option("--execute", "Actually perform the cleanup (default is dry-run)").option("--no-renumber", "Skip renumbering sessions after deletions").option("--no-reindex", "Skip triggering memory re-index after moves").action(async (projectSlug, opts) => {
20659
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
20807
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
20660
20808
  const registryBackend = await getRegistryBackend();
20661
20809
  const dryRun = !opts.execute;
20662
20810
  const skipReindex = opts.reindex === false;
@@ -20726,7 +20874,7 @@ function finalizeNote(notePath) {
20726
20874
  }
20727
20875
  async function cmdEnd(opts) {
20728
20876
  await cmdPause(opts);
20729
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
20877
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
20730
20878
  const registryBackend = await getRegistryBackend();
20731
20879
  const cwd = process.cwd();
20732
20880
  const project = await registryBackend.findProjectByCwdPrefix(cwd);
@@ -21174,7 +21322,7 @@ async function cmdFind(query, opts) {
21174
21322
  */
21175
21323
  async function getProjects(includeArchived) {
21176
21324
  try {
21177
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
21325
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
21178
21326
  const rows = await (await getRegistryBackend()).listProjectsWithSessionStats();
21179
21327
  return includeArchived ? rows : rows.filter((p) => p.status === "active");
21180
21328
  } catch {
@@ -21648,7 +21796,7 @@ async function cmdPick(opts = {}) {
21648
21796
  const onRemove = async (rec) => {
21649
21797
  if (!rec.slug) return false;
21650
21798
  try {
21651
- const { getRegistryBackend } = await import("./factory-CnKsU6zX.mjs");
21799
+ const { getRegistryBackend } = await import("./factory-XrH66erA.mjs");
21652
21800
  const registryBackend = await getRegistryBackend();
21653
21801
  const project = await registryBackend.getProjectBySlug(rec.slug);
21654
21802
  if (!project || project.status !== "active") return false;
@@ -21933,4 +22081,4 @@ claude() {
21933
22081
 
21934
22082
  //#endregion
21935
22083
  export { drainStdio as n, buildProgram as t };
21936
- //# sourceMappingURL=program-CfG1T_ko.mjs.map
22084
+ //# sourceMappingURL=program-BXns_5kO.mjs.map