@ouro.bot/cli 0.1.0-alpha.56 → 0.1.0-alpha.560

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 (392) hide show
  1. package/README.md +127 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +3596 -0
  13. package/dist/arc/attention-types.js +8 -0
  14. package/dist/arc/cares.js +140 -0
  15. package/dist/arc/episodes.js +117 -0
  16. package/dist/arc/intentions.js +133 -0
  17. package/dist/arc/json-store.js +117 -0
  18. package/dist/arc/obligations.js +237 -0
  19. package/dist/arc/packets.js +193 -0
  20. package/dist/arc/presence.js +185 -0
  21. package/dist/arc/task-lifecycle.js +65 -0
  22. package/dist/heart/active-work.js +837 -26
  23. package/dist/heart/agent-entry.js +58 -3
  24. package/dist/heart/attachments/image-normalize.js +194 -0
  25. package/dist/heart/attachments/materialize.js +97 -0
  26. package/dist/heart/attachments/originals.js +88 -0
  27. package/dist/heart/attachments/render.js +29 -0
  28. package/dist/heart/attachments/sources/adapter.js +2 -0
  29. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  30. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  31. package/dist/heart/attachments/sources/index.js +16 -0
  32. package/dist/heart/attachments/store.js +103 -0
  33. package/dist/heart/attachments/types.js +93 -0
  34. package/dist/heart/auth/auth-flow.js +479 -0
  35. package/dist/heart/background-operations.js +281 -0
  36. package/dist/heart/bundle-state.js +168 -0
  37. package/dist/heart/commitments.js +111 -0
  38. package/dist/heart/config-registry.js +322 -0
  39. package/dist/heart/config.js +114 -118
  40. package/dist/heart/core.js +913 -246
  41. package/dist/heart/cross-chat-delivery.js +3 -18
  42. package/dist/heart/daemon/agent-config-check.js +419 -0
  43. package/dist/heart/daemon/agent-discovery.js +102 -3
  44. package/dist/heart/daemon/agent-service.js +522 -0
  45. package/dist/heart/daemon/agentic-repair.js +547 -0
  46. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  47. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  48. package/dist/heart/daemon/cadence.js +70 -0
  49. package/dist/heart/daemon/cli-defaults.js +776 -0
  50. package/dist/heart/daemon/cli-exec.js +7457 -0
  51. package/dist/heart/daemon/cli-help.js +498 -0
  52. package/dist/heart/daemon/cli-parse.js +1592 -0
  53. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  54. package/dist/heart/daemon/cli-render.js +763 -0
  55. package/dist/heart/daemon/cli-types.js +8 -0
  56. package/dist/heart/daemon/connect-bay.js +323 -0
  57. package/dist/heart/daemon/daemon-cli.js +29 -1698
  58. package/dist/heart/daemon/daemon-entry.js +387 -2
  59. package/dist/heart/daemon/daemon-health.js +176 -0
  60. package/dist/heart/daemon/daemon-rollup.js +57 -0
  61. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  62. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  63. package/dist/heart/daemon/daemon.js +796 -71
  64. package/dist/heart/daemon/dns-workflow.js +394 -0
  65. package/dist/heart/daemon/doctor-types.js +8 -0
  66. package/dist/heart/daemon/doctor.js +826 -0
  67. package/dist/heart/daemon/health-monitor.js +122 -1
  68. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  69. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  70. package/dist/heart/daemon/http-health-probe.js +80 -0
  71. package/dist/heart/daemon/human-command-screens.js +234 -0
  72. package/dist/heart/daemon/human-readiness.js +114 -0
  73. package/dist/heart/daemon/inner-status.js +89 -0
  74. package/dist/heart/daemon/interactive-repair.js +394 -0
  75. package/dist/heart/daemon/launchd.js +37 -8
  76. package/dist/heart/daemon/log-tailer.js +82 -12
  77. package/dist/heart/daemon/logs-prune.js +110 -0
  78. package/dist/heart/daemon/mcp-canary.js +297 -0
  79. package/dist/heart/daemon/message-router.js +2 -2
  80. package/dist/heart/daemon/os-cron-deps.js +135 -0
  81. package/dist/heart/daemon/os-cron.js +14 -12
  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 +3 -31
  92. package/dist/heart/daemon/safe-mode.js +161 -0
  93. package/dist/heart/daemon/sense-manager.js +389 -38
  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 +158 -11
  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 +32 -56
  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 +203 -57
  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 +683 -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 +267 -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-readiness-cache.js +40 -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/runtime-cwd.js +87 -0
  156. package/dist/heart/sense-truth.js +13 -4
  157. package/dist/heart/session-activity.js +43 -22
  158. package/dist/heart/session-events.js +1149 -0
  159. package/dist/heart/session-playback-cli-main.js +5 -0
  160. package/dist/heart/session-playback-cli.js +36 -0
  161. package/dist/heart/session-playback.js +231 -0
  162. package/dist/heart/session-stats-cli-main.js +5 -0
  163. package/dist/heart/session-stats.js +182 -0
  164. package/dist/heart/session-transcript.js +243 -0
  165. package/dist/heart/start-of-turn-packet.js +345 -0
  166. package/dist/heart/streaming.js +44 -27
  167. package/dist/heart/sync-classification.js +176 -0
  168. package/dist/heart/sync.js +449 -0
  169. package/dist/heart/target-resolution.js +9 -5
  170. package/dist/heart/tempo.js +93 -0
  171. package/dist/heart/temporal-view.js +41 -0
  172. package/dist/heart/timeouts.js +101 -0
  173. package/dist/heart/tool-activity-callbacks.js +59 -0
  174. package/dist/heart/tool-description.js +139 -0
  175. package/dist/heart/tool-friction.js +55 -0
  176. package/dist/heart/tool-loop.js +200 -0
  177. package/dist/heart/turn-context.js +389 -0
  178. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  179. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  180. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  181. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  182. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  183. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  184. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  185. package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
  186. package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
  187. package/dist/mailbox-ui/index.html +15 -0
  188. package/dist/mailroom/attention.js +167 -0
  189. package/dist/mailroom/autonomy.js +209 -0
  190. package/dist/mailroom/blob-store.js +674 -0
  191. package/dist/mailroom/body-cache.js +61 -0
  192. package/dist/mailroom/core.js +720 -0
  193. package/dist/mailroom/entry.js +160 -0
  194. package/dist/mailroom/file-store.js +430 -0
  195. package/dist/mailroom/mbox-import.js +383 -0
  196. package/dist/mailroom/outbound.js +380 -0
  197. package/dist/mailroom/policy.js +263 -0
  198. package/dist/mailroom/reader.js +233 -0
  199. package/dist/mailroom/search-cache.js +256 -0
  200. package/dist/mailroom/search-relevance.js +319 -0
  201. package/dist/mailroom/smtp-ingress.js +176 -0
  202. package/dist/mailroom/source-state.js +176 -0
  203. package/dist/mailroom/thread.js +109 -0
  204. package/dist/mailroom/travel-extract.js +89 -0
  205. package/dist/mind/bundle-manifest.js +7 -1
  206. package/dist/mind/context.js +165 -101
  207. package/dist/mind/diary-integrity.js +60 -0
  208. package/dist/mind/{memory.js → diary.js} +62 -75
  209. package/dist/mind/embedding-provider.js +60 -0
  210. package/dist/mind/file-state.js +179 -0
  211. package/dist/mind/friends/channel.js +39 -0
  212. package/dist/mind/friends/resolver.js +54 -2
  213. package/dist/mind/friends/store-file.js +39 -3
  214. package/dist/mind/friends/types.js +2 -2
  215. package/dist/mind/journal-index.js +161 -0
  216. package/dist/mind/note-search.js +268 -0
  217. package/dist/mind/obligation-steering.js +221 -0
  218. package/dist/mind/pending.js +4 -0
  219. package/dist/mind/prompt-refresh.js +3 -2
  220. package/dist/mind/prompt.js +1011 -123
  221. package/dist/mind/provenance-trust.js +26 -0
  222. package/dist/mind/scrutiny.js +173 -0
  223. package/dist/nerves/cli-logging.js +7 -1
  224. package/dist/nerves/coverage/audit-rules.js +15 -6
  225. package/dist/nerves/coverage/audit.js +28 -2
  226. package/dist/nerves/coverage/cli.js +1 -1
  227. package/dist/nerves/coverage/contract.js +5 -5
  228. package/dist/nerves/coverage/file-completeness.js +129 -5
  229. package/dist/nerves/coverage/run-artifacts.js +1 -1
  230. package/dist/nerves/event-buffer.js +111 -0
  231. package/dist/nerves/index.js +224 -4
  232. package/dist/nerves/observation.js +20 -0
  233. package/dist/nerves/redact.js +79 -0
  234. package/dist/nerves/review/cli-main.js +5 -0
  235. package/dist/nerves/review/cli.js +156 -0
  236. package/dist/nerves/review/core.js +152 -0
  237. package/dist/nerves/runtime.js +5 -1
  238. package/dist/repertoire/ado-client.js +15 -56
  239. package/dist/repertoire/ado-semantic.js +11 -10
  240. package/dist/repertoire/api-client.js +97 -0
  241. package/dist/repertoire/bitwarden-store.js +963 -0
  242. package/dist/repertoire/bundle-templates.js +72 -0
  243. package/dist/repertoire/bw-installer.js +180 -0
  244. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  245. package/dist/repertoire/coding/context-pack.js +330 -0
  246. package/dist/repertoire/coding/feedback.js +197 -30
  247. package/dist/repertoire/coding/manager.js +158 -9
  248. package/dist/repertoire/coding/spawner.js +55 -9
  249. package/dist/repertoire/coding/tools.js +170 -7
  250. package/dist/repertoire/commerce-errors.js +109 -0
  251. package/dist/repertoire/commerce-self-test.js +156 -0
  252. package/dist/repertoire/credential-access.js +178 -0
  253. package/dist/repertoire/duffel-client.js +185 -0
  254. package/dist/repertoire/github-client.js +14 -55
  255. package/dist/repertoire/graph-client.js +11 -52
  256. package/dist/repertoire/guardrails.js +396 -0
  257. package/dist/repertoire/mcp-client.js +295 -0
  258. package/dist/repertoire/mcp-manager.js +362 -0
  259. package/dist/repertoire/mcp-tools.js +63 -0
  260. package/dist/repertoire/shell-sessions.js +133 -0
  261. package/dist/repertoire/skills.js +15 -24
  262. package/dist/repertoire/stripe-client.js +131 -0
  263. package/dist/repertoire/tasks/board.js +31 -5
  264. package/dist/repertoire/tasks/fix.js +182 -0
  265. package/dist/repertoire/tasks/index.js +16 -4
  266. package/dist/repertoire/tasks/lifecycle.js +2 -2
  267. package/dist/repertoire/tasks/parser.js +3 -2
  268. package/dist/repertoire/tasks/scanner.js +194 -37
  269. package/dist/repertoire/tasks/transitions.js +16 -78
  270. package/dist/repertoire/tool-results.js +29 -0
  271. package/dist/repertoire/tools-attachments.js +317 -0
  272. package/dist/repertoire/tools-base.js +47 -1075
  273. package/dist/repertoire/tools-bluebubbles.js +1 -0
  274. package/dist/repertoire/tools-bridge.js +142 -0
  275. package/dist/repertoire/tools-bundle.js +984 -0
  276. package/dist/repertoire/tools-config.js +185 -0
  277. package/dist/repertoire/tools-continuity.js +248 -0
  278. package/dist/repertoire/tools-credential.js +381 -0
  279. package/dist/repertoire/tools-files.js +342 -0
  280. package/dist/repertoire/tools-flight.js +224 -0
  281. package/dist/repertoire/tools-flow.js +119 -0
  282. package/dist/repertoire/tools-github.js +1 -7
  283. package/dist/repertoire/tools-mail.js +1857 -0
  284. package/dist/repertoire/tools-notes.js +421 -0
  285. package/dist/repertoire/tools-session.js +750 -0
  286. package/dist/repertoire/tools-shell.js +120 -0
  287. package/dist/repertoire/tools-stripe.js +180 -0
  288. package/dist/repertoire/tools-surface.js +243 -0
  289. package/dist/repertoire/tools-teams.js +9 -39
  290. package/dist/repertoire/tools-travel.js +125 -0
  291. package/dist/repertoire/tools-trip.js +604 -0
  292. package/dist/repertoire/tools-user-profile.js +144 -0
  293. package/dist/repertoire/tools-vault.js +40 -0
  294. package/dist/repertoire/tools.js +108 -100
  295. package/dist/repertoire/travel-api-client.js +360 -0
  296. package/dist/repertoire/user-profile.js +131 -0
  297. package/dist/repertoire/vault-setup.js +246 -0
  298. package/dist/repertoire/vault-unlock.js +594 -0
  299. package/dist/scripts/claude-code-hook.js +41 -0
  300. package/dist/scripts/claude-code-stop-hook.js +47 -0
  301. package/dist/senses/attention-queue.js +116 -0
  302. package/dist/senses/bluebubbles/active-turns.js +216 -0
  303. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  304. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  305. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  306. package/dist/senses/bluebubbles/entry.js +77 -0
  307. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  308. package/dist/senses/bluebubbles/index.js +2305 -0
  309. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  310. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  311. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  312. package/dist/senses/bluebubbles/processed-log.js +133 -0
  313. package/dist/senses/bluebubbles/replay.js +137 -0
  314. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  315. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  316. package/dist/senses/cli/bracketed-paste.js +82 -0
  317. package/dist/senses/cli/image-paste.js +287 -0
  318. package/dist/senses/cli/image-ref-navigation.js +75 -0
  319. package/dist/senses/cli/ink-app.js +156 -0
  320. package/dist/senses/cli/inline-diff.js +64 -0
  321. package/dist/senses/cli/input-keys.js +174 -0
  322. package/dist/senses/cli/kill-ring.js +86 -0
  323. package/dist/senses/cli/message-list.js +51 -0
  324. package/dist/senses/cli/ouro-tui.js +607 -0
  325. package/dist/senses/cli/spinner-imperative.js +135 -0
  326. package/dist/senses/cli/spinner.js +101 -0
  327. package/dist/senses/cli/status-line.js +60 -0
  328. package/dist/senses/cli/streaming-markdown.js +526 -0
  329. package/dist/senses/cli/tool-display.js +85 -0
  330. package/dist/senses/cli/tool-render.js +85 -0
  331. package/dist/senses/cli/tui-store.js +240 -0
  332. package/dist/senses/cli/virtual-list.js +35 -0
  333. package/dist/senses/cli-entry.js +60 -8
  334. package/dist/senses/cli-layout.js +187 -0
  335. package/dist/senses/cli.js +520 -209
  336. package/dist/senses/commands.js +66 -3
  337. package/dist/senses/habit-turn-message.js +108 -0
  338. package/dist/senses/inner-dialog-worker.js +175 -21
  339. package/dist/senses/inner-dialog.js +330 -27
  340. package/dist/senses/mail-entry.js +66 -0
  341. package/dist/senses/mail.js +379 -0
  342. package/dist/senses/pipeline.js +549 -181
  343. package/dist/senses/proactive-content-guard.js +51 -0
  344. package/dist/senses/shared-turn.js +248 -0
  345. package/dist/senses/surface-tool.js +68 -0
  346. package/dist/senses/teams-entry.js +60 -8
  347. package/dist/senses/teams.js +387 -98
  348. package/dist/senses/trust-gate.js +100 -5
  349. package/dist/senses/voice/elevenlabs.js +125 -0
  350. package/dist/senses/voice/index.js +22 -0
  351. package/dist/senses/voice/transcript.js +70 -0
  352. package/dist/senses/voice/turn.js +85 -0
  353. package/dist/senses/voice/types.js +2 -0
  354. package/dist/senses/voice/whisper.js +133 -0
  355. package/dist/senses/voice-entry.js +80 -0
  356. package/dist/trips/core.js +138 -0
  357. package/dist/trips/store.js +146 -0
  358. package/package.json +38 -7
  359. package/skills/agent-commerce.md +106 -0
  360. package/skills/browser-navigation.md +117 -0
  361. package/skills/commerce-setup-guide.md +116 -0
  362. package/skills/commerce-setup.md +84 -0
  363. package/skills/configure-dev-tools.md +101 -0
  364. package/skills/travel-planning.md +138 -0
  365. package/dist/heart/daemon/auth-flow.js +0 -351
  366. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  367. package/dist/heart/daemon/subagent-installer.js +0 -166
  368. package/dist/heart/session-recall.js +0 -116
  369. package/dist/mind/associative-recall.js +0 -209
  370. package/dist/senses/bluebubbles-entry.js +0 -13
  371. package/dist/senses/bluebubbles.js +0 -1177
  372. package/dist/senses/debug-activity.js +0 -148
  373. package/subagents/README.md +0 -86
  374. package/subagents/work-doer.md +0 -237
  375. package/subagents/work-merger.md +0 -618
  376. package/subagents/work-planner.md +0 -390
  377. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  378. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  379. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  380. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  381. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  382. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  383. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  384. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  385. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  386. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  387. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  388. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  389. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  390. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  391. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  392. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -37,15 +37,18 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.formatSurfacedValue = formatSurfacedValue;
