@ouro.bot/cli 0.1.0-alpha.36 → 0.1.0-alpha.361

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 (326) hide show
  1. package/README.md +194 -184
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
  4. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  5. package/changelog.json +2155 -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 +832 -0
  16. package/dist/heart/agent-entry.js +37 -2
  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 +463 -0
  28. package/dist/heart/bridges/manager.js +358 -0
  29. package/dist/heart/bridges/state-machine.js +135 -0
  30. package/dist/heart/bridges/store.js +123 -0
  31. package/dist/heart/bundle-state.js +168 -0
  32. package/dist/heart/commitments.js +111 -0
  33. package/dist/heart/config-registry.js +304 -0
  34. package/dist/heart/config.js +53 -21
  35. package/dist/heart/core.js +743 -252
  36. package/dist/heart/cross-chat-delivery.js +131 -0
  37. package/dist/heart/daemon/agent-config-check.js +561 -0
  38. package/dist/heart/daemon/agent-discovery.js +79 -3
  39. package/dist/heart/daemon/agent-service.js +360 -0
  40. package/dist/heart/daemon/agentic-repair.js +185 -0
  41. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  42. package/dist/heart/daemon/cadence.js +70 -0
  43. package/dist/heart/daemon/cli-defaults.js +591 -0
  44. package/dist/heart/daemon/cli-exec.js +2649 -0
  45. package/dist/heart/daemon/cli-help.js +306 -0
  46. package/dist/heart/daemon/cli-parse.js +913 -0
  47. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  48. package/dist/heart/daemon/cli-render.js +560 -0
  49. package/dist/heart/daemon/cli-types.js +8 -0
  50. package/dist/heart/daemon/daemon-cli.js +30 -1171
  51. package/dist/heart/daemon/daemon-entry.js +358 -3
  52. package/dist/heart/daemon/daemon-health.js +141 -0
  53. package/dist/heart/daemon/daemon-runtime-sync.js +157 -12
  54. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  55. package/dist/heart/daemon/daemon.js +757 -58
  56. package/dist/heart/daemon/doctor-types.js +8 -0
  57. package/dist/heart/daemon/doctor.js +465 -0
  58. package/dist/heart/daemon/health-monitor.js +79 -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/inner-status.js +89 -0
  63. package/dist/heart/daemon/interactive-repair.js +91 -0
  64. package/dist/heart/daemon/launchd.js +46 -9
  65. package/dist/heart/daemon/log-tailer.js +82 -12
  66. package/dist/heart/daemon/logs-prune.js +105 -0
  67. package/dist/heart/daemon/message-router.js +17 -8
  68. package/dist/heart/daemon/os-cron-deps.js +134 -0
  69. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  70. package/dist/heart/daemon/process-manager.js +201 -0
  71. package/dist/heart/daemon/provider-discovery.js +140 -0
  72. package/dist/heart/daemon/pulse.js +475 -0
  73. package/dist/heart/daemon/run-hooks.js +2 -0
  74. package/dist/heart/daemon/runtime-logging.js +67 -16
  75. package/dist/heart/daemon/runtime-metadata.js +101 -0
  76. package/dist/heart/daemon/runtime-mode.js +67 -0
  77. package/dist/heart/daemon/safe-mode.js +161 -0
  78. package/dist/heart/daemon/sense-manager.js +72 -3
  79. package/dist/heart/daemon/session-id-resolver.js +131 -0
  80. package/dist/heart/daemon/skill-management-installer.js +94 -0
  81. package/dist/heart/daemon/socket-client.js +307 -0
  82. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  83. package/dist/heart/daemon/startup-tui.js +237 -0
  84. package/dist/heart/daemon/task-scheduler.js +3 -25
  85. package/dist/heart/daemon/thoughts.js +510 -0
  86. package/dist/heart/daemon/up-progress.js +135 -0
  87. package/dist/heart/delegation.js +62 -0
  88. package/dist/heart/habits/habit-migration.js +181 -0
  89. package/dist/heart/habits/habit-parser.js +140 -0
  90. package/dist/heart/habits/habit-scheduler.js +371 -0
  91. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -120
  92. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  93. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  94. package/dist/heart/{daemon → hatch}/specialist-tools.js +56 -10
  95. package/dist/heart/identity.js +154 -59
  96. package/dist/heart/kept-notes.js +357 -0
  97. package/dist/heart/kicks.js +2 -20
  98. package/dist/heart/machine-identity.js +161 -0
  99. package/dist/heart/mcp/mcp-server.js +653 -0
  100. package/dist/heart/migrate-config.js +127 -0
  101. package/dist/heart/model-capabilities.js +59 -0
  102. package/dist/heart/outlook/outlook-http-hooks.js +64 -0
  103. package/dist/heart/outlook/outlook-http-response.js +7 -0
  104. package/dist/heart/outlook/outlook-http-routes.js +232 -0
  105. package/dist/heart/outlook/outlook-http-static.js +99 -0
  106. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  107. package/dist/heart/outlook/outlook-http.js +99 -0
  108. package/dist/heart/outlook/outlook-read.js +28 -0
  109. package/dist/heart/outlook/outlook-types.js +27 -0
  110. package/dist/heart/outlook/outlook-view.js +195 -0
  111. package/dist/heart/outlook/readers/agent-machine.js +359 -0
  112. package/dist/heart/outlook/readers/continuity-readers.js +332 -0
  113. package/dist/heart/outlook/readers/runtime-readers.js +660 -0
  114. package/dist/heart/outlook/readers/sessions.js +232 -0
  115. package/dist/heart/outlook/readers/shared.js +111 -0
  116. package/dist/heart/progress-story.js +42 -0
  117. package/dist/heart/provider-attempt.js +133 -0
  118. package/dist/heart/provider-binding-resolver.js +240 -0
  119. package/dist/heart/provider-credential-pool.js +395 -0
  120. package/dist/heart/provider-failover.js +274 -0
  121. package/dist/heart/provider-models.js +81 -0
  122. package/dist/heart/provider-ping.js +227 -0
  123. package/dist/heart/provider-state.js +208 -0
  124. package/dist/heart/provider-visibility.js +183 -0
  125. package/dist/heart/providers/anthropic-token.js +163 -0
  126. package/dist/heart/providers/anthropic.js +177 -50
  127. package/dist/heart/providers/azure.js +102 -11
  128. package/dist/heart/providers/error-classification.js +63 -0
  129. package/dist/heart/providers/github-copilot.js +145 -0
  130. package/dist/heart/providers/minimax-vlm.js +189 -0
  131. package/dist/heart/providers/minimax.js +28 -6
  132. package/dist/heart/providers/openai-codex.js +38 -23
  133. package/dist/heart/session-activity.js +190 -0
  134. package/dist/heart/session-events.js +855 -0
  135. package/dist/heart/session-transcript.js +167 -0
  136. package/dist/heart/start-of-turn-packet.js +345 -0
  137. package/dist/heart/streaming.js +36 -27
  138. package/dist/heart/sync.js +332 -0
  139. package/dist/heart/target-resolution.js +127 -0
  140. package/dist/heart/tempo.js +93 -0
  141. package/dist/heart/temporal-view.js +41 -0
  142. package/dist/heart/tool-activity-callbacks.js +36 -0
  143. package/dist/heart/tool-description.js +135 -0
  144. package/dist/heart/tool-friction.js +55 -0
  145. package/dist/heart/tool-loop.js +200 -0
  146. package/dist/heart/turn-context.js +362 -0
  147. package/dist/heart/turn-coordinator.js +28 -0
  148. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  149. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  150. package/dist/heart/versioning/ouro-path-installer.js +296 -0
  151. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  152. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  153. package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
  154. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  155. package/dist/mind/bundle-manifest.js +7 -1
  156. package/dist/mind/context.js +141 -94
  157. package/dist/mind/diary-integrity.js +60 -0
  158. package/dist/mind/{memory.js → diary.js} +84 -96
  159. package/dist/mind/embedding-provider.js +60 -0
  160. package/dist/mind/file-state.js +179 -0
  161. package/dist/mind/first-impressions.js +14 -1
  162. package/dist/mind/friends/channel.js +56 -0
  163. package/dist/mind/friends/group-context.js +144 -0
  164. package/dist/mind/friends/resolver.js +38 -1
  165. package/dist/mind/friends/store-file.js +58 -3
  166. package/dist/mind/friends/trust-explanation.js +74 -0
  167. package/dist/mind/friends/types.js +9 -1
  168. package/dist/mind/journal-index.js +161 -0
  169. package/dist/mind/note-search.js +268 -0
  170. package/dist/mind/obligation-steering.js +221 -0
  171. package/dist/mind/pending.js +74 -7
  172. package/dist/mind/prompt.js +1013 -112
  173. package/dist/mind/provenance-trust.js +26 -0
  174. package/dist/mind/scrutiny.js +173 -0
  175. package/dist/mind/token-estimate.js +8 -12
  176. package/dist/nerves/cli-logging.js +7 -1
  177. package/dist/nerves/coverage/audit-rules.js +15 -6
  178. package/dist/nerves/coverage/audit.js +28 -2
  179. package/dist/nerves/coverage/cli.js +1 -1
  180. package/dist/nerves/coverage/file-completeness.js +83 -5
  181. package/dist/nerves/coverage/run-artifacts.js +1 -1
  182. package/dist/nerves/event-buffer.js +111 -0
  183. package/dist/nerves/index.js +224 -4
  184. package/dist/nerves/observation.js +20 -0
  185. package/dist/nerves/redact.js +79 -0
  186. package/dist/nerves/runtime.js +5 -1
  187. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  188. package/dist/outlook-ui/assets/index-xTdv64BV.js +61 -0
  189. package/dist/outlook-ui/index.html +15 -0
  190. package/dist/repertoire/ado-client.js +15 -56
  191. package/dist/repertoire/ado-semantic.js +11 -10
  192. package/dist/repertoire/api-client.js +97 -0
  193. package/dist/repertoire/bitwarden-store.js +319 -0
  194. package/dist/repertoire/bundle-templates.js +72 -0
  195. package/dist/repertoire/bw-installer.js +79 -0
  196. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  197. package/dist/repertoire/coding/context-pack.js +330 -0
  198. package/dist/repertoire/coding/feedback.js +197 -30
  199. package/dist/repertoire/coding/manager.js +158 -9
  200. package/dist/repertoire/coding/spawner.js +55 -9
  201. package/dist/repertoire/coding/tools.js +170 -7
  202. package/dist/repertoire/commerce-errors.js +109 -0
  203. package/dist/repertoire/commerce-self-test.js +156 -0
  204. package/dist/repertoire/credential-access.js +527 -0
  205. package/dist/repertoire/duffel-client.js +185 -0
  206. package/dist/repertoire/github-client.js +14 -55
  207. package/dist/repertoire/graph-client.js +11 -52
  208. package/dist/repertoire/guardrails.js +375 -0
  209. package/dist/repertoire/mcp-client.js +255 -0
  210. package/dist/repertoire/mcp-manager.js +305 -0
  211. package/dist/repertoire/mcp-tools.js +63 -0
  212. package/dist/repertoire/shell-sessions.js +133 -0
  213. package/dist/repertoire/skills.js +15 -24
  214. package/dist/repertoire/stripe-client.js +131 -0
  215. package/dist/repertoire/tasks/board.js +43 -5
  216. package/dist/repertoire/tasks/fix.js +182 -0
  217. package/dist/repertoire/tasks/index.js +28 -10
  218. package/dist/repertoire/tasks/lifecycle.js +2 -2
  219. package/dist/repertoire/tasks/parser.js +3 -2
  220. package/dist/repertoire/tasks/scanner.js +194 -37
  221. package/dist/repertoire/tasks/transitions.js +16 -79
  222. package/dist/repertoire/tool-results.js +29 -0
  223. package/dist/repertoire/tools-attachments.js +316 -0
  224. package/dist/repertoire/tools-base.js +45 -771
  225. package/dist/repertoire/tools-bluebubbles.js +1 -0
  226. package/dist/repertoire/tools-bridge.js +141 -0
  227. package/dist/repertoire/tools-bundle.js +984 -0
  228. package/dist/repertoire/tools-config.js +185 -0
  229. package/dist/repertoire/tools-continuity.js +248 -0
  230. package/dist/repertoire/tools-credential.js +182 -0
  231. package/dist/repertoire/tools-files.js +342 -0
  232. package/dist/repertoire/tools-flight.js +224 -0
  233. package/dist/repertoire/tools-flow.js +105 -0
  234. package/dist/repertoire/tools-github.js +1 -7
  235. package/dist/repertoire/tools-notes.js +376 -0
  236. package/dist/repertoire/tools-session.js +739 -0
  237. package/dist/repertoire/tools-shell.js +120 -0
  238. package/dist/repertoire/tools-stripe.js +180 -0
  239. package/dist/repertoire/tools-surface.js +243 -0
  240. package/dist/repertoire/tools-teams.js +12 -62
  241. package/dist/repertoire/tools-travel.js +125 -0
  242. package/dist/repertoire/tools-user-profile.js +144 -0
  243. package/dist/repertoire/tools-vault.js +110 -0
  244. package/dist/repertoire/tools.js +144 -138
  245. package/dist/repertoire/travel-api-client.js +360 -0
  246. package/dist/repertoire/user-profile.js +118 -0
  247. package/dist/repertoire/vault-setup.js +241 -0
  248. package/dist/scripts/claude-code-hook.js +41 -0
  249. package/dist/scripts/claude-code-stop-hook.js +47 -0
  250. package/dist/senses/attention-queue.js +116 -0
  251. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  252. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  253. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +225 -9
  254. package/dist/senses/bluebubbles/entry.js +13 -0
  255. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  256. package/dist/senses/bluebubbles/index.js +1620 -0
  257. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  258. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +43 -12
  259. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  260. package/dist/senses/bluebubbles/replay.js +129 -0
  261. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  262. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  263. package/dist/senses/cli/bracketed-paste.js +82 -0
  264. package/dist/senses/cli/image-paste.js +287 -0
  265. package/dist/senses/cli/image-ref-navigation.js +75 -0
  266. package/dist/senses/cli/ink-app.js +156 -0
  267. package/dist/senses/cli/inline-diff.js +64 -0
  268. package/dist/senses/cli/input-keys.js +174 -0
  269. package/dist/senses/cli/kill-ring.js +86 -0
  270. package/dist/senses/cli/message-list.js +51 -0
  271. package/dist/senses/cli/ouro-tui.js +605 -0
  272. package/dist/senses/cli/spinner-imperative.js +135 -0
  273. package/dist/senses/cli/spinner.js +101 -0
  274. package/dist/senses/cli/status-line.js +60 -0
  275. package/dist/senses/cli/streaming-markdown.js +526 -0
  276. package/dist/senses/cli/tool-display.js +83 -0
  277. package/dist/senses/cli/tool-render.js +85 -0
  278. package/dist/senses/cli/tui-store.js +240 -0
  279. package/dist/senses/cli/virtual-list.js +35 -0
  280. package/dist/senses/cli-entry.js +1 -1
  281. package/dist/senses/cli-layout.js +187 -0
  282. package/dist/senses/cli.js +587 -249
  283. package/dist/senses/commands.js +66 -3
  284. package/dist/senses/continuity.js +94 -0
  285. package/dist/senses/habit-turn-message.js +108 -0
  286. package/dist/senses/inner-dialog-worker.js +112 -19
  287. package/dist/senses/inner-dialog.js +636 -86
  288. package/dist/senses/pipeline.js +603 -0
  289. package/dist/senses/proactive-content-guard.js +51 -0
  290. package/dist/senses/shared-turn.js +205 -0
  291. package/dist/senses/surface-tool.js +68 -0
  292. package/dist/senses/teams.js +693 -160
  293. package/dist/senses/trust-gate.js +112 -2
  294. package/package.json +29 -7
  295. package/skills/agent-commerce.md +106 -0
  296. package/skills/browser-navigation.md +110 -0
  297. package/skills/commerce-setup-guide.md +116 -0
  298. package/skills/commerce-setup.md +84 -0
  299. package/skills/configure-dev-tools.md +81 -0
  300. package/skills/travel-planning.md +138 -0
  301. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  302. package/dist/heart/daemon/subagent-installer.js +0 -134
  303. package/dist/mind/associative-recall.js +0 -197
  304. package/dist/senses/bluebubbles-entry.js +0 -11
  305. package/dist/senses/bluebubbles.js +0 -558
  306. package/dist/senses/debug-activity.js +0 -127
  307. package/subagents/README.md +0 -73
  308. package/subagents/work-doer.md +0 -235
  309. package/subagents/work-merger.md +0 -618
  310. package/subagents/work-planner.md +0 -382
  311. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  312. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  313. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  314. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  315. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  316. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  317. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  318. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  319. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  320. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  321. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  322. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  323. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  324. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  325. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  326. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,527 @@
