@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.921

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 (717) 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 +5826 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2997 -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-butler-upgrade.mjs +1254 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1564 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  38. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  39. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  40. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  41. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  42. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  43. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  44. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  45. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  46. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  52. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  53. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  54. package/deploy/unraid/sanctuary.xml +30 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +250 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command-grants.js +93 -0
  59. package/dist/a2a/delegated-command.js +197 -0
  60. package/dist/a2a/delegation-stores.js +56 -0
  61. package/dist/a2a/did-resolution.js +93 -0
  62. package/dist/a2a/escalation-grants.js +84 -0
  63. package/dist/a2a/escalation-wiring.js +60 -0
  64. package/dist/a2a/identity.js +258 -0
  65. package/dist/a2a/inbound-share.js +110 -0
  66. package/dist/a2a/mission-result-wire.js +196 -0
  67. package/dist/a2a/onboarding.js +133 -0
  68. package/dist/a2a/operator-trust.js +382 -0
  69. package/dist/a2a/outbox-client.js +57 -0
  70. package/dist/a2a/outbox-store.js +188 -0
  71. package/dist/a2a/outbox-wire.js +95 -0
  72. package/dist/a2a/pin-store.js +132 -0
  73. package/dist/a2a/replay-grant-holders.js +33 -0
  74. package/dist/a2a/replay-harness.js +188 -0
  75. package/dist/a2a/resolution-proof.js +53 -0
  76. package/dist/a2a/sealed-chat.js +113 -0
  77. package/dist/a2a/seen-ledger.js +120 -0
  78. package/dist/a2a/server.js +771 -0
  79. package/dist/a2a/task-store.js +69 -0
  80. package/dist/a2a/transport.js +45 -0
  81. package/dist/a2a/trust-commands.js +203 -0
  82. package/dist/a2a/trusted-files.js +185 -0
  83. package/dist/a2a/types.js +3 -0
  84. package/dist/arc/attention-types.js +8 -0
  85. package/dist/arc/cares.js +360 -0
  86. package/dist/arc/episodes.js +118 -0
  87. package/dist/arc/evolution.js +490 -0
  88. package/dist/arc/flight-recorder.js +1034 -0
  89. package/dist/arc/intentions.js +134 -0
  90. package/dist/arc/json-store.js +117 -0
  91. package/dist/arc/obligations.js +386 -0
  92. package/dist/arc/packets.js +336 -0
  93. package/dist/arc/presence.js +185 -0
  94. package/dist/arc/task-lifecycle.js +57 -0
  95. package/dist/commerce/store.js +755 -0
  96. package/dist/commerce/types.js +3 -0
  97. package/dist/heart/active-work.js +798 -40
  98. package/dist/heart/agent-entry.js +252 -3
  99. package/dist/heart/approval-files.js +113 -0
  100. package/dist/heart/approval-store.js +960 -0
  101. package/dist/heart/attachments/image-normalize.js +194 -0
  102. package/dist/heart/attachments/materialize.js +97 -0
  103. package/dist/heart/attachments/originals.js +88 -0
  104. package/dist/heart/attachments/render.js +29 -0
  105. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  106. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  107. package/dist/heart/attachments/sources/index.js +18 -0
  108. package/dist/heart/attachments/sources/telegram.js +71 -0
  109. package/dist/heart/attachments/store.js +132 -0
  110. package/dist/heart/attachments/types.js +93 -0
  111. package/dist/heart/auth/auth-flow.js +495 -0
  112. package/dist/heart/autonomy-budget.js +478 -0
  113. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  114. package/dist/heart/awaiting/await-alert.js +152 -0
  115. package/dist/heart/awaiting/await-expiry.js +143 -0
  116. package/dist/heart/awaiting/await-loader.js +91 -0
  117. package/dist/heart/awaiting/await-parser.js +152 -0
  118. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  119. package/dist/heart/awaiting/await-scheduler.js +391 -0
  120. package/dist/heart/background-operations.js +281 -0
  121. package/dist/heart/bluebubbles-host-account.js +78 -0
  122. package/dist/heart/bridges/manager.js +137 -17
  123. package/dist/heart/bridges/store.js +14 -2
  124. package/dist/heart/bundle-state.js +168 -0
  125. package/dist/heart/commitments.js +44 -18
  126. package/dist/heart/config-registry.js +331 -0
  127. package/dist/heart/config.js +174 -131
  128. package/dist/heart/context-loss-gauntlet.js +387 -0
  129. package/dist/heart/context-loss-sentinel.js +1159 -0
  130. package/dist/heart/core.js +2364 -578
  131. package/dist/heart/cross-chat-delivery.js +9 -22
  132. package/dist/heart/daemon/agent-config-check.js +451 -0
  133. package/dist/heart/daemon/agent-discovery.js +283 -3
  134. package/dist/heart/daemon/agent-home.js +319 -0
  135. package/dist/heart/daemon/agent-service.js +542 -0
  136. package/dist/heart/daemon/agentic-repair.js +547 -0
  137. package/dist/heart/daemon/await-private-wake.js +59 -0
  138. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  139. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  140. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  141. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  142. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  143. package/dist/heart/daemon/cadence.js +180 -0
  144. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  145. package/dist/heart/daemon/cli-defaults.js +876 -0
  146. package/dist/heart/daemon/cli-desk.js +322 -0
  147. package/dist/heart/daemon/cli-exec.js +9199 -0
  148. package/dist/heart/daemon/cli-help.js +735 -0
  149. package/dist/heart/daemon/cli-parse.js +3211 -0
  150. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  151. package/dist/heart/daemon/cli-render.js +819 -0
  152. package/dist/heart/daemon/cli-types.js +8 -0
  153. package/dist/heart/daemon/connect-bay.js +323 -0
  154. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  155. package/dist/heart/daemon/container-healthcheck.js +112 -0
  156. package/dist/heart/daemon/container-runtime.js +97 -0
  157. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  158. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  159. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  160. package/dist/heart/daemon/daemon-cli.js +29 -2350
  161. package/dist/heart/daemon/daemon-entry.js +953 -11
  162. package/dist/heart/daemon/daemon-health.js +186 -0
  163. package/dist/heart/daemon/daemon-rollup.js +57 -0
  164. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  165. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  166. package/dist/heart/daemon/daemon.js +2084 -105
  167. package/dist/heart/daemon/dns-workflow.js +394 -0
  168. package/dist/heart/daemon/doctor-types.js +8 -0
  169. package/dist/heart/daemon/doctor.js +1766 -0
  170. package/dist/heart/daemon/freshness.js +345 -0
  171. package/dist/heart/daemon/habit-private-wake.js +61 -0
  172. package/dist/heart/daemon/health-monitor.js +154 -11
  173. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  174. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  175. package/dist/heart/daemon/http-health-probe.js +80 -0
  176. package/dist/heart/daemon/human-command-screens.js +234 -0
  177. package/dist/heart/daemon/human-readiness.js +114 -0
  178. package/dist/heart/daemon/inner-status.js +78 -0
  179. package/dist/heart/daemon/interactive-repair.js +394 -0
  180. package/dist/heart/daemon/launchd.js +37 -8
  181. package/dist/heart/daemon/log-tailer.js +79 -10
  182. package/dist/heart/daemon/logs-prune.js +132 -0
  183. package/dist/heart/daemon/mcp-canary.js +524 -0
  184. package/dist/heart/daemon/message-router.js +65 -5
  185. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  186. package/dist/heart/daemon/os-cron-deps.js +135 -0
  187. package/dist/heart/daemon/os-cron.js +22 -14
  188. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  189. package/dist/heart/daemon/ouro-entry.js +5 -2
  190. package/dist/heart/daemon/plugin-cli.js +432 -0
  191. package/dist/heart/daemon/process-manager.js +760 -61
  192. package/dist/heart/daemon/provider-discovery.js +137 -0
  193. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  194. package/dist/heart/daemon/prunable-bundle.js +144 -0
  195. package/dist/heart/daemon/pulse.js +511 -0
  196. package/dist/heart/daemon/readiness-repair.js +365 -0
  197. package/dist/heart/daemon/run-hooks.js +2 -0
  198. package/dist/heart/daemon/runtime-logging.js +47 -14
  199. package/dist/heart/daemon/runtime-metadata.js +2 -30
  200. package/dist/heart/daemon/runtime-mode.js +13 -2
  201. package/dist/heart/daemon/safe-mode.js +161 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  206. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  207. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  208. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  209. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  210. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  211. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  212. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  213. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  214. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  215. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  216. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  217. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  219. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  220. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  225. package/dist/heart/daemon/sense-manager.js +733 -48
  226. package/dist/heart/daemon/session-id-resolver.js +131 -0
  227. package/dist/heart/daemon/skill-management-installer.js +1 -1
  228. package/dist/heart/daemon/socket-client.js +180 -12
  229. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  230. package/dist/heart/daemon/startup-tui.js +339 -0
  231. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  232. package/dist/heart/daemon/task-scheduler.js +117 -39
  233. package/dist/heart/daemon/terminal-ui.js +503 -0
  234. package/dist/heart/daemon/thoughts.js +138 -54
  235. package/dist/heart/daemon/up-progress.js +366 -0
  236. package/dist/heart/daemon/vault-items.js +56 -0
  237. package/dist/heart/delegation.js +1 -4
  238. package/dist/heart/external-events/router.js +1516 -0
  239. package/dist/heart/failure-reports.js +336 -0
  240. package/dist/heart/file-lock.js +109 -0
  241. package/dist/heart/frontend-approval-runtime.js +506 -0
  242. package/dist/heart/frontend-journal.js +215 -0
  243. package/dist/heart/frontend-session-service.js +237 -0
  244. package/dist/heart/frontend-socket-client.js +164 -0
  245. package/dist/heart/frontend-socket.js +400 -0
  246. package/dist/heart/habits/habit-cancel.js +810 -0
  247. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  248. package/dist/heart/habits/habit-migration.js +194 -0
  249. package/dist/heart/habits/habit-parser.js +278 -0
  250. package/dist/heart/habits/habit-runtime-state.js +93 -0
  251. package/dist/heart/habits/habit-scheduler.js +653 -0
  252. package/dist/heart/habits/habit-session-summary.js +318 -0
  253. package/dist/heart/habits/habit-session.js +636 -0
  254. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  255. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  256. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  257. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  258. package/dist/heart/identity.js +230 -59
  259. package/dist/heart/kept-notes.js +289 -0
  260. package/dist/heart/kicks.js +1 -1
  261. package/dist/heart/machine-identity.js +175 -0
  262. package/dist/heart/mail-import-discovery.js +356 -0
  263. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  264. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  265. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  266. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  267. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  268. package/dist/heart/mailbox/mailbox-http.js +99 -0
  269. package/dist/heart/mailbox/mailbox-read.js +39 -0
  270. package/dist/heart/mailbox/mailbox-types.js +27 -0
  271. package/dist/heart/mailbox/mailbox-view.js +197 -0
  272. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  273. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  274. package/dist/heart/mailbox/readers/mail.js +375 -0
  275. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  276. package/dist/heart/mailbox/readers/sessions.js +231 -0
  277. package/dist/heart/mailbox/readers/shared.js +111 -0
  278. package/dist/heart/mcp/mcp-server.js +696 -0
  279. package/dist/heart/migrate-config.js +100 -0
  280. package/dist/heart/model-capabilities.js +83 -16
  281. package/dist/heart/orientation-frame.js +345 -0
  282. package/dist/heart/platform.js +81 -0
  283. package/dist/heart/primitives.js +1 -1
  284. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  285. package/dist/heart/private-runtime/index.js +18 -0
  286. package/dist/heart/private-runtime/ledger.js +221 -0
  287. package/dist/heart/private-runtime/policy.js +260 -0
  288. package/dist/heart/private-runtime/types.js +2 -0
  289. package/dist/heart/progress-story.js +1 -1
  290. package/dist/heart/provider-attempt.js +137 -0
  291. package/dist/heart/provider-binding-resolver.js +273 -0
  292. package/dist/heart/provider-credentials.js +449 -0
  293. package/dist/heart/provider-failover.js +311 -0
  294. package/dist/heart/provider-models.js +96 -0
  295. package/dist/heart/provider-ping.js +265 -0
  296. package/dist/heart/provider-readiness-cache.js +119 -0
  297. package/dist/heart/provider-visibility.js +188 -0
  298. package/dist/heart/providers/anthropic-token.js +131 -0
  299. package/dist/heart/providers/anthropic.js +173 -60
  300. package/dist/heart/providers/azure.js +23 -11
  301. package/dist/heart/providers/error-classification.js +127 -0
  302. package/dist/heart/providers/github-copilot.js +38 -39
  303. package/dist/heart/providers/minimax-vlm.js +189 -0
  304. package/dist/heart/providers/minimax.js +26 -8
  305. package/dist/heart/providers/openai-codex-token.js +349 -0
  306. package/dist/heart/providers/openai-codex.js +55 -40
  307. package/dist/heart/providers/openai-compatible.js +177 -0
  308. package/dist/heart/reply-style.js +52 -0
  309. package/dist/heart/run-ledger.js +247 -0
  310. package/dist/heart/runtime-capability-check.js +170 -0
  311. package/dist/heart/runtime-credentials.js +607 -0
  312. package/dist/heart/runtime-cwd.js +87 -0
  313. package/dist/heart/sense-truth.js +24 -4
  314. package/dist/heart/session-activity.js +92 -24
  315. package/dist/heart/session-events.js +1504 -0
  316. package/dist/heart/session-playback-cli-main.js +5 -0
  317. package/dist/heart/session-playback-cli.js +36 -0
  318. package/dist/heart/session-playback.js +231 -0
  319. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  320. package/dist/heart/session-redaction-repair.js +552 -0
  321. package/dist/heart/session-stats-cli-main.js +5 -0
  322. package/dist/heart/session-stats.js +183 -0
  323. package/dist/heart/session-transcript.js +133 -0
  324. package/dist/heart/shelf-claims.js +78 -0
  325. package/dist/heart/shepherd-config.js +113 -0
  326. package/dist/heart/source-grounding.js +297 -0
  327. package/dist/heart/start-of-turn-packet.js +372 -0
  328. package/dist/heart/steward-policy.js +656 -0
  329. package/dist/heart/streaming.js +609 -207
  330. package/dist/heart/structured-output.js +196 -0
  331. package/dist/heart/sync-classification.js +176 -0
  332. package/dist/heart/sync-health.js +152 -0
  333. package/dist/heart/sync.js +726 -0
  334. package/dist/heart/target-resolution.js +11 -7
  335. package/dist/heart/tempo.js +93 -0
  336. package/dist/heart/temporal-view.js +41 -0
  337. package/dist/heart/timeouts.js +101 -0
  338. package/dist/heart/tool-activity-callbacks.js +59 -0
  339. package/dist/heart/tool-approval.js +382 -0
  340. package/dist/heart/tool-description.js +155 -0
  341. package/dist/heart/tool-friction.js +55 -0
  342. package/dist/heart/tool-loop.js +206 -0
  343. package/dist/heart/turn-context.js +496 -0
  344. package/dist/heart/turn-execution-lease.js +30 -0
  345. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  346. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  347. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  348. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  349. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  350. package/dist/heart/versioning/release-sources.js +173 -0
  351. package/dist/heart/versioning/self-update-defaults.js +294 -0
  352. package/dist/heart/versioning/self-update.js +196 -0
  353. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  354. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  355. package/dist/heart/versioning/update-hooks.js +154 -0
  356. package/dist/heart/versioning/update-state.js +126 -0
  357. package/dist/heart/versioning/updater-launchd.js +150 -0
  358. package/dist/heart/versioning/version-intent.js +114 -0
  359. package/dist/heart/work-card.js +380 -0
  360. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  361. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  362. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  363. package/dist/mailbox-ui/index.html +16 -0
  364. package/dist/mailroom/attention.js +167 -0
  365. package/dist/mailroom/autonomy.js +209 -0
  366. package/dist/mailroom/blob-store.js +889 -0
  367. package/dist/mailroom/body-cache.js +61 -0
  368. package/dist/mailroom/cache-sync-cli.js +58 -0
  369. package/dist/mailroom/core.js +803 -0
  370. package/dist/mailroom/entry.js +160 -0
  371. package/dist/mailroom/file-store.js +568 -0
  372. package/dist/mailroom/hosted-cache-sync.js +384 -0
  373. package/dist/mailroom/mbox-import.js +393 -0
  374. package/dist/mailroom/migration.js +164 -0
  375. package/dist/mailroom/outbound.js +380 -0
  376. package/dist/mailroom/policy.js +263 -0
  377. package/dist/mailroom/reader.js +292 -0
  378. package/dist/mailroom/search-cache.js +513 -0
  379. package/dist/mailroom/search-relevance.js +319 -0
  380. package/dist/mailroom/smtp-ingress.js +176 -0
  381. package/dist/mailroom/source-state.js +176 -0
  382. package/dist/mailroom/thread.js +109 -0
  383. package/dist/mailroom/travel-extract.js +89 -0
  384. package/dist/mind/bundle-manifest.js +24 -2
  385. package/dist/mind/context.js +307 -139
  386. package/dist/mind/desk-section.js +362 -0
  387. package/dist/mind/diary-integrity.js +60 -0
  388. package/dist/mind/{memory.js → diary.js} +68 -77
  389. package/dist/mind/embedding-provider.js +60 -0
  390. package/dist/mind/file-state.js +179 -0
  391. package/dist/mind/friend-link-codes.js +209 -0
  392. package/dist/mind/friend-merge.js +330 -0
  393. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  394. package/dist/mind/obligation-steering.js +199 -3
  395. package/dist/mind/pending.js +36 -10
  396. package/dist/mind/prompt-budget.js +479 -0
  397. package/dist/mind/prompt-refresh.js +3 -2
  398. package/dist/mind/prompt.js +1085 -198
  399. package/dist/mind/provenance-trust.js +26 -0
  400. package/dist/mind/record-paths.js +312 -0
  401. package/dist/mind/scrutiny.js +173 -0
  402. package/dist/mind/session-transaction.js +564 -0
  403. package/dist/nerves/cli-logging.js +7 -1
  404. package/dist/nerves/coverage/audit-rules.js +15 -6
  405. package/dist/nerves/coverage/audit.js +28 -2
  406. package/dist/nerves/coverage/cli.js +1 -1
  407. package/dist/nerves/coverage/contract.js +5 -5
  408. package/dist/nerves/coverage/file-completeness.js +139 -5
  409. package/dist/nerves/coverage/run-artifacts.js +55 -35
  410. package/dist/nerves/coverage/source-scanner.js +4 -4
  411. package/dist/nerves/event-buffer.js +111 -0
  412. package/dist/nerves/index.js +293 -9
  413. package/dist/nerves/observation.js +20 -0
  414. package/dist/nerves/redact.js +79 -0
  415. package/dist/nerves/review/cli-main.js +5 -0
  416. package/dist/nerves/review/cli.js +156 -0
  417. package/dist/nerves/review/core.js +159 -0
  418. package/dist/nerves/runtime.js +17 -1
  419. package/dist/repertoire/ado-client.js +15 -56
  420. package/dist/repertoire/ado-semantic.js +16 -10
  421. package/dist/repertoire/api-client.js +97 -0
  422. package/dist/repertoire/bitwarden-store.js +1201 -0
  423. package/dist/repertoire/bundle-templates.js +71 -0
  424. package/dist/repertoire/bw-installer.js +231 -0
  425. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  426. package/dist/repertoire/coding/context-pack.js +331 -0
  427. package/dist/repertoire/coding/feedback.js +174 -32
  428. package/dist/repertoire/coding/index.js +15 -3
  429. package/dist/repertoire/coding/manager.js +159 -10
  430. package/dist/repertoire/coding/spawner.js +40 -11
  431. package/dist/repertoire/coding/tools.js +182 -18
  432. package/dist/repertoire/coding/workbench-client.js +272 -0
  433. package/dist/repertoire/coding/workbench-manager.js +346 -0
  434. package/dist/repertoire/commerce-errors.js +109 -0
  435. package/dist/repertoire/commerce-self-test.js +156 -0
  436. package/dist/repertoire/credential-access.js +183 -0
  437. package/dist/repertoire/desk/classifier.js +362 -0
  438. package/dist/repertoire/duffel-client.js +185 -0
  439. package/dist/repertoire/github-client.js +14 -55
  440. package/dist/repertoire/graph-client.js +11 -52
  441. package/dist/repertoire/guardrails.js +968 -20
  442. package/dist/repertoire/house-sweep.js +469 -0
  443. package/dist/repertoire/mcp-client.js +58 -5
  444. package/dist/repertoire/mcp-manager.js +427 -139
  445. package/dist/repertoire/mcp-tools.js +132 -0
  446. package/dist/repertoire/mcp-write-guard.js +46 -0
  447. package/dist/repertoire/plugin-mcp.js +175 -0
  448. package/dist/repertoire/plugins.js +253 -0
  449. package/dist/repertoire/relationship-authorization.js +322 -0
  450. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  451. package/dist/repertoire/shell-sessions.js +134 -0
  452. package/dist/repertoire/skills.js +48 -4
  453. package/dist/repertoire/stripe-client.js +131 -0
  454. package/dist/repertoire/tool-arguments.js +182 -0
  455. package/dist/repertoire/tool-results.js +29 -0
  456. package/dist/repertoire/tools-a2a.js +699 -0
  457. package/dist/repertoire/tools-attachments.js +322 -0
  458. package/dist/repertoire/tools-awaiting.js +872 -0
  459. package/dist/repertoire/tools-base.js +83 -1168
  460. package/dist/repertoire/tools-bluebubbles.js +2 -0
  461. package/dist/repertoire/tools-bridge.js +144 -0
  462. package/dist/repertoire/tools-bundle.js +995 -0
  463. package/dist/repertoire/tools-commerce.js +253 -0
  464. package/dist/repertoire/tools-config.js +186 -0
  465. package/dist/repertoire/tools-continuity.js +575 -0
  466. package/dist/repertoire/tools-credential.js +383 -0
  467. package/dist/repertoire/tools-escalation.js +84 -0
  468. package/dist/repertoire/tools-evolution.js +527 -0
  469. package/dist/repertoire/tools-files.js +344 -0
  470. package/dist/repertoire/tools-flight.js +290 -0
  471. package/dist/repertoire/tools-flow.js +119 -0
  472. package/dist/repertoire/tools-friend-link.js +57 -0
  473. package/dist/repertoire/tools-github.js +3 -8
  474. package/dist/repertoire/tools-habits.js +103 -0
  475. package/dist/repertoire/tools-house-care.js +174 -0
  476. package/dist/repertoire/tools-mail.js +1828 -0
  477. package/dist/repertoire/tools-notes.js +496 -0
  478. package/dist/repertoire/tools-obligations.js +182 -0
  479. package/dist/repertoire/tools-orientation.js +31 -0
  480. package/dist/repertoire/tools-record.js +482 -0
  481. package/dist/repertoire/tools-rsvp.js +139 -0
  482. package/dist/repertoire/tools-runtime.js +238 -0
  483. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  484. package/dist/repertoire/tools-session.js +1133 -0
  485. package/dist/repertoire/tools-shell.js +149 -0
  486. package/dist/repertoire/tools-shepherd.js +262 -0
  487. package/dist/repertoire/tools-steward-policy.js +147 -0
  488. package/dist/repertoire/tools-stripe.js +224 -0
  489. package/dist/repertoire/tools-surface.js +369 -0
  490. package/dist/repertoire/tools-teams.js +12 -39
  491. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  492. package/dist/repertoire/tools-travel.js +125 -0
  493. package/dist/repertoire/tools-trip.js +982 -0
  494. package/dist/repertoire/tools-unraid.js +556 -0
  495. package/dist/repertoire/tools-user-profile.js +146 -0
  496. package/dist/repertoire/tools-vault.js +40 -0
  497. package/dist/repertoire/tools-voice-local.js +198 -0
  498. package/dist/repertoire/tools-voice.js +145 -0
  499. package/dist/repertoire/tools.js +514 -156
  500. package/dist/repertoire/travel-api-client.js +360 -0
  501. package/dist/repertoire/unraid-client.js +155 -0
  502. package/dist/repertoire/unraid-restart.js +339 -0
  503. package/dist/repertoire/user-profile.js +131 -0
  504. package/dist/repertoire/vault-setup.js +246 -0
  505. package/dist/repertoire/vault-unlock.js +686 -0
  506. package/dist/rsvp/aisleplanner-client.js +354 -0
  507. package/dist/rsvp/cli.js +936 -0
  508. package/dist/rsvp/config.js +327 -0
  509. package/dist/rsvp/cutover.js +433 -0
  510. package/dist/rsvp/diagnostics.js +232 -0
  511. package/dist/rsvp/diff-renderer.js +176 -0
  512. package/dist/rsvp/habit-policy.js +110 -0
  513. package/dist/rsvp/habit-stage.js +123 -0
  514. package/dist/rsvp/incident-bundle.js +97 -0
  515. package/dist/rsvp/migration.js +204 -0
  516. package/dist/rsvp/native-habit-runner.js +630 -0
  517. package/dist/rsvp/outbound-state.js +628 -0
  518. package/dist/rsvp/query.js +118 -0
  519. package/dist/rsvp/replay.js +233 -0
  520. package/dist/rsvp/snapshot.js +232 -0
  521. package/dist/rsvp/spend-ledger.js +175 -0
  522. package/dist/scripts/claude-code-hook.js +41 -0
  523. package/dist/scripts/claude-code-stop-hook.js +47 -0
  524. package/dist/senses/a2a-entry.js +132 -0
  525. package/dist/senses/acp-server.js +386 -0
  526. package/dist/senses/attention-queue.js +186 -0
  527. package/dist/senses/await-turn-message.js +65 -0
  528. package/dist/senses/bluebubbles/active-turns.js +216 -0
  529. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  530. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  531. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +379 -41
  532. package/dist/senses/bluebubbles/context-packet.js +207 -0
  533. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  534. package/dist/senses/bluebubbles/entry.js +90 -0
  535. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  536. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  537. package/dist/senses/bluebubbles/index.js +3878 -0
  538. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  539. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  540. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  541. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  542. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  543. package/dist/senses/bluebubbles/processed-log.js +133 -0
  544. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  545. package/dist/senses/bluebubbles/replay.js +284 -0
  546. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  547. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  548. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  549. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  550. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  551. package/dist/senses/cli/bracketed-paste.js +82 -0
  552. package/dist/senses/cli/image-paste.js +287 -0
  553. package/dist/senses/cli/image-ref-navigation.js +75 -0
  554. package/dist/senses/cli/ink-app.js +156 -0
  555. package/dist/senses/cli/inline-diff.js +64 -0
  556. package/dist/senses/cli/input-keys.js +174 -0
  557. package/dist/senses/cli/kill-ring.js +86 -0
  558. package/dist/senses/cli/message-list.js +51 -0
  559. package/dist/senses/cli/ouro-tui.js +607 -0
  560. package/dist/senses/cli/spinner-imperative.js +135 -0
  561. package/dist/senses/cli/spinner.js +101 -0
  562. package/dist/senses/cli/status-line.js +60 -0
  563. package/dist/senses/cli/streaming-markdown.js +526 -0
  564. package/dist/senses/cli/tool-display.js +85 -0
  565. package/dist/senses/cli/tool-render.js +85 -0
  566. package/dist/senses/cli/tui-store.js +241 -0
  567. package/dist/senses/cli/virtual-list.js +35 -0
  568. package/dist/senses/cli-entry.js +60 -8
  569. package/dist/senses/cli.js +601 -304
  570. package/dist/senses/commands.js +66 -3
  571. package/dist/senses/context-packet-ledger.js +371 -0
  572. package/dist/senses/context-packets.js +154 -0
  573. package/dist/senses/habit-lifecycle-guard.js +24 -0
  574. package/dist/senses/habit-turn-message.js +160 -0
  575. package/dist/senses/ingress-evidence.js +2 -0
  576. package/dist/senses/mail-entry.js +66 -0
  577. package/dist/senses/mail.js +524 -0
  578. package/dist/senses/pipeline.js +1158 -204
  579. package/dist/senses/private-runtime-worker.js +859 -0
  580. package/dist/senses/private-runtime.js +1627 -0
  581. package/dist/senses/proactive-content-guard.js +51 -0
  582. package/dist/senses/root-host-approval-port.js +345 -0
  583. package/dist/senses/root-host-approval-runtime.js +393 -0
  584. package/dist/senses/sanctuary-authority-resident.js +102 -0
  585. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  586. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  587. package/dist/senses/sanctuary-grounding.js +118 -0
  588. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  589. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  590. package/dist/senses/sanctuary-health-runner.js +104 -0
  591. package/dist/senses/sanctuary-health.js +422 -0
  592. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  593. package/dist/senses/sanctuary-interactive-control.js +410 -0
  594. package/dist/senses/sanctuary-media-catalog-contract.js +259 -0
  595. package/dist/senses/sanctuary-media-optimization.js +514 -0
  596. package/dist/senses/sanctuary-runtime.js +369 -0
  597. package/dist/senses/sanctuary-sab.js +85 -0
  598. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  599. package/dist/senses/shared-turn.js +793 -0
  600. package/dist/senses/shepherd/client.js +196 -0
  601. package/dist/senses/shepherd/cmux.js +352 -0
  602. package/dist/senses/shepherd/herdr.js +315 -0
  603. package/dist/senses/shepherd/host.js +14 -0
  604. package/dist/senses/shepherd/judge.js +137 -0
  605. package/dist/senses/shepherd/owner-notice.js +251 -0
  606. package/dist/senses/shepherd/redact.js +66 -0
  607. package/dist/senses/shepherd/returns.js +79 -0
  608. package/dist/senses/shepherd/sense.js +310 -0
  609. package/dist/senses/shepherd/terminal-process.js +99 -0
  610. package/dist/senses/shepherd-entry.js +78 -0
  611. package/dist/senses/surface-tool.js +109 -0
  612. package/dist/senses/teams-entry.js +68 -8
  613. package/dist/senses/teams.js +598 -233
  614. package/dist/senses/telegram-admission.js +718 -0
  615. package/dist/senses/telegram-approval-runtime.js +793 -0
  616. package/dist/senses/telegram-attachments.js +186 -0
  617. package/dist/senses/telegram-audit-ledger.js +220 -0
  618. package/dist/senses/telegram-authority-transport.js +231 -0
  619. package/dist/senses/telegram-client.js +1749 -0
  620. package/dist/senses/telegram-effect-adapter.js +900 -0
  621. package/dist/senses/telegram-entry.js +83 -0
  622. package/dist/senses/telegram-handoff.js +80 -0
  623. package/dist/senses/telegram.js +2405 -0
  624. package/dist/senses/trust-gate.js +104 -9
  625. package/dist/senses/voice/audio-playback.js +237 -0
  626. package/dist/senses/voice/audio-routing.js +119 -0
  627. package/dist/senses/voice/call-auth.js +250 -0
  628. package/dist/senses/voice/elevenlabs.js +202 -0
  629. package/dist/senses/voice/floor-control.js +431 -0
  630. package/dist/senses/voice/floor-controller.js +115 -0
  631. package/dist/senses/voice/golden-path.js +116 -0
  632. package/dist/senses/voice/index.js +29 -0
  633. package/dist/senses/voice/local-audio-control.js +344 -0
  634. package/dist/senses/voice/local-audio-devices.js +516 -0
  635. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  636. package/dist/senses/voice/local-audio-identity.js +103 -0
  637. package/dist/senses/voice/local-audio-join.js +325 -0
  638. package/dist/senses/voice/local-audio-mute.js +199 -0
  639. package/dist/senses/voice/local-audio-notify.js +121 -0
  640. package/dist/senses/voice/local-audio-prompts.js +116 -0
  641. package/dist/senses/voice/local-audio-transport.js +427 -0
  642. package/dist/senses/voice/local-audio.js +281 -0
  643. package/dist/senses/voice/local-media-stream.js +145 -0
  644. package/dist/senses/voice/meeting.js +113 -0
  645. package/dist/senses/voice/outbound.js +190 -0
  646. package/dist/senses/voice/phone.js +33 -0
  647. package/dist/senses/voice/playback.js +139 -0
  648. package/dist/senses/voice/process-guards.js +51 -0
  649. package/dist/senses/voice/realtime-eval.js +496 -0
  650. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  651. package/dist/senses/voice/realtime-trace.js +531 -0
  652. package/dist/senses/voice/transcript.js +70 -0
  653. package/dist/senses/voice/turn.js +191 -0
  654. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  655. package/dist/senses/voice/twilio-phone.js +5454 -0
  656. package/dist/senses/voice/types.js +2 -0
  657. package/dist/senses/voice/whisper.js +161 -0
  658. package/dist/senses/voice-entry.js +83 -0
  659. package/dist/senses/voice-realtime-eval-command.js +99 -0
  660. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  661. package/dist/senses/voice-twilio-entry.js +87 -0
  662. package/dist/trips/core.js +138 -0
  663. package/dist/trips/store.js +265 -0
  664. package/dist/util/frontmatter.js +69 -0
  665. package/npm-shrinkwrap.json +8100 -0
  666. package/package.json +74 -13
  667. package/skills/agent-commerce.md +113 -0
  668. package/skills/browser-navigation.md +117 -0
  669. package/skills/commerce-setup-guide.md +116 -0
  670. package/skills/commerce-setup.md +84 -0
  671. package/skills/configure-dev-tools.md +99 -0
  672. package/skills/travel-planning.md +138 -0
  673. package/dist/heart/daemon/auth-flow.js +0 -430
  674. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  675. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  676. package/dist/heart/daemon/update-hooks.js +0 -138
  677. package/dist/heart/obligations.js +0 -191
  678. package/dist/heart/safe-workspace.js +0 -362
  679. package/dist/heart/session-recall.js +0 -116
  680. package/dist/mind/friends/channel.js +0 -84
  681. package/dist/mind/friends/group-context.js +0 -144
  682. package/dist/mind/friends/resolver.js +0 -84
  683. package/dist/mind/friends/store-file.js +0 -190
  684. package/dist/mind/friends/store.js +0 -4
  685. package/dist/mind/friends/tokens.js +0 -26
  686. package/dist/mind/friends/trust-explanation.js +0 -74
  687. package/dist/mind/friends/types.js +0 -29
  688. package/dist/repertoire/tasks/board.js +0 -134
  689. package/dist/repertoire/tasks/index.js +0 -224
  690. package/dist/repertoire/tasks/lifecycle.js +0 -80
  691. package/dist/repertoire/tasks/middleware.js +0 -65
  692. package/dist/repertoire/tasks/parser.js +0 -173
  693. package/dist/repertoire/tasks/scanner.js +0 -132
  694. package/dist/repertoire/tasks/transitions.js +0 -144
  695. package/dist/senses/bluebubbles-entry.js +0 -13
  696. package/dist/senses/bluebubbles.js +0 -1181
  697. package/dist/senses/debug-activity.js +0 -154
  698. package/dist/senses/inner-dialog-worker.js +0 -90
  699. package/dist/senses/inner-dialog.js +0 -525
  700. package/subagents/README.md +0 -7
  701. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  702. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  703. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  704. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  705. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  706. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  707. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  708. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  709. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  710. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  711. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  712. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  713. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  714. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  715. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  716. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  717. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.routineActionRequester = routineActionRequester;
