@ouro.bot/cli 0.1.0-alpha.34 → 0.1.0-alpha.340

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 (314) hide show
  1. package/README.md +188 -187
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
  4. package/changelog.json +2031 -0
  5. package/dist/arc/attention-types.js +8 -0
  6. package/dist/arc/cares.js +140 -0
  7. package/dist/arc/episodes.js +117 -0
  8. package/dist/arc/intentions.js +133 -0
  9. package/dist/arc/json-store.js +117 -0
  10. package/dist/arc/obligations.js +237 -0
  11. package/dist/arc/packets.js +193 -0
  12. package/dist/arc/presence.js +185 -0
  13. package/dist/arc/task-lifecycle.js +65 -0
  14. package/dist/heart/active-work.js +832 -0
  15. package/dist/heart/agent-entry.js +37 -2
  16. package/dist/heart/attachments/image-normalize.js +194 -0
  17. package/dist/heart/attachments/materialize.js +97 -0
  18. package/dist/heart/attachments/originals.js +88 -0
  19. package/dist/heart/attachments/render.js +29 -0
  20. package/dist/heart/attachments/sources/adapter.js +2 -0
  21. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  22. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  23. package/dist/heart/attachments/sources/index.js +16 -0
  24. package/dist/heart/attachments/store.js +103 -0
  25. package/dist/heart/attachments/types.js +93 -0
  26. package/dist/heart/auth/auth-flow.js +463 -0
  27. package/dist/heart/bridges/manager.js +358 -0
  28. package/dist/heart/bridges/state-machine.js +135 -0
  29. package/dist/heart/bridges/store.js +123 -0
  30. package/dist/heart/bundle-state.js +168 -0
  31. package/dist/heart/commitments.js +111 -0
  32. package/dist/heart/config-registry.js +304 -0
  33. package/dist/heart/config.js +53 -21
  34. package/dist/heart/core.js +695 -195
  35. package/dist/heart/cross-chat-delivery.js +131 -0
  36. package/dist/heart/daemon/agent-config-check.js +292 -0
  37. package/dist/heart/daemon/agent-discovery.js +79 -3
  38. package/dist/heart/daemon/agent-service.js +360 -0
  39. package/dist/heart/daemon/agentic-repair.js +170 -0
  40. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  41. package/dist/heart/daemon/cadence.js +70 -0
  42. package/dist/heart/daemon/cli-defaults.js +591 -0
  43. package/dist/heart/daemon/cli-exec.js +2297 -0
  44. package/dist/heart/daemon/cli-help.js +306 -0
  45. package/dist/heart/daemon/cli-parse.js +824 -0
  46. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  47. package/dist/heart/daemon/cli-render.js +512 -0
  48. package/dist/heart/daemon/cli-types.js +8 -0
  49. package/dist/heart/daemon/daemon-cli.js +30 -1171
  50. package/dist/heart/daemon/daemon-entry.js +358 -3
  51. package/dist/heart/daemon/daemon-health.js +141 -0
  52. package/dist/heart/daemon/daemon-runtime-sync.js +157 -12
  53. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  54. package/dist/heart/daemon/daemon.js +751 -58
  55. package/dist/heart/daemon/doctor-types.js +8 -0
  56. package/dist/heart/daemon/doctor.js +401 -0
  57. package/dist/heart/daemon/health-monitor.js +79 -1
  58. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  59. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  60. package/dist/heart/daemon/http-health-probe.js +80 -0
  61. package/dist/heart/daemon/inner-status.js +89 -0
  62. package/dist/heart/daemon/interactive-repair.js +91 -0
  63. package/dist/heart/daemon/launchd.js +46 -9
  64. package/dist/heart/daemon/log-tailer.js +82 -12
  65. package/dist/heart/daemon/logs-prune.js +105 -0
  66. package/dist/heart/daemon/message-router.js +17 -8
  67. package/dist/heart/daemon/os-cron-deps.js +134 -0
  68. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  69. package/dist/heart/daemon/process-manager.js +201 -0
  70. package/dist/heart/daemon/provider-discovery.js +105 -0
  71. package/dist/heart/daemon/pulse.js +463 -0
  72. package/dist/heart/daemon/run-hooks.js +2 -0
  73. package/dist/heart/daemon/runtime-logging.js +67 -16
  74. package/dist/heart/daemon/runtime-metadata.js +101 -0
  75. package/dist/heart/daemon/runtime-mode.js +67 -0
  76. package/dist/heart/daemon/safe-mode.js +161 -0
  77. package/dist/heart/daemon/sense-manager.js +72 -3
  78. package/dist/heart/daemon/session-id-resolver.js +131 -0
  79. package/dist/heart/daemon/skill-management-installer.js +94 -0
  80. package/dist/heart/daemon/socket-client.js +307 -0
  81. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  82. package/dist/heart/daemon/startup-tui.js +237 -0
  83. package/dist/heart/daemon/task-scheduler.js +3 -25
  84. package/dist/heart/daemon/thoughts.js +510 -0
  85. package/dist/heart/daemon/up-progress.js +135 -0
  86. package/dist/heart/delegation.js +62 -0
  87. package/dist/heart/habits/habit-migration.js +181 -0
  88. package/dist/heart/habits/habit-parser.js +140 -0
  89. package/dist/heart/habits/habit-scheduler.js +371 -0
  90. package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -120
  91. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  92. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  93. package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
  94. package/dist/heart/identity.js +154 -59
  95. package/dist/heart/kicks.js +2 -20
  96. package/dist/heart/mcp/mcp-server.js +653 -0
  97. package/dist/heart/migrate-config.js +127 -0
  98. package/dist/heart/model-capabilities.js +59 -0
  99. package/dist/heart/outlook/outlook-http-hooks.js +64 -0
  100. package/dist/heart/outlook/outlook-http-response.js +7 -0
  101. package/dist/heart/outlook/outlook-http-routes.js +232 -0
  102. package/dist/heart/outlook/outlook-http-static.js +99 -0
  103. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  104. package/dist/heart/outlook/outlook-http.js +99 -0
  105. package/dist/heart/outlook/outlook-read.js +28 -0
  106. package/dist/heart/outlook/outlook-types.js +27 -0
  107. package/dist/heart/outlook/outlook-view.js +194 -0
  108. package/dist/heart/outlook/readers/agent-machine.js +355 -0
  109. package/dist/heart/outlook/readers/continuity-readers.js +332 -0
  110. package/dist/heart/outlook/readers/runtime-readers.js +660 -0
  111. package/dist/heart/outlook/readers/sessions.js +231 -0
  112. package/dist/heart/outlook/readers/shared.js +111 -0
  113. package/dist/heart/progress-story.js +42 -0
  114. package/dist/heart/provider-failover.js +135 -0
  115. package/dist/heart/provider-models.js +81 -0
  116. package/dist/heart/provider-ping.js +234 -0
  117. package/dist/heart/providers/anthropic-token.js +163 -0
  118. package/dist/heart/providers/anthropic.js +171 -50
  119. package/dist/heart/providers/azure.js +97 -11
  120. package/dist/heart/providers/error-classification.js +63 -0
  121. package/dist/heart/providers/github-copilot.js +135 -0
  122. package/dist/heart/providers/minimax-vlm.js +189 -0
  123. package/dist/heart/providers/minimax.js +23 -6
  124. package/dist/heart/providers/openai-codex.js +33 -23
  125. package/dist/heart/session-activity.js +190 -0
  126. package/dist/heart/session-events.js +726 -0
  127. package/dist/heart/session-recall.js +162 -0
  128. package/dist/heart/start-of-turn-packet.js +341 -0
  129. package/dist/heart/streaming.js +36 -27
  130. package/dist/heart/sync.js +332 -0
  131. package/dist/heart/target-resolution.js +127 -0
  132. package/dist/heart/tempo.js +93 -0
  133. package/dist/heart/temporal-view.js +41 -0
  134. package/dist/heart/tool-activity-callbacks.js +36 -0
  135. package/dist/heart/tool-description.js +135 -0
  136. package/dist/heart/tool-friction.js +55 -0
  137. package/dist/heart/tool-loop.js +200 -0
  138. package/dist/heart/turn-context.js +358 -0
  139. package/dist/heart/turn-coordinator.js +28 -0
  140. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  141. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  142. package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
  143. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  144. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  145. package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
  146. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  147. package/dist/mind/associative-recall.js +137 -66
  148. package/dist/mind/bundle-manifest.js +7 -1
  149. package/dist/mind/context.js +89 -93
  150. package/dist/mind/diary-integrity.js +60 -0
  151. package/dist/mind/{memory.js → diary.js} +84 -96
  152. package/dist/mind/embedding-provider.js +60 -0
  153. package/dist/mind/file-state.js +179 -0
  154. package/dist/mind/first-impressions.js +14 -1
  155. package/dist/mind/friends/channel.js +56 -0
  156. package/dist/mind/friends/group-context.js +144 -0
  157. package/dist/mind/friends/resolver.js +37 -0
  158. package/dist/mind/friends/store-file.js +58 -3
  159. package/dist/mind/friends/trust-explanation.js +74 -0
  160. package/dist/mind/friends/types.js +8 -0
  161. package/dist/mind/journal-index.js +161 -0
  162. package/dist/mind/obligation-steering.js +221 -0
  163. package/dist/mind/pending.js +74 -7
  164. package/dist/mind/prompt.js +999 -111
  165. package/dist/mind/provenance-trust.js +26 -0
  166. package/dist/mind/scrutiny.js +173 -0
  167. package/dist/mind/token-estimate.js +8 -12
  168. package/dist/nerves/cli-logging.js +7 -1
  169. package/dist/nerves/coverage/audit.js +1 -1
  170. package/dist/nerves/coverage/file-completeness.js +83 -5
  171. package/dist/nerves/coverage/run-artifacts.js +1 -1
  172. package/dist/nerves/event-buffer.js +111 -0
  173. package/dist/nerves/index.js +224 -4
  174. package/dist/nerves/observation.js +20 -0
  175. package/dist/nerves/redact.js +79 -0
  176. package/dist/nerves/runtime.js +5 -1
  177. package/dist/outlook-ui/assets/index-DC7sZefn.js +61 -0
  178. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  179. package/dist/outlook-ui/index.html +15 -0
  180. package/dist/repertoire/ado-client.js +15 -56
  181. package/dist/repertoire/ado-semantic.js +11 -10
  182. package/dist/repertoire/api-client.js +97 -0
  183. package/dist/repertoire/bitwarden-store.js +319 -0
  184. package/dist/repertoire/bundle-templates.js +72 -0
  185. package/dist/repertoire/bw-installer.js +79 -0
  186. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  187. package/dist/repertoire/coding/context-pack.js +330 -0
  188. package/dist/repertoire/coding/feedback.js +197 -30
  189. package/dist/repertoire/coding/manager.js +158 -9
  190. package/dist/repertoire/coding/spawner.js +55 -9
  191. package/dist/repertoire/coding/tools.js +170 -7
  192. package/dist/repertoire/commerce-errors.js +109 -0
  193. package/dist/repertoire/commerce-self-test.js +156 -0
  194. package/dist/repertoire/credential-access.js +527 -0
  195. package/dist/repertoire/duffel-client.js +185 -0
  196. package/dist/repertoire/github-client.js +14 -55
  197. package/dist/repertoire/graph-client.js +11 -52
  198. package/dist/repertoire/guardrails.js +375 -0
  199. package/dist/repertoire/mcp-client.js +255 -0
  200. package/dist/repertoire/mcp-manager.js +305 -0
  201. package/dist/repertoire/mcp-tools.js +63 -0
  202. package/dist/repertoire/shell-sessions.js +133 -0
  203. package/dist/repertoire/skills.js +14 -23
  204. package/dist/repertoire/stripe-client.js +131 -0
  205. package/dist/repertoire/tasks/board.js +43 -5
  206. package/dist/repertoire/tasks/fix.js +182 -0
  207. package/dist/repertoire/tasks/index.js +28 -10
  208. package/dist/repertoire/tasks/lifecycle.js +2 -2
  209. package/dist/repertoire/tasks/parser.js +3 -2
  210. package/dist/repertoire/tasks/scanner.js +194 -37
  211. package/dist/repertoire/tasks/transitions.js +16 -79
  212. package/dist/repertoire/tool-results.js +29 -0
  213. package/dist/repertoire/tools-attachments.js +316 -0
  214. package/dist/repertoire/tools-base.js +45 -771
  215. package/dist/repertoire/tools-bluebubbles.js +1 -0
  216. package/dist/repertoire/tools-bridge.js +141 -0
  217. package/dist/repertoire/tools-bundle.js +984 -0
  218. package/dist/repertoire/tools-config.js +185 -0
  219. package/dist/repertoire/tools-continuity.js +248 -0
  220. package/dist/repertoire/tools-credential.js +182 -0
  221. package/dist/repertoire/tools-files.js +342 -0
  222. package/dist/repertoire/tools-flight.js +224 -0
  223. package/dist/repertoire/tools-flow.js +105 -0
  224. package/dist/repertoire/tools-github.js +1 -7
  225. package/dist/repertoire/tools-memory.js +376 -0
  226. package/dist/repertoire/tools-session.js +739 -0
  227. package/dist/repertoire/tools-shell.js +120 -0
  228. package/dist/repertoire/tools-stripe.js +180 -0
  229. package/dist/repertoire/tools-surface.js +243 -0
  230. package/dist/repertoire/tools-teams.js +12 -62
  231. package/dist/repertoire/tools-travel.js +125 -0
  232. package/dist/repertoire/tools-user-profile.js +144 -0
  233. package/dist/repertoire/tools-vault.js +110 -0
  234. package/dist/repertoire/tools.js +144 -138
  235. package/dist/repertoire/travel-api-client.js +360 -0
  236. package/dist/repertoire/user-profile.js +118 -0
  237. package/dist/repertoire/vault-setup.js +241 -0
  238. package/dist/scripts/claude-code-hook.js +41 -0
  239. package/dist/scripts/claude-code-stop-hook.js +47 -0
  240. package/dist/senses/attention-queue.js +116 -0
  241. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  242. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  243. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +225 -9
  244. package/dist/senses/bluebubbles/entry.js +13 -0
  245. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  246. package/dist/senses/bluebubbles/index.js +1590 -0
  247. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  248. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +43 -12
  249. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  250. package/dist/senses/bluebubbles/replay.js +129 -0
  251. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  252. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  253. package/dist/senses/cli/bracketed-paste.js +82 -0
  254. package/dist/senses/cli/image-paste.js +287 -0
  255. package/dist/senses/cli/image-ref-navigation.js +75 -0
  256. package/dist/senses/cli/ink-app.js +156 -0
  257. package/dist/senses/cli/inline-diff.js +64 -0
  258. package/dist/senses/cli/input-keys.js +174 -0
  259. package/dist/senses/cli/kill-ring.js +86 -0
  260. package/dist/senses/cli/message-list.js +51 -0
  261. package/dist/senses/cli/ouro-tui.js +605 -0
  262. package/dist/senses/cli/spinner-imperative.js +135 -0
  263. package/dist/senses/cli/spinner.js +101 -0
  264. package/dist/senses/cli/status-line.js +60 -0
  265. package/dist/senses/cli/streaming-markdown.js +526 -0
  266. package/dist/senses/cli/tool-display.js +83 -0
  267. package/dist/senses/cli/tool-render.js +85 -0
  268. package/dist/senses/cli/tui-store.js +240 -0
  269. package/dist/senses/cli/virtual-list.js +35 -0
  270. package/dist/senses/cli-entry.js +1 -1
  271. package/dist/senses/cli-layout.js +187 -0
  272. package/dist/senses/cli.js +595 -246
  273. package/dist/senses/commands.js +65 -1
  274. package/dist/senses/continuity.js +94 -0
  275. package/dist/senses/habit-turn-message.js +108 -0
  276. package/dist/senses/inner-dialog-worker.js +112 -19
  277. package/dist/senses/inner-dialog.js +633 -86
  278. package/dist/senses/pipeline.js +567 -0
  279. package/dist/senses/shared-turn.js +199 -0
  280. package/dist/senses/surface-tool.js +68 -0
  281. package/dist/senses/teams.js +665 -160
  282. package/dist/senses/trust-gate.js +112 -2
  283. package/package.json +29 -7
  284. package/skills/agent-commerce.md +106 -0
  285. package/skills/browser-navigation.md +110 -0
  286. package/skills/commerce-setup-guide.md +116 -0
  287. package/skills/commerce-setup.md +84 -0
  288. package/skills/configure-dev-tools.md +81 -0
  289. package/skills/travel-planning.md +138 -0
  290. package/dist/heart/daemon/subagent-installer.js +0 -134
  291. package/dist/senses/bluebubbles-entry.js +0 -11
  292. package/dist/senses/bluebubbles.js +0 -547
  293. package/dist/senses/debug-activity.js +0 -124
  294. package/subagents/README.md +0 -73
  295. package/subagents/work-doer.md +0 -235
  296. package/subagents/work-merger.md +0 -618
  297. package/subagents/work-planner.md +0 -382
  298. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  299. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  300. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  301. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  302. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  303. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  304. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  305. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  306. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  307. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  308. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  309. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  310. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  311. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  312. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  313. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  314. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deliverCrossChatMessage = deliverCrossChatMessage;
