@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831

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 (647) 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 +5308 -16
  16. package/deploy/unraid/Dockerfile +54 -0
  17. package/deploy/unraid/README.txt +2983 -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-deployment-target.mjs +710 -0
  34. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  35. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  36. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  37. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  38. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  39. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  40. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  41. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  42. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
  43. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
  49. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  50. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
  51. package/deploy/unraid/sanctuary.xml +28 -0
  52. package/dist/a2a/card.js +57 -0
  53. package/dist/a2a/client.js +180 -0
  54. package/dist/a2a/config.js +50 -0
  55. package/dist/a2a/delegation-stores.js +56 -0
  56. package/dist/a2a/did-resolution.js +93 -0
  57. package/dist/a2a/identity.js +170 -0
  58. package/dist/a2a/inbound-share.js +107 -0
  59. package/dist/a2a/mission-result-wire.js +196 -0
  60. package/dist/a2a/onboarding.js +115 -0
  61. package/dist/a2a/pin-store.js +132 -0
  62. package/dist/a2a/seen-ledger.js +120 -0
  63. package/dist/a2a/server.js +604 -0
  64. package/dist/a2a/task-store.js +69 -0
  65. package/dist/a2a/transport.js +45 -0
  66. package/dist/a2a/types.js +3 -0
  67. package/dist/arc/attention-types.js +8 -0
  68. package/dist/arc/cares.js +360 -0
  69. package/dist/arc/episodes.js +118 -0
  70. package/dist/arc/evolution.js +490 -0
  71. package/dist/arc/flight-recorder.js +1034 -0
  72. package/dist/arc/intentions.js +134 -0
  73. package/dist/arc/json-store.js +117 -0
  74. package/dist/arc/obligations.js +386 -0
  75. package/dist/arc/packets.js +336 -0
  76. package/dist/arc/presence.js +185 -0
  77. package/dist/arc/task-lifecycle.js +57 -0
  78. package/dist/commerce/store.js +755 -0
  79. package/dist/commerce/types.js +3 -0
  80. package/dist/heart/active-work.js +798 -40
  81. package/dist/heart/agent-entry.js +252 -3
  82. package/dist/heart/approval-files.js +113 -0
  83. package/dist/heart/approval-store.js +960 -0
  84. package/dist/heart/attachments/image-normalize.js +194 -0
  85. package/dist/heart/attachments/materialize.js +97 -0
  86. package/dist/heart/attachments/originals.js +88 -0
  87. package/dist/heart/attachments/render.js +29 -0
  88. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  89. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  90. package/dist/heart/attachments/sources/index.js +18 -0
  91. package/dist/heart/attachments/sources/telegram.js +71 -0
  92. package/dist/heart/attachments/store.js +132 -0
  93. package/dist/heart/attachments/types.js +93 -0
  94. package/dist/heart/auth/auth-flow.js +495 -0
  95. package/dist/heart/autonomy-budget.js +478 -0
  96. package/dist/heart/awaiting/await-alert.js +148 -0
  97. package/dist/heart/awaiting/await-expiry.js +143 -0
  98. package/dist/heart/awaiting/await-loader.js +91 -0
  99. package/dist/heart/awaiting/await-parser.js +149 -0
  100. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  101. package/dist/heart/awaiting/await-scheduler.js +382 -0
  102. package/dist/heart/background-operations.js +281 -0
  103. package/dist/heart/bridges/manager.js +137 -17
  104. package/dist/heart/bridges/store.js +14 -2
  105. package/dist/heart/bundle-state.js +168 -0
  106. package/dist/heart/commitments.js +44 -18
  107. package/dist/heart/config-registry.js +331 -0
  108. package/dist/heart/config.js +174 -131
  109. package/dist/heart/context-loss-gauntlet.js +387 -0
  110. package/dist/heart/context-loss-sentinel.js +1157 -0
  111. package/dist/heart/core.js +2169 -581
  112. package/dist/heart/cross-chat-delivery.js +9 -22
  113. package/dist/heart/daemon/agent-config-check.js +451 -0
  114. package/dist/heart/daemon/agent-discovery.js +185 -3
  115. package/dist/heart/daemon/agent-service.js +542 -0
  116. package/dist/heart/daemon/agentic-repair.js +547 -0
  117. package/dist/heart/daemon/await-private-wake.js +59 -0
  118. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  119. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  120. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  121. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  122. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  123. package/dist/heart/daemon/cadence.js +180 -0
  124. package/dist/heart/daemon/cli-defaults.js +854 -0
  125. package/dist/heart/daemon/cli-desk.js +322 -0
  126. package/dist/heart/daemon/cli-exec.js +8822 -0
  127. package/dist/heart/daemon/cli-help.js +716 -0
  128. package/dist/heart/daemon/cli-parse.js +2771 -0
  129. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  130. package/dist/heart/daemon/cli-render.js +777 -0
  131. package/dist/heart/daemon/cli-types.js +8 -0
  132. package/dist/heart/daemon/connect-bay.js +323 -0
  133. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  134. package/dist/heart/daemon/container-healthcheck.js +112 -0
  135. package/dist/heart/daemon/container-runtime.js +97 -0
  136. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  137. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  138. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  139. package/dist/heart/daemon/daemon-cli.js +29 -2349
  140. package/dist/heart/daemon/daemon-entry.js +930 -11
  141. package/dist/heart/daemon/daemon-health.js +186 -0
  142. package/dist/heart/daemon/daemon-rollup.js +57 -0
  143. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  144. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  145. package/dist/heart/daemon/daemon.js +2084 -105
  146. package/dist/heart/daemon/dns-workflow.js +394 -0
  147. package/dist/heart/daemon/doctor-types.js +8 -0
  148. package/dist/heart/daemon/doctor.js +1755 -0
  149. package/dist/heart/daemon/freshness.js +345 -0
  150. package/dist/heart/daemon/habit-private-wake.js +61 -0
  151. package/dist/heart/daemon/health-monitor.js +142 -11
  152. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  153. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  154. package/dist/heart/daemon/http-health-probe.js +80 -0
  155. package/dist/heart/daemon/human-command-screens.js +234 -0
  156. package/dist/heart/daemon/human-readiness.js +114 -0
  157. package/dist/heart/daemon/inner-status.js +78 -0
  158. package/dist/heart/daemon/interactive-repair.js +394 -0
  159. package/dist/heart/daemon/launchd.js +37 -8
  160. package/dist/heart/daemon/log-tailer.js +79 -10
  161. package/dist/heart/daemon/logs-prune.js +132 -0
  162. package/dist/heart/daemon/mcp-canary.js +524 -0
  163. package/dist/heart/daemon/message-router.js +65 -5
  164. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  165. package/dist/heart/daemon/os-cron-deps.js +135 -0
  166. package/dist/heart/daemon/os-cron.js +22 -14
  167. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  168. package/dist/heart/daemon/ouro-entry.js +3 -1
  169. package/dist/heart/daemon/plugin-cli.js +432 -0
  170. package/dist/heart/daemon/process-manager.js +733 -61
  171. package/dist/heart/daemon/provider-discovery.js +137 -0
  172. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  173. package/dist/heart/daemon/prunable-bundle.js +144 -0
  174. package/dist/heart/daemon/pulse.js +511 -0
  175. package/dist/heart/daemon/readiness-repair.js +365 -0
  176. package/dist/heart/daemon/run-hooks.js +2 -0
  177. package/dist/heart/daemon/runtime-logging.js +47 -14
  178. package/dist/heart/daemon/runtime-metadata.js +2 -30
  179. package/dist/heart/daemon/runtime-mode.js +13 -2
  180. package/dist/heart/daemon/safe-mode.js +161 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  185. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  186. package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
  187. package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
  188. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  189. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
  190. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  191. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  192. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  193. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
  194. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  195. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  196. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  197. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  198. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  199. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  200. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  201. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  202. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  203. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
  204. package/dist/heart/daemon/sense-manager.js +699 -48
  205. package/dist/heart/daemon/session-id-resolver.js +131 -0
  206. package/dist/heart/daemon/skill-management-installer.js +1 -1
  207. package/dist/heart/daemon/socket-client.js +180 -12
  208. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  209. package/dist/heart/daemon/startup-tui.js +339 -0
  210. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  211. package/dist/heart/daemon/task-scheduler.js +117 -39
  212. package/dist/heart/daemon/terminal-ui.js +499 -0
  213. package/dist/heart/daemon/thoughts.js +138 -54
  214. package/dist/heart/daemon/up-progress.js +366 -0
  215. package/dist/heart/daemon/vault-items.js +56 -0
  216. package/dist/heart/delegation.js +1 -4
  217. package/dist/heart/external-events/router.js +1430 -0
  218. package/dist/heart/frontend-approval-runtime.js +506 -0
  219. package/dist/heart/frontend-journal.js +215 -0
  220. package/dist/heart/frontend-session-service.js +237 -0
  221. package/dist/heart/frontend-socket-client.js +164 -0
  222. package/dist/heart/frontend-socket.js +400 -0
  223. package/dist/heart/habits/habit-cancel.js +810 -0
  224. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  225. package/dist/heart/habits/habit-migration.js +194 -0
  226. package/dist/heart/habits/habit-parser.js +278 -0
  227. package/dist/heart/habits/habit-runtime-state.js +93 -0
  228. package/dist/heart/habits/habit-scheduler.js +653 -0
  229. package/dist/heart/habits/habit-session-summary.js +318 -0
  230. package/dist/heart/habits/habit-session.js +636 -0
  231. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  232. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  233. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  234. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  235. package/dist/heart/identity.js +196 -59
  236. package/dist/heart/kept-notes.js +289 -0
  237. package/dist/heart/kicks.js +1 -1
  238. package/dist/heart/machine-identity.js +161 -0
  239. package/dist/heart/mail-import-discovery.js +356 -0
  240. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  241. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  242. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  243. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  244. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  245. package/dist/heart/mailbox/mailbox-http.js +99 -0
  246. package/dist/heart/mailbox/mailbox-read.js +39 -0
  247. package/dist/heart/mailbox/mailbox-types.js +27 -0
  248. package/dist/heart/mailbox/mailbox-view.js +197 -0
  249. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  250. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  251. package/dist/heart/mailbox/readers/mail.js +375 -0
  252. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  253. package/dist/heart/mailbox/readers/sessions.js +231 -0
  254. package/dist/heart/mailbox/readers/shared.js +111 -0
  255. package/dist/heart/mcp/mcp-server.js +696 -0
  256. package/dist/heart/migrate-config.js +100 -0
  257. package/dist/heart/model-capabilities.js +11 -0
  258. package/dist/heart/orientation-frame.js +345 -0
  259. package/dist/heart/platform.js +81 -0
  260. package/dist/heart/primitives.js +1 -1
  261. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  262. package/dist/heart/private-runtime/index.js +18 -0
  263. package/dist/heart/private-runtime/ledger.js +221 -0
  264. package/dist/heart/private-runtime/policy.js +252 -0
  265. package/dist/heart/private-runtime/types.js +2 -0
  266. package/dist/heart/progress-story.js +1 -1
  267. package/dist/heart/provider-attempt.js +137 -0
  268. package/dist/heart/provider-binding-resolver.js +273 -0
  269. package/dist/heart/provider-credentials.js +449 -0
  270. package/dist/heart/provider-failover.js +311 -0
  271. package/dist/heart/provider-models.js +96 -0
  272. package/dist/heart/provider-ping.js +265 -0
  273. package/dist/heart/provider-readiness-cache.js +119 -0
  274. package/dist/heart/provider-visibility.js +188 -0
  275. package/dist/heart/providers/anthropic-token.js +131 -0
  276. package/dist/heart/providers/anthropic.js +173 -60
  277. package/dist/heart/providers/azure.js +23 -11
  278. package/dist/heart/providers/error-classification.js +127 -0
  279. package/dist/heart/providers/github-copilot.js +34 -38
  280. package/dist/heart/providers/minimax-vlm.js +189 -0
  281. package/dist/heart/providers/minimax.js +26 -8
  282. package/dist/heart/providers/openai-codex-token.js +349 -0
  283. package/dist/heart/providers/openai-codex.js +55 -40
  284. package/dist/heart/providers/openai-compatible.js +177 -0
  285. package/dist/heart/run-ledger.js +247 -0
  286. package/dist/heart/runtime-capability-check.js +170 -0
  287. package/dist/heart/runtime-credentials.js +607 -0
  288. package/dist/heart/runtime-cwd.js +87 -0
  289. package/dist/heart/sense-truth.js +22 -4
  290. package/dist/heart/session-activity.js +92 -24
  291. package/dist/heart/session-events.js +1504 -0
  292. package/dist/heart/session-playback-cli-main.js +5 -0
  293. package/dist/heart/session-playback-cli.js +36 -0
  294. package/dist/heart/session-playback.js +231 -0
  295. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  296. package/dist/heart/session-redaction-repair.js +552 -0
  297. package/dist/heart/session-stats-cli-main.js +5 -0
  298. package/dist/heart/session-stats.js +183 -0
  299. package/dist/heart/session-transcript.js +133 -0
  300. package/dist/heart/start-of-turn-packet.js +372 -0
  301. package/dist/heart/steward-policy.js +618 -0
  302. package/dist/heart/streaming.js +604 -207
  303. package/dist/heart/structured-output.js +196 -0
  304. package/dist/heart/sync-classification.js +176 -0
  305. package/dist/heart/sync.js +449 -0
  306. package/dist/heart/target-resolution.js +11 -7
  307. package/dist/heart/tempo.js +93 -0
  308. package/dist/heart/temporal-view.js +41 -0
  309. package/dist/heart/timeouts.js +101 -0
  310. package/dist/heart/tool-activity-callbacks.js +59 -0
  311. package/dist/heart/tool-approval.js +382 -0
  312. package/dist/heart/tool-description.js +155 -0
  313. package/dist/heart/tool-friction.js +55 -0
  314. package/dist/heart/tool-loop.js +200 -0
  315. package/dist/heart/turn-context.js +482 -0
  316. package/dist/heart/turn-execution-lease.js +30 -0
  317. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  318. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  319. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  320. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  321. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  322. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  323. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  324. package/dist/heart/versioning/update-hooks.js +154 -0
  325. package/dist/heart/versioning/version-intent.js +114 -0
  326. package/dist/heart/work-card.js +380 -0
  327. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  328. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  329. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  330. package/dist/mailbox-ui/index.html +16 -0
  331. package/dist/mailroom/attention.js +167 -0
  332. package/dist/mailroom/autonomy.js +209 -0
  333. package/dist/mailroom/blob-store.js +889 -0
  334. package/dist/mailroom/body-cache.js +61 -0
  335. package/dist/mailroom/cache-sync-cli.js +58 -0
  336. package/dist/mailroom/core.js +803 -0
  337. package/dist/mailroom/entry.js +160 -0
  338. package/dist/mailroom/file-store.js +568 -0
  339. package/dist/mailroom/hosted-cache-sync.js +384 -0
  340. package/dist/mailroom/mbox-import.js +393 -0
  341. package/dist/mailroom/migration.js +164 -0
  342. package/dist/mailroom/outbound.js +380 -0
  343. package/dist/mailroom/policy.js +263 -0
  344. package/dist/mailroom/reader.js +292 -0
  345. package/dist/mailroom/search-cache.js +513 -0
  346. package/dist/mailroom/search-relevance.js +319 -0
  347. package/dist/mailroom/smtp-ingress.js +176 -0
  348. package/dist/mailroom/source-state.js +176 -0
  349. package/dist/mailroom/thread.js +109 -0
  350. package/dist/mailroom/travel-extract.js +89 -0
  351. package/dist/mind/bundle-manifest.js +24 -2
  352. package/dist/mind/context.js +309 -111
  353. package/dist/mind/desk-section.js +362 -0
  354. package/dist/mind/diary-integrity.js +60 -0
  355. package/dist/mind/{memory.js → diary.js} +68 -77
  356. package/dist/mind/embedding-provider.js +60 -0
  357. package/dist/mind/file-state.js +179 -0
  358. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  359. package/dist/mind/obligation-steering.js +199 -3
  360. package/dist/mind/pending.js +36 -10
  361. package/dist/mind/prompt-budget.js +479 -0
  362. package/dist/mind/prompt-refresh.js +3 -2
  363. package/dist/mind/prompt.js +1050 -189
  364. package/dist/mind/provenance-trust.js +26 -0
  365. package/dist/mind/record-paths.js +312 -0
  366. package/dist/mind/scrutiny.js +173 -0
  367. package/dist/mind/session-transaction.js +564 -0
  368. package/dist/nerves/cli-logging.js +7 -1
  369. package/dist/nerves/coverage/audit-rules.js +15 -6
  370. package/dist/nerves/coverage/audit.js +28 -2
  371. package/dist/nerves/coverage/cli.js +1 -1
  372. package/dist/nerves/coverage/contract.js +5 -5
  373. package/dist/nerves/coverage/file-completeness.js +139 -5
  374. package/dist/nerves/coverage/run-artifacts.js +55 -35
  375. package/dist/nerves/coverage/source-scanner.js +4 -4
  376. package/dist/nerves/event-buffer.js +111 -0
  377. package/dist/nerves/index.js +293 -9
  378. package/dist/nerves/observation.js +20 -0
  379. package/dist/nerves/redact.js +79 -0
  380. package/dist/nerves/review/cli-main.js +5 -0
  381. package/dist/nerves/review/cli.js +156 -0
  382. package/dist/nerves/review/core.js +159 -0
  383. package/dist/nerves/runtime.js +17 -1
  384. package/dist/repertoire/ado-client.js +15 -56
  385. package/dist/repertoire/ado-semantic.js +16 -10
  386. package/dist/repertoire/api-client.js +97 -0
  387. package/dist/repertoire/bitwarden-store.js +1045 -0
  388. package/dist/repertoire/bundle-templates.js +71 -0
  389. package/dist/repertoire/bw-installer.js +180 -0
  390. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  391. package/dist/repertoire/coding/context-pack.js +331 -0
  392. package/dist/repertoire/coding/feedback.js +174 -32
  393. package/dist/repertoire/coding/index.js +15 -3
  394. package/dist/repertoire/coding/manager.js +159 -10
  395. package/dist/repertoire/coding/spawner.js +58 -11
  396. package/dist/repertoire/coding/tools.js +221 -15
  397. package/dist/repertoire/coding/workbench-client.js +272 -0
  398. package/dist/repertoire/coding/workbench-manager.js +346 -0
  399. package/dist/repertoire/commerce-errors.js +109 -0
  400. package/dist/repertoire/commerce-self-test.js +156 -0
  401. package/dist/repertoire/credential-access.js +178 -0
  402. package/dist/repertoire/desk/classifier.js +362 -0
  403. package/dist/repertoire/duffel-client.js +185 -0
  404. package/dist/repertoire/github-client.js +14 -55
  405. package/dist/repertoire/graph-client.js +11 -52
  406. package/dist/repertoire/guardrails.js +811 -18
  407. package/dist/repertoire/mcp-client.js +44 -3
  408. package/dist/repertoire/mcp-manager.js +427 -139
  409. package/dist/repertoire/mcp-tools.js +124 -0
  410. package/dist/repertoire/plugin-mcp.js +175 -0
  411. package/dist/repertoire/plugins.js +253 -0
  412. package/dist/repertoire/relationship-authorization.js +322 -0
  413. package/dist/repertoire/shell-sessions.js +134 -0
  414. package/dist/repertoire/skills.js +48 -4
  415. package/dist/repertoire/stripe-client.js +131 -0
  416. package/dist/repertoire/tool-arguments.js +170 -0
  417. package/dist/repertoire/tool-results.js +29 -0
  418. package/dist/repertoire/tools-a2a.js +699 -0
  419. package/dist/repertoire/tools-attachments.js +322 -0
  420. package/dist/repertoire/tools-awaiting.js +575 -0
  421. package/dist/repertoire/tools-base.js +77 -1138
  422. package/dist/repertoire/tools-bluebubbles.js +2 -0
  423. package/dist/repertoire/tools-bridge.js +144 -0
  424. package/dist/repertoire/tools-bundle.js +993 -0
  425. package/dist/repertoire/tools-commerce.js +253 -0
  426. package/dist/repertoire/tools-config.js +186 -0
  427. package/dist/repertoire/tools-continuity.js +575 -0
  428. package/dist/repertoire/tools-credential.js +383 -0
  429. package/dist/repertoire/tools-evolution.js +527 -0
  430. package/dist/repertoire/tools-files.js +344 -0
  431. package/dist/repertoire/tools-flight.js +290 -0
  432. package/dist/repertoire/tools-flow.js +119 -0
  433. package/dist/repertoire/tools-github.js +3 -8
  434. package/dist/repertoire/tools-habits.js +103 -0
  435. package/dist/repertoire/tools-mail.js +1828 -0
  436. package/dist/repertoire/tools-notes.js +485 -0
  437. package/dist/repertoire/tools-obligations.js +182 -0
  438. package/dist/repertoire/tools-orientation.js +31 -0
  439. package/dist/repertoire/tools-record.js +482 -0
  440. package/dist/repertoire/tools-rsvp.js +139 -0
  441. package/dist/repertoire/tools-runtime.js +150 -0
  442. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  443. package/dist/repertoire/tools-session.js +1133 -0
  444. package/dist/repertoire/tools-shell.js +149 -0
  445. package/dist/repertoire/tools-steward-policy.js +119 -0
  446. package/dist/repertoire/tools-stripe.js +224 -0
  447. package/dist/repertoire/tools-surface.js +369 -0
  448. package/dist/repertoire/tools-teams.js +12 -39
  449. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  450. package/dist/repertoire/tools-travel.js +125 -0
  451. package/dist/repertoire/tools-trip.js +982 -0
  452. package/dist/repertoire/tools-unraid.js +531 -0
  453. package/dist/repertoire/tools-user-profile.js +146 -0
  454. package/dist/repertoire/tools-vault.js +40 -0
  455. package/dist/repertoire/tools-voice.js +145 -0
  456. package/dist/repertoire/tools.js +494 -148
  457. package/dist/repertoire/travel-api-client.js +360 -0
  458. package/dist/repertoire/unraid-client.js +155 -0
  459. package/dist/repertoire/unraid-restart.js +339 -0
  460. package/dist/repertoire/user-profile.js +131 -0
  461. package/dist/repertoire/vault-setup.js +246 -0
  462. package/dist/repertoire/vault-unlock.js +628 -0
  463. package/dist/rsvp/aisleplanner-client.js +354 -0
  464. package/dist/rsvp/cli.js +926 -0
  465. package/dist/rsvp/config.js +327 -0
  466. package/dist/rsvp/cutover.js +433 -0
  467. package/dist/rsvp/diagnostics.js +232 -0
  468. package/dist/rsvp/diff-renderer.js +176 -0
  469. package/dist/rsvp/habit-policy.js +110 -0
  470. package/dist/rsvp/habit-stage.js +123 -0
  471. package/dist/rsvp/incident-bundle.js +97 -0
  472. package/dist/rsvp/migration.js +204 -0
  473. package/dist/rsvp/native-habit-runner.js +630 -0
  474. package/dist/rsvp/outbound-state.js +628 -0
  475. package/dist/rsvp/query.js +118 -0
  476. package/dist/rsvp/replay.js +233 -0
  477. package/dist/rsvp/snapshot.js +232 -0
  478. package/dist/rsvp/spend-ledger.js +175 -0
  479. package/dist/scripts/claude-code-hook.js +41 -0
  480. package/dist/scripts/claude-code-stop-hook.js +47 -0
  481. package/dist/senses/a2a-entry.js +115 -0
  482. package/dist/senses/acp-server.js +386 -0
  483. package/dist/senses/attention-queue.js +186 -0
  484. package/dist/senses/await-turn-message.js +58 -0
  485. package/dist/senses/bluebubbles/active-turns.js +216 -0
  486. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  487. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  488. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  489. package/dist/senses/bluebubbles/context-packet.js +207 -0
  490. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  491. package/dist/senses/bluebubbles/entry.js +90 -0
  492. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  493. package/dist/senses/bluebubbles/index.js +3841 -0
  494. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  495. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  496. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  497. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  498. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  499. package/dist/senses/bluebubbles/processed-log.js +133 -0
  500. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  501. package/dist/senses/bluebubbles/replay.js +284 -0
  502. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  503. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  504. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  505. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  506. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  507. package/dist/senses/cli/bracketed-paste.js +82 -0
  508. package/dist/senses/cli/image-paste.js +287 -0
  509. package/dist/senses/cli/image-ref-navigation.js +75 -0
  510. package/dist/senses/cli/ink-app.js +156 -0
  511. package/dist/senses/cli/inline-diff.js +64 -0
  512. package/dist/senses/cli/input-keys.js +174 -0
  513. package/dist/senses/cli/kill-ring.js +86 -0
  514. package/dist/senses/cli/message-list.js +51 -0
  515. package/dist/senses/cli/ouro-tui.js +607 -0
  516. package/dist/senses/cli/spinner-imperative.js +135 -0
  517. package/dist/senses/cli/spinner.js +101 -0
  518. package/dist/senses/cli/status-line.js +60 -0
  519. package/dist/senses/cli/streaming-markdown.js +526 -0
  520. package/dist/senses/cli/tool-display.js +85 -0
  521. package/dist/senses/cli/tool-render.js +85 -0
  522. package/dist/senses/cli/tui-store.js +241 -0
  523. package/dist/senses/cli/virtual-list.js +35 -0
  524. package/dist/senses/cli-entry.js +60 -8
  525. package/dist/senses/cli.js +604 -320
  526. package/dist/senses/commands.js +66 -3
  527. package/dist/senses/context-packet-ledger.js +371 -0
  528. package/dist/senses/context-packets.js +154 -0
  529. package/dist/senses/habit-lifecycle-guard.js +24 -0
  530. package/dist/senses/habit-turn-message.js +160 -0
  531. package/dist/senses/ingress-evidence.js +2 -0
  532. package/dist/senses/mail-entry.js +66 -0
  533. package/dist/senses/mail.js +524 -0
  534. package/dist/senses/pipeline.js +1115 -204
  535. package/dist/senses/private-runtime-worker.js +859 -0
  536. package/dist/senses/private-runtime.js +1517 -0
  537. package/dist/senses/proactive-content-guard.js +51 -0
  538. package/dist/senses/root-host-approval-port.js +345 -0
  539. package/dist/senses/root-host-approval-runtime.js +393 -0
  540. package/dist/senses/sanctuary-authority-resident.js +102 -0
  541. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  542. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  543. package/dist/senses/sanctuary-grounding.js +118 -0
  544. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  545. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  546. package/dist/senses/sanctuary-health-runner.js +100 -0
  547. package/dist/senses/sanctuary-health.js +408 -0
  548. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  549. package/dist/senses/sanctuary-interactive-control.js +410 -0
  550. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  551. package/dist/senses/sanctuary-media-optimization.js +514 -0
  552. package/dist/senses/sanctuary-runtime.js +340 -0
  553. package/dist/senses/sanctuary-sab.js +85 -0
  554. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  555. package/dist/senses/shared-turn.js +772 -0
  556. package/dist/senses/surface-tool.js +109 -0
  557. package/dist/senses/teams-entry.js +60 -8
  558. package/dist/senses/teams.js +519 -218
  559. package/dist/senses/telegram-admission.js +718 -0
  560. package/dist/senses/telegram-approval-runtime.js +793 -0
  561. package/dist/senses/telegram-attachments.js +186 -0
  562. package/dist/senses/telegram-audit-ledger.js +220 -0
  563. package/dist/senses/telegram-authority-transport.js +231 -0
  564. package/dist/senses/telegram-client.js +1749 -0
  565. package/dist/senses/telegram-effect-adapter.js +896 -0
  566. package/dist/senses/telegram-entry.js +83 -0
  567. package/dist/senses/telegram.js +2324 -0
  568. package/dist/senses/trust-gate.js +104 -9
  569. package/dist/senses/voice/audio-playback.js +237 -0
  570. package/dist/senses/voice/audio-routing.js +119 -0
  571. package/dist/senses/voice/elevenlabs.js +202 -0
  572. package/dist/senses/voice/floor-control.js +431 -0
  573. package/dist/senses/voice/floor-controller.js +115 -0
  574. package/dist/senses/voice/golden-path.js +116 -0
  575. package/dist/senses/voice/index.js +29 -0
  576. package/dist/senses/voice/meeting.js +113 -0
  577. package/dist/senses/voice/outbound.js +190 -0
  578. package/dist/senses/voice/phone.js +33 -0
  579. package/dist/senses/voice/playback.js +139 -0
  580. package/dist/senses/voice/realtime-eval.js +496 -0
  581. package/dist/senses/voice/realtime-trace.js +531 -0
  582. package/dist/senses/voice/transcript.js +70 -0
  583. package/dist/senses/voice/turn.js +191 -0
  584. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  585. package/dist/senses/voice/twilio-phone.js +5031 -0
  586. package/dist/senses/voice/types.js +2 -0
  587. package/dist/senses/voice/whisper.js +161 -0
  588. package/dist/senses/voice-entry.js +81 -0
  589. package/dist/senses/voice-realtime-eval-command.js +99 -0
  590. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  591. package/dist/senses/voice-twilio-entry.js +87 -0
  592. package/dist/trips/core.js +138 -0
  593. package/dist/trips/store.js +265 -0
  594. package/dist/util/frontmatter.js +69 -0
  595. package/npm-shrinkwrap.json +8138 -0
  596. package/package.json +72 -13
  597. package/skills/agent-commerce.md +113 -0
  598. package/skills/browser-navigation.md +117 -0
  599. package/skills/commerce-setup-guide.md +116 -0
  600. package/skills/commerce-setup.md +84 -0
  601. package/skills/configure-dev-tools.md +99 -0
  602. package/skills/travel-planning.md +138 -0
  603. package/dist/heart/daemon/auth-flow.js +0 -430
  604. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  605. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  606. package/dist/heart/daemon/update-hooks.js +0 -138
  607. package/dist/heart/obligations.js +0 -191
  608. package/dist/heart/safe-workspace.js +0 -228
  609. package/dist/heart/session-recall.js +0 -116
  610. package/dist/mind/friends/channel.js +0 -84
  611. package/dist/mind/friends/group-context.js +0 -144
  612. package/dist/mind/friends/resolver.js +0 -84
  613. package/dist/mind/friends/store-file.js +0 -190
  614. package/dist/mind/friends/store.js +0 -4
  615. package/dist/mind/friends/tokens.js +0 -26
  616. package/dist/mind/friends/trust-explanation.js +0 -74
  617. package/dist/mind/friends/types.js +0 -29
  618. package/dist/repertoire/tasks/board.js +0 -134
  619. package/dist/repertoire/tasks/index.js +0 -224
  620. package/dist/repertoire/tasks/lifecycle.js +0 -80
  621. package/dist/repertoire/tasks/middleware.js +0 -65
  622. package/dist/repertoire/tasks/parser.js +0 -173
  623. package/dist/repertoire/tasks/scanner.js +0 -132
  624. package/dist/repertoire/tasks/transitions.js +0 -144
  625. package/dist/senses/bluebubbles-entry.js +0 -13
  626. package/dist/senses/bluebubbles.js +0 -1181
  627. package/dist/senses/debug-activity.js +0 -154
  628. package/dist/senses/inner-dialog-worker.js +0 -90
  629. package/dist/senses/inner-dialog.js +0 -525
  630. package/subagents/README.md +0 -7
  631. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  632. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  633. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  643. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  644. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  645. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  646. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  647. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -1,12 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatOtherActiveSessionSummaries = formatOtherActiveSessionSummaries;