37
+ exports.authorizeRestartApprovalRequester = authorizeRestartApprovalRequester;
38
+ exports.authorizeRoutineActionRequester = authorizeRoutineActionRequester;
39
+ exports.renderRelationshipPreferences = renderRelationshipPreferences;
40
+ exports.withRelationshipPreference = withRelationshipPreference;
41
+ exports.loadRelationshipCapabilityRegistry = loadRelationshipCapabilityRegistry;
42
+ exports.relationshipSubjectFromFriend = relationshipSubjectFromFriend;
43
+ exports.createRelationshipAuthorizationEvaluator = createRelationshipAuthorizationEvaluator;
44
+ exports.resolveProfileScopedRelationshipAuthorization = resolveProfileScopedRelationshipAuthorization;
45
+ exports.authorizeRelationshipAccess = authorizeRelationshipAccess;
46
+ const fs = __importStar(require("node:fs"));
47
+ const path = __importStar(require("node:path"));
48
+ const node_crypto_1 = require("node:crypto");
49
+ const node_util_1 = require("node:util");
50
+ const router_1 = require("../heart/external-events/router");
51
+ const runtime_1 = require("../nerves/runtime");
52
+ function routineActionRequester(ctx, eventTarget) {
53
+ const relationship = ctx?.relationshipAuthorization;
54
+ if (!relationship)
55
+ return null;
56
+ if (ctx?.currentExternalEvent) {
57
+ if (!eventTarget || relationship.profileId !== "sanctuary-event")
58
+ return null;
59
+ const events = [ctx.currentExternalEvent, ...(ctx.currentExternalEvent.relatedEvents ?? [])].filter((event) => event.schemaVersion === 1 && event.source === "sanctuary-health" && event.eventId === `container:${eventTarget.target.id}:availability`);
60
+ if (events.length !== 1)
61
+ return null;
62
+ const event = events[0];
63
+ return {
64
+ kind: "owner_event", friendId: eventTarget.friendId, profileId: relationship.profileId,
65
+ event: { schemaVersion: 1, recordPath: event.recordPath, agent: event.agent, source: event.source, eventId: event.eventId, generation: event.generation, observationRevision: event.observationRevision, claimOwner: event.claimOwner },
66
+ target: { ...eventTarget.target },
67
+ };
68
+ }
69
+ const actor = relationship.actor;
70
+ const session = ctx?.currentSession;
71
+ if (!actor || !session || session.channel !== "telegram" || session.friendId !== actor.friendId
72
+ || [actor.friendId, actor.sessionEventId, relationship.requestId, session.key].some((value) => typeof value !== "string" || !value.trim()))
73
+ return null;
74
+ const kind = actor.trustLevel === "family" && relationship.profileId === "sanctuary-owner" ? "owner"
75
+ : actor.trustLevel === "friend" && relationship.profileId === "sanctuary-household" ? "household_request" : null;
76
+ if (!kind)
77
+ return null;
78
+ return { kind, friendId: actor.friendId, profileId: relationship.profileId, requestId: relationship.requestId, sessionEventId: actor.sessionEventId, origin: { friendId: session.friendId, channel: session.channel, key: session.key } };
79
+ }
80
+ function isRecord(value) {
81
+ return value !== null && typeof value === "object" && !Array.isArray(value);
82
+ }
83
+ function authorizeRestartApprovalRequester(ctx, args, binding) {
84
+ return authorizeRoutineActionRequester(ctx, args, {
85
+ requester: {
86
+ kind: "owner", friendId: binding.friendId, profileId: "sanctuary-owner", requestId: binding.requestId,
87
+ sessionEventId: binding.sessionEventId, origin: { friendId: binding.friendId, channel: "telegram", key: binding.sessionKey },
88
+ },
89
+ profileVersion: binding.profileVersion,
90
+ });
91
+ }
92
+ async function authorizeRoutineActionRequester(ctx, args, expected) {
93
+ if (!isRecord(args) || Object.keys(args).length !== 1 || typeof args.container !== "string"
94
+ || !args.container || args.container !== args.container.trim() || Buffer.byteLength(args.container) > 128 || args.container.includes("\uFFFD")
95
+ || !ctx?.agentRoot || !ctx.relationshipAuthorization)
96
+ return { allowed: false, reason: "routine action requires one exact target and current relationship" };
97
+ const target = args.container;
98
+ const agentRoot = ctx.agentRoot;
99
+ const relationship = ctx.relationshipAuthorization;
100
+ const sanctuary = ctx.sanctuary;
101
+ const initialRequester = routineActionRequester(ctx);
102
+ const event = ctx.currentExternalEvent && structuredClone(ctx.currentExternalEvent);
103
+ if (!initialRequester && (!event || event.source !== "sanctuary-health" || relationship.profileId !== "sanctuary-event"))
104
+ return { allowed: false, reason: "routine action requires a current human request or health event" };
105
+ const unchanged = () => ctx.agentRoot === agentRoot && ctx.relationshipAuthorization === relationship && ctx.sanctuary === sanctuary
106
+ && args.container === target && Object.keys(args).length === 1
107
+ && (0, node_util_1.isDeepStrictEqual)(initialRequester, routineActionRequester(ctx)) && (0, node_util_1.isDeepStrictEqual)(event, ctx.currentExternalEvent);
108
+ let authorization;
109
+ try {
110
+ authorization = await relationship.authorizeTool("unraid_restart_container", { container: target });
111
+ }
112
+ catch {
113
+ return { allowed: false, reason: "routine relationship authorization is unavailable" };
114
+ }
115
+ if (!authorization?.allowed)
116
+ return { allowed: false, reason: authorization?.allowed === false ? authorization.reason : "routine relationship authorization is unavailable" };
117
+ if (typeof authorization.profileVersion !== "number" || !Number.isSafeInteger(authorization.profileVersion) || authorization.profileVersion < 1
118
+ || typeof authorization.receiptId !== "string" || !authorization.receiptId.trim())
119
+ return { allowed: false, reason: "routine relationship authorization is not versioned" };
120
+ if (expected && authorization.profileVersion !== expected.profileVersion)
121
+ return { allowed: false, reason: "routine relationship profile version changed" };
122
+ if (!unchanged() || (authorization.profileId !== undefined && authorization.profileId !== relationship.profileId))
123
+ return { allowed: false, reason: "routine request binding changed during authorization" };
124
+ if (!event) {
125
+ if (!initialRequester || initialRequester.kind === "owner_event"
126
+ || (authorization.friendId !== undefined && authorization.friendId !== initialRequester.friendId)
127
+ || (authorization.requestId !== undefined && authorization.requestId !== initialRequester.requestId)
128
+ || (expected && !(0, node_util_1.isDeepStrictEqual)(expected.requester, initialRequester)))
129
+ return { allowed: false, reason: "routine request binding does not match live authorization" };
130
+ return { allowed: true, requester: initialRequester, receiptId: authorization.receiptId, profileVersion: authorization.profileVersion };
131
+ }
132
+ if (!sanctuary || authorization.profileId !== "sanctuary-event" || typeof authorization.friendId !== "string" || !authorization.friendId.trim())
133
+ return { allowed: false, reason: "current health event authorization is unavailable" };
134
+ let eventTarget;
135
+ if (expected) {
136
+ if (expected.requester.kind !== "owner_event" || expected.requester.target.name !== target)
137
+ return { allowed: false, reason: "current health event target binding changed" };
138
+ eventTarget = expected.requester.target;
139
+ }
140
+ else {
141
+ let listed;
142
+ try {
143
+ listed = await sanctuary.listContainers();
144
+ }
145
+ catch {
146
+ return { allowed: false, reason: "current health event container status is unavailable" };
147
+ }
148
+ if (!isRecord(listed) || listed.ok !== true || !isRecord(listed.data) || listed.data.truncated !== false || !Array.isArray(listed.data.containers))
149
+ return { allowed: false, reason: "current health event container status is invalid" };
150
+ const matches = listed.data.containers.filter((value) => isRecord(value) && value.name === target);
151
+ const container = matches[0];
152
+ if (matches.length !== 1 || !container || typeof container.id !== "string" || !container.id.trim()
153
+ || container.state !== "exited" || container.degraded !== false)
154
+ return { allowed: false, reason: "current health event target is not exactly stopped" };
155
+ eventTarget = { id: container.id, name: target };
156
+ }
157
+ const requester = routineActionRequester(ctx, { friendId: authorization.friendId, target: eventTarget });
158
+ if (!requester || requester.kind !== "owner_event" || !unchanged() || (expected && !(0, node_util_1.isDeepStrictEqual)(expected.requester, requester)))
159
+ return { allowed: false, reason: "current health event target or request binding changed" };
160
+ let current;
161
+ try {
162
+ current = (0, router_1.readExternalEventRecord)(requester.event.recordPath);
163
+ }
164
+ catch {
165
+ return { allowed: false, reason: "current health event record is unavailable" };
166
+ }
167
+ const lease = requester.event;
168
+ if (current.agent !== lease.agent || current.source !== lease.source || current.eventId !== lease.eventId || current.eventType !== "health.observed"
169
+ || current.generation !== lease.generation || current.observationRevision !== lease.observationRevision || current.claimOwner !== lease.claimOwner
170
+ || current.executionState !== "running" || !(Date.parse(current.claimExpiresAt ?? "") > Date.now())
171
+ || current.transition === "recovered" || current.pendingObservation !== null)
172
+ return { allowed: false, reason: "current health event claim or observation changed" };
173
+ return { allowed: true, requester, receiptId: authorization.receiptId, profileVersion: authorization.profileVersion };
174
+ }
175
+ function renderRelationshipPreferences(friend) {
176
+ const now = Date.now();
177
+ return Object.entries(friend.relationshipPolicy?.preferences ?? {})
178
+ .filter(([, preference]) => !preference.expiresAt || Date.parse(preference.expiresAt) > now)
179
+ .slice(0, 20)
180
+ .map(([category, preference]) => `- source=${preference.source}; provenance=${preference.provenance}; category=${category}; value=${String(preference.value).replace(/\s+/gu, " ").trim().slice(0, 500)}; version=${preference.version}; precedence=current${preference.expiresAt ? `; expires=${preference.expiresAt}` : ""}`);
181
+ }
182
+ function withRelationshipPreference(friend, input) {
183
+ const current = friend.relationshipPolicy ?? { schemaVersion: 1, version: 0, preferences: {} };
184
+ const previous = current.preferences[input.category];
185
+ return {
186
+ ...friend,
187
+ relationshipPolicy: {
188
+ schemaVersion: 1,
189
+ version: current.version + 1,
190
+ preferences: { ...current.preferences, [input.category]: { value: input.value, provenance: input.provenance, source: input.source, version: (previous?.version ?? 0) + 1 } },
191
+ },
192
+ updatedAt: new Date().toISOString(),
193
+ };
194
+ }
195
+ const deny = (reason) => ({ allowed: false, reason });
196
+ function authorizationReceipt(value) {
197
+ return `relationship-${(0, node_crypto_1.createHash)("sha256").update(JSON.stringify(value)).digest("hex")}`;
198
+ }
199
+ function stringList(value, label) {
200
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || !entry.trim()))
201
+ throw new Error(`${label} must be a string array`);
202
+ return [...new Set(value)];
203
+ }
204
+ function loadRelationshipCapabilityRegistry(agentRoot) {
205
+ const filePath = path.join(agentRoot, "tool-profiles.json");
206
+ const raw = JSON.parse(fs.readFileSync(filePath, "utf8"));
207
+ if (raw.version !== 2 || !raw.profiles || typeof raw.profiles !== "object" || Array.isArray(raw.profiles))
208
+ throw new Error("relationship capability registry version 2 is required");
209
+ const profiles = {};
210
+ for (const [id, value] of Object.entries(raw.profiles)) {
211
+ if (!value || typeof value !== "object" || Array.isArray(value))
212
+ throw new Error(`relationship capability profile ${id} is invalid`);
213
+ const candidate = value;
214
+ if (!Number.isInteger(candidate.version) || Number(candidate.version) < 1)
215
+ throw new Error(`relationship capability profile ${id} version is invalid`);
216
+ profiles[id] = {
217
+ id,
218
+ version: Number(candidate.version),
219
+ contextScopes: stringList(candidate.contextScopes, `${id}.contextScopes`),
220
+ toolNames: stringList(candidate.toolNames, `${id}.toolNames`),
221
+ effectScopes: stringList(candidate.effectScopes, `${id}.effectScopes`),
222
+ };
223
+ }
224
+ return { version: 2, profiles };
225
+ }
226
+ function relationshipSubjectFromFriend(friend) {
227
+ return {
228
+ friendId: friend.id,
229
+ trustLevel: friend.trustLevel ?? "stranger",
230
+ admissionState: friend.admissionState ?? "unverified",
231
+ initiativePolicy: friend.initiativePolicy ?? "none",
232
+ ...(friend.capabilityProfileId ? { capabilityProfileId: friend.capabilityProfileId } : {}),
233
+ };
234
+ }
235
+ function createRelationshipAuthorizationEvaluator(input) {
236
+ const subject = relationshipSubjectFromFriend(input.friend);
237
+ const relationshipProfile = subject.capabilityProfileId ? input.registry.profiles[subject.capabilityProfileId] : undefined;
238
+ const turnProfile = input.profileId ? input.registry.profiles[input.profileId] : relationshipProfile;
239
+ const profile = relationshipProfile && turnProfile
240
+ ? {
241
+ id: turnProfile.id,
242
+ version: turnProfile.version,
243
+ contextScopes: turnProfile.contextScopes.filter((scope) => relationshipProfile.contextScopes.includes(scope)),
244
+ toolNames: turnProfile.toolNames.filter((name) => relationshipProfile.toolNames.includes(name)),
245
+ effectScopes: turnProfile.effectScopes.filter((scope) => relationshipProfile.effectScopes.includes(scope)),
246
+ }
247
+ : undefined;
248
+ const effectiveSubject = { ...subject, ...(profile ? { capabilityProfileId: profile.id } : {}) };
249
+ const profiles = profile ? [profile] : [];
250
+ const evaluate = (request) => authorizeRelationshipAccess({
251
+ relationship: effectiveSubject,
252
+ profiles,
253
+ request,
254
+ activeRequestId: input.requestId,
255
+ requestPhase: input.requestPhase,
256
+ });
257
+ const advertisedToolNames = profile?.toolNames.filter((name) => evaluate({ kind: "tool", name, ...(input.requestId ? { requestId: input.requestId, returnTargetFriendId: subject.friendId } : {}) }).allowed) ?? [];
258
+ const authorizedContextScopes = profile?.contextScopes.filter((scope) => evaluate({ kind: "context", scope }).allowed) ?? [];
259
+ return {
260
+ subject,
261
+ ...(profile ? { profileId: profile.id } : {}),
262
+ authorizedContextScopes,
263
+ advertisedToolNames,
264
+ ...(input.sessionEventId ? { actor: { friendId: subject.friendId, trustLevel: subject.trustLevel, sessionEventId: input.sessionEventId } } : {}),
265
+ authorizeContext: (scope) => evaluate({ kind: "context", scope }),
266
+ authorizeTool: (name) => evaluate({ kind: "tool", name, ...(input.requestId ? { requestId: input.requestId, returnTargetFriendId: subject.friendId } : {}) }),
267
+ authorizeEffect: (scope) => evaluate({ kind: "effect", scope, ...(input.requestId ? { requestId: input.requestId, returnTargetFriendId: subject.friendId } : {}) }),
268
+ };
269
+ }
270
+ async function resolveProfileScopedRelationshipAuthorization(input) {
271
+ const friends = await input.store.listAll?.() ?? [];
272
+ const matches = friends.filter((friend) => friend.capabilityProfileId === input.relationshipProfileId);
273
+ if (matches.length !== 1)
274
+ throw new Error(`relationship profile ${input.relationshipProfileId} must resolve to exactly one Friend`);
275
+ return createRelationshipAuthorizationEvaluator({
276
+ friend: matches[0],
277
+ registry: input.registry,
278
+ ...(input.profileId ? { profileId: input.profileId } : {}),
279
+ ...(input.requestId ? { requestId: input.requestId } : {}),
280
+ ...(input.requestPhase ? { requestPhase: input.requestPhase } : {}),
281
+ ...(input.sessionEventId ? { sessionEventId: input.sessionEventId } : {}),
282
+ });
283
+ }
284
+ function authorizeRelationshipAccess(input) {
285
+ if (input.request.kind === "admission_gate") {
286
+ const pending = input.pendingAdmission;
287
+ const now = Date.parse(input.now ?? new Date().toISOString());
288
+ if (!pending || pending.admissionId !== input.request.admissionId || pending.botId !== input.request.botId || pending.userId !== input.request.userId || pending.chatId !== input.request.chatId || pending.expiresAt !== input.request.expiresAt || now >= Date.parse(input.request.expiresAt) || input.request.idempotencyKey !== `ack:${input.request.admissionId}`) {
289
+ return deny("admission gate authorization does not match a current pending admission");
290
+ }
291
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.relationship_authorized", message: "authorized fixed admission gate acknowledgement", meta: { authorizationKind: "admission_gate", admissionId: input.request.admissionId } });
292
+ return { allowed: true, authorizationKind: "admission_gate", receiptId: authorizationReceipt(input.request), admissionId: input.request.admissionId, idempotencyKey: input.request.idempotencyKey, expiresAt: input.request.expiresAt };
293
+ }
294
+ const relationship = input.relationship;
295
+ if (!relationship || relationship.admissionState !== "active")
296
+ return deny("relationship admission is not active");
297
+ if (relationship.trustLevel !== "friend" && relationship.trustLevel !== "family")
298
+ return deny("relationship trust is insufficient");
299
+ const profile = input.profiles.find((candidate) => candidate.id === relationship.capabilityProfileId);
300
+ if (!profile || !Number.isInteger(profile.version) || profile.version < 1)
301
+ return deny("relationship capability profile is missing or stale");
302
+ if (input.request.kind === "context" && !profile.contextScopes.includes(input.request.scope))
303
+ return deny("context scope is not authorized by the relationship profile");
304
+ if (input.request.kind === "tool" && !profile.toolNames.includes(input.request.name))
305
+ return deny("tool is not authorized by the relationship profile");
306
+ if (input.request.kind === "effect" && !profile.effectScopes.includes(input.request.scope))
307
+ return deny("effect is not authorized by the relationship profile");
308
+ const requestId = input.request.kind === "context" ? undefined : input.request.requestId;
309
+ const returnTarget = input.request.kind === "context" ? undefined : input.request.returnTargetFriendId;
310
+ if (relationship.initiativePolicy === "none")
311
+ return deny("initiative policy denies contact");
312
+ if (relationship.initiativePolicy === "reactive_only" && input.request.kind !== "context") {
313
+ if (input.requestPhase !== "inbound" || !requestId || requestId !== input.activeRequestId || returnTarget !== relationship.friendId)
314
+ return deny("initiative policy is reactive only");
315
+ }
316
+ if (relationship.initiativePolicy === "request_follow_up_only" && input.request.kind !== "context") {
317
+ if (!requestId || requestId !== input.activeRequestId || returnTarget !== relationship.friendId)
318
+ return deny("initiative policy requires the matching active request and return target");
319
+ }
320
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.relationship_authorized", message: "authorized relationship access", meta: { authorizationKind: "relationship", friendId: relationship.friendId, profileId: profile.id, profileVersion: profile.version, requestKind: input.request.kind } });
321
+ return { allowed: true, authorizationKind: "relationship", receiptId: authorizationReceipt({ relationship, request: input.request, activeRequestId: input.activeRequestId, requestPhase: input.requestPhase, profile }), friendId: relationship.friendId, profileId: profile.id, profileVersion: profile.version, requestId: requestId ?? null };
322
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.STOPPED_ON_PURPOSE_NOTE = exports.SERVICE_CONTAINERS = void 0;
4
+ exports.desiredContainerState = desiredContainerState;
5
+ exports.annotateContainers = annotateContainers;
6
+ const runtime_1 = require("../nerves/runtime");
7
+ /** House service name to the one container that is that service. */
8
+ exports.SERVICE_CONTAINERS = { Books: "calibre-web" };
9
+ const WANTED_ON = new Set(["on", "always_on", "expected_on"]);
10
+ const WANTED_OFF = /^(?:off|disabled|paused|intentionally_off|intentionally_paused)$/u;
11
+ exports.STOPPED_ON_PURPOSE_NOTE = "stopped on purpose by the steward policy; not needed by any running service; do not offer to start";
12
+ /** The policy's current desired state for a container, or null when the policy says nothing (or the entry expired). */
13
+ function desiredContainerState(policy, name, nowMs) {
14
+ const entry = policy?.desiredStates[`container:${name}`];
15
+ if (!entry)
16
+ return null;
17
+ const expires = entry.expiresAt ? Date.parse(entry.expiresAt) : Number.NaN;
18
+ if (Number.isFinite(expires) && expires <= nowMs)
19
+ return null;
20
+ const value = entry.value.trim().toLowerCase();
21
+ if (WANTED_ON.has(value))
22
+ return "running";
23
+ if (WANTED_OFF.test(value))
24
+ return "stopped";
25
+ return null;
26
+ }
27
+ /** Adds `desired`, `note` and `serves` to each container of an ok container-list result; any other result is returned unchanged. */
28
+ function annotateContainers(result, policy, nowMs) {
29
+ const value = result;
30
+ if (!value || value.ok !== true || !Array.isArray(value.data?.containers))
31
+ return result;
32
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.sanctuary_container_policy_annotated", message: "annotated the container list with steward-policy desired state", meta: { containers: value.data.containers.length, policyRead: policy !== null } });
33
+ const services = Object.entries(exports.SERVICE_CONTAINERS);
34
+ const containers = value.data.containers.map((entry) => {
35
+ const item = entry;
36
+ const name = typeof item.name === "string" ? item.name : "";
37
+ const desired = desiredContainerState(policy, name, nowMs);
38
+ const service = services.find(([, container]) => container === name)?.[0];
39
+ const running = item.state === "running";
40
+ const note = desired === "stopped"
41
+ ? (running ? "the steward policy wants this stopped but it is running; tell the owner, do not stop it yourself" : exports.STOPPED_ON_PURPOSE_NOTE)
42
+ : desired === "running" && !running ? "the steward policy wants this running but it is not" : undefined;
43
+ return { ...entry, ...(desired ? { desired } : {}), ...(note ? { note } : {}), ...(service ? { serves: service } : {}) };
44
+ });
45
+ return { ...result, data: { ...value.data, containers } };
46
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.spawnBackgroundShell = spawnBackgroundShell;
4
+ exports.getShellSession = getShellSession;
5
+ exports.listShellSessions = listShellSessions;
6
+ exports.tailShellSession = tailShellSession;
7
+ exports.resetShellSessions = resetShellSessions;
8
+ exports.detectDestructivePatterns = detectDestructivePatterns;
9
+ const child_process_1 = require("child_process");
10
+ const crypto_1 = require("crypto");
11
+ const runtime_1 = require("../nerves/runtime");
12
+ const sessions = new Map();
13
+ const MAX_OUTPUT_LINES = 200;
14
+ function spawnBackgroundShell(command, owner) {
15
+ const id = (0, crypto_1.randomUUID)();
16
+ const proc = (0, child_process_1.spawn)("sh", ["-c", command], {
17
+ stdio: ["pipe", "pipe", "pipe"],
18
+ });
19
+ const session = {
20
+ owner: Object.freeze({ ...owner }),
21
+ process: proc,
22
+ info: {
23
+ id,
24
+ command,
25
+ status: "running",
26
+ exitCode: null,
27
+ pid: proc.pid,
28
+ startedAt: Date.now(),
29
+ output: [],
30
+ },
31
+ };
32
+ const appendOutput = (data) => {
33
+ const lines = data.toString().split("\n");
34
+ for (const line of lines) {
35
+ if (line.length > 0 || session.info.output.length > 0) {
36
+ session.info.output.push(line);
37
+ }
38
+ }
39
+ // Keep only the last MAX_OUTPUT_LINES
40
+ if (session.info.output.length > MAX_OUTPUT_LINES) {
41
+ session.info.output = session.info.output.slice(-MAX_OUTPUT_LINES);
42
+ }
43
+ };
44
+ proc.stdout?.on("data", appendOutput);
45
+ proc.stderr?.on("data", appendOutput);
46
+ proc.on("close", (code) => {
47
+ session.info.status = "exited";
48
+ session.info.exitCode = code;
49
+ (0, runtime_1.emitNervesEvent)({
50
+ component: "repertoire",
51
+ event: "repertoire.shell.process_exit",
52
+ message: "background shell process exited",
53
+ meta: { id, command, exitCode: code, pid: proc.pid },
54
+ });
55
+ });
56
+ sessions.set(id, session);
57
+ (0, runtime_1.emitNervesEvent)({
58
+ component: "repertoire",
59
+ event: "repertoire.shell.spawn",
60
+ message: "spawned background shell session",
61
+ meta: { id, command, pid: proc.pid },
62
+ });
63
+ return { ...session.info };
64
+ }
65
+ function getShellSession(id, owner) {
66
+ const session = sessions.get(id);
67
+ if (!session || session.owner.agentName !== owner.agentName || session.owner.agentRoot !== owner.agentRoot)
68
+ return undefined;
69
+ (0, runtime_1.emitNervesEvent)({
70
+ component: "repertoire",
71
+ event: "repertoire.shell.status_check",
72
+ message: "checked shell session status",
73
+ meta: { id, status: session.info.status, exitCode: session.info.exitCode },
74
+ });
75
+ return { ...session.info };
76
+ }
77
+ function listShellSessions(owner) {
78
+ return Array.from(sessions.values()).filter((session) => session.owner.agentName === owner.agentName && session.owner.agentRoot === owner.agentRoot).map((s) => ({
79
+ id: s.info.id,
80
+ command: s.info.command,
81
+ status: s.info.status,
82
+ exitCode: s.info.exitCode,
83
+ pid: s.info.pid,
84
+ startedAt: s.info.startedAt,
85
+ output: [], // Don't include full output in listing
86
+ }));
87
+ }
88
+ function tailShellSession(id, owner, lines = 50) {
89
+ const session = sessions.get(id);
90
+ if (!session || session.owner.agentName !== owner.agentName || session.owner.agentRoot !== owner.agentRoot)
91
+ return undefined;
92
+ const tail = session.info.output.slice(-lines);
93
+ (0, runtime_1.emitNervesEvent)({
94
+ component: "repertoire",
95
+ event: "repertoire.shell.tail",
96
+ message: "tailed shell session output",
97
+ meta: { id, requestedLines: lines, returnedLines: tail.length },
98
+ });
99
+ return tail.join("\n");
100
+ }
101
+ /** Reset all sessions (for testing) */
102
+ function resetShellSessions() {
103
+ for (const session of sessions.values()) {
104
+ if (session.info.status === "running") {
105
+ session.process.kill();
106
+ }
107
+ }
108
+ sessions.clear();
109
+ }
110
+ const DESTRUCTIVE_PATTERNS = [
111
+ { name: "rm -rf root/home", regex: /rm\s+-rf\s+[/~]/ },
112
+ { name: "git push --force", regex: /git\s+push\s+--force/ },
113
+ { name: "git reset --hard", regex: /git\s+reset\s+--hard/ },
114
+ { name: "git clean -f", regex: /git\s+clean\s+-f/ },
115
+ { name: "git branch -D", regex: /git\s+branch\s+-D/ },
116
+ { name: "fork bomb", regex: /:\(\)\s*\{/ },
117
+ { name: "write to raw device", regex: />\s*\/dev\/sd/ },
118
+ { name: "git checkout .", regex: /git\s+checkout\s+\./ },
119
+ { name: "git stash drop", regex: /git\s+stash\s+drop/ },
120
+ ];
121
+ /**
122
+ * Detect destructive patterns in a shell command.
123
+ * Returns list of matched pattern names. Empty array = safe.
124
+ * This is a friction layer, not a hard block.
125
+ */
126
+ function detectDestructivePatterns(command) {
127
+ const matched = [];
128
+ for (const pattern of DESTRUCTIVE_PATTERNS) {
129
+ if (pattern.regex.test(command)) {
130
+ matched.push(pattern.name);
131
+ }
132
+ }
133
+ return matched;
134
+ }
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.getSkillsDir = getSkillsDir;
37
+ exports.getHarnessSkillsDir = getHarnessSkillsDir;
37
38
  exports.listSkills = listSkills;
38
39
  exports.loadSkill = loadSkill;
39
40
  exports.getLoadedSkills = getLoadedSkills;
@@ -42,6 +43,7 @@ const fs = __importStar(require("fs"));
42
43
  const path = __importStar(require("path"));
43
44
  const identity_1 = require("../heart/identity");
44
45
  const runtime_1 = require("../nerves/runtime");
46
+ const plugins_1 = require("./plugins");
45
47
  // Skills live in {agentRoot}/skills/ directory
46
48
  function getSkillsDir() {
47
49
  return path.join((0, identity_1.getAgentRoot)(), "skills");
@@ -50,6 +52,10 @@ function getSkillsDir() {
50
52
  function getProtocolMirrorDir() {
51
53
  return path.join(getSkillsDir(), "protocols");
52
54
  }
55
+ // Harness-level skills live in {repoRoot}/skills/ directory.
56
+ function getHarnessSkillsDir() {
57
+ return path.join((0, identity_1.getRepoRoot)(), "skills");
58
+ }
53
59
  function listMarkdownBasenames(dir) {
54
60
  if (!fs.existsSync(dir))
55
61
  return [];
@@ -59,7 +65,7 @@ function listMarkdownBasenames(dir) {
59
65
  .map((f) => path.basename(f, ".md"))
60
66
  .sort();
61
67
  }
62
- // in-memory store for loaded skills
68
+ // process-local store for loaded skills
63
69
  const loadedSkills = [];
64
70
  function listSkills() {
65
71
  (0, runtime_1.emitNervesEvent)({
@@ -70,7 +76,14 @@ function listSkills() {
70
76
  });
71
77
  const baseSkills = listMarkdownBasenames(getSkillsDir());
72
78
  const protocolMirrors = listMarkdownBasenames(getProtocolMirrorDir());
73
- const skills = [...new Set([...baseSkills, ...protocolMirrors])].sort();
79
+ const harnessSkills = listMarkdownBasenames(getHarnessSkillsDir());
80
+ const pluginSkills = (0, plugins_1.listPluginSkills)((0, plugins_1.listEnabledPlugins)());
81
+ // Agent skills (base + protocol) come first; harness skills are fallback;
82
+ // plugin skills surface after harness skills. Set deduplicates by name —
83
+ // agent overrides harness overrides plugins.
84
+ const skills = [
85
+ ...new Set([...baseSkills, ...protocolMirrors, ...harnessSkills, ...pluginSkills]),
86
+ ].sort();
74
87
  (0, runtime_1.emitNervesEvent)({
75
88
  event: "repertoire.load_end",
76
89
  component: "repertoire",
@@ -88,6 +101,7 @@ function loadSkill(skillName) {
88
101
  });
89
102
  const directSkillPath = path.join(getSkillsDir(), `${skillName}.md`);
90
103
  const protocolMirrorPath = path.join(getProtocolMirrorDir(), `${skillName}.md`);
104
+ const harnessSkillPath = path.join(getHarnessSkillsDir(), `${skillName}.md`);
91
105
  let resolvedPath = null;
92
106
  // 1) Direct agent skill.
93
107
  if (fs.existsSync(directSkillPath)) {
@@ -97,6 +111,35 @@ function loadSkill(skillName) {
97
111
  else if (fs.existsSync(protocolMirrorPath)) {
98
112
  resolvedPath = protocolMirrorPath;
99
113
  }
114
+ // 3) Harness-level skill (ships with npm package).
115
+ else if (fs.existsSync(harnessSkillPath)) {
116
+ resolvedPath = harnessSkillPath;
117
+ }
118
+ // 4) Plugin skill fallback. Iterate enabled plugins; first match wins.
119
+ if (!resolvedPath) {
120
+ for (const plugin of (0, plugins_1.listEnabledPlugins)()) {
121
+ try {
122
+ const content = (0, plugins_1.loadPluginSkill)(plugin.id, skillName);
123
+ if (!loadedSkills.includes(skillName)) {
124
+ loadedSkills.push(skillName);
125
+ }
126
+ (0, runtime_1.emitNervesEvent)({
127
+ event: "repertoire.load_end",
128
+ component: "repertoire",
129
+ message: "loaded skill",
130
+ meta: {
131
+ operation: "loadSkill",
132
+ skill: skillName,
133
+ path: `plugin:${plugin.id}`,
134
+ },
135
+ });
136
+ return content;
137
+ }
138
+ catch {
139
+ // try next plugin
140
+ }
141
+ }
142
+ }
100
143
  if (!resolvedPath) {
101
144
  (0, runtime_1.emitNervesEvent)({
102
145
  level: "error",
@@ -106,12 +149,13 @@ function loadSkill(skillName) {
106
149
  meta: {
107
150
  operation: "loadSkill",
108
151
  skill: skillName,
109
- checkedPaths: [directSkillPath, protocolMirrorPath],
152
+ checkedPaths: [directSkillPath, protocolMirrorPath, harnessSkillPath],
110
153
  },
111
154
  });
112
155
  throw new Error(`skill '${skillName}' not found in:\n` +
113
156
  `- ${directSkillPath}\n` +
114
- `- ${protocolMirrorPath}`);
157
+ `- ${protocolMirrorPath}\n` +
158
+ `- ${harnessSkillPath}`);
115
159
  }
116
160
  const content = fs.readFileSync(resolvedPath, "utf-8");
117
161
  if (!loadedSkills.includes(skillName)) {