@ouro.bot/cli 0.1.0-alpha.49 → 0.1.0-alpha.490

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 (365) hide show
  1. package/README.md +133 -19
  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 +3118 -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 +989 -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/background-operations.js +281 -0
  29. package/dist/heart/bridges/manager.js +37 -0
  30. package/dist/heart/bridges/state-machine.js +20 -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 +119 -129
  35. package/dist/heart/core.js +758 -227
  36. package/dist/heart/cross-chat-delivery.js +131 -0
  37. package/dist/heart/daemon/agent-config-check.js +490 -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 +216 -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 +640 -0
  44. package/dist/heart/daemon/cli-exec.js +7229 -0
  45. package/dist/heart/daemon/cli-help.js +493 -0
  46. package/dist/heart/daemon/cli-parse.js +1533 -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 +323 -0
  51. package/dist/heart/daemon/daemon-cli.js +29 -1616
  52. package/dist/heart/daemon/daemon-entry.js +345 -3
  53. package/dist/heart/daemon/daemon-health.js +141 -0
  54. package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
  55. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  56. package/dist/heart/daemon/daemon.js +677 -58
  57. package/dist/heart/daemon/dns-workflow.js +394 -0
  58. package/dist/heart/daemon/doctor-types.js +8 -0
  59. package/dist/heart/daemon/doctor.js +486 -0
  60. package/dist/heart/daemon/health-monitor.js +92 -1
  61. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  62. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  63. package/dist/heart/daemon/http-health-probe.js +80 -0
  64. package/dist/heart/daemon/human-command-screens.js +234 -0
  65. package/dist/heart/daemon/human-readiness.js +114 -0
  66. package/dist/heart/daemon/inner-status.js +89 -0
  67. package/dist/heart/daemon/interactive-repair.js +394 -0
  68. package/dist/heart/daemon/launchd.js +25 -5
  69. package/dist/heart/daemon/log-tailer.js +82 -12
  70. package/dist/heart/daemon/logs-prune.js +110 -0
  71. package/dist/heart/daemon/message-router.js +2 -2
  72. package/dist/heart/daemon/os-cron-deps.js +134 -0
  73. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  74. package/dist/heart/daemon/ouro-entry.js +3 -1
  75. package/dist/heart/daemon/process-manager.js +214 -0
  76. package/dist/heart/daemon/provider-discovery.js +137 -0
  77. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  78. package/dist/heart/daemon/pulse.js +475 -0
  79. package/dist/heart/daemon/readiness-repair.js +365 -0
  80. package/dist/heart/daemon/run-hooks.js +2 -0
  81. package/dist/heart/daemon/runtime-logging.js +67 -16
  82. package/dist/heart/daemon/runtime-metadata.js +73 -0
  83. package/dist/heart/daemon/runtime-mode.js +67 -0
  84. package/dist/heart/daemon/safe-mode.js +161 -0
  85. package/dist/heart/daemon/sense-manager.js +178 -37
  86. package/dist/heart/daemon/session-id-resolver.js +131 -0
  87. package/dist/heart/daemon/skill-management-installer.js +94 -0
  88. package/dist/heart/daemon/socket-client.js +109 -4
  89. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  90. package/dist/heart/daemon/startup-tui.js +264 -0
  91. package/dist/heart/daemon/task-scheduler.js +3 -25
  92. package/dist/heart/daemon/terminal-ui.js +499 -0
  93. package/dist/heart/daemon/thoughts.js +162 -17
  94. package/dist/heart/daemon/up-progress.js +366 -0
  95. package/dist/heart/daemon/vault-items.js +56 -0
  96. package/dist/heart/delegation.js +62 -0
  97. package/dist/heart/habits/habit-migration.js +189 -0
  98. package/dist/heart/habits/habit-parser.js +140 -0
  99. package/dist/heart/habits/habit-runtime-state.js +100 -0
  100. package/dist/heart/habits/habit-scheduler.js +372 -0
  101. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  102. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  103. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  104. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  105. package/dist/heart/identity.js +201 -66
  106. package/dist/heart/kept-notes.js +357 -0
  107. package/dist/heart/kicks.js +1 -1
  108. package/dist/heart/machine-identity.js +161 -0
  109. package/dist/heart/mail-import-discovery.js +353 -0
  110. package/dist/heart/mcp/mcp-server.js +653 -0
  111. package/dist/heart/migrate-config.js +100 -0
  112. package/dist/heart/model-capabilities.js +59 -0
  113. package/dist/heart/outlook/outlook-http-hooks.js +66 -0
  114. package/dist/heart/outlook/outlook-http-response.js +7 -0
  115. package/dist/heart/outlook/outlook-http-routes.js +244 -0
  116. package/dist/heart/outlook/outlook-http-static.js +103 -0
  117. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  118. package/dist/heart/outlook/outlook-http.js +99 -0
  119. package/dist/heart/outlook/outlook-read.js +31 -0
  120. package/dist/heart/outlook/outlook-types.js +27 -0
  121. package/dist/heart/outlook/outlook-view.js +195 -0
  122. package/dist/heart/outlook/readers/agent-machine.js +382 -0
  123. package/dist/heart/outlook/readers/continuity-readers.js +336 -0
  124. package/dist/heart/outlook/readers/mail.js +362 -0
  125. package/dist/heart/outlook/readers/runtime-readers.js +644 -0
  126. package/dist/heart/outlook/readers/sessions.js +232 -0
  127. package/dist/heart/outlook/readers/shared.js +111 -0
  128. package/dist/heart/platform.js +81 -0
  129. package/dist/heart/progress-story.js +42 -0
  130. package/dist/heart/provider-attempt.js +134 -0
  131. package/dist/heart/provider-binding-resolver.js +255 -0
  132. package/dist/heart/provider-credentials.js +424 -0
  133. package/dist/heart/provider-failover.js +301 -0
  134. package/dist/heart/provider-models.js +81 -0
  135. package/dist/heart/provider-ping.js +262 -0
  136. package/dist/heart/provider-state.js +216 -0
  137. package/dist/heart/provider-visibility.js +188 -0
  138. package/dist/heart/providers/anthropic-token.js +131 -0
  139. package/dist/heart/providers/anthropic.js +193 -55
  140. package/dist/heart/providers/azure.js +104 -13
  141. package/dist/heart/providers/error-classification.js +63 -0
  142. package/dist/heart/providers/github-copilot.js +145 -0
  143. package/dist/heart/providers/minimax-vlm.js +189 -0
  144. package/dist/heart/providers/minimax.js +29 -7
  145. package/dist/heart/providers/openai-codex.js +63 -39
  146. package/dist/heart/runtime-capability-check.js +170 -0
  147. package/dist/heart/runtime-credentials.js +260 -0
  148. package/dist/heart/sense-truth.js +11 -4
  149. package/dist/heart/session-activity.js +190 -0
  150. package/dist/heart/session-events.js +981 -0
  151. package/dist/heart/session-transcript.js +167 -0
  152. package/dist/heart/start-of-turn-packet.js +345 -0
  153. package/dist/heart/streaming.js +48 -28
  154. package/dist/heart/sync.js +332 -0
  155. package/dist/heart/target-resolution.js +127 -0
  156. package/dist/heart/tempo.js +93 -0
  157. package/dist/heart/temporal-view.js +41 -0
  158. package/dist/heart/tool-activity-callbacks.js +36 -0
  159. package/dist/heart/tool-description.js +135 -0
  160. package/dist/heart/tool-friction.js +55 -0
  161. package/dist/heart/tool-loop.js +200 -0
  162. package/dist/heart/turn-context.js +372 -0
  163. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  164. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  165. package/dist/heart/versioning/ouro-path-installer.js +425 -0
  166. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  167. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  168. package/dist/heart/{daemon → versioning}/update-checker.js +5 -1
  169. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  170. package/dist/mailroom/attention.js +167 -0
  171. package/dist/mailroom/autonomy.js +209 -0
  172. package/dist/mailroom/blob-store.js +600 -0
  173. package/dist/mailroom/core.js +658 -0
  174. package/dist/mailroom/entry.js +160 -0
  175. package/dist/mailroom/file-store.js +426 -0
  176. package/dist/mailroom/mbox-import.js +382 -0
  177. package/dist/mailroom/outbound.js +380 -0
  178. package/dist/mailroom/policy.js +263 -0
  179. package/dist/mailroom/reader.js +219 -0
  180. package/dist/mailroom/search-cache.js +182 -0
  181. package/dist/mailroom/search-relevance.js +319 -0
  182. package/dist/mailroom/smtp-ingress.js +176 -0
  183. package/dist/mailroom/source-state.js +176 -0
  184. package/dist/mailroom/travel-extract.js +89 -0
  185. package/dist/mind/bundle-manifest.js +7 -1
  186. package/dist/mind/context.js +164 -93
  187. package/dist/mind/diary-integrity.js +60 -0
  188. package/dist/mind/{memory.js → diary.js} +74 -93
  189. package/dist/mind/embedding-provider.js +60 -0
  190. package/dist/mind/file-state.js +179 -0
  191. package/dist/mind/friends/channel.js +30 -0
  192. package/dist/mind/friends/group-context.js +144 -0
  193. package/dist/mind/friends/resolver.js +54 -2
  194. package/dist/mind/friends/store-file.js +39 -3
  195. package/dist/mind/friends/trust-explanation.js +74 -0
  196. package/dist/mind/friends/types.js +2 -2
  197. package/dist/mind/journal-index.js +161 -0
  198. package/dist/mind/note-search.js +268 -0
  199. package/dist/mind/obligation-steering.js +221 -0
  200. package/dist/mind/pending.js +56 -8
  201. package/dist/mind/prompt-refresh.js +3 -2
  202. package/dist/mind/prompt.js +973 -168
  203. package/dist/mind/provenance-trust.js +26 -0
  204. package/dist/mind/scrutiny.js +173 -0
  205. package/dist/nerves/cli-logging.js +7 -1
  206. package/dist/nerves/coverage/audit-rules.js +15 -6
  207. package/dist/nerves/coverage/audit.js +28 -2
  208. package/dist/nerves/coverage/cli.js +1 -1
  209. package/dist/nerves/coverage/contract.js +5 -5
  210. package/dist/nerves/coverage/file-completeness.js +93 -5
  211. package/dist/nerves/coverage/run-artifacts.js +1 -1
  212. package/dist/nerves/event-buffer.js +111 -0
  213. package/dist/nerves/index.js +224 -4
  214. package/dist/nerves/observation.js +20 -0
  215. package/dist/nerves/redact.js +79 -0
  216. package/dist/nerves/runtime.js +5 -1
  217. package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
  218. package/dist/outlook-ui/assets/index-Cm51CY9W.js +61 -0
  219. package/dist/outlook-ui/index.html +15 -0
  220. package/dist/repertoire/ado-client.js +15 -56
  221. package/dist/repertoire/ado-semantic.js +11 -10
  222. package/dist/repertoire/api-client.js +97 -0
  223. package/dist/repertoire/bitwarden-store.js +774 -0
  224. package/dist/repertoire/bundle-templates.js +72 -0
  225. package/dist/repertoire/bw-installer.js +180 -0
  226. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  227. package/dist/repertoire/coding/context-pack.js +330 -0
  228. package/dist/repertoire/coding/feedback.js +197 -30
  229. package/dist/repertoire/coding/manager.js +158 -9
  230. package/dist/repertoire/coding/spawner.js +55 -9
  231. package/dist/repertoire/coding/tools.js +170 -7
  232. package/dist/repertoire/commerce-errors.js +109 -0
  233. package/dist/repertoire/commerce-self-test.js +156 -0
  234. package/dist/repertoire/credential-access.js +111 -0
  235. package/dist/repertoire/duffel-client.js +185 -0
  236. package/dist/repertoire/github-client.js +14 -55
  237. package/dist/repertoire/graph-client.js +11 -52
  238. package/dist/repertoire/guardrails.js +396 -0
  239. package/dist/repertoire/mcp-client.js +255 -0
  240. package/dist/repertoire/mcp-manager.js +305 -0
  241. package/dist/repertoire/mcp-tools.js +63 -0
  242. package/dist/repertoire/shell-sessions.js +133 -0
  243. package/dist/repertoire/skills.js +15 -24
  244. package/dist/repertoire/stripe-client.js +131 -0
  245. package/dist/repertoire/tasks/board.js +31 -5
  246. package/dist/repertoire/tasks/fix.js +182 -0
  247. package/dist/repertoire/tasks/index.js +16 -4
  248. package/dist/repertoire/tasks/lifecycle.js +2 -2
  249. package/dist/repertoire/tasks/parser.js +3 -2
  250. package/dist/repertoire/tasks/scanner.js +194 -37
  251. package/dist/repertoire/tasks/transitions.js +16 -78
  252. package/dist/repertoire/tool-results.js +29 -0
  253. package/dist/repertoire/tools-attachments.js +317 -0
  254. package/dist/repertoire/tools-base.js +46 -842
  255. package/dist/repertoire/tools-bluebubbles.js +1 -0
  256. package/dist/repertoire/tools-bridge.js +141 -0
  257. package/dist/repertoire/tools-bundle.js +984 -0
  258. package/dist/repertoire/tools-config.js +185 -0
  259. package/dist/repertoire/tools-continuity.js +248 -0
  260. package/dist/repertoire/tools-credential.js +381 -0
  261. package/dist/repertoire/tools-files.js +342 -0
  262. package/dist/repertoire/tools-flight.js +224 -0
  263. package/dist/repertoire/tools-flow.js +105 -0
  264. package/dist/repertoire/tools-github.js +1 -7
  265. package/dist/repertoire/tools-mail.js +1281 -0
  266. package/dist/repertoire/tools-notes.js +376 -0
  267. package/dist/repertoire/tools-session.js +749 -0
  268. package/dist/repertoire/tools-shell.js +120 -0
  269. package/dist/repertoire/tools-stripe.js +180 -0
  270. package/dist/repertoire/tools-surface.js +243 -0
  271. package/dist/repertoire/tools-teams.js +9 -39
  272. package/dist/repertoire/tools-travel.js +125 -0
  273. package/dist/repertoire/tools-trip.js +280 -0
  274. package/dist/repertoire/tools-user-profile.js +144 -0
  275. package/dist/repertoire/tools-vault.js +40 -0
  276. package/dist/repertoire/tools.js +144 -115
  277. package/dist/repertoire/travel-api-client.js +360 -0
  278. package/dist/repertoire/user-profile.js +131 -0
  279. package/dist/repertoire/vault-setup.js +246 -0
  280. package/dist/repertoire/vault-unlock.js +561 -0
  281. package/dist/scripts/claude-code-hook.js +41 -0
  282. package/dist/scripts/claude-code-stop-hook.js +47 -0
  283. package/dist/senses/attention-queue.js +116 -0
  284. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  285. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  286. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  287. package/dist/senses/bluebubbles/entry.js +73 -0
  288. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  289. package/dist/senses/bluebubbles/index.js +1835 -0
  290. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  291. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  292. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  293. package/dist/senses/bluebubbles/processed-log.js +111 -0
  294. package/dist/senses/bluebubbles/replay.js +129 -0
  295. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -2
  296. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  297. package/dist/senses/cli/bracketed-paste.js +82 -0
  298. package/dist/senses/cli/image-paste.js +287 -0
  299. package/dist/senses/cli/image-ref-navigation.js +75 -0
  300. package/dist/senses/cli/ink-app.js +156 -0
  301. package/dist/senses/cli/inline-diff.js +64 -0
  302. package/dist/senses/cli/input-keys.js +174 -0
  303. package/dist/senses/cli/kill-ring.js +86 -0
  304. package/dist/senses/cli/message-list.js +51 -0
  305. package/dist/senses/cli/ouro-tui.js +605 -0
  306. package/dist/senses/cli/spinner-imperative.js +135 -0
  307. package/dist/senses/cli/spinner.js +101 -0
  308. package/dist/senses/cli/status-line.js +60 -0
  309. package/dist/senses/cli/streaming-markdown.js +526 -0
  310. package/dist/senses/cli/tool-display.js +83 -0
  311. package/dist/senses/cli/tool-render.js +85 -0
  312. package/dist/senses/cli/tui-store.js +240 -0
  313. package/dist/senses/cli/virtual-list.js +35 -0
  314. package/dist/senses/cli-entry.js +60 -8
  315. package/dist/senses/cli-layout.js +187 -0
  316. package/dist/senses/cli.js +515 -211
  317. package/dist/senses/commands.js +66 -3
  318. package/dist/senses/habit-turn-message.js +108 -0
  319. package/dist/senses/inner-dialog-worker.js +110 -20
  320. package/dist/senses/inner-dialog.js +408 -21
  321. package/dist/senses/mail-entry.js +66 -0
  322. package/dist/senses/mail.js +379 -0
  323. package/dist/senses/pipeline.js +588 -81
  324. package/dist/senses/proactive-content-guard.js +51 -0
  325. package/dist/senses/shared-turn.js +205 -0
  326. package/dist/senses/surface-tool.js +68 -0
  327. package/dist/senses/teams-entry.js +60 -8
  328. package/dist/senses/teams.js +412 -163
  329. package/dist/senses/trust-gate.js +100 -5
  330. package/dist/trips/core.js +138 -0
  331. package/dist/trips/store.js +146 -0
  332. package/package.json +37 -7
  333. package/skills/agent-commerce.md +106 -0
  334. package/skills/browser-navigation.md +117 -0
  335. package/skills/commerce-setup-guide.md +116 -0
  336. package/skills/commerce-setup.md +84 -0
  337. package/skills/configure-dev-tools.md +101 -0
  338. package/skills/travel-planning.md +138 -0
  339. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  340. package/dist/heart/daemon/subagent-installer.js +0 -166
  341. package/dist/heart/session-recall.js +0 -116
  342. package/dist/mind/associative-recall.js +0 -209
  343. package/dist/senses/bluebubbles-entry.js +0 -13
  344. package/dist/senses/bluebubbles.js +0 -1032
  345. package/dist/senses/debug-activity.js +0 -127
  346. package/subagents/README.md +0 -86
  347. package/subagents/work-doer.md +0 -237
  348. package/subagents/work-merger.md +0 -618
  349. package/subagents/work-planner.md +0 -390
  350. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  351. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  352. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  353. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  354. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  355. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  356. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  357. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  358. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  359. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  360. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  361. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  362. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  363. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  364. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  365. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.cosineSimilarity = cosineSimilarity;
