@ouro.bot/cli 0.1.0-alpha.81 → 0.1.0-alpha.810

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 (623) 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/changelog.json +5177 -16
  15. package/deploy/unraid/Dockerfile +48 -0
  16. package/deploy/unraid/README.txt +3032 -0
  17. package/deploy/unraid/audit-container-spec.sh +4 -0
  18. package/deploy/unraid/container-runtime.json +1 -0
  19. package/deploy/unraid/docker-man-template-transaction.mjs +526 -0
  20. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  21. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  22. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  23. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  24. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  25. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  26. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  27. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  28. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  29. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  30. package/deploy/unraid/sanctuary-deployment-target.mjs +709 -0
  31. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  32. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2030 -0
  33. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  34. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  35. package/deploy/unraid/sanctuary.ouro/agent.json +24 -0
  36. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  37. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  38. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  39. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  40. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  41. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  42. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +11 -0
  43. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +11 -0
  45. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  46. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +23 -0
  47. package/deploy/unraid/sanctuary.xml +27 -0
  48. package/dist/a2a/card.js +57 -0
  49. package/dist/a2a/client.js +180 -0
  50. package/dist/a2a/config.js +50 -0
  51. package/dist/a2a/delegation-stores.js +56 -0
  52. package/dist/a2a/did-resolution.js +93 -0
  53. package/dist/a2a/identity.js +170 -0
  54. package/dist/a2a/inbound-share.js +107 -0
  55. package/dist/a2a/mission-result-wire.js +196 -0
  56. package/dist/a2a/onboarding.js +115 -0
  57. package/dist/a2a/pin-store.js +132 -0
  58. package/dist/a2a/seen-ledger.js +120 -0
  59. package/dist/a2a/server.js +604 -0
  60. package/dist/a2a/task-store.js +69 -0
  61. package/dist/a2a/transport.js +45 -0
  62. package/dist/a2a/types.js +3 -0
  63. package/dist/arc/attention-types.js +8 -0
  64. package/dist/arc/cares.js +360 -0
  65. package/dist/arc/episodes.js +118 -0
  66. package/dist/arc/evolution.js +490 -0
  67. package/dist/arc/flight-recorder.js +1034 -0
  68. package/dist/arc/intentions.js +134 -0
  69. package/dist/arc/json-store.js +117 -0
  70. package/dist/arc/obligations.js +386 -0
  71. package/dist/arc/packets.js +336 -0
  72. package/dist/arc/presence.js +185 -0
  73. package/dist/arc/task-lifecycle.js +57 -0
  74. package/dist/commerce/store.js +755 -0
  75. package/dist/commerce/types.js +3 -0
  76. package/dist/heart/active-work.js +820 -29
  77. package/dist/heart/agent-entry.js +252 -3
  78. package/dist/heart/approval-files.js +113 -0
  79. package/dist/heart/approval-store.js +950 -0
  80. package/dist/heart/attachments/image-normalize.js +194 -0
  81. package/dist/heart/attachments/materialize.js +97 -0
  82. package/dist/heart/attachments/originals.js +88 -0
  83. package/dist/heart/attachments/render.js +29 -0
  84. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  85. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  86. package/dist/heart/attachments/sources/index.js +18 -0
  87. package/dist/heart/attachments/sources/telegram.js +71 -0
  88. package/dist/heart/attachments/store.js +132 -0
  89. package/dist/heart/attachments/types.js +93 -0
  90. package/dist/heart/auth/auth-flow.js +495 -0
  91. package/dist/heart/autonomy-budget.js +478 -0
  92. package/dist/heart/awaiting/await-alert.js +148 -0
  93. package/dist/heart/awaiting/await-expiry.js +143 -0
  94. package/dist/heart/awaiting/await-loader.js +91 -0
  95. package/dist/heart/awaiting/await-parser.js +149 -0
  96. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  97. package/dist/heart/awaiting/await-scheduler.js +382 -0
  98. package/dist/heart/background-operations.js +281 -0
  99. package/dist/heart/bridges/manager.js +137 -17
  100. package/dist/heart/bridges/store.js +14 -2
  101. package/dist/heart/bundle-state.js +168 -0
  102. package/dist/heart/commitments.js +64 -18
  103. package/dist/heart/config-registry.js +331 -0
  104. package/dist/heart/config.js +142 -129
  105. package/dist/heart/context-loss-gauntlet.js +387 -0
  106. package/dist/heart/context-loss-sentinel.js +1157 -0
  107. package/dist/heart/core.js +2105 -574
  108. package/dist/heart/cross-chat-delivery.js +9 -22
  109. package/dist/heart/daemon/agent-config-check.js +451 -0
  110. package/dist/heart/daemon/agent-discovery.js +185 -3
  111. package/dist/heart/daemon/agent-service.js +542 -0
  112. package/dist/heart/daemon/agentic-repair.js +547 -0
  113. package/dist/heart/daemon/await-private-wake.js +59 -0
  114. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  115. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  116. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  117. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  118. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  119. package/dist/heart/daemon/cadence.js +180 -0
  120. package/dist/heart/daemon/cli-defaults.js +854 -0
  121. package/dist/heart/daemon/cli-desk.js +322 -0
  122. package/dist/heart/daemon/cli-exec.js +8822 -0
  123. package/dist/heart/daemon/cli-help.js +716 -0
  124. package/dist/heart/daemon/cli-parse.js +2771 -0
  125. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  126. package/dist/heart/daemon/cli-render.js +777 -0
  127. package/dist/heart/daemon/cli-types.js +8 -0
  128. package/dist/heart/daemon/connect-bay.js +323 -0
  129. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  130. package/dist/heart/daemon/container-healthcheck.js +112 -0
  131. package/dist/heart/daemon/container-runtime.js +97 -0
  132. package/dist/heart/daemon/container-spec-auditor-main.js +170 -0
  133. package/dist/heart/daemon/container-spec-auditor.js +236 -0
  134. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  135. package/dist/heart/daemon/daemon-cli.js +29 -2317
  136. package/dist/heart/daemon/daemon-entry.js +921 -11
  137. package/dist/heart/daemon/daemon-health.js +186 -0
  138. package/dist/heart/daemon/daemon-rollup.js +57 -0
  139. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  140. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  141. package/dist/heart/daemon/daemon.js +2073 -104
  142. package/dist/heart/daemon/dns-workflow.js +394 -0
  143. package/dist/heart/daemon/doctor-types.js +8 -0
  144. package/dist/heart/daemon/doctor.js +1755 -0
  145. package/dist/heart/daemon/freshness.js +345 -0
  146. package/dist/heart/daemon/habit-private-wake.js +61 -0
  147. package/dist/heart/daemon/health-monitor.js +142 -11
  148. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  149. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  150. package/dist/heart/daemon/http-health-probe.js +80 -0
  151. package/dist/heart/daemon/human-command-screens.js +234 -0
  152. package/dist/heart/daemon/human-readiness.js +114 -0
  153. package/dist/heart/daemon/inner-status.js +78 -0
  154. package/dist/heart/daemon/interactive-repair.js +394 -0
  155. package/dist/heart/daemon/launchd.js +37 -8
  156. package/dist/heart/daemon/log-tailer.js +79 -10
  157. package/dist/heart/daemon/logs-prune.js +132 -0
  158. package/dist/heart/daemon/mcp-canary.js +524 -0
  159. package/dist/heart/daemon/message-router.js +65 -5
  160. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  161. package/dist/heart/daemon/os-cron-deps.js +135 -0
  162. package/dist/heart/daemon/os-cron.js +22 -14
  163. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  164. package/dist/heart/daemon/ouro-entry.js +3 -1
  165. package/dist/heart/daemon/plugin-cli.js +432 -0
  166. package/dist/heart/daemon/process-manager.js +733 -61
  167. package/dist/heart/daemon/provider-discovery.js +137 -0
  168. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  169. package/dist/heart/daemon/prunable-bundle.js +144 -0
  170. package/dist/heart/daemon/pulse.js +511 -0
  171. package/dist/heart/daemon/readiness-repair.js +365 -0
  172. package/dist/heart/daemon/run-hooks.js +2 -0
  173. package/dist/heart/daemon/runtime-logging.js +47 -14
  174. package/dist/heart/daemon/runtime-metadata.js +2 -30
  175. package/dist/heart/daemon/runtime-mode.js +13 -2
  176. package/dist/heart/daemon/safe-mode.js +161 -0
  177. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2609 -0
  178. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1866 -0
  179. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  180. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +976 -0
  181. package/dist/heart/daemon/sanctuary-bundle-migration.js +728 -0
  182. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  183. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  184. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  185. package/dist/heart/daemon/sense-manager.js +689 -48
  186. package/dist/heart/daemon/session-id-resolver.js +131 -0
  187. package/dist/heart/daemon/skill-management-installer.js +1 -1
  188. package/dist/heart/daemon/socket-client.js +180 -12
  189. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  190. package/dist/heart/daemon/startup-tui.js +339 -0
  191. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  192. package/dist/heart/daemon/task-scheduler.js +117 -39
  193. package/dist/heart/daemon/terminal-ui.js +499 -0
  194. package/dist/heart/daemon/thoughts.js +138 -54
  195. package/dist/heart/daemon/up-progress.js +366 -0
  196. package/dist/heart/daemon/vault-items.js +56 -0
  197. package/dist/heart/delegation.js +1 -4
  198. package/dist/heart/external-events/router.js +1414 -0
  199. package/dist/heart/frontend-approval-runtime.js +432 -0
  200. package/dist/heart/frontend-journal.js +215 -0
  201. package/dist/heart/frontend-session-service.js +237 -0
  202. package/dist/heart/frontend-socket-client.js +154 -0
  203. package/dist/heart/frontend-socket.js +400 -0
  204. package/dist/heart/habits/habit-cancel.js +810 -0
  205. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  206. package/dist/heart/habits/habit-migration.js +194 -0
  207. package/dist/heart/habits/habit-parser.js +278 -0
  208. package/dist/heart/habits/habit-runtime-state.js +93 -0
  209. package/dist/heart/habits/habit-scheduler.js +653 -0
  210. package/dist/heart/habits/habit-session-summary.js +318 -0
  211. package/dist/heart/habits/habit-session.js +636 -0
  212. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  213. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  214. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  215. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  216. package/dist/heart/identity.js +184 -59
  217. package/dist/heart/kept-notes.js +289 -0
  218. package/dist/heart/kicks.js +1 -1
  219. package/dist/heart/machine-identity.js +161 -0
  220. package/dist/heart/mail-import-discovery.js +356 -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 +231 -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 +11 -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 +1 -1
  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 +173 -60
  258. package/dist/heart/providers/azure.js +23 -11
  259. package/dist/heart/providers/error-classification.js +127 -0
  260. package/dist/heart/providers/github-copilot.js +34 -38
  261. package/dist/heart/providers/minimax-vlm.js +189 -0
  262. package/dist/heart/providers/minimax.js +26 -8
  263. package/dist/heart/providers/openai-codex-token.js +349 -0
  264. package/dist/heart/providers/openai-codex.js +55 -40
  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 +22 -4
  271. package/dist/heart/session-activity.js +92 -24
  272. package/dist/heart/session-events.js +1433 -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-redaction-repair-cli-main.js +31 -0
  277. package/dist/heart/session-redaction-repair.js +543 -0
  278. package/dist/heart/session-stats-cli-main.js +5 -0
  279. package/dist/heart/session-stats.js +182 -0
  280. package/dist/heart/session-transcript.js +133 -0
  281. package/dist/heart/start-of-turn-packet.js +372 -0
  282. package/dist/heart/steward-policy.js +302 -0
  283. package/dist/heart/streaming.js +604 -207
  284. package/dist/heart/structured-output.js +196 -0
  285. package/dist/heart/sync-classification.js +176 -0
  286. package/dist/heart/sync.js +449 -0
  287. package/dist/heart/target-resolution.js +11 -7
  288. package/dist/heart/tempo.js +93 -0
  289. package/dist/heart/temporal-view.js +41 -0
  290. package/dist/heart/timeouts.js +101 -0
  291. package/dist/heart/tool-activity-callbacks.js +59 -0
  292. package/dist/heart/tool-approval.js +342 -0
  293. package/dist/heart/tool-description.js +155 -0
  294. package/dist/heart/tool-friction.js +55 -0
  295. package/dist/heart/tool-loop.js +200 -0
  296. package/dist/heart/turn-context.js +482 -0
  297. package/dist/heart/turn-execution-lease.js +30 -0
  298. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  299. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  300. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  301. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  302. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  303. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  304. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  305. package/dist/heart/versioning/update-hooks.js +154 -0
  306. package/dist/heart/versioning/version-intent.js +114 -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 +24 -2
  333. package/dist/mind/context.js +279 -111
  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} +68 -77
  337. package/dist/mind/embedding-provider.js +60 -0
  338. package/dist/mind/file-state.js +179 -0
  339. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  340. package/dist/mind/obligation-steering.js +227 -0
  341. package/dist/mind/pending.js +34 -8
  342. package/dist/mind/prompt-budget.js +479 -0
  343. package/dist/mind/prompt-refresh.js +3 -2
  344. package/dist/mind/prompt.js +1059 -187
  345. package/dist/mind/provenance-trust.js +26 -0
  346. package/dist/mind/record-paths.js +312 -0
  347. package/dist/mind/scrutiny.js +173 -0
  348. package/dist/mind/session-transaction.js +564 -0
  349. package/dist/nerves/cli-logging.js +7 -1
  350. package/dist/nerves/coverage/audit-rules.js +15 -6
  351. package/dist/nerves/coverage/audit.js +28 -2
  352. package/dist/nerves/coverage/cli.js +1 -1
  353. package/dist/nerves/coverage/contract.js +5 -5
  354. package/dist/nerves/coverage/file-completeness.js +139 -5
  355. package/dist/nerves/coverage/run-artifacts.js +55 -35
  356. package/dist/nerves/coverage/source-scanner.js +4 -4
  357. package/dist/nerves/event-buffer.js +111 -0
  358. package/dist/nerves/index.js +293 -9
  359. package/dist/nerves/observation.js +20 -0
  360. package/dist/nerves/redact.js +79 -0
  361. package/dist/nerves/review/cli-main.js +5 -0
  362. package/dist/nerves/review/cli.js +156 -0
  363. package/dist/nerves/review/core.js +159 -0
  364. package/dist/nerves/runtime.js +17 -1
  365. package/dist/repertoire/ado-client.js +15 -56
  366. package/dist/repertoire/ado-semantic.js +16 -10
  367. package/dist/repertoire/api-client.js +97 -0
  368. package/dist/repertoire/bitwarden-store.js +1045 -0
  369. package/dist/repertoire/bundle-templates.js +71 -0
  370. package/dist/repertoire/bw-installer.js +180 -0
  371. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  372. package/dist/repertoire/coding/context-pack.js +331 -0
  373. package/dist/repertoire/coding/feedback.js +218 -30
  374. package/dist/repertoire/coding/index.js +15 -3
  375. package/dist/repertoire/coding/manager.js +166 -10
  376. package/dist/repertoire/coding/spawner.js +58 -11
  377. package/dist/repertoire/coding/tools.js +242 -14
  378. package/dist/repertoire/coding/workbench-client.js +272 -0
  379. package/dist/repertoire/coding/workbench-manager.js +346 -0
  380. package/dist/repertoire/commerce-errors.js +109 -0
  381. package/dist/repertoire/commerce-self-test.js +156 -0
  382. package/dist/repertoire/credential-access.js +178 -0
  383. package/dist/repertoire/desk/classifier.js +362 -0
  384. package/dist/repertoire/duffel-client.js +185 -0
  385. package/dist/repertoire/github-client.js +14 -55
  386. package/dist/repertoire/graph-client.js +11 -52
  387. package/dist/repertoire/guardrails.js +811 -18
  388. package/dist/repertoire/mcp-client.js +44 -3
  389. package/dist/repertoire/mcp-manager.js +331 -27
  390. package/dist/repertoire/mcp-tools.js +83 -0
  391. package/dist/repertoire/plugin-mcp.js +175 -0
  392. package/dist/repertoire/plugins.js +253 -0
  393. package/dist/repertoire/relationship-authorization.js +194 -0
  394. package/dist/repertoire/shell-sessions.js +133 -0
  395. package/dist/repertoire/skills.js +48 -4
  396. package/dist/repertoire/stripe-client.js +131 -0
  397. package/dist/repertoire/tool-arguments.js +148 -0
  398. package/dist/repertoire/tool-results.js +29 -0
  399. package/dist/repertoire/tools-a2a.js +699 -0
  400. package/dist/repertoire/tools-attachments.js +322 -0
  401. package/dist/repertoire/tools-awaiting.js +575 -0
  402. package/dist/repertoire/tools-base.js +82 -1139
  403. package/dist/repertoire/tools-bluebubbles.js +2 -0
  404. package/dist/repertoire/tools-bridge.js +144 -0
  405. package/dist/repertoire/tools-bundle.js +993 -0
  406. package/dist/repertoire/tools-commerce.js +253 -0
  407. package/dist/repertoire/tools-config.js +186 -0
  408. package/dist/repertoire/tools-continuity.js +575 -0
  409. package/dist/repertoire/tools-credential.js +383 -0
  410. package/dist/repertoire/tools-evolution.js +527 -0
  411. package/dist/repertoire/tools-files.js +344 -0
  412. package/dist/repertoire/tools-flight.js +290 -0
  413. package/dist/repertoire/tools-flow.js +119 -0
  414. package/dist/repertoire/tools-github.js +3 -8
  415. package/dist/repertoire/tools-habits.js +103 -0
  416. package/dist/repertoire/tools-mail.js +1828 -0
  417. package/dist/repertoire/tools-notes.js +485 -0
  418. package/dist/repertoire/tools-obligations.js +182 -0
  419. package/dist/repertoire/tools-orientation.js +31 -0
  420. package/dist/repertoire/tools-record.js +482 -0
  421. package/dist/repertoire/tools-rsvp.js +139 -0
  422. package/dist/repertoire/tools-runtime.js +150 -0
  423. package/dist/repertoire/tools-session.js +1108 -0
  424. package/dist/repertoire/tools-shell.js +133 -0
  425. package/dist/repertoire/tools-steward-policy.js +95 -0
  426. package/dist/repertoire/tools-stripe.js +224 -0
  427. package/dist/repertoire/tools-surface.js +369 -0
  428. package/dist/repertoire/tools-teams.js +12 -39
  429. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  430. package/dist/repertoire/tools-travel.js +125 -0
  431. package/dist/repertoire/tools-trip.js +982 -0
  432. package/dist/repertoire/tools-unraid.js +484 -0
  433. package/dist/repertoire/tools-user-profile.js +146 -0
  434. package/dist/repertoire/tools-vault.js +40 -0
  435. package/dist/repertoire/tools-voice.js +145 -0
  436. package/dist/repertoire/tools.js +377 -80
  437. package/dist/repertoire/travel-api-client.js +360 -0
  438. package/dist/repertoire/unraid-client.js +155 -0
  439. package/dist/repertoire/unraid-restart.js +212 -0
  440. package/dist/repertoire/user-profile.js +131 -0
  441. package/dist/repertoire/vault-setup.js +246 -0
  442. package/dist/repertoire/vault-unlock.js +628 -0
  443. package/dist/rsvp/aisleplanner-client.js +354 -0
  444. package/dist/rsvp/cli.js +926 -0
  445. package/dist/rsvp/config.js +327 -0
  446. package/dist/rsvp/cutover.js +433 -0
  447. package/dist/rsvp/diagnostics.js +232 -0
  448. package/dist/rsvp/diff-renderer.js +176 -0
  449. package/dist/rsvp/habit-policy.js +110 -0
  450. package/dist/rsvp/habit-stage.js +123 -0
  451. package/dist/rsvp/incident-bundle.js +97 -0
  452. package/dist/rsvp/migration.js +204 -0
  453. package/dist/rsvp/native-habit-runner.js +630 -0
  454. package/dist/rsvp/outbound-state.js +628 -0
  455. package/dist/rsvp/query.js +118 -0
  456. package/dist/rsvp/replay.js +233 -0
  457. package/dist/rsvp/snapshot.js +232 -0
  458. package/dist/rsvp/spend-ledger.js +175 -0
  459. package/dist/scripts/claude-code-hook.js +41 -0
  460. package/dist/scripts/claude-code-stop-hook.js +47 -0
  461. package/dist/senses/a2a-entry.js +115 -0
  462. package/dist/senses/acp-server.js +386 -0
  463. package/dist/senses/attention-queue.js +186 -0
  464. package/dist/senses/await-turn-message.js +58 -0
  465. package/dist/senses/bluebubbles/active-turns.js +216 -0
  466. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  467. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  468. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  469. package/dist/senses/bluebubbles/context-packet.js +207 -0
  470. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  471. package/dist/senses/bluebubbles/entry.js +90 -0
  472. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  473. package/dist/senses/bluebubbles/index.js +3839 -0
  474. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  475. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  476. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  477. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  478. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  479. package/dist/senses/bluebubbles/processed-log.js +133 -0
  480. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  481. package/dist/senses/bluebubbles/replay.js +284 -0
  482. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  483. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  484. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  485. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  486. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  487. package/dist/senses/cli/bracketed-paste.js +82 -0
  488. package/dist/senses/cli/image-paste.js +287 -0
  489. package/dist/senses/cli/image-ref-navigation.js +75 -0
  490. package/dist/senses/cli/ink-app.js +156 -0
  491. package/dist/senses/cli/inline-diff.js +64 -0
  492. package/dist/senses/cli/input-keys.js +174 -0
  493. package/dist/senses/cli/kill-ring.js +86 -0
  494. package/dist/senses/cli/message-list.js +51 -0
  495. package/dist/senses/cli/ouro-tui.js +607 -0
  496. package/dist/senses/cli/spinner-imperative.js +135 -0
  497. package/dist/senses/cli/spinner.js +101 -0
  498. package/dist/senses/cli/status-line.js +60 -0
  499. package/dist/senses/cli/streaming-markdown.js +526 -0
  500. package/dist/senses/cli/tool-display.js +85 -0
  501. package/dist/senses/cli/tool-render.js +85 -0
  502. package/dist/senses/cli/tui-store.js +241 -0
  503. package/dist/senses/cli/virtual-list.js +35 -0
  504. package/dist/senses/cli-entry.js +60 -8
  505. package/dist/senses/cli.js +600 -317
  506. package/dist/senses/commands.js +66 -3
  507. package/dist/senses/context-packet-ledger.js +371 -0
  508. package/dist/senses/context-packets.js +154 -0
  509. package/dist/senses/habit-lifecycle-guard.js +24 -0
  510. package/dist/senses/habit-turn-message.js +160 -0
  511. package/dist/senses/ingress-evidence.js +2 -0
  512. package/dist/senses/mail-entry.js +66 -0
  513. package/dist/senses/mail.js +524 -0
  514. package/dist/senses/pipeline.js +1115 -204
  515. package/dist/senses/private-runtime-worker.js +859 -0
  516. package/dist/senses/private-runtime.js +1496 -0
  517. package/dist/senses/proactive-content-guard.js +51 -0
  518. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  519. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  520. package/dist/senses/sanctuary-grounding.js +118 -0
  521. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  522. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  523. package/dist/senses/sanctuary-health-runner.js +101 -0
  524. package/dist/senses/sanctuary-health.js +408 -0
  525. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  526. package/dist/senses/sanctuary-interactive-control.js +306 -0
  527. package/dist/senses/sanctuary-media-catalog-contract.js +235 -0
  528. package/dist/senses/sanctuary-media-optimization.js +514 -0
  529. package/dist/senses/sanctuary-runtime.js +338 -0
  530. package/dist/senses/sanctuary-sab.js +85 -0
  531. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  532. package/dist/senses/shared-turn.js +756 -0
  533. package/dist/senses/surface-tool.js +109 -0
  534. package/dist/senses/teams-entry.js +60 -8
  535. package/dist/senses/teams.js +515 -217
  536. package/dist/senses/telegram-admission.js +711 -0
  537. package/dist/senses/telegram-approval-runtime.js +566 -0
  538. package/dist/senses/telegram-attachments.js +182 -0
  539. package/dist/senses/telegram-audit-ledger.js +220 -0
  540. package/dist/senses/telegram-client.js +1677 -0
  541. package/dist/senses/telegram-effect-adapter.js +859 -0
  542. package/dist/senses/telegram-entry.js +83 -0
  543. package/dist/senses/telegram.js +2045 -0
  544. package/dist/senses/trust-gate.js +104 -9
  545. package/dist/senses/voice/audio-playback.js +237 -0
  546. package/dist/senses/voice/audio-routing.js +119 -0
  547. package/dist/senses/voice/elevenlabs.js +202 -0
  548. package/dist/senses/voice/floor-control.js +431 -0
  549. package/dist/senses/voice/floor-controller.js +115 -0
  550. package/dist/senses/voice/golden-path.js +116 -0
  551. package/dist/senses/voice/index.js +29 -0
  552. package/dist/senses/voice/meeting.js +113 -0
  553. package/dist/senses/voice/outbound.js +190 -0
  554. package/dist/senses/voice/phone.js +33 -0
  555. package/dist/senses/voice/playback.js +139 -0
  556. package/dist/senses/voice/realtime-eval.js +496 -0
  557. package/dist/senses/voice/realtime-trace.js +531 -0
  558. package/dist/senses/voice/transcript.js +70 -0
  559. package/dist/senses/voice/turn.js +191 -0
  560. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  561. package/dist/senses/voice/twilio-phone.js +5081 -0
  562. package/dist/senses/voice/types.js +2 -0
  563. package/dist/senses/voice/whisper.js +161 -0
  564. package/dist/senses/voice-entry.js +81 -0
  565. package/dist/senses/voice-realtime-eval-command.js +99 -0
  566. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  567. package/dist/senses/voice-twilio-entry.js +87 -0
  568. package/dist/trips/core.js +138 -0
  569. package/dist/trips/store.js +265 -0
  570. package/dist/util/frontmatter.js +69 -0
  571. package/npm-shrinkwrap.json +8138 -0
  572. package/package.json +72 -13
  573. package/skills/agent-commerce.md +113 -0
  574. package/skills/browser-navigation.md +117 -0
  575. package/skills/commerce-setup-guide.md +116 -0
  576. package/skills/commerce-setup.md +84 -0
  577. package/skills/configure-dev-tools.md +99 -0
  578. package/skills/travel-planning.md +138 -0
  579. package/dist/heart/daemon/auth-flow.js +0 -430
  580. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  581. package/dist/heart/daemon/ouro-version-manager.js +0 -164
  582. package/dist/heart/daemon/update-hooks.js +0 -138
  583. package/dist/heart/obligations.js +0 -141
  584. package/dist/heart/safe-workspace.js +0 -228
  585. package/dist/heart/session-recall.js +0 -116
  586. package/dist/mind/friends/channel.js +0 -84
  587. package/dist/mind/friends/group-context.js +0 -144
  588. package/dist/mind/friends/resolver.js +0 -84
  589. package/dist/mind/friends/store-file.js +0 -190
  590. package/dist/mind/friends/store.js +0 -4
  591. package/dist/mind/friends/tokens.js +0 -26
  592. package/dist/mind/friends/trust-explanation.js +0 -74
  593. package/dist/mind/friends/types.js +0 -29
  594. package/dist/repertoire/tasks/board.js +0 -134
  595. package/dist/repertoire/tasks/index.js +0 -224
  596. package/dist/repertoire/tasks/lifecycle.js +0 -80
  597. package/dist/repertoire/tasks/middleware.js +0 -65
  598. package/dist/repertoire/tasks/parser.js +0 -173
  599. package/dist/repertoire/tasks/scanner.js +0 -132
  600. package/dist/repertoire/tasks/transitions.js +0 -144
  601. package/dist/senses/bluebubbles-entry.js +0 -13
  602. package/dist/senses/bluebubbles.js +0 -1181
  603. package/dist/senses/debug-activity.js +0 -154
  604. package/dist/senses/inner-dialog-worker.js +0 -90
  605. package/dist/senses/inner-dialog.js +0 -525
  606. package/subagents/README.md +0 -7
  607. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  608. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  609. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  610. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  611. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  612. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  613. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  614. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  615. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  616. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  617. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  618. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  619. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  620. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  621. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  622. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  623. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * Soft/hard timeout pattern for boot-path operations — Layer 2.
