@ouro.bot/cli 0.1.0-alpha.67 → 0.1.0-alpha.671

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 (457) 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 +4277 -16
  13. package/dist/a2a/card.js +56 -0
  14. package/dist/a2a/client.js +143 -0
  15. package/dist/a2a/config.js +50 -0
  16. package/dist/a2a/onboarding.js +83 -0
  17. package/dist/a2a/server.js +498 -0
  18. package/dist/a2a/task-store.js +69 -0
  19. package/dist/a2a/types.js +3 -0
  20. package/dist/arc/attention-types.js +8 -0
  21. package/dist/arc/cares.js +144 -0
  22. package/dist/arc/episodes.js +118 -0
  23. package/dist/arc/evolution.js +487 -0
  24. package/dist/arc/flight-recorder.js +810 -0
  25. package/dist/arc/intentions.js +134 -0
  26. package/dist/arc/json-store.js +117 -0
  27. package/dist/arc/obligations.js +326 -0
  28. package/dist/arc/packets.js +288 -0
  29. package/dist/arc/presence.js +185 -0
  30. package/dist/arc/task-lifecycle.js +57 -0
  31. package/dist/commerce/store.js +755 -0
  32. package/dist/commerce/types.js +3 -0
  33. package/dist/heart/active-work.js +860 -43
  34. package/dist/heart/agent-entry.js +69 -3
  35. package/dist/heart/attachments/image-normalize.js +194 -0
  36. package/dist/heart/attachments/materialize.js +97 -0
  37. package/dist/heart/attachments/originals.js +88 -0
  38. package/dist/heart/attachments/render.js +29 -0
  39. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  40. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  41. package/dist/heart/attachments/sources/index.js +16 -0
  42. package/dist/heart/attachments/store.js +103 -0
  43. package/dist/heart/attachments/types.js +93 -0
  44. package/dist/heart/auth/auth-flow.js +479 -0
  45. package/dist/heart/awaiting/await-alert.js +146 -0
  46. package/dist/heart/awaiting/await-expiry.js +108 -0
  47. package/dist/heart/awaiting/await-loader.js +91 -0
  48. package/dist/heart/awaiting/await-parser.js +141 -0
  49. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  50. package/dist/heart/awaiting/await-scheduler.js +378 -0
  51. package/dist/heart/background-operations.js +281 -0
  52. package/dist/heart/bridges/manager.js +137 -17
  53. package/dist/heart/bridges/store.js +14 -2
  54. package/dist/heart/bundle-state.js +168 -0
  55. package/dist/heart/commitments.js +135 -0
  56. package/dist/heart/config-registry.js +331 -0
  57. package/dist/heart/config.js +118 -119
  58. package/dist/heart/context-loss-gauntlet.js +354 -0
  59. package/dist/heart/context-loss-sentinel.js +907 -0
  60. package/dist/heart/core.js +1288 -249
  61. package/dist/heart/cross-chat-delivery.js +8 -22
  62. package/dist/heart/daemon/agent-config-check.js +427 -0
  63. package/dist/heart/daemon/agent-discovery.js +102 -3
  64. package/dist/heart/daemon/agent-service.js +523 -0
  65. package/dist/heart/daemon/agentic-repair.js +547 -0
  66. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  67. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  68. package/dist/heart/daemon/cadence.js +70 -0
  69. package/dist/heart/daemon/cli-defaults.js +780 -0
  70. package/dist/heart/daemon/cli-desk.js +322 -0
  71. package/dist/heart/daemon/cli-exec.js +7940 -0
  72. package/dist/heart/daemon/cli-help.js +576 -0
  73. package/dist/heart/daemon/cli-parse.js +1850 -0
  74. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  75. package/dist/heart/daemon/cli-render.js +763 -0
  76. package/dist/heart/daemon/cli-types.js +8 -0
  77. package/dist/heart/daemon/connect-bay.js +323 -0
  78. package/dist/heart/daemon/daemon-cli.js +29 -1750
  79. package/dist/heart/daemon/daemon-entry.js +533 -3
  80. package/dist/heart/daemon/daemon-health.js +176 -0
  81. package/dist/heart/daemon/daemon-rollup.js +57 -0
  82. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  83. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  84. package/dist/heart/daemon/daemon.js +950 -76
  85. package/dist/heart/daemon/dns-workflow.js +394 -0
  86. package/dist/heart/daemon/doctor-types.js +8 -0
  87. package/dist/heart/daemon/doctor.js +873 -0
  88. package/dist/heart/daemon/health-monitor.js +125 -1
  89. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  90. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  91. package/dist/heart/daemon/http-health-probe.js +80 -0
  92. package/dist/heart/daemon/human-command-screens.js +234 -0
  93. package/dist/heart/daemon/human-readiness.js +114 -0
  94. package/dist/heart/daemon/inner-status.js +78 -0
  95. package/dist/heart/daemon/interactive-repair.js +394 -0
  96. package/dist/heart/daemon/launchd.js +37 -8
  97. package/dist/heart/daemon/log-tailer.js +79 -10
  98. package/dist/heart/daemon/logs-prune.js +110 -0
  99. package/dist/heart/daemon/mcp-canary.js +297 -0
  100. package/dist/heart/daemon/message-router.js +6 -2
  101. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  102. package/dist/heart/daemon/os-cron-deps.js +135 -0
  103. package/dist/heart/daemon/os-cron.js +14 -12
  104. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  105. package/dist/heart/daemon/ouro-entry.js +3 -1
  106. package/dist/heart/daemon/plugin-cli.js +432 -0
  107. package/dist/heart/daemon/process-manager.js +511 -40
  108. package/dist/heart/daemon/provider-discovery.js +137 -0
  109. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  110. package/dist/heart/daemon/pulse.js +475 -0
  111. package/dist/heart/daemon/readiness-repair.js +365 -0
  112. package/dist/heart/daemon/run-hooks.js +2 -0
  113. package/dist/heart/daemon/runtime-logging.js +41 -14
  114. package/dist/heart/daemon/runtime-metadata.js +2 -30
  115. package/dist/heart/daemon/safe-mode.js +161 -0
  116. package/dist/heart/daemon/sense-manager.js +564 -38
  117. package/dist/heart/daemon/session-id-resolver.js +131 -0
  118. package/dist/heart/daemon/skill-management-installer.js +1 -1
  119. package/dist/heart/daemon/socket-client.js +158 -11
  120. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  121. package/dist/heart/daemon/startup-tui.js +330 -0
  122. package/dist/heart/daemon/task-scheduler.js +117 -39
  123. package/dist/heart/daemon/terminal-ui.js +499 -0
  124. package/dist/heart/daemon/thoughts.js +229 -17
  125. package/dist/heart/daemon/up-progress.js +366 -0
  126. package/dist/heart/daemon/vault-items.js +56 -0
  127. package/dist/heart/delegation.js +1 -4
  128. package/dist/heart/habits/habit-migration.js +189 -0
  129. package/dist/heart/habits/habit-parser.js +211 -0
  130. package/dist/heart/habits/habit-runtime-state.js +114 -0
  131. package/dist/heart/habits/habit-scheduler.js +391 -0
  132. package/dist/heart/habits/habit-session-summary.js +318 -0
  133. package/dist/heart/habits/habit-session.js +618 -0
  134. package/dist/heart/{daemon → hatch}/hatch-flow.js +42 -56
  135. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  136. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  137. package/dist/heart/{daemon → hatch}/specialist-tools.js +45 -18
  138. package/dist/heart/identity.js +174 -57
  139. package/dist/heart/kept-notes.js +289 -0
  140. package/dist/heart/kicks.js +1 -1
  141. package/dist/heart/machine-identity.js +161 -0
  142. package/dist/heart/mail-import-discovery.js +353 -0
  143. package/dist/heart/mailbox/mailbox-http-hooks.js +96 -0
  144. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  145. package/dist/heart/mailbox/mailbox-http-routes.js +375 -0
  146. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  147. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  148. package/dist/heart/mailbox/mailbox-http.js +99 -0
  149. package/dist/heart/mailbox/mailbox-read.js +37 -0
  150. package/dist/heart/mailbox/mailbox-types.js +27 -0
  151. package/dist/heart/mailbox/mailbox-view.js +197 -0
  152. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  153. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  154. package/dist/heart/mailbox/readers/mail.js +375 -0
  155. package/dist/heart/mailbox/readers/runtime-readers.js +815 -0
  156. package/dist/heart/mailbox/readers/sessions.js +232 -0
  157. package/dist/heart/mailbox/readers/shared.js +111 -0
  158. package/dist/heart/mcp/mcp-server.js +696 -0
  159. package/dist/heart/migrate-config.js +100 -0
  160. package/dist/heart/model-capabilities.js +19 -0
  161. package/dist/heart/orientation-frame.js +217 -0
  162. package/dist/heart/platform.js +81 -0
  163. package/dist/heart/provider-attempt.js +134 -0
  164. package/dist/heart/provider-binding-resolver.js +273 -0
  165. package/dist/heart/provider-credentials.js +425 -0
  166. package/dist/heart/provider-failover.js +311 -0
  167. package/dist/heart/provider-models.js +81 -0
  168. package/dist/heart/provider-ping.js +262 -0
  169. package/dist/heart/provider-readiness-cache.js +119 -0
  170. package/dist/heart/provider-visibility.js +188 -0
  171. package/dist/heart/providers/anthropic-token.js +131 -0
  172. package/dist/heart/providers/anthropic.js +139 -52
  173. package/dist/heart/providers/azure.js +23 -11
  174. package/dist/heart/providers/error-classification.js +127 -0
  175. package/dist/heart/providers/github-copilot.js +145 -0
  176. package/dist/heart/providers/minimax-vlm.js +189 -0
  177. package/dist/heart/providers/minimax.js +26 -8
  178. package/dist/heart/providers/openai-codex-token.js +349 -0
  179. package/dist/heart/providers/openai-codex.js +55 -40
  180. package/dist/heart/runtime-capability-check.js +170 -0
  181. package/dist/heart/runtime-credentials.js +367 -0
  182. package/dist/heart/runtime-cwd.js +87 -0
  183. package/dist/heart/sense-truth.js +17 -4
  184. package/dist/heart/session-activity.js +48 -24
  185. package/dist/heart/session-events.js +1133 -0
  186. package/dist/heart/session-playback-cli-main.js +5 -0
  187. package/dist/heart/session-playback-cli.js +36 -0
  188. package/dist/heart/session-playback.js +231 -0
  189. package/dist/heart/session-stats-cli-main.js +5 -0
  190. package/dist/heart/session-stats.js +182 -0
  191. package/dist/heart/session-transcript.js +133 -0
  192. package/dist/heart/start-of-turn-packet.js +357 -0
  193. package/dist/heart/streaming.js +44 -27
  194. package/dist/heart/structured-output.js +196 -0
  195. package/dist/heart/sync-classification.js +176 -0
  196. package/dist/heart/sync.js +449 -0
  197. package/dist/heart/target-resolution.js +11 -7
  198. package/dist/heart/tempo.js +93 -0
  199. package/dist/heart/temporal-view.js +41 -0
  200. package/dist/heart/timeouts.js +101 -0
  201. package/dist/heart/tool-activity-callbacks.js +59 -0
  202. package/dist/heart/tool-description.js +155 -0
  203. package/dist/heart/tool-friction.js +55 -0
  204. package/dist/heart/tool-loop.js +200 -0
  205. package/dist/heart/turn-context.js +450 -0
  206. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  207. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  208. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  209. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  210. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  211. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  212. package/dist/heart/versioning/update-hooks.js +154 -0
  213. package/dist/heart/work-card.js +390 -0
  214. package/dist/mailbox-ui/assets/index-CaTIFDmv.js +1 -0
  215. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  216. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  217. package/dist/mailbox-ui/index.html +16 -0
  218. package/dist/mailroom/attention.js +167 -0
  219. package/dist/mailroom/autonomy.js +209 -0
  220. package/dist/mailroom/blob-store.js +715 -0
  221. package/dist/mailroom/body-cache.js +61 -0
  222. package/dist/mailroom/core.js +788 -0
  223. package/dist/mailroom/entry.js +160 -0
  224. package/dist/mailroom/file-store.js +568 -0
  225. package/dist/mailroom/mbox-import.js +393 -0
  226. package/dist/mailroom/migration.js +164 -0
  227. package/dist/mailroom/outbound.js +380 -0
  228. package/dist/mailroom/policy.js +263 -0
  229. package/dist/mailroom/reader.js +233 -0
  230. package/dist/mailroom/search-cache.js +334 -0
  231. package/dist/mailroom/search-relevance.js +319 -0
  232. package/dist/mailroom/smtp-ingress.js +176 -0
  233. package/dist/mailroom/source-state.js +176 -0
  234. package/dist/mailroom/thread.js +109 -0
  235. package/dist/mailroom/travel-extract.js +89 -0
  236. package/dist/mind/bundle-manifest.js +24 -2
  237. package/dist/mind/context.js +250 -101
  238. package/dist/mind/desk-section.js +362 -0
  239. package/dist/mind/diary-integrity.js +60 -0
  240. package/dist/mind/{memory.js → diary.js} +68 -77
  241. package/dist/mind/embedding-provider.js +60 -0
  242. package/dist/mind/file-state.js +179 -0
  243. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  244. package/dist/mind/obligation-steering.js +221 -0
  245. package/dist/mind/pending.js +6 -1
  246. package/dist/mind/prompt-refresh.js +3 -2
  247. package/dist/mind/prompt.js +1020 -148
  248. package/dist/mind/provenance-trust.js +26 -0
  249. package/dist/mind/record-paths.js +312 -0
  250. package/dist/mind/scrutiny.js +173 -0
  251. package/dist/nerves/cli-logging.js +7 -1
  252. package/dist/nerves/coverage/audit-rules.js +15 -6
  253. package/dist/nerves/coverage/audit.js +28 -2
  254. package/dist/nerves/coverage/cli.js +1 -1
  255. package/dist/nerves/coverage/contract.js +5 -5
  256. package/dist/nerves/coverage/file-completeness.js +139 -5
  257. package/dist/nerves/event-buffer.js +111 -0
  258. package/dist/nerves/index.js +224 -4
  259. package/dist/nerves/observation.js +20 -0
  260. package/dist/nerves/redact.js +79 -0
  261. package/dist/nerves/review/cli-main.js +5 -0
  262. package/dist/nerves/review/cli.js +156 -0
  263. package/dist/nerves/review/core.js +152 -0
  264. package/dist/nerves/runtime.js +5 -1
  265. package/dist/repertoire/ado-client.js +15 -56
  266. package/dist/repertoire/ado-semantic.js +16 -10
  267. package/dist/repertoire/api-client.js +97 -0
  268. package/dist/repertoire/bitwarden-store.js +1042 -0
  269. package/dist/repertoire/bundle-templates.js +71 -0
  270. package/dist/repertoire/bw-installer.js +180 -0
  271. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  272. package/dist/repertoire/coding/context-pack.js +331 -0
  273. package/dist/repertoire/coding/feedback.js +197 -30
  274. package/dist/repertoire/coding/manager.js +166 -10
  275. package/dist/repertoire/coding/spawner.js +55 -9
  276. package/dist/repertoire/coding/tools.js +219 -7
  277. package/dist/repertoire/commerce-errors.js +109 -0
  278. package/dist/repertoire/commerce-self-test.js +156 -0
  279. package/dist/repertoire/credential-access.js +178 -0
  280. package/dist/repertoire/desk/classifier.js +362 -0
  281. package/dist/repertoire/duffel-client.js +185 -0
  282. package/dist/repertoire/github-client.js +14 -55
  283. package/dist/repertoire/graph-client.js +11 -52
  284. package/dist/repertoire/guardrails.js +161 -27
  285. package/dist/repertoire/mcp-client.js +295 -0
  286. package/dist/repertoire/mcp-manager.js +434 -0
  287. package/dist/repertoire/mcp-tools.js +83 -0
  288. package/dist/repertoire/plugin-mcp.js +175 -0
  289. package/dist/repertoire/plugins.js +253 -0
  290. package/dist/repertoire/shell-sessions.js +133 -0
  291. package/dist/repertoire/skills.js +48 -4
  292. package/dist/repertoire/stripe-client.js +131 -0
  293. package/dist/repertoire/tool-results.js +29 -0
  294. package/dist/repertoire/tools-a2a.js +282 -0
  295. package/dist/repertoire/tools-attachments.js +317 -0
  296. package/dist/repertoire/tools-awaiting.js +372 -0
  297. package/dist/repertoire/tools-base.js +63 -1082
  298. package/dist/repertoire/tools-bluebubbles.js +2 -0
  299. package/dist/repertoire/tools-bridge.js +144 -0
  300. package/dist/repertoire/tools-bundle.js +993 -0
  301. package/dist/repertoire/tools-commerce.js +253 -0
  302. package/dist/repertoire/tools-config.js +186 -0
  303. package/dist/repertoire/tools-continuity.js +252 -0
  304. package/dist/repertoire/tools-credential.js +383 -0
  305. package/dist/repertoire/tools-evolution.js +527 -0
  306. package/dist/repertoire/tools-files.js +344 -0
  307. package/dist/repertoire/tools-flight.js +290 -0
  308. package/dist/repertoire/tools-flow.js +119 -0
  309. package/dist/repertoire/tools-github.js +3 -8
  310. package/dist/repertoire/tools-mail.js +1975 -0
  311. package/dist/repertoire/tools-notes.js +459 -0
  312. package/dist/repertoire/tools-obligations.js +143 -0
  313. package/dist/repertoire/tools-orientation.js +31 -0
  314. package/dist/repertoire/tools-record.js +482 -0
  315. package/dist/repertoire/tools-runtime.js +150 -0
  316. package/dist/repertoire/tools-session.js +906 -0
  317. package/dist/repertoire/tools-shell.js +120 -0
  318. package/dist/repertoire/tools-stripe.js +224 -0
  319. package/dist/repertoire/tools-surface.js +355 -0
  320. package/dist/repertoire/tools-teams.js +12 -39
  321. package/dist/repertoire/tools-travel.js +125 -0
  322. package/dist/repertoire/tools-trip.js +982 -0
  323. package/dist/repertoire/tools-user-profile.js +146 -0
  324. package/dist/repertoire/tools-vault.js +40 -0
  325. package/dist/repertoire/tools-voice.js +145 -0
  326. package/dist/repertoire/tools.js +250 -79
  327. package/dist/repertoire/travel-api-client.js +360 -0
  328. package/dist/repertoire/user-profile.js +131 -0
  329. package/dist/repertoire/vault-setup.js +246 -0
  330. package/dist/repertoire/vault-unlock.js +594 -0
  331. package/dist/scripts/claude-code-hook.js +41 -0
  332. package/dist/scripts/claude-code-stop-hook.js +47 -0
  333. package/dist/senses/a2a-entry.js +78 -0
  334. package/dist/senses/attention-queue.js +186 -0
  335. package/dist/senses/await-turn-message.js +58 -0
  336. package/dist/senses/bluebubbles/active-turns.js +216 -0
  337. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  338. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  339. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  340. package/dist/senses/bluebubbles/entry.js +77 -0
  341. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  342. package/dist/senses/bluebubbles/index.js +2732 -0
  343. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  344. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  345. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  346. package/dist/senses/bluebubbles/processed-log.js +133 -0
  347. package/dist/senses/bluebubbles/replay.js +137 -0
  348. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  349. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  350. package/dist/senses/bluebubbles-meta-guard.js +40 -0
  351. package/dist/senses/cli/bracketed-paste.js +82 -0
  352. package/dist/senses/cli/image-paste.js +287 -0
  353. package/dist/senses/cli/image-ref-navigation.js +75 -0
  354. package/dist/senses/cli/ink-app.js +156 -0
  355. package/dist/senses/cli/inline-diff.js +64 -0
  356. package/dist/senses/cli/input-keys.js +174 -0
  357. package/dist/senses/cli/kill-ring.js +86 -0
  358. package/dist/senses/cli/message-list.js +51 -0
  359. package/dist/senses/cli/ouro-tui.js +607 -0
  360. package/dist/senses/cli/spinner-imperative.js +135 -0
  361. package/dist/senses/cli/spinner.js +101 -0
  362. package/dist/senses/cli/status-line.js +60 -0
  363. package/dist/senses/cli/streaming-markdown.js +526 -0
  364. package/dist/senses/cli/tool-display.js +85 -0
  365. package/dist/senses/cli/tool-render.js +85 -0
  366. package/dist/senses/cli/tui-store.js +240 -0
  367. package/dist/senses/cli/virtual-list.js +35 -0
  368. package/dist/senses/cli-entry.js +60 -8
  369. package/dist/senses/cli-layout.js +100 -0
  370. package/dist/senses/cli.js +522 -212
  371. package/dist/senses/commands.js +66 -3
  372. package/dist/senses/habit-turn-message.js +160 -0
  373. package/dist/senses/inner-dialog-worker.js +499 -22
  374. package/dist/senses/inner-dialog.js +544 -47
  375. package/dist/senses/mail-entry.js +66 -0
  376. package/dist/senses/mail.js +379 -0
  377. package/dist/senses/pipeline.js +870 -179
  378. package/dist/senses/proactive-content-guard.js +51 -0
  379. package/dist/senses/shared-turn.js +416 -0
  380. package/dist/senses/surface-tool.js +109 -0
  381. package/dist/senses/teams-entry.js +60 -8
  382. package/dist/senses/teams.js +400 -112
  383. package/dist/senses/trust-gate.js +102 -7
  384. package/dist/senses/voice/audio-playback.js +237 -0
  385. package/dist/senses/voice/audio-routing.js +119 -0
  386. package/dist/senses/voice/elevenlabs.js +202 -0
  387. package/dist/senses/voice/floor-control.js +431 -0
  388. package/dist/senses/voice/floor-controller.js +115 -0
  389. package/dist/senses/voice/golden-path.js +116 -0
  390. package/dist/senses/voice/index.js +29 -0
  391. package/dist/senses/voice/meeting.js +113 -0
  392. package/dist/senses/voice/outbound.js +190 -0
  393. package/dist/senses/voice/phone.js +33 -0
  394. package/dist/senses/voice/playback.js +139 -0
  395. package/dist/senses/voice/realtime-eval.js +496 -0
  396. package/dist/senses/voice/realtime-trace.js +531 -0
  397. package/dist/senses/voice/transcript.js +70 -0
  398. package/dist/senses/voice/turn.js +191 -0
  399. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  400. package/dist/senses/voice/twilio-phone.js +5077 -0
  401. package/dist/senses/voice/types.js +2 -0
  402. package/dist/senses/voice/whisper.js +161 -0
  403. package/dist/senses/voice-entry.js +81 -0
  404. package/dist/senses/voice-realtime-eval-command.js +99 -0
  405. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  406. package/dist/senses/voice-twilio-entry.js +87 -0
  407. package/dist/trips/core.js +138 -0
  408. package/dist/trips/store.js +265 -0
  409. package/dist/util/frontmatter.js +69 -0
  410. package/package.json +57 -12
  411. package/skills/agent-commerce.md +113 -0
  412. package/skills/browser-navigation.md +117 -0
  413. package/skills/commerce-setup-guide.md +116 -0
  414. package/skills/commerce-setup.md +84 -0
  415. package/skills/configure-dev-tools.md +99 -0
  416. package/skills/travel-planning.md +138 -0
  417. package/dist/heart/daemon/auth-flow.js +0 -351
  418. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  419. package/dist/heart/daemon/update-hooks.js +0 -138
  420. package/dist/heart/safe-workspace.js +0 -228
  421. package/dist/heart/session-recall.js +0 -116
  422. package/dist/mind/friends/channel.js +0 -84
  423. package/dist/mind/friends/group-context.js +0 -144
  424. package/dist/mind/friends/resolver.js +0 -84
  425. package/dist/mind/friends/store-file.js +0 -190
  426. package/dist/mind/friends/store.js +0 -4
  427. package/dist/mind/friends/tokens.js +0 -26
  428. package/dist/mind/friends/trust-explanation.js +0 -74
  429. package/dist/mind/friends/types.js +0 -29
  430. package/dist/repertoire/tasks/board.js +0 -134
  431. package/dist/repertoire/tasks/index.js +0 -224
  432. package/dist/repertoire/tasks/lifecycle.js +0 -80
  433. package/dist/repertoire/tasks/middleware.js +0 -65
  434. package/dist/repertoire/tasks/parser.js +0 -173
  435. package/dist/repertoire/tasks/scanner.js +0 -132
  436. package/dist/repertoire/tasks/transitions.js +0 -144
  437. package/dist/senses/bluebubbles-entry.js +0 -13
  438. package/dist/senses/bluebubbles.js +0 -1177
  439. package/dist/senses/debug-activity.js +0 -148
  440. package/subagents/README.md +0 -7
  441. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  442. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  443. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  444. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  445. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  446. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  447. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  448. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  449. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  450. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  451. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  452. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  453. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  454. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  455. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  456. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  457. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,815 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readCodingDeep = readCodingDeep;
