patchwork-os 0.2.0-beta.9.canary.92 → 1.1.0-beta.1

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 (739) hide show
  1. package/README.bridge.md +15 -16
  2. package/README.md +46 -458
  3. package/dist/activationMetrics.js +2 -3
  4. package/dist/activationMetrics.js.map +1 -1
  5. package/dist/activityLog.d.ts +1 -0
  6. package/dist/activityLog.js +8 -3
  7. package/dist/activityLog.js.map +1 -1
  8. package/dist/adapters/gemini.js +2 -2
  9. package/dist/adapters/gemini.js.map +1 -1
  10. package/dist/adapters/grok.js +6 -1
  11. package/dist/adapters/grok.js.map +1 -1
  12. package/dist/adapters/openai.js +4 -0
  13. package/dist/adapters/openai.js.map +1 -1
  14. package/dist/approvalHttp.d.ts +9 -0
  15. package/dist/approvalHttp.js +210 -171
  16. package/dist/approvalHttp.js.map +1 -1
  17. package/dist/approvalKpi.d.ts +102 -0
  18. package/dist/approvalKpi.js +282 -0
  19. package/dist/approvalKpi.js.map +1 -0
  20. package/dist/approvalQueue.d.ts +1 -1
  21. package/dist/approvalQueue.js.map +1 -1
  22. package/dist/automation.d.ts +45 -4
  23. package/dist/automation.js +123 -15
  24. package/dist/automation.js.map +1 -1
  25. package/dist/bridge.d.ts +10 -0
  26. package/dist/bridge.js +225 -46
  27. package/dist/bridge.js.map +1 -1
  28. package/dist/bridgeLockDiscovery.d.ts +16 -1
  29. package/dist/bridgeLockDiscovery.js +38 -4
  30. package/dist/bridgeLockDiscovery.js.map +1 -1
  31. package/dist/bridgeToolsRules.js +3 -18
  32. package/dist/bridgeToolsRules.js.map +1 -1
  33. package/dist/claudeAuthHttp.d.ts +25 -0
  34. package/dist/claudeAuthHttp.js +219 -0
  35. package/dist/claudeAuthHttp.js.map +1 -0
  36. package/dist/claudeDriver.js +4 -1
  37. package/dist/claudeDriver.js.map +1 -1
  38. package/dist/claudeOrchestrator.d.ts +15 -0
  39. package/dist/claudeOrchestrator.js +44 -0
  40. package/dist/claudeOrchestrator.js.map +1 -1
  41. package/dist/commands/connect.d.ts +47 -0
  42. package/dist/commands/connect.js +419 -0
  43. package/dist/commands/connect.js.map +1 -0
  44. package/dist/commands/install.js +3 -10
  45. package/dist/commands/install.js.map +1 -1
  46. package/dist/commands/launchd.d.ts +7 -0
  47. package/dist/commands/launchd.js +20 -2
  48. package/dist/commands/launchd.js.map +1 -1
  49. package/dist/commands/patchworkInit.d.ts +7 -0
  50. package/dist/commands/patchworkInit.js +26 -0
  51. package/dist/commands/patchworkInit.js.map +1 -1
  52. package/dist/commands/recipe.d.ts +59 -4
  53. package/dist/commands/recipe.js +206 -5
  54. package/dist/commands/recipe.js.map +1 -1
  55. package/dist/commands/recipeInstall.d.ts +9 -0
  56. package/dist/commands/recipeInstall.js +56 -3
  57. package/dist/commands/recipeInstall.js.map +1 -1
  58. package/dist/commands/task.d.ts +25 -0
  59. package/dist/commands/task.js +61 -41
  60. package/dist/commands/task.js.map +1 -1
  61. package/dist/commands/tokenEfficiency.d.ts +4 -0
  62. package/dist/commands/tokenEfficiency.js +23 -26
  63. package/dist/commands/tokenEfficiency.js.map +1 -1
  64. package/dist/commands/tracesExport.d.ts +15 -1
  65. package/dist/commands/tracesExport.js +39 -5
  66. package/dist/commands/tracesExport.js.map +1 -1
  67. package/dist/config.js +16 -0
  68. package/dist/config.js.map +1 -1
  69. package/dist/connectorRoutes.js +613 -62
  70. package/dist/connectorRoutes.js.map +1 -1
  71. package/dist/connectors/asana.js +9 -3
  72. package/dist/connectors/asana.js.map +1 -1
  73. package/dist/connectors/baseConnector.d.ts +16 -0
  74. package/dist/connectors/baseConnector.js +2 -0
  75. package/dist/connectors/baseConnector.js.map +1 -1
  76. package/dist/connectors/caldiy.js +34 -0
  77. package/dist/connectors/caldiy.js.map +1 -1
  78. package/dist/connectors/confluence.js +9 -2
  79. package/dist/connectors/confluence.js.map +1 -1
  80. package/dist/connectors/connectorActivity.d.ts +24 -0
  81. package/dist/connectors/connectorActivity.js +32 -0
  82. package/dist/connectors/connectorActivity.js.map +1 -0
  83. package/dist/connectors/connectorRedirectUri.js +22 -2
  84. package/dist/connectors/connectorRedirectUri.js.map +1 -1
  85. package/dist/connectors/connectorRegistry.d.ts +0 -3
  86. package/dist/connectors/connectorRegistry.js +8 -8
  87. package/dist/connectors/connectorRegistry.js.map +1 -1
  88. package/dist/connectors/datadog.js +8 -1
  89. package/dist/connectors/datadog.js.map +1 -1
  90. package/dist/connectors/discord.js +4 -3
  91. package/dist/connectors/discord.js.map +1 -1
  92. package/dist/connectors/elasticsearch.js +22 -0
  93. package/dist/connectors/elasticsearch.js.map +1 -1
  94. package/dist/connectors/github.d.ts +38 -0
  95. package/dist/connectors/github.js +91 -5
  96. package/dist/connectors/github.js.map +1 -1
  97. package/dist/connectors/gitlab.js +19 -16
  98. package/dist/connectors/gitlab.js.map +1 -1
  99. package/dist/connectors/gmail.d.ts +5 -0
  100. package/dist/connectors/gmail.js +53 -11
  101. package/dist/connectors/gmail.js.map +1 -1
  102. package/dist/connectors/googleCalendar.js +5 -4
  103. package/dist/connectors/googleCalendar.js.map +1 -1
  104. package/dist/connectors/googleDocs.js +7 -6
  105. package/dist/connectors/googleDocs.js.map +1 -1
  106. package/dist/connectors/googleDrive.js +15 -8
  107. package/dist/connectors/googleDrive.js.map +1 -1
  108. package/dist/connectors/grafana.js +39 -3
  109. package/dist/connectors/grafana.js.map +1 -1
  110. package/dist/connectors/jira.d.ts +1 -1
  111. package/dist/connectors/jira.js +19 -4
  112. package/dist/connectors/jira.js.map +1 -1
  113. package/dist/connectors/linear.js +2 -2
  114. package/dist/connectors/linear.js.map +1 -1
  115. package/dist/connectors/mcpClient.d.ts +29 -1
  116. package/dist/connectors/mcpClient.js +114 -44
  117. package/dist/connectors/mcpClient.js.map +1 -1
  118. package/dist/connectors/mcpOAuth.d.ts +1 -0
  119. package/dist/connectors/mcpOAuth.js +49 -4
  120. package/dist/connectors/mcpOAuth.js.map +1 -1
  121. package/dist/connectors/monday.js +5 -4
  122. package/dist/connectors/monday.js.map +1 -1
  123. package/dist/connectors/mongodb.js +32 -5
  124. package/dist/connectors/mongodb.js.map +1 -1
  125. package/dist/connectors/notion.d.ts +1 -1
  126. package/dist/connectors/notion.js +22 -6
  127. package/dist/connectors/notion.js.map +1 -1
  128. package/dist/connectors/oauthError.d.ts +17 -0
  129. package/dist/connectors/oauthError.js +50 -0
  130. package/dist/connectors/oauthError.js.map +1 -0
  131. package/dist/connectors/postgres.d.ts +7 -0
  132. package/dist/connectors/postgres.js +32 -2
  133. package/dist/connectors/postgres.js.map +1 -1
  134. package/dist/connectors/posthog.js +26 -0
  135. package/dist/connectors/posthog.js.map +1 -1
  136. package/dist/connectors/redis.d.ts +1 -0
  137. package/dist/connectors/redis.js +47 -20
  138. package/dist/connectors/redis.js.map +1 -1
  139. package/dist/connectors/salesforce.js +66 -5
  140. package/dist/connectors/salesforce.js.map +1 -1
  141. package/dist/connectors/sentry.js +2 -2
  142. package/dist/connectors/sentry.js.map +1 -1
  143. package/dist/connectors/slack.js +37 -14
  144. package/dist/connectors/slack.js.map +1 -1
  145. package/dist/connectors/snowflake.js +24 -0
  146. package/dist/connectors/snowflake.js.map +1 -1
  147. package/dist/connectors/stripe.js +9 -2
  148. package/dist/connectors/stripe.js.map +1 -1
  149. package/dist/connectors/supabase.js +34 -0
  150. package/dist/connectors/supabase.js.map +1 -1
  151. package/dist/connectors/tokenStorage.d.ts +20 -0
  152. package/dist/connectors/tokenStorage.js +196 -64
  153. package/dist/connectors/tokenStorage.js.map +1 -1
  154. package/dist/connectors/woocommerce.js +34 -0
  155. package/dist/connectors/woocommerce.js.map +1 -1
  156. package/dist/copilot/parseIntent.d.ts +58 -0
  157. package/dist/copilot/parseIntent.js +149 -0
  158. package/dist/copilot/parseIntent.js.map +1 -0
  159. package/dist/decisionReplay.d.ts +8 -6
  160. package/dist/decisionReplay.js +35 -11
  161. package/dist/decisionReplay.js.map +1 -1
  162. package/dist/decisionTraceLog.d.ts +9 -0
  163. package/dist/decisionTraceLog.js +6 -0
  164. package/dist/decisionTraceLog.js.map +1 -1
  165. package/dist/drivers/claude/api.js +49 -7
  166. package/dist/drivers/claude/api.js.map +1 -1
  167. package/dist/drivers/claude/envSanitizer.d.ts +9 -1
  168. package/dist/drivers/claude/envSanitizer.js +41 -3
  169. package/dist/drivers/claude/envSanitizer.js.map +1 -1
  170. package/dist/drivers/claude/streamParser.d.ts +13 -0
  171. package/dist/drivers/claude/streamParser.js.map +1 -1
  172. package/dist/drivers/claude/subprocess.js +131 -16
  173. package/dist/drivers/claude/subprocess.js.map +1 -1
  174. package/dist/drivers/claude/subprocessSettings.d.ts +1 -1
  175. package/dist/drivers/claude/subprocessSettings.js +18 -4
  176. package/dist/drivers/claude/subprocessSettings.js.map +1 -1
  177. package/dist/drivers/gemini/index.d.ts +13 -0
  178. package/dist/drivers/gemini/index.js +211 -67
  179. package/dist/drivers/gemini/index.js.map +1 -1
  180. package/dist/drivers/local/index.d.ts +2 -17
  181. package/dist/drivers/local/index.js +5 -92
  182. package/dist/drivers/local/index.js.map +1 -1
  183. package/dist/drivers/openai/index.js +69 -9
  184. package/dist/drivers/openai/index.js.map +1 -1
  185. package/dist/drivers/outputCap.d.ts +27 -0
  186. package/dist/drivers/outputCap.js +50 -0
  187. package/dist/drivers/outputCap.js.map +1 -0
  188. package/dist/embeddings/cosine.d.ts +23 -0
  189. package/dist/embeddings/cosine.js +59 -0
  190. package/dist/embeddings/cosine.js.map +1 -0
  191. package/dist/embeddings/index.d.ts +19 -0
  192. package/dist/embeddings/index.js +35 -0
  193. package/dist/embeddings/index.js.map +1 -0
  194. package/dist/embeddings/localEmbeddings.d.ts +29 -0
  195. package/dist/embeddings/localEmbeddings.js +103 -0
  196. package/dist/embeddings/localEmbeddings.js.map +1 -0
  197. package/dist/embeddings/localEndpoints.d.ts +24 -0
  198. package/dist/embeddings/localEndpoints.js +37 -0
  199. package/dist/embeddings/localEndpoints.js.map +1 -0
  200. package/dist/embeddings/types.d.ts +32 -0
  201. package/dist/embeddings/types.js +12 -0
  202. package/dist/embeddings/types.js.map +1 -0
  203. package/dist/featureFlags.d.ts +18 -0
  204. package/dist/featureFlags.js +32 -0
  205. package/dist/featureFlags.js.map +1 -1
  206. package/dist/fp/automationInterpreter.js +118 -39
  207. package/dist/fp/automationInterpreter.js.map +1 -1
  208. package/dist/fp/automationProgram.d.ts +10 -0
  209. package/dist/fp/automationProgram.js.map +1 -1
  210. package/dist/fp/automationState.d.ts +6 -0
  211. package/dist/fp/automationState.js +38 -0
  212. package/dist/fp/automationState.js.map +1 -1
  213. package/dist/fp/commandDescription.d.ts +6 -0
  214. package/dist/fp/commandDescription.js +18 -5
  215. package/dist/fp/commandDescription.js.map +1 -1
  216. package/dist/fp/interpreterContext.d.ts +16 -5
  217. package/dist/fp/interpreterContext.js +59 -3
  218. package/dist/fp/interpreterContext.js.map +1 -1
  219. package/dist/fp/policyParser.js +18 -8
  220. package/dist/fp/policyParser.js.map +1 -1
  221. package/dist/haltPushDispatch.d.ts +4 -0
  222. package/dist/haltPushDispatch.js +7 -22
  223. package/dist/haltPushDispatch.js.map +1 -1
  224. package/dist/inboxRoutes.js +2 -2
  225. package/dist/inboxRoutes.js.map +1 -1
  226. package/dist/index.js +672 -135
  227. package/dist/index.js.map +1 -1
  228. package/dist/installGuard.js +6 -0
  229. package/dist/installGuard.js.map +1 -1
  230. package/dist/localEndpointGuard.d.ts +25 -0
  231. package/dist/localEndpointGuard.js +101 -0
  232. package/dist/localEndpointGuard.js.map +1 -0
  233. package/dist/mcpRoutes.js +1 -1
  234. package/dist/mcpRoutes.js.map +1 -1
  235. package/dist/oauth.d.ts +13 -0
  236. package/dist/oauth.js +53 -9
  237. package/dist/oauth.js.map +1 -1
  238. package/dist/orchestrator/childBridgeClient.d.ts +7 -0
  239. package/dist/orchestrator/childBridgeClient.js +42 -1
  240. package/dist/orchestrator/childBridgeClient.js.map +1 -1
  241. package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
  242. package/dist/orchestrator/orchestratorBridge.js +75 -9
  243. package/dist/orchestrator/orchestratorBridge.js.map +1 -1
  244. package/dist/patchworkConfig.d.ts +4 -0
  245. package/dist/patchworkConfig.js +33 -4
  246. package/dist/patchworkConfig.js.map +1 -1
  247. package/dist/probe.js +39 -5
  248. package/dist/probe.js.map +1 -1
  249. package/dist/recipeOrchestration.d.ts +59 -0
  250. package/dist/recipeOrchestration.js +314 -60
  251. package/dist/recipeOrchestration.js.map +1 -1
  252. package/dist/recipeRoutes.d.ts +93 -0
  253. package/dist/recipeRoutes.js +664 -27
  254. package/dist/recipeRoutes.js.map +1 -1
  255. package/dist/recipes/RecipeOrchestrator.d.ts +14 -0
  256. package/dist/recipes/RecipeOrchestrator.js +42 -2
  257. package/dist/recipes/RecipeOrchestrator.js.map +1 -1
  258. package/dist/recipes/agentExecutor.d.ts +51 -2
  259. package/dist/recipes/agentExecutor.js +86 -13
  260. package/dist/recipes/agentExecutor.js.map +1 -1
  261. package/dist/recipes/chainedRunner.d.ts +111 -3
  262. package/dist/recipes/chainedRunner.js +440 -45
  263. package/dist/recipes/chainedRunner.js.map +1 -1
  264. package/dist/recipes/compiler.js +42 -29
  265. package/dist/recipes/compiler.js.map +1 -1
  266. package/dist/recipes/connectorPreflight.js +31 -0
  267. package/dist/recipes/connectorPreflight.js.map +1 -1
  268. package/dist/recipes/dependencyGraph.d.ts +16 -0
  269. package/dist/recipes/dependencyGraph.js +37 -2
  270. package/dist/recipes/dependencyGraph.js.map +1 -1
  271. package/dist/recipes/eventTriggerPrograms.d.ts +36 -0
  272. package/dist/recipes/eventTriggerPrograms.js +158 -0
  273. package/dist/recipes/eventTriggerPrograms.js.map +1 -0
  274. package/dist/recipes/githubInstallSource.d.ts +9 -2
  275. package/dist/recipes/githubInstallSource.js +36 -6
  276. package/dist/recipes/githubInstallSource.js.map +1 -1
  277. package/dist/recipes/haltCategory.d.ts +10 -0
  278. package/dist/recipes/haltCategory.js +11 -1
  279. package/dist/recipes/haltCategory.js.map +1 -1
  280. package/dist/recipes/idempotencyKey.d.ts +30 -3
  281. package/dist/recipes/idempotencyKey.js +89 -5
  282. package/dist/recipes/idempotencyKey.js.map +1 -1
  283. package/dist/recipes/installer.js +12 -35
  284. package/dist/recipes/installer.js.map +1 -1
  285. package/dist/recipes/judgeVerdict.d.ts +11 -1
  286. package/dist/recipes/judgeVerdict.js +47 -7
  287. package/dist/recipes/judgeVerdict.js.map +1 -1
  288. package/dist/recipes/names.d.ts +5 -0
  289. package/dist/recipes/names.js +10 -5
  290. package/dist/recipes/names.js.map +1 -1
  291. package/dist/recipes/parser.js +74 -10
  292. package/dist/recipes/parser.js.map +1 -1
  293. package/dist/recipes/pricing/costRouter.d.ts +43 -0
  294. package/dist/recipes/pricing/costRouter.js +44 -0
  295. package/dist/recipes/pricing/costRouter.js.map +1 -0
  296. package/dist/recipes/pricing/priceTable.d.ts +76 -0
  297. package/dist/recipes/pricing/priceTable.js +144 -0
  298. package/dist/recipes/pricing/priceTable.js.map +1 -0
  299. package/dist/recipes/replayRun.js +5 -2
  300. package/dist/recipes/replayRun.js.map +1 -1
  301. package/dist/recipes/resolveRecipePath.js +15 -1
  302. package/dist/recipes/resolveRecipePath.js.map +1 -1
  303. package/dist/recipes/runBudget.d.ts +93 -32
  304. package/dist/recipes/runBudget.js +213 -49
  305. package/dist/recipes/runBudget.js.map +1 -1
  306. package/dist/recipes/runRegistry.d.ts +32 -0
  307. package/dist/recipes/runRegistry.js +54 -0
  308. package/dist/recipes/runRegistry.js.map +1 -0
  309. package/dist/recipes/scheduler.js +6 -2
  310. package/dist/recipes/scheduler.js.map +1 -1
  311. package/dist/recipes/schema.d.ts +59 -6
  312. package/dist/recipes/schemaGenerator.d.ts +9 -0
  313. package/dist/recipes/schemaGenerator.js +446 -77
  314. package/dist/recipes/schemaGenerator.js.map +1 -1
  315. package/dist/recipes/simulation/aggregateRunRisk.d.ts +46 -0
  316. package/dist/recipes/simulation/aggregateRunRisk.js +120 -0
  317. package/dist/recipes/simulation/aggregateRunRisk.js.map +1 -0
  318. package/dist/recipes/simulation/costProjector.d.ts +32 -0
  319. package/dist/recipes/simulation/costProjector.js +194 -0
  320. package/dist/recipes/simulation/costProjector.js.map +1 -0
  321. package/dist/recipes/simulation/sideEffects.d.ts +32 -0
  322. package/dist/recipes/simulation/sideEffects.js +62 -0
  323. package/dist/recipes/simulation/sideEffects.js.map +1 -0
  324. package/dist/recipes/simulation/simulate.d.ts +36 -0
  325. package/dist/recipes/simulation/simulate.js +264 -0
  326. package/dist/recipes/simulation/simulate.js.map +1 -0
  327. package/dist/recipes/simulation/simulateMockedRun.d.ts +52 -0
  328. package/dist/recipes/simulation/simulateMockedRun.js +84 -0
  329. package/dist/recipes/simulation/simulateMockedRun.js.map +1 -0
  330. package/dist/recipes/simulation/synthesizeMockedOutputs.d.ts +31 -0
  331. package/dist/recipes/simulation/synthesizeMockedOutputs.js +50 -0
  332. package/dist/recipes/simulation/synthesizeMockedOutputs.js.map +1 -0
  333. package/dist/recipes/simulation/types.d.ts +198 -0
  334. package/dist/recipes/simulation/types.js +30 -0
  335. package/dist/recipes/simulation/types.js.map +1 -0
  336. package/dist/recipes/stepObservation.d.ts +12 -0
  337. package/dist/recipes/stepObservation.js +21 -1
  338. package/dist/recipes/stepObservation.js.map +1 -1
  339. package/dist/recipes/toolRegistry.js +61 -24
  340. package/dist/recipes/toolRegistry.js.map +1 -1
  341. package/dist/recipes/tools/airtable.d.ts +15 -0
  342. package/dist/recipes/tools/airtable.js +240 -0
  343. package/dist/recipes/tools/airtable.js.map +1 -0
  344. package/dist/recipes/tools/caldiy.d.ts +13 -0
  345. package/dist/recipes/tools/caldiy.js +215 -0
  346. package/dist/recipes/tools/caldiy.js.map +1 -0
  347. package/dist/recipes/tools/circleci.d.ts +10 -0
  348. package/dist/recipes/tools/circleci.js +204 -0
  349. package/dist/recipes/tools/circleci.js.map +1 -0
  350. package/dist/recipes/tools/cloudflare.d.ts +13 -0
  351. package/dist/recipes/tools/cloudflare.js +211 -0
  352. package/dist/recipes/tools/cloudflare.js.map +1 -0
  353. package/dist/recipes/tools/confluence.js +11 -10
  354. package/dist/recipes/tools/confluence.js.map +1 -1
  355. package/dist/recipes/tools/datadog.js +13 -12
  356. package/dist/recipes/tools/datadog.js.map +1 -1
  357. package/dist/recipes/tools/docs.d.ts +18 -0
  358. package/dist/recipes/tools/docs.js +95 -0
  359. package/dist/recipes/tools/docs.js.map +1 -0
  360. package/dist/recipes/tools/elasticsearch.d.ts +11 -0
  361. package/dist/recipes/tools/elasticsearch.js +157 -0
  362. package/dist/recipes/tools/elasticsearch.js.map +1 -0
  363. package/dist/recipes/tools/fanOut.js +4 -4
  364. package/dist/recipes/tools/fanOut.js.map +1 -1
  365. package/dist/recipes/tools/figma.d.ts +12 -0
  366. package/dist/recipes/tools/figma.js +195 -0
  367. package/dist/recipes/tools/figma.js.map +1 -0
  368. package/dist/recipes/tools/file.js +43 -22
  369. package/dist/recipes/tools/file.js.map +1 -1
  370. package/dist/recipes/tools/github.js +162 -5
  371. package/dist/recipes/tools/github.js.map +1 -1
  372. package/dist/recipes/tools/gmail.js +45 -33
  373. package/dist/recipes/tools/gmail.js.map +1 -1
  374. package/dist/recipes/tools/grafana.d.ts +11 -0
  375. package/dist/recipes/tools/grafana.js +216 -0
  376. package/dist/recipes/tools/grafana.js.map +1 -0
  377. package/dist/recipes/tools/http.d.ts +1 -1
  378. package/dist/recipes/tools/http.js +10 -28
  379. package/dist/recipes/tools/http.js.map +1 -1
  380. package/dist/recipes/tools/hubspot.js +13 -12
  381. package/dist/recipes/tools/hubspot.js.map +1 -1
  382. package/dist/recipes/tools/index.d.ts +28 -0
  383. package/dist/recipes/tools/index.js +28 -0
  384. package/dist/recipes/tools/index.js.map +1 -1
  385. package/dist/recipes/tools/intercom.js +11 -10
  386. package/dist/recipes/tools/intercom.js.map +1 -1
  387. package/dist/recipes/tools/jira.js +13 -0
  388. package/dist/recipes/tools/jira.js.map +1 -1
  389. package/dist/recipes/tools/meetingNotes.js +2 -2
  390. package/dist/recipes/tools/monday.d.ts +22 -0
  391. package/dist/recipes/tools/monday.js +242 -0
  392. package/dist/recipes/tools/monday.js.map +1 -0
  393. package/dist/recipes/tools/mongodb.d.ts +19 -0
  394. package/dist/recipes/tools/mongodb.js +194 -0
  395. package/dist/recipes/tools/mongodb.js.map +1 -0
  396. package/dist/recipes/tools/notion.js +11 -10
  397. package/dist/recipes/tools/notion.js.map +1 -1
  398. package/dist/recipes/tools/obsidian.d.ts +15 -0
  399. package/dist/recipes/tools/obsidian.js +173 -0
  400. package/dist/recipes/tools/obsidian.js.map +1 -0
  401. package/dist/recipes/tools/outcomes.d.ts +15 -0
  402. package/dist/recipes/tools/outcomes.js +111 -0
  403. package/dist/recipes/tools/outcomes.js.map +1 -0
  404. package/dist/recipes/tools/paystack.d.ts +11 -0
  405. package/dist/recipes/tools/paystack.js +212 -0
  406. package/dist/recipes/tools/paystack.js.map +1 -0
  407. package/dist/recipes/tools/pipedrive.d.ts +16 -0
  408. package/dist/recipes/tools/pipedrive.js +234 -0
  409. package/dist/recipes/tools/pipedrive.js.map +1 -0
  410. package/dist/recipes/tools/postgres.d.ts +15 -0
  411. package/dist/recipes/tools/postgres.js +186 -0
  412. package/dist/recipes/tools/postgres.js.map +1 -0
  413. package/dist/recipes/tools/posthog.d.ts +16 -0
  414. package/dist/recipes/tools/posthog.js +219 -0
  415. package/dist/recipes/tools/posthog.js.map +1 -0
  416. package/dist/recipes/tools/redis.d.ts +9 -0
  417. package/dist/recipes/tools/redis.js +141 -0
  418. package/dist/recipes/tools/redis.js.map +1 -0
  419. package/dist/recipes/tools/resend.d.ts +8 -0
  420. package/dist/recipes/tools/resend.js +153 -0
  421. package/dist/recipes/tools/resend.js.map +1 -0
  422. package/dist/recipes/tools/salesforce.d.ts +16 -0
  423. package/dist/recipes/tools/salesforce.js +184 -0
  424. package/dist/recipes/tools/salesforce.js.map +1 -0
  425. package/dist/recipes/tools/sendgrid.d.ts +9 -0
  426. package/dist/recipes/tools/sendgrid.js +175 -0
  427. package/dist/recipes/tools/sendgrid.js.map +1 -0
  428. package/dist/recipes/tools/shopify.d.ts +16 -0
  429. package/dist/recipes/tools/shopify.js +266 -0
  430. package/dist/recipes/tools/shopify.js.map +1 -0
  431. package/dist/recipes/tools/snowflake.d.ts +16 -0
  432. package/dist/recipes/tools/snowflake.js +173 -0
  433. package/dist/recipes/tools/snowflake.js.map +1 -0
  434. package/dist/recipes/tools/stripe.js +13 -12
  435. package/dist/recipes/tools/stripe.js.map +1 -1
  436. package/dist/recipes/tools/supabase.d.ts +9 -0
  437. package/dist/recipes/tools/supabase.js +133 -0
  438. package/dist/recipes/tools/supabase.js.map +1 -0
  439. package/dist/recipes/tools/todoist.d.ts +15 -0
  440. package/dist/recipes/tools/todoist.js +228 -0
  441. package/dist/recipes/tools/todoist.js.map +1 -0
  442. package/dist/recipes/tools/twilio.d.ts +11 -0
  443. package/dist/recipes/tools/twilio.js +180 -0
  444. package/dist/recipes/tools/twilio.js.map +1 -0
  445. package/dist/recipes/tools/vercel.d.ts +9 -0
  446. package/dist/recipes/tools/vercel.js +146 -0
  447. package/dist/recipes/tools/vercel.js.map +1 -0
  448. package/dist/recipes/tools/webflow.d.ts +11 -0
  449. package/dist/recipes/tools/webflow.js +244 -0
  450. package/dist/recipes/tools/webflow.js.map +1 -0
  451. package/dist/recipes/tools/woocommerce.d.ts +18 -0
  452. package/dist/recipes/tools/woocommerce.js +260 -0
  453. package/dist/recipes/tools/woocommerce.js.map +1 -0
  454. package/dist/recipes/tools/wrapConnectorExecute.d.ts +25 -0
  455. package/dist/recipes/tools/wrapConnectorExecute.js +37 -0
  456. package/dist/recipes/tools/wrapConnectorExecute.js.map +1 -0
  457. package/dist/recipes/tools/zendesk.js +11 -10
  458. package/dist/recipes/tools/zendesk.js.map +1 -1
  459. package/dist/recipes/triggerVars.d.ts +15 -0
  460. package/dist/recipes/triggerVars.js +57 -0
  461. package/dist/recipes/triggerVars.js.map +1 -0
  462. package/dist/recipes/validation.d.ts +1 -1
  463. package/dist/recipes/validation.js +536 -12
  464. package/dist/recipes/validation.js.map +1 -1
  465. package/dist/recipes/yamlPositions.d.ts +1 -1
  466. package/dist/recipes/yamlPositions.js +7 -2
  467. package/dist/recipes/yamlPositions.js.map +1 -1
  468. package/dist/recipes/yamlRunner.d.ts +216 -4
  469. package/dist/recipes/yamlRunner.js +1030 -96
  470. package/dist/recipes/yamlRunner.js.map +1 -1
  471. package/dist/recipesHttp.d.ts +5 -0
  472. package/dist/recipesHttp.js +68 -6
  473. package/dist/recipesHttp.js.map +1 -1
  474. package/dist/resources.js +14 -1
  475. package/dist/resources.js.map +1 -1
  476. package/dist/riskSignals.d.ts +42 -0
  477. package/dist/riskSignals.js +197 -0
  478. package/dist/riskSignals.js.map +1 -0
  479. package/dist/riskTier.d.ts +9 -0
  480. package/dist/riskTier.js +48 -0
  481. package/dist/riskTier.js.map +1 -1
  482. package/dist/runLog.d.ts +53 -0
  483. package/dist/runLog.js +75 -16
  484. package/dist/runLog.js.map +1 -1
  485. package/dist/schemas/recipe.v1.json +360 -16
  486. package/dist/server.d.ts +60 -0
  487. package/dist/server.js +192 -31
  488. package/dist/server.js.map +1 -1
  489. package/dist/sessionCheckpoint.js +4 -1
  490. package/dist/sessionCheckpoint.js.map +1 -1
  491. package/dist/sessionDetail.d.ts +43 -0
  492. package/dist/sessionDetail.js +59 -0
  493. package/dist/sessionDetail.js.map +1 -0
  494. package/dist/settingsEnv.d.ts +47 -0
  495. package/dist/settingsEnv.js +88 -0
  496. package/dist/settingsEnv.js.map +1 -0
  497. package/dist/streamableHttp.js +44 -10
  498. package/dist/streamableHttp.js.map +1 -1
  499. package/dist/ta/backtest/abnday.d.ts +53 -0
  500. package/dist/ta/backtest/abnday.js +123 -0
  501. package/dist/ta/backtest/abnday.js.map +1 -0
  502. package/dist/ta/backtest/directional.d.ts +48 -0
  503. package/dist/ta/backtest/directional.js +103 -0
  504. package/dist/ta/backtest/directional.js.map +1 -0
  505. package/dist/ta/backtest/fundx.d.ts +67 -0
  506. package/dist/ta/backtest/fundx.js +264 -0
  507. package/dist/ta/backtest/fundx.js.map +1 -0
  508. package/dist/ta/backtest/fvg.d.ts +62 -0
  509. package/dist/ta/backtest/fvg.js +236 -0
  510. package/dist/ta/backtest/fvg.js.map +1 -0
  511. package/dist/ta/backtest/ichimoku.d.ts +41 -0
  512. package/dist/ta/backtest/ichimoku.js +146 -0
  513. package/dist/ta/backtest/ichimoku.js.map +1 -0
  514. package/dist/ta/backtest/ingest.d.ts +20 -0
  515. package/dist/ta/backtest/ingest.js +104 -0
  516. package/dist/ta/backtest/ingest.js.map +1 -0
  517. package/dist/ta/backtest/msb.d.ts +49 -0
  518. package/dist/ta/backtest/msb.js +162 -0
  519. package/dist/ta/backtest/msb.js.map +1 -0
  520. package/dist/ta/backtest/scoring.d.ts +33 -0
  521. package/dist/ta/backtest/scoring.js +82 -0
  522. package/dist/ta/backtest/scoring.js.map +1 -0
  523. package/dist/ta/backtest/summary.d.ts +20 -0
  524. package/dist/ta/backtest/summary.js +42 -0
  525. package/dist/ta/backtest/summary.js.map +1 -0
  526. package/dist/ta/backtest/tsmom.d.ts +72 -0
  527. package/dist/ta/backtest/tsmom.js +202 -0
  528. package/dist/ta/backtest/tsmom.js.map +1 -0
  529. package/dist/ta/backtest/volsq.d.ts +34 -0
  530. package/dist/ta/backtest/volsq.js +154 -0
  531. package/dist/ta/backtest/volsq.js.map +1 -0
  532. package/dist/ta/backtest/walkForward.d.ts +45 -0
  533. package/dist/ta/backtest/walkForward.js +136 -0
  534. package/dist/ta/backtest/walkForward.js.map +1 -0
  535. package/dist/ta/cycles.d.ts +15 -0
  536. package/dist/ta/cycles.js +31 -0
  537. package/dist/ta/cycles.js.map +1 -0
  538. package/dist/ta/desk/accrualEmitter.d.ts +59 -0
  539. package/dist/ta/desk/accrualEmitter.js +136 -0
  540. package/dist/ta/desk/accrualEmitter.js.map +1 -0
  541. package/dist/ta/desk/cellBacktest.d.ts +179 -0
  542. package/dist/ta/desk/cellBacktest.js +514 -0
  543. package/dist/ta/desk/cellBacktest.js.map +1 -0
  544. package/dist/ta/desk/cells/wpMaRejection.d.ts +49 -0
  545. package/dist/ta/desk/cells/wpMaRejection.js +141 -0
  546. package/dist/ta/desk/cells/wpMaRejection.js.map +1 -0
  547. package/dist/ta/desk/cells/wpVolumeClimax.d.ts +57 -0
  548. package/dist/ta/desk/cells/wpVolumeClimax.js +193 -0
  549. package/dist/ta/desk/cells/wpVolumeClimax.js.map +1 -0
  550. package/dist/ta/desk/collectors.d.ts +18 -0
  551. package/dist/ta/desk/collectors.js +450 -0
  552. package/dist/ta/desk/collectors.js.map +1 -0
  553. package/dist/ta/desk/contract.d.ts +51 -0
  554. package/dist/ta/desk/contract.js +261 -0
  555. package/dist/ta/desk/contract.js.map +1 -0
  556. package/dist/ta/desk/deskLedger.d.ts +36 -0
  557. package/dist/ta/desk/deskLedger.js +239 -0
  558. package/dist/ta/desk/deskLedger.js.map +1 -0
  559. package/dist/ta/desk/liqTape.d.ts +37 -0
  560. package/dist/ta/desk/liqTape.js +99 -0
  561. package/dist/ta/desk/liqTape.js.map +1 -0
  562. package/dist/ta/desk/post.d.ts +20 -0
  563. package/dist/ta/desk/post.js +65 -0
  564. package/dist/ta/desk/post.js.map +1 -0
  565. package/dist/ta/desk/render.d.ts +25 -0
  566. package/dist/ta/desk/render.js +398 -0
  567. package/dist/ta/desk/render.js.map +1 -0
  568. package/dist/ta/desk/surfaces.d.ts +216 -0
  569. package/dist/ta/desk/surfaces.js +472 -0
  570. package/dist/ta/desk/surfaces.js.map +1 -0
  571. package/dist/ta/desk/types.d.ts +174 -0
  572. package/dist/ta/desk/types.js +104 -0
  573. package/dist/ta/desk/types.js.map +1 -0
  574. package/dist/ta/index.d.ts +23 -0
  575. package/dist/ta/index.js +54 -0
  576. package/dist/ta/index.js.map +1 -0
  577. package/dist/ta/ledger.d.ts +44 -0
  578. package/dist/ta/ledger.js +95 -0
  579. package/dist/ta/ledger.js.map +1 -0
  580. package/dist/ta/levels.d.ts +21 -0
  581. package/dist/ta/levels.js +41 -0
  582. package/dist/ta/levels.js.map +1 -0
  583. package/dist/ta/swings.d.ts +30 -0
  584. package/dist/ta/swings.js +83 -0
  585. package/dist/ta/swings.js.map +1 -0
  586. package/dist/ta/types.d.ts +81 -0
  587. package/dist/ta/types.js +20 -0
  588. package/dist/ta/types.js.map +1 -0
  589. package/dist/telemetry.js +20 -9
  590. package/dist/telemetry.js.map +1 -1
  591. package/dist/tokenUsageTracker.d.ts +2 -1
  592. package/dist/tokenUsageTracker.js +38 -20
  593. package/dist/tokenUsageTracker.js.map +1 -1
  594. package/dist/tools/contextBundle.js +13 -9
  595. package/dist/tools/contextBundle.js.map +1 -1
  596. package/dist/tools/ctxGetTaskContext.js +8 -3
  597. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  598. package/dist/tools/ctxQueryTraces.d.ts +18 -1
  599. package/dist/tools/ctxQueryTraces.js +176 -27
  600. package/dist/tools/ctxQueryTraces.js.map +1 -1
  601. package/dist/tools/enrichCommit.js +5 -2
  602. package/dist/tools/enrichCommit.js.map +1 -1
  603. package/dist/tools/getDependencyTree.js +2 -2
  604. package/dist/tools/getDependencyTree.js.map +1 -1
  605. package/dist/tools/getDiagnostics.js +3 -0
  606. package/dist/tools/getDiagnostics.js.map +1 -1
  607. package/dist/tools/getDocumentSymbols.js +5 -1
  608. package/dist/tools/getDocumentSymbols.js.map +1 -1
  609. package/dist/tools/getGitHotspots.js +12 -1
  610. package/dist/tools/getGitHotspots.js.map +1 -1
  611. package/dist/tools/getGitLog.js +5 -2
  612. package/dist/tools/getGitLog.js.map +1 -1
  613. package/dist/tools/getGitStatus.js +6 -1
  614. package/dist/tools/getGitStatus.js.map +1 -1
  615. package/dist/tools/getProjectContext.js +3 -1
  616. package/dist/tools/getProjectContext.js.map +1 -1
  617. package/dist/tools/getToolCapabilities.js +39 -4
  618. package/dist/tools/getToolCapabilities.js.map +1 -1
  619. package/dist/tools/gitWrite.js +12 -3
  620. package/dist/tools/gitWrite.js.map +1 -1
  621. package/dist/tools/github/composite.d.ts +1 -1
  622. package/dist/tools/github/composite.js +7 -7
  623. package/dist/tools/github/composite.js.map +1 -1
  624. package/dist/tools/github/pr.d.ts +6 -6
  625. package/dist/tools/github/pr.js +18 -11
  626. package/dist/tools/github/pr.js.map +1 -1
  627. package/dist/tools/httpClient.js +55 -3
  628. package/dist/tools/httpClient.js.map +1 -1
  629. package/dist/tools/index.d.ts +2 -1
  630. package/dist/tools/index.js +19 -12
  631. package/dist/tools/index.js.map +1 -1
  632. package/dist/tools/lsp.d.ts +6 -0
  633. package/dist/tools/lsp.js +81 -12
  634. package/dist/tools/lsp.js.map +1 -1
  635. package/dist/tools/previewEdit.js +16 -1
  636. package/dist/tools/previewEdit.js.map +1 -1
  637. package/dist/tools/resumeClaudeTask.js +17 -0
  638. package/dist/tools/resumeClaudeTask.js.map +1 -1
  639. package/dist/tools/searchAndReplace.js +9 -5
  640. package/dist/tools/searchAndReplace.js.map +1 -1
  641. package/dist/tools/searchTools.d.ts +26 -0
  642. package/dist/tools/searchTools.js +42 -2
  643. package/dist/tools/searchTools.js.map +1 -1
  644. package/dist/tools/terminal.js +23 -51
  645. package/dist/tools/terminal.js.map +1 -1
  646. package/dist/tools/transaction.d.ts +9 -1
  647. package/dist/tools/transaction.js +59 -4
  648. package/dist/tools/transaction.js.map +1 -1
  649. package/dist/tools/utils.d.ts +16 -0
  650. package/dist/tools/utils.js +77 -7
  651. package/dist/tools/utils.js.map +1 -1
  652. package/dist/transport.d.ts +31 -0
  653. package/dist/transport.js +117 -14
  654. package/dist/transport.js.map +1 -1
  655. package/dist/wireHaltPushDispatch.js +12 -0
  656. package/dist/wireHaltPushDispatch.js.map +1 -1
  657. package/dist/workerGateDecisionLog.d.ts +141 -0
  658. package/dist/workerGateDecisionLog.js +361 -0
  659. package/dist/workerGateDecisionLog.js.map +1 -0
  660. package/dist/workers/actionClass.d.ts +38 -0
  661. package/dist/workers/actionClass.js +155 -0
  662. package/dist/workers/actionClass.js.map +1 -0
  663. package/dist/workers/backtest.d.ts +68 -0
  664. package/dist/workers/backtest.js +113 -0
  665. package/dist/workers/backtest.js.map +1 -0
  666. package/dist/workers/contextRisk.d.ts +35 -0
  667. package/dist/workers/contextRisk.js +20 -0
  668. package/dist/workers/contextRisk.js.map +1 -0
  669. package/dist/workers/contextRiskScorer.d.ts +48 -0
  670. package/dist/workers/contextRiskScorer.js +94 -0
  671. package/dist/workers/contextRiskScorer.js.map +1 -0
  672. package/dist/workers/graduation.d.ts +61 -0
  673. package/dist/workers/graduation.js +112 -0
  674. package/dist/workers/graduation.js.map +1 -0
  675. package/dist/workers/outcomeStore.d.ts +98 -0
  676. package/dist/workers/outcomeStore.js +146 -0
  677. package/dist/workers/outcomeStore.js.map +1 -0
  678. package/dist/workers/outcomesCli.d.ts +34 -0
  679. package/dist/workers/outcomesCli.js +91 -0
  680. package/dist/workers/outcomesCli.js.map +1 -0
  681. package/dist/workers/runWorkerShadow.d.ts +90 -0
  682. package/dist/workers/runWorkerShadow.js +323 -0
  683. package/dist/workers/runWorkerShadow.js.map +1 -0
  684. package/dist/workers/shadowGate.d.ts +30 -0
  685. package/dist/workers/shadowGate.js +58 -0
  686. package/dist/workers/shadowGate.js.map +1 -0
  687. package/dist/workers/shadowObserver.d.ts +165 -0
  688. package/dist/workers/shadowObserver.js +203 -0
  689. package/dist/workers/shadowObserver.js.map +1 -0
  690. package/dist/workers/shadowReport.d.ts +16 -0
  691. package/dist/workers/shadowReport.js +61 -0
  692. package/dist/workers/shadowReport.js.map +1 -0
  693. package/dist/workers/shadowRun.d.ts +38 -0
  694. package/dist/workers/shadowRun.js +44 -0
  695. package/dist/workers/shadowRun.js.map +1 -0
  696. package/dist/workers/trustLevel.d.ts +82 -0
  697. package/dist/workers/trustLevel.js +100 -0
  698. package/dist/workers/trustLevel.js.map +1 -0
  699. package/dist/workers/worker.d.ts +49 -0
  700. package/dist/workers/worker.js +88 -0
  701. package/dist/workers/worker.js.map +1 -0
  702. package/dist/workers/workerGate.d.ts +101 -0
  703. package/dist/workers/workerGate.js +210 -0
  704. package/dist/workers/workerGate.js.map +1 -0
  705. package/dist/workers/workerLevelStore.d.ts +33 -0
  706. package/dist/workers/workerLevelStore.js +87 -0
  707. package/dist/workers/workerLevelStore.js.map +1 -0
  708. package/dist/workers/workerLoader.d.ts +7 -0
  709. package/dist/workers/workerLoader.js +31 -0
  710. package/dist/workers/workerLoader.js.map +1 -0
  711. package/dist/writeFileAtomic.js +40 -13
  712. package/dist/writeFileAtomic.js.map +1 -1
  713. package/package.json +14 -6
  714. package/scripts/mcp-stdio-shim.cjs +247 -87
  715. package/templates/CLAUDE.bridge.md +1 -1
  716. package/templates/recipes/dependency-bump.yaml +33 -0
  717. package/templates/recipes/incident-to-pr.yaml +187 -0
  718. package/templates/recipes/outcome-ingester.yaml +53 -0
  719. package/templates/recipes/release-notes.yaml +30 -0
  720. package/templates/recipes/triage-failing-tests-autofile.yaml +152 -0
  721. package/templates/recipes/triage-failing-tests.yaml +38 -0
  722. package/templates/workers/dependency-upkeep.worker.yaml +26 -0
  723. package/templates/workers/release-notes.worker.yaml +17 -0
  724. package/templates/workers/test-guardian.worker.yaml +24 -0
  725. package/deploy/README.md +0 -172
  726. package/deploy/bootstrap-new-vps.sh +0 -364
  727. package/deploy/bootstrap-vps.sh +0 -192
  728. package/deploy/claude-ide-bridge.service.template +0 -67
  729. package/deploy/claude-ide-bridge@.service +0 -31
  730. package/deploy/deploy-dashboard.sh +0 -198
  731. package/deploy/deploy-landing.sh +0 -136
  732. package/deploy/ecosystem.config.js.example +0 -36
  733. package/deploy/install-vps-service.sh +0 -240
  734. package/deploy/macos/README.md +0 -153
  735. package/deploy/macos/com.patchwork.bridge.plist.template +0 -54
  736. package/deploy/macos/com.patchwork.tunnel.plist.template +0 -76
  737. package/deploy/macos/install-mac-bridge.sh +0 -244
  738. package/deploy/macos/uninstall-mac-bridge.sh +0 -22
  739. package/deploy/nginx-claude-bridge.conf.template +0 -129
