patchwork-os 0.2.0-beta.1 → 0.2.0-beta.10.canary.100

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 (701) hide show
  1. package/README.bridge.md +14 -14
  2. package/README.md +201 -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.js +1 -1
  24. package/dist/analyticsAggregator.js.map +1 -1
  25. package/dist/analyticsConfig.d.ts +29 -0
  26. package/dist/analyticsConfig.js +102 -0
  27. package/dist/analyticsConfig.js.map +1 -0
  28. package/dist/analyticsPrefs.d.ts +38 -2
  29. package/dist/analyticsPrefs.js +148 -23
  30. package/dist/analyticsPrefs.js.map +1 -1
  31. package/dist/analyticsSend.d.ts +17 -1
  32. package/dist/analyticsSend.js +67 -5
  33. package/dist/analyticsSend.js.map +1 -1
  34. package/dist/approvalHttp.d.ts +14 -0
  35. package/dist/approvalHttp.js +212 -9
  36. package/dist/approvalHttp.js.map +1 -1
  37. package/dist/approvalInsights.js +13 -5
  38. package/dist/approvalInsights.js.map +1 -1
  39. package/dist/approvalQueue.d.ts +97 -3
  40. package/dist/approvalQueue.js +193 -19
  41. package/dist/approvalQueue.js.map +1 -1
  42. package/dist/approvalSignals.js +19 -11
  43. package/dist/approvalSignals.js.map +1 -1
  44. package/dist/automation.d.ts +35 -10
  45. package/dist/automation.js +133 -37
  46. package/dist/automation.js.map +1 -1
  47. package/dist/automationSuggestions.js +10 -8
  48. package/dist/automationSuggestions.js.map +1 -1
  49. package/dist/bridge.d.ts +2 -0
  50. package/dist/bridge.js +219 -35
  51. package/dist/bridge.js.map +1 -1
  52. package/dist/bridgeLockDiscovery.d.ts +27 -1
  53. package/dist/bridgeLockDiscovery.js +38 -11
  54. package/dist/bridgeLockDiscovery.js.map +1 -1
  55. package/dist/bridgeToken.js +3 -2
  56. package/dist/bridgeToken.js.map +1 -1
  57. package/dist/claudeDriver.js +23 -8
  58. package/dist/claudeDriver.js.map +1 -1
  59. package/dist/claudeOrchestrator.d.ts +1 -1
  60. package/dist/claudeOrchestrator.js +87 -44
  61. package/dist/claudeOrchestrator.js.map +1 -1
  62. package/dist/commands/analytics.d.ts +8 -0
  63. package/dist/commands/analytics.js +134 -0
  64. package/dist/commands/analytics.js.map +1 -0
  65. package/dist/commands/auditEnv.d.ts +36 -0
  66. package/dist/commands/auditEnv.js +202 -0
  67. package/dist/commands/auditEnv.js.map +1 -0
  68. package/dist/commands/connect.d.ts +47 -0
  69. package/dist/commands/connect.js +419 -0
  70. package/dist/commands/connect.js.map +1 -0
  71. package/dist/commands/dashboard.js +8 -1
  72. package/dist/commands/dashboard.js.map +1 -1
  73. package/dist/commands/doctor.d.ts +35 -0
  74. package/dist/commands/doctor.js +51 -0
  75. package/dist/commands/doctor.js.map +1 -0
  76. package/dist/commands/install.js +3 -0
  77. package/dist/commands/install.js.map +1 -1
  78. package/dist/commands/launchd.js +15 -16
  79. package/dist/commands/launchd.js.map +1 -1
  80. package/dist/commands/patchworkInit.d.ts +5 -0
  81. package/dist/commands/patchworkInit.js +89 -7
  82. package/dist/commands/patchworkInit.js.map +1 -1
  83. package/dist/commands/recipe.d.ts +151 -0
  84. package/dist/commands/recipe.js +649 -9
  85. package/dist/commands/recipe.js.map +1 -1
  86. package/dist/commands/recipeInstall.js +11 -4
  87. package/dist/commands/recipeInstall.js.map +1 -1
  88. package/dist/commands/shadowScan.d.ts +34 -0
  89. package/dist/commands/shadowScan.js +142 -0
  90. package/dist/commands/shadowScan.js.map +1 -0
  91. package/dist/commands/task.d.ts +25 -0
  92. package/dist/commands/task.js +62 -42
  93. package/dist/commands/task.js.map +1 -1
  94. package/dist/commands/tools.d.ts +20 -1
  95. package/dist/commands/tools.js +112 -3
  96. package/dist/commands/tools.js.map +1 -1
  97. package/dist/commands/tracesExport.d.ts +15 -1
  98. package/dist/commands/tracesExport.js +39 -5
  99. package/dist/commands/tracesExport.js.map +1 -1
  100. package/dist/commands/tracesImport.js +21 -4
  101. package/dist/commands/tracesImport.js.map +1 -1
  102. package/dist/commitIssueLinkLog.d.ts +16 -0
  103. package/dist/commitIssueLinkLog.js +110 -24
  104. package/dist/commitIssueLinkLog.js.map +1 -1
  105. package/dist/companions/registry.js +15 -7
  106. package/dist/companions/registry.js.map +1 -1
  107. package/dist/config.d.ts +47 -3
  108. package/dist/config.js +111 -21
  109. package/dist/config.js.map +1 -1
  110. package/dist/connectorRoutes.js +1422 -57
  111. package/dist/connectorRoutes.js.map +1 -1
  112. package/dist/connectors/airtable.d.ts +230 -0
  113. package/dist/connectors/airtable.js +700 -0
  114. package/dist/connectors/airtable.js.map +1 -0
  115. package/dist/connectors/asana.js +13 -9
  116. package/dist/connectors/asana.js.map +1 -1
  117. package/dist/connectors/baseConnector.js +25 -3
  118. package/dist/connectors/baseConnector.js.map +1 -1
  119. package/dist/connectors/caldiy.d.ts +137 -0
  120. package/dist/connectors/caldiy.js +424 -0
  121. package/dist/connectors/caldiy.js.map +1 -0
  122. package/dist/connectors/circleci.d.ts +162 -0
  123. package/dist/connectors/circleci.js +576 -0
  124. package/dist/connectors/circleci.js.map +1 -0
  125. package/dist/connectors/cloudflare.d.ts +132 -0
  126. package/dist/connectors/cloudflare.js +622 -0
  127. package/dist/connectors/cloudflare.js.map +1 -0
  128. package/dist/connectors/confluence.js +35 -0
  129. package/dist/connectors/confluence.js.map +1 -1
  130. package/dist/connectors/connectorRedirectUri.d.ts +30 -0
  131. package/dist/connectors/connectorRedirectUri.js +38 -0
  132. package/dist/connectors/connectorRedirectUri.js.map +1 -0
  133. package/dist/connectors/connectorRegistry.d.ts +60 -0
  134. package/dist/connectors/connectorRegistry.js +354 -0
  135. package/dist/connectors/connectorRegistry.js.map +1 -0
  136. package/dist/connectors/datadog.js +41 -5
  137. package/dist/connectors/datadog.js.map +1 -1
  138. package/dist/connectors/discord.js +14 -10
  139. package/dist/connectors/discord.js.map +1 -1
  140. package/dist/connectors/elasticsearch.d.ts +141 -0
  141. package/dist/connectors/elasticsearch.js +601 -0
  142. package/dist/connectors/elasticsearch.js.map +1 -0
  143. package/dist/connectors/figma.d.ts +130 -0
  144. package/dist/connectors/figma.js +387 -0
  145. package/dist/connectors/figma.js.map +1 -0
  146. package/dist/connectors/github.d.ts +17 -0
  147. package/dist/connectors/github.js +53 -2
  148. package/dist/connectors/github.js.map +1 -1
  149. package/dist/connectors/gitlab.js +12 -6
  150. package/dist/connectors/gitlab.js.map +1 -1
  151. package/dist/connectors/gmail.js +72 -21
  152. package/dist/connectors/gmail.js.map +1 -1
  153. package/dist/connectors/googleCalendar.js +8 -8
  154. package/dist/connectors/googleCalendar.js.map +1 -1
  155. package/dist/connectors/googleDocs.d.ts +103 -0
  156. package/dist/connectors/googleDocs.js +409 -0
  157. package/dist/connectors/googleDocs.js.map +1 -0
  158. package/dist/connectors/googleDrive.d.ts +12 -0
  159. package/dist/connectors/googleDrive.js +35 -8
  160. package/dist/connectors/googleDrive.js.map +1 -1
  161. package/dist/connectors/grafana.d.ts +133 -0
  162. package/dist/connectors/grafana.js +478 -0
  163. package/dist/connectors/grafana.js.map +1 -0
  164. package/dist/connectors/jira.d.ts +25 -0
  165. package/dist/connectors/jira.js +234 -3
  166. package/dist/connectors/jira.js.map +1 -1
  167. package/dist/connectors/linear.js +1 -1
  168. package/dist/connectors/linear.js.map +1 -1
  169. package/dist/connectors/mcpClient.js +37 -23
  170. package/dist/connectors/mcpClient.js.map +1 -1
  171. package/dist/connectors/mcpOAuth.js +78 -16
  172. package/dist/connectors/mcpOAuth.js.map +1 -1
  173. package/dist/connectors/monday.d.ts +217 -0
  174. package/dist/connectors/monday.js +655 -0
  175. package/dist/connectors/monday.js.map +1 -0
  176. package/dist/connectors/mongodb.d.ts +139 -0
  177. package/dist/connectors/mongodb.js +455 -0
  178. package/dist/connectors/mongodb.js.map +1 -0
  179. package/dist/connectors/notion.d.ts +1 -1
  180. package/dist/connectors/notion.js +13 -4
  181. package/dist/connectors/notion.js.map +1 -1
  182. package/dist/connectors/oauthStateStore.d.ts +20 -0
  183. package/dist/connectors/oauthStateStore.js +94 -4
  184. package/dist/connectors/oauthStateStore.js.map +1 -1
  185. package/dist/connectors/obsidian.d.ts +83 -0
  186. package/dist/connectors/obsidian.js +441 -0
  187. package/dist/connectors/obsidian.js.map +1 -0
  188. package/dist/connectors/paystack.d.ts +159 -0
  189. package/dist/connectors/paystack.js +607 -0
  190. package/dist/connectors/paystack.js.map +1 -0
  191. package/dist/connectors/pipedrive.d.ts +189 -0
  192. package/dist/connectors/pipedrive.js +559 -0
  193. package/dist/connectors/pipedrive.js.map +1 -0
  194. package/dist/connectors/postgres.d.ts +127 -0
  195. package/dist/connectors/postgres.js +512 -0
  196. package/dist/connectors/postgres.js.map +1 -0
  197. package/dist/connectors/posthog.d.ts +119 -0
  198. package/dist/connectors/posthog.js +479 -0
  199. package/dist/connectors/posthog.js.map +1 -0
  200. package/dist/connectors/redis.d.ts +140 -0
  201. package/dist/connectors/redis.js +579 -0
  202. package/dist/connectors/redis.js.map +1 -0
  203. package/dist/connectors/resend.d.ts +131 -0
  204. package/dist/connectors/resend.js +529 -0
  205. package/dist/connectors/resend.js.map +1 -0
  206. package/dist/connectors/salesforce.d.ts +136 -0
  207. package/dist/connectors/salesforce.js +603 -0
  208. package/dist/connectors/salesforce.js.map +1 -0
  209. package/dist/connectors/secrets.d.ts +51 -0
  210. package/dist/connectors/secrets.js +102 -0
  211. package/dist/connectors/secrets.js.map +1 -0
  212. package/dist/connectors/sendgrid.d.ts +102 -0
  213. package/dist/connectors/sendgrid.js +423 -0
  214. package/dist/connectors/sendgrid.js.map +1 -0
  215. package/dist/connectors/shopify.d.ts +145 -0
  216. package/dist/connectors/shopify.js +502 -0
  217. package/dist/connectors/shopify.js.map +1 -0
  218. package/dist/connectors/slack.d.ts +1 -1
  219. package/dist/connectors/slack.js +61 -9
  220. package/dist/connectors/slack.js.map +1 -1
  221. package/dist/connectors/snowflake.d.ts +119 -0
  222. package/dist/connectors/snowflake.js +633 -0
  223. package/dist/connectors/snowflake.js.map +1 -0
  224. package/dist/connectors/supabase.d.ts +92 -0
  225. package/dist/connectors/supabase.js +630 -0
  226. package/dist/connectors/supabase.js.map +1 -0
  227. package/dist/connectors/todoist.d.ts +117 -0
  228. package/dist/connectors/todoist.js +485 -0
  229. package/dist/connectors/todoist.js.map +1 -0
  230. package/dist/connectors/tokenStorage.js +56 -14
  231. package/dist/connectors/tokenStorage.js.map +1 -1
  232. package/dist/connectors/twilio.d.ts +118 -0
  233. package/dist/connectors/twilio.js +475 -0
  234. package/dist/connectors/twilio.js.map +1 -0
  235. package/dist/connectors/vercel.d.ts +110 -0
  236. package/dist/connectors/vercel.js +479 -0
  237. package/dist/connectors/vercel.js.map +1 -0
  238. package/dist/connectors/webflow.d.ts +118 -0
  239. package/dist/connectors/webflow.js +393 -0
  240. package/dist/connectors/webflow.js.map +1 -0
  241. package/dist/connectors/woocommerce.d.ts +220 -0
  242. package/dist/connectors/woocommerce.js +464 -0
  243. package/dist/connectors/woocommerce.js.map +1 -0
  244. package/dist/crypto.js +7 -2
  245. package/dist/crypto.js.map +1 -1
  246. package/dist/decisionReplay.d.ts +8 -6
  247. package/dist/decisionReplay.js +50 -17
  248. package/dist/decisionReplay.js.map +1 -1
  249. package/dist/decisionTraceLog.d.ts +28 -0
  250. package/dist/decisionTraceLog.js +156 -29
  251. package/dist/decisionTraceLog.js.map +1 -1
  252. package/dist/drivers/claude/api.js +33 -9
  253. package/dist/drivers/claude/api.js.map +1 -1
  254. package/dist/drivers/claude/envSanitizer.d.ts +0 -6
  255. package/dist/drivers/claude/envSanitizer.js +17 -2
  256. package/dist/drivers/claude/envSanitizer.js.map +1 -1
  257. package/dist/drivers/claude/streamParser.js +5 -4
  258. package/dist/drivers/claude/streamParser.js.map +1 -1
  259. package/dist/drivers/claude/subprocess.js +69 -16
  260. package/dist/drivers/claude/subprocess.js.map +1 -1
  261. package/dist/drivers/gemini/index.d.ts +22 -0
  262. package/dist/drivers/gemini/index.js +256 -129
  263. package/dist/drivers/gemini/index.js.map +1 -1
  264. package/dist/drivers/local/index.d.ts +2 -0
  265. package/dist/drivers/local/index.js +12 -0
  266. package/dist/drivers/local/index.js.map +1 -1
  267. package/dist/drivers/openai/index.js +30 -2
  268. package/dist/drivers/openai/index.js.map +1 -1
  269. package/dist/extensionClient.d.ts +37 -4
  270. package/dist/extensionClient.js +58 -16
  271. package/dist/extensionClient.js.map +1 -1
  272. package/dist/featureFlags.d.ts +91 -0
  273. package/dist/featureFlags.js +174 -3
  274. package/dist/featureFlags.js.map +1 -1
  275. package/dist/fileLock.js +21 -12
  276. package/dist/fileLock.js.map +1 -1
  277. package/dist/fileLockSync.d.ts +67 -0
  278. package/dist/fileLockSync.js +126 -0
  279. package/dist/fileLockSync.js.map +1 -0
  280. package/dist/fp/activityAnalytics.js +26 -12
  281. package/dist/fp/activityAnalytics.js.map +1 -1
  282. package/dist/fp/automationInterpreter.d.ts +15 -1
  283. package/dist/fp/automationInterpreter.js +267 -87
  284. package/dist/fp/automationInterpreter.js.map +1 -1
  285. package/dist/fp/automationProgram.d.ts +30 -0
  286. package/dist/fp/automationProgram.js.map +1 -1
  287. package/dist/fp/automationState.d.ts +24 -5
  288. package/dist/fp/automationState.js +56 -9
  289. package/dist/fp/automationState.js.map +1 -1
  290. package/dist/fp/automationUtils.js +1 -1
  291. package/dist/fp/automationUtils.js.map +1 -1
  292. package/dist/fp/commandDescription.js +7 -1
  293. package/dist/fp/commandDescription.js.map +1 -1
  294. package/dist/fp/extensionSnapshot.js +8 -2
  295. package/dist/fp/extensionSnapshot.js.map +1 -1
  296. package/dist/fp/interpreterContext.d.ts +66 -1
  297. package/dist/fp/interpreterContext.js +91 -1
  298. package/dist/fp/interpreterContext.js.map +1 -1
  299. package/dist/fp/policyParser.js +34 -2
  300. package/dist/fp/policyParser.js.map +1 -1
  301. package/dist/fsWatchWithFallback.d.ts +36 -0
  302. package/dist/fsWatchWithFallback.js +128 -0
  303. package/dist/fsWatchWithFallback.js.map +1 -0
  304. package/dist/haltPushDispatch.d.ts +33 -0
  305. package/dist/haltPushDispatch.js +103 -0
  306. package/dist/haltPushDispatch.js.map +1 -0
  307. package/dist/httpBodyValidation.d.ts +41 -0
  308. package/dist/httpBodyValidation.js +45 -0
  309. package/dist/httpBodyValidation.js.map +1 -0
  310. package/dist/inboxRoutes.d.ts +22 -0
  311. package/dist/inboxRoutes.js +61 -1
  312. package/dist/inboxRoutes.js.map +1 -1
  313. package/dist/index.js +1206 -158
  314. package/dist/index.js.map +1 -1
  315. package/dist/installGuard.js +6 -2
  316. package/dist/installGuard.js.map +1 -1
  317. package/dist/localEndpointGuard.d.ts +25 -0
  318. package/dist/localEndpointGuard.js +101 -0
  319. package/dist/localEndpointGuard.js.map +1 -0
  320. package/dist/lockfile.js +31 -4
  321. package/dist/lockfile.js.map +1 -1
  322. package/dist/oauth.d.ts +9 -0
  323. package/dist/oauth.js +33 -0
  324. package/dist/oauth.js.map +1 -1
  325. package/dist/oauthRoutes.d.ts +1 -1
  326. package/dist/oauthRoutes.js +5 -3
  327. package/dist/oauthRoutes.js.map +1 -1
  328. package/dist/orchestrator/childBridgeClient.d.ts +5 -0
  329. package/dist/orchestrator/childBridgeClient.js +28 -1
  330. package/dist/orchestrator/childBridgeClient.js.map +1 -1
  331. package/dist/orchestrator/childBridgeRegistry.js +29 -11
  332. package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
  333. package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
  334. package/dist/orchestrator/orchestratorBridge.js +70 -9
  335. package/dist/orchestrator/orchestratorBridge.js.map +1 -1
  336. package/dist/patchworkConfig.d.ts +44 -1
  337. package/dist/patchworkConfig.js +28 -3
  338. package/dist/patchworkConfig.js.map +1 -1
  339. package/dist/pluginLoader.js +10 -1
  340. package/dist/pluginLoader.js.map +1 -1
  341. package/dist/pluginWatcher.js +12 -14
  342. package/dist/pluginWatcher.js.map +1 -1
  343. package/dist/preToolUseHook.js +3 -2
  344. package/dist/preToolUseHook.js.map +1 -1
  345. package/dist/processTree.d.ts +34 -0
  346. package/dist/processTree.js +105 -0
  347. package/dist/processTree.js.map +1 -0
  348. package/dist/prompts.js +3 -3
  349. package/dist/prompts.js.map +1 -1
  350. package/dist/recipeOrchestration.d.ts +9 -0
  351. package/dist/recipeOrchestration.js +341 -24
  352. package/dist/recipeOrchestration.js.map +1 -1
  353. package/dist/recipeRoutes.d.ts +58 -2
  354. package/dist/recipeRoutes.js +744 -115
  355. package/dist/recipeRoutes.js.map +1 -1
  356. package/dist/recipes/RecipeOrchestrator.d.ts +2 -0
  357. package/dist/recipes/RecipeOrchestrator.js +6 -1
  358. package/dist/recipes/RecipeOrchestrator.js.map +1 -1
  359. package/dist/recipes/agentExecutor.d.ts +25 -5
  360. package/dist/recipes/agentExecutor.js.map +1 -1
  361. package/dist/recipes/chainedRunner.d.ts +2 -0
  362. package/dist/recipes/chainedRunner.js +156 -9
  363. package/dist/recipes/chainedRunner.js.map +1 -1
  364. package/dist/recipes/compiler.js +9 -5
  365. package/dist/recipes/compiler.js.map +1 -1
  366. package/dist/recipes/connectorPreflight.d.ts +66 -0
  367. package/dist/recipes/connectorPreflight.js +169 -0
  368. package/dist/recipes/connectorPreflight.js.map +1 -0
  369. package/dist/recipes/dependencyGraph.d.ts +9 -0
  370. package/dist/recipes/dependencyGraph.js +32 -7
  371. package/dist/recipes/dependencyGraph.js.map +1 -1
  372. package/dist/recipes/githubInstallSource.d.ts +135 -0
  373. package/dist/recipes/githubInstallSource.js +236 -0
  374. package/dist/recipes/githubInstallSource.js.map +1 -0
  375. package/dist/recipes/haltCategory.d.ts +119 -0
  376. package/dist/recipes/haltCategory.js +188 -0
  377. package/dist/recipes/haltCategory.js.map +1 -0
  378. package/dist/recipes/idempotencyKey.d.ts +154 -0
  379. package/dist/recipes/idempotencyKey.js +375 -0
  380. package/dist/recipes/idempotencyKey.js.map +1 -0
  381. package/dist/recipes/installer.js +58 -3
  382. package/dist/recipes/installer.js.map +1 -1
  383. package/dist/recipes/judgeSummary.d.ts +50 -0
  384. package/dist/recipes/judgeSummary.js +47 -0
  385. package/dist/recipes/judgeSummary.js.map +1 -0
  386. package/dist/recipes/judgeVerdict.d.ts +48 -0
  387. package/dist/recipes/judgeVerdict.js +174 -0
  388. package/dist/recipes/judgeVerdict.js.map +1 -0
  389. package/dist/recipes/migrations/index.d.ts +9 -0
  390. package/dist/recipes/migrations/index.js +133 -0
  391. package/dist/recipes/migrations/index.js.map +1 -1
  392. package/dist/recipes/names.d.ts +20 -0
  393. package/dist/recipes/names.js +25 -0
  394. package/dist/recipes/names.js.map +1 -1
  395. package/dist/recipes/parser.js +116 -6
  396. package/dist/recipes/parser.js.map +1 -1
  397. package/dist/recipes/replayRun.js +1 -1
  398. package/dist/recipes/replayRun.js.map +1 -1
  399. package/dist/recipes/runBudget.d.ts +70 -0
  400. package/dist/recipes/runBudget.js +109 -0
  401. package/dist/recipes/runBudget.js.map +1 -0
  402. package/dist/recipes/scheduler.d.ts +30 -0
  403. package/dist/recipes/scheduler.js +69 -19
  404. package/dist/recipes/scheduler.js.map +1 -1
  405. package/dist/recipes/schema.d.ts +65 -2
  406. package/dist/recipes/schemaGenerator.js +119 -7
  407. package/dist/recipes/schemaGenerator.js.map +1 -1
  408. package/dist/recipes/stepObservation.js +9 -0
  409. package/dist/recipes/stepObservation.js.map +1 -1
  410. package/dist/recipes/toolRegistry.js +33 -7
  411. package/dist/recipes/toolRegistry.js.map +1 -1
  412. package/dist/recipes/tools/airtable.d.ts +15 -0
  413. package/dist/recipes/tools/airtable.js +239 -0
  414. package/dist/recipes/tools/airtable.js.map +1 -0
  415. package/dist/recipes/tools/fanOut.d.ts +20 -0
  416. package/dist/recipes/tools/fanOut.js +199 -0
  417. package/dist/recipes/tools/fanOut.js.map +1 -0
  418. package/dist/recipes/tools/file.js +5 -2
  419. package/dist/recipes/tools/file.js.map +1 -1
  420. package/dist/recipes/tools/github.d.ts +1 -1
  421. package/dist/recipes/tools/github.js +75 -1
  422. package/dist/recipes/tools/github.js.map +1 -1
  423. package/dist/recipes/tools/gmail.js +27 -5
  424. package/dist/recipes/tools/gmail.js.map +1 -1
  425. package/dist/recipes/tools/googleDrive.js +64 -0
  426. package/dist/recipes/tools/googleDrive.js.map +1 -1
  427. package/dist/recipes/tools/http.d.ts +10 -0
  428. package/dist/recipes/tools/http.js +176 -0
  429. package/dist/recipes/tools/http.js.map +1 -0
  430. package/dist/recipes/tools/index.d.ts +7 -0
  431. package/dist/recipes/tools/index.js +7 -0
  432. package/dist/recipes/tools/index.js.map +1 -1
  433. package/dist/recipes/tools/resend.d.ts +8 -0
  434. package/dist/recipes/tools/resend.js +152 -0
  435. package/dist/recipes/tools/resend.js.map +1 -0
  436. package/dist/recipes/tools/sendgrid.d.ts +9 -0
  437. package/dist/recipes/tools/sendgrid.js +174 -0
  438. package/dist/recipes/tools/sendgrid.js.map +1 -0
  439. package/dist/recipes/tools/slack.js +1 -1
  440. package/dist/recipes/tools/twilio.d.ts +11 -0
  441. package/dist/recipes/tools/twilio.js +179 -0
  442. package/dist/recipes/tools/twilio.js.map +1 -0
  443. package/dist/recipes/tools/vercel.d.ts +9 -0
  444. package/dist/recipes/tools/vercel.js +145 -0
  445. package/dist/recipes/tools/vercel.js.map +1 -0
  446. package/dist/recipes/validation.d.ts +17 -0
  447. package/dist/recipes/validation.js +141 -11
  448. package/dist/recipes/validation.js.map +1 -1
  449. package/dist/recipes/workspaceRoot.d.ts +37 -0
  450. package/dist/recipes/workspaceRoot.js +73 -0
  451. package/dist/recipes/workspaceRoot.js.map +1 -0
  452. package/dist/recipes/yamlPositions.d.ts +56 -0
  453. package/dist/recipes/yamlPositions.js +183 -0
  454. package/dist/recipes/yamlPositions.js.map +1 -0
  455. package/dist/recipes/yamlRunner.d.ts +185 -8
  456. package/dist/recipes/yamlRunner.js +967 -224
  457. package/dist/recipes/yamlRunner.js.map +1 -1
  458. package/dist/recipesHttp.d.ts +19 -3
  459. package/dist/recipesHttp.js +67 -11
  460. package/dist/recipesHttp.js.map +1 -1
  461. package/dist/resources.js +21 -13
  462. package/dist/resources.js.map +1 -1
  463. package/dist/runLog.d.ts +58 -5
  464. package/dist/runLog.js +98 -21
  465. package/dist/runLog.js.map +1 -1
  466. package/dist/sanitizeParsedJson.d.ts +39 -0
  467. package/dist/sanitizeParsedJson.js +55 -0
  468. package/dist/sanitizeParsedJson.js.map +1 -0
  469. package/dist/schemas/recipe.v1.json +887 -198
  470. package/dist/server.d.ts +160 -3
  471. package/dist/server.js +1099 -122
  472. package/dist/server.js.map +1 -1
  473. package/dist/sessionCheckpoint.d.ts +8 -0
  474. package/dist/sessionCheckpoint.js +33 -3
  475. package/dist/sessionCheckpoint.js.map +1 -1
  476. package/dist/ssrfGuard.d.ts +16 -0
  477. package/dist/ssrfGuard.js +87 -4
  478. package/dist/ssrfGuard.js.map +1 -1
  479. package/dist/streamableHttp.d.ts +9 -4
  480. package/dist/streamableHttp.js +76 -20
  481. package/dist/streamableHttp.js.map +1 -1
  482. package/dist/telemetry.js +37 -19
  483. package/dist/telemetry.js.map +1 -1
  484. package/dist/testing/shadowRun.d.ts +52 -0
  485. package/dist/testing/shadowRun.js +71 -0
  486. package/dist/testing/shadowRun.js.map +1 -0
  487. package/dist/tools/batchLsp.d.ts +3 -0
  488. package/dist/tools/bridgeDoctor.d.ts +11 -0
  489. package/dist/tools/bridgeDoctor.js +48 -2
  490. package/dist/tools/bridgeDoctor.js.map +1 -1
  491. package/dist/tools/bridgeStatus.d.ts +0 -12
  492. package/dist/tools/bridgeStatus.js +2 -28
  493. package/dist/tools/bridgeStatus.js.map +1 -1
  494. package/dist/tools/cancelClaudeTask.d.ts +1 -0
  495. package/dist/tools/clipboard.d.ts +2 -0
  496. package/dist/tools/closeTabs.d.ts +1 -0
  497. package/dist/tools/codeLens.d.ts +1 -0
  498. package/dist/tools/createIssueFromAIComment.d.ts +1 -0
  499. package/dist/tools/ctxGetTaskContext.d.ts +9 -0
  500. package/dist/tools/ctxGetTaskContext.js +50 -2
  501. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  502. package/dist/tools/ctxQueryTraces.js +32 -24
  503. package/dist/tools/ctxQueryTraces.js.map +1 -1
  504. package/dist/tools/ctxSaveTrace.d.ts +1 -0
  505. package/dist/tools/debug.d.ts +4 -0
  506. package/dist/tools/decorations.d.ts +2 -0
  507. package/dist/tools/detectUnusedCode.js +9 -7
  508. package/dist/tools/detectUnusedCode.js.map +1 -1
  509. package/dist/tools/documentLinks.d.ts +1 -0
  510. package/dist/tools/editText.d.ts +1 -0
  511. package/dist/tools/editText.js +2 -1
  512. package/dist/tools/editText.js.map +1 -1
  513. package/dist/tools/enrichCommit.d.ts +1 -0
  514. package/dist/tools/enrichStackTrace.js +11 -5
  515. package/dist/tools/enrichStackTrace.js.map +1 -1
  516. package/dist/tools/explainDiagnostic.d.ts +1 -0
  517. package/dist/tools/explainSymbol.d.ts +1 -0
  518. package/dist/tools/fileOperations.d.ts +3 -0
  519. package/dist/tools/fileOperations.js +2 -1
  520. package/dist/tools/fileOperations.js.map +1 -1
  521. package/dist/tools/fileWatcher.d.ts +2 -0
  522. package/dist/tools/fileWatcher.js +8 -2
  523. package/dist/tools/fileWatcher.js.map +1 -1
  524. package/dist/tools/findFiles.d.ts +1 -0
  525. package/dist/tools/fixAllLintErrors.d.ts +1 -0
  526. package/dist/tools/fixAllLintErrors.js +10 -5
  527. package/dist/tools/fixAllLintErrors.js.map +1 -1
  528. package/dist/tools/foldingRanges.d.ts +1 -0
  529. package/dist/tools/formatDocument.d.ts +1 -0
  530. package/dist/tools/formatDocument.js +10 -5
  531. package/dist/tools/formatDocument.js.map +1 -1
  532. package/dist/tools/generateTests.d.ts +1 -0
  533. package/dist/tools/getAIComments.d.ts +1 -0
  534. package/dist/tools/getAnalyticsReport.js +5 -1
  535. package/dist/tools/getAnalyticsReport.js.map +1 -1
  536. package/dist/tools/getBufferContent.d.ts +1 -0
  537. package/dist/tools/getChangeImpact.d.ts +1 -0
  538. package/dist/tools/getChangeImpact.js +23 -14
  539. package/dist/tools/getChangeImpact.js.map +1 -1
  540. package/dist/tools/getClaudeTaskStatus.d.ts +1 -0
  541. package/dist/tools/getCodeCoverage.d.ts +1 -0
  542. package/dist/tools/getCodeCoverage.js +32 -14
  543. package/dist/tools/getCodeCoverage.js.map +1 -1
  544. package/dist/tools/getCommitsForIssue.d.ts +1 -0
  545. package/dist/tools/getDebugState.d.ts +1 -0
  546. package/dist/tools/getDiagnostics.js +32 -29
  547. package/dist/tools/getDiagnostics.js.map +1 -1
  548. package/dist/tools/getDiffFromHandoff.js +8 -2
  549. package/dist/tools/getDiffFromHandoff.js.map +1 -1
  550. package/dist/tools/getDocumentSymbols.d.ts +1 -0
  551. package/dist/tools/getGitHotspots.d.ts +1 -0
  552. package/dist/tools/getGitStatus.js +6 -1
  553. package/dist/tools/getGitStatus.js.map +1 -1
  554. package/dist/tools/getImportedSignatures.d.ts +1 -0
  555. package/dist/tools/getImportedSignatures.js +18 -14
  556. package/dist/tools/getImportedSignatures.js.map +1 -1
  557. package/dist/tools/getPRTemplate.d.ts +1 -0
  558. package/dist/tools/getProjectContext.js +23 -10
  559. package/dist/tools/getProjectContext.js.map +1 -1
  560. package/dist/tools/getSymbolHistory.d.ts +1 -0
  561. package/dist/tools/getToolCapabilities.d.ts +10 -5
  562. package/dist/tools/getToolCapabilities.js +116 -204
  563. package/dist/tools/getToolCapabilities.js.map +1 -1
  564. package/dist/tools/getTypeSignature.d.ts +1 -0
  565. package/dist/tools/getWorkspaceSettings.d.ts +1 -0
  566. package/dist/tools/gitWrite.d.ts +11 -0
  567. package/dist/tools/github/actions.d.ts +2 -0
  568. package/dist/tools/github/composite.d.ts +4 -1
  569. package/dist/tools/github/composite.js +7 -7
  570. package/dist/tools/github/composite.js.map +1 -1
  571. package/dist/tools/github/issues.d.ts +4 -0
  572. package/dist/tools/github/pr.d.ts +13 -6
  573. package/dist/tools/github/pr.js +18 -11
  574. package/dist/tools/github/pr.js.map +1 -1
  575. package/dist/tools/handoffNote.d.ts +1 -0
  576. package/dist/tools/handoffNote.js +2 -1
  577. package/dist/tools/handoffNote.js.map +1 -1
  578. package/dist/tools/headless/lspClient.js +3 -0
  579. package/dist/tools/headless/lspClient.js.map +1 -1
  580. package/dist/tools/hoverAtCursor.d.ts +1 -0
  581. package/dist/tools/httpClient.d.ts +2 -0
  582. package/dist/tools/httpClient.js +38 -71
  583. package/dist/tools/httpClient.js.map +1 -1
  584. package/dist/tools/index.js +14 -10
  585. package/dist/tools/index.js.map +1 -1
  586. package/dist/tools/inlayHints.d.ts +1 -0
  587. package/dist/tools/launchQuickTask.d.ts +1 -0
  588. package/dist/tools/listClaudeTasks.d.ts +1 -0
  589. package/dist/tools/listClaudeTasks.js +10 -8
  590. package/dist/tools/listClaudeTasks.js.map +1 -1
  591. package/dist/tools/listTerminals.d.ts +1 -0
  592. package/dist/tools/lsp.d.ts +15 -0
  593. package/dist/tools/lsp.js +17 -0
  594. package/dist/tools/lsp.js.map +1 -1
  595. package/dist/tools/navigateToSymbolByName.d.ts +1 -0
  596. package/dist/tools/openDiff.d.ts +1 -0
  597. package/dist/tools/openDiff.js +4 -1
  598. package/dist/tools/openDiff.js.map +1 -1
  599. package/dist/tools/openFile.d.ts +1 -0
  600. package/dist/tools/openFile.js +4 -1
  601. package/dist/tools/openFile.js.map +1 -1
  602. package/dist/tools/openInBrowser.js +6 -1
  603. package/dist/tools/openInBrowser.js.map +1 -1
  604. package/dist/tools/organizeImports.d.ts +1 -0
  605. package/dist/tools/organizeImports.js +5 -3
  606. package/dist/tools/organizeImports.js.map +1 -1
  607. package/dist/tools/performanceReport.js +5 -3
  608. package/dist/tools/performanceReport.js.map +1 -1
  609. package/dist/tools/planPersistence.d.ts +3 -0
  610. package/dist/tools/planPersistence.js +4 -1
  611. package/dist/tools/planPersistence.js.map +1 -1
  612. package/dist/tools/previewEdit.d.ts +1 -0
  613. package/dist/tools/previewEdit.js +31 -5
  614. package/dist/tools/previewEdit.js.map +1 -1
  615. package/dist/tools/recentTracesDigest.js +54 -11
  616. package/dist/tools/recentTracesDigest.js.map +1 -1
  617. package/dist/tools/refactorAnalyze.d.ts +1 -0
  618. package/dist/tools/refactorExtractFunction.js +4 -1
  619. package/dist/tools/refactorExtractFunction.js.map +1 -1
  620. package/dist/tools/refactorPreview.d.ts +1 -0
  621. package/dist/tools/refactorPreview.js +10 -2
  622. package/dist/tools/refactorPreview.js.map +1 -1
  623. package/dist/tools/replaceBlock.d.ts +1 -0
  624. package/dist/tools/replaceBlock.js +2 -1
  625. package/dist/tools/replaceBlock.js.map +1 -1
  626. package/dist/tools/resumeClaudeTask.d.ts +1 -0
  627. package/dist/tools/runClaudeTask.d.ts +1 -0
  628. package/dist/tools/runTests.js +15 -4
  629. package/dist/tools/runTests.js.map +1 -1
  630. package/dist/tools/screenshot.d.ts +1 -0
  631. package/dist/tools/screenshotAndAnnotate.js +6 -2
  632. package/dist/tools/screenshotAndAnnotate.js.map +1 -1
  633. package/dist/tools/searchAndReplace.d.ts +1 -0
  634. package/dist/tools/searchAndReplace.js +21 -12
  635. package/dist/tools/searchAndReplace.js.map +1 -1
  636. package/dist/tools/searchTools.d.ts +26 -0
  637. package/dist/tools/searchTools.js +62 -21
  638. package/dist/tools/searchTools.js.map +1 -1
  639. package/dist/tools/searchWorkspace.d.ts +1 -0
  640. package/dist/tools/selectionRanges.d.ts +1 -0
  641. package/dist/tools/semanticTokens.d.ts +1 -0
  642. package/dist/tools/signatureHelp.d.ts +1 -0
  643. package/dist/tools/spawnWorkspace.js +15 -7
  644. package/dist/tools/spawnWorkspace.js.map +1 -1
  645. package/dist/tools/terminal.d.ts +6 -0
  646. package/dist/tools/testRunners/pytest.js +6 -2
  647. package/dist/tools/testRunners/pytest.js.map +1 -1
  648. package/dist/tools/testRunners/vitestJest.js +3 -1
  649. package/dist/tools/testRunners/vitestJest.js.map +1 -1
  650. package/dist/tools/testTraceToSource.d.ts +1 -0
  651. package/dist/tools/transaction.d.ts +13 -1
  652. package/dist/tools/transaction.js +63 -5
  653. package/dist/tools/transaction.js.map +1 -1
  654. package/dist/tools/typeHierarchy.d.ts +1 -0
  655. package/dist/tools/utils.d.ts +33 -0
  656. package/dist/tools/utils.js +122 -18
  657. package/dist/tools/utils.js.map +1 -1
  658. package/dist/tools/vscodeCommands.d.ts +2 -0
  659. package/dist/tools/vscodeTasks.d.ts +2 -0
  660. package/dist/tools/workspaceSettings.d.ts +1 -0
  661. package/dist/transport.d.ts +3 -1
  662. package/dist/transport.js +126 -52
  663. package/dist/transport.js.map +1 -1
  664. package/dist/winShim.d.ts +34 -0
  665. package/dist/winShim.js +94 -0
  666. package/dist/winShim.js.map +1 -0
  667. package/dist/wireHaltPushDispatch.d.ts +38 -0
  668. package/dist/wireHaltPushDispatch.js +71 -0
  669. package/dist/wireHaltPushDispatch.js.map +1 -0
  670. package/dist/writeFileAtomic.d.ts +23 -0
  671. package/dist/writeFileAtomic.js +121 -0
  672. package/dist/writeFileAtomic.js.map +1 -0
  673. package/package.json +23 -7
  674. package/scripts/postinstall.mjs +42 -2
  675. package/scripts/smoke/run-all.mjs +213 -0
  676. package/scripts/start-all.mjs +572 -0
  677. package/scripts/start-all.ps1 +209 -0
  678. package/scripts/start-all.sh +73 -17
  679. package/scripts/start-orchestrator.ps1 +158 -0
  680. package/scripts/start-remote.mjs +122 -0
  681. package/templates/automation-policies/recipe-authoring.json +1 -1
  682. package/templates/automation-policies/security-first.json +1 -1
  683. package/templates/automation-policies/strict-lint.json +1 -1
  684. package/templates/automation-policies/test-driven.json +1 -1
  685. package/templates/automation-policy.example.json +1 -1
  686. package/templates/co.patchwork-os.bridge.plist +2 -2
  687. package/templates/recipes/approval-queue-ui-test.yaml +1 -1
  688. package/templates/recipes/ctx-loop-test.yaml +1 -1
  689. package/templates/recipes/fix-errors-on-save.yaml +71 -0
  690. package/templates/recipes/morning-brief.yaml +5 -2
  691. package/templates/recipes/project-health-check.yaml +4 -1
  692. package/templates/recipes/sentry-to-linear.yaml +72 -38
  693. package/templates/recipes/webhook/apple-watch-health-log.yaml +145 -0
  694. package/templates/recipes/webhook/customer-escalation.yaml +8 -9
  695. package/templates/recipes/webhook/meeting-prep.yaml +11 -5
  696. package/dist/commands/marketplace.d.ts +0 -16
  697. package/dist/commands/marketplace.js +0 -32
  698. package/dist/commands/marketplace.js.map +0 -1
  699. package/dist/recipes/legacyRecipeCompat.d.ts +0 -10
  700. package/dist/recipes/legacyRecipeCompat.js +0 -131
  701. package/dist/recipes/legacyRecipeCompat.js.map +0 -1