1
+ "use strict";
2
+ /**
3
+ * Credential access layer — store-agnostic credential management.
4
+ *
5
+ * Two backends, one interface:
6
+ * - BuiltInCredentialStore: AES-256-GCM encrypted files, zero npm deps
7
+ * - AacCredentialStore: delegates to the `aac` CLI (Bitwarden Agent Access)
8
+ *
9
+ * Raw secrets are NEVER returned to callers except via getRawSecret(),
10
+ * which is reserved for internal use by the credential gateway (apiRequest).
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.AacCredentialStore = exports.BuiltInCredentialStore = void 0;
47
+ exports.domainToSlug = domainToSlug;
48
+ exports.ensureVaultDefaults = ensureVaultDefaults;
49
+ exports.getCredentialStore = getCredentialStore;
50
+ exports.resetCredentialStore = resetCredentialStore;
51
+ const crypto = __importStar(require("node:crypto"));
52
+ const fs = __importStar(require("node:fs"));
53
+ const path = __importStar(require("node:path"));
54
+ const os = __importStar(require("node:os"));
55
+ const node_child_process_1 = require("node:child_process");
56
+ const runtime_1 = require("../nerves/runtime");
57
+ const identity = __importStar(require("../heart/identity"));
58
+ // ---------------------------------------------------------------------------
59
+ // Helpers
60
+ // ---------------------------------------------------------------------------
61
+ /** Convert a domain string to a filesystem-safe slug. */
62
+ function domainToSlug(domain) {
63
+ return domain
64
+ .toLowerCase()
65
+ .replace(/[^a-z0-9]+/g, "-")
66
+ .replace(/^-+|-+$/g, "");
67
+ }
68
+ class BuiltInCredentialStore {
69
+ vaultDir;
70
+ keyPath;
71
+ masterKey = null;
72
+ constructor(agentName, vaultDir, keyDir) {
73
+ const homeBase = process.env.WEBSITE_SITE_NAME ? "/home" : os.homedir();
74
+ this.vaultDir = vaultDir ?? path.join(homeBase, "AgentBundles", `${agentName}.ouro`, "vault");
75
+ const effectiveKeyDir = keyDir ?? path.join(homeBase, ".agentsecrets", agentName);
76
+ this.keyPath = path.join(effectiveKeyDir, "vault.key");
77
+ }
78
+ isReady() {
79
+ return true;
80
+ }
81
+ async get(domain) {
82
+ (0, runtime_1.emitNervesEvent)({
83
+ event: "repertoire.credential_get_start",
84
+ component: "repertoire",
85
+ message: `getting credential for ${domain}`,
86
+ meta: { domain },
87
+ });
88
+ const stored = this.readEncrypted(domain);
89
+ if (!stored) {
90
+ (0, runtime_1.emitNervesEvent)({
91
+ event: "repertoire.credential_get_end",
92
+ component: "repertoire",
93
+ message: `no credential found for ${domain}`,
94
+ meta: { domain, found: false },
95
+ });
96
+ return null;
97
+ }
98
+ (0, runtime_1.emitNervesEvent)({
99
+ event: "repertoire.credential_get_end",
100
+ component: "repertoire",
101
+ message: `credential found for ${domain}`,
102
+ meta: { domain, found: true },
103
+ });
104
+ return {
105
+ domain: stored.domain,
106
+ username: stored.username,
107
+ notes: stored.notes,
108
+ createdAt: stored.createdAt,
109
+ };
110
+ }
111
+ async getRawSecret(domain, field) {
112
+ const stored = this.readEncrypted(domain);
113
+ if (!stored) {
114
+ (0, runtime_1.emitNervesEvent)({
115
+ level: "error",
116
+ event: "repertoire.credential_get_error",
117
+ component: "repertoire",
118
+ message: `no credential found for domain "${domain}"`,
119
+ meta: { domain, field, reason: `no credential found for domain "${domain}"` },
120
+ });
121
+ throw new Error(`no credential found for domain "${domain}"`);
122
+ }
123
+ const value = stored[field];
124
+ if (value === undefined || value === null) {
125
+ (0, runtime_1.emitNervesEvent)({
126
+ level: "error",
127
+ event: "repertoire.credential_get_error",
128
+ component: "repertoire",
129
+ message: `field "${field}" not found for domain "${domain}"`,
130
+ meta: { domain, field, reason: `field "${field}" not found for domain "${domain}"` },
131
+ });
132
+ throw new Error(`field "${field}" not found for domain "${domain}"`);
133
+ }
134
+ return String(value);
135
+ }
136
+ async store(domain, data) {
137
+ (0, runtime_1.emitNervesEvent)({
138
+ event: "repertoire.credential_store_start",
139
+ component: "repertoire",
140
+ message: `storing credential for ${domain}`,
141
+ meta: { domain },
142
+ });
143
+ this.ensureDirs();
144
+ const key = this.getOrCreateKey();
145
+ const credential = {
146
+ domain,
147
+ username: data.username,
148
+ password: data.password,
149
+ notes: data.notes,
150
+ createdAt: new Date().toISOString(),
151
+ };
152
+ const plaintext = JSON.stringify(credential);
153
+ const iv = crypto.randomBytes(12);
154
+ const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
155
+ const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
156
+ const tag = cipher.getAuthTag();
157
+ const payload = {
158
+ iv: iv.toString("hex"),
159
+ tag: tag.toString("hex"),
160
+ data: encrypted.toString("hex"),
161
+ };
162
+ const slug = domainToSlug(domain);
163
+ const encPath = path.join(this.vaultDir, `${slug}.enc`);
164
+ fs.writeFileSync(encPath, JSON.stringify(payload), "utf-8");
165
+ (0, runtime_1.emitNervesEvent)({
166
+ event: "repertoire.credential_store_end",
167
+ component: "repertoire",
168
+ message: `credential stored for ${domain}`,
169
+ meta: { domain },
170
+ });
171
+ }
172
+ async list() {
173
+ (0, runtime_1.emitNervesEvent)({
174
+ event: "repertoire.credential_list_start",
175
+ component: "repertoire",
176
+ message: "listing credentials",
177
+ meta: {},
178
+ });
179
+ if (!fs.existsSync(this.vaultDir)) {
180
+ (0, runtime_1.emitNervesEvent)({
181
+ event: "repertoire.credential_list_end",
182
+ component: "repertoire",
183
+ message: "credential list complete (no vault dir)",
184
+ meta: { count: 0 },
185
+ });
186
+ return [];
187
+ }
188
+ const files = fs.readdirSync(this.vaultDir).filter((f) => f.endsWith(".enc"));
189
+ const results = [];
190
+ for (const file of files) {
191
+ const slug = file.replace(/\.enc$/, "");
192
+ let stored = null;
193
+ try {
194
+ stored = this.readEncryptedBySlug(slug);
195
+ }
196
+ catch {
197
+ // Skip corrupt/unreadable files
198
+ }
199
+ if (stored) {
200
+ results.push({
201
+ domain: stored.domain,
202
+ username: stored.username,
203
+ notes: stored.notes,
204
+ createdAt: stored.createdAt,
205
+ });
206
+ }
207
+ }
208
+ (0, runtime_1.emitNervesEvent)({
209
+ event: "repertoire.credential_list_end",
210
+ component: "repertoire",
211
+ message: "credential list complete",
212
+ meta: { count: results.length },
213
+ });
214
+ return results;
215
+ }
216
+ async delete(domain) {
217
+ (0, runtime_1.emitNervesEvent)({
218
+ event: "repertoire.credential_delete_start",
219
+ component: "repertoire",
220
+ message: `deleting credential for ${domain}`,
221
+ meta: { domain },
222
+ });
223
+ const slug = domainToSlug(domain);
224
+ const encPath = path.join(this.vaultDir, `${slug}.enc`);
225
+ if (!fs.existsSync(encPath)) {
226
+ (0, runtime_1.emitNervesEvent)({
227
+ event: "repertoire.credential_delete_end",
228
+ component: "repertoire",
229
+ message: `no credential to delete for ${domain}`,
230
+ meta: { domain, deleted: false },
231
+ });
232
+ return false;
233
+ }
234
+ fs.unlinkSync(encPath);
235
+ (0, runtime_1.emitNervesEvent)({
236
+ event: "repertoire.credential_delete_end",
237
+ component: "repertoire",
238
+ message: `credential deleted for ${domain}`,
239
+ meta: { domain, deleted: true },
240
+ });
241
+ return true;
242
+ }
243
+ // --- Private ---
244
+ ensureDirs() {
245
+ if (!fs.existsSync(this.vaultDir)) {
246
+ fs.mkdirSync(this.vaultDir, { recursive: true });
247
+ }
248
+ const keyDir = path.dirname(this.keyPath);
249
+ if (!fs.existsSync(keyDir)) {
250
+ fs.mkdirSync(keyDir, { recursive: true, mode: 0o700 });
251
+ }
252
+ }
253
+ getOrCreateKey() {
254
+ if (this.masterKey)
255
+ return this.masterKey;
256
+ if (fs.existsSync(this.keyPath)) {
257
+ this.masterKey = fs.readFileSync(this.keyPath);
258
+ return this.masterKey;
259
+ }
260
+ // Generate new 256-bit key
261
+ const key = crypto.randomBytes(32);
262
+ fs.writeFileSync(this.keyPath, key, { mode: 0o600 });
263
+ this.masterKey = key;
264
+ return key;
265
+ }
266
+ readEncrypted(domain) {
267
+ return this.readEncryptedBySlug(domainToSlug(domain));
268
+ }
269
+ readEncryptedBySlug(slug) {
270
+ const encPath = path.join(this.vaultDir, `${slug}.enc`);
271
+ if (!fs.existsSync(encPath))
272
+ return null;
273
+ const key = this.getOrCreateKey();
274
+ const raw = fs.readFileSync(encPath, "utf-8");
275
+ const payload = JSON.parse(raw);
276
+ const iv = Buffer.from(payload.iv, "hex");
277
+ const tag = Buffer.from(payload.tag, "hex");
278
+ const encrypted = Buffer.from(payload.data, "hex");
279
+ const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
280
+ decipher.setAuthTag(tag);
281
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
282
+ return JSON.parse(decrypted.toString("utf-8"));
283
+ }
284
+ }
285
+ exports.BuiltInCredentialStore = BuiltInCredentialStore;
286
+ // ---------------------------------------------------------------------------
287
+ // AacCredentialStore — delegates to `aac` CLI
288
+ // ---------------------------------------------------------------------------
289
+ function execAac(args) {
290
+ return new Promise((resolve, reject) => {
291
+ (0, node_child_process_1.execFile)("aac", args, { timeout: 10_000 }, (err, stdout) => {
292
+ if (err) {
293
+ reject(new Error(`aac CLI error: ${err.message}`));
294
+ return;
295
+ }
296
+ resolve(stdout);
297
+ });
298
+ });
299
+ }
300
+ class AacCredentialStore {
301
+ aacAvailable = null;
302
+ isReady() {
303
+ // Synchronous check — returns last-known state or false if unchecked
304
+ return this.aacAvailable === true;
305
+ }
306
+ async checkReady() {
307
+ try {
308
+ const stdout = await execAac(["connections", "list"]);
309
+ const parsed = JSON.parse(stdout);
310
+ this.aacAvailable = Array.isArray(parsed) && parsed.length > 0;
311
+ }
312
+ catch {
313
+ this.aacAvailable = false;
314
+ }
315
+ return this.aacAvailable;
316
+ }
317
+ async get(domain) {
318
+ (0, runtime_1.emitNervesEvent)({
319
+ event: "repertoire.credential_get_start",
320
+ component: "repertoire",
321
+ message: `getting credential via aac for ${domain}`,
322
+ meta: { domain, backend: "aac" },
323
+ });
324
+ try {
325
+ const stdout = await execAac(["--domain", domain, "--output", "json"]);
326
+ const parsed = JSON.parse(stdout);
327
+ if (!parsed.success) {
328
+ (0, runtime_1.emitNervesEvent)({
329
+ event: "repertoire.credential_get_end",
330
+ component: "repertoire",
331
+ message: `no aac credential for ${domain}`,
332
+ meta: { domain, found: false, backend: "aac" },
333
+ });
334
+ return null;
335
+ }
336
+ const cred = parsed.credential;
337
+ (0, runtime_1.emitNervesEvent)({
338
+ event: "repertoire.credential_get_end",
339
+ component: "repertoire",
340
+ message: `aac credential found for ${domain}`,
341
+ meta: { domain, found: true, backend: "aac" },
342
+ });
343
+ return {
344
+ domain,
345
+ username: cred.username,
346
+ notes: cred.notes,
347
+ createdAt: cred.createdAt ?? new Date().toISOString(),
348
+ };
349
+ }
350
+ catch {
351
+ (0, runtime_1.emitNervesEvent)({
352
+ event: "repertoire.credential_get_end",
353
+ component: "repertoire",
354
+ message: `aac credential lookup failed for ${domain}`,
355
+ meta: { domain, found: false, backend: "aac" },
356
+ });
357
+ return null;
358
+ }
359
+ }
360
+ async getRawSecret(domain, field) {
361
+ const stdout = await execAac(["--domain", domain, "--output", "json"]);
362
+ const parsed = JSON.parse(stdout);
363
+ if (!parsed.success) {
364
+ throw new Error(`aac lookup failed for domain "${domain}": ${parsed.error ?? "unknown error"}`);
365
+ }
366
+ const value = parsed.credential[field];
367
+ if (value === undefined || value === null) {
368
+ throw new Error(`field "${field}" not found for domain "${domain}"`);
369
+ }
370
+ return String(value);
371
+ }
372
+ async store(_domain, _data) {
373
+ throw new Error("store() is not supported in aac mode — aac is read-from-vault only. " +
374
+ "Use BuiltInCredentialStore for agent-owned credentials, or manage vault items " +
375
+ "directly in Bitwarden.");
376
+ }
377
+ async list() {
378
+ (0, runtime_1.emitNervesEvent)({
379
+ event: "repertoire.credential_list_start",
380
+ component: "repertoire",
381
+ message: "listing aac connections",
382
+ meta: { backend: "aac" },
383
+ });
384
+ try {
385
+ const stdout = await execAac(["connections", "list"]);
386
+ const parsed = JSON.parse(stdout);
387
+ const results = (Array.isArray(parsed) ? parsed : []).map((item) => ({
388
+ domain: String(item.domain ?? ""),
389
+ username: item.username ? String(item.username) : undefined,
390
+ notes: item.notes ? String(item.notes) : undefined,
391
+ createdAt: item.createdAt ? String(item.createdAt) : new Date().toISOString(),
392
+ }));
393
+ (0, runtime_1.emitNervesEvent)({
394
+ event: "repertoire.credential_list_end",
395
+ component: "repertoire",
396
+ message: "aac connections listed",
397
+ meta: { backend: "aac", count: results.length },
398
+ });
399
+ return results;
400
+ }
401
+ catch {
402
+ (0, runtime_1.emitNervesEvent)({
403
+ event: "repertoire.credential_list_end",
404
+ component: "repertoire",
405
+ message: "aac connections list failed",
406
+ meta: { backend: "aac", count: 0 },
407
+ });
408
+ return [];
409
+ }
410
+ }
411
+ async delete(_domain) {
412
+ throw new Error("delete() is not supported in aac mode — manage vault items directly in Bitwarden.");
413
+ }
414
+ }
415
+ exports.AacCredentialStore = AacCredentialStore;
416
+ // ---------------------------------------------------------------------------
417
+ // Singleton + auto-detection
418
+ // ---------------------------------------------------------------------------
419
+ let _store = null;
420
+ /**
421
+ * Auto-add vault defaults to agent.json when no vault section exists.
422
+ * Returns the vault config (either existing or freshly written defaults).
423
+ */
424
+ function ensureVaultDefaults(agentName, agentRoot, existingVault) {
425
+ if (existingVault) {
426
+ return existingVault;
427
+ }
428
+ const configPath = path.join(agentRoot, "agent.json");
429
+ let raw;
430
+ try {
431
+ raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
432
+ }
433
+ catch {
434
+ // agent.json unreadable — cannot auto-configure
435
+ return undefined;
436
+ }
437
+ const defaults = {
438
+ email: `${agentName}@ouro.bot`,
439
+ serverUrl: "https://vault.ouro.bot",
440
+ };
441
+ raw.vault = defaults;
442
+ fs.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
443
+ (0, runtime_1.emitNervesEvent)({
444
+ event: "repertoire.vault_defaults_auto_configured",
445
+ component: "repertoire",
446
+ message: "auto-configured vault defaults in agent.json",
447
+ meta: { agentName, email: defaults.email, serverUrl: defaults.serverUrl },
448
+ });
449
+ return defaults;
450
+ }
451
+ /**
452
+ * Get the credential store singleton.
453
+ *
454
+ * Priority:
455
+ * 1. BitwardenCredentialStore — if vault config exists in agent.json + secrets.json
456
+ * 2. BuiltInCredentialStore — fallback for agents without a vault (local-only, encrypted files)
457
+ *
458
+ * Future auth providers (1Password, etc.) would be added here as additional backends.
459
+ */
460
+ function getCredentialStore() {
461
+ if (_store)
462
+ return _store;
463
+ // Resolve identity up front. The previous implementation wrapped this call
464
+ // in a try/catch that silently fell back to `agentName = "default"`, which
465
+ // meant any test that hit getCredentialStore() without mocking identity
466
+ // silently constructed a BuiltInCredentialStore("default") routing writes
467
+ // to `~/AgentBundles/default.ouro/vault/` and `~/.agentsecrets/default/`.
468
+ // Same silent-leak class we just fixed in coding/manager.ts. No fallback:
469
+ // getAgentName() throws loudly if argv lacks --agent, which is correct for
470
+ // the only caller (production agents with a real identity). Uses the
471
+ // static ESM import above instead of `require("../heart/identity")` so
472
+ // `vi.mock("../heart/identity", ...)` in tests actually intercepts the
473
+ // call — require() bypasses vitest's module registry.
474
+ const agentName = identity.getAgentName();
475
+ const agentRoot = identity.getAgentRoot(agentName);
476
+ // Try to load vault config from agent.json + secrets.json. Only this block
477
+ // is defended with try/catch — bitwarden wiring can legitimately fail
478
+ // (missing vault config, no bw CLI, unreachable server) and the fallback
479
+ // to BuiltInCredentialStore is the intended behavior.
480
+ let backend = "built-in";
481
+ try {
482
+ const config = identity.loadAgentConfig?.();
483
+ // Auto-configure vault defaults if missing
484
+ const vaultSection = ensureVaultDefaults(agentName, agentRoot, config?.vault);
485
+ const vaultConfig = identity.resolveVaultConfig?.(agentName, vaultSection);
486
+ const secretsPath = identity.getAgentSecretsPath?.(agentName);
487
+ let vaultSecrets;
488
+ /* v8 ignore start -- requires real agent secrets.json + vault config + bw CLI @preserve */
489
+ if (secretsPath) {
490
+ try {
491
+ const fsSync = require("fs");
492
+ const secrets = JSON.parse(fsSync.readFileSync(secretsPath, "utf-8"));
493
+ vaultSecrets = secrets.vault;
494
+ }
495
+ catch {
496
+ // No secrets file or no vault section — fall through to built-in
497
+ }
498
+ }
499
+ const serverUrl = vaultConfig?.serverUrl;
500
+ const email = vaultConfig?.email;
501
+ const masterPassword = vaultSecrets?.masterPassword;
502
+ if (serverUrl && email && masterPassword) {
503
+ const { BitwardenCredentialStore } = require("./bitwarden-store");
504
+ _store = new BitwardenCredentialStore(serverUrl, email, masterPassword);
505
+ backend = "bitwarden";
506
+ }
507
+ /* v8 ignore stop */
508
+ }
509
+ catch {
510
+ // Bitwarden wiring failed — fall through to built-in store below.
511
+ }
512
+ /* v8 ignore next -- false branch only reachable when BitwardenCredentialStore was created above @preserve */
513
+ if (!_store) {
514
+ _store = new BuiltInCredentialStore(agentName);
515
+ }
516
+ (0, runtime_1.emitNervesEvent)({
517
+ event: "repertoire.credential_store_init",
518
+ component: "repertoire",
519
+ message: "credential store initialized",
520
+ meta: { backend, agentName },
521
+ });
522
+ return _store;
523
+ }
524
+ /** Reset the singleton — for tests only. */
525
+ function resetCredentialStore() {
526
+ _store = null;
527
+ }