package/dist/server.js CHANGED
@@ -7,6 +7,7 @@ import { clearAnalyticsConfig, getAnalyticsConfig } from "./analyticsConfig.js";
7
7
  import { getAnalyticsPrefsAll, getAnalyticsPrefsPath, getAnalyticsSaltPath, getTelemetryPrefs, setTelemetryPrefs, } from "./analyticsPrefs.js";
8
8
  import { handleApprovalsStream, routeApprovalRequest } from "./approvalHttp.js";
9
9
  import { getApprovalQueue } from "./approvalQueue.js";
10
+ import { handleClaudeAuthCancel, handleClaudeAuthComplete, handleClaudeAuthStart, } from "./claudeAuthHttp.js";
10
11
  import { saveBridgeConfigDriver } from "./config.js";
11
12
  import { tryHandleConnectorRoute, tryHandlePublicConnectorRoute, } from "./connectorRoutes.js";
12
13
  import { timingSafeStringEqual } from "./crypto.js";
@@ -37,6 +38,32 @@ export { corsOrigin };
37
38
  // Re-export canonical constant-time comparison for use in this module.
38
39
  // Implementation lives in src/crypto.ts — see there for security notes.
39
40
  const timingSafeTokenCompare = timingSafeStringEqual;
41
+ /**
42
+ * H6 (audit 2026-06-19): the webhook auth gate must treat the
43
+ * `X-Hub-Signature-256` header identically at the bearer-bypass decision
44
+ * and at the HMAC verification step. A multi-valued header (duplicate
45
+ * lines collapsed to a `string[]` by an upstream proxy / HTTP-2 layer, or
46
+ * Node's comma-join) is NOT a usable single signature and must be rejected,
47
+ * never silently skipped. This returns the lone string only when exactly
48
+ * one usable value is present; otherwise `null`.
49
+ *
50
+ * - `undefined` → null (absent)
51
+ * - single string → that string
52
+ * - comma-joined string (Node merge of duplicates) → null (multi-valued)
53
+ * - `string[]` → null (multi-valued)
54
+ */
55
+ export function readSingleSignatureHeader(value) {
56
+ if (Array.isArray(value))
57
+ return null;
58
+ if (typeof value !== "string")
59
+ return null;
60
+ // Node merges duplicate non-special headers with ", ". A genuine GitHub
61
+ // signature is a single `sha256=<hex>` token and never contains a comma,
62
+ // so any comma marks a multi-valued (spoofed) header.
63
+ if (value.includes(","))
64
+ return null;
65
+ return value;
66
+ }
40
67
  function setupPongHandler(ws) {
41
68
  ws.on("pong", (_data) => {
42
69
  ws.isAlive = true;
@@ -141,6 +168,30 @@ export class Server extends EventEmitter {
141
168
  judgeSummaryFn = null;
142
169
  /** Patchwork: set by bridge to generate a dry-run plan for a recipe by name. */
143
170
  runPlanFn = null;
171
+ /** Patchwork: set by bridge to generate a What-If Preview simulation for a
172
+ * recipe by name (static counterfactual; superset of the dry-run plan). */
173
+ simulateFn = null;
174
+ /** Patchwork: read-only worker trust dial (shadow) — replays run + decision
175
+ * logs through the (worker × action-class) ramp. Backs GET /workers/shadow. */
176
+ workerShadowFn = null;
177
+ /** Patchwork: read-only query over the persisted Decision Record
178
+ * (worker_gate_decisions.jsonl). Backs GET /gate/decisions and the
179
+ * `patchwork gate explain` CLI command — "why did the worker
180
+ * allow/gate THIS action" without grepping the JSONL by hand. */
181
+ gateDecisionsFn = null;
182
+ /** Patchwork: record a Decision Record trace over HTTP. Backs
183
+ * POST /traces/decision — the HTTP twin of the `ctxSaveTrace` MCP tool,
184
+ * wired directly to `DecisionTraceLog.record()` so both paths persist
185
+ * through the same JSONL writer. Throws on invalid input (caller maps
186
+ * to 400); null when no bridge-side DecisionTraceLog is configured. */
187
+ saveDecisionTraceFn = null;
188
+ /** Patchwork: operator outcome dispositions (~/.patchwork/outcome-log.jsonl).
189
+ * Backs GET/POST /outcomes and the dashboard confirm/reject panel; mirrors
190
+ * the `patchwork outcomes` CLI. Never exposed as a recipe step / MCP tool. */
191
+ outcomeStoreFn = null;
192
+ /** Patchwork: the confirm queue — worker filings awaiting an operator
193
+ * disposition. Backs GET /outcomes/pending + `patchwork outcomes pending`. */
194
+ pendingConfirmationsFn = null;
144
195
  /** Patchwork (VD-4): mocked replay of an existing run. Returns the new
145
196
  * run's seq plus any unmocked steps the caller may want to surface. */
146
197
  runReplayFn = null;
@@ -286,6 +337,14 @@ export class Server extends EventEmitter {
286
337
  tracesFn = null;
287
338
  /** Set by bridge to handle CC hook notify events via POST /notify */
288
339
  notifyFn = null;
340
+ /**
341
+ * Patchwork: the configured workspace root (set by bridge from --workspace).
342
+ * Routes that resolve workspace-relative state — decision-replay and CC
343
+ * permission attribution, approval routing — must use this, NOT process.cwd():
344
+ * the bridge can be started with --workspace pointing elsewhere, and a
345
+ * launchd/systemd cwd is unrelated to the workspace (audit 2026-06-08 server-3).
346
+ */
347
+ workspace = process.cwd();
289
348
  /** Patchwork: set by bridge to list active agent sessions for the dashboard. */
290
349
  sessionsFn = null;
291
350
  /** Patchwork: set by bridge to answer GET /sessions/:id with per-session event stream + approvals. */
@@ -507,18 +566,26 @@ export class Server extends EventEmitter {
507
566
  const oauthResolved = !isStaticToken && this.oauthServer
508
567
  ? this.oauthServer.resolveBearerToken(bearer)
509
568
  : null;
510
- // Phone-path: approve/reject with x-approval-token header or ?token= query param bypass bearer check.
511
- // The token itself is validated inside routeApprovalRequest via queue.validateToken.
569
+ // Phone-path: approve/reject bypass the bearer check when they carry
570
+ // either the x-approval-token header (legacy ntfy/push) or the HMAC
571
+ // ?sig= query param (M23 signed callback). Both credentials are
572
+ // validated inside routeApprovalRequest. L43: the legacy ?token= query
573
+ // param is no longer accepted here — tokens in URLs leak into access
574
+ // logs, proxy logs, and Referer headers; use the header instead.
512
575
  const isPhoneApprovalPath = req.method === "POST" &&
513
576
  /^\/(approve|reject)\/[A-Za-z0-9-]+$/.test(parsedUrl.pathname) &&
514
- !!(req.headers["x-approval-token"] || parsedUrl.searchParams.get("token"));
577
+ !!(req.headers["x-approval-token"] || parsedUrl.searchParams.get("sig"));
515
578
  // GitHub-style webhook bypass: when --webhook-secret is configured,
516
579
  // POST /hooks/* requests carrying X-Hub-Signature-256 bypass the
517
580
  // bearer-token gate. Signature itself is verified inside the
518
581
  // /hooks/* handler after the body has been read.
582
+ // H6: only a single usable signature value counts as a webhook bypass
583
+ // candidate. A multi-valued header is rejected here (falls through to
584
+ // the bearer requirement — fail closed) and again at the HMAC step.
519
585
  const isHmacWebhookCandidate = req.method === "POST" &&
520
586
  parsedUrl.pathname.startsWith("/hooks/") &&
521
- !!req.headers["x-hub-signature-256"] &&
587
+ readSingleSignatureHeader(req.headers["x-hub-signature-256"]) !==
588
+ null &&
522
589
  this.webhookSecret !== null;
523
590
  // Rate-limit the phone bypass surface. Only applies when this is
524
591
  // actually a phone-path request that's relying on the bypass — a
@@ -541,8 +608,12 @@ export class Server extends EventEmitter {
541
608
  const now = Date.now();
542
609
  const entry = this.approvalIpCounts.get(remoteIp);
543
610
  if (entry && now - entry.windowStart < Server.APPROVAL_IP_WINDOW_MS) {
544
- entry.count++;
545
- if (entry.count > Server.APPROVAL_IP_MAX) {
611
+ // Check BEFORE incrementing so the counter is only advanced for
612
+ // requests that are allowed through. Increment-first then check
613
+ // lets exactly one extra request slip past the limit (the rejected
614
+ // request still bumps the counter, making the effective window
615
+ // allow MAX+1 unique IDs in degenerate edge cases).
616
+ if (entry.count >= Server.APPROVAL_IP_MAX) {
546
617
  res.writeHead(429, { "Content-Type": "application/json" });
547
618
  res.end(JSON.stringify({
548
619
  error: "too_many_requests",
@@ -550,18 +621,21 @@ export class Server extends EventEmitter {
550
621
  }));
551
622
  return;
552
623
  }
624
+ entry.count++;
553
625
  }
554
626
  else {
555
627
  this.approvalIpCounts.set(remoteIp, { count: 1, windowStart: now });
556
628
  }
557
- // GC stale entries opportunistically — bounded growth alongside
558
- // the same Map. 200 is well above any legitimate concurrent IP
559
- // count; well below memory pressure.
560
- if (this.approvalIpCounts.size > 200) {
561
- for (const [k, v] of this.approvalIpCounts) {
562
- if (now - v.windowStart > Server.APPROVAL_IP_WINDOW_MS) {
563
- this.approvalIpCounts.delete(k);
564
- }
629
+ // http-server-2: prune stale entries on EVERY phone-path request,
630
+ // not only once the map crosses 200. The old `size > 200` guard meant
631
+ // any deployment with fewer than 200 distinct IPs never evicted
632
+ // expired entries — a one-shot IP's 40-byte record survived for the
633
+ // whole process lifetime. Each window is short (APPROVAL_IP_WINDOW_MS)
634
+ // and the map is tiny in practice, so a full pass per request is
635
+ // cheap and keeps the map genuinely bounded.
636
+ for (const [k, v] of this.approvalIpCounts) {
637
+ if (now - v.windowStart > Server.APPROVAL_IP_WINDOW_MS) {
638
+ this.approvalIpCounts.delete(k);
565
639
  }
566
640
  }
567
641
  }
@@ -631,6 +705,28 @@ export class Server extends EventEmitter {
631
705
  const q = parsedUrl.searchParams;
632
706
  const sinceStr = q.get("since");
633
707
  const limitStr = q.get("limit");
708
+ // Validate numeric ranges up front so an out-of-range value returns a
709
+ // 400 with an actionable message instead of bubbling an exception
710
+ // from ctxQueryTraces' optionalInt() into a generic 500 (audit sem-1).
711
+ if (limitStr !== null && /^\d+$/.test(limitStr)) {
712
+ const limitNum = Number(limitStr);
713
+ if (limitNum < 1 || limitNum > 500) {
714
+ res.writeHead(400, { "Content-Type": "application/json" });
715
+ res.end(JSON.stringify({
716
+ error: "limit must be an integer between 1 and 500",
717
+ }));
718
+ return;
719
+ }
720
+ }
721
+ if (sinceStr !== null && /^\d+$/.test(sinceStr)) {
722
+ if (!Number.isSafeInteger(Number(sinceStr))) {
723
+ res.writeHead(400, { "Content-Type": "application/json" });
724
+ res.end(JSON.stringify({
725
+ error: "since must be a safe integer (epoch ms)",
726
+ }));
727
+ return;
728
+ }
729
+ }
634
730
  const data = this.tracesFn
635
731
  ? await this.tracesFn({
636
732
  traceType: q.get("traceType") ?? undefined,
@@ -643,6 +739,11 @@ export class Server extends EventEmitter {
643
739
  limit: limitStr !== null && /^\d+$/.test(limitStr)
644
740
  ? Number(limitStr)
645
741
  : undefined,
742
+ // Opt-in meaning-based ranking (?semantic=true). The bridge's
743
+ // tracesFn forwards it to ctxQueryTraces, which only ranks by
744
+ // cosine when an embeddings endpoint is configured — otherwise
745
+ // it falls back to the substring path. Safe default: false.
746
+ semantic: q.get("semantic") === "true",
646
747
  })
647
748
  : {
648
749
  traces: [],
@@ -920,7 +1021,16 @@ export class Server extends EventEmitter {
920
1021
  // computed over the raw on-the-wire bytes (read.bytes), not the
921
1022
  // utf-8-decoded string — non-UTF-8 or denormalized payloads must
922
1023
  // round-trip identically to validate.
923
- const sigHeader = req.headers["x-hub-signature-256"];
1024
+ // H6: reject multi-valued signature headers outright. The raw header
1025
+ // is present-but-unusable → 401, never a silent skip of HMAC.
1026
+ const rawSig = req.headers["x-hub-signature-256"];
1027
+ if (rawSig !== undefined &&
1028
+ readSingleSignatureHeader(rawSig) === null) {
1029
+ res.writeHead(401, { "Content-Type": "application/json" });
1030
+ res.end(JSON.stringify({ error: "invalid_signature" }));
1031
+ return;
1032
+ }
1033
+ const sigHeader = readSingleSignatureHeader(rawSig);
924
1034
  if (typeof sigHeader === "string" && sigHeader.length > 0) {
925
1035
  if (!this.webhookSecret) {
926
1036
  res.writeHead(401, { "Content-Type": "application/json" });
@@ -1076,7 +1186,7 @@ export class Server extends EventEmitter {
1076
1186
  : 0;
1077
1187
  const { computeDecisionReplay } = await import("./decisionReplay.js");
1078
1188
  const result = computeDecisionReplay(this.activityLog, {
1079
- workspace: process.cwd(),
1189
+ workspace: this.workspace,
1080
1190
  sinceMs,
1081
1191
  });
1082
1192
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -1102,7 +1212,7 @@ export class Server extends EventEmitter {
1102
1212
  now - this._explainRulesCache.at > 30_000) {
1103
1213
  this._explainRulesCache = {
1104
1214
  at: now,
1105
- rules: loadCcPermissionsAttributed(process.cwd()),
1215
+ rules: loadCcPermissionsAttributed(this.workspace),
1106
1216
  };
1107
1217
  }
1108
1218
  const explanation = explainRules(tool, specifier || undefined, this._explainRulesCache.rules);
@@ -1163,6 +1273,12 @@ export class Server extends EventEmitter {
1163
1273
  haltSummaryFn: this.haltSummaryFn,
1164
1274
  judgeSummaryFn: this.judgeSummaryFn,
1165
1275
  runPlanFn: this.runPlanFn,
1276
+ simulateFn: this.simulateFn,
1277
+ workerShadowFn: this.workerShadowFn,
1278
+ gateDecisionsFn: this.gateDecisionsFn,
1279
+ saveDecisionTraceFn: this.saveDecisionTraceFn,
1280
+ outcomeStoreFn: this.outcomeStoreFn,
1281
+ pendingConfirmationsFn: this.pendingConfirmationsFn,
1166
1282
  runReplayFn: this.runReplayFn,
1167
1283
  runRecipeFn: this.runRecipeFn,
1168
1284
  onRecipesChangedFn: this.onRecipesChangedFn,
@@ -1203,6 +1319,27 @@ export class Server extends EventEmitter {
1203
1319
  }
1204
1320
  return;
1205
1321
  }
1322
+ // /auth/claude/* — Claude Code subscription OAuth 2.0 + PKCE flow.
1323
+ // start → returns a claude.ai auth URL; complete → exchanges code for token;
1324
+ // cancel → discards the pending session. The dashboard "Connect Claude"
1325
+ // button drives this flow; after complete the dashboard saves the returned
1326
+ // token via POST /api/auth/anthropic-key → control-plane re-provisions
1327
+ // the container with CLAUDE_CODE_OAUTH_TOKEN so subprocess driver works.
1328
+ if (parsedUrl.pathname === "/auth/claude/start" &&
1329
+ req.method === "POST") {
1330
+ await handleClaudeAuthStart(req, res);
1331
+ return;
1332
+ }
1333
+ if (parsedUrl.pathname === "/auth/claude/complete" &&
1334
+ req.method === "POST") {
1335
+ await handleClaudeAuthComplete(req, res);
1336
+ return;
1337
+ }
1338
+ if (parsedUrl.pathname === "/auth/claude/cancel" &&
1339
+ req.method === "POST") {
1340
+ await handleClaudeAuthCancel(req, res);
1341
+ return;
1342
+ }
1206
1343
  if (parsedUrl.pathname === "/settings" && req.method === "POST") {
1207
1344
  // Kill-switch gate: during an incident a settings mutation can
1208
1345
  // defeat the panic posture (e.g. switching driver to one with a
@@ -1604,11 +1741,10 @@ export class Server extends EventEmitter {
1604
1741
  changes.ntfyTopic = ntfyTopicTrimmed ? "***" : "";
1605
1742
  if (ntfyServerTrimmed !== undefined)
1606
1743
  changes.ntfyServer = ntfyServerTrimmed || "";
1607
- const remoteAddr = req.headers["x-forwarded-for"]
1608
- ?.split(",")[0]
1609
- ?.trim() ||
1610
- req.socket.remoteAddress ||
1611
- "unknown";
1744
+ // L44: honor X-Forwarded-For only from trusted proxies. Routed
1745
+ // through getClientIp so an untrusted client cannot spoof the
1746
+ // audited actor IP.
1747
+ const remoteAddr = this.getClientIp(req) ?? "unknown";
1612
1748
  this.activityLog.recordEvent("settings.change", {
1613
1749
  actor: "http",
1614
1750
  ip: remoteAddr,
@@ -1902,11 +2038,8 @@ export class Server extends EventEmitter {
1902
2038
  if (this.activityLog) {
1903
2039
  this.activityLog.recordEvent("telemetry.reset", {
1904
2040
  actor: "http",
1905
- ip: req.headers["x-forwarded-for"]
1906
- ?.split(",")[0]
1907
- ?.trim() ||
1908
- req.socket.remoteAddress ||
1909
- "unknown",
2041
+ // L44: trusted-proxy-gated client IP (see getClientIp).
2042
+ ip: this.getClientIp(req) ?? "unknown",
1910
2043
  });
1911
2044
  }
1912
2045
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -2146,12 +2279,15 @@ export class Server extends EventEmitter {
2146
2279
  path: parsedUrl.pathname,
2147
2280
  body: parsedBody,
2148
2281
  query: parsedUrl.searchParams,
2282
+ // L43: read the approval token from the header ONLY. A token in
2283
+ // ?token= leaks into HTTP access logs, proxy logs, and Referer
2284
+ // headers. (The separately-signed `sig` query param — see
2285
+ // approvalHttp.ts — is an HMAC over the path and is unaffected.)
2149
2286
  approvalToken: req.headers["x-approval-token"] ??
2150
- parsedUrl.searchParams.get("token") ??
2151
2287
  undefined,
2152
2288
  }, {
2153
2289
  queue: getApprovalQueue(),
2154
- workspace: process.cwd(),
2290
+ workspace: this.workspace,
2155
2291
  managedSettingsPath: this.managedSettingsPath,
2156
2292
  onDecision: this.onApprovalDecision,
2157
2293
  webhookUrl: this.approvalWebhookUrl,
@@ -2458,7 +2594,7 @@ export class Server extends EventEmitter {
2458
2594
  // Enforce a minimum interval so a misconfigured value cannot spin
2459
2595
  // the event loop (setInterval(fn, 0) would fire on every tick).
2460
2596
  // 10 ms floor is low enough for tests, high enough to be safe.
2461
- }, Math.max(10, this.pingIntervalMs));
2597
+ }, Math.max(10, this.pingIntervalMs)).unref();
2462
2598
  resolve(addr.port);
2463
2599
  })
2464
2600
  .on("error", reject);
@@ -2471,7 +2607,27 @@ export class Server extends EventEmitter {
2471
2607
  // Fall through to OS-assigned port below
2472
2608
  }
2473
2609
  else {
2474
- return this.listen(preferredPort, bindAddress);
2610
+ // On Windows, SO_REUSEADDR does not release ports in TIME_WAIT (~4 min).
2611
+ // A supervisor restart with --port N crash-loops until the port clears.
2612
+ // Retry with exponential backoff (1s, 2s, 4s, 8s) before falling back
2613
+ // to an OS-assigned port, so a single restart attempt survives the
2614
+ // typical TIME_WAIT window without wedging the supervisor. (NET-001)
2615
+ const backoffs = [1000, 2000, 4000, 8000];
2616
+ for (let i = 0; i <= backoffs.length; i++) {
2617
+ try {
2618
+ return await this.listen(preferredPort, bindAddress);
2619
+ }
2620
+ catch (err) {
2621
+ if (err.code !== "EADDRINUSE")
2622
+ throw err;
2623
+ if (i === backoffs.length)
2624
+ break;
2625
+ this.logger.warn(`Port ${preferredPort} in use (attempt ${i + 1}/${backoffs.length}), ` +
2626
+ `retrying in ${backoffs[i]}ms…`);
2627
+ await new Promise((r) => setTimeout(r, backoffs[i]));
2628
+ }
2629
+ }
2630
+ this.logger.warn(`Port ${preferredPort} still in use after retries, falling back to OS-assigned port`);
2475
2631
  }
2476
2632
  }
2477
2633
  // Port 0 lets the OS kernel assign a free port atomically
@@ -2480,6 +2636,11 @@ export class Server extends EventEmitter {
2480
2636
  async close() {
2481
2637
  if (this.pingInterval)
2482
2638
  clearInterval(this.pingInterval);
2639
+ // close() may run before listen() (failed startup, or tests that stub
2640
+ // listen()); wss/httpServer are only created in listen(), so a pre-listen
2641
+ // close is a safe no-op rather than a crash on undefined this.wss.
2642
+ if (!this.wss)
2643
+ return;
2483
2644
  for (const client of this.wss.clients) {
2484
2645
  client.close(1001, "Server shutting down");
2485
2646
  }