@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
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
|
-
export class AstGrepParser {
|
|
3
|
-
getRuleDescription;
|
|
4
|
-
mapSeverity;
|
|
5
|
-
constructor(getRuleDescription, mapSeverity) {
|
|
6
|
-
this.getRuleDescription = getRuleDescription;
|
|
7
|
-
this.mapSeverity = mapSeverity;
|
|
8
|
-
}
|
|
9
|
-
parseOutput(output, filterFile) {
|
|
10
|
-
const resolvedFilterFile = path.resolve(filterFile);
|
|
11
|
-
try {
|
|
12
|
-
const items = JSON.parse(output);
|
|
13
|
-
if (Array.isArray(items)) {
|
|
14
|
-
return items
|
|
15
|
-
.map((item) => this.parseDiagnostic(item, resolvedFilterFile))
|
|
16
|
-
.filter((d) => d !== null);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
catch (err) {
|
|
20
|
-
void err;
|
|
21
|
-
}
|
|
22
|
-
return output
|
|
23
|
-
.split(/\r?\n/)
|
|
24
|
-
.filter((l) => l.trim())
|
|
25
|
-
.map((line) => {
|
|
26
|
-
try {
|
|
27
|
-
return this.parseDiagnostic(JSON.parse(line), resolvedFilterFile);
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
void err;
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
.filter((d) => d !== null);
|
|
35
|
-
}
|
|
36
|
-
parseDiagnostic(item, filterFile) {
|
|
37
|
-
if (item.labels?.length) {
|
|
38
|
-
return this.parseNewFormat(item, filterFile);
|
|
39
|
-
}
|
|
40
|
-
if (item.spans?.length) {
|
|
41
|
-
return this.parseLegacyFormat(item, filterFile);
|
|
42
|
-
}
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
parseNewFormat(item, filterFile) {
|
|
46
|
-
const label = item.labels.find((l) => l.style === "primary") || item.labels[0];
|
|
47
|
-
const filePath = path.resolve(label.file || filterFile);
|
|
48
|
-
if (filePath !== filterFile)
|
|
49
|
-
return null;
|
|
50
|
-
const start = label.range?.start || { line: 0, column: 0 };
|
|
51
|
-
const end = label.range?.end || start;
|
|
52
|
-
return {
|
|
53
|
-
line: start.line + 1,
|
|
54
|
-
column: start.column,
|
|
55
|
-
endLine: end.line + 1,
|
|
56
|
-
endColumn: end.column,
|
|
57
|
-
severity: this.mapSeverity(item.severity),
|
|
58
|
-
message: item.message || "Unknown issue",
|
|
59
|
-
rule: item.ruleId || "unknown",
|
|
60
|
-
ruleDescription: this.getRuleDescription(item.ruleId || "unknown"),
|
|
61
|
-
file: filePath,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
parseLegacyFormat(item, filterFile) {
|
|
65
|
-
const span = item.spans?.[0];
|
|
66
|
-
if (!span)
|
|
67
|
-
return null;
|
|
68
|
-
const filePath = path.resolve(span.file || filterFile);
|
|
69
|
-
if (filePath !== filterFile)
|
|
70
|
-
return null;
|
|
71
|
-
const start = span.range?.start || { line: 0, column: 0 };
|
|
72
|
-
const end = span.range?.end || start;
|
|
73
|
-
const ruleId = item.name || item.ruleId || "unknown";
|
|
74
|
-
return {
|
|
75
|
-
line: start.line + 1,
|
|
76
|
-
column: start.column,
|
|
77
|
-
endLine: end.line + 1,
|
|
78
|
-
endColumn: end.column,
|
|
79
|
-
severity: this.mapSeverity(item.severity || item.Severity || "warning"),
|
|
80
|
-
message: item.Message?.text || item.message || "Unknown issue",
|
|
81
|
-
rule: ruleId,
|
|
82
|
-
ruleDescription: this.getRuleDescription(ruleId),
|
|
83
|
-
file: filePath,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive LSP Installer
|
|
3
|
-
*
|
|
4
|
-
* Provides lazy auto-install with user prompt for common languages.
|
|
5
|
-
*
|
|
6
|
-
* Features:
|
|
7
|
-
* - 30-second timeout with auto-accept
|
|
8
|
-
* - --auto-install flag for non-interactive mode
|
|
9
|
-
* - User choice caching per project
|
|
10
|
-
* - Only prompts for "common" languages (Go, Rust, YAML, JSON, Bash)
|
|
11
|
-
*/
|
|
12
|
-
import * as fs from "node:fs/promises";
|
|
13
|
-
import * as path from "node:path";
|
|
14
|
-
import { getProjectDataDir } from "../file-utils.js";
|
|
15
|
-
import { globalInstallArgs, pmBinary, resolveNodePackageManager, } from "../package-manager.js";
|
|
16
|
-
import { safeSpawnAsync } from "../safe-spawn.js";
|
|
17
|
-
function canUseInteractivePrompt() {
|
|
18
|
-
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
19
|
-
}
|
|
20
|
-
async function isToolOnPath(toolId) {
|
|
21
|
-
const locator = process.platform === "win32" ? "where" : "which";
|
|
22
|
-
const result = await safeSpawnAsync(locator, [toolId], {
|
|
23
|
-
timeout: 5000,
|
|
24
|
-
ignoreAmbientSignal: true,
|
|
25
|
-
});
|
|
26
|
-
return result.status === 0;
|
|
27
|
-
}
|
|
28
|
-
// Languages that support interactive auto-install prompt
|
|
29
|
-
const COMMON_LANGUAGES = {
|
|
30
|
-
// --- Originally supported ---
|
|
31
|
-
go: {
|
|
32
|
-
toolId: "gopls",
|
|
33
|
-
toolName: "Go Language Server (gopls)",
|
|
34
|
-
installCommand: "go install golang.org/x/tools/gopls@latest",
|
|
35
|
-
installStrategy: "shell",
|
|
36
|
-
},
|
|
37
|
-
rust: {
|
|
38
|
-
toolId: "rust-analyzer",
|
|
39
|
-
toolName: "Rust Language Server (rust-analyzer)",
|
|
40
|
-
installCommand: "rustup component add rust-analyzer",
|
|
41
|
-
installStrategy: "shell",
|
|
42
|
-
},
|
|
43
|
-
yaml: {
|
|
44
|
-
toolId: "yaml-language-server",
|
|
45
|
-
toolName: "YAML Language Server",
|
|
46
|
-
installCommand: "npm install -g yaml-language-server",
|
|
47
|
-
packageName: "yaml-language-server",
|
|
48
|
-
installStrategy: "npm",
|
|
49
|
-
},
|
|
50
|
-
json: {
|
|
51
|
-
toolId: "vscode-json-language-server",
|
|
52
|
-
toolName: "JSON Language Server",
|
|
53
|
-
installCommand: "npm install -g vscode-langservers-extracted",
|
|
54
|
-
packageName: "vscode-langservers-extracted",
|
|
55
|
-
installStrategy: "npm",
|
|
56
|
-
},
|
|
57
|
-
bash: {
|
|
58
|
-
toolId: "bash-language-server",
|
|
59
|
-
toolName: "Bash Language Server",
|
|
60
|
-
installCommand: "npm install -g bash-language-server",
|
|
61
|
-
packageName: "bash-language-server",
|
|
62
|
-
installStrategy: "npm",
|
|
63
|
-
},
|
|
64
|
-
// --- Tier-4: previously silent on ENOENT ---
|
|
65
|
-
ruby: {
|
|
66
|
-
toolId: "ruby-lsp",
|
|
67
|
-
toolName: "Ruby LSP",
|
|
68
|
-
installCommand: "gem install ruby-lsp",
|
|
69
|
-
installStrategy: "shell",
|
|
70
|
-
},
|
|
71
|
-
php: {
|
|
72
|
-
toolId: "intelephense",
|
|
73
|
-
toolName: "PHP Language Server (Intelephense)",
|
|
74
|
-
installCommand: "npm install -g intelephense",
|
|
75
|
-
packageName: "intelephense",
|
|
76
|
-
installStrategy: "npm",
|
|
77
|
-
},
|
|
78
|
-
csharp: {
|
|
79
|
-
toolId: "csharp-ls",
|
|
80
|
-
toolName: "C# Language Server (csharp-ls)",
|
|
81
|
-
installCommand: "dotnet tool install -g csharp-ls",
|
|
82
|
-
installStrategy: "shell",
|
|
83
|
-
},
|
|
84
|
-
fsharp: {
|
|
85
|
-
toolId: "fsautocomplete",
|
|
86
|
-
toolName: "F# Language Server (FSAutocomplete)",
|
|
87
|
-
installCommand: "dotnet tool install -g fsautocomplete",
|
|
88
|
-
installStrategy: "shell",
|
|
89
|
-
},
|
|
90
|
-
java: {
|
|
91
|
-
toolId: "jdtls",
|
|
92
|
-
toolName: "Java Language Server (Eclipse JDT LS)",
|
|
93
|
-
installCommand: "brew install jdtls # or: https://github.com/eclipse-jdtls/eclipse.jdt.ls",
|
|
94
|
-
installStrategy: "manual",
|
|
95
|
-
},
|
|
96
|
-
kotlin: {
|
|
97
|
-
toolId: "kotlin-language-server",
|
|
98
|
-
toolName: "Kotlin Language Server",
|
|
99
|
-
installCommand: "brew install kotlin-language-server # or: https://github.com/fwcd/kotlin-language-server",
|
|
100
|
-
installStrategy: "manual",
|
|
101
|
-
},
|
|
102
|
-
swift: {
|
|
103
|
-
toolId: "sourcekit-lsp",
|
|
104
|
-
toolName: "Swift Language Server (SourceKit-LSP)",
|
|
105
|
-
installCommand: "xcode-select --install # bundled with Xcode / Swift toolchain",
|
|
106
|
-
installStrategy: "manual",
|
|
107
|
-
},
|
|
108
|
-
dart: {
|
|
109
|
-
toolId: "dart",
|
|
110
|
-
toolName: "Dart Language Server",
|
|
111
|
-
installCommand: "# Install Dart SDK: https://dart.dev/get-dart",
|
|
112
|
-
installStrategy: "manual",
|
|
113
|
-
},
|
|
114
|
-
lua: {
|
|
115
|
-
toolId: "lua-language-server",
|
|
116
|
-
toolName: "Lua Language Server",
|
|
117
|
-
installCommand: "brew install lua-language-server",
|
|
118
|
-
installStrategy: "shell",
|
|
119
|
-
},
|
|
120
|
-
cpp: {
|
|
121
|
-
toolId: "clangd",
|
|
122
|
-
toolName: "C/C++ Language Server (clangd)",
|
|
123
|
-
installCommand: "brew install llvm # or: apt install clangd",
|
|
124
|
-
installStrategy: "manual",
|
|
125
|
-
},
|
|
126
|
-
zig: {
|
|
127
|
-
toolId: "zls",
|
|
128
|
-
toolName: "Zig Language Server (ZLS)",
|
|
129
|
-
installCommand: "brew install zls",
|
|
130
|
-
installStrategy: "shell",
|
|
131
|
-
},
|
|
132
|
-
haskell: {
|
|
133
|
-
toolId: "haskell-language-server-wrapper",
|
|
134
|
-
toolName: "Haskell Language Server",
|
|
135
|
-
installCommand: "ghcup install hls",
|
|
136
|
-
installStrategy: "shell",
|
|
137
|
-
},
|
|
138
|
-
elixir: {
|
|
139
|
-
toolId: "elixir-ls",
|
|
140
|
-
toolName: "Elixir Language Server (ElixirLS)",
|
|
141
|
-
installCommand: "# Download from: https://github.com/elixir-lsp/elixir-ls/releases",
|
|
142
|
-
installStrategy: "manual",
|
|
143
|
-
},
|
|
144
|
-
gleam: {
|
|
145
|
-
toolId: "gleam",
|
|
146
|
-
toolName: "Gleam Language Server",
|
|
147
|
-
installCommand: "brew install gleam",
|
|
148
|
-
installStrategy: "shell",
|
|
149
|
-
},
|
|
150
|
-
ocaml: {
|
|
151
|
-
toolId: "ocamllsp",
|
|
152
|
-
toolName: "OCaml Language Server (ocamllsp)",
|
|
153
|
-
installCommand: "opam install ocaml-lsp-server",
|
|
154
|
-
installStrategy: "shell",
|
|
155
|
-
},
|
|
156
|
-
clojure: {
|
|
157
|
-
toolId: "clojure-lsp",
|
|
158
|
-
toolName: "Clojure Language Server",
|
|
159
|
-
installCommand: "brew install clojure-lsp/brew/clojure-lsp",
|
|
160
|
-
installStrategy: "shell",
|
|
161
|
-
},
|
|
162
|
-
terraform: {
|
|
163
|
-
toolId: "terraform-ls",
|
|
164
|
-
toolName: "Terraform Language Server",
|
|
165
|
-
installCommand: "brew install hashicorp/tap/terraform-ls",
|
|
166
|
-
installStrategy: "shell",
|
|
167
|
-
},
|
|
168
|
-
nix: {
|
|
169
|
-
toolId: "nixd",
|
|
170
|
-
toolName: "Nix Language Server (nixd)",
|
|
171
|
-
installCommand: "nix profile install nixpkgs#nixd",
|
|
172
|
-
installStrategy: "shell",
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
/**
|
|
176
|
-
* Get the cache file path for install choices
|
|
177
|
-
*/
|
|
178
|
-
function getCachePath(cwd) {
|
|
179
|
-
return path.join(getProjectDataDir(cwd), "install-choices.json");
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Read cached install choices
|
|
183
|
-
*/
|
|
184
|
-
async function readChoices(cwd) {
|
|
185
|
-
try {
|
|
186
|
-
const cachePath = getCachePath(cwd);
|
|
187
|
-
const content = await fs.readFile(cachePath, "utf-8");
|
|
188
|
-
return JSON.parse(content);
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
191
|
-
return {};
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Save install choice to cache
|
|
196
|
-
*/
|
|
197
|
-
async function saveChoice(cwd, toolId, choice) {
|
|
198
|
-
const choices = await readChoices(cwd);
|
|
199
|
-
choices[toolId] = { choice, timestamp: Date.now() };
|
|
200
|
-
try {
|
|
201
|
-
const cachePath = getCachePath(cwd);
|
|
202
|
-
await fs.mkdir(path.dirname(cachePath), { recursive: true });
|
|
203
|
-
await fs.writeFile(cachePath, JSON.stringify(choices, null, 2));
|
|
204
|
-
}
|
|
205
|
-
catch {
|
|
206
|
-
// Ignore cache write errors
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Prompt user with timeout
|
|
211
|
-
*/
|
|
212
|
-
function promptUser(timeoutMs) {
|
|
213
|
-
return new Promise((resolve) => {
|
|
214
|
-
// Set up stdin for single char input
|
|
215
|
-
process.stdin.setRawMode?.(true);
|
|
216
|
-
process.stdin.resume();
|
|
217
|
-
process.stdin.setEncoding("utf8");
|
|
218
|
-
const onData = (data) => {
|
|
219
|
-
const char = data.toString().trim().toLowerCase();
|
|
220
|
-
cleanup();
|
|
221
|
-
if (char === "y" || char === "\n" || char === "\r") {
|
|
222
|
-
resolve("yes");
|
|
223
|
-
}
|
|
224
|
-
else if (char === "n") {
|
|
225
|
-
resolve("no");
|
|
226
|
-
}
|
|
227
|
-
// For any other input, auto-accept after timeout
|
|
228
|
-
};
|
|
229
|
-
process.stdin.on("data", onData);
|
|
230
|
-
// Auto-decline after timeout
|
|
231
|
-
const timeout = setTimeout(() => {
|
|
232
|
-
cleanup();
|
|
233
|
-
resolve("no");
|
|
234
|
-
}, timeoutMs);
|
|
235
|
-
// Handle stdin closing
|
|
236
|
-
process.stdin.on("end", () => {
|
|
237
|
-
cleanup();
|
|
238
|
-
resolve("no");
|
|
239
|
-
});
|
|
240
|
-
function cleanup() {
|
|
241
|
-
clearTimeout(timeout);
|
|
242
|
-
process.stdin.removeListener("data", onData);
|
|
243
|
-
process.stdin.setRawMode?.(false);
|
|
244
|
-
process.stdin.pause();
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Check if --auto-install flag is set
|
|
250
|
-
*/
|
|
251
|
-
function isAutoInstallEnabled() {
|
|
252
|
-
// Check environment variable or process arguments
|
|
253
|
-
return (process.env.PI_LENS_AUTO_INSTALL === "1" ||
|
|
254
|
-
process.argv.includes("--auto-install"));
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Attempt to install a tool using the configured strategy.
|
|
258
|
-
*
|
|
259
|
-
* - "npm": global install via the resolved manager (npm/pnpm/yarn/bun)
|
|
260
|
-
* - "shell": run the static installCommand as argv (gem, dotnet, brew, etc.)
|
|
261
|
-
* - "manual": can't auto-install — print the command and return false
|
|
262
|
-
*/
|
|
263
|
-
export function _parseStaticInstallCommandForTest(command) {
|
|
264
|
-
const trimmed = command.trim();
|
|
265
|
-
// Shell-strategy commands in COMMON_LANGUAGES are deliberately simple static
|
|
266
|
-
// argv-style commands. Refuse metacharacters instead of routing through
|
|
267
|
-
// sh/powershell, so this installer path never executes shell text.
|
|
268
|
-
if (!trimmed || /[;&|<>$`\\\r\n]/.test(trimmed))
|
|
269
|
-
return undefined;
|
|
270
|
-
const [cmd, ...args] = trimmed.split(/\s+/);
|
|
271
|
-
return cmd ? [cmd, args] : undefined;
|
|
272
|
-
}
|
|
273
|
-
async function installTool(config) {
|
|
274
|
-
const { installCommand, packageName, installStrategy } = config;
|
|
275
|
-
if (installStrategy === "manual") {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
let invocation;
|
|
279
|
-
if (installStrategy === "npm" && packageName) {
|
|
280
|
-
// Resolve the machine's package manager (npm/pnpm/yarn/bun) rather than
|
|
281
|
-
// hardcoding npm — this global install is what makes an LSP server
|
|
282
|
-
// available on hosts without npm. The result lands in that manager's
|
|
283
|
-
// global bin dir, which `allAvailableGlobalBinDirs` already discovers.
|
|
284
|
-
const pm = await resolveNodePackageManager();
|
|
285
|
-
invocation = [pmBinary(pm), globalInstallArgs(pm, packageName)];
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
invocation = _parseStaticInstallCommandForTest(installCommand);
|
|
289
|
-
}
|
|
290
|
-
if (!invocation)
|
|
291
|
-
return false;
|
|
292
|
-
const [cmd, args] = invocation;
|
|
293
|
-
const result = await safeSpawnAsync(cmd, args, {
|
|
294
|
-
timeout: 180000,
|
|
295
|
-
ignoreAmbientSignal: true,
|
|
296
|
-
});
|
|
297
|
-
return result.status === 0;
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Prompt user for installation with timeout, or auto-install if flag set
|
|
301
|
-
*
|
|
302
|
-
* @param language - Language identifier (go, rust, yaml, json, bash)
|
|
303
|
-
* @param cwd - Project root
|
|
304
|
-
* @returns true if tool is/should be installed, false to skip
|
|
305
|
-
*/
|
|
306
|
-
export async function promptForInstall(language, cwd) {
|
|
307
|
-
const config = COMMON_LANGUAGES[language];
|
|
308
|
-
if (!config) {
|
|
309
|
-
// Not a common language, don't prompt
|
|
310
|
-
return false;
|
|
311
|
-
}
|
|
312
|
-
// Check cache first
|
|
313
|
-
const choices = await readChoices(cwd);
|
|
314
|
-
const cached = choices[config.toolId];
|
|
315
|
-
if (cached) {
|
|
316
|
-
// Cache valid for 30 days
|
|
317
|
-
const thirtyDays = 30 * 24 * 60 * 60 * 1000;
|
|
318
|
-
if (Date.now() - cached.timestamp < thirtyDays) {
|
|
319
|
-
if (cached.choice === "yes" || cached.choice === "auto") {
|
|
320
|
-
const toolAvailable = await isToolOnPath(config.toolId);
|
|
321
|
-
if (toolAvailable) {
|
|
322
|
-
return true;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
else {
|
|
326
|
-
return false; // User previously declined
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
// Check auto-install flag
|
|
331
|
-
if (isAutoInstallEnabled()) {
|
|
332
|
-
await saveChoice(cwd, config.toolId, "auto");
|
|
333
|
-
return installTool(config);
|
|
334
|
-
}
|
|
335
|
-
if (!canUseInteractivePrompt()) {
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
// For manual-only tools, skip the Y/n prompt because user must install manually.
|
|
339
|
-
if (config.installStrategy === "manual") {
|
|
340
|
-
await saveChoice(cwd, config.toolId, "no");
|
|
341
|
-
return false;
|
|
342
|
-
}
|
|
343
|
-
const answer = await promptUser(10000);
|
|
344
|
-
await saveChoice(cwd, config.toolId, answer);
|
|
345
|
-
if (answer === "yes") {
|
|
346
|
-
return installTool(config);
|
|
347
|
-
}
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Get install command for display purposes
|
|
352
|
-
*/
|
|
353
|
-
export function getInstallCommand(language) {
|
|
354
|
-
return COMMON_LANGUAGES[language]?.installCommand;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Get install strategy for a language (exposed for testing)
|
|
358
|
-
*/
|
|
359
|
-
export function getInstallStrategy(language) {
|
|
360
|
-
return COMMON_LANGUAGES[language]?.installStrategy;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Check if a language supports interactive install
|
|
364
|
-
*/
|
|
365
|
-
export function supportsInteractiveInstall(language) {
|
|
366
|
-
return language in COMMON_LANGUAGES;
|
|
367
|
-
}
|