@tekmidian/pai 0.41.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/aibroker-client-BP74gGwD.mjs +215 -0
  2. package/dist/aibroker-client-BP74gGwD.mjs.map +1 -0
  3. package/dist/aibroker-client-C6m71p6O.mjs +3 -0
  4. package/dist/{auto-route-BwzmlW3W.mjs → auto-route-_5zzJz5q.mjs} +2 -2
  5. package/dist/{auto-route-BwzmlW3W.mjs.map → auto-route-_5zzJz5q.mjs.map} +1 -1
  6. package/dist/{chain-zMjCDW-R.mjs → chain-DGXNoTwc.mjs} +70 -329
  7. package/dist/chain-DGXNoTwc.mjs.map +1 -0
  8. package/dist/cli/index.mjs +12 -10
  9. package/dist/cli/index.mjs.map +1 -1
  10. package/dist/cli/program.mjs +12 -10
  11. package/dist/{clusters-DRHhfli9.mjs → clusters-j0ZuNYp9.mjs} +1 -1
  12. package/dist/{clusters-DRHhfli9.mjs.map → clusters-j0ZuNYp9.mjs.map} +1 -1
  13. package/dist/{config-D1G9IFpn.mjs → config-B64vFg14.mjs} +3 -50
  14. package/dist/config-B64vFg14.mjs.map +1 -0
  15. package/dist/{config-DD52BPB-.mjs → config-C_ErGddD.mjs} +1 -1
  16. package/dist/{config-Dl8lT4Lu.mjs → config-DgzR5sfb.mjs} +2 -2
  17. package/dist/{config-Dl8lT4Lu.mjs.map → config-DgzR5sfb.mjs.map} +1 -1
  18. package/dist/{context-handover-cache-C6_rs7JT.mjs → context-handover-cache-dUnSZwaA.mjs} +4 -4
  19. package/dist/{context-handover-cache-C6_rs7JT.mjs.map → context-handover-cache-dUnSZwaA.mjs.map} +1 -1
  20. package/dist/daemon/index.mjs +13 -12
  21. package/dist/daemon/index.mjs.map +1 -1
  22. package/dist/daemon-CKBkhOsZ.mjs +23 -0
  23. package/dist/{daemon-CpdVUnl_.mjs → daemon-DsvP8KMy.mjs} +357 -27
  24. package/dist/daemon-DsvP8KMy.mjs.map +1 -0
  25. package/dist/daemon-mcp/index.mjs +10 -6
  26. package/dist/daemon-mcp/index.mjs.map +1 -1
  27. package/dist/detector-C-7KRi42.mjs +5 -0
  28. package/dist/{detector-smpCm7ku.mjs → detector-C73Nxm94.mjs} +1 -1
  29. package/dist/{detector-smpCm7ku.mjs.map → detector-C73Nxm94.mjs.map} +1 -1
  30. package/dist/{factory-Bc5EyN54.mjs → factory-DEb9NmHJ.mjs} +7 -7
  31. package/dist/{factory-Bc5EyN54.mjs.map → factory-DEb9NmHJ.mjs.map} +1 -1
  32. package/dist/factory-Dbo8yNPi.mjs +3 -0
  33. package/dist/{fallback-CgQ_x4I7.mjs → fallback-5UJO-RyX.mjs} +5 -4
  34. package/dist/{fallback-CgQ_x4I7.mjs.map → fallback-5UJO-RyX.mjs.map} +1 -1
  35. package/dist/hooks/worker-status-line.mjs +9 -4
  36. package/dist/hooks/worker-status-line.mjs.map +3 -3
  37. package/dist/hooks/worker-supervision.mjs +593 -0
  38. package/dist/hooks/worker-supervision.mjs.map +7 -0
  39. package/dist/{indexer-backend-rohVVKrA.mjs → indexer-backend-BPTzKFZU.mjs} +1 -1
  40. package/dist/{indexer-backend-rohVVKrA.mjs.map → indexer-backend-BPTzKFZU.mjs.map} +1 -1
  41. package/dist/{ipc-client-C7AVpsyv.mjs → ipc-client-BmypMNYk.mjs} +2 -2
  42. package/dist/{ipc-client-C7AVpsyv.mjs.map → ipc-client-BmypMNYk.mjs.map} +1 -1
  43. package/dist/{kg-entity-DbOMPdF9.mjs → kg-entity-r8duqhi9.mjs} +1 -1
  44. package/dist/{kg-entity-DbOMPdF9.mjs.map → kg-entity-r8duqhi9.mjs.map} +1 -1
  45. package/dist/{latent-ideas-iNp5s55R.mjs → latent-ideas-CtSca4qG.mjs} +2 -2
  46. package/dist/{latent-ideas-iNp5s55R.mjs.map → latent-ideas-CtSca4qG.mjs.map} +1 -1
  47. package/dist/{link-boost-NNzADHX_.mjs → link-boost-Bucnz3n8.mjs} +1 -1
  48. package/dist/{link-boost-NNzADHX_.mjs.map → link-boost-Bucnz3n8.mjs.map} +1 -1
  49. package/dist/{main-resolver-CM1IHbuu.mjs → main-resolver-BgIrC-D9.mjs} +4 -214
  50. package/dist/main-resolver-BgIrC-D9.mjs.map +1 -0
  51. package/dist/main-resolver-DXGuygFG.mjs +7 -0
  52. package/dist/{neighborhood-AGL7oXQ2.mjs → neighborhood-CM7Jgb51.mjs} +1 -1
  53. package/dist/{neighborhood-AGL7oXQ2.mjs.map → neighborhood-CM7Jgb51.mjs.map} +1 -1
  54. package/dist/{note-context-BHwYpSFf.mjs → note-context-DCwE2A-M.mjs} +1 -1
  55. package/dist/{note-context-BHwYpSFf.mjs.map → note-context-DCwE2A-M.mjs.map} +1 -1
  56. package/dist/{planner-DsmMRIZR.mjs → planner-BLDJt3ZS.mjs} +6 -5
  57. package/dist/{planner-DsmMRIZR.mjs.map → planner-BLDJt3ZS.mjs.map} +1 -1
  58. package/dist/{postgres-Dwxe290H.mjs → postgres-CtOzfoQU.mjs} +1 -1
  59. package/dist/{postgres-Dwxe290H.mjs.map → postgres-CtOzfoQU.mjs.map} +1 -1
  60. package/dist/{program-Bed-Pd-8.mjs → program-CruRnLtc.mjs} +36 -33
  61. package/dist/{program-Bed-Pd-8.mjs.map → program-CruRnLtc.mjs.map} +1 -1
  62. package/dist/query-feedback-DGoVRaWD.mjs +3 -0
  63. package/dist/{query-feedback-DZfjI34w.mjs → query-feedback-Dqz-HC__.mjs} +1 -1
  64. package/dist/{query-feedback-DZfjI34w.mjs.map → query-feedback-Dqz-HC__.mjs.map} +1 -1
  65. package/dist/router-BTIGZR2_.mjs +3 -0
  66. package/dist/{router-DHracTUC.mjs → router-DD6D4j31.mjs} +1 -1
  67. package/dist/{router-DHracTUC.mjs.map → router-DD6D4j31.mjs.map} +1 -1
  68. package/dist/runtime-paths-rni52zHX.mjs +50 -0
  69. package/dist/runtime-paths-rni52zHX.mjs.map +1 -0
  70. package/dist/scope-NIwCGxRI.mjs +351 -0
  71. package/dist/scope-NIwCGxRI.mjs.map +1 -0
  72. package/dist/{server-BOuAOj9b.mjs → server-Cp7tNzNC.mjs} +19 -2
  73. package/dist/server-Cp7tNzNC.mjs.map +1 -0
  74. package/dist/skills/Worker/SKILL.md +3 -0
  75. package/dist/{sources-ju6AA7lL.mjs → sources-CS43CpuS.mjs} +1 -1
  76. package/dist/{sources-ju6AA7lL.mjs.map → sources-CS43CpuS.mjs.map} +1 -1
  77. package/dist/{sqlite-kFZeWCJ2.mjs → sqlite-Cq3gJcq9.mjs} +1 -1
  78. package/dist/{sqlite-kFZeWCJ2.mjs.map → sqlite-Cq3gJcq9.mjs.map} +1 -1
  79. package/dist/{state-ahFAbD8b.mjs → state-BTa10SOM.mjs} +1 -1
  80. package/dist/{state-ahFAbD8b.mjs.map → state-BTa10SOM.mjs.map} +1 -1
  81. package/dist/{state-DH_mp5Xe.mjs → state-RXepvbnO.mjs} +1 -1
  82. package/dist/{themes-DqhNUUQk.mjs → themes-B7h9YDiy.mjs} +1 -1
  83. package/dist/{themes-DqhNUUQk.mjs.map → themes-B7h9YDiy.mjs.map} +1 -1
  84. package/dist/{tools-COna9vZR.mjs → tools-BW3NLMPk.mjs} +1 -1
  85. package/dist/{tools-CMlHa9lZ.mjs → tools-LlzcV_eK.mjs} +14 -14
  86. package/dist/{tools-CMlHa9lZ.mjs.map → tools-LlzcV_eK.mjs.map} +1 -1
  87. package/dist/{trace-DTP6k4B_.mjs → trace-u4hT-pLD.mjs} +1 -1
  88. package/dist/{trace-DTP6k4B_.mjs.map → trace-u4hT-pLD.mjs.map} +1 -1
  89. package/dist/{vault-indexer-YMH22mLU.mjs → vault-indexer-mata9S7b.mjs} +1 -1
  90. package/dist/{vault-indexer-YMH22mLU.mjs.map → vault-indexer-mata9S7b.mjs.map} +1 -1
  91. package/dist/{work-queue-worker-B3nl8yyn.mjs → work-queue-worker-7Vkli4Yh.mjs} +4 -4
  92. package/dist/{work-queue-worker-B3nl8yyn.mjs.map → work-queue-worker-7Vkli4Yh.mjs.map} +1 -1
  93. package/dist/work-queue-worker-D1p2V-ae.mjs +14 -0
  94. package/dist/{zettelkasten-DDvKRm2V.mjs → zettelkasten-F0D_XfQ4.mjs} +3 -3
  95. package/dist/{zettelkasten-DDvKRm2V.mjs.map → zettelkasten-F0D_XfQ4.mjs.map} +1 -1
  96. package/docs/commands/worker.md +1 -1
  97. package/docs/worker.md +40 -0
  98. package/package.json +1 -1
  99. package/plugins/productivity/hooks/hooks.json +5 -0
  100. package/src/hooks/ts/user-prompt/worker-supervision.ts +123 -0
  101. package/dist/chain-zMjCDW-R.mjs.map +0 -1
  102. package/dist/config-D1G9IFpn.mjs.map +0 -1
  103. package/dist/daemon-BSL9sXxm.mjs +0 -22
  104. package/dist/daemon-CpdVUnl_.mjs.map +0 -1
  105. package/dist/detector-BLVOCiJ_.mjs +0 -5
  106. package/dist/factory-C7ua_3ik.mjs +0 -3
  107. package/dist/main-resolver-CM1IHbuu.mjs.map +0 -1
  108. package/dist/main-resolver-E5WlilhM.mjs +0 -6
  109. package/dist/query-feedback-CGcEiGtY.mjs +0 -3
  110. package/dist/router-CAtyVQud.mjs +0 -3
  111. package/dist/server-BOuAOj9b.mjs.map +0 -1
  112. package/dist/work-queue-worker-BM1GcAAq.mjs +0 -14
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/daemon/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * PAI Daemon — Entry point\n *\n * Commands:\n * serve — Start the PAI daemon (foreground, managed by launchd in production)\n * status — Query daemon status via IPC\n * index — Trigger an immediate index run via IPC\n */\n\nimport { Command } from \"commander\";\nimport { loadConfig, ensureConfigDir } from \"./config.js\";\nimport { serve } from \"./daemon.js\";\nimport { PaiClient } from \"./ipc-client.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"pai-daemon\")\n .description(\"PAI Daemon — background service for PAI Knowledge OS\")\n .version(\"0.1.0\");\n\n// ---------------------------------------------------------------------------\n// serve\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"serve\")\n .description(\"Start the PAI daemon in the foreground\")\n .action(async () => {\n ensureConfigDir();\n const config = loadConfig();\n await serve(config);\n });\n\n// ---------------------------------------------------------------------------\n// status\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"status\")\n .description(\"Query the running daemon status\")\n .action(async () => {\n const config = loadConfig();\n const client = new PaiClient(config.socketPath);\n\n try {\n const status = await client.status();\n console.log(JSON.stringify(status, null, 2));\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error: ${msg}`);\n process.exit(1);\n }\n });\n\n// ---------------------------------------------------------------------------\n// index\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"index\")\n .description(\"Trigger an immediate index run in the running daemon\")\n .action(async () => {\n const config = loadConfig();\n const client = new PaiClient(config.socketPath);\n\n try {\n await client.triggerIndex();\n console.log(\"Index triggered. Check daemon logs for progress.\");\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error: ${msg}`);\n process.exit(1);\n }\n });\n\n// ---------------------------------------------------------------------------\n// Parse\n// ---------------------------------------------------------------------------\n\nprogram.parse(process.argv);\n\nif (process.argv.length <= 2) {\n program.help();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,MAAM,UAAU,IAAI,SAAS;AAE7B,QACG,KAAK,aAAa,CAClB,YAAY,uDAAuD,CACnE,QAAQ,QAAQ;AAMnB,QACG,QAAQ,QAAQ,CAChB,YAAY,yCAAyC,CACrD,OAAO,YAAY;AAClB,kBAAiB;AAEjB,OAAM,MADS,YAAY,CACR;EACnB;AAMJ,QACG,QAAQ,SAAS,CACjB,YAAY,kCAAkC,CAC9C,OAAO,YAAY;CAElB,MAAM,SAAS,IAAI,UADJ,YAAY,CACS,WAAW;AAE/C,KAAI;EACF,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;UACrC,GAAG;EACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,UAAQ,MAAM,UAAU,MAAM;AAC9B,UAAQ,KAAK,EAAE;;EAEjB;AAMJ,QACG,QAAQ,QAAQ,CAChB,YAAY,uDAAuD,CACnE,OAAO,YAAY;CAElB,MAAM,SAAS,IAAI,UADJ,YAAY,CACS,WAAW;AAE/C,KAAI;AACF,QAAM,OAAO,cAAc;AAC3B,UAAQ,IAAI,mDAAmD;UACxD,GAAG;EACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,UAAQ,MAAM,UAAU,MAAM;AAC9B,UAAQ,KAAK,EAAE;;EAEjB;AAMJ,QAAQ,MAAM,QAAQ,KAAK;AAE3B,IAAI,QAAQ,KAAK,UAAU,EACzB,SAAQ,MAAM"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/daemon/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * PAI Daemon — Entry point\n *\n * Commands:\n * serve — Start the PAI daemon (foreground, managed by launchd in production)\n * status — Query daemon status via IPC\n * index — Trigger an immediate index run via IPC\n */\n\nimport { Command } from \"commander\";\nimport { loadConfig, ensureConfigDir } from \"./config.js\";\nimport { serve } from \"./daemon.js\";\nimport { PaiClient } from \"./ipc-client.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"pai-daemon\")\n .description(\"PAI Daemon — background service for PAI Knowledge OS\")\n .version(\"0.1.0\");\n\n// ---------------------------------------------------------------------------\n// serve\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"serve\")\n .description(\"Start the PAI daemon in the foreground\")\n .action(async () => {\n ensureConfigDir();\n const config = loadConfig();\n await serve(config);\n });\n\n// ---------------------------------------------------------------------------\n// status\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"status\")\n .description(\"Query the running daemon status\")\n .action(async () => {\n const config = loadConfig();\n const client = new PaiClient(config.socketPath);\n\n try {\n const status = await client.status();\n console.log(JSON.stringify(status, null, 2));\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error: ${msg}`);\n process.exit(1);\n }\n });\n\n// ---------------------------------------------------------------------------\n// index\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"index\")\n .description(\"Trigger an immediate index run in the running daemon\")\n .action(async () => {\n const config = loadConfig();\n const client = new PaiClient(config.socketPath);\n\n try {\n await client.triggerIndex();\n console.log(\"Index triggered. Check daemon logs for progress.\");\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error: ${msg}`);\n process.exit(1);\n }\n });\n\n// ---------------------------------------------------------------------------\n// Parse\n// ---------------------------------------------------------------------------\n\nprogram.parse(process.argv);\n\nif (process.argv.length <= 2) {\n program.help();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,MAAM,UAAU,IAAI,SAAS;AAE7B,QACG,KAAK,aAAa,CAClB,YAAY,uDAAuD,CACnE,QAAQ,QAAQ;AAMnB,QACG,QAAQ,QAAQ,CAChB,YAAY,yCAAyC,CACrD,OAAO,YAAY;AAClB,kBAAiB;AAEjB,OAAM,MADS,YAAY,CACR;EACnB;AAMJ,QACG,QAAQ,SAAS,CACjB,YAAY,kCAAkC,CAC9C,OAAO,YAAY;CAElB,MAAM,SAAS,IAAI,UADJ,YAAY,CACS,WAAW;AAE/C,KAAI;EACF,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;UACrC,GAAG;EACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,UAAQ,MAAM,UAAU,MAAM;AAC9B,UAAQ,KAAK,EAAE;;EAEjB;AAMJ,QACG,QAAQ,QAAQ,CAChB,YAAY,uDAAuD,CACnE,OAAO,YAAY;CAElB,MAAM,SAAS,IAAI,UADJ,YAAY,CACS,WAAW;AAE/C,KAAI;AACF,QAAM,OAAO,cAAc;AAC3B,UAAQ,IAAI,mDAAmD;UACxD,GAAG;EACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,UAAQ,MAAM,UAAU,MAAM;AAC9B,UAAQ,KAAK,EAAE;;EAEjB;AAMJ,QAAQ,MAAM,QAAQ,KAAK;AAE3B,IAAI,QAAQ,KAAK,UAAU,EACzB,SAAQ,MAAM"}
@@ -0,0 +1,23 @@
1
+ import "./db-Ca5qfsMC.mjs";
2
+ import "./utils-9Err2RBW.mjs";
3
+ import "./migrate-Cjzeefn9.mjs";
4
+ import "./db-a1ixZQjr.mjs";
5
+ import "./helpers-IjZkXBhj.mjs";
6
+ import "./sync-BWbe8JTg.mjs";
7
+ import "./embeddings-DOLZnT1X.mjs";
8
+ import "./search-Rpk1cSBC.mjs";
9
+ import "./context-handover-cache-dUnSZwaA.mjs";
10
+ import "./indexer-D7MvSQPY.mjs";
11
+ import "./config-B64vFg14.mjs";
12
+ import "./factory-DEb9NmHJ.mjs";
13
+ import "./config-DgzR5sfb.mjs";
14
+ import "./server-Cp7tNzNC.mjs";
15
+ import "./scope-NIwCGxRI.mjs";
16
+ import { t as serve } from "./daemon-DsvP8KMy.mjs";
17
+ import "./state-BTa10SOM.mjs";
18
+ import "./router-DD6D4j31.mjs";
19
+ import "./tools-LlzcV_eK.mjs";
20
+ import "./detector-C73Nxm94.mjs";
21
+ import "./work-queue-worker-7Vkli4Yh.mjs";
22
+
23
+ export { serve };
@@ -3,15 +3,19 @@ import { t as openFederation } from "./db-a1ixZQjr.mjs";
3
3
  import { d as sha256 } from "./helpers-IjZkXBhj.mjs";