39
39
  exports.deriveInnerDialogStatus = deriveInnerDialogStatus;
40
+ exports.deriveInnerJob = deriveInnerJob;
40
41
  exports.formatInnerDialogStatus = formatInnerDialogStatus;
41
42
  exports.extractThoughtResponseFromMessages = extractThoughtResponseFromMessages;
42
43
  exports.parseInnerDialogSession = parseInnerDialogSession;
43
44
  exports.formatThoughtTurns = formatThoughtTurns;
44
45
  exports.getInnerDialogSessionPath = getInnerDialogSessionPath;
45
46
  exports.readInnerDialogStatus = readInnerDialogStatus;
47
+ exports.readInnerDialogRawData = readInnerDialogRawData;
46
48
  exports.followThoughts = followThoughts;
47
49
  const fs = __importStar(require("fs"));
48
50
  const path = __importStar(require("path"));
51
+ const session_events_1 = require("../session-events");
49
52
  const runtime_1 = require("../../nerves/runtime");
50
53
  function contentToText(content) {
51
54
  if (typeof content === "string")
@@ -91,7 +94,7 @@ function extractToolNames(messages) {
91
94
  if (msg.role === "assistant" && Array.isArray(msg.tool_calls)) {
92
95
  for (const tc of msg.tool_calls) {
93
96
  const toolFunction = extractToolFunction(tc);
94
- if (toolFunction?.name && toolFunction.name !== "final_answer")
97
+ if (toolFunction?.name && toolFunction.name !== "settle")
95
98
  names.push(toolFunction.name);
96
99
  }
97
100
  }
@@ -149,6 +152,21 @@ function formatSurfacedValue(text, maxLength = 120) {
149
152
  return `"${firstLine}"`;
150
153
  return `"${firstLine.slice(0, maxLength - 3)}..."`;
151
154
  }
155
+ function extractEnrichedFields(pendingMessages) {
156
+ const delegated = pendingMessages.find((msg) => msg.delegatedFrom);
157
+ if (!delegated?.delegatedFrom)
158
+ return {};
159
+ const snippet = delegated.content.length > 80 ? delegated.content.slice(0, 77) + "..." : delegated.content;
160
+ return {
161
+ origin: {
162
+ friendId: delegated.delegatedFrom.friendId,
163
+ channel: delegated.delegatedFrom.channel,
164
+ key: delegated.delegatedFrom.key,
165
+ },
166
+ contentSnippet: snippet,
167
+ ...(delegated.obligationStatus === "pending" ? { obligationPending: true } : {}),
168
+ };
169
+ }
152
170
  function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
153
171
  if (runtimeState?.status === "running") {
154
172
  if (pendingMessages.length > 0) {
@@ -157,6 +175,7 @@ function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
157
175
  wake: "queued behind active turn",
158
176
  processing: "pending",
159
177
  surfaced: "nothing yet",
178
+ ...extractEnrichedFields(pendingMessages),
160
179
  };
161
180
  }
162
181
  return {
@@ -172,6 +191,7 @@ function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
172
191
  wake: "awaiting inner session",
173
192
  processing: "pending",
174
193
  surfaced: "nothing yet",
194
+ ...extractEnrichedFields(pendingMessages),
175
195
  };
176
196
  }
177
197
  const latestProcessedPendingTurn = [...turns]
@@ -192,23 +212,125 @@ function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
192
212
  surfaced: formatSurfacedValue(latestProcessedPendingTurn.response),
193
213
  };