3
4
  exports.suggestBridgeForActiveWork = suggestBridgeForActiveWork;
4
5
  exports.buildActiveWorkFrame = buildActiveWorkFrame;
5
6
  exports.formatActiveWorkFrame = formatActiveWorkFrame;
7
+ exports.formatLiveWorldStateCheckpoint = formatLiveWorldStateCheckpoint;
8
+ exports.snapshotActiveWork = snapshotActiveWork;
9
+ exports.detectActiveWorkChanges = detectActiveWorkChanges;
10
+ exports.formatActiveWorkChanges = formatActiveWorkChanges;
6
11
  const runtime_1 = require("../nerves/runtime");
7
12
  const state_machine_1 = require("./bridges/state-machine");
8
- const obligations_1 = require("./obligations");
13
+ const obligations_1 = require("../arc/obligations");
14
+ const session_activity_1 = require("./session-activity");
9
15
  const target_resolution_1 = require("./target-resolution");
16
+ const config_1 = require("./config");
17
+ const orientation_frame_1 = require("./orientation-frame");
18
+ const RECENT_ACTIVE_OBLIGATION_WINDOW_MS = 60 * 60 * 1000;
10
19
  function activityPriority(source) {
11
20
  return source === "friend-facing" ? 0 : 1;
12
21
  }
