@herbertgao/pi-extensions 2026.8.6 → 2026.8.8
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 +8 -6
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +320 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +79 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +27 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +66 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
- package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +17 -13
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +21 -6
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +20 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +5 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +174 -100
- package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +5 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +10 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +10 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/tool-schema.md +11 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +5 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +140 -97
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +63 -28
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/selectors/projections.ts +22 -15
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state-reducer.ts +11 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/tool/response-envelope.ts +11 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/tool/types.ts +11 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/multi-select-view.ts +31 -17
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/preview/preview-block-renderer.ts +15 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/wrapping-select.ts +15 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +86 -38
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +76 -9
- package/node_modules/@narumitw/pi-btw/README.md +120 -111
- package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-btw/package.json +10 -6
- package/node_modules/@narumitw/pi-btw/src/btw.ts +36 -40
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +45 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +44 -1856
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +4 -6
- package/node_modules/pi-lens/CHANGELOG.md +999 -0
- package/node_modules/pi-lens/README.md +117 -3
- package/node_modules/pi-lens/config/ruff/core.toml +42 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +126 -13
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +67 -11
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
- package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +381 -13
- package/node_modules/pi-lens/dist/clients/biome-client.js +61 -30
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +129 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +206 -0
- package/node_modules/pi-lens/dist/clients/cache-observability.js +353 -76
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +20 -1
- package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
- package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +123 -31
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +84 -14
- package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
- package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +8 -2
- package/node_modules/pi-lens/dist/clients/deps/typebox.js +8 -3
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +147 -33
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +52 -2
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +256 -88
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +9 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +9 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +8 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +60 -53
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +25 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +20 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +44 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +32 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +47 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +14 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +127 -28
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +275 -13
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +21 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +734 -64
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +188 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +21 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +22 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +316 -0
- package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
- package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +31 -0
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +109 -9
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +8 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +1114 -100
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
- package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +87 -8
- package/node_modules/pi-lens/dist/clients/knip-client.js +310 -10
- package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +9 -2
- package/node_modules/pi-lens/dist/clients/latency-logger.js +440 -11
- package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +128 -8
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1660 -164
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +83 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2423 -151
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
- package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +277 -16
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +79 -3
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/mcp/session.js +10 -2
- package/node_modules/pi-lens/dist/clients/module-report.js +22 -1
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +114 -23
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
- package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +154 -33
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +84 -14
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +23 -9
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-report.js +62 -27
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +8 -3
- package/node_modules/pi-lens/dist/clients/read-guard.js +253 -10
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +194 -31
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
- package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +21 -0
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +6 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +96 -7
- package/node_modules/pi-lens/dist/clients/runtime-context.js +8 -1
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +352 -45
- package/node_modules/pi-lens/dist/clients/runtime-session.js +373 -9
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +212 -79
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +620 -67
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +157 -24
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +184 -0
- package/node_modules/pi-lens/dist/clients/sg-runner.js +116 -22
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +6 -2
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +5 -2
- package/node_modules/pi-lens/dist/clients/startup-timing.js +19 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +151 -16
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +125 -20
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +1 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +61407 -48577
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +476 -57
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +132 -43
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/docs/agent-guide.md +6 -1
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +515 -506
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +19 -5
- package/node_modules/pi-lens/docs/globalconfig.md +3 -0
- package/node_modules/pi-lens/docs/language-coverage.md +71 -5
- package/node_modules/pi-lens/docs/mcp.md +2 -2
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/settings.md +19 -1
- package/node_modules/pi-lens/docs/usage.md +1 -0
- package/node_modules/pi-lens/package.json +27 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +15 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +2 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +2 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +57 -12
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +22 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +23 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +33 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +34 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +6 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +53 -1
- package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
- package/node_modules/pi-lens/scripts/install-selftest.mjs +99 -11
- package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +75 -0
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +285 -0
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +233 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +2 -0
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +80 -3
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +41 -0
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +36 -0
- package/node_modules/pi-mcp-adapter/README.md +47 -5
- package/node_modules/pi-mcp-adapter/cli.js +163 -1
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +25 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +5 -4
- package/node_modules/pi-mcp-adapter/index.ts +219 -32
- package/node_modules/pi-mcp-adapter/init.ts +36 -4
- package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
- package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +32 -21
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +3 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +31 -37
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +140 -2
- package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
- package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +2 -0
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +37 -0
- package/node_modules/pi-web-access/README.md +32 -13
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/chrome-cookies.ts +86 -15
- package/node_modules/pi-web-access/curator-page.ts +6 -3
- package/node_modules/pi-web-access/curator-server.ts +4 -1
- package/node_modules/pi-web-access/data-uri-sanitize.ts +406 -0
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +40 -5
- package/node_modules/pi-web-access/firecrawl.ts +18 -2
- package/node_modules/pi-web-access/gemini-search.ts +16 -4
- package/node_modules/pi-web-access/github-extract.ts +65 -36
- package/node_modules/pi-web-access/index.ts +60 -61
- package/node_modules/pi-web-access/openai-search.ts +17 -6
- package/node_modules/pi-web-access/package.json +1 -1
- package/node_modules/pi-web-access/page-query.ts +4 -2
- package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
- package/node_modules/pi-web-access/parallel.ts +2 -2
- package/node_modules/pi-web-access/pdf-extract.ts +18 -5
- package/node_modules/pi-web-access/query-rewrite.ts +51 -0
- package/node_modules/pi-web-access/serper.ts +211 -0
- package/node_modules/pi-web-access/ssrf-protection.ts +12 -2
- package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
- package/node_modules/pi-web-access/summary-review.ts +44 -22
- package/node_modules/pi-web-access/tavily.ts +16 -4
- package/node_modules/pi-web-access/utils.ts +87 -0
- package/node_modules/pi-web-access/valyu.ts +199 -0
- package/package.json +14 -14
|
@@ -9,6 +9,31 @@ note: |
|
|
|
9
9
|
the `unsafe` keyword should be removed) or it is misplaced (an unsafe
|
|
10
10
|
operation lives outside an `unsafe { … }` block and should be wrapped).
|
|
11
11
|
Either case warrants review.
|
|
12
|
+
|
|
13
|
+
Exempt when a `/// # Safety` doc-comment section precedes the function:
|
|
14
|
+
Rust's own convention (rustdoc's `missing_safety_doc` lint, and
|
|
15
|
+
clippy's `undocumented_unsafe_blocks`) is that an `unsafe fn` states
|
|
16
|
+
its caller obligations in a `# Safety` doc section instead of wrapping
|
|
17
|
+
its whole body in a redundant `unsafe { ... }` block — the function
|
|
18
|
+
signature IS the unsafe boundary, the doc section is where the
|
|
19
|
+
contract lives.
|
|
20
|
+
|
|
21
|
+
2026-08-20 (review round, refs #1806): the first ship of this valve
|
|
22
|
+
used `follows: {stopBy: end, kind: line_comment, regex: '#\s*Safety'}`,
|
|
23
|
+
copying the `SAFETY:`-comment shape from `no-chained-type-assertions`
|
|
24
|
+
too literally. `stopBy: end` scans EVERY preceding sibling all the way
|
|
25
|
+
to the top of the file — one `# Safety` comment ANYWHERE earlier
|
|
26
|
+
(a stray file-top note, or a doc block that belongs to a DIFFERENT,
|
|
27
|
+
earlier function) exempted every `unsafe fn` after it. Probe: a
|
|
28
|
+
documented function followed by two undocumented ones scored 0 hits;
|
|
29
|
+
the two alone scored 2. Fixed by bounding the backward scan with
|
|
30
|
+
`stopBy: {not: {kind: line_comment}}` — it stops at the first
|
|
31
|
+
non-comment sibling, so only the CONTIGUOUS run of `///`/`//` lines
|
|
32
|
+
directly above the function is searched, never an earlier function's
|
|
33
|
+
doc block or an unrelated comment further up the file. (This valve
|
|
34
|
+
shipped with zero corpus hits either side in the original PR —
|
|
35
|
+
corpus silence isn't proof of correctness; the fixtures below are
|
|
36
|
+
the whole evidence, deliberately adversarial.)
|
|
12
37
|
rule:
|
|
13
38
|
all:
|
|
14
39
|
- kind: function_item
|
|
@@ -19,3 +44,10 @@ rule:
|
|
|
19
44
|
has:
|
|
20
45
|
kind: unsafe_block
|
|
21
46
|
stopBy: end
|
|
47
|
+
- not:
|
|
48
|
+
follows:
|
|
49
|
+
stopBy:
|
|
50
|
+
not:
|
|
51
|
+
kind: line_comment
|
|
52
|
+
kind: line_comment
|
|
53
|
+
regex: '#\s*Safety'
|
package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
id: require-safety-comment-for-as-unknown-as
|
|
2
|
+
language: TypeScript
|
|
3
|
+
severity: error
|
|
4
|
+
metadata:
|
|
5
|
+
category: pi-lens-self-scan
|
|
6
|
+
message: "'x as unknown as T' with no nearby SAFETY: comment — state the invariant TypeScript can't check"
|
|
7
|
+
note: |
|
|
8
|
+
Narrowed port of dmmulroy/anti-slop's
|
|
9
|
+
`require-safety-comment-for-type-assertion`
|
|
10
|
+
(src/rules/require-safety-comment-for-type-assertion.ts, MIT).
|
|
11
|
+
Upstream requires a `SAFETY:` comment before EVERY non-const type
|
|
12
|
+
assertion (`as`/angle-bracket), walking up through statement-owner
|
|
13
|
+
node kinds looking for a preceding comment. This port narrows the
|
|
14
|
+
target to `x as unknown as T` specifically — the two-hop cast through
|
|
15
|
+
`unknown`. The 2026-08-19 audit found 2,180 non-const assertions
|
|
16
|
+
repo-wide and ZERO `SAFETY:` comments; requiring one on every
|
|
17
|
+
assertion would mean authoring ~1,750 comments in one PR. `as unknown
|
|
18
|
+
as` is the form that actually launders evidence (routes through the
|
|
19
|
+
top type rather than a single verifiable hop), and it is the exact
|
|
20
|
+
shape AGENTS.md's defect shape 13 already asks for in prose: "when a
|
|
21
|
+
call site hands the policy an outcome it did NOT derive... justify it
|
|
22
|
+
in a comment at the call site." This rule makes that convention
|
|
23
|
+
checkable for its most evidence-destroying form.
|
|
24
|
+
|
|
25
|
+
2026-08-20 (refs #1727, #1777): promoted `hint` -> `error`. `error` is
|
|
26
|
+
the only tier that maps to semantic `blocking`
|
|
27
|
+
(`clients/dispatch/runners/ast-grep-napi.ts`), so AGENTS.md's severity
|
|
28
|
+
policy requires a documented zero-false-positive audit here. Two
|
|
29
|
+
changes make that audit come out clean.
|
|
30
|
+
|
|
31
|
+
1. STRUCTURAL SCOPING: test paths are excluded (`ignores:` below). In a
|
|
32
|
+
test, `x as unknown as T` is almost always a partial test double —
|
|
33
|
+
reaching into a private field or stubbing the two methods of a
|
|
34
|
+
surface the subject actually calls. The "invariant TypeScript can't
|
|
35
|
+
check" there is "this stub covers what the code under test touches",
|
|
36
|
+
which is the test's own subject matter, not a hidden runtime claim.
|
|
37
|
+
Four-corpus census (2026-08-20) confirms the shape concentrates in
|
|
38
|
+
test paths rather than assuming it:
|
|
39
|
+
|
|
40
|
+
| corpus | total | test-path | non-test | suppressed |
|
|
41
|
+
|---|---:|---:|---:|---:|
|
|
42
|
+
| pi-lens (`clients/`+`tests/`) | 305 | 289 | 16 | 95% |
|
|
43
|
+
| pi core (`packages/`) | 182 | 155 | 27 | 85% |
|
|
44
|
+
| opencode (`packages/`) | 194 | 154 | 40 | 79% |
|
|
45
|
+
| oh-my-pi (`packages/`) | 1803 | 1644 | 159 | 91% |
|
|
46
|
+
|
|
47
|
+
This is a FALSE-NEGATIVE bias, deliberately, and it is not small:
|
|
48
|
+
289 uncommented `as unknown as` sites in pi-lens's own `tests/`
|
|
49
|
+
now raise NO diagnostic at all, where each previously raised an
|
|
50
|
+
`error` through `no-chained-type-assertions.yml`'s `unknown` arm.
|
|
51
|
+
The same trade costs 1,644 sites on oh-my-pi. It is a path glob,
|
|
52
|
+
not a semantic check — ast-grep cannot verify a cast is really a
|
|
53
|
+
test double, only that it lives under a test path.
|
|
54
|
+
|
|
55
|
+
2. REPO-SIDE REMEDIATION: the 16 remaining `clients/` sites were read
|
|
56
|
+
individually and each was given a truthful `SAFETY:` comment
|
|
57
|
+
naming the specific invariant (an optional Node API absent from
|
|
58
|
+
`@types/node`, a two-phase-init field filled before first read, a
|
|
59
|
+
`Object.fromEntries` key-type loss, a process-global stash). None
|
|
60
|
+
was a comment written to silence the rule; where the cast had no
|
|
61
|
+
justification it was replaced instead
|
|
62
|
+
(`clients/runtime-context.ts`).
|
|
63
|
+
|
|
64
|
+
Post-narrowing census on pi-lens: 0 findings over `clients/` +
|
|
65
|
+
`tests/`. The rule is tagged `metadata.category: pi-lens-self-scan`,
|
|
66
|
+
so CI's `npm run astgrep:self-scan` lane keeps it at zero.
|
|
67
|
+
|
|
68
|
+
Placement contract: a `SAFETY:` comment may directly precede the cast,
|
|
69
|
+
its enclosing statement, or an object-literal member (`pair`) containing
|
|
70
|
+
the cast. Array elements and call arguments are also supported through the
|
|
71
|
+
direct-cast arm when the comment is immediately above the cast expression.
|
|
72
|
+
JSX attributes, class static blocks, and switch cases are not comment
|
|
73
|
+
anchors for this valve; place those comments on the enclosing statement.
|
|
74
|
+
Inline comments remain valid, for example `/* SAFETY: ... */ x as unknown
|
|
75
|
+
as T`. Upstream walks an arbitrary number of statement-owner levels looking
|
|
76
|
+
for ANY preceding comment in the file; this port only checks one level up
|
|
77
|
+
from the assertion and one level up from its immediate containing
|
|
78
|
+
statement or supported object member. There is NO dominance verification:
|
|
79
|
+
the rule proves a comment is adjacent, never that the comment is true or
|
|
80
|
+
that it describes this cast.
|
|
81
|
+
|
|
82
|
+
2026-08-20 (#1847, found in #1843's review): the "one level up from
|
|
83
|
+
its immediate containing statement" kind list omitted
|
|
84
|
+
`export_statement` and `public_field_definition`, so a `SAFETY:`
|
|
85
|
+
comment placed directly above an exported cast (`export const b =
|
|
86
|
+
(x as unknown as T).y;`) or a class-field cast (`bar: unknown = (x as
|
|
87
|
+
unknown as T).y;`) could not satisfy the valve — the rule is
|
|
88
|
+
`error`-tier and semantically `blocking`, so this left no escape for
|
|
89
|
+
those two shapes. Added both kinds. Verified the containing-statement
|
|
90
|
+
walk already covers casts nested deeper without a new kind: a cast
|
|
91
|
+
inside a `static {}` init block or an arrow-function body still
|
|
92
|
+
resolves to an ancestor `lexical_declaration`/`variable_declaration`
|
|
93
|
+
already in the list (probed with ast-grep's own `--rule` scan, not
|
|
94
|
+
reasoning about the grammar from memory), and a `SAFETY:` comment on
|
|
95
|
+
an `export const` nested inside a `namespace` block clears the valve
|
|
96
|
+
through the same `export_statement` kind — `stopBy: end` already
|
|
97
|
+
walks past the namespace wrapper to find it. `readonly`/`abstract`/
|
|
98
|
+
`static`/private-`#name` class fields all parse to the same
|
|
99
|
+
`public_field_definition` kind, so one entry covers all of them.
|
|
100
|
+
|
|
101
|
+
2026-08-20 (#1852 review, F1): the same defect shape one more time —
|
|
102
|
+
an enum member's initializer cast (`enum Foo { A = (x as unknown as
|
|
103
|
+
T).y }`) has no recognized ancestor either. The member's own kind is
|
|
104
|
+
`enum_assignment` (probed the same way: `ast-grep scan --rule` against
|
|
105
|
+
a real `enum`/`const enum`/`export enum` snippet rather than guessing
|
|
106
|
+
from the export/field precedent). One `enum_assignment` kind entry
|
|
107
|
+
covers plain, `const`, and `export` enums alike, the same way
|
|
108
|
+
`public_field_definition` covered every class-field modifier —
|
|
109
|
+
`enum_assignment` is the member-list node itself, unaffected by
|
|
110
|
+
keywords on the enclosing `enum_declaration`. `declare enum` members
|
|
111
|
+
have no initializer expression to cast, so there is nothing to probe
|
|
112
|
+
there.
|
|
113
|
+
|
|
114
|
+
Matched pair with `no-chained-type-assertions.yml`. As of 2026-08-20
|
|
115
|
+
the two PARTITION the assertion space instead of overlapping: this
|
|
116
|
+
rule owns `x as unknown as T` (with the `SAFETY:` escape valve); that
|
|
117
|
+
rule owns the concrete `x as A as B` chain, which has no escape valve
|
|
118
|
+
because it has no legitimate reading. Before the split both rules
|
|
119
|
+
matched the identical `as unknown as` site list (verified: 16/16
|
|
120
|
+
pi-lens, 182/182 pi, 194/194 opencode), so every uncommented site
|
|
121
|
+
raised two diagnostics for one defect.
|
|
122
|
+
|
|
123
|
+
2026-08-20 (#1834): both `follows` checks used `stopBy: end`, which
|
|
124
|
+
scans EVERY preceding sibling all the way to the top of the enclosing
|
|
125
|
+
block, not just the comment directly above the cast. A `SAFETY:`
|
|
126
|
+
comment attached to one cast silently exempted every LATER cast in the
|
|
127
|
+
same block, including casts on a different subject with no
|
|
128
|
+
justification of their own. Probe: `// SAFETY: ...` above `const a =
|
|
129
|
+
(y as unknown as string).length` followed by an undocumented `const b
|
|
130
|
+
= (x as unknown as string).length` scored 0 hits; `b`'s cast should
|
|
131
|
+
have been flagged. Fixed the same way as `redundant-unsafe-function`'s
|
|
132
|
+
identical valve (PR #1821, refs #1806): bound the backward scan with
|
|
133
|
+
`stopBy: {not: {kind: comment}}`, so it stops at the first non-comment
|
|
134
|
+
sibling and only ever searches the CONTIGUOUS comment run directly
|
|
135
|
+
above the cast (or its containing statement), never an earlier
|
|
136
|
+
statement's comment. The "Scope and known gap" note above already
|
|
137
|
+
described this contiguous-comment intent; the shipped pattern didn't
|
|
138
|
+
implement it.
|
|
139
|
+
|
|
140
|
+
2026-08-20 (#1870): the pair arm is bounded by the nearest `pair`. An
|
|
141
|
+
outer object member's SAFETY comment must not suppress a cast in a nested
|
|
142
|
+
member, and a nested member's comment must not suppress a parent cast.
|
|
143
|
+
The direct-cast arm remains the precise escape valve for comments adjacent
|
|
144
|
+
to casts in array elements and call arguments.
|
|
145
|
+
ignores:
|
|
146
|
+
- "**/*.test.ts"
|
|
147
|
+
- "**/*.test.tsx"
|
|
148
|
+
- "**/*.test.mts"
|
|
149
|
+
- "**/*.test.cts"
|
|
150
|
+
- "**/*.spec.ts"
|
|
151
|
+
- "**/*.spec.tsx"
|
|
152
|
+
- "**/tests/**"
|
|
153
|
+
- "**/test/**"
|
|
154
|
+
- "**/__tests__/**"
|
|
155
|
+
rule:
|
|
156
|
+
pattern: $X as unknown as $Y
|
|
157
|
+
not:
|
|
158
|
+
any:
|
|
159
|
+
- follows:
|
|
160
|
+
kind: comment
|
|
161
|
+
regex: 'SAFETY\s*:'
|
|
162
|
+
stopBy: { not: { kind: comment } }
|
|
163
|
+
- inside:
|
|
164
|
+
stopBy: { kind: pair }
|
|
165
|
+
any:
|
|
166
|
+
- kind: pair
|
|
167
|
+
follows:
|
|
168
|
+
kind: comment
|
|
169
|
+
regex: 'SAFETY\s*:'
|
|
170
|
+
stopBy: { not: { kind: comment } }
|
|
171
|
+
- inside:
|
|
172
|
+
stopBy: end
|
|
173
|
+
any:
|
|
174
|
+
- kind: expression_statement
|
|
175
|
+
- kind: lexical_declaration
|
|
176
|
+
- kind: variable_declaration
|
|
177
|
+
- kind: return_statement
|
|
178
|
+
- kind: export_statement
|
|
179
|
+
- kind: public_field_definition
|
|
180
|
+
- kind: enum_assignment
|
|
181
|
+
follows:
|
|
182
|
+
kind: comment
|
|
183
|
+
regex: 'SAFETY\s*:'
|
|
184
|
+
stopBy: { not: { kind: comment } }
|
|
@@ -5,6 +5,11 @@ message: void 0 for undefined - use undefined directly
|
|
|
5
5
|
metadata:
|
|
6
6
|
weight: 2
|
|
7
7
|
category: slop
|
|
8
|
+
note: |
|
|
9
|
+
Replacing `void 0` with `undefined` can change behavior when a local binding
|
|
10
|
+
shadows `undefined`. Shadowing `undefined` is itself a defect, and this fix
|
|
11
|
+
does not attempt to detect it.
|
|
8
12
|
rule:
|
|
9
13
|
kind: unary_expression
|
|
10
14
|
pattern: "void 0"
|
|
15
|
+
fix: undefined
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Regenerate with `npm run astgrep:self-scan -- --update-baseline` AFTER triaging every new entry (fix the underlying finding, or confirm it's a legitimate exception and document why in the same PR). Never regenerate to silently swallow an unreviewed hit.",
|
|
3
|
+
"generatedAt": "2026-08-19T20:44:05.206Z",
|
|
4
|
+
"allowed": []
|
|
5
|
+
}
|
|
@@ -202,6 +202,13 @@ function createState(files) {
|
|
|
202
202
|
aborted: 0,
|
|
203
203
|
timedOutSweeps: 0,
|
|
204
204
|
timedOutFilesTotal: 0,
|
|
205
|
+
// #1618: per-reason breakdown of the same total. Populated from each
|
|
206
|
+
// sweep's `unconfirmedByReason` metadata when present; a sweep logged
|
|
207
|
+
// by a pre-#1618 build carries no such field, so its files are
|
|
208
|
+
// bucketed under "budget (pre-#1618 build)" — the ABSENT field is
|
|
209
|
+
// itself the vintage signal, not an assumption that every one of
|
|
210
|
+
// those files really was a budget timeout.
|
|
211
|
+
unconfirmedByReason: counter(),
|
|
205
212
|
sweeps: [],
|
|
206
213
|
progress: [],
|
|
207
214
|
},
|
|
@@ -367,6 +374,27 @@ async function analyzeLatency(files, state) {
|
|
|
367
374
|
if (timedOut > 0) {
|
|
368
375
|
ws.timedOutSweeps += 1;
|
|
369
376
|
ws.timedOutFilesTotal += timedOut;
|
|
377
|
+
// #1618: attribute by the REAL per-reason tally when the build
|
|
378
|
+
// that wrote this log line has it — a service-destroyed file
|
|
379
|
+
// must never count toward "hit the per-file budget" the way it
|
|
380
|
+
// used to (the forensics tool that found #1618 in the first
|
|
381
|
+
// place read this exact field and mis-blamed budget exhaustion
|
|
382
|
+
// for what were mostly service-destroyed files).
|
|
383
|
+
const byReason = entry.metadata?.unconfirmedByReason;
|
|
384
|
+
if (byReason && typeof byReason === "object") {
|
|
385
|
+
for (const [reason, count] of Object.entries(byReason)) {
|
|
386
|
+
const n = Number(count) || 0;
|
|
387
|
+
if (n > 0) ws.unconfirmedByReason.inc(reason, n);
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
// Vintage-attribution fallback: no `unconfirmedByReason` means
|
|
391
|
+
// this line predates #1618 — the absent field IS the signal,
|
|
392
|
+
// not proof every file here was really a budget timeout.
|
|
393
|
+
ws.unconfirmedByReason.inc(
|
|
394
|
+
"budget (pre-#1618 build)",
|
|
395
|
+
timedOut,
|
|
396
|
+
);
|
|
397
|
+
}
|
|
370
398
|
state.smellTotals.inc("lsp-workspace-file-timeouts");
|
|
371
399
|
pushTop(
|
|
372
400
|
ws.sweeps,
|
|
@@ -1217,11 +1245,21 @@ function buildReport(state) {
|
|
|
1217
1245
|
"Full LSP workspace sweeps that logged a start but never a completion (hang/kill signature — the 8h-hang class #383 hardened)",
|
|
1218
1246
|
ws.progress.slice(0, limit),
|
|
1219
1247
|
);
|
|
1248
|
+
// #1618: "hit the per-file budget" used to be this smell's blanket
|
|
1249
|
+
// description regardless of WHY a file was unconfirmed — the exact
|
|
1250
|
+
// mislabeling the forensics pass on this class found (81/111 "budget"
|
|
1251
|
+
// files were actually service-destroyed). Render the real breakdown when
|
|
1252
|
+
// available.
|
|
1253
|
+
const unconfirmedReasonBreakdown = ws.unconfirmedByReason
|
|
1254
|
+
.top(limit)
|
|
1255
|
+
.map(({ key, count }) => `${key}=${count}`)
|
|
1256
|
+
.join(", ");
|
|
1220
1257
|
addSmell(
|
|
1221
1258
|
smells,
|
|
1222
1259
|
"lsp-workspace-file-timeouts",
|
|
1223
1260
|
smellCount("lsp-workspace-file-timeouts"),
|
|
1224
|
-
`Full LSP sweeps
|
|
1261
|
+
`Full LSP sweeps produced an unconfirmed file (${ws.timedOutFilesTotal} files across ${ws.timedOutSweeps} sweeps)` +
|
|
1262
|
+
(unconfirmedReasonBreakdown ? ` — by reason: ${unconfirmedReasonBreakdown}` : ""),
|
|
1225
1263
|
ws.sweeps.slice(0, limit),
|
|
1226
1264
|
);
|
|
1227
1265
|
|
|
@@ -1257,6 +1295,11 @@ function buildReport(state) {
|
|
|
1257
1295
|
aborted: ws.aborted,
|
|
1258
1296
|
timedOutSweeps: ws.timedOutSweeps,
|
|
1259
1297
|
timedOutFilesTotal: ws.timedOutFilesTotal,
|
|
1298
|
+
// #1618: the real per-reason breakdown of `timedOutFilesTotal`.
|
|
1299
|
+
// "budget (pre-#1618 build)" means those log lines predate the
|
|
1300
|
+
// per-reason tally entirely — an older build's absence of the field,
|
|
1301
|
+
// not a claim those files really timed out.
|
|
1302
|
+
unconfirmedByReason: ws.unconfirmedByReason.toJSON(),
|
|
1260
1303
|
},
|
|
1261
1304
|
},
|
|
1262
1305
|
cascade: {
|
|
@@ -1458,6 +1501,15 @@ function printReport(report) {
|
|
|
1458
1501
|
console.log(
|
|
1459
1502
|
` started=${ws.started} completed=${ws.completed} incomplete=${ws.incomplete} aborted=${ws.aborted} fileTimeouts=${ws.timedOutFilesTotal} (in ${ws.timedOutSweeps} sweeps)`,
|
|
1460
1503
|
);
|
|
1504
|
+
// #1618: never let a flat count alone read as "budget exhaustion" —
|
|
1505
|
+
// print the real per-reason split (or its absence, which itself means
|
|
1506
|
+
// every line here predates the tally).
|
|
1507
|
+
const reasons = Object.entries(ws.unconfirmedByReason ?? {});
|
|
1508
|
+
if (reasons.length) {
|
|
1509
|
+
console.log(
|
|
1510
|
+
` by reason: ${reasons.map(([reason, count]) => `${reason}=${count}`).join(", ")}`,
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1461
1513
|
}
|
|
1462
1514
|
const wl = report.worklog;
|
|
1463
1515
|
if (wl && (wl.byModel.length || wl.byRuleModel.length)) {
|
|
@@ -39,6 +39,24 @@ export const SOURCE_OVERRIDES = {
|
|
|
39
39
|
url: "https://unpkg.com/@tree-sitter-grammars/tree-sitter-yaml@0.7.1/tree-sitter-yaml.wasm",
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Grammars committed under `vendor/grammars/` rather than fetched.
|
|
44
|
+
*
|
|
45
|
+
* tree-sitter-cue: no published wasm exists — npm's `tree-sitter-cue` is a
|
|
46
|
+
* native binding, the `tree-sitter-wasms` aggregator has no CUE, and upstream
|
|
47
|
+
* cuts no releases — so we build it from a pinned commit (#1522).
|
|
48
|
+
*/
|
|
49
|
+
export const VENDORED_GRAMMARS = {
|
|
50
|
+
"tree-sitter-cue.wasm": {
|
|
51
|
+
repo: "https://github.com/eonpatapon/tree-sitter-cue",
|
|
52
|
+
commit: "dd7b90e0770ff18070c515937ba3c3d6d93db00e",
|
|
53
|
+
license: "MIT",
|
|
54
|
+
buildCommand: "npx tree-sitter-cli build --wasm",
|
|
55
|
+
sha256: "sha256:751f8cc8ccf72da760133e3d365562ff7bbf5b951e0b73568576fd159db7d601",
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
/** Directory the committed grammars live in, relative to the package root. */
|
|
59
|
+
export const VENDORED_DIR = "vendor/grammars";
|
|
42
60
|
/** The package a grammar's sidecar records (override or the global aggregator). */
|
|
43
61
|
export function expectedPackage(filename, manifest) {
|
|
44
62
|
return manifest.overrides?.[filename]?.package ?? SOURCE_OVERRIDES[filename]?.package ?? manifest.package;
|
|
@@ -210,6 +228,13 @@ async function regenerateManifest() {
|
|
|
210
228
|
version: TREE_SITTER_WASMS_VERSION,
|
|
211
229
|
grammars: sorted,
|
|
212
230
|
...(Object.keys(SOURCE_OVERRIDES).length ? { overrides: SOURCE_OVERRIDES } : {}),
|
|
231
|
+
// Re-emitted from the map above, not copied from the old manifest: a
|
|
232
|
+
// `--write-manifest` run on a tree-sitter-wasms bump must not silently
|
|
233
|
+
// drop the committed grammars' provenance, which would leave the guard
|
|
234
|
+
// with nothing to check.
|
|
235
|
+
...(Object.keys(VENDORED_GRAMMARS).length
|
|
236
|
+
? { vendored: VENDORED_GRAMMARS }
|
|
237
|
+
: {}),
|
|
213
238
|
};
|
|
214
239
|
writeFileSync(MANIFEST_PATH, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
215
240
|
console.error(`Wrote ${MANIFEST_PATH} (${GRAMMARS.length} grammars).`);
|
|
@@ -40,5 +40,14 @@
|
|
|
40
40
|
"version": "0.7.1",
|
|
41
41
|
"url": "https://unpkg.com/@tree-sitter-grammars/tree-sitter-yaml@0.7.1/tree-sitter-yaml.wasm"
|
|
42
42
|
}
|
|
43
|
+
},
|
|
44
|
+
"vendored": {
|
|
45
|
+
"tree-sitter-cue.wasm": {
|
|
46
|
+
"repo": "https://github.com/eonpatapon/tree-sitter-cue",
|
|
47
|
+
"commit": "dd7b90e0770ff18070c515937ba3c3d6d93db00e",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"buildCommand": "npx tree-sitter-cli build --wasm",
|
|
50
|
+
"sha256": "sha256:751f8cc8ccf72da760133e3d365562ff7bbf5b951e0b73568576fd159db7d601"
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
}
|
|
@@ -19,6 +19,20 @@
|
|
|
19
19
|
* build-script-provided assets (ast-grep CLI binary + tree-sitter grammars)
|
|
20
20
|
* that pnpm/bun skip by default. It runs no model and needs no credentials.
|
|
21
21
|
*
|
|
22
|
+
* WHAT IT NO LONGER COVERS (#1926)
|
|
23
|
+
* pi supplies `typebox` and `@earendil-works/pi-tui` from its own runtime, so
|
|
24
|
+
* they are optional peers and no install vendors them. This probe is not pi, so
|
|
25
|
+
* those specifiers cannot resolve here, and `dist/index.js` throws on the FIRST
|
|
26
|
+
* one it imports. A host-provided miss is therefore recorded as EXPECTED rather
|
|
27
|
+
* than failed. The cost is real and stated plainly: evaluation stops there, so
|
|
28
|
+
* the entry probe no longer proves the whole bundled graph resolves, which is
|
|
29
|
+
* what #285 and #335 asked it to prove. Any OTHER unresolved specifier still
|
|
30
|
+
* fails hard, and the per-module probes below (file-utils, complexity-client,
|
|
31
|
+
* bootstrap) still cover that graph directly. The surviving POSITIVE proof that
|
|
32
|
+
* the entry loads in full is the install-smoke `pi-load` job: it installs pi,
|
|
33
|
+
* installs pi-lens through pi, and confirms over RPC that pi-lens registered
|
|
34
|
+
* its commands.
|
|
35
|
+
*
|
|
22
36
|
* USAGE
|
|
23
37
|
* bun scripts/install-selftest.mjs # faithful: pi's runtime is bun
|
|
24
38
|
* node scripts/install-selftest.mjs # also works
|
|
@@ -28,10 +42,11 @@
|
|
|
28
42
|
*/
|
|
29
43
|
|
|
30
44
|
import { execFileSync } from "node:child_process";
|
|
45
|
+
import * as fs from "node:fs";
|
|
31
46
|
import { createRequire } from "node:module";
|
|
32
|
-
import { fileURLToPath } from "node:url";
|
|
33
47
|
import * as path from "node:path";
|
|
34
|
-
import
|
|
48
|
+
import { fileURLToPath } from "node:url";
|
|
49
|
+
import { HOST_PROVIDED_PACKAGES } from "./lib/host-provided-deps.mjs";
|
|
35
50
|
|
|
36
51
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
37
52
|
const pkgRoot = path.resolve(here, "..");
|
|
@@ -42,6 +57,26 @@ const results = [];
|
|
|
42
57
|
const record = (name, kind, ok, detail = "") =>
|
|
43
58
|
results.push({ name, kind, ok, detail });
|
|
44
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Which host-provided package, if any, a resolution error is about. Returns
|
|
62
|
+
* undefined for every other error, so an unrelated missing package still fails.
|
|
63
|
+
*/
|
|
64
|
+
function hostProvidedMiss(err) {
|
|
65
|
+
const text = `${err?.code || ""} ${err?.message || err}`;
|
|
66
|
+
if (
|
|
67
|
+
!/ERR_MODULE_NOT_FOUND|Cannot find (package|module)|ResolveMessage/.test(
|
|
68
|
+
text,
|
|
69
|
+
)
|
|
70
|
+
) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return HOST_PROVIDED_PACKAGES.find((name) =>
|
|
74
|
+
new RegExp(
|
|
75
|
+
`['"\`]${name.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&")}['"\`]`,
|
|
76
|
+
).test(text),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
45
80
|
/** Import a module by URL and record whether its (eager) dep graph resolved. */
|
|
46
81
|
async function probeImport(name, relPath) {
|
|
47
82
|
const url = new URL(
|
|
@@ -51,7 +86,24 @@ async function probeImport(name, relPath) {
|
|
|
51
86
|
await import(url.href);
|
|
52
87
|
record(name, "resolve", true);
|
|
53
88
|
} catch (err) {
|
|
54
|
-
|
|
89
|
+
// #1926: pi supplies these; outside pi they cannot resolve, and the entry
|
|
90
|
+
// throws on the first one. Expected, not a regression. Anything else is.
|
|
91
|
+
const host = hostProvidedMiss(err);
|
|
92
|
+
if (host) {
|
|
93
|
+
record(
|
|
94
|
+
name,
|
|
95
|
+
"expected",
|
|
96
|
+
true,
|
|
97
|
+
`stopped at host-provided '${host}' — pi supplies it; graph beyond this point unproven here (#1926)`,
|
|
98
|
+
);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
record(
|
|
102
|
+
name,
|
|
103
|
+
"resolve",
|
|
104
|
+
false,
|
|
105
|
+
`${err?.code || ""} ${err?.message || err}`.trim(),
|
|
106
|
+
);
|
|
55
107
|
}
|
|
56
108
|
}
|
|
57
109
|
|
|
@@ -61,27 +113,53 @@ function probeResolve(spec) {
|
|
|
61
113
|
require.resolve(spec);
|
|
62
114
|
record(spec, "resolve", true);
|
|
63
115
|
} catch (err) {
|
|
64
|
-
record(
|
|
116
|
+
record(
|
|
117
|
+
spec,
|
|
118
|
+
"resolve",
|
|
119
|
+
false,
|
|
120
|
+
`${err?.code || ""} ${err?.message || err}`.trim(),
|
|
121
|
+
);
|
|
65
122
|
}
|
|
66
123
|
}
|
|
67
124
|
|
|
68
125
|
// --- 1. The documented failure-point modules (eager bare imports) ----------
|
|
69
126
|
await probeImport("dist/index.js (entry)", "dist/index.js");
|
|
70
|
-
await probeImport(
|
|
71
|
-
|
|
72
|
-
|
|
127
|
+
await probeImport(
|
|
128
|
+
"clients/file-utils.js (→ minimatch)",
|
|
129
|
+
"dist/clients/file-utils.js",
|
|
130
|
+
);
|
|
131
|
+
await probeImport(
|
|
132
|
+
"clients/complexity-client.js (→ tree-sitter)",
|
|
133
|
+
"dist/clients/complexity-client.js",
|
|
134
|
+
);
|
|
135
|
+
await probeImport(
|
|
136
|
+
"clients/bootstrap.js (→ all analyzers)",
|
|
137
|
+
"dist/clients/bootstrap.js",
|
|
138
|
+
);
|
|
73
139
|
|
|
74
140
|
// --- 2. Direct bare-specifier resolution -----------------------------------
|
|
75
|
-
|
|
141
|
+
// Host-provided packages are subtracted, not listed as exceptions: pi resolves
|
|
142
|
+
// them from its own runtime, so nothing installs them and probing one here is
|
|
143
|
+
// guaranteed to fail (#1926). The subtraction reads the same list the bundler
|
|
144
|
+
// and the packaging tests use, so it cannot drift.
|
|
145
|
+
const BARE_SPECIFIERS = [
|
|
76
146
|
"minimatch",
|
|
77
147
|
"typebox",
|
|
78
148
|
"js-yaml",
|
|
79
149
|
"vscode-jsonrpc",
|
|
80
150
|
"web-tree-sitter",
|
|
81
151
|
"@ast-grep/napi",
|
|
82
|
-
])
|
|
152
|
+
].filter((spec) => !HOST_PROVIDED_PACKAGES.includes(spec));
|
|
153
|
+
|
|
154
|
+
for (const spec of BARE_SPECIFIERS) {
|
|
83
155
|
probeResolve(spec);
|
|
84
156
|
}
|
|
157
|
+
record(
|
|
158
|
+
"host-provided specifiers skipped",
|
|
159
|
+
"expected",
|
|
160
|
+
true,
|
|
161
|
+
`${HOST_PROVIDED_PACKAGES.join(", ")} — pi supplies these (#1926)`,
|
|
162
|
+
);
|
|
85
163
|
|
|
86
164
|
// --- 3. Spawned-binary tools (the universal net) ----------------------------
|
|
87
165
|
// For every tool that ships its binary in a per-platform npm package
|
|
@@ -121,11 +199,21 @@ try {
|
|
|
121
199
|
});
|
|
122
200
|
record(label, "tool", true, bin);
|
|
123
201
|
} catch (err) {
|
|
124
|
-
record(
|
|
202
|
+
record(
|
|
203
|
+
label,
|
|
204
|
+
"tool",
|
|
205
|
+
false,
|
|
206
|
+
`${bin} failed to run: ${err?.message || err}`,
|
|
207
|
+
);
|
|
125
208
|
}
|
|
126
209
|
}
|
|
127
210
|
} catch (err) {
|
|
128
|
-
record(
|
|
211
|
+
record(
|
|
212
|
+
"spawned-tool probe",
|
|
213
|
+
"tool",
|
|
214
|
+
false,
|
|
215
|
+
`installer load failed: ${err?.message || err}`,
|
|
216
|
+
);
|
|
129
217
|
}
|
|
130
218
|
|
|
131
219
|
// tree-sitter grammars — download-grammars.js postinstall writes them into
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the packages `scripts/bundle-dist.mjs` keeps out of
|
|
3
|
+
* the dist bundle, split by the REASON they stay external. #1926.
|
|
4
|
+
*
|
|
5
|
+
* HOST_PROVIDED_PACKAGES
|
|
6
|
+
* pi ships these inside its own runtime (`@earendil-works/pi-coding-agent`'s
|
|
7
|
+
* node_modules). They must be declared as OPTIONAL peer dependencies plus dev
|
|
8
|
+
* dependencies, never as runtime `dependencies`, because a runtime dependency
|
|
9
|
+
* makes `npm install --omit=dev` — the command pi runs for a `git:` install —
|
|
10
|
+
* vendor a private second copy into the extension's own node_modules. Node
|
|
11
|
+
* then resolves the bare specifier to that copy and evaluates a whole extra
|
|
12
|
+
* module graph at import. That is #1926: vendoring `typebox` and
|
|
13
|
+
* `@earendil-works/pi-tui` cost 720ms of the 838ms git-install import, and
|
|
14
|
+
* removing the copies took the PI_TIMING module import from 941ms to ~180ms.
|
|
15
|
+
*
|
|
16
|
+
* The three entries are NOT interchangeable at runtime. pi resolves the bare
|
|
17
|
+
* specifiers `typebox` and `@earendil-works/pi-tui` for an extension, so
|
|
18
|
+
* VALUE imports of those work with no copy on disk — verified by hiding both
|
|
19
|
+
* from the dogfood install and re-running under PI_TIMING (#1926), and by
|
|
20
|
+
* `@tintinweb/pi-subagents`, which declares pi-tui as a peer and ships no
|
|
21
|
+
* copy. `@earendil-works/pi-coding-agent` is different: it is not resolvable
|
|
22
|
+
* from an extension at all, so pi-lens imports it TYPE-ONLY and inlines the
|
|
23
|
+
* runtime helpers it needs. `tests/host-sdk-type-only.test.ts` enforces that
|
|
24
|
+
* separate rule (#1334 S6); do not read this list as permission to
|
|
25
|
+
* value-import the host SDK.
|
|
26
|
+
*
|
|
27
|
+
* LAZY_NATIVE_PACKAGES
|
|
28
|
+
* Native addon / wasm, dynamic-imported by absolute file:// URL at call time.
|
|
29
|
+
* They stay external because esbuild cannot inline a .node or .wasm, and they
|
|
30
|
+
* cost nothing at load because nothing imports them statically.
|
|
31
|
+
*
|
|
32
|
+
* `tests/packaging.test.ts` pins both invariants against package.json and
|
|
33
|
+
* against the built dist entry, so this list cannot drift from what ships.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Host-provided packages the extension VALUE-imports. pi resolves these bare
|
|
38
|
+
* specifiers at runtime, so the compiled entry cannot load without them.
|
|
39
|
+
* Outside pi — a bare `node dist/index.js` in a CI smoke check — nothing
|
|
40
|
+
* supplies them, so a job that wants a FULL load has to install them first, the
|
|
41
|
+
* way pi does. `scripts/supply-host-provided-deps.mjs` does that.
|
|
42
|
+
*/
|
|
43
|
+
export const HOST_PROVIDED_RUNTIME_PACKAGES = Object.freeze([
|
|
44
|
+
"typebox",
|
|
45
|
+
"@earendil-works/pi-tui",
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Host-provided packages the extension imports TYPE-ONLY. pi does not resolve
|
|
50
|
+
* these for an extension at all, which is why every runtime helper pi-lens
|
|
51
|
+
* needs from the host SDK is inlined instead; `tests/host-sdk-type-only.test.ts`
|
|
52
|
+
* enforces that (#1334 S6). Never install one of these to make a load succeed:
|
|
53
|
+
* the transitive tree has nested paths that exceed Windows MAX_PATH.
|
|
54
|
+
*/
|
|
55
|
+
export const HOST_PROVIDED_TYPE_ONLY_PACKAGES = Object.freeze([
|
|
56
|
+
"@earendil-works/pi-coding-agent",
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
/** Everything pi supplies, so pi-lens must never declare it a dependency. */
|
|
60
|
+
export const HOST_PROVIDED_PACKAGES = Object.freeze([
|
|
61
|
+
...HOST_PROVIDED_RUNTIME_PACKAGES,
|
|
62
|
+
...HOST_PROVIDED_TYPE_ONLY_PACKAGES,
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
/** Native/wasm packages dynamic-imported by absolute path at call time. */
|
|
66
|
+
export const LAZY_NATIVE_PACKAGES = Object.freeze([
|
|
67
|
+
"@ast-grep/napi",
|
|
68
|
+
"web-tree-sitter",
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
/** Everything esbuild must NOT inline into dist/index.js. */
|
|
72
|
+
export const BUNDLE_EXTERNALS = Object.freeze([
|
|
73
|
+
...HOST_PROVIDED_PACKAGES,
|
|
74
|
+
...LAZY_NATIVE_PACKAGES,
|
|
75
|
+
]);
|