patchwork-os 0.2.0-alpha.0
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/LICENSE +21 -0
- package/README.bridge.md +352 -0
- package/README.md +72 -0
- package/deploy/README.md +172 -0
- package/deploy/bootstrap-new-vps.sh +364 -0
- package/deploy/claude-ide-bridge.service.template +67 -0
- package/deploy/claude-ide-bridge@.service +31 -0
- package/deploy/ecosystem.config.js.example +36 -0
- package/deploy/install-vps-service.sh +240 -0
- package/deploy/nginx-claude-bridge.conf.template +129 -0
- package/dist/activityLog.d.ts +112 -0
- package/dist/activityLog.js +399 -0
- package/dist/activityLog.js.map +1 -0
- package/dist/activityTypes.d.ts +28 -0
- package/dist/activityTypes.js +9 -0
- package/dist/activityTypes.js.map +1 -0
- package/dist/adapters/base.d.ts +78 -0
- package/dist/adapters/base.js +14 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/claude.d.ts +18 -0
- package/dist/adapters/claude.js +276 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/gemini.d.ts +17 -0
- package/dist/adapters/gemini.js +218 -0
- package/dist/adapters/gemini.js.map +1 -0
- package/dist/adapters/grok.d.ts +7 -0
- package/dist/adapters/grok.js +21 -0
- package/dist/adapters/grok.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.js +37 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/local.d.ts +7 -0
- package/dist/adapters/local.js +22 -0
- package/dist/adapters/local.js.map +1 -0
- package/dist/adapters/openai.d.ts +22 -0
- package/dist/adapters/openai.js +284 -0
- package/dist/adapters/openai.js.map +1 -0
- package/dist/adapters/sse.d.ts +13 -0
- package/dist/adapters/sse.js +58 -0
- package/dist/adapters/sse.js.map +1 -0
- package/dist/analyticsAggregator.d.ts +28 -0
- package/dist/analyticsAggregator.js +133 -0
- package/dist/analyticsAggregator.js.map +1 -0
- package/dist/analyticsPrefs.d.ts +9 -0
- package/dist/analyticsPrefs.js +50 -0
- package/dist/analyticsPrefs.js.map +1 -0
- package/dist/analyticsSend.d.ts +12 -0
- package/dist/analyticsSend.js +34 -0
- package/dist/analyticsSend.js.map +1 -0
- package/dist/approvalHttp.d.ts +46 -0
- package/dist/approvalHttp.js +370 -0
- package/dist/approvalHttp.js.map +1 -0
- package/dist/approvalQueue.d.ts +49 -0
- package/dist/approvalQueue.js +84 -0
- package/dist/approvalQueue.js.map +1 -0
- package/dist/automation.d.ts +675 -0
- package/dist/automation.js +1038 -0
- package/dist/automation.js.map +1 -0
- package/dist/bridge.d.ts +85 -0
- package/dist/bridge.js +1535 -0
- package/dist/bridge.js.map +1 -0
- package/dist/bridgeLockDiscovery.d.ts +11 -0
- package/dist/bridgeLockDiscovery.js +49 -0
- package/dist/bridgeLockDiscovery.js.map +1 -0
- package/dist/bridgeToken.d.ts +22 -0
- package/dist/bridgeToken.js +114 -0
- package/dist/bridgeToken.js.map +1 -0
- package/dist/bridgeToolsRules.d.ts +20 -0
- package/dist/bridgeToolsRules.js +79 -0
- package/dist/bridgeToolsRules.js.map +1 -0
- package/dist/ccPermissions.d.ts +59 -0
- package/dist/ccPermissions.js +163 -0
- package/dist/ccPermissions.js.map +1 -0
- package/dist/claudeDriver.d.ts +129 -0
- package/dist/claudeDriver.js +459 -0
- package/dist/claudeDriver.js.map +1 -0
- package/dist/claudeMdPatch.d.ts +29 -0
- package/dist/claudeMdPatch.js +164 -0
- package/dist/claudeMdPatch.js.map +1 -0
- package/dist/claudeOrchestrator.d.ts +171 -0
- package/dist/claudeOrchestrator.js +591 -0
- package/dist/claudeOrchestrator.js.map +1 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +158 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/marketplace.d.ts +11 -0
- package/dist/commands/marketplace.js +120 -0
- package/dist/commands/marketplace.js.map +1 -0
- package/dist/commands/patchworkInit.d.ts +14 -0
- package/dist/commands/patchworkInit.js +155 -0
- package/dist/commands/patchworkInit.js.map +1 -0
- package/dist/commands/task.d.ts +14 -0
- package/dist/commands/task.js +289 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/tokenEfficiency.d.ts +9 -0
- package/dist/commands/tokenEfficiency.js +211 -0
- package/dist/commands/tokenEfficiency.js.map +1 -0
- package/dist/commands/tools.d.ts +28 -0
- package/dist/commands/tools.js +326 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commitIssueLinkLog.d.ts +77 -0
- package/dist/commitIssueLinkLog.js +142 -0
- package/dist/commitIssueLinkLog.js.map +1 -0
- package/dist/companions/registry.d.ts +12 -0
- package/dist/companions/registry.js +71 -0
- package/dist/companions/registry.js.map +1 -0
- package/dist/config.d.ts +105 -0
- package/dist/config.js +720 -0
- package/dist/config.js.map +1 -0
- package/dist/crypto.d.ts +16 -0
- package/dist/crypto.js +34 -0
- package/dist/crypto.js.map +1 -0
- package/dist/dashboard.d.ts +12 -0
- package/dist/dashboard.js +149 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/decisionTraceLog.d.ts +77 -0
- package/dist/decisionTraceLog.js +147 -0
- package/dist/decisionTraceLog.js.map +1 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.js +34 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensionClient.d.ts +279 -0
- package/dist/extensionClient.js +1253 -0
- package/dist/extensionClient.js.map +1 -0
- package/dist/fileLock.d.ts +36 -0
- package/dist/fileLock.js +121 -0
- package/dist/fileLock.js.map +1 -0
- package/dist/fp/activityAnalytics.d.ts +39 -0
- package/dist/fp/activityAnalytics.js +111 -0
- package/dist/fp/activityAnalytics.js.map +1 -0
- package/dist/fp/async.d.ts +48 -0
- package/dist/fp/async.js +60 -0
- package/dist/fp/async.js.map +1 -0
- package/dist/fp/automationInterpreter.d.ts +37 -0
- package/dist/fp/automationInterpreter.js +523 -0
- package/dist/fp/automationInterpreter.js.map +1 -0
- package/dist/fp/automationProgram.d.ts +89 -0
- package/dist/fp/automationProgram.js +29 -0
- package/dist/fp/automationProgram.js.map +1 -0
- package/dist/fp/automationState.d.ts +135 -0
- package/dist/fp/automationState.js +206 -0
- package/dist/fp/automationState.js.map +1 -0
- package/dist/fp/automationUtils.d.ts +31 -0
- package/dist/fp/automationUtils.js +61 -0
- package/dist/fp/automationUtils.js.map +1 -0
- package/dist/fp/brandedTypes.d.ts +32 -0
- package/dist/fp/brandedTypes.js +41 -0
- package/dist/fp/brandedTypes.js.map +1 -0
- package/dist/fp/commandDescription.d.ts +18 -0
- package/dist/fp/commandDescription.js +125 -0
- package/dist/fp/commandDescription.js.map +1 -0
- package/dist/fp/extensionSnapshot.d.ts +10 -0
- package/dist/fp/extensionSnapshot.js +14 -0
- package/dist/fp/extensionSnapshot.js.map +1 -0
- package/dist/fp/index.d.ts +8 -0
- package/dist/fp/index.js +9 -0
- package/dist/fp/index.js.map +1 -0
- package/dist/fp/interpreterContext.d.ts +69 -0
- package/dist/fp/interpreterContext.js +56 -0
- package/dist/fp/interpreterContext.js.map +1 -0
- package/dist/fp/policyParser.d.ts +16 -0
- package/dist/fp/policyParser.js +334 -0
- package/dist/fp/policyParser.js.map +1 -0
- package/dist/fp/result.d.ts +38 -0
- package/dist/fp/result.js +57 -0
- package/dist/fp/result.js.map +1 -0
- package/dist/fp/tokenBucket.d.ts +27 -0
- package/dist/fp/tokenBucket.js +36 -0
- package/dist/fp/tokenBucket.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1465 -0
- package/dist/index.js.map +1 -0
- package/dist/instructionsUtils.d.ts +17 -0
- package/dist/instructionsUtils.js +38 -0
- package/dist/instructionsUtils.js.map +1 -0
- package/dist/lockfile.d.ts +16 -0
- package/dist/lockfile.js +172 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +68 -0
- package/dist/logger.js.map +1 -0
- package/dist/oauth.d.ts +105 -0
- package/dist/oauth.js +880 -0
- package/dist/oauth.js.map +1 -0
- package/dist/orchestrator/childBridgeClient.d.ts +33 -0
- package/dist/orchestrator/childBridgeClient.js +321 -0
- package/dist/orchestrator/childBridgeClient.js.map +1 -0
- package/dist/orchestrator/childBridgeRegistry.d.ts +67 -0
- package/dist/orchestrator/childBridgeRegistry.js +297 -0
- package/dist/orchestrator/childBridgeRegistry.js.map +1 -0
- package/dist/orchestrator/index.d.ts +3 -0
- package/dist/orchestrator/index.js +3 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/orchestratorBridge.d.ts +32 -0
- package/dist/orchestrator/orchestratorBridge.js +412 -0
- package/dist/orchestrator/orchestratorBridge.js.map +1 -0
- package/dist/orchestrator/orchestratorConfig.d.ts +11 -0
- package/dist/orchestrator/orchestratorConfig.js +85 -0
- package/dist/orchestrator/orchestratorConfig.js.map +1 -0
- package/dist/orchestrator/orchestratorTools.d.ts +16 -0
- package/dist/orchestrator/orchestratorTools.js +272 -0
- package/dist/orchestrator/orchestratorTools.js.map +1 -0
- package/dist/patchworkCli.d.ts +15 -0
- package/dist/patchworkCli.js +41 -0
- package/dist/patchworkCli.js.map +1 -0
- package/dist/patchworkConfig.d.ts +28 -0
- package/dist/patchworkConfig.js +30 -0
- package/dist/patchworkConfig.js.map +1 -0
- package/dist/plugin.d.ts +106 -0
- package/dist/plugin.js +31 -0
- package/dist/plugin.js.map +1 -0
- package/dist/pluginLoader.d.ts +44 -0
- package/dist/pluginLoader.js +357 -0
- package/dist/pluginLoader.js.map +1 -0
- package/dist/pluginWatcher.d.ts +24 -0
- package/dist/pluginWatcher.js +139 -0
- package/dist/pluginWatcher.js.map +1 -0
- package/dist/preToolUseHook.d.ts +10 -0
- package/dist/preToolUseHook.js +57 -0
- package/dist/preToolUseHook.js.map +1 -0
- package/dist/probe.d.ts +35 -0
- package/dist/probe.js +143 -0
- package/dist/probe.js.map +1 -0
- package/dist/prompts.d.ts +27 -0
- package/dist/prompts.js +1680 -0
- package/dist/prompts.js.map +1 -0
- package/dist/quickTaskPresets.d.ts +64 -0
- package/dist/quickTaskPresets.js +156 -0
- package/dist/quickTaskPresets.js.map +1 -0
- package/dist/recipes/compiler.d.ts +44 -0
- package/dist/recipes/compiler.js +140 -0
- package/dist/recipes/compiler.js.map +1 -0
- package/dist/recipes/installer.d.ts +25 -0
- package/dist/recipes/installer.js +62 -0
- package/dist/recipes/installer.js.map +1 -0
- package/dist/recipes/parser.d.ts +18 -0
- package/dist/recipes/parser.js +160 -0
- package/dist/recipes/parser.js.map +1 -0
- package/dist/recipes/scheduler.d.ts +45 -0
- package/dist/recipes/scheduler.js +110 -0
- package/dist/recipes/scheduler.js.map +1 -0
- package/dist/recipes/schema.d.ts +71 -0
- package/dist/recipes/schema.js +11 -0
- package/dist/recipes/schema.js.map +1 -0
- package/dist/recipesHttp.d.ts +63 -0
- package/dist/recipesHttp.js +183 -0
- package/dist/recipesHttp.js.map +1 -0
- package/dist/resources.d.ts +33 -0
- package/dist/resources.js +266 -0
- package/dist/resources.js.map +1 -0
- package/dist/riskTier.d.ts +40 -0
- package/dist/riskTier.js +142 -0
- package/dist/riskTier.js.map +1 -0
- package/dist/runLog.d.ts +90 -0
- package/dist/runLog.js +143 -0
- package/dist/runLog.js.map +1 -0
- package/dist/server.d.ts +160 -0
- package/dist/server.js +1244 -0
- package/dist/server.js.map +1 -0
- package/dist/sessionCheckpoint.d.ts +37 -0
- package/dist/sessionCheckpoint.js +123 -0
- package/dist/sessionCheckpoint.js.map +1 -0
- package/dist/streamableHttp.d.ts +86 -0
- package/dist/streamableHttp.js +702 -0
- package/dist/streamableHttp.js.map +1 -0
- package/dist/telemetry.d.ts +18 -0
- package/dist/telemetry.js +95 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tools/activityLog.d.ts +140 -0
- package/dist/tools/activityLog.js +204 -0
- package/dist/tools/activityLog.js.map +1 -0
- package/dist/tools/auditDependencies.d.ts +67 -0
- package/dist/tools/auditDependencies.js +298 -0
- package/dist/tools/auditDependencies.js.map +1 -0
- package/dist/tools/batchLsp.d.ts +262 -0
- package/dist/tools/batchLsp.js +328 -0
- package/dist/tools/batchLsp.js.map +1 -0
- package/dist/tools/blame-utils.d.ts +30 -0
- package/dist/tools/blame-utils.js +60 -0
- package/dist/tools/blame-utils.js.map +1 -0
- package/dist/tools/bridgeDoctor.d.ts +78 -0
- package/dist/tools/bridgeDoctor.js +542 -0
- package/dist/tools/bridgeDoctor.js.map +1 -0
- package/dist/tools/bridgeStatus.d.ts +122 -0
- package/dist/tools/bridgeStatus.js +250 -0
- package/dist/tools/bridgeStatus.js.map +1 -0
- package/dist/tools/cancelClaudeTask.d.ts +48 -0
- package/dist/tools/cancelClaudeTask.js +56 -0
- package/dist/tools/cancelClaudeTask.js.map +1 -0
- package/dist/tools/checkDocumentDirty.d.ts +56 -0
- package/dist/tools/checkDocumentDirty.js +74 -0
- package/dist/tools/checkDocumentDirty.js.map +1 -0
- package/dist/tools/clipboard.d.ts +80 -0
- package/dist/tools/clipboard.js +211 -0
- package/dist/tools/clipboard.js.map +1 -0
- package/dist/tools/closeTabs.d.ts +84 -0
- package/dist/tools/closeTabs.js +97 -0
- package/dist/tools/closeTabs.js.map +1 -0
- package/dist/tools/codeLens.d.ts +50 -0
- package/dist/tools/codeLens.js +47 -0
- package/dist/tools/codeLens.js.map +1 -0
- package/dist/tools/contextBundle.d.ts +75 -0
- package/dist/tools/contextBundle.js +218 -0
- package/dist/tools/contextBundle.js.map +1 -0
- package/dist/tools/createIssueFromAIComment.d.ts +75 -0
- package/dist/tools/createIssueFromAIComment.js +119 -0
- package/dist/tools/createIssueFromAIComment.js.map +1 -0
- package/dist/tools/ctxGetTaskContext.d.ts +103 -0
- package/dist/tools/ctxGetTaskContext.js +274 -0
- package/dist/tools/ctxGetTaskContext.js.map +1 -0
- package/dist/tools/ctxQueryTraces.d.ts +142 -0
- package/dist/tools/ctxQueryTraces.js +194 -0
- package/dist/tools/ctxQueryTraces.js.map +1 -0
- package/dist/tools/ctxSaveTrace.d.ts +87 -0
- package/dist/tools/ctxSaveTrace.js +94 -0
- package/dist/tools/ctxSaveTrace.js.map +1 -0
- package/dist/tools/debug.d.ts +206 -0
- package/dist/tools/debug.js +234 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/decorations.d.ts +130 -0
- package/dist/tools/decorations.js +160 -0
- package/dist/tools/decorations.js.map +1 -0
- package/dist/tools/detectUnusedCode.d.ts +78 -0
- package/dist/tools/detectUnusedCode.js +173 -0
- package/dist/tools/detectUnusedCode.js.map +1 -0
- package/dist/tools/documentLinks.d.ts +62 -0
- package/dist/tools/documentLinks.js +55 -0
- package/dist/tools/documentLinks.js.map +1 -0
- package/dist/tools/editText.d.ts +108 -0
- package/dist/tools/editText.js +318 -0
- package/dist/tools/editText.js.map +1 -0
- package/dist/tools/enrichCommit.d.ts +89 -0
- package/dist/tools/enrichCommit.js +201 -0
- package/dist/tools/enrichCommit.js.map +1 -0
- package/dist/tools/enrichStackTrace.d.ts +121 -0
- package/dist/tools/enrichStackTrace.js +194 -0
- package/dist/tools/enrichStackTrace.js.map +1 -0
- package/dist/tools/explainDiagnostic.d.ts +137 -0
- package/dist/tools/explainDiagnostic.js +230 -0
- package/dist/tools/explainDiagnostic.js.map +1 -0
- package/dist/tools/explainSymbol.d.ts +119 -0
- package/dist/tools/explainSymbol.js +177 -0
- package/dist/tools/explainSymbol.js.map +1 -0
- package/dist/tools/fileOperations.d.ts +186 -0
- package/dist/tools/fileOperations.js +330 -0
- package/dist/tools/fileOperations.js.map +1 -0
- package/dist/tools/fileWatcher.d.ts +107 -0
- package/dist/tools/fileWatcher.js +121 -0
- package/dist/tools/fileWatcher.js.map +1 -0
- package/dist/tools/findFiles.d.ts +65 -0
- package/dist/tools/findFiles.js +142 -0
- package/dist/tools/findFiles.js.map +1 -0
- package/dist/tools/findRelatedTests.d.ts +83 -0
- package/dist/tools/findRelatedTests.js +196 -0
- package/dist/tools/findRelatedTests.js.map +1 -0
- package/dist/tools/fixAllLintErrors.d.ts +66 -0
- package/dist/tools/fixAllLintErrors.js +128 -0
- package/dist/tools/fixAllLintErrors.js.map +1 -0
- package/dist/tools/foldingRanges.d.ts +50 -0
- package/dist/tools/foldingRanges.js +51 -0
- package/dist/tools/foldingRanges.js.map +1 -0
- package/dist/tools/formatAndSave.d.ts +57 -0
- package/dist/tools/formatAndSave.js +87 -0
- package/dist/tools/formatAndSave.js.map +1 -0
- package/dist/tools/formatDocument.d.ts +61 -0
- package/dist/tools/formatDocument.js +144 -0
- package/dist/tools/formatDocument.js.map +1 -0
- package/dist/tools/generateAPIDocumentation.d.ts +62 -0
- package/dist/tools/generateAPIDocumentation.js +249 -0
- package/dist/tools/generateAPIDocumentation.js.map +1 -0
- package/dist/tools/generateTests.d.ts +75 -0
- package/dist/tools/generateTests.js +226 -0
- package/dist/tools/generateTests.js.map +1 -0
- package/dist/tools/getAIComments.d.ts +79 -0
- package/dist/tools/getAIComments.js +93 -0
- package/dist/tools/getAIComments.js.map +1 -0
- package/dist/tools/getAnalyticsReport.d.ts +102 -0
- package/dist/tools/getAnalyticsReport.js +137 -0
- package/dist/tools/getAnalyticsReport.js.map +1 -0
- package/dist/tools/getArchitectureContext.d.ts +85 -0
- package/dist/tools/getArchitectureContext.js +135 -0
- package/dist/tools/getArchitectureContext.js.map +1 -0
- package/dist/tools/getBufferContent.d.ts +80 -0
- package/dist/tools/getBufferContent.js +207 -0
- package/dist/tools/getBufferContent.js.map +1 -0
- package/dist/tools/getChangeImpact.d.ts +76 -0
- package/dist/tools/getChangeImpact.js +184 -0
- package/dist/tools/getChangeImpact.js.map +1 -0
- package/dist/tools/getClaudeTaskStatus.d.ts +87 -0
- package/dist/tools/getClaudeTaskStatus.js +89 -0
- package/dist/tools/getClaudeTaskStatus.js.map +1 -0
- package/dist/tools/getCodeCoverage.d.ts +86 -0
- package/dist/tools/getCodeCoverage.js +237 -0
- package/dist/tools/getCodeCoverage.js.map +1 -0
- package/dist/tools/getCommitsForIssue.d.ts +98 -0
- package/dist/tools/getCommitsForIssue.js +106 -0
- package/dist/tools/getCommitsForIssue.js.map +1 -0
- package/dist/tools/getCurrentSelection.d.ts +123 -0
- package/dist/tools/getCurrentSelection.js +113 -0
- package/dist/tools/getCurrentSelection.js.map +1 -0
- package/dist/tools/getDebugState.d.ts +140 -0
- package/dist/tools/getDebugState.js +109 -0
- package/dist/tools/getDebugState.js.map +1 -0
- package/dist/tools/getDependencyTree.d.ts +59 -0
- package/dist/tools/getDependencyTree.js +207 -0
- package/dist/tools/getDependencyTree.js.map +1 -0
- package/dist/tools/getDiagnostics.d.ts +108 -0
- package/dist/tools/getDiagnostics.js +371 -0
- package/dist/tools/getDiagnostics.js.map +1 -0
- package/dist/tools/getDiffFromHandoff.d.ts +89 -0
- package/dist/tools/getDiffFromHandoff.js +163 -0
- package/dist/tools/getDiffFromHandoff.js.map +1 -0
- package/dist/tools/getDocumentSymbols.d.ts +74 -0
- package/dist/tools/getDocumentSymbols.js +177 -0
- package/dist/tools/getDocumentSymbols.js.map +1 -0
- package/dist/tools/getFileTree.d.ts +66 -0
- package/dist/tools/getFileTree.js +131 -0
- package/dist/tools/getFileTree.js.map +1 -0
- package/dist/tools/getGitDiff.d.ts +50 -0
- package/dist/tools/getGitDiff.js +73 -0
- package/dist/tools/getGitDiff.js.map +1 -0
- package/dist/tools/getGitHotspots.d.ts +88 -0
- package/dist/tools/getGitHotspots.js +145 -0
- package/dist/tools/getGitHotspots.js.map +1 -0
- package/dist/tools/getGitLog.d.ts +62 -0
- package/dist/tools/getGitLog.js +87 -0
- package/dist/tools/getGitLog.js.map +1 -0
- package/dist/tools/getGitStatus.d.ts +72 -0
- package/dist/tools/getGitStatus.js +126 -0
- package/dist/tools/getGitStatus.js.map +1 -0
- package/dist/tools/getImportTree.d.ts +73 -0
- package/dist/tools/getImportTree.js +223 -0
- package/dist/tools/getImportTree.js.map +1 -0
- package/dist/tools/getImportedSignatures.d.ts +62 -0
- package/dist/tools/getImportedSignatures.js +255 -0
- package/dist/tools/getImportedSignatures.js.map +1 -0
- package/dist/tools/getOpenEditors.d.ts +62 -0
- package/dist/tools/getOpenEditors.js +126 -0
- package/dist/tools/getOpenEditors.js.map +1 -0
- package/dist/tools/getPRTemplate.d.ts +68 -0
- package/dist/tools/getPRTemplate.js +187 -0
- package/dist/tools/getPRTemplate.js.map +1 -0
- package/dist/tools/getProjectContext.d.ts +114 -0
- package/dist/tools/getProjectContext.js +344 -0
- package/dist/tools/getProjectContext.js.map +1 -0
- package/dist/tools/getProjectInfo.d.ts +51 -0
- package/dist/tools/getProjectInfo.js +325 -0
- package/dist/tools/getProjectInfo.js.map +1 -0
- package/dist/tools/getSecurityAdvisories.d.ts +105 -0
- package/dist/tools/getSecurityAdvisories.js +472 -0
- package/dist/tools/getSecurityAdvisories.js.map +1 -0
- package/dist/tools/getSessionUsage.d.ts +58 -0
- package/dist/tools/getSessionUsage.js +57 -0
- package/dist/tools/getSessionUsage.js.map +1 -0
- package/dist/tools/getSymbolHistory.d.ts +157 -0
- package/dist/tools/getSymbolHistory.js +256 -0
- package/dist/tools/getSymbolHistory.js.map +1 -0
- package/dist/tools/getToolCapabilities.d.ts +69 -0
- package/dist/tools/getToolCapabilities.js +298 -0
- package/dist/tools/getToolCapabilities.js.map +1 -0
- package/dist/tools/getTypeSignature.d.ts +70 -0
- package/dist/tools/getTypeSignature.js +132 -0
- package/dist/tools/getTypeSignature.js.map +1 -0
- package/dist/tools/getWorkspaceFolders.d.ts +58 -0
- package/dist/tools/getWorkspaceFolders.js +69 -0
- package/dist/tools/getWorkspaceFolders.js.map +1 -0
- package/dist/tools/getWorkspaceSettings.d.ts +44 -0
- package/dist/tools/getWorkspaceSettings.js +70 -0
- package/dist/tools/getWorkspaceSettings.js.map +1 -0
- package/dist/tools/git-utils.d.ts +16 -0
- package/dist/tools/git-utils.js +46 -0
- package/dist/tools/git-utils.js.map +1 -0
- package/dist/tools/gitHistory.d.ts +110 -0
- package/dist/tools/gitHistory.js +167 -0
- package/dist/tools/gitHistory.js.map +1 -0
- package/dist/tools/gitWrite.d.ts +612 -0
- package/dist/tools/gitWrite.js +983 -0
- package/dist/tools/gitWrite.js.map +1 -0
- package/dist/tools/github/actions.d.ts +152 -0
- package/dist/tools/github/actions.js +195 -0
- package/dist/tools/github/actions.js.map +1 -0
- package/dist/tools/github/index.d.ts +3 -0
- package/dist/tools/github/index.js +4 -0
- package/dist/tools/github/index.js.map +1 -0
- package/dist/tools/github/issues.d.ts +281 -0
- package/dist/tools/github/issues.js +340 -0
- package/dist/tools/github/issues.js.map +1 -0
- package/dist/tools/github/pr.d.ts +433 -0
- package/dist/tools/github/pr.js +588 -0
- package/dist/tools/github/pr.js.map +1 -0
- package/dist/tools/github/shared.d.ts +4 -0
- package/dist/tools/github/shared.js +12 -0
- package/dist/tools/github/shared.js.map +1 -0
- package/dist/tools/handoffNote.d.ts +106 -0
- package/dist/tools/handoffNote.js +232 -0
- package/dist/tools/handoffNote.js.map +1 -0
- package/dist/tools/headless/lspClient.d.ts +26 -0
- package/dist/tools/headless/lspClient.js +221 -0
- package/dist/tools/headless/lspClient.js.map +1 -0
- package/dist/tools/headless/lspFallback.d.ts +28 -0
- package/dist/tools/headless/lspFallback.js +122 -0
- package/dist/tools/headless/lspFallback.js.map +1 -0
- package/dist/tools/hoverAtCursor.d.ts +54 -0
- package/dist/tools/hoverAtCursor.js +68 -0
- package/dist/tools/hoverAtCursor.js.map +1 -0
- package/dist/tools/httpClient.d.ts +141 -0
- package/dist/tools/httpClient.js +486 -0
- package/dist/tools/httpClient.js.map +1 -0
- package/dist/tools/index.d.ts +49 -0
- package/dist/tools/index.js +672 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/inlayHints.d.ts +81 -0
- package/dist/tools/inlayHints.js +76 -0
- package/dist/tools/inlayHints.js.map +1 -0
- package/dist/tools/issueRefs.d.ts +14 -0
- package/dist/tools/issueRefs.js +27 -0
- package/dist/tools/issueRefs.js.map +1 -0
- package/dist/tools/jumpToFirstError.d.ts +63 -0
- package/dist/tools/jumpToFirstError.js +124 -0
- package/dist/tools/jumpToFirstError.js.map +1 -0
- package/dist/tools/launchQuickTask.d.ts +76 -0
- package/dist/tools/launchQuickTask.js +170 -0
- package/dist/tools/launchQuickTask.js.map +1 -0
- package/dist/tools/linters/biome.d.ts +2 -0
- package/dist/tools/linters/biome.js +44 -0
- package/dist/tools/linters/biome.js.map +1 -0
- package/dist/tools/linters/cargo.d.ts +2 -0
- package/dist/tools/linters/cargo.js +45 -0
- package/dist/tools/linters/cargo.js.map +1 -0
- package/dist/tools/linters/eslint.d.ts +2 -0
- package/dist/tools/linters/eslint.js +59 -0
- package/dist/tools/linters/eslint.js.map +1 -0
- package/dist/tools/linters/govet.d.ts +2 -0
- package/dist/tools/linters/govet.js +37 -0
- package/dist/tools/linters/govet.js.map +1 -0
- package/dist/tools/linters/pyright.d.ts +2 -0
- package/dist/tools/linters/pyright.js +34 -0
- package/dist/tools/linters/pyright.js.map +1 -0
- package/dist/tools/linters/ruff.d.ts +2 -0
- package/dist/tools/linters/ruff.js +30 -0
- package/dist/tools/linters/ruff.js.map +1 -0
- package/dist/tools/linters/types.d.ts +16 -0
- package/dist/tools/linters/types.js +2 -0
- package/dist/tools/linters/types.js.map +1 -0
- package/dist/tools/linters/typescript.d.ts +2 -0
- package/dist/tools/linters/typescript.js +38 -0
- package/dist/tools/linters/typescript.js.map +1 -0
- package/dist/tools/listClaudeTasks.d.ts +84 -0
- package/dist/tools/listClaudeTasks.js +88 -0
- package/dist/tools/listClaudeTasks.js.map +1 -0
- package/dist/tools/listTerminals.d.ts +55 -0
- package/dist/tools/listTerminals.js +78 -0
- package/dist/tools/listTerminals.js.map +1 -0
- package/dist/tools/lsp.d.ts +1086 -0
- package/dist/tools/lsp.js +1339 -0
- package/dist/tools/lsp.js.map +1 -0
- package/dist/tools/navigateToSymbolByName.d.ts +56 -0
- package/dist/tools/navigateToSymbolByName.js +170 -0
- package/dist/tools/navigateToSymbolByName.js.map +1 -0
- package/dist/tools/openDiff.d.ts +66 -0
- package/dist/tools/openDiff.js +126 -0
- package/dist/tools/openDiff.js.map +1 -0
- package/dist/tools/openFile.d.ts +69 -0
- package/dist/tools/openFile.js +129 -0
- package/dist/tools/openFile.js.map +1 -0
- package/dist/tools/openInBrowser.d.ts +55 -0
- package/dist/tools/openInBrowser.js +129 -0
- package/dist/tools/openInBrowser.js.map +1 -0
- package/dist/tools/organizeImports.d.ts +56 -0
- package/dist/tools/organizeImports.js +115 -0
- package/dist/tools/organizeImports.js.map +1 -0
- package/dist/tools/performanceReport.d.ts +133 -0
- package/dist/tools/performanceReport.js +218 -0
- package/dist/tools/performanceReport.js.map +1 -0
- package/dist/tools/planPersistence.d.ts +306 -0
- package/dist/tools/planPersistence.js +485 -0
- package/dist/tools/planPersistence.js.map +1 -0
- package/dist/tools/previewEdit.d.ts +107 -0
- package/dist/tools/previewEdit.js +270 -0
- package/dist/tools/previewEdit.js.map +1 -0
- package/dist/tools/recentTracesDigest.d.ts +35 -0
- package/dist/tools/recentTracesDigest.js +98 -0
- package/dist/tools/recentTracesDigest.js.map +1 -0
- package/dist/tools/refactorAnalyze.d.ts +78 -0
- package/dist/tools/refactorAnalyze.js +141 -0
- package/dist/tools/refactorAnalyze.js.map +1 -0
- package/dist/tools/refactorExtractFunction.d.ts +52 -0
- package/dist/tools/refactorExtractFunction.js +121 -0
- package/dist/tools/refactorExtractFunction.js.map +1 -0
- package/dist/tools/refactorPreview.d.ts +75 -0
- package/dist/tools/refactorPreview.js +93 -0
- package/dist/tools/refactorPreview.js.map +1 -0
- package/dist/tools/replaceBlock.d.ts +62 -0
- package/dist/tools/replaceBlock.js +125 -0
- package/dist/tools/replaceBlock.js.map +1 -0
- package/dist/tools/resumeClaudeTask.d.ts +75 -0
- package/dist/tools/resumeClaudeTask.js +149 -0
- package/dist/tools/resumeClaudeTask.js.map +1 -0
- package/dist/tools/runClaudeTask.d.ts +97 -0
- package/dist/tools/runClaudeTask.js +224 -0
- package/dist/tools/runClaudeTask.js.map +1 -0
- package/dist/tools/runCommand.d.ts +82 -0
- package/dist/tools/runCommand.js +101 -0
- package/dist/tools/runCommand.js.map +1 -0
- package/dist/tools/runTests.d.ts +146 -0
- package/dist/tools/runTests.js +315 -0
- package/dist/tools/runTests.js.map +1 -0
- package/dist/tools/saveDocument.d.ts +50 -0
- package/dist/tools/saveDocument.js +73 -0
- package/dist/tools/saveDocument.js.map +1 -0
- package/dist/tools/screenshot.d.ts +23 -0
- package/dist/tools/screenshot.js +43 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/screenshotAndAnnotate.d.ts +103 -0
- package/dist/tools/screenshotAndAnnotate.js +192 -0
- package/dist/tools/screenshotAndAnnotate.js.map +1 -0
- package/dist/tools/searchAndReplace.d.ts +108 -0
- package/dist/tools/searchAndReplace.js +281 -0
- package/dist/tools/searchAndReplace.js.map +1 -0
- package/dist/tools/searchTools.d.ts +61 -0
- package/dist/tools/searchTools.js +85 -0
- package/dist/tools/searchTools.js.map +1 -0
- package/dist/tools/searchWorkspace.d.ts +99 -0
- package/dist/tools/searchWorkspace.js +189 -0
- package/dist/tools/searchWorkspace.js.map +1 -0
- package/dist/tools/selectionRanges.d.ts +58 -0
- package/dist/tools/selectionRanges.js +61 -0
- package/dist/tools/selectionRanges.js.map +1 -0
- package/dist/tools/semanticTokens.d.ts +87 -0
- package/dist/tools/semanticTokens.js +86 -0
- package/dist/tools/semanticTokens.js.map +1 -0
- package/dist/tools/setActiveWorkspaceFolder.d.ts +41 -0
- package/dist/tools/setActiveWorkspaceFolder.js +38 -0
- package/dist/tools/setActiveWorkspaceFolder.js.map +1 -0
- package/dist/tools/signatureHelp.d.ts +86 -0
- package/dist/tools/signatureHelp.js +79 -0
- package/dist/tools/signatureHelp.js.map +1 -0
- package/dist/tools/spawnWorkspace.d.ts +103 -0
- package/dist/tools/spawnWorkspace.js +268 -0
- package/dist/tools/spawnWorkspace.js.map +1 -0
- package/dist/tools/stackTraceParser.d.ts +43 -0
- package/dist/tools/stackTraceParser.js +139 -0
- package/dist/tools/stackTraceParser.js.map +1 -0
- package/dist/tools/terminal.d.ts +352 -0
- package/dist/tools/terminal.js +670 -0
- package/dist/tools/terminal.js.map +1 -0
- package/dist/tools/testRunners/cargoTest.d.ts +2 -0
- package/dist/tools/testRunners/cargoTest.js +129 -0
- package/dist/tools/testRunners/cargoTest.js.map +1 -0
- package/dist/tools/testRunners/goTest.d.ts +2 -0
- package/dist/tools/testRunners/goTest.js +108 -0
- package/dist/tools/testRunners/goTest.js.map +1 -0
- package/dist/tools/testRunners/pytest.d.ts +2 -0
- package/dist/tools/testRunners/pytest.js +135 -0
- package/dist/tools/testRunners/pytest.js.map +1 -0
- package/dist/tools/testRunners/types.d.ts +18 -0
- package/dist/tools/testRunners/types.js +2 -0
- package/dist/tools/testRunners/types.js.map +1 -0
- package/dist/tools/testRunners/vitestJest.d.ts +3 -0
- package/dist/tools/testRunners/vitestJest.js +215 -0
- package/dist/tools/testRunners/vitestJest.js.map +1 -0
- package/dist/tools/testTraceToSource.d.ts +80 -0
- package/dist/tools/testTraceToSource.js +206 -0
- package/dist/tools/testTraceToSource.js.map +1 -0
- package/dist/tools/transaction.d.ts +243 -0
- package/dist/tools/transaction.js +309 -0
- package/dist/tools/transaction.js.map +1 -0
- package/dist/tools/typeHierarchy.d.ts +77 -0
- package/dist/tools/typeHierarchy.js +86 -0
- package/dist/tools/typeHierarchy.js.map +1 -0
- package/dist/tools/utils.d.ts +124 -0
- package/dist/tools/utils.js +566 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/vscodeCommands.d.ts +90 -0
- package/dist/tools/vscodeCommands.js +112 -0
- package/dist/tools/vscodeCommands.js.map +1 -0
- package/dist/tools/vscodeTasks.d.ts +102 -0
- package/dist/tools/vscodeTasks.js +110 -0
- package/dist/tools/vscodeTasks.js.map +1 -0
- package/dist/tools/watchDiagnostics.d.ts +64 -0
- package/dist/tools/watchDiagnostics.js +270 -0
- package/dist/tools/watchDiagnostics.js.map +1 -0
- package/dist/tools/workspaceSettings.d.ts +57 -0
- package/dist/tools/workspaceSettings.js +80 -0
- package/dist/tools/workspaceSettings.js.map +1 -0
- package/dist/transport.d.ts +207 -0
- package/dist/transport.js +1272 -0
- package/dist/transport.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.js +31 -0
- package/dist/version.js.map +1 -0
- package/dist/wsUtils.d.ts +8 -0
- package/dist/wsUtils.js +54 -0
- package/dist/wsUtils.js.map +1 -0
- package/package.json +118 -0
- package/scripts/gen-claude-desktop-config.sh +124 -0
- package/scripts/gen-mcp-config.sh +390 -0
- package/scripts/install-extension.sh +106 -0
- package/scripts/mcp-stdio-shim.cjs +482 -0
- package/scripts/postinstall.mjs +68 -0
- package/scripts/start-all.sh +502 -0
- package/scripts/start-orchestrator.sh +186 -0
- package/scripts/start-remote.sh +126 -0
- package/scripts/start-vps.sh +116 -0
- package/templates/CLAUDE.bridge.md +125 -0
- package/templates/automation-policies/security-first.json +46 -0
- package/templates/automation-policies/strict-lint.json +41 -0
- package/templates/automation-policies/test-driven.json +54 -0
- package/templates/automation-policy.example.json +105 -0
- package/templates/bridge-tools.md +111 -0
- package/templates/dispatch-context.md +33 -0
- package/templates/managed-agent/code-review-agent.md +50 -0
- package/templates/managed-agent/managed-agent-mcp.json +102 -0
- package/templates/recipes/ambient-journal.yaml +11 -0
- package/templates/recipes/daily-status.yaml +21 -0
- package/templates/recipes/lint-on-save.yaml +13 -0
- package/templates/recipes/stale-branches.yaml +18 -0
- package/templates/recipes/watch-failing-tests.yaml +15 -0
- package/templates/scheduled-tasks/dependency-audit/SKILL.md +77 -0
- package/templates/scheduled-tasks/health-check/SKILL.md +73 -0
- package/templates/scheduled-tasks/nightly-review/SKILL.md +69 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin loader for Claude IDE Bridge.
|
|
3
|
+
*
|
|
4
|
+
* Discovers, validates, and dynamically imports plugin packages declared via
|
|
5
|
+
* --plugin CLI flags or the `plugins` config file key.
|
|
6
|
+
*
|
|
7
|
+
* Security model:
|
|
8
|
+
* - Plugins are never auto-discovered. They must be explicitly declared.
|
|
9
|
+
* - Plugins run in-process with full Node.js access (no sandbox).
|
|
10
|
+
* - The `toolNamePrefix` field is enforced to prevent collision with built-in tools.
|
|
11
|
+
* - Sensitive config fields (authToken, etc.) are not exposed to plugins.
|
|
12
|
+
* - Each plugin load failure is isolated — a bad plugin is skipped, not fatal.
|
|
13
|
+
*/
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import { createRequire } from "node:module";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { pathToFileURL } from "node:url";
|
|
18
|
+
import { PACKAGE_VERSION } from "./version.js";
|
|
19
|
+
const MANIFEST_FILE = "claude-ide-bridge-plugin.json";
|
|
20
|
+
const SUPPORTED_SCHEMA_VERSION = 1;
|
|
21
|
+
const MAX_TOOLS_PER_PLUGIN = 100;
|
|
22
|
+
/** Runtime package version — compared against minBridgeVersion. */
|
|
23
|
+
const BRIDGE_VERSION = PACKAGE_VERSION;
|
|
24
|
+
// ── Semver helpers ────────────────────────────────────────────────────────────
|
|
25
|
+
/** Parse a semver string into [major, minor, patch]. Returns null on bad input. */
|
|
26
|
+
function parseSemver(v) {
|
|
27
|
+
const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
|
|
28
|
+
if (!m)
|
|
29
|
+
return null;
|
|
30
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
31
|
+
}
|
|
32
|
+
/** Returns true if `actual` satisfies `>= required`. */
|
|
33
|
+
function semverGte(actual, required) {
|
|
34
|
+
const a = parseSemver(actual);
|
|
35
|
+
const r = parseSemver(required);
|
|
36
|
+
if (!a || !r)
|
|
37
|
+
return true; // malformed — don't block
|
|
38
|
+
for (let i = 0; i < 3; i++) {
|
|
39
|
+
if ((a[i] ?? 0) > (r[i] ?? 0))
|
|
40
|
+
return true;
|
|
41
|
+
if ((a[i] ?? 0) < (r[i] ?? 0))
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true; // equal
|
|
45
|
+
}
|
|
46
|
+
// ── Manifest validation ───────────────────────────────────────────────────────
|
|
47
|
+
const PREFIX_RE = /^[a-zA-Z][a-zA-Z0-9_]{1,19}$/;
|
|
48
|
+
function validateManifest(raw, source) {
|
|
49
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
50
|
+
return { ok: false, reason: "manifest is not a JSON object" };
|
|
51
|
+
}
|
|
52
|
+
const m = raw;
|
|
53
|
+
if (m.schemaVersion !== SUPPORTED_SCHEMA_VERSION) {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
reason: `unsupported schemaVersion ${String(m.schemaVersion)} (expected ${SUPPORTED_SCHEMA_VERSION})`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (typeof m.name !== "string" || m.name.length === 0) {
|
|
60
|
+
return { ok: false, reason: '"name" must be a non-empty string' };
|
|
61
|
+
}
|
|
62
|
+
if (typeof m.entrypoint !== "string" || m.entrypoint.length === 0) {
|
|
63
|
+
return { ok: false, reason: '"entrypoint" must be a non-empty string' };
|
|
64
|
+
}
|
|
65
|
+
if (typeof m.toolNamePrefix !== "string") {
|
|
66
|
+
return { ok: false, reason: '"toolNamePrefix" must be a string' };
|
|
67
|
+
}
|
|
68
|
+
if (!PREFIX_RE.test(m.toolNamePrefix)) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
reason: `"toolNamePrefix" "${m.toolNamePrefix}" must match /^[a-zA-Z][a-zA-Z0-9_]{1,19}$/`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (m.version !== undefined && typeof m.version !== "string") {
|
|
75
|
+
return { ok: false, reason: '"version" must be a string if present' };
|
|
76
|
+
}
|
|
77
|
+
if (m.permissions !== undefined &&
|
|
78
|
+
(!Array.isArray(m.permissions) ||
|
|
79
|
+
m.permissions.some((p) => typeof p !== "string"))) {
|
|
80
|
+
return {
|
|
81
|
+
ok: false,
|
|
82
|
+
reason: '"permissions" must be an array of strings if present',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
void source; // used by caller for log context
|
|
86
|
+
return { ok: true, manifest: m };
|
|
87
|
+
}
|
|
88
|
+
// ── Path resolution ───────────────────────────────────────────────────────────
|
|
89
|
+
/**
|
|
90
|
+
* Resolve a plugin specifier to a directory path.
|
|
91
|
+
* - Relative/absolute paths are resolved directly.
|
|
92
|
+
* - Package names are resolved via require.resolve from cwd.
|
|
93
|
+
*/
|
|
94
|
+
function resolvePluginDir(spec) {
|
|
95
|
+
if (spec.startsWith("./") ||
|
|
96
|
+
spec.startsWith("../") ||
|
|
97
|
+
path.isAbsolute(spec)) {
|
|
98
|
+
return path.resolve(spec);
|
|
99
|
+
}
|
|
100
|
+
// npm package — find the package.json via require.resolve, then take its directory
|
|
101
|
+
const req = createRequire(path.join(process.cwd(), "noop.js"));
|
|
102
|
+
const pkgJsonPath = req.resolve(`${spec}/package.json`);
|
|
103
|
+
return path.dirname(pkgJsonPath);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Load all plugins declared in config.plugins and return full LoadedPlugin objects.
|
|
107
|
+
*
|
|
108
|
+
* Collision-detection across plugins still applies.
|
|
109
|
+
*/
|
|
110
|
+
export async function loadPluginsFull(pluginSpecs, config, logger) {
|
|
111
|
+
if (pluginSpecs.length === 0)
|
|
112
|
+
return [];
|
|
113
|
+
const loadedPlugins = [];
|
|
114
|
+
const registeredNames = new Set(); // collision guard across plugins
|
|
115
|
+
// Deduplicate resolved paths before loading
|
|
116
|
+
const seen = new Set();
|
|
117
|
+
const specs = [];
|
|
118
|
+
for (const spec of pluginSpecs) {
|
|
119
|
+
let resolved;
|
|
120
|
+
try {
|
|
121
|
+
resolved = resolvePluginDir(spec);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
resolved = spec;
|
|
125
|
+
}
|
|
126
|
+
if (!seen.has(resolved)) {
|
|
127
|
+
seen.add(resolved);
|
|
128
|
+
specs.push(spec);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
logger.warn(`Plugin "${spec}" resolves to a path already loaded — skipping duplicate`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
for (const spec of specs) {
|
|
135
|
+
const loaded = await loadOnePluginFull(spec, config, logger, registeredNames);
|
|
136
|
+
if (loaded !== null) {
|
|
137
|
+
loadedPlugins.push(loaded);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const totalTools = loadedPlugins.reduce((n, p) => n + p.tools.length, 0);
|
|
141
|
+
if (totalTools > 0) {
|
|
142
|
+
logger.info(`Plugins loaded: ${totalTools} tool${totalTools === 1 ? "" : "s"} registered`);
|
|
143
|
+
}
|
|
144
|
+
return loadedPlugins;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Load all plugins declared in config.plugins.
|
|
148
|
+
*
|
|
149
|
+
* Each plugin is loaded in isolation — a failure in one plugin is logged and
|
|
150
|
+
* skipped; the bridge continues with all successfully loaded plugins.
|
|
151
|
+
*
|
|
152
|
+
* Returns a flat list of tool registrations ready for registerAllTools().
|
|
153
|
+
*/
|
|
154
|
+
export async function loadPlugins(pluginSpecs, config, logger) {
|
|
155
|
+
const loaded = await loadPluginsFull(pluginSpecs, config, logger);
|
|
156
|
+
return loaded.flatMap((p) => p.tools);
|
|
157
|
+
}
|
|
158
|
+
export async function loadOnePluginFull(spec, config, logger, existingNames = new Set(), isHotReload = false) {
|
|
159
|
+
// 1. Resolve directory
|
|
160
|
+
let pluginDir;
|
|
161
|
+
try {
|
|
162
|
+
pluginDir = resolvePluginDir(spec);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
logger.warn(`Plugin "${spec}" — cannot resolve path: ${err instanceof Error ? err.message : String(err)}`);
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
// 2. Read & parse manifest
|
|
169
|
+
const manifestPath = path.join(pluginDir, MANIFEST_FILE);
|
|
170
|
+
if (!fs.existsSync(manifestPath)) {
|
|
171
|
+
logger.warn(`Plugin "${spec}" — manifest not found at ${manifestPath}`);
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
let rawManifest;
|
|
175
|
+
try {
|
|
176
|
+
rawManifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
logger.warn(`Plugin "${spec}" — failed to parse ${MANIFEST_FILE}: ${err instanceof Error ? err.message : String(err)}`);
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
const validation = validateManifest(rawManifest, spec);
|
|
183
|
+
if (!validation.ok) {
|
|
184
|
+
logger.warn(`Plugin "${spec}" — invalid manifest: ${validation.reason}`);
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const manifest = validation.manifest;
|
|
188
|
+
// 3. Version check
|
|
189
|
+
if (manifest.minBridgeVersion &&
|
|
190
|
+
!semverGte(BRIDGE_VERSION, manifest.minBridgeVersion)) {
|
|
191
|
+
logger.warn(`Plugin "${manifest.name}" — requires bridge >= ${manifest.minBridgeVersion}, running ${BRIDGE_VERSION} (loading anyway)`);
|
|
192
|
+
}
|
|
193
|
+
// 4. Log startup info
|
|
194
|
+
const desc = manifest.description ? ` — ${manifest.description}` : "";
|
|
195
|
+
const perms = manifest.permissions && manifest.permissions.length > 0
|
|
196
|
+
? ` [permissions: ${manifest.permissions.join(", ")}]`
|
|
197
|
+
: "";
|
|
198
|
+
logger.info(`Loading plugin "${manifest.name}"${manifest.version ? ` v${manifest.version}` : ""}${desc}${perms}`);
|
|
199
|
+
// 5. Dynamic import
|
|
200
|
+
const entrypointPath = path.resolve(pluginDir, manifest.entrypoint);
|
|
201
|
+
// Prevent entrypoint path traversal — the resolved path must stay inside pluginDir
|
|
202
|
+
if (path.relative(pluginDir, entrypointPath).startsWith("..")) {
|
|
203
|
+
logger.warn(`Plugin "${manifest.name}" — entrypoint path "${manifest.entrypoint}" escapes plugin directory (resolved to ${entrypointPath})`);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
let mod;
|
|
207
|
+
const ext = path.extname(entrypointPath).toLowerCase();
|
|
208
|
+
const isCjs = ext === ".cjs" ||
|
|
209
|
+
(ext === ".js" &&
|
|
210
|
+
(() => {
|
|
211
|
+
// Detect CJS by reading the nearest package.json "type" field.
|
|
212
|
+
// A .js file is CJS unless "type": "module" is set.
|
|
213
|
+
try {
|
|
214
|
+
let dir = path.dirname(entrypointPath);
|
|
215
|
+
while (true) {
|
|
216
|
+
const pkgPath = path.join(dir, "package.json");
|
|
217
|
+
if (fs.existsSync(pkgPath)) {
|
|
218
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
219
|
+
return pkg.type !== "module";
|
|
220
|
+
}
|
|
221
|
+
const parent = path.dirname(dir);
|
|
222
|
+
if (parent === dir)
|
|
223
|
+
break;
|
|
224
|
+
dir = parent;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Can't determine — assume ESM for safety (won't break ESM plugins)
|
|
229
|
+
}
|
|
230
|
+
return true; // default: CJS if no "type": "module" found
|
|
231
|
+
})());
|
|
232
|
+
try {
|
|
233
|
+
if (isCjs) {
|
|
234
|
+
// For CJS plugins, use createRequire + delete require.cache for reliable hot-reload.
|
|
235
|
+
// The ESM ?t= query-string approach doesn't work for CJS modules loaded via require().
|
|
236
|
+
const req = createRequire(entrypointPath);
|
|
237
|
+
// Invalidate the module and all its CJS children from the require cache
|
|
238
|
+
const visited = new Set();
|
|
239
|
+
function invalidateCjsCache(modPath) {
|
|
240
|
+
if (visited.has(modPath))
|
|
241
|
+
return;
|
|
242
|
+
visited.add(modPath);
|
|
243
|
+
const cached = req.cache?.[modPath];
|
|
244
|
+
if (cached) {
|
|
245
|
+
// Recurse into children before deleting the parent
|
|
246
|
+
for (const child of cached.children ?? []) {
|
|
247
|
+
invalidateCjsCache(child.filename);
|
|
248
|
+
}
|
|
249
|
+
delete req.cache?.[modPath];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
invalidateCjsCache(require.resolve(entrypointPath));
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// resolve may fail if not yet loaded — that's fine, just load fresh
|
|
257
|
+
}
|
|
258
|
+
mod = req(entrypointPath);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
// For ESM (.mjs or .js with "type": "module"), append a timestamp query string
|
|
262
|
+
// to attempt cache-busting. Note: Node's ESM loader may not honour query strings
|
|
263
|
+
// in all versions — this is a best-effort approach. Plugins should avoid top-level
|
|
264
|
+
// mutable state if hot-reload correctness is required.
|
|
265
|
+
const importUrl = `${pathToFileURL(entrypointPath).href}?t=${Date.now()}`;
|
|
266
|
+
if (isHotReload) {
|
|
267
|
+
logger.warn(`Plugin "${manifest.name}" — ESM hot-reload uses query-string cache busting, which may ` +
|
|
268
|
+
`not be fully reliable in all Node versions. Avoid top-level mutable state for correct hot-reload behaviour.`);
|
|
269
|
+
}
|
|
270
|
+
mod = await import(importUrl);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
logger.warn(`Plugin "${manifest.name}" — failed to import ${entrypointPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
// Accept either default export or named `register` export
|
|
278
|
+
const registerFn = mod.register ??
|
|
279
|
+
mod.default;
|
|
280
|
+
if (typeof registerFn !== "function") {
|
|
281
|
+
logger.warn(`Plugin "${manifest.name}" — entrypoint must export a "register" function (or default export)`);
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
// 6. Build context
|
|
285
|
+
const safeConfig = {
|
|
286
|
+
workspace: config.workspace,
|
|
287
|
+
workspaceFolders: config.workspaceFolders,
|
|
288
|
+
commandTimeout: config.commandTimeout,
|
|
289
|
+
maxResultSize: config.maxResultSize,
|
|
290
|
+
};
|
|
291
|
+
const pluginLogger = {
|
|
292
|
+
info: (msg, data) => logger.info(`[plugin:${manifest.name}] ${msg}`, data),
|
|
293
|
+
warn: (msg, data) => logger.warn(`[plugin:${manifest.name}] ${msg}`, data),
|
|
294
|
+
error: (msg, data) => logger.error(`[plugin:${manifest.name}] ${msg}`, data),
|
|
295
|
+
debug: (msg, data) => logger.debug(`[plugin:${manifest.name}] ${msg}`, data),
|
|
296
|
+
};
|
|
297
|
+
const context = {
|
|
298
|
+
workspace: config.workspace,
|
|
299
|
+
workspaceFolders: config.workspaceFolders,
|
|
300
|
+
config: safeConfig,
|
|
301
|
+
logger: pluginLogger,
|
|
302
|
+
};
|
|
303
|
+
// 7. Call register()
|
|
304
|
+
let registration;
|
|
305
|
+
try {
|
|
306
|
+
registration = await registerFn(context);
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
logger.warn(`Plugin "${manifest.name}" — register() threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
if (typeof registration !== "object" ||
|
|
313
|
+
registration === null ||
|
|
314
|
+
!Array.isArray(registration.tools)) {
|
|
315
|
+
logger.warn(`Plugin "${manifest.name}" — register() must return { tools: [...] }`);
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
if (registration.tools.length === 0) {
|
|
319
|
+
logger.warn(`Plugin "${manifest.name}" — registered 0 tools`);
|
|
320
|
+
return { spec, pluginDir, manifest, tools: [] };
|
|
321
|
+
}
|
|
322
|
+
if (registration.tools.length > MAX_TOOLS_PER_PLUGIN) {
|
|
323
|
+
logger.warn(`Plugin "${manifest.name}" — too many tools (${registration.tools.length} > ${MAX_TOOLS_PER_PLUGIN}); skipping plugin`);
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
// 8. Validate tool names against prefix and collision
|
|
327
|
+
const pluginToolNames = [];
|
|
328
|
+
for (const t of registration.tools) {
|
|
329
|
+
const name = t.schema?.name;
|
|
330
|
+
if (typeof name !== "string" || !/^[a-zA-Z0-9_]+$/.test(name)) {
|
|
331
|
+
logger.warn(`Plugin "${manifest.name}" — tool has invalid name "${String(name)}"; rejecting plugin`);
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
if (!name.startsWith(manifest.toolNamePrefix)) {
|
|
335
|
+
logger.warn(`Plugin "${manifest.name}" — tool "${name}" does not start with declared prefix "${manifest.toolNamePrefix}"; rejecting plugin`);
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
if (existingNames.has(name) || pluginToolNames.includes(name)) {
|
|
339
|
+
logger.warn(`Plugin "${manifest.name}" — tool name "${name}" collides with an already-registered tool; rejecting plugin`);
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
pluginToolNames.push(name);
|
|
343
|
+
}
|
|
344
|
+
// 9. Build final tool list
|
|
345
|
+
const tools = registration.tools.map((t) => ({
|
|
346
|
+
schema: t.schema,
|
|
347
|
+
handler: t.handler,
|
|
348
|
+
timeoutMs: t.timeoutMs,
|
|
349
|
+
}));
|
|
350
|
+
logger.info(`Plugin "${manifest.name}" — ${tools.length} tool${tools.length === 1 ? "" : "s"} registered: ${tools.map((t) => t.schema.name).join(", ")}`);
|
|
351
|
+
// Update existingNames synchronously before returning so the next plugin
|
|
352
|
+
// sees these names as already registered during its collision check.
|
|
353
|
+
for (const t of tools)
|
|
354
|
+
existingNames.add(t.schema.name);
|
|
355
|
+
return { spec, pluginDir, manifest, tools };
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=pluginLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginLoader.js","sourceRoot":"","sources":["../src/pluginLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Config } from "./config.js";
|
|
2
|
+
import type { Logger } from "./logger.js";
|
|
3
|
+
import { type LoadedPlugin, type LoadedPluginTool } from "./pluginLoader.js";
|
|
4
|
+
import type { McpTransport } from "./transport.js";
|
|
5
|
+
export declare class PluginWatcher {
|
|
6
|
+
private config;
|
|
7
|
+
private logger;
|
|
8
|
+
private sendListChanged;
|
|
9
|
+
private watchers;
|
|
10
|
+
private debounceTimers;
|
|
11
|
+
private loadedPlugins;
|
|
12
|
+
private transports;
|
|
13
|
+
private stopped;
|
|
14
|
+
private reloadInFlight;
|
|
15
|
+
constructor(config: Config, logger: Logger, sendListChanged: () => void);
|
|
16
|
+
start(plugins: LoadedPlugin[]): void;
|
|
17
|
+
addTransport(transport: McpTransport): void;
|
|
18
|
+
removeTransport(transport: McpTransport): void;
|
|
19
|
+
getTools(): LoadedPluginTool[];
|
|
20
|
+
stop(): void;
|
|
21
|
+
private scheduleReload;
|
|
22
|
+
reloadPlugin(spec: string): Promise<void>;
|
|
23
|
+
private _reloadPluginInner;
|
|
24
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { loadOnePluginFull, } from "./pluginLoader.js";
|
|
3
|
+
const DEBOUNCE_MS = 300;
|
|
4
|
+
export class PluginWatcher {
|
|
5
|
+
config;
|
|
6
|
+
logger;
|
|
7
|
+
sendListChanged;
|
|
8
|
+
watchers = new Map();
|
|
9
|
+
debounceTimers = new Map();
|
|
10
|
+
loadedPlugins = new Map(); // keyed by spec
|
|
11
|
+
transports = new Set();
|
|
12
|
+
stopped = false;
|
|
13
|
+
reloadInFlight = new Set();
|
|
14
|
+
constructor(config, logger, sendListChanged) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
this.sendListChanged = sendListChanged;
|
|
18
|
+
}
|
|
19
|
+
start(plugins) {
|
|
20
|
+
for (const plugin of plugins) {
|
|
21
|
+
this.loadedPlugins.set(plugin.spec, plugin);
|
|
22
|
+
try {
|
|
23
|
+
const watcher = fs.watch(plugin.pluginDir, { recursive: false }, (_event, _filename) => {
|
|
24
|
+
this.scheduleReload(plugin.spec);
|
|
25
|
+
});
|
|
26
|
+
this.watchers.set(plugin.spec, watcher);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
this.logger.warn(`[plugin-watch] Could not watch "${plugin.pluginDir}": ${err instanceof Error ? err.message : String(err)}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
addTransport(transport) {
|
|
34
|
+
this.transports.add(transport);
|
|
35
|
+
}
|
|
36
|
+
removeTransport(transport) {
|
|
37
|
+
this.transports.delete(transport);
|
|
38
|
+
}
|
|
39
|
+
getTools() {
|
|
40
|
+
return [...this.loadedPlugins.values()].flatMap((p) => p.tools);
|
|
41
|
+
}
|
|
42
|
+
stop() {
|
|
43
|
+
this.stopped = true;
|
|
44
|
+
for (const timer of this.debounceTimers.values())
|
|
45
|
+
clearTimeout(timer);
|
|
46
|
+
this.debounceTimers.clear();
|
|
47
|
+
for (const watcher of this.watchers.values()) {
|
|
48
|
+
try {
|
|
49
|
+
watcher.close();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* ignore */
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
this.watchers.clear();
|
|
56
|
+
}
|
|
57
|
+
scheduleReload(spec) {
|
|
58
|
+
if (this.stopped)
|
|
59
|
+
return;
|
|
60
|
+
const existing = this.debounceTimers.get(spec);
|
|
61
|
+
if (existing)
|
|
62
|
+
clearTimeout(existing);
|
|
63
|
+
const timer = setTimeout(() => {
|
|
64
|
+
this.debounceTimers.delete(spec);
|
|
65
|
+
void this.reloadPlugin(spec);
|
|
66
|
+
}, DEBOUNCE_MS);
|
|
67
|
+
this.debounceTimers.set(spec, timer);
|
|
68
|
+
}
|
|
69
|
+
async reloadPlugin(spec) {
|
|
70
|
+
if (this.reloadInFlight.has(spec)) {
|
|
71
|
+
// Another reload is already running; schedule one more after it finishes
|
|
72
|
+
this.scheduleReload(spec);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.reloadInFlight.add(spec);
|
|
76
|
+
try {
|
|
77
|
+
await this._reloadPluginInner(spec);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this.reloadInFlight.delete(spec);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async _reloadPluginInner(spec) {
|
|
84
|
+
const old = this.loadedPlugins.get(spec);
|
|
85
|
+
if (!old)
|
|
86
|
+
return;
|
|
87
|
+
this.logger.info(`[plugin-watch] Reloading plugin "${old.manifest.name}" ...`);
|
|
88
|
+
// Collision names = all names from OTHER plugins
|
|
89
|
+
const otherNames = new Set();
|
|
90
|
+
for (const [s, p] of this.loadedPlugins) {
|
|
91
|
+
if (s !== spec) {
|
|
92
|
+
for (const t of p.tools)
|
|
93
|
+
otherNames.add(t.schema.name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
let fresh;
|
|
97
|
+
try {
|
|
98
|
+
fresh = await loadOnePluginFull(spec, this.config, this.logger, otherNames, true);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
this.logger.warn(`[plugin-watch] Reload threw for "${old.manifest.name}": ${err instanceof Error ? err.message : String(err)}; keeping old tools`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (!fresh) {
|
|
105
|
+
this.logger.warn(`[plugin-watch] Reload failed for "${old.manifest.name}"; keeping old tools`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Apply to all active transports
|
|
109
|
+
for (const transport of this.transports) {
|
|
110
|
+
try {
|
|
111
|
+
transport.deregisterToolsByPrefix(old.manifest.toolNamePrefix);
|
|
112
|
+
for (const t of fresh.tools) {
|
|
113
|
+
transport.replaceTool(t.schema, t.handler, t.timeoutMs);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
this.logger.warn(`[plugin-watch] Failed to patch transport for "${fresh.manifest.name}": ${err instanceof Error ? err.message : String(err)}; attempting rollback`);
|
|
118
|
+
// Rollback: remove any partially-registered tools and restore old ones.
|
|
119
|
+
// Uses old prefix — if the plugin renamed its prefix between reloads the
|
|
120
|
+
// orphaned fresh-prefix tools will remain until the next successful reload.
|
|
121
|
+
// Prefix renames are uncommon and self-heal on the next save.
|
|
122
|
+
try {
|
|
123
|
+
transport.deregisterToolsByPrefix(old.manifest.toolNamePrefix);
|
|
124
|
+
for (const t of old.tools) {
|
|
125
|
+
transport.replaceTool(t.schema, t.handler, t.timeoutMs);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
this.logger.warn(`[plugin-watch] Rollback also failed for "${old.manifest.name}"`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
this.loadedPlugins.set(spec, fresh);
|
|
134
|
+
const names = fresh.tools.map((t) => t.schema.name).join(", ");
|
|
135
|
+
this.logger.info(`[plugin-watch] Plugin "${fresh.manifest.name}" reloaded — ${fresh.tools.length} tool(s)${names ? `: ${names}` : ""}`);
|
|
136
|
+
this.sendListChanged();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=pluginWatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginWatcher.js","sourceRoot":"","sources":["../src/pluginWatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface RegisterResult {
|
|
2
|
+
action: "added" | "already-wired" | "error";
|
|
3
|
+
path: string;
|
|
4
|
+
hookCommand: string;
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveHookScriptPath(baseDir?: string): string;
|
|
8
|
+
export declare function registerPreToolUseHook(ccSettingsPath: string, opts?: {
|
|
9
|
+
hookScriptPath?: string;
|
|
10
|
+
}): RegisterResult;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const HOOK_EVENT = "PreToolUse";
|
|
5
|
+
const HOOK_MARKER = "patchwork-approval-hook";
|
|
6
|
+
export function resolveHookScriptPath(baseDir) {
|
|
7
|
+
// When called from dist/, src/ lives one directory up in a dev checkout
|
|
8
|
+
// or two directories up in an npm install (node_modules/patchwork-os/…).
|
|
9
|
+
// Resolving relative to this file's URL handles both.
|
|
10
|
+
const here = baseDir ?? path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
return path.resolve(here, "..", "scripts", "patchwork-approval-hook.sh");
|
|
12
|
+
}
|
|
13
|
+
export function registerPreToolUseHook(ccSettingsPath, opts = {}) {
|
|
14
|
+
const hookScriptPath = opts.hookScriptPath ?? resolveHookScriptPath();
|
|
15
|
+
const hookCommand = `bash ${quoteIfNeeded(hookScriptPath)}`;
|
|
16
|
+
try {
|
|
17
|
+
let ccSettings = {};
|
|
18
|
+
if (existsSync(ccSettingsPath)) {
|
|
19
|
+
ccSettings = JSON.parse(readFileSync(ccSettingsPath, "utf-8"));
|
|
20
|
+
}
|
|
21
|
+
const allHooks = (ccSettings.hooks ?? {});
|
|
22
|
+
const entries = (allHooks[HOOK_EVENT] ?? []).map(normalize);
|
|
23
|
+
const alreadyWired = entries.some((entry) => (entry.hooks ?? []).some((h) => typeof h.command === "string" && h.command.includes(HOOK_MARKER)));
|
|
24
|
+
if (alreadyWired) {
|
|
25
|
+
return { action: "already-wired", path: ccSettingsPath, hookCommand };
|
|
26
|
+
}
|
|
27
|
+
entries.push({
|
|
28
|
+
matcher: "*",
|
|
29
|
+
hooks: [{ type: "command", command: hookCommand }],
|
|
30
|
+
});
|
|
31
|
+
allHooks[HOOK_EVENT] = entries;
|
|
32
|
+
ccSettings.hooks = allHooks;
|
|
33
|
+
writeFileSync(ccSettingsPath, `${JSON.stringify(ccSettings, null, 2)}\n`);
|
|
34
|
+
return { action: "added", path: ccSettingsPath, hookCommand };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return {
|
|
38
|
+
action: "error",
|
|
39
|
+
path: ccSettingsPath,
|
|
40
|
+
hookCommand,
|
|
41
|
+
error: err instanceof Error ? err.message : String(err),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function normalize(e) {
|
|
46
|
+
if (e && Array.isArray(e.hooks)) {
|
|
47
|
+
return {
|
|
48
|
+
matcher: e.matcher ?? "",
|
|
49
|
+
hooks: e.hooks ?? [],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { matcher: "", hooks: [e] };
|
|
53
|
+
}
|
|
54
|
+
function quoteIfNeeded(p) {
|
|
55
|
+
return /[\s"']/.test(p) ? `"${p.replace(/"/g, '\\"')}"` : p;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=preToolUseHook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preToolUseHook.js","sourceRoot":"","sources":["../src/preToolUseHook.ts"],"names":[],"mappings":"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"}
|