@ouro.bot/cli 0.1.0-alpha.65 → 0.1.0-alpha.650

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 (434) hide show
  1. package/README.md +127 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +4151 -14
  13. package/dist/arc/attention-types.js +8 -0
  14. package/dist/arc/cares.js +144 -0
  15. package/dist/arc/episodes.js +118 -0
  16. package/dist/arc/evolution.js +487 -0
  17. package/dist/arc/intentions.js +134 -0
  18. package/dist/arc/json-store.js +117 -0
  19. package/dist/arc/obligations.js +270 -0
  20. package/dist/arc/packets.js +288 -0
  21. package/dist/arc/presence.js +185 -0
  22. package/dist/arc/task-lifecycle.js +57 -0
  23. package/dist/heart/active-work.js +860 -43
  24. package/dist/heart/agent-entry.js +69 -3
  25. package/dist/heart/attachments/image-normalize.js +194 -0
  26. package/dist/heart/attachments/materialize.js +97 -0
  27. package/dist/heart/attachments/originals.js +88 -0
  28. package/dist/heart/attachments/render.js +29 -0
  29. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  30. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  31. package/dist/heart/attachments/sources/index.js +16 -0
  32. package/dist/heart/attachments/store.js +103 -0
  33. package/dist/heart/attachments/types.js +93 -0
  34. package/dist/heart/auth/auth-flow.js +479 -0
  35. package/dist/heart/awaiting/await-alert.js +146 -0
  36. package/dist/heart/awaiting/await-expiry.js +108 -0
  37. package/dist/heart/awaiting/await-loader.js +91 -0
  38. package/dist/heart/awaiting/await-parser.js +141 -0
  39. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  40. package/dist/heart/awaiting/await-scheduler.js +377 -0
  41. package/dist/heart/background-operations.js +281 -0
  42. package/dist/heart/bridges/manager.js +137 -17
  43. package/dist/heart/bridges/store.js +14 -2
  44. package/dist/heart/bundle-state.js +168 -0
  45. package/dist/heart/commitments.js +135 -0
  46. package/dist/heart/config-registry.js +322 -0
  47. package/dist/heart/config.js +118 -119
  48. package/dist/heart/core.js +1123 -247
  49. package/dist/heart/cross-chat-delivery.js +3 -18
  50. package/dist/heart/daemon/agent-config-check.js +419 -0
  51. package/dist/heart/daemon/agent-discovery.js +102 -3
  52. package/dist/heart/daemon/agent-service.js +522 -0
  53. package/dist/heart/daemon/agentic-repair.js +547 -0
  54. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  55. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  56. package/dist/heart/daemon/cadence.js +70 -0
  57. package/dist/heart/daemon/cli-defaults.js +780 -0
  58. package/dist/heart/daemon/cli-desk.js +322 -0
  59. package/dist/heart/daemon/cli-exec.js +7480 -0
  60. package/dist/heart/daemon/cli-help.js +505 -0
  61. package/dist/heart/daemon/cli-parse.js +1554 -0
  62. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  63. package/dist/heart/daemon/cli-render.js +763 -0
  64. package/dist/heart/daemon/cli-types.js +8 -0
  65. package/dist/heart/daemon/connect-bay.js +323 -0
  66. package/dist/heart/daemon/daemon-cli.js +29 -1750
  67. package/dist/heart/daemon/daemon-entry.js +485 -2
  68. package/dist/heart/daemon/daemon-health.js +176 -0
  69. package/dist/heart/daemon/daemon-rollup.js +57 -0
  70. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  71. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  72. package/dist/heart/daemon/daemon.js +932 -74
  73. package/dist/heart/daemon/dns-workflow.js +394 -0
  74. package/dist/heart/daemon/doctor-types.js +8 -0
  75. package/dist/heart/daemon/doctor.js +873 -0
  76. package/dist/heart/daemon/health-monitor.js +122 -1
  77. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  78. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  79. package/dist/heart/daemon/http-health-probe.js +80 -0
  80. package/dist/heart/daemon/human-command-screens.js +234 -0
  81. package/dist/heart/daemon/human-readiness.js +114 -0
  82. package/dist/heart/daemon/inner-status.js +89 -0
  83. package/dist/heart/daemon/interactive-repair.js +394 -0
  84. package/dist/heart/daemon/launchd.js +37 -8
  85. package/dist/heart/daemon/log-tailer.js +79 -10
  86. package/dist/heart/daemon/logs-prune.js +110 -0
  87. package/dist/heart/daemon/mcp-canary.js +297 -0
  88. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  89. package/dist/heart/daemon/os-cron-deps.js +135 -0
  90. package/dist/heart/daemon/os-cron.js +14 -12
  91. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  92. package/dist/heart/daemon/ouro-entry.js +3 -1
  93. package/dist/heart/daemon/plugin-cli.js +432 -0
  94. package/dist/heart/daemon/process-manager.js +510 -40
  95. package/dist/heart/daemon/provider-discovery.js +137 -0
  96. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  97. package/dist/heart/daemon/pulse.js +475 -0
  98. package/dist/heart/daemon/readiness-repair.js +365 -0
  99. package/dist/heart/daemon/run-hooks.js +2 -0
  100. package/dist/heart/daemon/runtime-logging.js +35 -14
  101. package/dist/heart/daemon/runtime-metadata.js +2 -30
  102. package/dist/heart/daemon/safe-mode.js +161 -0
  103. package/dist/heart/daemon/sense-manager.js +493 -38
  104. package/dist/heart/daemon/session-id-resolver.js +131 -0
  105. package/dist/heart/daemon/skill-management-installer.js +1 -1
  106. package/dist/heart/daemon/socket-client.js +158 -11
  107. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  108. package/dist/heart/daemon/startup-tui.js +330 -0
  109. package/dist/heart/daemon/task-scheduler.js +117 -39
  110. package/dist/heart/daemon/terminal-ui.js +499 -0
  111. package/dist/heart/daemon/thoughts.js +229 -17
  112. package/dist/heart/daemon/up-progress.js +366 -0
  113. package/dist/heart/daemon/vault-items.js +56 -0
  114. package/dist/heart/delegation.js +1 -4
  115. package/dist/heart/habits/habit-migration.js +189 -0
  116. package/dist/heart/habits/habit-parser.js +140 -0
  117. package/dist/heart/habits/habit-runtime-state.js +100 -0
  118. package/dist/heart/habits/habit-scheduler.js +372 -0
  119. package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
  120. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  121. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  122. package/dist/heart/{daemon → hatch}/specialist-tools.js +37 -14
  123. package/dist/heart/identity.js +168 -57
  124. package/dist/heart/kept-notes.js +357 -0
  125. package/dist/heart/kicks.js +1 -1
  126. package/dist/heart/machine-identity.js +161 -0
  127. package/dist/heart/mail-import-discovery.js +353 -0
  128. package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
  129. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  130. package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
  131. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  132. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  133. package/dist/heart/mailbox/mailbox-http.js +99 -0
  134. package/dist/heart/mailbox/mailbox-read.js +31 -0
  135. package/dist/heart/mailbox/mailbox-types.js +27 -0
  136. package/dist/heart/mailbox/mailbox-view.js +197 -0
  137. package/dist/heart/mailbox/readers/agent-machine.js +418 -0
  138. package/dist/heart/mailbox/readers/continuity-readers.js +319 -0
  139. package/dist/heart/mailbox/readers/mail.js +375 -0
  140. package/dist/heart/mailbox/readers/runtime-readers.js +756 -0
  141. package/dist/heart/mailbox/readers/sessions.js +232 -0
  142. package/dist/heart/mailbox/readers/shared.js +111 -0
  143. package/dist/heart/mcp/mcp-server.js +692 -0
  144. package/dist/heart/migrate-config.js +100 -0
  145. package/dist/heart/model-capabilities.js +19 -0
  146. package/dist/heart/orientation-frame.js +217 -0
  147. package/dist/heart/platform.js +81 -0
  148. package/dist/heart/provider-attempt.js +134 -0
  149. package/dist/heart/provider-binding-resolver.js +272 -0
  150. package/dist/heart/provider-credentials.js +425 -0
  151. package/dist/heart/provider-failover.js +311 -0
  152. package/dist/heart/provider-models.js +81 -0
  153. package/dist/heart/provider-ping.js +262 -0
  154. package/dist/heart/provider-readiness-cache.js +40 -0
  155. package/dist/heart/provider-visibility.js +188 -0
  156. package/dist/heart/providers/anthropic-token.js +131 -0
  157. package/dist/heart/providers/anthropic.js +139 -52
  158. package/dist/heart/providers/azure.js +23 -11
  159. package/dist/heart/providers/error-classification.js +127 -0
  160. package/dist/heart/providers/github-copilot.js +145 -0
  161. package/dist/heart/providers/minimax-vlm.js +189 -0
  162. package/dist/heart/providers/minimax.js +26 -8
  163. package/dist/heart/providers/openai-codex-token.js +349 -0
  164. package/dist/heart/providers/openai-codex.js +55 -40
  165. package/dist/heart/runtime-capability-check.js +170 -0
  166. package/dist/heart/runtime-credentials.js +367 -0
  167. package/dist/heart/runtime-cwd.js +87 -0
  168. package/dist/heart/sense-truth.js +13 -4
  169. package/dist/heart/session-activity.js +48 -24
  170. package/dist/heart/session-events.js +1163 -0
  171. package/dist/heart/session-playback-cli-main.js +5 -0
  172. package/dist/heart/session-playback-cli.js +36 -0
  173. package/dist/heart/session-playback.js +231 -0
  174. package/dist/heart/session-stats-cli-main.js +5 -0
  175. package/dist/heart/session-stats.js +182 -0
  176. package/dist/heart/session-transcript.js +133 -0
  177. package/dist/heart/start-of-turn-packet.js +345 -0
  178. package/dist/heart/streaming.js +44 -27
  179. package/dist/heart/structured-output.js +196 -0
  180. package/dist/heart/sync-classification.js +176 -0
  181. package/dist/heart/sync.js +449 -0
  182. package/dist/heart/target-resolution.js +9 -5
  183. package/dist/heart/tempo.js +93 -0
  184. package/dist/heart/temporal-view.js +41 -0
  185. package/dist/heart/timeouts.js +101 -0
  186. package/dist/heart/tool-activity-callbacks.js +59 -0
  187. package/dist/heart/tool-description.js +143 -0
  188. package/dist/heart/tool-friction.js +55 -0
  189. package/dist/heart/tool-loop.js +200 -0
  190. package/dist/heart/turn-context.js +389 -0
  191. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  192. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  193. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  194. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  195. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  196. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  197. package/dist/heart/versioning/update-hooks.js +154 -0
  198. package/dist/mailbox-ui/assets/index-9-AxCxuB.js +61 -0
  199. package/dist/mailbox-ui/assets/index-CWzt267f.css +1 -0
  200. package/dist/mailbox-ui/index.html +15 -0
  201. package/dist/mailroom/attention.js +167 -0
  202. package/dist/mailroom/autonomy.js +209 -0
  203. package/dist/mailroom/blob-store.js +715 -0
  204. package/dist/mailroom/body-cache.js +61 -0
  205. package/dist/mailroom/core.js +788 -0
  206. package/dist/mailroom/entry.js +160 -0
  207. package/dist/mailroom/file-store.js +568 -0
  208. package/dist/mailroom/mbox-import.js +393 -0
  209. package/dist/mailroom/migration.js +164 -0
  210. package/dist/mailroom/outbound.js +380 -0
  211. package/dist/mailroom/policy.js +263 -0
  212. package/dist/mailroom/reader.js +233 -0
  213. package/dist/mailroom/search-cache.js +334 -0
  214. package/dist/mailroom/search-relevance.js +319 -0
  215. package/dist/mailroom/smtp-ingress.js +176 -0
  216. package/dist/mailroom/source-state.js +176 -0
  217. package/dist/mailroom/thread.js +109 -0
  218. package/dist/mailroom/travel-extract.js +89 -0
  219. package/dist/mind/bundle-manifest.js +14 -1
  220. package/dist/mind/context.js +251 -101
  221. package/dist/mind/desk-section.js +310 -0
  222. package/dist/mind/diary-integrity.js +60 -0
  223. package/dist/mind/{memory.js → diary.js} +68 -76
  224. package/dist/mind/embedding-provider.js +60 -0
  225. package/dist/mind/file-state.js +179 -0
  226. package/dist/mind/friends/channel.js +39 -0
  227. package/dist/mind/friends/resolver.js +54 -2
  228. package/dist/mind/friends/store-file.js +48 -4
  229. package/dist/mind/friends/types.js +2 -2
  230. package/dist/mind/journal-index.js +162 -0
  231. package/dist/mind/note-search.js +268 -0
  232. package/dist/mind/obligation-steering.js +221 -0
  233. package/dist/mind/pending.js +6 -1
  234. package/dist/mind/prompt-refresh.js +3 -2
  235. package/dist/mind/prompt.js +1051 -138
  236. package/dist/mind/provenance-trust.js +26 -0
  237. package/dist/mind/scrutiny.js +173 -0
  238. package/dist/nerves/cli-logging.js +7 -1
  239. package/dist/nerves/coverage/audit-rules.js +15 -6
  240. package/dist/nerves/coverage/audit.js +28 -2
  241. package/dist/nerves/coverage/cli.js +1 -1
  242. package/dist/nerves/coverage/contract.js +5 -5
  243. package/dist/nerves/coverage/file-completeness.js +139 -5
  244. package/dist/nerves/event-buffer.js +111 -0
  245. package/dist/nerves/index.js +224 -4
  246. package/dist/nerves/observation.js +20 -0
  247. package/dist/nerves/redact.js +79 -0
  248. package/dist/nerves/review/cli-main.js +5 -0
  249. package/dist/nerves/review/cli.js +156 -0
  250. package/dist/nerves/review/core.js +152 -0
  251. package/dist/nerves/runtime.js +5 -1
  252. package/dist/repertoire/ado-client.js +15 -56
  253. package/dist/repertoire/ado-semantic.js +16 -10
  254. package/dist/repertoire/api-client.js +97 -0
  255. package/dist/repertoire/bitwarden-store.js +1041 -0
  256. package/dist/repertoire/bundle-templates.js +72 -0
  257. package/dist/repertoire/bw-installer.js +180 -0
  258. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  259. package/dist/repertoire/coding/context-pack.js +331 -0
  260. package/dist/repertoire/coding/feedback.js +197 -30
  261. package/dist/repertoire/coding/manager.js +166 -10
  262. package/dist/repertoire/coding/spawner.js +55 -9
  263. package/dist/repertoire/coding/tools.js +219 -7
  264. package/dist/repertoire/commerce-errors.js +109 -0
  265. package/dist/repertoire/commerce-self-test.js +156 -0
  266. package/dist/repertoire/credential-access.js +178 -0
  267. package/dist/repertoire/desk/classifier.js +362 -0
  268. package/dist/repertoire/duffel-client.js +185 -0
  269. package/dist/repertoire/github-client.js +14 -55
  270. package/dist/repertoire/graph-client.js +11 -52
  271. package/dist/repertoire/guardrails.js +136 -25
  272. package/dist/repertoire/mcp-client.js +295 -0
  273. package/dist/repertoire/mcp-manager.js +403 -0
  274. package/dist/repertoire/mcp-tools.js +83 -0
  275. package/dist/repertoire/plugin-mcp.js +175 -0
  276. package/dist/repertoire/plugins.js +253 -0
  277. package/dist/repertoire/shell-sessions.js +133 -0
  278. package/dist/repertoire/skills.js +48 -4
  279. package/dist/repertoire/stripe-client.js +131 -0
  280. package/dist/repertoire/tool-results.js +29 -0
  281. package/dist/repertoire/tools-attachments.js +317 -0
  282. package/dist/repertoire/tools-awaiting.js +372 -0
  283. package/dist/repertoire/tools-base.js +59 -1082
  284. package/dist/repertoire/tools-bluebubbles.js +2 -0
  285. package/dist/repertoire/tools-bridge.js +144 -0
  286. package/dist/repertoire/tools-bundle.js +993 -0
  287. package/dist/repertoire/tools-config.js +186 -0
  288. package/dist/repertoire/tools-continuity.js +252 -0
  289. package/dist/repertoire/tools-credential.js +383 -0
  290. package/dist/repertoire/tools-evolution.js +527 -0
  291. package/dist/repertoire/tools-files.js +344 -0
  292. package/dist/repertoire/tools-flight.js +227 -0
  293. package/dist/repertoire/tools-flow.js +119 -0
  294. package/dist/repertoire/tools-github.js +3 -8
  295. package/dist/repertoire/tools-mail.js +1975 -0
  296. package/dist/repertoire/tools-notes.js +438 -0
  297. package/dist/repertoire/tools-obligations.js +143 -0
  298. package/dist/repertoire/tools-orientation.js +31 -0
  299. package/dist/repertoire/tools-record.js +464 -0
  300. package/dist/repertoire/tools-runtime.js +150 -0
  301. package/dist/repertoire/tools-session.js +766 -0
  302. package/dist/repertoire/tools-shell.js +120 -0
  303. package/dist/repertoire/tools-stripe.js +182 -0
  304. package/dist/repertoire/tools-surface.js +344 -0
  305. package/dist/repertoire/tools-teams.js +12 -39
  306. package/dist/repertoire/tools-travel.js +125 -0
  307. package/dist/repertoire/tools-trip.js +982 -0
  308. package/dist/repertoire/tools-user-profile.js +146 -0
  309. package/dist/repertoire/tools-vault.js +40 -0
  310. package/dist/repertoire/tools-voice.js +145 -0
  311. package/dist/repertoire/tools.js +193 -77
  312. package/dist/repertoire/travel-api-client.js +360 -0
  313. package/dist/repertoire/user-profile.js +131 -0
  314. package/dist/repertoire/vault-setup.js +246 -0
  315. package/dist/repertoire/vault-unlock.js +594 -0
  316. package/dist/scripts/claude-code-hook.js +41 -0
  317. package/dist/scripts/claude-code-stop-hook.js +47 -0
  318. package/dist/senses/attention-queue.js +186 -0
  319. package/dist/senses/await-turn-message.js +58 -0
  320. package/dist/senses/bluebubbles/active-turns.js +216 -0
  321. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  322. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  323. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  324. package/dist/senses/bluebubbles/entry.js +77 -0
  325. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  326. package/dist/senses/bluebubbles/index.js +2737 -0
  327. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  328. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  329. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  330. package/dist/senses/bluebubbles/processed-log.js +133 -0
  331. package/dist/senses/bluebubbles/replay.js +137 -0
  332. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  333. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  334. package/dist/senses/bluebubbles-meta-guard.js +40 -0
  335. package/dist/senses/cli/bracketed-paste.js +82 -0
  336. package/dist/senses/cli/image-paste.js +287 -0
  337. package/dist/senses/cli/image-ref-navigation.js +75 -0
  338. package/dist/senses/cli/ink-app.js +156 -0
  339. package/dist/senses/cli/inline-diff.js +64 -0
  340. package/dist/senses/cli/input-keys.js +174 -0
  341. package/dist/senses/cli/kill-ring.js +86 -0
  342. package/dist/senses/cli/message-list.js +51 -0
  343. package/dist/senses/cli/ouro-tui.js +607 -0
  344. package/dist/senses/cli/spinner-imperative.js +135 -0
  345. package/dist/senses/cli/spinner.js +101 -0
  346. package/dist/senses/cli/status-line.js +60 -0
  347. package/dist/senses/cli/streaming-markdown.js +526 -0
  348. package/dist/senses/cli/tool-display.js +85 -0
  349. package/dist/senses/cli/tool-render.js +85 -0
  350. package/dist/senses/cli/tui-store.js +240 -0
  351. package/dist/senses/cli/virtual-list.js +35 -0
  352. package/dist/senses/cli-entry.js +60 -8
  353. package/dist/senses/cli-layout.js +100 -0
  354. package/dist/senses/cli.js +517 -204
  355. package/dist/senses/commands.js +66 -3
  356. package/dist/senses/habit-turn-message.js +108 -0
  357. package/dist/senses/inner-dialog-worker.js +254 -22
  358. package/dist/senses/inner-dialog.js +505 -40
  359. package/dist/senses/mail-entry.js +66 -0
  360. package/dist/senses/mail.js +379 -0
  361. package/dist/senses/pipeline.js +711 -181
  362. package/dist/senses/proactive-content-guard.js +51 -0
  363. package/dist/senses/shared-turn.js +393 -0
  364. package/dist/senses/surface-tool.js +108 -0
  365. package/dist/senses/teams-entry.js +60 -8
  366. package/dist/senses/teams.js +390 -98
  367. package/dist/senses/trust-gate.js +100 -5
  368. package/dist/senses/voice/audio-playback.js +237 -0
  369. package/dist/senses/voice/audio-routing.js +119 -0
  370. package/dist/senses/voice/elevenlabs.js +202 -0
  371. package/dist/senses/voice/floor-control.js +431 -0
  372. package/dist/senses/voice/floor-controller.js +115 -0
  373. package/dist/senses/voice/golden-path.js +116 -0
  374. package/dist/senses/voice/index.js +29 -0
  375. package/dist/senses/voice/meeting.js +113 -0
  376. package/dist/senses/voice/outbound.js +190 -0
  377. package/dist/senses/voice/phone.js +33 -0
  378. package/dist/senses/voice/playback.js +139 -0
  379. package/dist/senses/voice/realtime-eval.js +496 -0
  380. package/dist/senses/voice/realtime-trace.js +531 -0
  381. package/dist/senses/voice/transcript.js +70 -0
  382. package/dist/senses/voice/turn.js +191 -0
  383. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  384. package/dist/senses/voice/twilio-phone.js +5079 -0
  385. package/dist/senses/voice/types.js +2 -0
  386. package/dist/senses/voice/whisper.js +161 -0
  387. package/dist/senses/voice-entry.js +81 -0
  388. package/dist/senses/voice-realtime-eval-command.js +99 -0
  389. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  390. package/dist/senses/voice-twilio-entry.js +87 -0
  391. package/dist/trips/core.js +138 -0
  392. package/dist/trips/store.js +265 -0
  393. package/dist/util/frontmatter.js +53 -0
  394. package/package.json +53 -10
  395. package/skills/agent-commerce.md +106 -0
  396. package/skills/browser-navigation.md +117 -0
  397. package/skills/commerce-setup-guide.md +116 -0
  398. package/skills/commerce-setup.md +84 -0
  399. package/skills/configure-dev-tools.md +99 -0
  400. package/skills/travel-planning.md +138 -0
  401. package/dist/heart/daemon/auth-flow.js +0 -351
  402. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  403. package/dist/heart/daemon/update-hooks.js +0 -138
  404. package/dist/heart/safe-workspace.js +0 -228
  405. package/dist/heart/session-recall.js +0 -116
  406. package/dist/mind/associative-recall.js +0 -209
  407. package/dist/repertoire/tasks/board.js +0 -134
  408. package/dist/repertoire/tasks/index.js +0 -224
  409. package/dist/repertoire/tasks/lifecycle.js +0 -80
  410. package/dist/repertoire/tasks/middleware.js +0 -65
  411. package/dist/repertoire/tasks/parser.js +0 -173
  412. package/dist/repertoire/tasks/scanner.js +0 -132
  413. package/dist/repertoire/tasks/transitions.js +0 -144
  414. package/dist/senses/bluebubbles-entry.js +0 -13
  415. package/dist/senses/bluebubbles.js +0 -1177
  416. package/dist/senses/debug-activity.js +0 -148
  417. package/subagents/README.md +0 -7
  418. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  419. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  420. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  421. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  422. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  423. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  424. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  425. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  426. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  427. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  428. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  429. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  430. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  431. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  432. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  433. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  434. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,409 @@
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.DEFAULT_RETAIN_VERSIONS = void 0;
37
+ exports.getOuroCliHome = getOuroCliHome;
38
+ exports.getCurrentVersion = getCurrentVersion;
39
+ exports.getPreviousVersion = getPreviousVersion;
40
+ exports.buildChangelogCommand = buildChangelogCommand;
41
+ exports.listInstalledVersions = listInstalledVersions;
42
+ exports.validateInstalledVersionForActivation = validateInstalledVersionForActivation;
43
+ exports.installVersion = installVersion;
44
+ exports.activateVersion = activateVersion;
45
+ exports.compareCliVersions = compareCliVersions;
46
+ exports.selectVersionsToPrune = selectVersionsToPrune;
47
+ exports.pruneOldVersions = pruneOldVersions;
48
+ exports.ensureLayout = ensureLayout;
49
+ const fs = __importStar(require("fs"));
50
+ const os = __importStar(require("os"));
51
+ const path = __importStar(require("path"));
52
+ const runtime_1 = require("../../nerves/runtime");
53
+ /** Maximum number of installed CLI versions to retain after pruning. */
54
+ exports.DEFAULT_RETAIN_VERSIONS = 5;
55
+ const INSTALLED_RUNTIME_PACKAGE_PAYLOAD_PATHS = [
56
+ "assets",
57
+ "dist",
58
+ "RepairGuide.ouro",
59
+ "SerpentGuide.ouro",
60
+ "skills",
61
+ "changelog.json",
62
+ "package.json",
63
+ ];
64
+ const INSTALLED_RUNTIME_TEXT_EXTENSIONS = new Set([
65
+ ".cjs",
66
+ ".css",
67
+ ".html",
68
+ ".js",
69
+ ".json",
70
+ ".md",
71
+ ".mjs",
72
+ ".txt",
73
+ ]);
74
+ const BLOCKED_INSTALLED_RUNTIME_TEXT_SIGNATURES = [
75
+ {
76
+ label: "removed BlueBubbles timeout notice",
77
+ base64: "bGl2ZSBpTWVzc2FnZSB0dXJuIHRpbWVkIG91dDsgSSBjYXB0dXJlZCBpdCBmb3IgcmVjb3ZlcnkgaW5zdGVhZCBvZiBzaWxlbnRseSBoYW5naW5n",
78
+ },
79
+ ];
80
+ function getOuroCliHome(homeDir) {
81
+ /* v8 ignore next -- dep default: tests always inject @preserve */
82
+ const home = homeDir ?? os.homedir();
83
+ return path.join(home, ".ouro-cli");
84
+ }
85
+ function getCurrentVersion(deps) {
86
+ const cliHome = getOuroCliHome(deps.homeDir);
87
+ /* v8 ignore next -- dep default: tests always inject @preserve */
88
+ const readlinkSync = deps.readlinkSync ?? fs.readlinkSync;
89
+ try {
90
+ const target = readlinkSync(path.join(cliHome, "CurrentVersion"));
91
+ return path.basename(target);
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ }
97
+ function getPreviousVersion(deps) {
98
+ const cliHome = getOuroCliHome(deps.homeDir);
99
+ /* v8 ignore next -- dep default: tests always inject @preserve */
100
+ const readlinkSync = deps.readlinkSync ?? fs.readlinkSync;
101
+ try {
102
+ const target = readlinkSync(path.join(cliHome, "previous"));
103
+ return path.basename(target);
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ function buildChangelogCommand(previousVersion, currentVersion) {
110
+ if (!previousVersion || !currentVersion || previousVersion === currentVersion) {
111
+ return null;
112
+ }
113
+ return `ouro changelog --from ${previousVersion}`;
114
+ }
115
+ function listInstalledVersions(deps) {
116
+ const cliHome = getOuroCliHome(deps.homeDir);
117
+ /* v8 ignore next -- dep default: tests always inject @preserve */
118
+ const readdirSync = deps.readdirSync ?? ((p, opts) => fs.readdirSync(p, opts));
119
+ try {
120
+ const entries = readdirSync(path.join(cliHome, "versions"), { withFileTypes: true });
121
+ return entries.filter((e) => e.isDirectory()).map((e) => e.name);
122
+ }
123
+ catch {
124
+ return [];
125
+ }
126
+ }
127
+ function validateInstalledVersionForActivation(version, deps = {}) {
128
+ const cliHome = getOuroCliHome(deps.homeDir);
129
+ /* v8 ignore start -- dep defaults: tests inject @preserve */
130
+ const existsSync = deps.existsSync ?? fs.existsSync;
131
+ const readdirSync = deps.readdirSync ?? ((p, opts) => fs.readdirSync(p, opts));
132
+ const readFileSync = deps.readFileSync ?? fs.readFileSync;
133
+ /* v8 ignore stop */
134
+ const packageRoot = path.join(cliHome, "versions", version, "node_modules", "@ouro.bot", "cli");
135
+ const packageJsonPath = path.join(packageRoot, "package.json");
136
+ if (!existsSync(packageJsonPath)) {
137
+ const message = `installed runtime ${version} is missing its @ouro.bot/cli package; run 'ouro up' to restore the current release`;
138
+ (0, runtime_1.emitNervesEvent)({
139
+ component: "daemon",
140
+ event: "daemon.cli_version_activation_blocked",
141
+ message: "blocked CLI version activation",
142
+ meta: { version, packageRoot, reason: "missing-package" },
143
+ level: "warn",
144
+ });
145
+ return { ok: false, version, packageRoot, violations: ["missing @ouro.bot/cli package"], message };
146
+ }
147
+ const violations = findBlockedInstalledRuntimePayloadText(packageRoot, { existsSync, readdirSync, readFileSync });
148
+ if (violations.length === 0) {
149
+ return { ok: true, version, packageRoot, violations, message: "installed runtime package passed activation guard" };
150
+ }
151
+ const message = `installed runtime ${version} contains blocked package assets (${violations.join(", ")}); run 'ouro up' to stay on the current release`;
152
+ (0, runtime_1.emitNervesEvent)({
153
+ component: "daemon",
154
+ event: "daemon.cli_version_activation_blocked",
155
+ message: "blocked CLI version activation",
156
+ meta: { version, packageRoot, reason: "blocked-package-assets", violations },
157
+ level: "warn",
158
+ });
159
+ return { ok: false, version, packageRoot, violations, message };
160
+ }
161
+ function findBlockedInstalledRuntimePayloadText(packageRoot, deps) {
162
+ const violations = [];
163
+ const blockedText = BLOCKED_INSTALLED_RUNTIME_TEXT_SIGNATURES.map((signature) => ({
164
+ label: signature.label,
165
+ text: Buffer.from(signature.base64, "base64").toString("utf8"),
166
+ }));
167
+ for (const payloadPath of INSTALLED_RUNTIME_PACKAGE_PAYLOAD_PATHS) {
168
+ const absolutePath = path.join(packageRoot, payloadPath);
169
+ if (!deps.existsSync(absolutePath))
170
+ continue;
171
+ collectBlockedTextViolations(packageRoot, absolutePath, payloadPath, blockedText, deps, violations);
172
+ }
173
+ return violations.sort();
174
+ }
175
+ function collectBlockedTextViolations(packageRoot, absolutePath, relativePath, blockedText, deps, violations) {
176
+ let entries = null;
177
+ try {
178
+ entries = deps.readdirSync(absolutePath, { withFileTypes: true });
179
+ }
180
+ catch {
181
+ entries = null;
182
+ }
183
+ if (entries !== null) {
184
+ for (const entry of entries) {
185
+ const childRelativePath = `${relativePath}/${entry.name}`;
186
+ if (entry.isDirectory()) {
187
+ collectBlockedTextViolations(packageRoot, path.join(absolutePath, entry.name), childRelativePath, blockedText, deps, violations);
188
+ }
189
+ else if (entry.isFile()) {
190
+ inspectInstalledRuntimePayloadFile(packageRoot, childRelativePath, blockedText, deps, violations);
191
+ }
192
+ }
193
+ return;
194
+ }
195
+ inspectInstalledRuntimePayloadFile(packageRoot, relativePath, blockedText, deps, violations);
196
+ }
197
+ function inspectInstalledRuntimePayloadFile(packageRoot, relativePath, blockedText, deps, violations) {
198
+ if (!INSTALLED_RUNTIME_TEXT_EXTENSIONS.has(path.extname(relativePath)))
199
+ return;
200
+ let content = "";
201
+ try {
202
+ content = deps.readFileSync(path.join(packageRoot, relativePath), "utf8");
203
+ }
204
+ catch (error) {
205
+ const reason = error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error);
206
+ violations.push(`${relativePath} could not be inspected: ${reason}`);
207
+ return;
208
+ }
209
+ for (const blocked of blockedText) {
210
+ if (content.includes(blocked.text)) {
211
+ violations.push(`${relativePath} contains ${blocked.label}`);
212
+ }
213
+ }
214
+ }
215
+ function installVersion(version, deps) {
216
+ const cliHome = getOuroCliHome(deps.homeDir);
217
+ /* v8 ignore start -- dep defaults: tests always inject @preserve */
218
+ const mkdirSync = deps.mkdirSync ?? fs.mkdirSync;
219
+ const execSync = deps.execSync ?? ((cmd, opts) => require("child_process").execSync(cmd, opts));
220
+ /* v8 ignore stop */
221
+ const versionDir = path.join(cliHome, "versions", version);
222
+ (0, runtime_1.emitNervesEvent)({
223
+ component: "daemon",
224
+ event: "daemon.cli_version_install_start",
225
+ message: "installing CLI version",
226
+ meta: { version, versionDir },
227
+ });
228
+ mkdirSync(versionDir, { recursive: true });
229
+ execSync(`npm install --prefix ${versionDir} @ouro.bot/cli@${version}`, { stdio: "pipe" });
230
+ (0, runtime_1.emitNervesEvent)({
231
+ component: "daemon",
232
+ event: "daemon.cli_version_install_end",
233
+ message: "CLI version installed",
234
+ meta: { version, versionDir },
235
+ });
236
+ }
237
+ function activateVersion(version, deps) {
238
+ const cliHome = getOuroCliHome(deps.homeDir);
239
+ /* v8 ignore start -- dep defaults: tests always inject @preserve */
240
+ const readlinkSync = deps.readlinkSync ?? fs.readlinkSync;
241
+ const unlinkSync = deps.unlinkSync ?? fs.unlinkSync;
242
+ const symlinkSync = deps.symlinkSync ?? fs.symlinkSync;
243
+ const existsSync = deps.existsSync ?? fs.existsSync;
244
+ /* v8 ignore stop */
245
+ const currentVersionPath = path.join(cliHome, "CurrentVersion");
246
+ const previousPath = path.join(cliHome, "previous");
247
+ const newTarget = path.join(cliHome, "versions", version);
248
+ (0, runtime_1.emitNervesEvent)({
249
+ component: "daemon",
250
+ event: "daemon.cli_version_activate",
251
+ message: "activating CLI version",
252
+ meta: { version },
253
+ });
254
+ // Read old CurrentVersion target (may not exist)
255
+ let oldTarget = null;
256
+ try {
257
+ oldTarget = readlinkSync(currentVersionPath);
258
+ }
259
+ catch {
260
+ // No current version — first install
261
+ }
262
+ // Update previous symlink to point to old current
263
+ if (oldTarget) {
264
+ try {
265
+ unlinkSync(previousPath);
266
+ }
267
+ catch {
268
+ // previous symlink may not exist yet
269
+ }
270
+ symlinkSync(oldTarget, previousPath);
271
+ }
272
+ // Update CurrentVersion symlink
273
+ if (existsSync(currentVersionPath)) {
274
+ unlinkSync(currentVersionPath);
275
+ }
276
+ symlinkSync(newTarget, currentVersionPath);
277
+ }
278
+ /**
279
+ * Compare two version strings of the form `0.1.0-alpha.{n}`. Returns
280
+ * positive when `a` is newer, negative when `b` is newer, 0 when equal.
281
+ *
282
+ * The harness only ships `0.1.0-alpha.{n}` versions today; this comparator
283
+ * extracts the numeric tail and falls back to a lexicographic compare for
284
+ * any version that doesn't match the pattern (so unexpected version
285
+ * formats sort consistently rather than throwing).
286
+ */
287
+ function compareCliVersions(a, b) {
288
+ const aMatch = /alpha\.(\d+)/.exec(a);
289
+ const bMatch = /alpha\.(\d+)/.exec(b);
290
+ if (aMatch && bMatch) {
291
+ const aN = parseInt(aMatch[1], 10);
292
+ const bN = parseInt(bMatch[1], 10);
293
+ return aN - bN;
294
+ }
295
+ // Fallback: lexicographic. Both-mismatched and one-mismatched cases land
296
+ // here. Predictable, even if not strictly semver-correct.
297
+ if (a < b)
298
+ return -1;
299
+ if (a > b)
300
+ return 1;
301
+ return 0;
302
+ }
303
+ /**
304
+ * Identify which installed CLI versions can be safely deleted, given a
305
+ * retention policy. Pure: takes the full version list and the protected
306
+ * (current/previous) versions, returns the versions to delete.
307
+ *
308
+ * Retention rules:
309
+ * - Always keep the N most recent versions (default 5).
310
+ * - Always keep the currently-active version (CurrentVersion symlink target).
311
+ * - Always keep the previous version (previous symlink target) so rollback
312
+ * stays one command away.
313
+ * - Delete everything else.
314
+ *
315
+ * Exported so tests can pin the policy without shelling out to a real fs.
316
+ */
317
+ function selectVersionsToPrune(installedVersions, protectedVersions, retain = exports.DEFAULT_RETAIN_VERSIONS) {
318
+ if (installedVersions.length <= retain)
319
+ return [];
320
+ const sorted = [...installedVersions].sort(compareCliVersions).reverse();
321
+ const keepers = new Set(sorted.slice(0, retain));
322
+ if (protectedVersions.current)
323
+ keepers.add(protectedVersions.current);
324
+ if (protectedVersions.previous)
325
+ keepers.add(protectedVersions.previous);
326
+ return installedVersions.filter((v) => !keepers.has(v));
327
+ }
328
+ /**
329
+ * Prune installed CLI versions according to the retention policy. Removes
330
+ * `~/.ouro-cli/versions/{version}/` directories for versions outside the
331
+ * retention window. Best-effort: per-version delete failures are logged
332
+ * via nerves but don't propagate.
333
+ *
334
+ * Called from the activate path (cli-defaults.ts) so that every successful
335
+ * `ouro up` self-prunes. The user observed `~/.ouro-cli/versions/` going
336
+ * back to alpha.85 from March 20 — every CLI version they'd ever installed
337
+ * was still on disk because nothing ever GCed.
338
+ */
339
+ function pruneOldVersions(retain = exports.DEFAULT_RETAIN_VERSIONS, deps = {}) {
340
+ const cliHome = getOuroCliHome(deps.homeDir);
341
+ /* v8 ignore start -- dep defaults: tests always inject @preserve */
342
+ const readdirSync = deps.readdirSync ?? ((p, opts) => fs.readdirSync(p, opts));
343
+ const readlinkSync = deps.readlinkSync ?? fs.readlinkSync;
344
+ const rmSync = deps.rmSync ?? fs.rmSync;
345
+ /* v8 ignore stop */
346
+ const versionsDir = path.join(cliHome, "versions");
347
+ let installed;
348
+ try {
349
+ installed = readdirSync(versionsDir, { withFileTypes: true })
350
+ .filter((e) => e.isDirectory())
351
+ .map((e) => e.name);
352
+ }
353
+ catch {
354
+ return { kept: [], deleted: [], failed: [] };
355
+ }
356
+ const current = (() => {
357
+ try {
358
+ return path.basename(readlinkSync(path.join(cliHome, "CurrentVersion")));
359
+ }
360
+ catch {
361
+ return null;
362
+ }
363
+ })();
364
+ const previous = (() => {
365
+ try {
366
+ return path.basename(readlinkSync(path.join(cliHome, "previous")));
367
+ }
368
+ catch {
369
+ return null;
370
+ }
371
+ })();
372
+ const toDelete = selectVersionsToPrune(installed, { current, previous }, retain);
373
+ const deleted = [];
374
+ const failed = [];
375
+ for (const version of toDelete) {
376
+ const versionDir = path.join(versionsDir, version);
377
+ try {
378
+ rmSync(versionDir, { recursive: true, force: true });
379
+ deleted.push(version);
380
+ }
381
+ catch (error) {
382
+ failed.push({
383
+ version,
384
+ error: error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error),
385
+ });
386
+ }
387
+ }
388
+ (0, runtime_1.emitNervesEvent)({
389
+ component: "daemon",
390
+ event: "daemon.cli_versions_pruned",
391
+ message: `pruned ${deleted.length} old CLI versions`,
392
+ meta: { retain, deleted, failed: failed.length, kept: installed.filter((v) => !deleted.includes(v)) },
393
+ });
394
+ return { kept: installed.filter((v) => !deleted.includes(v)), deleted, failed };
395
+ }
396
+ function ensureLayout(deps) {
397
+ const cliHome = getOuroCliHome(deps.homeDir);
398
+ /* v8 ignore next -- dep default: tests always inject @preserve */
399
+ const mkdirSync = deps.mkdirSync ?? fs.mkdirSync;
400
+ mkdirSync(cliHome, { recursive: true });
401
+ mkdirSync(path.join(cliHome, "bin"), { recursive: true });
402
+ mkdirSync(path.join(cliHome, "versions"), { recursive: true });
403
+ (0, runtime_1.emitNervesEvent)({
404
+ component: "daemon",
405
+ event: "daemon.cli_layout_ensured",
406
+ message: "CLI directory layout ensured",
407
+ meta: { cliHome },
408
+ });
409
+ }
@@ -45,14 +45,22 @@ async function performStagedRestart(version, deps) {
45
45
  });
