patchwork-os 0.2.0-alpha.9 → 0.2.0-beta.0

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 (581) hide show
  1. package/README.bridge.md +6 -0
  2. package/README.md +315 -35
  3. package/deploy/bootstrap-new-vps.sh +12 -12
  4. package/deploy/bootstrap-vps.sh +187 -0
  5. package/deploy/deploy-dashboard.sh +174 -0
  6. package/deploy/deploy-landing.sh +136 -0
  7. package/dist/activationMetrics.d.ts +67 -0
  8. package/dist/activationMetrics.js +255 -0
  9. package/dist/activationMetrics.js.map +1 -0
  10. package/dist/activityLog.d.ts +49 -0
  11. package/dist/activityLog.js +78 -0
  12. package/dist/activityLog.js.map +1 -1
  13. package/dist/approvalHttp.d.ts +49 -2
  14. package/dist/approvalHttp.js +217 -21
  15. package/dist/approvalHttp.js.map +1 -1
  16. package/dist/approvalInsights.d.ts +49 -0
  17. package/dist/approvalInsights.js +97 -0
  18. package/dist/approvalInsights.js.map +1 -0
  19. package/dist/approvalQueue.d.ts +27 -1
  20. package/dist/approvalQueue.js +123 -3
  21. package/dist/approvalQueue.js.map +1 -1
  22. package/dist/approvalSignals.d.ts +124 -0
  23. package/dist/approvalSignals.js +512 -0
  24. package/dist/approvalSignals.js.map +1 -0
  25. package/dist/automation.d.ts +57 -0
  26. package/dist/automation.js +156 -59
  27. package/dist/automation.js.map +1 -1
  28. package/dist/automationSuggestions.d.ts +79 -0
  29. package/dist/automationSuggestions.js +150 -0
  30. package/dist/automationSuggestions.js.map +1 -0
  31. package/dist/bridge.d.ts +3 -0
  32. package/dist/bridge.js +174 -143
  33. package/dist/bridge.js.map +1 -1
  34. package/dist/bridgeToken.js +57 -19
  35. package/dist/bridgeToken.js.map +1 -1
  36. package/dist/ccPermissions.d.ts +15 -0
  37. package/dist/ccPermissions.js +21 -4
  38. package/dist/ccPermissions.js.map +1 -1
  39. package/dist/claudeDriver.js +74 -16
  40. package/dist/claudeDriver.js.map +1 -1
  41. package/dist/claudeOrchestrator.d.ts +1 -1
  42. package/dist/claudeOrchestrator.js +14 -8
  43. package/dist/claudeOrchestrator.js.map +1 -1
  44. package/dist/commands/dashboard.js +1 -1
  45. package/dist/commands/dashboard.js.map +1 -1
  46. package/dist/commands/launchd.d.ts +2 -0
  47. package/dist/commands/launchd.js +94 -0
  48. package/dist/commands/launchd.js.map +1 -0
  49. package/dist/commands/patchworkInit.d.ts +8 -0
  50. package/dist/commands/patchworkInit.js +77 -11
  51. package/dist/commands/patchworkInit.js.map +1 -1
  52. package/dist/commands/recipe.d.ts +289 -0
  53. package/dist/commands/recipe.js +1359 -0
  54. package/dist/commands/recipe.js.map +1 -0
  55. package/dist/commands/recipeInstall.d.ts +150 -0
  56. package/dist/commands/recipeInstall.js +647 -0
  57. package/dist/commands/recipeInstall.js.map +1 -0
  58. package/dist/commands/tracesExport.d.ts +83 -0
  59. package/dist/commands/tracesExport.js +269 -0
  60. package/dist/commands/tracesExport.js.map +1 -0
  61. package/dist/commands/tracesImport.d.ts +56 -0
  62. package/dist/commands/tracesImport.js +161 -0
  63. package/dist/commands/tracesImport.js.map +1 -0
  64. package/dist/config.d.ts +22 -1
  65. package/dist/config.js +108 -9
  66. package/dist/config.js.map +1 -1
  67. package/dist/connectorRoutes.d.ts +43 -0
  68. package/dist/connectorRoutes.js +1609 -0
  69. package/dist/connectorRoutes.js.map +1 -0
  70. package/dist/connectors/asana.d.ts +198 -0
  71. package/dist/connectors/asana.js +679 -0
  72. package/dist/connectors/asana.js.map +1 -0
  73. package/dist/connectors/baseConnector.d.ts +153 -0
  74. package/dist/connectors/baseConnector.js +336 -0
  75. package/dist/connectors/baseConnector.js.map +1 -0
  76. package/dist/connectors/confluence.d.ts +111 -0
  77. package/dist/connectors/confluence.js +406 -0
  78. package/dist/connectors/confluence.js.map +1 -0
  79. package/dist/connectors/datadog.d.ts +116 -0
  80. package/dist/connectors/datadog.js +385 -0
  81. package/dist/connectors/datadog.js.map +1 -0
  82. package/dist/connectors/discord.d.ts +150 -0
  83. package/dist/connectors/discord.js +543 -0
  84. package/dist/connectors/discord.js.map +1 -0
  85. package/dist/connectors/fixtureLibrary.d.ts +21 -0
  86. package/dist/connectors/fixtureLibrary.js +70 -0
  87. package/dist/connectors/fixtureLibrary.js.map +1 -0
  88. package/dist/connectors/fixtureRecorder.d.ts +1 -0
  89. package/dist/connectors/fixtureRecorder.js +35 -0
  90. package/dist/connectors/fixtureRecorder.js.map +1 -0
  91. package/dist/connectors/github.js +17 -18
  92. package/dist/connectors/github.js.map +1 -1
  93. package/dist/connectors/gitlab.d.ts +180 -0
  94. package/dist/connectors/gitlab.js +582 -0
  95. package/dist/connectors/gitlab.js.map +1 -0
  96. package/dist/connectors/gmail.d.ts +4 -1
  97. package/dist/connectors/gmail.js +149 -27
  98. package/dist/connectors/gmail.js.map +1 -1
  99. package/dist/connectors/googleCalendar.d.ts +4 -1
  100. package/dist/connectors/googleCalendar.js +88 -25
  101. package/dist/connectors/googleCalendar.js.map +1 -1
  102. package/dist/connectors/googleDrive.d.ts +34 -0
  103. package/dist/connectors/googleDrive.js +321 -0
  104. package/dist/connectors/googleDrive.js.map +1 -0
  105. package/dist/connectors/htmlEscape.d.ts +5 -0
  106. package/dist/connectors/htmlEscape.js +13 -0
  107. package/dist/connectors/htmlEscape.js.map +1 -0
  108. package/dist/connectors/hubspot.d.ts +112 -0
  109. package/dist/connectors/hubspot.js +408 -0
  110. package/dist/connectors/hubspot.js.map +1 -0
  111. package/dist/connectors/intercom.d.ts +102 -0
  112. package/dist/connectors/intercom.js +402 -0
  113. package/dist/connectors/intercom.js.map +1 -0
  114. package/dist/connectors/jira.d.ts +98 -0
  115. package/dist/connectors/jira.js +379 -0
  116. package/dist/connectors/jira.js.map +1 -0
  117. package/dist/connectors/linear.js +30 -19
  118. package/dist/connectors/linear.js.map +1 -1
  119. package/dist/connectors/mcpOAuth.d.ts +3 -0
  120. package/dist/connectors/mcpOAuth.js +64 -10
  121. package/dist/connectors/mcpOAuth.js.map +1 -1
  122. package/dist/connectors/mockConnector.d.ts +28 -0
  123. package/dist/connectors/mockConnector.js +81 -0
  124. package/dist/connectors/mockConnector.js.map +1 -0
  125. package/dist/connectors/notion.d.ts +143 -0
  126. package/dist/connectors/notion.js +424 -0
  127. package/dist/connectors/notion.js.map +1 -0
  128. package/dist/connectors/oauthStateStore.d.ts +31 -0
  129. package/dist/connectors/oauthStateStore.js +52 -0
  130. package/dist/connectors/oauthStateStore.js.map +1 -0
  131. package/dist/connectors/pagerduty.d.ts +160 -0
  132. package/dist/connectors/pagerduty.js +464 -0
  133. package/dist/connectors/pagerduty.js.map +1 -0
  134. package/dist/connectors/sentry.js +5 -13
  135. package/dist/connectors/sentry.js.map +1 -1
  136. package/dist/connectors/slack.d.ts +16 -1
  137. package/dist/connectors/slack.js +155 -32
  138. package/dist/connectors/slack.js.map +1 -1
  139. package/dist/connectors/stripe.d.ts +116 -0
  140. package/dist/connectors/stripe.js +379 -0
  141. package/dist/connectors/stripe.js.map +1 -0
  142. package/dist/connectors/tokenStorage.d.ts +35 -0
  143. package/dist/connectors/tokenStorage.js +484 -0
  144. package/dist/connectors/tokenStorage.js.map +1 -0
  145. package/dist/connectors/zendesk.d.ts +104 -0
  146. package/dist/connectors/zendesk.js +442 -0
  147. package/dist/connectors/zendesk.js.map +1 -0
  148. package/dist/cors.d.ts +10 -0
  149. package/dist/cors.js +29 -0
  150. package/dist/cors.js.map +1 -0
  151. package/dist/decisionReplay.d.ts +72 -0
  152. package/dist/decisionReplay.js +92 -0
  153. package/dist/decisionReplay.js.map +1 -0
  154. package/dist/decisionTraceLog.d.ts +6 -0
  155. package/dist/decisionTraceLog.js +54 -2
  156. package/dist/decisionTraceLog.js.map +1 -1
  157. package/dist/drivers/gemini/index.d.ts +5 -1
  158. package/dist/drivers/gemini/index.js +39 -5
  159. package/dist/drivers/gemini/index.js.map +1 -1
  160. package/dist/drivers/index.d.ts +5 -0
  161. package/dist/drivers/index.js +1 -1
  162. package/dist/drivers/index.js.map +1 -1
  163. package/dist/featureFlags.d.ts +79 -0
  164. package/dist/featureFlags.js +208 -0
  165. package/dist/featureFlags.js.map +1 -0
  166. package/dist/fp/automationInterpreter.js +26 -21
  167. package/dist/fp/automationInterpreter.js.map +1 -1
  168. package/dist/fp/automationProgram.d.ts +1 -1
  169. package/dist/fp/automationProgram.js.map +1 -1
  170. package/dist/fp/automationState.js +4 -1
  171. package/dist/fp/automationState.js.map +1 -1
  172. package/dist/fp/policyParser.js +21 -1
  173. package/dist/fp/policyParser.js.map +1 -1
  174. package/dist/inboxRoutes.d.ts +22 -0
  175. package/dist/inboxRoutes.js +114 -0
  176. package/dist/inboxRoutes.js.map +1 -0
  177. package/dist/index.js +1400 -201
  178. package/dist/index.js.map +1 -1
  179. package/dist/installGuard.d.ts +25 -0
  180. package/dist/installGuard.js +48 -0
  181. package/dist/installGuard.js.map +1 -0
  182. package/dist/mcpRoutes.d.ts +37 -0
  183. package/dist/mcpRoutes.js +76 -0
  184. package/dist/mcpRoutes.js.map +1 -0
  185. package/dist/oauth.d.ts +7 -1
  186. package/dist/oauth.js +201 -39
  187. package/dist/oauth.js.map +1 -1
  188. package/dist/oauthRoutes.d.ts +32 -0
  189. package/dist/oauthRoutes.js +124 -0
  190. package/dist/oauthRoutes.js.map +1 -0
  191. package/dist/orchestrator/orchestratorBridge.js +2 -2
  192. package/dist/orchestrator/orchestratorBridge.js.map +1 -1
  193. package/dist/patchworkConfig.d.ts +16 -0
  194. package/dist/patchworkConfig.js +1 -1
  195. package/dist/patchworkConfig.js.map +1 -1
  196. package/dist/pluginLoader.d.ts +28 -0
  197. package/dist/pluginLoader.js +77 -11
  198. package/dist/pluginLoader.js.map +1 -1
  199. package/dist/pluginWatcher.js +8 -3
  200. package/dist/pluginWatcher.js.map +1 -1
  201. package/dist/preToolUseHook.d.ts +12 -0
  202. package/dist/preToolUseHook.js +23 -0
  203. package/dist/preToolUseHook.js.map +1 -1
  204. package/dist/recipeOrchestration.d.ts +121 -0
  205. package/dist/recipeOrchestration.js +955 -0
  206. package/dist/recipeOrchestration.js.map +1 -0
  207. package/dist/recipeRoutes.d.ts +180 -0
  208. package/dist/recipeRoutes.js +1345 -0
  209. package/dist/recipeRoutes.js.map +1 -0
  210. package/dist/recipes/RecipeOrchestrator.d.ts +40 -0
  211. package/dist/recipes/RecipeOrchestrator.js +51 -0
  212. package/dist/recipes/RecipeOrchestrator.js.map +1 -0
  213. package/dist/recipes/agentExecutor.d.ts +29 -0
  214. package/dist/recipes/agentExecutor.js +49 -0
  215. package/dist/recipes/agentExecutor.js.map +1 -0
  216. package/dist/recipes/chainedRunner.d.ts +191 -0
  217. package/dist/recipes/chainedRunner.js +759 -0
  218. package/dist/recipes/chainedRunner.js.map +1 -0
  219. package/dist/recipes/compiler.js +3 -3
  220. package/dist/recipes/compiler.js.map +1 -1
  221. package/dist/recipes/dependencyGraph.d.ts +39 -0
  222. package/dist/recipes/dependencyGraph.js +199 -0
  223. package/dist/recipes/dependencyGraph.js.map +1 -0
  224. package/dist/recipes/disabledMarkers.d.ts +48 -0
  225. package/dist/recipes/disabledMarkers.js +52 -0
  226. package/dist/recipes/disabledMarkers.js.map +1 -0
  227. package/dist/recipes/installer.js +3 -3
  228. package/dist/recipes/installer.js.map +1 -1
  229. package/dist/recipes/legacyRecipeCompat.d.ts +10 -0
  230. package/dist/recipes/legacyRecipeCompat.js +131 -0
  231. package/dist/recipes/legacyRecipeCompat.js.map +1 -0
  232. package/dist/recipes/manifest.d.ts +47 -0
  233. package/dist/recipes/manifest.js +156 -0
  234. package/dist/recipes/manifest.js.map +1 -0
  235. package/dist/recipes/migrationWarnings.d.ts +12 -0
  236. package/dist/recipes/migrationWarnings.js +44 -0
  237. package/dist/recipes/migrationWarnings.js.map +1 -0
  238. package/dist/recipes/migrations/index.d.ts +24 -0
  239. package/dist/recipes/migrations/index.js +55 -0
  240. package/dist/recipes/migrations/index.js.map +1 -0
  241. package/dist/recipes/migrations/types.d.ts +28 -0
  242. package/dist/recipes/migrations/types.js +2 -0
  243. package/dist/recipes/migrations/types.js.map +1 -0
  244. package/dist/recipes/migrations/v1.d.ts +11 -0
  245. package/dist/recipes/migrations/v1.js +18 -0
  246. package/dist/recipes/migrations/v1.js.map +1 -0
  247. package/dist/recipes/names.d.ts +40 -0
  248. package/dist/recipes/names.js +66 -0
  249. package/dist/recipes/names.js.map +1 -0
  250. package/dist/recipes/nestedRecipeStep.d.ts +58 -0
  251. package/dist/recipes/nestedRecipeStep.js +95 -0
  252. package/dist/recipes/nestedRecipeStep.js.map +1 -0
  253. package/dist/recipes/outputRegistry.d.ts +28 -0
  254. package/dist/recipes/outputRegistry.js +52 -0
  255. package/dist/recipes/outputRegistry.js.map +1 -0
  256. package/dist/recipes/parser.js +4 -1
  257. package/dist/recipes/parser.js.map +1 -1
  258. package/dist/recipes/replayRun.d.ts +62 -0
  259. package/dist/recipes/replayRun.js +97 -0
  260. package/dist/recipes/replayRun.js.map +1 -0
  261. package/dist/recipes/resolveRecipePath.d.ts +69 -0
  262. package/dist/recipes/resolveRecipePath.js +202 -0
  263. package/dist/recipes/resolveRecipePath.js.map +1 -0
  264. package/dist/recipes/scheduler.d.ts +23 -7
  265. package/dist/recipes/scheduler.js +225 -45
  266. package/dist/recipes/scheduler.js.map +1 -1
  267. package/dist/recipes/schema.d.ts +17 -2
  268. package/dist/recipes/schemaGenerator.d.ts +28 -0
  269. package/dist/recipes/schemaGenerator.js +565 -0
  270. package/dist/recipes/schemaGenerator.js.map +1 -0
  271. package/dist/recipes/stepObservation.d.ts +44 -0
  272. package/dist/recipes/stepObservation.js +232 -0
  273. package/dist/recipes/stepObservation.js.map +1 -0
  274. package/dist/recipes/templateEngine.d.ts +62 -0
  275. package/dist/recipes/templateEngine.js +201 -0
  276. package/dist/recipes/templateEngine.js.map +1 -0
  277. package/dist/recipes/toolRegistry.d.ts +186 -0
  278. package/dist/recipes/toolRegistry.js +309 -0
  279. package/dist/recipes/toolRegistry.js.map +1 -0
  280. package/dist/recipes/tools/asana.d.ts +16 -0
  281. package/dist/recipes/tools/asana.js +524 -0
  282. package/dist/recipes/tools/asana.js.map +1 -0
  283. package/dist/recipes/tools/calendar.d.ts +6 -0
  284. package/dist/recipes/tools/calendar.js +61 -0
  285. package/dist/recipes/tools/calendar.js.map +1 -0
  286. package/dist/recipes/tools/confluence.d.ts +6 -0
  287. package/dist/recipes/tools/confluence.js +254 -0
  288. package/dist/recipes/tools/confluence.js.map +1 -0
  289. package/dist/recipes/tools/datadog.d.ts +6 -0
  290. package/dist/recipes/tools/datadog.js +239 -0
  291. package/dist/recipes/tools/datadog.js.map +1 -0
  292. package/dist/recipes/tools/diagnostics.d.ts +6 -0
  293. package/dist/recipes/tools/diagnostics.js +36 -0
  294. package/dist/recipes/tools/diagnostics.js.map +1 -0
  295. package/dist/recipes/tools/discord.d.ts +18 -0
  296. package/dist/recipes/tools/discord.js +254 -0
  297. package/dist/recipes/tools/discord.js.map +1 -0
  298. package/dist/recipes/tools/file.d.ts +12 -0
  299. package/dist/recipes/tools/file.js +174 -0
  300. package/dist/recipes/tools/file.js.map +1 -0
  301. package/dist/recipes/tools/git.d.ts +6 -0
  302. package/dist/recipes/tools/git.js +63 -0
  303. package/dist/recipes/tools/git.js.map +1 -0
  304. package/dist/recipes/tools/github.d.ts +6 -0
  305. package/dist/recipes/tools/github.js +116 -0
  306. package/dist/recipes/tools/github.js.map +1 -0
  307. package/dist/recipes/tools/gitlab.d.ts +11 -0
  308. package/dist/recipes/tools/gitlab.js +285 -0
  309. package/dist/recipes/tools/gitlab.js.map +1 -0
  310. package/dist/recipes/tools/gmail.d.ts +6 -0
  311. package/dist/recipes/tools/gmail.js +434 -0
  312. package/dist/recipes/tools/gmail.js.map +1 -0
  313. package/dist/recipes/tools/googleDrive.d.ts +1 -0
  314. package/dist/recipes/tools/googleDrive.js +55 -0
  315. package/dist/recipes/tools/googleDrive.js.map +1 -0
  316. package/dist/recipes/tools/hubspot.d.ts +6 -0
  317. package/dist/recipes/tools/hubspot.js +232 -0
  318. package/dist/recipes/tools/hubspot.js.map +1 -0
  319. package/dist/recipes/tools/index.d.ts +30 -0
  320. package/dist/recipes/tools/index.js +33 -0
  321. package/dist/recipes/tools/index.js.map +1 -0
  322. package/dist/recipes/tools/intercom.d.ts +6 -0
  323. package/dist/recipes/tools/intercom.js +226 -0
  324. package/dist/recipes/tools/intercom.js.map +1 -0
  325. package/dist/recipes/tools/jira.d.ts +14 -0
  326. package/dist/recipes/tools/jira.js +369 -0
  327. package/dist/recipes/tools/jira.js.map +1 -0
  328. package/dist/recipes/tools/linear.d.ts +7 -0
  329. package/dist/recipes/tools/linear.js +307 -0
  330. package/dist/recipes/tools/linear.js.map +1 -0
  331. package/dist/recipes/tools/meetingNotes.d.ts +21 -0
  332. package/dist/recipes/tools/meetingNotes.js +701 -0
  333. package/dist/recipes/tools/meetingNotes.js.map +1 -0
  334. package/dist/recipes/tools/notion.d.ts +6 -0
  335. package/dist/recipes/tools/notion.js +278 -0
  336. package/dist/recipes/tools/notion.js.map +1 -0
  337. package/dist/recipes/tools/pagerduty.d.ts +15 -0
  338. package/dist/recipes/tools/pagerduty.js +451 -0
  339. package/dist/recipes/tools/pagerduty.js.map +1 -0
  340. package/dist/recipes/tools/sentry.d.ts +12 -0
  341. package/dist/recipes/tools/sentry.js +73 -0
  342. package/dist/recipes/tools/sentry.js.map +1 -0
  343. package/dist/recipes/tools/slack.d.ts +6 -0
  344. package/dist/recipes/tools/slack.js +82 -0
  345. package/dist/recipes/tools/slack.js.map +1 -0
  346. package/dist/recipes/tools/stripe.d.ts +6 -0
  347. package/dist/recipes/tools/stripe.js +265 -0
  348. package/dist/recipes/tools/stripe.js.map +1 -0
  349. package/dist/recipes/tools/zendesk.d.ts +6 -0
  350. package/dist/recipes/tools/zendesk.js +245 -0
  351. package/dist/recipes/tools/zendesk.js.map +1 -0
  352. package/dist/recipes/validation.d.ts +13 -0
  353. package/dist/recipes/validation.js +617 -0
  354. package/dist/recipes/validation.js.map +1 -0
  355. package/dist/recipes/yamlRunner.d.ts +116 -1
  356. package/dist/recipes/yamlRunner.js +1000 -401
  357. package/dist/recipes/yamlRunner.js.map +1 -1
  358. package/dist/recipesHttp.d.ts +137 -6
  359. package/dist/recipesHttp.js +941 -29
  360. package/dist/recipesHttp.js.map +1 -1
  361. package/dist/riskTier.js +7 -1
  362. package/dist/riskTier.js.map +1 -1
  363. package/dist/runLog.d.ts +100 -1
  364. package/dist/runLog.js +258 -5
  365. package/dist/runLog.js.map +1 -1
  366. package/dist/schemas/dry-run-plan.v1.json +139 -0
  367. package/dist/schemas/recipe.v1.json +684 -0
  368. package/dist/server.d.ts +121 -8
  369. package/dist/server.js +538 -735
  370. package/dist/server.js.map +1 -1
  371. package/dist/ssrfGuard.d.ts +54 -0
  372. package/dist/ssrfGuard.js +122 -0
  373. package/dist/ssrfGuard.js.map +1 -0
  374. package/dist/streamableHttp.d.ts +39 -1
  375. package/dist/streamableHttp.js +128 -17
  376. package/dist/streamableHttp.js.map +1 -1
  377. package/dist/tokenUsageTracker.d.ts +33 -0
  378. package/dist/tokenUsageTracker.js +146 -0
  379. package/dist/tokenUsageTracker.js.map +1 -0
  380. package/dist/tools/activityLog.d.ts +2 -0
  381. package/dist/tools/addLinearComment.d.ts +1 -0
  382. package/dist/tools/addLinearComment.js +4 -2
  383. package/dist/tools/addLinearComment.js.map +1 -1
  384. package/dist/tools/batchLsp.d.ts +3 -0
  385. package/dist/tools/bridgeDoctor.d.ts +1 -0
  386. package/dist/tools/bridgeDoctor.js +2 -2
  387. package/dist/tools/bridgeDoctor.js.map +1 -1
  388. package/dist/tools/bridgeStatus.d.ts +1 -0
  389. package/dist/tools/cancelClaudeTask.d.ts +2 -0
  390. package/dist/tools/cancelClaudeTask.js +1 -0
  391. package/dist/tools/cancelClaudeTask.js.map +1 -1
  392. package/dist/tools/checkDocumentDirty.d.ts +1 -0
  393. package/dist/tools/clipboard.d.ts +2 -0
  394. package/dist/tools/closeTabs.d.ts +2 -0
  395. package/dist/tools/codeLens.d.ts +1 -0
  396. package/dist/tools/contextBundle.d.ts +1 -0
  397. package/dist/tools/createIssueFromAIComment.d.ts +1 -0
  398. package/dist/tools/createLinearIssue.d.ts +1 -0
  399. package/dist/tools/ctxGetTaskContext.d.ts +1 -0
  400. package/dist/tools/ctxQueryTraces.d.ts +1 -0
  401. package/dist/tools/ctxSaveTrace.d.ts +1 -0
  402. package/dist/tools/debug.d.ts +4 -0
  403. package/dist/tools/decorations.d.ts +2 -0
  404. package/dist/tools/documentLinks.d.ts +1 -0
  405. package/dist/tools/editText.d.ts +1 -0
  406. package/dist/tools/enrichCommit.d.ts +1 -0
  407. package/dist/tools/enrichStackTrace.d.ts +1 -0
  408. package/dist/tools/explainDiagnostic.d.ts +1 -0
  409. package/dist/tools/explainSymbol.d.ts +1 -0
  410. package/dist/tools/fetchCalendarEvents.d.ts +1 -0
  411. package/dist/tools/fetchGithubIssue.d.ts +1 -0
  412. package/dist/tools/fetchGithubPR.d.ts +1 -0
  413. package/dist/tools/fetchLinearIssue.d.ts +1 -0
  414. package/dist/tools/fetchSentryIssue.d.ts +1 -0
  415. package/dist/tools/fetchSlackProfile.d.ts +1 -0
  416. package/dist/tools/fetchSlackProfile.js +4 -1
  417. package/dist/tools/fetchSlackProfile.js.map +1 -1
  418. package/dist/tools/fileOperations.d.ts +3 -0
  419. package/dist/tools/fileWatcher.d.ts +2 -0
  420. package/dist/tools/findFiles.d.ts +1 -0
  421. package/dist/tools/findRelatedTests.d.ts +1 -0
  422. package/dist/tools/fixAllLintErrors.d.ts +1 -0
  423. package/dist/tools/foldingRanges.d.ts +1 -0
  424. package/dist/tools/formatDocument.d.ts +1 -0
  425. package/dist/tools/generateTests.d.ts +1 -0
  426. package/dist/tools/getAIComments.d.ts +1 -0
  427. package/dist/tools/getAnalyticsReport.d.ts +1 -0
  428. package/dist/tools/getArchitectureContext.d.ts +1 -0
  429. package/dist/tools/getBufferContent.d.ts +1 -0
  430. package/dist/tools/getChangeImpact.d.ts +1 -0
  431. package/dist/tools/getClaudeTaskStatus.d.ts +2 -0
  432. package/dist/tools/getClaudeTaskStatus.js +1 -0
  433. package/dist/tools/getClaudeTaskStatus.js.map +1 -1
  434. package/dist/tools/getCodeCoverage.d.ts +1 -0
  435. package/dist/tools/getCommitsForIssue.d.ts +1 -0
  436. package/dist/tools/getConnectorStatus.d.ts +1 -0
  437. package/dist/tools/getCurrentSelection.d.ts +2 -0
  438. package/dist/tools/getDebugState.d.ts +1 -0
  439. package/dist/tools/getDependencyTree.d.ts +1 -0
  440. package/dist/tools/getDiagnostics.d.ts +1 -0
  441. package/dist/tools/getDiffFromHandoff.d.ts +1 -0
  442. package/dist/tools/getDocumentSymbols.d.ts +25 -0
  443. package/dist/tools/getDocumentSymbols.js +74 -8
  444. package/dist/tools/getDocumentSymbols.js.map +1 -1
  445. package/dist/tools/getFileTree.d.ts +1 -0
  446. package/dist/tools/getGitDiff.d.ts +1 -0
  447. package/dist/tools/getGitHotspots.d.ts +1 -0
  448. package/dist/tools/getGitLog.d.ts +1 -0
  449. package/dist/tools/getGitStatus.d.ts +1 -0
  450. package/dist/tools/getImportTree.d.ts +1 -0
  451. package/dist/tools/getImportedSignatures.d.ts +1 -0
  452. package/dist/tools/getOpenEditors.d.ts +1 -0
  453. package/dist/tools/getPRTemplate.d.ts +1 -0
  454. package/dist/tools/getProjectContext.d.ts +1 -0
  455. package/dist/tools/getProjectInfo.d.ts +1 -0
  456. package/dist/tools/getSecurityAdvisories.d.ts +1 -0
  457. package/dist/tools/getSecurityAdvisories.js +10 -1
  458. package/dist/tools/getSecurityAdvisories.js.map +1 -1
  459. package/dist/tools/getSessionUsage.d.ts +4 -0
  460. package/dist/tools/getSessionUsage.js +3 -0
  461. package/dist/tools/getSessionUsage.js.map +1 -1
  462. package/dist/tools/getSymbolHistory.d.ts +1 -0
  463. package/dist/tools/getToolCapabilities.d.ts +1 -0
  464. package/dist/tools/getTypeSignature.d.ts +1 -0
  465. package/dist/tools/getWorkspaceFolders.d.ts +1 -0
  466. package/dist/tools/getWorkspaceSettings.d.ts +1 -0
  467. package/dist/tools/gitHistory.d.ts +2 -0
  468. package/dist/tools/gitWrite.d.ts +11 -0
  469. package/dist/tools/github/actions.d.ts +2 -0
  470. package/dist/tools/github/actions.js +4 -2
  471. package/dist/tools/github/actions.js.map +1 -1
  472. package/dist/tools/github/composite.d.ts +342 -0
  473. package/dist/tools/github/composite.js +343 -0
  474. package/dist/tools/github/composite.js.map +1 -0
  475. package/dist/tools/github/index.d.ts +1 -0
  476. package/dist/tools/github/index.js +1 -0
  477. package/dist/tools/github/index.js.map +1 -1
  478. package/dist/tools/github/issues.d.ts +4 -0
  479. package/dist/tools/github/issues.js +8 -4
  480. package/dist/tools/github/issues.js.map +1 -1
  481. package/dist/tools/github/pr.d.ts +7 -0
  482. package/dist/tools/github/pr.js +50 -12
  483. package/dist/tools/github/pr.js.map +1 -1
  484. package/dist/tools/handoffNote.d.ts +4 -0
  485. package/dist/tools/handoffNote.js +2 -0
  486. package/dist/tools/handoffNote.js.map +1 -1
  487. package/dist/tools/hoverAtCursor.d.ts +1 -0
  488. package/dist/tools/httpClient.d.ts +2 -0
  489. package/dist/tools/index.d.ts +8 -0
  490. package/dist/tools/index.js +47 -8
  491. package/dist/tools/index.js.map +1 -1
  492. package/dist/tools/inlayHints.d.ts +1 -0
  493. package/dist/tools/launchQuickTask.d.ts +2 -0
  494. package/dist/tools/launchQuickTask.js +1 -0
  495. package/dist/tools/launchQuickTask.js.map +1 -1
  496. package/dist/tools/listClaudeTasks.d.ts +2 -0
  497. package/dist/tools/listClaudeTasks.js +1 -0
  498. package/dist/tools/listClaudeTasks.js.map +1 -1
  499. package/dist/tools/listTerminals.d.ts +1 -0
  500. package/dist/tools/lsp.d.ts +14 -0
  501. package/dist/tools/navigateToSymbolByName.d.ts +1 -0
  502. package/dist/tools/openDiff.d.ts +1 -0
  503. package/dist/tools/openFile.d.ts +1 -0
  504. package/dist/tools/openInBrowser.d.ts +1 -0
  505. package/dist/tools/organizeImports.d.ts +1 -0
  506. package/dist/tools/performanceReport.d.ts +1 -0
  507. package/dist/tools/planPersistence.d.ts +5 -0
  508. package/dist/tools/previewEdit.d.ts +1 -0
  509. package/dist/tools/refactorAnalyze.d.ts +1 -0
  510. package/dist/tools/refactorPreview.d.ts +2 -0
  511. package/dist/tools/refactorPreview.js +1 -0
  512. package/dist/tools/refactorPreview.js.map +1 -1
  513. package/dist/tools/replaceBlock.d.ts +1 -0
  514. package/dist/tools/resumeClaudeTask.d.ts +2 -0
  515. package/dist/tools/resumeClaudeTask.js +1 -0
  516. package/dist/tools/resumeClaudeTask.js.map +1 -1
  517. package/dist/tools/runClaudeTask.d.ts +2 -0
  518. package/dist/tools/runClaudeTask.js +1 -0
  519. package/dist/tools/runClaudeTask.js.map +1 -1
  520. package/dist/tools/runCommand.d.ts +1 -0
  521. package/dist/tools/runTests.d.ts +1 -0
  522. package/dist/tools/saveDocument.d.ts +1 -0
  523. package/dist/tools/screenshotAndAnnotate.d.ts +1 -0
  524. package/dist/tools/searchAndReplace.d.ts +1 -0
  525. package/dist/tools/searchTools.d.ts +1 -0
  526. package/dist/tools/searchTools.js +1 -1
  527. package/dist/tools/searchTools.js.map +1 -1
  528. package/dist/tools/searchWorkspace.d.ts +1 -0
  529. package/dist/tools/selectionRanges.d.ts +1 -0
  530. package/dist/tools/semanticTokens.d.ts +1 -0
  531. package/dist/tools/setActiveWorkspaceFolder.d.ts +1 -0
  532. package/dist/tools/signatureHelp.d.ts +1 -0
  533. package/dist/tools/slackListChannels.d.ts +1 -0
  534. package/dist/tools/slackListChannels.js.map +1 -1
  535. package/dist/tools/slackPostMessage.d.ts +1 -0
  536. package/dist/tools/slackPostMessage.js +11 -6
  537. package/dist/tools/slackPostMessage.js.map +1 -1
  538. package/dist/tools/terminal.d.ts +6 -0
  539. package/dist/tools/testTraceToSource.d.ts +1 -0
  540. package/dist/tools/testTraceToSource.js +2 -2
  541. package/dist/tools/testTraceToSource.js.map +1 -1
  542. package/dist/tools/transaction.d.ts +23 -0
  543. package/dist/tools/transaction.js +29 -0
  544. package/dist/tools/transaction.js.map +1 -1
  545. package/dist/tools/typeHierarchy.d.ts +1 -0
  546. package/dist/tools/updateLinearIssue.d.ts +1 -0
  547. package/dist/tools/updateLinearIssue.js +20 -6
  548. package/dist/tools/updateLinearIssue.js.map +1 -1
  549. package/dist/tools/utils.d.ts +2 -0
  550. package/dist/tools/utils.js.map +1 -1
  551. package/dist/tools/vscodeCommands.d.ts +2 -0
  552. package/dist/tools/vscodeTasks.d.ts +2 -0
  553. package/dist/tools/workspaceSettings.d.ts +1 -0
  554. package/dist/traceEncryption.d.ts +46 -0
  555. package/dist/traceEncryption.js +124 -0
  556. package/dist/traceEncryption.js.map +1 -0
  557. package/dist/transport.d.ts +46 -1
  558. package/dist/transport.js +173 -19
  559. package/dist/transport.js.map +1 -1
  560. package/package.json +30 -8
  561. package/scripts/mcp-stdio-shim.cjs +19 -3
  562. package/scripts/start-all.sh +30 -1
  563. package/templates/automation-policies/recipe-authoring.json +25 -0
  564. package/templates/automation-policy.example.json +6 -0
  565. package/templates/co.patchwork-os.bridge.plist +34 -0
  566. package/templates/policies/README.md +72 -0
  567. package/templates/policies/conservative.json +14 -0
  568. package/templates/policies/developer.json +14 -0
  569. package/templates/policies/headless-ci.json +24 -0
  570. package/templates/policies/personal-assistant.json +15 -0
  571. package/templates/policies/regulated-industry.json +18 -0
  572. package/templates/recipes/lint-on-save.yaml +1 -2
  573. package/templates/recipes/morning-brief-slack.yaml +57 -0
  574. package/templates/recipes/morning-brief.yaml +2 -2
  575. package/templates/recipes/project-health-check.yaml +50 -0
  576. package/templates/recipes/webhook/README.md +70 -0
  577. package/templates/recipes/webhook/capture-thought.yaml +26 -0
  578. package/templates/recipes/webhook/customer-escalation.yaml +49 -0
  579. package/templates/recipes/webhook/incident-intake.yaml +46 -0
  580. package/templates/recipes/webhook/meeting-prep.yaml +48 -0
  581. package/templates/recipes/webhook/morning-brief.yaml +57 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Trace bundle encryption/decryption — AES-256-GCM with scrypt KDF.
