@ouro.bot/cli 0.1.0-alpha.43 → 0.1.0-alpha.431

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 (338) hide show
  1. package/README.md +123 -15
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  4. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  5. package/changelog.json +2715 -0
  6. package/dist/arc/attention-types.js +8 -0
  7. package/dist/arc/cares.js +140 -0
  8. package/dist/arc/episodes.js +117 -0
  9. package/dist/arc/intentions.js +133 -0
  10. package/dist/arc/json-store.js +117 -0
  11. package/dist/arc/obligations.js +237 -0
  12. package/dist/arc/packets.js +193 -0
  13. package/dist/arc/presence.js +185 -0
  14. package/dist/arc/task-lifecycle.js +65 -0
  15. package/dist/heart/active-work.js +832 -0
  16. package/dist/heart/agent-entry.js +58 -3
  17. package/dist/heart/attachments/image-normalize.js +194 -0
  18. package/dist/heart/attachments/materialize.js +97 -0
  19. package/dist/heart/attachments/originals.js +88 -0
  20. package/dist/heart/attachments/render.js +29 -0
  21. package/dist/heart/attachments/sources/adapter.js +2 -0
  22. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  23. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  24. package/dist/heart/attachments/sources/index.js +16 -0
  25. package/dist/heart/attachments/store.js +103 -0
  26. package/dist/heart/attachments/types.js +93 -0
  27. package/dist/heart/auth/auth-flow.js +426 -0
  28. package/dist/heart/bridges/manager.js +358 -0
  29. package/dist/heart/bridges/state-machine.js +135 -0
  30. package/dist/heart/bridges/store.js +123 -0
  31. package/dist/heart/bundle-state.js +168 -0
  32. package/dist/heart/commitments.js +111 -0
  33. package/dist/heart/config-registry.js +304 -0
  34. package/dist/heart/config.js +110 -128
  35. package/dist/heart/core.js +745 -227
  36. package/dist/heart/cross-chat-delivery.js +131 -0
  37. package/dist/heart/daemon/agent-config-check.js +424 -0
  38. package/dist/heart/daemon/agent-discovery.js +79 -3
  39. package/dist/heart/daemon/agent-service.js +360 -0
  40. package/dist/heart/daemon/agentic-repair.js +214 -0
  41. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  42. package/dist/heart/daemon/cadence.js +70 -0
  43. package/dist/heart/daemon/cli-defaults.js +604 -0
  44. package/dist/heart/daemon/cli-exec.js +5234 -0
  45. package/dist/heart/daemon/cli-help.js +428 -0
  46. package/dist/heart/daemon/cli-parse.js +1156 -0
  47. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  48. package/dist/heart/daemon/cli-render.js +561 -0
  49. package/dist/heart/daemon/cli-types.js +8 -0
  50. package/dist/heart/daemon/connect-bay.js +442 -0
  51. package/dist/heart/daemon/daemon-cli.js +28 -1582
  52. package/dist/heart/daemon/daemon-entry.js +356 -3
  53. package/dist/heart/daemon/daemon-health.js +141 -0
  54. package/dist/heart/daemon/daemon-runtime-sync.js +175 -12
  55. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  56. package/dist/heart/daemon/daemon.js +684 -58
  57. package/dist/heart/daemon/doctor-types.js +8 -0
  58. package/dist/heart/daemon/doctor.js +427 -0
  59. package/dist/heart/daemon/health-monitor.js +79 -1
  60. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  61. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  62. package/dist/heart/daemon/http-health-probe.js +80 -0
  63. package/dist/heart/daemon/human-command-screens.js +140 -0
  64. package/dist/heart/daemon/human-readiness.js +114 -0
  65. package/dist/heart/daemon/inner-status.js +89 -0
  66. package/dist/heart/daemon/interactive-repair.js +307 -0
  67. package/dist/heart/daemon/launchd.js +46 -9
  68. package/dist/heart/daemon/log-tailer.js +82 -12
  69. package/dist/heart/daemon/logs-prune.js +105 -0
  70. package/dist/heart/daemon/message-router.js +2 -2
  71. package/dist/heart/daemon/os-cron-deps.js +134 -0
  72. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  73. package/dist/heart/daemon/ouro-entry.js +3 -1
  74. package/dist/heart/daemon/process-manager.js +214 -0
  75. package/dist/heart/daemon/provider-discovery.js +137 -0
  76. package/dist/heart/daemon/pulse.js +475 -0
  77. package/dist/heart/daemon/readiness-repair.js +275 -0
  78. package/dist/heart/daemon/run-hooks.js +2 -0
  79. package/dist/heart/daemon/runtime-logging.js +67 -16
  80. package/dist/heart/daemon/runtime-metadata.js +73 -0
  81. package/dist/heart/daemon/runtime-mode.js +67 -0
  82. package/dist/heart/daemon/safe-mode.js +161 -0
  83. package/dist/heart/daemon/sense-manager.js +145 -32
  84. package/dist/heart/daemon/session-id-resolver.js +131 -0
  85. package/dist/heart/daemon/skill-management-installer.js +94 -0
  86. package/dist/heart/daemon/socket-client.js +307 -0
  87. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  88. package/dist/heart/daemon/startup-tui.js +272 -0
  89. package/dist/heart/daemon/task-scheduler.js +3 -25
  90. package/dist/heart/daemon/terminal-ui.js +169 -0
  91. package/dist/heart/daemon/thoughts.js +510 -0
  92. package/dist/heart/daemon/up-progress.js +271 -0
  93. package/dist/heart/delegation.js +62 -0
  94. package/dist/heart/habits/habit-migration.js +189 -0
  95. package/dist/heart/habits/habit-parser.js +140 -0
  96. package/dist/heart/habits/habit-runtime-state.js +100 -0
  97. package/dist/heart/habits/habit-scheduler.js +372 -0
  98. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  99. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  100. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  101. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  102. package/dist/heart/identity.js +161 -65
  103. package/dist/heart/kept-notes.js +357 -0
  104. package/dist/heart/kicks.js +1 -1
  105. package/dist/heart/machine-identity.js +161 -0
  106. package/dist/heart/mcp/mcp-server.js +653 -0
  107. package/dist/heart/migrate-config.js +100 -0
  108. package/dist/heart/model-capabilities.js +59 -0
  109. package/dist/heart/outlook/outlook-http-hooks.js +64 -0
  110. package/dist/heart/outlook/outlook-http-response.js +7 -0
  111. package/dist/heart/outlook/outlook-http-routes.js +232 -0
  112. package/dist/heart/outlook/outlook-http-static.js +99 -0
  113. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  114. package/dist/heart/outlook/outlook-http.js +99 -0
  115. package/dist/heart/outlook/outlook-read.js +28 -0
  116. package/dist/heart/outlook/outlook-types.js +27 -0
  117. package/dist/heart/outlook/outlook-view.js +195 -0
  118. package/dist/heart/outlook/readers/agent-machine.js +359 -0
  119. package/dist/heart/outlook/readers/continuity-readers.js +332 -0
  120. package/dist/heart/outlook/readers/runtime-readers.js +644 -0
  121. package/dist/heart/outlook/readers/sessions.js +232 -0
  122. package/dist/heart/outlook/readers/shared.js +111 -0
  123. package/dist/heart/platform.js +81 -0
  124. package/dist/heart/progress-story.js +42 -0
  125. package/dist/heart/provider-attempt.js +133 -0
  126. package/dist/heart/provider-binding-resolver.js +239 -0
  127. package/dist/heart/provider-credentials.js +391 -0
  128. package/dist/heart/provider-failover.js +266 -0
  129. package/dist/heart/provider-models.js +81 -0
  130. package/dist/heart/provider-ping.js +237 -0
  131. package/dist/heart/provider-state.js +216 -0
  132. package/dist/heart/provider-visibility.js +186 -0
  133. package/dist/heart/providers/anthropic-token.js +131 -0
  134. package/dist/heart/providers/anthropic.js +193 -55
  135. package/dist/heart/providers/azure.js +103 -12
  136. package/dist/heart/providers/error-classification.js +63 -0
  137. package/dist/heart/providers/github-copilot.js +145 -0
  138. package/dist/heart/providers/minimax-vlm.js +189 -0
  139. package/dist/heart/providers/minimax.js +29 -7
  140. package/dist/heart/providers/openai-codex.js +62 -38
  141. package/dist/heart/runtime-capability-check.js +170 -0
  142. package/dist/heart/runtime-credentials.js +260 -0
  143. package/dist/heart/sense-truth.js +3 -0
  144. package/dist/heart/session-activity.js +190 -0
  145. package/dist/heart/session-events.js +855 -0
  146. package/dist/heart/session-transcript.js +167 -0
  147. package/dist/heart/start-of-turn-packet.js +345 -0
  148. package/dist/heart/streaming.js +36 -27
  149. package/dist/heart/sync.js +332 -0
  150. package/dist/heart/target-resolution.js +127 -0
  151. package/dist/heart/tempo.js +93 -0
  152. package/dist/heart/temporal-view.js +41 -0
  153. package/dist/heart/tool-activity-callbacks.js +36 -0
  154. package/dist/heart/tool-description.js +135 -0
  155. package/dist/heart/tool-friction.js +55 -0
  156. package/dist/heart/tool-loop.js +200 -0
  157. package/dist/heart/turn-context.js +351 -0
  158. package/dist/heart/turn-coordinator.js +28 -0
  159. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  160. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  161. package/dist/heart/versioning/ouro-path-installer.js +301 -0
  162. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  163. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  164. package/dist/heart/{daemon → versioning}/update-checker.js +3 -1
  165. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  166. package/dist/mind/bundle-manifest.js +7 -1
  167. package/dist/mind/context.js +132 -93
  168. package/dist/mind/diary-integrity.js +60 -0
  169. package/dist/mind/{memory.js → diary.js} +74 -93
  170. package/dist/mind/embedding-provider.js +60 -0
  171. package/dist/mind/file-state.js +179 -0
  172. package/dist/mind/friends/channel.js +21 -0
  173. package/dist/mind/friends/group-context.js +144 -0
  174. package/dist/mind/friends/resolver.js +38 -1
  175. package/dist/mind/friends/store-file.js +39 -3
  176. package/dist/mind/friends/trust-explanation.js +74 -0
  177. package/dist/mind/friends/types.js +1 -1
  178. package/dist/mind/journal-index.js +161 -0
  179. package/dist/mind/note-search.js +268 -0
  180. package/dist/mind/obligation-steering.js +221 -0
  181. package/dist/mind/pending.js +66 -7
  182. package/dist/mind/prompt-refresh.js +3 -2
  183. package/dist/mind/prompt.js +947 -165
  184. package/dist/mind/provenance-trust.js +26 -0
  185. package/dist/mind/scrutiny.js +173 -0
  186. package/dist/nerves/cli-logging.js +7 -1
  187. package/dist/nerves/coverage/audit-rules.js +15 -6
  188. package/dist/nerves/coverage/audit.js +28 -2
  189. package/dist/nerves/coverage/cli.js +1 -1
  190. package/dist/nerves/coverage/contract.js +5 -5
  191. package/dist/nerves/coverage/file-completeness.js +83 -5
  192. package/dist/nerves/coverage/run-artifacts.js +1 -1
  193. package/dist/nerves/event-buffer.js +111 -0
  194. package/dist/nerves/index.js +224 -4
  195. package/dist/nerves/observation.js +20 -0
  196. package/dist/nerves/redact.js +79 -0
  197. package/dist/nerves/runtime.js +5 -1
  198. package/dist/outlook-ui/assets/index-BAcU08c-.css +1 -0
  199. package/dist/outlook-ui/assets/index-D7l3l4vY.js +61 -0
  200. package/dist/outlook-ui/index.html +15 -0
  201. package/dist/repertoire/ado-client.js +15 -56
  202. package/dist/repertoire/ado-semantic.js +11 -10
  203. package/dist/repertoire/api-client.js +97 -0
  204. package/dist/repertoire/bitwarden-store.js +702 -0
  205. package/dist/repertoire/bundle-templates.js +72 -0
  206. package/dist/repertoire/bw-installer.js +79 -0
  207. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  208. package/dist/repertoire/coding/context-pack.js +330 -0
  209. package/dist/repertoire/coding/feedback.js +197 -30
  210. package/dist/repertoire/coding/manager.js +158 -9
  211. package/dist/repertoire/coding/spawner.js +55 -9
  212. package/dist/repertoire/coding/tools.js +170 -7
  213. package/dist/repertoire/commerce-errors.js +109 -0
  214. package/dist/repertoire/commerce-self-test.js +156 -0
  215. package/dist/repertoire/credential-access.js +111 -0
  216. package/dist/repertoire/duffel-client.js +185 -0
  217. package/dist/repertoire/github-client.js +14 -55
  218. package/dist/repertoire/graph-client.js +11 -52
  219. package/dist/repertoire/guardrails.js +371 -0
  220. package/dist/repertoire/mcp-client.js +255 -0
  221. package/dist/repertoire/mcp-manager.js +305 -0
  222. package/dist/repertoire/mcp-tools.js +63 -0
  223. package/dist/repertoire/shell-sessions.js +133 -0
  224. package/dist/repertoire/skills.js +15 -24
  225. package/dist/repertoire/stripe-client.js +131 -0
  226. package/dist/repertoire/tasks/board.js +43 -5
  227. package/dist/repertoire/tasks/fix.js +182 -0
  228. package/dist/repertoire/tasks/index.js +37 -4
  229. package/dist/repertoire/tasks/lifecycle.js +2 -2
  230. package/dist/repertoire/tasks/parser.js +3 -2
  231. package/dist/repertoire/tasks/scanner.js +194 -37
  232. package/dist/repertoire/tasks/transitions.js +16 -78
  233. package/dist/repertoire/tool-results.js +29 -0
  234. package/dist/repertoire/tools-attachments.js +317 -0
  235. package/dist/repertoire/tools-base.js +42 -690
  236. package/dist/repertoire/tools-bluebubbles.js +1 -0
  237. package/dist/repertoire/tools-bridge.js +141 -0
  238. package/dist/repertoire/tools-bundle.js +984 -0
  239. package/dist/repertoire/tools-config.js +185 -0
  240. package/dist/repertoire/tools-continuity.js +248 -0
  241. package/dist/repertoire/tools-credential.js +361 -0
  242. package/dist/repertoire/tools-files.js +342 -0
  243. package/dist/repertoire/tools-flight.js +224 -0
  244. package/dist/repertoire/tools-flow.js +105 -0
  245. package/dist/repertoire/tools-github.js +1 -7
  246. package/dist/repertoire/tools-notes.js +376 -0
  247. package/dist/repertoire/tools-session.js +739 -0
  248. package/dist/repertoire/tools-shell.js +120 -0
  249. package/dist/repertoire/tools-stripe.js +180 -0
  250. package/dist/repertoire/tools-surface.js +243 -0
  251. package/dist/repertoire/tools-teams.js +9 -39
  252. package/dist/repertoire/tools-travel.js +125 -0
  253. package/dist/repertoire/tools-user-profile.js +144 -0
  254. package/dist/repertoire/tools-vault.js +40 -0
  255. package/dist/repertoire/tools.js +144 -113
  256. package/dist/repertoire/travel-api-client.js +360 -0
  257. package/dist/repertoire/user-profile.js +131 -0
  258. package/dist/repertoire/vault-setup.js +246 -0
  259. package/dist/repertoire/vault-unlock.js +421 -0
  260. package/dist/scripts/claude-code-hook.js +41 -0
  261. package/dist/scripts/claude-code-stop-hook.js +47 -0
  262. package/dist/senses/attention-queue.js +116 -0
  263. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  264. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  265. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +260 -9
  266. package/dist/senses/bluebubbles/entry.js +73 -0
  267. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  268. package/dist/senses/bluebubbles/index.js +1620 -0
  269. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  270. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  271. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +45 -3
  272. package/dist/senses/bluebubbles/replay.js +129 -0
  273. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  274. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  275. package/dist/senses/cli/bracketed-paste.js +82 -0
  276. package/dist/senses/cli/image-paste.js +287 -0
  277. package/dist/senses/cli/image-ref-navigation.js +75 -0
  278. package/dist/senses/cli/ink-app.js +156 -0
  279. package/dist/senses/cli/inline-diff.js +64 -0
  280. package/dist/senses/cli/input-keys.js +174 -0
  281. package/dist/senses/cli/kill-ring.js +86 -0
  282. package/dist/senses/cli/message-list.js +51 -0
  283. package/dist/senses/cli/ouro-tui.js +605 -0
  284. package/dist/senses/cli/spinner-imperative.js +135 -0
  285. package/dist/senses/cli/spinner.js +101 -0
  286. package/dist/senses/cli/status-line.js +60 -0
  287. package/dist/senses/cli/streaming-markdown.js +526 -0
  288. package/dist/senses/cli/tool-display.js +83 -0
  289. package/dist/senses/cli/tool-render.js +85 -0
  290. package/dist/senses/cli/tui-store.js +240 -0
  291. package/dist/senses/cli/virtual-list.js +35 -0
  292. package/dist/senses/cli-entry.js +60 -8
  293. package/dist/senses/cli-layout.js +187 -0
  294. package/dist/senses/cli.js +516 -211
  295. package/dist/senses/commands.js +66 -3
  296. package/dist/senses/habit-turn-message.js +108 -0
  297. package/dist/senses/inner-dialog-worker.js +102 -19
  298. package/dist/senses/inner-dialog.js +597 -95
  299. package/dist/senses/pipeline.js +533 -72
  300. package/dist/senses/proactive-content-guard.js +51 -0
  301. package/dist/senses/shared-turn.js +205 -0
  302. package/dist/senses/surface-tool.js +68 -0
  303. package/dist/senses/teams-entry.js +60 -8
  304. package/dist/senses/teams.js +413 -163
  305. package/dist/senses/trust-gate.js +5 -5
  306. package/package.json +32 -7
  307. package/skills/agent-commerce.md +106 -0
  308. package/skills/browser-navigation.md +117 -0
  309. package/skills/commerce-setup-guide.md +116 -0
  310. package/skills/commerce-setup.md +84 -0
  311. package/skills/configure-dev-tools.md +101 -0
  312. package/skills/travel-planning.md +138 -0
  313. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  314. package/dist/heart/daemon/subagent-installer.js +0 -134
  315. package/dist/mind/associative-recall.js +0 -209
  316. package/dist/senses/bluebubbles-entry.js +0 -11
  317. package/dist/senses/bluebubbles.js +0 -854
  318. package/dist/senses/debug-activity.js +0 -127
  319. package/subagents/README.md +0 -60
  320. package/subagents/work-doer.md +0 -235
  321. package/subagents/work-merger.md +0 -618
  322. package/subagents/work-planner.md +0 -382
  323. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  324. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  325. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  326. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  327. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  328. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  329. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  330. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  331. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  332. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  333. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  334. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  335. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  336. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  337. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  338. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -102,9 +102,11 @@ function stopUpdateChecker() {
102
102
  clearInterval(_intervalId);
103
103
  _intervalId = null;
104
104
  }