194
214
  }
215
+ function deriveInnerJob(pendingMessages, turns, runtimeState) {
216
+ const isRunning = runtimeState?.status === "running";
217
+ const delegated = pendingMessages.find((msg) => msg.delegatedFrom);
218
+ const enriched = extractEnrichedFields(pendingMessages);
219
+ const pendingMode = delegated && "mode" in delegated && delegated.mode ? delegated.mode : "reflect";
220
+ const origin = enriched.origin ?? null;
221
+ const content = delegated?.content ?? null;
222
+ const obligationStatus = delegated?.obligationStatus ?? null;
223
+ const queuedAt = delegated?.timestamp ?? null;
224
+ if (isRunning) {
225
+ (0, runtime_1.emitNervesEvent)({
226
+ component: "engine",
227
+ event: "engine.inner_job_derive",
228
+ message: "derived inner job state",
229
+ meta: { status: "running", mode: pendingMode, hasOrigin: origin !== null, hasObligation: obligationStatus !== null },
230
+ });
231
+ return {
232
+ status: "running",
233
+ content,
234
+ origin,
235
+ mode: pendingMode,
236
+ obligationStatus,
237
+ surfacedResult: null,
238
+ queuedAt,
239
+ startedAt: runtimeState?.startedAt ?? null,
240
+ surfacedAt: null,
241
+ };
242
+ }
243
+ if (pendingMessages.length > 0) {
244
+ (0, runtime_1.emitNervesEvent)({
245
+ component: "engine",
246
+ event: "engine.inner_job_derive",
247
+ message: "derived inner job state",
248
+ meta: { status: "queued", mode: pendingMode, hasOrigin: origin !== null, hasObligation: obligationStatus !== null },
249
+ });
250
+ return {
251
+ status: "queued",
252
+ content,
253
+ origin,
254
+ mode: pendingMode,
255
+ obligationStatus,
256
+ surfacedResult: null,
257
+ queuedAt,
258
+ startedAt: null,
259
+ surfacedAt: null,
260
+ };
261
+ }
262
+ // No pending, not running -- check for surfaced result
263
+ const latestProcessedPendingTurn = [...turns]
264
+ .reverse()
265
+ .find((turn) => extractPendingPromptMessages(turn.prompt).length > 0);
266
+ if (latestProcessedPendingTurn) {
267
+ const surfacedResult = extractThoughtResponseFromMessages([
268
+ { role: "assistant", content: latestProcessedPendingTurn.response },
269
+ ]);
270
+ (0, runtime_1.emitNervesEvent)({
271
+ component: "engine",
272
+ event: "engine.inner_job_derive",
273
+ message: "derived inner job state",
274
+ meta: { status: "surfaced", mode: "reflect", hasOrigin: false, hasObligation: false },
275
+ });
276
+ return {
277
+ status: "surfaced",
278
+ content: null,
279
+ origin: null,
280
+ mode: "reflect",
281
+ obligationStatus: null,
282
+ /* v8 ignore next -- defensive: surfacedResult fallback @preserve */
283
+ surfacedResult: surfacedResult || null,
284
+ queuedAt: null,
285
+ startedAt: null,
286
+ surfacedAt: null,
287
+ };
288
+ }
289
+ (0, runtime_1.emitNervesEvent)({
290
+ component: "engine",
291
+ event: "engine.inner_job_derive",
292
+ message: "derived inner job state",
293
+ meta: { status: "idle", mode: "reflect", hasOrigin: false, hasObligation: false },
294
+ });
295
+ return {
296
+ status: "idle",
297
+ content: null,
298
+ origin: null,
299
+ mode: "reflect",
300
+ obligationStatus: null,
301
+ surfacedResult: null,
302
+ queuedAt: null,
303
+ startedAt: null,
304
+ surfacedAt: null,
305
+ };
306
+ }
195
307
  function formatInnerDialogStatus(status) {
196
- return [
308
+ const lines = [
197
309
  `queue: ${status.queue}`,
198
310
  `wake: ${status.wake}`,
199
311
  `processing: ${status.processing}`,
200
312
  `surfaced: ${status.surfaced}`,
201
- ].join("\n");
313
+ ];
314
+ if (status.origin) {
315
+ lines.push(`origin: ${status.origin.friendId}/${status.origin.channel}/${status.origin.key}`);
316
+ }
317
+ if (status.contentSnippet) {
318
+ lines.push(`asked: ${status.contentSnippet}`);
319
+ }
320
+ if (status.obligationPending) {
321
+ lines.push("obligation: pending");
322
+ }
323
+ return lines.join("\n");
202
324
  }
