@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831

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 (647) 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/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5308 -16
  16. package/deploy/unraid/Dockerfile +54 -0
  17. package/deploy/unraid/README.txt +2983 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  34. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  35. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  36. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  37. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  38. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  39. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  40. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  41. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  42. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
  43. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
  49. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  50. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
  51. package/deploy/unraid/sanctuary.xml +28 -0
  52. package/dist/a2a/card.js +57 -0
  53. package/dist/a2a/client.js +180 -0
  54. package/dist/a2a/config.js +50 -0
  55. package/dist/a2a/delegation-stores.js +56 -0
  56. package/dist/a2a/did-resolution.js +93 -0
  57. package/dist/a2a/identity.js +170 -0
  58. package/dist/a2a/inbound-share.js +107 -0
  59. package/dist/a2a/mission-result-wire.js +196 -0
  60. package/dist/a2a/onboarding.js +115 -0
  61. package/dist/a2a/pin-store.js +132 -0
  62. package/dist/a2a/seen-ledger.js +120 -0
  63. package/dist/a2a/server.js +604 -0
  64. package/dist/a2a/task-store.js +69 -0
  65. package/dist/a2a/transport.js +45 -0
  66. package/dist/a2a/types.js +3 -0
  67. package/dist/arc/attention-types.js +8 -0
  68. package/dist/arc/cares.js +360 -0
  69. package/dist/arc/episodes.js +118 -0
  70. package/dist/arc/evolution.js +490 -0
  71. package/dist/arc/flight-recorder.js +1034 -0
  72. package/dist/arc/intentions.js +134 -0
  73. package/dist/arc/json-store.js +117 -0
  74. package/dist/arc/obligations.js +386 -0
  75. package/dist/arc/packets.js +336 -0
  76. package/dist/arc/presence.js +185 -0
  77. package/dist/arc/task-lifecycle.js +57 -0
  78. package/dist/commerce/store.js +755 -0
  79. package/dist/commerce/types.js +3 -0
  80. package/dist/heart/active-work.js +798 -40
  81. package/dist/heart/agent-entry.js +252 -3
  82. package/dist/heart/approval-files.js +113 -0
  83. package/dist/heart/approval-store.js +960 -0
  84. package/dist/heart/attachments/image-normalize.js +194 -0
  85. package/dist/heart/attachments/materialize.js +97 -0
  86. package/dist/heart/attachments/originals.js +88 -0
  87. package/dist/heart/attachments/render.js +29 -0
  88. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  89. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  90. package/dist/heart/attachments/sources/index.js +18 -0
  91. package/dist/heart/attachments/sources/telegram.js +71 -0
  92. package/dist/heart/attachments/store.js +132 -0
  93. package/dist/heart/attachments/types.js +93 -0
  94. package/dist/heart/auth/auth-flow.js +495 -0
  95. package/dist/heart/autonomy-budget.js +478 -0
  96. package/dist/heart/awaiting/await-alert.js +148 -0
  97. package/dist/heart/awaiting/await-expiry.js +143 -0
  98. package/dist/heart/awaiting/await-loader.js +91 -0
  99. package/dist/heart/awaiting/await-parser.js +149 -0
  100. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  101. package/dist/heart/awaiting/await-scheduler.js +382 -0
  102. package/dist/heart/background-operations.js +281 -0
  103. package/dist/heart/bridges/manager.js +137 -17
  104. package/dist/heart/bridges/store.js +14 -2
  105. package/dist/heart/bundle-state.js +168 -0
  106. package/dist/heart/commitments.js +44 -18
  107. package/dist/heart/config-registry.js +331 -0
  108. package/dist/heart/config.js +174 -131
  109. package/dist/heart/context-loss-gauntlet.js +387 -0
  110. package/dist/heart/context-loss-sentinel.js +1157 -0
  111. package/dist/heart/core.js +2169 -581
  112. package/dist/heart/cross-chat-delivery.js +9 -22
  113. package/dist/heart/daemon/agent-config-check.js +451 -0
  114. package/dist/heart/daemon/agent-discovery.js +185 -3
  115. package/dist/heart/daemon/agent-service.js +542 -0
  116. package/dist/heart/daemon/agentic-repair.js +547 -0
  117. package/dist/heart/daemon/await-private-wake.js +59 -0
  118. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  119. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  120. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  121. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  122. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  123. package/dist/heart/daemon/cadence.js +180 -0
  124. package/dist/heart/daemon/cli-defaults.js +854 -0
  125. package/dist/heart/daemon/cli-desk.js +322 -0
  126. package/dist/heart/daemon/cli-exec.js +8822 -0
  127. package/dist/heart/daemon/cli-help.js +716 -0
  128. package/dist/heart/daemon/cli-parse.js +2771 -0
  129. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  130. package/dist/heart/daemon/cli-render.js +777 -0
  131. package/dist/heart/daemon/cli-types.js +8 -0
  132. package/dist/heart/daemon/connect-bay.js +323 -0
  133. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  134. package/dist/heart/daemon/container-healthcheck.js +112 -0
  135. package/dist/heart/daemon/container-runtime.js +97 -0
  136. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  137. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  138. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  139. package/dist/heart/daemon/daemon-cli.js +29 -2349
  140. package/dist/heart/daemon/daemon-entry.js +930 -11
  141. package/dist/heart/daemon/daemon-health.js +186 -0
  142. package/dist/heart/daemon/daemon-rollup.js +57 -0
  143. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  144. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  145. package/dist/heart/daemon/daemon.js +2084 -105
  146. package/dist/heart/daemon/dns-workflow.js +394 -0
  147. package/dist/heart/daemon/doctor-types.js +8 -0
  148. package/dist/heart/daemon/doctor.js +1755 -0
  149. package/dist/heart/daemon/freshness.js +345 -0
  150. package/dist/heart/daemon/habit-private-wake.js +61 -0
  151. package/dist/heart/daemon/health-monitor.js +142 -11
  152. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  153. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  154. package/dist/heart/daemon/http-health-probe.js +80 -0
  155. package/dist/heart/daemon/human-command-screens.js +234 -0
  156. package/dist/heart/daemon/human-readiness.js +114 -0
  157. package/dist/heart/daemon/inner-status.js +78 -0
  158. package/dist/heart/daemon/interactive-repair.js +394 -0
  159. package/dist/heart/daemon/launchd.js +37 -8
  160. package/dist/heart/daemon/log-tailer.js +79 -10
  161. package/dist/heart/daemon/logs-prune.js +132 -0
  162. package/dist/heart/daemon/mcp-canary.js +524 -0
  163. package/dist/heart/daemon/message-router.js +65 -5
  164. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  165. package/dist/heart/daemon/os-cron-deps.js +135 -0
  166. package/dist/heart/daemon/os-cron.js +22 -14
  167. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  168. package/dist/heart/daemon/ouro-entry.js +3 -1
  169. package/dist/heart/daemon/plugin-cli.js +432 -0
  170. package/dist/heart/daemon/process-manager.js +733 -61
  171. package/dist/heart/daemon/provider-discovery.js +137 -0
  172. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  173. package/dist/heart/daemon/prunable-bundle.js +144 -0
  174. package/dist/heart/daemon/pulse.js +511 -0
  175. package/dist/heart/daemon/readiness-repair.js +365 -0
  176. package/dist/heart/daemon/run-hooks.js +2 -0
  177. package/dist/heart/daemon/runtime-logging.js +47 -14
  178. package/dist/heart/daemon/runtime-metadata.js +2 -30
  179. package/dist/heart/daemon/runtime-mode.js +13 -2
  180. package/dist/heart/daemon/safe-mode.js +161 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  185. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  186. package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
  187. package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
  188. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  189. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
  190. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  191. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  192. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  193. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
  194. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  195. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  196. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  197. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  198. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  199. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  200. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  201. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  202. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  203. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
  204. package/dist/heart/daemon/sense-manager.js +699 -48
  205. package/dist/heart/daemon/session-id-resolver.js +131 -0
  206. package/dist/heart/daemon/skill-management-installer.js +1 -1
  207. package/dist/heart/daemon/socket-client.js +180 -12
  208. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  209. package/dist/heart/daemon/startup-tui.js +339 -0
  210. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  211. package/dist/heart/daemon/task-scheduler.js +117 -39
  212. package/dist/heart/daemon/terminal-ui.js +499 -0
  213. package/dist/heart/daemon/thoughts.js +138 -54
  214. package/dist/heart/daemon/up-progress.js +366 -0
  215. package/dist/heart/daemon/vault-items.js +56 -0
  216. package/dist/heart/delegation.js +1 -4
  217. package/dist/heart/external-events/router.js +1430 -0
  218. package/dist/heart/frontend-approval-runtime.js +506 -0
  219. package/dist/heart/frontend-journal.js +215 -0
  220. package/dist/heart/frontend-session-service.js +237 -0
  221. package/dist/heart/frontend-socket-client.js +164 -0
  222. package/dist/heart/frontend-socket.js +400 -0
  223. package/dist/heart/habits/habit-cancel.js +810 -0
  224. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  225. package/dist/heart/habits/habit-migration.js +194 -0
  226. package/dist/heart/habits/habit-parser.js +278 -0
  227. package/dist/heart/habits/habit-runtime-state.js +93 -0
  228. package/dist/heart/habits/habit-scheduler.js +653 -0
  229. package/dist/heart/habits/habit-session-summary.js +318 -0
  230. package/dist/heart/habits/habit-session.js +636 -0
  231. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  232. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  233. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  234. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  235. package/dist/heart/identity.js +196 -59
  236. package/dist/heart/kept-notes.js +289 -0
  237. package/dist/heart/kicks.js +1 -1
  238. package/dist/heart/machine-identity.js +161 -0
  239. package/dist/heart/mail-import-discovery.js +356 -0
  240. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  241. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  242. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  243. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  244. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  245. package/dist/heart/mailbox/mailbox-http.js +99 -0
  246. package/dist/heart/mailbox/mailbox-read.js +39 -0
  247. package/dist/heart/mailbox/mailbox-types.js +27 -0
  248. package/dist/heart/mailbox/mailbox-view.js +197 -0
  249. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  250. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  251. package/dist/heart/mailbox/readers/mail.js +375 -0
  252. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  253. package/dist/heart/mailbox/readers/sessions.js +231 -0
  254. package/dist/heart/mailbox/readers/shared.js +111 -0
  255. package/dist/heart/mcp/mcp-server.js +696 -0
  256. package/dist/heart/migrate-config.js +100 -0
  257. package/dist/heart/model-capabilities.js +11 -0
  258. package/dist/heart/orientation-frame.js +345 -0
  259. package/dist/heart/platform.js +81 -0
  260. package/dist/heart/primitives.js +1 -1
  261. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  262. package/dist/heart/private-runtime/index.js +18 -0
  263. package/dist/heart/private-runtime/ledger.js +221 -0
  264. package/dist/heart/private-runtime/policy.js +252 -0
  265. package/dist/heart/private-runtime/types.js +2 -0
  266. package/dist/heart/progress-story.js +1 -1
  267. package/dist/heart/provider-attempt.js +137 -0
  268. package/dist/heart/provider-binding-resolver.js +273 -0
  269. package/dist/heart/provider-credentials.js +449 -0
  270. package/dist/heart/provider-failover.js +311 -0
  271. package/dist/heart/provider-models.js +96 -0
  272. package/dist/heart/provider-ping.js +265 -0
  273. package/dist/heart/provider-readiness-cache.js +119 -0
  274. package/dist/heart/provider-visibility.js +188 -0
  275. package/dist/heart/providers/anthropic-token.js +131 -0
  276. package/dist/heart/providers/anthropic.js +173 -60
  277. package/dist/heart/providers/azure.js +23 -11
  278. package/dist/heart/providers/error-classification.js +127 -0
  279. package/dist/heart/providers/github-copilot.js +34 -38
  280. package/dist/heart/providers/minimax-vlm.js +189 -0
  281. package/dist/heart/providers/minimax.js +26 -8
  282. package/dist/heart/providers/openai-codex-token.js +349 -0
  283. package/dist/heart/providers/openai-codex.js +55 -40
  284. package/dist/heart/providers/openai-compatible.js +177 -0
  285. package/dist/heart/run-ledger.js +247 -0
  286. package/dist/heart/runtime-capability-check.js +170 -0
  287. package/dist/heart/runtime-credentials.js +607 -0
  288. package/dist/heart/runtime-cwd.js +87 -0
  289. package/dist/heart/sense-truth.js +22 -4
  290. package/dist/heart/session-activity.js +92 -24
  291. package/dist/heart/session-events.js +1504 -0
  292. package/dist/heart/session-playback-cli-main.js +5 -0
  293. package/dist/heart/session-playback-cli.js +36 -0
  294. package/dist/heart/session-playback.js +231 -0
  295. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  296. package/dist/heart/session-redaction-repair.js +552 -0
  297. package/dist/heart/session-stats-cli-main.js +5 -0
  298. package/dist/heart/session-stats.js +183 -0
  299. package/dist/heart/session-transcript.js +133 -0
  300. package/dist/heart/start-of-turn-packet.js +372 -0
  301. package/dist/heart/steward-policy.js +618 -0
  302. package/dist/heart/streaming.js +604 -207
  303. package/dist/heart/structured-output.js +196 -0
  304. package/dist/heart/sync-classification.js +176 -0
  305. package/dist/heart/sync.js +449 -0
  306. package/dist/heart/target-resolution.js +11 -7
  307. package/dist/heart/tempo.js +93 -0
  308. package/dist/heart/temporal-view.js +41 -0
  309. package/dist/heart/timeouts.js +101 -0
  310. package/dist/heart/tool-activity-callbacks.js +59 -0
  311. package/dist/heart/tool-approval.js +382 -0
  312. package/dist/heart/tool-description.js +155 -0
  313. package/dist/heart/tool-friction.js +55 -0
  314. package/dist/heart/tool-loop.js +200 -0
  315. package/dist/heart/turn-context.js +482 -0
  316. package/dist/heart/turn-execution-lease.js +30 -0
  317. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  318. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  319. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  320. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  321. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  322. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  323. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  324. package/dist/heart/versioning/update-hooks.js +154 -0
  325. package/dist/heart/versioning/version-intent.js +114 -0
  326. package/dist/heart/work-card.js +380 -0
  327. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  328. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  329. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  330. package/dist/mailbox-ui/index.html +16 -0
  331. package/dist/mailroom/attention.js +167 -0
  332. package/dist/mailroom/autonomy.js +209 -0
  333. package/dist/mailroom/blob-store.js +889 -0
  334. package/dist/mailroom/body-cache.js +61 -0
  335. package/dist/mailroom/cache-sync-cli.js +58 -0
  336. package/dist/mailroom/core.js +803 -0
  337. package/dist/mailroom/entry.js +160 -0
  338. package/dist/mailroom/file-store.js +568 -0
  339. package/dist/mailroom/hosted-cache-sync.js +384 -0
  340. package/dist/mailroom/mbox-import.js +393 -0
  341. package/dist/mailroom/migration.js +164 -0
  342. package/dist/mailroom/outbound.js +380 -0
  343. package/dist/mailroom/policy.js +263 -0
  344. package/dist/mailroom/reader.js +292 -0
  345. package/dist/mailroom/search-cache.js +513 -0
  346. package/dist/mailroom/search-relevance.js +319 -0
  347. package/dist/mailroom/smtp-ingress.js +176 -0
  348. package/dist/mailroom/source-state.js +176 -0
  349. package/dist/mailroom/thread.js +109 -0
  350. package/dist/mailroom/travel-extract.js +89 -0
  351. package/dist/mind/bundle-manifest.js +24 -2
  352. package/dist/mind/context.js +309 -111
  353. package/dist/mind/desk-section.js +362 -0
  354. package/dist/mind/diary-integrity.js +60 -0
  355. package/dist/mind/{memory.js → diary.js} +68 -77
  356. package/dist/mind/embedding-provider.js +60 -0
  357. package/dist/mind/file-state.js +179 -0
  358. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  359. package/dist/mind/obligation-steering.js +199 -3
  360. package/dist/mind/pending.js +36 -10
  361. package/dist/mind/prompt-budget.js +479 -0
  362. package/dist/mind/prompt-refresh.js +3 -2
  363. package/dist/mind/prompt.js +1050 -189
  364. package/dist/mind/provenance-trust.js +26 -0
  365. package/dist/mind/record-paths.js +312 -0
  366. package/dist/mind/scrutiny.js +173 -0
  367. package/dist/mind/session-transaction.js +564 -0
  368. package/dist/nerves/cli-logging.js +7 -1
  369. package/dist/nerves/coverage/audit-rules.js +15 -6
  370. package/dist/nerves/coverage/audit.js +28 -2
  371. package/dist/nerves/coverage/cli.js +1 -1
  372. package/dist/nerves/coverage/contract.js +5 -5
  373. package/dist/nerves/coverage/file-completeness.js +139 -5
  374. package/dist/nerves/coverage/run-artifacts.js +55 -35
  375. package/dist/nerves/coverage/source-scanner.js +4 -4
  376. package/dist/nerves/event-buffer.js +111 -0
  377. package/dist/nerves/index.js +293 -9
  378. package/dist/nerves/observation.js +20 -0
  379. package/dist/nerves/redact.js +79 -0
  380. package/dist/nerves/review/cli-main.js +5 -0
  381. package/dist/nerves/review/cli.js +156 -0
  382. package/dist/nerves/review/core.js +159 -0
  383. package/dist/nerves/runtime.js +17 -1
  384. package/dist/repertoire/ado-client.js +15 -56
  385. package/dist/repertoire/ado-semantic.js +16 -10
  386. package/dist/repertoire/api-client.js +97 -0
  387. package/dist/repertoire/bitwarden-store.js +1045 -0
  388. package/dist/repertoire/bundle-templates.js +71 -0
  389. package/dist/repertoire/bw-installer.js +180 -0
  390. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  391. package/dist/repertoire/coding/context-pack.js +331 -0
  392. package/dist/repertoire/coding/feedback.js +174 -32
  393. package/dist/repertoire/coding/index.js +15 -3
  394. package/dist/repertoire/coding/manager.js +159 -10
  395. package/dist/repertoire/coding/spawner.js +58 -11
  396. package/dist/repertoire/coding/tools.js +221 -15
  397. package/dist/repertoire/coding/workbench-client.js +272 -0
  398. package/dist/repertoire/coding/workbench-manager.js +346 -0
  399. package/dist/repertoire/commerce-errors.js +109 -0
  400. package/dist/repertoire/commerce-self-test.js +156 -0
  401. package/dist/repertoire/credential-access.js +178 -0
  402. package/dist/repertoire/desk/classifier.js +362 -0
  403. package/dist/repertoire/duffel-client.js +185 -0
  404. package/dist/repertoire/github-client.js +14 -55
  405. package/dist/repertoire/graph-client.js +11 -52
  406. package/dist/repertoire/guardrails.js +811 -18
  407. package/dist/repertoire/mcp-client.js +44 -3
  408. package/dist/repertoire/mcp-manager.js +427 -139
  409. package/dist/repertoire/mcp-tools.js +124 -0
  410. package/dist/repertoire/plugin-mcp.js +175 -0
  411. package/dist/repertoire/plugins.js +253 -0
  412. package/dist/repertoire/relationship-authorization.js +322 -0
  413. package/dist/repertoire/shell-sessions.js +134 -0
  414. package/dist/repertoire/skills.js +48 -4
  415. package/dist/repertoire/stripe-client.js +131 -0
  416. package/dist/repertoire/tool-arguments.js +170 -0
  417. package/dist/repertoire/tool-results.js +29 -0
  418. package/dist/repertoire/tools-a2a.js +699 -0
  419. package/dist/repertoire/tools-attachments.js +322 -0
  420. package/dist/repertoire/tools-awaiting.js +575 -0
  421. package/dist/repertoire/tools-base.js +77 -1138
  422. package/dist/repertoire/tools-bluebubbles.js +2 -0
  423. package/dist/repertoire/tools-bridge.js +144 -0
  424. package/dist/repertoire/tools-bundle.js +993 -0
  425. package/dist/repertoire/tools-commerce.js +253 -0
  426. package/dist/repertoire/tools-config.js +186 -0
  427. package/dist/repertoire/tools-continuity.js +575 -0
  428. package/dist/repertoire/tools-credential.js +383 -0
  429. package/dist/repertoire/tools-evolution.js +527 -0
  430. package/dist/repertoire/tools-files.js +344 -0
  431. package/dist/repertoire/tools-flight.js +290 -0
  432. package/dist/repertoire/tools-flow.js +119 -0
  433. package/dist/repertoire/tools-github.js +3 -8
  434. package/dist/repertoire/tools-habits.js +103 -0
  435. package/dist/repertoire/tools-mail.js +1828 -0
  436. package/dist/repertoire/tools-notes.js +485 -0
  437. package/dist/repertoire/tools-obligations.js +182 -0
  438. package/dist/repertoire/tools-orientation.js +31 -0
  439. package/dist/repertoire/tools-record.js +482 -0
  440. package/dist/repertoire/tools-rsvp.js +139 -0
  441. package/dist/repertoire/tools-runtime.js +150 -0
  442. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  443. package/dist/repertoire/tools-session.js +1133 -0
  444. package/dist/repertoire/tools-shell.js +149 -0
  445. package/dist/repertoire/tools-steward-policy.js +119 -0
  446. package/dist/repertoire/tools-stripe.js +224 -0
  447. package/dist/repertoire/tools-surface.js +369 -0
  448. package/dist/repertoire/tools-teams.js +12 -39
  449. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  450. package/dist/repertoire/tools-travel.js +125 -0
  451. package/dist/repertoire/tools-trip.js +982 -0
  452. package/dist/repertoire/tools-unraid.js +531 -0
  453. package/dist/repertoire/tools-user-profile.js +146 -0
  454. package/dist/repertoire/tools-vault.js +40 -0
  455. package/dist/repertoire/tools-voice.js +145 -0
  456. package/dist/repertoire/tools.js +494 -148
  457. package/dist/repertoire/travel-api-client.js +360 -0
  458. package/dist/repertoire/unraid-client.js +155 -0
  459. package/dist/repertoire/unraid-restart.js +339 -0
  460. package/dist/repertoire/user-profile.js +131 -0
  461. package/dist/repertoire/vault-setup.js +246 -0
  462. package/dist/repertoire/vault-unlock.js +628 -0
  463. package/dist/rsvp/aisleplanner-client.js +354 -0
  464. package/dist/rsvp/cli.js +926 -0
  465. package/dist/rsvp/config.js +327 -0
  466. package/dist/rsvp/cutover.js +433 -0
  467. package/dist/rsvp/diagnostics.js +232 -0
  468. package/dist/rsvp/diff-renderer.js +176 -0
  469. package/dist/rsvp/habit-policy.js +110 -0
  470. package/dist/rsvp/habit-stage.js +123 -0
  471. package/dist/rsvp/incident-bundle.js +97 -0
  472. package/dist/rsvp/migration.js +204 -0
  473. package/dist/rsvp/native-habit-runner.js +630 -0
  474. package/dist/rsvp/outbound-state.js +628 -0
  475. package/dist/rsvp/query.js +118 -0
  476. package/dist/rsvp/replay.js +233 -0
  477. package/dist/rsvp/snapshot.js +232 -0
  478. package/dist/rsvp/spend-ledger.js +175 -0
  479. package/dist/scripts/claude-code-hook.js +41 -0
  480. package/dist/scripts/claude-code-stop-hook.js +47 -0
  481. package/dist/senses/a2a-entry.js +115 -0
  482. package/dist/senses/acp-server.js +386 -0
  483. package/dist/senses/attention-queue.js +186 -0
  484. package/dist/senses/await-turn-message.js +58 -0
  485. package/dist/senses/bluebubbles/active-turns.js +216 -0
  486. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  487. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  488. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  489. package/dist/senses/bluebubbles/context-packet.js +207 -0
  490. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  491. package/dist/senses/bluebubbles/entry.js +90 -0
  492. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  493. package/dist/senses/bluebubbles/index.js +3841 -0
  494. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  495. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  496. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  497. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  498. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  499. package/dist/senses/bluebubbles/processed-log.js +133 -0
  500. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  501. package/dist/senses/bluebubbles/replay.js +284 -0
  502. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  503. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  504. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  505. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  506. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  507. package/dist/senses/cli/bracketed-paste.js +82 -0
  508. package/dist/senses/cli/image-paste.js +287 -0
  509. package/dist/senses/cli/image-ref-navigation.js +75 -0
  510. package/dist/senses/cli/ink-app.js +156 -0
  511. package/dist/senses/cli/inline-diff.js +64 -0
  512. package/dist/senses/cli/input-keys.js +174 -0
  513. package/dist/senses/cli/kill-ring.js +86 -0
  514. package/dist/senses/cli/message-list.js +51 -0
  515. package/dist/senses/cli/ouro-tui.js +607 -0
  516. package/dist/senses/cli/spinner-imperative.js +135 -0
  517. package/dist/senses/cli/spinner.js +101 -0
  518. package/dist/senses/cli/status-line.js +60 -0
  519. package/dist/senses/cli/streaming-markdown.js +526 -0
  520. package/dist/senses/cli/tool-display.js +85 -0
  521. package/dist/senses/cli/tool-render.js +85 -0
  522. package/dist/senses/cli/tui-store.js +241 -0
  523. package/dist/senses/cli/virtual-list.js +35 -0
  524. package/dist/senses/cli-entry.js +60 -8
  525. package/dist/senses/cli.js +604 -320
  526. package/dist/senses/commands.js +66 -3
  527. package/dist/senses/context-packet-ledger.js +371 -0
  528. package/dist/senses/context-packets.js +154 -0
  529. package/dist/senses/habit-lifecycle-guard.js +24 -0
  530. package/dist/senses/habit-turn-message.js +160 -0
  531. package/dist/senses/ingress-evidence.js +2 -0
  532. package/dist/senses/mail-entry.js +66 -0
  533. package/dist/senses/mail.js +524 -0
  534. package/dist/senses/pipeline.js +1115 -204
  535. package/dist/senses/private-runtime-worker.js +859 -0
  536. package/dist/senses/private-runtime.js +1517 -0
  537. package/dist/senses/proactive-content-guard.js +51 -0
  538. package/dist/senses/root-host-approval-port.js +345 -0
  539. package/dist/senses/root-host-approval-runtime.js +393 -0
  540. package/dist/senses/sanctuary-authority-resident.js +102 -0
  541. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  542. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  543. package/dist/senses/sanctuary-grounding.js +118 -0
  544. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  545. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  546. package/dist/senses/sanctuary-health-runner.js +100 -0
  547. package/dist/senses/sanctuary-health.js +408 -0
  548. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  549. package/dist/senses/sanctuary-interactive-control.js +410 -0
  550. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  551. package/dist/senses/sanctuary-media-optimization.js +514 -0
  552. package/dist/senses/sanctuary-runtime.js +340 -0
  553. package/dist/senses/sanctuary-sab.js +85 -0
  554. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  555. package/dist/senses/shared-turn.js +772 -0
  556. package/dist/senses/surface-tool.js +109 -0
  557. package/dist/senses/teams-entry.js +60 -8
  558. package/dist/senses/teams.js +519 -218
  559. package/dist/senses/telegram-admission.js +718 -0
  560. package/dist/senses/telegram-approval-runtime.js +793 -0
  561. package/dist/senses/telegram-attachments.js +186 -0
  562. package/dist/senses/telegram-audit-ledger.js +220 -0
  563. package/dist/senses/telegram-authority-transport.js +231 -0
  564. package/dist/senses/telegram-client.js +1749 -0
  565. package/dist/senses/telegram-effect-adapter.js +896 -0
  566. package/dist/senses/telegram-entry.js +83 -0
  567. package/dist/senses/telegram.js +2324 -0
  568. package/dist/senses/trust-gate.js +104 -9
  569. package/dist/senses/voice/audio-playback.js +237 -0
  570. package/dist/senses/voice/audio-routing.js +119 -0
  571. package/dist/senses/voice/elevenlabs.js +202 -0
  572. package/dist/senses/voice/floor-control.js +431 -0
  573. package/dist/senses/voice/floor-controller.js +115 -0
  574. package/dist/senses/voice/golden-path.js +116 -0
  575. package/dist/senses/voice/index.js +29 -0
  576. package/dist/senses/voice/meeting.js +113 -0
  577. package/dist/senses/voice/outbound.js +190 -0
  578. package/dist/senses/voice/phone.js +33 -0
  579. package/dist/senses/voice/playback.js +139 -0
  580. package/dist/senses/voice/realtime-eval.js +496 -0
  581. package/dist/senses/voice/realtime-trace.js +531 -0
  582. package/dist/senses/voice/transcript.js +70 -0
  583. package/dist/senses/voice/turn.js +191 -0
  584. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  585. package/dist/senses/voice/twilio-phone.js +5031 -0
  586. package/dist/senses/voice/types.js +2 -0
  587. package/dist/senses/voice/whisper.js +161 -0
  588. package/dist/senses/voice-entry.js +81 -0
  589. package/dist/senses/voice-realtime-eval-command.js +99 -0
  590. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  591. package/dist/senses/voice-twilio-entry.js +87 -0
  592. package/dist/trips/core.js +138 -0
  593. package/dist/trips/store.js +265 -0
  594. package/dist/util/frontmatter.js +69 -0
  595. package/npm-shrinkwrap.json +8138 -0
  596. package/package.json +72 -13
  597. package/skills/agent-commerce.md +113 -0
  598. package/skills/browser-navigation.md +117 -0
  599. package/skills/commerce-setup-guide.md +116 -0
  600. package/skills/commerce-setup.md +84 -0
  601. package/skills/configure-dev-tools.md +99 -0
  602. package/skills/travel-planning.md +138 -0
  603. package/dist/heart/daemon/auth-flow.js +0 -430
  604. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  605. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  606. package/dist/heart/daemon/update-hooks.js +0 -138
  607. package/dist/heart/obligations.js +0 -191
  608. package/dist/heart/safe-workspace.js +0 -228
  609. package/dist/heart/session-recall.js +0 -116
  610. package/dist/mind/friends/channel.js +0 -84
  611. package/dist/mind/friends/group-context.js +0 -144
  612. package/dist/mind/friends/resolver.js +0 -84
  613. package/dist/mind/friends/store-file.js +0 -190
  614. package/dist/mind/friends/store.js +0 -4
  615. package/dist/mind/friends/tokens.js +0 -26
  616. package/dist/mind/friends/trust-explanation.js +0 -74
  617. package/dist/mind/friends/types.js +0 -29
  618. package/dist/repertoire/tasks/board.js +0 -134
  619. package/dist/repertoire/tasks/index.js +0 -224
  620. package/dist/repertoire/tasks/lifecycle.js +0 -80
  621. package/dist/repertoire/tasks/middleware.js +0 -65
  622. package/dist/repertoire/tasks/parser.js +0 -173
  623. package/dist/repertoire/tasks/scanner.js +0 -132
  624. package/dist/repertoire/tasks/transitions.js +0 -144
  625. package/dist/senses/bluebubbles-entry.js +0 -13
  626. package/dist/senses/bluebubbles.js +0 -1181
  627. package/dist/senses/debug-activity.js +0 -154
  628. package/dist/senses/inner-dialog-worker.js +0 -90
  629. package/dist/senses/inner-dialog.js +0 -525
  630. package/subagents/README.md +0 -7
  631. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  632. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  633. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  643. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  644. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  645. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  646. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  647. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,339 @@
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
+ const router_1 = require("../heart/external-events/router");
9
+ exports.SANCTUARY_RESTART_MUTATION = `mutation SanctuaryRestart($id: PrefixedID!) {
10
+ docker { restart(id: $id) { id names state status autoStart } }
11
+ }`;
12
+ class RoutineActionReceiptError extends Error {
13
+ constructor(cause) {
14
+ super("routine action receipt persistence failed", { cause });
15
+ this.name = "RoutineActionReceiptError";
16
+ }
17
+ }
18
+ function failure(code, message) {
19
+ return { ok: false, error: { code, message: message.slice(0, 500), degraded: true } };
20
+ }
21
+ function exactTarget(result, name) {
22
+ if (!result.ok)
23
+ return failure("invalid_response", result.error.message);
24
+ const matches = result.data.containers.filter((container) => container.name === name);
25
+ if (matches.length === 0)
26
+ return failure("not_found", `container '${name}' was not found`);
27
+ if (matches.length !== 1)
28
+ return failure("ambiguous", `container '${name}' is ambiguous`);
29
+ return matches[0];
30
+ }
31
+ function validArgument(value) {
32
+ return typeof value === "string" && value.length > 0 && Buffer.byteLength(value, "utf8") <= 128 && !value.includes("\uFFFD");
33
+ }
34
+ async function currentRoutineAuthorization(authority) {
35
+ let authorization;
36
+ try {
37
+ authorization = await authority.reauthorize();
38
+ }
39
+ catch {
40
+ throw new Error("routine relationship authorization is unavailable");
41
+ }
42
+ if (!authorization.allowed)
43
+ throw new Error(authorization.reason);
44
+ if (!authorization.receiptId.trim() || !Number.isInteger(authorization.profileVersion) || authorization.profileVersion < 1) {
45
+ throw new Error("routine relationship authorization is not versioned");
46
+ }
47
+ return { receiptId: authorization.receiptId, profileVersion: authorization.profileVersion };
48
+ }
49
+ function acknowledgedIdentity(data, target) {
50
+ const docker = data.docker;
51
+ if (!docker || typeof docker !== "object" || Array.isArray(docker))
52
+ return false;
53
+ const restart = docker.restart;
54
+ if (!restart || typeof restart !== "object" || Array.isArray(restart))
55
+ return false;
56
+ const record = restart;
57
+ return record.id === target.id && Array.isArray(record.names)
58
+ && record.names.length === 1 && String(record.names[0]).replace(/^\//u, "") === target.name;
59
+ }
60
+ function createApprovedUnraidRestartExecutor(options) {
61
+ const createClient = options.createClient ?? ((input) => new unraid_client_1.UnraidClient(input));
62
+ const sleep = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
63
+ const now = options.now ?? (() => new Date());
64
+ const observationTimeoutMs = options.observationTimeoutMs ?? 30_000;
65
+ const transitionRoutine = (input) => {
66
+ try {
67
+ options.transitionRoutineAction?.(input);
68
+ }
69
+ catch (error) {
70
+ throw new RoutineActionReceiptError(error);
71
+ }
72
+ };
73
+ return async (args, execution) => {
74
+ if (!validArgument(args.container))
75
+ return failure("invalid_response", "container must be one bounded exact name");
76
+ const routine = execution?.routine;
77
+ const approvalInput = execution?.approval;
78
+ if (execution && Object.hasOwn(execution, "approval") && (!approvalInput || typeof approvalInput.reauthorize !== "function"
79
+ || !validArgument(approvalInput.target?.id) || approvalInput.target.id !== approvalInput.target.id.trim()
80
+ || approvalInput.target.name !== args.container))
81
+ return failure("invalid_response", "restart approval authority is invalid");
82
+ const approvalAuthority = approvalInput && { target: { ...approvalInput.target }, reauthorize: approvalInput.reauthorize };
83
+ if (approvalAuthority && routine)
84
+ return failure("invalid_response", "restart has conflicting approval and routine authority");
85
+ const resolved = exactTarget(await options.listContainers(), args.container);
86
+ if ("ok" in resolved)
87
+ return resolved;
88
+ const fresh = exactTarget(await options.listContainers(), args.container);
89
+ if ("ok" in fresh)
90
+ return fresh;
91
+ if (fresh.id !== resolved.id)
92
+ return failure("stale_target", "container identity changed before restart");
93
+ let routineAuthorization = null;
94
+ if (routine) {
95
+ try {
96
+ routineAuthorization = await currentRoutineAuthorization(routine);
97
+ }
98
+ catch (error) {
99
+ return failure("stale_target", error instanceof Error ? error.message : "routine relationship authorization is unavailable");
100
+ }
101
+ }
102
+ const scenarioHandleDigest = options.acceptanceScenarioHandleDigest?.();
103
+ const approval = options.acceptanceApproval?.();
104
+ const attempt = {
105
+ container: { id: fresh.id, name: fresh.name },
106
+ beforeState: fresh.state,
107
+ observedAt: now().toISOString(),
108
+ actionDigest: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({ operation: "restart", container: { id: fresh.id, name: fresh.name } })).digest("hex"),
109
+ argumentDigest: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({ container: args.container })).digest("hex"),
110
+ ...(scenarioHandleDigest ? { scenarioHandleDigest } : {}),
111
+ ...(approval ? { approvalId: approval.approvalId } : {}),
112
+ attemptId: (0, node_crypto_1.randomUUID)(),
113
+ mutationAcknowledged: false,
114
+ afterState: null,
115
+ };
116
+ let routineReceipt = null;
117
+ const routineState = { current: null };
118
+ if (routine) {
119
+ if (!options.reserveRoutineAction || !options.transitionRoutineAction || !options.withRoutineActionAttempt)
120
+ return failure("invalid_response", "routine action ledger is unavailable");
121
+ try {
122
+ routineReceipt = structuredClone(options.reserveRoutineAction({
123
+ key: routine.key,
124
+ expectedPolicyVersion: routine.expectedPolicyVersion,
125
+ expectedDesiredStateVersion: routine.expectedDesiredStateVersion,
126
+ expectedGrantVersion: routine.expectedGrantVersion,
127
+ requester: routine.requester,
128
+ authorizationReceiptId: routineAuthorization.receiptId,
129
+ authorizationVersion: routineAuthorization.profileVersion,
130
+ action: "unraid.container.restart",
131
+ target: fresh.name,
132
+ attemptId: attempt.attemptId,
133
+ expectedBeforeState: fresh.state,
134
+ resolvedTarget: { id: fresh.id, name: fresh.name },
135
+ effect: { operation: "restart", targetId: fresh.id },
136
+ }));
137
+ routineState.current = "reserved";
138
+ }
139
+ catch (error) {
140
+ return failure("stale_target", error instanceof Error ? error.message : "routine action authority changed");
141
+ }
142
+ }
143
+ const failReserved = () => {
144
+ if (routineReceipt && routineState.current === "reserved") {
145
+ transitionRoutine({ id: routineReceipt.id, expectedState: "reserved", state: "failed", recoveryState: { state: "completed", compensation: "none" } });
146
+ routineState.current = null;
147
+ }
148
+ };
149
+ if (approval && approval.argumentDigest !== attempt.argumentDigest)
150
+ return failure("stale_target", "approval arguments changed before restart");
151
+ await options.persistAttempt?.({ ...attempt, observedAt: now().toISOString(), state: "attempt_not_started" });
152
+ let apiKey;
153
+ try {
154
+ apiKey = await options.loadWriteApiKey();
155
+ }
156
+ catch (error) {
157
+ failReserved();
158
+ throw error;
159
+ }
160
+ if (!apiKey.trim()) {
161
+ failReserved();
162
+ return failure("invalid_response", "Unraid write credential is unavailable");
163
+ }
164
+ let client;
165
+ try {
166
+ client = createClient({ endpoint: options.endpoint, apiKey });
167
+ }
168
+ catch (error) {
169
+ failReserved();
170
+ throw error;
171
+ }
172
+ const persistTerminal = async (terminal) => {
173
+ try {
174
+ await options.persistAttempt?.(terminal);
175
+ return true;
176
+ }
177
+ catch (error) {
178
+ (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" } });
179
+ return false;
180
+ }
181
+ };
182
+ let acknowledged = false;
183
+ const performMutation = async (signal) => {
184
+ signal?.throwIfAborted();
185
+ if (routineReceipt && routineState.current === "reserved") {
186
+ transitionRoutine({ id: routineReceipt.id, expectedState: "reserved", state: "attempting" });
187
+ routineState.current = "attempting";
188
+ }
189
+ await options.persistAttempt?.({ ...attempt, observedAt: now().toISOString(), state: "attempting" });
190
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.unraid_restart_start", message: "approved Unraid restart started", meta: { containerId: fresh.id, containerName: fresh.name } });
191
+ let mutation = null;
192
+ try {
193
+ signal?.throwIfAborted();
194
+ mutation = signal
195
+ ? await client.mutate(exports.SANCTUARY_RESTART_MUTATION, { id: fresh.id }, signal)
196
+ : await client.mutate(exports.SANCTUARY_RESTART_MUTATION, { id: fresh.id });
197
+ acknowledged = acknowledgedIdentity(mutation, fresh);
198
+ if (!acknowledged)
199
+ throw new Error("restart response identity was invalid");
200
+ }
201
+ catch {
202
+ acknowledged = false;
203
+ }
204
+ if (acknowledged && mutation && routineReceipt && routineState.current === "attempting") {
205
+ transitionRoutine({ id: routineReceipt.id, expectedState: "attempting", state: "effect_acknowledged", effectReceipt: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(mutation)).digest("hex") });
206
+ routineState.current = "effect_acknowledged";
207
+ }
208
+ else if (routineReceipt && routineState.current === "attempting") {
209
+ transitionRoutine({ id: routineReceipt.id, expectedState: "attempting", state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
210
+ routineState.current = "indeterminate";
211
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: false });
212
+ }
213
+ };
214
+ if (routineReceipt && routine) {
215
+ const authority = routine;
216
+ const reservation = routineReceipt;
217
+ const event = reservation.requester?.kind === "owner_event" ? reservation.requester.event : null;
218
+ const runFinalAttempt = (signal) => options.withRoutineActionAttempt(reservation, async () => {
219
+ const reauthorize = async () => {
220
+ signal?.throwIfAborted();
221
+ const authorization = await currentRoutineAuthorization(authority);
222
+ if (authorization.profileVersion !== routineAuthorization.profileVersion)
223
+ throw new Error("routine relationship profile version changed");
224
+ signal?.throwIfAborted();
225
+ };
226
+ await reauthorize();
227
+ const listed = signal ? await options.listContainers(signal) : await options.listContainers();
228
+ signal?.throwIfAborted();
229
+ if (!listed.ok)
230
+ throw new Error(listed.error.message);
231
+ const final = exactTarget(listed, args.container);
232
+ if ("ok" in final)
233
+ throw new Error(final.error.message);
234
+ if (listed.data.truncated || final.degraded || final.id !== fresh.id || final.name !== fresh.name
235
+ || Object.keys(args).length !== 1 || args.container !== fresh.name)
236
+ throw new Error("routine action final container or arguments changed");
237
+ if (event && final.state !== "exited")
238
+ throw new Error("current health event target is no longer exactly stopped");
239
+ await reauthorize();
240
+ }, () => performMutation(signal));
241
+ try {
242
+ if (event) {
243
+ await (0, router_1.renewExternalEventClaim)(event.recordPath, { owner: event.claimOwner, expectedGeneration: event.generation }, (_record, signal) => runFinalAttempt(signal));
244
+ }
245
+ else {
246
+ await runFinalAttempt();
247
+ }
248
+ }
249
+ catch (error) {
250
+ if (error instanceof RoutineActionReceiptError || routineState.current !== "reserved")
251
+ throw error;
252
+ failReserved();
253
+ return failure("stale_target", error instanceof Error ? error.message : "routine action authority changed");
254
+ }
255
+ }
256
+ else if (approvalAuthority) {
257
+ if (!options.withApprovalPolicyLease)
258
+ return failure("invalid_response", "restart approval policy lease is unavailable");
259
+ let attemptStarted = false;
260
+ try {
261
+ await options.withApprovalPolicyLease(async () => {
262
+ const listed = await options.listContainers();
263
+ if (!listed.ok)
264
+ throw new Error(listed.error.message);
265
+ const final = exactTarget(listed, args.container);
266
+ if ("ok" in final)
267
+ throw new Error(final.error.message);
268
+ if (listed.data.truncated || final.degraded || final.id !== fresh.id || final.name !== fresh.name
269
+ || final.id !== approvalAuthority.target.id || final.name !== approvalAuthority.target.name
270
+ || Object.keys(args).length !== 1 || args.container !== fresh.name)
271
+ throw new Error("restart approval final container or arguments changed");
272
+ const authorization = await approvalAuthority.reauthorize();
273
+ if (authorization?.allowed !== true)
274
+ throw new Error(authorization?.allowed === false && typeof authorization.reason === "string" && authorization.reason.trim()
275
+ ? authorization.reason : "restart approval authorization is unavailable");
276
+ attemptStarted = true;
277
+ await performMutation();
278
+ });
279
+ }
280
+ catch (error) {
281
+ if (attemptStarted)
282
+ throw error;
283
+ return failure("stale_target", error instanceof Error ? error.message : "restart approval authority changed");
284
+ }
285
+ }
286
+ else {
287
+ await performMutation();
288
+ }
289
+ const startedAt = now().getTime();
290
+ let sawRestarting = false;
291
+ try {
292
+ do {
293
+ const observed = exactTarget(await options.listContainers(), args.container);
294
+ if (!("ok" in observed)) {
295
+ if (observed.id !== fresh.id) {
296
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: acknowledged });
297
+ if (routineReceipt && routineState.current)
298
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState.current, state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
299
+ return failure("ambiguous", "container identity changed after restart attempt");
300
+ }
301
+ sawRestarting ||= observed.state === "restarting";
302
+ if (observed.state === "running" && !observed.degraded && (acknowledged || sawRestarting)) {
303
+ if (!await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "succeeded", mutationAcknowledged: acknowledged, afterState: observed.state })) {
304
+ return failure("ambiguous", "restart succeeded but its terminal receipt could not be persisted; it was not retried");
305
+ }
306
+ if (routineReceipt && (routineState.current === "attempting" || routineState.current === "indeterminate")) {
307
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState.current, state: "effect_acknowledged", effectReceipt: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({ observation: "restarting", target: fresh.id })).digest("hex") });
308
+ routineState.current = "effect_acknowledged";
309
+ }
310
+ if (routineReceipt && routineState.current === "effect_acknowledged") {
311
+ transitionRoutine({ id: routineReceipt.id, expectedState: "effect_acknowledged", state: "verified", verifiedAfterState: observed.state, recoveryState: { state: "completed", compensation: "none" } });
312
+ routineState.current = null;
313
+ }
314
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.unraid_restart_end", message: "approved Unraid restart completed", meta: { containerId: fresh.id, observedRestart: true } });
315
+ // One routine receipt owns both the effect and its verified after-state.
316
+ return { ok: true, data: { container: { id: fresh.id, name: fresh.name }, beforeState: fresh.state, afterState: observed.state, observedRestart: true, degraded: false, ...(routineReceipt ? { actionRefs: [routineReceipt.id], verificationRefs: [routineReceipt.id] } : {}) } };
317
+ }
318
+ }
319
+ if (now().getTime() - startedAt >= observationTimeoutMs)
320
+ break;
321
+ await sleep(1_000);
322
+ } while (true);
323
+ }
324
+ catch (error) {
325
+ if (error instanceof RoutineActionReceiptError)
326
+ throw error;
327
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: acknowledged });
328
+ if (routineReceipt && routineState.current)
329
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState.current, state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
330
+ (0, runtime_1.emitNervesEvent)({ level: "error", component: "repertoire", event: "repertoire.unraid_restart_error", message: "approved Unraid restart observation failed", meta: { containerId: fresh.id, acknowledged } });
331
+ return failure("ambiguous", "restart was attempted but observation failed; it was not retried");
332
+ }
333
+ await persistTerminal({ ...attempt, observedAt: now().toISOString(), state: "attempted_or_indeterminate", mutationAcknowledged: acknowledged });
334
+ if (routineReceipt && routineState.current)
335
+ transitionRoutine({ id: routineReceipt.id, expectedState: routineState.current, state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } });
336
+ (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 } });
337
+ return failure("ambiguous", "restart was attempted but could not be proven; it was not retried");
338
+ };
339
+ }
@@ -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
+ }