3
+ *
4
+ * Binary format (all multi-byte values big-endian):
5
+ *
6
+ * Offset Len Field
7
+ * 0 8 Magic: ASCII "PWTRACE\0"
8
+ * 8 1 Version: 0x01
9
+ * 9 16 Salt (random, for scrypt)
10
+ * 25 12 IV / nonce (random, for AES-GCM)
11
+ * 37 16 GCM authentication tag
12
+ * 53 N Ciphertext (the original .jsonl.gz bytes)
13
+ *
14
+ * Key derivation: scrypt(passphrase, salt, N=16384, r=8, p=1, keyLen=32).
15
+ * N=2^14 matches Node's `crypto.scryptSync` default and is safe for
16
+ * interactive use on a modern laptop (~50ms, 16MB RAM). They are stored implicitly
17
+ * (fixed); changing them is a version bump.
18
+ *
19
+ * Security properties:
20
+ * - Unique salt per export → unique key per file even with the same passphrase.
21
+ * - GCM authentication tag → any tamper of ciphertext or header is detected.
22
+ * - scrypt → GPU-resistant brute-force on passphrase.
23
+ * - Buffer.fill(0) on key material after use → minimise in-process lifetime.
24
+ *
25
+ * The encrypted file is NOT gzip-compressed on top (the plaintext already
26
+ * is). Compressing ciphertext adds no size benefit and obscures the magic
27
+ * header used by the import command to auto-detect the format.
28
+ */
29
+ import { createCipheriv, createDecipheriv, randomBytes, scryptSync, } from "node:crypto";
30
+ export const TRACE_ENCRYPT_MAGIC = Buffer.from("PWTRACE\0", "ascii");
31
+ export const TRACE_ENCRYPT_VERSION = 0x01;
32
+ const SALT_LEN = 16;
33
+ const IV_LEN = 12;
34
+ const TAG_LEN = 16;
35
+ const HEADER_LEN = TRACE_ENCRYPT_MAGIC.length + 1 + SALT_LEN + IV_LEN + TAG_LEN; // 53
36
+ const SCRYPT_N = 16384; // 2^14 — Node scryptSync default; needs 128*N*r = 16MB RAM
37
+ const SCRYPT_R = 8;
38
+ const SCRYPT_P = 1;
39
+ const KEY_LEN = 32;
40
+ function deriveKey(passphrase, salt) {
41
+ return scryptSync(passphrase, salt, KEY_LEN, {
42
+ N: SCRYPT_N,
43
+ r: SCRYPT_R,
44
+ p: SCRYPT_P,
45
+ });
46
+ }
47
+ /**
48
+ * Encrypt a Buffer (the gzip-compressed trace bundle) with a passphrase.
49
+ * Returns a new Buffer in the wire format described above.
50
+ */
51
+ export function encryptTraceBundle(plaintext, passphrase) {
52
+ const salt = randomBytes(SALT_LEN);
53
+ const iv = randomBytes(IV_LEN);
54
+ const key = deriveKey(passphrase, salt);
55
+ try {
56
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
57
+ const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
58
+ const tag = cipher.getAuthTag();
59
+ const header = Buffer.alloc(HEADER_LEN);
60
+ let offset = 0;
61
+ TRACE_ENCRYPT_MAGIC.copy(header, offset);
62
+ offset += TRACE_ENCRYPT_MAGIC.length;
63
+ header[offset++] = TRACE_ENCRYPT_VERSION;
64
+ salt.copy(header, offset);
65
+ offset += SALT_LEN;
66
+ iv.copy(header, offset);
67
+ offset += IV_LEN;
68
+ tag.copy(header, offset);
69
+ return Buffer.concat([header, encrypted]);
70
+ }
71
+ finally {
72
+ key.fill(0);
73
+ }
74
+ }
75
+ /**
76
+ * Decrypt a Buffer that was produced by `encryptTraceBundle`.
77
+ * Returns the original plaintext (the gzip-compressed trace bundle).
78
+ * Throws if the magic, version, or GCM tag don't match.
79
+ */
80
+ export function decryptTraceBundle(ciphertext, passphrase) {
81
+ if (ciphertext.length < HEADER_LEN) {
82
+ throw new Error("Trace bundle too short to be a valid encrypted file");
83
+ }
84
+ const magic = ciphertext.subarray(0, TRACE_ENCRYPT_MAGIC.length);
85
+ if (!magic.equals(TRACE_ENCRYPT_MAGIC)) {
86
+ throw new Error("Not an encrypted Patchwork trace bundle (magic mismatch)");
87
+ }
88
+ const version = ciphertext[TRACE_ENCRYPT_MAGIC.length];
89
+ if (version !== TRACE_ENCRYPT_VERSION) {
90
+ throw new Error(`Unsupported encrypted bundle version: 0x${version?.toString(16) ?? "??"} (expected 0x01)`);
91
+ }
92
+ let offset = TRACE_ENCRYPT_MAGIC.length + 1;
93
+ const salt = ciphertext.subarray(offset, offset + SALT_LEN);
94
+ offset += SALT_LEN;
95
+ const iv = ciphertext.subarray(offset, offset + IV_LEN);
96
+ offset += IV_LEN;
97
+ const tag = ciphertext.subarray(offset, offset + TAG_LEN);
98
+ offset += TAG_LEN;
99
+ const encrypted = ciphertext.subarray(offset);
100
+ const key = deriveKey(passphrase, salt);
101
+ try {
102
+ const decipher = createDecipheriv("aes-256-gcm", key, iv);
103
+ decipher.setAuthTag(tag);
104
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]);
105
+ }
106
+ catch {
107
+ throw new Error("Decryption failed — wrong passphrase or corrupted file");
108
+ }
109
+ finally {
110
+ key.fill(0);
111
+ }
112
+ }
113
+ /**
114
+ * Returns true if the buffer starts with the encrypted trace bundle magic.
115
+ * Use this to auto-detect encrypted bundles at import time.
116
+ */
117
+ export function isEncryptedTraceBundle(buf) {
118
+ if (buf.length < TRACE_ENCRYPT_MAGIC.length)
119
+ return false;
120
+ return buf
121
+ .subarray(0, TRACE_ENCRYPT_MAGIC.length)
122
+ .equals(TRACE_ENCRYPT_MAGIC);
123
+ }
124
+ //# sourceMappingURL=traceEncryption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceEncryption.js","sourceRoot":"","sources":["../src/traceEncryption.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,15 @@ export declare class McpTransport {
49
49
  private activeListener;
