@herbertgao/pi-extensions 2026.8.11 → 2026.8.13
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 +23 -10
- package/{node_modules/@herbertgao/pi-mermaid-open/LICENSE → THIRD_PARTY_NOTICES.md} +19 -1
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
- package/node_modules/@czottmann/pi-automode/README.md +5 -3
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
- package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
- package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
- package/node_modules/@czottmann/pi-automode/package.json +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
- package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
- package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
- package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +376 -0
- package/node_modules/@luxusai/pi-hindsight/README.md +92 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +56 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +169 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +107 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +89 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +189 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +54 -0
- package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +75 -0
- package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +300 -0
- package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +158 -0
- package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +164 -0
- package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +139 -0
- package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +74 -0
- package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +261 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +151 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +18 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +46 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +383 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +240 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +176 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +178 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +41 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +386 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +39 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +34 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +140 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +61 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +925 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +247 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +547 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +480 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +182 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +86 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +1010 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +175 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +425 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +210 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +817 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +25 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +319 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +196 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +189 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +65 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +260 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +244 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +59 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +82 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +45 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +331 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +354 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +66 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +132 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +228 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +74 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +16 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +648 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +105 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +68 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +71 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +13 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +162 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +131 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +104 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +37 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +893 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +35 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +177 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +7 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +21 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +112 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +111 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +214 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +70 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +392 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +45 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +9 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +860 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +105 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +189 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +299 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +201 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +47 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +239 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +50 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +259 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +77 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +534 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +319 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +325 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +42 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +244 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +56 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +50 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +167 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +207 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +120 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +8 -0
- package/node_modules/@luxusai/pi-hindsight/package.json +118 -0
- package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +75 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +6 -6
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
- package/node_modules/@tifan/pi-handoff/package.json +43 -0
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
- package/node_modules/@tifan/pi-recap/package.json +42 -0
- package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
- package/node_modules/@tifan/pi-rename/package.json +47 -0
- package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
- package/node_modules/pi-lens/CHANGELOG.md +96 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
- package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
- package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
- package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
- package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
- package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
- package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
- package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
- package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
- package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
- package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
- package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
- package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
- package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
- package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
- package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
- package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
- package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
- package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
- package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
- package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
- package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
- package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
- package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
- package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
- package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
- package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
- package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
- package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
- package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
- package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
- package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
- package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
- package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
- package/node_modules/pi-lens/dist/i18n.js +13 -5
- package/node_modules/pi-lens/dist/index.js +10797 -8627
- package/node_modules/pi-lens/dist/mcp/server.js +3 -1
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
- package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
- package/node_modules/pi-lens/package.json +160 -156
- package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
- package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +47 -0
- package/node_modules/pi-mcp-adapter/README.md +42 -13
- package/node_modules/pi-mcp-adapter/commands.ts +4 -2
- package/node_modules/pi-mcp-adapter/config.ts +45 -5
- package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
- package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +1087 -0
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
- package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
- package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
- package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
- package/node_modules/pi-mcp-adapter/index.ts +204 -82
- package/node_modules/pi-mcp-adapter/init.ts +41 -30
- package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
- package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
- package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
- package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
- package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
- package/node_modules/pi-mcp-adapter/package.json +24 -6
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
- package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
- package/node_modules/pi-mcp-adapter/state.ts +1 -3
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
- package/node_modules/pi-mcp-adapter/types.ts +48 -1
- package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
- package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
- package/node_modules/pi-mcp-adapter/utils.ts +21 -19
- package/node_modules/pi-web-access/CHANGELOG.md +26 -0
- package/node_modules/pi-web-access/README.md +71 -14
- package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
- package/node_modules/pi-web-access/credential-source.ts +6 -2
- package/node_modules/pi-web-access/curator-page.ts +5 -3
- package/node_modules/pi-web-access/curator-server.ts +2 -1
- package/node_modules/pi-web-access/extract.ts +89 -9
- package/node_modules/pi-web-access/fetch-params.ts +13 -0
- package/node_modules/pi-web-access/gemini-adc.ts +298 -0
- package/node_modules/pi-web-access/gemini-api.ts +59 -15
- package/node_modules/pi-web-access/gemini-search.ts +58 -18
- package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
- package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
- package/node_modules/pi-web-access/gemini-web.ts +9 -3
- package/node_modules/pi-web-access/github-api.ts +5 -4
- package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
- package/node_modules/pi-web-access/index.ts +403 -297
- package/node_modules/pi-web-access/kimi-search.ts +234 -0
- package/node_modules/pi-web-access/openai-search.ts +118 -21
- package/node_modules/pi-web-access/package.json +3 -2
- package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
- package/node_modules/pi-web-access/utils.ts +307 -1
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +46 -37
- package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
- package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
- package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
- package/node_modules/@herbertgao/pi-inline-skills/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
- package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
- package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
- package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/package.json +0 -55
- package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-rename/package.json +0 -63
- package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
- package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
- /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
|
@@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.29.0] - 2026-08-26
|
|
11
|
+
|
|
12
|
+
### Highlights
|
|
13
|
+
- `/mcp setup` can now add Parallel Search as an opt-in preset.
|
|
14
|
+
- Users can try web search and page fetching without first creating an API key.
|
|
15
|
+
- MCP status updates work better in non-TUI hosts that provide plain theme values.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Added an opt-in Parallel Search preset to `/mcp setup` for web search and page fetching without an API key. Thanks to [@georgeatparallel](https://github.com/georgeatparallel) for PR #448.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- MCP status updates now use plain text when a non-TUI host provides a theme without styling methods. Thanks to [@jinnnyang](https://github.com/jinnnyang) for #449.
|
|
22
|
+
|
|
23
|
+
## [2.28.0] - 2026-08-26
|
|
24
|
+
|
|
25
|
+
### Highlights
|
|
26
|
+
- MCP connections are less fragile when servers fail, recover, move slowly, or refresh their catalogs.
|
|
27
|
+
- Direct MCP tools are safer to expose, with stricter input checks and bounded result details when hosts opt in.
|
|
28
|
+
- Other Pi extensions can register MCP servers at runtime without sharing module state.
|
|
29
|
+
- Proxy calls now show live server progress in the interactive UI.
|
|
30
|
+
- Package installs and public helper imports are easier to use from downstream hosts.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- Persistent metadata cache entries now honor server `ttlMs` hints without extending the default max age. Thanks to [@Seinra](https://github.com/Seinra) for #431.
|
|
34
|
+
- Proxy tool calls now forward server progress notifications to the interactive UI. Thanks to [@Seinra](https://github.com/Seinra) for PR #440 and for mapping the area in #431.
|
|
35
|
+
- Added a pure `mcp:` reference resolver API for consumers that validate adapter tool names from explicit config and cache inputs. Thanks to [@abdwhb-png](https://github.com/abdwhb-png) for PR #420.
|
|
36
|
+
- Direct tools can opt into strict advertised-schema validation with one-layer JSON recovery for object and array properties. Thanks to [@4ndr3wxh1ll](https://github.com/4ndr3wxh1ll) for PR #430.
|
|
37
|
+
- Direct tools can opt into guarded raw MCP result details, retaining bounded structured fields while summarizing oversized values.
|
|
38
|
+
- Embedding hosts can import the configuration loader and metadata cache helpers from public package subpaths, and can validate cached metadata against an explicit private process environment.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- Runtime MCP registration now works across separately loaded Pi extensions through a versioned shared event contract. Thanks to [@fmoda3](https://github.com/fmoda3) for #443.
|
|
42
|
+
- Stdio MCP startup errors now identify a configured missing or non-directory `cwd` instead of blaming the executable. Thanks to [@SoyElf](https://github.com/SoyElf) for #442.
|
|
43
|
+
- Package installs with `--omit=dev` no longer run the public helper build during `prepare`; Git installs and package tarballs still include the built public exports. Thanks to [@KripaMishra](https://github.com/KripaMishra) for #441.
|
|
44
|
+
- MCP gateway descriptions now stay stable across metadata-only refreshes and keep live counts behind `mcp({})`. Thanks to [@voidfreud](https://github.com/voidfreud) for PR #432.
|
|
45
|
+
- Failed MCP servers in active backoff no longer remain advertised through cached direct tools, gateway list/search/describe results, or status tool counts. Thanks to [@voidfreud](https://github.com/voidfreud) for PR #434.
|
|
46
|
+
- OAuth token invalidation now preserves credentials replaced by another Pi process instead of letting a stale refresh delete newly authorized shared credentials. Thanks to [@mjlbach](https://github.com/mjlbach) for PR #422.
|
|
47
|
+
- Failed first-time MCP initialization no longer leaves the session permanently stuck with only `MCP not initialized`; the gateway keeps the failure reason and retries initialization on the next `mcp(...)` call. Thanks to [@hara-seihun](https://github.com/hara-seihun) for #428.
|
|
48
|
+
- HTTP 202 and unauthenticated HTTP 401 endpoint probes now report ambiguous endpoint shape instead of claiming the URL is not MCP. Thanks to [@jayshah5696](https://github.com/jayshah5696) for #415.
|
|
49
|
+
- Expanded `mcpScript` calls now show bounded submitted code. Thanks to [@DenisBalan](https://github.com/DenisBalan) for #413.
|
|
50
|
+
- Gateway parameters nested inside `args` now fail with top-level guidance instead of dispatching inconsistently. Thanks to [@voidfreud](https://github.com/voidfreud) for PR #417.
|
|
51
|
+
- Large direct-tool advisories now explain how to hide them with `settings.warnOnLargeDirectTools: false`. Thanks to [@afrodao2394](https://github.com/afrodao2394) for #412.
|
|
52
|
+
- Namespace proxy tools now use valid cached metadata, include resource-only proxy servers, clean up only prior namespace registrations, follow `MCP_DIRECT_TOOLS` selection, and skip ambiguous normalized server names. Thanks to [@abdwhb-png](https://github.com/abdwhb-png) for PR #414.
|
|
53
|
+
- Kept transient HTTP 503 connection failures as availability errors without multiplying gateway retries or misdiagnosing the endpoint as non-MCP. Thanks to [@elkaix](https://github.com/elkaix) for PR #411.
|
|
54
|
+
- Preserved cached keep-alive catalogs during transient 503 refresh outages while deferred recovery continues with bounded backoff.
|
|
55
|
+
- Startup connections that fail with a transient HTTP 503 now surface one quiet "temporarily unavailable; retry later" warning instead of the full hard failure; documented lifecycle behavior is unchanged, and keep-alive health checks continue their existing self-healing path. Thanks to [@elkaix](https://github.com/elkaix) for PR #424.
|
|
56
|
+
|
|
10
57
|
## [2.27.0] - 2026-08-20
|
|
11
58
|
|
|
12
59
|
### Highlights
|
|
@@ -24,6 +24,8 @@ pi install npm:pi-mcp-adapter
|
|
|
24
24
|
|
|
25
25
|
Restart Pi after installation.
|
|
26
26
|
|
|
27
|
+
> **DeepSeek Harness (third-party bridge):** Run the unmodified adapter in DSH via [pi2dsh](https://github.com/weijiafu14/pi2dsh); see the [verified dsh-TUI and Web MCP guide](https://github.com/weijiafu14/pi2dsh/tree/main/examples/tui-mcp).
|
|
28
|
+
|
|
27
29
|
## What happens on first run
|
|
28
30
|
|
|
29
31
|
The adapter reads standard MCP files automatically. No extra setup needed if you already have them.
|
|
@@ -145,22 +147,43 @@ A Pi package can ship MCP servers for the installed adapter without requiring a
|
|
|
145
147
|
An extension can register MCP servers with the installed adapter at runtime, for example a plugin host that discovers plugins after load:
|
|
146
148
|
|
|
147
149
|
```ts
|
|
148
|
-
|
|
150
|
+
const MCP_RUNTIME_REGISTER_EVENT = "pi-mcp-adapter:runtime-register:v1";
|
|
151
|
+
type RuntimeRegistrationRequest = {
|
|
152
|
+
version: 1;
|
|
153
|
+
name: string;
|
|
154
|
+
definition: { url: string };
|
|
155
|
+
result?:
|
|
156
|
+
| { ok: true; registration: { dispose(): Promise<void> } }
|
|
157
|
+
| { ok: false; error: Error };
|
|
158
|
+
};
|
|
149
159
|
|
|
150
160
|
export default function pluginHost(pi) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
let registration: { dispose(): Promise<void> } | undefined;
|
|
162
|
+
|
|
163
|
+
pi.on("session_start", () => {
|
|
164
|
+
if (registration) return;
|
|
165
|
+
const request: RuntimeRegistrationRequest = {
|
|
166
|
+
version: 1,
|
|
167
|
+
name: "acme__docs",
|
|
168
|
+
definition: { url: "https://mcp.example.com/mcp" },
|
|
169
|
+
};
|
|
170
|
+
pi.events.emit(MCP_RUNTIME_REGISTER_EVENT, request);
|
|
171
|
+
if (!request.result) throw new Error("pi-mcp-adapter is not installed");
|
|
172
|
+
if (!request.result.ok) throw request.result.error;
|
|
173
|
+
registration = request.result.registration;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
pi.on("session_shutdown", async () => {
|
|
177
|
+
const current = registration;
|
|
178
|
+
registration = undefined;
|
|
179
|
+
await current?.dispose();
|
|
157
180
|
});
|
|
158
|
-
// Later, when the plugin is uninstalled:
|
|
159
|
-
await registration.dispose();
|
|
160
181
|
}
|
|
161
182
|
```
|
|
162
183
|
|
|
163
|
-
|
|
184
|
+
Cross-extension registration uses Pi's shared event bus and does not require a runtime import from `pi-mcp-adapter`. Emit during `session_start` or later so the adapter listener is installed. The adapter writes `request.result` synchronously; the first adapter listener to respond wins.
|
|
185
|
+
|
|
186
|
+
Runtime registrations are session scoped and never written to config files. Duplicate server names fail closed against configured servers and other registrations. Registered servers use the normal lazy connection, OAuth, approval, and shutdown behavior, but they are proxy-tool-only and their tools become visible at the next tool sync. To change a definition, dispose the registration and register again.
|
|
164
187
|
|
|
165
188
|
### SDK configuration
|
|
166
189
|
|
|
@@ -383,6 +406,8 @@ When any enabled server uses `eager` or `keep-alive`, initialization also starts
|
|
|
383
406
|
| `oauthDir` | Legacy OAuth `tokens.json` import directory for this MCP config. Relative paths resolve from the active project cwd. `MCP_OAUTH_DIR` still wins when set. Persistent OAuth credentials are stored in the OS credential store, not this directory. |
|
|
384
407
|
| `mcpServers.<name>.oauth.authorizationParams` | Extra authorization URL parameters for provider-specific OAuth extensions. Flow-owned parameters such as `client_id`, `redirect_uri`, `scope`, `state`, `code_challenge`, `response_type`, and `resource` cannot be overridden. |
|
|
385
408
|
| `directTools` | Global default for all servers (default: false). Per-server overrides this. |
|
|
409
|
+
| `strictDirectToolArguments` | Validate direct-tool inputs against their advertised schemas and recover one JSON string layer for object and array properties (default: false). |
|
|
410
|
+
| `directToolResultDetails` | Direct-tool result details: `"lean"` (default) or `"bounded"` to retain the guarded raw MCP result. |
|
|
386
411
|
| `warnOnLargeDirectTools` | Show the advisory when 75 or more direct tools resolve (default: `true`). Set to `false` to suppress only this advisory. |
|
|
387
412
|
| `freezeDirectTools` | Keep direct-tool registration stable after the initial sync so automatic reconnects and list-change notifications do not rebuild the system prompt. Use `mcp({ connect: "server" })` or `/mcp reconnect <server>` to refresh deliberately. Default: false. |
|
|
388
413
|
| `scriptMode` | Register the MCP-only `mcpScript` plain-JavaScript tool (default: true). Set to `false` to hide it. |
|
|
@@ -438,7 +463,7 @@ Oversized MCP tool/resource results are guarded by default so a single huge resp
|
|
|
438
463
|
- Inline text output is capped at **50 KiB / 2,000 lines** (matching Pi's built-in `bash` guard). Larger output is truncated to a head preview and the full text is saved to a temp file whose path is included in the result, so the agent can `read`/`grep` it.
|
|
439
464
|
- **Image content blocks pass through unchanged** — only text output is guarded. Images are delivered to the provider as native image content.
|
|
440
465
|
- Binary resource blobs up to **10 MiB** are decoded to private temp files and replaced with file references. Each session is limited to **100 MiB** and **10,000 files**. The files are removed at session teardown.
|
|
441
|
-
- In proxy mode, `details.mcpResult` is kept raw when its JSON is **≤ 16 KiB**; larger results are replaced with a compact summary (block counts, sizes, key previews) and the raw JSON is saved to a temp file. Direct tools keep
|
|
466
|
+
- In proxy mode, `details.mcpResult` is kept raw when its JSON is **≤ 16 KiB**; larger results are replaced with a compact summary (block counts, sizes, key previews) and the raw JSON is saved to a temp file. Direct tools keep lean details unless `settings.directToolResultDetails` is set to `"bounded"`, which applies the same guarded `mcpResult` limit.
|
|
442
467
|
|
|
443
468
|
Tune the text and details limits with the object form:
|
|
444
469
|
|
|
@@ -592,6 +617,10 @@ Each direct tool costs ~150-300 tokens in the system prompt (name + description
|
|
|
592
617
|
|
|
593
618
|
Direct tools register from the metadata cache in the Pi agent dir (`~/.pi/agent/mcp-cache.json` by default, or `$PI_CODING_AGENT_DIR/mcp-cache.json` when set), so no server connections are needed at startup. On the first session after adding `directTools` to a new server, the cache won't exist yet — tools fall back to proxy-only while the cache populates, then the extension hot-loads the refreshed direct tools into the current session. Servers that advertise MCP list-change notifications refresh the current session when their tool or resource list changes. On Pi versions that expose `pi.unregisterTool()`, stale direct tools are removed from the registry during refresh; older Pi versions still deactivate them from the active tool set. To force a refresh: `/mcp reconnect <server>`.
|
|
594
619
|
|
|
620
|
+
Models sometimes encode an object or array argument as a JSON string. Set `settings.strictDirectToolArguments` to `true` to recover one such layer for schema-declared object and array properties, then validate the complete input against the advertised schema before execution.
|
|
621
|
+
|
|
622
|
+
Set `settings.directToolResultDetails` to `"bounded"` when an extension needs structured MCP result fields in Pi's direct-tool result details. The same output guard limits apply. Small leading structured fields stay available, while large fields receive bounded summaries and the complete guarded result follows the output guard's spill-file policy. The default `"lean"` mode keeps the existing server and tool metadata only.
|
|
623
|
+
|
|
595
624
|
If prompt-cache stability matters more than automatic direct-tool hot-loading, set `settings.freezeDirectTools` to `true`. The initial direct-tool sync still runs, but later automatic reconnects, lazy-connects, and list-change notifications keep the registered tool surface unchanged. Deliberate refreshes through `mcp({ connect: "server" })` or `/mcp reconnect <server>` still update direct tools.
|
|
596
625
|
|
|
597
626
|
When you change direct-tool toggles in `/mcp`, the extension updates direct tool registration in the current session. Broader setup writes from `/mcp setup` still use Pi's normal reload flow because they can add or restructure MCP config files.
|
|
@@ -730,9 +759,9 @@ Keys match a tool's original name, prefixed name, or a glob (`*` applies to ever
|
|
|
730
759
|
|
|
731
760
|
When `includeSchemas` is enabled, search and describe render common JSON Schema parameters as compact TypeScript shapes like `{ query: string; limit?: number; }`, with the older schema formatter retained as a fallback for unsupported schemas.
|
|
732
761
|
|
|
733
|
-
For HTTP servers, failed connects run a one-request shape probe that can turn opaque transport errors into setup hints such as `endpoint returned HTML (200) — this URL does not appear to speak MCP`. Healthy connections are not probed.
|
|
762
|
+
For HTTP servers, Pi reports HTTP 503 as temporary unavailability and does not add another immediate retry loop. Keep-alive servers keep cached metadata available and retry after 30 seconds, backing off to 5 minutes. Other failed connects run a one-request shape probe that can turn opaque transport errors into setup hints such as `endpoint returned HTML (200) — this URL does not appear to speak MCP`. Healthy connections are not probed.
|
|
734
763
|
|
|
735
|
-
Servers that provide usage guidance via the MCP `instructions` field surface it
|
|
764
|
+
Servers that provide usage guidance via the MCP `instructions` field surface it through discovery paths: `mcp({ server: "name" })` includes a preview, and `mcp({ instructions: "name" })` returns the full text. Instructions are captured at connect time and cached alongside tool metadata, so they stay available without a live connection.
|
|
736
765
|
|
|
737
766
|
## Commands
|
|
738
767
|
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
writeStarterProjectConfig,
|
|
18
18
|
} from "./config.ts";
|
|
19
19
|
import { markKeepAliveAfterConnect, notifyToolMetadataUpdated, updateMetadataCache, updateStatusBar, getFailureAgeSeconds, getFailureMessage, clearFailure, recordFailure } from "./init.ts";
|
|
20
|
+
import { isServerInActiveFailureBackoff } from "./failure-backoff.ts";
|
|
20
21
|
import { loadMetadataCache, reconstructPromptMetadata } from "./metadata-cache.ts";
|
|
21
22
|
import { buildToolMetadata } from "./tool-metadata.ts";
|
|
22
23
|
import { supportsOAuth, authenticate, removeAuth, type McpOAuthRuntime } from "./mcp-auth-flow.ts";
|
|
@@ -131,6 +132,7 @@ export async function showTools(state: McpExtensionState, ctx: ExtensionContext)
|
|
|
131
132
|
|
|
132
133
|
const allTools = [...state.toolMetadata.entries()]
|
|
133
134
|
.filter(([serverName]) => !isServerDisabled(state.config.mcpServers[serverName]))
|
|
135
|
+
.filter(([serverName]) => !isServerInActiveFailureBackoff(state, serverName))
|
|
134
136
|
.flatMap(([, metadata]) => metadata.map(m => m.name));
|
|
135
137
|
|
|
136
138
|
if (allTools.length === 0) {
|
|
@@ -196,9 +198,9 @@ export async function reconnectServer(
|
|
|
196
198
|
state.serverInstructions.delete(name);
|
|
197
199
|
}
|
|
198
200
|
updateMetadataCache(state, name);
|
|
199
|
-
|
|
201
|
+
const restored = clearFailure(state, name, "command-reconnect");
|
|
202
|
+
if (!restored) notifyToolMetadataUpdated(state, name, "command-reconnect");
|
|
200
203
|
markKeepAliveAfterConnect(state, name);
|
|
201
|
-
clearFailure(state, name);
|
|
202
204
|
|
|
203
205
|
if (ui) {
|
|
204
206
|
ui.notify(
|
|
@@ -42,6 +42,16 @@ export const KNOWN_SERVER_PRESETS: readonly KnownServerPreset[] = [
|
|
|
42
42
|
summary: "Look up current library documentation and examples.",
|
|
43
43
|
entry: { url: "https://mcp.context7.com/mcp", protocolVersion: "auto" },
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
id: "parallel-search",
|
|
47
|
+
name: "Parallel Search",
|
|
48
|
+
summary: "Search the web and fetch pages without an API key.",
|
|
49
|
+
entry: {
|
|
50
|
+
url: "https://search.parallel.ai/mcp",
|
|
51
|
+
protocolVersion: "auto",
|
|
52
|
+
directTools: true,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
45
55
|
{
|
|
46
56
|
id: "notion",
|
|
47
57
|
name: "Notion",
|
|
@@ -190,6 +200,7 @@ export function getConfigDiscoveryPaths(overridePath?: string, cwd = process.cwd
|
|
|
190
200
|
}
|
|
191
201
|
|
|
192
202
|
export function findAvailableImportConfigs(cwd = process.cwd()): DiscoveredImportConfig[] {
|
|
203
|
+
if (isExclusiveConfigMode()) return [];
|
|
193
204
|
const discovered: DiscoveredImportConfig[] = [];
|
|
194
205
|
|
|
195
206
|
for (const importKind of Object.keys(IMPORT_PATHS) as ImportKind[]) {
|
|
@@ -235,8 +246,11 @@ export function getMcpDiscoverySummary(
|
|
|
235
246
|
const sources = getConfigSourceSummaries(sourceSpecs);
|
|
236
247
|
const includeHostConfigs = options.includeHostConfigs !== false;
|
|
237
248
|
|
|
249
|
+
const importKinds = isExclusiveConfigMode()
|
|
250
|
+
? (readValidatedConfig(getEffectivePiGlobalConfigPath(overridePath), "MCP exclusive config")?.imports ?? [])
|
|
251
|
+
: (Object.keys(IMPORT_PATHS) as ImportKind[]);
|
|
238
252
|
const imports = includeHostConfigs
|
|
239
|
-
?
|
|
253
|
+
? importKinds
|
|
240
254
|
.map((kind) => {
|
|
241
255
|
const imported = loadImportedConfig(kind, cwd, `Failed to inspect imported MCP config from ${kind}:`);
|
|
242
256
|
if (!imported) return null;
|
|
@@ -248,10 +262,14 @@ export function getMcpDiscoverySummary(
|
|
|
248
262
|
})
|
|
249
263
|
.filter((value): value is ImportConfigSummary => value !== null)
|
|
250
264
|
: [];
|
|
251
|
-
const hostConfigDiscovery =
|
|
265
|
+
const hostConfigDiscovery = isExclusiveConfigMode()
|
|
266
|
+
? "off"
|
|
267
|
+
: getConfiguredHostConfigDiscovery(overridePath, cwd);
|
|
252
268
|
const hostConfigs = imports.map((entry) => ({ ...entry, active: hostConfigDiscovery === "on" }));
|
|
253
269
|
const settings = getMergedSettings(overridePath, cwd);
|
|
254
|
-
const agentPlugins =
|
|
270
|
+
const agentPlugins = isExclusiveConfigMode()
|
|
271
|
+
? []
|
|
272
|
+
: getAgentPluginSummaries(settings?.agentPluginPaths, cwd);
|
|
255
273
|
const totalServerCount = sources.reduce((sum, source) => sum + source.serverCount, 0) + agentPlugins.reduce((sum, plugin) => sum + plugin.serverCount, 0);
|
|
256
274
|
const hasSharedServers = sources.some((source) => source.kind === "shared" && source.serverCount > 0) || agentPlugins.some(plugin => plugin.serverCount > 0);
|
|
257
275
|
const hasPiOwnedServers = sources.some((source) => source.kind === "pi" && source.serverCount > 0);
|
|
@@ -297,7 +315,7 @@ export function loadMcpConfig(overridePath?: string, cwd = process.cwd()): McpCo
|
|
|
297
315
|
// Host files are a lower-precedence fallback. This ordering means an opt-in
|
|
298
316
|
// discovery cannot override a shared or Pi-owned definition, and all normal
|
|
299
317
|
// URL-bound credential stripping remains in mergeServerMaps.
|
|
300
|
-
let config: McpConfig = hostConfigDiscovery === "on"
|
|
318
|
+
let config: McpConfig = !isExclusiveConfigMode() && hostConfigDiscovery === "on"
|
|
301
319
|
? loadDiscoveredHostConfigs(cwd)
|
|
302
320
|
: { mcpServers: {} };
|
|
303
321
|
|
|
@@ -307,6 +325,8 @@ export function loadMcpConfig(overridePath?: string, cwd = process.cwd()): McpCo
|
|
|
307
325
|
config = mergeConfigs(config, expandImports(loaded, cwd));
|
|
308
326
|
}
|
|
309
327
|
|
|
328
|
+
if (isExclusiveConfigMode()) return config;
|
|
329
|
+
|
|
310
330
|
const packageConfig = loadPackageMcpConfigs(cwd);
|
|
311
331
|
const pluginConfig = loadAgentPluginConfigs(config.settings?.agentPluginPaths, cwd);
|
|
312
332
|
const packageServers = Object.fromEntries(
|
|
@@ -392,11 +412,23 @@ function getConfigConflicts(
|
|
|
392
412
|
}
|
|
393
413
|
|
|
394
414
|
function getConfigSources(overridePath?: string, cwd = process.cwd()): ConfigSourceSpec[] {
|
|
395
|
-
const userPath =
|
|
415
|
+
const userPath = getEffectivePiGlobalConfigPath(overridePath);
|
|
396
416
|
const projectPath = getProjectConfigPath(cwd);
|
|
397
417
|
const projectPiPath = getProjectPiConfigPath(cwd);
|
|
398
418
|
const sources: ConfigSourceSpec[] = [];
|
|
399
419
|
|
|
420
|
+
if (isExclusiveConfigMode()) {
|
|
421
|
+
return [{
|
|
422
|
+
id: "pi-global",
|
|
423
|
+
label: "Pi exclusive config",
|
|
424
|
+
readPath: userPath,
|
|
425
|
+
writePath: userPath,
|
|
426
|
+
kind: "user",
|
|
427
|
+
shared: false,
|
|
428
|
+
scope: "global",
|
|
429
|
+
}];
|
|
430
|
+
}
|
|
431
|
+
|
|
400
432
|
if (GENERIC_GLOBAL_CONFIG_PATH !== userPath) {
|
|
401
433
|
sources.push({
|
|
402
434
|
id: "shared-global",
|
|
@@ -461,6 +493,14 @@ function getConfigSources(overridePath?: string, cwd = process.cwd()): ConfigSou
|
|
|
461
493
|
return sources;
|
|
462
494
|
}
|
|
463
495
|
|
|
496
|
+
function isExclusiveConfigMode(): boolean {
|
|
497
|
+
return process.env.PI_MCP_CONFIG_MODE?.trim().toLowerCase() === "exclusive";
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function getEffectivePiGlobalConfigPath(overridePath?: string): string {
|
|
501
|
+
return getPiGlobalConfigPath(isExclusiveConfigMode() ? undefined : overridePath);
|
|
502
|
+
}
|
|
503
|
+
|
|
464
504
|
function mergeConfigs(base: McpConfig, next: McpConfig): McpConfig {
|
|
465
505
|
const imports = mergeImports(base.imports, next.imports);
|
|
466
506
|
const settings = next.settings ? { ...base.settings, ...next.settings } : base.settings;
|
|
@@ -15,16 +15,16 @@ import { createToolSelectorCandidateIndex, formatToolName, getToolNameCandidates
|
|
|
15
15
|
import { isUiToolVisibleToModel } from "./ui-tool-visibility.ts";
|
|
16
16
|
import { resourceNameToToolName } from "./resource-tools.ts";
|
|
17
17
|
import { authenticate, supportsOAuth } from "./mcp-auth-flow.ts";
|
|
18
|
-
import { formatAuthRequiredMessage, normalizeToolArguments, resolveServerUrl
|
|
18
|
+
import { formatAuthRequiredMessage, normalizeToolArguments, resolveServerUrl } from "./utils.ts";
|
|
19
19
|
import { SessionRecoveryAuthRequiredError, withSessionRecovery } from "./session-recovery.ts";
|
|
20
20
|
import { combineAbortSignals, isAbortError } from "./runtime-owner.ts";
|
|
21
21
|
import { ensureToolCallApproved } from "./tool-approval.ts";
|
|
22
|
+
import { Check, Errors } from "typebox/value";
|
|
22
23
|
|
|
23
24
|
type ClientCallToolResult = Awaited<ReturnType<Client["callTool"]>>;
|
|
24
25
|
type ClientReadResourceResult = Awaited<ReturnType<Client["readResource"]>>;
|
|
25
26
|
|
|
26
27
|
const BUILTIN_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "mcp"]);
|
|
27
|
-
const INSTRUCTIONS_SNIPPET_LENGTH = 150;
|
|
28
28
|
export const DIRECT_TOOLS_ADVISORY_THRESHOLD = 75;
|
|
29
29
|
|
|
30
30
|
type DirectAutoAuthResult =
|
|
@@ -32,6 +32,58 @@ type DirectAutoAuthResult =
|
|
|
32
32
|
| { status: "success" }
|
|
33
33
|
| { status: "failed"; message: string };
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Recover one model-emitted JSON layer for schema-declared object and array
|
|
37
|
+
* properties, then validate the complete input against the same schema.
|
|
38
|
+
*/
|
|
39
|
+
export function prepareDirectToolArguments(inputSchema: unknown, args: unknown): unknown {
|
|
40
|
+
if (!inputSchema || typeof inputSchema !== "object" || Array.isArray(inputSchema)) return args;
|
|
41
|
+
const schema = inputSchema as Record<string, unknown>;
|
|
42
|
+
if (schema.type !== "object") return args;
|
|
43
|
+
const input = args && typeof args === "object" && !Array.isArray(args)
|
|
44
|
+
? args as Record<string, unknown>
|
|
45
|
+
: null;
|
|
46
|
+
const properties = schema.properties;
|
|
47
|
+
let prepared: Record<string, unknown> | undefined;
|
|
48
|
+
|
|
49
|
+
if (input && properties && typeof properties === "object" && !Array.isArray(properties)) {
|
|
50
|
+
for (const [name, propertySchema] of Object.entries(properties)) {
|
|
51
|
+
if (!Object.hasOwn(input, name) || typeof input[name] !== "string"
|
|
52
|
+
|| !propertySchema || typeof propertySchema !== "object" || Array.isArray(propertySchema)) continue;
|
|
53
|
+
const expectedType = (propertySchema as Record<string, unknown>).type;
|
|
54
|
+
if (expectedType !== "object" && expectedType !== "array") continue;
|
|
55
|
+
try {
|
|
56
|
+
const parsed: unknown = JSON.parse(input[name] as string);
|
|
57
|
+
const matches = expectedType === "array"
|
|
58
|
+
? Array.isArray(parsed)
|
|
59
|
+
: parsed !== null && typeof parsed === "object" && !Array.isArray(parsed);
|
|
60
|
+
if (matches) {
|
|
61
|
+
prepared ??= { ...input };
|
|
62
|
+
prepared[name] = parsed;
|
|
63
|
+
}
|
|
64
|
+
} catch {
|
|
65
|
+
// Validation below reports malformed or shape-incompatible values.
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const candidate = prepared ?? args;
|
|
71
|
+
if (!Check(inputSchema as never, candidate)) {
|
|
72
|
+
const errors = Errors(inputSchema as never, candidate);
|
|
73
|
+
const issues = errors.slice(0, 8).map((error) => ({
|
|
74
|
+
instancePath: error.instancePath || "/",
|
|
75
|
+
keyword: error.keyword,
|
|
76
|
+
message: error.message,
|
|
77
|
+
}));
|
|
78
|
+
throw new TypeError(`MCP direct tool arguments do not match the advertised input schema: ${JSON.stringify({
|
|
79
|
+
issues,
|
|
80
|
+
total: errors.length,
|
|
81
|
+
truncated: errors.length > issues.length,
|
|
82
|
+
})}`);
|
|
83
|
+
}
|
|
84
|
+
return candidate;
|
|
85
|
+
}
|
|
86
|
+
|
|
35
87
|
function getDirectAuthRequiredMessage(
|
|
36
88
|
state: McpExtensionState,
|
|
37
89
|
serverName: string,
|
|
@@ -117,6 +169,8 @@ export function resolveDirectTools(
|
|
|
117
169
|
cache: MetadataCache | null,
|
|
118
170
|
prefix: ToolPrefix,
|
|
119
171
|
envOverride?: string[],
|
|
172
|
+
unavailableServers: ReadonlySet<string> = new Set(),
|
|
173
|
+
reservedNames?: Set<string>,
|
|
120
174
|
): DirectToolSpec[] {
|
|
121
175
|
const specs: DirectToolSpec[] = [];
|
|
122
176
|
if (!cache) return specs;
|
|
@@ -224,82 +278,33 @@ export function resolveDirectTools(
|
|
|
224
278
|
}
|
|
225
279
|
}
|
|
226
280
|
|
|
227
|
-
|
|
228
|
-
|
|
281
|
+
for (const spec of specs) reservedNames?.add(spec.prefixedName);
|
|
282
|
+
|
|
283
|
+
const emittedSpecs = unavailableServers.size === 0
|
|
284
|
+
? specs
|
|
285
|
+
: specs.filter((spec) => !unavailableServers.has(spec.serverName));
|
|
286
|
+
|
|
287
|
+
if (config.settings?.warnOnLargeDirectTools !== false && emittedSpecs.length >= DIRECT_TOOLS_ADVISORY_THRESHOLD) {
|
|
288
|
+
console.warn(`MCP: ${emittedSpecs.length} direct tools resolved. Each direct tool adds prompt context; README guidance recommends targeted sets of 5-20 tools and using the proxy or an explicit string[] when 75+ direct tools would be registered. Set settings.warnOnLargeDirectTools to false to hide this advisory.`);
|
|
229
289
|
}
|
|
230
290
|
|
|
231
|
-
return
|
|
291
|
+
return emittedSpecs;
|
|
232
292
|
}
|
|
233
293
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
)
|
|
239
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Pure function of config: the description must stay byte-stable across
|
|
296
|
+
* runtime metadata changes (tool counts, instructions, connection state) so
|
|
297
|
+
* re-registering the proxy tool never rewrites the cached prompt prefix.
|
|
298
|
+
* Live counts/status belong to `mcp({ })`, full instructions to
|
|
299
|
+
* `mcp({ instructions })`.
|
|
300
|
+
*/
|
|
301
|
+
export function buildProxyDescription(config: McpConfig): string {
|
|
240
302
|
let desc = `MCP gateway — server status, tool search/describe, auth, and single MCP tool calls. When one request needs several MCP calls with logic between them, use mcpScript. Non-MCP Pi tools should be called directly, not through mcp.\n`;
|
|
241
303
|
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (directByServer.size > 0) {
|
|
247
|
-
const parts = [...directByServer.entries()].map(
|
|
248
|
-
([server, count]) => `${server} (${count})`,
|
|
249
|
-
);
|
|
250
|
-
desc += `\nDirect tools available (call as normal tools): ${parts.join(", ")}\n`;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const serverSummaries: string[] = [];
|
|
254
|
-
for (const serverName of Object.keys(config.mcpServers)) {
|
|
255
|
-
const definition = config.mcpServers[serverName];
|
|
256
|
-
if (!definition || isServerDisabled(definition)) continue;
|
|
257
|
-
const cachedEntry = cache?.servers?.[serverName];
|
|
258
|
-
const entry = cachedEntry && isServerCacheValid(cachedEntry, definition) ? cachedEntry : undefined;
|
|
259
|
-
const effectivePrefix = resolveToolPrefix(definition, prefix);
|
|
260
|
-
const hasToolFilters =
|
|
261
|
-
(Array.isArray(definition.includeTools) && definition.includeTools.length > 0) ||
|
|
262
|
-
(Array.isArray(definition.excludeTools) && definition.excludeTools.length > 0);
|
|
263
|
-
const selectorCandidateIndex = hasToolFilters && cache ? (() => {
|
|
264
|
-
const candidates = new Set<string>();
|
|
265
|
-
for (const [otherServerName, otherDefinition] of Object.entries(config.mcpServers)) {
|
|
266
|
-
const otherEntry = cache.servers[otherServerName];
|
|
267
|
-
if (!otherEntry || !isServerCacheValid(otherEntry, otherDefinition) || isServerDisabled(otherDefinition)) continue;
|
|
268
|
-
const otherPrefix = resolveToolPrefix(otherDefinition, prefix);
|
|
269
|
-
for (const otherTool of otherEntry.tools ?? []) {
|
|
270
|
-
if (!isUiToolVisibleToModel(otherTool.uiVisibility)) continue;
|
|
271
|
-
for (const candidate of getToolNameCandidates(otherTool.name, otherServerName, otherPrefix, false)) candidates.add(candidate);
|
|
272
|
-
}
|
|
273
|
-
if (otherDefinition.exposeResources !== false) {
|
|
274
|
-
for (const resource of otherEntry.resources ?? []) {
|
|
275
|
-
const baseName = `read_${resourceNameToToolName(resource.name)}`;
|
|
276
|
-
for (const candidate of getToolNameCandidates(baseName, otherServerName, otherPrefix, false)) candidates.add(candidate);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return createToolSelectorCandidateIndex(candidates);
|
|
281
|
-
})() : undefined;
|
|
282
|
-
const toolCount = (entry?.tools ?? []).filter(
|
|
283
|
-
(tool) => isUiToolVisibleToModel(tool.uiVisibility)
|
|
284
|
-
&& isToolAllowed(tool.name, serverName, effectivePrefix, definition.includeTools, definition.excludeTools, selectorCandidateIndex),
|
|
285
|
-
).length;
|
|
286
|
-
const resourceCount = definition?.exposeResources !== false
|
|
287
|
-
? (entry?.resources ?? []).filter((resource) => {
|
|
288
|
-
const baseName = `read_${resourceNameToToolName(resource.name)}`;
|
|
289
|
-
return isToolAllowed(baseName, serverName, effectivePrefix, definition.includeTools, definition.excludeTools, selectorCandidateIndex);
|
|
290
|
-
}).length
|
|
291
|
-
: 0;
|
|
292
|
-
const totalItems = toolCount + resourceCount;
|
|
293
|
-
if (totalItems === 0) continue;
|
|
294
|
-
const directCount = directByServer.get(serverName) ?? 0;
|
|
295
|
-
const proxyCount = totalItems - directCount;
|
|
296
|
-
if (proxyCount > 0) {
|
|
297
|
-
serverSummaries.push(`${serverName} (${proxyCount} tools)`);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (serverSummaries.length > 0) {
|
|
302
|
-
desc += `\nServers: ${serverSummaries.join(", ")}\n`;
|
|
304
|
+
const serverNames = Object.keys(config.mcpServers)
|
|
305
|
+
.filter((serverName) => !isServerDisabled(config.mcpServers[serverName]));
|
|
306
|
+
if (serverNames.length > 0) {
|
|
307
|
+
desc += `\nServers: ${serverNames.join(", ")}\n`;
|
|
303
308
|
}
|
|
304
309
|
|
|
305
310
|
const disabledServers = Object.entries(config.mcpServers)
|
|
@@ -309,22 +314,8 @@ export function buildProxyDescription(
|
|
|
309
314
|
desc += `\nDisabled servers (enable with /mcp enable <server> and /reload): ${disabledServers.join(", ")}\n`;
|
|
310
315
|
}
|
|
311
316
|
|
|
312
|
-
const instructionSummaries: string[] = [];
|
|
313
|
-
for (const serverName of Object.keys(config.mcpServers)) {
|
|
314
|
-
if (isServerDisabled(config.mcpServers[serverName])) continue;
|
|
315
|
-
const definition = config.mcpServers[serverName];
|
|
316
|
-
const entry = definition && cache?.servers?.[serverName];
|
|
317
|
-
const instructions = entry && definition && isServerCacheValid(entry, definition) ? entry.instructions : undefined;
|
|
318
|
-
if (!instructions) continue;
|
|
319
|
-
const snippet = truncateAtWord(instructions.replace(/\s+/g, " ").trim(), INSTRUCTIONS_SNIPPET_LENGTH);
|
|
320
|
-
instructionSummaries.push(` ${serverName}: ${snippet}`);
|
|
321
|
-
}
|
|
322
|
-
if (instructionSummaries.length > 0) {
|
|
323
|
-
desc += `\nServer instructions (truncated - full text via mcp({ instructions: "name" })):\n${instructionSummaries.join("\n")}\n`;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
317
|
desc += `\nUsage:\n`;
|
|
327
|
-
desc += ` mcp({ }) → Show server status\n`;
|
|
318
|
+
desc += ` mcp({ }) → Show server status and tool counts\n`;
|
|
328
319
|
desc += ` mcp({ server: "name" }) → List tools from server\n`;
|
|
329
320
|
desc += ` mcp({ search: "query" }) → Search MCP tools by name/description\n`;
|
|
330
321
|
desc += ` mcp({ describe: "tool_name" }) → Show tool details and parameters\n`;
|
|
@@ -498,7 +489,10 @@ export function createDirectToolExecutor(
|
|
|
498
489
|
(conn) => conn.client.readResource({ uri: spec.resourceUri! }, requestOptions),
|
|
499
490
|
);
|
|
500
491
|
const content = transformMcpResourceContents(result.contents ?? [], state.owner?.signal);
|
|
501
|
-
const guarded = await guardMcpOutput(content.length > 0 ? content : [{ type: "text" as const, text: "(empty resource)" }],
|
|
492
|
+
const guarded = await guardMcpOutput(content.length > 0 ? content : [{ type: "text" as const, text: "(empty resource)" }], {
|
|
493
|
+
...outputGuardOptions,
|
|
494
|
+
...(state.config.settings?.directToolResultDetails === "bounded" ? { rawMcpResult: result } : {}),
|
|
495
|
+
});
|
|
502
496
|
return {
|
|
503
497
|
content: guarded.content,
|
|
504
498
|
details: { server: spec.serverName, resourceUri: spec.resourceUri, ...guardedMcpDetails(guarded) },
|
|
@@ -539,7 +533,13 @@ export function createDirectToolExecutor(
|
|
|
539
533
|
const content = transformMcpContent(mcpContent, state.owner?.signal);
|
|
540
534
|
const outputContent = content.length > 0 ? content : [{ type: "text" as const, text: "(empty result)" }];
|
|
541
535
|
const schemaText = spec.inputSchema ? `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}` : "";
|
|
542
|
-
const guarded = await guardMcpOutput(outputContent, {
|
|
536
|
+
const guarded = await guardMcpOutput(outputContent, {
|
|
537
|
+
...outputGuardOptions,
|
|
538
|
+
prefix: "Error: ",
|
|
539
|
+
suffix: schemaText,
|
|
540
|
+
emptyTextFallback: "Tool execution failed",
|
|
541
|
+
...(state.config.settings?.directToolResultDetails === "bounded" ? { rawMcpResult: result } : {}),
|
|
542
|
+
});
|
|
543
543
|
return {
|
|
544
544
|
content: guarded.content,
|
|
545
545
|
details: { error: "tool_error", server: spec.serverName, ...guardedMcpDetails(guarded) },
|
|
@@ -550,7 +550,11 @@ export function createDirectToolExecutor(
|
|
|
550
550
|
const outputContent = content.length > 0 ? content : [{ type: "text" as const, text: "(empty result)" }];
|
|
551
551
|
if (hasUi) {
|
|
552
552
|
const uiSummary = summarizeUiSessionResult(uiSession);
|
|
553
|
-
const guarded = await guardMcpOutput(outputContent, {
|
|
553
|
+
const guarded = await guardMcpOutput(outputContent, {
|
|
554
|
+
...outputGuardOptions,
|
|
555
|
+
suffix: `\n\n${uiSummary.message}`,
|
|
556
|
+
...(state.config.settings?.directToolResultDetails === "bounded" ? { rawMcpResult: result } : {}),
|
|
557
|
+
});
|
|
554
558
|
return {
|
|
555
559
|
content: guarded.content,
|
|
556
560
|
details: {
|
|
@@ -564,7 +568,10 @@ export function createDirectToolExecutor(
|
|
|
564
568
|
};
|
|
565
569
|
}
|
|
566
570
|
|
|
567
|
-
const guarded = await guardMcpOutput(outputContent, {
|
|
571
|
+
const guarded = await guardMcpOutput(outputContent, {
|
|
572
|
+
...outputGuardOptions,
|
|
573
|
+
...(state.config.settings?.directToolResultDetails === "bounded" ? { rawMcpResult: result } : {}),
|
|
574
|
+
});
|
|
568
575
|
return {
|
|
569
576
|
content: guarded.content,
|
|
570
577
|
details: { server: spec.serverName, tool: spec.originalName, ...guardedMcpDetails(guarded) },
|
|
@@ -590,12 +597,16 @@ export function createDirectToolExecutor(
|
|
|
590
597
|
};
|
|
591
598
|
}
|
|
592
599
|
const message = error instanceof Error ? error.message : String(error);
|
|
600
|
+
const aborted = isAbortError(error, ownedSignal);
|
|
601
|
+
if (!aborted) {
|
|
602
|
+
await state.manager.close(spec.serverName).catch(() => {});
|
|
603
|
+
}
|
|
593
604
|
uiSession?.sendToolCancelled(message);
|
|
594
605
|
const schemaText = spec.inputSchema ? `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}` : "";
|
|
595
606
|
const guarded = await guardMcpOutput([{ type: "text" as const, text: message }], { ...outputGuardOptions, prefix: "Failed to call tool: ", suffix: schemaText });
|
|
596
607
|
return {
|
|
597
608
|
content: guarded.content,
|
|
598
|
-
details: { error:
|
|
609
|
+
details: { error: aborted ? "aborted" : "call_failed", server: spec.serverName, ...guardedMcpDetails(guarded) },
|
|
599
610
|
};
|
|
600
611
|
} finally {
|
|
601
612
|
if (uiSession?.reused) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function getConfigDirName(): string;
|
|
2
|
+
export declare function getAgentDir(): string;
|
|
3
|
+
export declare function getAgentPath(...segments: string[]): string;
|
|
4
|
+
export declare function getAppName(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Home page the host declares for itself, via `piConfig.clientUri` in the same
|
|
7
|
+
* manifest that carries `piConfig.name`. Only the distribution knows its own
|
|
8
|
+
* URL, so this is the one place it can come from without guessing.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getAppClientUri(): string | undefined;
|