@ouro.bot/cli 0.1.0-alpha.69 → 0.1.0-alpha.691

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 (480) hide show
  1. package/README.md +133 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +4398 -14
  13. package/dist/a2a/card.js +57 -0
  14. package/dist/a2a/client.js +180 -0
  15. package/dist/a2a/config.js +50 -0
  16. package/dist/a2a/delegation-stores.js +56 -0
  17. package/dist/a2a/did-resolution.js +93 -0
  18. package/dist/a2a/identity.js +170 -0
  19. package/dist/a2a/inbound-share.js +107 -0
  20. package/dist/a2a/mission-result-wire.js +196 -0
  21. package/dist/a2a/onboarding.js +115 -0
  22. package/dist/a2a/pin-store.js +132 -0
  23. package/dist/a2a/seen-ledger.js +120 -0
  24. package/dist/a2a/server.js +604 -0
  25. package/dist/a2a/task-store.js +69 -0
  26. package/dist/a2a/transport.js +45 -0
  27. package/dist/a2a/types.js +3 -0
  28. package/dist/arc/attention-types.js +8 -0
  29. package/dist/arc/cares.js +144 -0
  30. package/dist/arc/episodes.js +118 -0
  31. package/dist/arc/evolution.js +490 -0
  32. package/dist/arc/flight-recorder.js +810 -0
  33. package/dist/arc/intentions.js +134 -0
  34. package/dist/arc/json-store.js +117 -0
  35. package/dist/arc/obligations.js +326 -0
  36. package/dist/arc/packets.js +288 -0
  37. package/dist/arc/presence.js +185 -0
  38. package/dist/arc/task-lifecycle.js +57 -0
  39. package/dist/commerce/store.js +755 -0
  40. package/dist/commerce/types.js +3 -0
  41. package/dist/heart/active-work.js +867 -43
  42. package/dist/heart/agent-entry.js +160 -3
  43. package/dist/heart/attachments/image-normalize.js +194 -0
  44. package/dist/heart/attachments/materialize.js +97 -0
  45. package/dist/heart/attachments/originals.js +88 -0
  46. package/dist/heart/attachments/render.js +29 -0
  47. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  48. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  49. package/dist/heart/attachments/sources/index.js +16 -0
  50. package/dist/heart/attachments/store.js +103 -0
  51. package/dist/heart/attachments/types.js +93 -0
  52. package/dist/heart/auth/auth-flow.js +479 -0
  53. package/dist/heart/awaiting/await-alert.js +146 -0
  54. package/dist/heart/awaiting/await-expiry.js +108 -0
  55. package/dist/heart/awaiting/await-loader.js +91 -0
  56. package/dist/heart/awaiting/await-parser.js +141 -0
  57. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  58. package/dist/heart/awaiting/await-scheduler.js +378 -0
  59. package/dist/heart/background-operations.js +281 -0
  60. package/dist/heart/bridges/manager.js +137 -17
  61. package/dist/heart/bridges/store.js +14 -2
  62. package/dist/heart/bundle-state.js +168 -0
  63. package/dist/heart/commitments.js +135 -0
  64. package/dist/heart/config-registry.js +331 -0
  65. package/dist/heart/config.js +122 -119
  66. package/dist/heart/context-loss-gauntlet.js +354 -0
  67. package/dist/heart/context-loss-sentinel.js +993 -0
  68. package/dist/heart/core.js +1297 -269
  69. package/dist/heart/cross-chat-delivery.js +8 -22
  70. package/dist/heart/daemon/agent-config-check.js +451 -0
  71. package/dist/heart/daemon/agent-discovery.js +185 -3
  72. package/dist/heart/daemon/agent-service.js +523 -0
  73. package/dist/heart/daemon/agentic-repair.js +547 -0
  74. package/dist/heart/daemon/await-private-wake.js +59 -0
  75. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  76. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  77. package/dist/heart/daemon/cadence.js +70 -0
  78. package/dist/heart/daemon/cli-defaults.js +780 -0
  79. package/dist/heart/daemon/cli-desk.js +322 -0
  80. package/dist/heart/daemon/cli-exec.js +8100 -0
  81. package/dist/heart/daemon/cli-help.js +601 -0
  82. package/dist/heart/daemon/cli-parse.js +1995 -0
  83. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  84. package/dist/heart/daemon/cli-render.js +770 -0
  85. package/dist/heart/daemon/cli-types.js +8 -0
  86. package/dist/heart/daemon/connect-bay.js +323 -0
  87. package/dist/heart/daemon/daemon-cli.js +29 -1814
  88. package/dist/heart/daemon/daemon-entry.js +668 -6
  89. package/dist/heart/daemon/daemon-health.js +176 -0
  90. package/dist/heart/daemon/daemon-rollup.js +57 -0
  91. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  92. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  93. package/dist/heart/daemon/daemon.js +1222 -84
  94. package/dist/heart/daemon/dns-workflow.js +394 -0
  95. package/dist/heart/daemon/doctor-types.js +8 -0
  96. package/dist/heart/daemon/doctor.js +873 -0
  97. package/dist/heart/daemon/habit-private-wake.js +56 -0
  98. package/dist/heart/daemon/health-monitor.js +131 -3
  99. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  100. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  101. package/dist/heart/daemon/http-health-probe.js +80 -0
  102. package/dist/heart/daemon/human-command-screens.js +234 -0
  103. package/dist/heart/daemon/human-readiness.js +114 -0
  104. package/dist/heart/daemon/inner-status.js +78 -0
  105. package/dist/heart/daemon/interactive-repair.js +394 -0
  106. package/dist/heart/daemon/launchd.js +37 -8
  107. package/dist/heart/daemon/log-tailer.js +79 -10
  108. package/dist/heart/daemon/logs-prune.js +110 -0
  109. package/dist/heart/daemon/mcp-canary.js +297 -0
  110. package/dist/heart/daemon/message-router.js +45 -5
  111. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  112. package/dist/heart/daemon/os-cron-deps.js +135 -0
  113. package/dist/heart/daemon/os-cron.js +14 -12
  114. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  115. package/dist/heart/daemon/ouro-entry.js +3 -1
  116. package/dist/heart/daemon/plugin-cli.js +432 -0
  117. package/dist/heart/daemon/process-manager.js +519 -40
  118. package/dist/heart/daemon/provider-discovery.js +137 -0
  119. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  120. package/dist/heart/daemon/pulse.js +511 -0
  121. package/dist/heart/daemon/readiness-repair.js +365 -0
  122. package/dist/heart/daemon/run-hooks.js +2 -0
  123. package/dist/heart/daemon/runtime-logging.js +41 -14
  124. package/dist/heart/daemon/runtime-metadata.js +2 -30
  125. package/dist/heart/daemon/safe-mode.js +161 -0
  126. package/dist/heart/daemon/sense-manager.js +583 -43
  127. package/dist/heart/daemon/session-id-resolver.js +131 -0
  128. package/dist/heart/daemon/skill-management-installer.js +1 -1
  129. package/dist/heart/daemon/socket-client.js +171 -12
  130. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  131. package/dist/heart/daemon/startup-tui.js +338 -0
  132. package/dist/heart/daemon/task-scheduler.js +117 -39
  133. package/dist/heart/daemon/terminal-ui.js +499 -0
  134. package/dist/heart/daemon/thoughts.js +255 -43
  135. package/dist/heart/daemon/up-progress.js +366 -0
  136. package/dist/heart/daemon/vault-items.js +56 -0
  137. package/dist/heart/delegation.js +1 -4
  138. package/dist/heart/external-events/router.js +121 -0
  139. package/dist/heart/habits/habit-migration.js +189 -0
  140. package/dist/heart/habits/habit-parser.js +211 -0
  141. package/dist/heart/habits/habit-runtime-state.js +114 -0
  142. package/dist/heart/habits/habit-scheduler.js +411 -0
  143. package/dist/heart/habits/habit-session-summary.js +318 -0
  144. package/dist/heart/habits/habit-session.js +618 -0
  145. package/dist/heart/{daemon → hatch}/hatch-flow.js +51 -57
  146. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  147. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  148. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  149. package/dist/heart/identity.js +174 -58
  150. package/dist/heart/kept-notes.js +289 -0
  151. package/dist/heart/kicks.js +1 -1
  152. package/dist/heart/machine-identity.js +161 -0
  153. package/dist/heart/mail-import-discovery.js +353 -0
  154. package/dist/heart/mailbox/mailbox-http-hooks.js +96 -0
  155. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  156. package/dist/heart/mailbox/mailbox-http-routes.js +375 -0
  157. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  158. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  159. package/dist/heart/mailbox/mailbox-http.js +99 -0
  160. package/dist/heart/mailbox/mailbox-read.js +37 -0
  161. package/dist/heart/mailbox/mailbox-types.js +27 -0
  162. package/dist/heart/mailbox/mailbox-view.js +197 -0
  163. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  164. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  165. package/dist/heart/mailbox/readers/mail.js +375 -0
  166. package/dist/heart/mailbox/readers/runtime-readers.js +815 -0
  167. package/dist/heart/mailbox/readers/sessions.js +232 -0
  168. package/dist/heart/mailbox/readers/shared.js +111 -0
  169. package/dist/heart/mcp/mcp-server.js +696 -0
  170. package/dist/heart/migrate-config.js +100 -0
  171. package/dist/heart/model-capabilities.js +19 -0
  172. package/dist/heart/orientation-frame.js +217 -0
  173. package/dist/heart/platform.js +81 -0
  174. package/dist/heart/primitives.js +1 -1
  175. package/dist/heart/private-runtime/decision-renderer.js +156 -0
  176. package/dist/heart/private-runtime/index.js +18 -0
  177. package/dist/heart/private-runtime/ledger.js +218 -0
  178. package/dist/heart/private-runtime/policy.js +214 -0
  179. package/dist/heart/private-runtime/types.js +2 -0
  180. package/dist/heart/progress-story.js +1 -1
  181. package/dist/heart/provider-attempt.js +134 -0
  182. package/dist/heart/provider-binding-resolver.js +273 -0
  183. package/dist/heart/provider-credentials.js +425 -0
  184. package/dist/heart/provider-failover.js +311 -0
  185. package/dist/heart/provider-models.js +81 -0
  186. package/dist/heart/provider-ping.js +262 -0
  187. package/dist/heart/provider-readiness-cache.js +119 -0
  188. package/dist/heart/provider-visibility.js +188 -0
  189. package/dist/heart/providers/anthropic-token.js +131 -0
  190. package/dist/heart/providers/anthropic.js +139 -52
  191. package/dist/heart/providers/azure.js +23 -11
  192. package/dist/heart/providers/error-classification.js +127 -0
  193. package/dist/heart/providers/github-copilot.js +145 -0
  194. package/dist/heart/providers/minimax-vlm.js +189 -0
  195. package/dist/heart/providers/minimax.js +26 -8
  196. package/dist/heart/providers/openai-codex-token.js +349 -0
  197. package/dist/heart/providers/openai-codex.js +55 -40
  198. package/dist/heart/runtime-capability-check.js +170 -0
  199. package/dist/heart/runtime-credentials.js +389 -0
  200. package/dist/heart/runtime-cwd.js +87 -0
  201. package/dist/heart/sense-truth.js +17 -4
  202. package/dist/heart/session-activity.js +90 -24
  203. package/dist/heart/session-events.js +1133 -0
  204. package/dist/heart/session-playback-cli-main.js +5 -0
  205. package/dist/heart/session-playback-cli.js +36 -0
  206. package/dist/heart/session-playback.js +231 -0
  207. package/dist/heart/session-stats-cli-main.js +5 -0
  208. package/dist/heart/session-stats.js +182 -0
  209. package/dist/heart/session-transcript.js +133 -0
  210. package/dist/heart/start-of-turn-packet.js +365 -0
  211. package/dist/heart/streaming.js +44 -27
  212. package/dist/heart/structured-output.js +196 -0
  213. package/dist/heart/sync-classification.js +176 -0
  214. package/dist/heart/sync.js +449 -0
  215. package/dist/heart/target-resolution.js +11 -7
  216. package/dist/heart/tempo.js +93 -0
  217. package/dist/heart/temporal-view.js +41 -0
  218. package/dist/heart/timeouts.js +101 -0
  219. package/dist/heart/tool-activity-callbacks.js +59 -0
  220. package/dist/heart/tool-description.js +155 -0
  221. package/dist/heart/tool-friction.js +55 -0
  222. package/dist/heart/tool-loop.js +200 -0
  223. package/dist/heart/turn-context.js +450 -0
  224. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  225. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  226. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  227. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  228. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  229. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  230. package/dist/heart/versioning/update-hooks.js +154 -0
  231. package/dist/heart/work-card.js +390 -0
  232. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  233. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  234. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  235. package/dist/mailbox-ui/index.html +16 -0
  236. package/dist/mailroom/attention.js +167 -0
  237. package/dist/mailroom/autonomy.js +209 -0
  238. package/dist/mailroom/blob-store.js +715 -0
  239. package/dist/mailroom/body-cache.js +61 -0
  240. package/dist/mailroom/core.js +788 -0
  241. package/dist/mailroom/entry.js +160 -0
  242. package/dist/mailroom/file-store.js +568 -0
  243. package/dist/mailroom/mbox-import.js +393 -0
  244. package/dist/mailroom/migration.js +164 -0
  245. package/dist/mailroom/outbound.js +380 -0
  246. package/dist/mailroom/policy.js +263 -0
  247. package/dist/mailroom/reader.js +233 -0
  248. package/dist/mailroom/search-cache.js +334 -0
  249. package/dist/mailroom/search-relevance.js +319 -0
  250. package/dist/mailroom/smtp-ingress.js +176 -0
  251. package/dist/mailroom/source-state.js +176 -0
  252. package/dist/mailroom/thread.js +109 -0
  253. package/dist/mailroom/travel-extract.js +89 -0
  254. package/dist/mind/bundle-manifest.js +24 -2
  255. package/dist/mind/context.js +250 -101
  256. package/dist/mind/desk-section.js +362 -0
  257. package/dist/mind/diary-integrity.js +60 -0
  258. package/dist/mind/{memory.js → diary.js} +68 -77
  259. package/dist/mind/embedding-provider.js +60 -0
  260. package/dist/mind/file-state.js +179 -0
  261. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  262. package/dist/mind/obligation-steering.js +221 -0
  263. package/dist/mind/pending.js +13 -8
  264. package/dist/mind/prompt-refresh.js +3 -2
  265. package/dist/mind/prompt.js +1009 -169
  266. package/dist/mind/provenance-trust.js +26 -0
  267. package/dist/mind/record-paths.js +312 -0
  268. package/dist/mind/scrutiny.js +173 -0
  269. package/dist/nerves/cli-logging.js +7 -1
  270. package/dist/nerves/coverage/audit-rules.js +15 -6
  271. package/dist/nerves/coverage/audit.js +28 -2
  272. package/dist/nerves/coverage/cli.js +1 -1
  273. package/dist/nerves/coverage/contract.js +5 -5
  274. package/dist/nerves/coverage/file-completeness.js +139 -5
  275. package/dist/nerves/event-buffer.js +111 -0
  276. package/dist/nerves/index.js +224 -4
  277. package/dist/nerves/observation.js +20 -0
  278. package/dist/nerves/redact.js +79 -0
  279. package/dist/nerves/review/cli-main.js +5 -0
  280. package/dist/nerves/review/cli.js +156 -0
  281. package/dist/nerves/review/core.js +152 -0
  282. package/dist/nerves/runtime.js +5 -1
  283. package/dist/repertoire/ado-client.js +15 -56
  284. package/dist/repertoire/ado-semantic.js +16 -10
  285. package/dist/repertoire/api-client.js +97 -0
  286. package/dist/repertoire/bitwarden-store.js +1042 -0
  287. package/dist/repertoire/bundle-templates.js +71 -0
  288. package/dist/repertoire/bw-installer.js +180 -0
  289. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  290. package/dist/repertoire/coding/context-pack.js +331 -0
  291. package/dist/repertoire/coding/feedback.js +218 -30
  292. package/dist/repertoire/coding/index.js +15 -3
  293. package/dist/repertoire/coding/manager.js +166 -10
  294. package/dist/repertoire/coding/spawner.js +58 -11
  295. package/dist/repertoire/coding/tools.js +242 -14
  296. package/dist/repertoire/coding/workbench-client.js +272 -0
  297. package/dist/repertoire/coding/workbench-manager.js +346 -0
  298. package/dist/repertoire/commerce-errors.js +109 -0
  299. package/dist/repertoire/commerce-self-test.js +156 -0
  300. package/dist/repertoire/credential-access.js +178 -0
  301. package/dist/repertoire/desk/classifier.js +362 -0
  302. package/dist/repertoire/duffel-client.js +185 -0
  303. package/dist/repertoire/github-client.js +14 -55
  304. package/dist/repertoire/graph-client.js +11 -52
  305. package/dist/repertoire/guardrails.js +159 -27
  306. package/dist/repertoire/mcp-client.js +44 -3
  307. package/dist/repertoire/mcp-manager.js +259 -20
  308. package/dist/repertoire/mcp-tools.js +83 -0
  309. package/dist/repertoire/plugin-mcp.js +175 -0
  310. package/dist/repertoire/plugins.js +253 -0
  311. package/dist/repertoire/shell-sessions.js +133 -0
  312. package/dist/repertoire/skills.js +48 -4
  313. package/dist/repertoire/stripe-client.js +131 -0
  314. package/dist/repertoire/tool-results.js +29 -0
  315. package/dist/repertoire/tools-a2a.js +699 -0
  316. package/dist/repertoire/tools-attachments.js +317 -0
  317. package/dist/repertoire/tools-awaiting.js +372 -0
  318. package/dist/repertoire/tools-base.js +63 -1095
  319. package/dist/repertoire/tools-bluebubbles.js +2 -0
  320. package/dist/repertoire/tools-bridge.js +144 -0
  321. package/dist/repertoire/tools-bundle.js +993 -0
  322. package/dist/repertoire/tools-commerce.js +253 -0
  323. package/dist/repertoire/tools-config.js +186 -0
  324. package/dist/repertoire/tools-continuity.js +252 -0
  325. package/dist/repertoire/tools-credential.js +383 -0
  326. package/dist/repertoire/tools-evolution.js +527 -0
  327. package/dist/repertoire/tools-files.js +344 -0
  328. package/dist/repertoire/tools-flight.js +290 -0
  329. package/dist/repertoire/tools-flow.js +119 -0
  330. package/dist/repertoire/tools-github.js +3 -8
  331. package/dist/repertoire/tools-mail.js +1975 -0
  332. package/dist/repertoire/tools-notes.js +459 -0
  333. package/dist/repertoire/tools-obligations.js +143 -0
  334. package/dist/repertoire/tools-orientation.js +31 -0
  335. package/dist/repertoire/tools-record.js +482 -0
  336. package/dist/repertoire/tools-runtime.js +150 -0
  337. package/dist/repertoire/tools-session.js +881 -0
  338. package/dist/repertoire/tools-shell.js +120 -0
  339. package/dist/repertoire/tools-stripe.js +224 -0
  340. package/dist/repertoire/tools-surface.js +355 -0
  341. package/dist/repertoire/tools-teams.js +12 -39
  342. package/dist/repertoire/tools-travel.js +125 -0
  343. package/dist/repertoire/tools-trip.js +982 -0
  344. package/dist/repertoire/tools-user-profile.js +146 -0
  345. package/dist/repertoire/tools-vault.js +40 -0
  346. package/dist/repertoire/tools-voice.js +145 -0
  347. package/dist/repertoire/tools.js +250 -80
  348. package/dist/repertoire/travel-api-client.js +360 -0
  349. package/dist/repertoire/user-profile.js +131 -0
  350. package/dist/repertoire/vault-setup.js +246 -0
  351. package/dist/repertoire/vault-unlock.js +594 -0
  352. package/dist/scripts/claude-code-hook.js +41 -0
  353. package/dist/scripts/claude-code-stop-hook.js +47 -0
  354. package/dist/senses/a2a-entry.js +115 -0
  355. package/dist/senses/attention-queue.js +186 -0
  356. package/dist/senses/await-turn-message.js +58 -0
  357. package/dist/senses/bluebubbles/active-turns.js +216 -0
  358. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  359. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  360. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  361. package/dist/senses/bluebubbles/entry.js +77 -0
  362. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  363. package/dist/senses/bluebubbles/index.js +2732 -0
  364. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  365. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  366. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  367. package/dist/senses/bluebubbles/processed-log.js +133 -0
  368. package/dist/senses/bluebubbles/replay.js +137 -0
  369. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  370. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  371. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  372. package/dist/senses/cli/bracketed-paste.js +82 -0
  373. package/dist/senses/cli/image-paste.js +287 -0
  374. package/dist/senses/cli/image-ref-navigation.js +75 -0
  375. package/dist/senses/cli/ink-app.js +156 -0
  376. package/dist/senses/cli/inline-diff.js +64 -0
  377. package/dist/senses/cli/input-keys.js +174 -0
  378. package/dist/senses/cli/kill-ring.js +86 -0
  379. package/dist/senses/cli/message-list.js +51 -0
  380. package/dist/senses/cli/ouro-tui.js +607 -0
  381. package/dist/senses/cli/spinner-imperative.js +135 -0
  382. package/dist/senses/cli/spinner.js +101 -0
  383. package/dist/senses/cli/status-line.js +60 -0
  384. package/dist/senses/cli/streaming-markdown.js +526 -0
  385. package/dist/senses/cli/tool-display.js +85 -0
  386. package/dist/senses/cli/tool-render.js +85 -0
  387. package/dist/senses/cli/tui-store.js +240 -0
  388. package/dist/senses/cli/virtual-list.js +35 -0
  389. package/dist/senses/cli-entry.js +60 -8
  390. package/dist/senses/cli-layout.js +100 -0
  391. package/dist/senses/cli.js +521 -214
  392. package/dist/senses/commands.js +66 -3
  393. package/dist/senses/habit-turn-message.js +160 -0
  394. package/dist/senses/mail-entry.js +66 -0
  395. package/dist/senses/mail.js +395 -0
  396. package/dist/senses/pipeline.js +873 -179
  397. package/dist/senses/private-runtime-worker.js +584 -0
  398. package/dist/senses/private-runtime.js +1145 -0
  399. package/dist/senses/proactive-content-guard.js +51 -0
  400. package/dist/senses/shared-turn.js +416 -0
  401. package/dist/senses/surface-tool.js +109 -0
  402. package/dist/senses/teams-entry.js +60 -8
  403. package/dist/senses/teams.js +397 -112
  404. package/dist/senses/trust-gate.js +104 -9
  405. package/dist/senses/voice/audio-playback.js +237 -0
  406. package/dist/senses/voice/audio-routing.js +119 -0
  407. package/dist/senses/voice/elevenlabs.js +202 -0
  408. package/dist/senses/voice/floor-control.js +431 -0
  409. package/dist/senses/voice/floor-controller.js +115 -0
  410. package/dist/senses/voice/golden-path.js +116 -0
  411. package/dist/senses/voice/index.js +29 -0
  412. package/dist/senses/voice/meeting.js +113 -0
  413. package/dist/senses/voice/outbound.js +190 -0
  414. package/dist/senses/voice/phone.js +33 -0
  415. package/dist/senses/voice/playback.js +139 -0
  416. package/dist/senses/voice/realtime-eval.js +496 -0
  417. package/dist/senses/voice/realtime-trace.js +531 -0
  418. package/dist/senses/voice/transcript.js +70 -0
  419. package/dist/senses/voice/turn.js +191 -0
  420. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  421. package/dist/senses/voice/twilio-phone.js +5077 -0
  422. package/dist/senses/voice/types.js +2 -0
  423. package/dist/senses/voice/whisper.js +161 -0
  424. package/dist/senses/voice-entry.js +81 -0
  425. package/dist/senses/voice-realtime-eval-command.js +99 -0
  426. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  427. package/dist/senses/voice-twilio-entry.js +87 -0
  428. package/dist/trips/core.js +138 -0
  429. package/dist/trips/store.js +265 -0
  430. package/dist/util/frontmatter.js +69 -0
  431. package/package.json +57 -12
  432. package/skills/agent-commerce.md +113 -0
  433. package/skills/browser-navigation.md +117 -0
  434. package/skills/commerce-setup-guide.md +116 -0
  435. package/skills/commerce-setup.md +84 -0
  436. package/skills/configure-dev-tools.md +99 -0
  437. package/skills/travel-planning.md +138 -0
  438. package/dist/heart/daemon/auth-flow.js +0 -351
  439. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  440. package/dist/heart/daemon/update-hooks.js +0 -138
  441. package/dist/heart/safe-workspace.js +0 -228
  442. package/dist/heart/session-recall.js +0 -116
  443. package/dist/mind/friends/channel.js +0 -84
  444. package/dist/mind/friends/group-context.js +0 -144
  445. package/dist/mind/friends/resolver.js +0 -84
  446. package/dist/mind/friends/store-file.js +0 -190
  447. package/dist/mind/friends/store.js +0 -4
  448. package/dist/mind/friends/tokens.js +0 -26
  449. package/dist/mind/friends/trust-explanation.js +0 -74
  450. package/dist/mind/friends/types.js +0 -29
  451. package/dist/repertoire/tasks/board.js +0 -134
  452. package/dist/repertoire/tasks/index.js +0 -224
  453. package/dist/repertoire/tasks/lifecycle.js +0 -80
  454. package/dist/repertoire/tasks/middleware.js +0 -65
  455. package/dist/repertoire/tasks/parser.js +0 -173
  456. package/dist/repertoire/tasks/scanner.js +0 -132
  457. package/dist/repertoire/tasks/transitions.js +0 -144
  458. package/dist/senses/bluebubbles-entry.js +0 -13
  459. package/dist/senses/bluebubbles.js +0 -1180
  460. package/dist/senses/debug-activity.js +0 -148
  461. package/dist/senses/inner-dialog-worker.js +0 -90
  462. package/dist/senses/inner-dialog.js +0 -480
  463. package/subagents/README.md +0 -7
  464. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  465. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  466. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  467. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  468. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  469. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  470. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  471. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  472. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  473. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  474. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  475. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  476. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  477. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  478. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  479. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  480. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -7,61 +7,20 @@ exports.graphRequest = graphRequest;