46
46
  // Step 1: Install new version
47
47
  try {
48
- deps.execSync(`npm install -g @ouro.bot/cli@${version}`);
48
+ if (deps.installNewVersion) {
49
+ deps.installNewVersion(version);
50
+ }
51
+ else {
52
+ // Backward-compat fallback for callers that haven't migrated to the
53
+ // version-managed installer. Tests use this path with a mocked
54
+ // execSync; production callers inject installNewVersion.
55
+ deps.execSync(`npm install -g @ouro.bot/cli@${version}`);
56
+ }
49
57
  }
50
58
  catch (err) {
51
59
  const errorMessage = err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err);
52
60
  (0, runtime_1.emitNervesEvent)({
53
61
  component: "daemon",
54
62
  event: "daemon.staged_restart_install_failed",
55
- message: "npm install failed",
63
+ message: "install failed",
56
64
  meta: { version, error: errorMessage },
57
65
  });
58
66
  return { ok: false, error: errorMessage };
@@ -90,25 +98,49 @@ async function performStagedRestart(version, deps) {
90
98
  });
91
99
  return { ok: false, error: `hook runner exited with code ${spawnResult.status}` };
92
100
  }
93
- // Step 4: Graceful shutdown (launchd will restart with new code)
101
+ // Step 4: Graceful shutdown then self-spawn new daemon
102
+ // We can't rely on launchd KeepAlive — the plist may not be loaded.
103
+ // Instead: shut down (releases socket), spawn new daemon from updated code.
94
104
  (0, runtime_1.emitNervesEvent)({
95
105
  component: "daemon",
96
106
  event: "daemon.staged_restart_hooks_passed",
97
- message: "hooks passed, shutting down for restart",
107
+ message: "hooks passed, shutting down and spawning new daemon",
98
108
  meta: { version },
99
109
  });
