@ouro.bot/cli 0.1.0-alpha.50 → 0.1.0-alpha.501

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 (369) 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 +3184 -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 +867 -35
  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/bundle-state.js +168 -0
  30. package/dist/heart/commitments.js +111 -0
  31. package/dist/heart/config-registry.js +304 -0
  32. package/dist/heart/config.js +119 -129
  33. package/dist/heart/core.js +898 -244
  34. package/dist/heart/cross-chat-delivery.js +131 -0
  35. package/dist/heart/daemon/agent-config-check.js +490 -0
  36. package/dist/heart/daemon/agent-discovery.js +79 -3
  37. package/dist/heart/daemon/agent-service.js +360 -0
  38. package/dist/heart/daemon/agentic-repair.js +216 -0
  39. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  40. package/dist/heart/daemon/cadence.js +70 -0
  41. package/dist/heart/daemon/cli-defaults.js +640 -0
  42. package/dist/heart/daemon/cli-exec.js +7239 -0
  43. package/dist/heart/daemon/cli-help.js +493 -0
  44. package/dist/heart/daemon/cli-parse.js +1533 -0
  45. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  46. package/dist/heart/daemon/cli-render.js +561 -0
  47. package/dist/heart/daemon/cli-types.js +8 -0
  48. package/dist/heart/daemon/connect-bay.js +323 -0
  49. package/dist/heart/daemon/daemon-cli.js +29 -1631
  50. package/dist/heart/daemon/daemon-entry.js +345 -3
  51. package/dist/heart/daemon/daemon-health.js +141 -0
  52. package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
  53. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  54. package/dist/heart/daemon/daemon.js +677 -58
  55. package/dist/heart/daemon/dns-workflow.js +394 -0
  56. package/dist/heart/daemon/doctor-types.js +8 -0
  57. package/dist/heart/daemon/doctor.js +615 -0
  58. package/dist/heart/daemon/health-monitor.js +92 -1
  59. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  60. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  61. package/dist/heart/daemon/http-health-probe.js +80 -0
  62. package/dist/heart/daemon/human-command-screens.js +234 -0
  63. package/dist/heart/daemon/human-readiness.js +114 -0
  64. package/dist/heart/daemon/inner-status.js +89 -0
  65. package/dist/heart/daemon/interactive-repair.js +394 -0
  66. package/dist/heart/daemon/launchd.js +25 -5
  67. package/dist/heart/daemon/log-tailer.js +82 -12
  68. package/dist/heart/daemon/logs-prune.js +110 -0
  69. package/dist/heart/daemon/message-router.js +2 -2
  70. package/dist/heart/daemon/os-cron-deps.js +134 -0
  71. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  72. package/dist/heart/daemon/ouro-entry.js +3 -1
  73. package/dist/heart/daemon/process-manager.js +214 -0
  74. package/dist/heart/daemon/provider-discovery.js +137 -0
  75. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  76. package/dist/heart/daemon/pulse.js +475 -0
  77. package/dist/heart/daemon/readiness-repair.js +365 -0
  78. package/dist/heart/daemon/run-hooks.js +2 -0
  79. package/dist/heart/daemon/runtime-logging.js +67 -16
  80. package/dist/heart/daemon/runtime-metadata.js +73 -0
  81. package/dist/heart/daemon/runtime-mode.js +67 -0
  82. package/dist/heart/daemon/safe-mode.js +161 -0
  83. package/dist/heart/daemon/sense-manager.js +178 -37
  84. package/dist/heart/daemon/session-id-resolver.js +131 -0
  85. package/dist/heart/daemon/skill-management-installer.js +94 -0
  86. package/dist/heart/daemon/socket-client.js +109 -4
  87. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  88. package/dist/heart/daemon/startup-tui.js +264 -0
  89. package/dist/heart/daemon/task-scheduler.js +3 -25
  90. package/dist/heart/daemon/terminal-ui.js +499 -0
  91. package/dist/heart/daemon/thoughts.js +162 -17
  92. package/dist/heart/daemon/up-progress.js +366 -0
  93. package/dist/heart/daemon/vault-items.js +56 -0
  94. package/dist/heart/delegation.js +1 -1
  95. package/dist/heart/habits/habit-migration.js +189 -0
  96. package/dist/heart/habits/habit-parser.js +140 -0
  97. package/dist/heart/habits/habit-runtime-state.js +100 -0
  98. package/dist/heart/habits/habit-scheduler.js +372 -0
  99. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  100. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  101. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  102. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  103. package/dist/heart/identity.js +201 -66
  104. package/dist/heart/kept-notes.js +357 -0
  105. package/dist/heart/kicks.js +1 -1
  106. package/dist/heart/machine-identity.js +161 -0
  107. package/dist/heart/mail-import-discovery.js +353 -0
  108. package/dist/heart/mcp/mcp-server.js +653 -0
  109. package/dist/heart/migrate-config.js +100 -0
  110. package/dist/heart/model-capabilities.js +59 -0
  111. package/dist/heart/outlook/outlook-http-hooks.js +66 -0
  112. package/dist/heart/outlook/outlook-http-response.js +7 -0
  113. package/dist/heart/outlook/outlook-http-routes.js +244 -0
  114. package/dist/heart/outlook/outlook-http-static.js +103 -0
  115. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  116. package/dist/heart/outlook/outlook-http.js +99 -0
  117. package/dist/heart/outlook/outlook-read.js +31 -0
  118. package/dist/heart/outlook/outlook-types.js +27 -0
  119. package/dist/heart/outlook/outlook-view.js +195 -0
  120. package/dist/heart/outlook/readers/agent-machine.js +382 -0
  121. package/dist/heart/outlook/readers/continuity-readers.js +336 -0
  122. package/dist/heart/outlook/readers/mail.js +362 -0
  123. package/dist/heart/outlook/readers/runtime-readers.js +644 -0
  124. package/dist/heart/outlook/readers/sessions.js +232 -0
  125. package/dist/heart/outlook/readers/shared.js +111 -0
  126. package/dist/heart/platform.js +81 -0
  127. package/dist/heart/provider-attempt.js +134 -0
  128. package/dist/heart/provider-binding-resolver.js +255 -0
  129. package/dist/heart/provider-credentials.js +424 -0
  130. package/dist/heart/provider-failover.js +301 -0
  131. package/dist/heart/provider-models.js +81 -0
  132. package/dist/heart/provider-ping.js +262 -0
  133. package/dist/heart/provider-state.js +216 -0
  134. package/dist/heart/provider-visibility.js +188 -0
  135. package/dist/heart/providers/anthropic-token.js +131 -0
  136. package/dist/heart/providers/anthropic.js +193 -55
  137. package/dist/heart/providers/azure.js +104 -13
  138. package/dist/heart/providers/error-classification.js +63 -0
  139. package/dist/heart/providers/github-copilot.js +145 -0
  140. package/dist/heart/providers/minimax-vlm.js +189 -0
  141. package/dist/heart/providers/minimax.js +29 -7
  142. package/dist/heart/providers/openai-codex.js +63 -39
  143. package/dist/heart/runtime-capability-check.js +170 -0
  144. package/dist/heart/runtime-credentials.js +260 -0
  145. package/dist/heart/sense-truth.js +11 -4
  146. package/dist/heart/session-activity.js +43 -22
  147. package/dist/heart/session-events.js +1089 -0
  148. package/dist/heart/session-playback-cli-main.js +5 -0
  149. package/dist/heart/session-playback-cli.js +36 -0
  150. package/dist/heart/session-playback.js +231 -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 +606 -0
  173. package/dist/mailroom/core.js +672 -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/thread.js +109 -0
  185. package/dist/mailroom/travel-extract.js +89 -0
  186. package/dist/mind/bundle-manifest.js +7 -1
  187. package/dist/mind/context.js +164 -101
  188. package/dist/mind/diary-integrity.js +60 -0
  189. package/dist/mind/{memory.js → diary.js} +74 -93
  190. package/dist/mind/embedding-provider.js +60 -0
  191. package/dist/mind/file-state.js +179 -0
  192. package/dist/mind/friends/channel.js +30 -0
  193. package/dist/mind/friends/group-context.js +144 -0
  194. package/dist/mind/friends/resolver.js +54 -2
  195. package/dist/mind/friends/store-file.js +39 -3
  196. package/dist/mind/friends/trust-explanation.js +74 -0
  197. package/dist/mind/friends/types.js +2 -2
  198. package/dist/mind/journal-index.js +161 -0
  199. package/dist/mind/note-search.js +268 -0
  200. package/dist/mind/obligation-steering.js +221 -0
  201. package/dist/mind/pending.js +4 -0
  202. package/dist/mind/prompt-refresh.js +3 -2
  203. package/dist/mind/prompt.js +948 -110
  204. package/dist/mind/provenance-trust.js +26 -0
  205. package/dist/mind/scrutiny.js +173 -0
  206. package/dist/nerves/cli-logging.js +7 -1
  207. package/dist/nerves/coverage/audit-rules.js +15 -6
  208. package/dist/nerves/coverage/audit.js +28 -2
  209. package/dist/nerves/coverage/cli.js +1 -1
  210. package/dist/nerves/coverage/contract.js +5 -5
  211. package/dist/nerves/coverage/file-completeness.js +106 -5
  212. package/dist/nerves/coverage/run-artifacts.js +1 -1
  213. package/dist/nerves/event-buffer.js +111 -0
  214. package/dist/nerves/index.js +224 -4
  215. package/dist/nerves/observation.js +20 -0
  216. package/dist/nerves/redact.js +79 -0
  217. package/dist/nerves/review/cli-main.js +5 -0
  218. package/dist/nerves/review/cli.js +156 -0
  219. package/dist/nerves/review/core.js +152 -0
  220. package/dist/nerves/runtime.js +5 -1
  221. package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
  222. package/dist/outlook-ui/assets/index-Cm51CY9W.js +61 -0
  223. package/dist/outlook-ui/index.html +15 -0
  224. package/dist/repertoire/ado-client.js +15 -56
  225. package/dist/repertoire/ado-semantic.js +11 -10
  226. package/dist/repertoire/api-client.js +97 -0
  227. package/dist/repertoire/bitwarden-store.js +774 -0
  228. package/dist/repertoire/bundle-templates.js +72 -0
  229. package/dist/repertoire/bw-installer.js +180 -0
  230. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  231. package/dist/repertoire/coding/context-pack.js +330 -0
  232. package/dist/repertoire/coding/feedback.js +197 -30
  233. package/dist/repertoire/coding/manager.js +158 -9
  234. package/dist/repertoire/coding/spawner.js +55 -9
  235. package/dist/repertoire/coding/tools.js +170 -7
  236. package/dist/repertoire/commerce-errors.js +109 -0
  237. package/dist/repertoire/commerce-self-test.js +156 -0
  238. package/dist/repertoire/credential-access.js +111 -0
  239. package/dist/repertoire/duffel-client.js +185 -0
  240. package/dist/repertoire/github-client.js +14 -55
  241. package/dist/repertoire/graph-client.js +11 -52
  242. package/dist/repertoire/guardrails.js +396 -0
  243. package/dist/repertoire/mcp-client.js +255 -0
  244. package/dist/repertoire/mcp-manager.js +305 -0
  245. package/dist/repertoire/mcp-tools.js +63 -0
  246. package/dist/repertoire/shell-sessions.js +133 -0
  247. package/dist/repertoire/skills.js +15 -24
  248. package/dist/repertoire/stripe-client.js +131 -0
  249. package/dist/repertoire/tasks/board.js +31 -5
  250. package/dist/repertoire/tasks/fix.js +182 -0
  251. package/dist/repertoire/tasks/index.js +16 -4
  252. package/dist/repertoire/tasks/lifecycle.js +2 -2
  253. package/dist/repertoire/tasks/parser.js +3 -2
  254. package/dist/repertoire/tasks/scanner.js +194 -37
  255. package/dist/repertoire/tasks/transitions.js +16 -78
  256. package/dist/repertoire/tool-results.js +29 -0
  257. package/dist/repertoire/tools-attachments.js +317 -0
  258. package/dist/repertoire/tools-base.js +46 -921
  259. package/dist/repertoire/tools-bluebubbles.js +1 -0
  260. package/dist/repertoire/tools-bridge.js +141 -0
  261. package/dist/repertoire/tools-bundle.js +984 -0
  262. package/dist/repertoire/tools-config.js +185 -0
  263. package/dist/repertoire/tools-continuity.js +248 -0
  264. package/dist/repertoire/tools-credential.js +381 -0
  265. package/dist/repertoire/tools-files.js +342 -0
  266. package/dist/repertoire/tools-flight.js +224 -0
  267. package/dist/repertoire/tools-flow.js +105 -0
  268. package/dist/repertoire/tools-github.js +1 -7
  269. package/dist/repertoire/tools-mail.js +1377 -0
  270. package/dist/repertoire/tools-notes.js +376 -0
  271. package/dist/repertoire/tools-session.js +749 -0
  272. package/dist/repertoire/tools-shell.js +120 -0
  273. package/dist/repertoire/tools-stripe.js +180 -0
  274. package/dist/repertoire/tools-surface.js +243 -0
  275. package/dist/repertoire/tools-teams.js +9 -39
  276. package/dist/repertoire/tools-travel.js +125 -0
  277. package/dist/repertoire/tools-trip.js +356 -0
  278. package/dist/repertoire/tools-user-profile.js +144 -0
  279. package/dist/repertoire/tools-vault.js +40 -0
  280. package/dist/repertoire/tools.js +144 -115
  281. package/dist/repertoire/travel-api-client.js +360 -0
  282. package/dist/repertoire/user-profile.js +131 -0
  283. package/dist/repertoire/vault-setup.js +246 -0
  284. package/dist/repertoire/vault-unlock.js +561 -0
  285. package/dist/scripts/claude-code-hook.js +41 -0
  286. package/dist/scripts/claude-code-stop-hook.js +47 -0
  287. package/dist/senses/attention-queue.js +116 -0
  288. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  289. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  290. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  291. package/dist/senses/bluebubbles/entry.js +73 -0
  292. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  293. package/dist/senses/bluebubbles/index.js +1881 -0
  294. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  295. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  296. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  297. package/dist/senses/bluebubbles/processed-log.js +111 -0
  298. package/dist/senses/bluebubbles/replay.js +129 -0
  299. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -2
  300. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  301. package/dist/senses/cli/bracketed-paste.js +82 -0
  302. package/dist/senses/cli/image-paste.js +287 -0
  303. package/dist/senses/cli/image-ref-navigation.js +75 -0
  304. package/dist/senses/cli/ink-app.js +156 -0
  305. package/dist/senses/cli/inline-diff.js +64 -0
  306. package/dist/senses/cli/input-keys.js +174 -0
  307. package/dist/senses/cli/kill-ring.js +86 -0
  308. package/dist/senses/cli/message-list.js +51 -0
  309. package/dist/senses/cli/ouro-tui.js +605 -0
  310. package/dist/senses/cli/spinner-imperative.js +135 -0
  311. package/dist/senses/cli/spinner.js +101 -0
  312. package/dist/senses/cli/status-line.js +60 -0
  313. package/dist/senses/cli/streaming-markdown.js +526 -0
  314. package/dist/senses/cli/tool-display.js +83 -0
  315. package/dist/senses/cli/tool-render.js +85 -0
  316. package/dist/senses/cli/tui-store.js +240 -0
  317. package/dist/senses/cli/virtual-list.js +35 -0
  318. package/dist/senses/cli-entry.js +60 -8
  319. package/dist/senses/cli-layout.js +187 -0
  320. package/dist/senses/cli.js +511 -209
  321. package/dist/senses/commands.js +66 -3
  322. package/dist/senses/habit-turn-message.js +108 -0
  323. package/dist/senses/inner-dialog-worker.js +175 -21
  324. package/dist/senses/inner-dialog.js +330 -27
  325. package/dist/senses/mail-entry.js +66 -0
  326. package/dist/senses/mail.js +379 -0
  327. package/dist/senses/pipeline.js +573 -164
  328. package/dist/senses/proactive-content-guard.js +51 -0
  329. package/dist/senses/shared-turn.js +248 -0
  330. package/dist/senses/surface-tool.js +68 -0
  331. package/dist/senses/teams-entry.js +60 -8
  332. package/dist/senses/teams.js +405 -170
  333. package/dist/senses/trust-gate.js +100 -5
  334. package/dist/trips/core.js +138 -0
  335. package/dist/trips/store.js +146 -0
  336. package/package.json +39 -8
  337. package/skills/agent-commerce.md +106 -0
  338. package/skills/browser-navigation.md +117 -0
  339. package/skills/commerce-setup-guide.md +116 -0
  340. package/skills/commerce-setup.md +84 -0
  341. package/skills/configure-dev-tools.md +101 -0
  342. package/skills/travel-planning.md +138 -0
  343. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  344. package/dist/heart/daemon/subagent-installer.js +0 -166
  345. package/dist/heart/session-recall.js +0 -116
  346. package/dist/mind/associative-recall.js +0 -209
  347. package/dist/senses/bluebubbles-entry.js +0 -13
  348. package/dist/senses/bluebubbles.js +0 -1142
  349. package/dist/senses/debug-activity.js +0 -148
  350. package/subagents/README.md +0 -86
  351. package/subagents/work-doer.md +0 -237
  352. package/subagents/work-merger.md +0 -618
  353. package/subagents/work-planner.md +0 -390
  354. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  355. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  356. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  357. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  358. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  359. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  360. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  361. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  362. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  363. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  364. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  365. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  366. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  367. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  368. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  369. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,365 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.vaultLockedIssue = vaultLockedIssue;
