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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/README.bridge.md +14 -14
  2. package/README.md +201 -34
  3. package/deploy/README.md +1 -1
  4. package/deploy/bootstrap-vps.sh +14 -9
  5. package/deploy/deploy-dashboard.sh +25 -1
  6. package/deploy/macos/README.md +153 -0
  7. package/deploy/macos/com.patchwork.bridge.plist.template +54 -0
  8. package/deploy/macos/com.patchwork.tunnel.plist.template +76 -0
  9. package/deploy/macos/install-mac-bridge.sh +244 -0
  10. package/deploy/macos/uninstall-mac-bridge.sh +22 -0
  11. package/dist/activityLog.d.ts +6 -0
  12. package/dist/activityLog.js +63 -26
  13. package/dist/activityLog.js.map +1 -1
  14. package/dist/adapters/claude.js +22 -16
  15. package/dist/adapters/claude.js.map +1 -1
  16. package/dist/adapters/gemini.js +15 -11
  17. package/dist/adapters/gemini.js.map +1 -1
  18. package/dist/adapters/openai.js +9 -9
  19. package/dist/adapters/openai.js.map +1 -1
  20. package/dist/ajv2020.d.ts +25 -0
  21. package/dist/ajv2020.js +33 -0
  22. package/dist/ajv2020.js.map +1 -0
  23. package/dist/analyticsAggregator.js +1 -1
  24. package/dist/analyticsAggregator.js.map +1 -1
  25. package/dist/analyticsConfig.d.ts +29 -0
  26. package/dist/analyticsConfig.js +102 -0
  27. package/dist/analyticsConfig.js.map +1 -0
  28. package/dist/analyticsPrefs.d.ts +38 -2
  29. package/dist/analyticsPrefs.js +148 -23
  30. package/dist/analyticsPrefs.js.map +1 -1
  31. package/dist/analyticsSend.d.ts +17 -1
  32. package/dist/analyticsSend.js +67 -5
  33. package/dist/analyticsSend.js.map +1 -1
  34. package/dist/approvalHttp.d.ts +14 -0
  35. package/dist/approvalHttp.js +212 -9
  36. package/dist/approvalHttp.js.map +1 -1
  37. package/dist/approvalInsights.js +13 -5
  38. package/dist/approvalInsights.js.map +1 -1
  39. package/dist/approvalQueue.d.ts +97 -3
  40. package/dist/approvalQueue.js +193 -19
  41. package/dist/approvalQueue.js.map +1 -1
  42. package/dist/approvalSignals.js +19 -11
  43. package/dist/approvalSignals.js.map +1 -1
  44. package/dist/automation.d.ts +35 -10
  45. package/dist/automation.js +133 -37
  46. package/dist/automation.js.map +1 -1
  47. package/dist/automationSuggestions.js +10 -8
  48. package/dist/automationSuggestions.js.map +1 -1
  49. package/dist/bridge.d.ts +2 -0
  50. package/dist/bridge.js +219 -35
  51. package/dist/bridge.js.map +1 -1
  52. package/dist/bridgeLockDiscovery.d.ts +27 -1
  53. package/dist/bridgeLockDiscovery.js +38 -11
  54. package/dist/bridgeLockDiscovery.js.map +1 -1
  55. package/dist/bridgeToken.js +3 -2
  56. package/dist/bridgeToken.js.map +1 -1
  57. package/dist/claudeDriver.js +23 -8
  58. package/dist/claudeDriver.js.map +1 -1
  59. package/dist/claudeOrchestrator.d.ts +1 -1
  60. package/dist/claudeOrchestrator.js +87 -44
  61. package/dist/claudeOrchestrator.js.map +1 -1
  62. package/dist/commands/analytics.d.ts +8 -0
  63. package/dist/commands/analytics.js +134 -0
  64. package/dist/commands/analytics.js.map +1 -0
  65. package/dist/commands/auditEnv.d.ts +36 -0
  66. package/dist/commands/auditEnv.js +202 -0
  67. package/dist/commands/auditEnv.js.map +1 -0
  68. package/dist/commands/connect.d.ts +47 -0
  69. package/dist/commands/connect.js +419 -0
  70. package/dist/commands/connect.js.map +1 -0
  71. package/dist/commands/dashboard.js +8 -1
  72. package/dist/commands/dashboard.js.map +1 -1
  73. package/dist/commands/doctor.d.ts +35 -0
  74. package/dist/commands/doctor.js +51 -0
  75. package/dist/commands/doctor.js.map +1 -0
  76. package/dist/commands/install.js +3 -0
  77. package/dist/commands/install.js.map +1 -1
  78. package/dist/commands/launchd.js +15 -16
  79. package/dist/commands/launchd.js.map +1 -1
  80. package/dist/commands/patchworkInit.d.ts +5 -0
  81. package/dist/commands/patchworkInit.js +89 -7
  82. package/dist/commands/patchworkInit.js.map +1 -1
  83. package/dist/commands/recipe.d.ts +151 -0
  84. package/dist/commands/recipe.js +649 -9
  85. package/dist/commands/recipe.js.map +1 -1
  86. package/dist/commands/recipeInstall.js +11 -4
  87. package/dist/commands/recipeInstall.js.map +1 -1
  88. package/dist/commands/shadowScan.d.ts +34 -0
  89. package/dist/commands/shadowScan.js +142 -0
  90. package/dist/commands/shadowScan.js.map +1 -0
  91. package/dist/commands/task.d.ts +25 -0
  92. package/dist/commands/task.js +62 -42
  93. package/dist/commands/task.js.map +1 -1
  94. package/dist/commands/tools.d.ts +20 -1
  95. package/dist/commands/tools.js +112 -3
  96. package/dist/commands/tools.js.map +1 -1
  97. package/dist/commands/tracesExport.d.ts +15 -1
  98. package/dist/commands/tracesExport.js +39 -5
  99. package/dist/commands/tracesExport.js.map +1 -1
  100. package/dist/commands/tracesImport.js +21 -4
  101. package/dist/commands/tracesImport.js.map +1 -1
  102. package/dist/commitIssueLinkLog.d.ts +16 -0
  103. package/dist/commitIssueLinkLog.js +110 -24
  104. package/dist/commitIssueLinkLog.js.map +1 -1
  105. package/dist/companions/registry.js +15 -7
  106. package/dist/companions/registry.js.map +1 -1
  107. package/dist/config.d.ts +47 -3
  108. package/dist/config.js +111 -21
  109. package/dist/config.js.map +1 -1
  110. package/dist/connectorRoutes.js +1422 -57
  111. package/dist/connectorRoutes.js.map +1 -1
  112. package/dist/connectors/airtable.d.ts +230 -0
  113. package/dist/connectors/airtable.js +700 -0
  114. package/dist/connectors/airtable.js.map +1 -0
  115. package/dist/connectors/asana.js +13 -9
  116. package/dist/connectors/asana.js.map +1 -1
  117. package/dist/connectors/baseConnector.js +25 -3
  118. package/dist/connectors/baseConnector.js.map +1 -1
  119. package/dist/connectors/caldiy.d.ts +137 -0
  120. package/dist/connectors/caldiy.js +424 -0
  121. package/dist/connectors/caldiy.js.map +1 -0
  122. package/dist/connectors/circleci.d.ts +162 -0
  123. package/dist/connectors/circleci.js +576 -0
  124. package/dist/connectors/circleci.js.map +1 -0
  125. package/dist/connectors/cloudflare.d.ts +132 -0
  126. package/dist/connectors/cloudflare.js +622 -0
  127. package/dist/connectors/cloudflare.js.map +1 -0
  128. package/dist/connectors/confluence.js +35 -0
  129. package/dist/connectors/confluence.js.map +1 -1
  130. package/dist/connectors/connectorRedirectUri.d.ts +30 -0
  131. package/dist/connectors/connectorRedirectUri.js +38 -0
  132. package/dist/connectors/connectorRedirectUri.js.map +1 -0
  133. package/dist/connectors/connectorRegistry.d.ts +60 -0
  134. package/dist/connectors/connectorRegistry.js +354 -0
  135. package/dist/connectors/connectorRegistry.js.map +1 -0
  136. package/dist/connectors/datadog.js +41 -5
  137. package/dist/connectors/datadog.js.map +1 -1
  138. package/dist/connectors/discord.js +14 -10
  139. package/dist/connectors/discord.js.map +1 -1
  140. package/dist/connectors/elasticsearch.d.ts +141 -0
  141. package/dist/connectors/elasticsearch.js +601 -0
  142. package/dist/connectors/elasticsearch.js.map +1 -0
  143. package/dist/connectors/figma.d.ts +130 -0
  144. package/dist/connectors/figma.js +387 -0
  145. package/dist/connectors/figma.js.map +1 -0
  146. package/dist/connectors/github.d.ts +17 -0
  147. package/dist/connectors/github.js +53 -2
  148. package/dist/connectors/github.js.map +1 -1
  149. package/dist/connectors/gitlab.js +12 -6
  150. package/dist/connectors/gitlab.js.map +1 -1
  151. package/dist/connectors/gmail.js +72 -21
  152. package/dist/connectors/gmail.js.map +1 -1
  153. package/dist/connectors/googleCalendar.js +8 -8
  154. package/dist/connectors/googleCalendar.js.map +1 -1
  155. package/dist/connectors/googleDocs.d.ts +103 -0
  156. package/dist/connectors/googleDocs.js +409 -0
  157. package/dist/connectors/googleDocs.js.map +1 -0
  158. package/dist/connectors/googleDrive.d.ts +12 -0
  159. package/dist/connectors/googleDrive.js +35 -8
  160. package/dist/connectors/googleDrive.js.map +1 -1
  161. package/dist/connectors/grafana.d.ts +133 -0
  162. package/dist/connectors/grafana.js +478 -0
  163. package/dist/connectors/grafana.js.map +1 -0
  164. package/dist/connectors/jira.d.ts +25 -0
  165. package/dist/connectors/jira.js +234 -3
  166. package/dist/connectors/jira.js.map +1 -1
  167. package/dist/connectors/linear.js +1 -1
  168. package/dist/connectors/linear.js.map +1 -1
  169. package/dist/connectors/mcpClient.js +37 -23
  170. package/dist/connectors/mcpClient.js.map +1 -1
  171. package/dist/connectors/mcpOAuth.js +78 -16
  172. package/dist/connectors/mcpOAuth.js.map +1 -1
  173. package/dist/connectors/monday.d.ts +217 -0
  174. package/dist/connectors/monday.js +655 -0
  175. package/dist/connectors/monday.js.map +1 -0
  176. package/dist/connectors/mongodb.d.ts +139 -0
  177. package/dist/connectors/mongodb.js +455 -0
  178. package/dist/connectors/mongodb.js.map +1 -0
  179. package/dist/connectors/notion.d.ts +1 -1
  180. package/dist/connectors/notion.js +13 -4
  181. package/dist/connectors/notion.js.map +1 -1
  182. package/dist/connectors/oauthStateStore.d.ts +20 -0
  183. package/dist/connectors/oauthStateStore.js +94 -4
  184. package/dist/connectors/oauthStateStore.js.map +1 -1
  185. package/dist/connectors/obsidian.d.ts +83 -0
  186. package/dist/connectors/obsidian.js +441 -0
  187. package/dist/connectors/obsidian.js.map +1 -0
  188. package/dist/connectors/paystack.d.ts +159 -0
  189. package/dist/connectors/paystack.js +607 -0
  190. package/dist/connectors/paystack.js.map +1 -0
  191. package/dist/connectors/pipedrive.d.ts +189 -0
  192. package/dist/connectors/pipedrive.js +559 -0
  193. package/dist/connectors/pipedrive.js.map +1 -0
  194. package/dist/connectors/postgres.d.ts +127 -0
  195. package/dist/connectors/postgres.js +512 -0
  196. package/dist/connectors/postgres.js.map +1 -0
  197. package/dist/connectors/posthog.d.ts +119 -0
  198. package/dist/connectors/posthog.js +479 -0
  199. package/dist/connectors/posthog.js.map +1 -0
  200. package/dist/connectors/redis.d.ts +140 -0
  201. package/dist/connectors/redis.js +579 -0
  202. package/dist/connectors/redis.js.map +1 -0
  203. package/dist/connectors/resend.d.ts +131 -0
  204. package/dist/connectors/resend.js +529 -0
  205. package/dist/connectors/resend.js.map +1 -0
  206. package/dist/connectors/salesforce.d.ts +136 -0
  207. package/dist/connectors/salesforce.js +603 -0
  208. package/dist/connectors/salesforce.js.map +1 -0
  209. package/dist/connectors/secrets.d.ts +51 -0
  210. package/dist/connectors/secrets.js +102 -0
  211. package/dist/connectors/secrets.js.map +1 -0
  212. package/dist/connectors/sendgrid.d.ts +102 -0
  213. package/dist/connectors/sendgrid.js +423 -0
  214. package/dist/connectors/sendgrid.js.map +1 -0
  215. package/dist/connectors/shopify.d.ts +145 -0
  216. package/dist/connectors/shopify.js +502 -0
  217. package/dist/connectors/shopify.js.map +1 -0
  218. package/dist/connectors/slack.d.ts +1 -1
  219. package/dist/connectors/slack.js +61 -9
  220. package/dist/connectors/slack.js.map +1 -1
  221. package/dist/connectors/snowflake.d.ts +119 -0
  222. package/dist/connectors/snowflake.js +633 -0
  223. package/dist/connectors/snowflake.js.map +1 -0
  224. package/dist/connectors/supabase.d.ts +92 -0
  225. package/dist/connectors/supabase.js +630 -0
  226. package/dist/connectors/supabase.js.map +1 -0
  227. package/dist/connectors/todoist.d.ts +117 -0
  228. package/dist/connectors/todoist.js +485 -0
  229. package/dist/connectors/todoist.js.map +1 -0
  230. package/dist/connectors/tokenStorage.js +56 -14
  231. package/dist/connectors/tokenStorage.js.map +1 -1
  232. package/dist/connectors/twilio.d.ts +118 -0
  233. package/dist/connectors/twilio.js +475 -0
  234. package/dist/connectors/twilio.js.map +1 -0
  235. package/dist/connectors/vercel.d.ts +110 -0
  236. package/dist/connectors/vercel.js +479 -0
  237. package/dist/connectors/vercel.js.map +1 -0
  238. package/dist/connectors/webflow.d.ts +118 -0
  239. package/dist/connectors/webflow.js +393 -0
  240. package/dist/connectors/webflow.js.map +1 -0
  241. package/dist/connectors/woocommerce.d.ts +220 -0
  242. package/dist/connectors/woocommerce.js +464 -0
  243. package/dist/connectors/woocommerce.js.map +1 -0
  244. package/dist/crypto.js +7 -2
  245. package/dist/crypto.js.map +1 -1
  246. package/dist/decisionReplay.d.ts +8 -6
  247. package/dist/decisionReplay.js +50 -17
  248. package/dist/decisionReplay.js.map +1 -1
  249. package/dist/decisionTraceLog.d.ts +28 -0
  250. package/dist/decisionTraceLog.js +156 -29
  251. package/dist/decisionTraceLog.js.map +1 -1
  252. package/dist/drivers/claude/api.js +33 -9
  253. package/dist/drivers/claude/api.js.map +1 -1
  254. package/dist/drivers/claude/envSanitizer.d.ts +0 -6
  255. package/dist/drivers/claude/envSanitizer.js +17 -2
  256. package/dist/drivers/claude/envSanitizer.js.map +1 -1
  257. package/dist/drivers/claude/streamParser.js +5 -4
  258. package/dist/drivers/claude/streamParser.js.map +1 -1
  259. package/dist/drivers/claude/subprocess.js +69 -16
  260. package/dist/drivers/claude/subprocess.js.map +1 -1
  261. package/dist/drivers/gemini/index.d.ts +22 -0
  262. package/dist/drivers/gemini/index.js +256 -129
  263. package/dist/drivers/gemini/index.js.map +1 -1
  264. package/dist/drivers/local/index.d.ts +2 -0
  265. package/dist/drivers/local/index.js +12 -0
  266. package/dist/drivers/local/index.js.map +1 -1
  267. package/dist/drivers/openai/index.js +30 -2
  268. package/dist/drivers/openai/index.js.map +1 -1
  269. package/dist/extensionClient.d.ts +37 -4
  270. package/dist/extensionClient.js +58 -16
  271. package/dist/extensionClient.js.map +1 -1
  272. package/dist/featureFlags.d.ts +91 -0
  273. package/dist/featureFlags.js +174 -3
  274. package/dist/featureFlags.js.map +1 -1
  275. package/dist/fileLock.js +21 -12
  276. package/dist/fileLock.js.map +1 -1
  277. package/dist/fileLockSync.d.ts +67 -0
  278. package/dist/fileLockSync.js +126 -0
  279. package/dist/fileLockSync.js.map +1 -0
  280. package/dist/fp/activityAnalytics.js +26 -12
  281. package/dist/fp/activityAnalytics.js.map +1 -1
  282. package/dist/fp/automationInterpreter.d.ts +15 -1
  283. package/dist/fp/automationInterpreter.js +267 -87
  284. package/dist/fp/automationInterpreter.js.map +1 -1
  285. package/dist/fp/automationProgram.d.ts +30 -0
  286. package/dist/fp/automationProgram.js.map +1 -1
  287. package/dist/fp/automationState.d.ts +24 -5
  288. package/dist/fp/automationState.js +56 -9
  289. package/dist/fp/automationState.js.map +1 -1
  290. package/dist/fp/automationUtils.js +1 -1
  291. package/dist/fp/automationUtils.js.map +1 -1
  292. package/dist/fp/commandDescription.js +7 -1
  293. package/dist/fp/commandDescription.js.map +1 -1
  294. package/dist/fp/extensionSnapshot.js +8 -2
  295. package/dist/fp/extensionSnapshot.js.map +1 -1
  296. package/dist/fp/interpreterContext.d.ts +66 -1
  297. package/dist/fp/interpreterContext.js +91 -1
  298. package/dist/fp/interpreterContext.js.map +1 -1
  299. package/dist/fp/policyParser.js +34 -2
  300. package/dist/fp/policyParser.js.map +1 -1
  301. package/dist/fsWatchWithFallback.d.ts +36 -0
  302. package/dist/fsWatchWithFallback.js +128 -0
  303. package/dist/fsWatchWithFallback.js.map +1 -0
  304. package/dist/haltPushDispatch.d.ts +33 -0
  305. package/dist/haltPushDispatch.js +103 -0
  306. package/dist/haltPushDispatch.js.map +1 -0
  307. package/dist/httpBodyValidation.d.ts +41 -0
  308. package/dist/httpBodyValidation.js +45 -0
  309. package/dist/httpBodyValidation.js.map +1 -0
  310. package/dist/inboxRoutes.d.ts +22 -0
  311. package/dist/inboxRoutes.js +61 -1
  312. package/dist/inboxRoutes.js.map +1 -1
  313. package/dist/index.js +1206 -158
  314. package/dist/index.js.map +1 -1
  315. package/dist/installGuard.js +6 -2
  316. package/dist/installGuard.js.map +1 -1
  317. package/dist/localEndpointGuard.d.ts +25 -0
  318. package/dist/localEndpointGuard.js +101 -0
  319. package/dist/localEndpointGuard.js.map +1 -0
  320. package/dist/lockfile.js +31 -4
  321. package/dist/lockfile.js.map +1 -1
  322. package/dist/oauth.d.ts +9 -0
  323. package/dist/oauth.js +33 -0
  324. package/dist/oauth.js.map +1 -1
  325. package/dist/oauthRoutes.d.ts +1 -1
  326. package/dist/oauthRoutes.js +5 -3
  327. package/dist/oauthRoutes.js.map +1 -1
  328. package/dist/orchestrator/childBridgeClient.d.ts +5 -0
  329. package/dist/orchestrator/childBridgeClient.js +28 -1
  330. package/dist/orchestrator/childBridgeClient.js.map +1 -1
  331. package/dist/orchestrator/childBridgeRegistry.js +29 -11
  332. package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
  333. package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
  334. package/dist/orchestrator/orchestratorBridge.js +70 -9
  335. package/dist/orchestrator/orchestratorBridge.js.map +1 -1
  336. package/dist/patchworkConfig.d.ts +44 -1
  337. package/dist/patchworkConfig.js +28 -3
  338. package/dist/patchworkConfig.js.map +1 -1
  339. package/dist/pluginLoader.js +10 -1
  340. package/dist/pluginLoader.js.map +1 -1
  341. package/dist/pluginWatcher.js +12 -14
  342. package/dist/pluginWatcher.js.map +1 -1
  343. package/dist/preToolUseHook.js +3 -2
  344. package/dist/preToolUseHook.js.map +1 -1
  345. package/dist/processTree.d.ts +34 -0
  346. package/dist/processTree.js +105 -0
  347. package/dist/processTree.js.map +1 -0
  348. package/dist/prompts.js +3 -3
  349. package/dist/prompts.js.map +1 -1
  350. package/dist/recipeOrchestration.d.ts +9 -0
  351. package/dist/recipeOrchestration.js +341 -24
  352. package/dist/recipeOrchestration.js.map +1 -1
  353. package/dist/recipeRoutes.d.ts +58 -2
  354. package/dist/recipeRoutes.js +744 -115
  355. package/dist/recipeRoutes.js.map +1 -1
  356. package/dist/recipes/RecipeOrchestrator.d.ts +2 -0
  357. package/dist/recipes/RecipeOrchestrator.js +6 -1
  358. package/dist/recipes/RecipeOrchestrator.js.map +1 -1
  359. package/dist/recipes/agentExecutor.d.ts +25 -5
  360. package/dist/recipes/agentExecutor.js.map +1 -1
  361. package/dist/recipes/chainedRunner.d.ts +2 -0
  362. package/dist/recipes/chainedRunner.js +156 -9
  363. package/dist/recipes/chainedRunner.js.map +1 -1
  364. package/dist/recipes/compiler.js +9 -5
  365. package/dist/recipes/compiler.js.map +1 -1
  366. package/dist/recipes/connectorPreflight.d.ts +66 -0
  367. package/dist/recipes/connectorPreflight.js +169 -0
  368. package/dist/recipes/connectorPreflight.js.map +1 -0
  369. package/dist/recipes/dependencyGraph.d.ts +9 -0
  370. package/dist/recipes/dependencyGraph.js +32 -7
  371. package/dist/recipes/dependencyGraph.js.map +1 -1
  372. package/dist/recipes/githubInstallSource.d.ts +135 -0
  373. package/dist/recipes/githubInstallSource.js +236 -0
  374. package/dist/recipes/githubInstallSource.js.map +1 -0
  375. package/dist/recipes/haltCategory.d.ts +119 -0
  376. package/dist/recipes/haltCategory.js +188 -0
  377. package/dist/recipes/haltCategory.js.map +1 -0
  378. package/dist/recipes/idempotencyKey.d.ts +154 -0
  379. package/dist/recipes/idempotencyKey.js +375 -0
  380. package/dist/recipes/idempotencyKey.js.map +1 -0
  381. package/dist/recipes/installer.js +58 -3
  382. package/dist/recipes/installer.js.map +1 -1
  383. package/dist/recipes/judgeSummary.d.ts +50 -0
  384. package/dist/recipes/judgeSummary.js +47 -0
  385. package/dist/recipes/judgeSummary.js.map +1 -0
  386. package/dist/recipes/judgeVerdict.d.ts +48 -0
  387. package/dist/recipes/judgeVerdict.js +174 -0
  388. package/dist/recipes/judgeVerdict.js.map +1 -0
  389. package/dist/recipes/migrations/index.d.ts +9 -0
  390. package/dist/recipes/migrations/index.js +133 -0
  391. package/dist/recipes/migrations/index.js.map +1 -1
  392. package/dist/recipes/names.d.ts +20 -0
  393. package/dist/recipes/names.js +25 -0
  394. package/dist/recipes/names.js.map +1 -1
  395. package/dist/recipes/parser.js +116 -6
  396. package/dist/recipes/parser.js.map +1 -1
  397. package/dist/recipes/replayRun.js +1 -1
  398. package/dist/recipes/replayRun.js.map +1 -1
  399. package/dist/recipes/runBudget.d.ts +70 -0
  400. package/dist/recipes/runBudget.js +109 -0
  401. package/dist/recipes/runBudget.js.map +1 -0
  402. package/dist/recipes/scheduler.d.ts +30 -0
  403. package/dist/recipes/scheduler.js +69 -19
  404. package/dist/recipes/scheduler.js.map +1 -1
  405. package/dist/recipes/schema.d.ts +65 -2
  406. package/dist/recipes/schemaGenerator.js +119 -7
  407. package/dist/recipes/schemaGenerator.js.map +1 -1
  408. package/dist/recipes/stepObservation.js +9 -0
  409. package/dist/recipes/stepObservation.js.map +1 -1
  410. package/dist/recipes/toolRegistry.js +33 -7
  411. package/dist/recipes/toolRegistry.js.map +1 -1
  412. package/dist/recipes/tools/airtable.d.ts +15 -0
  413. package/dist/recipes/tools/airtable.js +239 -0
  414. package/dist/recipes/tools/airtable.js.map +1 -0
  415. package/dist/recipes/tools/fanOut.d.ts +20 -0
  416. package/dist/recipes/tools/fanOut.js +199 -0
  417. package/dist/recipes/tools/fanOut.js.map +1 -0
  418. package/dist/recipes/tools/file.js +5 -2
  419. package/dist/recipes/tools/file.js.map +1 -1
  420. package/dist/recipes/tools/github.d.ts +1 -1
  421. package/dist/recipes/tools/github.js +75 -1
  422. package/dist/recipes/tools/github.js.map +1 -1
  423. package/dist/recipes/tools/gmail.js +27 -5
  424. package/dist/recipes/tools/gmail.js.map +1 -1
  425. package/dist/recipes/tools/googleDrive.js +64 -0
  426. package/dist/recipes/tools/googleDrive.js.map +1 -1
  427. package/dist/recipes/tools/http.d.ts +10 -0
  428. package/dist/recipes/tools/http.js +176 -0
  429. package/dist/recipes/tools/http.js.map +1 -0
  430. package/dist/recipes/tools/index.d.ts +7 -0
  431. package/dist/recipes/tools/index.js +7 -0
  432. package/dist/recipes/tools/index.js.map +1 -1
  433. package/dist/recipes/tools/resend.d.ts +8 -0
  434. package/dist/recipes/tools/resend.js +152 -0
  435. package/dist/recipes/tools/resend.js.map +1 -0
  436. package/dist/recipes/tools/sendgrid.d.ts +9 -0
  437. package/dist/recipes/tools/sendgrid.js +174 -0
  438. package/dist/recipes/tools/sendgrid.js.map +1 -0
  439. package/dist/recipes/tools/slack.js +1 -1
  440. package/dist/recipes/tools/twilio.d.ts +11 -0
  441. package/dist/recipes/tools/twilio.js +179 -0
  442. package/dist/recipes/tools/twilio.js.map +1 -0
  443. package/dist/recipes/tools/vercel.d.ts +9 -0
  444. package/dist/recipes/tools/vercel.js +145 -0
  445. package/dist/recipes/tools/vercel.js.map +1 -0
  446. package/dist/recipes/validation.d.ts +17 -0
  447. package/dist/recipes/validation.js +141 -11
  448. package/dist/recipes/validation.js.map +1 -1
  449. package/dist/recipes/workspaceRoot.d.ts +37 -0
  450. package/dist/recipes/workspaceRoot.js +73 -0
  451. package/dist/recipes/workspaceRoot.js.map +1 -0
  452. package/dist/recipes/yamlPositions.d.ts +56 -0
  453. package/dist/recipes/yamlPositions.js +183 -0
  454. package/dist/recipes/yamlPositions.js.map +1 -0
  455. package/dist/recipes/yamlRunner.d.ts +185 -8
  456. package/dist/recipes/yamlRunner.js +967 -224
  457. package/dist/recipes/yamlRunner.js.map +1 -1
  458. package/dist/recipesHttp.d.ts +19 -3
  459. package/dist/recipesHttp.js +67 -11
  460. package/dist/recipesHttp.js.map +1 -1
  461. package/dist/resources.js +21 -13
  462. package/dist/resources.js.map +1 -1
  463. package/dist/runLog.d.ts +58 -5
  464. package/dist/runLog.js +98 -21
  465. package/dist/runLog.js.map +1 -1
  466. package/dist/sanitizeParsedJson.d.ts +39 -0
  467. package/dist/sanitizeParsedJson.js +55 -0
  468. package/dist/sanitizeParsedJson.js.map +1 -0
  469. package/dist/schemas/recipe.v1.json +887 -198
  470. package/dist/server.d.ts +160 -3
  471. package/dist/server.js +1099 -122
  472. package/dist/server.js.map +1 -1
  473. package/dist/sessionCheckpoint.d.ts +8 -0
  474. package/dist/sessionCheckpoint.js +33 -3
  475. package/dist/sessionCheckpoint.js.map +1 -1
  476. package/dist/ssrfGuard.d.ts +16 -0
  477. package/dist/ssrfGuard.js +87 -4
  478. package/dist/ssrfGuard.js.map +1 -1
  479. package/dist/streamableHttp.d.ts +9 -4
  480. package/dist/streamableHttp.js +76 -20
  481. package/dist/streamableHttp.js.map +1 -1
  482. package/dist/telemetry.js +37 -19
  483. package/dist/telemetry.js.map +1 -1
  484. package/dist/testing/shadowRun.d.ts +52 -0
  485. package/dist/testing/shadowRun.js +71 -0
  486. package/dist/testing/shadowRun.js.map +1 -0
  487. package/dist/tools/batchLsp.d.ts +3 -0
  488. package/dist/tools/bridgeDoctor.d.ts +11 -0
  489. package/dist/tools/bridgeDoctor.js +48 -2
  490. package/dist/tools/bridgeDoctor.js.map +1 -1
  491. package/dist/tools/bridgeStatus.d.ts +0 -12
  492. package/dist/tools/bridgeStatus.js +2 -28
  493. package/dist/tools/bridgeStatus.js.map +1 -1
  494. package/dist/tools/cancelClaudeTask.d.ts +1 -0
  495. package/dist/tools/clipboard.d.ts +2 -0
  496. package/dist/tools/closeTabs.d.ts +1 -0
  497. package/dist/tools/codeLens.d.ts +1 -0
  498. package/dist/tools/createIssueFromAIComment.d.ts +1 -0
  499. package/dist/tools/ctxGetTaskContext.d.ts +9 -0
  500. package/dist/tools/ctxGetTaskContext.js +50 -2
  501. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  502. package/dist/tools/ctxQueryTraces.js +32 -24
  503. package/dist/tools/ctxQueryTraces.js.map +1 -1
  504. package/dist/tools/ctxSaveTrace.d.ts +1 -0
  505. package/dist/tools/debug.d.ts +4 -0
  506. package/dist/tools/decorations.d.ts +2 -0
  507. package/dist/tools/detectUnusedCode.js +9 -7
  508. package/dist/tools/detectUnusedCode.js.map +1 -1
  509. package/dist/tools/documentLinks.d.ts +1 -0
  510. package/dist/tools/editText.d.ts +1 -0
  511. package/dist/tools/editText.js +2 -1
  512. package/dist/tools/editText.js.map +1 -1
  513. package/dist/tools/enrichCommit.d.ts +1 -0
  514. package/dist/tools/enrichStackTrace.js +11 -5
  515. package/dist/tools/enrichStackTrace.js.map +1 -1
  516. package/dist/tools/explainDiagnostic.d.ts +1 -0
  517. package/dist/tools/explainSymbol.d.ts +1 -0
  518. package/dist/tools/fileOperations.d.ts +3 -0
  519. package/dist/tools/fileOperations.js +2 -1
  520. package/dist/tools/fileOperations.js.map +1 -1
  521. package/dist/tools/fileWatcher.d.ts +2 -0
  522. package/dist/tools/fileWatcher.js +8 -2
  523. package/dist/tools/fileWatcher.js.map +1 -1
  524. package/dist/tools/findFiles.d.ts +1 -0
  525. package/dist/tools/fixAllLintErrors.d.ts +1 -0
  526. package/dist/tools/fixAllLintErrors.js +10 -5
  527. package/dist/tools/fixAllLintErrors.js.map +1 -1
  528. package/dist/tools/foldingRanges.d.ts +1 -0
  529. package/dist/tools/formatDocument.d.ts +1 -0
  530. package/dist/tools/formatDocument.js +10 -5
  531. package/dist/tools/formatDocument.js.map +1 -1
  532. package/dist/tools/generateTests.d.ts +1 -0
  533. package/dist/tools/getAIComments.d.ts +1 -0
  534. package/dist/tools/getAnalyticsReport.js +5 -1
  535. package/dist/tools/getAnalyticsReport.js.map +1 -1
  536. package/dist/tools/getBufferContent.d.ts +1 -0
  537. package/dist/tools/getChangeImpact.d.ts +1 -0
  538. package/dist/tools/getChangeImpact.js +23 -14
  539. package/dist/tools/getChangeImpact.js.map +1 -1
  540. package/dist/tools/getClaudeTaskStatus.d.ts +1 -0
  541. package/dist/tools/getCodeCoverage.d.ts +1 -0
  542. package/dist/tools/getCodeCoverage.js +32 -14
  543. package/dist/tools/getCodeCoverage.js.map +1 -1
  544. package/dist/tools/getCommitsForIssue.d.ts +1 -0
  545. package/dist/tools/getDebugState.d.ts +1 -0
  546. package/dist/tools/getDiagnostics.js +32 -29
  547. package/dist/tools/getDiagnostics.js.map +1 -1
  548. package/dist/tools/getDiffFromHandoff.js +8 -2
  549. package/dist/tools/getDiffFromHandoff.js.map +1 -1
  550. package/dist/tools/getDocumentSymbols.d.ts +1 -0
  551. package/dist/tools/getGitHotspots.d.ts +1 -0
  552. package/dist/tools/getGitStatus.js +6 -1
  553. package/dist/tools/getGitStatus.js.map +1 -1
  554. package/dist/tools/getImportedSignatures.d.ts +1 -0
  555. package/dist/tools/getImportedSignatures.js +18 -14
  556. package/dist/tools/getImportedSignatures.js.map +1 -1
  557. package/dist/tools/getPRTemplate.d.ts +1 -0
  558. package/dist/tools/getProjectContext.js +23 -10
  559. package/dist/tools/getProjectContext.js.map +1 -1
  560. package/dist/tools/getSymbolHistory.d.ts +1 -0
  561. package/dist/tools/getToolCapabilities.d.ts +10 -5
  562. package/dist/tools/getToolCapabilities.js +116 -204
  563. package/dist/tools/getToolCapabilities.js.map +1 -1
  564. package/dist/tools/getTypeSignature.d.ts +1 -0
  565. package/dist/tools/getWorkspaceSettings.d.ts +1 -0
  566. package/dist/tools/gitWrite.d.ts +11 -0
  567. package/dist/tools/github/actions.d.ts +2 -0
  568. package/dist/tools/github/composite.d.ts +4 -1
  569. package/dist/tools/github/composite.js +7 -7
  570. package/dist/tools/github/composite.js.map +1 -1
  571. package/dist/tools/github/issues.d.ts +4 -0
  572. package/dist/tools/github/pr.d.ts +13 -6
  573. package/dist/tools/github/pr.js +18 -11
  574. package/dist/tools/github/pr.js.map +1 -1
  575. package/dist/tools/handoffNote.d.ts +1 -0
  576. package/dist/tools/handoffNote.js +2 -1
  577. package/dist/tools/handoffNote.js.map +1 -1
  578. package/dist/tools/headless/lspClient.js +3 -0
  579. package/dist/tools/headless/lspClient.js.map +1 -1
  580. package/dist/tools/hoverAtCursor.d.ts +1 -0
  581. package/dist/tools/httpClient.d.ts +2 -0
  582. package/dist/tools/httpClient.js +38 -71
  583. package/dist/tools/httpClient.js.map +1 -1
  584. package/dist/tools/index.js +14 -10
  585. package/dist/tools/index.js.map +1 -1
  586. package/dist/tools/inlayHints.d.ts +1 -0
  587. package/dist/tools/launchQuickTask.d.ts +1 -0
  588. package/dist/tools/listClaudeTasks.d.ts +1 -0
  589. package/dist/tools/listClaudeTasks.js +10 -8
  590. package/dist/tools/listClaudeTasks.js.map +1 -1
  591. package/dist/tools/listTerminals.d.ts +1 -0
  592. package/dist/tools/lsp.d.ts +15 -0
  593. package/dist/tools/lsp.js +17 -0
  594. package/dist/tools/lsp.js.map +1 -1
  595. package/dist/tools/navigateToSymbolByName.d.ts +1 -0
  596. package/dist/tools/openDiff.d.ts +1 -0
  597. package/dist/tools/openDiff.js +4 -1
  598. package/dist/tools/openDiff.js.map +1 -1
  599. package/dist/tools/openFile.d.ts +1 -0
  600. package/dist/tools/openFile.js +4 -1
  601. package/dist/tools/openFile.js.map +1 -1
  602. package/dist/tools/openInBrowser.js +6 -1
  603. package/dist/tools/openInBrowser.js.map +1 -1
  604. package/dist/tools/organizeImports.d.ts +1 -0
  605. package/dist/tools/organizeImports.js +5 -3
  606. package/dist/tools/organizeImports.js.map +1 -1
  607. package/dist/tools/performanceReport.js +5 -3
  608. package/dist/tools/performanceReport.js.map +1 -1
  609. package/dist/tools/planPersistence.d.ts +3 -0
  610. package/dist/tools/planPersistence.js +4 -1
  611. package/dist/tools/planPersistence.js.map +1 -1
  612. package/dist/tools/previewEdit.d.ts +1 -0
  613. package/dist/tools/previewEdit.js +31 -5
  614. package/dist/tools/previewEdit.js.map +1 -1
  615. package/dist/tools/recentTracesDigest.js +54 -11
  616. package/dist/tools/recentTracesDigest.js.map +1 -1
  617. package/dist/tools/refactorAnalyze.d.ts +1 -0
  618. package/dist/tools/refactorExtractFunction.js +4 -1
  619. package/dist/tools/refactorExtractFunction.js.map +1 -1
  620. package/dist/tools/refactorPreview.d.ts +1 -0
  621. package/dist/tools/refactorPreview.js +10 -2
  622. package/dist/tools/refactorPreview.js.map +1 -1
  623. package/dist/tools/replaceBlock.d.ts +1 -0
  624. package/dist/tools/replaceBlock.js +2 -1
  625. package/dist/tools/replaceBlock.js.map +1 -1
  626. package/dist/tools/resumeClaudeTask.d.ts +1 -0
  627. package/dist/tools/runClaudeTask.d.ts +1 -0
  628. package/dist/tools/runTests.js +15 -4
  629. package/dist/tools/runTests.js.map +1 -1
  630. package/dist/tools/screenshot.d.ts +1 -0
  631. package/dist/tools/screenshotAndAnnotate.js +6 -2
  632. package/dist/tools/screenshotAndAnnotate.js.map +1 -1
  633. package/dist/tools/searchAndReplace.d.ts +1 -0
  634. package/dist/tools/searchAndReplace.js +21 -12
  635. package/dist/tools/searchAndReplace.js.map +1 -1
  636. package/dist/tools/searchTools.d.ts +26 -0
  637. package/dist/tools/searchTools.js +62 -21
  638. package/dist/tools/searchTools.js.map +1 -1
  639. package/dist/tools/searchWorkspace.d.ts +1 -0
  640. package/dist/tools/selectionRanges.d.ts +1 -0
  641. package/dist/tools/semanticTokens.d.ts +1 -0
  642. package/dist/tools/signatureHelp.d.ts +1 -0
  643. package/dist/tools/spawnWorkspace.js +15 -7
  644. package/dist/tools/spawnWorkspace.js.map +1 -1
  645. package/dist/tools/terminal.d.ts +6 -0
  646. package/dist/tools/testRunners/pytest.js +6 -2
  647. package/dist/tools/testRunners/pytest.js.map +1 -1
  648. package/dist/tools/testRunners/vitestJest.js +3 -1
  649. package/dist/tools/testRunners/vitestJest.js.map +1 -1
  650. package/dist/tools/testTraceToSource.d.ts +1 -0
  651. package/dist/tools/transaction.d.ts +13 -1
  652. package/dist/tools/transaction.js +63 -5
  653. package/dist/tools/transaction.js.map +1 -1
  654. package/dist/tools/typeHierarchy.d.ts +1 -0
  655. package/dist/tools/utils.d.ts +33 -0
  656. package/dist/tools/utils.js +122 -18
  657. package/dist/tools/utils.js.map +1 -1
  658. package/dist/tools/vscodeCommands.d.ts +2 -0
  659. package/dist/tools/vscodeTasks.d.ts +2 -0
  660. package/dist/tools/workspaceSettings.d.ts +1 -0
  661. package/dist/transport.d.ts +3 -1
  662. package/dist/transport.js +126 -52
  663. package/dist/transport.js.map +1 -1
  664. package/dist/winShim.d.ts +34 -0
  665. package/dist/winShim.js +94 -0
  666. package/dist/winShim.js.map +1 -0
  667. package/dist/wireHaltPushDispatch.d.ts +38 -0
  668. package/dist/wireHaltPushDispatch.js +71 -0
  669. package/dist/wireHaltPushDispatch.js.map +1 -0
  670. package/dist/writeFileAtomic.d.ts +23 -0
  671. package/dist/writeFileAtomic.js +121 -0
  672. package/dist/writeFileAtomic.js.map +1 -0
  673. package/package.json +23 -7
  674. package/scripts/postinstall.mjs +42 -2
  675. package/scripts/smoke/run-all.mjs +213 -0
  676. package/scripts/start-all.mjs +572 -0
  677. package/scripts/start-all.ps1 +209 -0
  678. package/scripts/start-all.sh +73 -17
  679. package/scripts/start-orchestrator.ps1 +158 -0
  680. package/scripts/start-remote.mjs +122 -0
  681. package/templates/automation-policies/recipe-authoring.json +1 -1
  682. package/templates/automation-policies/security-first.json +1 -1
  683. package/templates/automation-policies/strict-lint.json +1 -1
  684. package/templates/automation-policies/test-driven.json +1 -1
  685. package/templates/automation-policy.example.json +1 -1
  686. package/templates/co.patchwork-os.bridge.plist +2 -2
  687. package/templates/recipes/approval-queue-ui-test.yaml +1 -1
  688. package/templates/recipes/ctx-loop-test.yaml +1 -1
  689. package/templates/recipes/fix-errors-on-save.yaml +71 -0
  690. package/templates/recipes/morning-brief.yaml +5 -2
  691. package/templates/recipes/project-health-check.yaml +4 -1
  692. package/templates/recipes/sentry-to-linear.yaml +72 -38
  693. package/templates/recipes/webhook/apple-watch-health-log.yaml +145 -0
  694. package/templates/recipes/webhook/customer-escalation.yaml +8 -9
  695. package/templates/recipes/webhook/meeting-prep.yaml +11 -5
  696. package/dist/commands/marketplace.d.ts +0 -16
  697. package/dist/commands/marketplace.js +0 -32
  698. package/dist/commands/marketplace.js.map +0 -1
  699. package/dist/recipes/legacyRecipeCompat.d.ts +0 -10
  700. package/dist/recipes/legacyRecipeCompat.js +0 -131
  701. package/dist/recipes/legacyRecipeCompat.js.map +0 -1