4
+ const types_1 = require("../mind/friends/types");
5
+ const runtime_1 = require("../nerves/runtime");
6
+ function buildPendingEnvelope(request, agentName, now) {
7
+ return {
8
+ from: agentName,
9
+ friendId: request.friendId,
10
+ channel: request.channel,
11
+ key: request.key,
12
+ content: request.content,
13
+ timestamp: now,
14
+ };
15
+ }
16
+ function queueForLater(request, deps, detail) {
17
+ deps.queuePending(buildPendingEnvelope(request, deps.agentName, (deps.now ?? Date.now)()));
18
+ return {
19
+ status: "queued_for_later",
20
+ detail,
21
+ };
22
+ }
23
+ function isExplicitlyAuthorized(request) {
24
+ return request.intent === "explicit_cross_chat"
25
+ && Boolean(request.authorizingSession)
26
+ && (0, types_1.isTrustedLevel)(request.authorizingSession?.trustLevel);
27
+ }
28
+ async function deliverCrossChatMessage(request, deps) {
29
+ (0, runtime_1.emitNervesEvent)({
30
+ component: "engine",
31
+ event: "engine.cross_chat_delivery_start",
32
+ message: "resolving cross-chat delivery",
33
+ meta: {
34
+ friendId: request.friendId,
35
+ channel: request.channel,
36
+ key: request.key,
37
+ intent: request.intent,
38
+ authorizingTrustLevel: request.authorizingSession?.trustLevel ?? null,
39
+ },
40
+ });
41
+ if (!isExplicitlyAuthorized(request) && request.intent !== "generic_outreach") {
42
+ const result = {
43
+ status: "blocked",
44
+ detail: "cross-chat delivery requires a trusted asking session or generic outreach intent",
45
+ };
46
+ (0, runtime_1.emitNervesEvent)({
47
+ level: "warn",
48
+ component: "engine",
49
+ event: "engine.cross_chat_delivery_end",
50
+ message: "blocked cross-chat delivery",
51
+ meta: {
52
+ friendId: request.friendId,
53
+ channel: request.channel,
54
+ key: request.key,
55
+ status: result.status,
56
+ },
57
+ });
58
+ return result;
59
+ }
60
+ const deliverer = deps.deliverers?.[request.channel];
61
+ if (!deliverer) {
62
+ const result = queueForLater(request, deps, "live delivery unavailable right now; queued for the next active turn");
63
+ (0, runtime_1.emitNervesEvent)({
64
+ component: "engine",
65
+ event: "engine.cross_chat_delivery_end",
66
+ message: "queued explicit cross-chat delivery because no live deliverer was available",
67
+ meta: {
68
+ friendId: request.friendId,
69
+ channel: request.channel,
70
+ key: request.key,
71
+ status: result.status,
72
+ },
73
+ });
74
+ return result;
75
+ }
76
+ try {
77
+ const direct = await deliverer(request);
78
+ if (direct.status === "delivered_now" || direct.status === "blocked" || direct.status === "failed") {
79
+ const result = {
80
+ status: direct.status,
81
+ detail: direct.detail,
82
+ };
83
+ (0, runtime_1.emitNervesEvent)({
84
+ level: result.status === "failed" ? "error" : result.status === "blocked" ? "warn" : "info",
85
+ component: "engine",
86
+ event: "engine.cross_chat_delivery_end",
87
+ message: "completed direct cross-chat delivery resolution",
88
+ meta: {
89
+ friendId: request.friendId,
90
+ channel: request.channel,
91
+ key: request.key,
92
+ status: result.status,
93
+ },
94
+ });
95
+ return result;
96
+ }
97
+ const result = queueForLater(request, deps, direct.detail.trim() || "live delivery unavailable right now; queued for the next active turn");
98
+ (0, runtime_1.emitNervesEvent)({
99
+ component: "engine",
100
+ event: "engine.cross_chat_delivery_end",
101
+ message: "queued explicit cross-chat delivery after adapter reported unavailability",
102
+ meta: {
103
+ friendId: request.friendId,
104
+ channel: request.channel,
105
+ key: request.key,
106
+ status: result.status,
107
+ },
108
+ });
109
+ return result;
110
+ }
111
+ catch (error) {
112
+ const result = {
113
+ status: "failed",
114
+ detail: error instanceof Error ? error.message : String(error),
115
+ };
116
+ (0, runtime_1.emitNervesEvent)({
117
+ level: "error",
118
+ component: "engine",
119
+ event: "engine.cross_chat_delivery_end",
120
+ message: "cross-chat delivery threw unexpectedly",
121
+ meta: {
122
+ friendId: request.friendId,
123
+ channel: request.channel,
124
+ key: request.key,
125
+ status: result.status,
126
+ reason: result.detail,
127
+ },
128
+ });
129
+ return result;
130
+ }
131
+ }
@@ -0,0 +1,292 @@
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.checkAgentConfig = checkAgentConfig;
37
+ exports.checkAgentConfigWithProviderHealth = checkAgentConfigWithProviderHealth;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const identity_1 = require("../identity");
41
+ const runtime_1 = require("../../nerves/runtime");
42
+ function isAgentProvider(value) {
43
+ return Object.prototype.hasOwnProperty.call(identity_1.PROVIDER_CREDENTIALS, value);
44
+ }
45
+ function formatFacingList(facings) {
46
+ if (facings.length === 1)
47
+ return facings[0];
48
+ return `${facings.slice(0, -1).join(", ")} and ${facings[facings.length - 1]}`;
49
+ }
50
+ function selectedProviderMap(selectedProviders) {
51
+ const byProvider = new Map();
52
+ for (const selected of selectedProviders) {
53
+ const facings = byProvider.get(selected.provider) ?? [];
54
+ facings.push(selected.facing);
55
+ byProvider.set(selected.provider, facings);
56
+ }
57
+ return byProvider;
58
+ }
59
+ function resolveFacingProvider(parsed, facing, agentName, agentJsonPath) {
60
+ const raw = parsed[facing];
61
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
62
+ return {
63
+ ok: false,
64
+ result: {
65
+ ok: false,
66
+ error: `agent.json for '${agentName}' is missing ${facing}.provider`,
67
+ fix: `Add ${facing}: { provider, model } to ${agentJsonPath}. Valid providers: ${Object.keys(identity_1.PROVIDER_CREDENTIALS).join(", ")}`,
68
+ },
69
+ };
70
+ }
71
+ const provider = raw.provider;
72
+ if (typeof provider !== "string" || provider.length === 0) {
73
+ return {
74
+ ok: false,
75
+ result: {
76
+ ok: false,
77
+ error: `agent.json for '${agentName}' is missing ${facing}.provider`,
78
+ fix: `Set ${facing}.provider in ${agentJsonPath}. Valid providers: ${Object.keys(identity_1.PROVIDER_CREDENTIALS).join(", ")}`,
79
+ },
80
+ };
81
+ }
82
+ if (!isAgentProvider(provider)) {
83
+ return {
84
+ ok: false,
85
+ result: {
86
+ ok: false,
87
+ error: `Unknown provider '${provider}' in ${facing}.provider for '${agentName}'`,
88
+ fix: `Set ${facing}.provider to one of: ${Object.keys(identity_1.PROVIDER_CREDENTIALS).join(", ")}`,
89
+ },
90
+ };
91
+ }
92
+ return { ok: true, selected: { facing, provider } };
93
+ }
94
+ function resolveSelectedProviders(parsed, agentName, agentJsonPath) {
95
+ const hasHumanFacing = parsed.humanFacing !== undefined;
96
+ const hasAgentFacing = parsed.agentFacing !== undefined;
97
+ if (!hasHumanFacing && !hasAgentFacing && typeof parsed.provider === "string") {
98
+ if (!isAgentProvider(parsed.provider)) {
99
+ return {
100
+ ok: false,
101
+ result: {
102
+ ok: false,
103
+ error: `Unknown provider '${parsed.provider}' in agent.json for '${agentName}'`,
104
+ fix: `Set provider to one of: ${Object.keys(identity_1.PROVIDER_CREDENTIALS).join(", ")}`,
105
+ },
106
+ };
107
+ }
108
+ return { ok: true, selectedProviders: [{ facing: "provider", provider: parsed.provider }] };
109
+ }
110
+ const human = resolveFacingProvider(parsed, "humanFacing", agentName, agentJsonPath);
111
+ if (!human.ok)
112
+ return human;
113
+ const agent = resolveFacingProvider(parsed, "agentFacing", agentName, agentJsonPath);
114
+ if (!agent.ok)
115
+ return agent;
116
+ return { ok: true, selectedProviders: [human.selected, agent.selected] };
117
+ }
118
+ function readConfigCheckContext(agentName, bundlesRoot, secretsRoot) {
119
+ const agentJsonPath = path.join(bundlesRoot, `${agentName}.ouro`, "agent.json");
120
+ let raw;
121
+ try {
122
+ raw = fs.readFileSync(agentJsonPath, "utf-8");
123
+ }
124
+ catch {
125
+ return {
126
+ ok: false,
127
+ result: {
128
+ ok: false,
129
+ error: `agent.json not found at ${agentJsonPath}`,
130
+ fix: `Run 'ouro hatch ${agentName}' to create the agent bundle, or verify that ${bundlesRoot}/${agentName}.ouro/ exists.`,
131
+ },
132
+ };
133
+ }
134
+ let parsed;
135
+ try {
136
+ parsed = JSON.parse(raw);
137
+ }
138
+ catch {
139
+ return {
140
+ ok: false,
141
+ result: {
142
+ ok: false,
143
+ error: `agent.json at ${agentJsonPath} contains invalid JSON`,
144
+ fix: `Open ${agentJsonPath} and fix the JSON syntax.`,
145
+ },
146
+ };
147
+ }
148
+ // Disabled agents are valid — they just won't run
149
+ if (parsed.enabled === false) {
150
+ return {
151
+ ok: true,
152
+ context: {
153
+ agentJsonPath,
154
+ secretsJsonPath: path.join(secretsRoot, agentName, "secrets.json"),
155
+ providers: {},
156
+ selectedProviders: [],
157
+ },
158
+ };
159
+ }
160
+ const selected = resolveSelectedProviders(parsed, agentName, agentJsonPath);
161
+ if (!selected.ok)
162
+ return selected;
163
+ const secretsJsonPath = path.join(secretsRoot, agentName, "secrets.json");
164
+ let secrets;
165
+ try {
166
+ const secretsRaw = fs.readFileSync(secretsJsonPath, "utf-8");
167
+ secrets = JSON.parse(secretsRaw);
168
+ }
169
+ catch {
170
+ const firstProvider = selected.selectedProviders[0].provider;
171
+ return {
172
+ ok: false,
173
+ result: {
174
+ ok: false,
175
+ error: `secrets.json not found or unreadable at ${secretsJsonPath}`,
176
+ fix: `Run 'ouro auth --agent ${agentName} --provider ${firstProvider}' to configure credentials, or create ${secretsJsonPath} with providers.${firstProvider} credentials.`,
177
+ },
178
+ };
179
+ }
180
+ const providers = secrets.providers;
181
+ if (!providers || typeof providers !== "object" || Array.isArray(providers)) {
182
+ const firstProvider = selected.selectedProviders[0].provider;
183
+ return {
184
+ ok: false,
185
+ result: {
186
+ ok: false,
187
+ error: `secrets.json for '${agentName}' is missing providers object`,
188
+ fix: `Run 'ouro auth --agent ${agentName} --provider ${firstProvider}' to configure credentials.`,
189
+ },
190
+ };
191
+ }
192
+ return {
193
+ ok: true,
194
+ context: {
195
+ agentJsonPath,
196
+ secretsJsonPath,
197
+ providers,
198
+ selectedProviders: selected.selectedProviders,
199
+ },
200
+ };
201
+ }
202
+ function validateSelectedProviderSecrets(agentName, context) {
203
+ for (const [provider, facings] of selectedProviderMap(context.selectedProviders)) {
204
+ const desc = identity_1.PROVIDER_CREDENTIALS[provider];
205
+ const providerSecrets = context.providers[provider];
206
+ const selectedBy = formatFacingList(facings);
207
+ if (!providerSecrets) {
208
+ return {
209
+ ok: false,
210
+ error: `secrets.json for '${agentName}' is missing providers.${provider} section selected by ${selectedBy}`,
211
+ fix: `Run 'ouro auth --agent ${agentName} --provider ${provider}' to configure ${provider} credentials.`,
212
+ };
213
+ }
214
+ // Azure special case: managed identity only needs endpoint + deployment.
215
+ if (provider === "azure") {
216
+ const hasEndpoint = typeof providerSecrets.endpoint === "string" && providerSecrets.endpoint.length > 0;
217
+ const hasDeployment = typeof providerSecrets.deployment === "string" && providerSecrets.deployment.length > 0;
218
+ const hasManagedId = typeof providerSecrets.managedIdentityClientId === "string" && providerSecrets.managedIdentityClientId.length > 0;
219
+ if (hasEndpoint && hasDeployment && hasManagedId) {
220
+ continue;
221
+ }
222
+ }
223
+ const missing = desc.required.filter((field) => {
224
+ const val = providerSecrets[field];
225
+ return typeof val !== "string" || val.length === 0;
226
+ });
227
+ if (missing.length > 0) {
228
+ return {
229
+ ok: false,
230
+ error: `secrets.json for '${agentName}' is missing required ${provider} credentials selected by ${selectedBy}: ${missing.join(", ")}`,
231
+ fix: `Run 'ouro auth --agent ${agentName} --provider ${provider}' to set up ${provider} credentials, or add the missing fields to providers.${provider} in ${context.secretsJsonPath}.`,
232
+ };
233
+ }
234
+ }
235
+ return { ok: true };
236
+ }
237
+ function emitConfigValid(agentName, context, liveProviderCheck) {
238
+ (0, runtime_1.emitNervesEvent)({
239
+ component: "daemon",
240
+ event: "daemon.agent_config_valid",
241
+ message: "agent config validation passed",
242
+ meta: {
243
+ agent: agentName,
244
+ providers: [...selectedProviderMap(context.selectedProviders).keys()],
245
+ liveProviderCheck,
246
+ },
247
+ });
248
+ }
249
+ function providerPingFailureResult(agentName, provider, facings, result) {
250
+ const selectedBy = formatFacingList(facings);
251
+ const authFix = `Run 'ouro auth --agent ${agentName} --provider ${provider}' to refresh credentials.`;
252
+ const verifyFix = `Run 'ouro auth verify --agent ${agentName} --provider ${provider}' for details.`;
253
+ return {
254
+ ok: false,
255
+ error: `selected provider ${provider} for ${selectedBy} failed health check: ${result.message}`,
256
+ fix: `${result.classification === "auth-failure" ? authFix : verifyFix} Or switch the affected facing to a working provider.`,
257
+ };
258
+ }
259
+ /**
260
+ * Pre-spawn validation: ensures agent.json exists and required secrets are present.
261
+ * Returns `{ ok: true }` when the agent is ready to run, or a descriptive error
262
+ * with an actionable fix message when something is missing.
263
+ */
264
+ function checkAgentConfig(agentName, bundlesRoot, secretsRoot) {
265
+ const contextResult = readConfigCheckContext(agentName, bundlesRoot, secretsRoot);
266
+ if (!contextResult.ok)
267
+ return contextResult.result;
268
+ const context = contextResult.context;
269
+ const structural = validateSelectedProviderSecrets(agentName, context);
270
+ if (!structural.ok)
271
+ return structural;
272
+ emitConfigValid(agentName, context, false);
273
+ return { ok: true };
274
+ }
275
+ async function checkAgentConfigWithProviderHealth(agentName, bundlesRoot, secretsRoot, deps = {}) {
276
+ const contextResult = readConfigCheckContext(agentName, bundlesRoot, secretsRoot);
277
+ if (!contextResult.ok)
278
+ return contextResult.result;
279
+ const context = contextResult.context;
280
+ const structural = validateSelectedProviderSecrets(agentName, context);
281
+ if (!structural.ok)
282
+ return structural;
283
+ const ping = deps.pingProvider ?? (await Promise.resolve().then(() => __importStar(require("../provider-ping")))).pingProvider;
284
+ for (const [provider, facings] of selectedProviderMap(context.selectedProviders)) {
285
+ const result = await ping(provider, context.providers[provider]);
286
+ if (!result.ok) {
287
+ return providerPingFailureResult(agentName, provider, facings, result);
288
+ }
289
+ }
290
+ emitConfigValid(agentName, context, true);
291
+ return { ok: true };
292
+ }
@@ -33,12 +33,25 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.listAllBundleAgents = listAllBundleAgents;
36
37
  exports.listEnabledBundleAgents = listEnabledBundleAgents;