203
- /** Extract text from a final_answer tool call's arguments. */
204
- function extractFinalAnswer(messages) {
325
+ /** Extract text from a settle tool call's arguments. */
326
+ function extractSettleAnswer(messages) {
205
327
  for (let k = messages.length - 1; k >= 0; k--) {
206
328
  const msg = messages[k];
207
329
  if (msg.role !== "assistant" || !Array.isArray(msg.tool_calls))
208
330
  continue;
209
331
  for (const tc of msg.tool_calls) {
210
332
  const toolFunction = extractToolFunction(tc);
211
- if (toolFunction?.name !== "final_answer")
333
+ if (toolFunction?.name !== "settle")
212
334
  continue;
213
335
  try {
214
336
  const parsed = JSON.parse(toolFunction.arguments ?? "{}");
@@ -227,7 +349,7 @@ function extractThoughtResponseFromMessages(messages) {
227
349
  const lastAssistant = assistantMsgs.reverse().find((message) => contentToText(message.content).trim().length > 0);
228
350
  return lastAssistant
229
351
  ? contentToText(lastAssistant.content).trim()
230
- : extractFinalAnswer(messages);
352
+ : extractSettleAnswer(messages);
231
353
  }
232
354
  function parseInnerDialogSession(sessionPath) {
233
355
  (0, runtime_1.emitNervesEvent)({
@@ -243,21 +365,34 @@ function parseInnerDialogSession(sessionPath) {
243
365
  catch {
244
366
  return [];
245
367
  }
246
- let data;
368
+ let parsedRaw;
247
369
  try {
248
- data = JSON.parse(raw);
370
+ parsedRaw = JSON.parse(raw);
249
371
  }
250
372
  catch {
251
373
  return [];
252
374
  }
253
- if (data.version !== 1 || !Array.isArray(data.messages))
375
+ const legacyRecord = parsedRaw && typeof parsedRaw === "object"
376
+ ? parsedRaw
377
+ : null;
378
+ const messages = legacyRecord?.version === 1 && Array.isArray(legacyRecord.messages)
379
+ ? legacyRecord.messages
380
+ : (() => {
381
+ const envelope = (0, session_events_1.parseSessionEnvelope)(parsedRaw, {
382
+ recordedAt: new Date().toISOString(),
383
+ });
384
+ if (!envelope)
385
+ return null;
386
+ return (0, session_events_1.projectProviderMessages)(envelope);
387
+ })();
388
+ if (!messages)
254
389
  return [];
390
+ const normalizedMessages = messages;
255
391
  const turns = [];
256
- const messages = data.messages;
257
392
  // Walk messages, pairing user → (tool calls) → assistant sequences
258
393
  let i = 0;
259
- while (i < messages.length) {
260
- const msg = messages[i];
394
+ while (i < normalizedMessages.length) {
395
+ const msg = normalizedMessages[i];
261
396
  if (msg.role === "system") {
262
397
  i++;
263
398
  continue;
@@ -271,12 +406,12 @@ function parseInnerDialogSession(sessionPath) {
271
406
  // Collect all messages until the next user message (or end)
272
407
  const turnMessages = [];
273
408
  let j = i + 1;
274
- while (j < messages.length && messages[j].role !== "user") {
275
- turnMessages.push(messages[j]);
409
+ while (j < normalizedMessages.length && normalizedMessages[j].role !== "user") {
410
+ turnMessages.push(normalizedMessages[j]);
276
411
  j++;
277
412
  }
278
413
  // Find the last assistant text response in this turn.
279
- // With tool_choice="required", the response may be inside a final_answer tool call.
414
+ // With tool_choice="required", the response may be inside a settle tool call.
280
415
  const response = extractThoughtResponseFromMessages(turnMessages);
281
416
  const tools = extractToolNames(turnMessages);
282
417
  turns.push({
@@ -347,6 +482,13 @@ function readInnerDialogStatus(sessionPath, pendingDir, runtimePath = getInnerDi
347
482
  const runtimeState = readInnerDialogRuntimeState(runtimePath);
348
483
  return deriveInnerDialogStatus(pendingMessages, turns, runtimeState);
349
484
  }
485
+ function readInnerDialogRawData(sessionPath, pendingDir) {
486
+ const runtimePath = getInnerDialogRuntimeStatePath(sessionPath);
487
+ const pendingMessages = readPendingMessagesForStatus(pendingDir);
488
+ const turns = parseInnerDialogSession(sessionPath);
489
+ const runtimeState = readInnerDialogRuntimeState(runtimePath);
490
+ return { pendingMessages, turns, runtimeState };
491
+ }
350
492
  /**
351
493
  * Watch a session file and emit new turns as they appear.
352
494
  * Returns a cleanup function that stops the watcher.
@@ -369,9 +511,12 @@ function followThoughts(sessionPath, onNewTurns, pollIntervalMs = 1000) {
369
511
  });
370
512
  return () => {
371
513
  fs.unwatchFile(sessionPath);
514
+ // Must be named `_end` (not `_stop`) to satisfy the nerves audit's
515
+ // start/end pairing rule — see src/nerves/coverage/audit-rules.ts which
516
+ // pairs `<prefix>_start` with `<prefix>_end` or `<prefix>_error`.
372
517
  (0, runtime_1.emitNervesEvent)({
373
518
  component: "daemon",
374
- event: "daemon.thoughts_follow_stop",
519
+ event: "daemon.thoughts_follow_end",
375
520
  message: "stopped following inner dialog session",
376
521
  meta: { sessionPath, totalTurns: displayedCount },
377
522
  });
@@ -0,0 +1,366 @@
1
+ "use strict";
2
+ /**
3
+ * UpProgress — accumulated-checklist progress renderer.
4
+ *
5
+ * Displays completed phases with checkmarks, the current phase with a
6
+ * spinner and elapsed time, and pending phases as plain text. Uses ANSI
7
+ * cursor control for in-place overwriting in TTY mode, and falls back to
8
+ * static line-per-phase output in non-TTY mode.
9
+ *
10
+ * The caller can drive animation by calling `render(now)`. In production CLI
11
+ * use, `autoRender` starts a short-lived timer while a TTY phase is active so
12
+ * long operations never leave a dead-looking cursor.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CommandProgress = exports.UpProgress = void 0;
16
+ const runtime_1 = require("../../nerves/runtime");
17
+ const terminal_ui_1 = require("./terminal-ui");
18
+ // ── ANSI constants (shared with startup-tui.ts pattern) ──
19
+ const SPINNER_FRAMES = "\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F";
20
+ const RESET = "\x1b[0m";
21
+ const BOLD = "\x1b[1m";
22
+ const DIM = "\x1b[2m";
23
+ const GREEN = "\x1b[38;2;46;204;64m";
24
+ const RED = "\x1b[38;2;255;106;106m";
25
+ const BASE_UP_PHASE_PLAN = [
26
+ "update check",
27
+ "system setup",
28
+ "provider checks",
29
+ "starting daemon",
30
+ "final daemon check",
31
+ ];
32
+ const FRIENDLY_UP_PHASE_LABELS = {
33
+ "update check": "Check for updates",
34
+ "system setup": "Prepare this machine",
35
+ "agent updates": "Update installed agents",
36
+ "bundle cleanup": "Clean up stale bundles",
37
+ "provider checks": "Check the providers your agents use right now",
38
+ "starting daemon": "Start the background service",
39
+ "final daemon check": "Confirm the background service stayed up",
40
+ };
41
+ function splitDetailLines(detail) {
42
+ if (!detail)
43
+ return [];
44
+ return detail
45
+ .split(/\r?\n/)
46
+ .map((line) => line.trimEnd())
47
+ .filter((line) => line.length > 0);
48
+ }
49
+ // ── UpProgress class ──
50
+ class UpProgress {
51
+ write;
52
+ isTTY;
53
+ columns;
54
+ now;
55
+ autoRender;
56
+ renderIntervalMs;
57
+ setTimer;
58
+ clearTimer;
59
+ eventScope;
60
+ commandName;
61
+ completed = [];
62
+ currentPhase = null;
63
+ currentDetail = null;
64
+ upPhasePlan = BASE_UP_PHASE_PLAN;
65
+ prevLineCount = 0;
66
+ ended = false;
67
+ renderTimer = null;
68
+ constructor(options) {
69
+ /* v8 ignore next -- thin wrapper: raw process.stdout.write for ANSI cursor control @preserve */
70
+ this.write = options?.write ?? ((text) => process.stdout.write(text));
71
+ /* v8 ignore next -- thin wrapper: real isTTY check injected for testability @preserve */
72
+ this.isTTY = options?.isTTY ?? (process.stdout.isTTY === true);
73
+ this.columns = options?.columns;
74
+ /* v8 ignore next -- thin wrapper: real Date.now injected for testability @preserve */
75
+ this.now = options?.now ?? (() => Date.now());
76
+ this.autoRender = options?.autoRender ?? false;
77
+ this.renderIntervalMs = options?.renderIntervalMs ?? 80;
78
+ /* v8 ignore start -- real timers are injected in tests when needed @preserve */
79
+ this.setTimer = options?.setInterval ?? ((callback, ms) => setInterval(callback, ms));
80
+ this.clearTimer = options?.clearInterval ?? ((handle) => clearInterval(handle));
81
+ /* v8 ignore stop */
82
+ this.eventScope = options?.eventScope ?? "up";
83
+ this.commandName = options?.commandName ?? null;
84
+ }
85
+ /**
86
+ * Begin a new phase with spinner. If a phase is already active, it is
87
+ * auto-completed (no detail text).
88
+ */
89
+ startPhase(label) {
90
+ if (this.currentPhase) {
91
+ this.completePhase(this.currentPhase.label);
92
+ }
93
+ this.currentPhase = { label, startedAt: this.now() };
94
+ this.currentDetail = null;
95
+ if (this.isTTY) {
96
+ this.ensureAutoRender();
97
+ this.flushRender();
98
+ }
99
+ else {
100
+ this.write(` ... ${label}\n`);
101
+ }
102
+ }
103
+ /**
104
+ * Emit a one-line status breadcrumb in non-TTY mode without affecting the
105
+ * accumulated checklist state. Used for daemon startup sub-steps.
106
+ */
107
+ announceStep(label) {
108
+ if (this.currentPhase) {
109
+ this.updateDetail(label);
110
+ return;
111
+ }
112
+ if (this.isTTY)
113
+ return;
114
+ this.write(` ${label}\n`);
115
+ }
116
+ setPhasePlan(labels) {
117
+ const nextPlan = [...new Set(labels.map((label) => label.trim()).filter((label) => label.length > 0))];
118
+ this.upPhasePlan = nextPlan.length > 0 ? nextPlan : BASE_UP_PHASE_PLAN;
119
+ if (this.isTTY && this.eventScope === "up") {
120
+ this.flushRender();
121
+ }
122
+ }
123
+ /**
124
+ * Update the sub-step detail on the current spinner phase. Rendered as
125
+ * "label (Xs) -- detail" in TTY mode. In non-TTY mode, writes changed
126
+ * detail lines so long operations remain visible in logs and captured output.
127
+ */
128
+ updateDetail(detail) {
129
+ if (!this.currentPhase || detail === this.currentDetail)
130
+ return;
131
+ this.currentDetail = detail;
132
+ this.currentPhase.detail = detail;
133
+ if (this.isTTY) {
134
+ this.flushRender();
135
+ return;
136
+ }
137
+ for (const line of splitDetailLines(detail)) {
138
+ this.write(` ${line}\n`);
139
+ }
140
+ }
141
+ /**
142
+ * Mark the current phase as done. In non-TTY mode, immediately writes
143
+ * a static line. Emits a nerves event for observability.
144
+ */
145
+ completePhase(label, detail) {
146
+ if (!this.currentPhase) {
147
+ return;
148
+ }
149
+ const elapsedMs = this.now() - this.currentPhase.startedAt;
150
+ this.completed.push({ status: "success", label, detail });
151
+ this.currentPhase = null;
152
+ this.currentDetail = null;
153
+ this.stopAutoRender();
154
+ if (this.eventScope === "command") {
155
+ (0, runtime_1.emitNervesEvent)({
156
+ component: "daemon",
157
+ event: "daemon.cli_progress_phase_complete",
158
+ message: `phase complete: ${label}`,
159
+ meta: { command: this.commandName, phase: label, detail: detail ?? null, elapsedMs },
160
+ });
161
+ }
162
+ else {
163
+ (0, runtime_1.emitNervesEvent)({
164
+ component: "daemon",
165
+ event: "daemon.up_phase_complete",
166
+ message: `phase complete: ${label}`,
167
+ meta: { phase: label, detail: detail ?? null, elapsedMs },
168
+ });
169
+ }
170
+ if (this.isTTY) {
171
+ this.flushRender();
172
+ }
173
+ else {
174
+ const detailStr = detail ? ` \u2014 ${detail}` : "";
175
+ this.write(` \u2713 ${label}${detailStr}\n`);
176
+ }
177
+ }
178
+ failPhase(label, detail) {
179
+ if (!this.currentPhase) {
180
+ return;
181
+ }
182
+ const elapsedMs = this.now() - this.currentPhase.startedAt;
183
+ this.completed.push({ status: "failure", label, detail });
184
+ this.currentPhase = null;
185
+ this.currentDetail = null;
186
+ this.stopAutoRender();
187
+ if (this.eventScope === "command") {
188
+ (0, runtime_1.emitNervesEvent)({
189
+ level: "warn",
190
+ component: "daemon",
191
+ event: "daemon.cli_progress_phase_failed",
192
+ message: `phase failed: ${label}`,
193
+ meta: { command: this.commandName, phase: label, detail: detail ?? null, elapsedMs },
194
+ });
195
+ }
196
+ else {
197
+ (0, runtime_1.emitNervesEvent)({
198
+ level: "warn",
199
+ component: "daemon",
200
+ event: "daemon.up_phase_failed",
201
+ message: `phase failed: ${label}`,
202
+ meta: { phase: label, detail: detail ?? null, elapsedMs },
203
+ });
204
+ }
205
+ if (this.isTTY) {
206
+ this.flushRender();
207
+ }
208
+ else {
209
+ const detailStr = detail ? ` \u2014 ${detail}` : "";
210
+ this.write(` \u2717 ${label}${detailStr}\n`);
211
+ }
212
+ }
213
+ /**
214
+ * Build an ANSI string for in-place terminal display. Returns empty
215
+ * string in non-TTY mode (output is written eagerly in completePhase).
216
+ */
217
+ render(now) {
218
+ if (!this.isTTY) {
219
+ return "";
220
+ }
221
+ const lines = this.renderLines(now);
222
+ const output = (0, terminal_ui_1.renderOverwriteFrame)(lines, this.prevLineCount, true);
223
+ this.prevLineCount = lines.length;
224
+ return output;
225
+ }
226
+ /**
227
+ * Finalize the progress display. Clears the current phase (if any) and
228
+ * writes the final checklist state. Idempotent.
229
+ */
230
+ end() {
231
+ if (this.ended) {
232
+ return;
233
+ }
234
+ this.ended = true;
235
+ if (this.currentPhase) {
236
+ this.currentPhase = null;
237
+ this.currentDetail = null;
238
+ }
239
+ this.stopAutoRender();
240
+ if (this.isTTY) {
241
+ this.flushRender();
242
+ }
243
+ }
244
+ ensureAutoRender() {
245
+ if (!this.autoRender || !this.isTTY || this.renderTimer !== null) {
246
+ return;
247
+ }
248
+ this.renderTimer = this.setTimer(() => this.flushRender(), this.renderIntervalMs);
249
+ }
250
+ stopAutoRender() {
251
+ if (this.renderTimer === null) {
252
+ return;
253
+ }
254
+ this.clearTimer(this.renderTimer);
255
+ this.renderTimer = null;
256
+ }
257
+ flushRender() {
258
+ const output = this.render(this.now());
259
+ this.write(output);
260
+ }
261
+ renderLines(now) {
262
+ if (this.eventScope === "up") {
263
+ return this.renderUpScreen(now);
264
+ }
265
+ const lines = [];
266
+ for (const phase of this.completed) {
267
+ const detailStr = phase.detail ? ` ${DIM}\u2014 ${phase.detail}${RESET}` : "";
268
+ if (phase.status === "failure") {
269
+ lines.push(` ${RED}\u2717${RESET} ${phase.label}${detailStr}`);
270
+ }
271
+ else {
272
+ lines.push(` ${GREEN}\u2713${RESET} ${phase.label}${detailStr}`);
273
+ }
274
+ }
275
+ if (this.currentPhase) {
276
+ const elapsed = now - this.currentPhase.startedAt;
277
+ const elapsedSec = (elapsed / 1000).toFixed(1);
278
+ const frameIndex = Math.floor(elapsed / 80) % SPINNER_FRAMES.length;
279
+ const spinner = SPINNER_FRAMES[frameIndex];
280
+ lines.push(` ${BOLD}${spinner}${RESET} ${this.currentPhase.label} ${DIM}(${elapsedSec}s)${RESET}`);
281
+ for (const detailLine of splitDetailLines(this.currentPhase.detail)) {
282
+ lines.push(` ${DIM}${detailLine}${RESET}`);
283
+ }
284
+ }
285
+ return lines;
286
+ }
287
+ renderUpStepLabel(label) {
288
+ return FRIENDLY_UP_PHASE_LABELS[label] ?? label;
289
+ }
290
+ renderUpScreen(now) {
291
+ const seenLabels = new Set();
292
+ const completedByLabel = new Map(this.completed.map((phase) => [phase.label, phase]));
293
+ const steps = [];
294
+ let currentStepLabel = this.completed.some((phase) => phase.status === "failure")
295
+ ? "Boot paused."
296
+ : this.completed.length > 0
297
+ ? "Boot checklist complete."
298
+ : "Waiting to begin.";
299
+ let currentStepDetails = [];
300
+ if (this.currentPhase) {
301
+ const elapsed = now - this.currentPhase.startedAt;
302
+ const elapsedSec = (elapsed / 1000).toFixed(1);
303
+ const frameIndex = Math.floor(elapsed / 80) % SPINNER_FRAMES.length;
304
+ const spinner = SPINNER_FRAMES[frameIndex];
305
+ currentStepLabel = `${spinner} ${this.renderUpStepLabel(this.currentPhase.label)} (${elapsedSec}s)`;
306
+ currentStepDetails = splitDetailLines(this.currentPhase.detail);
307
+ }
308
+ for (const label of this.upPhasePlan) {
309
+ seenLabels.add(label);
310
+ const completedPhase = completedByLabel.get(label);
311
+ if (completedPhase) {
312
+ steps.push({
313
+ label: this.renderUpStepLabel(label),
314
+ status: completedPhase.status === "failure" ? "failed" : "done",
315
+ detail: completedPhase.detail,
316
+ });
317
+ continue;
318
+ }
319
+ if (this.currentPhase?.label === label) {
320
+ steps.push({
321
+ label: this.renderUpStepLabel(label),
322
+ status: "active",
323
+ });
324
+ continue;
325
+ }
326
+ steps.push({
327
+ label: this.renderUpStepLabel(label),
328
+ status: "pending",
329
+ });
330
+ }
331
+ for (const phase of this.completed) {
332
+ if (!seenLabels.has(phase.label)) {
333
+ steps.push({
334
+ label: this.renderUpStepLabel(phase.label),
335
+ status: phase.status === "failure" ? "failed" : "done",
336
+ detail: phase.detail,
337
+ });
338
+ }
339
+ }
340
+ if (this.currentPhase && !seenLabels.has(this.currentPhase.label)) {
341
+ steps.push({
342
+ label: this.renderUpStepLabel(this.currentPhase.label),
343
+ status: "active",
344
+ });
345
+ }
346
+ return (0, terminal_ui_1.renderTerminalOperation)({
347
+ isTTY: true,
348
+ columns: this.columns,
349
+ masthead: {
350
+ subtitle: "Booting the local agent runtime.",
351
+ },
352
+ title: "Starting Ouro",
353
+ summary: "Ouro is bringing the local agent runtime online and will stop here if anything needs attention.",
354
+ currentStep: {
355
+ label: currentStepLabel,
356
+ detailLines: currentStepDetails,
357
+ },
358
+ steps,
359
+ currentTitle: "Doing now",
360
+ stepsTitle: "Boot checklist",
361
+ suppressEvent: true,
362
+ }).trimEnd().split("\n");
363
+ }
364
+ }
365
+ exports.UpProgress = UpProgress;
366
+ exports.CommandProgress = UpProgress;