@ouro.bot/cli 0.1.0-alpha.55 → 0.1.0-alpha.551

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 (386) hide show
  1. package/README.md +133 -19
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-bootstrap-drift.md +54 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/changelog.json +3561 -0
  14. package/dist/arc/attention-types.js +8 -0
  15. package/dist/arc/cares.js +140 -0
  16. package/dist/arc/episodes.js +117 -0
  17. package/dist/arc/intentions.js +133 -0
  18. package/dist/arc/json-store.js +117 -0
  19. package/dist/arc/obligations.js +237 -0
  20. package/dist/arc/packets.js +193 -0
  21. package/dist/arc/presence.js +185 -0
  22. package/dist/arc/task-lifecycle.js +65 -0
  23. package/dist/heart/active-work.js +837 -26
  24. package/dist/heart/agent-entry.js +58 -3
  25. package/dist/heart/attachments/image-normalize.js +194 -0
  26. package/dist/heart/attachments/materialize.js +97 -0
  27. package/dist/heart/attachments/originals.js +88 -0
  28. package/dist/heart/attachments/render.js +29 -0
  29. package/dist/heart/attachments/sources/adapter.js +2 -0
  30. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  31. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  32. package/dist/heart/attachments/sources/index.js +16 -0
  33. package/dist/heart/attachments/store.js +103 -0
  34. package/dist/heart/attachments/types.js +93 -0
  35. package/dist/heart/auth/auth-flow.js +479 -0
  36. package/dist/heart/background-operations.js +281 -0
  37. package/dist/heart/bundle-state.js +168 -0
  38. package/dist/heart/commitments.js +111 -0
  39. package/dist/heart/config-registry.js +304 -0
  40. package/dist/heart/config.js +114 -118
  41. package/dist/heart/core.js +925 -246
  42. package/dist/heart/cross-chat-delivery.js +3 -18
  43. package/dist/heart/daemon/agent-config-check.js +512 -0
  44. package/dist/heart/daemon/agent-discovery.js +102 -3
  45. package/dist/heart/daemon/agent-service.js +522 -0
  46. package/dist/heart/daemon/agentic-repair.js +554 -0
  47. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  48. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  49. package/dist/heart/daemon/cadence.js +70 -0
  50. package/dist/heart/daemon/cli-defaults.js +665 -0
  51. package/dist/heart/daemon/cli-exec.js +7565 -0
  52. package/dist/heart/daemon/cli-help.js +498 -0
  53. package/dist/heart/daemon/cli-parse.js +1590 -0
  54. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  55. package/dist/heart/daemon/cli-render.js +775 -0
  56. package/dist/heart/daemon/cli-types.js +8 -0
  57. package/dist/heart/daemon/connect-bay.js +323 -0
  58. package/dist/heart/daemon/daemon-cli.js +29 -1672
  59. package/dist/heart/daemon/daemon-entry.js +417 -2
  60. package/dist/heart/daemon/daemon-health.js +183 -0
  61. package/dist/heart/daemon/daemon-rollup.js +58 -0
  62. package/dist/heart/daemon/daemon-runtime-sync.js +87 -13
  63. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  64. package/dist/heart/daemon/daemon.js +796 -71
  65. package/dist/heart/daemon/dns-workflow.js +394 -0
  66. package/dist/heart/daemon/doctor-types.js +8 -0
  67. package/dist/heart/daemon/doctor.js +844 -0
  68. package/dist/heart/daemon/drift-detection.js +146 -0
  69. package/dist/heart/daemon/health-monitor.js +122 -1
  70. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  71. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  72. package/dist/heart/daemon/http-health-probe.js +80 -0
  73. package/dist/heart/daemon/human-command-screens.js +234 -0
  74. package/dist/heart/daemon/human-readiness.js +114 -0
  75. package/dist/heart/daemon/inner-status.js +102 -0
  76. package/dist/heart/daemon/interactive-repair.js +394 -0
  77. package/dist/heart/daemon/launchd.js +37 -8
  78. package/dist/heart/daemon/log-tailer.js +82 -12
  79. package/dist/heart/daemon/logs-prune.js +110 -0
  80. package/dist/heart/daemon/mcp-canary.js +297 -0
  81. package/dist/heart/daemon/message-router.js +2 -2
  82. package/dist/heart/daemon/os-cron-deps.js +135 -0
  83. package/dist/heart/daemon/os-cron.js +14 -12
  84. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  85. package/dist/heart/daemon/ouro-entry.js +3 -1
  86. package/dist/heart/daemon/process-manager.js +375 -33
  87. package/dist/heart/daemon/provider-discovery.js +137 -0
  88. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  89. package/dist/heart/daemon/pulse.js +475 -0
  90. package/dist/heart/daemon/readiness-repair.js +365 -0
  91. package/dist/heart/daemon/run-hooks.js +2 -0
  92. package/dist/heart/daemon/runtime-logging.js +67 -16
  93. package/dist/heart/daemon/runtime-metadata.js +3 -31
  94. package/dist/heart/daemon/safe-mode.js +161 -0
  95. package/dist/heart/daemon/sense-manager.js +353 -38
  96. package/dist/heart/daemon/session-id-resolver.js +131 -0
  97. package/dist/heart/daemon/skill-management-installer.js +94 -0
  98. package/dist/heart/daemon/socket-client.js +158 -11
  99. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  100. package/dist/heart/daemon/startup-tui.js +330 -0
  101. package/dist/heart/daemon/task-scheduler.js +3 -25
  102. package/dist/heart/daemon/terminal-ui.js +499 -0
  103. package/dist/heart/daemon/thoughts.js +162 -17
  104. package/dist/heart/daemon/up-progress.js +366 -0
  105. package/dist/heart/daemon/vault-items.js +56 -0
  106. package/dist/heart/delegation.js +1 -1
  107. package/dist/heart/habits/habit-migration.js +189 -0
  108. package/dist/heart/habits/habit-parser.js +140 -0
  109. package/dist/heart/habits/habit-runtime-state.js +100 -0
  110. package/dist/heart/habits/habit-scheduler.js +372 -0
  111. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  112. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  113. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  114. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  115. package/dist/heart/identity.js +200 -51
  116. package/dist/heart/kept-notes.js +357 -0
  117. package/dist/heart/kicks.js +1 -1
  118. package/dist/heart/machine-identity.js +161 -0
  119. package/dist/heart/mail-import-discovery.js +353 -0
  120. package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
  121. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  122. package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
  123. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  124. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  125. package/dist/heart/mailbox/mailbox-http.js +99 -0
  126. package/dist/heart/mailbox/mailbox-read.js +31 -0
  127. package/dist/heart/mailbox/mailbox-types.js +27 -0
  128. package/dist/heart/mailbox/mailbox-view.js +195 -0
  129. package/dist/heart/mailbox/readers/agent-machine.js +382 -0
  130. package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
  131. package/dist/heart/mailbox/readers/mail.js +362 -0
  132. package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
  133. package/dist/heart/mailbox/readers/sessions.js +232 -0
  134. package/dist/heart/mailbox/readers/shared.js +111 -0
  135. package/dist/heart/mcp/mcp-server.js +683 -0
  136. package/dist/heart/migrate-config.js +100 -0
  137. package/dist/heart/model-capabilities.js +19 -0
  138. package/dist/heart/platform.js +81 -0
  139. package/dist/heart/provider-attempt.js +134 -0
  140. package/dist/heart/provider-binding-resolver.js +255 -0
  141. package/dist/heart/provider-credentials.js +425 -0
  142. package/dist/heart/provider-failover.js +301 -0
  143. package/dist/heart/provider-models.js +81 -0
  144. package/dist/heart/provider-ping.js +262 -0
  145. package/dist/heart/provider-state.js +216 -0
  146. package/dist/heart/provider-visibility.js +188 -0
  147. package/dist/heart/providers/anthropic-token.js +131 -0
  148. package/dist/heart/providers/anthropic.js +139 -52
  149. package/dist/heart/providers/azure.js +97 -13
  150. package/dist/heart/providers/error-classification.js +127 -0
  151. package/dist/heart/providers/github-copilot.js +145 -0
  152. package/dist/heart/providers/minimax-vlm.js +189 -0
  153. package/dist/heart/providers/minimax.js +26 -8
  154. package/dist/heart/providers/openai-codex.js +55 -40
  155. package/dist/heart/runtime-capability-check.js +170 -0
  156. package/dist/heart/runtime-credentials.js +367 -0
  157. package/dist/heart/runtime-cwd.js +87 -0
  158. package/dist/heart/sense-truth.js +11 -4
  159. package/dist/heart/session-activity.js +43 -22
  160. package/dist/heart/session-events.js +1149 -0
  161. package/dist/heart/session-playback-cli-main.js +5 -0
  162. package/dist/heart/session-playback-cli.js +36 -0
  163. package/dist/heart/session-playback.js +231 -0
  164. package/dist/heart/session-stats-cli-main.js +5 -0
  165. package/dist/heart/session-stats.js +182 -0
  166. package/dist/heart/session-transcript.js +243 -0
  167. package/dist/heart/start-of-turn-packet.js +345 -0
  168. package/dist/heart/streaming.js +44 -27
  169. package/dist/heart/sync-classification.js +176 -0
  170. package/dist/heart/sync.js +449 -0
  171. package/dist/heart/target-resolution.js +9 -5
  172. package/dist/heart/tempo.js +93 -0
  173. package/dist/heart/temporal-view.js +41 -0
  174. package/dist/heart/timeouts.js +101 -0
  175. package/dist/heart/tool-activity-callbacks.js +59 -0
  176. package/dist/heart/tool-description.js +139 -0
  177. package/dist/heart/tool-friction.js +55 -0
  178. package/dist/heart/tool-loop.js +200 -0
  179. package/dist/heart/turn-context.js +381 -0
  180. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  181. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  182. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  183. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  184. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  185. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  186. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  187. package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
  188. package/dist/mailbox-ui/assets/index-Cm51CY9W.js +61 -0
  189. package/dist/mailbox-ui/index.html +15 -0
  190. package/dist/mailroom/attention.js +167 -0
  191. package/dist/mailroom/autonomy.js +209 -0
  192. package/dist/mailroom/blob-store.js +674 -0
  193. package/dist/mailroom/body-cache.js +61 -0
  194. package/dist/mailroom/core.js +720 -0
  195. package/dist/mailroom/entry.js +160 -0
  196. package/dist/mailroom/file-store.js +430 -0
  197. package/dist/mailroom/mbox-import.js +383 -0
  198. package/dist/mailroom/outbound.js +380 -0
  199. package/dist/mailroom/policy.js +263 -0
  200. package/dist/mailroom/reader.js +233 -0
  201. package/dist/mailroom/search-cache.js +256 -0
  202. package/dist/mailroom/search-relevance.js +319 -0
  203. package/dist/mailroom/smtp-ingress.js +176 -0
  204. package/dist/mailroom/source-state.js +176 -0
  205. package/dist/mailroom/thread.js +109 -0
  206. package/dist/mailroom/travel-extract.js +89 -0
  207. package/dist/mind/bundle-manifest.js +7 -1
  208. package/dist/mind/context.js +165 -101
  209. package/dist/mind/diary-integrity.js +60 -0
  210. package/dist/mind/{memory.js → diary.js} +62 -75
  211. package/dist/mind/embedding-provider.js +60 -0
  212. package/dist/mind/file-state.js +179 -0
  213. package/dist/mind/friends/channel.js +30 -0
  214. package/dist/mind/friends/resolver.js +54 -2
  215. package/dist/mind/friends/store-file.js +39 -3
  216. package/dist/mind/friends/types.js +2 -2
  217. package/dist/mind/journal-index.js +161 -0
  218. package/dist/mind/note-search.js +268 -0
  219. package/dist/mind/obligation-steering.js +221 -0
  220. package/dist/mind/pending.js +4 -0
  221. package/dist/mind/prompt-refresh.js +3 -2
  222. package/dist/mind/prompt.js +995 -123
  223. package/dist/mind/provenance-trust.js +26 -0
  224. package/dist/mind/scrutiny.js +173 -0
  225. package/dist/nerves/cli-logging.js +7 -1
  226. package/dist/nerves/coverage/audit-rules.js +15 -6
  227. package/dist/nerves/coverage/audit.js +28 -2
  228. package/dist/nerves/coverage/cli.js +1 -1
  229. package/dist/nerves/coverage/contract.js +5 -5
  230. package/dist/nerves/coverage/file-completeness.js +139 -5
  231. package/dist/nerves/coverage/run-artifacts.js +1 -1
  232. package/dist/nerves/event-buffer.js +111 -0
  233. package/dist/nerves/index.js +224 -4
  234. package/dist/nerves/observation.js +20 -0
  235. package/dist/nerves/redact.js +79 -0
  236. package/dist/nerves/review/cli-main.js +5 -0
  237. package/dist/nerves/review/cli.js +156 -0
  238. package/dist/nerves/review/core.js +152 -0
  239. package/dist/nerves/runtime.js +5 -1
  240. package/dist/repertoire/ado-client.js +15 -56
  241. package/dist/repertoire/ado-semantic.js +11 -10
  242. package/dist/repertoire/api-client.js +97 -0
  243. package/dist/repertoire/bitwarden-store.js +816 -0
  244. package/dist/repertoire/bundle-templates.js +72 -0
  245. package/dist/repertoire/bw-installer.js +180 -0
  246. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  247. package/dist/repertoire/coding/context-pack.js +330 -0
  248. package/dist/repertoire/coding/feedback.js +197 -30
  249. package/dist/repertoire/coding/manager.js +158 -9
  250. package/dist/repertoire/coding/spawner.js +55 -9
  251. package/dist/repertoire/coding/tools.js +170 -7
  252. package/dist/repertoire/commerce-errors.js +109 -0
  253. package/dist/repertoire/commerce-self-test.js +156 -0
  254. package/dist/repertoire/credential-access.js +111 -0
  255. package/dist/repertoire/duffel-client.js +185 -0
  256. package/dist/repertoire/github-client.js +14 -55
  257. package/dist/repertoire/graph-client.js +11 -52
  258. package/dist/repertoire/guardrails.js +396 -0
  259. package/dist/repertoire/mcp-client.js +295 -0
  260. package/dist/repertoire/mcp-manager.js +362 -0
  261. package/dist/repertoire/mcp-tools.js +63 -0
  262. package/dist/repertoire/shell-sessions.js +133 -0
  263. package/dist/repertoire/skills.js +15 -24
  264. package/dist/repertoire/stripe-client.js +131 -0
  265. package/dist/repertoire/tasks/board.js +31 -5
  266. package/dist/repertoire/tasks/fix.js +182 -0
  267. package/dist/repertoire/tasks/index.js +16 -4
  268. package/dist/repertoire/tasks/lifecycle.js +2 -2
  269. package/dist/repertoire/tasks/parser.js +3 -2
  270. package/dist/repertoire/tasks/scanner.js +194 -37
  271. package/dist/repertoire/tasks/transitions.js +16 -78
  272. package/dist/repertoire/tool-results.js +29 -0
  273. package/dist/repertoire/tools-attachments.js +317 -0
  274. package/dist/repertoire/tools-base.js +47 -1075
  275. package/dist/repertoire/tools-bluebubbles.js +1 -0
  276. package/dist/repertoire/tools-bridge.js +142 -0
  277. package/dist/repertoire/tools-bundle.js +984 -0
  278. package/dist/repertoire/tools-config.js +185 -0
  279. package/dist/repertoire/tools-continuity.js +248 -0
  280. package/dist/repertoire/tools-credential.js +381 -0
  281. package/dist/repertoire/tools-files.js +342 -0
  282. package/dist/repertoire/tools-flight.js +224 -0
  283. package/dist/repertoire/tools-flow.js +119 -0
  284. package/dist/repertoire/tools-github.js +1 -7
  285. package/dist/repertoire/tools-mail.js +1857 -0
  286. package/dist/repertoire/tools-notes.js +421 -0
  287. package/dist/repertoire/tools-session.js +750 -0
  288. package/dist/repertoire/tools-shell.js +120 -0
  289. package/dist/repertoire/tools-stripe.js +180 -0
  290. package/dist/repertoire/tools-surface.js +243 -0
  291. package/dist/repertoire/tools-teams.js +9 -39
  292. package/dist/repertoire/tools-travel.js +125 -0
  293. package/dist/repertoire/tools-trip.js +604 -0
  294. package/dist/repertoire/tools-user-profile.js +144 -0
  295. package/dist/repertoire/tools-vault.js +40 -0
  296. package/dist/repertoire/tools.js +108 -100
  297. package/dist/repertoire/travel-api-client.js +360 -0
  298. package/dist/repertoire/user-profile.js +131 -0
  299. package/dist/repertoire/vault-setup.js +246 -0
  300. package/dist/repertoire/vault-unlock.js +561 -0
  301. package/dist/scripts/claude-code-hook.js +41 -0
  302. package/dist/scripts/claude-code-stop-hook.js +47 -0
  303. package/dist/senses/attention-queue.js +116 -0
  304. package/dist/senses/bluebubbles/active-turns.js +216 -0
  305. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  306. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  307. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  308. package/dist/senses/bluebubbles/entry.js +77 -0
  309. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  310. package/dist/senses/bluebubbles/index.js +2305 -0
  311. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  312. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  313. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  314. package/dist/senses/bluebubbles/processed-log.js +133 -0
  315. package/dist/senses/bluebubbles/replay.js +137 -0
  316. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  317. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  318. package/dist/senses/cli/bracketed-paste.js +82 -0
  319. package/dist/senses/cli/image-paste.js +287 -0
  320. package/dist/senses/cli/image-ref-navigation.js +75 -0
  321. package/dist/senses/cli/ink-app.js +156 -0
  322. package/dist/senses/cli/inline-diff.js +64 -0
  323. package/dist/senses/cli/input-keys.js +174 -0
  324. package/dist/senses/cli/kill-ring.js +86 -0
  325. package/dist/senses/cli/message-list.js +51 -0
  326. package/dist/senses/cli/ouro-tui.js +607 -0
  327. package/dist/senses/cli/spinner-imperative.js +135 -0
  328. package/dist/senses/cli/spinner.js +101 -0
  329. package/dist/senses/cli/status-line.js +60 -0
  330. package/dist/senses/cli/streaming-markdown.js +526 -0
  331. package/dist/senses/cli/tool-display.js +85 -0
  332. package/dist/senses/cli/tool-render.js +85 -0
  333. package/dist/senses/cli/tui-store.js +240 -0
  334. package/dist/senses/cli/virtual-list.js +35 -0
  335. package/dist/senses/cli-entry.js +60 -8
  336. package/dist/senses/cli-layout.js +187 -0
  337. package/dist/senses/cli.js +520 -209
  338. package/dist/senses/commands.js +66 -3
  339. package/dist/senses/habit-turn-message.js +108 -0
  340. package/dist/senses/inner-dialog-worker.js +175 -21
  341. package/dist/senses/inner-dialog.js +330 -27
  342. package/dist/senses/mail-entry.js +66 -0
  343. package/dist/senses/mail.js +379 -0
  344. package/dist/senses/pipeline.js +569 -182
  345. package/dist/senses/proactive-content-guard.js +51 -0
  346. package/dist/senses/shared-turn.js +248 -0
  347. package/dist/senses/surface-tool.js +68 -0
  348. package/dist/senses/teams-entry.js +60 -8
  349. package/dist/senses/teams.js +387 -98
  350. package/dist/senses/trust-gate.js +100 -5
  351. package/dist/trips/core.js +138 -0
  352. package/dist/trips/store.js +146 -0
  353. package/package.json +38 -7
  354. package/skills/agent-commerce.md +106 -0
  355. package/skills/browser-navigation.md +117 -0
  356. package/skills/commerce-setup-guide.md +116 -0
  357. package/skills/commerce-setup.md +84 -0
  358. package/skills/configure-dev-tools.md +101 -0
  359. package/skills/travel-planning.md +138 -0
  360. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  361. package/dist/heart/daemon/subagent-installer.js +0 -166
  362. package/dist/heart/session-recall.js +0 -116
  363. package/dist/mind/associative-recall.js +0 -209
  364. package/dist/senses/bluebubbles-entry.js +0 -13
  365. package/dist/senses/bluebubbles.js +0 -1177
  366. package/dist/senses/debug-activity.js +0 -148
  367. package/subagents/README.md +0 -86
  368. package/subagents/work-doer.md +0 -237
  369. package/subagents/work-merger.md +0 -618
  370. package/subagents/work-planner.md +0 -390
  371. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  372. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  373. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  374. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  375. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  376. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  377. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  378. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  379. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  380. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  381. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  382. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  383. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  384. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  385. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  386. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.summarizeSessionTail = summarizeSessionTail;
