@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
|
@@ -1257,7 +1257,9 @@ async function callTool(name, args) {
|
|
|
1257
1257
|
`LSP: ${aliveClients} alive client(s)`,
|
|
1258
1258
|
...servers.flatMap((server) => [
|
|
1259
1259
|
` ${server.connected ? "✓" : "✗"} ${server.serverId} (${server.root})`,
|
|
1260
|
-
...server.pullFailureHistory
|
|
1260
|
+
...server.pullFailureHistory
|
|
1261
|
+
.slice(-1)
|
|
1262
|
+
.map((failure) => ` ⚠ diagnostics pull failed: ${failure.method}${failure.code !== undefined ? ` (${failure.code})` : ""} — ${failure.message.length > 200 ? `${failure.message.slice(0, 200)}…` : failure.message}`),
|
|
1261
1263
|
]),
|
|
1262
1264
|
...renderLspBrokenStatusLines(brokenServers),
|
|
1263
1265
|
...renderDegradationLines(degradations),
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Type } from "../clients/deps/typebox.js";
|
|
7
7
|
import { astGrepRemediationHint, classifyAstGrepError, logAstGrepToolEvent, } from "../clients/ast-grep-tool-logger.js";
|
|
8
|
-
import { hasStructuralIntent, synthesizeReplaceRule } from "../clients/ast-grep-yaml-synth.js";
|
|
8
|
+
import { hasStructuralIntent, synthesizeReplaceRule, } from "../clients/ast-grep-yaml-synth.js";
|
|
9
9
|
import { compactRenderResult } from "./render-compact.js";
|
|
10
10
|
/**
|
|
11
11
|
* Build the agent-facing error text, appending a remediation hint derived from
|
|
@@ -66,15 +66,21 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
66
66
|
description: "Target language",
|
|
67
67
|
}),
|
|
68
68
|
paths: Type.Optional(Type.Array(Type.String(), { description: "Specific files/folders" })),
|
|
69
|
-
insideKind: Type.Optional(Type.String({
|
|
69
|
+
insideKind: Type.Optional(Type.String({
|
|
70
|
+
description: "Restrict matches to nodes inside an ancestor of this AST node kind. Synthesizes a YAML rule.",
|
|
71
|
+
})),
|
|
70
72
|
hasKind: Type.Optional(Type.String({
|
|
71
73
|
description: 'Restrict matches to nodes whose immediate child has this AST node kind (ast-grep default stopBy: neighbor). Example: `hasKind: "await_expression"`.',
|
|
72
74
|
})),
|
|
73
75
|
hasDescendantKind: Type.Optional(Type.String({
|
|
74
76
|
description: "Restrict matches to nodes containing this AST node kind anywhere in their descendants. Explicit recursive form (`stopBy: end`); use this instead of `hasKind` when nesting is not immediate.",
|
|
75
77
|
})),
|
|
76
|
-
follows: Type.Optional(Type.String({
|
|
77
|
-
|
|
78
|
+
follows: Type.Optional(Type.String({
|
|
79
|
+
description: "Restrict matches to nodes that immediately follow a sibling matching this pattern.",
|
|
80
|
+
})),
|
|
81
|
+
precedes: Type.Optional(Type.String({
|
|
82
|
+
description: "Restrict matches to nodes that immediately precede a sibling matching this pattern.",
|
|
83
|
+
})),
|
|
78
84
|
apply: Type.Optional(Type.Boolean({ description: "Apply changes (default: false)" })),
|
|
79
85
|
strictness: Type.Optional(Type.String({
|
|
80
86
|
enum: ["smart", "relaxed", "ast", "cst", "signature", "template"],
|
|
@@ -83,7 +89,7 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
83
89
|
}),
|
|
84
90
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
85
91
|
const startedAt = Date.now();
|
|
86
|
-
const { pattern, rewrite, paths, apply, strictness, insideKind, hasKind, hasDescendantKind, follows, precedes } = params;
|
|
92
|
+
const { pattern, rewrite, paths, apply, strictness, insideKind, hasKind, hasDescendantKind, follows, precedes, } = params;
|
|
87
93
|
const lang = (params.lang ?? "").replace(/^"|"$/g, "");
|
|
88
94
|
const pathsCount = paths?.length ?? 1;
|
|
89
95
|
const applyFlag = apply ?? false;
|
|
@@ -127,27 +133,77 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
127
133
|
}
|
|
128
134
|
const searchPaths = paths?.length ? paths : [ctx.cwd || "."];
|
|
129
135
|
// Phase 3: structural-intent params → synthesize YAML with fix: field
|
|
130
|
-
if (hasStructuralIntent({
|
|
136
|
+
if (hasStructuralIntent({
|
|
137
|
+
insideKind,
|
|
138
|
+
hasKind,
|
|
139
|
+
hasDescendantKind,
|
|
140
|
+
follows,
|
|
141
|
+
precedes,
|
|
142
|
+
})) {
|
|
131
143
|
let ruleYaml;
|
|
132
144
|
try {
|
|
133
|
-
ruleYaml = synthesizeReplaceRule({
|
|
145
|
+
ruleYaml = synthesizeReplaceRule({
|
|
146
|
+
pattern,
|
|
147
|
+
lang,
|
|
148
|
+
rewrite,
|
|
149
|
+
insideKind,
|
|
150
|
+
hasKind,
|
|
151
|
+
hasDescendantKind,
|
|
152
|
+
follows,
|
|
153
|
+
precedes,
|
|
154
|
+
});
|
|
134
155
|
}
|
|
135
156
|
catch (err) {
|
|
136
157
|
logOutcome("error", { errorRaw: String(err) });
|
|
137
|
-
return {
|
|
158
|
+
return {
|
|
159
|
+
content: [
|
|
160
|
+
{
|
|
161
|
+
type: "text",
|
|
162
|
+
text: `Error synthesizing rule: ${err}`,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
isError: true,
|
|
166
|
+
details: {},
|
|
167
|
+
};
|
|
138
168
|
}
|
|
139
169
|
const ruleResult = await astGrepClient.replaceWithRule(ruleYaml, searchPaths, applyFlag);
|
|
140
170
|
if (ruleResult.stalePreview) {
|
|
141
171
|
logOutcome("error", { errorRaw: "stale_preview" });
|
|
142
|
-
return {
|
|
172
|
+
return {
|
|
173
|
+
content: [
|
|
174
|
+
{
|
|
175
|
+
type: "text",
|
|
176
|
+
text: "Stale preview — pattern no longer matches. Re-run with apply: false.",
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
isError: true,
|
|
180
|
+
details: { stalePreview: true },
|
|
181
|
+
};
|
|
143
182
|
}
|
|
144
183
|
if (ruleResult.error) {
|
|
145
184
|
logOutcome("error", { errorRaw: ruleResult.error });
|
|
146
|
-
return {
|
|
185
|
+
return {
|
|
186
|
+
content: [
|
|
187
|
+
{
|
|
188
|
+
type: "text",
|
|
189
|
+
text: errorTextWithHint(ruleResult.error),
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
isError: true,
|
|
193
|
+
details: {},
|
|
194
|
+
};
|
|
147
195
|
}
|
|
148
196
|
const output = astGrepClient.formatMatches(ruleResult.matches, !applyFlag, true);
|
|
149
|
-
logOutcome(ruleResult.matches.length === 0 ? "no_matches" : "success", {
|
|
150
|
-
|
|
197
|
+
logOutcome(ruleResult.matches.length === 0 ? "no_matches" : "success", {
|
|
198
|
+
matchCount: ruleResult.matches.length,
|
|
199
|
+
});
|
|
200
|
+
return {
|
|
201
|
+
content: [{ type: "text", text: output }],
|
|
202
|
+
details: {
|
|
203
|
+
matchCount: ruleResult.matches.length,
|
|
204
|
+
applied: applyFlag,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
151
207
|
}
|
|
152
208
|
const result = await astGrepClient.replace(pattern, rewrite, lang, searchPaths, applyFlag, { strictness });
|
|
153
209
|
if (result.stalePreview) {
|
|
@@ -45,8 +45,13 @@ import * as path from "node:path";
|
|
|
45
45
|
import { Type } from "../clients/deps/typebox.js";
|
|
46
46
|
import { markDisposition, normalizeMessage, } from "../clients/diagnostic-dispositions.js";
|
|
47
47
|
import { insertSuppressComment } from "../clients/dispatch/suppress-writer.js";
|
|
48
|
-
import { getFileDiagnostics } from "../clients/widget-state.js";
|
|
49
|
-
const DISPOSITIONS = [
|
|
48
|
+
import { getFileDiagnostics, } from "../clients/widget-state.js";
|
|
49
|
+
const DISPOSITIONS = [
|
|
50
|
+
"false-positive",
|
|
51
|
+
"suppress",
|
|
52
|
+
"defer",
|
|
53
|
+
"flagged",
|
|
54
|
+
];
|
|
50
55
|
// How far ± the caller's line the fuzzy fallback searches for a plausible
|
|
51
56
|
// (non-blank) line when there's no widget-state match to reanchor from.
|
|
52
57
|
const FUZZY_SEARCH_RADIUS = 5;
|
|
@@ -84,7 +89,9 @@ function widgetCrossCheck(absPath, tool, rule, message, callerLine) {
|
|
|
84
89
|
return undefined;
|
|
85
90
|
if (matches.length === 1)
|
|
86
91
|
return { line: matches[0].line, ambiguous: false };
|
|
87
|
-
const closest = matches.reduce((best, d) =>
|
|
92
|
+
const closest = matches.reduce((best, d) => Math.abs(d.line - callerLine) < Math.abs(best.line - callerLine)
|
|
93
|
+
? d
|
|
94
|
+
: best, matches[0]);
|
|
88
95
|
return { line: closest.line, ambiguous: true };
|
|
89
96
|
}
|
|
90
97
|
/**
|
|
@@ -135,7 +142,9 @@ function verifyLine(content, absPath, tool, rule, message, callerLine) {
|
|
|
135
142
|
reanchored,
|
|
136
143
|
note: reanchored
|
|
137
144
|
? `reanchored from line ${callerLine} to ${widgetResult.line}` +
|
|
138
|
-
(widgetResult.ambiguous
|
|
145
|
+
(widgetResult.ambiguous
|
|
146
|
+
? " (multiple live matches, chose nearest)"
|
|
147
|
+
: "") +
|
|
139
148
|
" against current diagnostics"
|
|
140
149
|
: undefined,
|
|
141
150
|
};
|
|
@@ -193,12 +202,16 @@ getIdentity) {
|
|
|
193
202
|
rule: Type.Optional(Type.String({
|
|
194
203
|
description: "The diagnostic's rule id, if it has one (shown in lens_diagnostics as [rule]). Required for disposition=suppress.",
|
|
195
204
|
})),
|
|
196
|
-
tool: Type.Optional(Type.String({
|
|
205
|
+
tool: Type.Optional(Type.String({
|
|
206
|
+
description: "The tool that produced the diagnostic, if known.",
|
|
207
|
+
})),
|
|
197
208
|
disposition: Type.String({
|
|
198
209
|
enum: DISPOSITIONS,
|
|
199
210
|
description: "false-positive = the rule misfired. suppress = real finding, won't fix (writes an inline ignore comment). defer = fix later, this session only. flagged = mark for you to fix.",
|
|
200
211
|
}),
|
|
201
|
-
reason: Type.Optional(Type.String({
|
|
212
|
+
reason: Type.Optional(Type.String({
|
|
213
|
+
description: "Optional short reason, kept alongside the disposition.",
|
|
214
|
+
})),
|
|
202
215
|
}),
|
|
203
216
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
204
217
|
const cwd = ctx.cwd ?? getCwd();
|
|
@@ -304,8 +317,9 @@ getIdentity) {
|
|
|
304
317
|
if (disposition === "suppress") {
|
|
305
318
|
let updated;
|
|
306
319
|
try {
|
|
320
|
+
updated = insertSuppressComment(content, absPath, verifiedLine,
|
|
307
321
|
// biome-ignore lint/style/noNonNullAssertion: validated above
|
|
308
|
-
|
|
322
|
+
rule);
|
|
309
323
|
}
|
|
310
324
|
catch (err) {
|
|
311
325
|
return {
|
|
@@ -12,16 +12,17 @@ import { promises as fs } from "node:fs";
|
|
|
12
12
|
import * as fsSync from "node:fs";
|
|
13
13
|
import * as path from "node:path";
|
|
14
14
|
import { Type } from "../clients/deps/typebox.js";
|
|
15
|
-
import { anchorsForDiagnostic, applyDispositions, applyWeakDispositions, getDisposition, } from "../clients/diagnostic-dispositions.js";
|
|
15
|
+
import { anchorsForDiagnostic, applyDispositions, applyWeakDispositions, hasAnyDispositionMarks, hasStrictDispositionMarks, getDisposition, } from "../clients/diagnostic-dispositions.js";
|
|
16
|
+
import { freshnessFromMtime } from "../clients/freshness.js";
|
|
16
17
|
import { applyInlineSuppressions } from "../clients/dispatch/inline-suppressions.js";
|
|
17
18
|
import { gateFindingsByPathFreshness } from "../clients/advisory-provenance.js";
|
|
18
19
|
import { normalizeRuleId } from "../clients/dispatch/rule-id-normalize.js";
|
|
19
|
-
import { applyRulePolicy, rulePolicyMapFromConfig } from "../clients/dispatch/rule-policy.js";
|
|
20
|
+
import { applyRulePolicy, rulePolicyMapFromConfig, } from "../clients/dispatch/rule-policy.js";
|
|
20
21
|
import { loadPiLensProjectConfig } from "../clients/project-lens-config.js";
|
|
21
22
|
import { compactRenderResult } from "./render-compact.js";
|
|
22
23
|
import { combineAbortSignals } from "../clients/deadline-utils.js";
|
|
23
24
|
import { getProjectIgnoreMatcher } from "../clients/file-utils.js";
|
|
24
|
-
import { isAtOrAboveHomeDir, normalizeFilePath, } from "../clients/path-utils.js";
|
|
25
|
+
import { isAtOrAboveHomeDir, normalizeEphemeralMapKey, normalizeFilePath, } from "../clients/path-utils.js";
|
|
25
26
|
import { getLSPService } from "../clients/lsp/index.js";
|
|
26
27
|
import { primaryServerId } from "../clients/lsp/config.js";
|
|
27
28
|
import { getFullScanWallClockMs } from "../clients/lsp/workspace-sweep-hold.js";
|
|
@@ -243,7 +244,7 @@ captureLspStatusRepaint, getRuntime) {
|
|
|
243
244
|
description: `Restrict any mode to an explicit file/directory list (max ${MAX_PATHS_ENTRIES} entries; ` +
|
|
244
245
|
"more errors instead of silently truncating). Entries may be relative " +
|
|
245
246
|
"(resolved against cwd) or absolute, and a directory entry matches all " +
|
|
246
|
-
|
|
247
|
+
'files under it (e.g. "src/"). mode=delta/all are a pure post-filter ' +
|
|
247
248
|
"of cached/session state — they can only show findings for files pi-lens " +
|
|
248
249
|
"has already dispatched, so an unseen file shows nothing (use mode=full " +
|
|
249
250
|
"for an active scan). mode=full actively scans exactly these paths (LSP " +
|
|
@@ -407,12 +408,108 @@ function appendProjectDiagnosticsDeltaLines(lines, cwd, report, severity, includ
|
|
|
407
408
|
}
|
|
408
409
|
return diagnostics.length;
|
|
409
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Bounded content memo for {@link applyCachedDispositions}' strict-immediate
|
|
413
|
+
* path: one read per (file revision), not per query. Keyed through
|
|
414
|
+
* `normalizeEphemeralMapKey` (cheap slash-fold + win32-lowercase — these keys
|
|
415
|
+
* are produced and consumed inside this process only) and validated against a
|
|
416
|
+
* fresh stat's mtimeMs+size on every hit, so an edit invalidates without a
|
|
417
|
+
* TTL. Insertion-ordered LRU cap bounds resident source bytes; repeated
|
|
418
|
+
* queries and multi-file reports that cite the same file reuse one read.
|
|
419
|
+
*/
|
|
420
|
+
const CACHED_CONTENT_MEMO_CAP = 64;
|
|
421
|
+
const cachedContentMemo = new Map();
|
|
422
|
+
function readContentForAnchors(filePath, stat) {
|
|
423
|
+
const key = normalizeEphemeralMapKey(filePath);
|
|
424
|
+
const hit = cachedContentMemo.get(key);
|
|
425
|
+
if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) {
|
|
426
|
+
// Refresh LRU position.
|
|
427
|
+
cachedContentMemo.delete(key);
|
|
428
|
+
cachedContentMemo.set(key, hit);
|
|
429
|
+
return hit.content;
|
|
430
|
+
}
|
|
431
|
+
let content;
|
|
432
|
+
try {
|
|
433
|
+
content = fsSync.readFileSync(filePath, "utf-8");
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
if (cachedContentMemo.size >= CACHED_CONTENT_MEMO_CAP) {
|
|
439
|
+
const oldest = cachedContentMemo.keys().next().value;
|
|
440
|
+
if (oldest !== undefined)
|
|
441
|
+
cachedContentMemo.delete(oldest);
|
|
442
|
+
}
|
|
443
|
+
cachedContentMemo.set(key, {
|
|
444
|
+
mtimeMs: stat.mtimeMs,
|
|
445
|
+
size: stat.size,
|
|
446
|
+
content,
|
|
447
|
+
});
|
|
448
|
+
return content;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* ONE disposition seam for every cache-only lens_diagnostics surface —
|
|
452
|
+
* mode=all summaries, mode=delta's actionable/quality warnings, the delta
|
|
453
|
+
* project-diagnostics report, and the empty-delta carried-over note. Cached
|
|
454
|
+
* findings predate any lens_diagnostic_mark, so each surface must re-apply
|
|
455
|
+
* dispositions at query time; before this seam each site hand-picked its own
|
|
456
|
+
* variant and three of them served stale STRICT false-positive marks via the
|
|
457
|
+
* weak-only filter (a weak filter can never drop a strict-anchored mark, nor
|
|
458
|
+
* any blocking finding — #1625 F1).
|
|
459
|
+
*
|
|
460
|
+
* Strict-immediate path: stat the file once, then compare its mtime against
|
|
461
|
+
* the newest cached diagnostic's own observation stamp through the freshness
|
|
462
|
+
* kernel (`freshnessFromMtime`). Fresh or stamp-less means the current bytes
|
|
463
|
+
* still describe what these findings were observed against, so the content is
|
|
464
|
+
* read (memoized per revision above) and the FULL applyDispositions filter
|
|
465
|
+
* runs — a fresh false-positive mark converges immediately, including on
|
|
466
|
+
* blocking findings.
|
|
467
|
+
*
|
|
468
|
+
* Weak fallback (zero further I/O): a file that is gone/unreadable, or whose
|
|
469
|
+
* mtime moved AFTER these diagnostics were observed. Stale-content edge: the
|
|
470
|
+
* cached findings describe a superseded revision, so their line numbers may no
|
|
471
|
+
* longer align with the lines a mark hashed; deriving strict anchors from the
|
|
472
|
+
* new content could match a DIFFERENT occurrence that merely shares the line
|
|
473
|
+
* number and identical text, so the mark waits for the next real dispatch to
|
|
474
|
+
* re-derive both sides against matching revisions. Weak suppress/defer marks
|
|
475
|
+
* are intent-level and never look at content, so they keep applying here.
|
|
476
|
+
*/
|
|
477
|
+
function applyCachedDispositions(cachedDiagnostics, cwd, filePath) {
|
|
478
|
+
// Zero-I/O fast paths (#1625 F2 precedent): with no marks at all there is
|
|
479
|
+
// nothing to filter; with only weak suppress/defer marks a strict anchor
|
|
480
|
+
// can never match, so the weak filter serves them without any stat/read.
|
|
481
|
+
if (!hasAnyDispositionMarks(cwd))
|
|
482
|
+
return cachedDiagnostics;
|
|
483
|
+
if (!hasStrictDispositionMarks(cwd)) {
|
|
484
|
+
return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
|
|
485
|
+
}
|
|
486
|
+
let stat;
|
|
487
|
+
try {
|
|
488
|
+
stat = fsSync.statSync(filePath);
|
|
489
|
+
}
|
|
490
|
+
catch {
|
|
491
|
+
return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
|
|
492
|
+
}
|
|
493
|
+
const referenceMs = cachedDiagnostics.reduce((latest, d) => Math.max(latest, d.observedAt ?? 0), 0);
|
|
494
|
+
if (referenceMs > 0 &&
|
|
495
|
+
freshnessFromMtime({ mtimeMs: stat.mtimeMs, referenceMs }).verdict ===
|
|
496
|
+
"stale") {
|
|
497
|
+
return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
|
|
498
|
+
}
|
|
499
|
+
const content = readContentForAnchors(filePath, stat);
|
|
500
|
+
if (content === undefined) {
|
|
501
|
+
return applyWeakDispositions(cachedDiagnostics, cwd, filePath);
|
|
502
|
+
}
|
|
503
|
+
return applyDispositions(cachedDiagnostics, cwd, filePath, content);
|
|
504
|
+
}
|
|
410
505
|
/**
|
|
411
506
|
* #755: drop project-diagnostics-delta findings disposed suppress/defer before
|
|
412
507
|
* delta mode re-serves them. Anchored via `projectDiagnosticToWidget` so the
|
|
413
508
|
* (tool, rule) an agent's mark binds to matches mode=full's own project-runner
|
|
414
509
|
* filter (`applyInlineSuppressionsToSummaries`), keeping the two paths in
|
|
415
|
-
* agreement.
|
|
510
|
+
* agreement. Goes through the shared {@link applyCachedDispositions} seam so
|
|
511
|
+
* strict false-positive anchors apply immediately, like every other cache-only
|
|
512
|
+
* surface. Also applies the project's
|
|
416
513
|
* `.pi-lens.json` `rules.<id>.disable`/`select` policy so a project's policy
|
|
417
514
|
* overlays the same delta report cache; the cache is otherwise insensitive to
|
|
418
515
|
* a project-config edit (the per-edit path picks it up immediately, but a
|
|
@@ -421,8 +518,7 @@ function appendProjectDiagnosticsDeltaLines(lines, cwd, report, severity, includ
|
|
|
421
518
|
function filterDeltaReportDispositions(report, cwd, policyMap) {
|
|
422
519
|
if (!report?.diagnostics.length)
|
|
423
520
|
return report;
|
|
424
|
-
const kept = report.diagnostics.filter((d) =>
|
|
425
|
-
.length === 1);
|
|
521
|
+
const kept = report.diagnostics.filter((d) => applyCachedDispositions([projectDiagnosticToWidget(d, d.filePath)], cwd, d.filePath).length === 1);
|
|
426
522
|
const policyKept = applyRulePolicy(kept, policyMap);
|
|
427
523
|
if (policyKept.length === report.diagnostics.length)
|
|
428
524
|
return report;
|
|
@@ -508,14 +604,14 @@ function formatDeltaMode(cacheManager, cwd, severity, pathsScope) {
|
|
|
508
604
|
const includeFile = (filePath) => ignoreFile(filePath) && (!pathsScope || pathsScope.includeFile(filePath));
|
|
509
605
|
// #755: delta re-serves the actionable/quality caches verbatim, but those
|
|
510
606
|
// were filtered at DISPATCH time — before any lens_diagnostic_mark. Re-apply
|
|
511
|
-
//
|
|
512
|
-
//
|
|
513
|
-
//
|
|
607
|
+
// dispositions here so a mark converges immediately, not only on the next
|
|
608
|
+
// edit — through the shared {@link applyCachedDispositions} seam, so strict
|
|
609
|
+
// false-positive marks land as fast as suppress/defer.
|
|
514
610
|
const visibleWarningFiles = (files) => (files ?? [])
|
|
515
611
|
.filter((file) => includeFile(file.filePath))
|
|
516
612
|
.map((file) => ({
|
|
517
613
|
filePath: file.filePath,
|
|
518
|
-
warnings: applyRulePolicy(
|
|
614
|
+
warnings: applyRulePolicy(applyCachedDispositions(file.warnings ?? [], cwd, file.filePath), policyMap),
|
|
519
615
|
}))
|
|
520
616
|
.filter((file) => file.warnings.length > 0);
|
|
521
617
|
const actionableFiles = applyDeltaFreshnessGate(visibleWarningFiles(actionable?.files), cwd, actionable?.generatedAt);
|
|
@@ -556,7 +652,7 @@ function formatDeltaMode(cacheManager, cwd, severity, pathsScope) {
|
|
|
556
652
|
.filter((f) => includeFile(f.filePath))
|
|
557
653
|
.map((f) => ({
|
|
558
654
|
...f,
|
|
559
|
-
diagnostics: applyRulePolicy(
|
|
655
|
+
diagnostics: applyRulePolicy(applyCachedDispositions(f.diagnostics, cwd, f.filePath), policyMap),
|
|
560
656
|
}))
|
|
561
657
|
.filter((f) => f.diagnostics.length > 0);
|
|
562
658
|
const carriedIssues = carried.reduce((n, f) => n + f.diagnostics.length, 0);
|
|
@@ -699,7 +795,10 @@ function filterProjectDiagnosticsDeltaReport(report, includeFile) {
|
|
|
699
795
|
function applyProjectRulePolicy(value, policyMap) {
|
|
700
796
|
if (!value)
|
|
701
797
|
return undefined;
|
|
702
|
-
return {
|
|
798
|
+
return {
|
|
799
|
+
...value,
|
|
800
|
+
diagnostics: applyRulePolicy(value.diagnostics, policyMap),
|
|
801
|
+
};
|
|
703
802
|
}
|
|
704
803
|
/** A diagnostic counts as error-like when it blocks or has error severity.
|
|
705
804
|
* A `stale` (#1641 past-EOF) entry is excluded — its cited line no longer
|
|
@@ -971,11 +1070,29 @@ function tallyLspPrimaryVsAuxiliary(results) {
|
|
|
971
1070
|
}
|
|
972
1071
|
return { primary, auxiliary };
|
|
973
1072
|
}
|
|
974
|
-
function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projectSnapshot, projectDelta
|
|
1073
|
+
export function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projectSnapshot, projectDelta,
|
|
1074
|
+
/**
|
|
1075
|
+
* #1993: resolved paths covered by a CONFIRMED, fully-covered LSP result
|
|
1076
|
+
* in `lspResults`. The fresh sweep is AUTHORITATIVE for these files - any
|
|
1077
|
+
* widget-store diagnostics seeded for them predate the sweep and must not
|
|
1078
|
+
* survive it (an additive-only merge let mid-edit stale 🔴 entries render
|
|
1079
|
+
* forever beside a clean sweep). Files absent from this set keep today's
|
|
1080
|
+
* additive behavior (fail-open: unconfirmed/timed-out sweeps never retire
|
|
1081
|
+
* widget state they did not actually re-check).
|
|
1082
|
+
*/
|
|
1083
|
+
authoritativeLspFiles) {
|
|
975
1084
|
const byFile = new Map();
|
|
976
1085
|
const seen = new Set();
|
|
977
1086
|
for (const summary of widgetSummaries) {
|
|
978
1087
|
const filePath = path.resolve(summary.filePath);
|
|
1088
|
+
// NOTE (#1993 review): dispositions recorded against a CACHED copy's
|
|
1089
|
+
// message text may not match this file's fresh sweep copy (weak
|
|
1090
|
+
// anchors key on message). Both copies derive from the same LSP
|
|
1091
|
+
// diagnostic via convertLspDiagnostics, so identity is stable in
|
|
1092
|
+
// practice; inline pi-lens-ignore comments are the primary
|
|
1093
|
+
// suppression mechanism.
|
|
1094
|
+
if (authoritativeLspFiles?.has(filePath))
|
|
1095
|
+
continue;
|
|
979
1096
|
const diagnostics = (summary.diagnostics ?? []).map((d) => ({ ...d }));
|
|
980
1097
|
byFile.set(filePath, { ...summary, filePath, diagnostics });
|
|
981
1098
|
for (const diagnostic of diagnostics) {
|
|
@@ -1167,7 +1284,9 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1167
1284
|
// signal from the same starting point instead of stacking.
|
|
1168
1285
|
const projectRunnersRequested = shouldIncludeProjectRunners(options.refreshRunners);
|
|
1169
1286
|
const analyzersPromise = projectRunnersRequested
|
|
1170
|
-
? loadBootstrapClients().then((clients) => fetchFreshProjectDiagnostics(cacheManager, cwd, clients, signal, {
|
|
1287
|
+
? loadBootstrapClients().then((clients) => fetchFreshProjectDiagnostics(cacheManager, cwd, clients, signal, {
|
|
1288
|
+
runtime: options.runtime,
|
|
1289
|
+
}))
|
|
1171
1290
|
: Promise.resolve({
|
|
1172
1291
|
diagnostics: [],
|
|
1173
1292
|
runners: [],
|
|
@@ -1225,14 +1344,10 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1225
1344
|
// the unfiltered `lspResults` in, so a timed-out file's placeholder `[]`
|
|
1226
1345
|
// read as "0 diagnostics" — false-clean — in the rendered/`details`
|
|
1227
1346
|
// output (#630).
|
|
1228
|
-
const confirmedLspResults = lspResults.filter((result) => !result.timedOut &&
|
|
1229
|
-
!result.error &&
|
|
1230
|
-
!mismatchedLspResults.has(result));
|
|
1347
|
+
const confirmedLspResults = lspResults.filter((result) => !result.timedOut && !result.error && !mismatchedLspResults.has(result));
|
|
1231
1348
|
const fullyCoveredLspResults = confirmedLspResults.filter((result) => (result.unconfirmedServerIds?.length ?? 0) === 0);
|
|
1232
1349
|
const partiallyCoveredLspResults = confirmedLspResults.filter((result) => (result.unconfirmedServerIds?.length ?? 0) > 0);
|
|
1233
|
-
const unconfirmedLspResults = lspResults.filter((result) => result.timedOut ||
|
|
1234
|
-
result.error ||
|
|
1235
|
-
mismatchedLspResults.has(result));
|
|
1350
|
+
const unconfirmedLspResults = lspResults.filter((result) => result.timedOut || result.error || mismatchedLspResults.has(result));
|
|
1236
1351
|
// #571: reconcile this scan's fresh, CONFIRMED per-file results into the
|
|
1237
1352
|
// footer cache. A footer write is never allowed to fail the tool call, so
|
|
1238
1353
|
// any unexpected throw is swallowed.
|
|
@@ -1301,7 +1416,25 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1301
1416
|
// read as "0 issues, clean" via its LSP contribution. It can still
|
|
1302
1417
|
// legitimately show diagnostics from widgetSummaries/project-runner state
|
|
1303
1418
|
// below if those independently have entries for it.
|
|
1304
|
-
|
|
1419
|
+
// #1993: files with a CONFIRMED, fully-covered LSP result are authoritative
|
|
1420
|
+
// - the fresh sweep replaces their widget-store state instead of merging
|
|
1421
|
+
// additively beside it.
|
|
1422
|
+
const authoritativeLspFiles = new Set(fullyCoveredLspResults.map((result) => path.resolve(result.filePath)));
|
|
1423
|
+
// #1993 review: retirement must be observable - if a future regression
|
|
1424
|
+
// makes the set falsely authoritative, findings would vanish silently.
|
|
1425
|
+
const authoritativeRetiredCount = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath) &&
|
|
1426
|
+
authoritativeLspFiles.has(path.resolve(summary.filePath)) &&
|
|
1427
|
+
(summary.diagnostics?.length ?? 0) > 0).length;
|
|
1428
|
+
if (authoritativeRetiredCount > 0) {
|
|
1429
|
+
logLatency({
|
|
1430
|
+
type: "phase",
|
|
1431
|
+
phase: "lsp_authoritative_widget_retire",
|
|
1432
|
+
filePath: "",
|
|
1433
|
+
durationMs: 0,
|
|
1434
|
+
metadata: { files: authoritativeRetiredCount },
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
const summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles), cwd, policyMap);
|
|
1305
1438
|
// #1888: the full-mode summary above is the first seam where every
|
|
1306
1439
|
// producing lane is correlated. The earlier footer loop intentionally writes
|
|
1307
1440
|
// only CONFIRMED LSP results, so an ast-grep backpressure failure left
|
|
@@ -1520,7 +1653,8 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1520
1653
|
const cheapScanStatusNote = !projectRunnersRequested
|
|
1521
1654
|
? `\n\ncheap project scan (tree-sitter/fact-rules/ast-grep): not run this call (${NOT_REQUESTED_REASON}).`
|
|
1522
1655
|
: options.refreshRunners === "cached"
|
|
1523
|
-
? cheapScanScannedAtMs !== undefined &&
|
|
1656
|
+
? cheapScanScannedAtMs !== undefined &&
|
|
1657
|
+
Number.isFinite(cheapScanScannedAtMs)
|
|
1524
1658
|
? `\n\ncheap project scan (tree-sitter/fact-rules/ast-grep): served from cache, ${formatCacheAgeOld(Date.now() - cheapScanScannedAtMs)} — not re-run this call.`
|
|
1525
1659
|
: `\n\ncheap project scan (tree-sitter/fact-rules/ast-grep): not run (no cached scan; refresh with refreshRunners=cheap/all to populate).`
|
|
1526
1660
|
: "";
|
|
@@ -1716,24 +1850,19 @@ function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummaries(),
|
|
|
1716
1850
|
const isFullMode = detailOverrides.mode === "full";
|
|
1717
1851
|
const ignoreFile = createCurrentIgnoreFilter(cwd);
|
|
1718
1852
|
const includeFile = (filePath) => ignoreFile(filePath) && (!pathsScope || pathsScope.includeFile(filePath));
|
|
1719
|
-
//
|
|
1720
|
-
//
|
|
1721
|
-
//
|
|
1722
|
-
//
|
|
1723
|
-
// show here. Re-apply the weak filter (zero I/O) for the cache-only path and
|
|
1724
|
-
// re-summarize so blocking/error/warning counts reflect the drop.
|
|
1725
|
-
// Same project rule policy (`.pi-lens.json` `rules.<id>.disable`/`select`)
|
|
1726
|
-
// overlays both modes: mode=full re-applies it after inline suppression /
|
|
1727
|
-
// disposition (zero I/O), mode=all applies it here on the cache-only path.
|
|
1728
|
-
// The full path's policyMover is loaded below in `applyInlineSuppressionsToSummaries`.
|
|
1853
|
+
// Cached summaries predate marks. Every cache-only surface re-applies
|
|
1854
|
+
// dispositions through the shared applyCachedDispositions seam — strict
|
|
1855
|
+
// false-positive anchors against current content when the file is
|
|
1856
|
+
// unchanged since observation, weak-only fallback otherwise.
|
|
1729
1857
|
const policyMap = loadProjectRulePolicyMap(cwd);
|
|
1730
1858
|
const dispositioned = isFullMode
|
|
1731
1859
|
? summaries
|
|
1732
1860
|
: summaries.map((s) => {
|
|
1733
|
-
const
|
|
1861
|
+
const diagnostics = s.diagnostics ?? [];
|
|
1862
|
+
const kept = applyCachedDispositions(diagnostics, cwd, s.filePath);
|
|
1734
1863
|
const policyKept = applyRulePolicy(kept, policyMap);
|
|
1735
1864
|
if (policyKept.length === kept.length &&
|
|
1736
|
-
kept.length ===
|
|
1865
|
+
kept.length === diagnostics.length)
|
|
1737
1866
|
return s;
|
|
1738
1867
|
return summarizeDiagnostics(s.filePath, policyKept, s.hasFinalSnapshot);
|
|
1739
1868
|
});
|
|
@@ -11,15 +11,15 @@ import { getProjectIgnoreMatcher, isExcludedDirName, } from "../clients/file-uti
|
|
|
11
11
|
import { getLSPService, groupFilesByPrimaryServer, runPerServerGroups, } from "../clients/lsp/index.js";
|
|
12
12
|
import { buildScopeKey, createWorkspaceDiagnosticsCacheContext, } from "../clients/lsp/workspace-diagnostics-cache.js";
|
|
13
13
|
import { getServersForFileWithConfig, primaryServerId, } from "../clients/lsp/config.js";
|
|
14
|
-
import { combineAbortSignals, withDeadline } from "../clients/deadline-utils.js";
|
|
14
|
+
import { combineAbortSignals, withDeadline, } from "../clients/deadline-utils.js";
|
|
15
15
|
import { applyAuxiliarySuppressions, retagAuxiliaryDiagnostics, } from "../clients/dispatch/auxiliary-lsp.js";
|
|
16
16
|
import { detectFileRole } from "../clients/file-role.js";
|
|
17
17
|
import { hashDiagnosticContent, touchCompletedConfirmationPolicy, touchCoverageGap, } from "../clients/lsp/diagnostic-binding.js";
|
|
18
18
|
import { classifyCascadeWaitTier } from "../clients/lsp/wait-policy/index.js";
|
|
19
|
-
import { attemptTsserverSyncDiagnostics
|
|
19
|
+
import { attemptTsserverSyncDiagnostics } from "../clients/lsp/tsserver-sync.js";
|
|
20
20
|
import { convertLspDiagnostics } from "../clients/dispatch/utils/lsp-diagnostics.js";
|
|
21
21
|
import { demoteInferredProjectDiagnostics } from "../clients/lsp/inferred-project.js";
|
|
22
|
-
import { isBlocking, reconcileScanDiagnostics } from "../clients/widget-state.js";
|
|
22
|
+
import { isBlocking, reconcileScanDiagnostics, } from "../clients/widget-state.js";
|
|
23
23
|
import { baseName, compactRenderResult } from "./render-compact.js";
|
|
24
24
|
import { makeProgressReporter, scanningSummaryLine } from "./scan-progress.js";
|
|
25
25
|
import { isWarmAttached, tryWarmAttachedDiagnostics, } from "../clients/warm-attach.js";
|
|
@@ -367,10 +367,12 @@ onConfirmedNoBlockers) {
|
|
|
367
367
|
if (Array.isArray(typedParams.paths) && typedParams.paths.length > 0) {
|
|
368
368
|
if (typedParams.paths.length > MAX_BATCH_FILES) {
|
|
369
369
|
return {
|
|
370
|
-
content: [
|
|
370
|
+
content: [
|
|
371
|
+
{
|
|
371
372
|
type: "text",
|
|
372
373
|
text: `paths accepts at most ${MAX_BATCH_FILES} files; received ${typedParams.paths.length}.`,
|
|
373
|
-
}
|
|
374
|
+
},
|
|
375
|
+
],
|
|
374
376
|
isError: true,
|
|
375
377
|
details: { mode: "batch", filesChecked: 0 },
|
|
376
378
|
};
|
|
@@ -378,7 +380,12 @@ onConfirmedNoBlockers) {
|
|
|
378
380
|
const rawPaths = typedParams.paths.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
379
381
|
if (rawPaths.length !== typedParams.paths.length) {
|
|
380
382
|
return {
|
|
381
|
-
content: [
|
|
383
|
+
content: [
|
|
384
|
+
{
|
|
385
|
+
type: "text",
|
|
386
|
+
text: "paths must contain non-empty file paths.",
|
|
387
|
+
},
|
|
388
|
+
],
|
|
382
389
|
isError: true,
|
|
383
390
|
details: { mode: "batch", filesChecked: 0 },
|
|
384
391
|
};
|
|
@@ -1206,7 +1213,17 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
1206
1213
|
for (const result of results) {
|
|
1207
1214
|
result.outcome = classifyBatchFileOutcome(result);
|
|
1208
1215
|
}
|
|
1209
|
-
const outcomeCounts = Object.fromEntries([
|
|
1216
|
+
const outcomeCounts = Object.fromEntries([
|
|
1217
|
+
"clean",
|
|
1218
|
+
"findings",
|
|
1219
|
+
"unsupported",
|
|
1220
|
+
"unavailable",
|
|
1221
|
+
"failed",
|
|
1222
|
+
"inconclusive",
|
|
1223
|
+
].map((outcome) => [
|
|
1224
|
+
outcome,
|
|
1225
|
+
results.filter((result) => result.outcome === outcome).length,
|
|
1226
|
+
]));
|
|
1210
1227
|
// Per-file primary-server lookup so a flattened multi-file `display` list
|
|
1211
1228
|
// can still be split into "primary findings" vs "auxiliary findings" —
|
|
1212
1229
|
// `clean`/`unconfirmed` above already reflect ONLY the primary server's
|
|
@@ -1098,7 +1098,9 @@ getFlag, mutationDeps) {
|
|
|
1098
1098
|
edit,
|
|
1099
1099
|
};
|
|
1100
1100
|
}
|
|
1101
|
-
const applied = await applyWorkspaceEdit(edit, ctx.cwd || ".", {
|
|
1101
|
+
const applied = await applyWorkspaceEdit(edit, ctx.cwd || ".", {
|
|
1102
|
+
mutationContext,
|
|
1103
|
+
});
|
|
1102
1104
|
for (const touchedFile of applied.files) {
|
|
1103
1105
|
try {
|
|
1104
1106
|
await openFileBestEffort(lspService, touchedFile, false);
|
|
@@ -29,7 +29,7 @@ export function createModuleReportTool(getProjectRoot) {
|
|
|
29
29
|
description: "Structured, navigable overview of a source module — a token-efficient substitute for reading the whole file. Returns each symbol's name/kind/signature/line-range (plus a first-line `doc` summary when a doc comment is attached), important inline callbacks/closures/lambdas with stable handles, plus who-uses-this, risk flags, and ranked recommendedReads. To read a symbol's body: call read/read_symbol with offset=startLine, limit=endLine-startLine+1 on THIS report's `path` — those aren't repeated per symbol. Prefer this before a full read; then use read_symbol (or read) for the exact body you need.\n" +
|
|
30
30
|
"Single mode: language-uniform tree-sitter outline + review-graph who-uses-this + inline executable extraction; degrades to outline-only when no cached graph is available. `semantic.source` reports whether graph data was used.\n" +
|
|
31
31
|
'Pass `blastRadius: true` to also get the cross-file blast radius — the transitive dependents of this module aggregated to ranked file `read` args ("if you change this, verify these files"). Read-only over the cached graph; omitted on a cold cache. Supersedes the standalone impact query.\n' +
|
|
32
|
-
|
|
32
|
+
"Pass `callGraph: true` to include bounded derived callers/callees from the cached FunctionCallGraph; unavailable cache state is explicit and never reported as zero calls.\n" +
|
|
33
33
|
'`view: "compact"` returns a line-oriented text rendering (one line per symbol/callback, cheapest option) instead of JSON — same data, roughly a quarter of the token cost; use it for a quick skim. Default view returns JSON. An outline shows shape, not bodies — it does NOT count as having read a symbol\'s body for editing; use read_symbol for that.',
|
|
34
34
|
promptSnippet: "Navigable file outline — a cheap substitute for reading a whole file",
|
|
35
35
|
renderResult: compactRenderResult(({ details, args, isError }) => {
|
|
@@ -40,7 +40,7 @@ export function createProjectReportTool(getProjectRoot) {
|
|
|
40
40
|
})),
|
|
41
41
|
view: Type.Optional(Type.String({
|
|
42
42
|
enum: ["default", "compact"],
|
|
43
|
-
description:
|
|
43
|
+
description: "Payload tier. compact (cheapest) returns a line-oriented TEXT rendering instead of JSON. Default returns JSON.",
|
|
44
44
|
})),
|
|
45
45
|
}),
|
|
46
46
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|