@ouro.bot/cli 0.1.0-alpha.8 → 0.1.0-alpha.800

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 (624) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -176
  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/SerpentGuide.ouro/agent.json +83 -0
  11. package/SerpentGuide.ouro/psyche/SOUL.md +25 -0
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
  13. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  14. package/assets/bluebubbles-host +264 -0
  15. package/assets/ouroboros.png +0 -0
  16. package/changelog.json +5563 -0
  17. package/deploy/unraid/Dockerfile +48 -0
  18. package/deploy/unraid/README.txt +3012 -0
  19. package/deploy/unraid/audit-container-spec.sh +4 -0
  20. package/deploy/unraid/container-runtime.json +1 -0
  21. package/deploy/unraid/docker-man-template-transaction.mjs +526 -0
  22. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  23. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  24. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  25. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  26. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  27. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  28. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  29. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  30. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  31. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  32. package/deploy/unraid/sanctuary-deployment-target.mjs +709 -0
  33. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  34. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2030 -0
  35. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  36. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  37. package/deploy/unraid/sanctuary.ouro/agent.json +24 -0
  38. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  39. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  40. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  41. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  42. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  43. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +11 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +11 -0
  47. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  48. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +23 -0
  49. package/deploy/unraid/sanctuary.xml +27 -0
  50. package/dist/a2a/card.js +57 -0
  51. package/dist/a2a/client.js +180 -0
  52. package/dist/a2a/config.js +50 -0
  53. package/dist/a2a/delegation-stores.js +56 -0
  54. package/dist/a2a/did-resolution.js +93 -0
  55. package/dist/a2a/identity.js +170 -0
  56. package/dist/a2a/inbound-share.js +107 -0
  57. package/dist/a2a/mission-result-wire.js +196 -0
  58. package/dist/a2a/onboarding.js +115 -0
  59. package/dist/a2a/pin-store.js +132 -0
  60. package/dist/a2a/seen-ledger.js +120 -0
  61. package/dist/a2a/server.js +604 -0
  62. package/dist/a2a/task-store.js +69 -0
  63. package/dist/a2a/transport.js +45 -0
  64. package/dist/a2a/types.js +3 -0
  65. package/dist/arc/attention-types.js +8 -0
  66. package/dist/arc/cares.js +360 -0
  67. package/dist/arc/episodes.js +118 -0
  68. package/dist/arc/evolution.js +490 -0
  69. package/dist/arc/flight-recorder.js +1034 -0
  70. package/dist/arc/intentions.js +134 -0
  71. package/dist/arc/json-store.js +117 -0
  72. package/dist/arc/obligations.js +386 -0
  73. package/dist/arc/packets.js +336 -0
  74. package/dist/arc/presence.js +185 -0
  75. package/dist/arc/task-lifecycle.js +57 -0
  76. package/dist/commerce/store.js +755 -0
  77. package/dist/commerce/types.js +3 -0
  78. package/dist/heart/active-work.js +1009 -0
  79. package/dist/heart/agent-entry.js +252 -3
  80. package/dist/heart/approval-files.js +113 -0
  81. package/dist/heart/approval-store.js +950 -0
  82. package/dist/heart/attachments/image-normalize.js +194 -0
  83. package/dist/heart/attachments/materialize.js +97 -0
  84. package/dist/heart/attachments/originals.js +88 -0
  85. package/dist/heart/attachments/render.js +29 -0
  86. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  87. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  88. package/dist/heart/attachments/sources/index.js +18 -0
  89. package/dist/heart/attachments/sources/telegram.js +71 -0
  90. package/dist/heart/attachments/store.js +132 -0
  91. package/dist/heart/attachments/types.js +93 -0
  92. package/dist/heart/auth/auth-flow.js +495 -0
  93. package/dist/heart/autonomy-budget.js +478 -0
  94. package/dist/heart/awaiting/await-alert.js +148 -0
  95. package/dist/heart/awaiting/await-expiry.js +143 -0
  96. package/dist/heart/awaiting/await-loader.js +91 -0
  97. package/dist/heart/awaiting/await-parser.js +149 -0
  98. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  99. package/dist/heart/awaiting/await-scheduler.js +382 -0
  100. package/dist/heart/background-operations.js +281 -0
  101. package/dist/heart/bridges/manager.js +478 -0
  102. package/dist/heart/bridges/state-machine.js +135 -0
  103. package/dist/heart/bridges/store.js +135 -0
  104. package/dist/heart/bundle-state.js +168 -0
  105. package/dist/heart/commitments.js +135 -0
  106. package/dist/heart/config-registry.js +331 -0
  107. package/dist/heart/config.js +195 -137
  108. package/dist/heart/context-loss-gauntlet.js +387 -0
  109. package/dist/heart/context-loss-sentinel.js +1157 -0
  110. package/dist/heart/core.js +2257 -338
  111. package/dist/heart/cross-chat-delivery.js +133 -0
  112. package/dist/heart/daemon/agent-config-check.js +451 -0
  113. package/dist/heart/daemon/agent-discovery.js +263 -0
  114. package/dist/heart/daemon/agent-service.js +542 -0
  115. package/dist/heart/daemon/agentic-repair.js +547 -0
  116. package/dist/heart/daemon/await-private-wake.js +59 -0
  117. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  118. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  119. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  120. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  121. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  122. package/dist/heart/daemon/cadence.js +180 -0
  123. package/dist/heart/daemon/cli-defaults.js +836 -0
  124. package/dist/heart/daemon/cli-desk.js +322 -0
  125. package/dist/heart/daemon/cli-exec.js +8730 -0
  126. package/dist/heart/daemon/cli-help.js +710 -0
  127. package/dist/heart/daemon/cli-parse.js +2719 -0
  128. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  129. package/dist/heart/daemon/cli-render.js +777 -0
  130. package/dist/heart/daemon/cli-types.js +8 -0
  131. package/dist/heart/daemon/connect-bay.js +323 -0
  132. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  133. package/dist/heart/daemon/container-healthcheck.js +112 -0
  134. package/dist/heart/daemon/container-runtime.js +97 -0
  135. package/dist/heart/daemon/container-spec-auditor-main.js +170 -0
  136. package/dist/heart/daemon/container-spec-auditor.js +236 -0
  137. package/dist/heart/daemon/daemon-bootstrap-startup.js +107 -0
  138. package/dist/heart/daemon/daemon-cli.js +30 -786
  139. package/dist/heart/daemon/daemon-entry.js +971 -13
  140. package/dist/heart/daemon/daemon-health.js +186 -0
  141. package/dist/heart/daemon/daemon-rollup.js +57 -0
  142. package/dist/heart/daemon/daemon-runtime-sync.js +287 -0
  143. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  144. package/dist/heart/daemon/daemon.js +2156 -28
  145. package/dist/heart/daemon/dns-workflow.js +394 -0
  146. package/dist/heart/daemon/doctor-types.js +8 -0
  147. package/dist/heart/daemon/doctor.js +1755 -0
  148. package/dist/heart/daemon/freshness.js +345 -0
  149. package/dist/heart/daemon/habit-private-wake.js +61 -0
  150. package/dist/heart/daemon/health-monitor.js +142 -11
  151. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  152. package/dist/heart/daemon/hooks/bundle-meta.js +226 -0
  153. package/dist/heart/daemon/http-health-probe.js +80 -0
  154. package/dist/heart/daemon/human-command-screens.js +234 -0
  155. package/dist/heart/daemon/human-readiness.js +114 -0
  156. package/dist/heart/daemon/inner-status.js +78 -0
  157. package/dist/heart/daemon/interactive-repair.js +394 -0
  158. package/dist/heart/daemon/launchd.js +188 -0
  159. package/dist/heart/daemon/log-tailer.js +82 -12
  160. package/dist/heart/daemon/logs-prune.js +132 -0
  161. package/dist/heart/daemon/mcp-canary.js +524 -0
  162. package/dist/heart/daemon/message-router.js +80 -11
  163. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  164. package/dist/heart/daemon/os-cron-deps.js +135 -0
  165. package/dist/heart/daemon/os-cron.js +22 -14
  166. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  167. package/dist/heart/daemon/ouro-entry.js +3 -1
  168. package/dist/heart/daemon/plugin-cli.js +432 -0
  169. package/dist/heart/daemon/process-manager.js +739 -54
  170. package/dist/heart/daemon/provider-discovery.js +137 -0
  171. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  172. package/dist/heart/daemon/prunable-bundle.js +144 -0
  173. package/dist/heart/daemon/pulse.js +511 -0
  174. package/dist/heart/daemon/readiness-repair.js +365 -0
  175. package/dist/heart/daemon/run-hooks.js +39 -0
  176. package/dist/heart/daemon/runtime-logging.js +92 -16
  177. package/dist/heart/daemon/runtime-metadata.js +191 -0
  178. package/dist/{repertoire/tasks/lifecycle.js → heart/daemon/runtime-mode.js} +37 -39
  179. package/dist/heart/daemon/safe-mode.js +161 -0
  180. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2609 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1866 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +976 -0
  184. package/dist/heart/daemon/sanctuary-bundle-migration.js +728 -0
  185. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  186. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  187. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  188. package/dist/heart/daemon/sense-manager.js +948 -0
  189. package/dist/heart/daemon/session-id-resolver.js +131 -0
  190. package/dist/heart/daemon/skill-management-installer.js +94 -0
  191. package/dist/heart/daemon/socket-client.js +370 -0
  192. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  193. package/dist/heart/daemon/startup-tui.js +339 -0
  194. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  195. package/dist/heart/daemon/task-scheduler.js +117 -39
  196. package/dist/heart/daemon/terminal-ui.js +499 -0
  197. package/dist/heart/daemon/thoughts.js +591 -0
  198. package/dist/heart/daemon/up-progress.js +366 -0
  199. package/dist/heart/daemon/vault-items.js +56 -0
  200. package/dist/heart/delegation.js +59 -0
  201. package/dist/heart/external-events/router.js +1414 -0
  202. package/dist/heart/habits/habit-cancel.js +810 -0
  203. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  204. package/dist/heart/habits/habit-migration.js +194 -0
  205. package/dist/heart/habits/habit-parser.js +278 -0
  206. package/dist/heart/habits/habit-runtime-state.js +93 -0
  207. package/dist/heart/habits/habit-scheduler.js +653 -0
  208. package/dist/heart/habits/habit-session-summary.js +318 -0
  209. package/dist/heart/habits/habit-session.js +636 -0
  210. package/dist/heart/{daemon → hatch}/hatch-animation.js +10 -3
  211. package/dist/heart/{daemon → hatch}/hatch-flow.js +57 -139
  212. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  213. package/dist/heart/hatch/specialist-orchestrator.js +129 -0
  214. package/dist/heart/hatch/specialist-prompt.js +102 -0
  215. package/dist/heart/hatch/specialist-tools.js +318 -0
  216. package/dist/heart/identity.js +297 -67
  217. package/dist/heart/kept-notes.js +289 -0
  218. package/dist/heart/kicks.js +2 -20
  219. package/dist/heart/machine-identity.js +161 -0
  220. package/dist/heart/mail-import-discovery.js +353 -0
  221. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  222. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  223. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  224. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  225. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  226. package/dist/heart/mailbox/mailbox-http.js +99 -0
  227. package/dist/heart/mailbox/mailbox-read.js +39 -0
  228. package/dist/heart/mailbox/mailbox-types.js +27 -0
  229. package/dist/heart/mailbox/mailbox-view.js +197 -0
  230. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  231. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  232. package/dist/heart/mailbox/readers/mail.js +375 -0
  233. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  234. package/dist/heart/mailbox/readers/sessions.js +232 -0
  235. package/dist/heart/mailbox/readers/shared.js +111 -0
  236. package/dist/heart/mcp/mcp-server.js +696 -0
  237. package/dist/heart/migrate-config.js +100 -0
  238. package/dist/heart/model-capabilities.js +59 -0
  239. package/dist/heart/orientation-frame.js +345 -0
  240. package/dist/heart/platform.js +81 -0
  241. package/dist/heart/primitives.js +1 -1
  242. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  243. package/dist/heart/private-runtime/index.js +18 -0
  244. package/dist/heart/private-runtime/ledger.js +221 -0
  245. package/dist/heart/private-runtime/policy.js +252 -0
  246. package/dist/heart/private-runtime/types.js +2 -0
  247. package/dist/heart/progress-story.js +42 -0
  248. package/dist/heart/provider-attempt.js +137 -0
  249. package/dist/heart/provider-binding-resolver.js +273 -0
  250. package/dist/heart/provider-credentials.js +449 -0
  251. package/dist/heart/provider-failover.js +311 -0
  252. package/dist/heart/provider-models.js +96 -0
  253. package/dist/heart/provider-ping.js +265 -0
  254. package/dist/heart/provider-readiness-cache.js +119 -0
  255. package/dist/heart/provider-visibility.js +188 -0
  256. package/dist/heart/providers/anthropic-token.js +131 -0
  257. package/dist/heart/providers/anthropic.js +236 -58
  258. package/dist/heart/providers/azure.js +104 -13
  259. package/dist/heart/providers/error-classification.js +127 -0
  260. package/dist/heart/providers/github-copilot.js +145 -0
  261. package/dist/heart/providers/minimax-vlm.js +189 -0
  262. package/dist/heart/providers/minimax.js +29 -7
  263. package/dist/heart/providers/openai-codex-token.js +349 -0
  264. package/dist/heart/providers/openai-codex.js +63 -39
  265. package/dist/heart/providers/openai-compatible.js +177 -0
  266. package/dist/heart/run-ledger.js +247 -0
  267. package/dist/heart/runtime-capability-check.js +170 -0
  268. package/dist/heart/runtime-credentials.js +607 -0
  269. package/dist/heart/runtime-cwd.js +87 -0
  270. package/dist/heart/sense-truth.js +79 -0
  271. package/dist/heart/session-activity.js +235 -0
  272. package/dist/heart/session-events.js +1318 -0
  273. package/dist/heart/session-playback-cli-main.js +5 -0
  274. package/dist/heart/session-playback-cli.js +36 -0
  275. package/dist/heart/session-playback.js +231 -0
  276. package/dist/heart/session-stats-cli-main.js +5 -0
  277. package/dist/heart/session-stats.js +182 -0
  278. package/dist/heart/session-transcript.js +133 -0
  279. package/dist/heart/start-of-turn-packet.js +372 -0
  280. package/dist/heart/steward-policy.js +302 -0
  281. package/dist/heart/streaming.js +682 -207
  282. package/dist/heart/structured-output.js +196 -0
  283. package/dist/heart/sync-classification.js +176 -0
  284. package/dist/heart/sync.js +449 -0
  285. package/dist/heart/target-resolution.js +127 -0
  286. package/dist/heart/tempo.js +93 -0
  287. package/dist/heart/temporal-view.js +41 -0
  288. package/dist/heart/timeouts.js +101 -0
  289. package/dist/heart/tool-activity-callbacks.js +59 -0
  290. package/dist/heart/tool-approval.js +342 -0
  291. package/dist/heart/tool-description.js +155 -0
  292. package/dist/heart/tool-friction.js +55 -0
  293. package/dist/heart/tool-loop.js +200 -0
  294. package/dist/heart/turn-context.js +481 -0
  295. package/dist/heart/turn-coordinator.js +28 -0
  296. package/dist/heart/versioning/ouro-bot-global-installer.js +129 -0
  297. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  298. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  299. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  300. package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
  301. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  302. package/dist/heart/versioning/staged-restart.js +146 -0
  303. package/dist/heart/versioning/update-checker.js +116 -0
  304. package/dist/heart/versioning/update-hooks.js +154 -0
  305. package/dist/heart/versioning/version-intent.js +114 -0
  306. package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
  307. package/dist/heart/work-card.js +380 -0
  308. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  309. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  310. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  311. package/dist/mailbox-ui/index.html +16 -0
  312. package/dist/mailroom/attention.js +167 -0
  313. package/dist/mailroom/autonomy.js +209 -0
  314. package/dist/mailroom/blob-store.js +889 -0
  315. package/dist/mailroom/body-cache.js +61 -0
  316. package/dist/mailroom/cache-sync-cli.js +58 -0
  317. package/dist/mailroom/core.js +803 -0
  318. package/dist/mailroom/entry.js +160 -0
  319. package/dist/mailroom/file-store.js +568 -0
  320. package/dist/mailroom/hosted-cache-sync.js +384 -0
  321. package/dist/mailroom/mbox-import.js +393 -0
  322. package/dist/mailroom/migration.js +164 -0
  323. package/dist/mailroom/outbound.js +380 -0
  324. package/dist/mailroom/policy.js +263 -0
  325. package/dist/mailroom/reader.js +292 -0
  326. package/dist/mailroom/search-cache.js +513 -0
  327. package/dist/mailroom/search-relevance.js +319 -0
  328. package/dist/mailroom/smtp-ingress.js +176 -0
  329. package/dist/mailroom/source-state.js +176 -0
  330. package/dist/mailroom/thread.js +109 -0
  331. package/dist/mailroom/travel-extract.js +89 -0
  332. package/dist/mind/bundle-manifest.js +93 -1
  333. package/dist/mind/context.js +287 -104
  334. package/dist/mind/desk-section.js +362 -0
  335. package/dist/mind/diary-integrity.js +60 -0
  336. package/dist/mind/{memory.js → diary.js} +90 -98
  337. package/dist/mind/embedding-provider.js +60 -0
  338. package/dist/mind/file-state.js +179 -0
  339. package/dist/mind/first-impressions.js +16 -2
  340. package/dist/mind/{associative-recall.js → note-search.js} +61 -60
  341. package/dist/mind/obligation-steering.js +227 -0
  342. package/dist/mind/pending.js +102 -9
  343. package/dist/mind/phrases.js +1 -0
  344. package/dist/mind/prompt-budget.js +479 -0
  345. package/dist/mind/prompt-refresh.js +3 -2
  346. package/dist/mind/prompt.js +1377 -140
  347. package/dist/mind/provenance-trust.js +26 -0
  348. package/dist/mind/record-paths.js +312 -0
  349. package/dist/mind/scrutiny.js +173 -0
  350. package/dist/mind/session-transaction.js +415 -0
  351. package/dist/mind/token-estimate.js +8 -12
  352. package/dist/nerves/cli-logging.js +22 -3
  353. package/dist/nerves/coverage/audit-rules.js +15 -6
  354. package/dist/nerves/coverage/audit.js +28 -2
  355. package/dist/nerves/coverage/cli.js +1 -1
  356. package/dist/nerves/coverage/contract.js +5 -5
  357. package/dist/nerves/coverage/file-completeness.js +139 -5
  358. package/dist/nerves/coverage/run-artifacts.js +56 -36
  359. package/dist/nerves/coverage/source-scanner.js +4 -4
  360. package/dist/nerves/event-buffer.js +111 -0
  361. package/dist/nerves/index.js +305 -9
  362. package/dist/nerves/observation.js +20 -0
  363. package/dist/nerves/redact.js +79 -0
  364. package/dist/nerves/review/cli-main.js +5 -0
  365. package/dist/nerves/review/cli.js +156 -0
  366. package/dist/nerves/review/core.js +159 -0
  367. package/dist/nerves/runtime.js +17 -1
  368. package/dist/repertoire/ado-client.js +17 -56
  369. package/dist/repertoire/ado-semantic.js +16 -10
  370. package/dist/repertoire/api-client.js +97 -0
  371. package/dist/repertoire/bitwarden-store.js +1045 -0
  372. package/dist/repertoire/bundle-templates.js +71 -0
  373. package/dist/repertoire/bw-installer.js +180 -0
  374. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  375. package/dist/repertoire/coding/context-pack.js +331 -0
  376. package/dist/repertoire/coding/feedback.js +322 -0
  377. package/dist/repertoire/coding/index.js +18 -3
  378. package/dist/repertoire/coding/manager.js +228 -14
  379. package/dist/repertoire/coding/spawner.js +61 -14
  380. package/dist/repertoire/coding/tools.js +279 -12
  381. package/dist/repertoire/coding/workbench-client.js +272 -0
  382. package/dist/repertoire/coding/workbench-manager.js +346 -0
  383. package/dist/repertoire/commerce-errors.js +109 -0
  384. package/dist/repertoire/commerce-self-test.js +156 -0
  385. package/dist/repertoire/credential-access.js +178 -0
  386. package/dist/repertoire/data/ado-endpoints.json +188 -0
  387. package/dist/repertoire/desk/classifier.js +362 -0
  388. package/dist/repertoire/duffel-client.js +185 -0
  389. package/dist/repertoire/github-client.js +14 -55
  390. package/dist/repertoire/graph-client.js +11 -52
  391. package/dist/repertoire/guardrails.js +1083 -0
  392. package/dist/repertoire/mcp-client.js +295 -0
  393. package/dist/repertoire/mcp-manager.js +434 -0
  394. package/dist/repertoire/mcp-tools.js +83 -0
  395. package/dist/repertoire/plugin-mcp.js +175 -0
  396. package/dist/repertoire/plugins.js +253 -0
  397. package/dist/repertoire/relationship-authorization.js +194 -0
  398. package/dist/repertoire/shell-sessions.js +133 -0
  399. package/dist/repertoire/skills.js +45 -24
  400. package/dist/repertoire/stripe-client.js +131 -0
  401. package/dist/repertoire/tool-arguments.js +148 -0
  402. package/dist/repertoire/tool-results.js +29 -0
  403. package/dist/repertoire/tools-a2a.js +699 -0
  404. package/dist/repertoire/tools-attachments.js +322 -0
  405. package/dist/repertoire/tools-awaiting.js +575 -0
  406. package/dist/repertoire/tools-base.js +85 -707
  407. package/dist/repertoire/tools-bluebubbles.js +95 -0
  408. package/dist/repertoire/tools-bridge.js +144 -0
  409. package/dist/repertoire/tools-bundle.js +993 -0
  410. package/dist/repertoire/tools-commerce.js +253 -0
  411. package/dist/repertoire/tools-config.js +186 -0
  412. package/dist/repertoire/tools-continuity.js +575 -0
  413. package/dist/repertoire/tools-credential.js +383 -0
  414. package/dist/repertoire/tools-evolution.js +527 -0
  415. package/dist/repertoire/tools-files.js +344 -0
  416. package/dist/repertoire/tools-flight.js +290 -0
  417. package/dist/repertoire/tools-flow.js +119 -0
  418. package/dist/repertoire/tools-github.js +3 -8
  419. package/dist/repertoire/tools-habits.js +103 -0
  420. package/dist/repertoire/tools-mail.js +1828 -0
  421. package/dist/repertoire/tools-notes.js +485 -0
  422. package/dist/repertoire/tools-obligations.js +182 -0
  423. package/dist/repertoire/tools-orientation.js +31 -0
  424. package/dist/repertoire/tools-record.js +482 -0
  425. package/dist/repertoire/tools-rsvp.js +139 -0
  426. package/dist/repertoire/tools-runtime.js +150 -0
  427. package/dist/repertoire/tools-session.js +1108 -0
  428. package/dist/repertoire/tools-shell.js +133 -0
  429. package/dist/repertoire/tools-steward-policy.js +95 -0
  430. package/dist/repertoire/tools-stripe.js +224 -0
  431. package/dist/repertoire/tools-surface.js +369 -0
  432. package/dist/repertoire/tools-teams.js +67 -61
  433. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  434. package/dist/repertoire/tools-travel.js +125 -0
  435. package/dist/repertoire/tools-trip.js +982 -0
  436. package/dist/repertoire/tools-unraid.js +484 -0
  437. package/dist/repertoire/tools-user-profile.js +146 -0
  438. package/dist/repertoire/tools-vault.js +40 -0
  439. package/dist/repertoire/tools-voice.js +145 -0
  440. package/dist/repertoire/tools.js +441 -102
  441. package/dist/repertoire/travel-api-client.js +360 -0
  442. package/dist/repertoire/unraid-client.js +155 -0
  443. package/dist/repertoire/unraid-restart.js +212 -0
  444. package/dist/repertoire/user-profile.js +131 -0
  445. package/dist/repertoire/vault-setup.js +246 -0
  446. package/dist/repertoire/vault-unlock.js +628 -0
  447. package/dist/rsvp/aisleplanner-client.js +354 -0
  448. package/dist/rsvp/cli.js +926 -0
  449. package/dist/rsvp/config.js +327 -0
  450. package/dist/rsvp/cutover.js +433 -0
  451. package/dist/rsvp/diagnostics.js +232 -0
  452. package/dist/rsvp/diff-renderer.js +176 -0
  453. package/dist/rsvp/habit-policy.js +110 -0
  454. package/dist/rsvp/habit-stage.js +123 -0
  455. package/dist/rsvp/incident-bundle.js +97 -0
  456. package/dist/rsvp/migration.js +204 -0
  457. package/dist/rsvp/native-habit-runner.js +630 -0
  458. package/dist/rsvp/outbound-state.js +628 -0
  459. package/dist/rsvp/query.js +118 -0
  460. package/dist/rsvp/replay.js +233 -0
  461. package/dist/rsvp/snapshot.js +232 -0
  462. package/dist/rsvp/spend-ledger.js +175 -0
  463. package/dist/scripts/claude-code-hook.js +41 -0
  464. package/dist/scripts/claude-code-stop-hook.js +47 -0
  465. package/dist/senses/a2a-entry.js +115 -0
  466. package/dist/senses/attention-queue.js +186 -0
  467. package/dist/senses/await-turn-message.js +58 -0
  468. package/dist/senses/bluebubbles/active-turns.js +216 -0
  469. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  470. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  471. package/dist/senses/bluebubbles/client.js +799 -0
  472. package/dist/senses/bluebubbles/context-packet.js +207 -0
  473. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  474. package/dist/senses/bluebubbles/entry.js +90 -0
  475. package/dist/senses/bluebubbles/inbound-log.js +127 -0
  476. package/dist/senses/bluebubbles/index.js +3839 -0
  477. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  478. package/dist/senses/bluebubbles/media.js +389 -0
  479. package/dist/senses/bluebubbles/model.js +392 -0
  480. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +57 -6
  481. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  482. package/dist/senses/bluebubbles/processed-log.js +133 -0
  483. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  484. package/dist/senses/bluebubbles/replay.js +284 -0
  485. package/dist/senses/bluebubbles/runtime-state.js +137 -0
  486. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  487. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  488. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  489. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  490. package/dist/senses/cli/bracketed-paste.js +82 -0
  491. package/dist/senses/cli/image-paste.js +287 -0
  492. package/dist/senses/cli/image-ref-navigation.js +75 -0
  493. package/dist/senses/cli/ink-app.js +156 -0
  494. package/dist/senses/cli/inline-diff.js +64 -0
  495. package/dist/senses/cli/input-keys.js +174 -0
  496. package/dist/senses/cli/kill-ring.js +86 -0
  497. package/dist/senses/cli/message-list.js +51 -0
  498. package/dist/senses/cli/ouro-tui.js +607 -0
  499. package/dist/senses/cli/spinner-imperative.js +135 -0
  500. package/dist/senses/cli/spinner.js +101 -0
  501. package/dist/senses/cli/status-line.js +60 -0
  502. package/dist/senses/cli/streaming-markdown.js +526 -0
  503. package/dist/senses/cli/tool-display.js +85 -0
  504. package/dist/senses/cli/tool-render.js +85 -0
  505. package/dist/senses/cli/tui-store.js +241 -0
  506. package/dist/senses/cli/virtual-list.js +35 -0
  507. package/dist/senses/cli-entry.js +60 -8
  508. package/dist/senses/cli-layout.js +187 -0
  509. package/dist/senses/cli.js +813 -281
  510. package/dist/senses/commands.js +66 -3
  511. package/dist/senses/context-packet-ledger.js +371 -0
  512. package/dist/senses/context-packets.js +154 -0
  513. package/dist/senses/continuity.js +94 -0
  514. package/dist/senses/habit-lifecycle-guard.js +24 -0
  515. package/dist/senses/habit-turn-message.js +160 -0
  516. package/dist/senses/ingress-evidence.js +2 -0
  517. package/dist/senses/mail-entry.js +66 -0
  518. package/dist/senses/mail.js +524 -0
  519. package/dist/senses/pipeline.js +1213 -0
  520. package/dist/senses/private-runtime-worker.js +859 -0
  521. package/dist/senses/private-runtime.js +1496 -0
  522. package/dist/senses/proactive-content-guard.js +51 -0
  523. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  524. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  525. package/dist/senses/sanctuary-grounding.js +118 -0
  526. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  527. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  528. package/dist/senses/sanctuary-health-runner.js +101 -0
  529. package/dist/senses/sanctuary-health.js +408 -0
  530. package/dist/senses/sanctuary-interactive-control.js +306 -0
  531. package/dist/senses/sanctuary-media-catalog-contract.js +235 -0
  532. package/dist/senses/sanctuary-media-optimization.js +514 -0
  533. package/dist/senses/sanctuary-runtime.js +338 -0
  534. package/dist/senses/sanctuary-sab.js +85 -0
  535. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  536. package/dist/senses/shared-turn.js +571 -0
  537. package/dist/senses/surface-tool.js +109 -0
  538. package/dist/senses/teams-entry.js +60 -8
  539. package/dist/senses/teams.js +953 -211
  540. package/dist/senses/telegram-admission.js +711 -0
  541. package/dist/senses/telegram-approval-runtime.js +566 -0
  542. package/dist/senses/telegram-attachments.js +182 -0
  543. package/dist/senses/telegram-audit-ledger.js +220 -0
  544. package/dist/senses/telegram-client.js +1677 -0
  545. package/dist/senses/telegram-effect-adapter.js +859 -0
  546. package/dist/senses/telegram-entry.js +83 -0
  547. package/dist/senses/telegram.js +2026 -0
  548. package/dist/senses/trust-gate.js +207 -2
  549. package/dist/senses/voice/audio-playback.js +237 -0
  550. package/dist/senses/voice/audio-routing.js +119 -0
  551. package/dist/senses/voice/elevenlabs.js +202 -0
  552. package/dist/senses/voice/floor-control.js +431 -0
  553. package/dist/senses/voice/floor-controller.js +115 -0
  554. package/dist/senses/voice/golden-path.js +116 -0
  555. package/dist/senses/voice/index.js +29 -0
  556. package/dist/senses/voice/meeting.js +113 -0
  557. package/dist/senses/voice/outbound.js +190 -0
  558. package/dist/senses/voice/phone.js +33 -0
  559. package/dist/senses/voice/playback.js +139 -0
  560. package/dist/senses/voice/realtime-eval.js +496 -0
  561. package/dist/senses/voice/realtime-trace.js +531 -0
  562. package/dist/senses/voice/transcript.js +70 -0
  563. package/dist/senses/voice/turn.js +191 -0
  564. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  565. package/dist/senses/voice/twilio-phone.js +5081 -0
  566. package/dist/senses/voice/types.js +2 -0
  567. package/dist/senses/voice/whisper.js +161 -0
  568. package/dist/senses/voice-entry.js +81 -0
  569. package/dist/senses/voice-realtime-eval-command.js +99 -0
  570. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  571. package/dist/senses/voice-twilio-entry.js +87 -0
  572. package/dist/trips/core.js +138 -0
  573. package/dist/trips/store.js +265 -0
  574. package/dist/util/frontmatter.js +69 -0
  575. package/npm-shrinkwrap.json +8144 -0
  576. package/package.json +82 -12
  577. package/skills/agent-commerce.md +113 -0
  578. package/skills/browser-navigation.md +117 -0
  579. package/skills/commerce-setup-guide.md +116 -0
  580. package/skills/commerce-setup.md +84 -0
  581. package/skills/configure-dev-tools.md +99 -0
  582. package/skills/travel-planning.md +138 -0
  583. package/AdoptionSpecialist.ouro/agent.json +0 -20
  584. package/AdoptionSpecialist.ouro/psyche/SOUL.md +0 -22
  585. package/dist/heart/daemon/specialist-orchestrator.js +0 -160
  586. package/dist/heart/daemon/specialist-prompt.js +0 -47
  587. package/dist/heart/daemon/specialist-session.js +0 -142
  588. package/dist/heart/daemon/specialist-tools.js +0 -132
  589. package/dist/heart/daemon/subagent-installer.js +0 -125
  590. package/dist/inner-worker-entry.js +0 -4
  591. package/dist/mind/friends/channel.js +0 -49
  592. package/dist/mind/friends/resolver.js +0 -84
  593. package/dist/mind/friends/store-file.js +0 -171
  594. package/dist/mind/friends/store.js +0 -4
  595. package/dist/mind/friends/tokens.js +0 -26
  596. package/dist/mind/friends/types.js +0 -21
  597. package/dist/repertoire/tasks/board.js +0 -122
  598. package/dist/repertoire/tasks/index.js +0 -210
  599. package/dist/repertoire/tasks/middleware.js +0 -65
  600. package/dist/repertoire/tasks/parser.js +0 -173
  601. package/dist/repertoire/tasks/scanner.js +0 -132
  602. package/dist/repertoire/tasks/transitions.js +0 -145
  603. package/dist/senses/bluebubbles-client.js +0 -279
  604. package/dist/senses/bluebubbles-entry.js +0 -11
  605. package/dist/senses/bluebubbles-model.js +0 -253
  606. package/dist/senses/bluebubbles.js +0 -332
  607. package/dist/senses/inner-dialog-worker.js +0 -61
  608. package/dist/senses/inner-dialog.js +0 -231
  609. package/subagents/README.md +0 -73
  610. package/subagents/work-doer.md +0 -233
  611. package/subagents/work-merger.md +0 -624
  612. package/subagents/work-planner.md +0 -373
  613. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  614. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  615. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  616. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  617. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  618. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  619. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  620. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  621. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  622. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  623. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  624. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
