patchwork-os 0.2.0-beta.0 → 0.2.0-beta.10

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 (673) hide show
  1. package/README.bridge.md +14 -14
  2. package/README.md +204 -34
  3. package/deploy/README.md +1 -1
  4. package/deploy/bootstrap-vps.sh +14 -9
  5. package/deploy/deploy-dashboard.sh +25 -1
  6. package/deploy/macos/README.md +153 -0
  7. package/deploy/macos/com.patchwork.bridge.plist.template +54 -0
  8. package/deploy/macos/com.patchwork.tunnel.plist.template +76 -0
  9. package/deploy/macos/install-mac-bridge.sh +244 -0
  10. package/deploy/macos/uninstall-mac-bridge.sh +22 -0
  11. package/dist/activityLog.d.ts +6 -0
  12. package/dist/activityLog.js +63 -26
  13. package/dist/activityLog.js.map +1 -1
  14. package/dist/adapters/claude.js +22 -16
  15. package/dist/adapters/claude.js.map +1 -1
  16. package/dist/adapters/gemini.js +15 -11
  17. package/dist/adapters/gemini.js.map +1 -1
  18. package/dist/adapters/openai.js +9 -9
  19. package/dist/adapters/openai.js.map +1 -1
  20. package/dist/ajv2020.d.ts +25 -0
  21. package/dist/ajv2020.js +33 -0
  22. package/dist/ajv2020.js.map +1 -0
  23. package/dist/analyticsAggregator.d.ts +5 -1
  24. package/dist/analyticsAggregator.js +16 -5
  25. package/dist/analyticsAggregator.js.map +1 -1
  26. package/dist/analyticsConfig.d.ts +29 -0
  27. package/dist/analyticsConfig.js +102 -0
  28. package/dist/analyticsConfig.js.map +1 -0
  29. package/dist/analyticsPrefs.d.ts +49 -2
  30. package/dist/analyticsPrefs.js +177 -19
  31. package/dist/analyticsPrefs.js.map +1 -1
  32. package/dist/analyticsSend.d.ts +17 -1
  33. package/dist/analyticsSend.js +67 -5
  34. package/dist/analyticsSend.js.map +1 -1
  35. package/dist/approvalHttp.d.ts +14 -0
  36. package/dist/approvalHttp.js +212 -9
  37. package/dist/approvalHttp.js.map +1 -1
  38. package/dist/approvalInsights.js +13 -5
  39. package/dist/approvalInsights.js.map +1 -1
  40. package/dist/approvalQueue.d.ts +97 -3
  41. package/dist/approvalQueue.js +193 -19
  42. package/dist/approvalQueue.js.map +1 -1
  43. package/dist/approvalSignals.js +19 -11
  44. package/dist/approvalSignals.js.map +1 -1
  45. package/dist/automation.d.ts +35 -10
  46. package/dist/automation.js +133 -37
  47. package/dist/automation.js.map +1 -1
  48. package/dist/automationSuggestions.js +10 -8
  49. package/dist/automationSuggestions.js.map +1 -1
  50. package/dist/bridge.d.ts +2 -0
  51. package/dist/bridge.js +238 -51
  52. package/dist/bridge.js.map +1 -1
  53. package/dist/bridgeLockDiscovery.d.ts +27 -1
  54. package/dist/bridgeLockDiscovery.js +38 -11
  55. package/dist/bridgeLockDiscovery.js.map +1 -1
  56. package/dist/bridgeToken.js +3 -2
  57. package/dist/bridgeToken.js.map +1 -1
  58. package/dist/claudeDriver.d.ts +0 -16
  59. package/dist/claudeDriver.js +42 -28
  60. package/dist/claudeDriver.js.map +1 -1
  61. package/dist/claudeMdPatch.d.ts +9 -3
  62. package/dist/claudeMdPatch.js +79 -13
  63. package/dist/claudeMdPatch.js.map +1 -1
  64. package/dist/claudeOrchestrator.d.ts +13 -1
  65. package/dist/claudeOrchestrator.js +89 -44
  66. package/dist/claudeOrchestrator.js.map +1 -1
  67. package/dist/commands/analytics.d.ts +8 -0
  68. package/dist/commands/analytics.js +134 -0
  69. package/dist/commands/analytics.js.map +1 -0
  70. package/dist/commands/auditEnv.d.ts +36 -0
  71. package/dist/commands/auditEnv.js +202 -0
  72. package/dist/commands/auditEnv.js.map +1 -0
  73. package/dist/commands/dashboard.js +8 -1
  74. package/dist/commands/dashboard.js.map +1 -1
  75. package/dist/commands/doctor.d.ts +35 -0
  76. package/dist/commands/doctor.js +51 -0
  77. package/dist/commands/doctor.js.map +1 -0
  78. package/dist/commands/install.js +3 -0
  79. package/dist/commands/install.js.map +1 -1
  80. package/dist/commands/launchd.js +15 -16
  81. package/dist/commands/launchd.js.map +1 -1
  82. package/dist/commands/patchworkInit.d.ts +5 -0
  83. package/dist/commands/patchworkInit.js +89 -7
  84. package/dist/commands/patchworkInit.js.map +1 -1
  85. package/dist/commands/recipe.d.ts +110 -0
  86. package/dist/commands/recipe.js +512 -9
  87. package/dist/commands/recipe.js.map +1 -1
  88. package/dist/commands/recipeInstall.js +11 -4
  89. package/dist/commands/recipeInstall.js.map +1 -1
  90. package/dist/commands/shadowScan.d.ts +34 -0
  91. package/dist/commands/shadowScan.js +142 -0
  92. package/dist/commands/shadowScan.js.map +1 -0
  93. package/dist/commands/task.js +2 -2
  94. package/dist/commands/task.js.map +1 -1
  95. package/dist/commands/tools.d.ts +20 -1
  96. package/dist/commands/tools.js +112 -3
  97. package/dist/commands/tools.js.map +1 -1
  98. package/dist/commands/tracesImport.js +21 -4
  99. package/dist/commands/tracesImport.js.map +1 -1
  100. package/dist/commitIssueLinkLog.d.ts +24 -0
  101. package/dist/commitIssueLinkLog.js +160 -22
  102. package/dist/commitIssueLinkLog.js.map +1 -1
  103. package/dist/companions/registry.js +15 -7
  104. package/dist/companions/registry.js.map +1 -1
  105. package/dist/config.d.ts +49 -5
  106. package/dist/config.js +123 -22
  107. package/dist/config.js.map +1 -1
  108. package/dist/connectorRoutes.js +913 -413
  109. package/dist/connectorRoutes.js.map +1 -1
  110. package/dist/connectors/airtable.d.ts +230 -0
  111. package/dist/connectors/airtable.js +700 -0
  112. package/dist/connectors/airtable.js.map +1 -0
  113. package/dist/connectors/asana.js +13 -9
  114. package/dist/connectors/asana.js.map +1 -1
  115. package/dist/connectors/baseConnector.js +25 -3
  116. package/dist/connectors/baseConnector.js.map +1 -1
  117. package/dist/connectors/caldiy.d.ts +137 -0
  118. package/dist/connectors/caldiy.js +424 -0
  119. package/dist/connectors/caldiy.js.map +1 -0
  120. package/dist/connectors/circleci.d.ts +162 -0
  121. package/dist/connectors/circleci.js +576 -0
  122. package/dist/connectors/circleci.js.map +1 -0
  123. package/dist/connectors/cloudflare.d.ts +132 -0
  124. package/dist/connectors/cloudflare.js +622 -0
  125. package/dist/connectors/cloudflare.js.map +1 -0
  126. package/dist/connectors/confluence.js +35 -0
  127. package/dist/connectors/confluence.js.map +1 -1
  128. package/dist/connectors/connectorRedirectUri.d.ts +30 -0
  129. package/dist/connectors/connectorRedirectUri.js +38 -0
  130. package/dist/connectors/connectorRedirectUri.js.map +1 -0
  131. package/dist/connectors/connectorRegistry.d.ts +63 -0
  132. package/dist/connectors/connectorRegistry.js +354 -0
  133. package/dist/connectors/connectorRegistry.js.map +1 -0
  134. package/dist/connectors/datadog.js +33 -4
  135. package/dist/connectors/datadog.js.map +1 -1
  136. package/dist/connectors/discord.js +14 -10
  137. package/dist/connectors/discord.js.map +1 -1
  138. package/dist/connectors/elasticsearch.d.ts +141 -0
  139. package/dist/connectors/elasticsearch.js +601 -0
  140. package/dist/connectors/elasticsearch.js.map +1 -0
  141. package/dist/connectors/figma.d.ts +130 -0
  142. package/dist/connectors/figma.js +387 -0
  143. package/dist/connectors/figma.js.map +1 -0
  144. package/dist/connectors/github.d.ts +17 -0
  145. package/dist/connectors/github.js +53 -2
  146. package/dist/connectors/github.js.map +1 -1
  147. package/dist/connectors/gitlab.js +12 -6
  148. package/dist/connectors/gitlab.js.map +1 -1
  149. package/dist/connectors/gmail.js +72 -21
  150. package/dist/connectors/gmail.js.map +1 -1
  151. package/dist/connectors/googleCalendar.js +8 -8
  152. package/dist/connectors/googleCalendar.js.map +1 -1
  153. package/dist/connectors/googleDocs.d.ts +103 -0
  154. package/dist/connectors/googleDocs.js +409 -0
  155. package/dist/connectors/googleDocs.js.map +1 -0
  156. package/dist/connectors/googleDrive.d.ts +12 -0
  157. package/dist/connectors/googleDrive.js +35 -8
  158. package/dist/connectors/googleDrive.js.map +1 -1
  159. package/dist/connectors/grafana.d.ts +133 -0
  160. package/dist/connectors/grafana.js +478 -0
  161. package/dist/connectors/grafana.js.map +1 -0
  162. package/dist/connectors/jira.d.ts +25 -0
  163. package/dist/connectors/jira.js +245 -2
  164. package/dist/connectors/jira.js.map +1 -1
  165. package/dist/connectors/linear.js +1 -1
  166. package/dist/connectors/linear.js.map +1 -1
  167. package/dist/connectors/mcpOAuth.js +78 -16
  168. package/dist/connectors/mcpOAuth.js.map +1 -1
  169. package/dist/connectors/monday.d.ts +217 -0
  170. package/dist/connectors/monday.js +655 -0
  171. package/dist/connectors/monday.js.map +1 -0
  172. package/dist/connectors/mongodb.d.ts +139 -0
  173. package/dist/connectors/mongodb.js +455 -0
  174. package/dist/connectors/mongodb.js.map +1 -0
  175. package/dist/connectors/oauthStateStore.d.ts +20 -0
  176. package/dist/connectors/oauthStateStore.js +94 -4
  177. package/dist/connectors/oauthStateStore.js.map +1 -1
  178. package/dist/connectors/obsidian.d.ts +83 -0
  179. package/dist/connectors/obsidian.js +441 -0
  180. package/dist/connectors/obsidian.js.map +1 -0
  181. package/dist/connectors/paystack.d.ts +159 -0
  182. package/dist/connectors/paystack.js +607 -0
  183. package/dist/connectors/paystack.js.map +1 -0
  184. package/dist/connectors/pipedrive.d.ts +189 -0
  185. package/dist/connectors/pipedrive.js +559 -0
  186. package/dist/connectors/pipedrive.js.map +1 -0
  187. package/dist/connectors/postgres.d.ts +127 -0
  188. package/dist/connectors/postgres.js +512 -0
  189. package/dist/connectors/postgres.js.map +1 -0
  190. package/dist/connectors/posthog.d.ts +119 -0
  191. package/dist/connectors/posthog.js +479 -0
  192. package/dist/connectors/posthog.js.map +1 -0
  193. package/dist/connectors/redis.d.ts +140 -0
  194. package/dist/connectors/redis.js +571 -0
  195. package/dist/connectors/redis.js.map +1 -0
  196. package/dist/connectors/resend.d.ts +131 -0
  197. package/dist/connectors/resend.js +529 -0
  198. package/dist/connectors/resend.js.map +1 -0
  199. package/dist/connectors/salesforce.d.ts +136 -0
  200. package/dist/connectors/salesforce.js +603 -0
  201. package/dist/connectors/salesforce.js.map +1 -0
  202. package/dist/connectors/secrets.d.ts +51 -0
  203. package/dist/connectors/secrets.js +102 -0
  204. package/dist/connectors/secrets.js.map +1 -0
  205. package/dist/connectors/sendgrid.d.ts +102 -0
  206. package/dist/connectors/sendgrid.js +423 -0
  207. package/dist/connectors/sendgrid.js.map +1 -0
  208. package/dist/connectors/shopify.d.ts +145 -0
  209. package/dist/connectors/shopify.js +502 -0
  210. package/dist/connectors/shopify.js.map +1 -0
  211. package/dist/connectors/slack.d.ts +1 -1
  212. package/dist/connectors/slack.js +61 -9
  213. package/dist/connectors/slack.js.map +1 -1
  214. package/dist/connectors/snowflake.d.ts +119 -0
  215. package/dist/connectors/snowflake.js +615 -0
  216. package/dist/connectors/snowflake.js.map +1 -0
  217. package/dist/connectors/supabase.d.ts +92 -0
  218. package/dist/connectors/supabase.js +630 -0
  219. package/dist/connectors/supabase.js.map +1 -0
  220. package/dist/connectors/todoist.d.ts +117 -0
  221. package/dist/connectors/todoist.js +485 -0
  222. package/dist/connectors/todoist.js.map +1 -0
  223. package/dist/connectors/tokenStorage.js +56 -14
  224. package/dist/connectors/tokenStorage.js.map +1 -1
  225. package/dist/connectors/twilio.d.ts +118 -0
  226. package/dist/connectors/twilio.js +475 -0
  227. package/dist/connectors/twilio.js.map +1 -0
  228. package/dist/connectors/vercel.d.ts +110 -0
  229. package/dist/connectors/vercel.js +479 -0
  230. package/dist/connectors/vercel.js.map +1 -0
  231. package/dist/connectors/webflow.d.ts +118 -0
  232. package/dist/connectors/webflow.js +393 -0
  233. package/dist/connectors/webflow.js.map +1 -0
  234. package/dist/connectors/woocommerce.d.ts +220 -0
  235. package/dist/connectors/woocommerce.js +464 -0
  236. package/dist/connectors/woocommerce.js.map +1 -0
  237. package/dist/crypto.js +7 -2
  238. package/dist/crypto.js.map +1 -1
  239. package/dist/decisionReplay.js +15 -6
  240. package/dist/decisionReplay.js.map +1 -1
  241. package/dist/decisionTraceLog.d.ts +28 -0
  242. package/dist/decisionTraceLog.js +156 -29
  243. package/dist/decisionTraceLog.js.map +1 -1
  244. package/dist/drivers/claude/api.js +5 -4
  245. package/dist/drivers/claude/api.js.map +1 -1
  246. package/dist/drivers/claude/envSanitizer.d.ts +0 -6
  247. package/dist/drivers/claude/envSanitizer.js +17 -2
  248. package/dist/drivers/claude/envSanitizer.js.map +1 -1
  249. package/dist/drivers/claude/streamParser.js +5 -4
  250. package/dist/drivers/claude/streamParser.js.map +1 -1
  251. package/dist/drivers/claude/subprocess.d.ts +12 -2
  252. package/dist/drivers/claude/subprocess.js +100 -8
  253. package/dist/drivers/claude/subprocess.js.map +1 -1
  254. package/dist/drivers/gemini/api.d.ts +18 -0
  255. package/dist/drivers/gemini/api.js +29 -0
  256. package/dist/drivers/gemini/api.js.map +1 -0
  257. package/dist/drivers/gemini/index.d.ts +22 -0
  258. package/dist/drivers/gemini/index.js +256 -129
  259. package/dist/drivers/gemini/index.js.map +1 -1
  260. package/dist/drivers/index.d.ts +3 -1
  261. package/dist/drivers/index.js +9 -1
  262. package/dist/drivers/index.js.map +1 -1
  263. package/dist/drivers/local/index.d.ts +43 -0
  264. package/dist/drivers/local/index.js +140 -0
  265. package/dist/drivers/local/index.js.map +1 -0
  266. package/dist/drivers/openai/index.js +30 -2
  267. package/dist/drivers/openai/index.js.map +1 -1
  268. package/dist/extensionClient.d.ts +37 -4
  269. package/dist/extensionClient.js +58 -16
  270. package/dist/extensionClient.js.map +1 -1
  271. package/dist/featureFlags.d.ts +91 -0
  272. package/dist/featureFlags.js +174 -3
  273. package/dist/featureFlags.js.map +1 -1
  274. package/dist/fileLock.js +21 -12
  275. package/dist/fileLock.js.map +1 -1
  276. package/dist/fileLockSync.d.ts +67 -0
  277. package/dist/fileLockSync.js +126 -0
  278. package/dist/fileLockSync.js.map +1 -0
  279. package/dist/fp/activityAnalytics.js +26 -12
  280. package/dist/fp/activityAnalytics.js.map +1 -1
  281. package/dist/fp/automationInterpreter.d.ts +15 -1
  282. package/dist/fp/automationInterpreter.js +217 -82
  283. package/dist/fp/automationInterpreter.js.map +1 -1
  284. package/dist/fp/automationProgram.d.ts +30 -0
  285. package/dist/fp/automationProgram.js.map +1 -1
  286. package/dist/fp/automationState.d.ts +24 -5
  287. package/dist/fp/automationState.js +56 -9
  288. package/dist/fp/automationState.js.map +1 -1
  289. package/dist/fp/automationUtils.js +1 -1
  290. package/dist/fp/automationUtils.js.map +1 -1
  291. package/dist/fp/commandDescription.js +7 -1
  292. package/dist/fp/commandDescription.js.map +1 -1
  293. package/dist/fp/extensionSnapshot.js +8 -2
  294. package/dist/fp/extensionSnapshot.js.map +1 -1
  295. package/dist/fp/interpreterContext.d.ts +66 -1
  296. package/dist/fp/interpreterContext.js +91 -1
  297. package/dist/fp/interpreterContext.js.map +1 -1
  298. package/dist/fp/policyParser.js +29 -1
  299. package/dist/fp/policyParser.js.map +1 -1
  300. package/dist/fsWatchWithFallback.d.ts +36 -0
  301. package/dist/fsWatchWithFallback.js +128 -0
  302. package/dist/fsWatchWithFallback.js.map +1 -0
  303. package/dist/haltPushDispatch.d.ts +33 -0
  304. package/dist/haltPushDispatch.js +103 -0
  305. package/dist/haltPushDispatch.js.map +1 -0
  306. package/dist/httpBodyValidation.d.ts +41 -0
  307. package/dist/httpBodyValidation.js +45 -0
  308. package/dist/httpBodyValidation.js.map +1 -0
  309. package/dist/httpErrorResponse.d.ts +36 -0
  310. package/dist/httpErrorResponse.js +46 -0
  311. package/dist/httpErrorResponse.js.map +1 -0
  312. package/dist/inboxRoutes.d.ts +22 -0
  313. package/dist/inboxRoutes.js +151 -12
  314. package/dist/inboxRoutes.js.map +1 -1
  315. package/dist/index.d.ts +1 -1
  316. package/dist/index.js +1054 -76
  317. package/dist/index.js.map +1 -1
  318. package/dist/installGuard.js +6 -2
  319. package/dist/installGuard.js.map +1 -1
  320. package/dist/lockfile.js +31 -4
  321. package/dist/lockfile.js.map +1 -1
  322. package/dist/oauth.d.ts +22 -0
  323. package/dist/oauth.js +46 -0
  324. package/dist/oauth.js.map +1 -1
  325. package/dist/oauthRoutes.d.ts +1 -1
  326. package/dist/oauthRoutes.js +8 -11
  327. package/dist/oauthRoutes.js.map +1 -1
  328. package/dist/orchestrator/childBridgeRegistry.js +29 -11
  329. package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
  330. package/dist/patchworkConfig.d.ts +57 -1
  331. package/dist/patchworkConfig.js +125 -5
  332. package/dist/patchworkConfig.js.map +1 -1
  333. package/dist/pluginLoader.js +10 -1
  334. package/dist/pluginLoader.js.map +1 -1
  335. package/dist/pluginWatcher.js +12 -14
  336. package/dist/pluginWatcher.js.map +1 -1
  337. package/dist/preToolUseHook.js +10 -3
  338. package/dist/preToolUseHook.js.map +1 -1
  339. package/dist/processTree.d.ts +34 -0
  340. package/dist/processTree.js +105 -0
  341. package/dist/processTree.js.map +1 -0
  342. package/dist/prompts.js +7 -3
  343. package/dist/prompts.js.map +1 -1
  344. package/dist/recipeOrchestration.d.ts +9 -0
  345. package/dist/recipeOrchestration.js +354 -27
  346. package/dist/recipeOrchestration.js.map +1 -1
  347. package/dist/recipeRoutes.d.ts +63 -2
  348. package/dist/recipeRoutes.js +790 -137
  349. package/dist/recipeRoutes.js.map +1 -1
  350. package/dist/recipes/RecipeOrchestrator.d.ts +2 -0
  351. package/dist/recipes/RecipeOrchestrator.js +6 -1
  352. package/dist/recipes/RecipeOrchestrator.js.map +1 -1
  353. package/dist/recipes/agentExecutor.d.ts +34 -5
  354. package/dist/recipes/agentExecutor.js +5 -4
  355. package/dist/recipes/agentExecutor.js.map +1 -1
  356. package/dist/recipes/chainedRunner.d.ts +2 -0
  357. package/dist/recipes/chainedRunner.js +142 -5
  358. package/dist/recipes/chainedRunner.js.map +1 -1
  359. package/dist/recipes/connectorPreflight.d.ts +66 -0
  360. package/dist/recipes/connectorPreflight.js +169 -0
  361. package/dist/recipes/connectorPreflight.js.map +1 -0
  362. package/dist/recipes/dependencyGraph.js +13 -5
  363. package/dist/recipes/dependencyGraph.js.map +1 -1
  364. package/dist/recipes/githubInstallSource.d.ts +128 -0
  365. package/dist/recipes/githubInstallSource.js +206 -0
  366. package/dist/recipes/githubInstallSource.js.map +1 -0
  367. package/dist/recipes/haltCategory.d.ts +119 -0
  368. package/dist/recipes/haltCategory.js +188 -0
  369. package/dist/recipes/haltCategory.js.map +1 -0
  370. package/dist/recipes/idempotencyKey.d.ts +134 -0
  371. package/dist/recipes/idempotencyKey.js +322 -0
  372. package/dist/recipes/idempotencyKey.js.map +1 -0
  373. package/dist/recipes/installer.js +48 -2
  374. package/dist/recipes/installer.js.map +1 -1
  375. package/dist/recipes/judgeSummary.d.ts +50 -0
  376. package/dist/recipes/judgeSummary.js +47 -0
  377. package/dist/recipes/judgeSummary.js.map +1 -0
  378. package/dist/recipes/judgeVerdict.d.ts +48 -0
  379. package/dist/recipes/judgeVerdict.js +174 -0
  380. package/dist/recipes/judgeVerdict.js.map +1 -0
  381. package/dist/recipes/migrations/index.d.ts +9 -0
  382. package/dist/recipes/migrations/index.js +133 -0
  383. package/dist/recipes/migrations/index.js.map +1 -1
  384. package/dist/recipes/names.d.ts +20 -0
  385. package/dist/recipes/names.js +25 -0
  386. package/dist/recipes/names.js.map +1 -1
  387. package/dist/recipes/parser.js +88 -5
  388. package/dist/recipes/parser.js.map +1 -1
  389. package/dist/recipes/replayRun.js +1 -1
  390. package/dist/recipes/replayRun.js.map +1 -1
  391. package/dist/recipes/runBudget.d.ts +70 -0
  392. package/dist/recipes/runBudget.js +109 -0
  393. package/dist/recipes/runBudget.js.map +1 -0
  394. package/dist/recipes/scheduler.d.ts +30 -0
  395. package/dist/recipes/scheduler.js +69 -19
  396. package/dist/recipes/scheduler.js.map +1 -1
  397. package/dist/recipes/schema.d.ts +36 -0
  398. package/dist/recipes/schemaGenerator.js +103 -5
  399. package/dist/recipes/schemaGenerator.js.map +1 -1
  400. package/dist/recipes/stepObservation.js +9 -0
  401. package/dist/recipes/stepObservation.js.map +1 -1
  402. package/dist/recipes/toolRegistry.js +20 -3
  403. package/dist/recipes/toolRegistry.js.map +1 -1
  404. package/dist/recipes/tools/fanOut.d.ts +20 -0
  405. package/dist/recipes/tools/fanOut.js +199 -0
  406. package/dist/recipes/tools/fanOut.js.map +1 -0
  407. package/dist/recipes/tools/file.js +5 -2
  408. package/dist/recipes/tools/file.js.map +1 -1
  409. package/dist/recipes/tools/github.d.ts +1 -1
  410. package/dist/recipes/tools/github.js +75 -1
  411. package/dist/recipes/tools/github.js.map +1 -1
  412. package/dist/recipes/tools/gmail.js +45 -6
  413. package/dist/recipes/tools/gmail.js.map +1 -1
  414. package/dist/recipes/tools/googleDrive.js +64 -0
  415. package/dist/recipes/tools/googleDrive.js.map +1 -1
  416. package/dist/recipes/tools/http.d.ts +10 -0
  417. package/dist/recipes/tools/http.js +176 -0
  418. package/dist/recipes/tools/http.js.map +1 -0
  419. package/dist/recipes/tools/index.d.ts +2 -0
  420. package/dist/recipes/tools/index.js +2 -0
  421. package/dist/recipes/tools/index.js.map +1 -1
  422. package/dist/recipes/tools/slack.js +1 -1
  423. package/dist/recipes/validation.d.ts +17 -0
  424. package/dist/recipes/validation.js +29 -11
  425. package/dist/recipes/validation.js.map +1 -1
  426. package/dist/recipes/workspaceRoot.d.ts +37 -0
  427. package/dist/recipes/workspaceRoot.js +73 -0
  428. package/dist/recipes/workspaceRoot.js.map +1 -0
  429. package/dist/recipes/yamlPositions.d.ts +56 -0
  430. package/dist/recipes/yamlPositions.js +183 -0
  431. package/dist/recipes/yamlPositions.js.map +1 -0
  432. package/dist/recipes/yamlRunner.d.ts +195 -8
  433. package/dist/recipes/yamlRunner.js +877 -209
  434. package/dist/recipes/yamlRunner.js.map +1 -1
  435. package/dist/recipesHttp.d.ts +33 -3
  436. package/dist/recipesHttp.js +126 -12
  437. package/dist/recipesHttp.js.map +1 -1
  438. package/dist/resources.js +21 -13
  439. package/dist/resources.js.map +1 -1
  440. package/dist/runLog.d.ts +58 -5
  441. package/dist/runLog.js +98 -21
  442. package/dist/runLog.js.map +1 -1
  443. package/dist/sanitizeParsedJson.d.ts +39 -0
  444. package/dist/sanitizeParsedJson.js +55 -0
  445. package/dist/sanitizeParsedJson.js.map +1 -0
  446. package/dist/schemas/recipe.v1.json +885 -196
  447. package/dist/server.d.ts +166 -3
  448. package/dist/server.js +1313 -332
  449. package/dist/server.js.map +1 -1
  450. package/dist/sessionCheckpoint.d.ts +8 -0
  451. package/dist/sessionCheckpoint.js +33 -3
  452. package/dist/sessionCheckpoint.js.map +1 -1
  453. package/dist/ssrfGuard.d.ts +16 -0
  454. package/dist/ssrfGuard.js +87 -4
  455. package/dist/ssrfGuard.js.map +1 -1
  456. package/dist/streamableHttp.d.ts +9 -4
  457. package/dist/streamableHttp.js +76 -20
  458. package/dist/streamableHttp.js.map +1 -1
  459. package/dist/telemetry.js +19 -12
  460. package/dist/telemetry.js.map +1 -1
  461. package/dist/testing/shadowRun.d.ts +52 -0
  462. package/dist/testing/shadowRun.js +71 -0
  463. package/dist/testing/shadowRun.js.map +1 -0
  464. package/dist/tools/batchLsp.d.ts +3 -0
  465. package/dist/tools/bridgeDoctor.d.ts +11 -0
  466. package/dist/tools/bridgeDoctor.js +48 -2
  467. package/dist/tools/bridgeDoctor.js.map +1 -1
  468. package/dist/tools/bridgeStatus.d.ts +0 -12
  469. package/dist/tools/bridgeStatus.js +2 -28
  470. package/dist/tools/bridgeStatus.js.map +1 -1
  471. package/dist/tools/cancelClaudeTask.d.ts +1 -0
  472. package/dist/tools/clipboard.d.ts +2 -0
  473. package/dist/tools/closeTabs.d.ts +1 -0
  474. package/dist/tools/codeLens.d.ts +1 -0
  475. package/dist/tools/createIssueFromAIComment.d.ts +1 -0
  476. package/dist/tools/ctxGetTaskContext.d.ts +9 -0
  477. package/dist/tools/ctxGetTaskContext.js +50 -2
  478. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  479. package/dist/tools/ctxQueryTraces.js +32 -24
  480. package/dist/tools/ctxQueryTraces.js.map +1 -1
  481. package/dist/tools/ctxSaveTrace.d.ts +1 -0
  482. package/dist/tools/debug.d.ts +4 -0
  483. package/dist/tools/decorations.d.ts +2 -0
  484. package/dist/tools/detectUnusedCode.js +9 -7
  485. package/dist/tools/detectUnusedCode.js.map +1 -1
  486. package/dist/tools/documentLinks.d.ts +1 -0
  487. package/dist/tools/editText.d.ts +1 -0
  488. package/dist/tools/editText.js +2 -1
  489. package/dist/tools/editText.js.map +1 -1
  490. package/dist/tools/enrichCommit.d.ts +1 -0
  491. package/dist/tools/enrichStackTrace.js +11 -5
  492. package/dist/tools/enrichStackTrace.js.map +1 -1
  493. package/dist/tools/explainDiagnostic.d.ts +1 -0
  494. package/dist/tools/explainSymbol.d.ts +1 -0
  495. package/dist/tools/fileOperations.d.ts +3 -0
  496. package/dist/tools/fileOperations.js +2 -1
  497. package/dist/tools/fileOperations.js.map +1 -1
  498. package/dist/tools/fileWatcher.d.ts +2 -0
  499. package/dist/tools/fileWatcher.js +8 -2
  500. package/dist/tools/fileWatcher.js.map +1 -1
  501. package/dist/tools/findFiles.d.ts +1 -0
  502. package/dist/tools/fixAllLintErrors.d.ts +1 -0
  503. package/dist/tools/fixAllLintErrors.js +10 -5
  504. package/dist/tools/fixAllLintErrors.js.map +1 -1
  505. package/dist/tools/foldingRanges.d.ts +1 -0
  506. package/dist/tools/formatDocument.d.ts +1 -0
  507. package/dist/tools/formatDocument.js +10 -5
  508. package/dist/tools/formatDocument.js.map +1 -1
  509. package/dist/tools/generateTests.d.ts +1 -0
  510. package/dist/tools/getAIComments.d.ts +1 -0
  511. package/dist/tools/getAnalyticsReport.js +5 -1
  512. package/dist/tools/getAnalyticsReport.js.map +1 -1
  513. package/dist/tools/getBufferContent.d.ts +1 -0
  514. package/dist/tools/getChangeImpact.d.ts +1 -0
  515. package/dist/tools/getChangeImpact.js +23 -14
  516. package/dist/tools/getChangeImpact.js.map +1 -1
  517. package/dist/tools/getClaudeTaskStatus.d.ts +1 -0
  518. package/dist/tools/getCodeCoverage.d.ts +1 -0
  519. package/dist/tools/getCodeCoverage.js +32 -14
  520. package/dist/tools/getCodeCoverage.js.map +1 -1
  521. package/dist/tools/getCommitsForIssue.d.ts +1 -0
  522. package/dist/tools/getDebugState.d.ts +1 -0
  523. package/dist/tools/getDiagnostics.js +32 -29
  524. package/dist/tools/getDiagnostics.js.map +1 -1
  525. package/dist/tools/getDiffFromHandoff.js +8 -2
  526. package/dist/tools/getDiffFromHandoff.js.map +1 -1
  527. package/dist/tools/getDocumentSymbols.d.ts +1 -0
  528. package/dist/tools/getGitHotspots.d.ts +1 -0
  529. package/dist/tools/getImportedSignatures.d.ts +1 -0
  530. package/dist/tools/getImportedSignatures.js +18 -14
  531. package/dist/tools/getImportedSignatures.js.map +1 -1
  532. package/dist/tools/getPRTemplate.d.ts +1 -0
  533. package/dist/tools/getProjectContext.js +23 -10
  534. package/dist/tools/getProjectContext.js.map +1 -1
  535. package/dist/tools/getSymbolHistory.d.ts +1 -0
  536. package/dist/tools/getToolCapabilities.d.ts +10 -5
  537. package/dist/tools/getToolCapabilities.js +79 -202
  538. package/dist/tools/getToolCapabilities.js.map +1 -1
  539. package/dist/tools/getTypeSignature.d.ts +1 -0
  540. package/dist/tools/getWorkspaceSettings.d.ts +1 -0
  541. package/dist/tools/gitWrite.d.ts +11 -0
  542. package/dist/tools/github/actions.d.ts +2 -0
  543. package/dist/tools/github/composite.d.ts +3 -0
  544. package/dist/tools/github/issues.d.ts +4 -0
  545. package/dist/tools/github/pr.d.ts +7 -0
  546. package/dist/tools/handoffNote.d.ts +1 -0
  547. package/dist/tools/handoffNote.js +2 -1
  548. package/dist/tools/handoffNote.js.map +1 -1
  549. package/dist/tools/headless/lspClient.js +3 -0
  550. package/dist/tools/headless/lspClient.js.map +1 -1
  551. package/dist/tools/hoverAtCursor.d.ts +1 -0
  552. package/dist/tools/httpClient.d.ts +2 -0
  553. package/dist/tools/httpClient.js +38 -71
  554. package/dist/tools/httpClient.js.map +1 -1
  555. package/dist/tools/inlayHints.d.ts +1 -0
  556. package/dist/tools/launchQuickTask.d.ts +1 -0
  557. package/dist/tools/listClaudeTasks.d.ts +1 -0
  558. package/dist/tools/listClaudeTasks.js +10 -8
  559. package/dist/tools/listClaudeTasks.js.map +1 -1
  560. package/dist/tools/listTerminals.d.ts +1 -0
  561. package/dist/tools/lsp.d.ts +15 -0
  562. package/dist/tools/lsp.js +17 -0
  563. package/dist/tools/lsp.js.map +1 -1
  564. package/dist/tools/navigateToSymbolByName.d.ts +1 -0
  565. package/dist/tools/openDiff.d.ts +1 -0
  566. package/dist/tools/openDiff.js +4 -1
  567. package/dist/tools/openDiff.js.map +1 -1
  568. package/dist/tools/openFile.d.ts +1 -0
  569. package/dist/tools/openFile.js +4 -1
  570. package/dist/tools/openFile.js.map +1 -1
  571. package/dist/tools/openInBrowser.js +6 -1
  572. package/dist/tools/openInBrowser.js.map +1 -1
  573. package/dist/tools/organizeImports.d.ts +1 -0
  574. package/dist/tools/organizeImports.js +5 -3
  575. package/dist/tools/organizeImports.js.map +1 -1
  576. package/dist/tools/performanceReport.js +5 -3
  577. package/dist/tools/performanceReport.js.map +1 -1
  578. package/dist/tools/planPersistence.d.ts +3 -0
  579. package/dist/tools/planPersistence.js +4 -1
  580. package/dist/tools/planPersistence.js.map +1 -1
  581. package/dist/tools/previewEdit.d.ts +1 -0
  582. package/dist/tools/previewEdit.js +15 -4
  583. package/dist/tools/previewEdit.js.map +1 -1
  584. package/dist/tools/recentTracesDigest.js +54 -11
  585. package/dist/tools/recentTracesDigest.js.map +1 -1
  586. package/dist/tools/refactorAnalyze.d.ts +1 -0
  587. package/dist/tools/refactorExtractFunction.js +4 -1
  588. package/dist/tools/refactorExtractFunction.js.map +1 -1
  589. package/dist/tools/refactorPreview.d.ts +1 -0
  590. package/dist/tools/refactorPreview.js +10 -2
  591. package/dist/tools/refactorPreview.js.map +1 -1
  592. package/dist/tools/replaceBlock.d.ts +1 -0
  593. package/dist/tools/replaceBlock.js +2 -1
  594. package/dist/tools/replaceBlock.js.map +1 -1
  595. package/dist/tools/resumeClaudeTask.d.ts +1 -0
  596. package/dist/tools/runClaudeTask.d.ts +1 -0
  597. package/dist/tools/runCommand.js +5 -0
  598. package/dist/tools/runCommand.js.map +1 -1
  599. package/dist/tools/runTests.js +15 -4
  600. package/dist/tools/runTests.js.map +1 -1
  601. package/dist/tools/screenshot.d.ts +1 -0
  602. package/dist/tools/screenshotAndAnnotate.js +6 -2
  603. package/dist/tools/screenshotAndAnnotate.js.map +1 -1
  604. package/dist/tools/searchAndReplace.d.ts +1 -0
  605. package/dist/tools/searchAndReplace.js +17 -7
  606. package/dist/tools/searchAndReplace.js.map +1 -1
  607. package/dist/tools/searchTools.js +20 -19
  608. package/dist/tools/searchTools.js.map +1 -1
  609. package/dist/tools/searchWorkspace.d.ts +1 -0
  610. package/dist/tools/selectionRanges.d.ts +1 -0
  611. package/dist/tools/semanticTokens.d.ts +1 -0
  612. package/dist/tools/signatureHelp.d.ts +1 -0
  613. package/dist/tools/spawnWorkspace.js +15 -7
  614. package/dist/tools/spawnWorkspace.js.map +1 -1
  615. package/dist/tools/terminal.d.ts +6 -0
  616. package/dist/tools/terminal.js +4 -0
  617. package/dist/tools/terminal.js.map +1 -1
  618. package/dist/tools/testRunners/pytest.js +6 -2
  619. package/dist/tools/testRunners/pytest.js.map +1 -1
  620. package/dist/tools/testRunners/vitestJest.js +3 -1
  621. package/dist/tools/testRunners/vitestJest.js.map +1 -1
  622. package/dist/tools/testTraceToSource.d.ts +1 -0
  623. package/dist/tools/transaction.d.ts +4 -0
  624. package/dist/tools/transaction.js +4 -1
  625. package/dist/tools/transaction.js.map +1 -1
  626. package/dist/tools/typeHierarchy.d.ts +1 -0
  627. package/dist/tools/utils.d.ts +22 -0
  628. package/dist/tools/utils.js +158 -14
  629. package/dist/tools/utils.js.map +1 -1
  630. package/dist/tools/vscodeCommands.d.ts +2 -0
  631. package/dist/tools/vscodeTasks.d.ts +2 -0
  632. package/dist/tools/workspaceSettings.d.ts +1 -0
  633. package/dist/transport.d.ts +3 -1
  634. package/dist/transport.js +103 -52
  635. package/dist/transport.js.map +1 -1
  636. package/dist/winShim.d.ts +34 -0
  637. package/dist/winShim.js +94 -0
  638. package/dist/winShim.js.map +1 -0
  639. package/dist/wireHaltPushDispatch.d.ts +38 -0
  640. package/dist/wireHaltPushDispatch.js +71 -0
  641. package/dist/wireHaltPushDispatch.js.map +1 -0
  642. package/dist/writeFileAtomic.d.ts +23 -0
  643. package/dist/writeFileAtomic.js +121 -0
  644. package/dist/writeFileAtomic.js.map +1 -0
  645. package/package.json +23 -7
  646. package/scripts/postinstall.mjs +42 -2
  647. package/scripts/smoke/run-all.mjs +213 -0
  648. package/scripts/start-all.mjs +572 -0
  649. package/scripts/start-all.ps1 +209 -0
  650. package/scripts/start-all.sh +77 -19
  651. package/scripts/start-orchestrator.ps1 +158 -0
  652. package/scripts/start-remote.mjs +122 -0
  653. package/templates/automation-policies/recipe-authoring.json +1 -1
  654. package/templates/automation-policies/security-first.json +1 -1
  655. package/templates/automation-policies/strict-lint.json +1 -1
  656. package/templates/automation-policies/test-driven.json +1 -1
  657. package/templates/automation-policy.example.json +1 -1
  658. package/templates/co.patchwork-os.bridge.plist +2 -2
  659. package/templates/recipes/approval-queue-ui-test.yaml +205 -0
  660. package/templates/recipes/ctx-loop-test.yaml +1 -1
  661. package/templates/recipes/fix-errors-on-save.yaml +71 -0
  662. package/templates/recipes/morning-brief.yaml +5 -2
  663. package/templates/recipes/project-health-check.yaml +4 -1
  664. package/templates/recipes/sentry-to-linear.yaml +72 -38
  665. package/templates/recipes/webhook/apple-watch-health-log.yaml +145 -0
  666. package/templates/recipes/webhook/customer-escalation.yaml +8 -9
  667. package/templates/recipes/webhook/meeting-prep.yaml +11 -5
  668. package/dist/commands/marketplace.d.ts +0 -11
  669. package/dist/commands/marketplace.js +0 -120
  670. package/dist/commands/marketplace.js.map +0 -1
  671. package/dist/recipes/legacyRecipeCompat.d.ts +0 -10
  672. package/dist/recipes/legacyRecipeCompat.js +0 -131
  673. package/dist/recipes/legacyRecipeCompat.js.map +0 -1
