@herbertgao/pi-extensions 2026.9.5 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -22
- package/THIRD_PARTY_NOTICES.md +0 -4
- package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +1 -1
- package/node_modules/@herbertgao/sol-pi/package.json +1 -1
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +0 -5
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +3 -1
- package/node_modules/@narumitw/pi-btw/README.md +2 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +284 -365
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +52 -53
- package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +494 -547
- package/node_modules/@narumitw/pi-btw/src/btw.ts +814 -856
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +673 -674
- package/node_modules/@narumitw/pi-btw/src/keybindings.ts +228 -270
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +309 -318
- package/node_modules/@narumitw/pi-btw/src/menu.ts +416 -454
- package/node_modules/@narumitw/pi-btw/src/settings.ts +203 -219
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +173 -201
- package/node_modules/@narumitw/pi-btw/src/text.ts +21 -23
- package/node_modules/@narumitw/pi-btw/src/transcript-markdown.ts +65 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +611 -662
- package/node_modules/pi-lens/CHANGELOG.md +239 -0
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +30 -4
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +2 -0
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +26 -0
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +403 -35
- package/node_modules/pi-lens/dist/clients/bootstrap.js +6 -1
- package/node_modules/pi-lens/dist/clients/cascade-format.js +200 -4
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +10 -2
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +16 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +12 -1
- package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +65 -0
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +28 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +9 -2
- package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +222 -0
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +389 -13
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +175 -25
- package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +62 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +2 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +4 -1
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +1 -0
- package/node_modules/pi-lens/dist/clients/effective-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +26 -1
- package/node_modules/pi-lens/dist/clients/file-role.js +21 -21
- package/node_modules/pi-lens/dist/clients/file-utils.js +156 -10
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +56 -9
- package/node_modules/pi-lens/dist/clients/format-service.js +39 -21
- package/node_modules/pi-lens/dist/clients/formatters.js +60 -13
- package/node_modules/pi-lens/dist/clients/generation-guard.js +2 -2
- package/node_modules/pi-lens/dist/clients/git-guard.js +11 -3
- package/node_modules/pi-lens/dist/clients/indent-retarget.js +78 -8
- package/node_modules/pi-lens/dist/clients/installer/index.js +333 -114
- package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +7 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +20 -10
- package/node_modules/pi-lens/dist/clients/language-profile.js +23 -1
- package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +4 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +12 -3
- package/node_modules/pi-lens/dist/clients/lens-events.js +2 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +79 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +25 -21
- package/node_modules/pi-lens/dist/clients/lsp/config.js +2 -2
- package/node_modules/pi-lens/dist/clients/lsp/index.js +7 -0
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +16 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +5 -3
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +12 -8
- package/node_modules/pi-lens/dist/clients/mcp/session.js +36 -4
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +24 -7
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +40 -2
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +23 -3
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +110 -15
- package/node_modules/pi-lens/dist/clients/path-utils.js +123 -3
- package/node_modules/pi-lens/dist/clients/performance-report.js +5 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +74 -5
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +37 -5
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +59 -3
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +45 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +70 -11
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +147 -9
- package/node_modules/pi-lens/dist/clients/ruff-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +33 -5
- package/node_modules/pi-lens/dist/clients/runtime-context.js +6 -2
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +77 -7
- package/node_modules/pi-lens/dist/clients/runtime-session.js +21 -2
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +43 -12
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +330 -85
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -17
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +258 -5
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +6 -0
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +50 -5
- package/node_modules/pi-lens/dist/clients/sg-runner.js +23 -11
- package/node_modules/pi-lens/dist/clients/sgconfig.js +79 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +6 -41
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +43 -0
- package/node_modules/pi-lens/dist/clients/tool-agreement.js +423 -0
- package/node_modules/pi-lens/dist/clients/tool-config.js +50 -0
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +47 -76
- package/node_modules/pi-lens/dist/clients/tool-policy.js +163 -7
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +120 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +127 -189
- package/node_modules/pi-lens/dist/clients/widget-state.js +98 -0
- package/node_modules/pi-lens/dist/clients/word-index.js +5 -2
- package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +7 -0
- package/node_modules/pi-lens/dist/index.js +27416 -24153
- package/node_modules/pi-lens/dist/mcp/server.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +7 -1
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +168 -53
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +244 -72
- package/node_modules/pi-lens/docs/audit1.md +5 -5
- package/node_modules/pi-lens/docs/dependencies.md +11 -0
- package/node_modules/pi-lens/docs/dispositions.md +52 -0
- package/node_modules/pi-lens/docs/environment-variables.md +2 -2
- package/node_modules/pi-lens/docs/features.md +4 -4
- package/node_modules/pi-lens/docs/globalconfig.md +3 -1
- package/node_modules/pi-lens/docs/language-coverage.md +1 -0
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +53 -94
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +43 -38
- package/node_modules/pi-lens/docs/pi-lens-retro.md +97 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +53 -66
- package/node_modules/pi-lens/docs/release-qa-baseline.md +22 -0
- package/node_modules/pi-lens/docs/settings.md +7 -4
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
- package/node_modules/pi-lens/docs/usage.md +2 -0
- package/node_modules/pi-lens/package.json +1 -1
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +40 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +15 -0
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +7 -0
- package/package.json +6 -17
- package/examples/pi-footer.json +0 -275
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +0 -70
- package/node_modules/@czottmann/pi-automode/LICENSE.md +0 -21
- package/node_modules/@czottmann/pi-automode/README.md +0 -215
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +0 -39
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +0 -46
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +0 -60
- package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +0 -6
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +0 -428
- package/node_modules/@czottmann/pi-automode/docs/configuration.md +0 -171
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +0 -178
- package/node_modules/@czottmann/pi-automode/docs/diagnostics.md +0 -90
- package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +0 -160
- package/node_modules/@czottmann/pi-automode/examples/automode.local.json +0 -44
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +0 -692
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +0 -852
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +0 -904
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +0 -228
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +0 -954
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +0 -429
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/log.ts +0 -173
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/model-selector.ts +0 -113
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/model.ts +0 -13
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +0 -297
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +0 -623
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/state.ts +0 -102
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/transcript.ts +0 -236
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +0 -205
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/utils.ts +0 -54
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +0 -26
- package/node_modules/@czottmann/pi-automode/package.json +0 -61
- package/node_modules/@czottmann/pi-automode/skills/automode-diagnostics/SKILL.md +0 -63
- package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +0 -376
- package/node_modules/@luxusai/pi-hindsight/README.md +0 -92
- package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +0 -56
- package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +0 -169
- package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +0 -107
- package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +0 -89
- package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +0 -189
- 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 +0 -54
- package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +0 -75
- package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +0 -300
- package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +0 -158
- package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +0 -164
- package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +0 -139
- package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +0 -74
- package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +0 -261
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +0 -151
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +0 -18
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +0 -46
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +0 -383
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +0 -240
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +0 -176
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +0 -178
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +0 -41
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +0 -386
- package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +0 -39
- package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +0 -34
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +0 -140
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +0 -61
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +0 -925
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +0 -247
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +0 -547
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +0 -480
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +0 -182
- package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +0 -86
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +0 -1010
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +0 -175
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +0 -425
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +0 -210
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +0 -817
- package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +0 -25
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +0 -319
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +0 -196
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +0 -189
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +0 -65
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +0 -260
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +0 -244
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +0 -59
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +0 -82
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +0 -45
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +0 -331
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +0 -354
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +0 -66
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +0 -132
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +0 -228
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +0 -74
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +0 -16
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +0 -648
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +0 -105
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +0 -68
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +0 -71
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +0 -13
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +0 -162
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +0 -131
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +0 -104
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +0 -37
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +0 -893
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +0 -35
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +0 -177
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +0 -7
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +0 -21
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +0 -112
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +0 -111
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +0 -214
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +0 -70
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +0 -392
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +0 -45
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +0 -9
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +0 -860
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +0 -105
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +0 -189
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +0 -299
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +0 -201
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +0 -47
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +0 -239
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +0 -50
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +0 -259
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +0 -77
- package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +0 -534
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +0 -319
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +0 -325
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +0 -42
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +0 -244
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +0 -56
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +0 -50
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +0 -167
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +0 -207
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +0 -120
- package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +0 -8
- package/node_modules/@luxusai/pi-hindsight/package.json +0 -118
- package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +0 -75
|
@@ -969,7 +969,8 @@ async function callTool(name, args) {
|
|
|
969
969
|
summaryLines.push(truncationNotice);
|
|
970
970
|
// #1107 phase 2: same "reached the seam but nothing rendered it" gap as
|
|
971
971
|
// #784's scanTruncationNotice, for the generated-name skip counters.
|
|
972
|
-
|
|
972
|
+
// #2535: render the MCP-callable tool names on this route.
|
|
973
|
+
const skipNotice = generatedSkipNotice(snapshot, "mcp");
|
|
973
974
|
if (skipNotice)
|
|
974
975
|
summaryLines.push(skipNotice);
|
|
975
976
|
return toolText(summaryLines.join("\n"), {
|
|
@@ -1375,7 +1376,9 @@ async function callTool(name, args) {
|
|
|
1375
1376
|
if (name === "pilens_diagnostics") {
|
|
1376
1377
|
const cwd = typeof args.cwd === "string" ? args.cwd : DEFAULT_CWD;
|
|
1377
1378
|
await ensureReady(cwd);
|
|
1378
|
-
const out = (await lensDiagnosticsTool.execute("mcp", args, new AbortController().signal, undefined,
|
|
1379
|
+
const out = (await lensDiagnosticsTool.execute("mcp", args, new AbortController().signal, undefined,
|
|
1380
|
+
// #2535: the shared tool renders host-callable advisory names.
|
|
1381
|
+
{ cwd, host: "mcp" }));
|
|
1379
1382
|
return out;
|
|
1380
1383
|
}
|
|
1381
1384
|
if (name === "pilens_latency") {
|
|
@@ -46,6 +46,7 @@ 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
48
|
import { getFileDiagnostics, } from "../clients/widget-state.js";
|
|
49
|
+
import { resolveLensToolName } from "../clients/tool-config.js";
|
|
49
50
|
const DISPOSITIONS = [
|
|
50
51
|
"false-positive",
|
|
51
52
|
"suppress",
|
|
@@ -179,7 +180,12 @@ getIdentity) {
|
|
|
179
180
|
name: "lens_diagnostic_mark",
|
|
180
181
|
label: "Mark Diagnostic",
|
|
181
182
|
description: "Record a disposition for a diagnostic. Exact reported identity is required; suppress re-anchors against live diagnostics and writes an inline ignore comment, apply multiple suppressions bottom-up, and defer is session-only. Example: mark a false positive with its reported file, line, rule, and message.",
|
|
182
|
-
|
|
183
|
+
// #2535 F3: this snippet registers on pi only (`lens_diagnostic_mark`
|
|
184
|
+
// is declared pi-only in PI_ONLY_TOOL_REASONS — MCP has no such
|
|
185
|
+
// tool), so the host is pinned, not defaulted. The fallback restates
|
|
186
|
+
// the same pi canonical and can only fire if the registry regresses,
|
|
187
|
+
// which the adapter-aware guard reds on first.
|
|
188
|
+
promptSnippet: `Use ${resolveLensToolName("lens_diagnostic_mark", "pi") ?? "lens_diagnostic_mark"} to dismiss a false-positive, suppress a won't-fix, defer, or flag a finding to fix later`,
|
|
183
189
|
parameters: Type.Object({
|
|
184
190
|
filePath: Type.String({
|
|
185
191
|
description: "The file the diagnostic was reported on (relative or absolute).",
|
|
@@ -16,16 +16,15 @@ import { Type } from "../clients/deps/typebox.js";
|
|
|
16
16
|
import { anchorsForDiagnostic, applyDispositions, applyWeakDispositions, hasAnyDispositionMarks, hasStrictDispositionMarks, getDisposition, } from "../clients/diagnostic-dispositions.js";
|
|
17
17
|
import { DEPENDENCY_DRIFT_MAX_DELIVERIES } from "../clients/blocker-freshness.js";
|
|
18
18
|
import { freshnessFromMtime } from "../clients/freshness.js";
|
|
19
|
-
import {
|
|
19
|
+
import { applyFindingPolicy, loadProjectRulePolicyMap, } from "../clients/dispatch/finding-policy.js";
|
|
20
20
|
import { gateFindingsByPathFreshness } from "../clients/advisory-provenance.js";
|
|
21
21
|
import { markUnreconciledFindings } from "../clients/finding-delivery-gate.js";
|
|
22
22
|
import { normalizeRuleId } from "../clients/dispatch/rule-id-normalize.js";
|
|
23
|
-
import { applyRulePolicy,
|
|
24
|
-
import { loadPiLensProjectConfig } from "../clients/project-lens-config.js";
|
|
23
|
+
import { applyRulePolicy, } from "../clients/dispatch/rule-policy.js";
|
|
25
24
|
import { compactRenderResult } from "./render-compact.js";
|
|
26
25
|
import { combineAbortSignals } from "../clients/deadline-utils.js";
|
|
27
26
|
import { getProjectIgnoreMatcher } from "../clients/file-utils.js";
|
|
28
|
-
import { isAtOrAboveHomeDir, normalizeEphemeralMapKey, normalizeFilePath, } from "../clients/path-utils.js";
|
|
27
|
+
import { isAtOrAboveHomeDir, normalizeEphemeralMapKey, normalizeFilePath, realpathOrResolve, } from "../clients/path-utils.js";
|
|
29
28
|
import { getLSPService } from "../clients/lsp/index.js";
|
|
30
29
|
import { retireInlineBlockerAndResyncGuard } from "../clients/git-guard.js";
|
|
31
30
|
import { primaryServerId, resolveLspCwdForFile, } from "../clients/lsp/config.js";
|
|
@@ -36,14 +35,15 @@ import { loadProjectDiagnosticsDeltaReport, loadProjectDiagnosticsSnapshot, PROJ
|
|
|
36
35
|
import { formatCacheAgeOld, formatNotRunEntry, } from "../clients/project-diagnostics/extractors.js";
|
|
37
36
|
import { ANALYZER_IDS, fetchFreshProjectDiagnostics, } from "../clients/project-diagnostics/fresh-fetch.js";
|
|
38
37
|
import { loadBootstrapClients } from "../clients/bootstrap.js";
|
|
38
|
+
import { resolveLensToolName, } from "../clients/tool-config.js";
|
|
39
39
|
import { generatedSkipNotice, scanTruncationNotice, } from "../clients/lens-engine.js";
|
|
40
40
|
import { scanProjectDiagnostics } from "../clients/project-diagnostics/scanner.js";
|
|
41
41
|
import { classifyDiagnosticTier, getFileDiagnosticSummaries, reconcileCorrelatedScanDiagnostics, reconcileScanDiagnostics, reconcileStaleWidgetDependencyBlockers, reconcileStaleWidgetFiles, widgetDiagnosticUri, } from "../clients/widget-state.js";
|
|
42
|
-
import { logLatency } from "../clients/latency-logger.js";
|
|
42
|
+
import { claimPhaseOncePerSession, logLatency, } from "../clients/latency-logger.js";
|
|
43
43
|
import { logExtension } from "../clients/extension-log.js";
|
|
44
44
|
import { recordDegradationOnce } from "../clients/degradation-ledger.js";
|
|
45
45
|
import { convertLspDiagnostics } from "../clients/dispatch/utils/lsp-diagnostics.js";
|
|
46
|
-
import { retagAuxiliaryDiagnostics } from "../clients/dispatch/auxiliary-lsp.js";
|
|
46
|
+
import { findAuxiliaryProfileForSource, retagAuxiliaryDiagnostics, } from "../clients/dispatch/auxiliary-lsp.js";
|
|
47
47
|
import { detectFileRole } from "../clients/file-role.js";
|
|
48
48
|
import { STALE_LINE_MARKER } from "../clients/stale-marker.js";
|
|
49
49
|
import { makeProgressReporter, scanningSummaryLine } from "./scan-progress.js";
|
|
@@ -63,9 +63,13 @@ const MAX_PATHS_ENTRIES = MAX_BATCH_FILES;
|
|
|
63
63
|
// trivy, govulncheck, dead-code, knip, jscpd, madge, opengrep, test-runner)
|
|
64
64
|
// when mode=full is called without refreshRunners=cheap/all/cached — the
|
|
65
65
|
// "quick mode" gate that skips the expensive fresh-fetch entirely (see
|
|
66
|
-
// `formatFullMode`'s `analyzersPromise`). One shared
|
|
67
|
-
// identically everywhere it's used
|
|
68
|
-
|
|
66
|
+
// `formatFullMode`'s `analyzersPromise`). One shared function so it renders
|
|
67
|
+
// identically everywhere it's used, naming the tool THIS host can call
|
|
68
|
+
// (#2535 F1 — the shared const named the pi tool on MCP too).
|
|
69
|
+
function notRequestedReason(host) {
|
|
70
|
+
return ("refreshRunners not requested this call (quick mode) — pass " +
|
|
71
|
+
`refreshRunners=cheap/all/cached to ${resolveLensToolName("lens_diagnostics", host) ?? "diagnostics"} mode=full to run it`);
|
|
72
|
+
}
|
|
69
73
|
// Wall-clock ceiling for the whole mode=full scan. Even with per-file budgets
|
|
70
74
|
// and abort-signal honoring, a pathological state (a language server hanging on
|
|
71
75
|
// spawn/initialize across many files) could otherwise stall the tool
|
|
@@ -314,6 +318,9 @@ captureLspStatusRepaint, getRuntime, isLensGuardEnabled = () => true) {
|
|
|
314
318
|
includeGenerated: Type.Optional(Type.Boolean({
|
|
315
319
|
description: "Include generated-name paths in full scans.",
|
|
316
320
|
})),
|
|
321
|
+
analysisRoot: Type.Optional(Type.String({
|
|
322
|
+
description: "Explicit project directory for heavyweight analyzers; it must exist and resolve strictly below the home directory.",
|
|
323
|
+
})),
|
|
317
324
|
severity: Type.Optional(Type.String({
|
|
318
325
|
enum: [...LSP_SEVERITY_FILTERS],
|
|
319
326
|
description: "Filter by severity threshold (default: all): error shows errors; warning includes errors and warnings; information includes errors, warnings, and information; hint and all show every known tier.",
|
|
@@ -464,6 +471,10 @@ captureLspStatusRepaint, getRuntime, isLensGuardEnabled = () => true) {
|
|
|
464
471
|
pathsScope,
|
|
465
472
|
nextWriteIndex,
|
|
466
473
|
runtime: getRuntime?.(),
|
|
474
|
+
analysisRoot: typeof params.analysisRoot === "string"
|
|
475
|
+
? params.analysisRoot
|
|
476
|
+
: undefined,
|
|
477
|
+
host: ctx.host ?? "pi",
|
|
467
478
|
});
|
|
468
479
|
}
|
|
469
480
|
return formatDeltaMode(cacheManager, cwd, severity, pathsScope);
|
|
@@ -643,17 +654,6 @@ function filterDeltaReportDispositions(report, cwd, policyMap) {
|
|
|
643
654
|
return report;
|
|
644
655
|
return { ...report, diagnostics: policyKept };
|
|
645
656
|
}
|
|
646
|
-
/**
|
|
647
|
-
* Load the rule-policy map from a project's `.pi-lens.json` — same source the
|
|
648
|
-
* per-edit dispatch path uses, so a project's policy applies consistently
|
|
649
|
-
* across every output surface. `loadPiLensProjectConfig` is mtime-cached, and
|
|
650
|
-
* the map is filtered to entries that actually have a `disable`/`select` list
|
|
651
|
-
* (thresholds are handled elsewhere), so the common case returns undefined and
|
|
652
|
-
* the filter step is skipped outright.
|
|
653
|
-
*/
|
|
654
|
-
function loadProjectRulePolicyMap(cwd) {
|
|
655
|
-
return rulePolicyMapFromConfig(loadPiLensProjectConfig(cwd).rules);
|
|
656
|
-
}
|
|
657
657
|
/**
|
|
658
658
|
* #1634 review round: `formatDeltaMode` re-serves the `actionable-warnings`/
|
|
659
659
|
* `code-quality-warnings` caches verbatim — each cited `file:line`, no
|
|
@@ -1048,7 +1048,13 @@ function lspDiagnosticToWidget(diagnostic) {
|
|
|
1048
1048
|
line: diagnostic.range.start.line + 1,
|
|
1049
1049
|
col: diagnostic.range.start.character + 1,
|
|
1050
1050
|
rule,
|
|
1051
|
-
|
|
1051
|
+
// #3041: keep auxiliary provenance. The footer-reconcile loop above already
|
|
1052
|
+
// gives a swept aux finding its real tool id via `retagAuxiliaryDiagnostics`
|
|
1053
|
+
// (#692); this second conversion of the SAME raw diagnostics did not, and
|
|
1054
|
+
// dispositions are anchored by `tool` — so a `false-positive`/`suppress`
|
|
1055
|
+
// mark recorded against the per-edit `ast-grep` finding never matched the
|
|
1056
|
+
// `lsp`-labelled copy mode=full renders.
|
|
1057
|
+
tool: findAuxiliaryProfileForSource(diagnostic.source)?.tool ?? "lsp",
|
|
1052
1058
|
};
|
|
1053
1059
|
}
|
|
1054
1060
|
function projectDiagnosticToWidget(diagnostic, filePath) {
|
|
@@ -1085,6 +1091,30 @@ function diagnosticDedupKey(filePath, diagnostic) {
|
|
|
1085
1091
|
function runnerIdOf(diagnostic) {
|
|
1086
1092
|
return diagnostic.tool ?? diagnostic.rule?.split(":", 1)[0] ?? "";
|
|
1087
1093
|
}
|
|
1094
|
+
/**
|
|
1095
|
+
* The one project-runner retirement decision. Coverage is authoritative when
|
|
1096
|
+
* present for the runner; the older id-only arm is used only when absent.
|
|
1097
|
+
*/
|
|
1098
|
+
export function runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds, authoritativeCoverage) {
|
|
1099
|
+
const runnerId = runnerIdOf(diagnostic);
|
|
1100
|
+
const coverage = (authoritativeCoverage ?? []).filter((entry) => entry.runnerId === runnerId && entry.files.size > 0);
|
|
1101
|
+
if (coverage.length === 0) {
|
|
1102
|
+
return authoritativeRunnerIds?.has(runnerId) ? "retire" : "keep";
|
|
1103
|
+
}
|
|
1104
|
+
const realFilePath = realpathOrResolve(filePath);
|
|
1105
|
+
for (const entry of coverage) {
|
|
1106
|
+
const root = entry.root;
|
|
1107
|
+
const relative = path.relative(root, realFilePath);
|
|
1108
|
+
const underRoot = relative === "" ||
|
|
1109
|
+
(!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
1110
|
+
if (!underRoot)
|
|
1111
|
+
continue;
|
|
1112
|
+
if (entry.files.has(realFilePath)) {
|
|
1113
|
+
return "retire";
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return "keep";
|
|
1117
|
+
}
|
|
1088
1118
|
function summarizeDiagnostics(filePath, diagnostics, hasFinalSnapshot) {
|
|
1089
1119
|
let blocking = 0;
|
|
1090
1120
|
let errors = 0;
|
|
@@ -1292,7 +1322,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
1292
1322
|
* additive behavior (fail-open: unconfirmed/timed-out sweeps never retire
|
|
1293
1323
|
* widget state they did not actually re-check).
|
|
1294
1324
|
*/
|
|
1295
|
-
authoritativeLspFiles, authoritativeRunnerIds) {
|
|
1325
|
+
authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage) {
|
|
1296
1326
|
const byFile = new Map();
|
|
1297
1327
|
const seen = new Set();
|
|
1298
1328
|
for (const summary of widgetSummaries) {
|
|
@@ -1307,7 +1337,7 @@ authoritativeLspFiles, authoritativeRunnerIds) {
|
|
|
1307
1337
|
continue;
|
|
1308
1338
|
const retained = summary.diagnostics ?? [];
|
|
1309
1339
|
const diagnostics = retained
|
|
1310
|
-
.filter((diagnostic) =>
|
|
1340
|
+
.filter((diagnostic) => runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds, authoritativeRunnerCoverage) !== "retire")
|
|
1311
1341
|
.map((d) => ({ ...d }));
|
|
1312
1342
|
byFile.set(filePath,
|
|
1313
1343
|
// #2154 v4: when the filter retires rows, the stored tallies describe
|
|
@@ -1377,17 +1407,20 @@ async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
|
|
|
1377
1407
|
? summary
|
|
1378
1408
|
: summarizeDiagnostics(summary.filePath, policyKept, summary.hasFinalSnapshot);
|
|
1379
1409
|
}
|
|
1380
|
-
|
|
1381
|
-
//
|
|
1382
|
-
//
|
|
1383
|
-
// diagnostics from a fresh LSP sweep/project scan that never
|
|
1384
|
-
// through
|
|
1385
|
-
|
|
1386
|
-
//
|
|
1387
|
-
//
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1410
|
+
// #690/#3088: inline `pi-lens-ignore` → the same false-positive/
|
|
1411
|
+
// suppress/defer disposition filter the per-edit dispatch path applies
|
|
1412
|
+
// (dispatcher.ts) → the project's `.pi-lens.json` rule policy. mode=full
|
|
1413
|
+
// merges in diagnostics from a fresh LSP sweep/project scan that never
|
|
1414
|
+
// went through the dispatch path, so without this a disposed finding
|
|
1415
|
+
// reappears here. #3088 folded the three calls onto the shared
|
|
1416
|
+
// `applyFindingPolicy` seam, which the `source=lsp` probe lane now calls
|
|
1417
|
+
// too — one stack, one order, for every model-facing surface.
|
|
1418
|
+
const { kept: policyKept } = applyFindingPolicy(summary.diagnostics, {
|
|
1419
|
+
cwd,
|
|
1420
|
+
filePath: summary.filePath,
|
|
1421
|
+
content,
|
|
1422
|
+
policyMap,
|
|
1423
|
+
});
|
|
1391
1424
|
// Tag `flagged` diagnostics for the render loop (formatAllMode). Content
|
|
1392
1425
|
// is already in hand here (unlike mode=all/delta's cache-only path), so
|
|
1393
1426
|
// this is the one place the tag can be computed without adding I/O to
|
|
@@ -1458,9 +1491,30 @@ async function getProjectDiagnosticsSnapshotForFullMode(cwd, options) {
|
|
|
1458
1491
|
// edited/deleted since the scan so a stale entry isn't replayed (#298). A
|
|
1459
1492
|
// fresh scan (above) is current by construction and needs no reconcile.
|
|
1460
1493
|
const cached = loadProjectDiagnosticsSnapshot(cwd);
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1494
|
+
if (!cached)
|
|
1495
|
+
return undefined;
|
|
1496
|
+
const reconciled = reconcileProjectDiagnosticsSnapshot(cached);
|
|
1497
|
+
// #2154: what this gate DROPS was invisible — the count was computed and
|
|
1498
|
+
// thrown away, so a session that silently retired another session's rows
|
|
1499
|
+
// (the whole point of the content axis added this round) left no record
|
|
1500
|
+
// of having done so. Bounded by construction: at most one row per
|
|
1501
|
+
// mode=full call, and only when rows were actually retired — the shape
|
|
1502
|
+
// `lsp_authoritative_widget_retire` uses for the sibling arm.
|
|
1503
|
+
if (reconciled.staleDropped > 0) {
|
|
1504
|
+
logLatency({
|
|
1505
|
+
type: "phase",
|
|
1506
|
+
toolName: "lens_diagnostics",
|
|
1507
|
+
filePath: cwd,
|
|
1508
|
+
phase: "project_snapshot_rows_retired",
|
|
1509
|
+
durationMs: 0,
|
|
1510
|
+
metadata: {
|
|
1511
|
+
files: reconciled.staleDropped,
|
|
1512
|
+
rows: cached.diagnostics.length - reconciled.snapshot.diagnostics.length,
|
|
1513
|
+
scannedAt: cached.scannedAt,
|
|
1514
|
+
},
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
return reconciled.snapshot;
|
|
1464
1518
|
}
|
|
1465
1519
|
return undefined;
|
|
1466
1520
|
}
|
|
@@ -1479,6 +1533,9 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1479
1533
|
};
|
|
1480
1534
|
}
|
|
1481
1535
|
const { signal, pathsScope, nextWriteIndex } = options;
|
|
1536
|
+
// #2535: advisories name the delivery host's callable tools; pi callers
|
|
1537
|
+
// omit host and keep the pi spelling.
|
|
1538
|
+
const host = options.host ?? "pi";
|
|
1482
1539
|
const includeFile = createScopedFileFilter(cwd, pathsScope);
|
|
1483
1540
|
// `paths` (#461): route the active scans at exactly the requested files
|
|
1484
1541
|
// instead of walking the whole project. Three cases:
|
|
@@ -1507,11 +1564,13 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1507
1564
|
const analyzersPromise = projectRunnersRequested
|
|
1508
1565
|
? loadBootstrapClients().then((clients) => fetchFreshProjectDiagnostics(cacheManager, cwd, clients, signal, {
|
|
1509
1566
|
runtime: options.runtime,
|
|
1567
|
+
analysisRoot: options.analysisRoot,
|
|
1510
1568
|
}))
|
|
1511
1569
|
: Promise.resolve({
|
|
1512
1570
|
diagnostics: [],
|
|
1513
1571
|
runners: [],
|
|
1514
1572
|
analyzed: [],
|
|
1573
|
+
authoritativeCoverage: [],
|
|
1515
1574
|
// #1623: every heavyweight analyzer is ELIGIBLE for this project but
|
|
1516
1575
|
// this call never asked for it (refreshRunners wasn't cheap/all/
|
|
1517
1576
|
// cached) — the expensive fetch below deliberately never runs in
|
|
@@ -1521,7 +1580,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1521
1580
|
// truth for which lanes this covers — reuse it rather than
|
|
1522
1581
|
// hand-listing ids here.
|
|
1523
1582
|
cold: [...ANALYZER_IDS],
|
|
1524
|
-
coldReasons: Object.fromEntries(ANALYZER_IDS.map((id) => [id,
|
|
1583
|
+
coldReasons: Object.fromEntries(ANALYZER_IDS.map((id) => [id, notRequestedReason(host)])),
|
|
1525
1584
|
failed: [],
|
|
1526
1585
|
timings: {},
|
|
1527
1586
|
});
|
|
@@ -1540,6 +1599,17 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1540
1599
|
}),
|
|
1541
1600
|
analyzersPromise,
|
|
1542
1601
|
]);
|
|
1602
|
+
if (extracted.analysisRootError) {
|
|
1603
|
+
return {
|
|
1604
|
+
content: [{ type: "text", text: extracted.analysisRootError }],
|
|
1605
|
+
isError: true,
|
|
1606
|
+
details: {
|
|
1607
|
+
mode: "full",
|
|
1608
|
+
analysisRootError: extracted.analysisRootError,
|
|
1609
|
+
analysisRootValidation: extracted.analysisRootValidation,
|
|
1610
|
+
},
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1543
1613
|
const aborted = signal?.aborted ?? false;
|
|
1544
1614
|
// #1640: before ANY consumer sees them — the footer reconcile, the widget
|
|
1545
1615
|
// merge, the rendered counts — demote TypeScript errors on files tsserver
|
|
@@ -1662,6 +1732,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1662
1732
|
// here; a second list of "which ids don't count" would be the mirror this
|
|
1663
1733
|
// repo's single-source-of-truth rule forbids.
|
|
1664
1734
|
const authoritativeRunnerIds = new Set(extracted.analyzed ?? []);
|
|
1735
|
+
const authoritativeRunnerCoverage = extracted.authoritativeCoverage ?? [];
|
|
1665
1736
|
const foldedProjectSnapshot = foldExtraDiagnosticsIntoSnapshot(scannedSnapshot, extracted.diagnostics.filter((d) => includeFile(d.filePath)), extracted.runners, cwd);
|
|
1666
1737
|
const projectSnapshot = applyProjectRulePolicy(foldedProjectSnapshot, policyMap);
|
|
1667
1738
|
const projectDelta = applyProjectRulePolicy(filterProjectDiagnosticsDeltaReport(loadProjectDiagnosticsDeltaReport(cwd), includeFile), policyMap);
|
|
@@ -1691,10 +1762,18 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1691
1762
|
// LSP sibling above — a retirement nobody can see is how a regression
|
|
1692
1763
|
// deletes findings silently. Bounded by construction: at most one row per
|
|
1693
1764
|
// mode=full call, and only when rows were actually retired.
|
|
1765
|
+
const retiredRunnerCounts = new Map();
|
|
1694
1766
|
const runnerRetiredRows = getFileDiagnosticSummaries()
|
|
1695
1767
|
.filter((summary) => includeFile(summary.filePath))
|
|
1696
1768
|
.reduce((total, summary) => total +
|
|
1697
|
-
(summary.diagnostics ?? []).filter((diagnostic) =>
|
|
1769
|
+
(summary.diagnostics ?? []).filter((diagnostic) => {
|
|
1770
|
+
const retired = runnerRetirementDecision(diagnostic, summary.filePath, authoritativeRunnerIds, authoritativeRunnerCoverage) === "retire";
|
|
1771
|
+
if (retired) {
|
|
1772
|
+
const runnerId = runnerIdOf(diagnostic);
|
|
1773
|
+
retiredRunnerCounts.set(runnerId, (retiredRunnerCounts.get(runnerId) ?? 0) + 1);
|
|
1774
|
+
}
|
|
1775
|
+
return retired;
|
|
1776
|
+
}).length, 0);
|
|
1698
1777
|
if (runnerRetiredRows > 0) {
|
|
1699
1778
|
logLatency({
|
|
1700
1779
|
type: "phase",
|
|
@@ -1703,11 +1782,31 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1703
1782
|
durationMs: 0,
|
|
1704
1783
|
metadata: {
|
|
1705
1784
|
rows: runnerRetiredRows,
|
|
1706
|
-
runners: [...
|
|
1785
|
+
runners: [...retiredRunnerCounts.keys()].join(","),
|
|
1786
|
+
coverage: authoritativeRunnerCoverage.map((entry) => ({
|
|
1787
|
+
runnerId: entry.runnerId,
|
|
1788
|
+
root: entry.root,
|
|
1789
|
+
files: entry.files.size,
|
|
1790
|
+
})),
|
|
1791
|
+
},
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
for (const entry of authoritativeRunnerCoverage) {
|
|
1795
|
+
if (!claimPhaseOncePerSession("runner_coverage_retired", entry.runnerId)) {
|
|
1796
|
+
continue;
|
|
1797
|
+
}
|
|
1798
|
+
logLatency({
|
|
1799
|
+
type: "phase",
|
|
1800
|
+
phase: "runner_coverage_retired",
|
|
1801
|
+
filePath: "",
|
|
1802
|
+
durationMs: 0,
|
|
1803
|
+
metadata: {
|
|
1804
|
+
runnerId: entry.runnerId,
|
|
1805
|
+
count: retiredRunnerCounts.get(entry.runnerId) ?? 0,
|
|
1707
1806
|
},
|
|
1708
1807
|
});
|
|
1709
1808
|
}
|
|
1710
|
-
let summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds), cwd, policyMap);
|
|
1809
|
+
let summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage), cwd, policyMap);
|
|
1711
1810
|
if (unreconciledFiles.size > 0) {
|
|
1712
1811
|
summaries = summaries.map((summary) => unreconciledFiles.has(path.resolve(summary.filePath))
|
|
1713
1812
|
? summarizeDiagnostics(summary.filePath, markUnreconciledFindings(summary.diagnostics), summary.hasFinalSnapshot)
|
|
@@ -1831,6 +1930,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1831
1930
|
// isn't (a re-run may well complete for that analyzer).
|
|
1832
1931
|
const abortedIds = new Set(extracted.abortedIds ?? []);
|
|
1833
1932
|
const genuinelyColdIds = extracted.cold.filter((id) => !abortedIds.has(id));
|
|
1933
|
+
const partialIds = extracted.partial ?? [];
|
|
1834
1934
|
// #747: an unsafe analysis root (cwd at/above $HOME) skips ALL heavyweight
|
|
1835
1935
|
// analyzers before anything spawns — rendering that as the per-analyzer
|
|
1836
1936
|
// "not applicable / unavailable" list would send the caller chasing seven
|
|
@@ -1842,7 +1942,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1842
1942
|
// shape). Single formatter (extractors.ts) so this note's wording can't
|
|
1843
1943
|
// drift from any other caller that renders the same `cold` list.
|
|
1844
1944
|
// #1623 fix-round F5: the "not requested" (quick-mode) batch shares ONE
|
|
1845
|
-
// reason (`
|
|
1945
|
+
// reason (`notRequestedReason`) across every id — `formatNotRunEntry`
|
|
1846
1946
|
// repeating that same ~130-char sentence per id makes the note nearly
|
|
1847
1947
|
// unreadable, and the "not applicable / unavailable this run" header
|
|
1848
1948
|
// below is a dishonest label for it: these lanes ARE applicable and
|
|
@@ -1852,14 +1952,21 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1852
1952
|
// id's reason really does differ (not a git repo vs binary unavailable
|
|
1853
1953
|
// vs retry cooldown, ...).
|
|
1854
1954
|
const coldNote = extracted.unsafeRoot
|
|
1855
|
-
? `\n\nheavyweight analyzers skipped: the
|
|
1856
|
-
:
|
|
1857
|
-
? `\n\
|
|
1858
|
-
: genuinelyColdIds.length > 0
|
|
1859
|
-
? `\n\
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1955
|
+
? `\n\nheavyweight analyzers skipped: the analysis root resolves at or above the home directory, so a fresh knip/jscpd/madge/gitleaks/govulncheck/trivy/dead-code scan would walk every unrelated tree under it. Supply a project directory below the home ceiling. Absence of their findings is NOT a clean verdict.`
|
|
1956
|
+
: extracted.analysisRootError
|
|
1957
|
+
? `\n\nheavyweight analyzers skipped: ${extracted.analysisRootError}. Supply an existing project directory below the home ceiling. Absence of their findings is NOT a clean verdict.`
|
|
1958
|
+
: !projectRunnersRequested && genuinelyColdIds.length > 0
|
|
1959
|
+
? `\n\nnot run this call (quick mode): ${genuinelyColdIds.join(", ")}. ${notRequestedReason(host)}. Absence of their findings is NOT a clean verdict.`
|
|
1960
|
+
: genuinelyColdIds.length > 0
|
|
1961
|
+
? `\n\ncold (not applicable / unavailable this run): ${genuinelyColdIds
|
|
1962
|
+
.map((id) => formatNotRunEntry(id, extracted.coldReasons))
|
|
1963
|
+
.join(", ")}. These analyzers have not contributed to this result — absence of their findings is NOT a clean verdict.`
|
|
1964
|
+
: "";
|
|
1965
|
+
const partialNote = partialIds.length > 0
|
|
1966
|
+
? `\n\n⚠ partial coverage (findings included): ${partialIds
|
|
1967
|
+
.map((id) => `${id} — ${extracted.partialReasons?.[id] ?? "coverage is incomplete"}`)
|
|
1968
|
+
.join(", ")}. Coverage is incomplete, so absence of findings is NOT a clean verdict.`
|
|
1969
|
+
: "";
|
|
1863
1970
|
// #1004: unlike every other analyzer above (knip/jscpd/madge/gitleaks/
|
|
1864
1971
|
// govulncheck/opengrep/trivy/dead-code all run a FRESH whole-project scan
|
|
1865
1972
|
// per the fresh-fetch.ts header, so "clean" there really does mean "the
|
|
@@ -1923,7 +2030,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1923
2030
|
// #1107 phase 2: same "reached the seam, nothing rendered it" gap as #784
|
|
1924
2031
|
// above, for the generated-name/dir skip counters.
|
|
1925
2032
|
const generatedSkipNoticeText = projectSnapshot
|
|
1926
|
-
? generatedSkipNotice(projectSnapshot)
|
|
2033
|
+
? generatedSkipNotice(projectSnapshot, host)
|
|
1927
2034
|
: undefined;
|
|
1928
2035
|
const generatedSkipNote = generatedSkipNoticeText
|
|
1929
2036
|
? `\n\n${generatedSkipNoticeText}`
|
|
@@ -1944,7 +2051,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1944
2051
|
? Date.parse(rawProjectSnapshot.scannedAt)
|
|
1945
2052
|
: undefined;
|
|
1946
2053
|
const cheapScanStatusNote = !projectRunnersRequested
|
|
1947
|
-
? `\n\ncheap project scan (tree-sitter/fact-rules/ast-grep): not run this call (${
|
|
2054
|
+
? `\n\ncheap project scan (tree-sitter/fact-rules/ast-grep): not run this call (${notRequestedReason(host)}).`
|
|
1948
2055
|
: options.refreshRunners === "cached"
|
|
1949
2056
|
? cheapScanScannedAtMs !== undefined &&
|
|
1950
2057
|
Number.isFinite(cheapScanScannedAtMs)
|
|
@@ -1989,6 +2096,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
1989
2096
|
details: {
|
|
1990
2097
|
...result.details,
|
|
1991
2098
|
coldRunners: extracted.cold,
|
|
2099
|
+
partialRunners: partialIds,
|
|
1992
2100
|
// #1623: the specific reason each cold id was skipped (single source
|
|
1993
2101
|
// of truth: extractors.ts's `formatNotRunEntry` renders the same map
|
|
1994
2102
|
// into the text note above) — lets a caller check WHY without parsing
|
|
@@ -2007,7 +2115,11 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
2007
2115
|
// #747: true when the fresh fetch refused an at-or-above-$HOME root —
|
|
2008
2116
|
// lets a caller distinguish "skipped for safety" from per-analyzer
|
|
2009
2117
|
// cold reasons without parsing the text note.
|
|
2010
|
-
|
|
2118
|
+
// This is the fetch seam's explicit-root policy. The cwd walk below is
|
|
2119
|
+
// intentionally separate: it answers a different root question.
|
|
2120
|
+
analyzersUnsafeRoot: extracted.analysisRootValidation?.state === "unsafe" ||
|
|
2121
|
+
extracted.unsafeRoot === true,
|
|
2122
|
+
analysisRootValidation: extracted.analysisRootValidation,
|
|
2011
2123
|
// #747: true when the cwd resolved at/above $HOME so the cheap project
|
|
2012
2124
|
// scan and the LSP workspace sweep both refused to walk — lets a caller
|
|
2013
2125
|
// distinguish "walked nothing for safety" from a genuinely clean sweep.
|
|
@@ -2067,6 +2179,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
2067
2179
|
unconfirmedLspNote +
|
|
2068
2180
|
auxiliaryCoverageNote +
|
|
2069
2181
|
lspPrimaryVsAuxiliaryNote +
|
|
2182
|
+
partialNote +
|
|
2070
2183
|
coldNote +
|
|
2071
2184
|
testRunnerEditScopedNote +
|
|
2072
2185
|
failedNote +
|
|
@@ -2086,6 +2199,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
2086
2199
|
}
|
|
2087
2200
|
if (missingNote ||
|
|
2088
2201
|
coldNote ||
|
|
2202
|
+
partialNote ||
|
|
2089
2203
|
testRunnerEditScopedNote ||
|
|
2090
2204
|
failedNote ||
|
|
2091
2205
|
dispositionSuppressedNote ||
|
|
@@ -2107,6 +2221,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager, options =
|
|
|
2107
2221
|
unconfirmedLspNote +
|
|
2108
2222
|
auxiliaryCoverageNote +
|
|
2109
2223
|
lspPrimaryVsAuxiliaryNote +
|
|
2224
|
+
partialNote +
|
|
2110
2225
|
coldNote +
|
|
2111
2226
|
testRunnerEditScopedNote +
|
|
2112
2227
|
failedNote +
|