@ouro.bot/cli 0.1.0-alpha.90 → 0.1.0-alpha.900

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 (701) 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 +5711 -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 +1614 -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 +27 -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/bridges/manager.js +137 -17
  122. package/dist/heart/bridges/store.js +14 -2
  123. package/dist/heart/bundle-state.js +168 -0
  124. package/dist/heart/commitments.js +44 -18
  125. package/dist/heart/config-registry.js +331 -0
  126. package/dist/heart/config.js +174 -131
  127. package/dist/heart/context-loss-gauntlet.js +387 -0
  128. package/dist/heart/context-loss-sentinel.js +1157 -0
  129. package/dist/heart/core.js +2319 -579
  130. package/dist/heart/cross-chat-delivery.js +9 -22
  131. package/dist/heart/daemon/agent-config-check.js +451 -0
  132. package/dist/heart/daemon/agent-discovery.js +277 -3
  133. package/dist/heart/daemon/agent-home.js +319 -0
  134. package/dist/heart/daemon/agent-service.js +542 -0
  135. package/dist/heart/daemon/agentic-repair.js +547 -0
  136. package/dist/heart/daemon/await-private-wake.js +59 -0
  137. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  138. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  139. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  140. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  141. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  142. package/dist/heart/daemon/cadence.js +180 -0
  143. package/dist/heart/daemon/cli-defaults.js +859 -0
  144. package/dist/heart/daemon/cli-desk.js +322 -0
  145. package/dist/heart/daemon/cli-exec.js +9003 -0
  146. package/dist/heart/daemon/cli-help.js +729 -0
  147. package/dist/heart/daemon/cli-parse.js +3140 -0
  148. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  149. package/dist/heart/daemon/cli-render.js +804 -0
  150. package/dist/heart/daemon/cli-types.js +8 -0
  151. package/dist/heart/daemon/connect-bay.js +323 -0
  152. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  153. package/dist/heart/daemon/container-healthcheck.js +112 -0
  154. package/dist/heart/daemon/container-runtime.js +97 -0
  155. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  156. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  157. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  158. package/dist/heart/daemon/daemon-cli.js +29 -2349
  159. package/dist/heart/daemon/daemon-entry.js +951 -11
  160. package/dist/heart/daemon/daemon-health.js +186 -0
  161. package/dist/heart/daemon/daemon-rollup.js +57 -0
  162. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  163. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  164. package/dist/heart/daemon/daemon.js +2084 -105
  165. package/dist/heart/daemon/dns-workflow.js +394 -0
  166. package/dist/heart/daemon/doctor-types.js +8 -0
  167. package/dist/heart/daemon/doctor.js +1755 -0
  168. package/dist/heart/daemon/freshness.js +345 -0
  169. package/dist/heart/daemon/habit-private-wake.js +61 -0
  170. package/dist/heart/daemon/health-monitor.js +142 -11
  171. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  172. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  173. package/dist/heart/daemon/http-health-probe.js +80 -0
  174. package/dist/heart/daemon/human-command-screens.js +234 -0
  175. package/dist/heart/daemon/human-readiness.js +114 -0
  176. package/dist/heart/daemon/inner-status.js +78 -0
  177. package/dist/heart/daemon/interactive-repair.js +394 -0
  178. package/dist/heart/daemon/launchd.js +37 -8
  179. package/dist/heart/daemon/log-tailer.js +79 -10
  180. package/dist/heart/daemon/logs-prune.js +132 -0
  181. package/dist/heart/daemon/mcp-canary.js +524 -0
  182. package/dist/heart/daemon/message-router.js +65 -5
  183. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  184. package/dist/heart/daemon/os-cron-deps.js +135 -0
  185. package/dist/heart/daemon/os-cron.js +22 -14
  186. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  187. package/dist/heart/daemon/ouro-entry.js +3 -1
  188. package/dist/heart/daemon/plugin-cli.js +432 -0
  189. package/dist/heart/daemon/process-manager.js +760 -61
  190. package/dist/heart/daemon/provider-discovery.js +137 -0
  191. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  192. package/dist/heart/daemon/prunable-bundle.js +144 -0
  193. package/dist/heart/daemon/pulse.js +511 -0
  194. package/dist/heart/daemon/readiness-repair.js +365 -0
  195. package/dist/heart/daemon/run-hooks.js +2 -0
  196. package/dist/heart/daemon/runtime-logging.js +47 -14
  197. package/dist/heart/daemon/runtime-metadata.js +2 -30
  198. package/dist/heart/daemon/runtime-mode.js +13 -2
  199. package/dist/heart/daemon/safe-mode.js +161 -0
  200. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  201. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  204. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  205. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  206. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  207. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  208. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  209. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  210. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  211. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  212. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  213. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  214. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  215. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  216. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  217. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  218. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  219. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  220. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  221. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  223. package/dist/heart/daemon/sense-manager.js +716 -48
  224. package/dist/heart/daemon/session-id-resolver.js +131 -0
  225. package/dist/heart/daemon/skill-management-installer.js +1 -1
  226. package/dist/heart/daemon/socket-client.js +180 -12
  227. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  228. package/dist/heart/daemon/startup-tui.js +339 -0
  229. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  230. package/dist/heart/daemon/task-scheduler.js +117 -39
  231. package/dist/heart/daemon/terminal-ui.js +499 -0
  232. package/dist/heart/daemon/thoughts.js +138 -54
  233. package/dist/heart/daemon/up-progress.js +366 -0
  234. package/dist/heart/daemon/vault-items.js +56 -0
  235. package/dist/heart/delegation.js +1 -4
  236. package/dist/heart/external-events/router.js +1516 -0
  237. package/dist/heart/failure-reports.js +335 -0
  238. package/dist/heart/file-lock.js +109 -0
  239. package/dist/heart/frontend-approval-runtime.js +506 -0
  240. package/dist/heart/frontend-journal.js +215 -0
  241. package/dist/heart/frontend-session-service.js +237 -0
  242. package/dist/heart/frontend-socket-client.js +164 -0
  243. package/dist/heart/frontend-socket.js +400 -0
  244. package/dist/heart/habits/habit-cancel.js +810 -0
  245. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  246. package/dist/heart/habits/habit-migration.js +194 -0
  247. package/dist/heart/habits/habit-parser.js +278 -0
  248. package/dist/heart/habits/habit-runtime-state.js +93 -0
  249. package/dist/heart/habits/habit-scheduler.js +653 -0
  250. package/dist/heart/habits/habit-session-summary.js +318 -0
  251. package/dist/heart/habits/habit-session.js +636 -0
  252. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  253. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  254. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  255. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  256. package/dist/heart/identity.js +199 -59
  257. package/dist/heart/kept-notes.js +289 -0
  258. package/dist/heart/kicks.js +1 -1
  259. package/dist/heart/machine-identity.js +175 -0
  260. package/dist/heart/mail-import-discovery.js +356 -0
  261. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  262. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  263. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  264. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  265. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  266. package/dist/heart/mailbox/mailbox-http.js +99 -0
  267. package/dist/heart/mailbox/mailbox-read.js +39 -0
  268. package/dist/heart/mailbox/mailbox-types.js +27 -0
  269. package/dist/heart/mailbox/mailbox-view.js +197 -0
  270. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  271. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  272. package/dist/heart/mailbox/readers/mail.js +375 -0
  273. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  274. package/dist/heart/mailbox/readers/sessions.js +231 -0
  275. package/dist/heart/mailbox/readers/shared.js +111 -0
  276. package/dist/heart/mcp/mcp-server.js +696 -0
  277. package/dist/heart/migrate-config.js +100 -0
  278. package/dist/heart/model-capabilities.js +11 -0
  279. package/dist/heart/orientation-frame.js +345 -0
  280. package/dist/heart/platform.js +81 -0
  281. package/dist/heart/primitives.js +1 -1
  282. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  283. package/dist/heart/private-runtime/index.js +18 -0
  284. package/dist/heart/private-runtime/ledger.js +221 -0
  285. package/dist/heart/private-runtime/policy.js +260 -0
  286. package/dist/heart/private-runtime/types.js +2 -0
  287. package/dist/heart/progress-story.js +1 -1
  288. package/dist/heart/provider-attempt.js +137 -0
  289. package/dist/heart/provider-binding-resolver.js +273 -0
  290. package/dist/heart/provider-credentials.js +449 -0
  291. package/dist/heart/provider-failover.js +311 -0
  292. package/dist/heart/provider-models.js +96 -0
  293. package/dist/heart/provider-ping.js +265 -0
  294. package/dist/heart/provider-readiness-cache.js +119 -0
  295. package/dist/heart/provider-visibility.js +188 -0
  296. package/dist/heart/providers/anthropic-token.js +131 -0
  297. package/dist/heart/providers/anthropic.js +173 -60
  298. package/dist/heart/providers/azure.js +23 -11
  299. package/dist/heart/providers/error-classification.js +127 -0
  300. package/dist/heart/providers/github-copilot.js +34 -38
  301. package/dist/heart/providers/minimax-vlm.js +189 -0
  302. package/dist/heart/providers/minimax.js +26 -8
  303. package/dist/heart/providers/openai-codex-token.js +349 -0
  304. package/dist/heart/providers/openai-codex.js +55 -40
  305. package/dist/heart/providers/openai-compatible.js +177 -0
  306. package/dist/heart/reply-style.js +56 -0
  307. package/dist/heart/run-ledger.js +247 -0
  308. package/dist/heart/runtime-capability-check.js +170 -0
  309. package/dist/heart/runtime-credentials.js +607 -0
  310. package/dist/heart/runtime-cwd.js +87 -0
  311. package/dist/heart/sense-truth.js +24 -4
  312. package/dist/heart/session-activity.js +92 -24
  313. package/dist/heart/session-events.js +1504 -0
  314. package/dist/heart/session-playback-cli-main.js +5 -0
  315. package/dist/heart/session-playback-cli.js +36 -0
  316. package/dist/heart/session-playback.js +231 -0
  317. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  318. package/dist/heart/session-redaction-repair.js +552 -0
  319. package/dist/heart/session-stats-cli-main.js +5 -0
  320. package/dist/heart/session-stats.js +183 -0
  321. package/dist/heart/session-transcript.js +133 -0
  322. package/dist/heart/shepherd-config.js +113 -0
  323. package/dist/heart/source-grounding.js +283 -0
  324. package/dist/heart/start-of-turn-packet.js +372 -0
  325. package/dist/heart/steward-policy.js +656 -0
  326. package/dist/heart/streaming.js +604 -207
  327. package/dist/heart/structured-output.js +196 -0
  328. package/dist/heart/sync-classification.js +176 -0
  329. package/dist/heart/sync.js +505 -0
  330. package/dist/heart/target-resolution.js +11 -7
  331. package/dist/heart/tempo.js +93 -0
  332. package/dist/heart/temporal-view.js +41 -0
  333. package/dist/heart/timeouts.js +101 -0
  334. package/dist/heart/tool-activity-callbacks.js +59 -0
  335. package/dist/heart/tool-approval.js +382 -0
  336. package/dist/heart/tool-description.js +155 -0
  337. package/dist/heart/tool-friction.js +55 -0
  338. package/dist/heart/tool-loop.js +206 -0
  339. package/dist/heart/turn-context.js +494 -0
  340. package/dist/heart/turn-execution-lease.js +30 -0
  341. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  342. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  343. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  344. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  345. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  346. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  347. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  348. package/dist/heart/versioning/update-hooks.js +154 -0
  349. package/dist/heart/versioning/version-intent.js +114 -0
  350. package/dist/heart/work-card.js +380 -0
  351. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  352. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  353. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  354. package/dist/mailbox-ui/index.html +16 -0
  355. package/dist/mailroom/attention.js +167 -0
  356. package/dist/mailroom/autonomy.js +209 -0
  357. package/dist/mailroom/blob-store.js +889 -0
  358. package/dist/mailroom/body-cache.js +61 -0
  359. package/dist/mailroom/cache-sync-cli.js +58 -0
  360. package/dist/mailroom/core.js +803 -0
  361. package/dist/mailroom/entry.js +160 -0
  362. package/dist/mailroom/file-store.js +568 -0
  363. package/dist/mailroom/hosted-cache-sync.js +384 -0
  364. package/dist/mailroom/mbox-import.js +393 -0
  365. package/dist/mailroom/migration.js +164 -0
  366. package/dist/mailroom/outbound.js +380 -0
  367. package/dist/mailroom/policy.js +263 -0
  368. package/dist/mailroom/reader.js +292 -0
  369. package/dist/mailroom/search-cache.js +513 -0
  370. package/dist/mailroom/search-relevance.js +319 -0
  371. package/dist/mailroom/smtp-ingress.js +176 -0
  372. package/dist/mailroom/source-state.js +176 -0
  373. package/dist/mailroom/thread.js +109 -0
  374. package/dist/mailroom/travel-extract.js +89 -0
  375. package/dist/mind/bundle-manifest.js +24 -2
  376. package/dist/mind/context.js +307 -139
  377. package/dist/mind/desk-section.js +362 -0
  378. package/dist/mind/diary-integrity.js +60 -0
  379. package/dist/mind/{memory.js → diary.js} +68 -77
  380. package/dist/mind/embedding-provider.js +60 -0
  381. package/dist/mind/file-state.js +179 -0
  382. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  383. package/dist/mind/obligation-steering.js +199 -3
  384. package/dist/mind/pending.js +36 -10
  385. package/dist/mind/prompt-budget.js +479 -0
  386. package/dist/mind/prompt-refresh.js +3 -2
  387. package/dist/mind/prompt.js +1085 -198
  388. package/dist/mind/provenance-trust.js +26 -0
  389. package/dist/mind/record-paths.js +312 -0
  390. package/dist/mind/scrutiny.js +173 -0
  391. package/dist/mind/session-transaction.js +564 -0
  392. package/dist/nerves/cli-logging.js +7 -1
  393. package/dist/nerves/coverage/audit-rules.js +15 -6
  394. package/dist/nerves/coverage/audit.js +28 -2
  395. package/dist/nerves/coverage/cli.js +1 -1
  396. package/dist/nerves/coverage/contract.js +5 -5
  397. package/dist/nerves/coverage/file-completeness.js +139 -5
  398. package/dist/nerves/coverage/run-artifacts.js +55 -35
  399. package/dist/nerves/coverage/source-scanner.js +4 -4
  400. package/dist/nerves/event-buffer.js +111 -0
  401. package/dist/nerves/index.js +293 -9
  402. package/dist/nerves/observation.js +20 -0
  403. package/dist/nerves/redact.js +79 -0
  404. package/dist/nerves/review/cli-main.js +5 -0
  405. package/dist/nerves/review/cli.js +156 -0
  406. package/dist/nerves/review/core.js +159 -0
  407. package/dist/nerves/runtime.js +17 -1
  408. package/dist/repertoire/ado-client.js +15 -56
  409. package/dist/repertoire/ado-semantic.js +16 -10
  410. package/dist/repertoire/api-client.js +97 -0
  411. package/dist/repertoire/bitwarden-store.js +1191 -0
  412. package/dist/repertoire/bundle-templates.js +71 -0
  413. package/dist/repertoire/bw-installer.js +180 -0
  414. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  415. package/dist/repertoire/coding/context-pack.js +331 -0
  416. package/dist/repertoire/coding/feedback.js +174 -32
  417. package/dist/repertoire/coding/index.js +15 -3
  418. package/dist/repertoire/coding/manager.js +159 -10
  419. package/dist/repertoire/coding/spawner.js +40 -11
  420. package/dist/repertoire/coding/tools.js +182 -18
  421. package/dist/repertoire/coding/workbench-client.js +272 -0
  422. package/dist/repertoire/coding/workbench-manager.js +346 -0
  423. package/dist/repertoire/commerce-errors.js +109 -0
  424. package/dist/repertoire/commerce-self-test.js +156 -0
  425. package/dist/repertoire/credential-access.js +182 -0
  426. package/dist/repertoire/desk/classifier.js +362 -0
  427. package/dist/repertoire/duffel-client.js +185 -0
  428. package/dist/repertoire/github-client.js +14 -55
  429. package/dist/repertoire/graph-client.js +11 -52
  430. package/dist/repertoire/guardrails.js +961 -19
  431. package/dist/repertoire/house-sweep.js +469 -0
  432. package/dist/repertoire/mcp-client.js +58 -5
  433. package/dist/repertoire/mcp-manager.js +427 -139
  434. package/dist/repertoire/mcp-tools.js +132 -0
  435. package/dist/repertoire/mcp-write-guard.js +46 -0
  436. package/dist/repertoire/plugin-mcp.js +175 -0
  437. package/dist/repertoire/plugins.js +253 -0
  438. package/dist/repertoire/relationship-authorization.js +322 -0
  439. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  440. package/dist/repertoire/shell-sessions.js +134 -0
  441. package/dist/repertoire/skills.js +48 -4
  442. package/dist/repertoire/stripe-client.js +131 -0
  443. package/dist/repertoire/tool-arguments.js +182 -0
  444. package/dist/repertoire/tool-results.js +29 -0
  445. package/dist/repertoire/tools-a2a.js +699 -0
  446. package/dist/repertoire/tools-attachments.js +322 -0
  447. package/dist/repertoire/tools-awaiting.js +870 -0
  448. package/dist/repertoire/tools-base.js +81 -1168
  449. package/dist/repertoire/tools-bluebubbles.js +2 -0
  450. package/dist/repertoire/tools-bridge.js +144 -0
  451. package/dist/repertoire/tools-bundle.js +993 -0
  452. package/dist/repertoire/tools-commerce.js +253 -0
  453. package/dist/repertoire/tools-config.js +186 -0
  454. package/dist/repertoire/tools-continuity.js +575 -0
  455. package/dist/repertoire/tools-credential.js +383 -0
  456. package/dist/repertoire/tools-escalation.js +84 -0
  457. package/dist/repertoire/tools-evolution.js +527 -0
  458. package/dist/repertoire/tools-files.js +344 -0
  459. package/dist/repertoire/tools-flight.js +290 -0
  460. package/dist/repertoire/tools-flow.js +119 -0
  461. package/dist/repertoire/tools-github.js +3 -8
  462. package/dist/repertoire/tools-habits.js +103 -0
  463. package/dist/repertoire/tools-house-care.js +174 -0
  464. package/dist/repertoire/tools-mail.js +1828 -0
  465. package/dist/repertoire/tools-notes.js +496 -0
  466. package/dist/repertoire/tools-obligations.js +182 -0
  467. package/dist/repertoire/tools-orientation.js +31 -0
  468. package/dist/repertoire/tools-record.js +482 -0
  469. package/dist/repertoire/tools-rsvp.js +139 -0
  470. package/dist/repertoire/tools-runtime.js +238 -0
  471. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  472. package/dist/repertoire/tools-session.js +1133 -0
  473. package/dist/repertoire/tools-shell.js +149 -0
  474. package/dist/repertoire/tools-shepherd.js +180 -0
  475. package/dist/repertoire/tools-steward-policy.js +147 -0
  476. package/dist/repertoire/tools-stripe.js +224 -0
  477. package/dist/repertoire/tools-surface.js +369 -0
  478. package/dist/repertoire/tools-teams.js +12 -39
  479. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  480. package/dist/repertoire/tools-travel.js +125 -0
  481. package/dist/repertoire/tools-trip.js +982 -0
  482. package/dist/repertoire/tools-unraid.js +556 -0
  483. package/dist/repertoire/tools-user-profile.js +146 -0
  484. package/dist/repertoire/tools-vault.js +40 -0
  485. package/dist/repertoire/tools-voice-local.js +198 -0
  486. package/dist/repertoire/tools-voice.js +145 -0
  487. package/dist/repertoire/tools.js +514 -156
  488. package/dist/repertoire/travel-api-client.js +360 -0
  489. package/dist/repertoire/unraid-client.js +155 -0
  490. package/dist/repertoire/unraid-restart.js +339 -0
  491. package/dist/repertoire/user-profile.js +131 -0
  492. package/dist/repertoire/vault-setup.js +246 -0
  493. package/dist/repertoire/vault-unlock.js +686 -0
  494. package/dist/rsvp/aisleplanner-client.js +354 -0
  495. package/dist/rsvp/cli.js +926 -0
  496. package/dist/rsvp/config.js +327 -0
  497. package/dist/rsvp/cutover.js +433 -0
  498. package/dist/rsvp/diagnostics.js +232 -0
  499. package/dist/rsvp/diff-renderer.js +176 -0
  500. package/dist/rsvp/habit-policy.js +110 -0
  501. package/dist/rsvp/habit-stage.js +123 -0
  502. package/dist/rsvp/incident-bundle.js +97 -0
  503. package/dist/rsvp/migration.js +204 -0
  504. package/dist/rsvp/native-habit-runner.js +630 -0
  505. package/dist/rsvp/outbound-state.js +628 -0
  506. package/dist/rsvp/query.js +118 -0
  507. package/dist/rsvp/replay.js +233 -0
  508. package/dist/rsvp/snapshot.js +232 -0
  509. package/dist/rsvp/spend-ledger.js +175 -0
  510. package/dist/scripts/claude-code-hook.js +41 -0
  511. package/dist/scripts/claude-code-stop-hook.js +47 -0
  512. package/dist/senses/a2a-entry.js +132 -0
  513. package/dist/senses/acp-server.js +386 -0
  514. package/dist/senses/attention-queue.js +186 -0
  515. package/dist/senses/await-turn-message.js +65 -0
  516. package/dist/senses/bluebubbles/active-turns.js +216 -0
  517. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  518. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  519. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  520. package/dist/senses/bluebubbles/context-packet.js +207 -0
  521. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  522. package/dist/senses/bluebubbles/entry.js +90 -0
  523. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  524. package/dist/senses/bluebubbles/index.js +3841 -0
  525. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  526. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  527. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  528. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  529. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  530. package/dist/senses/bluebubbles/processed-log.js +133 -0
  531. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  532. package/dist/senses/bluebubbles/replay.js +284 -0
  533. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  534. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  535. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  536. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  537. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  538. package/dist/senses/cli/bracketed-paste.js +82 -0
  539. package/dist/senses/cli/image-paste.js +287 -0
  540. package/dist/senses/cli/image-ref-navigation.js +75 -0
  541. package/dist/senses/cli/ink-app.js +156 -0
  542. package/dist/senses/cli/inline-diff.js +64 -0
  543. package/dist/senses/cli/input-keys.js +174 -0
  544. package/dist/senses/cli/kill-ring.js +86 -0
  545. package/dist/senses/cli/message-list.js +51 -0
  546. package/dist/senses/cli/ouro-tui.js +607 -0
  547. package/dist/senses/cli/spinner-imperative.js +135 -0
  548. package/dist/senses/cli/spinner.js +101 -0
  549. package/dist/senses/cli/status-line.js +60 -0
  550. package/dist/senses/cli/streaming-markdown.js +526 -0
  551. package/dist/senses/cli/tool-display.js +85 -0
  552. package/dist/senses/cli/tool-render.js +85 -0
  553. package/dist/senses/cli/tui-store.js +241 -0
  554. package/dist/senses/cli/virtual-list.js +35 -0
  555. package/dist/senses/cli-entry.js +60 -8
  556. package/dist/senses/cli.js +601 -304
  557. package/dist/senses/commands.js +66 -3
  558. package/dist/senses/context-packet-ledger.js +371 -0
  559. package/dist/senses/context-packets.js +154 -0
  560. package/dist/senses/habit-lifecycle-guard.js +24 -0
  561. package/dist/senses/habit-turn-message.js +160 -0
  562. package/dist/senses/ingress-evidence.js +2 -0
  563. package/dist/senses/mail-entry.js +66 -0
  564. package/dist/senses/mail.js +524 -0
  565. package/dist/senses/pipeline.js +1133 -204
  566. package/dist/senses/private-runtime-worker.js +859 -0
  567. package/dist/senses/private-runtime.js +1627 -0
  568. package/dist/senses/proactive-content-guard.js +51 -0
  569. package/dist/senses/root-host-approval-port.js +345 -0
  570. package/dist/senses/root-host-approval-runtime.js +393 -0
  571. package/dist/senses/sanctuary-authority-resident.js +102 -0
  572. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  573. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  574. package/dist/senses/sanctuary-grounding.js +118 -0
  575. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  576. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  577. package/dist/senses/sanctuary-health-runner.js +104 -0
  578. package/dist/senses/sanctuary-health.js +422 -0
  579. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  580. package/dist/senses/sanctuary-interactive-control.js +410 -0
  581. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  582. package/dist/senses/sanctuary-media-optimization.js +514 -0
  583. package/dist/senses/sanctuary-runtime.js +369 -0
  584. package/dist/senses/sanctuary-sab.js +85 -0
  585. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  586. package/dist/senses/shared-turn.js +793 -0
  587. package/dist/senses/shepherd/client.js +196 -0
  588. package/dist/senses/shepherd/cmux.js +332 -0
  589. package/dist/senses/shepherd/herdr.js +311 -0
  590. package/dist/senses/shepherd/host.js +14 -0
  591. package/dist/senses/shepherd/judge.js +98 -0
  592. package/dist/senses/shepherd/redact.js +37 -0
  593. package/dist/senses/shepherd/returns.js +79 -0
  594. package/dist/senses/shepherd/sense.js +288 -0
  595. package/dist/senses/shepherd-entry.js +78 -0
  596. package/dist/senses/surface-tool.js +109 -0
  597. package/dist/senses/teams-entry.js +60 -8
  598. package/dist/senses/teams.js +519 -218
  599. package/dist/senses/telegram-admission.js +718 -0
  600. package/dist/senses/telegram-approval-runtime.js +793 -0
  601. package/dist/senses/telegram-attachments.js +186 -0
  602. package/dist/senses/telegram-audit-ledger.js +220 -0
  603. package/dist/senses/telegram-authority-transport.js +231 -0
  604. package/dist/senses/telegram-client.js +1749 -0
  605. package/dist/senses/telegram-effect-adapter.js +900 -0
  606. package/dist/senses/telegram-entry.js +83 -0
  607. package/dist/senses/telegram.js +2351 -0
  608. package/dist/senses/trust-gate.js +104 -9
  609. package/dist/senses/voice/audio-playback.js +237 -0
  610. package/dist/senses/voice/audio-routing.js +119 -0
  611. package/dist/senses/voice/call-auth.js +250 -0
  612. package/dist/senses/voice/elevenlabs.js +202 -0
  613. package/dist/senses/voice/floor-control.js +431 -0
  614. package/dist/senses/voice/floor-controller.js +115 -0
  615. package/dist/senses/voice/golden-path.js +116 -0
  616. package/dist/senses/voice/index.js +29 -0
  617. package/dist/senses/voice/local-audio-control.js +344 -0
  618. package/dist/senses/voice/local-audio-devices.js +516 -0
  619. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  620. package/dist/senses/voice/local-audio-identity.js +103 -0
  621. package/dist/senses/voice/local-audio-join.js +325 -0
  622. package/dist/senses/voice/local-audio-mute.js +199 -0
  623. package/dist/senses/voice/local-audio-notify.js +121 -0
  624. package/dist/senses/voice/local-audio-prompts.js +116 -0
  625. package/dist/senses/voice/local-audio-transport.js +427 -0
  626. package/dist/senses/voice/local-audio.js +281 -0
  627. package/dist/senses/voice/local-media-stream.js +145 -0
  628. package/dist/senses/voice/meeting.js +113 -0
  629. package/dist/senses/voice/outbound.js +190 -0
  630. package/dist/senses/voice/phone.js +33 -0
  631. package/dist/senses/voice/playback.js +139 -0
  632. package/dist/senses/voice/process-guards.js +51 -0
  633. package/dist/senses/voice/realtime-eval.js +496 -0
  634. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  635. package/dist/senses/voice/realtime-trace.js +531 -0
  636. package/dist/senses/voice/transcript.js +70 -0
  637. package/dist/senses/voice/turn.js +191 -0
  638. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  639. package/dist/senses/voice/twilio-phone.js +5454 -0
  640. package/dist/senses/voice/types.js +2 -0
  641. package/dist/senses/voice/whisper.js +161 -0
  642. package/dist/senses/voice-entry.js +83 -0
  643. package/dist/senses/voice-realtime-eval-command.js +99 -0
  644. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  645. package/dist/senses/voice-twilio-entry.js +87 -0
  646. package/dist/trips/core.js +138 -0
  647. package/dist/trips/store.js +265 -0
  648. package/dist/util/frontmatter.js +69 -0
  649. package/npm-shrinkwrap.json +8100 -0
  650. package/package.json +73 -13
  651. package/skills/agent-commerce.md +113 -0
  652. package/skills/browser-navigation.md +117 -0
  653. package/skills/commerce-setup-guide.md +116 -0
  654. package/skills/commerce-setup.md +84 -0
  655. package/skills/configure-dev-tools.md +99 -0
  656. package/skills/travel-planning.md +138 -0
  657. package/dist/heart/daemon/auth-flow.js +0 -430
  658. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  659. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  660. package/dist/heart/daemon/update-hooks.js +0 -138
  661. package/dist/heart/obligations.js +0 -191
  662. package/dist/heart/safe-workspace.js +0 -362
  663. package/dist/heart/session-recall.js +0 -116
  664. package/dist/mind/friends/channel.js +0 -84
  665. package/dist/mind/friends/group-context.js +0 -144
  666. package/dist/mind/friends/resolver.js +0 -84
  667. package/dist/mind/friends/store-file.js +0 -190
  668. package/dist/mind/friends/store.js +0 -4
  669. package/dist/mind/friends/tokens.js +0 -26
  670. package/dist/mind/friends/trust-explanation.js +0 -74
  671. package/dist/mind/friends/types.js +0 -29
  672. package/dist/repertoire/tasks/board.js +0 -134
  673. package/dist/repertoire/tasks/index.js +0 -224
  674. package/dist/repertoire/tasks/lifecycle.js +0 -80
  675. package/dist/repertoire/tasks/middleware.js +0 -65
  676. package/dist/repertoire/tasks/parser.js +0 -173
  677. package/dist/repertoire/tasks/scanner.js +0 -132
  678. package/dist/repertoire/tasks/transitions.js +0 -144
  679. package/dist/senses/bluebubbles-entry.js +0 -13
  680. package/dist/senses/bluebubbles.js +0 -1181
  681. package/dist/senses/debug-activity.js +0 -154
  682. package/dist/senses/inner-dialog-worker.js +0 -90
  683. package/dist/senses/inner-dialog.js +0 -525
  684. package/subagents/README.md +0 -7
  685. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  686. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  687. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  688. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  689. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  690. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  691. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  692. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  693. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  694. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  695. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  696. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  697. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  698. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  699. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  700. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  701. /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)) {