@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,511 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getPulsePath = getPulsePath;
37
+ exports.getPulseDeliveredPath = getPulseDeliveredPath;
38
+ exports.buildAlertId = buildAlertId;
39
+ exports.readAgentActivity = readAgentActivity;
40
+ exports.buildPulseState = buildPulseState;
41
+ exports.findNovelBrokenAgents = findNovelBrokenAgents;
42
+ exports.findRecoveredAgents = findRecoveredAgents;
43
+ exports.buildRecoveryAlertId = buildRecoveryAlertId;
44
+ exports.buildPulsePrivateWakeRequest = buildPulsePrivateWakeRequest;
45
+ exports.pickWakeRecipient = pickWakeRecipient;
46
+ exports.writePulse = writePulse;
47
+ exports.readPulse = readPulse;
48
+ exports.readDeliveredState = readDeliveredState;
49
+ exports.writeDeliveredState = writeDeliveredState;
50
+ exports.pruneDeliveredState = pruneDeliveredState;
51
+ exports.flushPulse = flushPulse;
52
+ const fs = __importStar(require("fs"));
53
+ const os = __importStar(require("os"));
54
+ const path = __importStar(require("path"));
55
+ const runtime_1 = require("../../nerves/runtime");
56
+ const provider_visibility_1 = require("../provider-visibility");
57
+ /* v8 ignore next 3 -- path defaults: tests always inject @preserve */
58
+ function defaultPulsePath() {
59
+ return path.join(os.homedir(), ".ouro-cli", "pulse.json");
60
+ }
61
+ /* v8 ignore next 3 -- path defaults: tests always inject @preserve */
62
+ function defaultDeliveredPath() {
63
+ return path.join(os.homedir(), ".ouro-cli", "pulse-delivered.json");
64
+ }
65
+ function getPulsePath() {
66
+ return defaultPulsePath();
67
+ }
68
+ function getPulseDeliveredPath() {
69
+ return defaultDeliveredPath();
70
+ }
71
+ /**
72
+ * Hash an error reason into a short stable identifier. We use a simple
73
+ * non-cryptographic hash because we only need stability across daemon
74
+ * restarts on the same machine, not collision resistance against
75
+ * adversaries. djb2 is fine.
76
+ */
77
+ function hashErrorReason(reason) {
78
+ let h = 5381;
79
+ for (let i = 0; i < reason.length; i++) {
80
+ h = ((h << 5) + h + reason.charCodeAt(i)) >>> 0;
81
+ }
82
+ return h.toString(16);
83
+ }
84
+ /**
85
+ * Build a stable alert ID for a (agent, error) pair. Same agent + same
86
+ * error → same ID, even across daemon restarts. Different error → new ID.
87
+ */
88
+ function buildAlertId(agent, errorReason) {
89
+ return `${agent}:${hashErrorReason(errorReason)}`;
90
+ }
91
+ /**
92
+ * Read an agent's private-runtime state and format it as a short
93
+ * activity hint string suitable for display in another agent's pulse
94
+ * section. Returns null when the file is missing or malformed — both
95
+ * cases are silent (the pulse just doesn't include activity for that
96
+ * agent).
97
+ *
98
+ * Pure: takes a file reader so tests can inject content without touching
99
+ * fs. Defaults to fs.readFileSync for the production daemon caller.
100
+ */
101
+ function readAgentActivity(bundlePath, readFile = (p) => fs.readFileSync(p, "utf-8")) {
102
+ const runtimePath = path.join(bundlePath, "state", "sessions", "self", "inner", "runtime.json");
103
+ let raw;
104
+ try {
105
+ raw = readFile(runtimePath);
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ let parsed;
111
+ try {
112
+ parsed = JSON.parse(raw);
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ const status = typeof parsed.status === "string" ? parsed.status : null;
118
+ const reason = typeof parsed.reason === "string" ? parsed.reason : null;
119
+ const startedAt = typeof parsed.startedAt === "string" ? parsed.startedAt : null;
120
+ if (!status)
121
+ return null;
122
+ // Format compactly. Examples:
123
+ // "running (instinct since 23:44)"
124
+ // "idle since 21:30"
125
+ // "running"
126
+ const sinceStr = startedAt ? ` since ${startedAt.slice(11, 16)}` : "";
127
+ if (status === "running" && reason) {
128
+ return `running (${reason}${sinceStr})`;
129
+ }
130
+ return `${status}${sinceStr}`;
131
+ }
132
+ /**
133
+ * Convert daemon process-manager snapshots into the pulse state shape.
134
+ * Pure: no fs side effects (activity reading goes through the injected
135
+ * `readActivity` callback so tests can pin everything).
136
+ *
137
+ * The bundlePath comes from the bundlesRoot — we don't read the bundle
138
+ * directly, we just compute where it lives so sibling agents have a
139
+ * starting point if they want to navigate there manually.
140
+ */
141
+ function buildPulseState(snapshots, bundlesRoot, daemonVersion, now, readActivity = readAgentActivity, readProviderVisibility = () => null) {
142
+ const agents = snapshots.map((snap) => {
143
+ const errorReason = snap.errorReason;
144
+ const bundlePath = path.join(bundlesRoot, `${snap.name}.ouro`);
145
+ return {
146
+ name: snap.name,
147
+ bundlePath,
148
+ status: snap.status,
149
+ lastSeenAt: snap.startedAt,
150
+ errorReason,
151
+ fixHint: snap.fixHint,
152
+ alertId: errorReason ? buildAlertId(snap.name, errorReason) : null,
153
+ // Only read activity for agents that are actually running. For
154
+ // crashed/stopped agents, the runtime.json is stale at best.
155
+ currentActivity: snap.status === "running" ? readActivity(bundlePath) : null,
156
+ providerVisibility: readProviderVisibility(snap.name, bundlePath),
157
+ };
158
+ });
159
+ return {
160
+ generatedAt: now.toISOString(),
161
+ daemonVersion,
162
+ agents,
163
+ };
164
+ }
165
+ /**
166
+ * A "novel broken transition" is an agent that is currently broken AND
167
+ * either (a) wasn't broken in the previous pulse state, OR (b) was broken
168
+ * but with a different alertId. Used to decide when to queue a proactive
169
+ * pulse wake.
170
+ *
171
+ * Pure: takes prev and next states, returns the list of newly-broken
172
+ * agents that warrant a wake.
173
+ */
174
+ function findNovelBrokenAgents(prev, next) {
175
+ const novel = [];
176
+ for (const agent of next.agents) {
177
+ if (!agent.alertId)
178
+ continue;
179
+ const prevAgent = prev?.agents.find((a) => a.name === agent.name);
180
+ const wasBrokenWithSameAlert = prevAgent?.alertId === agent.alertId;
181
+ if (wasBrokenWithSameAlert)
182
+ continue;
183
+ novel.push(agent);
184
+ }
185
+ return novel;
186
+ }
187
+ /**
188
+ * A "recovery transition" is an agent that was broken in the previous
189
+ * pulse state but is healthy now. The pulse fires a wake on these too,
190
+ * so the user gets a positive notification when their fix takes effect.
191
+ *
192
+ * Pure: takes prev and next states, returns the list of newly-recovered
193
+ * agents that warrant a wake.
194
+ */
195
+ function findRecoveredAgents(prev, next) {
196
+ if (!prev)
197
+ return [];
198
+ const recovered = [];
199
+ for (const agent of next.agents) {
200
+ // Healthy in next.
201
+ if (agent.alertId !== null)
202
+ continue;
203
+ if (agent.status !== "running")
204
+ continue;
205
+ // Was broken in prev.
206
+ const prevAgent = prev.agents.find((a) => a.name === agent.name);
207
+ if (!prevAgent || prevAgent.alertId === null)
208
+ continue;
209
+ recovered.push(agent);
210
+ }
211
+ return recovered;
212
+ }
213
+ /**
214
+ * Build a stable alert ID for a recovery event. Used so the recovery
215
+ * wake is also at-most-once (no re-paging on every snapshot change after
216
+ * recovery). Includes the recovery timestamp so a later break+heal cycle
217
+ * generates a fresh ID.
218
+ */
219
+ function buildRecoveryAlertId(agent, recoveredAt) {
220
+ return `recovery:${agent}:${recoveredAt}`;
221
+ }
222
+ function buildPulsePrivateWakeRequest(options) {
223
+ const prefix = options.triggerSource === "pulse-alert" ? "pulse alert" : "pulse recovery";
224
+ const detail = options.subject.errorReason ? `: ${options.subject.errorReason}` : "";
225
+ const originKind = options.triggerSource === "pulse-alert" ? "pulse-alert" : "pulse-recovery";
226
+ return {
227
+ agent: options.recipient,
228
+ reason: `${prefix} for ${options.subject.name}${detail}`,
229
+ triggerSource: options.triggerSource,
230
+ budgetClass: "scheduled",
231
+ idempotencyKey: `pulse:${options.recipient}:${options.alertId}`,
232
+ originRefs: [
233
+ { kind: originKind, id: options.alertId },
234
+ { kind: "agent", id: options.subject.name },
235
+ ],
236
+ };
237
+ }
238
+ /**
239
+ * Pick which agent should receive a pulse wake for a fleet alert. Heuristic:
240
+ * the most-recently-active running agent (by `lastSeenAt`), excluding the
241
+ * broken agent itself and any agents that aren't currently running. Returns
242
+ * null if there's no eligible recipient (e.g., the only other agent on the
243
+ * machine is also broken).
244
+ *
245
+ * Pure: takes the pulse state and the alert target, returns the chosen
246
+ * recipient name or null.
247
+ */
248
+ function pickWakeRecipient(state, brokenAgent) {
249
+ const candidates = state.agents
250
+ .filter((a) => a.name !== brokenAgent)
251
+ .filter((a) => a.status === "running")
252
+ .filter((a) => a.lastSeenAt !== null)
253
+ .sort((a, b) => {
254
+ // Most-recent first. lastSeenAt is non-null per the filter above.
255
+ const aMs = Date.parse(a.lastSeenAt);
256
+ const bMs = Date.parse(b.lastSeenAt);
257
+ return bMs - aMs;
258
+ });
259
+ return candidates[0]?.name ?? null;
260
+ }
261
+ /**
262
+ * Write the pulse state to disk. Best-effort: if the write fails, emit a
263
+ * nerves event but do not throw. The pulse is a notification mechanism;
264
+ * the daemon's primary work should not be blocked by it.
265
+ */
266
+ function writePulse(state, deps = {}) {
267
+ /* v8 ignore start -- dep defaults: production-only paths; tests inject all four explicitly @preserve */
268
+ const filePath = deps.pulsePath ?? defaultPulsePath();
269
+ const writeFile = deps.writeFile ?? ((p, c) => fs.writeFileSync(p, c, "utf-8"));
270
+ const mkdirp = deps.mkdirp ?? ((d) => fs.mkdirSync(d, { recursive: true }));
271
+ /* v8 ignore stop */
272
+ try {
273
+ mkdirp(path.dirname(filePath));
274
+ writeFile(filePath, JSON.stringify(state, null, 2) + "\n");
275
+ (0, runtime_1.emitNervesEvent)({
276
+ component: "daemon",
277
+ event: "daemon.pulse_written",
278
+ message: "wrote machine pulse state",
279
+ meta: { filePath, agentCount: state.agents.length },
280
+ });
281
+ }
282
+ catch (error) {
283
+ (0, runtime_1.emitNervesEvent)({
284
+ level: "warn",
285
+ component: "daemon",
286
+ event: "daemon.pulse_write_error",
287
+ message: "failed to write pulse state",
288
+ meta: {
289
+ filePath,
290
+ error: error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error),
291
+ },
292
+ });
293
+ }
294
+ }
295
+ /**
296
+ * Read the pulse state from disk. Returns null if the file doesn't exist
297
+ * or is malformed — pulse readers (like the prompt assembler) should
298
+ * gracefully degrade to "no pulse, render nothing" rather than crash.
299
+ */
300
+ function readPulse(deps = {}) {
301
+ const filePath = deps.pulsePath ?? defaultPulsePath();
302
+ /* v8 ignore next -- dep default: tests always inject @preserve */
303
+ const readFile = deps.readFile ?? ((p) => fs.readFileSync(p, "utf-8"));
304
+ try {
305
+ const raw = readFile(filePath);
306
+ const parsed = JSON.parse(raw);
307
+ if (typeof parsed.generatedAt !== "string")
308
+ return null;
309
+ if (typeof parsed.daemonVersion !== "string")
310
+ return null;
311
+ if (!Array.isArray(parsed.agents))
312
+ return null;
313
+ return {
314
+ generatedAt: parsed.generatedAt,
315
+ daemonVersion: parsed.daemonVersion,
316
+ agents: parsed.agents.filter(isValidPulseAgentEntry).map((agent) => {
317
+ const rawAgent = agent;
318
+ if (!Object.prototype.hasOwnProperty.call(rawAgent, "providerVisibility"))
319
+ return agent;
320
+ return {
321
+ ...agent,
322
+ providerVisibility: (0, provider_visibility_1.isAgentProviderVisibility)(rawAgent.providerVisibility)
323
+ ? rawAgent.providerVisibility
324
+ : null,
325
+ };
326
+ }),
327
+ };
328
+ }
329
+ catch {
330
+ return null;
331
+ }
332
+ }
333
+ function isValidPulseAgentEntry(value) {
334
+ if (value === null || typeof value !== "object")
335
+ return false;
336
+ const v = value;
337
+ return (typeof v.name === "string"
338
+ && typeof v.bundlePath === "string"
339
+ && (v.status === "running" || v.status === "starting" || v.status === "stopped" || v.status === "crashed")
340
+ && (v.lastSeenAt === null || typeof v.lastSeenAt === "string")
341
+ && (v.errorReason === null || typeof v.errorReason === "string")
342
+ && (v.fixHint === null || typeof v.fixHint === "string")
343
+ && (v.alertId === null || typeof v.alertId === "string"));
344
+ }
345
+ /**
346
+ * Read the persistent delivered-alerts state. Returns an empty set if the
347
+ * file doesn't exist or is malformed.
348
+ */
349
+ function readDeliveredState(deps = {}) {
350
+ /* v8 ignore start -- dep defaults: production-only paths; tests inject all explicitly @preserve */
351
+ const filePath = deps.deliveredPath ?? defaultDeliveredPath();
352
+ const readFile = deps.readFile ?? ((p) => fs.readFileSync(p, "utf-8"));
353
+ /* v8 ignore stop */
354
+ try {
355
+ const raw = readFile(filePath);
356
+ const parsed = JSON.parse(raw);
357
+ if (!Array.isArray(parsed.delivered))
358
+ return new Set();
359
+ return new Set(parsed.delivered.filter((id) => typeof id === "string"));
360
+ }
361
+ catch {
362
+ return new Set();
363
+ }
364
+ }
365
+ /**
366
+ * Persist the delivered-alerts state to disk. Best-effort.
367
+ */
368
+ function writeDeliveredState(delivered, deps = {}) {
369
+ /* v8 ignore start -- dep defaults: production-only paths; tests inject all four explicitly @preserve */
370
+ const filePath = deps.deliveredPath ?? defaultDeliveredPath();
371
+ const writeFile = deps.writeFile ?? ((p, c) => fs.writeFileSync(p, c, "utf-8"));
372
+ const mkdirp = deps.mkdirp ?? ((d) => fs.mkdirSync(d, { recursive: true }));
373
+ /* v8 ignore stop */
374
+ try {
375
+ mkdirp(path.dirname(filePath));
376
+ const state = { delivered: [...delivered].sort() };
377
+ writeFile(filePath, JSON.stringify(state, null, 2) + "\n");
378
+ }
379
+ catch (error) {
380
+ (0, runtime_1.emitNervesEvent)({
381
+ level: "warn",
382
+ component: "daemon",
383
+ event: "daemon.pulse_delivered_write_error",
384
+ message: "failed to write pulse delivered state",
385
+ meta: {
386
+ filePath,
387
+ error: error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error),
388
+ },
389
+ });
390
+ }
391
+ }
392
+ /**
393
+ * Prune delivered alert IDs that no longer correspond to an active broken
394
+ * agent. When the user fixes ouroboros's config, the next pulse state has
395
+ * no alertId for ouroboros, so we drop the old delivered entry — meaning
396
+ * if ouroboros breaks AGAIN later (with the same error), we re-page.
397
+ */
398
+ function pruneDeliveredState(delivered, state) {
399
+ const liveAlertIds = new Set();
400
+ for (const agent of state.agents) {
401
+ if (agent.alertId)
402
+ liveAlertIds.add(agent.alertId);
403
+ }
404
+ const pruned = new Set();
405
+ for (const id of delivered) {
406
+ if (liveAlertIds.has(id))
407
+ pruned.add(id);
408
+ }
409
+ return pruned;
410
+ }
411
+ /**
412
+ * Single entry point the daemon's onSnapshotChange callback uses. Builds
413
+ * the new pulse state, diffs against the previous, writes the file, and
414
+ * queues pulse wakes on novel broken transitions for the most-recently-active
415
+ * sibling. Persistent at-most-once delivery via the delivered state file.
416
+ *
417
+ * Pure-ish: all I/O goes through dep callbacks so tests can pin every
418
+ * input and assert every effect. Defaults wire to the real fs functions
419
+ * for production callers.
420
+ */
421
+ function flushPulse(deps) {
422
+ const state = buildPulseState(deps.snapshots, deps.bundlesRoot, deps.daemonVersion, deps.now, readAgentActivity, (agentName, bundlePath) => (0, provider_visibility_1.buildAgentProviderVisibility)({ agentName, agentRoot: bundlePath }));
423
+ /* v8 ignore start -- dep defaults: production daemon path; the arrow functions only fire when the corresponding dep is omitted, which only happens in production code paths. Tests inject all deps explicitly. @preserve */
424
+ const readPrev = deps.readPrev ?? (() => readPulse());
425
+ const writeNext = deps.writeNext ?? ((s) => writePulse(s));
426
+ const readDelivered = deps.readDelivered ?? (() => readDeliveredState());
427
+ const writeDelivered = deps.writeDelivered ?? ((d) => writeDeliveredState(d));
428
+ const fireInnerWake = deps.fireInnerWake ?? null;
429
+ const firePrivateWake = deps.firePrivateWake ?? null;
430
+ /* v8 ignore stop */
431
+ const prev = readPrev();
432
+ let delivered = readDelivered();
433
+ // Write the new pulse state first so any reader (including the
434
+ // wake-recipient agent's prompt assembly on its next turn) sees the
435
+ // current state. Doing this before firing the wake matters: if the
436
+ // wake races against a fast prompt build on the recipient, we want
437
+ // the recipient to read the NEW state, not the old one.
438
+ writeNext(state);
439
+ // Find agents that newly transitioned to broken (or to a different
440
+ // error than before).
441
+ const novelBroken = findNovelBrokenAgents(prev, state);
442
+ // Of those, the ones we haven't already delivered an alert for.
443
+ const undeliveredBroken = novelBroken.filter((a) => a.alertId !== null && !delivered.has(a.alertId));
444
+ // Find agents that newly recovered (were broken in prev, healthy now).
445
+ const recovered = findRecoveredAgents(prev, state);
446
+ // For recovery wakes, build a fresh alert ID per recovery event so
447
+ // we don't re-page on every subsequent flush.
448
+ const recoveryAlertIds = recovered.map((a) => buildRecoveryAlertId(a.name, state.generatedAt));
449
+ const undeliveredRecovered = recovered.filter((_, i) => !delivered.has(recoveryAlertIds[i]));
450
+ // Fire wakes and update the delivered set.
451
+ const wakeFiredFor = [];
452
+ const newlyDelivered = [];
453
+ for (const broken of undeliveredBroken) {
454
+ /* v8 ignore next -- defensive: undeliveredBroken already filtered to non-null alertId; this is a TS narrowing helper @preserve */
455
+ if (broken.alertId === null)
456
+ continue;
457
+ const recipient = pickWakeRecipient(state, broken.name);
458
+ if (recipient !== null && firePrivateWake !== null) {
459
+ firePrivateWake(buildPulsePrivateWakeRequest({
460
+ recipient,
461
+ subject: broken,
462
+ alertId: broken.alertId,
463
+ triggerSource: "pulse-alert",
464
+ }));
465
+ wakeFiredFor.push(recipient);
466
+ }
467
+ else if (recipient !== null && fireInnerWake !== null) {
468
+ fireInnerWake(recipient);
469
+ wakeFiredFor.push(recipient);
470
+ }
471
+ // Mark delivered even if no recipient was available — otherwise
472
+ // the daemon will keep trying to wake every time the snapshot
473
+ // changes, which would spam logs without producing any user value.
474
+ // The passive prompt section still surfaces the broken state to
475
+ // the recipient when they eventually have a turn for any reason.
476
+ delivered.add(broken.alertId);
477
+ newlyDelivered.push(broken.alertId);
478
+ }
479
+ for (let i = 0; i < undeliveredRecovered.length; i++) {
480
+ const recoveredAgent = undeliveredRecovered[i];
481
+ const recoveryAlertId = buildRecoveryAlertId(recoveredAgent.name, state.generatedAt);
482
+ const recipient = pickWakeRecipient(state, recoveredAgent.name);
483
+ if (recipient !== null && firePrivateWake !== null) {
484
+ firePrivateWake(buildPulsePrivateWakeRequest({
485
+ recipient,
486
+ subject: recoveredAgent,
487
+ alertId: recoveryAlertId,
488
+ triggerSource: "pulse-recovery",
489
+ }));
490
+ wakeFiredFor.push(recipient);
491
+ }
492
+ else if (recipient !== null && fireInnerWake !== null) {
493
+ fireInnerWake(recipient);
494
+ wakeFiredFor.push(recipient);
495
+ }
496
+ delivered.add(recoveryAlertId);
497
+ newlyDelivered.push(recoveryAlertId);
498
+ }
499
+ // Drop delivered ids for agents that have healed since (this drops
500
+ // the original `agent_config_failure:...` IDs once the agent recovers,
501
+ // so a future relapse re-pages). Recovery alert IDs are NOT pruned by
502
+ // pruneDeliveredState because they're tied to a healthy state, not a
503
+ // broken state — they live in the delivered set until the same agent
504
+ // breaks and recovers again, at which point a new recovery ID is
505
+ // generated and the old one becomes harmless cruft. We could clean
506
+ // them up too, but the cost is bounded by the number of recovery
507
+ // cycles, which is small.
508
+ delivered = pruneDeliveredState(delivered, state);
509
+ writeDelivered(delivered);
510
+ return { state, wakeFiredFor, newlyDelivered };
511
+ }