@@ -0,0 +1,369 @@
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.surfaceToolDefinition = exports.surfaceToolDef = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const crypto_1 = require("crypto");
39
+ const config_1 = require("../heart/config");
40
+ const identity_1 = require("../heart/identity");
41
+ const surface_tool_1 = require("../senses/surface-tool");
42
+ const obligations_1 = require("../arc/obligations");
43
+ const packets_1 = require("../arc/packets");
44
+ const session_activity_1 = require("../heart/session-activity");
45
+ const bluebubbles_meta_guard_1 = require("../senses/bluebubbles-meta-guard");
46
+ const runtime_1 = require("../nerves/runtime");
47
+ const path = __importStar(require("path"));
48
+ const outbound_1 = require("../senses/voice/outbound");
49
+ /* v8 ignore start -- surface voice delivery hints are covered at the outbound voice bridge; this adapter only normalizes optional tool args @preserve */
50
+ function normalizeSurfaceDeliveryChannel(value) {
51
+ if (typeof value !== "string")
52
+ return "auto";
53
+ const normalized = value.trim().toLowerCase();
54
+ return normalized === "voice" ? "voice" : "auto";
55
+ }
56
+ function parseSurfaceVoiceInitialAudio(args) {
57
+ const source = args.voiceAudioSource === "url" || args.voiceAudioSource === "file" || args.voiceAudioSource === "tone"
58
+ ? args.voiceAudioSource
59
+ : undefined;
60
+ const hasAudioHint = Boolean(source
61
+ || args.voiceAudioUrl?.trim()
62
+ || args.voiceAudioPath?.trim()
63
+ || args.voiceAudioLabel?.trim()
64
+ || args.voiceAudioToneHz?.trim()
65
+ || args.voiceAudioDurationMs?.trim());
66
+ if (!hasAudioHint)
67
+ return undefined;
68
+ const toneHz = args.voiceAudioToneHz?.trim() ? Number(args.voiceAudioToneHz) : undefined;
69
+ const durationMs = args.voiceAudioDurationMs?.trim() ? Number(args.voiceAudioDurationMs) : undefined;
70
+ return {
71
+ source: source ?? "tone",
72
+ ...(args.voiceAudioUrl?.trim() ? { url: args.voiceAudioUrl.trim() } : {}),
73
+ ...(args.voiceAudioPath?.trim() ? { path: args.voiceAudioPath.trim() } : {}),
74
+ ...(args.voiceAudioLabel?.trim() ? { label: args.voiceAudioLabel.trim() } : {}),
75
+ ...(Number.isFinite(toneHz) ? { toneHz } : {}),
76
+ ...(Number.isFinite(durationMs) ? { durationMs } : {}),
77
+ };
78
+ }
79
+ /* v8 ignore stop */
80
+ // Surface tool schema — canonical home. Handler lives in senses/surface-tool.ts.
81
+ exports.surfaceToolDef = {
82
+ type: "function",
83
+ function: {
84
+ name: "surface",
85
+ description: "return a ready thought to a friend or active session without publishing private-runtime work to BlueBubbles. pass delegationId to address a held thought (see your attention queue above), or friendId for spontaneous outreach. Surface delivers tool responses to the active session. BlueBubbles is a dedicated channel - use send_message with channel=\"bluebubbles\" for intentional iMessage delivery. set channel=voice only when you intentionally want a live phone call; content becomes the call reason/opening context. does not end your turn.",
86
+ parameters: {
87
+ type: "object",
88
+ properties: {
89
+ content: {
90
+ type: "string",
91
+ description: "the message to deliver",
92
+ },
93
+ delegationId: {
94
+ type: "string",
95
+ description: "ID from your attention queue — addresses a specific held thought",
96
+ },
97
+ friendId: {
98
+ type: "string",
99
+ description: "friend to reach out to spontaneously (when not addressing a held thought)",
100
+ },
101
+ channel: {
102
+ type: "string",
103
+ enum: ["auto", "voice"],
104
+ description: "optional delivery channel; use voice for a live phone call to a trusted friend, otherwise omit",
105
+ },
106
+ phoneNumber: {
107
+ type: "string",
108
+ description: "optional E.164 phone override for channel=voice when the trusted friend's record has no usable phone handle",
109
+ },
110
+ voiceAudioSource: {
111
+ type: "string",
112
+ enum: ["tone", "url", "file"],
113
+ description: "optional initial non-speech audio to play after the opening greeting when channel=voice",
114
+ },
115
+ voiceAudioUrl: {
116
+ type: "string",
117
+ description: "short audio URL for voiceAudioSource=url",
118
+ },
119
+ voiceAudioPath: {
120
+ type: "string",
121
+ description: "local audio file path for voiceAudioSource=file",
122
+ },
123
+ voiceAudioLabel: {
124
+ type: "string",
125
+ description: "short label for the initial voice audio",
126
+ },
127
+ voiceAudioToneHz: {
128
+ type: "number",
129
+ description: "tone frequency for voiceAudioSource=tone",
130
+ },
131
+ voiceAudioDurationMs: {
132
+ type: "number",
133
+ description: "initial audio duration in milliseconds",
134
+ },
135
+ },
136
+ required: ["content"],
137
+ },
138
+ },
139
+ };
140
+ // Surface tool handler: routes content to friend's freshest session
141
+ /* v8 ignore start -- surface handler wiring: core logic tested via surface-tool.test.ts; this wires identity/routing deps @preserve */
142
+ exports.surfaceToolDefinition = {
143
+ tool: exports.surfaceToolDef,
144
+ handler: async (args, ctx) => {
145
+ const rawContent = args.content ?? "";
146
+ const deliveryHint = {
147
+ channel: normalizeSurfaceDeliveryChannel(args.channel),
148
+ phoneNumber: typeof args.phoneNumber === "string" ? args.phoneNumber : undefined,
149
+ initialAudio: parseSurfaceVoiceInitialAudio(args),
150
+ };
151
+ if ((0, bluebubbles_meta_guard_1.containsInternalMetaMarkers)(rawContent)) {
152
+ (0, runtime_1.emitNervesEvent)({
153
+ level: "warn",
154
+ component: "repertoire",
155
+ event: "tools.surface_meta_blocked",
156
+ message: "surface tool blocked: internal meta markers in content",
157
+ meta: {
158
+ hasDelegationId: Boolean(args.delegationId),
159
+ hasFriendId: Boolean(args.friendId),
160
+ contentLength: rawContent.length,
161
+ },
162
+ });
163
+ return "failed — blocked: contains internal meta markers";
164
+ }
165
+ const queue = ctx?.delegatedOrigins ?? [];
166
+ const agentName = (() => { try {
167
+ return (0, identity_1.getAgentName)();
168
+ }
169
+ catch {
170
+ return "unknown";
171
+ } })();
172
+ const routeToFriend = async (friendId, content, queueItem, hint) => {
173
+ /* v8 ignore start -- routing: integration path tested via private-runtime routing tests @preserve */
174
+ try {
175
+ const agentRoot = (0, identity_1.getAgentRoot)();
176
+ const sessionsDir = path.join(agentRoot, "state", "sessions");
177
+ const friendsDir = path.join(agentRoot, "friends");
178
+ const queueToSession = async (target, detail) => {
179
+ const { queuePendingMessage, getPendingDir } = await Promise.resolve().then(() => __importStar(require("../mind/pending")));
180
+ const pendingDir = getPendingDir(agentName, target.friendId, target.channel, target.key);
181
+ queuePendingMessage(pendingDir, {
182
+ from: agentName,
183
+ friendId: target.friendId,
184
+ channel: target.channel,
185
+ key: target.key,
186
+ content,
187
+ timestamp: Date.now(),
188
+ });
189
+ return { status: "queued", detail };
190
+ };
191
+ const deliverTelegramOrQueue = async (target, detail) => {
192
+ const telegramKey = (0, config_1.canonicalizeTelegramSessionKey)(target.key);
193
+ const hash = (0, crypto_1.createHash)("sha256").update(`${target.friendId}\0${telegramKey}\0${content}`).digest("hex");
194
+ const requestId = queueItem?.obligationId ?? `surface:${hash}`;
195
+ const deliveryId = queueItem?.obligationId ? `surface:${queueItem.obligationId}:${hash}` : `surface:${hash}`;
196
+ const { sendTelegramAwaitFollowUp } = await Promise.resolve().then(() => __importStar(require("../senses/telegram")));
197
+ const delivered = await sendTelegramAwaitFollowUp(agentName, {
198
+ friendId: target.friendId,
199
+ channel: "telegram",
200
+ key: telegramKey,
201
+ content,
202
+ requestId,
203
+ deliveryId,
204
+ intent: "generic_outreach",
205
+ });
206
+ return delivered.status === "delivered_now"
207
+ ? { status: "delivered", detail: "sent to Telegram now" }
208
+ : queueToSession(target, detail);
209
+ };
210
+ // Resolve friend name → UUID if needed (agents may pass name instead of UUID)
211
+ let resolvedFriendId = friendId;
212
+ if (!fs.existsSync(path.join(sessionsDir, friendId))) {
213
+ try {
214
+ const friendFiles = fs.readdirSync(friendsDir).filter((f) => f.endsWith(".json"));
215
+ for (const file of friendFiles) {
216
+ const raw = fs.readFileSync(path.join(friendsDir, file), "utf-8");
217
+ const record = JSON.parse(raw);
218
+ if (record.name?.toLowerCase() === friendId.toLowerCase() && record.id) {
219
+ resolvedFriendId = record.id;
220
+ break;
221
+ }
222
+ }
223
+ }
224
+ catch { /* friends dir unreadable — continue with original friendId */ }
225
+ }
226
+ friendId = resolvedFriendId;
227
+ if (hint?.channel === "voice") {
228
+ const voiceResult = await (0, outbound_1.placeTrustedFriendVoiceOutboundCall)({
229
+ agentName,
230
+ agentRoot,
231
+ friendId,
232
+ reason: content,
233
+ phoneNumber: hint.phoneNumber,
234
+ ...(hint.initialAudio ? { initialAudio: hint.initialAudio } : {}),
235
+ });
236
+ return voiceResult.status === "placed"
237
+ ? { status: "delivered", detail: voiceResult.detail }
238
+ : { status: "failed", detail: voiceResult.detail };
239
+ }
240
+ // Priority 1: Bridge-preferred session (if queue item has a bridgeId)
241
+ if (queueItem?.bridgeId) {
242
+ const { createBridgeManager } = await Promise.resolve().then(() => __importStar(require("../heart/bridges/manager")));
243
+ const bridge = createBridgeManager().getBridge(queueItem.bridgeId);
244
+ if (bridge && bridge.lifecycle !== "completed" && bridge.lifecycle !== "cancelled") {
245
+ const allSessions = (0, session_activity_1.listSessionActivity)({ sessionsDir, friendsDir, agentName, activeThresholdMs: Number.MAX_SAFE_INTEGER });
246
+ const bridgeTarget = allSessions.find((activity) => activity.friendId === friendId
247
+ && activity.channel !== "inner"
248
+ && bridge.attachedSessions.some((s) => s.friendId === activity.friendId && s.channel === activity.channel && s.key === activity.key));
249
+ if (bridgeTarget) {
250
+ const detail = `for next interaction via ${bridgeTarget.channel}`;
251
+ return bridgeTarget.channel === "telegram"
252
+ ? deliverTelegramOrQueue(bridgeTarget, detail)
253
+ : queueToSession(bridgeTarget, detail);
254
+ }
255
+ }
256
+ }
257
+ // Priority 1.5: exact held-work origin.
258
+ // A delegated return has a concrete reply address. Preserve that
259
+ // address before considering fresher sessions for the same friend,
260
+ // especially MCP sessions where check_response drains this path.
261
+ if (queueItem?.channel && queueItem.key && queueItem.channel !== "inner") {
262
+ const target = { friendId, channel: queueItem.channel, key: queueItem.key };
263
+ const detail = `for originating ${queueItem.channel} session`;
264
+ return queueItem.channel === "telegram"
265
+ ? deliverTelegramOrQueue(target, detail)
266
+ : queueToSession(target, detail);
267
+ }
268
+ // Priority 2: Try proactive delivery first, then queue to freshest session
269
+ const allFriendSessions = (0, session_activity_1.listSessionActivity)({ sessionsDir, friendsDir, agentName, activeThresholdMs: Number.MAX_SAFE_INTEGER })
270
+ .filter((s) => s.friendId === friendId && s.channel !== "inner");
271
+ // Priority 2: Queue to freshest non-private-runtime session
272
+ const freshest = allFriendSessions[0];
273
+ if (freshest) {
274
+ const detail = `for next interaction via ${freshest.channel}`;
275
+ return freshest.channel === "telegram"
276
+ ? deliverTelegramOrQueue(freshest, detail)
277
+ : queueToSession(freshest, detail);
278
+ }
279
+ // Priority 3: Deferred — no active session found
280
+ const { getDeferredReturnDir } = await Promise.resolve().then(() => __importStar(require("../mind/pending")));
281
+ const { queuePendingMessage: queueDeferred } = await Promise.resolve().then(() => __importStar(require("../mind/pending")));
282
+ const deferredDir = getDeferredReturnDir(agentName, friendId);
283
+ queueDeferred(deferredDir, {
284
+ from: agentName,
285
+ friendId,
286
+ channel: "deferred",
287
+ key: "return",
288
+ content,
289
+ timestamp: Date.now(),
290
+ });
291
+ return { status: "deferred", detail: "they'll see it next time" };
292
+ }
293
+ catch {
294
+ return { status: "failed" };
295
+ }
296
+ /* v8 ignore stop */
297
+ };
298
+ return (0, surface_tool_1.handleSurface)({
299
+ content: args.content ?? "",
300
+ delegationId: args.delegationId,
301
+ friendId: args.friendId,
302
+ deliveryHint: deliveryHint.channel === "voice" || deliveryHint.phoneNumber ? deliveryHint : undefined,
303
+ queue,
304
+ routeToFriend,
305
+ advanceObligation: (obligationId, update) => {
306
+ /* v8 ignore start -- obligation advance: tested via attention-queue tests @preserve */
307
+ try {
308
+ const name = (() => { try {
309
+ return (0, identity_1.getAgentName)();
310
+ }
311
+ catch {
312
+ return "unknown";
313
+ } })();
314
+ (0, obligations_1.advanceReturnObligation)(name, obligationId, {
315
+ status: update.status,
316
+ ...(update.returnedAt !== undefined ? { returnedAt: update.returnedAt } : {}),
317
+ ...(update.returnTarget !== undefined ? { returnTarget: update.returnTarget } : {}),
318
+ });
319
+ }
320
+ catch {
321
+ // swallowed — obligation advance must never break surface delivery
322
+ }
323
+ /* v8 ignore stop */
324
+ },
325
+ completePonderPacket: (packetId) => {
326
+ /* v8 ignore start -- packet completion: tested via surface-tool and arc packet unit tests @preserve */
327
+ try {
328
+ (0, packets_1.completePonderPacket)((0, identity_1.getAgentRoot)(), packetId);
329
+ }
330
+ catch {
331
+ // swallowed — packet completion must never break surface delivery
332
+ }
333
+ /* v8 ignore stop */
334
+ },
335
+ fulfillHeartObligation: (origin) => {
336
+ /* v8 ignore start -- heart obligation fulfillment: tested via surface-tool.test.ts @preserve */
337
+ try {
338
+ const agentRoot = (0, identity_1.getAgentRoot)();
339
+ const heartObligation = (0, obligations_1.findPendingObligationForOrigin)(agentRoot, origin);
340
+ if (heartObligation) {
341
+ (0, obligations_1.fulfillObligation)(agentRoot, heartObligation.id);
342
+ }
343
+ }
344
+ catch {
345
+ // swallowed — heart obligation fulfillment must never break surface delivery
346
+ }
347
+ /* v8 ignore stop */
348
+ },
349
+ onRouteResult: ({ targetFriendId, queueItem, result }) => {
350
+ ctx?.habitSession?.recordSurfaceAttempt?.({
351
+ recipient: targetFriendId,
352
+ channel: queueItem?.channel ?? args.channel ?? "surface",
353
+ reason: result.status === "failed" ? "blocked" : "answer",
354
+ result: result.status,
355
+ rawStatus: result.status,
356
+ ...(queueItem ? { routeKind: "originator" } : {}),
357
+ ...(result.status === "failed" ? { error: result.detail ?? "surface route failed" } : {}),
358
+ });
359
+ },
360
+ });
361
+ },
362
+ summaryKeys: ["content", "delegationId", "friendId", "channel"],
363
+ riskProfile: {
364
+ mutates: ["durable_state_write", "external_side_effect"],
365
+ risk: "high",
366
+ reason: "queues or delivers surfaced responses and may fulfill obligations",
367
+ },
368
+ };
369
+ /* v8 ignore stop */
@@ -3,24 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.teamsToolHandlers = exports.teamsTools = exports.teamsToolDefinitions = void 0;
7
- exports.summarizeTeamsArgs = summarizeTeamsArgs;
6
+ exports.teamsToolDefinitions = void 0;
8
7
  const graph_client_1 = require("./graph-client");
