@ouro.bot/cli 0.1.0-alpha.8 → 0.1.0-alpha.800

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