@@ -16,25 +25,93 @@ function compareActivity(a, b) {
16
25
  return sourceDiff;
17
26
  return b.lastActivityMs - a.lastActivityMs;
18
27
  }
19
- function summarizeLiveTasks(taskBoard) {
20
- const live = [
21
- ...taskBoard.byStatus.processing,
22
- ...taskBoard.byStatus.validating,
23
- ...taskBoard.byStatus.collaborating,
24
- ];
25
- return [...new Set(live)];
26
- }
27
28
  function isActiveBridge(bridge) {
28
29
  return bridge.lifecycle === "active";
29
30
  }
30
31
  function hasSharedObligationPressure(input) {
31
- return (typeof input.currentObligation === "string"
32
- && input.currentObligation.trim().length > 0) || input.mustResolveBeforeHandoff
33
- || summarizeLiveTasks(input.taskBoard).length > 0;
32
+ return input.mustResolveBeforeHandoff
33
+ || activeObligationCount(input.pendingObligations) > 0;
34
+ }
35
+ function formatCodingLaneLabel(session) {
36
+ return `${session.runner} ${session.id}`;
37
+ }
38
+ function compactCodingCheckpoint(session) {
39
+ const checkpoint = session.checkpoint?.replace(/\s+/g, " ").trim();
40
+ if (!checkpoint)
41
+ return "";
42
+ return checkpoint.length <= 80 ? checkpoint : `${checkpoint.slice(0, 77)}...`;
43
+ }
44
+ function describeCodingSessionScope(session, currentSession) {
45
+ if (!session.originSession)
46
+ return "";
47
+ if (currentSession
48
+ && session.originSession.friendId === currentSession.friendId
49
+ && session.originSession.channel === currentSession.channel
50
+ && session.originSession.key === currentSession.key) {
51
+ return " for this thread";
52
+ }
53
+ return ` for ${session.originSession.channel}/${session.originSession.key}`;
34
54
  }