@@ -0,0 +1,139 @@
1
+ /**
2
+ * MongoDB connector — direct-connection-string database connector.
3
+ *
4
+ * Stores a MongoDB connection URI ("mongodb://" or "mongodb+srv://") in
5
+ * secure token storage and exposes a small read-only query surface:
6
+ * listDatabases, listCollections, describeCollection, find, aggregate,
7
+ * count.
8
+ *
9
+ * The `mongodb` driver is loaded lazily via dynamic import so callers
10
+ * without the package installed see a friendly message instead of a
11
+ * module-resolution crash at startup. Tests inject a fake module via
12
+ * `__setMongoModuleForTest`.
13
+ *
14
+ * HTTP routes (wired centrally in src/connectorRoutes.ts):
15
+ * POST /connections/mongodb/connect — body: { connectionString, database? }
16
+ * POST /connections/mongodb/test — ping admin
17
+ * DELETE /connections/mongodb — disconnect + delete token
18
+ */
19
+ import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus, type OAuthConfig } from "./baseConnector.js";
20
+ export interface MongoTokens {
21
+ connectionString: string;
22
+ database?: string;
23
+ connected_at: string;
24
+ }
25
+ /**
26
+ * Minimal subset of the `mongodb` driver API we depend on. Declared
27
+ * structurally so tests can supply a hand-rolled fake without pulling the
28
+ * real package into the test runtime.
29
+ */
30
+ export interface MongoDriverLike {
31
+ MongoClient: new (uri: string, options?: unknown) => MongoClientLike;
32
+ MongoNetworkError?: new (...args: unknown[]) => Error;
33
+ }
34
+ export interface MongoClientLike {
35
+ connect(): Promise<unknown>;
36
+ close(): Promise<unknown>;
37
+ db(name?: string): MongoDbLike;
38
+ }
39
+ export interface MongoDbLike {
40
+ admin(): MongoAdminLike;
41
+ command(cmd: Record<string, unknown>): Promise<unknown>;
42
+ listCollections(filter?: Record<string, unknown>, options?: Record<string, unknown>): {
43
+ toArray(): Promise<Array<{
44
+ name: string;
45
+ }>>;
46
+ };
47
+ collection(name: string): MongoCollectionLike;
48
+ }
49
+ export interface MongoAdminLike {
50
+ listDatabases(): Promise<{
51
+ databases: Array<{
52
+ name: string;
53
+ }>;
54
+ }>;
55
+ command(cmd: Record<string, unknown>): Promise<unknown>;
56
+ }
57
+ export interface MongoCollectionLike {
58
+ indexes(): Promise<unknown[]>;
59
+ findOne(filter?: Record<string, unknown>): Promise<unknown>;
60
+ find(filter?: Record<string, unknown>, options?: Record<string, unknown>): {
61
+ toArray(): Promise<unknown[]>;
62
+ };
63
+ aggregate(pipeline: Array<Record<string, unknown>>, options?: Record<string, unknown>): {
64
+ toArray(): Promise<unknown[]>;
65
+ };
66
+ estimatedDocumentCount(): Promise<number>;
67
+ countDocuments(filter?: Record<string, unknown>): Promise<number>;
68
+ }
69
+ /** Inject a fake `mongodb` module for hermetic tests. */
70
+ export declare function __setMongoModuleForTest(mod: MongoDriverLike | null): void;
71
+ export declare function loadTokens(): MongoTokens | null;
72
+ export declare function saveTokens(tokens: MongoTokens): void;
73
+ export declare function clearTokens(): void;
74
+ /**
75
+ * Walk a filter/projection/pipeline value and reject any object key that
76
+ * matches dangerous Mongo operators at any depth:
77
+ *
78
+ * $where — server-side JS evaluation
79
+ * $function — server-side JS in aggregation
80
+ * $accumulator — server-side JS accumulator
81
+ * $out — pipeline stage that writes a collection
82
+ * $merge — pipeline stage that writes/upserts into a collection
83
+ *
84
+ * Returns true when the input is safe; throws otherwise so callers don't
85
+ * have to remember to check a boolean.
86
+ */
87
+ export declare function isReadOnlyMongoOp(value: unknown): true;
88
+ export declare class MongoConnector extends BaseConnector {
89
+ readonly providerName = "mongodb";
90
+ protected getOAuthConfig(): OAuthConfig | null;
91
+ authenticate(): Promise<AuthContext>;
92
+ getStatus(): ConnectorStatus;
93
+ healthCheck(): Promise<{
94
+ ok: boolean;
95
+ error?: ConnectorError;
96
+ }>;
97
+ normalizeError(error: unknown): ConnectorError;
98
+ disconnect(): Promise<void>;
99
+ }
100
+ export declare function mongoConnector(): MongoConnector;
101
+ export declare function listDatabases(): Promise<string[]>;
102
+ export declare function listCollections(database: string): Promise<string[]>;
103
+ export declare function describeCollection(database: string, collection: string): Promise<{
104
+ sample: unknown;
105
+ indexes: unknown[];
106
+ }>;
107
+ export interface FindOptions {
108
+ projection?: Record<string, unknown>;
109
+ limit?: number;
110
+ }
111
+ export declare function find(database: string, collection: string, filter?: Record<string, unknown>, options?: FindOptions): Promise<unknown[]>;
112
+ export declare function aggregate(database: string, collection: string, pipeline: Array<Record<string, unknown>>, limit?: number): Promise<unknown[]>;
113
+ export declare function count(database: string, collection: string, filter?: Record<string, unknown>): Promise<number>;
114
+ export interface ConnectorHandlerResult {
115
+ status: number;
116
+ body: string;
117
+ contentType?: string;
118
+ redirect?: string;
119
+ }
120
+ /**
121
+ * POST /connections/mongodb/connect
122
+ * Body: { connectionString: string, database?: string }
123
+ *
124
+ * Validates by issuing a ping. On success persists the credential.
125
+ */
126
+ export declare function handleMongoConnect(body: unknown): Promise<ConnectorHandlerResult>;
127
+ /**
128
+ * POST /connections/mongodb/test — re-ping the stored connection.
129
+ */
130
+ export declare function handleMongoTest(): Promise<ConnectorHandlerResult>;
131
+ /**
132
+ * DELETE /connections/mongodb — close client, drop token.
133
+ */
134
+ export declare function handleMongoDisconnect(): Promise<ConnectorHandlerResult>;
135
+ /**
136
+ * Optional HTML status page parity with other connectors. Not wired by
137
+ * default — exported for symmetry should the router need it.
138
+ */
139
+ export declare function renderMongoStatusHtml(): ConnectorHandlerResult;
@@ -0,0 +1,455 @@
1
+ /**
2
+ * MongoDB connector — direct-connection-string database connector.
3
+ *
4
+ * Stores a MongoDB connection URI ("mongodb://" or "mongodb+srv://") in
5
+ * secure token storage and exposes a small read-only query surface:
6
+ * listDatabases, listCollections, describeCollection, find, aggregate,
7
+ * count.
8
+ *
9
+ * The `mongodb` driver is loaded lazily via dynamic import so callers
10
+ * without the package installed see a friendly message instead of a
11
+ * module-resolution crash at startup. Tests inject a fake module via
12
+ * `__setMongoModuleForTest`.
13
+ *
14
+ * HTTP routes (wired centrally in src/connectorRoutes.ts):
15
+ * POST /connections/mongodb/connect — body: { connectionString, database? }
16
+ * POST /connections/mongodb/test — ping admin
17
+ * DELETE /connections/mongodb — disconnect + delete token
18
+ */
19
+ import { BaseConnector, } from "./baseConnector.js";
20
+ import { escHtml } from "./htmlEscape.js";
21
+ import { deleteSecretJsonSync, getSecretJsonSync, storeSecretJsonSync, } from "./tokenStorage.js";
22
+ let _injectedModule = null;
23
+ let _modulePromise = null;
24
+ /** Inject a fake `mongodb` module for hermetic tests. */
25
+ export function __setMongoModuleForTest(mod) {
26
+ _injectedModule = mod;
27
+ _modulePromise = null;
28
+ // Reset the singleton client so a re-injected fake takes effect.
29
+ if (_client) {
30
+ void _client.close().catch(() => undefined);
31
+ _client = null;
32
+ }
33
+ }
34
+ async function loadMongoModule() {
35
+ if (_injectedModule)
36
+ return _injectedModule;
37
+ if (_modulePromise)
38
+ return _modulePromise;
39
+ _modulePromise = (async () => {
40
+ try {
41
+ // @ts-expect-error optional peer dep; resolved at runtime
42
+ const mod = (await import("mongodb"));
43
+ return mod;
44
+ }
45
+ catch {
46
+ throw new Error("MongoDB driver not installed. Run: npm install mongodb");
47
+ }
48
+ })();
49
+ return _modulePromise;
50
+ }
51
+ // ── Singleton client ─────────────────────────────────────────────────────────
52
+ let _client = null;
53
+ let _clientUri = null;
54
+ async function getClient(uri) {
55
+ if (_client && _clientUri === uri)
56
+ return _client;
57
+ if (_client && _clientUri !== uri) {
58
+ try {
59
+ await _client.close();
60
+ }
61
+ catch {
62
+ // Best-effort close
63
+ }
64
+ _client = null;
65
+ }
66
+ const mod = await loadMongoModule();
67
+ const client = new mod.MongoClient(uri);
68
+ await client.connect();
69
+ _client = client;
70
+ _clientUri = uri;
71
+ return client;
72
+ }
73
+ async function disconnectClient() {
74
+ if (!_client)
75
+ return;
76
+ try {
77
+ await _client.close();
78
+ }
79
+ catch {
80
+ // Best-effort
81
+ }
82
+ _client = null;
83
+ _clientUri = null;
84
+ }
85
+ // ── Token persistence ────────────────────────────────────────────────────────
86
+ const PROVIDER = "mongodb";
87
+ export function loadTokens() {
88
+ const envUri = process.env.MONGODB_URI;
89
+ if (envUri) {
90
+ return {
91
+ connectionString: envUri,
92
+ database: process.env.MONGODB_DATABASE,
93
+ connected_at: new Date().toISOString(),
94
+ };
95
+ }
96
+ return getSecretJsonSync(PROVIDER);
97
+ }
98
+ export function saveTokens(tokens) {
99
+ storeSecretJsonSync(PROVIDER, tokens);
100
+ }
101
+ export function clearTokens() {
102
+ deleteSecretJsonSync(PROVIDER);
103
+ }
104
+ // ── Connection string validation ─────────────────────────────────────────────
105
+ function validateConnectionString(uri) {
106
+ if (typeof uri !== "string" || uri.length === 0) {
107
+ throw new Error("connectionString must be a non-empty string");
108
+ }
109
+ if (!/^mongodb(\+srv)?:\/\//i.test(uri)) {
110
+ throw new Error("connectionString must start with mongodb:// or mongodb+srv://");
111
+ }
112
+ // Catch obvious tampering up front (control chars, newlines).
113
+ if (/[\x00-\x1f]/.test(uri)) {
114
+ throw new Error("connectionString contains control characters");
115
+ }
116
+ return uri;
117
+ }
118
+ // ── Read-only operation guard ────────────────────────────────────────────────
119
+ const FORBIDDEN_KEY_RE = /^\$(where|function|accumulator|out|merge)$/i;
120
+ /**
121
+ * Walk a filter/projection/pipeline value and reject any object key that
122
+ * matches dangerous Mongo operators at any depth:
123
+ *
124
+ * $where — server-side JS evaluation
125
+ * $function — server-side JS in aggregation
126
+ * $accumulator — server-side JS accumulator
127
+ * $out — pipeline stage that writes a collection
128
+ * $merge — pipeline stage that writes/upserts into a collection
129
+ *
130
+ * Returns true when the input is safe; throws otherwise so callers don't
131
+ * have to remember to check a boolean.
132
+ */
133
+ export function isReadOnlyMongoOp(value) {
134
+ walk(value, 0);
135
+ return true;
136
+ }
137
+ function walk(value, depth) {
138
+ if (depth > 64) {
139
+ throw new Error("MongoDB filter/pipeline nested too deeply");
140
+ }
141
+ if (value === null || value === undefined)
142
+ return;
143
+ if (Array.isArray(value)) {
144
+ for (const item of value)
145
+ walk(item, depth + 1);
146
+ return;
147
+ }
148
+ if (typeof value !== "object")
149
+ return;
150
+ for (const key of Object.keys(value)) {
151
+ if (FORBIDDEN_KEY_RE.test(key)) {
152
+ throw new Error(`MongoDB operator not allowed (read-only guard): ${key}`);
153
+ }
154
+ walk(value[key], depth + 1);
155
+ }
156
+ }
157
+ // ── Connector class ──────────────────────────────────────────────────────────
158
+ export class MongoConnector extends BaseConnector {
159
+ providerName = "mongodb";
160
+ getOAuthConfig() {
161
+ return null; // Direct connection string, no OAuth.
162
+ }
163
+ async authenticate() {
164
+ const tokens = loadTokens();
165
+ if (!tokens) {
166
+ throw new Error("MongoDB not connected. POST /connections/mongodb/connect first.");
167
+ }
168
+ return { token: tokens.connectionString };
169
+ }
170
+ getStatus() {
171
+ const tokens = loadTokens();
172
+ return {
173
+ id: PROVIDER,
174
+ status: tokens ? "connected" : "disconnected",
175
+ lastSync: tokens?.connected_at,
176
+ workspace: tokens?.database,
177
+ };
178
+ }
179
+ async healthCheck() {
180
+ const tokens = loadTokens();
181
+ if (!tokens) {
182
+ return {
183
+ ok: false,
184
+ error: {
185
+ code: "auth_expired",
186
+ message: "MongoDB not connected",
187
+ retryable: false,
188
+ },
189
+ };
190
+ }
191
+ try {
192
+ const client = await getClient(tokens.connectionString);
193
+ await client.db("admin").command({ ping: 1 });
194
+ return { ok: true };
195
+ }
196
+ catch (err) {
197
+ return { ok: false, error: this.normalizeError(err) };
198
+ }
199
+ }
200
+ normalizeError(error) {
201
+ const message = error instanceof Error ? error.message : String(error);
202
+ const codeRaw = error?.code;
203
+ const code = typeof codeRaw === "number" ? codeRaw : undefined;
204
+ const name = error?.name;
205
+ // Network errors — check name first since some have no numeric code.
206
+ if (name === "MongoNetworkError" ||
207
+ name === "MongoServerSelectionError" ||
208
+ name === "MongoNetworkTimeoutError" ||
209
+ /ECONNREFUSED|ENOTFOUND|ETIMEDOUT|network/i.test(message)) {
210
+ return {
211
+ code: "network_error",
212
+ message,
213
+ providerDetail: error,
214
+ retryable: true,
215
+ };
216
+ }
217
+ switch (code) {
218
+ case 18: // AuthenticationFailed
219
+ return {
220
+ code: "auth_expired",
221
+ message,
222
+ providerDetail: error,
223
+ retryable: false,
224
+ suggestedAction: "Re-connect MongoDB via POST /connections/mongodb/connect",
225
+ };
226
+ case 13: // Unauthorized
227
+ return {
228
+ code: "permission_denied",
229
+ message,
230
+ providerDetail: error,
231
+ retryable: false,
232
+ };
233
+ case 11: // UserNotFound
234
+ case 26: // NamespaceNotFound
235
+ return {
236
+ code: "not_found",
237
+ message,
238
+ providerDetail: error,
239
+ retryable: false,
240
+ };
241
+ default:
242
+ return {
243
+ code: "provider_error",
244
+ message,
245
+ providerDetail: error,
246
+ retryable: false,
247
+ };
248
+ }
249
+ }
250
+ async disconnect() {
251
+ await disconnectClient();
252
+ clearTokens();
253
+ this.auth = null;
254
+ }
255
+ }
256
+ // ── Singleton ────────────────────────────────────────────────────────────────
257
+ let _connector = null;
258
+ export function mongoConnector() {
259
+ if (!_connector)
260
+ _connector = new MongoConnector();
261
+ return _connector;
262
+ }
263
+ // ── Read-only tool surface ───────────────────────────────────────────────────
264
+ const DEFAULT_LIMIT = 100;
265
+ const MAX_LIMIT = 1000;
266
+ function clampLimit(n) {
267
+ if (typeof n !== "number" || !Number.isFinite(n) || n <= 0) {
268
+ return DEFAULT_LIMIT;
269
+ }
270
+ return Math.min(Math.floor(n), MAX_LIMIT);
271
+ }
272
+ async function activeDb(name) {
273
+ const tokens = loadTokens();
274
+ if (!tokens) {
275
+ throw new Error("MongoDB not connected. POST /connections/mongodb/connect first.");
276
+ }
277
+ const client = await getClient(tokens.connectionString);
278
+ return client.db(name);
279
+ }
280
+ export async function listDatabases() {
281
+ const tokens = loadTokens();
282
+ if (!tokens) {
283
+ throw new Error("MongoDB not connected");
284
+ }
285
+ const client = await getClient(tokens.connectionString);
286
+ const res = await client.db().admin().listDatabases();
287
+ return (res.databases ?? []).map((d) => d.name);
288
+ }
289
+ export async function listCollections(database) {
290
+ if (!database)
291
+ throw new Error("database is required");
292
+ const db = await activeDb(database);
293
+ const rows = await db.listCollections({}, { nameOnly: true }).toArray();
294
+ return rows.map((r) => r.name);
295
+ }
296
+ export async function describeCollection(database, collection) {
297
+ if (!database)
298
+ throw new Error("database is required");
299
+ if (!collection)
300
+ throw new Error("collection is required");
301
+ const db = await activeDb(database);
302
+ const col = db.collection(collection);
303
+ const [sample, indexes] = await Promise.all([col.findOne({}), col.indexes()]);
304
+ return { sample, indexes };
305
+ }
306
+ export async function find(database, collection, filter = {}, options = {}) {
307
+ if (!database)
308
+ throw new Error("database is required");
309
+ if (!collection)
310
+ throw new Error("collection is required");
311
+ isReadOnlyMongoOp(filter);
312
+ if (options.projection)
313
+ isReadOnlyMongoOp(options.projection);
314
+ const db = await activeDb(database);
315
+ const cursor = db.collection(collection).find(filter, {
316
+ projection: options.projection,
317
+ limit: clampLimit(options.limit),
318
+ });
319
+ return cursor.toArray();
320
+ }
321
+ const FORBIDDEN_STAGE_RE = /^\$(out|merge|function|where|accumulator)$/i;
322
+ function rejectForbiddenStages(pipeline) {
323
+ for (const stage of pipeline) {
324
+ if (!stage || typeof stage !== "object")
325
+ continue;
326
+ for (const key of Object.keys(stage)) {
327
+ if (FORBIDDEN_STAGE_RE.test(key)) {
328
+ throw new Error(`MongoDB aggregation stage not allowed (read-only guard): ${key}`);
329
+ }
330
+ }
331
+ }
332
+ }
333
+ export async function aggregate(database, collection, pipeline, limit = DEFAULT_LIMIT) {
334
+ if (!database)
335
+ throw new Error("database is required");
336
+ if (!collection)
337
+ throw new Error("collection is required");
338
+ if (!Array.isArray(pipeline))
339
+ throw new Error("pipeline must be an array");
340
+ rejectForbiddenStages(pipeline);
341
+ isReadOnlyMongoOp(pipeline);
342
+ const cappedLimit = clampLimit(limit);
343
+ const capped = [...pipeline, { $limit: cappedLimit }];
344
+ const db = await activeDb(database);
345
+ return db.collection(collection).aggregate(capped).toArray();
346
+ }
347
+ export async function count(database, collection, filter) {
348
+ if (!database)
349
+ throw new Error("database is required");
350
+ if (!collection)
351
+ throw new Error("collection is required");
352
+ const db = await activeDb(database);
353
+ const col = db.collection(collection);
354
+ if (!filter || Object.keys(filter).length === 0) {
355
+ return col.estimatedDocumentCount();
356
+ }
357
+ isReadOnlyMongoOp(filter);
358
+ return col.countDocuments(filter);
359
+ }
360
+ function jsonResult(status, payload) {
361
+ return {
362
+ status,
363
+ contentType: "application/json",
364
+ body: JSON.stringify(payload),
365
+ };
366
+ }
367
+ /**
368
+ * POST /connections/mongodb/connect
369
+ * Body: { connectionString: string, database?: string }
370
+ *
371
+ * Validates by issuing a ping. On success persists the credential.
372
+ */
373
+ export async function handleMongoConnect(body) {
374
+ let connectionString;
375
+ let database;
376
+ try {
377
+ const parsed = (body ?? {});
378
+ connectionString = validateConnectionString(parsed.connectionString);
379
+ if (parsed.database !== undefined) {
380
+ if (typeof parsed.database !== "string") {
381
+ throw new Error("database must be a string");
382
+ }
383
+ database = parsed.database;
384
+ }
385
+ }
386
+ catch (err) {
387
+ return jsonResult(400, {
388
+ ok: false,
389
+ error: err instanceof Error ? err.message : String(err),
390
+ });
391
+ }
392
+ // Verify by pinging admin before persisting.
393
+ try {
394
+ const client = await getClient(connectionString);
395
+ await client.db("admin").command({ ping: 1 });
396
+ }
397
+ catch (err) {
398
+ // Close the failed client so a retry uses fresh state.
399
+ await disconnectClient();
400
+ return jsonResult(400, {
401
+ ok: false,
402
+ error: err instanceof Error ? err.message : String(err),
403
+ });
404
+ }
405
+ const tokens = {
406
+ connectionString,
407
+ database,
408
+ connected_at: new Date().toISOString(),
409
+ };
410
+ saveTokens(tokens);
411
+ return jsonResult(200, {
412
+ ok: true,
413
+ status: mongoConnector().getStatus(),
414
+ });
415
+ }
416
+ /**
417
+ * POST /connections/mongodb/test — re-ping the stored connection.
418
+ */
419
+ export async function handleMongoTest() {
420
+ const tokens = loadTokens();
421
+ if (!tokens) {
422
+ return jsonResult(400, { ok: false, error: "MongoDB not connected" });
423
+ }
424
+ try {
425
+ const client = await getClient(tokens.connectionString);
426
+ await client.db("admin").command({ ping: 1 });
427
+ return jsonResult(200, { ok: true, message: "connected" });
428
+ }
429
+ catch (err) {
430
+ return jsonResult(400, {
431
+ ok: false,
432
+ error: err instanceof Error ? err.message : String(err),
433
+ });
434
+ }
435
+ }
436
+ /**
437
+ * DELETE /connections/mongodb — close client, drop token.
438
+ */
439
+ export async function handleMongoDisconnect() {
440
+ await mongoConnector().disconnect();
441
+ return jsonResult(200, { ok: true });
442
+ }
443
+ /**
444
+ * Optional HTML status page parity with other connectors. Not wired by
445
+ * default — exported for symmetry should the router need it.
446
+ */
447
+ export function renderMongoStatusHtml() {
448
+ const status = mongoConnector().getStatus();
449
+ return {
450
+ status: 200,
451
+ contentType: "text/html",
452
+ body: `<html><body><h2>MongoDB</h2><pre>${escHtml(JSON.stringify(status, null, 2))}</pre></body></html>`,
453
+ };
454
+ }
455
+ //# sourceMappingURL=mongodb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongodb.js","sourceRoot":"","sources":["../../src/connectors/mongodb.ts"],"names":[],"mappings":"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"}
@@ -127,7 +127,7 @@ export interface ConnectorHandlerResult {
127
127
  contentType?: string;
128
128
  }
