@ouro.bot/cli 0.1.0-alpha.61 → 0.1.0-alpha.612

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 (418) 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 +3912 -0
  13. package/dist/arc/attention-types.js +8 -0
  14. package/dist/arc/cares.js +144 -0
  15. package/dist/arc/episodes.js +118 -0
  16. package/dist/arc/intentions.js +134 -0
  17. package/dist/arc/json-store.js +117 -0
  18. package/dist/arc/obligations.js +266 -0
  19. package/dist/arc/packets.js +194 -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 +69 -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/awaiting/await-alert.js +146 -0
  36. package/dist/heart/awaiting/await-expiry.js +108 -0
  37. package/dist/heart/awaiting/await-loader.js +91 -0
  38. package/dist/heart/awaiting/await-parser.js +141 -0
  39. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  40. package/dist/heart/awaiting/await-scheduler.js +377 -0
  41. package/dist/heart/background-operations.js +281 -0
  42. package/dist/heart/bridges/store.js +14 -2
  43. package/dist/heart/bundle-state.js +168 -0
  44. package/dist/heart/commitments.js +142 -0
  45. package/dist/heart/config-registry.js +322 -0
  46. package/dist/heart/config.js +114 -119
  47. package/dist/heart/core.js +909 -246
  48. package/dist/heart/cross-chat-delivery.js +3 -18
  49. package/dist/heart/daemon/agent-config-check.js +419 -0
  50. package/dist/heart/daemon/agent-discovery.js +102 -3
  51. package/dist/heart/daemon/agent-service.js +522 -0
  52. package/dist/heart/daemon/agentic-repair.js +547 -0
  53. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  54. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  55. package/dist/heart/daemon/cadence.js +70 -0
  56. package/dist/heart/daemon/cli-defaults.js +776 -0
  57. package/dist/heart/daemon/cli-exec.js +7579 -0
  58. package/dist/heart/daemon/cli-help.js +498 -0
  59. package/dist/heart/daemon/cli-parse.js +1599 -0
  60. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  61. package/dist/heart/daemon/cli-render.js +763 -0
  62. package/dist/heart/daemon/cli-types.js +8 -0
  63. package/dist/heart/daemon/connect-bay.js +323 -0
  64. package/dist/heart/daemon/daemon-cli.js +29 -1700
  65. package/dist/heart/daemon/daemon-entry.js +485 -2
  66. package/dist/heart/daemon/daemon-health.js +176 -0
  67. package/dist/heart/daemon/daemon-rollup.js +57 -0
  68. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  69. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  70. package/dist/heart/daemon/daemon.js +904 -70
  71. package/dist/heart/daemon/dns-workflow.js +394 -0
  72. package/dist/heart/daemon/doctor-types.js +8 -0
  73. package/dist/heart/daemon/doctor.js +873 -0
  74. package/dist/heart/daemon/health-monitor.js +122 -1
  75. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  76. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  77. package/dist/heart/daemon/http-health-probe.js +80 -0
  78. package/dist/heart/daemon/human-command-screens.js +234 -0
  79. package/dist/heart/daemon/human-readiness.js +114 -0
  80. package/dist/heart/daemon/inner-status.js +89 -0
  81. package/dist/heart/daemon/interactive-repair.js +394 -0
  82. package/dist/heart/daemon/launchd.js +37 -8
  83. package/dist/heart/daemon/log-tailer.js +78 -9
  84. package/dist/heart/daemon/logs-prune.js +110 -0
  85. package/dist/heart/daemon/mcp-canary.js +297 -0
  86. package/dist/heart/daemon/os-cron-deps.js +135 -0
  87. package/dist/heart/daemon/os-cron.js +14 -12
  88. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  89. package/dist/heart/daemon/ouro-entry.js +3 -1
  90. package/dist/heart/daemon/process-manager.js +463 -34
  91. package/dist/heart/daemon/provider-discovery.js +137 -0
  92. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  93. package/dist/heart/daemon/pulse.js +475 -0
  94. package/dist/heart/daemon/readiness-repair.js +365 -0
  95. package/dist/heart/daemon/run-hooks.js +2 -0
  96. package/dist/heart/daemon/runtime-logging.js +10 -2
  97. package/dist/heart/daemon/runtime-metadata.js +2 -30
  98. package/dist/heart/daemon/safe-mode.js +161 -0
  99. package/dist/heart/daemon/sense-manager.js +493 -38
  100. package/dist/heart/daemon/session-id-resolver.js +131 -0
  101. package/dist/heart/daemon/skill-management-installer.js +28 -7
  102. package/dist/heart/daemon/socket-client.js +158 -11
  103. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  104. package/dist/heart/daemon/startup-tui.js +330 -0
  105. package/dist/heart/daemon/task-scheduler.js +3 -25
  106. package/dist/heart/daemon/terminal-ui.js +499 -0
  107. package/dist/heart/daemon/thoughts.js +229 -17
  108. package/dist/heart/daemon/up-progress.js +366 -0
  109. package/dist/heart/daemon/vault-items.js +56 -0
  110. package/dist/heart/delegation.js +1 -1
  111. package/dist/heart/habits/habit-migration.js +189 -0
  112. package/dist/heart/habits/habit-parser.js +140 -0
  113. package/dist/heart/habits/habit-runtime-state.js +100 -0
  114. package/dist/heart/habits/habit-scheduler.js +372 -0
  115. package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
  116. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  117. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  118. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  119. package/dist/heart/identity.js +166 -55
  120. package/dist/heart/kept-notes.js +357 -0
  121. package/dist/heart/kicks.js +1 -1
  122. package/dist/heart/machine-identity.js +161 -0
  123. package/dist/heart/mail-import-discovery.js +353 -0
  124. package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
  125. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  126. package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
  127. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  128. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  129. package/dist/heart/mailbox/mailbox-http.js +99 -0
  130. package/dist/heart/mailbox/mailbox-read.js +31 -0
  131. package/dist/heart/mailbox/mailbox-types.js +27 -0
  132. package/dist/heart/mailbox/mailbox-view.js +197 -0
  133. package/dist/heart/mailbox/readers/agent-machine.js +425 -0
  134. package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
  135. package/dist/heart/mailbox/readers/mail.js +375 -0
  136. package/dist/heart/mailbox/readers/runtime-readers.js +756 -0
  137. package/dist/heart/mailbox/readers/sessions.js +232 -0
  138. package/dist/heart/mailbox/readers/shared.js +111 -0
  139. package/dist/heart/mcp/mcp-server.js +656 -0
  140. package/dist/heart/migrate-config.js +100 -0
  141. package/dist/heart/model-capabilities.js +19 -0
  142. package/dist/heart/platform.js +81 -0
  143. package/dist/heart/provider-attempt.js +134 -0
  144. package/dist/heart/provider-binding-resolver.js +267 -0
  145. package/dist/heart/provider-credentials.js +425 -0
  146. package/dist/heart/provider-failover.js +301 -0
  147. package/dist/heart/provider-models.js +81 -0
  148. package/dist/heart/provider-ping.js +262 -0
  149. package/dist/heart/provider-readiness-cache.js +40 -0
  150. package/dist/heart/provider-visibility.js +188 -0
  151. package/dist/heart/providers/anthropic-token.js +131 -0
  152. package/dist/heart/providers/anthropic.js +139 -52
  153. package/dist/heart/providers/azure.js +23 -11
  154. package/dist/heart/providers/error-classification.js +127 -0
  155. package/dist/heart/providers/github-copilot.js +145 -0
  156. package/dist/heart/providers/minimax-vlm.js +189 -0
  157. package/dist/heart/providers/minimax.js +26 -8
  158. package/dist/heart/providers/openai-codex.js +55 -40
  159. package/dist/heart/runtime-capability-check.js +170 -0
  160. package/dist/heart/runtime-credentials.js +367 -0
  161. package/dist/heart/runtime-cwd.js +87 -0
  162. package/dist/heart/sense-truth.js +13 -4
  163. package/dist/heart/session-activity.js +48 -24
  164. package/dist/heart/session-events.js +1156 -0
  165. package/dist/heart/session-playback-cli-main.js +5 -0
  166. package/dist/heart/session-playback-cli.js +36 -0
  167. package/dist/heart/session-playback.js +231 -0
  168. package/dist/heart/session-stats-cli-main.js +5 -0
  169. package/dist/heart/session-stats.js +182 -0
  170. package/dist/heart/session-transcript.js +133 -0
  171. package/dist/heart/start-of-turn-packet.js +345 -0
  172. package/dist/heart/streaming.js +44 -27
  173. package/dist/heart/sync-classification.js +176 -0
  174. package/dist/heart/sync.js +449 -0
  175. package/dist/heart/target-resolution.js +9 -5
  176. package/dist/heart/tempo.js +93 -0
  177. package/dist/heart/temporal-view.js +41 -0
  178. package/dist/heart/timeouts.js +101 -0
  179. package/dist/heart/tool-activity-callbacks.js +59 -0
  180. package/dist/heart/tool-description.js +143 -0
  181. package/dist/heart/tool-friction.js +55 -0
  182. package/dist/heart/tool-loop.js +200 -0
  183. package/dist/heart/turn-context.js +421 -0
  184. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  185. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  186. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  187. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  188. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  189. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  190. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  191. package/dist/mailbox-ui/assets/index-9-AxCxuB.js +61 -0
  192. package/dist/mailbox-ui/assets/index-CWzt267f.css +1 -0
  193. package/dist/mailbox-ui/index.html +15 -0
  194. package/dist/mailroom/attention.js +167 -0
  195. package/dist/mailroom/autonomy.js +209 -0
  196. package/dist/mailroom/blob-store.js +712 -0
  197. package/dist/mailroom/body-cache.js +61 -0
  198. package/dist/mailroom/core.js +788 -0
  199. package/dist/mailroom/entry.js +160 -0
  200. package/dist/mailroom/file-store.js +460 -0
  201. package/dist/mailroom/mbox-import.js +393 -0
  202. package/dist/mailroom/migration.js +164 -0
  203. package/dist/mailroom/outbound.js +380 -0
  204. package/dist/mailroom/policy.js +263 -0
  205. package/dist/mailroom/reader.js +233 -0
  206. package/dist/mailroom/search-cache.js +268 -0
  207. package/dist/mailroom/search-relevance.js +319 -0
  208. package/dist/mailroom/smtp-ingress.js +176 -0
  209. package/dist/mailroom/source-state.js +176 -0
  210. package/dist/mailroom/thread.js +109 -0
  211. package/dist/mailroom/travel-extract.js +89 -0
  212. package/dist/mind/bundle-manifest.js +7 -1
  213. package/dist/mind/context.js +250 -101
  214. package/dist/mind/diary-integrity.js +60 -0
  215. package/dist/mind/{memory.js → diary.js} +68 -76
  216. package/dist/mind/embedding-provider.js +60 -0
  217. package/dist/mind/file-state.js +179 -0
  218. package/dist/mind/friends/channel.js +39 -0
  219. package/dist/mind/friends/resolver.js +54 -2
  220. package/dist/mind/friends/store-file.js +48 -4
  221. package/dist/mind/friends/types.js +2 -2
  222. package/dist/mind/journal-index.js +162 -0
  223. package/dist/mind/note-search.js +268 -0
  224. package/dist/mind/obligation-steering.js +221 -0
  225. package/dist/mind/pending.js +6 -1
  226. package/dist/mind/prompt-refresh.js +3 -2
  227. package/dist/mind/prompt.js +1051 -135
  228. package/dist/mind/provenance-trust.js +26 -0
  229. package/dist/mind/scrutiny.js +173 -0
  230. package/dist/nerves/cli-logging.js +7 -1
  231. package/dist/nerves/coverage/audit-rules.js +15 -6
  232. package/dist/nerves/coverage/audit.js +28 -2
  233. package/dist/nerves/coverage/cli.js +1 -1
  234. package/dist/nerves/coverage/contract.js +5 -5
  235. package/dist/nerves/coverage/file-completeness.js +129 -5
  236. package/dist/nerves/event-buffer.js +111 -0
  237. package/dist/nerves/index.js +224 -4
  238. package/dist/nerves/observation.js +20 -0
  239. package/dist/nerves/redact.js +79 -0
  240. package/dist/nerves/review/cli-main.js +5 -0
  241. package/dist/nerves/review/cli.js +156 -0
  242. package/dist/nerves/review/core.js +152 -0
  243. package/dist/nerves/runtime.js +5 -1
  244. package/dist/repertoire/ado-client.js +15 -56
  245. package/dist/repertoire/ado-semantic.js +11 -10
  246. package/dist/repertoire/api-client.js +97 -0
  247. package/dist/repertoire/bitwarden-store.js +997 -0
  248. package/dist/repertoire/bundle-templates.js +72 -0
  249. package/dist/repertoire/bw-installer.js +180 -0
  250. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  251. package/dist/repertoire/coding/context-pack.js +331 -0
  252. package/dist/repertoire/coding/feedback.js +197 -30
  253. package/dist/repertoire/coding/manager.js +163 -10
  254. package/dist/repertoire/coding/spawner.js +55 -9
  255. package/dist/repertoire/coding/tools.js +170 -7
  256. package/dist/repertoire/commerce-errors.js +109 -0
  257. package/dist/repertoire/commerce-self-test.js +156 -0
  258. package/dist/repertoire/credential-access.js +178 -0
  259. package/dist/repertoire/duffel-client.js +185 -0
  260. package/dist/repertoire/github-client.js +14 -55
  261. package/dist/repertoire/graph-client.js +11 -52
  262. package/dist/repertoire/guardrails.js +396 -0
  263. package/dist/repertoire/mcp-client.js +295 -0
  264. package/dist/repertoire/mcp-manager.js +362 -0
  265. package/dist/repertoire/mcp-tools.js +63 -0
  266. package/dist/repertoire/shell-sessions.js +133 -0
  267. package/dist/repertoire/skills.js +18 -4
  268. package/dist/repertoire/stripe-client.js +131 -0
  269. package/dist/repertoire/tasks/board.js +31 -5
  270. package/dist/repertoire/tasks/fix.js +182 -0
  271. package/dist/repertoire/tasks/index.js +16 -4
  272. package/dist/repertoire/tasks/lifecycle.js +2 -2
  273. package/dist/repertoire/tasks/parser.js +3 -2
  274. package/dist/repertoire/tasks/scanner.js +194 -37
  275. package/dist/repertoire/tasks/transitions.js +16 -78
  276. package/dist/repertoire/tool-results.js +29 -0
  277. package/dist/repertoire/tools-attachments.js +317 -0
  278. package/dist/repertoire/tools-awaiting.js +365 -0
  279. package/dist/repertoire/tools-base.js +55 -1082
  280. package/dist/repertoire/tools-bluebubbles.js +1 -0
  281. package/dist/repertoire/tools-bridge.js +141 -0
  282. package/dist/repertoire/tools-bundle.js +984 -0
  283. package/dist/repertoire/tools-config.js +185 -0
  284. package/dist/repertoire/tools-continuity.js +248 -0
  285. package/dist/repertoire/tools-credential.js +381 -0
  286. package/dist/repertoire/tools-files.js +342 -0
  287. package/dist/repertoire/tools-flight.js +224 -0
  288. package/dist/repertoire/tools-flow.js +119 -0
  289. package/dist/repertoire/tools-github.js +1 -7
  290. package/dist/repertoire/tools-mail.js +1916 -0
  291. package/dist/repertoire/tools-notes.js +421 -0
  292. package/dist/repertoire/tools-obligations.js +142 -0
  293. package/dist/repertoire/tools-record.js +463 -0
  294. package/dist/repertoire/tools-runtime.js +148 -0
  295. package/dist/repertoire/tools-session.js +781 -0
  296. package/dist/repertoire/tools-shell.js +120 -0
  297. package/dist/repertoire/tools-stripe.js +180 -0
  298. package/dist/repertoire/tools-surface.js +345 -0
  299. package/dist/repertoire/tools-teams.js +9 -39
  300. package/dist/repertoire/tools-travel.js +125 -0
  301. package/dist/repertoire/tools-trip.js +604 -0
  302. package/dist/repertoire/tools-user-profile.js +144 -0
  303. package/dist/repertoire/tools-vault.js +40 -0
  304. package/dist/repertoire/tools-voice.js +144 -0
  305. package/dist/repertoire/tools.js +115 -103
  306. package/dist/repertoire/travel-api-client.js +360 -0
  307. package/dist/repertoire/user-profile.js +131 -0
  308. package/dist/repertoire/vault-setup.js +246 -0
  309. package/dist/repertoire/vault-unlock.js +594 -0
  310. package/dist/scripts/claude-code-hook.js +41 -0
  311. package/dist/scripts/claude-code-stop-hook.js +47 -0
  312. package/dist/senses/attention-queue.js +116 -0
  313. package/dist/senses/await-turn-message.js +58 -0
  314. package/dist/senses/bluebubbles/active-turns.js +216 -0
  315. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  316. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  317. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  318. package/dist/senses/bluebubbles/entry.js +77 -0
  319. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  320. package/dist/senses/bluebubbles/index.js +2613 -0
  321. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  322. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  323. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  324. package/dist/senses/bluebubbles/processed-log.js +133 -0
  325. package/dist/senses/bluebubbles/replay.js +137 -0
  326. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  327. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  328. package/dist/senses/bluebubbles-meta-guard.js +40 -0
  329. package/dist/senses/cli/bracketed-paste.js +82 -0
  330. package/dist/senses/cli/image-paste.js +287 -0
  331. package/dist/senses/cli/image-ref-navigation.js +75 -0
  332. package/dist/senses/cli/ink-app.js +156 -0
  333. package/dist/senses/cli/inline-diff.js +64 -0
  334. package/dist/senses/cli/input-keys.js +174 -0
  335. package/dist/senses/cli/kill-ring.js +86 -0
  336. package/dist/senses/cli/message-list.js +51 -0
  337. package/dist/senses/cli/ouro-tui.js +607 -0
  338. package/dist/senses/cli/spinner-imperative.js +135 -0
  339. package/dist/senses/cli/spinner.js +101 -0
  340. package/dist/senses/cli/status-line.js +60 -0
  341. package/dist/senses/cli/streaming-markdown.js +526 -0
  342. package/dist/senses/cli/tool-display.js +85 -0
  343. package/dist/senses/cli/tool-render.js +85 -0
  344. package/dist/senses/cli/tui-store.js +240 -0
  345. package/dist/senses/cli/virtual-list.js +35 -0
  346. package/dist/senses/cli-entry.js +60 -8
  347. package/dist/senses/cli-layout.js +100 -0
  348. package/dist/senses/cli.js +516 -204
  349. package/dist/senses/commands.js +66 -3
  350. package/dist/senses/habit-turn-message.js +108 -0
  351. package/dist/senses/inner-dialog-worker.js +185 -21
  352. package/dist/senses/inner-dialog.js +469 -39
  353. package/dist/senses/mail-entry.js +66 -0
  354. package/dist/senses/mail.js +379 -0
  355. package/dist/senses/pipeline.js +654 -181
  356. package/dist/senses/proactive-content-guard.js +51 -0
  357. package/dist/senses/shared-turn.js +392 -0
  358. package/dist/senses/surface-tool.js +70 -0
  359. package/dist/senses/teams-entry.js +60 -8
  360. package/dist/senses/teams.js +387 -98
  361. package/dist/senses/trust-gate.js +100 -5
  362. package/dist/senses/voice/audio-playback.js +237 -0
  363. package/dist/senses/voice/audio-routing.js +119 -0
  364. package/dist/senses/voice/elevenlabs.js +202 -0
  365. package/dist/senses/voice/floor-control.js +431 -0
  366. package/dist/senses/voice/floor-controller.js +115 -0
  367. package/dist/senses/voice/golden-path.js +116 -0
  368. package/dist/senses/voice/index.js +29 -0
  369. package/dist/senses/voice/meeting.js +113 -0
  370. package/dist/senses/voice/outbound.js +190 -0
  371. package/dist/senses/voice/phone.js +33 -0
  372. package/dist/senses/voice/playback.js +139 -0
  373. package/dist/senses/voice/realtime-eval.js +496 -0
  374. package/dist/senses/voice/realtime-trace.js +531 -0
  375. package/dist/senses/voice/transcript.js +70 -0
  376. package/dist/senses/voice/turn.js +191 -0
  377. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  378. package/dist/senses/voice/twilio-phone.js +5079 -0
  379. package/dist/senses/voice/types.js +2 -0
  380. package/dist/senses/voice/whisper.js +161 -0
  381. package/dist/senses/voice-entry.js +81 -0
  382. package/dist/senses/voice-realtime-eval-command.js +99 -0
  383. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  384. package/dist/senses/voice-twilio-entry.js +87 -0
  385. package/dist/trips/core.js +138 -0
  386. package/dist/trips/store.js +265 -0
  387. package/package.json +41 -7
  388. package/skills/agent-commerce.md +106 -0
  389. package/skills/browser-navigation.md +117 -0
  390. package/skills/commerce-setup-guide.md +116 -0
  391. package/skills/commerce-setup.md +84 -0
  392. package/skills/configure-dev-tools.md +99 -0
  393. package/skills/travel-planning.md +138 -0
  394. package/dist/heart/daemon/auth-flow.js +0 -351
  395. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  396. package/dist/heart/safe-workspace.js +0 -228
  397. package/dist/heart/session-recall.js +0 -116
  398. package/dist/mind/associative-recall.js +0 -209
  399. package/dist/senses/bluebubbles-entry.js +0 -13
  400. package/dist/senses/bluebubbles.js +0 -1177
  401. package/dist/senses/debug-activity.js +0 -148
  402. package/subagents/README.md +0 -7
  403. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  404. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  405. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  406. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  407. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  408. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  409. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  410. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  411. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  412. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  413. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  414. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  415. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  416. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  417. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  418. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Sync failure taxonomy classifier — Layer 2 of the harness-hardening sequence.