35
55
  function activeObligationCount(obligations) {
36
56
  return (obligations ?? []).filter((ob) => (0, obligations_1.isOpenObligationStatus)(ob.status)).length;
37
57
  }
58
+ const TERMINAL_EVOLUTION_CASE_STATUSES = new Set(["closed", "blocked", "deferred"]);
59
+ function liveEvolutionCases(cases) {
60
+ return (cases ?? []).filter((evolutionCase) => !TERMINAL_EVOLUTION_CASE_STATUSES.has(evolutionCase.status));
61
+ }
62
+ function formatEvolutionCaseLine(evolutionCase) {
63
+ return `- [${evolutionCase.status}] ${evolutionCase.id}: ${evolutionCase.title}; next: ${evolutionCase.nextAction}; budget: ${evolutionCase.budgetProfile}`;
64
+ }
65
+ function formatEvolutionCheckpointLine(cases) {
66
+ const [currentCase, ...otherCases] = cases;
67
+ if (!currentCase)
68
+ return null;
69
+ const suffix = otherCases.length > 0 ? ` (${otherCases.length + 1} open cases)` : "";
70
+ return `- evolution case: [${currentCase.status}] ${currentCase.id} ${currentCase.title}; next ${currentCase.nextAction}${suffix}`;
71
+ }
72
+ function obligationOriginKey(obligation) {
73
+ return `${obligation.origin.friendId}/${obligation.origin.channel}/${(0, config_1.sanitizeKey)(obligation.origin.key)}`;
74
+ }
75
+ function buildLiveCodingLabelSet(codingSessions, otherCodingSessions) {
76
+ return new Set([
77
+ ...codingSessions.map(formatCodingLaneLabel),
78
+ ...otherCodingSessions.map(formatCodingLaneLabel),
79
+ ]);
80
+ }
81
+ function isMaterialActiveObligation(obligation, liveCodingLabels, nowMs) {
82
+ if (obligation.currentArtifact?.trim())
83
+ return true;
84
+ if (obligation.status === "waiting_for_merge" || obligation.status === "updating_runtime")
85
+ return true;
86
+ const surface = obligation.currentSurface;
87
+ if (surface?.kind === "merge" || surface?.kind === "runtime")
88
+ return true;
89
+ const recentlyTouched = (nowMs - obligationTimestampMs(obligation)) <= RECENT_ACTIVE_OBLIGATION_WINDOW_MS;
90
+ if (surface?.kind === "coding") {
91
+ const liveLabel = surface.label.trim();
92
+ return (liveLabel.length > 0 && liveCodingLabels.has(liveLabel)) || recentlyTouched;
93
+ }
94
+ return recentlyTouched;
95
+ }
96
+ function normalizePendingObligations(obligations, codingSessions, otherCodingSessions) {
97
+ const openObligations = (obligations ?? []).filter((obligation) => (0, obligations_1.isOpenObligationStatus)(obligation.status));
98
+ if (openObligations.length === 0)
99
+ return [];
100
+ const liveCodingLabels = buildLiveCodingLabelSet(codingSessions, otherCodingSessions);
101
+ const nowMs = Date.now();
102
+ const normalized = [];
103
+ const seenOrigins = new Set();
104
+ for (const obligation of [...openObligations].sort(newestObligationFirst)) {
105
+ if (!isMaterialActiveObligation(obligation, liveCodingLabels, nowMs))
106
+ continue;
107
+ const originKey = obligationOriginKey(obligation);
108
+ if (seenOrigins.has(originKey))
109
+ continue;
110
+ seenOrigins.add(originKey);
111
+ normalized.push(obligation);
112
+ }
113
+ return normalized;
114
+ }
38
115
  function formatObligationSurface(obligation) {
39
116
  if (!obligation.currentSurface?.label)
40
117
  return "";
@@ -49,6 +126,401 @@ function formatObligationSurface(obligation) {
49
126
  return ` (${obligation.currentSurface.label})`;
50
127
  }
51
128
  }