110
+ let shutdownError;
100
111
  try {
101
112
  await deps.gracefulShutdown();
102
113
  }
103
114
  catch (err) {
104
- const shutdownError = err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err);
115
+ shutdownError = err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err);
105
116
  (0, runtime_1.emitNervesEvent)({
106
117
  component: "daemon",
107
118
  event: "daemon.staged_restart_shutdown_error",
108
- message: "graceful shutdown encountered error",
119
+ message: "graceful shutdown encountered error (continuing with spawn)",
109
120
  meta: { version, error: shutdownError },
110
121
  });
111
- return { ok: true, shutdownError };
112
122
  }
113
- return { ok: true };
123
+ // Spawn new daemon from updated code path
124
+ const newEntry = path.join(newCodePath, "dist", "heart", "daemon", "daemon-entry.js");
125
+ const socketArg = deps.socketPath ?? "/tmp/ouroboros-daemon.sock";
126
+ try {
127
+ const { pid } = deps.spawnNewDaemon(newEntry, socketArg);
128
+ (0, runtime_1.emitNervesEvent)({
129
+ component: "daemon",
130
+ event: "daemon.staged_restart_spawned",
131
+ message: "new daemon spawned successfully",
132
+ meta: { version, pid, entry: newEntry },
133
+ });
134
+ }
135
+ catch (err) {
136
+ const spawnError = err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err);
137
+ (0, runtime_1.emitNervesEvent)({
138
+ component: "daemon",
139
+ event: "daemon.staged_restart_respawn_failed",
140
+ message: "failed to spawn new daemon after shutdown",
141
+ meta: { version, error: spawnError, entry: newEntry },
142
+ });
143
+ return { ok: false, error: `shutdown succeeded but failed to spawn new daemon: ${spawnError}`, shutdownError };
144
+ }
145
+ return { ok: true, shutdownError };
114
146
  }