129
129
  /**
130
- * POST /connections/notion/connect { token: "secret_..." }
130
+ * POST /connections/notion/connect { token: "secret_..." | "ntn_..." }
131
131
  * Stores the integration token and verifies it by calling /users/me.
132
132
  */
133
133
  export declare function handleNotionConnect(body: string): Promise<ConnectorHandlerResult>;
@@ -13,7 +13,7 @@ import { unlinkSync } from "node:fs";
13
13
  import { homedir } from "node:os";
14
14
  import path from "node:path";
15
15
  import { BaseConnector, } from "./baseConnector.js";
16
- import { getSecretJsonSync, storeSecretJsonSync } from "./tokenStorage.js";
16
+ import { deleteSecretJsonSync, getSecretJsonSync, storeSecretJsonSync, } from "./tokenStorage.js";
17
17
  const NOTION_API = "https://api.notion.com/v1";
18
18
  const NOTION_VERSION = "2022-06-28";
19
19
  // ------------------------------------------------------------------ token helpers
@@ -31,6 +31,15 @@ export function saveTokens(tokens) {
31
31
  storeSecretJsonSync("notion", tokens);
32
32
  }
33
33
  export function clearTokens() {
34
+ // Primary: remove the token from secure storage (keychain or encrypted .enc).
35
+ // This is where saveTokens() actually persists the token.
36
+ try {
37
+ deleteSecretJsonSync("notion");
38
+ }
39
+ catch {
40
+ /* ignore — best effort */
41
+ }
42
+ // Best-effort cleanup of any legacy plaintext token file.
34
43
  try {
35
44
  const p = path.join(homedir(), ".patchwork", "tokens", "notion.json");
36
45
  unlinkSync(p);
@@ -301,7 +310,7 @@ export function resetNotionConnector() {
301
310
  // ------------------------------------------------------------------ convenience re-exports
302
311
  export { loadTokens as isConnected };
303
312
  /**
304
- * POST /connections/notion/connect { token: "secret_..." }
313
+ * POST /connections/notion/connect { token: "secret_..." | "ntn_..." }
305
314
  * Stores the integration token and verifies it by calling /users/me.
306
315
  */
307
316
  export async function handleNotionConnect(body) {
@@ -309,13 +318,13 @@ export async function handleNotionConnect(body) {
309
318
  try {
310
319
  const parsed = JSON.parse(body);
311
320
  if (typeof parsed.token !== "string" ||
312
- !parsed.token.startsWith("secret_")) {
321
+ !(parsed.token.startsWith("secret_") || parsed.token.startsWith("ntn_"))) {
313
322
  return {
314
323
  status: 400,
315
324
  contentType: "application/json",
316
325
  body: JSON.stringify({
317
326
  ok: false,
318
- error: 'Notion integration token must start with "secret_". Find it at https://www.notion.so/my-integrations',
327
+ error: 'Notion integration token must start with "secret_" or "ntn_". Find it at https://www.notion.so/my-integrations',
319
328
  }),
320
329
  };
321
330
  }