4
+ exports.searchSessionTranscript = searchSessionTranscript;
5
+ const runtime_1 = require("../nerves/runtime");
6
+ const session_events_1 = require("./session-events");
7
+ function shouldIncludeToolMessages(friendId, channel) {
8
+ return friendId === "self" && channel === "inner";
9
+ }
10
+ function sortEventsForTranscript(events) {
11
+ return [...events].sort((a, b) => {
12
+ const byTime = Date.parse((0, session_events_1.bestEventTimestamp)(a)) - Date.parse((0, session_events_1.bestEventTimestamp)(b));
13
+ return byTime === 0 ? a.sequence - b.sequence : byTime;
14
+ });
15
+ }
16
+ function parseToolArguments(toolCall) {
17
+ try {
18
+ const parsed = JSON.parse(toolCall.function.arguments);
19
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
20
+ ? parsed
21
+ : null;
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ function extractHumanVisibleToolText(event, context) {
28
+ if (event.role !== "assistant" || event.toolCalls.length === 0)
29
+ return "";
30
+ for (const toolCall of event.toolCalls) {
31
+ const args = parseToolArguments(toolCall);
32
+ if (!args)
33
+ continue;
34
+ if (toolCall.function.name === "settle" && typeof args.answer === "string") {
35
+ return args.answer.trim();
36
+ }
37
+ if (toolCall.function.name === "send_message" && typeof args.content === "string") {
38
+ const targetChannel = typeof args.channel === "string" ? args.channel : "";
39
+ const targetFriendId = typeof args.friendId === "string" ? args.friendId : "";
40
+ const targetKey = typeof args.key === "string" ? args.key : "session";
41
+ if (targetChannel === context.channel && targetFriendId === context.friendId && targetKey === context.key) {
42
+ return args.content.trim();
43
+ }
44
+ }
45
+ }
46
+ return "";
47
+ }
48
+ function normalizeSessionMessages(events, context) {
49
+ return sortEventsForTranscript(events)
50
+ .map((event) => ({
51
+ id: event.id,
52
+ role: event.role,
53
+ content: (0, session_events_1.extractEventText)(event) || extractHumanVisibleToolText(event, context),
54
+ timestamp: (0, session_events_1.formatSessionEventTimestamp)(event),
55
+ }))
56
+ .filter((message) => {
57
+ if (message.role === "system")
58
+ return false;
59
+ if (message.role === "tool" && !context.includeToolMessages)
60
+ return false;
61
+ return message.content.length > 0;
62
+ });
63
+ }
64
+ function buildSummaryInstruction(friendId, channel, trustLevel) {
65
+ if (friendId === "self" && channel === "inner") {
66
+ return "summarize this session transcript fully and transparently. this is my own inner dialog — include all details, decisions, and reasoning.";
67
+ }
68
+ return `summarize this session transcript. the person asking has trust level: ${trustLevel}. family=full transparency, friend=share work and general topics but protect other people's identities, acquaintance=very guarded minimal disclosure.`;
69
+ }
70
+ function clip(text, limit = 160) {
71
+ const compact = text.replace(/\s+/g, " ").trim();
72
+ return compact.length > limit ? compact.slice(0, limit - 1) + "…" : compact;
73
+ }
74
+ function buildSnapshot(summary, tailMessages) {
75
+ const lines = [`recent focus: ${clip(summary, 240)}`];
76
+ const latestUser = [...tailMessages].reverse().find((message) => message.role === "user")?.content;
77
+ const latestAssistant = [...tailMessages].reverse().find((message) => message.role === "assistant")?.content;
78
+ if (latestUser) {
79
+ lines.push(`latest user: ${clip(latestUser)}`);
80
+ }
81
+ if (latestAssistant) {
82
+ lines.push(`latest assistant: ${clip(latestAssistant)}`);
83
+ }
84
+ return lines.join("\n");
85
+ }
86
+ function selectSessionTailMessages(messages, messageCount) {
87
+ const requestedCount = Number.isFinite(messageCount) && messageCount > 0 ? Math.floor(messageCount) : 20;
88
+ const tail = messages.slice(-requestedCount);
89
+ const selectedIds = new Set(tail.map((message) => message.id));
90
+ const latestUser = [...messages].reverse().find((message) => message.role === "user");
91
+ const latestAssistant = [...messages].reverse().find((message) => message.role === "assistant");
92
+ if (latestUser)
93
+ selectedIds.add(latestUser.id);
94
+ if (latestAssistant)
95
+ selectedIds.add(latestAssistant.id);
96
+ return messages.filter((message) => selectedIds.has(message.id));
97
+ }
98
+ function buildSearchSnapshot(query, messages, includeLatestTurn = true) {
99
+ const lines = [`history query: "${clip(query, 120)}"`];
100
+ if (!includeLatestTurn) {
101
+ return lines.join("\n");
102
+ }
103
+ const latestUser = [...messages].reverse().find((message) => message.role === "user")?.content;
104
+ const latestAssistant = [...messages].reverse().find((message) => message.role === "assistant")?.content;
105
+ if (latestUser) {
106
+ lines.push(`latest user: ${clip(latestUser)}`);
107
+ }
108
+ if (latestAssistant) {
109
+ lines.push(`latest assistant: ${clip(latestAssistant)}`);
110
+ }
111
+ return lines.join("\n");
112
+ }
113
+ function buildSearchExcerpts(messages, query, maxMatches) {
114
+ const normalizedQuery = query.trim().toLowerCase();
115
+ if (!normalizedQuery)
116
+ return [];
117
+ const candidates = [];
118
+ let lastMatchIndex = -2;
119
+ for (let i = 0; i < messages.length; i++) {
120
+ if (!messages[i].content.toLowerCase().includes(normalizedQuery))
121
+ continue;
122
+ if (i <= lastMatchIndex + 1)
123
+ continue;
124
+ lastMatchIndex = i;
125
+ const start = Math.max(0, i - 1);
126
+ const end = Math.min(messages.length, i + 2);
127
+ const excerpt = messages
128
+ .slice(start, end)
129
+ .map((message) => `[${message.timestamp} | ${message.role} | ${message.id}] ${clip(message.content, 200)}`)
130
+ .join("\n");
131
+ const signature = messages
132
+ .slice(start, end)
133
+ .map((message) => `[${message.role}] ${clip(message.content, 200)}`)
134
+ .join("\n");
135
+ const score = messages
136
+ .slice(start, end)
137
+ .filter((message) => message.content.toLowerCase().includes(normalizedQuery))
138
+ .length;
139
+ candidates.push({ excerpt, signature, score, index: i });
140
+ }
141
+ const seen = new Set();
142
+ return candidates
143
+ .sort((a, b) => b.score - a.score || a.index - b.index)
144
+ .filter((candidate) => {
145
+ if (seen.has(candidate.signature))
146
+ return false;
147
+ seen.add(candidate.signature);
148
+ return true;
149
+ })
150
+ .slice(0, maxMatches)
151
+ .map((candidate) => candidate.excerpt);
152
+ }
153
+ async function summarizeSessionTail(options) {
154
+ (0, runtime_1.emitNervesEvent)({
155
+ component: "daemon",
156
+ event: "daemon.session_tail_summary",
157
+ message: "summarizing session transcript tail",
158
+ meta: {
159
+ friendId: options.friendId,
160
+ channel: options.channel,
161
+ key: options.key,
162
+ messageCount: options.messageCount,
163
+ },
164
+ });
165
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(options.sessionPath);
166
+ if (!envelope)
167
+ return { kind: "missing" };
168
+ const transcriptContext = {
169
+ friendId: options.friendId,
170
+ channel: options.channel,
171
+ key: options.key,
172
+ includeToolMessages: shouldIncludeToolMessages(options.friendId, options.channel),
173
+ };
174
+ let visibleMessages = normalizeSessionMessages(envelope.events, transcriptContext);
175
+ if (options.archiveFallback && !visibleMessages.some((message) => message.role === "user")) {
176
+ const fullHistoryMessages = normalizeSessionMessages((0, session_events_1.loadFullEventHistory)(options.sessionPath), transcriptContext);
177
+ if (fullHistoryMessages.length > 0)
178
+ visibleMessages = fullHistoryMessages;
179
+ }
180
+ const tailMessages = selectSessionTailMessages(visibleMessages, options.messageCount);
181
+ if (tailMessages.length === 0) {
182
+ return { kind: "empty" };
183
+ }
184
+ const transcript = tailMessages
185
+ .map((message) => `[${message.timestamp} | ${message.role} | ${message.id}] ${message.content}`)
186
+ .join("\n");
187
+ const summary = options.summarize
188
+ ? await options.summarize(transcript, buildSummaryInstruction(options.friendId, options.channel, options.trustLevel ?? "family"))
189
+ : transcript;
190
+ return {
191
+ kind: "ok",
192
+ transcript,
193
+ summary,
194
+ snapshot: buildSnapshot(summary, tailMessages),
195
+ tailMessages,
196
+ };
197
+ }
198
+ async function searchSessionTranscript(options) {
199
+ (0, runtime_1.emitNervesEvent)({
200
+ component: "daemon",
201
+ event: "daemon.session_search",
202
+ message: "searching session transcript",
203
+ meta: {
204
+ friendId: options.friendId,
205
+ channel: options.channel,
206
+ key: options.key,
207
+ query: options.query,
208
+ maxMatches: options.maxMatches ?? 5,
209
+ },
210
+ });
211
+ // Use full event history (envelope + archive) for search to find older messages
212
+ const allEvents = (0, session_events_1.loadFullEventHistory)(options.sessionPath);
213
+ if (allEvents.length === 0) {
214
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(options.sessionPath);
215
+ if (!envelope)
216
+ return { kind: "missing" };
217
+ return { kind: "empty" };
218
+ }
219
+ const messages = normalizeSessionMessages(allEvents, {
220
+ friendId: options.friendId,
221
+ channel: options.channel,
222
+ key: options.key,
223
+ includeToolMessages: shouldIncludeToolMessages(options.friendId, options.channel),
224
+ });
225
+ if (messages.length === 0) {
226
+ return { kind: "empty" };
227
+ }
228
+ const query = options.query.trim();
229
+ const matches = buildSearchExcerpts(messages, query, options.maxMatches ?? 5);
230
+ if (matches.length === 0) {
231
+ return {
232
+ kind: "no_match",
233
+ query,
234
+ snapshot: buildSearchSnapshot(query, messages),
235
+ };
236
+ }
237
+ return {
238
+ kind: "ok",
239
+ query,
240
+ snapshot: buildSearchSnapshot(query, messages, false),
241
+ matches,
242
+ };
243
+ }
@@ -0,0 +1,345 @@
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.buildCapabilitiesSection = buildCapabilitiesSection;
37
+ exports.buildStartOfTurnPacket = buildStartOfTurnPacket;
38
+ exports.renderStartOfTurnPacket = renderStartOfTurnPacket;
39
+ exports.renderCompactStartOfTurnPacket = renderCompactStartOfTurnPacket;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const runtime_1 = require("../nerves/runtime");
43
+ const bundle_state_1 = require("./bundle-state");
44
+ const tempo_1 = require("./tempo");
45
+ function estimateTokens(text) {
46
+ return Math.ceil(text.length / 4);
47
+ }
48
+ // --- Section builders (pure derivation from authored data, no embellishment) ---
49
+ function buildPlotLine(episodes, tempo) {
50
+ if (episodes.length === 0)
51
+ return "";
52
+ const limit = tempo === "crisis" ? 3 : tempo === "brief" ? 2 : 5;
53
+ const selected = episodes.slice(0, limit);
54
+ const lines = selected.map((ep) => {
55
+ const parts = [`- ${ep.summary}`];
56
+ if (ep.whyItMattered && tempo !== "brief") {
57
+ parts[0] += ` (${ep.whyItMattered})`;
58
+ }
59
+ return parts[0];
60
+ });
61
+ return lines.join("\n");
62
+ }
63
+ function buildObligationsSection(obligations) {
64
+ if (obligations.length === 0)
65
+ return "";
66
+ return obligations
67
+ .map((ob) => {
68
+ const parts = [`- ${ob.content}`];
69
+ if (ob.meaning?.resumeHint) {
70
+ parts.push(` [hint: ${ob.meaning.resumeHint}]`);
71
+ }
72
+ if (ob.meaning?.stalenessClass && ob.meaning.stalenessClass !== "fresh") {
73
+ parts.push(` (${ob.meaning.stalenessClass})`);
74
+ }
75
+ if (ob.meaning?.waitingOn) {
76
+ parts.push(` waiting on ${ob.meaning.waitingOn.kind}: ${ob.meaning.waitingOn.target}`);
77
+ }
78
+ return parts.join("");
79
+ })
80
+ .join("\n");
81
+ }
82
+ function buildCaresSection(cares) {
83
+ if (cares.length === 0)
84
+ return "";
85
+ return cares
86
+ .map((c) => {
87
+ const parts = [`- ${c.label}`];
88
+ if (c.salience !== "low") {
89
+ parts.push(` [${c.salience}]`);
90
+ }
91
+ if (c.currentRisk) {
92
+ parts.push(` risk: ${c.currentRisk}`);
93
+ }
94
+ return parts.join("");
95
+ })
96
+ .join("\n");
97
+ }
98
+ function buildPresenceSection(peers) {
99
+ if (peers.length === 0)
100
+ return "";
101
+ return peers
102
+ .map((p) => `- ${p.agentName}: ${p.availability}/${p.lane}`)
103
+ .join("\n");
104
+ }
105
+ function buildResumeHint(view, obligations) {
106
+ // Compose from authored obligation resumeHints and top intentions
107
+ const hints = [];
108
+ const effectiveObligations = obligations ?? view.activeObligations;
109
+ for (const ob of effectiveObligations) {
110
+ if (ob.meaning?.resumeHint) {
111
+ hints.push(ob.meaning.resumeHint);
112
+ }
113
+ }
114
+ for (const intent of view.openIntentions.slice(0, 3)) {
115
+ hints.push(intent.content);
116
+ }
117
+ if (hints.length === 0) {
118
+ // Fall back to top obligation content
119
+ if (effectiveObligations.length > 0) {
120
+ hints.push(effectiveObligations[0].content);
121
+ }
122
+ }
123
+ if (hints.length === 0)
124
+ return "";
125
+ return hints.join("; ");
126
+ }
127
+ /**
128
+ * Build a compact summary of capability changes between runtime versions.
129
+ * Reads bundle-meta.json for version info and changelog.json for change descriptions.
130
+ * Returns undefined if no version change detected or files are missing/malformed.
131
+ */
132
+ function buildCapabilitiesSection(bundleRoot) {
133
+ let meta;
134
+ try {
135
+ const raw = fs.readFileSync(path.join(bundleRoot, "bundle-meta.json"), "utf-8");
136
+ meta = JSON.parse(raw);
137
+ }
138
+ catch {
139
+ (0, runtime_1.emitNervesEvent)({
140
+ component: "heart",
141
+ event: "heart.capabilities_check",
142
+ message: "bundle-meta.json missing or malformed",
143
+ meta: { bundleRoot },
144
+ });
145
+ return undefined;
146
+ }
147
+ const currentVersion = meta.runtimeVersion;
148
+ const previousVersion = meta.previousRuntimeVersion;
149
+ if (typeof currentVersion !== "string" || typeof previousVersion !== "string") {
150
+ return undefined;
151
+ }
152
+ if (currentVersion === previousVersion) {
153
+ return undefined;
154
+ }
155
+ (0, runtime_1.emitNervesEvent)({
156
+ component: "heart",
157
+ event: "heart.capabilities_version_change",
158
+ message: `runtime version changed from ${previousVersion} to ${currentVersion}`,
159
+ meta: { previousVersion, currentVersion },
160
+ });
161
+ let changelog;
162
+ try {
163
+ const raw = fs.readFileSync(path.join(bundleRoot, "changelog.json"), "utf-8");
164
+ changelog = JSON.parse(raw);
165
+ }
166
+ catch {
167
+ // changelog missing -- still report the version change
168
+ }
169
+ const parts = [`Updated from ${previousVersion} to ${currentVersion}`];
170
+ if (changelog && Array.isArray(changelog)) {
171
+ const relevantChanges = [];
172
+ for (const entry of changelog) {
173
+ if (entry.version === previousVersion)
174
+ break;
175
+ if (Array.isArray(entry.changes)) {
176
+ relevantChanges.push(...entry.changes);
177
+ }
178
+ }
179
+ if (relevantChanges.length > 0) {
180
+ parts.push(`: ${relevantChanges.join("; ")}`);
181
+ }
182
+ }
183
+ return parts.join("");
184
+ }
185
+ function buildStartOfTurnPacket(view, opts) {
186
+ const tempo = view.tempo;
187
+ const tokenBudget = tempo_1.TEMPO_BUDGETS[tempo];
188
+ const effectiveObligations = opts?.canonicalObligations ? opts.canonicalObligations.all : view.activeObligations;
189
+ const packet = {
190
+ plotLine: buildPlotLine(view.recentEpisodes, tempo),
191
+ obligations: buildObligationsSection(effectiveObligations),
192
+ cares: buildCaresSection(view.activeCares),
193
+ presence: buildPresenceSection(view.peerPresence),
194
+ resumeHint: buildResumeHint(view, opts?.canonicalObligations ? effectiveObligations : undefined),
195
+ currentSessionTiming: opts?.currentSessionTiming,
196
+ tempo,
197
+ tokenBudget,
198
+ assembledAt: new Date().toISOString(),
199
+ };
200
+ (0, runtime_1.emitNervesEvent)({
201
+ component: "heart",
202
+ event: "heart.start_of_turn_packet_built",
203
+ message: `start-of-turn packet built: tempo=${tempo}`,
204
+ meta: {
205
+ tempo,
206
+ plotLineTokens: estimateTokens(packet.plotLine),
207
+ obligationsTokens: estimateTokens(packet.obligations),
208
+ caresTokens: estimateTokens(packet.cares),
209
+ presenceTokens: estimateTokens(packet.presence),
210
+ resumeHintTokens: estimateTokens(packet.resumeHint),
211
+ },
212
+ });
213
+ return packet;
214
+ }
215
+ /**
216
+ * Renders a start-of-turn packet to prompt text, respecting token budget.
217
+ * Truncation priority (last truncated first):
218
+ * resumeHint (PROTECTED) > obligations > cares > plotLine > presence
219
+ * So presence is truncated first, then plotLine, then cares, then obligations.
220
+ * resumeHint is never truncated.
221
+ */
222
+ function renderStartOfTurnPacket(packet) {
223
+ const budget = packet.tokenBudget;
224
+ // Assemble sections in priority order (highest priority first for budget allocation)
225
+ // Each section is { label, content, priority } where lower priority number = truncated first
226
+ const sections = [
227
+ // bundleState and syncFailure share the top remediation tier — both
228
+ // are actionable "fix your git" signals. bundleState is preferred
229
+ // because it's structured (array of enum values) while syncFailure is
230
+ // a legacy free-form string; both render when populated.
231
+ { label: "provider", content: packet.providerState ?? "", priority: 8 },
232
+ { label: "bundleState", content: (0, bundle_state_1.renderBundleStateHint)(packet.bundleState ?? []), priority: 7 },
233
+ { label: "syncFailure", content: packet.syncFailure ?? "", priority: 7 },
234
+ { label: "resume", content: packet.resumeHint, priority: 6 },
235
+ { label: "sessionTiming", content: packet.currentSessionTiming ?? "", priority: 5 },
236
+ { label: "obligations", content: packet.obligations, priority: 5 },
237
+ { label: "cares", content: packet.cares, priority: 4 },
238
+ { label: "plot", content: packet.plotLine, priority: 3 },
239
+ { label: "capabilities", content: packet.capabilities ?? "", priority: 2 },
240
+ { label: "presence", content: packet.presence, priority: 1 },
241
+ ].filter((s) => s.content.length > 0);
242
+ if (sections.length === 0) {
243
+ (0, runtime_1.emitNervesEvent)({
244
+ component: "heart",
245
+ event: "heart.start_of_turn_packet_rendered",
246
+ message: "start-of-turn packet rendered: empty",
247
+ meta: { tokens: 0, tempo: packet.tempo },
248
+ });
249
+ return "";
250
+ }
251
+ // Build the rendered output, truncating lower-priority sections first
252
+ let rendered = formatSections(sections);
253
+ let tokens = estimateTokens(rendered);
254
+ // Truncate sections from lowest priority until we fit budget
255
+ const sortedByPriority = [...sections].sort((a, b) => a.priority - b.priority);
256
+ for (const section of sortedByPriority) {
257
+ if (tokens <= budget.max)
258
+ break;
259
+ // Skip resumeHint — it's PROTECTED
260
+ if (section.label === "resume")
261
+ continue;
262
+ // Remove this section entirely
263
+ const idx = sections.findIndex((s) => s.label === section.label);
264
+ sections.splice(idx, 1);
265
+ rendered = formatSections(sections);
266
+ tokens = estimateTokens(rendered);
267
+ }
268
+ // If still over budget after removing all non-protected sections, trim what's left
269
+ if (tokens > budget.max) {
270
+ const maxChars = budget.max * 4;
271
+ rendered = rendered.slice(0, maxChars);
272
+ }
273
+ (0, runtime_1.emitNervesEvent)({
274
+ component: "heart",
275
+ event: "heart.start_of_turn_packet_rendered",
276
+ message: `start-of-turn packet rendered: ${tokens} tokens`,
277
+ meta: { tokens, tempo: packet.tempo, sectionCount: sections.length },
278
+ });
279
+ return rendered;
280
+ }
281
+ function formatSections(sections) {
282
+ const parts = [];
283
+ for (const section of sections) {
284
+ switch (section.label) {
285
+ case "resume":
286
+ parts.push(`**Next:** ${section.content}`);
287
+ break;
288
+ case "obligations":
289
+ parts.push(`**Owed:**\n${section.content}`);
290
+ break;
291
+ case "cares":
292
+ parts.push(`**Cares:**\n${section.content}`);
293
+ break;
294
+ case "plot":
295
+ parts.push(`**Recent:**\n${section.content}`);
296
+ break;
297
+ case "presence":
298
+ parts.push(`**Peers:**\n${section.content}`);
299
+ break;
300
+ case "capabilities":
301
+ parts.push(`**Capabilities:** ${section.content}`);
302
+ break;
303
+ case "syncFailure":
304
+ parts.push(`**Sync warning:** ${section.content}`);
305
+ break;
306
+ case "bundleState":
307
+ parts.push(`**Bundle:** ${section.content}`);
308
+ break;
309
+ case "provider":
310
+ parts.push(`**Provider:**\n${section.content}`);
311
+ break;
312
+ }
313
+ }
314
+ return parts.join("\n\n");
315
+ }
316
+ /**
317
+ * Ultra-compact version for coding context (max 200 tokens).
318
+ * Just resumeHint + top obligation + top care, single-line bullets.
319
+ */
320
+ function renderCompactStartOfTurnPacket(packet) {
321
+ const parts = [];
322
+ if (packet.resumeHint) {
323
+ parts.push(`next: ${packet.resumeHint}`);
324
+ }
325
+ if (packet.obligations) {
326
+ // Just first line of obligations
327
+ const firstOb = packet.obligations.split("\n")[0];
328
+ parts.push(`owed: ${firstOb.replace(/^- /, "")}`);
329
+ }
330
+ if (packet.cares) {
331
+ const firstCare = packet.cares.split("\n")[0];
332
+ parts.push(`care: ${firstCare.replace(/^- /, "")}`);
333
+ }
334
+ const compact = parts.join(" | ");
335
+ // Hard cap at 200 tokens (800 chars)
336
+ const maxChars = 200 * 4;
337
+ const result = compact.length > maxChars ? compact.slice(0, maxChars) : compact;
338
+ (0, runtime_1.emitNervesEvent)({
339
+ component: "heart",
340
+ event: "heart.start_of_turn_packet_compact_rendered",
341
+ message: `compact start-of-turn packet: ${estimateTokens(result)} tokens`,
342
+ meta: { tokens: estimateTokens(result) },
343
+ });
344
+ return result;
345
+ }