@ouro.bot/cli 0.1.0-alpha.80 → 0.1.0-alpha.801

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 (613) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -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/assets/bluebubbles-host +264 -0
  14. package/changelog.json +5123 -16
  15. package/deploy/unraid/Dockerfile +48 -0
  16. package/deploy/unraid/README.txt +3012 -0
  17. package/deploy/unraid/audit-container-spec.sh +4 -0
  18. package/deploy/unraid/container-runtime.json +1 -0
  19. package/deploy/unraid/docker-man-template-transaction.mjs +526 -0
  20. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  21. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  22. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  23. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  24. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  25. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  26. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  27. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  28. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  29. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  30. package/deploy/unraid/sanctuary-deployment-target.mjs +709 -0
  31. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  32. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2030 -0
  33. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  34. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  35. package/deploy/unraid/sanctuary.ouro/agent.json +24 -0
  36. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  37. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  38. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  39. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  40. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  41. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  42. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +11 -0
  43. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +11 -0
  45. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  46. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +23 -0
  47. package/deploy/unraid/sanctuary.xml +27 -0
  48. package/dist/a2a/card.js +57 -0
  49. package/dist/a2a/client.js +180 -0
  50. package/dist/a2a/config.js +50 -0
  51. package/dist/a2a/delegation-stores.js +56 -0
  52. package/dist/a2a/did-resolution.js +93 -0
  53. package/dist/a2a/identity.js +170 -0
  54. package/dist/a2a/inbound-share.js +107 -0
  55. package/dist/a2a/mission-result-wire.js +196 -0
  56. package/dist/a2a/onboarding.js +115 -0
  57. package/dist/a2a/pin-store.js +132 -0
  58. package/dist/a2a/seen-ledger.js +120 -0
  59. package/dist/a2a/server.js +604 -0
  60. package/dist/a2a/task-store.js +69 -0
  61. package/dist/a2a/transport.js +45 -0
  62. package/dist/a2a/types.js +3 -0
  63. package/dist/arc/attention-types.js +8 -0
  64. package/dist/arc/cares.js +360 -0
  65. package/dist/arc/episodes.js +118 -0
  66. package/dist/arc/evolution.js +490 -0
  67. package/dist/arc/flight-recorder.js +1034 -0
  68. package/dist/arc/intentions.js +134 -0
  69. package/dist/arc/json-store.js +117 -0
  70. package/dist/arc/obligations.js +386 -0
  71. package/dist/arc/packets.js +336 -0
  72. package/dist/arc/presence.js +185 -0
  73. package/dist/arc/task-lifecycle.js +57 -0
  74. package/dist/commerce/store.js +755 -0
  75. package/dist/commerce/types.js +3 -0
  76. package/dist/heart/active-work.js +820 -29
  77. package/dist/heart/agent-entry.js +252 -3
  78. package/dist/heart/approval-files.js +113 -0
  79. package/dist/heart/approval-store.js +950 -0
  80. package/dist/heart/attachments/image-normalize.js +194 -0
  81. package/dist/heart/attachments/materialize.js +97 -0
  82. package/dist/heart/attachments/originals.js +88 -0
  83. package/dist/heart/attachments/render.js +29 -0
  84. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  85. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  86. package/dist/heart/attachments/sources/index.js +18 -0
  87. package/dist/heart/attachments/sources/telegram.js +71 -0
  88. package/dist/heart/attachments/store.js +132 -0
  89. package/dist/heart/attachments/types.js +93 -0
  90. package/dist/heart/auth/auth-flow.js +495 -0
  91. package/dist/heart/autonomy-budget.js +478 -0
  92. package/dist/heart/awaiting/await-alert.js +148 -0
  93. package/dist/heart/awaiting/await-expiry.js +143 -0
  94. package/dist/heart/awaiting/await-loader.js +91 -0
  95. package/dist/heart/awaiting/await-parser.js +149 -0
  96. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  97. package/dist/heart/awaiting/await-scheduler.js +382 -0
  98. package/dist/heart/background-operations.js +281 -0
  99. package/dist/heart/bridges/manager.js +137 -17
  100. package/dist/heart/bridges/store.js +14 -2
  101. package/dist/heart/bundle-state.js +168 -0
  102. package/dist/heart/commitments.js +64 -18
  103. package/dist/heart/config-registry.js +331 -0
  104. package/dist/heart/config.js +142 -129
  105. package/dist/heart/context-loss-gauntlet.js +387 -0
  106. package/dist/heart/context-loss-sentinel.js +1157 -0
  107. package/dist/heart/core.js +2132 -572
  108. package/dist/heart/cross-chat-delivery.js +9 -22
  109. package/dist/heart/daemon/agent-config-check.js +451 -0
  110. package/dist/heart/daemon/agent-discovery.js +185 -3
  111. package/dist/heart/daemon/agent-service.js +542 -0
  112. package/dist/heart/daemon/agentic-repair.js +547 -0
  113. package/dist/heart/daemon/await-private-wake.js +59 -0
  114. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  115. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  116. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  117. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  118. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  119. package/dist/heart/daemon/cadence.js +180 -0
  120. package/dist/heart/daemon/cli-defaults.js +836 -0
  121. package/dist/heart/daemon/cli-desk.js +322 -0
  122. package/dist/heart/daemon/cli-exec.js +8730 -0
  123. package/dist/heart/daemon/cli-help.js +710 -0
  124. package/dist/heart/daemon/cli-parse.js +2719 -0
  125. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  126. package/dist/heart/daemon/cli-render.js +777 -0
  127. package/dist/heart/daemon/cli-types.js +8 -0
  128. package/dist/heart/daemon/connect-bay.js +323 -0
  129. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  130. package/dist/heart/daemon/container-healthcheck.js +112 -0
  131. package/dist/heart/daemon/container-runtime.js +97 -0
  132. package/dist/heart/daemon/container-spec-auditor-main.js +170 -0
  133. package/dist/heart/daemon/container-spec-auditor.js +236 -0
  134. package/dist/heart/daemon/daemon-bootstrap-startup.js +107 -0
  135. package/dist/heart/daemon/daemon-cli.js +29 -2284
  136. package/dist/heart/daemon/daemon-entry.js +920 -11
  137. package/dist/heart/daemon/daemon-health.js +186 -0
  138. package/dist/heart/daemon/daemon-rollup.js +57 -0
  139. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  140. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  141. package/dist/heart/daemon/daemon.js +2010 -88
  142. package/dist/heart/daemon/dns-workflow.js +394 -0
  143. package/dist/heart/daemon/doctor-types.js +8 -0
  144. package/dist/heart/daemon/doctor.js +1755 -0
  145. package/dist/heart/daemon/freshness.js +345 -0
  146. package/dist/heart/daemon/habit-private-wake.js +61 -0
  147. package/dist/heart/daemon/health-monitor.js +142 -11
  148. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  149. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  150. package/dist/heart/daemon/http-health-probe.js +80 -0
  151. package/dist/heart/daemon/human-command-screens.js +234 -0
  152. package/dist/heart/daemon/human-readiness.js +114 -0
  153. package/dist/heart/daemon/inner-status.js +78 -0
  154. package/dist/heart/daemon/interactive-repair.js +394 -0
  155. package/dist/heart/daemon/launchd.js +37 -8
  156. package/dist/heart/daemon/log-tailer.js +79 -10
  157. package/dist/heart/daemon/logs-prune.js +132 -0
  158. package/dist/heart/daemon/mcp-canary.js +524 -0
  159. package/dist/heart/daemon/message-router.js +65 -5
  160. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  161. package/dist/heart/daemon/os-cron-deps.js +135 -0
  162. package/dist/heart/daemon/os-cron.js +22 -14
  163. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  164. package/dist/heart/daemon/ouro-entry.js +3 -1
  165. package/dist/heart/daemon/plugin-cli.js +432 -0
  166. package/dist/heart/daemon/process-manager.js +733 -61
  167. package/dist/heart/daemon/provider-discovery.js +137 -0
  168. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  169. package/dist/heart/daemon/prunable-bundle.js +144 -0
  170. package/dist/heart/daemon/pulse.js +511 -0
  171. package/dist/heart/daemon/readiness-repair.js +365 -0
  172. package/dist/heart/daemon/run-hooks.js +2 -0
  173. package/dist/heart/daemon/runtime-logging.js +47 -14
  174. package/dist/heart/daemon/runtime-metadata.js +2 -30
  175. package/dist/heart/daemon/runtime-mode.js +13 -2
  176. package/dist/heart/daemon/safe-mode.js +161 -0
  177. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2609 -0
  178. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1866 -0
  179. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  180. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +976 -0
  181. package/dist/heart/daemon/sanctuary-bundle-migration.js +728 -0
  182. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  183. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  184. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  185. package/dist/heart/daemon/sense-manager.js +689 -48
  186. package/dist/heart/daemon/session-id-resolver.js +131 -0
  187. package/dist/heart/daemon/skill-management-installer.js +1 -1
  188. package/dist/heart/daemon/socket-client.js +180 -12
  189. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  190. package/dist/heart/daemon/startup-tui.js +339 -0
  191. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  192. package/dist/heart/daemon/task-scheduler.js +117 -39
  193. package/dist/heart/daemon/terminal-ui.js +499 -0
  194. package/dist/heart/daemon/thoughts.js +138 -54
  195. package/dist/heart/daemon/up-progress.js +366 -0
  196. package/dist/heart/daemon/vault-items.js +56 -0
  197. package/dist/heart/delegation.js +1 -4
  198. package/dist/heart/external-events/router.js +1414 -0
  199. package/dist/heart/habits/habit-cancel.js +810 -0
  200. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  201. package/dist/heart/habits/habit-migration.js +194 -0
  202. package/dist/heart/habits/habit-parser.js +278 -0
  203. package/dist/heart/habits/habit-runtime-state.js +93 -0
  204. package/dist/heart/habits/habit-scheduler.js +653 -0
  205. package/dist/heart/habits/habit-session-summary.js +318 -0
  206. package/dist/heart/habits/habit-session.js +636 -0
  207. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  208. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  209. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  210. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  211. package/dist/heart/identity.js +184 -59
  212. package/dist/heart/kept-notes.js +289 -0
  213. package/dist/heart/kicks.js +1 -1
  214. package/dist/heart/machine-identity.js +161 -0
  215. package/dist/heart/mail-import-discovery.js +353 -0
  216. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  217. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  218. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  219. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  220. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  221. package/dist/heart/mailbox/mailbox-http.js +99 -0
  222. package/dist/heart/mailbox/mailbox-read.js +39 -0
  223. package/dist/heart/mailbox/mailbox-types.js +27 -0
  224. package/dist/heart/mailbox/mailbox-view.js +197 -0
  225. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  226. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  227. package/dist/heart/mailbox/readers/mail.js +375 -0
  228. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  229. package/dist/heart/mailbox/readers/sessions.js +232 -0
  230. package/dist/heart/mailbox/readers/shared.js +111 -0
  231. package/dist/heart/mcp/mcp-server.js +696 -0
  232. package/dist/heart/migrate-config.js +100 -0
  233. package/dist/heart/model-capabilities.js +11 -0
  234. package/dist/heart/orientation-frame.js +345 -0
  235. package/dist/heart/platform.js +81 -0
  236. package/dist/heart/primitives.js +1 -1
  237. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  238. package/dist/heart/private-runtime/index.js +18 -0
  239. package/dist/heart/private-runtime/ledger.js +221 -0
  240. package/dist/heart/private-runtime/policy.js +252 -0
  241. package/dist/heart/private-runtime/types.js +2 -0
  242. package/dist/heart/progress-story.js +1 -1
  243. package/dist/heart/provider-attempt.js +137 -0
  244. package/dist/heart/provider-binding-resolver.js +273 -0
  245. package/dist/heart/provider-credentials.js +449 -0
  246. package/dist/heart/provider-failover.js +311 -0
  247. package/dist/heart/provider-models.js +96 -0
  248. package/dist/heart/provider-ping.js +265 -0
  249. package/dist/heart/provider-readiness-cache.js +119 -0
  250. package/dist/heart/provider-visibility.js +188 -0
  251. package/dist/heart/providers/anthropic-token.js +131 -0
  252. package/dist/heart/providers/anthropic.js +173 -60
  253. package/dist/heart/providers/azure.js +23 -11
  254. package/dist/heart/providers/error-classification.js +127 -0
  255. package/dist/heart/providers/github-copilot.js +34 -38
  256. package/dist/heart/providers/minimax-vlm.js +189 -0
  257. package/dist/heart/providers/minimax.js +26 -8
  258. package/dist/heart/providers/openai-codex-token.js +349 -0
  259. package/dist/heart/providers/openai-codex.js +55 -40
  260. package/dist/heart/providers/openai-compatible.js +177 -0
  261. package/dist/heart/run-ledger.js +247 -0
  262. package/dist/heart/runtime-capability-check.js +170 -0
  263. package/dist/heart/runtime-credentials.js +607 -0
  264. package/dist/heart/runtime-cwd.js +87 -0
  265. package/dist/heart/sense-truth.js +22 -4
  266. package/dist/heart/session-activity.js +90 -24
  267. package/dist/heart/session-events.js +1318 -0
  268. package/dist/heart/session-playback-cli-main.js +5 -0
  269. package/dist/heart/session-playback-cli.js +36 -0
  270. package/dist/heart/session-playback.js +231 -0
  271. package/dist/heart/session-stats-cli-main.js +5 -0
  272. package/dist/heart/session-stats.js +182 -0
  273. package/dist/heart/session-transcript.js +133 -0
  274. package/dist/heart/start-of-turn-packet.js +372 -0
  275. package/dist/heart/steward-policy.js +302 -0
  276. package/dist/heart/streaming.js +604 -207
  277. package/dist/heart/structured-output.js +196 -0
  278. package/dist/heart/sync-classification.js +176 -0
  279. package/dist/heart/sync.js +449 -0
  280. package/dist/heart/target-resolution.js +11 -7
  281. package/dist/heart/tempo.js +93 -0
  282. package/dist/heart/temporal-view.js +41 -0
  283. package/dist/heart/timeouts.js +101 -0
  284. package/dist/heart/tool-activity-callbacks.js +59 -0
  285. package/dist/heart/tool-approval.js +342 -0
  286. package/dist/heart/tool-description.js +155 -0
  287. package/dist/heart/tool-friction.js +55 -0
  288. package/dist/heart/tool-loop.js +200 -0
  289. package/dist/heart/turn-context.js +481 -0
  290. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  291. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  292. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  293. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  294. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  295. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  296. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  297. package/dist/heart/versioning/update-hooks.js +154 -0
  298. package/dist/heart/versioning/version-intent.js +114 -0
  299. package/dist/heart/work-card.js +380 -0
  300. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  301. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  302. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  303. package/dist/mailbox-ui/index.html +16 -0
  304. package/dist/mailroom/attention.js +167 -0
  305. package/dist/mailroom/autonomy.js +209 -0
  306. package/dist/mailroom/blob-store.js +889 -0
  307. package/dist/mailroom/body-cache.js +61 -0
  308. package/dist/mailroom/cache-sync-cli.js +58 -0
  309. package/dist/mailroom/core.js +803 -0
  310. package/dist/mailroom/entry.js +160 -0
  311. package/dist/mailroom/file-store.js +568 -0
  312. package/dist/mailroom/hosted-cache-sync.js +384 -0
  313. package/dist/mailroom/mbox-import.js +393 -0
  314. package/dist/mailroom/migration.js +164 -0
  315. package/dist/mailroom/outbound.js +380 -0
  316. package/dist/mailroom/policy.js +263 -0
  317. package/dist/mailroom/reader.js +292 -0
  318. package/dist/mailroom/search-cache.js +513 -0
  319. package/dist/mailroom/search-relevance.js +319 -0
  320. package/dist/mailroom/smtp-ingress.js +176 -0
  321. package/dist/mailroom/source-state.js +176 -0
  322. package/dist/mailroom/thread.js +109 -0
  323. package/dist/mailroom/travel-extract.js +89 -0
  324. package/dist/mind/bundle-manifest.js +24 -2
  325. package/dist/mind/context.js +278 -111
  326. package/dist/mind/desk-section.js +362 -0
  327. package/dist/mind/diary-integrity.js +60 -0
  328. package/dist/mind/{memory.js → diary.js} +68 -77
  329. package/dist/mind/embedding-provider.js +60 -0
  330. package/dist/mind/file-state.js +179 -0
  331. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  332. package/dist/mind/obligation-steering.js +227 -0
  333. package/dist/mind/pending.js +34 -8
  334. package/dist/mind/prompt-budget.js +479 -0
  335. package/dist/mind/prompt-refresh.js +3 -2
  336. package/dist/mind/prompt.js +1056 -187
  337. package/dist/mind/provenance-trust.js +26 -0
  338. package/dist/mind/record-paths.js +312 -0
  339. package/dist/mind/scrutiny.js +173 -0
  340. package/dist/mind/session-transaction.js +415 -0
  341. package/dist/nerves/cli-logging.js +7 -1
  342. package/dist/nerves/coverage/audit-rules.js +15 -6
  343. package/dist/nerves/coverage/audit.js +28 -2
  344. package/dist/nerves/coverage/cli.js +1 -1
  345. package/dist/nerves/coverage/contract.js +5 -5
  346. package/dist/nerves/coverage/file-completeness.js +139 -5
  347. package/dist/nerves/coverage/run-artifacts.js +55 -35
  348. package/dist/nerves/coverage/source-scanner.js +4 -4
  349. package/dist/nerves/event-buffer.js +111 -0
  350. package/dist/nerves/index.js +293 -9
  351. package/dist/nerves/observation.js +20 -0
  352. package/dist/nerves/redact.js +79 -0
  353. package/dist/nerves/review/cli-main.js +5 -0
  354. package/dist/nerves/review/cli.js +156 -0
  355. package/dist/nerves/review/core.js +159 -0
  356. package/dist/nerves/runtime.js +17 -1
  357. package/dist/repertoire/ado-client.js +15 -56
  358. package/dist/repertoire/ado-semantic.js +16 -10
  359. package/dist/repertoire/api-client.js +97 -0
  360. package/dist/repertoire/bitwarden-store.js +1045 -0
  361. package/dist/repertoire/bundle-templates.js +71 -0
  362. package/dist/repertoire/bw-installer.js +180 -0
  363. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  364. package/dist/repertoire/coding/context-pack.js +331 -0
  365. package/dist/repertoire/coding/feedback.js +218 -30
  366. package/dist/repertoire/coding/index.js +15 -3
  367. package/dist/repertoire/coding/manager.js +166 -10
  368. package/dist/repertoire/coding/spawner.js +58 -11
  369. package/dist/repertoire/coding/tools.js +242 -14
  370. package/dist/repertoire/coding/workbench-client.js +272 -0
  371. package/dist/repertoire/coding/workbench-manager.js +346 -0
  372. package/dist/repertoire/commerce-errors.js +109 -0
  373. package/dist/repertoire/commerce-self-test.js +156 -0
  374. package/dist/repertoire/credential-access.js +178 -0
  375. package/dist/repertoire/desk/classifier.js +362 -0
  376. package/dist/repertoire/duffel-client.js +185 -0
  377. package/dist/repertoire/github-client.js +14 -55
  378. package/dist/repertoire/graph-client.js +11 -52
  379. package/dist/repertoire/guardrails.js +811 -18
  380. package/dist/repertoire/mcp-client.js +44 -3
  381. package/dist/repertoire/mcp-manager.js +259 -20
  382. package/dist/repertoire/mcp-tools.js +83 -0
  383. package/dist/repertoire/plugin-mcp.js +175 -0
  384. package/dist/repertoire/plugins.js +253 -0
  385. package/dist/repertoire/relationship-authorization.js +194 -0
  386. package/dist/repertoire/shell-sessions.js +133 -0
  387. package/dist/repertoire/skills.js +48 -4
  388. package/dist/repertoire/stripe-client.js +131 -0
  389. package/dist/repertoire/tool-arguments.js +148 -0
  390. package/dist/repertoire/tool-results.js +29 -0
  391. package/dist/repertoire/tools-a2a.js +699 -0
  392. package/dist/repertoire/tools-attachments.js +322 -0
  393. package/dist/repertoire/tools-awaiting.js +575 -0
  394. package/dist/repertoire/tools-base.js +82 -1139
  395. package/dist/repertoire/tools-bluebubbles.js +2 -0
  396. package/dist/repertoire/tools-bridge.js +144 -0
  397. package/dist/repertoire/tools-bundle.js +993 -0
  398. package/dist/repertoire/tools-commerce.js +253 -0
  399. package/dist/repertoire/tools-config.js +186 -0
  400. package/dist/repertoire/tools-continuity.js +575 -0
  401. package/dist/repertoire/tools-credential.js +383 -0
  402. package/dist/repertoire/tools-evolution.js +527 -0
  403. package/dist/repertoire/tools-files.js +344 -0
  404. package/dist/repertoire/tools-flight.js +290 -0
  405. package/dist/repertoire/tools-flow.js +119 -0
  406. package/dist/repertoire/tools-github.js +3 -8
  407. package/dist/repertoire/tools-habits.js +103 -0
  408. package/dist/repertoire/tools-mail.js +1828 -0
  409. package/dist/repertoire/tools-notes.js +485 -0
  410. package/dist/repertoire/tools-obligations.js +182 -0
  411. package/dist/repertoire/tools-orientation.js +31 -0
  412. package/dist/repertoire/tools-record.js +482 -0
  413. package/dist/repertoire/tools-rsvp.js +139 -0
  414. package/dist/repertoire/tools-runtime.js +150 -0
  415. package/dist/repertoire/tools-session.js +1108 -0
  416. package/dist/repertoire/tools-shell.js +133 -0
  417. package/dist/repertoire/tools-steward-policy.js +95 -0
  418. package/dist/repertoire/tools-stripe.js +224 -0
  419. package/dist/repertoire/tools-surface.js +369 -0
  420. package/dist/repertoire/tools-teams.js +12 -39
  421. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  422. package/dist/repertoire/tools-travel.js +125 -0
  423. package/dist/repertoire/tools-trip.js +982 -0
  424. package/dist/repertoire/tools-unraid.js +484 -0
  425. package/dist/repertoire/tools-user-profile.js +146 -0
  426. package/dist/repertoire/tools-vault.js +40 -0
  427. package/dist/repertoire/tools-voice.js +145 -0
  428. package/dist/repertoire/tools.js +377 -80
  429. package/dist/repertoire/travel-api-client.js +360 -0
  430. package/dist/repertoire/unraid-client.js +155 -0
  431. package/dist/repertoire/unraid-restart.js +212 -0
  432. package/dist/repertoire/user-profile.js +131 -0
  433. package/dist/repertoire/vault-setup.js +246 -0
  434. package/dist/repertoire/vault-unlock.js +628 -0
  435. package/dist/rsvp/aisleplanner-client.js +354 -0
  436. package/dist/rsvp/cli.js +926 -0
  437. package/dist/rsvp/config.js +327 -0
  438. package/dist/rsvp/cutover.js +433 -0
  439. package/dist/rsvp/diagnostics.js +232 -0
  440. package/dist/rsvp/diff-renderer.js +176 -0
  441. package/dist/rsvp/habit-policy.js +110 -0
  442. package/dist/rsvp/habit-stage.js +123 -0
  443. package/dist/rsvp/incident-bundle.js +97 -0
  444. package/dist/rsvp/migration.js +204 -0
  445. package/dist/rsvp/native-habit-runner.js +630 -0
  446. package/dist/rsvp/outbound-state.js +628 -0
  447. package/dist/rsvp/query.js +118 -0
  448. package/dist/rsvp/replay.js +233 -0
  449. package/dist/rsvp/snapshot.js +232 -0
  450. package/dist/rsvp/spend-ledger.js +175 -0
  451. package/dist/scripts/claude-code-hook.js +41 -0
  452. package/dist/scripts/claude-code-stop-hook.js +47 -0
  453. package/dist/senses/a2a-entry.js +115 -0
  454. package/dist/senses/attention-queue.js +186 -0
  455. package/dist/senses/await-turn-message.js +58 -0
  456. package/dist/senses/bluebubbles/active-turns.js +216 -0
  457. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  458. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  459. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  460. package/dist/senses/bluebubbles/context-packet.js +207 -0
  461. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  462. package/dist/senses/bluebubbles/entry.js +90 -0
  463. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  464. package/dist/senses/bluebubbles/index.js +3839 -0
  465. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  466. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  467. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  468. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  469. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  470. package/dist/senses/bluebubbles/processed-log.js +133 -0
  471. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  472. package/dist/senses/bluebubbles/replay.js +284 -0
  473. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  474. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  475. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  476. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  477. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  478. package/dist/senses/cli/bracketed-paste.js +82 -0
  479. package/dist/senses/cli/image-paste.js +287 -0
  480. package/dist/senses/cli/image-ref-navigation.js +75 -0
  481. package/dist/senses/cli/ink-app.js +156 -0
  482. package/dist/senses/cli/inline-diff.js +64 -0
  483. package/dist/senses/cli/input-keys.js +174 -0
  484. package/dist/senses/cli/kill-ring.js +86 -0
  485. package/dist/senses/cli/message-list.js +51 -0
  486. package/dist/senses/cli/ouro-tui.js +607 -0
  487. package/dist/senses/cli/spinner-imperative.js +135 -0
  488. package/dist/senses/cli/spinner.js +101 -0
  489. package/dist/senses/cli/status-line.js +60 -0
  490. package/dist/senses/cli/streaming-markdown.js +526 -0
  491. package/dist/senses/cli/tool-display.js +85 -0
  492. package/dist/senses/cli/tool-render.js +85 -0
  493. package/dist/senses/cli/tui-store.js +241 -0
  494. package/dist/senses/cli/virtual-list.js +35 -0
  495. package/dist/senses/cli-entry.js +60 -8
  496. package/dist/senses/cli.js +600 -317
  497. package/dist/senses/commands.js +66 -3
  498. package/dist/senses/context-packet-ledger.js +371 -0
  499. package/dist/senses/context-packets.js +154 -0
  500. package/dist/senses/habit-lifecycle-guard.js +24 -0
  501. package/dist/senses/habit-turn-message.js +160 -0
  502. package/dist/senses/ingress-evidence.js +2 -0
  503. package/dist/senses/mail-entry.js +66 -0
  504. package/dist/senses/mail.js +524 -0
  505. package/dist/senses/pipeline.js +1110 -204
  506. package/dist/senses/private-runtime-worker.js +859 -0
  507. package/dist/senses/private-runtime.js +1496 -0
  508. package/dist/senses/proactive-content-guard.js +51 -0
  509. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  510. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  511. package/dist/senses/sanctuary-grounding.js +118 -0
  512. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  513. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  514. package/dist/senses/sanctuary-health-runner.js +101 -0
  515. package/dist/senses/sanctuary-health.js +408 -0
  516. package/dist/senses/sanctuary-interactive-control.js +306 -0
  517. package/dist/senses/sanctuary-media-catalog-contract.js +235 -0
  518. package/dist/senses/sanctuary-media-optimization.js +514 -0
  519. package/dist/senses/sanctuary-runtime.js +338 -0
  520. package/dist/senses/sanctuary-sab.js +85 -0
  521. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  522. package/dist/senses/shared-turn.js +571 -0
  523. package/dist/senses/surface-tool.js +109 -0
  524. package/dist/senses/teams-entry.js +60 -8
  525. package/dist/senses/teams.js +515 -217
  526. package/dist/senses/telegram-admission.js +711 -0
  527. package/dist/senses/telegram-approval-runtime.js +566 -0
  528. package/dist/senses/telegram-attachments.js +182 -0
  529. package/dist/senses/telegram-audit-ledger.js +220 -0
  530. package/dist/senses/telegram-client.js +1677 -0
  531. package/dist/senses/telegram-effect-adapter.js +859 -0
  532. package/dist/senses/telegram-entry.js +83 -0
  533. package/dist/senses/telegram.js +2031 -0
  534. package/dist/senses/trust-gate.js +104 -9
  535. package/dist/senses/voice/audio-playback.js +237 -0
  536. package/dist/senses/voice/audio-routing.js +119 -0
  537. package/dist/senses/voice/elevenlabs.js +202 -0
  538. package/dist/senses/voice/floor-control.js +431 -0
  539. package/dist/senses/voice/floor-controller.js +115 -0
  540. package/dist/senses/voice/golden-path.js +116 -0
  541. package/dist/senses/voice/index.js +29 -0
  542. package/dist/senses/voice/meeting.js +113 -0
  543. package/dist/senses/voice/outbound.js +190 -0
  544. package/dist/senses/voice/phone.js +33 -0
  545. package/dist/senses/voice/playback.js +139 -0
  546. package/dist/senses/voice/realtime-eval.js +496 -0
  547. package/dist/senses/voice/realtime-trace.js +531 -0
  548. package/dist/senses/voice/transcript.js +70 -0
  549. package/dist/senses/voice/turn.js +191 -0
  550. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  551. package/dist/senses/voice/twilio-phone.js +5081 -0
  552. package/dist/senses/voice/types.js +2 -0
  553. package/dist/senses/voice/whisper.js +161 -0
  554. package/dist/senses/voice-entry.js +81 -0
  555. package/dist/senses/voice-realtime-eval-command.js +99 -0
  556. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  557. package/dist/senses/voice-twilio-entry.js +87 -0
  558. package/dist/trips/core.js +138 -0
  559. package/dist/trips/store.js +265 -0
  560. package/dist/util/frontmatter.js +69 -0
  561. package/npm-shrinkwrap.json +8144 -0
  562. package/package.json +72 -13
  563. package/skills/agent-commerce.md +113 -0
  564. package/skills/browser-navigation.md +117 -0
  565. package/skills/commerce-setup-guide.md +116 -0
  566. package/skills/commerce-setup.md +84 -0
  567. package/skills/configure-dev-tools.md +99 -0
  568. package/skills/travel-planning.md +138 -0
  569. package/dist/heart/daemon/auth-flow.js +0 -430
  570. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  571. package/dist/heart/daemon/ouro-version-manager.js +0 -164
  572. package/dist/heart/daemon/update-hooks.js +0 -138
  573. package/dist/heart/obligations.js +0 -141
  574. package/dist/heart/safe-workspace.js +0 -228
  575. package/dist/heart/session-recall.js +0 -116
  576. package/dist/mind/friends/channel.js +0 -84
  577. package/dist/mind/friends/group-context.js +0 -144
  578. package/dist/mind/friends/resolver.js +0 -84
  579. package/dist/mind/friends/store-file.js +0 -190
  580. package/dist/mind/friends/store.js +0 -4
  581. package/dist/mind/friends/tokens.js +0 -26
  582. package/dist/mind/friends/trust-explanation.js +0 -74
  583. package/dist/mind/friends/types.js +0 -29
  584. package/dist/repertoire/tasks/board.js +0 -134
  585. package/dist/repertoire/tasks/index.js +0 -224
  586. package/dist/repertoire/tasks/lifecycle.js +0 -80
  587. package/dist/repertoire/tasks/middleware.js +0 -65
  588. package/dist/repertoire/tasks/parser.js +0 -173
  589. package/dist/repertoire/tasks/scanner.js +0 -132
  590. package/dist/repertoire/tasks/transitions.js +0 -144
  591. package/dist/senses/bluebubbles-entry.js +0 -13
  592. package/dist/senses/bluebubbles.js +0 -1181
  593. package/dist/senses/debug-activity.js +0 -154
  594. package/dist/senses/inner-dialog-worker.js +0 -90
  595. package/dist/senses/inner-dialog.js +0 -525
  596. package/subagents/README.md +0 -7
  597. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  598. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  599. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  600. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  601. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  602. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  603. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  604. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  605. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  606. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  607. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  608. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  609. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  610. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  611. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  612. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  613. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SANCTUARY_RESTART_MUTATION = void 0;