38
+ exports.listBundleSyncRows = listBundleSyncRows;
37
39
  const fs = __importStar(require("fs"));
38
40
  const path = __importStar(require("path"));
41
+ const child_process_1 = require("child_process");
39
42
  const identity_1 = require("../identity");
40
43
  const runtime_1 = require("../../nerves/runtime");
41
- function listEnabledBundleAgents(options = {}) {
44
+ /**
45
+ * Walk the bundles root and return one row per `<name>.ouro` directory whose
46
+ * `agent.json` is readable and parseable. Includes both enabled and disabled
47
+ * agents — the caller decides what to do with the `enabled` flag.
48
+ *
49
+ * Bundles whose `agent.json` is missing, malformed, or unreadable are skipped
50
+ * silently (they aren't real agents from the harness's perspective).
51
+ *
52
+ * Sorted alphabetically by name for stable display.
53
+ */
54
+ function listAllBundleAgents(options = {}) {
42
55
  const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
43
56
  const readdirSync = options.readdirSync ?? fs.readdirSync;
44
57
  const readFileSync = options.readFileSync ?? fs.readFileSync;
@@ -73,9 +86,72 @@ function listEnabledBundleAgents(options = {}) {
73
86
  catch {
74
87
  continue;
75
88
  }
89
+ discovered.push({ name: agentName, enabled });
90
+ }
91
+ return discovered.sort((left, right) => left.name.localeCompare(right.name));
92
+ }
93
+ function listEnabledBundleAgents(options = {}) {
94
+ return listAllBundleAgents(options).filter((row) => row.enabled).map((row) => row.name);
95
+ }
96
+ /**
97
+ * Read the per-agent sync block from each enabled bundle's agent.json.
98
+ * Used by the daemon (and stopped-state status renderer) to build per-agent
99
+ * sync rows without depending on argv-derived global identity. Bundles that
100
+ * cannot be read are skipped silently.
101
+ *
102
+ * For rows with sync enabled, also checks whether the bundle is a git repo
103
+ * (via .git directory presence) and resolves the remote URL via
104
+ * `git remote get-url <remote>`. On any error the URL is left undefined and
105
+ * the status renderer falls back to "local only" or "not a git repo".
106
+ */
107
+ function listBundleSyncRows(options = {}) {
108
+ const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
109
+ const readFileSync = options.readFileSync ?? fs.readFileSync;
110
+ const execFileSync = options.execFileSync ?? child_process_1.execFileSync;
111
+ const existsSync = options.existsSync ?? fs.existsSync;
112
+ const agents = listEnabledBundleAgents(options);
113
+ const rows = [];
114
+ for (const agent of agents) {
115
+ const bundleRoot = path.join(bundlesRoot, `${agent}.ouro`);
116
+ const configPath = path.join(bundleRoot, "agent.json");
117
+ let enabled = false;
118
+ let remote = "origin";
119
+ try {
120
+ const raw = readFileSync(configPath, "utf-8");
121
+ const parsed = JSON.parse(raw);
122
+ if (parsed.sync && typeof parsed.sync === "object") {
123
+ if (typeof parsed.sync.enabled === "boolean")
124
+ enabled = parsed.sync.enabled;
125
+ if (typeof parsed.sync.remote === "string" && parsed.sync.remote.length > 0) {
126
+ remote = parsed.sync.remote;
127
+ }
128
+ }
129
+ }
130
+ catch {
131
+ // Best-effort: bundle without readable config still gets a row with defaults
132
+ }
133
+ const row = { agent, enabled, remote };
76
134
  if (enabled) {
77
- discovered.push(agentName);
135
+ // Only meaningful when sync is enabled — we don't care about disabled bundles'
136
+ // git state. Check .git presence before attempting any git invocation.
137
+ const gitInitialized = existsSync(path.join(bundleRoot, ".git"));
138
+ row.gitInitialized = gitInitialized;
139
+ if (gitInitialized) {
140
+ try {
141
+ const out = execFileSync("git", ["remote", "get-url", remote], {
142
+ cwd: bundleRoot,
143
+ stdio: "pipe",
144
+ timeout: 5000,
145
+ }).toString().trim();
146
+ if (out.length > 0)
147
+ row.remoteUrl = out;
148
+ }
149
+ catch {
150
+ // No remote configured or git missing — leave remoteUrl undefined.
151
+ }
152
+ }
78
153
  }
154
+ rows.push(row);
79
155
  }
80
- return discovered.sort((left, right) => left.localeCompare(right));
156
+ return rows;
81
157
  }