@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831

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 (647) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/assets/bluebubbles-host +264 -0
  14. package/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5308 -16
  16. package/deploy/unraid/Dockerfile +54 -0
  17. package/deploy/unraid/README.txt +2983 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  34. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  35. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  36. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  37. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  38. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  39. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  40. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  41. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  42. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
  43. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
  49. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  50. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
  51. package/deploy/unraid/sanctuary.xml +28 -0
  52. package/dist/a2a/card.js +57 -0
  53. package/dist/a2a/client.js +180 -0
  54. package/dist/a2a/config.js +50 -0
  55. package/dist/a2a/delegation-stores.js +56 -0
  56. package/dist/a2a/did-resolution.js +93 -0
  57. package/dist/a2a/identity.js +170 -0
  58. package/dist/a2a/inbound-share.js +107 -0
  59. package/dist/a2a/mission-result-wire.js +196 -0
  60. package/dist/a2a/onboarding.js +115 -0
  61. package/dist/a2a/pin-store.js +132 -0
  62. package/dist/a2a/seen-ledger.js +120 -0
  63. package/dist/a2a/server.js +604 -0
  64. package/dist/a2a/task-store.js +69 -0
  65. package/dist/a2a/transport.js +45 -0
  66. package/dist/a2a/types.js +3 -0
  67. package/dist/arc/attention-types.js +8 -0
  68. package/dist/arc/cares.js +360 -0
  69. package/dist/arc/episodes.js +118 -0
  70. package/dist/arc/evolution.js +490 -0
  71. package/dist/arc/flight-recorder.js +1034 -0
  72. package/dist/arc/intentions.js +134 -0
  73. package/dist/arc/json-store.js +117 -0
  74. package/dist/arc/obligations.js +386 -0
  75. package/dist/arc/packets.js +336 -0
  76. package/dist/arc/presence.js +185 -0
  77. package/dist/arc/task-lifecycle.js +57 -0
  78. package/dist/commerce/store.js +755 -0
  79. package/dist/commerce/types.js +3 -0
  80. package/dist/heart/active-work.js +798 -40
  81. package/dist/heart/agent-entry.js +252 -3
  82. package/dist/heart/approval-files.js +113 -0
  83. package/dist/heart/approval-store.js +960 -0
  84. package/dist/heart/attachments/image-normalize.js +194 -0
  85. package/dist/heart/attachments/materialize.js +97 -0
  86. package/dist/heart/attachments/originals.js +88 -0
  87. package/dist/heart/attachments/render.js +29 -0
  88. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  89. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  90. package/dist/heart/attachments/sources/index.js +18 -0
  91. package/dist/heart/attachments/sources/telegram.js +71 -0
  92. package/dist/heart/attachments/store.js +132 -0
  93. package/dist/heart/attachments/types.js +93 -0
  94. package/dist/heart/auth/auth-flow.js +495 -0
  95. package/dist/heart/autonomy-budget.js +478 -0
  96. package/dist/heart/awaiting/await-alert.js +148 -0
  97. package/dist/heart/awaiting/await-expiry.js +143 -0
  98. package/dist/heart/awaiting/await-loader.js +91 -0
  99. package/dist/heart/awaiting/await-parser.js +149 -0
  100. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  101. package/dist/heart/awaiting/await-scheduler.js +382 -0
  102. package/dist/heart/background-operations.js +281 -0
  103. package/dist/heart/bridges/manager.js +137 -17
  104. package/dist/heart/bridges/store.js +14 -2
  105. package/dist/heart/bundle-state.js +168 -0
  106. package/dist/heart/commitments.js +44 -18
  107. package/dist/heart/config-registry.js +331 -0
  108. package/dist/heart/config.js +174 -131
  109. package/dist/heart/context-loss-gauntlet.js +387 -0
  110. package/dist/heart/context-loss-sentinel.js +1157 -0
  111. package/dist/heart/core.js +2169 -581
  112. package/dist/heart/cross-chat-delivery.js +9 -22
  113. package/dist/heart/daemon/agent-config-check.js +451 -0
  114. package/dist/heart/daemon/agent-discovery.js +185 -3
  115. package/dist/heart/daemon/agent-service.js +542 -0
  116. package/dist/heart/daemon/agentic-repair.js +547 -0
  117. package/dist/heart/daemon/await-private-wake.js +59 -0
  118. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  119. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  120. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  121. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  122. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  123. package/dist/heart/daemon/cadence.js +180 -0
  124. package/dist/heart/daemon/cli-defaults.js +854 -0
  125. package/dist/heart/daemon/cli-desk.js +322 -0
  126. package/dist/heart/daemon/cli-exec.js +8822 -0
  127. package/dist/heart/daemon/cli-help.js +716 -0
  128. package/dist/heart/daemon/cli-parse.js +2771 -0
  129. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  130. package/dist/heart/daemon/cli-render.js +777 -0
  131. package/dist/heart/daemon/cli-types.js +8 -0
  132. package/dist/heart/daemon/connect-bay.js +323 -0
  133. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  134. package/dist/heart/daemon/container-healthcheck.js +112 -0
  135. package/dist/heart/daemon/container-runtime.js +97 -0
  136. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  137. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  138. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  139. package/dist/heart/daemon/daemon-cli.js +29 -2349
  140. package/dist/heart/daemon/daemon-entry.js +930 -11
  141. package/dist/heart/daemon/daemon-health.js +186 -0
  142. package/dist/heart/daemon/daemon-rollup.js +57 -0
  143. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  144. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  145. package/dist/heart/daemon/daemon.js +2084 -105
  146. package/dist/heart/daemon/dns-workflow.js +394 -0
  147. package/dist/heart/daemon/doctor-types.js +8 -0
  148. package/dist/heart/daemon/doctor.js +1755 -0
  149. package/dist/heart/daemon/freshness.js +345 -0
  150. package/dist/heart/daemon/habit-private-wake.js +61 -0
  151. package/dist/heart/daemon/health-monitor.js +142 -11
  152. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  153. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  154. package/dist/heart/daemon/http-health-probe.js +80 -0
  155. package/dist/heart/daemon/human-command-screens.js +234 -0
  156. package/dist/heart/daemon/human-readiness.js +114 -0
  157. package/dist/heart/daemon/inner-status.js +78 -0
  158. package/dist/heart/daemon/interactive-repair.js +394 -0
  159. package/dist/heart/daemon/launchd.js +37 -8
  160. package/dist/heart/daemon/log-tailer.js +79 -10
  161. package/dist/heart/daemon/logs-prune.js +132 -0
  162. package/dist/heart/daemon/mcp-canary.js +524 -0
  163. package/dist/heart/daemon/message-router.js +65 -5
  164. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  165. package/dist/heart/daemon/os-cron-deps.js +135 -0
  166. package/dist/heart/daemon/os-cron.js +22 -14
  167. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  168. package/dist/heart/daemon/ouro-entry.js +3 -1
  169. package/dist/heart/daemon/plugin-cli.js +432 -0
  170. package/dist/heart/daemon/process-manager.js +733 -61
  171. package/dist/heart/daemon/provider-discovery.js +137 -0
  172. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  173. package/dist/heart/daemon/prunable-bundle.js +144 -0
  174. package/dist/heart/daemon/pulse.js +511 -0
  175. package/dist/heart/daemon/readiness-repair.js +365 -0
  176. package/dist/heart/daemon/run-hooks.js +2 -0
  177. package/dist/heart/daemon/runtime-logging.js +47 -14
  178. package/dist/heart/daemon/runtime-metadata.js +2 -30
  179. package/dist/heart/daemon/runtime-mode.js +13 -2
  180. package/dist/heart/daemon/safe-mode.js +161 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  185. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  186. package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
  187. package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
  188. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  189. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
  190. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  191. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  192. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  193. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
  194. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  195. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  196. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  197. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  198. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  199. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  200. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  201. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  202. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  203. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
  204. package/dist/heart/daemon/sense-manager.js +699 -48
  205. package/dist/heart/daemon/session-id-resolver.js +131 -0
  206. package/dist/heart/daemon/skill-management-installer.js +1 -1
  207. package/dist/heart/daemon/socket-client.js +180 -12
  208. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  209. package/dist/heart/daemon/startup-tui.js +339 -0
  210. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  211. package/dist/heart/daemon/task-scheduler.js +117 -39
  212. package/dist/heart/daemon/terminal-ui.js +499 -0
  213. package/dist/heart/daemon/thoughts.js +138 -54
  214. package/dist/heart/daemon/up-progress.js +366 -0
  215. package/dist/heart/daemon/vault-items.js +56 -0
  216. package/dist/heart/delegation.js +1 -4
  217. package/dist/heart/external-events/router.js +1430 -0
  218. package/dist/heart/frontend-approval-runtime.js +506 -0
  219. package/dist/heart/frontend-journal.js +215 -0
  220. package/dist/heart/frontend-session-service.js +237 -0
  221. package/dist/heart/frontend-socket-client.js +164 -0
  222. package/dist/heart/frontend-socket.js +400 -0
  223. package/dist/heart/habits/habit-cancel.js +810 -0
  224. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  225. package/dist/heart/habits/habit-migration.js +194 -0
  226. package/dist/heart/habits/habit-parser.js +278 -0
  227. package/dist/heart/habits/habit-runtime-state.js +93 -0
  228. package/dist/heart/habits/habit-scheduler.js +653 -0
  229. package/dist/heart/habits/habit-session-summary.js +318 -0
  230. package/dist/heart/habits/habit-session.js +636 -0
  231. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  232. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  233. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  234. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  235. package/dist/heart/identity.js +196 -59
  236. package/dist/heart/kept-notes.js +289 -0
  237. package/dist/heart/kicks.js +1 -1
  238. package/dist/heart/machine-identity.js +161 -0
  239. package/dist/heart/mail-import-discovery.js +356 -0
  240. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  241. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  242. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  243. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  244. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  245. package/dist/heart/mailbox/mailbox-http.js +99 -0
  246. package/dist/heart/mailbox/mailbox-read.js +39 -0
  247. package/dist/heart/mailbox/mailbox-types.js +27 -0
  248. package/dist/heart/mailbox/mailbox-view.js +197 -0
  249. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  250. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  251. package/dist/heart/mailbox/readers/mail.js +375 -0
  252. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  253. package/dist/heart/mailbox/readers/sessions.js +231 -0
  254. package/dist/heart/mailbox/readers/shared.js +111 -0
  255. package/dist/heart/mcp/mcp-server.js +696 -0
  256. package/dist/heart/migrate-config.js +100 -0
  257. package/dist/heart/model-capabilities.js +11 -0
  258. package/dist/heart/orientation-frame.js +345 -0
  259. package/dist/heart/platform.js +81 -0
  260. package/dist/heart/primitives.js +1 -1
  261. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  262. package/dist/heart/private-runtime/index.js +18 -0
  263. package/dist/heart/private-runtime/ledger.js +221 -0
  264. package/dist/heart/private-runtime/policy.js +252 -0
  265. package/dist/heart/private-runtime/types.js +2 -0
  266. package/dist/heart/progress-story.js +1 -1
  267. package/dist/heart/provider-attempt.js +137 -0
  268. package/dist/heart/provider-binding-resolver.js +273 -0
  269. package/dist/heart/provider-credentials.js +449 -0
  270. package/dist/heart/provider-failover.js +311 -0
  271. package/dist/heart/provider-models.js +96 -0
  272. package/dist/heart/provider-ping.js +265 -0
  273. package/dist/heart/provider-readiness-cache.js +119 -0
  274. package/dist/heart/provider-visibility.js +188 -0
  275. package/dist/heart/providers/anthropic-token.js +131 -0
  276. package/dist/heart/providers/anthropic.js +173 -60
  277. package/dist/heart/providers/azure.js +23 -11
  278. package/dist/heart/providers/error-classification.js +127 -0
  279. package/dist/heart/providers/github-copilot.js +34 -38
  280. package/dist/heart/providers/minimax-vlm.js +189 -0
  281. package/dist/heart/providers/minimax.js +26 -8
  282. package/dist/heart/providers/openai-codex-token.js +349 -0
  283. package/dist/heart/providers/openai-codex.js +55 -40
  284. package/dist/heart/providers/openai-compatible.js +177 -0
  285. package/dist/heart/run-ledger.js +247 -0
  286. package/dist/heart/runtime-capability-check.js +170 -0
  287. package/dist/heart/runtime-credentials.js +607 -0
  288. package/dist/heart/runtime-cwd.js +87 -0
  289. package/dist/heart/sense-truth.js +22 -4
  290. package/dist/heart/session-activity.js +92 -24
  291. package/dist/heart/session-events.js +1504 -0
  292. package/dist/heart/session-playback-cli-main.js +5 -0
  293. package/dist/heart/session-playback-cli.js +36 -0
  294. package/dist/heart/session-playback.js +231 -0
  295. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  296. package/dist/heart/session-redaction-repair.js +552 -0
  297. package/dist/heart/session-stats-cli-main.js +5 -0
  298. package/dist/heart/session-stats.js +183 -0
  299. package/dist/heart/session-transcript.js +133 -0
  300. package/dist/heart/start-of-turn-packet.js +372 -0
  301. package/dist/heart/steward-policy.js +618 -0
  302. package/dist/heart/streaming.js +604 -207
  303. package/dist/heart/structured-output.js +196 -0
  304. package/dist/heart/sync-classification.js +176 -0
  305. package/dist/heart/sync.js +449 -0
  306. package/dist/heart/target-resolution.js +11 -7
  307. package/dist/heart/tempo.js +93 -0
  308. package/dist/heart/temporal-view.js +41 -0
  309. package/dist/heart/timeouts.js +101 -0
  310. package/dist/heart/tool-activity-callbacks.js +59 -0
  311. package/dist/heart/tool-approval.js +382 -0
  312. package/dist/heart/tool-description.js +155 -0
  313. package/dist/heart/tool-friction.js +55 -0
  314. package/dist/heart/tool-loop.js +200 -0
  315. package/dist/heart/turn-context.js +482 -0
  316. package/dist/heart/turn-execution-lease.js +30 -0
  317. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  318. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  319. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  320. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  321. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  322. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  323. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  324. package/dist/heart/versioning/update-hooks.js +154 -0
  325. package/dist/heart/versioning/version-intent.js +114 -0
  326. package/dist/heart/work-card.js +380 -0
  327. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  328. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  329. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  330. package/dist/mailbox-ui/index.html +16 -0
  331. package/dist/mailroom/attention.js +167 -0
  332. package/dist/mailroom/autonomy.js +209 -0
  333. package/dist/mailroom/blob-store.js +889 -0
  334. package/dist/mailroom/body-cache.js +61 -0
  335. package/dist/mailroom/cache-sync-cli.js +58 -0
  336. package/dist/mailroom/core.js +803 -0
  337. package/dist/mailroom/entry.js +160 -0
  338. package/dist/mailroom/file-store.js +568 -0
  339. package/dist/mailroom/hosted-cache-sync.js +384 -0
  340. package/dist/mailroom/mbox-import.js +393 -0
  341. package/dist/mailroom/migration.js +164 -0
  342. package/dist/mailroom/outbound.js +380 -0
  343. package/dist/mailroom/policy.js +263 -0
  344. package/dist/mailroom/reader.js +292 -0
  345. package/dist/mailroom/search-cache.js +513 -0
  346. package/dist/mailroom/search-relevance.js +319 -0
  347. package/dist/mailroom/smtp-ingress.js +176 -0
  348. package/dist/mailroom/source-state.js +176 -0
  349. package/dist/mailroom/thread.js +109 -0
  350. package/dist/mailroom/travel-extract.js +89 -0
  351. package/dist/mind/bundle-manifest.js +24 -2
  352. package/dist/mind/context.js +309 -111
  353. package/dist/mind/desk-section.js +362 -0
  354. package/dist/mind/diary-integrity.js +60 -0
  355. package/dist/mind/{memory.js → diary.js} +68 -77
  356. package/dist/mind/embedding-provider.js +60 -0
  357. package/dist/mind/file-state.js +179 -0
  358. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  359. package/dist/mind/obligation-steering.js +199 -3
  360. package/dist/mind/pending.js +36 -10
  361. package/dist/mind/prompt-budget.js +479 -0
  362. package/dist/mind/prompt-refresh.js +3 -2
  363. package/dist/mind/prompt.js +1050 -189
  364. package/dist/mind/provenance-trust.js +26 -0
  365. package/dist/mind/record-paths.js +312 -0
  366. package/dist/mind/scrutiny.js +173 -0
  367. package/dist/mind/session-transaction.js +564 -0
  368. package/dist/nerves/cli-logging.js +7 -1
  369. package/dist/nerves/coverage/audit-rules.js +15 -6
  370. package/dist/nerves/coverage/audit.js +28 -2
  371. package/dist/nerves/coverage/cli.js +1 -1
  372. package/dist/nerves/coverage/contract.js +5 -5
  373. package/dist/nerves/coverage/file-completeness.js +139 -5
  374. package/dist/nerves/coverage/run-artifacts.js +55 -35
  375. package/dist/nerves/coverage/source-scanner.js +4 -4
  376. package/dist/nerves/event-buffer.js +111 -0
  377. package/dist/nerves/index.js +293 -9
  378. package/dist/nerves/observation.js +20 -0
  379. package/dist/nerves/redact.js +79 -0
  380. package/dist/nerves/review/cli-main.js +5 -0
  381. package/dist/nerves/review/cli.js +156 -0
  382. package/dist/nerves/review/core.js +159 -0
  383. package/dist/nerves/runtime.js +17 -1
  384. package/dist/repertoire/ado-client.js +15 -56
  385. package/dist/repertoire/ado-semantic.js +16 -10
  386. package/dist/repertoire/api-client.js +97 -0
  387. package/dist/repertoire/bitwarden-store.js +1045 -0
  388. package/dist/repertoire/bundle-templates.js +71 -0
  389. package/dist/repertoire/bw-installer.js +180 -0
  390. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  391. package/dist/repertoire/coding/context-pack.js +331 -0
  392. package/dist/repertoire/coding/feedback.js +174 -32
  393. package/dist/repertoire/coding/index.js +15 -3
  394. package/dist/repertoire/coding/manager.js +159 -10
  395. package/dist/repertoire/coding/spawner.js +58 -11
  396. package/dist/repertoire/coding/tools.js +221 -15
  397. package/dist/repertoire/coding/workbench-client.js +272 -0
  398. package/dist/repertoire/coding/workbench-manager.js +346 -0
  399. package/dist/repertoire/commerce-errors.js +109 -0
  400. package/dist/repertoire/commerce-self-test.js +156 -0
  401. package/dist/repertoire/credential-access.js +178 -0
  402. package/dist/repertoire/desk/classifier.js +362 -0
  403. package/dist/repertoire/duffel-client.js +185 -0
  404. package/dist/repertoire/github-client.js +14 -55
  405. package/dist/repertoire/graph-client.js +11 -52
  406. package/dist/repertoire/guardrails.js +811 -18
  407. package/dist/repertoire/mcp-client.js +44 -3
  408. package/dist/repertoire/mcp-manager.js +427 -139
  409. package/dist/repertoire/mcp-tools.js +124 -0
  410. package/dist/repertoire/plugin-mcp.js +175 -0
  411. package/dist/repertoire/plugins.js +253 -0
  412. package/dist/repertoire/relationship-authorization.js +322 -0
  413. package/dist/repertoire/shell-sessions.js +134 -0
  414. package/dist/repertoire/skills.js +48 -4
  415. package/dist/repertoire/stripe-client.js +131 -0
  416. package/dist/repertoire/tool-arguments.js +170 -0
  417. package/dist/repertoire/tool-results.js +29 -0
  418. package/dist/repertoire/tools-a2a.js +699 -0
  419. package/dist/repertoire/tools-attachments.js +322 -0
  420. package/dist/repertoire/tools-awaiting.js +575 -0
  421. package/dist/repertoire/tools-base.js +77 -1138
  422. package/dist/repertoire/tools-bluebubbles.js +2 -0
  423. package/dist/repertoire/tools-bridge.js +144 -0
  424. package/dist/repertoire/tools-bundle.js +993 -0
  425. package/dist/repertoire/tools-commerce.js +253 -0
  426. package/dist/repertoire/tools-config.js +186 -0
  427. package/dist/repertoire/tools-continuity.js +575 -0
  428. package/dist/repertoire/tools-credential.js +383 -0
  429. package/dist/repertoire/tools-evolution.js +527 -0
  430. package/dist/repertoire/tools-files.js +344 -0
  431. package/dist/repertoire/tools-flight.js +290 -0
  432. package/dist/repertoire/tools-flow.js +119 -0
  433. package/dist/repertoire/tools-github.js +3 -8
  434. package/dist/repertoire/tools-habits.js +103 -0
  435. package/dist/repertoire/tools-mail.js +1828 -0
  436. package/dist/repertoire/tools-notes.js +485 -0
  437. package/dist/repertoire/tools-obligations.js +182 -0
  438. package/dist/repertoire/tools-orientation.js +31 -0
  439. package/dist/repertoire/tools-record.js +482 -0
  440. package/dist/repertoire/tools-rsvp.js +139 -0
  441. package/dist/repertoire/tools-runtime.js +150 -0
  442. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  443. package/dist/repertoire/tools-session.js +1133 -0
  444. package/dist/repertoire/tools-shell.js +149 -0
  445. package/dist/repertoire/tools-steward-policy.js +119 -0
  446. package/dist/repertoire/tools-stripe.js +224 -0
  447. package/dist/repertoire/tools-surface.js +369 -0
  448. package/dist/repertoire/tools-teams.js +12 -39
  449. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  450. package/dist/repertoire/tools-travel.js +125 -0
  451. package/dist/repertoire/tools-trip.js +982 -0
  452. package/dist/repertoire/tools-unraid.js +531 -0
  453. package/dist/repertoire/tools-user-profile.js +146 -0
  454. package/dist/repertoire/tools-vault.js +40 -0
  455. package/dist/repertoire/tools-voice.js +145 -0
  456. package/dist/repertoire/tools.js +494 -148
  457. package/dist/repertoire/travel-api-client.js +360 -0
  458. package/dist/repertoire/unraid-client.js +155 -0
  459. package/dist/repertoire/unraid-restart.js +339 -0
  460. package/dist/repertoire/user-profile.js +131 -0
  461. package/dist/repertoire/vault-setup.js +246 -0
  462. package/dist/repertoire/vault-unlock.js +628 -0
  463. package/dist/rsvp/aisleplanner-client.js +354 -0
  464. package/dist/rsvp/cli.js +926 -0
  465. package/dist/rsvp/config.js +327 -0
  466. package/dist/rsvp/cutover.js +433 -0
  467. package/dist/rsvp/diagnostics.js +232 -0
  468. package/dist/rsvp/diff-renderer.js +176 -0
  469. package/dist/rsvp/habit-policy.js +110 -0
  470. package/dist/rsvp/habit-stage.js +123 -0
  471. package/dist/rsvp/incident-bundle.js +97 -0
  472. package/dist/rsvp/migration.js +204 -0
  473. package/dist/rsvp/native-habit-runner.js +630 -0
  474. package/dist/rsvp/outbound-state.js +628 -0
  475. package/dist/rsvp/query.js +118 -0
  476. package/dist/rsvp/replay.js +233 -0
  477. package/dist/rsvp/snapshot.js +232 -0
  478. package/dist/rsvp/spend-ledger.js +175 -0
  479. package/dist/scripts/claude-code-hook.js +41 -0
  480. package/dist/scripts/claude-code-stop-hook.js +47 -0
  481. package/dist/senses/a2a-entry.js +115 -0
  482. package/dist/senses/acp-server.js +386 -0
  483. package/dist/senses/attention-queue.js +186 -0
  484. package/dist/senses/await-turn-message.js +58 -0
  485. package/dist/senses/bluebubbles/active-turns.js +216 -0
  486. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  487. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  488. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  489. package/dist/senses/bluebubbles/context-packet.js +207 -0
  490. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  491. package/dist/senses/bluebubbles/entry.js +90 -0
  492. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  493. package/dist/senses/bluebubbles/index.js +3841 -0
  494. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  495. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  496. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  497. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  498. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  499. package/dist/senses/bluebubbles/processed-log.js +133 -0
  500. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  501. package/dist/senses/bluebubbles/replay.js +284 -0
  502. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  503. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  504. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  505. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  506. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  507. package/dist/senses/cli/bracketed-paste.js +82 -0
  508. package/dist/senses/cli/image-paste.js +287 -0
  509. package/dist/senses/cli/image-ref-navigation.js +75 -0
  510. package/dist/senses/cli/ink-app.js +156 -0
  511. package/dist/senses/cli/inline-diff.js +64 -0
  512. package/dist/senses/cli/input-keys.js +174 -0
  513. package/dist/senses/cli/kill-ring.js +86 -0
  514. package/dist/senses/cli/message-list.js +51 -0
  515. package/dist/senses/cli/ouro-tui.js +607 -0
  516. package/dist/senses/cli/spinner-imperative.js +135 -0
  517. package/dist/senses/cli/spinner.js +101 -0
  518. package/dist/senses/cli/status-line.js +60 -0
  519. package/dist/senses/cli/streaming-markdown.js +526 -0
  520. package/dist/senses/cli/tool-display.js +85 -0
  521. package/dist/senses/cli/tool-render.js +85 -0
  522. package/dist/senses/cli/tui-store.js +241 -0
  523. package/dist/senses/cli/virtual-list.js +35 -0
  524. package/dist/senses/cli-entry.js +60 -8
  525. package/dist/senses/cli.js +604 -320
  526. package/dist/senses/commands.js +66 -3
  527. package/dist/senses/context-packet-ledger.js +371 -0
  528. package/dist/senses/context-packets.js +154 -0
  529. package/dist/senses/habit-lifecycle-guard.js +24 -0
  530. package/dist/senses/habit-turn-message.js +160 -0
  531. package/dist/senses/ingress-evidence.js +2 -0
  532. package/dist/senses/mail-entry.js +66 -0
  533. package/dist/senses/mail.js +524 -0
  534. package/dist/senses/pipeline.js +1115 -204
  535. package/dist/senses/private-runtime-worker.js +859 -0
  536. package/dist/senses/private-runtime.js +1517 -0
  537. package/dist/senses/proactive-content-guard.js +51 -0
  538. package/dist/senses/root-host-approval-port.js +345 -0
  539. package/dist/senses/root-host-approval-runtime.js +393 -0
  540. package/dist/senses/sanctuary-authority-resident.js +102 -0
  541. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  542. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  543. package/dist/senses/sanctuary-grounding.js +118 -0
  544. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  545. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  546. package/dist/senses/sanctuary-health-runner.js +100 -0
  547. package/dist/senses/sanctuary-health.js +408 -0
  548. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  549. package/dist/senses/sanctuary-interactive-control.js +410 -0
  550. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  551. package/dist/senses/sanctuary-media-optimization.js +514 -0
  552. package/dist/senses/sanctuary-runtime.js +340 -0
  553. package/dist/senses/sanctuary-sab.js +85 -0
  554. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  555. package/dist/senses/shared-turn.js +772 -0
  556. package/dist/senses/surface-tool.js +109 -0
  557. package/dist/senses/teams-entry.js +60 -8
  558. package/dist/senses/teams.js +519 -218
  559. package/dist/senses/telegram-admission.js +718 -0
  560. package/dist/senses/telegram-approval-runtime.js +793 -0
  561. package/dist/senses/telegram-attachments.js +186 -0
  562. package/dist/senses/telegram-audit-ledger.js +220 -0
  563. package/dist/senses/telegram-authority-transport.js +231 -0
  564. package/dist/senses/telegram-client.js +1749 -0
  565. package/dist/senses/telegram-effect-adapter.js +896 -0
  566. package/dist/senses/telegram-entry.js +83 -0
  567. package/dist/senses/telegram.js +2324 -0
  568. package/dist/senses/trust-gate.js +104 -9
  569. package/dist/senses/voice/audio-playback.js +237 -0
  570. package/dist/senses/voice/audio-routing.js +119 -0
  571. package/dist/senses/voice/elevenlabs.js +202 -0
  572. package/dist/senses/voice/floor-control.js +431 -0
  573. package/dist/senses/voice/floor-controller.js +115 -0
  574. package/dist/senses/voice/golden-path.js +116 -0
  575. package/dist/senses/voice/index.js +29 -0
  576. package/dist/senses/voice/meeting.js +113 -0
  577. package/dist/senses/voice/outbound.js +190 -0
  578. package/dist/senses/voice/phone.js +33 -0
  579. package/dist/senses/voice/playback.js +139 -0
  580. package/dist/senses/voice/realtime-eval.js +496 -0
  581. package/dist/senses/voice/realtime-trace.js +531 -0
  582. package/dist/senses/voice/transcript.js +70 -0
  583. package/dist/senses/voice/turn.js +191 -0
  584. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  585. package/dist/senses/voice/twilio-phone.js +5031 -0
  586. package/dist/senses/voice/types.js +2 -0
  587. package/dist/senses/voice/whisper.js +161 -0
  588. package/dist/senses/voice-entry.js +81 -0
  589. package/dist/senses/voice-realtime-eval-command.js +99 -0
  590. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  591. package/dist/senses/voice-twilio-entry.js +87 -0
  592. package/dist/trips/core.js +138 -0
  593. package/dist/trips/store.js +265 -0
  594. package/dist/util/frontmatter.js +69 -0
  595. package/npm-shrinkwrap.json +8138 -0
  596. package/package.json +72 -13
  597. package/skills/agent-commerce.md +113 -0
  598. package/skills/browser-navigation.md +117 -0
  599. package/skills/commerce-setup-guide.md +116 -0
  600. package/skills/commerce-setup.md +84 -0
  601. package/skills/configure-dev-tools.md +99 -0
  602. package/skills/travel-planning.md +138 -0
  603. package/dist/heart/daemon/auth-flow.js +0 -430
  604. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  605. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  606. package/dist/heart/daemon/update-hooks.js +0 -138
  607. package/dist/heart/obligations.js +0 -191
  608. package/dist/heart/safe-workspace.js +0 -228
  609. package/dist/heart/session-recall.js +0 -116
  610. package/dist/mind/friends/channel.js +0 -84
  611. package/dist/mind/friends/group-context.js +0 -144
  612. package/dist/mind/friends/resolver.js +0 -84
  613. package/dist/mind/friends/store-file.js +0 -190
  614. package/dist/mind/friends/store.js +0 -4
  615. package/dist/mind/friends/tokens.js +0 -26
  616. package/dist/mind/friends/trust-explanation.js +0 -74
  617. package/dist/mind/friends/types.js +0 -29
  618. package/dist/repertoire/tasks/board.js +0 -134
  619. package/dist/repertoire/tasks/index.js +0 -224
  620. package/dist/repertoire/tasks/lifecycle.js +0 -80
  621. package/dist/repertoire/tasks/middleware.js +0 -65
  622. package/dist/repertoire/tasks/parser.js +0 -173
  623. package/dist/repertoire/tasks/scanner.js +0 -132
  624. package/dist/repertoire/tasks/transitions.js +0 -144
  625. package/dist/senses/bluebubbles-entry.js +0 -13
  626. package/dist/senses/bluebubbles.js +0 -1181
  627. package/dist/senses/debug-activity.js +0 -154
  628. package/dist/senses/inner-dialog-worker.js +0 -90
  629. package/dist/senses/inner-dialog.js +0 -525
  630. package/subagents/README.md +0 -7
  631. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  632. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  633. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  643. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  644. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  645. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  646. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  647. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ /**
3
+ * Pipeline freshness — "is this pipe still moving?"
4
+ *
5
+ * Every outage this module exists to prevent had the same shape: a health
6
+ * check verified that something was *configured* or *connected*, and reported
7
+ * a green tick next to a pipe that had been dead for weeks.
8
+ *
9
+ * - mail: `mail enabled` / `mail config ok` / `45479 messages` all passed
10
+ * while zero mail had been ingested for 77 days after a vault key rotation
11
+ * changed the mailbox keyIds. The message count is cumulative, so it can
12
+ * only ever go up — it is not a liveness signal.
13
+ * - bluebubbles: the upstream HTTP probe stayed `ok` for days while inbound
14
+ * delivery was dead, because the server was POSTing its webhook to a
15
+ * stale port. A reachable upstream does not prove inbound delivery.
16
+ * - launchd: checks asserted a plist *file* existed rather than that the
17
+ * job was loaded.
18
+ *
19
+ * The fix is to assert on *observed data flow*, with three rules baked into
20
+ * this primitive:
21
+ *
22
+ * 1. Age is always stated in the message, in human units, with the
23
+ * timestamp it was derived from.
24
+ * 2. "Never observed any activity" and "could not observe" are distinct
25
+ * states from "activity, but stale" — and none of them can read as
26
+ * `pass`. An unobservable pipe is unverified, not healthy.
27
+ * 3. Every non-`pass` result carries a concrete remediation hint.
28
+ *
29
+ * Thresholds are always supplied by the caller so freshness policy lives with
30
+ * the pipe it describes, not in this file.
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.DEFAULT_CLOCK_SKEW_TOLERANCE_MS = exports.FRESHNESS_DAY_MS = exports.FRESHNESS_HOUR_MS = exports.FRESHNESS_MINUTE_MS = void 0;
34
+ exports.formatFreshnessAge = formatFreshnessAge;
35
+ exports.formatFreshnessTimestamp = formatFreshnessTimestamp;
36
+ exports.evaluateFreshness = evaluateFreshness;
37
+ exports.observeCreatePerEventStore = observeCreatePerEventStore;
38
+ exports.observeMirroredStore = observeMirroredStore;
39
+ exports.observeAppendPerEventStore = observeAppendPerEventStore;
40
+ exports.resolveFreshnessThresholds = resolveFreshnessThresholds;
41
+ const runtime_1 = require("../../nerves/runtime");
42
+ exports.FRESHNESS_MINUTE_MS = 60 * 1000;
43
+ exports.FRESHNESS_HOUR_MS = 60 * exports.FRESHNESS_MINUTE_MS;
44
+ exports.FRESHNESS_DAY_MS = 24 * exports.FRESHNESS_HOUR_MS;
45
+ /** Small tolerance before a future timestamp is treated as clock skew. */
46
+ exports.DEFAULT_CLOCK_SKEW_TOLERANCE_MS = exports.FRESHNESS_MINUTE_MS;
47
+ /**
48
+ * Human-readable duration. Always rounds down so the age is never overstated:
49
+ * "77 days" means at least 77 days have elapsed.
50
+ */
51
+ function formatFreshnessAge(ms) {
52
+ const clamped = Math.max(0, ms);
53
+ const seconds = Math.floor(clamped / 1000);
54
+ if (seconds < 60)
55
+ return `${seconds} second${seconds === 1 ? "" : "s"}`;
56
+ const minutes = Math.floor(clamped / exports.FRESHNESS_MINUTE_MS);
57
+ if (minutes < 60)
58
+ return `${minutes} minute${minutes === 1 ? "" : "s"}`;
59
+ const hours = Math.floor(clamped / exports.FRESHNESS_HOUR_MS);
60
+ if (hours < 48)
61
+ return `${hours} hour${hours === 1 ? "" : "s"}`;
62
+ // The day bucket only starts at 48h, so it is always plural.
63
+ return `${Math.floor(clamped / exports.FRESHNESS_DAY_MS)} days`;
64
+ }
65
+ /** Minute-precision ISO instant — keeps the incident date visible and unambiguous. */
66
+ function formatFreshnessTimestamp(ms) {
67
+ return new Date(ms).toISOString().replace(/:\d{2}\.\d{3}Z$/, "Z");
68
+ }
69
+ function joinDetail(parts) {
70
+ return parts.filter((part) => !!part && part.trim().length > 0).join("; ");
71
+ }
72
+ function statusForAge(ageMs, thresholds) {
73
+ if (ageMs >= thresholds.failAfterMs)
74
+ return "fail";
75
+ if (ageMs >= thresholds.warnAfterMs)
76
+ return "warn";
77
+ return "pass";
78
+ }
79
+ /**
80
+ * Severity for "readable store, nothing ever recorded".
81
+ *
82
+ * Floors at `warn` on purpose: a configured-but-never-delivered pipe is never
83
+ * healthy, but a pipe wired up minutes ago does not deserve a hard failure.
84
+ */
85
+ function statusForNever(input) {
86
+ const since = input.configuredSinceMs;
87
+ if (typeof since !== "number" || !Number.isFinite(since)) {
88
+ return { status: "fail", configuredForMs: null };
89
+ }
90
+ const configuredForMs = Math.max(0, input.nowMs - since);
91
+ const escalated = statusForAge(configuredForMs, input.thresholds);
92
+ return { status: escalated === "pass" ? "warn" : escalated, configuredForMs };
93
+ }
94
+ function evaluateActivity(input, atMs) {
95
+ const tolerance = input.clockSkewToleranceMs ?? exports.DEFAULT_CLOCK_SKEW_TOLERANCE_MS;
96
+ const skewMs = atMs - input.nowMs;
97
+ const timestamp = formatFreshnessTimestamp(atMs);
98
+ if (skewMs > tolerance) {
99
+ return {
100
+ status: "warn",
101
+ state: "future",
102
+ ageMs: 0,
103
+ detail: joinDetail([
104
+ input.context,
105
+ `last ${input.unit} is timestamped ${timestamp}, ${formatFreshnessAge(skewMs)} in the future — clock skew means freshness cannot be trusted`,
106
+ input.provenance,
107
+ `fix: ${input.remediation}`,
108
+ ]),
109
+ };
110
+ }
111
+ const ageMs = Math.max(0, -skewMs);
112
+ const status = statusForAge(ageMs, input.thresholds);
113
+ if (status === "pass") {
114
+ return {
115
+ status,
116
+ state: "fresh",
117
+ ageMs,
118
+ detail: joinDetail([
119
+ input.context,
120
+ `${input.activity} ${formatFreshnessAge(ageMs)} ago (last ${input.unit} ${timestamp})`,
121
+ input.provenance,
122
+ ]),
123
+ };
124
+ }
125
+ return {
126
+ status,
127
+ state: "stale",
128
+ ageMs,
129
+ detail: joinDetail([
130
+ input.context,
131
+ `no ${input.activity} in ${formatFreshnessAge(ageMs)} — last ${input.unit} ${timestamp}`,
132
+ input.provenance,
133
+ `fix: ${input.remediation}`,
134
+ ]),
135
+ };
136
+ }
137
+ /**
138
+ * Turn a single observation into a status + actionable detail.
139
+ *
140
+ * The only path that can return `pass` is an observed activity timestamp
141
+ * inside the warn threshold. Everything else — no activity, unreadable store,
142
+ * skewed clock — is surfaced, never swallowed.
143
+ */
144
+ function evaluateFreshness(input) {
145
+ const observation = input.observation;
146
+ if (observation.kind === "unknown") {
147
+ return {
148
+ status: "fail",
149
+ state: "unknown",
150
+ ageMs: null,
151
+ detail: joinDetail([
152
+ input.context,
153
+ `${input.activity}: last-activity time could not be determined — ${observation.reason}; unverified, not healthy`,
154
+ input.provenance,
155
+ `fix: ${input.remediation}`,
156
+ ]),
157
+ };
158
+ }
159
+ if (observation.kind === "none") {
160
+ const { status, configuredForMs } = statusForNever(input);
161
+ return {
162
+ status,
163
+ state: "never",
164
+ ageMs: null,
165
+ detail: joinDetail([
166
+ input.context,
167
+ configuredForMs === null
168
+ ? `no ${input.activity} ever — the store is readable and empty`
169
+ : `no ${input.activity} ever — the store is readable and empty, and this pipe has been configured for ${formatFreshnessAge(configuredForMs)}`,
170
+ input.provenance,
171
+ `fix: ${input.remediation}`,
172
+ ]),
173
+ };
174
+ }
175
+ if (!Number.isFinite(observation.atMs)) {
176
+ return evaluateFreshness({
177
+ ...input,
178
+ observation: { kind: "unknown", reason: `observed timestamp is not a finite epoch-ms value (${String(observation.atMs)})` },
179
+ });
180
+ }
181
+ return evaluateActivity(input, observation.atMs);
182
+ }
183
+ /**
184
+ * Last-write probe for **create-per-event** stores — one new file per event,
185
+ * such as the mailroom's `messages/<id>.json`.
186
+ *
187
+ * A directory's mtime advances whenever an entry is created or removed, so it
188
+ * is an exact answer to "when was a file last added here" for O(1) cost, with
189
+ * no per-entry stat. That matters: the production mailroom holds ~45k message
190
+ * files and must never be stat-walked by a health check.
191
+ *
192
+ * It is also the semantically *correct* signal here. A message's `receivedAt`
193
+ * is when the mail was sent, not when this machine ingested it — an mbox
194
+ * backfill writes month-old `receivedAt` values today — so parsing message
195
+ * bodies would answer a different question than "is the pipe moving?".
196
+ *
197
+ * `hasEntries` is supplied by the caller (which typically already lists the
198
+ * directory for a count) so an empty directory reports `none` rather than
199
+ * reporting its own creation time as activity.
200
+ */
201
+ function observeCreatePerEventStore(dir, deps, options) {
202
+ const provenance = `derived from ${dir} directory mtime (O(1), no per-entry scan)`;
203
+ if (!deps.existsSync(dir)) {
204
+ return { observation: { kind: "none" }, provenance: `${dir} does not exist` };
205
+ }
206
+ if (!options.hasEntries) {
207
+ return { observation: { kind: "none" }, provenance: `${dir} is empty` };
208
+ }
209
+ try {
210
+ return { observation: { kind: "activity", atMs: deps.statSync(dir).mtimeMs }, provenance };
211
+ }
212
+ catch (error) {
213
+ return {
214
+ observation: { kind: "unknown", reason: `${dir} could not be stat'd: ${error instanceof Error ? error.message : String(error)}` },
215
+ provenance,
216
+ };
217
+ }
218
+ }
219
+ /**
220
+ * Last-observation probe for a **local mirror of a remote store** — the cache
221
+ * this machine writes as it reads a store that lives somewhere else, such as
222
+ * the hosted Mailroom's `state/mail-search/<messageId>.json` documents.
223
+ *
224
+ * Mechanically this is `observeCreatePerEventStore`: one file per event, named
225
+ * by a content-addressed id, so the directory mtime answers "when did this
226
+ * machine last record something it had never seen before" for O(1) cost.
227
+ *
228
+ * One rule differs, and it is the entire reason this exists: an absent or empty
229
+ * mirror is `unknown`, never `none`. For a local store the directory *is* the
230
+ * store, so empty means "nothing was ever delivered". For a mirror the
231
+ * authoritative store is remote and deliberately not read here — a health check
232
+ * must not need network access or credentials — so empty means only "this
233
+ * machine holds no record". That is absence of evidence, and rendering it as a
234
+ * confident "never delivered" would be the same crying-wolf failure as reading
235
+ * a local directory that nothing writes to any more.
236
+ */
237
+ function observeMirroredStore(dir, deps, options) {
238
+ const provenanceReadNote = options.authorityReadNote ?? "which doctor does not read";
239
+ const unknownReadNote = options.authorityReadNote ?? "is not read by doctor (no network calls, no credentials)";
240
+ const provenance = `derived from the local mirror at ${dir} (directory mtime, O(1), no per-entry scan); the authoritative store is ${options.remote}, ${provenanceReadNote}`;
241
+ const exists = deps.existsSync(dir);
242
+ if (!exists || !options.hasEntries) {
243
+ return {
244
+ observation: {
245
+ kind: "unknown",
246
+ reason: `the local mirror at ${dir} is ${exists ? "empty" : "absent"}, and ${options.remote} ${unknownReadNote}, so recency cannot be measured on this machine`,
247
+ },
248
+ provenance,
249
+ };
250
+ }
251
+ try {
252
+ return { observation: { kind: "activity", atMs: deps.statSync(dir).mtimeMs }, provenance };
253
+ }
254
+ catch (error) {
255
+ return {
256
+ observation: { kind: "unknown", reason: `${dir} could not be stat'd: ${error instanceof Error ? error.message : String(error)}` },
257
+ provenance,
258
+ };
259
+ }
260
+ }
261
+ /**
262
+ * Last-write probe for **append-per-event** stores — a small set of long-lived
263
+ * logs appended in place, such as the BlueBubbles inbound ndjson (one file per
264
+ * chat).
265
+ *
266
+ * Directory mtime is the wrong signal here: appending to an existing file does
267
+ * not touch its parent directory, so a busy-but-not-growing log set would look
268
+ * frozen. This stats each matching entry and takes the newest.
269
+ *
270
+ * The scan is bounded by `maxEntries`. When the bound is hit the provenance
271
+ * says so explicitly — a bounded scan must never masquerade as exhaustive.
272
+ */
273
+ function observeAppendPerEventStore(dir, deps, options) {
274
+ if (!deps.existsSync(dir)) {
275
+ return { observation: { kind: "none" }, provenance: `${dir} does not exist` };
276
+ }
277
+ let entries;
278
+ try {
279
+ entries = deps.readdirSync(dir).filter((name) => name.endsWith(options.suffix));
280
+ }
281
+ catch (error) {
282
+ return {
283
+ observation: { kind: "unknown", reason: `${dir} could not be listed: ${error instanceof Error ? error.message : String(error)}` },
284
+ provenance: `attempted directory listing of ${dir}`,
285
+ };
286
+ }
287
+ if (entries.length === 0) {
288
+ return { observation: { kind: "none" }, provenance: `${dir} holds no ${options.suffix} logs` };
289
+ }
290
+ const scanned = entries.slice(0, options.maxEntries);
291
+ const truncated = entries.length > scanned.length;
292
+ const provenance = truncated
293
+ ? `newest mtime across the first ${scanned.length} of ${entries.length} ${options.suffix} logs in ${dir} — scan bounded, newer activity may exist in the unscanned ${entries.length - scanned.length}`
294
+ : `newest mtime across ${scanned.length} ${options.suffix} log${scanned.length === 1 ? "" : "s"} in ${dir}`;
295
+ let newest = Number.NEGATIVE_INFINITY;
296
+ const failures = [];
297
+ for (const name of scanned) {
298
+ try {
299
+ const mtimeMs = deps.statSync(`${dir}/${name}`).mtimeMs;
300
+ if (mtimeMs > newest)
301
+ newest = mtimeMs;
302
+ }
303
+ catch (error) {
304
+ failures.push(`${name}: ${error instanceof Error ? error.message : String(error)}`);
305
+ }
306
+ }
307
+ if (newest === Number.NEGATIVE_INFINITY) {
308
+ return {
309
+ observation: { kind: "unknown", reason: `none of the ${scanned.length} log(s) in ${dir} could be stat'd: ${failures.slice(0, 3).join("; ")}` },
310
+ provenance,
311
+ };
312
+ }
313
+ return {
314
+ observation: { kind: "activity", atMs: newest },
315
+ provenance: failures.length > 0 ? `${provenance} (${failures.length} unreadable and skipped)` : provenance,
316
+ };
317
+ }
318
+ /**
319
+ * Merge an `agent.json` override onto in-repo defaults.
320
+ *
321
+ * Configuration lives in a committed config file rather than an environment
322
+ * variable, per the repo configuration policy. Non-positive and non-finite
323
+ * values are ignored so a malformed override can never disable the check.
324
+ */
325
+ function resolveFreshnessThresholds(defaults, override) {
326
+ const record = override && typeof override === "object" && !Array.isArray(override)
327
+ ? override
328
+ : null;
329
+ const hours = (key) => {
330
+ const value = record?.[key];
331
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value * exports.FRESHNESS_HOUR_MS : null;
332
+ };
333
+ return {
334
+ warnAfterMs: hours("warnAfterHours") ?? defaults.warnAfterMs,
335
+ failAfterMs: hours("failAfterHours") ?? defaults.failAfterMs,
336
+ };
337
+ }
338
+ /* v8 ignore start -- module load observability event */
339
+ (0, runtime_1.emitNervesEvent)({
340
+ component: "daemon",
341
+ event: "daemon.pipeline_freshness_loaded",
342
+ message: "pipeline freshness primitive loaded",
343
+ meta: {},
344
+ });
345
+ /* v8 ignore stop */
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildHabitPrivateWakeCommand = buildHabitPrivateWakeCommand;
4
+ exports.habitMessageFromPrivateWakeCommand = habitMessageFromPrivateWakeCommand;
5
+ const flight_recorder_1 = require("../../arc/flight-recorder");
6
+ const runtime_1 = require("../../nerves/runtime");
7
+ function buildHabitPrivateWakeCommand(options) {
8
+ const firedAt = (options.now ?? (() => new Date()))().toISOString();
9
+ const occurrenceId = options.occurrenceId ?? firedAt;
10
+ const triggerSource = `habit-${options.trigger}`;
11
+ (0, runtime_1.emitNervesEvent)({
12
+ component: "daemon",
13
+ event: "daemon.habit_private_wake_built",
14
+ message: "built habit private-runtime wake command",
15
+ meta: {
16
+ agent: options.agent,
17
+ habitName: options.habitName,
18
+ trigger: options.trigger,
19
+ triggerSource,
20
+ occurrenceId,
21
+ },
22
+ });
23
+ return {
24
+ kind: "private.wake",
25
+ agent: options.agent,
26
+ reason: `habit ${options.habitName} fired by ${options.trigger}`,
27
+ triggerSource,
28
+ budgetClass: "scheduled",
29
+ idempotencyKey: `habit:${options.agent}:${options.habitName}:${options.trigger}:${occurrenceId}`,
30
+ originRefs: [
31
+ { kind: "habit", id: options.habitName },
32
+ { kind: "habit-trigger", id: options.trigger },
33
+ { kind: "habit-occurrence", id: occurrenceId },
34
+ options.sourceRef,
35
+ ...(options.noSend ? [{ kind: "capability", id: "no-send" }] : []),
36
+ ],
37
+ ...(options.noSend ? { noSend: true } : {}),
38
+ };
39
+ }
40
+ function habitMessageFromPrivateWakeCommand(command) {
41
+ if (command.kind !== "private.wake")
42
+ return null;
43
+ if (typeof command.triggerSource !== "string" || !command.triggerSource.startsWith("habit-"))
44
+ return null;
45
+ const habitRef = command.originRefs?.find((ref) => ref.kind === "habit" && typeof ref.id === "string");
46
+ const triggerRef = command.originRefs?.find((ref) => ref.kind === "habit-trigger" && typeof ref.id === "string");
47
+ const noSendRef = command.originRefs?.some((ref) => ref.kind === "capability" && ref.id === "no-send") ?? false;
48
+ if (!habitRef || typeof habitRef.id !== "string" || !triggerRef || typeof triggerRef.id !== "string")
49
+ return null;
50
+ if ((command.noSend === true) !== noSendRef)
51
+ return null;
52
+ const habitName = habitRef.id.trim();
53
+ const trigger = triggerRef.id.trim();
54
+ if (habitName.length === 0)
55
+ return null;
56
+ if (!(0, flight_recorder_1.isHabitRunTrigger)(trigger))
57
+ return null;
58
+ if (command.triggerSource !== `habit-${trigger}`)
59
+ return null;
60
+ return { habitName, trigger, ...(noSendRef ? { noSend: true } : {}) };
61
+ }
@@ -7,37 +7,124 @@ class HealthMonitor {
7
7
  scheduler;
8
8
  alertSink;
9
9
  diskUsagePercent;
10
+ sentinelChecker;
11
+ onCriticalAgent;
12
+ onCriticalSense;
13
+ senseProbes;
14
+ senseProbeProvider;
15
+ intervalHandle = null;
16
+ lastResults = [];
10
17
  constructor(options) {
11
18
  this.processManager = options.processManager;
12
19
  this.scheduler = options.scheduler;
13
20
  this.alertSink = options.alertSink ?? (() => undefined);
14
21
  this.diskUsagePercent = options.diskUsagePercent ?? (() => 0);
22
+ this.sentinelChecker = options.sentinelChecker ?? (() => []);
23
+ this.onCriticalAgent = options.onCriticalAgent ?? (() => undefined);
24
+ this.onCriticalSense = options.onCriticalSense ?? (() => undefined);
25
+ this.senseProbes = options.senseProbes ?? [];
26
+ this.senseProbeProvider = options.senseProbeProvider ?? (() => []);
27
+ }
28
+ triggerSenseRecovery(probe, detail) {
29
+ if (!probe.managedName)
30
+ return;
31
+ try {
32
+ (0, runtime_1.emitNervesEvent)({
33
+ level: "warn",
34
+ component: "daemon",
35
+ event: "daemon.health_check_sense_recovery_attempted",
36
+ message: "triggering recovery restart for failed sense probe",
37
+ meta: {
38
+ probeName: probe.name,
39
+ managedName: probe.managedName,
40
+ detail,
41
+ },
42
+ });
43
+ this.onCriticalSense(probe.managedName, probe.name);
44
+ }
45
+ catch {
46
+ // Recovery is best-effort -- callback errors must not crash runChecks
47
+ }
48
+ }
49
+ startPeriodicChecks(intervalMs) {
50
+ if (this.intervalHandle !== null)
51
+ return;
52
+ (0, runtime_1.emitNervesEvent)({
53
+ level: "info",
54
+ component: "daemon",
55
+ event: "daemon.health_check_scheduled",
56
+ message: "periodic health checks started",
57
+ meta: { intervalMs },
58
+ });
59
+ this.intervalHandle = setInterval(() => {
60
+ void this.runChecks();
61
+ }, intervalMs);
62
+ }
63
+ stopPeriodicChecks() {
64
+ if (this.intervalHandle === null)
65
+ return;
66
+ clearInterval(this.intervalHandle);
67
+ this.intervalHandle = null;
15
68
  }
16
69
  async runChecks() {
17
70
  const results = [];
18
71
  const snapshots = this.processManager.listAgentSnapshots();
19
- const unhealthy = snapshots.filter((snapshot) => snapshot.status !== "running");
72
+ const unhealthy = snapshots.filter((snapshot) => snapshot.status !== "running" && snapshot.autoStart !== false);
73
+ const parked = snapshots.filter((snapshot) => snapshot.status !== "running" && snapshot.autoStart === false);
20
74
  if (unhealthy.length > 0) {
75
+ const unhealthySummary = unhealthy.map((item) => {
76
+ const detail = [
77
+ item.errorReason ?? null,
78
+ item.fixHint ? `fix: ${item.fixHint}` : null,
79
+ ].filter((part) => part !== null).join("; ");
80
+ return detail.length > 0 ? `${item.name} (${detail})` : item.name;
81
+ }).join(", ");
21
82
  results.push({
22
83
  name: "agent-processes",
23
84
  status: "critical",
24
- message: `non-running agents: ${unhealthy.map((item) => item.name).join(", ")}`,
85
+ message: `non-running agents: ${unhealthySummary}`,
25
86
  });
87
+ for (const agent of unhealthy) {
88
+ try {
89
+ (0, runtime_1.emitNervesEvent)({
90
+ level: "warn",
91
+ component: "daemon",
92
+ event: "daemon.health_check_recovery_attempted",
93
+ message: "triggering recovery restart for non-running agent",
94
+ meta: {
95
+ agentName: agent.name,
96
+ agentStatus: agent.status,
97
+ errorReason: agent.errorReason ?? null,
98
+ fixHint: agent.fixHint ?? null,
99
+ },
100
+ });
101
+ this.onCriticalAgent(agent.name);
102
+ }
103
+ catch {
104
+ // Recovery is best-effort -- callback errors must not crash runChecks
105
+ }
106
+ }
26
107
  }
27
108
  else {
28
- results.push({ name: "agent-processes", status: "ok", message: "all managed agents running" });
109
+ const message = parked.length > 0
110
+ ? `all auto-start managed agents running; parked agents: ${parked.map((item) => item.name).join(", ")}`
111
+ : "all managed agents running";
112
+ results.push({ name: "agent-processes", status: "ok", message });
29
113
  }
30
114
  const jobs = this.scheduler.listJobs();
31
- const neverRan = jobs.filter((job) => !job.lastRun);
32
- if (neverRan.length > 0) {
33
- results.push({
34
- name: "cron-health",
35
- status: "warn",
36
- message: `jobs never run: ${neverRan.map((job) => job.id).join(", ")}`,
37
- });
115
+ const degradedJobs = this.scheduler.listDegradedJobs?.() ?? [];
116
+ if (degradedJobs.length > 0) {
117
+ const degradedSummary = degradedJobs
118
+ .map((job) => `${job.id} (${job.reason})`)
119
+ .join(", ");
120
+ results.push({ name: "cron-health", status: "warn", message: `cron jobs degraded; timer fallback active: ${degradedSummary}` });
38
121
  }
39
122
  else {
40
- results.push({ name: "cron-health", status: "ok", message: "cron jobs are healthy" });
123
+ const neverRan = jobs.filter((job) => !job.lastRun);
124
+ const firstRunSuffix = neverRan.length > 0
125
+ ? `; pending first run: ${neverRan.map((job) => job.id).join(", ")}`
126
+ : "";
127
+ results.push({ name: "cron-health", status: "ok", message: `cron jobs are healthy${firstRunSuffix}` });
41
128
  }
42
129
  const diskPercent = this.diskUsagePercent();
43
130
  if (diskPercent >= 90) {
@@ -61,6 +148,47 @@ class HealthMonitor {
61
148
  message: `disk usage healthy (${diskPercent}%)`,
62
149
  });
63
150
  }
151
+ const senseProbes = [...this.senseProbes];
152
+ try {
153
+ senseProbes.push(...this.senseProbeProvider());
154
+ }
155
+ catch (error) {
156
+ results.push({
157
+ name: "sense-probes",
158
+ status: "warn",
159
+ message: `sense probe discovery failed: ${error instanceof Error ? error.message : String(error)}`,
160
+ });
161
+ }
162
+ for (const probe of senseProbes) {
163
+ try {
164
+ const outcome = await probe.check();
165
+ if (outcome.ok) {
166
+ results.push({
167
+ name: `sense-probe:${probe.name}`,
168
+ status: "ok",
169
+ message: `${probe.name} healthy`,
170
+ });
171
+ }
172
+ else {
173
+ this.triggerSenseRecovery(probe, outcome.detail ?? "unknown");
174
+ results.push({
175
+ name: `sense-probe:${probe.name}`,
176
+ status: "critical",
177
+ message: `${probe.name} failed: ${outcome.detail ?? "unknown"}`,
178
+ });
179
+ }
180
+ }
181
+ catch (error) {
182
+ this.triggerSenseRecovery(probe, error instanceof Error ? error.message : String(error));
183
+ results.push({
184
+ name: `sense-probe:${probe.name}`,
185
+ status: "critical",
186
+ message: `${probe.name} error: ${error instanceof Error ? error.message : String(error)}`,
187
+ });
188
+ }
189
+ }
190
+ results.push(...await this.sentinelChecker(results.map((result) => ({ ...result }))));
191
+ this.lastResults = results.map((result) => ({ ...result }));
64
192
  for (const result of results) {
65
193
  (0, runtime_1.emitNervesEvent)({
66
194
  level: result.status === "critical" ? "error" : result.status === "warn" ? "warn" : "info",
@@ -75,5 +203,8 @@ class HealthMonitor {
75
203
  }
76
204
  return results;
77
205
  }
206
+ getLastResults() {
207
+ return this.lastResults.map((result) => ({ ...result }));
208
+ }
78
209
  }
79
210
  exports.HealthMonitor = HealthMonitor;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agentConfigV2Hook = agentConfigV2Hook;
4
+ const runtime_1 = require("../../../nerves/runtime");
5
+ const migrate_config_1 = require("../../migrate-config");
6
+ async function agentConfigV2Hook(ctx) {
7
+ (0, runtime_1.emitNervesEvent)({
8
+ component: "daemon",
9
+ event: "daemon.agent_config_v2_hook_start",
10
+ message: "running agent-config-v2 update hook",
11
+ meta: { agentRoot: ctx.agentRoot, currentVersion: ctx.currentVersion },
12
+ });
13
+ try {
14
+ (0, migrate_config_1.migrateAgentConfigV1ToV2)(ctx.agentRoot);
15
+ }
16
+ catch (err) {
17
+ const errorMessage = err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err);
18
+ (0, runtime_1.emitNervesEvent)({
19
+ component: "daemon",
20
+ event: "daemon.agent_config_v2_hook_error",
21
+ message: "agent-config-v2 hook migration failed",
22
+ meta: { agentRoot: ctx.agentRoot, error: errorMessage },
23
+ });
24
+ return { ok: false, error: errorMessage };
25
+ }
26
+ (0, runtime_1.emitNervesEvent)({
27
+ component: "daemon",
28
+ event: "daemon.agent_config_v2_hook_end",
29
+ message: "agent-config-v2 hook completed",
30
+ meta: { agentRoot: ctx.agentRoot },
31
+ });
32
+ return { ok: true };
33
+ }