@herbertgao/pi-extensions 2026.8.11 → 2026.8.12
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.md +18 -10
- package/{node_modules/@herbertgao/pi-inline-skills/LICENSE → THIRD_PARTY_NOTICES.md} +15 -1
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
- package/node_modules/@czottmann/pi-automode/README.md +5 -3
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
- package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
- package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
- package/node_modules/@czottmann/pi-automode/package.json +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
- package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
- package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
- package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +6 -6
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
- package/node_modules/@tifan/pi-handoff/package.json +43 -0
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
- package/node_modules/@tifan/pi-recap/package.json +42 -0
- package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
- package/node_modules/@tifan/pi-rename/package.json +47 -0
- package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
- package/node_modules/pi-lens/CHANGELOG.md +96 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
- package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
- package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
- package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
- package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
- package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
- package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
- package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
- package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
- package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
- package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
- package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
- package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
- package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
- package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
- package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
- package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
- package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
- package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
- package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
- package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
- package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
- package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
- package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
- package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
- package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
- package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
- package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
- package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
- package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
- package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
- package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
- package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
- package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
- package/node_modules/pi-lens/dist/i18n.js +13 -5
- package/node_modules/pi-lens/dist/index.js +10797 -8627
- package/node_modules/pi-lens/dist/mcp/server.js +3 -1
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
- package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
- package/node_modules/pi-lens/package.json +160 -156
- package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
- package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +34 -0
- package/node_modules/pi-mcp-adapter/README.md +42 -13
- package/node_modules/pi-mcp-adapter/commands.ts +4 -2
- package/node_modules/pi-mcp-adapter/config.ts +35 -5
- package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
- package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +1077 -0
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
- package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
- package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
- package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
- package/node_modules/pi-mcp-adapter/index.ts +204 -82
- package/node_modules/pi-mcp-adapter/init.ts +36 -29
- package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
- package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
- package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
- package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
- package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
- package/node_modules/pi-mcp-adapter/package.json +24 -6
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
- package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
- package/node_modules/pi-mcp-adapter/state.ts +1 -3
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
- package/node_modules/pi-mcp-adapter/types.ts +48 -1
- package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
- package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
- package/node_modules/pi-mcp-adapter/utils.ts +21 -19
- package/node_modules/pi-web-access/CHANGELOG.md +26 -0
- package/node_modules/pi-web-access/README.md +71 -14
- package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
- package/node_modules/pi-web-access/credential-source.ts +6 -2
- package/node_modules/pi-web-access/curator-page.ts +5 -3
- package/node_modules/pi-web-access/curator-server.ts +2 -1
- package/node_modules/pi-web-access/extract.ts +89 -9
- package/node_modules/pi-web-access/fetch-params.ts +13 -0
- package/node_modules/pi-web-access/gemini-adc.ts +298 -0
- package/node_modules/pi-web-access/gemini-api.ts +59 -15
- package/node_modules/pi-web-access/gemini-search.ts +58 -18
- package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
- package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
- package/node_modules/pi-web-access/gemini-web.ts +9 -3
- package/node_modules/pi-web-access/github-api.ts +5 -4
- package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
- package/node_modules/pi-web-access/index.ts +403 -297
- package/node_modules/pi-web-access/kimi-search.ts +234 -0
- package/node_modules/pi-web-access/openai-search.ts +118 -21
- package/node_modules/pi-web-access/package.json +3 -2
- package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
- package/node_modules/pi-web-access/utils.ts +307 -1
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +40 -37
- package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
- package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
- package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
- package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
- package/node_modules/@herbertgao/pi-mermaid-open/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
- package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
- package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/package.json +0 -55
- package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-rename/package.json +0 -63
- package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
- package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
- /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import type { AgentToolResult, ExtensionAPI, ToolInfo } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import type { McpExtensionState } from "./state.ts";
|
|
4
|
+
import { isServerDisabled, type McpConfig } from "./types.ts";
|
|
5
|
+
import { isServerCacheValid, type MetadataCache } from "./metadata-cache.ts";
|
|
6
|
+
import { executeCall } from "./proxy-modes.ts";
|
|
7
|
+
import { createMcpProxyToolCallRenderer, createMcpToolResultRenderer, resolveMcpToolRenderOptions, type McpToolRenderOptions, type RenderTheme, type McpToolRenderContext } from "./tool-result-renderer.ts";
|
|
8
|
+
export { namespaceProxyName } from "./mcp-references.ts";
|
|
9
|
+
import { hasCallableCachedTargets, isMcpServerDirectlyRegistered, namespaceProxyName, type DirectToolSelectorOverride } from "./mcp-references.ts";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Namespace-proxy tool registration for proxy-only MCP servers.
|
|
13
|
+
*
|
|
14
|
+
* For each configured proxy-only server (no `directTools: true` and not a
|
|
15
|
+
* runtime server forced direct), register exactly one tool named
|
|
16
|
+
* `mcp__<server>` (matching the harness `_shared/mcp-tools` resolver's
|
|
17
|
+
* `namespaceProxyName`). Its execute accepts `{tool, args}` and forwards
|
|
18
|
+
* through the adapter's existing `executeCall`, so it inherits the same
|
|
19
|
+
* auto-auth, session recovery, output guard, and approval rules as the
|
|
20
|
+
* single `mcp` proxy tool — without polluting the prompt with one entry
|
|
21
|
+
* per tool.
|
|
22
|
+
*
|
|
23
|
+
* This unblocks `mcp:<server>` references from `tool-groups` and
|
|
24
|
+
* `slow-mode` against proxy-only servers without flipping `directTools: true`.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export interface NamespaceProxySpec {
|
|
28
|
+
serverName: string;
|
|
29
|
+
toolName: string;
|
|
30
|
+
description: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function namespaceProxyCandidate(
|
|
34
|
+
config: McpConfig,
|
|
35
|
+
cache: MetadataCache,
|
|
36
|
+
envOverride: DirectToolSelectorOverride | null,
|
|
37
|
+
existingDirectNames: Set<string>,
|
|
38
|
+
serverName: string,
|
|
39
|
+
): NamespaceProxySpec | null {
|
|
40
|
+
const definition = config.mcpServers[serverName];
|
|
41
|
+
if (!definition || isServerDisabled(definition)) return null;
|
|
42
|
+
if (isMcpServerDirectlyRegistered(definition, config.settings, serverName, envOverride)) return null;
|
|
43
|
+
const entry = cache.servers?.[serverName];
|
|
44
|
+
if (!entry || !isServerCacheValid(entry, definition) || !hasCallableCachedTargets(entry, definition)) return null;
|
|
45
|
+
const toolName = namespaceProxyName(serverName);
|
|
46
|
+
if (existingDirectNames.has(toolName)) return null;
|
|
47
|
+
return {
|
|
48
|
+
serverName,
|
|
49
|
+
toolName,
|
|
50
|
+
description:
|
|
51
|
+
`Namespace-proxy for MCP server "${serverName}". ` +
|
|
52
|
+
`Forwards \`{tool, args}\` through the adapter's executeCall, so it inherits ` +
|
|
53
|
+
`the same auth / lifecycle / output-guard rules as the \`mcp\` proxy.`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function filterCollidingNamespaceProxyTools(candidates: NamespaceProxySpec[]): NamespaceProxySpec[] {
|
|
58
|
+
const names = new Map<string, NamespaceProxySpec[]>();
|
|
59
|
+
for (const spec of candidates) {
|
|
60
|
+
const colliding = names.get(spec.toolName) ?? [];
|
|
61
|
+
colliding.push(spec);
|
|
62
|
+
names.set(spec.toolName, colliding);
|
|
63
|
+
}
|
|
64
|
+
return candidates.filter((spec) => {
|
|
65
|
+
const colliding = names.get(spec.toolName)!;
|
|
66
|
+
if (colliding.length === 1) return true;
|
|
67
|
+
if (colliding[0] === spec) {
|
|
68
|
+
console.warn(`MCP: skipping namespace proxy "${spec.toolName}" because servers ${colliding.map(({ serverName }) => `"${serverName}"`).sort().join(", ")} normalize to the same name`);
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function resolveNamespaceProxyTools(
|
|
75
|
+
config: McpConfig | null,
|
|
76
|
+
cache: MetadataCache | null,
|
|
77
|
+
envOverride: DirectToolSelectorOverride | null,
|
|
78
|
+
existingDirectNames: Set<string>,
|
|
79
|
+
unavailableServers: ReadonlySet<string>,
|
|
80
|
+
): NamespaceProxySpec[] {
|
|
81
|
+
if (!config || !cache) return [];
|
|
82
|
+
return filterCollidingNamespaceProxyTools(
|
|
83
|
+
Object.keys(config.mcpServers)
|
|
84
|
+
.map((serverName) => namespaceProxyCandidate(config, cache, envOverride, existingDirectNames, serverName))
|
|
85
|
+
.filter((spec): spec is NamespaceProxySpec => spec !== null),
|
|
86
|
+
).filter((spec) => !unavailableServers.has(spec.serverName));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Lazily-required reference to the agent state — passed as a closure so the
|
|
91
|
+
* namespace proxy tool's execute can call `executeCall` once `state` exists.
|
|
92
|
+
* `getInitPromise` lets the executor await the first initialization round
|
|
93
|
+
* the same way `createDirectToolExecutor` does.
|
|
94
|
+
*/
|
|
95
|
+
export type GetState = () => McpExtensionState | null;
|
|
96
|
+
export type GetInitPromise = () => Promise<McpExtensionState> | null;
|
|
97
|
+
export type GetPiTools = () => ToolInfo[];
|
|
98
|
+
|
|
99
|
+
function namespaceExecute(
|
|
100
|
+
getState: GetState,
|
|
101
|
+
getInitPromise: GetInitPromise,
|
|
102
|
+
serverName: string,
|
|
103
|
+
getPiTools: GetPiTools,
|
|
104
|
+
) {
|
|
105
|
+
return async (
|
|
106
|
+
_toolCallId: string,
|
|
107
|
+
params: { tool?: string; args?: Record<string, unknown> },
|
|
108
|
+
signal: AbortSignal | undefined,
|
|
109
|
+
): Promise<AgentToolResult<Record<string, unknown>>> => {
|
|
110
|
+
if (typeof params.tool !== "string" || params.tool.length === 0) {
|
|
111
|
+
return {
|
|
112
|
+
content: [{ type: "text" as const, text: `mcp__${serverName} requires a \`tool\` parameter naming the underlying MCP tool.` }],
|
|
113
|
+
details: { error: "missing_tool", server: serverName },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
let state = getState();
|
|
117
|
+
if (!state) {
|
|
118
|
+
const initPromise = getInitPromise();
|
|
119
|
+
if (initPromise) {
|
|
120
|
+
try {
|
|
121
|
+
state = await initPromise;
|
|
122
|
+
} catch (error) {
|
|
123
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
124
|
+
return {
|
|
125
|
+
content: [{ type: "text" as const, text: `MCP initialization failed for ${serverName}: ${message}` }],
|
|
126
|
+
details: { error: "init_failed", server: serverName, message },
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (!state) {
|
|
132
|
+
return {
|
|
133
|
+
content: [{ type: "text" as const, text: `MCP not initialized for ${serverName}.` }],
|
|
134
|
+
details: { error: "not_initialized", server: serverName },
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return executeCall(
|
|
138
|
+
state,
|
|
139
|
+
params.tool,
|
|
140
|
+
params.args ?? {},
|
|
141
|
+
serverName,
|
|
142
|
+
getPiTools,
|
|
143
|
+
signal,
|
|
144
|
+
"proxy",
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const parameters = Type.Object({
|
|
150
|
+
tool: Type.String({ description: "Underlying MCP tool name to call on this server." }),
|
|
151
|
+
args: Type.Optional(Type.Object({}, {
|
|
152
|
+
additionalProperties: true,
|
|
153
|
+
description: "Arguments for the underlying tool. The exact shape depends on the tool being called; use mcp({ describe: 'server/tool' }) to inspect.",
|
|
154
|
+
})),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
export interface SyncNamespaceProxyToolsInput {
|
|
158
|
+
config: McpConfig | null;
|
|
159
|
+
cache: MetadataCache | null;
|
|
160
|
+
envOverride: DirectToolSelectorOverride | null;
|
|
161
|
+
existingDirectNames: Set<string>;
|
|
162
|
+
activeDirectNames?: ReadonlySet<string>;
|
|
163
|
+
existingNamespaceNames: Set<string>;
|
|
164
|
+
unavailableServers?: ReadonlySet<string>;
|
|
165
|
+
pi: ExtensionAPI;
|
|
166
|
+
getState: GetState;
|
|
167
|
+
getInitPromise: GetInitPromise;
|
|
168
|
+
getPiTools: GetPiTools;
|
|
169
|
+
renderOptions?: McpToolRenderOptions;
|
|
170
|
+
renderShell?: "self" | "default";
|
|
171
|
+
renderResult?: unknown;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface SyncNamespaceProxyToolsResult {
|
|
175
|
+
specs: NamespaceProxySpec[];
|
|
176
|
+
added: string[];
|
|
177
|
+
updated: string[];
|
|
178
|
+
deactivated: string[];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function createNamespaceRenderCall(renderOptions: McpToolRenderOptions, serverName: string) {
|
|
182
|
+
const renderCall = createMcpProxyToolCallRenderer(renderOptions);
|
|
183
|
+
return (args: { tool?: string; args?: Record<string, unknown> }, theme?: RenderTheme, context?: McpToolRenderContext) => renderCall({
|
|
184
|
+
...(args.tool !== undefined ? { tool: args.tool } : {}),
|
|
185
|
+
...(args.args !== undefined ? { args: args.args } : {}),
|
|
186
|
+
server: serverName,
|
|
187
|
+
}, theme, context);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function registerNamespaceProxyTool(
|
|
191
|
+
input: SyncNamespaceProxyToolsInput,
|
|
192
|
+
spec: NamespaceProxySpec,
|
|
193
|
+
renderOptions: McpToolRenderOptions,
|
|
194
|
+
renderShell: "self" | "default",
|
|
195
|
+
renderResult: unknown,
|
|
196
|
+
): void {
|
|
197
|
+
(input.pi.registerTool as (tool: unknown) => unknown)({
|
|
198
|
+
name: spec.toolName,
|
|
199
|
+
label: `MCP: ${spec.serverName}`,
|
|
200
|
+
description: spec.description,
|
|
201
|
+
promptSnippet: `MCP namespace proxy for ${spec.serverName}`,
|
|
202
|
+
parameters,
|
|
203
|
+
renderShell,
|
|
204
|
+
renderCall: createNamespaceRenderCall(renderOptions, spec.serverName),
|
|
205
|
+
renderResult,
|
|
206
|
+
execute: namespaceExecute(
|
|
207
|
+
input.getState,
|
|
208
|
+
input.getInitPromise,
|
|
209
|
+
spec.serverName,
|
|
210
|
+
input.getPiTools,
|
|
211
|
+
),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function getActiveToolsForStaleCleanup(pi: ExtensionAPI, staleNames: string[]): string[] | undefined {
|
|
216
|
+
if (staleNames.length === 0) return undefined;
|
|
217
|
+
try {
|
|
218
|
+
return pi.getActiveTools?.();
|
|
219
|
+
} catch (error) {
|
|
220
|
+
if (error instanceof Error && error.message.includes("Action methods cannot be called during extension loading")) return undefined;
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function deactivateStaleNamespaceTools(input: SyncNamespaceProxyToolsInput, nextNames: Set<string>): string[] {
|
|
226
|
+
const activeDirectNames = input.activeDirectNames ?? new Set<string>();
|
|
227
|
+
const staleNames = [...input.existingNamespaceNames].filter(
|
|
228
|
+
(name) => !nextNames.has(name) && !activeDirectNames.has(name),
|
|
229
|
+
);
|
|
230
|
+
const deactivated: string[] = [];
|
|
231
|
+
const unregisterTool = (input.pi as unknown as {
|
|
232
|
+
unregisterTool?: (name: string) => boolean;
|
|
233
|
+
}).unregisterTool;
|
|
234
|
+
for (const stale of staleNames) {
|
|
235
|
+
if (unregisterTool?.(stale)) deactivated.push(stale);
|
|
236
|
+
}
|
|
237
|
+
const activeTools = getActiveToolsForStaleCleanup(input.pi, staleNames);
|
|
238
|
+
if (!activeTools) return deactivated;
|
|
239
|
+
|
|
240
|
+
const stale = new Set(staleNames);
|
|
241
|
+
const nextActiveTools = activeTools.filter((name) => !stale.has(name));
|
|
242
|
+
if (nextActiveTools.length === activeTools.length) return deactivated;
|
|
243
|
+
|
|
244
|
+
input.pi.setActiveTools(nextActiveTools);
|
|
245
|
+
for (const name of staleNames) {
|
|
246
|
+
if (!deactivated.includes(name)) deactivated.push(name);
|
|
247
|
+
}
|
|
248
|
+
return deactivated;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Idempotent sync of namespace-proxy tool registrations.
|
|
253
|
+
*/
|
|
254
|
+
export function syncNamespaceProxyTools(input: SyncNamespaceProxyToolsInput): SyncNamespaceProxyToolsResult {
|
|
255
|
+
const specs = resolveNamespaceProxyTools(
|
|
256
|
+
input.config,
|
|
257
|
+
input.cache,
|
|
258
|
+
input.envOverride,
|
|
259
|
+
input.existingDirectNames,
|
|
260
|
+
input.unavailableServers ?? new Set(),
|
|
261
|
+
);
|
|
262
|
+
const nextNames = new Set(specs.map((s) => s.toolName));
|
|
263
|
+
const result: SyncNamespaceProxyToolsResult = { specs, added: [], updated: [], deactivated: [] };
|
|
264
|
+
const renderOptions = input.renderOptions ?? resolveMcpToolRenderOptions();
|
|
265
|
+
const renderShell = input.renderShell ?? (renderOptions.resultRendering === "compact" ? "self" : "default");
|
|
266
|
+
const renderResult = input.renderResult ?? createMcpToolResultRenderer(renderOptions);
|
|
267
|
+
|
|
268
|
+
for (const spec of specs) {
|
|
269
|
+
registerNamespaceProxyTool(input, spec, renderOptions, renderShell, renderResult);
|
|
270
|
+
(input.existingNamespaceNames.has(spec.toolName) ? result.updated : result.added).push(spec.toolName);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
result.deactivated.push(...deactivateStaleNamespaceTools(input, nextNames));
|
|
274
|
+
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mcp-adapter",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.28.0",
|
|
4
4
|
"description": "MCP (Model Context Protocol) adapter extension for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.ts",
|
|
@@ -11,14 +11,24 @@
|
|
|
11
11
|
"default": "./index.ts"
|
|
12
12
|
},
|
|
13
13
|
"./types": {
|
|
14
|
-
"types": "./types.ts",
|
|
15
|
-
"import": "./types.
|
|
16
|
-
"default": "./types.
|
|
14
|
+
"types": "./dist/types.d.ts",
|
|
15
|
+
"import": "./dist/types.js",
|
|
16
|
+
"default": "./dist/types.js"
|
|
17
17
|
},
|
|
18
18
|
"./oauth": {
|
|
19
19
|
"types": "./oauth.ts",
|
|
20
20
|
"import": "./oauth.ts",
|
|
21
21
|
"default": "./oauth.ts"
|
|
22
|
+
},
|
|
23
|
+
"./config": {
|
|
24
|
+
"types": "./dist/config.d.ts",
|
|
25
|
+
"import": "./dist/config.js",
|
|
26
|
+
"default": "./dist/config.js"
|
|
27
|
+
},
|
|
28
|
+
"./metadata-cache": {
|
|
29
|
+
"types": "./dist/metadata-cache.d.ts",
|
|
30
|
+
"import": "./dist/metadata-cache.js",
|
|
31
|
+
"default": "./dist/metadata-cache.js"
|
|
22
32
|
}
|
|
23
33
|
},
|
|
24
34
|
"license": "MIT",
|
|
@@ -30,8 +40,12 @@
|
|
|
30
40
|
"pi-mcp-adapter": "cli.js"
|
|
31
41
|
},
|
|
32
42
|
"scripts": {
|
|
43
|
+
"build:public": "tsc -p tsconfig.public.json",
|
|
44
|
+
"prepack": "npm run build:public",
|
|
33
45
|
"typecheck": "tsc --noEmit",
|
|
34
|
-
"test": "
|
|
46
|
+
"test": "node test-runner.mjs",
|
|
47
|
+
"test:vitest": "vitest run",
|
|
48
|
+
"test:public-exports": "npm run build:public && node --test public-exports.test.mjs",
|
|
35
49
|
"test:watch": "vitest",
|
|
36
50
|
"test:coverage": "vitest run --coverage",
|
|
37
51
|
"test:oauth": "PI_MCP_ADAPTER_TEST_AUTH_STORE=memory PI_MCP_ADAPTER_DISABLE_AUTH_CACHE=1 node --import tsx --test --test-concurrency=1 oauth-public-api.test.ts mcp-auth.test.ts mcp-auth-flow.test.ts mcp-callback-server.test.ts mcp-oauth-provider.test.ts",
|
|
@@ -76,9 +90,12 @@
|
|
|
76
90
|
"search-ranking.ts",
|
|
77
91
|
"tool-approval.ts",
|
|
78
92
|
"init.ts",
|
|
93
|
+
"failure-backoff.ts",
|
|
79
94
|
"ui-session.ts",
|
|
80
95
|
"proxy-modes.ts",
|
|
81
96
|
"direct-tools.ts",
|
|
97
|
+
"namespace-tools.ts",
|
|
98
|
+
"mcp-references.ts",
|
|
82
99
|
"commands.ts",
|
|
83
100
|
"prompts.ts",
|
|
84
101
|
"onboarding-state.ts",
|
|
@@ -131,7 +148,8 @@
|
|
|
131
148
|
"skills",
|
|
132
149
|
"README.md",
|
|
133
150
|
"CHANGELOG.md",
|
|
134
|
-
"LICENSE"
|
|
151
|
+
"LICENSE",
|
|
152
|
+
"dist"
|
|
135
153
|
],
|
|
136
154
|
"dependencies": {
|
|
137
155
|
"@modelcontextprotocol/client": "2.0.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentToolResult, ToolInfo } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { UrlElicitationRequiredError, type Client } from "@modelcontextprotocol/client";
|
|
2
|
+
import { UrlElicitationRequiredError, type Client, type Progress, type RequestOptions } from "@modelcontextprotocol/client";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import type { McpExtensionState } from "./state.ts";
|
|
5
5
|
import type { ToolMetadata, McpContent } from "./types.ts";
|
|
@@ -18,6 +18,7 @@ import { authenticate, completeAuthFromInput, startAuth, supportsOAuth } from ".
|
|
|
18
18
|
import { SessionRecoveryAuthRequiredError, withSessionRecovery } from "./session-recovery.ts";
|
|
19
19
|
import { paginate, rankSuggestions, rankToolMatches, resolveSearchKeywords } from "./search-ranking.ts";
|
|
20
20
|
import { ensureToolCallApproved, isToolCallApprovalRequired } from "./tool-approval.ts";
|
|
21
|
+
import { isServerInActiveFailureBackoff } from "./failure-backoff.ts";
|
|
21
22
|
|
|
22
23
|
type ProxyToolResult = AgentToolResult<Record<string, unknown>>;
|
|
23
24
|
type ClientCallToolResult = Awaited<ReturnType<Client["callTool"]>>;
|
|
@@ -37,6 +38,30 @@ type AutoAuthResult =
|
|
|
37
38
|
| { status: "success" }
|
|
38
39
|
| { status: "failed"; message: string };
|
|
39
40
|
|
|
41
|
+
let nextProgressInvocationId = 1;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Bridges SDK request-local progress callbacks to the interactive UI notify
|
|
45
|
+
* path (#437 item 3). The SDK owns `_meta.progressToken` injection when
|
|
46
|
+
* `onprogress` is set; this never writes the token manually.
|
|
47
|
+
*/
|
|
48
|
+
function withUiProgressBridge(
|
|
49
|
+
options: RequestOptions | undefined,
|
|
50
|
+
ui: McpExtensionState["ui"],
|
|
51
|
+
serverName: string,
|
|
52
|
+
toolName: string,
|
|
53
|
+
): RequestOptions | undefined {
|
|
54
|
+
if (!ui) return options;
|
|
55
|
+
const label = `MCP ${serverName}/${toolName}#${nextProgressInvocationId++}`;
|
|
56
|
+
return {
|
|
57
|
+
...options,
|
|
58
|
+
onprogress: (progress: Progress) => {
|
|
59
|
+
const ratio = `${progress.progress}${progress.total === undefined ? "" : `/${progress.total}`}`;
|
|
60
|
+
ui.notify(progress.message ? `${label}: ${progress.message} (${ratio})` : `${label}: ${ratio}`, "info");
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
40
65
|
function getToolMatches(metadata: ToolMetadata[] | undefined, toolName: string, exact: boolean): ToolMetadata[] {
|
|
41
66
|
if (!metadata) return [];
|
|
42
67
|
if (exact) return metadata.filter(tool => tool.name === toolName);
|
|
@@ -53,6 +78,15 @@ function getEnabledToolMatches(state: McpExtensionState, toolName: string, exact
|
|
|
53
78
|
return matches;
|
|
54
79
|
}
|
|
55
80
|
|
|
81
|
+
function serverBackoffResult(state: McpExtensionState, mode: string, serverName: string): ProxyToolResult {
|
|
82
|
+
const failedAgo = getFailureAgeSeconds(state, serverName) ?? 0;
|
|
83
|
+
const message = `Server "${serverName}" not available (last failed ${failedAgo}s ago)`;
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: "text" as const, text: message }],
|
|
86
|
+
details: { mode, error: "server_backoff", server: serverName },
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
56
90
|
function getSingleToolMatch(metadata: ToolMetadata[] | undefined, toolName: string): ToolMetadata | "ambiguous" | undefined {
|
|
57
91
|
const exactMatches = getToolMatches(metadata, toolName, true);
|
|
58
92
|
const matches = exactMatches.length > 0 ? exactMatches : getToolMatches(metadata, toolName, false);
|
|
@@ -284,7 +318,6 @@ export function executeStatus(state: McpExtensionState): ProxyToolResult {
|
|
|
284
318
|
const disabled = isServerDisabled(definition);
|
|
285
319
|
const connection = disabled ? undefined : state.manager.getConnection(name);
|
|
286
320
|
const metadata = disabled ? undefined : state.toolMetadata.get(name);
|
|
287
|
-
const toolCount = metadata?.length ?? 0;
|
|
288
321
|
const failedAgo = disabled ? null : getFailureAgeSeconds(state, name);
|
|
289
322
|
let status = disabled ? "disabled" : "not connected";
|
|
290
323
|
if (!disabled && connection?.status === "connected") {
|
|
@@ -297,6 +330,8 @@ export function executeStatus(state: McpExtensionState): ProxyToolResult {
|
|
|
297
330
|
status = "cached";
|
|
298
331
|
}
|
|
299
332
|
|
|
333
|
+
const toolCount = status === "failed" ? 0 : metadata?.length ?? 0;
|
|
334
|
+
|
|
300
335
|
servers.push({ name, status, toolCount, failedAgo, ...(disabled ? { disabled: true } : {}) });
|
|
301
336
|
}
|
|
302
337
|
|
|
@@ -418,7 +453,7 @@ export async function executeAuthComplete(state: McpExtensionState, serverName:
|
|
|
418
453
|
}
|
|
419
454
|
|
|
420
455
|
await state.manager.close(serverName);
|
|
421
|
-
clearFailure(state, serverName);
|
|
456
|
+
clearFailure(state, serverName, "auth-complete");
|
|
422
457
|
updateStatusBar(state);
|
|
423
458
|
return {
|
|
424
459
|
content: [{ type: "text" as const, text: `OAuth authentication successful for "${serverName}". Run mcp({ connect: "${serverName}" }) to connect with the new token.` }],
|
|
@@ -434,15 +469,17 @@ export async function executeAuthComplete(state: McpExtensionState, serverName:
|
|
|
434
469
|
}
|
|
435
470
|
|
|
436
471
|
export function executeDescribe(state: McpExtensionState, toolName: string): ProxyToolResult {
|
|
437
|
-
const exactMatches = getEnabledToolMatches(state, toolName, true)
|
|
472
|
+
const exactMatches = getEnabledToolMatches(state, toolName, true)
|
|
473
|
+
.filter((match) => !isServerInActiveFailureBackoff(state, match.server));
|
|
438
474
|
if (exactMatches.length > 1) return ambiguousToolResult("describe", toolName);
|
|
439
|
-
if (exactMatches.length === 0 && getEnabledToolMatches(state, toolName, false).length > 1) {
|
|
475
|
+
if (exactMatches.length === 0 && getEnabledToolMatches(state, toolName, false).filter((match) => !isServerInActiveFailureBackoff(state, match.server)).length > 1) {
|
|
440
476
|
return ambiguousToolResult("describe", toolName);
|
|
441
477
|
}
|
|
442
478
|
|
|
443
479
|
let serverName = exactMatches[0]?.server;
|
|
444
480
|
let toolMeta = exactMatches[0]?.tool;
|
|
445
481
|
let disabledMatch: string | undefined;
|
|
482
|
+
let failedMatch: string | undefined;
|
|
446
483
|
|
|
447
484
|
if (!toolMeta) {
|
|
448
485
|
for (const [server, metadata] of state.toolMetadata.entries()) {
|
|
@@ -452,6 +489,10 @@ export function executeDescribe(state: McpExtensionState, toolName: string): Pro
|
|
|
452
489
|
disabledMatch ??= server;
|
|
453
490
|
continue;
|
|
454
491
|
}
|
|
492
|
+
if (isServerInActiveFailureBackoff(state, server)) {
|
|
493
|
+
failedMatch ??= server;
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
455
496
|
serverName = server;
|
|
456
497
|
toolMeta = found;
|
|
457
498
|
break;
|
|
@@ -460,6 +501,7 @@ export function executeDescribe(state: McpExtensionState, toolName: string): Pro
|
|
|
460
501
|
|
|
461
502
|
if (!serverName || !toolMeta) {
|
|
462
503
|
if (disabledMatch) return disabledResult("describe", disabledMatch);
|
|
504
|
+
if (failedMatch) return serverBackoffResult(state, "describe", failedMatch);
|
|
463
505
|
const suggestions = rankSuggestions(state, toolName, 5);
|
|
464
506
|
const suggestionText = suggestions.length > 0 ? ` Did you mean: ${suggestions.join(", ")}` : "";
|
|
465
507
|
return {
|
|
@@ -504,6 +546,7 @@ export function executeSearch(
|
|
|
504
546
|
): ProxyToolResult {
|
|
505
547
|
const showSchemas = includeSchemas !== false;
|
|
506
548
|
if (server && isServerDisabled(state.config.mcpServers[server])) return disabledResult("search", server);
|
|
549
|
+
if (server && isServerInActiveFailureBackoff(state, server)) return serverBackoffResult(state, "search", server);
|
|
507
550
|
|
|
508
551
|
let matches: Array<{ server: string; tool: ToolMetadata; score: number }>;
|
|
509
552
|
if (regex) {
|
|
@@ -545,6 +588,7 @@ export function executeSearch(
|
|
|
545
588
|
for (const [serverName, metadata] of state.toolMetadata.entries()) {
|
|
546
589
|
const definition = state.config.mcpServers[serverName];
|
|
547
590
|
if (isServerDisabled(definition)) continue;
|
|
591
|
+
if (isServerInActiveFailureBackoff(state, serverName)) continue;
|
|
548
592
|
if (server && serverName !== server) continue;
|
|
549
593
|
for (const tool of metadata) {
|
|
550
594
|
const matched = pattern.test(tool.name) || pattern.test(tool.description)
|
|
@@ -644,6 +688,12 @@ export function executeList(state: McpExtensionState, server: string): ProxyTool
|
|
|
644
688
|
const metadata = state.toolMetadata.get(server);
|
|
645
689
|
const toolNames = metadata?.map(m => m.name) ?? [];
|
|
646
690
|
const connection = state.manager.getConnection(server);
|
|
691
|
+
if (isServerInActiveFailureBackoff(state, server)) {
|
|
692
|
+
return {
|
|
693
|
+
...serverBackoffResult(state, "list", server),
|
|
694
|
+
details: { mode: "list", server, tools: [], count: 0, error: "server_backoff" },
|
|
695
|
+
};
|
|
696
|
+
}
|
|
647
697
|
const instructions = state.serverInstructions.get(server);
|
|
648
698
|
let instructionsText = "";
|
|
649
699
|
if (instructions) {
|
|
@@ -708,6 +758,7 @@ export function executeInstructions(state: McpExtensionState, server: string): P
|
|
|
708
758
|
};
|
|
709
759
|
}
|
|
710
760
|
if (isServerDisabled(definition)) return disabledResult("instructions", server);
|
|
761
|
+
if (isServerInActiveFailureBackoff(state, server)) return serverBackoffResult(state, "instructions", server);
|
|
711
762
|
|
|
712
763
|
const instructions = state.serverInstructions.get(server);
|
|
713
764
|
if (instructions) {
|
|
@@ -787,9 +838,9 @@ export async function executeConnect(state: McpExtensionState, serverName: strin
|
|
|
787
838
|
state.serverInstructions.delete(serverName);
|
|
788
839
|
}
|
|
789
840
|
updateMetadataCache(state, serverName);
|
|
790
|
-
|
|
841
|
+
const restored = clearFailure(state, serverName, "proxy-connect");
|
|
842
|
+
if (!restored) notifyToolMetadataUpdated(state, serverName, "proxy-connect");
|
|
791
843
|
markKeepAliveAfterConnect(state, serverName);
|
|
792
|
-
clearFailure(state, serverName);
|
|
793
844
|
updateStatusBar(state);
|
|
794
845
|
return executeList(state, serverName);
|
|
795
846
|
} catch (error) {
|
|
@@ -1100,10 +1151,10 @@ export async function executeCall(
|
|
|
1100
1151
|
};
|
|
1101
1152
|
}
|
|
1102
1153
|
}
|
|
1103
|
-
clearFailure(state, serverName);
|
|
1104
1154
|
updateServerMetadata(state, serverName);
|
|
1105
1155
|
updateMetadataCache(state, serverName);
|
|
1106
|
-
|
|
1156
|
+
const restored = clearFailure(state, serverName, "proxy-call-reconnect");
|
|
1157
|
+
if (!restored) notifyToolMetadataUpdated(state, serverName, "proxy-call-reconnect");
|
|
1107
1158
|
markKeepAliveAfterConnect(state, serverName);
|
|
1108
1159
|
updateStatusBar(state);
|
|
1109
1160
|
const match = getSingleToolMatch(state.toolMetadata.get(serverName), toolName);
|
|
@@ -1162,7 +1213,12 @@ export async function executeCall(
|
|
|
1162
1213
|
}
|
|
1163
1214
|
|
|
1164
1215
|
let uiSession: UiSessionRuntime | null = null;
|
|
1165
|
-
const requestOptions =
|
|
1216
|
+
const requestOptions = withUiProgressBridge(
|
|
1217
|
+
state.manager.getRequestOptions?.(serverName, ownedSignal) ?? (ownedSignal ? { signal: ownedSignal } : undefined),
|
|
1218
|
+
state.ui,
|
|
1219
|
+
serverName,
|
|
1220
|
+
toolMeta.originalName,
|
|
1221
|
+
);
|
|
1166
1222
|
|
|
1167
1223
|
const outputGuardOptions = resolveMcpOutputGuardOptions(state.config.settings);
|
|
1168
1224
|
const recoverAuthConnection = async () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { McpExtensionState } from "./state.ts";
|
|
2
2
|
import type { ServerEntry, ToolMetadata, ToolPrefix } from "./types.ts";
|
|
3
3
|
import { getServerPrefix, getToolNameCandidates, isServerDisabled, matchesToolPattern, resolveToolPrefix } from "./types.ts";
|
|
4
|
+
import { isServerInActiveFailureBackoff } from "./failure-backoff.ts";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Shortest field token allowed to stem-match a longer query token.
|
|
@@ -242,6 +243,7 @@ export function rankToolMatches(
|
|
|
242
243
|
if (server && serverName !== server) continue;
|
|
243
244
|
const definition = state.config.mcpServers[serverName];
|
|
244
245
|
if (isServerDisabled(definition)) continue;
|
|
246
|
+
if (isServerInActiveFailureBackoff(state, serverName)) continue;
|
|
245
247
|
for (const prepared of getPreparedTools(state, serverName, metadata, definition, globalPrefix, includeKeywords)) {
|
|
246
248
|
const score = scorePreparedToolMatch(prepared, normalizedQuery, queryTokens);
|
|
247
249
|
if (score !== null) matches.push({ server: serverName, tool: prepared.tool, score });
|