wicked-crew 0.7.40 → 0.7.46

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 (361) hide show
  1. package/dist/api/audit.d.ts +3 -0
  2. package/dist/api/audit.d.ts.map +1 -1
  3. package/dist/api/audit.js +2 -0
  4. package/dist/api/audit.js.map +1 -1
  5. package/dist/api/capture.d.ts +149 -0
  6. package/dist/api/capture.d.ts.map +1 -0
  7. package/dist/api/capture.js +330 -0
  8. package/dist/api/capture.js.map +1 -0
  9. package/dist/api/chat-citations.d.ts +174 -0
  10. package/dist/api/chat-citations.d.ts.map +1 -0
  11. package/dist/api/chat-citations.js +528 -0
  12. package/dist/api/chat-citations.js.map +1 -0
  13. package/dist/api/chat-transcripts.d.ts +20 -1
  14. package/dist/api/chat-transcripts.d.ts.map +1 -1
  15. package/dist/api/chat-transcripts.js +29 -0
  16. package/dist/api/chat-transcripts.js.map +1 -1
  17. package/dist/api/delivery-cache.d.ts +2 -2
  18. package/dist/api/delivery-freeze.d.ts +66 -0
  19. package/dist/api/delivery-freeze.d.ts.map +1 -0
  20. package/dist/api/delivery-freeze.js +104 -0
  21. package/dist/api/delivery-freeze.js.map +1 -0
  22. package/dist/api/delivery-index.d.ts +53 -9
  23. package/dist/api/delivery-index.d.ts.map +1 -1
  24. package/dist/api/delivery-index.js +115 -22
  25. package/dist/api/delivery-index.js.map +1 -1
  26. package/dist/api/demo.d.ts +90 -0
  27. package/dist/api/demo.d.ts.map +1 -0
  28. package/dist/api/demo.js +492 -0
  29. package/dist/api/demo.js.map +1 -0
  30. package/dist/api/diagnostics.d.ts +64 -1
  31. package/dist/api/diagnostics.d.ts.map +1 -1
  32. package/dist/api/diagnostics.js +129 -1
  33. package/dist/api/diagnostics.js.map +1 -1
  34. package/dist/api/eval-sample.d.ts +6 -6
  35. package/dist/api/governance-steering.d.ts +2 -2
  36. package/dist/api/mcp.d.ts +282 -0
  37. package/dist/api/mcp.d.ts.map +1 -0
  38. package/dist/api/mcp.js +521 -0
  39. package/dist/api/mcp.js.map +1 -0
  40. package/dist/api/plan-schema.d.ts +56 -0
  41. package/dist/api/plan-schema.d.ts.map +1 -0
  42. package/dist/api/plan-schema.js +26 -0
  43. package/dist/api/plan-schema.js.map +1 -0
  44. package/dist/api/roster-standing.d.ts +15 -2
  45. package/dist/api/roster-standing.d.ts.map +1 -1
  46. package/dist/api/roster-standing.js +59 -3
  47. package/dist/api/roster-standing.js.map +1 -1
  48. package/dist/api/routes.d.ts +630 -51
  49. package/dist/api/routes.d.ts.map +1 -1
  50. package/dist/api/routes.js +738 -127
  51. package/dist/api/routes.js.map +1 -1
  52. package/dist/api/run-files.d.ts.map +1 -1
  53. package/dist/api/run-files.js +31 -2
  54. package/dist/api/run-files.js.map +1 -1
  55. package/dist/api/run-liveness.d.ts +41 -0
  56. package/dist/api/run-liveness.d.ts.map +1 -0
  57. package/dist/api/run-liveness.js +166 -0
  58. package/dist/api/run-liveness.js.map +1 -0
  59. package/dist/api/seat-health.d.ts +35 -0
  60. package/dist/api/seat-health.d.ts.map +1 -1
  61. package/dist/api/seat-health.js +92 -4
  62. package/dist/api/seat-health.js.map +1 -1
  63. package/dist/api/seat-probe.d.ts +141 -0
  64. package/dist/api/seat-probe.d.ts.map +1 -0
  65. package/dist/api/seat-probe.js +257 -0
  66. package/dist/api/seat-probe.js.map +1 -0
  67. package/dist/api/seat-record.d.ts +40 -0
  68. package/dist/api/seat-record.d.ts.map +1 -0
  69. package/dist/api/seat-record.js +218 -0
  70. package/dist/api/seat-record.js.map +1 -0
  71. package/dist/api/seat-signin.d.ts.map +1 -1
  72. package/dist/api/seat-signin.js +3 -1
  73. package/dist/api/seat-signin.js.map +1 -1
  74. package/dist/api/seat-standing.d.ts +25 -5
  75. package/dist/api/seat-standing.d.ts.map +1 -1
  76. package/dist/api/seat-standing.js +76 -9
  77. package/dist/api/seat-standing.js.map +1 -1
  78. package/dist/api/server.d.ts +34 -48
  79. package/dist/api/server.d.ts.map +1 -1
  80. package/dist/api/server.js +283 -107
  81. package/dist/api/server.js.map +1 -1
  82. package/dist/api/skills.d.ts +3 -1
  83. package/dist/api/skills.d.ts.map +1 -1
  84. package/dist/api/skills.js +7 -2
  85. package/dist/api/skills.js.map +1 -1
  86. package/dist/api/stall-watchdog.d.ts +34 -3
  87. package/dist/api/stall-watchdog.d.ts.map +1 -1
  88. package/dist/api/stall-watchdog.js +107 -8
  89. package/dist/api/stall-watchdog.js.map +1 -1
  90. package/dist/api/steering-landing.d.ts +6 -6
  91. package/dist/api/steering-landing.d.ts.map +1 -1
  92. package/dist/api/steering-landing.js +7 -9
  93. package/dist/api/steering-landing.js.map +1 -1
  94. package/dist/api/testing.d.ts +6 -4
  95. package/dist/api/testing.d.ts.map +1 -1
  96. package/dist/api/testing.js +82 -47
  97. package/dist/api/testing.js.map +1 -1
  98. package/dist/campaign/boot-resume.d.ts +34 -0
  99. package/dist/campaign/boot-resume.d.ts.map +1 -0
  100. package/dist/campaign/boot-resume.js +45 -0
  101. package/dist/campaign/boot-resume.js.map +1 -0
  102. package/dist/campaigns/rollup.d.ts +4 -1
  103. package/dist/campaigns/rollup.d.ts.map +1 -1
  104. package/dist/campaigns/rollup.js +6 -1
  105. package/dist/campaigns/rollup.js.map +1 -1
  106. package/dist/campaigns/routes.d.ts +2 -2
  107. package/dist/cli/bearer.d.ts +27 -1
  108. package/dist/cli/bearer.d.ts.map +1 -1
  109. package/dist/cli/bearer.js +62 -2
  110. package/dist/cli/bearer.js.map +1 -1
  111. package/dist/cli/governance.d.ts +11 -0
  112. package/dist/cli/governance.d.ts.map +1 -1
  113. package/dist/cli/governance.js +8 -2
  114. package/dist/cli/governance.js.map +1 -1
  115. package/dist/cli/index.d.ts.map +1 -1
  116. package/dist/cli/index.js +140 -75
  117. package/dist/cli/index.js.map +1 -1
  118. package/dist/cli/mcp.d.ts +11 -0
  119. package/dist/cli/mcp.d.ts.map +1 -1
  120. package/dist/cli/mcp.js +40 -9
  121. package/dist/cli/mcp.js.map +1 -1
  122. package/dist/cli/service.d.ts +78 -0
  123. package/dist/cli/service.d.ts.map +1 -0
  124. package/dist/cli/service.js +334 -0
  125. package/dist/cli/service.js.map +1 -0
  126. package/dist/core/adapter.d.ts +238 -12
  127. package/dist/core/adapter.d.ts.map +1 -1
  128. package/dist/core/adapter.js +619 -157
  129. package/dist/core/adapter.js.map +1 -1
  130. package/dist/core/bridge-reaper.d.ts +4 -1
  131. package/dist/core/bridge-reaper.d.ts.map +1 -1
  132. package/dist/core/bridge-reaper.js +15 -1
  133. package/dist/core/bridge-reaper.js.map +1 -1
  134. package/dist/core/bus-notice.d.ts +27 -0
  135. package/dist/core/bus-notice.d.ts.map +1 -0
  136. package/dist/core/bus-notice.js +24 -0
  137. package/dist/core/bus-notice.js.map +1 -0
  138. package/dist/core/bus.d.ts +99 -0
  139. package/dist/core/bus.d.ts.map +1 -0
  140. package/dist/core/bus.js +176 -0
  141. package/dist/core/bus.js.map +1 -0
  142. package/dist/core/deliver-exclusions.d.ts +71 -0
  143. package/dist/core/deliver-exclusions.d.ts.map +1 -0
  144. package/dist/core/deliver-exclusions.js +110 -0
  145. package/dist/core/deliver-exclusions.js.map +1 -0
  146. package/dist/core/deliver-text.d.ts +61 -14
  147. package/dist/core/deliver-text.d.ts.map +1 -1
  148. package/dist/core/deliver-text.js +178 -30
  149. package/dist/core/deliver-text.js.map +1 -1
  150. package/dist/core/deliver-triage.d.ts +11 -2
  151. package/dist/core/deliver-triage.d.ts.map +1 -1
  152. package/dist/core/deliver-triage.js +19 -1
  153. package/dist/core/deliver-triage.js.map +1 -1
  154. package/dist/core/deliver.d.ts +161 -3
  155. package/dist/core/deliver.d.ts.map +1 -1
  156. package/dist/core/deliver.js +463 -25
  157. package/dist/core/deliver.js.map +1 -1
  158. package/dist/core/deliverable-floor.d.ts.map +1 -1
  159. package/dist/core/deliverable-floor.js +5 -7
  160. package/dist/core/deliverable-floor.js.map +1 -1
  161. package/dist/core/engine-bus.d.ts +40 -0
  162. package/dist/core/engine-bus.d.ts.map +1 -0
  163. package/dist/core/engine-bus.js +27 -0
  164. package/dist/core/engine-bus.js.map +1 -0
  165. package/dist/core/estate-mcp-client.d.ts +87 -5
  166. package/dist/core/estate-mcp-client.d.ts.map +1 -1
  167. package/dist/core/estate-mcp-client.js +90 -11
  168. package/dist/core/estate-mcp-client.js.map +1 -1
  169. package/dist/core/linked-issues.d.ts +46 -0
  170. package/dist/core/linked-issues.d.ts.map +1 -0
  171. package/dist/core/linked-issues.js +123 -0
  172. package/dist/core/linked-issues.js.map +1 -0
  173. package/dist/core/run-identity.d.ts +100 -0
  174. package/dist/core/run-identity.d.ts.map +1 -0
  175. package/dist/core/run-identity.js +178 -0
  176. package/dist/core/run-identity.js.map +1 -0
  177. package/dist/core/shutdown.d.ts +16 -0
  178. package/dist/core/shutdown.d.ts.map +1 -0
  179. package/dist/core/shutdown.js +39 -0
  180. package/dist/core/shutdown.js.map +1 -0
  181. package/dist/core/types.d.ts +15 -1
  182. package/dist/core/types.d.ts.map +1 -1
  183. package/dist/core/types.js +4 -0
  184. package/dist/core/types.js.map +1 -1
  185. package/dist/interactive/bridge-pool.d.ts +67 -3
  186. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  187. package/dist/interactive/bridge-pool.js +129 -13
  188. package/dist/interactive/bridge-pool.js.map +1 -1
  189. package/dist/interactive/bridge-root.d.ts +9 -0
  190. package/dist/interactive/bridge-root.d.ts.map +1 -1
  191. package/dist/interactive/bridge-root.js +11 -4
  192. package/dist/interactive/bridge-root.js.map +1 -1
  193. package/dist/interactive/chat-events.d.ts +14 -9
  194. package/dist/interactive/chat-events.d.ts.map +1 -1
  195. package/dist/interactive/chat-events.js +55 -57
  196. package/dist/interactive/chat-events.js.map +1 -1
  197. package/dist/interactive/council-outcome.d.ts +1 -0
  198. package/dist/interactive/council-outcome.d.ts.map +1 -1
  199. package/dist/interactive/council-outcome.js +33 -0
  200. package/dist/interactive/council-outcome.js.map +1 -1
  201. package/dist/interactive/draft-events.d.ts +36 -17
  202. package/dist/interactive/draft-events.d.ts.map +1 -1
  203. package/dist/interactive/draft-events.js +121 -92
  204. package/dist/interactive/draft-events.js.map +1 -1
  205. package/dist/interactive/draft-skill.d.ts +59 -0
  206. package/dist/interactive/draft-skill.d.ts.map +1 -1
  207. package/dist/interactive/draft-skill.js +233 -0
  208. package/dist/interactive/draft-skill.js.map +1 -1
  209. package/dist/interactive/edit-events.d.ts +1 -14
  210. package/dist/interactive/edit-events.d.ts.map +1 -1
  211. package/dist/interactive/edit-events.js +37 -70
  212. package/dist/interactive/edit-events.js.map +1 -1
  213. package/dist/interactive/proxy-routes.d.ts +2 -2
  214. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  215. package/dist/interactive/proxy-routes.js +4 -13
  216. package/dist/interactive/proxy-routes.js.map +1 -1
  217. package/dist/interactive/ws-relay.d.ts +9 -10
  218. package/dist/interactive/ws-relay.d.ts.map +1 -1
  219. package/dist/interactive/ws-relay.js +23 -50
  220. package/dist/interactive/ws-relay.js.map +1 -1
  221. package/dist/mcp/broker.d.ts +88 -0
  222. package/dist/mcp/broker.d.ts.map +1 -0
  223. package/dist/mcp/broker.js +307 -0
  224. package/dist/mcp/broker.js.map +1 -0
  225. package/dist/mcp/call-records.d.ts +61 -0
  226. package/dist/mcp/call-records.d.ts.map +1 -0
  227. package/dist/mcp/call-records.js +135 -0
  228. package/dist/mcp/call-records.js.map +1 -0
  229. package/dist/mcp/classify.d.ts +45 -0
  230. package/dist/mcp/classify.d.ts.map +1 -0
  231. package/dist/mcp/classify.js +83 -0
  232. package/dist/mcp/classify.js.map +1 -0
  233. package/dist/mcp/discovery.d.ts +24 -0
  234. package/dist/mcp/discovery.d.ts.map +1 -0
  235. package/dist/mcp/discovery.js +78 -0
  236. package/dist/mcp/discovery.js.map +1 -0
  237. package/dist/mcp/invoke.d.ts +36 -0
  238. package/dist/mcp/invoke.d.ts.map +1 -0
  239. package/dist/mcp/invoke.js +80 -0
  240. package/dist/mcp/invoke.js.map +1 -0
  241. package/dist/mcp/policies.d.ts +110 -0
  242. package/dist/mcp/policies.d.ts.map +1 -0
  243. package/dist/mcp/policies.js +400 -0
  244. package/dist/mcp/policies.js.map +1 -0
  245. package/dist/mcp/probe.d.ts +66 -0
  246. package/dist/mcp/probe.d.ts.map +1 -0
  247. package/dist/mcp/probe.js +116 -0
  248. package/dist/mcp/probe.js.map +1 -0
  249. package/dist/mcp/redact.d.ts +34 -0
  250. package/dist/mcp/redact.d.ts.map +1 -0
  251. package/dist/mcp/redact.js +84 -0
  252. package/dist/mcp/redact.js.map +1 -0
  253. package/dist/mcp/registry-store.d.ts +69 -0
  254. package/dist/mcp/registry-store.d.ts.map +1 -0
  255. package/dist/mcp/registry-store.js +82 -0
  256. package/dist/mcp/registry-store.js.map +1 -0
  257. package/dist/mcp/registry.d.ts +147 -0
  258. package/dist/mcp/registry.d.ts.map +1 -0
  259. package/dist/mcp/registry.js +509 -0
  260. package/dist/mcp/registry.js.map +1 -0
  261. package/dist/mcp/rest.d.ts +111 -0
  262. package/dist/mcp/rest.d.ts.map +1 -0
  263. package/dist/mcp/rest.js +606 -0
  264. package/dist/mcp/rest.js.map +1 -0
  265. package/dist/mcp/secrets.d.ts +66 -0
  266. package/dist/mcp/secrets.d.ts.map +1 -0
  267. package/dist/mcp/secrets.js +180 -0
  268. package/dist/mcp/secrets.js.map +1 -0
  269. package/dist/mcp/tool-list.d.ts +25 -0
  270. package/dist/mcp/tool-list.d.ts.map +1 -0
  271. package/dist/mcp/tool-list.js +62 -0
  272. package/dist/mcp/tool-list.js.map +1 -0
  273. package/dist/mcp/upstream-error.d.ts +12 -0
  274. package/dist/mcp/upstream-error.d.ts.map +1 -0
  275. package/dist/mcp/upstream-error.js +14 -0
  276. package/dist/mcp/upstream-error.js.map +1 -0
  277. package/dist/mcp/usage.d.ts +31 -0
  278. package/dist/mcp/usage.d.ts.map +1 -0
  279. package/dist/mcp/usage.js +159 -0
  280. package/dist/mcp/usage.js.map +1 -0
  281. package/dist/presets/routes.d.ts +53 -0
  282. package/dist/presets/routes.d.ts.map +1 -0
  283. package/dist/presets/routes.js +115 -0
  284. package/dist/presets/routes.js.map +1 -0
  285. package/dist/projects/activity.d.ts +6 -18
  286. package/dist/projects/activity.d.ts.map +1 -1
  287. package/dist/projects/activity.js +17 -60
  288. package/dist/projects/activity.js.map +1 -1
  289. package/dist/projects/events.d.ts +6 -5
  290. package/dist/projects/events.d.ts.map +1 -1
  291. package/dist/projects/events.js +33 -58
  292. package/dist/projects/events.js.map +1 -1
  293. package/dist/projects/routes.d.ts.map +1 -1
  294. package/dist/projects/routes.js +19 -0
  295. package/dist/projects/routes.js.map +1 -1
  296. package/dist/projects/state-home-preflight.d.ts.map +1 -1
  297. package/dist/projects/state-home-preflight.js +7 -0
  298. package/dist/projects/state-home-preflight.js.map +1 -1
  299. package/dist/projects/state-home-registry.d.ts.map +1 -1
  300. package/dist/projects/state-home-registry.js +9 -1
  301. package/dist/projects/state-home-registry.js.map +1 -1
  302. package/dist/qe/acceptance.d.ts +28 -28
  303. package/dist/qe/acceptance.d.ts.map +1 -1
  304. package/dist/qe/acceptance.js +60 -61
  305. package/dist/qe/acceptance.js.map +1 -1
  306. package/dist/qe/test-sets.d.ts +3 -5
  307. package/dist/qe/test-sets.d.ts.map +1 -1
  308. package/dist/qe/test-sets.js +5 -7
  309. package/dist/qe/test-sets.js.map +1 -1
  310. package/dist/skills/installed.d.ts +51 -0
  311. package/dist/skills/installed.d.ts.map +1 -0
  312. package/dist/skills/installed.js +46 -0
  313. package/dist/skills/installed.js.map +1 -0
  314. package/dist/standing-orders/evaluator.d.ts +113 -0
  315. package/dist/standing-orders/evaluator.d.ts.map +1 -0
  316. package/dist/standing-orders/evaluator.js +225 -0
  317. package/dist/standing-orders/evaluator.js.map +1 -0
  318. package/dist/standing-orders/history.d.ts +58 -0
  319. package/dist/standing-orders/history.d.ts.map +1 -0
  320. package/dist/standing-orders/history.js +117 -0
  321. package/dist/standing-orders/history.js.map +1 -0
  322. package/dist/standing-orders/parse.d.ts +19 -0
  323. package/dist/standing-orders/parse.d.ts.map +1 -0
  324. package/dist/standing-orders/parse.js +75 -0
  325. package/dist/standing-orders/parse.js.map +1 -0
  326. package/dist/standing-orders/routes.d.ts +180 -0
  327. package/dist/standing-orders/routes.d.ts.map +1 -0
  328. package/dist/standing-orders/routes.js +95 -0
  329. package/dist/standing-orders/routes.js.map +1 -0
  330. package/dist/standing-orders/store.d.ts +154 -0
  331. package/dist/standing-orders/store.d.ts.map +1 -0
  332. package/dist/standing-orders/store.js +189 -0
  333. package/dist/standing-orders/store.js.map +1 -0
  334. package/dist/studio/assets/index-CvV5qITf.css +32 -0
  335. package/dist/studio/assets/index-jCOy6Ns7.js +568 -0
  336. package/dist/studio/index.html +3 -3
  337. package/dist/studio/testid-inventory.json +3274 -894
  338. package/dist/team/key.d.ts +5 -0
  339. package/dist/team/key.d.ts.map +1 -0
  340. package/dist/team/key.js +21 -0
  341. package/dist/team/key.js.map +1 -0
  342. package/dist/team/routes.d.ts +196 -0
  343. package/dist/team/routes.d.ts.map +1 -0
  344. package/dist/team/routes.js +274 -0
  345. package/dist/team/routes.js.map +1 -0
  346. package/dist/team/ws-relay.d.ts +39 -0
  347. package/dist/team/ws-relay.d.ts.map +1 -0
  348. package/dist/team/ws-relay.js +63 -0
  349. package/dist/team/ws-relay.js.map +1 -0
  350. package/endpoint-manifest.json +502 -6
  351. package/package.json +6 -6
  352. package/dist/interactive/demo-events.d.ts +0 -367
  353. package/dist/interactive/demo-events.d.ts.map +0 -1
  354. package/dist/interactive/demo-events.js +0 -1293
  355. package/dist/interactive/demo-events.js.map +0 -1
  356. package/dist/qe/gate-events.d.ts +0 -113
  357. package/dist/qe/gate-events.d.ts.map +0 -1
  358. package/dist/qe/gate-events.js +0 -172
  359. package/dist/qe/gate-events.js.map +0 -1
  360. package/dist/studio/assets/index-Bg7Z3BR-.css +0 -32
  361. package/dist/studio/assets/index-BvOFMjf9.js +0 -554
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Result scrubbing for brokered MCP calls (DES-MCP-TOOLS-001 §4.3 D-2, §6 step 8).
3
+ *
4
+ * Every result an upstream returns passes through here before a worker, a log or a record sees
5
+ * it, in this order:
6
+ *
7
+ * 1. **Exact secrets**: every value the broker injected on THIS call is replaced wherever it
8
+ * appears (`scrubSecrets`, the same pass the registry's probe uses).
9
+ * 2. **Field names**: a value under a credential-named key (Authorization, Cookie, *token*,
10
+ * *secret*, *passw*, *credential*, *session*, api/private/access/secret key, ...) becomes
11
+ * `[REDACTED:field:<name>]`, recursively.
12
+ * 3. **Value shapes**: credential-shaped substrings anywhere (Bearer/Basic auth, JWTs, AWS access
13
+ * key ids, GitHub/OpenAI/Slack tokens, `password=...` pairs, PEM private keys) become
14
+ * `[REDACTED:<pattern-id>]`.
15
+ *
16
+ * Layers 2 and 3 are ported from wicked-garden's QE evidence redactor
17
+ * (`scripts/qe/runner/src/redact.mjs`). One difference: garden also denies a bare `key` field.
18
+ * An MCP result routinely carries `key` as an identifier (a Jira issue key, a cache key), so here
19
+ * only the qualified credential keys are denied (`api_key`, `private-key`, `accessKey`, ...).
20
+ */
21
+ export declare function isDeniedFieldName(name: string): boolean;
22
+ interface ValuePattern {
23
+ id: string;
24
+ re: RegExp;
25
+ replace?: (match: string, ...groups: string[]) => string;
26
+ }
27
+ export declare const VALUE_PATTERNS: ReadonlyArray<ValuePattern>;
28
+ export declare function redactString(value: string): string;
29
+ /** Layers 2 and 3 over any JSON value. Pure: returns a new value. */
30
+ export declare function redactDeep<T>(value: T): T;
31
+ /** All three layers: the exact injected `secrets` first, then field names and value shapes. */
32
+ export declare function scrubResult<T>(value: T, secrets: ReadonlyArray<string>): T;
33
+ export {};
34
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/mcp/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAmBH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;CAC1D;AAED,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,YAAY,CAetD,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAczC;AAED,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAE1E"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Result scrubbing for brokered MCP calls (DES-MCP-TOOLS-001 §4.3 D-2, §6 step 8).
3
+ *
4
+ * Every result an upstream returns passes through here before a worker, a log or a record sees
5
+ * it, in this order:
6
+ *
7
+ * 1. **Exact secrets**: every value the broker injected on THIS call is replaced wherever it
8
+ * appears (`scrubSecrets`, the same pass the registry's probe uses).
9
+ * 2. **Field names**: a value under a credential-named key (Authorization, Cookie, *token*,
10
+ * *secret*, *passw*, *credential*, *session*, api/private/access/secret key, ...) becomes
11
+ * `[REDACTED:field:<name>]`, recursively.
12
+ * 3. **Value shapes**: credential-shaped substrings anywhere (Bearer/Basic auth, JWTs, AWS access
13
+ * key ids, GitHub/OpenAI/Slack tokens, `password=...` pairs, PEM private keys) become
14
+ * `[REDACTED:<pattern-id>]`.
15
+ *
16
+ * Layers 2 and 3 are ported from wicked-garden's QE evidence redactor
17
+ * (`scripts/qe/runner/src/redact.mjs`). One difference: garden also denies a bare `key` field.
18
+ * An MCP result routinely carries `key` as an identifier (a Jira issue key, a cache key), so here
19
+ * only the qualified credential keys are denied (`api_key`, `private-key`, `accessKey`, ...).
20
+ */
21
+ import { scrubSecrets } from './secrets.js';
22
+ const REDACTED = (reason) => `[REDACTED:${reason}]`;
23
+ const FIELD_NAME_DENY = [
24
+ /authorization/i,
25
+ /cookie/i,
26
+ /token/i,
27
+ /secret/i,
28
+ /passw/i,
29
+ /passphrase/i,
30
+ /credential/i,
31
+ /session/i,
32
+ /apikey/i,
33
+ /(api|private|access|secret|signing|client)[-_.]?key/i,
34
+ ];
35
+ export function isDeniedFieldName(name) {
36
+ return FIELD_NAME_DENY.some((re) => re.test(name));
37
+ }
38
+ export const VALUE_PATTERNS = [
39
+ { id: 'bearer', re: /\bBearer\s+[A-Za-z0-9._~+/=-]{8,}/g },
40
+ { id: 'basic-auth', re: /\bBasic\s+[A-Za-z0-9+/=]{8,}/g },
41
+ { id: 'jwt', re: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\b/g },
42
+ { id: 'aws-access-key', re: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g },
43
+ { id: 'github-token', re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/g },
44
+ { id: 'github-pat', re: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g },
45
+ { id: 'openai-key', re: /\bsk-[A-Za-z0-9_-]{16,}\b/g },
46
+ { id: 'slack-token', re: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g },
47
+ {
48
+ id: 'kv-secret',
49
+ re: /\b(token|secret|password|passwd|pwd|api[-_]?key|apikey|access[-_]?key|auth)=([^&\s"']{4,})/gi,
50
+ replace: (_m, k) => `${k}=${REDACTED('kv')}`,
51
+ },
52
+ { id: 'private-key-block', re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g },
53
+ ];
54
+ export function redactString(value) {
55
+ let out = value;
56
+ for (const { id, re, replace } of VALUE_PATTERNS) {
57
+ re.lastIndex = 0;
58
+ out = replace !== undefined ? out.replace(re, replace) : out.replace(re, REDACTED(id));
59
+ }
60
+ return out;
61
+ }
62
+ /** Layers 2 and 3 over any JSON value. Pure: returns a new value. */
63
+ export function redactDeep(value) {
64
+ const walk = (v) => {
65
+ if (typeof v === 'string')
66
+ return redactString(v);
67
+ if (Array.isArray(v))
68
+ return v.map(walk);
69
+ if (v !== null && typeof v === 'object') {
70
+ const out = {};
71
+ for (const [k, inner] of Object.entries(v)) {
72
+ out[k] = isDeniedFieldName(k) ? REDACTED(`field:${k}`) : walk(inner);
73
+ }
74
+ return out;
75
+ }
76
+ return v;
77
+ };
78
+ return walk(value);
79
+ }
80
+ /** All three layers: the exact injected `secrets` first, then field names and value shapes. */
81
+ export function scrubResult(value, secrets) {
82
+ return redactDeep(scrubSecrets(value, secrets));
83
+ }
84
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/mcp/redact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The MCP tools registry at rest (DES-MCP-TOOLS-001 §5): `<state home>/mcp/registry.json`.
3
+ *
4
+ * It holds upstreams and their tools with secret REFERENCES only; a value never lands here (D-2).
5
+ * The `mcp` entry is registered in the state-home fence registry (tests/fixtures/
6
+ * state-home-subtrees.json, core's `src/state_home.rs`), so a worker can't read it. The directory
7
+ * is created on the first save, never at boot.
8
+ *
9
+ * Writes are serialized on one promise chain and land atomically (write a sibling temp file,
10
+ * then rename), so a crash never leaves a torn registry. A registry that does not parse is an
11
+ * error the routes answer 503; it is never silently replaced by an empty one, because that
12
+ * would drop every server the operator registered.
13
+ */
14
+ import type { McpAuthConfig, McpHealth, McpRestMapping, McpToolAnnotations, McpToolClass, McpUpstreamKind } from '../core/types.js';
15
+ export declare const MCP_STATE_DIRNAME = "mcp";
16
+ export declare const MCP_REGISTRY_FILENAME = "registry.json";
17
+ /** `<state home>/mcp` — the one directory the MCP slices write under. */
18
+ export declare function mcpStateDir(): string;
19
+ export interface McpToolRecord {
20
+ name: string;
21
+ description: string | null;
22
+ inputSchema: Record<string, unknown> | null;
23
+ outputSchema: Record<string, unknown> | null;
24
+ annotations: McpToolAnnotations | null;
25
+ classOverride: McpToolClass | null;
26
+ enabled: boolean;
27
+ /** The hash the operator saved (registered); `null` = never registered (a tool added after the preview). */
28
+ schemaHash: string | null;
29
+ /** The hash the last probe saw; differs from `schemaHash` when the schema changed. */
30
+ observedSchemaHash: string;
31
+ /** `false` = the last probe no longer lists the tool (`gone`, kept so old records resolve). */
32
+ present: boolean;
33
+ /** A `rest` tool's request mapping (slice S5a); absent/`null` for an MCP server's tool. */
34
+ rest?: McpRestMapping | null;
35
+ }
36
+ export interface McpServerRecord {
37
+ name: string;
38
+ kind: McpUpstreamKind;
39
+ command: string | null;
40
+ args: string[];
41
+ url: string | null;
42
+ auth: McpAuthConfig | null;
43
+ /** `rest` only (slice S5a): the OpenAPI URL, or the pasted document; the operations picked. */
44
+ openapiUrl?: string | null;
45
+ openapi?: Record<string, unknown> | null;
46
+ operations?: string[] | null;
47
+ enabled: boolean;
48
+ health: McpHealth;
49
+ registeredAt: string;
50
+ updatedAt: string;
51
+ tools: McpToolRecord[];
52
+ }
53
+ export interface McpRegistryFile {
54
+ version: 1;
55
+ servers: McpServerRecord[];
56
+ }
57
+ export declare class McpRegistryCorruptError extends Error {
58
+ }
59
+ export declare class McpRegistryStore {
60
+ private readonly dir;
61
+ private tail;
62
+ constructor(dir?: string);
63
+ get path(): string;
64
+ read(): Promise<McpRegistryFile>;
65
+ /** Read, apply `fn`, write back, one mutation at a time. `fn`'s result is returned. */
66
+ mutate<T>(fn: (file: McpRegistryFile) => T | Promise<T>): Promise<T>;
67
+ private write;
68
+ }
69
+ //# sourceMappingURL=registry-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-store.d.ts","sourceRoot":"","sources":["../../src/mcp/registry-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGpI,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAErD,yEAAyE;AACzE,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACvC,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,4GAA4G;IAC5G,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sFAAsF;IACtF,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+FAA+F;IAC/F,OAAO,EAAE,OAAO,CAAC;IACjB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,+FAA+F;IAC/F,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;CAAG;AAErD,qBAAa,gBAAgB;IAGf,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,OAAO,CAAC,IAAI,CAAuC;gBAEtB,GAAG,GAAE,MAAsB;IAExD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEK,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAqBtC,uFAAuF;IACvF,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;YAWtD,KAAK;CAWpB"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The MCP tools registry at rest (DES-MCP-TOOLS-001 §5): `<state home>/mcp/registry.json`.
3
+ *
4
+ * It holds upstreams and their tools with secret REFERENCES only; a value never lands here (D-2).
5
+ * The `mcp` entry is registered in the state-home fence registry (tests/fixtures/
6
+ * state-home-subtrees.json, core's `src/state_home.rs`), so a worker can't read it. The directory
7
+ * is created on the first save, never at boot.
8
+ *
9
+ * Writes are serialized on one promise chain and land atomically (write a sibling temp file,
10
+ * then rename), so a crash never leaves a torn registry. A registry that does not parse is an
11
+ * error the routes answer 503; it is never silently replaced by an empty one, because that
12
+ * would drop every server the operator registered.
13
+ */
14
+ import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
15
+ import { randomUUID } from 'node:crypto';
16
+ import { join } from 'node:path';
17
+ import { crewStateHome } from '../projects/state-home.js';
18
+ export const MCP_STATE_DIRNAME = 'mcp';
19
+ export const MCP_REGISTRY_FILENAME = 'registry.json';
20
+ /** `<state home>/mcp` — the one directory the MCP slices write under. */
21
+ export function mcpStateDir() {
22
+ return join(crewStateHome(), 'mcp');
23
+ }
24
+ export class McpRegistryCorruptError extends Error {
25
+ }
26
+ export class McpRegistryStore {
27
+ dir;
28
+ tail = Promise.resolve();
29
+ constructor(dir = mcpStateDir()) {
30
+ this.dir = dir;
31
+ }
32
+ get path() {
33
+ return join(this.dir, MCP_REGISTRY_FILENAME);
34
+ }
35
+ async read() {
36
+ let text;
37
+ try {
38
+ text = await readFile(this.path, 'utf8');
39
+ }
40
+ catch (err) {
41
+ if (err.code === 'ENOENT')
42
+ return { version: 1, servers: [] };
43
+ throw err;
44
+ }
45
+ let parsed;
46
+ try {
47
+ parsed = JSON.parse(text);
48
+ }
49
+ catch {
50
+ throw new McpRegistryCorruptError(`${this.path} is not valid JSON; fix or remove it`);
51
+ }
52
+ const file = parsed;
53
+ if (file.version !== 1 || !Array.isArray(file.servers)) {
54
+ throw new McpRegistryCorruptError(`${this.path} is not a version 1 MCP registry`);
55
+ }
56
+ return file;
57
+ }
58
+ /** Read, apply `fn`, write back, one mutation at a time. `fn`'s result is returned. */
59
+ mutate(fn) {
60
+ const next = this.tail.then(async () => {
61
+ const file = await this.read();
62
+ const result = await fn(file);
63
+ await this.write(file);
64
+ return result;
65
+ });
66
+ this.tail = next.catch(() => undefined);
67
+ return next;
68
+ }
69
+ async write(file) {
70
+ await mkdir(this.dir, { recursive: true, mode: 0o700 });
71
+ const tmp = join(this.dir, `${MCP_REGISTRY_FILENAME}.tmp-${randomUUID()}`);
72
+ try {
73
+ await writeFile(tmp, `${JSON.stringify(file, null, 2)}\n`, { mode: 0o600 });
74
+ await rename(tmp, this.path);
75
+ }
76
+ catch (err) {
77
+ await rm(tmp, { force: true });
78
+ throw err;
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=registry-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-store.js","sourceRoot":"","sources":["../../src/mcp/registry-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * The MCP tools registry (DES-MCP-TOOLS-001 §5, §8; slice S2): register upstream MCP servers,
3
+ * keep their tool lists honest, and hold their secrets out of every response.
4
+ *
5
+ * - **Preview, then save.** `preview` probes the server and answers its tools with their classes
6
+ * and a `previewHash` over the exact config and tool schemas it saw. `save` takes ONLY that hash
7
+ * and registers what the preview showed. A save without a hash, or with one this daemon did not
8
+ * issue (or issued more than {@link PREVIEW_TTL_MS} ago), is refused, so nothing is registered
9
+ * that the operator did not see.
10
+ * - **Tool diff.** `test` probes a registered server again and records the difference. A tool
11
+ * whose schema hash changed, and a tool the server added, is `unregistered` (D-5 denies it)
12
+ * until it is previewed and saved again. A tool the server dropped is `gone`: kept, never
13
+ * deleted, so old call records still resolve. Health turns `failing` after 3 consecutive
14
+ * failed probes.
15
+ * - **Secrets.** Only a reference is stored. A value is resolved just for the probe and scrubbed
16
+ * from its result (`probe.ts`).
17
+ */
18
+ import type { McpDiscoveredServer, McpPreviewResponse, McpRestMapping, McpServer, McpServersResponse, McpServerTestResponse, McpTool, McpToolAnnotations, McpToolClass, McpToolDiff, McpToolStatus, McpUpstreamKind } from '../core/types.js';
19
+ import type { McpUpstreamConfig, Prober } from './probe.js';
20
+ import type { McpRegistryStore, McpToolRecord } from './registry-store.js';
21
+ import { type SecretStore } from './secrets.js';
22
+ /** How long a preview can be saved. */
23
+ export declare const PREVIEW_TTL_MS: number;
24
+ /** Consecutive failed probes before a server's health reads `failing`. */
25
+ export declare const HEALTH_FAILING_AFTER = 3;
26
+ /** A refusal the routes map to a status code. */
27
+ export declare class McpRegistryError extends Error {
28
+ readonly status: 400 | 404 | 409 | 500 | 501 | 502 | 503;
29
+ readonly code: string;
30
+ constructor(status: 400 | 404 | 409 | 500 | 501 | 502 | 503, code: string, message: string);
31
+ }
32
+ /** What the registry holds for one brokered call's subject. */
33
+ export interface McpCallTarget {
34
+ config: McpUpstreamConfig;
35
+ /** A `rest` tool's request mapping (slice S5a); `null` for an MCP server's tool. */
36
+ rest: McpRestMapping | null;
37
+ annotations: McpToolAnnotations | null;
38
+ classOverride: McpToolClass | null;
39
+ registered: boolean;
40
+ }
41
+ /** A registered, enabled tool, as the tool list judges it (`callableTools`). */
42
+ export interface McpCallableTool {
43
+ server: string;
44
+ tool: string;
45
+ kind: McpUpstreamKind;
46
+ annotations: McpToolAnnotations | null;
47
+ classOverride: McpToolClass | null;
48
+ description: string | null;
49
+ inputSchema: Record<string, unknown> | null;
50
+ }
51
+ export interface McpRegistryDeps {
52
+ store: McpRegistryStore;
53
+ secrets: SecretStore;
54
+ probe: Prober;
55
+ discover: (managed: ReadonlySet<string>) => McpDiscoveredServer[];
56
+ now?: () => number;
57
+ env?: NodeJS.ProcessEnv;
58
+ }
59
+ export declare class McpRegistry {
60
+ private readonly deps;
61
+ private readonly previews;
62
+ private readonly now;
63
+ private readonly env;
64
+ constructor(deps: McpRegistryDeps);
65
+ get secretStoreAvailable(): boolean;
66
+ list(): Promise<McpServersResponse>;
67
+ get(name: string): Promise<McpServer>;
68
+ /**
69
+ * Probe `config` and hold exactly what it showed, for `save` (crew#719: with `stagedSecret`, the
70
+ * secret this server's own keychain reference will hold — probed with now, written only when the
71
+ * save commits, so the OS store and the registry row land together or not at all).
72
+ */
73
+ preview(config: McpUpstreamConfig, stagedSecret?: string | null): Promise<McpPreviewResponse>;
74
+ /**
75
+ * Register exactly what a preview showed. Saving over an existing name re-registers it: every
76
+ * tool of the preview becomes `registered`, a tool it no longer lists becomes `gone`, a tool's
77
+ * `enabled` switch survives, and a class override survives only while the schema is unchanged.
78
+ */
79
+ save(previewHash: string | undefined): Promise<McpServer>;
80
+ /**
81
+ * Run `commit`; if it throws and this save had written the OS secret store, put the entry back
82
+ * exactly as it was — deleted when there was no `prior` value, restored to `prior` when there
83
+ * was (crew#719, review of PR #724). Either way the registry row and the credential it
84
+ * references end up as they were before the save.
85
+ *
86
+ * A rollback that ALSO fails is reported rather than swallowed: the operator is told what was
87
+ * left behind and under which account, because nothing else can find a keychain entry for them.
88
+ */
89
+ private restoreSecretOnFailure;
90
+ /** What a held preview would register: its server name and each tool's schema hash (S6). */
91
+ peekPreview(previewHash: string): {
92
+ name: string;
93
+ tools: Array<{
94
+ name: string;
95
+ schemaHash: string;
96
+ }>;
97
+ } | null;
98
+ setServerEnabled(name: string, enabled: boolean): Promise<McpServer>;
99
+ /** Remove a server, and the keychain secret it owns (`keychain:wicked-mcp/<name>`). */
100
+ remove(name: string): Promise<void>;
101
+ patchTool(subject: string, patch: {
102
+ enabled?: boolean | undefined;
103
+ classOverride?: McpToolClass | null | undefined;
104
+ }): Promise<McpTool>;
105
+ /** Probe a registered server again: record its health and its tool diff. */
106
+ test(name: string): Promise<McpServerTestResponse>;
107
+ /** Write a server's secret to the OS store; answers the reference to put in its `auth.ref`. */
108
+ setSecret(name: string, value: string): Promise<string>;
109
+ /**
110
+ * The broker's resolution of one subject (§6 step 2). `null` = no server of that name. A server
111
+ * that is disabled, a tool that is disabled, `gone`, never saved, or whose schema changed since it
112
+ * was saved reads `registered: false`, which the engine denies (D-5).
113
+ */
114
+ resolveCall(server: string, tool: string): Promise<McpCallTarget | null>;
115
+ /**
116
+ * Every tool a call could reach right now (slice S4, the shim's `list`): enabled servers, and
117
+ * their enabled tools whose saved schema is the one last seen. Anything else is D-5 and would be
118
+ * refused by the broker, so it is never offered.
119
+ */
120
+ callableTools(): Promise<McpCallableTool[]>;
121
+ /**
122
+ * The secret a call to `config` is made with, resolved at the moment of the call and nowhere
123
+ * else. `missing` = the server names a secret that resolves to nothing: the call is not made
124
+ * unauthenticated.
125
+ */
126
+ callSecret(config: McpUpstreamConfig): Promise<{
127
+ secret: string | null;
128
+ missing: boolean;
129
+ }>;
130
+ private find;
131
+ private hold;
132
+ /**
133
+ * Probe with the server's secret. A server whose `auth` names a secret that resolves to nothing
134
+ * is NOT probed unauthenticated (that would register what an anonymous caller sees): it fails
135
+ * without connecting.
136
+ */
137
+ private probe;
138
+ private authState;
139
+ private view;
140
+ }
141
+ export declare function toolStatus(t: Pick<McpToolRecord, 'present' | 'schemaHash' | 'observedSchemaHash'>): McpToolStatus;
142
+ /** The difference between the registered tools and a probe's (by name, then schema hash). */
143
+ export declare function diffTools(registered: ReadonlyArray<Pick<McpToolRecord, 'name' | 'schemaHash' | 'present'>>, probed: ReadonlyArray<{
144
+ name: string;
145
+ schemaHash: string;
146
+ }>): McpToolDiff;
147
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"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"}