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
@@ -49,21 +49,48 @@ export function writeFileAtomicSync(target, data, opts = {}) {
49
49
  else {
50
50
  fs.writeFileSync(tmp, data, { mode });
51
51
  }
52
- try {
53
- fs.renameSync(tmp, target);
54
- }
55
- catch (renameErr) {
56
- // On Windows, renameSync throws EEXIST when the target already exists
57
- // (unlike POSIX which atomically replaces). Unlink the target and retry.
58
- if (process.platform === "win32" &&
59
- renameErr.code === "EEXIST") {
60
- fs.unlinkSync(target);
52
+ // Attempt the rename up to 4 times (immediate + 3 retries at ~50 ms).
53
+ // On Windows, Defender or an AV tool can hold a brief exclusive handle on
54
+ // the target (EPERM/EBUSY) between reads; a short backoff is enough.
55
+ // EEXIST means the target exists but no one holds it — unlink then retry.
56
+ const RETRYABLE = new Set(["EEXIST", "EPERM", "EBUSY"]);
57
+ let lastRenameErr;
58
+ for (let attempt = 0; attempt < 4; attempt++) {
59
+ try {
60
+ if (attempt > 0) {
61
+ // Atomics.wait is not allowed on the main thread (throws TypeError).
62
+ // Best-effort sleep: if it throws, skip the delay and retry immediately.
63
+ try {
64
+ const buf = new SharedArrayBuffer(4);
65
+ Atomics.wait(new Int32Array(buf), 0, 0, 50);
66
+ }
67
+ catch {
68
+ // main thread — no sleep available; retry immediately
69
+ }
70
+ }
61
71
  fs.renameSync(tmp, target);
72
+ lastRenameErr = undefined;
73
+ break;
62
74
  }
63
- else {
64
- throw renameErr;
75
+ catch (err) {
76
+ const code = err.code;
77
+ if (code === "EEXIST") {
78
+ // EEXIST: target exists — unlink it, then retry the rename.
79
+ try {
80
+ fs.unlinkSync(target);
81
+ }
82
+ catch {
83
+ /* ignore */
84
+ }
85
+ }
86
+ else if (!RETRYABLE.has(code ?? "")) {
87
+ throw err; // non-retryable error; propagate immediately
88
+ }
89
+ lastRenameErr = err;
65
90
  }
66
91
  }
92
+ if (lastRenameErr !== undefined)
93
+ throw lastRenameErr;
67
94
  }
68
95
  catch (err) {
69
96
  try {
@@ -98,8 +125,8 @@ export async function writeFileAtomic(target, data, opts = {}) {
98
125
  }
99
126
  catch (renameErr) {
100
127
  // Windows: rename throws EEXIST when target exists (unlike POSIX atomic replace).
101
- if (process.platform === "win32" &&
102
- renameErr.code === "EEXIST") {
128
+ // Guard not platform-restricted; POSIX rename never throws EEXIST in practice.
129
+ if (renameErr.code === "EEXIST") {
103
130
  await fs.promises.unlink(target);
104
131
  await fs.promises.rename(tmp, target);
105
132
  }
@@ -1 +1 @@
1
- {"version":3,"file":"writeFileAtomic.js","sourceRoot":"","sources":["../src/writeFileAtomic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"writeFileAtomic.js","sourceRoot":"","sources":["../src/writeFileAtomic.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchwork-os",
3
- "version": "0.2.0-beta.9.canary.92",
3
+ "version": "1.1.0-beta.1",
4
4
  "description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -64,6 +64,11 @@
64
64
  "dist",
65
65
  "!dist/__tests__",
66
66
  "!dist/**/__tests__",
67
+ "!dist/recipes/tools/altscan.*",
68
+ "!dist/recipes/tools/market.*",
69
+ "!dist/recipes/tools/ta.*",
70
+ "!dist/recipes/tools/taLedger.*",
71
+ "!dist/recipes/tools/watchlist.*",
67
72
  "scripts/start-all.sh",
68
73
  "scripts/start-all.mjs",
69
74
  "scripts/start-all.ps1",
@@ -79,7 +84,6 @@
79
84
  "scripts/gen-claude-desktop-config.sh",
80
85
  "scripts/smoke/run-all.mjs",
81
86
  "templates",
82
- "deploy",
83
87
  "LICENSE",
84
88
  "README.md"
85
89
  ],
@@ -97,6 +101,7 @@
97
101
  "test:smoke:dashboard": "node scripts/smoke/dashboard-walk.mjs",
98
102
  "schema:generate": "node scripts/generate-schemas.mjs",
99
103
  "schema:check": "node scripts/audit-schema-changes.mjs",
104
+ "parity:check": "node scripts/audit-parity-xfails.mjs",
100
105
  "schema:update": "node scripts/audit-schema-changes.mjs --update",
101
106
  "test:coverage": "vitest run --coverage",
102
107
  "test:watch": "vitest",
@@ -124,7 +129,7 @@
124
129
  },
125
130
  "dependencies": {
126
131
  "@opentelemetry/api": "^1.9.0",
127
- "@opentelemetry/exporter-trace-otlp-http": "^0.213.0",
132
+ "@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
128
133
  "@opentelemetry/resources": "^2.6.0",
129
134
  "@opentelemetry/sdk-trace-node": "^2.7.1",
130
135
  "@opentelemetry/semantic-conventions": "^1.40.0",
@@ -132,7 +137,7 @@
132
137
  "ipaddr.js": "^2.3.0",
133
138
  "minimatch": "^10.0.0",
134
139
  "node-cron": "^4.2.1",
135
- "undici": "^6.25.0",
140
+ "undici": "^6.27.0",
136
141
  "ws": "^8.18.0",
137
142
  "yaml": "^2.8.3"
138
143
  },
@@ -141,16 +146,19 @@
141
146
  "@types/node": "^22.0.0",
142
147
  "@types/node-cron": "^3.0.11",
143
148
  "@types/ws": "^8.5.0",
144
- "@vitest/coverage-v8": "^3.0.0",
149
+ "@vitest/coverage-v8": "^4.1.8",
145
150
  "@vscode/ripgrep": "^1.17.1",
146
151
  "fast-check": "^4.6.0",
147
152
  "husky": "^9.1.7",
148
153
  "lint-staged": "^16.4.0",
149
154
  "tsx": "^4.0.0",
150
155
  "typescript": "^5.7.0",
151
- "vitest": "^3.0.0"
156
+ "vitest": "^4.1.8"
152
157
  },
153
158
  "lint-staged": {
154
159
  "{src,vscode-extension/src,scripts,deploy}/**/*.{ts,js,mjs,cjs,json}": "biome check --no-errors-on-unmatched"
160
+ },
161
+ "overrides": {
162
+ "esbuild": "^0.28.1"
155
163
  }
156
164
  }
@@ -30,57 +30,95 @@ const { randomUUID } = require("node:crypto");
30
30
  // Resolve ws from the bridge's own node_modules (script lives in scripts/)
31
31
  const { WebSocket } = require(path.join(__dirname, "..", "node_modules", "ws"));
32
32
 
33
+ // process.kill(pid, 0) probes liveness without delivering a signal: it throws
34
+ // ESRCH when the process is gone and EPERM when it exists but isn't ours (still
35
+ // alive). A stale lock whose bridge has exited would otherwise be "selected"
36
+ // (newest mtime within its tier) and every connect would hang on a refused port
37
+ // until backoff gives up — the multi-bridge footgun. Mirrors the shared
38
+ // src/bridgeLockDiscovery.ts isLive() check.
39
+ function isAlive(pid) {
40
+ if (typeof pid !== "number" || !Number.isFinite(pid)) return true; // unknown pid → don't exclude
41
+ try {
42
+ process.kill(pid, 0);
43
+ return true;
44
+ } catch (err) {
45
+ return err.code === "EPERM";
46
+ }
47
+ }
48
+
49
+ // Remembers the last lock we logged a selection for, so the diagnostic below
50
+ // fires once at startup (and again only when the selection actually changes)
51
+ // rather than on every poll tick.
52
+ let lastSelectedLockPath = null;
53
+
54
+ // True when `cwd` is the workspace root or a descendant of it. Used (only when
55
+ // no --workspace filter is set) to prefer the bridge for the project the shim is
56
+ // actually running in, rather than whichever lock has the newest mtime. Mirrors
57
+ // cwdInWorkspace() in src/bridgeLockDiscovery.ts (unit-tested there).
58
+ function cwdInWorkspace(cwd, workspace) {
59
+ if (!workspace) return false;
60
+ const rel = path.relative(workspace, cwd);
61
+ return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));
62
+ }
63
+
33
64
  function findLockFile() {
34
65
  const lockDir = path.join(
35
66
  process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude"),
36
67
  "ide",
37
68
  );
38
- // Three-tier preference: orchestrator > bridge > any lock (each by newest mtime).
39
- // Orchestrator locks win because child bridge restarts produce newer lock files,
40
- // which would hijack the shim away from the orchestrator if we only used mtime.
41
- let orchestratorLock = null;
42
- let orchestratorMtime = 0;
43
- let bridgeLock = null;
44
- let bridgeMtime = 0;
45
- let fallbackLock = null;
46
- let fallbackMtime = 0;
69
+ const cwd = process.cwd();
70
+ // Three-tier preference: orchestrator > bridge > any lock. Within a tier, a
71
+ // lock whose workspace contains the cwd wins (so a no---workspace shim attaches
72
+ // to the project it is running in); ties break on newest mtime. Orchestrator
73
+ // locks still win across tiers because child bridge restarts produce newer
74
+ // lock files that would otherwise hijack the shim away from the orchestrator.
75
+ const orchestrator = { path: null, mtime: 0, data: null, cwdMatch: false };
76
+ const bridge = { path: null, mtime: 0, data: null, cwdMatch: false };
77
+ const fallback = { path: null, mtime: 0, data: null, cwdMatch: false };
47
78
  try {
48
79
  for (const f of fs.readdirSync(lockDir)) {
49
80
  if (!f.endsWith(".lock")) continue;
50
81
  const fullPath = path.join(lockDir, f);
51
82
  try {
52
83
  const stat = fs.statSync(fullPath);
53
- let isBridge = false;
54
- let isOrchestrator = false;
84
+ let data = null;
55
85
  try {
56
- const data = JSON.parse(fs.readFileSync(fullPath, "utf8"));
57
- isBridge = data.isBridge === true;
58
- isOrchestrator = data.orchestrator === true;
59
- // Skip locks that don't match the requested workspace
60
- if (
61
- workspaceFilter &&
62
- data.workspace &&
63
- data.workspace !== workspaceFilter
64
- )
65
- continue;
86
+ data = JSON.parse(fs.readFileSync(fullPath, "utf8"));
66
87
  } catch {
67
- // unparseable — treat as non-bridge
88
+ // unparseable — treated as a fallback lock with no metadata
68
89
  }
69
- if (isOrchestrator) {
70
- if (stat.mtimeMs > orchestratorMtime) {
71
- orchestratorMtime = stat.mtimeMs;
72
- orchestratorLock = fullPath;
73
- }
74
- } else if (isBridge) {
75
- if (stat.mtimeMs > bridgeMtime) {
76
- bridgeMtime = stat.mtimeMs;
77
- bridgeLock = fullPath;
78
- }
79
- } else {
80
- if (stat.mtimeMs > fallbackMtime) {
81
- fallbackMtime = stat.mtimeMs;
82
- fallbackLock = fullPath;
83
- }
90
+ // Skip locks whose owning bridge process has exited. Without this a
91
+ // wedged/stale lock can be picked and the connection hangs.
92
+ if (data && !isAlive(data.pid)) continue;
93
+ // When a workspace filter is set, require an EXACT workspace match — a
94
+ // lock with a missing/blank workspace field must not be picked under the
95
+ // filter (otherwise the shim can latch onto an unrelated bridge).
96
+ if (workspaceFilter && (!data || data.workspace !== workspaceFilter))
97
+ continue;
98
+ const isBridge = data ? data.isBridge === true : false;
99
+ const isOrchestrator = data ? data.orchestrator === true : false;
100
+ const tier = isOrchestrator
101
+ ? orchestrator
102
+ : isBridge
103
+ ? bridge
104
+ : fallback;
105
+ // When no --workspace filter is set, prefer a lock whose workspace
106
+ // contains the cwd over a non-matching one; otherwise fall back to
107
+ // newest mtime. (With a filter, every survivor already exact-matches,
108
+ // so cwdMatch is uniformly false and this reduces to newest-mtime.)
109
+ const cwdMatch =
110
+ !workspaceFilter &&
111
+ !!data &&
112
+ cwdInWorkspace(cwd, data.workspace || "");
113
+ const better =
114
+ tier.path === null ||
115
+ (cwdMatch && !tier.cwdMatch) ||
116
+ (cwdMatch === tier.cwdMatch && stat.mtimeMs > tier.mtime);
117
+ if (better) {
118
+ tier.mtime = stat.mtimeMs;
119
+ tier.path = fullPath;
120
+ tier.data = data;
121
+ tier.cwdMatch = cwdMatch;
84
122
  }
85
123
  } catch {
86
124
  // skip unreadable files
@@ -90,7 +128,25 @@ function findLockFile() {
90
128
  // lock dir doesn't exist
91
129
  }
92
130
  // Prefer orchestrator > bridge > fallback (each newest mtime within tier)
93
- return orchestratorLock ?? bridgeLock ?? fallbackLock;
131
+ const chosen = orchestrator.path
132
+ ? orchestrator
133
+ : bridge.path
134
+ ? bridge
135
+ : fallback.path
136
+ ? fallback
137
+ : null;
138
+ // One-line stderr diagnostic so operators can see which bridge/workspace the
139
+ // shim latched onto — silent wrong-bridge selection was a real footgun. stderr
140
+ // is not the JSON-RPC stream, so this never corrupts protocol traffic.
141
+ if (chosen && chosen.path !== lastSelectedLockPath) {
142
+ lastSelectedLockPath = chosen.path;
143
+ const wsName = chosen.data?.workspace || "(unknown workspace)";
144
+ const pid = chosen.data?.pid || "?";
145
+ process.stderr.write(
146
+ `mcp-stdio-shim: selected ${path.basename(chosen.path)} (workspace=${wsName}, pid=${pid})\n`,
147
+ );
148
+ }
149
+ return chosen ? chosen.path : null;
94
150
  }
95
151
 
96
152
  function parseLock(lockPath) {
@@ -199,11 +255,16 @@ function scheduleBackoffReconnect(errorType) {
199
255
  // Parse named flags first so they don't pollute positional port/token detection.
200
256
  const args = process.argv.slice(2);
201
257
  let workspaceFilter = null;
258
+ let pingMode = false;
202
259
  for (let i = 0; i < args.length; i++) {
203
- if (args[i] === "--workspace" && args[i + 1]) {
260
+ if (args[i] === "--ping" || args[i] === "--probe") {
261
+ pingMode = true;
262
+ args.splice(i, 1);
263
+ i--;
264
+ } else if (args[i] === "--workspace" && args[i + 1] !== undefined) {
204
265
  workspaceFilter = args[i + 1];
205
266
  args.splice(i, 2);
206
- break;
267
+ i--;
207
268
  }
208
269
  }
209
270
  const explicitPort = args[0] && args[1] ? Number(args[0]) : null;
@@ -369,8 +430,104 @@ function startPoll() {
369
430
  }, POLL_INTERVAL_MS);
370
431
  }
371
432
 
372
- // --- Initial connection ---
373
- if (explicitPort !== null) {
433
+ // --- Ping mode: one-shot probe, then exit ---
434
+ // `grok mcp doctor` (and similar stdio MCP verifiers) hang on this shim because
435
+ // it is a long-lived relay that only exits on stdin EOF. `--ping` / `--probe`
436
+ // gives those tools a clean check: connect, run initialize + tools/list, print a
437
+ // one-line summary, and exit. It skips the relay, lock watcher, and reconnect
438
+ // loops entirely.
439
+ if (pingMode) {
440
+ let pingPort = explicitPort;
441
+ let pingToken = explicitToken;
442
+ if (pingPort === null) {
443
+ const lockFile = findLockFile();
444
+ if (!lockFile) {
445
+ process.stderr.write("mcp-stdio-shim: --ping: no bridge lock found.\n");
446
+ process.exit(1);
447
+ }
448
+ try {
449
+ const parsed = parseLock(lockFile);
450
+ pingPort = parsed.port;
451
+ pingToken = parsed.authToken;
452
+ } catch (err) {
453
+ process.stderr.write(
454
+ `mcp-stdio-shim: --ping: lock unreadable (${err.message}).\n`,
455
+ );
456
+ process.exit(1);
457
+ }
458
+ }
459
+ let pingDone = false;
460
+ const pingWs = new WebSocket(`ws://127.0.0.1:${pingPort}`, {
461
+ headers: {
462
+ "x-claude-code-ide-authorization": pingToken,
463
+ "x-claude-code-session-id": CLIENT_SESSION_ID,
464
+ },
465
+ });
466
+ const failPing = (msg) => {
467
+ if (pingDone) return;
468
+ pingDone = true;
469
+ process.stderr.write(`mcp-stdio-shim: --ping: ${msg}\n`);
470
+ try {
471
+ pingWs.terminate();
472
+ } catch {
473
+ /* ignore */
474
+ }
475
+ process.exit(1);
476
+ };
477
+ const pingTimer = setTimeout(
478
+ () => failPing(`timed out after 5s (port ${pingPort})`),
479
+ 5000,
480
+ );
481
+ pingWs.on("open", () => {
482
+ pingWs.send(
483
+ JSON.stringify({
484
+ jsonrpc: "2.0",
485
+ id: 1,
486
+ method: "initialize",
487
+ params: {
488
+ protocolVersion: "2025-06-18",
489
+ capabilities: {},
490
+ clientInfo: { name: "shim-ping", version: "1" },
491
+ },
492
+ }),
493
+ );
494
+ });
495
+ pingWs.on("message", (raw) => {
496
+ let msg;
497
+ try {
498
+ msg = JSON.parse(raw.toString());
499
+ } catch {
500
+ return;
501
+ }
502
+ if (msg.id === 1) {
503
+ pingWs.send(
504
+ JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }),
505
+ );
506
+ pingWs.send(
507
+ JSON.stringify({ jsonrpc: "2.0", id: 2, method: "tools/list" }),
508
+ );
509
+ } else if (msg.id === 2) {
510
+ clearTimeout(pingTimer);
511
+ pingDone = true;
512
+ const n =
513
+ msg.result && Array.isArray(msg.result.tools)
514
+ ? msg.result.tools.length
515
+ : "?";
516
+ process.stdout.write(`bridge OK — port ${pingPort}, ${n} tools\n`);
517
+ try {
518
+ pingWs.close();
519
+ } catch {
520
+ /* ignore */
521
+ }
522
+ process.exit(0);
523
+ }
524
+ });
525
+ pingWs.on("error", (err) => failPing(`connect failed (${err.message})`));
526
+ pingWs.on("close", (code) =>
527
+ failPing(`closed before tools/list (code ${code})`),
528
+ );
529
+ } else if (explicitPort !== null) {
530
+ // --- Initial connection ---
374
531
  connect(explicitPort, explicitToken);
375
532
  } else {
376
533
  const lockFile = findLockFile();
@@ -398,7 +555,7 @@ if (explicitPort !== null) {
398
555
  // Watches ~/.claude/ide/ for .lock file changes. When a new bridge lock appears
399
556
  // on a different port, reconnects automatically. This means Claude Desktop never
400
557
  // needs to be restarted when the bridge restarts on a new port.
401
- if (explicitPort === null) {
558
+ if (!pingMode && explicitPort === null) {
402
559
  const lockDir = path.join(
403
560
  process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude"),
404
561
  "ide",
@@ -439,52 +596,38 @@ if (explicitPort === null) {
439
596
 
440
597
  // --- stdin → bridge (newline-delimited JSON-RPC) ---
441
598
  // Messages that arrive before the WebSocket is open are queued and flushed on connect.
442
- process.stdin.setEncoding("utf8");
443
- process.stdin.on("data", (chunk) => {
444
- buffer += chunk;
445
- const lines = buffer.split("\n");
446
- buffer = lines.pop() ?? "";
447
- for (const line of lines) {
448
- const trimmed = line.trim();
449
- if (!trimmed) continue;
450
- if (ws && ws.readyState === WebSocket.OPEN) {
451
- try {
452
- ws.send(trimmed);
453
- } catch (sendErr) {
599
+ // Skipped in --ping mode — the one-shot probe manages its own lifecycle and exits.
600
+ if (!pingMode) {
601
+ process.stdin.setEncoding("utf8");
602
+ process.stdin.on("data", (chunk) => {
603
+ buffer += chunk;
604
+ const lines = buffer.split("\n");
605
+ buffer = lines.pop() ?? "";
606
+ for (const line of lines) {
607
+ const trimmed = line.trim();
608
+ if (!trimmed) continue;
609
+ if (ws && ws.readyState === WebSocket.OPEN) {
610
+ try {
611
+ ws.send(trimmed);
612
+ } catch (sendErr) {
613
+ process.stderr.write(
614
+ `mcp-stdio-shim: ws.send failed (${sendErr.message}) — queuing message.\n`,
615
+ );
616
+ if (pendingLines.length < MAX_PENDING_LINES) {
617
+ pendingLines.push(trimmed);
618
+ }
619
+ }
620
+ } else if (pendingLines.length < MAX_PENDING_LINES) {
621
+ pendingLines.push(trimmed);
622
+ } else {
454
623
  process.stderr.write(
455
- `mcp-stdio-shim: ws.send failed (${sendErr.message}) — queuing message.\n`,
624
+ `mcp-stdio-shim: pendingLines overflow (${MAX_PENDING_LINES}) — dropping message (bridge not connected)\n`,
456
625
  );
457
- if (pendingLines.length < MAX_PENDING_LINES) {
458
- pendingLines.push(trimmed);
459
- }
460
626
  }
461
- } else if (pendingLines.length < MAX_PENDING_LINES) {
462
- pendingLines.push(trimmed);
463
- } else {
464
- process.stderr.write(
465
- `mcp-stdio-shim: pendingLines overflow (${MAX_PENDING_LINES}) — dropping message (bridge not connected)\n`,
466
- );
467
627
  }
468
- }
469
- });
470
-
471
- process.stdin.on("end", () => {
472
- if (ws) {
473
- try {
474
- ws.close();
475
- } catch {
476
- /* ignore */
477
- }
478
- }
479
- process.exit(0);
480
- });
628
+ });
481
629
 
482
- process.stdin.on("error", (err) => {
483
- // EPIPE / ERR_STREAM_DESTROYED means the MCP host closed the pipe — clean shutdown.
484
- if (err.code === "EPIPE" || err.code === "ERR_STREAM_DESTROYED") {
485
- process.stderr.write(
486
- `mcp-stdio-shim: stdin closed (${err.code}) — shutting down.\n`,
487
- );
630
+ process.stdin.on("end", () => {
488
631
  if (ws) {
489
632
  try {
490
633
  ws.close();
@@ -493,6 +636,23 @@ process.stdin.on("error", (err) => {
493
636
  }
494
637
  }
495
638
  process.exit(0);
496
- }
497
- process.stderr.write(`mcp-stdio-shim: stdin error: ${err.message}\n`);
498
- });
639
+ });
640
+
641
+ process.stdin.on("error", (err) => {
642
+ // EPIPE / ERR_STREAM_DESTROYED means the MCP host closed the pipe — clean shutdown.
643
+ if (err.code === "EPIPE" || err.code === "ERR_STREAM_DESTROYED") {
644
+ process.stderr.write(
645
+ `mcp-stdio-shim: stdin closed (${err.code}) — shutting down.\n`,
646
+ );
647
+ if (ws) {
648
+ try {
649
+ ws.close();
650
+ } catch {
651
+ /* ignore */
652
+ }
653
+ }
654
+ process.exit(0);
655
+ }
656
+ process.stderr.write(`mcp-stdio-shim: stdin error: ${err.message}\n`);
657
+ });
658
+ }
@@ -110,7 +110,7 @@ Workflow:
110
110
 
111
111
  **If bridge tools are missing from your tool list inside Cowork:** you're in the wrong context. Exit, run the prompt in regular chat, then return.
112
112
 
113
- Full details: [docs/cowork-workflow.md](docs/cowork-workflow.md)
113
+ Full details: [docs/cowork.md](docs/cowork.md)
114
114
 
115
115
  **Cowork uses git worktrees:** Cowork sessions operate in an isolated git worktree (separate branch/working copy), not the main workspace root. Files written by Cowork land in the worktree. Always add "write all files to the workspace root, not a subdirectory" as the first instruction in your CLAUDE.md when using Cowork with a synced workspace. After Cowork finishes, review and merge the worktree branch back to main.
116
116
 
@@ -0,0 +1,33 @@
1
+ # yaml-language-server: $schema=https://patchwork.dev/schemas/recipe.v1.json
2
+ # Body for the Dependency Upkeep Worker
3
+ # (templates/workers/dependency-upkeep.worker.yaml). Weekly cron — reviews the
4
+ # open dependency-update PRs rather than opening them (autonomyCeiling L3: a
5
+ # human still merges).
6
+ apiVersion: patchwork.sh/v1
7
+ name: dependency-bump
8
+ description: Weekly — list open dependency-update PRs and summarize which look safe to merge.
9
+ trigger:
10
+ type: cron
11
+ at: "0 9 * * MON"
12
+ steps:
13
+ - tool: github.list_prs
14
+ max: 30
15
+ into: prs
16
+ - agent:
17
+ prompt: |
18
+ Open pull requests:
19
+ {{prs}}
20
+
21
+ Identify the dependency-update PRs (dependabot / renovate / "bump …"
22
+ titles). For each, note the package, the version jump (patch / minor /
23
+ major), and a recommendation: SAFE to merge (patch/minor with green CI)
24
+ or NEEDS REVIEW (major, or a security-sensitive dependency). Output a
25
+ short markdown table; if there are none, say "No dependency PRs open."
26
+ driver: claude-code
27
+ into: review
28
+ - tool: file.write
29
+ path: ~/.patchwork/inbox/dependency-review-{{date}}.md
30
+ content: |
31
+ # Dependency PR review — {{date}}
32
+
33
+ {{review}}