4
+ *
5
+ * Soft timeout = "log a warning, keep going". The op continues; the consumer
6
+ * records the warning and moves on.
7
+ * Hard timeout = "abort the op via AbortSignal". The underlying op is
8
+ * expected to honour the signal (Node child_process accepts `{ signal }`,
9
+ * fetch accepts `{ signal }`, etc.). When the signal aborts, the op should
10
+ * reject with an AbortError, and the wrapper returns
11
+ * `{ classification: "timeout-hard" }` rather than re-throwing.
12
+ *
13
+ Two optional env overrides (currently only `GIT` is consumed):
14
+ * - `OURO_BOOT_TIMEOUT_GIT_SOFT` / `OURO_BOOT_TIMEOUT_GIT_HARD` — boot
15
+ * git operations (fetch / pull). Used when `envKey === "GIT"`.
16
+ *
17
+ * Env values are parsed as integer milliseconds. Non-numeric or non-positive
18
+ * values are ignored (the explicit `softMs` / `hardMs` defaults from the
19
+ * caller win in that case).
20
+ *
21
+ * Pattern guarantee: timers cleared on resolve / reject so the function
22
+ * holds no refs after settlement. Important because `ouro up` chains
23
+ * many of these and a leaking timer would block process exit.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.runWithTimeouts = runWithTimeouts;
27
+ function readEnvMs(name) {
28
+ const raw = process.env[name];
29
+ if (raw === undefined || raw === null)
30
+ return null;
31
+ const parsed = Number.parseInt(raw, 10);
32
+ if (!Number.isFinite(parsed) || parsed <= 0)
33
+ return null;
34
+ return parsed;
35
+ }
36
+ function resolveTimeouts(options) {
37
+ let softMs = options.softMs;
38
+ let hardMs = options.hardMs;
39
+ if (options.envKey === "GIT") {
40
+ const envSoft = readEnvMs("OURO_BOOT_TIMEOUT_GIT_SOFT");
41
+ if (envSoft !== null)
42
+ softMs = envSoft;
43
+ const envHard = readEnvMs("OURO_BOOT_TIMEOUT_GIT_HARD");
44
+ if (envHard !== null)
45
+ hardMs = envHard;
46
+ }
47
+ return { softMs, hardMs };
48
+ }
49
+ /**
50
+ * Run `fn` with soft and hard timeouts.
51
+ *
52
+ * - Returns `{ result }` on success.
53
+ * - Returns `{ classification: "timeout-hard", warnings }` when aborted.
54
+ * - Returns `{ result, warnings: [...] }` when soft tripped but op completed.
55
+ * - Rejects when `fn` throws a non-abort error (callers can wrap with
56
+ * classifier).
57
+ */
58
+ async function runWithTimeouts(fn, options) {
59
+ const { softMs, hardMs } = resolveTimeouts(options);
60
+ const controller = new AbortController();
61
+ const warnings = [];
62
+ let softTimer = setTimeout(() => {
63
+ softTimer = null;
64
+ warnings.push(`${options.label}: soft timeout exceeded (${softMs}ms) — warning, continuing until hard cut`);
65
+ }, softMs);
66
+ let hardTimer = setTimeout(() => {
67
+ hardTimer = null;
68
+ controller.abort();
69
+ }, hardMs);
70
+ const cleanup = () => {
71
+ if (softTimer !== null) {
72
+ clearTimeout(softTimer);
73
+ softTimer = null;
74
+ }
75
+ if (hardTimer !== null) {
76
+ clearTimeout(hardTimer);
77
+ hardTimer = null;
78
+ }
79
+ };
80
+ try {
81
+ const result = await fn(controller.signal);
82
+ cleanup();
83
+ // If the abort fired and the op resolved gracefully (e.g., the inner
84
+ // function caught the AbortError and returned a structured result), we
85
+ // still classify the outcome as timeout-hard — the op was aborted from
86
+ // the caller's perspective even if no exception propagated. The caller
87
+ // can ignore the classification and use `result` if both are present.
88
+ if (controller.signal.aborted) {
89
+ return { classification: "timeout-hard", warnings };
90
+ }
91
+ return { result, warnings };
92
+ }
93
+ catch (err) {
94
+ cleanup();
95
+ if (controller.signal.aborted) {
96
+ // Hard timeout fired — abort wins over whatever error the op threw.
97
+ return { classification: "timeout-hard", warnings };
98
+ }
99
+ throw err;
100
+ }
101
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createToolActivityCallbacks = createToolActivityCallbacks;
4
+ const tool_description_1 = require("./tool-description");
5
+ const runtime_1 = require("../nerves/runtime");
6
+ function createToolActivityCallbacks(options) {
7
+ (0, runtime_1.emitNervesEvent)({
8
+ component: "engine",
9
+ event: "engine.tool_activity_callbacks_created",
10
+ message: "tool activity callbacks initialized",
11
+ meta: {},
12
+ });
13
+ // Track the last description so we can reference it in END messages
14
+ let lastDescription = null;
15
+ // Track in-flight hidden tools so onToolEnd can SYMMETRICALLY suppress
16
+ // emission for the same tools that onToolStart already suppresses.
17
+ // Without this, a rejected hidden tool (e.g. settle blocked by the
18
+ // mustResolveBeforeHandoff gate or the private-runtime attention-queue gate)
19
+ // would emit "✗ <previous visible tool's description> — <hidden tool's args summary>"
20
+ // because lastDescription persists across calls and the hidden tool's summary
21
+ // (built via summarizeArgs) leaks args like settle's `answer`/`intent` into
22
+ // the visible chat. Counter map (not bool) so concurrent hidden starts don't
23
+ // underflow if ends arrive in any order.
24
+ const hiddenInFlight = new Map();
25
+ return {
26
+ onToolStart(name, args) {
27
+ const description = (0, tool_description_1.humanReadableToolDescription)(name, args);
28
+ if (description === null) {
29
+ // hidden tool (settle, rest, descend, observe, speak) — track so the
30
+ // matching onToolEnd is also suppressed symmetrically.
31
+ hiddenInFlight.set(name, (hiddenInFlight.get(name) ?? 0) + 1);
32
+ return;
33
+ }
34
+ lastDescription = description;
35
+ options.onDescription(description);
36
+ },
37
+ onToolEnd(name, summary, success) {
38
+ const hiddenCount = hiddenInFlight.get(name) ?? 0;
39
+ if (hiddenCount > 0) {
40
+ // Hidden tool's start was suppressed; suppress its end too.
41
+ if (hiddenCount === 1)
42
+ hiddenInFlight.delete(name);
43
+ else
44
+ hiddenInFlight.set(name, hiddenCount - 1);
45
+ return;
46
+ }
47
+ const desc = lastDescription ?? name;
48
+ // Strip trailing "..." from description for the result line
49
+ const cleanDesc = desc.endsWith("...") ? desc.slice(0, -3) : desc;
50
+ if (!success) {
51
+ options.onFailure(`✗ ${cleanDesc} — ${summary}`);
52
+ return;
53
+ }
54
+ if (options.isDebug()) {
55
+ options.onResult(`✓ ${cleanDesc}`);
56
+ }
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApprovalExecutionFailedError = exports.ApprovalExecutionIndeterminateError = void 0;
4
+ exports.coordinateApprovalDecision = coordinateApprovalDecision;
5
+ exports.digestApprovalSuspensionCheckpointPayload = digestApprovalSuspensionCheckpointPayload;
6
+ exports.commitApprovalProposal = commitApprovalProposal;
7
+ exports.recoverApprovalProposals = recoverApprovalProposals;
8
+ exports.executeApprovalDecision = executeApprovalDecision;
9
+ exports.recoverClaimedApproval = recoverClaimedApproval;
10
+ exports.recoverAttemptedApproval = recoverAttemptedApproval;
11
+ const node_crypto_1 = require("node:crypto");
12
+ const approval_store_1 = require("./approval-store");
13
+ const runtime_1 = require("../nerves/runtime");
14
+ const tool_arguments_1 = require("../repertoire/tool-arguments");
15
+ class ApprovalExecutionIndeterminateError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = "ApprovalExecutionIndeterminateError";
19
+ }
20
+ }
21
+ exports.ApprovalExecutionIndeterminateError = ApprovalExecutionIndeterminateError;
22
+ class ApprovalExecutionFailedError extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "ApprovalExecutionFailedError";
26
+ }
27
+ }
28
+ exports.ApprovalExecutionFailedError = ApprovalExecutionFailedError;
29
+ async function coordinateApprovalDecision(options) {
30
+ return options.withSessionLease(async (lease) => {
31
+ let currentSessionRevision = options.readCurrentRevision();
32
+ const record = await options.decideAndExecute({
33
+ currentSessionRevision,
34
+ lease,
35
+ hooks: {
36
+ afterClaim: async () => {
37
+ currentSessionRevision = options.readCurrentRevision();
38
+ },
39
+ },
40
+ });
41
+ await options.persist?.(record);
42
+ await options.resume(record);
43
+ (0, runtime_1.emitNervesEvent)({
44
+ component: "engine",
45
+ event: "engine.approval_decision_coordinated",
46
+ message: "approval decision coordinated under session turn lease",
47
+ meta: { approvalId: record.approvalId, state: record.state },
48
+ });
49
+ return { record };
50
+ });
51
+ }
52
+ function checkpointMatches(record, checkpoint) {
53
+ return checkpoint.approvalId === record.approvalId
54
+ && checkpoint.checkpointDigest === record.checkpointDigest
55
+ && checkpoint.baseSessionRevision === record.baseSessionRevision
56
+ && (record.state === "preparing" || checkpoint.suspendedSessionRevision === record.suspendedSessionRevision)
57
+ && checkpoint.argumentDigest === record.argumentDigest
58
+ && checkpoint.schemaDigest === record.schemaDigest
59
+ && checkpoint.toolDigest === record.toolDigest
60
+ && checkpoint.policyDigest === record.policyDigest
61
+ && checkpoint.preCallDigest === digestTranscript(checkpoint.preCallMessages)
62
+ && record.checkpointDigest === digestApprovalSuspensionCheckpointPayload(checkpoint)
63
+ && JSON.stringify(checkpoint.frozenAssistantMessage) === JSON.stringify(record.frozenAssistantMessage);
64
+ }
65
+ function frozenCallMatches(record, checkpoint) {
66
+ const message = checkpoint.frozenAssistantMessage;
67
+ if (message.role !== "assistant")
68
+ return false;
69
+ if (!Array.isArray(message.tool_calls) || message.tool_calls.length !== 1)
70
+ return false;
71
+ const call = message.tool_calls[0];
72
+ if (!call || typeof call !== "object" || Array.isArray(call))
73
+ return false;
74
+ const callRecord = call;
75
+ if (callRecord.type !== "function")
76
+ return false;
77
+ const fn = callRecord.function;
78
+ if (!fn || typeof fn !== "object" || Array.isArray(fn))
79
+ return false;
80
+ const functionRecord = fn;
81
+ if (callRecord.id !== record.toolCallId || functionRecord.name !== record.toolName || typeof functionRecord.arguments !== "string")
82
+ return false;
83
+ try {
84
+ const parsed = JSON.parse(functionRecord.arguments);
85
+ return JSON.stringify(parsed) === JSON.stringify(record.arguments);
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ }
91
+ function digestTranscript(messages) {
92
+ return (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(messages), "utf8").digest("hex");
93
+ }
94
+ function digestApprovalSuspensionCheckpointPayload(checkpoint) {
95
+ return (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({
96
+ baseSessionRevision: checkpoint.baseSessionRevision,
97
+ argumentDigest: checkpoint.argumentDigest,
98
+ schemaDigest: checkpoint.schemaDigest,
99
+ toolDigest: checkpoint.toolDigest,
100
+ policyDigest: checkpoint.policyDigest,
101
+ preCallDigest: checkpoint.preCallDigest,
102
+ preCallMessages: checkpoint.preCallMessages,
103
+ frozenAssistantMessage: checkpoint.frozenAssistantMessage,
104
+ }), "utf8").digest("hex");
105
+ }
106
+ function digestDecisionToken(token) {
107
+ return (0, node_crypto_1.createHash)("sha256").update(token, "utf8").digest("hex");
108
+ }
109
+ function commitApprovalProposal(options) {
110
+ (0, runtime_1.emitNervesEvent)({
111
+ component: "engine",
112
+ event: "engine.approval_proposal_commit_start",
113
+ message: "approval proposal commit started",
114
+ meta: { toolName: options.proposal.toolName, toolCallId: options.proposal.toolCallId },
115
+ });
116
+ const preCallDigest = digestTranscript(options.preCallMessages);
117
+ const checkpointDigest = digestApprovalSuspensionCheckpointPayload({
118
+ baseSessionRevision: options.proposal.baseSessionRevision,
119
+ argumentDigest: (0, approval_store_1.canonicalApprovalArguments)(options.proposal.arguments).digest,
120
+ schemaDigest: options.proposal.schemaDigest,
121
+ toolDigest: options.proposal.toolDigest,
122
+ policyDigest: options.proposal.policyDigest,
123
+ preCallDigest,
124
+ preCallMessages: options.preCallMessages,
125
+ frozenAssistantMessage: options.proposal.frozenAssistantMessage,
126
+ });
127
+ const prepared = options.approvalStore.prepare({ ...options.proposal, checkpointDigest });
128
+ options.hooks?.afterJournalPrepare?.();
129
+ options.tokenStore.put(prepared.record.approvalId, prepared.decisionToken);
130
+ options.hooks?.afterTokenPersist?.();
131
+ const attestation = options.checkpointStore.write({
132
+ approvalId: prepared.record.approvalId,
133
+ baseSessionRevision: prepared.record.baseSessionRevision,
134
+ argumentDigest: prepared.record.argumentDigest,
135
+ schemaDigest: prepared.record.schemaDigest,
136
+ toolDigest: prepared.record.toolDigest,
137
+ policyDigest: prepared.record.policyDigest,
138
+ preCallDigest,
139
+ preCallMessages: structuredClone(options.preCallMessages),
140
+ frozenAssistantMessage: structuredClone(prepared.record.frozenAssistantMessage),
141
+ });
142
+ options.hooks?.afterCheckpointWrite?.();
143
+ if (attestation.checkpointDigest !== prepared.record.checkpointDigest) {
144
+ options.tokenStore.remove(prepared.record.approvalId);
145
+ options.checkpointStore.remove(prepared.record.approvalId);
146
+ options.approvalStore.recoverPreparing({
147
+ approvalId: prepared.record.approvalId,
148
+ state: "drifted",
149
+ reason: "checkpoint attestation digest mismatch",
150
+ });
151
+ (0, runtime_1.emitNervesEvent)({
152
+ level: "error",
153
+ component: "engine",
154
+ event: "engine.approval_checkpoint_attestation_mismatch",
155
+ message: "approval checkpoint durability attestation did not match proposal",
156
+ meta: { approvalId: prepared.record.approvalId },
157
+ });
158
+ throw new approval_store_1.ApprovalStoreError("checkpoint_attestation_mismatch");
159
+ }
160
+ const record = options.approvalStore.activate({
161
+ approvalId: prepared.record.approvalId,
162
+ checkpointDigest: attestation.checkpointDigest,
163
+ suspendedSessionRevision: attestation.suspendedSessionRevision,
164
+ });
165
+ (0, runtime_1.emitNervesEvent)({
166
+ component: "engine",
167
+ event: "engine.approval_proposal_commit_end",
168
+ message: "approval proposal checkpoint activated",
169
+ meta: { approvalId: record.approvalId },
170
+ });
171
+ return { record, decisionToken: prepared.decisionToken };
172
+ }
173
+ function recoverApprovalProposals(options) {
174
+ const recovered = [];
175
+ const preparing = options.approvalStore.listPreparing();
176
+ const preparingIds = new Set(preparing.map((record) => record.approvalId));
177
+ for (const checkpoint of options.checkpointStore.list()) {
178
+ if (preparingIds.has(checkpoint.approvalId) || options.approvalStore.read(checkpoint.approvalId))
179
+ continue;
180
+ options.checkpointStore.remove(checkpoint.approvalId);
181
+ recovered.push({ approvalId: checkpoint.approvalId, state: "orphan_checkpoint_removed" });
182
+ (0, runtime_1.emitNervesEvent)({
183
+ level: "warn",
184
+ component: "engine",
185
+ event: "engine.approval_orphan_checkpoint_removed",
186
+ message: "removed approval checkpoint with no journal authority",
187
+ meta: { approvalId: checkpoint.approvalId },
188
+ });
189
+ }
190
+ for (const record of preparing) {
191
+ const checkpoint = options.checkpointStore.read(record.approvalId);
192
+ const token = options.tokenStore.get(record.approvalId);
193
+ const hasToken = token !== null;
194
+ const tokenMatches = token !== null && digestDecisionToken(token) === record.decisionTokenDigest;
195
+ if (checkpoint && tokenMatches && checkpointMatches(record, checkpoint)) {
196
+ const activated = options.approvalStore.activate({
197
+ approvalId: record.approvalId,
198
+ checkpointDigest: checkpoint.checkpointDigest,
199
+ suspendedSessionRevision: checkpoint.suspendedSessionRevision,
200
+ });
201
+ recovered.push({ approvalId: record.approvalId, state: activated.state });
202
+ continue;
203
+ }
204
+ options.tokenStore.remove(record.approvalId);
205
+ if (checkpoint)
206
+ options.checkpointStore.remove(record.approvalId);
207
+ const checkpointMismatch = checkpoint !== null && !checkpointMatches(record, checkpoint);
208
+ const tokenMismatch = hasToken && !tokenMatches;
209
+ const mismatch = checkpointMismatch || tokenMismatch;
210
+ const terminal = options.approvalStore.recoverPreparing({
211
+ approvalId: record.approvalId,
212
+ state: mismatch ? "drifted" : "abandoned_before_attempt",
213
+ reason: tokenMismatch ? "decision token evidence mismatch" : mismatch ? "checkpoint evidence mismatch" : "incomplete proposal commit",
214
+ });
215
+ recovered.push({ approvalId: record.approvalId, state: terminal.state });
216
+ }
217
+ (0, runtime_1.emitNervesEvent)({
218
+ component: "engine",
219
+ event: "engine.approval_proposal_recovery",
220
+ message: "approval proposal recovery scan completed",
221
+ meta: { recoveredCount: recovered.length },
222
+ });
223
+ return recovered;
224
+ }
225
+ function terminalizeClaimed(store, claimed, state, reason) {
226
+ (0, runtime_1.emitNervesEvent)({
227
+ level: "warn",
228
+ component: "engine",
229
+ event: "engine.approval_pre_attempt_terminalized",
230
+ message: "approval stopped during live revalidation",
231
+ meta: { approvalId: claimed.approvalId, state, reason },
232
+ });
233
+ return store.terminalizeBeforeAttempt({
234
+ approvalId: claimed.approvalId,
235
+ ownerId: claimed.ownerId,
236
+ epoch: claimed.epoch,
237
+ state,
238
+ reason,
239
+ });
240
+ }
241
+ async function executeApprovalDecision(options) {
242
+ const decided = options.approvalStore.decide({ ...options.decision, ownerId: options.ownerId });
243
+ if (decided.state !== "claimed")
244
+ return decided;
245
+ await options.hooks?.afterClaim?.();
246
+ if (options.currentSessionRevision !== decided.suspendedSessionRevision) {
247
+ return terminalizeClaimed(options.approvalStore, decided, "session_head_changed", "suspended session revision changed");
248
+ }
249
+ const checkpoint = options.checkpointStore.read(decided.approvalId);
250
+ if (!checkpoint || !checkpointMatches(decided, checkpoint) || !frozenCallMatches(decided, checkpoint)) {
251
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", "checkpoint evidence drift");
252
+ }
253
+ const definition = options.resolveTool(decided.toolName);
254
+ if (!definition || definition.tool.function.name !== decided.toolName) {
255
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", "tool identity drift");
256
+ }
257
+ const schema = definition.tool.function.parameters;
258
+ if (!schema || typeof schema !== "object") {
259
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", "advertised schema missing");
260
+ }
261
+ const validated = (0, tool_arguments_1.validateAdvertisedToolArguments)(JSON.stringify(decided.arguments), schema);
262
+ if (!validated.ok || validated.value.argumentDigest !== decided.argumentDigest
263
+ || validated.value.schemaDigest !== decided.schemaDigest) {
264
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", "tool arguments or schema drift");
265
+ }
266
+ const policy = await options.resolveApprovalPolicy?.(decided.toolName, validated.value.arguments)
267
+ ?? definition.approvalPolicy?.(validated.value.arguments)
268
+ ?? { kind: "not_required" };
269
+ if (policy.kind !== "required") {
270
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", "approval policy no longer requires approval");
271
+ }
272
+ const toolDigest = (0, tool_arguments_1.digestJson)({ name: decided.toolName, schemaDigest: validated.value.schemaDigest, policyId: policy.policyId });
273
+ const policyDigest = (0, tool_arguments_1.digestJson)({ policyId: policy.policyId, actionClass: policy.actionClass, classification: "required" });
274
+ if (policy.policyId !== decided.policyId || toolDigest !== decided.toolDigest || policyDigest !== decided.policyDigest) {
275
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", "approval policy or tool digest drift");
276
+ }
277
+ const context = {
278
+ record: structuredClone(decided),
279
+ checkpoint: structuredClone(checkpoint),
280
+ definition,
281
+ arguments: structuredClone(validated.value.arguments),
282
+ };
283
+ const guard = await options.liveGuard(context);
284
+ if (!guard.ok)
285
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", guard.reason);
286
+ const risk = await options.liveRisk(context);
287
+ if (!risk.ok)
288
+ return terminalizeClaimed(options.approvalStore, decided, "drifted", risk.reason);
289
+ const attempted = options.approvalStore.markAttempted({
290
+ approvalId: decided.approvalId,
291
+ ownerId: decided.ownerId,
292
+ epoch: decided.epoch,
293
+ });
294
+ await options.hooks?.afterAttempt?.();
295
+ let result;
296
+ try {
297
+ result = await options.execute(attempted.toolName, structuredClone(attempted.arguments));
298
+ }
299
+ catch (error) {
300
+ if (!(error instanceof ApprovalExecutionFailedError))
301
+ throw error;
302
+ await options.hooks?.afterHandler?.();
303
+ return options.approvalStore.complete({
304
+ approvalId: attempted.approvalId,
305
+ ownerId: attempted.ownerId,
306
+ epoch: attempted.epoch,
307
+ state: "failed",
308
+ result: `error: ${error.message}`,
309
+ });
310
+ }
311
+ await options.hooks?.afterHandler?.();
312
+ return options.approvalStore.complete({
313
+ approvalId: attempted.approvalId,
314
+ ownerId: attempted.ownerId,
315
+ epoch: attempted.epoch,
316
+ state: "succeeded",
317
+ result,
318
+ });
319
+ }
320
+ function recoverClaimedApproval(options) {
321
+ const record = options.approvalStore.read(options.approvalId);
322
+ if (!record || record.state !== "claimed" || !record.ownerId)
323
+ throw new approval_store_1.ApprovalStoreError("claimed_recovery_not_eligible");
324
+ return options.approvalStore.abandonBeforeAttempt({
325
+ approvalId: record.approvalId,
326
+ ownerId: record.ownerId,
327
+ epoch: record.epoch,
328
+ reason: options.reason,
329
+ });
330
+ }
331
+ function recoverAttemptedApproval(options) {
332
+ const record = options.approvalStore.read(options.approvalId);
333
+ if (!record || record.state !== "attempted" || !record.ownerId)
334
+ throw new approval_store_1.ApprovalStoreError("attempted_recovery_not_eligible");
335
+ return options.approvalStore.complete({
336
+ approvalId: record.approvalId,
337
+ ownerId: record.ownerId,
338
+ epoch: record.epoch,
339
+ state: "attempted_indeterminate",
340
+ result: "execution outcome is indeterminate after restart; action was not retried",
341
+ });
342
+ }
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.humanReadableToolDescription = humanReadableToolDescription;
4
+ const runtime_1 = require("../nerves/runtime");
5
+ function basename(filePath) {
6
+ const idx = filePath.lastIndexOf("/");
7
+ return idx >= 0 ? filePath.slice(idx + 1) : filePath;
8
+ }
9
+ function truncate(text, max) {
10
+ if (text.length <= max)
11
+ return text;
12
+ // Cut at last space before maxLen to avoid mid-word truncation
13
+ const slice = text.slice(0, max - 1);
14
+ const lastSpace = slice.lastIndexOf(" ");
15
+ if (lastSpace > 0)
16
+ return text.slice(0, lastSpace) + "\u2026";
17
+ // No space found (single long word) — hard truncate
18
+ return slice + "\u2026";
19
+ }
20
+ const TOOL_DESCRIPTIONS = {
21
+ // File operations
22
+ shell: (args) => {
23
+ const cmd = args.command;
24
+ if (!cmd)
25
+ return "running a command...";
26
+ return `running ${truncate(cmd, 50)}...`;
27
+ },
28
+ read_file: (args) => {
29
+ const fp = args.path || args.file_path;
30
+ if (!fp)
31
+ return "reading a file...";
32
+ return `reading ${basename(fp)}...`;
33
+ },
34
+ write_file: (args) => {
35
+ const fp = args.path || args.file_path;
36
+ if (!fp)
37
+ return "writing a file...";
38
+ return `writing ${basename(fp)}...`;
39
+ },
40
+ edit_file: (args) => {
41
+ const fp = args.path || args.file_path;
42
+ if (!fp)
43
+ return "editing a file...";
44
+ return `editing ${basename(fp)}...`;
45
+ },
46
+ glob: (args) => {
47
+ const p = args.pattern;
48
+ if (!p)
49
+ return "searching for files...";
50
+ return `searching for ${truncate(p, 40)}...`;
51
+ },
52
+ grep: (args) => {
53
+ const p = args.pattern;
54
+ if (!p)
55
+ return "searching code...";
56
+ return `searching code for '${truncate(p, 40)}'...`;
57
+ },
58
+ // Notes and knowledge
59
+ search_facts: (args) => {
60
+ const q = args.query;
61
+ if (!q)
62
+ return "searching facts...";
63
+ return `searching facts for '${truncate(q, 40)}'...`;
64
+ },
65
+ consult_diary: (args) => {
66
+ const q = args.query;
67
+ if (!q)
68
+ return "checking recent diary facts...";
69
+ return `consulting diary facts for '${truncate(q, 40)}'...`;
70
+ },
71
+ consult_notes: (args) => {
72
+ const q = args.query;
73
+ if (!q)
74
+ return "checking Desk record notes...";
75
+ return `consulting Desk record notes for '${truncate(q, 40)}'...`;
76
+ },
77
+ diary_write: (args) => {
78
+ const about = args.about;
79
+ return about ? `noting something about ${truncate(about, 30)}...` : "noting something down...";
80
+ },
81
+ save_friend_note: () => "making a note about you...",
82
+ get_friend_note: () => "checking my notes...",
83
+ load_skill: (args) => {
84
+ const name = args.name || args.skill;
85
+ return name ? `loading ${name} skill...` : "loading a skill...";
86
+ },
87
+ // Session and context
88
+ query_session: (args) => {
89
+ const mode = args.mode;
90
+ if (mode === "search")
91
+ return `searching session for '${truncate(args.query || "", 30)}'...`;
92
+ if (mode === "status")
93
+ return "checking private-runtime turn status...";
94
+ return "checking session history...";
95
+ },
96
+ web_search: (args) => {
97
+ const q = args.query;
98
+ return q ? `searching the web for '${truncate(q, 35)}'...` : "searching the web...";
99
+ },
100
+ coding_spawn: (args) => {
101
+ const runner = args.runner;
102
+ return runner ? `starting ${runner} coding session...` : "starting coding session...";
103
+ },
104
+ coding_status: () => "checking coding sessions...",
105
+ coding_tail: () => "reading coding output...",
106
+ coding_kill: () => "stopping coding session...",
107
+ bridge_manage: () => "managing conversation bridge...",
108
+ // Communication
109
+ send_message: (args) => {
110
+ const to = args.to || args.friendId;
111
+ /* v8 ignore next 3 -- voice-send status wording is exercised by outbound voice tool tests; this generic renderer keeps a defensive fallback @preserve */
112
+ if (args.channel === "voice") {
113
+ return to ? `placing a voice call to ${to}...` : "placing a voice call...";
114
+ }
115
+ return to ? `sending a message to ${to}...` : "sending a message...";
116
+ },
117
+ surface: () => "sharing a thought...",
118
+ // Metacognitive (private runtime)
119
+ ponder: (args) => {
120
+ const objective = args.objective || args.thought;
121
+ return objective ? `bookmarking ${truncate(objective, 40)}...` : "bookmarking deeper work...";
122
+ },
123
+ observe: () => null,
124
+ claude: () => "reasoning...",
125
+ set_reasoning_effort: (args) => {
126
+ const level = args.level;
127
+ return level ? `setting thinking depth to ${level}...` : "adjusting thinking depth...";
128
+ },
129
+ // Hidden — these ARE the response or end-of-turn
130
+ settle: () => null,
131
+ rest: () => null,
132
+ descend: () => null,
133
+ // speak's visible output is the message itself, delivered via onTextChunk +
134
+ // flushNow. The shared tool-activity callbacks must skip it so no per-sense
135
+ // tool-status text precedes the actual message.
136
+ speak: () => null,
137
+ };
138
+ function humanReadableToolDescription(name, args) {
139
+ (0, runtime_1.emitNervesEvent)({
140
+ component: "engine",
141
+ event: "engine.tool_description",
142
+ message: "generated human-readable tool description",
143
+ meta: { tool: name },
144
+ });
145
+ const builder = TOOL_DESCRIPTIONS[name];
146
+ if (builder)
147
+ return builder(args);
148
+ // MCP tools: mcp__server__toolname — extract last segment
149
+ if (name.startsWith("mcp__")) {
150
+ const parts = name.split("__");
151
+ const toolName = parts[parts.length - 1];
152
+ return `using ${toolName}...`;
153
+ }
154
+ return `using ${name}...`;
155
+ }