pi-lens 4.4.2 → 4.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +306 -0
- package/README.md +13 -1
- package/dist/{chunk-VITUCP5A.js → chunk-24AKHFGP.js} +9 -7
- package/dist/{chunk-JSQFTSC6.js → chunk-2FN63LPV.js} +11 -11
- package/dist/{chunk-CF24OIYI.js → chunk-2KXTHF3M.js} +20 -20
- package/dist/{chunk-ESBQHFMJ.js → chunk-3DA2JDOL.js} +543 -349
- package/dist/{chunk-RWWYJ623.js → chunk-3KAZU3VR.js} +1 -1
- package/dist/chunk-3PTHXJXR.js +28 -0
- package/dist/chunk-3QED2P4V.js +31 -0
- package/dist/{chunk-N2H3ZPZY.js → chunk-3RKP3FMS.js} +1 -0
- package/dist/{chunk-XVF2VVXP.js → chunk-5HSRT26B.js} +2 -2
- package/dist/{chunk-XKIZ2HNN.js → chunk-5IUSNGOC.js} +18 -16
- package/dist/{chunk-EJIUXPBX.js → chunk-5OFV52AM.js} +1 -1
- package/dist/{chunk-AW7R2GWG.js → chunk-5VSF4UUQ.js} +12 -7
- package/dist/{chunk-NW7BOILN.js → chunk-5WRPDP2A.js} +18 -18
- package/dist/{chunk-7ULNCDCO.js → chunk-6DLWKFEX.js} +35 -34
- package/dist/{chunk-WOA4LN2R.js → chunk-7D6L4MTX.js} +2 -2
- package/dist/{chunk-GAEGEPOC.js → chunk-7HXE67BN.js} +2 -2
- package/dist/chunk-AGSS7277.js +84 -0
- package/dist/{chunk-R3PCY3YS.js → chunk-AMERCH6V.js} +13 -13
- package/dist/{chunk-WU567RSC.js → chunk-ATKJFDQN.js} +14 -10
- package/dist/{chunk-VSSBEUFT.js → chunk-AWSCPCN2.js} +16 -16
- package/dist/{chunk-VCHXCQFG.js → chunk-BWD5EPKO.js} +3 -3
- package/dist/{chunk-ODBNXWT4.js → chunk-CT4MN5IU.js} +1271 -262
- package/dist/{chunk-34WSVGEM.js → chunk-CUHSHSB6.js} +83 -5
- package/dist/{chunk-CHOW74WE.js → chunk-CYRKQRPM.js} +7 -10
- package/dist/{chunk-Q7DUK4LX.js → chunk-DEL2U6CM.js} +5 -5
- package/dist/{chunk-6C7JWPCP.js → chunk-DGUKIYSI.js} +26 -23
- package/dist/{chunk-PHDMFAKM.js → chunk-DUO2TU77.js} +2 -2
- package/dist/{chunk-MRXKYPCS.js → chunk-EBC36LNN.js} +2 -2
- package/dist/chunk-ED36RF6Y.js +17 -0
- package/dist/{chunk-76MWC2K6.js → chunk-EUXZEFTV.js} +90 -97
- package/dist/{chunk-QOZXJ4NA.js → chunk-FM4RDMKT.js} +11 -8
- package/dist/{chunk-66VMUL7Q.js → chunk-GAQ7OQG6.js} +31 -28
- package/dist/{chunk-Q6ZWTCLY.js → chunk-GL5LUMZE.js} +23 -24
- package/dist/{chunk-BKE7E7TC.js → chunk-GMX5OS7B.js} +9 -9
- package/dist/{chunk-ZHFZWTZV.js → chunk-GSLNCYGG.js} +11 -11
- package/dist/{chunk-ARJ6PLFH.js → chunk-GSM5UU7A.js} +26 -34
- package/dist/{chunk-724UL2TJ.js → chunk-GXFV6MYU.js} +3 -3
- package/dist/chunk-HAD7QRQI.js +30 -0
- package/dist/{chunk-QOBUHWHX.js → chunk-HRNHZA3N.js} +6 -6
- package/dist/{chunk-VWCXW2E7.js → chunk-HWCCCQNX.js} +1 -1
- package/dist/{chunk-7DYBLXYA.js → chunk-HYGZEMX6.js} +3 -3
- package/dist/chunk-IJYGIDF4.js +186 -0
- package/dist/{chunk-4W4VLAPJ.js → chunk-IQWN5JCP.js} +11 -11
- package/dist/{chunk-GZYBXISR.js → chunk-IUE7SSKV.js} +9 -9
- package/dist/{chunk-IBGIOBEE.js → chunk-IWDLU6K3.js} +68 -5
- package/dist/{chunk-XCJN5IJU.js → chunk-IYNJ6YPZ.js} +4 -4
- package/dist/{chunk-JAU72XNY.js → chunk-J64T55EI.js} +3 -3
- package/dist/{chunk-2BBLFX75.js → chunk-J6MPGQTS.js} +5 -5
- package/dist/chunk-JORED7EX.js +44 -0
- package/dist/{chunk-6SDEP3AJ.js → chunk-JUKMK5Y4.js} +8 -8
- package/dist/{chunk-IBRALRBR.js → chunk-JW3YWBVB.js} +15 -14
- package/dist/{chunk-L3BLXZG7.js → chunk-KAPJINKN.js} +30 -69
- package/dist/{chunk-2B73ZPOK.js → chunk-KN35K52N.js} +3 -3
- package/dist/{chunk-C34ZXZ7O.js → chunk-KUA4OJ5Y.js} +24 -11
- package/dist/chunk-KYUB6QDC.js +72 -0
- package/dist/{chunk-67WMNWEE.js → chunk-LLJNQKQW.js} +12 -10
- package/dist/chunk-LZSEQW6A.js +57 -0
- package/dist/{chunk-ZANLILYD.js → chunk-M2IFVFWU.js} +2 -2
- package/dist/chunk-M2UD3LPU.js +88 -0
- package/dist/{chunk-WOKKRCJ5.js → chunk-MBKQHGA7.js} +15 -14
- package/dist/{chunk-P7266HLM.js → chunk-MPNJLASA.js} +2 -2
- package/dist/{chunk-6GFRNVYR.js → chunk-MZGQNL3Y.js} +10 -10
- package/dist/{chunk-QZVW3AAK.js → chunk-N5FLEO7W.js} +33 -31
- package/dist/{chunk-3JNKMP3B.js → chunk-O4NWQT6I.js} +4 -4
- package/dist/{chunk-PFNSLWU5.js → chunk-OHKJ7PQF.js} +33 -31
- package/dist/{chunk-VRZP76YM.js → chunk-P63GXC37.js} +4 -1
- package/dist/{chunk-XTMJ7XDT.js → chunk-POMLXPMY.js} +1 -1
- package/dist/{chunk-QQNQ7SJW.js → chunk-QBFBRV2B.js} +10 -4
- package/dist/{chunk-3UUPUE3O.js → chunk-R3T7CLQ2.js} +84 -60
- package/dist/{chunk-23WOO7TX.js → chunk-R7YOCSNV.js} +10 -10
- package/dist/{chunk-2CD5RS6M.js → chunk-RKBXZN3A.js} +23 -2
- package/dist/{chunk-OG5UUPN7.js → chunk-RKKOYPRA.js} +14 -14
- package/dist/{chunk-52FUZI6K.js → chunk-RMLC67LF.js} +1 -1
- package/dist/{chunk-XMSXXAHW.js → chunk-ROYSX2S5.js} +2 -2
- package/dist/{chunk-PV6LR5P5.js → chunk-RVK72CZX.js} +9605 -14776
- package/dist/{chunk-FLKWCIZH.js → chunk-S2HEXIWI.js} +5 -5
- package/dist/{chunk-UZ3TUTRV.js → chunk-S67KYG37.js} +1 -1
- package/dist/{chunk-JWA5I3SR.js → chunk-SD4I7ZO4.js} +16 -18
- package/dist/{chunk-Z527N6YQ.js → chunk-SKAMFC7A.js} +12 -12
- package/dist/{chunk-MQLUAEOC.js → chunk-SRYEJNES.js} +2 -2
- package/dist/{chunk-BRGDSBJE.js → chunk-SYE6T2EB.js} +12 -12
- package/dist/{chunk-GXW6K4YJ.js → chunk-T57LYLZT.js} +1 -1
- package/dist/{chunk-ZXYDQ3TZ.js → chunk-T7FEBKXN.js} +48 -15
- package/dist/{chunk-IXXDFY73.js → chunk-TIQ2PKDW.js} +3 -3
- package/dist/{chunk-QILIYSJF.js → chunk-TLX72JTG.js} +1 -1
- package/dist/{chunk-TYM6OUIT.js → chunk-TOY6QKOH.js} +12 -12
- package/dist/{chunk-IZSHAIJ7.js → chunk-TRETHTQO.js} +12 -12
- package/dist/{chunk-3VPVG5SU.js → chunk-U44DJXQP.js} +10 -6
- package/dist/{chunk-PNQDPDRC.js → chunk-UA7ZXYDR.js} +1 -1
- package/dist/{chunk-OXXKQCSV.js → chunk-UBOQLVT2.js} +4 -4
- package/dist/{chunk-QGQ5CCCG.js → chunk-UMS2MFPZ.js} +2 -2
- package/dist/{chunk-QHJ6DQ2R.js → chunk-US7ECLD7.js} +55 -13
- package/dist/{chunk-EETY4LF7.js → chunk-UZ2XCLYS.js} +8 -8
- package/dist/chunk-V35JG4JB.js +2667 -0
- package/dist/{chunk-N3X6Q4YT.js → chunk-VOOAPROD.js} +3 -3
- package/dist/{chunk-SAEFPSB6.js → chunk-W66O5E25.js} +21 -11
- package/dist/{chunk-KBG47GHP.js → chunk-WMYE35PX.js} +15 -11
- package/dist/{chunk-5NGR67U5.js → chunk-XBJVAEEO.js} +32 -5
- package/dist/chunk-XHJBS436.js +4217 -0
- package/dist/{chunk-GBPP5P7X.js → chunk-XTBDCR27.js} +4 -4
- package/dist/{chunk-4UNXBNE2.js → chunk-XTFDJI3T.js} +11 -11
- package/dist/{chunk-UXGETRP4.js → chunk-XYURS6EN.js} +13 -12
- package/dist/{chunk-RPLINGVB.js → chunk-Y6GZHWSJ.js} +6 -6
- package/dist/{chunk-2ZGIZPDG.js → chunk-YCWYO6TQ.js} +41 -38
- package/dist/{chunk-66SXUJCA.js → chunk-YH5MVY2U.js} +10 -8
- package/dist/{chunk-AOHZU2BM.js → chunk-YNE3RP52.js} +1 -1
- package/dist/{chunk-GOYRYZ2R.js → chunk-ZHH37KZL.js} +72 -20
- package/dist/{chunk-ZGDGW2V3.js → chunk-ZIVJBOO3.js} +2 -2
- package/dist/{chunk-GHB6AYCP.js → chunk-ZVUL7QYY.js} +29 -28
- package/dist/index.js +11559 -6213
- package/dist/mcp/analyze-cli.js +10 -9
- package/dist/mcp/cli.js +41 -38
- package/dist/mcp/server.js +1142 -495
- package/dist/mcp/worker.js +61 -57
- package/dist/probes/installer.js +19 -19
- package/dist/workers/project-snapshot-persist-worker.js +28 -9
- package/dist/workers/review-graph-persist-worker.js +1 -1
- package/docs/configuration.md +11 -0
- package/docs/engineering-principles.md +32 -0
- package/docs/lsp-capability-matrix.md +1 -1
- package/docs/lsp-idle-eviction.md +15 -26
- package/docs/pi-lens-fixer.md +117 -13
- package/docs/pi-lens-merge-policy.md +109 -11
- package/docs/pi-lens-monitor.md +8 -2
- package/docs/pi-lens-retro.md +4 -1
- package/docs/pi-lens-reviewer.md +114 -3
- package/docs/pi-lens-subagent.md +27 -14
- package/docs/release-qa-baseline.md +3 -1
- package/docs/servercapabilities.md +9 -19
- package/package.json +7 -5
- package/scripts/download-grammars.js +40 -7
- package/scripts/lib/latency-log-phases.mjs +95 -0
- package/scripts/rpc-load-check.mjs +570 -81
- package/dist/chunk-3WA4HP4I.js +0 -55
- package/dist/chunk-466Z26MG.js +0 -30
- package/dist/chunk-5JM2524W.js +0 -84
- package/dist/chunk-CO2G5PHH.js +0 -84
- package/dist/chunk-LOP6GRPH.js +0 -31
- package/dist/chunk-UOPVJQ4N.js +0 -103
- package/dist/chunk-XPZPXCBV.js +0 -28
- /package/dist/{chunk-FC4RP4I2.js → chunk-6HWVI6MI.js} +0 -0
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,35 +11,31 @@ 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";
|
|
26
|
+
import {
|
|
27
|
+
isHardFailureSummary
|
|
28
|
+
} from "../chunk-7U2IDNXN.js";
|
|
22
29
|
import {
|
|
23
30
|
RUNNERS,
|
|
24
31
|
formatRunDurationMs,
|
|
25
32
|
isExcludedTestTarget,
|
|
26
33
|
isRunnerErrorResult
|
|
27
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-SD4I7ZO4.js";
|
|
28
35
|
import {
|
|
29
36
|
GovulncheckClient
|
|
30
|
-
} from "../chunk-
|
|
31
|
-
import
|
|
32
|
-
GitleaksClient,
|
|
33
|
-
classifyAndFilterFindings
|
|
34
|
-
} from "../chunk-VITUCP5A.js";
|
|
35
|
-
import "../chunk-ZGDGW2V3.js";
|
|
36
|
-
import {
|
|
37
|
-
isHardFailureSummary
|
|
38
|
-
} from "../chunk-7U2IDNXN.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,65 +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-
|
|
109
|
-
import
|
|
123
|
+
} from "../chunk-5OFV52AM.js";
|
|
124
|
+
import {
|
|
125
|
+
findingsResult,
|
|
126
|
+
hasUsableResult,
|
|
127
|
+
reachedNoVerdict
|
|
128
|
+
} from "../chunk-RKBXZN3A.js";
|
|
129
|
+
import "../chunk-6HWVI6MI.js";
|
|
130
|
+
import "../chunk-S67KYG37.js";
|
|
131
|
+
import "../chunk-KN35K52N.js";
|
|
132
|
+
import {
|
|
133
|
+
resetGoAvailability
|
|
134
|
+
} from "../chunk-ROYSX2S5.js";
|
|
110
135
|
import {
|
|
111
136
|
TrivyClient
|
|
112
|
-
} from "../chunk-
|
|
113
|
-
import "../chunk-VCHXCQFG.js";
|
|
114
|
-
import "../chunk-IXXDFY73.js";
|
|
137
|
+
} from "../chunk-YH5MVY2U.js";
|
|
115
138
|
import {
|
|
116
|
-
|
|
117
|
-
} from "../chunk-
|
|
139
|
+
scannerReportParentDir
|
|
140
|
+
} from "../chunk-ED36RF6Y.js";
|
|
141
|
+
import "../chunk-BWD5EPKO.js";
|
|
142
|
+
import "../chunk-TIQ2PKDW.js";
|
|
118
143
|
import {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
import "../chunk-
|
|
123
|
-
import "../chunk-EETY4LF7.js";
|
|
144
|
+
resetRustAvailability
|
|
145
|
+
} from "../chunk-EBC36LNN.js";
|
|
146
|
+
import "../chunk-HYGZEMX6.js";
|
|
147
|
+
import "../chunk-UZ2XCLYS.js";
|
|
124
148
|
import {
|
|
125
149
|
getSgCommand,
|
|
126
150
|
resetDispatchAvailabilityState,
|
|
127
151
|
resolveManagedToolClient
|
|
128
|
-
} from "../chunk-
|
|
129
|
-
import "../chunk-
|
|
130
|
-
import "../chunk-
|
|
131
|
-
import "../chunk-
|
|
132
|
-
import "../chunk-
|
|
133
|
-
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";
|
|
134
157
|
import {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
158
|
+
SYMBOL_KIND_NAMES,
|
|
159
|
+
captureReviewGraphStructuralIr,
|
|
160
|
+
formatReviewGraphRevisionDriftNote,
|
|
161
|
+
publishReviewGraphFileIr,
|
|
162
|
+
reviewGraphIrContentHash
|
|
163
|
+
} from "../chunk-XHJBS436.js";
|
|
164
|
+
import {
|
|
165
|
+
buildSymbolId
|
|
166
|
+
} from "../chunk-3MED75HT.js";
|
|
138
167
|
import {
|
|
139
|
-
DEPENDENCY_DRIFT_MAX_DELIVERIES,
|
|
140
168
|
MAX_LATE_AUX_REARMS,
|
|
141
169
|
PAST_EOF_STALE_MARKER,
|
|
142
|
-
|
|
170
|
+
PRIMARY_UNAVAILABLE_CAUSE,
|
|
143
171
|
ReadGuard,
|
|
144
172
|
STALE_LINE_MARKER,
|
|
145
|
-
SYMBOL_KIND_NAMES,
|
|
146
173
|
Text,
|
|
147
|
-
TreeSitterSymbolExtractor,
|
|
148
174
|
WriteOrderingGuard,
|
|
149
175
|
anchorsForDiagnostic,
|
|
150
176
|
applyAuxiliarySuppressions,
|
|
@@ -155,12 +181,12 @@ import {
|
|
|
155
181
|
armDeferredLspWork,
|
|
156
182
|
attemptTsserverSyncDiagnostics,
|
|
157
183
|
beginScope,
|
|
158
|
-
|
|
184
|
+
buildProbeScopeKey,
|
|
159
185
|
canRearmPendingAuxiliary,
|
|
160
|
-
canWriteAnalysisRoot,
|
|
161
|
-
captureReviewGraphStructuralIr,
|
|
162
186
|
classifyDiagnosticTier,
|
|
163
187
|
clearAllSessions,
|
|
188
|
+
combinePrimaryUnavailableCauses,
|
|
189
|
+
configDisabledAuxiliaryLspServerIds,
|
|
164
190
|
countRetainedSuppressedRows,
|
|
165
191
|
createFileTime,
|
|
166
192
|
createLazyImport,
|
|
@@ -170,20 +196,21 @@ import {
|
|
|
170
196
|
drainPendingAuxCapEvictedCount,
|
|
171
197
|
drainPendingAuxiliaryCoverage,
|
|
172
198
|
drainRenderedDependencyDriftFilePaths,
|
|
173
|
-
exceedsLspSyncLimits,
|
|
174
199
|
findAuxiliaryProfileForSource,
|
|
175
|
-
formatReviewGraphRevisionDriftNote,
|
|
176
200
|
getActiveSessionId,
|
|
177
201
|
getDisposition,
|
|
178
202
|
getFileDiagnosticSummaries,
|
|
179
203
|
getLSPService,
|
|
180
204
|
getLspBudgetIdleTimeoutMs,
|
|
181
205
|
getMutationBridge,
|
|
206
|
+
getSuppressedDiagnostics,
|
|
182
207
|
getWidgetBlockingFilesForSweep,
|
|
208
|
+
goPackageFilesToAnnounce,
|
|
183
209
|
groupFilesByPrimaryServer,
|
|
184
210
|
hasAnyDispositionMarks,
|
|
185
211
|
hasStrictDispositionMarks,
|
|
186
212
|
hashDiagnosticContent,
|
|
213
|
+
importTargetsToAnnounce,
|
|
187
214
|
incrementWidgetDependencyDriftDelivery,
|
|
188
215
|
isAuxBacklogPublished,
|
|
189
216
|
isBlocking,
|
|
@@ -195,7 +222,7 @@ import {
|
|
|
195
222
|
newLspMutationCorrelationId,
|
|
196
223
|
nextOrderTurn,
|
|
197
224
|
pendingAuxiliaryCoverageSize,
|
|
198
|
-
|
|
225
|
+
primaryUnavailableCause,
|
|
199
226
|
rearmPendingAuxiliaryCoverage,
|
|
200
227
|
reconcileCorrelatedScanDiagnostics,
|
|
201
228
|
reconcileScanDiagnostics,
|
|
@@ -212,52 +239,42 @@ import {
|
|
|
212
239
|
resetOpaqueMutationState,
|
|
213
240
|
resetPendingAuxiliaryCoverage,
|
|
214
241
|
resetWorkspaceDiagnosticsCacheSession,
|
|
215
|
-
resolveImportToFiles,
|
|
216
242
|
resolveLiveBusEmitter,
|
|
217
243
|
resyncDocumentOnPastEof,
|
|
218
244
|
retagAuxiliaryDiagnostics,
|
|
219
245
|
retireScope,
|
|
220
246
|
retireWidgetDependencyDriftBlockers,
|
|
221
|
-
reviewGraphIrContentHash,
|
|
222
247
|
runPerServerGroups,
|
|
223
248
|
scopeCell,
|
|
224
249
|
setSessionLanguages,
|
|
225
250
|
shouldShortenLspIdleTimeout,
|
|
226
251
|
summarizeWorkspaceEdit,
|
|
227
|
-
sweepInlineBlockerFreshness,
|
|
228
|
-
symbolExtractionGrammar,
|
|
229
252
|
touchCompletedConfirmationPolicy,
|
|
230
253
|
touchCoverageGap,
|
|
231
254
|
tryWarmAttachedDiagnostics,
|
|
232
255
|
widgetDiagnosticUri,
|
|
233
256
|
workspaceEditTextPaths,
|
|
234
257
|
writeOrderToken
|
|
235
|
-
} from "../chunk-
|
|
236
|
-
import {
|
|
237
|
-
buildSymbolId
|
|
238
|
-
} from "../chunk-3MED75HT.js";
|
|
239
|
-
import {
|
|
240
|
-
emitBounded,
|
|
241
|
-
resetBoundedTelemetry
|
|
242
|
-
} from "../chunk-CO2G5PHH.js";
|
|
258
|
+
} from "../chunk-RVK72CZX.js";
|
|
243
259
|
import {
|
|
260
|
+
ANY_POSITION,
|
|
261
|
+
foldedFindingIdentity,
|
|
244
262
|
hashText,
|
|
245
263
|
normalizeMessage,
|
|
246
264
|
primePersistedMutationAttribution,
|
|
247
265
|
resetMutationAttribution,
|
|
266
|
+
retainRecordedFindings,
|
|
248
267
|
stableFindingId
|
|
249
|
-
} from "../chunk-
|
|
250
|
-
import {
|
|
251
|
-
resolveGitCheckout,
|
|
252
|
-
resolveLinkedWorktreeOwner
|
|
253
|
-
} from "../chunk-PNQDPDRC.js";
|
|
268
|
+
} from "../chunk-IWDLU6K3.js";
|
|
254
269
|
import {
|
|
255
270
|
mapWithConcurrency
|
|
256
271
|
} from "../chunk-XIMYZ3JA.js";
|
|
257
272
|
import {
|
|
273
|
+
canWriteAnalysisRoot,
|
|
258
274
|
classifyCascadeWaitTier,
|
|
259
275
|
customServerSpecsOf,
|
|
260
276
|
describeRootFallback,
|
|
277
|
+
disabledPrimaries,
|
|
261
278
|
explainServersForFile,
|
|
262
279
|
getAstGrepRuleFingerprint,
|
|
263
280
|
getServersForFileWithConfig,
|
|
@@ -272,11 +289,17 @@ import {
|
|
|
272
289
|
resetLSPCaseSensitivityState,
|
|
273
290
|
resolveLspCwdForFile,
|
|
274
291
|
shouldInitializeSessionRoot
|
|
275
|
-
} from "../chunk-
|
|
292
|
+
} from "../chunk-3DA2JDOL.js";
|
|
293
|
+
import "../chunk-HWCCCQNX.js";
|
|
276
294
|
import {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
295
|
+
emitBounded,
|
|
296
|
+
hasAmbientPythonEnvironment,
|
|
297
|
+
resetBoundedTelemetry
|
|
298
|
+
} from "../chunk-CUHSHSB6.js";
|
|
299
|
+
import {
|
|
300
|
+
resolveGitCheckout,
|
|
301
|
+
resolveLinkedWorktreeOwner
|
|
302
|
+
} from "../chunk-UA7ZXYDR.js";
|
|
280
303
|
import {
|
|
281
304
|
PROJECT_SNAPSHOT_VERSION,
|
|
282
305
|
getProjectSnapshotLegacyPath,
|
|
@@ -291,8 +314,25 @@ import {
|
|
|
291
314
|
readJsonCache,
|
|
292
315
|
readProjectSnapshotMeta,
|
|
293
316
|
saveRuntimeProjectSnapshot
|
|
294
|
-
} 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";
|
|
295
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";
|
|
296
336
|
import {
|
|
297
337
|
EXT_TO_LANG,
|
|
298
338
|
classifyTreeSitterWasmError,
|
|
@@ -305,7 +345,7 @@ import {
|
|
|
305
345
|
queryLoader,
|
|
306
346
|
reportBundledResourceDirHealth,
|
|
307
347
|
resolveTreeSitterLanguage
|
|
308
|
-
} from "../chunk-
|
|
348
|
+
} from "../chunk-US7ECLD7.js";
|
|
309
349
|
import "../chunk-Z54ZSOBZ.js";
|
|
310
350
|
import {
|
|
311
351
|
SCAN_LANGUAGE_PRIORITY,
|
|
@@ -313,35 +353,27 @@ import {
|
|
|
313
353
|
extensionsForLanguageToken,
|
|
314
354
|
getUserRuleRoot,
|
|
315
355
|
resolveLanguage
|
|
316
|
-
} from "../chunk-
|
|
356
|
+
} from "../chunk-GXFV6MYU.js";
|
|
317
357
|
import {
|
|
318
358
|
dump,
|
|
319
359
|
resolvePackagePath
|
|
320
|
-
} from "../chunk-
|
|
321
|
-
import "../chunk-GBPP5P7X.js";
|
|
322
|
-
import "../chunk-P7266HLM.js";
|
|
323
|
-
import {
|
|
324
|
-
SWEEP_IDLE_SAFETY_MARGIN_MS,
|
|
325
|
-
getFullScanWallClockMs,
|
|
326
|
-
isWorkspaceSweepActive,
|
|
327
|
-
runWhenWorkspaceSweepIdle
|
|
328
|
-
} from "../chunk-MQLUAEOC.js";
|
|
360
|
+
} from "../chunk-FM4RDMKT.js";
|
|
329
361
|
import {
|
|
330
362
|
HOOK_WALL_BUDGET_MS,
|
|
331
363
|
bounded,
|
|
332
364
|
combineAbortSignals,
|
|
333
365
|
withDeadline
|
|
334
|
-
} from "../chunk-
|
|
366
|
+
} from "../chunk-RMLC67LF.js";
|
|
335
367
|
import {
|
|
336
368
|
centralityFromReverseDeps,
|
|
337
369
|
getWordIndexBuildStatus,
|
|
338
370
|
logWordIndex,
|
|
339
371
|
searchWordIndex,
|
|
340
372
|
triggerBackgroundWordIndexBuild
|
|
341
|
-
} from "../chunk-
|
|
373
|
+
} from "../chunk-W66O5E25.js";
|
|
342
374
|
import {
|
|
343
375
|
getProjectDiagnosticsScannerMaxFiles
|
|
344
|
-
} from "../chunk-
|
|
376
|
+
} from "../chunk-7HXE67BN.js";
|
|
345
377
|
import {
|
|
346
378
|
PathKeyedMap
|
|
347
379
|
} from "../chunk-Z3CCVDUB.js";
|
|
@@ -349,32 +381,37 @@ import {
|
|
|
349
381
|
WARM_TURN_END_SCHEMA_VERSION,
|
|
350
382
|
createWarmIpcLineReader,
|
|
351
383
|
createWarmIpcRequestQueue,
|
|
352
|
-
freshnessFromMtime,
|
|
353
384
|
ipcPathForCwd,
|
|
354
385
|
readTurnEndStatus,
|
|
386
|
+
unlinkStaleUnixSocket
|
|
387
|
+
} from "../chunk-KAPJINKN.js";
|
|
388
|
+
import {
|
|
389
|
+
freshnessFromMtime,
|
|
390
|
+
hashContentBytes,
|
|
355
391
|
resolveRunnerPath,
|
|
356
392
|
toRunnerDisplayPath
|
|
357
|
-
} from "../chunk-
|
|
393
|
+
} from "../chunk-AGSS7277.js";
|
|
358
394
|
import "../chunk-2BEMIWEW.js";
|
|
395
|
+
import "../chunk-IJYGIDF4.js";
|
|
359
396
|
import {
|
|
360
397
|
commitDurableStore,
|
|
361
398
|
resetResolvedPathCache,
|
|
362
399
|
resetZizmorTokenAvailability
|
|
363
|
-
} from "../chunk-
|
|
400
|
+
} from "../chunk-GAQ7OQG6.js";
|
|
364
401
|
import {
|
|
365
402
|
resolveToolCwd
|
|
366
|
-
} from "../chunk-
|
|
403
|
+
} from "../chunk-DEL2U6CM.js";
|
|
367
404
|
import {
|
|
368
405
|
_resetPackageManagerCache,
|
|
369
406
|
findGlobalBinary,
|
|
370
407
|
pmBinary,
|
|
371
408
|
resolveNodePackageManager,
|
|
372
409
|
runScriptArgs
|
|
373
|
-
} from "../chunk-
|
|
410
|
+
} from "../chunk-5VSF4UUQ.js";
|
|
374
411
|
import {
|
|
375
412
|
getIsolatedNpxSpawnOptions,
|
|
376
413
|
probeToolAsync
|
|
377
|
-
} from "../chunk-
|
|
414
|
+
} from "../chunk-3KAZU3VR.js";
|
|
378
415
|
import {
|
|
379
416
|
classifyProbeFailure,
|
|
380
417
|
createAvailabilityLatch,
|
|
@@ -382,20 +419,20 @@ import {
|
|
|
382
419
|
logAvailabilityDecision,
|
|
383
420
|
resetInstallRetryLatches,
|
|
384
421
|
startHostStallSampler
|
|
385
|
-
} from "../chunk-
|
|
422
|
+
} from "../chunk-P63GXC37.js";
|
|
386
423
|
import {
|
|
387
424
|
canRunStartupHeavyScans,
|
|
388
425
|
detectProjectLanguageProfile,
|
|
389
426
|
getDefaultStartupTools
|
|
390
|
-
} from "../chunk-
|
|
391
|
-
import "../chunk-
|
|
427
|
+
} from "../chunk-HRNHZA3N.js";
|
|
428
|
+
import "../chunk-TLX72JTG.js";
|
|
392
429
|
import {
|
|
393
430
|
collectSourceFilesWithBudgetAsync,
|
|
394
431
|
getSlowFsVerdict,
|
|
395
432
|
isSlowFs,
|
|
396
433
|
slowFsDegradationNotice
|
|
397
|
-
} from "../chunk-
|
|
398
|
-
import "../chunk-
|
|
434
|
+
} from "../chunk-DGUKIYSI.js";
|
|
435
|
+
import "../chunk-XBJVAEEO.js";
|
|
399
436
|
import {
|
|
400
437
|
displayProjectDataPath,
|
|
401
438
|
drainProjectDataDirMigrations,
|
|
@@ -422,7 +459,7 @@ import {
|
|
|
422
459
|
sweepDeadEphemeralDataDirs,
|
|
423
460
|
updateHeartbeat,
|
|
424
461
|
withGenerationLockSync
|
|
425
|
-
} from "../chunk-
|
|
462
|
+
} from "../chunk-KUA4OJ5Y.js";
|
|
426
463
|
import {
|
|
427
464
|
createSingleFlight
|
|
428
465
|
} from "../chunk-BW5KFIQC.js";
|
|
@@ -432,7 +469,7 @@ import {
|
|
|
432
469
|
} from "../chunk-QYF5S6P6.js";
|
|
433
470
|
import {
|
|
434
471
|
detectFileKind
|
|
435
|
-
} from "../chunk-
|
|
472
|
+
} from "../chunk-DUO2TU77.js";
|
|
436
473
|
import {
|
|
437
474
|
compareKeys,
|
|
438
475
|
detectFileRole,
|
|
@@ -442,18 +479,18 @@ import {
|
|
|
442
479
|
provenanceView,
|
|
443
480
|
resolvePiLensConfig,
|
|
444
481
|
summarizeConfigResolution
|
|
445
|
-
} from "../chunk-
|
|
482
|
+
} from "../chunk-J6MPGQTS.js";
|
|
446
483
|
import {
|
|
447
484
|
LSP_NAMESPACE_KEY,
|
|
448
485
|
getPiLensGlobalConfigPath,
|
|
449
486
|
resetWorkspaceTopology
|
|
450
|
-
} from "../chunk-
|
|
487
|
+
} from "../chunk-5HSRT26B.js";
|
|
451
488
|
import {
|
|
452
489
|
getProjectTrustState,
|
|
453
490
|
isToolInstallAllowedByTrust,
|
|
454
491
|
projectTrustDenialReason,
|
|
455
492
|
setProjectTrustState
|
|
456
|
-
} from "../chunk-
|
|
493
|
+
} from "../chunk-M2IFVFWU.js";
|
|
457
494
|
import {
|
|
458
495
|
DEFAULT_MAX_OUTPUT_BYTES,
|
|
459
496
|
createBoundedOutputSink,
|
|
@@ -474,17 +511,17 @@ import {
|
|
|
474
511
|
resolveLensToolEnabled,
|
|
475
512
|
resolveLensToolName,
|
|
476
513
|
toolRegistryEntryForMcp
|
|
477
|
-
} from "../chunk-
|
|
514
|
+
} from "../chunk-J64T55EI.js";
|
|
478
515
|
import {
|
|
479
516
|
createSubsystemLogger,
|
|
480
517
|
flushExtensionLog,
|
|
481
518
|
logExtension
|
|
482
|
-
} from "../chunk-
|
|
519
|
+
} from "../chunk-POMLXPMY.js";
|
|
483
520
|
import "../chunk-JMYYOTQG.js";
|
|
484
521
|
import {
|
|
485
522
|
claimPhaseOncePerSession,
|
|
486
523
|
logLatency
|
|
487
|
-
} from "../chunk-
|
|
524
|
+
} from "../chunk-QBFBRV2B.js";
|
|
488
525
|
import {
|
|
489
526
|
beginTurnContext,
|
|
490
527
|
createNdjsonLogger,
|
|
@@ -493,11 +530,11 @@ import {
|
|
|
493
530
|
isTestMode,
|
|
494
531
|
runLogCleanup,
|
|
495
532
|
setTurnContextSession
|
|
496
|
-
} from "../chunk-
|
|
533
|
+
} from "../chunk-YNE3RP52.js";
|
|
497
534
|
import "../chunk-LJDODBBZ.js";
|
|
498
535
|
import {
|
|
499
536
|
FactStore
|
|
500
|
-
} from "../chunk-
|
|
537
|
+
} from "../chunk-CYRKQRPM.js";
|
|
501
538
|
import {
|
|
502
539
|
BoundedFifoMap,
|
|
503
540
|
BoundedLruCache
|
|
@@ -515,13 +552,13 @@ import {
|
|
|
515
552
|
resolveHostToolPath,
|
|
516
553
|
toProjectRelativePath,
|
|
517
554
|
uriToPath
|
|
518
|
-
} from "../chunk-
|
|
555
|
+
} from "../chunk-3RKP3FMS.js";
|
|
519
556
|
import "../chunk-NXL4FFQQ.js";
|
|
520
557
|
|
|
521
558
|
// dist/mcp/server.js
|
|
522
559
|
import * as fs25 from "node:fs";
|
|
523
560
|
import * as net from "node:net";
|
|
524
|
-
import * as
|
|
561
|
+
import * as path40 from "node:path";
|
|
525
562
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
526
563
|
|
|
527
564
|
// dist/tools/render-compact.js
|
|
@@ -786,7 +823,7 @@ function compactRenderResult(summarize) {
|
|
|
786
823
|
|
|
787
824
|
// dist/clients/ast-grep-client.js
|
|
788
825
|
import * as fs4 from "node:fs";
|
|
789
|
-
import * as
|
|
826
|
+
import * as os from "node:os";
|
|
790
827
|
import * as path4 from "node:path";
|
|
791
828
|
|
|
792
829
|
// dist/clients/ast-grep-rule-manager.js
|
|
@@ -927,7 +964,6 @@ var AstGrepRuleManager = class {
|
|
|
927
964
|
|
|
928
965
|
// dist/clients/sg-runner.js
|
|
929
966
|
import * as fs3 from "node:fs";
|
|
930
|
-
import * as os from "node:os";
|
|
931
967
|
import * as path3 from "node:path";
|
|
932
968
|
function buildBashRunArgs(cmd, allArgs) {
|
|
933
969
|
return ["-c", '"$0" "$@"', cmd, ...allArgs];
|
|
@@ -1356,6 +1392,7 @@ ${result.stderr}`)) {
|
|
|
1356
1392
|
case "cwd-unresolvable":
|
|
1357
1393
|
case "permission-denied":
|
|
1358
1394
|
case "spawn-failed":
|
|
1395
|
+
case "trust-refused":
|
|
1359
1396
|
case void 0:
|
|
1360
1397
|
return result.error ? "cli-failure" : void 0;
|
|
1361
1398
|
}
|
|
@@ -1473,7 +1510,7 @@ Original error: ${stderr}`;
|
|
|
1473
1510
|
}
|
|
1474
1511
|
// --- Shared helpers for temp-dir rule scans ---
|
|
1475
1512
|
prepareTempScan(ruleId, ruleYaml) {
|
|
1476
|
-
const sessionDir = fs3.mkdtempSync(path3.join(
|
|
1513
|
+
const sessionDir = fs3.mkdtempSync(path3.join(scannerReportParentDir(), `pi-lens-temp-${ruleId}-`));
|
|
1477
1514
|
try {
|
|
1478
1515
|
const rulesSubdir = path3.join(sessionDir, "rules");
|
|
1479
1516
|
const configFile = path3.join(sessionDir, ".sgconfig.yml");
|
|
@@ -1952,7 +1989,7 @@ var AstGrepClient = class {
|
|
|
1952
1989
|
* Dump the parsed tree-sitter AST for a snippet using ast-grep CLI.
|
|
1953
1990
|
*/
|
|
1954
1991
|
async dumpAst(source, lang, options = {}) {
|
|
1955
|
-
const tmpDir = fs4.mkdtempSync(path4.join(
|
|
1992
|
+
const tmpDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "pi-lens-ast-dump-"));
|
|
1956
1993
|
const tmpFile = path4.join(tmpDir, `snippet.${lang.replace(/[^a-z0-9_-]/gi, "") || "txt"}`);
|
|
1957
1994
|
try {
|
|
1958
1995
|
fs4.writeFileSync(tmpFile, source, "utf-8");
|
|
@@ -1982,7 +2019,7 @@ var AstGrepClient = class {
|
|
|
1982
2019
|
if (shapeError)
|
|
1983
2020
|
return { valid: false, error: shapeError };
|
|
1984
2021
|
const snippet = validationSnippetFor(lang);
|
|
1985
|
-
const tmpDir = fs4.mkdtempSync(path4.join(
|
|
2022
|
+
const tmpDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "pi-lens-sg-validate-"));
|
|
1986
2023
|
const tmpFile = path4.join(tmpDir, `snippet.${snippet.ext}`);
|
|
1987
2024
|
try {
|
|
1988
2025
|
fs4.writeFileSync(tmpFile, snippet.source, "utf-8");
|
|
@@ -2029,7 +2066,7 @@ var AstGrepClient = class {
|
|
|
2029
2066
|
return { valid: false, error: shapeError };
|
|
2030
2067
|
const language = extractRuleLanguage(ruleYaml) ?? "typescript";
|
|
2031
2068
|
const snippet = validationSnippetFor(language);
|
|
2032
|
-
const tmpDir = fs4.mkdtempSync(path4.join(
|
|
2069
|
+
const tmpDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "pi-lens-sg-rule-"));
|
|
2033
2070
|
try {
|
|
2034
2071
|
fs4.writeFileSync(path4.join(tmpDir, `snippet.${snippet.ext}`), snippet.source, "utf-8");
|
|
2035
2072
|
const result = await this.tempScanDetailed(tmpDir, ruleYaml, options);
|
|
@@ -2606,6 +2643,7 @@ async function scanFileMajorRules(cwd, files, signal) {
|
|
|
2606
2643
|
} finally {
|
|
2607
2644
|
facts.dropFileFacts(filePath);
|
|
2608
2645
|
}
|
|
2646
|
+
await new Promise((resolve32) => setImmediate(resolve32));
|
|
2609
2647
|
}
|
|
2610
2648
|
if (wasmAborted) {
|
|
2611
2649
|
astGrep.length = 0;
|
|
@@ -2937,29 +2975,29 @@ async function buildBootstrapClients() {
|
|
|
2937
2975
|
}
|
|
2938
2976
|
}
|
|
2939
2977
|
const [ruffClient, biomeClient, knipClient, todoScanner, jscpdClient, depChecker, testRunnerClient, metricsClient, complexityClient, goClient, govulncheckClient, gitleaksClient, trivyClient, opengrepClient, rustClient, agentBehaviorClient2, deadCodeClients] = await Promise.all([
|
|
2940
|
-
load("ruff", async () => new (await import("../chunk-
|
|
2941
|
-
load("biome", async () => new (await import("../chunk-
|
|
2942
|
-
load("knip", async () => new (await import("../chunk-
|
|
2943
|
-
load("todo", async () => new (await import("../chunk-
|
|
2944
|
-
load("jscpd", async () => new (await import("../chunk-
|
|
2945
|
-
load("dependency-checker", async () => new (await import("../chunk-
|
|
2946
|
-
load("test-runner", async () => new (await import("../chunk-
|
|
2947
|
-
load("metrics", async () => new (await import("../chunk-
|
|
2948
|
-
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()),
|
|
2949
2987
|
// The process-wide singleton, NOT a fresh instance (#2455 fix round 4,
|
|
2950
2988
|
// F2). `handleSessionStart` reads this object for its "Active tools"
|
|
2951
2989
|
// line while `resetGoAvailability` re-arms the singleton's latch; a
|
|
2952
2990
|
// second instance here meant the reset never reached the surface a
|
|
2953
2991
|
// user actually sees.
|
|
2954
|
-
load("go", async () => (await import("../chunk-
|
|
2955
|
-
load("govulncheck", async () => new (await import("../chunk-
|
|
2956
|
-
load("gitleaks", async () => new (await import("../chunk-
|
|
2957
|
-
load("trivy", async () => new (await import("../chunk-
|
|
2958
|
-
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()),
|
|
2959
2997
|
// The process-wide singleton, for the same reason as "go" above.
|
|
2960
|
-
load("rust", async () => (await import("../chunk-
|
|
2961
|
-
load("agent-behavior", async () => (await import("../chunk-
|
|
2962
|
-
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())
|
|
2963
3001
|
]);
|
|
2964
3002
|
if (failures.length > 0)
|
|
2965
3003
|
await logBootstrapFailures(failures);
|
|
@@ -3046,7 +3084,7 @@ function resetAnalyzerBootstrapSessionState() {
|
|
|
3046
3084
|
}
|
|
3047
3085
|
|
|
3048
3086
|
// dist/clients/formatters-lazy.js
|
|
3049
|
-
var lazyFormatters = createLazyImport(() => import("../chunk-
|
|
3087
|
+
var lazyFormatters = createLazyImport(() => import("../chunk-ZVUL7QYY.js"));
|
|
3050
3088
|
function warmFormatters() {
|
|
3051
3089
|
return lazyFormatters.get();
|
|
3052
3090
|
}
|
|
@@ -3200,13 +3238,18 @@ function readChangeLogMaxSeq(logPath) {
|
|
|
3200
3238
|
}
|
|
3201
3239
|
var CHANGE_LOG_LOCK = { staleMs: 5e3, waitMs: 500 };
|
|
3202
3240
|
function appendProjectChangeAllocated(cwd, build) {
|
|
3241
|
+
appendProjectChangesAllocated(cwd, (logMaxSeq) => [build(logMaxSeq)]);
|
|
3242
|
+
}
|
|
3243
|
+
function appendProjectChangesAllocated(cwd, buildAll) {
|
|
3203
3244
|
const logPath = getProjectChangeLogPath(cwd);
|
|
3204
3245
|
fs7.mkdirSync(path7.dirname(logPath), { recursive: true });
|
|
3205
3246
|
readChangeLogMaxSeq(logPath);
|
|
3206
3247
|
const append = (locked) => {
|
|
3207
|
-
const
|
|
3208
|
-
|
|
3209
|
-
|
|
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}
|
|
3210
3253
|
`, "utf-8");
|
|
3211
3254
|
};
|
|
3212
3255
|
const result = withGenerationLockSync(`${logPath}.locks`, CHANGE_LOG_LOCK, () => append(true));
|
|
@@ -3227,7 +3270,11 @@ function inlineBlockerSources(blockers) {
|
|
|
3227
3270
|
}
|
|
3228
3271
|
function inlineBlockerLines(blockers, filePath) {
|
|
3229
3272
|
const own = normalizeEphemeralMapKey(filePath);
|
|
3230
|
-
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");
|
|
3231
3278
|
}
|
|
3232
3279
|
|
|
3233
3280
|
// dist/clients/partial-edit-apply.js
|
|
@@ -3413,6 +3460,7 @@ function recordViewIncomplete(cwd, cause) {
|
|
|
3413
3460
|
});
|
|
3414
3461
|
}
|
|
3415
3462
|
var MAX_RESOLVED_BLOCKER_FILES = 10;
|
|
3463
|
+
var MAX_OWED_ANCHORS = 16;
|
|
3416
3464
|
var TOOL_CALL_ATTRIBUTION_CAPACITY = 256;
|
|
3417
3465
|
var TOOL_CALL_ATTRIBUTION_TTL_MS = 5 * 6e4;
|
|
3418
3466
|
var TurnWarningsBySession = class {
|
|
@@ -3462,7 +3510,7 @@ var RuntimeCoordinator = class {
|
|
|
3462
3510
|
diagnosticsSurfaced: 0,
|
|
3463
3511
|
coldSnapshotTouches: 0
|
|
3464
3512
|
};
|
|
3465
|
-
_complexityBaselines = /* @__PURE__ */ new
|
|
3513
|
+
_complexityBaselines = /* @__PURE__ */ new Set();
|
|
3466
3514
|
_fixedThisTurn = new PathKeyedMap(normalizeMapKey);
|
|
3467
3515
|
_writtenThisTurn = new PathKeyedMap(normalizeMapKey);
|
|
3468
3516
|
_autofixDemotedThisTurn = new PathKeyedMap(normalizeMapKey);
|
|
@@ -3551,6 +3599,26 @@ var RuntimeCoordinator = class {
|
|
|
3551
3599
|
_readWidenings = new BoundedLruCache(TOOL_CALL_ATTRIBUTION_CAPACITY);
|
|
3552
3600
|
_lspReadWarmState = /* @__PURE__ */ new Map();
|
|
3553
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);
|
|
3554
3622
|
/**
|
|
3555
3623
|
* #3507: one per-path order for BOTH verbs on `_pendingInlineBlockers`,
|
|
3556
3624
|
* the widget store's guard shape (`widget-state.ts` diagnosticsWriteGuard).
|
|
@@ -3639,6 +3707,8 @@ var RuntimeCoordinator = class {
|
|
|
3639
3707
|
this._readWidenings.clear();
|
|
3640
3708
|
this._lspReadWarmState.clear();
|
|
3641
3709
|
this._pendingInlineBlockers.clear();
|
|
3710
|
+
this._owedRunners.clear();
|
|
3711
|
+
this._owedAnchors.clear();
|
|
3642
3712
|
this._inlineBlockerWriteOrder.clear();
|
|
3643
3713
|
this._resolvedBlockerFilesThisTurn.clear();
|
|
3644
3714
|
this._resolvedBlockerFilesDropped = 0;
|
|
@@ -3792,20 +3862,79 @@ var RuntimeCoordinator = class {
|
|
|
3792
3862
|
}
|
|
3793
3863
|
}
|
|
3794
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) {
|
|
3795
3925
|
if (this._mutationReceipts.length >= MAX_MUTATION_RECEIPTS) {
|
|
3796
3926
|
this._mutationReceipts.shift();
|
|
3797
3927
|
this._droppedMutationReceipts += 1;
|
|
3798
3928
|
}
|
|
3799
3929
|
this._mutationReceipts.push({
|
|
3800
|
-
seq: projectSeq,
|
|
3930
|
+
seq: bump.projectSeq,
|
|
3801
3931
|
// Reuse the bump's normalized key (a realpath syscall: ~200us on
|
|
3802
3932
|
// Windows, ~1.8us on POSIX since #3098) — never re-derive it here.
|
|
3803
|
-
filePath: key,
|
|
3804
|
-
source
|
|
3933
|
+
filePath: bump.key,
|
|
3934
|
+
source,
|
|
3805
3935
|
turnIndex: this._turnIndex,
|
|
3806
3936
|
ts: Date.now()
|
|
3807
3937
|
});
|
|
3808
|
-
return { projectSeq, fileSeq };
|
|
3809
3938
|
}
|
|
3810
3939
|
/**
|
|
3811
3940
|
* Attributed mutations whose seq is strictly after `seq` — the receipt-level
|
|
@@ -4274,7 +4403,7 @@ var RuntimeCoordinator = class {
|
|
|
4274
4403
|
const existing = this._pendingInlineBlockers.get(key);
|
|
4275
4404
|
if (existing && !existing.diagnostics)
|
|
4276
4405
|
return 0;
|
|
4277
|
-
const identity = (d) => JSON.stringify([d
|
|
4406
|
+
const identity = (d) => JSON.stringify([foldedFindingIdentity(d), d.line, d.column]);
|
|
4278
4407
|
const known = new Set((existing?.diagnostics ?? []).map(identity));
|
|
4279
4408
|
const added = blocking.flatMap((d) => known.has(identity(d)) ? [] : [d]);
|
|
4280
4409
|
if (added.length === 0)
|
|
@@ -4310,6 +4439,91 @@ var RuntimeCoordinator = class {
|
|
|
4310
4439
|
});
|
|
4311
4440
|
return added.length;
|
|
4312
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
|
+
}
|
|
4313
4527
|
/**
|
|
4314
4528
|
* #3218 criterion 2: remember one file whose blocker a clean verdict just
|
|
4315
4529
|
* retired, for the turn-end "Resolved" line. Called from the two retire
|
|
@@ -4347,9 +4561,22 @@ var RuntimeCoordinator = class {
|
|
|
4347
4561
|
* counted as `blocker-clear-refused` per file key. A record with no
|
|
4348
4562
|
* `recordedHash` (#2982: the file was unreadable or over the baseline cap at
|
|
4349
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.
|
|
4350
4569
|
*/
|
|
4351
4570
|
clearInlineBlockers(filePath, writeIndex, orderTurn = this._writeOrderTurn, analysis) {
|
|
4352
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
|
+
}
|
|
4353
4580
|
if (existing && analysis && !analysis.authored && analysis.sha256 !== void 0 && existing.recordedHash === analysis.sha256) {
|
|
4354
4581
|
incrementDegradationCount({
|
|
4355
4582
|
kind: "blocker-clear-refused",
|
|
@@ -5344,7 +5571,8 @@ function boundDeferredTargets(entries, max, isOwn) {
|
|
|
5344
5571
|
}
|
|
5345
5572
|
|
|
5346
5573
|
// dist/clients/test-runner-delivery.js
|
|
5347
|
-
var
|
|
5574
|
+
var MAX_PENDING_DELIVERIES = 32;
|
|
5575
|
+
var pending = new BoundedFifoMap(MAX_PENDING_DELIVERIES);
|
|
5348
5576
|
function resetTestRunnerDelivery() {
|
|
5349
5577
|
pending.clear();
|
|
5350
5578
|
}
|
|
@@ -5603,8 +5831,8 @@ async function igniteDominantLanguageWarm(cwd, runtime, sessionGeneration, dbg)
|
|
|
5603
5831
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5604
5832
|
return;
|
|
5605
5833
|
const lspService = (await loadLspService()).getLSPService();
|
|
5606
|
-
const { collectSourceFilesAsync } = await import("../chunk-
|
|
5607
|
-
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");
|
|
5608
5836
|
const files = await collectSourceFilesAsync(cwd, {
|
|
5609
5837
|
inspectGeneratedHeaders: false
|
|
5610
5838
|
});
|
|
@@ -5670,7 +5898,7 @@ function scheduleManagedToolRefresh(dbg) {
|
|
|
5670
5898
|
const timer = setTimeout(() => {
|
|
5671
5899
|
void (async () => {
|
|
5672
5900
|
try {
|
|
5673
|
-
const refresh = await import("../chunk-
|
|
5901
|
+
const refresh = await import("../chunk-2KXTHF3M.js");
|
|
5674
5902
|
const outcome = await refresh.runManagedToolRefresh();
|
|
5675
5903
|
if (outcome.skipped) {
|
|
5676
5904
|
dbg(`session_start tool-refresh: skipped (${outcome.skipped})`);
|
|
@@ -5717,7 +5945,7 @@ function scanOneTodoFile(scanner, filePath, items) {
|
|
|
5717
5945
|
async function collectTodoBaselineItems(scanner, analysisRoot, stillCurrent) {
|
|
5718
5946
|
const items = [];
|
|
5719
5947
|
try {
|
|
5720
|
-
const { getSourceFilesAsync } = await import("../chunk-
|
|
5948
|
+
const { getSourceFilesAsync } = await import("../chunk-TRETHTQO.js");
|
|
5721
5949
|
const files = await getSourceFilesAsync(analysisRoot, true);
|
|
5722
5950
|
if (!stillCurrent())
|
|
5723
5951
|
return items;
|
|
@@ -5746,7 +5974,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5746
5974
|
const snapshot = loadProjectSnapshot(snapshotRoot);
|
|
5747
5975
|
const snapshotLoadMs = Date.now() - snapshotLoadStartMs;
|
|
5748
5976
|
if (snapshot?.wordIndex) {
|
|
5749
|
-
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");
|
|
5750
5978
|
const deserializeStartMs = Date.now();
|
|
5751
5979
|
const index = deserializeWordIndex(snapshot.wordIndex);
|
|
5752
5980
|
const deserializeMs = Date.now() - deserializeStartMs;
|
|
@@ -5771,6 +5999,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5771
5999
|
});
|
|
5772
6000
|
} else {
|
|
5773
6001
|
runtime.wordIndex = index;
|
|
6002
|
+
notifyWordIndexPublished2(snapshotRoot, index, "session_start");
|
|
5774
6003
|
let snapshotSaveSyncMs = 0;
|
|
5775
6004
|
if (!isProjectSnapshotFresh(snapshot, effectiveSeq, latestSeq.unlockedThrough) || result.refreshed > 0 || result.dropped > 0 || snapshot.wordIndex.truncated !== index.truncated) {
|
|
5776
6005
|
const serializeSaveEnqueueStartMs = Date.now();
|
|
@@ -5818,7 +6047,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5818
6047
|
}
|
|
5819
6048
|
}
|
|
5820
6049
|
}
|
|
5821
|
-
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes } = await import("../chunk-
|
|
6050
|
+
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes, notifyWordIndexPublished } = await import("../chunk-ATKJFDQN.js");
|
|
5822
6051
|
const docs = await collectWordIndexDocs(analysisRoot, () => runtime.isCurrentSession(sessionGeneration), rebuildPreflightFiles);
|
|
5823
6052
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5824
6053
|
return;
|
|
@@ -5835,6 +6064,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5835
6064
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5836
6065
|
return;
|
|
5837
6066
|
runtime.wordIndex = rebuiltIndex;
|
|
6067
|
+
notifyWordIndexPublished(snapshotRoot, rebuiltIndex, "session_start");
|
|
5838
6068
|
saveRuntimeProjectSnapshot({ cwd: snapshotRoot, runtime, dbg });
|
|
5839
6069
|
dbg(`session_start word-index: rebuilt (absent/stale, seq=${effectiveSeq}) ${runtime.wordIndex.docCount} files, ${runtime.wordIndex.postings.size} tokens (${Date.now() - startMs}ms)`);
|
|
5840
6070
|
logWordIndex({
|
|
@@ -5857,6 +6087,11 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5857
6087
|
reused: 0
|
|
5858
6088
|
};
|
|
5859
6089
|
}
|
|
6090
|
+
var STARTUP_TASK_DEFER_MS = {
|
|
6091
|
+
"call-graph": 5e3,
|
|
6092
|
+
"codebase-model": 5200,
|
|
6093
|
+
"ast-grep-exports": 5400
|
|
6094
|
+
};
|
|
5860
6095
|
function scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg) {
|
|
5861
6096
|
void (async () => {
|
|
5862
6097
|
const resolved = await demandBootstrapDeps(deps, "session-start-scans");
|
|
@@ -5878,15 +6113,10 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5878
6113
|
reason: "skipped (disabled by config)"
|
|
5879
6114
|
});
|
|
5880
6115
|
}
|
|
5881
|
-
const taskDeferMsByName = {
|
|
5882
|
-
"call-graph": 5e3,
|
|
5883
|
-
"codebase-model": 5200,
|
|
5884
|
-
"ast-grep exports": 5400,
|
|
5885
|
-
"project index": 5400
|
|
5886
|
-
};
|
|
5887
6116
|
const runTask = (name, task) => {
|
|
5888
6117
|
const queuedAt = Date.now();
|
|
5889
|
-
|
|
6118
|
+
const delay = STARTUP_TASK_DEFER_MS[name] ?? 0;
|
|
6119
|
+
dbg(`session_start task ${name}: scheduled deferMs=${delay}`);
|
|
5890
6120
|
runtime.markStartupScanInFlight(name, sessionGeneration);
|
|
5891
6121
|
const completion = new Promise((resolve32) => {
|
|
5892
6122
|
const fire = () => {
|
|
@@ -5903,7 +6133,6 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5903
6133
|
resolve32();
|
|
5904
6134
|
});
|
|
5905
6135
|
};
|
|
5906
|
-
const delay = taskDeferMsByName[name] ?? 0;
|
|
5907
6136
|
if (delay > 0) {
|
|
5908
6137
|
setTimeout(fire, delay).unref?.();
|
|
5909
6138
|
} else {
|
|
@@ -5915,7 +6144,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5915
6144
|
const canRunJsTsHeavyScans = canRunStartupHeavyScans(languageProfile, "jsts");
|
|
5916
6145
|
const scanNames = ["todo", "dead-code"];
|
|
5917
6146
|
if (canRunJsTsHeavyScans) {
|
|
5918
|
-
scanNames.push("knip", "jscpd", "ast-grep
|
|
6147
|
+
scanNames.push("knip", "jscpd", "ast-grep-exports");
|
|
5919
6148
|
}
|
|
5920
6149
|
dbg(`session_start: launching background scans (${scanNames.join(", ")})`);
|
|
5921
6150
|
void runTask("todo", async () => {
|
|
@@ -6183,9 +6412,9 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6183
6412
|
});
|
|
6184
6413
|
let callGraphIdentity;
|
|
6185
6414
|
const callGraphTask = runTask("call-graph", async () => {
|
|
6186
|
-
const { FactStore: FactStore2 } = await import("../chunk-
|
|
6187
|
-
const { buildOrUpdateGraph, extractSymbolsAndRefsFromGraph, getReviewGraphCacheIdentity } = await import("../chunk-
|
|
6188
|
-
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");
|
|
6189
6418
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
6190
6419
|
return;
|
|
6191
6420
|
const startMs = Date.now();
|
|
@@ -6226,7 +6455,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6226
6455
|
return;
|
|
6227
6456
|
if (!runtime.callGraph)
|
|
6228
6457
|
return;
|
|
6229
|
-
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");
|
|
6230
6459
|
if (!callGraphIdentity)
|
|
6231
6460
|
return;
|
|
6232
6461
|
const model = buildCodebaseModel(runtime.callGraph, analysisRoot, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET, callGraphIdentity);
|
|
@@ -6258,18 +6487,18 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6258
6487
|
});
|
|
6259
6488
|
});
|
|
6260
6489
|
}
|
|
6261
|
-
function scheduleDeferredToolProbes(deps, languageProfile, startupDefaults,
|
|
6490
|
+
function scheduleDeferredToolProbes(deps, languageProfile, startupDefaults, dbg) {
|
|
6262
6491
|
void (async () => {
|
|
6263
6492
|
const resolved = await demandBootstrapDeps(deps, "session-start-tool-probes");
|
|
6264
6493
|
if (!resolved) {
|
|
6265
6494
|
dbg("session_start tools: analyzer bootstrap unavailable \u2014 no probes");
|
|
6266
6495
|
return;
|
|
6267
6496
|
}
|
|
6268
|
-
scheduleDeferredToolProbesWithClients(resolved, languageProfile, startupDefaults,
|
|
6497
|
+
scheduleDeferredToolProbesWithClients(resolved, languageProfile, startupDefaults, dbg);
|
|
6269
6498
|
})();
|
|
6270
6499
|
}
|
|
6271
|
-
function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDefaults,
|
|
6272
|
-
const { biomeClient, ruffClient
|
|
6500
|
+
function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDefaults, dbg) {
|
|
6501
|
+
const { biomeClient, ruffClient } = deps;
|
|
6273
6502
|
const defaultTools = new Set(startupDefaults);
|
|
6274
6503
|
const probes = [];
|
|
6275
6504
|
if (languageProfile.present.jsts && !defaultTools.has("biome")) {
|
|
@@ -6278,9 +6507,6 @@ function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDef
|
|
|
6278
6507
|
if (languageProfile.present.python && !defaultTools.has("ruff")) {
|
|
6279
6508
|
probes.push(["ruff", () => ruffClient.ensureAvailable()]);
|
|
6280
6509
|
}
|
|
6281
|
-
if (startupScansWillRun) {
|
|
6282
|
-
probes.push(["madge", () => depChecker.ensureAvailable()]);
|
|
6283
|
-
}
|
|
6284
6510
|
if (probes.length === 0) {
|
|
6285
6511
|
dbg("session_start tools: no deferred availability probes needed");
|
|
6286
6512
|
return;
|
|
@@ -6299,6 +6525,34 @@ function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDef
|
|
|
6299
6525
|
dbg(`session_start tools (deferred probes complete, ${Date.now() - warmStart}ms): ${summary}`);
|
|
6300
6526
|
})();
|
|
6301
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
|
+
}
|
|
6302
6556
|
function readSubstituteGuidance(isEnabled) {
|
|
6303
6557
|
const units = [];
|
|
6304
6558
|
if (isEnabled("symbol_search")) {
|
|
@@ -6410,8 +6664,8 @@ async function handleSessionStart(deps) {
|
|
|
6410
6664
|
try {
|
|
6411
6665
|
warmupDbg("warmup: starting background warmup");
|
|
6412
6666
|
const scanContextStartedAt = Date.now();
|
|
6413
|
-
const startupScanModule = await import("../chunk-
|
|
6414
|
-
const languageProfileModule = await import("../chunk-
|
|
6667
|
+
const startupScanModule = await import("../chunk-GSLNCYGG.js");
|
|
6668
|
+
const languageProfileModule = await import("../chunk-AMERCH6V.js");
|
|
6415
6669
|
const warmupSnapshotRoot = resolveSnapshotRoot(warmupCwd);
|
|
6416
6670
|
const cachedSnapshot = loadProjectSnapshot(warmupSnapshotRoot);
|
|
6417
6671
|
warmupOwnSnapshotRead = cachedSnapshot ? {
|
|
@@ -6545,32 +6799,7 @@ async function handleSessionStart(deps) {
|
|
|
6545
6799
|
clearAllSessions();
|
|
6546
6800
|
runtime.complexityBaselines.clear();
|
|
6547
6801
|
resetDispatchBaselines2(ctxCwd);
|
|
6548
|
-
|
|
6549
|
-
resetOpaqueMutationState();
|
|
6550
|
-
resetObservedMutationNet();
|
|
6551
|
-
resetMutationAttribution();
|
|
6552
|
-
primePersistedMutationAttribution(ctxCwd);
|
|
6553
|
-
resetPendingAuxiliaryCoverage();
|
|
6554
|
-
resetSafeSpawnWindowsCommandCache();
|
|
6555
|
-
resetDispatchAvailabilityState();
|
|
6556
|
-
resetObservedRunnerLatency();
|
|
6557
|
-
resetPendingRunnerFindings();
|
|
6558
|
-
resetSpawnTimeoutCooldowns();
|
|
6559
|
-
clearFormatterCache();
|
|
6560
|
-
resetZizmorTokenAvailability();
|
|
6561
|
-
resetGoAvailability();
|
|
6562
|
-
resetRustAvailability();
|
|
6563
|
-
resetPsScriptAnalyzerAvailability();
|
|
6564
|
-
resetInstallRetryLatches();
|
|
6565
|
-
resetLazyInstallAttempts();
|
|
6566
|
-
resetDirectLspCommandAvailability();
|
|
6567
|
-
resetLSPCaseSensitivityState();
|
|
6568
|
-
resetResolvedPathCache();
|
|
6569
|
-
_resetPackageManagerCache();
|
|
6570
|
-
resetManagedToolRefreshSession();
|
|
6571
|
-
resetSmellsSessionState();
|
|
6572
|
-
resetSituationalToolTelemetry();
|
|
6573
|
-
resetWorkspaceDiagnosticsCacheSession(sessionStartMs);
|
|
6802
|
+
resetSessionScopedState(ctxCwd, sessionStartMs);
|
|
6574
6803
|
deps.bootstrap.peek()?.knipClient.resetSessionState?.();
|
|
6575
6804
|
resetCascadeTierSessionState();
|
|
6576
6805
|
runtime.resetForSession(sessionStartMs);
|
|
@@ -6957,10 +7186,8 @@ async function handleSessionStart(deps) {
|
|
|
6957
7186
|
dbg("session_start: no language defaults selected for pre-install");
|
|
6958
7187
|
}
|
|
6959
7188
|
const startupScansEnabled = deps.projectConfig?.startup?.scans?.enabled ?? deps.globalConfig?.startup?.scans?.enabled ?? true;
|
|
6960
|
-
const startupScansWillRun = allowBootstrapTasks && startupScan.canWarmCaches && startupScansEnabled;
|
|
6961
|
-
const jstsHeavyScansWillRun = startupScansWillRun && canRunStartupHeavyScans(languageProfile, "jsts");
|
|
6962
7189
|
if (allowBootstrapTasks) {
|
|
6963
|
-
scheduleDeferredToolProbes(deps, languageProfile, startupDefaults,
|
|
7190
|
+
scheduleDeferredToolProbes(deps, languageProfile, startupDefaults, dbg);
|
|
6964
7191
|
scheduleManagedToolRefresh(dbg);
|
|
6965
7192
|
}
|
|
6966
7193
|
if (allowBootstrapTasks) {
|
|
@@ -7331,6 +7558,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7331
7558
|
const cwd = path15.resolve(args.cwd);
|
|
7332
7559
|
const records = [...args.dispatchWarnings];
|
|
7333
7560
|
const lspService = getLSPService();
|
|
7561
|
+
const excludeServerIds = args.getFlag ? configDisabledAuxiliaryLspServerIds(args.getFlag) : void 0;
|
|
7334
7562
|
const observedAtByPath = /* @__PURE__ */ new Map();
|
|
7335
7563
|
const buildStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7336
7564
|
logActionableWarningsEvent({
|
|
@@ -7400,6 +7628,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7400
7628
|
const pullTimeoutMs = boundedNumber(args.lspPullTimeoutMs, ACTIONABLE_WARNINGS_LSP_PULL_TIMEOUT_MS);
|
|
7401
7629
|
const inBandDeps = {
|
|
7402
7630
|
lspService,
|
|
7631
|
+
excludeServerIds,
|
|
7403
7632
|
pullTimeoutMs,
|
|
7404
7633
|
// #2504 review round 4 (F2). This is the AWAITED hook: the batch
|
|
7405
7634
|
// budget has to bound what happens INSIDE a file, not only how many
|
|
@@ -7447,6 +7676,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7447
7676
|
const loopSignal = combineAbortSignals(args.signal, deferredSignal) ?? deferredSignal;
|
|
7448
7677
|
const deferredDeps = {
|
|
7449
7678
|
lspService,
|
|
7679
|
+
excludeServerIds,
|
|
7450
7680
|
pullTimeoutMs,
|
|
7451
7681
|
signal: loopSignal,
|
|
7452
7682
|
// OFF the hook by construction: this loop is the answer to
|
|
@@ -7561,7 +7791,7 @@ async function enrichFileFromLsp(cwd, args, target, deps) {
|
|
|
7561
7791
|
return out;
|
|
7562
7792
|
}
|
|
7563
7793
|
}
|
|
7564
|
-
const pulled = await boundedLspCall(() => lspService.getDiagnostics(filePath), deps);
|
|
7794
|
+
const pulled = await boundedLspCall(() => lspService.getDiagnostics(filePath, "full", deps.excludeServerIds), deps);
|
|
7565
7795
|
if (pulled === void 0) {
|
|
7566
7796
|
logActionableWarningsEvent({
|
|
7567
7797
|
event: "lsp_file_skipped",
|
|
@@ -8118,8 +8348,8 @@ var MAX_FAILURE_TRACKER_SIZE = 200;
|
|
|
8118
8348
|
var recentOldTextFailures = new BoundedFifoMap(MAX_FAILURE_TRACKER_SIZE);
|
|
8119
8349
|
|
|
8120
8350
|
// dist/clients/deferred-runner-blockers.js
|
|
8121
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
8122
8351
|
import * as fs14 from "node:fs";
|
|
8352
|
+
import { resolve as resolve9 } from "node:path";
|
|
8123
8353
|
function judgeDeferredRunnerFindings(pending2, cwd, options = {}) {
|
|
8124
8354
|
const findings = pending2.result?.diagnostics ?? [];
|
|
8125
8355
|
if (findings.length === 0) {
|
|
@@ -8160,7 +8390,7 @@ function judgeDeferredRunnerFindings(pending2, cwd, options = {}) {
|
|
|
8160
8390
|
};
|
|
8161
8391
|
}
|
|
8162
8392
|
function recordDeferredRunnerBlockers(runtime, pending2, survivors, bytes) {
|
|
8163
|
-
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));
|
|
8164
8394
|
if (blocking.length === 0)
|
|
8165
8395
|
return 0;
|
|
8166
8396
|
const recorded = runtime.recordDeferredInlineBlockers(pending2.filePath, blocking, {
|
|
@@ -8168,7 +8398,7 @@ function recordDeferredRunnerBlockers(runtime, pending2, survivors, bytes) {
|
|
|
8168
8398
|
...bytes ? {
|
|
8169
8399
|
contentBaseline: {
|
|
8170
8400
|
size: bytes.byteLength,
|
|
8171
|
-
sha256:
|
|
8401
|
+
sha256: hashContentBytes(bytes)
|
|
8172
8402
|
}
|
|
8173
8403
|
} : {}
|
|
8174
8404
|
});
|
|
@@ -8176,6 +8406,36 @@ function recordDeferredRunnerBlockers(runtime, pending2, survivors, bytes) {
|
|
|
8176
8406
|
runtime.updateGitGuardStatus(false, "");
|
|
8177
8407
|
return recorded;
|
|
8178
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
|
+
}
|
|
8179
8439
|
function readBytes(filePath) {
|
|
8180
8440
|
try {
|
|
8181
8441
|
return fs14.readFileSync(filePath);
|
|
@@ -8837,7 +9097,7 @@ function stillReportedParked(parked, current, keyOf, offeredKeys) {
|
|
|
8837
9097
|
}
|
|
8838
9098
|
|
|
8839
9099
|
// dist/clients/knip-scan-roots.js
|
|
8840
|
-
import { resolve as
|
|
9100
|
+
import { resolve as resolve14 } from "node:path";
|
|
8841
9101
|
var MAX_KNIP_ROOTS_PER_TURN = 3;
|
|
8842
9102
|
function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
8843
9103
|
const session = resolveGitCheckout(sessionCwd);
|
|
@@ -8847,7 +9107,7 @@ function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
|
8847
9107
|
let sessionOwnsEdit = false;
|
|
8848
9108
|
const linked = [];
|
|
8849
9109
|
for (const file of modifiedFiles) {
|
|
8850
|
-
const owner = resolveLinkedWorktreeOwner(session,
|
|
9110
|
+
const owner = resolveLinkedWorktreeOwner(session, resolve14(sessionCwd, file));
|
|
8851
9111
|
if (owner === null) {
|
|
8852
9112
|
sessionOwnsEdit = true;
|
|
8853
9113
|
} else if (!linked.some((known) => pathsEqual(known.root, owner.root))) {
|
|
@@ -9109,7 +9369,7 @@ function selectPersistentReverifyFiles(report, nowMs = Date.now()) {
|
|
|
9109
9369
|
} catch {
|
|
9110
9370
|
continue;
|
|
9111
9371
|
}
|
|
9112
|
-
if (mtimeMs
|
|
9372
|
+
if (freshnessFromMtime({ mtimeMs, referenceMs: stamp, toleranceMs: 0 }).verdict === "stale") {
|
|
9113
9373
|
skippedChanged += 1;
|
|
9114
9374
|
continue;
|
|
9115
9375
|
}
|
|
@@ -9500,6 +9760,10 @@ function lateDeadCodeScansOf(scope) {
|
|
|
9500
9760
|
function joinedEarlierScan(result, askedAt) {
|
|
9501
9761
|
return result.scannedAt !== void 0 && Date.parse(result.scannedAt) < askedAt;
|
|
9502
9762
|
}
|
|
9763
|
+
var KNIP_CARRIED_FILES = "knip-carried-files";
|
|
9764
|
+
function knipCarriedFilesOf(scope) {
|
|
9765
|
+
return scopeCell(scope, KNIP_CARRIED_FILES, () => /* @__PURE__ */ new Map());
|
|
9766
|
+
}
|
|
9503
9767
|
function withRowForFailureWrite(scan, cacheManager2, cacheKey, cwd, startRow) {
|
|
9504
9768
|
return scan.then((result) => result.success || startRow?.data.success === true ? { result, row: startRow } : cacheManager2.readCacheAsync(cacheKey, cwd).then((row) => ({ result, row })));
|
|
9505
9769
|
}
|
|
@@ -9843,6 +10107,7 @@ async function handleTurnEnd(deps) {
|
|
|
9843
10107
|
let runnerFindingsFailed = 0;
|
|
9844
10108
|
let runnerFindingsDropped = 0;
|
|
9845
10109
|
let runnerBlockersRecorded = 0;
|
|
10110
|
+
let runnerBlockersRetired = 0;
|
|
9846
10111
|
let runnerFindingsDispositionSuppressed = 0;
|
|
9847
10112
|
const runnerFindingsDeliveredIds = [];
|
|
9848
10113
|
for (const pending2 of pendingRunnerFindings) {
|
|
@@ -9869,6 +10134,7 @@ async function handleTurnEnd(deps) {
|
|
|
9869
10134
|
dropStaleRunnerFindings(pending2);
|
|
9870
10135
|
runnerFindingsDropped += 1;
|
|
9871
10136
|
}
|
|
10137
|
+
runnerBlockersRetired += retireSettledRunnerBlockers(runtime, pending2, verdict);
|
|
9872
10138
|
if (verdict.live === 0)
|
|
9873
10139
|
continue;
|
|
9874
10140
|
const displayPath = toRunnerDisplayPath(cwd, pending2.filePath);
|
|
@@ -9914,6 +10180,7 @@ ${lines.join("\n")}`;
|
|
|
9914
10180
|
failed: runnerFindingsFailed,
|
|
9915
10181
|
dropped: runnerFindingsDropped,
|
|
9916
10182
|
blockersRecorded: runnerBlockersRecorded,
|
|
10183
|
+
blockersRetired: runnerBlockersRetired,
|
|
9917
10184
|
dispositionSuppressed: runnerFindingsDispositionSuppressed,
|
|
9918
10185
|
deliveredIds: runnerFindingsDeliveredIds
|
|
9919
10186
|
}
|
|
@@ -10080,6 +10347,7 @@ ${policy.body}`);
|
|
|
10080
10347
|
durationMs: Date.now() - cascadeSettleStart,
|
|
10081
10348
|
metadata: { settled, timedOut }
|
|
10082
10349
|
});
|
|
10350
|
+
peekOutstandingCascadeTouches(holdScope);
|
|
10083
10351
|
const t0 = Date.now();
|
|
10084
10352
|
const cascadeRuns = (holdScope.guardedWrite("turn-end:cascade-runs", () => runtime.consumeCascadeRuns()) ?? []).filter((run) => {
|
|
10085
10353
|
const originSeq = run.origin?.projectSeq;
|
|
@@ -10132,40 +10400,91 @@ ${policy.body}`);
|
|
|
10132
10400
|
}
|
|
10133
10401
|
}
|
|
10134
10402
|
const cascadeLogFilePath = cascadeResults[0]?.filePath ?? files[0] ?? cwd;
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
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 });
|
|
10148
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) {
|
|
10149
10434
|
const parts = [];
|
|
10150
10435
|
const sectionRuns = [];
|
|
10151
10436
|
let injectedNeighborCount = 0;
|
|
10152
10437
|
let injectedDiagnosticCount = 0;
|
|
10153
10438
|
let suppressedByOwnership = 0;
|
|
10439
|
+
const sectionObservations = [];
|
|
10440
|
+
const shownUnansweredServerIds = /* @__PURE__ */ new Set();
|
|
10441
|
+
const unansweredLines = [];
|
|
10154
10442
|
for (const result of seen.values()) {
|
|
10155
|
-
const
|
|
10156
|
-
const ownsAny =
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
|
|
10162
|
-
if (
|
|
10163
|
-
|
|
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
|
+
}
|
|
10164
10472
|
const sectionRun = runByResult.get(result);
|
|
10165
10473
|
if (sectionRun)
|
|
10166
10474
|
sectionRuns.push(sectionRun);
|
|
10167
|
-
|
|
10168
|
-
|
|
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);
|
|
10169
10488
|
} else if (!ownsAny && result.formatted) {
|
|
10170
10489
|
suppressedByOwnership++;
|
|
10171
10490
|
}
|
|
@@ -10199,11 +10518,20 @@ ${testLines.join("\n")}`;
|
|
|
10199
10518
|
parts.push(testSection);
|
|
10200
10519
|
}
|
|
10201
10520
|
}
|
|
10521
|
+
if (unansweredLines.length > 0)
|
|
10522
|
+
parts.unshift(unansweredLines.join("\n"));
|
|
10202
10523
|
if (parts.length > 0) {
|
|
10203
10524
|
const section = parts.join("\n\n");
|
|
10204
10525
|
blockerParts.push(section);
|
|
10526
|
+
const shownServerIds = [...shownUnansweredServerIds];
|
|
10205
10527
|
deliveryHolds.push({
|
|
10206
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
|
+
},
|
|
10207
10535
|
onHeld: () => {
|
|
10208
10536
|
for (const run of sectionRuns)
|
|
10209
10537
|
runtime.appendCascadeRun(run);
|
|
@@ -10232,6 +10560,124 @@ ${testLines.join("\n")}`;
|
|
|
10232
10560
|
}
|
|
10233
10561
|
});
|
|
10234
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
|
+
};
|
|
10235
10681
|
const indeterminateRuns = cascadeRuns.filter((r) => r.indeterminate);
|
|
10236
10682
|
if (indeterminateRuns.length > 0) {
|
|
10237
10683
|
const buildAdvisory = (runs, frame) => {
|
|
@@ -10259,47 +10705,20 @@ ${lines.join("\n")}`;
|
|
|
10259
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);
|
|
10260
10706
|
const bindingRuns = indeterminateRuns.filter((r) => r.indeterminate?.reason === "lsp_binding_rejected" && r.indeterminate?.budget === void 0);
|
|
10261
10707
|
const budgetRuns = indeterminateRuns.filter((r) => r.indeterminate?.reason === "budget_truncated" || r.indeterminate?.budget !== void 0);
|
|
10262
|
-
const withCarryLabel = (advisory, runs) => {
|
|
10263
|
-
if (advisory === void 0)
|
|
10264
|
-
return void 0;
|
|
10265
|
-
const carried = runs.filter((r) => (r.carriedTurns ?? 0) > 0);
|
|
10266
|
-
if (carried.length === 0 || carried.length !== runs.length) {
|
|
10267
|
-
return advisory;
|
|
10268
|
-
}
|
|
10269
|
-
const stamps = carried.map((r) => r.observedAt);
|
|
10270
|
-
const observedAt = stamps.every((s) => s !== void 0) ? Math.min(...stamps) : void 0;
|
|
10271
|
-
const suffix = cascadeCarrySuffix(carried[0]?.carriedTurns, observedAt);
|
|
10272
|
-
if (!suffix)
|
|
10273
|
-
return advisory;
|
|
10274
|
-
labeledAdvisories += 1;
|
|
10275
|
-
return `${advisory}
|
|
10276
|
-
${suffix}`;
|
|
10277
|
-
};
|
|
10278
|
-
const holdAdvisory = (advisory, runs) => {
|
|
10279
|
-
if (advisory === void 0)
|
|
10280
|
-
return;
|
|
10281
|
-
deliveryHolds.push({
|
|
10282
|
-
part: advisory,
|
|
10283
|
-
onHeld: () => {
|
|
10284
|
-
for (const run of runs)
|
|
10285
|
-
runtime.appendCascadeRun({ ...run, result: void 0 });
|
|
10286
|
-
}
|
|
10287
|
-
});
|
|
10288
|
-
};
|
|
10289
10708
|
const graphAdvisory = withCarryLabel(buildAdvisory(graphRuns, {
|
|
10290
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.`,
|
|
10291
10710
|
fallbackDetail: (r) => r.indeterminate?.reason === "missing_node" ? "changed file not in the review graph" : "review graph unavailable"
|
|
10292
10711
|
}), graphRuns);
|
|
10293
10712
|
if (graphAdvisory)
|
|
10294
10713
|
advisoryParts.push(graphAdvisory);
|
|
10295
|
-
holdAdvisory(graphAdvisory, graphRuns);
|
|
10714
|
+
holdAdvisory(graphAdvisory, graphRuns, "indeterminate");
|
|
10296
10715
|
const bindingAdvisory = withCarryLabel(buildAdvisory(bindingRuns, {
|
|
10297
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.`,
|
|
10298
10717
|
fallbackDetail: () => "cascade diagnostics withheld (binding rejected)"
|
|
10299
10718
|
}), bindingRuns);
|
|
10300
10719
|
if (bindingAdvisory)
|
|
10301
10720
|
advisoryParts.push(bindingAdvisory);
|
|
10302
|
-
holdAdvisory(bindingAdvisory, bindingRuns);
|
|
10721
|
+
holdAdvisory(bindingAdvisory, bindingRuns, "indeterminate");
|
|
10303
10722
|
const budgetAdvisory = withCarryLabel(buildAdvisory(budgetRuns, {
|
|
10304
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.`,
|
|
10305
10724
|
fallbackDetail: (r) => {
|
|
@@ -10312,7 +10731,7 @@ ${suffix}`;
|
|
|
10312
10731
|
}), budgetRuns);
|
|
10313
10732
|
if (budgetAdvisory)
|
|
10314
10733
|
advisoryParts.push(budgetAdvisory);
|
|
10315
|
-
holdAdvisory(budgetAdvisory, budgetRuns);
|
|
10734
|
+
holdAdvisory(budgetAdvisory, budgetRuns, "indeterminate");
|
|
10316
10735
|
const fileCount = new Set(indeterminateRuns.map((r) => normalizeMapKey(r.filePath))).size;
|
|
10317
10736
|
const byFile = indeterminateRuns.map((r) => ({
|
|
10318
10737
|
file: toRunnerDisplayPath(cwd, r.filePath),
|
|
@@ -10336,6 +10755,57 @@ ${suffix}`;
|
|
|
10336
10755
|
}
|
|
10337
10756
|
});
|
|
10338
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
|
+
}
|
|
10339
10809
|
if (carriedRunsRendered > 0 || labeledAdvisories > 0) {
|
|
10340
10810
|
logCascade({
|
|
10341
10811
|
phase: "cascade_carry_rendered",
|
|
@@ -10369,6 +10839,7 @@ ${suffix}`;
|
|
|
10369
10839
|
skipped: cascadeSkipped
|
|
10370
10840
|
}
|
|
10371
10841
|
});
|
|
10842
|
+
const knipCarried = knipCarriedFilesOf(turnScope);
|
|
10372
10843
|
const knipScan = resolveKnipScanRoots(cwd, files);
|
|
10373
10844
|
for (const root of knipScan.overCap) {
|
|
10374
10845
|
incrementDegradationCount({
|
|
@@ -10379,7 +10850,7 @@ ${suffix}`;
|
|
|
10379
10850
|
}
|
|
10380
10851
|
const KNOWN_SLOW_KNIP_GRACE_MS = 1;
|
|
10381
10852
|
const KNIP_MAX_SHOWN = 5;
|
|
10382
|
-
const applyKnipResult = (scanRoot, prevKnip, knipResult, rowNow) => {
|
|
10853
|
+
const applyKnipResult = (scanRoot, prevKnip, knipResult, rowNow, joined) => {
|
|
10383
10854
|
const knipWouldPoison = wouldPoisonCache(rowNow, knipResult);
|
|
10384
10855
|
if (knipWouldPoison) {
|
|
10385
10856
|
dbg(`turn_end: keeping last good knip cache; this run failed: ${knipResult.summary}`);
|
|
@@ -10412,7 +10883,7 @@ ${suffix}`;
|
|
|
10412
10883
|
if (knipResult.success && knipResult.issues.length > 0) {
|
|
10413
10884
|
const issueKey = (i) => stableFindingKey(i.type, i.file, i.name, i.package);
|
|
10414
10885
|
const prevKeys = new Set((prevKnip?.data?.issues ?? []).map(issueKey));
|
|
10415
|
-
const modifiedSet = new Set(files.map((f) => resolveRunnerPath(cwd, f)));
|
|
10886
|
+
const modifiedSet = new Set([...files, ...knipCarried.get(scanRoot) ?? []].map((f) => resolveRunnerPath(cwd, f)));
|
|
10416
10887
|
const newIssues = knipResult.issues.filter((issue) => {
|
|
10417
10888
|
if (prevKeys.has(issueKey(issue)))
|
|
10418
10889
|
return false;
|
|
@@ -10472,6 +10943,13 @@ ${suffix}`;
|
|
|
10472
10943
|
deliveryHolds.push(cutAdvisoryHold("knip", knipAdvisoryLane, report, unusedExportDelta.slice(0, KNIP_MAX_SHOWN), (issue) => reOfferedKeys.has(issueKey(issue))));
|
|
10473
10944
|
}
|
|
10474
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);
|
|
10475
10953
|
return knipMeta;
|
|
10476
10954
|
};
|
|
10477
10955
|
const logKnipRow = (root, startedAt, metadata) => logLatency({
|
|
@@ -10538,7 +11016,8 @@ ${suffix}`;
|
|
|
10538
11016
|
});
|
|
10539
11017
|
}
|
|
10540
11018
|
} else {
|
|
10541
|
-
|
|
11019
|
+
const joined = scanned.result.success && scanned.result.execution !== "cache" && joinedEarlierScan(scanned.result, startedAt);
|
|
11020
|
+
metadata = applyKnipResult(scanRoot, prevKnip, scanned.result, scanned.row, joined);
|
|
10542
11021
|
}
|
|
10543
11022
|
}
|
|
10544
11023
|
budgetSpent = metadata.execution === "deferred" && (metadata.scanFloorMs === void 0 || metadata.aborted === true);
|
|
@@ -10909,7 +11388,7 @@ ${suffix}`;
|
|
|
10909
11388
|
metadata: madgeStats ?? { skipped: true }
|
|
10910
11389
|
});
|
|
10911
11390
|
if (!getFlag("no-tests") && files.length > 0) {
|
|
10912
|
-
const
|
|
11391
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
10913
11392
|
const targets = [];
|
|
10914
11393
|
const testRootFor = createTurnEndTestRoots(cwd);
|
|
10915
11394
|
const candidates = [];
|
|
@@ -10976,7 +11455,7 @@ ${suffix}`;
|
|
|
10976
11455
|
foreignDeferred++;
|
|
10977
11456
|
continue;
|
|
10978
11457
|
}
|
|
10979
|
-
if (
|
|
11458
|
+
if (seen2.has(carriedKey)) {
|
|
10980
11459
|
resolvedDeferralKeys.add(carriedKey);
|
|
10981
11460
|
continue;
|
|
10982
11461
|
}
|
|
@@ -11020,7 +11499,7 @@ ${suffix}`;
|
|
|
11020
11499
|
continue;
|
|
11021
11500
|
}
|
|
11022
11501
|
resolvedDeferralKeys.add(carriedKey);
|
|
11023
|
-
|
|
11502
|
+
seen2.add(carriedKey);
|
|
11024
11503
|
redispatchedDeferred++;
|
|
11025
11504
|
targets.push({
|
|
11026
11505
|
testFile,
|
|
@@ -11071,8 +11550,8 @@ ${suffix}`;
|
|
|
11071
11550
|
candidatesByRoot.set(testRoot, (candidatesByRoot.get(testRoot) ?? 0) + 1);
|
|
11072
11551
|
const target = testRunnerClient.getTestRunTarget(abs, testRoot, runtime.turnIndex);
|
|
11073
11552
|
const targetKey = target ? normalizeMapKey(target.testFile) : "";
|
|
11074
|
-
if (target && !
|
|
11075
|
-
|
|
11553
|
+
if (target && !seen2.has(targetKey)) {
|
|
11554
|
+
seen2.add(targetKey);
|
|
11076
11555
|
if (retiredKeys.has(targetKey)) {
|
|
11077
11556
|
retiredSkips++;
|
|
11078
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)})`);
|
|
@@ -11473,8 +11952,8 @@ ${suffix}`;
|
|
|
11473
11952
|
} else {
|
|
11474
11953
|
const callGraphStart = Date.now();
|
|
11475
11954
|
try {
|
|
11476
|
-
const { impact, formatImpact, parseSymbolKey } = await import("../chunk-
|
|
11477
|
-
const { callGraphImpactToProjectDiagnostics } = await import("../chunk-
|
|
11955
|
+
const { impact, formatImpact, parseSymbolKey } = await import("../chunk-GMX5OS7B.js");
|
|
11956
|
+
const { callGraphImpactToProjectDiagnostics } = await import("../chunk-MZGQNL3Y.js");
|
|
11478
11957
|
const impactLines = [];
|
|
11479
11958
|
let callGraphDispositionSuppressed = 0;
|
|
11480
11959
|
const impactFindings = [];
|
|
@@ -11597,6 +12076,8 @@ ${impactLines.join("\n")}`;
|
|
|
11597
12076
|
modifiedRangesByFile,
|
|
11598
12077
|
dispatchWarnings: runtime.peekActionableWarnings(sessionId),
|
|
11599
12078
|
includeLspCodeActions: !!getFlag("lens-actionable-warning-actions"),
|
|
12079
|
+
// #4323: the cold LSP read leaves a switched-off Opengrep unstarted.
|
|
12080
|
+
getFlag,
|
|
11600
12081
|
projectSeqStart: runtime.turnStartProjectSeq,
|
|
11601
12082
|
projectSeqEnd: runtime.projectSeq,
|
|
11602
12083
|
// #3676: the quick fix credits its writes with this epoch.
|
|
@@ -11715,31 +12196,7 @@ ${impactLines.join("\n")}`;
|
|
|
11715
12196
|
}
|
|
11716
12197
|
const t5 = Date.now();
|
|
11717
12198
|
try {
|
|
11718
|
-
const
|
|
11719
|
-
for (const warning of runtime.peekCodeQualityWarnings(sessionId)) {
|
|
11720
|
-
const group = qualityWarningsByFile.get(warning.filePath);
|
|
11721
|
-
if (group)
|
|
11722
|
-
group.push(warning);
|
|
11723
|
-
else
|
|
11724
|
-
qualityWarningsByFile.set(warning.filePath, [warning]);
|
|
11725
|
-
}
|
|
11726
|
-
const qualityWarnings = [];
|
|
11727
|
-
let qualityDispositionSuppressed = 0;
|
|
11728
|
-
for (const [filePath, group] of qualityWarningsByFile) {
|
|
11729
|
-
let content;
|
|
11730
|
-
try {
|
|
11731
|
-
content = fs17.readFileSync(filePath, "utf-8");
|
|
11732
|
-
} catch {
|
|
11733
|
-
content = void 0;
|
|
11734
|
-
}
|
|
11735
|
-
const { kept, suppressed } = applyPushedFindingPolicy(group, {
|
|
11736
|
-
cwd,
|
|
11737
|
-
filePath,
|
|
11738
|
-
content
|
|
11739
|
-
});
|
|
11740
|
-
qualityWarnings.push(...kept);
|
|
11741
|
-
qualityDispositionSuppressed += suppressed;
|
|
11742
|
-
}
|
|
12199
|
+
const { kept: qualityWarnings, suppressed: qualityDispositionSuppressed } = applyPushedFindingPolicyByFile(runtime.peekCodeQualityWarnings(sessionId), cwd);
|
|
11743
12200
|
const qualityReport = buildCodeQualityWarningsReport({
|
|
11744
12201
|
cwd,
|
|
11745
12202
|
sessionId: runtime.telemetrySessionId,
|
|
@@ -12467,7 +12924,7 @@ var TurnEndQueue = class {
|
|
|
12467
12924
|
}
|
|
12468
12925
|
};
|
|
12469
12926
|
var turnEndQueue = new TurnEndQueue();
|
|
12470
|
-
var pendingTurnEndDeliveries =
|
|
12927
|
+
var pendingTurnEndDeliveries = new BoundedFifoMap(TURN_END_DELIVERY_MAX);
|
|
12471
12928
|
var inFlightIpcTurnEnds = /* @__PURE__ */ new Map();
|
|
12472
12929
|
async function runTurnEndNowImpl(cwd, files = [], deferredDelivery = false) {
|
|
12473
12930
|
const ctx = await getMcpSessionContext();
|
|
@@ -12545,12 +13002,6 @@ function prunePendingTurnEndDeliveries(now = Date.now()) {
|
|
|
12545
13002
|
pendingTurnEndDeliveries.delete(deliveryId);
|
|
12546
13003
|
}
|
|
12547
13004
|
}
|
|
12548
|
-
while (pendingTurnEndDeliveries.size > TURN_END_DELIVERY_MAX) {
|
|
12549
|
-
const oldest = pendingTurnEndDeliveries.keys().next();
|
|
12550
|
-
if (oldest.done)
|
|
12551
|
-
break;
|
|
12552
|
-
pendingTurnEndDeliveries.delete(oldest.value);
|
|
12553
|
-
}
|
|
12554
13005
|
}
|
|
12555
13006
|
function pendingForCwd(cwd) {
|
|
12556
13007
|
for (const [deliveryId, delivery] of pendingTurnEndDeliveries) {
|
|
@@ -13167,7 +13618,7 @@ function blastReadArgs(graph, normalizedFile) {
|
|
|
13167
13618
|
return { path: normalizedFile, offset: 1, limit };
|
|
13168
13619
|
}
|
|
13169
13620
|
async function computeBlastRadius(graph, normalizedPath, projectRoot, maxDepth) {
|
|
13170
|
-
const { computeTransitiveImpact } = await import("../chunk-
|
|
13621
|
+
const { computeTransitiveImpact } = await import("../chunk-XTFDJI3T.js");
|
|
13171
13622
|
const result = computeTransitiveImpact(graph, normalizedPath, { maxDepth });
|
|
13172
13623
|
const byFile = /* @__PURE__ */ new Map();
|
|
13173
13624
|
for (const hit of result.hits) {
|
|
@@ -13784,7 +14235,7 @@ async function moduleReport(file, cwd, options) {
|
|
|
13784
14235
|
let callGraphIdentity;
|
|
13785
14236
|
let revisionDriftNote;
|
|
13786
14237
|
try {
|
|
13787
|
-
const { getCachedReviewGraph, getReviewGraphCacheIdentity, getReviewGraphSizeSkipVerdict, getReviewGraphRevisionDrift, formatReviewGraphRevisionDriftNote: formatReviewGraphRevisionDriftNote2 } = await import("../chunk-
|
|
14238
|
+
const { getCachedReviewGraph, getReviewGraphCacheIdentity, getReviewGraphSizeSkipVerdict, getReviewGraphRevisionDrift, formatReviewGraphRevisionDriftNote: formatReviewGraphRevisionDriftNote2 } = await import("../chunk-YCWYO6TQ.js");
|
|
13788
14239
|
graph = getCachedReviewGraph(cwd);
|
|
13789
14240
|
graphFileCap = getReviewGraphSizeSkipVerdict(cwd)?.maxFileCount;
|
|
13790
14241
|
const drift = graph ? getReviewGraphRevisionDrift(cwd) : void 0;
|
|
@@ -14568,7 +15019,7 @@ function roleFor(graph, filePath) {
|
|
|
14568
15019
|
return top.length > 0 ? top.map((s) => s.name).join(", ") : void 0;
|
|
14569
15020
|
}
|
|
14570
15021
|
async function computeHubs(graph, degrees, cwd, limit, focusTerms) {
|
|
14571
|
-
const { computeTransitiveImpact } = await import("../chunk-
|
|
15022
|
+
const { computeTransitiveImpact } = await import("../chunk-XTFDJI3T.js");
|
|
14572
15023
|
const ranked = [...graph.fileNodes.entries()].map(([filePath, fileNodeId]) => ({
|
|
14573
15024
|
filePath,
|
|
14574
15025
|
fileNodeId,
|
|
@@ -14820,7 +15271,7 @@ async function projectReport(cwd, options) {
|
|
|
14820
15271
|
const limit = clampLimit(options?.limit);
|
|
14821
15272
|
const focusTerms = normalizeFocus2(options?.focus);
|
|
14822
15273
|
const view = options?.view;
|
|
14823
|
-
const { getCachedReviewGraph, getReviewGraphSizeSkipVerdict, getLastReviewGraphBuildAttempt, buildOrUpdateGraph, isGraphBuildInFlight, getReviewGraphRevisionDrift } = await import("../chunk-
|
|
15274
|
+
const { getCachedReviewGraph, getReviewGraphSizeSkipVerdict, getLastReviewGraphBuildAttempt, buildOrUpdateGraph, isGraphBuildInFlight, getReviewGraphRevisionDrift } = await import("../chunk-YCWYO6TQ.js");
|
|
14824
15275
|
let graph;
|
|
14825
15276
|
try {
|
|
14826
15277
|
graph = getCachedReviewGraph(cwd);
|
|
@@ -14844,7 +15295,7 @@ async function projectReport(cwd, options) {
|
|
|
14844
15295
|
};
|
|
14845
15296
|
}
|
|
14846
15297
|
const previousAttempt = getLastReviewGraphBuildAttempt(cwd);
|
|
14847
|
-
const { FactStore: FactStore2 } = await import("../chunk-
|
|
15298
|
+
const { FactStore: FactStore2 } = await import("../chunk-UMS2MFPZ.js");
|
|
14848
15299
|
const trigger = triggerBackgroundGraphBuild(cwd, {
|
|
14849
15300
|
buildOrUpdateGraph,
|
|
14850
15301
|
isGraphBuildInFlight,
|
|
@@ -14945,7 +15396,7 @@ function renderCompactProjectReport(report) {
|
|
|
14945
15396
|
}
|
|
14946
15397
|
|
|
14947
15398
|
// dist/clients/effective-config.js
|
|
14948
|
-
import * as
|
|
15399
|
+
import * as os2 from "node:os";
|
|
14949
15400
|
import * as path28 from "node:path";
|
|
14950
15401
|
function isEffectiveFileViewError(file) {
|
|
14951
15402
|
return "error" in file;
|
|
@@ -15011,7 +15462,7 @@ function decidedByOrNothing(entry) {
|
|
|
15011
15462
|
}
|
|
15012
15463
|
async function effectiveConfig(options = {}) {
|
|
15013
15464
|
const cwd = options.cwd ?? process.cwd();
|
|
15014
|
-
const homeDir = options.homeDir ??
|
|
15465
|
+
const homeDir = options.homeDir ?? os2.homedir();
|
|
15015
15466
|
const resolveAt = (dir) => resolvePiLensConfig({
|
|
15016
15467
|
cwd: dir,
|
|
15017
15468
|
globalDir: getGlobalPiLensDir(),
|
|
@@ -15125,13 +15576,19 @@ function recentLatency(limit = 5, fileFilter) {
|
|
|
15125
15576
|
}
|
|
15126
15577
|
return reports.slice(-limit).reverse();
|
|
15127
15578
|
}
|
|
15128
|
-
function projectScan(cwd, maxFiles, includeGenerated) {
|
|
15129
|
-
|
|
15579
|
+
async function projectScan(cwd, maxFiles, includeGenerated) {
|
|
15580
|
+
const scan = await scanProjectDiagnostics({
|
|
15130
15581
|
cwd,
|
|
15131
15582
|
tier: "cheap",
|
|
15132
15583
|
maxFiles,
|
|
15133
15584
|
includeGenerated
|
|
15134
15585
|
});
|
|
15586
|
+
const policy = applyPushedFindingPolicyByFile(scan.diagnostics, cwd);
|
|
15587
|
+
return {
|
|
15588
|
+
...scan,
|
|
15589
|
+
diagnostics: policy.kept,
|
|
15590
|
+
dispositionSuppressed: policy.suppressed
|
|
15591
|
+
};
|
|
15135
15592
|
}
|
|
15136
15593
|
function scanTruncationNotice(snapshot) {
|
|
15137
15594
|
if (!snapshot.scanTruncated)
|
|
@@ -15263,7 +15720,7 @@ async function symbolSearch(query, cwd, limit = 20, options = {}) {
|
|
|
15263
15720
|
warmLease.release();
|
|
15264
15721
|
}
|
|
15265
15722
|
const hits = results.map(toSymbolSearchHit);
|
|
15266
|
-
const { getCachedReviewGraph } = await import("../chunk-
|
|
15723
|
+
const { getCachedReviewGraph } = await import("../chunk-YCWYO6TQ.js");
|
|
15267
15724
|
const graph = getCachedReviewGraph(cwd);
|
|
15268
15725
|
if (graph)
|
|
15269
15726
|
annotateSymbolSearchHitsWithGraph(hits, centrality, graph);
|
|
@@ -15460,10 +15917,12 @@ function canonicalLanguage(lang) {
|
|
|
15460
15917
|
}
|
|
15461
15918
|
|
|
15462
15919
|
// dist/tools/shared.js
|
|
15920
|
+
import * as path31 from "node:path";
|
|
15463
15921
|
function resolveAstGrepPaths(paths, cwd) {
|
|
15464
15922
|
const base = cwd || ".";
|
|
15465
|
-
|
|
15466
|
-
|
|
15923
|
+
if (!paths?.length)
|
|
15924
|
+
return [path31.resolve(base)];
|
|
15925
|
+
return paths.map((p) => resolveHostToolPath(p, base));
|
|
15467
15926
|
}
|
|
15468
15927
|
var LANGUAGES = [
|
|
15469
15928
|
"bash",
|
|
@@ -16413,7 +16872,7 @@ ${hint}` : `${output}${paginationNote}`;
|
|
|
16413
16872
|
// dist/tools/lens-diagnostics.js
|
|
16414
16873
|
import { promises as fs23 } from "node:fs";
|
|
16415
16874
|
import * as fsSync from "node:fs";
|
|
16416
|
-
import * as
|
|
16875
|
+
import * as path38 from "node:path";
|
|
16417
16876
|
|
|
16418
16877
|
// dist/clients/project-diagnostics/extractors.js
|
|
16419
16878
|
var WARM_TRIGGER = {
|
|
@@ -16472,13 +16931,13 @@ function reasonFromAvailabilityVerdict(tool, verdict) {
|
|
|
16472
16931
|
|
|
16473
16932
|
// dist/clients/project-diagnostics/fresh-fetch.js
|
|
16474
16933
|
import * as fs21 from "node:fs";
|
|
16475
|
-
import * as
|
|
16476
|
-
import * as
|
|
16934
|
+
import * as os3 from "node:os";
|
|
16935
|
+
import * as path36 from "node:path";
|
|
16477
16936
|
|
|
16478
16937
|
// dist/clients/project-diagnostics/runner-adapters/jscpd.js
|
|
16479
|
-
import * as
|
|
16938
|
+
import * as path32 from "node:path";
|
|
16480
16939
|
function resolveClonePath(cwd, file) {
|
|
16481
|
-
return
|
|
16940
|
+
return path32.isAbsolute(file) ? file : path32.resolve(cwd, file);
|
|
16482
16941
|
}
|
|
16483
16942
|
function jscpdCloneToProjectDiagnostics(cwd, clone) {
|
|
16484
16943
|
const a = resolveClonePath(cwd, clone.fileA);
|
|
@@ -16491,7 +16950,7 @@ function jscpdCloneToProjectDiagnostics(cwd, clone) {
|
|
|
16491
16950
|
tool: "jscpd",
|
|
16492
16951
|
runner: "jscpd",
|
|
16493
16952
|
rule: "jscpd:duplicate",
|
|
16494
|
-
message: `Duplicate code (${clone.lines} lines) \u2014 also at ${
|
|
16953
|
+
message: `Duplicate code (${clone.lines} lines) \u2014 also at ${path32.relative(cwd, otherFile)}:${otherLine}`,
|
|
16495
16954
|
source: "project-scan"
|
|
16496
16955
|
});
|
|
16497
16956
|
return [
|
|
@@ -16506,16 +16965,16 @@ function jscpdResultToProjectDiagnostics(cwd, result) {
|
|
|
16506
16965
|
}
|
|
16507
16966
|
|
|
16508
16967
|
// dist/clients/project-diagnostics/runner-adapters/madge.js
|
|
16509
|
-
import * as
|
|
16968
|
+
import * as path33 from "node:path";
|
|
16510
16969
|
function resolveCyclePath(cwd, file) {
|
|
16511
|
-
return
|
|
16970
|
+
return path33.isAbsolute(file) ? file : path33.resolve(cwd, file);
|
|
16512
16971
|
}
|
|
16513
16972
|
function cycleMembers(dep) {
|
|
16514
16973
|
return dep.path.length > 0 ? dep.path : [dep.file];
|
|
16515
16974
|
}
|
|
16516
16975
|
function circularDepToProjectDiagnostics(cwd, dep) {
|
|
16517
16976
|
const members = cycleMembers(dep);
|
|
16518
|
-
const rendered = `${members.map((f) =>
|
|
16977
|
+
const rendered = `${members.map((f) => path33.basename(f)).join(" \u2192 ")} \u2192 ${path33.basename(members[0] ?? "")}`;
|
|
16519
16978
|
return members.map((file) => ({
|
|
16520
16979
|
filePath: resolveCyclePath(cwd, file),
|
|
16521
16980
|
severity: "warning",
|
|
@@ -16541,7 +17000,7 @@ function circularDepsToProjectDiagnostics(cwd, circular) {
|
|
|
16541
17000
|
}
|
|
16542
17001
|
|
|
16543
17002
|
// dist/clients/project-diagnostics/runner-adapters/opengrep.js
|
|
16544
|
-
import * as
|
|
17003
|
+
import * as path34 from "node:path";
|
|
16545
17004
|
function severityFor(raw) {
|
|
16546
17005
|
switch (raw.toUpperCase()) {
|
|
16547
17006
|
case "ERROR":
|
|
@@ -16556,7 +17015,7 @@ function opengrepFindingToProjectDiagnostic(cwd, finding) {
|
|
|
16556
17015
|
const { severity, blocking } = severityFor(finding.severity);
|
|
16557
17016
|
const cweSuffix = finding.cwe?.length ? ` (${finding.cwe[0]})` : "";
|
|
16558
17017
|
return {
|
|
16559
|
-
filePath:
|
|
17018
|
+
filePath: path34.isAbsolute(finding.path) ? finding.path : path34.resolve(cwd, finding.path),
|
|
16560
17019
|
line: finding.startLine,
|
|
16561
17020
|
column: finding.startCol,
|
|
16562
17021
|
severity,
|
|
@@ -16576,7 +17035,7 @@ function opengrepResultToProjectDiagnostics(cwd, result) {
|
|
|
16576
17035
|
|
|
16577
17036
|
// dist/clients/project-diagnostics/runner-adapters/runner-findings.js
|
|
16578
17037
|
import * as fs20 from "node:fs";
|
|
16579
|
-
import * as
|
|
17038
|
+
import * as path35 from "node:path";
|
|
16580
17039
|
function failureMessage(failure) {
|
|
16581
17040
|
const firstLine2 = failure.message.split("\n")[0]?.slice(0, 300) ?? "";
|
|
16582
17041
|
return firstLine2 ? `${failure.name}: ${firstLine2}` : failure.name;
|
|
@@ -16642,7 +17101,7 @@ function testRunnerFindingsToProjectDiagnostics(cache, cwd, runtime) {
|
|
|
16642
17101
|
return [];
|
|
16643
17102
|
const validation = cwd ? validateAdvisoryProvenance(cache, cwd, runtime) : { status: "unknown", reasons: ["validation-context-missing"] };
|
|
16644
17103
|
const root = cwd ?? process.cwd();
|
|
16645
|
-
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)));
|
|
16646
17105
|
const historical = cache.superseded === true || cache.stale === true || validation.status !== "current";
|
|
16647
17106
|
return cache.results.filter((result) => !missingKeys.has(advisoryPathKey(result.file, root))).flatMap((result) => testResultToProjectDiagnostics(result, historical)).map((diagnostic) => historical ? {
|
|
16648
17107
|
...diagnostic,
|
|
@@ -16672,7 +17131,7 @@ function laneObservedAtMs(scannedAt, startedAtMs) {
|
|
|
16672
17131
|
return parseScannedAtMs(scannedAt) ?? startedAtMs;
|
|
16673
17132
|
}
|
|
16674
17133
|
async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal, options = {}) {
|
|
16675
|
-
const requestedRoot = options.analysisRoot === void 0 ? cwd :
|
|
17134
|
+
const requestedRoot = options.analysisRoot === void 0 ? cwd : path36.resolve(cwd, options.analysisRoot);
|
|
16676
17135
|
let analysisRoot;
|
|
16677
17136
|
let analysisRootValidation;
|
|
16678
17137
|
if (options.analysisRoot !== void 0) {
|
|
@@ -16711,7 +17170,7 @@ async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal,
|
|
|
16711
17170
|
analysisRoot = realpathOrResolve(cwd);
|
|
16712
17171
|
}
|
|
16713
17172
|
const unsafeRootReason = "the analysis root resolves at or above the home directory; heavyweight analyzers refuse to walk from there (#747)";
|
|
16714
|
-
const homeRoot = realpathOrResolve(options.homeDir ??
|
|
17173
|
+
const homeRoot = realpathOrResolve(options.homeDir ?? os3.homedir());
|
|
16715
17174
|
if (options.analysisRoot !== void 0) {
|
|
16716
17175
|
const unsafeExplicitRoot = !isSameOrWithin(homeRoot, analysisRoot) || isSameOrWithin(analysisRoot, homeRoot);
|
|
16717
17176
|
analysisRootValidation = unsafeExplicitRoot ? {
|
|
@@ -16839,7 +17298,7 @@ async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal,
|
|
|
16839
17298
|
markCold("jscpd", reasonFromAvailabilityVerdict("jscpd", clients.jscpdClient.getAvailabilityVerdict?.()));
|
|
16840
17299
|
return;
|
|
16841
17300
|
}
|
|
16842
|
-
const isTsProject = fs21.existsSync(
|
|
17301
|
+
const isTsProject = fs21.existsSync(path36.join(analysisRoot, "tsconfig.json"));
|
|
16843
17302
|
const scannerKey = isTsProject ? "jscpd-ts" : "jscpd";
|
|
16844
17303
|
const startMs = Date.now();
|
|
16845
17304
|
const result = await clients.jscpdClient.scan(analysisRoot, void 0, void 0, isTsProject);
|
|
@@ -17156,7 +17615,7 @@ function makeProgressReporter(onUpdate, label, throttleMs = 250) {
|
|
|
17156
17615
|
|
|
17157
17616
|
// dist/tools/lsp-diagnostics.js
|
|
17158
17617
|
import * as fs22 from "node:fs";
|
|
17159
|
-
import * as
|
|
17618
|
+
import * as path37 from "node:path";
|
|
17160
17619
|
var MAX_FILES = 100;
|
|
17161
17620
|
var MAX_BATCH_FILES = 100;
|
|
17162
17621
|
var MAX_DIAGNOSTICS = 200;
|
|
@@ -17239,11 +17698,11 @@ async function collectFiles(dir, extensions, maxFiles, isIgnored = () => false)
|
|
|
17239
17698
|
return;
|
|
17240
17699
|
if (entry.isSymbolicLink())
|
|
17241
17700
|
continue;
|
|
17242
|
-
const full =
|
|
17701
|
+
const full = path37.join(current, entry.name);
|
|
17243
17702
|
if (entry.isDirectory()) {
|
|
17244
17703
|
if (!isExcludedDirName(entry.name) && !isIgnored(full, true))
|
|
17245
17704
|
await walk(full);
|
|
17246
|
-
} else if (entry.isFile() && extensions.includes(
|
|
17705
|
+
} else if (entry.isFile() && extensions.includes(path37.extname(full))) {
|
|
17247
17706
|
if (isIgnored(full, false))
|
|
17248
17707
|
continue;
|
|
17249
17708
|
files.push(full);
|
|
@@ -17253,7 +17712,7 @@ async function collectFiles(dir, extensions, maxFiles, isIgnored = () => false)
|
|
|
17253
17712
|
await walk(dir);
|
|
17254
17713
|
return files;
|
|
17255
17714
|
}
|
|
17256
|
-
function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getService = getLSPService) {
|
|
17715
|
+
function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getService = getLSPService, getFlag) {
|
|
17257
17716
|
return {
|
|
17258
17717
|
async execute(_toolCallId, params, _signal, onUpdate, ctx) {
|
|
17259
17718
|
const signal = combineAbortSignals(_signal, ctx.signal);
|
|
@@ -17264,6 +17723,7 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17264
17723
|
const concurrency = boundedPositiveInt(typedParams.concurrency, DEFAULT_BATCH_CONCURRENCY, 1, MAX_BATCH_CONCURRENCY);
|
|
17265
17724
|
const waitMs = typeof typedParams.waitMs === "number" && typedParams.waitMs >= 0 ? Math.floor(typedParams.waitMs) : void 0;
|
|
17266
17725
|
const serverScope = typedParams.serverScope === "primary" ? "primary" : "all";
|
|
17726
|
+
const excludeServerIds = getFlag ? configDisabledAuxiliaryLspServerIds((name) => getFlag(name, cwd)) : void 0;
|
|
17267
17727
|
const lspService = getService();
|
|
17268
17728
|
if (!lspService) {
|
|
17269
17729
|
return {
|
|
@@ -17321,7 +17781,8 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17321
17781
|
nextWriteIndex,
|
|
17322
17782
|
serverScope,
|
|
17323
17783
|
cwd,
|
|
17324
|
-
onConfirmedNoBlockers
|
|
17784
|
+
onConfirmedNoBlockers,
|
|
17785
|
+
excludeServerIds
|
|
17325
17786
|
}, expanded);
|
|
17326
17787
|
}
|
|
17327
17788
|
const rawPath = typedParams.path;
|
|
@@ -17337,7 +17798,7 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17337
17798
|
details: {}
|
|
17338
17799
|
};
|
|
17339
17800
|
}
|
|
17340
|
-
const absPath = normalizeMapKey(
|
|
17801
|
+
const absPath = normalizeMapKey(typedParams.pathAlreadyResolved === true ? rawPath : resolveHostToolPath(rawPath, cwd));
|
|
17341
17802
|
let stat;
|
|
17342
17803
|
try {
|
|
17343
17804
|
stat = fs22.statSync(absPath);
|
|
@@ -17359,14 +17820,15 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17359
17820
|
nextWriteIndex,
|
|
17360
17821
|
serverScope,
|
|
17361
17822
|
cwd,
|
|
17362
|
-
onConfirmedNoBlockers
|
|
17823
|
+
onConfirmedNoBlockers,
|
|
17824
|
+
excludeServerIds
|
|
17363
17825
|
});
|
|
17364
17826
|
}
|
|
17365
|
-
return runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope, cwd, onConfirmedNoBlockers);
|
|
17827
|
+
return runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope, cwd, onConfirmedNoBlockers, excludeServerIds);
|
|
17366
17828
|
}
|
|
17367
17829
|
};
|
|
17368
17830
|
}
|
|
17369
|
-
async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs, serverScope = "all") {
|
|
17831
|
+
async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs, serverScope = "all", excludeServerIds) {
|
|
17370
17832
|
let timedOut = false;
|
|
17371
17833
|
let content;
|
|
17372
17834
|
let touched;
|
|
@@ -17431,6 +17893,7 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17431
17893
|
maxClientWaitMs: waitMs,
|
|
17432
17894
|
source: "lsp_diagnostics",
|
|
17433
17895
|
clientScope: serverScope,
|
|
17896
|
+
excludeServerIds,
|
|
17434
17897
|
// #3405: the caller asked whether THIS file is clean right now, and the
|
|
17435
17898
|
// content above was just read from disk — so it is the file's saved
|
|
17436
17899
|
// state. Without the save a save-triggered server answers zero
|
|
@@ -17438,10 +17901,11 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17438
17901
|
// as clean.
|
|
17439
17902
|
saved: true
|
|
17440
17903
|
});
|
|
17441
|
-
timedOut = touched?.inconclusive === true;
|
|
17904
|
+
timedOut = touched?.inconclusive === true && touched.inconclusiveReason !== "primary-unavailable";
|
|
17442
17905
|
} catch {
|
|
17443
17906
|
}
|
|
17444
|
-
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;
|
|
17445
17909
|
const filtered = content !== void 0 ? applyAuxiliarySuppressions(diagnostics, content, {
|
|
17446
17910
|
fileRole: detectFileRole(absPath, content),
|
|
17447
17911
|
filePath: absPath,
|
|
@@ -17449,11 +17913,18 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17449
17913
|
}) : diagnostics;
|
|
17450
17914
|
const binding = touched?.binding;
|
|
17451
17915
|
const confirmedByTouch = touchCompletedConfirmationPolicy(touched);
|
|
17916
|
+
const primaryUnavailable = describePrimaryUnavailable(touched, fallbackHealth);
|
|
17917
|
+
const noClientAnswered = fallbackHealth !== void 0 && String(fallbackHealth.health ?? "").startsWith("no_clients");
|
|
17452
17918
|
return {
|
|
17453
17919
|
diagnostics: filtered,
|
|
17454
17920
|
timedOut,
|
|
17455
17921
|
skipReason: touched?.skipReason,
|
|
17456
17922
|
confirmedByTouch,
|
|
17923
|
+
...noClientAnswered && { noClientAnswered: true },
|
|
17924
|
+
...primaryUnavailable !== void 0 && {
|
|
17925
|
+
primaryUnavailable: primaryUnavailable.text,
|
|
17926
|
+
primaryUnavailableCause: primaryUnavailable.cause
|
|
17927
|
+
},
|
|
17457
17928
|
// #1470: only a touch that resolved clients contributes a coverage gap;
|
|
17458
17929
|
// the getDiagnostics fallback never reports one, which is honest — that
|
|
17459
17930
|
// path claims no confirmation at all.
|
|
@@ -17463,6 +17934,27 @@ async function collectDiagnosticsForFile(absPath, lspService, scanRoot, waitMs,
|
|
|
17463
17934
|
binding
|
|
17464
17935
|
};
|
|
17465
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
|
+
}
|
|
17466
17958
|
function diagnosticsToFileDiags(file, diagnostics) {
|
|
17467
17959
|
return diagnostics.map((d) => ({
|
|
17468
17960
|
file,
|
|
@@ -17508,7 +18000,7 @@ async function resolveEmptyResult(file, lspService) {
|
|
|
17508
18000
|
function canTrustTouchConfirmation(file, serverScope, confirmedByTouch) {
|
|
17509
18001
|
return confirmedByTouch && (serverScope === "primary" || primaryServerId(file) !== "typescript");
|
|
17510
18002
|
}
|
|
17511
|
-
function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds) {
|
|
18003
|
+
function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds, excludeServerIds) {
|
|
17512
18004
|
const unconfirmed = new Set(unconfirmedServerIds);
|
|
17513
18005
|
const covered = /* @__PURE__ */ new Set();
|
|
17514
18006
|
let servers = [];
|
|
@@ -17523,6 +18015,8 @@ function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds) {
|
|
|
17523
18015
|
continue;
|
|
17524
18016
|
if (unconfirmed.has(server.id))
|
|
17525
18017
|
continue;
|
|
18018
|
+
if (excludeServerIds?.has(server.id))
|
|
18019
|
+
continue;
|
|
17526
18020
|
covered.add(auxiliary ? server.id : "lsp");
|
|
17527
18021
|
}
|
|
17528
18022
|
return [...covered];
|
|
@@ -17534,7 +18028,7 @@ function demoteInferredForFile(file, diagnostics, cwd, lspService) {
|
|
|
17534
18028
|
service: lspService
|
|
17535
18029
|
});
|
|
17536
18030
|
}
|
|
17537
|
-
function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity) {
|
|
18031
|
+
function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity, toolName = "lsp_diagnostics") {
|
|
17538
18032
|
const started = Date.now();
|
|
17539
18033
|
try {
|
|
17540
18034
|
const result = applyLspFindingPolicy(diagnostics, {
|
|
@@ -17549,7 +18043,7 @@ function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity) {
|
|
|
17549
18043
|
if (suppressed > 0) {
|
|
17550
18044
|
logLatency({
|
|
17551
18045
|
type: "phase",
|
|
17552
|
-
toolName
|
|
18046
|
+
toolName,
|
|
17553
18047
|
filePath: file,
|
|
17554
18048
|
phase: "lsp_probe_disposition_filter",
|
|
17555
18049
|
durationMs: Date.now() - started,
|
|
@@ -17571,15 +18065,11 @@ function applyProbeFindingPolicy(file, diagnostics, cwd, content, severity) {
|
|
|
17571
18065
|
}
|
|
17572
18066
|
}
|
|
17573
18067
|
function replayContentForStrictMarks(file, cwd) {
|
|
17574
|
-
|
|
17575
|
-
return void 0;
|
|
17576
|
-
try {
|
|
17577
|
-
return fs22.readFileSync(file, "utf-8");
|
|
17578
|
-
} catch {
|
|
17579
|
-
return void 0;
|
|
17580
|
-
}
|
|
18068
|
+
return hasStrictDispositionMarks(cwd) ? readFileContent(file) : void 0;
|
|
17581
18069
|
}
|
|
17582
|
-
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 };
|
|
17583
18073
|
const confirmed = (rawDiags.length > 0 || confirmation !== "unconfirmed") && !boundMismatch;
|
|
17584
18074
|
if (!confirmed)
|
|
17585
18075
|
return { confirmed: false, blocking: true };
|
|
@@ -17596,7 +18086,7 @@ function reconcileWidgetFromLspResult(file, rawDiags, confirmation, writeIndex,
|
|
|
17596
18086
|
return { confirmed: false, blocking: true };
|
|
17597
18087
|
}
|
|
17598
18088
|
}
|
|
17599
|
-
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) {
|
|
17600
18090
|
const writeIndex = nextWriteIndex?.();
|
|
17601
18091
|
const scannedAt = Date.now();
|
|
17602
18092
|
let stat;
|
|
@@ -17640,7 +18130,7 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17640
18130
|
};
|
|
17641
18131
|
}
|
|
17642
18132
|
}
|
|
17643
|
-
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);
|
|
17644
18134
|
if (tooLargeReason !== void 0) {
|
|
17645
18135
|
return { file, diagnostics: [], outcome: "too_large", tooLargeReason };
|
|
17646
18136
|
}
|
|
@@ -17649,7 +18139,7 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17649
18139
|
let confirmation;
|
|
17650
18140
|
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
17651
18141
|
confirmation = void 0;
|
|
17652
|
-
} else if (skipReason !== void 0) {
|
|
18142
|
+
} else if (skipReason !== void 0 || primaryUnavailable !== void 0) {
|
|
17653
18143
|
confirmation = "unconfirmed";
|
|
17654
18144
|
} else if (timedOut) {
|
|
17655
18145
|
if (applySeverityFilter(rawDiags, severity).length === 0) {
|
|
@@ -17689,13 +18179,14 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17689
18179
|
boundMismatch,
|
|
17690
18180
|
// #3505 r1 F1: the widget row is observed at the read, as the cache
|
|
17691
18181
|
// entry recorded below is.
|
|
17692
|
-
scannedAt
|
|
18182
|
+
scannedAt,
|
|
18183
|
+
primaryUnavailable !== void 0
|
|
17693
18184
|
);
|
|
17694
18185
|
if (verdict.confirmed && !verdict.blocking) {
|
|
17695
18186
|
onConfirmedNoBlockers?.({
|
|
17696
18187
|
filePath: file,
|
|
17697
18188
|
writeIndex,
|
|
17698
|
-
coveredSources: coveredSourcesForCheck(file, serverScope, unconfirmedServerIds),
|
|
18189
|
+
coveredSources: coveredSourcesForCheck(file, serverScope, unconfirmedServerIds, excludeServerIds),
|
|
17699
18190
|
cwd
|
|
17700
18191
|
});
|
|
17701
18192
|
}
|
|
@@ -17710,6 +18201,11 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17710
18201
|
timedOut: confirmation === "unconfirmed" ? timedOut : void 0,
|
|
17711
18202
|
...rootFallback && { rootFallback },
|
|
17712
18203
|
...skipReason !== void 0 && { skipReason },
|
|
18204
|
+
...primaryUnavailable !== void 0 && {
|
|
18205
|
+
primaryUnavailable,
|
|
18206
|
+
primaryUnavailableCause: primaryUnavailableCause2
|
|
18207
|
+
},
|
|
18208
|
+
...noClientAnswered && { noClientAnswered },
|
|
17713
18209
|
primaryServerId: primaryServerId(file),
|
|
17714
18210
|
diagnosticsUnsupported: diagnosticsUnsupportedServerIds.length > 0,
|
|
17715
18211
|
...policy.suppressed > 0 && {
|
|
@@ -17717,10 +18213,14 @@ async function collectFileDiagnosticResult(file, severity, lspService, waitMs, n
|
|
|
17717
18213
|
}
|
|
17718
18214
|
};
|
|
17719
18215
|
}
|
|
17720
|
-
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) {
|
|
17721
18217
|
const writeIndex = nextWriteIndex?.();
|
|
18218
|
+
lspService.announceCreatedFiles([
|
|
18219
|
+
...goPackageFilesToAnnounce([absPath]),
|
|
18220
|
+
...await importTargetsToAnnounce(cwd, [absPath])
|
|
18221
|
+
]);
|
|
17722
18222
|
const observedAt = Date.now();
|
|
17723
|
-
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);
|
|
17724
18224
|
if (tooLargeReason !== void 0) {
|
|
17725
18225
|
return {
|
|
17726
18226
|
content: [{ type: "text", text: tooLargeReason }],
|
|
@@ -17742,7 +18242,7 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17742
18242
|
let confirmation;
|
|
17743
18243
|
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
17744
18244
|
confirmation = void 0;
|
|
17745
|
-
} else if (skipReason !== void 0) {
|
|
18245
|
+
} else if (skipReason !== void 0 || primaryUnavailable !== void 0) {
|
|
17746
18246
|
confirmation = "unconfirmed";
|
|
17747
18247
|
} else if (timedOut) {
|
|
17748
18248
|
if (applySeverityFilter(rawDiags, severity).length === 0) {
|
|
@@ -17776,12 +18276,12 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17776
18276
|
const truncated = total > MAX_DIAGNOSTICS;
|
|
17777
18277
|
const limited = truncated ? filtered.slice(0, MAX_DIAGNOSTICS) : filtered;
|
|
17778
18278
|
const unconfirmed = confirmation === "unconfirmed";
|
|
17779
|
-
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);
|
|
17780
18280
|
if (verdict.confirmed && !verdict.blocking) {
|
|
17781
18281
|
onConfirmedNoBlockers?.({
|
|
17782
18282
|
filePath: absPath,
|
|
17783
18283
|
writeIndex,
|
|
17784
|
-
coveredSources: coveredSourcesForCheck(absPath, serverScope, unconfirmedServerIds),
|
|
18284
|
+
coveredSources: coveredSourcesForCheck(absPath, serverScope, unconfirmedServerIds, excludeServerIds),
|
|
17785
18285
|
cwd
|
|
17786
18286
|
});
|
|
17787
18287
|
}
|
|
@@ -17789,6 +18289,8 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17789
18289
|
const primaryDiags = limited.filter((d) => d.serverId === primaryId);
|
|
17790
18290
|
const auxiliaryDiags = limited.filter((d) => d.serverId !== primaryId);
|
|
17791
18291
|
const primaryLine = (() => {
|
|
18292
|
+
if (primaryUnavailable !== void 0)
|
|
18293
|
+
return primaryUnavailable;
|
|
17792
18294
|
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
17793
18295
|
return `Primary LSP${primaryId ? ` (${primaryId})` : ""}: navigation-only \u2014 diagnostics unsupported (no pull provider or publish evidence).`;
|
|
17794
18296
|
}
|
|
@@ -17808,12 +18310,14 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17808
18310
|
})();
|
|
17809
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;
|
|
17810
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.";
|
|
17811
18315
|
let text;
|
|
17812
18316
|
if (total === 0) {
|
|
17813
18317
|
text = [
|
|
17814
18318
|
primaryLine,
|
|
17815
18319
|
"",
|
|
17816
|
-
unavailable ??
|
|
18320
|
+
unavailable ?? noAuxiliaryLine,
|
|
17817
18321
|
...coverageLine ? [coverageLine] : [],
|
|
17818
18322
|
...suppressedLine ? [suppressedLine] : []
|
|
17819
18323
|
].join("\n");
|
|
@@ -17865,6 +18369,7 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
17865
18369
|
timedOut: unconfirmed ? timedOut : void 0,
|
|
17866
18370
|
navigationOnlyFiles: diagnosticsUnsupportedServerIds.length > 0 ? 1 : void 0,
|
|
17867
18371
|
...skipReason !== void 0 && { skipReason },
|
|
18372
|
+
...primaryUnavailable !== void 0 && { primaryUnavailable },
|
|
17868
18373
|
...rootFallback && {
|
|
17869
18374
|
rootFallbackReason: describeRootFallback(rootFallback)
|
|
17870
18375
|
},
|
|
@@ -17882,6 +18387,8 @@ function tallyConfirmation(results) {
|
|
|
17882
18387
|
let clean = 0;
|
|
17883
18388
|
let unconfirmed = 0;
|
|
17884
18389
|
let timedOut = 0;
|
|
18390
|
+
let primaryUnavailable = 0;
|
|
18391
|
+
const primaryUnavailableCauses = [];
|
|
17885
18392
|
const rootFallbackReasons = /* @__PURE__ */ new Set();
|
|
17886
18393
|
let navigationOnly = 0;
|
|
17887
18394
|
let tooLarge = 0;
|
|
@@ -17900,6 +18407,11 @@ function tallyConfirmation(results) {
|
|
|
17900
18407
|
unconfirmed += 1;
|
|
17901
18408
|
if (result.timedOut)
|
|
17902
18409
|
timedOut += 1;
|
|
18410
|
+
if (result.primaryUnavailable !== void 0) {
|
|
18411
|
+
primaryUnavailable += 1;
|
|
18412
|
+
if (result.primaryUnavailableCause !== void 0)
|
|
18413
|
+
primaryUnavailableCauses.push(result.primaryUnavailableCause);
|
|
18414
|
+
}
|
|
17903
18415
|
if (result.rootFallback) {
|
|
17904
18416
|
rootFallbackReasons.add(describeRootFallback(result.rootFallback));
|
|
17905
18417
|
}
|
|
@@ -17911,6 +18423,10 @@ function tallyConfirmation(results) {
|
|
|
17911
18423
|
clean,
|
|
17912
18424
|
unconfirmed,
|
|
17913
18425
|
timedOut,
|
|
18426
|
+
primaryUnavailable: {
|
|
18427
|
+
count: primaryUnavailable,
|
|
18428
|
+
cause: combinePrimaryUnavailableCauses(primaryUnavailableCauses)
|
|
18429
|
+
},
|
|
17914
18430
|
rootFallbackReasons: [...rootFallbackReasons],
|
|
17915
18431
|
navigationOnly,
|
|
17916
18432
|
tooLarge
|
|
@@ -17923,6 +18439,9 @@ function classifyBatchFileOutcome(result) {
|
|
|
17923
18439
|
return "too_large";
|
|
17924
18440
|
if (result.diagnosticsUnsupported)
|
|
17925
18441
|
return "unsupported";
|
|
18442
|
+
if (result.noClientAnswered && result.primaryUnavailable !== void 0) {
|
|
18443
|
+
return "unavailable";
|
|
18444
|
+
}
|
|
17926
18445
|
if (result.timedOut || result.confirmation === "unconfirmed") {
|
|
17927
18446
|
return "inconclusive";
|
|
17928
18447
|
}
|
|
@@ -17945,7 +18464,24 @@ function inconclusiveBatchResult(file, reason) {
|
|
|
17945
18464
|
inconclusiveReason: reason
|
|
17946
18465
|
};
|
|
17947
18466
|
}
|
|
17948
|
-
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
|
+
}
|
|
17949
18485
|
if (rootFallbackReasons.length > 0) {
|
|
17950
18486
|
return `${rootFallbackReasons.join("; ")} (${unconfirmed} unconfirmed in all).`;
|
|
17951
18487
|
}
|
|
@@ -17961,7 +18497,8 @@ function unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons = []
|
|
|
17961
18497
|
async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
17962
18498
|
const resolvedCwd = options.cwd ?? process.cwd();
|
|
17963
18499
|
const cacheCtx = createWorkspaceDiagnosticsCacheContext(resolvedCwd);
|
|
17964
|
-
const
|
|
18500
|
+
const serverScope = options.serverScope ?? "all";
|
|
18501
|
+
const scopeKey = buildProbeScopeKey(serverScope, options.excludeServerIds);
|
|
17965
18502
|
const resultsByIndex = /* @__PURE__ */ new Map();
|
|
17966
18503
|
let completed = 0;
|
|
17967
18504
|
const pendingIndices = /* @__PURE__ */ new Map();
|
|
@@ -17972,6 +18509,11 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
17972
18509
|
else
|
|
17973
18510
|
pendingIndices.set(file, [index]);
|
|
17974
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
|
+
]);
|
|
17975
18517
|
const groups = groupFilesByPrimaryServer(files);
|
|
17976
18518
|
await runPerServerGroups(groups, options.concurrency, async (group) => {
|
|
17977
18519
|
if (options.signal?.aborted)
|
|
@@ -17986,7 +18528,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
17986
18528
|
}
|
|
17987
18529
|
await mapWithConcurrency(group.files, 1, async (file) => {
|
|
17988
18530
|
const index = pendingIndices.get(file).shift();
|
|
17989
|
-
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);
|
|
17990
18532
|
const bounded2 = withDeadline(work, {
|
|
17991
18533
|
ms: batchFileDeadlineMs(),
|
|
17992
18534
|
onTimeout: "undefined",
|
|
@@ -18017,7 +18559,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
18017
18559
|
const total = allDiags.length;
|
|
18018
18560
|
const truncated = total > MAX_DIAGNOSTICS;
|
|
18019
18561
|
const display = truncated ? allDiags.slice(0, MAX_DIAGNOSTICS) : allDiags;
|
|
18020
|
-
const { clean, unconfirmed, timedOut, rootFallbackReasons } = tallyConfirmation(results);
|
|
18562
|
+
const { clean, unconfirmed, timedOut, primaryUnavailable, rootFallbackReasons } = tallyConfirmation(results);
|
|
18021
18563
|
for (const result of results) {
|
|
18022
18564
|
result.outcome = classifyBatchFileOutcome(result);
|
|
18023
18565
|
}
|
|
@@ -18049,6 +18591,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
18049
18591
|
unconfirmed,
|
|
18050
18592
|
timedOut,
|
|
18051
18593
|
rootFallbackReasons,
|
|
18594
|
+
primaryUnavailable,
|
|
18052
18595
|
outcomeCounts,
|
|
18053
18596
|
incompleteFiles: Math.max(0, files.length - results.length)
|
|
18054
18597
|
};
|
|
@@ -18058,7 +18601,7 @@ async function expandPathsToFiles(cwd, rawPaths) {
|
|
|
18058
18601
|
const directories = [];
|
|
18059
18602
|
const seenFileKeys = /* @__PURE__ */ new Set();
|
|
18060
18603
|
for (const entry of rawPaths) {
|
|
18061
|
-
const abs = normalizeMapKey(
|
|
18604
|
+
const abs = normalizeMapKey(resolveHostToolPath(entry, cwd));
|
|
18062
18605
|
let stat;
|
|
18063
18606
|
try {
|
|
18064
18607
|
stat = fs22.statSync(abs);
|
|
@@ -18103,7 +18646,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18103
18646
|
details: { mode: "batch", severity, filesChecked: 0 }
|
|
18104
18647
|
};
|
|
18105
18648
|
}
|
|
18106
|
-
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);
|
|
18107
18650
|
const navigationOnly = results.filter((result) => result.diagnosticsUnsupported).length;
|
|
18108
18651
|
const dispositionSuppressed = results.reduce((sum, result) => sum + (result.dispositionSuppressed ?? 0), 0);
|
|
18109
18652
|
const lines = [
|
|
@@ -18129,7 +18672,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18129
18672
|
const outcomeDetails = results.map((result) => ({
|
|
18130
18673
|
file: result.file,
|
|
18131
18674
|
outcome: result.outcome,
|
|
18132
|
-
reason: result
|
|
18675
|
+
reason: batchOutcomeReason(result)
|
|
18133
18676
|
}));
|
|
18134
18677
|
const tooLargeLines = renderBatchOutcomeLines(outcomeDetails);
|
|
18135
18678
|
if (tooLargeLines.length > 0) {
|
|
@@ -18139,8 +18682,11 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18139
18682
|
lines.push("", "LSP health warnings:", ...lspHealthWarnings.slice(0, 10));
|
|
18140
18683
|
}
|
|
18141
18684
|
if (unconfirmed > 0) {
|
|
18142
|
-
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.`);
|
|
18143
18686
|
}
|
|
18687
|
+
const auxiliaryOnlyLine = auxiliaryOnlyFindingsLine(results);
|
|
18688
|
+
if (auxiliaryOnlyLine)
|
|
18689
|
+
lines.push("", auxiliaryOnlyLine);
|
|
18144
18690
|
if (display.length === 0) {
|
|
18145
18691
|
if (unconfirmed === 0 && outcomeCounts.clean === results.length) {
|
|
18146
18692
|
lines.push("", "No diagnostics found.");
|
|
@@ -18185,7 +18731,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options,
|
|
|
18185
18731
|
outcomes: results.map((result) => ({
|
|
18186
18732
|
file: result.file,
|
|
18187
18733
|
outcome: result.outcome,
|
|
18188
|
-
reason: result
|
|
18734
|
+
reason: batchOutcomeReason(result),
|
|
18189
18735
|
primaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.serverId === result.primaryServerId).length,
|
|
18190
18736
|
auxiliaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.serverId !== result.primaryServerId).length
|
|
18191
18737
|
})),
|
|
@@ -18253,26 +18799,30 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18253
18799
|
}
|
|
18254
18800
|
};
|
|
18255
18801
|
}
|
|
18256
|
-
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);
|
|
18257
18803
|
const navigationOnly = results.filter((result) => result.diagnosticsUnsupported).length;
|
|
18258
18804
|
const dispositionSuppressed = results.reduce((sum, result) => sum + (result.dispositionSuppressed ?? 0), 0);
|
|
18259
18805
|
const suppressedLine = dispositionSuppressedLine(dispositionSuppressed);
|
|
18260
18806
|
const outcomeDetails = results.map((result) => ({
|
|
18261
18807
|
file: result.file,
|
|
18262
18808
|
outcome: result.outcome,
|
|
18263
|
-
reason: result
|
|
18809
|
+
reason: batchOutcomeReason(result)
|
|
18264
18810
|
}));
|
|
18265
|
-
const
|
|
18811
|
+
const auxiliaryOnlyLine = auxiliaryOnlyFindingsLine(results);
|
|
18812
|
+
const tooLargeLines = renderBatchOutcomeLines(outcomeDetails, (file) => path37.relative(absPath, file));
|
|
18266
18813
|
let text;
|
|
18267
18814
|
if (total === 0) {
|
|
18268
|
-
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.";
|
|
18269
18816
|
text = [
|
|
18270
18817
|
`Directory: ${absPath}`,
|
|
18271
18818
|
`Files scanned: ${filesToProcess.length}${wasCapped ? ` (capped at ${MAX_FILES})` : ""}`,
|
|
18272
18819
|
...lspHealthWarnings.length > 0 ? [
|
|
18273
18820
|
"LSP unavailable for one or more files:",
|
|
18274
18821
|
...lspHealthWarnings.slice(0, 10)
|
|
18275
|
-
] :
|
|
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] : [],
|
|
18276
18826
|
...tooLargeLines.length > 0 ? ["", "Files too large for LSP diagnostics:", ...tooLargeLines] : [],
|
|
18277
18827
|
...suppressedLine ? ["", suppressedLine] : []
|
|
18278
18828
|
].join("\n");
|
|
@@ -18288,13 +18838,14 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18288
18838
|
// whole found diagnostics elsewhere.
|
|
18289
18839
|
...unconfirmed > 0 ? [
|
|
18290
18840
|
"",
|
|
18291
|
-
`${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)
|
|
18292
18842
|
] : [],
|
|
18843
|
+
...auxiliaryOnlyLine ? ["", auxiliaryOnlyLine] : [],
|
|
18293
18844
|
""
|
|
18294
18845
|
];
|
|
18295
18846
|
const toRelative = (d) => ({
|
|
18296
18847
|
...d,
|
|
18297
|
-
file:
|
|
18848
|
+
file: path37.relative(absPath, d.file)
|
|
18298
18849
|
});
|
|
18299
18850
|
if (primaryDisplay.length > 0) {
|
|
18300
18851
|
lines.push(`Primary findings (${primaryDisplay.length}):`);
|
|
@@ -18325,7 +18876,7 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18325
18876
|
filesScanned: filesToProcess.length,
|
|
18326
18877
|
capped: wasCapped,
|
|
18327
18878
|
diagnostics: display.map((d) => ({
|
|
18328
|
-
file:
|
|
18879
|
+
file: path37.relative(absPath, d.file),
|
|
18329
18880
|
line: d.line,
|
|
18330
18881
|
character: d.character,
|
|
18331
18882
|
severity: d.severity,
|
|
@@ -18351,11 +18902,6 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18351
18902
|
}
|
|
18352
18903
|
};
|
|
18353
18904
|
}
|
|
18354
|
-
function dispositionSuppressedLine(suppressed) {
|
|
18355
|
-
if (suppressed <= 0)
|
|
18356
|
-
return void 0;
|
|
18357
|
-
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.`;
|
|
18358
|
-
}
|
|
18359
18905
|
function applySeverityFilter(diags, severity) {
|
|
18360
18906
|
if (severity === "all")
|
|
18361
18907
|
return diags;
|
|
@@ -18422,7 +18968,7 @@ async function findFullScanBindingMismatches(results) {
|
|
|
18422
18968
|
return mismatched;
|
|
18423
18969
|
}
|
|
18424
18970
|
function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSPService, flushPending = async () => {
|
|
18425
|
-
}, nextWriteIndex, captureLspStatusRepaint, getRuntime, isLensGuardEnabled2 = () => true) {
|
|
18971
|
+
}, nextWriteIndex, captureLspStatusRepaint, getRuntime, isLensGuardEnabled2 = () => true, getFlag) {
|
|
18426
18972
|
const lspProbe = createLspDiagnosticsTool(nextWriteIndex, (info) => {
|
|
18427
18973
|
const runtime = getRuntime?.();
|
|
18428
18974
|
if (!runtime)
|
|
@@ -18443,7 +18989,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18443
18989
|
message: `inline_blocker: retired for ${info.filePath}`
|
|
18444
18990
|
});
|
|
18445
18991
|
}
|
|
18446
|
-
}, getLspService);
|
|
18992
|
+
}, getLspService, getFlag);
|
|
18447
18993
|
return {
|
|
18448
18994
|
name: "lens_diagnostics",
|
|
18449
18995
|
label: "Project Diagnostics",
|
|
@@ -18455,7 +19001,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18455
19001
|
const files2 = details.filesChecked ?? details.filesScanned ?? 0;
|
|
18456
19002
|
const noun = count === 1 ? "diagnostic" : "diagnostics";
|
|
18457
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;
|
|
18458
|
-
const singleFile = (details?.mode === "file" || files2 === 1) && typeof filePath === "string" ? ` ${
|
|
19004
|
+
const singleFile = (details?.mode === "file" || files2 === 1) && typeof filePath === "string" ? ` ${path38.basename(filePath)}` : "";
|
|
18459
19005
|
const scope = files2 > 1 ? ` across ${files2} files` : singleFile;
|
|
18460
19006
|
if (isError)
|
|
18461
19007
|
return `lens_diagnostics lsp \u2014 ${text.split("\n")[0] ?? "error"}`;
|
|
@@ -18473,7 +19019,10 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18473
19019
|
if ((details.incompleteFiles ?? 0) > 0)
|
|
18474
19020
|
return `lens_diagnostics${scope} \u2014 incomplete (${details.incompleteFiles} files not confirmed)`;
|
|
18475
19021
|
if (count === 0 && details.unconfirmed)
|
|
18476
|
-
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
|
+
);
|
|
18477
19026
|
return `lens_diagnostics${scope} \u2014 ${count} ${noun}`;
|
|
18478
19027
|
}
|
|
18479
19028
|
const scanning = scanningSummaryLine(details, text);
|
|
@@ -18583,6 +19132,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18583
19132
|
const hasExplicitPaths = Array.isArray(lspParams.paths) && lspParams.paths.length > 0;
|
|
18584
19133
|
if (scope === "workspace" && !hasExplicitPath && !hasExplicitPaths) {
|
|
18585
19134
|
lspParams.path = cwd;
|
|
19135
|
+
lspParams.pathAlreadyResolved = true;
|
|
18586
19136
|
}
|
|
18587
19137
|
const lspStart = Date.now();
|
|
18588
19138
|
const result = await lspProbe.execute(_toolCallId, lspParams, signal, onUpdate, ctx.signal ? { cwd, signal: ctx.signal } : { cwd });
|
|
@@ -18701,7 +19251,7 @@ function appendProjectDiagnosticsDeltaLines(groups, cwd, report, severity, inclu
|
|
|
18701
19251
|
const diagnostics = [...gated.live, ...gated.stale];
|
|
18702
19252
|
const byFile = /* @__PURE__ */ new Map();
|
|
18703
19253
|
for (const diagnostic of diagnostics) {
|
|
18704
|
-
const filePath =
|
|
19254
|
+
const filePath = path38.resolve(diagnostic.filePath);
|
|
18705
19255
|
const bucket = byFile.get(filePath) ?? [];
|
|
18706
19256
|
bucket.push(diagnostic);
|
|
18707
19257
|
byFile.set(filePath, bucket);
|
|
@@ -18828,7 +19378,7 @@ function applyDeltaFreshnessGate(files, cwd, generatedAt) {
|
|
|
18828
19378
|
})).filter((file) => file.warnings.length > 0);
|
|
18829
19379
|
}
|
|
18830
19380
|
function getDeltaFileGroup(groups, cwd, filePath) {
|
|
18831
|
-
const rel =
|
|
19381
|
+
const rel = path38.relative(cwd, filePath);
|
|
18832
19382
|
let group = groups.get(rel);
|
|
18833
19383
|
if (!group) {
|
|
18834
19384
|
group = {
|
|
@@ -18952,7 +19502,7 @@ Summary (turn delta): ${aw} actionable warning${aw === 1 ? "" : "s"} \xB7 ${cq}
|
|
|
18952
19502
|
function createCurrentIgnoreFilter(cwd) {
|
|
18953
19503
|
try {
|
|
18954
19504
|
const matcher = getProjectIgnoreMatcher(cwd);
|
|
18955
|
-
return (filePath) => !matcher.isIgnored(
|
|
19505
|
+
return (filePath) => !matcher.isIgnored(path38.resolve(filePath), false);
|
|
18956
19506
|
} catch {
|
|
18957
19507
|
return () => true;
|
|
18958
19508
|
}
|
|
@@ -18963,7 +19513,7 @@ function resolvePathsScope(cwd, rawPaths) {
|
|
|
18963
19513
|
if (rawPaths.length > MAX_PATHS_ENTRIES) {
|
|
18964
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.`);
|
|
18965
19515
|
}
|
|
18966
|
-
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));
|
|
18967
19517
|
const missing = [];
|
|
18968
19518
|
const fileEntries = [];
|
|
18969
19519
|
const existingEntries = [];
|
|
@@ -18986,9 +19536,9 @@ function resolvePathsScope(cwd, rawPaths) {
|
|
|
18986
19536
|
}
|
|
18987
19537
|
const fileKeys = new Set(fileEntries.map((f) => normalizeFilePath(f)));
|
|
18988
19538
|
const dirPrefixes = dirEntries.map((d) => normalizeFilePath(d));
|
|
18989
|
-
const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(
|
|
19539
|
+
const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(path38.resolve(filePath)));
|
|
18990
19540
|
const includeFile = (filePath) => {
|
|
18991
|
-
const key = normalizeFilePath(
|
|
19541
|
+
const key = normalizeFilePath(path38.resolve(filePath));
|
|
18992
19542
|
if (fileKeys.has(key))
|
|
18993
19543
|
return true;
|
|
18994
19544
|
return dirPrefixes.some((prefix) => key === prefix || key.startsWith(`${prefix}/`));
|
|
@@ -19009,7 +19559,7 @@ function pathsScopeCacheOnlyNote(scope) {
|
|
|
19009
19559
|
function pathsScopeMissingNote(scope) {
|
|
19010
19560
|
if (!scope || scope.missing.length === 0)
|
|
19011
19561
|
return "";
|
|
19012
|
-
const shown2 = scope.missing.slice(0, 10).map((p) =>
|
|
19562
|
+
const shown2 = scope.missing.slice(0, 10).map((p) => path38.basename(p));
|
|
19013
19563
|
const more = scope.missing.length > shown2.length ? ` (+${scope.missing.length - shown2.length} more)` : "";
|
|
19014
19564
|
return `
|
|
19015
19565
|
|
|
@@ -19140,7 +19690,7 @@ function projectDiagnosticToWidget(diagnostic, filePath) {
|
|
|
19140
19690
|
}
|
|
19141
19691
|
function diagnosticDedupKey(filePath, diagnostic) {
|
|
19142
19692
|
const ruleId = normalizeRuleId(diagnostic.rule ?? diagnostic.tool ?? "");
|
|
19143
|
-
return [
|
|
19693
|
+
return [path38.resolve(filePath), diagnostic.line ?? "?", ruleId].join(":");
|
|
19144
19694
|
}
|
|
19145
19695
|
function runnerIdOf(diagnostic) {
|
|
19146
19696
|
return diagnostic.tool ?? diagnostic.rule?.split(":", 1)[0] ?? "";
|
|
@@ -19154,8 +19704,8 @@ function runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds,
|
|
|
19154
19704
|
const realFilePath = realpathOrResolve(filePath);
|
|
19155
19705
|
for (const entry of coverage) {
|
|
19156
19706
|
const root = entry.root;
|
|
19157
|
-
const relative9 =
|
|
19158
|
-
const underRoot = relative9 === "" || !relative9.startsWith("..") && !
|
|
19707
|
+
const relative9 = path38.relative(root, realFilePath);
|
|
19708
|
+
const underRoot = relative9 === "" || !relative9.startsWith("..") && !path38.isAbsolute(relative9);
|
|
19159
19709
|
if (!underRoot)
|
|
19160
19710
|
continue;
|
|
19161
19711
|
if (entry.files.has(realFilePath)) {
|
|
@@ -19205,7 +19755,11 @@ var UNCONFIRMED_REASON_SENTENCE = {
|
|
|
19205
19755
|
binding_mismatch: "the file changed on disk since this result was computed",
|
|
19206
19756
|
// #2052: no server was asked. Say WHY and say it is permanent for this
|
|
19207
19757
|
// path, so the reader does not read an empty result as "clean" or retry it.
|
|
19208
|
-
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})`
|
|
19209
19763
|
};
|
|
19210
19764
|
var UNCONFIRMED_REASON_COUNT_LABEL = {
|
|
19211
19765
|
budget: "timed out",
|
|
@@ -19214,7 +19768,10 @@ var UNCONFIRMED_REASON_COUNT_LABEL = {
|
|
|
19214
19768
|
service_destroyed: "service reset mid-sweep",
|
|
19215
19769
|
error: "errored",
|
|
19216
19770
|
binding_mismatch: "stale binding",
|
|
19217
|
-
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"
|
|
19218
19775
|
};
|
|
19219
19776
|
function classifyUnconfirmedReason(result, mismatched) {
|
|
19220
19777
|
if (mismatched.has(result))
|
|
@@ -19279,7 +19836,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19279
19836
|
const byFile = /* @__PURE__ */ new Map();
|
|
19280
19837
|
const seen = /* @__PURE__ */ new Set();
|
|
19281
19838
|
for (const summary of widgetSummaries) {
|
|
19282
|
-
const filePath =
|
|
19839
|
+
const filePath = path38.resolve(summary.filePath);
|
|
19283
19840
|
if (authoritativeLspFiles?.has(filePath))
|
|
19284
19841
|
continue;
|
|
19285
19842
|
const retained = summary.diagnostics ?? [];
|
|
@@ -19307,7 +19864,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19307
19864
|
byFile.set(filePath, summarizeDiagnostics(filePath, diagnostics, existing?.hasFinalSnapshot ?? true));
|
|
19308
19865
|
};
|
|
19309
19866
|
for (const result of lspResults) {
|
|
19310
|
-
const filePath =
|
|
19867
|
+
const filePath = path38.resolve(result.filePath);
|
|
19311
19868
|
for (const diagnostic of result.diagnostics ?? []) {
|
|
19312
19869
|
addDiagnostic(filePath, {
|
|
19313
19870
|
...lspDiagnosticToWidget(diagnostic),
|
|
@@ -19327,19 +19884,19 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19327
19884
|
});
|
|
19328
19885
|
}
|
|
19329
19886
|
for (const diagnostic of projectSnapshot?.diagnostics ?? []) {
|
|
19330
|
-
addDiagnostic(
|
|
19887
|
+
addDiagnostic(path38.resolve(diagnostic.filePath), projectDiagnosticToWidget(diagnostic, diagnostic.filePath));
|
|
19331
19888
|
}
|
|
19332
19889
|
for (const diagnostic of deltaDiagnostics) {
|
|
19333
19890
|
const widget = projectDiagnosticToWidget(diagnostic, diagnostic.filePath);
|
|
19334
19891
|
const observedAt = widget.observedAt ?? deltaObservedAt;
|
|
19335
|
-
addDiagnostic(
|
|
19892
|
+
addDiagnostic(path38.resolve(diagnostic.filePath), {
|
|
19336
19893
|
...widget,
|
|
19337
19894
|
...observedAt !== void 0 && { observedAt }
|
|
19338
19895
|
});
|
|
19339
19896
|
}
|
|
19340
19897
|
return [...byFile.values()];
|
|
19341
19898
|
}
|
|
19342
|
-
async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
|
|
19899
|
+
async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap, dispositionDropped) {
|
|
19343
19900
|
return Promise.all(summaries.map(async (summary) => {
|
|
19344
19901
|
if (!summary.diagnostics.length)
|
|
19345
19902
|
return summary;
|
|
@@ -19353,12 +19910,19 @@ async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
|
|
|
19353
19910
|
});
|
|
19354
19911
|
return policyKept2.length === summary.diagnostics.length ? summary : summarizeDiagnostics(summary.filePath, policyKept2, summary.hasFinalSnapshot);
|
|
19355
19912
|
}
|
|
19356
|
-
const { kept: policyKept } = applyFindingPolicy(summary.diagnostics, {
|
|
19913
|
+
const { kept: policyKept, inlineKept, disposed } = applyFindingPolicy(summary.diagnostics, {
|
|
19357
19914
|
cwd,
|
|
19358
19915
|
filePath: summary.filePath,
|
|
19359
19916
|
content,
|
|
19360
19917
|
policyMap
|
|
19361
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
|
+
}
|
|
19362
19926
|
for (const d of policyKept) {
|
|
19363
19927
|
const { weak } = anchorsForDiagnostic(cwd, summary.filePath, d, content);
|
|
19364
19928
|
if (getDisposition(cwd, weak)?.disposition === "flagged") {
|
|
@@ -19516,13 +20080,21 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19516
20080
|
const unconfirmedLspResults = lspResults.filter((result2) => result2.timedOut || result2.error || mismatchedLspResults.has(result2));
|
|
19517
20081
|
const authoritativeLspFiles = /* @__PURE__ */ new Set();
|
|
19518
20082
|
const unreconciledFiles = /* @__PURE__ */ new Set();
|
|
20083
|
+
const policyMap = loadProjectRulePolicyMap(cwd);
|
|
19519
20084
|
for (const result2 of fullyCoveredLspResults) {
|
|
19520
20085
|
try {
|
|
19521
20086
|
const diagnostics = convertLspDiagnostics(result2.diagnostics, result2.filePath, { scanOrigin: "lens_diagnostics_full" });
|
|
19522
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
|
+
});
|
|
19523
20095
|
const retired = reconcileScanDiagnostics(
|
|
19524
20096
|
result2.filePath,
|
|
19525
|
-
|
|
20097
|
+
policyKept,
|
|
19526
20098
|
true,
|
|
19527
20099
|
// The service reserves this token when the file enters the scan. The
|
|
19528
20100
|
// fallback preserves compatibility with older test doubles/services.
|
|
@@ -19535,32 +20107,31 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19535
20107
|
result2.observedAt
|
|
19536
20108
|
);
|
|
19537
20109
|
if (retired === true) {
|
|
19538
|
-
authoritativeLspFiles.add(
|
|
20110
|
+
authoritativeLspFiles.add(path38.resolve(result2.filePath));
|
|
19539
20111
|
} else {
|
|
19540
|
-
unreconciledFiles.add(
|
|
20112
|
+
unreconciledFiles.add(path38.resolve(result2.filePath));
|
|
19541
20113
|
recordDegradationOnce({
|
|
19542
20114
|
kind: "diagnostic-retained-unreconciled",
|
|
19543
|
-
subject: `${
|
|
20115
|
+
subject: `${path38.resolve(result2.filePath)}:lsp`,
|
|
19544
20116
|
reason: "confirmed diagnostic result could not replace retained widget state"
|
|
19545
20117
|
});
|
|
19546
20118
|
}
|
|
19547
20119
|
} catch {
|
|
19548
|
-
unreconciledFiles.add(
|
|
20120
|
+
unreconciledFiles.add(path38.resolve(result2.filePath));
|
|
19549
20121
|
recordDegradationOnce({
|
|
19550
20122
|
kind: "diagnostic-retained-unreconciled",
|
|
19551
|
-
subject: `${
|
|
20123
|
+
subject: `${path38.resolve(result2.filePath)}:lsp`,
|
|
19552
20124
|
reason: "confirmed diagnostic result failed during widget reconciliation"
|
|
19553
20125
|
});
|
|
19554
20126
|
}
|
|
19555
20127
|
}
|
|
19556
|
-
const policyMap = loadProjectRulePolicyMap(cwd);
|
|
19557
20128
|
const scannedSnapshot = filterProjectDiagnosticsSnapshot(rawProjectSnapshot, includeFile);
|
|
19558
20129
|
const authoritativeRunnerIds = new Set(extracted.analyzed ?? []);
|
|
19559
20130
|
const authoritativeRunnerCoverage = extracted.authoritativeCoverage ?? [];
|
|
19560
20131
|
const foldedProjectSnapshot = foldExtraDiagnosticsIntoSnapshot(scannedSnapshot, extracted.diagnostics.filter((d) => includeFile(d.filePath)), extracted.runners, cwd);
|
|
19561
20132
|
const projectSnapshot = applyProjectRulePolicy(foldedProjectSnapshot, policyMap, cwd);
|
|
19562
20133
|
const projectDelta = applyProjectRulePolicy(filterProjectDiagnosticsDeltaReport(loadProjectDiagnosticsDeltaReport(cwd), includeFile), policyMap, cwd);
|
|
19563
|
-
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;
|
|
19564
20135
|
if (authoritativeRetiredCount > 0) {
|
|
19565
20136
|
logLatency({
|
|
19566
20137
|
type: "phase",
|
|
@@ -19613,9 +20184,10 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19613
20184
|
}
|
|
19614
20185
|
});
|
|
19615
20186
|
}
|
|
19616
|
-
|
|
20187
|
+
const dispositionDropped = [];
|
|
20188
|
+
let summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage), cwd, policyMap, dispositionDropped);
|
|
19617
20189
|
if (unreconciledFiles.size > 0) {
|
|
19618
|
-
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);
|
|
19619
20191
|
}
|
|
19620
20192
|
const parsedProjectScanObservedAt = projectSnapshot?.scannedAt ? Date.parse(projectSnapshot.scannedAt) : void 0;
|
|
19621
20193
|
const projectScanObservedAt = parsedProjectScanObservedAt !== void 0 && Number.isFinite(parsedProjectScanObservedAt) ? parsedProjectScanObservedAt : void 0;
|
|
@@ -19637,14 +20209,26 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19637
20209
|
sources: projectDelta.sources,
|
|
19638
20210
|
turnIndex: projectDelta.turnIndex
|
|
19639
20211
|
}
|
|
19640
|
-
}, 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
|
+
});
|
|
19641
20224
|
const missingNote = pathsScopeMissingNote(pathsScope);
|
|
19642
20225
|
const unconfirmedByReason = tallyUnconfirmedReasons(unconfirmedLspResults, mismatchedLspResults);
|
|
19643
20226
|
const lspServerBreakdown = tallyLspByPrimaryServer(confirmedLspResults, unconfirmedLspResults);
|
|
19644
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";
|
|
19645
20229
|
const unconfirmedLspNote = unconfirmedLspResults.length > 0 ? `
|
|
19646
20230
|
|
|
19647
|
-
\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).` : "";
|
|
19648
20232
|
const uncoveredScannerIds = [
|
|
19649
20233
|
...new Set(partiallyCoveredLspResults.flatMap((result2) => result2.unconfirmedServerIds ?? []))
|
|
19650
20234
|
].sort((a, b) => Number(a > b) - Number(a < b));
|
|
@@ -19692,10 +20276,6 @@ test-runner coverage is edit-scoped, NOT a full-project run: its findings only r
|
|
|
19692
20276
|
const failedNote = failedAnalyzers.length > 0 ? `
|
|
19693
20277
|
|
|
19694
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.` : "";
|
|
19695
|
-
const dispositionSuppressedByLaneText = Object.entries(extracted.dispositionSuppressedByLane ?? {}).map(([id, count]) => `${id} ${count}`).join(", ");
|
|
19696
|
-
const dispositionSuppressedNote = (extracted.dispositionSuppressed ?? 0) > 0 ? `
|
|
19697
|
-
|
|
19698
|
-
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.` : "";
|
|
19699
20279
|
const walkUnsafeRoot = explicitFiles === void 0 && isAtOrAboveHomeDir(cwd);
|
|
19700
20280
|
const walkUnsafeRootNote = walkUnsafeRoot ? `
|
|
19701
20281
|
|
|
@@ -19743,7 +20323,9 @@ served from cache this call (not re-run): ${cachedAgeEntries.map(([id, ms]) => `
|
|
|
19743
20323
|
coldReasons: extracted.coldReasons ?? {},
|
|
19744
20324
|
failedAnalyzers,
|
|
19745
20325
|
analyzerTimingsMs: extracted.timings,
|
|
19746
|
-
|
|
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,
|
|
19747
20329
|
dispositionSuppressedByLane: extracted.dispositionSuppressedByLane ?? {},
|
|
19748
20330
|
// #1623: ms-old each cache-read-by-design lane's data was (today, only
|
|
19749
20331
|
// test-runner) — lets a caller distinguish "just ran" from "served
|
|
@@ -19798,18 +20380,18 @@ served from cache this call (not re-run): ${cachedAgeEntries.map(([id, ms]) => `
|
|
|
19798
20380
|
content: [
|
|
19799
20381
|
{
|
|
19800
20382
|
type: "text",
|
|
19801
|
-
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
|
|
19802
20384
|
}
|
|
19803
20385
|
],
|
|
19804
20386
|
details: { ...resultWithCold.details, timedOut }
|
|
19805
20387
|
};
|
|
19806
20388
|
}
|
|
19807
|
-
if (missingNote || coldNote || partialNote || testRunnerEditScopedNote || failedNote ||
|
|
20389
|
+
if (missingNote || coldNote || partialNote || testRunnerEditScopedNote || failedNote || walkUnsafeRootNote || scanTruncatedNote || generatedSkipNote || abortedNote || freshNote || cachedAgeNote || cheapScanStatusNote || unconfirmedLspNote || auxiliaryCoverageNote || lspPrimaryVsAuxiliaryNote) {
|
|
19808
20390
|
return {
|
|
19809
20391
|
content: [
|
|
19810
20392
|
{
|
|
19811
20393
|
type: "text",
|
|
19812
|
-
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
|
|
19813
20395
|
}
|
|
19814
20396
|
],
|
|
19815
20397
|
details: resultWithCold.details
|
|
@@ -19825,12 +20407,21 @@ async function projectResolvedCwd(summary, cwd) {
|
|
|
19825
20407
|
diagnostics: summary.diagnostics ?? []
|
|
19826
20408
|
};
|
|
19827
20409
|
}
|
|
19828
|
-
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: {} }) {
|
|
19829
20411
|
const footerCapped = summaries.reduce((n, s) => n + (s.diagnostics ?? []).filter((d) => d.footerRetired === true).length, 0);
|
|
19830
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)` : "");
|
|
19831
20413
|
const isFullMode = detailOverrides.mode === "full";
|
|
19832
20414
|
const includeFile = createScopedFileFilter(cwd, pathsScope);
|
|
19833
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;
|
|
19834
20425
|
const dispositioned = isFullMode ? summaries : summaries.map((s) => {
|
|
19835
20426
|
const diagnostics = s.diagnostics ?? [];
|
|
19836
20427
|
const kept = applyCachedDispositions(diagnostics, cwd, s.filePath);
|
|
@@ -19838,6 +20429,9 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19838
20429
|
root: cwd,
|
|
19839
20430
|
filePath: s.filePath
|
|
19840
20431
|
});
|
|
20432
|
+
if (includeFile(s.filePath)) {
|
|
20433
|
+
dispositionSuppressed += inScope(getSuppressedDiagnostics(s.filePath)) + inScope(diagnostics) - inScope(kept);
|
|
20434
|
+
}
|
|
19841
20435
|
if (policyKept.length === kept.length && kept.length === diagnostics.length)
|
|
19842
20436
|
return s;
|
|
19843
20437
|
return summarizeDiagnostics(s.filePath, policyKept, s.hasFinalSnapshot);
|
|
@@ -19863,14 +20457,19 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19863
20457
|
return s.blocking > 0 || s.errors > 0 || s.warnings > 0 || s.advisories > 0 || (s.diagnostics ?? []).some((d) => d.stale);
|
|
19864
20458
|
});
|
|
19865
20459
|
const pathsNote = isFullMode ? "" : pathsScopeCacheOnlyNote(pathsScope);
|
|
20460
|
+
const suppressedLine = dispositionSuppressedLine(dispositionSuppressed, suppressedBreakdown);
|
|
20461
|
+
const suppressedNote = suppressedLine ? `
|
|
20462
|
+
${suppressedLine}` : "";
|
|
20463
|
+
const suppressedDetails = dispositionSuppressed > 0 ? { dispositionSuppressed } : {};
|
|
19866
20464
|
if (withIssues.length === 0) {
|
|
19867
|
-
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;
|
|
19868
20466
|
return {
|
|
19869
20467
|
content: [{ type: "text", text }],
|
|
19870
20468
|
details: {
|
|
19871
20469
|
...detailOverrides,
|
|
19872
20470
|
filesChecked: visibleSummaries.length,
|
|
19873
|
-
staleDropped
|
|
20471
|
+
staleDropped,
|
|
20472
|
+
...suppressedDetails
|
|
19874
20473
|
}
|
|
19875
20474
|
};
|
|
19876
20475
|
}
|
|
@@ -19882,7 +20481,7 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19882
20481
|
let totalWarnings = 0;
|
|
19883
20482
|
let totalAdvisories = 0;
|
|
19884
20483
|
for (const s of rendered) {
|
|
19885
|
-
const rel =
|
|
20484
|
+
const rel = path38.relative(cwd, s.filePath);
|
|
19886
20485
|
const parts = [];
|
|
19887
20486
|
if (s.blocking > 0)
|
|
19888
20487
|
parts.push(`\u{1F534} ${s.blocking} blocking`);
|
|
@@ -19934,7 +20533,10 @@ Summary (${visibleSummaries.length} files diagnosed this session):`,
|
|
|
19934
20533
|
].filter(Boolean).join("\n");
|
|
19935
20534
|
return {
|
|
19936
20535
|
content: [
|
|
19937
|
-
{
|
|
20536
|
+
{
|
|
20537
|
+
type: "text",
|
|
20538
|
+
text: lines.join("\n") + summary + staleNote + suppressedNote
|
|
20539
|
+
}
|
|
19938
20540
|
],
|
|
19939
20541
|
details: {
|
|
19940
20542
|
...detailOverrides,
|
|
@@ -19943,14 +20545,15 @@ Summary (${visibleSummaries.length} files diagnosed this session):`,
|
|
|
19943
20545
|
totalErrors,
|
|
19944
20546
|
totalWarnings,
|
|
19945
20547
|
totalAdvisories,
|
|
19946
|
-
staleDropped
|
|
20548
|
+
staleDropped,
|
|
20549
|
+
...suppressedDetails
|
|
19947
20550
|
}
|
|
19948
20551
|
};
|
|
19949
20552
|
}
|
|
19950
20553
|
|
|
19951
20554
|
// dist/tools/lsp-navigation.js
|
|
19952
20555
|
import * as nodeFs2 from "node:fs";
|
|
19953
|
-
import * as
|
|
20556
|
+
import * as path39 from "node:path";
|
|
19954
20557
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
19955
20558
|
|
|
19956
20559
|
// dist/tools/lsp-structured-output.js
|
|
@@ -20310,6 +20913,12 @@ function operationSupportStatus(operation, support) {
|
|
|
20310
20913
|
return support.callHierarchy;
|
|
20311
20914
|
return null;
|
|
20312
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
|
+
}
|
|
20313
20922
|
function emptyReasonForOperation(operation) {
|
|
20314
20923
|
if (operation === "signatureHelp")
|
|
20315
20924
|
return "position-sensitive-or-no-signature";
|
|
@@ -20660,7 +21269,7 @@ function collectSearchReadsForOperation(operation, result, callHierarchyItem) {
|
|
|
20660
21269
|
}
|
|
20661
21270
|
function formatCapabilities(snapshots, filePath) {
|
|
20662
21271
|
if (snapshots.length === 0) {
|
|
20663
|
-
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.";
|
|
20664
21273
|
}
|
|
20665
21274
|
const rows = [
|
|
20666
21275
|
["definition", (s) => !!s.operationSupport.definition],
|
|
@@ -20690,7 +21299,7 @@ function formatCapabilities(snapshots, filePath) {
|
|
|
20690
21299
|
];
|
|
20691
21300
|
const lines = [];
|
|
20692
21301
|
for (const snapshot of snapshots) {
|
|
20693
|
-
const label = filePath ? `${snapshot.serverId} (${
|
|
21302
|
+
const label = filePath ? `${snapshot.serverId} (${path39.basename(filePath)})` : `${snapshot.serverId} (${snapshot.root})`;
|
|
20694
21303
|
lines.push(label);
|
|
20695
21304
|
for (const [name, supported, note] of rows) {
|
|
20696
21305
|
const suffix = note ? ` (${note})` : "";
|
|
@@ -20718,7 +21327,7 @@ function classifyCodeActions(actions) {
|
|
|
20718
21327
|
}
|
|
20719
21328
|
return { quickfix, refactor, other };
|
|
20720
21329
|
}
|
|
20721
|
-
async function openFileBestEffort(lspService, filePath, waitForDiagnostics = false) {
|
|
21330
|
+
async function openFileBestEffort(lspService, filePath, waitForDiagnostics = false, excludeServerIds) {
|
|
20722
21331
|
let fileContent;
|
|
20723
21332
|
try {
|
|
20724
21333
|
fileContent = nodeFs2.readFileSync(filePath, "utf-8");
|
|
@@ -20731,7 +21340,8 @@ async function openFileBestEffort(lspService, filePath, waitForDiagnostics = fal
|
|
|
20731
21340
|
await lspService.touchFile(filePath, fileContent, {
|
|
20732
21341
|
diagnostics: waitForDiagnostics ? "document" : "none",
|
|
20733
21342
|
source: "lsp_navigation",
|
|
20734
|
-
clientScope: waitForDiagnostics ? "all" : "primary"
|
|
21343
|
+
clientScope: waitForDiagnostics ? "all" : "primary",
|
|
21344
|
+
...excludeServerIds !== void 0 && { excludeServerIds }
|
|
20735
21345
|
});
|
|
20736
21346
|
} catch {
|
|
20737
21347
|
}
|
|
@@ -20881,6 +21491,7 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
20881
21491
|
const session = mutationDeps?.runtime?.captureSessionGeneration?.();
|
|
20882
21492
|
const startedAt = Date.now();
|
|
20883
21493
|
let supported = null;
|
|
21494
|
+
let noFileClient = false;
|
|
20884
21495
|
let diagnosticsMode = "unknown";
|
|
20885
21496
|
let columnResolution;
|
|
20886
21497
|
let openedFileContent;
|
|
@@ -21030,7 +21641,7 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21030
21641
|
resultCount: 0
|
|
21031
21642
|
});
|
|
21032
21643
|
}
|
|
21033
|
-
const filePath = rawPath ?
|
|
21644
|
+
const filePath = rawPath ? resolveHostToolPath(rawPath, ctx.cwd || ".") : "";
|
|
21034
21645
|
let filePathIsDirectory = false;
|
|
21035
21646
|
if (filePath) {
|
|
21036
21647
|
try {
|
|
@@ -21057,16 +21668,17 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21057
21668
|
});
|
|
21058
21669
|
}
|
|
21059
21670
|
if (operation === "workspaceDiagnostics") {
|
|
21671
|
+
const policyCwd = ctx.cwd || process.cwd();
|
|
21060
21672
|
const wsDiagSupport = rawPath ? await lspService.getWorkspaceDiagnosticsSupport(filePath) : await lspService.getWorkspaceDiagnosticsSupport(void 0, workspaceScopeAttribution);
|
|
21061
21673
|
diagnosticsMode = wsDiagSupport?.mode ?? "unknown";
|
|
21062
21674
|
if (rawPath && !filePathIsDirectory) {
|
|
21063
|
-
const hasLSP2 = lspService.supportsLSP(filePath);
|
|
21675
|
+
const hasLSP2 = lspService.supportsLSP(filePath) || disabledPrimaries(filePath).disabledServerIds.length > 0;
|
|
21064
21676
|
if (!hasLSP2) {
|
|
21065
21677
|
return finalize({
|
|
21066
21678
|
content: [
|
|
21067
21679
|
{
|
|
21068
21680
|
type: "text",
|
|
21069
|
-
text: `No LSP server available for ${
|
|
21681
|
+
text: `No LSP server available for ${path39.basename(filePath)}. Check that the language server is installed.`
|
|
21070
21682
|
}
|
|
21071
21683
|
],
|
|
21072
21684
|
isError: true
|
|
@@ -21077,8 +21689,12 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21077
21689
|
resultCount: 0
|
|
21078
21690
|
});
|
|
21079
21691
|
}
|
|
21080
|
-
|
|
21081
|
-
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;
|
|
21082
21698
|
const result3 = [
|
|
21083
21699
|
{
|
|
21084
21700
|
filePath,
|
|
@@ -21097,14 +21713,23 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
21097
21713
|
{
|
|
21098
21714
|
type: "text",
|
|
21099
21715
|
text: `${note2}
|
|
21100
|
-
${JSON.stringify(result3)}`
|
|
21716
|
+
${JSON.stringify(result3)}${primaryUnavailable ? `
|
|
21717
|
+
Note: ${primaryUnavailable}` : ""}${suppressedLine ? `
|
|
21718
|
+
Note: ${suppressedLine}` : ""}`
|
|
21101
21719
|
}
|
|
21102
21720
|
],
|
|
21103
21721
|
details: {
|
|
21104
21722
|
operation,
|
|
21105
21723
|
resultCount: resultCount2,
|
|
21106
21724
|
diagnosticsMode,
|
|
21107
|
-
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
|
+
}
|
|
21108
21733
|
}
|
|
21109
21734
|
}, {
|
|
21110
21735
|
operation,
|
|
@@ -21113,12 +21738,23 @@ ${JSON.stringify(result3)}`
|
|
|
21113
21738
|
resultCount: resultCount2
|
|
21114
21739
|
});
|
|
21115
21740
|
}
|
|
21116
|
-
const allDiagnostics = await lspService.getAllDiagnostics();
|
|
21117
|
-
|
|
21118
|
-
|
|
21119
|
-
|
|
21120
|
-
|
|
21121
|
-
|
|
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);
|
|
21122
21758
|
const noteMap2 = {
|
|
21123
21759
|
"push-only": "Note: push-only tracked diagnostics snapshot (not full workspace pull diagnostics).",
|
|
21124
21760
|
pull: "Note: tracked diagnostics snapshot from active clients. Provide path to force file-level diagnostics collection"
|
|
@@ -21129,14 +21765,18 @@ ${JSON.stringify(result3)}`
|
|
|
21129
21765
|
{
|
|
21130
21766
|
type: "text",
|
|
21131
21767
|
text: `${note}
|
|
21132
|
-
${JSON.stringify(result2)}`
|
|
21768
|
+
${JSON.stringify(result2)}${snapshotSuppressedLine ? `
|
|
21769
|
+
Note: ${snapshotSuppressedLine}` : ""}`
|
|
21133
21770
|
}
|
|
21134
21771
|
],
|
|
21135
21772
|
details: {
|
|
21136
21773
|
operation,
|
|
21137
21774
|
resultCount: result2.length,
|
|
21138
21775
|
diagnosticsMode,
|
|
21139
|
-
coverage: "tracked-open-files"
|
|
21776
|
+
coverage: "tracked-open-files",
|
|
21777
|
+
...snapshotSuppressed > 0 && {
|
|
21778
|
+
dispositionSuppressed: snapshotSuppressed
|
|
21779
|
+
}
|
|
21140
21780
|
}
|
|
21141
21781
|
}, {
|
|
21142
21782
|
operation,
|
|
@@ -21167,7 +21807,7 @@ ${JSON.stringify(result2)}`
|
|
|
21167
21807
|
content: [
|
|
21168
21808
|
{
|
|
21169
21809
|
type: "text",
|
|
21170
|
-
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.`
|
|
21171
21811
|
}
|
|
21172
21812
|
],
|
|
21173
21813
|
isError: true
|
|
@@ -21180,13 +21820,14 @@ ${JSON.stringify(result2)}`
|
|
|
21180
21820
|
}
|
|
21181
21821
|
if (needsFilePath) {
|
|
21182
21822
|
const support = await lspService.getOperationSupport(filePath);
|
|
21823
|
+
noFileClient = support === null;
|
|
21183
21824
|
supported = operationSupportStatus(operation, support);
|
|
21184
21825
|
if (supported === false) {
|
|
21185
21826
|
return finalize({
|
|
21186
21827
|
content: [
|
|
21187
21828
|
{
|
|
21188
21829
|
type: "text",
|
|
21189
|
-
text: `LSP server for ${
|
|
21830
|
+
text: `LSP server for ${path39.basename(filePath)} does not advertise support for ${operation}`
|
|
21190
21831
|
}
|
|
21191
21832
|
],
|
|
21192
21833
|
isError: true,
|
|
@@ -21315,7 +21956,7 @@ ${JSON.stringify(result2)}`
|
|
|
21315
21956
|
if (!newFilePath || newFilePath.trim().length === 0) {
|
|
21316
21957
|
throw new Error("__BADINPUT__ newFilePath parameter required for rename_file");
|
|
21317
21958
|
}
|
|
21318
|
-
const resolvedNewFilePath =
|
|
21959
|
+
const resolvedNewFilePath = resolveHostToolPath(newFilePath, ctx.cwd || ".");
|
|
21319
21960
|
const result2 = await lspService.renameFile(filePath, resolvedNewFilePath, {
|
|
21320
21961
|
cwd: ctx.cwd || ".",
|
|
21321
21962
|
apply: apply ?? false,
|
|
@@ -21459,7 +22100,15 @@ ${JSON.stringify(result2)}`
|
|
|
21459
22100
|
}, { operation, filePath, failureKind: "lsp_error", resultCount: 0 });
|
|
21460
22101
|
}
|
|
21461
22102
|
const isEmpty = !result || Array.isArray(result) && result.length === 0;
|
|
21462
|
-
|
|
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) : "";
|
|
21463
22112
|
const lineCtx = line ? ":" + line + ":" + character : "";
|
|
21464
22113
|
let output = isEmpty ? "No results for " + operation + fileCtx + lineCtx : JSON.stringify(result);
|
|
21465
22114
|
if (isEmpty && operation === "workspaceSymbol" && !rawPath) {
|
|
@@ -21701,11 +22350,11 @@ function resolveDefaultCwd() {
|
|
|
21701
22350
|
const fromArg = process.argv.find((arg) => arg.startsWith("--cwd="))?.slice("--cwd=".length);
|
|
21702
22351
|
return fromArg ?? process.env.PI_LENS_MCP_CWD ?? process.cwd();
|
|
21703
22352
|
}
|
|
21704
|
-
var DEFAULT_CWD =
|
|
22353
|
+
var DEFAULT_CWD = path40.resolve(resolveDefaultCwd());
|
|
21705
22354
|
var lspReadyCwds = /* @__PURE__ */ new Set();
|
|
21706
22355
|
var SERVER_FILE = fileURLToPath3(import.meta.url);
|
|
21707
|
-
var SERVER_DIR =
|
|
21708
|
-
var WORKER_PATH =
|
|
22356
|
+
var SERVER_DIR = path40.dirname(SERVER_FILE);
|
|
22357
|
+
var WORKER_PATH = path40.join(SERVER_DIR, "worker.js");
|
|
21709
22358
|
var REBUILD_SCRIPT = resolveRebuildScript(SERVER_FILE);
|
|
21710
22359
|
var STALENESS_STAT_PATH = process.env.PI_LENS_MCP_STALENESS_STAT_PATH ?? SERVER_FILE;
|
|
21711
22360
|
var BUILD_STAMP = computeBuildStamp(STALENESS_STAT_PATH);
|
|
@@ -21727,7 +22376,7 @@ function isWarmBuildStale() {
|
|
|
21727
22376
|
function findRepoRoot(start) {
|
|
21728
22377
|
let dir = start;
|
|
21729
22378
|
for (let depth = 0; depth < 6; depth++) {
|
|
21730
|
-
const pkgPath =
|
|
22379
|
+
const pkgPath = path40.join(dir, "package.json");
|
|
21731
22380
|
if (fs25.existsSync(pkgPath)) {
|
|
21732
22381
|
try {
|
|
21733
22382
|
const pkg = JSON.parse(fs25.readFileSync(pkgPath, "utf8"));
|
|
@@ -21736,16 +22385,16 @@ function findRepoRoot(start) {
|
|
|
21736
22385
|
} catch {
|
|
21737
22386
|
}
|
|
21738
22387
|
}
|
|
21739
|
-
const parent =
|
|
22388
|
+
const parent = path40.dirname(dir);
|
|
21740
22389
|
if (parent === dir)
|
|
21741
22390
|
break;
|
|
21742
22391
|
dir = parent;
|
|
21743
22392
|
}
|
|
21744
|
-
return
|
|
22393
|
+
return path40.resolve(start, "..", "..");
|
|
21745
22394
|
}
|
|
21746
|
-
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);
|
|
21747
22396
|
async function ensureReady(cwd) {
|
|
21748
|
-
const normalized =
|
|
22397
|
+
const normalized = path40.resolve(cwd);
|
|
21749
22398
|
if (!shouldInitializeSessionRoot(normalized, lspReadyCwds)) {
|
|
21750
22399
|
return;
|
|
21751
22400
|
}
|
|
@@ -21791,22 +22440,17 @@ function getAutoSessionStatus() {
|
|
|
21791
22440
|
}
|
|
21792
22441
|
var IPC_PATH = ipcPathForCwd(DEFAULT_CWD);
|
|
21793
22442
|
function rejectForeignTurnCwd(route, cwd) {
|
|
21794
|
-
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}`;
|
|
21795
22444
|
console.error(`[pi-lens-mcp] rejected ${message}`);
|
|
21796
22445
|
return message;
|
|
21797
22446
|
}
|
|
21798
22447
|
function isWithinServerWorkspace(cwd) {
|
|
21799
|
-
const target =
|
|
21800
|
-
const rel =
|
|
21801
|
-
return !rel.startsWith("..") && !
|
|
22448
|
+
const target = path40.resolve(cwd);
|
|
22449
|
+
const rel = path40.relative(DEFAULT_CWD, target);
|
|
22450
|
+
return !rel.startsWith("..") && !path40.isAbsolute(rel);
|
|
21802
22451
|
}
|
|
21803
22452
|
function startIpcServer() {
|
|
21804
|
-
|
|
21805
|
-
try {
|
|
21806
|
-
fs25.unlinkSync(IPC_PATH);
|
|
21807
|
-
} catch {
|
|
21808
|
-
}
|
|
21809
|
-
}
|
|
22453
|
+
unlinkStaleUnixSocket(IPC_PATH);
|
|
21810
22454
|
const requestQueue = createWarmIpcRequestQueue();
|
|
21811
22455
|
const ipc = net.createServer((socket) => {
|
|
21812
22456
|
socket.setEncoding("utf8");
|
|
@@ -21908,12 +22552,6 @@ function startIpcServer() {
|
|
|
21908
22552
|
ipc.close();
|
|
21909
22553
|
} catch {
|
|
21910
22554
|
}
|
|
21911
|
-
if (process.platform !== "win32") {
|
|
21912
|
-
try {
|
|
21913
|
-
fs25.unlinkSync(IPC_PATH);
|
|
21914
|
-
} catch {
|
|
21915
|
-
}
|
|
21916
|
-
}
|
|
21917
22555
|
};
|
|
21918
22556
|
process.on("exit", cleanup);
|
|
21919
22557
|
}
|
|
@@ -21974,7 +22612,11 @@ var lensDiagnosticsTool = createLensDiagnosticsTool(
|
|
|
21974
22612
|
// `lens-guard` off — a config bypass on a durable cross-surface store.
|
|
21975
22613
|
// Matches index.ts:1656 and the two sibling readers
|
|
21976
22614
|
// (clients/runtime-tool-call.ts, clients/runtime-tool-result.ts).
|
|
21977
|
-
() => 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)
|
|
21978
22620
|
);
|
|
21979
22621
|
var astGrepClient = new AstGrepClient();
|
|
21980
22622
|
var astGrepSearchTool = createAstGrepSearchTool(astGrepClient);
|
|
@@ -22293,7 +22935,7 @@ function enabledToolsForCwd(cwd) {
|
|
|
22293
22935
|
}
|
|
22294
22936
|
function formatAnalyze(result, cwd, mode, servedBy) {
|
|
22295
22937
|
const lspNote = result.lsp ? ` \xB7 lsp ${result.lsp.diagnosticCount} (${result.lsp.status}${result.lsp.failureKind ? `: ${result.lsp.failureKind}` : ""}, ${result.lsp.durationMs}ms)` : "";
|
|
22296
|
-
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 ? `
|
|
22297
22939
|
|
|
22298
22940
|
servedBy: ${servedBy}` : "");
|
|
22299
22941
|
return renderToolText(summary, servedBy ? { ...result, servedBy } : result);
|
|
@@ -22427,7 +23069,7 @@ ${outcome.output}`, {
|
|
|
22427
23069
|
}
|
|
22428
23070
|
const { deduped, byRule, byFile } = summarizeScan(snapshot.diagnostics);
|
|
22429
23071
|
const topRules = Object.entries(byRule).sort((a, b) => b[1] - a[1]);
|
|
22430
|
-
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 }));
|
|
22431
23073
|
const summaryLines = [
|
|
22432
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)` : ""),
|
|
22433
23075
|
...topRules.slice(0, 12).map(([rule, count]) => ` ${count}\xD7 ${rule}`)
|
|
@@ -22438,8 +23080,13 @@ ${outcome.output}`, {
|
|
|
22438
23080
|
const skipNotice = generatedSkipNotice(snapshot, "mcp");
|
|
22439
23081
|
if (skipNotice)
|
|
22440
23082
|
summaryLines.push(skipNotice);
|
|
23083
|
+
const { dispositionSuppressed } = snapshot;
|
|
23084
|
+
const suppressedLine = dispositionSuppressedLine(dispositionSuppressed);
|
|
23085
|
+
if (suppressedLine)
|
|
23086
|
+
summaryLines.push(suppressedLine);
|
|
22441
23087
|
return renderToolText(summaryLines.join("\n"), {
|
|
22442
23088
|
filesScanned: snapshot.filesScanned,
|
|
23089
|
+
...dispositionSuppressed > 0 ? { dispositionSuppressed } : {},
|
|
22443
23090
|
runners: snapshot.runners,
|
|
22444
23091
|
uniqueDiagnostics: deduped.length,
|
|
22445
23092
|
rawDiagnostics: snapshot.diagnostics.length,
|
|
@@ -22480,7 +23127,7 @@ ${stalenessNote}` : ""), {
|
|
|
22480
23127
|
}
|
|
22481
23128
|
const lines = [
|
|
22482
23129
|
`Top ${results.length} file(s) for "${query}":`,
|
|
22483
|
-
...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})`),
|
|
22484
23131
|
...stalenessNote ? ["", stalenessNote] : [],
|
|
22485
23132
|
...coverage ? [
|
|
22486
23133
|
`Index covers ${coverage.files} files${coverage.truncated ? " (capped \u2014 results may be incomplete)" : ""}.`
|
|
@@ -22490,7 +23137,7 @@ ${stalenessNote}` : ""), {
|
|
|
22490
23137
|
query,
|
|
22491
23138
|
coverage,
|
|
22492
23139
|
results: results.map((result) => {
|
|
22493
|
-
const relFile =
|
|
23140
|
+
const relFile = path40.relative(cwd, result.file);
|
|
22494
23141
|
return {
|
|
22495
23142
|
file: relFile,
|
|
22496
23143
|
score: result.score,
|
|
@@ -22529,12 +23176,12 @@ ${stalenessNote}` : ""), {
|
|
|
22529
23176
|
});
|
|
22530
23177
|
if (!report.available) {
|
|
22531
23178
|
return {
|
|
22532
|
-
...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),
|
|
22533
23180
|
isError: true
|
|
22534
23181
|
};
|
|
22535
23182
|
}
|
|
22536
23183
|
const graphStaleness = graphStalenessNote(report.graphBuiltAt, "Review graph");
|
|
22537
|
-
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 ? `
|
|
22538
23185
|
|
|
22539
23186
|
${graphStaleness}` : "");
|
|
22540
23187
|
if (view === "compact") {
|
|
@@ -22595,7 +23242,7 @@ ${graphStaleness}` : "");
|
|
|
22595
23242
|
if (!result.found) {
|
|
22596
23243
|
const suggestionSuffix = result.suggestions?.length ? ` Did you mean: ${result.suggestions.join(", ")}?` : " Use pilens_module_report to list symbols.";
|
|
22597
23244
|
return {
|
|
22598
|
-
...renderToolText(`Symbol "${symbol}" not found in ${
|
|
23245
|
+
...renderToolText(`Symbol "${symbol}" not found in ${path40.basename(file)}.${suggestionSuffix}`, {
|
|
22599
23246
|
found: false,
|
|
22600
23247
|
...result.suggestions ? { suggestions: result.suggestions } : {}
|
|
22601
23248
|
}),
|
|
@@ -22604,7 +23251,7 @@ ${graphStaleness}` : "");
|
|
|
22604
23251
|
}
|
|
22605
23252
|
const sigSuffix = result.signature ? ` ${result.signature}` : "";
|
|
22606
23253
|
const ambiguityNote = result.ambiguous ? ` (${result.ambiguous.count} matches \u2014 returned the ${result.kind}; pass \`kind\` to disambiguate: ${result.ambiguous.kinds.join(", ")})` : "";
|
|
22607
|
-
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}`;
|
|
22608
23255
|
return {
|
|
22609
23256
|
content: [
|
|
22610
23257
|
{
|
|
@@ -22642,14 +23289,14 @@ ${result.source ?? ""}`
|
|
|
22642
23289
|
|
|
22643
23290
|
Nested outline:
|
|
22644
23291
|
${JSON.stringify(result.outline)}` : "";
|
|
22645
|
-
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}`;
|
|
22646
23293
|
return {
|
|
22647
23294
|
...renderToolText(text, { found: false, line: result.line }),
|
|
22648
23295
|
isError: true
|
|
22649
23296
|
};
|
|
22650
23297
|
}
|
|
22651
23298
|
const range = result.partial ? `${result.startLine}-${result.endLine} (partial of ${result.enclosingStartLine}-${result.enclosingEndLine})` : `${result.startLine}-${result.endLine}`;
|
|
22652
|
-
const header = `${result.kind} ${result.name} ${
|
|
23299
|
+
const header = `${result.kind} ${result.name} ${path40.relative(cwd, result.path)}:${range}`;
|
|
22653
23300
|
return {
|
|
22654
23301
|
content: [
|
|
22655
23302
|
{
|
|
@@ -22684,7 +23331,7 @@ ${result.source ?? ""}`
|
|
|
22684
23331
|
]),
|
|
22685
23332
|
...renderLspBrokenStatusLines(brokenServers),
|
|
22686
23333
|
...renderDegradationLines(degradations),
|
|
22687
|
-
last ? `Last dispatch: ${
|
|
23334
|
+
last ? `Last dispatch: ${path40.basename(last.filePath)} \u2014 ${last.totalDurationMs}ms, ${last.totalDiagnostics} diagnostic(s)` : "Last dispatch: none yet",
|
|
22688
23335
|
`Diagnostics this session: ${stats.totalShown} shown \xB7 ${stats.totalAutoFixed} auto-fixed \xB7 ${stats.totalUnresolved} unresolved`,
|
|
22689
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)",
|
|
22690
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)",
|
|
@@ -22750,7 +23397,7 @@ ${result.source ?? ""}`
|
|
|
22750
23397
|
const limit = typeof args.limit === "number" && Number.isFinite(args.limit) ? Math.max(1, Math.floor(args.limit)) : 5;
|
|
22751
23398
|
const fileFilter = typeof args.file === "string" ? args.file : void 0;
|
|
22752
23399
|
const recent = recentLatency(limit, fileFilter);
|
|
22753
|
-
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");
|
|
22754
23401
|
return renderToolText(summary, recent);
|
|
22755
23402
|
}
|
|
22756
23403
|
if (name === "pilens_session_start") {
|