@herbertgao/pi-extensions 2026.9.2 → 2026.9.4
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 +4 -2
- package/THIRD_PARTY_NOTICES.md +49 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +3 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +16 -11
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +20 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +12 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +98 -0
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/sol-pi/LICENSE +19 -0
- package/node_modules/@herbertgao/sol-pi/README.md +159 -0
- package/node_modules/@herbertgao/sol-pi/SECURITY.md +26 -0
- package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +19 -0
- package/node_modules/@herbertgao/sol-pi/agents-install.md +150 -0
- package/node_modules/@herbertgao/sol-pi/assets/sol-pi-hero.png +0 -0
- package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +69 -0
- package/node_modules/@herbertgao/sol-pi/docs/configuration.md +75 -0
- package/node_modules/@herbertgao/sol-pi/package.json +76 -0
- package/node_modules/@herbertgao/sol-pi/scripts/check-pi-compat.mjs +32 -0
- package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +120 -0
- package/node_modules/@herbertgao/sol-pi/sol-pi.example.json +10 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +135 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +74 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +185 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +128 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/archive.ts +53 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/candidate.ts +101 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/config.ts +71 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/index.ts +220 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/journal.ts +25 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/provider.ts +164 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/receipt.ts +177 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/index.ts +227 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/ledger.ts +20 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +252 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +237 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +455 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +49 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +79 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +208 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +100 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/index.ts +42 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +17 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/tui.ts +71 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +12 -2
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +2 -2
- package/node_modules/@narumitw/pi-btw/package.json +1 -1
- package/node_modules/@narumitw/pi-btw/src/btw.ts +13 -2
- package/node_modules/pi-antigravity/LICENSE +21 -0
- package/node_modules/pi-antigravity/README.md +194 -0
- package/node_modules/pi-antigravity/package.json +67 -0
- package/node_modules/pi-antigravity/src/auth/index.ts +14 -0
- package/node_modules/pi-antigravity/src/auth/oauth.ts +442 -0
- package/node_modules/pi-antigravity/src/client/client.ts +561 -0
- package/node_modules/pi-antigravity/src/client/index.ts +1 -0
- package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +96 -0
- package/node_modules/pi-antigravity/src/diagnostics/index.ts +1 -0
- package/node_modules/pi-antigravity/src/image/image.ts +336 -0
- package/node_modules/pi-antigravity/src/image/index.ts +1 -0
- package/node_modules/pi-antigravity/src/index.ts +280 -0
- package/node_modules/pi-antigravity/src/models/discovery.ts +154 -0
- package/node_modules/pi-antigravity/src/models/grouping.ts +424 -0
- package/node_modules/pi-antigravity/src/models/index.ts +3 -0
- package/node_modules/pi-antigravity/src/models/models.ts +500 -0
- package/node_modules/pi-antigravity/src/stream/index.ts +1 -0
- package/node_modules/pi-antigravity/src/stream/stream.ts +1460 -0
- package/node_modules/pi-antigravity/src/types/enums.ts +42 -0
- package/node_modules/pi-antigravity/src/types/index.ts +2 -0
- package/node_modules/pi-antigravity/src/types/types.ts +292 -0
- package/node_modules/pi-antigravity/src/usage/index.ts +1 -0
- package/node_modules/pi-antigravity/src/usage/usage.ts +371 -0
- package/node_modules/pi-antigravity/src/utils/http.ts +91 -0
- package/node_modules/pi-antigravity/src/utils/index.ts +3 -0
- package/node_modules/pi-antigravity/src/utils/security.ts +73 -0
- package/node_modules/pi-antigravity/src/utils/util.ts +132 -0
- package/node_modules/pi-antigravity/tsconfig.json +21 -0
- package/node_modules/pi-lens/CHANGELOG.md +176 -0
- package/node_modules/pi-lens/README.md +13 -8
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -1
- package/node_modules/pi-lens/dist/clients/analysed-root.js +1 -0
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +13 -2
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +2 -0
- package/node_modules/pi-lens/dist/clients/cache-observability.js +122 -1
- package/node_modules/pi-lens/dist/clients/complexity-client.js +5 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +2 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +6 -3
- package/node_modules/pi-lens/dist/clients/config-schema.js +17 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +2 -2
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +8 -1
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +38 -15
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +2 -1
- 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 +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +19 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +12 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +12 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.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 +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +8 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +4 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/effective-config.js +12 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +4 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +54 -188
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -0
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +42 -6
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +48 -7
- package/node_modules/pi-lens/dist/clients/installer/index.js +196 -52
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +9 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +12 -2
- package/node_modules/pi-lens/dist/clients/latency-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/lens-config.js +4 -0
- package/node_modules/pi-lens/dist/clients/lsp/config.js +36 -7
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +24 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +78 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +281 -45
- package/node_modules/pi-lens/dist/clients/lsp/server.js +62 -15
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +37 -4
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +3 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +2 -0
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +2 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +2 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +8 -3
- package/node_modules/pi-lens/dist/clients/pipeline.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +38 -10
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +10 -9
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/ruff-client.js +18 -9
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +9 -0
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +5 -0
- package/node_modules/pi-lens/dist/clients/runtime-session.js +13 -4
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +4 -1
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +48 -1
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -2
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +69 -1
- package/node_modules/pi-lens/dist/clients/sg-runner.js +2 -1
- package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +108 -0
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +291 -76
- package/node_modules/pi-lens/dist/clients/tool-config.js +199 -0
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +299 -0
- package/node_modules/pi-lens/dist/clients/tool-probe.js +53 -0
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +42 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +9 -1
- package/node_modules/pi-lens/dist/clients/turn-context.js +52 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +4 -3
- package/node_modules/pi-lens/dist/index.js +21969 -20005
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -2
- package/node_modules/pi-lens/dist/mcp/server.js +135 -159
- package/node_modules/pi-lens/dist/tools/activate-tools.js +10 -7
- package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +2 -13
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +8 -13
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +83 -39
- package/node_modules/pi-lens/dist/tools/effective-config.js +4 -3
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +1 -10
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +353 -85
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +21 -110
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +20 -44
- package/node_modules/pi-lens/dist/tools/module-report.js +5 -9
- package/node_modules/pi-lens/dist/tools/project-report.js +9 -17
- package/node_modules/pi-lens/dist/tools/render-compact.js +280 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +2 -2
- package/node_modules/pi-lens/docs/agent-guide.md +3 -4
- package/node_modules/pi-lens/docs/agent-tools.md +46 -22
- package/node_modules/pi-lens/docs/configuration.md +9 -0
- package/node_modules/pi-lens/docs/environment-variables.md +0 -5
- package/node_modules/pi-lens/docs/features.md +5 -5
- package/node_modules/pi-lens/docs/globalconfig.md +11 -1
- package/node_modules/pi-lens/docs/mcp.md +13 -1
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +71 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +15 -0
- package/node_modules/pi-lens/docs/pi-lens-monitor.md +88 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +35 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +12 -4
- package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
- package/node_modules/pi-lens/docs/real-harness.md +46 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +5 -1
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -6
- package/node_modules/pi-lens/docs/settings.md +37 -2
- package/node_modules/pi-lens/docs/tools_improvement2.md +4 -4
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
- package/node_modules/pi-lens/docs/usage.md +13 -3
- package/node_modules/pi-lens/package.json +10 -1
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +7 -3
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +8 -6
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +19 -9
- package/node_modules/pi-web-access/CHANGELOG.md +29 -0
- package/node_modules/pi-web-access/README.md +33 -22
- package/node_modules/pi-web-access/abortable.ts +17 -0
- package/node_modules/pi-web-access/crawl4ai.ts +204 -0
- package/node_modules/pi-web-access/credential-source.ts +1 -0
- package/node_modules/pi-web-access/curator-page.ts +20 -2
- package/node_modules/pi-web-access/curator-run.ts +44 -0
- package/node_modules/pi-web-access/curator-server.ts +3 -1
- package/node_modules/pi-web-access/duckduckgo.ts +1 -1
- package/node_modules/pi-web-access/extract.ts +57 -12
- package/node_modules/pi-web-access/fetch-params.ts +1 -1
- package/node_modules/pi-web-access/gemini-search.ts +9 -5
- package/node_modules/pi-web-access/index.ts +25 -18
- package/node_modules/pi-web-access/openai-search.ts +35 -13
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +5 -2
- package/node_modules/pi-web-access/query-rewrite.ts +5 -2
- package/node_modules/pi-web-access/serpapi.ts +220 -0
- package/node_modules/pi-web-access/ssrf-protection.ts +5 -1
- package/node_modules/pi-web-access/storage.ts +10 -0
- package/node_modules/pi-web-access/summary-review.ts +34 -21
- package/node_modules/pi-web-access/utils.ts +6 -4
- package/package.json +11 -5
- package/node_modules/pi-lens/dist/tools/ast-dump.js +0 -103
|
@@ -23,3 +23,74 @@ redesigned before the fix is complete.
|
|
|
23
23
|
Verify the build and every targeted or sibling suite required by repository
|
|
24
24
|
policy. Follow the shared contract's Git authority. Report what ran, what was
|
|
25
25
|
skipped, and why. Use active, plain prose.
|
|
26
|
+
|
|
27
|
+
## Standard mechanics (apply unless the brief overrides)
|
|
28
|
+
|
|
29
|
+
A fix on `clients/lsp/`, the read guard, tool registration, or session lifecycle adds or updates a real-harness scenario when the defect is only observable through the host; the scenario is the red-first proof where a unit seam cannot show it.
|
|
30
|
+
|
|
31
|
+
- Every language pi-lens supports (`LANGUAGES` in `clients/language-registry.ts`),
|
|
32
|
+
never one: a fix on an LSP, dispatch, cache or tool seam is stated in
|
|
33
|
+
language-neutral terms, names which registry entries carry the facts it
|
|
34
|
+
needs and which fall to the honest fallback, and its test matrix has at
|
|
35
|
+
least one non-TypeScript row (catalog shape 42).
|
|
36
|
+
- `npm run build` before any test run; rebuild between mutations. Tests run as
|
|
37
|
+
`PI_LENS_HOME=$PWD/.probe-home node_modules/.bin/vitest run <files> --configLoader runner`
|
|
38
|
+
(sweeps get `30_000`). A CI-only red is reproduced in the job's shape first
|
|
39
|
+
(`npm test` PATH prefix, pinned `HOME`, no `PI_LENS_HOME`).
|
|
40
|
+
- When a task regenerates `package-lock.json`, use the exact npm version in
|
|
41
|
+
`package.json`'s `packageManager` field, which is also the CI production-install pin.
|
|
42
|
+
- Required test set = the named files + every test that mocks (`vi.mock`) or
|
|
43
|
+
deep-equals a module or record you touched + `tests/config/` when you add a
|
|
44
|
+
real-spawn test or a fixture + the flake-shape ratchet when you touch waits.
|
|
45
|
+
- Never `vi.waitFor` with real timers; never a `// flake-shape` admission for
|
|
46
|
+
a test you wrote; never `git stash`; never edit `CHANGELOG.md` (one fragment
|
|
47
|
+
under `.changelog/`, exactly one top-level entry).
|
|
48
|
+
- Every test id, probe id or fixture name you write into a PR-body table
|
|
49
|
+
(state-space, writers-by-axis, population) must exist as a grep-able `it(`
|
|
50
|
+
title or file name in the tree at handoff. The orchestrator greps each id
|
|
51
|
+
before accepting the round; a table whose ids do not exist is a fabricated
|
|
52
|
+
claim and fails the round (2026-09-10: #2877 r3 and #2868 r3 each shipped a
|
|
53
|
+
48- to 72-cell table with zero real ids).
|
|
54
|
+
- A claim about the HOST or the ENVIRONMENT is a transcript, not a sentence.
|
|
55
|
+
"pi does not re-run the factory on resume", "this failure is pre-existing on
|
|
56
|
+
master", "the harness cannot fire that event" — each carries the command and
|
|
57
|
+
output that measured it in the same environment (a probe extension against
|
|
58
|
+
real pi in rpc mode; the same test file run on origin/master in the same
|
|
59
|
+
tree). 2026-09-10: three rounds on #2866 and #2878 were built on unmeasured
|
|
60
|
+
host claims the verify overturned, and "pre-existing analyze-cli red" was
|
|
61
|
+
reported by four workers whose sandbox differed from CI and master.
|
|
62
|
+
- When a fix is a RULE (a scanner's scope rule, a lifecycle rule, a
|
|
63
|
+
classification), derive it from the source of truth and enumerate from
|
|
64
|
+
there — the tree-sitter grammar table, pi's pinned event types measured
|
|
65
|
+
live, the client's real return sites — never from a hand-written list of
|
|
66
|
+
the cases the reviewer named. Seven rounds on #2877 each closed the named
|
|
67
|
+
launderer and left the next scope kind open until round 4 generated the
|
|
68
|
+
scope table from the grammar.
|
|
69
|
+
- A change to a release-QA row (`docs/release-qa-baseline.md` +
|
|
70
|
+
`scripts/release-qa.mjs`) runs `node scripts/release-qa.mjs` end to end
|
|
71
|
+
once on the pushed head and quotes the verdict line in the body; the
|
|
72
|
+
row↔probe tie test cannot see a row that never passes (#2893).
|
|
73
|
+
- Before handoff, run `npm run preflight` last and paste its table in
|
|
74
|
+
`PR_BODY.md` — a handoff without it is incomplete.
|
|
75
|
+
- One set of template headings per PR. A fix round APPENDS `## Round N` and
|
|
76
|
+
edits the existing `## Observability` / `## Tests` sections in place; it
|
|
77
|
+
never adds a second `## Observability` (the lint reads the first one, and a
|
|
78
|
+
stale first section was the most common `PR body` red on 2026-09-10). Lint
|
|
79
|
+
the FULL body you will publish (`gh pr view <n> --json body -q .body` plus
|
|
80
|
+
your round), against the real `origin/master...HEAD` diff (fetch first),
|
|
81
|
+
not a hand-shaped diff.
|
|
82
|
+
- `PR_BODY.md` passes `node scripts/check-pr-body.mjs --lint-local PR_BODY.md`
|
|
83
|
+
before handoff. The gate requires the headings `## Summary`, `## Tests`,
|
|
84
|
+
`## Blast radius`, `## Class sweep`, `## Observability`, and
|
|
85
|
+
`## Test assessment` whenever the diff touches `tests/`; Observability
|
|
86
|
+
names a record literal that appears in the runtime diff, and may say
|
|
87
|
+
exactly "No new failure path; no record added." only when the diff adds no
|
|
88
|
+
failure path (no new catch, fallback or degradation branch). Record: on
|
|
89
|
+
2026-09-10 most open PRs failed the PR-body check on one of these two rules.
|
|
90
|
+
- No Git authority unless granted: leave changes uncommitted; hand off
|
|
91
|
+
`PR_BODY.md` (template headings, every red and mutation quoted in ≤5 lines)
|
|
92
|
+
plus two optional one-liners the reviewer reads first: `Operating rule:`
|
|
93
|
+
(the one sentence the change enforces) and `Kept:` (what was deliberately
|
|
94
|
+
not changed, so a reviewer does not re-litigate it);
|
|
95
|
+
and `COMMIT_MSG.txt` at the worktree root. Final message: verdict line, files
|
|
96
|
+
changed, test totals, what could not be verified.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Investigator contract
|
|
2
2
|
|
|
3
|
+
Grep the `turnId` first when correlating rows across telemetry sinks.
|
|
4
|
+
Premise-first reproductions of dogfood reports go through the harness with a fixture built from the reporter's shape, before any seam is named.
|
|
5
|
+
|
|
3
6
|
Root-cause runtime behavior from reproducible and durable evidence.
|
|
4
7
|
|
|
5
8
|
Define the symptom as a question that evidence can answer. Name the time window,
|
|
@@ -13,6 +16,18 @@ and against each hypothesis and the observation that would settle it. Sweep the
|
|
|
13
16
|
tree for the root-cause pattern and every member of the affected population.
|
|
14
17
|
State the blast radius and any missing or unbounded observability.
|
|
15
18
|
|
|
19
|
+
For a reported defect, the first deliverable is the reporter's symptom
|
|
20
|
+
reproduced through the production entry point (the tool handler or host
|
|
21
|
+
command the reporter used), red on the current code; a seam named before
|
|
22
|
+
that reproduction is a hypothesis and is labelled as one. Write the report
|
|
23
|
+
to a file at the worktree root AND, when the delegation grants issue
|
|
24
|
+
access, post it on the tracking issue: a file left in a worktree is not a
|
|
25
|
+
durable deliverable until it is posted or committed.
|
|
26
|
+
When the symptom involves a language server, runner or formatter, say which
|
|
27
|
+
registry entries (`clients/language-registry.ts`) the diagnosis covers and
|
|
28
|
+
whether the reporter's language is special or merely the one observed; the
|
|
29
|
+
fix lane inherits that scope (catalog shape 42).
|
|
30
|
+
|
|
16
31
|
Deliver a proven diagnosis and a concrete next step. If the task expands to an
|
|
17
32
|
implementation, stop and return it to the orchestrator for a fixer delegation.
|
|
18
33
|
Use concise, active, plain prose.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# pi-lens monitor — role contract
|
|
2
|
+
|
|
3
|
+
Read a LIVE pi-lens session's logs and report what the numbers say, so the
|
|
4
|
+
maintainer does not have to. The monitor observes; it never edits code,
|
|
5
|
+
never restarts anything, and never touches the session it is reading.
|
|
6
|
+
|
|
7
|
+
Read first: `AGENTS.md` (the "Recurring defect shapes" catalog, especially
|
|
8
|
+
shape 41: a fixed bound reached at p50 is a design defect), then
|
|
9
|
+
`docs/pi-lens-investigator.md` for the forensics conventions this role
|
|
10
|
+
inherits. This contract adds the standing readout.
|
|
11
|
+
|
|
12
|
+
## Inputs
|
|
13
|
+
|
|
14
|
+
- `~/.pi-lens/latency.log` and `~/.pi-lens/extension.log` (JSON lines; every
|
|
15
|
+
row carries `pid` and `ts`). The session is the `pid` the brief names, or the
|
|
16
|
+
newest pid with rows in the last hour when the brief says "live".
|
|
17
|
+
- The previous readout for the same project when one exists (an issue comment
|
|
18
|
+
the brief links, or a file under the scratch directory). Every number is
|
|
19
|
+
reported as a delta against it when available.
|
|
20
|
+
|
|
21
|
+
## The readout (fixed shape, one comment or file, never stdout to the session)
|
|
22
|
+
|
|
23
|
+
1. **Session line**: pid, project root, first/last row timestamps, row count,
|
|
24
|
+
pi-lens version if a session-start row carries it.
|
|
25
|
+
2. **Phase table**: for every `type:"phase"` value, `n | p50 | p95 | max |
|
|
26
|
+
total_ms`, sorted by total, top 15. Durations in ms, from `durationMs`.
|
|
27
|
+
3. **Bounds reached at p50** (shape 41): every phase whose p50 is within 10%
|
|
28
|
+
of a declared budget or timeout in its metadata (`budgetMs`, `timeoutMs`,
|
|
29
|
+
`elapsedMs` ≈ budget). Name the constant when it is known
|
|
30
|
+
(`PI_LENS_AUX_GRACE_MS`, `TOUCH_DEBOUNCE_MS`, drift batch) and the awaited
|
|
31
|
+
path it sits on (tool_result, agent_end, background).
|
|
32
|
+
4. **Per-server auxiliary outcomes**: from `lsp_aux_wait_outcome.metadata.outcomes[]`,
|
|
33
|
+
one row per `serverId | outcome | publishedThisContent`, with n and p50/p95
|
|
34
|
+
`elapsedMs` versus `budgetMs`.
|
|
35
|
+
5. **Degradation and error lines**: counts by `kind` from the degradation
|
|
36
|
+
records and by `message` from `extension.log` at `level:"error"`; any
|
|
37
|
+
message that repeats per file or per occurrence is flagged as catalog
|
|
38
|
+
shape 10 with the emit site if it can be found by grep.
|
|
39
|
+
Also report `Situational dead weight` from the `tools` extension-log row,
|
|
40
|
+
including its bounded `metadata.tools` list; `[]` means every situational
|
|
41
|
+
tool was activated or called in the conversation. A shutdown with
|
|
42
|
+
`targetSessionFile` emits the ending conversation's row before a new set
|
|
43
|
+
opens for new, resume, or fork. Reload re-runs the extension factory but
|
|
44
|
+
keeps the same session file, so it preserves one conversation row. Caveat: resuming into the session you are already in still carries `targetSessionFile`, so one conversation is split into two rows and a tool activated before the resume is listed as dead weight in the second (pi exposes no current-session-file accessor; not fixed). A process restart (`pi --continue`) recovers
|
|
45
|
+
nothing — the restore deactivates every situational tool — so the first row
|
|
46
|
+
after one legitimately lists all five, and shrinks only as the model
|
|
47
|
+
re-activates and uses them. MCP remains connection-scoped and owns the
|
|
48
|
+
terminal latch.
|
|
49
|
+
6. **Backlogs**: `lsp_document_drift` rows by disposition, files affected,
|
|
50
|
+
`driftAgeMs` p50/p95/max; `agent_end_deferred_mutation_drain` durations and
|
|
51
|
+
coalesced path counts; `deferred_format_file` runs with `changed:true`
|
|
52
|
+
versus total.
|
|
53
|
+
7. **Timeouts**: `lsp_diagnostics_timeout`, `lsp_nav_request_timeout`,
|
|
54
|
+
`lsp_client_wait_timeout` counts with `serverIds`/`source`.
|
|
55
|
+
8. **Delta**: for each of the above, the change since the previous readout,
|
|
56
|
+
one line each, only where the number moved by more than 20% or a new
|
|
57
|
+
kind appeared.
|
|
58
|
+
9. **Injected context**: report injected bytes per source per turn
|
|
59
|
+
(`sessionGuidance`, `turnFindings`, `testFindings`, `agentNudge`,
|
|
60
|
+
`turnEndAdvisory`, `other`) at p50/p95, plus the repeated-findings ratio
|
|
61
|
+
(`injectedFindingsRepeated` divided by injected finding observations).
|
|
62
|
+
10. **Findings**: at most five, each with the number that proves it, the seam
|
|
63
|
+
(file:line when found), and one of: `already filed #N` (search open issues
|
|
64
|
+
first: `gh issue list --search "<phase or kind>"`), `new`, or
|
|
65
|
+
`expected` (with the rule that makes it expected). A finding without a
|
|
66
|
+
number is not a finding.
|
|
67
|
+
|
|
68
|
+
## Rules
|
|
69
|
+
|
|
70
|
+
- Premise first: before naming a constant or a seam, read the code that owns
|
|
71
|
+
it (`clients/lsp/index.ts`, `clients/pipeline.ts`, `clients/runtime-agent-end.ts`,
|
|
72
|
+
`clients/lsp/document-drift.ts`). The 2026-09-09 readout mis-named a
|
|
73
|
+
suppression window as a trailing debounce; the correction cost a round.
|
|
74
|
+
- Bounded output: the readout is one comment or one file. Never one line per
|
|
75
|
+
row of the log. Quote at most three raw rows, each cut at 300 characters.
|
|
76
|
+
- No repo edits, no Git commands, no restarts, no writes under `~/.pi-lens`.
|
|
77
|
+
Scratch files go under the working tree's `.probe-home/` or the scratch
|
|
78
|
+
directory the brief names.
|
|
79
|
+
- File nothing yourself unless the brief grants `gh`; then one comment on the
|
|
80
|
+
issue the brief names, never a new issue: the orchestrator decides what
|
|
81
|
+
becomes a lane.
|
|
82
|
+
- A worker that finds the logs empty or the pid absent reports exactly that
|
|
83
|
+
with the `ls -la` of the two files and stops.
|
|
84
|
+
|
|
85
|
+
## Deliverable
|
|
86
|
+
|
|
87
|
+
`MONITOR.md` at the worktree root with the readout, and when `gh` is granted,
|
|
88
|
+
the same text as a comment on the issue the brief names (today: #2809).
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Reviewer contract
|
|
2
2
|
|
|
3
|
+
Reviewers run the relevant scenario as a probe and may add a throwaway scenario directory to reproduce a finding through the real host; quote the RPC event or tool result.
|
|
4
|
+
|
|
3
5
|
Adversarially verify a change before merge and report proven findings.
|
|
4
6
|
|
|
5
7
|
Assume the implementation's claims are incomplete. Read the issue, full diff,
|
|
@@ -31,3 +33,36 @@ Check that each regression test reaches the real seam and observes an independen
|
|
|
31
33
|
effect. Remove or mutate the claimed guard and require the test to fail for the
|
|
32
34
|
intended reason. Flag tests that restate the implementation, assert setup data,
|
|
33
35
|
or swap a real in-process store, sink, coordinator, or registry for a fake.
|
|
36
|
+
|
|
37
|
+
## Language coverage is a standing attack
|
|
38
|
+
|
|
39
|
+
For any diff on an LSP, dispatch, cache, runner or tool seam, ask whether the
|
|
40
|
+
rule holds for every entry in `clients/language-registry.ts` or only for the
|
|
41
|
+
language the fixer tested. A rule keyed on `.ts`/tsserver where rust-analyzer,
|
|
42
|
+
pyright or gopls behave the same is a finding (catalog shape 42); probe it
|
|
43
|
+
with one non-TypeScript fixture through the same seam and quote the result.
|
|
44
|
+
|
|
45
|
+
## Finding shape and disposition
|
|
46
|
+
|
|
47
|
+
Every finding is written in four moves, in this order: the smallest concrete
|
|
48
|
+
instance (the probe command and its output, or the failing scenario) with the
|
|
49
|
+
expected value beside it; one plain-language sentence saying what is wrong;
|
|
50
|
+
the cause and its cost in prose; the remedy, with options labelled A/B when
|
|
51
|
+
more than one is defensible. Symbols and `file:line` anchor the prose and
|
|
52
|
+
never replace it. Severity is earned by the instance: a CRITICAL or HIGH
|
|
53
|
+
without a reproduced failure scenario is a MEDIUM at most.
|
|
54
|
+
|
|
55
|
+
The verdict line comes first. After the findings, two fixed sections:
|
|
56
|
+
"Could not verify" (what was blocked and why, never implied green) and
|
|
57
|
+
"Named output" (the structural insight the probes could not close). A Named
|
|
58
|
+
output entry may carry an advisory strength — Strong, Worth exploring, or
|
|
59
|
+
Speculative — judged by the deletion test alone (would removing the shared
|
|
60
|
+
module concentrate complexity back into callers, or merely relocate it); it is
|
|
61
|
+
a triage aid for the orchestrator, never a severity, and never substitutes for
|
|
62
|
+
a reproduced instance on a finding. A verify
|
|
63
|
+
round ends with a disposition table for the previous round's findings —
|
|
64
|
+
`fixed | not fixed | new defect | withdrawn` per finding id — so the
|
|
65
|
+
orchestrator reads outcomes, not prose. Safe deltas (a body sentence, a
|
|
66
|
+
comment, a literal, a doc line) are reported as such and never counted as
|
|
67
|
+
actionable rounds. Borrowed shape: p3bot/library `tasks/review/pre-commit`
|
|
68
|
+
(finding IDs, per-item template, remediation summary), 2026-09-09.
|
|
@@ -16,7 +16,10 @@ and every member of any enumerable population. Record both sweeps.
|
|
|
16
16
|
|
|
17
17
|
State the blast radius, including callers, durable shapes, strict parsers, and
|
|
18
18
|
tool surfaces. Add bounded observability for every new failure path. Include the
|
|
19
|
-
required changelog fragment for a code change
|
|
19
|
+
required changelog fragment for a code change: ONE file under `.changelog/`;
|
|
20
|
+
never edit `CHANGELOG.md` itself (it is generated at release; two fixers
|
|
21
|
+
hand-edited it on 2026-09-09 and the orchestrator had to revert both).
|
|
22
|
+
Report verification honestly.
|
|
20
23
|
Write active, direct prose with short sentences and consistent terms.
|
|
21
24
|
|
|
22
25
|
## Tautological tests considered harmful
|
|
@@ -26,6 +29,7 @@ or feed the expected answer in through setup. Keep the red-first failure tied to
|
|
|
26
29
|
the defect, and mutate the guard or filter to prove the test can detect its loss.
|
|
27
30
|
Mocks belong only at true process or host boundaries. When a test can use the
|
|
28
31
|
real store, sink, coordinator, or registry, use it and assert the durable result.
|
|
32
|
+
For a whole-module mock, prefer `vi.mock("./module.js", async (importOriginal) => ({ ...(await importOriginal()), override }))` so new exports pass through by default; annotate dynamic imports as `typeof import(spec)` when needed.
|
|
29
33
|
|
|
30
34
|
Git authority is separate from the role. Commit, push, or open a PR only when
|
|
31
35
|
the delegation explicitly grants that authority after worktree verification.
|
|
@@ -34,11 +38,15 @@ directory, leave every change uncommitted, and write two handoff files at the
|
|
|
34
38
|
worktree root: `PR_BODY.md` (the full PR body, transcripts pasted) and
|
|
35
39
|
`COMMIT_MSG.txt` (subject, body, issue ref, trailers). Name any path inside the
|
|
36
40
|
worktree that must not be committed. The orchestrator commits from those files;
|
|
37
|
-
they are never committed themselves. Never merge.
|
|
41
|
+
they are never committed themselves. Never merge. Every report or artifact
|
|
42
|
+
the delegation asks for lives at the worktree root under the name the brief
|
|
43
|
+
gives it; nothing else at the root is assumed to matter. When the brief
|
|
44
|
+
names findings by id, the handoff answers each id with one of
|
|
45
|
+
`fixed | not fixed | withdrawn (why)` before any prose.
|
|
38
46
|
|
|
39
47
|
A sandboxed worker may find the shared `.git` and the linked `node_modules`
|
|
40
|
-
read-only and the network absent (
|
|
41
|
-
|
|
48
|
+
read-only and the network absent (a write-confined sandbox does this; the
|
|
49
|
+
runner's own notes say which mode lifts it). Run Vitest as
|
|
42
50
|
`node_modules/.bin/vitest run <files> --configLoader runner`, and if the
|
|
43
51
|
tree-sitter grammar prefetch hangs offline, verify through direct probes of the
|
|
44
52
|
built code and say so; the orchestrator re-runs the files outside the sandbox.
|
|
@@ -107,6 +107,7 @@ this policy explicitly reserves the right to change.
|
|
|
107
107
|
| `PILENS_CFG_0006` | A config key that would modify an object's prototype (`__proto__`, `constructor`, `prototype`) was refused. | Both halves of the config core, through the shared policy in `clients/config-core/safe-object.ts`. |
|
|
108
108
|
| `PILENS_CFG_0007` | Further config notices were suppressed by a bound, and this one carries the count — the WHOLE count, including anything an earlier bound in the same pipeline dropped. Nothing about the config is wrong; the notice list was truncated. | `MigrationRecordCollector.finalize` (`clients/config-core/records.ts`) — the ONE producer, reached through `finalizeRecords` by every record list: the shared resolution, the global loader's unknown-key scan, the project loader's unknown-key scan, and its legacy-document enumeration. Rendered with neutral prose and recorded under the `config-notice-suppressed` degradation kind, never `config-ignored`. |
|
|
109
109
|
| `PILENS_CFG_0008` | Resolving a config failed internally, so the WHOLE file was ignored and pi-lens ran on defaults. | The two guards under the pipeline: `resolveConfig` (`clients/config-core/resolve.ts`) and the global loader's post-parse catch (`clients/lens-config.ts`). Carries the error class only, never its message. |
|
|
110
|
+
| `PILENS_CFG_0009` | A tool config key is unknown or names a required, non-disableable tool. | The shared model-facing tool registry (`clients/tool-config.ts`) and both pi/MCP registration surfaces. |
|
|
110
111
|
|
|
111
112
|
A reserved code is registered and referenced by the deprecation registry, but
|
|
112
113
|
nothing emits it today. That is deliberate: the number must be pinned before the
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Real pi harness
|
|
2
|
+
|
|
3
|
+
The real-harness lane runs the built extension inside a real `pi --mode rpc`
|
|
4
|
+
process. Use it when a host event, provider turn, or tool handler crosses a
|
|
5
|
+
process boundary that an in-process test cannot observe.
|
|
6
|
+
|
|
7
|
+
## Five-minute scenario recipe
|
|
8
|
+
|
|
9
|
+
1. Add `tests/fixtures/real-harness/<name>/project/` and a `script.json`.
|
|
10
|
+
2. Use `withRealPi({ fixture: "<name>", script: "script.json" }, ...)`.
|
|
11
|
+
3. Call `awaitAssistantTurn()` after each prompt.
|
|
12
|
+
4. Call `awaitToolResult("<tool>")` for every expected tool result.
|
|
13
|
+
5. Add the test to `realHarnessInclude` and the real-process-spawn ratchet.
|
|
14
|
+
|
|
15
|
+
Scripts contain turns. Each turn contains text or typed tool-call actions.
|
|
16
|
+
Malformed scripts fail validation before the child starts.
|
|
17
|
+
|
|
18
|
+
## Run one file
|
|
19
|
+
|
|
20
|
+
Build first, then run one serialized file with the pinned probe home:
|
|
21
|
+
|
|
22
|
+
`PI_LENS_HOME=$PWD/.probe-home npm run test:real-harness -- tests/real-harness/scenario-1.test.ts`
|
|
23
|
+
|
|
24
|
+
The lane has a 60-second wall budget and one worker. Do not use it for tests
|
|
25
|
+
that can assert the same behavior through an in-process seam.
|
|
26
|
+
|
|
27
|
+
## Hermetic home contents
|
|
28
|
+
|
|
29
|
+
The harness pins `HOME`, `PI_LENS_HOME`, and the provider observation log to a
|
|
30
|
+
claimed scratch directory. It copies only the scenario project fixture. The
|
|
31
|
+
scratch seam records an owner PID, sweeps dead entries when a run starts, and
|
|
32
|
+
removes the project and home in `finally`. A killed run is therefore cleaned
|
|
33
|
+
by the next run before it claims new directories.
|
|
34
|
+
|
|
35
|
+
## Wall budget
|
|
36
|
+
|
|
37
|
+
Real provider startup, RPC traffic, tool execution, and teardown share the
|
|
38
|
+
60-second test budget. Keep assertions on events and durable sink rows. Avoid
|
|
39
|
+
elapsed-time assertions inside scenarios; scheduler-sensitive timing belongs
|
|
40
|
+
in the serialized wall-clock lane.
|
|
41
|
+
|
|
42
|
+
## Live mode
|
|
43
|
+
|
|
44
|
+
Live-provider mode remains a placeholder for #2826. The scripted provider is
|
|
45
|
+
hermetic and is the only supported provider for this lane until that issue
|
|
46
|
+
defines credentials, redaction, and replay rules.
|
|
@@ -17,7 +17,9 @@ first six runs — which pinned the pi-lens home but passed no environment to
|
|
|
17
17
|
`npm` at all — put 41 records into the maintainer's real
|
|
18
18
|
`~/.pi-lens/install.log` (#2619 review F1). The pack runs in a
|
|
19
19
|
`git archive HEAD` export, never the live checkout, because `npm pack` fires our
|
|
20
|
-
own `prepack` (rewrites `package.json` + `package-lock.json`) and `prepare
|
|
20
|
+
own `prepack` (rewrites `package.json` + `package-lock.json`) and `prepare`.
|
|
21
|
+
When regenerating the lockfile, use the exact npm version in `package.json`'s
|
|
22
|
+
`packageManager` field (`npm@11.18.0`), matching the production-install CI job.
|
|
21
23
|
(rebuilds `dist/`, downloads grammars, reinstalls git hooks).
|
|
22
24
|
|
|
23
25
|
Why it exists: #2587. The four shipped skills were suspected of never
|
|
@@ -84,6 +86,7 @@ PR's packed tarball (#2700, the check #2587 was missing). `attw`
|
|
|
84
86
|
| config-provenance | a project config is LOADED and its provenance is reportable | mcp-stdio | `tools/call` `pilens_effective_config` with the fixture file | result names the fixture's `.pi-lens.json` as a contributing document | tool result text | new — `tests/config/pi-lens-config-schema.test.ts` covers the schema, not the packaged load | — |
|
|
85
87
|
| degradation-visible | a silently-ignored input is RECORDED as a degradation instead of vanishing | mcp-stdio | `tools/call` `pilens_health` with the fixture's project-tier `lsp.enabled` (a global-only setting) loaded | health text carries a `config-ignored` degradation line naming the fixture's `.pi-lens.json` | health tool result text | `clients/degradation-ledger.ts` is the reused machinery; no smoke asserts it end to end | #1605 lane 2 (availability-lifecycle): the degradation-recorded half; #1605 additionally asserts RECOVERY, which this row does not |
|
|
86
88
|
| git-install-loads | a `git:` install of a pushed ref builds and loads in a real pi | git-install | `pi install git:github.com/apmantza/pi-lens@<ref>` then `get_commands` | at least 1 `lens-*` command and at least 4 skills | get_commands response JSON | `scripts/rpc-load-check.mjs` assertion, re-run against the git layout | — |
|
|
89
|
+
| tool-smoke-install | every npm/pip entry in the installer registry resolves on a real install | npm-install | `node <export>/scripts/smoke-tools.mjs --install --install-registry --installer-root=<installed>/` (registry `<installed>/dist/clients/installer/index.js`; about 1m 29s cold on this box for 33 entries; harness from export root) | the report shows every npm/pip entry resolved or a named legitimate skip (toolchain absent, declined), and no genuine install failure; a registry-unreachable classification leaves the lane UNMEASURED; requires network access to the npm and pip registries | install-registry JSON report | `classifyInstallOutcome` from the #2661 fixture lanes — this lane sweeps the whole npm/pip registry, where fixture lanes exercise only the entries their fixtures name | — |
|
|
87
90
|
|
|
88
91
|
## Why `skills-registered` pins the registrar
|
|
89
92
|
|
|
@@ -150,6 +153,7 @@ Ship line, from the outcomes:
|
|
|
150
153
|
| pi did not boot with NO candidate installed | BLOCKED — no verdict | 3 | 0 |
|
|
151
154
|
| pi booted, the candidate would not install or activate | do not ship, cause named on the verdict | 1 | 0 |
|
|
152
155
|
| any row FAILED | do not ship | 1 | N |
|
|
156
|
+
| any row classified registry-unreachable (its lane UNMEASURED) | INCONCLUSIVE — no verdict, the skips are not green | 3 | N |
|
|
153
157
|
| pi booted but zero rows PASSED | INCONCLUSIVE — no verdict | 3 | N |
|
|
154
158
|
| any UNTESTED or SKIPPED, at least one PASS | ship with caveats, each named | 2 | N |
|
|
155
159
|
| all PASS | ship | 0 | N |
|
|
@@ -6,7 +6,7 @@ server's `initialize` handshake. Generated by `node scripts/server-capabilities.
|
|
|
6
6
|
absent on the generating host are listed under *Unavailable* — run in a
|
|
7
7
|
provisioned environment (the nightly) to capture those rows.
|
|
8
8
|
|
|
9
|
-
_Last generated: 2026-09-
|
|
9
|
+
_Last generated: 2026-09-09 on linux; 31 servers captured, 13 unavailable._
|
|
10
10
|
|
|
11
11
|
## Diagnostic mode + navigation/edit operations
|
|
12
12
|
|
|
@@ -109,7 +109,6 @@ Toolchain/binary not installed here, so capabilities weren't captured
|
|
|
109
109
|
(many are the toolchain-gated family tracked in #241):
|
|
110
110
|
|
|
111
111
|
- @prisma/language-server
|
|
112
|
-
- @vue/language-server
|
|
113
112
|
- PowerShell Editor Services (pwsh Start-EditorServices.ps1 -Stdio)
|
|
114
113
|
- clangd
|
|
115
114
|
- cmake-language-server
|
|
@@ -122,7 +121,3 @@ Toolchain/binary not installed here, so capabilities weren't captured
|
|
|
122
121
|
- ocamllsp
|
|
123
122
|
- rust-analyzer
|
|
124
123
|
- sourcekit-lsp
|
|
125
|
-
- typescript native (clean file)
|
|
126
|
-
- typescript native (tsc --lsp --stdio, TS7+)
|
|
127
|
-
- typescript-language-server
|
|
128
|
-
- typescript-language-server (clean file)
|
|
@@ -9,6 +9,19 @@ flags in context, see [Usage](./usage.md).
|
|
|
9
9
|
pi-lens ships with sensible defaults, so **zero configuration is needed** — it
|
|
10
10
|
works out of the box. Everything below is optional tuning.
|
|
11
11
|
|
|
12
|
+
Tool root resolution is recorded in the pi-lens extension log as one bounded
|
|
13
|
+
line per session key: `cwd <kind> <tool> cwd=<path>
|
|
14
|
+
reason=<dispatch-root|marker:<name>|git-root|file-dir-fallback|home-cap>`.
|
|
15
|
+
Fallbacks also create one `tool-cwd-resolution` degradation record per tool and
|
|
16
|
+
session, so repeated files do not create unbounded health or log rows.
|
|
17
|
+
|
|
18
|
+
Complete MCP tool results use `COMPLETE_MCP_RESULT_INPUT_BUDGET_BYTES` (8 MiB) as
|
|
19
|
+
their input budget. Results above this budget
|
|
20
|
+
write a bounded head, an `[incomplete: N bytes omitted, budget M]` marker, and a
|
|
21
|
+
tail to the session log, and record one `mcp-complete-result-budget-exceeded`
|
|
22
|
+
degradation per session. Results at or below the budget keep the complete-log
|
|
23
|
+
contract.
|
|
24
|
+
|
|
12
25
|
## The three ways to configure pi-lens
|
|
13
26
|
|
|
14
27
|
1. **Environment variables** (`PI_LENS_*`) — read at process start; set them in
|
|
@@ -60,7 +73,7 @@ column is the effective behavior when nothing is set.
|
|
|
60
73
|
| `--no-tests` | `tests.enabled` | global | test runner **on** |
|
|
61
74
|
| `--no-delta` | `delta.enabled` | global | delta mode **on** (new diagnostics only) |
|
|
62
75
|
| `--lens-guard` | `guard.enabled` | global | **off** |
|
|
63
|
-
|
|
76
|
+
| `--lens-checkout-guard` | `guard.sharedCheckout` | global | **off** |
|
|
64
77
|
| `--no-opengrep` | `opengrep.enabled` | global | Opengrep scanner **on** |
|
|
65
78
|
| `--no-read-guard` | `readGuard.enabled` | global | read-before-edit monitor **on** |
|
|
66
79
|
| `--no-lens-context` | `contextInjection.enabled` | global | context injection **on** |
|
|
@@ -70,14 +83,36 @@ column is the effective behavior when nothing is set.
|
|
|
70
83
|
| `--lens-actionable-warning-autofix` | `actionableWarnings.autoFix.enabled` | project | **off** |
|
|
71
84
|
| `--lens-actionable-warning-all` | `actionableWarnings.deltaOnly` (`false`) | global | `deltaOnly` **on** (report this turn only) |
|
|
72
85
|
| `--lens-compact-tool-line` | `ui.compactToolLine` | global | **off** (two-row tool rendering) |
|
|
73
|
-
| `--no-lazy-tools` | `tools.lazy` | global | lazy tools **on** (
|
|
86
|
+
| `--no-lazy-tools` | `tools.lazy` | global | lazy tools **on** (five situational tools start inactive) |
|
|
87
|
+
| `--no-tool=<name>` | `tools.<name>.enabled` | project | every lens tool **on** |
|
|
74
88
|
| `--lens-turn-end-madge` | `turnEnd.madge.enabled` | global | **off** (madge runs at session start, not per turn) |
|
|
89
|
+
| `--no-knip` | `knip.enabled` | project | knip analyzer **on** |
|
|
90
|
+
| `--no-jscpd` | `jscpd.enabled` | project | jscpd analyzer **on** |
|
|
91
|
+
| `--no-madge` | `madge.enabled` | project | madge analyzer **on** |
|
|
92
|
+
| `--no-gitleaks` | `gitleaks.enabled` | project | gitleaks analyzer **on** |
|
|
93
|
+
| `--no-govulncheck` | `govulncheck.enabled` | project | govulncheck analyzer **on** |
|
|
94
|
+
| `--no-dead-code` | `deadCode.enabled` | project | dead-code analyzer **on** |
|
|
95
|
+
| `--no-complexity` | `complexity.enabled` | project | complexity analyzer **on** |
|
|
75
96
|
|
|
76
97
|
`--no-lazy-tools` keeps every pi-lens tool active for the whole session, so the
|
|
77
98
|
advertised tool list never changes. The `pi_lens_activate_tools` loader stays
|
|
78
99
|
registered and keeps its usual description; under this flag the tools it names
|
|
79
100
|
are already active, so calling it is a no-op.
|
|
80
101
|
|
|
102
|
+
The `tools.<name>.enabled` population covers every model-facing pi and MCP
|
|
103
|
+
tool. The loader `pi_lens_activate_tools` and MCP lifecycle tools
|
|
104
|
+
`pilens_session_start`, `pilens_turn_end`, and `pilens_session_end` are
|
|
105
|
+
required by their host protocols and cannot be disabled. Unknown or
|
|
106
|
+
non-disableable names emit `PILENS_CFG_0009`.
|
|
107
|
+
|
|
108
|
+
Valid names for `tools.<name>.enabled` include `ast_grep_search`,
|
|
109
|
+
`ast_grep_replace`, `ast_grep_outline`, `lsp_navigation`,
|
|
110
|
+
`lens_diagnostics`, `lens_diagnostic_mark`, `symbol_search`,
|
|
111
|
+
`module_report`, `project_report`, `read_symbol`, `read_enclosing`,
|
|
112
|
+
`effective_config`, `analyze`, `health`, `latency`, `project_scan`, and
|
|
113
|
+
`rebuild`. The activation loader and MCP lifecycle tools `session_start`,
|
|
114
|
+
`turn_end`, and `session_end` cannot be disabled.
|
|
115
|
+
|
|
81
116
|
`--lens-guard` is **EXPERIMENTAL and strictly opt-in**. When enabled, actual
|
|
82
117
|
`git commit`/`git push` commands are blocked only for current, structured
|
|
83
118
|
blocking findings (including blocking test failures); advisory/no-action-required
|
|
@@ -276,7 +276,7 @@ These categories are language-agnostic at the tool UX level even if implementati
|
|
|
276
276
|
- Keep `items: "exports"` prominent in the docs; it is much more usable than `items: "all"` on configuration-heavy modules.
|
|
277
277
|
- Include a clear `syntaxOnly: true` and “does not satisfy read guard” note in the main text, not only details.
|
|
278
278
|
|
|
279
|
-
## `
|
|
279
|
+
## `ast_grep_search` dump mode
|
|
280
280
|
|
|
281
281
|
### What works well
|
|
282
282
|
|
|
@@ -322,12 +322,12 @@ These categories are language-agnostic at the tool UX level even if implementati
|
|
|
322
322
|
- For `codeAction`, include whether diagnostics were present at the requested range; an empty result is more useful if it says “no diagnostic at range” vs “server has no quickfix.”
|
|
323
323
|
- For rename previews, the current summary is useful; consider adding a `filesTouched` / `editsCount` top-level summary for easier scanning.
|
|
324
324
|
|
|
325
|
-
## `
|
|
325
|
+
## `lens_diagnostics` (`source=session` / `source=lsp`)
|
|
326
326
|
|
|
327
327
|
### What works well
|
|
328
328
|
|
|
329
|
-
- `
|
|
330
|
-
- `
|
|
329
|
+
- `source=lsp` is good for file-scoped type/error checks before builds.
|
|
330
|
+
- `source=session` is valuable because it includes non-LSP runners.
|
|
331
331
|
|
|
332
332
|
### Proposed improvements
|
|
333
333
|
|
|
@@ -218,7 +218,7 @@ Rule source: `rules/tree-sitter-queries/<language>/`.
|
|
|
218
218
|
| `no-eval` | error | security | eval() detected — security risk, never use eval |
|
|
219
219
|
| `no-jump-in-finally` | warning | bug | return/break/continue/throw in finally overrides the try/catch result and silently swallows exceptions |
|
|
220
220
|
| `self-assignment` | error | reliability | '{{VAR}}' is assigned to itself |
|
|
221
|
-
| `sql-injection` |
|
|
221
|
+
| `sql-injection` | warning | security | SQL injection risk — use parameterized queries, never interpolate into SQL |
|
|
222
222
|
| `switch-case-termination` | error | reliability | Switch case should end with break, return, throw, or continue |
|
|
223
223
|
| `switch-non-case-labels-ts` | error | reliability | switch statements should not contain non-case labels |
|
|
224
224
|
| `ts-command-injection` | error | security | Potential command injection sink — avoid child_process command execution with untrusted input |
|
|
@@ -50,9 +50,11 @@ for the consumer-facing version of this routing.
|
|
|
50
50
|
|
|
51
51
|
pi-lens exposes these high-value tools to agents:
|
|
52
52
|
|
|
53
|
-
- `lens_diagnostics` —
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
- `lens_diagnostics` — `source=session` (default) reports cached findings; an
|
|
54
|
+
empty cache is not proof of a clean file. If changed files have no cached
|
|
55
|
+
diagnostics or stale findings, use `source=lsp scope=paths` for targeted
|
|
56
|
+
active verification (or `scope=workspace` to sweep a whole directory/project).
|
|
57
|
+
- `lsp_navigation` — IDE-style code navigation (definition/references/etc.).
|
|
56
58
|
- `ast_grep_search` / `ast_grep_replace` — AST-aware structural search/replace.
|
|
57
59
|
- `module_report` / `read_symbol` — navigable outline and targeted symbol-body
|
|
58
60
|
reads; prefer these before broad full-file reads.
|
|
@@ -105,12 +107,20 @@ pi --no-autofix # Skip auto-fix (Biome, Ruff, ESLint, stylelint, sqlflu
|
|
|
105
107
|
pi --no-tests # Skip test runner
|
|
106
108
|
pi --no-delta # Disable delta mode (show all diagnostics, not just new ones)
|
|
107
109
|
pi --lens-guard # Block git commit/push when unresolved blockers exist (experimental)
|
|
110
|
+
pi --lens-checkout-guard # Decline git commands that rewrite the working tree while another live pi-lens session shares this dirty checkout (experimental)
|
|
108
111
|
pi --no-opengrep # Disable the Opengrep security scanner (default-on auxiliary LSP)
|
|
109
112
|
pi --no-read-guard # Disable the read-before-edit behavior monitor
|
|
110
113
|
pi --lens-turn-summary # Persist a per-turn summary of diagnostics, autofixes, and autoformats
|
|
111
114
|
pi --lens-compact-tool-line # Render tool results as one compact, theme-aware line (closes #1327)
|
|
112
115
|
pi --no-lazy-tools # Keep every pi-lens tool active instead of activating the situational ones on demand
|
|
113
116
|
pi --lens-turn-end-madge # Run the madge circular-dependency check at every turn end, not just at session start
|
|
117
|
+
pi --no-knip # Disable the knip session-start analyzer
|
|
118
|
+
pi --no-jscpd # Disable the jscpd session-start analyzer
|
|
119
|
+
pi --no-madge # Disable the madge session-start analyzer
|
|
120
|
+
pi --no-gitleaks # Disable the gitleaks session-start analyzer
|
|
121
|
+
pi --no-govulncheck # Disable the govulncheck session-start analyzer
|
|
122
|
+
pi --no-dead-code # Disable the dead-code session-start analyzer
|
|
123
|
+
pi --no-complexity # Disable the complexity session-start analyzer
|
|
114
124
|
|
|
115
125
|
# Actionable warnings (all default off)
|
|
116
126
|
pi --lens-actionable-warnings # Report fixable warnings at turn end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lens",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo",
|
|
6
6
|
"repository": {
|
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"test:integration": "node scripts/with-test-lock.mjs -- vitest run tests/index-integration.test.ts tests/clients/lsp/integration.test.ts",
|
|
34
34
|
"test:targeted": "node scripts/with-test-lock.mjs --shared -- vitest run",
|
|
35
35
|
"test:watch": "vitest",
|
|
36
|
+
"test:real-harness": "node scripts/with-test-lock.mjs --shared -- vitest run",
|
|
37
|
+
"mutation:diff": "node scripts/stryker-diff.mjs --base origin/master --max-files 6",
|
|
36
38
|
"hygiene": "node scripts/prune-agent-worktrees.mjs",
|
|
37
39
|
"check": "node scripts/check-extensions.mjs",
|
|
38
40
|
"selftest:install": "node scripts/install-selftest.mjs",
|
|
39
41
|
"check:lockfile": "node scripts/check-lockfile-sync.mjs",
|
|
42
|
+
"preflight": "node scripts/pr-preflight.mjs",
|
|
40
43
|
"knip": "node scripts/run-knip.mjs",
|
|
41
44
|
"check:grammars": "node scripts/check-grammar-provenance.mjs",
|
|
42
45
|
"check:grammar-load": "node scripts/check-grammar-load.mjs",
|
|
@@ -49,7 +52,9 @@
|
|
|
49
52
|
"bench:cascade-budget": "node scripts/bench-cascade-budget.mjs",
|
|
50
53
|
"bench:word-index-replacement": "node scripts/bench-word-index-replacement.mjs",
|
|
51
54
|
"logs:smells": "node scripts/analyze-pi-lens-logs.mjs",
|
|
55
|
+
"complexity": "node scripts/complexity-report.mjs",
|
|
52
56
|
"changelog:check": "node scripts/rollup-changelog.mjs --check",
|
|
57
|
+
"test:regen": "node scripts/regen-test-baseline.mjs",
|
|
53
58
|
"changelog:release": "node scripts/changelog-release.mjs",
|
|
54
59
|
"changelog:extract": "node scripts/changelog-extract.mjs",
|
|
55
60
|
"release:backfill-notes": "node scripts/backfill-github-releases.mjs",
|
|
@@ -83,6 +88,7 @@
|
|
|
83
88
|
"engines": {
|
|
84
89
|
"node": ">=22.19.0"
|
|
85
90
|
},
|
|
91
|
+
"packageManager": "npm@11.18.0",
|
|
86
92
|
"files": [
|
|
87
93
|
"dist/",
|
|
88
94
|
"docs/",
|
|
@@ -145,5 +151,8 @@
|
|
|
145
151
|
"@ast-grep/cli@0.45.3": true,
|
|
146
152
|
"@google/genai@1.52.0": true,
|
|
147
153
|
"protobufjs@7.6.5": true
|
|
154
|
+
},
|
|
155
|
+
"overrides": {
|
|
156
|
+
"qs": "^6.15.4"
|
|
148
157
|
}
|
|
149
158
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# SQL Injection Detection
|
|
2
|
-
# Detects unsafe interpolation in SQL-like template literals
|
|
2
|
+
# Detects unsafe interpolation in SQL-like template literals.
|
|
3
|
+
# Demoted from error/blocking to warning on 2026-09-10 (maintainer): the
|
|
4
|
+
# query keys on the callee NAME only (query|execute|exec|run), so any
|
|
5
|
+
# `run(`…${x}…`)` / `exec(`…`)` in non-SQL code fires — too many false
|
|
6
|
+
# positives to block on. A real SQL sink needs a receiver/type signal.
|
|
3
7
|
id: sql-injection
|
|
4
8
|
name: SQL Injection Risk
|
|
5
|
-
severity:
|
|
9
|
+
severity: warning
|
|
6
10
|
category: security
|
|
7
11
|
defect_class: injection
|
|
8
|
-
inline_tier:
|
|
12
|
+
inline_tier: warning
|
|
9
13
|
language: typescript
|
|
10
14
|
|
|
11
15
|
message: "SQL injection risk — use parameterized queries, never interpolate into SQL"
|