@ouro.bot/cli 0.1.0-alpha.73 → 0.1.0-alpha.730

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 (527) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -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/changelog.json +4633 -14
  15. package/dist/a2a/card.js +57 -0
  16. package/dist/a2a/client.js +180 -0
  17. package/dist/a2a/config.js +50 -0
  18. package/dist/a2a/delegation-stores.js +56 -0
  19. package/dist/a2a/did-resolution.js +93 -0
  20. package/dist/a2a/identity.js +170 -0
  21. package/dist/a2a/inbound-share.js +107 -0
  22. package/dist/a2a/mission-result-wire.js +196 -0
  23. package/dist/a2a/onboarding.js +115 -0
  24. package/dist/a2a/pin-store.js +132 -0
  25. package/dist/a2a/seen-ledger.js +120 -0
  26. package/dist/a2a/server.js +604 -0
  27. package/dist/a2a/task-store.js +69 -0
  28. package/dist/a2a/transport.js +45 -0
  29. package/dist/a2a/types.js +3 -0
  30. package/dist/arc/attention-types.js +8 -0
  31. package/dist/arc/cares.js +144 -0
  32. package/dist/arc/episodes.js +118 -0
  33. package/dist/arc/evolution.js +490 -0
  34. package/dist/arc/flight-recorder.js +1034 -0
  35. package/dist/arc/intentions.js +134 -0
  36. package/dist/arc/json-store.js +117 -0
  37. package/dist/arc/obligations.js +348 -0
  38. package/dist/arc/packets.js +336 -0
  39. package/dist/arc/presence.js +185 -0
  40. package/dist/arc/task-lifecycle.js +57 -0
  41. package/dist/commerce/store.js +755 -0
  42. package/dist/commerce/types.js +3 -0
  43. package/dist/heart/active-work.js +874 -43
  44. package/dist/heart/agent-entry.js +190 -3
  45. package/dist/heart/approval-store.js +791 -0
  46. package/dist/heart/attachments/image-normalize.js +194 -0
  47. package/dist/heart/attachments/materialize.js +97 -0
  48. package/dist/heart/attachments/originals.js +88 -0
  49. package/dist/heart/attachments/render.js +29 -0
  50. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  51. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  52. package/dist/heart/attachments/sources/index.js +16 -0
  53. package/dist/heart/attachments/store.js +103 -0
  54. package/dist/heart/attachments/types.js +93 -0
  55. package/dist/heart/auth/auth-flow.js +479 -0
  56. package/dist/heart/autonomy-budget.js +434 -0
  57. package/dist/heart/awaiting/await-alert.js +146 -0
  58. package/dist/heart/awaiting/await-expiry.js +108 -0
  59. package/dist/heart/awaiting/await-loader.js +91 -0
  60. package/dist/heart/awaiting/await-parser.js +141 -0
  61. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  62. package/dist/heart/awaiting/await-scheduler.js +378 -0
  63. package/dist/heart/background-operations.js +281 -0
  64. package/dist/heart/bridges/manager.js +137 -17
  65. package/dist/heart/bridges/store.js +14 -2
  66. package/dist/heart/bundle-state.js +168 -0
  67. package/dist/heart/commitments.js +135 -0
  68. package/dist/heart/config-registry.js +331 -0
  69. package/dist/heart/config.js +120 -129
  70. package/dist/heart/context-loss-gauntlet.js +354 -0
  71. package/dist/heart/context-loss-sentinel.js +1155 -0
  72. package/dist/heart/core.js +1763 -320
  73. package/dist/heart/cross-chat-delivery.js +8 -22
  74. package/dist/heart/daemon/agent-config-check.js +451 -0
  75. package/dist/heart/daemon/agent-discovery.js +185 -3
  76. package/dist/heart/daemon/agent-service.js +542 -0
  77. package/dist/heart/daemon/agentic-repair.js +547 -0
  78. package/dist/heart/daemon/await-private-wake.js +59 -0
  79. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  80. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  81. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  82. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  83. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  84. package/dist/heart/daemon/cadence.js +180 -0
  85. package/dist/heart/daemon/cli-defaults.js +832 -0
  86. package/dist/heart/daemon/cli-desk.js +322 -0
  87. package/dist/heart/daemon/cli-exec.js +8586 -0
  88. package/dist/heart/daemon/cli-help.js +700 -0
  89. package/dist/heart/daemon/cli-parse.js +2688 -0
  90. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  91. package/dist/heart/daemon/cli-render.js +777 -0
  92. package/dist/heart/daemon/cli-types.js +8 -0
  93. package/dist/heart/daemon/connect-bay.js +323 -0
  94. package/dist/heart/daemon/daemon-cli.js +29 -2093
  95. package/dist/heart/daemon/daemon-entry.js +842 -10
  96. package/dist/heart/daemon/daemon-health.js +176 -0
  97. package/dist/heart/daemon/daemon-rollup.js +57 -0
  98. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  99. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  100. package/dist/heart/daemon/daemon.js +1610 -87
  101. package/dist/heart/daemon/dns-workflow.js +394 -0
  102. package/dist/heart/daemon/doctor-types.js +8 -0
  103. package/dist/heart/daemon/doctor.js +1440 -0
  104. package/dist/heart/daemon/freshness.js +343 -0
  105. package/dist/heart/daemon/habit-private-wake.js +61 -0
  106. package/dist/heart/daemon/health-monitor.js +142 -11
  107. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  108. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  109. package/dist/heart/daemon/http-health-probe.js +80 -0
  110. package/dist/heart/daemon/human-command-screens.js +234 -0
  111. package/dist/heart/daemon/human-readiness.js +114 -0
  112. package/dist/heart/daemon/inner-status.js +78 -0
  113. package/dist/heart/daemon/interactive-repair.js +394 -0
  114. package/dist/heart/daemon/launchd.js +37 -8
  115. package/dist/heart/daemon/log-tailer.js +79 -10
  116. package/dist/heart/daemon/logs-prune.js +110 -0
  117. package/dist/heart/daemon/mcp-canary.js +524 -0
  118. package/dist/heart/daemon/message-router.js +45 -5
  119. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  120. package/dist/heart/daemon/os-cron-deps.js +135 -0
  121. package/dist/heart/daemon/os-cron.js +22 -14
  122. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  123. package/dist/heart/daemon/ouro-entry.js +3 -1
  124. package/dist/heart/daemon/plugin-cli.js +432 -0
  125. package/dist/heart/daemon/process-manager.js +624 -61
  126. package/dist/heart/daemon/provider-discovery.js +137 -0
  127. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  128. package/dist/heart/daemon/pulse.js +511 -0
  129. package/dist/heart/daemon/readiness-repair.js +365 -0
  130. package/dist/heart/daemon/run-hooks.js +2 -0
  131. package/dist/heart/daemon/runtime-logging.js +41 -14
  132. package/dist/heart/daemon/runtime-metadata.js +2 -30
  133. package/dist/heart/daemon/safe-mode.js +161 -0
  134. package/dist/heart/daemon/sense-manager.js +670 -48
  135. package/dist/heart/daemon/session-id-resolver.js +131 -0
  136. package/dist/heart/daemon/skill-management-installer.js +1 -1
  137. package/dist/heart/daemon/socket-client.js +180 -12
  138. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  139. package/dist/heart/daemon/startup-tui.js +338 -0
  140. package/dist/heart/daemon/task-scheduler.js +117 -39
  141. package/dist/heart/daemon/terminal-ui.js +499 -0
  142. package/dist/heart/daemon/thoughts.js +255 -43
  143. package/dist/heart/daemon/up-progress.js +366 -0
  144. package/dist/heart/daemon/vault-items.js +56 -0
  145. package/dist/heart/delegation.js +1 -4
  146. package/dist/heart/external-events/router.js +121 -0
  147. package/dist/heart/habits/habit-cancel.js +810 -0
  148. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  149. package/dist/heart/habits/habit-migration.js +194 -0
  150. package/dist/heart/habits/habit-parser.js +278 -0
  151. package/dist/heart/habits/habit-runtime-state.js +93 -0
  152. package/dist/heart/habits/habit-scheduler.js +649 -0
  153. package/dist/heart/habits/habit-session-summary.js +318 -0
  154. package/dist/heart/habits/habit-session.js +636 -0
  155. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  156. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  157. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  158. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  159. package/dist/heart/identity.js +174 -59
  160. package/dist/heart/kept-notes.js +289 -0
  161. package/dist/heart/kicks.js +1 -1
  162. package/dist/heart/machine-identity.js +161 -0
  163. package/dist/heart/mail-import-discovery.js +353 -0
  164. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  165. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  166. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  167. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  168. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  169. package/dist/heart/mailbox/mailbox-http.js +99 -0
  170. package/dist/heart/mailbox/mailbox-read.js +39 -0
  171. package/dist/heart/mailbox/mailbox-types.js +27 -0
  172. package/dist/heart/mailbox/mailbox-view.js +197 -0
  173. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  174. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  175. package/dist/heart/mailbox/readers/mail.js +375 -0
  176. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  177. package/dist/heart/mailbox/readers/sessions.js +232 -0
  178. package/dist/heart/mailbox/readers/shared.js +111 -0
  179. package/dist/heart/mcp/mcp-server.js +696 -0
  180. package/dist/heart/migrate-config.js +100 -0
  181. package/dist/heart/model-capabilities.js +11 -0
  182. package/dist/heart/orientation-frame.js +345 -0
  183. package/dist/heart/platform.js +81 -0
  184. package/dist/heart/primitives.js +1 -1
  185. package/dist/heart/private-runtime/decision-renderer.js +156 -0
  186. package/dist/heart/private-runtime/index.js +18 -0
  187. package/dist/heart/private-runtime/ledger.js +218 -0
  188. package/dist/heart/private-runtime/policy.js +214 -0
  189. package/dist/heart/private-runtime/types.js +2 -0
  190. package/dist/heart/progress-story.js +1 -1
  191. package/dist/heart/provider-attempt.js +137 -0
  192. package/dist/heart/provider-binding-resolver.js +273 -0
  193. package/dist/heart/provider-credentials.js +441 -0
  194. package/dist/heart/provider-failover.js +311 -0
  195. package/dist/heart/provider-models.js +81 -0
  196. package/dist/heart/provider-ping.js +262 -0
  197. package/dist/heart/provider-readiness-cache.js +119 -0
  198. package/dist/heart/provider-visibility.js +188 -0
  199. package/dist/heart/providers/anthropic-token.js +131 -0
  200. package/dist/heart/providers/anthropic.js +173 -60
  201. package/dist/heart/providers/azure.js +23 -11
  202. package/dist/heart/providers/error-classification.js +127 -0
  203. package/dist/heart/providers/github-copilot.js +34 -38
  204. package/dist/heart/providers/minimax-vlm.js +189 -0
  205. package/dist/heart/providers/minimax.js +26 -8
  206. package/dist/heart/providers/openai-codex-token.js +349 -0
  207. package/dist/heart/providers/openai-codex.js +55 -40
  208. package/dist/heart/run-ledger.js +247 -0
  209. package/dist/heart/runtime-capability-check.js +170 -0
  210. package/dist/heart/runtime-credentials.js +398 -0
  211. package/dist/heart/runtime-cwd.js +87 -0
  212. package/dist/heart/sense-truth.js +20 -4
  213. package/dist/heart/session-activity.js +90 -24
  214. package/dist/heart/session-events.js +1300 -0
  215. package/dist/heart/session-playback-cli-main.js +5 -0
  216. package/dist/heart/session-playback-cli.js +36 -0
  217. package/dist/heart/session-playback.js +231 -0
  218. package/dist/heart/session-stats-cli-main.js +5 -0
  219. package/dist/heart/session-stats.js +182 -0
  220. package/dist/heart/session-transcript.js +133 -0
  221. package/dist/heart/start-of-turn-packet.js +368 -0
  222. package/dist/heart/streaming.js +604 -207
  223. package/dist/heart/structured-output.js +196 -0
  224. package/dist/heart/sync-classification.js +176 -0
  225. package/dist/heart/sync.js +449 -0
  226. package/dist/heart/target-resolution.js +11 -7
  227. package/dist/heart/tempo.js +93 -0
  228. package/dist/heart/temporal-view.js +41 -0
  229. package/dist/heart/timeouts.js +101 -0
  230. package/dist/heart/tool-activity-callbacks.js +59 -0
  231. package/dist/heart/tool-approval.js +339 -0
  232. package/dist/heart/tool-description.js +155 -0
  233. package/dist/heart/tool-friction.js +55 -0
  234. package/dist/heart/tool-loop.js +200 -0
  235. package/dist/heart/turn-context.js +472 -0
  236. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  237. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  238. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  239. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  240. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  241. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  242. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  243. package/dist/heart/versioning/update-hooks.js +154 -0
  244. package/dist/heart/versioning/version-intent.js +114 -0
  245. package/dist/heart/work-card.js +380 -0
  246. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  247. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  248. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  249. package/dist/mailbox-ui/index.html +16 -0
  250. package/dist/mailroom/attention.js +167 -0
  251. package/dist/mailroom/autonomy.js +209 -0
  252. package/dist/mailroom/blob-store.js +715 -0
  253. package/dist/mailroom/body-cache.js +61 -0
  254. package/dist/mailroom/core.js +788 -0
  255. package/dist/mailroom/entry.js +160 -0
  256. package/dist/mailroom/file-store.js +568 -0
  257. package/dist/mailroom/mbox-import.js +393 -0
  258. package/dist/mailroom/migration.js +164 -0
  259. package/dist/mailroom/outbound.js +380 -0
  260. package/dist/mailroom/policy.js +263 -0
  261. package/dist/mailroom/reader.js +233 -0
  262. package/dist/mailroom/search-cache.js +334 -0
  263. package/dist/mailroom/search-relevance.js +319 -0
  264. package/dist/mailroom/smtp-ingress.js +176 -0
  265. package/dist/mailroom/source-state.js +176 -0
  266. package/dist/mailroom/thread.js +109 -0
  267. package/dist/mailroom/travel-extract.js +89 -0
  268. package/dist/mind/bundle-manifest.js +24 -2
  269. package/dist/mind/context.js +273 -111
  270. package/dist/mind/desk-section.js +362 -0
  271. package/dist/mind/diary-integrity.js +60 -0
  272. package/dist/mind/{memory.js → diary.js} +68 -77
  273. package/dist/mind/embedding-provider.js +60 -0
  274. package/dist/mind/file-state.js +179 -0
  275. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  276. package/dist/mind/obligation-steering.js +227 -0
  277. package/dist/mind/pending.js +13 -8
  278. package/dist/mind/prompt-budget.js +479 -0
  279. package/dist/mind/prompt-refresh.js +3 -2
  280. package/dist/mind/prompt.js +1058 -172
  281. package/dist/mind/provenance-trust.js +26 -0
  282. package/dist/mind/record-paths.js +312 -0
  283. package/dist/mind/scrutiny.js +173 -0
  284. package/dist/mind/session-transaction.js +379 -0
  285. package/dist/nerves/cli-logging.js +7 -1
  286. package/dist/nerves/coverage/audit-rules.js +15 -6
  287. package/dist/nerves/coverage/audit.js +28 -2
  288. package/dist/nerves/coverage/cli.js +1 -1
  289. package/dist/nerves/coverage/contract.js +5 -5
  290. package/dist/nerves/coverage/file-completeness.js +139 -5
  291. package/dist/nerves/coverage/run-artifacts.js +55 -35
  292. package/dist/nerves/event-buffer.js +111 -0
  293. package/dist/nerves/index.js +234 -4
  294. package/dist/nerves/observation.js +20 -0
  295. package/dist/nerves/redact.js +79 -0
  296. package/dist/nerves/review/cli-main.js +5 -0
  297. package/dist/nerves/review/cli.js +156 -0
  298. package/dist/nerves/review/core.js +159 -0
  299. package/dist/nerves/runtime.js +5 -1
  300. package/dist/repertoire/ado-client.js +15 -56
  301. package/dist/repertoire/ado-semantic.js +16 -10
  302. package/dist/repertoire/api-client.js +97 -0
  303. package/dist/repertoire/bitwarden-store.js +1045 -0
  304. package/dist/repertoire/bundle-templates.js +71 -0
  305. package/dist/repertoire/bw-installer.js +180 -0
  306. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  307. package/dist/repertoire/coding/context-pack.js +331 -0
  308. package/dist/repertoire/coding/feedback.js +218 -30
  309. package/dist/repertoire/coding/index.js +15 -3
  310. package/dist/repertoire/coding/manager.js +166 -10
  311. package/dist/repertoire/coding/spawner.js +58 -11
  312. package/dist/repertoire/coding/tools.js +242 -14
  313. package/dist/repertoire/coding/workbench-client.js +272 -0
  314. package/dist/repertoire/coding/workbench-manager.js +346 -0
  315. package/dist/repertoire/commerce-errors.js +109 -0
  316. package/dist/repertoire/commerce-self-test.js +156 -0
  317. package/dist/repertoire/credential-access.js +178 -0
  318. package/dist/repertoire/desk/classifier.js +362 -0
  319. package/dist/repertoire/duffel-client.js +185 -0
  320. package/dist/repertoire/github-client.js +14 -55
  321. package/dist/repertoire/graph-client.js +11 -52
  322. package/dist/repertoire/guardrails.js +138 -18
  323. package/dist/repertoire/mcp-client.js +44 -3
  324. package/dist/repertoire/mcp-manager.js +259 -20
  325. package/dist/repertoire/mcp-tools.js +83 -0
  326. package/dist/repertoire/plugin-mcp.js +175 -0
  327. package/dist/repertoire/plugins.js +253 -0
  328. package/dist/repertoire/shell-sessions.js +133 -0
  329. package/dist/repertoire/skills.js +48 -4
  330. package/dist/repertoire/stripe-client.js +131 -0
  331. package/dist/repertoire/tool-arguments.js +104 -0
  332. package/dist/repertoire/tool-results.js +29 -0
  333. package/dist/repertoire/tools-a2a.js +699 -0
  334. package/dist/repertoire/tools-attachments.js +317 -0
  335. package/dist/repertoire/tools-awaiting.js +372 -0
  336. package/dist/repertoire/tools-base.js +67 -1095
  337. package/dist/repertoire/tools-bluebubbles.js +2 -0
  338. package/dist/repertoire/tools-bridge.js +144 -0
  339. package/dist/repertoire/tools-bundle.js +993 -0
  340. package/dist/repertoire/tools-commerce.js +253 -0
  341. package/dist/repertoire/tools-config.js +186 -0
  342. package/dist/repertoire/tools-continuity.js +252 -0
  343. package/dist/repertoire/tools-credential.js +383 -0
  344. package/dist/repertoire/tools-evolution.js +527 -0
  345. package/dist/repertoire/tools-files.js +344 -0
  346. package/dist/repertoire/tools-flight.js +290 -0
  347. package/dist/repertoire/tools-flow.js +119 -0
  348. package/dist/repertoire/tools-github.js +3 -8
  349. package/dist/repertoire/tools-habits.js +103 -0
  350. package/dist/repertoire/tools-mail.js +1975 -0
  351. package/dist/repertoire/tools-notes.js +459 -0
  352. package/dist/repertoire/tools-obligations.js +182 -0
  353. package/dist/repertoire/tools-orientation.js +31 -0
  354. package/dist/repertoire/tools-record.js +482 -0
  355. package/dist/repertoire/tools-rsvp.js +139 -0
  356. package/dist/repertoire/tools-runtime.js +150 -0
  357. package/dist/repertoire/tools-session.js +881 -0
  358. package/dist/repertoire/tools-shell.js +133 -0
  359. package/dist/repertoire/tools-stripe.js +224 -0
  360. package/dist/repertoire/tools-surface.js +355 -0
  361. package/dist/repertoire/tools-teams.js +12 -39
  362. package/dist/repertoire/tools-travel.js +125 -0
  363. package/dist/repertoire/tools-trip.js +982 -0
  364. package/dist/repertoire/tools-user-profile.js +146 -0
  365. package/dist/repertoire/tools-vault.js +40 -0
  366. package/dist/repertoire/tools-voice.js +145 -0
  367. package/dist/repertoire/tools.js +258 -79
  368. package/dist/repertoire/travel-api-client.js +360 -0
  369. package/dist/repertoire/user-profile.js +131 -0
  370. package/dist/repertoire/vault-setup.js +246 -0
  371. package/dist/repertoire/vault-unlock.js +594 -0
  372. package/dist/rsvp/aisleplanner-client.js +354 -0
  373. package/dist/rsvp/cli.js +926 -0
  374. package/dist/rsvp/config.js +327 -0
  375. package/dist/rsvp/cutover.js +433 -0
  376. package/dist/rsvp/diagnostics.js +232 -0
  377. package/dist/rsvp/diff-renderer.js +176 -0
  378. package/dist/rsvp/habit-policy.js +110 -0
  379. package/dist/rsvp/habit-stage.js +123 -0
  380. package/dist/rsvp/incident-bundle.js +97 -0
  381. package/dist/rsvp/migration.js +204 -0
  382. package/dist/rsvp/native-habit-runner.js +630 -0
  383. package/dist/rsvp/outbound-state.js +628 -0
  384. package/dist/rsvp/query.js +118 -0
  385. package/dist/rsvp/replay.js +233 -0
  386. package/dist/rsvp/snapshot.js +232 -0
  387. package/dist/rsvp/spend-ledger.js +175 -0
  388. package/dist/scripts/claude-code-hook.js +41 -0
  389. package/dist/scripts/claude-code-stop-hook.js +47 -0
  390. package/dist/senses/a2a-entry.js +115 -0
  391. package/dist/senses/attention-queue.js +186 -0
  392. package/dist/senses/await-turn-message.js +58 -0
  393. package/dist/senses/bluebubbles/active-turns.js +216 -0
  394. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  395. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  396. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  397. package/dist/senses/bluebubbles/context-packet.js +207 -0
  398. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  399. package/dist/senses/bluebubbles/entry.js +90 -0
  400. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  401. package/dist/senses/bluebubbles/index.js +3839 -0
  402. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  403. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  404. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  405. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  406. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  407. package/dist/senses/bluebubbles/processed-log.js +133 -0
  408. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  409. package/dist/senses/bluebubbles/replay.js +284 -0
  410. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  411. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  412. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  413. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  414. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  415. package/dist/senses/cli/bracketed-paste.js +82 -0
  416. package/dist/senses/cli/image-paste.js +287 -0
  417. package/dist/senses/cli/image-ref-navigation.js +75 -0
  418. package/dist/senses/cli/ink-app.js +156 -0
  419. package/dist/senses/cli/inline-diff.js +64 -0
  420. package/dist/senses/cli/input-keys.js +174 -0
  421. package/dist/senses/cli/kill-ring.js +86 -0
  422. package/dist/senses/cli/message-list.js +51 -0
  423. package/dist/senses/cli/ouro-tui.js +607 -0
  424. package/dist/senses/cli/spinner-imperative.js +135 -0
  425. package/dist/senses/cli/spinner.js +101 -0
  426. package/dist/senses/cli/status-line.js +60 -0
  427. package/dist/senses/cli/streaming-markdown.js +526 -0
  428. package/dist/senses/cli/tool-display.js +85 -0
  429. package/dist/senses/cli/tool-render.js +85 -0
  430. package/dist/senses/cli/tui-store.js +241 -0
  431. package/dist/senses/cli/virtual-list.js +35 -0
  432. package/dist/senses/cli-entry.js +60 -8
  433. package/dist/senses/cli-layout.js +100 -0
  434. package/dist/senses/cli.js +640 -312
  435. package/dist/senses/commands.js +66 -3
  436. package/dist/senses/context-packet-ledger.js +371 -0
  437. package/dist/senses/context-packets.js +154 -0
  438. package/dist/senses/habit-lifecycle-guard.js +24 -0
  439. package/dist/senses/habit-turn-message.js +160 -0
  440. package/dist/senses/ingress-evidence.js +2 -0
  441. package/dist/senses/mail-entry.js +66 -0
  442. package/dist/senses/mail.js +524 -0
  443. package/dist/senses/pipeline.js +1075 -176
  444. package/dist/senses/private-runtime-worker.js +740 -0
  445. package/dist/senses/private-runtime.js +1212 -0
  446. package/dist/senses/proactive-content-guard.js +51 -0
  447. package/dist/senses/shared-turn.js +424 -0
  448. package/dist/senses/surface-tool.js +109 -0
  449. package/dist/senses/teams-entry.js +60 -8
  450. package/dist/senses/teams.js +515 -217
  451. package/dist/senses/trust-gate.js +104 -9
  452. package/dist/senses/voice/audio-playback.js +237 -0
  453. package/dist/senses/voice/audio-routing.js +119 -0
  454. package/dist/senses/voice/elevenlabs.js +202 -0
  455. package/dist/senses/voice/floor-control.js +431 -0
  456. package/dist/senses/voice/floor-controller.js +115 -0
  457. package/dist/senses/voice/golden-path.js +116 -0
  458. package/dist/senses/voice/index.js +29 -0
  459. package/dist/senses/voice/meeting.js +113 -0
  460. package/dist/senses/voice/outbound.js +190 -0
  461. package/dist/senses/voice/phone.js +33 -0
  462. package/dist/senses/voice/playback.js +139 -0
  463. package/dist/senses/voice/realtime-eval.js +496 -0
  464. package/dist/senses/voice/realtime-trace.js +531 -0
  465. package/dist/senses/voice/transcript.js +70 -0
  466. package/dist/senses/voice/turn.js +191 -0
  467. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  468. package/dist/senses/voice/twilio-phone.js +5081 -0
  469. package/dist/senses/voice/types.js +2 -0
  470. package/dist/senses/voice/whisper.js +161 -0
  471. package/dist/senses/voice-entry.js +81 -0
  472. package/dist/senses/voice-realtime-eval-command.js +99 -0
  473. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  474. package/dist/senses/voice-twilio-entry.js +87 -0
  475. package/dist/trips/core.js +138 -0
  476. package/dist/trips/store.js +265 -0
  477. package/dist/util/frontmatter.js +69 -0
  478. package/package.json +65 -12
  479. package/skills/agent-commerce.md +113 -0
  480. package/skills/browser-navigation.md +117 -0
  481. package/skills/commerce-setup-guide.md +116 -0
  482. package/skills/commerce-setup.md +84 -0
  483. package/skills/configure-dev-tools.md +99 -0
  484. package/skills/travel-planning.md +138 -0
  485. package/dist/heart/daemon/auth-flow.js +0 -430
  486. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  487. package/dist/heart/daemon/update-hooks.js +0 -138
  488. package/dist/heart/safe-workspace.js +0 -228
  489. package/dist/heart/session-recall.js +0 -116
  490. package/dist/mind/friends/channel.js +0 -84
  491. package/dist/mind/friends/group-context.js +0 -144
  492. package/dist/mind/friends/resolver.js +0 -84
  493. package/dist/mind/friends/store-file.js +0 -190
  494. package/dist/mind/friends/store.js +0 -4
  495. package/dist/mind/friends/tokens.js +0 -26
  496. package/dist/mind/friends/trust-explanation.js +0 -74
  497. package/dist/mind/friends/types.js +0 -29
  498. package/dist/repertoire/tasks/board.js +0 -134
  499. package/dist/repertoire/tasks/index.js +0 -224
  500. package/dist/repertoire/tasks/lifecycle.js +0 -80
  501. package/dist/repertoire/tasks/middleware.js +0 -65
  502. package/dist/repertoire/tasks/parser.js +0 -173
  503. package/dist/repertoire/tasks/scanner.js +0 -132
  504. package/dist/repertoire/tasks/transitions.js +0 -144
  505. package/dist/senses/bluebubbles-entry.js +0 -13
  506. package/dist/senses/bluebubbles.js +0 -1180
  507. package/dist/senses/debug-activity.js +0 -148
  508. package/dist/senses/inner-dialog-worker.js +0 -90
  509. package/dist/senses/inner-dialog.js +0 -480
  510. package/subagents/README.md +0 -7
  511. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  512. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  513. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  514. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  515. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  516. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  517. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  518. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  519. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  520. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  521. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  522. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  523. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  524. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  525. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  526. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  527. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pruneDaemonLogs = pruneDaemonLogs;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const crypto_1 = require("crypto");
