@ouro.bot/cli 0.1.0-alpha.53 → 0.1.0-alpha.531

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 (382) hide show
  1. package/README.md +133 -19
  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-bootstrap-drift.md +54 -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/changelog.json +3434 -0
  14. package/dist/arc/attention-types.js +8 -0
  15. package/dist/arc/cares.js +140 -0
  16. package/dist/arc/episodes.js +117 -0
  17. package/dist/arc/intentions.js +133 -0
  18. package/dist/arc/json-store.js +117 -0
  19. package/dist/arc/obligations.js +237 -0
  20. package/dist/arc/packets.js +193 -0
  21. package/dist/arc/presence.js +185 -0
  22. package/dist/arc/task-lifecycle.js +65 -0
  23. package/dist/heart/active-work.js +837 -26
  24. package/dist/heart/agent-entry.js +58 -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/adapter.js +2 -0
  30. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  31. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  32. package/dist/heart/attachments/sources/index.js +16 -0
  33. package/dist/heart/attachments/store.js +103 -0
  34. package/dist/heart/attachments/types.js +93 -0
  35. package/dist/heart/auth/auth-flow.js +427 -0
  36. package/dist/heart/background-operations.js +281 -0
  37. package/dist/heart/bundle-state.js +168 -0
  38. package/dist/heart/commitments.js +111 -0
  39. package/dist/heart/config-registry.js +304 -0
  40. package/dist/heart/config.js +119 -129
  41. package/dist/heart/core.js +948 -243
  42. package/dist/heart/cross-chat-delivery.js +3 -18
  43. package/dist/heart/daemon/agent-config-check.js +512 -0
  44. package/dist/heart/daemon/agent-discovery.js +102 -3
  45. package/dist/heart/daemon/agent-service.js +522 -0
  46. package/dist/heart/daemon/agentic-repair.js +554 -0
  47. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  48. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  49. package/dist/heart/daemon/cadence.js +70 -0
  50. package/dist/heart/daemon/cli-defaults.js +643 -0
  51. package/dist/heart/daemon/cli-exec.js +7544 -0
  52. package/dist/heart/daemon/cli-help.js +498 -0
  53. package/dist/heart/daemon/cli-parse.js +1561 -0
  54. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  55. package/dist/heart/daemon/cli-render.js +728 -0
  56. package/dist/heart/daemon/cli-types.js +8 -0
  57. package/dist/heart/daemon/connect-bay.js +323 -0
  58. package/dist/heart/daemon/daemon-cli.js +29 -1650
  59. package/dist/heart/daemon/daemon-entry.js +384 -2
  60. package/dist/heart/daemon/daemon-health.js +183 -0
  61. package/dist/heart/daemon/daemon-rollup.js +58 -0
  62. package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
  63. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  64. package/dist/heart/daemon/daemon.js +798 -69
  65. package/dist/heart/daemon/dns-workflow.js +394 -0
  66. package/dist/heart/daemon/doctor-types.js +8 -0
  67. package/dist/heart/daemon/doctor.js +844 -0
  68. package/dist/heart/daemon/drift-detection.js +146 -0
  69. package/dist/heart/daemon/health-monitor.js +117 -1
  70. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  71. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  72. package/dist/heart/daemon/http-health-probe.js +80 -0
  73. package/dist/heart/daemon/human-command-screens.js +234 -0
  74. package/dist/heart/daemon/human-readiness.js +114 -0
  75. package/dist/heart/daemon/inner-status.js +102 -0
  76. package/dist/heart/daemon/interactive-repair.js +394 -0
  77. package/dist/heart/daemon/launchd.js +22 -5
  78. package/dist/heart/daemon/log-tailer.js +82 -12
  79. package/dist/heart/daemon/logs-prune.js +110 -0
  80. package/dist/heart/daemon/message-router.js +2 -2
  81. package/dist/heart/daemon/os-cron-deps.js +134 -0
  82. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  83. package/dist/heart/daemon/ouro-entry.js +3 -1
  84. package/dist/heart/daemon/process-manager.js +375 -33
  85. package/dist/heart/daemon/provider-discovery.js +137 -0
  86. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  87. package/dist/heart/daemon/pulse.js +475 -0
  88. package/dist/heart/daemon/readiness-repair.js +365 -0
  89. package/dist/heart/daemon/run-hooks.js +2 -0
  90. package/dist/heart/daemon/runtime-logging.js +67 -16
  91. package/dist/heart/daemon/runtime-metadata.js +73 -0
  92. package/dist/heart/daemon/safe-mode.js +161 -0
  93. package/dist/heart/daemon/sense-manager.js +341 -37
  94. package/dist/heart/daemon/session-id-resolver.js +131 -0
  95. package/dist/heart/daemon/skill-management-installer.js +94 -0
  96. package/dist/heart/daemon/socket-client.js +109 -4
  97. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  98. package/dist/heart/daemon/startup-tui.js +330 -0
  99. package/dist/heart/daemon/task-scheduler.js +3 -25
  100. package/dist/heart/daemon/terminal-ui.js +499 -0
  101. package/dist/heart/daemon/thoughts.js +162 -17
  102. package/dist/heart/daemon/up-progress.js +366 -0
  103. package/dist/heart/daemon/vault-items.js +56 -0
  104. package/dist/heart/delegation.js +1 -1
  105. package/dist/heart/habits/habit-migration.js +189 -0
  106. package/dist/heart/habits/habit-parser.js +140 -0
  107. package/dist/heart/habits/habit-runtime-state.js +100 -0
  108. package/dist/heart/habits/habit-scheduler.js +372 -0
  109. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  110. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  111. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  112. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  113. package/dist/heart/identity.js +205 -66
  114. package/dist/heart/kept-notes.js +357 -0
  115. package/dist/heart/kicks.js +1 -1
  116. package/dist/heart/machine-identity.js +161 -0
  117. package/dist/heart/mail-import-discovery.js +353 -0
  118. package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
  119. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  120. package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
  121. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  122. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  123. package/dist/heart/mailbox/mailbox-http.js +99 -0
  124. package/dist/heart/mailbox/mailbox-read.js +31 -0
  125. package/dist/heart/mailbox/mailbox-types.js +27 -0
  126. package/dist/heart/mailbox/mailbox-view.js +195 -0
  127. package/dist/heart/mailbox/readers/agent-machine.js +382 -0
  128. package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
  129. package/dist/heart/mailbox/readers/mail.js +362 -0
  130. package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
  131. package/dist/heart/mailbox/readers/sessions.js +232 -0
  132. package/dist/heart/mailbox/readers/shared.js +111 -0
  133. package/dist/heart/mcp/mcp-server.js +653 -0
  134. package/dist/heart/migrate-config.js +100 -0
  135. package/dist/heart/model-capabilities.js +19 -0
  136. package/dist/heart/platform.js +81 -0
  137. package/dist/heart/provider-attempt.js +134 -0
  138. package/dist/heart/provider-binding-resolver.js +255 -0
  139. package/dist/heart/provider-credentials.js +425 -0
  140. package/dist/heart/provider-failover.js +301 -0
  141. package/dist/heart/provider-models.js +81 -0
  142. package/dist/heart/provider-ping.js +262 -0
  143. package/dist/heart/provider-state.js +216 -0
  144. package/dist/heart/provider-visibility.js +188 -0
  145. package/dist/heart/providers/anthropic-token.js +131 -0
  146. package/dist/heart/providers/anthropic.js +139 -52
  147. package/dist/heart/providers/azure.js +97 -13
  148. package/dist/heart/providers/error-classification.js +127 -0
  149. package/dist/heart/providers/github-copilot.js +145 -0
  150. package/dist/heart/providers/minimax-vlm.js +189 -0
  151. package/dist/heart/providers/minimax.js +26 -8
  152. package/dist/heart/providers/openai-codex.js +55 -40
  153. package/dist/heart/runtime-capability-check.js +170 -0
  154. package/dist/heart/runtime-credentials.js +367 -0
  155. package/dist/heart/sense-truth.js +11 -4
  156. package/dist/heart/session-activity.js +43 -22
  157. package/dist/heart/session-events.js +1149 -0
  158. package/dist/heart/session-playback-cli-main.js +5 -0
  159. package/dist/heart/session-playback-cli.js +36 -0
  160. package/dist/heart/session-playback.js +231 -0
  161. package/dist/heart/session-stats-cli-main.js +5 -0
  162. package/dist/heart/session-stats.js +182 -0
  163. package/dist/heart/session-transcript.js +243 -0
  164. package/dist/heart/start-of-turn-packet.js +345 -0
  165. package/dist/heart/streaming.js +44 -27
  166. package/dist/heart/sync-classification.js +176 -0
  167. package/dist/heart/sync.js +449 -0
  168. package/dist/heart/target-resolution.js +9 -5
  169. package/dist/heart/tempo.js +93 -0
  170. package/dist/heart/temporal-view.js +41 -0
  171. package/dist/heart/timeouts.js +101 -0
  172. package/dist/heart/tool-activity-callbacks.js +59 -0
  173. package/dist/heart/tool-description.js +139 -0
  174. package/dist/heart/tool-friction.js +55 -0
  175. package/dist/heart/tool-loop.js +200 -0
  176. package/dist/heart/turn-context.js +381 -0
  177. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  178. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  179. package/dist/heart/versioning/ouro-path-installer.js +425 -0
  180. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  181. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  182. package/dist/heart/{daemon → versioning}/update-checker.js +5 -1
  183. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  184. package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
  185. package/dist/mailbox-ui/assets/index-Cm51CY9W.js +61 -0
  186. package/dist/mailbox-ui/index.html +15 -0
  187. package/dist/mailroom/attention.js +167 -0
  188. package/dist/mailroom/autonomy.js +209 -0
  189. package/dist/mailroom/blob-store.js +606 -0
  190. package/dist/mailroom/body-cache.js +61 -0
  191. package/dist/mailroom/core.js +672 -0
  192. package/dist/mailroom/entry.js +160 -0
  193. package/dist/mailroom/file-store.js +426 -0
  194. package/dist/mailroom/mbox-import.js +382 -0
  195. package/dist/mailroom/outbound.js +380 -0
  196. package/dist/mailroom/policy.js +263 -0
  197. package/dist/mailroom/reader.js +228 -0
  198. package/dist/mailroom/search-cache.js +182 -0
  199. package/dist/mailroom/search-relevance.js +319 -0
  200. package/dist/mailroom/smtp-ingress.js +176 -0
  201. package/dist/mailroom/source-state.js +176 -0
  202. package/dist/mailroom/thread.js +109 -0
  203. package/dist/mailroom/travel-extract.js +89 -0
  204. package/dist/mind/bundle-manifest.js +7 -1
  205. package/dist/mind/context.js +165 -101
  206. package/dist/mind/diary-integrity.js +60 -0
  207. package/dist/mind/{memory.js → diary.js} +74 -93
  208. package/dist/mind/embedding-provider.js +60 -0
  209. package/dist/mind/file-state.js +179 -0
  210. package/dist/mind/friends/channel.js +30 -0
  211. package/dist/mind/friends/resolver.js +54 -2
  212. package/dist/mind/friends/store-file.js +39 -3
  213. package/dist/mind/friends/types.js +2 -2
  214. package/dist/mind/journal-index.js +161 -0
  215. package/dist/mind/note-search.js +268 -0
  216. package/dist/mind/obligation-steering.js +221 -0
  217. package/dist/mind/pending.js +4 -0
  218. package/dist/mind/prompt-refresh.js +3 -2
  219. package/dist/mind/prompt.js +942 -122
  220. package/dist/mind/provenance-trust.js +26 -0
  221. package/dist/mind/scrutiny.js +173 -0
  222. package/dist/nerves/cli-logging.js +7 -1
  223. package/dist/nerves/coverage/audit-rules.js +15 -6
  224. package/dist/nerves/coverage/audit.js +28 -2
  225. package/dist/nerves/coverage/cli.js +1 -1
  226. package/dist/nerves/coverage/contract.js +5 -5
  227. package/dist/nerves/coverage/file-completeness.js +139 -5
  228. package/dist/nerves/coverage/run-artifacts.js +1 -1
  229. package/dist/nerves/event-buffer.js +111 -0
  230. package/dist/nerves/index.js +224 -4
  231. package/dist/nerves/observation.js +20 -0
  232. package/dist/nerves/redact.js +79 -0
  233. package/dist/nerves/review/cli-main.js +5 -0
  234. package/dist/nerves/review/cli.js +156 -0
  235. package/dist/nerves/review/core.js +152 -0
  236. package/dist/nerves/runtime.js +5 -1
  237. package/dist/repertoire/ado-client.js +15 -56
  238. package/dist/repertoire/ado-semantic.js +11 -10
  239. package/dist/repertoire/api-client.js +97 -0
  240. package/dist/repertoire/bitwarden-store.js +816 -0
  241. package/dist/repertoire/bundle-templates.js +72 -0
  242. package/dist/repertoire/bw-installer.js +180 -0
  243. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  244. package/dist/repertoire/coding/context-pack.js +330 -0
  245. package/dist/repertoire/coding/feedback.js +197 -30
  246. package/dist/repertoire/coding/manager.js +158 -9
  247. package/dist/repertoire/coding/spawner.js +55 -9
  248. package/dist/repertoire/coding/tools.js +170 -7
  249. package/dist/repertoire/commerce-errors.js +109 -0
  250. package/dist/repertoire/commerce-self-test.js +156 -0
  251. package/dist/repertoire/credential-access.js +111 -0
  252. package/dist/repertoire/duffel-client.js +185 -0
  253. package/dist/repertoire/github-client.js +14 -55
  254. package/dist/repertoire/graph-client.js +11 -52
  255. package/dist/repertoire/guardrails.js +396 -0
  256. package/dist/repertoire/mcp-client.js +255 -0
  257. package/dist/repertoire/mcp-manager.js +305 -0
  258. package/dist/repertoire/mcp-tools.js +63 -0
  259. package/dist/repertoire/shell-sessions.js +133 -0
  260. package/dist/repertoire/skills.js +15 -24
  261. package/dist/repertoire/stripe-client.js +131 -0
  262. package/dist/repertoire/tasks/board.js +31 -5
  263. package/dist/repertoire/tasks/fix.js +182 -0
  264. package/dist/repertoire/tasks/index.js +16 -4
  265. package/dist/repertoire/tasks/lifecycle.js +2 -2
  266. package/dist/repertoire/tasks/parser.js +3 -2
  267. package/dist/repertoire/tasks/scanner.js +194 -37
  268. package/dist/repertoire/tasks/transitions.js +16 -78
  269. package/dist/repertoire/tool-results.js +29 -0
  270. package/dist/repertoire/tools-attachments.js +317 -0
  271. package/dist/repertoire/tools-base.js +47 -1075
  272. package/dist/repertoire/tools-bluebubbles.js +1 -0
  273. package/dist/repertoire/tools-bridge.js +142 -0
  274. package/dist/repertoire/tools-bundle.js +984 -0
  275. package/dist/repertoire/tools-config.js +185 -0
  276. package/dist/repertoire/tools-continuity.js +248 -0
  277. package/dist/repertoire/tools-credential.js +381 -0
  278. package/dist/repertoire/tools-files.js +342 -0
  279. package/dist/repertoire/tools-flight.js +224 -0
  280. package/dist/repertoire/tools-flow.js +119 -0
  281. package/dist/repertoire/tools-github.js +1 -7
  282. package/dist/repertoire/tools-mail.js +1477 -0
  283. package/dist/repertoire/tools-notes.js +421 -0
  284. package/dist/repertoire/tools-session.js +750 -0
  285. package/dist/repertoire/tools-shell.js +120 -0
  286. package/dist/repertoire/tools-stripe.js +180 -0
  287. package/dist/repertoire/tools-surface.js +243 -0
  288. package/dist/repertoire/tools-teams.js +9 -39
  289. package/dist/repertoire/tools-travel.js +125 -0
  290. package/dist/repertoire/tools-trip.js +422 -0
  291. package/dist/repertoire/tools-user-profile.js +144 -0
  292. package/dist/repertoire/tools-vault.js +40 -0
  293. package/dist/repertoire/tools.js +108 -100
  294. package/dist/repertoire/travel-api-client.js +360 -0
  295. package/dist/repertoire/user-profile.js +131 -0
  296. package/dist/repertoire/vault-setup.js +246 -0
  297. package/dist/repertoire/vault-unlock.js +561 -0
  298. package/dist/scripts/claude-code-hook.js +41 -0
  299. package/dist/scripts/claude-code-stop-hook.js +47 -0
  300. package/dist/senses/attention-queue.js +116 -0
  301. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  302. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  303. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  304. package/dist/senses/bluebubbles/entry.js +77 -0
  305. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  306. package/dist/senses/bluebubbles/index.js +2236 -0
  307. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  308. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  309. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  310. package/dist/senses/bluebubbles/processed-log.js +111 -0
  311. package/dist/senses/bluebubbles/replay.js +129 -0
  312. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +16 -2
  313. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  314. package/dist/senses/cli/bracketed-paste.js +82 -0
  315. package/dist/senses/cli/image-paste.js +287 -0
  316. package/dist/senses/cli/image-ref-navigation.js +75 -0
  317. package/dist/senses/cli/ink-app.js +156 -0
  318. package/dist/senses/cli/inline-diff.js +64 -0
  319. package/dist/senses/cli/input-keys.js +174 -0
  320. package/dist/senses/cli/kill-ring.js +86 -0
  321. package/dist/senses/cli/message-list.js +51 -0
  322. package/dist/senses/cli/ouro-tui.js +607 -0
  323. package/dist/senses/cli/spinner-imperative.js +135 -0
  324. package/dist/senses/cli/spinner.js +101 -0
  325. package/dist/senses/cli/status-line.js +60 -0
  326. package/dist/senses/cli/streaming-markdown.js +526 -0
  327. package/dist/senses/cli/tool-display.js +85 -0
  328. package/dist/senses/cli/tool-render.js +85 -0
  329. package/dist/senses/cli/tui-store.js +240 -0
  330. package/dist/senses/cli/virtual-list.js +35 -0
  331. package/dist/senses/cli-entry.js +60 -8
  332. package/dist/senses/cli-layout.js +187 -0
  333. package/dist/senses/cli.js +520 -209
  334. package/dist/senses/commands.js +66 -3
  335. package/dist/senses/habit-turn-message.js +108 -0
  336. package/dist/senses/inner-dialog-worker.js +175 -21
  337. package/dist/senses/inner-dialog.js +330 -27
  338. package/dist/senses/mail-entry.js +66 -0
  339. package/dist/senses/mail.js +379 -0
  340. package/dist/senses/pipeline.js +569 -182
  341. package/dist/senses/proactive-content-guard.js +51 -0
  342. package/dist/senses/shared-turn.js +248 -0
  343. package/dist/senses/surface-tool.js +68 -0
  344. package/dist/senses/teams-entry.js +60 -8
  345. package/dist/senses/teams.js +387 -98
  346. package/dist/senses/trust-gate.js +100 -5
  347. package/dist/trips/core.js +138 -0
  348. package/dist/trips/store.js +146 -0
  349. package/package.json +38 -7
  350. package/skills/agent-commerce.md +106 -0
  351. package/skills/browser-navigation.md +117 -0
  352. package/skills/commerce-setup-guide.md +116 -0
  353. package/skills/commerce-setup.md +84 -0
  354. package/skills/configure-dev-tools.md +101 -0
  355. package/skills/travel-planning.md +138 -0
  356. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  357. package/dist/heart/daemon/subagent-installer.js +0 -166
  358. package/dist/heart/session-recall.js +0 -116
  359. package/dist/mind/associative-recall.js +0 -209
  360. package/dist/senses/bluebubbles-entry.js +0 -13
  361. package/dist/senses/bluebubbles.js +0 -1177
  362. package/dist/senses/debug-activity.js +0 -148
  363. package/subagents/README.md +0 -86
  364. package/subagents/work-doer.md +0 -237
  365. package/subagents/work-merger.md +0 -618
  366. package/subagents/work-planner.md +0 -390
  367. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  368. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  369. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  370. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  371. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  372. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  373. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  374. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  375. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  376. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  377. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  378. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  379. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  380. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  381. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  382. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,728 @@
