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
package/dist/bridge.js
CHANGED
|
@@ -5,7 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import { WebSocket } from "ws";
|
|
6
6
|
import { ActivityLog } from "./activityLog.js";
|
|
7
7
|
import { buildSummary } from "./analyticsAggregator.js";
|
|
8
|
-
import { getAnalyticsPref } from "./analyticsPrefs.js";
|
|
8
|
+
import { getAnalyticsPref, getAnalyticsSalt } from "./analyticsPrefs.js";
|
|
9
9
|
import { sendAnalytics } from "./analyticsSend.js";
|
|
10
10
|
import { getApprovalQueue } from "./approvalQueue.js";
|
|
11
11
|
import { AutomationHooks, loadPolicy } from "./automation.js";
|
|
@@ -16,18 +16,20 @@ import { CommitIssueLinkLog } from "./commitIssueLinkLog.js";
|
|
|
16
16
|
import { DecisionTraceLog } from "./decisionTraceLog.js";
|
|
17
17
|
import { createDriver } from "./drivers/index.js";
|
|
18
18
|
import { ExtensionClient } from "./extensionClient.js";
|
|
19
|
-
import { lockKillSwitchEnv } from "./featureFlags.js";
|
|
19
|
+
import { lockKillSwitchEnv, watchFlags } from "./featureFlags.js";
|
|
20
20
|
import { FileLock } from "./fileLock.js";
|
|
21
21
|
import { buildEnforcementReminder } from "./instructionsUtils.js";
|
|
22
22
|
import { LockFileManager } from "./lockfile.js";
|
|
23
23
|
import { Logger } from "./logger.js";
|
|
24
24
|
import { OAuthServerImpl } from "./oauth.js";
|
|
25
|
-
import { loadConfig as loadPatchworkConfig } from "./patchworkConfig.js";
|
|
25
|
+
import { defaultConfigPath, getApiKeysPresent, loadConfig as loadPatchworkConfig, } from "./patchworkConfig.js";
|
|
26
26
|
import { loadPlugins, loadPluginsFull } from "./pluginLoader.js";
|
|
27
27
|
import { PluginWatcher } from "./pluginWatcher.js";
|
|
28
28
|
import { isPreToolUseHookRegistered } from "./preToolUseHook.js";
|
|
29
29
|
import { probeAll } from "./probe.js";
|
|
30
30
|
import { RecipeOrchestration } from "./recipeOrchestration.js";
|
|
31
|
+
import { haltSummaryToPrometheus, summariseHalts, } from "./recipes/haltCategory.js";
|
|
32
|
+
import { judgeSummaryToPrometheus, summariseJudgments, } from "./recipes/judgeSummary.js";
|
|
31
33
|
import { warnAboutLegacyPermissionsSidecars } from "./recipes/migrationWarnings.js";
|
|
32
34
|
import { RecipeOrchestrator } from "./recipes/RecipeOrchestrator.js";
|
|
33
35
|
import { classifyTool } from "./riskTier.js";
|
|
@@ -45,6 +47,7 @@ import { buildRecentTracesDigest } from "./tools/recentTracesDigest.js";
|
|
|
45
47
|
import { resolveFilePath } from "./tools/utils.js";
|
|
46
48
|
import { McpTransport } from "./transport.js";
|
|
47
49
|
import { PACKAGE_VERSION } from "./version.js";
|
|
50
|
+
import { wireHaltPushDispatch } from "./wireHaltPushDispatch.js";
|
|
48
51
|
const SHUTDOWN_TIMEOUT_MS = 5000;
|
|
49
52
|
let globalHandlersRegistered = false;
|
|
50
53
|
/** Collect the union of openedFiles across all sessions in a checkpoint. */
|
|
@@ -143,8 +146,9 @@ export class Bridge {
|
|
|
143
146
|
this.lockFile = new LockFileManager(this.logger);
|
|
144
147
|
const configDir = process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
|
|
145
148
|
this.authToken = config.fixedToken ?? loadOrCreateBridgeToken(configDir);
|
|
146
|
-
this.server = new Server(this.authToken, this.logger, config.corsOrigins);
|
|
149
|
+
this.server = new Server(this.authToken, this.logger, config.corsOrigins, undefined, config.trustedProxies);
|
|
147
150
|
this.server.bridgeConfigPath = config.configFilePath ?? undefined;
|
|
151
|
+
this.server.webhookSecret = config.webhookSecret ?? null;
|
|
148
152
|
if (config.issuerUrl) {
|
|
149
153
|
this.oauthServer = new OAuthServerImpl(this.authToken, config.issuerUrl, {
|
|
150
154
|
configDir,
|
|
@@ -245,7 +249,11 @@ export class Bridge {
|
|
|
245
249
|
}
|
|
246
250
|
// ─────────────────────────────────────────────────────────────────────
|
|
247
251
|
// Reject connections beyond capacity (grace-period sessions don't count)
|
|
248
|
-
|
|
252
|
+
let activeSessionCount = 0;
|
|
253
|
+
for (const s of this.sessions.values()) {
|
|
254
|
+
if (!s.graceTimer)
|
|
255
|
+
activeSessionCount++;
|
|
256
|
+
}
|
|
249
257
|
if (activeSessionCount >= this.config.maxSessions) {
|
|
250
258
|
this.logger.warn(`Session capacity reached (${this.config.maxSessions} active). Rejecting connection.`);
|
|
251
259
|
ws.close(1013, "Bridge at capacity");
|
|
@@ -493,10 +501,15 @@ export class Bridge {
|
|
|
493
501
|
// Detect false→true transition (session started)
|
|
494
502
|
if (!this._lastDebugSessionActive && state.hasActiveSession) {
|
|
495
503
|
const breakpoints = state.breakpoints ?? [];
|
|
504
|
+
let enabledBreakpoints = 0;
|
|
505
|
+
for (const b of breakpoints) {
|
|
506
|
+
if (b.enabled)
|
|
507
|
+
enabledBreakpoints++;
|
|
508
|
+
}
|
|
496
509
|
this.automationHooks?.handleDebugSessionStart({
|
|
497
510
|
sessionName: state.sessionName ?? "unknown",
|
|
498
511
|
sessionType: state.sessionType ?? "unknown",
|
|
499
|
-
breakpointCount:
|
|
512
|
+
breakpointCount: enabledBreakpoints,
|
|
500
513
|
activeFile: breakpoints[0]?.file ?? "",
|
|
501
514
|
});
|
|
502
515
|
}
|
|
@@ -534,8 +547,14 @@ export class Bridge {
|
|
|
534
547
|
let warnings = 0;
|
|
535
548
|
const errorFiles = [];
|
|
536
549
|
for (const [file, diags] of this.extensionClient.latestDiagnostics) {
|
|
537
|
-
|
|
538
|
-
|
|
550
|
+
let e = 0;
|
|
551
|
+
let w = 0;
|
|
552
|
+
for (const d of diags) {
|
|
553
|
+
if (d.severity === "error")
|
|
554
|
+
e++;
|
|
555
|
+
else if (d.severity === "warning")
|
|
556
|
+
w++;
|
|
557
|
+
}
|
|
539
558
|
errors += e;
|
|
540
559
|
warnings += w;
|
|
541
560
|
if (e > 0)
|
|
@@ -580,6 +599,8 @@ export class Bridge {
|
|
|
580
599
|
}
|
|
581
600
|
/** Write a periodic auto-snapshot while sessions are active (every 5 minutes). */
|
|
582
601
|
_periodicSnapshotTimer = null;
|
|
602
|
+
/** Cleanup handle for `watchFlags()` — set in start(), invoked in stop(). */
|
|
603
|
+
_stopFlagsWatch = null;
|
|
583
604
|
_startPeriodicSnapshots() {
|
|
584
605
|
if (this._periodicSnapshotTimer)
|
|
585
606
|
return;
|
|
@@ -721,6 +742,10 @@ export class Bridge {
|
|
|
721
742
|
// recipe steps mutating `process.env.PATCHWORK_FLAG_*` cannot disable an
|
|
722
743
|
// active emergency stop. Closes MED-2 from the 2026-04-28 audit.
|
|
723
744
|
lockKillSwitchEnv();
|
|
745
|
+
// 0a-bis. Watch flags.json for cross-process changes — picks up CLI
|
|
746
|
+
// fallback writes and sibling-bridge updates in a multi-bridge fleet.
|
|
747
|
+
// v2-S1 + v2-B2 from issue #422.
|
|
748
|
+
this._stopFlagsWatch = watchFlags();
|
|
724
749
|
// 0b. Auto-repair .claude/rules/bridge-tools.md if stale (present but missing the
|
|
725
750
|
// current version sentinel). Older package versions write stale files that may
|
|
726
751
|
// lack new tool substitution rules. Repair is silent on success; falls back to
|
|
@@ -752,13 +777,15 @@ export class Bridge {
|
|
|
752
777
|
const driver = createDriver(this.config.driver, {
|
|
753
778
|
binary: this.config.claudeBinary,
|
|
754
779
|
antBinary: this.config.antBinary,
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
:
|
|
780
|
+
// Provided to all subprocess-style drivers (claude, gemini). The
|
|
781
|
+
// claude SubprocessDriver only injects --mcp-config when the spawned
|
|
782
|
+
// task sets providerOptions.mcpAccess=true (per-recipe-step opt-in).
|
|
783
|
+
// Gemini wires it unconditionally into ~/.gemini/settings.json.
|
|
784
|
+
bridgeMcp: () => this.port > 0
|
|
785
|
+
? {
|
|
786
|
+
url: `http://127.0.0.1:${this.port}/mcp`,
|
|
787
|
+
authToken: this.authToken,
|
|
788
|
+
}
|
|
762
789
|
: undefined,
|
|
763
790
|
}, (msg) => this.logger.info(msg));
|
|
764
791
|
// Patchwork: enrichment link log is useful regardless of orchestrator.
|
|
@@ -847,17 +874,35 @@ export class Bridge {
|
|
|
847
874
|
});
|
|
848
875
|
// scheduler.start() deferred to after this.port is set (see below)
|
|
849
876
|
// so bridgeMcp callback has a valid port when first cron fires.
|
|
877
|
+
//
|
|
878
|
+
// Hot-reload: re-prime the scheduler whenever the recipe set
|
|
879
|
+
// changes on disk (install / save / delete). RecipeScheduler.start()
|
|
880
|
+
// is idempotent (calls this.stop() first) and reads the recipes
|
|
881
|
+
// directory fresh, so calling it again cleanly picks up the new
|
|
882
|
+
// file. Stored as a callback on the Server so route handlers can
|
|
883
|
+
// fire it post-success without owning a reference to the scheduler.
|
|
884
|
+
this.server.onRecipesChangedFn = () => {
|
|
885
|
+
if (!this.recipeScheduler)
|
|
886
|
+
return;
|
|
887
|
+
try {
|
|
888
|
+
const scheduled = this.recipeScheduler.start();
|
|
889
|
+
this.logger.info(`[patchwork] scheduler re-primed after recipe change · ${scheduled.length} cron recipe${scheduled.length === 1 ? "" : "s"} active`);
|
|
890
|
+
}
|
|
891
|
+
catch (err) {
|
|
892
|
+
this.logger.warn?.(`[patchwork] scheduler restart failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
893
|
+
}
|
|
894
|
+
};
|
|
850
895
|
}
|
|
851
896
|
}
|
|
852
897
|
if (this.config.automationEnabled) {
|
|
853
898
|
if (!this.orchestrator) {
|
|
854
|
-
throw new Error("--automation requires --
|
|
899
|
+
throw new Error("--automation requires --driver != none");
|
|
855
900
|
}
|
|
856
901
|
if (!this.config.automationPolicyPath) {
|
|
857
902
|
throw new Error("--automation requires --automation-policy <path>");
|
|
858
903
|
}
|
|
859
904
|
const policy = loadPolicy(this.config.automationPolicyPath);
|
|
860
|
-
this.automationHooks = new AutomationHooks(policy, this.orchestrator, (msg) => this.logger.info(msg), this.extensionClient, this.config.workspace);
|
|
905
|
+
this.automationHooks = new AutomationHooks(policy, this.orchestrator, (msg) => this.logger.info(msg), this.extensionClient, this.config.workspace, this.config.automationAllowPrivateWebhooks);
|
|
861
906
|
this.logger.info(`[bridge] Automation enabled (policy: ${this.config.automationPolicyPath})`);
|
|
862
907
|
}
|
|
863
908
|
// 3. Wire up /health endpoint data and /metrics
|
|
@@ -883,10 +928,37 @@ export class Bridge {
|
|
|
883
928
|
tokens: this.tokenUsageTracker.getTotals(),
|
|
884
929
|
};
|
|
885
930
|
};
|
|
886
|
-
this.server.metricsFn = () =>
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
931
|
+
this.server.metricsFn = () => {
|
|
932
|
+
const base = this.activityLog.toPrometheus({
|
|
933
|
+
rateLimitRejected: this.activityLog.getRateLimitRejections(),
|
|
934
|
+
extensionDisconnects: this.extensionDisconnectCount,
|
|
935
|
+
});
|
|
936
|
+
// Append per-category halt gauges from the runLog so users with
|
|
937
|
+
// their own Prometheus stack can dashboard halts without using
|
|
938
|
+
// Patchwork's UI. Reads everything currently in the in-memory ring
|
|
939
|
+
// (bounded by runLog memoryCap); rotation may cause the values to
|
|
940
|
+
// decrease, so we expose this as a `gauge` rather than a `counter`.
|
|
941
|
+
// Composes #441/#444/#447 — same data shape as /runs/halt-summary
|
|
942
|
+
// and `patchwork halts`, surfaced through the existing /metrics
|
|
943
|
+
// route.
|
|
944
|
+
let haltLines = [];
|
|
945
|
+
let judgeLines = [];
|
|
946
|
+
try {
|
|
947
|
+
if (this.recipeRunLog) {
|
|
948
|
+
const runs = this.recipeRunLog.query({ limit: 500 });
|
|
949
|
+
haltLines = haltSummaryToPrometheus(summariseHalts(runs));
|
|
950
|
+
// PR3b — judge verdicts are a separate channel from halts
|
|
951
|
+
// (augment-only invariant; see judgeVerdict.ts). Same window,
|
|
952
|
+
// same fail-open posture.
|
|
953
|
+
judgeLines = judgeSummaryToPrometheus(summariseJudgments(runs));
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
catch {
|
|
957
|
+
/* fail-open: prometheus must never break on log read */
|
|
958
|
+
}
|
|
959
|
+
const extras = [...haltLines, ...judgeLines];
|
|
960
|
+
return extras.length > 0 ? `${base}\n${extras.join("\n")}\n` : base;
|
|
961
|
+
};
|
|
890
962
|
this.server.perfDataFn = () => {
|
|
891
963
|
const windowMs = 60 * 60_000; // 1h window for dashboard
|
|
892
964
|
const windowedS = this.activityLog.windowedStats(windowMs);
|
|
@@ -897,10 +969,11 @@ export class Bridge {
|
|
|
897
969
|
totalCalls += s.count;
|
|
898
970
|
totalErrors += s.errors;
|
|
899
971
|
}
|
|
900
|
-
|
|
901
|
-
const overallP95Ms = p95Values.length > 0 ? Math.max(...p95Values) : 0;
|
|
972
|
+
let overallP95Ms = 0;
|
|
902
973
|
const perTool = {};
|
|
903
974
|
for (const [tool, pct] of Object.entries(allPercentiles)) {
|
|
975
|
+
if (pct.p95 > overallP95Ms)
|
|
976
|
+
overallP95Ms = pct.p95;
|
|
904
977
|
const ws = windowedS[tool];
|
|
905
978
|
perTool[tool] = {
|
|
906
979
|
p50: pct.p50,
|
|
@@ -1009,14 +1082,16 @@ export class Bridge {
|
|
|
1009
1082
|
// Count automation tasks (isAutomationTask) created within the window.
|
|
1010
1083
|
// These originate from automation hooks (onFileSave, onGitCommit, etc.)
|
|
1011
1084
|
// and accurately represent "hooks fired" rather than session lifecycle events.
|
|
1012
|
-
const
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1085
|
+
const allTasks = this.orchestrator ? this.orchestrator.list() : null;
|
|
1086
|
+
let hooksLast24h = 0;
|
|
1087
|
+
if (allTasks) {
|
|
1088
|
+
for (const t of allTasks) {
|
|
1089
|
+
if (t.isAutomationTask && t.createdAt > cutoff)
|
|
1090
|
+
hooksLast24h++;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
const recentAutomationTasks = allTasks
|
|
1094
|
+
? allTasks
|
|
1020
1095
|
.sort((a, b) => b.createdAt - a.createdAt)
|
|
1021
1096
|
.slice(0, 20)
|
|
1022
1097
|
.map((t) => ({
|
|
@@ -1047,6 +1122,23 @@ export class Bridge {
|
|
|
1047
1122
|
};
|
|
1048
1123
|
};
|
|
1049
1124
|
this.server.streamFn = (listener) => this.activityLog.subscribe(listener);
|
|
1125
|
+
// v2-I8 (#422): broadcast kind:"kill-switch" SSE when state changes.
|
|
1126
|
+
// The activityLog subscriber list fans out to all open /stream clients.
|
|
1127
|
+
this.server.broadcastKillSwitchEventFn = (engaged, reason) => {
|
|
1128
|
+
for (const listener of this.activityLog.getListeners()) {
|
|
1129
|
+
try {
|
|
1130
|
+
listener("kill-switch", {
|
|
1131
|
+
id: 0,
|
|
1132
|
+
timestamp: new Date().toISOString(),
|
|
1133
|
+
event: engaged ? "engage" : "release",
|
|
1134
|
+
metadata: { engaged, ...(reason ? { reason } : {}) },
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
catch {
|
|
1138
|
+
/* listener must not crash broadcast */
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
};
|
|
1050
1142
|
this.server.cancelTaskFn = (id) => this.orchestrator?.cancel(id, "user") ?? false;
|
|
1051
1143
|
// Wire `/sessions` for the dashboard's Sessions page. The same Map is
|
|
1052
1144
|
// already iterated by `statusFn` for the bridge-status payload — exposing
|
|
@@ -1078,6 +1170,24 @@ export class Bridge {
|
|
|
1078
1170
|
}
|
|
1079
1171
|
return out;
|
|
1080
1172
|
};
|
|
1173
|
+
this.server.restartCheckFn = () => {
|
|
1174
|
+
let totalSessions = 0;
|
|
1175
|
+
let totalInFlight = 0;
|
|
1176
|
+
const busySessions = [];
|
|
1177
|
+
for (const [sid, session] of this.sessions) {
|
|
1178
|
+
totalSessions++;
|
|
1179
|
+
const stats = session.transport.getStats();
|
|
1180
|
+
if (stats.activeToolCalls > 0) {
|
|
1181
|
+
totalInFlight += stats.activeToolCalls;
|
|
1182
|
+
busySessions.push(`${sid.slice(0, 8)} (${stats.activeToolCalls} tool${stats.activeToolCalls === 1 ? "" : "s"}: ${stats.inFlightTools.join(", ")})`);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return {
|
|
1186
|
+
totalSessions,
|
|
1187
|
+
inFlightCalls: totalInFlight,
|
|
1188
|
+
busySessions,
|
|
1189
|
+
};
|
|
1190
|
+
};
|
|
1081
1191
|
this.server.tasksFn = () => ({
|
|
1082
1192
|
tasks: (this.orchestrator?.list() ?? []).map((t) => ({
|
|
1083
1193
|
taskId: t.id,
|
|
@@ -1119,9 +1229,33 @@ export class Bridge {
|
|
|
1119
1229
|
// ~/.patchwork/config.json's enableTimeOfDayAnomaly field.
|
|
1120
1230
|
this.server.enableTimeOfDayAnomaly =
|
|
1121
1231
|
this.config.enableTimeOfDayAnomaly ?? false;
|
|
1232
|
+
// Push / ntfy config — previously only set by /settings and lost on
|
|
1233
|
+
// restart. Now restored from ~/.patchwork/config.json on boot so the
|
|
1234
|
+
// mobile-oversight phone path survives a bridge bounce.
|
|
1235
|
+
this.server.pushServiceUrl = this.config.pushServiceUrl ?? undefined;
|
|
1236
|
+
this.server.pushServiceToken = this.config.pushServiceToken ?? undefined;
|
|
1237
|
+
this.server.pushServiceBaseUrl =
|
|
1238
|
+
this.config.pushServiceBaseUrl ?? undefined;
|
|
1239
|
+
this.server.ntfyTopic = this.config.ntfyTopic ?? undefined;
|
|
1240
|
+
this.server.ntfyServer = this.config.ntfyServer ?? undefined;
|
|
1241
|
+
// Wire recipe-halt → Web Push dispatch. The listener reads
|
|
1242
|
+
// pushServiceUrl/Token via getter each fire, so config edits
|
|
1243
|
+
// through /settings take effect without a restart. Push request
|
|
1244
|
+
// is fire-and-forget; runner is never blocked on a relay outage.
|
|
1245
|
+
wireHaltPushDispatch({
|
|
1246
|
+
activityLog: this.activityLog,
|
|
1247
|
+
getPushConfig: () => {
|
|
1248
|
+
const url = this.server.pushServiceUrl;
|
|
1249
|
+
const token = this.server.pushServiceToken;
|
|
1250
|
+
if (!url || !token)
|
|
1251
|
+
return null;
|
|
1252
|
+
return { url, token };
|
|
1253
|
+
},
|
|
1254
|
+
logger: this.logger,
|
|
1255
|
+
});
|
|
1122
1256
|
this.server.readyFn = () => {
|
|
1123
1257
|
// Count tools from the first active session (all sessions share the same tool set)
|
|
1124
|
-
const anySession =
|
|
1258
|
+
const anySession = this.sessions.values().next().value;
|
|
1125
1259
|
const toolCount = anySession?.transport.toolCount ?? 0;
|
|
1126
1260
|
return {
|
|
1127
1261
|
ready: this.ready,
|
|
@@ -1129,6 +1263,30 @@ export class Bridge {
|
|
|
1129
1263
|
extensionConnected: this.extensionClient.isConnected(),
|
|
1130
1264
|
};
|
|
1131
1265
|
};
|
|
1266
|
+
// Wire kill-switch audit-trace emit to decisionTraceLog. State
|
|
1267
|
+
// transitions become DecisionTrace entries with tags=["kill-switch",
|
|
1268
|
+
// "engage"|"release", "actor:http"]; query via ctxQueryTraces. See
|
|
1269
|
+
// step 5 of #422.
|
|
1270
|
+
if (this.decisionTraceLog) {
|
|
1271
|
+
const traceLog = this.decisionTraceLog;
|
|
1272
|
+
const workspace = this.config.workspace;
|
|
1273
|
+
this.server.recordKillSwitchTraceFn = (event) => {
|
|
1274
|
+
const direction = event.engaged ? "engage" : "release";
|
|
1275
|
+
const isoTs = new Date(event.ts).toISOString();
|
|
1276
|
+
try {
|
|
1277
|
+
traceLog.record({
|
|
1278
|
+
ref: "kill-switch.writes",
|
|
1279
|
+
problem: event.reason ?? direction,
|
|
1280
|
+
solution: `${event.engaged ? "ENGAGED" : "RELEASED"} at ${isoTs}`,
|
|
1281
|
+
workspace,
|
|
1282
|
+
tags: ["kill-switch", direction, "actor:http"],
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
catch (err) {
|
|
1286
|
+
this.logger.warn(`[kill-switch] failed to record audit trace: ${err instanceof Error ? err.message : String(err)}`);
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1132
1290
|
this.server.statusFn = () => {
|
|
1133
1291
|
let sessionsInGrace = 0;
|
|
1134
1292
|
const sessionList = [];
|
|
@@ -1156,22 +1314,31 @@ export class Bridge {
|
|
|
1156
1314
|
extension: this.extensionClient.isConnected(),
|
|
1157
1315
|
extensionCircuitBreaker: this.extensionClient.getCircuitBreakerState(),
|
|
1158
1316
|
timeline: this.activityLog.queryTimeline({ last: 50 }),
|
|
1159
|
-
patchwork: {
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1317
|
+
patchwork: (() => {
|
|
1318
|
+
const cfg = loadPatchworkConfig();
|
|
1319
|
+
return {
|
|
1320
|
+
workspace: this.config.workspace,
|
|
1321
|
+
approvalGate: this.server.approvalGate,
|
|
1322
|
+
enableTimeOfDayAnomaly: this.server.enableTimeOfDayAnomaly,
|
|
1323
|
+
fullMode: this.config.fullMode,
|
|
1324
|
+
driver: this.config.driver,
|
|
1325
|
+
model: cfg.model,
|
|
1326
|
+
localEndpoint: cfg.localEndpoint,
|
|
1327
|
+
localModel: cfg.localModel,
|
|
1328
|
+
automationEnabled: this.config.automationEnabled,
|
|
1329
|
+
port: this.port,
|
|
1330
|
+
httpPort: this.port,
|
|
1331
|
+
inboxDir: path.join(os.homedir(), ".patchwork", "inbox"),
|
|
1332
|
+
configPath: defaultConfigPath(),
|
|
1333
|
+
apiKeysPresent: getApiKeysPresent(),
|
|
1334
|
+
webhookUrl: this.server.approvalWebhookUrl ?? null,
|
|
1335
|
+
pushServiceUrl: this.server.pushServiceUrl ?? null,
|
|
1336
|
+
pushServiceToken: this.server.pushServiceToken ? "***" : null,
|
|
1337
|
+
pushServiceBaseUrl: this.server.pushServiceBaseUrl ?? null,
|
|
1338
|
+
ntfyTopic: this.server.ntfyTopic ?? null,
|
|
1339
|
+
ntfyServer: this.server.ntfyServer ?? null,
|
|
1340
|
+
};
|
|
1341
|
+
})(),
|
|
1175
1342
|
};
|
|
1176
1343
|
};
|
|
1177
1344
|
// 3b-notify. Wire CC hook notify endpoint
|
|
@@ -1231,7 +1398,7 @@ export class Bridge {
|
|
|
1231
1398
|
if (result === null) {
|
|
1232
1399
|
return {
|
|
1233
1400
|
ok: false,
|
|
1234
|
-
error: "launchQuickTask not registered — requires --
|
|
1401
|
+
error: "launchQuickTask not registered — requires --driver subprocess",
|
|
1235
1402
|
};
|
|
1236
1403
|
}
|
|
1237
1404
|
const r = result;
|
|
@@ -1371,6 +1538,16 @@ export class Bridge {
|
|
|
1371
1538
|
// All process-level signal handlers are guarded by globalHandlersRegistered so
|
|
1372
1539
|
// that repeated start() calls (e.g. in tests or --watch restarts) don't
|
|
1373
1540
|
// accumulate process.once listeners and trigger MaxListenersExceededWarning.
|
|
1541
|
+
// Wire server callbacks so /restart and /shutdown invoke the bridge's
|
|
1542
|
+
// shutdown sequence directly. This is the only path that works on
|
|
1543
|
+
// Windows, where `process.kill(pid, 'SIGTERM')` is TerminateProcess
|
|
1544
|
+
// and registered handlers never fire.
|
|
1545
|
+
this.server.restartKillFn = () => {
|
|
1546
|
+
void shutdown("SIGTERM", 143);
|
|
1547
|
+
};
|
|
1548
|
+
this.server.shutdownFn = () => {
|
|
1549
|
+
void shutdown("SIGTERM", 0);
|
|
1550
|
+
};
|
|
1374
1551
|
if (!globalHandlersRegistered) {
|
|
1375
1552
|
globalHandlersRegistered = true;
|
|
1376
1553
|
process.once("SIGINT", () => shutdown("SIGINT", 130));
|
|
@@ -1468,6 +1645,15 @@ export class Bridge {
|
|
|
1468
1645
|
this.stopped = true;
|
|
1469
1646
|
this.logger.info("Shutting down...");
|
|
1470
1647
|
this._stopPeriodicSnapshots();
|
|
1648
|
+
if (this._stopFlagsWatch) {
|
|
1649
|
+
try {
|
|
1650
|
+
this._stopFlagsWatch();
|
|
1651
|
+
}
|
|
1652
|
+
catch {
|
|
1653
|
+
/* ignore */
|
|
1654
|
+
}
|
|
1655
|
+
this._stopFlagsWatch = null;
|
|
1656
|
+
}
|
|
1471
1657
|
this.tokenUsageTracker.stop();
|
|
1472
1658
|
this.automationHooks?.destroy();
|
|
1473
1659
|
this.recipeScheduler?.stop();
|
|
@@ -1512,7 +1698,7 @@ export class Bridge {
|
|
|
1512
1698
|
}
|
|
1513
1699
|
// Clean up all active sessions (cleanupSession skips the extension notification
|
|
1514
1700
|
// during shutdown because this.stopped is already true)
|
|
1515
|
-
for (const id of
|
|
1701
|
+
for (const id of this.sessions.keys()) {
|
|
1516
1702
|
this.cleanupSession(id);
|
|
1517
1703
|
}
|
|
1518
1704
|
const shutdownErrorPart = totalErrors > 0
|
|
@@ -1526,7 +1712,8 @@ export class Bridge {
|
|
|
1526
1712
|
if (analyticsOn === true && totalSessions > 0) {
|
|
1527
1713
|
try {
|
|
1528
1714
|
const entries = this.activityLog.query({ last: 500 });
|
|
1529
|
-
const
|
|
1715
|
+
const salt = getAnalyticsSalt();
|
|
1716
|
+
const summary = buildSummary(entries, maxDurationMs, PACKAGE_VERSION, salt);
|
|
1530
1717
|
await Promise.race([
|
|
1531
1718
|
sendAnalytics(summary),
|
|
1532
1719
|
new Promise((resolve) => setTimeout(resolve, 2000)),
|