105
+ // `_end` (not `_stop`) to satisfy the nerves audit's start/end pairing
106
+ // rule — counterpart to `daemon.update_checker_start` above.
105
107
  (0, runtime_1.emitNervesEvent)({
106
108
  component: "daemon",
107
- event: "daemon.update_checker_stop",
109
+ event: "daemon.update_checker_end",
108
110
  message: "stopping update checker",
109
111
  meta: {},
110
112
  });
@@ -65,74 +65,78 @@ async function applyPendingUpdates(bundlesRoot, currentVersion) {
65
65
  message: "applying pending updates",
66
66
  meta: { bundlesRoot, currentVersion },
67
67
  });
68
- if (!fs.existsSync(bundlesRoot)) {
69
- return summary;
70
- }
71
- let entries;
72
68
  try {
73
- entries = fs.readdirSync(bundlesRoot, { withFileTypes: true });
74
- }
75
- catch {
76
- return summary;
77
- }
78
- for (const entry of entries) {
79
- if (!entry.isDirectory() || !entry.name.endsWith(".ouro"))
80
- continue;
81
- const agentRoot = path.join(bundlesRoot, entry.name);
82
- let previousVersion;
83
- const metaPath = path.join(agentRoot, "bundle-meta.json");
69
+ if (!fs.existsSync(bundlesRoot)) {
70
+ return summary;
71
+ }
72
+ let entries;
84
73
  try {
85
- if (fs.existsSync(metaPath)) {
86
- const raw = fs.readFileSync(metaPath, "utf-8");
87
- const meta = JSON.parse(raw);
88
- previousVersion = meta.runtimeVersion;
89
- if (previousVersion === currentVersion) {
90
- continue;
91
- }
92
- // Skip downgrades — only update forward
93
- if (semver.valid(previousVersion) && semver.valid(currentVersion) && semver.gte(previousVersion, currentVersion)) {
94
- (0, runtime_1.emitNervesEvent)({
95
- component: "daemon",
96
- event: "daemon.update_hook_skip_downgrade",
97
- message: "skipping downgrade",
98
- meta: { agentRoot, previousVersion, currentVersion },
99
- });
100
- continue;
101
- }
102
- }
74
+ entries = fs.readdirSync(bundlesRoot, { withFileTypes: true });
103
75
  }
104
76
  catch {
105
- // Malformed or unreadable bundle-meta.json -- treat as needing update
106
- previousVersion = undefined;
77
+ return summary;
107
78
  }
108
- const ctx = { agentRoot, currentVersion, previousVersion };
109
- for (const hook of _hooks) {
79
+ for (const entry of entries) {
80
+ if (!entry.isDirectory() || !entry.name.endsWith(".ouro"))
81
+ continue;
82
+ const agentRoot = path.join(bundlesRoot, entry.name);
83
+ let previousVersion;
84
+ const metaPath = path.join(agentRoot, "bundle-meta.json");
110
85
  try {
111
- await hook(ctx);
86
+ if (fs.existsSync(metaPath)) {
87
+ const raw = fs.readFileSync(metaPath, "utf-8");
88
+ const meta = JSON.parse(raw);
89
+ previousVersion = meta.runtimeVersion;
90
+ if (previousVersion === currentVersion) {
91
+ continue;
92
+ }
93
+ // Skip downgrades — only update forward
94
+ if (semver.valid(previousVersion) && semver.valid(currentVersion) && semver.gte(previousVersion, currentVersion)) {
95
+ (0, runtime_1.emitNervesEvent)({
96
+ component: "daemon",
97
+ event: "daemon.update_hook_skip_downgrade",
98
+ message: "skipping downgrade",
99
+ meta: { agentRoot, previousVersion, currentVersion },
100
+ });
101
+ continue;
102
+ }
103
+ }
104
+ }
105
+ catch {
106
+ // Malformed or unreadable bundle-meta.json -- treat as needing update
107
+ previousVersion = undefined;
112
108
  }
113
- catch (err) {
114
- (0, runtime_1.emitNervesEvent)({
115
- component: "daemon",
116
- event: "daemon.update_hook_error",
117
- message: "update hook threw",
118
- meta: {
119
- agentRoot,
120
- error: err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err),
121
- },
122
- });
109
+ const ctx = { agentRoot, currentVersion, previousVersion };
110
+ for (const hook of _hooks) {
111
+ try {
112
+ await hook(ctx);
113
+ }
114
+ catch (err) {
115
+ (0, runtime_1.emitNervesEvent)({
116
+ component: "daemon",
117
+ event: "daemon.update_hook_error",
118
+ message: "update hook threw",
119
+ meta: {
120
+ agentRoot,
121
+ error: err instanceof Error ? err.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(err),
122
+ },
123
+ });
124
+ }
123
125
  }
126
+ summary.updated.push({
127
+ agent: entry.name.replace(/\.ouro$/, ""),
128
+ from: previousVersion,
129
+ to: currentVersion,
130
+ });
124
131
  }
125
- summary.updated.push({
126
- agent: entry.name.replace(/\.ouro$/, ""),
127
- from: previousVersion,
128
- to: currentVersion,
132
+ return summary;
133
+ }
134
+ finally {
135
+ (0, runtime_1.emitNervesEvent)({
136
+ component: "daemon",
137
+ event: "daemon.apply_pending_updates_end",
138
+ message: "pending updates applied",
139
+ meta: { bundlesRoot },
129
140
  });
130
141
  }
131
- (0, runtime_1.emitNervesEvent)({
132
- component: "daemon",
133
- event: "daemon.apply_pending_updates_end",
134
- message: "pending updates applied",
135
- meta: { bundlesRoot },
136
- });
137
- return summary;
138
142
  }
@@ -52,7 +52,13 @@ exports.CANONICAL_BUNDLE_MANIFEST = [
52
52
  { path: "psyche/LORE.md", kind: "file" },
53
53
  { path: "psyche/TACIT.md", kind: "file" },
54
54
  { path: "psyche/ASPIRATIONS.md", kind: "file" },
55
- { path: "psyche/memory", kind: "dir" },
55
+ { path: "arc", kind: "dir" },
56
+ { path: "arc/episodes", kind: "dir" },
57
+ { path: "arc/obligations", kind: "dir" },
58
+ { path: "arc/cares", kind: "dir" },
59
+ { path: "arc/intentions", kind: "dir" },
60
+ { path: "diary", kind: "dir" },
61
+ { path: "journal", kind: "dir" },
56
62
  { path: "friends", kind: "dir" },
57
63
  { path: "state", kind: "dir" },
58
64
  { path: "tasks", kind: "dir" },
@@ -33,18 +33,26 @@ 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 = 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
50
  const path = __importStar(require("path"));
47
51
  const token_estimate_1 = require("./token-estimate");
52
+ var session_events_2 = require("../heart/session-events");
53
+ Object.defineProperty(exports, "migrateToolNames", { enumerable: true, get: function () { return session_events_2.migrateToolNames; } });
54
+ Object.defineProperty(exports, "repairSessionMessages", { enumerable: true, get: function () { return session_events_2.repairSessionMessages; } });
55
+ Object.defineProperty(exports, "validateSessionMessages", { enumerable: true, get: function () { return session_events_2.validateSessionMessages; } });
48
56
  function buildTrimmableBlocks(messages) {
49
57
  const blocks = [];
50
58
  let i = 0;
@@ -173,114 +181,94 @@ function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
173
181
  * user → assistant (with optional tool calls/results) → user → assistant...
174
182
  * Never assistant → assistant without a user in between.
175
183
  */
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;
184
+ function denormalizeContinuityState(state) {
185
+ if (!state.mustResolveBeforeHandoff && typeof state.lastFriendActivityAt !== "string")
186
+ return undefined;
187
+ return {
188
+ ...(state.mustResolveBeforeHandoff ? { mustResolveBeforeHandoff: true } : {}),
189
+ ...(typeof state.lastFriendActivityAt === "string" ? { lastFriendActivityAt: state.lastFriendActivityAt } : {}),
190
+ };
200
191
  }
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);
220
- }
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 },
227
- });
228
- return result;
192
+ function writeSessionEnvelope(filePath, envelope) {
193
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
194
+ fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
229
195
  }