7
7
  exports.getProfile = getProfile;
8
8
  const api_error_1 = require("../heart/api-error");
9
9
  const runtime_1 = require("../nerves/runtime");
10
+ const api_client_1 = require("./api-client");
10
11
  const GRAPH_BASE = "https://graph.microsoft.com/v1.0";
11
12
  // Generic Graph API request. Returns response body as pretty-printed JSON string.
12
13
  async function graphRequest(token, method, path, body) {
13
- try {
14
- (0, runtime_1.emitNervesEvent)({
15
- event: "client.request_start",
16
- component: "clients",
17
- message: "starting Graph request",
18
- meta: { client: "graph", method, path },
19
- });
20
- const url = `${GRAPH_BASE}${path}`;
21
- const opts = {
22
- method,
23
- headers: {
24
- Authorization: `Bearer ${token}`,
25
- "Content-Type": "application/json",
26
- },
27
- };
28
- if (body)
29
- opts.body = body;
30
- const res = await fetch(url, opts);
31
- if (!res.ok) {
32
- (0, runtime_1.emitNervesEvent)({
33
- level: "error",
34
- event: "client.error",
35
- component: "clients",
36
- message: "Graph request failed",
37
- meta: { client: "graph", method, path, status: res.status },
38
- });
39
- return (0, api_error_1.handleApiError)(res, "Graph", "graph");
40
- }
41
- const data = await res.json();
42
- (0, runtime_1.emitNervesEvent)({
43
- event: "client.request_end",
44
- component: "clients",
45
- message: "Graph request completed",
46
- meta: { client: "graph", method, path, success: true },
47
- });
48
- return JSON.stringify(data, null, 2);
49
- }
50
- catch (err) {
51
- (0, runtime_1.emitNervesEvent)({
52
- level: "error",
53
- event: "client.error",
54
- component: "clients",
55
- message: "Graph request threw exception",
56
- meta: {
57
- client: "graph",
58
- method,
59
- path,
60
- reason: err instanceof Error ? err.message : String(err),
61
- },
62
- });
63
- return (0, api_error_1.handleApiError)(err, "Graph", "graph");
64
- }
14
+ return (0, api_client_1.apiRequest)({
15
+ baseUrl: GRAPH_BASE,
16
+ method,
17
+ path,
18
+ token,
19
+ clientName: "graph",
20
+ serviceLabel: "Graph",
21
+ connectionName: "graph",
22
+ body,
23
+ });
65
24
  }