4
4
  import { n as indexAll } from "./sync-BWbe8JTg.mjs";
5
5
  import { t as configureEmbeddingModel } from "./embeddings-DOLZnT1X.mjs";
6
- import { l as DEFAULT_NOTIFICATION_CONFIG, n as CONFIG_FILE, t as CONFIG_DIR } from "./config-D1G9IFpn.mjs";
7
- import { n as getBackendOutage, t as createStorageBackend } from "./factory-Bc5EyN54.mjs";
8
- import { C as setStorageBackend, D as storageBackend, E as startTime, O as vaultIndexInProgress, S as setStartTime, T as shutdownRequested, _ as setLastIndexTime, a as indexSchedulerTimer, b as setRegistryDb, c as lastVaultIndexTime, d as setDaemonConfig, f as setEmbedInProgress, g as setLastEmbedTime, h as setIndexSchedulerTimer, i as indexInProgress, l as notificationConfig, m as setIndexInProgress, n as embedInProgress, o as lastEmbedTime, p as setEmbedSchedulerTimer, r as embedSchedulerTimer, s as lastIndexTime, t as daemonConfig, u as registryDb, v as setLastVaultIndexTime, w as setVaultIndexInProgress, x as setShutdownRequested, y as setNotificationConfig } from "./state-ahFAbD8b.mjs";
9
- import { t as routeNotification } from "./router-DHracTUC.mjs";
10
- import { C as toolProjectInfo, D as toolMemoryGet, O as toolMemorySearch, S as toolProjectHealth, T as toolProjectTodo, a as toolMemoryWakeup, b as toolSessionRoute, i as toolMemoryTaxonomy, n as toolMemoryFeedback, t as toolMemoryKgSearch, v as toolRegistrySearch, w as toolProjectList, x as toolProjectDetect, y as toolSessionList } from "./tools-CMlHa9lZ.mjs";
11
- import { t as detectTopicShift } from "./detector-smpCm7ku.mjs";
12
- import { a as enqueue, i as stopWorker, n as notifyNewWork, o as getStats, r as startWorker, s as loadQueue } from "./work-queue-worker-B3nl8yyn.mjs";
13
- import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
6
+ import { l as DEFAULT_NOTIFICATION_CONFIG, n as CONFIG_FILE, t as CONFIG_DIR } from "./config-B64vFg14.mjs";
7
+ import { n as getBackendOutage, t as createStorageBackend } from "./factory-DEb9NmHJ.mjs";
8
+ import { m as readWorkersSection } from "./config-DgzR5sfb.mjs";
9
+ import { _ as workersLogDir } from "./server-Cp7tNzNC.mjs";
10
+ import { d as alive, g as loadStatuses, n as itermForClaudeSession, v as nowStamp } from "./scope-NIwCGxRI.mjs";
11
+ import { C as setStorageBackend, D as storageBackend, E as startTime, O as vaultIndexInProgress, S as setStartTime, T as shutdownRequested, _ as setLastIndexTime, a as indexSchedulerTimer, b as setRegistryDb, c as lastVaultIndexTime, d as setDaemonConfig, f as setEmbedInProgress, g as setLastEmbedTime, h as setIndexSchedulerTimer, i as indexInProgress, l as notificationConfig, m as setIndexInProgress, n as embedInProgress, o as lastEmbedTime, p as setEmbedSchedulerTimer, r as embedSchedulerTimer, s as lastIndexTime, t as daemonConfig, u as registryDb, v as setLastVaultIndexTime, w as setVaultIndexInProgress, x as setShutdownRequested, y as setNotificationConfig } from "./state-BTa10SOM.mjs";
12
+ import { t as routeNotification } from "./router-DD6D4j31.mjs";
13
+ import { C as toolProjectInfo, D as toolMemoryGet, O as toolMemorySearch, S as toolProjectHealth, T as toolProjectTodo, a as toolMemoryWakeup, b as toolSessionRoute, i as toolMemoryTaxonomy, n as toolMemoryFeedback, t as toolMemoryKgSearch, v as toolRegistrySearch, w as toolProjectList, x as toolProjectDetect, y as toolSessionList } from "./tools-LlzcV_eK.mjs";
14
+ import { t as detectTopicShift } from "./detector-C73Nxm94.mjs";
15
+ import { a as enqueue, i as stopWorker, n as notifyNewWork, o as getStats, r as startWorker, s as loadQueue } from "./work-queue-worker-7Vkli4Yh.mjs";
16
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
14
17
  import { setPriority } from "node:os";
