@ouro.bot/cli 0.1.0-alpha.84 → 0.1.0-alpha.841

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 (649) 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 +5368 -16
  16. package/deploy/unraid/Dockerfile +54 -0
  17. package/deploy/unraid/README.txt +2983 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-butler-upgrade.mjs +933 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  36. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  37. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  38. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  39. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  40. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  41. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  42. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  43. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
  44. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
  50. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  51. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +204 -0
  52. package/deploy/unraid/sanctuary.xml +28 -0
  53. package/dist/a2a/card.js +57 -0
  54. package/dist/a2a/client.js +236 -0
  55. package/dist/a2a/config.js +50 -0
  56. package/dist/a2a/delegation-stores.js +56 -0
  57. package/dist/a2a/did-resolution.js +93 -0
  58. package/dist/a2a/identity.js +204 -0
  59. package/dist/a2a/inbound-share.js +110 -0
  60. package/dist/a2a/mission-result-wire.js +196 -0
  61. package/dist/a2a/onboarding.js +133 -0
  62. package/dist/a2a/pin-store.js +132 -0
  63. package/dist/a2a/sealed-chat.js +112 -0
  64. package/dist/a2a/seen-ledger.js +120 -0
  65. package/dist/a2a/server.js +661 -0
  66. package/dist/a2a/task-store.js +69 -0
  67. package/dist/a2a/transport.js +45 -0
  68. package/dist/a2a/types.js +3 -0
  69. package/dist/arc/attention-types.js +8 -0
  70. package/dist/arc/cares.js +360 -0
  71. package/dist/arc/episodes.js +118 -0
  72. package/dist/arc/evolution.js +490 -0
  73. package/dist/arc/flight-recorder.js +1034 -0
  74. package/dist/arc/intentions.js +134 -0
  75. package/dist/arc/json-store.js +117 -0
  76. package/dist/arc/obligations.js +386 -0
  77. package/dist/arc/packets.js +336 -0
  78. package/dist/arc/presence.js +185 -0
  79. package/dist/arc/task-lifecycle.js +57 -0
  80. package/dist/commerce/store.js +755 -0
  81. package/dist/commerce/types.js +3 -0
  82. package/dist/heart/active-work.js +798 -40
  83. package/dist/heart/agent-entry.js +252 -3
  84. package/dist/heart/approval-files.js +113 -0
  85. package/dist/heart/approval-store.js +960 -0
  86. package/dist/heart/attachments/image-normalize.js +194 -0
  87. package/dist/heart/attachments/materialize.js +97 -0
  88. package/dist/heart/attachments/originals.js +88 -0
  89. package/dist/heart/attachments/render.js +29 -0
  90. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  91. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  92. package/dist/heart/attachments/sources/index.js +18 -0
  93. package/dist/heart/attachments/sources/telegram.js +71 -0
  94. package/dist/heart/attachments/store.js +132 -0
  95. package/dist/heart/attachments/types.js +93 -0
  96. package/dist/heart/auth/auth-flow.js +495 -0
  97. package/dist/heart/autonomy-budget.js +478 -0
  98. package/dist/heart/awaiting/await-alert.js +148 -0
  99. package/dist/heart/awaiting/await-expiry.js +143 -0
  100. package/dist/heart/awaiting/await-loader.js +91 -0
  101. package/dist/heart/awaiting/await-parser.js +149 -0
  102. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  103. package/dist/heart/awaiting/await-scheduler.js +382 -0
  104. package/dist/heart/background-operations.js +281 -0
  105. package/dist/heart/bridges/manager.js +137 -17
  106. package/dist/heart/bridges/store.js +14 -2
  107. package/dist/heart/bundle-state.js +168 -0
  108. package/dist/heart/commitments.js +44 -18
  109. package/dist/heart/config-registry.js +331 -0
  110. package/dist/heart/config.js +174 -131
  111. package/dist/heart/context-loss-gauntlet.js +387 -0
  112. package/dist/heart/context-loss-sentinel.js +1157 -0
  113. package/dist/heart/core.js +2169 -581
  114. package/dist/heart/cross-chat-delivery.js +9 -22
  115. package/dist/heart/daemon/agent-config-check.js +451 -0
  116. package/dist/heart/daemon/agent-discovery.js +185 -3
  117. package/dist/heart/daemon/agent-service.js +542 -0
  118. package/dist/heart/daemon/agentic-repair.js +547 -0
  119. package/dist/heart/daemon/await-private-wake.js +59 -0
  120. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  121. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  122. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  123. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  124. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  125. package/dist/heart/daemon/cadence.js +180 -0
  126. package/dist/heart/daemon/cli-defaults.js +854 -0
  127. package/dist/heart/daemon/cli-desk.js +322 -0
  128. package/dist/heart/daemon/cli-exec.js +8896 -0
  129. package/dist/heart/daemon/cli-help.js +716 -0
  130. package/dist/heart/daemon/cli-parse.js +2872 -0
  131. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  132. package/dist/heart/daemon/cli-render.js +777 -0
  133. package/dist/heart/daemon/cli-types.js +8 -0
  134. package/dist/heart/daemon/connect-bay.js +323 -0
  135. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  136. package/dist/heart/daemon/container-healthcheck.js +112 -0
  137. package/dist/heart/daemon/container-runtime.js +97 -0
  138. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  139. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  140. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  141. package/dist/heart/daemon/daemon-cli.js +29 -2349
  142. package/dist/heart/daemon/daemon-entry.js +930 -11
  143. package/dist/heart/daemon/daemon-health.js +186 -0
  144. package/dist/heart/daemon/daemon-rollup.js +57 -0
  145. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  146. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  147. package/dist/heart/daemon/daemon.js +2084 -105
  148. package/dist/heart/daemon/dns-workflow.js +394 -0
  149. package/dist/heart/daemon/doctor-types.js +8 -0
  150. package/dist/heart/daemon/doctor.js +1755 -0
  151. package/dist/heart/daemon/freshness.js +345 -0
  152. package/dist/heart/daemon/habit-private-wake.js +61 -0
  153. package/dist/heart/daemon/health-monitor.js +142 -11
  154. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  155. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  156. package/dist/heart/daemon/http-health-probe.js +80 -0
  157. package/dist/heart/daemon/human-command-screens.js +234 -0
  158. package/dist/heart/daemon/human-readiness.js +114 -0
  159. package/dist/heart/daemon/inner-status.js +78 -0
  160. package/dist/heart/daemon/interactive-repair.js +394 -0
  161. package/dist/heart/daemon/launchd.js +37 -8
  162. package/dist/heart/daemon/log-tailer.js +79 -10
  163. package/dist/heart/daemon/logs-prune.js +132 -0
  164. package/dist/heart/daemon/mcp-canary.js +524 -0
  165. package/dist/heart/daemon/message-router.js +65 -5
  166. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  167. package/dist/heart/daemon/os-cron-deps.js +135 -0
  168. package/dist/heart/daemon/os-cron.js +22 -14
  169. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  170. package/dist/heart/daemon/ouro-entry.js +3 -1
  171. package/dist/heart/daemon/plugin-cli.js +432 -0
  172. package/dist/heart/daemon/process-manager.js +733 -61
  173. package/dist/heart/daemon/provider-discovery.js +137 -0
  174. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  175. package/dist/heart/daemon/prunable-bundle.js +144 -0
  176. package/dist/heart/daemon/pulse.js +511 -0
  177. package/dist/heart/daemon/readiness-repair.js +365 -0
  178. package/dist/heart/daemon/run-hooks.js +2 -0
  179. package/dist/heart/daemon/runtime-logging.js +47 -14
  180. package/dist/heart/daemon/runtime-metadata.js +2 -30
  181. package/dist/heart/daemon/runtime-mode.js +13 -2
  182. package/dist/heart/daemon/safe-mode.js +161 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  185. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  186. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  187. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  188. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  189. package/dist/heart/daemon/sanctuary-authority-installation.js +152 -0
  190. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  191. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1146 -0
  192. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  193. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  194. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  195. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  196. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  197. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  198. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  199. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  200. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  201. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  202. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  203. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  204. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  205. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +663 -0
  206. package/dist/heart/daemon/sense-manager.js +699 -48
  207. package/dist/heart/daemon/session-id-resolver.js +131 -0
  208. package/dist/heart/daemon/skill-management-installer.js +1 -1
  209. package/dist/heart/daemon/socket-client.js +180 -12
  210. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  211. package/dist/heart/daemon/startup-tui.js +339 -0
  212. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  213. package/dist/heart/daemon/task-scheduler.js +117 -39
  214. package/dist/heart/daemon/terminal-ui.js +499 -0
  215. package/dist/heart/daemon/thoughts.js +138 -54
  216. package/dist/heart/daemon/up-progress.js +366 -0
  217. package/dist/heart/daemon/vault-items.js +56 -0
  218. package/dist/heart/delegation.js +1 -4
  219. package/dist/heart/external-events/router.js +1430 -0
  220. package/dist/heart/frontend-approval-runtime.js +506 -0
  221. package/dist/heart/frontend-journal.js +215 -0
  222. package/dist/heart/frontend-session-service.js +237 -0
  223. package/dist/heart/frontend-socket-client.js +164 -0
  224. package/dist/heart/frontend-socket.js +400 -0
  225. package/dist/heart/habits/habit-cancel.js +810 -0
  226. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  227. package/dist/heart/habits/habit-migration.js +194 -0
  228. package/dist/heart/habits/habit-parser.js +278 -0
  229. package/dist/heart/habits/habit-runtime-state.js +93 -0
  230. package/dist/heart/habits/habit-scheduler.js +653 -0
  231. package/dist/heart/habits/habit-session-summary.js +318 -0
  232. package/dist/heart/habits/habit-session.js +636 -0
  233. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  234. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  235. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  236. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  237. package/dist/heart/identity.js +196 -59
  238. package/dist/heart/kept-notes.js +289 -0
  239. package/dist/heart/kicks.js +1 -1
  240. package/dist/heart/machine-identity.js +161 -0
  241. package/dist/heart/mail-import-discovery.js +356 -0
  242. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  243. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  244. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  245. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  246. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  247. package/dist/heart/mailbox/mailbox-http.js +99 -0
  248. package/dist/heart/mailbox/mailbox-read.js +39 -0
  249. package/dist/heart/mailbox/mailbox-types.js +27 -0
  250. package/dist/heart/mailbox/mailbox-view.js +197 -0
  251. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  252. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  253. package/dist/heart/mailbox/readers/mail.js +375 -0
  254. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  255. package/dist/heart/mailbox/readers/sessions.js +231 -0
  256. package/dist/heart/mailbox/readers/shared.js +111 -0
  257. package/dist/heart/mcp/mcp-server.js +696 -0
  258. package/dist/heart/migrate-config.js +100 -0
  259. package/dist/heart/model-capabilities.js +11 -0
  260. package/dist/heart/orientation-frame.js +345 -0
  261. package/dist/heart/platform.js +81 -0
  262. package/dist/heart/primitives.js +1 -1
  263. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  264. package/dist/heart/private-runtime/index.js +18 -0
  265. package/dist/heart/private-runtime/ledger.js +221 -0
  266. package/dist/heart/private-runtime/policy.js +252 -0
  267. package/dist/heart/private-runtime/types.js +2 -0
  268. package/dist/heart/progress-story.js +1 -1
  269. package/dist/heart/provider-attempt.js +137 -0
  270. package/dist/heart/provider-binding-resolver.js +273 -0
  271. package/dist/heart/provider-credentials.js +449 -0
  272. package/dist/heart/provider-failover.js +311 -0
  273. package/dist/heart/provider-models.js +96 -0
  274. package/dist/heart/provider-ping.js +265 -0
  275. package/dist/heart/provider-readiness-cache.js +119 -0
  276. package/dist/heart/provider-visibility.js +188 -0
  277. package/dist/heart/providers/anthropic-token.js +131 -0
  278. package/dist/heart/providers/anthropic.js +173 -60
  279. package/dist/heart/providers/azure.js +23 -11
  280. package/dist/heart/providers/error-classification.js +127 -0
  281. package/dist/heart/providers/github-copilot.js +34 -38
  282. package/dist/heart/providers/minimax-vlm.js +189 -0
  283. package/dist/heart/providers/minimax.js +26 -8
  284. package/dist/heart/providers/openai-codex-token.js +349 -0
  285. package/dist/heart/providers/openai-codex.js +55 -40
  286. package/dist/heart/providers/openai-compatible.js +177 -0
  287. package/dist/heart/run-ledger.js +247 -0
  288. package/dist/heart/runtime-capability-check.js +170 -0
  289. package/dist/heart/runtime-credentials.js +607 -0
  290. package/dist/heart/runtime-cwd.js +87 -0
  291. package/dist/heart/sense-truth.js +22 -4
  292. package/dist/heart/session-activity.js +92 -24
  293. package/dist/heart/session-events.js +1504 -0
  294. package/dist/heart/session-playback-cli-main.js +5 -0
  295. package/dist/heart/session-playback-cli.js +36 -0
  296. package/dist/heart/session-playback.js +231 -0
  297. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  298. package/dist/heart/session-redaction-repair.js +552 -0
  299. package/dist/heart/session-stats-cli-main.js +5 -0
  300. package/dist/heart/session-stats.js +183 -0
  301. package/dist/heart/session-transcript.js +133 -0
  302. package/dist/heart/start-of-turn-packet.js +372 -0
  303. package/dist/heart/steward-policy.js +618 -0
  304. package/dist/heart/streaming.js +604 -207
  305. package/dist/heart/structured-output.js +196 -0
  306. package/dist/heart/sync-classification.js +176 -0
  307. package/dist/heart/sync.js +449 -0
  308. package/dist/heart/target-resolution.js +11 -7
  309. package/dist/heart/tempo.js +93 -0
  310. package/dist/heart/temporal-view.js +41 -0
  311. package/dist/heart/timeouts.js +101 -0
  312. package/dist/heart/tool-activity-callbacks.js +59 -0
  313. package/dist/heart/tool-approval.js +382 -0
  314. package/dist/heart/tool-description.js +155 -0
  315. package/dist/heart/tool-friction.js +55 -0
  316. package/dist/heart/tool-loop.js +200 -0
  317. package/dist/heart/turn-context.js +482 -0
  318. package/dist/heart/turn-execution-lease.js +30 -0
  319. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  320. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  321. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  322. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  323. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  324. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  325. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  326. package/dist/heart/versioning/update-hooks.js +154 -0
  327. package/dist/heart/versioning/version-intent.js +114 -0
  328. package/dist/heart/work-card.js +380 -0
  329. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  330. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  331. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  332. package/dist/mailbox-ui/index.html +16 -0
  333. package/dist/mailroom/attention.js +167 -0
  334. package/dist/mailroom/autonomy.js +209 -0
  335. package/dist/mailroom/blob-store.js +889 -0
  336. package/dist/mailroom/body-cache.js +61 -0
  337. package/dist/mailroom/cache-sync-cli.js +58 -0
  338. package/dist/mailroom/core.js +803 -0
  339. package/dist/mailroom/entry.js +160 -0
  340. package/dist/mailroom/file-store.js +568 -0
  341. package/dist/mailroom/hosted-cache-sync.js +384 -0
  342. package/dist/mailroom/mbox-import.js +393 -0
  343. package/dist/mailroom/migration.js +164 -0
  344. package/dist/mailroom/outbound.js +380 -0
  345. package/dist/mailroom/policy.js +263 -0
  346. package/dist/mailroom/reader.js +292 -0
  347. package/dist/mailroom/search-cache.js +513 -0
  348. package/dist/mailroom/search-relevance.js +319 -0
  349. package/dist/mailroom/smtp-ingress.js +176 -0
  350. package/dist/mailroom/source-state.js +176 -0
  351. package/dist/mailroom/thread.js +109 -0
  352. package/dist/mailroom/travel-extract.js +89 -0
  353. package/dist/mind/bundle-manifest.js +24 -2
  354. package/dist/mind/context.js +309 -111
  355. package/dist/mind/desk-section.js +362 -0
  356. package/dist/mind/diary-integrity.js +60 -0
  357. package/dist/mind/{memory.js → diary.js} +68 -77
  358. package/dist/mind/embedding-provider.js +60 -0
  359. package/dist/mind/file-state.js +179 -0
  360. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  361. package/dist/mind/obligation-steering.js +199 -3
  362. package/dist/mind/pending.js +36 -10
  363. package/dist/mind/prompt-budget.js +479 -0
  364. package/dist/mind/prompt-refresh.js +3 -2
  365. package/dist/mind/prompt.js +1048 -198
  366. package/dist/mind/provenance-trust.js +26 -0
  367. package/dist/mind/record-paths.js +312 -0
  368. package/dist/mind/scrutiny.js +173 -0
  369. package/dist/mind/session-transaction.js +564 -0
  370. package/dist/nerves/cli-logging.js +7 -1
  371. package/dist/nerves/coverage/audit-rules.js +15 -6
  372. package/dist/nerves/coverage/audit.js +28 -2
  373. package/dist/nerves/coverage/cli.js +1 -1
  374. package/dist/nerves/coverage/contract.js +5 -5
  375. package/dist/nerves/coverage/file-completeness.js +139 -5
  376. package/dist/nerves/coverage/run-artifacts.js +55 -35
  377. package/dist/nerves/coverage/source-scanner.js +4 -4
  378. package/dist/nerves/event-buffer.js +111 -0
  379. package/dist/nerves/index.js +293 -9
  380. package/dist/nerves/observation.js +20 -0
  381. package/dist/nerves/redact.js +79 -0
  382. package/dist/nerves/review/cli-main.js +5 -0
  383. package/dist/nerves/review/cli.js +156 -0
  384. package/dist/nerves/review/core.js +159 -0
  385. package/dist/nerves/runtime.js +17 -1
  386. package/dist/repertoire/ado-client.js +15 -56
  387. package/dist/repertoire/ado-semantic.js +16 -10
  388. package/dist/repertoire/api-client.js +97 -0
  389. package/dist/repertoire/bitwarden-store.js +1045 -0
  390. package/dist/repertoire/bundle-templates.js +71 -0
  391. package/dist/repertoire/bw-installer.js +180 -0
  392. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  393. package/dist/repertoire/coding/context-pack.js +331 -0
  394. package/dist/repertoire/coding/feedback.js +174 -32
  395. package/dist/repertoire/coding/index.js +15 -3
  396. package/dist/repertoire/coding/manager.js +159 -10
  397. package/dist/repertoire/coding/spawner.js +58 -11
  398. package/dist/repertoire/coding/tools.js +221 -15
  399. package/dist/repertoire/coding/workbench-client.js +272 -0
  400. package/dist/repertoire/coding/workbench-manager.js +346 -0
  401. package/dist/repertoire/commerce-errors.js +109 -0
  402. package/dist/repertoire/commerce-self-test.js +156 -0
  403. package/dist/repertoire/credential-access.js +178 -0
  404. package/dist/repertoire/desk/classifier.js +362 -0
  405. package/dist/repertoire/duffel-client.js +185 -0
  406. package/dist/repertoire/github-client.js +14 -55
  407. package/dist/repertoire/graph-client.js +11 -52
  408. package/dist/repertoire/guardrails.js +811 -18
  409. package/dist/repertoire/mcp-client.js +44 -3
  410. package/dist/repertoire/mcp-manager.js +427 -139
  411. package/dist/repertoire/mcp-tools.js +124 -0
  412. package/dist/repertoire/plugin-mcp.js +175 -0
  413. package/dist/repertoire/plugins.js +253 -0
  414. package/dist/repertoire/relationship-authorization.js +322 -0
  415. package/dist/repertoire/shell-sessions.js +134 -0
  416. package/dist/repertoire/skills.js +48 -4
  417. package/dist/repertoire/stripe-client.js +131 -0
  418. package/dist/repertoire/tool-arguments.js +170 -0
  419. package/dist/repertoire/tool-results.js +29 -0
  420. package/dist/repertoire/tools-a2a.js +699 -0
  421. package/dist/repertoire/tools-attachments.js +322 -0
  422. package/dist/repertoire/tools-awaiting.js +575 -0
  423. package/dist/repertoire/tools-base.js +77 -1168
  424. package/dist/repertoire/tools-bluebubbles.js +2 -0
  425. package/dist/repertoire/tools-bridge.js +144 -0
  426. package/dist/repertoire/tools-bundle.js +993 -0
  427. package/dist/repertoire/tools-commerce.js +253 -0
  428. package/dist/repertoire/tools-config.js +186 -0
  429. package/dist/repertoire/tools-continuity.js +575 -0
  430. package/dist/repertoire/tools-credential.js +383 -0
  431. package/dist/repertoire/tools-evolution.js +527 -0
  432. package/dist/repertoire/tools-files.js +344 -0
  433. package/dist/repertoire/tools-flight.js +290 -0
  434. package/dist/repertoire/tools-flow.js +119 -0
  435. package/dist/repertoire/tools-github.js +3 -8
  436. package/dist/repertoire/tools-habits.js +103 -0
  437. package/dist/repertoire/tools-mail.js +1828 -0
  438. package/dist/repertoire/tools-notes.js +485 -0
  439. package/dist/repertoire/tools-obligations.js +182 -0
  440. package/dist/repertoire/tools-orientation.js +31 -0
  441. package/dist/repertoire/tools-record.js +482 -0
  442. package/dist/repertoire/tools-rsvp.js +139 -0
  443. package/dist/repertoire/tools-runtime.js +150 -0
  444. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  445. package/dist/repertoire/tools-session.js +1133 -0
  446. package/dist/repertoire/tools-shell.js +149 -0
  447. package/dist/repertoire/tools-steward-policy.js +119 -0
  448. package/dist/repertoire/tools-stripe.js +224 -0
  449. package/dist/repertoire/tools-surface.js +369 -0
  450. package/dist/repertoire/tools-teams.js +12 -39
  451. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  452. package/dist/repertoire/tools-travel.js +125 -0
  453. package/dist/repertoire/tools-trip.js +982 -0
  454. package/dist/repertoire/tools-unraid.js +531 -0
  455. package/dist/repertoire/tools-user-profile.js +146 -0
  456. package/dist/repertoire/tools-vault.js +40 -0
  457. package/dist/repertoire/tools-voice.js +145 -0
  458. package/dist/repertoire/tools.js +506 -148
  459. package/dist/repertoire/travel-api-client.js +360 -0
  460. package/dist/repertoire/unraid-client.js +155 -0
  461. package/dist/repertoire/unraid-restart.js +339 -0
  462. package/dist/repertoire/user-profile.js +131 -0
  463. package/dist/repertoire/vault-setup.js +246 -0
  464. package/dist/repertoire/vault-unlock.js +628 -0
  465. package/dist/rsvp/aisleplanner-client.js +354 -0
  466. package/dist/rsvp/cli.js +926 -0
  467. package/dist/rsvp/config.js +327 -0
  468. package/dist/rsvp/cutover.js +433 -0
  469. package/dist/rsvp/diagnostics.js +232 -0
  470. package/dist/rsvp/diff-renderer.js +176 -0
  471. package/dist/rsvp/habit-policy.js +110 -0
  472. package/dist/rsvp/habit-stage.js +123 -0
  473. package/dist/rsvp/incident-bundle.js +97 -0
  474. package/dist/rsvp/migration.js +204 -0
  475. package/dist/rsvp/native-habit-runner.js +630 -0
  476. package/dist/rsvp/outbound-state.js +628 -0
  477. package/dist/rsvp/query.js +118 -0
  478. package/dist/rsvp/replay.js +233 -0
  479. package/dist/rsvp/snapshot.js +232 -0
  480. package/dist/rsvp/spend-ledger.js +175 -0
  481. package/dist/scripts/claude-code-hook.js +41 -0
  482. package/dist/scripts/claude-code-stop-hook.js +47 -0
  483. package/dist/senses/a2a-entry.js +115 -0
  484. package/dist/senses/acp-server.js +386 -0
  485. package/dist/senses/attention-queue.js +186 -0
  486. package/dist/senses/await-turn-message.js +58 -0
  487. package/dist/senses/bluebubbles/active-turns.js +216 -0
  488. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  489. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  490. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  491. package/dist/senses/bluebubbles/context-packet.js +207 -0
  492. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  493. package/dist/senses/bluebubbles/entry.js +90 -0
  494. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  495. package/dist/senses/bluebubbles/index.js +3841 -0
  496. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  497. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  498. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  499. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  500. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  501. package/dist/senses/bluebubbles/processed-log.js +133 -0
  502. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  503. package/dist/senses/bluebubbles/replay.js +284 -0
  504. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  505. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  506. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  507. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  508. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  509. package/dist/senses/cli/bracketed-paste.js +82 -0
  510. package/dist/senses/cli/image-paste.js +287 -0
  511. package/dist/senses/cli/image-ref-navigation.js +75 -0
  512. package/dist/senses/cli/ink-app.js +156 -0
  513. package/dist/senses/cli/inline-diff.js +64 -0
  514. package/dist/senses/cli/input-keys.js +174 -0
  515. package/dist/senses/cli/kill-ring.js +86 -0
  516. package/dist/senses/cli/message-list.js +51 -0
  517. package/dist/senses/cli/ouro-tui.js +607 -0
  518. package/dist/senses/cli/spinner-imperative.js +135 -0
  519. package/dist/senses/cli/spinner.js +101 -0
  520. package/dist/senses/cli/status-line.js +60 -0
  521. package/dist/senses/cli/streaming-markdown.js +526 -0
  522. package/dist/senses/cli/tool-display.js +85 -0
  523. package/dist/senses/cli/tool-render.js +85 -0
  524. package/dist/senses/cli/tui-store.js +241 -0
  525. package/dist/senses/cli/virtual-list.js +35 -0
  526. package/dist/senses/cli-entry.js +60 -8
  527. package/dist/senses/cli.js +604 -320
  528. package/dist/senses/commands.js +66 -3
  529. package/dist/senses/context-packet-ledger.js +371 -0
  530. package/dist/senses/context-packets.js +154 -0
  531. package/dist/senses/habit-lifecycle-guard.js +24 -0
  532. package/dist/senses/habit-turn-message.js +160 -0
  533. package/dist/senses/ingress-evidence.js +2 -0
  534. package/dist/senses/mail-entry.js +66 -0
  535. package/dist/senses/mail.js +524 -0
  536. package/dist/senses/pipeline.js +1115 -204
  537. package/dist/senses/private-runtime-worker.js +859 -0
  538. package/dist/senses/private-runtime.js +1517 -0
  539. package/dist/senses/proactive-content-guard.js +51 -0
  540. package/dist/senses/root-host-approval-port.js +345 -0
  541. package/dist/senses/root-host-approval-runtime.js +393 -0
  542. package/dist/senses/sanctuary-authority-resident.js +102 -0
  543. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  544. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  545. package/dist/senses/sanctuary-grounding.js +118 -0
  546. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  547. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  548. package/dist/senses/sanctuary-health-runner.js +100 -0
  549. package/dist/senses/sanctuary-health.js +408 -0
  550. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  551. package/dist/senses/sanctuary-interactive-control.js +410 -0
  552. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  553. package/dist/senses/sanctuary-media-optimization.js +514 -0
  554. package/dist/senses/sanctuary-runtime.js +340 -0
  555. package/dist/senses/sanctuary-sab.js +85 -0
  556. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  557. package/dist/senses/shared-turn.js +772 -0
  558. package/dist/senses/surface-tool.js +109 -0
  559. package/dist/senses/teams-entry.js +60 -8
  560. package/dist/senses/teams.js +519 -218
  561. package/dist/senses/telegram-admission.js +718 -0
  562. package/dist/senses/telegram-approval-runtime.js +793 -0
  563. package/dist/senses/telegram-attachments.js +186 -0
  564. package/dist/senses/telegram-audit-ledger.js +220 -0
  565. package/dist/senses/telegram-authority-transport.js +231 -0
  566. package/dist/senses/telegram-client.js +1749 -0
  567. package/dist/senses/telegram-effect-adapter.js +896 -0
  568. package/dist/senses/telegram-entry.js +83 -0
  569. package/dist/senses/telegram.js +2324 -0
  570. package/dist/senses/trust-gate.js +104 -9
  571. package/dist/senses/voice/audio-playback.js +237 -0
  572. package/dist/senses/voice/audio-routing.js +119 -0
  573. package/dist/senses/voice/elevenlabs.js +202 -0
  574. package/dist/senses/voice/floor-control.js +431 -0
  575. package/dist/senses/voice/floor-controller.js +115 -0
  576. package/dist/senses/voice/golden-path.js +116 -0
  577. package/dist/senses/voice/index.js +29 -0
  578. package/dist/senses/voice/meeting.js +113 -0
  579. package/dist/senses/voice/outbound.js +190 -0
  580. package/dist/senses/voice/phone.js +33 -0
  581. package/dist/senses/voice/playback.js +139 -0
  582. package/dist/senses/voice/realtime-eval.js +496 -0
  583. package/dist/senses/voice/realtime-trace.js +531 -0
  584. package/dist/senses/voice/transcript.js +70 -0
  585. package/dist/senses/voice/turn.js +191 -0
  586. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  587. package/dist/senses/voice/twilio-phone.js +5031 -0
  588. package/dist/senses/voice/types.js +2 -0
  589. package/dist/senses/voice/whisper.js +161 -0
  590. package/dist/senses/voice-entry.js +81 -0
  591. package/dist/senses/voice-realtime-eval-command.js +99 -0
  592. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  593. package/dist/senses/voice-twilio-entry.js +87 -0
  594. package/dist/trips/core.js +138 -0
  595. package/dist/trips/store.js +265 -0
  596. package/dist/util/frontmatter.js +69 -0
  597. package/npm-shrinkwrap.json +8138 -0
  598. package/package.json +72 -13
  599. package/skills/agent-commerce.md +113 -0
  600. package/skills/browser-navigation.md +117 -0
  601. package/skills/commerce-setup-guide.md +116 -0
  602. package/skills/commerce-setup.md +84 -0
  603. package/skills/configure-dev-tools.md +99 -0
  604. package/skills/travel-planning.md +138 -0
  605. package/dist/heart/daemon/auth-flow.js +0 -430
  606. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  607. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  608. package/dist/heart/daemon/update-hooks.js +0 -138
  609. package/dist/heart/obligations.js +0 -191
  610. package/dist/heart/safe-workspace.js +0 -261
  611. package/dist/heart/session-recall.js +0 -116
  612. package/dist/mind/friends/channel.js +0 -84
  613. package/dist/mind/friends/group-context.js +0 -144
  614. package/dist/mind/friends/resolver.js +0 -84
  615. package/dist/mind/friends/store-file.js +0 -190
  616. package/dist/mind/friends/store.js +0 -4
  617. package/dist/mind/friends/tokens.js +0 -26
  618. package/dist/mind/friends/trust-explanation.js +0 -74
  619. package/dist/mind/friends/types.js +0 -29
  620. package/dist/repertoire/tasks/board.js +0 -134
  621. package/dist/repertoire/tasks/index.js +0 -224
  622. package/dist/repertoire/tasks/lifecycle.js +0 -80
  623. package/dist/repertoire/tasks/middleware.js +0 -65
  624. package/dist/repertoire/tasks/parser.js +0 -173
  625. package/dist/repertoire/tasks/scanner.js +0 -132
  626. package/dist/repertoire/tasks/transitions.js +0 -144
  627. package/dist/senses/bluebubbles-entry.js +0 -13
  628. package/dist/senses/bluebubbles.js +0 -1181
  629. package/dist/senses/debug-activity.js +0 -154
  630. package/dist/senses/inner-dialog-worker.js +0 -90
  631. package/dist/senses/inner-dialog.js +0 -525
  632. package/subagents/README.md +0 -7
  633. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  643. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  644. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  645. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  646. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  647. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  648. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  649. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,186 @@
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.MAX_TELEGRAM_ATTACHMENT_BYTES = void 0;
37
+ exports.ingestTelegramAttachments = ingestTelegramAttachments;
38
+ const fs = __importStar(require("node:fs/promises"));
39
+ const path = __importStar(require("node:path"));
40
+ const node_crypto_1 = require("node:crypto");
41
+ const store_1 = require("../heart/attachments/store");
42
+ const store_2 = require("../heart/attachments/store");
43
+ const originals_1 = require("../heart/attachments/originals");
44
+ const originals_2 = require("../heart/attachments/originals");
45
+ const telegram_1 = require("../heart/attachments/sources/telegram");
46
+ const runtime_1 = require("../nerves/runtime");
47
+ exports.MAX_TELEGRAM_ATTACHMENT_BYTES = 20_000_000;
48
+ const MAX_TELEGRAM_ATTACHMENTS_PER_MESSAGE = 8;
49
+ const SAFE_FILE_PATH = /^(?!\/)(?!.*(?:^|\/)\.\.(?:\/|$))[A-Za-z0-9._/-]{1,512}$/u;
50
+ async function readBounded(response, limit) {
51
+ const advertised = Number(response.headers.get("content-length"));
52
+ if (Number.isFinite(advertised) && advertised > limit)
53
+ throw new Error("advertised size exceeds limit");
54
+ if (!response.body)
55
+ throw new Error("empty response body");
56
+ const chunks = [];
57
+ let total = 0;
58
+ const reader = response.body.getReader();
59
+ try {
60
+ for (;;) {
61
+ const { done, value } = await reader.read();
62
+ if (done)
63
+ break;
64
+ total += value.byteLength;
65
+ if (total > limit)
66
+ throw new Error("download exceeds limit");
67
+ chunks.push(value);
68
+ }
69
+ }
70
+ finally {
71
+ await reader.cancel().catch(() => undefined);
72
+ }
73
+ return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total);
74
+ }
75
+ async function atomicWrite(filePath, buffer) {
76
+ const directory = path.dirname(filePath);
77
+ await fs.mkdir(directory, { recursive: true, mode: 0o700 });
78
+ const temporary = `${filePath}.${(0, node_crypto_1.randomUUID)()}.tmp`;
79
+ let handle;
80
+ try {
81
+ handle = await fs.open(temporary, "wx", 0o600);
82
+ await handle.writeFile(buffer);
83
+ await handle.sync();
84
+ await handle.close();
85
+ handle = undefined;
86
+ await fs.rename(temporary, filePath);
87
+ const directoryHandle = await fs.open(directory, "r");
88
+ try {
89
+ await directoryHandle.sync();
90
+ }
91
+ finally {
92
+ await directoryHandle.close();
93
+ }
94
+ }
95
+ finally {
96
+ await handle?.close().catch(() => undefined);
97
+ await fs.unlink(temporary).catch((error) => { if (error.code !== "ENOENT")
98
+ throw error; });
99
+ }
100
+ }
101
+ async function ingestTelegramAttachments(input) {
102
+ const fetchImpl = input.fetch ?? globalThis.fetch;
103
+ const unique = [...new Map(input.attachments.map((attachment) => [attachment.fileId, attachment])).values()]
104
+ .slice(0, MAX_TELEGRAM_ATTACHMENTS_PER_MESSAGE);
105
+ const attachments = [];
106
+ const notices = [];
107
+ for (const candidate of unique) {
108
+ try {
109
+ if (!/^[A-Za-z0-9_-]{1,512}$/u.test(candidate.fileId))
110
+ throw new Error("invalid file id");
111
+ if (candidate.byteCount !== undefined && (!Number.isSafeInteger(candidate.byteCount) || candidate.byteCount < 0 || candidate.byteCount > exports.MAX_TELEGRAM_ATTACHMENT_BYTES))
112
+ throw new Error("advertised size exceeds limit");
113
+ const cached = (0, store_2.getRecentAttachment)(input.agentName, `attachment:telegram:${candidate.fileId}`, input.agentRoot);
114
+ if (cached?.source === "telegram") {
115
+ const localPath = cached.sourceData.localPath;
116
+ if (typeof localPath === "string") {
117
+ await (0, originals_2.ensureReadableFile)(localPath);
118
+ attachments.push(cached);
119
+ continue;
120
+ }
121
+ }
122
+ const recoverable = (0, telegram_1.buildTelegramAttachmentRecord)({
123
+ fileId: candidate.fileId,
124
+ displayName: candidate.displayName,
125
+ mimeType: candidate.mimeType,
126
+ byteCount: candidate.byteCount,
127
+ localPath: path.resolve(input.agentRoot, "state", "attachments", ".pending", candidate.fileId),
128
+ });
129
+ const recoverablePath = (0, originals_1.originalStoragePath)(input.agentRoot, recoverable, recoverable.mimeType);
130
+ try {
131
+ const stat = await fs.lstat(recoverablePath);
132
+ if (!stat.isFile() || stat.size > exports.MAX_TELEGRAM_ATTACHMENT_BYTES)
133
+ throw new Error("persisted attachment is invalid");
134
+ const recovered = (0, store_1.cacheRecentAttachment)(input.agentName, (0, telegram_1.buildTelegramAttachmentRecord)({
135
+ fileId: candidate.fileId,
136
+ displayName: candidate.displayName,
137
+ mimeType: candidate.mimeType,
138
+ byteCount: stat.size,
139
+ localPath: recoverablePath,
140
+ }), input.agentRoot);
141
+ attachments.push(recovered);
142
+ continue;
143
+ }
144
+ catch (error) {
145
+ if (error.code !== "ENOENT")
146
+ throw error;
147
+ }
148
+ const remote = await input.api.request("getFile", { file_id: candidate.fileId });
149
+ if (typeof remote.file_path !== "string" || !SAFE_FILE_PATH.test(remote.file_path))
150
+ throw new Error("invalid remote path");
151
+ if (remote.file_size !== undefined && (!Number.isSafeInteger(remote.file_size) || remote.file_size < 0 || remote.file_size > exports.MAX_TELEGRAM_ATTACHMENT_BYTES))
152
+ throw new Error("advertised size exceeds limit");
153
+ const response = input.downloadFile
154
+ ? await input.downloadFile(remote.file_path)
155
+ : input.botToken
156
+ ? await fetchImpl(`https://api.telegram.org/file/bot${input.botToken}/${remote.file_path}`, { signal: AbortSignal.timeout(30_000) })
157
+ : (() => { throw new Error("attachment transport is unavailable"); })();
158
+ if (!response.ok)
159
+ throw new Error(`download failed with HTTP ${response.status}`);
160
+ const buffer = await readBounded(response, exports.MAX_TELEGRAM_ATTACHMENT_BYTES);
161
+ const provisional = (0, telegram_1.buildTelegramAttachmentRecord)({
162
+ fileId: candidate.fileId,
163
+ displayName: candidate.displayName,
164
+ mimeType: candidate.mimeType ?? response.headers.get("content-type") ?? undefined,
165
+ byteCount: buffer.length,
166
+ localPath: path.resolve(input.agentRoot, "state", "attachments", ".pending", candidate.fileId),
167
+ });
168
+ const localPath = (0, originals_1.originalStoragePath)(input.agentRoot, provisional, provisional.mimeType);
169
+ await atomicWrite(localPath, buffer);
170
+ const record = (0, store_1.cacheRecentAttachment)(input.agentName, (0, telegram_1.buildTelegramAttachmentRecord)({
171
+ fileId: candidate.fileId,
172
+ displayName: candidate.displayName,
173
+ mimeType: provisional.mimeType,
174
+ byteCount: buffer.length,
175
+ localPath,
176
+ }), input.agentRoot);
177
+ attachments.push(record);
178
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.telegram_attachment_ingested", message: "Telegram attachment entered the shared attachment store", meta: { kind: record.kind, byteCount: buffer.length } });
179
+ }
180
+ catch (error) {
181
+ notices.push(`attachment unavailable: ${candidate.displayName}`);
182
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.telegram_attachment_ingest_error", message: "Telegram attachment ingestion failed", meta: { kind: candidate.kind, reason: error instanceof Error ? error.name : "unknown" } });
183
+ }
184
+ }
185
+ return { attachments, notices };
186
+ }
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TELEGRAM_ACCEPTANCE_AUDIT_HEAD_RELATIVE_PATH = exports.TELEGRAM_ACCEPTANCE_AUDIT_RELATIVE_PATH = void 0;
7
+ exports.verifyTelegramAuditLedger = verifyTelegramAuditLedger;
8
+ exports.createTelegramAuditLedger = createTelegramAuditLedger;
9
+ const node_crypto_1 = require("node:crypto");
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const redact_1 = require("../nerves/redact");
13
+ const runtime_1 = require("../nerves/runtime");
14
+ const SCHEMA = "sanctuary-telegram-audit-chain-v1";
15
+ const GENESIS_MAC = "0".repeat(64);
16
+ const SHA256 = /^[0-9a-f]{64}$/u;
17
+ const MAX_BYTES = 32 * 1024 * 1024;
18
+ const MAX_ROWS = 100_000;
19
+ const MAX_ROW_BYTES = 64 * 1024;
20
+ const LEVELS = new Set(["debug", "info", "warn", "error"]);
21
+ const ROW_KEYS = ["component", "event", "level", "message", "meta", "previousMac", "rowMac", "schemaVersion", "sequence", "trace_id", "ts"].sort();
22
+ const HEAD_KEYS = ["headMac", "lastMac", "recordCount", "schemaVersion"].sort();
23
+ exports.TELEGRAM_ACCEPTANCE_AUDIT_RELATIVE_PATH = node_path_1.default.join("state", "acceptance", "telegram-audit-chain.ndjson");
24
+ exports.TELEGRAM_ACCEPTANCE_AUDIT_HEAD_RELATIVE_PATH = node_path_1.default.join("state", "acceptance", "telegram-audit-chain.head.json");
25
+ function canonicalJson(value) {
26
+ if (Array.isArray(value))
27
+ return `[${value.map(canonicalJson).join(",")}]`;
28
+ if (value && typeof value === "object") {
29
+ const record = value;
30
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
31
+ }
32
+ const rendered = JSON.stringify(value);
33
+ if (rendered === undefined)
34
+ throw new Error("Telegram audit ledger contains an unsupported value");
35
+ return rendered;
36
+ }
37
+ function rowMac(identityKey, row) {
38
+ return (0, node_crypto_1.createHmac)("sha256", identityKey).update(`ouroboros.telegram.audit-row.v1\0${canonicalJson(row)}`, "utf8").digest("hex");
39
+ }
40
+ function headMac(identityKey, recordCount, lastMac) {
41
+ return (0, node_crypto_1.createHmac)("sha256", identityKey).update(`ouroboros.telegram.audit-head.v1\0${recordCount}\0${lastMac}`, "utf8").digest("hex");
42
+ }
43
+ function canonicalIso(value) {
44
+ return typeof value === "string" && value.length <= 30 && Number.isFinite(Date.parse(value)) && new Date(Date.parse(value)).toISOString() === value;
45
+ }
46
+ function object(value, label) {
47
+ if (!value || typeof value !== "object" || Array.isArray(value))
48
+ throw new Error(`${label} is invalid`);
49
+ return value;
50
+ }
51
+ function parseJson(raw, label) {
52
+ try {
53
+ return JSON.parse(raw);
54
+ }
55
+ catch (error) {
56
+ throw new Error(`${label} JSON is invalid`, { cause: error });
57
+ }
58
+ }
59
+ function containsPrivateMaterial(raw, privateValues) {
60
+ return privateValues.some((value) => value.length >= 5 && raw.includes(value))
61
+ || /\b\d{5,16}:[A-Za-z0-9_-]{20,}\b/u.test(raw)
62
+ || /"(?:authorized_?user_?id|authorized_?chat_?id|transport_?user_?id|transport_?chat_?id|user_?id|chat_?id|update_?id|message_?id)"\s*:\s*"?\d{1,20}"?/iu.test(raw);
63
+ }
64
+ function parseHead(raw, identityKey) {
65
+ if (Buffer.byteLength(raw) > 4 * 1024)
66
+ throw new Error("Telegram audit head exceeds its bound");
67
+ const value = object(parseJson(raw, "Telegram audit head"), "Telegram audit head");
68
+ if (JSON.stringify(Object.keys(value).sort()) !== JSON.stringify(HEAD_KEYS)
69
+ || value.schemaVersion !== SCHEMA
70
+ || !Number.isSafeInteger(value.recordCount) || Number(value.recordCount) < 0 || Number(value.recordCount) > MAX_ROWS
71
+ || typeof value.lastMac !== "string" || !SHA256.test(value.lastMac)
72
+ || typeof value.headMac !== "string" || !SHA256.test(value.headMac)
73
+ || value.headMac !== headMac(identityKey, Number(value.recordCount), value.lastMac))
74
+ throw new Error("Telegram audit head MAC is invalid");
75
+ return value;
76
+ }
77
+ function verifyTelegramAuditLedger(options) {
78
+ if (Buffer.byteLength(options.ledgerRaw) > MAX_BYTES)
79
+ throw new Error("Telegram audit ledger exceeds its bound");
80
+ const lines = options.ledgerRaw.split("\n").filter(Boolean);
81
+ if (lines.length > MAX_ROWS || lines.some((line) => Buffer.byteLength(line) > MAX_ROW_BYTES))
82
+ throw new Error("Telegram audit ledger exceeds its bound");
83
+ const head = parseHead(options.headRaw, options.identityKey);
84
+ let previousMac = GENESIS_MAC;
85
+ const events = lines.map((line, index) => {
86
+ if (containsPrivateMaterial(line, options.privateValues ?? []))
87
+ throw new Error("Telegram audit ledger contains private material");
88
+ const value = object(parseJson(line, "Telegram audit ledger row"), "Telegram audit ledger row");
89
+ if (JSON.stringify(Object.keys(value).sort()) !== JSON.stringify(ROW_KEYS)
90
+ || value.schemaVersion !== SCHEMA || value.sequence !== index + 1 || value.previousMac !== previousMac
91
+ || !canonicalIso(value.ts) || typeof value.level !== "string" || !LEVELS.has(value.level)
92
+ || typeof value.event !== "string" || value.event.length < 1 || value.event.length > 256
93
+ || typeof value.component !== "string" || value.component.length < 1 || value.component.length > 128
94
+ || typeof value.trace_id !== "string" || value.trace_id.length < 1 || value.trace_id.length > 256
95
+ || typeof value.message !== "string" || value.message.length > 4_096
96
+ || !value.meta || typeof value.meta !== "object" || Array.isArray(value.meta)
97
+ || typeof value.rowMac !== "string" || !SHA256.test(value.rowMac))
98
+ throw new Error("Telegram audit ledger row is invalid");
99
+ const unsigned = Object.fromEntries(Object.entries(value).filter(([key]) => key !== "rowMac"));
100
+ if (value.rowMac !== rowMac(options.identityKey, unsigned))
101
+ throw new Error("Telegram audit ledger row MAC is invalid");
102
+ previousMac = value.rowMac;
103
+ return { event: value.event, at: Date.parse(value.ts), meta: value.meta };
104
+ });
105
+ if (head.recordCount !== lines.length || head.lastMac !== previousMac)
106
+ throw new Error("Telegram audit head does not match the append-only ledger");
107
+ return events;
108
+ }
109
+ function writeHead(filePath, directory, head) {
110
+ const temporary = `${filePath}.tmp-${process.pid}-${(0, node_crypto_1.randomUUID)()}`;
111
+ (0, node_fs_1.writeFileSync)(temporary, `${JSON.stringify(head)}\n`, { flag: "wx", mode: 0o600 });
112
+ const file = (0, node_fs_1.openSync)(temporary, "r");
113
+ try {
114
+ (0, node_fs_1.fsyncSync)(file);
115
+ }
116
+ finally {
117
+ (0, node_fs_1.closeSync)(file);
118
+ }
119
+ (0, node_fs_1.renameSync)(temporary, filePath);
120
+ const directoryHandle = (0, node_fs_1.openSync)(directory, "r");
121
+ try {
122
+ (0, node_fs_1.fsyncSync)(directoryHandle);
123
+ }
124
+ finally {
125
+ (0, node_fs_1.closeSync)(directoryHandle);
126
+ }
127
+ }
128
+ function createTelegramAuditLedger(options) {
129
+ const directory = node_path_1.default.join(options.root, "state", "acceptance");
130
+ const ledgerPath = node_path_1.default.join(options.root, exports.TELEGRAM_ACCEPTANCE_AUDIT_RELATIVE_PATH);
131
+ const headPath = node_path_1.default.join(options.root, exports.TELEGRAM_ACCEPTANCE_AUDIT_HEAD_RELATIVE_PATH);
132
+ (0, node_fs_1.mkdirSync)(directory, { recursive: true, mode: 0o700 });
133
+ if ((0, node_fs_1.existsSync)(ledgerPath) !== (0, node_fs_1.existsSync)(headPath))
134
+ throw new Error("Telegram audit ledger/head presence mismatch");
135
+ if (!(0, node_fs_1.existsSync)(ledgerPath)) {
136
+ (0, node_fs_1.writeFileSync)(ledgerPath, "", { flag: "wx", mode: 0o600 });
137
+ writeHead(headPath, directory, { schemaVersion: SCHEMA, recordCount: 0, lastMac: GENESIS_MAC, headMac: headMac(options.identityKey, 0, GENESIS_MAC) });
138
+ }
139
+ let records = verifyTelegramAuditLedger({ ledgerRaw: (0, node_fs_1.readFileSync)(ledgerPath, "utf8"), headRaw: (0, node_fs_1.readFileSync)(headPath, "utf8"), identityKey: options.identityKey, privateValues: options.privateValues });
140
+ let currentHead = parseHead((0, node_fs_1.readFileSync)(headPath, "utf8"), options.identityKey);
141
+ const maxBytes = options._maxBytes ?? MAX_BYTES;
142
+ let failure;
143
+ (0, runtime_1.emitNervesEvent)({
144
+ component: "senses",
145
+ event: "senses.telegram_audit_ledger_ready",
146
+ message: "Telegram acceptance audit ledger is verified",
147
+ meta: { recordCount: currentHead.recordCount },
148
+ });
149
+ return {
150
+ ledgerPath,
151
+ headPath,
152
+ append(event) {
153
+ if (failure)
154
+ throw failure;
155
+ try {
156
+ const original = JSON.stringify(event);
157
+ if (containsPrivateMaterial(original, options.privateValues ?? []))
158
+ throw new Error("Telegram audit event contains private material");
159
+ const redacted = JSON.parse((0, redact_1.redactString)(JSON.stringify((0, redact_1.redactLogEntry)(event))));
160
+ const unsigned = {
161
+ schemaVersion: SCHEMA,
162
+ sequence: currentHead.recordCount + 1,
163
+ previousMac: currentHead.lastMac,
164
+ ts: redacted.ts,
165
+ level: redacted.level,
166
+ event: redacted.event,
167
+ component: redacted.component,
168
+ trace_id: redacted.trace_id,
169
+ message: redacted.message,
170
+ meta: redacted.meta,
171
+ };
172
+ const row = { ...unsigned, rowMac: rowMac(options.identityKey, unsigned) };
173
+ const serialized = JSON.stringify(row);
174
+ if (Buffer.byteLength(serialized) > MAX_ROW_BYTES || currentHead.recordCount >= MAX_ROWS
175
+ || Buffer.byteLength((0, node_fs_1.readFileSync)(ledgerPath)) + Buffer.byteLength(serialized) + 1 > maxBytes)
176
+ throw new Error("Telegram audit ledger exceeds its bound");
177
+ (0, node_fs_1.appendFileSync)(ledgerPath, `${serialized}\n`, { encoding: "utf8", mode: 0o600 });
178
+ const ledgerHandle = (0, node_fs_1.openSync)(ledgerPath, "r");
179
+ try {
180
+ (0, node_fs_1.fsyncSync)(ledgerHandle);
181
+ }
182
+ finally {
183
+ (0, node_fs_1.closeSync)(ledgerHandle);
184
+ }
185
+ currentHead = {
186
+ schemaVersion: SCHEMA,
187
+ recordCount: row.sequence,
188
+ lastMac: row.rowMac,
189
+ headMac: headMac(options.identityKey, row.sequence, row.rowMac),
190
+ };
191
+ writeHead(headPath, directory, currentHead);
192
+ records = [...records, { event: row.event, at: Date.parse(row.ts), meta: row.meta }];
193
+ }
194
+ catch (error) {
195
+ failure = error instanceof Error ? error : new Error(String(error));
196
+ throw failure;
197
+ }
198
+ },
199
+ poison(error) {
200
+ failure ??= error;
201
+ throw failure;
202
+ },
203
+ assertHealthy() {
204
+ if (failure)
205
+ throw failure;
206
+ records = verifyTelegramAuditLedger({ ledgerRaw: (0, node_fs_1.readFileSync)(ledgerPath, "utf8"), headRaw: (0, node_fs_1.readFileSync)(headPath, "utf8"), identityKey: options.identityKey, privateValues: options.privateValues });
207
+ currentHead = parseHead((0, node_fs_1.readFileSync)(headPath, "utf8"), options.identityKey);
208
+ },
209
+ assertCapacity(additionalRows = 1) {
210
+ if (!Number.isSafeInteger(additionalRows) || additionalRows < 1)
211
+ throw new Error("Telegram audit capacity reservation is invalid");
212
+ if (failure)
213
+ throw failure;
214
+ if (currentHead.recordCount + additionalRows > MAX_ROWS
215
+ || Buffer.byteLength((0, node_fs_1.readFileSync)(ledgerPath)) + additionalRows * (MAX_ROW_BYTES + 1) > maxBytes) {
216
+ throw new Error("Telegram audit ledger lacks reserved capacity");
217
+ }
218
+ },
219
+ };
220
+ }
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSanctuaryTelegramAuthorityTransport = createSanctuaryTelegramAuthorityTransport;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const runtime_1 = require("../nerves/runtime");
6
+ const sanctuary_authority_codec_1 = require("../heart/daemon/sanctuary-authority-codec");
7
+ const root_host_approval_port_1 = require("./root-host-approval-port");
8
+ function isObject(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10
+ }
11
+ function validPollBody(body) {
12
+ return Object.keys(body).sort().join(",") === "allowed_updates,offset,timeout"
13
+ && Number.isSafeInteger(body.offset)
14
+ && body.offset >= 0
15
+ && body.timeout === 50
16
+ && Array.isArray(body.allowed_updates)
17
+ && body.allowed_updates.length === 2
18
+ && body.allowed_updates[0] === "message"
19
+ && body.allowed_updates[1] === "callback_query";
20
+ }
21
+ function rawUpdateDigest(update) {
22
+ return `tgu_${(0, node_crypto_1.createHash)("sha256")
23
+ .update(`ouroboros.telegram.update.v1\0${JSON.stringify(update)}`, "utf8")
24
+ .digest("base64url")}`;
25
+ }
26
+ function exactKeys(value, keys) {
27
+ const actual = Object.keys(value).sort();
28
+ const expected = [...keys].sort();
29
+ return actual.length === expected.length && actual.every((key, index) => key === expected[index]);
30
+ }
31
+ function canonicalTime(value) {
32
+ if (typeof value !== "string")
33
+ return false;
34
+ const instant = new Date(value);
35
+ return !Number.isNaN(instant.getTime()) && instant.toISOString() === value;
36
+ }
37
+ function verifyObservation(artifact, update, verification) {
38
+ let payload;
39
+ try {
40
+ payload = (0, sanctuary_authority_codec_1.verifyAuthorityPayload)({
41
+ artifact,
42
+ expectedDomain: "ouro.sanctuary.telegram-observation.v1",
43
+ expectedKeyId: verification.expectedKeyId,
44
+ publicKey: verification.publicKey,
45
+ });
46
+ }
47
+ catch (error) {
48
+ throw new Error("Sanctuary Telegram authority poll response is invalid", { cause: error });
49
+ }
50
+ if (!isObject(payload)
51
+ || !exactKeys(payload, [
52
+ "targetHost", "botId", "updateId", "updateClass", "userId", "chatId", "ownerEligible",
53
+ "messageId", "callbackQueryId", "rawUpdateDigest", "observedAt", "settlement", "nonce", "publicKeyDigest",
54
+ ...(Object.hasOwn(payload, "deliveryUpdateDigest") ? ["deliveryUpdateDigest"] : []),
55
+ ])
56
+ || payload.targetHost !== verification.expectedTargetHost
57
+ || payload.botId !== verification.expectedBotId
58
+ || payload.publicKeyDigest !== verification.expectedPublicKeyDigest
59
+ || payload.updateId !== update.update_id
60
+ || !["message", "callback"].includes(String(payload.updateClass))
61
+ || typeof payload.userId !== "string"
62
+ || typeof payload.chatId !== "string"
63
+ || typeof payload.ownerEligible !== "boolean"
64
+ || (payload.messageId !== null && typeof payload.messageId !== "string")
65
+ || (payload.callbackQueryId !== null && typeof payload.callbackQueryId !== "string")
66
+ || typeof payload.rawUpdateDigest !== "string"
67
+ || !/^tgu_[A-Za-z0-9_-]{43}$/u.test(payload.rawUpdateDigest)
68
+ || (Object.hasOwn(payload, "deliveryUpdateDigest") && typeof payload.deliveryUpdateDigest !== "string")
69
+ || (payload.deliveryUpdateDigest ?? payload.rawUpdateDigest) !== rawUpdateDigest(update)
70
+ || !canonicalTime(payload.observedAt)
71
+ || payload.settlement !== "pending"
72
+ || typeof payload.nonce !== "string"
73
+ || !/^[A-Za-z0-9_-]{43}$/u.test(payload.nonce)) {
74
+ throw new Error("Sanctuary Telegram authority observation payload is invalid");
75
+ }
76
+ const callback = update.callback_query;
77
+ const message = update.message;
78
+ if ((!callback && !message) || (callback && message) || (callback && (!callback.message || !callback.from)) || (message && !message.from)) {
79
+ throw new Error("Sanctuary Telegram authority observation update is unsupported");
80
+ }
81
+ const updateClass = callback ? "callback" : "message";
82
+ const userId = String(callback ? callback.from.id : message.from.id);
83
+ const chatId = String(callback ? callback.message.chat.id : message.chat.id);
84
+ const messageId = String(callback ? callback.message.message_id : message.message_id);
85
+ const callbackQueryId = callback ? callback.id : null;
86
+ if (payload.updateClass !== updateClass
87
+ || payload.userId !== userId
88
+ || payload.chatId !== chatId
89
+ || payload.messageId !== messageId
90
+ || payload.callbackQueryId !== callbackQueryId
91
+ || payload.ownerEligible !== (userId === verification.expectedOwnerUserId && chatId === verification.expectedOwnerChatId)) {
92
+ throw new Error("Sanctuary Telegram authority observation coordinates changed");
93
+ }
94
+ return Object.freeze({
95
+ schemaVersion: 1,
96
+ observationDigest: (0, sanctuary_authority_codec_1.authorityArtifactDigest)(artifact.domain, payload),
97
+ targetHost: payload.targetHost,
98
+ botId: payload.botId,
99
+ updateId: payload.updateId,
100
+ updateClass: payload.updateClass,
101
+ userId: payload.userId,
102
+ chatId: payload.chatId,
103
+ ownerEligible: payload.ownerEligible,
104
+ messageId: payload.messageId,
105
+ callbackQueryId: payload.callbackQueryId,
106
+ rawUpdateDigest: payload.rawUpdateDigest,
107
+ ...(payload.deliveryUpdateDigest ? { deliveryUpdateDigest: payload.deliveryUpdateDigest } : {}),
108
+ observedAt: payload.observedAt,
109
+ keyId: artifact.keyId,
110
+ publicKeyDigest: payload.publicKeyDigest,
111
+ });
112
+ }
113
+ function createSanctuaryTelegramAuthorityTransport(client, verification) {
114
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_authority_transport_created", message: "Tokenless Sanctuary Telegram authority transport created" });
115
+ verification = Object.freeze({ ...verification });
116
+ const observations = new Map();
117
+ const metadata = new Map();
118
+ const callbacks = new Map();
119
+ let currentObservation = null;
120
+ let stopped = false;
121
+ const api = {
122
+ async request(method, body, signal) {
123
+ if (signal?.aborted)
124
+ throw signal.reason;
125
+ if (stopped)
126
+ throw new Error("Sanctuary Telegram authority transport is stopped");
127
+ if (method !== "getUpdates") {
128
+ return await client.request("telegram.request", {
129
+ method,
130
+ body,
131
+ ...(currentObservation ? {
132
+ observation: {
133
+ updateId: currentObservation.payload.updateId,
134
+ observationDigest: (0, sanctuary_authority_codec_1.authorityArtifactDigest)(currentObservation.domain, currentObservation.payload),
135
+ },
136
+ } : {}),
137
+ });
138
+ }
139
+ if (!validPollBody(body))
140
+ throw new Error("Sanctuary Telegram authority poll request is invalid");
141
+ const result = await client.request("telegram.poll", {});
142
+ if (result === null)
143
+ return [];
144
+ if (!isObject(result)
145
+ || !isObject(result.observation)
146
+ || !isObject(result.observation.payload)
147
+ || !isObject(result.update)
148
+ || !Number.isSafeInteger(result.update.update_id)
149
+ || result.observation.payload.updateId !== result.update.update_id) {
150
+ throw new Error("Sanctuary Telegram authority poll response is invalid");
151
+ }
152
+ const update = result.update;
153
+ const observation = result.observation;
154
+ const verifiedMetadata = verifyObservation(observation, update, verification);
155
+ const existing = observations.get(update.update_id);
156
+ if (existing
157
+ && (0, sanctuary_authority_codec_1.authorityArtifactDigest)(existing.domain, existing.payload)
158
+ !== (0, sanctuary_authority_codec_1.authorityArtifactDigest)(observation.domain, observation.payload)) {
159
+ throw new Error("Sanctuary Telegram authority observation changed during redelivery");
160
+ }
161
+ observations.set(update.update_id, observation);
162
+ metadata.set(update.update_id, verifiedMetadata);
163
+ callbacks.set(update.update_id, result.hostCallback);
164
+ currentObservation = observation;
165
+ return [update];
166
+ },
167
+ stop() {
168
+ if (stopped)
169
+ return;
170
+ stopped = true;
171
+ client.close();
172
+ },
173
+ };
174
+ const transport = {
175
+ api,
176
+ async downloadFile(filePath) {
177
+ const result = await client.request("telegram.file", { filePath });
178
+ if (!isObject(result)
179
+ || typeof result.bodyBase64 !== "string"
180
+ || (result.contentType !== undefined && typeof result.contentType !== "string")) {
181
+ throw new Error("Sanctuary Telegram authority file response is invalid");
182
+ }
183
+ const body = Buffer.from(result.bodyBase64, "base64");
184
+ if (body.toString("base64") !== result.bodyBase64 || body.length > 20_000_000) {
185
+ throw new Error("Sanctuary Telegram authority file response is invalid");
186
+ }
187
+ return new Response(body, {
188
+ headers: result.contentType ? { "content-type": result.contentType } : undefined,
189
+ });
190
+ },
191
+ async admitChat(input) {
192
+ await client.request("telegram.chat.admit", input);
193
+ },
194
+ async revokeChat(input) {
195
+ await client.request("telegram.chat.revoke", input);
196
+ },
197
+ metadataForUpdate(update) {
198
+ const value = metadata.get(update.update_id);
199
+ if (!value)
200
+ return null;
201
+ if ((value.deliveryUpdateDigest ?? value.rawUpdateDigest) !== rawUpdateDigest(update)) {
202
+ throw new Error("Sanctuary Telegram authority update changed after verification");
203
+ }
204
+ return value;
205
+ },
206
+ async settleTransport(update, outcome) {
207
+ const observation = observations.get(update.update_id);
208
+ if (!observation)
209
+ throw new Error("Sanctuary Telegram authority observation is unavailable for settlement");
210
+ await client.request("telegram.settle", {
211
+ updateId: update.update_id,
212
+ observationDigest: (0, sanctuary_authority_codec_1.authorityArtifactDigest)(observation.domain, observation.payload),
213
+ outcome,
214
+ });
215
+ observations.delete(update.update_id);
216
+ metadata.delete(update.update_id);
217
+ callbacks.delete(update.update_id);
218
+ if (currentObservation?.payload.updateId === update.update_id)
219
+ currentObservation = null;
220
+ },
221
+ };
222
+ transport.hostApproval = (0, root_host_approval_port_1.createRootHostApprovalPort)(client, verification, {
223
+ current: () => currentObservation ? metadata.get(currentObservation.payload.updateId) : null,
224
+ lookup: (update) => {
225
+ const value = transport.metadataForUpdate(update);
226
+ return value ? { metadata: value, hostCallback: callbacks.get(update.update_id) } : null;
227
+ },
228
+ stopped: () => stopped,
229
+ });
230
+ return transport;
231
+ }