pi-lens 4.4.3 → 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 +281 -0
- package/README.md +13 -1
- package/dist/{chunk-SS36ZX4J.js → chunk-24AKHFGP.js} +6 -6
- package/dist/{chunk-JSQFTSC6.js → chunk-2FN63LPV.js} +11 -11
- package/dist/{chunk-5UCAH366.js → chunk-2KXTHF3M.js} +20 -20
- package/dist/{chunk-EU63SDCG.js → chunk-3DA2JDOL.js} +367 -281
- 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-MXGY6KPT.js → chunk-5IUSNGOC.js} +15 -15
- package/dist/{chunk-EJIUXPBX.js → chunk-5OFV52AM.js} +1 -1
- package/dist/{chunk-AW7R2GWG.js → chunk-5VSF4UUQ.js} +12 -7
- package/dist/{chunk-6STA6Z7I.js → chunk-5WRPDP2A.js} +18 -18
- package/dist/{chunk-YIUAVF7E.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-H6MF6EVN.js → chunk-CT4MN5IU.js} +1200 -230
- package/dist/{chunk-FCSOVF55.js → chunk-CUHSHSB6.js} +6 -6
- 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-CSHFH5IN.js → chunk-ED36RF6Y.js} +1 -1
- package/dist/{chunk-76MWC2K6.js → chunk-EUXZEFTV.js} +90 -97
- package/dist/{chunk-QOZXJ4NA.js → chunk-FM4RDMKT.js} +11 -8
- package/dist/{chunk-ACXEQZOU.js → chunk-GAQ7OQG6.js} +31 -28
- package/dist/{chunk-XAGLWMJ4.js → chunk-GL5LUMZE.js} +23 -23
- package/dist/{chunk-BKE7E7TC.js → chunk-GMX5OS7B.js} +9 -9
- package/dist/{chunk-ZHFZWTZV.js → chunk-GSLNCYGG.js} +11 -11
- package/dist/{chunk-3W7IEVVL.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-SQ4TVJBR.js → chunk-IUE7SSKV.js} +7 -7
- 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-FMSO6RDZ.js → chunk-JW3YWBVB.js} +15 -15
- 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-XIJZVPD5.js → chunk-MBKQHGA7.js} +15 -15
- package/dist/{chunk-P7266HLM.js → chunk-MPNJLASA.js} +2 -2
- package/dist/{chunk-6GFRNVYR.js → chunk-MZGQNL3Y.js} +10 -10
- package/dist/{chunk-ZWFS3OEF.js → chunk-N5FLEO7W.js} +33 -32
- package/dist/{chunk-3JNKMP3B.js → chunk-O4NWQT6I.js} +4 -4
- package/dist/{chunk-T6CPIZNT.js → chunk-OHKJ7PQF.js} +33 -32
- 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-CMMHNUZ2.js → chunk-R3T7CLQ2.js} +60 -38
- package/dist/{chunk-23WOO7TX.js → chunk-R7YOCSNV.js} +10 -10
- package/dist/{chunk-2CD5RS6M.js → chunk-RKBXZN3A.js} +23 -2
- package/dist/{chunk-OCAGUNBC.js → chunk-RKKOYPRA.js} +12 -12
- package/dist/{chunk-52FUZI6K.js → chunk-RMLC67LF.js} +1 -1
- package/dist/{chunk-XMSXXAHW.js → chunk-ROYSX2S5.js} +2 -2
- package/dist/{chunk-M6HSLBWY.js → chunk-RVK72CZX.js} +6507 -7514
- package/dist/{chunk-FLKWCIZH.js → chunk-S2HEXIWI.js} +5 -5
- package/dist/{chunk-UZ3TUTRV.js → chunk-S67KYG37.js} +1 -1
- package/dist/{chunk-VCO24T4L.js → chunk-SD4I7ZO4.js} +14 -14
- 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-3EFKIGZN.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-AB3YYG6N.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-YYOIQFRS.js → chunk-XHJBS436.js} +122 -44
- 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-2VUQMUMT.js → chunk-YCWYO6TQ.js} +41 -38
- package/dist/{chunk-77M37OKR.js → chunk-YH5MVY2U.js} +7 -7
- package/dist/{chunk-AOHZU2BM.js → chunk-YNE3RP52.js} +1 -1
- package/dist/{chunk-YSZNHOBY.js → chunk-ZHH37KZL.js} +12 -12
- package/dist/{chunk-ZGDGW2V3.js → chunk-ZIVJBOO3.js} +2 -2
- package/dist/{chunk-RXCOMYPY.js → chunk-ZVUL7QYY.js} +29 -28
- package/dist/index.js +11052 -5852
- package/dist/mcp/analyze-cli.js +10 -9
- package/dist/mcp/cli.js +41 -38
- package/dist/mcp/server.js +1120 -474
- package/dist/mcp/worker.js +61 -58
- 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 +97 -7
- package/docs/pi-lens-monitor.md +8 -2
- package/docs/pi-lens-retro.md +4 -1
- package/docs/pi-lens-reviewer.md +112 -4
- package/docs/pi-lens-subagent.md +22 -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-3YN6V5TV.js +0 -85
- package/dist/chunk-466Z26MG.js +0 -30
- package/dist/chunk-EC47DWFA.js +0 -56
- package/dist/chunk-KDERNTCQ.js +0 -28
- package/dist/chunk-KSX3TXSZ.js +0 -69
- package/dist/chunk-LOP6GRPH.js +0 -31
- package/dist/chunk-UOPVJQ4N.js +0 -103
- /package/dist/{chunk-FC4RP4I2.js → chunk-6HWVI6MI.js} +0 -0
package/dist/mcp/server.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
GitleaksClient,
|
|
5
|
+
classifyAndFilterFindings
|
|
6
|
+
} from "../chunk-24AKHFGP.js";
|
|
3
7
|
import {
|
|
4
8
|
DEAD_CODE_DELTA_MAX_SHOWN,
|
|
5
9
|
deadCodeIssueCount,
|
|
@@ -7,18 +11,18 @@ import {
|
|
|
7
11
|
deadCodeIssues,
|
|
8
12
|
formatDeadCodeDelta,
|
|
9
13
|
stableFindingKey
|
|
10
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-RKKOYPRA.js";
|
|
11
15
|
import {
|
|
12
16
|
clearFormatterCache
|
|
13
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-GSM5UU7A.js";
|
|
14
18
|
import {
|
|
15
19
|
findNearestProjectRoot,
|
|
16
20
|
isStartupScanVerdictFresh,
|
|
17
21
|
resolveStartupScanContext
|
|
18
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-U44DJXQP.js";
|
|
19
23
|
import {
|
|
20
24
|
loadCallGraph
|
|
21
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-7D6L4MTX.js";
|
|
22
26
|
import {
|
|
23
27
|
isHardFailureSummary
|
|
24
28
|
} from "../chunk-7U2IDNXN.js";
|
|
@@ -27,15 +31,11 @@ import {
|
|
|
27
31
|
formatRunDurationMs,
|
|
28
32
|
isExcludedTestTarget,
|
|
29
33
|
isRunnerErrorResult
|
|
30
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-SD4I7ZO4.js";
|
|
31
35
|
import {
|
|
32
36
|
GovulncheckClient
|
|
33
|
-
} from "../chunk-
|
|
34
|
-
import
|
|
35
|
-
GitleaksClient,
|
|
36
|
-
classifyAndFilterFindings
|
|
37
|
-
} from "../chunk-SS36ZX4J.js";
|
|
38
|
-
import "../chunk-ZGDGW2V3.js";
|
|
37
|
+
} from "../chunk-IUE7SSKV.js";
|
|
38
|
+
import "../chunk-ZIVJBOO3.js";
|
|
39
39
|
import {
|
|
40
40
|
resetManagedToolRefreshSession
|
|
41
41
|
} from "../chunk-UXVNL3D7.js";
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
peekTurnEndFindings,
|
|
54
54
|
snapshotAdvisoryProvenance,
|
|
55
55
|
validateAdvisoryProvenance
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-WMYE35PX.js";
|
|
57
57
|
import {
|
|
58
58
|
CacheManager,
|
|
59
59
|
DELTA_UNUSED_PROMOTION_NOTE,
|
|
@@ -64,21 +64,27 @@ import {
|
|
|
64
64
|
applyFindingPolicy,
|
|
65
65
|
applyLspFindingPolicy,
|
|
66
66
|
applyPushedFindingPolicy,
|
|
67
|
+
applyPushedFindingPolicyByFile,
|
|
67
68
|
applyRulePolicy,
|
|
68
69
|
canHandle,
|
|
69
70
|
cascadeCarrySuffix,
|
|
70
71
|
cascadeSettleWaitMs,
|
|
72
|
+
cascadeStillPresentSince,
|
|
73
|
+
composeCascadeSection,
|
|
71
74
|
convertLspDiagnostics,
|
|
72
75
|
createDispatchContext,
|
|
73
76
|
createMcpHost,
|
|
74
77
|
demoteInferredProjectDiagnostics,
|
|
75
78
|
demoteInferredProjectSweepResults,
|
|
79
|
+
dispositionSuppressedLine,
|
|
76
80
|
drainPendingRunnerFindings,
|
|
77
81
|
dropStaleRunnerFindings,
|
|
78
82
|
evaluateAstGrepRules,
|
|
79
83
|
evaluateRules,
|
|
80
84
|
filterFindingsByDisposition,
|
|
85
|
+
forgetCascadePendingNeighbor,
|
|
81
86
|
formatCacheAgeLabel,
|
|
87
|
+
formatCascadeNeighborDiagnostics,
|
|
82
88
|
formatDiagnostics,
|
|
83
89
|
getAvailableRunners,
|
|
84
90
|
getDiagnosticTracker,
|
|
@@ -86,75 +92,85 @@ import {
|
|
|
86
92
|
getLatencyReports,
|
|
87
93
|
getToolPlan,
|
|
88
94
|
inlineBlockerIdentities,
|
|
95
|
+
laneCopyStandsFor,
|
|
96
|
+
listCascadePendingNeighbors,
|
|
89
97
|
loadProjectRulePolicyMap,
|
|
90
98
|
loadSg,
|
|
91
99
|
logCascade,
|
|
100
|
+
markCascadeUnansweredPrimariesDelivered,
|
|
92
101
|
markUnreconciledFindings,
|
|
93
102
|
normalizeRuleId,
|
|
103
|
+
owedByContentOnly,
|
|
104
|
+
peekOutstandingCascadeTouches,
|
|
94
105
|
pendingRunnerFindingsSize,
|
|
106
|
+
readFileContent,
|
|
107
|
+
recordDeliveredCascadeNeighbor,
|
|
108
|
+
renderCascadeResult,
|
|
95
109
|
requeueRunnerFindings,
|
|
96
110
|
resetCascadeTierSessionState,
|
|
97
111
|
resetDispatchBaselines,
|
|
98
112
|
resetObservedRunnerLatency,
|
|
99
113
|
resetPendingRunnerFindings,
|
|
100
114
|
resetPsScriptAnalyzerAvailability,
|
|
101
|
-
runProviders
|
|
102
|
-
|
|
115
|
+
runProviders,
|
|
116
|
+
stampLineHashes
|
|
117
|
+
} from "../chunk-CT4MN5IU.js";
|
|
103
118
|
import {
|
|
104
119
|
resetLazyInstallAttempts
|
|
105
|
-
} from "../chunk-
|
|
120
|
+
} from "../chunk-UBOQLVT2.js";
|
|
106
121
|
import {
|
|
107
122
|
isTestRoleCollateral
|
|
108
|
-
} from "../chunk-
|
|
123
|
+
} from "../chunk-5OFV52AM.js";
|
|
109
124
|
import {
|
|
110
125
|
findingsResult,
|
|
111
|
-
hasUsableResult
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
import "../chunk-
|
|
126
|
+
hasUsableResult,
|
|
127
|
+
reachedNoVerdict
|
|
128
|
+
} from "../chunk-RKBXZN3A.js";
|
|
129
|
+
import "../chunk-6HWVI6MI.js";
|
|
130
|
+
import "../chunk-S67KYG37.js";
|
|
131
|
+
import "../chunk-KN35K52N.js";
|
|
115
132
|
import {
|
|
116
133
|
resetGoAvailability
|
|
117
|
-
} from "../chunk-
|
|
134
|
+
} from "../chunk-ROYSX2S5.js";
|
|
118
135
|
import {
|
|
119
136
|
TrivyClient
|
|
120
|
-
} from "../chunk-
|
|
121
|
-
import
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
} from "../chunk-YH5MVY2U.js";
|
|
138
|
+
import {
|
|
139
|
+
scannerReportParentDir
|
|
140
|
+
} from "../chunk-ED36RF6Y.js";
|
|
141
|
+
import "../chunk-BWD5EPKO.js";
|
|
142
|
+
import "../chunk-TIQ2PKDW.js";
|
|
124
143
|
import {
|
|
125
144
|
resetRustAvailability
|
|
126
|
-
} from "../chunk-
|
|
127
|
-
import "../chunk-
|
|
128
|
-
import "../chunk-
|
|
145
|
+
} from "../chunk-EBC36LNN.js";
|
|
146
|
+
import "../chunk-HYGZEMX6.js";
|
|
147
|
+
import "../chunk-UZ2XCLYS.js";
|
|
129
148
|
import {
|
|
130
149
|
getSgCommand,
|
|
131
150
|
resetDispatchAvailabilityState,
|
|
132
151
|
resolveManagedToolClient
|
|
133
|
-
} from "../chunk-
|
|
134
|
-
import "../chunk-
|
|
135
|
-
import "../chunk-
|
|
136
|
-
import "../chunk-
|
|
137
|
-
import "../chunk-
|
|
138
|
-
import "../chunk-2B73ZPOK.js";
|
|
152
|
+
} from "../chunk-ZHH37KZL.js";
|
|
153
|
+
import "../chunk-Y6GZHWSJ.js";
|
|
154
|
+
import "../chunk-IYNJ6YPZ.js";
|
|
155
|
+
import "../chunk-EUXZEFTV.js";
|
|
156
|
+
import "../chunk-T57LYLZT.js";
|
|
139
157
|
import {
|
|
140
158
|
SYMBOL_KIND_NAMES,
|
|
141
159
|
captureReviewGraphStructuralIr,
|
|
142
160
|
formatReviewGraphRevisionDriftNote,
|
|
143
161
|
publishReviewGraphFileIr,
|
|
144
162
|
reviewGraphIrContentHash
|
|
145
|
-
} from "../chunk-
|
|
163
|
+
} from "../chunk-XHJBS436.js";
|
|
146
164
|
import {
|
|
147
165
|
buildSymbolId
|
|
148
166
|
} from "../chunk-3MED75HT.js";
|
|
149
167
|
import {
|
|
150
|
-
DEPENDENCY_DRIFT_MAX_DELIVERIES,
|
|
151
168
|
MAX_LATE_AUX_REARMS,
|
|
152
169
|
PAST_EOF_STALE_MARKER,
|
|
153
|
-
|
|
170
|
+
PRIMARY_UNAVAILABLE_CAUSE,
|
|
154
171
|
ReadGuard,
|
|
155
172
|
STALE_LINE_MARKER,
|
|
156
173
|
Text,
|
|
157
|
-
TreeSitterSymbolExtractor,
|
|
158
174
|
WriteOrderingGuard,
|
|
159
175
|
anchorsForDiagnostic,
|
|
160
176
|
applyAuxiliarySuppressions,
|
|
@@ -165,10 +181,12 @@ import {
|
|
|
165
181
|
armDeferredLspWork,
|
|
166
182
|
attemptTsserverSyncDiagnostics,
|
|
167
183
|
beginScope,
|
|
168
|
-
|
|
184
|
+
buildProbeScopeKey,
|
|
169
185
|
canRearmPendingAuxiliary,
|
|
170
186
|
classifyDiagnosticTier,
|
|
171
187
|
clearAllSessions,
|
|
188
|
+
combinePrimaryUnavailableCauses,
|
|
189
|
+
configDisabledAuxiliaryLspServerIds,
|
|
172
190
|
countRetainedSuppressedRows,
|
|
173
191
|
createFileTime,
|
|
174
192
|
createLazyImport,
|
|
@@ -178,7 +196,6 @@ import {
|
|
|
178
196
|
drainPendingAuxCapEvictedCount,
|
|
179
197
|
drainPendingAuxiliaryCoverage,
|
|
180
198
|
drainRenderedDependencyDriftFilePaths,
|
|
181
|
-
exceedsLspSyncLimits,
|
|
182
199
|
findAuxiliaryProfileForSource,
|
|
183
200
|
getActiveSessionId,
|
|
184
201
|
getDisposition,
|
|
@@ -186,11 +203,14 @@ import {
|
|
|
186
203
|
getLSPService,
|
|
187
204
|
getLspBudgetIdleTimeoutMs,
|
|
188
205
|
getMutationBridge,
|
|
206
|
+
getSuppressedDiagnostics,
|
|
189
207
|
getWidgetBlockingFilesForSweep,
|
|
208
|
+
goPackageFilesToAnnounce,
|
|
190
209
|
groupFilesByPrimaryServer,
|
|
191
210
|
hasAnyDispositionMarks,
|
|
192
211
|
hasStrictDispositionMarks,
|
|
193
212
|
hashDiagnosticContent,
|
|
213
|
+
importTargetsToAnnounce,
|
|
194
214
|
incrementWidgetDependencyDriftDelivery,
|
|
195
215
|
isAuxBacklogPublished,
|
|
196
216
|
isBlocking,
|
|
@@ -202,6 +222,7 @@ import {
|
|
|
202
222
|
newLspMutationCorrelationId,
|
|
203
223
|
nextOrderTurn,
|
|
204
224
|
pendingAuxiliaryCoverageSize,
|
|
225
|
+
primaryUnavailableCause,
|
|
205
226
|
rearmPendingAuxiliaryCoverage,
|
|
206
227
|
reconcileCorrelatedScanDiagnostics,
|
|
207
228
|
reconcileScanDiagnostics,
|
|
@@ -218,7 +239,6 @@ import {
|
|
|
218
239
|
resetOpaqueMutationState,
|
|
219
240
|
resetPendingAuxiliaryCoverage,
|
|
220
241
|
resetWorkspaceDiagnosticsCacheSession,
|
|
221
|
-
resolveImportToFiles,
|
|
222
242
|
resolveLiveBusEmitter,
|
|
223
243
|
resyncDocumentOnPastEof,
|
|
224
244
|
retagAuxiliaryDiagnostics,
|
|
@@ -229,22 +249,23 @@ import {
|
|
|
229
249
|
setSessionLanguages,
|
|
230
250
|
shouldShortenLspIdleTimeout,
|
|
231
251
|
summarizeWorkspaceEdit,
|
|
232
|
-
sweepInlineBlockerFreshness,
|
|
233
|
-
symbolExtractionGrammar,
|
|
234
252
|
touchCompletedConfirmationPolicy,
|
|
235
253
|
touchCoverageGap,
|
|
236
254
|
tryWarmAttachedDiagnostics,
|
|
237
255
|
widgetDiagnosticUri,
|
|
238
256
|
workspaceEditTextPaths,
|
|
239
257
|
writeOrderToken
|
|
240
|
-
} from "../chunk-
|
|
258
|
+
} from "../chunk-RVK72CZX.js";
|
|
241
259
|
import {
|
|
260
|
+
ANY_POSITION,
|
|
261
|
+
foldedFindingIdentity,
|
|
242
262
|
hashText,
|
|
243
263
|
normalizeMessage,
|
|
244
264
|
primePersistedMutationAttribution,
|
|
245
265
|
resetMutationAttribution,
|
|
266
|
+
retainRecordedFindings,
|
|
246
267
|
stableFindingId
|
|
247
|
-
} from "../chunk-
|
|
268
|
+
} from "../chunk-IWDLU6K3.js";
|
|
248
269
|
import {
|
|
249
270
|
mapWithConcurrency
|
|
250
271
|
} from "../chunk-XIMYZ3JA.js";
|
|
@@ -253,6 +274,7 @@ import {
|
|
|
253
274
|
classifyCascadeWaitTier,
|
|
254
275
|
customServerSpecsOf,
|
|
255
276
|
describeRootFallback,
|
|
277
|
+
disabledPrimaries,
|
|
256
278
|
explainServersForFile,
|
|
257
279
|
getAstGrepRuleFingerprint,
|
|
258
280
|
getServersForFileWithConfig,
|
|
@@ -267,17 +289,17 @@ import {
|
|
|
267
289
|
resetLSPCaseSensitivityState,
|
|
268
290
|
resolveLspCwdForFile,
|
|
269
291
|
shouldInitializeSessionRoot
|
|
270
|
-
} from "../chunk-
|
|
271
|
-
import "../chunk-
|
|
292
|
+
} from "../chunk-3DA2JDOL.js";
|
|
293
|
+
import "../chunk-HWCCCQNX.js";
|
|
272
294
|
import {
|
|
273
295
|
emitBounded,
|
|
274
296
|
hasAmbientPythonEnvironment,
|
|
275
297
|
resetBoundedTelemetry
|
|
276
|
-
} from "../chunk-
|
|
298
|
+
} from "../chunk-CUHSHSB6.js";
|
|
277
299
|
import {
|
|
278
300
|
resolveGitCheckout,
|
|
279
301
|
resolveLinkedWorktreeOwner
|
|
280
|
-
} from "../chunk-
|
|
302
|
+
} from "../chunk-UA7ZXYDR.js";
|
|
281
303
|
import {
|
|
282
304
|
PROJECT_SNAPSHOT_VERSION,
|
|
283
305
|
getProjectSnapshotLegacyPath,
|
|
@@ -292,8 +314,25 @@ import {
|
|
|
292
314
|
readJsonCache,
|
|
293
315
|
readProjectSnapshotMeta,
|
|
294
316
|
saveRuntimeProjectSnapshot
|
|
295
|
-
} from "../chunk-
|
|
317
|
+
} from "../chunk-T7FEBKXN.js";
|
|
318
|
+
import {
|
|
319
|
+
SWEEP_IDLE_SAFETY_MARGIN_MS,
|
|
320
|
+
getFullScanWallClockMs,
|
|
321
|
+
isWorkspaceSweepActive,
|
|
322
|
+
runWhenWorkspaceSweepIdle
|
|
323
|
+
} from "../chunk-SRYEJNES.js";
|
|
296
324
|
import "../chunk-5W3R6LFT.js";
|
|
325
|
+
import {
|
|
326
|
+
DEPENDENCY_DRIFT_MAX_DELIVERIES,
|
|
327
|
+
RUNTIME_CONFIG,
|
|
328
|
+
TreeSitterSymbolExtractor,
|
|
329
|
+
exceedsLspSyncLimits,
|
|
330
|
+
resolveImportToFiles,
|
|
331
|
+
sweepInlineBlockerFreshness,
|
|
332
|
+
symbolExtractionGrammar
|
|
333
|
+
} from "../chunk-V35JG4JB.js";
|
|
334
|
+
import "../chunk-XTBDCR27.js";
|
|
335
|
+
import "../chunk-MPNJLASA.js";
|
|
297
336
|
import {
|
|
298
337
|
EXT_TO_LANG,
|
|
299
338
|
classifyTreeSitterWasmError,
|
|
@@ -306,7 +345,7 @@ import {
|
|
|
306
345
|
queryLoader,
|
|
307
346
|
reportBundledResourceDirHealth,
|
|
308
347
|
resolveTreeSitterLanguage
|
|
309
|
-
} from "../chunk-
|
|
348
|
+
} from "../chunk-US7ECLD7.js";
|
|
310
349
|
import "../chunk-Z54ZSOBZ.js";
|
|
311
350
|
import {
|
|
312
351
|
SCAN_LANGUAGE_PRIORITY,
|
|
@@ -314,35 +353,27 @@ import {
|
|
|
314
353
|
extensionsForLanguageToken,
|
|
315
354
|
getUserRuleRoot,
|
|
316
355
|
resolveLanguage
|
|
317
|
-
} from "../chunk-
|
|
356
|
+
} from "../chunk-GXFV6MYU.js";
|
|
318
357
|
import {
|
|
319
358
|
dump,
|
|
320
359
|
resolvePackagePath
|
|
321
|
-
} from "../chunk-
|
|
322
|
-
import "../chunk-GBPP5P7X.js";
|
|
323
|
-
import "../chunk-P7266HLM.js";
|
|
324
|
-
import {
|
|
325
|
-
SWEEP_IDLE_SAFETY_MARGIN_MS,
|
|
326
|
-
getFullScanWallClockMs,
|
|
327
|
-
isWorkspaceSweepActive,
|
|
328
|
-
runWhenWorkspaceSweepIdle
|
|
329
|
-
} from "../chunk-MQLUAEOC.js";
|
|
360
|
+
} from "../chunk-FM4RDMKT.js";
|
|
330
361
|
import {
|
|
331
362
|
HOOK_WALL_BUDGET_MS,
|
|
332
363
|
bounded,
|
|
333
364
|
combineAbortSignals,
|
|
334
365
|
withDeadline
|
|
335
|
-
} from "../chunk-
|
|
366
|
+
} from "../chunk-RMLC67LF.js";
|
|
336
367
|
import {
|
|
337
368
|
centralityFromReverseDeps,
|
|
338
369
|
getWordIndexBuildStatus,
|
|
339
370
|
logWordIndex,
|
|
340
371
|
searchWordIndex,
|
|
341
372
|
triggerBackgroundWordIndexBuild
|
|
342
|
-
} from "../chunk-
|
|
373
|
+
} from "../chunk-W66O5E25.js";
|
|
343
374
|
import {
|
|
344
375
|
getProjectDiagnosticsScannerMaxFiles
|
|
345
|
-
} from "../chunk-
|
|
376
|
+
} from "../chunk-7HXE67BN.js";
|
|
346
377
|
import {
|
|
347
378
|
PathKeyedMap
|
|
348
379
|
} from "../chunk-Z3CCVDUB.js";
|
|
@@ -350,32 +381,37 @@ import {
|
|
|
350
381
|
WARM_TURN_END_SCHEMA_VERSION,
|
|
351
382
|
createWarmIpcLineReader,
|
|
352
383
|
createWarmIpcRequestQueue,
|
|
353
|
-
freshnessFromMtime,
|
|
354
384
|
ipcPathForCwd,
|
|
355
385
|
readTurnEndStatus,
|
|
386
|
+
unlinkStaleUnixSocket
|
|
387
|
+
} from "../chunk-KAPJINKN.js";
|
|
388
|
+
import {
|
|
389
|
+
freshnessFromMtime,
|
|
390
|
+
hashContentBytes,
|
|
356
391
|
resolveRunnerPath,
|
|
357
392
|
toRunnerDisplayPath
|
|
358
|
-
} from "../chunk-
|
|
393
|
+
} from "../chunk-AGSS7277.js";
|
|
359
394
|
import "../chunk-2BEMIWEW.js";
|
|
395
|
+
import "../chunk-IJYGIDF4.js";
|
|
360
396
|
import {
|
|
361
397
|
commitDurableStore,
|
|
362
398
|
resetResolvedPathCache,
|
|
363
399
|
resetZizmorTokenAvailability
|
|
364
|
-
} from "../chunk-
|
|
400
|
+
} from "../chunk-GAQ7OQG6.js";
|
|
365
401
|
import {
|
|
366
402
|
resolveToolCwd
|
|
367
|
-
} from "../chunk-
|
|
403
|
+
} from "../chunk-DEL2U6CM.js";
|
|
368
404
|
import {
|
|
369
405
|
_resetPackageManagerCache,
|
|
370
406
|
findGlobalBinary,
|
|
371
407
|
pmBinary,
|
|
372
408
|
resolveNodePackageManager,
|
|
373
409
|
runScriptArgs
|
|
374
|
-
} from "../chunk-
|
|
410
|
+
} from "../chunk-5VSF4UUQ.js";
|
|
375
411
|
import {
|
|
376
412
|
getIsolatedNpxSpawnOptions,
|
|
377
413
|
probeToolAsync
|
|
378
|
-
} from "../chunk-
|
|
414
|
+
} from "../chunk-3KAZU3VR.js";
|
|
379
415
|
import {
|
|
380
416
|
classifyProbeFailure,
|
|
381
417
|
createAvailabilityLatch,
|
|
@@ -383,20 +419,20 @@ import {
|
|
|
383
419
|
logAvailabilityDecision,
|
|
384
420
|
resetInstallRetryLatches,
|
|
385
421
|
startHostStallSampler
|
|
386
|
-
} from "../chunk-
|
|
422
|
+
} from "../chunk-P63GXC37.js";
|
|
387
423
|
import {
|
|
388
424
|
canRunStartupHeavyScans,
|
|
389
425
|
detectProjectLanguageProfile,
|
|
390
426
|
getDefaultStartupTools
|
|
391
|
-
} from "../chunk-
|
|
392
|
-
import "../chunk-
|
|
427
|
+
} from "../chunk-HRNHZA3N.js";
|
|
428
|
+
import "../chunk-TLX72JTG.js";
|
|
393
429
|
import {
|
|
394
430
|
collectSourceFilesWithBudgetAsync,
|
|
395
431
|
getSlowFsVerdict,
|
|
396
432
|
isSlowFs,
|
|
397
433
|
slowFsDegradationNotice
|
|
398
|
-
} from "../chunk-
|
|
399
|
-
import "../chunk-
|
|
434
|
+
} from "../chunk-DGUKIYSI.js";
|
|
435
|
+
import "../chunk-XBJVAEEO.js";
|
|
400
436
|
import {
|
|
401
437
|
displayProjectDataPath,
|
|
402
438
|
drainProjectDataDirMigrations,
|
|
@@ -423,7 +459,7 @@ import {
|
|
|
423
459
|
sweepDeadEphemeralDataDirs,
|
|
424
460
|
updateHeartbeat,
|
|
425
461
|
withGenerationLockSync
|
|
426
|
-
} from "../chunk-
|
|
462
|
+
} from "../chunk-KUA4OJ5Y.js";
|
|
427
463
|
import {
|
|
428
464
|
createSingleFlight
|
|
429
465
|
} from "../chunk-BW5KFIQC.js";
|
|
@@ -433,7 +469,7 @@ import {
|
|
|
433
469
|
} from "../chunk-QYF5S6P6.js";
|
|
434
470
|
import {
|
|
435
471
|
detectFileKind
|
|
436
|
-
} from "../chunk-
|
|
472
|
+
} from "../chunk-DUO2TU77.js";
|
|
437
473
|
import {
|
|
438
474
|
compareKeys,
|
|
439
475
|
detectFileRole,
|
|
@@ -443,18 +479,18 @@ import {
|
|
|
443
479
|
provenanceView,
|
|
444
480
|
resolvePiLensConfig,
|
|
445
481
|
summarizeConfigResolution
|
|
446
|
-
} from "../chunk-
|
|
482
|
+
} from "../chunk-J6MPGQTS.js";
|
|
447
483
|
import {
|
|
448
484
|
LSP_NAMESPACE_KEY,
|
|
449
485
|
getPiLensGlobalConfigPath,
|
|
450
486
|
resetWorkspaceTopology
|
|
451
|
-
} from "../chunk-
|
|
487
|
+
} from "../chunk-5HSRT26B.js";
|
|
452
488
|
import {
|
|
453
489
|
getProjectTrustState,
|
|
454
490
|
isToolInstallAllowedByTrust,
|
|
455
491
|
projectTrustDenialReason,
|
|
456
492
|
setProjectTrustState
|
|
457
|
-
} from "../chunk-
|
|
493
|
+
} from "../chunk-M2IFVFWU.js";
|
|
458
494
|
import {
|
|
459
495
|
DEFAULT_MAX_OUTPUT_BYTES,
|
|
460
496
|
createBoundedOutputSink,
|
|
@@ -475,17 +511,17 @@ import {
|
|
|
475
511
|
resolveLensToolEnabled,
|
|
476
512
|
resolveLensToolName,
|
|
477
513
|
toolRegistryEntryForMcp
|
|
478
|
-
} from "../chunk-
|
|
514
|
+
} from "../chunk-J64T55EI.js";
|
|
479
515
|
import {
|
|
480
516
|
createSubsystemLogger,
|
|
481
517
|
flushExtensionLog,
|
|
482
518
|
logExtension
|
|
483
|
-
} from "../chunk-
|
|
519
|
+
} from "../chunk-POMLXPMY.js";
|
|
484
520
|
import "../chunk-JMYYOTQG.js";
|
|
485
521
|
import {
|
|
486
522
|
claimPhaseOncePerSession,
|
|
487
523
|
logLatency
|
|
488
|
-
} from "../chunk-
|
|
524
|
+
} from "../chunk-QBFBRV2B.js";
|
|
489
525
|
import {
|
|
490
526
|
beginTurnContext,
|
|
491
527
|
createNdjsonLogger,
|
|
@@ -494,11 +530,11 @@ import {
|
|
|
494
530
|
isTestMode,
|
|
495
531
|
runLogCleanup,
|
|
496
532
|
setTurnContextSession
|
|
497
|
-
} from "../chunk-
|
|
533
|
+
} from "../chunk-YNE3RP52.js";
|
|
498
534
|
import "../chunk-LJDODBBZ.js";
|
|
499
535
|
import {
|
|
500
536
|
FactStore
|
|
501
|
-
} from "../chunk-
|
|
537
|
+
} from "../chunk-CYRKQRPM.js";
|
|
502
538
|
import {
|
|
503
539
|
BoundedFifoMap,
|
|
504
540
|
BoundedLruCache
|
|
@@ -516,13 +552,13 @@ import {
|
|
|
516
552
|
resolveHostToolPath,
|
|
517
553
|
toProjectRelativePath,
|
|
518
554
|
uriToPath
|
|
519
|
-
} from "../chunk-
|
|
555
|
+
} from "../chunk-3RKP3FMS.js";
|
|
520
556
|
import "../chunk-NXL4FFQQ.js";
|
|
521
557
|
|
|
522
558
|
// dist/mcp/server.js
|
|
523
559
|
import * as fs25 from "node:fs";
|
|
524
560
|
import * as net from "node:net";
|
|
525
|
-
import * as
|
|
561
|
+
import * as path40 from "node:path";
|
|
526
562
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
527
563
|
|
|
528
564
|
// dist/tools/render-compact.js
|
|
@@ -787,7 +823,7 @@ function compactRenderResult(summarize) {
|
|
|
787
823
|
|
|
788
824
|
// dist/clients/ast-grep-client.js
|
|
789
825
|
import * as fs4 from "node:fs";
|
|
790
|
-
import * as
|
|
826
|
+
import * as os from "node:os";
|
|
791
827
|
import * as path4 from "node:path";
|
|
792
828
|
|
|
793
829
|
// dist/clients/ast-grep-rule-manager.js
|
|
@@ -928,7 +964,6 @@ var AstGrepRuleManager = class {
|
|
|
928
964
|
|
|
929
965
|
// dist/clients/sg-runner.js
|
|
930
966
|
import * as fs3 from "node:fs";
|
|
931
|
-
import * as os from "node:os";
|
|
932
967
|
import * as path3 from "node:path";
|
|
933
968
|
function buildBashRunArgs(cmd, allArgs) {
|
|
934
969
|
return ["-c", '"$0" "$@"', cmd, ...allArgs];
|
|
@@ -1357,6 +1392,7 @@ ${result.stderr}`)) {
|
|
|
1357
1392
|
case "cwd-unresolvable":
|
|
1358
1393
|
case "permission-denied":
|
|
1359
1394
|
case "spawn-failed":
|
|
1395
|
+
case "trust-refused":
|
|
1360
1396
|
case void 0:
|
|
1361
1397
|
return result.error ? "cli-failure" : void 0;
|
|
1362
1398
|
}
|
|
@@ -1474,7 +1510,7 @@ Original error: ${stderr}`;
|
|
|
1474
1510
|
}
|
|
1475
1511
|
// --- Shared helpers for temp-dir rule scans ---
|
|
1476
1512
|
prepareTempScan(ruleId, ruleYaml) {
|
|
1477
|
-
const sessionDir = fs3.mkdtempSync(path3.join(
|
|
1513
|
+
const sessionDir = fs3.mkdtempSync(path3.join(scannerReportParentDir(), `pi-lens-temp-${ruleId}-`));
|
|
1478
1514
|
try {
|
|
1479
1515
|
const rulesSubdir = path3.join(sessionDir, "rules");
|
|
1480
1516
|
const configFile = path3.join(sessionDir, ".sgconfig.yml");
|
|
@@ -1953,7 +1989,7 @@ var AstGrepClient = class {
|
|
|
1953
1989
|
* Dump the parsed tree-sitter AST for a snippet using ast-grep CLI.
|
|
1954
1990
|
*/
|
|
1955
1991
|
async dumpAst(source, lang, options = {}) {
|
|
1956
|
-
const tmpDir = fs4.mkdtempSync(path4.join(
|
|
1992
|
+
const tmpDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "pi-lens-ast-dump-"));
|
|
1957
1993
|
const tmpFile = path4.join(tmpDir, `snippet.${lang.replace(/[^a-z0-9_-]/gi, "") || "txt"}`);
|
|
1958
1994
|
try {
|
|
1959
1995
|
fs4.writeFileSync(tmpFile, source, "utf-8");
|
|
@@ -1983,7 +2019,7 @@ var AstGrepClient = class {
|
|
|
1983
2019
|
if (shapeError)
|
|
1984
2020
|
return { valid: false, error: shapeError };
|
|
1985
2021
|
const snippet = validationSnippetFor(lang);
|
|
1986
|
-
const tmpDir = fs4.mkdtempSync(path4.join(
|
|
2022
|
+
const tmpDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "pi-lens-sg-validate-"));
|
|
1987
2023
|
const tmpFile = path4.join(tmpDir, `snippet.${snippet.ext}`);
|
|
1988
2024
|
try {
|
|
1989
2025
|
fs4.writeFileSync(tmpFile, snippet.source, "utf-8");
|
|
@@ -2030,7 +2066,7 @@ var AstGrepClient = class {
|
|
|
2030
2066
|
return { valid: false, error: shapeError };
|
|
2031
2067
|
const language = extractRuleLanguage(ruleYaml) ?? "typescript";
|
|
2032
2068
|
const snippet = validationSnippetFor(language);
|
|
2033
|
-
const tmpDir = fs4.mkdtempSync(path4.join(
|
|
2069
|
+
const tmpDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "pi-lens-sg-rule-"));
|
|
2034
2070
|
try {
|
|
2035
2071
|
fs4.writeFileSync(path4.join(tmpDir, `snippet.${snippet.ext}`), snippet.source, "utf-8");
|
|
2036
2072
|
const result = await this.tempScanDetailed(tmpDir, ruleYaml, options);
|
|
@@ -2607,6 +2643,7 @@ async function scanFileMajorRules(cwd, files, signal) {
|
|
|
2607
2643
|
} finally {
|
|
2608
2644
|
facts.dropFileFacts(filePath);
|
|
2609
2645
|
}
|
|
2646
|
+
await new Promise((resolve32) => setImmediate(resolve32));
|
|
2610
2647
|
}
|
|
2611
2648
|
if (wasmAborted) {
|
|
2612
2649
|
astGrep.length = 0;
|
|
@@ -2938,29 +2975,29 @@ async function buildBootstrapClients() {
|
|
|
2938
2975
|
}
|
|
2939
2976
|
}
|
|
2940
2977
|
const [ruffClient, biomeClient, knipClient, todoScanner, jscpdClient, depChecker, testRunnerClient, metricsClient, complexityClient, goClient, govulncheckClient, gitleaksClient, trivyClient, opengrepClient, rustClient, agentBehaviorClient2, deadCodeClients] = await Promise.all([
|
|
2941
|
-
load("ruff", async () => new (await import("../chunk-
|
|
2942
|
-
load("biome", async () => new (await import("../chunk-
|
|
2943
|
-
load("knip", async () => new (await import("../chunk-
|
|
2944
|
-
load("todo", async () => new (await import("../chunk-
|
|
2945
|
-
load("jscpd", async () => new (await import("../chunk-
|
|
2946
|
-
load("dependency-checker", async () => new (await import("../chunk-
|
|
2947
|
-
load("test-runner", async () => new (await import("../chunk-
|
|
2948
|
-
load("metrics", async () => new (await import("../chunk-
|
|
2949
|
-
load("complexity", async () => new (await import("../chunk-
|
|
2978
|
+
load("ruff", async () => new (await import("../chunk-OHKJ7PQF.js")).RuffClient()),
|
|
2979
|
+
load("biome", async () => new (await import("../chunk-N5FLEO7W.js")).BiomeClient()),
|
|
2980
|
+
load("knip", async () => new (await import("../chunk-6DLWKFEX.js")).KnipClient()),
|
|
2981
|
+
load("todo", async () => new (await import("../chunk-2FN63LPV.js")).TodoScanner()),
|
|
2982
|
+
load("jscpd", async () => new (await import("../chunk-R3T7CLQ2.js")).JscpdClient()),
|
|
2983
|
+
load("dependency-checker", async () => new (await import("../chunk-LZSEQW6A.js")).DependencyChecker()),
|
|
2984
|
+
load("test-runner", async () => new (await import("../chunk-GL5LUMZE.js")).TestRunnerClient()),
|
|
2985
|
+
load("metrics", async () => new (await import("../chunk-VOOAPROD.js")).MetricsClient()),
|
|
2986
|
+
load("complexity", async () => new (await import("../chunk-AWSCPCN2.js")).ComplexityClient()),
|
|
2950
2987
|
// The process-wide singleton, NOT a fresh instance (#2455 fix round 4,
|
|
2951
2988
|
// F2). `handleSessionStart` reads this object for its "Active tools"
|
|
2952
2989
|
// line while `resetGoAvailability` re-arms the singleton's latch; a
|
|
2953
2990
|
// second instance here meant the reset never reached the surface a
|
|
2954
2991
|
// user actually sees.
|
|
2955
|
-
load("go", async () => (await import("../chunk-
|
|
2956
|
-
load("govulncheck", async () => new (await import("../chunk-
|
|
2957
|
-
load("gitleaks", async () => new (await import("../chunk-
|
|
2958
|
-
load("trivy", async () => new (await import("../chunk-
|
|
2959
|
-
load("opengrep", async () => new (await import("../chunk-
|
|
2992
|
+
load("go", async () => (await import("../chunk-SKAMFC7A.js")).goClient),
|
|
2993
|
+
load("govulncheck", async () => new (await import("../chunk-3PTHXJXR.js")).GovulncheckClient()),
|
|
2994
|
+
load("gitleaks", async () => new (await import("../chunk-MBKQHGA7.js")).GitleaksClient()),
|
|
2995
|
+
load("trivy", async () => new (await import("../chunk-JW3YWBVB.js")).TrivyClient()),
|
|
2996
|
+
load("opengrep", async () => new (await import("../chunk-5IUSNGOC.js")).OpengrepClient()),
|
|
2960
2997
|
// The process-wide singleton, for the same reason as "go" above.
|
|
2961
|
-
load("rust", async () => (await import("../chunk-
|
|
2962
|
-
load("agent-behavior", async () => (await import("../chunk-
|
|
2963
|
-
loadList("dead-code", async () => (await import("../chunk-
|
|
2998
|
+
load("rust", async () => (await import("../chunk-SYE6T2EB.js")).rustClient),
|
|
2999
|
+
load("agent-behavior", async () => (await import("../chunk-R7YOCSNV.js")).agentBehaviorClient),
|
|
3000
|
+
loadList("dead-code", async () => (await import("../chunk-5WRPDP2A.js")).getDeadCodeClients())
|
|
2964
3001
|
]);
|
|
2965
3002
|
if (failures.length > 0)
|
|
2966
3003
|
await logBootstrapFailures(failures);
|
|
@@ -3047,7 +3084,7 @@ function resetAnalyzerBootstrapSessionState() {
|
|
|
3047
3084
|
}
|
|
3048
3085
|
|
|
3049
3086
|
// dist/clients/formatters-lazy.js
|
|
3050
|
-
var lazyFormatters = createLazyImport(() => import("../chunk-
|
|
3087
|
+
var lazyFormatters = createLazyImport(() => import("../chunk-ZVUL7QYY.js"));
|
|
3051
3088
|
function warmFormatters() {
|
|
3052
3089
|
return lazyFormatters.get();
|
|
3053
3090
|
}
|
|
@@ -3201,13 +3238,18 @@ function readChangeLogMaxSeq(logPath) {
|
|
|
3201
3238
|
}
|
|
3202
3239
|
var CHANGE_LOG_LOCK = { staleMs: 5e3, waitMs: 500 };
|
|
3203
3240
|
function appendProjectChangeAllocated(cwd, build) {
|
|
3241
|
+
appendProjectChangesAllocated(cwd, (logMaxSeq) => [build(logMaxSeq)]);
|
|
3242
|
+
}
|
|
3243
|
+
function appendProjectChangesAllocated(cwd, buildAll) {
|
|
3204
3244
|
const logPath = getProjectChangeLogPath(cwd);
|
|
3205
3245
|
fs7.mkdirSync(path7.dirname(logPath), { recursive: true });
|
|
3206
3246
|
readChangeLogMaxSeq(logPath);
|
|
3207
3247
|
const append = (locked) => {
|
|
3208
|
-
const
|
|
3209
|
-
|
|
3210
|
-
|
|
3248
|
+
const entries = buildAll(readChangeLogMaxSeq(logPath));
|
|
3249
|
+
if (entries.length === 0)
|
|
3250
|
+
return;
|
|
3251
|
+
const payload = entries.map((entry) => JSON.stringify(locked ? entry : { ...entry, unlocked: true })).join("\n");
|
|
3252
|
+
fs7.appendFileSync(logPath, `${payload}
|
|
3211
3253
|
`, "utf-8");
|
|
3212
3254
|
};
|
|
3213
3255
|
const result = withGenerationLockSync(`${logPath}.locks`, CHANGE_LOG_LOCK, () => append(true));
|
|
@@ -3228,7 +3270,11 @@ function inlineBlockerSources(blockers) {
|
|
|
3228
3270
|
}
|
|
3229
3271
|
function inlineBlockerLines(blockers, filePath) {
|
|
3230
3272
|
const own = normalizeEphemeralMapKey(filePath);
|
|
3231
|
-
return blockers.filter(
|
|
3273
|
+
return blockers.filter(
|
|
3274
|
+
// #4509 (N3): a stale entry's line is from older bytes, so it cites
|
|
3275
|
+
// none: the past-EOF sweep would retire the whole record on it.
|
|
3276
|
+
(d) => !d.positionStale && normalizeEphemeralMapKey(d.filePath) === own
|
|
3277
|
+
).map((d) => d.line).filter((line) => typeof line === "number");
|
|
3232
3278
|
}
|
|
3233
3279
|
|
|
3234
3280
|
// dist/clients/partial-edit-apply.js
|
|
@@ -3414,6 +3460,7 @@ function recordViewIncomplete(cwd, cause) {
|
|
|
3414
3460
|
});
|
|
3415
3461
|
}
|
|
3416
3462
|
var MAX_RESOLVED_BLOCKER_FILES = 10;
|
|
3463
|
+
var MAX_OWED_ANCHORS = 16;
|
|
3417
3464
|
var TOOL_CALL_ATTRIBUTION_CAPACITY = 256;
|
|
3418
3465
|
var TOOL_CALL_ATTRIBUTION_TTL_MS = 5 * 6e4;
|
|
3419
3466
|
var TurnWarningsBySession = class {
|
|
@@ -3463,7 +3510,7 @@ var RuntimeCoordinator = class {
|
|
|
3463
3510
|
diagnosticsSurfaced: 0,
|
|
3464
3511
|
coldSnapshotTouches: 0
|
|
3465
3512
|
};
|
|
3466
|
-
_complexityBaselines = /* @__PURE__ */ new
|
|
3513
|
+
_complexityBaselines = /* @__PURE__ */ new Set();
|
|
3467
3514
|
_fixedThisTurn = new PathKeyedMap(normalizeMapKey);
|
|
3468
3515
|
_writtenThisTurn = new PathKeyedMap(normalizeMapKey);
|
|
3469
3516
|
_autofixDemotedThisTurn = new PathKeyedMap(normalizeMapKey);
|
|
@@ -3552,6 +3599,26 @@ var RuntimeCoordinator = class {
|
|
|
3552
3599
|
_readWidenings = new BoundedLruCache(TOOL_CALL_ATTRIBUTION_CAPACITY);
|
|
3553
3600
|
_lspReadWarmState = /* @__PURE__ */ new Map();
|
|
3554
3601
|
_pendingInlineBlockers = new PathKeyedMap(normalizeMapKey);
|
|
3602
|
+
/**
|
|
3603
|
+
* #4484 round 4: per file, what its last applied inline verdict left owed
|
|
3604
|
+
* (`setAnalysisAnchor`), for a file whose record is gone or has no anchor.
|
|
3605
|
+
* The positions live on the blocker record
|
|
3606
|
+
* (`InlineBlockerRecord.analysisAnchor`). Round 5: this keeps each owing
|
|
3607
|
+
* runner's owed line texts (`owedByContentOnly`, at most
|
|
3608
|
+
* `MAX_OWED_LINE_TEXTS` hashes per runner, 16 KB), not only its id, so
|
|
3609
|
+
* the next write owes it only the lines with those texts, never the whole
|
|
3610
|
+
* file for a skip. Replaced by every applied verdict of the file and
|
|
3611
|
+
* cleared per session.
|
|
3612
|
+
*/
|
|
3613
|
+
_owedRunners = new PathKeyedMap(normalizeMapKey);
|
|
3614
|
+
/**
|
|
3615
|
+
* #4484 round 5: for a file with no blocker record, its last verdict's
|
|
3616
|
+
* whole anchor (line hashes too), so the next write still remaps owed
|
|
3617
|
+
* positions exactly (verify probe P23). At most `MAX_OWED_ANCHORS` files,
|
|
3618
|
+
* 400 KB each; an evicted file falls back to `_owedRunners`' owed line
|
|
3619
|
+
* texts, a superset. Cleared per session.
|
|
3620
|
+
*/
|
|
3621
|
+
_owedAnchors = new PathKeyedMap(normalizeMapKey, MAX_OWED_ANCHORS);
|
|
3555
3622
|
/**
|
|
3556
3623
|
* #3507: one per-path order for BOTH verbs on `_pendingInlineBlockers`,
|
|
3557
3624
|
* the widget store's guard shape (`widget-state.ts` diagnosticsWriteGuard).
|
|
@@ -3640,6 +3707,8 @@ var RuntimeCoordinator = class {
|
|
|
3640
3707
|
this._readWidenings.clear();
|
|
3641
3708
|
this._lspReadWarmState.clear();
|
|
3642
3709
|
this._pendingInlineBlockers.clear();
|
|
3710
|
+
this._owedRunners.clear();
|
|
3711
|
+
this._owedAnchors.clear();
|
|
3643
3712
|
this._inlineBlockerWriteOrder.clear();
|
|
3644
3713
|
this._resolvedBlockerFilesThisTurn.clear();
|
|
3645
3714
|
this._resolvedBlockerFilesDropped = 0;
|
|
@@ -3793,20 +3862,79 @@ var RuntimeCoordinator = class {
|
|
|
3793
3862
|
}
|
|
3794
3863
|
}
|
|
3795
3864
|
const { projectSeq, fileSeq, key } = logged ?? this.bumpFileSeq(args.filePath);
|
|
3865
|
+
this.recordMutationReceipt({ projectSeq, fileSeq, key }, args.source);
|
|
3866
|
+
return { projectSeq, fileSeq };
|
|
3867
|
+
}
|
|
3868
|
+
/**
|
|
3869
|
+
* #4535: the bulk form of {@link recordProjectMutation}, for a disk change
|
|
3870
|
+
* pi-lens did not author that spans many paths (a publisher's recorded
|
|
3871
|
+
* population). It allocates from the SAME sequence, in ONE locked append:
|
|
3872
|
+
* `appendProjectChangesAllocated` takes the change-log lock once and writes
|
|
3873
|
+
* every line under it, so a 400-path HEAD move costs one lock round-trip
|
|
3874
|
+
* inside a hook budget instead of 400. The lock-failure semantics are the
|
|
3875
|
+
* single writer's: when the lock is unavailable every appended line is
|
|
3876
|
+
* tagged `unlocked` and one `change-log-lock-unavailable` degradation is
|
|
3877
|
+
* recorded for the batch. Receipts are appended per path with the same ring
|
|
3878
|
+
* cap and drop counter as a single mutation.
|
|
3879
|
+
*
|
|
3880
|
+
* Returns the batch's last allocated `projectSeq` (the record's seq after
|
|
3881
|
+
* the batch) and each path's `fileSeq` keyed by the bump's normalized key.
|
|
3882
|
+
* Duplicate paths are the caller's to collapse: each entry bumps.
|
|
3883
|
+
*/
|
|
3884
|
+
recordProjectMutations(args) {
|
|
3885
|
+
let logged;
|
|
3886
|
+
if (args.cwd !== void 0 && args.paths.length > 0) {
|
|
3887
|
+
try {
|
|
3888
|
+
const cwd = args.cwd;
|
|
3889
|
+
const paths = args.paths;
|
|
3890
|
+
appendProjectChangesAllocated(cwd, (logMaxSeq) => {
|
|
3891
|
+
const ownSeq = this._projectSeq;
|
|
3892
|
+
const bumps2 = paths.map((filePath) => this.bumpFileSeq(filePath, logMaxSeq));
|
|
3893
|
+
logged = bumps2;
|
|
3894
|
+
if (this._viewMissingThrough > 0) {
|
|
3895
|
+
recordViewIncomplete(cwd, { ownSeq, logMaxSeq });
|
|
3896
|
+
}
|
|
3897
|
+
return bumps2.map((bump, index) => ({
|
|
3898
|
+
seq: bump.projectSeq,
|
|
3899
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3900
|
+
sessionId: this.telemetrySessionId,
|
|
3901
|
+
turnIndex: this.turnIndex,
|
|
3902
|
+
source: args.source,
|
|
3903
|
+
filePath: path8.resolve(paths[index]),
|
|
3904
|
+
fileSeq: bump.fileSeq
|
|
3905
|
+
}));
|
|
3906
|
+
});
|
|
3907
|
+
} catch (err) {
|
|
3908
|
+
args.onAppendError?.(err);
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
const bumps = logged ?? args.paths.map((filePath) => this.bumpFileSeq(filePath));
|
|
3912
|
+
const fileSeqs = /* @__PURE__ */ new Map();
|
|
3913
|
+
for (const bump of bumps) {
|
|
3914
|
+
this.recordMutationReceipt({ projectSeq: bump.projectSeq, fileSeq: bump.fileSeq, key: bump.key }, args.source);
|
|
3915
|
+
fileSeqs.set(bump.key, bump.fileSeq);
|
|
3916
|
+
}
|
|
3917
|
+
return { projectSeq: this._projectSeq, fileSeqs };
|
|
3918
|
+
}
|
|
3919
|
+
/**
|
|
3920
|
+
* The receipt ring (§ {@link MutationReceipt}): one entry per bump, oldest
|
|
3921
|
+
* evicted at the cap and counted, never silently incomplete. One writer, so
|
|
3922
|
+
* the single and bulk mutation paths cannot drift apart on attribution.
|
|
3923
|
+
*/
|
|
3924
|
+
recordMutationReceipt(bump, source) {
|
|
3796
3925
|
if (this._mutationReceipts.length >= MAX_MUTATION_RECEIPTS) {
|
|
3797
3926
|
this._mutationReceipts.shift();
|
|
3798
3927
|
this._droppedMutationReceipts += 1;
|
|
3799
3928
|
}
|
|
3800
3929
|
this._mutationReceipts.push({
|
|
3801
|
-
seq: projectSeq,
|
|
3930
|
+
seq: bump.projectSeq,
|
|
3802
3931
|
// Reuse the bump's normalized key (a realpath syscall: ~200us on
|
|
3803
3932
|
// Windows, ~1.8us on POSIX since #3098) — never re-derive it here.
|
|
3804
|
-
filePath: key,
|
|
3805
|
-
source
|
|
3933
|
+
filePath: bump.key,
|
|
3934
|
+
source,
|
|
3806
3935
|
turnIndex: this._turnIndex,
|
|
3807
3936
|
ts: Date.now()
|
|
3808
3937
|
});
|
|
3809
|
-
return { projectSeq, fileSeq };
|
|
3810
3938
|
}
|
|
3811
3939
|
/**
|
|
3812
3940
|
* Attributed mutations whose seq is strictly after `seq` — the receipt-level
|
|
@@ -4275,7 +4403,7 @@ var RuntimeCoordinator = class {
|
|
|
4275
4403
|
const existing = this._pendingInlineBlockers.get(key);
|
|
4276
4404
|
if (existing && !existing.diagnostics)
|
|
4277
4405
|
return 0;
|
|
4278
|
-
const identity = (d) => JSON.stringify([d
|
|
4406
|
+
const identity = (d) => JSON.stringify([foldedFindingIdentity(d), d.line, d.column]);
|
|
4279
4407
|
const known = new Set((existing?.diagnostics ?? []).map(identity));
|
|
4280
4408
|
const added = blocking.flatMap((d) => known.has(identity(d)) ? [] : [d]);
|
|
4281
4409
|
if (added.length === 0)
|
|
@@ -4311,6 +4439,91 @@ var RuntimeCoordinator = class {
|
|
|
4311
4439
|
});
|
|
4312
4440
|
return added.length;
|
|
4313
4441
|
}
|
|
4442
|
+
/**
|
|
4443
|
+
* #4484 round 2: the file's recorded blocking diagnostics, which the next
|
|
4444
|
+
* write's pipeline carries forward unless a conclusive observation from
|
|
4445
|
+
* their own source shows them gone. Undefined when nothing is recorded or
|
|
4446
|
+
* the record holds text only.
|
|
4447
|
+
*/
|
|
4448
|
+
getInlineBlockerDiagnostics(filePath) {
|
|
4449
|
+
return this._pendingInlineBlockers.get(path8.resolve(filePath))?.diagnostics;
|
|
4450
|
+
}
|
|
4451
|
+
/**
|
|
4452
|
+
* #4484 round 3: the anchor the next write's pipeline aligns to: the line
|
|
4453
|
+
* hashes of the bytes the file's blocker record is about, and the lines
|
|
4454
|
+
* still owed. Round 4: it is the record's own anchor. A file without one
|
|
4455
|
+
* (no record, or a record a collect-later settle started) gets no hashes,
|
|
4456
|
+
* so the pipeline cannot align. Round 5: it gets the owed line texts.
|
|
4457
|
+
*/
|
|
4458
|
+
getAnalysisAnchor(filePath) {
|
|
4459
|
+
return this._pendingInlineBlockers.get(filePath)?.analysisAnchor ?? this._owedAnchors.get(filePath) ?? this._owedRunners.get(filePath);
|
|
4460
|
+
}
|
|
4461
|
+
/**
|
|
4462
|
+
* #4484 round 3: store the anchor of an inline verdict that just applied
|
|
4463
|
+
* (`recordInlineBlockers` or `clearInlineBlockers` returned applied), so it
|
|
4464
|
+
* always describes the bytes the record is about. Round 4: it goes on the
|
|
4465
|
+
* record, and lives as long as the record; what is owed goes apart
|
|
4466
|
+
* (`_owedRunners`, by content since round 5), so it outlives a record that
|
|
4467
|
+
* a later retire drops. Round 5: a file with no record keeps its whole
|
|
4468
|
+
* anchor too (`_owedAnchors`, bounded).
|
|
4469
|
+
*/
|
|
4470
|
+
setAnalysisAnchor(filePath, anchor) {
|
|
4471
|
+
const existing = this._pendingInlineBlockers.get(filePath);
|
|
4472
|
+
if (existing) {
|
|
4473
|
+
const key = path8.resolve(filePath);
|
|
4474
|
+
const { analysisAnchor: _dropped, ...rest } = existing;
|
|
4475
|
+
this._pendingInlineBlockers.set(key, anchor ? { ...rest, analysisAnchor: anchor } : rest);
|
|
4476
|
+
}
|
|
4477
|
+
const owed = owedByContentOnly(anchor);
|
|
4478
|
+
if (owed)
|
|
4479
|
+
this._owedRunners.set(filePath, owed);
|
|
4480
|
+
else
|
|
4481
|
+
this._owedRunners.delete(filePath);
|
|
4482
|
+
if (owed && anchor?.lineHashes && !existing)
|
|
4483
|
+
this._owedAnchors.set(filePath, anchor);
|
|
4484
|
+
else
|
|
4485
|
+
this._owedAnchors.delete(filePath);
|
|
4486
|
+
}
|
|
4487
|
+
/**
|
|
4488
|
+
* #4484 round 2: a settled collect-later run is the observation that can
|
|
4489
|
+
* retire the blockers its runner left pending while it was in flight. Its
|
|
4490
|
+
* runner's recorded blockers that the run no longer observes leave the
|
|
4491
|
+
* record; blockers from other runners, and from a server the run left
|
|
4492
|
+
* unconfirmed, stay. A blocker is still observed only at its own line, in
|
|
4493
|
+
* range or withheld by the run's edit-range gate (#4484 round 3). The run
|
|
4494
|
+
* must be about the recorded bytes: marked after
|
|
4495
|
+
* they were read (`recordedAtMs`), with the file still holding them
|
|
4496
|
+
* (`recordedHash`). An emptied record is deleted and its file is noted
|
|
4497
|
+
* Resolved for turn end, as a clean write's clear does.
|
|
4498
|
+
*
|
|
4499
|
+
* @returns how many recorded blockers the run retired.
|
|
4500
|
+
*/
|
|
4501
|
+
retireUnobservedRunnerBlockers(filePath, run) {
|
|
4502
|
+
const key = path8.resolve(filePath);
|
|
4503
|
+
const existing = this._pendingInlineBlockers.get(key);
|
|
4504
|
+
if (!existing?.diagnostics || run.sha256 === void 0 || existing.recordedHash !== run.sha256 || existing.recordedAtMs === void 0 || run.markedAtMs < existing.recordedAtMs)
|
|
4505
|
+
return 0;
|
|
4506
|
+
const unconfirmed = new Set(run.unconfirmedServerIds);
|
|
4507
|
+
const { kept, retired } = retainRecordedFindings(existing.diagnostics, run.observed, {
|
|
4508
|
+
positionOf: (d) => d.positionStale ? ANY_POSITION : d.line,
|
|
4509
|
+
keepUnobserved: (d) => d.runnerId !== run.runnerId || d.serverId !== void 0 && unconfirmed.has(d.serverId)
|
|
4510
|
+
});
|
|
4511
|
+
if (retired.length === 0)
|
|
4512
|
+
return 0;
|
|
4513
|
+
if (kept.length === 0) {
|
|
4514
|
+
this.noteResolvedBlockerFile(existing, void 0, false);
|
|
4515
|
+
this._pendingInlineBlockers.delete(key);
|
|
4516
|
+
return retired.length;
|
|
4517
|
+
}
|
|
4518
|
+
this._pendingInlineBlockers.set(key, {
|
|
4519
|
+
...existing,
|
|
4520
|
+
summary: formatDiagnostics(kept, "blocking").trim(),
|
|
4521
|
+
diagnostics: kept,
|
|
4522
|
+
sources: inlineBlockerSources(kept),
|
|
4523
|
+
lines: inlineBlockerLines(kept, existing.filePath)
|
|
4524
|
+
});
|
|
4525
|
+
return retired.length;
|
|
4526
|
+
}
|
|
4314
4527
|
/**
|
|
4315
4528
|
* #3218 criterion 2: remember one file whose blocker a clean verdict just
|
|
4316
4529
|
* retired, for the turn-end "Resolved" line. Called from the two retire
|
|
@@ -4348,9 +4561,22 @@ var RuntimeCoordinator = class {
|
|
|
4348
4561
|
* counted as `blocker-clear-refused` per file key. A record with no
|
|
4349
4562
|
* `recordedHash` (#2982: the file was unreadable or over the baseline cap at
|
|
4350
4563
|
* record time) cannot be matched and is cleared as before.
|
|
4564
|
+
*
|
|
4565
|
+
* #4484: a blocker is pending until a fresh observation no longer holds it,
|
|
4566
|
+
* so a run whose own observation still holds `analysis.blocking` blockers
|
|
4567
|
+
* never clears the record, whatever its authorship or its delta said; it
|
|
4568
|
+
* is refused and counted the same way.
|
|
4351
4569
|
*/
|
|
4352
4570
|
clearInlineBlockers(filePath, writeIndex, orderTurn = this._writeOrderTurn, analysis) {
|
|
4353
4571
|
const existing = this._pendingInlineBlockers.get(path8.resolve(filePath));
|
|
4572
|
+
if (existing && (analysis?.blocking ?? 0) > 0) {
|
|
4573
|
+
incrementDegradationCount({
|
|
4574
|
+
kind: "blocker-clear-refused",
|
|
4575
|
+
subject: normalizeMapKey(filePath),
|
|
4576
|
+
reason: "the clearing run still observed a blocker on the file; the record stays until an observation holds none (#4484)"
|
|
4577
|
+
});
|
|
4578
|
+
return false;
|
|
4579
|
+
}
|
|
4354
4580
|
if (existing && analysis && !analysis.authored && analysis.sha256 !== void 0 && existing.recordedHash === analysis.sha256) {
|
|
4355
4581
|
incrementDegradationCount({
|
|
4356
4582
|
kind: "blocker-clear-refused",
|
|
@@ -5345,7 +5571,8 @@ function boundDeferredTargets(entries, max, isOwn) {
|
|
|
5345
5571
|
}
|
|
5346
5572
|
|
|
5347
5573
|
// dist/clients/test-runner-delivery.js
|
|
5348
|
-
var
|
|
5574
|
+
var MAX_PENDING_DELIVERIES = 32;
|
|
5575
|
+
var pending = new BoundedFifoMap(MAX_PENDING_DELIVERIES);
|
|
5349
5576
|
function resetTestRunnerDelivery() {
|
|
5350
5577
|
pending.clear();
|
|
5351
5578
|
}
|
|
@@ -5604,8 +5831,8 @@ async function igniteDominantLanguageWarm(cwd, runtime, sessionGeneration, dbg)
|
|
|
5604
5831
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5605
5832
|
return;
|
|
5606
5833
|
const lspService = (await loadLspService()).getLSPService();
|
|
5607
|
-
const { collectSourceFilesAsync } = await import("../chunk-
|
|
5608
|
-
const { CODE_KINDS, detectFileKind: detectFileKind2 } = await import("../chunk-
|
|
5834
|
+
const { collectSourceFilesAsync } = await import("../chunk-IQWN5JCP.js");
|
|
5835
|
+
const { CODE_KINDS, detectFileKind: detectFileKind2 } = await import("../chunk-S2HEXIWI.js");
|
|
5609
5836
|
const files = await collectSourceFilesAsync(cwd, {
|
|
5610
5837
|
inspectGeneratedHeaders: false
|
|
5611
5838
|
});
|
|
@@ -5671,7 +5898,7 @@ function scheduleManagedToolRefresh(dbg) {
|
|
|
5671
5898
|
const timer = setTimeout(() => {
|
|
5672
5899
|
void (async () => {
|
|
5673
5900
|
try {
|
|
5674
|
-
const refresh = await import("../chunk-
|
|
5901
|
+
const refresh = await import("../chunk-2KXTHF3M.js");
|
|
5675
5902
|
const outcome = await refresh.runManagedToolRefresh();
|
|
5676
5903
|
if (outcome.skipped) {
|
|
5677
5904
|
dbg(`session_start tool-refresh: skipped (${outcome.skipped})`);
|
|
@@ -5718,7 +5945,7 @@ function scanOneTodoFile(scanner, filePath, items) {
|
|
|
5718
5945
|
async function collectTodoBaselineItems(scanner, analysisRoot, stillCurrent) {
|
|
5719
5946
|
const items = [];
|
|
5720
5947
|
try {
|
|
5721
|
-
const { getSourceFilesAsync } = await import("../chunk-
|
|
5948
|
+
const { getSourceFilesAsync } = await import("../chunk-TRETHTQO.js");
|
|
5722
5949
|
const files = await getSourceFilesAsync(analysisRoot, true);
|
|
5723
5950
|
if (!stillCurrent())
|
|
5724
5951
|
return items;
|
|
@@ -5747,7 +5974,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5747
5974
|
const snapshot = loadProjectSnapshot(snapshotRoot);
|
|
5748
5975
|
const snapshotLoadMs = Date.now() - snapshotLoadStartMs;
|
|
5749
5976
|
if (snapshot?.wordIndex) {
|
|
5750
|
-
const { deserializeWordIndex, refreshWordIndexIncrementally, countWordIndexPostingEntries: countWordIndexPostingEntries2, estimateWordIndexResidentBytes: estimateWordIndexResidentBytes2 } = await import("../chunk-
|
|
5977
|
+
const { deserializeWordIndex, refreshWordIndexIncrementally, countWordIndexPostingEntries: countWordIndexPostingEntries2, estimateWordIndexResidentBytes: estimateWordIndexResidentBytes2, notifyWordIndexPublished: notifyWordIndexPublished2 } = await import("../chunk-ATKJFDQN.js");
|
|
5751
5978
|
const deserializeStartMs = Date.now();
|
|
5752
5979
|
const index = deserializeWordIndex(snapshot.wordIndex);
|
|
5753
5980
|
const deserializeMs = Date.now() - deserializeStartMs;
|
|
@@ -5772,6 +5999,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5772
5999
|
});
|
|
5773
6000
|
} else {
|
|
5774
6001
|
runtime.wordIndex = index;
|
|
6002
|
+
notifyWordIndexPublished2(snapshotRoot, index, "session_start");
|
|
5775
6003
|
let snapshotSaveSyncMs = 0;
|
|
5776
6004
|
if (!isProjectSnapshotFresh(snapshot, effectiveSeq, latestSeq.unlockedThrough) || result.refreshed > 0 || result.dropped > 0 || snapshot.wordIndex.truncated !== index.truncated) {
|
|
5777
6005
|
const serializeSaveEnqueueStartMs = Date.now();
|
|
@@ -5819,7 +6047,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5819
6047
|
}
|
|
5820
6048
|
}
|
|
5821
6049
|
}
|
|
5822
|
-
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes } = await import("../chunk-
|
|
6050
|
+
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes, notifyWordIndexPublished } = await import("../chunk-ATKJFDQN.js");
|
|
5823
6051
|
const docs = await collectWordIndexDocs(analysisRoot, () => runtime.isCurrentSession(sessionGeneration), rebuildPreflightFiles);
|
|
5824
6052
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5825
6053
|
return;
|
|
@@ -5836,6 +6064,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5836
6064
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5837
6065
|
return;
|
|
5838
6066
|
runtime.wordIndex = rebuiltIndex;
|
|
6067
|
+
notifyWordIndexPublished(snapshotRoot, rebuiltIndex, "session_start");
|
|
5839
6068
|
saveRuntimeProjectSnapshot({ cwd: snapshotRoot, runtime, dbg });
|
|
5840
6069
|
dbg(`session_start word-index: rebuilt (absent/stale, seq=${effectiveSeq}) ${runtime.wordIndex.docCount} files, ${runtime.wordIndex.postings.size} tokens (${Date.now() - startMs}ms)`);
|
|
5841
6070
|
logWordIndex({
|
|
@@ -5858,6 +6087,11 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5858
6087
|
reused: 0
|
|
5859
6088
|
};
|
|
5860
6089
|
}
|
|
6090
|
+
var STARTUP_TASK_DEFER_MS = {
|
|
6091
|
+
"call-graph": 5e3,
|
|
6092
|
+
"codebase-model": 5200,
|
|
6093
|
+
"ast-grep-exports": 5400
|
|
6094
|
+
};
|
|
5861
6095
|
function scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg) {
|
|
5862
6096
|
void (async () => {
|
|
5863
6097
|
const resolved = await demandBootstrapDeps(deps, "session-start-scans");
|
|
@@ -5879,15 +6113,10 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5879
6113
|
reason: "skipped (disabled by config)"
|
|
5880
6114
|
});
|
|
5881
6115
|
}
|
|
5882
|
-
const taskDeferMsByName = {
|
|
5883
|
-
"call-graph": 5e3,
|
|
5884
|
-
"codebase-model": 5200,
|
|
5885
|
-
"ast-grep exports": 5400,
|
|
5886
|
-
"project index": 5400
|
|
5887
|
-
};
|
|
5888
6116
|
const runTask = (name, task) => {
|
|
5889
6117
|
const queuedAt = Date.now();
|
|
5890
|
-
|
|
6118
|
+
const delay = STARTUP_TASK_DEFER_MS[name] ?? 0;
|
|
6119
|
+
dbg(`session_start task ${name}: scheduled deferMs=${delay}`);
|
|
5891
6120
|
runtime.markStartupScanInFlight(name, sessionGeneration);
|
|
5892
6121
|
const completion = new Promise((resolve32) => {
|
|
5893
6122
|
const fire = () => {
|
|
@@ -5904,7 +6133,6 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5904
6133
|
resolve32();
|
|
5905
6134
|
});
|
|
5906
6135
|
};
|
|
5907
|
-
const delay = taskDeferMsByName[name] ?? 0;
|
|
5908
6136
|
if (delay > 0) {
|
|
5909
6137
|
setTimeout(fire, delay).unref?.();
|
|
5910
6138
|
} else {
|
|
@@ -5916,7 +6144,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5916
6144
|
const canRunJsTsHeavyScans = canRunStartupHeavyScans(languageProfile, "jsts");
|
|
5917
6145
|
const scanNames = ["todo", "dead-code"];
|
|
5918
6146
|
if (canRunJsTsHeavyScans) {
|
|
5919
|
-
scanNames.push("knip", "jscpd", "ast-grep
|
|
6147
|
+
scanNames.push("knip", "jscpd", "ast-grep-exports");
|
|
5920
6148
|
}
|
|
5921
6149
|
dbg(`session_start: launching background scans (${scanNames.join(", ")})`);
|
|
5922
6150
|
void runTask("todo", async () => {
|
|
@@ -6184,9 +6412,9 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6184
6412
|
});
|
|
6185
6413
|
let callGraphIdentity;
|
|
6186
6414
|
const callGraphTask = runTask("call-graph", async () => {
|
|
6187
|
-
const { FactStore: FactStore2 } = await import("../chunk-
|
|
6188
|
-
const { buildOrUpdateGraph, extractSymbolsAndRefsFromGraph, getReviewGraphCacheIdentity } = await import("../chunk-
|
|
6189
|
-
const { buildCallGraph, saveCallGraph, loadCallGraph: loadCallGraph2 } = await import("../chunk-
|
|
6415
|
+
const { FactStore: FactStore2 } = await import("../chunk-UMS2MFPZ.js");
|
|
6416
|
+
const { buildOrUpdateGraph, extractSymbolsAndRefsFromGraph, getReviewGraphCacheIdentity } = await import("../chunk-YCWYO6TQ.js");
|
|
6417
|
+
const { buildCallGraph, saveCallGraph, loadCallGraph: loadCallGraph2 } = await import("../chunk-GMX5OS7B.js");
|
|
6190
6418
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
6191
6419
|
return;
|
|
6192
6420
|
const startMs = Date.now();
|
|
@@ -6227,7 +6455,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6227
6455
|
return;
|
|
6228
6456
|
if (!runtime.callGraph)
|
|
6229
6457
|
return;
|
|
6230
|
-
const { buildCodebaseModel, saveCodebaseModel, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET } = await import("../chunk-
|
|
6458
|
+
const { buildCodebaseModel, saveCodebaseModel, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET } = await import("../chunk-TOY6QKOH.js");
|
|
6231
6459
|
if (!callGraphIdentity)
|
|
6232
6460
|
return;
|
|
6233
6461
|
const model = buildCodebaseModel(runtime.callGraph, analysisRoot, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET, callGraphIdentity);
|
|
@@ -6259,18 +6487,18 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6259
6487
|
});
|
|
6260
6488
|
});
|
|
6261
6489
|
}
|
|
6262
|
-
function scheduleDeferredToolProbes(deps, languageProfile, startupDefaults,
|
|
6490
|
+
function scheduleDeferredToolProbes(deps, languageProfile, startupDefaults, dbg) {
|
|
6263
6491
|
void (async () => {
|
|
6264
6492
|
const resolved = await demandBootstrapDeps(deps, "session-start-tool-probes");
|
|
6265
6493
|
if (!resolved) {
|
|
6266
6494
|
dbg("session_start tools: analyzer bootstrap unavailable \u2014 no probes");
|
|
6267
6495
|
return;
|
|
6268
6496
|
}
|
|
6269
|
-
scheduleDeferredToolProbesWithClients(resolved, languageProfile, startupDefaults,
|
|
6497
|
+
scheduleDeferredToolProbesWithClients(resolved, languageProfile, startupDefaults, dbg);
|
|
6270
6498
|
})();
|
|
6271
6499
|
}
|
|
6272
|
-
function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDefaults,
|
|
6273
|
-
const { biomeClient, ruffClient
|
|
6500
|
+
function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDefaults, dbg) {
|
|
6501
|
+
const { biomeClient, ruffClient } = deps;
|
|
6274
6502
|
const defaultTools = new Set(startupDefaults);
|
|
6275
6503
|
const probes = [];
|
|
6276
6504
|
if (languageProfile.present.jsts && !defaultTools.has("biome")) {
|
|
@@ -6279,9 +6507,6 @@ function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDef
|
|
|
6279
6507
|
if (languageProfile.present.python && !defaultTools.has("ruff")) {
|
|
6280
6508
|
probes.push(["ruff", () => ruffClient.ensureAvailable()]);
|
|
6281
6509
|
}
|
|
6282
|
-
if (startupScansWillRun) {
|
|
6283
|
-
probes.push(["madge", () => depChecker.ensureAvailable()]);
|
|
6284
|
-
}
|
|
6285
6510
|
if (probes.length === 0) {
|
|
6286
6511
|
dbg("session_start tools: no deferred availability probes needed");
|
|
6287
6512
|
return;
|
|
@@ -6300,6 +6525,34 @@ function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDef
|
|
|
6300
6525
|
dbg(`session_start tools (deferred probes complete, ${Date.now() - warmStart}ms): ${summary}`);
|
|
6301
6526
|
})();
|
|
6302
6527
|
}
|
|
6528
|
+
function resetSessionScopedState(cwd, sessionStartMs = Date.now()) {
|
|
6529
|
+
resetWorkspaceTopology();
|
|
6530
|
+
resetOpaqueMutationState();
|
|
6531
|
+
resetObservedMutationNet();
|
|
6532
|
+
resetMutationAttribution();
|
|
6533
|
+
primePersistedMutationAttribution(cwd);
|
|
6534
|
+
resetPendingAuxiliaryCoverage();
|
|
6535
|
+
resetSafeSpawnWindowsCommandCache();
|
|
6536
|
+
resetDispatchAvailabilityState();
|
|
6537
|
+
resetObservedRunnerLatency();
|
|
6538
|
+
resetPendingRunnerFindings();
|
|
6539
|
+
resetSpawnTimeoutCooldowns();
|
|
6540
|
+
clearFormatterCache();
|
|
6541
|
+
resetZizmorTokenAvailability();
|
|
6542
|
+
resetGoAvailability();
|
|
6543
|
+
resetRustAvailability();
|
|
6544
|
+
resetPsScriptAnalyzerAvailability();
|
|
6545
|
+
resetInstallRetryLatches();
|
|
6546
|
+
resetLazyInstallAttempts();
|
|
6547
|
+
resetDirectLspCommandAvailability();
|
|
6548
|
+
resetLSPCaseSensitivityState();
|
|
6549
|
+
resetResolvedPathCache();
|
|
6550
|
+
_resetPackageManagerCache();
|
|
6551
|
+
resetManagedToolRefreshSession();
|
|
6552
|
+
resetSmellsSessionState();
|
|
6553
|
+
resetSituationalToolTelemetry();
|
|
6554
|
+
resetWorkspaceDiagnosticsCacheSession(sessionStartMs);
|
|
6555
|
+
}
|
|
6303
6556
|
function readSubstituteGuidance(isEnabled) {
|
|
6304
6557
|
const units = [];
|
|
6305
6558
|
if (isEnabled("symbol_search")) {
|
|
@@ -6411,8 +6664,8 @@ async function handleSessionStart(deps) {
|
|
|
6411
6664
|
try {
|
|
6412
6665
|
warmupDbg("warmup: starting background warmup");
|
|
6413
6666
|
const scanContextStartedAt = Date.now();
|
|
6414
|
-
const startupScanModule = await import("../chunk-
|
|
6415
|
-
const languageProfileModule = await import("../chunk-
|
|
6667
|
+
const startupScanModule = await import("../chunk-GSLNCYGG.js");
|
|
6668
|
+
const languageProfileModule = await import("../chunk-AMERCH6V.js");
|
|
6416
6669
|
const warmupSnapshotRoot = resolveSnapshotRoot(warmupCwd);
|
|
6417
6670
|
const cachedSnapshot = loadProjectSnapshot(warmupSnapshotRoot);
|
|
6418
6671
|
warmupOwnSnapshotRead = cachedSnapshot ? {
|
|
@@ -6546,32 +6799,7 @@ async function handleSessionStart(deps) {
|
|
|
6546
6799
|
clearAllSessions();
|
|
6547
6800
|
runtime.complexityBaselines.clear();
|
|
6548
6801
|
resetDispatchBaselines2(ctxCwd);
|
|
6549
|
-
|
|
6550
|
-
resetOpaqueMutationState();
|
|
6551
|
-
resetObservedMutationNet();
|
|
6552
|
-
resetMutationAttribution();
|
|
6553
|
-
primePersistedMutationAttribution(ctxCwd);
|
|
6554
|
-
resetPendingAuxiliaryCoverage();
|
|
6555
|
-
resetSafeSpawnWindowsCommandCache();
|
|
6556
|
-
resetDispatchAvailabilityState();
|
|
6557
|
-
resetObservedRunnerLatency();
|
|
6558
|
-
resetPendingRunnerFindings();
|
|
6559
|
-
resetSpawnTimeoutCooldowns();
|
|
6560
|
-
clearFormatterCache();
|
|
6561
|
-
resetZizmorTokenAvailability();
|
|
6562
|
-
resetGoAvailability();
|
|
6563
|
-
resetRustAvailability();
|
|
6564
|
-
resetPsScriptAnalyzerAvailability();
|
|
6565
|
-
resetInstallRetryLatches();
|
|
6566
|
-
resetLazyInstallAttempts();
|
|
6567
|
-
resetDirectLspCommandAvailability();
|
|
6568
|
-
resetLSPCaseSensitivityState();
|
|
6569
|
-
resetResolvedPathCache();
|
|
6570
|
-
_resetPackageManagerCache();
|
|
6571
|
-
resetManagedToolRefreshSession();
|
|
6572
|
-
resetSmellsSessionState();
|
|
6573
|
-
resetSituationalToolTelemetry();
|
|
6574
|
-
resetWorkspaceDiagnosticsCacheSession(sessionStartMs);
|
|
6802
|
+
resetSessionScopedState(ctxCwd, sessionStartMs);
|
|
6575
6803
|
deps.bootstrap.peek()?.knipClient.resetSessionState?.();
|
|
6576
6804
|
resetCascadeTierSessionState();
|
|
6577
6805
|
runtime.resetForSession(sessionStartMs);
|
|
@@ -6958,10 +7186,8 @@ async function handleSessionStart(deps) {
|
|
|
6958
7186
|
dbg("session_start: no language defaults selected for pre-install");
|
|
6959
7187
|
}
|
|
6960
7188
|
const startupScansEnabled = deps.projectConfig?.startup?.scans?.enabled ?? deps.globalConfig?.startup?.scans?.enabled ?? true;
|
|
6961
|
-
const startupScansWillRun = allowBootstrapTasks && startupScan.canWarmCaches && startupScansEnabled;
|
|
6962
|
-
const jstsHeavyScansWillRun = startupScansWillRun && canRunStartupHeavyScans(languageProfile, "jsts");
|
|
6963
7189
|
if (allowBootstrapTasks) {
|
|
6964
|
-
scheduleDeferredToolProbes(deps, languageProfile, startupDefaults,
|
|
7190
|
+
scheduleDeferredToolProbes(deps, languageProfile, startupDefaults, dbg);
|
|
6965
7191
|
scheduleManagedToolRefresh(dbg);
|
|
6966
7192
|
}
|
|
6967
7193
|
if (allowBootstrapTasks) {
|
|
@@ -7332,6 +7558,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7332
7558
|
const cwd = path15.resolve(args.cwd);
|
|
7333
7559
|
const records = [...args.dispatchWarnings];
|
|
7334
7560
|
const lspService = getLSPService();
|
|
7561
|
+
const excludeServerIds = args.getFlag ? configDisabledAuxiliaryLspServerIds(args.getFlag) : void 0;
|
|
7335
7562
|
const observedAtByPath = /* @__PURE__ */ new Map();
|
|
7336
7563
|
const buildStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7337
7564
|
logActionableWarningsEvent({
|
|
@@ -7401,6 +7628,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7401
7628
|
const pullTimeoutMs = boundedNumber(args.lspPullTimeoutMs, ACTIONABLE_WARNINGS_LSP_PULL_TIMEOUT_MS);
|
|
7402
7629
|
const inBandDeps = {
|
|
7403
7630
|
lspService,
|
|
7631
|
+
excludeServerIds,
|
|
7404
7632
|
pullTimeoutMs,
|
|
7405
7633
|
// #2504 review round 4 (F2). This is the AWAITED hook: the batch
|
|
7406
7634
|
// budget has to bound what happens INSIDE a file, not only how many
|
|
@@ -7448,6 +7676,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7448
7676
|
const loopSignal = combineAbortSignals(args.signal, deferredSignal) ?? deferredSignal;
|
|
7449
7677
|
const deferredDeps = {
|
|
7450
7678
|
lspService,
|
|
7679
|
+
excludeServerIds,
|
|
7451
7680
|
pullTimeoutMs,
|
|
7452
7681
|
signal: loopSignal,
|
|
7453
7682
|
// OFF the hook by construction: this loop is the answer to
|
|
@@ -7562,7 +7791,7 @@ async function enrichFileFromLsp(cwd, args, target, deps) {
|
|
|
7562
7791
|
return out;
|
|
7563
7792
|
}
|
|
7564
7793
|
}
|
|
7565
|
-
const pulled = await boundedLspCall(() => lspService.getDiagnostics(filePath), deps);
|
|
7794
|
+
const pulled = await boundedLspCall(() => lspService.getDiagnostics(filePath, "full", deps.excludeServerIds), deps);
|
|
7566
7795
|
if (pulled === void 0) {
|
|
7567
7796
|
logActionableWarningsEvent({
|
|
7568
7797
|
event: "lsp_file_skipped",
|
|
@@ -8119,8 +8348,8 @@ var MAX_FAILURE_TRACKER_SIZE = 200;
|
|
|
8119
8348
|
var recentOldTextFailures = new BoundedFifoMap(MAX_FAILURE_TRACKER_SIZE);
|
|
8120
8349
|
|
|
8121
8350
|
// dist/clients/deferred-runner-blockers.js
|
|
8122
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
8123
8351
|
import * as fs14 from "node:fs";
|
|
8352
|
+
import { resolve as resolve9 } from "node:path";
|
|
8124
8353
|
function judgeDeferredRunnerFindings(pending2, cwd, options = {}) {
|
|
8125
8354
|
const findings = pending2.result?.diagnostics ?? [];
|
|
8126
8355
|
if (findings.length === 0) {
|
|
@@ -8161,7 +8390,7 @@ function judgeDeferredRunnerFindings(pending2, cwd, options = {}) {
|
|
|
8161
8390
|
};
|
|
8162
8391
|
}
|
|
8163
8392
|
function recordDeferredRunnerBlockers(runtime, pending2, survivors, bytes) {
|
|
8164
|
-
const blocking = survivors.flatMap((d) => d.semantic === "blocking" ? [d] : []);
|
|
8393
|
+
const blocking = stampLineHashes(withoutLaneCopies(runtime, pending2, survivors).flatMap((d) => d.semantic === "blocking" ? [{ ...d, runnerId: d.runnerId ?? pending2.runnerId }] : []), bytes?.toString("utf-8"), (d) => !d.filePath || resolve9(d.filePath) === resolve9(pending2.filePath));
|
|
8165
8394
|
if (blocking.length === 0)
|
|
8166
8395
|
return 0;
|
|
8167
8396
|
const recorded = runtime.recordDeferredInlineBlockers(pending2.filePath, blocking, {
|
|
@@ -8169,7 +8398,7 @@ function recordDeferredRunnerBlockers(runtime, pending2, survivors, bytes) {
|
|
|
8169
8398
|
...bytes ? {
|
|
8170
8399
|
contentBaseline: {
|
|
8171
8400
|
size: bytes.byteLength,
|
|
8172
|
-
sha256:
|
|
8401
|
+
sha256: hashContentBytes(bytes)
|
|
8173
8402
|
}
|
|
8174
8403
|
} : {}
|
|
8175
8404
|
});
|
|
@@ -8177,6 +8406,36 @@ function recordDeferredRunnerBlockers(runtime, pending2, survivors, bytes) {
|
|
|
8177
8406
|
runtime.updateGitGuardStatus(false, "");
|
|
8178
8407
|
return recorded;
|
|
8179
8408
|
}
|
|
8409
|
+
function retireSettledRunnerBlockers(runtime, pending2, verdict) {
|
|
8410
|
+
const result = pending2.result;
|
|
8411
|
+
if (!result || reachedNoVerdict(result) || result.coveredBy !== void 0 && result.skipReason === "covered-by-primary")
|
|
8412
|
+
return 0;
|
|
8413
|
+
const bytes = readBytes(pending2.filePath);
|
|
8414
|
+
const retired = runtime.retireUnobservedRunnerBlockers(pending2.filePath, {
|
|
8415
|
+
runnerId: pending2.runnerId,
|
|
8416
|
+
// #4484 round 3: what the run's edit-range gate withheld is still
|
|
8417
|
+
// observed, at its own line.
|
|
8418
|
+
observed: [
|
|
8419
|
+
...withoutLaneCopies(runtime, pending2, verdict.kept),
|
|
8420
|
+
...result.outOfEditScope ?? []
|
|
8421
|
+
].flatMap((d) => d.semantic === "blocking" ? [d] : []),
|
|
8422
|
+
markedAtMs: pending2.markedAtMs,
|
|
8423
|
+
sha256: bytes ? hashContentBytes(bytes) : void 0,
|
|
8424
|
+
...result.unconfirmedServerIds !== void 0 && {
|
|
8425
|
+
unconfirmedServerIds: result.unconfirmedServerIds
|
|
8426
|
+
}
|
|
8427
|
+
});
|
|
8428
|
+
if (retired > 0)
|
|
8429
|
+
runtime.updateGitGuardStatus(false, "");
|
|
8430
|
+
return retired;
|
|
8431
|
+
}
|
|
8432
|
+
function withoutLaneCopies(runtime, pending2, findings) {
|
|
8433
|
+
const lane = pending2.result?.coveredBy;
|
|
8434
|
+
if (lane === void 0)
|
|
8435
|
+
return findings;
|
|
8436
|
+
const standsFor = laneCopyStandsFor((runtime.getInlineBlockerDiagnostics(pending2.filePath) ?? []).flatMap((d) => d.runnerId === lane.runnerId && (lane.serverId === void 0 || d.serverId === lane.serverId) ? [d] : []));
|
|
8437
|
+
return findings.flatMap((d) => standsFor(d) ? [] : [d]);
|
|
8438
|
+
}
|
|
8180
8439
|
function readBytes(filePath) {
|
|
8181
8440
|
try {
|
|
8182
8441
|
return fs14.readFileSync(filePath);
|
|
@@ -8838,7 +9097,7 @@ function stillReportedParked(parked, current, keyOf, offeredKeys) {
|
|
|
8838
9097
|
}
|
|
8839
9098
|
|
|
8840
9099
|
// dist/clients/knip-scan-roots.js
|
|
8841
|
-
import { resolve as
|
|
9100
|
+
import { resolve as resolve14 } from "node:path";
|
|
8842
9101
|
var MAX_KNIP_ROOTS_PER_TURN = 3;
|
|
8843
9102
|
function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
8844
9103
|
const session = resolveGitCheckout(sessionCwd);
|
|
@@ -8848,7 +9107,7 @@ function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
|
8848
9107
|
let sessionOwnsEdit = false;
|
|
8849
9108
|
const linked = [];
|
|
8850
9109
|
for (const file of modifiedFiles) {
|
|
8851
|
-
const owner = resolveLinkedWorktreeOwner(session,
|
|
9110
|
+
const owner = resolveLinkedWorktreeOwner(session, resolve14(sessionCwd, file));
|
|
8852
9111
|
if (owner === null) {
|
|
8853
9112
|
sessionOwnsEdit = true;
|
|
8854
9113
|
} else if (!linked.some((known) => pathsEqual(known.root, owner.root))) {
|
|
@@ -9110,7 +9369,7 @@ function selectPersistentReverifyFiles(report, nowMs = Date.now()) {
|
|
|
9110
9369
|
} catch {
|
|
9111
9370
|
continue;
|
|
9112
9371
|
}
|
|
9113
|
-
if (mtimeMs
|
|
9372
|
+
if (freshnessFromMtime({ mtimeMs, referenceMs: stamp, toleranceMs: 0 }).verdict === "stale") {
|
|
9114
9373
|
skippedChanged += 1;
|
|
9115
9374
|
continue;
|
|
9116
9375
|
}
|
|
@@ -9501,6 +9760,10 @@ function lateDeadCodeScansOf(scope) {
|
|
|
9501
9760
|
function joinedEarlierScan(result, askedAt) {
|
|
9502
9761
|
return result.scannedAt !== void 0 && Date.parse(result.scannedAt) < askedAt;
|
|
9503
9762
|
}
|
|
9763
|
+
var KNIP_CARRIED_FILES = "knip-carried-files";
|
|
9764
|
+
function knipCarriedFilesOf(scope) {
|
|
9765
|
+
return scopeCell(scope, KNIP_CARRIED_FILES, () => /* @__PURE__ */ new Map());
|
|
9766
|
+
}
|
|
9504
9767
|
function withRowForFailureWrite(scan, cacheManager2, cacheKey, cwd, startRow) {
|
|
9505
9768
|
return scan.then((result) => result.success || startRow?.data.success === true ? { result, row: startRow } : cacheManager2.readCacheAsync(cacheKey, cwd).then((row) => ({ result, row })));
|
|
9506
9769
|
}
|
|
@@ -9844,6 +10107,7 @@ async function handleTurnEnd(deps) {
|
|
|
9844
10107
|
let runnerFindingsFailed = 0;
|
|
9845
10108
|
let runnerFindingsDropped = 0;
|
|
9846
10109
|
let runnerBlockersRecorded = 0;
|
|
10110
|
+
let runnerBlockersRetired = 0;
|
|
9847
10111
|
let runnerFindingsDispositionSuppressed = 0;
|
|
9848
10112
|
const runnerFindingsDeliveredIds = [];
|
|
9849
10113
|
for (const pending2 of pendingRunnerFindings) {
|
|
@@ -9870,6 +10134,7 @@ async function handleTurnEnd(deps) {
|
|
|
9870
10134
|
dropStaleRunnerFindings(pending2);
|
|
9871
10135
|
runnerFindingsDropped += 1;
|
|
9872
10136
|
}
|
|
10137
|
+
runnerBlockersRetired += retireSettledRunnerBlockers(runtime, pending2, verdict);
|
|
9873
10138
|
if (verdict.live === 0)
|
|
9874
10139
|
continue;
|
|
9875
10140
|
const displayPath = toRunnerDisplayPath(cwd, pending2.filePath);
|
|
@@ -9915,6 +10180,7 @@ ${lines.join("\n")}`;
|
|
|
9915
10180
|
failed: runnerFindingsFailed,
|
|
9916
10181
|
dropped: runnerFindingsDropped,
|
|
9917
10182
|
blockersRecorded: runnerBlockersRecorded,
|
|
10183
|
+
blockersRetired: runnerBlockersRetired,
|
|
9918
10184
|
dispositionSuppressed: runnerFindingsDispositionSuppressed,
|
|
9919
10185
|
deliveredIds: runnerFindingsDeliveredIds
|
|
9920
10186
|
}
|
|
@@ -10081,6 +10347,7 @@ ${policy.body}`);
|
|
|
10081
10347
|
durationMs: Date.now() - cascadeSettleStart,
|
|
10082
10348
|
metadata: { settled, timedOut }
|
|
10083
10349
|
});
|
|
10350
|
+
peekOutstandingCascadeTouches(holdScope);
|
|
10084
10351
|
const t0 = Date.now();
|
|
10085
10352
|
const cascadeRuns = (holdScope.guardedWrite("turn-end:cascade-runs", () => runtime.consumeCascadeRuns()) ?? []).filter((run) => {
|
|
10086
10353
|
const originSeq = run.origin?.projectSeq;
|
|
@@ -10133,40 +10400,91 @@ ${policy.body}`);
|
|
|
10133
10400
|
}
|
|
10134
10401
|
}
|
|
10135
10402
|
const cascadeLogFilePath = cascadeResults[0]?.filePath ?? files[0] ?? cwd;
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10403
|
+
const cascadeTurn = runtime.turnIndex;
|
|
10404
|
+
const editedKeys = /* @__PURE__ */ new Set();
|
|
10405
|
+
for (const file of files) {
|
|
10406
|
+
const absolute = path24.resolve(cwd, file);
|
|
10407
|
+
editedKeys.add(normalizeMapKey(absolute));
|
|
10408
|
+
forgetCascadePendingNeighbor(absolute);
|
|
10409
|
+
}
|
|
10410
|
+
const seen = /* @__PURE__ */ new Map();
|
|
10411
|
+
for (const result of cascadeResults) {
|
|
10412
|
+
seen.set(normalizeMapKey(result.filePath), result);
|
|
10413
|
+
}
|
|
10414
|
+
const keptResults = new Set(seen.values());
|
|
10415
|
+
const lastObserver = /* @__PURE__ */ new Map();
|
|
10416
|
+
for (const run of [...cascadeRuns].reverse()) {
|
|
10417
|
+
if (run.result && !keptResults.has(run.result))
|
|
10418
|
+
continue;
|
|
10419
|
+
for (const neighborPath of [
|
|
10420
|
+
...(run.result?.neighbors ?? []).map((n) => n.filePath),
|
|
10421
|
+
...run.observedNeighborPaths ?? []
|
|
10422
|
+
]) {
|
|
10423
|
+
const nk = normalizeMapKey(neighborPath);
|
|
10424
|
+
if (!lastObserver.has(nk))
|
|
10425
|
+
lastObserver.set(nk, { run, filePath: neighborPath });
|
|
10149
10426
|
}
|
|
10427
|
+
}
|
|
10428
|
+
for (const [nk, { run, filePath }] of lastObserver) {
|
|
10429
|
+
const observedClean = run.observedNeighborPaths?.some((p) => normalizeMapKey(p) === nk) && !run.result?.neighbors.some((n) => normalizeMapKey(n.filePath) === nk && n.diagnostics.length > 0);
|
|
10430
|
+
if (observedClean)
|
|
10431
|
+
forgetCascadePendingNeighbor(filePath);
|
|
10432
|
+
}
|
|
10433
|
+
if (cascadeResults.length > 0) {
|
|
10150
10434
|
const parts = [];
|
|
10151
10435
|
const sectionRuns = [];
|
|
10152
10436
|
let injectedNeighborCount = 0;
|
|
10153
10437
|
let injectedDiagnosticCount = 0;
|
|
10154
10438
|
let suppressedByOwnership = 0;
|
|
10439
|
+
const sectionObservations = [];
|
|
10440
|
+
const shownUnansweredServerIds = /* @__PURE__ */ new Set();
|
|
10441
|
+
const unansweredLines = [];
|
|
10155
10442
|
for (const result of seen.values()) {
|
|
10156
|
-
const
|
|
10157
|
-
const ownsAny =
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
if (
|
|
10164
|
-
|
|
10443
|
+
const ownedNeighbors = result.neighbors.filter((n) => lastObserver.get(normalizeMapKey(n.filePath))?.run.result === result);
|
|
10444
|
+
const ownsAny = ownedNeighbors.length > 0;
|
|
10445
|
+
let rendered = ownsAny && result.formatted ? renderCascadeResult(result, shownUnansweredServerIds) : void 0;
|
|
10446
|
+
const layout = result.layout;
|
|
10447
|
+
if (rendered && layout) {
|
|
10448
|
+
const since = (n, d) => cascadeStillPresentSince(n.filePath, d, cascadeTurn);
|
|
10449
|
+
const relabel = ownedNeighbors.some((n) => n.diagnostics.some((d) => since(n, d) !== void 0));
|
|
10450
|
+
if (relabel || ownedNeighbors.length < result.neighbors.length) {
|
|
10451
|
+
const block = formatCascadeNeighborDiagnostics(layout.cwd, ownedNeighbors, {
|
|
10452
|
+
noun: layout.noun,
|
|
10453
|
+
includeReason: layout.includeReason,
|
|
10454
|
+
stillPresentSince: since
|
|
10455
|
+
});
|
|
10456
|
+
rendered = {
|
|
10457
|
+
...rendered,
|
|
10458
|
+
text: composeCascadeSection(block, layout)
|
|
10459
|
+
};
|
|
10460
|
+
}
|
|
10461
|
+
}
|
|
10462
|
+
if (rendered && (rendered.text || rendered.lines.length > 0)) {
|
|
10463
|
+
unansweredLines.push(...rendered.lines);
|
|
10464
|
+
if (rendered.text) {
|
|
10465
|
+
const carryMeta = carriedMetaByResult.get(result);
|
|
10466
|
+
const carrySuffix = cascadeCarrySuffix(carryMeta?.carriedTurns, carryMeta?.observedAt);
|
|
10467
|
+
parts.push(carrySuffix ? `${rendered.text}
|
|
10468
|
+
${carrySuffix}` : rendered.text);
|
|
10469
|
+
if (carrySuffix)
|
|
10470
|
+
carriedRunsRendered += 1;
|
|
10471
|
+
}
|
|
10165
10472
|
const sectionRun = runByResult.get(result);
|
|
10166
10473
|
if (sectionRun)
|
|
10167
10474
|
sectionRuns.push(sectionRun);
|
|
10168
|
-
|
|
10169
|
-
|
|
10475
|
+
for (const n of ownedNeighbors) {
|
|
10476
|
+
if (n.diagnostics.length === 0)
|
|
10477
|
+
continue;
|
|
10478
|
+
if (editedKeys.has(normalizeMapKey(n.filePath)))
|
|
10479
|
+
continue;
|
|
10480
|
+
sectionObservations.push({
|
|
10481
|
+
filePath: n.filePath,
|
|
10482
|
+
diagnostics: n.diagnostics,
|
|
10483
|
+
checkedAt: sectionRun?.checkedAt
|
|
10484
|
+
});
|
|
10485
|
+
}
|
|
10486
|
+
injectedNeighborCount += ownedNeighbors.length;
|
|
10487
|
+
injectedDiagnosticCount += ownedNeighbors.reduce((s, n) => s + n.diagnostics.length, 0);
|
|
10170
10488
|
} else if (!ownsAny && result.formatted) {
|
|
10171
10489
|
suppressedByOwnership++;
|
|
10172
10490
|
}
|
|
@@ -10200,11 +10518,20 @@ ${testLines.join("\n")}`;
|
|
|
10200
10518
|
parts.push(testSection);
|
|
10201
10519
|
}
|
|
10202
10520
|
}
|
|
10521
|
+
if (unansweredLines.length > 0)
|
|
10522
|
+
parts.unshift(unansweredLines.join("\n"));
|
|
10203
10523
|
if (parts.length > 0) {
|
|
10204
10524
|
const section = parts.join("\n\n");
|
|
10205
10525
|
blockerParts.push(section);
|
|
10526
|
+
const shownServerIds = [...shownUnansweredServerIds];
|
|
10206
10527
|
deliveryHolds.push({
|
|
10207
10528
|
part: section,
|
|
10529
|
+
onDelivered: () => {
|
|
10530
|
+
markCascadeUnansweredPrimariesDelivered(shownServerIds);
|
|
10531
|
+
for (const o of sectionObservations) {
|
|
10532
|
+
recordDeliveredCascadeNeighbor(o.filePath, o.diagnostics, cascadeTurn, o.checkedAt ?? 0);
|
|
10533
|
+
}
|
|
10534
|
+
},
|
|
10208
10535
|
onHeld: () => {
|
|
10209
10536
|
for (const run of sectionRuns)
|
|
10210
10537
|
runtime.appendCascadeRun(run);
|
|
@@ -10233,6 +10560,124 @@ ${testLines.join("\n")}`;
|
|
|
10233
10560
|
}
|
|
10234
10561
|
});
|
|
10235
10562
|
}
|
|
10563
|
+
const pendingCandidates = listCascadePendingNeighbors().filter((entry) => {
|
|
10564
|
+
const key = normalizeMapKey(entry.filePath);
|
|
10565
|
+
if (lastObserver.has(key) || editedKeys.has(key))
|
|
10566
|
+
return false;
|
|
10567
|
+
return isUnderDir(entry.filePath, cwd);
|
|
10568
|
+
});
|
|
10569
|
+
const { "cascade-pending-neighbors": pendingGate } = gateFindingsByPathFreshness({
|
|
10570
|
+
cwd,
|
|
10571
|
+
quiet: true,
|
|
10572
|
+
sources: {
|
|
10573
|
+
"cascade-pending-neighbors": {
|
|
10574
|
+
findings: pendingCandidates,
|
|
10575
|
+
citedPath: (entry) => entry.filePath,
|
|
10576
|
+
scannedAtOf: (entry) => entry.checkedAt
|
|
10577
|
+
}
|
|
10578
|
+
}
|
|
10579
|
+
});
|
|
10580
|
+
const unresolvedNeighbors = pendingGate.live;
|
|
10581
|
+
const changedNeighbors = pendingGate.stale;
|
|
10582
|
+
const gateKept = /* @__PURE__ */ new Set([...unresolvedNeighbors, ...changedNeighbors]);
|
|
10583
|
+
const deletedNeighbors = [];
|
|
10584
|
+
for (const entry of pendingCandidates) {
|
|
10585
|
+
if (gateKept.has(entry))
|
|
10586
|
+
continue;
|
|
10587
|
+
deletedNeighbors.push(entry);
|
|
10588
|
+
forgetCascadePendingNeighbor(entry.filePath);
|
|
10589
|
+
}
|
|
10590
|
+
const maxShown = RUNTIME_CONFIG.pipeline.cascadeMaxFiles;
|
|
10591
|
+
const pendingAge = (checkedAt) => formatCacheAgeLabel(checkedAt > 0 ? checkedAt : void 0);
|
|
10592
|
+
const pendingBlocks = [];
|
|
10593
|
+
let unresolvedShown = 0;
|
|
10594
|
+
if (unresolvedNeighbors.length > 0) {
|
|
10595
|
+
const lines = unresolvedNeighbors.slice(-maxShown).reverse().map((entry) => ` \u2022 ${toRunnerDisplayPath(cwd, entry.filePath)}: ${entry.errorCount} error(s) unresolved (${pendingAge(entry.checkedAt)})`);
|
|
10596
|
+
unresolvedShown = lines.length;
|
|
10597
|
+
const more = unresolvedNeighbors.length - lines.length;
|
|
10598
|
+
if (more > 0)
|
|
10599
|
+
lines.push(` ... and ${more} more neighbor file(s)`);
|
|
10600
|
+
pendingBlocks.push(`\u{1F4D0} Cascade errors from an earlier turn, not re-checked this turn \u2014 still unresolved until a cascade or an edit shows them gone:
|
|
10601
|
+
${lines.join("\n")}`);
|
|
10602
|
+
}
|
|
10603
|
+
const changedShown = changedNeighbors.slice(-maxShown).reverse();
|
|
10604
|
+
if (changedShown.length > 0) {
|
|
10605
|
+
const lines = changedShown.map((entry) => ` \u2022 ${toRunnerDisplayPath(cwd, entry.filePath)}: ${entry.errorCount} error(s) changed since checked (${pendingAge(entry.checkedAt)}), not re-checked`);
|
|
10606
|
+
const more = changedNeighbors.length - changedShown.length;
|
|
10607
|
+
if (more > 0)
|
|
10608
|
+
lines.push(` ... and ${more} more neighbor file(s)`);
|
|
10609
|
+
pendingBlocks.push(`\u{1F4D0} Cascade errors from an earlier turn whose file changed outside pi since they were checked \u2014 not re-checked, named this once:
|
|
10610
|
+
${lines.join("\n")}`);
|
|
10611
|
+
}
|
|
10612
|
+
if (pendingBlocks.length > 0) {
|
|
10613
|
+
const pendingSection = pendingBlocks.join("\n");
|
|
10614
|
+
blockerParts.push(pendingSection);
|
|
10615
|
+
if (changedShown.length > 0) {
|
|
10616
|
+
deliveryHolds.push({
|
|
10617
|
+
part: pendingSection,
|
|
10618
|
+
onDelivered: () => {
|
|
10619
|
+
for (const entry of changedShown) {
|
|
10620
|
+
forgetCascadePendingNeighbor(entry.filePath);
|
|
10621
|
+
}
|
|
10622
|
+
}
|
|
10623
|
+
});
|
|
10624
|
+
}
|
|
10625
|
+
logCascade({
|
|
10626
|
+
phase: "cascade_pending_rendered",
|
|
10627
|
+
filePath: cascadeLogFilePath,
|
|
10628
|
+
metadata: {
|
|
10629
|
+
neighbors: unresolvedNeighbors.length,
|
|
10630
|
+
shown: unresolvedShown,
|
|
10631
|
+
changed: changedShown.length
|
|
10632
|
+
}
|
|
10633
|
+
});
|
|
10634
|
+
}
|
|
10635
|
+
if (changedNeighbors.length + deletedNeighbors.length > 0) {
|
|
10636
|
+
logCascade({
|
|
10637
|
+
phase: "cascade_pending_gated",
|
|
10638
|
+
filePath: cascadeLogFilePath,
|
|
10639
|
+
metadata: {
|
|
10640
|
+
changed: changedNeighbors.length,
|
|
10641
|
+
deleted: deletedNeighbors.length,
|
|
10642
|
+
changedPaths: changedNeighbors.slice(0, 10).map((e) => e.filePath),
|
|
10643
|
+
deletedPaths: deletedNeighbors.slice(0, 10).map((e) => e.filePath)
|
|
10644
|
+
}
|
|
10645
|
+
});
|
|
10646
|
+
}
|
|
10647
|
+
const withCarryLabel = (advisory, runs) => {
|
|
10648
|
+
if (advisory === void 0)
|
|
10649
|
+
return void 0;
|
|
10650
|
+
const carried = runs.filter((r) => (r.carriedTurns ?? 0) > 0);
|
|
10651
|
+
if (carried.length === 0 || carried.length !== runs.length) {
|
|
10652
|
+
return advisory;
|
|
10653
|
+
}
|
|
10654
|
+
const stamps = carried.map((r) => r.observedAt);
|
|
10655
|
+
const observedAt = stamps.every((s) => s !== void 0) ? Math.min(...stamps) : void 0;
|
|
10656
|
+
const suffix = cascadeCarrySuffix(carried[0]?.carriedTurns, observedAt);
|
|
10657
|
+
if (!suffix)
|
|
10658
|
+
return advisory;
|
|
10659
|
+
labeledAdvisories += 1;
|
|
10660
|
+
return `${advisory}
|
|
10661
|
+
${suffix}`;
|
|
10662
|
+
};
|
|
10663
|
+
const holdAdvisory = (advisory, runs, keep) => {
|
|
10664
|
+
if (advisory === void 0)
|
|
10665
|
+
return;
|
|
10666
|
+
deliveryHolds.push({
|
|
10667
|
+
part: advisory,
|
|
10668
|
+
onHeld: () => {
|
|
10669
|
+
for (const run of runs) {
|
|
10670
|
+
const restored = { ...run, result: void 0 };
|
|
10671
|
+
delete restored.observedNeighborPaths;
|
|
10672
|
+
if (keep !== "indeterminate")
|
|
10673
|
+
delete restored.indeterminate;
|
|
10674
|
+
if (keep !== "unconfirmed")
|
|
10675
|
+
delete restored.unconfirmed;
|
|
10676
|
+
runtime.appendCascadeRun(restored);
|
|
10677
|
+
}
|
|
10678
|
+
}
|
|
10679
|
+
});
|
|
10680
|
+
};
|
|
10236
10681
|
const indeterminateRuns = cascadeRuns.filter((r) => r.indeterminate);
|
|
10237
10682
|
if (indeterminateRuns.length > 0) {
|
|
10238
10683
|
const buildAdvisory = (runs, frame) => {
|
|
@@ -10260,47 +10705,20 @@ ${lines.join("\n")}`;
|
|
|
10260
10705
|
const graphRuns = indeterminateRuns.filter((r) => r.indeterminate?.reason !== "lsp_binding_rejected" && r.indeterminate?.reason !== "excluded_by_role" && r.indeterminate?.reason !== "budget_truncated" && r.indeterminate?.budget === void 0);
|
|
10261
10706
|
const bindingRuns = indeterminateRuns.filter((r) => r.indeterminate?.reason === "lsp_binding_rejected" && r.indeterminate?.budget === void 0);
|
|
10262
10707
|
const budgetRuns = indeterminateRuns.filter((r) => r.indeterminate?.reason === "budget_truncated" || r.indeterminate?.budget !== void 0);
|
|
10263
|
-
const withCarryLabel = (advisory, runs) => {
|
|
10264
|
-
if (advisory === void 0)
|
|
10265
|
-
return void 0;
|
|
10266
|
-
const carried = runs.filter((r) => (r.carriedTurns ?? 0) > 0);
|
|
10267
|
-
if (carried.length === 0 || carried.length !== runs.length) {
|
|
10268
|
-
return advisory;
|
|
10269
|
-
}
|
|
10270
|
-
const stamps = carried.map((r) => r.observedAt);
|
|
10271
|
-
const observedAt = stamps.every((s) => s !== void 0) ? Math.min(...stamps) : void 0;
|
|
10272
|
-
const suffix = cascadeCarrySuffix(carried[0]?.carriedTurns, observedAt);
|
|
10273
|
-
if (!suffix)
|
|
10274
|
-
return advisory;
|
|
10275
|
-
labeledAdvisories += 1;
|
|
10276
|
-
return `${advisory}
|
|
10277
|
-
${suffix}`;
|
|
10278
|
-
};
|
|
10279
|
-
const holdAdvisory = (advisory, runs) => {
|
|
10280
|
-
if (advisory === void 0)
|
|
10281
|
-
return;
|
|
10282
|
-
deliveryHolds.push({
|
|
10283
|
-
part: advisory,
|
|
10284
|
-
onHeld: () => {
|
|
10285
|
-
for (const run of runs)
|
|
10286
|
-
runtime.appendCascadeRun({ ...run, result: void 0 });
|
|
10287
|
-
}
|
|
10288
|
-
});
|
|
10289
|
-
};
|
|
10290
10708
|
const graphAdvisory = withCarryLabel(buildAdvisory(graphRuns, {
|
|
10291
10709
|
lead: (fileCount2, reasons) => `Cascade could not compute downstream impact for ${fileCount2} edited file(s) this turn \u2014 the review graph was unavailable (${reasons}), so their dependents were not cascade-checked and a clean cascade result does not cover them.`,
|
|
10292
10710
|
fallbackDetail: (r) => r.indeterminate?.reason === "missing_node" ? "changed file not in the review graph" : "review graph unavailable"
|
|
10293
10711
|
}), graphRuns);
|
|
10294
10712
|
if (graphAdvisory)
|
|
10295
10713
|
advisoryParts.push(graphAdvisory);
|
|
10296
|
-
holdAdvisory(graphAdvisory, graphRuns);
|
|
10714
|
+
holdAdvisory(graphAdvisory, graphRuns, "indeterminate");
|
|
10297
10715
|
const bindingAdvisory = withCarryLabel(buildAdvisory(bindingRuns, {
|
|
10298
10716
|
lead: (fileCount2, reasons) => `Cascade identified dependents for ${fileCount2} edited file(s) this turn, but their diagnostics could not be freshly confirmed (${reasons}) and were withheld \u2014 a clean cascade result does not cover them.`,
|
|
10299
10717
|
fallbackDetail: () => "cascade diagnostics withheld (binding rejected)"
|
|
10300
10718
|
}), bindingRuns);
|
|
10301
10719
|
if (bindingAdvisory)
|
|
10302
10720
|
advisoryParts.push(bindingAdvisory);
|
|
10303
|
-
holdAdvisory(bindingAdvisory, bindingRuns);
|
|
10721
|
+
holdAdvisory(bindingAdvisory, bindingRuns, "indeterminate");
|
|
10304
10722
|
const budgetAdvisory = withCarryLabel(buildAdvisory(budgetRuns, {
|
|
10305
10723
|
lead: (fileCount2, reasons) => `Cascade checked the selected neighbors for ${fileCount2} edited file(s) this turn, but some eligible dependents were not checked because the cascade budget was exhausted (${reasons}); a clean cascade result does not cover them.`,
|
|
10306
10724
|
fallbackDetail: (r) => {
|
|
@@ -10313,7 +10731,7 @@ ${suffix}`;
|
|
|
10313
10731
|
}), budgetRuns);
|
|
10314
10732
|
if (budgetAdvisory)
|
|
10315
10733
|
advisoryParts.push(budgetAdvisory);
|
|
10316
|
-
holdAdvisory(budgetAdvisory, budgetRuns);
|
|
10734
|
+
holdAdvisory(budgetAdvisory, budgetRuns, "indeterminate");
|
|
10317
10735
|
const fileCount = new Set(indeterminateRuns.map((r) => normalizeMapKey(r.filePath))).size;
|
|
10318
10736
|
const byFile = indeterminateRuns.map((r) => ({
|
|
10319
10737
|
file: toRunnerDisplayPath(cwd, r.filePath),
|
|
@@ -10337,6 +10755,57 @@ ${suffix}`;
|
|
|
10337
10755
|
}
|
|
10338
10756
|
});
|
|
10339
10757
|
}
|
|
10758
|
+
const unconfirmedRuns = cascadeRuns.filter((r) => r.unconfirmed);
|
|
10759
|
+
if (unconfirmedRuns.length > 0) {
|
|
10760
|
+
const runOrder = new Map(cascadeRuns.map((r, i) => [r, i]));
|
|
10761
|
+
const byServer = /* @__PURE__ */ new Map();
|
|
10762
|
+
for (const run of unconfirmedRuns) {
|
|
10763
|
+
for (const group of run.unconfirmed?.servers ?? []) {
|
|
10764
|
+
for (const neighborPath of group.paths) {
|
|
10765
|
+
const nk = normalizeMapKey(neighborPath);
|
|
10766
|
+
if (editedKeys.has(nk))
|
|
10767
|
+
continue;
|
|
10768
|
+
const observer = lastObserver.get(nk)?.run;
|
|
10769
|
+
if (observer && (runOrder.get(observer) ?? -1) > (runOrder.get(run) ?? -1))
|
|
10770
|
+
continue;
|
|
10771
|
+
const bucket = byServer.get(group.serverId) ?? {
|
|
10772
|
+
waitMs: group.waitMs,
|
|
10773
|
+
primaries: /* @__PURE__ */ new Set(),
|
|
10774
|
+
paths: /* @__PURE__ */ new Map()
|
|
10775
|
+
};
|
|
10776
|
+
bucket.waitMs = Math.max(bucket.waitMs, group.waitMs);
|
|
10777
|
+
bucket.primaries.add(toRunnerDisplayPath(cwd, run.filePath));
|
|
10778
|
+
bucket.paths.set(nk, toRunnerDisplayPath(cwd, neighborPath));
|
|
10779
|
+
byServer.set(group.serverId, bucket);
|
|
10780
|
+
}
|
|
10781
|
+
}
|
|
10782
|
+
}
|
|
10783
|
+
const capped = (items, max) => items.length > max ? `${items.slice(0, max).join(", ")} (+${items.length - max} more)` : items.join(", ");
|
|
10784
|
+
const blocks = [];
|
|
10785
|
+
let pathCount = 0;
|
|
10786
|
+
for (const [serverId, bucket] of byServer) {
|
|
10787
|
+
const paths = [...bucket.paths.values()];
|
|
10788
|
+
pathCount += paths.length;
|
|
10789
|
+
const within = bucket.waitMs > 0 ? ` within ${bucket.waitMs} ms` : "";
|
|
10790
|
+
blocks.push(`Cascade sent ${paths.length} dependent(s) of ${capped([...bucket.primaries], 3)} to ${serverId}, but no answer arrived${within}; a clean cascade result does not cover them.
|
|
10791
|
+
\u2022 ${serverId}: ${capped(paths, 5)}`);
|
|
10792
|
+
}
|
|
10793
|
+
if (blocks.length > 0) {
|
|
10794
|
+
const pendingAdvisory = withCarryLabel(blocks.join("\n"), unconfirmedRuns);
|
|
10795
|
+
if (pendingAdvisory)
|
|
10796
|
+
advisoryParts.push(pendingAdvisory);
|
|
10797
|
+
holdAdvisory(pendingAdvisory, unconfirmedRuns, "unconfirmed");
|
|
10798
|
+
logCascade({
|
|
10799
|
+
phase: "cascade_unconfirmed_rendered",
|
|
10800
|
+
filePath: cascadeLogFilePath,
|
|
10801
|
+
metadata: {
|
|
10802
|
+
servers: byServer.size,
|
|
10803
|
+
paths: pathCount,
|
|
10804
|
+
runs: unconfirmedRuns.length
|
|
10805
|
+
}
|
|
10806
|
+
});
|
|
10807
|
+
}
|
|
10808
|
+
}
|
|
10340
10809
|
if (carriedRunsRendered > 0 || labeledAdvisories > 0) {
|
|
10341
10810
|
logCascade({
|
|
10342
10811
|
phase: "cascade_carry_rendered",
|
|
@@ -10370,6 +10839,7 @@ ${suffix}`;
|
|
|
10370
10839
|
skipped: cascadeSkipped
|
|
10371
10840
|
}
|
|
10372
10841
|
});
|
|
10842
|
+
const knipCarried = knipCarriedFilesOf(turnScope);
|
|
10373
10843
|
const knipScan = resolveKnipScanRoots(cwd, files);
|
|
10374
10844
|
for (const root of knipScan.overCap) {
|
|
10375
10845
|
incrementDegradationCount({
|
|
@@ -10380,7 +10850,7 @@ ${suffix}`;
|
|
|
10380
10850
|
}
|
|
10381
10851
|
const KNOWN_SLOW_KNIP_GRACE_MS = 1;
|
|
10382
10852
|
const KNIP_MAX_SHOWN = 5;
|
|
10383
|
-
const applyKnipResult = (scanRoot, prevKnip, knipResult, rowNow) => {
|
|
10853
|
+
const applyKnipResult = (scanRoot, prevKnip, knipResult, rowNow, joined) => {
|
|
10384
10854
|
const knipWouldPoison = wouldPoisonCache(rowNow, knipResult);
|
|
10385
10855
|
if (knipWouldPoison) {
|
|
10386
10856
|
dbg(`turn_end: keeping last good knip cache; this run failed: ${knipResult.summary}`);
|
|
@@ -10413,7 +10883,7 @@ ${suffix}`;
|
|
|
10413
10883
|
if (knipResult.success && knipResult.issues.length > 0) {
|
|
10414
10884
|
const issueKey = (i) => stableFindingKey(i.type, i.file, i.name, i.package);
|
|
10415
10885
|
const prevKeys = new Set((prevKnip?.data?.issues ?? []).map(issueKey));
|
|
10416
|
-
const modifiedSet = new Set(files.map((f) => resolveRunnerPath(cwd, f)));
|
|
10886
|
+
const modifiedSet = new Set([...files, ...knipCarried.get(scanRoot) ?? []].map((f) => resolveRunnerPath(cwd, f)));
|
|
10417
10887
|
const newIssues = knipResult.issues.filter((issue) => {
|
|
10418
10888
|
if (prevKeys.has(issueKey(issue)))
|
|
10419
10889
|
return false;
|
|
@@ -10473,6 +10943,13 @@ ${suffix}`;
|
|
|
10473
10943
|
deliveryHolds.push(cutAdvisoryHold("knip", knipAdvisoryLane, report, unusedExportDelta.slice(0, KNIP_MAX_SHOWN), (issue) => reOfferedKeys.has(issueKey(issue))));
|
|
10474
10944
|
}
|
|
10475
10945
|
}
|
|
10946
|
+
if (joined) {
|
|
10947
|
+
const carry = new Set(files);
|
|
10948
|
+
knipCarried.set(scanRoot, carry);
|
|
10949
|
+
knipMeta.joined = true;
|
|
10950
|
+
knipMeta.carried = carry.size;
|
|
10951
|
+
} else if (knipResult.success)
|
|
10952
|
+
knipCarried.delete(scanRoot);
|
|
10476
10953
|
return knipMeta;
|
|
10477
10954
|
};
|
|
10478
10955
|
const logKnipRow = (root, startedAt, metadata) => logLatency({
|
|
@@ -10539,7 +11016,8 @@ ${suffix}`;
|
|
|
10539
11016
|
});
|
|
10540
11017
|
}
|
|
10541
11018
|
} else {
|
|
10542
|
-
|
|
11019
|
+
const joined = scanned.result.success && scanned.result.execution !== "cache" && joinedEarlierScan(scanned.result, startedAt);
|
|
11020
|
+
metadata = applyKnipResult(scanRoot, prevKnip, scanned.result, scanned.row, joined);
|
|
10543
11021
|
}
|
|
10544
11022
|
}
|
|
10545
11023
|
budgetSpent = metadata.execution === "deferred" && (metadata.scanFloorMs === void 0 || metadata.aborted === true);
|
|
@@ -10910,7 +11388,7 @@ ${suffix}`;
|
|
|
10910
11388
|
metadata: madgeStats ?? { skipped: true }
|
|
10911
11389
|
});
|
|
10912
11390
|
if (!getFlag("no-tests") && files.length > 0) {
|
|
10913
|
-
const
|
|
11391
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
10914
11392
|
const targets = [];
|
|
10915
11393
|
const testRootFor = createTurnEndTestRoots(cwd);
|
|
10916
11394
|
const candidates = [];
|
|
@@ -10977,7 +11455,7 @@ ${suffix}`;
|
|
|
10977
11455
|
foreignDeferred++;
|
|
10978
11456
|
continue;
|
|
10979
11457
|
}
|
|
10980
|
-
if (
|
|
11458
|
+
if (seen2.has(carriedKey)) {
|
|
10981
11459
|
resolvedDeferralKeys.add(carriedKey);
|
|
10982
11460
|
continue;
|
|
10983
11461
|
}
|
|
@@ -11021,7 +11499,7 @@ ${suffix}`;
|
|
|
11021
11499
|
continue;
|
|
11022
11500
|
}
|
|
11023
11501
|
resolvedDeferralKeys.add(carriedKey);
|
|
11024
|
-
|
|
11502
|
+
seen2.add(carriedKey);
|
|
11025
11503
|
redispatchedDeferred++;
|
|
11026
11504
|
targets.push({
|
|
11027
11505
|
testFile,
|
|
@@ -11072,8 +11550,8 @@ ${suffix}`;
|
|
|
11072
11550
|
candidatesByRoot.set(testRoot, (candidatesByRoot.get(testRoot) ?? 0) + 1);
|
|
11073
11551
|
const target = testRunnerClient.getTestRunTarget(abs, testRoot, runtime.turnIndex);
|
|
11074
11552
|
const targetKey = target ? normalizeMapKey(target.testFile) : "";
|
|
11075
|
-
if (target && !
|
|
11076
|
-
|
|
11553
|
+
if (target && !seen2.has(targetKey)) {
|
|
11554
|
+
seen2.add(targetKey);
|
|
11077
11555
|
if (retiredKeys.has(targetKey)) {
|
|
11078
11556
|
retiredSkips++;
|
|
11079
11557
|
dbg(`turn_end: ${display} \u2192 test target retired earlier this session (outran the turn-end batch budget), skipping spawn (${path24.relative(cwd, target.testFile)})`);
|
|
@@ -11474,8 +11952,8 @@ ${suffix}`;
|
|
|
11474
11952
|
} else {
|
|
11475
11953
|
const callGraphStart = Date.now();
|
|
11476
11954
|
try {
|
|
11477
|
-
const { impact, formatImpact, parseSymbolKey } = await import("../chunk-
|
|
11478
|
-
const { callGraphImpactToProjectDiagnostics } = await import("../chunk-
|
|
11955
|
+
const { impact, formatImpact, parseSymbolKey } = await import("../chunk-GMX5OS7B.js");
|
|
11956
|
+
const { callGraphImpactToProjectDiagnostics } = await import("../chunk-MZGQNL3Y.js");
|
|
11479
11957
|
const impactLines = [];
|
|
11480
11958
|
let callGraphDispositionSuppressed = 0;
|
|
11481
11959
|
const impactFindings = [];
|
|
@@ -11598,6 +12076,8 @@ ${impactLines.join("\n")}`;
|
|
|
11598
12076
|
modifiedRangesByFile,
|
|
11599
12077
|
dispatchWarnings: runtime.peekActionableWarnings(sessionId),
|
|
11600
12078
|
includeLspCodeActions: !!getFlag("lens-actionable-warning-actions"),
|
|
12079
|
+
// #4323: the cold LSP read leaves a switched-off Opengrep unstarted.
|
|
12080
|
+
getFlag,
|
|
11601
12081
|
projectSeqStart: runtime.turnStartProjectSeq,
|
|
11602
12082
|
projectSeqEnd: runtime.projectSeq,
|
|
11603
12083
|
// #3676: the quick fix credits its writes with this epoch.
|
|
@@ -11716,31 +12196,7 @@ ${impactLines.join("\n")}`;
|
|
|
11716
12196
|
}
|
|
11717
12197
|
const t5 = Date.now();
|
|
11718
12198
|
try {
|
|
11719
|
-
const
|
|
11720
|
-
for (const warning of runtime.peekCodeQualityWarnings(sessionId)) {
|
|
11721
|
-
const group = qualityWarningsByFile.get(warning.filePath);
|
|
11722
|
-
if (group)
|
|
11723
|
-
group.push(warning);
|
|
11724
|
-
else
|
|
11725
|
-
qualityWarningsByFile.set(warning.filePath, [warning]);
|
|
11726
|
-
}
|
|
11727
|
-
const qualityWarnings = [];
|
|
11728
|
-
let qualityDispositionSuppressed = 0;
|
|
11729
|
-
for (const [filePath, group] of qualityWarningsByFile) {
|
|
11730
|
-
let content;
|
|
11731
|
-
try {
|
|
11732
|
-
content = fs17.readFileSync(filePath, "utf-8");
|
|
11733
|
-
} catch {
|
|
11734
|
-
content = void 0;
|
|
11735
|
-
}
|
|
11736
|
-
const { kept, suppressed } = applyPushedFindingPolicy(group, {
|
|
11737
|
-
cwd,
|
|
11738
|
-
filePath,
|
|
11739
|
-
content
|
|
11740
|
-
});
|
|
11741
|
-
qualityWarnings.push(...kept);
|
|
11742
|
-
qualityDispositionSuppressed += suppressed;
|
|
11743
|
-
}
|
|
12199
|
+
const { kept: qualityWarnings, suppressed: qualityDispositionSuppressed } = applyPushedFindingPolicyByFile(runtime.peekCodeQualityWarnings(sessionId), cwd);
|
|
11744
12200
|
const qualityReport = buildCodeQualityWarningsReport({
|
|
11745
12201
|
cwd,
|
|
11746
12202
|
sessionId: runtime.telemetrySessionId,
|
|
@@ -12468,7 +12924,7 @@ var TurnEndQueue = class {
|
|
|
12468
12924
|
}
|
|
12469
12925
|
};
|
|
12470
12926
|
var turnEndQueue = new TurnEndQueue();
|
|
12471
|
-
var pendingTurnEndDeliveries =
|
|
12927
|
+
var pendingTurnEndDeliveries = new BoundedFifoMap(TURN_END_DELIVERY_MAX);
|
|
12472
12928
|
var inFlightIpcTurnEnds = /* @__PURE__ */ new Map();
|
|
12473
12929
|
async function runTurnEndNowImpl(cwd, files = [], deferredDelivery = false) {
|
|
12474
12930
|
const ctx = await getMcpSessionContext();
|
|
@@ -12546,12 +13002,6 @@ function prunePendingTurnEndDeliveries(now = Date.now()) {
|
|
|
12546
13002
|
pendingTurnEndDeliveries.delete(deliveryId);
|
|
12547
13003
|
}
|
|
12548
13004
|
}
|
|
12549
|
-
while (pendingTurnEndDeliveries.size > TURN_END_DELIVERY_MAX) {
|
|
12550
|
-
const oldest = pendingTurnEndDeliveries.keys().next();
|
|
12551
|
-
if (oldest.done)
|
|
12552
|
-
break;
|
|
12553
|
-
pendingTurnEndDeliveries.delete(oldest.value);
|
|
12554
|
-
}
|
|
12555
13005
|
}
|
|
12556
13006
|
function pendingForCwd(cwd) {
|
|
12557
13007
|
for (const [deliveryId, delivery] of pendingTurnEndDeliveries) {
|
|
@@ -13168,7 +13618,7 @@ function blastReadArgs(graph, normalizedFile) {
|
|
|
13168
13618
|
return { path: normalizedFile, offset: 1, limit };
|
|
13169
13619
|
}
|
|
13170
13620
|
async function computeBlastRadius(graph, normalizedPath, projectRoot, maxDepth) {
|
|
13171
|
-
const { computeTransitiveImpact } = await import("../chunk-
|
|
13621
|
+
const { computeTransitiveImpact } = await import("../chunk-XTFDJI3T.js");
|
|
13172
13622
|
const result = computeTransitiveImpact(graph, normalizedPath, { maxDepth });
|
|
13173
13623
|
const byFile = /* @__PURE__ */ new Map();
|
|
13174
13624
|
for (const hit of result.hits) {
|
|
@@ -13785,7 +14235,7 @@ async function moduleReport(file, cwd, options) {
|
|
|
13785
14235
|
let callGraphIdentity;
|
|
13786
14236
|
let revisionDriftNote;
|
|
13787
14237
|
try {
|
|
13788
|
-
const { getCachedReviewGraph, getReviewGraphCacheIdentity, getReviewGraphSizeSkipVerdict, getReviewGraphRevisionDrift, formatReviewGraphRevisionDriftNote: formatReviewGraphRevisionDriftNote2 } = await import("../chunk-
|
|
14238
|
+
const { getCachedReviewGraph, getReviewGraphCacheIdentity, getReviewGraphSizeSkipVerdict, getReviewGraphRevisionDrift, formatReviewGraphRevisionDriftNote: formatReviewGraphRevisionDriftNote2 } = await import("../chunk-YCWYO6TQ.js");
|
|
13789
14239
|
graph = getCachedReviewGraph(cwd);
|
|
13790
14240
|
graphFileCap = getReviewGraphSizeSkipVerdict(cwd)?.maxFileCount;
|
|
13791
14241
|
const drift = graph ? getReviewGraphRevisionDrift(cwd) : void 0;
|
|
@@ -14569,7 +15019,7 @@ function roleFor(graph, filePath) {
|
|
|
14569
15019
|
return top.length > 0 ? top.map((s) => s.name).join(", ") : void 0;
|
|
14570
15020
|
}
|
|
14571
15021
|
async function computeHubs(graph, degrees, cwd, limit, focusTerms) {
|
|
14572
|
-
const { computeTransitiveImpact } = await import("../chunk-
|
|
15022
|
+
const { computeTransitiveImpact } = await import("../chunk-XTFDJI3T.js");
|
|
14573
15023
|
const ranked = [...graph.fileNodes.entries()].map(([filePath, fileNodeId]) => ({
|
|
14574
15024
|
filePath,
|
|
14575
15025
|
fileNodeId,
|
|
@@ -14821,7 +15271,7 @@ async function projectReport(cwd, options) {
|
|
|
14821
15271
|
const limit = clampLimit(options?.limit);
|
|
14822
15272
|
const focusTerms = normalizeFocus2(options?.focus);
|
|
14823
15273
|
const view = options?.view;
|
|
14824
|
-
const { getCachedReviewGraph, getReviewGraphSizeSkipVerdict, getLastReviewGraphBuildAttempt, buildOrUpdateGraph, isGraphBuildInFlight, getReviewGraphRevisionDrift } = await import("../chunk-
|
|
15274
|
+
const { getCachedReviewGraph, getReviewGraphSizeSkipVerdict, getLastReviewGraphBuildAttempt, buildOrUpdateGraph, isGraphBuildInFlight, getReviewGraphRevisionDrift } = await import("../chunk-YCWYO6TQ.js");
|
|
14825
15275
|
let graph;
|
|
14826
15276
|
try {
|
|
14827
15277
|
graph = getCachedReviewGraph(cwd);
|
|
@@ -14845,7 +15295,7 @@ async function projectReport(cwd, options) {
|
|
|
14845
15295
|
};
|
|
14846
15296
|
}
|
|
14847
15297
|
const previousAttempt = getLastReviewGraphBuildAttempt(cwd);
|
|
14848
|
-
const { FactStore: FactStore2 } = await import("../chunk-
|
|
15298
|
+
const { FactStore: FactStore2 } = await import("../chunk-UMS2MFPZ.js");
|
|
14849
15299
|
const trigger = triggerBackgroundGraphBuild(cwd, {
|
|
14850
15300
|
buildOrUpdateGraph,
|
|
14851
15301
|
isGraphBuildInFlight,
|
|
@@ -14946,7 +15396,7 @@ function renderCompactProjectReport(report) {
|
|
|
14946
15396
|
}
|
|
14947
15397
|
|
|
14948
15398
|
// dist/clients/effective-config.js
|
|
14949
|
-
import * as
|
|
15399
|
+
import * as os2 from "node:os";
|
|
14950
15400
|
import * as path28 from "node:path";
|
|
14951
15401
|
function isEffectiveFileViewError(file) {
|
|
14952
15402
|
return "error" in file;
|
|
@@ -15012,7 +15462,7 @@ function decidedByOrNothing(entry) {
|
|
|
15012
15462
|
}
|
|
15013
15463
|
async function effectiveConfig(options = {}) {
|
|
15014
15464
|
const cwd = options.cwd ?? process.cwd();
|
|
15015
|
-
const homeDir = options.homeDir ??
|
|
15465
|
+
const homeDir = options.homeDir ?? os2.homedir();
|
|
15016
15466
|
const resolveAt = (dir) => resolvePiLensConfig({
|
|
15017
15467
|
cwd: dir,
|
|
15018
15468
|
globalDir: getGlobalPiLensDir(),
|
|
@@ -15126,13 +15576,19 @@ function recentLatency(limit = 5, fileFilter) {
|
|
|
15126
15576
|
}
|
|
15127
15577
|
return reports.slice(-limit).reverse();
|
|
15128
15578
|
}
|
|
15129
|
-
function projectScan(cwd, maxFiles, includeGenerated) {
|
|
15130
|
-
|
|
15579
|
+
async function projectScan(cwd, maxFiles, includeGenerated) {
|
|
15580
|
+
const scan = await scanProjectDiagnostics({
|
|
15131
15581
|
cwd,
|
|
15132
15582
|
tier: "cheap",
|
|
15133
15583
|
maxFiles,
|
|
15134
15584
|
includeGenerated
|
|
15135
15585
|
});
|
|
15586
|
+
const policy = applyPushedFindingPolicyByFile(scan.diagnostics, cwd);
|
|
15587
|
+
return {
|
|
15588
|
+
...scan,
|
|
15589
|
+
diagnostics: policy.kept,
|
|
15590
|
+
dispositionSuppressed: policy.suppressed
|
|
15591
|
+
};
|
|
15136
15592
|
}
|
|
15137
15593
|
function scanTruncationNotice(snapshot) {
|
|
15138
15594
|
if (!snapshot.scanTruncated)
|
|
@@ -15264,7 +15720,7 @@ async function symbolSearch(query, cwd, limit = 20, options = {}) {
|
|
|
15264
15720
|
warmLease.release();
|
|
15265
15721
|
}
|
|
15266
15722
|
const hits = results.map(toSymbolSearchHit);
|
|
15267
|
-
const { getCachedReviewGraph } = await import("../chunk-
|
|
15723
|
+
const { getCachedReviewGraph } = await import("../chunk-YCWYO6TQ.js");
|
|
15268
15724
|
const graph = getCachedReviewGraph(cwd);
|
|
15269
15725
|
if (graph)
|
|
15270
15726
|
annotateSymbolSearchHitsWithGraph(hits, centrality, graph);
|
|
@@ -15461,10 +15917,12 @@ function canonicalLanguage(lang) {
|
|
|
15461
15917
|
}
|
|
15462
15918
|
|
|
15463
15919
|
// dist/tools/shared.js
|
|
15920
|
+
import * as path31 from "node:path";
|
|
15464
15921
|
function resolveAstGrepPaths(paths, cwd) {
|
|
15465
15922
|
const base = cwd || ".";
|
|
15466
|
-
|
|
15467
|
-
|
|
15923
|
+
if (!paths?.length)
|
|
15924
|
+
return [path31.resolve(base)];
|
|
15925
|
+
return paths.map((p) => resolveHostToolPath(p, base));
|
|
15468
15926
|
}
|
|
15469
15927
|
var LANGUAGES = [
|
|
15470
15928
|
"bash",
|
|
@@ -16414,7 +16872,7 @@ ${hint}` : `${output}${paginationNote}`;
|
|
|
16414
16872
|
// dist/tools/lens-diagnostics.js
|
|
16415
16873
|
import { promises as fs23 } from "node:fs";
|
|
16416
16874
|
import * as fsSync from "node:fs";
|
|
16417
|
-
import * as
|
|
16875
|
+
import * as path38 from "node:path";
|
|
16418
16876
|
|
|
16419
16877
|
// dist/clients/project-diagnostics/extractors.js
|
|
16420
16878
|
var WARM_TRIGGER = {
|
|
@@ -16473,13 +16931,13 @@ function reasonFromAvailabilityVerdict(tool, verdict) {
|
|
|
16473
16931
|
|
|
16474
16932
|
// dist/clients/project-diagnostics/fresh-fetch.js
|
|
16475
16933
|
import * as fs21 from "node:fs";
|
|
16476
|
-
import * as
|
|
16477
|
-
import * as
|
|
16934
|
+
import * as os3 from "node:os";
|
|
16935
|
+
import * as path36 from "node:path";
|
|
16478
16936
|
|
|
16479
16937
|
// dist/clients/project-diagnostics/runner-adapters/jscpd.js
|
|
16480
|
-
import * as
|
|
16938
|
+
import * as path32 from "node:path";
|
|
16481
16939
|
function resolveClonePath(cwd, file) {
|
|
16482
|
-
return
|
|
16940
|
+
return path32.isAbsolute(file) ? file : path32.resolve(cwd, file);
|
|
16483
16941
|
}
|
|
16484
16942
|
function jscpdCloneToProjectDiagnostics(cwd, clone) {
|
|
16485
16943
|
const a = resolveClonePath(cwd, clone.fileA);
|
|
@@ -16492,7 +16950,7 @@ function jscpdCloneToProjectDiagnostics(cwd, clone) {
|
|
|
16492
16950
|
tool: "jscpd",
|
|
16493
16951
|
runner: "jscpd",
|
|
16494
16952
|
rule: "jscpd:duplicate",
|
|
16495
|
-
message: `Duplicate code (${clone.lines} lines) \u2014 also at ${
|
|
16953
|
+
message: `Duplicate code (${clone.lines} lines) \u2014 also at ${path32.relative(cwd, otherFile)}:${otherLine}`,
|
|
16496
16954
|
source: "project-scan"
|
|
16497
16955
|
});
|
|
16498
16956
|
return [
|
|
@@ -16507,16 +16965,16 @@ function jscpdResultToProjectDiagnostics(cwd, result) {
|
|
|
16507
16965
|
}
|
|
16508
16966
|
|
|
16509
16967
|
// dist/clients/project-diagnostics/runner-adapters/madge.js
|
|
16510
|
-
import * as
|
|
16968
|
+
import * as path33 from "node:path";
|
|
16511
16969
|
function resolveCyclePath(cwd, file) {
|
|
16512
|
-
return
|
|
16970
|
+
return path33.isAbsolute(file) ? file : path33.resolve(cwd, file);
|
|
16513
16971
|
}
|
|
16514
16972
|
function cycleMembers(dep) {
|
|
16515
16973
|
return dep.path.length > 0 ? dep.path : [dep.file];
|
|
16516
16974
|
}
|
|
16517
16975
|
function circularDepToProjectDiagnostics(cwd, dep) {
|
|
16518
16976
|
const members = cycleMembers(dep);
|
|
16519
|
-
const rendered = `${members.map((f) =>
|
|
16977
|
+
const rendered = `${members.map((f) => path33.basename(f)).join(" \u2192 ")} \u2192 ${path33.basename(members[0] ?? "")}`;
|
|
16520
16978
|
return members.map((file) => ({
|
|
16521
16979
|
filePath: resolveCyclePath(cwd, file),
|
|
16522
16980
|
severity: "warning",
|
|
@@ -16542,7 +17000,7 @@ function circularDepsToProjectDiagnostics(cwd, circular) {
|
|
|
16542
17000
|
}
|
|
16543
17001
|
|
|
16544
17002
|
// dist/clients/project-diagnostics/runner-adapters/opengrep.js
|
|
16545
|
-
import * as
|
|
17003
|
+
import * as path34 from "node:path";
|
|
16546
17004
|
function severityFor(raw) {
|
|
16547
17005
|
switch (raw.toUpperCase()) {
|
|
16548
17006
|
case "ERROR":
|
|
@@ -16557,7 +17015,7 @@ function opengrepFindingToProjectDiagnostic(cwd, finding) {
|
|
|
16557
17015
|
const { severity, blocking } = severityFor(finding.severity);
|
|
16558
17016
|
const cweSuffix = finding.cwe?.length ? ` (${finding.cwe[0]})` : "";
|
|
16559
17017
|
return {
|
|
16560
|
-
filePath:
|
|
17018
|
+
filePath: path34.isAbsolute(finding.path) ? finding.path : path34.resolve(cwd, finding.path),
|
|
16561
17019
|
line: finding.startLine,
|
|
16562
17020
|
column: finding.startCol,
|
|
16563
17021
|
severity,
|
|
@@ -16577,7 +17035,7 @@ function opengrepResultToProjectDiagnostics(cwd, result) {
|
|
|
16577
17035
|
|
|
16578
17036
|
// dist/clients/project-diagnostics/runner-adapters/runner-findings.js
|
|
16579
17037
|
import * as fs20 from "node:fs";
|
|
16580
|
-
import * as
|
|
17038
|
+
import * as path35 from "node:path";
|
|
16581
17039
|
function failureMessage(failure) {
|
|
16582
17040
|
const firstLine2 = failure.message.split("\n")[0]?.slice(0, 300) ?? "";
|
|
16583
17041
|
return firstLine2 ? `${failure.name}: ${firstLine2}` : failure.name;
|
|
@@ -16643,7 +17101,7 @@ function testRunnerFindingsToProjectDiagnostics(cache, cwd, runtime) {
|
|
|
16643
17101
|
return [];
|
|
16644
17102
|
const validation = cwd ? validateAdvisoryProvenance(cache, cwd, runtime) : { status: "unknown", reasons: ["validation-context-missing"] };
|
|
16645
17103
|
const root = cwd ?? process.cwd();
|
|
16646
|
-
const missingKeys = new Set((cache.provenance?.files ?? []).filter((file) => !fs20.existsSync(
|
|
17104
|
+
const missingKeys = new Set((cache.provenance?.files ?? []).filter((file) => !fs20.existsSync(path35.resolve(root, file.path))).map((file) => advisoryPathKey(file.path, root)));
|
|
16647
17105
|
const historical = cache.superseded === true || cache.stale === true || validation.status !== "current";
|
|
16648
17106
|
return cache.results.filter((result) => !missingKeys.has(advisoryPathKey(result.file, root))).flatMap((result) => testResultToProjectDiagnostics(result, historical)).map((diagnostic) => historical ? {
|
|
16649
17107
|
...diagnostic,
|
|
@@ -16673,7 +17131,7 @@ function laneObservedAtMs(scannedAt, startedAtMs) {
|
|
|
16673
17131
|
return parseScannedAtMs(scannedAt) ?? startedAtMs;
|
|
16674
17132
|
}
|
|
16675
17133
|
async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal, options = {}) {
|
|
16676
|
-
const requestedRoot = options.analysisRoot === void 0 ? cwd :
|
|
17134
|
+
const requestedRoot = options.analysisRoot === void 0 ? cwd : path36.resolve(cwd, options.analysisRoot);
|
|
16677
17135
|
let analysisRoot;
|
|
16678
17136
|
let analysisRootValidation;
|
|
16679
17137
|
if (options.analysisRoot !== void 0) {
|
|
@@ -16712,7 +17170,7 @@ async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal,
|
|
|
16712
17170
|
analysisRoot = realpathOrResolve(cwd);
|
|
16713
17171
|
}
|
|
16714
17172
|
const unsafeRootReason = "the analysis root resolves at or above the home directory; heavyweight analyzers refuse to walk from there (#747)";
|
|
16715
|
-
const homeRoot = realpathOrResolve(options.homeDir ??
|
|
17173
|
+
const homeRoot = realpathOrResolve(options.homeDir ?? os3.homedir());
|
|
16716
17174
|
if (options.analysisRoot !== void 0) {
|
|
16717
17175
|
const unsafeExplicitRoot = !isSameOrWithin(homeRoot, analysisRoot) || isSameOrWithin(analysisRoot, homeRoot);
|
|
16718
17176
|
analysisRootValidation = unsafeExplicitRoot ? {
|
|
@@ -16840,7 +17298,7 @@ async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal,
|
|
|
16840
17298
|
markCold("jscpd", reasonFromAvailabilityVerdict("jscpd", clients.jscpdClient.getAvailabilityVerdict?.()));
|
|
16841
17299
|
return;
|
|
16842
17300
|
}
|
|
16843
|
-
const isTsProject = fs21.existsSync(
|
|
17301
|
+
const isTsProject = fs21.existsSync(path36.join(analysisRoot, "tsconfig.json"));
|
|
16844
17302
|
const scannerKey = isTsProject ? "jscpd-ts" : "jscpd";
|
|
16845
17303
|
const startMs = Date.now();
|
|
16846
17304
|
const result = await clients.jscpdClient.scan(analysisRoot, void 0, void 0, isTsProject);
|
|
@@ -17157,7 +17615,7 @@ function makeProgressReporter(onUpdate, label, throttleMs = 250) {
|
|
|
17157
17615
|
|
|
17158
17616
|
// dist/tools/lsp-diagnostics.js
|
|
17159
17617
|
import * as fs22 from "node:fs";
|
|
17160
|
-
import * as
|
|
17618
|
+
import * as path37 from "node:path";
|
|
17161
17619
|
var MAX_FILES = 100;
|
|
17162
17620
|
var MAX_BATCH_FILES = 100;
|
|
17163
17621
|
var MAX_DIAGNOSTICS = 200;
|
|
@@ -17240,11 +17698,11 @@ async function collectFiles(dir, extensions, maxFiles, isIgnored = () => false)
|
|
|
17240
17698
|
return;
|
|
17241
17699
|
if (entry.isSymbolicLink())
|
|
17242
17700
|
continue;
|
|
17243
|
-
const full =
|
|
17701
|
+
const full = path37.join(current, entry.name);
|
|
17244
17702
|
if (entry.isDirectory()) {
|
|
17245
17703
|
if (!isExcludedDirName(entry.name) && !isIgnored(full, true))
|
|
17246
17704
|
await walk(full);
|
|
17247
|
-
} else if (entry.isFile() && extensions.includes(
|
|
17705
|
+
} else if (entry.isFile() && extensions.includes(path37.extname(full))) {
|
|
17248
17706
|
if (isIgnored(full, false))
|
|
17249
17707
|
continue;
|
|
17250
17708
|
files.push(full);
|
|
@@ -17254,7 +17712,7 @@ async function collectFiles(dir, extensions, maxFiles, isIgnored = () => false)
|
|
|
17254
17712
|
await walk(dir);
|
|
17255
17713
|
return files;
|
|
17256
17714
|
}
|
|
17257
|
-
function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getService = getLSPService) {
|
|
17715
|
+
function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getService = getLSPService, getFlag) {
|
|
17258
17716
|
return {
|
|
17259
17717
|
async execute(_toolCallId, params, _signal, onUpdate, ctx) {
|
|
17260
17718
|
const signal = combineAbortSignals(_signal, ctx.signal);
|
|
@@ -17265,6 +17723,7 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17265
17723
|
const concurrency = boundedPositiveInt(typedParams.concurrency, DEFAULT_BATCH_CONCURRENCY, 1, MAX_BATCH_CONCURRENCY);
|
|
17266
17724
|
const waitMs = typeof typedParams.waitMs === "number" && typedParams.waitMs >= 0 ? Math.floor(typedParams.waitMs) : void 0;
|
|
17267
17725
|
const serverScope = typedParams.serverScope === "primary" ? "primary" : "all";
|
|
17726
|
+
const excludeServerIds = getFlag ? configDisabledAuxiliaryLspServerIds((name) => getFlag(name, cwd)) : void 0;
|
|
17268
17727
|
const lspService = getService();
|
|
17269
17728
|
if (!lspService) {
|
|
17270
17729
|
return {
|
|
@@ -17322,7 +17781,8 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17322
17781
|
nextWriteIndex,
|
|
17323
17782
|
serverScope,
|
|
17324
17783
|
cwd,
|
|
17325
|
-
onConfirmedNoBlockers
|
|
17784
|
+
onConfirmedNoBlockers,
|
|
17785
|
+
excludeServerIds
|
|
17326
17786
|
}, expanded);
|
|
17327
17787
|
}
|
|
17328
17788
|
const rawPath = typedParams.path;
|
|
@@ -17338,7 +17798,7 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17338
17798
|
details: {}
|
|
17339
17799
|
};
|
|
17340
17800
|
}
|
|
17341
|
-
const absPath = normalizeMapKey(
|
|
17801
|
+
const absPath = normalizeMapKey(typedParams.pathAlreadyResolved === true ? rawPath : resolveHostToolPath(rawPath, cwd));
|
|
17342
17802
|
let stat;
|
|
17343
17803
|
try {
|
|
17344
17804
|
stat = fs22.statSync(absPath);
|
|
@@ -17360,14 +17820,15 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17360
17820
|
nextWriteIndex,
|
|
17361
17821
|
serverScope,
|
|
17362
17822
|
cwd,
|
|
17363
|
-
onConfirmedNoBlockers
|
|
17823
|
+
onConfirmedNoBlockers,
|
|
17824
|
+
excludeServerIds
|
|
17364
17825
|
});
|
|
17365
17826
|
}
|
|
17366
|
-
return runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope, cwd, onConfirmedNoBlockers);
|
|
17827
|
+
return runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope, cwd, onConfirmedNoBlockers, excludeServerIds);
|
|
17367
17828
|
}
|
|
17368
17829
|
};
|
|
17369
17830
|
}
|
|
17370
|
-
async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs, serverScope = "all") {
|
|
17831
|
+
async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs, serverScope = "all", excludeServerIds) {
|
|
17371
17832
|
let timedOut = false;
|
|
17372
17833
|
let content;
|
|
17373
17834
|
let touched;
|
|
@@ -17432,6 +17893,7 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17432
17893
|
maxClientWaitMs: waitMs,
|
|
17433
17894
|
source: "lsp_diagnostics",
|
|
17434
17895
|
clientScope: serverScope,
|
|
17896
|
+
excludeServerIds,
|
|
17435
17897
|
// #3405: the caller asked whether THIS file is clean right now, and the
|
|
17436
17898
|
// content above was just read from disk — so it is the file's saved
|
|
17437
17899
|
// state. Without the save a save-triggered server answers zero
|
|
@@ -17439,10 +17901,11 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17439
17901
|
// as clean.
|
|
17440
17902
|
saved: true
|
|
17441
17903
|
});
|
|
17442
|
-
timedOut = touched?.inconclusive === true;
|
|
17904
|
+
timedOut = touched?.inconclusive === true && touched.inconclusiveReason !== "primary-unavailable";
|
|
17443
17905
|
} catch {
|
|
17444
17906
|
}
|
|
17445
|
-
const diagnostics = touched !== void 0 ? touched.diags : await lspService.getDiagnostics(absPath, waitMs !== void 0 ? "document" : "full");
|
|
17907
|
+
const diagnostics = touched !== void 0 ? touched.diags : await lspService.getDiagnostics(absPath, waitMs !== void 0 ? "document" : "full", excludeServerIds);
|
|
17908
|
+
const fallbackHealth = touched === void 0 ? lspService.getDiagnosticsHealth?.(absPath) : void 0;
|
|
17446
17909
|
const filtered = content !== void 0 ? applyAuxiliarySuppressions(diagnostics, content, {
|
|
17447
17910
|
fileRole: detectFileRole(absPath, content),
|
|
17448
17911
|
filePath: absPath,
|
|
@@ -17450,11 +17913,18 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17450
17913
|
}) : diagnostics;
|
|
17451
17914
|
const binding = touched?.binding;
|
|
17452
17915
|
const confirmedByTouch = touchCompletedConfirmationPolicy(touched);
|
|
17916
|
+
const primaryUnavailable = describePrimaryUnavailable(touched, fallbackHealth);
|
|
17917
|
+
const noClientAnswered = fallbackHealth !== void 0 && String(fallbackHealth.health ?? "").startsWith("no_clients");
|
|
17453
17918
|
return {
|
|
17454
17919
|
diagnostics: filtered,
|
|
17455
17920
|
timedOut,
|
|
17456
17921
|
skipReason: touched?.skipReason,
|
|
17457
17922
|
confirmedByTouch,
|
|
17923
|
+
...noClientAnswered && { noClientAnswered: true },
|
|
17924
|
+
...primaryUnavailable !== void 0 && {
|
|
17925
|
+
primaryUnavailable: primaryUnavailable.text,
|
|
17926
|
+
primaryUnavailableCause: primaryUnavailable.cause
|
|
17927
|
+
},
|
|
17458
17928
|
// #1470: only a touch that resolved clients contributes a coverage gap;
|
|
17459
17929
|
// the getDiagnostics fallback never reports one, which is honest — that
|
|
17460
17930
|
// path claims no confirmation at all.
|
|
@@ -17464,6 +17934,27 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17464
17934
|
binding
|
|
17465
17935
|
};
|
|
17466
17936
|
}
|
|
17937
|
+
function describePrimaryUnavailable(touched, fallbackHealth) {
|
|
17938
|
+
let serverIds;
|
|
17939
|
+
let disabledServerIds;
|
|
17940
|
+
let carriedCause;
|
|
17941
|
+
if (touched?.inconclusiveReason === "primary-unavailable") {
|
|
17942
|
+
serverIds = touched.inconclusiveServerIds ?? [];
|
|
17943
|
+
disabledServerIds = touched.disabledPrimaryServerIds ?? [];
|
|
17944
|
+
carriedCause = touched.primaryUnavailableCause;
|
|
17945
|
+
} else if (fallbackHealth?.unavailablePrimaryServerIds?.length) {
|
|
17946
|
+
serverIds = fallbackHealth.unavailablePrimaryServerIds;
|
|
17947
|
+
disabledServerIds = fallbackHealth.disabledPrimaryServerIds ?? [];
|
|
17948
|
+
carriedCause = fallbackHealth.primaryUnavailableCause;
|
|
17949
|
+
} else {
|
|
17950
|
+
return void 0;
|
|
17951
|
+
}
|
|
17952
|
+
const cause = carriedCause ?? primaryUnavailableCause(serverIds, disabledServerIds);
|
|
17953
|
+
return {
|
|
17954
|
+
text: `Primary LSP (${serverIds.join(", ")}): not available \u2014 no language server answered for this file (${PRIMARY_UNAVAILABLE_CAUSE[cause]}). NOT the same as 0 diagnostics; auxiliary scanners do not check the language itself.`,
|
|
17955
|
+
cause
|
|
17956
|
+
};
|
|
17957
|
+
}
|
|
17467
17958
|
function diagnosticsToFileDiags(file, diagnostics) {
|
|
17468
17959
|
return diagnostics.map((d) => ({
|
|
17469
17960
|
file,
|
|
@@ -17509,7 +18000,7 @@ async function resolveEmptyResult(file, lspService) {
|
|
|
17509
18000
|
function canTrustTouchConfirmation(file, serverScope, confirmedByTouch) {
|
|
17510
18001
|
return confirmedByTouch && (serverScope === "primary" || primaryServerId(file) !== "typescript");
|
|
17511
18002
|
}
|
|
17512
|
-
function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds) {
|
|
18003
|
+
function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds, excludeServerIds) {
|
|
17513
18004
|
const unconfirmed = new Set(unconfirmedServerIds);
|
|
17514
18005
|
const covered = /* @__PURE__ */ new Set();
|
|
17515
18006
|
let servers = [];
|
|
@@ -17524,6 +18015,8 @@ function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds) {
|
|
|
17524
18015
|
continue;
|
|
17525
18016
|
if (unconfirmed.has(server.id))
|
|
17526
18017
|
continue;
|
|
18018
|
+
if (excludeServerIds?.has(server.id))
|
|
18019
|
+
continue;
|
|
17527
18020
|
covered.add(auxiliary ? server.id : "lsp");
|
|
17528
18021
|
}
|
|
17529
18022
|
return [...covered];
|
|
@@ -17535,7 +18028,7 @@ function demoteInferredForFile(file, diagnostics, cwd, lspService) {
|
|
|
17535
18028
|
service: lspService
|
|
17536
18029
|
});
|
|
17537
18030
|
}
|
|
17538
|
-
function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity) {
|
|
18031
|
+
function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity, toolName = "lsp_diagnostics") {
|
|
17539
18032
|
const started = Date.now();
|
|
17540
18033
|
try {
|
|
17541
18034
|
const result = applyLspFindingPolicy(diagnostics, {
|
|
@@ -17550,7 +18043,7 @@ function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity) {
|
|
|
17550
18043
|
if (suppressed > 0) {
|
|
17551
18044
|
logLatency({
|
|
17552
18045
|
type: "phase",
|
|
17553
|
-
toolName
|
|
18046
|
+
toolName,
|
|
17554
18047
|
filePath: file,
|
|
17555
18048
|
phase: "lsp_probe_disposition_filter",
|
|
17556
18049
|
durationMs: Date.now() - started,
|
|
@@ -17572,15 +18065,11 @@ function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity) {
|
|
|
17572
18065
|
}
|
|
17573
18066
|
}
|
|
17574
18067
|
function replayContentForStrictMarks(file, cwd) {
|
|
17575
|
-
|
|
17576
|
-
return void 0;
|
|
17577
|
-
try {
|
|
17578
|
-
return fs22.readFileSync(file, "utf-8");
|
|
17579
|
-
} catch {
|
|
17580
|
-
return void 0;
|
|
17581
|
-
}
|
|
18068
|
+
return hasStrictDispositionMarks(cwd) ? readFileContent(file) : void 0;
|
|
17582
18069
|
}
|
|
17583
|
-
function reconcileWidgetFromLspResult(file, rawDiags, confirmation, writeIndex, cwd, content, boundMismatch = false, observedAt) {
|
|
18070
|
+
function reconcileWidgetFromLspResult(file, rawDiags, confirmation, writeIndex, cwd, content, boundMismatch = false, observedAt, auxiliariesOnly = false) {
|
|
18071
|
+
if (auxiliariesOnly)
|
|
18072
|
+
return { confirmed: false, blocking: true };
|
|
17584
18073
|
const confirmed = (rawDiags.length > 0 || confirmation !== "unconfirmed") && !boundMismatch;
|
|
17585
18074
|
if (!confirmed)
|
|
17586
18075
|
return { confirmed: false, blocking: true };
|
|
@@ -17597,7 +18086,7 @@ function reconcileWidgetFromLspResult(file, rawDiags, confirmation, writeIndex,
|
|
|
17597
18086
|
return { confirmed: false, blocking: true };
|
|
17598
18087
|
}
|
|
17599
18088
|
}
|
|
17600
|
-
async function collectFileDiagnosticResult(file, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cacheCtx, scopeKey, cwd = process.cwd(), onConfirmedNoBlockers) {
|
|
18089
|
+
async function collectFileDiagnosticResult(file, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cacheCtx, scopeKey, cwd = process.cwd(), onConfirmedNoBlockers, excludeServerIds) {
|
|
17601
18090
|
const writeIndex = nextWriteIndex?.();
|
|
17602
18091
|
const scannedAt = Date.now();
|
|
17603
18092
|
let stat;
|
|
@@ -17641,7 +18130,7 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17641
18130
|
};
|
|
17642
18131
|
}
|
|
17643
18132
|
}
|
|
17644
|
-
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, diagnosticsUnsupportedServerIds, content: collectedContent, binding, tooLargeReason, skipReason } = await collectDiagnosticsForFile(file, lspService, cwd, waitMs, serverScope);
|
|
18133
|
+
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, diagnosticsUnsupportedServerIds, content: collectedContent, binding, tooLargeReason, skipReason, primaryUnavailable, primaryUnavailableCause: primaryUnavailableCause2, noClientAnswered } = await collectDiagnosticsForFile(file, lspService, cwd, waitMs, serverScope, excludeServerIds);
|
|
17645
18134
|
if (tooLargeReason !== void 0) {
|
|
17646
18135
|
return { file, diagnostics: [], outcome: "too_large", tooLargeReason };
|
|
17647
18136
|
}
|
|
@@ -17650,7 +18139,7 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17650
18139
|
let confirmation;
|
|
17651
18140
|
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
17652
18141
|
confirmation = void 0;
|
|
17653
|
-
} else if (skipReason !== void 0) {
|
|
18142
|
+
} else if (skipReason !== void 0 || primaryUnavailable !== void 0) {
|
|
17654
18143
|
confirmation = "unconfirmed";
|
|
17655
18144
|
} else if (timedOut) {
|
|
17656
18145
|
if (applySeverityFilter(rawDiags, severity).length === 0) {
|
|
@@ -17690,13 +18179,14 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17690
18179
|
boundMismatch,
|
|
17691
18180
|
// #3505 r1 F1: the widget row is observed at the read, as the cache
|
|
17692
18181
|
// entry recorded below is.
|
|
17693
|
-
scannedAt
|
|
18182
|
+
scannedAt,
|
|
18183
|
+
primaryUnavailable !== void 0
|
|
17694
18184
|
);
|
|
17695
18185
|
if (verdict.confirmed && !verdict.blocking) {
|
|
17696
18186
|
onConfirmedNoBlockers?.({
|
|
17697
18187
|
filePath: file,
|
|
17698
18188
|
writeIndex,
|
|
17699
|
-
coveredSources: coveredSourcesForCheck(file, serverScope, unconfirmedServerIds),
|
|
18189
|
+
coveredSources: coveredSourcesForCheck(file, serverScope, unconfirmedServerIds, excludeServerIds),
|
|
17700
18190
|
cwd
|
|
17701
18191
|
});
|
|
17702
18192
|
}
|
|
@@ -17711,6 +18201,11 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17711
18201
|
timedOut: confirmation === "unconfirmed" ? timedOut : void 0,
|
|
17712
18202
|
...rootFallback && { rootFallback },
|
|
17713
18203
|
...skipReason !== void 0 && { skipReason },
|
|
18204
|
+
...primaryUnavailable !== void 0 && {
|
|
18205
|
+
primaryUnavailable,
|
|
18206
|
+
primaryUnavailableCause: primaryUnavailableCause2
|
|
18207
|
+
},
|
|
18208
|
+
...noClientAnswered && { noClientAnswered },
|
|
17714
18209
|
primaryServerId: primaryServerId(file),
|
|
17715
18210
|
diagnosticsUnsupported: diagnosticsUnsupportedServerIds.length > 0,
|
|
17716
18211
|
...policy.suppressed > 0 && {
|
|
@@ -17718,10 +18213,14 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17718
18213
|
}
|
|
17719
18214
|
};
|
|
17720
18215
|
}
|
|
17721
|
-
async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cwd = process.cwd(), onConfirmedNoBlockers) {
|
|
18216
|
+
async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cwd = process.cwd(), onConfirmedNoBlockers, excludeServerIds) {
|
|
17722
18217
|
const writeIndex = nextWriteIndex?.();
|
|
18218
|
+
lspService.announceCreatedFiles([
|
|
18219
|
+
...goPackageFilesToAnnounce([absPath]),
|
|
18220
|
+
...await importTargetsToAnnounce(cwd, [absPath])
|
|
18221
|
+
]);
|
|
17723
18222
|
const observedAt = Date.now();
|
|
17724
|
-
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, diagnosticsUnsupportedServerIds, content: collectedContent, binding, tooLargeReason, skipReason } = await collectDiagnosticsForFile(absPath, lspService, cwd, waitMs, serverScope);
|
|
18223
|
+
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, diagnosticsUnsupportedServerIds, content: collectedContent, binding, tooLargeReason, skipReason, primaryUnavailable } = await collectDiagnosticsForFile(absPath, lspService, cwd, waitMs, serverScope, excludeServerIds);
|
|
17725
18224
|
if (tooLargeReason !== void 0) {
|
|
17726
18225
|
return {
|
|
17727
18226
|
content: [{ type: "text", text: tooLargeReason }],
|
|
@@ -17743,7 +18242,7 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17743
18242
|
let confirmation;
|
|
17744
18243
|
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
17745
18244
|
confirmation = void 0;
|
|
17746
|
-
} else if (skipReason !== void 0) {
|
|
18245
|
+
} else if (skipReason !== void 0 || primaryUnavailable !== void 0) {
|
|
17747
18246
|
confirmation = "unconfirmed";
|
|
17748
18247
|
} else if (timedOut) {
|
|
17749
18248
|
if (applySeverityFilter(rawDiags, severity).length === 0) {
|
|
@@ -17777,12 +18276,12 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17777
18276
|
const truncated = total > MAX_DIAGNOSTICS;
|
|
17778
18277
|
const limited = truncated ? filtered.slice(0, MAX_DIAGNOSTICS) : filtered;
|
|
17779
18278
|
const unconfirmed = confirmation === "unconfirmed";
|
|
17780
|
-
const verdict = reconcileWidgetFromLspResult(absPath, effectiveRawDiags, confirmation, writeIndex, cwd, collectedContent, boundMismatch, observedAt);
|
|
18279
|
+
const verdict = reconcileWidgetFromLspResult(absPath, effectiveRawDiags, confirmation, writeIndex, cwd, collectedContent, boundMismatch, observedAt, primaryUnavailable !== void 0);
|
|
17781
18280
|
if (verdict.confirmed && !verdict.blocking) {
|
|
17782
18281
|
onConfirmedNoBlockers?.({
|
|
17783
18282
|
filePath: absPath,
|
|
17784
18283
|
writeIndex,
|
|
17785
|
-
coveredSources: coveredSourcesForCheck(absPath, serverScope, unconfirmedServerIds),
|
|
18284
|
+
coveredSources: coveredSourcesForCheck(absPath, serverScope, unconfirmedServerIds, excludeServerIds),
|
|
17786
18285
|
cwd
|
|
17787
18286
|
});
|
|
17788
18287
|
}
|
|
@@ -17790,6 +18289,8 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17790
18289
|
const primaryDiags = limited.filter((d) => d.serverId === primaryId);
|
|
17791
18290
|
const auxiliaryDiags = limited.filter((d) => d.serverId !== primaryId);
|
|
17792
18291
|
const primaryLine = (() => {
|
|
18292
|
+
if (primaryUnavailable !== void 0)
|
|
18293
|
+
return primaryUnavailable;
|
|
17793
18294
|
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
17794
18295
|
return `Primary LSP${primaryId ? ` (${primaryId})` : ""}: navigation-only \u2014 diagnostics unsupported (no pull provider or publish evidence).`;
|
|
17795
18296
|
}
|
|
@@ -17809,12 +18310,14 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17809
18310
|
})();
|
|
17810
18311
|
const coverageLine = unconfirmedServerIds.length > 0 ? `Auxiliary coverage INCOMPLETE \u2014 ${[...unconfirmedServerIds].join(", ")} did not answer within the wait budget, so ${unconfirmedServerIds.length === 1 ? "its findings are" : "their findings are"} NOT included here. This is not a clean bill of health for ${unconfirmedServerIds.length === 1 ? "that scanner" : "those scanners"}; re-check after the next edit. waitMs can extend an ordinary wait, but it cannot override a session-demoted scanner.` : void 0;
|
|
17811
18312
|
const suppressedLine = dispositionSuppressedLine(policy.suppressed);
|
|
18313
|
+
const switchedOffServerIds = serverScope === "all" && excludeServerIds && excludeServerIds.size > 0 ? getServersForFileWithConfig(absPath).flatMap((server) => excludeServerIds.has(server.id) ? [server.id] : []) : [];
|
|
18314
|
+
const noAuxiliaryLine = switchedOffServerIds.length > 0 ? `No auxiliary findings. Switched off, not run: ${switchedOffServerIds.join(", ")}.` : "No auxiliary findings.";
|
|
17812
18315
|
let text;
|
|
17813
18316
|
if (total === 0) {
|
|
17814
18317
|
text = [
|
|
17815
18318
|
primaryLine,
|
|
17816
18319
|
"",
|
|
17817
|
-
unavailable ??
|
|
18320
|
+
unavailable ?? noAuxiliaryLine,
|
|
17818
18321
|
...coverageLine ? [coverageLine] : [],
|
|
17819
18322
|
...suppressedLine ? [suppressedLine] : []
|
|
17820
18323
|
].join("\n");
|
|
@@ -17866,6 +18369,7 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17866
18369
|
timedOut: unconfirmed ? timedOut : void 0,
|
|
17867
18370
|
navigationOnlyFiles: diagnosticsUnsupportedServerIds.length > 0 ? 1 : void 0,
|
|
17868
18371
|
...skipReason !== void 0 && { skipReason },
|
|
18372
|
+
...primaryUnavailable !== void 0 && { primaryUnavailable },
|
|
17869
18373
|
...rootFallback && {
|
|
17870
18374
|
rootFallbackReason: describeRootFallback(rootFallback)
|
|
17871
18375
|
},
|
|
@@ -17883,6 +18387,8 @@ function tallyConfirmation(results) {
|
|
|
17883
18387
|
let clean = 0;
|
|
17884
18388
|
let unconfirmed = 0;
|
|
17885
18389
|
let timedOut = 0;
|
|
18390
|
+
let primaryUnavailable = 0;
|
|
18391
|
+
const primaryUnavailableCauses = [];
|
|
17886
18392
|
const rootFallbackReasons = /* @__PURE__ */ new Set();
|
|
17887
18393
|
let navigationOnly = 0;
|
|
17888
18394
|
let tooLarge = 0;
|
|
@@ -17901,6 +18407,11 @@ function tallyConfirmation(results) {
|
|
|
17901
18407
|
unconfirmed += 1;
|
|
17902
18408
|
if (result.timedOut)
|
|
17903
18409
|
timedOut += 1;
|
|
18410
|
+
if (result.primaryUnavailable !== void 0) {
|
|
18411
|
+
primaryUnavailable += 1;
|
|
18412
|
+
if (result.primaryUnavailableCause !== void 0)
|
|
18413
|
+
primaryUnavailableCauses.push(result.primaryUnavailableCause);
|
|
18414
|
+
}
|
|
17904
18415
|
if (result.rootFallback) {
|
|
17905
18416
|
rootFallbackReasons.add(describeRootFallback(result.rootFallback));
|
|
17906
18417
|
}
|
|
@@ -17912,6 +18423,10 @@ function tallyConfirmation(results) {
|
|
|
17912
18423
|
clean,
|
|
17913
18424
|
unconfirmed,
|
|
17914
18425
|
timedOut,
|
|
18426
|
+
primaryUnavailable: {
|
|
18427
|
+
count: primaryUnavailable,
|
|
18428
|
+
cause: combinePrimaryUnavailableCauses(primaryUnavailableCauses)
|
|
18429
|
+
},
|
|
17915
18430
|
rootFallbackReasons: [...rootFallbackReasons],
|
|
17916
18431
|
navigationOnly,
|
|
17917
18432
|
tooLarge
|
|
@@ -17924,6 +18439,9 @@ function classifyBatchFileOutcome(result) {
|
|
|
17924
18439
|
return "too_large";
|
|
17925
18440
|
if (result.diagnosticsUnsupported)
|
|
17926
18441
|
return "unsupported";
|
|
18442
|
+
if (result.noClientAnswered && result.primaryUnavailable !== void 0) {
|
|
18443
|
+
return "unavailable";
|
|
18444
|
+
}
|
|
17927
18445
|
if (result.timedOut || result.confirmation === "unconfirmed") {
|
|
17928
18446
|
return "inconclusive";
|
|
17929
18447
|
}
|
|
@@ -17946,7 +18464,24 @@ function inconclusiveBatchResult(file, reason) {
|
|
|
17946
18464
|
inconclusiveReason: reason
|
|
17947
18465
|
};
|
|
17948
18466
|
}
|
|
17949
|
-
function
|
|
18467
|
+
function batchOutcomeReason(result) {
|
|
18468
|
+
return result.tooLargeReason ?? // #4322: a file only auxiliaries answered for names its language server.
|
|
18469
|
+
result.primaryUnavailable ?? result.inconclusiveReason ?? result.error ?? result.unavailable;
|
|
18470
|
+
}
|
|
18471
|
+
function auxiliaryOnlyFindingsLine(results) {
|
|
18472
|
+
const auxiliaryOnly = results.filter((result) => result.diagnostics.length > 0 && result.primaryUnavailable !== void 0 && result.noClientAnswered === void 0);
|
|
18473
|
+
const count = auxiliaryOnly.length;
|
|
18474
|
+
if (count === 0)
|
|
18475
|
+
return void 0;
|
|
18476
|
+
const cause = combinePrimaryUnavailableCauses(auxiliaryOnly.flatMap((result) => result.primaryUnavailableCause ?? [])) ?? "unstarted";
|
|
18477
|
+
return `${count} file${count === 1 ? "" : "s"} with auxiliary findings only: no language server answered (${PRIMARY_UNAVAILABLE_CAUSE[cause]}), so the language itself was not checked.`;
|
|
18478
|
+
}
|
|
18479
|
+
function unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons = [], primaryUnavailable = { count: 0, cause: void 0 }) {
|
|
18480
|
+
if (primaryUnavailable.count > 0) {
|
|
18481
|
+
const head = `${primaryUnavailable.count} with no language server answer (${PRIMARY_UNAVAILABLE_CAUSE[primaryUnavailable.cause ?? "unstarted"]})`;
|
|
18482
|
+
const rest = unconfirmed - primaryUnavailable.count;
|
|
18483
|
+
return rest > 0 ? `${head}; the other ${rest}: ${unconfirmedReasonClause(rest, timedOut, rootFallbackReasons)}` : `${head}.`;
|
|
18484
|
+
}
|
|
17950
18485
|
if (rootFallbackReasons.length > 0) {
|
|
17951
18486
|
return `${rootFallbackReasons.join("; ")} (${unconfirmed} unconfirmed in all).`;
|
|
17952
18487
|
}
|
|
@@ -17962,7 +18497,8 @@ function unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons = []
|
|
|
17962
18497
|
async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
17963
18498
|
const resolvedCwd = options.cwd ?? process.cwd();
|
|
17964
18499
|
const cacheCtx = createWorkspaceDiagnosticsCacheContext(resolvedCwd);
|
|
17965
|
-
const
|
|
18500
|
+
const serverScope = options.serverScope ?? "all";
|
|
18501
|
+
const scopeKey = buildProbeScopeKey(serverScope, options.excludeServerIds);
|
|
17966
18502
|
const resultsByIndex = /* @__PURE__ */ new Map();
|
|
17967
18503
|
let completed = 0;
|
|
17968
18504
|
const pendingIndices = /* @__PURE__ */ new Map();
|
|
@@ -17973,6 +18509,11 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
17973
18509
|
else
|
|
17974
18510
|
pendingIndices.set(file, [index]);
|
|
17975
18511
|
});
|
|
18512
|
+
lspService.announceCreatedFiles([
|
|
18513
|
+
...files,
|
|
18514
|
+
...goPackageFilesToAnnounce(files),
|
|
18515
|
+
...await importTargetsToAnnounce(resolvedCwd, files.filter((file) => !cacheCtx.servesClean(file, scopeKey)), (file, scope) => cacheCtx.noteImportScope(file, scope))
|
|
18516
|
+
]);
|
|
17976
18517
|
const groups = groupFilesByPrimaryServer(files);
|
|
17977
18518
|
await runPerServerGroups(groups, options.concurrency, async (group) => {
|
|
17978
18519
|
if (options.signal?.aborted)
|
|
@@ -17987,7 +18528,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
17987
18528
|
}
|
|
17988
18529
|
await mapWithConcurrency(group.files, 1, async (file) => {
|
|
17989
18530
|
const index = pendingIndices.get(file).shift();
|
|
17990
|
-
const work = collectFileDiagnosticResult(file, severity, lspService, options.waitMs, options.nextWriteIndex, options.serverScope, cacheCtx, scopeKey, resolvedCwd, options.onConfirmedNoBlockers);
|
|
18531
|
+
const work = collectFileDiagnosticResult(file, severity, lspService, options.waitMs, options.nextWriteIndex, options.serverScope, cacheCtx, scopeKey, resolvedCwd, options.onConfirmedNoBlockers, options.excludeServerIds);
|
|
17991
18532
|
const bounded2 = withDeadline(work, {
|
|
17992
18533
|
ms: batchFileDeadlineMs(),
|
|
17993
18534
|
onTimeout: "undefined",
|
|
@@ -18018,7 +18559,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
18018
18559
|
const total = allDiags.length;
|
|
18019
18560
|
const truncated = total > MAX_DIAGNOSTICS;
|
|
18020
18561
|
const display = truncated ? allDiags.slice(0, MAX_DIAGNOSTICS) : allDiags;
|
|
18021
|
-
const { clean, unconfirmed, timedOut, rootFallbackReasons } = tallyConfirmation(results);
|
|
18562
|
+
const { clean, unconfirmed, timedOut, primaryUnavailable, rootFallbackReasons } = tallyConfirmation(results);
|
|
18022
18563
|
for (const result of results) {
|
|
18023
18564
|
result.outcome = classifyBatchFileOutcome(result);
|
|
18024
18565
|
}
|
|
@@ -18050,6 +18591,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
18050
18591
|
unconfirmed,
|
|
18051
18592
|
timedOut,
|
|
18052
18593
|
rootFallbackReasons,
|
|
18594
|
+
primaryUnavailable,
|
|
18053
18595
|
outcomeCounts,
|
|
18054
18596
|
incompleteFiles: Math.max(0, files.length - results.length)
|
|
18055
18597
|
};
|
|
@@ -18059,7 +18601,7 @@ async function expandPathsToFiles(cwd, rawPaths) {
|
|
|
18059
18601
|
const directories = [];
|
|
18060
18602
|
const seenFileKeys = /* @__PURE__ */ new Set();
|
|
18061
18603
|
for (const entry of rawPaths) {
|
|
18062
|
-
const abs = normalizeMapKey(
|
|
18604
|
+
const abs = normalizeMapKey(resolveHostToolPath(entry, cwd));
|
|
18063
18605
|
let stat;
|
|
18064
18606
|
try {
|
|
18065
18607
|
stat = fs22.statSync(abs);
|
|
@@ -18104,7 +18646,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18104
18646
|
details: { mode: "batch", severity, filesChecked: 0 }
|
|
18105
18647
|
};
|
|
18106
18648
|
}
|
|
18107
|
-
const { results, fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, rootFallbackReasons, outcomeCounts, incompleteFiles } = await collectBatchDiagnostics(absPaths, severity, lspService, options);
|
|
18649
|
+
const { results, fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, rootFallbackReasons, primaryUnavailable, outcomeCounts, incompleteFiles } = await collectBatchDiagnostics(absPaths, severity, lspService, options);
|
|
18108
18650
|
const navigationOnly = results.filter((result) => result.diagnosticsUnsupported).length;
|
|
18109
18651
|
const dispositionSuppressed = results.reduce((sum, result) => sum + (result.dispositionSuppressed ?? 0), 0);
|
|
18110
18652
|
const lines = [
|
|
@@ -18130,7 +18672,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18130
18672
|
const outcomeDetails = results.map((result) => ({
|
|
18131
18673
|
file: result.file,
|
|
18132
18674
|
outcome: result.outcome,
|
|
18133
|
-
reason: result
|
|
18675
|
+
reason: batchOutcomeReason(result)
|
|
18134
18676
|
}));
|
|
18135
18677
|
const tooLargeLines = renderBatchOutcomeLines(outcomeDetails);
|
|
18136
18678
|
if (tooLargeLines.length > 0) {
|
|
@@ -18140,8 +18682,11 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18140
18682
|
lines.push("", "LSP health warnings:", ...lspHealthWarnings.slice(0, 10));
|
|
18141
18683
|
}
|
|
18142
18684
|
if (unconfirmed > 0) {
|
|
18143
|
-
lines.push("", `${clean} file${clean === 1 ? "" : "s"} confirmed clean, ${unconfirmed} unconfirmed: ${unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons)} NOT the same as 0 diagnostics.`);
|
|
18685
|
+
lines.push("", `${clean} file${clean === 1 ? "" : "s"} confirmed clean, ${unconfirmed} unconfirmed: ${unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons, primaryUnavailable)} NOT the same as 0 diagnostics.`);
|
|
18144
18686
|
}
|
|
18687
|
+
const auxiliaryOnlyLine = auxiliaryOnlyFindingsLine(results);
|
|
18688
|
+
if (auxiliaryOnlyLine)
|
|
18689
|
+
lines.push("", auxiliaryOnlyLine);
|
|
18145
18690
|
if (display.length === 0) {
|
|
18146
18691
|
if (unconfirmed === 0 && outcomeCounts.clean === results.length) {
|
|
18147
18692
|
lines.push("", "No diagnostics found.");
|
|
@@ -18186,7 +18731,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18186
18731
|
outcomes: results.map((result) => ({
|
|
18187
18732
|
file: result.file,
|
|
18188
18733
|
outcome: result.outcome,
|
|
18189
|
-
reason: result
|
|
18734
|
+
reason: batchOutcomeReason(result),
|
|
18190
18735
|
primaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.serverId === result.primaryServerId).length,
|
|
18191
18736
|
auxiliaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.serverId !== result.primaryServerId).length
|
|
18192
18737
|
})),
|
|
@@ -18254,26 +18799,30 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18254
18799
|
}
|
|
18255
18800
|
};
|
|
18256
18801
|
}
|
|
18257
|
-
const { results, fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, rootFallbackReasons, outcomeCounts } = await collectBatchDiagnostics(filesToProcess, severity, lspService, options);
|
|
18802
|
+
const { results, fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, rootFallbackReasons, primaryUnavailable, outcomeCounts } = await collectBatchDiagnostics(filesToProcess, severity, lspService, options);
|
|
18258
18803
|
const navigationOnly = results.filter((result) => result.diagnosticsUnsupported).length;
|
|
18259
18804
|
const dispositionSuppressed = results.reduce((sum, result) => sum + (result.dispositionSuppressed ?? 0), 0);
|
|
18260
18805
|
const suppressedLine = dispositionSuppressedLine(dispositionSuppressed);
|
|
18261
18806
|
const outcomeDetails = results.map((result) => ({
|
|
18262
18807
|
file: result.file,
|
|
18263
18808
|
outcome: result.outcome,
|
|
18264
|
-
reason: result
|
|
18809
|
+
reason: batchOutcomeReason(result)
|
|
18265
18810
|
}));
|
|
18266
|
-
const
|
|
18811
|
+
const auxiliaryOnlyLine = auxiliaryOnlyFindingsLine(results);
|
|
18812
|
+
const tooLargeLines = renderBatchOutcomeLines(outcomeDetails, (file) => path37.relative(absPath, file));
|
|
18267
18813
|
let text;
|
|
18268
18814
|
if (total === 0) {
|
|
18269
|
-
const cleanLine = unconfirmed > 0 ? `${clean} clean \xB7 ${unconfirmed} unconfirmed: ${unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons)} NOT the same as 0 diagnostics.` : "No diagnostics found.";
|
|
18815
|
+
const cleanLine = unconfirmed > 0 ? `${clean} clean \xB7 ${unconfirmed} unconfirmed: ${unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons, primaryUnavailable)} NOT the same as 0 diagnostics.` : "No diagnostics found.";
|
|
18270
18816
|
text = [
|
|
18271
18817
|
`Directory: ${absPath}`,
|
|
18272
18818
|
`Files scanned: ${filesToProcess.length}${wasCapped ? ` (capped at ${MAX_FILES})` : ""}`,
|
|
18273
18819
|
...lspHealthWarnings.length > 0 ? [
|
|
18274
18820
|
"LSP unavailable for one or more files:",
|
|
18275
18821
|
...lspHealthWarnings.slice(0, 10)
|
|
18276
|
-
] :
|
|
18822
|
+
] : [],
|
|
18823
|
+
// #4403: an unconfirmed file says why even beside a health warning,
|
|
18824
|
+
// which names what was missing but not that the file is unconfirmed.
|
|
18825
|
+
...unconfirmed > 0 || lspHealthWarnings.length === 0 && outcomeCounts.clean === filesToProcess.length ? [cleanLine] : [],
|
|
18277
18826
|
...tooLargeLines.length > 0 ? ["", "Files too large for LSP diagnostics:", ...tooLargeLines] : [],
|
|
18278
18827
|
...suppressedLine ? ["", suppressedLine] : []
|
|
18279
18828
|
].join("\n");
|
|
@@ -18289,13 +18838,14 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18289
18838
|
// whole found diagnostics elsewhere.
|
|
18290
18839
|
...unconfirmed > 0 ? [
|
|
18291
18840
|
"",
|
|
18292
|
-
`${clean} other file${clean === 1 ? "" : "s"} confirmed clean, ${unconfirmed} unconfirmed: ` + unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons)
|
|
18841
|
+
`${clean} other file${clean === 1 ? "" : "s"} confirmed clean, ${unconfirmed} unconfirmed: ` + unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons, primaryUnavailable)
|
|
18293
18842
|
] : [],
|
|
18843
|
+
...auxiliaryOnlyLine ? ["", auxiliaryOnlyLine] : [],
|
|
18294
18844
|
""
|
|
18295
18845
|
];
|
|
18296
18846
|
const toRelative = (d) => ({
|
|
18297
18847
|
...d,
|
|
18298
|
-
file:
|
|
18848
|
+
file: path37.relative(absPath, d.file)
|
|
18299
18849
|
});
|
|
18300
18850
|
if (primaryDisplay.length > 0) {
|
|
18301
18851
|
lines.push(`Primary findings (${primaryDisplay.length}):`);
|
|
@@ -18326,7 +18876,7 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18326
18876
|
filesScanned: filesToProcess.length,
|
|
18327
18877
|
capped: wasCapped,
|
|
18328
18878
|
diagnostics: display.map((d) => ({
|
|
18329
|
-
file:
|
|
18879
|
+
file: path37.relative(absPath, d.file),
|
|
18330
18880
|
line: d.line,
|
|
18331
18881
|
character: d.character,
|
|
18332
18882
|
severity: d.severity,
|
|
@@ -18352,11 +18902,6 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18352
18902
|
}
|
|
18353
18903
|
};
|
|
18354
18904
|
}
|
|
18355
|
-
function dispositionSuppressedLine(suppressed) {
|
|
18356
|
-
if (suppressed <= 0)
|
|
18357
|
-
return void 0;
|
|
18358
|
-
return `suppressed by disposition: ${suppressed} finding(s) dropped from this result because they're marked false-positive/won't-fix, disabled by \`.pi-lens.json\` rule policy, or suppressed by an inline \`pi-lens-ignore\` comment. Not a clean verdict for those locations \u2014 they were found, then intentionally hidden.`;
|
|
18359
|
-
}
|
|
18360
18905
|
function applySeverityFilter(diags, severity) {
|
|
18361
18906
|
if (severity === "all")
|
|
18362
18907
|
return diags;
|
|
@@ -18423,7 +18968,7 @@ async function findFullScanBindingMismatches(results) {
|
|
|
18423
18968
|
return mismatched;
|
|
18424
18969
|
}
|
|
18425
18970
|
function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSPService, flushPending = async () => {
|
|
18426
|
-
}, nextWriteIndex, captureLspStatusRepaint, getRuntime, isLensGuardEnabled2 = () => true) {
|
|
18971
|
+
}, nextWriteIndex, captureLspStatusRepaint, getRuntime, isLensGuardEnabled2 = () => true, getFlag) {
|
|
18427
18972
|
const lspProbe = createLspDiagnosticsTool(nextWriteIndex, (info) => {
|
|
18428
18973
|
const runtime = getRuntime?.();
|
|
18429
18974
|
if (!runtime)
|
|
@@ -18444,7 +18989,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18444
18989
|
message: `inline_blocker: retired for ${info.filePath}`
|
|
18445
18990
|
});
|
|
18446
18991
|
}
|
|
18447
|
-
}, getLspService);
|
|
18992
|
+
}, getLspService, getFlag);
|
|
18448
18993
|
return {
|
|
18449
18994
|
name: "lens_diagnostics",
|
|
18450
18995
|
label: "Project Diagnostics",
|
|
@@ -18456,7 +19001,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18456
19001
|
const files2 = details.filesChecked ?? details.filesScanned ?? 0;
|
|
18457
19002
|
const noun = count === 1 ? "diagnostic" : "diagnostics";
|
|
18458
19003
|
const filePath = typeof details?.filePath === "string" ? details.filePath : Array.isArray(args?.paths) && args.paths.length === 1 && typeof args.paths[0] === "string" ? args.paths[0] : void 0;
|
|
18459
|
-
const singleFile = (details?.mode === "file" || files2 === 1) && typeof filePath === "string" ? ` ${
|
|
19004
|
+
const singleFile = (details?.mode === "file" || files2 === 1) && typeof filePath === "string" ? ` ${path38.basename(filePath)}` : "";
|
|
18460
19005
|
const scope = files2 > 1 ? ` across ${files2} files` : singleFile;
|
|
18461
19006
|
if (isError)
|
|
18462
19007
|
return `lens_diagnostics lsp \u2014 ${text.split("\n")[0] ?? "error"}`;
|
|
@@ -18474,7 +19019,10 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18474
19019
|
if ((details.incompleteFiles ?? 0) > 0)
|
|
18475
19020
|
return `lens_diagnostics${scope} \u2014 incomplete (${details.incompleteFiles} files not confirmed)`;
|
|
18476
19021
|
if (count === 0 && details.unconfirmed)
|
|
18477
|
-
return details.timedOut ? `lens_diagnostics${scope} \u2014 timed out (result may be incomplete)` :
|
|
19022
|
+
return details.timedOut ? `lens_diagnostics${scope} \u2014 timed out (result may be incomplete)` : (
|
|
19023
|
+
// #4322: no language server answered; it is not a silent server.
|
|
19024
|
+
details.primaryUnavailable !== void 0 ? `lens_diagnostics${scope} \u2014 unconfirmed (no language server answered)` : `lens_diagnostics${scope} \u2014 unconfirmed (server cannot confirm clean)`
|
|
19025
|
+
);
|
|
18478
19026
|
return `lens_diagnostics${scope} \u2014 ${count} ${noun}`;
|
|
18479
19027
|
}
|
|
18480
19028
|
const scanning = scanningSummaryLine(details, text);
|
|
@@ -18584,6 +19132,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18584
19132
|
const hasExplicitPaths = Array.isArray(lspParams.paths) && lspParams.paths.length > 0;
|
|
18585
19133
|
if (scope === "workspace" && !hasExplicitPath && !hasExplicitPaths) {
|
|
18586
19134
|
lspParams.path = cwd;
|
|
19135
|
+
lspParams.pathAlreadyResolved = true;
|
|
18587
19136
|
}
|
|
18588
19137
|
const lspStart = Date.now();
|
|
18589
19138
|
const result = await lspProbe.execute(_toolCallId, lspParams, signal, onUpdate, ctx.signal ? { cwd, signal: ctx.signal } : { cwd });
|
|
@@ -18702,7 +19251,7 @@ function appendProjectDiagnosticsDeltaLines(groups, cwd, report, severity, inclu
|
|
|
18702
19251
|
const diagnostics = [...gated.live, ...gated.stale];
|
|
18703
19252
|
const byFile = /* @__PURE__ */ new Map();
|
|
18704
19253
|
for (const diagnostic of diagnostics) {
|
|
18705
|
-
const filePath =
|
|
19254
|
+
const filePath = path38.resolve(diagnostic.filePath);
|
|
18706
19255
|
const bucket = byFile.get(filePath) ?? [];
|
|
18707
19256
|
bucket.push(diagnostic);
|
|
18708
19257
|
byFile.set(filePath, bucket);
|
|
@@ -18829,7 +19378,7 @@ function applyDeltaFreshnessGate(files, cwd, generatedAt) {
|
|
|
18829
19378
|
})).filter((file) => file.warnings.length > 0);
|
|
18830
19379
|
}
|
|
18831
19380
|
function getDeltaFileGroup(groups, cwd, filePath) {
|
|
18832
|
-
const rel =
|
|
19381
|
+
const rel = path38.relative(cwd, filePath);
|
|
18833
19382
|
let group = groups.get(rel);
|
|
18834
19383
|
if (!group) {
|
|
18835
19384
|
group = {
|
|
@@ -18953,7 +19502,7 @@ Summary (turn delta): ${aw} actionable warning${aw === 1 ? "" : "s"} \xB7 ${cq}
|
|
|
18953
19502
|
function createCurrentIgnoreFilter(cwd) {
|
|
18954
19503
|
try {
|
|
18955
19504
|
const matcher = getProjectIgnoreMatcher(cwd);
|
|
18956
|
-
return (filePath) => !matcher.isIgnored(
|
|
19505
|
+
return (filePath) => !matcher.isIgnored(path38.resolve(filePath), false);
|
|
18957
19506
|
} catch {
|
|
18958
19507
|
return () => true;
|
|
18959
19508
|
}
|
|
@@ -18964,7 +19513,7 @@ function resolvePathsScope(cwd, rawPaths) {
|
|
|
18964
19513
|
if (rawPaths.length > MAX_PATHS_ENTRIES) {
|
|
18965
19514
|
throw new Error(`paths has ${rawPaths.length} entries, over the ${MAX_PATHS_ENTRIES} cap. Narrow the list or omit paths to scan without a restriction.`);
|
|
18966
19515
|
}
|
|
18967
|
-
const entries = rawPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) =>
|
|
19516
|
+
const entries = rawPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) => resolveHostToolPath(entry, cwd));
|
|
18968
19517
|
const missing = [];
|
|
18969
19518
|
const fileEntries = [];
|
|
18970
19519
|
const existingEntries = [];
|
|
@@ -18987,9 +19536,9 @@ function resolvePathsScope(cwd, rawPaths) {
|
|
|
18987
19536
|
}
|
|
18988
19537
|
const fileKeys = new Set(fileEntries.map((f) => normalizeFilePath(f)));
|
|
18989
19538
|
const dirPrefixes = dirEntries.map((d) => normalizeFilePath(d));
|
|
18990
|
-
const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(
|
|
19539
|
+
const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(path38.resolve(filePath)));
|
|
18991
19540
|
const includeFile = (filePath) => {
|
|
18992
|
-
const key = normalizeFilePath(
|
|
19541
|
+
const key = normalizeFilePath(path38.resolve(filePath));
|
|
18993
19542
|
if (fileKeys.has(key))
|
|
18994
19543
|
return true;
|
|
18995
19544
|
return dirPrefixes.some((prefix) => key === prefix || key.startsWith(`${prefix}/`));
|
|
@@ -19010,7 +19559,7 @@ function pathsScopeCacheOnlyNote(scope) {
|
|
|
19010
19559
|
function pathsScopeMissingNote(scope) {
|
|
19011
19560
|
if (!scope || scope.missing.length === 0)
|
|
19012
19561
|
return "";
|
|
19013
|
-
const shown2 = scope.missing.slice(0, 10).map((p) =>
|
|
19562
|
+
const shown2 = scope.missing.slice(0, 10).map((p) => path38.basename(p));
|
|
19014
19563
|
const more = scope.missing.length > shown2.length ? ` (+${scope.missing.length - shown2.length} more)` : "";
|
|
19015
19564
|
return `
|
|
19016
19565
|
|
|
@@ -19141,7 +19690,7 @@ function projectDiagnosticToWidget(diagnostic, filePath) {
|
|
|
19141
19690
|
}
|
|
19142
19691
|
function diagnosticDedupKey(filePath, diagnostic) {
|
|
19143
19692
|
const ruleId = normalizeRuleId(diagnostic.rule ?? diagnostic.tool ?? "");
|
|
19144
|
-
return [
|
|
19693
|
+
return [path38.resolve(filePath), diagnostic.line ?? "?", ruleId].join(":");
|
|
19145
19694
|
}
|
|
19146
19695
|
function runnerIdOf(diagnostic) {
|
|
19147
19696
|
return diagnostic.tool ?? diagnostic.rule?.split(":", 1)[0] ?? "";
|
|
@@ -19155,8 +19704,8 @@ function runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds,
|
|
|
19155
19704
|
const realFilePath = realpathOrResolve(filePath);
|
|
19156
19705
|
for (const entry of coverage) {
|
|
19157
19706
|
const root = entry.root;
|
|
19158
|
-
const relative9 =
|
|
19159
|
-
const underRoot = relative9 === "" || !relative9.startsWith("..") && !
|
|
19707
|
+
const relative9 = path38.relative(root, realFilePath);
|
|
19708
|
+
const underRoot = relative9 === "" || !relative9.startsWith("..") && !path38.isAbsolute(relative9);
|
|
19160
19709
|
if (!underRoot)
|
|
19161
19710
|
continue;
|
|
19162
19711
|
if (entry.files.has(realFilePath)) {
|
|
@@ -19206,7 +19755,11 @@ var UNCONFIRMED_REASON_SENTENCE = {
|
|
|
19206
19755
|
binding_mismatch: "the file changed on disk since this result was computed",
|
|
19207
19756
|
// #2052: no server was asked. Say WHY and say it is permanent for this
|
|
19208
19757
|
// path, so the reader does not read an empty result as "clean" or retry it.
|
|
19209
|
-
outside_project_root: "the file is outside every initialized session project root, so no language server was asked"
|
|
19758
|
+
outside_project_root: "the file is outside every initialized session project root, so no language server was asked",
|
|
19759
|
+
// #4403: the per-file note's wording, one sentence per cause.
|
|
19760
|
+
primary_unavailable: `no primary language server answered (${PRIMARY_UNAVAILABLE_CAUSE.unstarted})`,
|
|
19761
|
+
primary_disabled: `no primary language server answered (${PRIMARY_UNAVAILABLE_CAUSE.disabled})`,
|
|
19762
|
+
primary_disabled_fallback: `no primary language server answered (${PRIMARY_UNAVAILABLE_CAUSE.disabledFallback})`
|
|
19210
19763
|
};
|
|
19211
19764
|
var UNCONFIRMED_REASON_COUNT_LABEL = {
|
|
19212
19765
|
budget: "timed out",
|
|
@@ -19215,7 +19768,10 @@ var UNCONFIRMED_REASON_COUNT_LABEL = {
|
|
|
19215
19768
|
service_destroyed: "service reset mid-sweep",
|
|
19216
19769
|
error: "errored",
|
|
19217
19770
|
binding_mismatch: "stale binding",
|
|
19218
|
-
outside_project_root: "outside project root"
|
|
19771
|
+
outside_project_root: "outside project root",
|
|
19772
|
+
primary_unavailable: "no primary started",
|
|
19773
|
+
primary_disabled: "primary disabled in config",
|
|
19774
|
+
primary_disabled_fallback: "primary disabled, fallback did not answer"
|
|
19219
19775
|
};
|
|
19220
19776
|
function classifyUnconfirmedReason(result, mismatched) {
|
|
19221
19777
|
if (mismatched.has(result))
|
|
@@ -19280,7 +19836,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19280
19836
|
const byFile = /* @__PURE__ */ new Map();
|
|
19281
19837
|
const seen = /* @__PURE__ */ new Set();
|
|
19282
19838
|
for (const summary of widgetSummaries) {
|
|
19283
|
-
const filePath =
|
|
19839
|
+
const filePath = path38.resolve(summary.filePath);
|
|
19284
19840
|
if (authoritativeLspFiles?.has(filePath))
|
|
19285
19841
|
continue;
|
|
19286
19842
|
const retained = summary.diagnostics ?? [];
|
|
@@ -19308,7 +19864,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19308
19864
|
byFile.set(filePath, summarizeDiagnostics(filePath, diagnostics, existing?.hasFinalSnapshot ?? true));
|
|
19309
19865
|
};
|
|
19310
19866
|
for (const result of lspResults) {
|
|
19311
|
-
const filePath =
|
|
19867
|
+
const filePath = path38.resolve(result.filePath);
|
|
19312
19868
|
for (const diagnostic of result.diagnostics ?? []) {
|
|
19313
19869
|
addDiagnostic(filePath, {
|
|
19314
19870
|
...lspDiagnosticToWidget(diagnostic),
|
|
@@ -19328,19 +19884,19 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19328
19884
|
});
|
|
19329
19885
|
}
|
|
19330
19886
|
for (const diagnostic of projectSnapshot?.diagnostics ?? []) {
|
|
19331
|
-
addDiagnostic(
|
|
19887
|
+
addDiagnostic(path38.resolve(diagnostic.filePath), projectDiagnosticToWidget(diagnostic, diagnostic.filePath));
|
|
19332
19888
|
}
|
|
19333
19889
|
for (const diagnostic of deltaDiagnostics) {
|
|
19334
19890
|
const widget = projectDiagnosticToWidget(diagnostic, diagnostic.filePath);
|
|
19335
19891
|
const observedAt = widget.observedAt ?? deltaObservedAt;
|
|
19336
|
-
addDiagnostic(
|
|
19892
|
+
addDiagnostic(path38.resolve(diagnostic.filePath), {
|
|
19337
19893
|
...widget,
|
|
19338
19894
|
...observedAt !== void 0 && { observedAt }
|
|
19339
19895
|
});
|
|
19340
19896
|
}
|
|
19341
19897
|
return [...byFile.values()];
|
|
19342
19898
|
}
|
|
19343
|
-
async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
|
|
19899
|
+
async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap, dispositionDropped) {
|
|
19344
19900
|
return Promise.all(summaries.map(async (summary) => {
|
|
19345
19901
|
if (!summary.diagnostics.length)
|
|
19346
19902
|
return summary;
|
|
@@ -19354,12 +19910,19 @@ async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
|
|
|
19354
19910
|
});
|
|
19355
19911
|
return policyKept2.length === summary.diagnostics.length ? summary : summarizeDiagnostics(summary.filePath, policyKept2, summary.hasFinalSnapshot);
|
|
19356
19912
|
}
|
|
19357
|
-
const { kept: policyKept } = applyFindingPolicy(summary.diagnostics, {
|
|
19913
|
+
const { kept: policyKept, inlineKept, disposed } = applyFindingPolicy(summary.diagnostics, {
|
|
19358
19914
|
cwd,
|
|
19359
19915
|
filePath: summary.filePath,
|
|
19360
19916
|
content,
|
|
19361
19917
|
policyMap
|
|
19362
19918
|
});
|
|
19919
|
+
if (disposed.length < inlineKept.length) {
|
|
19920
|
+
const survivors = new Set(disposed);
|
|
19921
|
+
for (const d of inlineKept) {
|
|
19922
|
+
if (!survivors.has(d))
|
|
19923
|
+
dispositionDropped.push(d);
|
|
19924
|
+
}
|
|
19925
|
+
}
|
|
19363
19926
|
for (const d of policyKept) {
|
|
19364
19927
|
const { weak } = anchorsForDiagnostic(cwd, summary.filePath, d, content);
|
|
19365
19928
|
if (getDisposition(cwd, weak)?.disposition === "flagged") {
|
|
@@ -19517,13 +20080,21 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19517
20080
|
const unconfirmedLspResults = lspResults.filter((result2) => result2.timedOut || result2.error || mismatchedLspResults.has(result2));
|
|
19518
20081
|
const authoritativeLspFiles = /* @__PURE__ */ new Set();
|
|
19519
20082
|
const unreconciledFiles = /* @__PURE__ */ new Set();
|
|
20083
|
+
const policyMap = loadProjectRulePolicyMap(cwd);
|
|
19520
20084
|
for (const result2 of fullyCoveredLspResults) {
|
|
19521
20085
|
try {
|
|
19522
20086
|
const diagnostics = convertLspDiagnostics(result2.diagnostics, result2.filePath, { scanOrigin: "lens_diagnostics_full" });
|
|
19523
20087
|
const retagged = retagAuxiliaryDiagnostics(diagnostics, result2.diagnostics, "", { cwd, fileRole: detectFileRole(result2.filePath) });
|
|
20088
|
+
const content = readFileContent(result2.filePath);
|
|
20089
|
+
const { kept: policyKept } = applyFindingPolicy(retagged, {
|
|
20090
|
+
cwd,
|
|
20091
|
+
filePath: result2.filePath,
|
|
20092
|
+
content: content ?? "",
|
|
20093
|
+
policyMap
|
|
20094
|
+
});
|
|
19524
20095
|
const retired = reconcileScanDiagnostics(
|
|
19525
20096
|
result2.filePath,
|
|
19526
|
-
|
|
20097
|
+
policyKept,
|
|
19527
20098
|
true,
|
|
19528
20099
|
// The service reserves this token when the file enters the scan. The
|
|
19529
20100
|
// fallback preserves compatibility with older test doubles/services.
|
|
@@ -19536,32 +20107,31 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19536
20107
|
result2.observedAt
|
|
19537
20108
|
);
|
|
19538
20109
|
if (retired === true) {
|
|
19539
|
-
authoritativeLspFiles.add(
|
|
20110
|
+
authoritativeLspFiles.add(path38.resolve(result2.filePath));
|
|
19540
20111
|
} else {
|
|
19541
|
-
unreconciledFiles.add(
|
|
20112
|
+
unreconciledFiles.add(path38.resolve(result2.filePath));
|
|
19542
20113
|
recordDegradationOnce({
|
|
19543
20114
|
kind: "diagnostic-retained-unreconciled",
|
|
19544
|
-
subject: `${
|
|
20115
|
+
subject: `${path38.resolve(result2.filePath)}:lsp`,
|
|
19545
20116
|
reason: "confirmed diagnostic result could not replace retained widget state"
|
|
19546
20117
|
});
|
|
19547
20118
|
}
|
|
19548
20119
|
} catch {
|
|
19549
|
-
unreconciledFiles.add(
|
|
20120
|
+
unreconciledFiles.add(path38.resolve(result2.filePath));
|
|
19550
20121
|
recordDegradationOnce({
|
|
19551
20122
|
kind: "diagnostic-retained-unreconciled",
|
|
19552
|
-
subject: `${
|
|
20123
|
+
subject: `${path38.resolve(result2.filePath)}:lsp`,
|
|
19553
20124
|
reason: "confirmed diagnostic result failed during widget reconciliation"
|
|
19554
20125
|
});
|
|
19555
20126
|
}
|
|
19556
20127
|
}
|
|
19557
|
-
const policyMap = loadProjectRulePolicyMap(cwd);
|
|
19558
20128
|
const scannedSnapshot = filterProjectDiagnosticsSnapshot(rawProjectSnapshot, includeFile);
|
|
19559
20129
|
const authoritativeRunnerIds = new Set(extracted.analyzed ?? []);
|
|
19560
20130
|
const authoritativeRunnerCoverage = extracted.authoritativeCoverage ?? [];
|
|
19561
20131
|
const foldedProjectSnapshot = foldExtraDiagnosticsIntoSnapshot(scannedSnapshot, extracted.diagnostics.filter((d) => includeFile(d.filePath)), extracted.runners, cwd);
|
|
19562
20132
|
const projectSnapshot = applyProjectRulePolicy(foldedProjectSnapshot, policyMap, cwd);
|
|
19563
20133
|
const projectDelta = applyProjectRulePolicy(filterProjectDiagnosticsDeltaReport(loadProjectDiagnosticsDeltaReport(cwd), includeFile), policyMap, cwd);
|
|
19564
|
-
const authoritativeRetiredCount = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath) && authoritativeLspFiles.has(
|
|
20134
|
+
const authoritativeRetiredCount = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath) && authoritativeLspFiles.has(path38.resolve(summary.filePath)) && (summary.diagnostics?.length ?? 0) > 0).length;
|
|
19565
20135
|
if (authoritativeRetiredCount > 0) {
|
|
19566
20136
|
logLatency({
|
|
19567
20137
|
type: "phase",
|
|
@@ -19614,9 +20184,10 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19614
20184
|
}
|
|
19615
20185
|
});
|
|
19616
20186
|
}
|
|
19617
|
-
|
|
20187
|
+
const dispositionDropped = [];
|
|
20188
|
+
let summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage), cwd, policyMap, dispositionDropped);
|
|
19618
20189
|
if (unreconciledFiles.size > 0) {
|
|
19619
|
-
summaries = summaries.map((summary) => unreconciledFiles.has(
|
|
20190
|
+
summaries = summaries.map((summary) => unreconciledFiles.has(path38.resolve(summary.filePath)) ? summarizeDiagnostics(summary.filePath, markUnreconciledFindings(summary.diagnostics), summary.hasFinalSnapshot) : summary);
|
|
19620
20191
|
}
|
|
19621
20192
|
const parsedProjectScanObservedAt = projectSnapshot?.scannedAt ? Date.parse(projectSnapshot.scannedAt) : void 0;
|
|
19622
20193
|
const projectScanObservedAt = parsedProjectScanObservedAt !== void 0 && Number.isFinite(parsedProjectScanObservedAt) ? parsedProjectScanObservedAt : void 0;
|
|
@@ -19638,14 +20209,26 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19638
20209
|
sources: projectDelta.sources,
|
|
19639
20210
|
turnIndex: projectDelta.turnIndex
|
|
19640
20211
|
}
|
|
19641
|
-
}, 0, pathsScope
|
|
20212
|
+
}, 0, pathsScope, 0, {
|
|
20213
|
+
dropped: dispositionDropped,
|
|
20214
|
+
// #1617: the #1616 suppressed-bucket rule applied to the analyzers —
|
|
20215
|
+
// a finding marked false-positive/won't-fix drops out of
|
|
20216
|
+
// `diagnostics` (fresh-fetch.ts's `record()`), and the drop stays
|
|
20217
|
+
// visible as a count. Review-round F4 (#1625): per-lane attribution
|
|
20218
|
+
// ("gitleaks 2, knip 1") says WHICH analyzer's marks are doing the
|
|
20219
|
+
// suppressing. A lane that's 100% suppressed still won't appear in
|
|
20220
|
+
// `runners`/`cold` as distinct from "ran clean" — #1623's territory.
|
|
20221
|
+
analyzers: extracted.dispositionSuppressed ?? 0,
|
|
20222
|
+
analyzersByLane: extracted.dispositionSuppressedByLane ?? {}
|
|
20223
|
+
});
|
|
19642
20224
|
const missingNote = pathsScopeMissingNote(pathsScope);
|
|
19643
20225
|
const unconfirmedByReason = tallyUnconfirmedReasons(unconfirmedLspResults, mismatchedLspResults);
|
|
19644
20226
|
const lspServerBreakdown = tallyLspByPrimaryServer(confirmedLspResults, unconfirmedLspResults);
|
|
19645
20227
|
const serverBreakdownClause = lspServerBreakdown.size > 1 ? ` \u2014 by server: ${formatLspServerBreakdown(lspServerBreakdown)}.` : "";
|
|
20228
|
+
const retryClause = [...unconfirmedByReason.keys()].every((reason) => reason === "primary_disabled") ? "" : "; re-run mode=full to retry them";
|
|
19646
20229
|
const unconfirmedLspNote = unconfirmedLspResults.length > 0 ? `
|
|
19647
20230
|
|
|
19648
|
-
\u26A0 LSP sweep: ${confirmedLspResults.length} file(s) confirmed via LSP, ${unconfirmedLspResults.length} unconfirmed (${formatUnconfirmedReasonClause(unconfirmedByReason)})${serverBreakdownClause} \u2014 NOT the same as 0 diagnostics for: ${unconfirmedLspResults.slice(0, 20).map((result2) => result2.filePath).join(", ")}${unconfirmedLspResults.length > 20 ? ", \u2026" : ""}. These files' LSP contribution is excluded from this result
|
|
20231
|
+
\u26A0 LSP sweep: ${confirmedLspResults.length} file(s) confirmed via LSP, ${unconfirmedLspResults.length} unconfirmed (${formatUnconfirmedReasonClause(unconfirmedByReason)})${serverBreakdownClause} \u2014 NOT the same as 0 diagnostics for: ${unconfirmedLspResults.slice(0, 20).map((result2) => result2.filePath).join(", ")}${unconfirmedLspResults.length > 20 ? ", \u2026" : ""}. These files' LSP contribution is excluded from this result${retryClause} (they may still show findings above from cached/project-runner state).` : "";
|
|
19649
20232
|
const uncoveredScannerIds = [
|
|
19650
20233
|
...new Set(partiallyCoveredLspResults.flatMap((result2) => result2.unconfirmedServerIds ?? []))
|
|
19651
20234
|
].sort((a, b) => Number(a > b) - Number(a < b));
|
|
@@ -19693,10 +20276,6 @@ test-runner coverage is edit-scoped, NOT a full-project run: its findings only r
|
|
|
19693
20276
|
const failedNote = failedAnalyzers.length > 0 ? `
|
|
19694
20277
|
|
|
19695
20278
|
failed (ran, but no trustworthy result): ${failedAnalyzers.map(({ id, summary }) => `${id} \u2014 ${summary}`).join(", ")}. These analyzers were not cached and will be retried; absence of their findings is NOT a clean verdict.` : "";
|
|
19696
|
-
const dispositionSuppressedByLaneText = Object.entries(extracted.dispositionSuppressedByLane ?? {}).map(([id, count]) => `${id} ${count}`).join(", ");
|
|
19697
|
-
const dispositionSuppressedNote = (extracted.dispositionSuppressed ?? 0) > 0 ? `
|
|
19698
|
-
|
|
19699
|
-
suppressed by disposition: ${extracted.dispositionSuppressed} finding(s) dropped from this result because they're marked false-positive or won't-fix (${dispositionSuppressedByLaneText}). Not a clean verdict for those locations \u2014 they were found, then intentionally hidden.` : "";
|
|
19700
20279
|
const walkUnsafeRoot = explicitFiles === void 0 && isAtOrAboveHomeDir(cwd);
|
|
19701
20280
|
const walkUnsafeRootNote = walkUnsafeRoot ? `
|
|
19702
20281
|
|
|
@@ -19744,7 +20323,9 @@ served from cache this call (not re-run): ${cachedAgeEntries.map(([id, ms]) => `
|
|
|
19744
20323
|
coldReasons: extracted.coldReasons ?? {},
|
|
19745
20324
|
failedAnalyzers,
|
|
19746
20325
|
analyzerTimingsMs: extracted.timings,
|
|
19747
|
-
|
|
20326
|
+
// #1634: every lane the call filtered — the sweep's and the
|
|
20327
|
+
// analyzers' — in one count, the one the text states.
|
|
20328
|
+
dispositionSuppressed: result.details.dispositionSuppressed ?? 0,
|
|
19748
20329
|
dispositionSuppressedByLane: extracted.dispositionSuppressedByLane ?? {},
|
|
19749
20330
|
// #1623: ms-old each cache-read-by-design lane's data was (today, only
|
|
19750
20331
|
// test-runner) — lets a caller distinguish "just ran" from "served
|
|
@@ -19799,18 +20380,18 @@ served from cache this call (not re-run): ${cachedAgeEntries.map(([id, ms]) => `
|
|
|
19799
20380
|
content: [
|
|
19800
20381
|
{
|
|
19801
20382
|
type: "text",
|
|
19802
|
-
text: result.content[0].text + note + unconfirmedLspNote + auxiliaryCoverageNote + lspPrimaryVsAuxiliaryNote + partialNote + coldNote + testRunnerEditScopedNote + failedNote +
|
|
20383
|
+
text: result.content[0].text + note + unconfirmedLspNote + auxiliaryCoverageNote + lspPrimaryVsAuxiliaryNote + partialNote + coldNote + testRunnerEditScopedNote + failedNote + walkUnsafeRootNote + scanTruncatedNote + generatedSkipNote + abortedNote + freshNote + cachedAgeNote + cheapScanStatusNote + missingNote
|
|
19803
20384
|
}
|
|
19804
20385
|
],
|
|
19805
20386
|
details: { ...resultWithCold.details, timedOut }
|
|
19806
20387
|
};
|
|
19807
20388
|
}
|
|
19808
|
-
if (missingNote || coldNote || partialNote || testRunnerEditScopedNote || failedNote ||
|
|
20389
|
+
if (missingNote || coldNote || partialNote || testRunnerEditScopedNote || failedNote || walkUnsafeRootNote || scanTruncatedNote || generatedSkipNote || abortedNote || freshNote || cachedAgeNote || cheapScanStatusNote || unconfirmedLspNote || auxiliaryCoverageNote || lspPrimaryVsAuxiliaryNote) {
|
|
19809
20390
|
return {
|
|
19810
20391
|
content: [
|
|
19811
20392
|
{
|
|
19812
20393
|
type: "text",
|
|
19813
|
-
text: result.content[0].text + unconfirmedLspNote + auxiliaryCoverageNote + lspPrimaryVsAuxiliaryNote + partialNote + coldNote + testRunnerEditScopedNote + failedNote +
|
|
20394
|
+
text: result.content[0].text + unconfirmedLspNote + auxiliaryCoverageNote + lspPrimaryVsAuxiliaryNote + partialNote + coldNote + testRunnerEditScopedNote + failedNote + walkUnsafeRootNote + scanTruncatedNote + generatedSkipNote + abortedNote + freshNote + cachedAgeNote + cheapScanStatusNote + missingNote
|
|
19814
20395
|
}
|
|
19815
20396
|
],
|
|
19816
20397
|
details: resultWithCold.details
|
|
@@ -19826,12 +20407,21 @@ async function projectResolvedCwd(summary, cwd) {
|
|
|
19826
20407
|
diagnostics: summary.diagnostics ?? []
|
|
19827
20408
|
};
|
|
19828
20409
|
}
|
|
19829
|
-
async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummaries(), detailOverrides = { mode: "all" }, staleDropped = 0, pathsScope, dependencyDemoted = 0) {
|
|
20410
|
+
async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummaries(), detailOverrides = { mode: "all" }, staleDropped = 0, pathsScope, dependencyDemoted = 0, fullModeDisposition = { dropped: [], analyzers: 0, analyzersByLane: {} }) {
|
|
19830
20411
|
const footerCapped = summaries.reduce((n, s) => n + (s.diagnostics ?? []).filter((d) => d.footerRetired === true).length, 0);
|
|
19831
20412
|
const staleNote = (staleDropped > 0 ? ` (${staleDropped} changed file${staleDropped === 1 ? "" : "s"} omitted as stale \u2014 use mode=full to rescan)` : "") + (dependencyDemoted > 0 ? ` (${dependencyDemoted} blocking finding${dependencyDemoted === 1 ? "" : "s"} demoted to [stale] \u2014 an imported file changed since; re-run to confirm)` : "") + (footerCapped > 0 ? ` (${footerCapped} demoted finding${footerCapped === 1 ? "" : "s"} capped after ${DEPENDENCY_DRIFT_MAX_DELIVERIES} unconfirmed deliveries \u2014 no longer shown in the pi-lens footer, still listed here; re-run to confirm)` : "");
|
|
19832
20413
|
const isFullMode = detailOverrides.mode === "full";
|
|
19833
20414
|
const includeFile = createScopedFileFilter(cwd, pathsScope);
|
|
19834
20415
|
const policyMap = loadProjectRulePolicyMap(cwd);
|
|
20416
|
+
const inScope = (rows) => rows.reduce((n, d) => n + (matchesSeverity(d, severity) ? 1 : 0), 0);
|
|
20417
|
+
const sweepSuppressed = isFullMode ? inScope(fullModeDisposition.dropped) : 0;
|
|
20418
|
+
const lanes = [];
|
|
20419
|
+
for (const [id, count] of Object.entries(fullModeDisposition.analyzersByLane)) {
|
|
20420
|
+
if (count > 0)
|
|
20421
|
+
lanes.push(`${id} ${count}`);
|
|
20422
|
+
}
|
|
20423
|
+
const suppressedBreakdown = lanes.length > 0 ? `analyzer lanes: ${lanes.join(", ")}` : void 0;
|
|
20424
|
+
let dispositionSuppressed = sweepSuppressed + fullModeDisposition.analyzers;
|
|
19835
20425
|
const dispositioned = isFullMode ? summaries : summaries.map((s) => {
|
|
19836
20426
|
const diagnostics = s.diagnostics ?? [];
|
|
19837
20427
|
const kept = applyCachedDispositions(diagnostics, cwd, s.filePath);
|
|
@@ -19839,6 +20429,9 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19839
20429
|
root: cwd,
|
|
19840
20430
|
filePath: s.filePath
|
|
19841
20431
|
});
|
|
20432
|
+
if (includeFile(s.filePath)) {
|
|
20433
|
+
dispositionSuppressed += inScope(getSuppressedDiagnostics(s.filePath)) + inScope(diagnostics) - inScope(kept);
|
|
20434
|
+
}
|
|
19842
20435
|
if (policyKept.length === kept.length && kept.length === diagnostics.length)
|
|
19843
20436
|
return s;
|
|
19844
20437
|
return summarizeDiagnostics(s.filePath, policyKept, s.hasFinalSnapshot);
|
|
@@ -19864,14 +20457,19 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19864
20457
|
return s.blocking > 0 || s.errors > 0 || s.warnings > 0 || s.advisories > 0 || (s.diagnostics ?? []).some((d) => d.stale);
|
|
19865
20458
|
});
|
|
19866
20459
|
const pathsNote = isFullMode ? "" : pathsScopeCacheOnlyNote(pathsScope);
|
|
20460
|
+
const suppressedLine = dispositionSuppressedLine(dispositionSuppressed, suppressedBreakdown);
|
|
20461
|
+
const suppressedNote = suppressedLine ? `
|
|
20462
|
+
${suppressedLine}` : "";
|
|
20463
|
+
const suppressedDetails = dispositionSuppressed > 0 ? { dispositionSuppressed } : {};
|
|
19867
20464
|
if (withIssues.length === 0) {
|
|
19868
|
-
const text = (visibleSummaries.length === 0 ? "No files diagnosed yet this session." : `No ${severity === "all" ? "" : severity + " "}issues across ${visibleSummaries.length} file${visibleSummaries.length === 1 ? "" : "s"} diagnosed this session. \u2713`) + staleNote + pathsNote;
|
|
20465
|
+
const text = (visibleSummaries.length === 0 ? "No files diagnosed yet this session." : `No ${severity === "all" ? "" : severity + " "}issues across ${visibleSummaries.length} file${visibleSummaries.length === 1 ? "" : "s"} diagnosed this session. \u2713`) + staleNote + suppressedNote + pathsNote;
|
|
19869
20466
|
return {
|
|
19870
20467
|
content: [{ type: "text", text }],
|
|
19871
20468
|
details: {
|
|
19872
20469
|
...detailOverrides,
|
|
19873
20470
|
filesChecked: visibleSummaries.length,
|
|
19874
|
-
staleDropped
|
|
20471
|
+
staleDropped,
|
|
20472
|
+
...suppressedDetails
|
|
19875
20473
|
}
|
|
19876
20474
|
};
|
|
19877
20475
|
}
|
|
@@ -19883,7 +20481,7 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19883
20481
|
let totalWarnings = 0;
|
|
19884
20482
|
let totalAdvisories = 0;
|
|
19885
20483
|
for (const s of rendered) {
|
|
19886
|
-
const rel =
|
|
20484
|
+
const rel = path38.relative(cwd, s.filePath);
|
|
19887
20485
|
const parts = [];
|
|
19888
20486
|
if (s.blocking > 0)
|
|
19889
20487
|
parts.push(`\u{1F534} ${s.blocking} blocking`);
|
|
@@ -19935,7 +20533,10 @@ Summary (${visibleSummaries.length} files diagnosed this session):`,
|
|
|
19935
20533
|
].filter(Boolean).join("\n");
|
|
19936
20534
|
return {
|
|
19937
20535
|
content: [
|
|
19938
|
-
{
|
|
20536
|
+
{
|
|
20537
|
+
type: "text",
|
|
20538
|
+
text: lines.join("\n") + summary + staleNote + suppressedNote
|
|
20539
|
+
}
|
|
19939
20540
|
],
|
|
19940
20541
|
details: {
|
|
19941
20542
|
...detailOverrides,
|
|
@@ -19944,14 +20545,15 @@ Summary (${visibleSummaries.length} files diagnosed this session):`,
|
|
|
19944
20545
|
totalErrors,
|
|
19945
20546
|
totalWarnings,
|
|
19946
20547
|
totalAdvisories,
|
|
19947
|
-
staleDropped
|
|
20548
|
+
staleDropped,
|
|
20549
|
+
...suppressedDetails
|
|
19948
20550
|
}
|
|
19949
20551
|
};
|
|
19950
20552
|
}
|
|
19951
20553
|
|
|
19952
20554
|
// dist/tools/lsp-navigation.js
|
|
19953
20555
|
import * as nodeFs2 from "node:fs";
|
|
19954
|
-
import * as
|
|
20556
|
+
import * as path39 from "node:path";
|
|
19955
20557
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
19956
20558
|
|
|
19957
20559
|
// dist/tools/lsp-structured-output.js
|
|
@@ -20311,6 +20913,12 @@ function operationSupportStatus(operation, support) {
|
|
|
20311
20913
|
return support.callHierarchy;
|
|
20312
20914
|
return null;
|
|
20313
20915
|
}
|
|
20916
|
+
function noServerAnsweredText(filePath) {
|
|
20917
|
+
const { disabledServerIds, fallbackServerIds } = disabledPrimaries(filePath);
|
|
20918
|
+
const cause = primaryUnavailableCause([...fallbackServerIds, ...disabledServerIds], disabledServerIds, fallbackServerIds);
|
|
20919
|
+
const who = disabledServerIds.length > 0 ? `Primary LSP (${disabledServerIds.join(", ")}) did not answer` : "no language server answered";
|
|
20920
|
+
return `No LSP server available for ${path39.basename(filePath)}: ${who} (${PRIMARY_UNAVAILABLE_CAUSE[cause]}).`;
|
|
20921
|
+
}
|
|
20314
20922
|
function emptyReasonForOperation(operation) {
|
|
20315
20923
|
if (operation === "signatureHelp")
|
|
20316
20924
|
return "position-sensitive-or-no-signature";
|
|
@@ -20661,7 +21269,7 @@ function collectSearchReadsForOperation(operation, result, callHierarchyItem) {
|
|
|
20661
21269
|
}
|
|
20662
21270
|
function formatCapabilities(snapshots, filePath) {
|
|
20663
21271
|
if (snapshots.length === 0) {
|
|
20664
|
-
return filePath ? `No active LSP server for ${
|
|
21272
|
+
return filePath ? `No active LSP server for ${path39.basename(filePath)}. Open/touch the file first or run another LSP operation to start the server.` : "No active LSP servers in this session.";
|
|
20665
21273
|
}
|
|
20666
21274
|
const rows = [
|
|
20667
21275
|
["definition", (s) => !!s.operationSupport.definition],
|
|
@@ -20691,7 +21299,7 @@ function formatCapabilities(snapshots, filePath) {
|
|
|
20691
21299
|
];
|
|
20692
21300
|
const lines = [];
|
|
20693
21301
|
for (const snapshot of snapshots) {
|
|
20694
|
-
const label = filePath ? `${snapshot.serverId} (${
|
|
21302
|
+
const label = filePath ? `${snapshot.serverId} (${path39.basename(filePath)})` : `${snapshot.serverId} (${snapshot.root})`;
|
|
20695
21303
|
lines.push(label);
|
|
20696
21304
|
for (const [name, supported, note] of rows) {
|
|
20697
21305
|
const suffix = note ? ` (${note})` : "";
|
|
@@ -20719,7 +21327,7 @@ function classifyCodeActions(actions) {
|
|
|
20719
21327
|
}
|
|
20720
21328
|
return { quickfix, refactor, other };
|
|
20721
21329
|
}
|
|
20722
|
-
async function openFileBestEffort(lspService, filePath, waitForDiagnostics = false) {
|
|
21330
|
+
async function openFileBestEffort(lspService, filePath, waitForDiagnostics = false, excludeServerIds) {
|
|
20723
21331
|
let fileContent;
|
|
20724
21332
|
try {
|
|
20725
21333
|
fileContent = nodeFs2.readFileSync(filePath, "utf-8");
|
|
@@ -20732,7 +21340,8 @@ async function openFileBestEffort(lspService, filePath, waitForDiagnostics = fal
|
|
|
20732
21340
|
await lspService.touchFile(filePath, fileContent, {
|
|
20733
21341
|
diagnostics: waitForDiagnostics ? "document" : "none",
|
|
20734
21342
|
source: "lsp_navigation",
|
|
20735
|
-
clientScope: waitForDiagnostics ? "all" : "primary"
|
|
21343
|
+
clientScope: waitForDiagnostics ? "all" : "primary",
|
|
21344
|
+
...excludeServerIds !== void 0 && { excludeServerIds }
|
|
20736
21345
|
});
|
|
20737
21346
|
} catch {
|
|
20738
21347
|
}
|
|
@@ -20882,6 +21491,7 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
20882
21491
|
const session = mutationDeps?.runtime?.captureSessionGeneration?.();
|
|
20883
21492
|
const startedAt = Date.now();
|
|
20884
21493
|
let supported = null;
|
|
21494
|
+
let noFileClient = false;
|
|
20885
21495
|
let diagnosticsMode = "unknown";
|
|
20886
21496
|
let columnResolution;
|
|
20887
21497
|
let openedFileContent;
|
|
@@ -21031,7 +21641,7 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21031
21641
|
resultCount: 0
|
|
21032
21642
|
});
|
|
21033
21643
|
}
|
|
21034
|
-
const filePath = rawPath ?
|
|
21644
|
+
const filePath = rawPath ? resolveHostToolPath(rawPath, ctx.cwd || ".") : "";
|
|
21035
21645
|
let filePathIsDirectory = false;
|
|
21036
21646
|
if (filePath) {
|
|
21037
21647
|
try {
|
|
@@ -21058,16 +21668,17 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21058
21668
|
});
|
|
21059
21669
|
}
|
|
21060
21670
|
if (operation === "workspaceDiagnostics") {
|
|
21671
|
+
const policyCwd = ctx.cwd || process.cwd();
|
|
21061
21672
|
const wsDiagSupport = rawPath ? await lspService.getWorkspaceDiagnosticsSupport(filePath) : await lspService.getWorkspaceDiagnosticsSupport(void 0, workspaceScopeAttribution);
|
|
21062
21673
|
diagnosticsMode = wsDiagSupport?.mode ?? "unknown";
|
|
21063
21674
|
if (rawPath && !filePathIsDirectory) {
|
|
21064
|
-
const hasLSP2 = lspService.supportsLSP(filePath);
|
|
21675
|
+
const hasLSP2 = lspService.supportsLSP(filePath) || disabledPrimaries(filePath).disabledServerIds.length > 0;
|
|
21065
21676
|
if (!hasLSP2) {
|
|
21066
21677
|
return finalize({
|
|
21067
21678
|
content: [
|
|
21068
21679
|
{
|
|
21069
21680
|
type: "text",
|
|
21070
|
-
text: `No LSP server available for ${
|
|
21681
|
+
text: `No LSP server available for ${path39.basename(filePath)}. Check that the language server is installed.`
|
|
21071
21682
|
}
|
|
21072
21683
|
],
|
|
21073
21684
|
isError: true
|
|
@@ -21078,8 +21689,12 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21078
21689
|
resultCount: 0
|
|
21079
21690
|
});
|
|
21080
21691
|
}
|
|
21081
|
-
|
|
21082
|
-
const
|
|
21692
|
+
const excludeServerIds = configDisabledAuxiliaryLspServerIds((name) => getFlag(name, ctx.cwd));
|
|
21693
|
+
const openedContent = await openFileBestEffort(lspService, filePath, true, excludeServerIds);
|
|
21694
|
+
const policy = applyProbeFindingPolicy(filePath, await lspService.getDiagnostics(filePath, void 0, excludeServerIds), policyCwd, openedContent, "all", "lsp_navigation");
|
|
21695
|
+
const diagnostics = policy.kept;
|
|
21696
|
+
const suppressedLine = dispositionSuppressedLine(policy.suppressed);
|
|
21697
|
+
const primaryUnavailable = describePrimaryUnavailable(void 0, lspService.getDiagnosticsHealth(filePath))?.text;
|
|
21083
21698
|
const result3 = [
|
|
21084
21699
|
{
|
|
21085
21700
|
filePath,
|
|
@@ -21098,14 +21713,23 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21098
21713
|
{
|
|
21099
21714
|
type: "text",
|
|
21100
21715
|
text: `${note2}
|
|
21101
|
-
${JSON.stringify(result3)}`
|
|
21716
|
+
${JSON.stringify(result3)}${primaryUnavailable ? `
|
|
21717
|
+
Note: ${primaryUnavailable}` : ""}${suppressedLine ? `
|
|
21718
|
+
Note: ${suppressedLine}` : ""}`
|
|
21102
21719
|
}
|
|
21103
21720
|
],
|
|
21104
21721
|
details: {
|
|
21105
21722
|
operation,
|
|
21106
21723
|
resultCount: resultCount2,
|
|
21107
21724
|
diagnosticsMode,
|
|
21108
|
-
coverage: "requested-file"
|
|
21725
|
+
coverage: "requested-file",
|
|
21726
|
+
...policy.suppressed > 0 && {
|
|
21727
|
+
dispositionSuppressed: policy.suppressed
|
|
21728
|
+
},
|
|
21729
|
+
...primaryUnavailable !== void 0 && {
|
|
21730
|
+
unconfirmed: true,
|
|
21731
|
+
primaryUnavailable
|
|
21732
|
+
}
|
|
21109
21733
|
}
|
|
21110
21734
|
}, {
|
|
21111
21735
|
operation,
|
|
@@ -21114,12 +21738,23 @@ ${JSON.stringify(result3)}`
|
|
|
21114
21738
|
resultCount: resultCount2
|
|
21115
21739
|
});
|
|
21116
21740
|
}
|
|
21117
|
-
const allDiagnostics = await lspService.getAllDiagnostics();
|
|
21118
|
-
|
|
21119
|
-
|
|
21120
|
-
|
|
21121
|
-
|
|
21122
|
-
|
|
21741
|
+
const allDiagnostics = await lspService.getAllDiagnostics(configDisabledAuxiliaryLspServerIds((name) => getFlag(name, ctx.cwd)));
|
|
21742
|
+
let snapshotSuppressed = 0;
|
|
21743
|
+
const result2 = Array.from(allDiagnostics.entries()).map(([trackedFile, { diags, ts }]) => {
|
|
21744
|
+
let kept = diags;
|
|
21745
|
+
if (diags.length > 0) {
|
|
21746
|
+
const policy = applyProbeFindingPolicy(trackedFile, diags, policyCwd, readFileContent(trackedFile), "all", "lsp_navigation");
|
|
21747
|
+
snapshotSuppressed += policy.suppressed;
|
|
21748
|
+
kept = policy.kept;
|
|
21749
|
+
}
|
|
21750
|
+
return {
|
|
21751
|
+
filePath: trackedFile,
|
|
21752
|
+
diagnostics: kept,
|
|
21753
|
+
count: kept.length,
|
|
21754
|
+
lag: formatCacheAgeLabel(ts)
|
|
21755
|
+
};
|
|
21756
|
+
});
|
|
21757
|
+
const snapshotSuppressedLine = dispositionSuppressedLine(snapshotSuppressed);
|
|
21123
21758
|
const noteMap2 = {
|
|
21124
21759
|
"push-only": "Note: push-only tracked diagnostics snapshot (not full workspace pull diagnostics).",
|
|
21125
21760
|
pull: "Note: tracked diagnostics snapshot from active clients. Provide path to force file-level diagnostics collection"
|
|
@@ -21130,14 +21765,18 @@ ${JSON.stringify(result3)}`
|
|
|
21130
21765
|
{
|
|
21131
21766
|
type: "text",
|
|
21132
21767
|
text: `${note}
|
|
21133
|
-
${JSON.stringify(result2)}`
|
|
21768
|
+
${JSON.stringify(result2)}${snapshotSuppressedLine ? `
|
|
21769
|
+
Note: ${snapshotSuppressedLine}` : ""}`
|
|
21134
21770
|
}
|
|
21135
21771
|
],
|
|
21136
21772
|
details: {
|
|
21137
21773
|
operation,
|
|
21138
21774
|
resultCount: result2.length,
|
|
21139
21775
|
diagnosticsMode,
|
|
21140
|
-
coverage: "tracked-open-files"
|
|
21776
|
+
coverage: "tracked-open-files",
|
|
21777
|
+
...snapshotSuppressed > 0 && {
|
|
21778
|
+
dispositionSuppressed: snapshotSuppressed
|
|
21779
|
+
}
|
|
21141
21780
|
}
|
|
21142
21781
|
}, {
|
|
21143
21782
|
operation,
|
|
@@ -21168,7 +21807,7 @@ ${JSON.stringify(result2)}`
|
|
|
21168
21807
|
content: [
|
|
21169
21808
|
{
|
|
21170
21809
|
type: "text",
|
|
21171
|
-
text: `No LSP server available for ${
|
|
21810
|
+
text: disabledPrimaries(filePath).disabledServerIds.length > 0 ? noServerAnsweredText(filePath) : `No LSP server available for ${path39.basename(filePath)}. Check that the language server is installed.`
|
|
21172
21811
|
}
|
|
21173
21812
|
],
|
|
21174
21813
|
isError: true
|
|
@@ -21181,13 +21820,14 @@ ${JSON.stringify(result2)}`
|
|
|
21181
21820
|
}
|
|
21182
21821
|
if (needsFilePath) {
|
|
21183
21822
|
const support = await lspService.getOperationSupport(filePath);
|
|
21823
|
+
noFileClient = support === null;
|
|
21184
21824
|
supported = operationSupportStatus(operation, support);
|
|
21185
21825
|
if (supported === false) {
|
|
21186
21826
|
return finalize({
|
|
21187
21827
|
content: [
|
|
21188
21828
|
{
|
|
21189
21829
|
type: "text",
|
|
21190
|
-
text: `LSP server for ${
|
|
21830
|
+
text: `LSP server for ${path39.basename(filePath)} does not advertise support for ${operation}`
|
|
21191
21831
|
}
|
|
21192
21832
|
],
|
|
21193
21833
|
isError: true,
|
|
@@ -21316,7 +21956,7 @@ ${JSON.stringify(result2)}`
|
|
|
21316
21956
|
if (!newFilePath || newFilePath.trim().length === 0) {
|
|
21317
21957
|
throw new Error("__BADINPUT__ newFilePath parameter required for rename_file");
|
|
21318
21958
|
}
|
|
21319
|
-
const resolvedNewFilePath =
|
|
21959
|
+
const resolvedNewFilePath = resolveHostToolPath(newFilePath, ctx.cwd || ".");
|
|
21320
21960
|
const result2 = await lspService.renameFile(filePath, resolvedNewFilePath, {
|
|
21321
21961
|
cwd: ctx.cwd || ".",
|
|
21322
21962
|
apply: apply ?? false,
|
|
@@ -21460,7 +22100,15 @@ ${JSON.stringify(result2)}`
|
|
|
21460
22100
|
}, { operation, filePath, failureKind: "lsp_error", resultCount: 0 });
|
|
21461
22101
|
}
|
|
21462
22102
|
const isEmpty = !result || Array.isArray(result) && result.length === 0;
|
|
21463
|
-
|
|
22103
|
+
if (isEmpty && noFileClient) {
|
|
22104
|
+
return finalize({
|
|
22105
|
+
content: [
|
|
22106
|
+
{ type: "text", text: noServerAnsweredText(filePath) }
|
|
22107
|
+
],
|
|
22108
|
+
isError: true
|
|
22109
|
+
}, { operation, filePath, failureKind: "no_server", resultCount: 0 });
|
|
22110
|
+
}
|
|
22111
|
+
const fileCtx = filePath ? " at " + path39.basename(filePath) : "";
|
|
21464
22112
|
const lineCtx = line ? ":" + line + ":" + character : "";
|
|
21465
22113
|
let output = isEmpty ? "No results for " + operation + fileCtx + lineCtx : JSON.stringify(result);
|
|
21466
22114
|
if (isEmpty && operation === "workspaceSymbol" && !rawPath) {
|
|
@@ -21702,11 +22350,11 @@ function resolveDefaultCwd() {
|
|
|
21702
22350
|
const fromArg = process.argv.find((arg) => arg.startsWith("--cwd="))?.slice("--cwd=".length);
|
|
21703
22351
|
return fromArg ?? process.env.PI_LENS_MCP_CWD ?? process.cwd();
|
|
21704
22352
|
}
|
|
21705
|
-
var DEFAULT_CWD =
|
|
22353
|
+
var DEFAULT_CWD = path40.resolve(resolveDefaultCwd());
|
|
21706
22354
|
var lspReadyCwds = /* @__PURE__ */ new Set();
|
|
21707
22355
|
var SERVER_FILE = fileURLToPath3(import.meta.url);
|
|
21708
|
-
var SERVER_DIR =
|
|
21709
|
-
var WORKER_PATH =
|
|
22356
|
+
var SERVER_DIR = path40.dirname(SERVER_FILE);
|
|
22357
|
+
var WORKER_PATH = path40.join(SERVER_DIR, "worker.js");
|
|
21710
22358
|
var REBUILD_SCRIPT = resolveRebuildScript(SERVER_FILE);
|
|
21711
22359
|
var STALENESS_STAT_PATH = process.env.PI_LENS_MCP_STALENESS_STAT_PATH ?? SERVER_FILE;
|
|
21712
22360
|
var BUILD_STAMP = computeBuildStamp(STALENESS_STAT_PATH);
|
|
@@ -21728,7 +22376,7 @@ function isWarmBuildStale() {
|
|
|
21728
22376
|
function findRepoRoot(start) {
|
|
21729
22377
|
let dir = start;
|
|
21730
22378
|
for (let depth = 0; depth < 6; depth++) {
|
|
21731
|
-
const pkgPath =
|
|
22379
|
+
const pkgPath = path40.join(dir, "package.json");
|
|
21732
22380
|
if (fs25.existsSync(pkgPath)) {
|
|
21733
22381
|
try {
|
|
21734
22382
|
const pkg = JSON.parse(fs25.readFileSync(pkgPath, "utf8"));
|
|
@@ -21737,16 +22385,16 @@ function findRepoRoot(start) {
|
|
|
21737
22385
|
} catch {
|
|
21738
22386
|
}
|
|
21739
22387
|
}
|
|
21740
|
-
const parent =
|
|
22388
|
+
const parent = path40.dirname(dir);
|
|
21741
22389
|
if (parent === dir)
|
|
21742
22390
|
break;
|
|
21743
22391
|
dir = parent;
|
|
21744
22392
|
}
|
|
21745
|
-
return
|
|
22393
|
+
return path40.resolve(start, "..", "..");
|
|
21746
22394
|
}
|
|
21747
|
-
var REPO_ROOT = process.env.PI_LENS_MCP_REPO_ROOT ?
|
|
22395
|
+
var REPO_ROOT = process.env.PI_LENS_MCP_REPO_ROOT ? path40.resolve(process.env.PI_LENS_MCP_REPO_ROOT) : findRepoRoot(SERVER_DIR);
|
|
21748
22396
|
async function ensureReady(cwd) {
|
|
21749
|
-
const normalized =
|
|
22397
|
+
const normalized = path40.resolve(cwd);
|
|
21750
22398
|
if (!shouldInitializeSessionRoot(normalized, lspReadyCwds)) {
|
|
21751
22399
|
return;
|
|
21752
22400
|
}
|
|
@@ -21792,22 +22440,17 @@ function getAutoSessionStatus() {
|
|
|
21792
22440
|
}
|
|
21793
22441
|
var IPC_PATH = ipcPathForCwd(DEFAULT_CWD);
|
|
21794
22442
|
function rejectForeignTurnCwd(route, cwd) {
|
|
21795
|
-
const message = `${route} cwd outside this server's workspace: ${
|
|
22443
|
+
const message = `${route} cwd outside this server's workspace: ${path40.resolve(cwd)} not within ${DEFAULT_CWD}`;
|
|
21796
22444
|
console.error(`[pi-lens-mcp] rejected ${message}`);
|
|
21797
22445
|
return message;
|
|
21798
22446
|
}
|
|
21799
22447
|
function isWithinServerWorkspace(cwd) {
|
|
21800
|
-
const target =
|
|
21801
|
-
const rel =
|
|
21802
|
-
return !rel.startsWith("..") && !
|
|
22448
|
+
const target = path40.resolve(cwd);
|
|
22449
|
+
const rel = path40.relative(DEFAULT_CWD, target);
|
|
22450
|
+
return !rel.startsWith("..") && !path40.isAbsolute(rel);
|
|
21803
22451
|
}
|
|
21804
22452
|
function startIpcServer() {
|
|
21805
|
-
|
|
21806
|
-
try {
|
|
21807
|
-
fs25.unlinkSync(IPC_PATH);
|
|
21808
|
-
} catch {
|
|
21809
|
-
}
|
|
21810
|
-
}
|
|
22453
|
+
unlinkStaleUnixSocket(IPC_PATH);
|
|
21811
22454
|
const requestQueue = createWarmIpcRequestQueue();
|
|
21812
22455
|
const ipc = net.createServer((socket) => {
|
|
21813
22456
|
socket.setEncoding("utf8");
|
|
@@ -21909,12 +22552,6 @@ function startIpcServer() {
|
|
|
21909
22552
|
ipc.close();
|
|
21910
22553
|
} catch {
|
|
21911
22554
|
}
|
|
21912
|
-
if (process.platform !== "win32") {
|
|
21913
|
-
try {
|
|
21914
|
-
fs25.unlinkSync(IPC_PATH);
|
|
21915
|
-
} catch {
|
|
21916
|
-
}
|
|
21917
|
-
}
|
|
21918
22555
|
};
|
|
21919
22556
|
process.on("exit", cleanup);
|
|
21920
22557
|
}
|
|
@@ -21975,7 +22612,11 @@ var lensDiagnosticsTool = createLensDiagnosticsTool(
|
|
|
21975
22612
|
// `lens-guard` off — a config bypass on a durable cross-surface store.
|
|
21976
22613
|
// Matches index.ts:1656 and the two sibling readers
|
|
21977
22614
|
// (clients/runtime-tool-call.ts, clients/runtime-tool-result.ts).
|
|
21978
|
-
() => isLensGuardEnabled()
|
|
22615
|
+
() => isLensGuardEnabled(),
|
|
22616
|
+
// #4323: `opengrep.enabled=false` keeps the explicit `source=lsp` probe from
|
|
22617
|
+
// starting Opengrep, as it does for `pilens_analyze`. Resolved per call
|
|
22618
|
+
// against the call's own project, like `lspNavigationTool` below (#792).
|
|
22619
|
+
(name, cwd) => createMcpHost(void 0, cwd).getFlag(name)
|
|
21979
22620
|
);
|
|
21980
22621
|
var astGrepClient = new AstGrepClient();
|
|
21981
22622
|
var astGrepSearchTool = createAstGrepSearchTool(astGrepClient);
|
|
@@ -22294,7 +22935,7 @@ function enabledToolsForCwd(cwd) {
|
|
|
22294
22935
|
}
|
|
22295
22936
|
function formatAnalyze(result, cwd, mode, servedBy) {
|
|
22296
22937
|
const lspNote = result.lsp ? ` \xB7 lsp ${result.lsp.diagnosticCount} (${result.lsp.status}${result.lsp.failureKind ? `: ${result.lsp.failureKind}` : ""}, ${result.lsp.durationMs}ms)` : "";
|
|
22297
|
-
const summary = `${
|
|
22938
|
+
const summary = `${path40.relative(cwd, result.filePath) || result.filePath} [${mode}] \u2014 ${result.counts.blockers} blocking, ${result.counts.warnings} warning(s), ${result.counts.advisories} advisory(ies), ${result.counts.diagnostics} total` + (result.latency ? ` \xB7 ${result.latency.totalDurationMs}ms` : "") + lspNote + (result.counts.fixed > 0 ? ` \xB7 ${result.counts.fixed} auto-fixed` : "") + (servedBy ? `
|
|
22298
22939
|
|
|
22299
22940
|
servedBy: ${servedBy}` : "");
|
|
22300
22941
|
return renderToolText(summary, servedBy ? { ...result, servedBy } : result);
|
|
@@ -22428,7 +23069,7 @@ ${outcome.output}`, {
|
|
|
22428
23069
|
}
|
|
22429
23070
|
const { deduped, byRule, byFile } = summarizeScan(snapshot.diagnostics);
|
|
22430
23071
|
const topRules = Object.entries(byRule).sort((a, b) => b[1] - a[1]);
|
|
22431
|
-
const topFiles = Object.entries(byFile).sort((a, b) => b[1] - a[1]).slice(0, 15).map(([file, count]) => ({ file:
|
|
23072
|
+
const topFiles = Object.entries(byFile).sort((a, b) => b[1] - a[1]).slice(0, 15).map(([file, count]) => ({ file: path40.relative(cwd, file), count }));
|
|
22432
23073
|
const summaryLines = [
|
|
22433
23074
|
`Scanned ${snapshot.filesScanned} file(s) [${snapshot.runners.join(", ")}] \u2192 ${deduped.length} unique diagnostic(s)` + (snapshot.diagnostics.length !== deduped.length ? ` (${snapshot.diagnostics.length} raw, ${snapshot.diagnostics.length - deduped.length} duplicate)` : ""),
|
|
22434
23075
|
...topRules.slice(0, 12).map(([rule, count]) => ` ${count}\xD7 ${rule}`)
|
|
@@ -22439,8 +23080,13 @@ ${outcome.output}`, {
|
|
|
22439
23080
|
const skipNotice = generatedSkipNotice(snapshot, "mcp");
|
|
22440
23081
|
if (skipNotice)
|
|
22441
23082
|
summaryLines.push(skipNotice);
|
|
23083
|
+
const { dispositionSuppressed } = snapshot;
|
|
23084
|
+
const suppressedLine = dispositionSuppressedLine(dispositionSuppressed);
|
|
23085
|
+
if (suppressedLine)
|
|
23086
|
+
summaryLines.push(suppressedLine);
|
|
22442
23087
|
return renderToolText(summaryLines.join("\n"), {
|
|
22443
23088
|
filesScanned: snapshot.filesScanned,
|
|
23089
|
+
...dispositionSuppressed > 0 ? { dispositionSuppressed } : {},
|
|
22444
23090
|
runners: snapshot.runners,
|
|
22445
23091
|
uniqueDiagnostics: deduped.length,
|
|
22446
23092
|
rawDiagnostics: snapshot.diagnostics.length,
|
|
@@ -22481,7 +23127,7 @@ ${stalenessNote}` : ""), {
|
|
|
22481
23127
|
}
|
|
22482
23128
|
const lines = [
|
|
22483
23129
|
`Top ${results.length} file(s) for "${query}":`,
|
|
22484
|
-
...results.map((result, i) => ` ${i + 1}. ${
|
|
23130
|
+
...results.map((result, i) => ` ${i + 1}. ${path40.relative(cwd, result.file)} (score ${result.score.toFixed(2)}, ${result.hits} hit(s), line ${result.startLine})`),
|
|
22485
23131
|
...stalenessNote ? ["", stalenessNote] : [],
|
|
22486
23132
|
...coverage ? [
|
|
22487
23133
|
`Index covers ${coverage.files} files${coverage.truncated ? " (capped \u2014 results may be incomplete)" : ""}.`
|
|
@@ -22491,7 +23137,7 @@ ${stalenessNote}` : ""), {
|
|
|
22491
23137
|
query,
|
|
22492
23138
|
coverage,
|
|
22493
23139
|
results: results.map((result) => {
|
|
22494
|
-
const relFile =
|
|
23140
|
+
const relFile = path40.relative(cwd, result.file);
|
|
22495
23141
|
return {
|
|
22496
23142
|
file: relFile,
|
|
22497
23143
|
score: result.score,
|
|
@@ -22530,12 +23176,12 @@ ${stalenessNote}` : ""), {
|
|
|
22530
23176
|
});
|
|
22531
23177
|
if (!report.available) {
|
|
22532
23178
|
return {
|
|
22533
|
-
...renderToolText(`No module report for ${
|
|
23179
|
+
...renderToolText(`No module report for ${path40.relative(cwd, path40.resolve(cwd, file))} \u2014 not a symbol-bearing file, or unreadable.`, report, true),
|
|
22534
23180
|
isError: true
|
|
22535
23181
|
};
|
|
22536
23182
|
}
|
|
22537
23183
|
const graphStaleness = graphStalenessNote(report.graphBuiltAt, "Review graph");
|
|
22538
|
-
const summary = `${
|
|
23184
|
+
const summary = `${path40.relative(cwd, report.path) || report.path} [${report.staleness}] \u2014 ${report.summary.symbols} symbol(s), ${report.summary.exports} exported, ${report.api.length} in public API` + (graphStaleness ? `
|
|
22539
23185
|
|
|
22540
23186
|
${graphStaleness}` : "");
|
|
22541
23187
|
if (view === "compact") {
|
|
@@ -22596,7 +23242,7 @@ ${graphStaleness}` : "");
|
|
|
22596
23242
|
if (!result.found) {
|
|
22597
23243
|
const suggestionSuffix = result.suggestions?.length ? ` Did you mean: ${result.suggestions.join(", ")}?` : " Use pilens_module_report to list symbols.";
|
|
22598
23244
|
return {
|
|
22599
|
-
...renderToolText(`Symbol "${symbol}" not found in ${
|
|
23245
|
+
...renderToolText(`Symbol "${symbol}" not found in ${path40.basename(file)}.${suggestionSuffix}`, {
|
|
22600
23246
|
found: false,
|
|
22601
23247
|
...result.suggestions ? { suggestions: result.suggestions } : {}
|
|
22602
23248
|
}),
|
|
@@ -22605,7 +23251,7 @@ ${graphStaleness}` : "");
|
|
|
22605
23251
|
}
|
|
22606
23252
|
const sigSuffix = result.signature ? ` ${result.signature}` : "";
|
|
22607
23253
|
const ambiguityNote = result.ambiguous ? ` (${result.ambiguous.count} matches \u2014 returned the ${result.kind}; pass \`kind\` to disambiguate: ${result.ambiguous.kinds.join(", ")})` : "";
|
|
22608
|
-
const header = `${result.kind} ${result.name}${ambiguityNote}${sigSuffix} ${
|
|
23254
|
+
const header = `${result.kind} ${result.name}${ambiguityNote}${sigSuffix} ${path40.relative(cwd, result.path)}:${result.startLine}-${result.endLine}`;
|
|
22609
23255
|
return {
|
|
22610
23256
|
content: [
|
|
22611
23257
|
{
|
|
@@ -22643,14 +23289,14 @@ ${result.source ?? ""}`
|
|
|
22643
23289
|
|
|
22644
23290
|
Nested outline:
|
|
22645
23291
|
${JSON.stringify(result.outline)}` : "";
|
|
22646
|
-
const text = result.error ? `Could not read enclosing range in ${
|
|
23292
|
+
const text = result.error ? `Could not read enclosing range in ${path40.basename(file)}:${result.line}: ${result.error}${warningSuffix}${outlineSuffix}` : `No enclosing symbol/callback found in ${path40.basename(file)}:${result.line}.${warningSuffix}`;
|
|
22647
23293
|
return {
|
|
22648
23294
|
...renderToolText(text, { found: false, line: result.line }),
|
|
22649
23295
|
isError: true
|
|
22650
23296
|
};
|
|
22651
23297
|
}
|
|
22652
23298
|
const range = result.partial ? `${result.startLine}-${result.endLine} (partial of ${result.enclosingStartLine}-${result.enclosingEndLine})` : `${result.startLine}-${result.endLine}`;
|
|
22653
|
-
const header = `${result.kind} ${result.name} ${
|
|
23299
|
+
const header = `${result.kind} ${result.name} ${path40.relative(cwd, result.path)}:${range}`;
|
|
22654
23300
|
return {
|
|
22655
23301
|
content: [
|
|
22656
23302
|
{
|
|
@@ -22685,7 +23331,7 @@ ${result.source ?? ""}`
|
|
|
22685
23331
|
]),
|
|
22686
23332
|
...renderLspBrokenStatusLines(brokenServers),
|
|
22687
23333
|
...renderDegradationLines(degradations),
|
|
22688
|
-
last ? `Last dispatch: ${
|
|
23334
|
+
last ? `Last dispatch: ${path40.basename(last.filePath)} \u2014 ${last.totalDurationMs}ms, ${last.totalDiagnostics} diagnostic(s)` : "Last dispatch: none yet",
|
|
22689
23335
|
`Diagnostics this session: ${stats.totalShown} shown \xB7 ${stats.totalAutoFixed} auto-fixed \xB7 ${stats.totalUnresolved} unresolved`,
|
|
22690
23336
|
autoSession ? `Auto session_start: ${autoSession.succeeded ? "succeeded" : autoSession.error ? "FAILED" : autoSession.attempted ? "in progress" : "not yet attempted"}${autoSession.firedAt ? ` (fired ${autoSession.firedAt})` : ""}${autoSession.error ? ` \u2014 ${autoSession.error}` : ""}` : "Auto session_start: disabled (PI_LENS_MCP_AUTO_SESSION not set)",
|
|
22691
23337
|
turnEnd ? `Stop-hook turn-end: ${turnEnd.ran} ran \xB7 ${turnEnd.skipped} skipped${turnEnd.lastRunAt ? ` (last ran ${turnEnd.lastRunAt})` : ""}${turnEnd.lastSkipReason ? ` \u2014 last skip: ${turnEnd.lastSkipReason}${turnEnd.lastSkipAt ? ` at ${turnEnd.lastSkipAt}` : ""}` : ""}` : "Stop-hook turn-end: no activity recorded (hook not installed, or no Stop yet)",
|
|
@@ -22751,7 +23397,7 @@ ${result.source ?? ""}`
|
|
|
22751
23397
|
const limit = typeof args.limit === "number" && Number.isFinite(args.limit) ? Math.max(1, Math.floor(args.limit)) : 5;
|
|
22752
23398
|
const fileFilter = typeof args.file === "string" ? args.file : void 0;
|
|
22753
23399
|
const recent = recentLatency(limit, fileFilter);
|
|
22754
|
-
const summary = recent.length === 0 ? "No dispatch latency reports yet." : recent.map((report) => `${
|
|
23400
|
+
const summary = recent.length === 0 ? "No dispatch latency reports yet." : recent.map((report) => `${path40.basename(report.filePath)}: ${report.totalDurationMs}ms (${report.totalDiagnostics} diag${report.stoppedEarly ? ", stopped early" : ""})`).join("\n");
|
|
22755
23401
|
return renderToolText(summary, recent);
|
|
22756
23402
|
}
|
|
22757
23403
|
if (name === "pilens_session_start") {
|