18
+ import { dirname, join } from "node:path";
15
19
  import { connect, createServer } from "node:net";
16
20
 
17
21
  //#region src/notifications/config.ts
@@ -83,6 +87,295 @@ function patchNotificationConfig(patch) {
83
87
  return current;
84
88
  }
85
89
 
90
+ //#endregion
91
+ //#region src/workers/supervision.ts
92
+ /**
93
+ * supervision.ts — daemon-side worker supervision, event push not polling.
94
+ *
95
+ * An orchestrating session must keep an eye on its workers without sleeping
96
+ * (the Worker skill forbids busy-waiting), the same way the AIBroker daemon
97
+ * keeps an eye on sessions. The PAI daemon already runs all day; this module
98
+ * gives it a tick that watches every worker's status file and pushes one-line
99
+ * events to the owning session when something happens:
100
+ *
101
+ * finished — the run ended clean (state done, rc 0)
102
+ * failed — the run ended badly (state failed/killed/lost, or rc != 0,
103
+ * or the runner pid vanished while state was still running)
104
+ * stalled — state running, runner alive, but no new turn for longer than
105
+ * the stall threshold (PAI_WORKER_STALL_MINUTES, default 10)
106
+ *
107
+ * Delivery, in order of preference, never both counted as required:
108
+ * 1. AIBroker `send_to_session` into the orchestrator's terminal — the
109
+ * one-line Agentish-style notification, arriving as a user turn without
110
+ * the orchestrator asking for it. Needs the iTerm identity of the owner,
111
+ * which the status line bridges into the session map (see scope.ts).
112
+ * 2. An append-only event file, <logDir>/supervision/<owner>.events, one
113
+ * JSON line per event. The UserPromptSubmit hook
114
+ * (src/hooks/ts/user-prompt/worker-supervision.ts) surfaces undelivered
115
+ * lines into the session that owns them, so the events reach the model
116
+ * on its next turn even with AIBroker absent.
117
+ *
118
+ * Exactly-once: every event carries a deterministic id and the set of
119
+ * delivered ids per worker is persisted (<logDir>/supervision/state.json), so
120
+ * a daemon restart replays nothing. A first run with no state adopts every
121
+ * already-terminal worker as delivered — supervision reports transitions it
122
+ * observes, not history. Chain stages are separate workers with their own
123
+ * status files and are supervised individually.
124
+ *
125
+ * No model is ever called from here — this is daemon code, and it must stay
126
+ * that way: supervision that bills tokens to watch tokens is a bug.
127
+ */
128
+ /**
129
+ * The owning session of a worker, or null when nobody claims it (and so
130
+ * nothing to notify): the spawner's claude session id first — that is what
131
+ * the hook knows a session by — else the AIBroker iTerm uuid.
132
+ */
133
+ function ownershipKey(s) {
134
+ if (s.spawnerSession) return s.spawnerSession;
135
+ if (s.session?.id) return s.session.id;
136
+ return null;
137
+ }
138
+ const TERMINAL = [
139
+ "done",
140
+ "failed",
141
+ "killed",
142
+ "lost"
143
+ ];
144
+ function isTerminal(s) {
145
+ return TERMINAL.includes(s.state);
146
+ }
147
+ /** Age of a "YYYY-MM-DD HH:MM:SS" stamp in ms, NaN-safe (unparsable → 0). */
148
+ function ageMs(ts, now) {
149
+ const t = Date.parse(ts.replace(" ", "T"));
150
+ if (Number.isNaN(t)) return 0;
151
+ return Math.max(0, now.getTime() - t);
152
+ }
153
+ /**
154
+ * The stall threshold in minutes from PAI_WORKER_STALL_MINUTES (default 10).
155
+ * Anything unparsible or non-positive falls back to the default — a broken
156
+ * value must not turn supervision off or make it fire every tick.
157
+ */
158
+ const DEFAULT_STALL_MINUTES = 10;
159
+ function stallMinutesFromEnv(env = process.env) {
160
+ const raw = env.PAI_WORKER_STALL_MINUTES;
161
+ if (raw === void 0 || raw === "") return DEFAULT_STALL_MINUTES;
162
+ const n = Number(raw);
163
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_STALL_MINUTES;
164
+ }
165
+ /**
166
+ * Event id: `<worker>#<kind>` for the once-per-run terminal kinds, and
167
+ * `<worker>#stalled@<turns>` for stalls — the turn count re-arms the id, so a
168
+ * worker that resumes and stalls again gets a second event while a restart
169
+ * cannot replay the first.
170
+ */
171
+ function eventId(worker, kind, turns = 0) {
172
+ return kind === "stalled" ? `${worker}#stalled@${turns}` : `${worker}#${kind}`;
173
+ }
174
+ /** One event's one-liner — the exact line the orchestrator reads. */
175
+ function eventText(kind, s, rc, stalledMin) {
176
+ const tail = `- see pai worker replay ${s.id}`;
177
+ if (kind === "finished") return `worker ${s.id} ${s.label} finished rc=0 ${tail}`;
178
+ if (kind === "stalled") return `worker ${s.id} ${s.label} stalled ${stalledMin}m no turns ${tail}`;
179
+ const why = rc === null ? "runner gone" : `rc=${rc}`;
180
+ return `worker ${s.id} ${s.label} failed ${why} ${tail}`;
181
+ }
182
+ /**
183
+ * Detect conditions across a ledger snapshot. Pure: statuses in, events out;
184
+ * dedup against delivered ids is the caller's job (see filterUndelivered).
185
+ * Workers without an owning session are skipped — nobody to notify.
186
+ */
187
+ function detectSupervisionEvents(statuses, opts) {
188
+ const isAlive = opts.isAlive ?? alive;
189
+ const deadGraceMs = opts.deadGraceMs ?? 15e3;
190
+ const out = [];
191
+ for (const s of statuses) {
192
+ const session = ownershipKey(s);
193
+ if (!session) continue;
194
+ let kind = null;
195
+ let rc = null;
196
+ let stalledMin = null;
197
+ if (isTerminal(s)) if (s.state === "done" && (s.rc ?? 0) === 0) {
198
+ kind = "finished";
199
+ rc = 0;
200
+ } else {
201
+ kind = "failed";
202
+ rc = s.state === "lost" ? null : s.rc;
203
+ }
204
+ else if (!isAlive(s.pid) && ageMs(s.updated, opts.now) > deadGraceMs) {
205
+ kind = "failed";
206
+ rc = null;
207
+ } else if (ageMs(s.updated, opts.now) > opts.stallMs) {
208
+ kind = "stalled";
209
+ stalledMin = Math.floor(ageMs(s.updated, opts.now) / 6e4);
210
+ }
211
+ if (!kind) continue;
212
+ out.push({
213
+ id: eventId(s.id, kind, s.turns),
214
+ ts: nowStamp(opts.now),
215
+ kind,
216
+ worker: s.id,
217
+ label: s.label,
218
+ session,
219
+ rc,
220
+ stalledMin,
221
+ text: eventText(kind, s, rc, stalledMin)
222
+ });
223
+ }
224
+ return out;
225
+ }
226
+ /** Cap on remembered workers: terminal and delivered is history, not state. */
227
+ const MAX_REMEMBERED_WORKERS = 500;
228
+ function supervisionDirPath(logDir) {
229
+ return join(logDir, "supervision");
230
+ }
231
+ function supervisionStatePath(logDir) {
232
+ return join(supervisionDirPath(logDir), "state.json");
233
+ }
234
+ function supervisionEventsPath(logDir, session) {
235
+ return join(supervisionDirPath(logDir), `${session}.events`);
236
+ }
237
+ /** Receipts of events already pushed into a terminal, one event id per line. */
238
+ function supervisionPushedPath(logDir, session) {
239
+ return join(supervisionDirPath(logDir), `${session}.pushed`);
240
+ }
241
+ function loadSupervisionState(path) {
242
+ if (!existsSync(path)) return {
243
+ state: { delivered: {} },
244
+ fresh: true
245
+ };
246
+ try {
247
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
248
+ if (parsed && typeof parsed === "object" && typeof parsed.delivered === "object") return {
249
+ state: parsed,
250
+ fresh: false
251
+ };
252
+ } catch {}
253
+ return {
254
+ state: { delivered: {} },
255
+ fresh: true
256
+ };
257
+ }
258
+ function saveSupervisionState(path, state) {
259
+ const dir = dirname(path);
260
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
261
+ const tmp = `${path}.tmp`;
262
+ writeFileSync(tmp, JSON.stringify(state), "utf8");
263
+ renameSync(tmp, path);
264
+ }
265
+ /**
266
+ * Drop workers the ledger no longer lists and cap the rest (newest ids last —
267
+ * worker ids sort chronologically), so the persisted state stays bounded.
268
+ */
269
+ function pruneState(state, statuses) {
270
+ const present = new Set(statuses.map((s) => s.id));
271
+ const kept = Object.entries(state.delivered).filter(([id]) => present.has(id)).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).slice(-MAX_REMEMBERED_WORKERS);
272
+ return { delivered: Object.fromEntries(kept) };
273
+ }
274
+ /**
275
+ * First run: adopt every already-terminal worker as delivered. Supervision
276
+ * reports the transitions it observes from now on, never a replay of every
277
+ * worker that ever finished before it started.
278
+ */
279
+ function baselineState(statuses) {
280
+ const delivered = {};
281
+ for (const s of statuses) {
282
+ if (!isTerminal(s) || !ownershipKey(s)) continue;
283
+ delivered[s.id] = [eventId(s.id, "finished"), eventId(s.id, "failed")];
284
+ }
285
+ return { delivered };
286
+ }
287
+ /** The events whose ids the state has not seen yet. */
288
+ function filterUndelivered(events, state) {
289
+ return events.filter((e) => !(state.delivered[e.worker] ?? []).includes(e.id));
290
+ }
291
+ function markDelivered(state, events) {
292
+ for (const e of events) {
293
+ const ids = state.delivered[e.worker] ?? [];
294
+ if (!ids.includes(e.id)) ids.push(e.id);
295
+ state.delivered[e.worker] = ids;
296
+ }
297
+ }
298
+ /**
299
+ * Default push: AIBroker `send_to_session` into the orchestrator's terminal,
300
+ * using the iTerm uuid the worker recorded (`session.id`) or the one the
301
+ * session map bridges for the spawner's claude session. A timeout still
302
+ * delivered (see aibroker-client) counts as delivered; every failure is
303
+ * reported as not-delivered so only the event file carries the event.
304
+ */
305
+ const aibrokerPush = async (logDir, target, ev) => {
306
+ const iterm = target.iterm ?? (target.claudeSession ? itermForClaudeSession(logDir, target.claudeSession) : null);
307
+ if (!iterm) return false;
308
+ try {
309
+ const { sendToSession } = await import("./aibroker-client-C6m71p6O.mjs");
310
+ const r = await sendToSession(iterm, ev.text);
311
+ return r.ok || r.timedOut === true;
312
+ } catch {
313
+ return false;
314
+ }
315
+ };
316
+ function appendEventFile(logDir, ev) {
317
+ const path = supervisionEventsPath(logDir, ev.session);
318
+ const dir = supervisionDirPath(logDir);
319
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
320
+ appendFileSync(path, JSON.stringify(ev) + "\n", "utf8");
321
+ }
322
+ /** Record that an event reached its owner's terminal — the hook then skips it. */
323
+ function appendPushReceipt(logDir, ev) {
324
+ try {
325
+ appendFileSync(supervisionPushedPath(logDir, ev.session), `${ev.id}\n`, "utf8");
326
+ } catch {}
327
+ }
328
+ /**
329
+ * One supervision pass over the ledger: detect, append each new event to its
330
+ * owner's event file, push it best effort, persist the delivered ids. The
331
+ * event file is the durable record — an event is marked delivered only after
332
+ * its line landed there, so a failed tick retries, a repeated one replays
333
+ * nothing.
334
+ */
335
+ async function runSupervisionTick(logDir, opts = {}) {
336
+ const now = opts.now ?? /* @__PURE__ */ new Date();
337
+ const statuses = opts.statuses ?? loadStatuses(logDir);
338
+ const statePath = supervisionStatePath(logDir);
339
+ const loaded = loadSupervisionState(statePath);
340
+ let state = loaded.state;
341
+ if (loaded.fresh) state = baselineState(statuses);
342
+ const pending = filterUndelivered(detectSupervisionEvents(statuses, {
343
+ stallMs: opts.stallMs ?? DEFAULT_STALL_MINUTES * 6e4,
344
+ now,
345
+ ...opts.isAlive ? { isAlive: opts.isAlive } : {}
346
+ }), state);
347
+ const written = [];
348
+ for (const ev of pending) {
349
+ appendEventFile(logDir, ev);
350
+ written.push(ev);
351
+ }
352
+ const push = opts.push ?? aibrokerPush;
353
+ const pushed = [];
354
+ for (const ev of written) {
355
+ const owner = statuses.find((s) => s.id === ev.worker);
356
+ const target = {
357
+ claudeSession: owner?.spawnerSession ?? null,
358
+ iterm: owner?.session?.id ?? null
359
+ };
360
+ let ok = false;
361
+ try {
362
+ ok = await push(logDir, target, ev);
363
+ } catch {
364
+ ok = false;
365
+ }
366
+ if (ok) {
367
+ pushed.push(ev);
368
+ appendPushReceipt(logDir, ev);
369
+ }
370
+ }
371
+ markDelivered(state, written);
372
+ saveSupervisionState(statePath, pruneState(state, statuses));
373
+ return {
374
+ events: written,
375
+ pushed
376
+ };
377
+ }
378
+
86
379
  //#endregion