37
+ exports.searchDiaryFactsForQuery = searchDiaryFactsForQuery;
38
+ exports.searchJournalIndex = searchJournalIndex;
39
+ exports.injectNoteSearchContext = injectNoteSearchContext;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const runtime_1 = require("../nerves/runtime");
43
+ const diary_1 = require("./diary");
44
+ const provenance_trust_1 = require("./provenance-trust");
45
+ const embedding_provider_1 = require("./embedding-provider");
46
+ const DEFAULT_MIN_SCORE = 0.5;
47
+ const DEFAULT_TOP_K = 3;
48
+ function createDefaultProvider() {
49
+ const provider = (0, embedding_provider_1.createDefaultEmbeddingProvider)();
50
+ if (!provider) {
51
+ throw new Error("openaiEmbeddingsApiKey not configured");
52
+ }
53
+ return provider;
54
+ }
55
+ function readFacts(diaryRoot) {
56
+ const factsPath = path.join(diaryRoot, "facts.jsonl");
57
+ if (!fs.existsSync(factsPath))
58
+ return [];
59
+ const raw = fs.readFileSync(factsPath, "utf8").trim();
60
+ if (!raw)
61
+ return [];
62
+ const facts = [];
63
+ for (const line of raw.split("\n")) {
64
+ const trimmed = line.trim();
65
+ if (!trimmed)
66
+ continue;
67
+ try {
68
+ facts.push(JSON.parse(trimmed));
69
+ }
70
+ catch {
71
+ // Skip corrupt lines (e.g. partial write from a crash).
72
+ }
73
+ }
74
+ return facts;
75
+ }
76
+ function getLatestUserText(messages) {
77
+ for (let i = messages.length - 1; i >= 0; i--) {
78
+ const message = messages[i];
79
+ if (message.role !== "user")
80
+ continue;
81
+ if (typeof message.content !== "string")
82
+ continue;
83
+ const text = message.content.trim();
84
+ if (text.length > 0)
85
+ return text;
86
+ }
87
+ return "";
88
+ }
89
+ function cosineSimilarity(left, right) {
90
+ if (left.length === 0 || right.length === 0 || left.length !== right.length)
91
+ return 0;
92
+ let dot = 0;
93
+ let leftNorm = 0;
94
+ let rightNorm = 0;
95
+ for (let i = 0; i < left.length; i++) {
96
+ dot += left[i] * right[i];
97
+ leftNorm += left[i] * left[i];
98
+ rightNorm += right[i] * right[i];
99
+ }
100
+ if (leftNorm === 0 || rightNorm === 0)
101
+ return 0;
102
+ return dot / (Math.sqrt(leftNorm) * Math.sqrt(rightNorm));
103
+ }
104
+ async function searchDiaryFactsForQuery(query, facts, provider, options) {
105
+ const trimmed = query.trim();
106
+ if (!trimmed)
107
+ return [];
108
+ const minScore = options?.minScore ?? DEFAULT_MIN_SCORE;
109
+ const topK = options?.topK ?? DEFAULT_TOP_K;
110
+ const [queryEmbedding] = await provider.embed([trimmed]);
111
+ return facts
112
+ .map((fact) => ({
113
+ ...fact,
114
+ score: cosineSimilarity(queryEmbedding, fact.embedding),
115
+ }))
116
+ .filter((fact) => fact.score >= minScore)
117
+ .sort((left, right) => right.score - left.score)
118
+ .slice(0, topK);
119
+ }
120
+ function readJournalIndex(journalDir) {
121
+ const indexPath = path.join(journalDir, ".index.json");
122
+ try {
123
+ const raw = fs.readFileSync(indexPath, "utf8");
124
+ const parsed = JSON.parse(raw);
125
+ if (!Array.isArray(parsed))
126
+ return [];
127
+ return parsed;
128
+ }
129
+ catch {
130
+ return [];
131
+ }
132
+ }
133
+ function searchJournalIndex(queryEmbedding, entries, options) {
134
+ const minScore = options?.minScore ?? DEFAULT_MIN_SCORE;
135
+ const topK = options?.topK ?? DEFAULT_TOP_K;
136
+ return entries
137
+ .filter((entry) => Array.isArray(entry.embedding) && entry.embedding.length > 0)
138
+ .map((entry) => ({
139
+ filename: entry.filename,
140
+ preview: entry.preview,
141
+ score: cosineSimilarity(queryEmbedding, entry.embedding),
142
+ }))
143
+ .filter((entry) => entry.score >= minScore)
144
+ .sort((left, right) => right.score - left.score)
145
+ .slice(0, topK);
146
+ }
147
+ function resolveJournalDir(diaryRoot, explicitJournalDir) {
148
+ if (explicitJournalDir)
149
+ return explicitJournalDir;
150
+ // journal/ is a sibling of diary/ at the agent root level
151
+ const agentRoot = path.dirname(diaryRoot);
152
+ return path.join(agentRoot, "journal");
153
+ }
154
+ async function injectNoteSearchContext(messages, options) {
155
+ try {
156
+ if (messages[0]?.role !== "system" || typeof messages[0].content !== "string")
157
+ return;
158
+ const query = getLatestUserText(messages);
159
+ if (!query)
160
+ return;
161
+ const diaryRoot = options?.diaryRoot ?? (0, diary_1.resolveDiaryRoot)();
162
+ const facts = readFacts(diaryRoot);
163
+ const journalDir = resolveJournalDir(diaryRoot, options?.journalDir);
164
+ const journalEntries = readJournalIndex(journalDir);
165
+ if (facts.length === 0 && journalEntries.length === 0)
166
+ return;
167
+ // Build combined result lines tagged by source
168
+ const resultLines = [];
169
+ let queryEmbedding;
170
+ // Search diary entries
171
+ if (facts.length > 0) {
172
+ let found;
173
+ try {
174
+ const provider = options?.provider ?? createDefaultProvider();
175
+ found = await searchDiaryFactsForQuery(query, facts, provider, options);
176
+ // Compute query embedding for journal search while provider is available
177
+ if (journalEntries.length > 0) {
178
+ const [qe] = await provider.embed([query.trim()]);
179
+ queryEmbedding = qe;
180
+ }
181
+ }
182
+ catch {
183
+ // Embeddings unavailable — fall back to substring matching
184
+ const lowerQuery = query.toLowerCase();
185
+ const topK = options?.topK ?? DEFAULT_TOP_K;
186
+ found = facts
187
+ .filter((fact) => fact.text.toLowerCase().includes(lowerQuery))
188
+ .slice(0, topK)
189
+ .map((fact) => ({ ...fact, score: 1 }));
190
+ if (found.length > 0) {
191
+ (0, runtime_1.emitNervesEvent)({
192
+ level: "warn",
193
+ component: "mind",
194
+ event: "mind.note_search_fallback",
195
+ message: "embeddings unavailable, used substring fallback",
196
+ meta: { matchCount: found.length },
197
+ });
198
+ }
199
+ }
200
+ for (const fact of found) {
201
+ let meta = `score=${fact.score.toFixed(3)} source=${fact.source}`;
202
+ if (fact.provenance) {
203
+ if (fact.provenance.channel)
204
+ meta += ` channel=${fact.provenance.channel}`;
205
+ if (fact.provenance.friendName)
206
+ meta += ` friend=${fact.provenance.friendName}`;
207
+ if (fact.provenance.trust)
208
+ meta += ` trust=${fact.provenance.trust}`;
209
+ }
210
+ const tag = (0, provenance_trust_1.classifyProvenanceTrust)(fact.provenance) === "external" ? "diary/external" : "diary";
211
+ resultLines.push({
212
+ text: `[${tag}] ${fact.text} [${meta}]`,
213
+ score: fact.score,
214
+ });
215
+ }
216
+ }
217
+ // Search journal entries (works whether diary had results or not)
218
+ if (journalEntries.length > 0) {
219
+ try {
220
+ if (!queryEmbedding) {
221
+ const provider = options?.provider ?? createDefaultProvider();
222
+ const [qe] = await provider.embed([query.trim()]);
223
+ queryEmbedding = qe;
224
+ }
225
+ if (queryEmbedding) {
226
+ const journalResults = searchJournalIndex(queryEmbedding, journalEntries, options);
227
+ for (const entry of journalResults) {
228
+ resultLines.push({
229
+ text: `[journal] ${entry.filename}: ${entry.preview} [score=${entry.score.toFixed(3)}]`,
230
+ score: entry.score,
231
+ });
232
+ }
233
+ }
234
+ }
235
+ catch {
236
+ // Embeddings unavailable — no journal fallback
237
+ }
238
+ }
239
+ if (resultLines.length === 0)
240
+ return;
241
+ // Sort all results by score descending
242
+ resultLines.sort((left, right) => right.score - left.score);
243
+ const noteSection = resultLines
244
+ .map((entry, index) => `${index + 1}. ${entry.text}`)
245
+ .join("\n");
246
+ messages[0] = {
247
+ role: "system",
248
+ content: `${messages[0].content}\n\n## from my diary and journal\n${noteSection}`,
249
+ };
250
+ (0, runtime_1.emitNervesEvent)({
251
+ component: "mind",
252
+ event: "mind.note_search_context",
253
+ message: "note search injected",
254
+ meta: { count: resultLines.length },
255
+ });
256
+ }
257
+ catch (error) {
258
+ (0, runtime_1.emitNervesEvent)({
259
+ level: "warn",
260
+ component: "mind",
261
+ event: "mind.note_search_context_error",
262
+ message: "note search failed",
263
+ meta: {
264
+ reason: error instanceof Error ? error.message : /* v8 ignore start -- defensive: non-Error catch branch @preserve */ String(error) /* v8 ignore stop */,
265
+ },
266
+ });
267
+ }
268
+ }
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findActivePersistentObligation = findActivePersistentObligation;
4
+ exports.findStatusObligation = findStatusObligation;
5
+ exports.renderActiveObligationSteering = renderActiveObligationSteering;
6
+ exports.renderConcreteStatusGuidance = renderConcreteStatusGuidance;
7
+ exports.renderLiveThreadStatusShape = renderLiveThreadStatusShape;
8
+ exports.buildExactStatusReply = buildExactStatusReply;
9
+ exports.renderExactStatusReplyContract = renderExactStatusReplyContract;
10
+ const config_1 = require("../heart/config");
11
+ const active_work_1 = require("../heart/active-work");
12
+ const runtime_1 = require("../nerves/runtime");
13
+ function findActivePersistentObligation(frame) {
14
+ if (!frame)
15
+ return null;
16
+ return (frame.pendingObligations ?? []).find((ob) => ob.status !== "pending" && ob.status !== "fulfilled") ?? null;
17
+ }
18
+ function obligationTimestampMs(obligation) {
19
+ return Date.parse(obligation.updatedAt ?? obligation.createdAt);
20
+ }
21
+ function newestObligationFirst(left, right) {
22
+ return obligationTimestampMs(right) - obligationTimestampMs(left);
23
+ }
24
+ function matchesCurrentSession(frame, obligation) {
25
+ return matchesSessionOrigin(frame, obligation.origin);
26
+ }
27
+ function matchesSessionOrigin(frame, origin) {
28
+ return Boolean(frame.currentSession
29
+ && origin.friendId === frame.currentSession.friendId
30
+ && origin.channel === frame.currentSession.channel
31
+ && (0, config_1.sanitizeKey)(origin.key) === (0, config_1.sanitizeKey)(frame.currentSession.key));
32
+ }
33
+ function findStatusObligation(frame) {
34
+ if (!frame)
35
+ return null;
36
+ const openObligations = [...(frame.pendingObligations ?? [])]
37
+ .filter((obligation) => obligation.status !== "fulfilled")
38
+ .sort(newestObligationFirst);
39
+ const sameSession = openObligations.find((obligation) => matchesCurrentSession(frame, obligation));
40
+ if (sameSession)
41
+ return sameSession;
42
+ return openObligations[0] ?? null;
43
+ }
44
+ function findCurrentSessionStatusObligation(frame) {
45
+ const openObligations = [...(frame.pendingObligations ?? [])]
46
+ .filter((obligation) => obligation.status !== "fulfilled")
47
+ .sort(newestObligationFirst);
48
+ return openObligations.find((obligation) => matchesCurrentSession(frame, obligation)) ?? null;
49
+ }
50
+ function renderActiveObligationSteering(obligation) {
51
+ (0, runtime_1.emitNervesEvent)({
52
+ component: "mind",
53
+ event: "mind.obligation_steering_rendered",
54
+ message: "rendered active obligation steering",
55
+ meta: {
56
+ hasObligation: Boolean(obligation),
57
+ hasSurface: Boolean(obligation?.currentSurface?.label),
58
+ },
59
+ });
60
+ if (!obligation)
61
+ return "";
62
+ const name = obligation.origin.friendId;
63
+ const surfaceLine = obligation.currentSurface?.label
64
+ ? `\nright now that work is happening in ${obligation.currentSurface.label}.`
65
+ : "";
66
+ return `## where my attention is
67
+ i'm already working on something i owe ${name}.${surfaceLine}
68
+
69
+ i should close that loop before i act like this is a fresh blank turn.`;
70
+ }
71
+ function mergeArtifactFallback(obligation) {
72
+ const trimmed = obligation.content.trim();
73
+ if (!trimmed)
74
+ return "the fix";
75
+ const stripped = trimmed.replace(/^merge(?:\s+|$)/i, "").trim();
76
+ return stripped || "the fix";
77
+ }
78
+ function formatMergeArtifact(obligation) {
79
+ const currentArtifact = obligation.currentArtifact?.trim();
80
+ if (currentArtifact)
81
+ return currentArtifact;
82
+ if (obligation.currentSurface?.kind === "merge") {
83
+ const surfaceLabel = obligation.currentSurface.label.trim();
84
+ if (surfaceLabel)
85
+ return surfaceLabel;
86
+ }
87
+ return mergeArtifactFallback(obligation);
88
+ }
89
+ function formatActiveLane(frame, obligation) {
90
+ const liveCodingSession = frame.codingSessions?.[0];
91
+ if (liveCodingSession) {
92
+ const sameThread = frame.currentSession
93
+ && liveCodingSession.originSession
94
+ && liveCodingSession.originSession.friendId === frame.currentSession.friendId
95
+ && liveCodingSession.originSession.channel === frame.currentSession.channel
96
+ && liveCodingSession.originSession.key === frame.currentSession.key;
97
+ return sameThread
98
+ ? `${liveCodingSession.runner} ${liveCodingSession.id} for this same thread`
99
+ : liveCodingSession.originSession
100
+ ? `${liveCodingSession.runner} ${liveCodingSession.id} for ${liveCodingSession.originSession.channel}/${liveCodingSession.originSession.key}`
101
+ : `${liveCodingSession.runner} ${liveCodingSession.id}`;
102
+ }
103
+ return obligation.currentSurface?.label
104
+ || (matchesCurrentSession(frame, obligation) ? "this same thread" : "this live loop");
105
+ }
106
+ function formatCurrentArtifact(frame, obligation) {
107
+ if (obligation?.currentArtifact)
108
+ return obligation.currentArtifact;
109
+ if (obligation?.currentSurface?.kind === "merge")
110
+ return obligation.currentSurface.label;
111
+ if ((frame.codingSessions ?? []).length > 0)
112
+ return "no PR or merge artifact yet";
113
+ return obligation ? "no artifact yet" : "";
114
+ }
115
+ function formatNextAction(frame, obligation) {
116
+ const obligationHasConcreteArtifact = Boolean(obligation?.currentArtifact?.trim())
117
+ || obligation?.currentSurface?.kind === "merge";
118
+ if (obligation?.status === "waiting_for_merge") {
119
+ return obligation.nextAction?.trim() || `wait for checks, merge ${formatMergeArtifact(obligation)}, then update runtime`;
120
+ }
121
+ if (obligation?.status === "updating_runtime") {
122
+ return obligation.nextAction?.trim() || "update runtime, verify version/changelog, then re-observe";
123
+ }
124
+ if (obligationHasConcreteArtifact && obligation?.nextAction?.trim()) {
125
+ return obligation.nextAction.trim();
126
+ }
127
+ const liveCodingSession = frame.codingSessions?.[0];
128
+ if (liveCodingSession?.status === "waiting_input") {
129
+ return `answer ${liveCodingSession.runner} ${liveCodingSession.id} and continue`;
130
+ }
131
+ if (liveCodingSession?.status === "stalled") {
132
+ return `unstick ${liveCodingSession.runner} ${liveCodingSession.id} and continue`;
133
+ }
134
+ if (liveCodingSession) {
135
+ return "finish the coding pass and bring the result back here";
136
+ }
137
+ if (obligation?.nextAction?.trim())
138
+ return obligation.nextAction.trim();
139
+ if (obligation?.content?.trim()) {
140
+ return `work on "${obligation.content.trim()}" and bring back a concrete artifact`;
141
+ }
142
+ return obligation ? "continue the active loop and bring the result back here" : "";
143
+ }
144
+ function renderConcreteStatusGuidance(frame, obligation) {
145
+ const activeLane = obligation ? formatActiveLane(frame, obligation) : "";
146
+ const currentArtifact = formatCurrentArtifact(frame, obligation);
147
+ const nextAction = formatNextAction(frame, obligation);
148
+ const liveConversation = frame.currentSession
149
+ ? `${frame.currentSession.channel}/${frame.currentSession.key}`
150
+ : "";
151
+ if (!activeLane && !currentArtifact && !nextAction)
152
+ return "";
153
+ return `if someone asks what i'm doing or for status mid-task, i answer from these live facts instead of copying a canned block.
154
+ the live conversation is ${liveConversation || "not in a live conversation"}.
155
+ the active lane is ${activeLane}.
156
+ the current artifact is ${currentArtifact}.
157
+ if i just finished or verified something concrete in this live lane, i name that as the latest checkpoint.
158
+ the next action is ${nextAction}.
159
+
160
+ i answer naturally from those facts instead of forcing a canned status block.`;
161
+ }
162
+ function renderLiveThreadStatusShape(frame) {
163
+ if (!frame.currentSession)
164
+ return "";
165
+ return `if someone asks what i'm doing or for status mid-task in this live thread, i answer in these exact lines, in order, with no intro paragraph:
166
+ live conversation: ${frame.currentSession.channel}/${frame.currentSession.key}
167
+ active lane: this same thread
168
+ current artifact: <actual artifact or "no artifact yet">
169
+ latest checkpoint: <freshest concrete thing i just finished or verified>
170
+ next action: <smallest concrete next step i'm taking now>
171
+
172
+ no recap paragraph before those lines.
173
+ no option list.
174
+ present tense only.
175
+ if a finished step matters, i label it "just finished" instead of presenting it as current work.`;
176
+ }
177
+ function buildExactStatusReply(frame, obligation, latestCheckpoint, statusCheckScope) {
178
+ const headerObligation = statusCheckScope === "all-sessions-family"
179
+ ? findCurrentSessionStatusObligation(frame)
180
+ : obligation;
181
+ const liveConversation = frame.currentSession
182
+ ? `${frame.currentSession.channel}/${frame.currentSession.key}`
183
+ : "not in a live conversation";
184
+ const activeLane = headerObligation
185
+ ? formatActiveLane(frame, headerObligation)
186
+ : (frame.currentSession ? "this same thread" : "this live loop");
187
+ const currentArtifact = formatCurrentArtifact(frame, headerObligation) || "no artifact yet";
188
+ const nextAction = formatNextAction(frame, headerObligation) || "continue the active loop and bring the result back here";
189
+ const latest = latestCheckpoint.trim() || "<freshest concrete thing i just finished or verified>";
190
+ const lines = [
191
+ `live conversation: ${liveConversation}`,
192
+ `active lane: ${activeLane}`,
193
+ `current artifact: ${currentArtifact}`,
194
+ `latest checkpoint: ${latest}`,
195
+ `next action: ${nextAction}`,
196
+ ];
197
+ if (statusCheckScope === "all-sessions-family") {
198
+ lines.push("other active sessions:");
199
+ const summaries = (0, active_work_1.formatOtherActiveSessionSummaries)(frame);
200
+ lines.push(...(summaries.length > 0 ? summaries : ["- none"]));
201
+ }
202
+ return lines.join("\n");
203
+ }
204
+ function renderExactStatusReplyContract(frame, obligation, statusCheckScope) {
205
+ const headerObligation = statusCheckScope === "all-sessions-family"
206
+ ? findCurrentSessionStatusObligation(frame)
207
+ : obligation;
208
+ if (statusCheckScope === "all-sessions-family") {
209
+ return `reply using exactly this status shape and nothing else:
210
+ live conversation: ${frame.currentSession ? `${frame.currentSession.channel}/${frame.currentSession.key}` : "not in a live conversation"}
211
+ active lane: ${headerObligation ? formatActiveLane(frame, headerObligation) : (frame.currentSession ? "this same thread" : "this live loop")}
212
+ current artifact: ${formatCurrentArtifact(frame, headerObligation) || "no artifact yet"}
213
+ latest checkpoint: <freshest concrete thing i just finished or verified>
214
+ next action: ${formatNextAction(frame, headerObligation) || "continue the active loop and bring the result back here"}
215
+ other active sessions:
216
+ - <session label>: <what i'm doing there right now>`;
217
+ }
218
+ return `reply using exactly these five lines and nothing else:
219
+ ${buildExactStatusReply(frame, obligation, "<freshest concrete thing i just finished or verified>")}
220
+ `;
221
+ }
@@ -35,8 +35,12 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.INNER_DIALOG_PENDING = void 0;
37
37
  exports.getPendingDir = getPendingDir;