37
+ exports.readAttentionView = readAttentionView;
38
+ exports.readBridgeInventory = readBridgeInventory;
39
+ exports.readDaemonHealthDeep = readDaemonHealthDeep;
40
+ exports.readNotesView = readNotesView;
41
+ exports.readFriendView = readFriendView;
42
+ exports.readLogView = readLogView;
43
+ exports.readHabitView = readHabitView;
44
+ exports.readHabitRunView = readHabitRunView;
45
+ exports.readHabitRunReceiptView = readHabitRunReceiptView;
46
+ exports.readHabitSessionSummaryListView = readHabitSessionSummaryListView;
47
+ exports.readHabitSessionSummaryView = readHabitSessionSummaryView;
48
+ exports.readNeedsMeView = readNeedsMeView;
49
+ exports.readDeskPrefs = readDeskPrefs;
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const runtime_1 = require("../../../nerves/runtime");
53
+ const habit_parser_1 = require("../../habits/habit-parser");
54
+ const habit_runtime_state_1 = require("../../habits/habit-runtime-state");
55
+ const habit_session_summary_1 = require("../../habits/habit-session-summary");
56
+ const identity_1 = require("../../identity");
57
+ const daemon_health_1 = require("../../daemon/daemon-health");
58
+ const flight_recorder_1 = require("../../../arc/flight-recorder");
59
+ const shared_1 = require("./shared");
60
+ const agent_machine_1 = require("./agent-machine");
61
+ const sessions_1 = require("./sessions");
62
+ const record_paths_1 = require("../../../mind/record-paths");
63
+ const NOTES_VIEW_LIMIT = 20;
64
+ const DEFAULT_HABIT_RUN_LIMIT = 20;
65
+ const MAX_HABIT_RUN_LIMIT = 100;
66
+ /* v8 ignore start — defensive parsing of on-disk JSON, fallback branches are safety nets */
67
+ function readCodingDeep(agentRoot) {
68
+ const stateFilePath = path.join(agentRoot, "state", "coding", "sessions.json");
69
+ if (!fs.existsSync(stateFilePath)) {
70
+ return { totalCount: 0, activeCount: 0, blockedCount: 0, items: [] };
71
+ }
72
+ let parsed;
73
+ try {
74
+ parsed = JSON.parse(fs.readFileSync(stateFilePath, "utf-8"));
75
+ }
76
+ catch {
77
+ return { totalCount: 0, activeCount: 0, blockedCount: 0, items: [] };
78
+ }
79
+ const items = Array.isArray(parsed.records)
80
+ ? parsed.records.flatMap((record) => {
81
+ const s = record?.session;
82
+ if (!s || typeof s.id !== "string" || typeof s.status !== "string")
83
+ return [];
84
+ const checkpoint = typeof s.checkpoint === "string" ? s.checkpoint
85
+ : typeof s.stderrTail === "string" && s.stderrTail.trim().length > 0 ? s.stderrTail.trim()
86
+ : typeof s.stdoutTail === "string" && s.stdoutTail.trim().length > 0 ? s.stdoutTail.trim()
87
+ : null;
88
+ const originSession = s.originSession;
89
+ const normalizedOrigin = originSession
90
+ && typeof originSession.friendId === "string"
91
+ && typeof originSession.channel === "string"
92
+ && typeof originSession.key === "string"
93
+ ? { friendId: originSession.friendId, channel: originSession.channel, key: originSession.key }
94
+ : null;
95
+ const failure = s.failure;
96
+ const normalizedFailure = failure && typeof failure === "object"
97
+ ? {
98
+ command: typeof failure.command === "string" ? failure.command : "",
99
+ args: Array.isArray(failure.args) ? failure.args.map(String) : [],
100
+ code: typeof failure.code === "number" ? failure.code : null,
101
+ signal: typeof failure.signal === "string" ? failure.signal : null,
102
+ stdoutTail: typeof failure.stdoutTail === "string" ? failure.stdoutTail : "",
103
+ stderrTail: typeof failure.stderrTail === "string" ? failure.stderrTail : "",
104
+ }
105
+ : null;
106
+ return [{
107
+ id: s.id,
108
+ runner: (typeof s.runner === "string" ? s.runner : "claude"),
109
+ status: s.status,
110
+ checkpoint,
111
+ taskRef: typeof s.taskRef === "string" ? s.taskRef : null,
112
+ workdir: typeof s.workdir === "string" ? s.workdir : "",
113
+ originSession: normalizedOrigin,
114
+ obligationId: typeof s.obligationId === "string" ? s.obligationId : null,
115
+ scopeFile: typeof s.scopeFile === "string" ? s.scopeFile : null,
116
+ stateFile: typeof s.stateFile === "string" ? s.stateFile : null,
117
+ artifactPath: typeof s.artifactPath === "string" ? s.artifactPath : null,
118
+ pid: typeof s.pid === "number" ? s.pid : null,
119
+ startedAt: typeof s.startedAt === "string" ? s.startedAt : "",
120
+ lastActivityAt: typeof s.lastActivityAt === "string" ? s.lastActivityAt : "",
121
+ endedAt: typeof s.endedAt === "string" ? s.endedAt : null,
122
+ restartCount: typeof s.restartCount === "number" ? s.restartCount : 0,
123
+ lastExitCode: typeof s.lastExitCode === "number" ? s.lastExitCode : null,
124
+ lastSignal: typeof s.lastSignal === "string" ? s.lastSignal : null,
125
+ stdoutTail: typeof s.stdoutTail === "string" ? s.stdoutTail : "",
126
+ stderrTail: typeof s.stderrTail === "string" ? s.stderrTail : "",
127
+ failure: normalizedFailure,
128
+ }];
129
+ })
130
+ : [];
131
+ return {
132
+ totalCount: items.length,
133
+ activeCount: items.filter((item) => shared_1.ACTIVE_CODING_STATUSES.has(item.status)).length,
134
+ blockedCount: items.filter((item) => shared_1.BLOCKED_CODING_STATUSES.has(item.status)).length,
135
+ items,
136
+ };
137
+ }
138
+ /* v8 ignore stop */
139
+ function scanPendingChannels(agentRoot) {
140
+ const pendingRoot = path.join(agentRoot, "state", "pending");
141
+ const channels = [];
142
+ for (const friendId of (0, shared_1.safeReaddir)(pendingRoot)) {
143
+ if (friendId === "self")
144
+ continue;
145
+ const friendDir = path.join(pendingRoot, friendId);
146
+ if (!(0, shared_1.safeIsDirectory)(friendDir))
147
+ continue;
148
+ for (const channel of (0, shared_1.safeReaddir)(friendDir)) {
149
+ const channelDir = path.join(friendDir, channel);
150
+ if (!(0, shared_1.safeIsDirectory)(channelDir))
151
+ continue;
152
+ for (const key of (0, shared_1.safeReaddir)(channelDir)) {
153
+ const keyDir = path.join(channelDir, key);
154
+ if (!(0, shared_1.safeIsDirectory)(keyDir))
155
+ continue;
156
+ const files = (0, shared_1.safeReaddir)(keyDir).filter((f) => f.endsWith(".json") || f.endsWith(".json.processing"));
157
+ if (files.length > 0) {
158
+ channels.push({ friendId, channel, key, messageCount: files.length });
159
+ }
160
+ }
161
+ }
162
+ }
163
+ return channels;
164
+ }
165
+ function readPendingMessagesNonDestructive(pendingDir) {
166
+ const files = (0, shared_1.safeReaddir)(pendingDir).filter((f) => f.endsWith(".json") || f.endsWith(".json.processing"));
167
+ const messages = [];
168
+ for (const file of files.sort()) {
169
+ try {
170
+ const raw = fs.readFileSync(path.join(pendingDir, file), "utf-8");
171
+ messages.push(JSON.parse(raw));
172
+ }
173
+ catch {
174
+ // skip unparseable pending messages
175
+ }
176
+ }
177
+ return messages;
178
+ }
179
+ function readAttentionView(agentName, options = {}) {
180
+ const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
181
+ const agentRoot = path.join(bundlesRoot, `${agentName}.ouro`);
182
+ const friendsDir = path.join(agentRoot, "friends");
183
+ const pendingChannels = scanPendingChannels(agentRoot);
184
+ const queueItems = [];
185
+ const pendingRoot = path.join(agentRoot, "state", "pending");
186
+ for (const pending of pendingChannels) {
187
+ const pendingDir = path.join(pendingRoot, pending.friendId, pending.channel, pending.key);
188
+ const messages = readPendingMessagesNonDestructive(pendingDir);
189
+ for (const msg of messages) {
190
+ const delegatedFrom = msg.delegatedFrom;
191
+ queueItems.push({
192
+ id: typeof msg.timestamp === "number" ? `${msg.timestamp}-${pending.friendId}` : `pending-${Date.now()}`,
193
+ friendId: pending.friendId,
194
+ friendName: (0, shared_1.resolveFriendName)(friendsDir, pending.friendId),
195
+ channel: pending.channel,
196
+ key: pending.key,
197
+ bridgeId: delegatedFrom && typeof delegatedFrom.bridgeId === "string" ? delegatedFrom.bridgeId : null,
198
+ delegatedContent: typeof msg.content === "string" ? msg.content : "",
199
+ obligationId: typeof msg.obligationId === "string" ? msg.obligationId : null,
200
+ source: "pending",
201
+ timestamp: typeof msg.timestamp === "number" ? msg.timestamp : 0,
202
+ });
203
+ }
204
+ }
205
+ queueItems.sort((a, b) => a.timestamp - b.timestamp);
206
+ const returnObligations = (0, agent_machine_1.readObligationSummary)(agentRoot).items;
207
+ (0, runtime_1.emitNervesEvent)({
208
+ component: "heart",
209
+ event: "heart.mailbox_attention_read",
210
+ message: "reading mailbox attention queue",
211
+ meta: { agentName, queueLength: queueItems.length, pendingChannelCount: pendingChannels.length },
212
+ });
213
+ return {
214
+ queueLength: queueItems.length,
215
+ queueItems,
216
+ pendingChannels,
217
+ returnObligations,
218
+ };
219
+ }
220
+ /* v8 ignore start — defensive parsing */
221
+ function readBridgeInventory(agentRoot) {
222
+ const bridgesDir = path.join(agentRoot, "state", "bridges");
223
+ const items = [];
224
+ for (const file of (0, shared_1.safeReaddir)(bridgesDir)) {
225
+ if (!file.endsWith(".json"))
226
+ continue;
227
+ try {
228
+ const raw = fs.readFileSync(path.join(bridgesDir, file), "utf-8");
229
+ const bridge = JSON.parse(raw);
230
+ if (typeof bridge.id !== "string")
231
+ continue;
232
+ const attachedSessions = Array.isArray(bridge.attachedSessions)
233
+ ? bridge.attachedSessions
234
+ .filter((s) => typeof s.friendId === "string")
235
+ .map((s) => ({
236
+ friendId: s.friendId,
237
+ channel: typeof s.channel === "string" ? s.channel : "",
238
+ key: typeof s.key === "string" ? s.key : "",
239
+ sessionPath: typeof s.sessionPath === "string" ? s.sessionPath : "",
240
+ snapshot: typeof s.snapshot === "string" ? s.snapshot : null,
241
+ }))
242
+ : [];
243
+ const taskLink = bridge.task;
244
+ const normalizedTask = taskLink && typeof taskLink === "object" && typeof taskLink.taskName === "string"
245
+ ? {
246
+ taskName: taskLink.taskName,
247
+ path: typeof taskLink.path === "string" ? taskLink.path : "",
248
+ mode: typeof taskLink.mode === "string" ? taskLink.mode : "bound",
249
+ boundAt: typeof taskLink.boundAt === "string" ? taskLink.boundAt : "",
250
+ }
251
+ : null;
252
+ items.push({
253
+ id: bridge.id,
254
+ objective: typeof bridge.objective === "string" ? bridge.objective : "",
255
+ summary: typeof bridge.summary === "string" ? bridge.summary : "",
256
+ lifecycle: typeof bridge.lifecycle === "string" ? bridge.lifecycle : "unknown",
257
+ runtime: typeof bridge.runtime === "string" ? bridge.runtime : "unknown",
258
+ createdAt: typeof bridge.createdAt === "string" ? bridge.createdAt : "",
259
+ updatedAt: typeof bridge.updatedAt === "string" ? bridge.updatedAt : "",
260
+ attachedSessions,
261
+ task: normalizedTask,
262
+ });
263
+ }
264
+ catch {
265
+ // skip unparseable bridge files
266
+ }
267
+ }
268
+ items.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
269
+ const activeCount = items.filter((item) => item.lifecycle === "active").length;
270
+ return {
271
+ totalCount: items.length,
272
+ activeCount,
273
+ items,
274
+ };
275
+ }
276
+ /* v8 ignore stop */
277
+ /* v8 ignore start — defensive parsing */
278
+ function readDaemonHealthDeep(healthPath) {
279
+ const resolvedPath = healthPath ?? path.join(process.env.HOME ?? "", ".ouro-cli", "daemon-health.json");
280
+ try {
281
+ const raw = fs.readFileSync(resolvedPath, "utf-8");
282
+ const health = JSON.parse(raw);
283
+ return {
284
+ // Layer 1: tighten the parse so only post-Layer-1 vocabulary
285
+ // carries through. Stale cached files that still hold legacy
286
+ // string values like "ok" or "running" — written by an older
287
+ // daemon binary — fall back to "unknown" so downstream Mailbox
288
+ // consumers can detect the unparseable case explicitly.
289
+ status: (0, daemon_health_1.isDaemonStatus)(health.status) ? health.status : "unknown",
290
+ mode: typeof health.mode === "string" ? health.mode : "unknown",
291
+ pid: typeof health.pid === "number" ? health.pid : 0,
292
+ startedAt: typeof health.startedAt === "string" ? health.startedAt : "",
293
+ uptimeSeconds: typeof health.uptimeSeconds === "number" ? health.uptimeSeconds : 0,
294
+ safeMode: health.safeMode && typeof health.safeMode === "object"
295
+ ? {
296
+ active: health.safeMode.active === true,
297
+ reason: typeof health.safeMode.reason === "string" ? health.safeMode.reason : "",
298
+ enteredAt: typeof health.safeMode.enteredAt === "string" ? health.safeMode.enteredAt : "",
299
+ }
300
+ : null,
301
+ degradedComponents: Array.isArray(health.degraded)
302
+ ? health.degraded.map((c) => ({
303
+ component: typeof c.component === "string" ? c.component : "",
304
+ reason: typeof c.reason === "string" ? c.reason : "",
305
+ since: typeof c.since === "string" ? c.since : "",
306
+ }))
307
+ : [],
308
+ agentHealth: health.agents && typeof health.agents === "object"
309
+ ? Object.fromEntries(Object.entries(health.agents).map(([name, entry]) => [
310
+ name,
311
+ {
312
+ status: typeof entry.status === "string" ? entry.status : "unknown",
313
+ pid: typeof entry.pid === "number" ? entry.pid : null,
314
+ crashes: typeof entry.crashes === "number" ? entry.crashes : 0,
315
+ },
316
+ ]))
317
+ : {},
318
+ habitHealth: health.habits && typeof health.habits === "object"
319
+ ? Object.fromEntries(Object.entries(health.habits).map(([name, entry]) => [
320
+ name,
321
+ {
322
+ cronStatus: typeof entry.cronStatus === "string" ? entry.cronStatus : "unknown",
323
+ lastFired: typeof entry.lastFired === "string" ? entry.lastFired : null,
324
+ fallback: entry.fallback === true,
325
+ },
326
+ ]))
327
+ : {},
328
+ };
329
+ }
330
+ catch {
331
+ return null;
332
+ }
333
+ }
334
+ /* v8 ignore stop */
335
+ function readNotesView(agentRoot) {
336
+ const recordPaths = (0, record_paths_1.resolveDeskRecordPaths)(agentRoot);
337
+ const diaryEntries = [];
338
+ try {
339
+ const raw = fs.readFileSync(recordPaths.factsPath, "utf-8");
340
+ for (const line of raw.split("\n")) {
341
+ if (!line.trim())
342
+ continue;
343
+ try {
344
+ const entry = JSON.parse(line);
345
+ if (typeof entry.id === "string" && typeof entry.text === "string") {
346
+ diaryEntries.push({
347
+ id: entry.id,
348
+ text: entry.text,
349
+ source: typeof entry.source === "string" ? entry.source : "",
350
+ createdAt: typeof entry.createdAt === "string" ? entry.createdAt : "",
351
+ });
352
+ }
353
+ }
354
+ catch {
355
+ // skip unparseable lines
356
+ }
357
+ }
358
+ }
359
+ catch {
360
+ // no diary facts file
361
+ }
362
+ diaryEntries.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
363
+ const canonicalNotes = readCanonicalNotes(recordPaths.notesRoot);
364
+ return {
365
+ diaryEntryCount: diaryEntries.length,
366
+ recentDiaryEntries: diaryEntries.slice(0, NOTES_VIEW_LIMIT),
367
+ canonicalNoteCount: canonicalNotes.length,
368
+ recentCanonicalNotes: canonicalNotes.slice(0, NOTES_VIEW_LIMIT),
369
+ };
370
+ }
371
+ function readCanonicalNotes(notesRoot) {
372
+ const notes = [];
373
+ for (const filename of (0, shared_1.safeReaddir)(notesRoot)) {
374
+ if (!filename.endsWith(".md"))
375
+ continue;
376
+ const filePath = path.join(notesRoot, filename);
377
+ if ((0, shared_1.safeIsDirectory)(filePath))
378
+ continue;
379
+ try {
380
+ const raw = fs.readFileSync(filePath, "utf-8");
381
+ const { frontmatter, body } = parseMarkdownFrontmatter(raw);
382
+ const writtenAt = safeCanonicalNoteTimestamp(frontmatter.created_at, filePath);
383
+ notes.push({
384
+ filename,
385
+ title: firstMarkdownHeading(body) ?? titleFromFilename(filename),
386
+ tags: Array.isArray(frontmatter.tags) ? frontmatter.tags : [],
387
+ preview: body.slice(0, 200),
388
+ writtenAt,
389
+ });
390
+ }
391
+ catch {
392
+ // skip unreadable notes
393
+ }
394
+ }
395
+ notes.sort((a, b) => b.writtenAt.localeCompare(a.writtenAt) || b.filename.localeCompare(a.filename));
396
+ return notes;
397
+ }
398
+ function safeCanonicalNoteTimestamp(value, filePath) {
399
+ const fallback = (0, shared_1.safeFileMtime)(filePath);
400
+ if (typeof value !== "string")
401
+ return fallback;
402
+ const trimmed = value.trim();
403
+ if (!trimmed)
404
+ return fallback;
405
+ return Number.isNaN(new Date(trimmed).getTime()) ? fallback : trimmed;
406
+ }
407
+ function parseMarkdownFrontmatter(raw) {
408
+ const lines = raw.split(/\r?\n/);
409
+ if (lines[0] !== "---")
410
+ return { frontmatter: {}, body: raw };
411
+ const endIndex = lines.findIndex((line, index) => index > 0 && line === "---");
412
+ if (endIndex === -1)
413
+ return { frontmatter: {}, body: raw };
414
+ return {
415
+ frontmatter: parseMinimalFrontmatter(lines.slice(1, endIndex)),
416
+ body: lines.slice(endIndex + 1).join("\n").replace(/^\n/, ""),
417
+ };
418
+ }
419
+ function parseMinimalFrontmatter(lines) {
420
+ const frontmatter = {};
421
+ for (let index = 0; index < lines.length; index += 1) {
422
+ const line = lines[index];
423
+ const match = line?.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
424
+ if (!match)
425
+ continue;
426
+ const key = match[1];
427
+ const rawValue = match[2];
428
+ if (key === "tags") {
429
+ frontmatter.tags = parseFrontmatterTags(rawValue, lines, index + 1);
430
+ continue;
431
+ }
432
+ frontmatter[key] = rawValue.trim();
433
+ }
434
+ return frontmatter;
435
+ }
436
+ function parseFrontmatterTags(rawValue, lines, startIndex) {
437
+ const trimmed = rawValue.trim();
438
+ if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
439
+ try {
440
+ const parsed = JSON.parse(trimmed);
441
+ return parsed.filter((item) => typeof item === "string");
442
+ }
443
+ catch {
444
+ return trimmed.slice(1, -1).split(",").map((tag) => tag.trim().replace(/^['"]|['"]$/g, "")).filter(Boolean);
445
+ }
446
+ }
447
+ if (trimmed.length > 0)
448
+ return [trimmed];
449
+ const tags = [];
450
+ for (let index = startIndex; index < lines.length; index += 1) {
451
+ const itemMatch = lines[index]?.match(/^\s*-\s*(.+)$/);
452
+ if (!itemMatch)
453
+ break;
454
+ const tag = itemMatch[1].trim().replace(/^['"]|['"]$/g, "");
455
+ if (tag)
456
+ tags.push(tag);
457
+ }
458
+ return tags;
459
+ }
460
+ function firstMarkdownHeading(body) {
461
+ const heading = body
462
+ .split(/\r?\n/)
463
+ .map((line) => line.match(/^#\s+(.+)$/)?.[1]?.trim())
464
+ .find((title) => title && title.length > 0);
465
+ return heading ?? null;
466
+ }
467
+ function titleFromFilename(filename) {
468
+ const stem = filename.replace(/\.md$/i, "").replace(/^\d{4}-\d{2}-\d{2}-/, "");
469
+ return stem.replace(/[-_]+/g, " ").trim() || filename;
470
+ }
471
+ function readFriendView(agentName, options = {}) {
472
+ const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
473
+ const agentRoot = path.join(bundlesRoot, `${agentName}.ouro`);
474
+ const friendsDir = path.join(agentRoot, "friends");
475
+ const sessionsDir = path.join(agentRoot, "state", "sessions");
476
+ const friends = [];
477
+ for (const file of (0, shared_1.safeReaddir)(friendsDir)) {
478
+ if (!file.endsWith(".json"))
479
+ continue;
480
+ const friendId = file.slice(0, -5);
481
+ try {
482
+ const raw = fs.readFileSync(path.join(friendsDir, file), "utf-8");
483
+ const record = JSON.parse(raw);
484
+ const friendSessionsDir = path.join(sessionsDir, friendId);
485
+ const channels = new Set();
486
+ let sessionCount = 0;
487
+ let latestActivity = null;
488
+ for (const channel of (0, shared_1.safeReaddir)(friendSessionsDir)) {
489
+ const channelDir = path.join(friendSessionsDir, channel);
490
+ if (!(0, shared_1.safeIsDirectory)(channelDir))
491
+ continue;
492
+ for (const keyFile of (0, shared_1.safeReaddir)(channelDir)) {
493
+ if (!keyFile.endsWith(".json"))
494
+ continue;
495
+ channels.add(channel);
496
+ sessionCount++;
497
+ const mtime = (0, shared_1.safeFileMtime)(path.join(channelDir, keyFile));
498
+ if (mtime && (!latestActivity || mtime > latestActivity)) {
499
+ latestActivity = mtime;
500
+ }
501
+ }
502
+ }
503
+ friends.push({
504
+ friendId,
505
+ friendName: typeof record.name === "string" ? record.name : friendId,
506
+ totalTokens: typeof record.totalTokens === "number" ? record.totalTokens : 0,
507
+ sessionCount,
508
+ channels: [...channels].sort(),
509
+ lastActivityAt: latestActivity,
510
+ });
511
+ }
512
+ catch {
513
+ // skip unparseable friend records
514
+ }
515
+ }
516
+ friends.sort((a, b) => b.totalTokens - a.totalTokens);
517
+ return {
518
+ totalFriends: friends.length,
519
+ friends,
520
+ };
521
+ }
522
+ function readLogView(logPath, limit = 100) {
523
+ if (!logPath || !fs.existsSync(logPath)) {
524
+ return { logPath, totalLines: 0, entries: [] };
525
+ }
526
+ try {
527
+ const raw = fs.readFileSync(logPath, "utf-8");
528
+ const lines = raw.split("\n").filter((l) => l.trim().length > 0);
529
+ const totalLines = lines.length;
530
+ const recentLines = lines.slice(-limit);
531
+ const entries = [];
532
+ for (const line of recentLines) {
533
+ try {
534
+ const parsed = JSON.parse(line);
535
+ entries.push({
536
+ ts: typeof parsed.ts === "string" ? parsed.ts : "",
537
+ level: typeof parsed.level === "string" ? parsed.level : "info",
538
+ event: typeof parsed.event === "string" ? parsed.event : "",
539
+ component: typeof parsed.component === "string" ? parsed.component : "",
540
+ message: typeof parsed.message === "string" ? parsed.message : "",
541
+ trace_id: typeof parsed.trace_id === "string" ? parsed.trace_id : "",
542
+ meta: parsed.meta && typeof parsed.meta === "object" ? parsed.meta : {},
543
+ });
544
+ }
545
+ catch {
546
+ // skip unparseable log lines
547
+ }
548
+ }
549
+ return { logPath, totalLines, entries };
550
+ }
551
+ catch { /* v8 ignore next */
552
+ return { logPath, totalLines: 0, entries: [] };
553
+ }
554
+ }
555
+ function readHabitView(agentRoot, options = {}) {
556
+ const habitsDir = path.join(agentRoot, "habits");
557
+ const now = options.now?.() ?? new Date();
558
+ const items = [];
559
+ for (const file of (0, shared_1.safeReaddir)(habitsDir)) {
560
+ if (!file.endsWith(".md"))
561
+ continue;
562
+ try {
563
+ const filePath = path.join(habitsDir, file);
564
+ const raw = fs.readFileSync(filePath, "utf-8");
565
+ if (!/^---\r?\n[\s\S]*?\r?\n---/.test(raw))
566
+ continue;
567
+ const habit = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(raw, filePath));
568
+ const cadenceMs = parseCadenceMs(habit.cadence);
569
+ let isOverdue = false;
570
+ let overdueMs = null;
571
+ if (habit.status === "active" && habit.lastRun && cadenceMs) {
572
+ const elapsed = now.getTime() - Date.parse(habit.lastRun);
573
+ if (elapsed > cadenceMs) {
574
+ isOverdue = true;
575
+ overdueMs = elapsed - cadenceMs;
576
+ }
577
+ }
578
+ items.push({
579
+ name: habit.name,
580
+ title: habit.title,
581
+ cadence: habit.cadence,
582
+ status: habit.status,
583
+ lastRun: habit.lastRun,
584
+ bodyExcerpt: (0, shared_1.truncateExcerpt)(habit.body, 120),
585
+ isDegraded: false,
586
+ degradedReason: null,
587
+ isOverdue,
588
+ overdueMs,
589
+ });
590
+ }
591
+ catch {
592
+ // skip unparseable habit files
593
+ }
594
+ }
595
+ items.sort((a, b) => {
596
+ if (a.isOverdue && !b.isOverdue)
597
+ return -1;
598
+ if (!a.isOverdue && b.isOverdue)
599
+ return 1;
600
+ return a.name.localeCompare(b.name);
601
+ });
602
+ return {
603
+ totalCount: items.length,
604
+ activeCount: items.filter((h) => h.status === "active").length,
605
+ pausedCount: items.filter((h) => h.status === "paused").length,
606
+ degradedCount: items.filter((h) => h.isDegraded).length,
607
+ overdueCount: items.filter((h) => h.isOverdue).length,
608
+ items,
609
+ };
610
+ }
611
+ function normalizeHabitRunLimit(limit) {
612
+ if (limit === undefined || !Number.isInteger(limit))
613
+ return DEFAULT_HABIT_RUN_LIMIT;
614
+ return Math.min(MAX_HABIT_RUN_LIMIT, Math.max(1, limit));
615
+ }
616
+ function summarizeHabitRunReceipt(receipt) {
617
+ return {
618
+ runId: receipt.runId,
619
+ habitName: receipt.habitName,
620
+ trigger: receipt.trigger,
621
+ startedAt: receipt.startedAt,
622
+ endedAt: receipt.endedAt,
623
+ outcome: receipt.outcome,
624
+ nextRunAt: receipt.nextRunAt,
625
+ permissionEnvelope: receipt.permissionEnvelope,
626
+ toolPolicy: receipt.toolPolicy,
627
+ producedRefs: receipt.producedRefs,
628
+ surfaceAttempts: receipt.surfaceAttempts,
629
+ errorCount: receipt.errors.length,
630
+ errors: receipt.errors,
631
+ receiptLocator: receipt.receiptLocator,
632
+ sessionLocator: receipt.sessionLocator,
633
+ runtimeStateLocator: receipt.runtimeStateLocator,
634
+ };
635
+ }
636
+ function readHabitRunView(agentRoot, options = {}) {
637
+ const limit = normalizeHabitRunLimit(options.limit);
638
+ const receipts = (0, flight_recorder_1.listHabitRunReceipts)(agentRoot);
639
+ const items = receipts.slice(0, limit).map(summarizeHabitRunReceipt);
640
+ (0, runtime_1.emitNervesEvent)({
641
+ component: "heart",
642
+ event: "heart.mailbox_habit_runs_read",
643
+ message: "reading mailbox habit run receipts",
644
+ meta: { agentRoot, totalCount: receipts.length, limit, itemCount: items.length },
645
+ });
646
+ return {
647
+ totalCount: receipts.length,
648
+ limit,
649
+ items,
650
+ };
651
+ }
652
+ function readHabitRunReceiptView(agentRoot, runId) {
653
+ const receipt = (0, flight_recorder_1.readHabitRunReceipt)(agentRoot, runId);
654
+ (0, runtime_1.emitNervesEvent)({
655
+ component: "heart",
656
+ event: "heart.mailbox_habit_run_receipt_read",
657
+ message: "reading mailbox habit run receipt",
658
+ meta: { agentRoot, runId, found: receipt !== null },
659
+ });
660
+ return receipt ? { receipt } : null;
661
+ }
662
+ function readHabitSessionSummaryListView(agentRoot, options = {}) {
663
+ const limit = normalizeHabitRunLimit(options.limit);
664
+ const receipts = (0, flight_recorder_1.listHabitRunReceipts)(agentRoot);
665
+ const items = receipts.slice(0, limit)
666
+ .map((receipt) => (0, habit_session_summary_1.readHabitSessionSummary)(agentRoot, { runId: receipt.runId }))
667
+ .filter((summary) => summary !== null);
668
+ (0, runtime_1.emitNervesEvent)({
669
+ component: "heart",
670
+ event: "heart.mailbox_habit_run_summaries_read",
671
+ message: "reading mailbox habit run summaries",
672
+ meta: { agentRoot, totalCount: receipts.length, limit, itemCount: items.length },
673
+ });
674
+ return {
675
+ totalCount: receipts.length,
676
+ limit,
677
+ items,
678
+ };
679
+ }
680
+ function readHabitSessionSummaryView(agentRoot, selector) {
681
+ const summary = (0, habit_session_summary_1.readHabitSessionSummary)(agentRoot, selector);
682
+ (0, runtime_1.emitNervesEvent)({
683
+ component: "heart",
684
+ event: "heart.mailbox_habit_run_summary_read",
685
+ message: "reading mailbox habit run summary",
686
+ meta: { agentRoot, runId: summary?.runId ?? null, habitName: summary?.habitName ?? selector.habitName ?? null, found: summary !== null },
687
+ });
688
+ return summary;
689
+ }
690
+ function readNeedsMeView(agentName, options = {}) {
691
+ const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
692
+ const now = options.now?.() ?? new Date();
693
+ const agentRoot = path.join(bundlesRoot, `${agentName}.ouro`);
694
+ const items = [];
695
+ const prefs = readDeskPrefs(agentRoot);
696
+ const dismissed = new Set(prefs.dismissedObligations);
697
+ const sessions = (0, sessions_1.readSessionInventory)(agentName, options);
698
+ for (const s of sessions.items) {
699
+ if (s.replyState === "needs-reply") {
700
+ items.push({
701
+ urgency: "owed-reply",
702
+ label: `${s.friendName} is waiting for a reply`,
703
+ detail: `via ${s.channel} · ${s.latestUserExcerpt ? (0, shared_1.truncateExcerpt)(s.latestUserExcerpt, 80) : ""}`,
704
+ ref: { tab: "sessions", focus: `${s.friendId}/${s.channel}/${s.key}` },
705
+ ageMs: now.getTime() - Date.parse(s.lastActivityAt),
706
+ });
707
+ }
708
+ }
709
+ const obligations = (0, agent_machine_1.readObligationSummary)(agentRoot);
710
+ for (const o of obligations.items) {
711
+ if (dismissed.has(o.id))
712
+ continue;
713
+ const ageMs = now.getTime() - Date.parse(o.updatedAt);
714
+ const isStale = ageMs > 24 * 60 * 60 * 1000;
715
+ const hasResult = o.currentSurface !== null;
716
+ const isOpen = o.status === "pending" || o.status === "investigating" || o.status === "waiting_for_merge" || o.status === "updating_runtime";
717
+ if (isOpen) {
718
+ items.push({
719
+ urgency: hasResult ? "return-ready" : isStale ? "stale-delegation" : "blocking-obligation",
720
+ label: (0, shared_1.truncateExcerpt)(o.content, 80) ?? o.id,
721
+ detail: hasResult ? `result ready — ${o.currentSurface.kind}: ${o.currentSurface.label}` : `${o.status}${o.nextAction ? ` · next: ${o.nextAction}` : ""}`,
722
+ ref: { tab: "work", focus: o.id },
723
+ ageMs,
724
+ });
725
+ }
726
+ }
727
+ const pendingChannels = scanPendingChannels(agentRoot);
728
+ for (const p of pendingChannels) {
729
+ const friendName = (0, shared_1.resolveFriendName)(path.join(agentRoot, "friends"), p.friendId);
730
+ items.push({
731
+ urgency: "stale-delegation",
732
+ label: `${p.messageCount} pending from ${friendName}`,
733
+ detail: `${p.channel}/${p.key}`,
734
+ ref: { tab: "connections" },
735
+ ageMs: null,
736
+ });
737
+ }
738
+ const habits = readHabitView(agentRoot, options);
739
+ for (const h of habits.items) {
740
+ if (h.isOverdue) {
741
+ items.push({
742
+ urgency: "overdue-habit",
743
+ label: `${h.title} is overdue`,
744
+ detail: `every ${h.cadence} · last ${h.lastRun}`,
745
+ ref: { tab: "inner" },
746
+ ageMs: h.overdueMs,
747
+ });
748
+ }
749
+ }
750
+ const urgencyOrder = {
751
+ "owed-reply": 0,
752
+ "blocking-obligation": 1,
753
+ "broken-return": 2,
754
+ "stale-delegation": 3,
755
+ "return-ready": 4,
756
+ "overdue-habit": 5,
757
+ };
758
+ items.sort((a, b) => urgencyOrder[a.urgency] - urgencyOrder[b.urgency]);
759
+ return { items };
760
+ }
761
+ /* v8 ignore start — defensive JSON parsing in desk prefs reader */
762
+ function readDeskPrefs(agentRoot) {
763
+ const prefsPath = path.join(agentRoot, "state", "mailbox-prefs.json");
764
+ const legacyPrefsPath = path.join(agentRoot, "state", "outlook-prefs.json");
765
+ const defaults = {
766
+ carrying: null,
767
+ statusLine: null,
768
+ tabOrder: null,
769
+ starredFriends: [],
770
+ pinnedConstellations: [],
771
+ dismissedObligations: [],
772
+ };
773
+ try {
774
+ const raw = fs.readFileSync(fs.existsSync(prefsPath) ? prefsPath : legacyPrefsPath, "utf-8");
775
+ const parsed = JSON.parse(raw);
776
+ return {
777
+ carrying: typeof parsed.carrying === "string" ? parsed.carrying : null,
778
+ statusLine: typeof parsed.statusLine === "string" ? parsed.statusLine : null,
779
+ tabOrder: Array.isArray(parsed.tabOrder) ? parsed.tabOrder.filter((t) => typeof t === "string") : null,
780
+ starredFriends: Array.isArray(parsed.starredFriends) ? parsed.starredFriends.filter((f) => typeof f === "string") : [],
781
+ pinnedConstellations: Array.isArray(parsed.pinnedConstellations)
782
+ ? parsed.pinnedConstellations.map((c) => ({
783
+ label: typeof c.label === "string" ? c.label : "",
784
+ friendIds: Array.isArray(c.friendIds) ? c.friendIds.filter((f) => typeof f === "string") : [],
785
+ taskRefs: Array.isArray(c.taskRefs) ? c.taskRefs.filter((t) => typeof t === "string") : [],
786
+ bridgeIds: Array.isArray(c.bridgeIds) ? c.bridgeIds.filter((b) => typeof b === "string") : [],
787
+ codingIds: Array.isArray(c.codingIds) ? c.codingIds.filter((c2) => typeof c2 === "string") : [],
788
+ }))
789
+ : [],
790
+ dismissedObligations: Array.isArray(parsed.dismissedObligations) ? parsed.dismissedObligations.filter((id) => typeof id === "string") : [],
791
+ };
792
+ }
793
+ catch {
794
+ return defaults;
795
+ }
796
+ }
797
+ /* v8 ignore stop */
798
+ function parseCadenceMs(cadence) {
799
+ if (!cadence)
800
+ return null;
801
+ const match = /^(\d+)\s*(m|min|h|hr|d|day)s?$/i.exec(cadence.trim());
802
+ if (!match)
803
+ return null;
804
+ const value = parseInt(match[1], 10);
805
+ const multipliers = {
806
+ m: 60 * 1000,
807
+ min: 60 * 1000,
808
+ h: 60 * 60 * 1000,
809
+ hr: 60 * 60 * 1000,
810
+ d: 24 * 60 * 60 * 1000,
811
+ day: 24 * 60 * 60 * 1000,
812
+ };
813
+ const unit = match[2].toLowerCase();
814
+ return value * multipliers[unit];
815
+ }