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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. package/README.bridge.md +14 -14
  2. package/README.md +204 -34
  3. package/deploy/README.md +1 -1
  4. package/deploy/bootstrap-vps.sh +14 -9
  5. package/deploy/deploy-dashboard.sh +25 -1
  6. package/deploy/macos/README.md +153 -0
  7. package/deploy/macos/com.patchwork.bridge.plist.template +54 -0
  8. package/deploy/macos/com.patchwork.tunnel.plist.template +76 -0
  9. package/deploy/macos/install-mac-bridge.sh +244 -0
  10. package/deploy/macos/uninstall-mac-bridge.sh +22 -0
  11. package/dist/activityLog.d.ts +6 -0
  12. package/dist/activityLog.js +63 -26
  13. package/dist/activityLog.js.map +1 -1
  14. package/dist/adapters/claude.js +22 -16
  15. package/dist/adapters/claude.js.map +1 -1
  16. package/dist/adapters/gemini.js +15 -11
  17. package/dist/adapters/gemini.js.map +1 -1
  18. package/dist/adapters/openai.js +9 -9
  19. package/dist/adapters/openai.js.map +1 -1
  20. package/dist/ajv2020.d.ts +25 -0
  21. package/dist/ajv2020.js +33 -0
  22. package/dist/ajv2020.js.map +1 -0
  23. package/dist/analyticsAggregator.d.ts +5 -1
  24. package/dist/analyticsAggregator.js +16 -5
  25. package/dist/analyticsAggregator.js.map +1 -1
  26. package/dist/analyticsConfig.d.ts +29 -0
  27. package/dist/analyticsConfig.js +102 -0
  28. package/dist/analyticsConfig.js.map +1 -0
  29. package/dist/analyticsPrefs.d.ts +49 -2
  30. package/dist/analyticsPrefs.js +177 -19
  31. package/dist/analyticsPrefs.js.map +1 -1
  32. package/dist/analyticsSend.d.ts +17 -1
  33. package/dist/analyticsSend.js +67 -5
  34. package/dist/analyticsSend.js.map +1 -1
  35. package/dist/approvalHttp.d.ts +14 -0
  36. package/dist/approvalHttp.js +212 -9
  37. package/dist/approvalHttp.js.map +1 -1
  38. package/dist/approvalInsights.js +13 -5
  39. package/dist/approvalInsights.js.map +1 -1
  40. package/dist/approvalQueue.d.ts +97 -3
  41. package/dist/approvalQueue.js +193 -19
  42. package/dist/approvalQueue.js.map +1 -1
  43. package/dist/approvalSignals.js +19 -11
  44. package/dist/approvalSignals.js.map +1 -1
  45. package/dist/automation.d.ts +35 -10
  46. package/dist/automation.js +133 -37
  47. package/dist/automation.js.map +1 -1
  48. package/dist/automationSuggestions.js +10 -8
  49. package/dist/automationSuggestions.js.map +1 -1
  50. package/dist/bridge.d.ts +2 -0
  51. package/dist/bridge.js +238 -51
  52. package/dist/bridge.js.map +1 -1
  53. package/dist/bridgeLockDiscovery.d.ts +27 -1
  54. package/dist/bridgeLockDiscovery.js +38 -11
  55. package/dist/bridgeLockDiscovery.js.map +1 -1
  56. package/dist/bridgeToken.js +3 -2
  57. package/dist/bridgeToken.js.map +1 -1
  58. package/dist/claudeDriver.d.ts +0 -16
  59. package/dist/claudeDriver.js +42 -28
  60. package/dist/claudeDriver.js.map +1 -1
  61. package/dist/claudeMdPatch.d.ts +9 -3
  62. package/dist/claudeMdPatch.js +79 -13
  63. package/dist/claudeMdPatch.js.map +1 -1
  64. package/dist/claudeOrchestrator.d.ts +13 -1
  65. package/dist/claudeOrchestrator.js +89 -44
  66. package/dist/claudeOrchestrator.js.map +1 -1
  67. package/dist/commands/analytics.d.ts +8 -0
  68. package/dist/commands/analytics.js +134 -0
  69. package/dist/commands/analytics.js.map +1 -0
  70. package/dist/commands/auditEnv.d.ts +36 -0
  71. package/dist/commands/auditEnv.js +202 -0
  72. package/dist/commands/auditEnv.js.map +1 -0
  73. package/dist/commands/dashboard.js +8 -1
  74. package/dist/commands/dashboard.js.map +1 -1
  75. package/dist/commands/doctor.d.ts +35 -0
  76. package/dist/commands/doctor.js +51 -0
  77. package/dist/commands/doctor.js.map +1 -0
  78. package/dist/commands/install.js +3 -0
  79. package/dist/commands/install.js.map +1 -1
  80. package/dist/commands/launchd.js +15 -16
  81. package/dist/commands/launchd.js.map +1 -1
  82. package/dist/commands/patchworkInit.d.ts +5 -0
  83. package/dist/commands/patchworkInit.js +89 -7
  84. package/dist/commands/patchworkInit.js.map +1 -1
  85. package/dist/commands/recipe.d.ts +110 -0
  86. package/dist/commands/recipe.js +512 -9
  87. package/dist/commands/recipe.js.map +1 -1
  88. package/dist/commands/recipeInstall.js +11 -4
  89. package/dist/commands/recipeInstall.js.map +1 -1
  90. package/dist/commands/shadowScan.d.ts +34 -0
  91. package/dist/commands/shadowScan.js +142 -0
  92. package/dist/commands/shadowScan.js.map +1 -0
  93. package/dist/commands/task.js +2 -2
  94. package/dist/commands/task.js.map +1 -1
  95. package/dist/commands/tools.d.ts +20 -1
  96. package/dist/commands/tools.js +112 -3
  97. package/dist/commands/tools.js.map +1 -1
  98. package/dist/commands/tracesImport.js +21 -4
  99. package/dist/commands/tracesImport.js.map +1 -1
  100. package/dist/commitIssueLinkLog.d.ts +24 -0
  101. package/dist/commitIssueLinkLog.js +160 -22
  102. package/dist/commitIssueLinkLog.js.map +1 -1
  103. package/dist/companions/registry.js +15 -7
  104. package/dist/companions/registry.js.map +1 -1
  105. package/dist/config.d.ts +49 -5
  106. package/dist/config.js +123 -22
  107. package/dist/config.js.map +1 -1
  108. package/dist/connectorRoutes.js +913 -413
  109. package/dist/connectorRoutes.js.map +1 -1
  110. package/dist/connectors/airtable.d.ts +230 -0
  111. package/dist/connectors/airtable.js +700 -0
  112. package/dist/connectors/airtable.js.map +1 -0
  113. package/dist/connectors/asana.js +13 -9
  114. package/dist/connectors/asana.js.map +1 -1
  115. package/dist/connectors/baseConnector.js +25 -3
  116. package/dist/connectors/baseConnector.js.map +1 -1
  117. package/dist/connectors/caldiy.d.ts +137 -0
  118. package/dist/connectors/caldiy.js +424 -0
  119. package/dist/connectors/caldiy.js.map +1 -0
  120. package/dist/connectors/circleci.d.ts +162 -0
  121. package/dist/connectors/circleci.js +576 -0
  122. package/dist/connectors/circleci.js.map +1 -0
  123. package/dist/connectors/cloudflare.d.ts +132 -0
  124. package/dist/connectors/cloudflare.js +622 -0
  125. package/dist/connectors/cloudflare.js.map +1 -0
  126. package/dist/connectors/confluence.js +35 -0
  127. package/dist/connectors/confluence.js.map +1 -1
  128. package/dist/connectors/connectorRedirectUri.d.ts +30 -0
  129. package/dist/connectors/connectorRedirectUri.js +38 -0
  130. package/dist/connectors/connectorRedirectUri.js.map +1 -0
  131. package/dist/connectors/connectorRegistry.d.ts +63 -0
  132. package/dist/connectors/connectorRegistry.js +354 -0
  133. package/dist/connectors/connectorRegistry.js.map +1 -0
  134. package/dist/connectors/datadog.js +33 -4
  135. package/dist/connectors/datadog.js.map +1 -1
  136. package/dist/connectors/discord.js +14 -10
  137. package/dist/connectors/discord.js.map +1 -1
  138. package/dist/connectors/elasticsearch.d.ts +141 -0
  139. package/dist/connectors/elasticsearch.js +601 -0
  140. package/dist/connectors/elasticsearch.js.map +1 -0
  141. package/dist/connectors/figma.d.ts +130 -0
  142. package/dist/connectors/figma.js +387 -0
  143. package/dist/connectors/figma.js.map +1 -0
  144. package/dist/connectors/github.d.ts +17 -0
  145. package/dist/connectors/github.js +53 -2
  146. package/dist/connectors/github.js.map +1 -1
  147. package/dist/connectors/gitlab.js +12 -6
  148. package/dist/connectors/gitlab.js.map +1 -1
  149. package/dist/connectors/gmail.js +72 -21
  150. package/dist/connectors/gmail.js.map +1 -1
  151. package/dist/connectors/googleCalendar.js +8 -8
  152. package/dist/connectors/googleCalendar.js.map +1 -1
  153. package/dist/connectors/googleDocs.d.ts +103 -0
  154. package/dist/connectors/googleDocs.js +409 -0
  155. package/dist/connectors/googleDocs.js.map +1 -0
  156. package/dist/connectors/googleDrive.d.ts +12 -0
  157. package/dist/connectors/googleDrive.js +35 -8
  158. package/dist/connectors/googleDrive.js.map +1 -1
  159. package/dist/connectors/grafana.d.ts +133 -0
  160. package/dist/connectors/grafana.js +478 -0
  161. package/dist/connectors/grafana.js.map +1 -0
  162. package/dist/connectors/jira.d.ts +25 -0
  163. package/dist/connectors/jira.js +245 -2
  164. package/dist/connectors/jira.js.map +1 -1
  165. package/dist/connectors/linear.js +1 -1
  166. package/dist/connectors/linear.js.map +1 -1
  167. package/dist/connectors/mcpOAuth.js +78 -16
  168. package/dist/connectors/mcpOAuth.js.map +1 -1
  169. package/dist/connectors/monday.d.ts +217 -0
  170. package/dist/connectors/monday.js +655 -0
  171. package/dist/connectors/monday.js.map +1 -0
  172. package/dist/connectors/mongodb.d.ts +139 -0
  173. package/dist/connectors/mongodb.js +455 -0
  174. package/dist/connectors/mongodb.js.map +1 -0
  175. package/dist/connectors/oauthStateStore.d.ts +20 -0
  176. package/dist/connectors/oauthStateStore.js +94 -4
  177. package/dist/connectors/oauthStateStore.js.map +1 -1
  178. package/dist/connectors/obsidian.d.ts +83 -0
  179. package/dist/connectors/obsidian.js +441 -0
  180. package/dist/connectors/obsidian.js.map +1 -0
  181. package/dist/connectors/paystack.d.ts +159 -0
  182. package/dist/connectors/paystack.js +607 -0
  183. package/dist/connectors/paystack.js.map +1 -0
  184. package/dist/connectors/pipedrive.d.ts +189 -0
  185. package/dist/connectors/pipedrive.js +559 -0
  186. package/dist/connectors/pipedrive.js.map +1 -0
  187. package/dist/connectors/postgres.d.ts +127 -0
  188. package/dist/connectors/postgres.js +512 -0
  189. package/dist/connectors/postgres.js.map +1 -0
  190. package/dist/connectors/posthog.d.ts +119 -0
  191. package/dist/connectors/posthog.js +479 -0
  192. package/dist/connectors/posthog.js.map +1 -0
  193. package/dist/connectors/redis.d.ts +140 -0
  194. package/dist/connectors/redis.js +571 -0
  195. package/dist/connectors/redis.js.map +1 -0
  196. package/dist/connectors/resend.d.ts +131 -0
  197. package/dist/connectors/resend.js +529 -0
  198. package/dist/connectors/resend.js.map +1 -0
  199. package/dist/connectors/salesforce.d.ts +136 -0
  200. package/dist/connectors/salesforce.js +603 -0
  201. package/dist/connectors/salesforce.js.map +1 -0
  202. package/dist/connectors/secrets.d.ts +51 -0
  203. package/dist/connectors/secrets.js +102 -0
  204. package/dist/connectors/secrets.js.map +1 -0
  205. package/dist/connectors/sendgrid.d.ts +102 -0
  206. package/dist/connectors/sendgrid.js +423 -0
  207. package/dist/connectors/sendgrid.js.map +1 -0
  208. package/dist/connectors/shopify.d.ts +145 -0
  209. package/dist/connectors/shopify.js +502 -0
  210. package/dist/connectors/shopify.js.map +1 -0
  211. package/dist/connectors/slack.d.ts +1 -1
  212. package/dist/connectors/slack.js +61 -9
  213. package/dist/connectors/slack.js.map +1 -1
  214. package/dist/connectors/snowflake.d.ts +119 -0
  215. package/dist/connectors/snowflake.js +615 -0
  216. package/dist/connectors/snowflake.js.map +1 -0
  217. package/dist/connectors/supabase.d.ts +92 -0
  218. package/dist/connectors/supabase.js +630 -0
  219. package/dist/connectors/supabase.js.map +1 -0
  220. package/dist/connectors/todoist.d.ts +117 -0
  221. package/dist/connectors/todoist.js +485 -0
  222. package/dist/connectors/todoist.js.map +1 -0
  223. package/dist/connectors/tokenStorage.js +56 -14
  224. package/dist/connectors/tokenStorage.js.map +1 -1
  225. package/dist/connectors/twilio.d.ts +118 -0
  226. package/dist/connectors/twilio.js +475 -0
  227. package/dist/connectors/twilio.js.map +1 -0
  228. package/dist/connectors/vercel.d.ts +110 -0
  229. package/dist/connectors/vercel.js +479 -0
  230. package/dist/connectors/vercel.js.map +1 -0
  231. package/dist/connectors/webflow.d.ts +118 -0
  232. package/dist/connectors/webflow.js +393 -0
  233. package/dist/connectors/webflow.js.map +1 -0
  234. package/dist/connectors/woocommerce.d.ts +220 -0
  235. package/dist/connectors/woocommerce.js +464 -0
  236. package/dist/connectors/woocommerce.js.map +1 -0
  237. package/dist/crypto.js +7 -2
  238. package/dist/crypto.js.map +1 -1
  239. package/dist/decisionReplay.js +15 -6
  240. package/dist/decisionReplay.js.map +1 -1
  241. package/dist/decisionTraceLog.d.ts +28 -0
  242. package/dist/decisionTraceLog.js +156 -29
  243. package/dist/decisionTraceLog.js.map +1 -1
  244. package/dist/drivers/claude/api.js +5 -4
  245. package/dist/drivers/claude/api.js.map +1 -1
  246. package/dist/drivers/claude/envSanitizer.d.ts +0 -6
  247. package/dist/drivers/claude/envSanitizer.js +17 -2
  248. package/dist/drivers/claude/envSanitizer.js.map +1 -1
  249. package/dist/drivers/claude/streamParser.js +5 -4
  250. package/dist/drivers/claude/streamParser.js.map +1 -1
  251. package/dist/drivers/claude/subprocess.d.ts +12 -2
  252. package/dist/drivers/claude/subprocess.js +100 -8
  253. package/dist/drivers/claude/subprocess.js.map +1 -1
  254. package/dist/drivers/gemini/api.d.ts +18 -0
  255. package/dist/drivers/gemini/api.js +29 -0
  256. package/dist/drivers/gemini/api.js.map +1 -0
  257. package/dist/drivers/gemini/index.d.ts +22 -0
  258. package/dist/drivers/gemini/index.js +256 -129
  259. package/dist/drivers/gemini/index.js.map +1 -1
  260. package/dist/drivers/index.d.ts +3 -1
  261. package/dist/drivers/index.js +9 -1
  262. package/dist/drivers/index.js.map +1 -1
  263. package/dist/drivers/local/index.d.ts +43 -0
  264. package/dist/drivers/local/index.js +140 -0
  265. package/dist/drivers/local/index.js.map +1 -0
  266. package/dist/drivers/openai/index.js +30 -2
  267. package/dist/drivers/openai/index.js.map +1 -1
  268. package/dist/extensionClient.d.ts +37 -4
  269. package/dist/extensionClient.js +58 -16
  270. package/dist/extensionClient.js.map +1 -1
  271. package/dist/featureFlags.d.ts +91 -0
  272. package/dist/featureFlags.js +174 -3
  273. package/dist/featureFlags.js.map +1 -1
  274. package/dist/fileLock.js +21 -12
  275. package/dist/fileLock.js.map +1 -1
  276. package/dist/fileLockSync.d.ts +67 -0
  277. package/dist/fileLockSync.js +126 -0
  278. package/dist/fileLockSync.js.map +1 -0
  279. package/dist/fp/activityAnalytics.js +26 -12
  280. package/dist/fp/activityAnalytics.js.map +1 -1
  281. package/dist/fp/automationInterpreter.d.ts +15 -1
  282. package/dist/fp/automationInterpreter.js +217 -82
  283. package/dist/fp/automationInterpreter.js.map +1 -1
  284. package/dist/fp/automationProgram.d.ts +30 -0
  285. package/dist/fp/automationProgram.js.map +1 -1
  286. package/dist/fp/automationState.d.ts +24 -5
  287. package/dist/fp/automationState.js +56 -9
  288. package/dist/fp/automationState.js.map +1 -1
  289. package/dist/fp/automationUtils.js +1 -1
  290. package/dist/fp/automationUtils.js.map +1 -1
  291. package/dist/fp/commandDescription.js +7 -1
  292. package/dist/fp/commandDescription.js.map +1 -1
  293. package/dist/fp/extensionSnapshot.js +8 -2
  294. package/dist/fp/extensionSnapshot.js.map +1 -1
  295. package/dist/fp/interpreterContext.d.ts +66 -1
  296. package/dist/fp/interpreterContext.js +91 -1
  297. package/dist/fp/interpreterContext.js.map +1 -1
  298. package/dist/fp/policyParser.js +29 -1
  299. package/dist/fp/policyParser.js.map +1 -1
  300. package/dist/fsWatchWithFallback.d.ts +36 -0
  301. package/dist/fsWatchWithFallback.js +128 -0
  302. package/dist/fsWatchWithFallback.js.map +1 -0
  303. package/dist/haltPushDispatch.d.ts +33 -0
  304. package/dist/haltPushDispatch.js +103 -0
  305. package/dist/haltPushDispatch.js.map +1 -0
  306. package/dist/httpBodyValidation.d.ts +41 -0
  307. package/dist/httpBodyValidation.js +45 -0
  308. package/dist/httpBodyValidation.js.map +1 -0
  309. package/dist/httpErrorResponse.d.ts +36 -0
  310. package/dist/httpErrorResponse.js +46 -0
  311. package/dist/httpErrorResponse.js.map +1 -0
  312. package/dist/inboxRoutes.d.ts +22 -0
  313. package/dist/inboxRoutes.js +151 -12
  314. package/dist/inboxRoutes.js.map +1 -1
  315. package/dist/index.d.ts +1 -1
  316. package/dist/index.js +1054 -76
  317. package/dist/index.js.map +1 -1
  318. package/dist/installGuard.js +6 -2
  319. package/dist/installGuard.js.map +1 -1
  320. package/dist/lockfile.js +31 -4
  321. package/dist/lockfile.js.map +1 -1
  322. package/dist/oauth.d.ts +22 -0
  323. package/dist/oauth.js +46 -0
  324. package/dist/oauth.js.map +1 -1
  325. package/dist/oauthRoutes.d.ts +1 -1
  326. package/dist/oauthRoutes.js +8 -11
  327. package/dist/oauthRoutes.js.map +1 -1
  328. package/dist/orchestrator/childBridgeRegistry.js +29 -11
  329. package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
  330. package/dist/patchworkConfig.d.ts +57 -1
  331. package/dist/patchworkConfig.js +125 -5
  332. package/dist/patchworkConfig.js.map +1 -1
  333. package/dist/pluginLoader.js +10 -1
  334. package/dist/pluginLoader.js.map +1 -1
  335. package/dist/pluginWatcher.js +12 -14
  336. package/dist/pluginWatcher.js.map +1 -1
  337. package/dist/preToolUseHook.js +10 -3
  338. package/dist/preToolUseHook.js.map +1 -1
  339. package/dist/processTree.d.ts +34 -0
  340. package/dist/processTree.js +105 -0
  341. package/dist/processTree.js.map +1 -0
  342. package/dist/prompts.js +7 -3
  343. package/dist/prompts.js.map +1 -1
  344. package/dist/recipeOrchestration.d.ts +9 -0
  345. package/dist/recipeOrchestration.js +354 -27
  346. package/dist/recipeOrchestration.js.map +1 -1
  347. package/dist/recipeRoutes.d.ts +63 -2
  348. package/dist/recipeRoutes.js +790 -137
  349. package/dist/recipeRoutes.js.map +1 -1
  350. package/dist/recipes/RecipeOrchestrator.d.ts +2 -0
  351. package/dist/recipes/RecipeOrchestrator.js +6 -1
  352. package/dist/recipes/RecipeOrchestrator.js.map +1 -1
  353. package/dist/recipes/agentExecutor.d.ts +34 -5
  354. package/dist/recipes/agentExecutor.js +5 -4
  355. package/dist/recipes/agentExecutor.js.map +1 -1
  356. package/dist/recipes/chainedRunner.d.ts +2 -0
  357. package/dist/recipes/chainedRunner.js +142 -5
  358. package/dist/recipes/chainedRunner.js.map +1 -1
  359. package/dist/recipes/connectorPreflight.d.ts +66 -0
  360. package/dist/recipes/connectorPreflight.js +169 -0
  361. package/dist/recipes/connectorPreflight.js.map +1 -0
  362. package/dist/recipes/dependencyGraph.js +13 -5
  363. package/dist/recipes/dependencyGraph.js.map +1 -1
  364. package/dist/recipes/githubInstallSource.d.ts +128 -0
  365. package/dist/recipes/githubInstallSource.js +206 -0
  366. package/dist/recipes/githubInstallSource.js.map +1 -0
  367. package/dist/recipes/haltCategory.d.ts +119 -0
  368. package/dist/recipes/haltCategory.js +188 -0
  369. package/dist/recipes/haltCategory.js.map +1 -0
  370. package/dist/recipes/idempotencyKey.d.ts +134 -0
  371. package/dist/recipes/idempotencyKey.js +322 -0
  372. package/dist/recipes/idempotencyKey.js.map +1 -0
  373. package/dist/recipes/installer.js +48 -2
  374. package/dist/recipes/installer.js.map +1 -1
  375. package/dist/recipes/judgeSummary.d.ts +50 -0
  376. package/dist/recipes/judgeSummary.js +47 -0
  377. package/dist/recipes/judgeSummary.js.map +1 -0
  378. package/dist/recipes/judgeVerdict.d.ts +48 -0
  379. package/dist/recipes/judgeVerdict.js +174 -0
  380. package/dist/recipes/judgeVerdict.js.map +1 -0
  381. package/dist/recipes/migrations/index.d.ts +9 -0
  382. package/dist/recipes/migrations/index.js +133 -0
  383. package/dist/recipes/migrations/index.js.map +1 -1
  384. package/dist/recipes/names.d.ts +20 -0
  385. package/dist/recipes/names.js +25 -0
  386. package/dist/recipes/names.js.map +1 -1
  387. package/dist/recipes/parser.js +88 -5
  388. package/dist/recipes/parser.js.map +1 -1
  389. package/dist/recipes/replayRun.js +1 -1
  390. package/dist/recipes/replayRun.js.map +1 -1
  391. package/dist/recipes/runBudget.d.ts +70 -0
  392. package/dist/recipes/runBudget.js +109 -0
  393. package/dist/recipes/runBudget.js.map +1 -0
  394. package/dist/recipes/scheduler.d.ts +30 -0
  395. package/dist/recipes/scheduler.js +69 -19
  396. package/dist/recipes/scheduler.js.map +1 -1
  397. package/dist/recipes/schema.d.ts +36 -0
  398. package/dist/recipes/schemaGenerator.js +103 -5
  399. package/dist/recipes/schemaGenerator.js.map +1 -1
  400. package/dist/recipes/stepObservation.js +9 -0
  401. package/dist/recipes/stepObservation.js.map +1 -1
  402. package/dist/recipes/toolRegistry.js +20 -3
  403. package/dist/recipes/toolRegistry.js.map +1 -1
  404. package/dist/recipes/tools/fanOut.d.ts +20 -0
  405. package/dist/recipes/tools/fanOut.js +199 -0
  406. package/dist/recipes/tools/fanOut.js.map +1 -0
  407. package/dist/recipes/tools/file.js +5 -2
  408. package/dist/recipes/tools/file.js.map +1 -1
  409. package/dist/recipes/tools/github.d.ts +1 -1
  410. package/dist/recipes/tools/github.js +75 -1
  411. package/dist/recipes/tools/github.js.map +1 -1
  412. package/dist/recipes/tools/gmail.js +45 -6
  413. package/dist/recipes/tools/gmail.js.map +1 -1
  414. package/dist/recipes/tools/googleDrive.js +64 -0
  415. package/dist/recipes/tools/googleDrive.js.map +1 -1
  416. package/dist/recipes/tools/http.d.ts +10 -0
  417. package/dist/recipes/tools/http.js +176 -0
  418. package/dist/recipes/tools/http.js.map +1 -0
  419. package/dist/recipes/tools/index.d.ts +2 -0
  420. package/dist/recipes/tools/index.js +2 -0
  421. package/dist/recipes/tools/index.js.map +1 -1
  422. package/dist/recipes/tools/slack.js +1 -1
  423. package/dist/recipes/validation.d.ts +17 -0
  424. package/dist/recipes/validation.js +29 -11
  425. package/dist/recipes/validation.js.map +1 -1
  426. package/dist/recipes/workspaceRoot.d.ts +37 -0
  427. package/dist/recipes/workspaceRoot.js +73 -0
  428. package/dist/recipes/workspaceRoot.js.map +1 -0
  429. package/dist/recipes/yamlPositions.d.ts +56 -0
  430. package/dist/recipes/yamlPositions.js +183 -0
  431. package/dist/recipes/yamlPositions.js.map +1 -0
  432. package/dist/recipes/yamlRunner.d.ts +195 -8
  433. package/dist/recipes/yamlRunner.js +877 -209
  434. package/dist/recipes/yamlRunner.js.map +1 -1
  435. package/dist/recipesHttp.d.ts +33 -3
  436. package/dist/recipesHttp.js +126 -12
  437. package/dist/recipesHttp.js.map +1 -1
  438. package/dist/resources.js +21 -13
  439. package/dist/resources.js.map +1 -1
  440. package/dist/runLog.d.ts +58 -5
  441. package/dist/runLog.js +98 -21
  442. package/dist/runLog.js.map +1 -1
  443. package/dist/sanitizeParsedJson.d.ts +39 -0
  444. package/dist/sanitizeParsedJson.js +55 -0
  445. package/dist/sanitizeParsedJson.js.map +1 -0
  446. package/dist/schemas/recipe.v1.json +885 -196
  447. package/dist/server.d.ts +166 -3
  448. package/dist/server.js +1313 -332
  449. package/dist/server.js.map +1 -1
  450. package/dist/sessionCheckpoint.d.ts +8 -0
  451. package/dist/sessionCheckpoint.js +33 -3
  452. package/dist/sessionCheckpoint.js.map +1 -1
  453. package/dist/ssrfGuard.d.ts +16 -0
  454. package/dist/ssrfGuard.js +87 -4
  455. package/dist/ssrfGuard.js.map +1 -1
  456. package/dist/streamableHttp.d.ts +9 -4
  457. package/dist/streamableHttp.js +76 -20
  458. package/dist/streamableHttp.js.map +1 -1
  459. package/dist/telemetry.js +19 -12
  460. package/dist/telemetry.js.map +1 -1
  461. package/dist/testing/shadowRun.d.ts +52 -0
  462. package/dist/testing/shadowRun.js +71 -0
  463. package/dist/testing/shadowRun.js.map +1 -0
  464. package/dist/tools/batchLsp.d.ts +3 -0
  465. package/dist/tools/bridgeDoctor.d.ts +11 -0
  466. package/dist/tools/bridgeDoctor.js +48 -2
  467. package/dist/tools/bridgeDoctor.js.map +1 -1
  468. package/dist/tools/bridgeStatus.d.ts +0 -12
  469. package/dist/tools/bridgeStatus.js +2 -28
  470. package/dist/tools/bridgeStatus.js.map +1 -1
  471. package/dist/tools/cancelClaudeTask.d.ts +1 -0
  472. package/dist/tools/clipboard.d.ts +2 -0
  473. package/dist/tools/closeTabs.d.ts +1 -0
  474. package/dist/tools/codeLens.d.ts +1 -0
  475. package/dist/tools/createIssueFromAIComment.d.ts +1 -0
  476. package/dist/tools/ctxGetTaskContext.d.ts +9 -0
  477. package/dist/tools/ctxGetTaskContext.js +50 -2
  478. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  479. package/dist/tools/ctxQueryTraces.js +32 -24
  480. package/dist/tools/ctxQueryTraces.js.map +1 -1
  481. package/dist/tools/ctxSaveTrace.d.ts +1 -0
  482. package/dist/tools/debug.d.ts +4 -0
  483. package/dist/tools/decorations.d.ts +2 -0
  484. package/dist/tools/detectUnusedCode.js +9 -7
  485. package/dist/tools/detectUnusedCode.js.map +1 -1
  486. package/dist/tools/documentLinks.d.ts +1 -0
  487. package/dist/tools/editText.d.ts +1 -0
  488. package/dist/tools/editText.js +2 -1
  489. package/dist/tools/editText.js.map +1 -1
  490. package/dist/tools/enrichCommit.d.ts +1 -0
  491. package/dist/tools/enrichStackTrace.js +11 -5
  492. package/dist/tools/enrichStackTrace.js.map +1 -1
  493. package/dist/tools/explainDiagnostic.d.ts +1 -0
  494. package/dist/tools/explainSymbol.d.ts +1 -0
  495. package/dist/tools/fileOperations.d.ts +3 -0
  496. package/dist/tools/fileOperations.js +2 -1
  497. package/dist/tools/fileOperations.js.map +1 -1
  498. package/dist/tools/fileWatcher.d.ts +2 -0
  499. package/dist/tools/fileWatcher.js +8 -2
  500. package/dist/tools/fileWatcher.js.map +1 -1
  501. package/dist/tools/findFiles.d.ts +1 -0
  502. package/dist/tools/fixAllLintErrors.d.ts +1 -0
  503. package/dist/tools/fixAllLintErrors.js +10 -5
  504. package/dist/tools/fixAllLintErrors.js.map +1 -1
  505. package/dist/tools/foldingRanges.d.ts +1 -0
  506. package/dist/tools/formatDocument.d.ts +1 -0
  507. package/dist/tools/formatDocument.js +10 -5
  508. package/dist/tools/formatDocument.js.map +1 -1
  509. package/dist/tools/generateTests.d.ts +1 -0
  510. package/dist/tools/getAIComments.d.ts +1 -0
  511. package/dist/tools/getAnalyticsReport.js +5 -1
  512. package/dist/tools/getAnalyticsReport.js.map +1 -1
  513. package/dist/tools/getBufferContent.d.ts +1 -0
  514. package/dist/tools/getChangeImpact.d.ts +1 -0
  515. package/dist/tools/getChangeImpact.js +23 -14
  516. package/dist/tools/getChangeImpact.js.map +1 -1
  517. package/dist/tools/getClaudeTaskStatus.d.ts +1 -0
  518. package/dist/tools/getCodeCoverage.d.ts +1 -0
  519. package/dist/tools/getCodeCoverage.js +32 -14
  520. package/dist/tools/getCodeCoverage.js.map +1 -1
  521. package/dist/tools/getCommitsForIssue.d.ts +1 -0
  522. package/dist/tools/getDebugState.d.ts +1 -0
  523. package/dist/tools/getDiagnostics.js +32 -29
  524. package/dist/tools/getDiagnostics.js.map +1 -1
  525. package/dist/tools/getDiffFromHandoff.js +8 -2
  526. package/dist/tools/getDiffFromHandoff.js.map +1 -1
  527. package/dist/tools/getDocumentSymbols.d.ts +1 -0
  528. package/dist/tools/getGitHotspots.d.ts +1 -0
  529. package/dist/tools/getImportedSignatures.d.ts +1 -0
  530. package/dist/tools/getImportedSignatures.js +18 -14
  531. package/dist/tools/getImportedSignatures.js.map +1 -1
  532. package/dist/tools/getPRTemplate.d.ts +1 -0
  533. package/dist/tools/getProjectContext.js +23 -10
  534. package/dist/tools/getProjectContext.js.map +1 -1
  535. package/dist/tools/getSymbolHistory.d.ts +1 -0
  536. package/dist/tools/getToolCapabilities.d.ts +10 -5
  537. package/dist/tools/getToolCapabilities.js +79 -202
  538. package/dist/tools/getToolCapabilities.js.map +1 -1
  539. package/dist/tools/getTypeSignature.d.ts +1 -0
  540. package/dist/tools/getWorkspaceSettings.d.ts +1 -0
  541. package/dist/tools/gitWrite.d.ts +11 -0
  542. package/dist/tools/github/actions.d.ts +2 -0
  543. package/dist/tools/github/composite.d.ts +3 -0
  544. package/dist/tools/github/issues.d.ts +4 -0
  545. package/dist/tools/github/pr.d.ts +7 -0
  546. package/dist/tools/handoffNote.d.ts +1 -0
  547. package/dist/tools/handoffNote.js +2 -1
  548. package/dist/tools/handoffNote.js.map +1 -1
  549. package/dist/tools/headless/lspClient.js +3 -0
  550. package/dist/tools/headless/lspClient.js.map +1 -1
  551. package/dist/tools/hoverAtCursor.d.ts +1 -0
  552. package/dist/tools/httpClient.d.ts +2 -0
  553. package/dist/tools/httpClient.js +38 -71
  554. package/dist/tools/httpClient.js.map +1 -1
  555. package/dist/tools/inlayHints.d.ts +1 -0
  556. package/dist/tools/launchQuickTask.d.ts +1 -0
  557. package/dist/tools/listClaudeTasks.d.ts +1 -0
  558. package/dist/tools/listClaudeTasks.js +10 -8
  559. package/dist/tools/listClaudeTasks.js.map +1 -1
  560. package/dist/tools/listTerminals.d.ts +1 -0
  561. package/dist/tools/lsp.d.ts +15 -0
  562. package/dist/tools/lsp.js +17 -0
  563. package/dist/tools/lsp.js.map +1 -1
  564. package/dist/tools/navigateToSymbolByName.d.ts +1 -0
  565. package/dist/tools/openDiff.d.ts +1 -0
  566. package/dist/tools/openDiff.js +4 -1
  567. package/dist/tools/openDiff.js.map +1 -1
  568. package/dist/tools/openFile.d.ts +1 -0
  569. package/dist/tools/openFile.js +4 -1
  570. package/dist/tools/openFile.js.map +1 -1
  571. package/dist/tools/openInBrowser.js +6 -1
  572. package/dist/tools/openInBrowser.js.map +1 -1
  573. package/dist/tools/organizeImports.d.ts +1 -0
  574. package/dist/tools/organizeImports.js +5 -3
  575. package/dist/tools/organizeImports.js.map +1 -1
  576. package/dist/tools/performanceReport.js +5 -3
  577. package/dist/tools/performanceReport.js.map +1 -1
  578. package/dist/tools/planPersistence.d.ts +3 -0
  579. package/dist/tools/planPersistence.js +4 -1
  580. package/dist/tools/planPersistence.js.map +1 -1
  581. package/dist/tools/previewEdit.d.ts +1 -0
  582. package/dist/tools/previewEdit.js +15 -4
  583. package/dist/tools/previewEdit.js.map +1 -1
  584. package/dist/tools/recentTracesDigest.js +54 -11
  585. package/dist/tools/recentTracesDigest.js.map +1 -1
  586. package/dist/tools/refactorAnalyze.d.ts +1 -0
  587. package/dist/tools/refactorExtractFunction.js +4 -1
  588. package/dist/tools/refactorExtractFunction.js.map +1 -1
  589. package/dist/tools/refactorPreview.d.ts +1 -0
  590. package/dist/tools/refactorPreview.js +10 -2
  591. package/dist/tools/refactorPreview.js.map +1 -1
  592. package/dist/tools/replaceBlock.d.ts +1 -0
  593. package/dist/tools/replaceBlock.js +2 -1
  594. package/dist/tools/replaceBlock.js.map +1 -1
  595. package/dist/tools/resumeClaudeTask.d.ts +1 -0
  596. package/dist/tools/runClaudeTask.d.ts +1 -0
  597. package/dist/tools/runCommand.js +5 -0
  598. package/dist/tools/runCommand.js.map +1 -1
  599. package/dist/tools/runTests.js +15 -4
  600. package/dist/tools/runTests.js.map +1 -1
  601. package/dist/tools/screenshot.d.ts +1 -0
  602. package/dist/tools/screenshotAndAnnotate.js +6 -2
  603. package/dist/tools/screenshotAndAnnotate.js.map +1 -1
  604. package/dist/tools/searchAndReplace.d.ts +1 -0
  605. package/dist/tools/searchAndReplace.js +17 -7
  606. package/dist/tools/searchAndReplace.js.map +1 -1
  607. package/dist/tools/searchTools.js +20 -19
  608. package/dist/tools/searchTools.js.map +1 -1
  609. package/dist/tools/searchWorkspace.d.ts +1 -0
  610. package/dist/tools/selectionRanges.d.ts +1 -0
  611. package/dist/tools/semanticTokens.d.ts +1 -0
  612. package/dist/tools/signatureHelp.d.ts +1 -0
  613. package/dist/tools/spawnWorkspace.js +15 -7
  614. package/dist/tools/spawnWorkspace.js.map +1 -1
  615. package/dist/tools/terminal.d.ts +6 -0
  616. package/dist/tools/terminal.js +4 -0
  617. package/dist/tools/terminal.js.map +1 -1
  618. package/dist/tools/testRunners/pytest.js +6 -2
  619. package/dist/tools/testRunners/pytest.js.map +1 -1
  620. package/dist/tools/testRunners/vitestJest.js +3 -1
  621. package/dist/tools/testRunners/vitestJest.js.map +1 -1
  622. package/dist/tools/testTraceToSource.d.ts +1 -0
  623. package/dist/tools/transaction.d.ts +4 -0
  624. package/dist/tools/transaction.js +4 -1
  625. package/dist/tools/transaction.js.map +1 -1
  626. package/dist/tools/typeHierarchy.d.ts +1 -0
  627. package/dist/tools/utils.d.ts +22 -0
  628. package/dist/tools/utils.js +158 -14
  629. package/dist/tools/utils.js.map +1 -1
  630. package/dist/tools/vscodeCommands.d.ts +2 -0
  631. package/dist/tools/vscodeTasks.d.ts +2 -0
  632. package/dist/tools/workspaceSettings.d.ts +1 -0
  633. package/dist/transport.d.ts +3 -1
  634. package/dist/transport.js +103 -52
  635. package/dist/transport.js.map +1 -1
  636. package/dist/winShim.d.ts +34 -0
  637. package/dist/winShim.js +94 -0
  638. package/dist/winShim.js.map +1 -0
  639. package/dist/wireHaltPushDispatch.d.ts +38 -0
  640. package/dist/wireHaltPushDispatch.js +71 -0
  641. package/dist/wireHaltPushDispatch.js.map +1 -0
  642. package/dist/writeFileAtomic.d.ts +23 -0
  643. package/dist/writeFileAtomic.js +121 -0
  644. package/dist/writeFileAtomic.js.map +1 -0
  645. package/package.json +23 -7
  646. package/scripts/postinstall.mjs +42 -2
  647. package/scripts/smoke/run-all.mjs +213 -0
  648. package/scripts/start-all.mjs +572 -0
  649. package/scripts/start-all.ps1 +209 -0
  650. package/scripts/start-all.sh +77 -19
  651. package/scripts/start-orchestrator.ps1 +158 -0
  652. package/scripts/start-remote.mjs +122 -0
  653. package/templates/automation-policies/recipe-authoring.json +1 -1
  654. package/templates/automation-policies/security-first.json +1 -1
  655. package/templates/automation-policies/strict-lint.json +1 -1
  656. package/templates/automation-policies/test-driven.json +1 -1
  657. package/templates/automation-policy.example.json +1 -1
  658. package/templates/co.patchwork-os.bridge.plist +2 -2
  659. package/templates/recipes/approval-queue-ui-test.yaml +205 -0
  660. package/templates/recipes/ctx-loop-test.yaml +1 -1
  661. package/templates/recipes/fix-errors-on-save.yaml +71 -0
  662. package/templates/recipes/morning-brief.yaml +5 -2
  663. package/templates/recipes/project-health-check.yaml +4 -1
  664. package/templates/recipes/sentry-to-linear.yaml +72 -38
  665. package/templates/recipes/webhook/apple-watch-health-log.yaml +145 -0
  666. package/templates/recipes/webhook/customer-escalation.yaml +8 -9
  667. package/templates/recipes/webhook/meeting-prep.yaml +11 -5
  668. package/dist/commands/marketplace.d.ts +0 -11
  669. package/dist/commands/marketplace.js +0 -120
  670. package/dist/commands/marketplace.js.map +0 -1
  671. package/dist/recipes/legacyRecipeCompat.d.ts +0 -10
  672. package/dist/recipes/legacyRecipeCompat.js +0 -131
  673. package/dist/recipes/legacyRecipeCompat.js.map +0 -1