38
+ exports.getDeferredReturnDir = getDeferredReturnDir;
38
39
  exports.getInnerDialogPendingDir = getInnerDialogPendingDir;
39
40
  exports.hasPendingMessages = hasPendingMessages;
41
+ exports.queuePendingMessage = queuePendingMessage;
42
+ exports.enqueueDeferredReturn = enqueueDeferredReturn;
43
+ exports.drainDeferredReturns = drainDeferredReturns;
40
44
  exports.drainPending = drainPending;
41
45
  const fs = __importStar(require("fs"));
42
46
  const path = __importStar(require("path"));
@@ -45,6 +49,9 @@ const runtime_1 = require("../nerves/runtime");
45
49
  function getPendingDir(agentName, friendId, channel, key) {
46
50
  return path.join((0, identity_1.getAgentRoot)(agentName), "state", "pending", friendId, channel, key);
47
51
  }
52
+ function getDeferredReturnDir(agentName, friendId) {
53
+ return path.join((0, identity_1.getAgentRoot)(agentName), "state", "pending-returns", friendId);
54
+ }
48
55
  /** Canonical inner-dialog pending path segments. */
49
56
  exports.INNER_DIALOG_PENDING = { friendId: "self", channel: "inner", key: "dialog" };
50
57
  /** Returns the pending dir for this agent's inner dialog. */
