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,236 @@
1
+ /**
2
+ * Parses + allowlists the `github:<owner>/<repo>/(recipes|bundles)/<name>`
3
+ * source format used by `POST /recipes/install`.
4
+ *
5
+ * Before this module existed, the install handler hard-coded
6
+ * `github:patchworkos/recipes/...` everywhere — every URL, every
7
+ * prefix match. Third-party orgs / forks / private mirrors could not
8
+ * host recipe catalogs even though the rest of the install pipeline
9
+ * (SSRF guard, parser, scheduler) is org-agnostic.
10
+ *
11
+ * Allowlist policy:
12
+ * - Always includes `patchworkos/recipes` (backward compat).
13
+ * - Operator opts in additional `<owner>/<repo>` entries via the
14
+ * `PATCHWORK_RECIPE_REPO_ALLOWLIST` env var (comma-separated).
15
+ * - Allowlist matching is case-insensitive (GitHub itself is).
16
+ * - Both owner and repo segments must match the strict regex
17
+ * `[a-z0-9_.-]{1,100}` AFTER lowercasing — guards against
18
+ * traversal segments smuggled into the source string.
19
+ *
20
+ * The default-only behaviour matches the audit recommendation: real
21
+ * multi-org support is opt-in, so existing single-org deployments
22
+ * don't see a behaviour change.
23
+ */
24
+ const DEFAULT_ALLOWLIST = ["patchworkos/recipes"];
25
+ export const SEGMENT_RE = /^(?!.*\.\.)[a-z0-9_.-]{1,100}$/;
26
+ /**
27
+ * Read the runtime allowlist. Combines the always-on default with
28
+ * whatever the operator has set in PATCHWORK_RECIPE_REPO_ALLOWLIST.
29
+ * Entries are lowercased + de-duplicated; trailing whitespace, empty
30
+ * fragments, and shapes that don't look like `owner/repo` are
31
+ * silently dropped (logging here is the install handler's job, not
32
+ * this pure helper's).
33
+ */
34
+ export function loadAllowlist(env = process.env) {
35
+ const fromEnv = (env.PATCHWORK_RECIPE_REPO_ALLOWLIST ?? "")
36
+ .split(",")
37
+ .map((s) => s.trim().toLowerCase())
38
+ .filter((s) => s.length > 0 && s.includes("/"));
39
+ return Array.from(new Set([...DEFAULT_ALLOWLIST, ...fromEnv]));
40
+ }
41
+ /**
42
+ * Parse a `github:owner/repo/(recipes|bundles)/name` source string
43
+ * against the active allowlist. Pure — does NOT fetch anything; the
44
+ * install handler is responsible for the network leg and the SSRF
45
+ * guard. Returns a discriminated union the caller can map to a 400
46
+ * (bad_shape / bad_segment) or 403 (not_allowlisted) response.
47
+ */
48
+ export function parseGithubInstallSource(source, allowlist = loadAllowlist()) {
49
+ if (!source.startsWith("github:")) {
50
+ return {
51
+ ok: false,
52
+ code: "bad_shape",
53
+ error: "source must start with 'github:'",
54
+ };
55
+ }
56
+ // After the `github:` prefix we expect <owner>/<repo>/<kind>/<name>.
57
+ // We split into exactly 4 segments — extra trailing slashes or
58
+ // missing components are rejected with `bad_shape` so the response
59
+ // is actionable.
60
+ const tail = source.slice("github:".length);
61
+ const segments = tail.split("/");
62
+ if (segments.length !== 4) {
63
+ return {
64
+ ok: false,
65
+ code: "bad_shape",
66
+ error: "source must match 'github:<owner>/<repo>/(recipes|bundles)/<name>'",
67
+ };
68
+ }
69
+ const [ownerRaw, repoRaw, kindRaw, nameRaw] = segments;
70
+ const owner = ownerRaw.toLowerCase();
71
+ const repo = repoRaw.toLowerCase();
72
+ if (!SEGMENT_RE.test(owner) || !SEGMENT_RE.test(repo)) {
73
+ return {
74
+ ok: false,
75
+ code: "bad_segment",
76
+ error: "owner and repo must match [a-z0-9_.-]{1,100}",
77
+ };
78
+ }
79
+ if (kindRaw !== "recipes" && kindRaw !== "bundles") {
80
+ return {
81
+ ok: false,
82
+ code: "bad_shape",
83
+ error: "third path segment must be 'recipes' or 'bundles'",
84
+ };
85
+ }
86
+ // Extract an optional trailing `@<ref>` from the name segment so dashboard /
87
+ // HTTP installs can pin a branch / tag / commit SHA, matching the CLI path
88
+ // (`github:owner/repo[@ref]`). The ref is opaque to us — git accepts
89
+ // branches, tags, and SHAs in the same slot — but we apply the same charset
90
+ // guard recipeInstall.ts uses so it can't smuggle URL syntax into the
91
+ // constructed raw / api URLs.
92
+ let name = nameRaw;
93
+ let ref;
94
+ const atIdx = nameRaw.lastIndexOf("@");
95
+ if (atIdx !== -1) {
96
+ ref = nameRaw.slice(atIdx + 1);
97
+ name = nameRaw.slice(0, atIdx);
98
+ if (!ref) {
99
+ return {
100
+ ok: false,
101
+ code: "bad_segment",
102
+ error: "ref after '@' must not be empty",
103
+ };
104
+ }
105
+ if (/[@:?#\s]/.test(ref) || ref.includes("..")) {
106
+ return {
107
+ ok: false,
108
+ code: "bad_segment",
109
+ error: "ref contains disallowed characters",
110
+ };
111
+ }
112
+ }
113
+ // Reuse the strict basename predicate inline rather than importing
114
+ // recipeInstall.ts here (circular deps), but match its rules:
115
+ // single segment, no `..`, no slashes, conservative charset, ≤100.
116
+ if (!SEGMENT_RE.test(name.toLowerCase())) {
117
+ return {
118
+ ok: false,
119
+ code: "bad_segment",
120
+ error: "name must match [a-z0-9_.-]{1,100}",
121
+ };
122
+ }
123
+ const allowSet = new Set(allowlist.map((s) => s.toLowerCase()));
124
+ if (!allowSet.has(`${owner}/${repo}`)) {
125
+ return {
126
+ ok: false,
127
+ code: "not_allowlisted",
128
+ error: `'${owner}/${repo}' is not in the recipe-repo allowlist. Set PATCHWORK_RECIPE_REPO_ALLOWLIST=${owner}/${repo} to opt in.`,
129
+ };
130
+ }
131
+ return {
132
+ ok: true,
133
+ parsed: {
134
+ kind: kindRaw === "recipes" ? "recipe" : "bundle",
135
+ owner,
136
+ repo,
137
+ name,
138
+ ...(ref ? { ref } : {}),
139
+ },
140
+ };
141
+ }
142
+ /**
143
+ * The repo-relative path of the file for a parsed install source.
144
+ * `recipes/<name>/<name>.yaml` or `bundles/<name>/patchwork-bundle.json`.
145
+ */
146
+ function repoRelativePath(parsed) {
147
+ if (parsed.kind === "recipe") {
148
+ return `recipes/${parsed.name}/${parsed.name}.yaml`;
149
+ }
150
+ return `bundles/${parsed.name}/patchwork-bundle.json`;
151
+ }
152
+ /**
153
+ * Build the raw.githubusercontent URL for a parsed install source.
154
+ * Uses the pinned `parsed.ref` (branch / tag / commit SHA) when present,
155
+ * else defaults to the `main` branch HEAD.
156
+ */
157
+ export function buildGithubRawUrl(parsed) {
158
+ const ref = parsed.ref ?? "main";
159
+ return `https://raw.githubusercontent.com/${parsed.owner}/${parsed.repo}/${ref}/${repoRelativePath(parsed)}`;
160
+ }
161
+ /**
162
+ * Build the `api.github.com` Contents-API URL for a parsed install
163
+ * source. Used as a FALLBACK when `raw.githubusercontent.com` is
164
+ * unreachable — many corporate / proxied networks block the raw host
165
+ * even when `api.github.com` is allowed. Combined with the
166
+ * `Accept: application/vnd.github.raw` request header (see
167
+ * `fetchGithubInstallFile`), this endpoint returns the raw file bytes
168
+ * directly — no base64 decode needed. Public repos work unauthenticated.
169
+ */
170
+ export function buildGithubApiUrl(parsed) {
171
+ const ref = parsed.ref ?? "main";
172
+ return `https://api.github.com/repos/${parsed.owner}/${parsed.repo}/contents/${repoRelativePath(parsed)}?ref=${ref}`;
173
+ }
174
+ export async function fetchGithubInstallFile(parsed, init = {}) {
175
+ const rawUrl = buildGithubRawUrl(parsed);
176
+ let rawResponse = null;
177
+ let rawNetworkError = null;
178
+ try {
179
+ rawResponse = await fetch(rawUrl, {
180
+ signal: init.signal,
181
+ redirect: "follow",
182
+ });
183
+ }
184
+ catch (err) {
185
+ rawNetworkError = err;
186
+ }
187
+ // Fast path: raw host returned a usable response.
188
+ if (rawResponse?.ok) {
189
+ return { ok: true, response: rawResponse };
190
+ }
191
+ // Raw host either threw OR returned non-ok → try the API fallback.
192
+ const apiUrl = buildGithubApiUrl(parsed);
193
+ let apiResponse = null;
194
+ let apiNetworkError = null;
195
+ try {
196
+ apiResponse = await fetch(apiUrl, {
197
+ signal: init.signal,
198
+ redirect: "follow",
199
+ headers: { Accept: "application/vnd.github.raw" },
200
+ });
201
+ }
202
+ catch (err) {
203
+ apiNetworkError = err;
204
+ }
205
+ if (apiResponse?.ok) {
206
+ return { ok: true, response: apiResponse };
207
+ }
208
+ // Neither host yielded an ok body. Decide which failure to surface.
209
+ //
210
+ // A non-404 HTTP failure (5xx / 403 rate-limit) is the most
211
+ // actionable signal — prefer it over a 404 from the other host, so a
212
+ // transient upstream problem isn't misreported as "recipe missing".
213
+ // The API response is the more authoritative of the two here (raw is
214
+ // a CDN; the API gives proper status codes), so check it first.
215
+ if (apiResponse && apiResponse.status !== 404) {
216
+ return { ok: false, kind: "upstream_error", response: apiResponse };
217
+ }
218
+ if (rawResponse && rawResponse.status !== 404) {
219
+ return { ok: false, kind: "upstream_error", response: rawResponse };
220
+ }
221
+ // Whatever is left is a genuine 404 from one or both hosts → keep
222
+ // the not-found distinction so the caller surfaces a 404, not a 502.
223
+ if (apiResponse && apiResponse.status === 404) {
224
+ return { ok: false, kind: "not_found", response: apiResponse };
225
+ }
226
+ if (rawResponse && rawResponse.status === 404) {
227
+ return { ok: false, kind: "not_found", response: rawResponse };
228
+ }
229
+ // Both hosts threw network errors.
230
+ return {
231
+ ok: false,
232
+ kind: "network_error",
233
+ error: apiNetworkError ?? rawNetworkError,
234
+ };
235
+ }
236
+ //# sourceMappingURL=githubInstallSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubInstallSource.js","sourceRoot":"","sources":["../../src/recipes/githubInstallSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Halt-category derivation.
3
+ *
4
+ * PR1c of the Val-inspired plan. PR1 attached a `haltReason` sentence to
5
+ * every error-status StepResult; this module categorises those sentences
6
+ * into a small bounded enum so the dashboard / metrics layer can count
7
+ * them over time. Foundation for "is the haltReason work actually
8
+ * surfacing useful signal, or is everything landing in `unknown`?"
9
+ *
10
+ * The mapping is intentionally pattern-based against the 5 phrases
11
+ * emitted by yamlRunner.ts. Keep this file and those phrases in sync.
12
+ * When a new error site is added, add a category here AND a test.
13
+ */
14
+ export type HaltCategory = "agent_silent_fail" | "agent_narration_only" | "agent_threw" | "tool_threw" | "tool_error"
15
+ /** Write blocked by the global kill-switch (#422). Distinct from a real tool failure. */
16
+ | "kill_switch"
17
+ /** Recipe's `tokensMax` budget breached (PR2b). */
18
+ | "budget_exceeded"
19
+ /** Per-step `expect` assertion failed (slice 2). */
20
+ | "expect_failed"
21
+ /** Per-step wall-clock `timeout_ms` exceeded (sandbox-alternative slice). */
22
+ | "step_timeout"
23
+ /**
24
+ * Connector returned 401/403 — token expired or scopes insufficient.
25
+ * Actionable: user should reconnect from /connections.
26
+ */
27
+ | "auth_failure"
28
+ /**
29
+ * External service returned 429 / rate limit. Actionable: retry later
30
+ * or back off the cron cadence.
31
+ */
32
+ | "rate_limited"
33
+ /**
34
+ * Transport failed before the request reached the service
35
+ * (ECONNREFUSED, ENOTFOUND, fetch failed). Distinct from a 4xx/5xx
36
+ * from the service itself — usually a local network / DNS issue.
37
+ */
38
+ | "network_error"
39
+ /**
40
+ * Tool needed a connector that isn't configured for this workspace.
41
+ * Actionable: install/connect from /connections.
42
+ */
43
+ | "missing_connector"
44
+ /** Whole-recipe failure (e.g. circular dependencies) — has no step row. */
45
+ | "run_level" | "unknown";
46
+ /**
47
+ * Human-readable label per category. Shared by the `halts` CLI, the
48
+ * `recipe doctor` command, and (mirrored) the dashboard, so the wording
49
+ * stays consistent across surfaces.
50
+ */
51
+ export declare const HALT_CATEGORY_LABELS: Record<HaltCategory, string>;
52
+ /**
53
+ * Actionable one-liner per category — "what to do about it". Shared by
54
+ * the `halts` CLI and `recipe doctor` so SSH / mobile users get the fix
55
+ * hint without opening the dashboard.
56
+ */
57
+ export declare const HALT_CATEGORY_HINTS: Record<HaltCategory, string>;
58
+ export declare function categoriseHaltReason(reason: string | undefined): HaltCategory;
59
+ export interface HaltSummary {
60
+ /** Total error-status step results scanned. */
61
+ total: number;
62
+ /** Per-category counts; categories with zero hits are omitted. */
63
+ byCategory: Partial<Record<HaltCategory, number>>;
64
+ /** Most recent 5 halt reasons (verbatim) for surfacing in the UI. */
65
+ recent: Array<{
66
+ reason: string;
67
+ category: HaltCategory;
68
+ runSeq: number;
69
+ }>;
70
+ }
71
+ interface HaltSummaryInputRun {
72
+ seq: number;
73
+ /** Top-level run status — `run_level` halts are runs with status === "error" but no error stepResults (e.g. circular-dep failure before any step ran). */
74
+ status?: "running" | "done" | "error" | "cancelled" | "interrupted";
75
+ /** Top-level errorMessage — surfaced as a `run_level` halt when no per-step halts cover it. */
76
+ errorMessage?: string;
77
+ stepResults?: Array<{
78
+ status: "ok" | "skipped" | "error";
79
+ haltReason?: string;
80
+ /** Pre-tagged category from yamlRunner throw site — avoids regex re-derivation when present. */
81
+ haltCategory?: HaltCategory;
82
+ }>;
83
+ }
84
+ /**
85
+ * Aggregate halt categories across a set of runs. Runs are expected to be
86
+ * sorted newest-first so `recent` reflects the most recent halts.
87
+ *
88
+ * A run contributes:
89
+ * - one entry per error-status stepResult that has a `haltReason`
90
+ * - plus one `run_level` entry if `status === "error"` and there were no
91
+ * per-step halts that already explained it (avoids double-counting).
92
+ */
93
+ export declare function summariseHalts(runs: HaltSummaryInputRun[]): HaltSummary;
94
+ /**
95
+ * Format a `HaltSummary` as Prometheus text-exposition lines for the
96
+ * `bridge_recipe_halts{category="..."} N` gauge. Returns an empty array
97
+ * when the summary is empty (no HELP/TYPE block emitted in that case so
98
+ * Prom scrapers don't see an orphan declaration).
99
+ *
100
+ * Surfaced via `/metrics` so users with their own observability stack
101
+ * can dashboard halts without using Patchwork's UI.
102
+ */
103
+ export declare function haltSummaryToPrometheus(summary: HaltSummary): string[];
104
+ /**
105
+ * Derive a one-sentence haltReason from a step's error-status + raw error
106
+ * string. Used by `chainedRunner` to mirror the convention emitted by
107
+ * `yamlRunner`. Returns `undefined` for non-error rows or missing error.
108
+ *
109
+ * Pattern-matches the same phrases `categoriseHaltReason` knows about,
110
+ * so chained-run haltReasons categorise into the same buckets.
111
+ */
112
+ export declare function deriveHaltReasonFromError(opts: {
113
+ stepId: string;
114
+ toolName?: string;
115
+ isAgent?: boolean;
116
+ status: "ok" | "skipped" | "error";
117
+ error?: string;
118
+ }): string | undefined;
119
+ export {};
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Halt-category derivation.
3
+ *
4
+ * PR1c of the Val-inspired plan. PR1 attached a `haltReason` sentence to
5
+ * every error-status StepResult; this module categorises those sentences
6
+ * into a small bounded enum so the dashboard / metrics layer can count
7
+ * them over time. Foundation for "is the haltReason work actually
8
+ * surfacing useful signal, or is everything landing in `unknown`?"
9
+ *
10
+ * The mapping is intentionally pattern-based against the 5 phrases
11
+ * emitted by yamlRunner.ts. Keep this file and those phrases in sync.
12
+ * When a new error site is added, add a category here AND a test.
13
+ */
14
+ /**
15
+ * Human-readable label per category. Shared by the `halts` CLI, the
16
+ * `recipe doctor` command, and (mirrored) the dashboard, so the wording
17
+ * stays consistent across surfaces.
18
+ */
19
+ export const HALT_CATEGORY_LABELS = {
20
+ agent_silent_fail: "agent silent-fail",
21
+ agent_narration_only: "agent narration-only",
22
+ agent_threw: "agent threw",
23
+ tool_threw: "tool threw",
24
+ tool_error: "tool error",
25
+ kill_switch: "kill-switch blocked",
26
+ budget_exceeded: "budget exceeded",
27
+ expect_failed: "expect failed",
28
+ step_timeout: "step timeout",
29
+ auth_failure: "auth failure",
30
+ rate_limited: "rate limited",
31
+ network_error: "network error",
32
+ missing_connector: "missing connector",
33
+ run_level: "run-level halt",
34
+ unknown: "uncategorised",
35
+ };
36
+ /**
37
+ * Actionable one-liner per category — "what to do about it". Shared by
38
+ * the `halts` CLI and `recipe doctor` so SSH / mobile users get the fix
39
+ * hint without opening the dashboard.
40
+ */
41
+ export const HALT_CATEGORY_HINTS = {
42
+ agent_silent_fail: "inspect prompt + check trace",
43
+ agent_narration_only: "tighten prompt or add `into:` target",
44
+ agent_threw: "open run trace",
45
+ tool_threw: "check inner error in trace",
46
+ tool_error: "check inner error in trace",
47
+ kill_switch: "run `patchwork kill-switch release`",
48
+ budget_exceeded: "raise tokensMax or shrink prompts",
49
+ expect_failed: "inspect assertion vs actual output",
50
+ step_timeout: "bump timeout_ms or speed up step",
51
+ auth_failure: "reconnect from /connections",
52
+ rate_limited: "back off cron cadence or wait",
53
+ network_error: "check connectivity to upstream",
54
+ missing_connector: "install/connect from /connections",
55
+ run_level: "check recipe for circular deps / parse errors",
56
+ unknown: "open run trace for raw error",
57
+ };
58
+ export function categoriseHaltReason(reason) {
59
+ if (!reason)
60
+ return "unknown";
61
+ // Order matters: more specific phrases (silent-fail, narration, kill
62
+ // switch) must match before the general "Agent step ... threw" /
63
+ // "Tool ... threw" patterns. The phrases below mirror
64
+ // yamlRunner.ts:558-606,677-684,693-708 and
65
+ // featureFlags.ts:assertWriteAllowed.
66
+ if (/silent-fail/i.test(reason))
67
+ return "agent_silent_fail";
68
+ if (/narration|whitespace|no content/i.test(reason))
69
+ return "agent_narration_only";
70
+ if (/kill[- _]?switch/i.test(reason))
71
+ return "kill_switch";
72
+ if (/budget[_ ]?exceeded|exceeded its token budget/i.test(reason))
73
+ return "budget_exceeded";
74
+ if (/^expect_failed/i.test(reason))
75
+ return "expect_failed";
76
+ // Must precede the `^Tool ... threw` matcher: timeouts surface wrapped
77
+ // inside the tool-threw envelope (`Tool "x" in step "y" threw: step_timeout: ...`).
78
+ if (/step_timeout/i.test(reason))
79
+ return "step_timeout";
80
+ // Sub-categories that peek inside the wrapped `Tool "x" threw: <inner>` /
81
+ // `Tool "x" reported an error: <inner>` envelope. Must precede the
82
+ // generic `tool_threw` / `tool_error` matchers below. Patterns are
83
+ // deliberately narrow — e.g. "unreachable" alone stays in `tool_error`
84
+ // because too many tools use it as a generic phrase.
85
+ if (/\b(401|403)\b|unauthori[sz]ed|forbidden|invalid[_ -]?token|token[_ -]?expired|authentication[_ -]?failed/i.test(reason))
86
+ return "auth_failure";
87
+ if (/\b429\b|rate[_ -]?limit|too many requests/i.test(reason))
88
+ return "rate_limited";
89
+ if (/ECONNREFUSED|ENOTFOUND|ECONNRESET|ETIMEDOUT|EAI_AGAIN|fetch failed|network[_ -]?error|getaddrinfo/i.test(reason))
90
+ return "network_error";
91
+ if (/connector[_ -]?not[_ -]?configured|no[_ -]?(connector[_ -]?)?token|not[_ -]?connected|missing[_ -]?connector/i.test(reason))
92
+ return "missing_connector";
93
+ if (/^Agent step .* threw/i.test(reason))
94
+ return "agent_threw";
95
+ if (/^Tool .* threw/i.test(reason))
96
+ return "tool_threw";
97
+ if (/^Tool .* reported an error/i.test(reason))
98
+ return "tool_error";
99
+ return "unknown";
100
+ }
101
+ /**
102
+ * Aggregate halt categories across a set of runs. Runs are expected to be
103
+ * sorted newest-first so `recent` reflects the most recent halts.
104
+ *
105
+ * A run contributes:
106
+ * - one entry per error-status stepResult that has a `haltReason`
107
+ * - plus one `run_level` entry if `status === "error"` and there were no
108
+ * per-step halts that already explained it (avoids double-counting).
109
+ */
110
+ export function summariseHalts(runs) {
111
+ const byCategory = {};
112
+ const recent = [];
113
+ let total = 0;
114
+ for (const run of runs) {
115
+ let stepHaltsForRun = 0;
116
+ for (const step of run.stepResults ?? []) {
117
+ if (step.status !== "error" || !step.haltReason)
118
+ continue;
119
+ stepHaltsForRun++;
120
+ total++;
121
+ const cat = step.haltCategory ?? categoriseHaltReason(step.haltReason);
122
+ byCategory[cat] = (byCategory[cat] ?? 0) + 1;
123
+ if (recent.length < 5) {
124
+ recent.push({
125
+ reason: step.haltReason,
126
+ category: cat,
127
+ runSeq: run.seq,
128
+ });
129
+ }
130
+ }
131
+ if (stepHaltsForRun === 0 && run.status === "error" && run.errorMessage) {
132
+ total++;
133
+ byCategory.run_level = (byCategory.run_level ?? 0) + 1;
134
+ if (recent.length < 5) {
135
+ recent.push({
136
+ reason: run.errorMessage,
137
+ category: "run_level",
138
+ runSeq: run.seq,
139
+ });
140
+ }
141
+ }
142
+ }
143
+ return { total, byCategory, recent };
144
+ }
145
+ /**
146
+ * Format a `HaltSummary` as Prometheus text-exposition lines for the
147
+ * `bridge_recipe_halts{category="..."} N` gauge. Returns an empty array
148
+ * when the summary is empty (no HELP/TYPE block emitted in that case so
149
+ * Prom scrapers don't see an orphan declaration).
150
+ *
151
+ * Surfaced via `/metrics` so users with their own observability stack
152
+ * can dashboard halts without using Patchwork's UI.
153
+ */
154
+ export function haltSummaryToPrometheus(summary) {
155
+ if (summary.total === 0)
156
+ return [];
157
+ const lines = [
158
+ "# HELP bridge_recipe_halts Recipe halts in the in-memory run-log window, by category",
159
+ "# TYPE bridge_recipe_halts gauge",
160
+ ];
161
+ for (const [category, count] of Object.entries(summary.byCategory)) {
162
+ lines.push(`bridge_recipe_halts{category="${category}"} ${count}`);
163
+ }
164
+ return lines;
165
+ }
166
+ /**
167
+ * Derive a one-sentence haltReason from a step's error-status + raw error
168
+ * string. Used by `chainedRunner` to mirror the convention emitted by
169
+ * `yamlRunner`. Returns `undefined` for non-error rows or missing error.
170
+ *
171
+ * Pattern-matches the same phrases `categoriseHaltReason` knows about,
172
+ * so chained-run haltReasons categorise into the same buckets.
173
+ */
174
+ export function deriveHaltReasonFromError(opts) {
175
+ if (opts.status !== "error" || !opts.error)
176
+ return undefined;
177
+ if (/silent-fail/i.test(opts.error)) {
178
+ return `Step "${opts.stepId}" returned no usable output (silent-fail).`;
179
+ }
180
+ if (/narration|whitespace|no content/i.test(opts.error)) {
181
+ return `Step "${opts.stepId}" returned only narration or whitespace — no content.`;
182
+ }
183
+ if (opts.isAgent) {
184
+ return `Agent step "${opts.stepId}" threw before completing: ${opts.error}`;
185
+ }
186
+ return `Tool "${opts.toolName ?? "?"}" in step "${opts.stepId}" reported an error: ${opts.error}`;
187
+ }
188
+ //# sourceMappingURL=haltCategory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"haltCategory.js","sourceRoot":"","sources":["../../src/recipes/haltCategory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAyCH;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAiC;IAChE,iBAAiB,EAAE,mBAAmB;IACtC,oBAAoB,EAAE,sBAAsB;IAC5C,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,qBAAqB;IAClC,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,SAAS,EAAE,gBAAgB;IAC3B,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiC;IAC/D,iBAAiB,EAAE,8BAA8B;IACjD,oBAAoB,EAAE,sCAAsC;IAC5D,WAAW,EAAE,gBAAgB;IAC7B,UAAU,EAAE,4BAA4B;IACxC,UAAU,EAAE,4BAA4B;IACxC,WAAW,EAAE,qCAAqC;IAClD,eAAe,EAAE,mCAAmC;IACpD,aAAa,EAAE,oCAAoC;IACnD,YAAY,EAAE,kCAAkC;IAChD,YAAY,EAAE,6BAA6B;IAC3C,YAAY,EAAE,+BAA+B;IAC7C,aAAa,EAAE,gCAAgC;IAC/C,iBAAiB,EAAE,mCAAmC;IACtD,SAAS,EAAE,+CAA+C;IAC1D,OAAO,EAAE,8BAA8B;CACxC,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,MAA0B;IAC7D,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,qEAAqE;IACrE,iEAAiE;IACjE,sDAAsD;IACtD,4CAA4C;IAC5C,sCAAsC;IACtC,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAC5D,IAAI,kCAAkC,CAAC,IAAI,CAAC,MAAM,CAAC;QACjD,OAAO,sBAAsB,CAAC;IAChC,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,aAAa,CAAC;IAC3D,IAAI,gDAAgD,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/D,OAAO,iBAAiB,CAAC;IAC3B,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,eAAe,CAAC;IAC3D,uEAAuE;IACvE,oFAAoF;IACpF,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,cAAc,CAAC;IACxD,0EAA0E;IAC1E,mEAAmE;IACnE,mEAAmE;IACnE,uEAAuE;IACvE,qDAAqD;IACrD,IACE,2GAA2G,CAAC,IAAI,CAC9G,MAAM,CACP;QAED,OAAO,cAAc,CAAC;IACxB,IAAI,4CAA4C,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3D,OAAO,cAAc,CAAC;IACxB,IACE,oGAAoG,CAAC,IAAI,CACvG,MAAM,CACP;QAED,OAAO,eAAe,CAAC;IACzB,IACE,+GAA+G,CAAC,IAAI,CAClH,MAAM,CACP;QAED,OAAO,mBAAmB,CAAC;IAC7B,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,aAAa,CAAC;IAC/D,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IACxD,IAAI,6BAA6B,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IACpE,OAAO,SAAS,CAAC;AACnB,CAAC;AAyBD;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,IAA2B;IACxD,MAAM,UAAU,GAA0C,EAAE,CAAC;IAC7D,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,SAAS;YAC1D,eAAe,EAAE,CAAC;YAClB,KAAK,EAAE,CAAC;YACR,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,IAAI,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACvE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC;oBACV,MAAM,EAAE,IAAI,CAAC,UAAU;oBACvB,QAAQ,EAAE,GAAG;oBACb,MAAM,EAAE,GAAG,CAAC,GAAG;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,IAAI,eAAe,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;YACxE,KAAK,EAAE,CAAC;YACR,UAAU,CAAC,SAAS,GAAG,CAAC,UAAU,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC;oBACV,MAAM,EAAE,GAAG,CAAC,YAAY;oBACxB,QAAQ,EAAE,WAAW;oBACrB,MAAM,EAAE,GAAG,CAAC,GAAG;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAoB;IAC1D,IAAI,OAAO,CAAC,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAa;QACtB,sFAAsF;QACtF,kCAAkC;KACnC,CAAC;IACF,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,iCAAiC,QAAQ,MAAM,KAAK,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAMzC;IACC,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7D,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,SAAS,IAAI,CAAC,MAAM,4CAA4C,CAAC;IAC1E,CAAC;IACD,IAAI,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,SAAS,IAAI,CAAC,MAAM,uDAAuD,CAAC;IACrF,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,eAAe,IAAI,CAAC,MAAM,8BAA8B,IAAI,CAAC,KAAK,EAAE,CAAC;IAC9E,CAAC;IACD,OAAO,SAAS,IAAI,CAAC,QAAQ,IAAI,GAAG,cAAc,IAAI,CAAC,MAAM,wBAAwB,IAAI,CAAC,KAAK,EAAE,CAAC;AACpG,CAAC"}