patchwork-os 0.2.0-beta.0 → 0.2.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.bridge.md +14 -14
- package/README.md +204 -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.d.ts +5 -1
- package/dist/analyticsAggregator.js +16 -5
- 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 +49 -2
- package/dist/analyticsPrefs.js +177 -19
- 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 +238 -51
- 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.d.ts +0 -16
- package/dist/claudeDriver.js +42 -28
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeMdPatch.d.ts +9 -3
- package/dist/claudeMdPatch.js +79 -13
- package/dist/claudeMdPatch.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +13 -1
- package/dist/claudeOrchestrator.js +89 -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/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 +110 -0
- package/dist/commands/recipe.js +512 -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.js +2 -2
- 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/tracesImport.js +21 -4
- package/dist/commands/tracesImport.js.map +1 -1
- package/dist/commitIssueLinkLog.d.ts +24 -0
- package/dist/commitIssueLinkLog.js +160 -22
- 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 +49 -5
- package/dist/config.js +123 -22
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +913 -413
- 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 +63 -0
- package/dist/connectors/connectorRegistry.js +354 -0
- package/dist/connectors/connectorRegistry.js.map +1 -0
- package/dist/connectors/datadog.js +33 -4
- 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 +245 -2
- 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/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/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 +571 -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 +615 -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.js +15 -6
- 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 +5 -4
- 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.d.ts +12 -2
- package/dist/drivers/claude/subprocess.js +100 -8
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/gemini/api.d.ts +18 -0
- package/dist/drivers/gemini/api.js +29 -0
- package/dist/drivers/gemini/api.js.map +1 -0
- 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/index.d.ts +3 -1
- package/dist/drivers/index.js +9 -1
- package/dist/drivers/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +43 -0
- package/dist/drivers/local/index.js +140 -0
- package/dist/drivers/local/index.js.map +1 -0
- 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 +217 -82
- 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 +29 -1
- 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/httpErrorResponse.d.ts +36 -0
- package/dist/httpErrorResponse.js +46 -0
- package/dist/httpErrorResponse.js.map +1 -0
- package/dist/inboxRoutes.d.ts +22 -0
- package/dist/inboxRoutes.js +151 -12
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1054 -76
- package/dist/index.js.map +1 -1
- package/dist/installGuard.js +6 -2
- package/dist/installGuard.js.map +1 -1
- package/dist/lockfile.js +31 -4
- package/dist/lockfile.js.map +1 -1
- package/dist/oauth.d.ts +22 -0
- package/dist/oauth.js +46 -0
- package/dist/oauth.js.map +1 -1
- package/dist/oauthRoutes.d.ts +1 -1
- package/dist/oauthRoutes.js +8 -11
- package/dist/oauthRoutes.js.map +1 -1
- package/dist/orchestrator/childBridgeRegistry.js +29 -11
- package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
- package/dist/patchworkConfig.d.ts +57 -1
- package/dist/patchworkConfig.js +125 -5
- 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 +10 -3
- 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 +7 -3
- package/dist/prompts.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +9 -0
- package/dist/recipeOrchestration.js +354 -27
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +63 -2
- package/dist/recipeRoutes.js +790 -137
- 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 +34 -5
- package/dist/recipes/agentExecutor.js +5 -4
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/chainedRunner.d.ts +2 -0
- package/dist/recipes/chainedRunner.js +142 -5
- package/dist/recipes/chainedRunner.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.js +13 -5
- package/dist/recipes/dependencyGraph.js.map +1 -1
- package/dist/recipes/githubInstallSource.d.ts +128 -0
- package/dist/recipes/githubInstallSource.js +206 -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 +134 -0
- package/dist/recipes/idempotencyKey.js +322 -0
- package/dist/recipes/idempotencyKey.js.map +1 -0
- package/dist/recipes/installer.js +48 -2
- 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 +88 -5
- 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 +36 -0
- package/dist/recipes/schemaGenerator.js +103 -5
- 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 +20 -3
- package/dist/recipes/toolRegistry.js.map +1 -1
- 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 +45 -6
- 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 +2 -0
- package/dist/recipes/tools/index.js +2 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/slack.js +1 -1
- package/dist/recipes/validation.d.ts +17 -0
- package/dist/recipes/validation.js +29 -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 +195 -8
- package/dist/recipes/yamlRunner.js +877 -209
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +33 -3
- package/dist/recipesHttp.js +126 -12
- 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 +885 -196
- package/dist/server.d.ts +166 -3
- package/dist/server.js +1313 -332
- 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 +19 -12
- 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/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 +79 -202
- 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 +3 -0
- package/dist/tools/github/issues.d.ts +4 -0
- package/dist/tools/github/pr.d.ts +7 -0
- 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/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 +15 -4
- 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/runCommand.js +5 -0
- package/dist/tools/runCommand.js.map +1 -1
- 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 +17 -7
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/searchTools.js +20 -19
- 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/terminal.js +4 -0
- package/dist/tools/terminal.js.map +1 -1
- 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 +4 -0
- package/dist/tools/transaction.js +4 -1
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/typeHierarchy.d.ts +1 -0
- package/dist/tools/utils.d.ts +22 -0
- package/dist/tools/utils.js +158 -14
- 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 +103 -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 +77 -19
- 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 +205 -0
- 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 -11
- package/dist/commands/marketplace.js +0 -120
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drivers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drivers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAoBpD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAgB,EAChB,IAAuB,EACvB,GAA0B;IAE1B,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,IAAI,KAAK,YAAY;QACvB,OAAO,IAAI,gBAAgB,CACzB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,SAAS,EACd,GAAG,EACH,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,IAAI,KAAK,QAAQ;QACnB,OAAO,IAAI,sBAAsB,CAC/B,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EACjD,GAAG,EACH,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reject any LOCAL_ENDPOINT that doesn't resolve to loopback or RFC1918
|
|
4
|
+
* private space. The local driver streams the user prompt + context-file
|
|
5
|
+
* paths to whatever URL is set; if a malicious recipe (or a user pasting
|
|
6
|
+
* a phishy "free local LLM" link) sets `LOCAL_ENDPOINT=https://attacker/v1`,
|
|
7
|
+
* everything the local driver receives gets exfiltrated.
|
|
8
|
+
*
|
|
9
|
+
* Rule: hostname must be one of
|
|
10
|
+
* - localhost / 127.0.0.1 / ::1
|
|
11
|
+
* - RFC1918 private space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
|
|
12
|
+
* - link-local (169.254.0.0/16, fe80::/10)
|
|
13
|
+
* - .local mDNS / .lan / .home / .internal suffixes
|
|
14
|
+
*
|
|
15
|
+
* To opt out (e.g. authorized remote inference cluster), the operator can
|
|
16
|
+
* set LOCAL_ENDPOINT_ALLOW_REMOTE=1 — explicit override, audited via env.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isLoopbackOrPrivateEndpoint(rawUrl: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Local LLM driver — Ollama, LM Studio, vLLM, llama.cpp server, and most
|
|
21
|
+
* other self-hosted runtimes expose an OpenAI-compatible chat-completions
|
|
22
|
+
* endpoint at /v1/chat/completions. Same trick as Grok / Gemini API:
|
|
23
|
+
* subclass OpenAIApiDriver with a different baseURL + default model.
|
|
24
|
+
*
|
|
25
|
+
* Auth: most local runtimes don't validate the API key, but the OpenAI SDK
|
|
26
|
+
* requires *something* in the apiKey field — we send a constant placeholder.
|
|
27
|
+
*
|
|
28
|
+
* Configuration: LOCAL_ENDPOINT and LOCAL_MODEL environment variables.
|
|
29
|
+
* The bridge auto-injects `patchwork.localEndpoint` / `patchwork.localModel`
|
|
30
|
+
* into these env vars at startup (see config.ts), so saving via the
|
|
31
|
+
* dashboard's Local LLM card flows straight through to the driver.
|
|
32
|
+
*
|
|
33
|
+
* Examples:
|
|
34
|
+
* Ollama → http://localhost:11434/v1
|
|
35
|
+
* LM Studio → http://localhost:1234/v1
|
|
36
|
+
* vLLM → http://localhost:8000/v1
|
|
37
|
+
* llama.cpp → http://localhost:8080/v1
|
|
38
|
+
*/
|
|
39
|
+
export declare class LocalApiDriver extends OpenAIApiDriver {
|
|
40
|
+
readonly name = "local";
|
|
41
|
+
constructor(log: (msg: string) => void);
|
|
42
|
+
protected apiKey(): string | undefined;
|
|
43
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reject any LOCAL_ENDPOINT that doesn't resolve to loopback or RFC1918
|
|
4
|
+
* private space. The local driver streams the user prompt + context-file
|
|
5
|
+
* paths to whatever URL is set; if a malicious recipe (or a user pasting
|
|
6
|
+
* a phishy "free local LLM" link) sets `LOCAL_ENDPOINT=https://attacker/v1`,
|
|
7
|
+
* everything the local driver receives gets exfiltrated.
|
|
8
|
+
*
|
|
9
|
+
* Rule: hostname must be one of
|
|
10
|
+
* - localhost / 127.0.0.1 / ::1
|
|
11
|
+
* - RFC1918 private space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
|
|
12
|
+
* - link-local (169.254.0.0/16, fe80::/10)
|
|
13
|
+
* - .local mDNS / .lan / .home / .internal suffixes
|
|
14
|
+
*
|
|
15
|
+
* To opt out (e.g. authorized remote inference cluster), the operator can
|
|
16
|
+
* set LOCAL_ENDPOINT_ALLOW_REMOTE=1 — explicit override, audited via env.
|
|
17
|
+
*/
|
|
18
|
+
export function isLoopbackOrPrivateEndpoint(rawUrl) {
|
|
19
|
+
let host;
|
|
20
|
+
let wasBracketed = false;
|
|
21
|
+
try {
|
|
22
|
+
host = new URL(rawUrl).hostname.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (!host)
|
|
28
|
+
return false;
|
|
29
|
+
// Strip IPv6 brackets if any
|
|
30
|
+
if (host.startsWith("[") && host.endsWith("]")) {
|
|
31
|
+
host = host.slice(1, -1);
|
|
32
|
+
wasBracketed = true;
|
|
33
|
+
}
|
|
34
|
+
if (host === "localhost" || host === "127.0.0.1" || host === "::1") {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
// IPv4 RFC1918 + link-local + 127/8 (check first — strict literal match)
|
|
38
|
+
const v4 = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
39
|
+
if (v4) {
|
|
40
|
+
const a = Number(v4[1]);
|
|
41
|
+
const b = Number(v4[2]);
|
|
42
|
+
if (a === 10)
|
|
43
|
+
return true;
|
|
44
|
+
if (a === 127)
|
|
45
|
+
return true;
|
|
46
|
+
if (a === 169 && b === 254)
|
|
47
|
+
return true;
|
|
48
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
49
|
+
return true;
|
|
50
|
+
if (a === 192 && b === 168)
|
|
51
|
+
return true;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// IPv6 ranges — only when the input looked like an IPv6 literal (was
|
|
55
|
+
// bracketed in the URL, or matches an IPv6 syntactic shape). Without this
|
|
56
|
+
// gate, a hostname like `fc-services.example.com` or `fe8a-test` would
|
|
57
|
+
// match the legacy `startsWith("fc")` / `startsWith("fe8")` checks and
|
|
58
|
+
// bypass the validator. RFC3986 allows IPv6 literals only inside `[…]`,
|
|
59
|
+
// so requiring the brackets is the conservative path.
|
|
60
|
+
if (wasBracketed || /^[0-9a-f:]+$/.test(host)) {
|
|
61
|
+
if (host.startsWith("fe8") ||
|
|
62
|
+
host.startsWith("fe9") ||
|
|
63
|
+
host.startsWith("fea") ||
|
|
64
|
+
host.startsWith("feb")) {
|
|
65
|
+
return true; // link-local fe80::/10
|
|
66
|
+
}
|
|
67
|
+
if (host.startsWith("fc") || host.startsWith("fd")) {
|
|
68
|
+
return true; // unique-local fc00::/7
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// mDNS / common LAN suffixes — checked LAST and require a leading dot
|
|
72
|
+
// boundary so attacker-registered public domains like `evil.com.local`
|
|
73
|
+
// don't slip through (`.local` and `.lan` are not reserved TLDs at the
|
|
74
|
+
// DNS resolver level — only RFC6762 reserves them for mDNS, but public
|
|
75
|
+
// resolvers will happily look them up).
|
|
76
|
+
//
|
|
77
|
+
// The trade-off: a host literally named `printer.local` (single label
|
|
78
|
+
// before `.local`) is the legitimate mDNS form and matches; a host like
|
|
79
|
+
// `evil.com.local` (two-or-more labels before `.local`) is only the
|
|
80
|
+
// mDNS form by accident and is the bypass we're rejecting.
|
|
81
|
+
for (const suffix of [".local", ".lan", ".home", ".internal"]) {
|
|
82
|
+
if (host.endsWith(suffix)) {
|
|
83
|
+
const labels = host.split(".");
|
|
84
|
+
// 2 labels exactly: `<name>.local` — legitimate mDNS shape.
|
|
85
|
+
if (labels.length === 2)
|
|
86
|
+
return true;
|
|
87
|
+
// More labels: ambiguous — refuse by default. Operator can opt out
|
|
88
|
+
// via LOCAL_ENDPOINT_ALLOW_REMOTE for legitimate multi-label
|
|
89
|
+
// internal DNS zones (e.g. `service.team.internal`).
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Local LLM driver — Ollama, LM Studio, vLLM, llama.cpp server, and most
|
|
96
|
+
* other self-hosted runtimes expose an OpenAI-compatible chat-completions
|
|
97
|
+
* endpoint at /v1/chat/completions. Same trick as Grok / Gemini API:
|
|
98
|
+
* subclass OpenAIApiDriver with a different baseURL + default model.
|
|
99
|
+
*
|
|
100
|
+
* Auth: most local runtimes don't validate the API key, but the OpenAI SDK
|
|
101
|
+
* requires *something* in the apiKey field — we send a constant placeholder.
|
|
102
|
+
*
|
|
103
|
+
* Configuration: LOCAL_ENDPOINT and LOCAL_MODEL environment variables.
|
|
104
|
+
* The bridge auto-injects `patchwork.localEndpoint` / `patchwork.localModel`
|
|
105
|
+
* into these env vars at startup (see config.ts), so saving via the
|
|
106
|
+
* dashboard's Local LLM card flows straight through to the driver.
|
|
107
|
+
*
|
|
108
|
+
* Examples:
|
|
109
|
+
* Ollama → http://localhost:11434/v1
|
|
110
|
+
* LM Studio → http://localhost:1234/v1
|
|
111
|
+
* vLLM → http://localhost:8000/v1
|
|
112
|
+
* llama.cpp → http://localhost:8080/v1
|
|
113
|
+
*/
|
|
114
|
+
export class LocalApiDriver extends OpenAIApiDriver {
|
|
115
|
+
name = "local";
|
|
116
|
+
constructor(log) {
|
|
117
|
+
const baseURL = process.env.LOCAL_ENDPOINT;
|
|
118
|
+
if (!baseURL) {
|
|
119
|
+
throw new Error("LocalApiDriver requires LOCAL_ENDPOINT environment variable (e.g. http://localhost:11434/v1)");
|
|
120
|
+
}
|
|
121
|
+
if (process.env.LOCAL_ENDPOINT_ALLOW_REMOTE !== "1" &&
|
|
122
|
+
!isLoopbackOrPrivateEndpoint(baseURL)) {
|
|
123
|
+
throw new Error(`LocalApiDriver: LOCAL_ENDPOINT="${baseURL}" is not loopback or private. ` +
|
|
124
|
+
`The local driver streams prompts + context to this URL — a public host ` +
|
|
125
|
+
`would exfiltrate them. Set LOCAL_ENDPOINT_ALLOW_REMOTE=1 to override ` +
|
|
126
|
+
`(only for audited internal inference clusters).`);
|
|
127
|
+
}
|
|
128
|
+
super(log, {
|
|
129
|
+
baseURL,
|
|
130
|
+
// Per-install default — caller can still override via input.model.
|
|
131
|
+
defaultModel: process.env.LOCAL_MODEL ?? "llama3.2",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
apiKey() {
|
|
135
|
+
// Most local runtimes ignore the key but the OpenAI SDK requires a
|
|
136
|
+
// non-empty value. "ollama" is the conventional placeholder.
|
|
137
|
+
return process.env.LOCAL_API_KEY ?? "ollama";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/local/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,16 @@ export class OpenAIApiDriver {
|
|
|
17
17
|
if (!process.env.OPENAI_API_KEY && !opts.baseURL) {
|
|
18
18
|
throw new Error("OpenAIApiDriver requires OPENAI_API_KEY environment variable");
|
|
19
19
|
}
|
|
20
|
+
// Subclasses (Grok, Gemini, Local) MUST set their own defaultModel —
|
|
21
|
+
// a bare OpenAI driver defaults to gpt-4o here, but a subclass that
|
|
22
|
+
// overrides baseURL without defaultModel would otherwise silently dial
|
|
23
|
+
// the foreign endpoint asking for gpt-4o (which doesn't exist on Grok,
|
|
24
|
+
// Gemini, or local LLMs) and surface as a confusing 404 / phantom-model
|
|
25
|
+
// error far from the actual misconfiguration.
|
|
26
|
+
if (opts.baseURL && !opts.defaultModel) {
|
|
27
|
+
throw new Error("OpenAIApiDriver: subclass must set defaultModel when baseURL is " +
|
|
28
|
+
"overridden — bare 'gpt-4o' fallback only applies to OpenAI's API.");
|
|
29
|
+
}
|
|
20
30
|
}
|
|
21
31
|
async run(input) {
|
|
22
32
|
// biome-ignore lint/suspicious/noExplicitAny: dynamic import of optional peer dep
|
|
@@ -71,10 +81,28 @@ export class OpenAIApiDriver {
|
|
|
71
81
|
if (delta) {
|
|
72
82
|
if (firstChunkAt === undefined)
|
|
73
83
|
firstChunkAt = Date.now();
|
|
74
|
-
text
|
|
75
|
-
|
|
84
|
+
if (text.length < OUTPUT_CAP) {
|
|
85
|
+
// Cap accumulation in-loop to bound memory under runaway streams
|
|
86
|
+
// (e.g. local LLMs that loop). Once we hit the cap, stop appending
|
|
87
|
+
// and abort the upstream stream so sockets and decoder buffers
|
|
88
|
+
// are released. onChunk is gated by the same cap so partial
|
|
89
|
+
// listeners stop receiving deltas.
|
|
90
|
+
text += delta;
|
|
76
91
|
input.onChunk?.(delta);
|
|
77
92
|
}
|
|
93
|
+
else {
|
|
94
|
+
// biome-ignore lint/suspicious/noExplicitAny: stream shape
|
|
95
|
+
const ctrl = stream.controller;
|
|
96
|
+
if (ctrl && typeof ctrl.abort === "function") {
|
|
97
|
+
try {
|
|
98
|
+
ctrl.abort();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* best effort */
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
78
106
|
}
|
|
79
107
|
}
|
|
80
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/openai/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/openai/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -154,6 +154,15 @@ export declare class ExtensionClient {
|
|
|
154
154
|
* for that, do a runtime shape check in the client method.
|
|
155
155
|
*/
|
|
156
156
|
private tryRequest;
|
|
157
|
+
/**
|
|
158
|
+
* Like tryRequest, but preserves the extension error message instead of
|
|
159
|
+
* collapsing it to null. Use when the caller wants to surface the upstream
|
|
160
|
+
* error (e.g. report "format provider errored: X" instead of silently
|
|
161
|
+
* falling back to a CLI tool). Returns an envelope so the success-path
|
|
162
|
+
* value is still typed and the historical `value === null` check works
|
|
163
|
+
* unchanged.
|
|
164
|
+
*/
|
|
165
|
+
private tryRequestWithError;
|
|
157
166
|
/**
|
|
158
167
|
* Shape-validated request — handles shape-wrap bugs where the extension
|
|
159
168
|
* handler returns a different structural shape than the client expects
|
|
@@ -191,7 +200,11 @@ export declare class ExtensionClient {
|
|
|
191
200
|
getHover(file: string, line: number, column: number, signal?: AbortSignal): Promise<unknown>;
|
|
192
201
|
getCodeActions(file: string, startLine: number, startColumn: number, endLine: number, endColumn: number, signal?: AbortSignal): Promise<unknown>;
|
|
193
202
|
applyCodeAction(file: string, startLine: number, startColumn: number, endLine: number, endColumn: number, actionTitle: string, signal?: AbortSignal): Promise<unknown>;
|
|
194
|
-
previewCodeAction(file: string, startLine: number, startColumn: number, endLine: number, endColumn: number, actionTitle: string, signal?: AbortSignal): Promise<
|
|
203
|
+
previewCodeAction(file: string, startLine: number, startColumn: number, endLine: number, endColumn: number, actionTitle: string, signal?: AbortSignal): Promise<{
|
|
204
|
+
value: unknown;
|
|
205
|
+
error: string | null;
|
|
206
|
+
errorData: Record<string, unknown> | null;
|
|
207
|
+
}>;
|
|
195
208
|
renameSymbol(file: string, line: number, column: number, newName: string, signal?: AbortSignal): Promise<unknown>;
|
|
196
209
|
searchSymbols(query: string, maxResults?: number, signal?: AbortSignal): Promise<unknown>;
|
|
197
210
|
prepareRename(file: string, line: number, column: number, signal?: AbortSignal): Promise<unknown>;
|
|
@@ -215,9 +228,21 @@ export declare class ExtensionClient {
|
|
|
215
228
|
replaceBlock(filePath: string, oldContent: string, newContent: string, save?: boolean): Promise<unknown>;
|
|
216
229
|
getDocumentSymbols(file: string, signal?: AbortSignal): Promise<unknown>;
|
|
217
230
|
getCallHierarchy(file: string, line: number, column: number, direction?: string, maxResults?: number, signal?: AbortSignal): Promise<unknown>;
|
|
218
|
-
formatDocument(file: string): Promise<
|
|
219
|
-
|
|
220
|
-
|
|
231
|
+
formatDocument(file: string): Promise<{
|
|
232
|
+
value: unknown;
|
|
233
|
+
error: string | null;
|
|
234
|
+
errorData: Record<string, unknown> | null;
|
|
235
|
+
}>;
|
|
236
|
+
fixAllLintErrors(file: string): Promise<{
|
|
237
|
+
value: unknown;
|
|
238
|
+
error: string | null;
|
|
239
|
+
errorData: Record<string, unknown> | null;
|
|
240
|
+
}>;
|
|
241
|
+
organizeImports(file: string): Promise<{
|
|
242
|
+
value: unknown;
|
|
243
|
+
error: string | null;
|
|
244
|
+
errorData: Record<string, unknown> | null;
|
|
245
|
+
}>;
|
|
221
246
|
createTerminal(name?: string, cwd?: string, env?: Record<string, string>, show?: boolean): Promise<unknown>;
|
|
222
247
|
sendTerminalCommand(text: string, name?: string, index?: number, addNewline?: boolean): Promise<unknown>;
|
|
223
248
|
waitForTerminalOutput(pattern: string, name?: string, index?: number, timeoutMs?: number): Promise<unknown>;
|
|
@@ -269,6 +294,14 @@ export declare class ExtensionClient {
|
|
|
269
294
|
openCount: number;
|
|
270
295
|
lastOpenedAt: string | null;
|
|
271
296
|
};
|
|
297
|
+
/**
|
|
298
|
+
* Tracks whether the connected extension has a protocol-major-version
|
|
299
|
+
* mismatch with the bridge. When set, `isConnected()` returns false so
|
|
300
|
+
* `extensionRequired` tools fail fast with a clear "extension protocol
|
|
301
|
+
* mismatch" error instead of attempting requests that would silently
|
|
302
|
+
* misbehave (e.g. handler accepting a v1 shape but bridge sending v2).
|
|
303
|
+
*/
|
|
304
|
+
private extensionProtocolMismatch;
|
|
272
305
|
isConnected(): boolean;
|
|
273
306
|
/**
|
|
274
307
|
* Push a server-initiated notification to the connected extension.
|
package/dist/extensionClient.js
CHANGED
|
@@ -144,6 +144,9 @@ export class ExtensionClient {
|
|
|
144
144
|
this.diagnosticsListeners.clear();
|
|
145
145
|
// Clear LSP readiness — language servers may need to re-index after reconnect
|
|
146
146
|
this.lspReadyLanguages.clear();
|
|
147
|
+
// Reset protocol-mismatch flag so a fresh hello on reconnect can
|
|
148
|
+
// re-evaluate compatibility (operator may have updated the extension).
|
|
149
|
+
this.extensionProtocolMismatch = false;
|
|
147
150
|
this.logger.info(`Extension disconnected: ${reason}`);
|
|
148
151
|
this.safeCallback(this.onExtensionDisconnected);
|
|
149
152
|
};
|
|
@@ -326,9 +329,20 @@ export class ExtensionClient {
|
|
|
326
329
|
const bridgeMajor = Number.parseInt(BRIDGE_PROTOCOL_VERSION.split(".")[0] ?? "", 10);
|
|
327
330
|
if (Number.isNaN(extMajor)) {
|
|
328
331
|
this.logger.debug(`Extension protocol version "${extVer}" is not a recognized semver format, skipping version check`);
|
|
332
|
+
this.extensionProtocolMismatch = false;
|
|
329
333
|
}
|
|
330
334
|
else if (extMajor !== bridgeMajor) {
|
|
331
|
-
|
|
335
|
+
// Mark the extension as unavailable. Without this, the bridge
|
|
336
|
+
// would proceed sending requests of one protocol-major to a
|
|
337
|
+
// handler of another, surfacing as opaque field-shape errors
|
|
338
|
+
// far from the actual cause. `extensionRequired` tools fail
|
|
339
|
+
// fast with a clear isError content block.
|
|
340
|
+
this.logger.error(`Extension protocol major version mismatch: bridge=${BRIDGE_PROTOCOL_VERSION}, extension=${extVer}. ` +
|
|
341
|
+
`Marking extension as unavailable. Update the VS Code extension to a build whose protocolVersion major matches the bridge.`);
|
|
342
|
+
this.extensionProtocolMismatch = true;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
this.extensionProtocolMismatch = false;
|
|
332
346
|
}
|
|
333
347
|
break;
|
|
334
348
|
}
|
|
@@ -658,6 +672,23 @@ export class ExtensionClient {
|
|
|
658
672
|
return null;
|
|
659
673
|
return raw;
|
|
660
674
|
}
|
|
675
|
+
/**
|
|
676
|
+
* Like tryRequest, but preserves the extension error message instead of
|
|
677
|
+
* collapsing it to null. Use when the caller wants to surface the upstream
|
|
678
|
+
* error (e.g. report "format provider errored: X" instead of silently
|
|
679
|
+
* falling back to a CLI tool). Returns an envelope so the success-path
|
|
680
|
+
* value is still typed and the historical `value === null` check works
|
|
681
|
+
* unchanged.
|
|
682
|
+
*/
|
|
683
|
+
async tryRequestWithError(method, params, timeout, signal) {
|
|
684
|
+
const raw = await this.requestOrNull(method, params, timeout, signal);
|
|
685
|
+
if (this.isErrorResponse(raw)) {
|
|
686
|
+
const obj = raw;
|
|
687
|
+
const msg = typeof obj.error === "string" ? obj.error : "extension error";
|
|
688
|
+
return { value: null, error: msg, errorData: obj };
|
|
689
|
+
}
|
|
690
|
+
return { value: raw, error: null, errorData: null };
|
|
691
|
+
}
|
|
661
692
|
/**
|
|
662
693
|
* Shape-validated request — handles shape-wrap bugs where the extension
|
|
663
694
|
* handler returns a different structural shape than the client expects
|
|
@@ -781,7 +812,7 @@ export class ExtensionClient {
|
|
|
781
812
|
return this.validatedRequest("extension/getHover", { file, line, column }, (r) => {
|
|
782
813
|
const o = r;
|
|
783
814
|
return Array.isArray(o.contents) ? r : null;
|
|
784
|
-
},
|
|
815
|
+
}, 12_000, signal);
|
|
785
816
|
}
|
|
786
817
|
// handler returns { actions: [{title, kind?, isPreferred}] } — validated
|
|
787
818
|
async getCodeActions(file, startLine, startColumn, endLine, endColumn, signal) {
|
|
@@ -797,9 +828,10 @@ export class ExtensionClient {
|
|
|
797
828
|
return typeof o.applied === "boolean" ? r : null;
|
|
798
829
|
}, undefined, signal);
|
|
799
830
|
}
|
|
800
|
-
// handler returns { title, changes, ... } | { error } —
|
|
831
|
+
// handler returns { title, changes, ... } | { error, available? } — preserve error so
|
|
832
|
+
// callers can include the upstream message (and `available` list) in their failure reply
|
|
801
833
|
async previewCodeAction(file, startLine, startColumn, endLine, endColumn, actionTitle, signal) {
|
|
802
|
-
return this.
|
|
834
|
+
return this.tryRequestWithError("extension/previewCodeAction", { file, startLine, startColumn, endLine, endColumn, actionTitle }, 15_000, signal);
|
|
803
835
|
}
|
|
804
836
|
// handler returns { success, newName?, affectedFiles?, totalEdits?, error? } — rich contract, caller needs success field
|
|
805
837
|
async renameSymbol(file, line, column, newName, signal) {
|
|
@@ -924,7 +956,7 @@ export class ExtensionClient {
|
|
|
924
956
|
return this.validatedRequest("extension/getDocumentSymbols", { file }, (r) => {
|
|
925
957
|
const o = r;
|
|
926
958
|
return Array.isArray(o.symbols) ? r : null;
|
|
927
|
-
},
|
|
959
|
+
}, 15_000, signal);
|
|
928
960
|
}
|
|
929
961
|
// handler returns { symbol, incoming?, outgoing? } | null — validated
|
|
930
962
|
async getCallHierarchy(file, line, column, direction, maxResults, signal) {
|
|
@@ -934,20 +966,17 @@ export class ExtensionClient {
|
|
|
934
966
|
}, 15_000, signal);
|
|
935
967
|
}
|
|
936
968
|
// --- Code Actions (format, fix, organize) ---
|
|
969
|
+
// Extension returns { error: "..." } on failure. Envelope preserves the
|
|
970
|
+
// error string so callers can surface it before falling back to a CLI tool
|
|
971
|
+
// (previously the message was silently dropped — see [extension-shape] audit).
|
|
937
972
|
async formatDocument(file) {
|
|
938
|
-
|
|
939
|
-
// tryRequest unwraps to null so consumers' `!== null` check falls through
|
|
940
|
-
// to their CLI formatter fallback instead of reporting false success.
|
|
941
|
-
return this.tryRequest("extension/formatDocument", { file }, 15_000);
|
|
973
|
+
return this.tryRequestWithError("extension/formatDocument", { file }, 15_000);
|
|
942
974
|
}
|
|
943
975
|
async fixAllLintErrors(file) {
|
|
944
|
-
|
|
945
|
-
// unwraps to null so consumers fall through to their CLI fallback.
|
|
946
|
-
return this.tryRequest("extension/fixAllLintErrors", { file }, 15_000);
|
|
976
|
+
return this.tryRequestWithError("extension/fixAllLintErrors", { file }, 15_000);
|
|
947
977
|
}
|
|
948
|
-
// handler returns { success: true, actionsApplied } | { error } — tryRequest (error-obj on failure)
|
|
949
978
|
async organizeImports(file) {
|
|
950
|
-
return this.
|
|
979
|
+
return this.tryRequestWithError("extension/organizeImports", { file }, 15_000);
|
|
951
980
|
}
|
|
952
981
|
// --- Terminal Control ---
|
|
953
982
|
// handler returns { success: true, name, index } — validatedRequest
|
|
@@ -1177,7 +1206,12 @@ export class ExtensionClient {
|
|
|
1177
1206
|
this.latestDiagnosticsUpdatedAt.delete(f);
|
|
1178
1207
|
}
|
|
1179
1208
|
}
|
|
1180
|
-
|
|
1209
|
+
const result = [];
|
|
1210
|
+
for (const diags of this.latestDiagnostics.values()) {
|
|
1211
|
+
for (const d of diags)
|
|
1212
|
+
result.push(d);
|
|
1213
|
+
}
|
|
1214
|
+
return result;
|
|
1181
1215
|
}
|
|
1182
1216
|
addDiagnosticsListener(listener) {
|
|
1183
1217
|
this.diagnosticsListeners.add(listener);
|
|
@@ -1226,8 +1260,16 @@ export class ExtensionClient {
|
|
|
1226
1260
|
lastOpenedAt: this._lastCircuitOpenedAt?.toISOString() ?? null,
|
|
1227
1261
|
};
|
|
1228
1262
|
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Tracks whether the connected extension has a protocol-major-version
|
|
1265
|
+
* mismatch with the bridge. When set, `isConnected()` returns false so
|
|
1266
|
+
* `extensionRequired` tools fail fast with a clear "extension protocol
|
|
1267
|
+
* mismatch" error instead of attempting requests that would silently
|
|
1268
|
+
* misbehave (e.g. handler accepting a v1 shape but bridge sending v2).
|
|
1269
|
+
*/
|
|
1270
|
+
extensionProtocolMismatch = false;
|
|
1229
1271
|
isConnected() {
|
|
1230
|
-
return this.connected;
|
|
1272
|
+
return this.connected && !this.extensionProtocolMismatch;
|
|
1231
1273
|
}
|
|
1232
1274
|
/**
|
|
1233
1275
|
* Push a server-initiated notification to the connected extension.
|