7
+ const nerves_1 = require("../../nerves");
8
+ const runtime_1 = require("../../nerves/runtime");
9
+ const identity_1 = require("../identity");
10
+ function isActiveLogStream(name) {
11
+ if (name.endsWith(".ndjson")) {
12
+ return !/\.\d+\.ndjson$/.test(name);
13
+ }
14
+ if (name.endsWith(".log")) {
15
+ return !/\.\d+\.log$/.test(name);
16
+ }
17
+ return false;
18
+ }
19
+ function pruneDaemonLogs(options = {}) {
20
+ /* v8 ignore next -- defensive: tests always pass logsDir to avoid prod paths @preserve */
21
+ const logsDir = options.logsDir ?? (0, identity_1.getAgentDaemonLogsDir)(options.agentName);
22
+ const maxSizeBytes = options.maxSizeBytes ?? nerves_1.DEFAULT_MAX_LOG_SIZE_BYTES;
23
+ const maxGenerations = options.maxGenerations ?? nerves_1.DEFAULT_MAX_GENERATIONS;
24
+ const traceId = (0, crypto_1.randomUUID)();
25
+ (0, runtime_1.emitNervesEvent)({
26
+ component: "nerves",
27
+ event: "nerves.logs_prune_start",
28
+ trace_id: traceId,
29
+ message: "pruning daemon logs",
30
+ meta: { logsDir, maxSizeBytes, maxGenerations },
31
+ });
32
+ let completed = false;
33
+ try {
34
+ if (!(0, fs_1.existsSync)(logsDir)) {
35
+ completed = true;
36
+ (0, runtime_1.emitNervesEvent)({
37
+ component: "nerves",
38
+ event: "nerves.logs_prune_end",
39
+ trace_id: traceId,
40
+ message: "daemon logs dir does not exist",
41
+ meta: { logsDir, filesCompacted: 0, bytesFreed: 0 },
42
+ });
43
+ return { filesCompacted: 0, bytesFreed: 0 };
44
+ }
45
+ let filesCompacted = 0;
46
+ let bytesFreed = 0;
47
+ // Enumerate and rotate each active structured stream plus legacy launchd
48
+ // .log streams. We explicitly skip .gz and other files — only the active
49
+ // stream can be a rotation candidate. Legacy generation files are handled
50
+ // inside rotateIfNeeded's generation-shift step, so we skip them here to
51
+ // avoid double-rotating.
52
+ for (const name of (0, fs_1.readdirSync)(logsDir)) {
53
+ if (!isActiveLogStream(name))
54
+ continue;
55
+ const filePath = (0, path_1.join)(logsDir, name);
56
+ let sizeBefore;
57
+ try {
58
+ sizeBefore = (0, fs_1.statSync)(filePath).size;
59
+ /* v8 ignore start -- defensive: file disappears between readdir and stat @preserve */
60
+ }
61
+ catch {
62
+ continue;
63
+ }
64
+ /* v8 ignore stop */
65
+ if (sizeBefore < maxSizeBytes)
66
+ continue;
67
+ // rotateIfNeeded returns true because we pre-checked sizeBefore >=
68
+ // maxSizeBytes above. The false branch of `if (rotated)` is defensive
69
+ // and unreachable under normal flow; we skip it from coverage so a
70
+ // future refactor that weakens the pre-check still reports correct
71
+ // counts without needing a contrived test.
72
+ const rotated = (0, nerves_1.rotateIfNeeded)(filePath, {
73
+ maxSizeBytes,
74
+ maxGenerations,
75
+ compress: true,
76
+ });
77
+ /* v8 ignore next 3 -- defensive: pre-check guarantees rotated=true @preserve */
78
+ if (!rotated) {
79
+ continue;
80
+ }
81
+ filesCompacted += 1;
82
+ bytesFreed += sizeBefore;
83
+ }
84
+ completed = true;
85
+ (0, runtime_1.emitNervesEvent)({
86
+ component: "nerves",
87
+ event: "nerves.logs_prune_end",
88
+ trace_id: traceId,
89
+ message: "daemon logs pruned",
90
+ meta: { logsDir, filesCompacted, bytesFreed },
91
+ });
92
+ return { filesCompacted, bytesFreed };
93
+ }
94
+ catch (err) {
95
+ /* v8 ignore next -- defensive: completed=true only reached after try returns @preserve */
96
+ if (!completed) {
97
+ /* v8 ignore next -- defensive: rotation always throws real Errors @preserve */
98
+ const reason = err instanceof Error ? err.message : String(err);
99
+ (0, runtime_1.emitNervesEvent)({
100
+ component: "nerves",
101
+ event: "nerves.logs_prune_error",
102
+ trace_id: traceId,
103
+ level: "error",
104
+ message: "daemon logs prune failed",
105
+ meta: { logsDir, error: reason },
106
+ });
107
+ }
108
+ throw err;
109
+ }
110
+ }
@@ -0,0 +1,524 @@
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.SETUP_CANARY_TIMEOUT_MS = exports.DEFAULT_CANARY_TIMEOUT_MS = void 0;
37
+ exports.classifyMcpBoundary = classifyMcpBoundary;
38
+ exports.sanitizeMcpCanaryText = sanitizeMcpCanaryText;
39
+ exports.sanitizeMcpCanaryArgs = sanitizeMcpCanaryArgs;
40
+ exports.buildMcpBridgeRepairGuidance = buildMcpBridgeRepairGuidance;
41
+ exports.formatMcpBridgeRepairDetails = formatMcpBridgeRepairDetails;
42
+ exports.buildMcpDoctorNextSteps = buildMcpDoctorNextSteps;
43
+ exports.formatMcpDoctorNextStepDetails = formatMcpDoctorNextStepDetails;
44
+ exports.parseMcpStatusText = parseMcpStatusText;
45
+ exports.runMcpStatusCanary = runMcpStatusCanary;
46
+ exports.formatMcpStatusCanaryResult = formatMcpStatusCanaryResult;
47
+ exports.formatMcpStatusDoctorResult = formatMcpStatusDoctorResult;
48
+ exports.createMcpStatusCanaryProbe = createMcpStatusCanaryProbe;
49
+ const child_process_1 = require("child_process");
50
+ const path = __importStar(require("path"));
51
+ const runtime_1 = require("../../nerves/runtime");
52
+ exports.DEFAULT_CANARY_TIMEOUT_MS = 60_000;
53
+ exports.SETUP_CANARY_TIMEOUT_MS = 10_000;
54
+ const MCP_PROTOCOL_VERSION = "2024-11-05";
55
+ function classifyMcpBoundary(input) {
56
+ if (!input.bridgeHealthy)
57
+ return "ouro-bridge-failed";
58
+ return input.hostStallObserved ? "host-stall-unexplained" : "ouro-bridge-healthy-at-capture";
59
+ }
60
+ function sanitizeMcpCanaryText(text) {
61
+ return text
62
+ .replace(/(https?:\/\/[^\s?]+)\?[^\s]*/g, "$1?[redacted]")
63
+ .replace(/"(?:password|token|secret|api[_-]?key)"\s*:\s*"[^"]*"/gi, '"credential":"[redacted]"')
64
+ .replace(/\bBearer\s+[^\s]+/gi, "Bearer [redacted]")
65
+ .replace(/--(?:password|token|secret|api[_-]?key)(\s+|=)[^\s]+/gi, "--credential$1[redacted]")
66
+ .replace(/\b(?:password|token|secret|api[_-]?key)=([^\s]+)/gi, "credential=[redacted]")
67
+ .trim();
68
+ }
69
+ function sanitizeMcpCanaryArgs(args) {
70
+ const sanitized = [];
71
+ let redactNext = false;
72
+ for (const arg of args) {
73
+ if (redactNext) {
74
+ sanitized.push("[redacted]");
75
+ redactNext = false;
76
+ continue;
77
+ }
78
+ if (/^--(?:password|token|secret|api[_-]?key)$/i.test(arg)) {
79
+ sanitized.push("--credential");
80
+ redactNext = true;
81
+ continue;
82
+ }
83
+ sanitized.push(sanitizeMcpCanaryText(arg));
84
+ }
85
+ return sanitized;
86
+ }
87
+ function defaultCommandArgs(agent, socketPath) {
88
+ const entryPath = path.join(__dirname, "ouro-bot-entry.js");
89
+ return [
90
+ entryPath,
91
+ "mcp-serve",
92
+ "--agent",
93
+ agent,
94
+ ...(socketPath ? ["--socket", socketPath] : []),
95
+ ];
96
+ }
97
+ function isRecord(value) {
98
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
99
+ }
100
+ function requireInitializeResult(response) {
101
+ if (!isRecord(response.result)) {
102
+ throw new Error("MCP canary received invalid initialize result");
103
+ }
104
+ }
105
+ function requireStatusText(response) {
106
+ if (!isRecord(response.result)) {
107
+ throw new Error("MCP canary received invalid status result");
108
+ }
109
+ if (response.result.isError === true) {
110
+ const errorContent = response.result.content;
111
+ const errorFirst = Array.isArray(errorContent) ? errorContent[0] : undefined;
112
+ const errorText = isRecord(errorFirst) && typeof errorFirst.text === "string"
113
+ ? errorFirst.text
114
+ : "MCP status tool returned an error";
115
+ throw new Error(errorText);
116
+ }
117
+ const content = response.result.content;
118
+ const first = Array.isArray(content) ? content[0] : undefined;
119
+ if (!isRecord(first) || typeof first.text !== "string") {
120
+ throw new Error("MCP canary received invalid status result");
121
+ }
122
+ return first.text;
123
+ }
124
+ function parseFields(line) {
125
+ const parsed = {};
126
+ for (const segment of line.split("\t")) {
127
+ const idx = segment.indexOf("=");
128
+ if (idx <= 0)
129
+ continue;
130
+ parsed[segment.slice(0, idx)] = segment.slice(idx + 1);
131
+ }
132
+ return parsed;
133
+ }
134
+ function shellArg(value) {
135
+ return /^[A-Za-z0-9._/-]+$/.test(value)
136
+ ? value
137
+ : `'${value.replace(/'/g, "'\\''")}'`;
138
+ }
139
+ function buildMcpBridgeRepairGuidance(agent) {
140
+ const agentArg = shellArg(agent);
141
+ return {
142
+ actor: "agent-runnable",
143
+ commands: [
144
+ `ouro setup --tool codex --agent ${agentArg}`,
145
+ `ouro setup --tool claude-code --agent ${agentArg}`,
146
+ ],
147
+ reload: "open a fresh dev-tool session after setup; existing MCP processes keep their old runtime",
148
+ verify: `ouro mcp doctor --agent ${agentArg}`,
149
+ };
150
+ }
151
+ function formatMcpBridgeRepairDetails(repair) {
152
+ return [
153
+ `repair actor=${repair.actor}`,
154
+ ...repair.commands.map((command) => `repair command=${command}`),
155
+ `reload required: ${repair.reload}`,
156
+ `verify command=${repair.verify}`,
157
+ ];
158
+ }
159
+ function buildMcpDoctorNextSteps(result, agent) {
160
+ const agentArg = shellArg(agent);
161
+ const text = [result.summary, ...result.details].join("\n");
162
+ const daemonUnreachable = text.includes("daemon=unreachable")
163
+ || text.includes("ECONNREFUSED")
164
+ || text.includes("ENOENT");
165
+ if (daemonUnreachable) {
166
+ return {
167
+ actor: "agent-runnable",
168
+ commands: [
169
+ "ouro up",
170
+ `ouro mcp doctor --agent ${agentArg}`,
171
+ ],
172
+ note: "start or refresh the daemon before trusting bridge status",
173
+ };
174
+ }
175
+ return {
176
+ actor: "agent-runnable",
177
+ commands: [
178
+ "ouro doctor",
179
+ `ouro status --agent ${agentArg}`,
180
+ `ouro repair --agent ${agentArg}`,
181
+ `ouro mcp doctor --agent ${agentArg}`,
182
+ ],
183
+ note: "fix reported daemon or sense health before rerunning bridge registration repair",
184
+ };
185
+ }
186
+ function formatMcpDoctorNextStepDetails(nextSteps) {
187
+ return [
188
+ `next actor=${nextSteps.actor}`,
189
+ ...nextSteps.commands.map((command) => `next command=${command}`),
190
+ `next note=${nextSteps.note}`,
191
+ ];
192
+ }
193
+ function parseMcpStatusText(text) {
194
+ const daemon = {};
195
+ const senses = {};
196
+ for (const line of text.split(/\r?\n/)) {
197
+ const trimmed = line.trim();
198
+ if (!trimmed)
199
+ continue;
200
+ if (trimmed.startsWith("daemon=")) {
201
+ Object.assign(daemon, parseFields(trimmed));
202
+ continue;
203
+ }
204
+ if (!trimmed.startsWith("sense="))
205
+ continue;
206
+ const fields = parseFields(trimmed);
207
+ const sense = fields.sense;
208
+ if (!sense)
209
+ continue;
210
+ const [name, status = "unknown"] = sense.split(":");
211
+ senses[name] = { ...fields, name, status };
212
+ }
213
+ return { daemon, senses, raw: text };
214
+ }
215
+ function validateMcpStatus(parsed, requiredSenses, options = {}) {
216
+ const failures = [];
217
+ if (parsed.daemon.daemon !== "running") {
218
+ failures.push(`daemon=${parsed.daemon.daemon ?? "missing"}`);
219
+ }
220
+ if (!options.ignoreOverviewHealth && parsed.daemon.health !== "ok") {
221
+ failures.push(`health=${parsed.daemon.health ?? "missing"}`);
222
+ }
223
+ const hasVersionMismatch = !!(parsed.daemon.daemonVersion &&
224
+ parsed.daemon.mcpVersion &&
225
+ parsed.daemon.daemonVersion !== parsed.daemon.mcpVersion);
226
+ if (hasVersionMismatch) {
227
+ failures.push(`version mismatch daemon=${parsed.daemon.daemonVersion} mcp=${parsed.daemon.mcpVersion}`);
228
+ }
229
+ if (!options.ignoreSenseHealth) {
230
+ for (const [sense, row] of Object.entries(parsed.senses)) {
231
+ if (row.status === "disabled")
232
+ continue;
233
+ if (row.status === "running" || row.status === "interactive")
234
+ continue;
235
+ failures.push(`sense=${sense}:${row.status}`);
236
+ }
237
+ }
238
+ for (const sense of requiredSenses) {
239
+ const row = parsed.senses[sense];
240
+ if (!row) {
241
+ failures.push(`required sense missing: ${sense}`);
242
+ continue;
243
+ }
244
+ if (row.status !== "running" && row.status !== "interactive") {
245
+ failures.push(`required sense unhealthy: ${sense}:${row.status}`);
246
+ }
247
+ }
248
+ const senseSummary = Object.values(parsed.senses)
249
+ .map((row) => `${row.name}:${row.status}`)
250
+ .join(",");
251
+ const summary = failures.length === 0
252
+ ? `mcp canary ok: daemon=${parsed.daemon.daemon} health=${parsed.daemon.health}${options.ignoreOverviewHealth ? " (overview ignored)" : ""} senses=${senseSummary}${options.ignoreSenseHealth ? " (sense health reported, not gated)" : ""}`
253
+ : `mcp canary failed: ${failures.join("; ")}`;
254
+ const repair = hasVersionMismatch && options.agent
255
+ ? buildMcpBridgeRepairGuidance(options.agent)
256
+ : undefined;
257
+ const repairDetails = repair ? formatMcpBridgeRepairDetails(repair) : [];
258
+ return {
259
+ ok: failures.length === 0,
260
+ summary,
261
+ details: failures.length === 0 ? [parsed.raw] : [...failures, ...repairDetails, parsed.raw],
262
+ parsed,
263
+ ...(repair ? { repair } : {}),
264
+ };
265
+ }
266
+ async function runMcpStatusCanary(options) {
267
+ const startedAt = Date.now();
268
+ const timeoutMs = options.timeoutMs ?? exports.DEFAULT_CANARY_TIMEOUT_MS;
269
+ const deadlineAt = startedAt + timeoutMs;
270
+ const evidence = {
271
+ capturedAt: new Date(startedAt).toISOString(),
272
+ durationMs: 0,
273
+ childPid: null,
274
+ phase: "spawn",
275
+ exitCode: null,
276
+ exitSignal: null,
277
+ stderr: "",
278
+ };
279
+ const decorate = (result, bridgeHealthy = false) => ({
280
+ ...result,
281
+ classification: classifyMcpBoundary({ bridgeHealthy, hostStallObserved: options.hostStallObserved === true }),
282
+ evidence,
283
+ });
284
+ /* v8 ignore next -- default spawn is exercised by live canaries, while unit tests inject a fake child @preserve */
285
+ const spawnImpl = options.spawnImpl ?? child_process_1.spawn;
286
+ const command = options.command ?? process.execPath;
287
+ const commandArgs = options.commandArgs ?? defaultCommandArgs(options.agent, options.socketPath);
288
+ const requiredSenses = options.requiredSenses ?? [];
289
+ (0, runtime_1.emitNervesEvent)({
290
+ component: "daemon",
291
+ event: "daemon.mcp_canary_start",
292
+ message: "starting MCP status canary",
293
+ meta: {
294
+ agent: options.agent,
295
+ command,
296
+ commandArgs: sanitizeMcpCanaryArgs(commandArgs),
297
+ timeoutMs,
298
+ requiredSenses,
299
+ ignoreOverviewHealth: options.ignoreOverviewHealth === true,
300
+ ignoreSenseHealth: options.ignoreSenseHealth === true,
301
+ },
302
+ });
303
+ let child;
304
+ try {
305
+ child = spawnImpl(command, commandArgs, { stdio: ["pipe", "pipe", "pipe"] });
306
+ evidence.childPid = child.pid ?? null;
307
+ }
308
+ catch (error) {
309
+ const reason = sanitizeMcpCanaryText(error instanceof Error ? error.message : String(error));
310
+ evidence.durationMs = Date.now() - startedAt;
311
+ (0, runtime_1.emitNervesEvent)({
312
+ component: "daemon",
313
+ event: "daemon.mcp_canary_error",
314
+ level: "error",
315
+ message: "MCP status canary failed to spawn",
316
+ meta: { agent: options.agent, reason },
317
+ });
318
+ return decorate({ ok: false, summary: `mcp canary failed: ${reason}`, details: [reason] });
319
+ }
320
+ let buffer = "";
321
+ let stderr = "";
322
+ const pending = new Map();
323
+ let resolveExit;
324
+ const exitObserved = new Promise((resolve) => { resolveExit = resolve; });
325
+ function safeStderr() {
326
+ return sanitizeMcpCanaryText(stderr);
327
+ }
328
+ function cleanup() {
329
+ for (const [, request] of pending) {
330
+ clearTimeout(request.timer);
331
+ }
332
+ pending.clear();
333
+ if (!child.killed)
334
+ child.kill();
335
+ }
336
+ function failAll(error) {
337
+ for (const [, request] of pending) {
338
+ clearTimeout(request.timer);
339
+ request.reject(error);
340
+ }
341
+ pending.clear();
342
+ }
343
+ child.stderr?.setEncoding("utf8");
344
+ child.stderr?.on("data", (chunk) => {
345
+ stderr += chunk.toString();
346
+ });
347
+ child.stdout?.setEncoding("utf8");
348
+ child.stdout?.on("data", (chunk) => {
349
+ buffer += chunk.toString();
350
+ for (;;) {
351
+ const idx = buffer.indexOf("\n");
352
+ if (idx === -1)
353
+ break;
354
+ const line = buffer.slice(0, idx).trim();
355
+ buffer = buffer.slice(idx + 1);
356
+ if (!line)
357
+ continue;
358
+ let parsedResponse;
359
+ try {
360
+ parsedResponse = JSON.parse(line);
361
+ }
362
+ catch {
363
+ failAll(new Error(`MCP canary received malformed JSON: ${line}`));
364
+ return;
365
+ }
366
+ if (!isRecord(parsedResponse)) {
367
+ failAll(new Error("MCP canary received malformed JSON-RPC response"));
368
+ return;
369
+ }
370
+ const response = parsedResponse;
371
+ const id = typeof response.id === "number" ? response.id : null;
372
+ if (id === null)
373
+ continue;
374
+ const request = pending.get(id);
375
+ if (!request)
376
+ continue;
377
+ pending.delete(id);
378
+ clearTimeout(request.timer);
379
+ const hasResult = Object.prototype.hasOwnProperty.call(response, "result");
380
+ const hasError = Object.prototype.hasOwnProperty.call(response, "error");
381
+ if (response.jsonrpc !== "2.0" || (!hasResult && !hasError)) {
382
+ request.reject(new Error("MCP canary received malformed JSON-RPC response"));
383
+ continue;
384
+ }
385
+ if (hasError) {
386
+ request.reject(new Error(`MCP canary received JSON-RPC error: ${JSON.stringify(response.error)}`));
387
+ continue;
388
+ }
389
+ request.resolve(response);
390
+ }
391
+ });
392
+ child.on("error", (error) => failAll(error));
393
+ child.on("close", (code, signal) => {
394
+ evidence.exitCode = code;
395
+ evidence.exitSignal = signal;
396
+ resolveExit();
397
+ if (pending.size === 0)
398
+ return;
399
+ failAll(new Error(`MCP canary process closed before response code=${code} signal=${signal ?? "none"} stderr=${safeStderr()}`));
400
+ });
401
+ let nextId = 1;
402
+ function request(method, params) {
403
+ return new Promise((resolve, reject) => {
404
+ if (!child.stdin?.writable) {
405
+ reject(new Error("MCP canary stdin is not writable"));
406
+ return;
407
+ }
408
+ const remainingMs = deadlineAt - Date.now();
409
+ if (remainingMs <= 0) {
410
+ reject(new Error(`MCP canary timed out waiting for ${method}; stderr=${safeStderr()}`));
411
+ return;
412
+ }
413
+ const id = nextId++;
414
+ const timer = setTimeout(() => {
415
+ pending.delete(id);
416
+ reject(new Error(`MCP canary timed out waiting for ${method}; stderr=${safeStderr()}`));
417
+ }, remainingMs);
418
+ pending.set(id, { resolve, reject, timer });
419
+ child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
420
+ });
421
+ }
422
+ try {
423
+ evidence.phase = "initialize";
424
+ const initializeResponse = await request("initialize", {
425
+ protocolVersion: MCP_PROTOCOL_VERSION,
426
+ capabilities: {},
427
+ clientInfo: { name: "ouro-mcp-canary", version: "1.0" },
428
+ });
429
+ requireInitializeResult(initializeResponse);
430
+ child.stdin?.write(JSON.stringify({ jsonrpc: "2.0", method: "initialized" }) + "\n");
431
+ evidence.phase = "status";
432
+ const statusResponse = await request("tools/call", {
433
+ name: "status",
434
+ arguments: {},
435
+ });
436
+ const statusText = requireStatusText(statusResponse);
437
+ const bridgeHealthy = true;
438
+ const parsed = parseMcpStatusText(sanitizeMcpCanaryText(statusText));
439
+ const canary = validateMcpStatus(parsed, requiredSenses, {
440
+ agent: options.agent,
441
+ ignoreOverviewHealth: options.ignoreOverviewHealth,
442
+ ignoreSenseHealth: options.ignoreSenseHealth,
443
+ });
444
+ evidence.phase = "complete";
445
+ (0, runtime_1.emitNervesEvent)({
446
+ component: "daemon",
447
+ event: canary.ok ? "daemon.mcp_canary_end" : "daemon.mcp_canary_error",
448
+ level: canary.ok ? "info" : "error",
449
+ message: canary.summary,
450
+ meta: { agent: options.agent, ok: canary.ok },
451
+ });
452
+ return decorate(canary, bridgeHealthy);
453
+ }
454
+ catch (error) {
455
+ const reason = sanitizeMcpCanaryText(error instanceof Error ? error.message : String(error));
456
+ (0, runtime_1.emitNervesEvent)({
457
+ component: "daemon",
458
+ event: "daemon.mcp_canary_error",
459
+ level: "error",
460
+ message: "MCP status canary failed",
461
+ meta: { agent: options.agent, reason },
462
+ });
463
+ return decorate({ ok: false, summary: `mcp canary failed: ${reason}`, details: [reason] });
464
+ }
465
+ finally {
466
+ child.stdin?.end();
467
+ cleanup();
468
+ let exitTimer;
469
+ const remainingExitWaitMs = Math.min(100, Math.max(0, deadlineAt - Date.now()));
470
+ await Promise.race([
471
+ exitObserved,
472
+ new Promise((resolve) => { exitTimer = setTimeout(resolve, remainingExitWaitMs); }),
473
+ ]);
474
+ clearTimeout(exitTimer);
475
+ evidence.stderr = safeStderr();
476
+ evidence.durationMs = Date.now() - startedAt;
477
+ }
478
+ }
479
+ function formatMcpStatusCanaryResult(result) {
480
+ return [
481
+ result.ok ? "mcp canary: ok" : "mcp canary: failed",
482
+ ...(result.classification ? [`classification: ${result.classification}`] : []),
483
+ ...(result.evidence ? [
484
+ `captured=${result.evidence.capturedAt} durationMs=${result.evidence.durationMs} childPid=${result.evidence.childPid ?? "none"} phase=${result.evidence.phase} exitCode=${result.evidence.exitCode ?? "none"} exitSignal=${result.evidence.exitSignal ?? "none"}`,
485
+ ...(result.evidence.stderr ? [`stderr=${result.evidence.stderr}`] : []),
486
+ ] : []),
487
+ result.summary,
488
+ ...result.details.map((line) => ` ${line}`),
489
+ ].join("\n");
490
+ }
491
+ function formatMcpStatusDoctorResult(result, agent) {
492
+ const rawDetails = result.details.filter((line) => !line.startsWith("repair ")
493
+ && !line.startsWith("reload required:")
494
+ && !line.startsWith("verify command="));
495
+ const lines = [
496
+ result.ok ? "mcp doctor: ok" : "mcp doctor: failed",
497
+ ...(result.classification ? [`classification: ${result.classification}`] : []),
498
+ ...(result.evidence ? [
499
+ `captured=${result.evidence.capturedAt} durationMs=${result.evidence.durationMs} childPid=${result.evidence.childPid ?? "none"} phase=${result.evidence.phase} exitCode=${result.evidence.exitCode ?? "none"} exitSignal=${result.evidence.exitSignal ?? "none"}`,
500
+ ...(result.evidence.stderr ? [`stderr=${result.evidence.stderr}`] : []),
501
+ ] : []),
502
+ result.summary,
503
+ ...rawDetails.map((line) => ` ${line}`),
504
+ ];
505
+ if (result.ok || result.repair) {
506
+ const repair = result.repair ?? buildMcpBridgeRepairGuidance(agent);
507
+ lines.push("bridge registration path:");
508
+ lines.push(...formatMcpBridgeRepairDetails(repair).map((line) => ` ${line}`));
509
+ }
510
+ else {
511
+ lines.push("next checks:");
512
+ lines.push(...formatMcpDoctorNextStepDetails(buildMcpDoctorNextSteps(result, agent)).map((line) => ` ${line}`));
513
+ }
514
+ return lines.join("\n");
515
+ }
516
+ function createMcpStatusCanaryProbe(options) {
517
+ return {
518
+ name: `mcp-canary:${options.agent}`,
519
+ check: async () => {
520
+ const result = await runMcpStatusCanary(options);
521
+ return { ok: result.ok, detail: result.summary };
522
+ },
523
+ };
524
+ }