pi-lens 4.4.0 → 4.4.2
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/CHANGELOG.md +158 -0
- package/README.md +1 -0
- package/config/dependency-cruiser-eager-allowlist.json +3 -1
- package/dist/{chunk-IXEBJSUE.js → chunk-23WOO7TX.js} +11 -10
- package/dist/{chunk-E2WFBRHM.js → chunk-2B73ZPOK.js} +3 -3
- package/dist/{chunk-DQ2NZ7C4.js → chunk-2BBLFX75.js} +139 -11
- package/dist/{chunk-ZMOL6RQC.js → chunk-2CD5RS6M.js} +2 -2
- package/dist/{chunk-VD4JQCQC.js → chunk-2ZGIZPDG.js} +38 -37
- package/dist/{chunk-DIULIWKU.js → chunk-34WSVGEM.js} +29 -3
- package/dist/chunk-3JNKMP3B.js +17 -0
- package/dist/{chunk-HVUZXSWK.js → chunk-3UUPUE3O.js} +45 -41
- package/dist/{chunk-5RXBNSW2.js → chunk-3VPVG5SU.js} +16 -8
- package/dist/chunk-3WA4HP4I.js +55 -0
- package/dist/chunk-466Z26MG.js +30 -0
- package/dist/{chunk-34U7PLGE.js → chunk-4UNXBNE2.js} +12 -11
- package/dist/{chunk-E4MAEDPM.js → chunk-4W4VLAPJ.js} +12 -11
- package/dist/{chunk-GUOGVTCQ.js → chunk-52FUZI6K.js} +4 -2
- package/dist/chunk-5JM2524W.js +84 -0
- package/dist/{chunk-VHQLPIRJ.js → chunk-5NGR67U5.js} +2 -2
- package/dist/{chunk-DFVMIKMQ.js → chunk-66SXUJCA.js} +45 -9
- package/dist/{chunk-OQGFCZJ4.js → chunk-66VMUL7Q.js} +16 -16
- package/dist/{chunk-HWBZIGMJ.js → chunk-67WMNWEE.js} +9 -8
- package/dist/{chunk-6QIUX4EP.js → chunk-6C7JWPCP.js} +7 -7
- package/dist/{chunk-47D2BO4S.js → chunk-6GFRNVYR.js} +11 -10
- package/dist/{chunk-ZAWW3AF6.js → chunk-6SDEP3AJ.js} +9 -8
- package/dist/{chunk-TGPXLY2J.js → chunk-724UL2TJ.js} +38 -2
- package/dist/{chunk-YLF3PPT5.js → chunk-76MWC2K6.js} +3 -3
- package/dist/{chunk-F3P7VQ7H.js → chunk-7DYBLXYA.js} +3 -3
- package/dist/{chunk-AJ3QXTRQ.js → chunk-7ULNCDCO.js} +37 -35
- package/dist/{chunk-UK3CMEAL.js → chunk-AOHZU2BM.js} +1 -1
- package/dist/{chunk-F3AU2TMM.js → chunk-ARJ6PLFH.js} +44 -28
- package/dist/{chunk-U3VGR4VU.js → chunk-AW7R2GWG.js} +65 -8
- package/dist/{chunk-FJNKANOS.js → chunk-BKE7E7TC.js} +10 -9
- package/dist/{chunk-4W2PLC4J.js → chunk-BRGDSBJE.js} +13 -12
- package/dist/{chunk-VN2AXLEX.js → chunk-C34ZXZ7O.js} +102 -16
- package/dist/{chunk-T4ERT73Y.js → chunk-CF24OIYI.js} +21 -20
- package/dist/{chunk-NMABWBZN.js → chunk-CHOW74WE.js} +1 -1
- package/dist/{chunk-ARFCXG7S.js → chunk-CO2G5PHH.js} +2 -2
- package/dist/{chunk-AS44CFQ4.js → chunk-EETY4LF7.js} +24 -10
- package/dist/{chunk-I3R7GKDR.js → chunk-EJIUXPBX.js} +1 -1
- package/dist/{chunk-B3I2UUT4.js → chunk-ESBQHFMJ.js} +653 -251
- package/dist/{chunk-O5WILGMI.js → chunk-FLKWCIZH.js} +8 -5
- package/dist/{chunk-LNAKEO63.js → chunk-GAEGEPOC.js} +4 -4
- package/dist/{chunk-V7R425XG.js → chunk-GBPP5P7X.js} +4 -4
- package/dist/{chunk-XK4CIILI.js → chunk-GHB6AYCP.js} +27 -26
- package/dist/{chunk-7FBF7NPR.js → chunk-GOYRYZ2R.js} +29 -26
- package/dist/{chunk-JOLITGCC.js → chunk-GXW6K4YJ.js} +1 -1
- package/dist/{chunk-NXPS2L6U.js → chunk-GZYBXISR.js} +9 -9
- package/dist/{chunk-OAXNDZJ7.js → chunk-IBGIOBEE.js} +8 -4
- package/dist/{chunk-IIXOAGHR.js → chunk-IBRALRBR.js} +19 -15
- package/dist/{chunk-7F72PXY2.js → chunk-IXXDFY73.js} +3 -3
- package/dist/chunk-IZSHAIJ7.js +26 -0
- package/dist/{chunk-N3YQJI6O.js → chunk-JAU72XNY.js} +20 -15
- package/dist/chunk-JMYYOTQG.js +77 -0
- package/dist/{chunk-NL5GLMFI.js → chunk-JSQFTSC6.js} +12 -11
- package/dist/{chunk-IVP5KAB7.js → chunk-JWA5I3SR.js} +35 -21
- package/dist/{chunk-Y4T27COV.js → chunk-KBG47GHP.js} +4 -4
- package/dist/{chunk-PWFHBTSF.js → chunk-L3BLXZG7.js} +2 -2
- package/dist/chunk-LOP6GRPH.js +31 -0
- package/dist/chunk-MQLUAEOC.js +162 -0
- package/dist/{chunk-RPD5K5NC.js → chunk-MRXKYPCS.js} +2 -2
- package/dist/{chunk-Q5U6FMDI.js → chunk-N2H3ZPZY.js} +59 -7
- package/dist/{chunk-27BBHSZC.js → chunk-N3X6Q4YT.js} +3 -3
- package/dist/{chunk-UY752QSN.js → chunk-NW7BOILN.js} +19 -17
- package/dist/{chunk-TLGFBM3F.js → chunk-ODBNXWT4.js} +302 -113
- package/dist/{chunk-TT22N74J.js → chunk-OG5UUPN7.js} +13 -13
- package/dist/{chunk-C2AUYXQH.js → chunk-OXXKQCSV.js} +6 -6
- package/dist/{chunk-PAK6IDME.js → chunk-P7266HLM.js} +2 -2
- package/dist/{chunk-52H5B5TC.js → chunk-PFNSLWU5.js} +31 -30
- package/dist/{chunk-5ZEJHV35.js → chunk-PHDMFAKM.js} +12 -2
- package/dist/{chunk-3I5QFT3N.js → chunk-PNQDPDRC.js} +6 -3
- package/dist/{chunk-TVN5N6GY.js → chunk-PV6LR5P5.js} +6057 -1311
- package/dist/{chunk-AHDW3GPE.js → chunk-Q6ZWTCLY.js} +24 -22
- package/dist/{chunk-RUOG5D2C.js → chunk-Q7DUK4LX.js} +5 -5
- package/dist/{chunk-YSNFMJKN.js → chunk-QGQ5CCCG.js} +2 -2
- package/dist/{chunk-LW6XKDZQ.js → chunk-QHJ6DQ2R.js} +287 -38
- package/dist/{chunk-GVXA6CCE.js → chunk-QILIYSJF.js} +1 -1
- package/dist/{chunk-22AVIGXS.js → chunk-QOBUHWHX.js} +12 -7
- package/dist/{chunk-5THXD6X5.js → chunk-QQNQ7SJW.js} +2 -75
- package/dist/{chunk-4RERDEXR.js → chunk-QZVW3AAK.js} +50 -41
- package/dist/{chunk-AWE5TMPO.js → chunk-R3PCY3YS.js} +14 -13
- package/dist/{chunk-HHYAELLJ.js → chunk-RPLINGVB.js} +7 -7
- package/dist/{chunk-EOKRQ3SA.js → chunk-RWWYJ623.js} +10 -1
- package/dist/{chunk-YGVYKNSN.js → chunk-SAEFPSB6.js} +59 -12
- package/dist/{chunk-K6VYLB2U.js → chunk-TYM6OUIT.js} +13 -12
- package/dist/{chunk-AJXODZY6.js → chunk-UXGETRP4.js} +13 -12
- package/dist/{chunk-I7SPGOWI.js → chunk-UZ3TUTRV.js} +1 -1
- package/dist/{chunk-TO6WL3GM.js → chunk-VCHXCQFG.js} +12 -2
- package/dist/{chunk-BRJKOBZP.js → chunk-VITUCP5A.js} +17 -6
- package/dist/{chunk-WONERJTP.js → chunk-VRZP76YM.js} +1 -1
- package/dist/{chunk-OS32RNR2.js → chunk-VSSBEUFT.js} +16 -15
- package/dist/{chunk-VDBPVIKD.js → chunk-VWCXW2E7.js} +1 -1
- package/dist/{chunk-NKOUFPQF.js → chunk-WOA4LN2R.js} +2 -2
- package/dist/{chunk-RIISMHKN.js → chunk-WOKKRCJ5.js} +15 -13
- package/dist/{chunk-XECLWQZN.js → chunk-WU567RSC.js} +13 -10
- package/dist/{chunk-V5PXFSZK.js → chunk-XCJN5IJU.js} +4 -4
- package/dist/{chunk-ORTMY4Q4.js → chunk-XKIZ2HNN.js} +22 -14
- package/dist/{chunk-6VCD4VKZ.js → chunk-XMSXXAHW.js} +2 -2
- package/dist/chunk-XPZPXCBV.js +28 -0
- package/dist/{chunk-O6TQT6RI.js → chunk-XTMJ7XDT.js} +1 -1
- package/dist/{chunk-VNMT7C64.js → chunk-XVF2VVXP.js} +5 -3
- package/dist/chunk-Z527N6YQ.js +28 -0
- package/dist/{chunk-NTUJEGDZ.js → chunk-ZANLILYD.js} +22 -2
- package/dist/{chunk-6P62QVEA.js → chunk-ZGDGW2V3.js} +2 -2
- package/dist/{chunk-ODEEOXPH.js → chunk-ZHFZWTZV.js} +12 -11
- package/dist/{chunk-AJVLWNFN.js → chunk-ZXYDQ3TZ.js} +5 -5
- package/dist/index.js +102097 -97778
- package/dist/mcp/analyze-cli.js +18 -8
- package/dist/mcp/cli.js +48 -37
- package/dist/mcp/server.js +695 -426
- package/dist/mcp/worker.js +66 -55
- package/dist/probes/installer.js +20 -19
- package/docs/ast-grep_rules_catalog.md +2 -2
- package/docs/astplayground.md +1 -1
- package/docs/configuration.md +38 -2
- package/docs/custom-rules.md +25 -2
- package/docs/dependencies.md +3 -0
- package/docs/environment-variables.md +34 -6
- package/docs/features.md +39 -3
- package/docs/globalconfig.md +3 -1
- package/docs/language-coverage.md +2 -1
- package/docs/lsp-capability-matrix.md +29 -6
- package/docs/lsp-idle-eviction.md +38 -47
- package/docs/pi-lens-fixer.md +13 -5
- package/docs/pi-lens-merge-policy.md +48 -1
- package/docs/pi-lens-monitor.md +3 -1
- package/docs/pi-lens-retro.md +2 -1
- package/docs/pi-lens-reviewer.md +19 -3
- package/docs/pi-lens-subagent.md +2 -0
- package/docs/real-harness.md +17 -0
- package/docs/schema/pi-lens-config-v1.json +565 -0
- package/docs/servercapabilities.md +18 -4
- package/docs/settings.md +2 -1
- package/docs/word-index.md +6 -0
- package/package.json +1 -1
- package/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
- package/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
- package/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
- package/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
- package/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
- package/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
- package/dist/chunk-54B42YRX.js +0 -27
- package/dist/chunk-CGGAIP7J.js +0 -29
- package/dist/chunk-D6QS3U6M.js +0 -30
- package/dist/chunk-HMFXILPV.js +0 -83
- package/dist/chunk-LSMJ6KBE.js +0 -4139
- package/dist/chunk-NTHH2J74.js +0 -27
- package/dist/chunk-RPD4ZSB7.js +0 -25
- package/dist/chunk-T6D4Q4AQ.js +0 -54
- package/dist/chunk-VCSRSYLF.js +0 -81
package/dist/mcp/worker.js
CHANGED
|
@@ -2,74 +2,79 @@
|
|
|
2
2
|
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
analyzeFile
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-ODBNXWT4.js";
|
|
6
|
+
import "../chunk-OXXKQCSV.js";
|
|
7
|
+
import "../chunk-EJIUXPBX.js";
|
|
8
8
|
import "../chunk-FC4RP4I2.js";
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-66SXUJCA.js";
|
|
10
|
+
import "../chunk-VCHXCQFG.js";
|
|
11
|
+
import "../chunk-IXXDFY73.js";
|
|
12
|
+
import "../chunk-MRXKYPCS.js";
|
|
13
|
+
import "../chunk-2CD5RS6M.js";
|
|
14
|
+
import "../chunk-UZ3TUTRV.js";
|
|
15
|
+
import "../chunk-EETY4LF7.js";
|
|
16
|
+
import "../chunk-GOYRYZ2R.js";
|
|
17
|
+
import "../chunk-RPLINGVB.js";
|
|
18
|
+
import "../chunk-XCJN5IJU.js";
|
|
19
|
+
import "../chunk-76MWC2K6.js";
|
|
20
|
+
import "../chunk-GXW6K4YJ.js";
|
|
21
|
+
import "../chunk-2B73ZPOK.js";
|
|
22
|
+
import "../chunk-XMSXXAHW.js";
|
|
23
|
+
import "../chunk-7DYBLXYA.js";
|
|
24
|
+
import "../chunk-PV6LR5P5.js";
|
|
25
25
|
import "../chunk-3MED75HT.js";
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
-
import "../chunk-OAXNDZJ7.js";
|
|
26
|
+
import "../chunk-CO2G5PHH.js";
|
|
27
|
+
import "../chunk-IBGIOBEE.js";
|
|
28
|
+
import "../chunk-PNQDPDRC.js";
|
|
30
29
|
import "../chunk-XIMYZ3JA.js";
|
|
31
|
-
import "../chunk-
|
|
32
|
-
import "../chunk-
|
|
33
|
-
import "../chunk-
|
|
30
|
+
import "../chunk-ESBQHFMJ.js";
|
|
31
|
+
import "../chunk-34WSVGEM.js";
|
|
32
|
+
import "../chunk-VWCXW2E7.js";
|
|
33
|
+
import "../chunk-ZXYDQ3TZ.js";
|
|
34
34
|
import "../chunk-5W3R6LFT.js";
|
|
35
|
-
import "../chunk-
|
|
35
|
+
import "../chunk-QHJ6DQ2R.js";
|
|
36
36
|
import "../chunk-Z54ZSOBZ.js";
|
|
37
|
-
import "../chunk-
|
|
37
|
+
import "../chunk-724UL2TJ.js";
|
|
38
38
|
import "../chunk-QOZXJ4NA.js";
|
|
39
|
-
import "../chunk-
|
|
40
|
-
import "../chunk-
|
|
41
|
-
import "../chunk-
|
|
42
|
-
import "../chunk-
|
|
43
|
-
import "../chunk-
|
|
44
|
-
import "../chunk-
|
|
39
|
+
import "../chunk-GBPP5P7X.js";
|
|
40
|
+
import "../chunk-P7266HLM.js";
|
|
41
|
+
import "../chunk-MQLUAEOC.js";
|
|
42
|
+
import "../chunk-52FUZI6K.js";
|
|
43
|
+
import "../chunk-SAEFPSB6.js";
|
|
44
|
+
import "../chunk-GAEGEPOC.js";
|
|
45
45
|
import "../chunk-Z3CCVDUB.js";
|
|
46
|
-
import "../chunk-
|
|
46
|
+
import "../chunk-L3BLXZG7.js";
|
|
47
47
|
import "../chunk-2BEMIWEW.js";
|
|
48
|
-
import "../chunk-
|
|
49
|
-
import "../chunk-
|
|
50
|
-
import "../chunk-
|
|
51
|
-
import "../chunk-
|
|
52
|
-
import "../chunk-
|
|
53
|
-
import "../chunk-
|
|
54
|
-
import "../chunk-
|
|
55
|
-
import "../chunk-
|
|
56
|
-
import "../chunk-
|
|
57
|
-
import "../chunk-
|
|
58
|
-
import "../chunk-VN2AXLEX.js";
|
|
48
|
+
import "../chunk-66VMUL7Q.js";
|
|
49
|
+
import "../chunk-Q7DUK4LX.js";
|
|
50
|
+
import "../chunk-AW7R2GWG.js";
|
|
51
|
+
import "../chunk-RWWYJ623.js";
|
|
52
|
+
import "../chunk-VRZP76YM.js";
|
|
53
|
+
import "../chunk-QOBUHWHX.js";
|
|
54
|
+
import "../chunk-QILIYSJF.js";
|
|
55
|
+
import "../chunk-6C7JWPCP.js";
|
|
56
|
+
import "../chunk-5NGR67U5.js";
|
|
57
|
+
import "../chunk-C34ZXZ7O.js";
|
|
59
58
|
import "../chunk-BW5KFIQC.js";
|
|
60
59
|
import "../chunk-QYF5S6P6.js";
|
|
61
|
-
import "../chunk-
|
|
62
|
-
import "../chunk-
|
|
63
|
-
import "../chunk-
|
|
60
|
+
import "../chunk-PHDMFAKM.js";
|
|
61
|
+
import "../chunk-2BBLFX75.js";
|
|
62
|
+
import "../chunk-XVF2VVXP.js";
|
|
63
|
+
import {
|
|
64
|
+
setProjectTrustState
|
|
65
|
+
} from "../chunk-ZANLILYD.js";
|
|
64
66
|
import "../chunk-2EECBNC5.js";
|
|
65
|
-
import "../chunk-
|
|
66
|
-
import
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
import "../chunk-JAU72XNY.js";
|
|
68
|
+
import {
|
|
69
|
+
logExtension
|
|
70
|
+
} from "../chunk-XTMJ7XDT.js";
|
|
71
|
+
import "../chunk-JMYYOTQG.js";
|
|
72
|
+
import "../chunk-QQNQ7SJW.js";
|
|
73
|
+
import "../chunk-AOHZU2BM.js";
|
|
69
74
|
import "../chunk-LJDODBBZ.js";
|
|
70
|
-
import "../chunk-
|
|
75
|
+
import "../chunk-CHOW74WE.js";
|
|
71
76
|
import "../chunk-ABBOA7UD.js";
|
|
72
|
-
import "../chunk-
|
|
77
|
+
import "../chunk-N2H3ZPZY.js";
|
|
73
78
|
import "../chunk-NXL4FFQQ.js";
|
|
74
79
|
|
|
75
80
|
// dist/mcp/worker.js
|
|
@@ -79,6 +84,12 @@ function arg(name) {
|
|
|
79
84
|
return found ? found.slice(prefix.length) : void 0;
|
|
80
85
|
}
|
|
81
86
|
async function main() {
|
|
87
|
+
setProjectTrustState("trusted");
|
|
88
|
+
logExtension({
|
|
89
|
+
subsystem: "project-trust",
|
|
90
|
+
level: "debug",
|
|
91
|
+
message: "mcp-worker: workspace trust belongs to the MCP client; pi trust not consulted"
|
|
92
|
+
});
|
|
82
93
|
const file = arg("file");
|
|
83
94
|
const cwd = arg("cwd") ?? process.cwd();
|
|
84
95
|
if (!file) {
|
package/dist/probes/installer.js
CHANGED
|
@@ -53,30 +53,31 @@ import {
|
|
|
53
53
|
verifyNpmPackageEntry,
|
|
54
54
|
verifyToolBinary,
|
|
55
55
|
wasLastResolveTransient
|
|
56
|
-
} from "../chunk-
|
|
57
|
-
import "../chunk-
|
|
58
|
-
import "../chunk-
|
|
59
|
-
import "../chunk-
|
|
60
|
-
import "../chunk-
|
|
61
|
-
import "../chunk-
|
|
62
|
-
import "../chunk-
|
|
63
|
-
import "../chunk-
|
|
64
|
-
import "../chunk-
|
|
65
|
-
import "../chunk-
|
|
66
|
-
import "../chunk-VN2AXLEX.js";
|
|
56
|
+
} from "../chunk-66VMUL7Q.js";
|
|
57
|
+
import "../chunk-Q7DUK4LX.js";
|
|
58
|
+
import "../chunk-AW7R2GWG.js";
|
|
59
|
+
import "../chunk-RWWYJ623.js";
|
|
60
|
+
import "../chunk-VRZP76YM.js";
|
|
61
|
+
import "../chunk-QOBUHWHX.js";
|
|
62
|
+
import "../chunk-QILIYSJF.js";
|
|
63
|
+
import "../chunk-6C7JWPCP.js";
|
|
64
|
+
import "../chunk-5NGR67U5.js";
|
|
65
|
+
import "../chunk-C34ZXZ7O.js";
|
|
67
66
|
import "../chunk-BW5KFIQC.js";
|
|
68
67
|
import "../chunk-QYF5S6P6.js";
|
|
69
|
-
import "../chunk-
|
|
70
|
-
import "../chunk-
|
|
71
|
-
import "../chunk-
|
|
68
|
+
import "../chunk-PHDMFAKM.js";
|
|
69
|
+
import "../chunk-2BBLFX75.js";
|
|
70
|
+
import "../chunk-XVF2VVXP.js";
|
|
71
|
+
import "../chunk-ZANLILYD.js";
|
|
72
72
|
import "../chunk-2EECBNC5.js";
|
|
73
|
-
import "../chunk-
|
|
74
|
-
import "../chunk-
|
|
75
|
-
import "../chunk-
|
|
76
|
-
import "../chunk-
|
|
73
|
+
import "../chunk-JAU72XNY.js";
|
|
74
|
+
import "../chunk-XTMJ7XDT.js";
|
|
75
|
+
import "../chunk-JMYYOTQG.js";
|
|
76
|
+
import "../chunk-QQNQ7SJW.js";
|
|
77
|
+
import "../chunk-AOHZU2BM.js";
|
|
77
78
|
import "../chunk-LJDODBBZ.js";
|
|
78
79
|
import "../chunk-ABBOA7UD.js";
|
|
79
|
-
import "../chunk-
|
|
80
|
+
import "../chunk-N2H3ZPZY.js";
|
|
80
81
|
import "../chunk-NXL4FFQQ.js";
|
|
81
82
|
export {
|
|
82
83
|
GITHUB_TOOLS,
|
|
@@ -231,7 +231,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
|
|
|
231
231
|
| `prefer-structured-clone-js` | warning | no | pi-lens | Use structuredClone() instead of JSON.parse(JSON.stringify()) for deep cloning |
|
|
232
232
|
| `strict-equality-js` | warning | yes | pi-lens | Use === instead of == |
|
|
233
233
|
| `strict-inequality-js` | warning | yes | pi-lens | Use !== instead of != |
|
|
234
|
-
| `throw-new-error-js` |
|
|
234
|
+
| `throw-new-error-js` | warning | no | pi-lens | Use new Error() not Error() — explicit construction is clearer |
|
|
235
235
|
| `unchecked-throwing-call-js` | error | no | pi-lens | $CALL without try/catch — throws on invalid input |
|
|
236
236
|
| `weak-rsa-key-js` | error | no | pi-lens | Weak RSA key size — use at least 2048 bits |
|
|
237
237
|
|
|
@@ -547,7 +547,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
|
|
|
547
547
|
| `strict-equality` | warning | yes | pi-lens | Use === instead of == |
|
|
548
548
|
| `strict-inequality` | warning | yes | pi-lens | Use !== instead of != |
|
|
549
549
|
| `switch-without-default` | warning | no | pi-lens | switch has no default clause — values matching no case are silently ignored; add a default (even one that throws) |
|
|
550
|
-
| `throw-new-error` |
|
|
550
|
+
| `throw-new-error` | warning | no | pi-lens | Use new Error() not Error() — explicit construction is clearer |
|
|
551
551
|
| `ts-array-concat-spread` | warning | no | pi-lens | arr.concat([...items]) - use arr.push(...items) or [...arr, ...items] |
|
|
552
552
|
| `ts-array-every-some` | warning | no | pi-lens | arr.map(x => x.prop).every(Boolean) - use arr.every(x => !!x.prop) |
|
|
553
553
|
| `ts-boolean-return-if-else` | warning | no | pi-lens | if/else returning true/false - simplify to return the condition directly |
|
package/docs/astplayground.md
CHANGED
|
@@ -17,7 +17,7 @@ The shipped rule set runs in two engines:
|
|
|
17
17
|
|
|
18
18
|
| Path | Engine | Source |
|
|
19
19
|
|------|--------|--------|
|
|
20
|
-
| ast-grep LSP (the live path) | upstream binary, auto-installed by `ensureTool` | the binary's `ast-grep` version may be ahead of
|
|
20
|
+
| ast-grep LSP (the live path) | upstream binary, auto-installed by `ensureTool` | the binary's `ast-grep` version may be ahead of the npm `@ast-grep/cli` version |
|
|
21
21
|
| ast-grep napi runner (fallback) | `@ast-grep/napi` npm package, version-pinned in `package.json` | can lag the binary by a release |
|
|
22
22
|
|
|
23
23
|
The CLI test in `tests/clients/dispatch/runners/ast-grep-catalog-rules.test.ts`
|
package/docs/configuration.md
CHANGED
|
@@ -10,6 +10,21 @@ There are **two** pi-lens config files:
|
|
|
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.
|
|
12
12
|
|
|
13
|
+
Executable LSP fields from a project config are admitted only when pi has
|
|
14
|
+
marked the project trusted. This includes custom `command` values, command
|
|
15
|
+
overrides, `env`, and `initializationOptions`; an untrusted or older host is
|
|
16
|
+
fail-closed and emits one bounded notice telling you to mark the project
|
|
17
|
+
trusted in pi or upgrade pi. Global config remains trusted, and a project can
|
|
18
|
+
always disable a server. pi-lens does not maintain a second trust setting.
|
|
19
|
+
|
|
20
|
+
The editor-facing JSON Schema is published at
|
|
21
|
+
[`docs/schema/pi-lens-config-v1.json`](schema/pi-lens-config-v1.json). LSP
|
|
22
|
+
server entries also accept canonical argv arrays, optional `name` (defaulting
|
|
23
|
+
to the map id), `enabled`, `role` (`language` or `auxiliary`), `args`, and
|
|
24
|
+
`rootMarkers`. These new fields are experimental; reserved role, root-policy,
|
|
25
|
+
and timing semantics are inert until their planned catalog slices land, so this
|
|
26
|
+
schema slice does not change server launch behavior.
|
|
27
|
+
|
|
13
28
|
```jsonc
|
|
14
29
|
{
|
|
15
30
|
"$schema": "https://raw.githubusercontent.com/apmantza/pi-lens/master/docs/schema/pi-lens-config-v1.json",
|
|
@@ -23,8 +38,7 @@ everything LSP-related lives under an `lsp` namespace inside them.
|
|
|
23
38
|
"my-server": {
|
|
24
39
|
"name": "My Custom LSP",
|
|
25
40
|
"extensions": [".myext"],
|
|
26
|
-
"command": "my-lsp-server",
|
|
27
|
-
"args": ["--stdio"],
|
|
41
|
+
"command": ["my-lsp-server", "--stdio"],
|
|
28
42
|
"covers": ["shellcheck"]
|
|
29
43
|
}
|
|
30
44
|
},
|
|
@@ -37,6 +51,10 @@ everything LSP-related lives under an `lsp` namespace inside them.
|
|
|
37
51
|
}
|
|
38
52
|
```
|
|
39
53
|
|
|
54
|
+
An override may also provide an experimental launcher `command` and `env`.
|
|
55
|
+
The built-in server ID and strategy remain in force; only the launcher is
|
|
56
|
+
replaced, and project-sourced launcher fields follow the same pi trust gate.
|
|
57
|
+
|
|
40
58
|
Each model-facing tool accepts `tools.<name>.enabled` in the config file. Valid
|
|
41
59
|
names include `ast_grep_search`, `ast_grep_replace`, `ast_grep_outline`,
|
|
42
60
|
`lsp_navigation`, `lens_diagnostics`,
|
|
@@ -46,6 +64,24 @@ names include `ast_grep_search`, `ast_grep_replace`, `ast_grep_outline`,
|
|
|
46
64
|
lifecycle tools `session_start`, `turn_end`, and `session_end` remain enabled
|
|
47
65
|
because their host protocols require them.
|
|
48
66
|
|
|
67
|
+
To see the resolved tool surface, use `/lens-health`; the `effective_config`
|
|
68
|
+
tool provides the full configuration provenance. Bundled skills are managed by
|
|
69
|
+
pi's package-manifest filters.
|
|
70
|
+
|
|
71
|
+
### Session-start orientation
|
|
72
|
+
|
|
73
|
+
The session-start orientation names only the tools pi-lens actually registered.
|
|
74
|
+
A tool disabled with `tools.<name>.enabled: false` is never advertised, so the
|
|
75
|
+
orientation cannot direct the agent to a tool it cannot call. The tool roster is
|
|
76
|
+
the same registry that drives registration; there is no second list.
|
|
77
|
+
|
|
78
|
+
`contextInjection.requirePreExistingFixes` (default `true`) controls one
|
|
79
|
+
sentence in that orientation: whether pre-existing blocking errors must be
|
|
80
|
+
fixed. Set it to `false` when the task's scope excludes pre-existing debt. The
|
|
81
|
+
orientation then requires fixes only for blocking errors the agent's own edits
|
|
82
|
+
introduce; pre-existing ones are reported, not demanded. It is a global setting,
|
|
83
|
+
like every `contextInjection` key.
|
|
84
|
+
|
|
49
85
|
### `lsp.servers.<id>.covers` — declaring which runners a custom server subsumes
|
|
50
86
|
|
|
51
87
|
A custom server entry accepts an optional `covers` array naming dispatch
|
package/docs/custom-rules.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Custom Rules
|
|
2
2
|
|
|
3
|
-
pi-lens picks up project-local rules automatically alongside its built-ins.
|
|
3
|
+
pi-lens picks up project-local and user-level rules automatically alongside its built-ins.
|
|
4
4
|
Drop YAML files in the right directory and they are active on the next file dispatch — no config required.
|
|
5
5
|
|
|
6
6
|
> For the full list of bundled rules per language, see the generated catalogs:
|
|
@@ -20,7 +20,30 @@ your-project/
|
|
|
20
20
|
my-rule.yml ← ast-grep rule, overrides built-in with same id
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Both rule families are fingerprinted by relative path and contents, so in-place edits, renames, additions, and removals are picked up without a restart, even when mtimes are preserved.
|
|
24
|
+
|
|
25
|
+
### When an edit takes effect
|
|
26
|
+
|
|
27
|
+
A per-file dispatch reads the rule corpus fresh every time: its cache key is a
|
|
28
|
+
content fingerprint of every rule file the language's rule set is built from,
|
|
29
|
+
so an edit, addition, or removal is live on the next dispatched file.
|
|
30
|
+
|
|
31
|
+
Whole-project surfaces — a project scan and a structural search — reuse a
|
|
32
|
+
corpus fingerprint computed once per turn, so a rule edit lands on the next
|
|
33
|
+
turn, or immediately if any file is dispatched in between (a dispatch
|
|
34
|
+
republishes the fresh fingerprint for the rest of that turn). This is what
|
|
35
|
+
keeps a warm scan at the cost of a string comparison instead of re-reading
|
|
36
|
+
every rule file on every call.
|
|
37
|
+
|
|
38
|
+
### User-level rules
|
|
39
|
+
|
|
40
|
+
Rules shared across projects live under the relocatable machine-data directory:
|
|
41
|
+
`<PI_LENS_HOME>/rules/` (or the platform default pi-lens directory when
|
|
42
|
+
`PI_LENS_HOME` is unset). Use the same `tree-sitter-queries/` and
|
|
43
|
+
`ast-grep-rules/` layout shown above. Precedence is project > user > bundled;
|
|
44
|
+
when rule IDs collide, the higher tier wins and the lower definition is
|
|
45
|
+
shadowed from execution. User rules are part of the same fingerprints as
|
|
46
|
+
project rules, so they follow the same timing above.
|
|
24
47
|
|
|
25
48
|
---
|
|
26
49
|
|
package/docs/dependencies.md
CHANGED
|
@@ -28,6 +28,7 @@ Auto-install behavior depends on gate type:
|
|
|
28
28
|
| `shellcheck` | Shell script linting | Yes | GitHub release |
|
|
29
29
|
| `shfmt` | Shell script formatting | Yes | GitHub release |
|
|
30
30
|
| `rust-analyzer` | Rust LSP | Yes | GitHub release |
|
|
31
|
+
| `lake serve` | Lean 4 LSP | No | `lake` must be on PATH; uses the project's Lean toolchain |
|
|
31
32
|
| `golangci-lint` | Go linting | Yes | GitHub release |
|
|
32
33
|
| `hadolint` | Dockerfile linting | Yes | GitHub release |
|
|
33
34
|
| `ktlint` | Kotlin linting | Yes | GitHub release |
|
|
@@ -51,6 +52,8 @@ Auto-install behavior depends on gate type:
|
|
|
51
52
|
| `trivy` | Dependency-CVE session scan | Auto-install | Explicit opt-in (`trivy.enabled`) |
|
|
52
53
|
| `psscriptanalyzer` | PowerShell linting | Manual | — |
|
|
53
54
|
|
|
55
|
+
Lean LSP is launched as `lake serve` from the detected Lake project root, so elan selects the toolchain from that project's `lean-toolchain` file and Lake supplies its project environment. pi-lens does not install or manage Lean/elan; install Lean and Lake separately and ensure `lake` is on `PATH`.
|
|
56
|
+
|
|
54
57
|
Additional language servers (gopls, ruby-lsp, solargraph, etc.) are auto-detected from PATH or installed via native package managers (`go install`, `gem install`) when their language is detected.
|
|
55
58
|
|
|
56
59
|
## Pip tool installation order
|
|
@@ -104,12 +104,14 @@ without changing the steady-state behaviour of an interactive session.
|
|
|
104
104
|
|
|
105
105
|
### `PI_LENS_STARTUP_SCAN_VERDICT_TTL_MS`
|
|
106
106
|
|
|
107
|
-
How long (ms) a persisted `too-many-source-files`
|
|
108
|
-
trusted before the
|
|
109
|
-
is cached in the project snapshot so repeated `pi -p` runs in
|
|
110
|
-
repo skip the counting walk entirely; a repo that shrinks below
|
|
111
|
-
recovers when the TTL expires.
|
|
112
|
-
|
|
107
|
+
How long (ms) a persisted size-skip startup-scan verdict (`too-many-source-files`
|
|
108
|
+
or `too-many-entries`) is trusted before the project is re-walked (default
|
|
109
|
+
24h). The verdict is cached in the project snapshot so repeated `pi -p` runs in
|
|
110
|
+
a very large repo skip the counting walk entirely; a repo that shrinks below
|
|
111
|
+
the threshold recovers when the TTL expires. The verdict also records the
|
|
112
|
+
bounds that produced it (`maxProjectFiles`, `PI_LENS_STARTUP_SCAN_MAX_ENTRIES`),
|
|
113
|
+
so raising either one invalidates it at once and the next session re-walks.
|
|
114
|
+
Other verdicts use content-based freshness and ignore this setting.
|
|
113
115
|
|
|
114
116
|
## Scale and limits
|
|
115
117
|
|
|
@@ -144,6 +146,24 @@ Minimum wall-clock budget (ms) for every dispatch runner; the effective timeout
|
|
|
144
146
|
is `max(runner budget, floor)`. **Default:** `0` (no floor). Also settable via
|
|
145
147
|
the `dispatch.runnerTimeoutFloorMs` config key, which wins when both are set.
|
|
146
148
|
|
|
149
|
+
### `PI_LENS_WORD_INDEX_MEMO_BACKSTOP_MS`
|
|
150
|
+
|
|
151
|
+
Backstop (ms) for the word index's serialized memo, which is also its
|
|
152
|
+
incremental-serialize cache: it is kept while a run edits (so each per-edit
|
|
153
|
+
persist stays O(dirty tokens)) and released once per run at `agent_settled`.
|
|
154
|
+
The backstop releases it when no persist has refreshed it for this long, for a
|
|
155
|
+
host that never emits `agent_settled` and for a stalled run. It is re-armed by
|
|
156
|
+
every serialize and never keeps the process alive. **Default:** `600000` (10
|
|
157
|
+
minutes). `0`, a negative or a non-numeric value means the default (a backstop
|
|
158
|
+
that fired at once would switch the memo off), and a value above `2147483647`
|
|
159
|
+
(about 24.8 days, Node's largest timer delay) is clamped to it. The default is
|
|
160
|
+
deliberately conservative: the maintainer's
|
|
161
|
+
`latency.log` held only two intra-run gaps between `project_snapshot_persist`
|
|
162
|
+
records (5.8 s), too few to derive a percentile. A release leaves one
|
|
163
|
+
`word_index_memo_released` row in `latency.log` (`trigger`: `settle`,
|
|
164
|
+
`post_settle_persist` or `backstop`). Releasing costs the next persist a full
|
|
165
|
+
re-serialize.
|
|
166
|
+
|
|
147
167
|
## Install control
|
|
148
168
|
|
|
149
169
|
### `PI_LENS_DISABLE_LSP_INSTALL`
|
|
@@ -268,6 +288,14 @@ nightly measurement behind each declaration, is in
|
|
|
268
288
|
When unset or invalid, `PI_LENS_TS_IDLE_EVICT_MS` (below) is read.
|
|
269
289
|
**Default:** 20 minutes (`1200000`).
|
|
270
290
|
|
|
291
|
+
### `PI_LENS_EPHEMERAL_LSP_IDLE_EVICT_MS`
|
|
292
|
+
|
|
293
|
+
Idle window (ms) for language-service clients whose workspace is inside a
|
|
294
|
+
temporary or ephemeral Git checkout. This overrides the shared window above
|
|
295
|
+
for those roots; when unset or invalid, the default is 60 seconds (`60000`).
|
|
296
|
+
The nightly idle-eviction measurement temporarily sets this variable alongside
|
|
297
|
+
`PI_LENS_LSP_IDLE_EVICT_MS` so both root policies are measured.
|
|
298
|
+
|
|
271
299
|
### `PI_LENS_TS_IDLE_EVICT_MS`
|
|
272
300
|
|
|
273
301
|
The original, TypeScript-named spelling of the same window, retained for
|
package/docs/features.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
### LSP Support
|
|
4
4
|
|
|
5
|
-
pi-lens includes **
|
|
5
|
+
pi-lens includes **49 language server definitions** (including four cross-cutting *auxiliary* scanners that attach alongside the file's language server — Opengrep, ast-grep, zizmor, and typos — see below). LSP is **enabled by default**; use `--no-lsp` to disable it for a session. Servers are auto-discovered from PATH, project `node_modules`, and managed installs. When a server with a managed installer is not installed, pi-lens offers an interactive install prompt; toolchain-bundled servers, such as Lean's `lake`, are PATH-only, and pi-lens never installs or manages them.
|
|
6
6
|
|
|
7
7
|
**LSP Idle Management:** LSP servers shut down after 240 seconds of inactivity (no files modified) to free resources. The timer resets when you resume editing, preventing cold-start penalties during active development.
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ pi-lens includes **48 language server definitions** (including four cross-cuttin
|
|
|
19
19
|
- **`capabilities`** — shows which operations are supported by the active LSP server(s) for a file, read directly from the cached `initialize` response (no round-trip).
|
|
20
20
|
- **Symbol column resolution** — passing `symbol: "myFunc"` instead of an exact `character` position resolves the correct column automatically. Use `symbol: "foo#2"` for the second occurrence of `foo` on the line.
|
|
21
21
|
|
|
22
|
-
LSP servers for: TypeScript, Deno, Python (pyright/basedpyright + jedi), Go, Rust, Ruby (ruby-lsp + solargraph), PHP, PowerShell, C# (omnisharp), F#, Java (JDT LS, with Lombok javaagent support when a Lombok jar is available), Kotlin, Swift, Dart, Lua, C/C++, Zig, Haskell, Elixir, Gleam, Typst (tinymist), Markdown (marksman), OCaml, Clojure, CUE (syntax and parse diagnostics; evaluation errors via the cue-vet auxiliary runner), Terraform, Nix, Bash, Shuck (zsh-aware shell language server), Fish, CMake, Docker, YAML, JSON, HTML, TOML, Prisma, Vue, Svelte, CSS.
|
|
22
|
+
LSP servers for: TypeScript, Deno, Python (pyright/basedpyright + jedi), Go, Rust, Ruby (ruby-lsp + solargraph), PHP, PowerShell, C# (omnisharp), F#, Java (JDT LS, with Lombok javaagent support when a Lombok jar is available), Kotlin, Lean, Swift, Dart, Lua, C/C++, Zig, Haskell, Elixir, Gleam, Typst (tinymist), Markdown (marksman), OCaml, Clojure, CUE (syntax and parse diagnostics; evaluation errors via the cue-vet auxiliary runner), Terraform, Nix, Bash, Shuck (zsh-aware shell language server), Fish, CMake, Docker, YAML, JSON, HTML, TOML, Prisma, Vue, Svelte, CSS.
|
|
23
23
|
|
|
24
24
|
### Formatters
|
|
25
25
|
|
|
@@ -183,7 +183,7 @@ pi-lens MCP server expose the same shape to Claude Code / any MCP client.
|
|
|
183
183
|
|
|
184
184
|
At `turn_end`, pi-lens writes `<project-data-dir>/cache/actionable-warnings.json` summarizing fixable warnings introduced by the current turn. This powers the optional conservative autofix at `agent_end`.
|
|
185
185
|
|
|
186
|
-
`<project-data-dir>` is whatever `getProjectDataDir(cwd)` resolves to: `<project>/.pi-lens` only when that legacy directory already exists, otherwise `~/.pi-lens/projects/<project-slug>` (or a `PILENS_DATA_DIR` location). The turn-end advisory points at `lens_diagnostics mode=delta` first and names the resolved file second, so you never have to work the layout out by hand (#2521).
|
|
186
|
+
`<project-data-dir>` is whatever `getProjectDataDir(cwd)` resolves to: `<project>/.pi-lens` only when that legacy directory already exists when the process first resolves the root (a `.pi-lens` created mid-process takes effect at the next process start), otherwise `~/.pi-lens/projects/<project-slug>` (or a `PILENS_DATA_DIR` location). The turn-end advisory points at `lens_diagnostics mode=delta` first and names the resolved file second, so you never have to work the layout out by hand (#2521).
|
|
187
187
|
|
|
188
188
|
**Report contents:**
|
|
189
189
|
|
|
@@ -234,6 +234,42 @@ One event per logical write batch (not per file) — e.g. a single eslint `--fix
|
|
|
234
234
|
|
|
235
235
|
**Kill switch:** `PI_LENS_BUS_PUBLISH=0` disables publishing entirely (see `docs/environment-variables.md`). Publishing is fire-and-forget — a disabled/unavailable/throwing bus never affects the write path's own success or latency.
|
|
236
236
|
|
|
237
|
+
### Bus Events — `pilens:format:*` (#673)
|
|
238
|
+
|
|
239
|
+
Deferred formatting has a separate lifecycle on the same `pi.events` bus:
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
pilens:format:queued { v: 1, source: "pi-lens", filePath, cwd, tool, kinds,
|
|
243
|
+
ownerSessionId?, turnIndex?, batchId? }
|
|
244
|
+
pilens:format:start { v: 1, source: "pi-lens", cwd, paths, fileCount, kinds,
|
|
245
|
+
ownerSessionId?, turnIndex?, batchId? }
|
|
246
|
+
pilens:format:done { v: 1, source: "pi-lens", cwd, paths, fileCount, kinds,
|
|
247
|
+
ownerSessionId?, turnIndex?, batchId?, settled? }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Paths and `cwd` are absolute, normalized strings. `queued` is emitted when a
|
|
251
|
+
file first enters the deferred queue; `start` is emitted when a non-empty
|
|
252
|
+
claimed format batch begins; and `done` is emitted after all formatters in that
|
|
253
|
+
batch and any late-write resyncs have settled. `paths: []` on `done` means the
|
|
254
|
+
batch changed no bytes. `batchId` is process-unique and monotonic across
|
|
255
|
+
coordinator generations, so
|
|
256
|
+
two same-millisecond reloads cannot share a lifecycle identity. A normal
|
|
257
|
+
`pilens:format:done` has `settled: true` (or omits the additive field for old
|
|
258
|
+
producers). If the formatter remains unsettled after the bounded hook/format
|
|
259
|
+
drain, pi-lens emits one terminal `pilens:format:done` with `settled: false`
|
|
260
|
+
and the still-pending paths, and records one `deferred-format-unsettled`
|
|
261
|
+
degradation for that batch. A later formatter write is resynced by the late
|
|
262
|
+
continuation and does not emit a second done event.
|
|
263
|
+
The session and turn fields let a listener match the lifecycle to its own
|
|
264
|
+
session and turn; consumers must not infer ownership from paths or timing.
|
|
265
|
+
|
|
266
|
+
These are visibility events, not a flush API. They are fire-and-forget and can
|
|
267
|
+
be absent when the bus is disabled, unwired, stale, or throws. Replaced-session
|
|
268
|
+
and aborted drains publish only for work they actually claim and finish; work
|
|
269
|
+
requeued for its owner is not
|
|
270
|
+
announced as done by the replacing session. The events are additive v1 schemas
|
|
271
|
+
and may gain optional fields without a version bump.
|
|
272
|
+
|
|
237
273
|
**Fix provenance (#502):** `FilesTouchedPayload` gained an additive, optional `fixes` field so a diff/review consumer can distinguish a pi-lens-mechanical hunk from an agent edit:
|
|
238
274
|
|
|
239
275
|
```
|
package/docs/globalconfig.md
CHANGED
|
@@ -112,6 +112,8 @@ Hide the diagnostics widget by default, run formatting immediately after write/e
|
|
|
112
112
|
|
|
113
113
|
`contextInjection.enabled` (default `true`) controls whether pi-lens prepends automatic findings — session-start guidance, turn-end findings, and test findings — into the next model turn. Set it to `false` (or use `--no-lens-context` / `PI_LENS_NO_CONTEXT_INJECTION=1` / `/lens-context-toggle`) to keep tools, LSP, read-guard, and formatting running while avoiding the prompt-cache invalidation that injected messages cause in long, cache-sensitive sessions. Findings are still cached, so `lens_diagnostics` and `/lens-health` keep working.
|
|
114
114
|
|
|
115
|
+
`contextInjection.requirePreExistingFixes` (default `true`) controls whether the session-start orientation tells the agent to fix pre-existing blocking errors; set `false` to scope that demand to errors its own edits introduce.
|
|
116
|
+
|
|
115
117
|
`actionableWarnings.enabled` gates the turn_end report. `includeLspCodeActions` fetches LSP code actions for each warning (requires an active language server). `deltaOnly` (default `true`) limits the report to lines touched in the current turn. `autoFix.enabled` applies conservative LSP quickfixes at `agent_end`; `autoFix.maxFixes` caps the number applied per turn (default `5`, must be a non-negative whole number). `maxFixes: 0` keeps the report and applies nothing, which is a useful halfway step before enabling `autoFix` for real. Unlike the toggles in the table above there is no CLI counterpart, since it takes a number rather than being on or off.
|
|
116
118
|
|
|
117
119
|
`turnEnd.madge.enabled` (default `false`) runs the per-turn-end madge circular-dependency check on import-changed files. It is off by default because that pass only writes debug output — user-facing madge diagnostics come from the session-start scan cache and the `lens_diagnostics` extractor — and its subprocess spawns dominated the turn-end latency tail (#766). Enable it with `--lens-turn-end-madge` or `turnEnd.madge.enabled: true` if you want the per-edit circular-dependency note.
|
|
@@ -263,7 +265,7 @@ not corrupt delta baselines.
|
|
|
263
265
|
|
|
264
266
|
### `maxProjectFiles`
|
|
265
267
|
|
|
266
|
-
Single scale knob (default `2000`) that a large-but-healthy repo can raise to scale five independent size budgets together instead of tripping each one separately: the project-diagnostics scanner (0.25×, default 500 files), the review graph (0.5× up to a point, default 1,000 files — see below), the startup scan (1×, default 2,
|
|
268
|
+
Single scale knob (default `2000`) that a large-but-healthy repo can raise to scale five independent size budgets together instead of tripping each one separately: the project-diagnostics scanner (0.25×, default 500 files), the review graph (0.5× up to a point, default 1,000 files — see below), the startup scan (1.25×, default 2,500 source files), jscpd (3×, default 6,000 directory entries), and the word index (3×, default 6,000 files). Raising it (e.g. to `5000`) scales all five proportionally. Each subsystem's own environment-variable override (e.g. `PI_LENS_REVIEW_GRAPH_MAX_FILES`, `PI_LENS_STARTUP_SCAN_MAX_ENTRIES`) still takes precedence over this knob when set, and a separate `PI_LENS_MAX_PROJECT_FILES` environment variable sits below `maxProjectFiles` but above the built-in default. See `clients/project-scale.ts` for the full ratio table and precedence order.
|
|
267
269
|
|
|
268
270
|
Unlike the other four, the review graph's budget stops scaling flatly at 0.5× once `maxProjectFiles` climbs past 4,000 — it tapers toward a 5,000-file ceiling instead of growing unbounded (#775). Its higher per-file cold-build cost bounds this default file budget independently of the graph's disk-persist circuit-breaker, whose measured default is now 500,000 elements (#936; override with `PI_LENS_GRAPH_PERSIST_MAX_ELEMENTS`). An over-cap graph persists a centrality-ranked partial snapshot with explicit total-versus-persisted coverage; read-only orientation may use it, but incremental builds never reuse it as a complete base. Below the 4,000 threshold (which covers every typical/default-sized project) it's the same flat 0.5× ratio as before. See `reviewGraph.maxFiles` below for an explicit opt-in past the taper.
|
|
269
271
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Language Coverage
|
|
2
2
|
|
|
3
|
-
pi-lens supports **
|
|
3
|
+
pi-lens supports **37+ languages** through dispatch runners and LSP integration.
|
|
4
4
|
|
|
5
5
|
Formatting uses a single selected formatter per file: explicit project config wins, otherwise pi-lens uses a smart default where supported, and config-first ecosystems do not autoformat without config.
|
|
6
6
|
|
|
@@ -33,6 +33,7 @@ Dispatch is diagnostics-oriented: automatic formatting and safe autofix happen i
|
|
|
33
33
|
| Java | ✓ | lsp, javac | google-java-format |
|
|
34
34
|
| Java + Lombok | ✓ | JDT LS launched with `-javaagent:<lombok.jar>` when Lombok is detected and a jar is found (`PI_LENS_LOMBOK_JAR` / `LOMBOK_JAR`, project `.lombok/lombok.jar`, or Maven/Gradle cache) | google-java-format |
|
|
35
35
|
| Kotlin | ✓ | lsp, ktlint, detekt | ktlint |
|
|
36
|
+
| Lean 4 | ✓ (Lake `serve`) | lsp; uses each project's Lake toolchain and environment | — |
|
|
36
37
|
| Swift | ✓ | lsp, swiftlint | swiftformat |
|
|
37
38
|
| Dart | ✓ | lsp, dart-analyze | dart format |
|
|
38
39
|
| Lua | ✓ | lsp | stylua |
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# LSP capability matrix — affirmative-clean-signal strategy
|
|
2
2
|
|
|
3
|
+
## Project-code trust class (#4269)
|
|
4
|
+
|
|
5
|
+
Some global language-server binaries execute repository-owned build, plugin, or
|
|
6
|
+
macro code while starting or indexing. The built-in registry marks these with
|
|
7
|
+
`executesProjectCode`; the launch gate refuses them unless pi reports the
|
|
8
|
+
project as trusted. Unknown trust is a `spawn-failed` refusal, not
|
|
9
|
+
`tool-not-found`, and does not install or retry the server. The class currently
|
|
10
|
+
includes rust-analyzer (Cargo `build.rs` and proc macros), Ruby LSP
|
|
11
|
+
(Bundler/Gemfile composed-bundle setup), PowerShell Editor Services (workspace
|
|
12
|
+
modules), C# / F# servers (MSBuild targets), JDT LS and Kotlin (Gradle/Maven),
|
|
13
|
+
SourceKit-LSP (SwiftPM plugins), Haskell Language Server (Cabal/Stack and
|
|
14
|
+
Template Haskell), ElixirLS / Expert (`mix compile`), and the project-configured
|
|
15
|
+
analysis servers whose startup evaluates workspace configuration: Dart, ZLS,
|
|
16
|
+
OCaml, Clojure, Terraform, Nix, CMake, Vue, and Svelte. Lean is tracked by
|
|
17
|
+
#4122 and will declare itself when that change lands. gopls is excluded: its
|
|
18
|
+
startup/index discovery uses `go list`; cgo is not compiled by gopls startup.
|
|
19
|
+
|
|
3
20
|
How pi-lens knows a just-edited file is **clean** (no diagnostics) vs the server
|
|
4
21
|
simply **hasn't answered yet** (cold/crashed/silent). pi-lens waits *synchronously*
|
|
5
22
|
for a verdict, so — unlike an editor, which renders asynchronously and never needs
|
|
@@ -68,8 +85,10 @@ discriminator either.
|
|
|
68
85
|
|
|
69
86
|
`tests/config/lsp-first-publish-census.test.ts` compares this column against the
|
|
70
87
|
`emptyFirstPublish` markers and reds in BOTH directions, which is the expiry
|
|
71
|
-
check: when
|
|
72
|
-
refresh
|
|
88
|
+
check: when two consecutive nights re-measure a server into a different class,
|
|
89
|
+
the docs refresh commits the confirmed class and the marker must move with it.
|
|
90
|
+
A single-night flip remains in the refresh-state JSON below and does not change
|
|
91
|
+
the census's confirmed population.
|
|
73
92
|
|
|
74
93
|
## The strategies
|
|
75
94
|
|
|
@@ -148,7 +167,7 @@ carries the named admission until then.
|
|
|
148
167
|
| deno | deno (alt of typescript) | pull | — | n/a (pull) | 1 | dev+ci |
|
|
149
168
|
| ruby | ruby-lsp | pull | — | n/a (pull) | 1 | ci |
|
|
150
169
|
| csharp | csharp-ls | pull | — | n/a (pull) | 1 | ci |
|
|
151
|
-
| typescript | typescript-language-server | push-only | silent |
|
|
170
|
+
| typescript | typescript-language-server | push-only | silent | empty-first | 3 | dev+ci |
|
|
152
171
|
| markdown | marksman | push-only | silent | direct | 3 | ci |
|
|
153
172
|
| lua | lua-language-server | push-only | silent | direct | 3 | dev+ci |
|
|
154
173
|
| python | pyright | push-only | publishes-versioned | direct | 2 | dev+ci |
|
|
@@ -156,6 +175,7 @@ carries the named admission until then.
|
|
|
156
175
|
| yaml | yaml-language-server | push-only | publishes-unversioned | direct | 2* | dev+ci |
|
|
157
176
|
| shell | bash-language-server | push-only | publishes-versioned | direct | 2 | dev+ci |
|
|
158
177
|
| dockerfile | docker-langserver | push-only | publishes-unversioned | direct | 2* | dev+ci |
|
|
178
|
+
| dockerfile-official | docker-language-server (official) | push-only | publishes-versioned | direct | 2 | dev+ci |
|
|
159
179
|
| toml | taplo | push-only | publishes-unversioned | direct | 2* | dev+ci |
|
|
160
180
|
| terraform | terraform-ls | push-only | publishes-unversioned | empty-first | 2* | dev+ci |
|
|
161
181
|
| prisma | @prisma/language-server | push-only | publishes-unversioned | direct | 2* | dev+ci |
|
|
@@ -210,6 +230,9 @@ and were characterized `push-only` in the run above).
|
|
|
210
230
|
`first-publish` measurements on the dev box, 2026-09-23: php `empty-first`,
|
|
211
231
|
typescript / opengrep / ast-grep / marksman `direct` (so the class does not
|
|
212
232
|
extend to them on the measurement, whatever their comments suggest).
|
|
233
|
+
- The official Docker row's clean-gate witness requires the BuildKit-backed
|
|
234
|
+
`JSONArgsRecommended` rule and skips when `docker buildx` is unavailable;
|
|
235
|
+
its first-publish class is the nightly's measured `direct`.
|
|
213
236
|
- **#458's learned-deadline target set = the tier-3 rows only.** 2\* rows resolve
|
|
214
237
|
the wait at runtime and must NOT be given learned deadlines.
|
|
215
238
|
- **Tier 3 is budget-bound by necessity**, not laziness: a silent server's silence is
|
|
@@ -255,10 +278,10 @@ _None observed as of the last probe run._
|
|
|
255
278
|
|
|
256
279
|
## Capability matrix refresh state (nightly-generated)
|
|
257
280
|
|
|
258
|
-
Bookkeeping for the
|
|
259
|
-
|
|
281
|
+
Bookkeeping for the two-run `first-publish`/`clean-behavior` hysteresis, the
|
|
282
|
+
date-based `direct` expiry (#3401) and consecutive-night `idle-eviction`
|
|
260
283
|
counts (#3989). Regenerated every run; never a measurement.
|
|
261
284
|
|
|
262
285
|
```json
|
|
263
|
-
{"
|
|
286
|
+
{"first-publish":{"dockerfile":{"firstMissed":"2026-10-10"},"prisma":{"firstMissed":"2026-10-10"},"python":{"firstMissed":"2026-10-10"},"shell":{"firstMissed":"2026-10-10"},"terraform":{"pendingFirstPublish":"direct","runs":1},"yaml":{"firstMissed":"2026-10-10"}}}
|
|
264
287
|
```
|