@@ -61,15 +68,25 @@ function hasPendingMessages(pendingDir) {
61
68
  return false;
62
69
  }
63
70
  }
64
- function drainPending(pendingDir) {
65
- if (!fs.existsSync(pendingDir))
66
- return [];
71
+ function writeQueueFile(queueDir, message) {
72
+ fs.mkdirSync(queueDir, { recursive: true });
73
+ const fileName = `${message.timestamp}-${Math.random().toString(36).slice(2, 10)}.json`;
74
+ const filePath = path.join(queueDir, fileName);
75
+ fs.writeFileSync(filePath, JSON.stringify(message, null, 2));
76
+ return filePath;
77
+ }
78
+ function queuePendingMessage(pendingDir, message) {
79
+ writeQueueFile(pendingDir, message);
80
+ }
81
+ function drainQueue(queueDir) {
82
+ if (!fs.existsSync(queueDir))
83
+ return { messages: [], recovered: 0 };
67
84
  let entries;
68
85
  try {
69
- entries = fs.readdirSync(pendingDir);
86
+ entries = fs.readdirSync(queueDir);
70
87
  }
71
88
  catch {
72
- return [];
89
+ return { messages: [], recovered: 0 };
73
90
  }
74
91
  // Collect both .json (new) and .processing (crash recovery)
75
92
  const jsonFiles = entries.filter(f => f.endsWith(".json") && !f.endsWith(".processing"));
@@ -81,9 +98,9 @@ function drainPending(pendingDir) {
81
98
  ].sort((a, b) => a.file.localeCompare(b.file));
82
99
  const messages = [];
83
100
  for (const { file, needsRename } of allFiles) {
84
- const srcPath = path.join(pendingDir, file);
101
+ const srcPath = path.join(queueDir, file);
85
102
  const processingPath = needsRename
86
- ? path.join(pendingDir, file + ".processing")
103
+ ? path.join(queueDir, file + ".processing")
87
104
  : srcPath;
88
105
  try {
89
106
  if (needsRename) {
@@ -102,11 +119,42 @@ function drainPending(pendingDir) {
102
119
  catch { /* ignore */ }
103
120
  }
104
121
  }
122
+ return {
123
+ messages,
124
+ recovered: processingFiles.length,
125
+ };
126
+ }
127
+ function enqueueDeferredReturn(agentName, friendId, message) {
128
+ const queueDir = getDeferredReturnDir(agentName, friendId);
129
+ const filePath = writeQueueFile(queueDir, message);
130
+ (0, runtime_1.emitNervesEvent)({
131
+ event: "mind.deferred_return_enqueued",
132
+ component: "mind",
133
+ message: "deferred return queued for later friend delivery",
134
+ meta: { friendId, queueDir },
135
+ });
136
+ return filePath;
137
+ }
138
+ function drainDeferredReturns(agentName, friendId) {
139
+ const queueDir = getDeferredReturnDir(agentName, friendId);
140
+ const { messages } = drainQueue(queueDir);
141
+ (0, runtime_1.emitNervesEvent)({
142
+ event: "mind.deferred_returns_drained",
143
+ component: "mind",
144
+ message: "deferred friend returns drained",
145
+ meta: { friendId, queueDir, count: messages.length },
146
+ });
147
+ return messages;
148
+ }
149
+ function drainPending(pendingDir) {
150
+ if (!fs.existsSync(pendingDir))
151
+ return [];
152
+ const { messages, recovered } = drainQueue(pendingDir);
105
153
  (0, runtime_1.emitNervesEvent)({
106
154
  event: "mind.pending_drained",
107
155
  component: "mind",
108
156
  message: "pending queue drained",
109
- meta: { pendingDir, count: messages.length, recovered: processingFiles.length },
157
+ meta: { pendingDir, count: messages.length, recovered },
110
158
  });
111
159
  return messages;
112
160
  }
@@ -5,11 +5,12 @@ const prompt_1 = require("./prompt");
5
5
  const runtime_1 = require("../nerves/runtime");
6
6
  async function refreshSystemPrompt(messages, channel, options, context) {
7
7
  const newSystem = await (0, prompt_1.buildSystem)(channel, options, context);
8
+ const flattened = (0, prompt_1.flattenSystemPrompt)(newSystem);
8
9
  if (messages.length > 0 && messages[0].role === "system") {
9
- messages[0] = { role: "system", content: newSystem };
10
+ messages[0] = { role: "system", content: flattened };
10
11
  }
11
12
  else {
12
- messages.unshift({ role: "system", content: newSystem });
13
+ messages.unshift({ role: "system", content: flattened });
13
14
  }
14
15
  (0, runtime_1.emitNervesEvent)({
15
16
  event: "mind.system_prompt_refreshed",