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
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Watch a directory for any change, falling back to mtime polling when
3
+ * `fs.watch` is unavailable or fails.
4
+ *
5
+ * Motivation: `fs.watch` is unreliable on several real-world filesystems —
6
+ * Windows network drives (SMB/CIFS), WSL bind mounts, and macOS volumes
7
+ * mounted from a Linux host all either throw at watch time or stop firing
8
+ * events silently mid-session. The bridge's plugin hot-reload and kill-
9
+ * switch flag watcher silently went dead on those mounts.
10
+ *
11
+ * Behaviour:
12
+ * - First try `fs.watch(dir, { recursive: false })`. If it succeeds, also
13
+ * listen for the watcher's `error` event so a mid-session breakdown
14
+ * swaps to polling without losing change notifications.
15
+ * - If `fs.watch` throws (e.g. ENOENT — the directory doesn't exist yet,
16
+ * or EPERM — the filesystem doesn't support watching), start polling
17
+ * immediately.
18
+ * - Polling: stat the directory every `pollIntervalMs` (default 2000ms)
19
+ * and stat each non-dot file in it. Fire `onChange` if any file's
20
+ * mtime advanced, a file appeared, or a file disappeared. If the
21
+ * directory itself is missing, keep polling — it may appear later.
22
+ *
23
+ * Caller filters changes by re-reading the file(s) of interest. The helper
24
+ * deliberately does NOT expose the changed filename: polling can't reliably
25
+ * provide that, and fs.watch filenames are already null on some platforms
26
+ * (Windows rename events, atomic saves). One source of truth keeps callers
27
+ * platform-agnostic.
28
+ *
29
+ * Returns a `stop()` function that releases both the watcher and the timer.
30
+ */
31
+ export declare function watchDirectoryWithFallback(dir: string, onChange: () => void, opts?: {
32
+ pollIntervalMs?: number;
33
+ logger?: {
34
+ warn: (msg: string) => void;
35
+ } | undefined;
36
+ }): () => void;
@@ -0,0 +1,128 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ /**
4
+ * Watch a directory for any change, falling back to mtime polling when
5
+ * `fs.watch` is unavailable or fails.
6
+ *
7
+ * Motivation: `fs.watch` is unreliable on several real-world filesystems —
8
+ * Windows network drives (SMB/CIFS), WSL bind mounts, and macOS volumes
9
+ * mounted from a Linux host all either throw at watch time or stop firing
10
+ * events silently mid-session. The bridge's plugin hot-reload and kill-
11
+ * switch flag watcher silently went dead on those mounts.
12
+ *
13
+ * Behaviour:
14
+ * - First try `fs.watch(dir, { recursive: false })`. If it succeeds, also
15
+ * listen for the watcher's `error` event so a mid-session breakdown
16
+ * swaps to polling without losing change notifications.
17
+ * - If `fs.watch` throws (e.g. ENOENT — the directory doesn't exist yet,
18
+ * or EPERM — the filesystem doesn't support watching), start polling
19
+ * immediately.
20
+ * - Polling: stat the directory every `pollIntervalMs` (default 2000ms)
21
+ * and stat each non-dot file in it. Fire `onChange` if any file's
22
+ * mtime advanced, a file appeared, or a file disappeared. If the
23
+ * directory itself is missing, keep polling — it may appear later.
24
+ *
25
+ * Caller filters changes by re-reading the file(s) of interest. The helper
26
+ * deliberately does NOT expose the changed filename: polling can't reliably
27
+ * provide that, and fs.watch filenames are already null on some platforms
28
+ * (Windows rename events, atomic saves). One source of truth keeps callers
29
+ * platform-agnostic.
30
+ *
31
+ * Returns a `stop()` function that releases both the watcher and the timer.
32
+ */
33
+ export function watchDirectoryWithFallback(dir, onChange, opts = {}) {
34
+ const pollIntervalMs = opts.pollIntervalMs ?? 2000;
35
+ const logger = opts.logger;
36
+ let watcher = null;
37
+ let pollTimer = null;
38
+ let stopped = false;
39
+ // Snapshot: filename → mtimeMs. Empty Map when directory doesn't exist.
40
+ let snapshot = new Map();
41
+ const snapshotDir = () => {
42
+ const out = new Map();
43
+ try {
44
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
45
+ for (const ent of entries) {
46
+ if (!ent.isFile())
47
+ continue;
48
+ if (ent.name.startsWith("."))
49
+ continue;
50
+ try {
51
+ const st = fs.statSync(path.join(dir, ent.name));
52
+ out.set(ent.name, st.mtimeMs);
53
+ }
54
+ catch {
55
+ /* file disappeared between readdir and stat — ignore */
56
+ }
57
+ }
58
+ }
59
+ catch {
60
+ /* dir missing — empty snapshot */
61
+ }
62
+ return out;
63
+ };
64
+ const startPolling = (reason) => {
65
+ if (pollTimer || stopped)
66
+ return;
67
+ if (logger)
68
+ logger.warn(`[fs-watch] falling back to polling: ${reason}`);
69
+ snapshot = snapshotDir();
70
+ pollTimer = setInterval(() => {
71
+ if (stopped)
72
+ return;
73
+ const next = snapshotDir();
74
+ let changed = next.size !== snapshot.size;
75
+ if (!changed) {
76
+ for (const [name, mtime] of next) {
77
+ const prev = snapshot.get(name);
78
+ if (prev === undefined || prev !== mtime) {
79
+ changed = true;
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ snapshot = next;
85
+ if (changed)
86
+ onChange();
87
+ }, pollIntervalMs);
88
+ // Don't keep the event loop alive solely for polling.
89
+ pollTimer.unref?.();
90
+ };
91
+ try {
92
+ watcher = fs.watch(dir, { recursive: false }, () => {
93
+ if (!stopped)
94
+ onChange();
95
+ });
96
+ watcher.on("error", (err) => {
97
+ // Watcher broke mid-session. Tear it down, start polling.
98
+ try {
99
+ watcher?.close();
100
+ }
101
+ catch {
102
+ /* ignore */
103
+ }
104
+ watcher = null;
105
+ startPolling(`watcher error: ${err.message}`);
106
+ });
107
+ }
108
+ catch (err) {
109
+ startPolling(`fs.watch threw: ${err instanceof Error ? err.message : String(err)}`);
110
+ }
111
+ return () => {
112
+ stopped = true;
113
+ if (watcher) {
114
+ try {
115
+ watcher.close();
116
+ }
117
+ catch {
118
+ /* ignore */
119
+ }
120
+ watcher = null;
121
+ }
122
+ if (pollTimer) {
123
+ clearInterval(pollTimer);
124
+ pollTimer = null;
125
+ }
126
+ };
127
+ }
128
+ //# sourceMappingURL=fsWatchWithFallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsWatchWithFallback.js","sourceRoot":"","sources":["../src/fsWatchWithFallback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Bridge → push relay dispatch for recipe halt events.
3
+ *
4
+ * Sibling of `dispatchPushNotification` in [src/approvalHttp.ts](./approvalHttp.ts).
5
+ * The bridge POSTs a halt payload to `${pushServiceUrl}/halt`; the relay
6
+ * (a hosted push service or the dashboard's `/api/relay/halt` route)
7
+ * fans it out to every subscribed browser via Web Push.
8
+ *
9
+ * SSRF guard mirrors the approval dispatcher: HTTPS-only, hostname
10
+ * blocklist (localhost / loopback / private IPs after DNS resolve),
11
+ * 5s abort timeout, fire-and-forget so the recipe runner is never
12
+ * blocked on a push relay outage.
13
+ *
14
+ * Wired via `wireHaltPushDispatch` (subscribes to ActivityLog) — keeps
15
+ * the runner itself ignorant of push transport.
16
+ */
17
+ export interface HaltPushPayload {
18
+ recipeName: string;
19
+ runSeq: number;
20
+ /** Always "error" or "halted" — the runner emits "error" today; the
21
+ * shape leaves room for the dashboard's halted/error distinction. */
22
+ status: "error" | "halted";
23
+ haltReason?: string;
24
+ haltCategory?: string;
25
+ stepId?: string;
26
+ errorMessage?: string;
27
+ occurredAt?: number;
28
+ }
29
+ /**
30
+ * Fire-and-forget dispatch. Never throws — caller cannot recover from a
31
+ * push relay outage. Logged via console.warn for ops visibility.
32
+ */
33
+ export declare function dispatchHaltPushNotification(pushServiceUrl: string, pushServiceToken: string, payload: HaltPushPayload): Promise<void>;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Bridge → push relay dispatch for recipe halt events.
3
+ *
4
+ * Sibling of `dispatchPushNotification` in [src/approvalHttp.ts](./approvalHttp.ts).
5
+ * The bridge POSTs a halt payload to `${pushServiceUrl}/halt`; the relay
6
+ * (a hosted push service or the dashboard's `/api/relay/halt` route)
7
+ * fans it out to every subscribed browser via Web Push.
8
+ *
9
+ * SSRF guard mirrors the approval dispatcher: HTTPS-only, hostname
10
+ * blocklist (localhost / loopback / private IPs after DNS resolve),
11
+ * 5s abort timeout, fire-and-forget so the recipe runner is never
12
+ * blocked on a push relay outage.
13
+ *
14
+ * Wired via `wireHaltPushDispatch` (subscribes to ActivityLog) — keeps
15
+ * the runner itself ignorant of push transport.
16
+ */
17
+ import dns from "node:dns/promises";
18
+ /**
19
+ * Same SSRF blocklist as `dispatchPushNotification` in approvalHttp.ts.
20
+ * Duplicated inline to keep this dispatcher self-contained (the
21
+ * approvalHttp version is module-private and the file is already
22
+ * dense). If a third dispatcher ever lands, extract to a shared
23
+ * `src/sanitizeIp.ts`.
24
+ */
25
+ function isBlockedIp(ip) {
26
+ if (ip === "::1" || ip === "0:0:0:0:0:0:0:1")
27
+ return true;
28
+ const parts = ip.split(".").map(Number);
29
+ if (parts.length !== 4)
30
+ return false;
31
+ const [a, b] = parts;
32
+ if (a === 127)
33
+ return true;
34
+ if (a === 10)
35
+ return true;
36
+ if (a === 172 && b >= 16 && b <= 31)
37
+ return true;
38
+ if (a === 192 && b === 168)
39
+ return true;
40
+ if (a === 169 && b === 254)
41
+ return true;
42
+ return false;
43
+ }
44
+ /**
45
+ * Fire-and-forget dispatch. Never throws — caller cannot recover from a
46
+ * push relay outage. Logged via console.warn for ops visibility.
47
+ */
48
+ export async function dispatchHaltPushNotification(pushServiceUrl, pushServiceToken, payload) {
49
+ if (!pushServiceUrl.startsWith("https://")) {
50
+ console.warn(`[halt-push] Rejected non-HTTPS push service URL`);
51
+ return;
52
+ }
53
+ let hostname;
54
+ try {
55
+ hostname = new URL(pushServiceUrl).hostname;
56
+ }
57
+ catch {
58
+ console.warn(`[halt-push] Malformed push service URL — skipping`);
59
+ return;
60
+ }
61
+ if (hostname === "localhost") {
62
+ console.warn(`[halt-push] Blocked loopback push service hostname`);
63
+ return;
64
+ }
65
+ try {
66
+ const resolved = await dns.lookup(hostname);
67
+ if (isBlockedIp(resolved.address)) {
68
+ console.warn(`[halt-push] Blocked private/loopback IP for push service: ${resolved.address}`);
69
+ return;
70
+ }
71
+ }
72
+ catch (err) {
73
+ console.warn(`[halt-push] DNS resolution failed for ${hostname}: ${err instanceof Error ? err.message : String(err)}`);
74
+ return;
75
+ }
76
+ const controller = new AbortController();
77
+ const timer = setTimeout(() => controller.abort(), 5_000);
78
+ try {
79
+ const res = await fetch(`${pushServiceUrl}/halt`, {
80
+ method: "POST",
81
+ headers: {
82
+ "Content-Type": "application/json",
83
+ Authorization: `Bearer ${pushServiceToken}`,
84
+ },
85
+ body: JSON.stringify(payload),
86
+ signal: controller.signal,
87
+ });
88
+ if (!res.ok) {
89
+ // 404 is informational ("no subscribers yet") — same relay
90
+ // contract as the approval path. Anything else is worth a warn.
91
+ if (res.status !== 404) {
92
+ console.warn(`[halt-push] Non-2xx from push relay: ${res.status} ${res.statusText}`);
93
+ }
94
+ }
95
+ }
96
+ catch (err) {
97
+ console.warn(`[halt-push] Dispatch failed: ${err instanceof Error ? err.message : String(err)}`);
98
+ }
99
+ finally {
100
+ clearTimeout(timer);
101
+ }
102
+ }
103
+ //# sourceMappingURL=haltPushDispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"haltPushDispatch.js","sourceRoot":"","sources":["../src/haltPushDispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Strict allow-list validation for HTTP request body keys.
3
+ *
4
+ * `readJsonBody<T>()` is type-erased at runtime — the generic only documents
5
+ * the EXPECTED shape; unknown top-level keys are silently kept on the parsed
6
+ * object and dropped by the handler's destructure. Misspelled fields
7
+ * (`enabledZ`, `targerName`, `vasr`) succeed as a no-op + 200, which masks
8
+ * client bugs and complicates dashboard debugging.
9
+ *
10
+ * This helper closes the silent-failure gap for the highest-value
11
+ * configuration endpoints (settings, telemetry, kill-switch, recipe run /
12
+ * promote / trust). Callers extract the body, run this check, and on
13
+ * failure return a 400 enumerating the unknown keys.
14
+ *
15
+ * Sister module to `httpErrorResponse.ts`; same one-function-one-file style.
16
+ */
17
+ import type { ServerResponse } from "node:http";
18
+ export type AllowedKeysResult = {
19
+ ok: true;
20
+ } | {
21
+ ok: false;
22
+ unknownKeys: string[];
23
+ };
24
+ /**
25
+ * Returns `{ok: true}` when every own enumerable key on `body` is in
26
+ * `allowed`. Otherwise lists the offending keys.
27
+ *
28
+ * Uses `Object.hasOwn` to avoid prototype walk surface (see project memory
29
+ * `feedback_record_string_prototype_walk.md` — 5 prod sites burned by
30
+ * `key in obj` / bare bracket access on attacker-controlled objects).
31
+ *
32
+ * Non-object / null / array bodies short-circuit `{ok: true}` — the
33
+ * handler's own shape-check will reject them with its existing 400.
34
+ */
35
+ export declare function validateAllowedBodyKeys(body: unknown, allowed: readonly string[]): AllowedKeysResult;
36
+ /**
37
+ * Convenience: writes the canonical 400 response and returns true when the
38
+ * body fails the allow-list check. Returns false on success so callers can
39
+ * `if (respondIfUnknownBodyKeys(...)) return;` and keep flowing.
40
+ */
41
+ export declare function respondIfUnknownBodyKeys(res: ServerResponse, body: unknown, allowed: readonly string[]): boolean;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Returns `{ok: true}` when every own enumerable key on `body` is in
3
+ * `allowed`. Otherwise lists the offending keys.
4
+ *
5
+ * Uses `Object.hasOwn` to avoid prototype walk surface (see project memory
6
+ * `feedback_record_string_prototype_walk.md` — 5 prod sites burned by
7
+ * `key in obj` / bare bracket access on attacker-controlled objects).
8
+ *
9
+ * Non-object / null / array bodies short-circuit `{ok: true}` — the
10
+ * handler's own shape-check will reject them with its existing 400.
11
+ */
12
+ export function validateAllowedBodyKeys(body, allowed) {
13
+ if (body === null || typeof body !== "object" || Array.isArray(body)) {
14
+ return { ok: true };
15
+ }
16
+ const allowSet = new Set(allowed);
17
+ const unknownKeys = [];
18
+ for (const key of Object.keys(body)) {
19
+ if (!Object.hasOwn(body, key))
20
+ continue;
21
+ if (!allowSet.has(key))
22
+ unknownKeys.push(key);
23
+ }
24
+ if (unknownKeys.length > 0) {
25
+ return { ok: false, unknownKeys };
26
+ }
27
+ return { ok: true };
28
+ }
29
+ /**
30
+ * Convenience: writes the canonical 400 response and returns true when the
31
+ * body fails the allow-list check. Returns false on success so callers can
32
+ * `if (respondIfUnknownBodyKeys(...)) return;` and keep flowing.
33
+ */
34
+ export function respondIfUnknownBodyKeys(res, body, allowed) {
35
+ const result = validateAllowedBodyKeys(body, allowed);
36
+ if (result.ok)
37
+ return false;
38
+ res.writeHead(400, { "Content-Type": "application/json" });
39
+ res.end(JSON.stringify({
40
+ error: "Unknown body fields",
41
+ unknownKeys: result.unknownKeys,
42
+ }));
43
+ return true;
44
+ }
45
+ //# sourceMappingURL=httpBodyValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpBodyValidation.js","sourceRoot":"","sources":["../src/httpBodyValidation.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAa,EACb,OAA0B;IAE1B,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAA+B,CAAC,EAAE,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAc,EAAE,GAAG,CAAC;YAAE,SAAS;QAClD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,GAAmB,EACnB,IAAa,EACb,OAA0B;IAE1B,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC3D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC;QACb,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CACH,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Centralized HTTP error responder for the bridge's plain-`http` route
3
+ * handlers.
4
+ *
5
+ * Replaces the ~96 inline `res.end(JSON.stringify({error: err.message}))`
6
+ * blocks scattered across `server.ts`, `connectorRoutes.ts`,
7
+ * `recipeRoutes.ts`, `inboxRoutes.ts`, and `oauthRoutes.ts` — every one of
8
+ * which leaked the underlying error message (and sometimes a stack frame
9
+ * via `Error.toString`) to the network. CodeQL flagged each as
10
+ * `js/stack-trace-exposure` (89 open alerts at the time of writing).
11
+ *
12
+ * Contract:
13
+ * - Always returns a generic `{error: "Internal server error"}` body, never
14
+ * the underlying error.message — even for non-Error throws.
15
+ * - Logs the full detail (stack preferred, message fallback, String(err)
16
+ * last) to stderr with an optional context label so post-incident
17
+ * debugging is unaffected.
18
+ * - Idempotent on `headersSent` / `writableEnded` so callers nested inside
19
+ * other try/catch blocks can safely call this without re-throwing.
20
+ *
21
+ * Note: the dashboard's Next.js route handlers (`dashboard/src/app/api/**`)
22
+ * are a separate runtime — they use `NextResponse.json(...)` and have their
23
+ * own (smaller) leak surface; this helper is bridge-side only.
24
+ */
25
+ import type { ServerResponse } from "node:http";
26
+ /**
27
+ * Write a generic 500 response and log the underlying error detail
28
+ * server-side.
29
+ *
30
+ * @param res The Node http response to write to.
31
+ * @param err The thrown value caught by the route handler.
32
+ * @param context Optional short tag identifying the route ("recipes/lint",
33
+ * "connectors/jira/connect", etc.). Surfaces in the server
34
+ * log only — never sent to the client.
35
+ */
36
+ export declare function respond500(res: ServerResponse, err: unknown, context?: string): void;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Centralized HTTP error responder for the bridge's plain-`http` route
3
+ * handlers.
4
+ *
5
+ * Replaces the ~96 inline `res.end(JSON.stringify({error: err.message}))`
6
+ * blocks scattered across `server.ts`, `connectorRoutes.ts`,
7
+ * `recipeRoutes.ts`, `inboxRoutes.ts`, and `oauthRoutes.ts` — every one of
8
+ * which leaked the underlying error message (and sometimes a stack frame
9
+ * via `Error.toString`) to the network. CodeQL flagged each as
10
+ * `js/stack-trace-exposure` (89 open alerts at the time of writing).
11
+ *
12
+ * Contract:
13
+ * - Always returns a generic `{error: "Internal server error"}` body, never
14
+ * the underlying error.message — even for non-Error throws.
15
+ * - Logs the full detail (stack preferred, message fallback, String(err)
16
+ * last) to stderr with an optional context label so post-incident
17
+ * debugging is unaffected.
18
+ * - Idempotent on `headersSent` / `writableEnded` so callers nested inside
19
+ * other try/catch blocks can safely call this without re-throwing.
20
+ *
21
+ * Note: the dashboard's Next.js route handlers (`dashboard/src/app/api/**`)
22
+ * are a separate runtime — they use `NextResponse.json(...)` and have their
23
+ * own (smaller) leak surface; this helper is bridge-side only.
24
+ */
25
+ const GENERIC_BODY = JSON.stringify({ error: "Internal server error" });
26
+ /**
27
+ * Write a generic 500 response and log the underlying error detail
28
+ * server-side.
29
+ *
30
+ * @param res The Node http response to write to.
31
+ * @param err The thrown value caught by the route handler.
32
+ * @param context Optional short tag identifying the route ("recipes/lint",
33
+ * "connectors/jira/connect", etc.). Surfaces in the server
34
+ * log only — never sent to the client.
35
+ */
36
+ export function respond500(res, err, context) {
37
+ const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);
38
+ console.error(`[http-500]${context ? ` ${context}` : ""}: ${detail}`);
39
+ if (!res.headersSent) {
40
+ res.writeHead(500, { "Content-Type": "application/json" });
41
+ }
42
+ if (!res.writableEnded) {
43
+ res.end(GENERIC_BODY);
44
+ }
45
+ }
46
+ //# sourceMappingURL=httpErrorResponse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpErrorResponse.js","sourceRoot":"","sources":["../src/httpErrorResponse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAExE;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,GAAmB,EACnB,GAAY,EACZ,OAAgB;IAEhB,MAAM,MAAM,GACV,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO,CAAC,KAAK,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -14,6 +14,28 @@
14
14
  * preserved verbatim from the original.
15
15
  */
16
16
  import type { IncomingMessage, ServerResponse } from "node:http";
17
+ /**
18
+ * Phase 0β provenance shape. Optional + additive — files without
19
+ * frontmatter return `provenance: undefined`.
20
+ */
21
+ export interface InboxProvenance {
22
+ recipe?: string;
23
+ runSeq?: number;
24
+ trigger?: string;
25
+ deliveredAt?: string;
26
+ }
27
+ /**
28
+ * Split a markdown file into its YAML-frontmatter block (parsed as a flat
29
+ * `key: value` map) and the remaining body. Frontmatter is recognised
30
+ * only when the file begins with `---\n` and a closing `---` line is
31
+ * found within the first 30 lines (cap to bound the scan). Returns
32
+ * `{ provenance: undefined, body: content }` for files without
33
+ * frontmatter so callers degrade gracefully on legacy inbox items.
34
+ */
35
+ export declare function parseInboxFile(content: string): {
36
+ provenance: InboxProvenance | undefined;
37
+ body: string;
38
+ };
17
39
  /**
18
40
  * Try to handle an `/inbox` or `/inbox/<filename>.md` route. Returns true
19
41
  * if the route was dispatched (caller should `return` from the request