pi-lens 4.4.2 → 4.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +306 -0
- package/README.md +13 -1
- package/dist/{chunk-VITUCP5A.js → chunk-24AKHFGP.js} +9 -7
- package/dist/{chunk-JSQFTSC6.js → chunk-2FN63LPV.js} +11 -11
- package/dist/{chunk-CF24OIYI.js → chunk-2KXTHF3M.js} +20 -20
- package/dist/{chunk-ESBQHFMJ.js → chunk-3DA2JDOL.js} +543 -349
- package/dist/{chunk-RWWYJ623.js → chunk-3KAZU3VR.js} +1 -1
- package/dist/chunk-3PTHXJXR.js +28 -0
- package/dist/chunk-3QED2P4V.js +31 -0
- package/dist/{chunk-N2H3ZPZY.js → chunk-3RKP3FMS.js} +1 -0
- package/dist/{chunk-XVF2VVXP.js → chunk-5HSRT26B.js} +2 -2
- package/dist/{chunk-XKIZ2HNN.js → chunk-5IUSNGOC.js} +18 -16
- package/dist/{chunk-EJIUXPBX.js → chunk-5OFV52AM.js} +1 -1
- package/dist/{chunk-AW7R2GWG.js → chunk-5VSF4UUQ.js} +12 -7
- package/dist/{chunk-NW7BOILN.js → chunk-5WRPDP2A.js} +18 -18
- package/dist/{chunk-7ULNCDCO.js → chunk-6DLWKFEX.js} +35 -34
- package/dist/{chunk-WOA4LN2R.js → chunk-7D6L4MTX.js} +2 -2
- package/dist/{chunk-GAEGEPOC.js → chunk-7HXE67BN.js} +2 -2
- package/dist/chunk-AGSS7277.js +84 -0
- package/dist/{chunk-R3PCY3YS.js → chunk-AMERCH6V.js} +13 -13
- package/dist/{chunk-WU567RSC.js → chunk-ATKJFDQN.js} +14 -10
- package/dist/{chunk-VSSBEUFT.js → chunk-AWSCPCN2.js} +16 -16
- package/dist/{chunk-VCHXCQFG.js → chunk-BWD5EPKO.js} +3 -3
- package/dist/{chunk-ODBNXWT4.js → chunk-CT4MN5IU.js} +1271 -262
- package/dist/{chunk-34WSVGEM.js → chunk-CUHSHSB6.js} +83 -5
- package/dist/{chunk-CHOW74WE.js → chunk-CYRKQRPM.js} +7 -10
- package/dist/{chunk-Q7DUK4LX.js → chunk-DEL2U6CM.js} +5 -5
- package/dist/{chunk-6C7JWPCP.js → chunk-DGUKIYSI.js} +26 -23
- package/dist/{chunk-PHDMFAKM.js → chunk-DUO2TU77.js} +2 -2
- package/dist/{chunk-MRXKYPCS.js → chunk-EBC36LNN.js} +2 -2
- package/dist/chunk-ED36RF6Y.js +17 -0
- package/dist/{chunk-76MWC2K6.js → chunk-EUXZEFTV.js} +90 -97
- package/dist/{chunk-QOZXJ4NA.js → chunk-FM4RDMKT.js} +11 -8
- package/dist/{chunk-66VMUL7Q.js → chunk-GAQ7OQG6.js} +31 -28
- package/dist/{chunk-Q6ZWTCLY.js → chunk-GL5LUMZE.js} +23 -24
- package/dist/{chunk-BKE7E7TC.js → chunk-GMX5OS7B.js} +9 -9
- package/dist/{chunk-ZHFZWTZV.js → chunk-GSLNCYGG.js} +11 -11
- package/dist/{chunk-ARJ6PLFH.js → chunk-GSM5UU7A.js} +26 -34
- package/dist/{chunk-724UL2TJ.js → chunk-GXFV6MYU.js} +3 -3
- package/dist/chunk-HAD7QRQI.js +30 -0
- package/dist/{chunk-QOBUHWHX.js → chunk-HRNHZA3N.js} +6 -6
- package/dist/{chunk-VWCXW2E7.js → chunk-HWCCCQNX.js} +1 -1
- package/dist/{chunk-7DYBLXYA.js → chunk-HYGZEMX6.js} +3 -3
- package/dist/chunk-IJYGIDF4.js +186 -0
- package/dist/{chunk-4W4VLAPJ.js → chunk-IQWN5JCP.js} +11 -11
- package/dist/{chunk-GZYBXISR.js → chunk-IUE7SSKV.js} +9 -9
- package/dist/{chunk-IBGIOBEE.js → chunk-IWDLU6K3.js} +68 -5
- package/dist/{chunk-XCJN5IJU.js → chunk-IYNJ6YPZ.js} +4 -4
- package/dist/{chunk-JAU72XNY.js → chunk-J64T55EI.js} +3 -3
- package/dist/{chunk-2BBLFX75.js → chunk-J6MPGQTS.js} +5 -5
- package/dist/chunk-JORED7EX.js +44 -0
- package/dist/{chunk-6SDEP3AJ.js → chunk-JUKMK5Y4.js} +8 -8
- package/dist/{chunk-IBRALRBR.js → chunk-JW3YWBVB.js} +15 -14
- package/dist/{chunk-L3BLXZG7.js → chunk-KAPJINKN.js} +30 -69
- package/dist/{chunk-2B73ZPOK.js → chunk-KN35K52N.js} +3 -3
- package/dist/{chunk-C34ZXZ7O.js → chunk-KUA4OJ5Y.js} +24 -11
- package/dist/chunk-KYUB6QDC.js +72 -0
- package/dist/{chunk-67WMNWEE.js → chunk-LLJNQKQW.js} +12 -10
- package/dist/chunk-LZSEQW6A.js +57 -0
- package/dist/{chunk-ZANLILYD.js → chunk-M2IFVFWU.js} +2 -2
- package/dist/chunk-M2UD3LPU.js +88 -0
- package/dist/{chunk-WOKKRCJ5.js → chunk-MBKQHGA7.js} +15 -14
- package/dist/{chunk-P7266HLM.js → chunk-MPNJLASA.js} +2 -2
- package/dist/{chunk-6GFRNVYR.js → chunk-MZGQNL3Y.js} +10 -10
- package/dist/{chunk-QZVW3AAK.js → chunk-N5FLEO7W.js} +33 -31
- package/dist/{chunk-3JNKMP3B.js → chunk-O4NWQT6I.js} +4 -4
- package/dist/{chunk-PFNSLWU5.js → chunk-OHKJ7PQF.js} +33 -31
- package/dist/{chunk-VRZP76YM.js → chunk-P63GXC37.js} +4 -1
- package/dist/{chunk-XTMJ7XDT.js → chunk-POMLXPMY.js} +1 -1
- package/dist/{chunk-QQNQ7SJW.js → chunk-QBFBRV2B.js} +10 -4
- package/dist/{chunk-3UUPUE3O.js → chunk-R3T7CLQ2.js} +84 -60
- package/dist/{chunk-23WOO7TX.js → chunk-R7YOCSNV.js} +10 -10
- package/dist/{chunk-2CD5RS6M.js → chunk-RKBXZN3A.js} +23 -2
- package/dist/{chunk-OG5UUPN7.js → chunk-RKKOYPRA.js} +14 -14
- package/dist/{chunk-52FUZI6K.js → chunk-RMLC67LF.js} +1 -1
- package/dist/{chunk-XMSXXAHW.js → chunk-ROYSX2S5.js} +2 -2
- package/dist/{chunk-PV6LR5P5.js → chunk-RVK72CZX.js} +9605 -14776
- package/dist/{chunk-FLKWCIZH.js → chunk-S2HEXIWI.js} +5 -5
- package/dist/{chunk-UZ3TUTRV.js → chunk-S67KYG37.js} +1 -1
- package/dist/{chunk-JWA5I3SR.js → chunk-SD4I7ZO4.js} +16 -18
- package/dist/{chunk-Z527N6YQ.js → chunk-SKAMFC7A.js} +12 -12
- package/dist/{chunk-MQLUAEOC.js → chunk-SRYEJNES.js} +2 -2
- package/dist/{chunk-BRGDSBJE.js → chunk-SYE6T2EB.js} +12 -12
- package/dist/{chunk-GXW6K4YJ.js → chunk-T57LYLZT.js} +1 -1
- package/dist/{chunk-ZXYDQ3TZ.js → chunk-T7FEBKXN.js} +48 -15
- package/dist/{chunk-IXXDFY73.js → chunk-TIQ2PKDW.js} +3 -3
- package/dist/{chunk-QILIYSJF.js → chunk-TLX72JTG.js} +1 -1
- package/dist/{chunk-TYM6OUIT.js → chunk-TOY6QKOH.js} +12 -12
- package/dist/{chunk-IZSHAIJ7.js → chunk-TRETHTQO.js} +12 -12
- package/dist/{chunk-3VPVG5SU.js → chunk-U44DJXQP.js} +10 -6
- package/dist/{chunk-PNQDPDRC.js → chunk-UA7ZXYDR.js} +1 -1
- package/dist/{chunk-OXXKQCSV.js → chunk-UBOQLVT2.js} +4 -4
- package/dist/{chunk-QGQ5CCCG.js → chunk-UMS2MFPZ.js} +2 -2
- package/dist/{chunk-QHJ6DQ2R.js → chunk-US7ECLD7.js} +55 -13
- package/dist/{chunk-EETY4LF7.js → chunk-UZ2XCLYS.js} +8 -8
- package/dist/chunk-V35JG4JB.js +2667 -0
- package/dist/{chunk-N3X6Q4YT.js → chunk-VOOAPROD.js} +3 -3
- package/dist/{chunk-SAEFPSB6.js → chunk-W66O5E25.js} +21 -11
- package/dist/{chunk-KBG47GHP.js → chunk-WMYE35PX.js} +15 -11
- package/dist/{chunk-5NGR67U5.js → chunk-XBJVAEEO.js} +32 -5
- package/dist/chunk-XHJBS436.js +4217 -0
- package/dist/{chunk-GBPP5P7X.js → chunk-XTBDCR27.js} +4 -4
- package/dist/{chunk-4UNXBNE2.js → chunk-XTFDJI3T.js} +11 -11
- package/dist/{chunk-UXGETRP4.js → chunk-XYURS6EN.js} +13 -12
- package/dist/{chunk-RPLINGVB.js → chunk-Y6GZHWSJ.js} +6 -6
- package/dist/{chunk-2ZGIZPDG.js → chunk-YCWYO6TQ.js} +41 -38
- package/dist/{chunk-66SXUJCA.js → chunk-YH5MVY2U.js} +10 -8
- package/dist/{chunk-AOHZU2BM.js → chunk-YNE3RP52.js} +1 -1
- package/dist/{chunk-GOYRYZ2R.js → chunk-ZHH37KZL.js} +72 -20
- package/dist/{chunk-ZGDGW2V3.js → chunk-ZIVJBOO3.js} +2 -2
- package/dist/{chunk-GHB6AYCP.js → chunk-ZVUL7QYY.js} +29 -28
- package/dist/index.js +11559 -6213
- package/dist/mcp/analyze-cli.js +10 -9
- package/dist/mcp/cli.js +41 -38
- package/dist/mcp/server.js +1142 -495
- package/dist/mcp/worker.js +61 -57
- package/dist/probes/installer.js +19 -19
- package/dist/workers/project-snapshot-persist-worker.js +28 -9
- package/dist/workers/review-graph-persist-worker.js +1 -1
- package/docs/configuration.md +11 -0
- package/docs/engineering-principles.md +32 -0
- package/docs/lsp-capability-matrix.md +1 -1
- package/docs/lsp-idle-eviction.md +15 -26
- package/docs/pi-lens-fixer.md +117 -13
- package/docs/pi-lens-merge-policy.md +109 -11
- package/docs/pi-lens-monitor.md +8 -2
- package/docs/pi-lens-retro.md +4 -1
- package/docs/pi-lens-reviewer.md +114 -3
- package/docs/pi-lens-subagent.md +27 -14
- package/docs/release-qa-baseline.md +3 -1
- package/docs/servercapabilities.md +9 -19
- package/package.json +7 -5
- package/scripts/download-grammars.js +40 -7
- package/scripts/lib/latency-log-phases.mjs +95 -0
- package/scripts/rpc-load-check.mjs +570 -81
- package/dist/chunk-3WA4HP4I.js +0 -55
- package/dist/chunk-466Z26MG.js +0 -30
- package/dist/chunk-5JM2524W.js +0 -84
- package/dist/chunk-CO2G5PHH.js +0 -84
- package/dist/chunk-LOP6GRPH.js +0 -31
- package/dist/chunk-UOPVJQ4N.js +0 -103
- package/dist/chunk-XPZPXCBV.js +0 -28
- /package/dist/{chunk-FC4RP4I2.js → chunk-6HWVI6MI.js} +0 -0
|
@@ -6,7 +6,7 @@ server's `initialize` handshake. Generated by `node scripts/server-capabilities.
|
|
|
6
6
|
absent on the generating host are listed under *Unavailable* — run in a
|
|
7
7
|
provisioned environment (the nightly) to capture those rows.
|
|
8
8
|
|
|
9
|
-
_Last generated: 2026-10-
|
|
9
|
+
_Last generated: 2026-10-18 on linux; 41 servers captured, 9 unavailable._
|
|
10
10
|
|
|
11
11
|
## Diagnostic mode + navigation/edit operations
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ Legend: ✓ advertised, · not. **mode** = document diagnostics (`pull` = `textD
|
|
|
16
16
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
17
17
|
| ast-grep | push-only | · | · | · | · | · | · | ✓ | · | · | · | ✓ | · | · | · | 1 |
|
|
18
18
|
| bash | push-only | · | · | ✓ | · | · | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | · | · | 0 |
|
|
19
|
-
| clojure | push-only | · | save+text | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
19
|
+
| clojure | push-only | · | save+text | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 64 |
|
|
20
20
|
| cmake | push-only | · | save | · | · | · | · | ✓ | · | · | · | · | · | · | · | 0 |
|
|
21
21
|
| cpp | push-only | · | save | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 3 |
|
|
22
22
|
| csharp | pull | ✓ | save+text | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 0 |
|
|
@@ -31,7 +31,7 @@ Legend: ✓ advertised, · not. **mode** = document diagnostics (`pull` = `textD
|
|
|
31
31
|
| fish | push-only | · | save+text | ✓ | · | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | · | 23 |
|
|
32
32
|
| fsharp | push-only | · | save+text | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 0 |
|
|
33
33
|
| gleam | push-only | · | save | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | · | ✓ | ✓ | · | · | 0 |
|
|
34
|
-
| go | push-only | · | save | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
34
|
+
| go | push-only | · | save | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 50 |
|
|
35
35
|
| html | pull | · | · | ✓ | · | · | ✓ | ✓ | ✓ | ✓ | · | · | ✓ | · | · | 0 |
|
|
36
36
|
| json | pull | · | · | · | · | · | · | ✓ | · | ✓ | · | ✓ | · | · | · | 0 |
|
|
37
37
|
| kotlin | push-only | · | · | ✓ | · | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | · | · | 1 |
|
|
@@ -58,6 +58,9 @@ Legend: ✓ advertised, · not. **mode** = document diagnostics (`pull` = `textD
|
|
|
58
58
|
|
|
59
59
|
## Raw advertised capability keys
|
|
60
60
|
|
|
61
|
+
Top-level keys of each server's `ServerCapabilities` — the full advertised
|
|
62
|
+
surface, including providers pi-lens does not yet consume.
|
|
63
|
+
|
|
61
64
|
- **ast-grep**: codeActionProvider, executeCommandProvider, hoverProvider, textDocumentSync
|
|
62
65
|
- **bash**: codeActionProvider, completionProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentSymbolProvider, hoverProvider, referencesProvider, renameProvider, textDocumentSync, workspaceSymbolProvider
|
|
63
66
|
- **clojure**: callHierarchyProvider, codeActionProvider, codeLensProvider, completionProvider, declarationProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentRangeFormattingProvider, documentSymbolProvider, executeCommandProvider, experimental, foldingRangeProvider, hoverProvider, implementationProvider, linkedEditingRangeProvider, referencesProvider, renameProvider, selectionRangeProvider, semanticTokensProvider, signatureHelpProvider, textDocumentSync, workspace, workspaceSymbolProvider
|
|
@@ -99,14 +102,11 @@ Legend: ✓ advertised, · not. **mode** = document diagnostics (`pull` = `textD
|
|
|
99
102
|
- **yaml**: codeActionProvider, codeLensProvider, completionProvider, definitionProvider, documentFormattingProvider, documentLinkProvider, documentOnTypeFormattingProvider, documentRangeFormattingProvider, documentSymbolProvider, executeCommandProvider, foldingRangeProvider, hoverProvider, renameProvider, selectionRangeProvider, textDocumentSync, workspace
|
|
100
103
|
- **zig**: codeActionProvider, colorProvider, completionProvider, declarationProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentRangeFormattingProvider, documentSymbolProvider, foldingRangeProvider, hoverProvider, implementationProvider, inlayHintProvider, positionEncoding, referencesProvider, renameProvider, selectionRangeProvider, semanticTokensProvider, signatureHelpProvider, textDocumentSync, typeDefinitionProvider, workspace, workspaceSymbolProvider
|
|
101
104
|
- **zizmor**: textDocumentSync
|
|
102
|
-
Top-level keys of each server's `ServerCapabilities` — the full advertised
|
|
103
|
-
surface, including providers pi-lens does not yet consume.
|
|
104
|
-
|
|
105
105
|
|
|
106
106
|
## Advertised executeCommand allowlists
|
|
107
107
|
|
|
108
108
|
- **ast-grep** (1): ast-grep.applyAllFixes
|
|
109
|
-
- **clojure** (
|
|
109
|
+
- **clojure** (64): add-import-to-namespace, add-missing-import, add-missing-libspec, add-require-suggestion, as-to-refer, backward, backward-barf, backward-select, backward-slurp, change-coll, clean-ns, cond->if-refactor, create-function, create-test, cursor-info, cycle-coll, cycle-keyword-auto-resolve, cycle-namespaced-map, cycle-privacy, demote-fn, destructure-keys, drag-backward, drag-forward, drag-param-backward, drag-param-forward, expand-let, extract-function, extract-to-def, forward, forward-barf, forward-select, forward-slurp, get-in-all, get-in-less, get-in-more, get-in-none, if->cond-refactor, inline-function, inline-symbol, introduce-let, …
|
|
110
110
|
- **cpp** (3): clangd.applyFix, clangd.applyRename, clangd.applyTweak
|
|
111
111
|
- **cue** (1): cuelsp.externalvalidate
|
|
112
112
|
- **dart** (18): dart.edit.codeAction.apply, dart.edit.fixAll, dart.edit.fixAllInWorkspace, dart.edit.fixAllInWorkspace.preview, dart.edit.organizeImports, dart.edit.sendWorkspaceEdit, dart.edit.sortMembers, dart.logAction, dart.refactor.add_constructor_name, dart.refactor.convert_all_formal_parameters_to_named, dart.refactor.convert_selected_formal_parameters_to_named, dart.refactor.move_selected_formal_parameters_left, dart.refactor.move_top_level_to_file, dart.refactor.remove_constructor_name, dart.refactor.remove_import_prefix, dart.refactor_add.import_prefix, refactor.perform, refactor.validate
|
|
@@ -115,7 +115,7 @@ surface, including providers pi-lens does not yet consume.
|
|
|
115
115
|
- **emmylua** (4): fake.applyEdit, fake.applyEditDeferred, fake.doThing, fake.releaseDeferredApplyEdit
|
|
116
116
|
- **expert** (2): Reindex, connectionDetails
|
|
117
117
|
- **fish** (23): fish-lsp.checkHealth, fish-lsp.createTheme, fish-lsp.execute, fish-lsp.executeBuffer, fish-lsp.executeLine, fish-lsp.executeRange, fish-lsp.fixAll, fish-lsp.generateEnvVariables, fish-lsp.selectQuickFixPosition, fish-lsp.showEnvVariables, fish-lsp.showInfo, fish-lsp.showReferences, fish-lsp.showStatusDocs, fish-lsp.showWorkspaceMessage, fish-lsp.toggleSingleWorkspaceSupport, fish-lsp.updateWorkspace, quickfix.delete, quickfix.disable, quickfix.fix, quickfix.fixAll, refactor.extract, refactor.rewrite, source.rename
|
|
118
|
-
- **go** (
|
|
118
|
+
- **go** (50): gopls.add_dependency, gopls.add_import, gopls.add_telemetry_counters, gopls.add_test, gopls.apply_fix, gopls.assembly, gopls.change_signature, gopls.check_upgrades, gopls.client_open_url, gopls.diagnose_files, gopls.doc, gopls.dragon_slayer, gopls.edit_go_directive, gopls.extract_to_new_file, gopls.fetch_vulncheck_result, gopls.free_symbols, gopls.gc_details, gopls.generate, gopls.go_get_package, gopls.implement_interface, gopls.list_imports, gopls.list_known_packages, gopls.lsp, gopls.maybe_prompt_for_telemetry, gopls.mem_stats, gopls.modify_tags, gopls.modules, gopls.move_declaration, gopls.move_type, gopls.package_symbols, gopls.packages, gopls.regenerate_cgo, gopls.remove_dependency, gopls.reset_go_mod_diagnostics, gopls.resolve_target, gopls.run_go_work_command, gopls.run_govulncheck, gopls.run_tests, gopls.scan_imports, gopls.split_package, …
|
|
119
119
|
- **kotlin** (1): convertJavaToKotlin
|
|
120
120
|
- **lua** (6): lua.autoRequire, lua.getConfig, lua.jsonToLua, lua.removeSpace, lua.setConfig, lua.solve
|
|
121
121
|
- **opengrep** (2): semgrep/autofix, semgrep/ignore
|
|
@@ -130,22 +130,12 @@ surface, including providers pi-lens does not yet consume.
|
|
|
130
130
|
Toolchain/binary not installed here, so capabilities weren't captured
|
|
131
131
|
(many are the toolchain-gated family tracked in #241):
|
|
132
132
|
|
|
133
|
-
- @prisma/language-server
|
|
134
|
-
- @vue/language-server
|
|
135
|
-
- bash-language-server
|
|
136
133
|
- elixir-ls
|
|
137
|
-
- fake custom lua server
|
|
138
|
-
- fish-lsp
|
|
139
134
|
- haskell-language-server
|
|
140
|
-
- intelephense
|
|
141
135
|
- jdtls
|
|
142
136
|
- jdtls + lombok javaagent
|
|
137
|
+
- lake serve (Lean 4)
|
|
143
138
|
- nixd
|
|
144
139
|
- ocamllsp
|
|
145
|
-
- pyright
|
|
146
140
|
- shuck
|
|
147
141
|
- sourcekit-lsp
|
|
148
|
-
- svelte-language-server
|
|
149
|
-
- vscode-css-language-server
|
|
150
|
-
- vscode-html-language-server
|
|
151
|
-
- yaml-language-server
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lens",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo",
|
|
6
6
|
"repository": {
|
|
@@ -20,10 +20,11 @@
|
|
|
20
20
|
"prepare": "npm run build:dist && node scripts/download-grammars.js --core --dest grammars && node scripts/setup-git-hooks.mjs && node scripts/stamp-package-lock.mjs && node scripts/warm-loader-cache.mjs",
|
|
21
21
|
"prepack": "node scripts/strip-dev-deps-for-pack.mjs --strip",
|
|
22
22
|
"postpack": "node scripts/strip-dev-deps-for-pack.mjs --restore",
|
|
23
|
-
"lint": "tsc --project tsconfig.json && npm run lint:js && npm run lint:js:tests",
|
|
23
|
+
"lint": "tsc --project tsconfig.json && npm run lint:js && npm run lint:js:tests && npm run lint:js:promises",
|
|
24
24
|
"lint:js": "oxlint --deny-warnings --import-plugin --promise-plugin -D block-scoped-var -D import/default -D import/namespace -D import/no-absolute-path -D import/no-empty-named-blocks -D import/no-named-as-default -D import/no-self-import -D no-extend-native -D no-extra-bind -D no-implied-eval -D no-new -D no-unexpected-multiline -D no-useless-constructor -D oxc/approx-constant -D oxc/misrefactored-assign-op -D oxc/no-accumulating-spread -D oxc/no-async-endpoint-handlers -D oxc/no-this-in-exported-function -D promise/no-callback-in-promise -D promise/no-multiple-resolved -D promise/no-new-statics -D promise/valid-params -D typescript/no-confusing-non-null-assertion -D typescript/no-extraneous-class -D typescript/no-unnecessary-type-constraint -D typescript/no-unsafe-enum-comparison -D unicorn/no-accessor-recursion -D unicorn/no-array-fill-with-reference-type -D unicorn/no-confusing-array-with -D unicorn/no-instanceof-builtins -D unicorn/prefer-array-flat-map -D unicorn/require-module-specifiers --ignore-pattern \"tests/**/*.ts\" --ignore-pattern \"tests/**/*.tsx\" --ignore-pattern \"**/*.d.mts\" --ignore-pattern \"tests/fixtures/autofix-smoke/**\" --ignore-pattern \"tests/fixtures/format-smoke/**\" --ignore-pattern \"tests/fixtures/tool-smoke/**\" --ignore-pattern \"tests/fixtures/call-graph/javascript/**\" --ignore-pattern \"tests/fixtures/function-facts/javascript-parameter.js\" .",
|
|
25
25
|
"lint:js:advisory": "node scripts/lint-js-advisory.mjs --deny-warnings --format unix -D correctness -D suspicious -D perf --import-plugin --promise-plugin --type-aware -A no-underscore-dangle -A no-await-in-loop -A unicorn/no-array-sort -A unicorn/consistent-function-scoping -A promise/no-promise-in-callback -A no-useless-call -A import/no-unassigned-import -A no-unmodified-loop-condition --ignore-pattern \"**/*.d.mts\" --ignore-pattern \"tests/fixtures/autofix-smoke/**\" --ignore-pattern \"tests/fixtures/format-smoke/**\" --ignore-pattern \"tests/fixtures/tool-smoke/**\" --ignore-pattern \"tests/fixtures/call-graph/javascript/**\" --ignore-pattern \"tests/fixtures/function-facts/javascript-parameter.js\" .",
|
|
26
26
|
"lint:js:tests": "node scripts/lint-js-advisory.mjs --deny-warnings --format unix --type-aware -A correctness -A suspicious -A perf --ignore-pattern \"tests/fixtures/**\" tests",
|
|
27
|
+
"lint:js:promises": "node scripts/lint-js-advisory.mjs --deny-warnings --format unix --type-aware -A all -D typescript/await-thenable -D typescript/no-floating-promises -D typescript/no-misused-promises clients mcp tools index.ts",
|
|
27
28
|
"depcruise:check": "depcruise --validate --config .dependency-cruiser.cjs --ignore-known .dependency-cruiser-known-violations.json --output-type err index.ts \"clients/**/*.ts\"",
|
|
28
29
|
"fmt": "oxfmt",
|
|
29
30
|
"fmt:check": "oxfmt --check",
|
|
@@ -113,6 +114,7 @@
|
|
|
113
114
|
"scripts/analyze-pi-lens-logs.mjs",
|
|
114
115
|
"scripts/install-selftest.mjs",
|
|
115
116
|
"scripts/lib/host-provided-deps.mjs",
|
|
117
|
+
"scripts/lib/latency-log-phases.mjs",
|
|
116
118
|
"scripts/lib/skills-predicate.mjs",
|
|
117
119
|
"scripts/lib/web-tree-sitter-dir.mjs",
|
|
118
120
|
"scripts/lib/warm-loader-cache.mjs",
|
|
@@ -124,8 +126,8 @@
|
|
|
124
126
|
"banner.png"
|
|
125
127
|
],
|
|
126
128
|
"dependencies": {
|
|
127
|
-
"@ast-grep/cli": "0.
|
|
128
|
-
"@ast-grep/napi": "^0.
|
|
129
|
+
"@ast-grep/cli": "0.50.0",
|
|
130
|
+
"@ast-grep/napi": "^0.50.0",
|
|
129
131
|
"js-yaml": "^5.2.2",
|
|
130
132
|
"minimatch": "^10.2.6",
|
|
131
133
|
"pidusage": "^4.0.1",
|
|
@@ -160,7 +162,7 @@
|
|
|
160
162
|
]
|
|
161
163
|
},
|
|
162
164
|
"allowScripts": {
|
|
163
|
-
"@ast-grep/cli@0.
|
|
165
|
+
"@ast-grep/cli@0.50.0": true,
|
|
164
166
|
"@google/genai@2.21.0": true,
|
|
165
167
|
"esbuild@0.28.2": true,
|
|
166
168
|
"fsevents@2.3.3": false,
|
|
@@ -172,11 +172,44 @@ function baseUrl(version) {
|
|
|
172
172
|
function grammarUrl(version, filename) {
|
|
173
173
|
return SOURCE_OVERRIDES[filename]?.url ?? `${baseUrl(version)}/${filename}`;
|
|
174
174
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Abort a fetch that receives no bytes for this long, headers included; each
|
|
177
|
+
* chunk restarts the count, so a slow link that keeps delivering completes.
|
|
178
|
+
* Mirrors `GRAMMAR_STALL_MS` in clients/grammar-source.ts, which this script
|
|
179
|
+
* cannot import before the TS build; `tests/clients/grammar-source.test.ts`
|
|
180
|
+
* pins the two together (#4425).
|
|
181
|
+
*/
|
|
182
|
+
export const GRAMMAR_STALL_MS = 15_000;
|
|
183
|
+
async function fetchGrammar(version, filename, stallMs = GRAMMAR_STALL_MS) {
|
|
184
|
+
const controller = new AbortController();
|
|
185
|
+
const timer = setTimeout(() => controller.abort(), stallMs);
|
|
186
|
+
try {
|
|
187
|
+
const res = await fetch(grammarUrl(version, filename), {
|
|
188
|
+
signal: controller.signal,
|
|
189
|
+
});
|
|
190
|
+
if (!res.ok)
|
|
191
|
+
throw new Error(`HTTP ${res.status} fetching ${filename}`);
|
|
192
|
+
const reader = res.body?.getReader();
|
|
193
|
+
if (!reader)
|
|
194
|
+
return Buffer.from(await res.arrayBuffer());
|
|
195
|
+
const chunks = [];
|
|
196
|
+
for (;;) {
|
|
197
|
+
const { done, value } = await reader.read();
|
|
198
|
+
if (done)
|
|
199
|
+
return Buffer.concat(chunks);
|
|
200
|
+
timer.refresh();
|
|
201
|
+
chunks.push(value);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
if (controller.signal.aborted) {
|
|
206
|
+
throw new Error(`no bytes arrived for ${stallMs} ms fetching ${filename}`);
|
|
207
|
+
}
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
clearTimeout(timer);
|
|
212
|
+
}
|
|
180
213
|
}
|
|
181
214
|
/**
|
|
182
215
|
* Download `filename` into `destDir` (if it isn't already verified), checking its
|
|
@@ -184,12 +217,12 @@ async function fetchGrammar(version, filename) {
|
|
|
184
217
|
* integrity mismatch — a grammar whose bytes don't match the pinned manifest is
|
|
185
218
|
* never written (guards CDN corruption / tampering / ABI drift).
|
|
186
219
|
*/
|
|
187
|
-
async function downloadGrammar(destDir, filename, manifest) {
|
|
220
|
+
export async function downloadGrammar(destDir, filename, manifest, stallMs = GRAMMAR_STALL_MS) {
|
|
188
221
|
if (!needsDownload(destDir, filename, manifest)) {
|
|
189
222
|
console.error(` skip ${filename} (verified)`);
|
|
190
223
|
return;
|
|
191
224
|
}
|
|
192
|
-
const buf = await fetchGrammar(manifest.version, filename);
|
|
225
|
+
const buf = await fetchGrammar(manifest.version, filename, stallMs);
|
|
193
226
|
const actual = sha256(buf);
|
|
194
227
|
const expected = manifest.grammars[filename];
|
|
195
228
|
if (expected && actual !== expected) {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Pure NDJSON latency-log phase parsing for scripts/compat-smoke-behavioral.mjs
|
|
2
|
+
// (#476, Layer B).
|
|
3
|
+
//
|
|
4
|
+
// `clients/latency-logger.ts` writes one JSON object per line to
|
|
5
|
+
// `~/.pi-lens/latency.log` (see `createNdjsonLogger`). Layer B launches real
|
|
6
|
+
// `pi` processes and needs to assert (or assert the ABSENCE of) specific
|
|
7
|
+
// `type: "phase"` entries that landed during a bounded time window — this
|
|
8
|
+
// module is the pure parsing/filtering half, kept separate from the
|
|
9
|
+
// file-reading/process-spawning orchestration so it is unit-testable without
|
|
10
|
+
// touching the filesystem or spawning anything.
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Parse NDJSON text into an array of entries. Malformed lines (partial write,
|
|
14
|
+
* truncation mid-append) are skipped rather than throwing — the log is
|
|
15
|
+
* best-effort by construction (ndjson-logger.ts swallows write errors), so a
|
|
16
|
+
* single bad line must never abort the whole read.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} text raw latency.log contents
|
|
19
|
+
* @returns {Array<Record<string, unknown>>}
|
|
20
|
+
*/
|
|
21
|
+
export function parseNdjsonEntries(text) {
|
|
22
|
+
const entries = [];
|
|
23
|
+
for (const line of text.split(/\r?\n/)) {
|
|
24
|
+
const trimmed = line.trim();
|
|
25
|
+
if (!trimmed) continue;
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(trimmed);
|
|
28
|
+
if (parsed && typeof parsed === "object") entries.push(parsed);
|
|
29
|
+
} catch {
|
|
30
|
+
// partial/corrupt line — skip
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return entries;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Filter entries to `type: "phase"` records with the given `phase` name,
|
|
38
|
+
* optionally restricted to entries whose `ts` (ISO timestamp) falls at or
|
|
39
|
+
* after `sinceIso`. Used to scope a check to "phases logged by THIS run" when
|
|
40
|
+
* the log file is long-lived and shared across sessions.
|
|
41
|
+
*
|
|
42
|
+
* @param {Array<Record<string, unknown>>} entries
|
|
43
|
+
* @param {string} phase
|
|
44
|
+
* @param {string} [sinceIso] ISO timestamp lower bound (inclusive)
|
|
45
|
+
*/
|
|
46
|
+
export function findPhaseEntries(entries, phase, sinceIso) {
|
|
47
|
+
const sinceMs = sinceIso ? Date.parse(sinceIso) : undefined;
|
|
48
|
+
return entries.filter((e) => {
|
|
49
|
+
if (e.type !== "phase" || e.phase !== phase) return false;
|
|
50
|
+
if (sinceMs === undefined) return true;
|
|
51
|
+
const ts = typeof e.ts === "string" ? Date.parse(e.ts) : Number.NaN;
|
|
52
|
+
return Number.isFinite(ts) && ts >= sinceMs;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* True iff at least one `findPhaseEntries` match exists.
|
|
58
|
+
*
|
|
59
|
+
* @param {Array<Record<string, unknown>>} entries
|
|
60
|
+
* @param {string} phase
|
|
61
|
+
* @param {string} [sinceIso]
|
|
62
|
+
*/
|
|
63
|
+
export function phaseWasLogged(entries, phase, sinceIso) {
|
|
64
|
+
return findPhaseEntries(entries, phase, sinceIso).length > 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* True iff NO phase in `phases` was logged since `sinceIso` — used to assert
|
|
69
|
+
* a degraded/skip path did NOT engage (e.g. heavyweight scans must be absent
|
|
70
|
+
* under subagent light mode).
|
|
71
|
+
*
|
|
72
|
+
* @param {Array<Record<string, unknown>>} entries
|
|
73
|
+
* @param {string[]} phases
|
|
74
|
+
* @param {string} [sinceIso]
|
|
75
|
+
*/
|
|
76
|
+
export function noPhasesLogged(entries, phases, sinceIso) {
|
|
77
|
+
return phases.every((phase) => !phaseWasLogged(entries, phase, sinceIso));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Number of entries (any type) whose `ts` falls at or after `sinceIso`.
|
|
82
|
+
* Positive control for the absence assertions: "no heavyweight phase logged"
|
|
83
|
+
* is only evidence when the run wrote SOMETHING to the log the smoke is
|
|
84
|
+
* reading — an empty or mis-located log made those pass vacuously (#2570).
|
|
85
|
+
*
|
|
86
|
+
* @param {Array<Record<string, unknown>>} entries
|
|
87
|
+
* @param {string} sinceIso ISO timestamp lower bound (inclusive)
|
|
88
|
+
*/
|
|
89
|
+
export function countEntriesSince(entries, sinceIso) {
|
|
90
|
+
const sinceMs = Date.parse(sinceIso);
|
|
91
|
+
return entries.filter((e) => {
|
|
92
|
+
const ts = typeof e.ts === "string" ? Date.parse(e.ts) : Number.NaN;
|
|
93
|
+
return Number.isFinite(ts) && ts >= sinceMs;
|
|
94
|
+
}).length;
|
|
95
|
+
}
|