50
50
  private inFlightControllers;
51
51
  private inFlightToolNames;
52
+ /**
53
+ * Snapshot of in-flight tool-call ids captured at `detachSoft()` time.
54
+ * Used by the per-call `finally` clause to clean up `inFlightControllers`
55
+ * + `activeToolCalls` even after attach() bumped `this.generation`. Without
56
+ * this set, an old-gen tool that settles after grace-period reattach would
57
+ * leak its slot in inFlightControllers AND its activeToolCalls count,
58
+ * which in turn makes HTTP eviction skip the session forever.
59
+ */
60
+ private detachSoftInflight;
52
61
  /** Pending elicitation/create requests waiting for a client response. */
53
62
  private pendingElicitations;
54
63
  private initialized;
@@ -57,6 +66,13 @@ export declare class McpTransport {
57
66
  private activeToolCalls;
58
67
  private callCount;
59
68
  private errorCount;
69
+ /**
70
+ * Tool calls rejected/expired by the human approval gate. Tracked
71
+ * separately from errorCount so dashboard stats and getSessionUsage can
72
+ * distinguish "human said no" from "tool blew up". Rejections never
73
+ * increment errorCount and never produce a tool-stats entry.
74
+ */
75
+ private approvalRejectionCount;
60
76
  private generation;
61
77
  private readonly sessionStartedAt;
62
78
  private readonly resultSizeTracker;
@@ -78,8 +94,12 @@ export declare class McpTransport {
78
94
  private readonly ajv;
79
95
  private readonly schemaValidators;
80
96
  private readonly outputValidators;
81
- /** Cached wire-schema array for tools/list. Invalidated on any tool registration change. */
97
+ /** Cached wire-schema array for tools/list (full mode). Invalidated on any tool registration change. */
82
98
  private wireSchemaCache;
99
+ /** Cached wire-schema array for tools/list in lazy mode (inputSchema stripped). */
100
+ private wireSchemaCacheLazy;
101
+ /** When true, tools/list omits inputSchema. Clients must call tools/schema before tools/call. */
102
+ private lazyTools;
83
103
  /** Per-session tool-call rate limit (calls/minute). 0 = disabled. */
84
104
  private toolRateLimit;
85
105
  /**
@@ -112,6 +132,8 @@ export declare class McpTransport {
112
132
  * Called at HTTP session initialize time from X-Bridge-Deny-Tools header.
113
133
  */
114
134
  setDenyTools(tools: Set<string>): void;
135
+ /** Enable lazy-tools mode: tools/list omits inputSchema; clients use tools/schema to fetch it. */
136
+ setLazyTools(enabled: boolean): void;
115
137
  /** Configure per-session tool call rate limiting (calls/minute, 0 = disabled). */
116
138
  setToolRateLimit(limit: number): void;
117
139
  /**
@@ -173,10 +195,33 @@ export declare class McpTransport {
173
195
  /** Remove all tools whose name starts with `prefix`. Returns count removed. */
174
196
  deregisterTool(name: string): boolean;
175
197
  deregisterToolsByPrefix(prefix: string): number;
198
+ /**
199
+ * Soft cleanup of stale per-connection state, used by the bridge's
200
+ * grace-period resumption path BEFORE calling `attach(ws)` with a new
201
+ * WebSocket. Unlike `detach()`, this does NOT abort in-flight tool calls
202
+ * or zero `activeToolCalls` — grace-period semantics preserve those
203
+ * across the reconnect. It only:
204
+ *
205
+ * 1. Removes the old WebSocket's "message" listener so it can't fire
206
+ * against the new connection's state.
207
+ * 2. Rejects any pending elicitation requests, because the original
208
+ * client that issued them may not be the one reattaching, and an
209
+ * unrelated client should not be allowed to answer another client's
210
+ * elicitation by id collision.
211
+ *
212
+ * Without this, two leaks survive a resumption:
213
+ * - The old `ws.on("message", ...)` listener accumulates (gen-guarded
214
+ * so it no-ops, but still attached to the now-closed socket).
215
+ * - `pendingElicitations` from the old connection persist in the map;
216
+ * the elicit timer keeps ticking and resolving against the NEW
217
+ * `activeWs`, surfacing prompts to a client that didn't request them.
218
+ */
219
+ detachSoft(): void;
176
220
  detach(): void;
177
221
  getStats(): {
178
222
  callCount: number;
179
223
  errorCount: number;
224
+ approvalRejectionCount: number;
180
225
  activeToolCalls: number;
181
226
  inFlightTools: string[];
182
227
  startedAt: number;
package/dist/transport.js CHANGED
@@ -41,6 +41,15 @@ export class McpTransport {
41
41
  activeListener = null;
42
42
  inFlightControllers = new Map();
43
43
  inFlightToolNames = new Map();
44
+ /**
45
+ * Snapshot of in-flight tool-call ids captured at `detachSoft()` time.
46
+ * Used by the per-call `finally` clause to clean up `inFlightControllers`
47
+ * + `activeToolCalls` even after attach() bumped `this.generation`. Without
48
+ * this set, an old-gen tool that settles after grace-period reattach would
49
+ * leak its slot in inFlightControllers AND its activeToolCalls count,
50
+ * which in turn makes HTTP eviction skip the session forever.
51
+ */
52
+ detachSoftInflight = new Set();
44
53
  /** Pending elicitation/create requests waiting for a client response. */
45
54
  pendingElicitations = new Map();
46
55
  initialized = false;
@@ -49,6 +58,13 @@ export class McpTransport {
49
58
  activeToolCalls = 0;
50
59
  callCount = 0;
51
60
  errorCount = 0;
61
+ /**
62
+ * Tool calls rejected/expired by the human approval gate. Tracked
63
+ * separately from errorCount so dashboard stats and getSessionUsage can
64
+ * distinguish "human said no" from "tool blew up". Rejections never
65
+ * increment errorCount and never produce a tool-stats entry.
66
+ */
67
+ approvalRejectionCount = 0;
52
68
  generation = 0; // incremented on each attach; stale handlers check this
53
69
  sessionStartedAt = Date.now();
54
70
  resultSizeTracker = new Map();
@@ -72,8 +88,12 @@ export class McpTransport {
72
88
  ajv = new Ajv({ strict: false, allErrors: true });
73
89
  schemaValidators = new Map();
74
90
  outputValidators = new Map();
75
- /** Cached wire-schema array for tools/list. Invalidated on any tool registration change. */
91
+ /** Cached wire-schema array for tools/list (full mode). Invalidated on any tool registration change. */
76
92
  wireSchemaCache = null;
93
+ /** Cached wire-schema array for tools/list in lazy mode (inputSchema stripped). */
94
+ wireSchemaCacheLazy = null;
95
+ /** When true, tools/list omits inputSchema. Clients must call tools/schema before tools/call. */
96
+ lazyTools = false;
77
97
  /** Per-session tool-call rate limit (calls/minute). 0 = disabled. */
78
98
  toolRateLimit = 60;
79
99
  /**
@@ -113,6 +133,10 @@ export class McpTransport {
113
133
  setDenyTools(tools) {
114
134
  this.denyTools = tools;
115
135
  }
136
+ /** Enable lazy-tools mode: tools/list omits inputSchema; clients use tools/schema to fetch it. */
137
+ setLazyTools(enabled) {
138
+ this.lazyTools = enabled;
139
+ }
116
140
  /** Configure per-session tool call rate limiting (calls/minute, 0 = disabled). */
117
141
  setToolRateLimit(limit) {
118
142
  this.toolRateLimit = limit;
@@ -281,6 +305,7 @@ export class McpTransport {
281
305
  this.schemaValidators.delete(schema.name);
282
306
  this.outputValidators.delete(schema.name);
283
307
  this.wireSchemaCache = null;
308
+ this.wireSchemaCacheLazy = null;
284
309
  this.tools.set(schema.name, {
285
310
  schema,
286
311
  handler,
@@ -292,6 +317,7 @@ export class McpTransport {
292
317
  this.schemaValidators.delete(name);
293
318
  this.outputValidators.delete(name);
294
319
  this.wireSchemaCache = null;
320
+ this.wireSchemaCacheLazy = null;
295
321
  return this.tools.delete(name);
296
322
  }
297
323
  deregisterToolsByPrefix(prefix) {
@@ -306,10 +332,51 @@ export class McpTransport {
306
332
  count++;
307
333
  }
308
334
  }
309
- if (count > 0)
335
+ if (count > 0) {
310
336
  this.wireSchemaCache = null;
337
+ this.wireSchemaCacheLazy = null;
338
+ }
311
339
  return count;
312
340
  }
341
+ /**
342
+ * Soft cleanup of stale per-connection state, used by the bridge's
343
+ * grace-period resumption path BEFORE calling `attach(ws)` with a new
344
+ * WebSocket. Unlike `detach()`, this does NOT abort in-flight tool calls
345
+ * or zero `activeToolCalls` — grace-period semantics preserve those
346
+ * across the reconnect. It only:
347
+ *
348
+ * 1. Removes the old WebSocket's "message" listener so it can't fire
349
+ * against the new connection's state.
350
+ * 2. Rejects any pending elicitation requests, because the original
351
+ * client that issued them may not be the one reattaching, and an
352
+ * unrelated client should not be allowed to answer another client's
353
+ * elicitation by id collision.
354
+ *
355
+ * Without this, two leaks survive a resumption:
356
+ * - The old `ws.on("message", ...)` listener accumulates (gen-guarded
357
+ * so it no-ops, but still attached to the now-closed socket).
358
+ * - `pendingElicitations` from the old connection persist in the map;
359
+ * the elicit timer keeps ticking and resolving against the NEW
360
+ * `activeWs`, surfacing prompts to a client that didn't request them.
361
+ */
362
+ detachSoft() {
363
+ if (this.activeWs && this.activeListener) {
364
+ this.activeWs.removeListener("message", this.activeListener);
365
+ this.activeListener = null;
366
+ }
367
+ for (const [, pending] of this.pendingElicitations) {
368
+ pending.reject(new Error("Client disconnected before responding to elicitation"));
369
+ }
370
+ this.pendingElicitations.clear();
371
+ // Snapshot in-flight ids so the per-call finally can clean them up after
372
+ // attach() flips `this.generation`. Merge into the existing set rather
373
+ // than replacing it — multiple back-to-back grace-period reconnects can
374
+ // leave several "old" generations of tool calls in flight, and a later
375
+ // detachSoft must not lose ids carried over from an earlier one.
376
+ for (const id of this.inFlightControllers.keys()) {
377
+ this.detachSoftInflight.add(id);
378
+ }
379
+ }
313
380
  detach() {
314
381
  // Remove listener from old WebSocket to prevent accumulation
315
382
  if (this.activeWs && this.activeListener) {
@@ -322,6 +389,9 @@ export class McpTransport {
322
389
  }
323
390
  this.inFlightControllers.clear();
324
391
  this.inFlightToolNames.clear();
392
+ // Hard detach also drops any pending detachSoft snapshot — those calls
393
+ // are aborted, their finally clauses can no longer leak.
394
+ this.detachSoftInflight.clear();
325
395
  // Reject all pending elicitation requests so callers don't hang after disconnect
326
396
  for (const [, pending] of this.pendingElicitations) {
327
397
  pending.reject(new Error("Client disconnected before responding to elicitation"));
@@ -342,6 +412,7 @@ export class McpTransport {
342
412
  return {
343
413
  callCount: this.callCount,
344
414
  errorCount: this.errorCount,
415
+ approvalRejectionCount: this.approvalRejectionCount,
345
416
  activeToolCalls: this.activeToolCalls,
346
417
  inFlightTools: [...this.inFlightToolNames.values()],
347
418
  startedAt: this.sessionStartedAt,
@@ -363,6 +434,7 @@ export class McpTransport {
363
434
  }
364
435
  // Invalidate wire cache — categories are stripped but getToolSchemas reads them
365
436
  this.wireSchemaCache = null;
437
+ this.wireSchemaCacheLazy = null;
366
438
  }
367
439
  /** Returns all registered tool schemas — used by searchTools for keyword/category discovery. */
368
440
  getToolSchemas() {
@@ -608,15 +680,33 @@ export class McpTransport {
608
680
  };
609
681
  break;
610
682
  }
611
- if (!this.wireSchemaCache) {
612
- this.wireSchemaCache = Array.from(this.tools.values()).map((t) => {
613
- // Strip internal-only fields before sending on the wire.
614
- // cache_control is intentionally NOT stripped — it passes through to clients.
615
- const { extensionRequired: _ext, timeoutMs: _timeout, categories: _cat, outputSchema: _outputSchema, ...wireSchema } = t.schema;
616
- return wireSchema;
617
- });
683
+ if (this.lazyTools) {
684
+ // Lazy mode: strip inputSchema from wire response.
685
+ // Clients must call tools/schema to fetch the full schema before tools/call.
686
+ if (!this.wireSchemaCacheLazy) {
687
+ this.wireSchemaCacheLazy = Array.from(this.tools.values()).map((t) => {
688
+ // Strip internal-only fields AND inputSchema in lazy mode.
689
+ // cache_control is intentionally NOT stripped — it passes through to clients.
690
+ const { extensionRequired: _ext, timeoutMs: _timeout, categories: _cat, outputSchema: _outputSchema, inputSchema: _inputSchema, ...wireSchema } = t.schema;
691
+ return wireSchema;
692
+ });
693
+ }
694
+ }
695
+ else {
696
+ if (!this.wireSchemaCache) {
697
+ this.wireSchemaCache = Array.from(this.tools.values()).map((t) => {
698
+ // Strip internal-only fields before sending on the wire.
699
+ // cache_control is intentionally NOT stripped — it passes through to clients.
700
+ const { extensionRequired: _ext, timeoutMs: _timeout, categories: _cat, outputSchema: _outputSchema, ...wireSchema } = t.schema;
701
+ return wireSchema;
702
+ });
703
+ }
618
704
  }
619
- const allTools = this.wireSchemaCache;
705
+ const allTools = this.lazyTools
706
+ ? // biome-ignore lint/style/noNonNullAssertion: built above
707
+ this.wireSchemaCacheLazy
708
+ : // biome-ignore lint/style/noNonNullAssertion: built above
709
+ this.wireSchemaCache;
620
710
  // Parse cursor (opaque base64-encoded decimal offset)
621
711
  const listParams = msg.params;
622
712
  let offset = 0;
@@ -649,6 +739,48 @@ export class McpTransport {
649
739
  };
650
740
  break;
651
741
  }
742
+ case "tools/schema": {
743
+ // Fetch full schema for a single tool by name.
744
+ // Always available regardless of lazyTools mode.
745
+ // Schema validation uses in-memory schema regardless of lazyTools mode.
746
+ const schemaParams = msg.params;
747
+ if (typeof schemaParams?.name !== "string" || !schemaParams.name) {
748
+ response = {
749
+ jsonrpc: "2.0",
750
+ id: msg.id,
751
+ error: {
752
+ code: ErrorCodes.INVALID_PARAMS,
753
+ message: 'Missing required param: "name"',
754
+ },
755
+ };
756
+ break;
757
+ }
758
+ const toolEntry = this.tools.get(schemaParams.name);
759
+ if (!toolEntry) {
760
+ response = {
761
+ jsonrpc: "2.0",
762
+ id: msg.id,
763
+ error: {
764
+ code: ErrorCodes.METHOD_NOT_FOUND,
765
+ message: `Tool not found: ${schemaParams.name}`,
766
+ },
767
+ };
768
+ break;
769
+ }
770
+ response = {
771
+ jsonrpc: "2.0",
772
+ id: msg.id,
773
+ result: {
774
+ name: toolEntry.schema.name,
775
+ description: toolEntry.schema.description,
776
+ inputSchema: toolEntry.schema.inputSchema,
777
+ ...(toolEntry.schema.outputSchema !== undefined && {
778
+ outputSchema: toolEntry.schema.outputSchema,
779
+ }),
780
+ },
781
+ };
782
+ break;
783
+ }
652
784
  case "tools/call": {
653
785
  if (!this.initialized) {
654
786
  response = {
@@ -832,7 +964,11 @@ export class McpTransport {
832
964
  };
833
965
  }
834
966
  else {
835
- const startTime = Date.now();
967
+ // startTime is captured AFTER the approval gate (below) so that
968
+ // human-decision wait time is excluded from tool stats. Capturing
969
+ // it here would inflate avgDurationMs / p95 / p99 by the entire
970
+ // approval wait — see fix for approval-gate stats pollution bug.
971
+ let startTime = 0;
836
972
  const callId = Math.random().toString(36).slice(2, 10);
837
973
  const callLog = this.logger.child({ tool: params.name, callId });
838
974
  let timedOut = false;
@@ -874,7 +1010,8 @@ export class McpTransport {
874
1010
  // schemas use additionalProperties:false, so leaving it in causes
875
1011
  // AJV to reject the call with -32602.
876
1012
  const { _meta: _stripped, ...toolArgs } = rawArgs;
877
- // AJV structural validation
1013
+ // Schema validation uses in-memory schema regardless of lazyTools mode.
1014
+ // AJV compiles from tool.schema.inputSchema, not from the wire response.
878
1015
  const validate = this.getValidator(params.name);
879
1016
  if (validate && !validate(toolArgs)) {
880
1017
  this.callCount++;
@@ -923,8 +1060,15 @@ export class McpTransport {
923
1060
  this.activeToolCalls--;
924
1061
  this.inFlightToolNames.delete(msg.id);
925
1062
  this.inFlightControllers.delete(msg.id);
926
- this.errorCount++;
927
- this.activityLog?.record(params.name, Date.now() - startTime, "error", undefined, this.sessionId ?? undefined);
1063
+ // Approval rejections/expiries are NOT tool failures — track
1064
+ // them on a dedicated counter and record a lifecycle event
1065
+ // (not a tool entry) so stats() avg/p95/p99 stay clean.
1066
+ this.approvalRejectionCount++;
1067
+ this.activityLog?.recordEvent("approval_rejected", {
1068
+ tool: params.name,
1069
+ decision,
1070
+ sessionId: this.sessionId ?? undefined,
1071
+ });
928
1072
  response = {
929
1073
  jsonrpc: "2.0",
930
1074
  id: msg.id,
@@ -943,6 +1087,10 @@ export class McpTransport {
943
1087
  break;
944
1088
  }
945
1089
  }
1090
+ // Start the duration clock now — AFTER the approval gate has
1091
+ // resolved — so stats reflect actual tool execution time, not
1092
+ // the time the human spent thinking about the approval.
1093
+ startTime = Date.now();
946
1094
  try {
947
1095
  const effectiveTimeout = tool.timeoutMs ?? TOOL_TIMEOUT_MS;
948
1096
  const timeoutPromise = new Promise((_, reject) => {
@@ -1024,11 +1172,17 @@ export class McpTransport {
1024
1172
  finally {
1025
1173
  if (timeoutHandle !== undefined)
1026
1174
  clearTimeout(timeoutHandle);
1027
- // Only touch shared state if we're still on the same generation.
1028
- // detach() clears inFlightControllers and resets activeToolCalls for
1029
- // new connections; an orphaned finally from a previous generation must
1030
- // not delete the new session's controller or skew its counter.
1031
- if (gen === this.generation) {
1175
+ // Only touch shared state if we're still on the same generation,
1176
+ // OR if this id was snapshotted by detachSoft() (grace-period
1177
+ // resumption). detach() clears inFlightControllers and resets
1178
+ // activeToolCalls for hard reconnects; an orphaned finally
1179
+ // from a previous generation must not delete the new session's
1180
+ // controller or skew its counter — UNLESS detachSoft preserved
1181
+ // this id, in which case its slot in inFlightControllers and
1182
+ // its activeToolCalls count survived the reattach and MUST be
1183
+ // released now that the call has settled.
1184
+ const wasSoftPreserved = this.detachSoftInflight.delete(msg.id);
1185
+ if (gen === this.generation || wasSoftPreserved) {
1032
1186
  this.inFlightControllers.delete(msg.id);
1033
1187
  this.inFlightToolNames.delete(msg.id);
1034
1188
  this.activeToolCalls = Math.max(0, this.activeToolCalls - 1);