230
196
  function saveSession(filePath, messages, lastUsage, state) {
231
- const violations = validateSessionMessages(messages);
232
- if (violations.length > 0) {
197
+ const existing = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
198
+ const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
199
+ const currentIngressTimes = messages.map(session_events_1.getIngressTime);
200
+ const sanitized = (0, session_events_1.sanitizeProviderMessages)(messages);
201
+ const { envelope } = (0, session_events_1.buildCanonicalSessionEnvelope)({
202
+ existing,
203
+ previousMessages,
204
+ currentMessages: sanitized,
205
+ trimmedMessages: sanitized,
206
+ currentIngressTimes,
207
+ recordedAt: new Date().toISOString(),
208
+ lastUsage: lastUsage ?? null,
209
+ state,
210
+ projectionBasis: {
211
+ maxTokens: null,
212
+ contextMargin: null,
213
+ inputTokens: lastUsage?.input_tokens ?? null,
214
+ },
215
+ });
216
+ writeSessionEnvelope(filePath, envelope);
217
+ }
218
+ function appendSyntheticAssistantMessage(filePath, content) {
219
+ try {
220
+ if (!fs.existsSync(filePath))
221
+ return false;
222
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
223
+ if (!envelope)
224
+ return false;
225
+ const updated = (0, session_events_1.appendSyntheticAssistantEvent)(envelope, content, new Date().toISOString());
226
+ writeSessionEnvelope(filePath, updated);
233
227
  (0, runtime_1.emitNervesEvent)({
234
- level: "warn",
235
- event: "mind.session_invariant_violation",
236
228
  component: "mind",
237
- message: "session invariant violated on save",
238
- meta: { path: filePath, violations },
229
+ event: "mind.session_synthetic_message_appended",
230
+ message: "appended synthetic assistant message to session",
231
+ meta: { path: filePath, contentLength: content.length },
239
232
  });
240
- messages = repairSessionMessages(messages);
233
+ return true;
241
234
  }
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) {
247
- envelope.state = { mustResolveBeforeHandoff: true };
235
+ catch {
236
+ return false;
248
237
  }
249
- fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
250
238
  }
251
239
  function loadSession(filePath) {
252
240
  try {
253
- const raw = fs.readFileSync(filePath, "utf-8");
254
- const data = JSON.parse(raw);
255
- if (data.version !== 1)
241
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
242
+ if (!envelope)
256
243
  return null;
257
- let messages = data.messages;
258
- const violations = validateSessionMessages(messages);
259
- if (violations.length > 0) {
260
- (0, runtime_1.emitNervesEvent)({
261
- level: "warn",
262
- event: "mind.session_invariant_violation",
263
- component: "mind",
264
- message: "session invariant violated on load",
265
- meta: { path: filePath, violations },
266
- });
267
- messages = repairSessionMessages(messages);
268
- }
269
- const state = data?.state && typeof data.state === "object" && data.state !== null
270
- && typeof data.state.mustResolveBeforeHandoff === "boolean"
271
- && data.state.mustResolveBeforeHandoff === true
272
- ? { mustResolveBeforeHandoff: true }
273
- : undefined;
274
- return { messages, lastUsage: data.lastUsage, state };
244
+ return {
245
+ messages: (0, session_events_1.annotateMessageTimestamps)(envelope, (0, session_events_1.projectProviderMessages)(envelope)),
246
+ events: envelope.events,
247
+ lastUsage: envelope.lastUsage ?? undefined,
248
+ state: denormalizeContinuityState(envelope.state),
249
+ };
275
250
  }
276
251
  catch {
277
252
  return null;
278
253
  }
279
254
  }
255
+ /**
256
+ * Synchronous post-turn: sanitize, trim (mutates messages in place), and persist to disk.
257
+ * For non-blocking persist, use postTurnTrim() + deferPostTurnPersist() instead.
258
+ */
280
259
  function postTurn(messages, sessPath, usage, hooks, state) {
260
+ const prepared = postTurnTrim(messages, usage, hooks);
261
+ postTurnPersist(sessPath, prepared, usage, state);
262
+ }
263
+ /**
264
+ * Synchronous phase: run hooks, sanitize, trim, and mutate the messages array in place.
265
+ * Returns the data needed by postTurnPersist / deferPostTurnPersist.
266
+ */
267
+ function postTurnTrim(messages, usage, hooks) {
268
+ const preTrimMessages = [...messages];
281
269
  if (hooks?.beforeTrim) {
282
270
  try {
283
- hooks.beforeTrim([...messages]);
271
+ hooks.beforeTrim(preTrimMessages);
284
272
  }
285
273
  catch (error) {
286
274
  (0, runtime_1.emitNervesEvent)({
@@ -295,9 +283,60 @@ function postTurn(messages, sessPath, usage, hooks, state) {
295
283
  }
296
284
  }
297
285
  const { maxTokens, contextMargin } = (0, config_1.getContextConfig)();
298
- const trimmed = trimMessages(messages, maxTokens, contextMargin, usage?.input_tokens);
299
- messages.splice(0, messages.length, ...trimmed);
300
- saveSession(sessPath, messages, usage, state);
286
+ const currentIngressTimes = messages.map(session_events_1.getIngressTime);
287
+ const currentMessages = (0, session_events_1.sanitizeProviderMessages)(messages);
288
+ const trimmedMessages = trimMessages(currentMessages, maxTokens, contextMargin, usage?.input_tokens);
289
+ messages.splice(0, messages.length, ...trimmedMessages);
290
+ return { currentMessages, trimmedMessages, currentIngressTimes, maxTokens, contextMargin };
291
+ }
292
+ /**
293
+ * Synchronous persist: load existing envelope, build canonical envelope, write to disk.
294
+ */
295
+ function postTurnPersist(sessPath, prepared, usage, state) {
296
+ const existing = (0, session_events_1.loadSessionEnvelopeFile)(sessPath);
297
+ const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
298
+ const { envelope, evictedEvents } = (0, session_events_1.buildCanonicalSessionEnvelope)({
299
+ existing,
300
+ previousMessages,
301
+ currentMessages: prepared.currentMessages,
302
+ trimmedMessages: prepared.trimmedMessages,
303
+ currentIngressTimes: prepared.currentIngressTimes,
304
+ recordedAt: new Date().toISOString(),
305
+ lastUsage: usage ?? null,
306
+ state,
307
+ projectionBasis: {
308
+ maxTokens: prepared.maxTokens,
309
+ contextMargin: prepared.contextMargin,
310
+ inputTokens: usage?.input_tokens ?? null,
311
+ },
312
+ });
313
+ (0, session_events_1.appendEvictedToArchive)(sessPath, evictedEvents);
314
+ writeSessionEnvelope(sessPath, envelope);
315
+ return envelope.events;
316
+ }
317
+ /**
318
+ * Deferred persist: same as postTurnPersist but runs on the next event loop tick.
319
+ * Returns a promise that resolves when the persist completes.
320
+ */
321
+ function deferPostTurnPersist(sessPath, prepared, usage, state) {
322
+ return new Promise((resolve) => {
323
+ setImmediate(() => {
324
+ try {
325
+ const events = postTurnPersist(sessPath, prepared, usage, state);
326
+ resolve(events);
327
+ }
328
+ catch (err) {
329
+ (0, runtime_1.emitNervesEvent)({
330
+ level: "warn",
331
+ component: "mind",
332
+ event: "mind.deferred_persist_error",
333
+ message: "deferred session persist failed",
334
+ meta: { error: err instanceof Error ? err.message : String(err) },
335
+ });
336
+ resolve([]);
337
+ }
338
+ });
339
+ });
301
340
  }
302
341
  function deleteSession(filePath) {
303
342
  try {
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectSuspiciousContent = detectSuspiciousContent;
4
+ const PATTERN_CATEGORIES = [
5
+ {
6
+ name: "instruction_framing",
7
+ patterns: [
8
+ /\byou are (?:a|an) (?:ai|assistant|language model|helpful assistant)\b/i,
9
+ /\byour (?:new )?instructions are\b/i,
10
+ /\bsystem\s*:/i,
11
+ /\bignore (?:all |my )?previous instructions\b/i,
12
+ /\bdo not reveal\b/i,
13
+ ],
14
+ },
15
+ {
16
+ name: "override_language",
17
+ patterns: [
18
+ /\bdisregard\b/i,
19
+ /\bforget everything\b/i,
20
+ /\bnew instructions:/i,
21
+ /\boverride (?:all |any |previous )?instructions\b/i,
22
+ ],
23
+ },
24
+ {
25
+ name: "role_injection",
26
+ patterns: [
27
+ /\bas (?:a|an) (?:ai|language model)\b/i,
28
+ /\byou must always\b/i,
29
+ /\byou are now\b/i,
30
+ ],
31
+ },
32
+ {
33
+ name: "boundary_markers",
34
+ patterns: [
35
+ /```system/i,
36
+ /<<SYS>>/i,
37
+ /\[INST\]/i,
38
+ /<\/?system>/i,
39
+ /\[system\]/i,
40
+ ],
41
+ },
42
+ ];
43
+ function detectSuspiciousContent(text) {
44
+ if (!text) {
45
+ return { suspicious: false, patterns: [] };
46
+ }
47
+ const matched = new Set();
48
+ for (const category of PATTERN_CATEGORIES) {
49
+ for (const pattern of category.patterns) {
50
+ if (pattern.test(text)) {
51
+ matched.add(category.name);
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ return {
57
+ suspicious: matched.size > 0,
58
+ patterns: [...matched],
59
+ };
60
+ }