@ouro.bot/cli 0.1.0-alpha.85 → 0.1.0-alpha.851

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 (650) 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 +5434 -16
  16. package/deploy/unraid/Dockerfile +58 -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-butler-upgrade.mjs +933 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  36. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  37. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  38. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  39. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  40. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  41. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  42. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  43. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +1364 -0
  44. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +18 -0
  50. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  51. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +220 -0
  52. package/deploy/unraid/sanctuary.xml +28 -0
  53. package/dist/a2a/card.js +57 -0
  54. package/dist/a2a/client.js +237 -0
  55. package/dist/a2a/config.js +50 -0
  56. package/dist/a2a/delegated-command.js +85 -0
  57. package/dist/a2a/delegation-stores.js +56 -0
  58. package/dist/a2a/did-resolution.js +93 -0
  59. package/dist/a2a/identity.js +204 -0
  60. package/dist/a2a/inbound-share.js +110 -0
  61. package/dist/a2a/mission-result-wire.js +196 -0
  62. package/dist/a2a/onboarding.js +133 -0
  63. package/dist/a2a/pin-store.js +132 -0
  64. package/dist/a2a/sealed-chat.js +113 -0
  65. package/dist/a2a/seen-ledger.js +120 -0
  66. package/dist/a2a/server.js +700 -0
  67. package/dist/a2a/task-store.js +69 -0
  68. package/dist/a2a/transport.js +45 -0
  69. package/dist/a2a/types.js +3 -0
  70. package/dist/arc/attention-types.js +8 -0
  71. package/dist/arc/cares.js +360 -0
  72. package/dist/arc/episodes.js +118 -0
  73. package/dist/arc/evolution.js +490 -0
  74. package/dist/arc/flight-recorder.js +1034 -0
  75. package/dist/arc/intentions.js +134 -0
  76. package/dist/arc/json-store.js +117 -0
  77. package/dist/arc/obligations.js +386 -0
  78. package/dist/arc/packets.js +336 -0
  79. package/dist/arc/presence.js +185 -0
  80. package/dist/arc/task-lifecycle.js +57 -0
  81. package/dist/commerce/store.js +755 -0
  82. package/dist/commerce/types.js +3 -0
  83. package/dist/heart/active-work.js +798 -40
  84. package/dist/heart/agent-entry.js +252 -3
  85. package/dist/heart/approval-files.js +113 -0
  86. package/dist/heart/approval-store.js +960 -0
  87. package/dist/heart/attachments/image-normalize.js +194 -0
  88. package/dist/heart/attachments/materialize.js +97 -0
  89. package/dist/heart/attachments/originals.js +88 -0
  90. package/dist/heart/attachments/render.js +29 -0
  91. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  92. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  93. package/dist/heart/attachments/sources/index.js +18 -0
  94. package/dist/heart/attachments/sources/telegram.js +71 -0
  95. package/dist/heart/attachments/store.js +132 -0
  96. package/dist/heart/attachments/types.js +93 -0
  97. package/dist/heart/auth/auth-flow.js +495 -0
  98. package/dist/heart/autonomy-budget.js +478 -0
  99. package/dist/heart/awaiting/await-alert.js +148 -0
  100. package/dist/heart/awaiting/await-expiry.js +143 -0
  101. package/dist/heart/awaiting/await-loader.js +91 -0
  102. package/dist/heart/awaiting/await-parser.js +149 -0
  103. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  104. package/dist/heart/awaiting/await-scheduler.js +382 -0
  105. package/dist/heart/background-operations.js +281 -0
  106. package/dist/heart/bridges/manager.js +137 -17
  107. package/dist/heart/bridges/store.js +14 -2
  108. package/dist/heart/bundle-state.js +168 -0
  109. package/dist/heart/commitments.js +44 -18
  110. package/dist/heart/config-registry.js +331 -0
  111. package/dist/heart/config.js +174 -131
  112. package/dist/heart/context-loss-gauntlet.js +387 -0
  113. package/dist/heart/context-loss-sentinel.js +1157 -0
  114. package/dist/heart/core.js +2199 -581
  115. package/dist/heart/cross-chat-delivery.js +9 -22
  116. package/dist/heart/daemon/agent-config-check.js +451 -0
  117. package/dist/heart/daemon/agent-discovery.js +185 -3
  118. package/dist/heart/daemon/agent-service.js +542 -0
  119. package/dist/heart/daemon/agentic-repair.js +547 -0
  120. package/dist/heart/daemon/await-private-wake.js +59 -0
  121. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  122. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  123. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  124. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  125. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  126. package/dist/heart/daemon/cadence.js +180 -0
  127. package/dist/heart/daemon/cli-defaults.js +854 -0
  128. package/dist/heart/daemon/cli-desk.js +322 -0
  129. package/dist/heart/daemon/cli-exec.js +8897 -0
  130. package/dist/heart/daemon/cli-help.js +716 -0
  131. package/dist/heart/daemon/cli-parse.js +2877 -0
  132. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  133. package/dist/heart/daemon/cli-render.js +777 -0
  134. package/dist/heart/daemon/cli-types.js +8 -0
  135. package/dist/heart/daemon/connect-bay.js +323 -0
  136. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  137. package/dist/heart/daemon/container-healthcheck.js +112 -0
  138. package/dist/heart/daemon/container-runtime.js +97 -0
  139. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  140. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  141. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  142. package/dist/heart/daemon/daemon-cli.js +29 -2349
  143. package/dist/heart/daemon/daemon-entry.js +930 -11
  144. package/dist/heart/daemon/daemon-health.js +186 -0
  145. package/dist/heart/daemon/daemon-rollup.js +57 -0
  146. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  147. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  148. package/dist/heart/daemon/daemon.js +2084 -105
  149. package/dist/heart/daemon/dns-workflow.js +394 -0
  150. package/dist/heart/daemon/doctor-types.js +8 -0
  151. package/dist/heart/daemon/doctor.js +1755 -0
  152. package/dist/heart/daemon/freshness.js +345 -0
  153. package/dist/heart/daemon/habit-private-wake.js +61 -0
  154. package/dist/heart/daemon/health-monitor.js +142 -11
  155. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  156. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  157. package/dist/heart/daemon/http-health-probe.js +80 -0
  158. package/dist/heart/daemon/human-command-screens.js +234 -0
  159. package/dist/heart/daemon/human-readiness.js +114 -0
  160. package/dist/heart/daemon/inner-status.js +78 -0
  161. package/dist/heart/daemon/interactive-repair.js +394 -0
  162. package/dist/heart/daemon/launchd.js +37 -8
  163. package/dist/heart/daemon/log-tailer.js +79 -10
  164. package/dist/heart/daemon/logs-prune.js +132 -0
  165. package/dist/heart/daemon/mcp-canary.js +524 -0
  166. package/dist/heart/daemon/message-router.js +65 -5
  167. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  168. package/dist/heart/daemon/os-cron-deps.js +135 -0
  169. package/dist/heart/daemon/os-cron.js +22 -14
  170. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  171. package/dist/heart/daemon/ouro-entry.js +3 -1
  172. package/dist/heart/daemon/plugin-cli.js +432 -0
  173. package/dist/heart/daemon/process-manager.js +733 -61
  174. package/dist/heart/daemon/provider-discovery.js +137 -0
  175. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  176. package/dist/heart/daemon/prunable-bundle.js +144 -0
  177. package/dist/heart/daemon/pulse.js +511 -0
  178. package/dist/heart/daemon/readiness-repair.js +365 -0
  179. package/dist/heart/daemon/run-hooks.js +2 -0
  180. package/dist/heart/daemon/runtime-logging.js +47 -14
  181. package/dist/heart/daemon/runtime-metadata.js +2 -30
  182. package/dist/heart/daemon/runtime-mode.js +13 -2
  183. package/dist/heart/daemon/safe-mode.js +161 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  185. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  186. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  187. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  188. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  189. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  190. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  191. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  192. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1165 -0
  193. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  194. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  195. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  196. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  197. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  198. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  199. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  200. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  201. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  202. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  203. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  204. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  205. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  206. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +663 -0
  207. package/dist/heart/daemon/sense-manager.js +699 -48
  208. package/dist/heart/daemon/session-id-resolver.js +131 -0
  209. package/dist/heart/daemon/skill-management-installer.js +1 -1
  210. package/dist/heart/daemon/socket-client.js +180 -12
  211. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  212. package/dist/heart/daemon/startup-tui.js +339 -0
  213. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  214. package/dist/heart/daemon/task-scheduler.js +117 -39
  215. package/dist/heart/daemon/terminal-ui.js +499 -0
  216. package/dist/heart/daemon/thoughts.js +138 -54
  217. package/dist/heart/daemon/up-progress.js +366 -0
  218. package/dist/heart/daemon/vault-items.js +56 -0
  219. package/dist/heart/delegation.js +1 -4
  220. package/dist/heart/external-events/router.js +1430 -0
  221. package/dist/heart/frontend-approval-runtime.js +506 -0
  222. package/dist/heart/frontend-journal.js +215 -0
  223. package/dist/heart/frontend-session-service.js +237 -0
  224. package/dist/heart/frontend-socket-client.js +164 -0
  225. package/dist/heart/frontend-socket.js +400 -0
  226. package/dist/heart/habits/habit-cancel.js +810 -0
  227. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  228. package/dist/heart/habits/habit-migration.js +194 -0
  229. package/dist/heart/habits/habit-parser.js +278 -0
  230. package/dist/heart/habits/habit-runtime-state.js +93 -0
  231. package/dist/heart/habits/habit-scheduler.js +653 -0
  232. package/dist/heart/habits/habit-session-summary.js +318 -0
  233. package/dist/heart/habits/habit-session.js +636 -0
  234. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  235. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  236. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  237. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  238. package/dist/heart/identity.js +196 -59
  239. package/dist/heart/kept-notes.js +289 -0
  240. package/dist/heart/kicks.js +1 -1
  241. package/dist/heart/machine-identity.js +161 -0
  242. package/dist/heart/mail-import-discovery.js +356 -0
  243. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  244. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  245. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  246. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  247. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  248. package/dist/heart/mailbox/mailbox-http.js +99 -0
  249. package/dist/heart/mailbox/mailbox-read.js +39 -0
  250. package/dist/heart/mailbox/mailbox-types.js +27 -0
  251. package/dist/heart/mailbox/mailbox-view.js +197 -0
  252. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  253. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  254. package/dist/heart/mailbox/readers/mail.js +375 -0
  255. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  256. package/dist/heart/mailbox/readers/sessions.js +231 -0
  257. package/dist/heart/mailbox/readers/shared.js +111 -0
  258. package/dist/heart/mcp/mcp-server.js +696 -0
  259. package/dist/heart/migrate-config.js +100 -0
  260. package/dist/heart/model-capabilities.js +11 -0
  261. package/dist/heart/orientation-frame.js +345 -0
  262. package/dist/heart/platform.js +81 -0
  263. package/dist/heart/primitives.js +1 -1
  264. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  265. package/dist/heart/private-runtime/index.js +18 -0
  266. package/dist/heart/private-runtime/ledger.js +221 -0
  267. package/dist/heart/private-runtime/policy.js +252 -0
  268. package/dist/heart/private-runtime/types.js +2 -0
  269. package/dist/heart/progress-story.js +1 -1
  270. package/dist/heart/provider-attempt.js +137 -0
  271. package/dist/heart/provider-binding-resolver.js +273 -0
  272. package/dist/heart/provider-credentials.js +449 -0
  273. package/dist/heart/provider-failover.js +311 -0
  274. package/dist/heart/provider-models.js +96 -0
  275. package/dist/heart/provider-ping.js +265 -0
  276. package/dist/heart/provider-readiness-cache.js +119 -0
  277. package/dist/heart/provider-visibility.js +188 -0
  278. package/dist/heart/providers/anthropic-token.js +131 -0
  279. package/dist/heart/providers/anthropic.js +173 -60
  280. package/dist/heart/providers/azure.js +23 -11
  281. package/dist/heart/providers/error-classification.js +127 -0
  282. package/dist/heart/providers/github-copilot.js +34 -38
  283. package/dist/heart/providers/minimax-vlm.js +189 -0
  284. package/dist/heart/providers/minimax.js +26 -8
  285. package/dist/heart/providers/openai-codex-token.js +349 -0
  286. package/dist/heart/providers/openai-codex.js +55 -40
  287. package/dist/heart/providers/openai-compatible.js +177 -0
  288. package/dist/heart/run-ledger.js +247 -0
  289. package/dist/heart/runtime-capability-check.js +170 -0
  290. package/dist/heart/runtime-credentials.js +607 -0
  291. package/dist/heart/runtime-cwd.js +87 -0
  292. package/dist/heart/sense-truth.js +22 -4
  293. package/dist/heart/session-activity.js +92 -24
  294. package/dist/heart/session-events.js +1504 -0
  295. package/dist/heart/session-playback-cli-main.js +5 -0
  296. package/dist/heart/session-playback-cli.js +36 -0
  297. package/dist/heart/session-playback.js +231 -0
  298. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  299. package/dist/heart/session-redaction-repair.js +552 -0
  300. package/dist/heart/session-stats-cli-main.js +5 -0
  301. package/dist/heart/session-stats.js +183 -0
  302. package/dist/heart/session-transcript.js +133 -0
  303. package/dist/heart/start-of-turn-packet.js +372 -0
  304. package/dist/heart/steward-policy.js +626 -0
  305. package/dist/heart/streaming.js +604 -207
  306. package/dist/heart/structured-output.js +196 -0
  307. package/dist/heart/sync-classification.js +176 -0
  308. package/dist/heart/sync.js +505 -0
  309. package/dist/heart/target-resolution.js +11 -7
  310. package/dist/heart/tempo.js +93 -0
  311. package/dist/heart/temporal-view.js +41 -0
  312. package/dist/heart/timeouts.js +101 -0
  313. package/dist/heart/tool-activity-callbacks.js +59 -0
  314. package/dist/heart/tool-approval.js +382 -0
  315. package/dist/heart/tool-description.js +155 -0
  316. package/dist/heart/tool-friction.js +55 -0
  317. package/dist/heart/tool-loop.js +200 -0
  318. package/dist/heart/turn-context.js +487 -0
  319. package/dist/heart/turn-execution-lease.js +30 -0
  320. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  321. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  322. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  323. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  324. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  325. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  326. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  327. package/dist/heart/versioning/update-hooks.js +154 -0
  328. package/dist/heart/versioning/version-intent.js +114 -0
  329. package/dist/heart/work-card.js +380 -0
  330. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  331. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  332. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  333. package/dist/mailbox-ui/index.html +16 -0
  334. package/dist/mailroom/attention.js +167 -0
  335. package/dist/mailroom/autonomy.js +209 -0
  336. package/dist/mailroom/blob-store.js +889 -0
  337. package/dist/mailroom/body-cache.js +61 -0
  338. package/dist/mailroom/cache-sync-cli.js +58 -0
  339. package/dist/mailroom/core.js +803 -0
  340. package/dist/mailroom/entry.js +160 -0
  341. package/dist/mailroom/file-store.js +568 -0
  342. package/dist/mailroom/hosted-cache-sync.js +384 -0
  343. package/dist/mailroom/mbox-import.js +393 -0
  344. package/dist/mailroom/migration.js +164 -0
  345. package/dist/mailroom/outbound.js +380 -0
  346. package/dist/mailroom/policy.js +263 -0
  347. package/dist/mailroom/reader.js +292 -0
  348. package/dist/mailroom/search-cache.js +513 -0
  349. package/dist/mailroom/search-relevance.js +319 -0
  350. package/dist/mailroom/smtp-ingress.js +176 -0
  351. package/dist/mailroom/source-state.js +176 -0
  352. package/dist/mailroom/thread.js +109 -0
  353. package/dist/mailroom/travel-extract.js +89 -0
  354. package/dist/mind/bundle-manifest.js +24 -2
  355. package/dist/mind/context.js +309 -111
  356. package/dist/mind/desk-section.js +362 -0
  357. package/dist/mind/diary-integrity.js +60 -0
  358. package/dist/mind/{memory.js → diary.js} +68 -77
  359. package/dist/mind/embedding-provider.js +60 -0
  360. package/dist/mind/file-state.js +179 -0
  361. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  362. package/dist/mind/obligation-steering.js +199 -3
  363. package/dist/mind/pending.js +36 -10
  364. package/dist/mind/prompt-budget.js +479 -0
  365. package/dist/mind/prompt-refresh.js +3 -2
  366. package/dist/mind/prompt.js +1048 -198
  367. package/dist/mind/provenance-trust.js +26 -0
  368. package/dist/mind/record-paths.js +312 -0
  369. package/dist/mind/scrutiny.js +173 -0
  370. package/dist/mind/session-transaction.js +564 -0
  371. package/dist/nerves/cli-logging.js +7 -1
  372. package/dist/nerves/coverage/audit-rules.js +15 -6
  373. package/dist/nerves/coverage/audit.js +28 -2
  374. package/dist/nerves/coverage/cli.js +1 -1
  375. package/dist/nerves/coverage/contract.js +5 -5
  376. package/dist/nerves/coverage/file-completeness.js +139 -5
  377. package/dist/nerves/coverage/run-artifacts.js +55 -35
  378. package/dist/nerves/coverage/source-scanner.js +4 -4
  379. package/dist/nerves/event-buffer.js +111 -0
  380. package/dist/nerves/index.js +293 -9
  381. package/dist/nerves/observation.js +20 -0
  382. package/dist/nerves/redact.js +79 -0
  383. package/dist/nerves/review/cli-main.js +5 -0
  384. package/dist/nerves/review/cli.js +156 -0
  385. package/dist/nerves/review/core.js +159 -0
  386. package/dist/nerves/runtime.js +17 -1
  387. package/dist/repertoire/ado-client.js +15 -56
  388. package/dist/repertoire/ado-semantic.js +16 -10
  389. package/dist/repertoire/api-client.js +97 -0
  390. package/dist/repertoire/bitwarden-store.js +1045 -0
  391. package/dist/repertoire/bundle-templates.js +71 -0
  392. package/dist/repertoire/bw-installer.js +180 -0
  393. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  394. package/dist/repertoire/coding/context-pack.js +331 -0
  395. package/dist/repertoire/coding/feedback.js +174 -32
  396. package/dist/repertoire/coding/index.js +15 -3
  397. package/dist/repertoire/coding/manager.js +159 -10
  398. package/dist/repertoire/coding/spawner.js +58 -11
  399. package/dist/repertoire/coding/tools.js +221 -15
  400. package/dist/repertoire/coding/workbench-client.js +272 -0
  401. package/dist/repertoire/coding/workbench-manager.js +346 -0
  402. package/dist/repertoire/commerce-errors.js +109 -0
  403. package/dist/repertoire/commerce-self-test.js +156 -0
  404. package/dist/repertoire/credential-access.js +178 -0
  405. package/dist/repertoire/desk/classifier.js +362 -0
  406. package/dist/repertoire/duffel-client.js +185 -0
  407. package/dist/repertoire/github-client.js +14 -55
  408. package/dist/repertoire/graph-client.js +11 -52
  409. package/dist/repertoire/guardrails.js +811 -18
  410. package/dist/repertoire/mcp-client.js +44 -3
  411. package/dist/repertoire/mcp-manager.js +427 -139
  412. package/dist/repertoire/mcp-tools.js +124 -0
  413. package/dist/repertoire/plugin-mcp.js +175 -0
  414. package/dist/repertoire/plugins.js +253 -0
  415. package/dist/repertoire/relationship-authorization.js +322 -0
  416. package/dist/repertoire/shell-sessions.js +134 -0
  417. package/dist/repertoire/skills.js +48 -4
  418. package/dist/repertoire/stripe-client.js +131 -0
  419. package/dist/repertoire/tool-arguments.js +170 -0
  420. package/dist/repertoire/tool-results.js +29 -0
  421. package/dist/repertoire/tools-a2a.js +699 -0
  422. package/dist/repertoire/tools-attachments.js +322 -0
  423. package/dist/repertoire/tools-awaiting.js +575 -0
  424. package/dist/repertoire/tools-base.js +77 -1168
  425. package/dist/repertoire/tools-bluebubbles.js +2 -0
  426. package/dist/repertoire/tools-bridge.js +144 -0
  427. package/dist/repertoire/tools-bundle.js +993 -0
  428. package/dist/repertoire/tools-commerce.js +253 -0
  429. package/dist/repertoire/tools-config.js +186 -0
  430. package/dist/repertoire/tools-continuity.js +575 -0
  431. package/dist/repertoire/tools-credential.js +383 -0
  432. package/dist/repertoire/tools-evolution.js +527 -0
  433. package/dist/repertoire/tools-files.js +344 -0
  434. package/dist/repertoire/tools-flight.js +290 -0
  435. package/dist/repertoire/tools-flow.js +119 -0
  436. package/dist/repertoire/tools-github.js +3 -8
  437. package/dist/repertoire/tools-habits.js +103 -0
  438. package/dist/repertoire/tools-mail.js +1828 -0
  439. package/dist/repertoire/tools-notes.js +485 -0
  440. package/dist/repertoire/tools-obligations.js +182 -0
  441. package/dist/repertoire/tools-orientation.js +31 -0
  442. package/dist/repertoire/tools-record.js +482 -0
  443. package/dist/repertoire/tools-rsvp.js +139 -0
  444. package/dist/repertoire/tools-runtime.js +150 -0
  445. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  446. package/dist/repertoire/tools-session.js +1133 -0
  447. package/dist/repertoire/tools-shell.js +149 -0
  448. package/dist/repertoire/tools-steward-policy.js +136 -0
  449. package/dist/repertoire/tools-stripe.js +224 -0
  450. package/dist/repertoire/tools-surface.js +369 -0
  451. package/dist/repertoire/tools-teams.js +12 -39
  452. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  453. package/dist/repertoire/tools-travel.js +125 -0
  454. package/dist/repertoire/tools-trip.js +982 -0
  455. package/dist/repertoire/tools-unraid.js +531 -0
  456. package/dist/repertoire/tools-user-profile.js +146 -0
  457. package/dist/repertoire/tools-vault.js +40 -0
  458. package/dist/repertoire/tools-voice.js +145 -0
  459. package/dist/repertoire/tools.js +504 -156
  460. package/dist/repertoire/travel-api-client.js +360 -0
  461. package/dist/repertoire/unraid-client.js +155 -0
  462. package/dist/repertoire/unraid-restart.js +339 -0
  463. package/dist/repertoire/user-profile.js +131 -0
  464. package/dist/repertoire/vault-setup.js +246 -0
  465. package/dist/repertoire/vault-unlock.js +628 -0
  466. package/dist/rsvp/aisleplanner-client.js +354 -0
  467. package/dist/rsvp/cli.js +926 -0
  468. package/dist/rsvp/config.js +327 -0
  469. package/dist/rsvp/cutover.js +433 -0
  470. package/dist/rsvp/diagnostics.js +232 -0
  471. package/dist/rsvp/diff-renderer.js +176 -0
  472. package/dist/rsvp/habit-policy.js +110 -0
  473. package/dist/rsvp/habit-stage.js +123 -0
  474. package/dist/rsvp/incident-bundle.js +97 -0
  475. package/dist/rsvp/migration.js +204 -0
  476. package/dist/rsvp/native-habit-runner.js +630 -0
  477. package/dist/rsvp/outbound-state.js +628 -0
  478. package/dist/rsvp/query.js +118 -0
  479. package/dist/rsvp/replay.js +233 -0
  480. package/dist/rsvp/snapshot.js +232 -0
  481. package/dist/rsvp/spend-ledger.js +175 -0
  482. package/dist/scripts/claude-code-hook.js +41 -0
  483. package/dist/scripts/claude-code-stop-hook.js +47 -0
  484. package/dist/senses/a2a-entry.js +126 -0
  485. package/dist/senses/acp-server.js +386 -0
  486. package/dist/senses/attention-queue.js +186 -0
  487. package/dist/senses/await-turn-message.js +58 -0
  488. package/dist/senses/bluebubbles/active-turns.js +216 -0
  489. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  490. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  491. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  492. package/dist/senses/bluebubbles/context-packet.js +207 -0
  493. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  494. package/dist/senses/bluebubbles/entry.js +90 -0
  495. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  496. package/dist/senses/bluebubbles/index.js +3841 -0
  497. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  498. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  499. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  500. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  501. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  502. package/dist/senses/bluebubbles/processed-log.js +133 -0
  503. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  504. package/dist/senses/bluebubbles/replay.js +284 -0
  505. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  506. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  507. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  508. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  509. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  510. package/dist/senses/cli/bracketed-paste.js +82 -0
  511. package/dist/senses/cli/image-paste.js +287 -0
  512. package/dist/senses/cli/image-ref-navigation.js +75 -0
  513. package/dist/senses/cli/ink-app.js +156 -0
  514. package/dist/senses/cli/inline-diff.js +64 -0
  515. package/dist/senses/cli/input-keys.js +174 -0
  516. package/dist/senses/cli/kill-ring.js +86 -0
  517. package/dist/senses/cli/message-list.js +51 -0
  518. package/dist/senses/cli/ouro-tui.js +607 -0
  519. package/dist/senses/cli/spinner-imperative.js +135 -0
  520. package/dist/senses/cli/spinner.js +101 -0
  521. package/dist/senses/cli/status-line.js +60 -0
  522. package/dist/senses/cli/streaming-markdown.js +526 -0
  523. package/dist/senses/cli/tool-display.js +85 -0
  524. package/dist/senses/cli/tool-render.js +85 -0
  525. package/dist/senses/cli/tui-store.js +241 -0
  526. package/dist/senses/cli/virtual-list.js +35 -0
  527. package/dist/senses/cli-entry.js +60 -8
  528. package/dist/senses/cli.js +604 -320
  529. package/dist/senses/commands.js +66 -3
  530. package/dist/senses/context-packet-ledger.js +371 -0
  531. package/dist/senses/context-packets.js +154 -0
  532. package/dist/senses/habit-lifecycle-guard.js +24 -0
  533. package/dist/senses/habit-turn-message.js +160 -0
  534. package/dist/senses/ingress-evidence.js +2 -0
  535. package/dist/senses/mail-entry.js +66 -0
  536. package/dist/senses/mail.js +524 -0
  537. package/dist/senses/pipeline.js +1115 -204
  538. package/dist/senses/private-runtime-worker.js +859 -0
  539. package/dist/senses/private-runtime.js +1517 -0
  540. package/dist/senses/proactive-content-guard.js +51 -0
  541. package/dist/senses/root-host-approval-port.js +345 -0
  542. package/dist/senses/root-host-approval-runtime.js +393 -0
  543. package/dist/senses/sanctuary-authority-resident.js +102 -0
  544. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  545. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  546. package/dist/senses/sanctuary-grounding.js +118 -0
  547. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  548. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  549. package/dist/senses/sanctuary-health-runner.js +100 -0
  550. package/dist/senses/sanctuary-health.js +408 -0
  551. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  552. package/dist/senses/sanctuary-interactive-control.js +410 -0
  553. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  554. package/dist/senses/sanctuary-media-optimization.js +514 -0
  555. package/dist/senses/sanctuary-runtime.js +340 -0
  556. package/dist/senses/sanctuary-sab.js +85 -0
  557. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  558. package/dist/senses/shared-turn.js +789 -0
  559. package/dist/senses/surface-tool.js +109 -0
  560. package/dist/senses/teams-entry.js +60 -8
  561. package/dist/senses/teams.js +519 -218
  562. package/dist/senses/telegram-admission.js +718 -0
  563. package/dist/senses/telegram-approval-runtime.js +793 -0
  564. package/dist/senses/telegram-attachments.js +186 -0
  565. package/dist/senses/telegram-audit-ledger.js +220 -0
  566. package/dist/senses/telegram-authority-transport.js +231 -0
  567. package/dist/senses/telegram-client.js +1749 -0
  568. package/dist/senses/telegram-effect-adapter.js +896 -0
  569. package/dist/senses/telegram-entry.js +83 -0
  570. package/dist/senses/telegram.js +2347 -0
  571. package/dist/senses/trust-gate.js +104 -9
  572. package/dist/senses/voice/audio-playback.js +237 -0
  573. package/dist/senses/voice/audio-routing.js +119 -0
  574. package/dist/senses/voice/elevenlabs.js +202 -0
  575. package/dist/senses/voice/floor-control.js +431 -0
  576. package/dist/senses/voice/floor-controller.js +115 -0
  577. package/dist/senses/voice/golden-path.js +116 -0
  578. package/dist/senses/voice/index.js +29 -0
  579. package/dist/senses/voice/meeting.js +113 -0
  580. package/dist/senses/voice/outbound.js +190 -0
  581. package/dist/senses/voice/phone.js +33 -0
  582. package/dist/senses/voice/playback.js +139 -0
  583. package/dist/senses/voice/realtime-eval.js +496 -0
  584. package/dist/senses/voice/realtime-trace.js +531 -0
  585. package/dist/senses/voice/transcript.js +70 -0
  586. package/dist/senses/voice/turn.js +191 -0
  587. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  588. package/dist/senses/voice/twilio-phone.js +5031 -0
  589. package/dist/senses/voice/types.js +2 -0
  590. package/dist/senses/voice/whisper.js +161 -0
  591. package/dist/senses/voice-entry.js +81 -0
  592. package/dist/senses/voice-realtime-eval-command.js +99 -0
  593. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  594. package/dist/senses/voice-twilio-entry.js +87 -0
  595. package/dist/trips/core.js +138 -0
  596. package/dist/trips/store.js +265 -0
  597. package/dist/util/frontmatter.js +69 -0
  598. package/npm-shrinkwrap.json +8096 -0
  599. package/package.json +72 -13
  600. package/skills/agent-commerce.md +113 -0
  601. package/skills/browser-navigation.md +117 -0
  602. package/skills/commerce-setup-guide.md +116 -0
  603. package/skills/commerce-setup.md +84 -0
  604. package/skills/configure-dev-tools.md +99 -0
  605. package/skills/travel-planning.md +138 -0
  606. package/dist/heart/daemon/auth-flow.js +0 -430
  607. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  608. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  609. package/dist/heart/daemon/update-hooks.js +0 -138
  610. package/dist/heart/obligations.js +0 -191
  611. package/dist/heart/safe-workspace.js +0 -269
  612. package/dist/heart/session-recall.js +0 -116
  613. package/dist/mind/friends/channel.js +0 -84
  614. package/dist/mind/friends/group-context.js +0 -144
  615. package/dist/mind/friends/resolver.js +0 -84
  616. package/dist/mind/friends/store-file.js +0 -190
  617. package/dist/mind/friends/store.js +0 -4
  618. package/dist/mind/friends/tokens.js +0 -26
  619. package/dist/mind/friends/trust-explanation.js +0 -74
  620. package/dist/mind/friends/types.js +0 -29
  621. package/dist/repertoire/tasks/board.js +0 -134
  622. package/dist/repertoire/tasks/index.js +0 -224
  623. package/dist/repertoire/tasks/lifecycle.js +0 -80
  624. package/dist/repertoire/tasks/middleware.js +0 -65
  625. package/dist/repertoire/tasks/parser.js +0 -173
  626. package/dist/repertoire/tasks/scanner.js +0 -132
  627. package/dist/repertoire/tasks/transitions.js +0 -144
  628. package/dist/senses/bluebubbles-entry.js +0 -13
  629. package/dist/senses/bluebubbles.js +0 -1181
  630. package/dist/senses/debug-activity.js +0 -154
  631. package/dist/senses/inner-dialog-worker.js +0 -90
  632. package/dist/senses/inner-dialog.js +0 -525
  633. package/subagents/README.md +0 -7
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  643. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  644. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  645. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  646. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  647. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  648. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  649. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  650. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -33,18 +33,28 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateSessionMessages = exports.repairSessionMessages = exports.migrateToolNames = exports.detectDuplicateToolCallIds = void 0;
36
37
  exports.trimMessages = trimMessages;