1
+ "use strict";
2
+ /**
3
+ * CLI output formatting and rendering helpers.
4
+ *
5
+ * Pure functions that transform data into human-readable CLI output.
6
+ * No side effects — callers handle writing to stdout.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.parseStatusPayload = parseStatusPayload;
43
+ exports.humanizeSenseName = humanizeSenseName;
44
+ exports.formatTable = formatTable;
45
+ exports.formatDaemonStatusOutput = formatDaemonStatusOutput;
46
+ exports.formatVersionOutput = formatVersionOutput;
47
+ exports.buildStoppedStatusPayload = buildStoppedStatusPayload;
48
+ exports.renderRollupStatusLine = renderRollupStatusLine;
49
+ exports.daemonUnavailableStatusOutput = daemonUnavailableStatusOutput;
50
+ exports.isDaemonUnavailableError = isDaemonUnavailableError;
51
+ exports.formatMcpResponse = formatMcpResponse;
52
+ const path = __importStar(require("path"));
53
+ const runtime_metadata_1 = require("./runtime-metadata");
54
+ const runtime_mode_1 = require("./runtime-mode");
55
+ const identity_1 = require("../identity");
56
+ const daemon_tombstone_1 = require("./daemon-tombstone");
57
+ const daemon_health_1 = require("./daemon-health");
58
+ const agent_discovery_1 = require("./agent-discovery");
59
+ // ── Field extractors ──
60
+ function stringField(value) {
61
+ return typeof value === "string" ? value : null;
62
+ }
63
+ function numberField(value) {
64
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
65
+ }
66
+ function booleanField(value) {
67
+ return typeof value === "boolean" ? value : null;
68
+ }
69
+ function formatDurationMs(ms) {
70
+ if (ms < 1_000)
71
+ return `${Math.round(ms)}ms`;
72
+ if (ms < 60_000)
73
+ return `${Math.round(ms / 1_000)}s`;
74
+ if (ms < 3_600_000)
75
+ return `${Math.round(ms / 60_000)}m`;
76
+ if (ms < 86_400_000)
77
+ return `${Math.round(ms / 3_600_000)}h`;
78
+ return `${Math.round(ms / 86_400_000)}d`;
79
+ }
80
+ function formatSenseDetail(row) {
81
+ const details = [row.detail];
82
+ const proofParts = [];
83
+ if (row.proofMethod)
84
+ proofParts.push(`proof=${row.proofMethod}`);
85
+ if (row.lastProofAt)
86
+ proofParts.push(`lastProof=${row.lastProofAt}`);
87
+ if (row.proofAgeMs !== undefined)
88
+ proofParts.push(`proofAge=${formatDurationMs(row.proofAgeMs)}`);
89
+ if (proofParts.length > 0)
90
+ details.push(proofParts.join(" "));
91
+ const recoveryParts = [];
92
+ if (row.pendingRecoveryCount !== undefined)
93
+ recoveryParts.push(`pendingRecovery=${row.pendingRecoveryCount}`);
94
+ if (row.failedRecoveryCount !== undefined)
95
+ recoveryParts.push(`failedRecovery=${row.failedRecoveryCount}`);
96
+ if (row.oldestPendingRecoveryAt)
97
+ recoveryParts.push(`oldestPending=${row.oldestPendingRecoveryAt}`);
98
+ if (row.oldestPendingRecoveryAgeMs !== undefined)
99
+ recoveryParts.push(`oldestPendingAge=${formatDurationMs(row.oldestPendingRecoveryAgeMs)}`);
100
+ if (recoveryParts.length > 0)
101
+ details.push(recoveryParts.join(" "));
102
+ const failureParts = [];
103
+ if (row.failureLayer)
104
+ failureParts.push(`failureLayer=${row.failureLayer}`);
105
+ if (row.lastFailure)
106
+ failureParts.push(`lastFailure=${row.lastFailure}`);
107
+ if (row.recoveryAction)
108
+ failureParts.push(`recovery=${row.recoveryAction}`);
109
+ if (failureParts.length > 0)
110
+ details.push(failureParts.join(" "));
111
+ return details.filter(Boolean).join("; ");
112
+ }
113
+ // ── Parsers ──
114
+ function parseStatusPayload(data) {
115
+ if (!data || typeof data !== "object" || Array.isArray(data))
116
+ return null;
117
+ const raw = data;
118
+ const overview = raw.overview;
119
+ const senses = raw.senses;
120
+ const workers = raw.workers;
121
+ const sync = raw.sync;
122
+ const agents = raw.agents;
123
+ const providers = raw.providers;
124
+ if (!overview || typeof overview !== "object" || Array.isArray(overview))
125
+ return null;
126
+ if (!Array.isArray(senses) || !Array.isArray(workers))
127
+ return null;
128
+ // sync, agents, and providers are optional for backward compatibility — older daemons may omit them
129
+ if (sync !== undefined && !Array.isArray(sync))
130
+ return null;
131
+ if (agents !== undefined && !Array.isArray(agents))
132
+ return null;
133
+ if (providers !== undefined && !Array.isArray(providers))
134
+ return null;
135
+ const parsedOverview = {
136
+ daemon: stringField(overview.daemon) ?? "unknown",
137
+ health: stringField(overview.health) ?? "unknown",
138
+ socketPath: stringField(overview.socketPath) ?? "unknown",
139
+ mailboxUrl: stringField(overview.mailboxUrl)
140
+ ?? stringField(overview.outlookUrl)
141
+ ?? "unavailable",
142
+ outlookUrl: stringField(overview.outlookUrl) ?? undefined,
143
+ version: stringField(overview.version) ?? "unknown",
144
+ lastUpdated: stringField(overview.lastUpdated) ?? "unknown",
145
+ repoRoot: stringField(overview.repoRoot) ?? "unknown",
146
+ configFingerprint: stringField(overview.configFingerprint) ?? "unknown",
147
+ workerCount: numberField(overview.workerCount) ?? 0,
148
+ senseCount: numberField(overview.senseCount) ?? 0,
149
+ entryPath: stringField(overview.entryPath) ?? "unknown",
150
+ mode: stringField(overview.mode) ?? "unknown",
151
+ };
152
+ const parsedSenses = senses.map((entry) => {
153
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
154
+ return null;
155
+ const row = entry;
156
+ const agent = stringField(row.agent);
157
+ const sense = stringField(row.sense);
158
+ const status = stringField(row.status);
159
+ const detail = stringField(row.detail);
160
+ const enabled = booleanField(row.enabled);
161
+ if (!agent || !sense || !status || detail === null || enabled === null)
162
+ return null;
163
+ const parsed = {
164
+ agent,
165
+ sense,
166
+ label: stringField(row.label) ?? undefined,
167
+ enabled,
168
+ status,
169
+ detail,
170
+ };
171
+ const proofMethod = stringField(row.proofMethod);
172
+ const lastProofAt = stringField(row.lastProofAt);
173
+ const proofAgeMs = numberField(row.proofAgeMs);
174
+ const lastFailure = stringField(row.lastFailure);
175
+ const failureLayer = stringField(row.failureLayer);
176
+ const recoveryAction = stringField(row.recoveryAction);
177
+ const pendingRecoveryCount = numberField(row.pendingRecoveryCount);
178
+ const failedRecoveryCount = numberField(row.failedRecoveryCount);
179
+ const oldestPendingRecoveryAt = stringField(row.oldestPendingRecoveryAt);
180
+ const oldestPendingRecoveryAgeMs = numberField(row.oldestPendingRecoveryAgeMs);
181
+ if (proofMethod !== null)
182
+ parsed.proofMethod = proofMethod;
183
+ if (lastProofAt !== null)
184
+ parsed.lastProofAt = lastProofAt;
185
+ if (proofAgeMs !== null)
186
+ parsed.proofAgeMs = proofAgeMs;
187
+ if (lastFailure !== null)
188
+ parsed.lastFailure = lastFailure;
189
+ if (failureLayer !== null)
190
+ parsed.failureLayer = failureLayer;
191
+ if (recoveryAction !== null)
192
+ parsed.recoveryAction = recoveryAction;
193
+ if (pendingRecoveryCount !== null)
194
+ parsed.pendingRecoveryCount = pendingRecoveryCount;
195
+ if (failedRecoveryCount !== null)
196
+ parsed.failedRecoveryCount = failedRecoveryCount;
197
+ if (oldestPendingRecoveryAt !== null)
198
+ parsed.oldestPendingRecoveryAt = oldestPendingRecoveryAt;
199
+ if (oldestPendingRecoveryAgeMs !== null)
200
+ parsed.oldestPendingRecoveryAgeMs = oldestPendingRecoveryAgeMs;
201
+ return parsed;
202
+ });
203
+ const parsedWorkers = workers.map((entry) => {
204
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
205
+ return null;
206
+ const row = entry;
207
+ const agent = stringField(row.agent);
208
+ const worker = stringField(row.worker);
209
+ const status = stringField(row.status);
210
+ const restartCount = numberField(row.restartCount);
211
+ const hasPid = Object.prototype.hasOwnProperty.call(row, "pid");
212
+ const pid = row.pid === null ? null : numberField(row.pid);
213
+ const pidInvalid = !hasPid || (row.pid !== null && pid === null);
214
+ if (!agent || !worker || !status || restartCount === null || pidInvalid)
215
+ return null;
216
+ return {
217
+ agent,
218
+ worker,
219
+ status,
220
+ pid,
221
+ restartCount,
222
+ lastExitCode: numberField(row.lastExitCode) ?? null,
223
+ lastSignal: stringField(row.lastSignal) ?? null,
224
+ startedAt: stringField(row.startedAt) ?? null,
225
+ errorReason: stringField(row.errorReason) ?? null,
226
+ fixHint: stringField(row.fixHint) ?? null,
227
+ };
228
+ });
229
+ const parsedSync = (sync ?? []).map((entry) => {
230
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
231
+ return null;
232
+ const row = entry;
233
+ const agent = stringField(row.agent);
234
+ const enabled = booleanField(row.enabled);
235
+ const remote = stringField(row.remote);
236
+ if (!agent || enabled === null || !remote)
237
+ return null;
238
+ const parsed = { agent, enabled, remote };
239
+ const remoteUrl = stringField(row.remoteUrl);
240
+ if (remoteUrl !== null)
241
+ parsed.remoteUrl = remoteUrl;
242
+ const gitInitialized = booleanField(row.gitInitialized);
243
+ if (gitInitialized !== null)
244
+ parsed.gitInitialized = gitInitialized;
245
+ return parsed;
246
+ });
247
+ const parsedAgents = (agents ?? []).map((entry) => {
248
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
249
+ return null;
250
+ const row = entry;
251
+ const name = stringField(row.name);
252
+ const enabled = booleanField(row.enabled);
253
+ if (!name || enabled === null)
254
+ return null;
255
+ return { name, enabled };
256
+ });
257
+ const parsedProviders = (providers ?? []).map((entry) => {
258
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
259
+ return null;
260
+ const row = entry;
261
+ const agent = stringField(row.agent);
262
+ const lane = stringField(row.lane);
263
+ const provider = stringField(row.provider);
264
+ const model = stringField(row.model);
265
+ const source = stringField(row.source);
266
+ const readiness = stringField(row.readiness);
267
+ const credential = stringField(row.credential);
268
+ if (!agent || !lane || !provider || !model || !source || !readiness || !credential)
269
+ return null;
270
+ const parsed = {
271
+ agent,
272
+ lane,
273
+ provider,
274
+ model,
275
+ source,
276
+ readiness,
277
+ credential,
278
+ };
279
+ const detail = stringField(row.detail);
280
+ if (detail !== null)
281
+ parsed.detail = detail;
282
+ return parsed;
283
+ });
284
+ if (parsedSenses.some((row) => row === null) ||
285
+ parsedWorkers.some((row) => row === null) ||
286
+ parsedSync.some((row) => row === null) ||
287
+ parsedAgents.some((row) => row === null) ||
288
+ parsedProviders.some((row) => row === null))
289
+ return null;
290
+ return {
291
+ overview: parsedOverview,
292
+ senses: parsedSenses,
293
+ workers: parsedWorkers,
294
+ sync: parsedSync,
295
+ agents: parsedAgents,
296
+ providers: parsedProviders,
297
+ };
298
+ }
299
+ // ── ANSI color helpers (private) ──
300
+ const RESET = "\x1b[0m";
301
+ const BOLD = "\x1b[1m";
302
+ const DIM = "\x1b[2m";
303
+ const TEAL = "\x1b[38;2;78;201;176m";
304
+ const GREEN = "\x1b[38;2;46;204;64m";
305
+ const RED = "\x1b[38;2;231;76;60m";
306
+ const YELLOW = "\x1b[38;2;230;190;50m";
307
+ /* v8 ignore start -- cosmetic ANSI wrappers @preserve */
308
+ function teal(text) { return `${TEAL}${text}${RESET}`; }
309
+ function green(text) { return `${GREEN}${text}${RESET}`; }
310
+ function red(text) { return `${RED}${text}${RESET}`; }
311
+ function yellow(text) { return `${YELLOW}${text}${RESET}`; }
312
+ function bold(text) { return `${BOLD}${text}${RESET}`; }
313
+ function dim(text) { return `${DIM}${text}${RESET}`; }
314
+ /* v8 ignore stop */
315
+ /* v8 ignore start -- cosmetic display: status dot color mapping tested visually @preserve */
316
+ function statusDot(status) {
317
+ switch (status) {
318
+ case "running":
319
+ case "ok":
320
+ case "interactive":
321
+ case "enabled":
322
+ case "ready":
323
+ return green("●");
324
+ case "crashed":
325
+ case "warn":
326
+ case "error":
327
+ case "failed":
328
+ return red("●");
329
+ case "needs_config":
330
+ case "not_attached":
331
+ case "stale":
332
+ return yellow("●");
333
+ case "disabled":
334
+ case "stopped":
335
+ return dim("○");
336
+ default:
337
+ return dim("●");
338
+ }
339
+ }
340
+ /* v8 ignore stop */
341
+ // ── Formatters ──
342
+ function humanizeSenseName(sense, label) {
343
+ if (label)
344
+ return label;
345
+ if (sense === "cli")
346
+ return "CLI";
347
+ if (sense === "bluebubbles")
348
+ return "BlueBubbles";
349
+ if (sense === "teams")
350
+ return "Teams";
351
+ return sense;
352
+ }
353
+ /* v8 ignore start -- utility formatter; retained for non-status table output @preserve */
354
+ function formatTable(headers, rows) {
355
+ const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => row[index].length)));
356
+ const renderRow = (row) => `| ${row.map((cell, index) => (index === row.length - 1
357
+ ? cell
358
+ : cell.padEnd(widths[index]))).join(" | ")} |`;
359
+ const divider = `|-${widths.map((width) => "-".repeat(width)).join("-|-")}-|`;
360
+ return [
361
+ renderRow(headers),
362
+ divider,
363
+ ...rows.map(renderRow),
364
+ ].join("\n");
365
+ }
366
+ /* v8 ignore stop */
367
+ function formatDaemonStatusOutput(response, fallback) {
368
+ const payload = parseStatusPayload(response.data);
369
+ if (!payload)
370
+ return fallback;
371
+ const ov = payload.overview;
372
+ const lines = [];
373
+ // ── Header banner ──
374
+ const modeTag = ov.mode === "dev" ? "dev" : "";
375
+ const daemonStatus = ov.daemon === "running" ? green("●") + " " + bold("running") : red("●") + " " + bold(ov.daemon);
376
+ const modeStr = modeTag ? ` ${dim(`(${modeTag})`)}` : "";
377
+ const bannerContent = ` ${bold(ov.version)} ${daemonStatus}${modeStr} `;
378
+ // Measure raw content width (strip ANSI for width calc)
379
+ const rawBanner = bannerContent.replace(/\x1b\[[0-9;]*m/g, "");
380
+ const bannerWidth = Math.max(rawBanner.length, 42);
381
+ const titleLabel = " ouroboros daemon ";
382
+ const topRightPad = Math.max(0, bannerWidth - titleLabel.length - 2);
383
+ lines.push(` ${teal("╭─")}${teal(titleLabel)}${teal("─".repeat(topRightPad))}${teal("╮")}`);
384
+ lines.push(` ${teal("│")}${bannerContent}${" ".repeat(Math.max(0, bannerWidth - rawBanner.length))}${teal("│")}`);
385
+ lines.push(` ${teal("╰")}${teal("─".repeat(bannerWidth))}${teal("╯")}`);
386
+ lines.push("");
387
+ // ── Key-value overview ──
388
+ const kvLine = (label, value) => ` ${teal(label.padEnd(11))} ${value}`;
389
+ lines.push(kvLine("Socket", ov.socketPath));
390
+ lines.push(kvLine("Mailbox", ov.mailboxUrl));
391
+ lines.push(kvLine("Health", `${statusDot(ov.health)} ${ov.health}`));
392
+ lines.push(kvLine("Updated", ov.lastUpdated));
393
+ lines.push("");
394
+ // ── Agents ──
395
+ // Every discovered bundle, including disabled ones. The Senses/Workers/
396
+ // Git Sync sections below only show enabled bundles, so without this
397
+ // section disabled agents would be invisible in `ouro status`.
398
+ if (payload.agents.length > 0) {
399
+ lines.push(` ${teal("──")} ${bold("Agents")} ${teal("─".repeat(37))}`);
400
+ const agentNameWidth = Math.max(12, ...payload.agents.map((r) => r.name.length));
401
+ for (const row of payload.agents) {
402
+ const name = row.name.padEnd(agentNameWidth);
403
+ const dot = row.enabled ? green("●") : dim("○");
404
+ const stateText = row.enabled ? "enabled " : "disabled";
405
+ lines.push(` ${name} ${dot} ${stateText}`);
406
+ }
407
+ lines.push("");
408
+ }
409
+ // ── Providers ──
410
+ if (payload.providers.length > 0) {
411
+ lines.push(` ${teal("──")} ${bold("Providers")} ${teal("─".repeat(34))}`);
412
+ const agentLaneWidth = Math.max(16, ...payload.providers.map((r) => `${r.agent} ${r.lane}`.length));
413
+ for (const row of payload.providers) {
414
+ const agentLane = `${row.agent} ${row.lane}`.padEnd(agentLaneWidth);
415
+ const model = `${row.provider} / ${row.model}`;
416
+ const detail = [row.readiness, row.detail, row.source, row.credential].filter(Boolean).join("; ");
417
+ lines.push(` ${agentLane} ${statusDot(row.readiness)} ${model} ${dim(detail)}`);
418
+ }
419
+ lines.push("");
420
+ }
421
+ // ── Senses ──
422
+ if (payload.senses.length > 0) {
423
+ lines.push(` ${teal("──")} ${bold("Senses")} ${teal("─".repeat(37))}`);
424
+ // Group senses by agent
425
+ const sensesByAgent = new Map();
426
+ for (const row of payload.senses) {
427
+ const list = sensesByAgent.get(row.agent) ?? [];
428
+ list.push(row);
429
+ sensesByAgent.set(row.agent, list);
430
+ }
431
+ // Calculate column widths for alignment
432
+ const allSenseNames = payload.senses.map((r) => humanizeSenseName(r.sense, r.label));
433
+ const nameWidth = Math.max(12, ...allSenseNames.map((n) => n.length));
434
+ const allStatuses = payload.senses.map((r) => r.status);
435
+ const statusWidth = Math.max(10, ...allStatuses.map((s) => s.length));
436
+ for (const [agent, rows] of sensesByAgent) {
437
+ lines.push(` ${bold(agent)}`);
438
+ for (const row of rows) {
439
+ const name = humanizeSenseName(row.sense, row.label).padEnd(nameWidth);
440
+ const dot = row.enabled ? statusDot(row.status) : dim("○");
441
+ const statusText = (row.enabled ? row.status : "disabled").padEnd(statusWidth);
442
+ lines.push(` ${name} ${dot} ${statusText} ${dim(formatSenseDetail(row))}`);
443
+ }
444
+ }
445
+ lines.push("");
446
+ }
447
+ // ── Workers ──
448
+ if (payload.workers.length > 0) {
449
+ lines.push(` ${teal("──")} ${bold("Workers")} ${teal("─".repeat(36))}`);
450
+ // Group workers by agent
451
+ const workersByAgent = new Map();
452
+ for (const row of payload.workers) {
453
+ const list = workersByAgent.get(row.agent) ?? [];
454
+ list.push(row);
455
+ workersByAgent.set(row.agent, list);
456
+ }
457
+ const allWorkerNames = payload.workers.map((r) => r.worker);
458
+ const workerNameWidth = Math.max(12, ...allWorkerNames.map((n) => n.length));
459
+ for (const [agent, rows] of workersByAgent) {
460
+ lines.push(` ${bold(agent)}`);
461
+ for (const row of rows) {
462
+ const name = row.worker.padEnd(workerNameWidth);
463
+ const dot = statusDot(row.status);
464
+ const pidStr = row.pid !== null ? `pid ${row.pid}` : "";
465
+ const restartStr = `restarts: ${row.restartCount}`;
466
+ /* v8 ignore start — exit info branches tested via daemon-crash-context; v8 misreports conditional chains @preserve */
467
+ let exitStr = "";
468
+ if (row.lastExitCode !== null)
469
+ exitStr = `exit=${row.lastExitCode}`;
470
+ if (row.lastSignal !== null)
471
+ exitStr = row.lastExitCode !== null ? `exit=${row.lastExitCode} sig=${row.lastSignal}` : `sig=${row.lastSignal}`;
472
+ /* v8 ignore stop */
473
+ const details = [pidStr, restartStr, exitStr].filter(Boolean).join(" ");
474
+ lines.push(` ${name} ${dot} ${row.status.padEnd(10)} ${dim(details)}`);
475
+ if (row.errorReason) {
476
+ lines.push(` ${dim(`error: ${row.errorReason}`)}`);
477
+ }
478
+ if (row.fixHint) {
479
+ lines.push(` ${dim(`fix: ${row.fixHint}`)}`);
480
+ }
481
+ }
482
+ }
483
+ lines.push("");
484
+ }
485
+ // ── Git Sync (per agent) ──
486
+ if (payload.sync.length > 0) {
487
+ lines.push(` ${teal("──")} ${bold("Git Sync")} ${teal("─".repeat(35))}`);
488
+ const agentNameWidth = Math.max(12, ...payload.sync.map((r) => r.agent.length));
489
+ for (const row of payload.sync) {
490
+ const name = row.agent.padEnd(agentNameWidth);
491
+ // Three states for enabled rows: error (not a repo), ok (remote URL), ok (local only).
492
+ // Disabled rows show the usual dim dot + "disabled".
493
+ let dot;
494
+ let stateText;
495
+ let detail;
496
+ if (!row.enabled) {
497
+ dot = dim("○");
498
+ stateText = "disabled".padEnd(10);
499
+ detail = "";
500
+ }
501
+ else if (row.gitInitialized === false) {
502
+ dot = red("●");
503
+ stateText = "error ".padEnd(10);
504
+ detail = "not a git repo — run `git init` to enable sync";
505
+ }
506
+ else if (row.remoteUrl !== undefined) {
507
+ dot = green("●");
508
+ stateText = "enabled ".padEnd(10);
509
+ detail = `${row.remote} → ${row.remoteUrl}`;
510
+ }
511
+ else {
512
+ dot = green("●");
513
+ stateText = "enabled ".padEnd(10);
514
+ detail = "local only";
515
+ }
516
+ lines.push(` ${name} ${dot} ${stateText} ${dim(detail)}`);
517
+ }
518
+ lines.push("");
519
+ }
520
+ return lines.join("\n");
521
+ }
522
+ function formatVersionOutput() {
523
+ const version = (0, runtime_metadata_1.getRuntimeMetadata)().version;
524
+ const mode = (0, runtime_mode_1.detectRuntimeMode)((0, identity_1.getRepoRoot)());
525
+ /* v8 ignore start — cosmetic display toggle; dev mode always true in test env */
526
+ return mode === "dev" ? `${version} (dev)` : version;
527
+ /* v8 ignore stop */
528
+ }
529
+ function buildStoppedStatusPayload(socketPath, syncRows = [], agentRows = []) {
530
+ const metadata = (0, runtime_metadata_1.getRuntimeMetadata)();
531
+ const repoRoot = (0, identity_1.getRepoRoot)();
532
+ return {
533
+ overview: {
534
+ daemon: "stopped",
535
+ health: "warn",
536
+ socketPath,
537
+ mailboxUrl: "unavailable",
538
+ outlookUrl: "unavailable",
539
+ version: metadata.version,
540
+ lastUpdated: metadata.lastUpdated,
541
+ repoRoot: metadata.repoRoot,
542
+ configFingerprint: metadata.configFingerprint,
543
+ workerCount: 0,
544
+ senseCount: 0,
545
+ entryPath: path.join(repoRoot, "dist", "heart", "daemon", "daemon-entry.js"),
546
+ mode: (0, runtime_mode_1.detectRuntimeMode)(repoRoot),
547
+ },
548
+ senses: [],
549
+ workers: [],
550
+ sync: syncRows,
551
+ agents: agentRows,
552
+ providers: [],
553
+ };
554
+ }
555
+ /**
556
+ * Render the cached daemon-rollup status as a one-line string for the
557
+ * "daemon not running" view. Each `DaemonStatus` literal maps to a
558
+ * label + a brief explanatory copy fragment. The default branch is
559
+ * `never`-typed so future widening of `DaemonStatus` compile-errors
560
+ * here — Layer 1's compiler-forced exhaustiveness contract.
561
+ *
562
+ * The `degraded` literal splits into two copy variants based on the
563
+ * cached health file's `agents` map:
564
+ * - empty map → "no agents configured" (fresh-install copy).
565
+ * - non-empty map → "none ready" (all-agents-failed-live-check copy).
566
+ *
567
+ * The split lives at the render layer (not in the rollup status itself)
568
+ * so the same status can carry distinct UX copy without inflating the
569
+ * type union.
570
+ */
571
+ function renderRollupStatusLine(health) {
572
+ const status = health.status;
573
+ const tail = `(pid ${health.pid}, uptime ${health.uptimeSeconds}s)`;
574
+ /* v8 ignore next -- v8 instruments the switch statement itself as a branch; the never-typed default below is unreachable by construction so v8 cannot observe its branch firing @preserve */
575
+ switch (status) {
576
+ case "healthy":
577
+ return `Last known status: healthy ${tail}`;
578
+ case "partial": {
579
+ // `partial` arises from two independent sources:
580
+ // (a) some enabled agents not in `running` state, or
581
+ // (b) Layer-4 drift between agent.json (intent) and state/providers.json (observed).
582
+ // Either or both can be true. Render mentions both when applicable so
583
+ // the operator isn't misled into thinking agents are unhealthy when the
584
+ // only anomaly is configuration drift.
585
+ const unhealthyCount = Object.values(health.agents).filter((agent) => agent.status !== "running").length;
586
+ const driftCount = (health.drift ?? []).length;
587
+ const parts = [];
588
+ if (unhealthyCount > 0) {
589
+ parts.push(`${unhealthyCount} agent${unhealthyCount === 1 ? "" : "s"} unhealthy`);
590
+ }
591
+ if (driftCount > 0) {
592
+ parts.push(`drift on ${driftCount} agent${driftCount === 1 ? "" : "s"}`);
593
+ }
594
+ // Fallback for legacy cached files: status="partial" with no
595
+ // visible cause (no unhealthy agents AND no drift array). This
596
+ // happens when the file pre-dates Layer 4 and the daemon flagged
597
+ // partial via some signal that's no longer expressible. Prompt
598
+ // refresh via `ouro up` rather than asserting a specific cause.
599
+ const detail = parts.length > 0
600
+ ? ` — ${parts.join("; ")}`
601
+ : " — stale cache, run `ouro up` to refresh";
602
+ return `Last known status: partial${detail} ${tail}`;
603
+ }
604
+ case "degraded": {
605
+ // Three-way copy split based on the cached agents map:
606
+ // - empty map → fresh install / no agents configured.
607
+ // - non-empty + any agent reports "running" → legacy stale cache:
608
+ // pre-Layer-1, status="degraded" meant "any sick component," so a
609
+ // running agent could coexist with a degraded daemon. Post-Layer-1,
610
+ // degraded means "zero serving" — mutually exclusive with a running
611
+ // agent. A live disagreement therefore implies the cache pre-dates
612
+ // the rollup-semantics fix; prompt for `ouro up` to refresh rather
613
+ // than falsely claim "none ready."
614
+ // - non-empty + zero agents reporting "running" → all-failed copy.
615
+ const agentEntries = Object.values(health.agents);
616
+ if (agentEntries.length === 0) {
617
+ return `Last known status: degraded — no agents configured (run \`ouro hatch\` to add one) ${tail}`;
618
+ }
619
+ const anyRunning = agentEntries.some((agent) => agent.status === "running");
620
+ if (anyRunning) {
621
+ return `Last known status: degraded — stale cache, run \`ouro up\` to refresh ${tail}`;
622
+ }
623
+ return `Last known status: degraded — agents configured but none ready (run \`ouro doctor\`) ${tail}`;
624
+ }
625
+ case "safe-mode":
626
+ return `Last known status: safe-mode — crash loop tripped ${tail}`;
627
+ case "down":
628
+ return `Last known status: down ${tail}`;
629
+ /* v8 ignore start -- compiler-forced exhaustiveness: the never-typed default branch is unreachable by construction; if DaemonStatus widens, tsc errors at the assignment before the throw can run @preserve */
630
+ default: {
631
+ // Compiler-forced exhaustiveness. If DaemonStatus grows a new
632
+ // literal, this `never` cast errors at tsc, forcing every
633
+ // consumer to handle it explicitly. NEVER replace this with a
634
+ // permissive `default:` returning a fallback string — that's
635
+ // exactly how the old "ok | degraded" semantics leaked through.
636
+ const _exhaustive = status;
637
+ throw new Error(`unhandled daemon status: ${_exhaustive}`);
638
+ }
639
+ /* v8 ignore stop */
640
+ }
641
+ }
642
+ function daemonUnavailableStatusOutput(socketPath, healthFilePath) {
643
+ // Read per-agent sync config and bundle list from disk so the user still
644
+ // sees them when the daemon is down. Best-effort: any fs error returns []
645
+ // and the corresponding section is omitted.
646
+ let syncRows = [];
647
+ let agentRows = [];
648
+ try {
649
+ syncRows = (0, agent_discovery_1.listBundleSyncRows)();
650
+ }
651
+ catch {
652
+ // listBundleSyncRows already swallows fs errors internally; this catch is a defensive
653
+ // safety net for environments where the fs module itself is partially mocked.
654
+ }
655
+ try {
656
+ agentRows = (0, agent_discovery_1.listAllBundleAgents)();
657
+ }
658
+ catch {
659
+ // Same defensive safety net for the bundle list.
660
+ }
661
+ /* v8 ignore start — tombstone read tested in daemon-status-tombstone.test; branch misreported @preserve */
662
+ const tombstone = (0, daemon_tombstone_1.readDaemonTombstone)();
663
+ const deathLine = tombstone
664
+ ? `Last death: ${tombstone.timestamp} -- ${tombstone.reason}: ${tombstone.message}`
665
+ : null;
666
+ /* v8 ignore stop */
667
+ const lines = [
668
+ formatDaemonStatusOutput({
669
+ ok: true,
670
+ summary: "daemon not running",
671
+ data: buildStoppedStatusPayload(socketPath, syncRows, agentRows),
672
+ }, "daemon not running"),
673
+ "",
674
+ ];
675
+ /* v8 ignore start — tombstone presence requires real daemon crash @preserve */
676
+ if (deathLine) {
677
+ lines.push(deathLine);
678
+ lines.push("");
679
+ /* v8 ignore stop */
680
+ }
681
+ // Read health file for last-known state (best-effort)
682
+ const resolvedHealthPath = healthFilePath ?? (0, daemon_health_1.getDefaultHealthPath)();
683
+ const health = (0, daemon_health_1.readHealth)(resolvedHealthPath);
684
+ if (health) {
685
+ lines.push(renderRollupStatusLine(health));
686
+ if (health.safeMode?.active) {
687
+ lines.push(`SAFE MODE: ${health.safeMode.reason}`);
688
+ }
689
+ if (health.degraded.length > 0) {
690
+ lines.push("");
691
+ lines.push("Degraded:");
692
+ for (const d of health.degraded) {
693
+ lines.push(` ${d.component}: ${d.reason} (since ${d.since})`);
694
+ }
695
+ }
696
+ lines.push("");
697
+ }
698
+ lines.push("daemon not running; run `ouro up`");
699
+ return lines.join("\n");
700
+ }
701
+ function isDaemonUnavailableError(error) {
702
+ const code = typeof error === "object" && error !== null && "code" in error
703
+ ? String(error.code ?? "")
704
+ : "";
705
+ return code === "ENOENT" || code === "ECONNREFUSED";
706
+ }
707
+ function formatMcpResponse(command, response) {
708
+ if (command.kind === "mcp.list") {
709
+ const allTools = response.data;
710
+ if (!allTools || allTools.length === 0) {
711
+ return response.message ?? "no tools available from connected MCP servers";
712
+ }
713
+ const lines = [];
714
+ for (const entry of allTools) {
715
+ lines.push(`[${entry.server}]`);
716
+ for (const tool of entry.tools) {
717
+ lines.push(` ${tool.name}: ${tool.description}`);
718
+ }
719
+ }
720
+ return lines.join("\n");
721
+ }
722
+ // mcp.call
723
+ const result = response.data;
724
+ if (!result) {
725
+ return response.message ?? "no result";
726
+ }
727
+ return result.content.map((c) => c.text).join("\n");
728
+ }