4
+ *
5
+ * Pure pattern-matcher over (error, context) that turns common git failure
6
+ * shapes into the locked taxonomy variants. Used by `runBootSyncProbe` (the
7
+ * `ouro up` pre-flight pull orchestrator) and by `postTurnPush`'s legacy
8
+ * push-rejected/conflict path so both producers share one vocabulary.
9
+ *
10
+ * Pattern priority — most actionable / specific wins:
11
+ * 1. Abort signal (timeout-soft / timeout-hard) — caller explicitly aborted.
12
+ * 2. not-found-404 — 404 / "Repository not found": remote endpoint gone.
13
+ * 3. auth-failed — 401 / 403 / "Authentication failed".
14
+ * 4. network-down — ENOTFOUND / ECONNREFUSED / "Could not resolve host".
15
+ * 5. dirty-working-tree — "would be overwritten" / "stash them".
16
+ * 6. merge-conflict — CONFLICT marker in stderr (also collects file list).
17
+ * 7. non-fast-forward — "non-fast-forward" / "fetch first".
18
+ * 8. unknown — fallthrough.
19
+ *
20
+ * The classifier never throws and never writes to disk. It calls
21
+ * `git status --porcelain=v1` only when it has already classified the error
22
+ * as a merge conflict, to enumerate unmerged paths for the consumer.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.classifySyncFailure = classifySyncFailure;
26
+ const child_process_1 = require("child_process");
27
+ /**
28
+ * Enumerate unmerged paths via `git status --porcelain=v1`. Pulled out as a
29
+ * pure helper so the classifier can be tested without a live git repo (the
30
+ * caller mocks `child_process.execFileSync`).
31
+ *
32
+ * Mirrors `sync.ts:collectRebaseConflictFiles` — kept as a separate copy here
33
+ * so this module has zero internal dep on `sync.ts`. The caller of
34
+ * `classifySyncFailure` doesn't see the duplication; the runtime cost is one
35
+ * git invocation per merge-conflict classification, same as before.
36
+ */
37
+ function collectConflictFiles(agentRoot) {
38
+ try {
39
+ const output = (0, child_process_1.execFileSync)("git", ["status", "--porcelain=v1"], {
40
+ cwd: agentRoot,
41
+ stdio: "pipe",
42
+ timeout: 5000,
43
+ }).toString();
44
+ const files = [];
45
+ for (const line of output.split("\n")) {
46
+ // Unmerged paths in porcelain v1 are prefixed with UU/AA/DD/AU/UA/DU/UD.
47
+ if (/^(UU|AA|DD|AU|UA|DU|UD) /.test(line)) {
48
+ files.push(line.slice(3).trim());
49
+ }
50
+ }
51
+ return files;
52
+ }
53
+ catch {
54
+ /* v8 ignore next -- defensive: git status failure inside a git repo would require a corrupt repo @preserve */
55
+ return [];
56
+ }
57
+ }
58
+ function isAbortError(error) {
59
+ if (typeof error !== "object" || error === null)
60
+ return false;
61
+ const candidate = error;
62
+ if (candidate.name === "AbortError")
63
+ return true;
64
+ if (candidate.code === "ABORT_ERR")
65
+ return true;
66
+ return false;
67
+ }
68
+ function readMessage(error) {
69
+ if (error instanceof Error)
70
+ return error.message;
71
+ if (typeof error === "string")
72
+ return error;
73
+ if (error === null || error === undefined)
74
+ return String(error);
75
+ try {
76
+ return JSON.stringify(error);
77
+ }
78
+ catch {
79
+ /* v8 ignore next -- defensive: JSON.stringify only fails on circular/BigInt; real-world git errors don't trigger it @preserve */
80
+ return String(error);
81
+ }
82
+ }
83
+ function readErrorCode(error) {
84
+ if (typeof error !== "object" || error === null)
85
+ return undefined;
86
+ const code = error.code;
87
+ return typeof code === "string" ? code : undefined;
88
+ }
89
+ /**
90
+ * Classify a sync failure into one of the locked taxonomy variants.
91
+ *
92
+ * Pure: never throws, never writes. Calls `git status` only when the error
93
+ * was already classified as a merge conflict, to enumerate unmerged files.
94
+ */
95
+ function classifySyncFailure(error, context) {
96
+ const message = readMessage(error);
97
+ const errorCode = readErrorCode(error);
98
+ // 1. Abort signal — highest priority. Caller's signal trumps content match.
99
+ if (isAbortError(error)) {
100
+ const reason = context.abortReason ?? "hard";
101
+ return {
102
+ classification: reason === "soft" ? "timeout-soft" : "timeout-hard",
103
+ error: message,
104
+ conflictFiles: [],
105
+ };
106
+ }
107
+ // Lowercased copy for case-insensitive substring matching.
108
+ const lower = message.toLowerCase();
109
+ // 2. Not-found-404 — most actionable diagnosis when both 404 and other
110
+ // signals are present. "404" and "Repository not found" are the canonical
111
+ // shapes.
112
+ if (lower.includes("404") || lower.includes("repository not found")) {
113
+ return {
114
+ classification: "not-found-404",
115
+ error: message,
116
+ conflictFiles: [],
117
+ };
118
+ }
119
+ // 3. Auth failed — 401 / 403 / "Authentication failed" / "Permission denied".
120
+ if (lower.includes("401")
121
+ || lower.includes("403")
122
+ || lower.includes("authentication failed")
123
+ || lower.includes("permission denied")) {
124
+ return {
125
+ classification: "auth-failed",
126
+ error: message,
127
+ conflictFiles: [],
128
+ };
129
+ }
130
+ // 4. Network down — DNS / connection errors.
131
+ if (errorCode === "ENOTFOUND"
132
+ || errorCode === "ECONNREFUSED"
133
+ || lower.includes("enotfound")
134
+ || lower.includes("econnrefused")
135
+ || lower.includes("could not resolve host")
136
+ || lower.includes("connection refused")) {
137
+ return {
138
+ classification: "network-down",
139
+ error: message,
140
+ conflictFiles: [],
141
+ };
142
+ }
143
+ // 5. Dirty working tree — pull / merge would clobber uncommitted changes.
144
+ if (lower.includes("would be overwritten")
145
+ || lower.includes("commit your changes or stash them")) {
146
+ return {
147
+ classification: "dirty-working-tree",
148
+ error: message,
149
+ conflictFiles: [],
150
+ };
151
+ }
152
+ // 6. Merge conflict — CONFLICT marker in stderr. Collect unmerged files.
153
+ if (lower.includes("conflict")) {
154
+ return {
155
+ classification: "merge-conflict",
156
+ error: message,
157
+ conflictFiles: collectConflictFiles(context.agentRoot),
158
+ };
159
+ }
160
+ // 7. Non-fast-forward — push rejected because remote moved.
161
+ if (lower.includes("non-fast-forward")
162
+ || lower.includes("fetch first")
163
+ || lower.includes("rejected")) {
164
+ return {
165
+ classification: "non-fast-forward",
166
+ error: message,
167
+ conflictFiles: [],
168
+ };
169
+ }
170
+ // 8. Fallthrough.
171
+ return {
172
+ classification: "unknown",
173
+ error: message,
174
+ conflictFiles: [],
175
+ };
176
+ }
@@ -0,0 +1,449 @@
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.preTurnPull = preTurnPull;
37
+ exports.postTurnPush = postTurnPush;
38
+ exports.preTurnPullAsync = preTurnPullAsync;
39
+ const child_process_1 = require("child_process");
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const runtime_1 = require("../nerves/runtime");
43
+ function writePendingSync(agentRoot, error, classification, conflictFiles) {
44
+ const pendingSyncPath = path.join(agentRoot, "state", "pending-sync.json");
45
+ fs.mkdirSync(path.join(agentRoot, "state"), { recursive: true });
46
+ const record = {
47
+ error,
48
+ failedAt: new Date().toISOString(),
49
+ classification,
50
+ conflictFiles,
51
+ };
52
+ fs.writeFileSync(pendingSyncPath, JSON.stringify(record, null, 2), "utf-8");
53
+ }
54
+ function collectRebaseConflictFiles(agentRoot) {
55
+ try {
56
+ const output = (0, child_process_1.execFileSync)("git", ["status", "--porcelain=v1"], {
57
+ cwd: agentRoot,
58
+ stdio: "pipe",
59
+ timeout: 5000,
60
+ }).toString();
61
+ const files = [];
62
+ for (const line of output.split("\n")) {
63
+ // Unmerged paths in porcelain v1 are prefixed with UU/AA/DD/AU/UA/DU/UD
64
+ if (/^(UU|AA|DD|AU|UA|DU|UD) /.test(line)) {
65
+ files.push(line.slice(3).trim());
66
+ }
67
+ }
68
+ return files;
69
+ }
70
+ catch {
71
+ /* v8 ignore next -- git status --porcelain failure inside a repo would require a corrupt repo @preserve */
72
+ return [];
73
+ }
74
+ }
75
+ /**
76
+ * Check whether the bundle is initialized as a git repo.
77
+ * Used by both pre-turn pull and post-turn push to surface a clear,
78
+ * actionable error when sync is enabled but the user never ran `git init`
79
+ * inside their bundle. This error is propagated all the way into the
80
+ * agent's start-of-turn packet as a Sync warning, so the agent can
81
+ * either ask the user or run `git init` itself.
82
+ */
83
+ function ensureGitRepo(agentRoot) {
84
+ if (fs.existsSync(path.join(agentRoot, ".git"))) {
85
+ return { ok: true };
86
+ }
87
+ const error = `bundle is not a git repo; run \`git init\` inside ${agentRoot} to enable sync (or disable sync in agent.json)`;
88
+ return { ok: false, error };
89
+ }
90
+ /**
91
+ * Pre-turn pull: sync the agent bundle from remote before assembling the start-of-turn packet.
92
+ *
93
+ * If the bundle has no git remote configured, the pull is skipped and the function
94
+ * returns ok — matching the no-remote behavior of postTurnPush. This supports the
95
+ * "local-only sync" mode where the bundle accumulates a commit log without ever
96
+ * pushing or pulling from a remote.
97
+ */
98
+ function preTurnPull(agentRoot, config) {
99
+ (0, runtime_1.emitNervesEvent)({
100
+ component: "heart",
101
+ event: "heart.sync_pull_start",
102
+ message: "pre-turn pull starting",
103
+ meta: { agentRoot, remote: config.remote },
104
+ });
105
+ // Check that the bundle is actually a git repo before touching git at all.
106
+ // Surfaces a clear, actionable error via syncFailure → start-of-turn packet
107
+ // so the agent can propose running `git init` (or just do it).
108
+ const repoCheck = ensureGitRepo(agentRoot);
109
+ if (!repoCheck.ok) {
110
+ (0, runtime_1.emitNervesEvent)({
111
+ level: "warn",
112
+ component: "heart",
113
+ event: "heart.sync_not_a_repo",
114
+ message: "pre-turn pull failed: bundle is not a git repo",
115
+ meta: { agentRoot },
116
+ });
117
+ return repoCheck;
118
+ }
119
+ // Check if any remote is configured. If not, skip the pull (local-only mode).
120
+ try {
121
+ const remoteOutput = (0, child_process_1.execFileSync)("git", ["remote"], {
122
+ cwd: agentRoot,
123
+ stdio: "pipe",
124
+ timeout: 5000,
125
+ }).toString().trim();
126
+ if (remoteOutput.length === 0) {
127
+ (0, runtime_1.emitNervesEvent)({
128
+ component: "heart",
129
+ event: "heart.sync_pull_end",
130
+ message: "pre-turn pull skipped: no remote configured",
131
+ meta: { agentRoot },
132
+ });
133
+ return { ok: true };
134
+ }
135
+ }
136
+ catch (err) {
137
+ const error = err instanceof Error ? err.message : String(err);
138
+ (0, runtime_1.emitNervesEvent)({
139
+ component: "heart",
140
+ event: "heart.sync_pull_error",
141
+ message: "pre-turn pull failed: git remote check failed",
142
+ meta: { agentRoot, error },
143
+ });
144
+ return { ok: false, error };
145
+ }
146
+ try {
147
+ (0, child_process_1.execFileSync)("git", ["pull", config.remote], {
148
+ cwd: agentRoot,
149
+ stdio: "pipe",
150
+ timeout: 30000,
151
+ });
152
+ (0, runtime_1.emitNervesEvent)({
153
+ component: "heart",
154
+ event: "heart.sync_pull_end",
155
+ message: "pre-turn pull complete",
156
+ meta: { agentRoot },
157
+ });
158
+ return { ok: true };
159
+ }
160
+ catch (err) {
161
+ const error = err instanceof Error ? err.message : String(err);
162
+ (0, runtime_1.emitNervesEvent)({
163
+ component: "heart",
164
+ event: "heart.sync_pull_error",
165
+ message: "pre-turn pull failed",
166
+ meta: { agentRoot, error },
167
+ });
168
+ return { ok: false, error };
169
+ }
170
+ }
171
+ /**
172
+ * Post-turn push: discover dirty files via `git status`, commit, and push.
173
+ * Uses git-status-based discovery instead of explicit path tracking, ensuring
174
+ * all file writers are captured regardless of whether they call a tracking API.
175
+ */
176
+ function postTurnPush(agentRoot, config) {
177
+ (0, runtime_1.emitNervesEvent)({
178
+ component: "heart",
179
+ event: "heart.sync_push_start",
180
+ message: "post-turn push starting",
181
+ meta: { agentRoot, remote: config.remote },
182
+ });
183
+ // Same git-repo check as preTurnPull. This is the more common failure path
184
+ // since postTurnPush runs after every turn while preTurnPull only runs on
185
+ // user-initiated turns. Prior to this guard, an un-init'd bundle would fail
186
+ // the git-status invocation below with a generic "not a git repository"
187
+ // error; now we catch it explicitly with an actionable message.
188
+ const repoCheck = ensureGitRepo(agentRoot);
189
+ if (!repoCheck.ok) {
190
+ (0, runtime_1.emitNervesEvent)({
191
+ level: "warn",
192
+ component: "heart",
193
+ event: "heart.sync_not_a_repo",
194
+ message: "post-turn push failed: bundle is not a git repo",
195
+ meta: { agentRoot },
196
+ });
197
+ return repoCheck;
198
+ }
199
+ let statusOutput;
200
+ try {
201
+ statusOutput = (0, child_process_1.execFileSync)("git", ["status", "--porcelain"], {
202
+ cwd: agentRoot,
203
+ stdio: "pipe",
204
+ timeout: 10000,
205
+ }).toString().trim();
206
+ }
207
+ catch (err) {
208
+ const error = err instanceof Error ? err.message : String(err);
209
+ (0, runtime_1.emitNervesEvent)({
210
+ component: "heart",
211
+ event: "heart.sync_push_error",
212
+ message: "post-turn push: git status failed",
213
+ meta: { agentRoot, error },
214
+ });
215
+ return { ok: false, error };
216
+ }
217
+ if (statusOutput.length === 0) {
218
+ (0, runtime_1.emitNervesEvent)({
219
+ component: "heart",
220
+ event: "heart.sync_push_end",
221
+ message: "post-turn push: no changes to sync",
222
+ meta: { agentRoot },
223
+ });
224
+ return { ok: true };
225
+ }
226
+ const changedCount = statusOutput.split("\n").length;
227
+ try {
228
+ (0, child_process_1.execFileSync)("git", ["add", "-A"], {
229
+ cwd: agentRoot,
230
+ stdio: "pipe",
231
+ timeout: 10000,
232
+ });
233
+ (0, child_process_1.execFileSync)("git", ["commit", "-m", "sync: post-turn update"], {
234
+ cwd: agentRoot,
235
+ stdio: "pipe",
236
+ timeout: 10000,
237
+ });
238
+ // Check if a remote exists
239
+ const remoteOutput = (0, child_process_1.execFileSync)("git", ["remote"], {
240
+ cwd: agentRoot,
241
+ stdio: "pipe",
242
+ timeout: 5000,
243
+ }).toString().trim();
244
+ if (remoteOutput.length === 0) {
245
+ (0, runtime_1.emitNervesEvent)({
246
+ component: "heart",
247
+ event: "heart.sync_push_end",
248
+ message: "post-turn push: committed locally, no remote configured",
249
+ meta: { agentRoot, changedCount },
250
+ });
251
+ return { ok: true };
252
+ }
253
+ try {
254
+ (0, child_process_1.execFileSync)("git", ["push", config.remote], {
255
+ cwd: agentRoot,
256
+ stdio: "pipe",
257
+ timeout: 30000,
258
+ });
259
+ }
260
+ catch {
261
+ // Push rejected -- try pull-rebase-push
262
+ let rebaseError = null;
263
+ try {
264
+ (0, child_process_1.execFileSync)("git", ["pull", "--rebase", config.remote], {
265
+ cwd: agentRoot,
266
+ stdio: "pipe",
267
+ timeout: 30000,
268
+ });
269
+ }
270
+ catch (err) {
271
+ rebaseError = err instanceof Error ? err.message : String(err);
272
+ }
273
+ if (rebaseError === null) {
274
+ try {
275
+ (0, child_process_1.execFileSync)("git", ["push", config.remote], {
276
+ cwd: agentRoot,
277
+ stdio: "pipe",
278
+ timeout: 30000,
279
+ });
280
+ // rebase + retry push both succeeded — fall through to success
281
+ (0, runtime_1.emitNervesEvent)({
282
+ component: "heart",
283
+ event: "heart.sync_push_end",
284
+ message: "post-turn push complete after rebase retry",
285
+ meta: { agentRoot, changedCount },
286
+ });
287
+ return { ok: true };
288
+ }
289
+ catch (retryErr) {
290
+ // Second push rejected — remote advanced again during rebase
291
+ const retryError = retryErr instanceof Error ? retryErr.message : /* v8 ignore next -- defensive non-Error catch @preserve */ String(retryErr);
292
+ writePendingSync(agentRoot, retryError, "push_rejected", []);
293
+ (0, runtime_1.emitNervesEvent)({
294
+ component: "heart",
295
+ event: "heart.sync_push_error",
296
+ message: "post-turn push failed after retry: push_rejected",
297
+ meta: { agentRoot, error: retryError, classification: "push_rejected" },
298
+ });
299
+ return { ok: false, error: retryError };
300
+ }
301
+ }
302
+ // Rebase failed — detect conflict files via git status. Preserve
303
+ // the original rebase error message so callers see the real cause.
304
+ const conflictFiles = collectRebaseConflictFiles(agentRoot);
305
+ const classification = conflictFiles.length > 0 ? "pull_rebase_conflict" : "unknown";
306
+ writePendingSync(agentRoot, rebaseError, classification, conflictFiles);
307
+ (0, runtime_1.emitNervesEvent)({
308
+ component: "heart",
309
+ event: "heart.sync_push_error",
310
+ message: `post-turn push failed: ${classification}`,
311
+ meta: { agentRoot, error: rebaseError, classification, conflictFiles },
312
+ });
313
+ return { ok: false, error: rebaseError };
314
+ }
315
+ (0, runtime_1.emitNervesEvent)({
316
+ component: "heart",
317
+ event: "heart.sync_push_end",
318
+ message: "post-turn push complete",
319
+ meta: { agentRoot, changedCount },
320
+ });
321
+ return { ok: true };
322
+ }
323
+ catch (err) {
324
+ const error = err instanceof Error ? err.message : String(err);
325
+ (0, runtime_1.emitNervesEvent)({
326
+ component: "heart",
327
+ event: "heart.sync_push_error",
328
+ message: "post-turn push failed",
329
+ meta: { agentRoot, error },
330
+ });
331
+ return { ok: false, error };
332
+ }
333
+ }
334
+ /**
335
+ * Layer 2 — async, signal-aware sibling of `preTurnPull`.
336
+ *
337
+ * Used by `runBootSyncProbe` (the `ouro up` boot orchestrator) to perform
338
+ * the pre-flight pull with end-to-end `AbortSignal` propagation. The
339
+ * underlying `child_process.execFile` accepts the signal and kills the git
340
+ * child process when it aborts, so a hung remote (DNS hole, slow server)
341
+ * can be cut by the boot timeout wrapper rather than hanging the whole
342
+ * boot.
343
+ *
344
+ * The legacy sync `preTurnPull` is preserved unchanged for the per-turn
345
+ * pipeline at `src/senses/pipeline.ts:522`. The two functions share the
346
+ * same `.git` and remote-availability gates — the only difference is the
347
+ * pull itself: `execFileSync` (no signal) vs `execFile` + `{ signal }`.
348
+ *
349
+ * Honour-the-signal contract:
350
+ * - If `options.signal` is already aborted at call time, the pull is
351
+ * skipped and the result is `{ ok: false, error: "aborted" }`.
352
+ * - If `options.signal` aborts mid-fetch, the child receives `SIGTERM`
353
+ * via Node's built-in AbortSignal handling, and the result is
354
+ * `{ ok: false, error: <abort message> }`.
355
+ * - With no signal supplied, behaviour matches the sync version (subject
356
+ * to the small differences listed above — same git-repo / no-remote
357
+ * gates and same nerves events).
358
+ */
359
+ function preTurnPullAsync(agentRoot, config, options = {}) {
360
+ (0, runtime_1.emitNervesEvent)({
361
+ component: "heart",
362
+ event: "heart.sync_pull_start",
363
+ message: "pre-turn pull starting (async)",
364
+ meta: { agentRoot, remote: config.remote },
365
+ });
366
+ // Bail early when the caller has already aborted — saves a git invocation
367
+ // and signals failure consistently.
368
+ if (options.signal?.aborted) {
369
+ (0, runtime_1.emitNervesEvent)({
370
+ level: "warn",
371
+ component: "heart",
372
+ event: "heart.sync_pull_aborted",
373
+ message: "pre-turn pull skipped: signal already aborted",
374
+ meta: { agentRoot },
375
+ });
376
+ return Promise.resolve({ ok: false, error: "aborted before pull started" });
377
+ }
378
+ // Same .git presence check as the sync version.
379
+ const repoCheck = ensureGitRepo(agentRoot);
380
+ if (!repoCheck.ok) {
381
+ (0, runtime_1.emitNervesEvent)({
382
+ level: "warn",
383
+ component: "heart",
384
+ event: "heart.sync_not_a_repo",
385
+ message: "pre-turn pull failed: bundle is not a git repo (async)",
386
+ meta: { agentRoot },
387
+ });
388
+ return Promise.resolve(repoCheck);
389
+ }
390
+ // Remote-presence check stays sync — it's a fast local op and doesn't
391
+ // need cancellation. The hangable op is the actual pull.
392
+ try {
393
+ const remoteOutput = (0, child_process_1.execFileSync)("git", ["remote"], {
394
+ cwd: agentRoot,
395
+ stdio: "pipe",
396
+ timeout: 5000,
397
+ }).toString().trim();
398
+ if (remoteOutput.length === 0) {
399
+ (0, runtime_1.emitNervesEvent)({
400
+ component: "heart",
401
+ event: "heart.sync_pull_end",
402
+ message: "pre-turn pull skipped: no remote configured (async)",
403
+ meta: { agentRoot },
404
+ });
405
+ return Promise.resolve({ ok: true });
406
+ }
407
+ }
408
+ catch (err) {
409
+ const error = err instanceof Error ? err.message : String(err);
410
+ (0, runtime_1.emitNervesEvent)({
411
+ component: "heart",
412
+ event: "heart.sync_pull_error",
413
+ message: "pre-turn pull failed: git remote check failed (async)",
414
+ meta: { agentRoot, error },
415
+ });
416
+ return Promise.resolve({ ok: false, error });
417
+ }
418
+ // The hangable op. `execFile` accepts `{ signal }` and kills the child
419
+ // when the signal aborts — that's the whole point of the async path.
420
+ const execOptions = {
421
+ cwd: agentRoot,
422
+ timeout: 30000,
423
+ };
424
+ if (options.signal) {
425
+ execOptions.signal = options.signal;
426
+ }
427
+ return new Promise((resolve) => {
428
+ (0, child_process_1.execFile)("git", ["pull", config.remote], execOptions, (err) => {
429
+ if (err) {
430
+ const error = err instanceof Error ? err.message : String(err);
431
+ (0, runtime_1.emitNervesEvent)({
432
+ component: "heart",
433
+ event: "heart.sync_pull_error",
434
+ message: "pre-turn pull failed (async)",
435
+ meta: { agentRoot, error },
436
+ });
437
+ resolve({ ok: false, error });
438
+ return;
439
+ }
440
+ (0, runtime_1.emitNervesEvent)({
441
+ component: "heart",
442
+ event: "heart.sync_pull_end",
443
+ message: "pre-turn pull complete (async)",
444
+ meta: { agentRoot },
445
+ });
446
+ resolve({ ok: true });
447
+ });
448
+ });
449
+ }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listTargetSessionCandidates = listTargetSessionCandidates;
4
4
  exports.formatTargetSessionCandidates = formatTargetSessionCandidates;