87
380
  //#region src/daemon/daemon/scheduler.ts
88
381
  /**
@@ -110,7 +403,7 @@ async function runIndex() {
110
403
  try {
111
404
  process.stderr.write("[pai-daemon] Starting scheduled index run...\n");
112
405
  if (storageBackend.backendType === "sqlite") {
113
- const { SQLiteBackend } = await import("./sqlite-kFZeWCJ2.mjs");
406
+ const { SQLiteBackend } = await import("./sqlite-Cq3gJcq9.mjs");
114
407
  if (storageBackend instanceof SQLiteBackend) {
115
408
  const { projects, result } = await indexAll(storageBackend.getRawDb(), registryDb);
116
409
  const elapsed = Date.now() - t0;
@@ -118,7 +411,7 @@ async function runIndex() {
118
411
  process.stderr.write(`[pai-daemon] Index complete: ${projects} projects, ${result.filesProcessed} files, ${result.chunksCreated} chunks (${elapsed}ms)\n`);
119
412
  }
120
413
  } else {
121
- const { indexAllWithBackend } = await import("./indexer-backend-rohVVKrA.mjs");
414
+ const { indexAllWithBackend } = await import("./indexer-backend-BPTzKFZU.mjs");
122
415
  const { projects, result } = await indexAllWithBackend(storageBackend, registryDb);
123
416
  const elapsed = Date.now() - t0;
124
417
  setLastIndexTime(Date.now());
@@ -145,7 +438,7 @@ async function runVaultIndex() {
145
438
  process.stderr.write("[pai-daemon] Index/embed in progress, deferring vault index.\n");
146
439
  return;
147
440
  }
148
- const { lastVaultIndexTime } = await import("./state-DH_mp5Xe.mjs");
441
+ const { lastVaultIndexTime } = await import("./state-RXepvbnO.mjs");
149
442
  if (lastVaultIndexTime > 0 && Date.now() - lastVaultIndexTime < VAULT_INDEX_MIN_INTERVAL_MS) return;
150
443
  let vaultProjectId = daemonConfig.vaultProjectId;
151
444
  if (!vaultProjectId) {
@@ -157,7 +450,7 @@ async function runVaultIndex() {
157
450
  const t0 = Date.now();
158
451
  process.stderr.write("[pai-daemon] Starting vault index run...\n");
159
452
  try {
160
- const { indexVault } = await import("./vault-indexer-YMH22mLU.mjs");
453
+ const { indexVault } = await import("./vault-indexer-mata9S7b.mjs");
161
454
  const r = await indexVault(storageBackend, vaultProjectId, daemonConfig.vaultPath);
162
455
  const elapsed = Date.now() - t0;
163
456
  setLastVaultIndexTime(Date.now());
@@ -228,11 +521,11 @@ async function runEmbed() {
228
521
  const rows = registryDb.prepare("SELECT id, slug FROM projects WHERE status = 'active'").all();
229
522
  for (const r of rows) projectNames.set(r.id, r.slug);
230
523
  } catch {}
231
- const { embedChunksWithBackend } = await import("./indexer-backend-rohVVKrA.mjs");
524
+ const { embedChunksWithBackend } = await import("./indexer-backend-BPTzKFZU.mjs");
232
525
  const count = await embedChunksWithBackend(storageBackend, () => shutdownRequested, projectNames, { maxMillis: 24e4 });
233
526
  let vaultEmbedCount = 0;
234
527
  if (daemonConfig.vaultPath) try {
235
- const { SQLiteBackend } = await import("./sqlite-kFZeWCJ2.mjs");
528
+ const { SQLiteBackend } = await import("./sqlite-Cq3gJcq9.mjs");
236
529
  const { openFederation } = await import("./db-O-cyAPfS.mjs");
237
530
  const federationDb = openFederation();
238
531
  const vaultSqliteBackend = new SQLiteBackend(federationDb);
@@ -292,17 +585,53 @@ const REGISTRY_SCAN_STARTUP_DELAY_MS = 1e4;
292
585
  function startRegistryScanScheduler() {
293
586
  process.stderr.write("[pai-daemon] Registry scan scheduler: every 30min (first in 10s)\n");
294
587
  setTimeout(() => {
295
- import("./work-queue-worker-BM1GcAAq.mjs").then(({ enqueueRegistryScan }) => enqueueRegistryScan()).catch((e) => {
588
+ import("./work-queue-worker-D1p2V-ae.mjs").then(({ enqueueRegistryScan }) => enqueueRegistryScan()).catch((e) => {
296
589
  process.stderr.write(`[pai-daemon] Startup registry scan error: ${e}\n`);
297
590
  });
298
591
  }, REGISTRY_SCAN_STARTUP_DELAY_MS);
299
592
  const timer = setInterval(() => {
300
- import("./work-queue-worker-BM1GcAAq.mjs").then(({ enqueueRegistryScan }) => enqueueRegistryScan()).catch((e) => {
593
+ import("./work-queue-worker-D1p2V-ae.mjs").then(({ enqueueRegistryScan }) => enqueueRegistryScan()).catch((e) => {
301
594
  process.stderr.write(`[pai-daemon] Scheduled registry scan error: ${e}\n`);
302
595
  });
303
596
  }, REGISTRY_SCAN_INTERVAL_MS);
304
597
  if (timer.unref) timer.unref();
305
598
  }
599
+ /** How often the daemon looks at the worker ledger for supervision events. */
600
+ const SUPERVISION_TICK_MS = 3e4;
601
+ /** First supervision pass waits for the first statuses to exist at all. */
602
+ const SUPERVISION_STARTUP_DELAY_MS = 15e3;
603
+ /**
604
+ * Start the worker supervisor: one tick every 30 s over the workers ledger
605
+ * (src/workers/supervision.ts) that pushes finished/failed/stalled events to
606
+ * the owning session — the daemon-side replacement for orchestrator polling.
607
+ * Daemon code only: no model call has any business being here, and none is
608
+ * made. Disabled workers disable the supervisor with it.
609
+ */
610
+ function startWorkerSupervisor() {
611
+ let enabled = false;
612
+ try {
613
+ enabled = readWorkersSection().workers.enabled;
614
+ } catch (e) {
615
+ process.stderr.write(`[pai-daemon] Worker supervisor: not started (${e instanceof Error ? e.message : String(e)})\n`);
616
+ return;
617
+ }
618
+ if (!enabled) {
619
+ process.stderr.write("[pai-daemon] Worker supervisor: disabled (workers are off)\n");
620
+ return;
621
+ }
622
+ const tick = () => {
623
+ runSupervisionTick(workersLogDir(readWorkersSection().workers), { stallMs: stallMinutesFromEnv() * 6e4 }).then((r) => {
624
+ for (const ev of r.events) process.stderr.write(`[pai-daemon] Supervision: ${ev.text}\n`);
625
+ }).catch((e) => {
626
+ process.stderr.write(`[pai-daemon] Supervision tick error: ${e instanceof Error ? e.message : String(e)}\n`);
627
+ });
628
+ };
629
+ const first = setTimeout(tick, SUPERVISION_STARTUP_DELAY_MS);
630
+ if (first.unref) first.unref();
631
+ const timer = setInterval(tick, SUPERVISION_TICK_MS);
632
+ if (timer.unref) timer.unref();
633
+ process.stderr.write(`[pai-daemon] Worker supervisor: every ${Math.round(SUPERVISION_TICK_MS / 1e3)}s\n`);
634
+ }
306
635
 