9
8
  const ado_client_1 = require("./ado-client");
10
9
  const graph_endpoints_json_1 = __importDefault(require("./data/graph-endpoints.json"));
11
10
  const ado_endpoints_json_1 = __importDefault(require("./data/ado-endpoints.json"));
12
11
  const runtime_1 = require("../nerves/runtime");
13
12
  const MUTATE_METHODS = ["POST", "PATCH", "DELETE"];
14
- // Map HTTP method to authority action name for canWrite() checks
15
- const METHOD_TO_ACTION = {
16
- POST: "createWorkItem",
17
- PATCH: "updateWorkItem",
18
- DELETE: "deleteWorkItem",
19
- };
20
- // Check if a tool response indicates a 403 PERMISSION_DENIED (authority checker removed; this is now a no-op kept for call-site stability)
21
- function checkAndRecord403(_result, _integration, _scope, _action, _ctx) {
22
- // No-op: AuthorityChecker eliminated. 403 recording removed.
23
- }
24
13
  const DEFAULT_ADO_QUERY = "SELECT [System.Id], [System.Title], [System.State], [System.AssignedTo] FROM WorkItems WHERE [System.AssignedTo] = @Me AND [System.State] <> 'Closed' ORDER BY [System.ChangedDate] DESC";
25
14
  exports.teamsToolDefinitions = [
26
15
  // -- Generic Graph tools --
@@ -46,6 +35,7 @@ exports.teamsToolDefinitions = [
46
35
  return (0, graph_client_1.graphRequest)(ctx.graphToken, "GET", args.path);
47
36
  },
48
37
  integration: "graph",
38
+ summaryKeys: ["path"],
49
39
  },
