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

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 +3555 -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 +758 -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,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pruneDaemonLogs = pruneDaemonLogs;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const crypto_1 = require("crypto");
7
+ const nerves_1 = require("../../nerves");
8
+ const runtime_1 = require("../../nerves/runtime");
9
+ const identity_1 = require("../identity");
10
+ function isActiveLogStream(name) {
11
+ if (name.endsWith(".ndjson")) {
12
+ return !/\.\d+\.ndjson$/.test(name);
13
+ }
14
+ if (name.endsWith(".log")) {
15
+ return !/\.\d+\.log$/.test(name);
16
+ }
17
+ return false;
18
+ }
19
+ function pruneDaemonLogs(options = {}) {
20
+ /* v8 ignore next -- defensive: tests always pass logsDir to avoid prod paths @preserve */
21
+ const logsDir = options.logsDir ?? (0, identity_1.getAgentDaemonLogsDir)(options.agentName);
22
+ const maxSizeBytes = options.maxSizeBytes ?? nerves_1.DEFAULT_MAX_LOG_SIZE_BYTES;
23
+ const maxGenerations = options.maxGenerations ?? nerves_1.DEFAULT_MAX_GENERATIONS;
24
+ const traceId = (0, crypto_1.randomUUID)();
25
+ (0, runtime_1.emitNervesEvent)({
26
+ component: "nerves",
27
+ event: "nerves.logs_prune_start",
28
+ trace_id: traceId,
29
+ message: "pruning daemon logs",
30
+ meta: { logsDir, maxSizeBytes, maxGenerations },
31
+ });
32
+ let completed = false;
33
+ try {
34
+ if (!(0, fs_1.existsSync)(logsDir)) {
35
+ completed = true;
36
+ (0, runtime_1.emitNervesEvent)({
37
+ component: "nerves",
38
+ event: "nerves.logs_prune_end",
39
+ trace_id: traceId,
40
+ message: "daemon logs dir does not exist",
41
+ meta: { logsDir, filesCompacted: 0, bytesFreed: 0 },
42
+ });
43
+ return { filesCompacted: 0, bytesFreed: 0 };
44
+ }
45
+ let filesCompacted = 0;
46
+ let bytesFreed = 0;
47
+ // Enumerate and rotate each active structured stream plus legacy launchd
48
+ // .log streams. We explicitly skip .gz and other files — only the active
49
+ // stream can be a rotation candidate. Legacy generation files are handled
50
+ // inside rotateIfNeeded's generation-shift step, so we skip them here to
51
+ // avoid double-rotating.
52
+ for (const name of (0, fs_1.readdirSync)(logsDir)) {
53
+ if (!isActiveLogStream(name))
54
+ continue;
55
+ const filePath = (0, path_1.join)(logsDir, name);
56
+ let sizeBefore;
57
+ try {
58
+ sizeBefore = (0, fs_1.statSync)(filePath).size;
59
+ /* v8 ignore start -- defensive: file disappears between readdir and stat @preserve */
60
+ }
61
+ catch {
62
+ continue;
63
+ }
64
+ /* v8 ignore stop */
65
+ if (sizeBefore < maxSizeBytes)
66
+ continue;
67
+ // rotateIfNeeded returns true because we pre-checked sizeBefore >=
68
+ // maxSizeBytes above. The false branch of `if (rotated)` is defensive
69
+ // and unreachable under normal flow; we skip it from coverage so a
70
+ // future refactor that weakens the pre-check still reports correct
71
+ // counts without needing a contrived test.
72
+ const rotated = (0, nerves_1.rotateIfNeeded)(filePath, {
73
+ maxSizeBytes,
74
+ maxGenerations,
75
+ compress: true,
76
+ });
77
+ /* v8 ignore next 3 -- defensive: pre-check guarantees rotated=true @preserve */
78
+ if (!rotated) {
79
+ continue;
80
+ }
81
+ filesCompacted += 1;
82
+ bytesFreed += sizeBefore;
83
+ }
84
+ completed = true;
85
+ (0, runtime_1.emitNervesEvent)({
86
+ component: "nerves",
87
+ event: "nerves.logs_prune_end",
88
+ trace_id: traceId,
89
+ message: "daemon logs pruned",
90
+ meta: { logsDir, filesCompacted, bytesFreed },
91
+ });
92
+ return { filesCompacted, bytesFreed };
93
+ }
94
+ catch (err) {
95
+ /* v8 ignore next -- defensive: completed=true only reached after try returns @preserve */
96
+ if (!completed) {
97
+ /* v8 ignore next -- defensive: rotation always throws real Errors @preserve */
98
+ const reason = err instanceof Error ? err.message : String(err);
99
+ (0, runtime_1.emitNervesEvent)({
100
+ component: "nerves",
101
+ event: "nerves.logs_prune_error",
102
+ trace_id: traceId,
103
+ level: "error",
104
+ message: "daemon logs prune failed",
105
+ meta: { logsDir, error: reason },
106
+ });
107
+ }
108
+ throw err;
109
+ }
110
+ }
@@ -0,0 +1,297 @@
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.parseMcpStatusText = parseMcpStatusText;
37
+ exports.runMcpStatusCanary = runMcpStatusCanary;
38
+ exports.formatMcpStatusCanaryResult = formatMcpStatusCanaryResult;
39
+ exports.createMcpStatusCanaryProbe = createMcpStatusCanaryProbe;
40
+ const child_process_1 = require("child_process");
41
+ const path = __importStar(require("path"));
42
+ const runtime_1 = require("../../nerves/runtime");
43
+ const DEFAULT_CANARY_TIMEOUT_MS = 10_000;
44
+ const MCP_PROTOCOL_VERSION = "2024-11-05";
45
+ function defaultCommandArgs(agent, socketPath) {
46
+ const entryPath = path.join(__dirname, "ouro-bot-entry.js");
47
+ return [
48
+ entryPath,
49
+ "mcp-serve",
50
+ "--agent",
51
+ agent,
52
+ ...(socketPath ? ["--socket", socketPath] : []),
53
+ ];
54
+ }
55
+ function responseText(response) {
56
+ const result = response.result;
57
+ if (!result || typeof result !== "object" || Array.isArray(result))
58
+ return JSON.stringify(response);
59
+ const content = result.content;
60
+ if (!Array.isArray(content))
61
+ return JSON.stringify(response);
62
+ const first = content[0];
63
+ if (!first || typeof first !== "object" || Array.isArray(first))
64
+ return JSON.stringify(response);
65
+ const text = first.text;
66
+ return typeof text === "string" ? text : JSON.stringify(response);
67
+ }
68
+ function parseFields(line) {
69
+ const parsed = {};
70
+ for (const segment of line.split("\t")) {
71
+ const idx = segment.indexOf("=");
72
+ if (idx <= 0)
73
+ continue;
74
+ parsed[segment.slice(0, idx)] = segment.slice(idx + 1);
75
+ }
76
+ return parsed;
77
+ }
78
+ function parseMcpStatusText(text) {
79
+ const daemon = {};
80
+ const senses = {};
81
+ for (const line of text.split(/\r?\n/)) {
82
+ const trimmed = line.trim();
83
+ if (!trimmed)
84
+ continue;
85
+ if (trimmed.startsWith("daemon=")) {
86
+ Object.assign(daemon, parseFields(trimmed));
87
+ continue;
88
+ }
89
+ if (!trimmed.startsWith("sense="))
90
+ continue;
91
+ const fields = parseFields(trimmed);
92
+ const sense = fields.sense;
93
+ if (!sense)
94
+ continue;
95
+ const [name, status = "unknown"] = sense.split(":");
96
+ senses[name] = { ...fields, name, status };
97
+ }
98
+ return { daemon, senses, raw: text };
99
+ }
100
+ function validateMcpStatus(parsed, requiredSenses, options = {}) {
101
+ const failures = [];
102
+ if (parsed.daemon.daemon !== "running") {
103
+ failures.push(`daemon=${parsed.daemon.daemon ?? "missing"}`);
104
+ }
105
+ if (!options.ignoreOverviewHealth && parsed.daemon.health !== "ok") {
106
+ failures.push(`health=${parsed.daemon.health ?? "missing"}`);
107
+ }
108
+ if (parsed.daemon.daemonVersion &&
109
+ parsed.daemon.mcpVersion &&
110
+ parsed.daemon.daemonVersion !== parsed.daemon.mcpVersion) {
111
+ failures.push(`version mismatch daemon=${parsed.daemon.daemonVersion} mcp=${parsed.daemon.mcpVersion}`);
112
+ }
113
+ for (const [sense, row] of Object.entries(parsed.senses)) {
114
+ if (row.status === "disabled")
115
+ continue;
116
+ if (row.status === "running" || row.status === "interactive")
117
+ continue;
118
+ failures.push(`sense=${sense}:${row.status}`);
119
+ }
120
+ for (const sense of requiredSenses) {
121
+ const row = parsed.senses[sense];
122
+ if (!row) {
123
+ failures.push(`required sense missing: ${sense}`);
124
+ continue;
125
+ }
126
+ if (row.status !== "running" && row.status !== "interactive") {
127
+ failures.push(`required sense unhealthy: ${sense}:${row.status}`);
128
+ }
129
+ }
130
+ const senseSummary = Object.values(parsed.senses)
131
+ .map((row) => `${row.name}:${row.status}`)
132
+ .join(",");
133
+ const summary = failures.length === 0
134
+ ? `mcp canary ok: daemon=${parsed.daemon.daemon} health=${parsed.daemon.health}${options.ignoreOverviewHealth ? " (overview ignored)" : ""} senses=${senseSummary}`
135
+ : `mcp canary failed: ${failures.join("; ")}`;
136
+ return {
137
+ ok: failures.length === 0,
138
+ summary,
139
+ details: failures.length === 0 ? [parsed.raw] : [...failures, parsed.raw],
140
+ parsed,
141
+ };
142
+ }
143
+ async function runMcpStatusCanary(options) {
144
+ const timeoutMs = options.timeoutMs ?? DEFAULT_CANARY_TIMEOUT_MS;
145
+ /* v8 ignore next -- default spawn is exercised by live canaries, while unit tests inject a fake child @preserve */
146
+ const spawnImpl = options.spawnImpl ?? child_process_1.spawn;
147
+ const command = options.command ?? process.execPath;
148
+ const commandArgs = options.commandArgs ?? defaultCommandArgs(options.agent, options.socketPath);
149
+ const requiredSenses = options.requiredSenses ?? [];
150
+ (0, runtime_1.emitNervesEvent)({
151
+ component: "daemon",
152
+ event: "daemon.mcp_canary_start",
153
+ message: "starting MCP status canary",
154
+ meta: {
155
+ agent: options.agent,
156
+ command,
157
+ commandArgs,
158
+ timeoutMs,
159
+ requiredSenses,
160
+ ignoreOverviewHealth: options.ignoreOverviewHealth === true,
161
+ },
162
+ });
163
+ const child = spawnImpl(command, commandArgs, { stdio: ["pipe", "pipe", "pipe"] });
164
+ let buffer = "";
165
+ let stderr = "";
166
+ const pending = new Map();
167
+ function cleanup() {
168
+ for (const [, request] of pending) {
169
+ clearTimeout(request.timer);
170
+ }
171
+ pending.clear();
172
+ if (!child.killed)
173
+ child.kill();
174
+ }
175
+ function failAll(error) {
176
+ for (const [, request] of pending) {
177
+ clearTimeout(request.timer);
178
+ request.reject(error);
179
+ }
180
+ pending.clear();
181
+ }
182
+ child.stderr?.setEncoding("utf8");
183
+ child.stderr?.on("data", (chunk) => {
184
+ stderr += chunk.toString();
185
+ });
186
+ child.stdout?.setEncoding("utf8");
187
+ child.stdout?.on("data", (chunk) => {
188
+ buffer += chunk.toString();
189
+ for (;;) {
190
+ const idx = buffer.indexOf("\n");
191
+ if (idx === -1)
192
+ break;
193
+ const line = buffer.slice(0, idx).trim();
194
+ buffer = buffer.slice(idx + 1);
195
+ if (!line)
196
+ continue;
197
+ let response;
198
+ try {
199
+ response = JSON.parse(line);
200
+ }
201
+ catch {
202
+ failAll(new Error(`MCP canary received malformed JSON: ${line}`));
203
+ return;
204
+ }
205
+ const id = typeof response.id === "number" ? response.id : null;
206
+ if (id === null)
207
+ continue;
208
+ const request = pending.get(id);
209
+ if (!request)
210
+ continue;
211
+ pending.delete(id);
212
+ clearTimeout(request.timer);
213
+ request.resolve(response);
214
+ }
215
+ });
216
+ child.on("error", (error) => failAll(error));
217
+ child.on("close", (code, signal) => {
218
+ if (pending.size === 0)
219
+ return;
220
+ failAll(new Error(`MCP canary process closed before response code=${code} signal=${signal ?? "none"} stderr=${stderr.trim()}`));
221
+ });
222
+ let nextId = 1;
223
+ function request(method, params) {
224
+ return new Promise((resolve, reject) => {
225
+ if (!child.stdin?.writable) {
226
+ reject(new Error("MCP canary stdin is not writable"));
227
+ return;
228
+ }
229
+ const id = nextId++;
230
+ const timer = setTimeout(() => {
231
+ pending.delete(id);
232
+ reject(new Error(`MCP canary timed out waiting for ${method}; stderr=${stderr.trim()}`));
233
+ }, timeoutMs);
234
+ pending.set(id, { resolve, reject, timer });
235
+ child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
236
+ });
237
+ }
238
+ try {
239
+ await request("initialize", {
240
+ protocolVersion: MCP_PROTOCOL_VERSION,
241
+ capabilities: {},
242
+ clientInfo: { name: "ouro-mcp-canary", version: "1.0" },
243
+ });
244
+ child.stdin?.write(JSON.stringify({ jsonrpc: "2.0", method: "initialized" }) + "\n");
245
+ const statusResponse = await request("tools/call", {
246
+ name: "status",
247
+ arguments: {},
248
+ });
249
+ const result = statusResponse.result;
250
+ if (result && typeof result === "object" && !Array.isArray(result) && result.isError === true) {
251
+ throw new Error(responseText(statusResponse));
252
+ }
253
+ const parsed = parseMcpStatusText(responseText(statusResponse));
254
+ const canary = validateMcpStatus(parsed, requiredSenses, {
255
+ ignoreOverviewHealth: options.ignoreOverviewHealth,
256
+ });
257
+ (0, runtime_1.emitNervesEvent)({
258
+ component: "daemon",
259
+ event: canary.ok ? "daemon.mcp_canary_end" : "daemon.mcp_canary_error",
260
+ level: canary.ok ? "info" : "error",
261
+ message: canary.summary,
262
+ meta: { agent: options.agent, ok: canary.ok },
263
+ });
264
+ return canary;
265
+ }
266
+ catch (error) {
267
+ const reason = error instanceof Error ? error.message : String(error);
268
+ (0, runtime_1.emitNervesEvent)({
269
+ component: "daemon",
270
+ event: "daemon.mcp_canary_error",
271
+ level: "error",
272
+ message: "MCP status canary failed",
273
+ meta: { agent: options.agent, reason },
274
+ });
275
+ return { ok: false, summary: `mcp canary failed: ${reason}`, details: [reason] };
276
+ }
277
+ finally {
278
+ child.stdin?.end();
279
+ cleanup();
280
+ }
281
+ }
282
+ function formatMcpStatusCanaryResult(result) {
283
+ return [
284
+ result.ok ? "mcp canary: ok" : "mcp canary: failed",
285
+ result.summary,
286
+ ...result.details.map((line) => ` ${line}`),
287
+ ].join("\n");
288
+ }
289
+ function createMcpStatusCanaryProbe(options) {
290
+ return {
291
+ name: `mcp-canary:${options.agent}`,
292
+ check: async () => {
293
+ const result = await runMcpStatusCanary(options);
294
+ return { ok: result.ok, detail: result.summary };
295
+ },
296
+ };
297
+ }
@@ -35,9 +35,9 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.FileMessageRouter = void 0;
37
37
  const fs = __importStar(require("fs"));