307
636
  //#endregion
308
637
  //#region src/observations/store.ts
@@ -607,7 +936,7 @@ async function dispatchTool(method, params) {
607
936
  case "zettel_themes":
608
937
  case "zettel_god_notes":
609
938
  case "zettel_communities": {
610
- const { toolZettelExplore, toolZettelHealth, toolZettelSurprise, toolZettelSuggest, toolZettelConverse, toolZettelThemes, toolZettelGodNotes, toolZettelCommunities } = await import("./tools-COna9vZR.mjs");
939
+ const { toolZettelExplore, toolZettelHealth, toolZettelSurprise, toolZettelSuggest, toolZettelConverse, toolZettelThemes, toolZettelGodNotes, toolZettelCommunities } = await import("./tools-BW3NLMPk.mjs");
611
940
  switch (method) {
612
941
  case "zettel_explore": return toolZettelExplore(storageBackend, p);
613
942
  case "zettel_health": return toolZettelHealth(storageBackend, p);
@@ -621,27 +950,27 @@ async function dispatchTool(method, params) {
621
950
  break;
622
951
  }
623
952
  case "graph_clusters": {
624
- const { handleGraphClusters } = await import("./clusters-DRHhfli9.mjs");
953
+ const { handleGraphClusters } = await import("./clusters-j0ZuNYp9.mjs");
625
954
  return handleGraphClusters(storageBackend.getPool?.() ?? null, storageBackend, p);
626
955
  }
627
956
  case "graph_neighborhood": {
628
- const { handleGraphNeighborhood } = await import("./neighborhood-AGL7oXQ2.mjs");
957
+ const { handleGraphNeighborhood } = await import("./neighborhood-CM7Jgb51.mjs");
629
958
  return handleGraphNeighborhood(storageBackend.getPool?.() ?? null, storageBackend, p);
630
959
  }
631
960
  case "graph_note_context": {
632
- const { handleGraphNoteContext } = await import("./note-context-BHwYpSFf.mjs");
961
+ const { handleGraphNoteContext } = await import("./note-context-DCwE2A-M.mjs");
633
962
  return handleGraphNoteContext(storageBackend.getPool?.() ?? null, storageBackend, p);
634
963
  }
635
964
  case "graph_trace": {
636
- const { handleGraphTrace } = await import("./trace-DTP6k4B_.mjs");
965
+ const { handleGraphTrace } = await import("./trace-u4hT-pLD.mjs");
637
966
  return handleGraphTrace(storageBackend, p);
638
967
  }
639
968
  case "graph_latent_ideas": {
640
- const { handleGraphLatentIdeas } = await import("./latent-ideas-iNp5s55R.mjs");
969
+ const { handleGraphLatentIdeas } = await import("./latent-ideas-CtSca4qG.mjs");
641
970
  return handleGraphLatentIdeas(storageBackend, p);
642
971
  }
643
972
  case "idea_materialize": {
644
- const { handleIdeaMaterialize } = await import("./latent-ideas-iNp5s55R.mjs");
973
+ const { handleIdeaMaterialize } = await import("./latent-ideas-CtSca4qG.mjs");
645
974
  if (!daemonConfig.vaultPath) throw new Error("idea_materialize requires vaultPath to be configured in the daemon config");
646
975
  return handleIdeaMaterialize(p, daemonConfig.vaultPath);
647
976
  }
@@ -649,7 +978,7 @@ async function dispatchTool(method, params) {
649
978
  case "kg_query":
650
979
  case "kg_invalidate":
651
980
  case "kg_contradictions": {
652
- const { toolKgAdd, toolKgQuery, toolKgInvalidate, toolKgContradictions } = await import("./tools-COna9vZR.mjs");
981
+ const { toolKgAdd, toolKgQuery, toolKgInvalidate, toolKgContradictions } = await import("./tools-BW3NLMPk.mjs");
653
982
  const pgPool = storageBackend.getPool?.() ?? null;
654
983
  if (!pgPool) throw new Error(`${method} requires a Postgres storage backend`);
655
984
  switch (method) {
@@ -661,7 +990,7 @@ async function dispatchTool(method, params) {
661
990
  break;
662
991
  }
663
992
  case "memory_tunnels": {
664
- const { toolMemoryTunnels } = await import("./tools-COna9vZR.mjs");
993
+ const { toolMemoryTunnels } = await import("./tools-BW3NLMPk.mjs");
665
994
  return toolMemoryTunnels(registryDb, storageBackend, p);
666
995
  }
667
996
  case "memory_feedback": {
@@ -1312,7 +1641,7 @@ async function serve(config) {
1312
1641
  process.stderr.write("[pai-daemon] Starting daemon...\n");
1313
1642
  process.stderr.write(`[pai-daemon] Socket: ${config.socketPath}\n`);
1314
1643
  process.stderr.write(`[pai-daemon] Storage backend: ${config.storageBackend}\n`);
1315
- const { notificationConfig } = await import("./state-DH_mp5Xe.mjs");
1644
+ const { notificationConfig } = await import("./state-RXepvbnO.mjs");
1316
1645
  process.stderr.write(`[pai-daemon] Notification mode: ${notificationConfig.mode}\n`);
1317
1646
  try {
1318
1647
  setPriority(process.pid, 10);
@@ -1328,6 +1657,7 @@ async function serve(config) {
1328
1657
  }
1329
1658
  const server = await startIpcServer(config.socketPath);
1330
1659
  startRegistryScanScheduler();
1660
+ startWorkerSupervisor();
1331
1661
  createStorageBackend(config, { waitForPostgres: true }).then((backend) => {
1332
1662
  setStorageBackend(backend);
1333
1663
  process.stderr.write(`[pai-daemon] Federation backend: ${backend.backendType}\n`);
@@ -1376,4 +1706,4 @@ async function serve(config) {
1376
1706
 
1377
1707
  //#endregion
1378
1708
  export { serve as t };
1379
- //# sourceMappingURL=daemon-CpdVUnl_.mjs.map
1709
+ //# sourceMappingURL=daemon-DsvP8KMy.mjs.map