66
25
  // Backward-compatible thin wrapper: fetches /me and formats as human-readable text.
67
26
  async function getProfile(token) {
@@ -36,9 +36,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.OURO_CLI_TRUST_MANIFEST = void 0;
37
37
  exports.guardInvocation = guardInvocation;
38
38
  const fs = __importStar(require("node:fs"));
39
- const os = __importStar(require("node:os"));
40
- const types_1 = require("../mind/friends/types");
39
+ const path = __importStar(require("node:path"));
40
+ const friends_1 = require("@ouro.bot/friends");
41
41
  const runtime_1 = require("../nerves/runtime");
42
+ const store_1 = require("../commerce/store");
42
43
  const deny = (reason) => ({ allowed: false, reason });
43
44
  const allow = { allowed: true };
44
45
  // --- reason templates ---
@@ -48,7 +49,6 @@ const REASONS = {
48
49
  readBeforeOverwrite: "i need to read that file first before i can overwrite it.",
49
50
  protectedPath: "that path is protected — i can read it but not modify it.",
50
51
  destructiveCommand: "that command is too dangerous to run — it could cause irreversible damage.",
51
- compoundCommand: "i can only run simple commands for you — no chaining with && or ;",
52
52
  // Trust reasons (vary by relationship)
53
53
  needsTrust: "i'd need a closer friend to vouch for you before i can do that.",
54
54
  needsTrustForWrite: "i'd need a closer friend to vouch for you before i can write files outside my home.",
@@ -56,17 +56,19 @@ const REASONS = {
56
56
  // --- read-only tools that never need guardrails ---
57
57
  const READ_ONLY_TOOLS = new Set(["read_file", "glob", "grep"]);
58
58
  // --- protected path detection ---
59
- const PROTECTED_PATH_SEGMENTS = [".git/"];
60
- function getProtectedAbsolutePrefixes() {
61
- return [`${os.homedir()}/.agentsecrets/`];
62
- }
59
+ const PROTECTED_PATH_SEGMENTS = [
60
+ ".git/",
61
+ ".ouro-cli/vault-unlock/",
62
+ ".ouro-cli/vault-unlock-dpapi/",
63
+ ];
64
+ const PROTECTED_FILENAMES = ["agent.json"];
63
65
  function isProtectedPath(filePath) {
64
66
  for (const segment of PROTECTED_PATH_SEGMENTS) {
65
67
  if (filePath.includes(`/${segment}`) || filePath.startsWith(segment))
66
68
  return true;
67
69
  }
68
- for (const prefix of getProtectedAbsolutePrefixes()) {
69
- if (filePath.startsWith(prefix))
70
+ for (const name of PROTECTED_FILENAMES) {
71
+ if (path.basename(filePath) === name)
70
72
  return true;
71
73
  }
72
74
  return false;
@@ -90,9 +92,6 @@ function splitShellCommands(command) {
90
92
  return [command];
91
93
  return command.split(COMPOUND_SEPARATORS).filter(Boolean);
92
94
  }
93
- function isCompoundCommand(command) {
94
- return SUBSHELL_PATTERN.test(command) || splitShellCommands(command).length > 1;
95
- }
96
95
  // --- shell commands that write to protected paths ---
97
96
  function shellWritesToProtectedPath(command) {
98
97
  const redirectMatch = command.match(/>\s*(\S+)/);
@@ -159,19 +158,19 @@ exports.OURO_CLI_TRUST_MANIFEST = {
159
158
  whoami: "acquaintance",
160
159
  changelog: "acquaintance",
161
160
  "session list": "acquaintance",
162
- "task board": "friend",
163
- "task create": "friend",
164
- "task update": "friend",
165
- "task show": "friend",
166
- "task actionable": "friend",
167
- "task deps": "friend",
168
- "task sessions": "friend",
169
161
  "friend list": "friend",
170
162
  "friend show": "friend",
171
163
  "friend create": "friend",
172
- "reminder create": "friend",
164
+ "friend update": "family",
165
+ "config model": "friend",
166
+ "config models": "friend",
173
167
  "mcp list": "acquaintance",
174
168
  "mcp call": "friend",
169
+ auth: "family",
170
+ "auth verify": "family",
171
+ "auth switch": "family",
172
+ rollback: "family",
173
+ versions: "acquaintance",
175
174
  };
176
175
  // --- trust level comparison ---
177
176
  const LEVEL_ORDER = {
@@ -206,6 +205,26 @@ function resolveOuroSubcommand(command) {
206
205
  return tokens[0];
207
206
  return null;
208
207
  }
208
+ // --- MCP server-specific trust rules ---
209
+ const MCP_SERVER_TRUST = {
210
+ browser: { minTrust: "friend", blockGroupChat: true },
211
+ };
212
+ function checkMcpServerTrust(command, context) {
213
+ const match = command.match(/^ouro\s+mcp\s+call\s+(\S+)/);
214
+ if (!match)
215
+ return allow;
216
+ const serverName = match[1];
217
+ const rules = MCP_SERVER_TRUST[serverName];
218
+ if (!rules)
219
+ return allow; // no special rules for this server
220
+ if (!trustLevelSatisfied(rules.minTrust, context.trustLevel ?? "friend")) {
221
+ return deny(REASONS.needsTrust);
222
+ }
223
+ if (rules.blockGroupChat && context.isGroupChat) {
224
+ return deny("browser tools are only available in 1:1 conversations, not group chats.");
225
+ }
226
+ return allow;
227
+ }
209
228
  function checkSingleShellCommandTrust(command, trustLevel) {
210
229
  const trimmed = command.trim();
211
230
  const tokens = trimmed.split(/\s+/);
@@ -231,11 +250,21 @@ function checkSingleShellCommandTrust(command, trustLevel) {
231
250
  return deny(REASONS.needsTrust);
232
251
  }
233
252
  function checkShellTrustGuardrails(command, trustLevel) {
234
- // Compound commands: for untrusted users, reject entirely.
235
- // This prevents "ouro whoami && rm -rf /" from smuggling dangerous commands.
236
- if (isCompoundCommand(command))
237
- return deny(REASONS.compoundCommand);
238
- return checkSingleShellCommandTrust(command, trustLevel);
253
+ // Subshell patterns ($(), backticks) can't be reliably split — check as single command
254
+ /* v8 ignore next -- subshell branch: tested via guardrails.test.ts @preserve */
255
+ if (SUBSHELL_PATTERN.test(command)) {
256
+ return checkSingleShellCommandTrust(command, trustLevel);
257
+ }
258
+ // Compound commands: check each subcommand individually
259
+ const subcommands = splitShellCommands(command);
260
+ if (subcommands.length === 0)
261
+ return checkSingleShellCommandTrust(command, trustLevel);
262
+ for (const sub of subcommands) {
263
+ const result = checkSingleShellCommandTrust(sub, trustLevel);
264
+ if (!result.allowed)
265
+ return result;
266
+ }
267
+ return allow;
239
268
  }
240
269
  function checkWriteTrustGuardrails(toolName, args, context) {
241
270
  if (toolName !== "write_file" && toolName !== "edit_file")
@@ -247,9 +276,112 @@ function checkWriteTrustGuardrails(toolName, args, context) {
247
276
  return allow;
248
277
  return deny(REASONS.needsTrustForWrite);
249
278
  }
279
+ // --- credential tool trust gating ---
280
+ // Credential write tools: family only
281
+ const CREDENTIAL_FAMILY_TOOLS = new Set([
282
+ "credential_generate_password", "credential_store", "credential_delete", "vault_setup",
283
+ // User profile tools: family only
284
+ "user_profile_store", "user_profile_get", "user_profile_delete",
285
+ // Payment tools: family only
286
+ "stripe_create_card", "stripe_deactivate_card", "stripe_list_cards",
287
+ // Booking tools that involve payment: family only
288
+ "flight_book", "flight_hold", "flight_cancel",
289
+ ]);
290
+ // Credential read tools: friend+
291
+ const CREDENTIAL_TRUSTED_TOOLS = new Set(["credential_get", "credential_list"]);
292
+ // Travel tools: friend+ (weather_lookup accesses vault credentials indirectly;
293
+ // advisory and geocode are public APIs but gated for consistency)
294
+ // Flight search is also friend+ (read-only, no payment)
295
+ const TRAVEL_TRUSTED_TOOLS = new Set(["weather_lookup", "travel_advisory", "geocode_search", "flight_search"]);
296
+ const A2A_TRUSTED_TOOLS = new Set(["a2a_list_peers", "a2a_send_message", "a2a_get_task"]);
297
+ const COMMERCE_FAMILY_TOOLS = new Set(["commerce_checkout_preview", "commerce_checkout_commit", "commerce_receipt_get", "commerce_access_log"]);
298
+ const COMMERCE_AUTHORITY_TOOLS = new Set(["stripe_create_card", "flight_hold", "flight_book"]);
299
+ const MAIL_FAMILY_TOOLS = new Set(["mail_screener", "mail_decide", "mail_access_log", "mail_send", "mail_index_refresh"]);
300
+ const MAIL_DELEGATED_READ_TOOLS = new Set(["mail_recent", "mail_search"]);
301
+ function mailTrustGuardrail(toolName, args, context) {
302
+ if (MAIL_FAMILY_TOOLS.has(toolName)) {
303
+ if (context.trustLevel === undefined || context.trustLevel === "family")
304
+ return allow;
305
+ if (toolName === "mail_send")
306
+ return deny("outbound mail sends require family trust.");
307
+ return deny(toolName === "mail_decide"
308
+ ? "mail screener decisions require family trust."
309
+ : "delegated human mail requires family trust.");
310
+ }
311
+ if (MAIL_DELEGATED_READ_TOOLS.has(toolName)) {
312
+ const scope = (args.scope ?? "").trim().toLowerCase();
313
+ if (scope === "delegated" || scope === "all") {
314
+ if (context.trustLevel === undefined || context.trustLevel === "family")
315
+ return allow;
316
+ return deny("delegated human mail requires family trust.");
317
+ }
318
+ }
319
+ return allow;
320
+ }
321
+ function checkCredentialTrustGuardrails(toolName, context) {
322
+ if (CREDENTIAL_FAMILY_TOOLS.has(toolName) || COMMERCE_FAMILY_TOOLS.has(toolName)) {
323
+ if (context.trustLevel === "family")
324
+ return allow;
325
+ return deny(REASONS.needsTrust);
326
+ }
327
+ if (CREDENTIAL_TRUSTED_TOOLS.has(toolName) || TRAVEL_TRUSTED_TOOLS.has(toolName) || A2A_TRUSTED_TOOLS.has(toolName)) {
328
+ if ((0, friends_1.isTrustedLevel)(context.trustLevel))
329
+ return allow;
330
+ return deny(REASONS.needsTrust);
331
+ }
332
+ return allow;
333
+ }
334
+ function checkCommerceAuthorityGuardrails(toolName, args, context) {
335
+ if (!COMMERCE_AUTHORITY_TOOLS.has(toolName))
336
+ return allow;
337
+ if (!context.agentRoot)
338
+ return deny("commerce authority unavailable: agent root could not be resolved.");
339
+ const result = (0, store_1.validateCommerceAuthority)({
340
+ agentRoot: context.agentRoot,
341
+ token: args.commerce_authority,
342
+ toolName,
343
+ args,
344
+ friendId: context.friendId,
345
+ });
346
+ if (result.ok)
347
+ return allow;
348
+ return deny(`commerce authority required: ${result.reason}`);
349
+ }
350
+ function checkFirstClassMcpTrust(context) {
351
+ if (!context.mcpServerName)
352
+ return allow;
353
+ const rules = MCP_SERVER_TRUST[context.mcpServerName] ?? { minTrust: "friend", blockGroupChat: false };
354
+ if (!trustLevelSatisfied(rules.minTrust, context.trustLevel ?? "friend")) {
355
+ return deny(REASONS.needsTrust);
356
+ }
357
+ if (rules.blockGroupChat && context.isGroupChat) {
358
+ return deny("browser tools are only available in 1:1 conversations, not group chats.");
359
+ }
360
+ return allow;
361
+ }
250
362
  function checkTrustLevelGuardrails(toolName, args, context) {
251
- // Trusted levels (family/friend) — no trust guardrails. Undefined defaults to friend.
252
- if ((0, types_1.isTrustedLevel)(context.trustLevel))
363
+ const mailResult = mailTrustGuardrail(toolName, args, context);
364
+ if (!mailResult.allowed)
365
+ return mailResult;
366
+ // Credential tools have their own trust rules that apply at all levels
367
+ const credentialResult = checkCredentialTrustGuardrails(toolName, context);
368
+ if (!credentialResult.allowed)
369
+ return credentialResult;
370
+ const commerceAuthorityResult = checkCommerceAuthorityGuardrails(toolName, args, context);
371
+ if (!commerceAuthorityResult.allowed)
372
+ return commerceAuthorityResult;
373
+ // First-class MCP tool trust (e.g. browser_navigate) — applies at all trust levels
374
+ const firstClassMcpResult = checkFirstClassMcpTrust(context);
375
+ if (!firstClassMcpResult.allowed)
376
+ return firstClassMcpResult;
377
+ // MCP server-specific trust via shell (e.g. ouro mcp call browser) — applies at all trust levels
378
+ if (toolName === "shell") {
379
+ const mcpResult = checkMcpServerTrust(args.command || "", context);
380
+ if (!mcpResult.allowed)
381
+ return mcpResult;
382
+ }
383
+ // Trusted levels (family/friend) — no further trust guardrails. Undefined defaults to friend.
384
+ if ((0, friends_1.isTrustedLevel)(context.trustLevel))
253
385
  return allow;
254
386
  if (toolName === "shell") {
255
387
  return checkShellTrustGuardrails(args.command || "", context.trustLevel);
@@ -1,11 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.McpClient = void 0;
4
+ exports.isMcpTransportError = isMcpTransportError;
4
5
  const child_process_1 = require("child_process");
5
6
  const readline_1 = require("readline");
6
7
  const runtime_1 = require("../nerves/runtime");
8
+ const runtime_cwd_1 = require("../heart/runtime-cwd");
7
9
  const MCP_PROTOCOL_VERSION = "2024-11-05";
10
+ const DEFAULT_REQUEST_TIMEOUT = 10_000;
8
11
  const DEFAULT_TOOL_CALL_TIMEOUT = 30_000;
12
+ function isMcpTransportError(error) {
13
+ const message = error instanceof Error ? error.message : String(error);
14
+ const normalized = message.toLowerCase();
15
+ return normalized.includes("disconnected")
16
+ || normalized.includes("transport")
17
+ || normalized.includes("closed")
18
+ || normalized.includes("econnreset")
19
+ || normalized.includes("econnrefused")
20
+ || normalized.includes("enoent")
21
+ || normalized.includes("epipe")
22
+ || normalized.includes("broken pipe")
23
+ || normalized.includes("not writable");
24
+ }
9
25
  class McpClient {
10
26
  config;
11
27
  process = null;
@@ -18,6 +34,9 @@ class McpClient {
18
34
  this.config = config;
19
35
  }
20
36
  async connect() {
37
+ if (this.connected)
38
+ return;
39
+ this.shutdownProcessOnly();
21
40
  (0, runtime_1.emitNervesEvent)({
22
41
  event: "mcp.connect_start",
23
42
  component: "repertoire",
@@ -25,9 +44,11 @@ class McpClient {
25
44
  meta: { command: this.config.command },
26
45
  });
27
46
  const env = { ...process.env, ...this.config.env };
47
+ const spawnCwd = this.config.cwd ?? (0, runtime_cwd_1.recoverRuntimeCwd)();
28
48
  this.process = (0, child_process_1.spawn)(this.config.command, this.config.args ?? [], {
29
49
  env,
30
50
  stdio: ["pipe", "pipe", "pipe"],
51
+ cwd: spawnCwd,
31
52
  });
32
53
  this.setupLineReader();
33
54
  this.setupProcessHandlers();
@@ -43,6 +64,7 @@ class McpClient {
43
64
  }
44
65
  catch (error) {
45
66
  this.connected = false;
67
+ this.shutdownProcessOnly();
46
68
  (0, runtime_1.emitNervesEvent)({
47
69
  level: "error",
48
70
  event: "mcp.connect_error",
@@ -75,6 +97,10 @@ class McpClient {
75
97
  this.cachedTools = allTools;
76
98
  return allTools;
77
99
  }
100
+ async refreshTools() {
101
+ this.cachedTools = null;
102
+ return this.listTools();
103
+ }
78
104
  async callTool(name, args, timeout = DEFAULT_TOOL_CALL_TIMEOUT) {
79
105
  (0, runtime_1.emitNervesEvent)({
80
106
  event: "mcp.tool_call_start",
@@ -138,7 +164,7 @@ class McpClient {
138
164
  });
139
165
  return result;
140
166
  }
141
- sendRequest(method, params, timeout) {
167
+ sendRequest(method, params, timeout = DEFAULT_REQUEST_TIMEOUT) {
142
168
  return new Promise((resolve, reject) => {
143
169
  if (!this.process || !this.connected && method !== "initialize") {
144
170
  reject(new Error("MCP client is disconnected"));
@@ -159,14 +185,21 @@ class McpClient {
159
185
  method,
160
186
  params,
161
187
  };
162
- this.writeMessage(request);
188
+ if (!this.writeMessage(request)) {
189
+ this.pending.delete(id);
190
+ if (pending.timer) {
191
+ clearTimeout(pending.timer);
192
+ }
193
+ reject(new Error(`MCP transport is not writable for request: ${method}`));
194
+ }
163
195
  });
164
196
  }
165
197
  writeMessage(message) {
166
- /* v8 ignore next -- defensive: stdin always writable during active connection @preserve */
167
198
  if (this.process?.stdin?.writable) {
168
199
  this.process.stdin.write(JSON.stringify(message) + "\n");
200
+ return true;
169
201
  }
202
+ return false;
170
203
  }
171
204
  setupLineReader() {
172
205
  /* v8 ignore next -- defensive: stdout always exists after spawn @preserve */
@@ -250,5 +283,13 @@ class McpClient {
250
283
  this.pending.delete(id);
251
284
  }
252
285
  }
286
+ shutdownProcessOnly() {
287
+ this.rejectAllPending(new Error("MCP transport closed during reconnect"));
288
+ /* v8 ignore next -- defensive: process may already be absent @preserve */
289
+ if (this.process && !this.process.killed) {
290
+ this.process.kill();
291
+ }
292
+ this.process = null;
293
+ }
253
294
  }
254
295
  exports.McpClient = McpClient;