@herbertgao/pi-extensions 2026.8.3 → 2026.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -4
- package/examples/pi-footer.json +275 -0
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +5 -8
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
- package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +15 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
- package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
- package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
- package/node_modules/@narumitw/pi-btw/README.md +8 -7
- package/node_modules/@narumitw/pi-btw/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/src/menu.ts +1 -0
- package/node_modules/pi-footer/CHANGELOG.md +145 -0
- package/node_modules/pi-footer/LICENSE +21 -0
- package/node_modules/pi-footer/README.md +354 -0
- package/node_modules/pi-footer/package.json +68 -0
- package/node_modules/pi-footer/src/cache.ts +106 -0
- package/node_modules/pi-footer/src/colors.ts +237 -0
- package/node_modules/pi-footer/src/config.ts +202 -0
- package/node_modules/pi-footer/src/event-widgets.ts +41 -0
- package/node_modules/pi-footer/src/extension-statuses.ts +102 -0
- package/node_modules/pi-footer/src/git.ts +135 -0
- package/node_modules/pi-footer/src/index.ts +268 -0
- package/node_modules/pi-footer/src/metrics.ts +141 -0
- package/node_modules/pi-footer/src/presets.ts +383 -0
- package/node_modules/pi-footer/src/render.ts +114 -0
- package/node_modules/pi-footer/src/separators.ts +52 -0
- package/node_modules/pi-footer/src/types.ts +122 -0
- package/node_modules/pi-footer/src/ui/color-level-confirm.ts +22 -0
- package/node_modules/pi-footer/src/ui/color-options.ts +195 -0
- package/node_modules/pi-footer/src/ui/config-lifecycle.ts +61 -0
- package/node_modules/pi-footer/src/ui/edit-colors.ts +13 -0
- package/node_modules/pi-footer/src/ui/events.ts +35 -0
- package/node_modules/pi-footer/src/ui/extension-status-picker.ts +60 -0
- package/node_modules/pi-footer/src/ui/extension-statuses.ts +73 -0
- package/node_modules/pi-footer/src/ui/fields.ts +252 -0
- package/node_modules/pi-footer/src/ui/global-menu.ts +126 -0
- package/node_modules/pi-footer/src/ui/helpers.ts +44 -0
- package/node_modules/pi-footer/src/ui/layout.ts +17 -0
- package/node_modules/pi-footer/src/ui/line-list.ts +19 -0
- package/node_modules/pi-footer/src/ui/model.ts +64 -0
- package/node_modules/pi-footer/src/ui/navigation.ts +29 -0
- package/node_modules/pi-footer/src/ui/option-edit.ts +93 -0
- package/node_modules/pi-footer/src/ui/overlay-render.ts +103 -0
- package/node_modules/pi-footer/src/ui/screen-context.ts +18 -0
- package/node_modules/pi-footer/src/ui/screen-controller.ts +27 -0
- package/node_modules/pi-footer/src/ui/screen-render.ts +32 -0
- package/node_modules/pi-footer/src/ui/screen-state.ts +20 -0
- package/node_modules/pi-footer/src/ui/screen.ts +243 -0
- package/node_modules/pi-footer/src/ui/screens/add-widget.ts +92 -0
- package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +52 -0
- package/node_modules/pi-footer/src/ui/screens/controller.ts +12 -0
- package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +68 -0
- package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +115 -0
- package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +61 -0
- package/node_modules/pi-footer/src/ui/screens/global.ts +75 -0
- package/node_modules/pi-footer/src/ui/screens/line-list.ts +108 -0
- package/node_modules/pi-footer/src/ui/screens/main.ts +99 -0
- package/node_modules/pi-footer/src/ui/screens/terminal.ts +121 -0
- package/node_modules/pi-footer/src/ui/screens/widget-list.ts +154 -0
- package/node_modules/pi-footer/src/ui/terminal-menu.ts +32 -0
- package/node_modules/pi-footer/src/ui/theme.ts +48 -0
- package/node_modules/pi-footer/src/ui/title-bar.ts +100 -0
- package/node_modules/pi-footer/src/ui/widget-actions.ts +76 -0
- package/node_modules/pi-footer/src/ui.ts +66 -0
- package/node_modules/pi-footer/src/widgets/context.ts +28 -0
- package/node_modules/pi-footer/src/widgets/core/active-tools.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/context-window.ts +24 -0
- package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +19 -0
- package/node_modules/pi-footer/src/widgets/core/cwd.ts +108 -0
- package/node_modules/pi-footer/src/widgets/core/event.ts +34 -0
- package/node_modules/pi-footer/src/widgets/core/external-status.ts +102 -0
- package/node_modules/pi-footer/src/widgets/core/model-provider.ts +20 -0
- package/node_modules/pi-footer/src/widgets/core/model.ts +35 -0
- package/node_modules/pi-footer/src/widgets/core/provider.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/session-name.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/branch.ts +81 -0
- package/node_modules/pi-footer/src/widgets/git/clean.ts +19 -0
- package/node_modules/pi-footer/src/widgets/git/deletions.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/diff.ts +38 -0
- package/node_modules/pi-footer/src/widgets/git/insertions.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/remote.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/root.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/sha.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/staged.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/status.ts +19 -0
- package/node_modules/pi-footer/src/widgets/git/unstaged.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/untracked.ts +17 -0
- package/node_modules/pi-footer/src/widgets/instance.ts +118 -0
- package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +18 -0
- package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +32 -0
- package/node_modules/pi-footer/src/widgets/layout/separator.ts +57 -0
- package/node_modules/pi-footer/src/widgets/layout/spacer.ts +31 -0
- package/node_modules/pi-footer/src/widgets/options.ts +122 -0
- package/node_modules/pi-footer/src/widgets/project/runtime.ts +361 -0
- package/node_modules/pi-footer/src/widgets/registry.ts +223 -0
- package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/compactions.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/elapsed.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/last-activity.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/messages.ts +19 -0
- package/node_modules/pi-footer/src/widgets/session/session-id.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/session-start.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/tool-results.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/total-messages.ts +19 -0
- package/node_modules/pi-footer/src/widgets/session/total-time.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/user-messages.ts +17 -0
- package/node_modules/pi-footer/src/widgets/store.ts +26 -0
- package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +55 -0
- package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +108 -0
- package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +26 -0
- package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +29 -0
- package/node_modules/pi-footer/src/widgets/tokens/context.ts +29 -0
- package/node_modules/pi-footer/src/widgets/tokens/cost.ts +51 -0
- package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +25 -0
- package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +25 -0
- package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +20 -0
- package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +25 -0
- package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +18 -0
- package/node_modules/pi-footer/src/widgets/types.ts +181 -0
- package/node_modules/pi-footer/src/widgets/utils/colors.ts +11 -0
- package/node_modules/pi-footer/src/widgets/utils/context.ts +112 -0
- package/node_modules/pi-footer/src/widgets/utils/session.ts +19 -0
- package/node_modules/pi-footer/src/widgets/utils/token-format.ts +78 -0
- package/node_modules/pi-lens/CHANGELOG.md +2440 -954
- package/node_modules/pi-lens/README.md +13 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
- package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
- package/node_modules/pi-lens/dist/clients/biome-client.js +29 -25
- package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
- package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
- package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
- package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
- package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
- package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +14 -0
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
- package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +347 -75
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +61 -11
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +63 -20
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1085 -681
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +14 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +277 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
- package/node_modules/pi-lens/dist/clients/extension-log.js +139 -0
- package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
- package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
- package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +16 -3
- package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
- package/node_modules/pi-lens/dist/clients/git-guard.js +681 -11
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
- package/node_modules/pi-lens/dist/clients/go-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +8 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
- package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +390 -99
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +31 -54
- package/node_modules/pi-lens/dist/clients/knip-client.js +15 -36
- package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
- package/node_modules/pi-lens/dist/clients/latency-logger.js +23 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
- package/node_modules/pi-lens/dist/clients/lens-events.js +27 -4
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +30 -0
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +493 -48
- package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +86 -0
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
- package/node_modules/pi-lens/dist/clients/lsp/index.js +1807 -780
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +196 -32
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +123 -32
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
- package/node_modules/pi-lens/dist/clients/mcp/session.js +216 -8
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
- package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
- package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
- package/node_modules/pi-lens/dist/clients/pipeline.js +47 -13
- package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
- package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
- package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
- package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
- package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
- package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +107 -73
- package/node_modules/pi-lens/dist/clients/runtime-context.js +36 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +74 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +405 -117
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +218 -23
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +237 -64
- package/node_modules/pi-lens/dist/clients/rust-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
- package/node_modules/pi-lens/dist/clients/sg-runner.js +284 -174
- package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +224 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
- package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
- package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
- package/node_modules/pi-lens/dist/clients/startup-timing.js +1 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +38 -8
- package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +388 -39
- package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
- package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +33 -13
- package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
- package/node_modules/pi-lens/dist/clients/word-index.js +391 -64
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
- package/node_modules/pi-lens/dist/index.js +49361 -36888
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
- package/node_modules/pi-lens/dist/mcp/server.js +211 -44
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +200 -36
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +153 -40
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
- package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
- package/node_modules/pi-lens/docs/agent-guide.md +2 -2
- package/node_modules/pi-lens/docs/agent-tools.md +21 -10
- package/node_modules/pi-lens/docs/analysisall.md +192 -0
- package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
- package/node_modules/pi-lens/docs/environment-variables.md +44 -0
- package/node_modules/pi-lens/docs/fable.md +27 -0
- package/node_modules/pi-lens/docs/features.md +31 -2
- package/node_modules/pi-lens/docs/globalconfig.md +45 -1
- package/node_modules/pi-lens/docs/language-coverage.md +4 -3
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
- package/node_modules/pi-lens/docs/mcp.md +37 -4
- package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
- package/node_modules/pi-lens/docs/settings.md +12 -1
- package/node_modules/pi-lens/docs/tools.md +4 -1
- package/node_modules/pi-lens/docs/usage.md +18 -0
- package/node_modules/pi-lens/package.json +10 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
- package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +55 -2
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +25 -0
- package/node_modules/pi-mcp-adapter/README.md +34 -3
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
- package/node_modules/pi-mcp-adapter/commands.ts +15 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +54 -7
- package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
- package/node_modules/pi-mcp-adapter/index.ts +8 -3
- package/node_modules/pi-mcp-adapter/init.ts +29 -5
- package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +27 -4
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
- package/node_modules/pi-mcp-adapter/package.json +3 -3
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
- package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
- package/node_modules/pi-mcp-adapter/server-manager.ts +36 -7
- package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
- package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +42 -4
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
- package/node_modules/pi-mcp-adapter/types.ts +93 -27
- package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
- package/package.json +17 -13
- package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
- package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
- package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
- package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
- package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
- package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
- package/node_modules/pi-lens/dist/clients/types.js +0 -11
|
@@ -24,13 +24,14 @@ import * as path from "node:path";
|
|
|
24
24
|
import { fileURLToPath } from "node:url";
|
|
25
25
|
import { AstGrepClient } from "../clients/ast-grep-client.js";
|
|
26
26
|
import { CacheManager } from "../clients/cache-manager.js";
|
|
27
|
-
import {
|
|
28
|
-
import { analyzeFile, analyzeFileFresh, canRebuildPiLens, createMcpHost, diagnosticStats, ensureLspConfig, ipcPathForCwd, lspStatus,
|
|
27
|
+
import { getDegradationSummary, renderDegradationLines, } from "../clients/degradation-ledger.js";
|
|
28
|
+
import { acknowledgeTurnEnd, analyzeFile, analyzeFileFresh, canRebuildPiLens, createMcpHost, createWarmIpcLineReader, createWarmIpcRequestQueue, diagnosticStats, ensureLspConfig, generatedSkipNotice, ipcPathForCwd, lspStatus, moduleReport, projectReport, projectScan, readEnclosing, readSymbol, readTurnEndStatus, recentLatency, renderCompactModuleReport, renderCompactProjectReport, renderLspBrokenStatusLines, resolveRebuildScript, resourceFootprint, runRebuild, runSessionStart, runTurnEnd, runTurnEndForIpc, scanTruncationNotice, summarizeScan, symbolSearch, treeSitterRuntimeStatus, WARM_TURN_END_SCHEMA_VERSION, } from "../clients/lens-engine.js";
|
|
29
29
|
import { createAstGrepReplaceTool } from "../tools/ast-grep-replace.js";
|
|
30
30
|
import { createAstGrepSearchTool } from "../tools/ast-grep-search.js";
|
|
31
31
|
import { createLensDiagnosticsTool } from "../tools/lens-diagnostics.js";
|
|
32
32
|
import { createLspDiagnosticsTool } from "../tools/lsp-diagnostics.js";
|
|
33
33
|
import { createLspNavigationTool } from "../tools/lsp-navigation.js";
|
|
34
|
+
import { computeBuildStamp, STALE_SERVED_BY_FRESH, STALE_WARN_ONLY, StalenessGate, stalenessCheckEnabled, } from "./build-staleness.js";
|
|
34
35
|
// Any stray stdout write corrupts the JSON-RPC stream; force it onto stderr.
|
|
35
36
|
console.log = (...args) => {
|
|
36
37
|
console.error(...args);
|
|
@@ -191,6 +192,32 @@ function getAutoSessionStatus() {
|
|
|
191
192
|
// runs in THIS warm process (LSP-complete) instead of a cold hook process.
|
|
192
193
|
// Responses go over the socket — never stdout — so the MCP stream is untouched.
|
|
193
194
|
const IPC_PATH = ipcPathForCwd(DEFAULT_CWD);
|
|
195
|
+
/**
|
|
196
|
+
* #1273: the turn-end route runs the TARGET directory's configured test runner
|
|
197
|
+
* and spins up an LSP for it, from a client-supplied `cwd`. Every legitimate
|
|
198
|
+
* client derived the socket path from that same cwd, so a workspace check costs
|
|
199
|
+
* nothing legitimate — but without it, anything that can reach this endpoint
|
|
200
|
+
* (same-uid processes, a permissive-umask shared host, a Windows named pipe's
|
|
201
|
+
* more generous default DACL) can make the server execute an arbitrary
|
|
202
|
+
* directory's test suite. "Lint one file" and "run this directory's test suite"
|
|
203
|
+
* are different blast radii, so the guard is on turn-end and its ack.
|
|
204
|
+
*/
|
|
205
|
+
function rejectForeignTurnCwd(route, cwd) {
|
|
206
|
+
const message = `${route} cwd outside this server's workspace: ${path.resolve(cwd)} not within ${DEFAULT_CWD}`;
|
|
207
|
+
console.error(`[pi-lens-mcp] rejected ${message}`);
|
|
208
|
+
return message;
|
|
209
|
+
}
|
|
210
|
+
function isWithinServerWorkspace(cwd) {
|
|
211
|
+
const target = path.resolve(cwd);
|
|
212
|
+
// `path.relative` applies the platform's own path semantics (including
|
|
213
|
+
// win32 case-insensitivity), which is what "inside the workspace" means
|
|
214
|
+
// here — do NOT hand-roll a case fold. An empty result means `target`
|
|
215
|
+
// IS `DEFAULT_CWD` (win32 can reach that via a pure case/drive-letter
|
|
216
|
+
// difference, since path.relative there is case-insensitive) and must
|
|
217
|
+
// be accepted, not rejected — do NOT reintroduce a `rel !== ""` guard.
|
|
218
|
+
const rel = path.relative(DEFAULT_CWD, target);
|
|
219
|
+
return !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
220
|
+
}
|
|
194
221
|
function startIpcServer() {
|
|
195
222
|
// POSIX: a stale socket file blocks listen; remove it first. (Named pipes on
|
|
196
223
|
// Windows don't need this.)
|
|
@@ -202,33 +229,77 @@ function startIpcServer() {
|
|
|
202
229
|
// no stale socket — fine
|
|
203
230
|
}
|
|
204
231
|
}
|
|
232
|
+
const requestQueue = createWarmIpcRequestQueue();
|
|
205
233
|
const ipc = net.createServer((socket) => {
|
|
206
234
|
socket.setEncoding("utf8");
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const line = buffer.slice(0, newline);
|
|
214
|
-
void (async () => {
|
|
235
|
+
// One-shot per connection (#1219): clients write exactly one request and
|
|
236
|
+
// read one reply, so a handler that kept re-reading the same buffered
|
|
237
|
+
// line re-dispatched the request on stray bytes. The reader consumes the
|
|
238
|
+
// line and ignores anything after it.
|
|
239
|
+
socket.on("data", createWarmIpcLineReader((line) => {
|
|
240
|
+
void requestQueue.enqueue(async () => {
|
|
215
241
|
try {
|
|
216
|
-
// #535: the PostToolUse hook bin (mcp/analyze-cli.ts) already treats
|
|
217
|
-
// ANY error response as "no usable warm server" and falls back to
|
|
218
|
-
// its own cold, load-fresh-from-disk analysis path — so on a stale
|
|
219
|
-
// warm build, replying with an error IS the fresh-fork behavior for
|
|
220
|
-
// this channel, for free. No separate fresh-fork plumbing needed
|
|
221
|
-
// here: the client-side fallback already loads current code.
|
|
222
242
|
if (isWarmBuildStale()) {
|
|
223
|
-
console.error("[pi-lens-mcp] warm
|
|
224
|
-
socket.end(`${JSON.stringify({ error: "warm build stale
|
|
243
|
+
console.error("[pi-lens-mcp] warm request: build stale, replying with an error");
|
|
244
|
+
socket.end(`${JSON.stringify({ error: "warm build stale" })}\n`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const parsed = JSON.parse(line);
|
|
248
|
+
if (parsed.route === "turn-end-ack") {
|
|
249
|
+
if (parsed.version !== WARM_TURN_END_SCHEMA_VERSION ||
|
|
250
|
+
typeof parsed.deliveryId !==
|
|
251
|
+
"string") {
|
|
252
|
+
socket.end(`${JSON.stringify({ error: `turn-end ack schema ${parsed.version} != ${WARM_TURN_END_SCHEMA_VERSION}` })}\n`);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const turnCwd = parsed.cwd ?? DEFAULT_CWD;
|
|
256
|
+
if (!isWithinServerWorkspace(turnCwd)) {
|
|
257
|
+
socket.end(`${JSON.stringify({ error: rejectForeignTurnCwd("turn-end-ack", turnCwd) })}\n`);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const acknowledged = acknowledgeTurnEnd(turnCwd, parsed.deliveryId);
|
|
261
|
+
socket.end(`${JSON.stringify({
|
|
262
|
+
result: {
|
|
263
|
+
route: "turn-end-ack",
|
|
264
|
+
version: WARM_TURN_END_SCHEMA_VERSION,
|
|
265
|
+
acknowledged,
|
|
266
|
+
},
|
|
267
|
+
})}\n`);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (parsed.route === "turn-end") {
|
|
271
|
+
if (parsed.version !== WARM_TURN_END_SCHEMA_VERSION) {
|
|
272
|
+
socket.end(`${JSON.stringify({ error: `turn-end schema ${parsed.version} != ${WARM_TURN_END_SCHEMA_VERSION}` })}\n`);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const turnCwd = parsed.cwd ?? DEFAULT_CWD;
|
|
276
|
+
if (!isWithinServerWorkspace(turnCwd)) {
|
|
277
|
+
socket.end(`${JSON.stringify({ error: rejectForeignTurnCwd("turn-end", turnCwd) })}\n`);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// #1274: a client that already gave up (hook timeout, killed
|
|
281
|
+
// Claude Code) leaves a destroyed socket. Starting a heavy
|
|
282
|
+
// pass whose reply nobody can read is pure waste; the findings
|
|
283
|
+
// stay in the cache for the next Stop either way.
|
|
284
|
+
if (socket.destroyed) {
|
|
285
|
+
console.error(`[pi-lens-mcp] warm turn-end: client gone before the pass started (${turnCwd})`);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
console.error(`[pi-lens-mcp] warm turn-end: ${turnCwd}`);
|
|
289
|
+
await ensureReady(turnCwd);
|
|
290
|
+
const delivery = await runTurnEndForIpc(turnCwd);
|
|
291
|
+
const result = {
|
|
292
|
+
route: "turn-end",
|
|
293
|
+
version: WARM_TURN_END_SCHEMA_VERSION,
|
|
294
|
+
turnEnd: delivery.outcome.turnEnd,
|
|
295
|
+
tests: delivery.outcome.tests,
|
|
296
|
+
deliveryId: delivery.deliveryId,
|
|
297
|
+
};
|
|
298
|
+
socket.end(`${JSON.stringify({ result })}\n`);
|
|
225
299
|
return;
|
|
226
300
|
}
|
|
227
|
-
const req =
|
|
301
|
+
const req = parsed;
|
|
228
302
|
console.error(`[pi-lens-mcp] warm analyze: ${req.file}`);
|
|
229
|
-
// Warm = full LSP + an edit-detection path (register turn-state) +
|
|
230
|
-
// review-graph maintenance (#536 — this is an in-process, long-lived
|
|
231
|
-
// path, unlike the ephemeral `fresh` worker).
|
|
232
303
|
const result = await analyzeFile(req.file, req.cwd, {
|
|
233
304
|
registerTurnState: true,
|
|
234
305
|
updateGraph: true,
|
|
@@ -238,8 +309,8 @@ function startIpcServer() {
|
|
|
238
309
|
catch (err) {
|
|
239
310
|
socket.end(`${JSON.stringify({ error: String(err) })}\n`);
|
|
240
311
|
}
|
|
241
|
-
})
|
|
242
|
-
});
|
|
312
|
+
});
|
|
313
|
+
}));
|
|
243
314
|
socket.on("error", () => socket.destroy());
|
|
244
315
|
});
|
|
245
316
|
ipc.on("error", (err) => {
|
|
@@ -395,7 +466,7 @@ const ALL_TOOLS = [
|
|
|
395
466
|
},
|
|
396
467
|
flags: {
|
|
397
468
|
type: "object",
|
|
398
|
-
description:
|
|
469
|
+
description: 'Optional pi-lens flag overrides for this run, e.g. {"no-lsp": true} to bench the non-LSP path.',
|
|
399
470
|
},
|
|
400
471
|
},
|
|
401
472
|
required: ["file"],
|
|
@@ -415,8 +486,14 @@ const ALL_TOOLS = [
|
|
|
415
486
|
inputSchema: {
|
|
416
487
|
type: "object",
|
|
417
488
|
properties: {
|
|
418
|
-
limit: {
|
|
419
|
-
|
|
489
|
+
limit: {
|
|
490
|
+
type: "number",
|
|
491
|
+
description: "Max reports to return (default 5).",
|
|
492
|
+
},
|
|
493
|
+
file: {
|
|
494
|
+
type: "string",
|
|
495
|
+
description: "Only reports whose path ends with this.",
|
|
496
|
+
},
|
|
420
497
|
},
|
|
421
498
|
},
|
|
422
499
|
},
|
|
@@ -439,6 +516,13 @@ const ALL_TOOLS = [
|
|
|
439
516
|
properties: {
|
|
440
517
|
cwd: { type: "string" },
|
|
441
518
|
maxFiles: { type: "number", description: "Cap files scanned." },
|
|
519
|
+
includeGenerated: {
|
|
520
|
+
type: "boolean",
|
|
521
|
+
description: "Scan WITHOUT the generated/artifact NAME-heuristic filter " +
|
|
522
|
+
"(lockfiles, gen.ts-style names, generated/ dirs, …). Default " +
|
|
523
|
+
"false. Use when a scan's 'excluded by generated-name " +
|
|
524
|
+
"heuristics' notice suggests a real file was skipped.",
|
|
525
|
+
},
|
|
442
526
|
},
|
|
443
527
|
},
|
|
444
528
|
},
|
|
@@ -495,7 +579,9 @@ const ALL_TOOLS = [
|
|
|
495
579
|
"(this path never calls LSP). `semantic.source` reports whether graph " +
|
|
496
580
|
"data was used. Pass `blastRadius: true` for the cross-file blast radius " +
|
|
497
581
|
"(transitive dependents as ranked file reads, read-only over the cached " +
|
|
498
|
-
|
|
582
|
+
"graph). Pass `callGraph: true` for bounded derived callers/callees; a " +
|
|
583
|
+
"cold or stale call-graph cache is reported explicitly, never as zero calls. " +
|
|
584
|
+
'`view: "compact"` returns a line-oriented text rendering ' +
|
|
499
585
|
"(cheapest option) instead of JSON. An outline shows shape, not bodies.",
|
|
500
586
|
inputSchema: {
|
|
501
587
|
type: "object",
|
|
@@ -526,6 +612,14 @@ const ALL_TOOLS = [
|
|
|
526
612
|
type: "number",
|
|
527
613
|
description: "Max hops for the blast-radius walk (default 3). Only used with blastRadius.",
|
|
528
614
|
},
|
|
615
|
+
callGraph: {
|
|
616
|
+
type: "boolean",
|
|
617
|
+
description: "Include bounded derived callers/callees from the cached FunctionCallGraph; cold or stale cache state is explicit.",
|
|
618
|
+
},
|
|
619
|
+
maxCallGraphEntries: {
|
|
620
|
+
type: "number",
|
|
621
|
+
description: "Per-direction cap for call-graph relations (default 20).",
|
|
622
|
+
},
|
|
529
623
|
},
|
|
530
624
|
required: ["file"],
|
|
531
625
|
},
|
|
@@ -685,8 +779,11 @@ const ALL_TOOLS = [
|
|
|
685
779
|
{
|
|
686
780
|
name: "pilens_ast_grep_search",
|
|
687
781
|
description: "Structural (AST) code search via ast-grep — match by code structure, not " +
|
|
688
|
-
"text. Use
|
|
689
|
-
"'function $NAME() { $$$ }')
|
|
782
|
+
"text. Use complete patterns with arguments (e.g. 'console.log($MSG)', " +
|
|
783
|
+
"'function $NAME($$$ARGS) { $$$BODY }'), or use nodeKind to find every " +
|
|
784
|
+
"node of a known grammar kind. Metavariables do not match text inside " +
|
|
785
|
+
"quoted string literals; use an exact string or grep for wildcard text. " +
|
|
786
|
+
"This is the same schema and synthesis path as the pi tool.",
|
|
690
787
|
inputSchema: schemaWithCwd(astGrepSearchTool.parameters),
|
|
691
788
|
},
|
|
692
789
|
{
|
|
@@ -739,7 +836,10 @@ async function callTool(name, args) {
|
|
|
739
836
|
if (name === "pilens_analyze") {
|
|
740
837
|
const file = args.file;
|
|
741
838
|
if (typeof file !== "string" || file.length === 0) {
|
|
742
|
-
return {
|
|
839
|
+
return {
|
|
840
|
+
...toolText("pilens_analyze requires a 'file' string."),
|
|
841
|
+
isError: true,
|
|
842
|
+
};
|
|
743
843
|
}
|
|
744
844
|
const cwd = typeof args.cwd === "string" ? args.cwd : DEFAULT_CWD;
|
|
745
845
|
const requestedMode = args.mode === "fresh" ? "fresh" : "warm";
|
|
@@ -814,7 +914,8 @@ async function callTool(name, args) {
|
|
|
814
914
|
const maxFiles = typeof args.maxFiles === "number" && Number.isFinite(args.maxFiles)
|
|
815
915
|
? Math.max(1, Math.floor(args.maxFiles))
|
|
816
916
|
: undefined;
|
|
817
|
-
const
|
|
917
|
+
const includeGenerated = args.includeGenerated === true;
|
|
918
|
+
const snapshot = await projectScan(cwd, maxFiles, includeGenerated);
|
|
818
919
|
// #747: a cwd at/above $HOME refuses to walk — say so instead of letting
|
|
819
920
|
// "Scanned 0 file(s) → 0 diagnostics" read as a clean project.
|
|
820
921
|
if (snapshot.unsafeRoot) {
|
|
@@ -840,6 +941,11 @@ async function callTool(name, args) {
|
|
|
840
941
|
const truncationNotice = scanTruncationNotice(snapshot);
|
|
841
942
|
if (truncationNotice)
|
|
842
943
|
summaryLines.push(truncationNotice);
|
|
944
|
+
// #1107 phase 2: same "reached the seam but nothing rendered it" gap as
|
|
945
|
+
// #784's scanTruncationNotice, for the generated-name skip counters.
|
|
946
|
+
const skipNotice = generatedSkipNotice(snapshot);
|
|
947
|
+
if (skipNotice)
|
|
948
|
+
summaryLines.push(skipNotice);
|
|
843
949
|
return toolText(summaryLines.join("\n"), {
|
|
844
950
|
filesScanned: snapshot.filesScanned,
|
|
845
951
|
runners: snapshot.runners,
|
|
@@ -852,6 +958,15 @@ async function callTool(name, args) {
|
|
|
852
958
|
...(snapshot.treeSitterStatus
|
|
853
959
|
? { treeSitterStatus: snapshot.treeSitterStatus }
|
|
854
960
|
: {}),
|
|
961
|
+
...(snapshot.generatedFileSkips
|
|
962
|
+
? { generatedFileSkips: snapshot.generatedFileSkips }
|
|
963
|
+
: {}),
|
|
964
|
+
...(snapshot.generatedNameOnlySkips
|
|
965
|
+
? { generatedNameOnlySkips: snapshot.generatedNameOnlySkips }
|
|
966
|
+
: {}),
|
|
967
|
+
...(snapshot.generatedDirSkips
|
|
968
|
+
? { generatedDirSkips: snapshot.generatedDirSkips }
|
|
969
|
+
: {}),
|
|
855
970
|
});
|
|
856
971
|
}
|
|
857
972
|
if (name === "pilens_symbol_search") {
|
|
@@ -868,7 +983,8 @@ async function callTool(name, args) {
|
|
|
868
983
|
const lang = typeof args.lang === "string" ? args.lang : undefined;
|
|
869
984
|
const { available, results, hint, unavailableReason, coverage, snapshotGeneratedAt, } = await symbolSearch(query, cwd, limit, { paths, lang });
|
|
870
985
|
if (!available) {
|
|
871
|
-
return toolText(hint ??
|
|
986
|
+
return toolText(hint ??
|
|
987
|
+
"No word index for this workspace yet — run pilens_session_start first.", { available: false, query, hint, unavailableReason }, true);
|
|
872
988
|
}
|
|
873
989
|
const stalenessNote = graphStalenessNote(snapshotGeneratedAt, "Project snapshot");
|
|
874
990
|
if (results.length === 0) {
|
|
@@ -934,12 +1050,21 @@ async function callTool(name, args) {
|
|
|
934
1050
|
Number.isFinite(args.blastRadiusDepth)
|
|
935
1051
|
? Math.max(1, Math.floor(args.blastRadiusDepth))
|
|
936
1052
|
: undefined;
|
|
937
|
-
const
|
|
1053
|
+
const callGraph = args.callGraph === true;
|
|
1054
|
+
const maxCallGraphEntries = typeof args.maxCallGraphEntries === "number" &&
|
|
1055
|
+
Number.isFinite(args.maxCallGraphEntries)
|
|
1056
|
+
? Math.max(1, Math.floor(args.maxCallGraphEntries))
|
|
1057
|
+
: undefined;
|
|
1058
|
+
const view = args.view === "summary" || args.view === "compact"
|
|
1059
|
+
? args.view
|
|
1060
|
+
: undefined;
|
|
938
1061
|
const focus = typeof args.focus === "string" ? args.focus : undefined;
|
|
939
1062
|
const report = await moduleReport(file, cwd, {
|
|
940
1063
|
maxRefsPerSymbol,
|
|
941
1064
|
blastRadius,
|
|
942
1065
|
blastRadiusDepth,
|
|
1066
|
+
callGraph,
|
|
1067
|
+
maxCallGraphEntries,
|
|
943
1068
|
view,
|
|
944
1069
|
focus,
|
|
945
1070
|
});
|
|
@@ -960,14 +1085,18 @@ async function callTool(name, args) {
|
|
|
960
1085
|
content: [
|
|
961
1086
|
{
|
|
962
1087
|
type: "text",
|
|
963
|
-
text: graphStaleness
|
|
1088
|
+
text: graphStaleness
|
|
1089
|
+
? `${compactText}\n\n${graphStaleness}`
|
|
1090
|
+
: compactText,
|
|
964
1091
|
},
|
|
965
1092
|
],
|
|
966
1093
|
};
|
|
967
1094
|
}
|
|
968
1095
|
// Compact (unindented) JSON — matches the pi tool's mirror (#512); an
|
|
969
1096
|
// agent parses this payload, it doesn't read it formatted.
|
|
970
|
-
return toolText(summary, graphStaleness
|
|
1097
|
+
return toolText(summary, graphStaleness
|
|
1098
|
+
? { ...report, graphStalenessNote: graphStaleness }
|
|
1099
|
+
: report, true);
|
|
971
1100
|
}
|
|
972
1101
|
if (name === "pilens_project_report") {
|
|
973
1102
|
const cwd = typeof args.cwd === "string" ? args.cwd : DEFAULT_CWD;
|
|
@@ -992,7 +1121,9 @@ async function callTool(name, args) {
|
|
|
992
1121
|
content: [
|
|
993
1122
|
{
|
|
994
1123
|
type: "text",
|
|
995
|
-
text: graphStaleness
|
|
1124
|
+
text: graphStaleness
|
|
1125
|
+
? `${compactText}\n\n${graphStaleness}`
|
|
1126
|
+
: compactText,
|
|
996
1127
|
},
|
|
997
1128
|
],
|
|
998
1129
|
};
|
|
@@ -1001,7 +1132,9 @@ async function callTool(name, args) {
|
|
|
1001
1132
|
`${report.entryPoints?.length ?? 0} entry point(s), ` +
|
|
1002
1133
|
`${report.riskHotspots?.length ?? 0} risk hotspot(s)` +
|
|
1003
1134
|
(graphStaleness ? `\n\n${graphStaleness}` : "");
|
|
1004
|
-
return toolText(summary, graphStaleness
|
|
1135
|
+
return toolText(summary, graphStaleness
|
|
1136
|
+
? { ...report, graphStalenessNote: graphStaleness }
|
|
1137
|
+
: report, true);
|
|
1005
1138
|
}
|
|
1006
1139
|
if (name === "pilens_read_symbol") {
|
|
1007
1140
|
const file = typeof args.file === "string" ? args.file : "";
|
|
@@ -1032,13 +1165,20 @@ async function callTool(name, args) {
|
|
|
1032
1165
|
? ` (${result.ambiguous.count} matches — returned the ${result.kind}; pass \`kind\` to disambiguate: ${result.ambiguous.kinds.join(", ")})`
|
|
1033
1166
|
: "";
|
|
1034
1167
|
const header = `${result.kind} ${result.name}${ambiguityNote}${sigSuffix} ${path.relative(cwd, result.path)}:${result.startLine}-${result.endLine}`;
|
|
1035
|
-
return {
|
|
1168
|
+
return {
|
|
1169
|
+
content: [
|
|
1170
|
+
{ type: "text", text: `${header}\n\n${result.source ?? ""}` },
|
|
1171
|
+
],
|
|
1172
|
+
};
|
|
1036
1173
|
}
|
|
1037
1174
|
if (name === "pilens_read_enclosing") {
|
|
1038
1175
|
const file = typeof args.file === "string" ? args.file : "";
|
|
1039
1176
|
const line = typeof args.line === "number" ? args.line : Number.NaN;
|
|
1040
1177
|
if (!file.trim() || !Number.isFinite(line)) {
|
|
1041
|
-
return {
|
|
1178
|
+
return {
|
|
1179
|
+
...toolText("Provide `file` and a numeric `line`."),
|
|
1180
|
+
isError: true,
|
|
1181
|
+
};
|
|
1042
1182
|
}
|
|
1043
1183
|
const cwd = typeof args.cwd === "string" ? args.cwd : DEFAULT_CWD;
|
|
1044
1184
|
const kinds = Array.isArray(args.kinds)
|
|
@@ -1082,7 +1222,11 @@ async function callTool(name, args) {
|
|
|
1082
1222
|
? `${result.startLine}-${result.endLine} (partial of ${result.enclosingStartLine}-${result.enclosingEndLine})`
|
|
1083
1223
|
: `${result.startLine}-${result.endLine}`;
|
|
1084
1224
|
const header = `${result.kind} ${result.name} ${path.relative(cwd, result.path)}:${range}`;
|
|
1085
|
-
return {
|
|
1225
|
+
return {
|
|
1226
|
+
content: [
|
|
1227
|
+
{ type: "text", text: `${header}\n\n${result.source ?? ""}` },
|
|
1228
|
+
],
|
|
1229
|
+
};
|
|
1086
1230
|
}
|
|
1087
1231
|
if (name === "pilens_health") {
|
|
1088
1232
|
const { aliveClients, servers, brokenServers } = lspStatus();
|
|
@@ -1090,6 +1234,13 @@ async function callTool(name, args) {
|
|
|
1090
1234
|
const stats = diagnosticStats();
|
|
1091
1235
|
const autoSession = getAutoSessionStatus();
|
|
1092
1236
|
const treeSitter = treeSitterRuntimeStatus();
|
|
1237
|
+
const degradations = getDegradationSummary();
|
|
1238
|
+
// #1272, following the #544 precedent: the Stop hook is a separate,
|
|
1239
|
+
// short-lived process, so a turn-end it skipped left no trace here at all
|
|
1240
|
+
// — a dead integration looked exactly like a clean turn, forever. The
|
|
1241
|
+
// hook records its outcome per workspace; this is where it becomes
|
|
1242
|
+
// visible without `claude --debug` log spelunking.
|
|
1243
|
+
const turnEnd = readTurnEndStatus(DEFAULT_CWD) ?? null;
|
|
1093
1244
|
// #620: best-effort — a footprint read failure must never break the rest
|
|
1094
1245
|
// of pilens_health's (much older, more load-bearing) reporting.
|
|
1095
1246
|
const footprint = await resourceFootprint().catch(() => null);
|
|
@@ -1098,8 +1249,12 @@ async function callTool(name, args) {
|
|
|
1098
1249
|
? `Tree-sitter: DEGRADED — WASM runtime aborted${treeSitter.abortedAt ? ` at ${treeSitter.abortedAt}` : ""}; restart this server to recover`
|
|
1099
1250
|
: "Tree-sitter: available",
|
|
1100
1251
|
`LSP: ${aliveClients} alive client(s)`,
|
|
1101
|
-
...servers.
|
|
1252
|
+
...servers.flatMap((server) => [
|
|
1253
|
+
` ${server.connected ? "✓" : "✗"} ${server.serverId} (${server.root})`,
|
|
1254
|
+
...server.pullFailureHistory.slice(-1).map((failure) => ` ⚠ diagnostics pull failed: ${failure.method}${failure.code !== undefined ? ` (${failure.code})` : ""} — ${failure.message.length > 200 ? `${failure.message.slice(0, 200)}…` : failure.message}`),
|
|
1255
|
+
]),
|
|
1102
1256
|
...renderLspBrokenStatusLines(brokenServers),
|
|
1257
|
+
...renderDegradationLines(degradations),
|
|
1103
1258
|
last
|
|
1104
1259
|
? `Last dispatch: ${path.basename(last.filePath)} — ${last.totalDurationMs}ms, ${last.totalDiagnostics} diagnostic(s)`
|
|
1105
1260
|
: "Last dispatch: none yet",
|
|
@@ -1107,6 +1262,11 @@ async function callTool(name, args) {
|
|
|
1107
1262
|
autoSession
|
|
1108
1263
|
? `Auto session_start: ${autoSession.succeeded ? "succeeded" : autoSession.error ? "FAILED" : autoSession.attempted ? "in progress" : "not yet attempted"}${autoSession.firedAt ? ` (fired ${autoSession.firedAt})` : ""}${autoSession.error ? ` — ${autoSession.error}` : ""}`
|
|
1109
1264
|
: "Auto session_start: disabled (PI_LENS_MCP_AUTO_SESSION not set)",
|
|
1265
|
+
turnEnd
|
|
1266
|
+
? `Stop-hook turn-end: ${turnEnd.ran} ran · ${turnEnd.skipped} skipped` +
|
|
1267
|
+
`${turnEnd.lastRunAt ? ` (last ran ${turnEnd.lastRunAt})` : ""}` +
|
|
1268
|
+
`${turnEnd.lastSkipReason ? ` — last skip: ${turnEnd.lastSkipReason}${turnEnd.lastSkipAt ? ` at ${turnEnd.lastSkipAt}` : ""}` : ""}`
|
|
1269
|
+
: "Stop-hook turn-end: no activity recorded (hook not installed, or no Stop yet)",
|
|
1110
1270
|
footprint
|
|
1111
1271
|
? `Resource footprint: ${footprint.instanceCount} pi-lens instance(s) · ` +
|
|
1112
1272
|
`${(footprint.totalRssBytes / 1024 / 1024).toFixed(0)}MB RSS · ` +
|
|
@@ -1132,7 +1292,9 @@ async function callTool(name, args) {
|
|
|
1132
1292
|
},
|
|
1133
1293
|
autoSession,
|
|
1134
1294
|
treeSitter,
|
|
1295
|
+
turnEnd,
|
|
1135
1296
|
resourceFootprint: footprint,
|
|
1297
|
+
degradations,
|
|
1136
1298
|
});
|
|
1137
1299
|
}
|
|
1138
1300
|
if (name === "pilens_diagnostics") {
|
|
@@ -1186,7 +1348,9 @@ async function callTool(name, args) {
|
|
|
1186
1348
|
}
|
|
1187
1349
|
if (name === "pilens_ast_grep_search" || name === "pilens_ast_grep_replace") {
|
|
1188
1350
|
const cwd = typeof args.cwd === "string" ? args.cwd : DEFAULT_CWD;
|
|
1189
|
-
const tool = name === "pilens_ast_grep_search"
|
|
1351
|
+
const tool = name === "pilens_ast_grep_search"
|
|
1352
|
+
? astGrepSearchTool
|
|
1353
|
+
: astGrepReplaceTool;
|
|
1190
1354
|
const out = (await tool.execute("mcp", args, new AbortController().signal, undefined, { cwd }));
|
|
1191
1355
|
return { content: out.content };
|
|
1192
1356
|
}
|
|
@@ -1270,7 +1434,10 @@ function withStaleWarning(result) {
|
|
|
1270
1434
|
...result,
|
|
1271
1435
|
content: [
|
|
1272
1436
|
...result.content.slice(0, -1),
|
|
1273
|
-
{
|
|
1437
|
+
{
|
|
1438
|
+
...last,
|
|
1439
|
+
text: `${last.text}\n\nwarmCodeStale: true\n${STALE_WARN_ONLY}`,
|
|
1440
|
+
},
|
|
1274
1441
|
],
|
|
1275
1442
|
};
|
|
1276
1443
|
}
|