37
- exports.validateSessionMessages = validateSessionMessages;
38
- exports.repairSessionMessages = repairSessionMessages;
39
38
  exports.saveSession = saveSession;
39
+ exports.appendSyntheticAssistantMessage = appendSyntheticAssistantMessage;
40
40
  exports.loadSession = loadSession;
41
41
  exports.postTurn = postTurn;
42
+ exports.postTurnTrim = postTurnTrim;
43
+ exports.postTurnPersist = postTurnPersist;
44
+ exports.deferPostTurnPersist = deferPostTurnPersist;
42
45
  exports.deleteSession = deleteSession;
43
46
  const config_1 = require("../heart/config");
47
+ const session_events_1 = require("../heart/session-events");
44
48
  const runtime_1 = require("../nerves/runtime");
45
49
  const fs = __importStar(require("fs"));
46
- const path = __importStar(require("path"));
50
+ const session_transaction_1 = require("./session-transaction");
47
51
  const token_estimate_1 = require("./token-estimate");
52
+ var session_events_2 = require("../heart/session-events");
53
+ Object.defineProperty(exports, "detectDuplicateToolCallIds", { enumerable: true, get: function () { return session_events_2.detectDuplicateToolCallIds; } });
54
+ Object.defineProperty(exports, "migrateToolNames", { enumerable: true, get: function () { return session_events_2.migrateToolNames; } });
55
+ Object.defineProperty(exports, "repairSessionMessages", { enumerable: true, get: function () { return session_events_2.repairSessionMessages; } });
56
+ Object.defineProperty(exports, "validateSessionMessages", { enumerable: true, get: function () { return session_events_2.validateSessionMessages; } });
57
+ const IDLE_REST_ONLY_KEEP_TURNS = 20;
48
58
  function buildTrimmableBlocks(messages) {
49
59
  const blocks = [];
50
60
  let i = 0;
@@ -86,6 +96,89 @@ function getSystemMessageIndices(messages) {
86
96
  function buildTrimmedMessages(messages, kept) {
87
97
  return messages.filter((m, idx) => m.role === "system" || kept.has(idx));
88
98
  }
99
+ function messageContentToText(content) {
100
+ if (typeof content === "string")
101
+ return content;
102
+ if (!Array.isArray(content))
103
+ return "";
104
+ return content
105
+ .map((part) => {
106
+ if (part && typeof part === "object" && "text" in part && typeof part.text === "string") {
107
+ return part.text;
108
+ }
109
+ return "";
110
+ })
111
+ .join("\n");
112
+ }
113
+ function toolCallName(toolCall) {
114
+ return toolCall.function.name;
115
+ }
116
+ function toolCallId(toolCall) {
117
+ return toolCall.id;
118
+ }
119
+ function isIdleHeartbeatRestUserMessage(message) {
120
+ if (message.role !== "user")
121
+ return false;
122
+ const text = messageContentToText(message.content);
123
+ return text.includes("...time passing. anything stirring?")
124
+ && !text.includes("[pending from ")
125
+ && !text.includes("## task:");
126
+ }
127
+ function isEmptyRestOnlyAssistantMessage(message) {
128
+ if (message.role !== "assistant")
129
+ return null;
130
+ if (messageContentToText(message.content).trim())
131
+ return null;
132
+ if (!Array.isArray(message.tool_calls) || message.tool_calls.length !== 1)
133
+ return null;
134
+ const onlyToolCall = message.tool_calls[0];
135
+ if (toolCallName(onlyToolCall) !== "rest")
136
+ return null;
137
+ return toolCallId(onlyToolCall);
138
+ }
139
+ function isMatchingToolResult(message, toolId) {
140
+ return message.tool_call_id === toolId;
141
+ }
142
+ function compactIdleRestOnlyTurns(messages, keepTurns = IDLE_REST_ONLY_KEEP_TURNS) {
143
+ const blocks = [];
144
+ let i = 0;
145
+ while (i < messages.length - 2) {
146
+ const userMessage = messages[i];
147
+ const assistantMessage = messages[i + 1];
148
+ const toolMessage = messages[i + 2];
149
+ const restToolId = isIdleHeartbeatRestUserMessage(userMessage)
150
+ ? isEmptyRestOnlyAssistantMessage(assistantMessage)
151
+ : null;
152
+ if (restToolId && isMatchingToolResult(toolMessage, restToolId)) {
153
+ blocks.push({ start: i, end: i + 2 });
154
+ i += 3;
155
+ continue;
156
+ }
157
+ i++;
158
+ }
159
+ if (blocks.length <= keepTurns)
160
+ return messages;
161
+ const drop = new Set();
162
+ for (const block of blocks.slice(0, blocks.length - keepTurns)) {
163
+ for (let index = block.start; index <= block.end; index++) {
164
+ drop.add(index);
165
+ }
166
+ }
167
+ const compacted = messages.filter((_message, index) => !drop.has(index));
168
+ (0, runtime_1.emitNervesEvent)({
169
+ component: "mind",
170
+ event: "mind.session_idle_rest_compaction",
171
+ message: "compacted old idle rest-only private-runtime turns",
172
+ meta: {
173
+ removedTurns: blocks.length - keepTurns,
174
+ keptTurns: keepTurns,
175
+ removedMessages: drop.size,
176
+ originalCount: messages.length,
177
+ finalCount: compacted.length,
178
+ },
179
+ });
180
+ return compacted;
181
+ }
89
182
  function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
90
183
  const targetTokens = Math.floor(maxTokens * (1 - contextMargin / 100));
91
184
  const estimatedBefore = (0, token_estimate_1.estimateTokensForMessages)(messages);
@@ -173,122 +266,116 @@ function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
173
266
  * user → assistant (with optional tool calls/results) → user → assistant...
174
267
  * Never assistant → assistant without a user in between.
175
268
  */
176
- function validateSessionMessages(messages) {
177
- const violations = [];
178
- let prevNonToolRole = null;
179
- let prevAssistantHadToolCalls = false;
180
- let sawToolResultSincePrevAssistant = false;
181
- for (let i = 0; i < messages.length; i++) {
182
- const msg = messages[i];
183
- if (msg.role === "system")
184
- continue;
185
- if (msg.role === "tool") {
186
- sawToolResultSincePrevAssistant = true;
187
- continue;
188
- }
189
- if (msg.role === "assistant" && prevNonToolRole === "assistant") {
190
- // assistant → tool(s) → assistant is valid (tool call flow)
191
- if (!(prevAssistantHadToolCalls && sawToolResultSincePrevAssistant)) {
192
- violations.push(`back-to-back assistant at index ${i}`);
193
- }
194
- }
195
- prevAssistantHadToolCalls = msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0;
196
- sawToolResultSincePrevAssistant = false;
197
- prevNonToolRole = msg.role;
198
- }
199
- return violations;
269
+ function denormalizeContinuityState(state) {
270
+ if (!state.mustResolveBeforeHandoff && typeof state.lastFriendActivityAt !== "string")
271
+ return undefined;
272
+ return {
273
+ ...(state.mustResolveBeforeHandoff ? { mustResolveBeforeHandoff: true } : {}),
274
+ ...(typeof state.lastFriendActivityAt === "string" ? { lastFriendActivityAt: state.lastFriendActivityAt } : {}),
275
+ };
200
276
  }
201
- /**
202
- * Repairs session invariant violations by merging consecutive assistant messages.
203
- */
204
- function repairSessionMessages(messages) {
205
- const violations = validateSessionMessages(messages);
206
- if (violations.length === 0)
207
- return messages;
208
- const result = [];
209
- for (const msg of messages) {
210
- if (msg.role === "assistant" && result.length > 0) {
211
- const prev = result[result.length - 1];
212
- if (prev.role === "assistant" && !("tool_calls" in prev)) {
213
- const prevContent = typeof prev.content === "string" ? prev.content : "";
214
- const curContent = typeof msg.content === "string" ? msg.content : "";
215
- prev.content = `${prevContent}\n\n${curContent}`;
216
- continue;
217
- }
218
- }
219
- result.push(msg);
277
+ function withMutationLease(filePath, lease, work) {
278
+ if (lease) {
279
+ (0, session_transaction_1.assertSessionTurnLease)(filePath, lease);
280
+ return work(lease);
220
281
  }
221
- (0, runtime_1.emitNervesEvent)({
222
- level: "warn",
223
- event: "mind.session_invariant_repair",
224
- component: "mind",
225
- message: "repaired session invariant violations",
226
- meta: { violations },
282
+ const contextual = (0, session_transaction_1.currentSessionTurnLease)(filePath);
283
+ if (contextual)
284
+ return work(contextual);
285
+ return (0, session_transaction_1.withImmediateSessionTurnLease)(filePath, work);
286
+ }
287
+ function writeSessionEnvelopeUnderLease(filePath, envelope, lease, expectedRevision) {
288
+ const current = (0, session_transaction_1.readSessionTransaction)(filePath, lease);
289
+ (0, session_transaction_1.writeSessionTransaction)(filePath, envelope, {
290
+ lease,
291
+ expectedRevision: expectedRevision ?? current.revision,
227
292
  });
228
- return result;
229
293
  }
230
- function saveSession(filePath, messages, lastUsage, state) {
231
- const violations = validateSessionMessages(messages);
232
- if (violations.length > 0) {
233
- (0, runtime_1.emitNervesEvent)({
234
- level: "warn",
235
- event: "mind.session_invariant_violation",
236
- component: "mind",
237
- message: "session invariant violated on save",
238
- meta: { path: filePath, violations },
294
+ function saveSession(filePath, messages, lastUsage, state, lease) {
295
+ return withMutationLease(filePath, lease, (owned) => {
296
+ const existing = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
297
+ const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
298
+ const currentIngressTimes = messages.map(session_events_1.getIngressTime);
299
+ const currentIngressRelations = messages.map(session_events_1.getIngressRelations);
300
+ const sanitized = (0, session_events_1.sanitizeProviderMessages)(messages);
301
+ const { envelope } = (0, session_events_1.buildCanonicalSessionEnvelope)({
302
+ existing,
303
+ previousMessages,
304
+ currentMessages: sanitized,
305
+ trimmedMessages: sanitized,
306
+ currentIngressTimes,
307
+ currentIngressRelations,
308
+ recordedAt: new Date().toISOString(),
309
+ lastUsage: lastUsage ?? null,
310
+ state,
311
+ projectionBasis: {
312
+ maxTokens: null,
313
+ contextMargin: null,
314
+ inputTokens: lastUsage?.input_tokens ?? null,
315
+ },
316
+ });
317
+ writeSessionEnvelopeUnderLease(filePath, envelope, owned);
318
+ return envelope.events;
319
+ });
320
+ }
321
+ function appendSyntheticAssistantMessage(filePath, content, lease) {
322
+ try {
323
+ return withMutationLease(filePath, lease, (owned) => {
324
+ if (!fs.existsSync(filePath))
325
+ return false;
326
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
327
+ if (!envelope)
328
+ return false;
329
+ const updated = (0, session_events_1.appendSyntheticAssistantEvent)(envelope, content, new Date().toISOString());
330
+ writeSessionEnvelopeUnderLease(filePath, updated, owned);
331
+ (0, runtime_1.emitNervesEvent)({
332
+ component: "mind",
333
+ event: "mind.session_synthetic_message_appended",
334
+ message: "appended synthetic assistant message to session",
335
+ meta: { path: filePath, contentLength: content.length },
336
+ });
337
+ return true;
239
338
  });
240
- messages = repairSessionMessages(messages);
241
339
  }
242
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
243
- const envelope = { version: 1, messages };
244
- if (lastUsage)
245
- envelope.lastUsage = lastUsage;
246
- if (state?.mustResolveBeforeHandoff === true || typeof state?.lastFriendActivityAt === "string") {
247
- envelope.state = {
248
- ...(state?.mustResolveBeforeHandoff === true ? { mustResolveBeforeHandoff: true } : {}),
249
- ...(typeof state?.lastFriendActivityAt === "string" ? { lastFriendActivityAt: state.lastFriendActivityAt } : {}),
250
- };
340
+ catch {
341
+ return false;
251
342
  }
252
- fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
253
343
  }
254
344
  function loadSession(filePath) {
255
345
  try {
256
- const raw = fs.readFileSync(filePath, "utf-8");
257
- const data = JSON.parse(raw);
258
- if (data.version !== 1)
346
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
347
+ if (!envelope)
259
348
  return null;
260
- let messages = data.messages;
261
- const violations = validateSessionMessages(messages);
262
- if (violations.length > 0) {
263
- (0, runtime_1.emitNervesEvent)({
264
- level: "warn",
265
- event: "mind.session_invariant_violation",
266
- component: "mind",
267
- message: "session invariant violated on load",
268
- meta: { path: filePath, violations },
269
- });
270
- messages = repairSessionMessages(messages);
271
- }
272
- const rawState = data?.state && typeof data.state === "object" && data.state !== null
273
- ? data.state
274
- : undefined;
275
- const state = rawState && (rawState.mustResolveBeforeHandoff === true
276
- || typeof rawState.lastFriendActivityAt === "string")
277
- ? {
278
- ...(rawState.mustResolveBeforeHandoff === true ? { mustResolveBeforeHandoff: true } : {}),
279
- ...(typeof rawState.lastFriendActivityAt === "string" ? { lastFriendActivityAt: rawState.lastFriendActivityAt } : {}),
280
- }
281
- : undefined;
282
- return { messages, lastUsage: data.lastUsage, state };
349
+ return {
350
+ messages: (0, session_events_1.sanitizeProviderMessages)((0, session_events_1.projectProviderMessages)(envelope)),
351
+ events: envelope.events,
352
+ projectionEventIds: [...(0, session_events_1.projectedSessionEventIds)(envelope)],
353
+ structuredOutputs: envelope.structuredOutputs ?? [],
354
+ lastUsage: envelope.lastUsage ?? undefined,
355
+ state: denormalizeContinuityState(envelope.state),
356
+ };
283
357
  }
284
358
  catch {
285
359
  return null;
286
360
  }
287
361
  }
362
+ /**
363
+ * Synchronous post-turn: sanitize, trim (mutates messages in place), and persist to disk.
364
+ * For non-blocking persist, use postTurnTrim() + deferPostTurnPersist() instead.
365
+ */
288
366
  function postTurn(messages, sessPath, usage, hooks, state) {
367
+ const prepared = postTurnTrim(messages, usage, hooks);
368
+ postTurnPersist(sessPath, prepared, usage, state);
369
+ }
370
+ /**
371
+ * Synchronous phase: run hooks, sanitize, trim, and mutate the messages array in place.
372
+ * Returns the data needed by postTurnPersist / deferPostTurnPersist.
373
+ */
374
+ function postTurnTrim(messages, usage, hooks) {
375
+ const preTrimMessages = [...messages];
289
376
  if (hooks?.beforeTrim) {
290
377
  try {
291
- hooks.beforeTrim([...messages]);
378
+ hooks.beforeTrim(preTrimMessages);
292
379
  }
293
380
  catch (error) {
294
381
  (0, runtime_1.emitNervesEvent)({
@@ -303,16 +390,127 @@ function postTurn(messages, sessPath, usage, hooks, state) {
303
390
  }
304
391
  }
305
392
  const { maxTokens, contextMargin } = (0, config_1.getContextConfig)();
306
- const trimmed = trimMessages(messages, maxTokens, contextMargin, usage?.input_tokens);
307
- messages.splice(0, messages.length, ...trimmed);
308
- saveSession(sessPath, messages, usage, state);
309
- }
310
- function deleteSession(filePath) {
311
- try {
312
- fs.unlinkSync(filePath);
313
- }
314
- catch (e) {
315
- if (e instanceof Error && e.code !== "ENOENT")
316
- throw e;
393
+ const currentIngressTimes = preTrimMessages.map(session_events_1.getIngressTime);
394
+ const currentIngressRelations = preTrimMessages.map(session_events_1.getIngressRelations);
395
+ const currentMessages = (0, session_events_1.sanitizeProviderMessages)(messages);
396
+ let tokenTrimmedMessages = trimMessages(currentMessages, maxTokens, contextMargin, usage?.input_tokens);
397
+ const estimatedTokens = (0, token_estimate_1.estimateTokensForMessages)(tokenTrimmedMessages);
398
+ if (estimatedTokens > maxTokens) {
399
+ const targetTokens = Math.floor(maxTokens * (1 - contextMargin / 100));
400
+ const lastUser = tokenTrimmedMessages.findLastIndex((message) => message.role === "user");
401
+ const lastAssistant = tokenTrimmedMessages.findLastIndex((message) => message.role === "assistant");
402
+ const dropped = new Set();
403
+ let remaining = estimatedTokens;
404
+ for (const block of buildTrimmableBlocks(tokenTrimmedMessages)) {
405
+ if (remaining <= targetTokens)
406
+ break;
407
+ if (block.indices.includes(lastUser) || lastAssistant > lastUser && block.indices.includes(lastAssistant))
408
+ continue;
409
+ for (const index of block.indices)
410
+ dropped.add(index);
411
+ remaining -= block.estimatedTokens;
412
+ }
413
+ tokenTrimmedMessages = remaining > maxTokens ? [] : tokenTrimmedMessages.filter((_message, index) => !dropped.has(index));
414
+ (0, runtime_1.emitNervesEvent)({
415
+ level: tokenTrimmedMessages.length === 0 ? "warn" : "info",
416
+ event: "mind.step_end",
417
+ component: "mind",
418
+ message: "bounded post-turn projection using canonical token estimates",
419
+ meta: {
420
+ maxTokens, targetTokens, estimated_before: estimatedTokens,
421
+ estimated_after: (0, token_estimate_1.estimateTokensForMessages)(tokenTrimmedMessages),
422
+ reported_input_tokens: usage?.input_tokens ?? null,
423
+ emptyProjection: tokenTrimmedMessages.length === 0,
424
+ },
425
+ });
317
426
  }
427
+ const trimmedMessages = compactIdleRestOnlyTurns(tokenTrimmedMessages);
428
+ messages.splice(0, messages.length, ...trimmedMessages);
429
+ return { currentMessages, trimmedMessages, currentIngressTimes, currentIngressRelations, maxTokens, contextMargin };
430
+ }
431
+ /**
432
+ * Synchronous persist: load existing envelope, build canonical envelope, write to disk.
433
+ */
434
+ function postTurnPersist(sessPath, prepared, usage, state, lease, expectedRevision) {
435
+ return withMutationLease(sessPath, lease, (owned) => {
436
+ const existing = (0, session_events_1.loadSessionEnvelopeFile)(sessPath);
437
+ const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
438
+ const { envelope } = (0, session_events_1.buildCanonicalSessionEnvelope)({
439
+ existing,
440
+ previousMessages,
441
+ currentMessages: prepared.currentMessages,
442
+ trimmedMessages: prepared.trimmedMessages,
443
+ currentIngressTimes: prepared.currentIngressTimes,
444
+ currentIngressRelations: prepared.currentIngressRelations,
445
+ recordedAt: new Date().toISOString(),
446
+ lastUsage: usage ?? null,
447
+ state,
448
+ projectionBasis: {
449
+ maxTokens: prepared.maxTokens,
450
+ contextMargin: prepared.contextMargin,
451
+ inputTokens: usage?.input_tokens ?? null,
452
+ },
453
+ });
454
+ writeSessionEnvelopeUnderLease(sessPath, envelope, owned, expectedRevision);
455
+ return envelope.events;
456
+ });
457
+ }
458
+ /**
459
+ * Per-sessPath serialization queue. Without this, two concurrent
460
+ * `deferPostTurnPersist` calls (e.g. two BlueBubbles webhooks for the same
461
+ * chat firing back-to-back, or a CLI postTurn racing the private-runtime turn
462
+ * for the same MCP session) would each load the envelope, both compute the
463
+ * same "next sequence", and write events with colliding ids. The session
464
+ * file would silently accumulate duplicates and replay would diverge from
465
+ * what was actually sent on the wire.
466
+ *
467
+ * The queue is in-process only — it does not protect against multiple Node
468
+ * processes writing to the same file. The dedup-on-load behaviour in
469
+ * parseSessionEnvelope keeps cross-process races from leaving permanent
470
+ * corruption; this serializer just keeps the common (single-process) case
471
+ * race-free in the first place.
472
+ */
473
+ const sessionPersistQueues = new Map();
474
+ function enqueueSessionPersist(sessPath, fn) {
475
+ const previous = sessionPersistQueues.get(sessPath) ?? Promise.resolve();
476
+ // Chain on the previous tail. fn runs whether previous resolved or rejected,
477
+ // so one failed turn cannot block subsequent turns on the same session.
478
+ const next = previous.then(fn, fn);
479
+ // Save a swallowed-rejection sentinel as the new tail so the next caller's
480
+ // `previous.then(fn, fn)` sees a clean resolution; the original `next` still
481
+ // propagates rejection to its own caller as expected.
482
+ /* v8 ignore start -- the swallow only matters when fn rejects, which is the failure path covered separately */
483
+ const sentinel = next.then(() => undefined, () => undefined);
484
+ /* v8 ignore stop */
485
+ sessionPersistQueues.set(sessPath, sentinel);
486
+ return next;
487
+ }
488
+ /**
489
+ * Deferred persist: same as postTurnPersist but runs on the next event loop
490
+ * tick AND serializes against any other deferred persist for the same
491
+ * sessPath, so concurrent turns cannot race and produce duplicate event ids
492
+ * in the saved session.
493
+ */
494
+ function deferPostTurnPersist(sessPath, prepared, usage, state, lease, expectedRevision) {
495
+ return enqueueSessionPersist(sessPath, () => new Promise((resolve) => {
496
+ setImmediate(() => {
497
+ try {
498
+ const events = postTurnPersist(sessPath, prepared, usage, state, lease, expectedRevision);
499
+ resolve(events);
500
+ }
501
+ catch (err) {
502
+ (0, runtime_1.emitNervesEvent)({
503
+ level: "warn",
504
+ component: "mind",
505
+ event: "mind.deferred_persist_error",
506
+ message: "deferred session persist failed",
507
+ meta: { error: err instanceof Error ? err.message : String(err) },
508
+ });
509
+ resolve([]);
510
+ }
511
+ });
512
+ }));
513
+ }
514
+ function deleteSession(filePath, lease) {
515
+ withMutationLease(filePath, lease, (owned) => (0, session_transaction_1.deleteSessionTransaction)(filePath, owned));
318
516
  }