@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.921

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 (717) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/assets/bluebubbles-host +264 -0
  14. package/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5826 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2997 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1254 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1564 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  38. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  39. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  40. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  41. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  42. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  43. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  44. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  45. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  46. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  52. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  53. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  54. package/deploy/unraid/sanctuary.xml +30 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +250 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command-grants.js +93 -0
  59. package/dist/a2a/delegated-command.js +197 -0
  60. package/dist/a2a/delegation-stores.js +56 -0
  61. package/dist/a2a/did-resolution.js +93 -0
  62. package/dist/a2a/escalation-grants.js +84 -0
  63. package/dist/a2a/escalation-wiring.js +60 -0
  64. package/dist/a2a/identity.js +258 -0
  65. package/dist/a2a/inbound-share.js +110 -0
  66. package/dist/a2a/mission-result-wire.js +196 -0
  67. package/dist/a2a/onboarding.js +133 -0
  68. package/dist/a2a/operator-trust.js +382 -0
  69. package/dist/a2a/outbox-client.js +57 -0
  70. package/dist/a2a/outbox-store.js +188 -0
  71. package/dist/a2a/outbox-wire.js +95 -0
  72. package/dist/a2a/pin-store.js +132 -0
  73. package/dist/a2a/replay-grant-holders.js +33 -0
  74. package/dist/a2a/replay-harness.js +188 -0
  75. package/dist/a2a/resolution-proof.js +53 -0
  76. package/dist/a2a/sealed-chat.js +113 -0
  77. package/dist/a2a/seen-ledger.js +120 -0
  78. package/dist/a2a/server.js +771 -0
  79. package/dist/a2a/task-store.js +69 -0
  80. package/dist/a2a/transport.js +45 -0
  81. package/dist/a2a/trust-commands.js +203 -0
  82. package/dist/a2a/trusted-files.js +185 -0
  83. package/dist/a2a/types.js +3 -0
  84. package/dist/arc/attention-types.js +8 -0
  85. package/dist/arc/cares.js +360 -0
  86. package/dist/arc/episodes.js +118 -0
  87. package/dist/arc/evolution.js +490 -0
  88. package/dist/arc/flight-recorder.js +1034 -0
  89. package/dist/arc/intentions.js +134 -0
  90. package/dist/arc/json-store.js +117 -0
  91. package/dist/arc/obligations.js +386 -0
  92. package/dist/arc/packets.js +336 -0
  93. package/dist/arc/presence.js +185 -0
  94. package/dist/arc/task-lifecycle.js +57 -0
  95. package/dist/commerce/store.js +755 -0
  96. package/dist/commerce/types.js +3 -0
  97. package/dist/heart/active-work.js +798 -40
  98. package/dist/heart/agent-entry.js +252 -3
  99. package/dist/heart/approval-files.js +113 -0
  100. package/dist/heart/approval-store.js +960 -0
  101. package/dist/heart/attachments/image-normalize.js +194 -0
  102. package/dist/heart/attachments/materialize.js +97 -0
  103. package/dist/heart/attachments/originals.js +88 -0
  104. package/dist/heart/attachments/render.js +29 -0
  105. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  106. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  107. package/dist/heart/attachments/sources/index.js +18 -0
  108. package/dist/heart/attachments/sources/telegram.js +71 -0
  109. package/dist/heart/attachments/store.js +132 -0
  110. package/dist/heart/attachments/types.js +93 -0
  111. package/dist/heart/auth/auth-flow.js +495 -0
  112. package/dist/heart/autonomy-budget.js +478 -0
  113. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  114. package/dist/heart/awaiting/await-alert.js +152 -0
  115. package/dist/heart/awaiting/await-expiry.js +143 -0
  116. package/dist/heart/awaiting/await-loader.js +91 -0
  117. package/dist/heart/awaiting/await-parser.js +152 -0
  118. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  119. package/dist/heart/awaiting/await-scheduler.js +391 -0
  120. package/dist/heart/background-operations.js +281 -0
  121. package/dist/heart/bluebubbles-host-account.js +78 -0
  122. package/dist/heart/bridges/manager.js +137 -17
  123. package/dist/heart/bridges/store.js +14 -2
  124. package/dist/heart/bundle-state.js +168 -0
  125. package/dist/heart/commitments.js +44 -18
  126. package/dist/heart/config-registry.js +331 -0
  127. package/dist/heart/config.js +174 -131
  128. package/dist/heart/context-loss-gauntlet.js +387 -0
  129. package/dist/heart/context-loss-sentinel.js +1159 -0
  130. package/dist/heart/core.js +2364 -578
  131. package/dist/heart/cross-chat-delivery.js +9 -22
  132. package/dist/heart/daemon/agent-config-check.js +451 -0
  133. package/dist/heart/daemon/agent-discovery.js +283 -3
  134. package/dist/heart/daemon/agent-home.js +319 -0
  135. package/dist/heart/daemon/agent-service.js +542 -0
  136. package/dist/heart/daemon/agentic-repair.js +547 -0
  137. package/dist/heart/daemon/await-private-wake.js +59 -0
  138. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  139. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  140. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  141. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  142. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  143. package/dist/heart/daemon/cadence.js +180 -0
  144. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  145. package/dist/heart/daemon/cli-defaults.js +876 -0
  146. package/dist/heart/daemon/cli-desk.js +322 -0
  147. package/dist/heart/daemon/cli-exec.js +9199 -0
  148. package/dist/heart/daemon/cli-help.js +735 -0
  149. package/dist/heart/daemon/cli-parse.js +3211 -0
  150. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  151. package/dist/heart/daemon/cli-render.js +819 -0
  152. package/dist/heart/daemon/cli-types.js +8 -0
  153. package/dist/heart/daemon/connect-bay.js +323 -0
  154. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  155. package/dist/heart/daemon/container-healthcheck.js +112 -0
  156. package/dist/heart/daemon/container-runtime.js +97 -0
  157. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  158. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  159. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  160. package/dist/heart/daemon/daemon-cli.js +29 -2350
  161. package/dist/heart/daemon/daemon-entry.js +953 -11
  162. package/dist/heart/daemon/daemon-health.js +186 -0
  163. package/dist/heart/daemon/daemon-rollup.js +57 -0
  164. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  165. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  166. package/dist/heart/daemon/daemon.js +2084 -105
  167. package/dist/heart/daemon/dns-workflow.js +394 -0
  168. package/dist/heart/daemon/doctor-types.js +8 -0
  169. package/dist/heart/daemon/doctor.js +1766 -0
  170. package/dist/heart/daemon/freshness.js +345 -0
  171. package/dist/heart/daemon/habit-private-wake.js +61 -0
  172. package/dist/heart/daemon/health-monitor.js +154 -11
  173. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  174. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  175. package/dist/heart/daemon/http-health-probe.js +80 -0
  176. package/dist/heart/daemon/human-command-screens.js +234 -0
  177. package/dist/heart/daemon/human-readiness.js +114 -0
  178. package/dist/heart/daemon/inner-status.js +78 -0
  179. package/dist/heart/daemon/interactive-repair.js +394 -0
  180. package/dist/heart/daemon/launchd.js +37 -8
  181. package/dist/heart/daemon/log-tailer.js +79 -10
  182. package/dist/heart/daemon/logs-prune.js +132 -0
  183. package/dist/heart/daemon/mcp-canary.js +524 -0
  184. package/dist/heart/daemon/message-router.js +65 -5
  185. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  186. package/dist/heart/daemon/os-cron-deps.js +135 -0
  187. package/dist/heart/daemon/os-cron.js +22 -14
  188. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  189. package/dist/heart/daemon/ouro-entry.js +5 -2
  190. package/dist/heart/daemon/plugin-cli.js +432 -0
  191. package/dist/heart/daemon/process-manager.js +760 -61
  192. package/dist/heart/daemon/provider-discovery.js +137 -0
  193. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  194. package/dist/heart/daemon/prunable-bundle.js +144 -0
  195. package/dist/heart/daemon/pulse.js +511 -0
  196. package/dist/heart/daemon/readiness-repair.js +365 -0
  197. package/dist/heart/daemon/run-hooks.js +2 -0
  198. package/dist/heart/daemon/runtime-logging.js +47 -14
  199. package/dist/heart/daemon/runtime-metadata.js +2 -30
  200. package/dist/heart/daemon/runtime-mode.js +13 -2
  201. package/dist/heart/daemon/safe-mode.js +161 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  206. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  207. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  208. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  209. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  210. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  211. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  212. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  213. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  214. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  215. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  216. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  217. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  219. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  220. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  225. package/dist/heart/daemon/sense-manager.js +733 -48
  226. package/dist/heart/daemon/session-id-resolver.js +131 -0
  227. package/dist/heart/daemon/skill-management-installer.js +1 -1
  228. package/dist/heart/daemon/socket-client.js +180 -12
  229. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  230. package/dist/heart/daemon/startup-tui.js +339 -0
  231. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  232. package/dist/heart/daemon/task-scheduler.js +117 -39
  233. package/dist/heart/daemon/terminal-ui.js +503 -0
  234. package/dist/heart/daemon/thoughts.js +138 -54
  235. package/dist/heart/daemon/up-progress.js +366 -0
  236. package/dist/heart/daemon/vault-items.js +56 -0
  237. package/dist/heart/delegation.js +1 -4
  238. package/dist/heart/external-events/router.js +1516 -0
  239. package/dist/heart/failure-reports.js +336 -0
  240. package/dist/heart/file-lock.js +109 -0
  241. package/dist/heart/frontend-approval-runtime.js +506 -0
  242. package/dist/heart/frontend-journal.js +215 -0
  243. package/dist/heart/frontend-session-service.js +237 -0
  244. package/dist/heart/frontend-socket-client.js +164 -0
  245. package/dist/heart/frontend-socket.js +400 -0
  246. package/dist/heart/habits/habit-cancel.js +810 -0
  247. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  248. package/dist/heart/habits/habit-migration.js +194 -0
  249. package/dist/heart/habits/habit-parser.js +278 -0
  250. package/dist/heart/habits/habit-runtime-state.js +93 -0
  251. package/dist/heart/habits/habit-scheduler.js +653 -0
  252. package/dist/heart/habits/habit-session-summary.js +318 -0
  253. package/dist/heart/habits/habit-session.js +636 -0
  254. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  255. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  256. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  257. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  258. package/dist/heart/identity.js +230 -59
  259. package/dist/heart/kept-notes.js +289 -0
  260. package/dist/heart/kicks.js +1 -1
  261. package/dist/heart/machine-identity.js +175 -0
  262. package/dist/heart/mail-import-discovery.js +356 -0
  263. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  264. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  265. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  266. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  267. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  268. package/dist/heart/mailbox/mailbox-http.js +99 -0
  269. package/dist/heart/mailbox/mailbox-read.js +39 -0
  270. package/dist/heart/mailbox/mailbox-types.js +27 -0
  271. package/dist/heart/mailbox/mailbox-view.js +197 -0
  272. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  273. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  274. package/dist/heart/mailbox/readers/mail.js +375 -0
  275. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  276. package/dist/heart/mailbox/readers/sessions.js +231 -0
  277. package/dist/heart/mailbox/readers/shared.js +111 -0
  278. package/dist/heart/mcp/mcp-server.js +696 -0
  279. package/dist/heart/migrate-config.js +100 -0
  280. package/dist/heart/model-capabilities.js +83 -16
  281. package/dist/heart/orientation-frame.js +345 -0
  282. package/dist/heart/platform.js +81 -0
  283. package/dist/heart/primitives.js +1 -1
  284. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  285. package/dist/heart/private-runtime/index.js +18 -0
  286. package/dist/heart/private-runtime/ledger.js +221 -0
  287. package/dist/heart/private-runtime/policy.js +260 -0
  288. package/dist/heart/private-runtime/types.js +2 -0
  289. package/dist/heart/progress-story.js +1 -1
  290. package/dist/heart/provider-attempt.js +137 -0
  291. package/dist/heart/provider-binding-resolver.js +273 -0
  292. package/dist/heart/provider-credentials.js +449 -0
  293. package/dist/heart/provider-failover.js +311 -0
  294. package/dist/heart/provider-models.js +96 -0
  295. package/dist/heart/provider-ping.js +265 -0
  296. package/dist/heart/provider-readiness-cache.js +119 -0
  297. package/dist/heart/provider-visibility.js +188 -0
  298. package/dist/heart/providers/anthropic-token.js +131 -0
  299. package/dist/heart/providers/anthropic.js +173 -60
  300. package/dist/heart/providers/azure.js +23 -11
  301. package/dist/heart/providers/error-classification.js +127 -0
  302. package/dist/heart/providers/github-copilot.js +38 -39
  303. package/dist/heart/providers/minimax-vlm.js +189 -0
  304. package/dist/heart/providers/minimax.js +26 -8
  305. package/dist/heart/providers/openai-codex-token.js +349 -0
  306. package/dist/heart/providers/openai-codex.js +55 -40
  307. package/dist/heart/providers/openai-compatible.js +177 -0
  308. package/dist/heart/reply-style.js +52 -0
  309. package/dist/heart/run-ledger.js +247 -0
  310. package/dist/heart/runtime-capability-check.js +170 -0
  311. package/dist/heart/runtime-credentials.js +607 -0
  312. package/dist/heart/runtime-cwd.js +87 -0
  313. package/dist/heart/sense-truth.js +24 -4
  314. package/dist/heart/session-activity.js +92 -24
  315. package/dist/heart/session-events.js +1504 -0
  316. package/dist/heart/session-playback-cli-main.js +5 -0
  317. package/dist/heart/session-playback-cli.js +36 -0
  318. package/dist/heart/session-playback.js +231 -0
  319. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  320. package/dist/heart/session-redaction-repair.js +552 -0
  321. package/dist/heart/session-stats-cli-main.js +5 -0
  322. package/dist/heart/session-stats.js +183 -0
  323. package/dist/heart/session-transcript.js +133 -0
  324. package/dist/heart/shelf-claims.js +78 -0
  325. package/dist/heart/shepherd-config.js +113 -0
  326. package/dist/heart/source-grounding.js +297 -0
  327. package/dist/heart/start-of-turn-packet.js +372 -0
  328. package/dist/heart/steward-policy.js +656 -0
  329. package/dist/heart/streaming.js +609 -207
  330. package/dist/heart/structured-output.js +196 -0
  331. package/dist/heart/sync-classification.js +176 -0
  332. package/dist/heart/sync-health.js +152 -0
  333. package/dist/heart/sync.js +726 -0
  334. package/dist/heart/target-resolution.js +11 -7
  335. package/dist/heart/tempo.js +93 -0
  336. package/dist/heart/temporal-view.js +41 -0
  337. package/dist/heart/timeouts.js +101 -0
  338. package/dist/heart/tool-activity-callbacks.js +59 -0
  339. package/dist/heart/tool-approval.js +382 -0
  340. package/dist/heart/tool-description.js +155 -0
  341. package/dist/heart/tool-friction.js +55 -0
  342. package/dist/heart/tool-loop.js +206 -0
  343. package/dist/heart/turn-context.js +496 -0
  344. package/dist/heart/turn-execution-lease.js +30 -0
  345. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  346. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  347. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  348. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  349. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  350. package/dist/heart/versioning/release-sources.js +173 -0
  351. package/dist/heart/versioning/self-update-defaults.js +294 -0
  352. package/dist/heart/versioning/self-update.js +196 -0
  353. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  354. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  355. package/dist/heart/versioning/update-hooks.js +154 -0
  356. package/dist/heart/versioning/update-state.js +126 -0
  357. package/dist/heart/versioning/updater-launchd.js +150 -0
  358. package/dist/heart/versioning/version-intent.js +114 -0
  359. package/dist/heart/work-card.js +380 -0
  360. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  361. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  362. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  363. package/dist/mailbox-ui/index.html +16 -0
  364. package/dist/mailroom/attention.js +167 -0
  365. package/dist/mailroom/autonomy.js +209 -0
  366. package/dist/mailroom/blob-store.js +889 -0
  367. package/dist/mailroom/body-cache.js +61 -0
  368. package/dist/mailroom/cache-sync-cli.js +58 -0
  369. package/dist/mailroom/core.js +803 -0
  370. package/dist/mailroom/entry.js +160 -0
  371. package/dist/mailroom/file-store.js +568 -0
  372. package/dist/mailroom/hosted-cache-sync.js +384 -0
  373. package/dist/mailroom/mbox-import.js +393 -0
  374. package/dist/mailroom/migration.js +164 -0
  375. package/dist/mailroom/outbound.js +380 -0
  376. package/dist/mailroom/policy.js +263 -0
  377. package/dist/mailroom/reader.js +292 -0
  378. package/dist/mailroom/search-cache.js +513 -0
  379. package/dist/mailroom/search-relevance.js +319 -0
  380. package/dist/mailroom/smtp-ingress.js +176 -0
  381. package/dist/mailroom/source-state.js +176 -0
  382. package/dist/mailroom/thread.js +109 -0
  383. package/dist/mailroom/travel-extract.js +89 -0
  384. package/dist/mind/bundle-manifest.js +24 -2
  385. package/dist/mind/context.js +307 -139
  386. package/dist/mind/desk-section.js +362 -0
  387. package/dist/mind/diary-integrity.js +60 -0
  388. package/dist/mind/{memory.js → diary.js} +68 -77
  389. package/dist/mind/embedding-provider.js +60 -0
  390. package/dist/mind/file-state.js +179 -0
  391. package/dist/mind/friend-link-codes.js +209 -0
  392. package/dist/mind/friend-merge.js +330 -0
  393. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  394. package/dist/mind/obligation-steering.js +199 -3
  395. package/dist/mind/pending.js +36 -10
  396. package/dist/mind/prompt-budget.js +479 -0
  397. package/dist/mind/prompt-refresh.js +3 -2
  398. package/dist/mind/prompt.js +1085 -198
  399. package/dist/mind/provenance-trust.js +26 -0
  400. package/dist/mind/record-paths.js +312 -0
  401. package/dist/mind/scrutiny.js +173 -0
  402. package/dist/mind/session-transaction.js +564 -0
  403. package/dist/nerves/cli-logging.js +7 -1
  404. package/dist/nerves/coverage/audit-rules.js +15 -6
  405. package/dist/nerves/coverage/audit.js +28 -2
  406. package/dist/nerves/coverage/cli.js +1 -1
  407. package/dist/nerves/coverage/contract.js +5 -5
  408. package/dist/nerves/coverage/file-completeness.js +139 -5
  409. package/dist/nerves/coverage/run-artifacts.js +55 -35
  410. package/dist/nerves/coverage/source-scanner.js +4 -4
  411. package/dist/nerves/event-buffer.js +111 -0
  412. package/dist/nerves/index.js +293 -9
  413. package/dist/nerves/observation.js +20 -0
  414. package/dist/nerves/redact.js +79 -0
  415. package/dist/nerves/review/cli-main.js +5 -0
  416. package/dist/nerves/review/cli.js +156 -0
  417. package/dist/nerves/review/core.js +159 -0
  418. package/dist/nerves/runtime.js +17 -1
  419. package/dist/repertoire/ado-client.js +15 -56
  420. package/dist/repertoire/ado-semantic.js +16 -10
  421. package/dist/repertoire/api-client.js +97 -0
  422. package/dist/repertoire/bitwarden-store.js +1201 -0
  423. package/dist/repertoire/bundle-templates.js +71 -0
  424. package/dist/repertoire/bw-installer.js +231 -0
  425. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  426. package/dist/repertoire/coding/context-pack.js +331 -0
  427. package/dist/repertoire/coding/feedback.js +174 -32
  428. package/dist/repertoire/coding/index.js +15 -3
  429. package/dist/repertoire/coding/manager.js +159 -10
  430. package/dist/repertoire/coding/spawner.js +40 -11
  431. package/dist/repertoire/coding/tools.js +182 -18
  432. package/dist/repertoire/coding/workbench-client.js +272 -0
  433. package/dist/repertoire/coding/workbench-manager.js +346 -0
  434. package/dist/repertoire/commerce-errors.js +109 -0
  435. package/dist/repertoire/commerce-self-test.js +156 -0
  436. package/dist/repertoire/credential-access.js +183 -0
  437. package/dist/repertoire/desk/classifier.js +362 -0
  438. package/dist/repertoire/duffel-client.js +185 -0
  439. package/dist/repertoire/github-client.js +14 -55
  440. package/dist/repertoire/graph-client.js +11 -52
  441. package/dist/repertoire/guardrails.js +968 -20
  442. package/dist/repertoire/house-sweep.js +469 -0
  443. package/dist/repertoire/mcp-client.js +58 -5
  444. package/dist/repertoire/mcp-manager.js +427 -139
  445. package/dist/repertoire/mcp-tools.js +132 -0
  446. package/dist/repertoire/mcp-write-guard.js +46 -0
  447. package/dist/repertoire/plugin-mcp.js +175 -0
  448. package/dist/repertoire/plugins.js +253 -0
  449. package/dist/repertoire/relationship-authorization.js +322 -0
  450. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  451. package/dist/repertoire/shell-sessions.js +134 -0
  452. package/dist/repertoire/skills.js +48 -4
  453. package/dist/repertoire/stripe-client.js +131 -0
  454. package/dist/repertoire/tool-arguments.js +182 -0
  455. package/dist/repertoire/tool-results.js +29 -0
  456. package/dist/repertoire/tools-a2a.js +699 -0
  457. package/dist/repertoire/tools-attachments.js +322 -0
  458. package/dist/repertoire/tools-awaiting.js +872 -0
  459. package/dist/repertoire/tools-base.js +83 -1168
  460. package/dist/repertoire/tools-bluebubbles.js +2 -0
  461. package/dist/repertoire/tools-bridge.js +144 -0
  462. package/dist/repertoire/tools-bundle.js +995 -0
  463. package/dist/repertoire/tools-commerce.js +253 -0
  464. package/dist/repertoire/tools-config.js +186 -0
  465. package/dist/repertoire/tools-continuity.js +575 -0
  466. package/dist/repertoire/tools-credential.js +383 -0
  467. package/dist/repertoire/tools-escalation.js +84 -0
  468. package/dist/repertoire/tools-evolution.js +527 -0
  469. package/dist/repertoire/tools-files.js +344 -0
  470. package/dist/repertoire/tools-flight.js +290 -0
  471. package/dist/repertoire/tools-flow.js +119 -0
  472. package/dist/repertoire/tools-friend-link.js +57 -0
  473. package/dist/repertoire/tools-github.js +3 -8
  474. package/dist/repertoire/tools-habits.js +103 -0
  475. package/dist/repertoire/tools-house-care.js +174 -0
  476. package/dist/repertoire/tools-mail.js +1828 -0
  477. package/dist/repertoire/tools-notes.js +496 -0
  478. package/dist/repertoire/tools-obligations.js +182 -0
  479. package/dist/repertoire/tools-orientation.js +31 -0
  480. package/dist/repertoire/tools-record.js +482 -0
  481. package/dist/repertoire/tools-rsvp.js +139 -0
  482. package/dist/repertoire/tools-runtime.js +238 -0
  483. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  484. package/dist/repertoire/tools-session.js +1133 -0
  485. package/dist/repertoire/tools-shell.js +149 -0
  486. package/dist/repertoire/tools-shepherd.js +262 -0
  487. package/dist/repertoire/tools-steward-policy.js +147 -0
  488. package/dist/repertoire/tools-stripe.js +224 -0
  489. package/dist/repertoire/tools-surface.js +369 -0
  490. package/dist/repertoire/tools-teams.js +12 -39
  491. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  492. package/dist/repertoire/tools-travel.js +125 -0
  493. package/dist/repertoire/tools-trip.js +982 -0
  494. package/dist/repertoire/tools-unraid.js +556 -0
  495. package/dist/repertoire/tools-user-profile.js +146 -0
  496. package/dist/repertoire/tools-vault.js +40 -0
  497. package/dist/repertoire/tools-voice-local.js +198 -0
  498. package/dist/repertoire/tools-voice.js +145 -0
  499. package/dist/repertoire/tools.js +514 -156
  500. package/dist/repertoire/travel-api-client.js +360 -0
  501. package/dist/repertoire/unraid-client.js +155 -0
  502. package/dist/repertoire/unraid-restart.js +339 -0
  503. package/dist/repertoire/user-profile.js +131 -0
  504. package/dist/repertoire/vault-setup.js +246 -0
  505. package/dist/repertoire/vault-unlock.js +686 -0
  506. package/dist/rsvp/aisleplanner-client.js +354 -0
  507. package/dist/rsvp/cli.js +936 -0
  508. package/dist/rsvp/config.js +327 -0
  509. package/dist/rsvp/cutover.js +433 -0
  510. package/dist/rsvp/diagnostics.js +232 -0
  511. package/dist/rsvp/diff-renderer.js +176 -0
  512. package/dist/rsvp/habit-policy.js +110 -0
  513. package/dist/rsvp/habit-stage.js +123 -0
  514. package/dist/rsvp/incident-bundle.js +97 -0
  515. package/dist/rsvp/migration.js +204 -0
  516. package/dist/rsvp/native-habit-runner.js +630 -0
  517. package/dist/rsvp/outbound-state.js +628 -0
  518. package/dist/rsvp/query.js +118 -0
  519. package/dist/rsvp/replay.js +233 -0
  520. package/dist/rsvp/snapshot.js +232 -0
  521. package/dist/rsvp/spend-ledger.js +175 -0
  522. package/dist/scripts/claude-code-hook.js +41 -0
  523. package/dist/scripts/claude-code-stop-hook.js +47 -0
  524. package/dist/senses/a2a-entry.js +132 -0
  525. package/dist/senses/acp-server.js +386 -0
  526. package/dist/senses/attention-queue.js +186 -0
  527. package/dist/senses/await-turn-message.js +65 -0
  528. package/dist/senses/bluebubbles/active-turns.js +216 -0
  529. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  530. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  531. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +379 -41
  532. package/dist/senses/bluebubbles/context-packet.js +207 -0
  533. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  534. package/dist/senses/bluebubbles/entry.js +90 -0
  535. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  536. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  537. package/dist/senses/bluebubbles/index.js +3878 -0
  538. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  539. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  540. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  541. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  542. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  543. package/dist/senses/bluebubbles/processed-log.js +133 -0
  544. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  545. package/dist/senses/bluebubbles/replay.js +284 -0
  546. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  547. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  548. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  549. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  550. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  551. package/dist/senses/cli/bracketed-paste.js +82 -0
  552. package/dist/senses/cli/image-paste.js +287 -0
  553. package/dist/senses/cli/image-ref-navigation.js +75 -0
  554. package/dist/senses/cli/ink-app.js +156 -0
  555. package/dist/senses/cli/inline-diff.js +64 -0
  556. package/dist/senses/cli/input-keys.js +174 -0
  557. package/dist/senses/cli/kill-ring.js +86 -0
  558. package/dist/senses/cli/message-list.js +51 -0
  559. package/dist/senses/cli/ouro-tui.js +607 -0
  560. package/dist/senses/cli/spinner-imperative.js +135 -0
  561. package/dist/senses/cli/spinner.js +101 -0
  562. package/dist/senses/cli/status-line.js +60 -0
  563. package/dist/senses/cli/streaming-markdown.js +526 -0
  564. package/dist/senses/cli/tool-display.js +85 -0
  565. package/dist/senses/cli/tool-render.js +85 -0
  566. package/dist/senses/cli/tui-store.js +241 -0
  567. package/dist/senses/cli/virtual-list.js +35 -0
  568. package/dist/senses/cli-entry.js +60 -8
  569. package/dist/senses/cli.js +601 -304
  570. package/dist/senses/commands.js +66 -3
  571. package/dist/senses/context-packet-ledger.js +371 -0
  572. package/dist/senses/context-packets.js +154 -0
  573. package/dist/senses/habit-lifecycle-guard.js +24 -0
  574. package/dist/senses/habit-turn-message.js +160 -0
  575. package/dist/senses/ingress-evidence.js +2 -0
  576. package/dist/senses/mail-entry.js +66 -0
  577. package/dist/senses/mail.js +524 -0
  578. package/dist/senses/pipeline.js +1158 -204
  579. package/dist/senses/private-runtime-worker.js +859 -0
  580. package/dist/senses/private-runtime.js +1627 -0
  581. package/dist/senses/proactive-content-guard.js +51 -0
  582. package/dist/senses/root-host-approval-port.js +345 -0
  583. package/dist/senses/root-host-approval-runtime.js +393 -0
  584. package/dist/senses/sanctuary-authority-resident.js +102 -0
  585. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  586. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  587. package/dist/senses/sanctuary-grounding.js +118 -0
  588. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  589. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  590. package/dist/senses/sanctuary-health-runner.js +104 -0
  591. package/dist/senses/sanctuary-health.js +422 -0
  592. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  593. package/dist/senses/sanctuary-interactive-control.js +410 -0
  594. package/dist/senses/sanctuary-media-catalog-contract.js +259 -0
  595. package/dist/senses/sanctuary-media-optimization.js +514 -0
  596. package/dist/senses/sanctuary-runtime.js +369 -0
  597. package/dist/senses/sanctuary-sab.js +85 -0
  598. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  599. package/dist/senses/shared-turn.js +793 -0
  600. package/dist/senses/shepherd/client.js +196 -0
  601. package/dist/senses/shepherd/cmux.js +352 -0
  602. package/dist/senses/shepherd/herdr.js +315 -0
  603. package/dist/senses/shepherd/host.js +14 -0
  604. package/dist/senses/shepherd/judge.js +137 -0
  605. package/dist/senses/shepherd/owner-notice.js +251 -0
  606. package/dist/senses/shepherd/redact.js +66 -0
  607. package/dist/senses/shepherd/returns.js +79 -0
  608. package/dist/senses/shepherd/sense.js +310 -0
  609. package/dist/senses/shepherd/terminal-process.js +99 -0
  610. package/dist/senses/shepherd-entry.js +78 -0
  611. package/dist/senses/surface-tool.js +109 -0
  612. package/dist/senses/teams-entry.js +68 -8
  613. package/dist/senses/teams.js +598 -233
  614. package/dist/senses/telegram-admission.js +718 -0
  615. package/dist/senses/telegram-approval-runtime.js +793 -0
  616. package/dist/senses/telegram-attachments.js +186 -0
  617. package/dist/senses/telegram-audit-ledger.js +220 -0
  618. package/dist/senses/telegram-authority-transport.js +231 -0
  619. package/dist/senses/telegram-client.js +1749 -0
  620. package/dist/senses/telegram-effect-adapter.js +900 -0
  621. package/dist/senses/telegram-entry.js +83 -0
  622. package/dist/senses/telegram-handoff.js +80 -0
  623. package/dist/senses/telegram.js +2405 -0
  624. package/dist/senses/trust-gate.js +104 -9
  625. package/dist/senses/voice/audio-playback.js +237 -0
  626. package/dist/senses/voice/audio-routing.js +119 -0
  627. package/dist/senses/voice/call-auth.js +250 -0
  628. package/dist/senses/voice/elevenlabs.js +202 -0
  629. package/dist/senses/voice/floor-control.js +431 -0
  630. package/dist/senses/voice/floor-controller.js +115 -0
  631. package/dist/senses/voice/golden-path.js +116 -0
  632. package/dist/senses/voice/index.js +29 -0
  633. package/dist/senses/voice/local-audio-control.js +344 -0
  634. package/dist/senses/voice/local-audio-devices.js +516 -0
  635. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  636. package/dist/senses/voice/local-audio-identity.js +103 -0
  637. package/dist/senses/voice/local-audio-join.js +325 -0
  638. package/dist/senses/voice/local-audio-mute.js +199 -0
  639. package/dist/senses/voice/local-audio-notify.js +121 -0
  640. package/dist/senses/voice/local-audio-prompts.js +116 -0
  641. package/dist/senses/voice/local-audio-transport.js +427 -0
  642. package/dist/senses/voice/local-audio.js +281 -0
  643. package/dist/senses/voice/local-media-stream.js +145 -0
  644. package/dist/senses/voice/meeting.js +113 -0
  645. package/dist/senses/voice/outbound.js +190 -0
  646. package/dist/senses/voice/phone.js +33 -0
  647. package/dist/senses/voice/playback.js +139 -0
  648. package/dist/senses/voice/process-guards.js +51 -0
  649. package/dist/senses/voice/realtime-eval.js +496 -0
  650. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  651. package/dist/senses/voice/realtime-trace.js +531 -0
  652. package/dist/senses/voice/transcript.js +70 -0
  653. package/dist/senses/voice/turn.js +191 -0
  654. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  655. package/dist/senses/voice/twilio-phone.js +5454 -0
  656. package/dist/senses/voice/types.js +2 -0
  657. package/dist/senses/voice/whisper.js +161 -0
  658. package/dist/senses/voice-entry.js +83 -0
  659. package/dist/senses/voice-realtime-eval-command.js +99 -0
  660. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  661. package/dist/senses/voice-twilio-entry.js +87 -0
  662. package/dist/trips/core.js +138 -0
  663. package/dist/trips/store.js +265 -0
  664. package/dist/util/frontmatter.js +69 -0
  665. package/npm-shrinkwrap.json +8100 -0
  666. package/package.json +74 -13
  667. package/skills/agent-commerce.md +113 -0
  668. package/skills/browser-navigation.md +117 -0
  669. package/skills/commerce-setup-guide.md +116 -0
  670. package/skills/commerce-setup.md +84 -0
  671. package/skills/configure-dev-tools.md +99 -0
  672. package/skills/travel-planning.md +138 -0
  673. package/dist/heart/daemon/auth-flow.js +0 -430
  674. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  675. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  676. package/dist/heart/daemon/update-hooks.js +0 -138
  677. package/dist/heart/obligations.js +0 -191
  678. package/dist/heart/safe-workspace.js +0 -362
  679. package/dist/heart/session-recall.js +0 -116
  680. package/dist/mind/friends/channel.js +0 -84
  681. package/dist/mind/friends/group-context.js +0 -144
  682. package/dist/mind/friends/resolver.js +0 -84
  683. package/dist/mind/friends/store-file.js +0 -190
  684. package/dist/mind/friends/store.js +0 -4
  685. package/dist/mind/friends/tokens.js +0 -26
  686. package/dist/mind/friends/trust-explanation.js +0 -74
  687. package/dist/mind/friends/types.js +0 -29
  688. package/dist/repertoire/tasks/board.js +0 -134
  689. package/dist/repertoire/tasks/index.js +0 -224
  690. package/dist/repertoire/tasks/lifecycle.js +0 -80
  691. package/dist/repertoire/tasks/middleware.js +0 -65
  692. package/dist/repertoire/tasks/parser.js +0 -173
  693. package/dist/repertoire/tasks/scanner.js +0 -132
  694. package/dist/repertoire/tasks/transitions.js +0 -144
  695. package/dist/senses/bluebubbles-entry.js +0 -13
  696. package/dist/senses/bluebubbles.js +0 -1181
  697. package/dist/senses/debug-activity.js +0 -154
  698. package/dist/senses/inner-dialog-worker.js +0 -90
  699. package/dist/senses/inner-dialog.js +0 -525
  700. package/subagents/README.md +0 -7
  701. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  702. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  703. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  704. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  705. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  706. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  707. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  708. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  709. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  710. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  711. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  712. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  713. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  714. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  715. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  716. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  717. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,196 @@
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.CmuxSocketError = void 0;
37
+ exports.createCmuxClient = createCmuxClient;
38
+ const node_crypto_1 = require("node:crypto");
39
+ const net = __importStar(require("node:net"));
40
+ const shepherd_config_1 = require("../../heart/shepherd-config");
41
+ const runtime_1 = require("../../nerves/runtime");
42
+ class CmuxSocketError extends Error {
43
+ code;
44
+ constructor(code, message) {
45
+ super(message);
46
+ this.code = code;
47
+ this.name = "CmuxSocketError";
48
+ }
49
+ }
50
+ exports.CmuxSocketError = CmuxSocketError;
51
+ const ACCESS_REFUSED = /access denied|authentication required|invalid password|not authorized|unauthori[sz]ed/i;
52
+ function isRecord(value) {
53
+ return !!value && typeof value === "object" && !Array.isArray(value);
54
+ }
55
+ function parseRecord(line) {
56
+ try {
57
+ const value = JSON.parse(line);
58
+ return isRecord(value) ? value : null;
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ function createCmuxClient(connection, options = {}) {
65
+ const timeoutMs = options.timeoutMs ?? 5_000;
66
+ const repair = (0, shepherd_config_1.shepherdRepairHint)(options.agentName ?? "<agent>");
67
+ const wrap = (line) => connection.auth.kind === "capability"
68
+ ? `_cmux_capability_v1 ${connection.auth.token} ${line}`
69
+ : line;
70
+ const refusal = (text) => text.startsWith("ERROR:") && ACCESS_REFUSED.test(text)
71
+ ? new CmuxSocketError("auth", `cmux refused the socket connection (${text.slice(0, 200)}); ${repair}`)
72
+ : null;
73
+ const connectError = (error) => new CmuxSocketError("unavailable", `cmux socket is not reachable at ${connection.socketPath} (${String(error.code)}); is cmux running?`);
74
+ /** Opens a connection, runs the password handshake when needed, and hands back a line reader. */
75
+ function open(onLine, onEnd) {
76
+ return new Promise((resolve) => {
77
+ const socket = net.createConnection(connection.socketPath);
78
+ let buffer = "";
79
+ let handshake = connection.auth.kind === "password";
80
+ socket.setEncoding("utf-8");
81
+ socket.on("error", (error) => onEnd(connectError(error)));
82
+ socket.on("close", () => onEnd());
83
+ socket.on("data", (chunk) => {
84
+ buffer += chunk;
85
+ let index = buffer.indexOf("\n");
86
+ while (index >= 0) {
87
+ const line = buffer.slice(0, index).trim();
88
+ buffer = buffer.slice(index + 1);
89
+ index = buffer.indexOf("\n");
90
+ if (!line)
91
+ continue;
92
+ if (handshake) {
93
+ handshake = false;
94
+ if (line.startsWith("ERROR:") && !line.includes("Unknown command 'auth'")) {
95
+ socket.destroy();
96
+ onEnd(new CmuxSocketError("auth", `cmux rejected the socket password (${line.slice(0, 200)}); ${repair}`));
97
+ continue;
98
+ }
99
+ resolve(socket);
100
+ continue;
101
+ }
102
+ onLine(line);
103
+ }
104
+ });
105
+ socket.on("connect", () => {
106
+ if (connection.auth.kind === "password")
107
+ socket.write(`auth ${connection.auth.password}\n`);
108
+ else
109
+ resolve(socket);
110
+ });
111
+ });
112
+ }
113
+ function request(line) {
114
+ return new Promise((resolve, reject) => {
115
+ let settled = false;
116
+ let socket = null;
117
+ const finish = (error, value) => {
118
+ if (settled)
119
+ return;
120
+ settled = true;
121
+ clearTimeout(timer);
122
+ socket?.destroy();
123
+ if (error)
124
+ reject(error);
125
+ else
126
+ resolve(value);
127
+ };
128
+ const timer = setTimeout(() => finish(new CmuxSocketError("timeout", `cmux did not answer within ${timeoutMs} ms`)), timeoutMs);
129
+ void open((response) => finish(refusal(response), response), (error) => finish(error ?? new CmuxSocketError("unavailable", "cmux closed the socket before answering"))).then((opened) => {
130
+ socket = opened;
131
+ opened.write(`${wrap(line)}\n`);
132
+ });
133
+ });
134
+ }
135
+ const v2Line = (method, params) => JSON.stringify({ id: (0, node_crypto_1.randomUUID)(), method, params });
136
+ function parseV2(text) {
137
+ const parsed = parseRecord(text);
138
+ if (!parsed)
139
+ throw new CmuxSocketError(text.startsWith("ERROR:") ? "command_failed" : "protocol", `unexpected cmux response: ${text.slice(0, 200)}`);
140
+ if (parsed.ok === true)
141
+ return isRecord(parsed.result) ? parsed.result : {};
142
+ const error = isRecord(parsed.error) ? parsed.error : {};
143
+ throw new CmuxSocketError(typeof error.code === "string" ? error.code : "error", typeof error.message === "string" && error.message ? error.message : "cmux error");
144
+ }
145
+ return {
146
+ async call(method, params = {}) {
147
+ const text = await request(v2Line(method, params));
148
+ const result = parseV2(text);
149
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_call", message: "cmux socket call answered", meta: { method } });
150
+ return result;
151
+ },
152
+ async command(line) {
153
+ const text = await request(line);
154
+ if (text.startsWith("ERROR:"))
155
+ throw new CmuxSocketError("command_failed", text.slice(0, 500));
156
+ return text;
157
+ },
158
+ stream(params, handlers) {
159
+ let closed = false;
160
+ let socket = null;
161
+ const end = (error) => {
162
+ if (closed)
163
+ return;
164
+ closed = true;
165
+ socket?.destroy();
166
+ handlers.onClose(error);
167
+ };
168
+ void open((line) => {
169
+ if (closed)
170
+ return;
171
+ const refused = refusal(line);
172
+ if (refused)
173
+ return end(refused);
174
+ const frame = parseRecord(line);
175
+ if (!frame)
176
+ return end(new CmuxSocketError("protocol", `unexpected cmux event frame: ${line.slice(0, 200)}`));
177
+ if (frame.ok === false) {
178
+ try {
179
+ parseV2(line);
180
+ }
181
+ catch (error) {
182
+ return end(error);
183
+ }
184
+ }
185
+ handlers.onFrame(frame);
186
+ }, end).then((opened) => {
187
+ socket = opened;
188
+ if (closed)
189
+ opened.destroy();
190
+ else
191
+ opened.write(`${wrap(v2Line("events.stream", params))}\n`);
192
+ });
193
+ return { close: () => end() };
194
+ },
195
+ };
196
+ }
@@ -0,0 +1,352 @@
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.QUIET_MAX_MS = exports.HOOKED_QUIET_MS = exports.QUIET_MS = exports.POLL_MS = exports.BACKGROUND_GRACE_MS = exports.GRACE_MS = exports.CMUX_STATUS_KEY = void 0;
37
+ exports.realSchedule = realSchedule;
38
+ exports.readCmuxHookSession = readCmuxHookSession;
39
+ exports.createCmuxHost = createCmuxHost;
40
+ const node_crypto_1 = require("node:crypto");
41
+ const fs = __importStar(require("node:fs"));
42
+ const os = __importStar(require("node:os"));
43
+ const path = __importStar(require("node:path"));
44
+ const runtime_1 = require("../../nerves/runtime");
45
+ const terminal_process_1 = require("./terminal-process");
46
+ /**
47
+ * The cmux host (0.64.22 or later). A return is cmux's own "agent stopped" signal: an
48
+ * `agent.hook.Stop` event, which cmux publishes for every agent its hooks cover (Claude Code,
49
+ * Codex, Copilot and more). After a short grace period, a stop is dropped if the agent resumed. A
50
+ * stop that cmux's session store says left background work running waits longer, and is then
51
+ * passed on marked as such: the agent is still working, not handing back control. Every terminal
52
+ * whose agent is not idle is also polled: output that stops changing for a quiet window counts
53
+ * as a return. That covers an agent cmux does not hook, and a hooked agent sitting mid-turn at a
54
+ * prompt that fires no stop (a permission or trust question); a hooked agent gets a longer window,
55
+ * because its stop normally speaks first. cmux has no bell or output event, so polling is the fallback.
56
+ */
57
+ exports.CMUX_STATUS_KEY = "ouro";
58
+ exports.GRACE_MS = 3_000;
59
+ /** A stop with background work still running waits this much longer before it is judged (as working, unless the work finished). */
60
+ exports.BACKGROUND_GRACE_MS = 30_000;
61
+ exports.POLL_MS = 4_000;
62
+ exports.QUIET_MS = 8_000;
63
+ /** A hooked agent mid-turn: long enough that a stop hook or a spinner normally speaks before the quiet screen does. */
64
+ exports.HOOKED_QUIET_MS = 20_000;
65
+ /** A quiet terminal judged as still working or not an agent is checked less often, doubling up to this. */
66
+ exports.QUIET_MAX_MS = 60_000;
67
+ const POLL_LINES = 40;
68
+ const RECONNECT_DELAYS_MS = [1_000, 2_000, 5_000, 10_000, 30_000];
69
+ const STOP_HOOKS = new Set(["Stop", "StopFailure"]);
70
+ /** Hooks after which the agent waits for the human: a stop, or a session that has not been given work yet. */
71
+ const IDLE_HOOKS = new Set([...STOP_HOOKS, "SessionStart"]);
72
+ /** Hooks that say nothing about whether the main agent is working. */
73
+ const NEUTRAL_HOOKS = new Set(["SubagentStop", "Notification"]);
74
+ /** Keys cmux presses with `surface.send_key`, by its own names; every other key is typed as its character. */
75
+ const NAMED_KEYS = { enter: "enter", escape: "escape", up: "up", down: "down", tab: "tab", "ctrl-c": "ctrl+c" };
76
+ const SUBMIT_DELAY_MS = 300;
77
+ /** A timer that can be cancelled; the sense and the host take it as an option so tests can drive time. */
78
+ function realSchedule(fn, ms) {
79
+ const timer = setTimeout(fn, ms);
80
+ return () => clearTimeout(timer);
81
+ }
82
+ function isRecord(value) {
83
+ return !!value && typeof value === "object" && !Array.isArray(value);
84
+ }
85
+ function str(value) {
86
+ return typeof value === "string" && value.length > 0 ? value : null;
87
+ }
88
+ function list(value) {
89
+ return Array.isArray(value) ? value.filter(isRecord) : [];
90
+ }
91
+ /** A v1 socket argument: quoted, with the characters cmux's tokenizer treats as special escaped. */
92
+ function socketQuote(value) {
93
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
94
+ }
95
+ /** cmux keeps each hooked agent's session in `~/.cmuxterm/<agent>-hook-sessions.json`, keyed by the agent's own session id. */
96
+ function readCmuxHookSession(homeDir, agent, sessionId) {
97
+ try {
98
+ const store = JSON.parse(fs.readFileSync(path.join(homeDir, ".cmuxterm", `${path.basename(agent)}-hook-sessions.json`), "utf-8"));
99
+ const sessions = isRecord(store) && isRecord(store.sessions) ? store.sessions : {};
100
+ // Hook events name the session `<agent>-<id>`; the store keys it by the bare id.
101
+ const key = [sessionId, sessionId.replace(`${agent}-`, "")].find((candidate) => isRecord(sessions[candidate]));
102
+ return key ? sessions[key] : null;
103
+ }
104
+ catch {
105
+ return null;
106
+ }
107
+ }
108
+ function createCmuxHost(client, options = {}) {
109
+ const homeDir = options.homeDir ?? os.homedir();
110
+ const now = options.now ?? Date.now;
111
+ const schedule = options.schedule ?? realSchedule;
112
+ /** What hook events taught: which surface a session runs in, and which agent and folder it has. */
113
+ const hooked = new Map();
114
+ const sessionSurface = new Map();
115
+ /** Terminals showing a Shepherd status, so it can be cleared when the agent resumes. */
116
+ const statused = new Map();
117
+ /** Quiet windows stretched by `pace`. */
118
+ const quietMs = new Map();
119
+ /** One status entry per terminal: cmux keys status pills per workspace, and a workspace can hold several agents. */
120
+ const statusKey = (surface) => `${exports.CMUX_STATUS_KEY}_${surface.ref.replace(/\W/g, "_")}`;
121
+ const clearStatus = (surfaceId) => {
122
+ const entry = statused.get(surfaceId);
123
+ if (!entry)
124
+ return;
125
+ statused.delete(surfaceId);
126
+ client.command(`clear_status ${entry.key} --tab=${entry.workspaceId}`).catch((error) => {
127
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.shepherd_cmux_status_error", message: "could not clear a Shepherd status", meta: { error: error.message } });
128
+ });
129
+ };
130
+ async function surfaces() {
131
+ const tree = await client.call("system.tree", { all_windows: true });
132
+ const entries = list(tree.windows).flatMap((window) => list(window.workspaces).map((workspace) => ({ window, workspace }))).flatMap(({ window, workspace }) => list(workspace.panes).flatMap((pane) => list(pane.surfaces)).map((surface) => ({
133
+ id: str(surface.id) ?? "",
134
+ ref: str(surface.ref) ?? "",
135
+ workspace: str(workspace.ref),
136
+ workspaceTitle: str(workspace.title),
137
+ workspaceId: str(workspace.id) ?? "",
138
+ title: str(surface.title) ?? "",
139
+ tty: str(surface.tty),
140
+ type: str(surface.type) ?? "",
141
+ agent: hooked.get(str(surface.id) ?? "")?.agent ?? null,
142
+ cwd: hooked.get(str(surface.id) ?? "")?.cwd ?? null,
143
+ // The human's terminal: the focused surface of the selected workspace in a visible window.
144
+ focused: surface.focused === true && workspace.selected === true && window.visible !== false,
145
+ })));
146
+ const identities = await (options.identifyTerminals ?? terminal_process_1.identifyTerminalProcesses)(entries.filter((entry) => entry.type === "terminal" && entry.tty).map((entry) => entry.tty));
147
+ return entries.map((entry) => {
148
+ const identity = entry.tty ? identities.get(entry.tty) : undefined;
149
+ return { ...entry, agent: identity?.agent ?? entry.agent, cwd: identity?.cwd ?? entry.cwd };
150
+ });
151
+ }
152
+ async function locate(sessionId) {
153
+ const surface = (await surfaces()).find((entry) => entry.id === sessionId || entry.ref === sessionId);
154
+ if (!surface)
155
+ throw new Error(`no cmux terminal ${sessionId}`);
156
+ return surface;
157
+ }
158
+ async function read(sessionId, lines) {
159
+ const result = await client.call("surface.read_text", { surface_id: sessionId, lines, scrollback: true });
160
+ return typeof result.text === "string" ? result.text : "";
161
+ }
162
+ return {
163
+ name: "cmux",
164
+ async list() {
165
+ return (await surfaces()).filter((surface) => surface.type === "terminal").map(({ workspaceId: _workspaceId, type: _type, ...session }) => session);
166
+ },
167
+ read,
168
+ async prompt(sessionId, line) {
169
+ const surface = await locate(sessionId);
170
+ const target = { workspace_id: surface.workspaceId, surface_id: surface.id };
171
+ // A paste lands as one block, so no character of it is read as a keystroke; Enter follows on its own.
172
+ await client.call("terminal.paste", { ...target, text: line, submit_key: "none" });
173
+ await new Promise((resolve) => schedule(() => resolve(undefined), SUBMIT_DELAY_MS));
174
+ await client.call("surface.send_key", { ...target, key: "enter" });
175
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_cmux_prompted", message: "typed a line into a cmux terminal", meta: { chars: line.length } });
176
+ },
177
+ async key(sessionId, key) {
178
+ const surface = await locate(sessionId);
179
+ const target = { workspace_id: surface.workspaceId, surface_id: surface.id };
180
+ const named = NAMED_KEYS[key];
181
+ if (named)
182
+ await client.call("surface.send_key", { ...target, key: named });
183
+ else
184
+ await client.call("surface.send_text", { ...target, text: key });
185
+ },
186
+ async signal(sessionId, status, notification) {
187
+ const surface = await locate(sessionId);
188
+ const key = statusKey(surface);
189
+ await client.command(status
190
+ ? `set_status ${key} ${socketQuote(status)} --tab=${surface.workspaceId} --panel=${surface.id}`
191
+ : `clear_status ${key} --tab=${surface.workspaceId}`);
192
+ if (status)
193
+ statused.set(surface.id, { key, workspaceId: surface.workspaceId });
194
+ else
195
+ statused.delete(surface.id);
196
+ if (notification)
197
+ await client.call("notification.create", { title: notification.title, subtitle: "", body: notification.body, workspace_id: surface.workspaceId });
198
+ },
199
+ pace(sessionId, slower) {
200
+ if (slower)
201
+ quietMs.set(sessionId, Math.min((quietMs.get(sessionId) ?? exports.QUIET_MS) * 2, exports.QUIET_MAX_MS));
202
+ else
203
+ quietMs.delete(sessionId);
204
+ },
205
+ watch(handlers) {
206
+ let closed = false;
207
+ let cursor = null;
208
+ let attempt = 0;
209
+ let stream = null;
210
+ let cancelReconnect = null;
211
+ let cancelPoll = null;
212
+ const pending = new Map();
213
+ const screens = new Map();
214
+ const forget = (surfaceId) => {
215
+ hooked.delete(surfaceId);
216
+ for (const [session, surface] of sessionSurface)
217
+ if (surface === surfaceId)
218
+ sessionSurface.delete(session);
219
+ };
220
+ const cancelPending = (surfaceId) => {
221
+ pending.get(surfaceId)?.();
222
+ pending.delete(surfaceId);
223
+ };
224
+ /** A stop becomes a return only if nothing resumed it within the grace period; background work earns it a longer wait. */
225
+ const stopped = (surfaceId, transitionId, agent, sessionId, cwd, waited = false) => {
226
+ cancelPending(surfaceId);
227
+ pending.set(surfaceId, schedule(() => {
228
+ pending.delete(surfaceId);
229
+ const session = sessionId ? readCmuxHookSession(homeDir, agent, sessionId) : null;
230
+ const backgroundWork = session?.hadPendingBackgroundWorkAtStop === true || session?.agentLifecycle === "backgroundWorkPending" || session?.agentLifecycle === "running";
231
+ if (backgroundWork && !waited) {
232
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_stop_deferred", message: "a cmux stop left background work running; waiting longer", meta: { agent } });
233
+ return stopped(surfaceId, transitionId, agent, sessionId, cwd, true);
234
+ }
235
+ handlers.returned({ sessionId: surfaceId, transitionId, agent, cwd: str(session?.cwd) ?? cwd, lastBody: str(session?.lastBody), backgroundWork });
236
+ }, waited ? exports.BACKGROUND_GRACE_MS : exports.GRACE_MS));
237
+ };
238
+ const onEvent = (frame) => {
239
+ const name = str(frame.name) ?? "";
240
+ const payload = isRecord(frame.payload) ? frame.payload : {};
241
+ const surfaceId = str(payload.surface_id) ?? str(frame.surface_id);
242
+ if (name === "surface.focused" && surfaceId) {
243
+ quietMs.delete(surfaceId);
244
+ return handlers.focused(surfaceId);
245
+ }
246
+ if (name === "surface.closed" && surfaceId) {
247
+ cancelPending(surfaceId);
248
+ forget(surfaceId);
249
+ screens.delete(surfaceId);
250
+ statused.delete(surfaceId);
251
+ return;
252
+ }
253
+ if (!name.startsWith("agent.hook.") || (payload.phase !== undefined && payload.phase !== "received"))
254
+ return;
255
+ const hook = name.slice("agent.hook.".length);
256
+ const sessionId = str(payload.session_id);
257
+ if (sessionId && surfaceId)
258
+ sessionSurface.set(sessionId, surfaceId);
259
+ const surface = surfaceId ?? (sessionId ? sessionSurface.get(sessionId) : undefined);
260
+ if (!surface)
261
+ return;
262
+ const agent = str(payload._source) ?? str(frame.source) ?? "unknown";
263
+ const cwd = str(payload.cwd);
264
+ const neutral = NEUTRAL_HOOKS.has(hook);
265
+ // An idle agent's return came from its stop; the quiet-screen poll leaves it alone until it works again.
266
+ hooked.set(surface, { agent, cwd, sessionId, idle: IDLE_HOOKS.has(hook) || (neutral && hooked.get(surface)?.idle === true) });
267
+ if (STOP_HOOKS.has(hook))
268
+ return stopped(surface, `cmux:${String(frame.boot_id)}:${String(frame.seq)}`, agent, sessionId, cwd);
269
+ if (neutral || hook === "SessionStart")
270
+ return;
271
+ // The agent is working again: no pending stop, no stale status, and its quiet screen is checked at the normal pace.
272
+ cancelPending(surface);
273
+ clearStatus(surface);
274
+ quietMs.delete(surface);
275
+ // An agent that exited leaves a plain terminal, which the quiet-screen fallback watches again.
276
+ if (hook === "SessionEnd")
277
+ forget(surface);
278
+ };
279
+ const connect = () => {
280
+ cancelReconnect = null;
281
+ stream = client.stream({ ...(cursor !== null ? { after_seq: cursor } : {}), categories: ["agent", "surface"], include_heartbeats: false }, {
282
+ onFrame: (frame) => {
283
+ if (frame.type === "ack") {
284
+ attempt = 0;
285
+ const resume = isRecord(frame.resume) ? frame.resume : {};
286
+ // A first connection, a restart or a gap starts from cmux's latest event: old stops are not replayed as new returns.
287
+ if (cursor === null || resume.gap === true)
288
+ cursor = typeof resume.latest_seq === "number" ? resume.latest_seq : cursor;
289
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_cmux_connected", message: "cmux event stream connected", meta: { gap: resume.gap === true } });
290
+ return;
291
+ }
292
+ if (frame.type !== "event" || typeof frame.seq !== "number" || (cursor !== null && frame.seq <= cursor))
293
+ return;
294
+ cursor = frame.seq;
295
+ onEvent(frame);
296
+ },
297
+ onClose: (error) => {
298
+ stream = null;
299
+ if (closed)
300
+ return;
301
+ const delay = RECONNECT_DELAYS_MS[Math.min(attempt, RECONNECT_DELAYS_MS.length - 1)];
302
+ attempt += 1;
303
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.shepherd_cmux_closed", message: "cmux event stream closed; reconnecting", meta: { delay, error: error?.message ?? null } });
304
+ cancelReconnect = schedule(connect, delay);
305
+ },
306
+ });
307
+ };
308
+ /** Terminals whose agent is not idle: output that changed and then held still for the quiet window is a return. */
309
+ const poll = async () => {
310
+ try {
311
+ const terminals = (await surfaces()).filter((surface) => surface.type === "terminal" && hooked.get(surface.id)?.idle !== true);
312
+ const seen = new Set(terminals.map((surface) => surface.id));
313
+ for (const id of screens.keys())
314
+ if (!seen.has(id))
315
+ screens.delete(id);
316
+ for (const surface of terminals) {
317
+ const hash = (0, node_crypto_1.createHash)("sha256").update(await read(surface.id, POLL_LINES)).digest("hex");
318
+ const last = screens.get(surface.id);
319
+ const at = now();
320
+ if (!last)
321
+ screens.set(surface.id, { hash, changedAt: at, active: false });
322
+ else if (last.hash !== hash) {
323
+ screens.set(surface.id, { hash, changedAt: at, active: true });
324
+ clearStatus(surface.id);
325
+ }
326
+ else if (last.active && at - last.changedAt >= Math.max(quietMs.get(surface.id) ?? exports.QUIET_MS, hooked.has(surface.id) ? exports.HOOKED_QUIET_MS : 0)) {
327
+ last.active = false;
328
+ handlers.returned({ sessionId: surface.id, transitionId: `cmux:quiet:${surface.id}:${last.changedAt}`, agent: surface.agent, cwd: surface.cwd ?? null, title: surface.title, workspaceTitle: surface.workspaceTitle, lastBody: null, backgroundWork: null });
329
+ }
330
+ }
331
+ }
332
+ catch (error) {
333
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.shepherd_cmux_poll_error", message: "could not poll cmux terminals; the next poll retries", meta: { error: error.message } });
334
+ }
335
+ if (!closed)
336
+ cancelPoll = schedule(() => void poll(), exports.POLL_MS);
337
+ };
338
+ connect();
339
+ void poll();
340
+ return {
341
+ close() {
342
+ closed = true;
343
+ cancelReconnect?.();
344
+ cancelPoll?.();
345
+ for (const cancel of pending.values())
346
+ cancel();
347
+ stream?.close();
348
+ },
349
+ };
350
+ },
351
+ };
352
+ }