package/dist/fileLock.js CHANGED
@@ -39,10 +39,12 @@ export class FileLock {
39
39
  if (holder !== sessionId) {
40
40
  return { lockedBySession: holder };
41
41
  }
42
- // Same session already holds the lock grant re-entry. The new promise
43
- // chains behind the existing one; the caller gets its own release handle.
42
+ // Same-session re-entry: return a no-op release so we don't overwrite
43
+ // the live lock-tail promise, which would break the FIFO chain for any
44
+ // subsequent acquire() caller that chains behind it.
45
+ return { release: () => { } };
44
46
  }
45
- // Lock is free (or same-session re-entry) — grant it synchronously.
47
+ // Lock is free — grant it synchronously.
46
48
  let release;
47
49
  const next = new Promise((r) => {
48
50
  release = r;
@@ -81,18 +83,23 @@ export class FileLock {
81
83
  await Promise.race([prev, timeout]);
82
84
  clearTimeout(timeoutId);
83
85
  if (timedOut) {
84
- // Resolve next before throwing so any waiter chained behind us is not
85
- // blocked for another full timeout cycle they get the lock immediately
86
- // (even though we do no work) and proceed normally.
87
- release();
88
- if (this.locks.get(path) === next)
89
- this.locks.delete(path);
86
+ // Bridge: resolve our slot only after the previous holder actually
87
+ // releases, so any waiter already chained behind us (awaiting `next`)
88
+ // gets the lock in FIFO order rather than immediately.
89
+ // Do NOT delete locks[path] here — the bridge needs it to stay so
90
+ // a new caller who arrives before prev resolves chains correctly.
91
+ void prev.then(() => {
92
+ release();
93
+ if (this.locks.get(path) === next)
94
+ this.locks.delete(path);
95
+ });
90
96
  throw new Error(`Timed out waiting for file lock on "${path}" after ${this.timeoutMs / 1000}s — another session may be editing the same file`);
91
97
  }
92
98
  }
93
99
  catch (err) {
94
100
  clearTimeout(timeoutId);
95
- if (this.locks.get(path) === next)
101
+ // Do not delete the lock when timedOut — the bridge above will clean up.
102
+ if (!timedOut && this.locks.get(path) === next)
96
103
  this.locks.delete(path);
97
104
  throw err;
98
105
  }
@@ -103,13 +110,15 @@ export class FileLock {
103
110
  this.locks.delete(path);
104
111
  throw new Error("Aborted before lock acquired");
105
112
  }
106
- // Clean up map entry after release so it doesn't grow forever
113
+ // Clean up map entry after release so it doesn't grow forever.
114
+ // acquire() does not own the holders map (only tryAcquire writes it),
115
+ // so we must not unconditionally delete a holders entry that a
116
+ // concurrent tryAcquire may have written.
107
117
  const wrappedRelease = () => {
108
118
  signal?.removeEventListener("abort", onAbort);
109
119
  release();
110
120
  if (this.locks.get(path) === next)
111
121
  this.locks.delete(path);
112
- this.holders.delete(path);
113
122
  };
114
123
  // If the holder is aborted while holding the lock, release automatically
115
124
  // so downstream waiters are not blocked for the full timeout period.
@@ -1 +1 @@
1
- {"version":3,"file":"fileLock.js","sourceRoot":"","sources":["../src/fileLock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fileLock.js","sourceRoot":"","sources":["../src/fileLock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Tiny cross-process file mutex for synchronous critical sections.
3
+ *
4
+ * Used to wrap append-only JSONL writers (`decisionTraceLog`,
5
+ * `runLog`, `commitIssueLinkLog`) so two bridge processes sharing
6
+ * one `~/.claude/ide/` log directory can't interleave bytes within a
7
+ * single row.
8
+ *
9
+ * Why ad-hoc instead of `proper-lockfile`? proper-lockfile is the more
10
+ * featureful option (TTL refresh, retry jitter, async API) but adds a
11
+ * runtime dependency for a use case the bridge needs only synchronously
12
+ * in three call-sites. The pattern below — `openSync(file, "wx")` as
13
+ * the atomic lock primitive plus a stale-lock cleanup heuristic — is
14
+ * standard for shell-style flock without a native binding.
15
+ *
16
+ * ## Semantics
17
+ *
18
+ * `withFileLockSync(file, fn)`:
19
+ *
20
+ * 1. Attempts to create `${file}.lock` with `O_EXCL` (`flag: "wx"`).
21
+ * First writer wins atomically — the kernel rejects EEXIST for
22
+ * every other contender.
23
+ * 2. On EEXIST, polls with a short busy-wait (`Atomics.wait` would
24
+ * need a shared SharedArrayBuffer across processes — out of scope;
25
+ * hot-loop with `process.hrtime` instead, kernels schedule sleep
26
+ * anyway under contention).
27
+ * 3. If the existing lock is older than `staleLockMs` (default 30s),
28
+ * assumes the owner crashed and force-unlinks it before retrying.
29
+ * The append-only JSONL writes the bridge does complete in <1ms in
30
+ * practice, so 30s is generous.
31
+ * 4. Runs `fn()`, unlinks the lock in `finally`. Rethrows fn's
32
+ * exception.
33
+ *
34
+ * Lock granularity is per-file (each log gets its own lock). At the
35
+ * bridge's write volume (≤ tens/min across all three logs) contention
36
+ * is effectively zero.
37
+ *
38
+ * ## Failure modes
39
+ *
40
+ * - **Deadlock-on-crash:** mitigated by the 30s stale-lock TTL. A bridge
41
+ * that crashes mid-append leaves the lock until the next contender
42
+ * notices it's stale and clears it. The first crash is invisible
43
+ * (target file already written); subsequent contenders pay a 30s
44
+ * penalty only if they happen to arrive within the window.
45
+ * - **TOCTOU on stale-lock unlink:** two processes both decide the lock
46
+ * is stale and both `unlinkSync`. Second `unlinkSync` ENOENT is
47
+ * swallowed. Both then race the `openSync("wx")` — one wins, the
48
+ * other goes back to polling. No data corruption.
49
+ * - **NFS / non-POSIX FS:** O_EXCL is undefined on stale NFSv2; modern
50
+ * NFS (≥ v3 with `noac`) and all local FS we ship on (apfs / ext4 /
51
+ * ntfs) implement it correctly.
52
+ *
53
+ * @param file - The target file the caller is about to write. The lock
54
+ * sentinel is `${file}.lock`.
55
+ * @param fn - Synchronous critical section. Holds the lock for its
56
+ * entire duration.
57
+ * @param opts.timeoutMs - Max wait for the lock before throwing (default
58
+ * 5000). Use a small value — appends finish in <1ms in practice; a
59
+ * timeout this far above the expected duration only fires if
60
+ * something genuinely wrong happens.
61
+ * @param opts.staleLockMs - Age (ms) at which an existing lock is
62
+ * considered abandoned and force-unlinked. Default 30000.
63
+ */
64
+ export declare function withFileLockSync<T>(file: string, fn: () => T, opts?: {
65
+ timeoutMs?: number;
66
+ staleLockMs?: number;
67
+ }): T;
@@ -0,0 +1,126 @@
1
+ import { closeSync, openSync, statSync, unlinkSync } from "node:fs";
2
+ /**
3
+ * Tiny cross-process file mutex for synchronous critical sections.
4
+ *
5
+ * Used to wrap append-only JSONL writers (`decisionTraceLog`,
6
+ * `runLog`, `commitIssueLinkLog`) so two bridge processes sharing
7
+ * one `~/.claude/ide/` log directory can't interleave bytes within a
8
+ * single row.
9
+ *
10
+ * Why ad-hoc instead of `proper-lockfile`? proper-lockfile is the more
11
+ * featureful option (TTL refresh, retry jitter, async API) but adds a
12
+ * runtime dependency for a use case the bridge needs only synchronously
13
+ * in three call-sites. The pattern below — `openSync(file, "wx")` as
14
+ * the atomic lock primitive plus a stale-lock cleanup heuristic — is
15
+ * standard for shell-style flock without a native binding.
16
+ *
17
+ * ## Semantics
18
+ *
19
+ * `withFileLockSync(file, fn)`:
20
+ *
21
+ * 1. Attempts to create `${file}.lock` with `O_EXCL` (`flag: "wx"`).
22
+ * First writer wins atomically — the kernel rejects EEXIST for
23
+ * every other contender.
24
+ * 2. On EEXIST, polls with a short busy-wait (`Atomics.wait` would
25
+ * need a shared SharedArrayBuffer across processes — out of scope;
26
+ * hot-loop with `process.hrtime` instead, kernels schedule sleep
27
+ * anyway under contention).
28
+ * 3. If the existing lock is older than `staleLockMs` (default 30s),
29
+ * assumes the owner crashed and force-unlinks it before retrying.
30
+ * The append-only JSONL writes the bridge does complete in <1ms in
31
+ * practice, so 30s is generous.
32
+ * 4. Runs `fn()`, unlinks the lock in `finally`. Rethrows fn's
33
+ * exception.
34
+ *
35
+ * Lock granularity is per-file (each log gets its own lock). At the
36
+ * bridge's write volume (≤ tens/min across all three logs) contention
37
+ * is effectively zero.
38
+ *
39
+ * ## Failure modes
40
+ *
41
+ * - **Deadlock-on-crash:** mitigated by the 30s stale-lock TTL. A bridge
42
+ * that crashes mid-append leaves the lock until the next contender
43
+ * notices it's stale and clears it. The first crash is invisible
44
+ * (target file already written); subsequent contenders pay a 30s
45
+ * penalty only if they happen to arrive within the window.
46
+ * - **TOCTOU on stale-lock unlink:** two processes both decide the lock
47
+ * is stale and both `unlinkSync`. Second `unlinkSync` ENOENT is
48
+ * swallowed. Both then race the `openSync("wx")` — one wins, the
49
+ * other goes back to polling. No data corruption.
50
+ * - **NFS / non-POSIX FS:** O_EXCL is undefined on stale NFSv2; modern
51
+ * NFS (≥ v3 with `noac`) and all local FS we ship on (apfs / ext4 /
52
+ * ntfs) implement it correctly.
53
+ *
54
+ * @param file - The target file the caller is about to write. The lock
55
+ * sentinel is `${file}.lock`.
56
+ * @param fn - Synchronous critical section. Holds the lock for its
57
+ * entire duration.
58
+ * @param opts.timeoutMs - Max wait for the lock before throwing (default
59
+ * 5000). Use a small value — appends finish in <1ms in practice; a
60
+ * timeout this far above the expected duration only fires if
61
+ * something genuinely wrong happens.
62
+ * @param opts.staleLockMs - Age (ms) at which an existing lock is
63
+ * considered abandoned and force-unlinked. Default 30000.
64
+ */
65
+ export function withFileLockSync(file, fn, opts = {}) {
66
+ const lockFile = `${file}.lock`;
67
+ const timeoutMs = opts.timeoutMs ?? 5000;
68
+ const staleLockMs = opts.staleLockMs ?? 30_000;
69
+ const deadline = Date.now() + timeoutMs;
70
+ let lockFd = null;
71
+ while (lockFd === null) {
72
+ try {
73
+ // O_EXCL — atomic create; first caller wins.
74
+ lockFd = openSync(lockFile, "wx", 0o600);
75
+ }
76
+ catch (err) {
77
+ const code = err.code;
78
+ if (code !== "EEXIST")
79
+ throw err;
80
+ // Stale-lock cleanup. Best-effort: another contender may unlink
81
+ // ours simultaneously; that race resolves benignly (next openSync
82
+ // either wins or sees EEXIST again).
83
+ try {
84
+ const stat = statSync(lockFile);
85
+ if (Date.now() - stat.mtimeMs > staleLockMs) {
86
+ try {
87
+ unlinkSync(lockFile);
88
+ }
89
+ catch {
90
+ /* already gone — another contender beat us to the cleanup */
91
+ }
92
+ continue;
93
+ }
94
+ }
95
+ catch {
96
+ // statSync ENOENT — lock cleared between EEXIST and stat; retry
97
+ // immediately.
98
+ continue;
99
+ }
100
+ if (Date.now() > deadline) {
101
+ throw new Error(`withFileLockSync: timed out after ${timeoutMs}ms waiting for ${lockFile}`);
102
+ }
103
+ // Busy-spin for ~5ms via hrtime. Node has no sync sleep; under
104
+ // contention the kernel preempts us, so this isn't actually a hot
105
+ // loop in practice (and tests can pass a 0ms timeout for the
106
+ // "already locked" case).
107
+ const spinUntil = process.hrtime.bigint() + 5000000n; // 5ms
108
+ while (process.hrtime.bigint() < spinUntil) {
109
+ /* yield */
110
+ }
111
+ }
112
+ }
113
+ try {
114
+ closeSync(lockFd);
115
+ return fn();
116
+ }
117
+ finally {
118
+ try {
119
+ unlinkSync(lockFile);
120
+ }
121
+ catch {
122
+ /* lock cleared by stale-lock cleanup in another process; ok */
123
+ }
124
+ }
125
+ }
126
+ //# sourceMappingURL=fileLockSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileLockSync.js","sourceRoot":"","sources":["../src/fileLockSync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,EAAW,EACX,OAAqD,EAAE;IAEvD,MAAM,QAAQ,GAAG,GAAG,IAAI,OAAO,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAExC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,OAAO,MAAM,KAAK,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,6CAA6C;YAC7C,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,IAAI,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;YACjC,gEAAgE;YAChE,kEAAkE;YAClE,qCAAqC;YACrC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAChC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC;oBAC5C,IAAI,CAAC;wBACH,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACvB,CAAC;oBAAC,MAAM,CAAC;wBACP,6DAA6D;oBAC/D,CAAC;oBACD,SAAS;gBACX,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,gEAAgE;gBAChE,eAAe;gBACf,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACb,qCAAqC,SAAS,kBAAkB,QAAQ,EAAE,CAC3E,CAAC;YACJ,CAAC;YACD,+DAA+D;YAC/D,kEAAkE;YAClE,6DAA6D;YAC7D,0BAA0B;YAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,QAAU,CAAC,CAAC,MAAM;YAC9D,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;gBAC3C,WAAW;YACb,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;QACjE,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -3,12 +3,15 @@ const CO_OCCURRENCE_MAP_CAP = 200;
3
3
  export function computeStats(entries) {
4
4
  const map = new Map();
5
5
  for (const entry of entries) {
6
- const s = map.get(entry.tool) ?? { count: 0, totalMs: 0, errors: 0 };
6
+ let s = map.get(entry.tool);
7
+ if (!s) {
8
+ s = { count: 0, totalMs: 0, errors: 0 };
9
+ map.set(entry.tool, s);
10
+ }
7
11
  s.count++;
8
12
  s.totalMs += entry.durationMs;
9
13
  if (entry.status === "error")
10
14
  s.errors++;
11
- map.set(entry.tool, s);
12
15
  }
13
16
  const result = {};
14
17
  for (const [tool, s] of map) {
@@ -53,17 +56,21 @@ export function computePercentiles(samples) {
53
56
  export function computeCoOccurrence(entries, windowMs, maxPairs = 50) {
54
57
  const counts = new Map();
55
58
  const n = entries.length;
59
+ // Pre-compute epoch timestamps once to avoid repeated Date construction in nested loop.
60
+ const times = new Array(n);
61
+ for (let k = 0; k < n; k++) {
62
+ times[k] = Date.parse(entries[k]?.timestamp ?? "");
63
+ }
56
64
  for (let i = 0; i < n; i++) {
57
65
  const a = entries[i];
58
66
  if (!a)
59
67
  continue;
60
- const tA = new Date(a.timestamp).getTime();
68
+ const tA = times[i] ?? 0;
61
69
  for (let j = i + 1; j < n; j++) {
62
70
  const b = entries[j];
63
71
  if (!b)
64
72
  continue;
65
- const tB = new Date(b.timestamp).getTime();
66
- if (tB - tA > windowMs)
73
+ if ((times[j] ?? 0) - tA > windowMs)
67
74
  break;
68
75
  if (a.tool === b.tool)
69
76
  continue;
@@ -73,10 +80,14 @@ export function computeCoOccurrence(entries, windowMs, maxPairs = 50) {
73
80
  counts.set(key, (counts.get(key) ?? 0) + 1);
74
81
  }
75
82
  }
76
- return [...counts.entries()]
77
- .map(([pair, count]) => ({ pair, count }))
78
- .sort((a, b) => b.count - a.count)
79
- .slice(0, maxPairs);
83
+ const pairs = Array.from(counts.entries());
84
+ pairs.sort((a, b) => b[1] - a[1]);
85
+ const result = [];
86
+ for (let i = 0; i < pairs.length && i < maxPairs; i++) {
87
+ const [pair, count] = pairs[i];
88
+ result.push({ pair, count });
89
+ }
90
+ return result;
80
91
  }
81
92
  /**
82
93
  * Per-tool stats within a sliding time window.
@@ -89,14 +100,17 @@ export function computeWindowedStats(entries, windowMs, now) {
89
100
  const e = entries[i];
90
101
  if (!e)
91
102
  continue;
92
- if (new Date(e.timestamp).getTime() < cutoff)
103
+ if (Date.parse(e.timestamp) < cutoff)
93
104
  break;
94
- const s = map.get(e.tool) ?? { count: 0, totalMs: 0, errors: 0 };
105
+ let s = map.get(e.tool);
106
+ if (!s) {
107
+ s = { count: 0, totalMs: 0, errors: 0 };
108
+ map.set(e.tool, s);
109
+ }
95
110
  s.count++;
96
111
  s.totalMs += e.durationMs;
97
112
  if (e.status === "error")
98
113
  s.errors++;
99
- map.set(e.tool, s);
100
114
  }
101
115
  const result = {};
102
116
  for (const [tool, s] of map) {
@@ -1 +1 @@
1
- {"version":3,"file":"activityAnalytics.js","sourceRoot":"","sources":["../../src/fp/activityAnalytics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"activityAnalytics.js","sourceRoot":"","sources":["../../src/fp/activityAnalytics.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,12 @@ import { type ToolResult } from "./result.js";
10
10
  /**
11
11
  * Returns true if `value` matches the condition pattern.
12
12
  * Negation via "!" prefix. Missing pattern → always true.
13
+ *
14
+ * On Windows, file paths arrive as `C:\Users\foo\src\bar.ts` while users
15
+ * write POSIX-style globs (`src/**\/*.ts`). minimatch is strict on `/` and
16
+ * NTFS is case-insensitive, so without normalisation onFileSave/onFileChanged
17
+ * hooks silently never fire on Windows. Normalise backslashes to forward
18
+ * slashes on both sides and pass `nocase` on win32.
13
19
  */
14
20
  export declare function matchesCondition(pattern: string | undefined, value: string): boolean;
15
21
  /**
@@ -25,7 +31,13 @@ export declare function primaryValue(hookType: HookType, eventData: Readonly<Rec
25
31
  * Resolve a PromptSourceNode to a string.
26
32
  * For named prompts, calls getPrompt() and concatenates user messages.
27
33
  * Returns null if a named prompt cannot be resolved (unknown name / missing args).
34
+ *
35
+ * When `source.kind === "none"`, returns the symbol `NO_PROMPT` so callers
36
+ * can distinguish "no inline prompt configured" (webhook-only hook) from
37
+ * "named prompt failed to resolve" (skip silently).
28
38
  */
39
+ export declare const NO_PROMPT: unique symbol;
40
+ export type ResolvedPrompt = string | null | typeof NO_PROMPT;
29
41
  export declare function resolvePromptSource(source: {
30
42
  kind: "inline";
31
43
  prompt: string;
@@ -33,5 +45,7 @@ export declare function resolvePromptSource(source: {
33
45
  kind: "named";
34
46
  promptName: string;
35
47
  promptArgs?: Record<string, string>;
36
- }, eventData: Readonly<Record<string, string>>): string | null;
48
+ } | {
49
+ kind: "none";
50
+ }, eventData: Readonly<Record<string, string>>): ResolvedPrompt;
37
51
  export declare function executeAutomationPolicy(programs: AutomationProgram[], ctx: InterpreterContext): Promise<ToolResult<InterpreterResult>>;