@@ -24,6 +24,7 @@
24
24
  * - Pre-extraction grep confirmed zero `this.` references in either
25
25
  * block, so no dependency injection was needed.
26
26
  */
27
+ import { respond500 } from "./httpErrorResponse.js";
27
28
  import { readBodyWithCap, respond413 } from "./recipeRoutes.js";
28
29
  /**
29
30
  * Token-paste connector body cap. The legitimate payload is a small JSON
@@ -58,12 +59,7 @@ async function dispatchConnectorConnect(req, res, loadHandler) {
58
59
  res.end(result.body);
59
60
  }
60
61
  catch (err) {
61
- if (!res.headersSent) {
62
- res.writeHead(500, { "Content-Type": "application/json" });
63
- res.end(JSON.stringify({
64
- error: err instanceof Error ? err.message : String(err),
65
- }));
66
- }
62
+ respond500(res, err);
67
63
  }
68
64
  }
69
65
  /**
@@ -87,12 +83,7 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
87
83
  res.end(result.body);
88
84
  }
89
85
  catch (err) {
90
- if (!res.headersSent) {
91
- res.writeHead(500, { "Content-Type": "application/json" });
92
- res.end(JSON.stringify({
93
- error: err instanceof Error ? err.message : String(err),
94
- }));
95
- }
86
+ respond500(res, err);
96
87
  }
97
88
  })();
98
89
  return true;
@@ -112,12 +103,7 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
112
103
  res.end(result.body);
113
104
  }
114
105
  catch (err) {
115
- if (!res.headersSent) {
116
- res.writeHead(500, { "Content-Type": "application/json" });
117
- res.end(JSON.stringify({
118
- error: err instanceof Error ? err.message : String(err),
119
- }));
120
- }
106
+ respond500(res, err);
121
107
  }
122
108
  })();
123
109
  return true;
@@ -137,12 +123,7 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
137
123
  res.end(result.body);
138
124
  }
139
125
  catch (err) {
140
- if (!res.headersSent) {
141
- res.writeHead(500, { "Content-Type": "application/json" });
142
- res.end(JSON.stringify({
143
- error: err instanceof Error ? err.message : String(err),
144
- }));
145
- }
126
+ respond500(res, err);
146
127
  }
147
128
  })();
148
129
  return true;
@@ -162,12 +143,7 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
162
143
  res.end(result.body);
163
144
  }
164
145
  catch (err) {
165
- if (!res.headersSent) {
166
- res.writeHead(500, { "Content-Type": "application/json" });
167
- res.end(JSON.stringify({
168
- error: err instanceof Error ? err.message : String(err),
169
- }));
170
- }
146
+ respond500(res, err);
171
147
  }
172
148
  })();
173
149
  return true;
@@ -187,12 +163,67 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
187
163
  res.end(result.body);
188
164
  }
189
165
  catch (err) {
190
- if (!res.headersSent) {
191
- res.writeHead(500, { "Content-Type": "application/json" });
192
- res.end(JSON.stringify({
193
- error: err instanceof Error ? err.message : String(err),
194
- }));
195
- }
166
+ respond500(res, err);
167
+ }
168
+ })();
169
+ return true;
170
+ }
171
+ if (parsedUrl.pathname === "/connections/google-docs/callback" &&
172
+ req.method === "GET") {
173
+ void (async () => {
174
+ try {
175
+ const { handleDocsCallback } = await import("./connectors/googleDocs.js");
176
+ const code = parsedUrl.searchParams.get("code");
177
+ const state = parsedUrl.searchParams.get("state");
178
+ const error = parsedUrl.searchParams.get("error");
179
+ const result = await handleDocsCallback(code, state, error);
180
+ res.writeHead(result.status, {
181
+ "Content-Type": result.contentType ?? "application/json",
182
+ });
183
+ res.end(result.body);
184
+ }
185
+ catch (err) {
186
+ respond500(res, err);
187
+ }
188
+ })();
189
+ return true;
190
+ }
191
+ if (parsedUrl.pathname === "/connections/monday/callback" &&
192
+ req.method === "GET") {
193
+ void (async () => {
194
+ try {
195
+ const { handleMondayCallback } = await import("./connectors/monday.js");
196
+ const code = parsedUrl.searchParams.get("code");
197
+ const state = parsedUrl.searchParams.get("state");
198
+ const error = parsedUrl.searchParams.get("error");
199
+ const result = await handleMondayCallback(code, state, error);
200
+ res.writeHead(result.status, {
201
+ "Content-Type": result.contentType ?? "application/json",
202
+ });
203
+ res.end(result.body);
204
+ }
205
+ catch (err) {
206
+ respond500(res, err);
207
+ }
208
+ })();
209
+ return true;
210
+ }
211
+ if (parsedUrl.pathname === "/connections/salesforce/callback" &&
212
+ req.method === "GET") {
213
+ void (async () => {
214
+ try {
215
+ const { handleSalesforceCallback } = await import("./connectors/salesforce.js");
216
+ const code = parsedUrl.searchParams.get("code");
217
+ const state = parsedUrl.searchParams.get("state");
218
+ const error = parsedUrl.searchParams.get("error");
219
+ const result = await handleSalesforceCallback(code, state, error);
220
+ res.writeHead(result.status, {
221
+ "Content-Type": result.contentType ?? "application/json",
222
+ });
223
+ res.end(result.body);
224
+ }
225
+ catch (err) {
226
+ respond500(res, err);
196
227
  }
197
228
  })();
198
229
  return true;
@@ -212,12 +243,7 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
212
243
  res.end(result.body);
213
244
  }
214
245
  catch (err) {
215
- if (!res.headersSent) {
216
- res.writeHead(500, { "Content-Type": "application/json" });
217
- res.end(JSON.stringify({
218
- error: err instanceof Error ? err.message : String(err),
219
- }));
220
- }
246
+ respond500(res, err);
221
247
  }
222
248
  })();
223
249
  return true;
@@ -237,12 +263,71 @@ export function tryHandlePublicConnectorRoute(req, res, parsedUrl) {
237
263
  res.end(result.body);
238
264
  }
239
265
  catch (err) {
240
- if (!res.headersSent) {
241
- res.writeHead(500, { "Content-Type": "application/json" });
242
- res.end(JSON.stringify({
243
- error: err instanceof Error ? err.message : String(err),
244
- }));
245
- }
266
+ respond500(res, err);
267
+ }
268
+ })();
269
+ return true;
270
+ }
271
+ // Discord, Asana, GitLab — OAuth authorization-code connectors whose vendor
272
+ // redirects back to these callback URLs with no Patchwork bearer token.
273
+ // They must be registered here (pre-auth) so the browser redirect doesn't
274
+ // hit the bearer-auth gate and get rejected with 401.
275
+ if (parsedUrl.pathname === "/connections/discord/callback" &&
276
+ req.method === "GET") {
277
+ void (async () => {
278
+ try {
279
+ const { handleDiscordCallback } = await import("./connectors/discord.js");
280
+ const code = parsedUrl.searchParams.get("code");
281
+ const state = parsedUrl.searchParams.get("state");
282
+ const error = parsedUrl.searchParams.get("error");
283
+ const result = await handleDiscordCallback(code, state, error);
284
+ res.writeHead(result.status, {
285
+ "Content-Type": result.contentType ?? "text/html",
286
+ });
287
+ res.end(result.body);
288
+ }
289
+ catch (err) {
290
+ respond500(res, err);
291
+ }
292
+ })();
293
+ return true;
294
+ }
295
+ if (parsedUrl.pathname === "/connections/asana/callback" &&
296
+ req.method === "GET") {
297
+ void (async () => {
298
+ try {
299
+ const { handleAsanaCallback } = await import("./connectors/asana.js");
300
+ const code = parsedUrl.searchParams.get("code");
301
+ const state = parsedUrl.searchParams.get("state");
302
+ const error = parsedUrl.searchParams.get("error");
303
+ const result = await handleAsanaCallback(code, state, error);
304
+ res.writeHead(result.status, {
305
+ "Content-Type": result.contentType ?? "text/html",
306
+ });
307
+ res.end(result.body);
308
+ }
309
+ catch (err) {
310
+ respond500(res, err);
311
+ }
312
+ })();
313
+ return true;
314
+ }
315
+ if (parsedUrl.pathname === "/connections/gitlab/callback" &&
316
+ req.method === "GET") {
317
+ void (async () => {
318
+ try {
319
+ const { handleGitLabCallback } = await import("./connectors/gitlab.js");
320
+ const code = parsedUrl.searchParams.get("code");
321
+ const state = parsedUrl.searchParams.get("state");
322
+ const error = parsedUrl.searchParams.get("error");
323
+ const result = await handleGitLabCallback(code, state, error);
324
+ res.writeHead(result.status, {
325
+ "Content-Type": result.contentType ?? "text/html",
326
+ });
327
+ res.end(result.body);
328
+ }
329
+ catch (err) {
330
+ respond500(res, err);
246
331
  }
247
332
  })();
248
333
  return true;
@@ -271,12 +356,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
271
356
  res.end(result.body);
272
357
  }
273
358
  catch (err) {
274
- if (!res.headersSent) {
275
- res.writeHead(500, { "Content-Type": "application/json" });
276
- res.end(JSON.stringify({
277
- error: err instanceof Error ? err.message : String(err),
278
- }));
279
- }
359
+ respond500(res, err);
280
360
  }
281
361
  })();
282
362
  return true;
@@ -299,12 +379,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
299
379
  }
300
380
  }
301
381
  catch (err) {
302
- if (!res.headersSent) {
303
- res.writeHead(500, { "Content-Type": "application/json" });
304
- res.end(JSON.stringify({
305
- error: err instanceof Error ? err.message : String(err),
306
- }));
307
- }
382
+ respond500(res, err);
308
383
  }
309
384
  })();
310
385
  return true;
@@ -320,12 +395,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
320
395
  res.end(result.body);
321
396
  }
322
397
  catch (err) {
323
- if (!res.headersSent) {
324
- res.writeHead(500, { "Content-Type": "application/json" });
325
- res.end(JSON.stringify({
326
- error: err instanceof Error ? err.message : String(err),
327
- }));
328
- }
398
+ respond500(res, err);
329
399
  }
330
400
  })();
331
401
  return true;
@@ -342,12 +412,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
342
412
  res.end(result.body);
343
413
  }
344
414
  catch (err) {
345
- if (!res.headersSent) {
346
- res.writeHead(500, { "Content-Type": "application/json" });
347
- res.end(JSON.stringify({
348
- error: err instanceof Error ? err.message : String(err),
349
- }));
350
- }
415
+ respond500(res, err);
351
416
  }
352
417
  })();
353
418
  return true;
@@ -371,12 +436,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
371
436
  }
372
437
  }
373
438
  catch (err) {
374
- if (!res.headersSent) {
375
- res.writeHead(500, { "Content-Type": "application/json" });
376
- res.end(JSON.stringify({
377
- error: err instanceof Error ? err.message : String(err),
378
- }));
379
- }
439
+ respond500(res, err);
380
440
  }
381
441
  })();
382
442
  return true;
@@ -393,12 +453,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
393
453
  res.end(result.body);
394
454
  }
395
455
  catch (err) {
396
- if (!res.headersSent) {
397
- res.writeHead(500, { "Content-Type": "application/json" });
398
- res.end(JSON.stringify({
399
- error: err instanceof Error ? err.message : String(err),
400
- }));
401
- }
456
+ respond500(res, err);
402
457
  }
403
458
  })();
404
459
  return true;
@@ -414,12 +469,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
414
469
  res.end(result.body);
415
470
  }
416
471
  catch (err) {
417
- if (!res.headersSent) {
418
- res.writeHead(500, { "Content-Type": "application/json" });
419
- res.end(JSON.stringify({
420
- error: err instanceof Error ? err.message : String(err),
421
- }));
422
- }
472
+ respond500(res, err);
423
473
  }
424
474
  })();
425
475
  return true;
@@ -443,12 +493,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
443
493
  }
444
494
  }
445
495
  catch (err) {
446
- if (!res.headersSent) {
447
- res.writeHead(500, { "Content-Type": "application/json" });
448
- res.end(JSON.stringify({
449
- error: err instanceof Error ? err.message : String(err),
450
- }));
451
- }
496
+ respond500(res, err);
452
497
  }
453
498
  })();
454
499
  return true;
@@ -468,12 +513,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
468
513
  res.end(result.body);
469
514
  }
470
515
  catch (err) {
471
- if (!res.headersSent) {
472
- res.writeHead(500, { "Content-Type": "application/json" });
473
- res.end(JSON.stringify({
474
- error: err instanceof Error ? err.message : String(err),
475
- }));
476
- }
516
+ respond500(res, err);
477
517
  }
478
518
  })();
479
519
  return true;
@@ -490,12 +530,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
490
530
  res.end(result.body);
491
531
  }
492
532
  catch (err) {
493
- if (!res.headersSent) {
494
- res.writeHead(500, { "Content-Type": "application/json" });
495
- res.end(JSON.stringify({
496
- error: err instanceof Error ? err.message : String(err),
497
- }));
498
- }
533
+ respond500(res, err);
499
534
  }
500
535
  })();
501
536
  return true;
@@ -511,12 +546,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
511
546
  res.end(result.body);
512
547
  }
513
548
  catch (err) {
514
- if (!res.headersSent) {
515
- res.writeHead(500, { "Content-Type": "application/json" });
516
- res.end(JSON.stringify({
517
- error: err instanceof Error ? err.message : String(err),
518
- }));
519
- }
549
+ respond500(res, err);
520
550
  }
521
551
  })();
522
552
  return true;
@@ -540,12 +570,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
540
570
  }
541
571
  }
542
572
  catch (err) {
543
- if (!res.headersSent) {
544
- res.writeHead(500, { "Content-Type": "application/json" });
545
- res.end(JSON.stringify({
546
- error: err instanceof Error ? err.message : String(err),
547
- }));
548
- }
573
+ respond500(res, err);
549
574
  }
550
575
  })();
551
576
  return true;
@@ -565,12 +590,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
565
590
  res.end(result.body);
566
591
  }
567
592
  catch (err) {
568
- if (!res.headersSent) {
569
- res.writeHead(500, { "Content-Type": "application/json" });
570
- res.end(JSON.stringify({
571
- error: err instanceof Error ? err.message : String(err),
572
- }));
573
- }
593
+ respond500(res, err);
574
594
  }
575
595
  })();
576
596
  return true;
@@ -587,12 +607,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
587
607
  res.end(result.body);
588
608
  }
589
609
  catch (err) {
590
- if (!res.headersSent) {
591
- res.writeHead(500, { "Content-Type": "application/json" });
592
- res.end(JSON.stringify({
593
- error: err instanceof Error ? err.message : String(err),
594
- }));
595
- }
610
+ respond500(res, err);
596
611
  }
597
612
  })();
598
613
  return true;
@@ -608,12 +623,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
608
623
  res.end(result.body);
609
624
  }
610
625
  catch (err) {
611
- if (!res.headersSent) {
612
- res.writeHead(500, { "Content-Type": "application/json" });
613
- res.end(JSON.stringify({
614
- error: err instanceof Error ? err.message : String(err),
615
- }));
616
- }
626
+ respond500(res, err);
617
627
  }
618
628
  })();
619
629
  return true;
@@ -638,12 +648,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
638
648
  }
639
649
  }
640
650
  catch (err) {
641
- if (!res.headersSent) {
642
- res.writeHead(500, { "Content-Type": "application/json" });
643
- res.end(JSON.stringify({
644
- error: err instanceof Error ? err.message : String(err),
645
- }));
646
- }
651
+ respond500(res, err);
647
652
  }
648
653
  })();
649
654
  return true;
@@ -660,12 +665,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
660
665
  res.end(result.body);
661
666
  }
662
667
  catch (err) {
663
- if (!res.headersSent) {
664
- res.writeHead(500, { "Content-Type": "application/json" });
665
- res.end(JSON.stringify({
666
- error: err instanceof Error ? err.message : String(err),
667
- }));
668
- }
668
+ respond500(res, err);
669
669
  }
670
670
  })();
671
671
  return true;
@@ -674,19 +674,14 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
674
674
  void (async () => {
675
675
  try {
676
676
  const { handleSlackDisconnect } = await import("./connectors/slack.js");
677
- const result = handleSlackDisconnect();
677
+ const result = await handleSlackDisconnect();
678
678
  res.writeHead(result.status, {
679
679
  "Content-Type": result.contentType ?? "application/json",
680
680
  });
681
681
  res.end(result.body);
682
682
  }
683
683
  catch (err) {
684
- if (!res.headersSent) {
685
- res.writeHead(500, { "Content-Type": "application/json" });
686
- res.end(JSON.stringify({
687
- error: err instanceof Error ? err.message : String(err),
688
- }));
689
- }
684
+ respond500(res, err);
690
685
  }
691
686
  })();
692
687
  return true;
@@ -711,12 +706,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
711
706
  }
712
707
  }
713
708
  catch (err) {
714
- if (!res.headersSent) {
715
- res.writeHead(500, { "Content-Type": "application/json" });
716
- res.end(JSON.stringify({
717
- error: err instanceof Error ? err.message : String(err),
718
- }));
719
- }
709
+ respond500(res, err);
720
710
  }
721
711
  })();
722
712
  return true;
@@ -736,12 +726,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
736
726
  res.end(result.body);
737
727
  }
738
728
  catch (err) {
739
- if (!res.headersSent) {
740
- res.writeHead(500, { "Content-Type": "application/json" });
741
- res.end(JSON.stringify({
742
- error: err instanceof Error ? err.message : String(err),
743
- }));
744
- }
729
+ respond500(res, err);
745
730
  }
746
731
  })();
747
732
  return true;
@@ -758,12 +743,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
758
743
  res.end(result.body);
759
744
  }
760
745
  catch (err) {
761
- if (!res.headersSent) {
762
- res.writeHead(500, { "Content-Type": "application/json" });
763
- res.end(JSON.stringify({
764
- error: err instanceof Error ? err.message : String(err),
765
- }));
766
- }
746
+ respond500(res, err);
767
747
  }
768
748
  })();
769
749
  return true;
@@ -780,12 +760,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
780
760
  res.end(result.body);
781
761
  }
782
762
  catch (err) {
783
- if (!res.headersSent) {
784
- res.writeHead(500, { "Content-Type": "application/json" });
785
- res.end(JSON.stringify({
786
- error: err instanceof Error ? err.message : String(err),
787
- }));
788
- }
763
+ respond500(res, err);
789
764
  }
790
765
  })();
791
766
  return true;
@@ -810,12 +785,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
810
785
  }
811
786
  }
812
787
  catch (err) {
813
- if (!res.headersSent) {
814
- res.writeHead(500, { "Content-Type": "application/json" });
815
- res.end(JSON.stringify({
816
- error: err instanceof Error ? err.message : String(err),
817
- }));
818
- }
788
+ respond500(res, err);
819
789
  }
820
790
  })();
821
791
  return true;
@@ -835,12 +805,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
835
805
  res.end(result.body);
836
806
  }
837
807
  catch (err) {
838
- if (!res.headersSent) {
839
- res.writeHead(500, { "Content-Type": "application/json" });
840
- res.end(JSON.stringify({
841
- error: err instanceof Error ? err.message : String(err),
842
- }));
843
- }
808
+ respond500(res, err);
844
809
  }
845
810
  })();
846
811
  return true;
@@ -857,12 +822,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
857
822
  res.end(result.body);
858
823
  }
859
824
  catch (err) {
860
- if (!res.headersSent) {
861
- res.writeHead(500, { "Content-Type": "application/json" });
862
- res.end(JSON.stringify({
863
- error: err instanceof Error ? err.message : String(err),
864
- }));
865
- }
825
+ respond500(res, err);
866
826
  }
867
827
  })();
868
828
  return true;
@@ -878,12 +838,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
878
838
  res.end(result.body);
879
839
  }
880
840
  catch (err) {
881
- if (!res.headersSent) {
882
- res.writeHead(500, { "Content-Type": "application/json" });
883
- res.end(JSON.stringify({
884
- error: err instanceof Error ? err.message : String(err),
885
- }));
886
- }
841
+ respond500(res, err);
887
842
  }
888
843
  })();
889
844
  return true;
@@ -908,12 +863,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
908
863
  }
909
864
  }
910
865
  catch (err) {
911
- if (!res.headersSent) {
912
- res.writeHead(500, { "Content-Type": "application/json" });
913
- res.end(JSON.stringify({
914
- error: err instanceof Error ? err.message : String(err),
915
- }));
916
- }
866
+ respond500(res, err);
917
867
  }
918
868
  })();
919
869
  return true;
@@ -933,12 +883,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
933
883
  res.end(result.body);
934
884
  }
935
885
  catch (err) {
936
- if (!res.headersSent) {
937
- res.writeHead(500, { "Content-Type": "application/json" });
938
- res.end(JSON.stringify({
939
- error: err instanceof Error ? err.message : String(err),
940
- }));
941
- }
886
+ respond500(res, err);
942
887
  }
943
888
  })();
944
889
  return true;
@@ -955,12 +900,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
955
900
  res.end(result.body);
956
901
  }
957
902
  catch (err) {
958
- if (!res.headersSent) {
959
- res.writeHead(500, { "Content-Type": "application/json" });
960
- res.end(JSON.stringify({
961
- error: err instanceof Error ? err.message : String(err),
962
- }));
963
- }
903
+ respond500(res, err);
964
904
  }
965
905
  })();
966
906
  return true;
@@ -976,12 +916,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
976
916
  res.end(result.body);
977
917
  }
978
918
  catch (err) {
979
- if (!res.headersSent) {
980
- res.writeHead(500, { "Content-Type": "application/json" });
981
- res.end(JSON.stringify({
982
- error: err instanceof Error ? err.message : String(err),
983
- }));
984
- }
919
+ respond500(res, err);
985
920
  }
986
921
  })();
987
922
  return true;
@@ -1007,12 +942,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1007
942
  res.end(result.body);
1008
943
  }
1009
944
  catch (err) {
1010
- if (!res.headersSent) {
1011
- res.writeHead(500, { "Content-Type": "application/json" });
1012
- res.end(JSON.stringify({
1013
- error: err instanceof Error ? err.message : String(err),
1014
- }));
1015
- }
945
+ respond500(res, err);
1016
946
  }
1017
947
  })();
1018
948
  return true;
@@ -1028,12 +958,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1028
958
  res.end(result.body);
1029
959
  }
1030
960
  catch (err) {
1031
- if (!res.headersSent) {
1032
- res.writeHead(500, { "Content-Type": "application/json" });
1033
- res.end(JSON.stringify({
1034
- error: err instanceof Error ? err.message : String(err),
1035
- }));
1036
- }
961
+ respond500(res, err);
1037
962
  }
1038
963
  })();
1039
964
  return true;
@@ -1059,12 +984,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1059
984
  res.end(result.body);
1060
985
  }
1061
986
  catch (err) {
1062
- if (!res.headersSent) {
1063
- res.writeHead(500, { "Content-Type": "application/json" });
1064
- res.end(JSON.stringify({
1065
- error: err instanceof Error ? err.message : String(err),
1066
- }));
1067
- }
987
+ respond500(res, err);
1068
988
  }
1069
989
  })();
1070
990
  return true;
@@ -1081,12 +1001,49 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1081
1001
  res.end(result.body);
1082
1002
  }
1083
1003
  catch (err) {
1084
- if (!res.headersSent) {
1085
- res.writeHead(500, { "Content-Type": "application/json" });
1086
- res.end(JSON.stringify({
1087
- error: err instanceof Error ? err.message : String(err),
1088
- }));
1089
- }
1004
+ respond500(res, err);
1005
+ }
1006
+ })();
1007
+ return true;
1008
+ }
1009
+ // ── Jira routes ─────────────────────────────────────────────────
1010
+ if (parsedUrl.pathname === "/connections/jira/connect" &&
1011
+ req.method === "POST") {
1012
+ void dispatchConnectorConnect(req, res, async () => {
1013
+ const m = await import("./connectors/jira.js");
1014
+ return m.handleJiraConnect;
1015
+ });
1016
+ return true;
1017
+ }
1018
+ if (parsedUrl.pathname === "/connections/jira/test" &&
1019
+ req.method === "POST") {
1020
+ void (async () => {
1021
+ try {
1022
+ const { handleJiraTest } = await import("./connectors/jira.js");
1023
+ const result = await handleJiraTest();
1024
+ res.writeHead(result.status, {
1025
+ "Content-Type": result.contentType ?? "application/json",
1026
+ });
1027
+ res.end(result.body);
1028
+ }
1029
+ catch (err) {
1030
+ respond500(res, err);
1031
+ }
1032
+ })();
1033
+ return true;
1034
+ }
1035
+ if (parsedUrl.pathname === "/connections/jira" && req.method === "DELETE") {
1036
+ void (async () => {
1037
+ try {
1038
+ const { handleJiraDisconnect } = await import("./connectors/jira.js");
1039
+ const result = handleJiraDisconnect();
1040
+ res.writeHead(result.status, {
1041
+ "Content-Type": result.contentType ?? "application/json",
1042
+ });
1043
+ res.end(result.body);
1044
+ }
1045
+ catch (err) {
1046
+ respond500(res, err);
1090
1047
  }
1091
1048
  })();
1092
1049
  return true;
@@ -1112,12 +1069,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1112
1069
  res.end(result.body);
1113
1070
  }
1114
1071
  catch (err) {
1115
- if (!res.headersSent) {
1116
- res.writeHead(500, { "Content-Type": "application/json" });
1117
- res.end(JSON.stringify({
1118
- error: err instanceof Error ? err.message : String(err),
1119
- }));
1120
- }
1072
+ respond500(res, err);
1121
1073
  }
1122
1074
  })();
1123
1075
  return true;
@@ -1134,12 +1086,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1134
1086
  res.end(result.body);
1135
1087
  }
1136
1088
  catch (err) {
1137
- if (!res.headersSent) {
1138
- res.writeHead(500, { "Content-Type": "application/json" });
1139
- res.end(JSON.stringify({
1140
- error: err instanceof Error ? err.message : String(err),
1141
- }));
1142
- }
1089
+ respond500(res, err);
1143
1090
  }
1144
1091
  })();
1145
1092
  return true;
@@ -1165,12 +1112,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1165
1112
  res.end(result.body);
1166
1113
  }
1167
1114
  catch (err) {
1168
- if (!res.headersSent) {
1169
- res.writeHead(500, { "Content-Type": "application/json" });
1170
- res.end(JSON.stringify({
1171
- error: err instanceof Error ? err.message : String(err),
1172
- }));
1173
- }
1115
+ respond500(res, err);
1174
1116
  }
1175
1117
  })();
1176
1118
  return true;
@@ -1187,12 +1129,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1187
1129
  res.end(result.body);
1188
1130
  }
1189
1131
  catch (err) {
1190
- if (!res.headersSent) {
1191
- res.writeHead(500, { "Content-Type": "application/json" });
1192
- res.end(JSON.stringify({
1193
- error: err instanceof Error ? err.message : String(err),
1194
- }));
1195
- }
1132
+ respond500(res, err);
1196
1133
  }
1197
1134
  })();
1198
1135
  return true;
@@ -1218,12 +1155,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1218
1155
  res.end(result.body);
1219
1156
  }
1220
1157
  catch (err) {
1221
- if (!res.headersSent) {
1222
- res.writeHead(500, { "Content-Type": "application/json" });
1223
- res.end(JSON.stringify({
1224
- error: err instanceof Error ? err.message : String(err),
1225
- }));
1226
- }
1158
+ respond500(res, err);
1227
1159
  }
1228
1160
  })();
1229
1161
  return true;
@@ -1240,12 +1172,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1240
1172
  res.end(result.body);
1241
1173
  }
1242
1174
  catch (err) {
1243
- if (!res.headersSent) {
1244
- res.writeHead(500, { "Content-Type": "application/json" });
1245
- res.end(JSON.stringify({
1246
- error: err instanceof Error ? err.message : String(err),
1247
- }));
1248
- }
1175
+ respond500(res, err);
1249
1176
  }
1250
1177
  })();
1251
1178
  return true;
@@ -1271,12 +1198,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1271
1198
  res.end(result.body);
1272
1199
  }
1273
1200
  catch (err) {
1274
- if (!res.headersSent) {
1275
- res.writeHead(500, { "Content-Type": "application/json" });
1276
- res.end(JSON.stringify({
1277
- error: err instanceof Error ? err.message : String(err),
1278
- }));
1279
- }
1201
+ respond500(res, err);
1280
1202
  }
1281
1203
  })();
1282
1204
  return true;
@@ -1293,12 +1215,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1293
1215
  res.end(result.body);
1294
1216
  }
1295
1217
  catch (err) {
1296
- if (!res.headersSent) {
1297
- res.writeHead(500, { "Content-Type": "application/json" });
1298
- res.end(JSON.stringify({
1299
- error: err instanceof Error ? err.message : String(err),
1300
- }));
1301
- }
1218
+ respond500(res, err);
1302
1219
  }
1303
1220
  })();
1304
1221
  return true;
@@ -1324,12 +1241,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1324
1241
  res.end(result.body);
1325
1242
  }
1326
1243
  catch (err) {
1327
- if (!res.headersSent) {
1328
- res.writeHead(500, { "Content-Type": "application/json" });
1329
- res.end(JSON.stringify({
1330
- error: err instanceof Error ? err.message : String(err),
1331
- }));
1332
- }
1244
+ respond500(res, err);
1333
1245
  }
1334
1246
  })();
1335
1247
  return true;
@@ -1346,12 +1258,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1346
1258
  res.end(result.body);
1347
1259
  }
1348
1260
  catch (err) {
1349
- if (!res.headersSent) {
1350
- res.writeHead(500, { "Content-Type": "application/json" });
1351
- res.end(JSON.stringify({
1352
- error: err instanceof Error ? err.message : String(err),
1353
- }));
1354
- }
1261
+ respond500(res, err);
1355
1262
  }
1356
1263
  })();
1357
1264
  return true;
@@ -1377,12 +1284,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1377
1284
  res.end(result.body);
1378
1285
  }
1379
1286
  catch (err) {
1380
- if (!res.headersSent) {
1381
- res.writeHead(500, { "Content-Type": "application/json" });
1382
- res.end(JSON.stringify({
1383
- error: err instanceof Error ? err.message : String(err),
1384
- }));
1385
- }
1287
+ respond500(res, err);
1386
1288
  }
1387
1289
  })();
1388
1290
  return true;
@@ -1398,140 +1300,494 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1398
1300
  res.end(result.body);
1399
1301
  }
1400
1302
  catch (err) {
1401
- if (!res.headersSent) {
1402
- res.writeHead(500, { "Content-Type": "application/json" });
1403
- res.end(JSON.stringify({
1404
- error: err instanceof Error ? err.message : String(err),
1405
- }));
1406
- }
1303
+ respond500(res, err);
1407
1304
  }
1408
1305
  })();
1409
1306
  return true;
1410
1307
  }
1411
- // ── Google Calendar routes ──────────────────────────────────────
1412
- if (parsedUrl.pathname === "/connections/google-calendar/auth" &&
1413
- req.method === "GET") {
1308
+ // ── Postgres routes ─────────────────────────────────────────────
1309
+ if (parsedUrl.pathname === "/connections/postgres/connect" &&
1310
+ req.method === "POST") {
1311
+ void dispatchConnectorConnect(req, res, async () => {
1312
+ const m = await import("./connectors/postgres.js");
1313
+ return m.handlePostgresConnect;
1314
+ });
1315
+ return true;
1316
+ }
1317
+ if (parsedUrl.pathname === "/connections/postgres/test" &&
1318
+ req.method === "POST") {
1414
1319
  void (async () => {
1415
1320
  try {
1416
- const { handleCalendarAuthRedirect } = await import("./connectors/googleCalendar.js");
1417
- const result = handleCalendarAuthRedirect();
1418
- if (result.redirect) {
1419
- res.writeHead(302, { Location: result.redirect });
1420
- res.end();
1421
- }
1422
- else {
1423
- res.writeHead(result.status, {
1424
- "Content-Type": result.contentType ?? "application/json",
1425
- });
1426
- res.end(result.body);
1427
- }
1321
+ const { handlePostgresTest } = await import("./connectors/postgres.js");
1322
+ const result = await handlePostgresTest();
1323
+ res.writeHead(result.status, {
1324
+ "Content-Type": result.contentType ?? "application/json",
1325
+ });
1326
+ res.end(result.body);
1428
1327
  }
1429
1328
  catch (err) {
1430
- if (!res.headersSent) {
1431
- res.writeHead(500, { "Content-Type": "application/json" });
1432
- res.end(JSON.stringify({
1433
- error: err instanceof Error ? err.message : String(err),
1434
- }));
1435
- }
1329
+ respond500(res, err);
1436
1330
  }
1437
1331
  })();
1438
1332
  return true;
1439
1333
  }
1440
- if (parsedUrl.pathname === "/connections/google-calendar/callback" &&
1441
- req.method === "GET") {
1334
+ if (parsedUrl.pathname === "/connections/postgres" &&
1335
+ req.method === "DELETE") {
1442
1336
  void (async () => {
1443
1337
  try {
1444
- const { handleCalendarCallback } = await import("./connectors/googleCalendar.js");
1445
- const code = parsedUrl.searchParams.get("code");
1446
- const state = parsedUrl.searchParams.get("state");
1447
- const error = parsedUrl.searchParams.get("error");
1448
- const result = await handleCalendarCallback(code, state, error);
1338
+ const { handlePostgresDisconnect } = await import("./connectors/postgres.js");
1339
+ const result = await handlePostgresDisconnect();
1449
1340
  res.writeHead(result.status, {
1450
1341
  "Content-Type": result.contentType ?? "application/json",
1451
1342
  });
1452
1343
  res.end(result.body);
1453
1344
  }
1454
1345
  catch (err) {
1455
- if (!res.headersSent) {
1456
- res.writeHead(500, { "Content-Type": "application/json" });
1457
- res.end(JSON.stringify({
1458
- error: err instanceof Error ? err.message : String(err),
1459
- }));
1460
- }
1346
+ respond500(res, err);
1461
1347
  }
1462
1348
  })();
1463
1349
  return true;
1464
1350
  }
1465
- if (parsedUrl.pathname === "/connections/google-calendar/test" &&
1351
+ // ── MongoDB routes ──────────────────────────────────────────────
1352
+ if (parsedUrl.pathname === "/connections/mongodb/connect" &&
1353
+ req.method === "POST") {
1354
+ void dispatchConnectorConnect(req, res, async () => {
1355
+ const m = await import("./connectors/mongodb.js");
1356
+ return m.handleMongoConnect;
1357
+ });
1358
+ return true;
1359
+ }
1360
+ if (parsedUrl.pathname === "/connections/mongodb/test" &&
1466
1361
  req.method === "POST") {
1467
1362
  void (async () => {
1468
1363
  try {
1469
- const { handleCalendarTest } = await import("./connectors/googleCalendar.js");
1470
- const result = await handleCalendarTest();
1364
+ const { handleMongoTest } = await import("./connectors/mongodb.js");
1365
+ const result = await handleMongoTest();
1471
1366
  res.writeHead(result.status, {
1472
1367
  "Content-Type": result.contentType ?? "application/json",
1473
1368
  });
1474
1369
  res.end(result.body);
1475
1370
  }
1476
1371
  catch (err) {
1477
- if (!res.headersSent) {
1478
- res.writeHead(500, { "Content-Type": "application/json" });
1479
- res.end(JSON.stringify({
1480
- error: err instanceof Error ? err.message : String(err),
1481
- }));
1482
- }
1372
+ respond500(res, err);
1483
1373
  }
1484
1374
  })();
1485
1375
  return true;
1486
1376
  }
1487
- if (parsedUrl.pathname === "/connections/google-calendar" &&
1377
+ if (parsedUrl.pathname === "/connections/mongodb" &&
1488
1378
  req.method === "DELETE") {
1489
1379
  void (async () => {
1490
1380
  try {
1491
- const { handleCalendarDisconnect } = await import("./connectors/googleCalendar.js");
1492
- const result = await handleCalendarDisconnect();
1381
+ const { handleMongoDisconnect } = await import("./connectors/mongodb.js");
1382
+ const result = await handleMongoDisconnect();
1493
1383
  res.writeHead(result.status, {
1494
1384
  "Content-Type": result.contentType ?? "application/json",
1495
1385
  });
1496
1386
  res.end(result.body);
1497
1387
  }
1498
1388
  catch (err) {
1499
- if (!res.headersSent) {
1500
- res.writeHead(500, { "Content-Type": "application/json" });
1501
- res.end(JSON.stringify({
1502
- error: err instanceof Error ? err.message : String(err),
1503
- }));
1504
- }
1389
+ respond500(res, err);
1505
1390
  }
1506
1391
  })();
1507
1392
  return true;
1508
1393
  }
1509
- // ── Google Drive routes ─────────────────────────────────────────
1510
- if (parsedUrl.pathname === "/connections/google-drive/auth" &&
1511
- req.method === "GET") {
1394
+ // ── Redis routes ────────────────────────────────────────────────
1395
+ if (parsedUrl.pathname === "/connections/redis/connect" &&
1396
+ req.method === "POST") {
1397
+ void dispatchConnectorConnect(req, res, async () => {
1398
+ const m = await import("./connectors/redis.js");
1399
+ return m.handleRedisConnect;
1400
+ });
1401
+ return true;
1402
+ }
1403
+ if (parsedUrl.pathname === "/connections/redis/test" &&
1404
+ req.method === "POST") {
1512
1405
  void (async () => {
1513
1406
  try {
1514
- const { handleDriveAuthRedirect } = await import("./connectors/googleDrive.js");
1515
- const result = handleDriveAuthRedirect();
1516
- if (result.redirect) {
1517
- res.writeHead(302, { Location: result.redirect });
1518
- res.end();
1519
- }
1520
- else {
1521
- res.writeHead(result.status, {
1522
- "Content-Type": result.contentType ?? "application/json",
1523
- });
1524
- res.end(result.body);
1407
+ const { handleRedisTest } = await import("./connectors/redis.js");
1408
+ const result = await handleRedisTest();
1409
+ res.writeHead(result.status, {
1410
+ "Content-Type": result.contentType ?? "application/json",
1411
+ });
1412
+ res.end(result.body);
1413
+ }
1414
+ catch (err) {
1415
+ respond500(res, err);
1416
+ }
1417
+ })();
1418
+ return true;
1419
+ }
1420
+ if (parsedUrl.pathname === "/connections/redis" && req.method === "DELETE") {
1421
+ void (async () => {
1422
+ try {
1423
+ const { handleRedisDisconnect } = await import("./connectors/redis.js");
1424
+ const result = await handleRedisDisconnect();
1425
+ res.writeHead(result.status, {
1426
+ "Content-Type": result.contentType ?? "application/json",
1427
+ });
1428
+ res.end(result.body);
1429
+ }
1430
+ catch (err) {
1431
+ respond500(res, err);
1432
+ }
1433
+ })();
1434
+ return true;
1435
+ }
1436
+ // ── Elasticsearch routes ────────────────────────────────────────
1437
+ if (parsedUrl.pathname === "/connections/elasticsearch/connect" &&
1438
+ req.method === "POST") {
1439
+ void dispatchConnectorConnect(req, res, async () => {
1440
+ const m = await import("./connectors/elasticsearch.js");
1441
+ return m.handleElasticsearchConnect;
1442
+ });
1443
+ return true;
1444
+ }
1445
+ if (parsedUrl.pathname === "/connections/elasticsearch/test" &&
1446
+ req.method === "POST") {
1447
+ void (async () => {
1448
+ try {
1449
+ const { handleElasticsearchTest } = await import("./connectors/elasticsearch.js");
1450
+ const result = await handleElasticsearchTest();
1451
+ res.writeHead(result.status, {
1452
+ "Content-Type": result.contentType ?? "application/json",
1453
+ });
1454
+ res.end(result.body);
1455
+ }
1456
+ catch (err) {
1457
+ respond500(res, err);
1458
+ }
1459
+ })();
1460
+ return true;
1461
+ }
1462
+ if (parsedUrl.pathname === "/connections/elasticsearch" &&
1463
+ req.method === "DELETE") {
1464
+ void (async () => {
1465
+ try {
1466
+ const { handleElasticsearchDisconnect } = await import("./connectors/elasticsearch.js");
1467
+ const result = await handleElasticsearchDisconnect();
1468
+ res.writeHead(result.status, {
1469
+ "Content-Type": result.contentType ?? "application/json",
1470
+ });
1471
+ res.end(result.body);
1472
+ }
1473
+ catch (err) {
1474
+ respond500(res, err);
1475
+ }
1476
+ })();
1477
+ return true;
1478
+ }
1479
+ // ── SendGrid routes ─────────────────────────────────────────────
1480
+ if (parsedUrl.pathname === "/connections/sendgrid/connect" &&
1481
+ req.method === "POST") {
1482
+ void dispatchConnectorConnect(req, res, async () => {
1483
+ const m = await import("./connectors/sendgrid.js");
1484
+ return m.handleSendGridConnect;
1485
+ });
1486
+ return true;
1487
+ }
1488
+ if (parsedUrl.pathname === "/connections/sendgrid/test" &&
1489
+ req.method === "POST") {
1490
+ void (async () => {
1491
+ try {
1492
+ const { handleSendGridTest } = await import("./connectors/sendgrid.js");
1493
+ const result = await handleSendGridTest();
1494
+ res.writeHead(result.status, {
1495
+ "Content-Type": result.contentType ?? "application/json",
1496
+ });
1497
+ res.end(result.body);
1498
+ }
1499
+ catch (err) {
1500
+ respond500(res, err);
1501
+ }
1502
+ })();
1503
+ return true;
1504
+ }
1505
+ if (parsedUrl.pathname === "/connections/sendgrid" &&
1506
+ req.method === "DELETE") {
1507
+ void (async () => {
1508
+ try {
1509
+ const { handleSendGridDisconnect } = await import("./connectors/sendgrid.js");
1510
+ const result = handleSendGridDisconnect();
1511
+ res.writeHead(result.status, {
1512
+ "Content-Type": result.contentType ?? "application/json",
1513
+ });
1514
+ res.end(result.body);
1515
+ }
1516
+ catch (err) {
1517
+ respond500(res, err);
1518
+ }
1519
+ })();
1520
+ return true;
1521
+ }
1522
+ // ── Twilio routes ───────────────────────────────────────────────
1523
+ if (parsedUrl.pathname === "/connections/twilio/connect" &&
1524
+ req.method === "POST") {
1525
+ void dispatchConnectorConnect(req, res, async () => {
1526
+ const m = await import("./connectors/twilio.js");
1527
+ return m.handleTwilioConnect;
1528
+ });
1529
+ return true;
1530
+ }
1531
+ if (parsedUrl.pathname === "/connections/twilio/test" &&
1532
+ req.method === "POST") {
1533
+ void (async () => {
1534
+ try {
1535
+ const { handleTwilioTest } = await import("./connectors/twilio.js");
1536
+ const result = await handleTwilioTest();
1537
+ res.writeHead(result.status, {
1538
+ "Content-Type": result.contentType ?? "application/json",
1539
+ });
1540
+ res.end(result.body);
1541
+ }
1542
+ catch (err) {
1543
+ respond500(res, err);
1544
+ }
1545
+ })();
1546
+ return true;
1547
+ }
1548
+ if (parsedUrl.pathname === "/connections/twilio" && req.method === "DELETE") {
1549
+ void (async () => {
1550
+ try {
1551
+ const { handleTwilioDisconnect } = await import("./connectors/twilio.js");
1552
+ const result = handleTwilioDisconnect();
1553
+ res.writeHead(result.status, {
1554
+ "Content-Type": result.contentType ?? "application/json",
1555
+ });
1556
+ res.end(result.body);
1557
+ }
1558
+ catch (err) {
1559
+ respond500(res, err);
1560
+ }
1561
+ })();
1562
+ return true;
1563
+ }
1564
+ // ── Figma routes ────────────────────────────────────────────────
1565
+ if (parsedUrl.pathname === "/connections/figma/connect" &&
1566
+ req.method === "POST") {
1567
+ void dispatchConnectorConnect(req, res, async () => {
1568
+ const m = await import("./connectors/figma.js");
1569
+ return m.handleFigmaConnect;
1570
+ });
1571
+ return true;
1572
+ }
1573
+ if (parsedUrl.pathname === "/connections/figma/test" &&
1574
+ req.method === "POST") {
1575
+ void (async () => {
1576
+ try {
1577
+ const { handleFigmaTest } = await import("./connectors/figma.js");
1578
+ const result = await handleFigmaTest();
1579
+ res.writeHead(result.status, {
1580
+ "Content-Type": result.contentType ?? "application/json",
1581
+ });
1582
+ res.end(result.body);
1583
+ }
1584
+ catch (err) {
1585
+ respond500(res, err);
1586
+ }
1587
+ })();
1588
+ return true;
1589
+ }
1590
+ if (parsedUrl.pathname === "/connections/figma" && req.method === "DELETE") {
1591
+ void (async () => {
1592
+ try {
1593
+ const { handleFigmaDisconnect } = await import("./connectors/figma.js");
1594
+ const result = handleFigmaDisconnect();
1595
+ res.writeHead(result.status, {
1596
+ "Content-Type": result.contentType ?? "application/json",
1597
+ });
1598
+ res.end(result.body);
1599
+ }
1600
+ catch (err) {
1601
+ respond500(res, err);
1602
+ }
1603
+ })();
1604
+ return true;
1605
+ }
1606
+ // ── Airtable routes ─────────────────────────────────────────────
1607
+ if (parsedUrl.pathname === "/connections/airtable/connect" &&
1608
+ req.method === "POST") {
1609
+ void dispatchConnectorConnect(req, res, async () => {
1610
+ const m = await import("./connectors/airtable.js");
1611
+ return m.handleAirtableConnect;
1612
+ });
1613
+ return true;
1614
+ }
1615
+ if (parsedUrl.pathname === "/connections/airtable/test" &&
1616
+ req.method === "POST") {
1617
+ void (async () => {
1618
+ try {
1619
+ const { handleAirtableTest } = await import("./connectors/airtable.js");
1620
+ const result = await handleAirtableTest();
1621
+ res.writeHead(result.status, {
1622
+ "Content-Type": result.contentType ?? "application/json",
1623
+ });
1624
+ res.end(result.body);
1625
+ }
1626
+ catch (err) {
1627
+ respond500(res, err);
1628
+ }
1629
+ })();
1630
+ return true;
1631
+ }
1632
+ if (parsedUrl.pathname === "/connections/airtable" &&
1633
+ req.method === "DELETE") {
1634
+ void (async () => {
1635
+ try {
1636
+ const { handleAirtableDisconnect } = await import("./connectors/airtable.js");
1637
+ const result = handleAirtableDisconnect();
1638
+ res.writeHead(result.status, {
1639
+ "Content-Type": result.contentType ?? "application/json",
1640
+ });
1641
+ res.end(result.body);
1642
+ }
1643
+ catch (err) {
1644
+ respond500(res, err);
1645
+ }
1646
+ })();
1647
+ return true;
1648
+ }
1649
+ // ── Webflow routes ──────────────────────────────────────────────
1650
+ if (parsedUrl.pathname === "/connections/webflow/connect" &&
1651
+ req.method === "POST") {
1652
+ void dispatchConnectorConnect(req, res, async () => {
1653
+ const m = await import("./connectors/webflow.js");
1654
+ return m.handleWebflowConnect;
1655
+ });
1656
+ return true;
1657
+ }
1658
+ if (parsedUrl.pathname === "/connections/webflow/test" &&
1659
+ req.method === "POST") {
1660
+ void (async () => {
1661
+ try {
1662
+ const { handleWebflowTest } = await import("./connectors/webflow.js");
1663
+ const result = await handleWebflowTest();
1664
+ res.writeHead(result.status, {
1665
+ "Content-Type": result.contentType ?? "application/json",
1666
+ });
1667
+ res.end(result.body);
1668
+ }
1669
+ catch (err) {
1670
+ respond500(res, err);
1671
+ }
1672
+ })();
1673
+ return true;
1674
+ }
1675
+ if (parsedUrl.pathname === "/connections/webflow" &&
1676
+ req.method === "DELETE") {
1677
+ void (async () => {
1678
+ try {
1679
+ const { handleWebflowDisconnect } = await import("./connectors/webflow.js");
1680
+ const result = handleWebflowDisconnect();
1681
+ res.writeHead(result.status, {
1682
+ "Content-Type": result.contentType ?? "application/json",
1683
+ });
1684
+ res.end(result.body);
1685
+ }
1686
+ catch (err) {
1687
+ respond500(res, err);
1688
+ }
1689
+ })();
1690
+ return true;
1691
+ }
1692
+ // ── Google Calendar routes ──────────────────────────────────────
1693
+ if (parsedUrl.pathname === "/connections/google-calendar/auth" &&
1694
+ req.method === "GET") {
1695
+ void (async () => {
1696
+ try {
1697
+ const { handleCalendarAuthRedirect } = await import("./connectors/googleCalendar.js");
1698
+ const result = handleCalendarAuthRedirect();
1699
+ if (result.redirect) {
1700
+ res.writeHead(302, { Location: result.redirect });
1701
+ res.end();
1525
1702
  }
1703
+ else {
1704
+ res.writeHead(result.status, {
1705
+ "Content-Type": result.contentType ?? "application/json",
1706
+ });
1707
+ res.end(result.body);
1708
+ }
1709
+ }
1710
+ catch (err) {
1711
+ respond500(res, err);
1712
+ }
1713
+ })();
1714
+ return true;
1715
+ }
1716
+ if (parsedUrl.pathname === "/connections/google-calendar/callback" &&
1717
+ req.method === "GET") {
1718
+ void (async () => {
1719
+ try {
1720
+ const { handleCalendarCallback } = await import("./connectors/googleCalendar.js");
1721
+ const code = parsedUrl.searchParams.get("code");
1722
+ const state = parsedUrl.searchParams.get("state");
1723
+ const error = parsedUrl.searchParams.get("error");
1724
+ const result = await handleCalendarCallback(code, state, error);
1725
+ res.writeHead(result.status, {
1726
+ "Content-Type": result.contentType ?? "application/json",
1727
+ });
1728
+ res.end(result.body);
1729
+ }
1730
+ catch (err) {
1731
+ respond500(res, err);
1732
+ }
1733
+ })();
1734
+ return true;
1735
+ }
1736
+ if (parsedUrl.pathname === "/connections/google-calendar/test" &&
1737
+ req.method === "POST") {
1738
+ void (async () => {
1739
+ try {
1740
+ const { handleCalendarTest } = await import("./connectors/googleCalendar.js");
1741
+ const result = await handleCalendarTest();
1742
+ res.writeHead(result.status, {
1743
+ "Content-Type": result.contentType ?? "application/json",
1744
+ });
1745
+ res.end(result.body);
1526
1746
  }
1527
1747
  catch (err) {
1528
- if (!res.headersSent) {
1529
- res.writeHead(500, { "Content-Type": "application/json" });
1530
- res.end(JSON.stringify({
1531
- error: err instanceof Error ? err.message : String(err),
1532
- }));
1748
+ respond500(res, err);
1749
+ }
1750
+ })();
1751
+ return true;
1752
+ }
1753
+ if (parsedUrl.pathname === "/connections/google-calendar" &&
1754
+ req.method === "DELETE") {
1755
+ void (async () => {
1756
+ try {
1757
+ const { handleCalendarDisconnect } = await import("./connectors/googleCalendar.js");
1758
+ const result = await handleCalendarDisconnect();
1759
+ res.writeHead(result.status, {
1760
+ "Content-Type": result.contentType ?? "application/json",
1761
+ });
1762
+ res.end(result.body);
1763
+ }
1764
+ catch (err) {
1765
+ respond500(res, err);
1766
+ }
1767
+ })();
1768
+ return true;
1769
+ }
1770
+ // ── Google Drive routes ─────────────────────────────────────────
1771
+ if (parsedUrl.pathname === "/connections/google-drive/auth" &&
1772
+ req.method === "GET") {
1773
+ void (async () => {
1774
+ try {
1775
+ const { handleDriveAuthRedirect } = await import("./connectors/googleDrive.js");
1776
+ const result = handleDriveAuthRedirect();
1777
+ if (result.redirect) {
1778
+ res.writeHead(302, { Location: result.redirect });
1779
+ res.end();
1780
+ }
1781
+ else {
1782
+ res.writeHead(result.status, {
1783
+ "Content-Type": result.contentType ?? "application/json",
1784
+ });
1785
+ res.end(result.body);
1533
1786
  }
1534
1787
  }
1788
+ catch (err) {
1789
+ respond500(res, err);
1790
+ }
1535
1791
  })();
1536
1792
  return true;
1537
1793
  }
@@ -1550,12 +1806,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1550
1806
  res.end(result.body);
1551
1807
  }
1552
1808
  catch (err) {
1553
- if (!res.headersSent) {
1554
- res.writeHead(500, { "Content-Type": "application/json" });
1555
- res.end(JSON.stringify({
1556
- error: err instanceof Error ? err.message : String(err),
1557
- }));
1558
- }
1809
+ respond500(res, err);
1559
1810
  }
1560
1811
  })();
1561
1812
  return true;
@@ -1572,12 +1823,7 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1572
1823
  res.end(result.body);
1573
1824
  }
1574
1825
  catch (err) {
1575
- if (!res.headersSent) {
1576
- res.writeHead(500, { "Content-Type": "application/json" });
1577
- res.end(JSON.stringify({
1578
- error: err instanceof Error ? err.message : String(err),
1579
- }));
1580
- }
1826
+ respond500(res, err);
1581
1827
  }
1582
1828
  })();
1583
1829
  return true;
@@ -1594,13 +1840,267 @@ export function tryHandleConnectorRoute(req, res, parsedUrl) {
1594
1840
  res.end(result.body);
1595
1841
  }
1596
1842
  catch (err) {
1597
- if (!res.headersSent) {
1598
- res.writeHead(500, { "Content-Type": "application/json" });
1599
- res.end(JSON.stringify({
1600
- error: err instanceof Error ? err.message : String(err),
1601
- }));
1843
+ respond500(res, err);
1844
+ }
1845
+ })();
1846
+ return true;
1847
+ }
1848
+ // ── Google Docs routes ──────────────────────────────────────────
1849
+ if (parsedUrl.pathname === "/connections/google-docs/auth" &&
1850
+ req.method === "GET") {
1851
+ void (async () => {
1852
+ try {
1853
+ const { handleDocsAuthRedirect } = await import("./connectors/googleDocs.js");
1854
+ const result = handleDocsAuthRedirect();
1855
+ if (result.redirect) {
1856
+ res.writeHead(302, { Location: result.redirect });
1857
+ res.end();
1858
+ }
1859
+ else {
1860
+ res.writeHead(result.status, {
1861
+ "Content-Type": result.contentType ?? "application/json",
1862
+ });
1863
+ res.end(result.body);
1864
+ }
1865
+ }
1866
+ catch (err) {
1867
+ respond500(res, err);
1868
+ }
1869
+ })();
1870
+ return true;
1871
+ }
1872
+ if (parsedUrl.pathname === "/connections/google-docs/test" &&
1873
+ req.method === "POST") {
1874
+ void (async () => {
1875
+ try {
1876
+ const { handleDocsTest } = await import("./connectors/googleDocs.js");
1877
+ const result = await handleDocsTest();
1878
+ res.writeHead(result.status, {
1879
+ "Content-Type": result.contentType ?? "application/json",
1880
+ });
1881
+ res.end(result.body);
1882
+ }
1883
+ catch (err) {
1884
+ respond500(res, err);
1885
+ }
1886
+ })();
1887
+ return true;
1888
+ }
1889
+ if (parsedUrl.pathname === "/connections/google-docs" &&
1890
+ req.method === "DELETE") {
1891
+ void (async () => {
1892
+ try {
1893
+ const { handleDocsDisconnect } = await import("./connectors/googleDocs.js");
1894
+ const result = await handleDocsDisconnect();
1895
+ res.writeHead(result.status, {
1896
+ "Content-Type": result.contentType ?? "application/json",
1897
+ });
1898
+ res.end(result.body);
1899
+ }
1900
+ catch (err) {
1901
+ respond500(res, err);
1902
+ }
1903
+ })();
1904
+ return true;
1905
+ }
1906
+ // ── Monday routes ───────────────────────────────────────────────
1907
+ if (parsedUrl.pathname === "/connections/monday/auth" &&
1908
+ req.method === "GET") {
1909
+ void (async () => {
1910
+ try {
1911
+ const { handleMondayAuthRedirect } = await import("./connectors/monday.js");
1912
+ const result = handleMondayAuthRedirect();
1913
+ if (result.redirect) {
1914
+ res.writeHead(302, { Location: result.redirect });
1915
+ res.end();
1916
+ }
1917
+ else {
1918
+ res.writeHead(result.status, {
1919
+ "Content-Type": result.contentType ?? "application/json",
1920
+ });
1921
+ res.end(result.body);
1922
+ }
1923
+ }
1924
+ catch (err) {
1925
+ respond500(res, err);
1926
+ }
1927
+ })();
1928
+ return true;
1929
+ }
1930
+ if (parsedUrl.pathname === "/connections/monday/test" &&
1931
+ req.method === "POST") {
1932
+ void (async () => {
1933
+ try {
1934
+ const { handleMondayTest } = await import("./connectors/monday.js");
1935
+ const result = await handleMondayTest();
1936
+ res.writeHead(result.status, {
1937
+ "Content-Type": result.contentType ?? "application/json",
1938
+ });
1939
+ res.end(result.body);
1940
+ }
1941
+ catch (err) {
1942
+ respond500(res, err);
1943
+ }
1944
+ })();
1945
+ return true;
1946
+ }
1947
+ if (parsedUrl.pathname === "/connections/monday" && req.method === "DELETE") {
1948
+ void (async () => {
1949
+ try {
1950
+ const { handleMondayDisconnect } = await import("./connectors/monday.js");
1951
+ const result = await handleMondayDisconnect();
1952
+ res.writeHead(result.status, {
1953
+ "Content-Type": result.contentType ?? "application/json",
1954
+ });
1955
+ res.end(result.body);
1956
+ }
1957
+ catch (err) {
1958
+ respond500(res, err);
1959
+ }
1960
+ })();
1961
+ return true;
1962
+ }
1963
+ // ── Salesforce routes ───────────────────────────────────────────
1964
+ if (parsedUrl.pathname === "/connections/salesforce/auth" &&
1965
+ req.method === "GET") {
1966
+ void (async () => {
1967
+ try {
1968
+ const { handleSalesforceAuthRedirect } = await import("./connectors/salesforce.js");
1969
+ const result = handleSalesforceAuthRedirect();
1970
+ if (result.redirect) {
1971
+ res.writeHead(302, { Location: result.redirect });
1972
+ res.end();
1973
+ }
1974
+ else {
1975
+ res.writeHead(result.status, {
1976
+ "Content-Type": result.contentType ?? "application/json",
1977
+ });
1978
+ res.end(result.body);
1602
1979
  }
1603
1980
  }
1981
+ catch (err) {
1982
+ respond500(res, err);
1983
+ }
1984
+ })();
1985
+ return true;
1986
+ }
1987
+ if (parsedUrl.pathname === "/connections/salesforce/test" &&
1988
+ req.method === "POST") {
1989
+ void (async () => {
1990
+ try {
1991
+ const { handleSalesforceTest } = await import("./connectors/salesforce.js");
1992
+ const result = await handleSalesforceTest();
1993
+ res.writeHead(result.status, {
1994
+ "Content-Type": result.contentType ?? "application/json",
1995
+ });
1996
+ res.end(result.body);
1997
+ }
1998
+ catch (err) {
1999
+ respond500(res, err);
2000
+ }
2001
+ })();
2002
+ return true;
2003
+ }
2004
+ if (parsedUrl.pathname === "/connections/salesforce" &&
2005
+ req.method === "DELETE") {
2006
+ void (async () => {
2007
+ try {
2008
+ const { handleSalesforceDisconnect } = await import("./connectors/salesforce.js");
2009
+ const result = await handleSalesforceDisconnect();
2010
+ res.writeHead(result.status, {
2011
+ "Content-Type": result.contentType ?? "application/json",
2012
+ });
2013
+ res.end(result.body);
2014
+ }
2015
+ catch (err) {
2016
+ respond500(res, err);
2017
+ }
2018
+ })();
2019
+ return true;
2020
+ }
2021
+ // ── Shopify routes ──────────────────────────────────────────────
2022
+ if (parsedUrl.pathname === "/connections/shopify/connect" &&
2023
+ req.method === "POST") {
2024
+ void dispatchConnectorConnect(req, res, async () => {
2025
+ const m = await import("./connectors/shopify.js");
2026
+ return m.handleShopifyConnect;
2027
+ });
2028
+ return true;
2029
+ }
2030
+ if (parsedUrl.pathname === "/connections/shopify/test" &&
2031
+ req.method === "POST") {
2032
+ void (async () => {
2033
+ try {
2034
+ const { handleShopifyTest } = await import("./connectors/shopify.js");
2035
+ const result = await handleShopifyTest();
2036
+ res.writeHead(result.status, {
2037
+ "Content-Type": result.contentType ?? "application/json",
2038
+ });
2039
+ res.end(result.body);
2040
+ }
2041
+ catch (err) {
2042
+ respond500(res, err);
2043
+ }
2044
+ })();
2045
+ return true;
2046
+ }
2047
+ if (parsedUrl.pathname === "/connections/shopify" &&
2048
+ req.method === "DELETE") {
2049
+ void (async () => {
2050
+ try {
2051
+ const { handleShopifyDisconnect } = await import("./connectors/shopify.js");
2052
+ const result = await handleShopifyDisconnect();
2053
+ res.writeHead(result.status, {
2054
+ "Content-Type": result.contentType ?? "application/json",
2055
+ });
2056
+ res.end(result.body);
2057
+ }
2058
+ catch (err) {
2059
+ respond500(res, err);
2060
+ }
2061
+ })();
2062
+ return true;
2063
+ }
2064
+ // ── Snowflake routes ────────────────────────────────────────────
2065
+ if (parsedUrl.pathname === "/connections/snowflake/connect" &&
2066
+ req.method === "POST") {
2067
+ void dispatchConnectorConnect(req, res, async () => {
2068
+ const m = await import("./connectors/snowflake.js");
2069
+ return m.handleSnowflakeConnect;
2070
+ });
2071
+ return true;
2072
+ }
2073
+ if (parsedUrl.pathname === "/connections/snowflake/test" &&
2074
+ req.method === "POST") {
2075
+ void (async () => {
2076
+ try {
2077
+ const { handleSnowflakeTest } = await import("./connectors/snowflake.js");
2078
+ const result = await handleSnowflakeTest();
2079
+ res.writeHead(result.status, {
2080
+ "Content-Type": result.contentType ?? "application/json",
2081
+ });
2082
+ res.end(result.body);
2083
+ }
2084
+ catch (err) {
2085
+ respond500(res, err);
2086
+ }
2087
+ })();
2088
+ return true;
2089
+ }
2090
+ if (parsedUrl.pathname === "/connections/snowflake" &&
2091
+ req.method === "DELETE") {
2092
+ void (async () => {
2093
+ try {
2094
+ const { handleSnowflakeDisconnect } = await import("./connectors/snowflake.js");
2095
+ const result = await handleSnowflakeDisconnect();
2096
+ res.writeHead(result.status, {
2097
+ "Content-Type": result.contentType ?? "application/json",
2098
+ });
2099
+ res.end(result.body);
2100
+ }
2101
+ catch (err) {
2102
+ respond500(res, err);
2103
+ }
1604
2104
  })();
1605
2105
  return true;
1606
2106
  }