@@ -0,0 +1,202 @@
1
+ /**
2
+ * auditEnv — statically scan a recipe YAML for {{env.FOO}} references
3
+ * and verify those vars exist in process.env (or an optional .env file).
4
+ *
5
+ * Fills a gap that `recipe preflight` does NOT cover: preflight checks
6
+ * lint/tools/write-steps but silently produces empty string at runtime
7
+ * for missing {{env.FOO}} references. auditEnv catches that statically.
8
+ */
9
+ import { existsSync, readFileSync, statSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+ import { parse as parseYaml } from "yaml";
12
+ import { resolveFilePath } from "../tools/utils.js";
13
+ // ── Pattern ──────────────────────────────────────────────────────────────────
14
+ /** Matches {{env.FOO}} and {{env.foo}} references in template strings. */
15
+ const ENV_REF_RE = /\{\{env\.([A-Za-z_][A-Za-z0-9_]*)\}\}/g;
16
+ /**
17
+ * Walk every string value in an arbitrary JSON/YAML-parsed object and collect
18
+ * all unique env var names referenced via {{env.NAME}}.
19
+ */
20
+ function collectEnvRefs(value, seen = new Set()) {
21
+ if (typeof value === "string") {
22
+ for (const m of value.matchAll(ENV_REF_RE)) {
23
+ // m[1] is always defined — the regex has exactly one capture group
24
+ seen.add(m[1]);
25
+ }
26
+ }
27
+ else if (Array.isArray(value)) {
28
+ for (const item of value) {
29
+ collectEnvRefs(item, seen);
30
+ }
31
+ }
32
+ else if (value !== null && typeof value === "object") {
33
+ for (const v of Object.values(value)) {
34
+ collectEnvRefs(v, seen);
35
+ }
36
+ }
37
+ return seen;
38
+ }
39
+ // ── .env file parser ──────────────────────────────────────────────────────────
40
+ /**
41
+ * Parse a simple KEY=VALUE .env file. Lines starting with # and blank lines
42
+ * are ignored. Values may be optionally quoted with ' or ". Does NOT expand
43
+ * variable references — only static values are relevant for presence checks.
44
+ */
45
+ function parseDotEnv(content) {
46
+ const map = new Map();
47
+ for (const rawLine of content.split(/\r?\n/)) {
48
+ const line = rawLine.trim();
49
+ if (!line || line.startsWith("#"))
50
+ continue;
51
+ const eqIdx = line.indexOf("=");
52
+ if (eqIdx === -1)
53
+ continue;
54
+ const key = line.slice(0, eqIdx).trim();
55
+ if (!key)
56
+ continue;
57
+ let val = line.slice(eqIdx + 1).trim();
58
+ // Strip surrounding quotes if present
59
+ if ((val.startsWith('"') && val.endsWith('"')) ||
60
+ (val.startsWith("'") && val.endsWith("'"))) {
61
+ val = val.slice(1, -1);
62
+ }
63
+ map.set(key, val);
64
+ }
65
+ return map;
66
+ }
67
+ // ── Placeholder heuristic ─────────────────────────────────────────────────────
68
+ /** Values that look like placeholders rather than real secrets. */
69
+ const PLACEHOLDER_RE = /^(changeme|replace[-_]?me|todo|fixme|<[^>]+>|\[.*\]|your[-_]?.*here|placeholder|example|xxx+|dummy|fake|test)$/i;
70
+ function looksLikePlaceholder(val) {
71
+ return PLACEHOLDER_RE.test(val.trim());
72
+ }
73
+ // ── Public API ────────────────────────────────────────────────────────────────
74
+ /**
75
+ * Scan `recipeRef` (file path or installed recipe name) for {{env.FOO}}
76
+ * references and report which env vars are present / missing.
77
+ *
78
+ * `recipeRef` is resolved exactly like `recipe lint` — absolute/relative file
79
+ * paths are used directly; bare names are looked up under the default recipes
80
+ * dir. We intentionally do NOT re-import the heavy `resolveRecipePath` helper
81
+ * from recipe.ts (would pull in the entire 2 400-line module). Instead we do
82
+ * a minimal two-step: try direct path first, then give a clear error.
83
+ */
84
+ export async function runAuditEnv(recipeRef, options = {}) {
85
+ // ── 1. Resolve recipe path ─────────────────────────────────────────────────
86
+ const directPath = resolve(recipeRef);
87
+ let recipePath;
88
+ if (existsSync(directPath) && statSync(directPath).isFile()) {
89
+ recipePath = directPath;
90
+ }
91
+ else {
92
+ return {
93
+ ok: false,
94
+ recipe: recipeRef,
95
+ missing: [],
96
+ present: [],
97
+ warnings: [`Recipe file not found: ${recipeRef}`],
98
+ };
99
+ }
100
+ // ── 2. Load + parse YAML ───────────────────────────────────────────────────
101
+ let raw;
102
+ try {
103
+ const text = readFileSync(recipePath, "utf-8");
104
+ raw = parseYaml(text);
105
+ }
106
+ catch (err) {
107
+ const msg = err instanceof Error ? err.message : String(err);
108
+ return {
109
+ ok: false,
110
+ recipe: recipeRef,
111
+ missing: [],
112
+ present: [],
113
+ warnings: [`Failed to parse recipe YAML: ${msg}`],
114
+ };
115
+ }
116
+ // Prefer recipe.name for display; fall back to path.
117
+ const recipeName = raw !== null &&
118
+ typeof raw === "object" &&
119
+ typeof raw.name === "string"
120
+ ? raw.name
121
+ : recipeRef;
122
+ // ── 3. Collect {{env.FOO}} references ─────────────────────────────────────
123
+ const refs = collectEnvRefs(raw);
124
+ if (refs.size === 0) {
125
+ return {
126
+ ok: true,
127
+ recipe: recipeName,
128
+ missing: [],
129
+ present: [],
130
+ warnings: [],
131
+ };
132
+ }
133
+ // ── 4. Build env lookup map ────────────────────────────────────────────────
134
+ // Start with process.env as baseline.
135
+ let envMap = new Map(Object.entries(process.env));
136
+ if (options.envFile) {
137
+ // Security: envFile must stay within workspace.
138
+ if (!options.workspace) {
139
+ return {
140
+ ok: false,
141
+ recipe: recipeName,
142
+ missing: [],
143
+ present: [],
144
+ warnings: [
145
+ "envFile provided but workspace is required for path validation",
146
+ ],
147
+ };
148
+ }
149
+ try {
150
+ resolveFilePath(options.envFile, options.workspace);
151
+ }
152
+ catch (err) {
153
+ const msg = err instanceof Error ? err.message : String(err);
154
+ return {
155
+ ok: false,
156
+ recipe: recipeName,
157
+ missing: [],
158
+ present: [],
159
+ warnings: [`envFile path rejected: ${msg}`],
160
+ };
161
+ }
162
+ const envFilePath = resolve(options.workspace, options.envFile);
163
+ if (!existsSync(envFilePath)) {
164
+ return {
165
+ ok: false,
166
+ recipe: recipeName,
167
+ missing: [],
168
+ present: [],
169
+ warnings: [`envFile not found: ${options.envFile}`],
170
+ };
171
+ }
172
+ const dotEnvContent = readFileSync(envFilePath, "utf-8");
173
+ const dotEnvMap = parseDotEnv(dotEnvContent);
174
+ // envFile entries supplement (and override) process.env entries.
175
+ envMap = new Map([...envMap, ...dotEnvMap]);
176
+ }
177
+ // ── 5. Split refs into present / missing ──────────────────────────────────
178
+ const missing = [];
179
+ const present = [];
180
+ const warnings = [];
181
+ for (const name of Array.from(refs).sort()) {
182
+ const val = envMap.get(name);
183
+ if (val === undefined || val === null) {
184
+ missing.push(name);
185
+ }
186
+ else {
187
+ present.push(name);
188
+ // Warn if the value looks like an unfilled placeholder.
189
+ if (looksLikePlaceholder(val)) {
190
+ warnings.push(`${name} is set but value looks like a placeholder ("${val}")`);
191
+ }
192
+ }
193
+ }
194
+ return {
195
+ ok: missing.length === 0,
196
+ recipe: recipeName,
197
+ missing,
198
+ present,
199
+ warnings,
200
+ };
201
+ }
202
+ //# sourceMappingURL=auditEnv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auditEnv.js","sourceRoot":"","sources":["../../src/commands/auditEnv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * `patchwork connect` — the connector front-door.
3
+ *
4
+ * A thin CLI→HTTP shim over the bridge's already-built `/connections/*`
5
+ * routes (see src/connectorRoutes.ts). 23 connector error messages already
6
+ * tell users to "Run: patchwork connect <vendor>"; this is that command.
7
+ *
8
+ * NO new bridge or connector logic lives here — every verb maps to one
9
+ * existing HTTP route:
10
+ * - list → GET /connections (Bearer)
11
+ * - <vendor> → GET /connections/<id>/auth (OAuth, 302 Location)
12
+ * or POST /connections/<id>/connect (PAT, {token})
13
+ * - test → POST /connections/<id>/test (health probe)
14
+ * - disconnect → DELETE /connections/<id> (revoke)
15
+ *
16
+ * Bridge discovery + Bearer auth mirror src/commands/task.ts. All side
17
+ * effects (lock discovery, fetch, stdout/stderr, exit) are injectable so
18
+ * the command is unit-testable without a live bridge.
19
+ */
20
+ import { type ConnectorDescriptor } from "../connectors/connectorRegistry.js";
21
+ interface LockInfo {
22
+ port: number;
23
+ authToken: string;
24
+ }
25
+ export interface ConnectDeps {
26
+ /** Resolve a running bridge. `port` selects a specific lock. */
27
+ findBridgeLock: (port?: number) => LockInfo | null;
28
+ /** HTTP transport (defaults to global fetch). */
29
+ fetchFn: typeof fetch;
30
+ /** Connector roster (defaults to the shared registry). */
31
+ connectors: readonly ConnectorDescriptor[];
32
+ /** stdout sink. */
33
+ write: (s: string) => void;
34
+ /** stderr sink. */
35
+ writeErr: (s: string) => void;
36
+ /** Process exit (capture-only in tests). */
37
+ exit: (code: number) => void;
38
+ }
39
+ /**
40
+ * `patchwork connect ...` dispatcher.
41
+ *
42
+ * `deps` is fully injectable for tests. In production, callers pass
43
+ * `findBridgeLock` (from src/commands/task.ts's lock helper) plus any
44
+ * overrides; everything else defaults to real process I/O.
45
+ */
46
+ export declare function runConnect(argv: string[], deps: Partial<ConnectDeps> & Pick<ConnectDeps, "findBridgeLock">): Promise<void>;
47
+ export {};
@@ -0,0 +1,419 @@
1
+ /**
2
+ * `patchwork connect` — the connector front-door.
3
+ *
4
+ * A thin CLI→HTTP shim over the bridge's already-built `/connections/*`
5
+ * routes (see src/connectorRoutes.ts). 23 connector error messages already
6
+ * tell users to "Run: patchwork connect <vendor>"; this is that command.
7
+ *
8
+ * NO new bridge or connector logic lives here — every verb maps to one
9
+ * existing HTTP route:
10
+ * - list → GET /connections (Bearer)
11
+ * - <vendor> → GET /connections/<id>/auth (OAuth, 302 Location)
12
+ * or POST /connections/<id>/connect (PAT, {token})
13
+ * - test → POST /connections/<id>/test (health probe)
14
+ * - disconnect → DELETE /connections/<id> (revoke)
15
+ *
16
+ * Bridge discovery + Bearer auth mirror src/commands/task.ts. All side
17
+ * effects (lock discovery, fetch, stdout/stderr, exit) are injectable so
18
+ * the command is unit-testable without a live bridge.
19
+ */
20
+ import { CONNECTORS, } from "../connectors/connectorRegistry.js";
21
+ const TIMEOUT_MS = 10_000;
22
+ function parseArgs(argv) {
23
+ const out = {
24
+ positional: [],
25
+ json: false,
26
+ urlOnly: false,
27
+ help: false,
28
+ };
29
+ for (let i = 0; i < argv.length; i++) {
30
+ const a = argv[i];
31
+ if (a === undefined)
32
+ continue;
33
+ if (a === "--json")
34
+ out.json = true;
35
+ else if (a === "--url-only")
36
+ out.urlOnly = true;
37
+ else if (a === "--help" || a === "-h")
38
+ out.help = true;
39
+ else if (a === "--token") {
40
+ const next = argv[++i];
41
+ if (next !== undefined)
42
+ out.token = next;
43
+ }
44
+ else if (a === "--port") {
45
+ const next = argv[++i];
46
+ if (next !== undefined)
47
+ out.port = Number(next);
48
+ }
49
+ else if (!a.startsWith("-")) {
50
+ out.positional.push(a);
51
+ }
52
+ }
53
+ return out;
54
+ }
55
+ // ── helpers ──────────────────────────────────────────────────────────────────
56
+ function bearer(lock) {
57
+ return { Authorization: `Bearer ${lock.authToken}` };
58
+ }
59
+ function statusGlyph(status) {
60
+ if (status === "connected")
61
+ return "✓ connected";
62
+ if (status === "needs_reauth")
63
+ return "⚠ needs reauth";
64
+ return "✗ not connected";
65
+ }
66
+ function normalizeStatus(raw) {
67
+ if (raw === "connected" || raw === "needs_reauth")
68
+ return raw;
69
+ return "disconnected";
70
+ }
71
+ /** Levenshtein distance for "did you mean" suggestions. */
72
+ function editDistance(a, b) {
73
+ const m = a.length;
74
+ const n = b.length;
75
+ const prev = Array.from({ length: n + 1 }, (_, j) => j);
76
+ const curr = new Array(n + 1).fill(0);
77
+ for (let i = 1; i <= m; i++) {
78
+ curr[0] = i;
79
+ for (let j = 1; j <= n; j++) {
80
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
81
+ const del = (prev[j] ?? 0) + 1;
82
+ const ins = (curr[j - 1] ?? 0) + 1;
83
+ const sub = (prev[j - 1] ?? 0) + cost;
84
+ curr[j] = Math.min(del, ins, sub);
85
+ }
86
+ for (let j = 0; j <= n; j++)
87
+ prev[j] = curr[j] ?? 0;
88
+ }
89
+ return prev[n] ?? 0;
90
+ }
91
+ function suggestVendor(input, connectors) {
92
+ let best;
93
+ for (const c of connectors) {
94
+ const dist = editDistance(input, c.id);
95
+ if (!best || dist < best.dist)
96
+ best = { id: c.id, dist };
97
+ }
98
+ // Only suggest when reasonably close.
99
+ return best && best.dist <= 3 ? best.id : undefined;
100
+ }
101
+ function resolveLock(deps, port) {
102
+ const lock = deps.findBridgeLock(port);
103
+ if (!lock) {
104
+ deps.writeErr("No running bridge — start it with: patchwork start\n" +
105
+ (port !== undefined
106
+ ? `(checked port ${port}; lock missing, IDE-owned, or dead)\n`
107
+ : ""));
108
+ deps.exit(1);
109
+ return null;
110
+ }
111
+ return lock;
112
+ }
113
+ async function readJson(res) {
114
+ const text = await res.text();
115
+ if (!text)
116
+ return null;
117
+ try {
118
+ return JSON.parse(text);
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ }
124
+ function networkError(deps, err, json) {
125
+ const msg = err instanceof Error ? err.message : String(err);
126
+ if (json) {
127
+ deps.write(`${JSON.stringify({ ok: false, error: msg })}\n`);
128
+ }
129
+ deps.writeErr(`Error contacting bridge: ${msg}\n`);
130
+ deps.exit(1);
131
+ }
132
+ // ── verbs ────────────────────────────────────────────────────────────────────
133
+ async function runList(deps, args) {
134
+ const lock = resolveLock(deps, args.port);
135
+ if (!lock)
136
+ return;
137
+ let live;
138
+ try {
139
+ const res = await deps.fetchFn(`http://127.0.0.1:${lock.port}/connections`, {
140
+ method: "GET",
141
+ headers: bearer(lock),
142
+ signal: AbortSignal.timeout(TIMEOUT_MS),
143
+ });
144
+ live = await readJson(res);
145
+ }
146
+ catch (err) {
147
+ networkError(deps, err, args.json);
148
+ return;
149
+ }
150
+ // Join live status onto the full registry roster so connectors absent
151
+ // from the response render as not-connected rather than vanishing.
152
+ const statusById = new Map();
153
+ for (const c of live?.connectors ?? []) {
154
+ if (c.id)
155
+ statusById.set(c.id, normalizeStatus(c.status));
156
+ }
157
+ const rows = deps.connectors.map((c) => ({
158
+ id: c.id,
159
+ label: c.label,
160
+ authKind: c.authKind,
161
+ status: statusById.get(c.id) ?? "disconnected",
162
+ }));
163
+ if (args.json) {
164
+ deps.write(`${JSON.stringify({ connectors: rows })}\n`);
165
+ deps.exit(0);
166
+ return;
167
+ }
168
+ // Connected first, then needs_reauth, then disconnected; stable by label.
169
+ const rank = {
170
+ connected: 0,
171
+ needs_reauth: 1,
172
+ disconnected: 2,
173
+ };
174
+ rows.sort((a, b) => rank[a.status] - rank[b.status] || a.label.localeCompare(b.label));
175
+ const idWidth = Math.max(...rows.map((r) => r.id.length), 2);
176
+ deps.write("Connectors:\n");
177
+ for (const r of rows) {
178
+ deps.write(` ${r.id.padEnd(idWidth)} ${statusGlyph(r.status).padEnd(16)}` +
179
+ `${r.label} (${r.authKind})\n`);
180
+ }
181
+ deps.exit(0);
182
+ }
183
+ async function runOauth(deps, descriptor, args) {
184
+ const lock = resolveLock(deps, args.port);
185
+ if (!lock)
186
+ return;
187
+ let res;
188
+ try {
189
+ res = await deps.fetchFn(`http://127.0.0.1:${lock.port}/connections/${descriptor.id}/auth`, {
190
+ method: "GET",
191
+ headers: bearer(lock),
192
+ redirect: "manual",
193
+ signal: AbortSignal.timeout(TIMEOUT_MS),
194
+ });
195
+ }
196
+ catch (err) {
197
+ networkError(deps, err, args.json);
198
+ return;
199
+ }
200
+ const location = res.headers.get("location");
201
+ if (res.status === 302 && location) {
202
+ if (args.json) {
203
+ deps.write(`${JSON.stringify({ ok: true, url: location })}\n`);
204
+ }
205
+ else if (args.urlOnly) {
206
+ deps.write(`${location}\n`);
207
+ }
208
+ else {
209
+ deps.write(`Open this URL in your browser to authorize ${descriptor.label}:\n` +
210
+ ` ${location}\n`);
211
+ }
212
+ deps.exit(0);
213
+ return;
214
+ }
215
+ // No redirect — surface the bridge's error body if present.
216
+ const body = await readJson(res);
217
+ const detail = body?.error ?? `HTTP ${res.status}`;
218
+ if (args.json) {
219
+ deps.write(`${JSON.stringify({ ok: false, error: detail })}\n`);
220
+ }
221
+ deps.writeErr(`Could not start ${descriptor.label} authorization: ${detail}\n`);
222
+ deps.exit(1);
223
+ }
224
+ async function runPatConnect(deps, descriptor, args) {
225
+ if (!args.token) {
226
+ // No token supplied — print honest instructions rather than guessing.
227
+ deps.write(`${descriptor.label} is a token (PAT) connector.\n` +
228
+ ` Pass a token directly:\n` +
229
+ ` patchwork connect ${descriptor.id} --token <TOKEN>\n` +
230
+ ` Some connectors need more than one field (e.g. Jira/Confluence/` +
231
+ `Zendesk/Datadog need a URL + email + token).\n` +
232
+ ` For those, use the dashboard /connections page to connect.\n`);
233
+ deps.exit(0);
234
+ return;
235
+ }
236
+ const lock = resolveLock(deps, args.port);
237
+ if (!lock)
238
+ return;
239
+ let res;
240
+ try {
241
+ res = await deps.fetchFn(`http://127.0.0.1:${lock.port}/connections/${descriptor.id}/connect`, {
242
+ method: "POST",
243
+ headers: { ...bearer(lock), "Content-Type": "application/json" },
244
+ body: JSON.stringify({ token: args.token }),
245
+ signal: AbortSignal.timeout(TIMEOUT_MS),
246
+ });
247
+ }
248
+ catch (err) {
249
+ networkError(deps, err, args.json);
250
+ return;
251
+ }
252
+ const body = await readJson(res);
253
+ const ok = res.status >= 200 && res.status < 300 && body?.ok !== false;
254
+ if (args.json) {
255
+ deps.write(`${JSON.stringify({ ok, ...(body ?? {}) })}\n`);
256
+ }
257
+ else if (ok) {
258
+ const where = body?.workspace ? ` (workspace: ${body.workspace})` : "";
259
+ deps.write(`✓ Connected ${descriptor.label}${where}\n`);
260
+ }
261
+ else {
262
+ deps.writeErr(`✗ Failed to connect ${descriptor.label}: ${body?.error ?? `HTTP ${res.status}`}\n`);
263
+ }
264
+ deps.exit(ok ? 0 : 1);
265
+ }
266
+ async function runTest(deps, vendor, args) {
267
+ const descriptor = resolveVendor(deps, vendor);
268
+ if (!descriptor)
269
+ return;
270
+ const lock = resolveLock(deps, args.port);
271
+ if (!lock)
272
+ return;
273
+ let res;
274
+ try {
275
+ res = await deps.fetchFn(`http://127.0.0.1:${lock.port}/connections/${descriptor.id}/test`, {
276
+ method: "POST",
277
+ headers: bearer(lock),
278
+ signal: AbortSignal.timeout(TIMEOUT_MS),
279
+ });
280
+ }
281
+ catch (err) {
282
+ networkError(deps, err, args.json);
283
+ return;
284
+ }
285
+ const body = await readJson(res);
286
+ const ok = res.status >= 200 && res.status < 300 && body?.ok !== false;
287
+ if (args.json) {
288
+ deps.write(`${JSON.stringify({ ok, ...(body ?? {}) })}\n`);
289
+ }
290
+ else if (ok) {
291
+ deps.write(`✓ ${descriptor.label} is healthy\n`);
292
+ }
293
+ else {
294
+ deps.writeErr(`✗ ${descriptor.label} test failed: ${body?.error ?? `HTTP ${res.status}`}\n`);
295
+ }
296
+ deps.exit(ok ? 0 : 1);
297
+ }
298
+ async function runDisconnect(deps, vendor, args) {
299
+ const descriptor = resolveVendor(deps, vendor);
300
+ if (!descriptor)
301
+ return;
302
+ const lock = resolveLock(deps, args.port);
303
+ if (!lock)
304
+ return;
305
+ let res;
306
+ try {
307
+ res = await deps.fetchFn(`http://127.0.0.1:${lock.port}/connections/${descriptor.id}`, {
308
+ method: "DELETE",
309
+ headers: bearer(lock),
310
+ signal: AbortSignal.timeout(TIMEOUT_MS),
311
+ });
312
+ }
313
+ catch (err) {
314
+ networkError(deps, err, args.json);
315
+ return;
316
+ }
317
+ const body = await readJson(res);
318
+ const ok = res.status >= 200 && res.status < 300 && body?.ok !== false;
319
+ if (args.json) {
320
+ deps.write(`${JSON.stringify({ ok, ...(body ?? {}) })}\n`);
321
+ }
322
+ else if (ok) {
323
+ deps.write(`✓ Disconnected ${descriptor.label}\n`);
324
+ }
325
+ else {
326
+ deps.writeErr(`✗ Failed to disconnect ${descriptor.label}: ${body?.error ?? `HTTP ${res.status}`}\n`);
327
+ }
328
+ deps.exit(ok ? 0 : 1);
329
+ }
330
+ /** Resolve a vendor id to its descriptor, or emit an error + exit(1). */
331
+ function resolveVendor(deps, vendor) {
332
+ if (!vendor) {
333
+ deps.writeErr("Missing connector id.\n");
334
+ deps.exit(1);
335
+ return undefined;
336
+ }
337
+ const descriptor = deps.connectors.find((c) => c.id === vendor);
338
+ if (!descriptor) {
339
+ const hint = suggestVendor(vendor, deps.connectors);
340
+ const validIds = deps.connectors.map((c) => c.id).join(", ");
341
+ deps.writeErr(`Unknown connector "${vendor}".\n` +
342
+ (hint ? `Did you mean "${hint}"?\n` : "") +
343
+ `Valid ids: ${validIds}\n`);
344
+ deps.exit(1);
345
+ return undefined;
346
+ }
347
+ return descriptor;
348
+ }
349
+ function printHelp(deps) {
350
+ deps.write("Usage: patchwork connect [<vendor>|list|test <vendor>|disconnect <vendor>]\n" +
351
+ "\n" +
352
+ " connect [list] [--json] List connectors + connection status\n" +
353
+ " connect <vendor> [--url-only] OAuth: print the authorize URL to open\n" +
354
+ " connect <vendor> --token <TOKEN> PAT: paste a token to connect\n" +
355
+ " connect test <vendor> [--json] Health-probe a connector\n" +
356
+ " connect disconnect <vendor> Revoke a connector\n" +
357
+ "\n" +
358
+ " --port <n> Target a specific bridge lock\n" +
359
+ " --url-only Print only the OAuth URL (headless/CI)\n" +
360
+ " --json Machine-readable output\n");
361
+ deps.exit(0);
362
+ }
363
+ // ── entrypoint ───────────────────────────────────────────────────────────────
364
+ const DEFAULT_DEPS = {
365
+ fetchFn: globalThis.fetch,
366
+ connectors: CONNECTORS,
367
+ write: (s) => process.stdout.write(s),
368
+ writeErr: (s) => process.stderr.write(s),
369
+ exit: (c) => process.exit(c),
370
+ };
371
+ /**
372
+ * `patchwork connect ...` dispatcher.
373
+ *
374
+ * `deps` is fully injectable for tests. In production, callers pass
375
+ * `findBridgeLock` (from src/commands/task.ts's lock helper) plus any
376
+ * overrides; everything else defaults to real process I/O.
377
+ */
378
+ export async function runConnect(argv, deps) {
379
+ const resolved = { ...DEFAULT_DEPS, ...deps };
380
+ const args = parseArgs(argv);
381
+ if (args.help) {
382
+ printHelp(resolved);
383
+ return;
384
+ }
385
+ const verb = args.positional[0];
386
+ // Bare `connect` or `connect list` → list.
387
+ if (verb === undefined || verb === "list") {
388
+ await runList(resolved, args);
389
+ return;
390
+ }
391
+ if (verb === "test") {
392
+ await runTest(resolved, args.positional[1], args);
393
+ return;
394
+ }
395
+ if (verb === "disconnect") {
396
+ await runDisconnect(resolved, args.positional[1], args);
397
+ return;
398
+ }
399
+ // Otherwise `verb` is a vendor id: OAuth (auth) or PAT (connect).
400
+ const descriptor = resolveVendor(resolved, verb);
401
+ if (!descriptor)
402
+ return;
403
+ if (descriptor.authKind === "oauth" && descriptor.supports.auth) {
404
+ await runOauth(resolved, descriptor, args);
405
+ return;
406
+ }
407
+ if (descriptor.supports.connect) {
408
+ await runPatConnect(resolved, descriptor, args);
409
+ return;
410
+ }
411
+ // OAuth-capable PAT connectors (auth:true but pat): prefer the token path.
412
+ if (descriptor.supports.auth) {
413
+ await runOauth(resolved, descriptor, args);
414
+ return;
415
+ }
416
+ resolved.writeErr(`Connector "${descriptor.id}" does not support an interactive connect flow.\n`);
417
+ resolved.exit(1);
418
+ }
419
+ //# sourceMappingURL=connect.js.map