129
+ function mergeArtifactFallback(obligation) {
130
+ const trimmed = obligation.content.trim();
131
+ if (!trimmed)
132
+ return "the fix";
133
+ const stripped = trimmed.replace(/^merge(?:\s+|$)/i, "").trim();
134
+ return stripped || "the fix";
135
+ }
136
+ function formatMergeArtifact(obligation) {
137
+ const currentArtifact = obligation.currentArtifact?.trim();
138
+ if (currentArtifact)
139
+ return currentArtifact;
140
+ if (obligation.currentSurface?.kind === "merge") {
141
+ const surfaceLabel = obligation.currentSurface.label.trim();
142
+ if (surfaceLabel)
143
+ return surfaceLabel;
144
+ }
145
+ return mergeArtifactFallback(obligation);
146
+ }
147
+ /* v8 ignore start -- Epic 1: obligation selection, resume handles, change detection @preserve */
148
+ function obligationStatusPriority(status) {
149
+ switch (status) {
150
+ case "investigating": return 0;
151
+ case "waiting_for_merge": return 1;
152
+ case "updating_runtime": return 2;
153
+ case "pending": return 3;
154
+ case "fulfilled": return 4;
155
+ }
156
+ }
157
+ function selectPrimaryObligation(obligations, currentSession) {
158
+ const open = obligations.filter(obligations_1.isOpenObligation);
159
+ if (open.length === 0)
160
+ return null;
161
+ // Prefer current-session match among advanced (non-pending) obligations
162
+ const sessionMatch = currentSession
163
+ ? open.find((ob) => ob.status !== "pending"
164
+ && ob.origin.friendId === currentSession.friendId
165
+ && ob.origin.channel === currentSession.channel
166
+ && (0, config_1.sanitizeKey)(ob.origin.key) === (0, config_1.sanitizeKey)(currentSession.key))
167
+ : null;
168
+ if (sessionMatch)
169
+ return sessionMatch;
170
+ // Then any advanced obligation, sorted by status priority then freshness
171
+ const sorted = [...open].sort((a, b) => {
172
+ const statusDiff = obligationStatusPriority(a.status) - obligationStatusPriority(b.status);
173
+ if (statusDiff !== 0)
174
+ return statusDiff;
175
+ return obligationTimestampMs(b) - obligationTimestampMs(a);
176
+ });
177
+ return sorted[0] ?? null;
178
+ }
179
+ function findPrimaryOpenObligation(frame) {
180
+ return frame.primaryObligation ?? selectPrimaryObligation(frame.pendingObligations ?? [], frame.currentSession);
181
+ }
182
+ function matchesCurrentSession(frame, obligation) {
183
+ return Boolean(frame.currentSession
184
+ && obligation.origin.friendId === frame.currentSession.friendId
185
+ && obligation.origin.channel === frame.currentSession.channel
186
+ && (0, config_1.sanitizeKey)(obligation.origin.key) === (0, config_1.sanitizeKey)(frame.currentSession.key));
187
+ }
188
+ function findCurrentSessionOpenObligation(frame) {
189
+ return (frame.pendingObligations ?? []).find((obligation) => (0, obligations_1.isOpenObligationStatus)(obligation.status) && matchesCurrentSession(frame, obligation))
190
+ ?? null;
191
+ }
192
+ function formatActiveLane(frame, obligation) {
193
+ const liveCodingSession = frame.codingSessions?.[0];
194
+ if (liveCodingSession) {
195
+ return `${formatCodingLaneLabel(liveCodingSession)}${describeCodingSessionScope(liveCodingSession, frame.currentSession)}`;
196
+ }
197
+ if (obligation?.currentSurface?.label) {
198
+ return obligation.currentSurface.label;
199
+ }
200
+ if (obligation && matchesCurrentSession(frame, obligation) && frame.currentSession) {
201
+ return "this same thread";
202
+ }
203
+ if (frame.inner?.job?.status === "running") {
204
+ return "private runtime";
205
+ }
206
+ return null;
207
+ }
208
+ function formatCodingArtifact(session) {
209
+ const artifactPath = session?.artifactPath?.trim();
210
+ if (artifactPath)
211
+ return artifactPath;
212
+ return session ? "no PR or merge artifact yet" : null;
213
+ }
214
+ function formatCurrentArtifact(frame, obligation) {
215
+ // Live coding session artifact takes precedence (fresher evidence)
216
+ const liveCodingSession = frame.codingSessions?.[0];
217
+ if (liveCodingSession?.artifactPath?.trim()) {
218
+ return liveCodingSession.artifactPath.trim();
219
+ }
220
+ if (obligation?.currentArtifact?.trim()) {
221
+ return obligation.currentArtifact.trim();
222
+ }
223
+ if (obligation?.currentSurface?.kind === "merge" && obligation.currentSurface.label.trim()) {
224
+ return obligation.currentSurface.label.trim();
225
+ }
226
+ const liveCodingArtifact = formatCodingArtifact(liveCodingSession);
227
+ if (liveCodingArtifact) {
228
+ return liveCodingArtifact;
229
+ }
230
+ if (obligation) {
231
+ return "no artifact yet";
232
+ }
233
+ return null;
234
+ }
235
+ function formatObligationContentNextAction(obligation) {
236
+ const content = obligation?.content?.trim();
237
+ if (!content)
238
+ return null;
239
+ return `work on "${content}" and bring back a concrete artifact`;
240
+ }
241
+ function backgroundOperationPriority(operation) {
242
+ switch (operation.status) {
243
+ case "failed": return 0;
244
+ case "queued": return 1;
245
+ case "running": return 2;
246
+ case "succeeded": return 3;
247
+ }
248
+ }
249
+ function backgroundOperationSpecText(spec, key) {
250
+ const value = spec?.[key];
251
+ return typeof value === "string" ? value.trim() : "";
252
+ }
253
+ function selectPrimaryBackgroundOperation(frame) {
254
+ const operations = frame.backgroundOperations ?? [];
255
+ if (operations.length === 0)
256
+ return null;
257
+ return [...operations].sort((left, right) => {
258
+ const priorityDiff = backgroundOperationPriority(left) - backgroundOperationPriority(right);
259
+ if (priorityDiff !== 0)
260
+ return priorityDiff;
261
+ return Date.parse(right.updatedAt) - Date.parse(left.updatedAt);
262
+ })[0] ?? null;
263
+ }
264
+ function formatBackgroundOperationNextAction(operation) {
265
+ if (operation.kind === "mail.import-discovered") {
266
+ return "inspect the import-ready archive and start the matching mail import";
267
+ }
268
+ if (operation.kind === "mail.import-mbox") {
269
+ switch (operation.status) {
270
+ case "failed":
271
+ switch (operation.failure?.class?.trim()) {
272
+ case "transient-storage-read":
273
+ return "retry-safe once the transient storage/network issue clears";
274
+ case "mailroom-auth":
275
+ case "mailroom-config":
276
+ return "repair mail auth/config access, then retry";
277
+ case "source-grant-missing":
278
+ case "source-grant-ambiguous":
279
+ return "repair the delegated owner/source lane, then retry";
280
+ case "archive-discovery":
281
+ case "archive-ambiguity":
282
+ case "archive-missing":
283
+ case "archive-access":
284
+ return "materialize or point at the correct local archive, then retry";
285
+ }
286
+ if (operation.failure?.retryDisposition === "retry-safe") {
287
+ return "retry the failed mail import once the transient issue clears or the dependency answers again";
288
+ }
289
+ if (operation.failure?.retryDisposition === "investigate-first") {
290
+ return "inspect the failed mail import carefully, confirm the root cause, and then decide whether to retry";
291
+ }
292
+ return "inspect the failed mail import, fix the issue, and retry it";
293
+ case "queued":
294
+ return "queued — no action unless it stalls or i need live status";
295
+ case "running":
296
+ return "in flight — no action unless it stalls or i need live status";
297
+ case "succeeded":
298
+ return "caught up — no rerun needed unless a newer archive appears";
299
+ }
300
+ }
301
+ switch (operation.status) {
302
+ case "failed": return `repair the failed ${operation.title} operation and retry it`;
303
+ case "queued": return `let the queued ${operation.title} operation start, then re-check progress`;
304
+ case "running": return `monitor the ${operation.title} operation and react when it changes`;
305
+ case "succeeded": return `review the completed ${operation.title} operation and continue`;
306
+ }
307
+ }
308
+ function formatMailImportRecoveryUniverse(operation) {
309
+ const failureClass = operation.failure?.class?.trim();
310
+ if (!failureClass)
311
+ return null;
312
+ switch (failureClass) {
313
+ case "transient-storage-read":
314
+ return "transient dependency/read issue — safe to retry once storage/network answers again";
315
+ case "mailroom-auth":
316
+ case "mailroom-config":
317
+ return "mail auth/config issue — repair mail access or runtime config before retrying";
318
+ case "source-grant-missing":
319
+ case "source-grant-ambiguous":
320
+ return "delegated lane/registry issue — inspect owner/source linking before retrying";
321
+ case "archive-discovery":
322
+ case "archive-ambiguity":
323
+ case "archive-missing":
324
+ case "archive-access":
325
+ return "local archive/file issue — materialize or point at the right archive before retrying";
326
+ default:
327
+ return "unclassified import issue — inspect the recorded error before retrying";
328
+ }
329
+ }
330
+ function formatBackgroundOperationMeta(operation) {
331
+ const lines = [`operation: ${operation.id}`];
332
+ const filePath = backgroundOperationSpecText(operation.spec, "filePath")
333
+ || backgroundOperationSpecText(operation.spec, "newestCandidatePath");
334
+ if (filePath)
335
+ lines.push(`file: ${filePath}`);
336
+ const originLabel = backgroundOperationSpecText(operation.spec, "fileOriginLabel")
337
+ || backgroundOperationSpecText(operation.spec, "newestCandidateOriginLabel");
338
+ if (originLabel)
339
+ lines.push(`origin: ${originLabel}`);
340
+ const ownerEmail = backgroundOperationSpecText(operation.spec, "ownerEmail");
341
+ const source = backgroundOperationSpecText(operation.spec, "source");
342
+ if (ownerEmail || source) {
343
+ lines.push(`owner/source: ${ownerEmail || "unknown"} / ${source || "unknown"}`);
344
+ }
345
+ if (operation.failure?.class?.trim())
346
+ lines.push(`failure class: ${operation.failure.class}`);
347
+ if (operation.failure?.retryDisposition?.trim())
348
+ lines.push(`retry: ${operation.failure.retryDisposition}`);
349
+ if (operation.failure?.hint?.trim())
350
+ lines.push(`recovery: ${operation.failure.hint}`);
351
+ const recoveryUniverse = operation.kind === "mail.import-mbox" ? formatMailImportRecoveryUniverse(operation) : null;
352
+ if (recoveryUniverse)
353
+ lines.push(`recovery universe: ${recoveryUniverse}`);
354
+ if (operation.startedAt?.trim())
355
+ lines.push(`started: ${operation.startedAt}`);
356
+ if (operation.finishedAt?.trim())
357
+ lines.push(`finished: ${operation.finishedAt}`);
358
+ else if (operation.updatedAt?.trim())
359
+ lines.push(`updated: ${operation.updatedAt}`);
360
+ const nextAction = formatBackgroundOperationNextAction(operation);
361
+ if (nextAction.trim().length > 0)
362
+ lines.push(`next: ${nextAction}`);
363
+ if (operation.remediation?.length) {
364
+ lines.push(...operation.remediation.map((step) => `remediation: ${step}`));
365
+ }
366
+ return lines;
367
+ }
368
+ function formatNextAction(frame, obligation) {
369
+ const obligationHasConcreteArtifact = Boolean(obligation?.currentArtifact?.trim())
370
+ || obligation?.currentSurface?.kind === "merge";
371
+ if (obligation?.status === "waiting_for_merge") {
372
+ return obligation.nextAction?.trim() || `wait for checks, merge ${formatMergeArtifact(obligation)}, then update runtime`;
373
+ }
374
+ if (obligation?.status === "updating_runtime") {
375
+ return obligation.nextAction?.trim() || "update runtime, verify version/changelog, then re-observe";
376
+ }
377
+ if (obligationHasConcreteArtifact && obligation?.nextAction?.trim()) {
378
+ return obligation.nextAction.trim();
379
+ }
380
+ const liveCodingSession = frame.codingSessions?.[0];
381
+ if (liveCodingSession?.status === "waiting_input") {
382
+ return `answer ${formatCodingLaneLabel(liveCodingSession)} and continue`;
383
+ }
384
+ if (liveCodingSession?.status === "stalled") {
385
+ return `unstick ${formatCodingLaneLabel(liveCodingSession)} and continue`;
386
+ }
387
+ if (liveCodingSession) {
388
+ return "finish the coding pass and bring the result back here";
389
+ }
390
+ if (obligation?.nextAction?.trim())
391
+ return obligation.nextAction.trim();
392
+ if (obligation) {
393
+ return formatObligationContentNextAction(obligation) || "continue the active loop and bring the result back here";
394
+ }
395
+ const backgroundOperation = selectPrimaryBackgroundOperation(frame);
396
+ if (backgroundOperation) {
397
+ return formatBackgroundOperationNextAction(backgroundOperation);
398
+ }
399
+ if (frame.mustResolveBeforeHandoff) {
400
+ return "finish what i started here before moving on";
401
+ }
402
+ return null;
403
+ }
404
+ const RECENT_OTHER_LIVE_SESSION_WINDOW_MS = 60 * 60 * 1000;
405
+ function sessionOriginKey(origin) {
406
+ return `${origin.friendId}/${origin.channel}/${(0, config_1.sanitizeKey)(origin.key)}`;
407
+ }
408
+ function codingSessionTimestampMs(session) {
409
+ return Date.parse(session.lastActivityAt ?? session.startedAt);
410
+ }
411
+ function obligationTimestampMs(obligation) {
412
+ const value = Date.parse(obligation.updatedAt ?? obligation.createdAt);
413
+ return Number.isFinite(value) ? value : 0;
414
+ }
415
+ function newestObligationFirst(left, right) {
416
+ return obligationTimestampMs(right) - obligationTimestampMs(left);
417
+ }
418
+ function formatOtherSessionArtifact(obligation, codingSession) {
419
+ if (obligation?.currentArtifact?.trim())
420
+ return obligation.currentArtifact.trim();
421
+ if (obligation?.currentSurface?.kind === "merge" && obligation.currentSurface.label.trim()) {
422
+ return obligation.currentSurface.label.trim();
423
+ }
424
+ const codingArtifact = formatCodingArtifact(codingSession);
425
+ if (codingArtifact)
426
+ return codingArtifact;
427
+ return obligation ? "no artifact yet" : "no explicit artifact yet";
428
+ }
429
+ function formatOtherSessionNextAction(obligation, codingSession) {
430
+ if (obligation?.nextAction?.trim())
431
+ return obligation.nextAction.trim();
432
+ if (obligation?.status === "waiting_for_merge") {
433
+ return `wait for checks, merge ${formatMergeArtifact(obligation)}, then update runtime`;
434
+ }
435
+ if (obligation?.status === "updating_runtime") {
436
+ return "update runtime, verify version/changelog, then re-observe";
437
+ }
438
+ if (codingSession?.status === "waiting_input") {
439
+ return `answer ${formatCodingLaneLabel(codingSession)} and continue`;
440
+ }
441
+ if (codingSession?.status === "stalled") {
442
+ return `unstick ${formatCodingLaneLabel(codingSession)} and continue`;
443
+ }
444
+ if (codingSession) {
445
+ return "finish the coding pass and bring the result back there";
446
+ }
447
+ if (obligation) {
448
+ return formatObligationContentNextAction(obligation) || "continue the active loop and bring the result back there";
449
+ }
450
+ return "check this session and bring back the latest concrete state";
451
+ }
452
+ function formatOtherSessionLine(label, status, activeLane, artifact, nextAction) {
453
+ return `- ${label}: [${status}] ${activeLane}; artifact ${artifact}; next ${nextAction}`;
454
+ }
455
+ function formatOtherActiveSessionSummaries(frame, nowMs = Date.now()) {
456
+ const originMap = new Map();
457
+ for (const session of frame.friendActivity?.allOtherLiveSessions ?? []) {
458
+ if (session.friendId === "self" || session.channel === "inner")
459
+ continue;
460
+ originMap.set(sessionOriginKey(session), {
461
+ friendId: session.friendId,
462
+ channel: session.channel,
463
+ key: session.key,
464
+ });
465
+ }
466
+ const orphanCodingSummaries = (frame.otherCodingSessions ?? [])
467
+ .filter((session) => !session.originSession)
468
+ .sort((left, right) => codingSessionTimestampMs(right) - codingSessionTimestampMs(left))
469
+ .map((session) => ({
470
+ timestampMs: codingSessionTimestampMs(session),
471
+ line: formatOtherSessionLine("another session", session.status, formatCodingLaneLabel(session), formatCodingArtifact(session), formatOtherSessionNextAction(null, session)),
472
+ }));
473
+ for (const session of frame.otherCodingSessions ?? []) {
474
+ if (!session.originSession)
475
+ continue;
476
+ if (frame.currentSession
477
+ && session.originSession.friendId === frame.currentSession.friendId
478
+ && session.originSession.channel === frame.currentSession.channel
479
+ && (0, config_1.sanitizeKey)(session.originSession.key) === (0, config_1.sanitizeKey)(frame.currentSession.key)) {
480
+ continue;
481
+ }
482
+ originMap.set(sessionOriginKey(session.originSession), session.originSession);
483
+ }
484
+ for (const obligation of frame.pendingObligations ?? []) {
485
+ if (obligation.status === "fulfilled" || matchesCurrentSession(frame, obligation))
486
+ continue;
487
+ originMap.set(sessionOriginKey(obligation.origin), obligation.origin);
488
+ }
489
+ const summaries = [...originMap.values()].map((origin) => {
490
+ const originKey = sessionOriginKey(origin);
491
+ const obligation = [...(frame.pendingObligations ?? [])]
492
+ .filter((candidate) => candidate.status !== "fulfilled" && sessionOriginKey(candidate.origin) === originKey)
493
+ .sort(newestObligationFirst)[0] ?? null;
494
+ const codingSession = [...(frame.otherCodingSessions ?? [])]
495
+ .filter((candidate) => candidate.originSession && sessionOriginKey(candidate.originSession) === originKey)
496
+ .sort((left, right) => codingSessionTimestampMs(right) - codingSessionTimestampMs(left))[0] ?? null;
497
+ const liveSession = (frame.friendActivity?.allOtherLiveSessions ?? []).find((candidate) => sessionOriginKey(candidate) === originKey) ?? null;
498
+ const hasMaterialLiveSession = liveSession
499
+ ? ((nowMs - liveSession.lastActivityMs) <= RECENT_OTHER_LIVE_SESSION_WINDOW_MS
500
+ || (frame.currentSession != null
501
+ && liveSession.friendId === frame.currentSession.friendId
502
+ && liveSession.channel !== frame.currentSession.channel))
503
+ : false;
504
+ if (!obligation && !codingSession && !hasMaterialLiveSession) {
505
+ return null;
506
+ }
507
+ const timestampMs = Math.max(liveSession?.lastActivityMs ?? 0, codingSession ? codingSessionTimestampMs(codingSession) : 0, obligation ? obligationTimestampMs(obligation) : 0);
508
+ const activeLane = codingSession
509
+ ? formatCodingLaneLabel(codingSession)
510
+ : obligation?.currentSurface?.label?.trim() || "this live thread";
511
+ const artifact = formatOtherSessionArtifact(obligation, codingSession);
512
+ const nextAction = formatOtherSessionNextAction(obligation, codingSession);
513
+ const status = obligation?.status ?? codingSession?.status ?? "active";
514
+ const label = liveSession?.friendName ?? origin.friendId;
515
+ return {
516
+ timestampMs,
517
+ line: formatOtherSessionLine(`${label}/${origin.channel}/${origin.key}`, status, activeLane, artifact, nextAction),
518
+ };
519
+ }).filter((entry) => entry !== null)
520
+ .sort((left, right) => right.timestampMs - left.timestampMs);
521
+ const lines = summaries.map((entry) => entry.line);
522
+ return [...lines, ...orphanCodingSummaries.map((entry) => entry.line)];
523
+ }
52
524
  function suggestBridgeForActiveWork(input) {
53
525
  const targetCandidates = (input.targetCandidates ?? [])
54
526
  .filter((candidate) => {
@@ -68,10 +540,16 @@ function suggestBridgeForActiveWork(input) {
68
540
  .sort((a, b) => {
69
541
  return b.lastActivityMs - a.lastActivityMs;
70
542
  });
71
- if (!hasSharedObligationPressure(input) || targetCandidates.length === 0) {
543
+ if (!hasSharedObligationPressure({
544
+ mustResolveBeforeHandoff: input.mustResolveBeforeHandoff,
545
+ pendingObligations: input.pendingObligations,
546
+ }) || targetCandidates.length === 0) {
72
547
  return null;
73
548
  }
74
549
  const targetSession = targetCandidates[0];
550
+ const objectiveHint = [...(input.pendingObligations ?? [])]
551
+ .find((obligation) => (0, obligations_1.isOpenObligationStatus)(obligation.status))
552
+ ?.content?.trim() || "keep this shared work aligned";
75
553
  const activeBridge = input.bridges.find(isActiveBridge) ?? null;
76
554
  if (activeBridge) {
77
555
  const alreadyAttached = activeBridge.attachedSessions.some((session) => session.friendId === targetSession.friendId
@@ -90,27 +568,70 @@ function suggestBridgeForActiveWork(input) {
90
568
  return {
91
569
  kind: "begin-new",
92
570
  targetSession,
93
- objectiveHint: input.currentObligation?.trim() || "keep this shared work aligned",
571
+ objectiveHint,
94
572
  reason: "shared-work-candidate",
95
573
  };
96
574
  }
97
575
  function formatSessionLabel(session) {
98
576
  return `${session.channel}/${session.key}`;
99
577
  }
578
+ function deriveResumeHandleConfidence(primaryObligation, codingSession) {
579
+ if (primaryObligation?.currentArtifact?.trim() && primaryObligation.nextAction?.trim())
580
+ return "high";
581
+ if (codingSession?.checkpoint?.trim())
582
+ return "medium";
583
+ if (primaryObligation)
584
+ return "low";
585
+ return "low";
586
+ }
587
+ function buildResumeHandle(currentSession, primaryObligation, codingSessions) {
588
+ const sessionLabel = currentSession ? formatSessionLabel(currentSession) : null;
589
+ if (!sessionLabel)
590
+ return null;
591
+ const liveCoding = codingSessions[0] ?? null;
592
+ const lane = liveCoding
593
+ ? `${formatCodingLaneLabel(liveCoding)}${describeCodingSessionScope(liveCoding, currentSession)}`
594
+ : (primaryObligation?.currentSurface?.label?.trim() || null);
595
+ const artifact = primaryObligation?.currentArtifact?.trim()
596
+ || (liveCoding?.artifactPath?.trim() || null);
597
+ const blockerOrWaitingOn = primaryObligation?.meaning?.waitingOn?.detail?.trim() || null;
598
+ const nextAction = primaryObligation?.nextAction?.trim()
599
+ || (primaryObligation?.content?.trim() ? `work on "${primaryObligation.content.trim()}" and bring back a concrete artifact` : null);
600
+ const lastVerifiedCheckpoint = liveCoding?.checkpoint?.trim() || null;
601
+ const codingIdentity = liveCoding
602
+ ? { sessionId: liveCoding.id, runner: liveCoding.runner, status: liveCoding.status }
603
+ : null;
604
+ return {
605
+ sessionLabel,
606
+ lane,
607
+ artifact,
608
+ blockerOrWaitingOn,
609
+ nextAction,
610
+ lastVerifiedCheckpoint,
611
+ confidence: deriveResumeHandleConfidence(primaryObligation, liveCoding),
612
+ codingIdentity,
613
+ };
614
+ }
100
615
  function buildActiveWorkFrame(input) {
101
616
  const friendSessions = input.currentSession
102
617
  ? input.friendActivity
103
618
  .filter((entry) => entry.friendId === input.currentSession?.friendId)
104
619
  .sort(compareActivity)
105
620
  : [];
106
- const liveTaskNames = summarizeLiveTasks(input.taskBoard);
107
621
  const activeBridgePresent = input.bridges.some(isActiveBridge);
108
- const openObligations = activeObligationCount(input.pendingObligations);
622
+ const liveCodingSessions = input.codingSessions ?? [];
623
+ const openEvolutionCases = liveEvolutionCases(input.evolutionCases);
624
+ const allOtherLiveSessions = [...input.friendActivity].sort(compareActivity);
625
+ const otherCodingSessions = input.otherCodingSessions ?? [];
626
+ const pendingObligations = normalizePendingObligations(input.pendingObligations, liveCodingSessions, otherCodingSessions);
627
+ const openObligations = activeObligationCount(pendingObligations);
109
628
  const centerOfGravity = activeBridgePresent
110
629
  ? "shared-work"
111
- : (input.inner.status === "running" || input.inner.hasPending || input.mustResolveBeforeHandoff || openObligations > 0)
630
+ : (input.inner.status === "running" || input.inner.hasPending || input.mustResolveBeforeHandoff || openObligations > 0 || liveCodingSessions.length > 0)
112
631
  ? "inward-work"
113
632
  : "local-turn";
633
+ const primaryObligation = selectPrimaryObligation(pendingObligations, input.currentSession ?? null);
634
+ const resumeHandle = buildResumeHandle(input.currentSession ?? null, primaryObligation, liveCodingSessions);
114
635
  const frame = {
115
636
  currentSession: input.currentSession ?? null,
116
637
  currentObligation: input.currentObligation?.trim() || null,
@@ -118,25 +639,28 @@ function buildActiveWorkFrame(input) {
118
639
  centerOfGravity,
119
640
  inner: input.inner,
120
641
  bridges: input.bridges,
121
- taskPressure: {
122
- compactBoard: input.taskBoard.compact,
123
- liveTaskNames,
124
- activeBridges: input.taskBoard.activeBridges,
125
- },
126
642
  friendActivity: {
127
643
  freshestForCurrentFriend: friendSessions[0] ?? null,
128
644
  otherLiveSessionsForCurrentFriend: friendSessions,
645
+ allOtherLiveSessions,
129
646
  },
130
- pendingObligations: input.pendingObligations ?? [],
647
+ codingSessions: liveCodingSessions,
648
+ evolutionCases: openEvolutionCases,
649
+ backgroundOperations: input.backgroundOperations ?? [],
650
+ otherCodingSessions,
651
+ pendingObligations,
131
652
  targetCandidates: input.targetCandidates ?? [],
653
+ innerReturnObligations: input.innerReturnObligations ?? [],
132
654
  bridgeSuggestion: suggestBridgeForActiveWork({
133
655
  currentSession: input.currentSession,
134
656
  currentObligation: input.currentObligation,
135
657
  mustResolveBeforeHandoff: input.mustResolveBeforeHandoff,
136
658
  bridges: input.bridges,
137
- taskBoard: input.taskBoard,
659
+ pendingObligations,
138
660
  targetCandidates: input.targetCandidates,
139
661
  }),
662
+ primaryObligation,
663
+ resumeHandle,
140
664
  };
141
665
  (0, runtime_1.emitNervesEvent)({
142
666
  component: "engine",
@@ -146,21 +670,38 @@ function buildActiveWorkFrame(input) {
146
670
  centerOfGravity: frame.centerOfGravity,
147
671
  friendId: frame.currentSession?.friendId ?? null,
148
672
  bridges: frame.bridges.length,
149
- liveTasks: frame.taskPressure.liveTaskNames.length,
150
673
  liveSessions: frame.friendActivity.otherLiveSessionsForCurrentFriend.length,
674
+ codingSessions: frame.codingSessions.length,
675
+ otherLiveSessions: allOtherLiveSessions.length,
676
+ otherCodingSessions: otherCodingSessions.length,
151
677
  pendingObligations: openObligations,
678
+ evolutionCases: openEvolutionCases.length,
152
679
  hasBridgeSuggestion: frame.bridgeSuggestion !== null,
153
680
  },
154
681
  });
155
682
  return frame;
156
683
  }
157
- function formatActiveWorkFrame(frame) {
684
+ function formatActiveWorkFrame(frame, options) {
158
685
  const lines = ["## what i'm holding"];
686
+ lines.push("this is my top-level live world-state right now. private-runtime work, coding lanes, other sessions, and return obligations all belong inside this picture.");
687
+ lines.push("if older checkpoints elsewhere in the transcript disagree with this picture, this picture wins.");
688
+ const friendContactTiming = (0, session_activity_1.describeSessionActivityTiming)((0, session_activity_1.selectFreshestFriendFacingActivity)(frame.friendActivity?.allOtherLiveSessions ?? []), { prefix: "freshest friend-facing contact" });
689
+ if (friendContactTiming) {
690
+ lines.push("");
691
+ lines.push("## contact timing");
692
+ lines.push(`- ${friendContactTiming}`);
693
+ }
694
+ const primaryObligation = findPrimaryOpenObligation(frame);
695
+ const currentSessionObligation = findCurrentSessionOpenObligation(frame);
696
+ const activeLane = formatActiveLane(frame, primaryObligation);
697
+ const currentArtifact = formatCurrentArtifact(frame, primaryObligation);
698
+ const nextAction = formatNextAction(frame, primaryObligation);
699
+ const otherActiveSessions = formatOtherActiveSessionSummaries(frame);
159
700
  // Session line
160
701
  if (frame.currentSession) {
161
702
  let sessionLine = `i'm in a conversation on ${formatSessionLabel(frame.currentSession)}.`;
162
- if (typeof frame.currentObligation === "string" && frame.currentObligation.trim().length > 0) {
163
- sessionLine += ` i told them i'd ${frame.currentObligation.trim()}.`;
703
+ if (currentSessionObligation?.content?.trim()) {
704
+ sessionLine += ` i still owe them: ${currentSessionObligation.content.trim()}.`;
164
705
  }
165
706
  else if (frame.mustResolveBeforeHandoff) {
166
707
  sessionLine += " i need to finish what i started here before moving on.";
@@ -172,6 +713,25 @@ function formatActiveWorkFrame(frame) {
172
713
  lines.push("");
173
714
  lines.push("i'm not in a conversation right now.");
174
715
  }
716
+ if (activeLane || currentArtifact || nextAction) {
717
+ lines.push("");
718
+ lines.push("## current concrete state");
719
+ if (frame.currentSession) {
720
+ lines.push(`- live conversation: ${formatSessionLabel(frame.currentSession)}`);
721
+ }
722
+ if (activeLane) {
723
+ lines.push(`- active lane: ${activeLane}`);
724
+ }
725
+ if (currentArtifact) {
726
+ lines.push(`- current artifact: ${currentArtifact}`);
727
+ }
728
+ if (nextAction) {
729
+ lines.push(`- next action: ${nextAction}`);
730
+ }
731
+ if (frame.resumeHandle?.lastVerifiedCheckpoint) {
732
+ lines.push(`- last checkpoint: ${frame.resumeHandle.lastVerifiedCheckpoint}`);
733
+ }
734
+ }
175
735
  // Inner status block
176
736
  const job = frame.inner?.job;
177
737
  if (job) {
@@ -205,10 +765,57 @@ function formatActiveWorkFrame(frame) {
205
765
  }
206
766
  // idle, returned, abandoned: omitted
207
767
  }
208
- // Task pressure
209
- if ((frame.taskPressure?.liveTaskNames ?? []).length > 0) {
768
+ if ((frame.codingSessions ?? []).length > 0) {
210
769
  lines.push("");
211
- lines.push(`i'm also tracking: ${frame.taskPressure.liveTaskNames.join(", ")}.`);
770
+ lines.push("## live coding work");
771
+ for (const session of frame.codingSessions) {
772
+ const checkpoint = compactCodingCheckpoint(session);
773
+ lines.push(`- [${session.status}] ${formatCodingLaneLabel(session)}${describeCodingSessionScope(session, frame.currentSession)}${checkpoint ? `: ${checkpoint}` : ""}`);
774
+ /* v8 ignore start -- coding identity display: tested in identity-packet.test.ts @preserve */
775
+ if (session.codingIdentity) {
776
+ const id = session.codingIdentity;
777
+ lines.push(` branch: ${id.branch ?? "unknown"} commit: ${id.commit ?? "unknown"} ${id.dirty ? "dirty" : "clean"} verification: ${id.verificationStatus}`);
778
+ }
779
+ /* v8 ignore stop */
780
+ }
781
+ }
782
+ const evolutionCases = liveEvolutionCases(frame.evolutionCases);
783
+ if (evolutionCases.length > 0) {
784
+ lines.push("");
785
+ lines.push("## evolution cases");
786
+ for (const evolutionCase of evolutionCases) {
787
+ lines.push(formatEvolutionCaseLine(evolutionCase));
788
+ }
789
+ }
790
+ const backgroundOperations = frame.backgroundOperations ?? [];
791
+ if (backgroundOperations.length > 0) {
792
+ lines.push("");
793
+ lines.push("## background operations");
794
+ for (const operation of backgroundOperations) {
795
+ let line = `- [${operation.status}] ${operation.title}`;
796
+ if (operation.summary.trim().length > 0) {
797
+ line += `: ${operation.summary}`;
798
+ }
799
+ line += `\n ${formatBackgroundOperationMeta(operation).join("\n ")}`;
800
+ if (operation.detail?.trim()) {
801
+ line += `\n ${operation.detail.trim()}`;
802
+ }
803
+ if (operation.progress) {
804
+ const current = typeof operation.progress.current === "number" ? String(operation.progress.current) : "?";
805
+ const total = typeof operation.progress.total === "number" ? String(operation.progress.total) : null;
806
+ const unit = operation.progress.unit?.trim() ? ` ${operation.progress.unit.trim()}` : "";
807
+ line += `\n progress: ${total ? `${current}/${total}` : current}${unit}`;
808
+ }
809
+ if (operation.error?.message?.trim()) {
810
+ line += `\n error: ${operation.error.message.trim()}`;
811
+ }
812
+ lines.push(line);
813
+ }
814
+ }
815
+ if (otherActiveSessions.length > 0) {
816
+ lines.push("");
817
+ lines.push("## other active sessions");
818
+ lines.push(...otherActiveSessions);
212
819
  }
213
820
  // Bridges
214
821
  if ((frame.bridges ?? []).length > 0) {
@@ -225,16 +832,35 @@ function formatActiveWorkFrame(frame) {
225
832
  lines.push(targetCandidatesBlock);
226
833
  }
227
834
  if ((frame.pendingObligations ?? []).length > 0) {
228
- lines.push("");
229
- lines.push("## return obligations");
230
- for (const obligation of frame.pendingObligations) {
231
- if (!(0, obligations_1.isOpenObligationStatus)(obligation.status))
232
- continue;
233
- let obligationLine = `- [${obligation.status}] ${obligation.origin.friendId}/${obligation.origin.channel}/${obligation.origin.key}: ${obligation.content}${formatObligationSurface(obligation)}`;
234
- if (obligation.latestNote?.trim()) {
235
- obligationLine += `\n latest: ${obligation.latestNote.trim()}`;
835
+ const openCount = frame.pendingObligations.filter((ob) => (0, obligations_1.isOpenObligationStatus)(ob.status)).length;
836
+ if (options?.obligationDetailsRenderedElsewhere && openCount > 0) {
837
+ // Enriched obligation data (with resumeHint, stalenessClass, waitingOn) is rendered elsewhere.
838
+ // Avoid duplicating the full list — just anchor the count here.
839
+ lines.push("");
840
+ lines.push(`return obligations: ${openCount} active (canonical details in **Owed** section of start-of-turn packet)`);
841
+ }
842
+ else if (openCount > 0) {
843
+ lines.push("");
844
+ lines.push("## return obligations");
845
+ for (const obligation of frame.pendingObligations) {
846
+ if (!(0, obligations_1.isOpenObligationStatus)(obligation.status))
847
+ continue;
848
+ let obligationLine = `- [${obligation.status}] ${obligation.origin.friendId}/${obligation.origin.channel}/${obligation.origin.key}: ${obligation.content}${formatObligationSurface(obligation)}`;
849
+ if (obligation.latestNote?.trim()) {
850
+ obligationLine += `\n latest: ${obligation.latestNote.trim()}`;
851
+ }
852
+ lines.push(obligationLine);
236
853
  }
237
- lines.push(obligationLine);
854
+ }
855
+ }
856
+ if (frame.innerReturnObligations && frame.innerReturnObligations.length > 0) {
857
+ lines.push("");
858
+ lines.push("## private-runtime return obligations");
859
+ for (const ob of frame.innerReturnObligations) {
860
+ const preview = ob.delegatedContent.length > 60
861
+ ? `${ob.delegatedContent.slice(0, 57)}...`
862
+ : ob.delegatedContent;
863
+ lines.push(`- [${ob.status}] ${ob.origin.friendId}/${ob.origin.channel}/${ob.origin.key}: ${preview}`);
238
864
  }
239
865
  }
240
866
  // Bridge suggestion
@@ -247,5 +873,137 @@ function formatActiveWorkFrame(frame) {
247
873
  lines.push(`this work relates to bridge ${frame.bridgeSuggestion.bridgeId} -- i should connect ${formatSessionLabel(frame.bridgeSuggestion.targetSession)} to it.`);
248
874
  }
249
875
  }
876
+ const rendered = lines.join("\n");
877
+ return typeof options?.resumePriorWork === "boolean"
878
+ ? (0, orientation_frame_1.labelPriorWorkSurface)(rendered, options.resumePriorWork)
879
+ : rendered;
880
+ }
881
+ function formatLiveWorldStateCheckpoint(frame, options) {
882
+ const primaryObligation = findPrimaryOpenObligation(frame);
883
+ const activeLane = formatActiveLane(frame, primaryObligation) ?? "no explicit live lane";
884
+ const currentArtifact = formatCurrentArtifact(frame, primaryObligation) ?? "no artifact yet";
885
+ const nextAction = formatNextAction(frame, primaryObligation) ?? "continue from the live world-state";
886
+ const otherActiveSessions = formatOtherActiveSessionSummaries(frame);
887
+ const lines = [
888
+ "## live world-state",
889
+ "This is the freshest state for this turn. If older transcript history conflicts with it, this state wins.",
890
+ `- live conversation: ${frame.currentSession ? formatSessionLabel(frame.currentSession) : "not in a live conversation"}`,
891
+ `- active lane: ${activeLane}`,
892
+ `- current artifact: ${currentArtifact}`,
893
+ `- next action: ${nextAction}`,
894
+ ];
895
+ if (frame.resumeHandle?.lastVerifiedCheckpoint) {
896
+ lines.push(`- last checkpoint: ${frame.resumeHandle.lastVerifiedCheckpoint}`);
897
+ }
898
+ const evolutionCheckpointLine = formatEvolutionCheckpointLine(liveEvolutionCases(frame.evolutionCases));
899
+ if (evolutionCheckpointLine) {
900
+ lines.push(evolutionCheckpointLine);
901
+ }
902
+ if (otherActiveSessions.length > 0) {
903
+ lines.push("other active sessions:");
904
+ lines.push(...otherActiveSessions);
905
+ }
906
+ const rendered = lines.join("\n");
907
+ return typeof options?.resumePriorWork === "boolean"
908
+ ? (0, orientation_frame_1.labelPriorWorkSurface)(rendered, options.resumePriorWork)
909
+ : rendered;
910
+ }
911
+ function snapshotActiveWork(frame) {
912
+ return {
913
+ obligationSnapshots: (frame.pendingObligations ?? []).map((ob) => ({
914
+ id: ob.id,
915
+ status: ob.status,
916
+ artifact: ob.currentArtifact?.trim() || null,
917
+ nextAction: ob.nextAction?.trim() || null,
918
+ })),
919
+ codingSnapshots: (frame.codingSessions ?? []).map((cs) => ({
920
+ id: cs.id,
921
+ status: cs.status,
922
+ artifact: cs.artifactPath?.trim() || null,
923
+ checkpoint: cs.checkpoint?.trim() || null,
924
+ })),
925
+ timestamp: new Date().toISOString(),
926
+ };
927
+ }
928
+ function detectActiveWorkChanges(previous, current) {
929
+ const changes = [];
930
+ const prevObMap = new Map(previous.obligationSnapshots.map((ob) => [ob.id, ob]));
931
+ const currObMap = new Map(current.obligationSnapshots.map((ob) => [ob.id, ob]));
932
+ // Detect new and changed obligations
933
+ for (const [id, curr] of currObMap) {
934
+ const prev = prevObMap.get(id);
935
+ if (!prev) {
936
+ changes.push({
937
+ kind: "obligation_appeared",
938
+ id,
939
+ from: null,
940
+ to: curr.status,
941
+ summary: `new obligation: ${curr.status}`,
942
+ });
943
+ continue;
944
+ }
945
+ if (prev.status !== curr.status) {
946
+ changes.push({
947
+ kind: "obligation_status_changed",
948
+ id,
949
+ from: prev.status,
950
+ to: curr.status,
951
+ summary: `obligation ${prev.status} -> ${curr.status}`,
952
+ });
953
+ }
954
+ if (prev.artifact !== curr.artifact) {
955
+ changes.push({
956
+ kind: "obligation_artifact_changed",
957
+ id,
958
+ from: prev.artifact,
959
+ to: curr.artifact,
960
+ summary: curr.artifact ? `artifact updated: ${curr.artifact}` : "artifact cleared",
961
+ });
962
+ }
963
+ }
964
+ const prevCodingMap = new Map(previous.codingSnapshots.map((cs) => [cs.id, cs]));
965
+ const currCodingMap = new Map(current.codingSnapshots.map((cs) => [cs.id, cs]));
966
+ for (const [id, curr] of currCodingMap) {
967
+ const prev = prevCodingMap.get(id);
968
+ if (!prev)
969
+ continue;
970
+ if (prev.status !== curr.status) {
971
+ changes.push({
972
+ kind: "coding_status_changed",
973
+ id,
974
+ from: prev.status,
975
+ to: curr.status,
976
+ summary: `coding ${prev.status} -> ${curr.status}`,
977
+ });
978
+ }
979
+ if (prev.artifact !== curr.artifact) {
980
+ changes.push({
981
+ kind: "coding_artifact_changed",
982
+ id,
983
+ from: prev.artifact,
984
+ to: curr.artifact,
985
+ summary: curr.artifact ? `artifact updated: ${curr.artifact}` : "artifact cleared",
986
+ });
987
+ }
988
+ if (prev.checkpoint !== curr.checkpoint) {
989
+ changes.push({
990
+ kind: "coding_checkpoint_changed",
991
+ id,
992
+ from: prev.checkpoint,
993
+ to: curr.checkpoint,
994
+ summary: curr.checkpoint ? `checkpoint: ${curr.checkpoint}` : "checkpoint cleared",
995
+ });
996
+ }
997
+ }
998
+ return changes;
999
+ }
1000
+ function formatActiveWorkChanges(changes) {
1001
+ if (changes.length === 0)
1002
+ return "";
1003
+ const lines = ["## what changed since last looked"];
1004
+ for (const change of changes) {
1005
+ lines.push(`- ${change.summary}`);
1006
+ }
250
1007
  return lines.join("\n");
251
1008
  }
1009
+ /* v8 ignore stop */