@herbertgao/pi-extensions 2026.8.11 → 2026.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -10
- package/{node_modules/@herbertgao/pi-inline-skills/LICENSE → THIRD_PARTY_NOTICES.md} +15 -1
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
- package/node_modules/@czottmann/pi-automode/README.md +5 -3
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
- package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
- package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
- package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
- package/node_modules/@czottmann/pi-automode/package.json +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
- package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
- package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
- package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +6 -6
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
- package/node_modules/@tifan/pi-handoff/package.json +43 -0
- package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
- package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
- package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
- package/node_modules/@tifan/pi-recap/package.json +42 -0
- package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
- package/node_modules/@tifan/pi-rename/package.json +47 -0
- package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
- package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
- package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
- package/node_modules/pi-lens/CHANGELOG.md +96 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
- package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
- package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
- package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
- package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
- package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
- package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
- package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
- package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
- package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
- package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
- package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
- package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
- package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
- package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
- package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
- package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
- package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
- package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
- package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
- package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
- package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
- package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
- package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
- package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
- package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
- package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
- package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
- package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
- package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
- package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
- package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
- package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
- package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
- package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
- package/node_modules/pi-lens/dist/i18n.js +13 -5
- package/node_modules/pi-lens/dist/index.js +10797 -8627
- package/node_modules/pi-lens/dist/mcp/server.js +3 -1
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
- package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
- package/node_modules/pi-lens/package.json +160 -156
- package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
- package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +34 -0
- package/node_modules/pi-mcp-adapter/README.md +42 -13
- package/node_modules/pi-mcp-adapter/commands.ts +4 -2
- package/node_modules/pi-mcp-adapter/config.ts +35 -5
- package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
- package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +1077 -0
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
- package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
- package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
- package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
- package/node_modules/pi-mcp-adapter/index.ts +204 -82
- package/node_modules/pi-mcp-adapter/init.ts +36 -29
- package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
- package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
- package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
- package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
- package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
- package/node_modules/pi-mcp-adapter/package.json +24 -6
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
- package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
- package/node_modules/pi-mcp-adapter/state.ts +1 -3
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
- package/node_modules/pi-mcp-adapter/types.ts +48 -1
- package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
- package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
- package/node_modules/pi-mcp-adapter/utils.ts +21 -19
- package/node_modules/pi-web-access/CHANGELOG.md +26 -0
- package/node_modules/pi-web-access/README.md +71 -14
- package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
- package/node_modules/pi-web-access/credential-source.ts +6 -2
- package/node_modules/pi-web-access/curator-page.ts +5 -3
- package/node_modules/pi-web-access/curator-server.ts +2 -1
- package/node_modules/pi-web-access/extract.ts +89 -9
- package/node_modules/pi-web-access/fetch-params.ts +13 -0
- package/node_modules/pi-web-access/gemini-adc.ts +298 -0
- package/node_modules/pi-web-access/gemini-api.ts +59 -15
- package/node_modules/pi-web-access/gemini-search.ts +58 -18
- package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
- package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
- package/node_modules/pi-web-access/gemini-web.ts +9 -3
- package/node_modules/pi-web-access/github-api.ts +5 -4
- package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
- package/node_modules/pi-web-access/index.ts +403 -297
- package/node_modules/pi-web-access/kimi-search.ts +234 -0
- package/node_modules/pi-web-access/openai-search.ts +118 -21
- package/node_modules/pi-web-access/package.json +3 -2
- package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
- package/node_modules/pi-web-access/utils.ts +307 -1
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +40 -37
- package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
- package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
- package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
- package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
- package/node_modules/@herbertgao/pi-mermaid-open/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
- package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
- package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-recap/package.json +0 -55
- package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
- package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
- package/node_modules/@herbertgao/pi-rename/package.json +0 -63
- package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
- package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
- /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
- /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
|
@@ -38,7 +38,9 @@ function severityForDepth(depth) {
|
|
|
38
38
|
export function impact(graph, startKey, maxDepth = 3, minWeight = 0.1) {
|
|
39
39
|
const results = [];
|
|
40
40
|
const visited = new Set([startKey]);
|
|
41
|
-
const queue = [
|
|
41
|
+
const queue = [
|
|
42
|
+
{ key: startKey, depth: 0 },
|
|
43
|
+
];
|
|
42
44
|
// Build a weight lookup from edges for filtering
|
|
43
45
|
const edgeWeightMap = new Map();
|
|
44
46
|
for (const edge of graph.edges) {
|
|
@@ -63,7 +65,11 @@ export function impact(graph, startKey, maxDepth = 3, minWeight = 0.1) {
|
|
|
63
65
|
continue;
|
|
64
66
|
visited.add(callerKey);
|
|
65
67
|
const depth = item.depth + 1;
|
|
66
|
-
results.push({
|
|
68
|
+
results.push({
|
|
69
|
+
symbolKey: callerKey,
|
|
70
|
+
depth,
|
|
71
|
+
severity: severityForDepth(depth),
|
|
72
|
+
});
|
|
67
73
|
queue.push({ key: callerKey, depth });
|
|
68
74
|
}
|
|
69
75
|
}
|
|
@@ -101,10 +107,16 @@ export function formatImpact(results, projectRoot) {
|
|
|
101
107
|
return file ? `${name} (${file})` : name;
|
|
102
108
|
};
|
|
103
109
|
if (willBreak.length > 0) {
|
|
104
|
-
parts.push(willBreak
|
|
110
|
+
parts.push(willBreak
|
|
111
|
+
.slice(0, 3)
|
|
112
|
+
.map((r) => `${label(r)} ⚠ WillBreak`)
|
|
113
|
+
.join(", "));
|
|
105
114
|
}
|
|
106
115
|
if (mayBreak.length > 0) {
|
|
107
|
-
parts.push(mayBreak
|
|
116
|
+
parts.push(mayBreak
|
|
117
|
+
.slice(0, 2)
|
|
118
|
+
.map((r) => `${label(r)} MayBreak`)
|
|
119
|
+
.join(", "));
|
|
108
120
|
}
|
|
109
121
|
if (review.length > 0) {
|
|
110
122
|
parts.push(`${review.length} Review caller${review.length === 1 ? "" : "s"}`);
|
|
@@ -118,25 +130,106 @@ export function formatImpact(results, projectRoot) {
|
|
|
118
130
|
*/
|
|
119
131
|
const STDLIB_NAMES = new Set([
|
|
120
132
|
// JS/TS
|
|
121
|
-
"console",
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
133
|
+
"console",
|
|
134
|
+
"Math",
|
|
135
|
+
"Object",
|
|
136
|
+
"Array",
|
|
137
|
+
"String",
|
|
138
|
+
"Number",
|
|
139
|
+
"Boolean",
|
|
140
|
+
"Promise",
|
|
141
|
+
"Error",
|
|
142
|
+
"Map",
|
|
143
|
+
"Set",
|
|
144
|
+
"WeakMap",
|
|
145
|
+
"WeakSet",
|
|
146
|
+
"JSON",
|
|
147
|
+
"Date",
|
|
148
|
+
"RegExp",
|
|
149
|
+
"Symbol",
|
|
150
|
+
"BigInt",
|
|
151
|
+
"parseInt",
|
|
152
|
+
"parseFloat",
|
|
153
|
+
"isNaN",
|
|
154
|
+
"isFinite",
|
|
155
|
+
"setTimeout",
|
|
156
|
+
"clearTimeout",
|
|
157
|
+
"setInterval",
|
|
158
|
+
"clearInterval",
|
|
159
|
+
"fetch",
|
|
160
|
+
"URL",
|
|
161
|
+
"URLSearchParams",
|
|
162
|
+
"Buffer",
|
|
163
|
+
"process",
|
|
164
|
+
"require",
|
|
126
165
|
// Python
|
|
127
|
-
"print",
|
|
128
|
-
"
|
|
129
|
-
"
|
|
166
|
+
"print",
|
|
167
|
+
"len",
|
|
168
|
+
"range",
|
|
169
|
+
"list",
|
|
170
|
+
"dict",
|
|
171
|
+
"str",
|
|
172
|
+
"int",
|
|
173
|
+
"float",
|
|
174
|
+
"bool",
|
|
175
|
+
"open",
|
|
176
|
+
"isinstance",
|
|
177
|
+
"issubclass",
|
|
178
|
+
"type",
|
|
179
|
+
"super",
|
|
180
|
+
"hasattr",
|
|
181
|
+
"getattr",
|
|
182
|
+
"setattr",
|
|
183
|
+
"enumerate",
|
|
184
|
+
"zip",
|
|
185
|
+
"map",
|
|
186
|
+
"filter",
|
|
187
|
+
"sorted",
|
|
188
|
+
"reversed",
|
|
130
189
|
// Go
|
|
131
|
-
"fmt",
|
|
132
|
-
"
|
|
190
|
+
"fmt",
|
|
191
|
+
"log",
|
|
192
|
+
"os",
|
|
193
|
+
"io",
|
|
194
|
+
"err",
|
|
195
|
+
"make",
|
|
196
|
+
"append",
|
|
197
|
+
"cap",
|
|
198
|
+
"copy",
|
|
199
|
+
"close",
|
|
200
|
+
"delete",
|
|
201
|
+
"panic",
|
|
202
|
+
"recover",
|
|
203
|
+
"new",
|
|
133
204
|
// Rust
|
|
134
|
-
"eprintln",
|
|
135
|
-
"
|
|
205
|
+
"eprintln",
|
|
206
|
+
"eprint",
|
|
207
|
+
"vec",
|
|
208
|
+
"Some",
|
|
209
|
+
"None",
|
|
210
|
+
"Ok",
|
|
211
|
+
"Err",
|
|
212
|
+
"Box",
|
|
213
|
+
"Rc",
|
|
214
|
+
"Arc",
|
|
215
|
+
"Vec",
|
|
216
|
+
"HashMap",
|
|
217
|
+
"HashSet",
|
|
218
|
+
"format",
|
|
136
219
|
// Java/Kotlin
|
|
137
|
-
"System",
|
|
220
|
+
"System",
|
|
221
|
+
"toString",
|
|
222
|
+
"equals",
|
|
223
|
+
"hashCode",
|
|
224
|
+
"Objects",
|
|
138
225
|
// Generic
|
|
139
|
-
"this",
|
|
226
|
+
"this",
|
|
227
|
+
"self",
|
|
228
|
+
"nil",
|
|
229
|
+
"null",
|
|
230
|
+
"undefined",
|
|
231
|
+
"true",
|
|
232
|
+
"false",
|
|
140
233
|
]);
|
|
141
234
|
// ── Core resolution ────────────────────────────────────────────────────────────
|
|
142
235
|
/**
|
|
@@ -253,7 +346,9 @@ allRefs, inputCoverage) {
|
|
|
253
346
|
// Canonical graph identity is authoritative. Never recover a name by
|
|
254
347
|
// splitting an id: symbol ids contain kind and line components.
|
|
255
348
|
const callee = defIndex.byId.get(ref.targetId);
|
|
256
|
-
if (!callee ||
|
|
349
|
+
if (!callee ||
|
|
350
|
+
ref.resolution === "name-only" ||
|
|
351
|
+
ref.resolution === "unresolved") {
|
|
257
352
|
if (!hasInputCoverage) {
|
|
258
353
|
unresolvedRefs++;
|
|
259
354
|
coverage.unresolvedEvidence++;
|
|
@@ -271,7 +366,9 @@ allRefs, inputCoverage) {
|
|
|
271
366
|
// There is no typed/import evidence to select one definition, so retain
|
|
272
367
|
// every cross-file candidate and discount each edge. Picking [0] made
|
|
273
368
|
// graph iteration order decide which caller was reported.
|
|
274
|
-
const refName = ref.symbolName ??
|
|
369
|
+
const refName = ref.symbolName ??
|
|
370
|
+
parseSymbolKey(ref.symbolId, callerFile).symbolName ??
|
|
371
|
+
"";
|
|
275
372
|
if (STDLIB_NAMES.has(refName) || !refName) {
|
|
276
373
|
if (!hasInputCoverage)
|
|
277
374
|
coverage.unsupportedEvidence++;
|
|
@@ -287,7 +384,8 @@ allRefs, inputCoverage) {
|
|
|
287
384
|
}
|
|
288
385
|
const crossFileDefs = defs
|
|
289
386
|
.map((id) => defIndex.byId.get(id))
|
|
290
|
-
.filter((candidate) => candidate !== undefined &&
|
|
387
|
+
.filter((candidate) => candidate !== undefined &&
|
|
388
|
+
normalizeMapKey(candidate.filePath) !== callerFileKey);
|
|
291
389
|
if (crossFileDefs.length === 0) {
|
|
292
390
|
if (!hasInputCoverage)
|
|
293
391
|
coverage.unsupportedEvidence++;
|
|
@@ -295,10 +393,15 @@ allRefs, inputCoverage) {
|
|
|
295
393
|
}
|
|
296
394
|
const resolution = crossFileDefs.length === 1 ? "exact" : "name-only";
|
|
297
395
|
for (const callee of crossFileDefs) {
|
|
298
|
-
candidates.push({
|
|
396
|
+
candidates.push({
|
|
397
|
+
callee,
|
|
398
|
+
resolution,
|
|
399
|
+
candidateCount: crossFileDefs.length,
|
|
400
|
+
});
|
|
299
401
|
}
|
|
300
402
|
}
|
|
301
|
-
if (ref.evidenceKind &&
|
|
403
|
+
if (ref.evidenceKind &&
|
|
404
|
+
candidates.some(({ resolution }) => resolution === "name-only")) {
|
|
302
405
|
if (!hasInputCoverage) {
|
|
303
406
|
unresolvedRefs++;
|
|
304
407
|
coverage.unresolvedEvidence++;
|
|
@@ -331,9 +434,10 @@ allRefs, inputCoverage) {
|
|
|
331
434
|
const existing = edgeByPair.get(pairKey);
|
|
332
435
|
if (existing) {
|
|
333
436
|
existing.evidenceCount = (existing.evidenceCount ?? 1) + 1;
|
|
334
|
-
existing.evidenceKind =
|
|
335
|
-
|
|
336
|
-
|
|
437
|
+
existing.evidenceKind =
|
|
438
|
+
existing.evidenceKind === ref.evidenceKind
|
|
439
|
+
? existing.evidenceKind
|
|
440
|
+
: "mixed";
|
|
337
441
|
// Duplicate evidence is a property of the logical pair, not of
|
|
338
442
|
// whether the producer happened to tag the record. Keep the edge,
|
|
339
443
|
// coverage, and centrality views consistent for legacy refs too.
|
|
@@ -388,15 +492,20 @@ allRefs, inputCoverage) {
|
|
|
388
492
|
if (hasInputCoverage)
|
|
389
493
|
totalRefs = coverage.totalEvidence;
|
|
390
494
|
const languagesKnownComplete = Object.values(coverage.languages ?? {}).every((status) => status === "complete");
|
|
391
|
-
coverage.complete =
|
|
392
|
-
coverage.
|
|
393
|
-
|
|
495
|
+
coverage.complete =
|
|
496
|
+
coverage.complete &&
|
|
497
|
+
hasInputCoverage &&
|
|
498
|
+
coverage.unsupportedEvidence === 0 &&
|
|
499
|
+
languagesKnownComplete &&
|
|
500
|
+
(allSymbols.size > 0 || coverage.totalEvidence > 0);
|
|
394
501
|
return {
|
|
395
502
|
callees,
|
|
396
503
|
callers,
|
|
397
504
|
inDegree,
|
|
398
505
|
edges: [...edgeByPair.values()],
|
|
399
|
-
unresolvedRefs: hasInputCoverage
|
|
506
|
+
unresolvedRefs: hasInputCoverage
|
|
507
|
+
? coverage.unresolvedEvidence
|
|
508
|
+
: unresolvedRefs,
|
|
400
509
|
totalRefs,
|
|
401
510
|
coverage,
|
|
402
511
|
builtAt: new Date().toISOString(),
|
|
@@ -433,7 +542,10 @@ export function saveCallGraph(cwd, graph, identity) {
|
|
|
433
542
|
coverage: graph.coverage,
|
|
434
543
|
};
|
|
435
544
|
writeFileAtomic(cacheFile, JSON.stringify(persisted));
|
|
436
|
-
writeFileAtomic(metaFile, JSON.stringify({
|
|
545
|
+
writeFileAtomic(metaFile, JSON.stringify({
|
|
546
|
+
savedAt: new Date().toISOString(),
|
|
547
|
+
edgeCount: graph.edges.length,
|
|
548
|
+
}));
|
|
437
549
|
}
|
|
438
550
|
catch {
|
|
439
551
|
// Non-fatal — next session rebuilds from scratch.
|
|
@@ -485,21 +597,36 @@ function finiteCount(value) {
|
|
|
485
597
|
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
486
598
|
}
|
|
487
599
|
function countsMatch(left, right) {
|
|
488
|
-
return Math.abs(left - right) <=
|
|
600
|
+
return (Math.abs(left - right) <=
|
|
601
|
+
1e-9 * Math.max(1, Math.abs(left), Math.abs(right)));
|
|
489
602
|
}
|
|
490
603
|
function validatePersistedCallGraph(raw, coverage) {
|
|
491
604
|
const nonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
492
605
|
const enumValue = (value, values) => typeof value === "string" && values.includes(value);
|
|
493
606
|
const edgeKinds = ["calls", "references", "mixed"];
|
|
494
|
-
const resolutions = [
|
|
495
|
-
|
|
607
|
+
const resolutions = [
|
|
608
|
+
"exact",
|
|
609
|
+
"import",
|
|
610
|
+
"receiver-type",
|
|
611
|
+
"name-only",
|
|
612
|
+
"unresolved",
|
|
613
|
+
];
|
|
614
|
+
if (!raw ||
|
|
615
|
+
raw.version !== CALL_GRAPH_CACHE_VERSION ||
|
|
616
|
+
!nonEmptyString(raw.builtAt))
|
|
496
617
|
return false;
|
|
497
|
-
if (!nonEmptyString(raw.reviewGraphVersion) ||
|
|
618
|
+
if (!nonEmptyString(raw.reviewGraphVersion) ||
|
|
619
|
+
!nonEmptyString(raw.reviewGraphSignature))
|
|
498
620
|
return false;
|
|
499
621
|
if (raw.coverage !== undefined &&
|
|
500
|
-
(!raw.coverage ||
|
|
622
|
+
(!raw.coverage ||
|
|
623
|
+
typeof raw.coverage !== "object" ||
|
|
624
|
+
Array.isArray(raw.coverage)))
|
|
501
625
|
return false;
|
|
502
|
-
if (!Array.isArray(raw.edges) ||
|
|
626
|
+
if (!Array.isArray(raw.edges) ||
|
|
627
|
+
!Array.isArray(raw.callees) ||
|
|
628
|
+
!Array.isArray(raw.callers) ||
|
|
629
|
+
!Array.isArray(raw.inDegree))
|
|
503
630
|
return false;
|
|
504
631
|
const coverageValues = [
|
|
505
632
|
coverage.totalEvidence,
|
|
@@ -513,23 +640,34 @@ function validatePersistedCallGraph(raw, coverage) {
|
|
|
513
640
|
coverage.sameFileEvidence,
|
|
514
641
|
coverage.duplicateEvidence,
|
|
515
642
|
];
|
|
516
|
-
if (typeof coverage.complete !== "boolean" ||
|
|
643
|
+
if (typeof coverage.complete !== "boolean" ||
|
|
644
|
+
coverageValues.some((value) => !finiteCount(value)))
|
|
517
645
|
return false;
|
|
518
646
|
if (coverage.languages !== undefined &&
|
|
519
|
-
(!coverage.languages ||
|
|
520
|
-
|
|
647
|
+
(!coverage.languages ||
|
|
648
|
+
typeof coverage.languages !== "object" ||
|
|
649
|
+
Array.isArray(coverage.languages) ||
|
|
650
|
+
Object.entries(coverage.languages).some(([language, status]) => !nonEmptyString(language) ||
|
|
651
|
+
!enumValue(status, ["complete", "partial", "unavailable"]))))
|
|
521
652
|
return false;
|
|
522
|
-
if (coverage.callsEvidence + coverage.referencesEvidence !==
|
|
653
|
+
if (coverage.callsEvidence + coverage.referencesEvidence !==
|
|
654
|
+
coverage.totalEvidence)
|
|
523
655
|
return false;
|
|
524
656
|
if (coverage.resolvedEvidence > coverage.eligibleEvidence)
|
|
525
657
|
return false;
|
|
526
658
|
if (coverage.eligibleEvidence !== coverage.resolvedEvidence)
|
|
527
659
|
return false;
|
|
528
|
-
if (coverage.resolvedEvidence +
|
|
660
|
+
if (coverage.resolvedEvidence +
|
|
661
|
+
coverage.unresolvedEvidence +
|
|
662
|
+
coverage.typeOnlyEvidence +
|
|
663
|
+
coverage.unsupportedEvidence +
|
|
664
|
+
coverage.sameFileEvidence !==
|
|
665
|
+
coverage.totalEvidence)
|
|
529
666
|
return false;
|
|
530
667
|
if (coverage.complete && coverage.unsupportedEvidence > 0)
|
|
531
668
|
return false;
|
|
532
|
-
if (coverage.complete &&
|
|
669
|
+
if (coverage.complete &&
|
|
670
|
+
Object.values(coverage.languages ?? {}).some((status) => status !== "complete"))
|
|
533
671
|
return false;
|
|
534
672
|
const expectedCallees = new Map();
|
|
535
673
|
const expectedCallers = new Map();
|
|
@@ -538,9 +676,17 @@ function validatePersistedCallGraph(raw, coverage) {
|
|
|
538
676
|
let weightedEdgeEvidence = 0;
|
|
539
677
|
let weightedDuplicateEvidence = 0;
|
|
540
678
|
for (const edge of raw.edges) {
|
|
541
|
-
if (!edge ||
|
|
542
|
-
|
|
543
|
-
!nonEmptyString(edge.
|
|
679
|
+
if (!edge ||
|
|
680
|
+
typeof edge !== "object" ||
|
|
681
|
+
!nonEmptyString(edge.callerKey) ||
|
|
682
|
+
!nonEmptyString(edge.calleeKey) ||
|
|
683
|
+
!nonEmptyString(edge.callerFile) ||
|
|
684
|
+
!nonEmptyString(edge.calleeFile) ||
|
|
685
|
+
!nonEmptyString(edge.calleeSymbol) ||
|
|
686
|
+
typeof edge.weight !== "number" ||
|
|
687
|
+
!Number.isFinite(edge.weight) ||
|
|
688
|
+
edge.weight <= 0 ||
|
|
689
|
+
edge.weight > 1)
|
|
544
690
|
return false;
|
|
545
691
|
if (edge.callerSymbol !== undefined && !nonEmptyString(edge.callerSymbol))
|
|
546
692
|
return false;
|
|
@@ -548,19 +694,27 @@ function validatePersistedCallGraph(raw, coverage) {
|
|
|
548
694
|
return false;
|
|
549
695
|
if (edge.calleeKind !== undefined && !nonEmptyString(edge.calleeKind))
|
|
550
696
|
return false;
|
|
551
|
-
if (edge.evidenceKind !== undefined &&
|
|
697
|
+
if (edge.evidenceKind !== undefined &&
|
|
698
|
+
!enumValue(edge.evidenceKind, edgeKinds))
|
|
552
699
|
return false;
|
|
553
|
-
if (edge.resolution !== undefined &&
|
|
700
|
+
if (edge.resolution !== undefined &&
|
|
701
|
+
!enumValue(edge.resolution, resolutions))
|
|
554
702
|
return false;
|
|
555
|
-
if (edge.evidenceCount !== undefined &&
|
|
703
|
+
if (edge.evidenceCount !== undefined &&
|
|
704
|
+
(!finiteCount(edge.evidenceCount) || edge.evidenceCount < 1))
|
|
556
705
|
return false;
|
|
557
706
|
const evidenceCount = edge.evidenceCount ?? 1;
|
|
558
707
|
const callerIdentity = parseCanonicalSymbolKey(edge.callerKey, edge.callerFile);
|
|
559
708
|
const calleeIdentity = parseCanonicalSymbolKey(edge.calleeKey, edge.calleeFile);
|
|
560
|
-
if (normalizeMapKey(callerIdentity.filePath) !==
|
|
561
|
-
normalizeMapKey(
|
|
562
|
-
(calleeIdentity.
|
|
563
|
-
|
|
709
|
+
if (normalizeMapKey(callerIdentity.filePath) !==
|
|
710
|
+
normalizeMapKey(edge.callerFile) ||
|
|
711
|
+
normalizeMapKey(calleeIdentity.filePath) !==
|
|
712
|
+
normalizeMapKey(edge.calleeFile) ||
|
|
713
|
+
(calleeIdentity.symbolName !== undefined &&
|
|
714
|
+
calleeIdentity.symbolName !== edge.calleeSymbol) ||
|
|
715
|
+
(callerIdentity.symbolName !== undefined &&
|
|
716
|
+
edge.callerSymbol !== undefined &&
|
|
717
|
+
callerIdentity.symbolName !== edge.callerSymbol))
|
|
564
718
|
return false;
|
|
565
719
|
const pair = `${edge.callerKey}\u0000${edge.calleeKey}`;
|
|
566
720
|
if (pairKeys.has(pair))
|
|
@@ -583,7 +737,11 @@ function validatePersistedCallGraph(raw, coverage) {
|
|
|
583
737
|
return false;
|
|
584
738
|
if (!countsMatch(weightedDuplicateEvidence, coverage.duplicateEvidence))
|
|
585
739
|
return false;
|
|
586
|
-
if (!countsMatch(coverage.totalEvidence, weightedEdgeEvidence +
|
|
740
|
+
if (!countsMatch(coverage.totalEvidence, weightedEdgeEvidence +
|
|
741
|
+
coverage.unresolvedEvidence +
|
|
742
|
+
coverage.typeOnlyEvidence +
|
|
743
|
+
coverage.unsupportedEvidence +
|
|
744
|
+
coverage.sameFileEvidence))
|
|
587
745
|
return false;
|
|
588
746
|
if (raw.totalRefs !== undefined && !finiteCount(raw.totalRefs))
|
|
589
747
|
return false;
|
|
@@ -591,14 +749,18 @@ function validatePersistedCallGraph(raw, coverage) {
|
|
|
591
749
|
return false;
|
|
592
750
|
if (raw.totalRefs !== undefined && raw.totalRefs !== coverage.totalEvidence)
|
|
593
751
|
return false;
|
|
594
|
-
if (raw.unresolvedRefs !== undefined &&
|
|
752
|
+
if (raw.unresolvedRefs !== undefined &&
|
|
753
|
+
raw.unresolvedRefs !== coverage.unresolvedEvidence)
|
|
595
754
|
return false;
|
|
596
755
|
const readAdjacency = (entries) => {
|
|
597
756
|
const result = new Map();
|
|
598
757
|
if (!Array.isArray(entries))
|
|
599
758
|
return undefined;
|
|
600
759
|
for (const entry of entries) {
|
|
601
|
-
if (!Array.isArray(entry) ||
|
|
760
|
+
if (!Array.isArray(entry) ||
|
|
761
|
+
!nonEmptyString(entry[0]) ||
|
|
762
|
+
!Array.isArray(entry[1]) ||
|
|
763
|
+
entry[1].some((key) => !nonEmptyString(key)))
|
|
602
764
|
return undefined;
|
|
603
765
|
const keys = entry[1];
|
|
604
766
|
if (new Set(keys).size !== keys.length || result.has(entry[0]))
|
|
@@ -609,21 +771,32 @@ function validatePersistedCallGraph(raw, coverage) {
|
|
|
609
771
|
};
|
|
610
772
|
const actualCallees = readAdjacency(raw.callees);
|
|
611
773
|
const actualCallers = readAdjacency(raw.callers);
|
|
612
|
-
if (!actualCallees ||
|
|
774
|
+
if (!actualCallees ||
|
|
775
|
+
!actualCallers ||
|
|
776
|
+
actualCallees.size !== expectedCallees.size ||
|
|
777
|
+
actualCallers.size !== expectedCallers.size)
|
|
613
778
|
return false;
|
|
614
779
|
const sameSets = (actual, expected) => {
|
|
615
780
|
for (const [key, values] of expected) {
|
|
616
781
|
const got = actual.get(key);
|
|
617
|
-
if (!got ||
|
|
782
|
+
if (!got ||
|
|
783
|
+
got.size !== values.size ||
|
|
784
|
+
[...values].some((value) => !got.has(value)))
|
|
618
785
|
return false;
|
|
619
786
|
}
|
|
620
787
|
return true;
|
|
621
788
|
};
|
|
622
|
-
if (!sameSets(actualCallees, expectedCallees) ||
|
|
789
|
+
if (!sameSets(actualCallees, expectedCallees) ||
|
|
790
|
+
!sameSets(actualCallers, expectedCallers))
|
|
623
791
|
return false;
|
|
624
792
|
const actualInDegree = new Map();
|
|
625
793
|
for (const entry of raw.inDegree) {
|
|
626
|
-
if (!Array.isArray(entry) ||
|
|
794
|
+
if (!Array.isArray(entry) ||
|
|
795
|
+
!nonEmptyString(entry[0]) ||
|
|
796
|
+
typeof entry[1] !== "number" ||
|
|
797
|
+
!Number.isFinite(entry[1]) ||
|
|
798
|
+
entry[1] < 0 ||
|
|
799
|
+
actualInDegree.has(entry[0]))
|
|
627
800
|
return false;
|
|
628
801
|
actualInDegree.set(entry[0], entry[1]);
|
|
629
802
|
}
|
|
@@ -645,14 +818,16 @@ export function loadCallGraph(cwd, expectedIdentity) {
|
|
|
645
818
|
const raw = JSON.parse(fs.readFileSync(cacheFile, "utf-8"));
|
|
646
819
|
if (raw.version !== CALL_GRAPH_CACHE_VERSION)
|
|
647
820
|
return undefined;
|
|
648
|
-
if (typeof raw.reviewGraphVersion !== "string" ||
|
|
821
|
+
if (typeof raw.reviewGraphVersion !== "string" ||
|
|
822
|
+
typeof raw.reviewGraphSignature !== "string")
|
|
649
823
|
return undefined;
|
|
650
824
|
const identity = {
|
|
651
825
|
reviewGraphVersion: raw.reviewGraphVersion,
|
|
652
826
|
reviewGraphSignature: raw.reviewGraphSignature,
|
|
653
827
|
};
|
|
654
|
-
if (expectedIdentity &&
|
|
655
|
-
identity.
|
|
828
|
+
if (expectedIdentity &&
|
|
829
|
+
(identity.reviewGraphVersion !== expectedIdentity.reviewGraphVersion ||
|
|
830
|
+
identity.reviewGraphSignature !== expectedIdentity.reviewGraphSignature))
|
|
656
831
|
return undefined;
|
|
657
832
|
const coverage = loadCoverage(raw.coverage, raw.edges);
|
|
658
833
|
if (!validatePersistedCallGraph(raw, coverage))
|
|
@@ -79,8 +79,10 @@ export function buildCodebaseModel(graph, cwd, budget = DEFAULT_CODEBASE_MODEL_T
|
|
|
79
79
|
// carries that graph's identity rather than inventing a second freshness
|
|
80
80
|
// policy.
|
|
81
81
|
const fileRole = detectFileRole(filePath);
|
|
82
|
-
if (fileRole === "test" ||
|
|
83
|
-
|
|
82
|
+
if (fileRole === "test" ||
|
|
83
|
+
fileRole === "generated" ||
|
|
84
|
+
isExternalOrVendorFile(filePath, cwd) ||
|
|
85
|
+
isBuildArtifact(filePath)) {
|
|
84
86
|
continue;
|
|
85
87
|
}
|
|
86
88
|
// Deduplicate by name when the same function appears in multiple files
|
|
@@ -138,7 +140,11 @@ export function saveCodebaseModel(cwd, model) {
|
|
|
138
140
|
try {
|
|
139
141
|
fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
|
|
140
142
|
writeFileAtomic(cacheFile, JSON.stringify(model));
|
|
141
|
-
writeFileAtomic(metaFilePath(cwd), JSON.stringify({
|
|
143
|
+
writeFileAtomic(metaFilePath(cwd), JSON.stringify({
|
|
144
|
+
savedAt: new Date().toISOString(),
|
|
145
|
+
entryCount: model.entries.length,
|
|
146
|
+
totalTokens: model.totalTokens,
|
|
147
|
+
}));
|
|
142
148
|
}
|
|
143
149
|
catch {
|
|
144
150
|
// Non-fatal — next session rebuilds.
|
|
@@ -149,8 +155,10 @@ export function loadCodebaseModel(cwd, expectedIdentity) {
|
|
|
149
155
|
try {
|
|
150
156
|
const raw = JSON.parse(fs.readFileSync(cacheFilePath(cwd), "utf-8"));
|
|
151
157
|
if (raw.version !== CODEBASE_MODEL_VERSION ||
|
|
152
|
-
typeof raw.reviewGraphVersion !== "string" ||
|
|
153
|
-
|
|
158
|
+
typeof raw.reviewGraphVersion !== "string" ||
|
|
159
|
+
raw.reviewGraphVersion.length === 0 ||
|
|
160
|
+
typeof raw.reviewGraphSignature !== "string" ||
|
|
161
|
+
raw.reviewGraphSignature.length === 0 ||
|
|
154
162
|
typeof raw.generatedAt !== "string" ||
|
|
155
163
|
!Array.isArray(raw.entries))
|
|
156
164
|
return undefined;
|
|
@@ -371,9 +371,7 @@ function countSingleUseFunctions(functions) {
|
|
|
371
371
|
export class ComplexityClient {
|
|
372
372
|
log;
|
|
373
373
|
constructor(verbose = false) {
|
|
374
|
-
this.log = verbose
|
|
375
|
-
? createSubsystemLogger("complexity")
|
|
376
|
-
: () => { };
|
|
374
|
+
this.log = verbose ? createSubsystemLogger("complexity") : () => { };
|
|
377
375
|
}
|
|
378
376
|
/** True if the file's grammar has a complexity node mapping. */
|
|
379
377
|
isSupportedFile(filePath) {
|
|
@@ -119,9 +119,7 @@ export class PythonDeadCodeClient {
|
|
|
119
119
|
inFlight = new Map();
|
|
120
120
|
log;
|
|
121
121
|
constructor(verbose = false) {
|
|
122
|
-
this.log = verbose
|
|
123
|
-
? createSubsystemLogger("dead-code:python")
|
|
124
|
-
: () => { };
|
|
122
|
+
this.log = verbose ? createSubsystemLogger("dead-code:python") : () => { };
|
|
125
123
|
}
|
|
126
124
|
get minConfidence() {
|
|
127
125
|
const raw = Number.parseInt(process.env.PI_LENS_VULTURE_MIN_CONFIDENCE ?? "60", 10);
|
|
@@ -181,7 +179,10 @@ export class PythonDeadCodeClient {
|
|
|
181
179
|
path.join(".venv", "Scripts", "vulture.exe"),
|
|
182
180
|
path.join("venv", "Scripts", "vulture.exe"),
|
|
183
181
|
]
|
|
184
|
-
: [
|
|
182
|
+
: [
|
|
183
|
+
path.join(".venv", "bin", "vulture"),
|
|
184
|
+
path.join("venv", "bin", "vulture"),
|
|
185
|
+
];
|
|
185
186
|
return relPaths
|
|
186
187
|
.map((rel) => path.join(root, rel))
|
|
187
188
|
.filter((full) => fs.existsSync(full))
|
|
@@ -312,9 +313,17 @@ export class PythonDeadCodeClient {
|
|
|
312
313
|
const existing = this.inFlight.get(key);
|
|
313
314
|
if (existing)
|
|
314
315
|
return existing;
|
|
315
|
-
const promise = this.runAnalyze(key)
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
const promise = this.runAnalyze(key);
|
|
317
|
+
const wrapped = promise.finally(() => {
|
|
318
|
+
// Identity-guarded release (#1968, #1967's pattern): delete only if
|
|
319
|
+
// THIS build is still the registered one. A bare delete-by-key lets
|
|
320
|
+
// a late-settling build A evict a live build B that replaced the
|
|
321
|
+
// entry mid-flight, and the next caller starts a duplicate.
|
|
322
|
+
if (this.inFlight.get(key) === wrapped)
|
|
323
|
+
this.inFlight.delete(key);
|
|
324
|
+
});
|
|
325
|
+
this.inFlight.set(key, wrapped);
|
|
326
|
+
return wrapped;
|
|
318
327
|
}
|
|
319
328
|
/**
|
|
320
329
|
* True when `<root>/pyproject.toml` carries a `[tool.vulture]` table.
|
|
@@ -392,7 +401,9 @@ export class PythonDeadCodeClient {
|
|
|
392
401
|
});
|
|
393
402
|
return {
|
|
394
403
|
...emptyResult(this.language),
|
|
395
|
-
summary: stderr
|
|
404
|
+
summary: stderr
|
|
405
|
+
? `vulture error: ${firstOutputLine(stderr)}`
|
|
406
|
+
: reason,
|
|
396
407
|
durationMs,
|
|
397
408
|
};
|
|
398
409
|
}
|
|
@@ -12,8 +12,7 @@ import { createNdjsonLogger } from "./ndjson-logger.js";
|
|
|
12
12
|
const LOG_DIR = getGlobalPiLensDir();
|
|
13
13
|
const LOG_FILE = path.join(LOG_DIR, "dead-code.log");
|
|
14
14
|
const LOG_BACKUP_FILE = path.join(LOG_DIR, "dead-code.log.1");
|
|
15
|
-
const MAX_LOG_BYTES = Math.max(128 * 1024, Number.parseInt(process.env.PI_LENS_DEAD_CODE_LOG_MAX_BYTES ?? "1048576", 10) ||
|
|
16
|
-
1048576);
|
|
15
|
+
const MAX_LOG_BYTES = Math.max(128 * 1024, Number.parseInt(process.env.PI_LENS_DEAD_CODE_LOG_MAX_BYTES ?? "1048576", 10) || 1048576);
|
|
17
16
|
const writer = createNdjsonLogger({
|
|
18
17
|
filePath: LOG_FILE,
|
|
19
18
|
maxBytes: MAX_LOG_BYTES,
|
|
@@ -29,7 +29,9 @@ export function combineAbortSignals(...signals) {
|
|
|
29
29
|
controller.abort(s.reason);
|
|
30
30
|
break;
|
|
31
31
|
}
|
|
32
|
-
s.addEventListener("abort", () => controller.abort(s.reason), {
|
|
32
|
+
s.addEventListener("abort", () => controller.abort(s.reason), {
|
|
33
|
+
once: true,
|
|
34
|
+
});
|
|
33
35
|
}
|
|
34
36
|
return controller.signal;
|
|
35
37
|
}
|
|
@@ -162,6 +162,13 @@ export function writeHeapSnapshotNow(label) {
|
|
|
162
162
|
}
|
|
163
163
|
const durationMs = Date.now() - start;
|
|
164
164
|
pruneOldSnapshots(dir);
|
|
165
|
-
writer?.log({
|
|
165
|
+
writer?.log({
|
|
166
|
+
ts,
|
|
167
|
+
label,
|
|
168
|
+
path: written,
|
|
169
|
+
pid: process.pid,
|
|
170
|
+
rssBytes,
|
|
171
|
+
durationMs,
|
|
172
|
+
});
|
|
166
173
|
return { path: written, rssBytes, durationMs };
|
|
167
174
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { logExtension } from "./extension-log.js";
|
|
3
3
|
import { LEDGER_FIELD_MAX, truncateForLedger } from "./ledger-bounds.js";
|
|
4
4
|
import { logLatency } from "./latency-logger.js";
|
|
5
|
-
import { getSinkWriteFailures, resetSinkWriteFailures } from "./ndjson-logger.js";
|
|
5
|
+
import { getSinkWriteFailures, resetSinkWriteFailures, } from "./ndjson-logger.js";
|
|
6
6
|
// Re-exported so existing importers keep one name for the ledger's bound.
|
|
7
7
|
export { LEDGER_FIELD_MAX, truncateForLedger };
|
|
8
8
|
const ENTRIES_PER_KIND = 20;
|