4
+ exports.createApprovedUnraidRestartExecutor = createApprovedUnraidRestartExecutor;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const runtime_1 = require("../nerves/runtime");
7
+ const unraid_client_1 = require("./unraid-client");
8
+ exports.SANCTUARY_RESTART_MUTATION = `mutation SanctuaryRestart($id: PrefixedID!) {
9
+ docker { restart(id: $id) { id names state status autoStart } }
10
+ }`;
11
+ class RoutineActionReceiptError extends Error {
12
+ constructor(cause) {
13
+ super("routine action receipt persistence failed", { cause });
14
+ this.name = "RoutineActionReceiptError";
15
+ }
16
+ }
17
+ function failure(code, message) {
18
+ return { ok: false, error: { code, message, degraded: true } };
19
+ }
20
+ function exactTarget(result, name) {
21
+ if (!result.ok)
22
+ return failure("invalid_response", result.error.message);
23
+ const matches = result.data.containers.filter((container) => container.name === name);
24
+ if (matches.length === 0)
25
+ return failure("not_found", `container '${name}' was not found`);
26
+ if (matches.length !== 1)
27
+ return failure("ambiguous", `container '${name}' is ambiguous`);
28
+ return matches[0];
29
+ }
30
+ function validArgument(value) {
31
+ return typeof value === "string" && value.length > 0 && Buffer.byteLength(value, "utf8") <= 128 && !value.includes("\uFFFD");
32
+ }
33
+ function acknowledgedIdentity(data, target) {
34
+ const docker = data.docker;
35
+ if (!docker || typeof docker !== "object" || Array.isArray(docker))
36
+ return false;
37
+ const restart = docker.restart;
38
+ if (!restart || typeof restart !== "object" || Array.isArray(restart))
39
+ return false;
40
+ const record = restart;
41
+ return record.id === target.id && Array.isArray(record.names)
42
+ && record.names.length === 1 && String(record.names[0]).replace(/^\//u, "") === target.name;
43
+ }
44
+ function createApprovedUnraidRestartExecutor(options) {
45
+ const createClient = options.createClient ?? ((input) => new unraid_client_1.UnraidClient(input));
46
+ const sleep = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
47
+ const now = options.now ?? (() => new Date());
48
+ const observationTimeoutMs = options.observationTimeoutMs ?? 30_000;
49
+ const transitionRoutine = (input) => {
50
+ try {
51
+ options.transitionRoutineAction?.(input);
52
+ }
53
+ catch (error) {
54
+ throw new RoutineActionReceiptError(error);
55
+ }
56
+ };
57
+ return async (args, execution) => {
58
+ if (!validArgument(args.container))
59
+ return failure("invalid_response", "container must be one bounded exact name");
60
+ const resolved = exactTarget(await options.listContainers(), args.container);
61
+ if ("ok" in resolved)
62
+ return resolved;
63
+ const fresh = exactTarget(await options.listContainers(), args.container);
64
+ if ("ok" in fresh)
65
+ return fresh;
66
+ if (fresh.id !== resolved.id)
67
+ return failure("stale_target", "container identity changed before restart");
68
+ let routineAuthorization = null;
69
+ if (execution?.routine) {
70
+ let authorization;
71
+ try {
72
+ authorization = await execution.routine.reauthorize();
73
+ }
74
+ catch {
75
+ return failure("stale_target", "routine relationship authorization is unavailable");
76
+ }
77
+ if (!authorization.allowed)
78
+ return failure("stale_target", authorization.reason);
79
+ if (!authorization.receiptId.trim() || !Number.isInteger(authorization.profileVersion) || authorization.profileVersion < 1) {
80
+ return failure("stale_target", "routine relationship authorization is not versioned");
81
+ }
82
+ routineAuthorization = { receiptId: authorization.receiptId, profileVersion: authorization.profileVersion };
83
+ }
84
+ const scenarioHandleDigest = options.acceptanceScenarioHandleDigest?.();
85
+ const approval = options.acceptanceApproval?.();
86
+ const attempt = {
87
+ container: { id: fresh.id, name: fresh.name },
88
+ beforeState: fresh.state,
89
+ observedAt: now().toISOString(),
90
+ actionDigest: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({ operation: "restart", container: { id: fresh.id, name: fresh.name } })).digest("hex"),
91
+ argumentDigest: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({ container: args.container })).digest("hex"),
92
+ ...(scenarioHandleDigest ? { scenarioHandleDigest } : {}),
93
+ ...(approval ? { approvalId: approval.approvalId } : {}),
94
+ attemptId: (0, node_crypto_1.randomUUID)(),
95
+ mutationAcknowledged: false,
96
+ afterState: null,
97
+ };
98
+ let routineReceipt = null;
99
+ let routineState = null;
100
+ if (execution?.routine) {
101
+ if (!options.reserveRoutineAction || !options.transitionRoutineAction)
102
+ return failure("invalid_response", "routine action ledger is unavailable");
103
+ try {
104
+ routineReceipt = options.reserveRoutineAction({
105
+ key: execution.routine.key,
106
+ expectedPolicyVersion: execution.routine.expectedPolicyVersion,
107
+ authorizationReceiptId: routineAuthorization.receiptId,
108
+ authorizationVersion: routineAuthorization.profileVersion,
109
+ action: "unraid.container.restart",
110
+ target: fresh.name,
111
+ attemptId: attempt.attemptId,
112
+ expectedBeforeState: fresh.state,
113
+ resolvedTarget: { id: fresh.id, name: fresh.name },
114
+ effect: { operation: "restart", targetId: fresh.id },
115
+ });
116
+ routineState = "reserved";
117
+ }
118
+ catch (error) {
119
+ return failure("stale_target", error instanceof Error ? error.message : "routine action authority changed");
120
+ }
121
+ }
122
+ if (approval && approval.argumentDigest !== attempt.argumentDigest)
123
+ return failure("stale_target", "approval arguments changed before restart");
124
+ await options.persistAttempt?.({ ...attempt, observedAt: now().toISOString(), state: "attempt_not_started" });
125
+ const apiKey = await options.loadWriteApiKey();
126
+ if (!apiKey.trim()) {
127
+ if (routineReceipt && routineState === "reserved")
128
+ transitionRoutine({ id: routineReceipt.id, expectedState: "reserved", state: "failed", recoveryState: { state: "completed", compensation: "none" } });
129
+ return failure("invalid_response", "Unraid write credential is unavailable");
130
+ }
131
+ const client = createClient({ endpoint: options.endpoint, apiKey });
132
+ if (routineReceipt && routineState === "reserved") {
133
+ transitionRoutine({ id: routineReceipt.id, expectedState: "reserved", state: "attempting" });
134
+ routineState = "attempting";
135
+ }
136
+ await options.persistAttempt?.({ ...attempt, observedAt: now().toISOString(), state: "attempting" });
137
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.unraid_restart_start", message: "approved Unraid restart started", meta: { containerId: fresh.id, containerName: fresh.name } });
138
+ const persistTerminal = async (terminal) => {
139
+ try {
140
+ await options.persistAttempt?.(terminal);
141
+ return true;
142
+ }
143
+ catch (error) {
144
+ (0, runtime_1.emitNervesEvent)({ level: "error", component: "repertoire", event: "repertoire.unraid_restart_error", message: "approved Unraid restart terminal receipt persistence failed", meta: { containerId: fresh.id, category: error instanceof Error ? error.name : "unknown" } });
145
+ return false;
146
+ }
147
+ };
148
+ let acknowledged = false;
149
+ let mutation = null;
150
+ try {
151
+ mutation = await client.mutate(exports.SANCTUARY_RESTART_MUTATION, { id: fresh.id });
152
+ acknowledged = acknowledgedIdentity(mutation, fresh);
153
+ if (!acknowledged)
154
+ throw new Error("restart response identity was invalid");
155
+ }
156
+ catch {
157
+ acknowledged = false;
158
+ }
159
+ if (acknowledged && mutation && routineReceipt && routineState === "attempting") {
160
+ transitionRoutine({ id: routineReceipt.id, expectedState: "attempting", state: "effect_acknowledged", effectReceipt: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(mutation)).digest("hex") });
161
+ routineState = "effect_acknowledged";
162
+ }
163
+ const startedAt = now().getTime();
164
+ let sawRestarting = false;
165
+ try {
166
+ do {
167
+ const observed = exactTarget(await options.listContainers(), args.container);
168
+ if (!("ok" in observed)) {
169
+ if (observed.id !== fresh.id) {
170
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: acknowledged });
171
+ if (routineReceipt && routineState)
172
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState, state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
173
+ return failure("ambiguous", "container identity changed after restart attempt");
174
+ }
175
+ sawRestarting ||= observed.state === "restarting";
176
+ if (observed.state === "running" && !observed.degraded && (acknowledged || sawRestarting)) {
177
+ if (!await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "succeeded", mutationAcknowledged: acknowledged, afterState: observed.state })) {
178
+ return failure("ambiguous", "restart succeeded but its terminal receipt could not be persisted; it was not retried");
179
+ }
180
+ if (routineReceipt && routineState === "attempting") {
181
+ transitionRoutine({ id: routineReceipt.id, expectedState: "attempting", state: "effect_acknowledged", effectReceipt: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({ observation: "restarting", target: fresh.id })).digest("hex") });
182
+ routineState = "effect_acknowledged";
183
+ }
184
+ if (routineReceipt && routineState === "effect_acknowledged") {
185
+ transitionRoutine({ id: routineReceipt.id, expectedState: "effect_acknowledged", state: "verified", verifiedAfterState: observed.state, recoveryState: { state: "completed", compensation: "none" } });
186
+ routineState = null;
187
+ }
188
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.unraid_restart_end", message: "approved Unraid restart completed", meta: { containerId: fresh.id, observedRestart: true } });
189
+ return { ok: true, data: { container: { id: fresh.id, name: fresh.name }, beforeState: fresh.state, afterState: observed.state, observedRestart: true, degraded: false } };
190
+ }
191
+ }
192
+ if (now().getTime() - startedAt >= observationTimeoutMs)
193
+ break;
194
+ await sleep(1_000);
195
+ } while (true);
196
+ }
197
+ catch (error) {
198
+ if (error instanceof RoutineActionReceiptError)
199
+ throw error;
200
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: acknowledged });
201
+ if (routineReceipt && routineState)
202
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState, state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
203
+ (0, runtime_1.emitNervesEvent)({ level: "error", component: "repertoire", event: "repertoire.unraid_restart_error", message: "approved Unraid restart observation failed", meta: { containerId: fresh.id, acknowledged } });
204
+ return failure("ambiguous", "restart was attempted but observation failed; it was not retried");
205
+ }
206
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: acknowledged });
207
+ if (routineReceipt && routineState)
208
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState, state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
209
+ (0, runtime_1.emitNervesEvent)({ level: "error", component: "repertoire", event: "repertoire.unraid_restart_error", message: "approved Unraid restart outcome was ambiguous", meta: { containerId: fresh.id, acknowledged } });
210
+ return failure("ambiguous", "restart was attempted but could not be proven; it was not retried");
211
+ };
212
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /**
3
+ * User profile model and vault storage.
4
+ *
5
+ * Profiles are stored as secure notes in the agent's Vaultwarden vault,
6
+ * keyed by friend ID: `user-profile/{friendId}`.
7
+ *
8
+ * The storage layer uses the existing CredentialStore interface — the profile
9
+ * JSON is stored in the `password` field of a login item (the vault's most
10
+ * reliable field for arbitrary data). Field-level access ensures the full
11
+ * profile is never dumped to model context unnecessarily.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.storeUserProfile = storeUserProfile;
15
+ exports.getUserProfile = getUserProfile;
16
+ exports.getUserProfileField = getUserProfileField;
17
+ exports.deleteUserProfile = deleteUserProfile;
18
+ exports.updateUserProfileFields = updateUserProfileFields;
19
+ const runtime_1 = require("../nerves/runtime");
20
+ // ---------------------------------------------------------------------------
21
+ // Storage key
22
+ // ---------------------------------------------------------------------------
23
+ function profileKey(friendId) {
24
+ return `user-profile/${friendId}`;
25
+ }
26
+ function isMissingUserProfileError(err) {
27
+ const message = err instanceof Error ? err.message : String(err);
28
+ return /no credential found/i.test(message) || /field "password" not found/i.test(message);
29
+ }
30
+ // ---------------------------------------------------------------------------
31
+ // CRUD operations
32
+ // ---------------------------------------------------------------------------
33
+ /**
34
+ * Store a complete user profile in the vault.
35
+ * Overwrites any existing profile for the given friend ID.
36
+ */
37
+ async function storeUserProfile(friendId, profile, store) {
38
+ (0, runtime_1.emitNervesEvent)({
39
+ event: "repertoire.user_profile_store",
40
+ component: "repertoire",
41
+ message: `storing user profile for ${friendId}`,
42
+ meta: { friendId },
43
+ });
44
+ const key = profileKey(friendId);
45
+ /* v8 ignore start -- platform-dependent v8 branch counting on await @preserve */
46
+ await store.store(key, {
47
+ password: JSON.stringify(profile),
48
+ notes: "user-profile",
49
+ });
50
+ /* v8 ignore stop */
51
+ }
52
+ /**
53
+ * Retrieve the full user profile for a friend.
54
+ * Returns null if no profile exists. Throws if the stored data is malformed
55
+ * or the vault cannot be read.
56
+ */
57
+ async function getUserProfile(friendId, store) {
58
+ (0, runtime_1.emitNervesEvent)({
59
+ event: "repertoire.user_profile_get",
60
+ component: "repertoire",
61
+ message: `getting user profile for ${friendId}`,
62
+ meta: { friendId },
63
+ });
64
+ try {
65
+ const raw = await store.getRawSecret(profileKey(friendId), "password");
66
+ const parsed = JSON.parse(raw);
67
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
68
+ throw new Error(`stored user profile for ${friendId} is malformed`);
69
+ }
70
+ return parsed;
71
+ }
72
+ catch (err) {
73
+ if (err instanceof SyntaxError) {
74
+ throw new Error(`stored user profile for ${friendId} is malformed`);
75
+ }
76
+ if (isMissingUserProfileError(err)) {
77
+ return null;
78
+ }
79
+ throw err;
80
+ }
81
+ }
82
+ /**
83
+ * Retrieve a specific field from a user profile.
84
+ * Returns undefined if the profile doesn't exist or the field is not set.
85
+ */
86
+ async function getUserProfileField(friendId, field, store) {
87
+ const profile = await getUserProfile(friendId, store);
88
+ if (!profile)
89
+ return undefined;
90
+ return profile[field];
91
+ }
92
+ /**
93
+ * Delete a user profile from the vault.
94
+ * Returns true if the profile was deleted, false if it didn't exist.
95
+ */
96
+ async function deleteUserProfile(friendId, store) {
97
+ (0, runtime_1.emitNervesEvent)({
98
+ event: "repertoire.user_profile_delete",
99
+ component: "repertoire",
100
+ message: `deleting user profile for ${friendId}`,
101
+ meta: { friendId },
102
+ });
103
+ return store.delete(profileKey(friendId));
104
+ }
105
+ /**
106
+ * Update specific fields on a user profile, merging with existing data.
107
+ * Creates the profile if it doesn't exist.
108
+ * Preferences are merged (not replaced) at the key level.
109
+ */
110
+ async function updateUserProfileFields(friendId, fields, store) {
111
+ (0, runtime_1.emitNervesEvent)({
112
+ event: "repertoire.user_profile_update",
113
+ component: "repertoire",
114
+ message: `updating user profile fields for ${friendId}`,
115
+ meta: { friendId, fieldCount: Object.keys(fields).length },
116
+ });
117
+ const existing = await getUserProfile(friendId, store);
118
+ let merged;
119
+ if (existing) {
120
+ // Merge preferences at key level
121
+ const mergedPreferences = {
122
+ ...existing.preferences,
123
+ ...(fields.preferences ?? {}),
124
+ };
125
+ merged = { ...existing, ...fields, preferences: mergedPreferences };
126
+ }
127
+ else {
128
+ merged = fields;
129
+ }
130
+ await storeUserProfile(friendId, merged, store);
131
+ }
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ /**
3
+ * Vault setup module — Bitwarden/Vaultwarden account creation.
4
+ *
5
+ * Implements the Bitwarden registration protocol using Node.js crypto:
6
+ * - PBKDF2-SHA256 for master key derivation
7
+ * - HKDF-SHA256 for key stretching
8
+ * - AES-256-CBC for symmetric key protection
9
+ * - RSA-2048 keypair for asymmetric encryption
10
+ *
11
+ * All crypto follows the Bitwarden security whitepaper:
12
+ * https://bitwarden.com/help/bitwarden-security-white-paper/
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.deriveMasterKey = deriveMasterKey;
49
+ exports.deriveMasterPasswordHash = deriveMasterPasswordHash;
50
+ exports.deriveStretchedMasterKey = deriveStretchedMasterKey;
51
+ exports.makeProtectedSymmetricKey = makeProtectedSymmetricKey;
52
+ exports.createVaultAccount = createVaultAccount;
53
+ const crypto = __importStar(require("node:crypto"));
54
+ const runtime_1 = require("../nerves/runtime");
55
+ // ---------------------------------------------------------------------------
56
+ // Crypto primitives
57
+ // ---------------------------------------------------------------------------
58
+ /**
59
+ * Derive the master key from password and email using PBKDF2-SHA256.
60
+ * Email is lowercased and used as the salt per Bitwarden spec.
61
+ */
62
+ function deriveMasterKey(password, email, iterations) {
63
+ return new Promise((resolve, reject) => {
64
+ crypto.pbkdf2(password, email.toLowerCase(), iterations, 32, "sha256", (err, key) => {
65
+ /* v8 ignore next -- defensive: pbkdf2 rejects on invalid input @preserve */
66
+ if (err)
67
+ reject(err);
68
+ else
69
+ resolve(key);
70
+ });
71
+ });
72
+ }
73
+ /**
74
+ * Derive the master password hash: PBKDF2-SHA256(masterKey, password, 1 iteration).
75
+ * This hash is sent to the server for authentication — it never sees the master key.
76
+ */
77
+ function deriveMasterPasswordHash(masterKey, password) {
78
+ return new Promise((resolve, reject) => {
79
+ crypto.pbkdf2(masterKey, password, 1, 32, "sha256", (err, hash) => {
80
+ /* v8 ignore next -- defensive: pbkdf2 rejects on invalid input @preserve */
81
+ if (err)
82
+ reject(err);
83
+ else
84
+ resolve(hash.toString("base64"));
85
+ });
86
+ });
87
+ }
88
+ /**
89
+ * Stretch the master key using HKDF-Expand-only (RFC 5869 §2.3) to produce a 64-byte key.
90
+ * First 32 bytes = encryption key, last 32 bytes = MAC key.
91
+ *
92
+ * CRITICAL: Bitwarden uses HKDF-Expand ONLY (no Extract step).
93
+ * Node.js crypto.hkdfSync() does Extract+Expand which produces DIFFERENT output.
94
+ * Reference: https://github.com/bitwarden/sdk-internal/blob/main/crates/bitwarden-crypto/src/util.rs
95
+ * Bitwarden calls Hkdf::<Sha256>::from_prk(masterKey).expand(info, output) — Expand only.
96
+ */
97
+ function deriveStretchedMasterKey(masterKey) {
98
+ const encKey = hkdfExpandOnly(masterKey, "enc", 32);
99
+ const macKey = hkdfExpandOnly(masterKey, "mac", 32);
100
+ return Buffer.concat([encKey, macKey]);
101
+ }
102
+ /**
103
+ * HKDF-Expand only (RFC 5869 §2.3) — no Extract step.
104
+ * Matches Bitwarden's Hkdf::from_prk(prk).expand(info).
105
+ */
106
+ function hkdfExpandOnly(prk, info, length) {
107
+ const hashLen = 32; // SHA-256
108
+ const n = Math.ceil(length / hashLen);
109
+ let okm = Buffer.alloc(0);
110
+ let t = Buffer.alloc(0);
111
+ for (let i = 1; i <= n; i++) {
112
+ t = crypto.createHmac("sha256", prk)
113
+ .update(Buffer.concat([t, Buffer.from(info, "utf8"), Buffer.from([i])]))
114
+ .digest();
115
+ okm = Buffer.concat([okm, t]);
116
+ }
117
+ return okm.subarray(0, length);
118
+ }
119
+ /**
120
+ * Encrypt data with AES-256-CBC and HMAC-SHA256 MAC.
121
+ * Returns a Bitwarden "type 2" cipherstring: "2.<iv>|<ct>|<mac>"
122
+ */
123
+ function encryptWithStretchedKey(data, stretchedKey) {
124
+ const encKey = stretchedKey.subarray(0, 32);
125
+ const macKey = stretchedKey.subarray(32, 64);
126
+ const iv = crypto.randomBytes(16);
127
+ const cipher = crypto.createCipheriv("aes-256-cbc", encKey, iv);
128
+ const ct = Buffer.concat([cipher.update(data), cipher.final()]);
129
+ // MAC covers iv + ct
130
+ const mac = crypto.createHmac("sha256", macKey)
131
+ .update(iv)
132
+ .update(ct)
133
+ .digest();
134
+ return `2.${iv.toString("base64")}|${ct.toString("base64")}|${mac.toString("base64")}`;
135
+ }
136
+ /**
137
+ * Generate a 64-byte symmetric key, encrypt it with the stretched master key.
138
+ * Returns the "protected symmetric key" cipherstring.
139
+ */
140
+ function makeProtectedSymmetricKey(stretchedMasterKey) {
141
+ const symKey = crypto.randomBytes(64);
142
+ return encryptWithStretchedKey(symKey, stretchedMasterKey);
143
+ }
144
+ /**
145
+ * Generate an RSA-2048 keypair.
146
+ * Returns { publicKey: base64-DER, privateKeyDer: Buffer }.
147
+ */
148
+ function generateRsaKeypair() {
149
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
150
+ modulusLength: 2048,
151
+ publicKeyEncoding: { type: "spki", format: "der" },
152
+ privateKeyEncoding: { type: "pkcs8", format: "der" },
153
+ });
154
+ return {
155
+ publicKeyB64: publicKey.toString("base64"),
156
+ privateKeyDer: privateKey,
157
+ };
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Registration
161
+ // ---------------------------------------------------------------------------
162
+ const KDF_PBKDF2 = 0;
163
+ const KDF_ITERATIONS = 600000;
164
+ const REGISTER_ACCOUNT_PATH = "/identity/accounts/register";
165
+ /**
166
+ * Create a Bitwarden account on the configured Vaultwarden server.
167
+ * Uses the Bitwarden registration API with standard KDF implementation.
168
+ */
169
+ async function createVaultAccount(agentName, serverUrl, email, masterPassword) {
170
+ (0, runtime_1.emitNervesEvent)({
171
+ event: "repertoire.vault_setup_start",
172
+ component: "repertoire",
173
+ message: `creating vault account for ${agentName}`,
174
+ meta: { agentName, serverUrl, email },
175
+ });
176
+ try {
177
+ // Step 1: Derive keys
178
+ const masterKey = await deriveMasterKey(masterPassword, email, KDF_ITERATIONS);
179
+ const masterPasswordHash = await deriveMasterPasswordHash(masterKey, masterPassword);
180
+ const stretchedKey = deriveStretchedMasterKey(masterKey);
181
+ // Step 2: Generate symmetric key (64 bytes = 32 enc + 32 mac), encrypt with stretched key
182
+ const symKey = crypto.randomBytes(64);
183
+ const protectedSymKey = encryptWithStretchedKey(symKey, stretchedKey);
184
+ // Step 3: Generate RSA keypair, encrypt private key with the symmetric key
185
+ const { publicKeyB64, privateKeyDer } = generateRsaKeypair();
186
+ const encryptedPrivateKey = encryptWithStretchedKey(privateKeyDer, symKey);
187
+ // Step 4: POST registration
188
+ const registrationUrl = `${serverUrl}${REGISTER_ACCOUNT_PATH}`;
189
+ const res = await fetch(registrationUrl, {
190
+ method: "POST",
191
+ headers: { "Content-Type": "application/json" },
192
+ body: JSON.stringify({
193
+ name: agentName,
194
+ email,
195
+ masterPasswordHash,
196
+ masterPasswordHint: null,
197
+ key: protectedSymKey,
198
+ kdf: KDF_PBKDF2,
199
+ kdfIterations: KDF_ITERATIONS,
200
+ keys: {
201
+ publicKey: publicKeyB64,
202
+ encryptedPrivateKey,
203
+ },
204
+ }),
205
+ });
206
+ if (!res.ok) {
207
+ let errorDetail;
208
+ try {
209
+ const body = await res.json();
210
+ errorDetail = body.message ?? `HTTP ${res.status} ${res.statusText}`;
211
+ }
212
+ catch {
213
+ errorDetail = `HTTP ${res.status} ${res.statusText}`;
214
+ }
215
+ const endpointAwareError = `${errorDetail} from ${registrationUrl}. Check --server; Ouro expects a Bitwarden/Vaultwarden identity API.`;
216
+ (0, runtime_1.emitNervesEvent)({
217
+ level: "error",
218
+ event: "repertoire.vault_setup_error",
219
+ component: "repertoire",
220
+ message: `vault registration failed: ${endpointAwareError}`,
221
+ meta: { agentName, serverUrl, email, registrationUrl, reason: endpointAwareError },
222
+ });
223
+ return { success: false, email, serverUrl, error: endpointAwareError };
224
+ }
225
+ (0, runtime_1.emitNervesEvent)({
226
+ event: "repertoire.vault_setup_end",
227
+ component: "repertoire",
228
+ message: `vault account created for ${agentName}`,
229
+ meta: { agentName, serverUrl, email },
230
+ });
231
+ return { success: true, email, serverUrl };
232
+ }
233
+ catch (err) {
234
+ const reason = err instanceof Error ? err.message : String(err);
235
+ const registrationUrl = `${serverUrl}${REGISTER_ACCOUNT_PATH}`;
236
+ const endpointAwareError = `cannot reach vault registration endpoint ${registrationUrl}: ${reason}. Check network, DNS/TLS, and --server.`;
237
+ (0, runtime_1.emitNervesEvent)({
238
+ level: "error",
239
+ event: "repertoire.vault_setup_error",
240
+ component: "repertoire",
241
+ message: `vault setup failed: ${endpointAwareError}`,
242
+ meta: { agentName, serverUrl, email, registrationUrl, reason: endpointAwareError },
243
+ });
244
+ return { success: false, email, serverUrl, error: endpointAwareError };
245
+ }
246
+ }