38
- const os = __importStar(require("os"));
39
38
  const path = __importStar(require("path"));
40
39
  const runtime_1 = require("../../nerves/runtime");
40
+ const identity_1 = require("../identity");
41
41
  function messageId(nowIso) {
42
42
  return `msg-${nowIso.replace(/[^0-9]/g, "")}`;
43
43
  }
@@ -45,7 +45,7 @@ class FileMessageRouter {
45
45
  baseDir;
46
46
  now;
47
47
  constructor(options = {}) {
48
- this.baseDir = options.baseDir ?? path.join(os.homedir(), ".agentstate", "messages");
48
+ this.baseDir = options.baseDir ?? (0, identity_1.getAgentMessagesRoot)();
49
49
  this.now = options.now ?? (() => new Date().toISOString());
50
50
  fs.mkdirSync(this.baseDir, { recursive: true });
51
51
  }
@@ -0,0 +1,135 @@
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.createRealOsCronDeps = createRealOsCronDeps;
37
+ exports.createRealCrontabDeps = createRealCrontabDeps;
38
+ exports.resolveOuroBinaryPath = resolveOuroBinaryPath;
39
+ const child_process_1 = require("child_process");
40
+ const fs = __importStar(require("fs"));
41
+ const os = __importStar(require("os"));
42
+ const path = __importStar(require("path"));
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ function createRealOsCronDeps() {
45
+ (0, runtime_1.emitNervesEvent)({
46
+ component: "daemon",
47
+ event: "daemon.os_cron_deps_created",
48
+ message: "created real OS cron deps",
49
+ meta: { platform: process.platform },
50
+ });
51
+ return {
52
+ exec: (cmd) => {
53
+ try {
54
+ (0, child_process_1.execSync)(cmd, { stdio: "ignore" });
55
+ }
56
+ catch {
57
+ /* best effort */
58
+ }
59
+ },
60
+ writeFile: (p, c) => fs.writeFileSync(p, c, "utf-8"),
61
+ removeFile: (p) => {
62
+ try {
63
+ fs.unlinkSync(p);
64
+ }
65
+ catch {
66
+ /* best effort — file may already be gone */
67
+ }
68
+ },
69
+ existsFile: (p) => fs.existsSync(p),
70
+ listDir: (dir) => {
71
+ try {
72
+ return fs.readdirSync(dir);
73
+ }
74
+ catch {
75
+ return [];
76
+ }
77
+ },
78
+ mkdirp: (dir) => fs.mkdirSync(dir, { recursive: true }),
79
+ homeDir: os.homedir(),
80
+ envPath: process.env.PATH ?? "",
81
+ };
82
+ }
83
+ function createRealCrontabDeps() {
84
+ (0, runtime_1.emitNervesEvent)({
85
+ component: "daemon",
86
+ event: "daemon.crontab_deps_created",
87
+ message: "created real crontab deps",
88
+ meta: {},
89
+ });
90
+ /* v8 ignore start -- crontab exec closures: calling these in tests would modify the real system crontab @preserve */
91
+ return {
92
+ execOutput: (cmd) => (0, child_process_1.execSync)(cmd, { encoding: "utf-8" }),
93
+ execWrite: (cmd, stdin) => {
94
+ (0, child_process_1.execSync)(cmd, { input: stdin, stdio: ["pipe", "ignore", "ignore"] });
95
+ },
96
+ };
97
+ /* v8 ignore stop */
98
+ }
99
+ /* v8 ignore start -- ouro path resolution: probes process.argv, filesystem layout, and PATH; branches depend on install method and runtime environment @preserve */
100
+ function resolveOuroBinaryPath() {
101
+ // Try to resolve from process.argv[1] — the script being run
102
+ const scriptPath = process.argv[1];
103
+ if (scriptPath) {
104
+ // If running via node dist/heart/daemon/daemon-entry.js, resolve the ouro wrapper
105
+ // The ouro binary is typically at the package root's bin
106
+ const distDir = path.resolve(path.dirname(scriptPath));
107
+ const packageBin = path.resolve(distDir, "..", "..", "..", "node_modules", ".bin", "ouro");
108
+ if (fs.existsSync(packageBin)) {
109
+ return packageBin;
110
+ }
111
+ // Try the repo-local scripts/ouro.sh
112
+ const repoOuro = path.resolve(distDir, "..", "..", "..", "scripts", "ouro.sh");
113
+ if (fs.existsSync(repoOuro)) {
114
+ return repoOuro;
115
+ }
116
+ }
117
+ // Try which ouro
118
+ try {
119
+ const result = (0, child_process_1.execSync)("which ouro", { encoding: "utf-8" }).trim();
120
+ if (result.length > 0)
121
+ return result;
122
+ }
123
+ catch {
124
+ /* not on PATH */
125
+ }
126
+ // Fallback: use "ouro" and rely on PATH
127
+ (0, runtime_1.emitNervesEvent)({
128
+ component: "daemon",
129
+ event: "daemon.ouro_path_fallback",
130
+ message: "could not resolve full ouro binary path, falling back to 'ouro'",
131
+ meta: {},
132
+ });
133
+ return "ouro";
134
+ }
135
+ /* v8 ignore stop */
@@ -43,6 +43,7 @@ exports.crontabLine = crontabLine;
43
43
  const os = __importStar(require("os"));
44
44
  const runtime_1 = require("../../nerves/runtime");
45
45
  const PLIST_PREFIX = "bot.ouro.";
46
+ const DAEMON_PLIST_FILENAME = "bot.ouro.daemon.plist";
46
47
  function plistLabel(job) {
47
48
  return `${PLIST_PREFIX}${job.agent}.${job.taskId}`;
48
49
  }
@@ -80,7 +81,7 @@ function scheduleToCalendarInterval(schedule) {
80
81
  result.Month = parseInt(month, 10);
81
82
  return Object.keys(result).length > 0 ? result : null;
82
83
  }
83
- function generatePlistXml(job) {
84
+ function generatePlistXml(job, envPath) {
84
85
  const label = plistLabel(job);
85
86
  const seconds = cadenceToSeconds(job.schedule);
86
87
  const calendar = seconds === null ? scheduleToCalendarInterval(job.schedule) : null;
@@ -97,7 +98,7 @@ function generatePlistXml(job) {
97
98
  else {
98
99
  triggerXml = ` <key>StartInterval</key>\n <integer>1800</integer>`;
99
100
  }
100
- return [
101
+ const lines = [
101
102
  `<?xml version="1.0" encoding="UTF-8"?>`,
102
103
  `<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">`,
103
104
  `<plist version="1.0">`,
@@ -110,14 +111,12 @@ function generatePlistXml(job) {
110
111
  ...job.command.split(" ").slice(1).map((arg) => ` <string>${arg}</string>`),
111
112
  ` </array>`,
112
113
  triggerXml,
113
- ` <key>StandardOutPath</key>`,
114
- ` <string>/tmp/${label}.stdout.log</string>`,
115
- ` <key>StandardErrorPath</key>`,
116
- ` <string>/tmp/${label}.stderr.log</string>`,
117
- `</dict>`,
118
- `</plist>`,
119
- ``,
120
- ].join("\n");
114
+ ];
115
+ if (envPath) {
116
+ lines.push(` <key>EnvironmentVariables</key>`, ` <dict>`, ` <key>PATH</key>`, ` <string>${envPath}</string>`, ` </dict>`);
117
+ }
118
+ lines.push(` <key>StandardOutPath</key>`, ` <string>/tmp/${label}.stdout.log</string>`, ` <key>StandardErrorPath</key>`, ` <string>/tmp/${label}.stderr.log</string>`, `</dict>`, `</plist>`, ``);
119
+ return lines.join("\n");
121
120
  }
122
121
  class LaunchdCronManager {
123
122
  deps;
@@ -148,7 +147,7 @@ class LaunchdCronManager {
148
147
  const label = plistLabel(job);
149
148
  const filename = `${label}.plist`;
150
149
  const fullPath = `${this.launchAgentsDir}/${filename}`;
151
- const xml = generatePlistXml(job);
150
+ const xml = generatePlistXml(job, this.deps.envPath);
152
151
  try {
153
152
  this.deps.exec(`launchctl unload "${fullPath}"`);
154
153
  }
@@ -178,7 +177,9 @@ class LaunchdCronManager {
178
177
  listPlistFiles() {
179
178
  if (!this.deps.existsFile(this.launchAgentsDir))
180
179
  return [];
181
- return this.deps.listDir(this.launchAgentsDir).filter((f) => f.startsWith(PLIST_PREFIX) && f.endsWith(".plist"));
180
+ return this.deps.listDir(this.launchAgentsDir).filter((f) => f.startsWith(PLIST_PREFIX) &&
181
+ f.endsWith(".plist") &&
182
+ f !== DAEMON_PLIST_FILENAME);
182
183
  }
183
184
  }
184
185
  exports.LaunchdCronManager = LaunchdCronManager;
@@ -248,6 +249,7 @@ function createOsCronManager(options = {}) {
248
249
  listDir: () => [],
249
250
  mkdirp: () => { },
250
251
  homeDir: os.homedir(),
252
+ envPath: process.env.PATH ?? "",
251
253
  };
252
254
  /* v8 ignore stop */
253
255
  return new LaunchdCronManager(deps);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const runtime_1 = require("../../nerves/runtime");
5
5
  const runtime_logging_1 = require("./runtime-logging");
6
- const ouro_bot_wrapper_1 = require("./ouro-bot-wrapper");
6
+ const ouro_bot_wrapper_1 = require("../versioning/ouro-bot-wrapper");
7
7
  (0, runtime_logging_1.configureDaemonRuntimeLogger)("ouro-bot");
8
8
  (0, runtime_1.emitNervesEvent)({
9
9
  component: "daemon",
@@ -12,12 +12,14 @@ const ouro_bot_wrapper_1 = require("./ouro-bot-wrapper");
12
12
  meta: { args: process.argv.slice(2) },
13
13
  });
14
14
  void (0, ouro_bot_wrapper_1.runOuroBotWrapper)(process.argv.slice(2)).catch((error) => {
15
+ const message = error instanceof Error ? error.message : String(error);
16
+ process.stderr.write(`${message}\n`);
15
17
  (0, runtime_1.emitNervesEvent)({
16
18
  level: "error",
17
19
  component: "daemon",
18
20
  event: "daemon.ouro_bot_entry_error",
19
21
  message: "ouro.bot wrapper entrypoint failed",
20
- meta: { error: error instanceof Error ? error.message : String(error) },
22
+ meta: { error: message },
21
23
  });
22
24
  process.exit(1);
23
25
  });
@@ -12,12 +12,14 @@ const runtime_logging_1 = require("./runtime-logging");
12
12
  meta: { args: process.argv.slice(2) },
13
13
  });
14
14
  void (0, daemon_cli_1.runOuroCli)(process.argv.slice(2)).catch((error) => {
15
+ const message = error instanceof Error ? error.message : String(error);
16
+ process.stderr.write(`${message}\n`);
15
17
  (0, runtime_1.emitNervesEvent)({
16
18
  level: "error",
17
19
  component: "daemon",
18
20
  event: "daemon.cli_entry_error",
19
21
  message: "ouro CLI entrypoint failed",
20
- meta: { error: error instanceof Error ? error.message : String(error) },
22
+ meta: { error: message },
21
23
  });
22
24
  process.exit(1);
23
25
  });