50
40
  {
51
41
  tool: {
@@ -74,7 +64,8 @@ exports.teamsToolDefinitions = [
74
64
  return (0, graph_client_1.graphRequest)(ctx.graphToken, args.method, args.path, args.body);
75
65
  },
76
66
  integration: "graph",
77
- confirmationRequired: true,
67
+ summaryKeys: ["method", "path"],
68
+ riskProfile: { mutates: "external_side_effect", risk: "high", reason: "mutates Microsoft Graph resources" },
78
69
  },
79
70
  // -- Generic ADO tools --
80
71
  {
@@ -82,7 +73,7 @@ exports.teamsToolDefinitions = [
82
73
  type: "function",
83
74
  function: {
84
75
  name: "ado_query",
85
- description: "GET or POST (for WIQL read queries) any Azure DevOps API endpoint. Use ado_docs first to look up the correct path.",
76
+ description: "GET or POST (for WIQL read queries) any Azure DevOps API endpoint. Use ado_docs first to look up the correct path and host.",
86
77
  parameters: {
87
78
  type: "object",
88
79
  properties: {
@@ -90,6 +81,7 @@ exports.teamsToolDefinitions = [
90
81
  path: { type: "string", description: "ADO API path after /{org}, e.g. /_apis/wit/wiql" },
91
82
  method: { type: "string", enum: ["GET", "POST"], description: "HTTP method (defaults to GET)" },
92
83
  body: { type: "string", description: "JSON request body (optional, used with POST for WIQL)" },
84
+ host: { type: "string", description: "API host override for non-standard APIs (e.g. 'vsapm.dev.azure.com' for entitlements, 'vssps.dev.azure.com' for users). Omit for standard dev.azure.com." },
93
85
  },
94
86
  required: ["organization", "path"],
95
87
  },
@@ -100,18 +92,17 @@ exports.teamsToolDefinitions = [
100
92
  return "AUTH_REQUIRED:ado -- I need access to Azure DevOps. Please sign in when prompted.";
101
93
  }
102
94
  const method = args.method || "GET";
103
- const result = await (0, ado_client_1.adoRequest)(ctx.adoToken, method, args.organization, args.path, args.body);
104
- checkAndRecord403(result, "ado", args.organization, method, ctx);
105
- return result;
95
+ return (0, ado_client_1.adoRequest)(ctx.adoToken, method, args.organization, args.path, args.body, args.host);
106
96
  },
107
97
  integration: "ado",
98
+ summaryKeys: ["method", "organization", "path"],
108
99
  },
109
100
  {
110
101
  tool: {
111
102
  type: "function",
112
103
  function: {
113
104
  name: "ado_mutate",
114
- description: "POST/PATCH/DELETE any Azure DevOps API endpoint for actual mutations. Use ado_docs first to look up the correct path.",
105
+ description: "POST/PATCH/DELETE any Azure DevOps API endpoint for actual mutations. Use ado_docs first to look up the correct path and host.",
115
106
  parameters: {
116
107
  type: "object",
117
108
  properties: {
@@ -119,6 +110,7 @@ exports.teamsToolDefinitions = [
119
110
  organization: { type: "string", description: "Azure DevOps organization name" },
120
111
  path: { type: "string", description: "ADO API path after /{org}" },
121
112
  body: { type: "string", description: "JSON request body (optional)" },
113
+ host: { type: "string", description: "API host override for non-standard APIs (e.g. 'vsapm.dev.azure.com' for entitlements, 'vssps.dev.azure.com' for users). Omit for standard dev.azure.com." },
122
114
  },
123
115
  required: ["method", "organization", "path"],
124
116
  },
@@ -131,14 +123,11 @@ exports.teamsToolDefinitions = [
131
123
  if (!MUTATE_METHODS.includes(args.method)) {
132
124
  return `Invalid method "${args.method}". Must be one of: ${MUTATE_METHODS.join(", ")}`;
133
125
  }
134
- /* v8 ignore next -- fallback unreachable: method is validated against MUTATE_METHODS above @preserve */
135
- const action = METHOD_TO_ACTION[args.method] || args.method;
136
- const result = await (0, ado_client_1.adoRequest)(ctx.adoToken, args.method, args.organization, args.path, args.body);
137
- checkAndRecord403(result, "ado", args.organization, action, ctx);
138
- return result;
126
+ return (0, ado_client_1.adoRequest)(ctx.adoToken, args.method, args.organization, args.path, args.body, args.host);
139
127
  },
140
128
  integration: "ado",
141
- confirmationRequired: true,
129
+ summaryKeys: ["method", "organization", "path"],
130
+ riskProfile: { mutates: "external_side_effect", risk: "high", reason: "mutates Azure DevOps resources" },
142
131
  },
143
132
  // -- Convenience aliases (backward compat) --
144
133
  {
@@ -157,6 +146,7 @@ exports.teamsToolDefinitions = [
157
146
  return (0, graph_client_1.getProfile)(ctx.graphToken);
158
147
  },
159
148
  integration: "graph",
149
+ summaryKeys: [],
160
150
  },
161
151
  {
162
152
  tool: {
@@ -200,6 +190,55 @@ exports.teamsToolDefinitions = [
200
190
  return (0, ado_client_1.queryWorkItems)(ctx.adoToken, org, query);
201
191
  },
202
192
  integration: "ado",
193
+ summaryKeys: ["organization", "query"],
194
+ },
195
+ // -- Proactive messaging --
196
+ {
197
+ tool: {
198
+ type: "function",
199
+ function: {
200
+ name: "teams_send_message",
201
+ description: "send a proactive 1:1 Teams message to a user. requires their AAD object ID (use graph_query /users to find it). the message appears as coming from the bot.",
202
+ parameters: {
203
+ type: "object",
204
+ properties: {
205
+ user_id: { type: "string", description: "AAD object ID of the user to message" },
206
+ user_name: { type: "string", description: "display name of the user (for logging)" },
207
+ message: { type: "string", description: "message text to send" },
208
+ tenant_id: { type: "string", description: "tenant ID (optional, defaults to current conversation tenant)" },
209
+ },
210
+ required: ["user_id", "message"],
211
+ },
212
+ },
213
+ },
214
+ /* v8 ignore start -- proactive messaging requires live Teams SDK conversation client @preserve */
215
+ handler: async (args, ctx) => {
216
+ if (!ctx?.botApi) {
217
+ return "proactive messaging is not available -- no bot API context (this tool only works in the Teams channel)";
218
+ }
219
+ try {
220
+ const tenantId = args.tenant_id || ctx.tenantId;
221
+ // Cast to the SDK's ConversationClient shape (kept as `unknown` in ToolContext to avoid type coupling)
222
+ const conversations = ctx.botApi.conversations;
223
+ const conversation = await conversations.create({
224
+ bot: { id: ctx.botApi.id },
225
+ members: [{ id: args.user_id, role: "user", name: args.user_name || args.user_id }],
226
+ tenantId,
227
+ isGroup: false,
228
+ });
229
+ await conversations.activities(conversation.id).create({
230
+ type: "message",
231
+ text: args.message,
232
+ });
233
+ return `message sent to ${args.user_name || args.user_id}`;
234
+ }
235
+ catch (e) {
236
+ return `failed to send proactive message: ${e instanceof Error ? e.message : String(e)}`;
237
+ }
238
+ },
239
+ /* v8 ignore stop */
240
+ summaryKeys: ["user_name", "user_id"],
241
+ riskProfile: { mutates: "external_side_effect", risk: "high", reason: "sends a proactive Teams message" },
203
242
  },
204
243
  // -- Documentation tools --
205
244
  {
@@ -221,6 +260,7 @@ exports.teamsToolDefinitions = [
221
260
  return searchEndpoints(graph_endpoints_json_1.default, args.query || "");
222
261
  },
223
262
  integration: "graph",
263
+ summaryKeys: ["query"],
224
264
  },
225
265
  {
226
266
  tool: {
@@ -241,12 +281,9 @@ exports.teamsToolDefinitions = [
241
281
  return searchEndpoints(ado_endpoints_json_1.default, args.query || "");
242
282
  },
243
283
  integration: "ado",
284
+ summaryKeys: ["query"],
244
285
  },
245
286
  ];
246
- // Backward-compat: extract just the OpenAI tool schemas
247
- exports.teamsTools = exports.teamsToolDefinitions.map((d) => d.tool);
248
- // Backward-compat: extract just the handlers by name
249
- exports.teamsToolHandlers = Object.fromEntries(exports.teamsToolDefinitions.map((d) => [d.tool.function.name, d.handler]));
250
287
  function searchEndpoints(entries, query) {
251
288
  (0, runtime_1.emitNervesEvent)({
252
289
  component: "repertoire",
@@ -268,41 +305,10 @@ function searchEndpoints(entries, query) {
268
305
  ` ${e.description}`,
269
306
  ` Params: ${e.params || "none"}`,
270
307
  ];
308
+ if (e.host)
309
+ lines.push(` Host: ${e.host}`);
271
310
  if (e.scopes)
272
311
  lines.push(` Scopes: ${e.scopes}`);
273
312
  return lines.join("\n");
274
313
  }).join("\n\n");
275
314
  }
276
- function summarizeTeamsArgs(name, args) {
277
- function summarizeKeyValues(keys) {
278
- const parts = [];
279
- for (const key of keys) {
280
- const raw = args[key];
281
- if (raw === undefined || raw === null)
282
- continue;
283
- const compact = String(raw).replace(/\s+/g, " ").trim();
284
- if (!compact)
285
- continue;
286
- const clipped = compact.length > 60 ? compact.slice(0, 60) + "..." : compact;
287
- parts.push(`${key}=${clipped}`);
288
- }
289
- return parts.join(" ");
290
- }
291
- if (name === "graph_profile")
292
- return "";
293
- if (name === "ado_work_items")
294
- return summarizeKeyValues(["organization", "query"]);
295
- if (name === "graph_query")
296
- return summarizeKeyValues(["path"]);
297
- if (name === "graph_mutate")
298
- return summarizeKeyValues(["method", "path"]);
299
- if (name === "ado_query")
300
- return summarizeKeyValues(["method", "organization", "path"]);
301
- if (name === "ado_mutate")
302
- return summarizeKeyValues(["method", "organization", "path"]);
303
- if (name === "graph_docs")
304
- return summarizeKeyValues(["query"]);
305
- if (name === "ado_docs")
306
- return summarizeKeyValues(["query"]);
307
- return undefined;
308
- }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.telegramContactToolDefinition = void 0;
4
+ const runtime_1 = require("../nerves/runtime");
5
+ exports.telegramContactToolDefinition = {
6
+ tool: { type: "function", function: {
7
+ name: "telegram_contact_manage",
8
+ description: "List household Telegram contacts, revoke one exact approved contact, or release one exact blocked contact request. Owner only; quarantined message text is never returned.",
9
+ parameters: { type: "object", properties: {
10
+ action: { type: "string", enum: ["list", "revoke", "unblock"] },
11
+ friendId: { type: "string", description: "Exact Friend ID from list; required for revoke." },
12
+ admissionId: { type: "string", description: "Exact blocked admission ID from list; required for unblock." },
13
+ }, required: ["action"], additionalProperties: false },
14
+ } },
15
+ handler: async (args, ctx) => {
16
+ const actor = ctx?.relationshipAuthorization?.actor;
17
+ const manager = ctx?.telegramContactManager;
18
+ if (!actor || actor.trustLevel !== "family" || !manager)
19
+ return JSON.stringify({ ok: false, error: "Telegram contact management requires the live owner relationship" });
20
+ const action = String(args.action ?? "");
21
+ if (action === "list")
22
+ return JSON.stringify({ ok: true, ...(await manager.list({ actorFriendId: actor.friendId })) });
23
+ if (action === "revoke" && typeof args.friendId === "string" && args.friendId.trim())
24
+ return JSON.stringify({ ok: true, ...(await manager.revoke({ actorFriendId: actor.friendId, friendId: args.friendId })) });
25
+ if (action === "unblock" && typeof args.admissionId === "string" && args.admissionId.trim())
26
+ return JSON.stringify({ ok: true, ...(await manager.unblock({ actorFriendId: actor.friendId, admissionId: args.admissionId })) });
27
+ return JSON.stringify({ ok: false, error: "Telegram contact management arguments are invalid" });
28
+ },
29
+ riskProfile: (args) => String(args.action) === "list" ? { mutates: "none", risk: "low" } : { mutates: "durable_state_write", risk: "high", reason: "changes one exact household Telegram admission" },
30
+ approvalPolicy: () => ({ kind: "not_required" }),
31
+ };
32
+ (0, runtime_1.emitNervesEvent)({
33
+ component: "repertoire",
34
+ event: "repertoire.telegram_contact_tool_loaded",
35
+ message: "Telegram contact management tool loaded",
36
+ meta: { operations: 3 },
37
+ });