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.
- package/README.bridge.md +14 -14
- package/README.md +201 -34
- package/deploy/README.md +1 -1
- package/deploy/bootstrap-vps.sh +14 -9
- package/deploy/deploy-dashboard.sh +25 -1
- package/deploy/macos/README.md +153 -0
- package/deploy/macos/com.patchwork.bridge.plist.template +54 -0
- package/deploy/macos/com.patchwork.tunnel.plist.template +76 -0
- package/deploy/macos/install-mac-bridge.sh +244 -0
- package/deploy/macos/uninstall-mac-bridge.sh +22 -0
- package/dist/activityLog.d.ts +6 -0
- package/dist/activityLog.js +63 -26
- package/dist/activityLog.js.map +1 -1
- package/dist/adapters/claude.js +22 -16
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/gemini.js +15 -11
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/openai.js +9 -9
- package/dist/adapters/openai.js.map +1 -1
- package/dist/ajv2020.d.ts +25 -0
- package/dist/ajv2020.js +33 -0
- package/dist/ajv2020.js.map +1 -0
- package/dist/analyticsAggregator.js +1 -1
- package/dist/analyticsAggregator.js.map +1 -1
- package/dist/analyticsConfig.d.ts +29 -0
- package/dist/analyticsConfig.js +102 -0
- package/dist/analyticsConfig.js.map +1 -0
- package/dist/analyticsPrefs.d.ts +38 -2
- package/dist/analyticsPrefs.js +148 -23
- package/dist/analyticsPrefs.js.map +1 -1
- package/dist/analyticsSend.d.ts +17 -1
- package/dist/analyticsSend.js +67 -5
- package/dist/analyticsSend.js.map +1 -1
- package/dist/approvalHttp.d.ts +14 -0
- package/dist/approvalHttp.js +212 -9
- package/dist/approvalHttp.js.map +1 -1
- package/dist/approvalInsights.js +13 -5
- package/dist/approvalInsights.js.map +1 -1
- package/dist/approvalQueue.d.ts +97 -3
- package/dist/approvalQueue.js +193 -19
- package/dist/approvalQueue.js.map +1 -1
- package/dist/approvalSignals.js +19 -11
- package/dist/approvalSignals.js.map +1 -1
- package/dist/automation.d.ts +35 -10
- package/dist/automation.js +133 -37
- package/dist/automation.js.map +1 -1
- package/dist/automationSuggestions.js +10 -8
- package/dist/automationSuggestions.js.map +1 -1
- package/dist/bridge.d.ts +2 -0
- package/dist/bridge.js +219 -35
- package/dist/bridge.js.map +1 -1
- package/dist/bridgeLockDiscovery.d.ts +27 -1
- package/dist/bridgeLockDiscovery.js +38 -11
- package/dist/bridgeLockDiscovery.js.map +1 -1
- package/dist/bridgeToken.js +3 -2
- package/dist/bridgeToken.js.map +1 -1
- package/dist/claudeDriver.js +23 -8
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +1 -1
- package/dist/claudeOrchestrator.js +87 -44
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/analytics.d.ts +8 -0
- package/dist/commands/analytics.js +134 -0
- package/dist/commands/analytics.js.map +1 -0
- package/dist/commands/auditEnv.d.ts +36 -0
- package/dist/commands/auditEnv.js +202 -0
- package/dist/commands/auditEnv.js.map +1 -0
- package/dist/commands/connect.d.ts +47 -0
- package/dist/commands/connect.js +419 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/dashboard.js +8 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/doctor.d.ts +35 -0
- package/dist/commands/doctor.js +51 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/install.js +3 -0
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/launchd.js +15 -16
- package/dist/commands/launchd.js.map +1 -1
- package/dist/commands/patchworkInit.d.ts +5 -0
- package/dist/commands/patchworkInit.js +89 -7
- package/dist/commands/patchworkInit.js.map +1 -1
- package/dist/commands/recipe.d.ts +151 -0
- package/dist/commands/recipe.js +649 -9
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.js +11 -4
- package/dist/commands/recipeInstall.js.map +1 -1
- package/dist/commands/shadowScan.d.ts +34 -0
- package/dist/commands/shadowScan.js +142 -0
- package/dist/commands/shadowScan.js.map +1 -0
- package/dist/commands/task.d.ts +25 -0
- package/dist/commands/task.js +62 -42
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/tools.d.ts +20 -1
- package/dist/commands/tools.js +112 -3
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/tracesExport.d.ts +15 -1
- package/dist/commands/tracesExport.js +39 -5
- package/dist/commands/tracesExport.js.map +1 -1
- package/dist/commands/tracesImport.js +21 -4
- package/dist/commands/tracesImport.js.map +1 -1
- package/dist/commitIssueLinkLog.d.ts +16 -0
- package/dist/commitIssueLinkLog.js +110 -24
- package/dist/commitIssueLinkLog.js.map +1 -1
- package/dist/companions/registry.js +15 -7
- package/dist/companions/registry.js.map +1 -1
- package/dist/config.d.ts +47 -3
- package/dist/config.js +111 -21
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +1422 -57
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/airtable.d.ts +230 -0
- package/dist/connectors/airtable.js +700 -0
- package/dist/connectors/airtable.js.map +1 -0
- package/dist/connectors/asana.js +13 -9
- package/dist/connectors/asana.js.map +1 -1
- package/dist/connectors/baseConnector.js +25 -3
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/caldiy.d.ts +137 -0
- package/dist/connectors/caldiy.js +424 -0
- package/dist/connectors/caldiy.js.map +1 -0
- package/dist/connectors/circleci.d.ts +162 -0
- package/dist/connectors/circleci.js +576 -0
- package/dist/connectors/circleci.js.map +1 -0
- package/dist/connectors/cloudflare.d.ts +132 -0
- package/dist/connectors/cloudflare.js +622 -0
- package/dist/connectors/cloudflare.js.map +1 -0
- package/dist/connectors/confluence.js +35 -0
- package/dist/connectors/confluence.js.map +1 -1
- package/dist/connectors/connectorRedirectUri.d.ts +30 -0
- package/dist/connectors/connectorRedirectUri.js +38 -0
- package/dist/connectors/connectorRedirectUri.js.map +1 -0
- package/dist/connectors/connectorRegistry.d.ts +60 -0
- package/dist/connectors/connectorRegistry.js +354 -0
- package/dist/connectors/connectorRegistry.js.map +1 -0
- package/dist/connectors/datadog.js +41 -5
- package/dist/connectors/datadog.js.map +1 -1
- package/dist/connectors/discord.js +14 -10
- package/dist/connectors/discord.js.map +1 -1
- package/dist/connectors/elasticsearch.d.ts +141 -0
- package/dist/connectors/elasticsearch.js +601 -0
- package/dist/connectors/elasticsearch.js.map +1 -0
- package/dist/connectors/figma.d.ts +130 -0
- package/dist/connectors/figma.js +387 -0
- package/dist/connectors/figma.js.map +1 -0
- package/dist/connectors/github.d.ts +17 -0
- package/dist/connectors/github.js +53 -2
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gitlab.js +12 -6
- package/dist/connectors/gitlab.js.map +1 -1
- package/dist/connectors/gmail.js +72 -21
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleCalendar.js +8 -8
- package/dist/connectors/googleCalendar.js.map +1 -1
- package/dist/connectors/googleDocs.d.ts +103 -0
- package/dist/connectors/googleDocs.js +409 -0
- package/dist/connectors/googleDocs.js.map +1 -0
- package/dist/connectors/googleDrive.d.ts +12 -0
- package/dist/connectors/googleDrive.js +35 -8
- package/dist/connectors/googleDrive.js.map +1 -1
- package/dist/connectors/grafana.d.ts +133 -0
- package/dist/connectors/grafana.js +478 -0
- package/dist/connectors/grafana.js.map +1 -0
- package/dist/connectors/jira.d.ts +25 -0
- package/dist/connectors/jira.js +234 -3
- package/dist/connectors/jira.js.map +1 -1
- package/dist/connectors/linear.js +1 -1
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/mcpClient.js +37 -23
- package/dist/connectors/mcpClient.js.map +1 -1
- package/dist/connectors/mcpOAuth.js +78 -16
- package/dist/connectors/mcpOAuth.js.map +1 -1
- package/dist/connectors/monday.d.ts +217 -0
- package/dist/connectors/monday.js +655 -0
- package/dist/connectors/monday.js.map +1 -0
- package/dist/connectors/mongodb.d.ts +139 -0
- package/dist/connectors/mongodb.js +455 -0
- package/dist/connectors/mongodb.js.map +1 -0
- package/dist/connectors/notion.d.ts +1 -1
- package/dist/connectors/notion.js +13 -4
- package/dist/connectors/notion.js.map +1 -1
- package/dist/connectors/oauthStateStore.d.ts +20 -0
- package/dist/connectors/oauthStateStore.js +94 -4
- package/dist/connectors/oauthStateStore.js.map +1 -1
- package/dist/connectors/obsidian.d.ts +83 -0
- package/dist/connectors/obsidian.js +441 -0
- package/dist/connectors/obsidian.js.map +1 -0
- package/dist/connectors/paystack.d.ts +159 -0
- package/dist/connectors/paystack.js +607 -0
- package/dist/connectors/paystack.js.map +1 -0
- package/dist/connectors/pipedrive.d.ts +189 -0
- package/dist/connectors/pipedrive.js +559 -0
- package/dist/connectors/pipedrive.js.map +1 -0
- package/dist/connectors/postgres.d.ts +127 -0
- package/dist/connectors/postgres.js +512 -0
- package/dist/connectors/postgres.js.map +1 -0
- package/dist/connectors/posthog.d.ts +119 -0
- package/dist/connectors/posthog.js +479 -0
- package/dist/connectors/posthog.js.map +1 -0
- package/dist/connectors/redis.d.ts +140 -0
- package/dist/connectors/redis.js +579 -0
- package/dist/connectors/redis.js.map +1 -0
- package/dist/connectors/resend.d.ts +131 -0
- package/dist/connectors/resend.js +529 -0
- package/dist/connectors/resend.js.map +1 -0
- package/dist/connectors/salesforce.d.ts +136 -0
- package/dist/connectors/salesforce.js +603 -0
- package/dist/connectors/salesforce.js.map +1 -0
- package/dist/connectors/secrets.d.ts +51 -0
- package/dist/connectors/secrets.js +102 -0
- package/dist/connectors/secrets.js.map +1 -0
- package/dist/connectors/sendgrid.d.ts +102 -0
- package/dist/connectors/sendgrid.js +423 -0
- package/dist/connectors/sendgrid.js.map +1 -0
- package/dist/connectors/shopify.d.ts +145 -0
- package/dist/connectors/shopify.js +502 -0
- package/dist/connectors/shopify.js.map +1 -0
- package/dist/connectors/slack.d.ts +1 -1
- package/dist/connectors/slack.js +61 -9
- package/dist/connectors/slack.js.map +1 -1
- package/dist/connectors/snowflake.d.ts +119 -0
- package/dist/connectors/snowflake.js +633 -0
- package/dist/connectors/snowflake.js.map +1 -0
- package/dist/connectors/supabase.d.ts +92 -0
- package/dist/connectors/supabase.js +630 -0
- package/dist/connectors/supabase.js.map +1 -0
- package/dist/connectors/todoist.d.ts +117 -0
- package/dist/connectors/todoist.js +485 -0
- package/dist/connectors/todoist.js.map +1 -0
- package/dist/connectors/tokenStorage.js +56 -14
- package/dist/connectors/tokenStorage.js.map +1 -1
- package/dist/connectors/twilio.d.ts +118 -0
- package/dist/connectors/twilio.js +475 -0
- package/dist/connectors/twilio.js.map +1 -0
- package/dist/connectors/vercel.d.ts +110 -0
- package/dist/connectors/vercel.js +479 -0
- package/dist/connectors/vercel.js.map +1 -0
- package/dist/connectors/webflow.d.ts +118 -0
- package/dist/connectors/webflow.js +393 -0
- package/dist/connectors/webflow.js.map +1 -0
- package/dist/connectors/woocommerce.d.ts +220 -0
- package/dist/connectors/woocommerce.js +464 -0
- package/dist/connectors/woocommerce.js.map +1 -0
- package/dist/crypto.js +7 -2
- package/dist/crypto.js.map +1 -1
- package/dist/decisionReplay.d.ts +8 -6
- package/dist/decisionReplay.js +50 -17
- package/dist/decisionReplay.js.map +1 -1
- package/dist/decisionTraceLog.d.ts +28 -0
- package/dist/decisionTraceLog.js +156 -29
- package/dist/decisionTraceLog.js.map +1 -1
- package/dist/drivers/claude/api.js +33 -9
- package/dist/drivers/claude/api.js.map +1 -1
- package/dist/drivers/claude/envSanitizer.d.ts +0 -6
- package/dist/drivers/claude/envSanitizer.js +17 -2
- package/dist/drivers/claude/envSanitizer.js.map +1 -1
- package/dist/drivers/claude/streamParser.js +5 -4
- package/dist/drivers/claude/streamParser.js.map +1 -1
- package/dist/drivers/claude/subprocess.js +69 -16
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/gemini/index.d.ts +22 -0
- package/dist/drivers/gemini/index.js +256 -129
- package/dist/drivers/gemini/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +2 -0
- package/dist/drivers/local/index.js +12 -0
- package/dist/drivers/local/index.js.map +1 -1
- package/dist/drivers/openai/index.js +30 -2
- package/dist/drivers/openai/index.js.map +1 -1
- package/dist/extensionClient.d.ts +37 -4
- package/dist/extensionClient.js +58 -16
- package/dist/extensionClient.js.map +1 -1
- package/dist/featureFlags.d.ts +91 -0
- package/dist/featureFlags.js +174 -3
- package/dist/featureFlags.js.map +1 -1
- package/dist/fileLock.js +21 -12
- package/dist/fileLock.js.map +1 -1
- package/dist/fileLockSync.d.ts +67 -0
- package/dist/fileLockSync.js +126 -0
- package/dist/fileLockSync.js.map +1 -0
- package/dist/fp/activityAnalytics.js +26 -12
- package/dist/fp/activityAnalytics.js.map +1 -1
- package/dist/fp/automationInterpreter.d.ts +15 -1
- package/dist/fp/automationInterpreter.js +267 -87
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationProgram.d.ts +30 -0
- package/dist/fp/automationProgram.js.map +1 -1
- package/dist/fp/automationState.d.ts +24 -5
- package/dist/fp/automationState.js +56 -9
- package/dist/fp/automationState.js.map +1 -1
- package/dist/fp/automationUtils.js +1 -1
- package/dist/fp/automationUtils.js.map +1 -1
- package/dist/fp/commandDescription.js +7 -1
- package/dist/fp/commandDescription.js.map +1 -1
- package/dist/fp/extensionSnapshot.js +8 -2
- package/dist/fp/extensionSnapshot.js.map +1 -1
- package/dist/fp/interpreterContext.d.ts +66 -1
- package/dist/fp/interpreterContext.js +91 -1
- package/dist/fp/interpreterContext.js.map +1 -1
- package/dist/fp/policyParser.js +34 -2
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/fsWatchWithFallback.d.ts +36 -0
- package/dist/fsWatchWithFallback.js +128 -0
- package/dist/fsWatchWithFallback.js.map +1 -0
- package/dist/haltPushDispatch.d.ts +33 -0
- package/dist/haltPushDispatch.js +103 -0
- package/dist/haltPushDispatch.js.map +1 -0
- package/dist/httpBodyValidation.d.ts +41 -0
- package/dist/httpBodyValidation.js +45 -0
- package/dist/httpBodyValidation.js.map +1 -0
- package/dist/inboxRoutes.d.ts +22 -0
- package/dist/inboxRoutes.js +61 -1
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.js +1206 -158
- package/dist/index.js.map +1 -1
- package/dist/installGuard.js +6 -2
- package/dist/installGuard.js.map +1 -1
- package/dist/localEndpointGuard.d.ts +25 -0
- package/dist/localEndpointGuard.js +101 -0
- package/dist/localEndpointGuard.js.map +1 -0
- package/dist/lockfile.js +31 -4
- package/dist/lockfile.js.map +1 -1
- package/dist/oauth.d.ts +9 -0
- package/dist/oauth.js +33 -0
- package/dist/oauth.js.map +1 -1
- package/dist/oauthRoutes.d.ts +1 -1
- package/dist/oauthRoutes.js +5 -3
- package/dist/oauthRoutes.js.map +1 -1
- package/dist/orchestrator/childBridgeClient.d.ts +5 -0
- package/dist/orchestrator/childBridgeClient.js +28 -1
- package/dist/orchestrator/childBridgeClient.js.map +1 -1
- package/dist/orchestrator/childBridgeRegistry.js +29 -11
- package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
- package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
- package/dist/orchestrator/orchestratorBridge.js +70 -9
- package/dist/orchestrator/orchestratorBridge.js.map +1 -1
- package/dist/patchworkConfig.d.ts +44 -1
- package/dist/patchworkConfig.js +28 -3
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/pluginLoader.js +10 -1
- package/dist/pluginLoader.js.map +1 -1
- package/dist/pluginWatcher.js +12 -14
- package/dist/pluginWatcher.js.map +1 -1
- package/dist/preToolUseHook.js +3 -2
- package/dist/preToolUseHook.js.map +1 -1
- package/dist/processTree.d.ts +34 -0
- package/dist/processTree.js +105 -0
- package/dist/processTree.js.map +1 -0
- package/dist/prompts.js +3 -3
- package/dist/prompts.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +9 -0
- package/dist/recipeOrchestration.js +341 -24
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +58 -2
- package/dist/recipeRoutes.js +744 -115
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/RecipeOrchestrator.d.ts +2 -0
- package/dist/recipes/RecipeOrchestrator.js +6 -1
- package/dist/recipes/RecipeOrchestrator.js.map +1 -1
- package/dist/recipes/agentExecutor.d.ts +25 -5
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/chainedRunner.d.ts +2 -0
- package/dist/recipes/chainedRunner.js +156 -9
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/compiler.js +9 -5
- package/dist/recipes/compiler.js.map +1 -1
- package/dist/recipes/connectorPreflight.d.ts +66 -0
- package/dist/recipes/connectorPreflight.js +169 -0
- package/dist/recipes/connectorPreflight.js.map +1 -0
- package/dist/recipes/dependencyGraph.d.ts +9 -0
- package/dist/recipes/dependencyGraph.js +32 -7
- package/dist/recipes/dependencyGraph.js.map +1 -1
- package/dist/recipes/githubInstallSource.d.ts +135 -0
- package/dist/recipes/githubInstallSource.js +236 -0
- package/dist/recipes/githubInstallSource.js.map +1 -0
- package/dist/recipes/haltCategory.d.ts +119 -0
- package/dist/recipes/haltCategory.js +188 -0
- package/dist/recipes/haltCategory.js.map +1 -0
- package/dist/recipes/idempotencyKey.d.ts +154 -0
- package/dist/recipes/idempotencyKey.js +375 -0
- package/dist/recipes/idempotencyKey.js.map +1 -0
- package/dist/recipes/installer.js +58 -3
- package/dist/recipes/installer.js.map +1 -1
- package/dist/recipes/judgeSummary.d.ts +50 -0
- package/dist/recipes/judgeSummary.js +47 -0
- package/dist/recipes/judgeSummary.js.map +1 -0
- package/dist/recipes/judgeVerdict.d.ts +48 -0
- package/dist/recipes/judgeVerdict.js +174 -0
- package/dist/recipes/judgeVerdict.js.map +1 -0
- package/dist/recipes/migrations/index.d.ts +9 -0
- package/dist/recipes/migrations/index.js +133 -0
- package/dist/recipes/migrations/index.js.map +1 -1
- package/dist/recipes/names.d.ts +20 -0
- package/dist/recipes/names.js +25 -0
- package/dist/recipes/names.js.map +1 -1
- package/dist/recipes/parser.js +116 -6
- package/dist/recipes/parser.js.map +1 -1
- package/dist/recipes/replayRun.js +1 -1
- package/dist/recipes/replayRun.js.map +1 -1
- package/dist/recipes/runBudget.d.ts +70 -0
- package/dist/recipes/runBudget.js +109 -0
- package/dist/recipes/runBudget.js.map +1 -0
- package/dist/recipes/scheduler.d.ts +30 -0
- package/dist/recipes/scheduler.js +69 -19
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schema.d.ts +65 -2
- package/dist/recipes/schemaGenerator.js +119 -7
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/stepObservation.js +9 -0
- package/dist/recipes/stepObservation.js.map +1 -1
- package/dist/recipes/toolRegistry.js +33 -7
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/airtable.d.ts +15 -0
- package/dist/recipes/tools/airtable.js +239 -0
- package/dist/recipes/tools/airtable.js.map +1 -0
- package/dist/recipes/tools/fanOut.d.ts +20 -0
- package/dist/recipes/tools/fanOut.js +199 -0
- package/dist/recipes/tools/fanOut.js.map +1 -0
- package/dist/recipes/tools/file.js +5 -2
- package/dist/recipes/tools/file.js.map +1 -1
- package/dist/recipes/tools/github.d.ts +1 -1
- package/dist/recipes/tools/github.js +75 -1
- package/dist/recipes/tools/github.js.map +1 -1
- package/dist/recipes/tools/gmail.js +27 -5
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/tools/googleDrive.js +64 -0
- package/dist/recipes/tools/googleDrive.js.map +1 -1
- package/dist/recipes/tools/http.d.ts +10 -0
- package/dist/recipes/tools/http.js +176 -0
- package/dist/recipes/tools/http.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +7 -0
- package/dist/recipes/tools/index.js +7 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/resend.d.ts +8 -0
- package/dist/recipes/tools/resend.js +152 -0
- package/dist/recipes/tools/resend.js.map +1 -0
- package/dist/recipes/tools/sendgrid.d.ts +9 -0
- package/dist/recipes/tools/sendgrid.js +174 -0
- package/dist/recipes/tools/sendgrid.js.map +1 -0
- package/dist/recipes/tools/slack.js +1 -1
- package/dist/recipes/tools/twilio.d.ts +11 -0
- package/dist/recipes/tools/twilio.js +179 -0
- package/dist/recipes/tools/twilio.js.map +1 -0
- package/dist/recipes/tools/vercel.d.ts +9 -0
- package/dist/recipes/tools/vercel.js +145 -0
- package/dist/recipes/tools/vercel.js.map +1 -0
- package/dist/recipes/validation.d.ts +17 -0
- package/dist/recipes/validation.js +141 -11
- package/dist/recipes/validation.js.map +1 -1
- package/dist/recipes/workspaceRoot.d.ts +37 -0
- package/dist/recipes/workspaceRoot.js +73 -0
- package/dist/recipes/workspaceRoot.js.map +1 -0
- package/dist/recipes/yamlPositions.d.ts +56 -0
- package/dist/recipes/yamlPositions.js +183 -0
- package/dist/recipes/yamlPositions.js.map +1 -0
- package/dist/recipes/yamlRunner.d.ts +185 -8
- package/dist/recipes/yamlRunner.js +967 -224
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +19 -3
- package/dist/recipesHttp.js +67 -11
- package/dist/recipesHttp.js.map +1 -1
- package/dist/resources.js +21 -13
- package/dist/resources.js.map +1 -1
- package/dist/runLog.d.ts +58 -5
- package/dist/runLog.js +98 -21
- package/dist/runLog.js.map +1 -1
- package/dist/sanitizeParsedJson.d.ts +39 -0
- package/dist/sanitizeParsedJson.js +55 -0
- package/dist/sanitizeParsedJson.js.map +1 -0
- package/dist/schemas/recipe.v1.json +887 -198
- package/dist/server.d.ts +160 -3
- package/dist/server.js +1099 -122
- package/dist/server.js.map +1 -1
- package/dist/sessionCheckpoint.d.ts +8 -0
- package/dist/sessionCheckpoint.js +33 -3
- package/dist/sessionCheckpoint.js.map +1 -1
- package/dist/ssrfGuard.d.ts +16 -0
- package/dist/ssrfGuard.js +87 -4
- package/dist/ssrfGuard.js.map +1 -1
- package/dist/streamableHttp.d.ts +9 -4
- package/dist/streamableHttp.js +76 -20
- package/dist/streamableHttp.js.map +1 -1
- package/dist/telemetry.js +37 -19
- package/dist/telemetry.js.map +1 -1
- package/dist/testing/shadowRun.d.ts +52 -0
- package/dist/testing/shadowRun.js +71 -0
- package/dist/testing/shadowRun.js.map +1 -0
- package/dist/tools/batchLsp.d.ts +3 -0
- package/dist/tools/bridgeDoctor.d.ts +11 -0
- package/dist/tools/bridgeDoctor.js +48 -2
- package/dist/tools/bridgeDoctor.js.map +1 -1
- package/dist/tools/bridgeStatus.d.ts +0 -12
- package/dist/tools/bridgeStatus.js +2 -28
- package/dist/tools/bridgeStatus.js.map +1 -1
- package/dist/tools/cancelClaudeTask.d.ts +1 -0
- package/dist/tools/clipboard.d.ts +2 -0
- package/dist/tools/closeTabs.d.ts +1 -0
- package/dist/tools/codeLens.d.ts +1 -0
- package/dist/tools/createIssueFromAIComment.d.ts +1 -0
- package/dist/tools/ctxGetTaskContext.d.ts +9 -0
- package/dist/tools/ctxGetTaskContext.js +50 -2
- package/dist/tools/ctxGetTaskContext.js.map +1 -1
- package/dist/tools/ctxQueryTraces.js +32 -24
- package/dist/tools/ctxQueryTraces.js.map +1 -1
- package/dist/tools/ctxSaveTrace.d.ts +1 -0
- package/dist/tools/debug.d.ts +4 -0
- package/dist/tools/decorations.d.ts +2 -0
- package/dist/tools/detectUnusedCode.js +9 -7
- package/dist/tools/detectUnusedCode.js.map +1 -1
- package/dist/tools/documentLinks.d.ts +1 -0
- package/dist/tools/editText.d.ts +1 -0
- package/dist/tools/editText.js +2 -1
- package/dist/tools/editText.js.map +1 -1
- package/dist/tools/enrichCommit.d.ts +1 -0
- package/dist/tools/enrichStackTrace.js +11 -5
- package/dist/tools/enrichStackTrace.js.map +1 -1
- package/dist/tools/explainDiagnostic.d.ts +1 -0
- package/dist/tools/explainSymbol.d.ts +1 -0
- package/dist/tools/fileOperations.d.ts +3 -0
- package/dist/tools/fileOperations.js +2 -1
- package/dist/tools/fileOperations.js.map +1 -1
- package/dist/tools/fileWatcher.d.ts +2 -0
- package/dist/tools/fileWatcher.js +8 -2
- package/dist/tools/fileWatcher.js.map +1 -1
- package/dist/tools/findFiles.d.ts +1 -0
- package/dist/tools/fixAllLintErrors.d.ts +1 -0
- package/dist/tools/fixAllLintErrors.js +10 -5
- package/dist/tools/fixAllLintErrors.js.map +1 -1
- package/dist/tools/foldingRanges.d.ts +1 -0
- package/dist/tools/formatDocument.d.ts +1 -0
- package/dist/tools/formatDocument.js +10 -5
- package/dist/tools/formatDocument.js.map +1 -1
- package/dist/tools/generateTests.d.ts +1 -0
- package/dist/tools/getAIComments.d.ts +1 -0
- package/dist/tools/getAnalyticsReport.js +5 -1
- package/dist/tools/getAnalyticsReport.js.map +1 -1
- package/dist/tools/getBufferContent.d.ts +1 -0
- package/dist/tools/getChangeImpact.d.ts +1 -0
- package/dist/tools/getChangeImpact.js +23 -14
- package/dist/tools/getChangeImpact.js.map +1 -1
- package/dist/tools/getClaudeTaskStatus.d.ts +1 -0
- package/dist/tools/getCodeCoverage.d.ts +1 -0
- package/dist/tools/getCodeCoverage.js +32 -14
- package/dist/tools/getCodeCoverage.js.map +1 -1
- package/dist/tools/getCommitsForIssue.d.ts +1 -0
- package/dist/tools/getDebugState.d.ts +1 -0
- package/dist/tools/getDiagnostics.js +32 -29
- package/dist/tools/getDiagnostics.js.map +1 -1
- package/dist/tools/getDiffFromHandoff.js +8 -2
- package/dist/tools/getDiffFromHandoff.js.map +1 -1
- package/dist/tools/getDocumentSymbols.d.ts +1 -0
- package/dist/tools/getGitHotspots.d.ts +1 -0
- package/dist/tools/getGitStatus.js +6 -1
- package/dist/tools/getGitStatus.js.map +1 -1
- package/dist/tools/getImportedSignatures.d.ts +1 -0
- package/dist/tools/getImportedSignatures.js +18 -14
- package/dist/tools/getImportedSignatures.js.map +1 -1
- package/dist/tools/getPRTemplate.d.ts +1 -0
- package/dist/tools/getProjectContext.js +23 -10
- package/dist/tools/getProjectContext.js.map +1 -1
- package/dist/tools/getSymbolHistory.d.ts +1 -0
- package/dist/tools/getToolCapabilities.d.ts +10 -5
- package/dist/tools/getToolCapabilities.js +116 -204
- package/dist/tools/getToolCapabilities.js.map +1 -1
- package/dist/tools/getTypeSignature.d.ts +1 -0
- package/dist/tools/getWorkspaceSettings.d.ts +1 -0
- package/dist/tools/gitWrite.d.ts +11 -0
- package/dist/tools/github/actions.d.ts +2 -0
- package/dist/tools/github/composite.d.ts +4 -1
- package/dist/tools/github/composite.js +7 -7
- package/dist/tools/github/composite.js.map +1 -1
- package/dist/tools/github/issues.d.ts +4 -0
- package/dist/tools/github/pr.d.ts +13 -6
- package/dist/tools/github/pr.js +18 -11
- package/dist/tools/github/pr.js.map +1 -1
- package/dist/tools/handoffNote.d.ts +1 -0
- package/dist/tools/handoffNote.js +2 -1
- package/dist/tools/handoffNote.js.map +1 -1
- package/dist/tools/headless/lspClient.js +3 -0
- package/dist/tools/headless/lspClient.js.map +1 -1
- package/dist/tools/hoverAtCursor.d.ts +1 -0
- package/dist/tools/httpClient.d.ts +2 -0
- package/dist/tools/httpClient.js +38 -71
- package/dist/tools/httpClient.js.map +1 -1
- package/dist/tools/index.js +14 -10
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/inlayHints.d.ts +1 -0
- package/dist/tools/launchQuickTask.d.ts +1 -0
- package/dist/tools/listClaudeTasks.d.ts +1 -0
- package/dist/tools/listClaudeTasks.js +10 -8
- package/dist/tools/listClaudeTasks.js.map +1 -1
- package/dist/tools/listTerminals.d.ts +1 -0
- package/dist/tools/lsp.d.ts +15 -0
- package/dist/tools/lsp.js +17 -0
- package/dist/tools/lsp.js.map +1 -1
- package/dist/tools/navigateToSymbolByName.d.ts +1 -0
- package/dist/tools/openDiff.d.ts +1 -0
- package/dist/tools/openDiff.js +4 -1
- package/dist/tools/openDiff.js.map +1 -1
- package/dist/tools/openFile.d.ts +1 -0
- package/dist/tools/openFile.js +4 -1
- package/dist/tools/openFile.js.map +1 -1
- package/dist/tools/openInBrowser.js +6 -1
- package/dist/tools/openInBrowser.js.map +1 -1
- package/dist/tools/organizeImports.d.ts +1 -0
- package/dist/tools/organizeImports.js +5 -3
- package/dist/tools/organizeImports.js.map +1 -1
- package/dist/tools/performanceReport.js +5 -3
- package/dist/tools/performanceReport.js.map +1 -1
- package/dist/tools/planPersistence.d.ts +3 -0
- package/dist/tools/planPersistence.js +4 -1
- package/dist/tools/planPersistence.js.map +1 -1
- package/dist/tools/previewEdit.d.ts +1 -0
- package/dist/tools/previewEdit.js +31 -5
- package/dist/tools/previewEdit.js.map +1 -1
- package/dist/tools/recentTracesDigest.js +54 -11
- package/dist/tools/recentTracesDigest.js.map +1 -1
- package/dist/tools/refactorAnalyze.d.ts +1 -0
- package/dist/tools/refactorExtractFunction.js +4 -1
- package/dist/tools/refactorExtractFunction.js.map +1 -1
- package/dist/tools/refactorPreview.d.ts +1 -0
- package/dist/tools/refactorPreview.js +10 -2
- package/dist/tools/refactorPreview.js.map +1 -1
- package/dist/tools/replaceBlock.d.ts +1 -0
- package/dist/tools/replaceBlock.js +2 -1
- package/dist/tools/replaceBlock.js.map +1 -1
- package/dist/tools/resumeClaudeTask.d.ts +1 -0
- package/dist/tools/runClaudeTask.d.ts +1 -0
- package/dist/tools/runTests.js +15 -4
- package/dist/tools/runTests.js.map +1 -1
- package/dist/tools/screenshot.d.ts +1 -0
- package/dist/tools/screenshotAndAnnotate.js +6 -2
- package/dist/tools/screenshotAndAnnotate.js.map +1 -1
- package/dist/tools/searchAndReplace.d.ts +1 -0
- package/dist/tools/searchAndReplace.js +21 -12
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/searchTools.d.ts +26 -0
- package/dist/tools/searchTools.js +62 -21
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/searchWorkspace.d.ts +1 -0
- package/dist/tools/selectionRanges.d.ts +1 -0
- package/dist/tools/semanticTokens.d.ts +1 -0
- package/dist/tools/signatureHelp.d.ts +1 -0
- package/dist/tools/spawnWorkspace.js +15 -7
- package/dist/tools/spawnWorkspace.js.map +1 -1
- package/dist/tools/terminal.d.ts +6 -0
- package/dist/tools/testRunners/pytest.js +6 -2
- package/dist/tools/testRunners/pytest.js.map +1 -1
- package/dist/tools/testRunners/vitestJest.js +3 -1
- package/dist/tools/testRunners/vitestJest.js.map +1 -1
- package/dist/tools/testTraceToSource.d.ts +1 -0
- package/dist/tools/transaction.d.ts +13 -1
- package/dist/tools/transaction.js +63 -5
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/typeHierarchy.d.ts +1 -0
- package/dist/tools/utils.d.ts +33 -0
- package/dist/tools/utils.js +122 -18
- package/dist/tools/utils.js.map +1 -1
- package/dist/tools/vscodeCommands.d.ts +2 -0
- package/dist/tools/vscodeTasks.d.ts +2 -0
- package/dist/tools/workspaceSettings.d.ts +1 -0
- package/dist/transport.d.ts +3 -1
- package/dist/transport.js +126 -52
- package/dist/transport.js.map +1 -1
- package/dist/winShim.d.ts +34 -0
- package/dist/winShim.js +94 -0
- package/dist/winShim.js.map +1 -0
- package/dist/wireHaltPushDispatch.d.ts +38 -0
- package/dist/wireHaltPushDispatch.js +71 -0
- package/dist/wireHaltPushDispatch.js.map +1 -0
- package/dist/writeFileAtomic.d.ts +23 -0
- package/dist/writeFileAtomic.js +121 -0
- package/dist/writeFileAtomic.js.map +1 -0
- package/package.json +23 -7
- package/scripts/postinstall.mjs +42 -2
- package/scripts/smoke/run-all.mjs +213 -0
- package/scripts/start-all.mjs +572 -0
- package/scripts/start-all.ps1 +209 -0
- package/scripts/start-all.sh +73 -17
- package/scripts/start-orchestrator.ps1 +158 -0
- package/scripts/start-remote.mjs +122 -0
- package/templates/automation-policies/recipe-authoring.json +1 -1
- package/templates/automation-policies/security-first.json +1 -1
- package/templates/automation-policies/strict-lint.json +1 -1
- package/templates/automation-policies/test-driven.json +1 -1
- package/templates/automation-policy.example.json +1 -1
- package/templates/co.patchwork-os.bridge.plist +2 -2
- package/templates/recipes/approval-queue-ui-test.yaml +1 -1
- package/templates/recipes/ctx-loop-test.yaml +1 -1
- package/templates/recipes/fix-errors-on-save.yaml +71 -0
- package/templates/recipes/morning-brief.yaml +5 -2
- package/templates/recipes/project-health-check.yaml +4 -1
- package/templates/recipes/sentry-to-linear.yaml +72 -38
- package/templates/recipes/webhook/apple-watch-health-log.yaml +145 -0
- package/templates/recipes/webhook/customer-escalation.yaml +8 -9
- package/templates/recipes/webhook/meeting-prep.yaml +11 -5
- package/dist/commands/marketplace.d.ts +0 -16
- package/dist/commands/marketplace.js +0 -32
- package/dist/commands/marketplace.js.map +0 -1
- package/dist/recipes/legacyRecipeCompat.d.ts +0 -10
- package/dist/recipes/legacyRecipeCompat.js +0 -131
- package/dist/recipes/legacyRecipeCompat.js.map +0 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-namespace → connector id (matching the IDs returned by
|
|
3
|
+
* `/connections` — see src/connectors/gmail.ts handleConnectionsList).
|
|
4
|
+
* Both `google-calendar` and the dashboard's `googleCalendar` spelling
|
|
5
|
+
* are accepted on the caller side; this map is authoritative for the
|
|
6
|
+
* bridge.
|
|
7
|
+
*
|
|
8
|
+
* Keys are BARE namespace names (no separator). The matcher accepts BOTH
|
|
9
|
+
* dot-form (`slack.post_message`) and underscore-form (`slack_post_message`)
|
|
10
|
+
* tool IDs. Real registry tools use dot-form
|
|
11
|
+
* (e.g. `src/recipes/tools/slack.ts` registers `slack.post_message`); the
|
|
12
|
+
* previous map keyed by `slack_` etc. silently failed every YAML recipe
|
|
13
|
+
* install because `tool.startsWith("slack_")` never matched `slack.post_message`.
|
|
14
|
+
*/
|
|
15
|
+
export const TOOL_NAMESPACE_TO_CONNECTOR = {
|
|
16
|
+
slack: "slack",
|
|
17
|
+
github: "github",
|
|
18
|
+
jira: "jira",
|
|
19
|
+
linear: "linear",
|
|
20
|
+
gmail: "gmail",
|
|
21
|
+
calendar: "google-calendar",
|
|
22
|
+
drive: "google-drive",
|
|
23
|
+
intercom: "intercom",
|
|
24
|
+
hubspot: "hubspot",
|
|
25
|
+
datadog: "datadog",
|
|
26
|
+
stripe: "stripe",
|
|
27
|
+
sentry: "sentry",
|
|
28
|
+
zendesk: "zendesk",
|
|
29
|
+
asana: "asana",
|
|
30
|
+
notion: "notion",
|
|
31
|
+
confluence: "confluence",
|
|
32
|
+
discord: "discord",
|
|
33
|
+
gitlab: "gitlab",
|
|
34
|
+
pagerduty: "pagerduty",
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use `TOOL_NAMESPACE_TO_CONNECTOR` instead. Kept as a thin
|
|
38
|
+
* alias derived from the canonical map so legacy callers (and the
|
|
39
|
+
* underscore-suffix tool-name shape) keep working until they migrate.
|
|
40
|
+
*/
|
|
41
|
+
export const TOOL_PREFIX_TO_CONNECTOR = Object.fromEntries(Object.entries(TOOL_NAMESPACE_TO_CONNECTOR).map(([ns, connector]) => [
|
|
42
|
+
`${ns}_`,
|
|
43
|
+
connector,
|
|
44
|
+
]));
|
|
45
|
+
/**
|
|
46
|
+
* Extract the namespace prefix from a registered tool ID. Tool IDs land
|
|
47
|
+
* in either `namespace.tool_name` (the canonical dot-form used by every
|
|
48
|
+
* registry entry today — see `src/recipes/tools/*.ts`) or the older
|
|
49
|
+
* `namespace_tool_name` underscore-form some tests use. Either form
|
|
50
|
+
* resolves to the bare namespace, lowercased.
|
|
51
|
+
*/
|
|
52
|
+
function extractNamespace(toolId) {
|
|
53
|
+
const m = toolId.match(/^([a-z][a-z0-9-]*)[_.]/i);
|
|
54
|
+
return m?.[1]?.toLowerCase();
|
|
55
|
+
}
|
|
56
|
+
function toolsOfStep(step) {
|
|
57
|
+
// agent: false steps carry a single `tool` field. agent: true steps
|
|
58
|
+
// optionally list permitted tools in `tools[]`. Other shapes (nested
|
|
59
|
+
// recipe calls, sub-agents) are not first-class in the schema today.
|
|
60
|
+
if (step.agent === false) {
|
|
61
|
+
return [step.tool];
|
|
62
|
+
}
|
|
63
|
+
if (step.agent === true && Array.isArray(step.tools)) {
|
|
64
|
+
return step.tools;
|
|
65
|
+
}
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Compiled list of tool-name prefixes (without the trailing underscore)
|
|
70
|
+
* used by `promptMentionsConnector`. Built once at module load — the
|
|
71
|
+
* source map is small and stable, so caching this avoids regex churn
|
|
72
|
+
* inside the per-step loop.
|
|
73
|
+
*/
|
|
74
|
+
const PROMPT_PREFIX_PATTERNS = Object.entries(TOOL_NAMESPACE_TO_CONNECTOR).map(([prefix, connector]) => ({
|
|
75
|
+
prefix,
|
|
76
|
+
connector,
|
|
77
|
+
}));
|
|
78
|
+
/**
|
|
79
|
+
* Inspect an agent step's `prompt` for references to tool names from
|
|
80
|
+
* known connectors. Catches the common case where the LLM is told
|
|
81
|
+
* which tool to call inside the prompt body rather than via the
|
|
82
|
+
* `tools[]` allowlist — e.g.:
|
|
83
|
+
*
|
|
84
|
+
* - id: notify
|
|
85
|
+
* agent:
|
|
86
|
+
* prompt: Use slack_post_message to send "{{summary}}" to #ops.
|
|
87
|
+
*
|
|
88
|
+
* That prompt previously fell through `toolsOfStep` entirely (no
|
|
89
|
+
* `tool`, empty `tools[]`) and the install panel told the user "no
|
|
90
|
+
* connectors needed" despite the recipe relying on Slack at runtime.
|
|
91
|
+
*
|
|
92
|
+
* Detection is deliberately lossy — we match `<prefix>_` followed by a
|
|
93
|
+
* word char (the literal tool-name shape `slack_post_message`) and we
|
|
94
|
+
* also match `<prefix>.` to catch prose like "use slack.fetch". False
|
|
95
|
+
* positives are tolerable: surfacing one extra "you may want to
|
|
96
|
+
* authorise X" hint is strictly better than the pre-fix silent miss.
|
|
97
|
+
*
|
|
98
|
+
* Audit 2026-05-17.
|
|
99
|
+
*/
|
|
100
|
+
function promptMentionsConnectors(prompt) {
|
|
101
|
+
const found = new Set();
|
|
102
|
+
// Only look at the prompt body — vars / outputs / context refs go
|
|
103
|
+
// through `{{...}}` interpolation which the runtime resolves later.
|
|
104
|
+
for (const { prefix, connector } of PROMPT_PREFIX_PATTERNS) {
|
|
105
|
+
// Anchor on a word boundary so `unrelated_slack_word` doesn't
|
|
106
|
+
// match (\\bslack[_.]\\w would also match `slack_alert`, which is
|
|
107
|
+
// the intended target).
|
|
108
|
+
const re = new RegExp(`\\b${escapeForRegex(prefix)}[_.]\\w`, "i");
|
|
109
|
+
if (re.test(prompt))
|
|
110
|
+
found.add(connector);
|
|
111
|
+
}
|
|
112
|
+
return [...found];
|
|
113
|
+
}
|
|
114
|
+
function escapeForRegex(s) {
|
|
115
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Walk a recipe's steps and return the connector ids it likely needs.
|
|
119
|
+
* Stable order (sorted) so the response is deterministic.
|
|
120
|
+
*/
|
|
121
|
+
export function detectRequiredConnectors(recipe) {
|
|
122
|
+
const required = new Set();
|
|
123
|
+
for (const step of recipe.steps) {
|
|
124
|
+
// Explicit `tool` / `tools[]` fields (canonical detection path).
|
|
125
|
+
// Pull the namespace out of the tool ID — works for both dot-form
|
|
126
|
+
// (the registry's canonical `slack.post_message`) and the legacy
|
|
127
|
+
// underscore-form some tests use (`slack_post_message`).
|
|
128
|
+
for (const tool of toolsOfStep(step)) {
|
|
129
|
+
const ns = extractNamespace(tool);
|
|
130
|
+
if (ns) {
|
|
131
|
+
const connector = TOOL_NAMESPACE_TO_CONNECTOR[ns];
|
|
132
|
+
if (connector)
|
|
133
|
+
required.add(connector);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Prompt body scan for agent-mode steps — catches recipes that
|
|
137
|
+
// tell the LLM which tool to call inline (e.g. "Use slack_post_message
|
|
138
|
+
// to ...") without listing it in `tools[]`. See
|
|
139
|
+
// `promptMentionsConnectors` above for the rationale.
|
|
140
|
+
if (step.agent === true && typeof step.prompt === "string") {
|
|
141
|
+
for (const connector of promptMentionsConnectors(step.prompt)) {
|
|
142
|
+
required.add(connector);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return [...required].sort();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Compare required connectors against the bridge's `/connections`
|
|
150
|
+
* payload. Returns the ids of connectors the recipe needs but the
|
|
151
|
+
* user hasn't connected (or whose status is not "connected").
|
|
152
|
+
*
|
|
153
|
+
* Lenient on input shape — the live `/connections` response has a
|
|
154
|
+
* stable contract, but tests + future surfaces may pass in something
|
|
155
|
+
* shaped slightly differently. Anything we can't classify is treated
|
|
156
|
+
* as "not connected" so a malformed connections payload doesn't
|
|
157
|
+
* silently make every recipe look healthy.
|
|
158
|
+
*/
|
|
159
|
+
export function findMissingConnectors(required, connections) {
|
|
160
|
+
const connectedSet = new Set();
|
|
161
|
+
for (const c of connections) {
|
|
162
|
+
if (typeof c?.id !== "string")
|
|
163
|
+
continue;
|
|
164
|
+
if (c.status === "connected")
|
|
165
|
+
connectedSet.add(c.id);
|
|
166
|
+
}
|
|
167
|
+
return required.filter((id) => !connectedSet.has(id));
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=connectorPreflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectorPreflight.js","sourceRoot":"","sources":["../../src/recipes/connectorPreflight.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,15 @@ export interface DependencyGraph {
|
|
|
16
16
|
steps: StepDependency[];
|
|
17
17
|
hasCycles: boolean;
|
|
18
18
|
topologicalOrder: string[];
|
|
19
|
+
/**
|
|
20
|
+
* `awaits:` targets that reference a step id that does not exist. A
|
|
21
|
+
* phantom target is skipped by cycle-detection (so `hasCycles` stays
|
|
22
|
+
* false) but, if counted in Kahn's in-degree, would silently drop the
|
|
23
|
+
* awaiting step and its dependents from `topologicalOrder` — they'd
|
|
24
|
+
* never run, yet the run would report success. Callers MUST reject the
|
|
25
|
+
* run when this is non-empty. Sorted + de-duplicated.
|
|
26
|
+
*/
|
|
27
|
+
unknownAwaitTargets: string[];
|
|
19
28
|
}
|
|
20
29
|
export interface ExecutionOptions {
|
|
21
30
|
maxConcurrency: number;
|
|
@@ -14,6 +14,19 @@ export function buildDependencyGraph(steps) {
|
|
|
14
14
|
awaits: s.awaits ?? [],
|
|
15
15
|
index,
|
|
16
16
|
}));
|
|
17
|
+
// Collect every declared step id so we can tell a real dependency edge
|
|
18
|
+
// from a phantom one. A phantom `awaits:` target (no matching step) must
|
|
19
|
+
// NOT be counted as an in-degree edge — otherwise Kahn's algorithm never
|
|
20
|
+
// decrements it and silently drops the awaiting step + its dependents
|
|
21
|
+
// from the topological order while the run still reports success.
|
|
22
|
+
const knownStepIds = new Set(nodes.map((n) => n.stepId));
|
|
23
|
+
const unknownTargets = new Set();
|
|
24
|
+
for (const node of nodes) {
|
|
25
|
+
for (const depId of node.awaits) {
|
|
26
|
+
if (!knownStepIds.has(depId))
|
|
27
|
+
unknownTargets.add(depId);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
17
30
|
// Detect cycles using DFS
|
|
18
31
|
const visited = new Set();
|
|
19
32
|
const visiting = new Set();
|
|
@@ -47,8 +60,11 @@ export function buildDependencyGraph(steps) {
|
|
|
47
60
|
const inDegree = new Map();
|
|
48
61
|
const adjacency = new Map();
|
|
49
62
|
for (const node of nodes) {
|
|
50
|
-
|
|
51
|
-
|
|
63
|
+
// Only count edges to REAL steps. Counting phantom targets here is the
|
|
64
|
+
// root cause of the silent-drop bug — see `unknownTargets` above.
|
|
65
|
+
const realAwaits = node.awaits.filter((dep) => knownStepIds.has(dep));
|
|
66
|
+
inDegree.set(node.stepId, realAwaits.length);
|
|
67
|
+
for (const dep of realAwaits) {
|
|
52
68
|
if (!adjacency.has(dep))
|
|
53
69
|
adjacency.set(dep, []);
|
|
54
70
|
adjacency.get(dep)?.push(node.stepId);
|
|
@@ -61,6 +77,7 @@ export function buildDependencyGraph(steps) {
|
|
|
61
77
|
}
|
|
62
78
|
const topologicalOrder = [];
|
|
63
79
|
while (queue.length > 0) {
|
|
80
|
+
// biome-ignore lint/style/noNonNullAssertion: queue.length > 0 guard ensures shift() is defined
|
|
64
81
|
const stepId = queue.shift();
|
|
65
82
|
topologicalOrder.push(stepId);
|
|
66
83
|
const dependents = adjacency.get(stepId) ?? [];
|
|
@@ -75,6 +92,7 @@ export function buildDependencyGraph(steps) {
|
|
|
75
92
|
steps: nodes,
|
|
76
93
|
hasCycles: cycles.length > 0,
|
|
77
94
|
topologicalOrder,
|
|
95
|
+
unknownAwaitTargets: [...unknownTargets].sort(),
|
|
78
96
|
};
|
|
79
97
|
}
|
|
80
98
|
/** Format cycle for error message */
|
|
@@ -163,13 +181,15 @@ export async function executeWithDependencies(graph, executeStep, options) {
|
|
|
163
181
|
resolvers.delete(stepId);
|
|
164
182
|
}
|
|
165
183
|
}
|
|
166
|
-
// Execute with concurrency limit
|
|
184
|
+
// Execute with concurrency limit (clamp to 1 so maxConcurrency:0 or negative never busy-loops)
|
|
185
|
+
const concurrency = Math.max(1, options.maxConcurrency);
|
|
167
186
|
const executing = [];
|
|
168
187
|
const queue = [...graph.topologicalOrder];
|
|
169
188
|
async function processQueue() {
|
|
170
189
|
while (queue.length > 0 || executing.length > 0) {
|
|
171
190
|
// Start new steps if under concurrency limit
|
|
172
|
-
while (executing.length <
|
|
191
|
+
while (executing.length < concurrency && queue.length > 0) {
|
|
192
|
+
// biome-ignore lint/style/noNonNullAssertion: queue.length > 0 guard ensures shift() is defined
|
|
173
193
|
const stepId = queue.shift();
|
|
174
194
|
// C2: push before attaching .then() so indexOf is never -1
|
|
175
195
|
let resolveSlot;
|
|
@@ -192,8 +212,13 @@ export async function executeWithDependencies(graph, executeStep, options) {
|
|
|
192
212
|
}
|
|
193
213
|
/** Get steps that can run immediately (no unresolved dependencies) */
|
|
194
214
|
export function getReadySteps(graph, completed) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
.
|
|
215
|
+
const result = [];
|
|
216
|
+
for (const s of graph.steps) {
|
|
217
|
+
if (!completed.has(s.stepId) &&
|
|
218
|
+
s.awaits.every((dep) => completed.has(dep))) {
|
|
219
|
+
result.push(s.stepId);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return result;
|
|
198
223
|
}
|
|
199
224
|
//# sourceMappingURL=dependencyGraph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencyGraph.js","sourceRoot":"","sources":["../../src/recipes/dependencyGraph.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"dependencyGraph.js","sourceRoot":"","sources":["../../src/recipes/dependencyGraph.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+BH,mDAAmD;AACnD,MAAM,UAAU,oBAAoB,CAClC,KAA+C;IAE/C,MAAM,KAAK,GAAqB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,CAAC,EAAE;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;QACtB,KAAK;KACN,CAAC,CAAC,CAAC;IAEJ,uEAAuE;IACvE,yEAAyE;IACzE,yEAAyE;IACzE,sEAAsE;IACtE,kEAAkE;IAClE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,MAAM,GAAe,EAAE,CAAC;IAE9B,SAAS,KAAK,CAAC,IAAoB,EAAE,IAAc;QACjD,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,wCAAwC;YACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO;QAErC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;YAClD,IAAI,GAAG;gBAAE,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,uEAAuE;QACvE,kEAAkE;QAClE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAChD,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACxC,IAAI,MAAM,KAAK,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,gBAAgB,GAAa,EAAE,CAAC;IACtC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,gGAAgG;QAChG,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC9B,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE9B,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC7B,IAAI,SAAS,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;QAC5B,gBAAgB;QAChB,mBAAmB,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,EAAE;KAChD,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACrD,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;SAC3D,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAsB,EACtB,WAAyB,EACzB,OAAyB;IAEzB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAA+C,CAAC;IACvE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC,CAAC,yCAAyC;IAC3E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,yDAAyD;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAC;IAEvD,uDAAuD;IACvD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,SAAS,WAAW,CAAC,MAAc;QACjC,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,UAAU,OAAO,CAAC,MAAc;QACnC,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO;QAE5D,0CAA0C;QAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,6CAA6C;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,2BAA2B,SAAS,UAAU,CAAC,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACpD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnB,OAAO,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACtC,wCAAwC;YACxC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,KAAK,MAAM,OAAO,IAAI,OAAO;gBAAE,OAAO,EAAE,CAAC;YACzC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QAED,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,OAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YACxD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,+CAA+C;QACrE,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC1C,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1B,oBAAoB;YACpB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,+FAA+F;IAC/F,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE1C,KAAK,UAAU,YAAY;QACzB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,6CAA6C;YAC7C,OAAO,SAAS,CAAC,MAAM,GAAG,WAAW,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1D,gGAAgG;gBAChG,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;gBAC9B,2DAA2D;gBAC3D,IAAI,WAAwB,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;oBACnC,WAAW,GAAG,CAAC,CAAC;gBAClB,CAAC,CAAC,CAAC;gBACH,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;oBACxB,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC7C,WAAW,EAAE,CAAC;gBAChB,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,YAAY,EAAE,CAAC;IACrB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,aAAa,CAC3B,KAAsB,EACtB,SAAsB;IAEtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5B,IACE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACxB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAC3C,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses + allowlists the `github:<owner>/<repo>/(recipes|bundles)/<name>`
|
|
3
|
+
* source format used by `POST /recipes/install`.
|
|
4
|
+
*
|
|
5
|
+
* Before this module existed, the install handler hard-coded
|
|
6
|
+
* `github:patchworkos/recipes/...` everywhere — every URL, every
|
|
7
|
+
* prefix match. Third-party orgs / forks / private mirrors could not
|
|
8
|
+
* host recipe catalogs even though the rest of the install pipeline
|
|
9
|
+
* (SSRF guard, parser, scheduler) is org-agnostic.
|
|
10
|
+
*
|
|
11
|
+
* Allowlist policy:
|
|
12
|
+
* - Always includes `patchworkos/recipes` (backward compat).
|
|
13
|
+
* - Operator opts in additional `<owner>/<repo>` entries via the
|
|
14
|
+
* `PATCHWORK_RECIPE_REPO_ALLOWLIST` env var (comma-separated).
|
|
15
|
+
* - Allowlist matching is case-insensitive (GitHub itself is).
|
|
16
|
+
* - Both owner and repo segments must match the strict regex
|
|
17
|
+
* `[a-z0-9_.-]{1,100}` AFTER lowercasing — guards against
|
|
18
|
+
* traversal segments smuggled into the source string.
|
|
19
|
+
*
|
|
20
|
+
* The default-only behaviour matches the audit recommendation: real
|
|
21
|
+
* multi-org support is opt-in, so existing single-org deployments
|
|
22
|
+
* don't see a behaviour change.
|
|
23
|
+
*/
|
|
24
|
+
export type GithubInstallKind = "recipe" | "bundle";
|
|
25
|
+
export interface ParsedGithubInstallSource {
|
|
26
|
+
kind: GithubInstallKind;
|
|
27
|
+
owner: string;
|
|
28
|
+
repo: string;
|
|
29
|
+
/** Recipe name (single basename) or bundle name. */
|
|
30
|
+
name: string;
|
|
31
|
+
/**
|
|
32
|
+
* Optional git ref (branch / tag / commit SHA) parsed from a trailing
|
|
33
|
+
* `@<ref>` on the name segment. Mirrors the CLI install path
|
|
34
|
+
* (`github:owner/repo[@ref]`). When absent, the URL builders default to
|
|
35
|
+
* `main`. Refs are NOT lowercased — tags/SHAs are case-sensitive.
|
|
36
|
+
*/
|
|
37
|
+
ref?: string;
|
|
38
|
+
}
|
|
39
|
+
export type GithubInstallParseResult = {
|
|
40
|
+
ok: true;
|
|
41
|
+
parsed: ParsedGithubInstallSource;
|
|
42
|
+
} | {
|
|
43
|
+
ok: false;
|
|
44
|
+
code: "bad_shape" | "bad_segment" | "not_allowlisted";
|
|
45
|
+
error: string;
|
|
46
|
+
};
|
|
47
|
+
export declare const SEGMENT_RE: RegExp;
|
|
48
|
+
/**
|
|
49
|
+
* Read the runtime allowlist. Combines the always-on default with
|
|
50
|
+
* whatever the operator has set in PATCHWORK_RECIPE_REPO_ALLOWLIST.
|
|
51
|
+
* Entries are lowercased + de-duplicated; trailing whitespace, empty
|
|
52
|
+
* fragments, and shapes that don't look like `owner/repo` are
|
|
53
|
+
* silently dropped (logging here is the install handler's job, not
|
|
54
|
+
* this pure helper's).
|
|
55
|
+
*/
|
|
56
|
+
export declare function loadAllowlist(env?: NodeJS.ProcessEnv): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Parse a `github:owner/repo/(recipes|bundles)/name` source string
|
|
59
|
+
* against the active allowlist. Pure — does NOT fetch anything; the
|
|
60
|
+
* install handler is responsible for the network leg and the SSRF
|
|
61
|
+
* guard. Returns a discriminated union the caller can map to a 400
|
|
62
|
+
* (bad_shape / bad_segment) or 403 (not_allowlisted) response.
|
|
63
|
+
*/
|
|
64
|
+
export declare function parseGithubInstallSource(source: string, allowlist?: ReadonlyArray<string>): GithubInstallParseResult;
|
|
65
|
+
/**
|
|
66
|
+
* Build the raw.githubusercontent URL for a parsed install source.
|
|
67
|
+
* Uses the pinned `parsed.ref` (branch / tag / commit SHA) when present,
|
|
68
|
+
* else defaults to the `main` branch HEAD.
|
|
69
|
+
*/
|
|
70
|
+
export declare function buildGithubRawUrl(parsed: ParsedGithubInstallSource): string;
|
|
71
|
+
/**
|
|
72
|
+
* Build the `api.github.com` Contents-API URL for a parsed install
|
|
73
|
+
* source. Used as a FALLBACK when `raw.githubusercontent.com` is
|
|
74
|
+
* unreachable — many corporate / proxied networks block the raw host
|
|
75
|
+
* even when `api.github.com` is allowed. Combined with the
|
|
76
|
+
* `Accept: application/vnd.github.raw` request header (see
|
|
77
|
+
* `fetchGithubInstallFile`), this endpoint returns the raw file bytes
|
|
78
|
+
* directly — no base64 decode needed. Public repos work unauthenticated.
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildGithubApiUrl(parsed: ParsedGithubInstallSource): string;
|
|
81
|
+
/**
|
|
82
|
+
* Fetch a recipe / bundle file for a parsed `github:` install source
|
|
83
|
+
* with a raw-host-first, API-fallback strategy.
|
|
84
|
+
*
|
|
85
|
+
* 1. Try `raw.githubusercontent.com` (fast path, no rate limit).
|
|
86
|
+
* 2. If that throws a network error OR returns a non-ok response,
|
|
87
|
+
* fall back to `api.github.com/repos/.../contents/...` with the
|
|
88
|
+
* `Accept: application/vnd.github.raw` header (returns raw bytes).
|
|
89
|
+
*
|
|
90
|
+
* Return contract — designed so the caller's existing error mapping
|
|
91
|
+
* (502 / `fetch_network_error`, 404 not-found, upstream-error) is
|
|
92
|
+
* unchanged:
|
|
93
|
+
*
|
|
94
|
+
* - `{ ok: true, response }` — a usable ok `Response`, from whichever
|
|
95
|
+
* host succeeded. Caller reads the body as before.
|
|
96
|
+
* - `{ ok: false, kind: "not_found", response }` — BOTH hosts agree
|
|
97
|
+
* the file does not exist (raw 404 AND api 404). Caller surfaces
|
|
98
|
+
* this as a genuine not-found (404), not a network error.
|
|
99
|
+
* - `{ ok: false, kind: "upstream_error", response }` — a non-ok,
|
|
100
|
+
* non-404 HTTP response (e.g. 5xx / 403 rate-limit). Caller maps
|
|
101
|
+
* the upstream status as today.
|
|
102
|
+
* - `{ ok: false, kind: "network_error", error }` — both hosts threw
|
|
103
|
+
* a network-level error (DNS / connect / abort). Caller surfaces
|
|
104
|
+
* the existing 502 `fetch_network_error` shape.
|
|
105
|
+
*
|
|
106
|
+
* Intentional edge case: when raw returns 404 but the api fallback
|
|
107
|
+
* *network-errors* (rather than also returning 404), the result is
|
|
108
|
+
* classified `not_found`, not `network_error`. This is a deliberate
|
|
109
|
+
* conservative call — a raw 404 is a strong signal the file is absent,
|
|
110
|
+
* and reporting "not found" is more actionable than a generic network
|
|
111
|
+
* error. Do not "fix" this to prefer network_error without weighing
|
|
112
|
+
* that tradeoff (see the matching test case).
|
|
113
|
+
*
|
|
114
|
+
* `signal` (caller's AbortController) and timeout behaviour are
|
|
115
|
+
* preserved — the same signal is passed to both fetch attempts.
|
|
116
|
+
*/
|
|
117
|
+
export type GithubInstallFetchResult = {
|
|
118
|
+
ok: true;
|
|
119
|
+
response: Response;
|
|
120
|
+
} | {
|
|
121
|
+
ok: false;
|
|
122
|
+
kind: "not_found";
|
|
123
|
+
response: Response;
|
|
124
|
+
} | {
|
|
125
|
+
ok: false;
|
|
126
|
+
kind: "upstream_error";
|
|
127
|
+
response: Response;
|
|
128
|
+
} | {
|
|
129
|
+
ok: false;
|
|
130
|
+
kind: "network_error";
|
|
131
|
+
error: unknown;
|
|
132
|
+
};
|
|
133
|
+
export declare function fetchGithubInstallFile(parsed: ParsedGithubInstallSource, init?: {
|
|
134
|
+
signal?: AbortSignal;
|
|
135
|
+
}): Promise<GithubInstallFetchResult>;
|