@herbertgao/pi-extensions 2026.8.4 → 2026.8.5
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 +4 -4
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +5 -8
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
- package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +15 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
- package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
- package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
- package/node_modules/@narumitw/pi-btw/README.md +8 -7
- package/node_modules/@narumitw/pi-btw/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/src/menu.ts +1 -0
- package/node_modules/pi-lens/CHANGELOG.md +2440 -954
- package/node_modules/pi-lens/README.md +13 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
- package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
- package/node_modules/pi-lens/dist/clients/biome-client.js +29 -25
- package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
- package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
- package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
- package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
- package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
- package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +14 -0
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
- package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +347 -75
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +61 -11
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +63 -20
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1085 -681
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +14 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +277 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
- package/node_modules/pi-lens/dist/clients/extension-log.js +139 -0
- package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
- package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
- package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +16 -3
- package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
- package/node_modules/pi-lens/dist/clients/git-guard.js +681 -11
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
- package/node_modules/pi-lens/dist/clients/go-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +8 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
- package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +390 -99
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +31 -54
- package/node_modules/pi-lens/dist/clients/knip-client.js +15 -36
- package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
- package/node_modules/pi-lens/dist/clients/latency-logger.js +23 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
- package/node_modules/pi-lens/dist/clients/lens-events.js +27 -4
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +30 -0
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +493 -48
- package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +86 -0
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
- package/node_modules/pi-lens/dist/clients/lsp/index.js +1807 -780
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +196 -32
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +123 -32
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
- package/node_modules/pi-lens/dist/clients/mcp/session.js +216 -8
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
- package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
- package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
- package/node_modules/pi-lens/dist/clients/pipeline.js +47 -13
- package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
- package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
- package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
- package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
- package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
- package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +107 -73
- package/node_modules/pi-lens/dist/clients/runtime-context.js +36 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +74 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +405 -117
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +218 -23
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +237 -64
- package/node_modules/pi-lens/dist/clients/rust-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
- package/node_modules/pi-lens/dist/clients/sg-runner.js +284 -174
- package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +224 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
- package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
- package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
- package/node_modules/pi-lens/dist/clients/startup-timing.js +1 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +38 -8
- package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +388 -39
- package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
- package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +33 -13
- package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
- package/node_modules/pi-lens/dist/clients/word-index.js +391 -64
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
- package/node_modules/pi-lens/dist/index.js +49361 -36888
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
- package/node_modules/pi-lens/dist/mcp/server.js +211 -44
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +200 -36
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +153 -40
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
- package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
- package/node_modules/pi-lens/docs/agent-guide.md +2 -2
- package/node_modules/pi-lens/docs/agent-tools.md +21 -10
- package/node_modules/pi-lens/docs/analysisall.md +192 -0
- package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
- package/node_modules/pi-lens/docs/environment-variables.md +44 -0
- package/node_modules/pi-lens/docs/fable.md +27 -0
- package/node_modules/pi-lens/docs/features.md +31 -2
- package/node_modules/pi-lens/docs/globalconfig.md +45 -1
- package/node_modules/pi-lens/docs/language-coverage.md +4 -3
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
- package/node_modules/pi-lens/docs/mcp.md +37 -4
- package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
- package/node_modules/pi-lens/docs/settings.md +12 -1
- package/node_modules/pi-lens/docs/tools.md +4 -1
- package/node_modules/pi-lens/docs/usage.md +18 -0
- package/node_modules/pi-lens/package.json +10 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
- package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +55 -2
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +25 -0
- package/node_modules/pi-mcp-adapter/README.md +34 -3
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
- package/node_modules/pi-mcp-adapter/commands.ts +15 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +54 -7
- package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
- package/node_modules/pi-mcp-adapter/index.ts +8 -3
- package/node_modules/pi-mcp-adapter/init.ts +29 -5
- package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +27 -4
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
- package/node_modules/pi-mcp-adapter/package.json +3 -3
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
- package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
- package/node_modules/pi-mcp-adapter/server-manager.ts +36 -7
- package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
- package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +42 -4
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
- package/node_modules/pi-mcp-adapter/types.ts +93 -27
- package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
- package/package.json +11 -12
- package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
- package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
- package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
- package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
- package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
- package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
- package/node_modules/pi-lens/dist/clients/types.js +0 -11
|
@@ -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, isToolAllowed, resolveToolPrefix } from "./types.ts";
|
|
4
|
+
import { 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";
|
|
@@ -11,19 +11,57 @@ export function buildToolMetadata(
|
|
|
11
11
|
resources: McpResource[],
|
|
12
12
|
definition: ServerEntry,
|
|
13
13
|
serverName: string,
|
|
14
|
-
prefix: ToolPrefix
|
|
14
|
+
prefix: ToolPrefix,
|
|
15
|
+
configuredServers?: Record<string, ServerEntry>,
|
|
16
|
+
knownMetadata?: Map<string, ToolMetadata[]>,
|
|
17
|
+
includeMissingConfiguredCandidates = false,
|
|
15
18
|
): { metadata: ToolMetadata[]; failedTools: string[] } {
|
|
16
19
|
const metadata: ToolMetadata[] = [];
|
|
17
20
|
const failedTools: string[] = [];
|
|
18
21
|
const seenNames = new Set<string>();
|
|
19
22
|
const effectivePrefix = resolveToolPrefix(definition, prefix);
|
|
23
|
+
const getOtherCurrentCandidates = (toolName: string): Set<string> | undefined => {
|
|
24
|
+
if (!configuredServers) return undefined;
|
|
25
|
+
const candidates = new Set<string>();
|
|
26
|
+
const addCandidates = (originalName: string, candidateServerName: string, candidatePrefix: ToolPrefix) => {
|
|
27
|
+
for (const candidate of getToolNameCandidates(originalName, candidateServerName, candidatePrefix, false)) candidates.add(candidate);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
for (const tool of tools) {
|
|
31
|
+
if (tool?.name) addCandidates(tool.name, serverName, effectivePrefix);
|
|
32
|
+
}
|
|
33
|
+
if (definition.exposeResources !== false) {
|
|
34
|
+
for (const resource of resources) {
|
|
35
|
+
if (resource?.name && resource?.uri) addCandidates(`read_${resourceNameToToolName(resource.name)}`, serverName, effectivePrefix);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const [otherServerName, otherDefinition] of Object.entries(configuredServers)) {
|
|
39
|
+
if (otherServerName === serverName) continue;
|
|
40
|
+
const knownTools = knownMetadata?.get(otherServerName);
|
|
41
|
+
if (knownTools) {
|
|
42
|
+
const otherPrefix = resolveToolPrefix(otherDefinition, prefix);
|
|
43
|
+
for (const tool of knownTools) {
|
|
44
|
+
candidates.add(tool.name);
|
|
45
|
+
addCandidates(tool.originalName, otherServerName, otherPrefix);
|
|
46
|
+
}
|
|
47
|
+
} else if (!knownMetadata || includeMissingConfiguredCandidates) {
|
|
48
|
+
const otherPrefix = resolveToolPrefix(otherDefinition, prefix);
|
|
49
|
+
addCandidates(toolName, otherServerName, otherPrefix);
|
|
50
|
+
if (includeMissingConfiguredCandidates) {
|
|
51
|
+
for (const candidate of getToolNameCandidates(toolName, otherServerName, otherPrefix, false)) candidates.add(candidate.replace(/-/g, "_"));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const candidate of getToolNameCandidates(toolName, serverName, effectivePrefix, false)) candidates.delete(candidate);
|
|
56
|
+
return candidates;
|
|
57
|
+
};
|
|
20
58
|
|
|
21
59
|
for (const tool of tools) {
|
|
22
60
|
if (!tool?.name) {
|
|
23
61
|
failedTools.push("(unnamed)");
|
|
24
62
|
continue;
|
|
25
63
|
}
|
|
26
|
-
if (!isToolAllowed(tool.name, serverName, effectivePrefix, definition.includeTools, definition.excludeTools)) {
|
|
64
|
+
if (!isToolAllowed(tool.name, serverName, effectivePrefix, definition.includeTools, definition.excludeTools, getOtherCurrentCandidates(tool.name))) {
|
|
27
65
|
continue;
|
|
28
66
|
}
|
|
29
67
|
|
|
@@ -59,7 +97,7 @@ export function buildToolMetadata(
|
|
|
59
97
|
if (definition.exposeResources !== false) {
|
|
60
98
|
for (const resource of resources) {
|
|
61
99
|
const baseName = `read_${resourceNameToToolName(resource.name)}`;
|
|
62
|
-
if (!isToolAllowed(baseName, serverName, effectivePrefix, definition.includeTools, definition.excludeTools)) {
|
|
100
|
+
if (!isToolAllowed(baseName, serverName, effectivePrefix, definition.includeTools, definition.excludeTools, getOtherCurrentCandidates(baseName))) {
|
|
63
101
|
continue;
|
|
64
102
|
}
|
|
65
103
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentToolResult, ToolRenderResultOptions } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { type Component, Text } from "@earendil-works/pi-tui";
|
|
2
|
+
import { type Component, Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
3
|
|
|
4
4
|
type McpToolResultDetails = Record<string, unknown> & { error?: unknown };
|
|
5
5
|
type McpToolContentBlock = AgentToolResult<McpToolResultDetails>["content"][number];
|
|
@@ -23,8 +23,27 @@ export interface McpProxyToolCallInput {
|
|
|
23
23
|
action?: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
interface McpToolRenderState {
|
|
27
|
+
compactTitle?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
interface McpToolRenderContext {
|
|
27
31
|
isError: boolean;
|
|
32
|
+
isPartial?: boolean;
|
|
33
|
+
expanded?: boolean;
|
|
34
|
+
state?: McpToolRenderState;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type McpToolResultRendering = "compact" | "boxed";
|
|
38
|
+
|
|
39
|
+
export interface McpToolRenderOptions {
|
|
40
|
+
resultRendering: McpToolResultRendering;
|
|
41
|
+
collapsedResultLines: 1 | 2 | 3;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface McpToolRenderSettings {
|
|
45
|
+
toolResultRendering?: unknown;
|
|
46
|
+
collapsedResultLines?: unknown;
|
|
28
47
|
}
|
|
29
48
|
|
|
30
49
|
export interface McpToolResultDisplay {
|
|
@@ -33,10 +52,62 @@ export interface McpToolResultDisplay {
|
|
|
33
52
|
}
|
|
34
53
|
|
|
35
54
|
const DEFAULT_MAX_CALL_INPUT_CHARS = 1500;
|
|
36
|
-
const
|
|
55
|
+
const DEFAULT_BOXED_COLLAPSED_LINES = 3;
|
|
56
|
+
const DEFAULT_COMPACT_COLLAPSED_LINES = 1;
|
|
37
57
|
const DEFAULT_MAX_COLLAPSED_CHARS = 8000;
|
|
38
58
|
const COLLAPSED_RENDER_CHAR_SLACK = 8;
|
|
39
59
|
|
|
60
|
+
class EmptyComponent implements Component {
|
|
61
|
+
render(): string[] {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
invalidate(): void {}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class CompactMcpToolResult implements Component {
|
|
69
|
+
private rendered: { width: number; lines: string[] } | null = null;
|
|
70
|
+
|
|
71
|
+
constructor(
|
|
72
|
+
private readonly title: string,
|
|
73
|
+
private readonly display: McpToolResultDisplay,
|
|
74
|
+
private readonly theme: RenderTheme,
|
|
75
|
+
) {}
|
|
76
|
+
|
|
77
|
+
render(width: number): string[] {
|
|
78
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
79
|
+
if (this.rendered?.width === safeWidth) return this.rendered.lines;
|
|
80
|
+
|
|
81
|
+
const resultLines = this.display.lines.filter((line, index, lines) => {
|
|
82
|
+
return !(this.display.truncated && index === lines.length - 1 && line === "…");
|
|
83
|
+
});
|
|
84
|
+
const lines = resultLines.length > 0 ? resultLines : [""];
|
|
85
|
+
const bodies = lines.map((line, index) => {
|
|
86
|
+
const prefix = index === 0 && this.title ? `${this.theme.fg("toolTitle", this.title)} → ` : "";
|
|
87
|
+
return `${prefix}${this.theme.fg("toolOutput", line)}`;
|
|
88
|
+
});
|
|
89
|
+
const hiddenText = this.display.truncated || bodies.some((body) => visibleWidth(body) > safeWidth);
|
|
90
|
+
const rendered = bodies.map((body, index) => {
|
|
91
|
+
const suffix = hiddenText && index === bodies.length - 1 ? " … (Ctrl+O to expand)" : "";
|
|
92
|
+
if (!suffix) return truncateToWidth(body, safeWidth, "…");
|
|
93
|
+
if (safeWidth >= suffix.length + 20) {
|
|
94
|
+
return `${truncateToWidth(body, safeWidth - suffix.length, "…")}${this.theme.fg("muted", suffix)}`;
|
|
95
|
+
}
|
|
96
|
+
const shortSuffix = " (Ctrl+O)";
|
|
97
|
+
if (safeWidth >= shortSuffix.length + 5) {
|
|
98
|
+
return `${truncateToWidth(body, safeWidth - shortSuffix.length, "…")}${this.theme.fg("muted", shortSuffix)}`;
|
|
99
|
+
}
|
|
100
|
+
return truncateToWidth(this.theme.fg("muted", shortSuffix.trim()), safeWidth, "…");
|
|
101
|
+
});
|
|
102
|
+
this.rendered = { width: safeWidth, lines: rendered };
|
|
103
|
+
return rendered;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
invalidate(): void {
|
|
107
|
+
this.rendered = null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
40
111
|
class CollapsibleText implements Component {
|
|
41
112
|
private readonly fullText: Text;
|
|
42
113
|
private readonly footerText: Text;
|
|
@@ -47,8 +118,8 @@ class CollapsibleText implements Component {
|
|
|
47
118
|
private readonly text: string,
|
|
48
119
|
private readonly expanded: boolean,
|
|
49
120
|
private readonly maxCollapsedLines: number,
|
|
50
|
-
|
|
51
|
-
|
|
121
|
+
ellipsis: string,
|
|
122
|
+
expandHint: string,
|
|
52
123
|
private readonly preTruncated = false,
|
|
53
124
|
) {
|
|
54
125
|
this.fullText = new Text(text, 0, 0);
|
|
@@ -168,13 +239,52 @@ function renderToolCallLines(lines: string[], theme?: RenderTheme) {
|
|
|
168
239
|
return new Text([styledTitle, ...styledRest].join("\n"), 0, 0);
|
|
169
240
|
}
|
|
170
241
|
|
|
171
|
-
export function
|
|
172
|
-
|
|
242
|
+
export function resolveMcpToolRenderOptions(settings?: McpToolRenderSettings): McpToolRenderOptions {
|
|
243
|
+
const resultRendering = settings?.toolResultRendering === "boxed" ? "boxed" : "compact";
|
|
244
|
+
const collapsedLines = settings?.collapsedResultLines;
|
|
245
|
+
const defaultLines = resultRendering === "boxed" ? DEFAULT_BOXED_COLLAPSED_LINES : DEFAULT_COMPACT_COLLAPSED_LINES;
|
|
246
|
+
return {
|
|
247
|
+
resultRendering,
|
|
248
|
+
collapsedResultLines: collapsedLines === 1 || collapsedLines === 2 || collapsedLines === 3 ? collapsedLines : defaultLines,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function shouldUseCompactFinalRender(options: McpToolRenderOptions, context?: McpToolRenderContext): boolean {
|
|
253
|
+
return options.resultRendering === "compact"
|
|
254
|
+
&& context !== undefined
|
|
255
|
+
&& context.isPartial === false
|
|
256
|
+
&& context.expanded !== true
|
|
257
|
+
&& context.isError !== true;
|
|
173
258
|
}
|
|
174
259
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
260
|
+
function renderToolCall(
|
|
261
|
+
lines: string[],
|
|
262
|
+
theme: RenderTheme | undefined,
|
|
263
|
+
context: McpToolRenderContext | undefined,
|
|
264
|
+
options: McpToolRenderOptions,
|
|
265
|
+
) {
|
|
266
|
+
if (context?.state) context.state.compactTitle = lines[0] ?? "mcp";
|
|
267
|
+
if (shouldUseCompactFinalRender(options, context)) return new EmptyComponent();
|
|
268
|
+
return renderToolCallLines(lines, theme);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function renderMcpProxyToolCall(
|
|
272
|
+
args: McpProxyToolCallInput,
|
|
273
|
+
theme?: RenderTheme,
|
|
274
|
+
context?: McpToolRenderContext,
|
|
275
|
+
) {
|
|
276
|
+
return renderToolCall(formatMcpProxyToolCallLines(args), theme, context, resolveMcpToolRenderOptions());
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export function createMcpProxyToolCallRenderer(options: McpToolRenderOptions) {
|
|
280
|
+
return (args: McpProxyToolCallInput, theme?: RenderTheme, context?: McpToolRenderContext) => {
|
|
281
|
+
return renderToolCall(formatMcpProxyToolCallLines(args), theme, context, options);
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function createMcpDirectToolCallRenderer(displayName: string, options = resolveMcpToolRenderOptions()) {
|
|
286
|
+
return (args: Record<string, unknown>, theme?: RenderTheme, context?: McpToolRenderContext) => {
|
|
287
|
+
return renderToolCall(formatMcpDirectToolCallLines(displayName, args), theme, context, options);
|
|
178
288
|
};
|
|
179
289
|
}
|
|
180
290
|
|
|
@@ -254,7 +364,7 @@ export function formatMcpToolResultIdentity(details: McpToolResultDetails | unde
|
|
|
254
364
|
export function formatMcpToolResultLines(
|
|
255
365
|
result: Pick<AgentToolResult<McpToolResultDetails>, "content">,
|
|
256
366
|
expanded: boolean,
|
|
257
|
-
maxCollapsedLines =
|
|
367
|
+
maxCollapsedLines = DEFAULT_BOXED_COLLAPSED_LINES,
|
|
258
368
|
maxCollapsedChars = DEFAULT_MAX_COLLAPSED_CHARS,
|
|
259
369
|
): McpToolResultDisplay {
|
|
260
370
|
if (!expanded) {
|
|
@@ -271,6 +381,7 @@ export function renderMcpToolResult(
|
|
|
271
381
|
options: ToolRenderResultOptions,
|
|
272
382
|
theme?: RenderTheme,
|
|
273
383
|
context?: McpToolRenderContext,
|
|
384
|
+
renderOptions = resolveMcpToolRenderOptions(),
|
|
274
385
|
) {
|
|
275
386
|
const activeTheme = theme ?? plainTheme;
|
|
276
387
|
if (options.isPartial) {
|
|
@@ -279,7 +390,13 @@ export function renderMcpToolResult(
|
|
|
279
390
|
|
|
280
391
|
const hasErrorDetails = Boolean(result.details.error);
|
|
281
392
|
const expanded = options.expanded || context?.isError === true || hasErrorDetails;
|
|
282
|
-
|
|
393
|
+
if (!expanded && renderOptions.resultRendering === "compact") {
|
|
394
|
+
const display = formatMcpToolResultLines(result, false, renderOptions.collapsedResultLines);
|
|
395
|
+
const title = context?.state?.compactTitle ?? formatMcpToolResultIdentity(result.details) ?? "";
|
|
396
|
+
return new CompactMcpToolResult(title, display, activeTheme);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const display = formatMcpToolResultLines(result, expanded, renderOptions.collapsedResultLines);
|
|
283
400
|
const identity = formatMcpToolResultIdentity(result.details);
|
|
284
401
|
const output = [
|
|
285
402
|
...(identity ? [activeTheme.fg("muted", identity)] : []),
|
|
@@ -289,9 +406,18 @@ export function renderMcpToolResult(
|
|
|
289
406
|
return new CollapsibleText(
|
|
290
407
|
output,
|
|
291
408
|
expanded,
|
|
292
|
-
|
|
409
|
+
renderOptions.collapsedResultLines + (identity ? 1 : 0),
|
|
293
410
|
activeTheme.fg("muted", "…"),
|
|
294
411
|
activeTheme.fg("muted", "(Ctrl+O to expand)"),
|
|
295
412
|
display.truncated,
|
|
296
413
|
);
|
|
297
414
|
}
|
|
415
|
+
|
|
416
|
+
export function createMcpToolResultRenderer(renderOptions: McpToolRenderOptions) {
|
|
417
|
+
return (
|
|
418
|
+
result: AgentToolResult<McpToolResultDetails>,
|
|
419
|
+
options: ToolRenderResultOptions,
|
|
420
|
+
theme?: RenderTheme,
|
|
421
|
+
context?: McpToolRenderContext,
|
|
422
|
+
) => renderMcpToolResult(result, options, theme, context, renderOptions);
|
|
423
|
+
}
|
|
@@ -395,6 +395,13 @@ export interface ServerEntry {
|
|
|
395
395
|
// Include/exclude specific MCP tools/resources by original or prefixed name
|
|
396
396
|
includeTools?: string[];
|
|
397
397
|
excludeTools?: string[];
|
|
398
|
+
/**
|
|
399
|
+
* Extra search keywords per tool, keyed by original name, prefixed name, or
|
|
400
|
+
* glob (same matching rules as includeTools/excludeTools). Keywords boost
|
|
401
|
+
* mcp({ search }) ranking only — they never appear in tool schemas,
|
|
402
|
+
* describe output, or the metadata cache.
|
|
403
|
+
*/
|
|
404
|
+
searchKeywords?: Record<string, string[]>;
|
|
398
405
|
// Require interactive approval before calling matching MCP tools/resources.
|
|
399
406
|
approveTools?: boolean | string[];
|
|
400
407
|
// Debug
|
|
@@ -473,6 +480,8 @@ export interface McpSettings {
|
|
|
473
480
|
showStatusIcon?: boolean;
|
|
474
481
|
/** Footer status verbosity: full details, compact connected/enabled count, or no footer status. Defaults to full. */
|
|
475
482
|
mcpFooterStatus?: McpFooterStatus;
|
|
483
|
+
/** Show successful startup connection notifications. Defaults to true. */
|
|
484
|
+
notifyOnStartupConnect?: boolean;
|
|
476
485
|
/** Discover detected host-specific MCP configs only when explicitly enabled. */
|
|
477
486
|
hostConfigDiscovery?: HostConfigDiscovery;
|
|
478
487
|
/** Agent Plugin package directories to load MCP servers from. */
|
|
@@ -482,6 +491,10 @@ export interface McpSettings {
|
|
|
482
491
|
directTools?: boolean;
|
|
483
492
|
/** Register the trusted MCP-only JavaScript scripting tool. Defaults to true; set false to hide it. */
|
|
484
493
|
scriptMode?: boolean;
|
|
494
|
+
/** Render MCP tool results as compact self-rendered rows by default, or as the legacy boxed row. */
|
|
495
|
+
toolResultRendering?: "compact" | "boxed";
|
|
496
|
+
/** Number of result text lines to show before expansion. Supports 1, 2, or 3. Defaults to 1 in compact mode and 3 in boxed mode. */
|
|
497
|
+
collapsedResultLines?: 1 | 2 | 3;
|
|
485
498
|
/** Default approval gate for matching tools/resources; per-server settings override it. */
|
|
486
499
|
approveTools?: boolean | string[];
|
|
487
500
|
disableProxyTool?: boolean;
|
|
@@ -635,18 +648,25 @@ export interface McpPanelResult {
|
|
|
635
648
|
/**
|
|
636
649
|
* Get server prefix based on tool prefix mode.
|
|
637
650
|
*/
|
|
651
|
+
function sanitizeServerPrefix(serverName: string, preserveProviderValid = true): string {
|
|
652
|
+
const validCharacters = preserveProviderValid ? /^[A-Za-z0-9_-]$/ : /^[A-Za-z0-9]$/;
|
|
653
|
+
return Array.from(serverName, char =>
|
|
654
|
+
validCharacters.test(char) ? char : `_${char.codePointAt(0)!.toString(16)}_`,
|
|
655
|
+
).join("");
|
|
656
|
+
}
|
|
657
|
+
|
|
638
658
|
export function getServerPrefix(
|
|
639
659
|
serverName: string,
|
|
640
660
|
mode: ToolPrefix
|
|
641
661
|
): string {
|
|
642
662
|
if (mode === "none") return "";
|
|
643
663
|
if (mode === "short") {
|
|
644
|
-
let short = serverName.replace(/-?mcp$/i, "")
|
|
664
|
+
let short = sanitizeServerPrefix(serverName.replace(/-?mcp$/i, ""));
|
|
645
665
|
if (!short) short = "mcp";
|
|
646
666
|
return short;
|
|
647
667
|
}
|
|
648
|
-
if (mode === "mcp") return `mcp__${serverName
|
|
649
|
-
return serverName
|
|
668
|
+
if (mode === "mcp") return `mcp__${sanitizeServerPrefix(serverName)}`;
|
|
669
|
+
return sanitizeServerPrefix(serverName);
|
|
650
670
|
}
|
|
651
671
|
|
|
652
672
|
/**
|
|
@@ -700,11 +720,9 @@ export function resolveServerFromToolName(
|
|
|
700
720
|
if (candidates.length === 0) return undefined;
|
|
701
721
|
candidates.sort((a, b) => b.prefix.length - a.prefix.length);
|
|
702
722
|
const best = candidates[0];
|
|
703
|
-
// Fail safe:
|
|
704
|
-
//
|
|
705
|
-
//
|
|
706
|
-
// downstream permission gate falls back to its existing wildcard path rather
|
|
707
|
-
// than enforcing a rule against the wrong server.
|
|
723
|
+
// Fail safe: short mode can intentionally map names such as foo and foo-mcp
|
|
724
|
+
// to the same prefix. Return undefined so a downstream permission gate uses
|
|
725
|
+
// its existing wildcard path rather than enforcing a rule against the wrong server.
|
|
708
726
|
if (candidates.some((c) => c.prefix === best!.prefix && c.name !== best!.name)) {
|
|
709
727
|
return undefined;
|
|
710
728
|
}
|
|
@@ -722,22 +740,48 @@ export function formatPromptCommandName(
|
|
|
722
740
|
serverName: string,
|
|
723
741
|
prefix: ToolPrefix,
|
|
724
742
|
): string {
|
|
725
|
-
const serverPart = getServerPrefix(serverName, prefix) || serverName
|
|
743
|
+
const serverPart = getServerPrefix(serverName, prefix) || sanitizeServerPrefix(serverName) || "server";
|
|
726
744
|
return `mcp__${serverPart}__${sanitizePromptName(promptName)}`;
|
|
727
745
|
}
|
|
728
746
|
|
|
729
|
-
function
|
|
730
|
-
|
|
747
|
+
function getLegacyServerPrefix(serverName: string, mode: ToolPrefix): string {
|
|
748
|
+
if (mode === "none") return "";
|
|
749
|
+
if (mode === "short") return sanitizeServerPrefix(serverName.replace(/-?mcp$/i, ""), false) || "mcp";
|
|
750
|
+
if (mode === "mcp") return `mcp__${sanitizeServerPrefix(serverName, false)}`;
|
|
751
|
+
return sanitizeServerPrefix(serverName, false);
|
|
731
752
|
}
|
|
732
753
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
754
|
+
function formatLegacyToolName(toolName: string, serverName: string, prefix: ToolPrefix): string {
|
|
755
|
+
const serverPrefix = getLegacyServerPrefix(serverName, prefix);
|
|
756
|
+
const sanitizedToolName = toolName.replace(/[.-]/g, "_");
|
|
757
|
+
return serverPrefix ? `${serverPrefix}_${sanitizedToolName}` : sanitizedToolName;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
export function getToolNameCandidates(toolName: string, serverName: string, prefix: ToolPrefix, includeLegacy = true): Set<string> {
|
|
761
|
+
const candidates = new Set<string>([
|
|
762
|
+
toolName,
|
|
763
|
+
formatToolName(toolName, serverName, prefix),
|
|
764
|
+
formatToolName(toolName, serverName, "server"),
|
|
765
|
+
formatToolName(toolName, serverName, "short"),
|
|
766
|
+
formatToolName(toolName, serverName, "mcp"),
|
|
740
767
|
]);
|
|
768
|
+
if (includeLegacy) {
|
|
769
|
+
const legacyToolName = toolName.replace(/-/g, "_");
|
|
770
|
+
candidates.add(legacyToolName);
|
|
771
|
+
candidates.add(formatToolName(legacyToolName, serverName, prefix));
|
|
772
|
+
candidates.add(formatToolName(legacyToolName, serverName, "server"));
|
|
773
|
+
candidates.add(formatToolName(legacyToolName, serverName, "short"));
|
|
774
|
+
candidates.add(formatToolName(legacyToolName, serverName, "mcp"));
|
|
775
|
+
candidates.add(formatLegacyToolName(toolName, serverName, prefix));
|
|
776
|
+
candidates.add(formatLegacyToolName(toolName, serverName, "server"));
|
|
777
|
+
candidates.add(formatLegacyToolName(toolName, serverName, "short"));
|
|
778
|
+
candidates.add(formatLegacyToolName(toolName, serverName, "mcp"));
|
|
779
|
+
candidates.add(formatToolName(toolName, serverName, prefix).replace(/-/g, "_"));
|
|
780
|
+
candidates.add(formatToolName(toolName, serverName, "server").replace(/-/g, "_"));
|
|
781
|
+
candidates.add(formatToolName(toolName, serverName, "short").replace(/-/g, "_"));
|
|
782
|
+
candidates.add(formatToolName(toolName, serverName, "mcp").replace(/-/g, "_"));
|
|
783
|
+
}
|
|
784
|
+
return candidates;
|
|
741
785
|
}
|
|
742
786
|
|
|
743
787
|
function globToRegExp(pattern: string): RegExp {
|
|
@@ -750,11 +794,10 @@ export function matchesToolPattern(candidates: Set<string>, patterns?: unknown):
|
|
|
750
794
|
|
|
751
795
|
for (const pattern of patterns) {
|
|
752
796
|
if (typeof pattern !== "string") continue;
|
|
753
|
-
|
|
754
|
-
if (!normalized.includes("*") && !normalized.includes("?") && candidates.has(normalized)) {
|
|
797
|
+
if (!pattern.includes("*") && !pattern.includes("?") && candidates.has(pattern)) {
|
|
755
798
|
return true;
|
|
756
799
|
}
|
|
757
|
-
if ((
|
|
800
|
+
if ((pattern.includes("*") || pattern.includes("?")) && [...candidates].some(candidate => globToRegExp(pattern).test(candidate))) {
|
|
758
801
|
return true;
|
|
759
802
|
}
|
|
760
803
|
}
|
|
@@ -762,23 +805,45 @@ export function matchesToolPattern(candidates: Set<string>, patterns?: unknown):
|
|
|
762
805
|
return false;
|
|
763
806
|
}
|
|
764
807
|
|
|
808
|
+
function matchesToolSelector(
|
|
809
|
+
toolName: string,
|
|
810
|
+
serverName: string,
|
|
811
|
+
prefix: ToolPrefix,
|
|
812
|
+
patterns: unknown,
|
|
813
|
+
otherCurrentCandidates?: Set<string>,
|
|
814
|
+
): boolean {
|
|
815
|
+
const currentCandidates = getToolNameCandidates(toolName, serverName, prefix, false);
|
|
816
|
+
if (matchesToolPattern(currentCandidates, patterns)) return true;
|
|
817
|
+
if (!otherCurrentCandidates) return matchesToolPattern(getToolNameCandidates(toolName, serverName, prefix), patterns);
|
|
818
|
+
const legacyCandidates = getToolNameCandidates(toolName, serverName, prefix);
|
|
819
|
+
for (const candidate of currentCandidates) legacyCandidates.delete(candidate);
|
|
820
|
+
if (!Array.isArray(patterns)) return false;
|
|
821
|
+
return patterns.some(pattern =>
|
|
822
|
+
typeof pattern === "string"
|
|
823
|
+
&& !matchesToolPattern(otherCurrentCandidates, [pattern])
|
|
824
|
+
&& matchesToolPattern(legacyCandidates, [pattern]),
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
|
|
765
828
|
export function isToolIncluded(
|
|
766
829
|
toolName: string,
|
|
767
830
|
serverName: string,
|
|
768
831
|
prefix: ToolPrefix,
|
|
769
|
-
includeTools?: unknown
|
|
832
|
+
includeTools?: unknown,
|
|
833
|
+
otherCurrentCandidates?: Set<string>,
|
|
770
834
|
): boolean {
|
|
771
835
|
if (!Array.isArray(includeTools) || includeTools.length === 0) return true;
|
|
772
|
-
return
|
|
836
|
+
return matchesToolSelector(toolName, serverName, prefix, includeTools, otherCurrentCandidates);
|
|
773
837
|
}
|
|
774
838
|
|
|
775
839
|
export function isToolExcluded(
|
|
776
840
|
toolName: string,
|
|
777
841
|
serverName: string,
|
|
778
842
|
prefix: ToolPrefix,
|
|
779
|
-
excludeTools?: unknown
|
|
843
|
+
excludeTools?: unknown,
|
|
844
|
+
otherCurrentCandidates?: Set<string>,
|
|
780
845
|
): boolean {
|
|
781
|
-
return
|
|
846
|
+
return matchesToolSelector(toolName, serverName, prefix, excludeTools, otherCurrentCandidates);
|
|
782
847
|
}
|
|
783
848
|
|
|
784
849
|
export function isToolAllowed(
|
|
@@ -787,7 +852,8 @@ export function isToolAllowed(
|
|
|
787
852
|
prefix: ToolPrefix,
|
|
788
853
|
includeTools?: unknown,
|
|
789
854
|
excludeTools?: unknown,
|
|
855
|
+
otherCurrentCandidates?: Set<string>,
|
|
790
856
|
): boolean {
|
|
791
|
-
return isToolIncluded(toolName, serverName, prefix, includeTools)
|
|
792
|
-
&& !isToolExcluded(toolName, serverName, prefix, excludeTools);
|
|
857
|
+
return isToolIncluded(toolName, serverName, prefix, includeTools, otherCurrentCandidates)
|
|
858
|
+
&& !isToolExcluded(toolName, serverName, prefix, excludeTools, otherCurrentCandidates);
|
|
793
859
|
}
|
|
@@ -18,6 +18,7 @@ import type { McpExtensionState } from "./state.ts";
|
|
|
18
18
|
import { SessionRecoveryAuthRequiredError, withSessionRecovery, type SessionRecoveryDeps } from "./session-recovery.ts";
|
|
19
19
|
import { ensureToolCallApproved, isToolCallApprovalRequired } from "./tool-approval.ts";
|
|
20
20
|
import { extractUiToolVisibility, isUiToolCallableByApp, isUiToolVisibleToModel } from "./ui-tool-visibility.ts";
|
|
21
|
+
import { resourceNameToToolName } from "./resource-tools.ts";
|
|
21
22
|
import {
|
|
22
23
|
createUiModelContextUpdate,
|
|
23
24
|
extractUiPromptText,
|
|
@@ -451,6 +452,23 @@ export async function startUiServer(options: UiServerOptions): Promise<UiServerH
|
|
|
451
452
|
...(toolDefinition?.inputSchema !== undefined ? { inputSchema: toolDefinition.inputSchema } : {}),
|
|
452
453
|
...(uiVisibility !== undefined ? { uiVisibility } : {}),
|
|
453
454
|
};
|
|
455
|
+
const approvalMetadata = new Map(options.state?.toolMetadata);
|
|
456
|
+
const definition = options.config?.mcpServers[options.serverName] ?? options.state?.config.mcpServers[options.serverName];
|
|
457
|
+
approvalMetadata.set(options.serverName, [
|
|
458
|
+
...connection.tools.map(tool => ({
|
|
459
|
+
name: tool.name,
|
|
460
|
+
originalName: tool.name,
|
|
461
|
+
description: tool.description ?? "",
|
|
462
|
+
})),
|
|
463
|
+
...(definition?.exposeResources !== false ? (connection.resources ?? []).map(resource => {
|
|
464
|
+
const originalName = `read_${resourceNameToToolName(resource.name)}`;
|
|
465
|
+
return {
|
|
466
|
+
name: originalName,
|
|
467
|
+
originalName,
|
|
468
|
+
description: resource.description ?? `Read resource: ${resource.uri}`,
|
|
469
|
+
};
|
|
470
|
+
}) : []),
|
|
471
|
+
]);
|
|
454
472
|
const approval = options.state
|
|
455
473
|
? await ensureToolCallApproved(
|
|
456
474
|
options.state,
|
|
@@ -459,8 +477,9 @@ export async function startUiServer(options: UiServerOptions): Promise<UiServerH
|
|
|
459
477
|
callArgs.arguments,
|
|
460
478
|
options.state.owner?.signal,
|
|
461
479
|
"iframe",
|
|
480
|
+
approvalMetadata,
|
|
462
481
|
)
|
|
463
|
-
: options.config && isToolCallApprovalRequired(options.config, options.serverName, toolMeta)
|
|
482
|
+
: options.config && isToolCallApprovalRequired(options.config, options.serverName, toolMeta, approvalMetadata)
|
|
464
483
|
? { ok: false as const, reason: "approval_required_headless" as const }
|
|
465
484
|
: { ok: true as const };
|
|
466
485
|
if (approval.ok === false) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herbertgao/pi-extensions",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.5",
|
|
4
4
|
"description": "Aggregate installer for HerbertGao-maintained Pi extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"extensions",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@earendil-works/pi-tui": "^0.84.1",
|
|
43
43
|
"@effect/platform-node": "4.0.0-beta.103",
|
|
44
44
|
"@effect/platform-node-shared": "4.0.0-beta.103",
|
|
45
|
-
"@herbertgao/pi-cc-extensions": "0.8.
|
|
45
|
+
"@herbertgao/pi-cc-extensions": "0.8.54",
|
|
46
46
|
"@herbertgao/pi-copy-response": "0.2.6",
|
|
47
47
|
"@herbertgao/pi-handoff": "1.1.2",
|
|
48
48
|
"@herbertgao/pi-inline-skills": "1.0.5",
|
|
@@ -51,18 +51,18 @@
|
|
|
51
51
|
"@herbertgao/pi-recap": "0.4.4",
|
|
52
52
|
"@herbertgao/pi-rename": "0.4.2",
|
|
53
53
|
"@herbertgao/pi-stash": "0.1.1",
|
|
54
|
-
"@herbertgao/pi-subagents": "0.15.
|
|
54
|
+
"@herbertgao/pi-subagents": "0.15.4",
|
|
55
55
|
"@herbertgao/pi-titlebar-spinner": "0.1.3",
|
|
56
|
-
"@juicesharp/rpiv-ask-user-question": "2.
|
|
57
|
-
"@juicesharp/rpiv-config": "^2.
|
|
56
|
+
"@juicesharp/rpiv-ask-user-question": "2.5.2",
|
|
57
|
+
"@juicesharp/rpiv-config": "^2.5.2",
|
|
58
58
|
"@modelcontextprotocol/client": "2.0.0",
|
|
59
59
|
"@modelcontextprotocol/core": "2.0.0",
|
|
60
60
|
"@modelcontextprotocol/ext-apps": "^1.2.2",
|
|
61
61
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
62
62
|
"@mozilla/readability": "^0.6.0",
|
|
63
63
|
"@napi-rs/keyring": "^1.3.0",
|
|
64
|
-
"@narumitw/pi-btw": "0.
|
|
65
|
-
"@narumitw/pi-tui-kit": "^0.
|
|
64
|
+
"@narumitw/pi-btw": "0.51.0",
|
|
65
|
+
"@narumitw/pi-tui-kit": "^0.54.0",
|
|
66
66
|
"@noble/ed25519": "^3.1.0",
|
|
67
67
|
"@pi-plugins/fast-mode": "0.1.9",
|
|
68
68
|
"@shikijs/cli": "^4.0.2",
|
|
@@ -77,13 +77,13 @@
|
|
|
77
77
|
"jiti": "^2.7.0",
|
|
78
78
|
"js-yaml": "^5.2.2",
|
|
79
79
|
"linkedom": "^0.16.0",
|
|
80
|
-
"minimatch": "^10.2.
|
|
80
|
+
"minimatch": "^10.2.6",
|
|
81
81
|
"nanoid": "^5.0.0",
|
|
82
82
|
"open": "^10.2.0",
|
|
83
83
|
"p-limit": "^6.1.0",
|
|
84
84
|
"pi-footer": "0.5.1",
|
|
85
|
-
"pi-lens": "
|
|
86
|
-
"pi-mcp-adapter": "2.
|
|
85
|
+
"pi-lens": "4.0.0",
|
|
86
|
+
"pi-mcp-adapter": "2.25.0",
|
|
87
87
|
"pi-web-access": "0.22.0",
|
|
88
88
|
"pidusage": "^4.0.1",
|
|
89
89
|
"promise.try": "^2.0.1",
|
|
@@ -161,8 +161,7 @@
|
|
|
161
161
|
"skills": [
|
|
162
162
|
"./node_modules/@dietrichgebert/ponytail/skills",
|
|
163
163
|
"./node_modules/pi-mcp-adapter/skills",
|
|
164
|
-
"./node_modules/pi-lens/skills"
|
|
165
|
-
"./node_modules/remote-pi/skills"
|
|
164
|
+
"./node_modules/pi-lens/skills"
|
|
166
165
|
]
|
|
167
166
|
}
|
|
168
167
|
}
|