4
+ exports.vaultUnconfiguredIssue = vaultUnconfiguredIssue;
5
+ exports.providerCredentialMissingIssue = providerCredentialMissingIssue;
6
+ exports.providerLiveCheckFix = providerLiveCheckFix;
7
+ exports.preferredConnectRepairAction = preferredConnectRepairAction;
8
+ exports.providerLiveCheckFailedIssue = providerLiveCheckFailedIssue;
9
+ exports.genericReadinessIssue = genericReadinessIssue;
10
+ exports.isKnownReadinessIssue = isKnownReadinessIssue;
11
+ exports.renderReadinessIssue = renderReadinessIssue;
12
+ exports.renderReadinessIssueNextSteps = renderReadinessIssueNextSteps;
13
+ exports.runGuidedReadinessRepair = runGuidedReadinessRepair;
14
+ const runtime_1 = require("../../nerves/runtime");
15
+ const human_readiness_1 = require("./human-readiness");
16
+ const human_command_screens_1 = require("./human-command-screens");
17
+ function vaultLockedIssue(agentName) {
18
+ return {
19
+ kind: "vault-locked",
20
+ severity: "blocked",
21
+ actor: "human-required",
22
+ summary: `${agentName}: vault locked`,
23
+ detail: "Pick the path that matches what the human actually has. Ouro will not print or store the unlock secret as a portable file.",
24
+ actions: [
25
+ {
26
+ kind: "vault-unlock",
27
+ label: "Unlock with saved secret",
28
+ command: `ouro vault unlock --agent ${agentName}`,
29
+ actor: "human-required",
30
+ },
31
+ {
32
+ kind: "vault-replace",
33
+ label: "Create empty replacement vault",
34
+ command: `ouro vault replace --agent ${agentName}`,
35
+ actor: "human-required",
36
+ },
37
+ {
38
+ kind: "vault-recover",
39
+ label: "Recover from JSON export",
40
+ command: `ouro vault recover --agent ${agentName} --from <json>`,
41
+ actor: "human-required",
42
+ executable: false,
43
+ },
44
+ ],
45
+ };
46
+ }
47
+ function vaultUnconfiguredIssue(agentName) {
48
+ return {
49
+ kind: "vault-unconfigured",
50
+ severity: "blocked",
51
+ actor: "human-required",
52
+ summary: `${agentName}: vault not configured`,
53
+ detail: "This bundle does not have a vault locator in agent.json yet. Create the agent vault before authenticating providers.",
54
+ actions: [
55
+ {
56
+ kind: "vault-create",
57
+ label: "Create this agent's vault",
58
+ command: `ouro vault create --agent ${agentName}`,
59
+ actor: "human-required",
60
+ },
61
+ {
62
+ kind: "vault-recover",
63
+ label: "Recover from JSON export",
64
+ command: `ouro vault recover --agent ${agentName} --from <json>`,
65
+ actor: "human-required",
66
+ executable: false,
67
+ },
68
+ ],
69
+ };
70
+ }
71
+ function providerCredentialMissingIssue(input) {
72
+ return {
73
+ kind: "provider-credentials-missing",
74
+ severity: "blocked",
75
+ actor: "human-required",
76
+ summary: `${input.agentName}: missing ${input.provider} credentials (${input.lane}, ${input.model})`,
77
+ detail: `source: ${input.credentialPath}`,
78
+ actions: [
79
+ {
80
+ kind: "provider-auth",
81
+ label: `Authenticate ${input.provider}`,
82
+ command: `ouro auth --agent ${input.agentName} --provider ${input.provider}`,
83
+ actor: "human-required",
84
+ provider: input.provider,
85
+ },
86
+ {
87
+ kind: "provider-use",
88
+ label: "Choose another provider/model",
89
+ command: `ouro use --agent ${input.agentName} --lane ${input.lane} --provider <provider> --model <model>`,
90
+ actor: "human-choice",
91
+ executable: false,
92
+ lane: input.lane,
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ function normalizeProviderLiveCheckClassification(classification) {
98
+ switch (classification) {
99
+ case "auth-failure":
100
+ case "usage-limit":
101
+ case "rate-limit":
102
+ case "server-error":
103
+ case "network-error":
104
+ case "unknown":
105
+ return classification;
106
+ default:
107
+ return "unknown";
108
+ }
109
+ }
110
+ function providerUseAction(input) {
111
+ return {
112
+ kind: "provider-use",
113
+ label: "Choose a different working provider/model",
114
+ command: `ouro use --agent ${input.agentName} --lane ${input.lane} --provider <provider> --model <model>`,
115
+ actor: "human-choice",
116
+ executable: false,
117
+ lane: input.lane,
118
+ };
119
+ }
120
+ function providerAuthAction(input) {
121
+ return {
122
+ kind: "provider-auth",
123
+ label: `Refresh ${input.provider} credentials`,
124
+ command: `ouro auth --agent ${input.agentName} --provider ${input.provider}`,
125
+ actor: "human-required",
126
+ provider: input.provider,
127
+ };
128
+ }
129
+ function providerRetryAction(input) {
130
+ return {
131
+ kind: "provider-retry",
132
+ label: input.label,
133
+ command: `ouro repair --agent ${input.agentName}`,
134
+ actor: "human-choice",
135
+ executable: false,
136
+ };
137
+ }
138
+ function providerLiveCheckFix(input) {
139
+ const classification = normalizeProviderLiveCheckClassification(input.classification);
140
+ const authCommand = `ouro auth --agent ${input.agentName} --provider ${input.provider}`;
141
+ const useCommand = `ouro use --agent ${input.agentName} --lane ${input.lane} --provider <provider> --model <model>`;
142
+ switch (classification) {
143
+ case "auth-failure":
144
+ return `Run '${authCommand}' to refresh credentials, or run '${useCommand}' to choose another provider/model for this lane.`;
145
+ case "usage-limit":
146
+ return `This usually means ${input.provider} hit a usage limit. Restore quota, then run 'ouro up' again. Or run '${useCommand}' to choose another provider/model for this lane.`;
147
+ case "rate-limit":
148
+ return `Run 'ouro up' again after a short wait. Or run '${useCommand}' to choose another provider/model for this lane.`;
149
+ case "server-error":
150
+ return `Run 'ouro up' again in a moment. If ${input.provider} keeps failing, run '${useCommand}' to choose another provider/model for this lane.`;
151
+ case "network-error":
152
+ return `Check the network or provider availability, then run 'ouro up' again. Or run '${useCommand}' to choose another provider/model for this lane.`;
153
+ case "unknown":
154
+ return `Run 'ouro up' again. If it keeps failing, run '${authCommand}' to refresh credentials or '${useCommand}' to choose another provider/model for this lane.`;
155
+ }
156
+ }
157
+ function providerLiveCheckActions(input) {
158
+ const classification = normalizeProviderLiveCheckClassification(input.classification);
159
+ const useAction = providerUseAction(input);
160
+ const authAction = providerAuthAction(input);
161
+ switch (classification) {
162
+ case "auth-failure":
163
+ return [authAction, useAction];
164
+ case "usage-limit":
165
+ return [
166
+ providerRetryAction({ agentName: input.agentName, label: "After restoring quota, check again" }),
167
+ useAction,
168
+ ];
169
+ case "rate-limit":
170
+ return [
171
+ providerRetryAction({ agentName: input.agentName, label: "Give it a minute, then check again" }),
172
+ useAction,
173
+ ];
174
+ case "server-error":
175
+ return [
176
+ providerRetryAction({ agentName: input.agentName, label: "Check again in a moment" }),
177
+ useAction,
178
+ ];
179
+ case "network-error":
180
+ return [
181
+ providerRetryAction({ agentName: input.agentName, label: "Check again after the network settles" }),
182
+ useAction,
183
+ authAction,
184
+ ];
185
+ case "unknown":
186
+ return [
187
+ providerRetryAction({ agentName: input.agentName, label: "Check again" }),
188
+ authAction,
189
+ useAction,
190
+ ];
191
+ }
192
+ }
193
+ function preferredConnectRepairAction(issue) {
194
+ if (!issue)
195
+ return undefined;
196
+ if (issue.kind === "provider-live-check-failed" && issue.actions[0]?.kind === "provider-retry") {
197
+ return issue.actions.find((action) => action.kind !== "provider-retry") ?? issue.actions[0];
198
+ }
199
+ return issue.actions[0];
200
+ }
201
+ function providerLiveCheckFailedIssue(input) {
202
+ return {
203
+ kind: "provider-live-check-failed",
204
+ severity: "blocked",
205
+ actor: "human-choice",
206
+ summary: `${input.agentName}: ${input.lane} provider ${input.provider} / ${input.model} failed live check`,
207
+ detail: input.message,
208
+ actions: providerLiveCheckActions(input),
209
+ };
210
+ }
211
+ function genericReadinessIssue(input) {
212
+ return {
213
+ kind: "generic",
214
+ severity: "degraded",
215
+ actor: "human-choice",
216
+ summary: input.summary,
217
+ ...(input.detail ? { detail: input.detail } : {}),
218
+ actions: input.fix
219
+ ? [{
220
+ kind: "provider-use",
221
+ label: "Follow the printed fix",
222
+ command: input.fix,
223
+ actor: "human-choice",
224
+ executable: false,
225
+ }]
226
+ : [],
227
+ };
228
+ }
229
+ function isKnownReadinessIssue(issue) {
230
+ return !!issue && issue.kind !== "generic";
231
+ }
232
+ function renderReadinessIssue(issue) {
233
+ const lines = [issue.summary];
234
+ if (issue.detail) {
235
+ lines.push(` ${issue.detail}`);
236
+ }
237
+ if (issue.actions.length > 0) {
238
+ lines.push("");
239
+ }
240
+ issue.actions.forEach((action, index) => {
241
+ if (index > 0)
242
+ lines.push("");
243
+ lines.push(`${index + 1}. ${action.label}`);
244
+ lines.push(` ${action.command}`);
245
+ });
246
+ if (issue.actions.length > 0) {
247
+ lines.push("");
248
+ }
249
+ lines.push(`${issue.actions.length + 1}. Skip for now`);
250
+ return lines.join("\n");
251
+ }
252
+ function renderReadinessIssueNextSteps(issue) {
253
+ const lines = [issue.summary];
254
+ if (issue.detail && issue.kind !== "vault-locked") {
255
+ lines.push(` ${issue.detail}`);
256
+ }
257
+ issue.actions.forEach((action, index) => {
258
+ lines.push(` ${index === 0 ? "next" : "or"}: ${action.command}`);
259
+ });
260
+ return lines;
261
+ }
262
+ function selectedActionFor(answer, issue) {
263
+ const selected = Number.parseInt(answer.trim(), 10);
264
+ if (!Number.isFinite(selected))
265
+ return null;
266
+ if (selected === issue.actions.length + 1)
267
+ return "skip";
268
+ if (selected < 1 || selected > issue.actions.length)
269
+ return null;
270
+ /* v8 ignore next -- defensive: bounds were checked above, but keep sparse arrays harmless @preserve */
271
+ return issue.actions[selected - 1] ?? null;
272
+ }
273
+ function isExecutableAction(action) {
274
+ if (action.executable === false)
275
+ return false;
276
+ return !action.command.includes("<");
277
+ }
278
+ async function runGuidedReadinessRepair(reports, deps) {
279
+ (0, runtime_1.emitNervesEvent)({
280
+ level: "info",
281
+ component: "daemon",
282
+ event: "daemon.readiness_repair_start",
283
+ message: "guided readiness repair started",
284
+ meta: { reportCount: reports.length },
285
+ });
286
+ let repairsAttempted = false;
287
+ for (const report of reports) {
288
+ if (report.ok || report.issues.length === 0)
289
+ continue;
290
+ for (const issue of report.issues) {
291
+ if (deps.isTTY) {
292
+ const snapshot = (0, human_readiness_1.buildHumanReadinessSnapshot)({
293
+ agent: report.agent,
294
+ title: `Repair ${report.agent}`,
295
+ items: [
296
+ (0, human_readiness_1.readinessItemFromIssue)(issue, {
297
+ key: `${report.agent}:${issue.kind}`,
298
+ title: issue.summary,
299
+ }),
300
+ ],
301
+ });
302
+ deps.writeStdout((0, human_command_screens_1.renderHumanReadinessBoard)({
303
+ agent: report.agent,
304
+ title: `Repair ${report.agent}`,
305
+ subtitle: "Choose the path that matches what the human actually has.",
306
+ snapshot,
307
+ isTTY: true,
308
+ columns: deps.stdoutColumns,
309
+ prompt: `Choose [1-${issue.actions.length + 1}]: `,
310
+ }).trimEnd());
311
+ }
312
+ else {
313
+ deps.writeStdout(renderReadinessIssue(issue));
314
+ }
315
+ if (!deps.promptInput) {
316
+ deps.writeStdout(`manual repair required for ${report.agent}; run one of the commands above.`);
317
+ continue;
318
+ }
319
+ const answer = await deps.promptInput(`Choose [1-${issue.actions.length + 1}]: `);
320
+ const action = selectedActionFor(answer, issue);
321
+ if (action === "skip") {
322
+ deps.writeStdout(`skipped ${report.agent} for now.`);
323
+ continue;
324
+ }
325
+ if (!action) {
326
+ deps.writeStdout(`invalid choice for ${report.agent}; no repair attempted.`);
327
+ continue;
328
+ }
329
+ if (!isExecutableAction(action)) {
330
+ deps.writeStdout(`manual step for ${report.agent}: ${action.command}`);
331
+ continue;
332
+ }
333
+ if (!deps.runRepairAction) {
334
+ deps.writeStdout(`repair runner unavailable for ${report.agent}; run \`${action.command}\` manually.`);
335
+ continue;
336
+ }
337
+ try {
338
+ deps.onActionAttempted?.(report.agent, action, issue);
339
+ await deps.runRepairAction(report.agent, action, issue);
340
+ repairsAttempted = true;
341
+ deps.writeStdout(`repair step finished for ${report.agent}.`);
342
+ }
343
+ catch (error) {
344
+ const message = error instanceof Error ? error.message : String(error);
345
+ repairsAttempted = true;
346
+ deps.writeStdout(`repair error for ${report.agent}: ${message}`);
347
+ (0, runtime_1.emitNervesEvent)({
348
+ level: "error",
349
+ component: "daemon",
350
+ event: "daemon.readiness_repair_error",
351
+ message: "guided readiness repair action failed",
352
+ meta: { agent: report.agent, issue: issue.kind, action: action.kind, error: message },
353
+ });
354
+ }
355
+ }
356
+ }
357
+ (0, runtime_1.emitNervesEvent)({
358
+ level: "info",
359
+ component: "daemon",
360
+ event: "daemon.readiness_repair_end",
361
+ message: "guided readiness repair completed",
362
+ meta: { repairsAttempted },
363
+ });
364
+ return { repairsAttempted };
365
+ }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runHooks = runHooks;
4
4
  const runtime_1 = require("../../nerves/runtime");
5
5
  const bundle_meta_1 = require("./hooks/bundle-meta");
6
+ const agent_config_v2_1 = require("./hooks/agent-config-v2");
6
7
  async function runHooks(deps) {
7
8
  (0, runtime_1.emitNervesEvent)({
8
9
  component: "daemon",
@@ -12,6 +13,7 @@ async function runHooks(deps) {
12
13
  });
13
14
  try {
14
15
  deps.registerUpdateHook(bundle_meta_1.bundleMetaHook);
16
+ deps.registerUpdateHook(agent_config_v2_1.agentConfigV2Hook);
15
17
  const currentVersion = deps.getPackageVersion();
16
18
  await deps.applyPendingUpdates(deps.bundlesRoot, currentVersion);
17
19
  (0, runtime_1.emitNervesEvent)({
@@ -35,53 +35,104 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.configureDaemonRuntimeLogger = configureDaemonRuntimeLogger;
37
37
  const fs = __importStar(require("fs"));
38
- const os = __importStar(require("os"));
39
38
  const path = __importStar(require("path"));
40
39
  const nerves_1 = require("../../nerves");
41
40
  const runtime_1 = require("../../nerves/runtime");
42
- const DEFAULT_RUNTIME_LOGGING = {
41
+ const identity_1 = require("../identity");
42
+ const LEGACY_SHARED_RUNTIME_LOGGING = {
43
43
  level: "info",
44
44
  sinks: ["terminal", "ndjson"],
45
45
  };
46
- function defaultLevelForProcess(processName) {
47
- return processName === "daemon" ? "info" : "warn";
46
+ function defaultLoggingForProcess(processName) {
47
+ if (processName === "ouro" || processName === "ouro-bot") {
48
+ return {
49
+ level: "info",
50
+ sinks: ["ndjson"],
51
+ };
52
+ }
53
+ if (processName === "bluebubbles" || processName === "mail") {
54
+ return {
55
+ level: "warn",
56
+ sinks: ["terminal", "ndjson"],
57
+ };
58
+ }
59
+ return { ...LEGACY_SHARED_RUNTIME_LOGGING };
48
60
  }
49
61
  function isLogLevel(value) {
50
62
  return value === "debug" || value === "info" || value === "warn" || value === "error";
51
63
  }
64
+ function normalizeSinks(value, fallback) {
65
+ if (!Array.isArray(value)) {
66
+ return [...fallback];
67
+ }
68
+ const sinks = value.filter((entry) => entry === "terminal" || entry === "ndjson");
69
+ return sinks.length > 0 ? [...new Set(sinks)] : [...fallback];
70
+ }
71
+ function isLegacySharedDefaultConfig(candidate, normalizedLevel, normalizedSinks) {
72
+ return normalizedLevel === LEGACY_SHARED_RUNTIME_LOGGING.level
73
+ && normalizedSinks.length === LEGACY_SHARED_RUNTIME_LOGGING.sinks.length
74
+ && LEGACY_SHARED_RUNTIME_LOGGING.sinks.every((sink) => normalizedSinks.includes(sink))
75
+ && Object.keys(candidate).every((key) => key === "level" || key === "sinks");
76
+ }
52
77
  function resolveRuntimeLoggingConfig(configPath, processName) {
53
- const defaultLevel = defaultLevelForProcess(processName);
78
+ const processDefault = defaultLoggingForProcess(processName);
54
79
  let parsed = null;
55
80
  try {
56
81
  const raw = fs.readFileSync(configPath, "utf-8");
57
82
  parsed = JSON.parse(raw);
58
83
  }
59
84
  catch {
60
- return { ...DEFAULT_RUNTIME_LOGGING, level: defaultLevel };
85
+ return { ...processDefault };
61
86
  }
62
87
  if (!parsed || typeof parsed !== "object") {
63
- return { ...DEFAULT_RUNTIME_LOGGING, level: defaultLevel };
88
+ return { ...processDefault };
64
89
  }
65
90
  const candidate = parsed;
66
- const level = isLogLevel(candidate.level) ? candidate.level : defaultLevel;
67
- const sinks = Array.isArray(candidate.sinks)
68
- ? candidate.sinks.filter((entry) => entry === "terminal" || entry === "ndjson")
69
- : DEFAULT_RUNTIME_LOGGING.sinks;
91
+ const level = isLogLevel(candidate.level) ? candidate.level : processDefault.level;
92
+ const sinks = normalizeSinks(candidate.sinks, processDefault.sinks);
93
+ if ((processName === "ouro" || processName === "ouro-bot")
94
+ && isLegacySharedDefaultConfig(candidate, level, sinks)) {
95
+ return { ...processDefault };
96
+ }
70
97
  return {
71
98
  level,
72
- sinks: sinks.length > 0 ? [...new Set(sinks)] : [...DEFAULT_RUNTIME_LOGGING.sinks],
99
+ sinks,
73
100
  };
74
101
  }
102
+ function resolveAgentNameForPaths(explicit) {
103
+ if (explicit && explicit.trim().length > 0)
104
+ return explicit.trim();
105
+ try {
106
+ return (0, identity_1.getAgentName)();
107
+ }
108
+ catch {
109
+ return "slugger";
110
+ }
111
+ }
75
112
  function configureDaemonRuntimeLogger(processName, options = {}) {
76
- const homeDir = options.homeDir ?? os.homedir();
77
- const configPath = options.configPath ?? path.join(homeDir, ".agentstate", "daemon", "logging.json");
113
+ const agentName = resolveAgentNameForPaths(options.agentName);
114
+ const configPath = options.configPath
115
+ ?? (options.homeDir
116
+ ? path.join(options.homeDir, "AgentBundles", `${agentName}.ouro`, "state", "daemon", "logging.json")
117
+ : (0, identity_1.getAgentDaemonLoggingConfigPath)(agentName));
78
118
  const config = resolveRuntimeLoggingConfig(configPath, processName);
119
+ const logsDir = options.homeDir
120
+ ? path.join(options.homeDir, "AgentBundles", `${agentName}.ouro`, "state", "daemon", "logs")
121
+ : (0, identity_1.getAgentDaemonLogsDir)(agentName);
122
+ // Rotation policy per daemon ndjson stream (Unit 1c):
123
+ // 25 MB threshold x 5 gzipped generations = ~30 MB peak per stream.
124
+ // Call sites previously relied on the implicit 50 MB default; we now pass
125
+ // the options object explicitly so the policy is visible at the call site.
79
126
  const sinks = config.sinks.map((sinkName) => {
80
127
  if (sinkName === "terminal") {
81
128
  return (0, nerves_1.createTerminalSink)();
82
129
  }
83
- const ndjsonPath = path.join(homeDir, ".agentstate", "daemon", "logs", `${processName}.ndjson`);
84
- return (0, nerves_1.createNdjsonFileSink)(ndjsonPath);
130
+ const ndjsonPath = path.join(logsDir, `${processName}.ndjson`);
131
+ return (0, nerves_1.createNdjsonFileSink)(ndjsonPath, {
132
+ maxSizeBytes: 25 * 1024 * 1024,
133
+ maxGenerations: 5,
134
+ compress: true,
135
+ });
85
136
  });
86
137
  const logger = (0, nerves_1.createLogger)({
87
138
  level: config.level,
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.getRuntimeMetadata = getRuntimeMetadata;
37
+ const crypto_1 = require("crypto");
37
38
  const fs = __importStar(require("fs"));
38
39
  const path = __importStar(require("path"));
39
40
  const childProcess = __importStar(require("child_process"));
@@ -85,10 +86,71 @@ function readLastUpdated(repoRoot, packageJsonPath, statSyncImpl, execFileSyncIm
85
86
  return { value: UNKNOWN_METADATA, source: "unknown" };
86
87
  }
87
88
  }
89
+ function listConfigTargets(bundlesRoot, daemonLoggingPath, readdirSyncImpl) {
90
+ if (!readdirSyncImpl)
91
+ return [];
92
+ const targets = new Set();
93
+ if (daemonLoggingPath) {
94
+ targets.add(daemonLoggingPath);
95
+ }
96
+ try {
97
+ const bundleEntries = readdirSyncImpl(bundlesRoot, { withFileTypes: true });
98
+ for (const entry of bundleEntries) {
99
+ if (!entry.isDirectory() || !entry.name.endsWith(".ouro"))
100
+ continue;
101
+ targets.add(path.join(bundlesRoot, entry.name, "agent.json"));
102
+ }
103
+ }
104
+ catch {
105
+ // ignore unreadable bundle roots
106
+ }
107
+ return [...targets].sort();
108
+ }
109
+ function readConfigFingerprint(targets, readFileSyncImpl, existsSyncImpl) {
110
+ if (!readFileSyncImpl || !existsSyncImpl) {
111
+ return {
112
+ value: UNKNOWN_METADATA,
113
+ source: "unknown",
114
+ trackedFiles: targets.length,
115
+ presentFiles: 0,
116
+ };
117
+ }
118
+ const hash = (0, crypto_1.createHash)("sha256");
119
+ let presentFiles = 0;
120
+ for (const target of targets) {
121
+ hash.update(target);
122
+ hash.update("\0");
123
+ if (!existsSyncImpl(target)) {
124
+ hash.update("missing");
125
+ hash.update("\0");
126
+ continue;
127
+ }
128
+ presentFiles += 1;
129
+ hash.update("present");
130
+ hash.update("\0");
131
+ try {
132
+ hash.update(readFileSyncImpl(target, "utf-8"));
133
+ }
134
+ catch {
135
+ hash.update("unreadable");
136
+ }
137
+ hash.update("\0");
138
+ }
139
+ return {
140
+ value: hash.digest("hex"),
141
+ source: "content-hash",
142
+ trackedFiles: targets.length,
143
+ presentFiles,
144
+ };
145
+ }
88
146
  function getRuntimeMetadata(deps = {}) {
89
147
  const repoRoot = deps.repoRoot ?? (0, identity_1.getRepoRoot)();
148
+ const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
149
+ const daemonLoggingPath = deps.daemonLoggingPath ?? (0, identity_1.getAgentDaemonLoggingConfigPath)();
90
150
  const readFileSyncImpl = deps.readFileSync ?? optionalFunction(fs, "readFileSync")?.bind(fs) ?? null;
91
151
  const statSyncImpl = deps.statSync ?? optionalFunction(fs, "statSync")?.bind(fs) ?? null;
152
+ const readdirSyncImpl = deps.readdirSync ?? optionalFunction(fs, "readdirSync")?.bind(fs) ?? null;
153
+ const existsSyncImpl = deps.existsSync ?? optionalFunction(fs, "existsSync")?.bind(fs) ?? null;
92
154
  const execFileSyncImpl = deps.execFileSync
93
155
  ?? optionalFunction(childProcess, "execFileSync")?.bind(childProcess)
94
156
  ?? null;
@@ -101,6 +163,8 @@ function getRuntimeMetadata(deps = {}) {
101
163
  throw new Error("git unavailable");
102
164
  }))
103
165
  : { value: UNKNOWN_METADATA, source: "unknown" };
166
+ const configTargets = listConfigTargets(bundlesRoot, daemonLoggingPath, readdirSyncImpl);
167
+ const configFingerprint = readConfigFingerprint(configTargets, readFileSyncImpl, existsSyncImpl);
104
168
  (0, runtime_1.emitNervesEvent)({
105
169
  component: "daemon",
106
170
  event: "daemon.runtime_metadata_read",
@@ -109,10 +173,19 @@ function getRuntimeMetadata(deps = {}) {
109
173
  version,
110
174
  lastUpdated: lastUpdated.value,
111
175
  lastUpdatedSource: lastUpdated.source,
176
+ repoRoot,
177
+ configFingerprint: configFingerprint.value === UNKNOWN_METADATA
178
+ ? UNKNOWN_METADATA
179
+ : configFingerprint.value.slice(0, 12),
180
+ configFingerprintSource: configFingerprint.source,
181
+ configTrackedFiles: configFingerprint.trackedFiles,
182
+ configPresentFiles: configFingerprint.presentFiles,
112
183
  },
113
184
  });
114
185
  return {
115
186
  version,
116
187
  lastUpdated: lastUpdated.value,
188
+ repoRoot,
189
+ configFingerprint: configFingerprint.value,
117
190
  };
118
191
  }
@@ -0,0 +1,67 @@
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.detectRuntimeMode = detectRuntimeMode;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const runtime_1 = require("../../nerves/runtime");
40
+ function detectRuntimeMode(rootPath, deps = {}) {
41
+ const checkExists = deps.existsSync ?? fs.existsSync;
42
+ // 1. Production: installed via npm
43
+ if (rootPath.includes("node_modules/@ouro.bot/cli") ||
44
+ rootPath.includes("node_modules/ouro.bot")) {
45
+ (0, runtime_1.emitNervesEvent)({
46
+ component: "daemon",
47
+ event: "daemon.runtime_mode_detected",
48
+ message: "detected runtime mode",
49
+ meta: { rootPath, mode: "production" },
50
+ });
51
+ return "production";
52
+ }
53
+ // 2-4. Everything else is dev: worktrees, git repos, unknown paths
54
+ // (conservative default: assume dev unless proven production)
55
+ const reason = rootPath.includes(".claude/worktrees/")
56
+ ? "worktree"
57
+ : checkExists(path.join(rootPath, ".git"))
58
+ ? "git-repo"
59
+ : "unknown";
60
+ (0, runtime_1.emitNervesEvent)({
61
+ component: "daemon",
62
+ event: "daemon.runtime_mode_detected",
63
+ message: "detected runtime mode",
64
+ meta: { rootPath, mode: "dev", reason },
65
+ });
66
+ return "dev";
67
+ }