5
- const session_recall_1 = require("./session-recall");
5
+ const session_transcript_1 = require("./session-transcript");
6
6
  const session_activity_1 = require("./session-activity");
7
7
  const trust_explanation_1 = require("../mind/friends/trust-explanation");
8
8
  const runtime_1 = require("../nerves/runtime");
@@ -34,6 +34,10 @@ function activityPriority(source) {
34
34
  return source === "friend-facing" ? 0 : 1;
35
35
  }
36
36
  function describeDelivery(candidate) {
37
+ if (candidate.channel === "mcp") {
38
+ // MCP can't push (no proactive API), but can queue — dev tool picks up via check_response
39
+ return { mode: "queue_only", reason: "MCP session — message queued for dev tool to pick up via check_response" };
40
+ }
37
41
  if (candidate.channel !== "bluebubbles" && candidate.channel !== "teams") {
38
42
  return { mode: "blocked", reason: "this channel does not support proactive outward delivery yet" };
39
43
  }
@@ -67,7 +71,7 @@ async function listTargetSessionCandidates(input) {
67
71
  friend,
68
72
  channel: entry.channel,
69
73
  });
70
- const recall = await (0, session_recall_1.recallSession)({
74
+ const sessionTail = await (0, session_transcript_1.summarizeSessionTail)({
71
75
  sessionPath: entry.sessionPath,
72
76
  friendId: entry.friendId,
73
77
  channel: entry.channel,
@@ -76,9 +80,9 @@ async function listTargetSessionCandidates(input) {
76
80
  summarize: input.summarize,
77
81
  trustLevel: trust.level,
78
82
  });
79
- const snapshot = recall.kind === "ok"
80
- ? recall.snapshot
81
- : recall.kind === "empty"
83
+ const snapshot = sessionTail.kind === "ok"
84
+ ? sessionTail.snapshot
85
+ : sessionTail.kind === "empty"
82
86
  ? "recent focus: no recent visible messages"
83
87
  : "recent focus: session transcript unavailable";
84
88
  const delivery = describeDelivery({