@herbertgao/pi-extensions 2026.9.15 → 2026.9.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/THIRD_PARTY_NOTICES.md +26 -0
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +1 -1
- package/node_modules/@narumitw/pi-btw/dist/index.ts +12 -6
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +4 -4
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +2 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +16 -4
- package/node_modules/pi-lens/CHANGELOG.md +498 -0
- package/node_modules/pi-lens/README.md +45 -2
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +23 -7
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +187 -51
- package/node_modules/pi-lens/dist/clients/cache-manager.js +64 -5
- package/node_modules/pi-lens/dist/clients/child-unref.js +17 -8
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +2 -0
- package/node_modules/pi-lens/dist/clients/config-locations.js +237 -9
- package/node_modules/pi-lens/dist/clients/config-resolve.js +7 -1
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +33 -3
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +87 -64
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -3
- package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +118 -1
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +8 -2
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +23 -4
- package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +14 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +26 -28
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +38 -25
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +32 -49
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +16 -14
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +25 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +28 -47
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +11 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +27 -22
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +31 -46
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +29 -46
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +91 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +16 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +38 -23
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +27 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +31 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +34 -60
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +6 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +12 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +22 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +39 -16
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +27 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +18 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +6 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +11 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +10 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +11 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +12 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +30 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +23 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +8 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +11 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +15 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +12 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +27 -39
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +13 -3
- package/node_modules/pi-lens/dist/clients/effective-config.js +3 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +42 -11
- package/node_modules/pi-lens/dist/clients/formatters.js +49 -11
- package/node_modules/pi-lens/dist/clients/git-guard.js +247 -34
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +121 -25
- package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +186 -0
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +19 -6
- package/node_modules/pi-lens/dist/clients/installer/index.js +281 -32
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +8 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +8 -0
- package/node_modules/pi-lens/dist/clients/lens-config.js +66 -8
- package/node_modules/pi-lens/dist/clients/lsp/client.js +139 -11
- package/node_modules/pi-lens/dist/clients/lsp/config.js +9 -7
- package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +41 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +23 -2
- package/node_modules/pi-lens/dist/clients/lsp/server.js +106 -25
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +14 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +105 -16
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +232 -44
- package/node_modules/pi-lens/dist/clients/mcp/review.js +53 -7
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +11 -6
- package/node_modules/pi-lens/dist/clients/pipeline.js +121 -66
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +21 -3
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +11 -3
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +34 -26
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +16 -10
- package/node_modules/pi-lens/dist/clients/ruff-client.js +31 -4
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +38 -4
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +16 -5
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +27 -12
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +447 -280
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +256 -65
- package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +84 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +119 -58
- package/node_modules/pi-lens/dist/clients/turn-end/lane.js +51 -0
- package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +112 -0
- package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +204 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +59 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +145 -14
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +57 -3
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +26 -13
- package/node_modules/pi-lens/dist/index.js +5695 -3733
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +4 -0
- package/node_modules/pi-lens/dist/mcp/server.js +33 -21
- package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +123 -0
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +43 -16
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +118 -7
- package/node_modules/pi-lens/docs/adr/0001-stale-advisory-live-arm.md +29 -0
- package/node_modules/pi-lens/docs/adr/0002-workspace-hash-rendezvous.md +30 -0
- package/node_modules/pi-lens/docs/adr/0003-git-guard-latch-writer.md +203 -0
- package/node_modules/pi-lens/docs/adr/0004-disposition-policy-seam.md +38 -0
- package/node_modules/pi-lens/docs/adr/0005-tool-availability-enforcement-seam.md +29 -0
- package/node_modules/pi-lens/docs/adr/0006-derived-state-benchmark-first.md +31 -0
- package/node_modules/pi-lens/docs/adr/0007-end-to-end-witness-per-seam-slice.md +38 -0
- package/node_modules/pi-lens/docs/adr/0008-turn-end-lane-interface.md +165 -0
- package/node_modules/pi-lens/docs/adr/0009-reported-path-attribution.md +114 -0
- package/node_modules/pi-lens/docs/adr/README.md +26 -0
- package/node_modules/pi-lens/docs/agent-tools.md +18 -1
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +4 -3
- package/node_modules/pi-lens/docs/configuration.md +55 -1
- package/node_modules/pi-lens/docs/engineering-principles.md +202 -0
- package/node_modules/pi-lens/docs/environment-variables.md +61 -4
- package/node_modules/pi-lens/docs/features.md +2 -2
- package/node_modules/pi-lens/docs/globalconfig.md +6 -1
- package/node_modules/pi-lens/docs/language-coverage.md +17 -0
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +98 -31
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +57 -3
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +9 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +16 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +9 -0
- package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +2 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +21 -11
- package/node_modules/pi-lens/docs/settings.md +12 -3
- package/node_modules/pi-lens/docs/subagent-compat.md +1 -1
- package/node_modules/pi-lens/package.json +5 -3
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
- package/node_modules/pi-lens/scripts/install-selftest.mjs +21 -17
- package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +123 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +29 -0
- package/node_modules/pi-mcp-adapter/OAUTH.md +369 -0
- package/node_modules/pi-mcp-adapter/README.md +12 -5
- package/node_modules/pi-mcp-adapter/config.ts +31 -8
- package/node_modules/pi-mcp-adapter/direct-tool-surface.ts +1 -1
- package/node_modules/pi-mcp-adapter/dist/config.js +33 -8
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js +15 -2
- package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-auth.d.ts +2 -0
- package/node_modules/pi-mcp-adapter/dist/mcp-auth.js +27 -2
- package/node_modules/pi-mcp-adapter/dist/mcp-auth.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +1 -1
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/server-manager.js +6 -4
- package/node_modules/pi-mcp-adapter/dist/server-manager.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +2 -2
- package/node_modules/pi-mcp-adapter/dist/utils.d.ts +2 -0
- package/node_modules/pi-mcp-adapter/dist/utils.js +10 -3
- package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -1
- package/node_modules/pi-mcp-adapter/index.ts +37 -20
- package/node_modules/pi-mcp-adapter/init.ts +14 -15
- package/node_modules/pi-mcp-adapter/json-schema-validator.ts +16 -2
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +27 -2
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +1 -1
- package/node_modules/pi-mcp-adapter/package.json +3 -2
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +1 -1
- package/node_modules/pi-mcp-adapter/server-manager.ts +6 -3
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +99 -6
- package/node_modules/pi-mcp-adapter/types.ts +2 -2
- package/node_modules/pi-mcp-adapter/ui-session.ts +60 -27
- package/node_modules/pi-mcp-adapter/utils.ts +11 -3
- package/node_modules/pi-next-cue/.github/workflows/publish.yml +20 -0
- package/node_modules/pi-next-cue/LICENSE +21 -0
- package/node_modules/pi-next-cue/README.md +81 -0
- package/node_modules/pi-next-cue/index.ts +358 -0
- package/node_modules/pi-next-cue/package.json +28 -0
- package/package.json +8 -5
|
@@ -46,7 +46,24 @@ same gate rather than bypassing it.
|
|
|
46
46
|
`workspace`; explicit `paths` always win over `scope`). `severity` is a
|
|
47
47
|
threshold, not an exact filter: `error` shows only errors; `warning` adds
|
|
48
48
|
warnings; `information` adds information; `hint`/`all` (default) show every
|
|
49
|
-
tier.
|
|
49
|
+
tier. `source=lsp` reads a file's on-disk content and will not sync it to a
|
|
50
|
+
language server past **2 MiB or 5000 lines** (`clients/runtime-config.ts`
|
|
51
|
+
`pipeline.lspMaxFileBytes`/`lspMaxFileLines`, checked in
|
|
52
|
+
`clients/lsp/content-limits.ts`) — not env-tunable today. A file over that
|
|
53
|
+
bound gets an explicit `file too large for LSP diagnostics (<N> bytes/lines
|
|
54
|
+
> <limit>)` result instead of stale or partial diagnostics. This is a
|
|
55
|
+
*different* 2 MiB from the auto-fix full-content attachment cap described in
|
|
56
|
+
[agent-guide.md](agent-guide.md), section 6 ("Auto-format / auto-fix
|
|
57
|
+
timing") — the two caps currently share one constant
|
|
58
|
+
(`RUNTIME_CONFIG.pipeline.lspMaxFileBytes`) but gate unrelated behaviors
|
|
59
|
+
(LSP sync vs. tool-result content attachment) and can diverge independently
|
|
60
|
+
in the future. Separately, every save-triggered edit now sends the server a
|
|
61
|
+
`textDocument/didSave` when it declared `textDocumentSync.save` — with the
|
|
62
|
+
file text when the server asked for it (`includeText`) and the file is
|
|
63
|
+
within the same bound, otherwise the save is still sent but without `text`
|
|
64
|
+
(never dropped outright); this is what makes save-triggered servers like
|
|
65
|
+
Expert (Elixir) re-diagnose an edit made through pi-lens (refs #3405,
|
|
66
|
+
#3408). Legacy `mode`: `delta` (current turn), `all` (resurfaces stale
|
|
50
67
|
blockers dropped from turn context), `full` (project-wide scan).
|
|
51
68
|
- **`lens_diagnostic_mark`** — Triage a diagnostic: `false-positive` /
|
|
52
69
|
`suppress` (writes an inline `pi-lens-ignore` comment) / `defer`
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- GENERATED by scripts/gen-rule-catalogs.mjs — do not edit by hand. Run `npm run docs:rule-catalogs` after changing rules. -->
|
|
4
4
|
|
|
5
|
-
pi-lens bundles **
|
|
5
|
+
pi-lens bundles **482 enabled** ast-grep rules (298 pi-lens-authored + 184 vendored from CodeRabbit) across **17 languages**, plus 16 disabled.
|
|
6
6
|
|
|
7
7
|
See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `rules/ast-grep-rules/rules/` (pi-lens), `rules/ast-grep-rules/coderabbit/rules/` (vendored).
|
|
8
8
|
|
|
@@ -260,7 +260,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
|
|
|
260
260
|
| `openssl-cbc-static-iv-php` | warning | no | CodeRabbit | Static IV used with AES in CBC mode. Static IVs enable chosen-plaintext attacks against encrypted data. |
|
|
261
261
|
| `search-active-debug-php` | warning | no | CodeRabbit | Debug logging is explicitly enabled. This can potentially disclose sensitive information and should never be active on production systems. |
|
|
262
262
|
|
|
263
|
-
### Python (
|
|
263
|
+
### Python (99)
|
|
264
264
|
|
|
265
265
|
| Rule | Severity | Fixable | Source | Description |
|
|
266
266
|
|---|---|---|---|---|
|
|
@@ -271,7 +271,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
|
|
|
271
271
|
| `hashids-with-flask-secret-python` | warning | no | CodeRabbit | The Flask secret key is used as salt in HashIDs. The HashID mechanism is not secure. By observing sufficient HashIDs, the salt used to cons… |
|
|
272
272
|
| `insecure-cipher-algorithm-rc4-python` | warning | no | CodeRabbit | Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use… |
|
|
273
273
|
| `jwt-python-hardcoded-secret-python` | warning | no | CodeRabbit | Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definition… |
|
|
274
|
-
| `no-assert-tuple` |
|
|
274
|
+
| `no-assert-tuple` | warning | no | pi-lens | Assert should not be called on a tuple literal |
|
|
275
275
|
| `no-aws-access-key-literal` | error | no | pi-lens | AWS access keys should not be hardcoded — use IAM roles, environment variables, or AWS Secrets Manager |
|
|
276
276
|
| `no-aws-apigateway-no-auth` | error | no | pi-lens | AWS API Gateway should require authentication |
|
|
277
277
|
| `no-aws-s3-public-access` | error | no | pi-lens | S3 buckets should not grant access to all users or authenticated users |
|
|
@@ -361,6 +361,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
|
|
|
361
361
|
| `python-webrepl-empty-password-python` | warning | no | CodeRabbit | The application creates a database connection with an empty password. This can lead to unauthorized access by either an internal or externa… |
|
|
362
362
|
| `python-webrepl-hardcoded-secret-python` | warning | no | CodeRabbit | A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive da… |
|
|
363
363
|
| `reducible-list-comprehension` | warning | yes | pi-lens | A list comprehension is unnecessary here; use a generator expression |
|
|
364
|
+
| `unchecked-numeric-parse-python` | warning | no | pi-lens | int()/float() without try/except — raises ValueError on non-numeric input |
|
|
364
365
|
| `unchecked-throwing-call-python` | error | no | pi-lens | Call without try/except — throws on invalid input or missing file |
|
|
365
366
|
|
|
366
367
|
### Ruby (20)
|
|
@@ -5,7 +5,7 @@ There are **two** pi-lens config files:
|
|
|
5
5
|
| File | Scope | Notes |
|
|
6
6
|
| --- | --- | --- |
|
|
7
7
|
| `.pi-lens.json` | the project | Committed or not, your call. Nearest one wins **per field** — a package can override one setting without restating the repo root's. |
|
|
8
|
-
| `~/.pi-lens/config.json` | the machine | Your defaults across every project.
|
|
8
|
+
| `~/.pi-lens/config.json` | the machine | Your defaults across every project. The winning global location is selected by the [global-location table](#global-config-location); see [environment variables](environment-variables.md) for the knobs. |
|
|
9
9
|
|
|
10
10
|
Both files have the same shape, with one exception noted below the example:
|
|
11
11
|
everything LSP-related lives under an `lsp` namespace inside them.
|
|
@@ -86,6 +86,60 @@ Subsystem-specific env overrides follow the same shape: a
|
|
|
86
86
|
`reviewGraph.maxFiles`. `docs/environment-variables.md` and `docs/settings.md`
|
|
87
87
|
are the per-setting references.
|
|
88
88
|
|
|
89
|
+
### Global config location
|
|
90
|
+
|
|
91
|
+
The global file is selected by this order, highest precedence first. The
|
|
92
|
+
canonical default is still `~/.pi-lens/config.json`; `PI_LENS_HOME` relocates
|
|
93
|
+
machine-generated data and state, not this file. This is the complete truth
|
|
94
|
+
table for the three existence axes.
|
|
95
|
+
|
|
96
|
+
| `PI_LENS_CONFIG_PATH` | `~/.pi-lens/config.json` exists | `PI_CODING_AGENT_DIR` set and `extensions/pi-lens.json` exists | Winner |
|
|
97
|
+
| --- | --- | --- | --- |
|
|
98
|
+
| unset | no | no | `~/.pi-lens/config.json` (canonical default) |
|
|
99
|
+
| unset | no | yes | `$PI_CODING_AGENT_DIR/extensions/pi-lens.json` |
|
|
100
|
+
| unset | yes | no | `~/.pi-lens/config.json` (grandfathered existing file) |
|
|
101
|
+
| unset | yes | yes | `~/.pi-lens/config.json` (the host file is shadowed; shadowed file reported once per session (#3299)) |
|
|
102
|
+
| set | no | no | the explicit `PI_LENS_CONFIG_PATH` file |
|
|
103
|
+
| set | no | yes | the explicit `PI_LENS_CONFIG_PATH` file |
|
|
104
|
+
| set | yes | no | the explicit `PI_LENS_CONFIG_PATH` file |
|
|
105
|
+
| set | yes | yes | the explicit `PI_LENS_CONFIG_PATH` file |
|
|
106
|
+
|
|
107
|
+
If an existence probe for a recognized candidate errors (for example,
|
|
108
|
+
`ENOTDIR`, `EACCES`, or `ELOOP`), that candidate's tier is retained rather
|
|
109
|
+
than falling through to a lower location. The subsequent read reports the
|
|
110
|
+
degraded config under `PILENS_CFG_0001`; a probe error is not treated as
|
|
111
|
+
absence.
|
|
112
|
+
|
|
113
|
+
pi-lens does not write this file. Create or edit it yourself, then start a new
|
|
114
|
+
process. For an XDG-like setup, put generated data and state at a durable data
|
|
115
|
+
root and choose one config surface:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
export PI_LENS_HOME="$HOME/.local/share/pi-lens"
|
|
119
|
+
|
|
120
|
+
# XDG-shaped host: use its config directory.
|
|
121
|
+
export PI_CODING_AGENT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/pi"
|
|
122
|
+
mkdir -p "$PI_CODING_AGENT_DIR/extensions"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
For hosts without `PI_CODING_AGENT_DIR`, use an explicit config path instead:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
export PI_LENS_CONFIG_PATH="${XDG_CONFIG_HOME:-$HOME/.config}/pi-lens/config.json"
|
|
129
|
+
mkdir -p "$(dirname "$PI_LENS_CONFIG_PATH")"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
When migrating an existing `~/.pi-lens/config.json`, create the new file first
|
|
133
|
+
and delete the old file second. While both exist, the old file wins by design;
|
|
134
|
+
deleting it first would leave the process without the intended settings. Copy
|
|
135
|
+
the file (or hand-author it, since pi-lens has no writer), verify the new
|
|
136
|
+
location, then run `rm "$HOME/.pi-lens/config.json"` to opt out of
|
|
137
|
+
grandfathering. If the new host file is later deleted, the old file wins again
|
|
138
|
+
while it exists; with neither file present, the canonical default path is used.
|
|
139
|
+
|
|
140
|
+
See also the [environment-variable reference](environment-variables.md#config-location)
|
|
141
|
+
and [settings overview](settings.md#the-three-ways-to-configure-pi-lens).
|
|
142
|
+
|
|
89
143
|
### One exception: `lsp.disabledServers` is a denial, not a value
|
|
90
144
|
|
|
91
145
|
Ordinary settings are last-tier-wins. A **denial** is not, because the tier
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Engineering principles
|
|
2
|
+
|
|
3
|
+
Source of truth: https://github.com/apmantza/engineering-principles (private), file PRINCIPLES.md. Verbatim copy; the repo wins on drift. Project-level AGENTS.md / CLAUDE.md add the project catalog and win on conflict.
|
|
4
|
+
|
|
5
|
+
Project-neutral rules distilled from the pi-lens contracts, playbooks and merge
|
|
6
|
+
train (2026-08 to 2026-09). Each rule is imperative and carries the reason it
|
|
7
|
+
exists. Projects keep their own catalog of defect shapes, registries, and
|
|
8
|
+
commands; this file is what stays the same across them.
|
|
9
|
+
|
|
10
|
+
Read order for any agent starting work: this file, then the project's own
|
|
11
|
+
AGENTS.md or CLAUDE.md, then the role contract for the task (fixer, reviewer,
|
|
12
|
+
investigator). Project instructions win on conflict.
|
|
13
|
+
|
|
14
|
+
## 1. Building
|
|
15
|
+
|
|
16
|
+
**Premise first.** Reproduce a reported defect through the production call
|
|
17
|
+
path before writing a fix. Drive the real dispatcher, loader, or builder; never
|
|
18
|
+
a hand-shaped input that exists only to hit the bug. If it does not reproduce,
|
|
19
|
+
the deliverable is the recorded refutation (which invariant covers it, with the
|
|
20
|
+
probe) and, where cheap, an assertion that pins it, not machinery for a
|
|
21
|
+
collision that cannot occur.
|
|
22
|
+
|
|
23
|
+
**Climb the minimalism ladder before writing code.** Be lazy about the
|
|
24
|
+
solution, never about reading. Trace the real flow, then ask in order: does this
|
|
25
|
+
need to exist at all; does the codebase already do it (reuse the seam); does the
|
|
26
|
+
platform or stdlib do it; does an installed dependency do it; is it one line.
|
|
27
|
+
Only then write the minimum that works. Validation, error handling, security and
|
|
28
|
+
bounded observability are never skipped in the name of minimalism.
|
|
29
|
+
|
|
30
|
+
**Net-count rule for shared helpers.** A change that introduces a shared helper
|
|
31
|
+
while same-shape siblings exist deletes at least one sibling in the same change.
|
|
32
|
+
The helper count never goes up. Deferring the fold is allowed only when the
|
|
33
|
+
brief names every sibling, states why folding them together is unsafe, and
|
|
34
|
+
links the follow-up. This binds whoever writes the brief as much as whoever
|
|
35
|
+
implements it.
|
|
36
|
+
|
|
37
|
+
**A fix's pattern matters more than its instance.** When a root cause is
|
|
38
|
+
understood, name the defect shape and sweep the whole tree for other members
|
|
39
|
+
before closing. Fix the contained siblings in the same change; file the rest
|
|
40
|
+
with the member list; record what was grepped and what was found clean. Seeing
|
|
41
|
+
without recording is indistinguishable from not looking. Every sweep ends with
|
|
42
|
+
a consolidation verdict: fold onto one seam (name it) or stay distributed (say
|
|
43
|
+
why). The deciding test is deletion: would removing the shared module
|
|
44
|
+
concentrate complexity back into callers (fold) or merely relocate the same
|
|
45
|
+
lines (stay)?
|
|
46
|
+
|
|
47
|
+
**Design shared state once, at design time.** Before adding a second writer to
|
|
48
|
+
any shared record (a cache entry, a latch, a ledger, a mirror, a counter) decide
|
|
49
|
+
whether every actor needs one canonical object or each can own its record and
|
|
50
|
+
merge at read. Refresh mirrors inside the guard that published the durable
|
|
51
|
+
state. A resource bounded along one axis and unbounded along another is a leak.
|
|
52
|
+
|
|
53
|
+
**Every new failure path gets bounded observability.** One record per distinct
|
|
54
|
+
event per session, never one per occurrence in a loop; repeated degradations go
|
|
55
|
+
through a once-only or counted record. A discriminator nothing can observe is a
|
|
56
|
+
vacuous guard and does not ship.
|
|
57
|
+
|
|
58
|
+
**Blast radius as a call-tree diff.** For any change to a shared seam, list the
|
|
59
|
+
changed symbol, its callers above, its callees below, with plus and minus on the
|
|
60
|
+
lines that moved. Prose keeps missing callers; a tree the reviewer can grep does
|
|
61
|
+
not. Name every strict consumer of a durable record whose shape changes, and
|
|
62
|
+
prove old records still parse.
|
|
63
|
+
|
|
64
|
+
**Deletion sweeps dependents first.** Before removing a guard, a defensive
|
|
65
|
+
branch, or a field, grep every caller and every test double. Correct-looking
|
|
66
|
+
deletion asks have redded CI because dozens of doubles depended on the removed
|
|
67
|
+
line.
|
|
68
|
+
|
|
69
|
+
**Identity and lifecycle rules are stated before the first edit.** When a change
|
|
70
|
+
touches session, ownership, or resume semantics, write the invariants and the
|
|
71
|
+
writers-by-axis table (which actor, which identity, which timing) first, and
|
|
72
|
+
choose the simplest identity rule that satisfies every cell. Adding a second
|
|
73
|
+
identity clause "to be safe" produced two consecutive regressions on one seam.
|
|
74
|
+
|
|
75
|
+
## 2. Testing
|
|
76
|
+
|
|
77
|
+
**Red first, and keep the transcript.** Every regression test is shown failing
|
|
78
|
+
on the pre-fix code with the failure that matches the defect, and the output is
|
|
79
|
+
pasted into the change description. A test that passes pre-fix is a finding.
|
|
80
|
+
|
|
81
|
+
**Tests ship with the code, in the same commit.** A change and the tests that
|
|
82
|
+
prove it land together; a test-only follow-up round means the first commit
|
|
83
|
+
shipped unproven. The failure list is written before the first edit, and the
|
|
84
|
+
mutation table is that list with transcripts, never a list invented after the
|
|
85
|
+
code.
|
|
86
|
+
|
|
87
|
+
**Keep fixture corpora from every supported version.** Every durable record,
|
|
88
|
+
config file, cache entry or wire message the project still reads has a fixture
|
|
89
|
+
from each version that produced it, and the parser is run over all of them. An
|
|
90
|
+
old-record parse proof is a fixture in the corpus, not a sentence in a PR body.
|
|
91
|
+
|
|
92
|
+
**Mutation output is quoted, not ticked.** For every new guard, branch, filter,
|
|
93
|
+
cap or fallback: neuter it in the built output, run the suite that should catch
|
|
94
|
+
it, and paste the red. A checked box with no transcript is treated as false. A
|
|
95
|
+
mutation that fails to compile proves nothing about the test; redo it as a
|
|
96
|
+
compile-valid change. A guard that cannot be made to red does not need to exist.
|
|
97
|
+
|
|
98
|
+
**Tautological tests are harmful.** A test observes behaviour through the real
|
|
99
|
+
seam and asserts an independent effect. It never restates the implementation,
|
|
100
|
+
never asserts a value its own setup supplied, and never swaps a real in-process
|
|
101
|
+
store, sink, coordinator or registry for a fake. Mocks belong only at true
|
|
102
|
+
process or host boundaries.
|
|
103
|
+
|
|
104
|
+
**Every guard test names the recurrence it prevents** in its own comment: the
|
|
105
|
+
shipped defect or the concrete drift it would catch. A guard with no named
|
|
106
|
+
recurrence is speculative and does not ship.
|
|
107
|
+
|
|
108
|
+
**Detectors match code, not prose.** Any test-side scan that regexes source
|
|
109
|
+
must run over comment-and-string-blanked text, with a per-needle policy for the
|
|
110
|
+
rare needle whose evidence is a string literal. A comment quoting the needle
|
|
111
|
+
must never satisfy a requirement or an exemption. The self-excuse direction
|
|
112
|
+
(prose makes a guard pass) is the dangerous one; the false-positive direction
|
|
113
|
+
reds loudly and is lower priority.
|
|
114
|
+
|
|
115
|
+
**Ratchets and baselines are admissions, not loosening.** A new real spawn,
|
|
116
|
+
timer, or wall-clock assertion is admitted with a header stating why the real
|
|
117
|
+
thing is required, a registry entry, a baseline row and lane membership. A
|
|
118
|
+
mocked seam is not a real spawn and gets an exemption with its reason, never an
|
|
119
|
+
admission.
|
|
120
|
+
|
|
121
|
+
**Run targeted files while iterating; the full suite runs once.** Build before
|
|
122
|
+
testing when tests execute compiled output, and rebuild between mutations. A red
|
|
123
|
+
is environmental only when the same test is red on the base branch in the same
|
|
124
|
+
environment; say so with the evidence.
|
|
125
|
+
|
|
126
|
+
**Probe hygiene.** Every probe, test run and child process pins its home,
|
|
127
|
+
data and log directories under the working tree. Nothing an agent runs writes
|
|
128
|
+
to the maintainer's real home.
|
|
129
|
+
|
|
130
|
+
## 3. Reviewing and delegating
|
|
131
|
+
|
|
132
|
+
**Every change is reviewed adversarially, including small and self-authored
|
|
133
|
+
ones.** Depth follows what the diff touches, never the priority label: runtime,
|
|
134
|
+
tooling, CI and manifests get full adversarial review; test-only diffs that are
|
|
135
|
+
not ratchets get one scoped pass; docs and renames get an orchestrator read plus
|
|
136
|
+
CI on the exact head.
|
|
137
|
+
|
|
138
|
+
**A finding is real when a probe proves it; a fix is real when the same probe
|
|
139
|
+
passes.** Reviewers attack with throwaway probes and quote the output. They
|
|
140
|
+
reproduce the red run themselves (keep the tests, revert the source), mutate
|
|
141
|
+
every new guard, check merge state first (a conflicted change silently skips
|
|
142
|
+
its gates), and read CI on the exact head. Reviewer prescriptions are
|
|
143
|
+
hypotheses: the verify round attacks them as a rival's.
|
|
144
|
+
|
|
145
|
+
**The same reviewer verifies each fix round.** Continuity is the reviewer's
|
|
146
|
+
judgment and probe set; the checkout under it is rebuilt fresh at the new head
|
|
147
|
+
every round. When a review or verify names a new defect on the same seam, the
|
|
148
|
+
next fix opens with the state-space table written before any edit, on the
|
|
149
|
+
strongest available model. Never send a third patch-only round on one seam.
|
|
150
|
+
|
|
151
|
+
**Round routing.** A round that only applies a prescribed remedy with quoted
|
|
152
|
+
reds merges on green. A round that adds mechanism, touches lifecycle or session
|
|
153
|
+
semantics, or rewrites a guard gets a fresh verify. Classify by the worst
|
|
154
|
+
finding, not the count. Intent-free findings (a body sentence, a comment, a
|
|
155
|
+
literal, a changelog line) are applied by the orchestrator as trailing commits
|
|
156
|
+
and never re-verified; anything that changes what code means goes through a
|
|
157
|
+
round, however small it looks.
|
|
158
|
+
|
|
159
|
+
**Merge gate.** Merge only when the verdict is merge-ready, every gating check
|
|
160
|
+
genuinely executed and passed on the exact head, and every failing check was
|
|
161
|
+
read and judged. Absent is not green. Read exit codes directly, never after a
|
|
162
|
+
pipe. After a merge, check the other open changes for conflicts and prune only
|
|
163
|
+
the merged lane's worktrees.
|
|
164
|
+
|
|
165
|
+
**Delegation contract.** Every delegation names the role, the absolute worktree,
|
|
166
|
+
branch, base, acceptance criteria, non-goals, sibling files to avoid, and Git
|
|
167
|
+
authority. A role never grants Git authority by itself. A worker without it
|
|
168
|
+
leaves changes uncommitted and hands off through a PR body and a commit message
|
|
169
|
+
at the worktree root; the orchestrator commits. Implementation and review are
|
|
170
|
+
never mixed in one delegation. Scope changes are mirrored on the tracking issue
|
|
171
|
+
before they are sent, so the worker can verify them.
|
|
172
|
+
|
|
173
|
+
**No manufactured work.** An idle worker is cheaper than fake work. Delegate
|
|
174
|
+
when a real producer, consumer, probe or diagnosis is unresolved, never to keep
|
|
175
|
+
a pool busy. The same applies to status artifacts: they exist for coordination
|
|
176
|
+
someone consumes.
|
|
177
|
+
|
|
178
|
+
## 4. Honesty and records
|
|
179
|
+
|
|
180
|
+
**Closes versus refs follows delivery, not optimism.** Close only when every
|
|
181
|
+
acceptance criterion is met; otherwise reference the issue and post the named
|
|
182
|
+
remainder before anything merges. After merging a referencing change, verify the
|
|
183
|
+
issue carries that comment or close it crediting the change.
|
|
184
|
+
|
|
185
|
+
**Report what ran, what was skipped, and what CI must still confirm.** A
|
|
186
|
+
skipped suite, an environment-blocked file, a mutation that could not be
|
|
187
|
+
executed: each is named, never implied green.
|
|
188
|
+
|
|
189
|
+
**Contracts move in the same session.** When a review or an incident reveals a
|
|
190
|
+
defect class rather than an instance, the rule enters the project's catalog with
|
|
191
|
+
the reference and a one-line screen before the next dispatch. Two rounds on the
|
|
192
|
+
same shape in one session is the trigger.
|
|
193
|
+
|
|
194
|
+
**Detection retrospective on every merged bug fix.** Record which verification
|
|
195
|
+
layer caught it and which layer should have caught it earlier and at what cost.
|
|
196
|
+
If that layer does not exist, file it with the bug as its named recurrence.
|
|
197
|
+
|
|
198
|
+
**Keep a lane ledger.** One row per lane with a fixed state vocabulary (not
|
|
199
|
+
started, fixing rN, waiting on CI, waiting on review, waiting on verify,
|
|
200
|
+
blocked, ready to merge, merged, needs user decision, held). It is what survives
|
|
201
|
+
a context reset, and it lets a different orchestrator build the status table
|
|
202
|
+
without reading transcripts.
|
|
@@ -30,13 +30,36 @@ config JSON) and how they interact, see [Settings](settings.md).
|
|
|
30
30
|
|
|
31
31
|
### `PI_LENS_CONFIG_PATH`
|
|
32
32
|
|
|
33
|
-
Override the path of the global config file. **Default:**
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
Override the path of the global config file. **Default:** the resolution order
|
|
34
|
+
below. When set, the value is resolved to an absolute path and used verbatim;
|
|
35
|
+
it wins over every other location. See the [winning-location table](configuration.md#global-config-location).
|
|
36
36
|
|
|
37
37
|
**When to set it:** keeping the config under version control or a dotfiles
|
|
38
38
|
manager at a non-default location, or pointing CI at a fixture config.
|
|
39
39
|
|
|
40
|
+
### `PI_CODING_AGENT_DIR`
|
|
41
|
+
|
|
42
|
+
Host-relative global config location, honored by pi-lens when pi sets it.
|
|
43
|
+
**Resolved path:** `$PI_CODING_AGENT_DIR/extensions/pi-lens.json`. The tier is
|
|
44
|
+
opt-in by creation: the file is read when it EXISTS and the legacy default
|
|
45
|
+
does not. Absent, nothing changes.
|
|
46
|
+
|
|
47
|
+
The full resolution order for the global config file, highest first:
|
|
48
|
+
|
|
49
|
+
1. `PI_LENS_CONFIG_PATH` — an explicit file override, used verbatim.
|
|
50
|
+
2. `~/.pi-lens/config.json` — **only when it already exists**; current users
|
|
51
|
+
never move.
|
|
52
|
+
3. `$PI_CODING_AGENT_DIR/extensions/pi-lens.json` — **only when it exists**
|
|
53
|
+
and step 2 missed.
|
|
54
|
+
4. `~/.pi-lens/config.json` — the canonical default (unchanged).
|
|
55
|
+
|
|
56
|
+
pi-lens does not write the global config; there is no settings writer in this
|
|
57
|
+
repository. Create or edit the selected file by hand. `effective_config` shows
|
|
58
|
+
which file supplies the global tier. If an existence probe errors (a file where
|
|
59
|
+
a directory belongs, permission errors, or a symlink loop), the errored tier is
|
|
60
|
+
retained and the read failure is reported under `PILENS_CFG_0001`; it is not
|
|
61
|
+
treated as absent. See the [XDG-like recipe](configuration.md#global-config-location).
|
|
62
|
+
|
|
40
63
|
## Data directory
|
|
41
64
|
|
|
42
65
|
### `PILENS_DATA_DIR`
|
|
@@ -260,12 +283,46 @@ Days to keep rotated logs before cleanup. **Default:** `7`.
|
|
|
260
283
|
|
|
261
284
|
Maximum log size (MB) before rotation. **Default:** `10`.
|
|
262
285
|
|
|
286
|
+
## Diagnostic-only knobs
|
|
287
|
+
|
|
288
|
+
These use the `PILENS_` (no underscore after `PI`) prefix, so they are
|
|
289
|
+
invisible to a `grep PI_LENS_` sweep — use the wider `grep -E 'PI_?LENS_'`
|
|
290
|
+
below to find them and anything like them. Not part of the supported surface;
|
|
291
|
+
each exists for a narrow diagnostic or escape-hatch purpose, not everyday
|
|
292
|
+
tuning.
|
|
293
|
+
|
|
294
|
+
### `PILENS_PROBE`
|
|
295
|
+
|
|
296
|
+
Set to `1` to force an ad-hoc probe (a bare `node -e` or throwaway script
|
|
297
|
+
against built `clients/*.js`, run outside a test harness and without
|
|
298
|
+
`PI_LENS_HOME` set) to redirect its home/log directory away from the real
|
|
299
|
+
`~/.pi-lens`, the same way running from an agent worktree or `os.tmpdir()`
|
|
300
|
+
already does automatically (`clients/probe-home-state.ts`). Prefer setting
|
|
301
|
+
`PI_LENS_HOME` explicitly; this is the forced opt-in for a probe run from an
|
|
302
|
+
ordinary project checkout, where the automatic detection would not fire.
|
|
303
|
+
|
|
304
|
+
### `PILENS_UNSAFE_FORCE_GRAMMAR_LOAD`
|
|
305
|
+
|
|
306
|
+
Diagnostic escape hatch for the grammar-health probe only (`clients/grammar-source.ts`).
|
|
307
|
+
Set to `1` to force-load a tree-sitter grammar this runtime has blocklisted,
|
|
308
|
+
to test whether a newer build/runtime lifts the block. Disables the crash
|
|
309
|
+
protection the blocklist provides and can abort the process. Never set in
|
|
310
|
+
normal operation.
|
|
311
|
+
|
|
312
|
+
### `PILENS_PUB_DEBUG`
|
|
313
|
+
|
|
314
|
+
Set to `1` to trace each LSP server's `publishDiagnostics` behavior (version +
|
|
315
|
+
diagnostic count) to diagnose the clean-file affirmative-signal question:
|
|
316
|
+
which servers publish an empty-with-version set on a clean scan vs. go silent
|
|
317
|
+
(`clients/lsp/client.ts`). Off by default.
|
|
318
|
+
|
|
263
319
|
## Advanced tuning knobs
|
|
264
320
|
|
|
265
321
|
pi-lens also has many advanced/internal tuning variables — LSP timeouts and
|
|
266
322
|
memory budgets, debounce intervals (`PI_LENS_LSP_*`, and others). These are for
|
|
267
323
|
edge-case tuning, are not part of the supported surface above, and are documented
|
|
268
|
-
in the source; enumerate them with `grep
|
|
324
|
+
in the source; enumerate them with `grep -E 'PI_?LENS_' clients/` (the wider
|
|
325
|
+
pattern catches the `PILENS_` diagnostic-only knobs above too).
|
|
269
326
|
|
|
270
327
|
## Related
|
|
271
328
|
|
|
@@ -316,7 +316,7 @@ Covers JavaScript/TypeScript, Python, Go, Rust, Ruby, Shell, and CMake. A TypeSc
|
|
|
316
316
|
|
|
317
317
|
Structural rules organized by language in `rules/tree-sitter-queries/<language>/`. Rules marked **🔴** block the agent inline at write time (only for lines in the current edit); others are advisory.
|
|
318
318
|
|
|
319
|
-
**Suppressing a finding:** add `// pi-lens-ignore: rule-id` on the flagged line or the line above (JS/TS), or `# pi-lens-ignore: rule-id` for Python/Ruby/Shell. This suppresses
|
|
319
|
+
**Suppressing a finding:** add `// pi-lens-ignore: rule-id` on the flagged line or the line above (JS/TS), or `# pi-lens-ignore: rule-id` for Python/Ruby/Shell. Rule ids are comma-separated. A supported separator (` -- `, ` — `, or `: `) starts one trailing reason suffix for the whole payload; all remaining text, including commas, stays in the reason and is not parsed as another rule id. This suppresses each listed rule at that location only.
|
|
320
320
|
|
|
321
321
|
**Bring your own rules:** drop YAML query files into `rules/tree-sitter-queries/<language>/` in your project — pi-lens merges them with the built-ins on session start. The schema, predicates (`eq`, `match`, `any-of`), and `inline_tier` (`blocking` | `warning` | `review`) are documented in [`custom-rules.md`](custom-rules.md). A `rules/tree-sitter-queries/rule-schema.json` JSON Schema is bundled for editor autocomplete via `.vscode/settings.json`.
|
|
322
322
|
|
|
@@ -401,7 +401,7 @@ pi-lens ships an MCP (Model Context Protocol) server so Claude Code — or any M
|
|
|
401
401
|
| **Per-turn** | `pilens_turn_end` | Drives the **real** `handleTurnEnd` (knip incremental, dep-circular, cascade, tests, actionable+code-quality warnings) — not a re-implementation. Caller-supplied edited files are auto-registered into turn-state via `addModifiedRange`. |
|
|
402
402
|
| **Per-session** | `pilens_session_start` | Drives the **real** `handleSessionStart` — full jscpd/knip/madge/govulncheck/gitleaks/trivy scans + complexity baselines + LSP warm. The error-debt baseline is not currently populated by the production session-start path. |
|
|
403
403
|
| **Project / observability** | `pilens_project_scan`, `pilens_project_report`, `pilens_diagnostics`, `pilens_health`, `pilens_latency`, `pilens_symbol_search`, `pilens_effective_config` | Cheap project-wide scans, cached diagnostic state, latency telemetry, ranked identifier search (BM25 over the persisted word index — see [docs/word-index.md](word-index.md)). Cross-file blast radius now lives in `pilens_module_report`'s `blastRadius` option. `pilens_health` (and its pi-side `/lens-health` counterpart) also reports a bounded, process-local **degradation ledger** — trust refusals, mode suppressions, LSP breaker trips, formatter skips/failures, TypeScript/word-index/review-graph/project-snapshot idle evictions, WASM aborts, and diagnostics-timeout tallies — so silently degraded behavior stays visible instead of vanishing into a log. `pilens_effective_config` answers **“why is X running / why is X not running”** from one query — the resolved configuration with the provenance of every setting, and for a file you name, its language plus every LSP server with the reason it was selected or denied and the runners that would dispatch. It reports sources, never values. |
|
|
404
|
-
| **Lifecycle / loop** | `pilens_rebuild` |
|
|
404
|
+
| **Lifecycle / loop** | `pilens_rebuild`, `pilens_session_end` | `pilens_rebuild` runs `npm run build:dist` so `pilens_analyze mode=fresh` reflects the latest commit. Makes the review loop self-contained: commit → `pilens_rebuild` → `pilens_analyze mode=fresh` → `pilens_latency`. `pilens_session_end` ends the MCP connection's telemetry session and writes its bounded situational-tool telemetry line; terminal for the connection. |
|
|
405
405
|
|
|
406
406
|
**Honest limits** (live-tested, documented in `mcp.md`):
|
|
407
407
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Configuration
|
|
2
2
|
|
|
3
|
-
pi-lens reads optional user preferences from
|
|
3
|
+
pi-lens reads optional user preferences from the global file selected by the
|
|
4
|
+
[winning-location table](configuration.md#global-config-location) (`~/.pi-lens/config.json`
|
|
5
|
+
by default; `%USERPROFILE%\\.pi-lens\\config.json` on Windows). An unrecognized
|
|
6
|
+
top-level key is logged once (to surface a typo like `lps` for `lsp`) and then
|
|
7
|
+
ignored; `$schema` is always allowed for editor JSON-schema association. Missing
|
|
8
|
+
or invalid config falls back to defaults.
|
|
4
9
|
|
|
5
10
|
## Every toggle, both ways
|
|
6
11
|
|
|
@@ -50,6 +50,8 @@ Dispatch is diagnostics-oriented: automatic formatting and safe autofix happen i
|
|
|
50
50
|
| CMake | ✓ (cmake-language-server) | lsp | cmake-format |
|
|
51
51
|
| CUE | ✓ (syntax via cue lsp, evaluation via cue vet) | lsp, cue-vet | cue fmt |
|
|
52
52
|
|
|
53
|
+
### CUE tree-sitter grammar
|
|
54
|
+
|
|
53
55
|
`cue lsp` reports load and parse errors as you type but leaves conflicting
|
|
54
56
|
values and failed constraints to `cue vet` — the `cue-vet` auxiliary runner
|
|
55
57
|
(#1522) covers that gap, so together they give full coverage: syntax/parse
|
|
@@ -79,6 +81,21 @@ Both are upstream grammar limitations (tracked among
|
|
|
79
81
|
[eonpatapon/tree-sitter-cue](https://github.com/eonpatapon/tree-sitter-cue)'s
|
|
80
82
|
open issues), not something a query change here can fix.
|
|
81
83
|
|
|
84
|
+
## Non-core grammars
|
|
85
|
+
|
|
86
|
+
The `tree-sitter` runner and `symbol_search`/`module_report` structural
|
|
87
|
+
extraction ship a fixed set of core grammars; grammars for the other
|
|
88
|
+
languages in the table above (CUE included) are fetched lazily on first use
|
|
89
|
+
into web-tree-sitter's resolved package directory, verified against
|
|
90
|
+
`scripts/grammars.lock.json`. This resolution works on a runtime that cannot
|
|
91
|
+
resolve a bare package specifier — pi shipped as a `bun build --compile`
|
|
92
|
+
binary — via one shared subpath-based ladder
|
|
93
|
+
(`scripts/lib/web-tree-sitter-dir.mjs`, #3409); before that fix, non-core
|
|
94
|
+
languages could never be analysed on those hosts. A grammar that never loads
|
|
95
|
+
(fetch failure, unwritable target, an unsupported runtime) is recorded as a
|
|
96
|
+
`grammar_unavailable` **skip**, never a clean pass
|
|
97
|
+
(`clients/dispatch/runners/tree-sitter.ts`).
|
|
98
|
+
|
|
82
99
|
## Considered and skipped (2026-08-20 survey, closed out by #1757)
|
|
83
100
|
|
|
84
101
|
Recorded so these are not re-litigated. The 2026-08-20 survey's first pass
|