@@ -33,12 +33,15 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CLI_UPDATE_DIST_TAG = exports.CLI_UPDATE_CHECK_TIMEOUT_MS = void 0;
36
37
  exports.checkForUpdate = checkForUpdate;
37
38
  exports.startUpdateChecker = startUpdateChecker;
38
39
  exports.stopUpdateChecker = stopUpdateChecker;
39
40
  const semver = __importStar(require("semver"));
40
41
  const runtime_1 = require("../../nerves/runtime");
41
42
  const DEFAULT_INTERVAL_MS = 30 * 60 * 1000; // 30 minutes
43
+ exports.CLI_UPDATE_CHECK_TIMEOUT_MS = 3_000;
44
+ exports.CLI_UPDATE_DIST_TAG = "latest";
42
45
  async function checkForUpdate(currentVersion, deps) {
43
46
  (0, runtime_1.emitNervesEvent)({
44
47
  component: "daemon",
@@ -102,9 +105,11 @@ function stopUpdateChecker() {
102
105
  clearInterval(_intervalId);
103
106
  _intervalId = null;
104
107
  }
108
+ // `_end` (not `_stop`) to satisfy the nerves audit's start/end pairing
109
+ // rule — counterpart to `daemon.update_checker_start` above.
105
110
  (0, runtime_1.emitNervesEvent)({
106
111
  component: "daemon",
107
- event: "daemon.update_checker_stop",
112
+ event: "daemon.update_checker_end",
108
113
  message: "stopping update checker",
109
114
  meta: {},
110
115
  });
@@ -0,0 +1,154 @@
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.registerUpdateHook = registerUpdateHook;
37
+ exports.getRegisteredHooks = getRegisteredHooks;
38
+ exports.clearRegisteredHooks = clearRegisteredHooks;
39
+ exports.applyPendingUpdates = applyPendingUpdates;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const semver = __importStar(require("semver"));
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ const _hooks = [];
45
+ function registerUpdateHook(hook) {
46
+ _hooks.push(hook);
47
+ (0, runtime_1.emitNervesEvent)({
48
+ component: "daemon",
49
+ event: "daemon.update_hook_registered",
50
+ message: "registered update hook",
51
+ meta: {},
52
+ });
53
+ }
54
+ function getRegisteredHooks() {
55
+ return _hooks;
56
+ }
57
+ function clearRegisteredHooks() {
58
+ _hooks.length = 0;
59
+ }
60
+ function isNoAgentDefaultBundle(agentRoot, entryName) {
61
+ return entryName === "default.ouro" && !fs.existsSync(path.join(agentRoot, "agent.json"));
62
+ }
63
+ async function applyPendingUpdates(bundlesRoot, currentVersion) {
64
+ const summary = { updated: [] };
65
+ (0, runtime_1.emitNervesEvent)({
66
+ component: "daemon",
67
+ event: "daemon.apply_pending_updates_start",
68
+ message: "applying pending updates",
69
+ meta: { bundlesRoot, currentVersion },
70
+ });
71
+ try {
72
+ if (!fs.existsSync(bundlesRoot)) {
73
+ return summary;
74
+ }
75
+ let entries;
76
+ try {
77
+ entries = fs.readdirSync(bundlesRoot, { withFileTypes: true });
78
+ }
79
+ catch {
80
+ return summary;
81
+ }
82
+ for (const entry of entries) {
83
+ if (!entry.isDirectory() || !entry.name.endsWith(".ouro"))
84
+ continue;
85
+ const agentRoot = path.join(bundlesRoot, entry.name);
86
+ if (isNoAgentDefaultBundle(agentRoot, entry.name)) {
87
+ (0, runtime_1.emitNervesEvent)({
88
+ component: "daemon",
89
+ event: "daemon.update_hook_skip_no_agent_default",
90
+ message: "skipping no-agent default bundle during pending updates",
91
+ meta: { agentRoot },
92
+ });
93
+ continue;
94
+ }
95
+ let previousVersion;
96
+ const metaPath = path.join(agentRoot, "bundle-meta.json");
97
+ try {
98
+ if (fs.existsSync(metaPath)) {
99
+ const raw = fs.readFileSync(metaPath, "utf-8");
100
+ const meta = JSON.parse(raw);
101
+ previousVersion = meta.runtimeVersion;
102
+ if (previousVersion === currentVersion) {
103
+ continue;
104
+ }
105
+ // Skip downgrades — only update forward
106
+ if (semver.valid(previousVersion) && semver.valid(currentVersion) && semver.gte(previousVersion, currentVersion)) {
107
+ (0, runtime_1.emitNervesEvent)({
108
+ component: "daemon",
109
+ event: "daemon.update_hook_skip_downgrade",
110
+ message: "skipping downgrade",
111
+ meta: { agentRoot, previousVersion, currentVersion },
112
+ });
113
+ continue;
114
+ }
115
+ }
116
+ }
117
+ catch {
118
+ // Malformed or unreadable bundle-meta.json -- treat as needing update
119
+ previousVersion = undefined;
120
+ }
121
+ const ctx = { agentRoot, currentVersion, previousVersion };
122
+ for (const hook of _hooks) {
123
+ try {
124
+ await hook(ctx);
125
+ }
126
+ catch (err) {
127
+ (0, runtime_1.emitNervesEvent)({
128
+ component: "daemon",
129
+ event: "daemon.update_hook_error",
130
+ message: "update hook threw",
131
+ meta: {
132
+ agentRoot,
133
+ error: err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err),
134
+ },
135
+ });
136
+ }
137
+ }
138
+ summary.updated.push({
139
+ agent: entry.name.replace(/\.ouro$/, ""),
140
+ from: previousVersion,
141
+ to: currentVersion,
142
+ });
143
+ }
144
+ return summary;
145
+ }
146
+ finally {
147
+ (0, runtime_1.emitNervesEvent)({
148
+ component: "daemon",
149
+ event: "daemon.apply_pending_updates_end",
150
+ message: "pending updates applied",
151
+ meta: { bundlesRoot },
152
+ });
153
+ }
154
+ }