@herbertgao/pi-extensions 2026.8.5 → 2026.8.7
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 +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +272 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +48 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +16 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
- package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +22 -15
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +34 -10
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +29 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +3 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +46 -10
- package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +8 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
- package/node_modules/@narumitw/pi-btw/README.md +119 -103
- package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-btw/package.json +13 -9
- package/node_modules/@narumitw/pi-btw/src/btw.ts +40 -42
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +78 -15
- package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/pi-lens/CHANGELOG.md +1004 -0
- package/node_modules/pi-lens/README.md +11 -3
- package/node_modules/pi-lens/config/ruff/core.toml +42 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +427 -0
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +79 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
- package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
- package/node_modules/pi-lens/dist/clients/biome-client.js +176 -37
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
- package/node_modules/pi-lens/dist/clients/bus-publish.js +11 -3
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +76 -2
- package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
- package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +16 -4
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +249 -52
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +43 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +153 -37
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +165 -11
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +325 -72
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +81 -41
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +488 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +84 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +943 -93
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +106 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +317 -3
- package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
- package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +39 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
- package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +49 -21
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/go-client.js +21 -39
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +219 -10
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +9 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +1119 -101
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
- package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +86 -15
- package/node_modules/pi-lens/dist/clients/knip-client.js +361 -24
- package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +487 -9
- package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
- package/node_modules/pi-lens/dist/clients/lens-events.js +56 -25
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +45 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +160 -20
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1666 -148
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +111 -0
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2496 -171
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
- package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +517 -69
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +172 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +61 -3
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +4 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +39 -18
- package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
- package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +178 -30
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +85 -15
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +76 -4
- package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +248 -13
- package/node_modules/pi-lens/dist/clients/runtime-context.js +112 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +472 -61
- package/node_modules/pi-lens/dist/clients/runtime-session.js +359 -13
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +269 -22
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +948 -87
- package/node_modules/pi-lens/dist/clients/rust-client.js +21 -37
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +224 -8
- package/node_modules/pi-lens/dist/clients/sg-runner.js +249 -37
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +18 -11
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-timing.js +26 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +574 -32
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +127 -20
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
- package/node_modules/pi-lens/dist/clients/warm-attach.js +17 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/word-index.js +305 -33
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +64677 -49484
- package/node_modules/pi-lens/dist/mcp/server.js +8 -2
- package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +469 -56
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +190 -46
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
- package/node_modules/pi-lens/docs/agent-guide.md +44 -14
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +518 -501
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +33 -6
- package/node_modules/pi-lens/docs/globalconfig.md +14 -0
- package/node_modules/pi-lens/docs/language-coverage.md +71 -5
- package/node_modules/pi-lens/docs/mcp.md +2 -2
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/settings.md +25 -1
- package/node_modules/pi-lens/docs/usage.md +24 -5
- package/node_modules/pi-lens/docs/word-index.md +35 -0
- package/node_modules/pi-lens/package.json +10 -6
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +22 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +66 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +42 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +132 -1
- package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +12 -11
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +87 -116
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +170 -0
- package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +49 -0
- package/node_modules/pi-mcp-adapter/README.md +51 -6
- package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
- package/node_modules/pi-mcp-adapter/cli.js +188 -5
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +28 -10
- package/node_modules/pi-mcp-adapter/direct-tools.ts +23 -19
- package/node_modules/pi-mcp-adapter/index.ts +219 -32
- package/node_modules/pi-mcp-adapter/init.ts +36 -4
- package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
- package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +46 -25
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +4 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +330 -0
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +145 -2
- package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
- package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +38 -18
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +95 -10
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +37 -0
- package/node_modules/pi-web-access/README.md +38 -14
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/auth-fetch.ts +148 -0
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
- package/node_modules/pi-web-access/curator-page.ts +8 -3
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +134 -37
- package/node_modules/pi-web-access/fetch-params.ts +17 -3
- package/node_modules/pi-web-access/firecrawl.ts +172 -12
- package/node_modules/pi-web-access/gemini-search.ts +33 -7
- package/node_modules/pi-web-access/index.ts +160 -104
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +4 -2
- package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
- package/node_modules/pi-web-access/parallel.ts +2 -2
- package/node_modules/pi-web-access/query-rewrite.ts +51 -0
- package/node_modules/pi-web-access/serper.ts +211 -0
- package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
- package/node_modules/pi-web-access/summary-review.ts +51 -23
- package/node_modules/pi-web-access/tavily.ts +16 -4
- package/node_modules/pi-web-access/utils.ts +87 -0
- package/node_modules/pi-web-access/valyu.ts +199 -0
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +13 -13
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { mkdirSync } from "node:fs";
|
|
2
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
3
|
import {
|
|
3
4
|
Client,
|
|
5
|
+
SdkError,
|
|
6
|
+
SdkErrorCode,
|
|
4
7
|
SdkHttpError,
|
|
5
8
|
SSEClientTransport,
|
|
6
9
|
StreamableHTTPClientTransport,
|
|
7
10
|
UnauthorizedError,
|
|
8
11
|
type GetPromptResult,
|
|
9
12
|
type ReadResourceResult,
|
|
13
|
+
type CacheableRequestOptions,
|
|
10
14
|
type RequestOptions,
|
|
11
15
|
type UrlElicitationRequiredError,
|
|
12
16
|
type VersionNegotiationOptions,
|
|
@@ -32,6 +36,7 @@ import { logger } from "./logger.ts";
|
|
|
32
36
|
import { McpOAuthProvider } from "./mcp-oauth-provider.ts";
|
|
33
37
|
import { extractOAuthConfig, supportsOAuth, type McpOAuthRuntime } from "./mcp-auth-flow.ts";
|
|
34
38
|
import { invalidateAuthEntryCache, type AuthStorageOptions } from "./mcp-auth.ts";
|
|
39
|
+
import { getBearerTokenForUrl } from "./mcp-bearer-store.ts";
|
|
35
40
|
import { registerSamplingHandler, type ServerSamplingConfig } from "./sampling-handler.ts";
|
|
36
41
|
import {
|
|
37
42
|
handleUrlElicitation,
|
|
@@ -56,6 +61,7 @@ import {
|
|
|
56
61
|
traceTransportKind,
|
|
57
62
|
wrapTransportWithMcpTrace,
|
|
58
63
|
} from "./mcp-trace.ts";
|
|
64
|
+
import { createRequestHeadersCommandFetch } from "./request-headers-command.ts";
|
|
59
65
|
|
|
60
66
|
const MAX_CAPTURED_STDERR_BYTES = 8 * 1024;
|
|
61
67
|
const MAX_CAPTURED_STDERR_LINES = 3;
|
|
@@ -122,6 +128,8 @@ export interface ServerConnection {
|
|
|
122
128
|
transport: Transport;
|
|
123
129
|
definition: ServerDefinition;
|
|
124
130
|
tools: McpTool[];
|
|
131
|
+
/** Monotonic guard against older refresh responses replacing newer notifications. */
|
|
132
|
+
toolsRevision?: number;
|
|
125
133
|
resources: McpResource[];
|
|
126
134
|
prompts: McpPrompt[];
|
|
127
135
|
/** True when prompts were advertised but prompts/list failed. */
|
|
@@ -138,6 +146,10 @@ export interface ServerConnection {
|
|
|
138
146
|
type UiStreamListener = (serverName: string, notification: ServerStreamResultPatchNotification["params"]) => void;
|
|
139
147
|
type MetadataListChangedListener = (serverName: string, reason: string) => void;
|
|
140
148
|
|
|
149
|
+
export type ToolRefreshResult = "updated" | "unchanged" | "superseded" | "refresh-timeout";
|
|
150
|
+
|
|
151
|
+
const KEEP_ALIVE_REFRESH_TIMEOUT_MS = 5_000;
|
|
152
|
+
|
|
141
153
|
export class McpServerManager {
|
|
142
154
|
private connections = new Map<string, ServerConnection>();
|
|
143
155
|
private connectPromises = new Map<string, Promise<ServerConnection>>();
|
|
@@ -145,6 +157,10 @@ export class McpServerManager {
|
|
|
145
157
|
private uiStreamListeners = new Map<string, UiStreamListener>();
|
|
146
158
|
private samplingConfig: ServerSamplingConfig | undefined;
|
|
147
159
|
private metadataListChangedListener: MetadataListChangedListener | undefined;
|
|
160
|
+
private pendingMetadataPublications = new Map<
|
|
161
|
+
string,
|
|
162
|
+
{ connection: ServerConnection; reason: string }
|
|
163
|
+
>();
|
|
148
164
|
private elicitationConfig: ServerElicitationConfig | undefined;
|
|
149
165
|
private authStorageOptions: AuthStorageOptions = {};
|
|
150
166
|
private oauthRuntime: McpOAuthRuntime | undefined;
|
|
@@ -169,6 +185,25 @@ export class McpServerManager {
|
|
|
169
185
|
this.metadataListChangedListener = listener;
|
|
170
186
|
}
|
|
171
187
|
|
|
188
|
+
publishMetadataChanged(
|
|
189
|
+
name: string,
|
|
190
|
+
expectedConnection: ServerConnection,
|
|
191
|
+
reason: string,
|
|
192
|
+
): boolean {
|
|
193
|
+
const current = this.connections.get(name);
|
|
194
|
+
if (current !== expectedConnection || current.status !== "connected") return false;
|
|
195
|
+
try {
|
|
196
|
+
this.metadataListChangedListener?.(name, reason);
|
|
197
|
+
this.pendingMetadataPublications.delete(name);
|
|
198
|
+
return true;
|
|
199
|
+
} catch (error) {
|
|
200
|
+
this.pendingMetadataPublications.set(name, { connection: expectedConnection, reason });
|
|
201
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
202
|
+
logger.debug(`MCP: metadata publication failed for ${name}; queued for retry: ${message}`);
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
172
207
|
setElicitationConfig(config: ServerElicitationConfig | undefined): void {
|
|
173
208
|
this.elicitationConfig = config;
|
|
174
209
|
}
|
|
@@ -302,6 +337,100 @@ export class McpServerManager {
|
|
|
302
337
|
return abortable(promise, ownedSignal);
|
|
303
338
|
}
|
|
304
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Fetch the authoritative tool catalog for a connection that still appears
|
|
342
|
+
* connected. The SDK response cache is explicitly bypassed so this request
|
|
343
|
+
* also proves the remote Streamable HTTP session is usable. Results are
|
|
344
|
+
* identity-guarded: a late response from a replaced connection is ignored.
|
|
345
|
+
*/
|
|
346
|
+
async refreshTools(
|
|
347
|
+
name: string,
|
|
348
|
+
expectedConnection: ServerConnection,
|
|
349
|
+
signal?: AbortSignal,
|
|
350
|
+
): Promise<ToolRefreshResult> {
|
|
351
|
+
if (this.stopped) throw new Error("MCP server manager is closed");
|
|
352
|
+
const ownedSignal = combineAbortSignals(this.runtimeSignal, signal);
|
|
353
|
+
throwIfAborted(ownedSignal);
|
|
354
|
+
|
|
355
|
+
const current = this.connections.get(name);
|
|
356
|
+
if (current !== expectedConnection || current.status !== "connected") {
|
|
357
|
+
return "superseded";
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const requestOptions = this.buildRequestOptions(expectedConnection.definition, signal);
|
|
361
|
+
const timeout = Math.min(requestOptions?.timeout ?? KEEP_ALIVE_REFRESH_TIMEOUT_MS, KEEP_ALIVE_REFRESH_TIMEOUT_MS);
|
|
362
|
+
const healthOptions = {
|
|
363
|
+
...requestOptions,
|
|
364
|
+
timeout,
|
|
365
|
+
};
|
|
366
|
+
if (!expectedConnection.client.getServerCapabilities?.()?.tools) {
|
|
367
|
+
await expectedConnection.client.ping(healthOptions);
|
|
368
|
+
throwIfAborted(ownedSignal);
|
|
369
|
+
if (this.connections.get(name) !== expectedConnection || expectedConnection.status !== "connected") {
|
|
370
|
+
return "superseded";
|
|
371
|
+
}
|
|
372
|
+
this.retryPendingMetadataPublication(name, expectedConnection);
|
|
373
|
+
return "unchanged";
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const toolsRevision = expectedConnection.toolsRevision ?? 0;
|
|
377
|
+
const refreshSignal = combineAbortSignals(healthOptions.signal, AbortSignal.timeout(timeout));
|
|
378
|
+
let tools: McpTool[];
|
|
379
|
+
try {
|
|
380
|
+
tools = await this.fetchAllTools(expectedConnection.client, {
|
|
381
|
+
...healthOptions,
|
|
382
|
+
...(refreshSignal ? { signal: refreshSignal } : {}),
|
|
383
|
+
cacheMode: "refresh",
|
|
384
|
+
});
|
|
385
|
+
} catch (error) {
|
|
386
|
+
throwIfAborted(ownedSignal);
|
|
387
|
+
if (this.connections.get(name) !== expectedConnection || expectedConnection.status !== "connected") {
|
|
388
|
+
return "superseded";
|
|
389
|
+
}
|
|
390
|
+
if (error instanceof SdkError && error.code === SdkErrorCode.RequestTimeout) {
|
|
391
|
+
return "refresh-timeout";
|
|
392
|
+
}
|
|
393
|
+
throw error;
|
|
394
|
+
}
|
|
395
|
+
throwIfAborted(ownedSignal);
|
|
396
|
+
|
|
397
|
+
if (this.connections.get(name) !== expectedConnection || expectedConnection.status !== "connected") {
|
|
398
|
+
return "superseded";
|
|
399
|
+
}
|
|
400
|
+
if ((expectedConnection.toolsRevision ?? 0) !== toolsRevision) {
|
|
401
|
+
return "superseded";
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (isDeepStrictEqual(expectedConnection.tools, tools)) {
|
|
405
|
+
this.retryPendingMetadataPublication(name, expectedConnection);
|
|
406
|
+
return "unchanged";
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const previousTools = expectedConnection.tools;
|
|
410
|
+
expectedConnection.tools = tools;
|
|
411
|
+
expectedConnection.toolsRevision = toolsRevision + 1;
|
|
412
|
+
try {
|
|
413
|
+
await this.metadataListChangedListener?.(name, "keep-alive-refresh");
|
|
414
|
+
this.pendingMetadataPublications.delete(name);
|
|
415
|
+
} catch (error) {
|
|
416
|
+
if (this.connections.get(name) === expectedConnection && expectedConnection.tools === tools) {
|
|
417
|
+
expectedConnection.tools = previousTools;
|
|
418
|
+
expectedConnection.toolsRevision = toolsRevision;
|
|
419
|
+
}
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
422
|
+
return "updated";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private retryPendingMetadataPublication(name: string, connection: ServerConnection): void {
|
|
426
|
+
const pendingPublication = this.pendingMetadataPublications.get(name);
|
|
427
|
+
if (pendingPublication?.connection !== connection) return;
|
|
428
|
+
this.metadataListChangedListener?.(name, pendingPublication.reason);
|
|
429
|
+
if (this.pendingMetadataPublications.get(name) === pendingPublication) {
|
|
430
|
+
this.pendingMetadataPublications.delete(name);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
305
434
|
private async doReconnect(
|
|
306
435
|
name: string,
|
|
307
436
|
definition: ServerDefinition,
|
|
@@ -439,6 +568,7 @@ export class McpServerManager {
|
|
|
439
568
|
transport,
|
|
440
569
|
definition,
|
|
441
570
|
tools: [],
|
|
571
|
+
toolsRevision: 0,
|
|
442
572
|
resources: [],
|
|
443
573
|
prompts: [],
|
|
444
574
|
...(instructions !== undefined ? { instructions } : {}),
|
|
@@ -640,7 +770,9 @@ export class McpServerManager {
|
|
|
640
770
|
const connection = this.connections.get(serverName);
|
|
641
771
|
if (!connection || connection.client !== client || connection.status !== "connected") return;
|
|
642
772
|
connection.tools = tools;
|
|
773
|
+
connection.toolsRevision = (connection.toolsRevision ?? 0) + 1;
|
|
643
774
|
this.metadataListChangedListener?.(serverName, "tools-list-changed");
|
|
775
|
+
this.pendingMetadataPublications.delete(serverName);
|
|
644
776
|
}
|
|
645
777
|
|
|
646
778
|
private handlePromptsListChanged(
|
|
@@ -659,6 +791,7 @@ export class McpServerManager {
|
|
|
659
791
|
connection.prompts = prompts;
|
|
660
792
|
connection.promptDiscoveryFailed = false;
|
|
661
793
|
this.metadataListChangedListener?.(serverName, "prompts-list-changed");
|
|
794
|
+
this.pendingMetadataPublications.delete(serverName);
|
|
662
795
|
}
|
|
663
796
|
|
|
664
797
|
private handleResourcesListChanged(
|
|
@@ -676,6 +809,7 @@ export class McpServerManager {
|
|
|
676
809
|
if (!connection || connection.client !== client || connection.status !== "connected") return;
|
|
677
810
|
connection.resources = resources;
|
|
678
811
|
this.metadataListChangedListener?.(serverName, "resources-list-changed");
|
|
812
|
+
this.pendingMetadataPublications.delete(serverName);
|
|
679
813
|
}
|
|
680
814
|
|
|
681
815
|
async handleUrlElicitationRequired(
|
|
@@ -733,7 +867,10 @@ export class McpServerManager {
|
|
|
733
867
|
if (definition.auth === "bearer") {
|
|
734
868
|
const token = commandBearer
|
|
735
869
|
? resolveCommandSecret(commandBearer, `MCP server "${serverName}" HTTP bearer token`)
|
|
736
|
-
: resolveBearerToken(definition)
|
|
870
|
+
: resolveBearerToken(definition)
|
|
871
|
+
?? (definition.bearerToken === undefined && definition.bearerTokenEnv === undefined && definition.bearerTokenStore === true
|
|
872
|
+
? getBearerTokenForUrl(serverName, serverUrl)
|
|
873
|
+
: undefined);
|
|
737
874
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
738
875
|
}
|
|
739
876
|
|
|
@@ -746,6 +883,9 @@ export class McpServerManager {
|
|
|
746
883
|
}
|
|
747
884
|
|
|
748
885
|
const requestInit = Object.keys(headers).length > 0 ? { headers } : undefined;
|
|
886
|
+
const requestFetch = definition.requestHeadersCommand
|
|
887
|
+
? createRequestHeadersCommandFetch(definition.requestHeadersCommand)
|
|
888
|
+
: undefined;
|
|
749
889
|
const createAuthProvider = (): McpOAuthProvider => new McpOAuthProvider(
|
|
750
890
|
serverName,
|
|
751
891
|
serverUrl,
|
|
@@ -772,6 +912,7 @@ export class McpServerManager {
|
|
|
772
912
|
const authProvider = "provider" in authState ? authState.provider : undefined;
|
|
773
913
|
const transportOptions = {
|
|
774
914
|
...(requestInit !== undefined ? { requestInit } : {}),
|
|
915
|
+
...(requestFetch !== undefined ? { fetch: requestFetch } : {}),
|
|
775
916
|
...(authProvider !== undefined ? { authProvider } : {}),
|
|
776
917
|
...(authProvider !== undefined
|
|
777
918
|
&& definition.oauth !== false
|
|
@@ -846,7 +987,7 @@ export class McpServerManager {
|
|
|
846
987
|
}
|
|
847
988
|
}
|
|
848
989
|
|
|
849
|
-
private async fetchAllTools(client: Client, requestOptions?:
|
|
990
|
+
private async fetchAllTools(client: Client, requestOptions?: CacheableRequestOptions): Promise<McpTool[]> {
|
|
850
991
|
const allTools: McpTool[] = [];
|
|
851
992
|
let cursor: string | undefined;
|
|
852
993
|
|
|
@@ -974,6 +1115,7 @@ export class McpServerManager {
|
|
|
974
1115
|
async close(name: string): Promise<void> {
|
|
975
1116
|
this.closeGenerations.set(name, (this.closeGenerations.get(name) ?? 0) + 1);
|
|
976
1117
|
this.connectAttempts.get(name)?.abort(new Error(`MCP connection ${name} was closed`));
|
|
1118
|
+
this.pendingMetadataPublications.delete(name);
|
|
977
1119
|
|
|
978
1120
|
const connection = this.connections.get(name);
|
|
979
1121
|
if (!connection) {
|
|
@@ -1037,6 +1179,7 @@ export class McpServerManager {
|
|
|
1037
1179
|
.filter(error => this.containsCleanupFailure(error));
|
|
1038
1180
|
this.uiStreamListeners.clear();
|
|
1039
1181
|
this.acceptedUrlElicitations.clear();
|
|
1182
|
+
this.pendingMetadataPublications.clear();
|
|
1040
1183
|
this.samplingConfig = undefined;
|
|
1041
1184
|
this.elicitationConfig = undefined;
|
|
1042
1185
|
await this.traceWriter?.flush();
|
|
@@ -146,6 +146,13 @@ export async function withSessionRecovery<T>(
|
|
|
146
146
|
throw err;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
try {
|
|
150
|
+
deps.manager.publishMetadataChanged(serverName, freshConnection, "session-reconnect");
|
|
151
|
+
} catch (publicationError) {
|
|
152
|
+
const message = publicationError instanceof Error ? publicationError.message : String(publicationError);
|
|
153
|
+
logger.debug(`MCP metadata publication after reconnect failed for "${serverName}": ${message}`);
|
|
154
|
+
}
|
|
155
|
+
throwIfAborted(deps.signal);
|
|
149
156
|
return fn(freshConnection);
|
|
150
157
|
}
|
|
151
158
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { abortable } from "./abort.ts";
|
|
3
3
|
import { combineAbortSignals } from "./runtime-owner.ts";
|
|
4
4
|
import type { McpExtensionState } from "./state.ts";
|
|
@@ -20,6 +20,18 @@ export type ToolCallApprovalResult =
|
|
|
20
20
|
| { ok: true }
|
|
21
21
|
| { ok: false; reason: "denied" | "approval_required_headless" };
|
|
22
22
|
|
|
23
|
+
function stableStringify(value: unknown): string {
|
|
24
|
+
if (value === null || value === undefined || typeof value !== "object") {
|
|
25
|
+
const serialized = JSON.stringify(value);
|
|
26
|
+
return serialized === undefined ? "undefined" : serialized;
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
return `[${value.map(item => stableStringify(item)).join(",")}]`;
|
|
30
|
+
}
|
|
31
|
+
const object = value as Record<string, unknown>;
|
|
32
|
+
return `{${Object.keys(object).sort().map(key => `${JSON.stringify(key)}:${stableStringify(object[key])}`).join(",")}}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
export function isToolCallApprovalRequired(
|
|
24
36
|
config: McpConfig,
|
|
25
37
|
serverName: string,
|
|
@@ -136,7 +148,8 @@ export async function ensureToolCallApproved(
|
|
|
136
148
|
origin: McpToolApprovalOrigin = toolMeta.resourceUri ? "resource" : "proxy",
|
|
137
149
|
approvalMetadata?: ReadonlyMap<string, readonly ToolMetadata[]>,
|
|
138
150
|
): Promise<ToolCallApprovalResult> {
|
|
139
|
-
const
|
|
151
|
+
const argsHash = createHash("sha256").update(stableStringify(args ?? {})).digest("hex");
|
|
152
|
+
const cacheKey = `${serverName}\u0000${toolMeta.originalName}\u0000${argsHash}`;
|
|
140
153
|
const approvedToolCalls = state.approvedToolCalls ??= new Map<string, true>();
|
|
141
154
|
if (approvedToolCalls.has(cacheKey)) {
|
|
142
155
|
return { ok: true };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getToolUiResourceUri } from "./ui-app-bridge-helpers.ts";
|
|
2
2
|
import type { McpExtensionState } from "./state.ts";
|
|
3
3
|
import type { ToolMetadata, McpTool, McpResource, ServerEntry, ToolPrefix } from "./types.ts";
|
|
4
|
-
import { formatToolName, getToolNameCandidates, isToolAllowed, resolveToolPrefix } from "./types.ts";
|
|
4
|
+
import { createToolSelectorCandidateIndex, formatToolName, getToolNameCandidates, isToolAllowed, resolveToolPrefix } from "./types.ts";
|
|
5
5
|
import { resourceNameToToolName } from "./resource-tools.ts";
|
|
6
6
|
import { extractToolUiStreamMode } from "./utils.ts";
|
|
7
7
|
import { extractUiToolVisibility, isUiToolVisibleToModel } from "./ui-tool-visibility.ts";
|
|
@@ -20,48 +20,68 @@ export function buildToolMetadata(
|
|
|
20
20
|
const failedTools: string[] = [];
|
|
21
21
|
const seenNames = new Set<string>();
|
|
22
22
|
const effectivePrefix = resolveToolPrefix(definition, prefix);
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const hasToolFilters =
|
|
24
|
+
(Array.isArray(definition.includeTools) && definition.includeTools.length > 0) ||
|
|
25
|
+
(Array.isArray(definition.excludeTools) && definition.excludeTools.length > 0);
|
|
26
|
+
const selectorCandidateIndex = hasToolFilters && configuredServers ? (() => {
|
|
25
27
|
const candidates = new Set<string>();
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
+
const additionalCandidatesByToolName = new Map<string, Set<string>>();
|
|
29
|
+
const evaluatedToolNames = new Set<string>();
|
|
30
|
+
const addCandidates = (
|
|
31
|
+
target: Set<string>,
|
|
32
|
+
originalName: string,
|
|
33
|
+
candidateServerName: string,
|
|
34
|
+
candidatePrefix: ToolPrefix,
|
|
35
|
+
) => {
|
|
36
|
+
for (const candidate of getToolNameCandidates(originalName, candidateServerName, candidatePrefix, false)) target.add(candidate);
|
|
28
37
|
};
|
|
29
38
|
|
|
30
39
|
for (const tool of tools) {
|
|
31
|
-
if (tool?.name)
|
|
40
|
+
if (!tool?.name) continue;
|
|
41
|
+
evaluatedToolNames.add(tool.name);
|
|
42
|
+
addCandidates(candidates, tool.name, serverName, effectivePrefix);
|
|
32
43
|
}
|
|
33
44
|
if (definition.exposeResources !== false) {
|
|
34
45
|
for (const resource of resources) {
|
|
35
|
-
|
|
46
|
+
const baseName = `read_${resourceNameToToolName(resource.name)}`;
|
|
47
|
+
evaluatedToolNames.add(baseName);
|
|
48
|
+
if (resource?.name && resource?.uri) addCandidates(candidates, baseName, serverName, effectivePrefix);
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
51
|
for (const [otherServerName, otherDefinition] of Object.entries(configuredServers)) {
|
|
39
52
|
if (otherServerName === serverName) continue;
|
|
53
|
+
const otherPrefix = resolveToolPrefix(otherDefinition, prefix);
|
|
40
54
|
const knownTools = knownMetadata?.get(otherServerName);
|
|
41
55
|
if (knownTools) {
|
|
42
|
-
const otherPrefix = resolveToolPrefix(otherDefinition, prefix);
|
|
43
56
|
for (const tool of knownTools) {
|
|
44
57
|
candidates.add(tool.name);
|
|
45
|
-
addCandidates(tool.originalName, otherServerName, otherPrefix);
|
|
58
|
+
addCandidates(candidates, tool.originalName, otherServerName, otherPrefix);
|
|
46
59
|
}
|
|
47
60
|
} else if (!knownMetadata || includeMissingConfiguredCandidates) {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
for (const toolName of evaluatedToolNames) {
|
|
62
|
+
let additionalCandidates = additionalCandidatesByToolName.get(toolName);
|
|
63
|
+
if (!additionalCandidates) {
|
|
64
|
+
additionalCandidates = new Set<string>();
|
|
65
|
+
additionalCandidatesByToolName.set(toolName, additionalCandidates);
|
|
66
|
+
}
|
|
67
|
+
addCandidates(additionalCandidates, toolName, otherServerName, otherPrefix);
|
|
68
|
+
if (includeMissingConfiguredCandidates) {
|
|
69
|
+
for (const candidate of getToolNameCandidates(toolName, otherServerName, otherPrefix, false)) {
|
|
70
|
+
additionalCandidates.add(candidate.replace(/-/g, "_"));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
52
73
|
}
|
|
53
74
|
}
|
|
54
75
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
76
|
+
return createToolSelectorCandidateIndex(candidates, additionalCandidatesByToolName);
|
|
77
|
+
})() : undefined;
|
|
58
78
|
|
|
59
79
|
for (const tool of tools) {
|
|
60
80
|
if (!tool?.name) {
|
|
61
81
|
failedTools.push("(unnamed)");
|
|
62
82
|
continue;
|
|
63
83
|
}
|
|
64
|
-
if (!isToolAllowed(tool.name, serverName, effectivePrefix, definition.includeTools, definition.excludeTools,
|
|
84
|
+
if (!isToolAllowed(tool.name, serverName, effectivePrefix, definition.includeTools, definition.excludeTools, selectorCandidateIndex)) {
|
|
65
85
|
continue;
|
|
66
86
|
}
|
|
67
87
|
|
|
@@ -97,7 +117,7 @@ export function buildToolMetadata(
|
|
|
97
117
|
if (definition.exposeResources !== false) {
|
|
98
118
|
for (const resource of resources) {
|
|
99
119
|
const baseName = `read_${resourceNameToToolName(resource.name)}`;
|
|
100
|
-
if (!isToolAllowed(baseName, serverName, effectivePrefix, definition.includeTools, definition.excludeTools,
|
|
120
|
+
if (!isToolAllowed(baseName, serverName, effectivePrefix, definition.includeTools, definition.excludeTools, selectorCandidateIndex)) {
|
|
101
121
|
continue;
|
|
102
122
|
}
|
|
103
123
|
|
|
@@ -25,6 +25,7 @@ export interface McpProxyToolCallInput {
|
|
|
25
25
|
|
|
26
26
|
interface McpToolRenderState {
|
|
27
27
|
compactTitle?: string;
|
|
28
|
+
compactInputPreview?: string;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
interface McpToolRenderContext {
|
|
@@ -52,6 +53,7 @@ export interface McpToolResultDisplay {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
const DEFAULT_MAX_CALL_INPUT_CHARS = 1500;
|
|
56
|
+
const DEFAULT_MAX_COMPACT_INPUT_CHARS = 240;
|
|
55
57
|
const DEFAULT_BOXED_COLLAPSED_LINES = 3;
|
|
56
58
|
const DEFAULT_COMPACT_COLLAPSED_LINES = 1;
|
|
57
59
|
const DEFAULT_MAX_COLLAPSED_CHARS = 8000;
|
|
@@ -70,6 +72,7 @@ class CompactMcpToolResult implements Component {
|
|
|
70
72
|
|
|
71
73
|
constructor(
|
|
72
74
|
private readonly title: string,
|
|
75
|
+
private readonly inputPreview: string,
|
|
73
76
|
private readonly display: McpToolResultDisplay,
|
|
74
77
|
private readonly theme: RenderTheme,
|
|
75
78
|
) {}
|
|
@@ -83,7 +86,7 @@ class CompactMcpToolResult implements Component {
|
|
|
83
86
|
});
|
|
84
87
|
const lines = resultLines.length > 0 ? resultLines : [""];
|
|
85
88
|
const bodies = lines.map((line, index) => {
|
|
86
|
-
const prefix = index === 0
|
|
89
|
+
const prefix = index === 0 ? this.renderPrefix(safeWidth) : "";
|
|
87
90
|
return `${prefix}${this.theme.fg("toolOutput", line)}`;
|
|
88
91
|
});
|
|
89
92
|
const hiddenText = this.display.truncated || bodies.some((body) => visibleWidth(body) > safeWidth);
|
|
@@ -106,6 +109,22 @@ class CompactMcpToolResult implements Component {
|
|
|
106
109
|
invalidate(): void {
|
|
107
110
|
this.rendered = null;
|
|
108
111
|
}
|
|
112
|
+
|
|
113
|
+
private renderPrefix(width: number): string {
|
|
114
|
+
if (!this.title) return "";
|
|
115
|
+
const arrow = " → ";
|
|
116
|
+
if (!this.inputPreview) return `${this.theme.fg("toolTitle", this.title)}${arrow}`;
|
|
117
|
+
|
|
118
|
+
const maxPrefixWidth = Math.max(12, Math.floor(width * 0.55));
|
|
119
|
+
const titleWidth = visibleWidth(this.title);
|
|
120
|
+
const inputWidth = Math.max(0, maxPrefixWidth - titleWidth - 1);
|
|
121
|
+
if (inputWidth <= 3) {
|
|
122
|
+
return `${this.theme.fg("toolTitle", truncateToWidth(this.title, maxPrefixWidth, "…"))}${arrow}`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const input = truncateToWidth(this.inputPreview, inputWidth, "…");
|
|
126
|
+
return `${this.theme.fg("toolTitle", this.title)} ${this.theme.fg("muted", input)}${arrow}`;
|
|
127
|
+
}
|
|
109
128
|
}
|
|
110
129
|
|
|
111
130
|
class CollapsibleText implements Component {
|
|
@@ -239,6 +258,10 @@ function renderToolCallLines(lines: string[], theme?: RenderTheme) {
|
|
|
239
258
|
return new Text([styledTitle, ...styledRest].join("\n"), 0, 0);
|
|
240
259
|
}
|
|
241
260
|
|
|
261
|
+
function formatCompactInputPreview(lines: string[], maxChars = DEFAULT_MAX_COMPACT_INPUT_CHARS): string {
|
|
262
|
+
return truncateText(lines.slice(1).join(" ").replace(/\s+/g, " ").trim(), maxChars);
|
|
263
|
+
}
|
|
264
|
+
|
|
242
265
|
export function resolveMcpToolRenderOptions(settings?: McpToolRenderSettings): McpToolRenderOptions {
|
|
243
266
|
const resultRendering = settings?.toolResultRendering === "boxed" ? "boxed" : "compact";
|
|
244
267
|
const collapsedLines = settings?.collapsedResultLines;
|
|
@@ -263,7 +286,10 @@ function renderToolCall(
|
|
|
263
286
|
context: McpToolRenderContext | undefined,
|
|
264
287
|
options: McpToolRenderOptions,
|
|
265
288
|
) {
|
|
266
|
-
if (context?.state)
|
|
289
|
+
if (context?.state) {
|
|
290
|
+
context.state.compactTitle = lines[0] ?? "mcp";
|
|
291
|
+
context.state.compactInputPreview = formatCompactInputPreview(lines);
|
|
292
|
+
}
|
|
267
293
|
if (shouldUseCompactFinalRender(options, context)) return new EmptyComponent();
|
|
268
294
|
return renderToolCallLines(lines, theme);
|
|
269
295
|
}
|
|
@@ -307,6 +333,19 @@ function collectCollapsedResultLines(
|
|
|
307
333
|
let truncated = false;
|
|
308
334
|
|
|
309
335
|
const appendLine = (line: string) => {
|
|
336
|
+
if (lines.length === 0) {
|
|
337
|
+
const previewWidth = Math.min(line.length, remainingChars);
|
|
338
|
+
if (line.slice(0, previewWidth).trim() === "") {
|
|
339
|
+
if (line.length >= remainingChars) {
|
|
340
|
+
truncated = true;
|
|
341
|
+
remainingChars = 0;
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
remainingChars -= line.length + 1;
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
310
349
|
if (lines.length >= maxLines || remainingChars <= 0) {
|
|
311
350
|
truncated = true;
|
|
312
351
|
return false;
|
|
@@ -342,7 +381,7 @@ function collectCollapsedResultLines(
|
|
|
342
381
|
if (truncated) break;
|
|
343
382
|
}
|
|
344
383
|
|
|
345
|
-
if (lines.length === 0) lines.push("");
|
|
384
|
+
if (lines.length === 0) lines.push(truncated ? "(leading blank output omitted)" : "");
|
|
346
385
|
if (truncated && lines.length >= maxLines) lines.push("…");
|
|
347
386
|
return { lines, truncated };
|
|
348
387
|
}
|
|
@@ -393,7 +432,8 @@ export function renderMcpToolResult(
|
|
|
393
432
|
if (!expanded && renderOptions.resultRendering === "compact") {
|
|
394
433
|
const display = formatMcpToolResultLines(result, false, renderOptions.collapsedResultLines);
|
|
395
434
|
const title = context?.state?.compactTitle ?? formatMcpToolResultIdentity(result.details) ?? "";
|
|
396
|
-
|
|
435
|
+
const inputPreview = context?.state?.compactInputPreview ?? "";
|
|
436
|
+
return new CompactMcpToolResult(title, inputPreview, display, activeTheme);
|
|
397
437
|
}
|
|
398
438
|
|
|
399
439
|
const display = formatMcpToolResultLines(result, expanded, renderOptions.collapsedResultLines);
|