pi-lens 4.4.0 → 4.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +158 -0
- package/README.md +1 -0
- package/config/dependency-cruiser-eager-allowlist.json +3 -1
- package/dist/{chunk-IXEBJSUE.js → chunk-23WOO7TX.js} +11 -10
- package/dist/{chunk-E2WFBRHM.js → chunk-2B73ZPOK.js} +3 -3
- package/dist/{chunk-DQ2NZ7C4.js → chunk-2BBLFX75.js} +139 -11
- package/dist/{chunk-ZMOL6RQC.js → chunk-2CD5RS6M.js} +2 -2
- package/dist/{chunk-VD4JQCQC.js → chunk-2ZGIZPDG.js} +38 -37
- package/dist/{chunk-DIULIWKU.js → chunk-34WSVGEM.js} +29 -3
- package/dist/chunk-3JNKMP3B.js +17 -0
- package/dist/{chunk-HVUZXSWK.js → chunk-3UUPUE3O.js} +45 -41
- package/dist/{chunk-5RXBNSW2.js → chunk-3VPVG5SU.js} +16 -8
- package/dist/chunk-3WA4HP4I.js +55 -0
- package/dist/chunk-466Z26MG.js +30 -0
- package/dist/{chunk-34U7PLGE.js → chunk-4UNXBNE2.js} +12 -11
- package/dist/{chunk-E4MAEDPM.js → chunk-4W4VLAPJ.js} +12 -11
- package/dist/{chunk-GUOGVTCQ.js → chunk-52FUZI6K.js} +4 -2
- package/dist/chunk-5JM2524W.js +84 -0
- package/dist/{chunk-VHQLPIRJ.js → chunk-5NGR67U5.js} +2 -2
- package/dist/{chunk-DFVMIKMQ.js → chunk-66SXUJCA.js} +45 -9
- package/dist/{chunk-OQGFCZJ4.js → chunk-66VMUL7Q.js} +16 -16
- package/dist/{chunk-HWBZIGMJ.js → chunk-67WMNWEE.js} +9 -8
- package/dist/{chunk-6QIUX4EP.js → chunk-6C7JWPCP.js} +7 -7
- package/dist/{chunk-47D2BO4S.js → chunk-6GFRNVYR.js} +11 -10
- package/dist/{chunk-ZAWW3AF6.js → chunk-6SDEP3AJ.js} +9 -8
- package/dist/{chunk-TGPXLY2J.js → chunk-724UL2TJ.js} +38 -2
- package/dist/{chunk-YLF3PPT5.js → chunk-76MWC2K6.js} +3 -3
- package/dist/{chunk-F3P7VQ7H.js → chunk-7DYBLXYA.js} +3 -3
- package/dist/{chunk-AJ3QXTRQ.js → chunk-7ULNCDCO.js} +37 -35
- package/dist/{chunk-UK3CMEAL.js → chunk-AOHZU2BM.js} +1 -1
- package/dist/{chunk-F3AU2TMM.js → chunk-ARJ6PLFH.js} +44 -28
- package/dist/{chunk-U3VGR4VU.js → chunk-AW7R2GWG.js} +65 -8
- package/dist/{chunk-FJNKANOS.js → chunk-BKE7E7TC.js} +10 -9
- package/dist/{chunk-4W2PLC4J.js → chunk-BRGDSBJE.js} +13 -12
- package/dist/{chunk-VN2AXLEX.js → chunk-C34ZXZ7O.js} +102 -16
- package/dist/{chunk-T4ERT73Y.js → chunk-CF24OIYI.js} +21 -20
- package/dist/{chunk-NMABWBZN.js → chunk-CHOW74WE.js} +1 -1
- package/dist/{chunk-ARFCXG7S.js → chunk-CO2G5PHH.js} +2 -2
- package/dist/{chunk-AS44CFQ4.js → chunk-EETY4LF7.js} +24 -10
- package/dist/{chunk-I3R7GKDR.js → chunk-EJIUXPBX.js} +1 -1
- package/dist/{chunk-B3I2UUT4.js → chunk-ESBQHFMJ.js} +653 -251
- package/dist/{chunk-O5WILGMI.js → chunk-FLKWCIZH.js} +8 -5
- package/dist/{chunk-LNAKEO63.js → chunk-GAEGEPOC.js} +4 -4
- package/dist/{chunk-V7R425XG.js → chunk-GBPP5P7X.js} +4 -4
- package/dist/{chunk-XK4CIILI.js → chunk-GHB6AYCP.js} +27 -26
- package/dist/{chunk-7FBF7NPR.js → chunk-GOYRYZ2R.js} +29 -26
- package/dist/{chunk-JOLITGCC.js → chunk-GXW6K4YJ.js} +1 -1
- package/dist/{chunk-NXPS2L6U.js → chunk-GZYBXISR.js} +9 -9
- package/dist/{chunk-OAXNDZJ7.js → chunk-IBGIOBEE.js} +8 -4
- package/dist/{chunk-IIXOAGHR.js → chunk-IBRALRBR.js} +19 -15
- package/dist/{chunk-7F72PXY2.js → chunk-IXXDFY73.js} +3 -3
- package/dist/chunk-IZSHAIJ7.js +26 -0
- package/dist/{chunk-N3YQJI6O.js → chunk-JAU72XNY.js} +20 -15
- package/dist/chunk-JMYYOTQG.js +77 -0
- package/dist/{chunk-NL5GLMFI.js → chunk-JSQFTSC6.js} +12 -11
- package/dist/{chunk-IVP5KAB7.js → chunk-JWA5I3SR.js} +35 -21
- package/dist/{chunk-Y4T27COV.js → chunk-KBG47GHP.js} +4 -4
- package/dist/{chunk-PWFHBTSF.js → chunk-L3BLXZG7.js} +2 -2
- package/dist/chunk-LOP6GRPH.js +31 -0
- package/dist/chunk-MQLUAEOC.js +162 -0
- package/dist/{chunk-RPD5K5NC.js → chunk-MRXKYPCS.js} +2 -2
- package/dist/{chunk-Q5U6FMDI.js → chunk-N2H3ZPZY.js} +59 -7
- package/dist/{chunk-27BBHSZC.js → chunk-N3X6Q4YT.js} +3 -3
- package/dist/{chunk-UY752QSN.js → chunk-NW7BOILN.js} +19 -17
- package/dist/{chunk-TLGFBM3F.js → chunk-ODBNXWT4.js} +302 -113
- package/dist/{chunk-TT22N74J.js → chunk-OG5UUPN7.js} +13 -13
- package/dist/{chunk-C2AUYXQH.js → chunk-OXXKQCSV.js} +6 -6
- package/dist/{chunk-PAK6IDME.js → chunk-P7266HLM.js} +2 -2
- package/dist/{chunk-52H5B5TC.js → chunk-PFNSLWU5.js} +31 -30
- package/dist/{chunk-5ZEJHV35.js → chunk-PHDMFAKM.js} +12 -2
- package/dist/{chunk-3I5QFT3N.js → chunk-PNQDPDRC.js} +6 -3
- package/dist/{chunk-TVN5N6GY.js → chunk-PV6LR5P5.js} +6057 -1311
- package/dist/{chunk-AHDW3GPE.js → chunk-Q6ZWTCLY.js} +24 -22
- package/dist/{chunk-RUOG5D2C.js → chunk-Q7DUK4LX.js} +5 -5
- package/dist/{chunk-YSNFMJKN.js → chunk-QGQ5CCCG.js} +2 -2
- package/dist/{chunk-LW6XKDZQ.js → chunk-QHJ6DQ2R.js} +287 -38
- package/dist/{chunk-GVXA6CCE.js → chunk-QILIYSJF.js} +1 -1
- package/dist/{chunk-22AVIGXS.js → chunk-QOBUHWHX.js} +12 -7
- package/dist/{chunk-5THXD6X5.js → chunk-QQNQ7SJW.js} +2 -75
- package/dist/{chunk-4RERDEXR.js → chunk-QZVW3AAK.js} +50 -41
- package/dist/{chunk-AWE5TMPO.js → chunk-R3PCY3YS.js} +14 -13
- package/dist/{chunk-HHYAELLJ.js → chunk-RPLINGVB.js} +7 -7
- package/dist/{chunk-EOKRQ3SA.js → chunk-RWWYJ623.js} +10 -1
- package/dist/{chunk-YGVYKNSN.js → chunk-SAEFPSB6.js} +59 -12
- package/dist/{chunk-K6VYLB2U.js → chunk-TYM6OUIT.js} +13 -12
- package/dist/{chunk-AJXODZY6.js → chunk-UXGETRP4.js} +13 -12
- package/dist/{chunk-I7SPGOWI.js → chunk-UZ3TUTRV.js} +1 -1
- package/dist/{chunk-TO6WL3GM.js → chunk-VCHXCQFG.js} +12 -2
- package/dist/{chunk-BRJKOBZP.js → chunk-VITUCP5A.js} +17 -6
- package/dist/{chunk-WONERJTP.js → chunk-VRZP76YM.js} +1 -1
- package/dist/{chunk-OS32RNR2.js → chunk-VSSBEUFT.js} +16 -15
- package/dist/{chunk-VDBPVIKD.js → chunk-VWCXW2E7.js} +1 -1
- package/dist/{chunk-NKOUFPQF.js → chunk-WOA4LN2R.js} +2 -2
- package/dist/{chunk-RIISMHKN.js → chunk-WOKKRCJ5.js} +15 -13
- package/dist/{chunk-XECLWQZN.js → chunk-WU567RSC.js} +13 -10
- package/dist/{chunk-V5PXFSZK.js → chunk-XCJN5IJU.js} +4 -4
- package/dist/{chunk-ORTMY4Q4.js → chunk-XKIZ2HNN.js} +22 -14
- package/dist/{chunk-6VCD4VKZ.js → chunk-XMSXXAHW.js} +2 -2
- package/dist/chunk-XPZPXCBV.js +28 -0
- package/dist/{chunk-O6TQT6RI.js → chunk-XTMJ7XDT.js} +1 -1
- package/dist/{chunk-VNMT7C64.js → chunk-XVF2VVXP.js} +5 -3
- package/dist/chunk-Z527N6YQ.js +28 -0
- package/dist/{chunk-NTUJEGDZ.js → chunk-ZANLILYD.js} +22 -2
- package/dist/{chunk-6P62QVEA.js → chunk-ZGDGW2V3.js} +2 -2
- package/dist/{chunk-ODEEOXPH.js → chunk-ZHFZWTZV.js} +12 -11
- package/dist/{chunk-AJVLWNFN.js → chunk-ZXYDQ3TZ.js} +5 -5
- package/dist/index.js +102097 -97778
- package/dist/mcp/analyze-cli.js +18 -8
- package/dist/mcp/cli.js +48 -37
- package/dist/mcp/server.js +695 -426
- package/dist/mcp/worker.js +66 -55
- package/dist/probes/installer.js +20 -19
- package/docs/ast-grep_rules_catalog.md +2 -2
- package/docs/astplayground.md +1 -1
- package/docs/configuration.md +38 -2
- package/docs/custom-rules.md +25 -2
- package/docs/dependencies.md +3 -0
- package/docs/environment-variables.md +34 -6
- package/docs/features.md +39 -3
- package/docs/globalconfig.md +3 -1
- package/docs/language-coverage.md +2 -1
- package/docs/lsp-capability-matrix.md +29 -6
- package/docs/lsp-idle-eviction.md +38 -47
- package/docs/pi-lens-fixer.md +13 -5
- package/docs/pi-lens-merge-policy.md +48 -1
- package/docs/pi-lens-monitor.md +3 -1
- package/docs/pi-lens-retro.md +2 -1
- package/docs/pi-lens-reviewer.md +19 -3
- package/docs/pi-lens-subagent.md +2 -0
- package/docs/real-harness.md +17 -0
- package/docs/schema/pi-lens-config-v1.json +565 -0
- package/docs/servercapabilities.md +18 -4
- package/docs/settings.md +2 -1
- package/docs/word-index.md +6 -0
- package/package.json +1 -1
- package/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
- package/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
- package/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
- package/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
- package/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
- package/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
- package/dist/chunk-54B42YRX.js +0 -27
- package/dist/chunk-CGGAIP7J.js +0 -29
- package/dist/chunk-D6QS3U6M.js +0 -30
- package/dist/chunk-HMFXILPV.js +0 -83
- package/dist/chunk-LSMJ6KBE.js +0 -4139
- package/dist/chunk-NTHH2J74.js +0 -27
- package/dist/chunk-RPD4ZSB7.js +0 -25
- package/dist/chunk-T6D4Q4AQ.js +0 -54
- package/dist/chunk-VCSRSYLF.js +0 -81
package/dist/mcp/server.js
CHANGED
|
@@ -7,33 +7,32 @@ import {
|
|
|
7
7
|
deadCodeIssues,
|
|
8
8
|
formatDeadCodeDelta,
|
|
9
9
|
stableFindingKey
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-OG5UUPN7.js";
|
|
11
11
|
import {
|
|
12
12
|
clearFormatterCache
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-ARJ6PLFH.js";
|
|
14
14
|
import {
|
|
15
15
|
findNearestProjectRoot,
|
|
16
|
-
getStartupScanMaxEntries,
|
|
17
16
|
isStartupScanVerdictFresh,
|
|
18
17
|
resolveStartupScanContext
|
|
19
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-3VPVG5SU.js";
|
|
20
19
|
import {
|
|
21
20
|
loadCallGraph
|
|
22
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-WOA4LN2R.js";
|
|
23
22
|
import {
|
|
24
23
|
RUNNERS,
|
|
25
24
|
formatRunDurationMs,
|
|
26
25
|
isExcludedTestTarget,
|
|
27
26
|
isRunnerErrorResult
|
|
28
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-JWA5I3SR.js";
|
|
29
28
|
import {
|
|
30
29
|
GovulncheckClient
|
|
31
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-GZYBXISR.js";
|
|
32
31
|
import {
|
|
33
32
|
GitleaksClient,
|
|
34
33
|
classifyAndFilterFindings
|
|
35
|
-
} from "../chunk-
|
|
36
|
-
import "../chunk-
|
|
34
|
+
} from "../chunk-VITUCP5A.js";
|
|
35
|
+
import "../chunk-ZGDGW2V3.js";
|
|
37
36
|
import {
|
|
38
37
|
isHardFailureSummary
|
|
39
38
|
} from "../chunk-7U2IDNXN.js";
|
|
@@ -54,12 +53,13 @@ import {
|
|
|
54
53
|
peekTurnEndFindings,
|
|
55
54
|
snapshotAdvisoryProvenance,
|
|
56
55
|
validateAdvisoryProvenance
|
|
57
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-KBG47GHP.js";
|
|
58
57
|
import {
|
|
59
58
|
CacheManager,
|
|
60
59
|
DELTA_UNUSED_PROMOTION_NOTE,
|
|
61
60
|
MCP_TURN_STATE_OWNER_ID,
|
|
62
61
|
acquireWarmWordIndex,
|
|
62
|
+
admitsProjectWideFindings,
|
|
63
63
|
analyzeFile,
|
|
64
64
|
applyFindingPolicy,
|
|
65
65
|
applyLspFindingPolicy,
|
|
@@ -99,56 +99,42 @@ import {
|
|
|
99
99
|
resetPendingRunnerFindings,
|
|
100
100
|
resetPsScriptAnalyzerAvailability,
|
|
101
101
|
runProviders
|
|
102
|
-
} from "../chunk-
|
|
102
|
+
} from "../chunk-ODBNXWT4.js";
|
|
103
103
|
import {
|
|
104
104
|
resetLazyInstallAttempts
|
|
105
|
-
} from "../chunk-
|
|
105
|
+
} from "../chunk-OXXKQCSV.js";
|
|
106
106
|
import {
|
|
107
107
|
isTestRoleCollateral
|
|
108
|
-
} from "../chunk-
|
|
108
|
+
} from "../chunk-EJIUXPBX.js";
|
|
109
109
|
import "../chunk-FC4RP4I2.js";
|
|
110
110
|
import {
|
|
111
111
|
TrivyClient
|
|
112
|
-
} from "../chunk-
|
|
113
|
-
import "../chunk-
|
|
114
|
-
import "../chunk-
|
|
112
|
+
} from "../chunk-66SXUJCA.js";
|
|
113
|
+
import "../chunk-VCHXCQFG.js";
|
|
114
|
+
import "../chunk-IXXDFY73.js";
|
|
115
115
|
import {
|
|
116
116
|
resetRustAvailability
|
|
117
|
-
} from "../chunk-
|
|
117
|
+
} from "../chunk-MRXKYPCS.js";
|
|
118
118
|
import {
|
|
119
119
|
findingsResult,
|
|
120
120
|
hasUsableResult
|
|
121
|
-
} from "../chunk-
|
|
122
|
-
import "../chunk-
|
|
123
|
-
import "../chunk-
|
|
121
|
+
} from "../chunk-2CD5RS6M.js";
|
|
122
|
+
import "../chunk-UZ3TUTRV.js";
|
|
123
|
+
import "../chunk-EETY4LF7.js";
|
|
124
124
|
import {
|
|
125
125
|
getSgCommand,
|
|
126
126
|
resetDispatchAvailabilityState,
|
|
127
127
|
resolveManagedToolClient
|
|
128
|
-
} from "../chunk-
|
|
129
|
-
import "../chunk-
|
|
130
|
-
import "../chunk-
|
|
131
|
-
import "../chunk-
|
|
132
|
-
import "../chunk-
|
|
133
|
-
import "../chunk-
|
|
128
|
+
} from "../chunk-GOYRYZ2R.js";
|
|
129
|
+
import "../chunk-RPLINGVB.js";
|
|
130
|
+
import "../chunk-XCJN5IJU.js";
|
|
131
|
+
import "../chunk-76MWC2K6.js";
|
|
132
|
+
import "../chunk-GXW6K4YJ.js";
|
|
133
|
+
import "../chunk-2B73ZPOK.js";
|
|
134
134
|
import {
|
|
135
135
|
resetGoAvailability
|
|
136
|
-
} from "../chunk-
|
|
137
|
-
import "../chunk-
|
|
138
|
-
import {
|
|
139
|
-
SYMBOL_KIND_NAMES,
|
|
140
|
-
captureReviewGraphStructuralIr,
|
|
141
|
-
formatReviewGraphRevisionDriftNote,
|
|
142
|
-
publishReviewGraphFileIr,
|
|
143
|
-
reviewGraphIrContentHash
|
|
144
|
-
} from "../chunk-LSMJ6KBE.js";
|
|
145
|
-
import {
|
|
146
|
-
buildSymbolId
|
|
147
|
-
} from "../chunk-3MED75HT.js";
|
|
148
|
-
import {
|
|
149
|
-
resolveGitCheckout,
|
|
150
|
-
resolveLinkedWorktreeOwner
|
|
151
|
-
} from "../chunk-3I5QFT3N.js";
|
|
136
|
+
} from "../chunk-XMSXXAHW.js";
|
|
137
|
+
import "../chunk-7DYBLXYA.js";
|
|
152
138
|
import {
|
|
153
139
|
DEPENDENCY_DRIFT_MAX_DELIVERIES,
|
|
154
140
|
MAX_LATE_AUX_REARMS,
|
|
@@ -156,7 +142,7 @@ import {
|
|
|
156
142
|
RUNTIME_CONFIG,
|
|
157
143
|
ReadGuard,
|
|
158
144
|
STALE_LINE_MARKER,
|
|
159
|
-
|
|
145
|
+
SYMBOL_KIND_NAMES,
|
|
160
146
|
Text,
|
|
161
147
|
TreeSitterSymbolExtractor,
|
|
162
148
|
WriteOrderingGuard,
|
|
@@ -171,6 +157,8 @@ import {
|
|
|
171
157
|
beginScope,
|
|
172
158
|
buildScopeKey,
|
|
173
159
|
canRearmPendingAuxiliary,
|
|
160
|
+
canWriteAnalysisRoot,
|
|
161
|
+
captureReviewGraphStructuralIr,
|
|
174
162
|
classifyDiagnosticTier,
|
|
175
163
|
clearAllSessions,
|
|
176
164
|
countRetainedSuppressedRows,
|
|
@@ -184,10 +172,10 @@ import {
|
|
|
184
172
|
drainRenderedDependencyDriftFilePaths,
|
|
185
173
|
exceedsLspSyncLimits,
|
|
186
174
|
findAuxiliaryProfileForSource,
|
|
175
|
+
formatReviewGraphRevisionDriftNote,
|
|
187
176
|
getActiveSessionId,
|
|
188
177
|
getDisposition,
|
|
189
178
|
getFileDiagnosticSummaries,
|
|
190
|
-
getFullScanWallClockMs,
|
|
191
179
|
getLSPService,
|
|
192
180
|
getLspBudgetIdleTimeoutMs,
|
|
193
181
|
getMutationBridge,
|
|
@@ -201,13 +189,13 @@ import {
|
|
|
201
189
|
isBlocking,
|
|
202
190
|
isPendingAuxiliaryPastRearmTtl,
|
|
203
191
|
isWarmAttached,
|
|
204
|
-
isWorkspaceSweepActive,
|
|
205
192
|
loadLspService,
|
|
206
193
|
logBusEvent,
|
|
207
194
|
markWidgetFileBlockersStale,
|
|
208
195
|
newLspMutationCorrelationId,
|
|
209
196
|
nextOrderTurn,
|
|
210
197
|
pendingAuxiliaryCoverageSize,
|
|
198
|
+
publishReviewGraphFileIr,
|
|
211
199
|
rearmPendingAuxiliaryCoverage,
|
|
212
200
|
reconcileCorrelatedScanDiagnostics,
|
|
213
201
|
reconcileScanDiagnostics,
|
|
@@ -230,8 +218,8 @@ import {
|
|
|
230
218
|
retagAuxiliaryDiagnostics,
|
|
231
219
|
retireScope,
|
|
232
220
|
retireWidgetDependencyDriftBlockers,
|
|
221
|
+
reviewGraphIrContentHash,
|
|
233
222
|
runPerServerGroups,
|
|
234
|
-
runWhenWorkspaceSweepIdle,
|
|
235
223
|
scopeCell,
|
|
236
224
|
setSessionLanguages,
|
|
237
225
|
shouldShortenLspIdleTimeout,
|
|
@@ -244,18 +232,25 @@ import {
|
|
|
244
232
|
widgetDiagnosticUri,
|
|
245
233
|
workspaceEditTextPaths,
|
|
246
234
|
writeOrderToken
|
|
247
|
-
} from "../chunk-
|
|
235
|
+
} from "../chunk-PV6LR5P5.js";
|
|
236
|
+
import {
|
|
237
|
+
buildSymbolId
|
|
238
|
+
} from "../chunk-3MED75HT.js";
|
|
248
239
|
import {
|
|
249
240
|
emitBounded,
|
|
250
241
|
resetBoundedTelemetry
|
|
251
|
-
} from "../chunk-
|
|
242
|
+
} from "../chunk-CO2G5PHH.js";
|
|
252
243
|
import {
|
|
253
244
|
hashText,
|
|
254
245
|
normalizeMessage,
|
|
255
246
|
primePersistedMutationAttribution,
|
|
256
247
|
resetMutationAttribution,
|
|
257
248
|
stableFindingId
|
|
258
|
-
} from "../chunk-
|
|
249
|
+
} from "../chunk-IBGIOBEE.js";
|
|
250
|
+
import {
|
|
251
|
+
resolveGitCheckout,
|
|
252
|
+
resolveLinkedWorktreeOwner
|
|
253
|
+
} from "../chunk-PNQDPDRC.js";
|
|
259
254
|
import {
|
|
260
255
|
mapWithConcurrency
|
|
261
256
|
} from "../chunk-XIMYZ3JA.js";
|
|
@@ -264,8 +259,10 @@ import {
|
|
|
264
259
|
customServerSpecsOf,
|
|
265
260
|
describeRootFallback,
|
|
266
261
|
explainServersForFile,
|
|
262
|
+
getAstGrepRuleFingerprint,
|
|
267
263
|
getServersForFileWithConfig,
|
|
268
264
|
initLSPConfig,
|
|
265
|
+
isAuxiliary,
|
|
269
266
|
isSameOrWithin,
|
|
270
267
|
loadLSPConfig,
|
|
271
268
|
lspConfigOf,
|
|
@@ -275,11 +272,26 @@ import {
|
|
|
275
272
|
resetLSPCaseSensitivityState,
|
|
276
273
|
resolveLspCwdForFile,
|
|
277
274
|
shouldInitializeSessionRoot
|
|
278
|
-
} from "../chunk-
|
|
275
|
+
} from "../chunk-ESBQHFMJ.js";
|
|
279
276
|
import {
|
|
280
277
|
hasAmbientPythonEnvironment
|
|
281
|
-
} from "../chunk-
|
|
282
|
-
import "../chunk-
|
|
278
|
+
} from "../chunk-34WSVGEM.js";
|
|
279
|
+
import "../chunk-VWCXW2E7.js";
|
|
280
|
+
import {
|
|
281
|
+
PROJECT_SNAPSHOT_VERSION,
|
|
282
|
+
getProjectSnapshotLegacyPath,
|
|
283
|
+
getProjectSnapshotPath,
|
|
284
|
+
hydrateRuntimeFromProjectSnapshot,
|
|
285
|
+
hydrateRuntimeFromProjectSnapshotIfIdle,
|
|
286
|
+
isProjectSnapshotFresh,
|
|
287
|
+
isProjectSnapshotMetaStale,
|
|
288
|
+
loadProjectSnapshot,
|
|
289
|
+
loadProjectSnapshotExportsAndRules,
|
|
290
|
+
loadProjectSnapshotWithoutWordIndex,
|
|
291
|
+
readJsonCache,
|
|
292
|
+
readProjectSnapshotMeta,
|
|
293
|
+
saveRuntimeProjectSnapshot
|
|
294
|
+
} from "../chunk-ZXYDQ3TZ.js";
|
|
283
295
|
import "../chunk-5W3R6LFT.js";
|
|
284
296
|
import {
|
|
285
297
|
EXT_TO_LANG,
|
|
@@ -293,51 +305,43 @@ import {
|
|
|
293
305
|
queryLoader,
|
|
294
306
|
reportBundledResourceDirHealth,
|
|
295
307
|
resolveTreeSitterLanguage
|
|
296
|
-
} from "../chunk-
|
|
308
|
+
} from "../chunk-QHJ6DQ2R.js";
|
|
297
309
|
import "../chunk-Z54ZSOBZ.js";
|
|
298
310
|
import {
|
|
299
311
|
SCAN_LANGUAGE_PRIORITY,
|
|
300
312
|
extensionsForLanguage,
|
|
301
313
|
extensionsForLanguageToken,
|
|
314
|
+
getUserRuleRoot,
|
|
302
315
|
resolveLanguage
|
|
303
|
-
} from "../chunk-
|
|
316
|
+
} from "../chunk-724UL2TJ.js";
|
|
304
317
|
import {
|
|
305
318
|
dump,
|
|
306
319
|
resolvePackagePath
|
|
307
320
|
} from "../chunk-QOZXJ4NA.js";
|
|
308
|
-
import "../chunk-
|
|
309
|
-
import "../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";
|
|
310
329
|
import {
|
|
311
330
|
HOOK_WALL_BUDGET_MS,
|
|
312
331
|
bounded,
|
|
313
332
|
combineAbortSignals,
|
|
314
333
|
withDeadline
|
|
315
|
-
} from "../chunk-
|
|
316
|
-
import {
|
|
317
|
-
PROJECT_SNAPSHOT_VERSION,
|
|
318
|
-
getProjectSnapshotLegacyPath,
|
|
319
|
-
getProjectSnapshotPath,
|
|
320
|
-
hydrateRuntimeFromProjectSnapshot,
|
|
321
|
-
hydrateRuntimeFromProjectSnapshotIfIdle,
|
|
322
|
-
isProjectSnapshotFresh,
|
|
323
|
-
isProjectSnapshotMetaStale,
|
|
324
|
-
loadProjectSnapshot,
|
|
325
|
-
loadProjectSnapshotExportsAndRules,
|
|
326
|
-
loadProjectSnapshotWithoutWordIndex,
|
|
327
|
-
readJsonCache,
|
|
328
|
-
readProjectSnapshotMeta,
|
|
329
|
-
saveRuntimeProjectSnapshot
|
|
330
|
-
} from "../chunk-AJVLWNFN.js";
|
|
334
|
+
} from "../chunk-52FUZI6K.js";
|
|
331
335
|
import {
|
|
332
336
|
centralityFromReverseDeps,
|
|
333
337
|
getWordIndexBuildStatus,
|
|
334
338
|
logWordIndex,
|
|
335
339
|
searchWordIndex,
|
|
336
340
|
triggerBackgroundWordIndexBuild
|
|
337
|
-
} from "../chunk-
|
|
341
|
+
} from "../chunk-SAEFPSB6.js";
|
|
338
342
|
import {
|
|
339
343
|
getProjectDiagnosticsScannerMaxFiles
|
|
340
|
-
} from "../chunk-
|
|
344
|
+
} from "../chunk-GAEGEPOC.js";
|
|
341
345
|
import {
|
|
342
346
|
PathKeyedMap
|
|
343
347
|
} from "../chunk-Z3CCVDUB.js";
|
|
@@ -350,30 +354,27 @@ import {
|
|
|
350
354
|
readTurnEndStatus,
|
|
351
355
|
resolveRunnerPath,
|
|
352
356
|
toRunnerDisplayPath
|
|
353
|
-
} from "../chunk-
|
|
357
|
+
} from "../chunk-L3BLXZG7.js";
|
|
354
358
|
import "../chunk-2BEMIWEW.js";
|
|
355
359
|
import {
|
|
356
360
|
commitDurableStore,
|
|
357
361
|
resetResolvedPathCache,
|
|
358
362
|
resetZizmorTokenAvailability
|
|
359
|
-
} from "../chunk-
|
|
363
|
+
} from "../chunk-66VMUL7Q.js";
|
|
360
364
|
import {
|
|
361
365
|
resolveToolCwd
|
|
362
|
-
} from "../chunk-
|
|
366
|
+
} from "../chunk-Q7DUK4LX.js";
|
|
363
367
|
import {
|
|
364
368
|
_resetPackageManagerCache,
|
|
365
369
|
findGlobalBinary,
|
|
366
370
|
pmBinary,
|
|
367
371
|
resolveNodePackageManager,
|
|
368
372
|
runScriptArgs
|
|
369
|
-
} from "../chunk-
|
|
370
|
-
import {
|
|
371
|
-
isToolInstallAllowedByTrust,
|
|
372
|
-
projectTrustDenialReason
|
|
373
|
-
} from "../chunk-NTUJEGDZ.js";
|
|
373
|
+
} from "../chunk-AW7R2GWG.js";
|
|
374
374
|
import {
|
|
375
|
+
getIsolatedNpxSpawnOptions,
|
|
375
376
|
probeToolAsync
|
|
376
|
-
} from "../chunk-
|
|
377
|
+
} from "../chunk-RWWYJ623.js";
|
|
377
378
|
import {
|
|
378
379
|
classifyProbeFailure,
|
|
379
380
|
createAvailabilityLatch,
|
|
@@ -381,20 +382,20 @@ import {
|
|
|
381
382
|
logAvailabilityDecision,
|
|
382
383
|
resetInstallRetryLatches,
|
|
383
384
|
startHostStallSampler
|
|
384
|
-
} from "../chunk-
|
|
385
|
+
} from "../chunk-VRZP76YM.js";
|
|
385
386
|
import {
|
|
386
387
|
canRunStartupHeavyScans,
|
|
387
388
|
detectProjectLanguageProfile,
|
|
388
389
|
getDefaultStartupTools
|
|
389
|
-
} from "../chunk-
|
|
390
|
-
import "../chunk-
|
|
390
|
+
} from "../chunk-QOBUHWHX.js";
|
|
391
|
+
import "../chunk-QILIYSJF.js";
|
|
391
392
|
import {
|
|
392
393
|
collectSourceFilesWithBudgetAsync,
|
|
393
394
|
getSlowFsVerdict,
|
|
394
395
|
isSlowFs,
|
|
395
396
|
slowFsDegradationNotice
|
|
396
|
-
} from "../chunk-
|
|
397
|
-
import "../chunk-
|
|
397
|
+
} from "../chunk-6C7JWPCP.js";
|
|
398
|
+
import "../chunk-5NGR67U5.js";
|
|
398
399
|
import {
|
|
399
400
|
displayProjectDataPath,
|
|
400
401
|
drainProjectDataDirMigrations,
|
|
@@ -421,7 +422,7 @@ import {
|
|
|
421
422
|
sweepDeadEphemeralDataDirs,
|
|
422
423
|
updateHeartbeat,
|
|
423
424
|
withGenerationLockSync
|
|
424
|
-
} from "../chunk-
|
|
425
|
+
} from "../chunk-C34ZXZ7O.js";
|
|
425
426
|
import {
|
|
426
427
|
createSingleFlight
|
|
427
428
|
} from "../chunk-BW5KFIQC.js";
|
|
@@ -431,7 +432,7 @@ import {
|
|
|
431
432
|
} from "../chunk-QYF5S6P6.js";
|
|
432
433
|
import {
|
|
433
434
|
detectFileKind
|
|
434
|
-
} from "../chunk-
|
|
435
|
+
} from "../chunk-PHDMFAKM.js";
|
|
435
436
|
import {
|
|
436
437
|
compareKeys,
|
|
437
438
|
detectFileRole,
|
|
@@ -441,12 +442,18 @@ import {
|
|
|
441
442
|
provenanceView,
|
|
442
443
|
resolvePiLensConfig,
|
|
443
444
|
summarizeConfigResolution
|
|
444
|
-
} from "../chunk-
|
|
445
|
+
} from "../chunk-2BBLFX75.js";
|
|
445
446
|
import {
|
|
446
447
|
LSP_NAMESPACE_KEY,
|
|
447
448
|
getPiLensGlobalConfigPath,
|
|
448
449
|
resetWorkspaceTopology
|
|
449
|
-
} from "../chunk-
|
|
450
|
+
} from "../chunk-XVF2VVXP.js";
|
|
451
|
+
import {
|
|
452
|
+
getProjectTrustState,
|
|
453
|
+
isToolInstallAllowedByTrust,
|
|
454
|
+
projectTrustDenialReason,
|
|
455
|
+
setProjectTrustState
|
|
456
|
+
} from "../chunk-ZANLILYD.js";
|
|
450
457
|
import {
|
|
451
458
|
DEFAULT_MAX_OUTPUT_BYTES,
|
|
452
459
|
createBoundedOutputSink,
|
|
@@ -467,28 +474,30 @@ import {
|
|
|
467
474
|
resolveLensToolEnabled,
|
|
468
475
|
resolveLensToolName,
|
|
469
476
|
toolRegistryEntryForMcp
|
|
470
|
-
} from "../chunk-
|
|
477
|
+
} from "../chunk-JAU72XNY.js";
|
|
471
478
|
import {
|
|
472
479
|
createSubsystemLogger,
|
|
473
480
|
flushExtensionLog,
|
|
474
481
|
logExtension
|
|
475
|
-
} from "../chunk-
|
|
482
|
+
} from "../chunk-XTMJ7XDT.js";
|
|
483
|
+
import "../chunk-JMYYOTQG.js";
|
|
476
484
|
import {
|
|
477
485
|
claimPhaseOncePerSession,
|
|
478
486
|
logLatency
|
|
479
|
-
} from "../chunk-
|
|
487
|
+
} from "../chunk-QQNQ7SJW.js";
|
|
480
488
|
import {
|
|
481
489
|
beginTurnContext,
|
|
482
490
|
createNdjsonLogger,
|
|
483
491
|
getGlobalPiLensLogDir,
|
|
492
|
+
getProcessSingleton,
|
|
484
493
|
isTestMode,
|
|
485
494
|
runLogCleanup,
|
|
486
495
|
setTurnContextSession
|
|
487
|
-
} from "../chunk-
|
|
496
|
+
} from "../chunk-AOHZU2BM.js";
|
|
488
497
|
import "../chunk-LJDODBBZ.js";
|
|
489
498
|
import {
|
|
490
499
|
FactStore
|
|
491
|
-
} from "../chunk-
|
|
500
|
+
} from "../chunk-CHOW74WE.js";
|
|
492
501
|
import {
|
|
493
502
|
BoundedFifoMap,
|
|
494
503
|
BoundedLruCache
|
|
@@ -503,15 +512,16 @@ import {
|
|
|
503
512
|
normalizeMapKey,
|
|
504
513
|
pathsEqual,
|
|
505
514
|
realpathOrResolve,
|
|
515
|
+
resolveHostToolPath,
|
|
506
516
|
toProjectRelativePath,
|
|
507
517
|
uriToPath
|
|
508
|
-
} from "../chunk-
|
|
518
|
+
} from "../chunk-N2H3ZPZY.js";
|
|
509
519
|
import "../chunk-NXL4FFQQ.js";
|
|
510
520
|
|
|
511
521
|
// dist/mcp/server.js
|
|
512
522
|
import * as fs25 from "node:fs";
|
|
513
523
|
import * as net from "node:net";
|
|
514
|
-
import * as
|
|
524
|
+
import * as path39 from "node:path";
|
|
515
525
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
516
526
|
|
|
517
527
|
// dist/tools/render-compact.js
|
|
@@ -821,37 +831,59 @@ function checkAstGrepRulesHealth(ruleDir) {
|
|
|
821
831
|
var AstGrepRuleManager = class {
|
|
822
832
|
ruleDir;
|
|
823
833
|
log;
|
|
834
|
+
fingerprint;
|
|
824
835
|
ruleDescriptions = null;
|
|
825
|
-
|
|
836
|
+
ruleFingerprint = null;
|
|
837
|
+
constructor(ruleDir, log, fingerprint = () => getAstGrepRuleFingerprint()) {
|
|
826
838
|
this.ruleDir = ruleDir;
|
|
827
839
|
this.log = log;
|
|
840
|
+
this.fingerprint = fingerprint;
|
|
828
841
|
}
|
|
829
842
|
loadRuleDescriptions() {
|
|
830
|
-
|
|
843
|
+
const fingerprint = this.fingerprint();
|
|
844
|
+
if (this.ruleDescriptions !== null && this.ruleFingerprint === fingerprint)
|
|
831
845
|
return this.ruleDescriptions;
|
|
832
846
|
const descriptions = /* @__PURE__ */ new Map();
|
|
833
|
-
const
|
|
834
|
-
const
|
|
847
|
+
const roots = Array.isArray(this.ruleDir) ? this.ruleDir : [this.ruleDir];
|
|
848
|
+
const possiblePaths = roots.flatMap(candidateAstGrepRulesPaths);
|
|
849
|
+
const rulesPaths = [];
|
|
850
|
+
if (Array.isArray(this.ruleDir)) {
|
|
851
|
+
for (const candidate of possiblePaths) {
|
|
852
|
+
if (fs2.existsSync(candidate))
|
|
853
|
+
rulesPaths.push(candidate);
|
|
854
|
+
}
|
|
855
|
+
} else {
|
|
856
|
+
for (const candidate of possiblePaths) {
|
|
857
|
+
if (!fs2.existsSync(candidate))
|
|
858
|
+
continue;
|
|
859
|
+
rulesPaths.push(candidate);
|
|
860
|
+
break;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const rulesPath = rulesPaths[0];
|
|
835
864
|
if (!rulesPath) {
|
|
836
865
|
this.log(`Rule descriptions: no rules directory found in ${possiblePaths.join(", ")}`);
|
|
837
866
|
this.ruleDescriptions = descriptions;
|
|
867
|
+
this.ruleFingerprint = fingerprint;
|
|
838
868
|
return descriptions;
|
|
839
869
|
}
|
|
840
870
|
try {
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
descriptions.
|
|
871
|
+
for (const resolvedPath of rulesPaths) {
|
|
872
|
+
const files = fs2.readdirSync(resolvedPath).filter((f) => f.endsWith(".yml"));
|
|
873
|
+
this.log(`Loaded ${files.length} rule descriptions from ${resolvedPath}`);
|
|
874
|
+
for (const file of files) {
|
|
875
|
+
const filePath = path2.join(resolvedPath, file);
|
|
876
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
877
|
+
const rule = this.parseRuleYaml(content);
|
|
878
|
+
if (rule && !descriptions.has(rule.id))
|
|
879
|
+
descriptions.set(rule.id, rule);
|
|
849
880
|
}
|
|
850
881
|
}
|
|
851
882
|
} catch (err) {
|
|
852
883
|
this.log(`Failed to load rule descriptions: ${err.message}`);
|
|
853
884
|
}
|
|
854
885
|
this.ruleDescriptions = descriptions;
|
|
886
|
+
this.ruleFingerprint = fingerprint;
|
|
855
887
|
return descriptions;
|
|
856
888
|
}
|
|
857
889
|
parseRuleYaml(content) {
|
|
@@ -953,6 +985,7 @@ var SgRunner = class {
|
|
|
953
985
|
log;
|
|
954
986
|
sgPath = null;
|
|
955
987
|
sgArgsPrefix = [];
|
|
988
|
+
sgSpawnOptions;
|
|
956
989
|
/**
|
|
957
990
|
* Availability memo, backed by the shared transient-aware latch (#1476).
|
|
958
991
|
*
|
|
@@ -1034,17 +1067,25 @@ var SgRunner = class {
|
|
|
1034
1067
|
this.sweepFallbackCause = "probe-timeout";
|
|
1035
1068
|
this.sweepHostStallMs = 0;
|
|
1036
1069
|
this.sweepDurablyMissing = [];
|
|
1070
|
+
const trustedProject = getProjectTrustState() === "trusted";
|
|
1037
1071
|
const pathCommand = await this.probeCommandCandidates([
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1072
|
+
...trustedProject ? [
|
|
1073
|
+
{ cmd: "ast-grep", argsPrefix: [] },
|
|
1074
|
+
{ cmd: "sg", argsPrefix: [] }
|
|
1075
|
+
] : [],
|
|
1076
|
+
// The scoped npx fallback starts a Node process before it can answer, so
|
|
1041
1077
|
// it is the candidate most likely to blow a 5 s budget on a cold or busy
|
|
1042
1078
|
// box. Marked a fallback so its timeout cannot veto the install.
|
|
1043
|
-
{
|
|
1079
|
+
{
|
|
1080
|
+
cmd: "npx",
|
|
1081
|
+
argsPrefix: ["--no", "--package", "@ast-grep/cli", "--", "ast-grep"],
|
|
1082
|
+
fallback: true
|
|
1083
|
+
}
|
|
1044
1084
|
]);
|
|
1045
1085
|
if (pathCommand) {
|
|
1046
1086
|
this.sgPath = pathCommand.cmd;
|
|
1047
1087
|
this.sgArgsPrefix = pathCommand.argsPrefix;
|
|
1088
|
+
this.sgSpawnOptions = pathCommand.cmd === "npx" ? getIsolatedNpxSpawnOptions() : void 0;
|
|
1048
1089
|
this.noteAvailable(startedAt, `ast-grep found on PATH: ${pathCommand.cmd}`);
|
|
1049
1090
|
return true;
|
|
1050
1091
|
}
|
|
@@ -1057,7 +1098,7 @@ var SgRunner = class {
|
|
|
1057
1098
|
return true;
|
|
1058
1099
|
}
|
|
1059
1100
|
}
|
|
1060
|
-
const platformBinary = await this.probePlatformPackageBinary();
|
|
1101
|
+
const platformBinary = trustedProject ? await this.probePlatformPackageBinary() : void 0;
|
|
1061
1102
|
if (platformBinary) {
|
|
1062
1103
|
this.sgPath = platformBinary;
|
|
1063
1104
|
this.sgArgsPrefix = [];
|
|
@@ -1090,6 +1131,7 @@ var SgRunner = class {
|
|
|
1090
1131
|
if (installed.outcome === "success") {
|
|
1091
1132
|
this.sgPath = installed.value;
|
|
1092
1133
|
this.sgArgsPrefix = [];
|
|
1134
|
+
this.sgSpawnOptions = void 0;
|
|
1093
1135
|
this.noteAvailable(startedAt, `ast-grep auto-installed: ${installed.value}`);
|
|
1094
1136
|
return true;
|
|
1095
1137
|
}
|
|
@@ -1109,7 +1151,7 @@ var SgRunner = class {
|
|
|
1109
1151
|
* sweep already asked, and the sweep returns at the first one that answers,
|
|
1110
1152
|
* so at this point the flag means "a tier the winner is supposed to lose to
|
|
1111
1153
|
* never got a fair hearing". Latching that pinned the session to
|
|
1112
|
-
* `npx
|
|
1154
|
+
* `npx` — a Node start per invocation — over a healthy
|
|
1113
1155
|
* ast-grep on PATH, until the next restart. Provisional instead: served now,
|
|
1114
1156
|
* re-swept once the stalled tier's cooldown expires.
|
|
1115
1157
|
*
|
|
@@ -1252,7 +1294,10 @@ var SgRunner = class {
|
|
|
1252
1294
|
let result;
|
|
1253
1295
|
let hostStallMs;
|
|
1254
1296
|
try {
|
|
1255
|
-
result = await
|
|
1297
|
+
result = cmd === "npx" ? await safeSpawnAsync(cmd, [...argsPrefix, "--version"], {
|
|
1298
|
+
...getIsolatedNpxSpawnOptions(),
|
|
1299
|
+
timeout: PROBE_TIMEOUT_MS
|
|
1300
|
+
}) : await probeToolAsync(cmd, [...argsPrefix, "--version"], {
|
|
1256
1301
|
timeout: PROBE_TIMEOUT_MS
|
|
1257
1302
|
});
|
|
1258
1303
|
} finally {
|
|
@@ -1339,6 +1384,7 @@ Original error: ${stderr}`;
|
|
|
1339
1384
|
async execRaw(args, timeout = DEFAULT_EXEC_TIMEOUT_MS, options = {}) {
|
|
1340
1385
|
const command = this.getSgCommand();
|
|
1341
1386
|
const result = await safeSpawnAsync(command.cmd, [...command.argsPrefix, ...args], {
|
|
1387
|
+
...this.sgSpawnOptions,
|
|
1342
1388
|
timeout,
|
|
1343
1389
|
deadlineAt: options.deadlineAt,
|
|
1344
1390
|
signal: options.signal,
|
|
@@ -1367,6 +1413,7 @@ Original error: ${stderr}`;
|
|
|
1367
1413
|
const hasBash = Boolean(process.env.MSYSTEM || process.env.GIT_SHELL);
|
|
1368
1414
|
const useBash = isWindows && hasBash;
|
|
1369
1415
|
const result = await safeSpawnAsync(useBash ? "bash" : command.cmd, useBash ? buildBashRunArgs(command.cmd, allArgs) : allArgs, {
|
|
1416
|
+
...this.sgSpawnOptions,
|
|
1370
1417
|
timeout: DEFAULT_EXEC_TIMEOUT_MS,
|
|
1371
1418
|
deadlineAt: options.deadlineAt,
|
|
1372
1419
|
signal: options.signal,
|
|
@@ -1515,6 +1562,7 @@ Original error: ${stderr}`;
|
|
|
1515
1562
|
...sgExcludeArgsForProject(dir),
|
|
1516
1563
|
dir
|
|
1517
1564
|
], {
|
|
1565
|
+
...sgCmd === "npx" ? getIsolatedNpxSpawnOptions() : {},
|
|
1518
1566
|
timeout,
|
|
1519
1567
|
deadlineAt: options.deadlineAt,
|
|
1520
1568
|
signal: options.signal,
|
|
@@ -1552,6 +1600,7 @@ Original error: ${stderr}`;
|
|
|
1552
1600
|
dir
|
|
1553
1601
|
];
|
|
1554
1602
|
const spawnOptions = {
|
|
1603
|
+
...sgCmd === "npx" ? getIsolatedNpxSpawnOptions() : {},
|
|
1555
1604
|
timeout,
|
|
1556
1605
|
deadlineAt: options.deadlineAt,
|
|
1557
1606
|
signal: options.signal,
|
|
@@ -1641,7 +1690,7 @@ function reportAstGrepRulesHealth(bundledRuleDir) {
|
|
|
1641
1690
|
});
|
|
1642
1691
|
reportBundledResourceDirHealth("ast-grep-rules-dir-missing", bundledRuleDir, health, "ast-grep rule descriptions");
|
|
1643
1692
|
}
|
|
1644
|
-
function recordAstGrepApply(matches, lineage) {
|
|
1693
|
+
function recordAstGrepApply(matches, lineage, toolCallId) {
|
|
1645
1694
|
const bridge = getMutationBridge();
|
|
1646
1695
|
if (!bridge || matches.length === 0)
|
|
1647
1696
|
return;
|
|
@@ -1657,13 +1706,22 @@ function recordAstGrepApply(matches, lineage) {
|
|
|
1657
1706
|
}
|
|
1658
1707
|
for (const [filePath, editRanges] of rangesByFile) {
|
|
1659
1708
|
bridge.recordMutation({
|
|
1660
|
-
|
|
1709
|
+
// ast-grep echoes the spelling passed to its CLI. Resolve that
|
|
1710
|
+
// tool-relative spelling at the producer boundary, then use the
|
|
1711
|
+
// existing canonical path seam before recordability is checked (#4140).
|
|
1712
|
+
filePath: normalizeFilePath(path4.resolve(process.cwd(), filePath)),
|
|
1661
1713
|
kind: "edit",
|
|
1662
1714
|
editRanges,
|
|
1663
1715
|
consumer: "ast_grep_replace",
|
|
1716
|
+
provenance: "observed",
|
|
1664
1717
|
// #3763: the call's session, so an apply that lands after `/new`
|
|
1665
1718
|
// writes none of the next session's state.
|
|
1666
|
-
...lineage && { lineage }
|
|
1719
|
+
...lineage && { lineage },
|
|
1720
|
+
// #4187 R4-1: the apply rewrites every matched file, which an
|
|
1721
|
+
// `ast_grep_replace` call names only when its `paths` are files. The
|
|
1722
|
+
// call's own id lets the guard advance exactly the paths that call
|
|
1723
|
+
// checked, and end the authorship of every other file it rewrote.
|
|
1724
|
+
...toolCallId !== void 0 && { toolCallId }
|
|
1667
1725
|
});
|
|
1668
1726
|
}
|
|
1669
1727
|
}
|
|
@@ -1732,6 +1790,9 @@ function validateInputShape(value, maxChars, label) {
|
|
|
1732
1790
|
}
|
|
1733
1791
|
return void 0;
|
|
1734
1792
|
}
|
|
1793
|
+
function extractRuleLanguage(ruleYaml) {
|
|
1794
|
+
return /^[^\S\n\r\u2028\u2029]*language:\s*([^\s#]+)/im.exec(ruleYaml)?.[1];
|
|
1795
|
+
}
|
|
1735
1796
|
function stderrHasError(stderr) {
|
|
1736
1797
|
return stderr.split(/\r?\n/).some((line) => /^\s*(error|Error):/.test(line));
|
|
1737
1798
|
}
|
|
@@ -1766,7 +1827,7 @@ var AstGrepClient = class {
|
|
|
1766
1827
|
this.log = verbose ? createSubsystemLogger("ast-grep") : () => {
|
|
1767
1828
|
};
|
|
1768
1829
|
this.ensureRulesHealthReported();
|
|
1769
|
-
this.ruleManager = new AstGrepRuleManager(this.ruleDir, this.log);
|
|
1830
|
+
this.ruleManager = new AstGrepRuleManager(ruleDir ? this.ruleDir : [projectRuleDir, getUserRuleRoot(), this.ruleDir], this.log, () => getAstGrepRuleFingerprint(process.cwd()));
|
|
1770
1831
|
this.runner = new SgRunner(verbose);
|
|
1771
1832
|
}
|
|
1772
1833
|
/**
|
|
@@ -1810,7 +1871,7 @@ var AstGrepClient = class {
|
|
|
1810
1871
|
* Replace using a raw YAML rule that includes a `fix:` field (Phase 3/4 of #125).
|
|
1811
1872
|
* Dry-run returns matches for preview; apply writes fixes to disk.
|
|
1812
1873
|
*/
|
|
1813
|
-
async replaceWithRule(ruleYaml, paths, apply) {
|
|
1874
|
+
async replaceWithRule(ruleYaml, paths, apply, options) {
|
|
1814
1875
|
const allMatches = [];
|
|
1815
1876
|
for (const scanPath of paths) {
|
|
1816
1877
|
if (apply) {
|
|
@@ -1843,6 +1904,8 @@ var AstGrepClient = class {
|
|
|
1843
1904
|
}
|
|
1844
1905
|
allMatches.push(...result.matches);
|
|
1845
1906
|
}
|
|
1907
|
+
if (apply)
|
|
1908
|
+
recordAstGrepApply(allMatches, options?.lineage, options?.toolCallId);
|
|
1846
1909
|
return {
|
|
1847
1910
|
matches: allMatches,
|
|
1848
1911
|
totalMatches: allMatches.length,
|
|
@@ -1964,7 +2027,7 @@ var AstGrepClient = class {
|
|
|
1964
2027
|
const shapeError = validateInputShape(ruleYaml, MAX_VALIDATE_RULE_CHARS, "rule");
|
|
1965
2028
|
if (shapeError)
|
|
1966
2029
|
return { valid: false, error: shapeError };
|
|
1967
|
-
const language =
|
|
2030
|
+
const language = extractRuleLanguage(ruleYaml) ?? "typescript";
|
|
1968
2031
|
const snippet = validationSnippetFor(language);
|
|
1969
2032
|
const tmpDir = fs4.mkdtempSync(path4.join(os2.tmpdir(), "pi-lens-sg-rule-"));
|
|
1970
2033
|
try {
|
|
@@ -2109,7 +2172,7 @@ var AstGrepClient = class {
|
|
|
2109
2172
|
error: applyResult.error
|
|
2110
2173
|
};
|
|
2111
2174
|
}
|
|
2112
|
-
recordAstGrepApply(preCheck.matches, options?.lineage);
|
|
2175
|
+
recordAstGrepApply(preCheck.matches, options?.lineage, options?.toolCallId);
|
|
2113
2176
|
return {
|
|
2114
2177
|
matches: preCheck.matches,
|
|
2115
2178
|
totalMatches: preCheck.totalMatches,
|
|
@@ -2239,7 +2302,7 @@ message: found
|
|
|
2239
2302
|
};
|
|
2240
2303
|
|
|
2241
2304
|
// dist/clients/lens-engine.js
|
|
2242
|
-
import * as
|
|
2305
|
+
import * as path29 from "node:path";
|
|
2243
2306
|
|
|
2244
2307
|
// dist/clients/project-diagnostics/scanner.js
|
|
2245
2308
|
import * as fs6 from "node:fs";
|
|
@@ -2686,7 +2749,7 @@ function resolveRebuildScript(serverFilePath) {
|
|
|
2686
2749
|
return serverFilePath.replace(/\\/g, "/").includes("/dist/") ? "build:dist" : "build";
|
|
2687
2750
|
}
|
|
2688
2751
|
function analyzeFileFresh(workerPath, file, cwd, options = {}, timeoutMs = 12e4) {
|
|
2689
|
-
return new Promise((
|
|
2752
|
+
return new Promise((resolve32) => {
|
|
2690
2753
|
const args = [workerPath, `--file=${file}`, `--cwd=${cwd}`];
|
|
2691
2754
|
if (options.flags)
|
|
2692
2755
|
args.push(`--flags=${JSON.stringify(options.flags)}`);
|
|
@@ -2696,7 +2759,7 @@ function analyzeFileFresh(workerPath, file, cwd, options = {}, timeoutMs = 12e4)
|
|
|
2696
2759
|
stdio: ["ignore", "pipe", "pipe"]
|
|
2697
2760
|
});
|
|
2698
2761
|
} catch (err) {
|
|
2699
|
-
|
|
2762
|
+
resolve32({
|
|
2700
2763
|
error: `failed to fork worker: ${err instanceof Error ? err.message : String(err)}`
|
|
2701
2764
|
});
|
|
2702
2765
|
return;
|
|
@@ -2709,7 +2772,7 @@ function analyzeFileFresh(workerPath, file, cwd, options = {}, timeoutMs = 12e4)
|
|
|
2709
2772
|
return;
|
|
2710
2773
|
settled = true;
|
|
2711
2774
|
clearTimeout(timer);
|
|
2712
|
-
|
|
2775
|
+
resolve32(outcome);
|
|
2713
2776
|
};
|
|
2714
2777
|
const timer = setTimeout(() => {
|
|
2715
2778
|
child.kill();
|
|
@@ -2817,7 +2880,7 @@ function summarizeScan(diagnostics) {
|
|
|
2817
2880
|
// dist/clients/mcp/session.js
|
|
2818
2881
|
import * as crypto from "node:crypto";
|
|
2819
2882
|
import * as fs18 from "node:fs";
|
|
2820
|
-
import * as
|
|
2883
|
+
import * as path25 from "node:path";
|
|
2821
2884
|
|
|
2822
2885
|
// dist/clients/bootstrap.js
|
|
2823
2886
|
var residentClients = null;
|
|
@@ -2874,29 +2937,29 @@ async function buildBootstrapClients() {
|
|
|
2874
2937
|
}
|
|
2875
2938
|
}
|
|
2876
2939
|
const [ruffClient, biomeClient, knipClient, todoScanner, jscpdClient, depChecker, testRunnerClient, metricsClient, complexityClient, goClient, govulncheckClient, gitleaksClient, trivyClient, opengrepClient, rustClient, agentBehaviorClient2, deadCodeClients] = await Promise.all([
|
|
2877
|
-
load("ruff", async () => new (await import("../chunk-
|
|
2878
|
-
load("biome", async () => new (await import("../chunk-
|
|
2879
|
-
load("knip", async () => new (await import("../chunk-
|
|
2880
|
-
load("todo", async () => new (await import("../chunk-
|
|
2881
|
-
load("jscpd", async () => new (await import("../chunk-
|
|
2882
|
-
load("dependency-checker", async () => new (await import("../chunk-
|
|
2883
|
-
load("test-runner", async () => new (await import("../chunk-
|
|
2884
|
-
load("metrics", async () => new (await import("../chunk-
|
|
2885
|
-
load("complexity", async () => new (await import("../chunk-
|
|
2940
|
+
load("ruff", async () => new (await import("../chunk-PFNSLWU5.js")).RuffClient()),
|
|
2941
|
+
load("biome", async () => new (await import("../chunk-QZVW3AAK.js")).BiomeClient()),
|
|
2942
|
+
load("knip", async () => new (await import("../chunk-7ULNCDCO.js")).KnipClient()),
|
|
2943
|
+
load("todo", async () => new (await import("../chunk-JSQFTSC6.js")).TodoScanner()),
|
|
2944
|
+
load("jscpd", async () => new (await import("../chunk-3UUPUE3O.js")).JscpdClient()),
|
|
2945
|
+
load("dependency-checker", async () => new (await import("../chunk-3WA4HP4I.js")).DependencyChecker()),
|
|
2946
|
+
load("test-runner", async () => new (await import("../chunk-Q6ZWTCLY.js")).TestRunnerClient()),
|
|
2947
|
+
load("metrics", async () => new (await import("../chunk-N3X6Q4YT.js")).MetricsClient()),
|
|
2948
|
+
load("complexity", async () => new (await import("../chunk-VSSBEUFT.js")).ComplexityClient()),
|
|
2886
2949
|
// The process-wide singleton, NOT a fresh instance (#2455 fix round 4,
|
|
2887
2950
|
// F2). `handleSessionStart` reads this object for its "Active tools"
|
|
2888
2951
|
// line while `resetGoAvailability` re-arms the singleton's latch; a
|
|
2889
2952
|
// second instance here meant the reset never reached the surface a
|
|
2890
2953
|
// user actually sees.
|
|
2891
|
-
load("go", async () => (await import("../chunk-
|
|
2892
|
-
load("govulncheck", async () => new (await import("../chunk-
|
|
2893
|
-
load("gitleaks", async () => new (await import("../chunk-
|
|
2894
|
-
load("trivy", async () => new (await import("../chunk-
|
|
2895
|
-
load("opengrep", async () => new (await import("../chunk-
|
|
2954
|
+
load("go", async () => (await import("../chunk-Z527N6YQ.js")).goClient),
|
|
2955
|
+
load("govulncheck", async () => new (await import("../chunk-XPZPXCBV.js")).GovulncheckClient()),
|
|
2956
|
+
load("gitleaks", async () => new (await import("../chunk-WOKKRCJ5.js")).GitleaksClient()),
|
|
2957
|
+
load("trivy", async () => new (await import("../chunk-IBRALRBR.js")).TrivyClient()),
|
|
2958
|
+
load("opengrep", async () => new (await import("../chunk-XKIZ2HNN.js")).OpengrepClient()),
|
|
2896
2959
|
// The process-wide singleton, for the same reason as "go" above.
|
|
2897
|
-
load("rust", async () => (await import("../chunk-
|
|
2898
|
-
load("agent-behavior", async () => (await import("../chunk-
|
|
2899
|
-
loadList("dead-code", async () => (await import("../chunk-
|
|
2960
|
+
load("rust", async () => (await import("../chunk-BRGDSBJE.js")).rustClient),
|
|
2961
|
+
load("agent-behavior", async () => (await import("../chunk-23WOO7TX.js")).agentBehaviorClient),
|
|
2962
|
+
loadList("dead-code", async () => (await import("../chunk-NW7BOILN.js")).getDeadCodeClients())
|
|
2900
2963
|
]);
|
|
2901
2964
|
if (failures.length > 0)
|
|
2902
2965
|
await logBootstrapFailures(failures);
|
|
@@ -2983,7 +3046,7 @@ function resetAnalyzerBootstrapSessionState() {
|
|
|
2983
3046
|
}
|
|
2984
3047
|
|
|
2985
3048
|
// dist/clients/formatters-lazy.js
|
|
2986
|
-
var lazyFormatters = createLazyImport(() => import("../chunk-
|
|
3049
|
+
var lazyFormatters = createLazyImport(() => import("../chunk-GHB6AYCP.js"));
|
|
2987
3050
|
function warmFormatters() {
|
|
2988
3051
|
return lazyFormatters.get();
|
|
2989
3052
|
}
|
|
@@ -3332,6 +3395,13 @@ function deriveProviderFromModelId(modelId) {
|
|
|
3332
3395
|
|
|
3333
3396
|
// dist/clients/runtime-coordinator.js
|
|
3334
3397
|
var MAX_PENDING_CASCADE_RUNS = 32;
|
|
3398
|
+
function nextTelemetrySessionId() {
|
|
3399
|
+
const state = getProcessSingleton("runtime-coordinator-telemetry", 1, () => ({
|
|
3400
|
+
processId: randomBytes(6).toString("hex"),
|
|
3401
|
+
nextGeneration: 0
|
|
3402
|
+
}));
|
|
3403
|
+
return `lens-${state.processId}-${++state.nextGeneration}`;
|
|
3404
|
+
}
|
|
3335
3405
|
var MAX_CUT_ADVISORY_LANES = 16;
|
|
3336
3406
|
var MAX_MUTATION_RECEIPTS = 512;
|
|
3337
3407
|
function recordViewIncomplete(cwd, cause) {
|
|
@@ -3403,7 +3473,8 @@ var RuntimeCoordinator = class {
|
|
|
3403
3473
|
rules: [],
|
|
3404
3474
|
hasCustomRules: false
|
|
3405
3475
|
};
|
|
3406
|
-
|
|
3476
|
+
/** Process-unique and monotonic across coordinator reloads (#4213). */
|
|
3477
|
+
_telemetrySessionId = nextTelemetrySessionId();
|
|
3407
3478
|
_lifecycleReason;
|
|
3408
3479
|
_hasStableSessionId = false;
|
|
3409
3480
|
_telemetryModel = "unknown";
|
|
@@ -3472,9 +3543,10 @@ var RuntimeCoordinator = class {
|
|
|
3472
3543
|
/** tool_call → tool_result path-attribution correlation (#1642). */
|
|
3473
3544
|
_toolCallAttributions = new BoundedLruCache(TOOL_CALL_ATTRIBUTION_CAPACITY);
|
|
3474
3545
|
/**
|
|
3475
|
-
* #3555:
|
|
3476
|
-
*
|
|
3477
|
-
*
|
|
3546
|
+
* #3555: a widening rides its own correlation, with the same bound. Since
|
|
3547
|
+
* #4138 a read also carries a {@link ToolCallAttribution} (its origin cwd
|
|
3548
|
+
* is what a relative read path resolves against at tool_result); the
|
|
3549
|
+
* widening stays separate because it outlives a blocked call's attribution.
|
|
3478
3550
|
*/
|
|
3479
3551
|
_readWidenings = new BoundedLruCache(TOOL_CALL_ATTRIBUTION_CAPACITY);
|
|
3480
3552
|
_lspReadWarmState = /* @__PURE__ */ new Map();
|
|
@@ -3543,7 +3615,7 @@ var RuntimeCoordinator = class {
|
|
|
3543
3615
|
this._droppedMutationReceipts = 0;
|
|
3544
3616
|
this._actionableWarningsThisTurn.clear(this._telemetrySessionId);
|
|
3545
3617
|
this._codeQualityWarningsThisTurn.clear(this._telemetrySessionId);
|
|
3546
|
-
this._telemetrySessionId =
|
|
3618
|
+
this._telemetrySessionId = nextTelemetrySessionId();
|
|
3547
3619
|
this._hasStableSessionId = false;
|
|
3548
3620
|
this._telemetryModel = "unknown";
|
|
3549
3621
|
this._telemetryModelId = "";
|
|
@@ -4013,7 +4085,9 @@ var RuntimeCoordinator = class {
|
|
|
4013
4085
|
* session; it is therefore required. `filePath` is the edited file the
|
|
4014
4086
|
* compute belongs to, the subject of a dropped admission's ledger row.
|
|
4015
4087
|
*/
|
|
4016
|
-
appendCascadePromise(p, generation, filePath) {
|
|
4088
|
+
appendCascadePromise(p, generation, filePath, analysisRootMode = "session") {
|
|
4089
|
+
if (!canWriteAnalysisRoot(analysisRootMode))
|
|
4090
|
+
return;
|
|
4017
4091
|
if (generation.guardedWrite(filePath, () => true) === void 0)
|
|
4018
4092
|
return;
|
|
4019
4093
|
if (this._pendingCascadeRuns.length < MAX_PENDING_CASCADE_RUNS) {
|
|
@@ -4075,8 +4149,8 @@ var RuntimeCoordinator = class {
|
|
|
4075
4149
|
});
|
|
4076
4150
|
return entry;
|
|
4077
4151
|
});
|
|
4078
|
-
const timeout = new Promise((
|
|
4079
|
-
setTimeout(
|
|
4152
|
+
const timeout = new Promise((resolve32) => {
|
|
4153
|
+
setTimeout(resolve32, maxWaitMs).unref?.();
|
|
4080
4154
|
});
|
|
4081
4155
|
await Promise.race([
|
|
4082
4156
|
Promise.allSettled(tracked.map((t) => t.promise)),
|
|
@@ -4782,7 +4856,9 @@ var RuntimeCoordinator = class {
|
|
|
4782
4856
|
* for a same-kind re-touch. Callers publish each kind's first transition
|
|
4783
4857
|
* without spamming repeated edits before `agent_end`.
|
|
4784
4858
|
*/
|
|
4785
|
-
deferMutation(filePath, cwd, toolName, turnStateCwd, kind, ownerSessionId, originCwd, readGuardBranchEpoch = this.readGuard.currentBranchEpoch) {
|
|
4859
|
+
deferMutation(filePath, cwd, toolName, turnStateCwd, kind, ownerSessionId, originCwd, readGuardBranchEpoch = this.readGuard.currentBranchEpoch, analysisRootMode = "session") {
|
|
4860
|
+
if (!canWriteAnalysisRoot(analysisRootMode))
|
|
4861
|
+
return false;
|
|
4786
4862
|
const key = path8.resolve(filePath);
|
|
4787
4863
|
const now = Date.now();
|
|
4788
4864
|
const resolvedOriginCwd = originCwd ?? turnStateCwd;
|
|
@@ -4817,8 +4893,19 @@ var RuntimeCoordinator = class {
|
|
|
4817
4893
|
});
|
|
4818
4894
|
return true;
|
|
4819
4895
|
}
|
|
4820
|
-
deferFormat(filePath, cwd, toolName, turnStateCwd, ownerSessionId, originCwd) {
|
|
4821
|
-
return this.deferMutation(filePath, cwd, toolName, turnStateCwd, "format", ownerSessionId, originCwd);
|
|
4896
|
+
deferFormat(filePath, cwd, toolName, turnStateCwd, ownerSessionId, originCwd, analysisRootMode = "session") {
|
|
4897
|
+
return this.deferMutation(filePath, cwd, toolName, turnStateCwd, "format", ownerSessionId, originCwd, void 0, analysisRootMode);
|
|
4898
|
+
}
|
|
4899
|
+
/** Return the ownership identity of a queued format record for bus events. */
|
|
4900
|
+
deferredFormatIdentity(filePath) {
|
|
4901
|
+
const record = this._pendingDeferredMutations.get(path8.resolve(filePath));
|
|
4902
|
+
if (!record || !record.kinds.has("format"))
|
|
4903
|
+
return void 0;
|
|
4904
|
+
return {
|
|
4905
|
+
ownerSessionId: record.ownerSessionId,
|
|
4906
|
+
turnIndex: record.queuedTurnIndex,
|
|
4907
|
+
batchId: record.queuedTurnId
|
|
4908
|
+
};
|
|
4822
4909
|
}
|
|
4823
4910
|
get pendingDeferredFormatCount() {
|
|
4824
4911
|
return this._pendingDeferredMutations.size;
|
|
@@ -4946,7 +5033,7 @@ var RuntimeCoordinator = class {
|
|
|
4946
5033
|
|
|
4947
5034
|
// dist/clients/runtime-session.js
|
|
4948
5035
|
import * as nodeFs from "node:fs";
|
|
4949
|
-
import * as
|
|
5036
|
+
import * as path13 from "node:path";
|
|
4950
5037
|
|
|
4951
5038
|
// dist/clients/message-end-attribution.js
|
|
4952
5039
|
var lastStableSessionId;
|
|
@@ -5224,6 +5311,38 @@ function emitSituationalDeadWeight() {
|
|
|
5224
5311
|
});
|
|
5225
5312
|
}
|
|
5226
5313
|
|
|
5314
|
+
// dist/clients/deferred-test-targets.js
|
|
5315
|
+
import * as path12 from "node:path";
|
|
5316
|
+
var TEST_RUNNER_MAX_PERSISTED_TARGETS = 64;
|
|
5317
|
+
function deferralEntryKey(entry) {
|
|
5318
|
+
return `${entry.sessionId ?? ""}\0${normalizeMapKey(path12.resolve(entry.testFile))}`;
|
|
5319
|
+
}
|
|
5320
|
+
function mergeDeferredTargets(existing, incoming) {
|
|
5321
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
5322
|
+
for (const entry of [...existing, ...incoming]) {
|
|
5323
|
+
const key = deferralEntryKey(entry);
|
|
5324
|
+
const prior = byKey.get(key);
|
|
5325
|
+
if (prior && (prior.attempts ?? 0) >= (entry.attempts ?? 0))
|
|
5326
|
+
continue;
|
|
5327
|
+
byKey.set(key, entry);
|
|
5328
|
+
}
|
|
5329
|
+
return [...byKey.values()];
|
|
5330
|
+
}
|
|
5331
|
+
function boundDeferredTargets(entries, max, isOwn) {
|
|
5332
|
+
const foreign = [];
|
|
5333
|
+
const own = [];
|
|
5334
|
+
for (const entry of entries) {
|
|
5335
|
+
if (isOwn(entry))
|
|
5336
|
+
own.push(entry);
|
|
5337
|
+
else
|
|
5338
|
+
foreign.push(entry);
|
|
5339
|
+
}
|
|
5340
|
+
const ordered = [...foreign, ...own];
|
|
5341
|
+
if (ordered.length <= max)
|
|
5342
|
+
return ordered;
|
|
5343
|
+
return ordered.slice(-max);
|
|
5344
|
+
}
|
|
5345
|
+
|
|
5227
5346
|
// dist/clients/test-runner-delivery.js
|
|
5228
5347
|
var pending = /* @__PURE__ */ new Map();
|
|
5229
5348
|
function resetTestRunnerDelivery() {
|
|
@@ -5231,6 +5350,30 @@ function resetTestRunnerDelivery() {
|
|
|
5231
5350
|
}
|
|
5232
5351
|
|
|
5233
5352
|
// dist/clients/runtime-session.js
|
|
5353
|
+
function notifyStartupWarmSkip(args) {
|
|
5354
|
+
if (!args.runtime.isCurrentSession(args.sessionGeneration))
|
|
5355
|
+
return;
|
|
5356
|
+
const reason = args.scan.reason;
|
|
5357
|
+
if (reason !== "too-many-source-files" && reason !== "too-many-entries") {
|
|
5358
|
+
return;
|
|
5359
|
+
}
|
|
5360
|
+
const bound = reason === "too-many-entries" ? {
|
|
5361
|
+
name: "maxScanEntries",
|
|
5362
|
+
value: args.scan.maxScanEntries,
|
|
5363
|
+
hint: `set PI_LENS_STARTUP_SCAN_MAX_ENTRIES=<n> to override the ${args.scan.maxScanEntries}-entry cap`
|
|
5364
|
+
} : {
|
|
5365
|
+
name: "maxProjectFiles",
|
|
5366
|
+
value: args.scan.maxProjectFiles,
|
|
5367
|
+
hint: `set maxProjectFiles in .pi-lens.json to override the ${args.scan.maxProjectFiles}-source-file cap`
|
|
5368
|
+
};
|
|
5369
|
+
recordDegradationOnce({
|
|
5370
|
+
kind: "startup-warm-skipped",
|
|
5371
|
+
subject: args.analysisRoot,
|
|
5372
|
+
reason: `${reason}; ${bound.name}=${bound.value}`,
|
|
5373
|
+
metadata: { reason, [bound.name]: bound.value }
|
|
5374
|
+
});
|
|
5375
|
+
args.notify(`\u{1F4E6} Project-size limits disabled background warm scans (heavy scans, TODO scan, LSP pre-warm) (${bound.hint}).`, "warning");
|
|
5376
|
+
}
|
|
5234
5377
|
async function demandBootstrapDeps(deps, reason) {
|
|
5235
5378
|
const clients = await deps.bootstrap.request(reason);
|
|
5236
5379
|
if (!clients)
|
|
@@ -5256,7 +5399,7 @@ function logHostReadyDelay(deps, cwd) {
|
|
|
5256
5399
|
});
|
|
5257
5400
|
}
|
|
5258
5401
|
function resolveSnapshotRoot(cwd) {
|
|
5259
|
-
const resolvedCwd =
|
|
5402
|
+
const resolvedCwd = path13.resolve(cwd);
|
|
5260
5403
|
const nearest = findNearestProjectRoot(resolvedCwd);
|
|
5261
5404
|
if (!nearest || isAtOrAboveHomeDir(nearest)) {
|
|
5262
5405
|
return resolvedCwd;
|
|
@@ -5359,8 +5502,8 @@ async function readSequenceWithBudget(args) {
|
|
|
5359
5502
|
const { snapshotRoot, base, cwd, runtime, sessionGeneration, dbg, onDeferredSequenceResolved } = args;
|
|
5360
5503
|
const readPromise = readLatestProjectSequenceAsync(snapshotRoot, base);
|
|
5361
5504
|
let timeoutHandle;
|
|
5362
|
-
const timeoutPromise = new Promise((
|
|
5363
|
-
timeoutHandle = setTimeout(() =>
|
|
5505
|
+
const timeoutPromise = new Promise((resolve32) => {
|
|
5506
|
+
timeoutHandle = setTimeout(() => resolve32({ timedOut: true }), sequenceReadBudgetMs());
|
|
5364
5507
|
timeoutHandle.unref();
|
|
5365
5508
|
});
|
|
5366
5509
|
const raced = await Promise.race([
|
|
@@ -5429,7 +5572,7 @@ async function igniteWarmFiles(cwd, warmFiles, runtime, sessionGeneration, dbg)
|
|
|
5429
5572
|
for (const relPath of warmFiles) {
|
|
5430
5573
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5431
5574
|
return;
|
|
5432
|
-
const filePath =
|
|
5575
|
+
const filePath = path13.isAbsolute(relPath) ? relPath : path13.resolve(cwd, relPath);
|
|
5433
5576
|
if (!nodeFs.existsSync(filePath)) {
|
|
5434
5577
|
dbg(`session_start lsp-warm: not found: ${relPath}`);
|
|
5435
5578
|
errors++;
|
|
@@ -5460,8 +5603,8 @@ async function igniteDominantLanguageWarm(cwd, runtime, sessionGeneration, dbg)
|
|
|
5460
5603
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5461
5604
|
return;
|
|
5462
5605
|
const lspService = (await loadLspService()).getLSPService();
|
|
5463
|
-
const { collectSourceFilesAsync } = await import("../chunk-
|
|
5464
|
-
const { CODE_KINDS, detectFileKind: detectFileKind2 } = await import("../chunk-
|
|
5606
|
+
const { collectSourceFilesAsync } = await import("../chunk-4W4VLAPJ.js");
|
|
5607
|
+
const { CODE_KINDS, detectFileKind: detectFileKind2 } = await import("../chunk-FLKWCIZH.js");
|
|
5465
5608
|
const files = await collectSourceFilesAsync(cwd, {
|
|
5466
5609
|
inspectGeneratedHeaders: false
|
|
5467
5610
|
});
|
|
@@ -5495,7 +5638,7 @@ async function igniteDominantLanguageWarm(cwd, runtime, sessionGeneration, dbg)
|
|
|
5495
5638
|
clientScope: "primary",
|
|
5496
5639
|
maxClientWaitMs: 2e3
|
|
5497
5640
|
});
|
|
5498
|
-
dbg(`session_start lsp-warm: dominant=${kind} via ${
|
|
5641
|
+
dbg(`session_start lsp-warm: dominant=${kind} via ${path13.basename(sample)}`);
|
|
5499
5642
|
return;
|
|
5500
5643
|
}
|
|
5501
5644
|
dbg("session_start lsp-warm: no dominant-language LSP file found to warm");
|
|
@@ -5527,7 +5670,7 @@ function scheduleManagedToolRefresh(dbg) {
|
|
|
5527
5670
|
const timer = setTimeout(() => {
|
|
5528
5671
|
void (async () => {
|
|
5529
5672
|
try {
|
|
5530
|
-
const refresh = await import("../chunk-
|
|
5673
|
+
const refresh = await import("../chunk-CF24OIYI.js");
|
|
5531
5674
|
const outcome = await refresh.runManagedToolRefresh();
|
|
5532
5675
|
if (outcome.skipped) {
|
|
5533
5676
|
dbg(`session_start tool-refresh: skipped (${outcome.skipped})`);
|
|
@@ -5544,7 +5687,7 @@ function scheduleManagedToolRefresh(dbg) {
|
|
|
5544
5687
|
timer.unref?.();
|
|
5545
5688
|
}
|
|
5546
5689
|
async function probePrettierInstall(ensureTool, dbg, analysisRoot) {
|
|
5547
|
-
const pkgPath =
|
|
5690
|
+
const pkgPath = path13.join(analysisRoot, "package.json");
|
|
5548
5691
|
try {
|
|
5549
5692
|
const raw = await nodeFs.promises.readFile(pkgPath, "utf-8");
|
|
5550
5693
|
const pkg = JSON.parse(raw);
|
|
@@ -5574,7 +5717,7 @@ function scanOneTodoFile(scanner, filePath, items) {
|
|
|
5574
5717
|
async function collectTodoBaselineItems(scanner, analysisRoot, stillCurrent) {
|
|
5575
5718
|
const items = [];
|
|
5576
5719
|
try {
|
|
5577
|
-
const { getSourceFilesAsync } = await import("../chunk-
|
|
5720
|
+
const { getSourceFilesAsync } = await import("../chunk-IZSHAIJ7.js");
|
|
5578
5721
|
const files = await getSourceFilesAsync(analysisRoot, true);
|
|
5579
5722
|
if (!stillCurrent())
|
|
5580
5723
|
return items;
|
|
@@ -5603,7 +5746,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5603
5746
|
const snapshot = loadProjectSnapshot(snapshotRoot);
|
|
5604
5747
|
const snapshotLoadMs = Date.now() - snapshotLoadStartMs;
|
|
5605
5748
|
if (snapshot?.wordIndex) {
|
|
5606
|
-
const { deserializeWordIndex, refreshWordIndexIncrementally, countWordIndexPostingEntries: countWordIndexPostingEntries2, estimateWordIndexResidentBytes: estimateWordIndexResidentBytes2 } = await import("../chunk-
|
|
5749
|
+
const { deserializeWordIndex, refreshWordIndexIncrementally, countWordIndexPostingEntries: countWordIndexPostingEntries2, estimateWordIndexResidentBytes: estimateWordIndexResidentBytes2 } = await import("../chunk-WU567RSC.js");
|
|
5607
5750
|
const deserializeStartMs = Date.now();
|
|
5608
5751
|
const index = deserializeWordIndex(snapshot.wordIndex);
|
|
5609
5752
|
const deserializeMs = Date.now() - deserializeStartMs;
|
|
@@ -5675,7 +5818,7 @@ async function buildOrRefreshWordIndex(args) {
|
|
|
5675
5818
|
}
|
|
5676
5819
|
}
|
|
5677
5820
|
}
|
|
5678
|
-
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes } = await import("../chunk-
|
|
5821
|
+
const { buildWordIndexAsync, collectWordIndexDocs, countWordIndexPostingEntries, estimateWordIndexResidentBytes } = await import("../chunk-WU567RSC.js");
|
|
5679
5822
|
const docs = await collectWordIndexDocs(analysisRoot, () => runtime.isCurrentSession(sessionGeneration), rebuildPreflightFiles);
|
|
5680
5823
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5681
5824
|
return;
|
|
@@ -5745,7 +5888,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5745
5888
|
const queuedAt = Date.now();
|
|
5746
5889
|
dbg(`session_start task ${name}: scheduled`);
|
|
5747
5890
|
runtime.markStartupScanInFlight(name, sessionGeneration);
|
|
5748
|
-
const completion = new Promise((
|
|
5891
|
+
const completion = new Promise((resolve32) => {
|
|
5749
5892
|
const fire = () => {
|
|
5750
5893
|
const startedAt = Date.now();
|
|
5751
5894
|
dbg(`session_start task ${name}: start queuedMs=${startedAt - queuedAt}`);
|
|
@@ -5757,7 +5900,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5757
5900
|
}).finally(() => {
|
|
5758
5901
|
runtime.clearStartupScanInFlight(name, sessionGeneration);
|
|
5759
5902
|
dbg(`session_start task ${name}: end`);
|
|
5760
|
-
|
|
5903
|
+
resolve32();
|
|
5761
5904
|
});
|
|
5762
5905
|
};
|
|
5763
5906
|
const delay = taskDeferMsByName[name] ?? 0;
|
|
@@ -5834,7 +5977,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
5834
5977
|
if (await jscpdClient.ensureAvailable()) {
|
|
5835
5978
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
5836
5979
|
return;
|
|
5837
|
-
const isTsProject = nodeFs.existsSync(
|
|
5980
|
+
const isTsProject = nodeFs.existsSync(path13.join(analysisRoot, "tsconfig.json"));
|
|
5838
5981
|
const scannerKey = isTsProject ? "jscpd-ts" : "jscpd";
|
|
5839
5982
|
const cached = cacheManager2.readCache(scannerKey, analysisRoot);
|
|
5840
5983
|
if (cached) {
|
|
@@ -6040,9 +6183,9 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6040
6183
|
});
|
|
6041
6184
|
let callGraphIdentity;
|
|
6042
6185
|
const callGraphTask = runTask("call-graph", async () => {
|
|
6043
|
-
const { FactStore: FactStore2 } = await import("../chunk-
|
|
6044
|
-
const { buildOrUpdateGraph, extractSymbolsAndRefsFromGraph, getReviewGraphCacheIdentity } = await import("../chunk-
|
|
6045
|
-
const { buildCallGraph, saveCallGraph, loadCallGraph: loadCallGraph2 } = await import("../chunk-
|
|
6186
|
+
const { FactStore: FactStore2 } = await import("../chunk-QGQ5CCCG.js");
|
|
6187
|
+
const { buildOrUpdateGraph, extractSymbolsAndRefsFromGraph, getReviewGraphCacheIdentity } = await import("../chunk-2ZGIZPDG.js");
|
|
6188
|
+
const { buildCallGraph, saveCallGraph, loadCallGraph: loadCallGraph2 } = await import("../chunk-BKE7E7TC.js");
|
|
6046
6189
|
if (!runtime.isCurrentSession(sessionGeneration))
|
|
6047
6190
|
return;
|
|
6048
6191
|
const startMs = Date.now();
|
|
@@ -6083,7 +6226,7 @@ function scheduleStartupScansWithClients(deps, runtime, sessionGeneration, analy
|
|
|
6083
6226
|
return;
|
|
6084
6227
|
if (!runtime.callGraph)
|
|
6085
6228
|
return;
|
|
6086
|
-
const { buildCodebaseModel, saveCodebaseModel, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET } = await import("../chunk-
|
|
6229
|
+
const { buildCodebaseModel, saveCodebaseModel, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET } = await import("../chunk-TYM6OUIT.js");
|
|
6087
6230
|
if (!callGraphIdentity)
|
|
6088
6231
|
return;
|
|
6089
6232
|
const model = buildCodebaseModel(runtime.callGraph, analysisRoot, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET, callGraphIdentity);
|
|
@@ -6156,11 +6299,79 @@ function scheduleDeferredToolProbesWithClients(deps, languageProfile, startupDef
|
|
|
6156
6299
|
dbg(`session_start tools (deferred probes complete, ${Date.now() - warmStart}ms): ${summary}`);
|
|
6157
6300
|
})();
|
|
6158
6301
|
}
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6302
|
+
function readSubstituteGuidance(isEnabled) {
|
|
6303
|
+
const units = [];
|
|
6304
|
+
if (isEnabled("symbol_search")) {
|
|
6305
|
+
units.push({ name: "symbol_search", role: "ranked identifier search" });
|
|
6306
|
+
}
|
|
6307
|
+
if (isEnabled("module_report")) {
|
|
6308
|
+
units.push({
|
|
6309
|
+
name: "module_report",
|
|
6310
|
+
role: "navigable outline/callback handles"
|
|
6311
|
+
});
|
|
6312
|
+
}
|
|
6313
|
+
const readSymbol2 = isEnabled("read_symbol");
|
|
6314
|
+
const readEnclosing2 = isEnabled("read_enclosing");
|
|
6315
|
+
if (readSymbol2 && readEnclosing2) {
|
|
6316
|
+
units.push({
|
|
6317
|
+
name: "read_symbol/read_enclosing",
|
|
6318
|
+
role: "exact body reads"
|
|
6319
|
+
});
|
|
6320
|
+
} else if (readSymbol2) {
|
|
6321
|
+
units.push({ name: "read_symbol", role: "exact body reads" });
|
|
6322
|
+
} else if (readEnclosing2) {
|
|
6323
|
+
units.push({ name: "read_enclosing", role: "exact body reads" });
|
|
6324
|
+
}
|
|
6325
|
+
if (units.length === 0)
|
|
6326
|
+
return void 0;
|
|
6327
|
+
const roles = units.map((unit) => unit.role);
|
|
6328
|
+
const roleTail = roles.length === 1 ? roles[0] : roles.length === 2 ? `${roles[0]}, then ${roles[1]}` : `${roles[0]}, then ${roles[1]} + ${roles[2]}`;
|
|
6329
|
+
return `\u2022 ${units.map((unit) => unit.name).join(" \u2192 ")} \u2014 ${roleTail}; cheaper than reading a whole file before editing.`;
|
|
6330
|
+
}
|
|
6331
|
+
function situationalGuidance(isEnabled) {
|
|
6332
|
+
const active = [];
|
|
6333
|
+
for (const name of [
|
|
6334
|
+
"lsp_navigation",
|
|
6335
|
+
"ast_grep_search",
|
|
6336
|
+
"ast_grep_replace"
|
|
6337
|
+
]) {
|
|
6338
|
+
if (isEnabled(name))
|
|
6339
|
+
active.push(name);
|
|
6340
|
+
}
|
|
6341
|
+
if (active.length === 0)
|
|
6342
|
+
return void 0;
|
|
6343
|
+
let text = `\u2022 Situational (activate via pi_lens_activate_tools): ${active.join(", ")}.`;
|
|
6344
|
+
if (isEnabled("ast_grep_search")) {
|
|
6345
|
+
text += " Use ast_grep_search with dump=true to inspect AST nodes.";
|
|
6346
|
+
}
|
|
6347
|
+
return text;
|
|
6348
|
+
}
|
|
6349
|
+
function renderSessionStartGuidance(options = {}) {
|
|
6350
|
+
const disabled = new Set(options.disabledToolNames ?? []);
|
|
6351
|
+
const isEnabled = (name) => !disabled.has(name);
|
|
6352
|
+
const requirePreExistingFixes = options.requirePreExistingFixes !== false;
|
|
6353
|
+
const header = "\u{1F4CC} pi-lens active \u2014 automated checks run on every edit/write; " + (requirePreExistingFixes ? "blocking errors (including pre-existing) show inline and must be fixed." : "blocking errors you introduce must be fixed; pre-existing ones are only reported.");
|
|
6354
|
+
const bullets = [];
|
|
6355
|
+
if (isEnabled("lens_diagnostics")) {
|
|
6356
|
+
bullets.push("\u2022 lens_diagnostics \u2014 source=session reads cache; empty cache \u2260 clean; use source=lsp scope=paths for changed files with absent or stale findings (aggregate hosts: lens(action=diagnostics)).");
|
|
6357
|
+
}
|
|
6358
|
+
const readSubstitute = readSubstituteGuidance(isEnabled);
|
|
6359
|
+
if (readSubstitute)
|
|
6360
|
+
bullets.push(readSubstitute);
|
|
6361
|
+
const situational = situationalGuidance(isEnabled);
|
|
6362
|
+
if (situational)
|
|
6363
|
+
bullets.push(situational);
|
|
6364
|
+
const lines = [header];
|
|
6365
|
+
if (bullets.length > 0) {
|
|
6366
|
+
lines.push("Key tools (see each tool's own description for args):");
|
|
6367
|
+
lines.push(...bullets);
|
|
6368
|
+
}
|
|
6369
|
+
return [lines.join("\n")];
|
|
6370
|
+
}
|
|
6371
|
+
var SESSION_START_GUIDANCE = renderSessionStartGuidance();
|
|
6162
6372
|
async function handleSessionStart(deps) {
|
|
6163
6373
|
resetDegradationLedger();
|
|
6374
|
+
let sessionGenerationAtStart = deps.runtime.sessionGeneration;
|
|
6164
6375
|
resetAnalyzerBootstrapSessionState();
|
|
6165
6376
|
resetProjectDataDirSessionState();
|
|
6166
6377
|
resetTestRunnerDelivery();
|
|
@@ -6199,8 +6410,8 @@ async function handleSessionStart(deps) {
|
|
|
6199
6410
|
try {
|
|
6200
6411
|
warmupDbg("warmup: starting background warmup");
|
|
6201
6412
|
const scanContextStartedAt = Date.now();
|
|
6202
|
-
const startupScanModule = await import("../chunk-
|
|
6203
|
-
const languageProfileModule = await import("../chunk-
|
|
6413
|
+
const startupScanModule = await import("../chunk-ZHFZWTZV.js");
|
|
6414
|
+
const languageProfileModule = await import("../chunk-R3PCY3YS.js");
|
|
6204
6415
|
const warmupSnapshotRoot = resolveSnapshotRoot(warmupCwd);
|
|
6205
6416
|
const cachedSnapshot = loadProjectSnapshot(warmupSnapshotRoot);
|
|
6206
6417
|
warmupOwnSnapshotRead = cachedSnapshot ? {
|
|
@@ -6212,7 +6423,7 @@ async function handleSessionStart(deps) {
|
|
|
6212
6423
|
const cachedVerdict = cachedSnapshot?.startupScan;
|
|
6213
6424
|
let scan;
|
|
6214
6425
|
if (cachedVerdict && startupScanModule.isStartupScanVerdictFresh(cachedVerdict)) {
|
|
6215
|
-
scan = { ...cachedVerdict, cwd:
|
|
6426
|
+
scan = { ...cachedVerdict, cwd: path13.resolve(warmupCwd) };
|
|
6216
6427
|
warmupDbg(`warmup: scan-context reused from cache (canWarm=${scan.canWarmCaches}${scan.reason ? `, reason=${scan.reason}` : ""})`);
|
|
6217
6428
|
} else {
|
|
6218
6429
|
scan = await startupScanModule.resolveStartupScanContextAsync(warmupCwd);
|
|
@@ -6241,6 +6452,13 @@ async function handleSessionStart(deps) {
|
|
|
6241
6452
|
});
|
|
6242
6453
|
if (!scan.canWarmCaches) {
|
|
6243
6454
|
warmupDbg(`warmup: skipping language-profile (canWarm=false, reason=${scan.reason ?? "unknown"})`);
|
|
6455
|
+
notifyStartupWarmSkip({
|
|
6456
|
+
scan,
|
|
6457
|
+
analysisRoot: scan.projectRoot ?? warmupCwd,
|
|
6458
|
+
notify: deps.notify,
|
|
6459
|
+
runtime: deps.runtime,
|
|
6460
|
+
sessionGeneration: sessionGenerationAtStart
|
|
6461
|
+
});
|
|
6244
6462
|
return;
|
|
6245
6463
|
}
|
|
6246
6464
|
const languageRoot = scan.projectRoot ?? warmupCwd;
|
|
@@ -6356,6 +6574,7 @@ async function handleSessionStart(deps) {
|
|
|
6356
6574
|
deps.bootstrap.peek()?.knipClient.resetSessionState?.();
|
|
6357
6575
|
resetCascadeTierSessionState();
|
|
6358
6576
|
runtime.resetForSession(sessionStartMs);
|
|
6577
|
+
sessionGenerationAtStart = runtime.sessionGeneration;
|
|
6359
6578
|
logLatency({
|
|
6360
6579
|
type: "phase",
|
|
6361
6580
|
phase: "session_start_runtime_reset",
|
|
@@ -6398,7 +6617,7 @@ async function handleSessionStart(deps) {
|
|
|
6398
6617
|
const cwd = ctxCwd ?? process.cwd();
|
|
6399
6618
|
const projectDataDir = getProjectDataDir(cwd);
|
|
6400
6619
|
for (const migration of drainProjectDataDirMigrations()) {
|
|
6401
|
-
const targetName =
|
|
6620
|
+
const targetName = path13.basename(migration.to);
|
|
6402
6621
|
const hash = targetName.match(/([0-9a-f]{8})$/)?.[1] ?? "unknown";
|
|
6403
6622
|
if (migration.outcome === "ephemeral") {
|
|
6404
6623
|
recordDegradationOnce({
|
|
@@ -6417,11 +6636,11 @@ async function handleSessionStart(deps) {
|
|
|
6417
6636
|
const globalDir = getGlobalPiLensDir();
|
|
6418
6637
|
void sweepAtomicWriteStages([
|
|
6419
6638
|
projectDataDir,
|
|
6420
|
-
|
|
6421
|
-
|
|
6639
|
+
path13.join(projectDataDir, "cache"),
|
|
6640
|
+
path13.join(projectDataDir, "sessions"),
|
|
6422
6641
|
globalDir,
|
|
6423
|
-
|
|
6424
|
-
|
|
6642
|
+
path13.join(globalDir, "bin"),
|
|
6643
|
+
path13.join(globalDir, "tools")
|
|
6425
6644
|
]).catch(() => {
|
|
6426
6645
|
});
|
|
6427
6646
|
void sweepDeadEphemeralDataDirs({ isPidAlive: realIsPidAlive }).catch(() => {
|
|
@@ -6570,7 +6789,7 @@ async function handleSessionStart(deps) {
|
|
|
6570
6789
|
if (allowBootstrapTasks && !getFlag("no-lsp")) {
|
|
6571
6790
|
const cleaned = cleanStaleTsBuildInfo(ctxCwd ?? process.cwd());
|
|
6572
6791
|
if (cleaned.length > 0) {
|
|
6573
|
-
notify(`\u{1F9F9} Deleted stale TypeScript build cache (${cleaned.map((f) =>
|
|
6792
|
+
notify(`\u{1F9F9} Deleted stale TypeScript build cache (${cleaned.map((f) => path13.basename(f)).join(", ")}) \u2014 phantom errors suppressed.`, "warning");
|
|
6574
6793
|
dbg(`session_start: cleaned stale tsbuildinfo: ${cleaned.join(", ")}`);
|
|
6575
6794
|
}
|
|
6576
6795
|
}
|
|
@@ -6655,7 +6874,7 @@ async function handleSessionStart(deps) {
|
|
|
6655
6874
|
const startupScanSource = cachedStartupScan ? "snapshot" : "computed";
|
|
6656
6875
|
let startupScan;
|
|
6657
6876
|
if (cachedStartupScan) {
|
|
6658
|
-
startupScan = { ...cachedStartupScan, cwd:
|
|
6877
|
+
startupScan = { ...cachedStartupScan, cwd: path13.resolve(cwd) };
|
|
6659
6878
|
} else {
|
|
6660
6879
|
const scanContextStartedAt = Date.now();
|
|
6661
6880
|
startupScan = resolveStartupScanContext(cwd);
|
|
@@ -6760,7 +6979,10 @@ async function handleSessionStart(deps) {
|
|
|
6760
6979
|
tools.push("Rust (cargo)");
|
|
6761
6980
|
log(`Active tools: ${tools.join(", ")}`);
|
|
6762
6981
|
dbg(`session_start tools: ${tools.join(", ")}`);
|
|
6763
|
-
const agentStartupGuidance =
|
|
6982
|
+
const agentStartupGuidance = renderSessionStartGuidance({
|
|
6983
|
+
disabledToolNames: deps.disabledToolNames,
|
|
6984
|
+
requirePreExistingFixes: deps.globalConfig?.contextInjection?.requirePreExistingFixes
|
|
6985
|
+
});
|
|
6764
6986
|
runtime.projectRulesScan = scanProjectRules(analysisRoot);
|
|
6765
6987
|
saveRuntimeProjectSnapshot({
|
|
6766
6988
|
cwd: snapshotRoot,
|
|
@@ -6792,10 +7014,13 @@ async function handleSessionStart(deps) {
|
|
|
6792
7014
|
} else if (!startupScan.canWarmCaches) {
|
|
6793
7015
|
dbg(`session_start: skipping heavy scans (${startupScan.reason ?? "unknown"})`);
|
|
6794
7016
|
dbg(`session_start: skipping TODO scan (${startupScan.reason ?? "unknown"})`);
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
7017
|
+
notifyStartupWarmSkip({
|
|
7018
|
+
scan: startupScan,
|
|
7019
|
+
analysisRoot,
|
|
7020
|
+
notify,
|
|
7021
|
+
runtime,
|
|
7022
|
+
sessionGeneration
|
|
7023
|
+
});
|
|
6799
7024
|
} else {
|
|
6800
7025
|
scheduleStartupScans(deps, runtime, sessionGeneration, analysisRoot, snapshotRoot, languageProfile, dbg);
|
|
6801
7026
|
}
|
|
@@ -6857,18 +7082,18 @@ function emitSmellsSessionStartLine(dbg, sessionStartMs) {
|
|
|
6857
7082
|
|
|
6858
7083
|
// dist/clients/runtime-turn.js
|
|
6859
7084
|
import * as fs17 from "node:fs";
|
|
6860
|
-
import * as
|
|
7085
|
+
import * as path24 from "node:path";
|
|
6861
7086
|
|
|
6862
7087
|
// dist/clients/actionable-warnings.js
|
|
6863
7088
|
import { createHash as createHash2 } from "node:crypto";
|
|
6864
7089
|
import * as fs12 from "node:fs";
|
|
6865
|
-
import * as
|
|
7090
|
+
import * as path15 from "node:path";
|
|
6866
7091
|
|
|
6867
7092
|
// dist/clients/actionable-warnings-logger.js
|
|
6868
|
-
import * as
|
|
7093
|
+
import * as path14 from "node:path";
|
|
6869
7094
|
var AW_LOG_DIR = getGlobalPiLensLogDir();
|
|
6870
|
-
var AW_LOG_FILE =
|
|
6871
|
-
var AW_LOG_BACKUP_FILE =
|
|
7095
|
+
var AW_LOG_FILE = path14.join(AW_LOG_DIR, "actionable-warnings.log");
|
|
7096
|
+
var AW_LOG_BACKUP_FILE = path14.join(AW_LOG_DIR, "actionable-warnings.log.1");
|
|
6872
7097
|
var MAX_LOG_BYTES2 = Math.max(128 * 1024, Number.parseInt(process.env.PI_LENS_AW_LOG_MAX_BYTES ?? "1048576", 10) || 1048576);
|
|
6873
7098
|
var writer2 = createNdjsonLogger({
|
|
6874
7099
|
filePath: AW_LOG_FILE,
|
|
@@ -6903,7 +7128,7 @@ function createActionableWarningId(args) {
|
|
|
6903
7128
|
});
|
|
6904
7129
|
}
|
|
6905
7130
|
function legacyActionableWarningId(args) {
|
|
6906
|
-
const rel =
|
|
7131
|
+
const rel = path15.relative(args.cwd, args.filePath).replace(/\\/g, "/");
|
|
6907
7132
|
const legacyRelativeFile = rel && !rel.startsWith("..") ? rel : normalizeMapKey(args.filePath);
|
|
6908
7133
|
const parts = [
|
|
6909
7134
|
legacyRelativeFile,
|
|
@@ -6949,7 +7174,7 @@ function deserializeSuppressionState(contents) {
|
|
|
6949
7174
|
}
|
|
6950
7175
|
}
|
|
6951
7176
|
function readSuppressionState(cwd) {
|
|
6952
|
-
const statePath =
|
|
7177
|
+
const statePath = path15.join(getProjectDataDir(cwd), "cache", "actionable-warning-state.json");
|
|
6953
7178
|
try {
|
|
6954
7179
|
return deserializeSuppressionState(fs12.readFileSync(statePath, "utf8"));
|
|
6955
7180
|
} catch {
|
|
@@ -6957,8 +7182,8 @@ function readSuppressionState(cwd) {
|
|
|
6957
7182
|
}
|
|
6958
7183
|
}
|
|
6959
7184
|
function updateWarningState(cwd, warnings) {
|
|
6960
|
-
const statePath =
|
|
6961
|
-
fs12.mkdirSync(
|
|
7185
|
+
const statePath = path15.join(getProjectDataDir(cwd), "cache", "actionable-warning-state.json");
|
|
7186
|
+
fs12.mkdirSync(path15.dirname(statePath), { recursive: true });
|
|
6962
7187
|
const hook = beforeWarningStateLockForTests;
|
|
6963
7188
|
beforeWarningStateLockForTests = null;
|
|
6964
7189
|
hook?.();
|
|
@@ -7103,7 +7328,7 @@ function boundedNumber(value, fallback) {
|
|
|
7103
7328
|
return value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
7104
7329
|
}
|
|
7105
7330
|
async function buildActionableWarningsReport(args) {
|
|
7106
|
-
const cwd =
|
|
7331
|
+
const cwd = path15.resolve(args.cwd);
|
|
7107
7332
|
const records = [...args.dispatchWarnings];
|
|
7108
7333
|
const lspService = getLSPService();
|
|
7109
7334
|
const observedAtByPath = /* @__PURE__ */ new Map();
|
|
@@ -7125,7 +7350,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7125
7350
|
const eligible = [];
|
|
7126
7351
|
let outsideRoot = 0;
|
|
7127
7352
|
for (const file of args.files) {
|
|
7128
|
-
const filePath =
|
|
7353
|
+
const filePath = path15.resolve(cwd, file);
|
|
7129
7354
|
if (normalizeMapKey(filePath) === normalizeMapKey(cwd) || !isUnderDir(filePath, cwd)) {
|
|
7130
7355
|
outsideRoot++;
|
|
7131
7356
|
logActionableWarningsEvent({
|
|
@@ -7235,7 +7460,7 @@ async function buildActionableWarningsReport(args) {
|
|
|
7235
7460
|
}
|
|
7236
7461
|
};
|
|
7237
7462
|
const deferredWork = (async () => {
|
|
7238
|
-
await new Promise((
|
|
7463
|
+
await new Promise((resolve32) => setTimeout(resolve32, 0));
|
|
7239
7464
|
const deferredRecords = [...carried];
|
|
7240
7465
|
const deferredDeadline = Date.now() + ACTIONABLE_WARNINGS_DEFERRED_BUDGET_MS;
|
|
7241
7466
|
deferredDeps.deadlineAt = deferredDeadline;
|
|
@@ -7612,7 +7837,7 @@ function publishActionableWarningsReport(cacheManager2, cwd, report, opts = {})
|
|
|
7612
7837
|
const reason = `${merged.droppedFiles.length} carried-forward entries: findings are LOST on this channel; ${cause} (files: ${merged.droppedFiles.slice(0, 3).join(", ")}${merged.droppedFiles.length > 3 ? ", ..." : ""})`;
|
|
7613
7838
|
incrementDegradationCount({
|
|
7614
7839
|
kind: "actionable-warnings-inband-superseded",
|
|
7615
|
-
subject: `${
|
|
7840
|
+
subject: `${path15.resolve(cwd)}:inband-carry-superseded`,
|
|
7616
7841
|
reason
|
|
7617
7842
|
});
|
|
7618
7843
|
opts.dbg?.(`actionable_warnings: in-band publish dropped ${merged.droppedFiles.length} superseded carried-forward file entry/entries (${merged.droppedFiles.slice(0, 3).join(", ")}${merged.droppedFiles.length > 3 ? ", ..." : ""})`);
|
|
@@ -7664,7 +7889,7 @@ function writeDeferredActionableWarningsReport(args) {
|
|
|
7664
7889
|
if (droppedFiles.length > 0) {
|
|
7665
7890
|
incrementDegradationCount({
|
|
7666
7891
|
kind: "actionable-warnings-deferred-superseded",
|
|
7667
|
-
subject: `${
|
|
7892
|
+
subject: `${path15.resolve(args.cwd)}:deferred-file-superseded`,
|
|
7668
7893
|
reason: `${droppedFiles.length} changed file(s): warnings are LOST; unchanged files were merged into the persisted report (files: ${droppedFiles.slice(0, 3).join(", ")}${droppedFiles.length > 3 ? ", ..." : ""})`
|
|
7669
7894
|
});
|
|
7670
7895
|
args.dbg?.(`turn_end: deferred actionable-warnings dropped ${droppedFiles.length} superseded file entry/entries`);
|
|
@@ -7673,7 +7898,7 @@ function writeDeferredActionableWarningsReport(args) {
|
|
|
7673
7898
|
return { mergedFiles, droppedFiles: droppedFiles.length };
|
|
7674
7899
|
}
|
|
7675
7900
|
function getActionableWarningsHistoryPath(cwd) {
|
|
7676
|
-
return
|
|
7901
|
+
return path15.join(getProjectDataDir(cwd), "actionable-warnings.jsonl");
|
|
7677
7902
|
}
|
|
7678
7903
|
function appendActionableWarningsHistory(cwd, report) {
|
|
7679
7904
|
const entries = [];
|
|
@@ -7712,7 +7937,7 @@ function appendActionableWarningsHistory(cwd, report) {
|
|
|
7712
7937
|
return;
|
|
7713
7938
|
const historyPath = getActionableWarningsHistoryPath(cwd);
|
|
7714
7939
|
try {
|
|
7715
|
-
fs12.mkdirSync(
|
|
7940
|
+
fs12.mkdirSync(path15.dirname(historyPath), { recursive: true });
|
|
7716
7941
|
fs12.appendFileSync(historyPath, `${entries.map((entry) => JSON.stringify(entry)).join("\n")}
|
|
7717
7942
|
`, "utf8");
|
|
7718
7943
|
} catch {
|
|
@@ -7751,7 +7976,7 @@ ${fileList}${more}` : void 0,
|
|
|
7751
7976
|
|
|
7752
7977
|
// dist/clients/code-quality-warnings.js
|
|
7753
7978
|
import * as fs13 from "node:fs";
|
|
7754
|
-
import * as
|
|
7979
|
+
import * as path16 from "node:path";
|
|
7755
7980
|
var TIER_BUDGET_ORDER = [
|
|
7756
7981
|
"warning",
|
|
7757
7982
|
"info",
|
|
@@ -7765,7 +7990,7 @@ function lineInModifiedRanges2(line, ranges) {
|
|
|
7765
7990
|
return ranges.some((range) => line >= range.start - 2 && line <= range.end + 2);
|
|
7766
7991
|
}
|
|
7767
7992
|
function buildCodeQualityWarningsReport(args) {
|
|
7768
|
-
const cwd =
|
|
7993
|
+
const cwd = path16.resolve(args.cwd);
|
|
7769
7994
|
const maxWarnings = Math.max(1, args.maxWarnings ?? 50);
|
|
7770
7995
|
const byId = /* @__PURE__ */ new Map();
|
|
7771
7996
|
for (const warning of args.warnings) {
|
|
@@ -7829,7 +8054,7 @@ function writeCodeQualityWarningsReport(cacheManager2, cwd, report) {
|
|
|
7829
8054
|
cacheManager2.writeCache("code-quality-warnings", report, cwd);
|
|
7830
8055
|
}
|
|
7831
8056
|
function getCodeQualityWarningsHistoryPath(cwd) {
|
|
7832
|
-
return
|
|
8057
|
+
return path16.join(getProjectDataDir(cwd), "code-quality-warnings.jsonl");
|
|
7833
8058
|
}
|
|
7834
8059
|
function appendCodeQualityWarningsHistory(cwd, report) {
|
|
7835
8060
|
const warnings = report.files.flatMap((file) => file.warnings.map((warning) => ({
|
|
@@ -7854,7 +8079,7 @@ function appendCodeQualityWarningsHistory(cwd, report) {
|
|
|
7854
8079
|
return;
|
|
7855
8080
|
const historyPath = getCodeQualityWarningsHistoryPath(cwd);
|
|
7856
8081
|
try {
|
|
7857
|
-
fs13.mkdirSync(
|
|
8082
|
+
fs13.mkdirSync(path16.dirname(historyPath), { recursive: true });
|
|
7858
8083
|
fs13.appendFileSync(historyPath, `${warnings.map((entry) => JSON.stringify(entry)).join("\n")}
|
|
7859
8084
|
`, "utf8");
|
|
7860
8085
|
} catch {
|
|
@@ -7886,7 +8111,7 @@ function formatCodeQualityWarningsAdvisory(report, cwd, host = "pi") {
|
|
|
7886
8111
|
}
|
|
7887
8112
|
|
|
7888
8113
|
// dist/clients/git-guard.js
|
|
7889
|
-
import * as
|
|
8114
|
+
import * as path17 from "node:path";
|
|
7890
8115
|
|
|
7891
8116
|
// dist/clients/read-guard-tool-lines.js
|
|
7892
8117
|
var MAX_FAILURE_TRACKER_SIZE = 200;
|
|
@@ -7961,7 +8186,7 @@ function readBytes(filePath) {
|
|
|
7961
8186
|
|
|
7962
8187
|
// dist/clients/git-guard.js
|
|
7963
8188
|
function resolveGuardPath(filePath, cwd) {
|
|
7964
|
-
return
|
|
8189
|
+
return path17.resolve(cwd, filePath);
|
|
7965
8190
|
}
|
|
7966
8191
|
function guardPathKey(filePath, cwd) {
|
|
7967
8192
|
return advisoryPathKey(filePath, cwd);
|
|
@@ -8084,7 +8309,9 @@ function resyncGitGuardAfterInlinePolicy(args) {
|
|
|
8084
8309
|
return;
|
|
8085
8310
|
args.runtime.updateGitGuardStatus(false, "");
|
|
8086
8311
|
}
|
|
8087
|
-
function syncGitGuardRecord(runtime, cacheManager2, cwd, editedFilePath) {
|
|
8312
|
+
function syncGitGuardRecord(runtime, cacheManager2, cwd, editedFilePath, analysisRootMode = "session") {
|
|
8313
|
+
if (!canWriteAnalysisRoot(analysisRootMode))
|
|
8314
|
+
return;
|
|
8088
8315
|
const entries = (runtime.getInlineBlockersSnapshot?.() ?? []).filter((entry) => !entry.policySuppressed);
|
|
8089
8316
|
const inspection = cacheManager2.inspectCache("turn-end-findings", cwd);
|
|
8090
8317
|
const existing = cacheRecord(cacheManager2, cwd);
|
|
@@ -8278,10 +8505,10 @@ function dedupeSecretFindings(findings) {
|
|
|
8278
8505
|
}
|
|
8279
8506
|
|
|
8280
8507
|
// dist/clients/project-diagnostics/runner-adapters/govulncheck.js
|
|
8281
|
-
import * as
|
|
8508
|
+
import * as path18 from "node:path";
|
|
8282
8509
|
function govulncheckFindingToProjectDiagnostic(cwd, finding) {
|
|
8283
8510
|
const frame = finding.trace?.find((f) => f.filename);
|
|
8284
|
-
const filePath = frame?.filename ?
|
|
8511
|
+
const filePath = frame?.filename ? path18.isAbsolute(frame.filename) ? frame.filename : path18.resolve(cwd, frame.filename) : cwd;
|
|
8285
8512
|
const fix = finding.fixedVersion ? ` (fixed in ${finding.fixedVersion})` : "";
|
|
8286
8513
|
return {
|
|
8287
8514
|
filePath,
|
|
@@ -8354,12 +8581,12 @@ var govulncheckLane = {
|
|
|
8354
8581
|
};
|
|
8355
8582
|
|
|
8356
8583
|
// dist/clients/project-diagnostics/runner-adapters/gitleaks.js
|
|
8357
|
-
import * as
|
|
8584
|
+
import * as path19 from "node:path";
|
|
8358
8585
|
function gitleaksFindingToProjectDiagnostic(cwd, finding) {
|
|
8359
8586
|
const statusSuffix = finding.pathStatus ? ` [git: ${finding.pathStatus}]` : "";
|
|
8360
8587
|
const isBlocking2 = finding.pathStatus !== "scratch" && finding.pathStatus !== "ignored" && finding.pathStatus !== "nested-repository";
|
|
8361
8588
|
return {
|
|
8362
|
-
filePath:
|
|
8589
|
+
filePath: path19.isAbsolute(finding.file) ? finding.file : path19.resolve(cwd, finding.file),
|
|
8363
8590
|
line: finding.startLine,
|
|
8364
8591
|
severity: isBlocking2 ? "error" : "info",
|
|
8365
8592
|
semantic: isBlocking2 ? "blocking" : "none",
|
|
@@ -8377,9 +8604,9 @@ function gitleaksResultToProjectDiagnostics(cwd, result) {
|
|
|
8377
8604
|
}
|
|
8378
8605
|
|
|
8379
8606
|
// dist/clients/project-diagnostics/runner-adapters/trivy.js
|
|
8380
|
-
import * as
|
|
8607
|
+
import * as path20 from "node:path";
|
|
8381
8608
|
function trivyFindingToProjectDiagnostic(cwd, finding) {
|
|
8382
|
-
const filePath = finding.target ?
|
|
8609
|
+
const filePath = finding.target ? path20.isAbsolute(finding.target) ? finding.target : path20.resolve(cwd, finding.target) : cwd;
|
|
8383
8610
|
const version = finding.installedVersion ? `@${finding.installedVersion}` : "";
|
|
8384
8611
|
const fix = finding.fixedVersion ? ` (fixed in ${finding.fixedVersion})` : "";
|
|
8385
8612
|
return {
|
|
@@ -8396,7 +8623,7 @@ function trivyFindingToProjectDiagnostic(cwd, finding) {
|
|
|
8396
8623
|
}
|
|
8397
8624
|
function trivySecretFindingToProjectDiagnostic(cwd, finding) {
|
|
8398
8625
|
return {
|
|
8399
|
-
filePath:
|
|
8626
|
+
filePath: path20.isAbsolute(finding.file) ? finding.file : path20.resolve(cwd, finding.file),
|
|
8400
8627
|
line: finding.line,
|
|
8401
8628
|
severity: "error",
|
|
8402
8629
|
semantic: "blocking",
|
|
@@ -8610,7 +8837,7 @@ function stillReportedParked(parked, current, keyOf, offeredKeys) {
|
|
|
8610
8837
|
}
|
|
8611
8838
|
|
|
8612
8839
|
// dist/clients/knip-scan-roots.js
|
|
8613
|
-
import { resolve as
|
|
8840
|
+
import { resolve as resolve13 } from "node:path";
|
|
8614
8841
|
var MAX_KNIP_ROOTS_PER_TURN = 3;
|
|
8615
8842
|
function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
8616
8843
|
const session = resolveGitCheckout(sessionCwd);
|
|
@@ -8620,7 +8847,7 @@ function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
|
8620
8847
|
let sessionOwnsEdit = false;
|
|
8621
8848
|
const linked = [];
|
|
8622
8849
|
for (const file of modifiedFiles) {
|
|
8623
|
-
const owner = resolveLinkedWorktreeOwner(session,
|
|
8850
|
+
const owner = resolveLinkedWorktreeOwner(session, resolve13(sessionCwd, file));
|
|
8624
8851
|
if (owner === null) {
|
|
8625
8852
|
sessionOwnsEdit = true;
|
|
8626
8853
|
} else if (!linked.some((known) => pathsEqual(known.root, owner.root))) {
|
|
@@ -8636,7 +8863,7 @@ function resolveKnipScanRoots(sessionCwd, modifiedFiles) {
|
|
|
8636
8863
|
}
|
|
8637
8864
|
|
|
8638
8865
|
// dist/clients/project-diagnostics/runner-adapters/dead-code.js
|
|
8639
|
-
import * as
|
|
8866
|
+
import * as path21 from "node:path";
|
|
8640
8867
|
function deadCodeRunnerId(language) {
|
|
8641
8868
|
return `dead-code-${language}`;
|
|
8642
8869
|
}
|
|
@@ -8652,7 +8879,7 @@ function deadCodeMessage(issue) {
|
|
|
8652
8879
|
function deadCodeIssueToProjectDiagnostic(cwd, issue, language) {
|
|
8653
8880
|
const blocking = issue.category === "unlisted";
|
|
8654
8881
|
return {
|
|
8655
|
-
filePath: issue.file ?
|
|
8882
|
+
filePath: issue.file ? path21.isAbsolute(issue.file) ? issue.file : path21.resolve(cwd, issue.file) : cwd,
|
|
8656
8883
|
line: issue.line,
|
|
8657
8884
|
severity: blocking ? "error" : "warning",
|
|
8658
8885
|
semantic: blocking ? "blocking" : "warning",
|
|
@@ -8676,11 +8903,11 @@ function deadCodeResultToProjectDiagnostics(cwd, result) {
|
|
|
8676
8903
|
}
|
|
8677
8904
|
|
|
8678
8905
|
// dist/clients/project-diagnostics/runner-adapters/knip.js
|
|
8679
|
-
import * as
|
|
8906
|
+
import * as path22 from "node:path";
|
|
8680
8907
|
function knipIssueFile(cwd, issue) {
|
|
8681
8908
|
if (!issue.file)
|
|
8682
8909
|
return cwd;
|
|
8683
|
-
return
|
|
8910
|
+
return path22.isAbsolute(issue.file) ? issue.file : path22.resolve(cwd, issue.file);
|
|
8684
8911
|
}
|
|
8685
8912
|
function knipIssueMessage(issue) {
|
|
8686
8913
|
if (issue.type === "unlisted") {
|
|
@@ -9025,7 +9252,7 @@ async function runPersistentReverify(args) {
|
|
|
9025
9252
|
|
|
9026
9253
|
// dist/clients/inline-blocker-dispositions.js
|
|
9027
9254
|
import * as fs16 from "node:fs";
|
|
9028
|
-
import * as
|
|
9255
|
+
import * as path23 from "node:path";
|
|
9029
9256
|
function readCurrentContent(filePath) {
|
|
9030
9257
|
try {
|
|
9031
9258
|
return fs16.readFileSync(filePath, "utf-8");
|
|
@@ -9053,7 +9280,7 @@ function applyInlineBlockerPolicy(record, cwd) {
|
|
|
9053
9280
|
}
|
|
9054
9281
|
const byFile = /* @__PURE__ */ new Map();
|
|
9055
9282
|
for (const diagnostic of diagnostics) {
|
|
9056
|
-
const owner =
|
|
9283
|
+
const owner = path23.resolve(cwd, diagnostic.filePath);
|
|
9057
9284
|
const group = byFile.get(owner);
|
|
9058
9285
|
if (group)
|
|
9059
9286
|
group.push(diagnostic);
|
|
@@ -9192,21 +9419,6 @@ var TEST_RUNNER_MAX_TARGETS = 12;
|
|
|
9192
9419
|
var TURN_END_SELECTION_ROOT_ROWS = 8;
|
|
9193
9420
|
var TEST_RUNNER_BATCH_BUDGET_MS = 2e4;
|
|
9194
9421
|
var TEST_RUNNER_MAX_DEFERRALS = 2;
|
|
9195
|
-
var TEST_RUNNER_MAX_PERSISTED_TARGETS = 64;
|
|
9196
|
-
function deferralEntryKey(entry) {
|
|
9197
|
-
return `${entry.sessionId ?? ""}\0${normalizeMapKey(path23.resolve(entry.testFile))}`;
|
|
9198
|
-
}
|
|
9199
|
-
function mergeDeferredTargets(existing, incoming) {
|
|
9200
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
9201
|
-
for (const entry of [...existing, ...incoming]) {
|
|
9202
|
-
const key = deferralEntryKey(entry);
|
|
9203
|
-
const prior = byKey.get(key);
|
|
9204
|
-
if (prior && (prior.attempts ?? 0) >= (entry.attempts ?? 0))
|
|
9205
|
-
continue;
|
|
9206
|
-
byKey.set(key, entry);
|
|
9207
|
-
}
|
|
9208
|
-
return [...byKey.values()];
|
|
9209
|
-
}
|
|
9210
9422
|
async function runTestTargetsBounded(args) {
|
|
9211
9423
|
const results = [];
|
|
9212
9424
|
if (args.targets.length === 0)
|
|
@@ -9249,7 +9461,7 @@ async function runTestTargetsBounded(args) {
|
|
|
9249
9461
|
});
|
|
9250
9462
|
void pool.catch(() => {
|
|
9251
9463
|
});
|
|
9252
|
-
await new Promise((
|
|
9464
|
+
await new Promise((resolve32) => {
|
|
9253
9465
|
let settled = false;
|
|
9254
9466
|
const finish = (reason) => {
|
|
9255
9467
|
if (settled)
|
|
@@ -9261,7 +9473,7 @@ async function runTestTargetsBounded(args) {
|
|
|
9261
9473
|
batchAbort.abort();
|
|
9262
9474
|
clearTimeout(timer);
|
|
9263
9475
|
args.signal?.removeEventListener("abort", onAbort);
|
|
9264
|
-
|
|
9476
|
+
resolve32();
|
|
9265
9477
|
};
|
|
9266
9478
|
const onAbort = () => finish("abort");
|
|
9267
9479
|
const timer = setTimeout(() => finish("budget"), budgetMs);
|
|
@@ -9495,22 +9707,26 @@ async function handleTurnEnd(deps) {
|
|
|
9495
9707
|
dbg(`turn_end: retaining newer turn state (dispatch=${turnIndexAtDispatch}, current=${runtime.turnIndex})`);
|
|
9496
9708
|
return;
|
|
9497
9709
|
}
|
|
9498
|
-
cacheManager2.clearTurnState(cwd, currentOwner);
|
|
9710
|
+
cacheManager2.clearTurnState(cwd, currentOwner, isSecondarySession ? sessionId : void 0);
|
|
9499
9711
|
};
|
|
9500
9712
|
void updateHeartbeat().catch(() => {
|
|
9501
9713
|
});
|
|
9502
9714
|
const cwd = ctxCwd ?? process.cwd();
|
|
9503
|
-
|
|
9715
|
+
const isSecondarySession = deps.sessionScope?.role === "secondary";
|
|
9716
|
+
const sessionRole = isSecondarySession ? "secondary" : "primary";
|
|
9717
|
+
const allowProjectWideFindings = admitsProjectWideFindings(sessionRole);
|
|
9718
|
+
const turnStateSessionId = isSecondarySession ? sessionId : void 0;
|
|
9719
|
+
let turnState = cacheManager2.readTurnState(cwd, turnStateSessionId);
|
|
9504
9720
|
const currentOwner = {
|
|
9505
9721
|
...owner ?? {
|
|
9506
9722
|
kind: "pi",
|
|
9507
|
-
id: runtime.telemetrySessionId,
|
|
9723
|
+
id: sessionId ?? runtime.telemetrySessionId,
|
|
9508
9724
|
pid: process.pid,
|
|
9509
9725
|
lastSeen: (/* @__PURE__ */ new Date()).toISOString()
|
|
9510
9726
|
},
|
|
9511
9727
|
sessionStartedAt: owner?.sessionStartedAt ?? runtime.sessionStartedAt
|
|
9512
9728
|
};
|
|
9513
|
-
const access = cacheManager2.getTurnStateAccess(cwd, currentOwner);
|
|
9729
|
+
const access = isSecondarySession ? "owned" : cacheManager2.getTurnStateAccess(cwd, currentOwner);
|
|
9514
9730
|
const gateOwnerLabel = turnState.owner ? `${turnState.owner.kind}:${turnState.owner.id}` : turnState.sessionId ? `legacy:${turnState.sessionId}` : "none";
|
|
9515
9731
|
const sameProcessPiSessionHandoff = access === "foreign-live" && currentOwner.kind === "pi" && turnState.owner?.kind === "pi" && turnState.owner.pid === process.pid && turnState.owner.id !== currentOwner.id;
|
|
9516
9732
|
if (access === "foreign-live" && !sameProcessPiSessionHandoff) {
|
|
@@ -9520,9 +9736,10 @@ async function handleTurnEnd(deps) {
|
|
|
9520
9736
|
if (access === "available" && (turnState.files || turnState.owner || turnState.sessionId)) {
|
|
9521
9737
|
dbg("turn_end: evicting stale turn-state owner");
|
|
9522
9738
|
clearOwnedTurnState();
|
|
9523
|
-
turnState = cacheManager2.readTurnState(cwd);
|
|
9739
|
+
turnState = cacheManager2.readTurnState(cwd, turnStateSessionId);
|
|
9524
9740
|
}
|
|
9525
|
-
const
|
|
9741
|
+
const ownFiles = Object.keys(turnState.files);
|
|
9742
|
+
const files = ownFiles;
|
|
9526
9743
|
let widgetDemotedFindingsRetired = 0;
|
|
9527
9744
|
for (const wPath of drainRenderedDependencyDriftFilePaths()) {
|
|
9528
9745
|
const deliveryCount = incrementWidgetDependencyDriftDelivery(wPath);
|
|
@@ -9538,7 +9755,7 @@ async function handleTurnEnd(deps) {
|
|
|
9538
9755
|
}
|
|
9539
9756
|
}
|
|
9540
9757
|
}
|
|
9541
|
-
if (files.length === 0 && !runtime.hasCascadeRuns()) {
|
|
9758
|
+
if (files.length === 0 && !runtime.hasCascadeRuns() && !isSecondarySession) {
|
|
9542
9759
|
if (getFlag("lens-guard") && !runtime.gitGuardHasBlockers) {
|
|
9543
9760
|
const guardRecord = cacheManager2.readCache("turn-end-findings", cwd)?.data;
|
|
9544
9761
|
if (guardRecord?.sessionId === runtime.telemetrySessionId && guardRecord.testFailures !== true) {
|
|
@@ -9570,7 +9787,7 @@ async function handleTurnEnd(deps) {
|
|
|
9570
9787
|
dbg("turn_end: cancelled pending LSP idle reset (active editing)");
|
|
9571
9788
|
}
|
|
9572
9789
|
dbg(`turn_end: ${files.length} file(s) modified, cycles: ${turnState.turnCycles}/${turnState.maxCycles}, access: ${access}, owner: ${gateOwnerLabel}`);
|
|
9573
|
-
if (cacheManager2.isMaxCyclesExceeded(cwd)) {
|
|
9790
|
+
if (cacheManager2.isMaxCyclesExceeded(cwd, turnStateSessionId)) {
|
|
9574
9791
|
dbg("turn_end: max cycles exceeded, clearing state and forcing through");
|
|
9575
9792
|
clearOwnedTurnState();
|
|
9576
9793
|
runtime.fixedThisTurn.clear();
|
|
@@ -9613,7 +9830,14 @@ async function handleTurnEnd(deps) {
|
|
|
9613
9830
|
const projectDiagnosticsDelta = [];
|
|
9614
9831
|
const projectDiagnosticsSources = /* @__PURE__ */ new Set();
|
|
9615
9832
|
const runnerFindingsStart = Date.now();
|
|
9616
|
-
const
|
|
9833
|
+
const runnerDrainSignal = deps.signal;
|
|
9834
|
+
const deliverySessionId = sessionId ?? runtime.telemetrySessionId;
|
|
9835
|
+
const pendingRunnerFindings = await bounded(drainPendingRunnerFindings(0, runtime.sessionScope.capture(), deliverySessionId), {
|
|
9836
|
+
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
9837
|
+
signal: runnerDrainSignal,
|
|
9838
|
+
hook: "turn_end",
|
|
9839
|
+
label: "drainPendingRunnerFindings"
|
|
9840
|
+
}) ?? [];
|
|
9617
9841
|
let runnerFindingsDelivered = 0;
|
|
9618
9842
|
let runnerFindingsStale = 0;
|
|
9619
9843
|
let runnerFindingsFailed = 0;
|
|
@@ -9838,7 +10062,16 @@ ${policy.body}`);
|
|
|
9838
10062
|
});
|
|
9839
10063
|
}
|
|
9840
10064
|
const cascadeSettleStart = Date.now();
|
|
9841
|
-
const
|
|
10065
|
+
const cascadeSettleSignal = deps.signal;
|
|
10066
|
+
const { settled, timedOut } = await bounded(runtime.settleCascadeRuns(cascadeSettleWaitMs(), {
|
|
10067
|
+
trackTurnEndClock: true,
|
|
10068
|
+
generation: holdScope
|
|
10069
|
+
}), {
|
|
10070
|
+
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
10071
|
+
signal: cascadeSettleSignal,
|
|
10072
|
+
hook: "turn_end",
|
|
10073
|
+
label: "settleCascadeRuns"
|
|
10074
|
+
}) ?? { settled: 0, timedOut: 0 };
|
|
9842
10075
|
logLatency({
|
|
9843
10076
|
type: "phase",
|
|
9844
10077
|
toolName: "turn_end",
|
|
@@ -9855,11 +10088,11 @@ ${policy.body}`);
|
|
|
9855
10088
|
const changedSince = runtime.getFilesChangedSince(originSeq);
|
|
9856
10089
|
if (changedSince.length > 0) {
|
|
9857
10090
|
const changedSet = new Set(changedSince);
|
|
9858
|
-
const primaryKey = normalizeMapKey(
|
|
10091
|
+
const primaryKey = normalizeMapKey(path24.resolve(run.filePath));
|
|
9859
10092
|
const neighborKeys = [
|
|
9860
10093
|
...(run.result?.neighbors ?? []).map((n) => n.filePath),
|
|
9861
10094
|
...run.selectedNeighborPaths ?? []
|
|
9862
|
-
].map((filePath) => normalizeMapKey(
|
|
10095
|
+
].map((filePath) => normalizeMapKey(path24.resolve(filePath)));
|
|
9863
10096
|
const supersededByOwnFile = changedSet.has(primaryKey) || neighborKeys.some((k) => changedSet.has(k));
|
|
9864
10097
|
if (supersededByOwnFile) {
|
|
9865
10098
|
logCascade({
|
|
@@ -10565,15 +10798,15 @@ ${suffix}`;
|
|
|
10565
10798
|
const govGate = scannerGates.govulncheck;
|
|
10566
10799
|
const gitleaksGate = scannerGates.gitleaks;
|
|
10567
10800
|
const trivySecretsGate = scannerGates["trivy-secrets"];
|
|
10568
|
-
const govDelivery = govulncheckLane.render(govulncheckLane.gate({ govulncheck: govGate }, laneCtx), laneCtx);
|
|
10801
|
+
const govDelivery = allowProjectWideFindings ? govulncheckLane.render(govulncheckLane.gate({ govulncheck: govGate }, laneCtx), laneCtx) : {};
|
|
10569
10802
|
for (const [store, count] of Object.entries(govDelivery.dispositionSuppressed ?? {})) {
|
|
10570
10803
|
recordDispositionSuppressed(store, count);
|
|
10571
10804
|
}
|
|
10572
10805
|
advisoryParts.push(...govDelivery.advisoryParts ?? []);
|
|
10573
|
-
const secretsDelivery = secretsLane.render(secretsLane.gate({
|
|
10806
|
+
const secretsDelivery = allowProjectWideFindings ? secretsLane.render(secretsLane.gate({
|
|
10574
10807
|
gitleaks: gitleaksGate,
|
|
10575
10808
|
"trivy-secrets": trivySecretsGate
|
|
10576
|
-
}, laneCtx), laneCtx);
|
|
10809
|
+
}, laneCtx), laneCtx) : {};
|
|
10577
10810
|
for (const [store, count] of Object.entries(secretsDelivery.dispositionSuppressed ?? {})) {
|
|
10578
10811
|
recordDispositionSuppressed(store, count);
|
|
10579
10812
|
}
|
|
@@ -10640,16 +10873,22 @@ ${suffix}`;
|
|
|
10640
10873
|
}
|
|
10641
10874
|
const t3 = Date.now();
|
|
10642
10875
|
let madgeStats;
|
|
10643
|
-
|
|
10644
|
-
|
|
10876
|
+
const madgeAvailabilitySignal = deps.signal;
|
|
10877
|
+
if (getFlag("lens-turn-end-madge") && await bounded(depChecker.ensureAvailable(), {
|
|
10878
|
+
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
10879
|
+
signal: madgeAvailabilitySignal,
|
|
10880
|
+
hook: "turn_end",
|
|
10881
|
+
label: "madge.ensureAvailable"
|
|
10882
|
+
})) {
|
|
10883
|
+
const madgeFiles = cacheManager2.getFilesForMadge(cwd, turnStateSessionId);
|
|
10645
10884
|
if (madgeFiles.length > 0) {
|
|
10646
10885
|
dbg(`turn_end: madge checking ${madgeFiles.length} file(s) for circular deps`);
|
|
10647
|
-
const absFiles = madgeFiles.map((file) =>
|
|
10886
|
+
const absFiles = madgeFiles.map((file) => path24.resolve(cwd, file));
|
|
10648
10887
|
const batch = await depChecker.checkFilesBatch(absFiles, cwd);
|
|
10649
10888
|
const depResults = batch.results;
|
|
10650
10889
|
madgeStats = batch.stats;
|
|
10651
10890
|
for (const file of madgeFiles) {
|
|
10652
|
-
const absPath =
|
|
10891
|
+
const absPath = path24.resolve(cwd, file);
|
|
10653
10892
|
const depResult = depResults.get(absPath);
|
|
10654
10893
|
if (!depResult)
|
|
10655
10894
|
continue;
|
|
@@ -10685,7 +10924,7 @@ ${suffix}`;
|
|
|
10685
10924
|
}
|
|
10686
10925
|
for (const result of cascadeResults) {
|
|
10687
10926
|
for (const neighbor of result.neighbors) {
|
|
10688
|
-
const abs =
|
|
10927
|
+
const abs = path24.isAbsolute(neighbor.filePath) ? neighbor.filePath : resolveRunnerPath(cwd, neighbor.filePath);
|
|
10689
10928
|
const key = normalizeMapKey(abs);
|
|
10690
10929
|
if (seenCandidateKeys.has(key))
|
|
10691
10930
|
continue;
|
|
@@ -10697,20 +10936,17 @@ ${suffix}`;
|
|
|
10697
10936
|
const carriedDeferred = priorTestCache?.deferredTargets ?? [];
|
|
10698
10937
|
const turnSessionId = sessionId ?? runtime.telemetrySessionId;
|
|
10699
10938
|
const isThisSession = (entry) => entry.sessionId === turnSessionId;
|
|
10700
|
-
const entryPathKey = (entry) => normalizeMapKey(
|
|
10939
|
+
const entryPathKey = (entry) => normalizeMapKey(path24.resolve(cwd, entry.testFile));
|
|
10701
10940
|
const retiredCarry = (priorTestCache?.retiredTargets ?? []).filter(isThisSession);
|
|
10702
10941
|
const retiredKeys = new Set(retiredCarry.map(entryPathKey));
|
|
10703
10942
|
const resolvedDeferralKeys = /* @__PURE__ */ new Set();
|
|
10704
10943
|
const heldDeferred = [];
|
|
10705
10944
|
const boundPersisted = (entries, label) => {
|
|
10706
|
-
const
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
return ordered;
|
|
10712
|
-
dbg(`turn_end: ${label} test target list held ${ordered.length} entries, bounded to the newest ${TEST_RUNNER_MAX_PERSISTED_TARGETS} (oldest foreign-session rows dropped)`);
|
|
10713
|
-
return ordered.slice(-TEST_RUNNER_MAX_PERSISTED_TARGETS);
|
|
10945
|
+
const bounded2 = boundDeferredTargets(entries, TEST_RUNNER_MAX_PERSISTED_TARGETS, isThisSession);
|
|
10946
|
+
if (bounded2.length !== entries.length) {
|
|
10947
|
+
dbg(`turn_end: ${label} test target list held ${entries.length} entries, bounded to the newest ${TEST_RUNNER_MAX_PERSISTED_TARGETS} (oldest foreign-session rows dropped)`);
|
|
10948
|
+
}
|
|
10949
|
+
return bounded2;
|
|
10714
10950
|
};
|
|
10715
10951
|
const writeTestFindings = (record, ownDeferred) => {
|
|
10716
10952
|
const live = cacheManager2.readCache("test-runner-findings", cwd)?.data;
|
|
@@ -10734,7 +10970,7 @@ ${suffix}`;
|
|
|
10734
10970
|
let redispatchedDeferred = 0;
|
|
10735
10971
|
let retiredThisTurn = 0;
|
|
10736
10972
|
for (const carried of carriedDeferred) {
|
|
10737
|
-
const testFile =
|
|
10973
|
+
const testFile = path24.resolve(cwd, carried.testFile);
|
|
10738
10974
|
const carriedKey = normalizeMapKey(testFile);
|
|
10739
10975
|
if (!isThisSession(carried)) {
|
|
10740
10976
|
foreignDeferred++;
|
|
@@ -10759,9 +10995,9 @@ ${suffix}`;
|
|
|
10759
10995
|
incrementDegradationCount({
|
|
10760
10996
|
kind: "test-runner-batch-capped",
|
|
10761
10997
|
subject: `${cwd}:deferral-exhausted`,
|
|
10762
|
-
reason: `test target was cut after ${attempts} turn(s) at the turn-end budget and is retired for this session \u2014 too slow for a per-turn batch; run it explicitly (target: ${
|
|
10998
|
+
reason: `test target was cut after ${attempts} turn(s) at the turn-end budget and is retired for this session \u2014 too slow for a per-turn batch; run it explicitly (target: ${path24.relative(cwd, testFile)})`
|
|
10763
10999
|
});
|
|
10764
|
-
dbg(`turn_end: retiring deferred test target ${
|
|
11000
|
+
dbg(`turn_end: retiring deferred test target ${path24.relative(cwd, testFile)} after ${attempts} cut batch(es) \u2014 too slow for the turn-end budget, run it explicitly`);
|
|
10765
11001
|
}
|
|
10766
11002
|
continue;
|
|
10767
11003
|
}
|
|
@@ -10795,7 +11031,7 @@ ${suffix}`;
|
|
|
10795
11031
|
testRoot: carriedRoot,
|
|
10796
11032
|
deferralAttempts: attempts
|
|
10797
11033
|
});
|
|
10798
|
-
dbg(`turn_end: re-running deferred test target ${
|
|
11034
|
+
dbg(`turn_end: re-running deferred test target ${path24.relative(cwd, testFile)} (${carried.runner}) from the previous turn's cut batch`);
|
|
10799
11035
|
}
|
|
10800
11036
|
if (deadDeferred > 0) {
|
|
10801
11037
|
dbg(`turn_end: dropped ${deadDeferred} deferred test target(s) that no longer resolve (missing file, excluded, or unknown runner)`);
|
|
@@ -10839,17 +11075,17 @@ ${suffix}`;
|
|
|
10839
11075
|
seen.add(targetKey);
|
|
10840
11076
|
if (retiredKeys.has(targetKey)) {
|
|
10841
11077
|
retiredSkips++;
|
|
10842
|
-
dbg(`turn_end: ${display} \u2192 test target retired earlier this session (outran the turn-end batch budget), skipping spawn (${
|
|
11078
|
+
dbg(`turn_end: ${display} \u2192 test target retired earlier this session (outran the turn-end batch budget), skipping spawn (${path24.relative(cwd, target.testFile)})`);
|
|
10843
11079
|
continue;
|
|
10844
11080
|
}
|
|
10845
11081
|
if (isExcludedTestTarget(target.testFile, testRoot)) {
|
|
10846
11082
|
excludedTargets++;
|
|
10847
|
-
dbg(`turn_end: ${display} \u2192 test target excluded by the built-in turn-end policy, skipping spawn (${
|
|
11083
|
+
dbg(`turn_end: ${display} \u2192 test target excluded by the built-in turn-end policy, skipping spawn (${path24.relative(cwd, target.testFile)})`);
|
|
10848
11084
|
continue;
|
|
10849
11085
|
}
|
|
10850
11086
|
if (!fs17.existsSync(target.testFile)) {
|
|
10851
11087
|
missingTargetFiles++;
|
|
10852
|
-
dbg(`turn_end: ${display} \u2192 test file missing, skipping spawn (${
|
|
11088
|
+
dbg(`turn_end: ${display} \u2192 test file missing, skipping spawn (${path24.relative(cwd, target.testFile)})`);
|
|
10853
11089
|
continue;
|
|
10854
11090
|
}
|
|
10855
11091
|
if (targets.length >= TEST_RUNNER_MAX_TARGETS) {
|
|
@@ -10857,7 +11093,7 @@ ${suffix}`;
|
|
|
10857
11093
|
continue;
|
|
10858
11094
|
}
|
|
10859
11095
|
targets.push({ ...target, sourceFile: abs, testRoot });
|
|
10860
|
-
dbg(`turn_end: ${display} \u2192 test ${target.runner} ${
|
|
11096
|
+
dbg(`turn_end: ${display} \u2192 test ${target.runner} ${path24.relative(cwd, target.testFile)} (${target.strategy}${isNeighbor ? ", cascade-neighbor" : ""})`);
|
|
10861
11097
|
} else if (!target) {
|
|
10862
11098
|
noTestFile++;
|
|
10863
11099
|
dbg(`turn_end: ${display} \u2192 no test file found${isNeighbor ? " (cascade-neighbor)" : ""}`);
|
|
@@ -10989,6 +11225,7 @@ ${suffix}`;
|
|
|
10989
11225
|
{
|
|
10990
11226
|
file: result.value.file,
|
|
10991
11227
|
sourceFile: target.sourceFile,
|
|
11228
|
+
runner: target.runner,
|
|
10992
11229
|
fileSeq: target.fileSeqAtRun === void 0 ? {
|
|
10993
11230
|
state: "unknown",
|
|
10994
11231
|
reason: "sequence-unavailable"
|
|
@@ -11020,7 +11257,7 @@ ${suffix}`;
|
|
|
11020
11257
|
});
|
|
11021
11258
|
dbg(`turn_end: test batch stopped early (${stopReason ?? "incomplete"}), ${deferred.length} target(s) deferred to the next turn`);
|
|
11022
11259
|
}
|
|
11023
|
-
const deferralNote = deferred.length > 0 ? `${deferred.length} test target(s) did not finish within the turn-end batch budget and are deferred to the next turn (they run first): ${deferredTargets.map((t) =>
|
|
11260
|
+
const deferralNote = deferred.length > 0 ? `${deferred.length} test target(s) did not finish within the turn-end batch budget and are deferred to the next turn (they run first): ${deferredTargets.map((t) => path24.relative(cwd, t.testFile)).join(", ")}` : "";
|
|
11024
11261
|
const supersededByNewerGeneration = (label) => {
|
|
11025
11262
|
const current = cacheManager2.readCache("test-runner-findings", cwd)?.data;
|
|
11026
11263
|
const currentGeneration = current?.testRunGeneration;
|
|
@@ -11072,7 +11309,7 @@ ${suffix}`;
|
|
|
11072
11309
|
const { file, runner, passed, failed, duration, error } = r.value;
|
|
11073
11310
|
if (failed > 0)
|
|
11074
11311
|
hasRealFailure = true;
|
|
11075
|
-
const shortFile =
|
|
11312
|
+
const shortFile = path24.basename(file);
|
|
11076
11313
|
const elapsed = formatRunDurationMs(duration);
|
|
11077
11314
|
const verdict = failed > 0 ? "FAIL" : "PASS";
|
|
11078
11315
|
const summary = isRunnerErrorResult(r.value) ? passed > 0 ? `error: ${error} (${passed} passed before)` : `error: ${error}` : `${verdict} ${passed}p/${failed}f (${elapsed})`;
|
|
@@ -11236,8 +11473,8 @@ ${suffix}`;
|
|
|
11236
11473
|
} else {
|
|
11237
11474
|
const callGraphStart = Date.now();
|
|
11238
11475
|
try {
|
|
11239
|
-
const { impact, formatImpact, parseSymbolKey } = await import("../chunk-
|
|
11240
|
-
const { callGraphImpactToProjectDiagnostics } = await import("../chunk-
|
|
11476
|
+
const { impact, formatImpact, parseSymbolKey } = await import("../chunk-BKE7E7TC.js");
|
|
11477
|
+
const { callGraphImpactToProjectDiagnostics } = await import("../chunk-6GFRNVYR.js");
|
|
11241
11478
|
const impactLines = [];
|
|
11242
11479
|
let callGraphDispositionSuppressed = 0;
|
|
11243
11480
|
const impactFindings = [];
|
|
@@ -11544,13 +11781,17 @@ ${impactLines.join("\n")}`;
|
|
|
11544
11781
|
}
|
|
11545
11782
|
});
|
|
11546
11783
|
}
|
|
11547
|
-
cacheManager2.incrementTurnCycle(cwd, currentOwner);
|
|
11784
|
+
cacheManager2.incrementTurnCycle(cwd, currentOwner, turnStateSessionId);
|
|
11548
11785
|
const lateAuxStart = Date.now();
|
|
11549
|
-
const
|
|
11786
|
+
const lateAuxDrain = isSecondarySession ? {
|
|
11787
|
+
drainedPairs: drainPendingAuxiliaryCoverage(),
|
|
11788
|
+
lateAuxCapEvicted: drainPendingAuxCapEvictedCount()
|
|
11789
|
+
} : holdScope.guardedWrite("turn-end:late-aux", () => ({
|
|
11550
11790
|
drainedPairs: drainPendingAuxiliaryCoverage(),
|
|
11551
11791
|
lateAuxCapEvicted: drainPendingAuxCapEvictedCount()
|
|
11552
11792
|
})) ?? { drainedPairs: [], lateAuxCapEvicted: 0 };
|
|
11553
|
-
const
|
|
11793
|
+
const { drainedPairs, lateAuxCapEvicted } = lateAuxDrain;
|
|
11794
|
+
const rearmLateAux = (pair) => isSecondarySession ? (rearmPendingAuxiliaryCoverage(pair), true) : holdScope.guardedWrite(
|
|
11554
11795
|
// One subject for the store (#4168 F3): the row's count carries how many.
|
|
11555
11796
|
"turn-end:late-aux-rearm",
|
|
11556
11797
|
() => {
|
|
@@ -11830,7 +12071,7 @@ ${lines.join("\n")}`;
|
|
|
11830
12071
|
}
|
|
11831
12072
|
});
|
|
11832
12073
|
}
|
|
11833
|
-
const unresolvedKeys = new Set(unresolvedBlockers.map((record) => normalizeMapKey(
|
|
12074
|
+
const unresolvedKeys = new Set(unresolvedBlockers.map((record) => normalizeMapKey(path24.resolve(record.filePath))));
|
|
11834
12075
|
const formatResolvedTail = (dropped) => `\u2026 and ${dropped} more`;
|
|
11835
12076
|
const resolvedTailMax = formatResolvedTail(Number.MAX_SAFE_INTEGER).length;
|
|
11836
12077
|
const resolvedShareChars = Math.floor(RUNTIME_CONFIG.turnEnd.maxChars * RESOLVED_SHARE_OF_CHARS) - resolvedTailMax;
|
|
@@ -11855,7 +12096,7 @@ ${lines.join("\n")}`;
|
|
|
11855
12096
|
let resolvedChars = 0;
|
|
11856
12097
|
let resolvedCount = 0;
|
|
11857
12098
|
const { files: resolvedBlockerFileList, dropped: resolvedBlockerFilesDropped } = runtime.consumeResolvedBlockerFiles((entry) => {
|
|
11858
|
-
if (unresolvedKeys.has(normalizeMapKey(
|
|
12099
|
+
if (unresolvedKeys.has(normalizeMapKey(path24.resolve(entry.filePath))))
|
|
11859
12100
|
return true;
|
|
11860
12101
|
const cost = formatResolvedLine(entry).length + 1;
|
|
11861
12102
|
if (resolvedCount > 0 && (resolvedCount >= resolvedLineBudget || resolvedChars + cost > resolvedCharBudget))
|
|
@@ -11951,7 +12192,7 @@ ${raw}`
|
|
|
11951
12192
|
projectSeqStart: runtime.turnStartProjectSeq,
|
|
11952
12193
|
projectSeqEnd: runtime.projectSeq,
|
|
11953
12194
|
fileSeqByPath: Object.fromEntries(runtime.getFileSeqEntries().map(([filePath, seq]) => [
|
|
11954
|
-
normalizeMapKey(
|
|
12195
|
+
normalizeMapKey(path24.resolve(filePath)),
|
|
11955
12196
|
seq
|
|
11956
12197
|
])),
|
|
11957
12198
|
fileContentHashes: {},
|
|
@@ -11968,7 +12209,7 @@ ${raw}`
|
|
|
11968
12209
|
settleHolds(false);
|
|
11969
12210
|
const fileSeqByPath2 = {};
|
|
11970
12211
|
for (const [filePath, seq] of runtime.getFileSeqEntries()) {
|
|
11971
|
-
fileSeqByPath2[normalizeMapKey(
|
|
12212
|
+
fileSeqByPath2[normalizeMapKey(path24.resolve(filePath))] = seq;
|
|
11972
12213
|
}
|
|
11973
12214
|
if (getFlag("lens-guard")) {
|
|
11974
12215
|
const existingGuard = cacheManager2.readCache("turn-end-findings", cwd)?.data;
|
|
@@ -12186,10 +12427,10 @@ var TurnEndQueue = class {
|
|
|
12186
12427
|
if (this.pending.length >= 1) {
|
|
12187
12428
|
return Promise.reject(new Error("turn_end queue is busy"));
|
|
12188
12429
|
}
|
|
12189
|
-
return new Promise((
|
|
12430
|
+
return new Promise((resolve32, reject) => {
|
|
12190
12431
|
const item = {
|
|
12191
12432
|
work,
|
|
12192
|
-
resolve:
|
|
12433
|
+
resolve: resolve32,
|
|
12193
12434
|
reject,
|
|
12194
12435
|
timer: setTimeout(() => {
|
|
12195
12436
|
const index = this.pending.indexOf(item);
|
|
@@ -12233,7 +12474,7 @@ async function runTurnEndNowImpl(cwd, files = [], deferredDelivery = false) {
|
|
|
12233
12474
|
const host = createMcpHost(void 0, cwd);
|
|
12234
12475
|
let registered = 0;
|
|
12235
12476
|
for (const file of files) {
|
|
12236
|
-
const abs =
|
|
12477
|
+
const abs = path25.isAbsolute(file) ? file : path25.resolve(cwd, file);
|
|
12237
12478
|
let lineCount3 = 1;
|
|
12238
12479
|
try {
|
|
12239
12480
|
lineCount3 = fs18.readFileSync(abs, "utf8").split("\n").length;
|
|
@@ -12377,7 +12618,7 @@ function acknowledgeTurnEnd(cwd, deliveryId) {
|
|
|
12377
12618
|
|
|
12378
12619
|
// dist/clients/module-report.js
|
|
12379
12620
|
import * as fs19 from "node:fs";
|
|
12380
|
-
import * as
|
|
12621
|
+
import * as path26 from "node:path";
|
|
12381
12622
|
|
|
12382
12623
|
// dist/clients/middle-man-analysis.js
|
|
12383
12624
|
var SELF_TOKEN = {
|
|
@@ -12926,7 +13167,7 @@ function blastReadArgs(graph, normalizedFile) {
|
|
|
12926
13167
|
return { path: normalizedFile, offset: 1, limit };
|
|
12927
13168
|
}
|
|
12928
13169
|
async function computeBlastRadius(graph, normalizedPath, projectRoot, maxDepth) {
|
|
12929
|
-
const { computeTransitiveImpact } = await import("../chunk-
|
|
13170
|
+
const { computeTransitiveImpact } = await import("../chunk-4UNXBNE2.js");
|
|
12930
13171
|
const result = computeTransitiveImpact(graph, normalizedPath, { maxDepth });
|
|
12931
13172
|
const byFile = /* @__PURE__ */ new Map();
|
|
12932
13173
|
for (const hit of result.hits) {
|
|
@@ -13516,7 +13757,7 @@ async function moduleReport(file, cwd, options) {
|
|
|
13516
13757
|
const startedAt = Date.now();
|
|
13517
13758
|
const maxRefs = normalizeMaxRefsPerSymbol(options?.maxRefsPerSymbol);
|
|
13518
13759
|
const maxCallGraphEntries = Math.min(CALL_GRAPH_MAX_ENTRY_CAP, Math.max(1, Math.floor(options?.maxCallGraphEntries ?? CALL_GRAPH_DEFAULT_ENTRY_CAP)));
|
|
13519
|
-
const absPath =
|
|
13760
|
+
const absPath = path26.resolve(cwd, file);
|
|
13520
13761
|
const normalizedPath = normalizeMapKey(absPath);
|
|
13521
13762
|
let content;
|
|
13522
13763
|
try {
|
|
@@ -13543,7 +13784,7 @@ async function moduleReport(file, cwd, options) {
|
|
|
13543
13784
|
let callGraphIdentity;
|
|
13544
13785
|
let revisionDriftNote;
|
|
13545
13786
|
try {
|
|
13546
|
-
const { getCachedReviewGraph, getReviewGraphCacheIdentity, getReviewGraphSizeSkipVerdict, getReviewGraphRevisionDrift, formatReviewGraphRevisionDriftNote: formatReviewGraphRevisionDriftNote2 } = await import("../chunk-
|
|
13787
|
+
const { getCachedReviewGraph, getReviewGraphCacheIdentity, getReviewGraphSizeSkipVerdict, getReviewGraphRevisionDrift, formatReviewGraphRevisionDriftNote: formatReviewGraphRevisionDriftNote2 } = await import("../chunk-2ZGIZPDG.js");
|
|
13547
13788
|
graph = getCachedReviewGraph(cwd);
|
|
13548
13789
|
graphFileCap = getReviewGraphSizeSkipVerdict(cwd)?.maxFileCount;
|
|
13549
13790
|
const drift = graph ? getReviewGraphRevisionDrift(cwd) : void 0;
|
|
@@ -13833,7 +14074,7 @@ function suggestSimilarNames(candidates, target) {
|
|
|
13833
14074
|
async function readSymbol(file, symbolName, cwd, options = {}) {
|
|
13834
14075
|
const { kind: symbolKindFilter } = options;
|
|
13835
14076
|
const startedAt = Date.now();
|
|
13836
|
-
const absPath =
|
|
14077
|
+
const absPath = path26.resolve(cwd, file);
|
|
13837
14078
|
const log = (found) => {
|
|
13838
14079
|
logLatency({
|
|
13839
14080
|
type: "phase",
|
|
@@ -14008,7 +14249,7 @@ function enclosingOutline(selected, symbols, callbacks, filters, filePath) {
|
|
|
14008
14249
|
}
|
|
14009
14250
|
async function readEnclosing(file, line, cwd, options) {
|
|
14010
14251
|
const startedAt = Date.now();
|
|
14011
|
-
const absPath =
|
|
14252
|
+
const absPath = path26.resolve(cwd, file);
|
|
14012
14253
|
const targetLine = Math.max(1, Math.floor(line));
|
|
14013
14254
|
const log = (found) => {
|
|
14014
14255
|
logLatency({
|
|
@@ -14184,7 +14425,7 @@ async function readEnclosing(file, line, cwd, options) {
|
|
|
14184
14425
|
}
|
|
14185
14426
|
|
|
14186
14427
|
// dist/clients/project-report.js
|
|
14187
|
-
import * as
|
|
14428
|
+
import * as path27 from "node:path";
|
|
14188
14429
|
var DEFAULT_LIMIT = 10;
|
|
14189
14430
|
var STALE_THRESHOLD_MS = 15 * 6e4;
|
|
14190
14431
|
var LOW_COVERAGE_THRESHOLD = 0.8;
|
|
@@ -14327,7 +14568,7 @@ function roleFor(graph, filePath) {
|
|
|
14327
14568
|
return top.length > 0 ? top.map((s) => s.name).join(", ") : void 0;
|
|
14328
14569
|
}
|
|
14329
14570
|
async function computeHubs(graph, degrees, cwd, limit, focusTerms) {
|
|
14330
|
-
const { computeTransitiveImpact } = await import("../chunk-
|
|
14571
|
+
const { computeTransitiveImpact } = await import("../chunk-4UNXBNE2.js");
|
|
14331
14572
|
const ranked = [...graph.fileNodes.entries()].map(([filePath, fileNodeId]) => ({
|
|
14332
14573
|
filePath,
|
|
14333
14574
|
fileNodeId,
|
|
@@ -14565,7 +14806,7 @@ function computeDeadWeight(graph, degrees, entryPointFiles, cwd, limit) {
|
|
|
14565
14806
|
}
|
|
14566
14807
|
var inFlightGraphBuilds = /* @__PURE__ */ new Set();
|
|
14567
14808
|
function triggerBackgroundGraphBuild(cwd, deps) {
|
|
14568
|
-
const key = normalizeMapKey(
|
|
14809
|
+
const key = normalizeMapKey(path27.resolve(cwd));
|
|
14569
14810
|
if (inFlightGraphBuilds.has(key))
|
|
14570
14811
|
return "already_running";
|
|
14571
14812
|
const deduped = deps.isGraphBuildInFlight(key, []);
|
|
@@ -14579,7 +14820,7 @@ async function projectReport(cwd, options) {
|
|
|
14579
14820
|
const limit = clampLimit(options?.limit);
|
|
14580
14821
|
const focusTerms = normalizeFocus2(options?.focus);
|
|
14581
14822
|
const view = options?.view;
|
|
14582
|
-
const { getCachedReviewGraph, getReviewGraphSizeSkipVerdict, getLastReviewGraphBuildAttempt, buildOrUpdateGraph, isGraphBuildInFlight, getReviewGraphRevisionDrift } = await import("../chunk-
|
|
14823
|
+
const { getCachedReviewGraph, getReviewGraphSizeSkipVerdict, getLastReviewGraphBuildAttempt, buildOrUpdateGraph, isGraphBuildInFlight, getReviewGraphRevisionDrift } = await import("../chunk-2ZGIZPDG.js");
|
|
14583
14824
|
let graph;
|
|
14584
14825
|
try {
|
|
14585
14826
|
graph = getCachedReviewGraph(cwd);
|
|
@@ -14603,7 +14844,7 @@ async function projectReport(cwd, options) {
|
|
|
14603
14844
|
};
|
|
14604
14845
|
}
|
|
14605
14846
|
const previousAttempt = getLastReviewGraphBuildAttempt(cwd);
|
|
14606
|
-
const { FactStore: FactStore2 } = await import("../chunk-
|
|
14847
|
+
const { FactStore: FactStore2 } = await import("../chunk-QGQ5CCCG.js");
|
|
14607
14848
|
const trigger = triggerBackgroundGraphBuild(cwd, {
|
|
14608
14849
|
buildOrUpdateGraph,
|
|
14609
14850
|
isGraphBuildInFlight,
|
|
@@ -14705,7 +14946,7 @@ function renderCompactProjectReport(report) {
|
|
|
14705
14946
|
|
|
14706
14947
|
// dist/clients/effective-config.js
|
|
14707
14948
|
import * as os3 from "node:os";
|
|
14708
|
-
import * as
|
|
14949
|
+
import * as path28 from "node:path";
|
|
14709
14950
|
function isEffectiveFileViewError(file) {
|
|
14710
14951
|
return "error" in file;
|
|
14711
14952
|
}
|
|
@@ -14779,10 +15020,10 @@ async function effectiveConfig(options = {}) {
|
|
|
14779
15020
|
globalConfigPath: getPiLensGlobalConfigPath(),
|
|
14780
15021
|
homeDir
|
|
14781
15022
|
});
|
|
14782
|
-
const requestedFile = options.file === void 0 ? void 0 :
|
|
15023
|
+
const requestedFile = options.file === void 0 ? void 0 : path28.resolve(cwd, options.file);
|
|
14783
15024
|
const fileOutsideCwd = requestedFile !== void 0 && !isSameOrWithin(cwd, requestedFile);
|
|
14784
15025
|
const absolute = fileOutsideCwd ? void 0 : requestedFile;
|
|
14785
|
-
const resolution = resolveAt(absolute === void 0 ? cwd :
|
|
15026
|
+
const resolution = resolveAt(absolute === void 0 ? cwd : path28.dirname(absolute));
|
|
14786
15027
|
const resolved = {
|
|
14787
15028
|
value: resolution.value,
|
|
14788
15029
|
provenance: resolution.provenance
|
|
@@ -14816,7 +15057,7 @@ async function effectiveConfig(options = {}) {
|
|
|
14816
15057
|
// `{ absolute, lspConfig }` struct (#2520): `absolute` is already
|
|
14817
15058
|
// this branch's narrowed local, so the struct's own field was
|
|
14818
15059
|
// carrying the same fact twice.
|
|
14819
|
-
registerLSPConfig(lspConfigOf(resolution.value))
|
|
15060
|
+
registerLSPConfig(lspConfigOf(resolution.value, void 0, resolution.provenance))
|
|
14820
15061
|
)
|
|
14821
15062
|
}
|
|
14822
15063
|
};
|
|
@@ -14944,10 +15185,10 @@ function symbolSearchFileMatchesLang(file, lang) {
|
|
|
14944
15185
|
const exts = extensionsForLanguageToken(lang);
|
|
14945
15186
|
if (exts.length === 0)
|
|
14946
15187
|
return false;
|
|
14947
|
-
return exts.includes(
|
|
15188
|
+
return exts.includes(path29.extname(file).toLowerCase());
|
|
14948
15189
|
}
|
|
14949
15190
|
function fileMatchesPathGlobs(file, cwd, globs) {
|
|
14950
|
-
const rel =
|
|
15191
|
+
const rel = path29.relative(cwd, file).split(path29.sep).join("/");
|
|
14951
15192
|
const options = { dot: true, nocase: process.platform === "win32" };
|
|
14952
15193
|
return globs.some((raw) => {
|
|
14953
15194
|
const pattern = raw.split("\\").join("/");
|
|
@@ -14969,7 +15210,7 @@ function buildSymbolSearchFileFilter(cwd, options) {
|
|
|
14969
15210
|
}
|
|
14970
15211
|
function annotateSymbolSearchHitsWithGraph(hits, centrality, graph) {
|
|
14971
15212
|
for (const hit of hits) {
|
|
14972
|
-
const normalized = normalizeMapKey(
|
|
15213
|
+
const normalized = normalizeMapKey(path29.resolve(hit.file));
|
|
14973
15214
|
const fanIn = centrality.get(hit.file) ?? 0;
|
|
14974
15215
|
let complexity;
|
|
14975
15216
|
for (const symbolId of graph.symbolNodesByFile.get(normalized) ?? []) {
|
|
@@ -15015,14 +15256,14 @@ async function symbolSearch(query, cwd, limit = 20, options = {}) {
|
|
|
15015
15256
|
let centrality;
|
|
15016
15257
|
let results;
|
|
15017
15258
|
try {
|
|
15018
|
-
centrality = centralityFromReverseDeps(index, snapshot?.reverseDeps, (file) => normalizeMapKey(
|
|
15259
|
+
centrality = centralityFromReverseDeps(index, snapshot?.reverseDeps, (file) => normalizeMapKey(path29.resolve(file)));
|
|
15019
15260
|
const fileFilter = buildSymbolSearchFileFilter(cwd, options);
|
|
15020
15261
|
results = searchWordIndex(index, query, { limit, centrality, fileFilter });
|
|
15021
15262
|
} finally {
|
|
15022
15263
|
warmLease.release();
|
|
15023
15264
|
}
|
|
15024
15265
|
const hits = results.map(toSymbolSearchHit);
|
|
15025
|
-
const { getCachedReviewGraph } = await import("../chunk-
|
|
15266
|
+
const { getCachedReviewGraph } = await import("../chunk-2ZGIZPDG.js");
|
|
15026
15267
|
const graph = getCachedReviewGraph(cwd);
|
|
15027
15268
|
if (graph)
|
|
15028
15269
|
annotateSymbolSearchHitsWithGraph(hits, centrality, graph);
|
|
@@ -15039,10 +15280,10 @@ async function symbolSearch(query, cwd, limit = 20, options = {}) {
|
|
|
15039
15280
|
import { Type } from "typebox";
|
|
15040
15281
|
|
|
15041
15282
|
// dist/clients/ast-grep-tool-logger.js
|
|
15042
|
-
import * as
|
|
15283
|
+
import * as path30 from "node:path";
|
|
15043
15284
|
var AG_LOG_DIR = getGlobalPiLensLogDir();
|
|
15044
|
-
var AG_LOG_FILE =
|
|
15045
|
-
var AG_LOG_BACKUP_FILE =
|
|
15285
|
+
var AG_LOG_FILE = path30.join(AG_LOG_DIR, "ast-grep-tools.log");
|
|
15286
|
+
var AG_LOG_BACKUP_FILE = path30.join(AG_LOG_DIR, "ast-grep-tools.log.1");
|
|
15046
15287
|
var MAX_LOG_BYTES3 = Math.max(128 * 1024, Number.parseInt(process.env.PI_LENS_AST_GREP_LOG_MAX_BYTES ?? "1048576", 10) || 1048576);
|
|
15047
15288
|
var writer3 = createNdjsonLogger({
|
|
15048
15289
|
filePath: AG_LOG_FILE,
|
|
@@ -15219,6 +15460,11 @@ function canonicalLanguage(lang) {
|
|
|
15219
15460
|
}
|
|
15220
15461
|
|
|
15221
15462
|
// dist/tools/shared.js
|
|
15463
|
+
function resolveAstGrepPaths(paths, cwd) {
|
|
15464
|
+
const base = cwd || ".";
|
|
15465
|
+
const requested = paths?.length ? paths : [base];
|
|
15466
|
+
return requested.map((p) => resolveHostToolPath(p, base));
|
|
15467
|
+
}
|
|
15222
15468
|
var LANGUAGES = [
|
|
15223
15469
|
"bash",
|
|
15224
15470
|
"c",
|
|
@@ -15355,7 +15601,7 @@ function createAstGrepReplaceTool(astGrepClient2, captureLineage) {
|
|
|
15355
15601
|
details: {}
|
|
15356
15602
|
};
|
|
15357
15603
|
}
|
|
15358
|
-
const searchPaths = paths
|
|
15604
|
+
const searchPaths = resolveAstGrepPaths(paths, ctx.cwd);
|
|
15359
15605
|
if (hasStructuralIntent({
|
|
15360
15606
|
insideKind,
|
|
15361
15607
|
hasKind,
|
|
@@ -15388,7 +15634,7 @@ function createAstGrepReplaceTool(astGrepClient2, captureLineage) {
|
|
|
15388
15634
|
details: {}
|
|
15389
15635
|
};
|
|
15390
15636
|
}
|
|
15391
|
-
const ruleResult = await astGrepClient2.replaceWithRule(ruleYaml, searchPaths, applyFlag);
|
|
15637
|
+
const ruleResult = await astGrepClient2.replaceWithRule(ruleYaml, searchPaths, applyFlag, { lineage, toolCallId: _toolCallId });
|
|
15392
15638
|
if (ruleResult.stalePreview) {
|
|
15393
15639
|
logOutcome("error", { errorRaw: "stale_preview" });
|
|
15394
15640
|
return {
|
|
@@ -15427,7 +15673,7 @@ function createAstGrepReplaceTool(astGrepClient2, captureLineage) {
|
|
|
15427
15673
|
}
|
|
15428
15674
|
};
|
|
15429
15675
|
}
|
|
15430
|
-
const result = await astGrepClient2.replace(pattern, rewrite, lang, searchPaths, applyFlag, { strictness, lineage });
|
|
15676
|
+
const result = await astGrepClient2.replace(pattern, rewrite, lang, searchPaths, applyFlag, { strictness, lineage, toolCallId: _toolCallId });
|
|
15431
15677
|
if (result.stalePreview) {
|
|
15432
15678
|
logOutcome("error", { errorRaw: "stale_preview" });
|
|
15433
15679
|
return {
|
|
@@ -15975,7 +16221,7 @@ function createAstGrepSearchTool(astGrepClient2) {
|
|
|
15975
16221
|
details: {}
|
|
15976
16222
|
};
|
|
15977
16223
|
}
|
|
15978
|
-
const searchPaths = paths
|
|
16224
|
+
const searchPaths = resolveAstGrepPaths(paths, ctx.cwd);
|
|
15979
16225
|
const PAGE_SIZE = Math.max(1, Math.min(MAX_PAGE_SIZE, Number.isFinite(maxMatches) ? Math.floor(maxMatches) : DEFAULT_PAGE_SIZE));
|
|
15980
16226
|
let effectiveRule = hasRawRule ? rawRule : void 0;
|
|
15981
16227
|
if (!effectiveRule && (hasNodeKind || hasStructuralIntent({
|
|
@@ -16167,7 +16413,7 @@ ${hint}` : `${output}${paginationNote}`;
|
|
|
16167
16413
|
// dist/tools/lens-diagnostics.js
|
|
16168
16414
|
import { promises as fs23 } from "node:fs";
|
|
16169
16415
|
import * as fsSync from "node:fs";
|
|
16170
|
-
import * as
|
|
16416
|
+
import * as path37 from "node:path";
|
|
16171
16417
|
|
|
16172
16418
|
// dist/clients/project-diagnostics/extractors.js
|
|
16173
16419
|
var WARM_TRIGGER = {
|
|
@@ -16227,12 +16473,12 @@ function reasonFromAvailabilityVerdict(tool, verdict) {
|
|
|
16227
16473
|
// dist/clients/project-diagnostics/fresh-fetch.js
|
|
16228
16474
|
import * as fs21 from "node:fs";
|
|
16229
16475
|
import * as os4 from "node:os";
|
|
16230
|
-
import * as
|
|
16476
|
+
import * as path35 from "node:path";
|
|
16231
16477
|
|
|
16232
16478
|
// dist/clients/project-diagnostics/runner-adapters/jscpd.js
|
|
16233
|
-
import * as
|
|
16479
|
+
import * as path31 from "node:path";
|
|
16234
16480
|
function resolveClonePath(cwd, file) {
|
|
16235
|
-
return
|
|
16481
|
+
return path31.isAbsolute(file) ? file : path31.resolve(cwd, file);
|
|
16236
16482
|
}
|
|
16237
16483
|
function jscpdCloneToProjectDiagnostics(cwd, clone) {
|
|
16238
16484
|
const a = resolveClonePath(cwd, clone.fileA);
|
|
@@ -16245,7 +16491,7 @@ function jscpdCloneToProjectDiagnostics(cwd, clone) {
|
|
|
16245
16491
|
tool: "jscpd",
|
|
16246
16492
|
runner: "jscpd",
|
|
16247
16493
|
rule: "jscpd:duplicate",
|
|
16248
|
-
message: `Duplicate code (${clone.lines} lines) \u2014 also at ${
|
|
16494
|
+
message: `Duplicate code (${clone.lines} lines) \u2014 also at ${path31.relative(cwd, otherFile)}:${otherLine}`,
|
|
16249
16495
|
source: "project-scan"
|
|
16250
16496
|
});
|
|
16251
16497
|
return [
|
|
@@ -16260,16 +16506,16 @@ function jscpdResultToProjectDiagnostics(cwd, result) {
|
|
|
16260
16506
|
}
|
|
16261
16507
|
|
|
16262
16508
|
// dist/clients/project-diagnostics/runner-adapters/madge.js
|
|
16263
|
-
import * as
|
|
16509
|
+
import * as path32 from "node:path";
|
|
16264
16510
|
function resolveCyclePath(cwd, file) {
|
|
16265
|
-
return
|
|
16511
|
+
return path32.isAbsolute(file) ? file : path32.resolve(cwd, file);
|
|
16266
16512
|
}
|
|
16267
16513
|
function cycleMembers(dep) {
|
|
16268
16514
|
return dep.path.length > 0 ? dep.path : [dep.file];
|
|
16269
16515
|
}
|
|
16270
16516
|
function circularDepToProjectDiagnostics(cwd, dep) {
|
|
16271
16517
|
const members = cycleMembers(dep);
|
|
16272
|
-
const rendered = `${members.map((f) =>
|
|
16518
|
+
const rendered = `${members.map((f) => path32.basename(f)).join(" \u2192 ")} \u2192 ${path32.basename(members[0] ?? "")}`;
|
|
16273
16519
|
return members.map((file) => ({
|
|
16274
16520
|
filePath: resolveCyclePath(cwd, file),
|
|
16275
16521
|
severity: "warning",
|
|
@@ -16295,7 +16541,7 @@ function circularDepsToProjectDiagnostics(cwd, circular) {
|
|
|
16295
16541
|
}
|
|
16296
16542
|
|
|
16297
16543
|
// dist/clients/project-diagnostics/runner-adapters/opengrep.js
|
|
16298
|
-
import * as
|
|
16544
|
+
import * as path33 from "node:path";
|
|
16299
16545
|
function severityFor(raw) {
|
|
16300
16546
|
switch (raw.toUpperCase()) {
|
|
16301
16547
|
case "ERROR":
|
|
@@ -16310,7 +16556,7 @@ function opengrepFindingToProjectDiagnostic(cwd, finding) {
|
|
|
16310
16556
|
const { severity, blocking } = severityFor(finding.severity);
|
|
16311
16557
|
const cweSuffix = finding.cwe?.length ? ` (${finding.cwe[0]})` : "";
|
|
16312
16558
|
return {
|
|
16313
|
-
filePath:
|
|
16559
|
+
filePath: path33.isAbsolute(finding.path) ? finding.path : path33.resolve(cwd, finding.path),
|
|
16314
16560
|
line: finding.startLine,
|
|
16315
16561
|
column: finding.startCol,
|
|
16316
16562
|
severity,
|
|
@@ -16330,7 +16576,7 @@ function opengrepResultToProjectDiagnostics(cwd, result) {
|
|
|
16330
16576
|
|
|
16331
16577
|
// dist/clients/project-diagnostics/runner-adapters/runner-findings.js
|
|
16332
16578
|
import * as fs20 from "node:fs";
|
|
16333
|
-
import * as
|
|
16579
|
+
import * as path34 from "node:path";
|
|
16334
16580
|
function failureMessage(failure) {
|
|
16335
16581
|
const firstLine2 = failure.message.split("\n")[0]?.slice(0, 300) ?? "";
|
|
16336
16582
|
return firstLine2 ? `${failure.name}: ${firstLine2}` : failure.name;
|
|
@@ -16396,7 +16642,7 @@ function testRunnerFindingsToProjectDiagnostics(cache, cwd, runtime) {
|
|
|
16396
16642
|
return [];
|
|
16397
16643
|
const validation = cwd ? validateAdvisoryProvenance(cache, cwd, runtime) : { status: "unknown", reasons: ["validation-context-missing"] };
|
|
16398
16644
|
const root = cwd ?? process.cwd();
|
|
16399
|
-
const missingKeys = new Set((cache.provenance?.files ?? []).filter((file) => !fs20.existsSync(
|
|
16645
|
+
const missingKeys = new Set((cache.provenance?.files ?? []).filter((file) => !fs20.existsSync(path34.resolve(root, file.path))).map((file) => advisoryPathKey(file.path, root)));
|
|
16400
16646
|
const historical = cache.superseded === true || cache.stale === true || validation.status !== "current";
|
|
16401
16647
|
return cache.results.filter((result) => !missingKeys.has(advisoryPathKey(result.file, root))).flatMap((result) => testResultToProjectDiagnostics(result, historical)).map((diagnostic) => historical ? {
|
|
16402
16648
|
...diagnostic,
|
|
@@ -16426,7 +16672,7 @@ function laneObservedAtMs(scannedAt, startedAtMs) {
|
|
|
16426
16672
|
return parseScannedAtMs(scannedAt) ?? startedAtMs;
|
|
16427
16673
|
}
|
|
16428
16674
|
async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal, options = {}) {
|
|
16429
|
-
const requestedRoot = options.analysisRoot === void 0 ? cwd :
|
|
16675
|
+
const requestedRoot = options.analysisRoot === void 0 ? cwd : path35.resolve(cwd, options.analysisRoot);
|
|
16430
16676
|
let analysisRoot;
|
|
16431
16677
|
let analysisRootValidation;
|
|
16432
16678
|
if (options.analysisRoot !== void 0) {
|
|
@@ -16593,7 +16839,7 @@ async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal,
|
|
|
16593
16839
|
markCold("jscpd", reasonFromAvailabilityVerdict("jscpd", clients.jscpdClient.getAvailabilityVerdict?.()));
|
|
16594
16840
|
return;
|
|
16595
16841
|
}
|
|
16596
|
-
const isTsProject = fs21.existsSync(
|
|
16842
|
+
const isTsProject = fs21.existsSync(path35.join(analysisRoot, "tsconfig.json"));
|
|
16597
16843
|
const scannerKey = isTsProject ? "jscpd-ts" : "jscpd";
|
|
16598
16844
|
const startMs = Date.now();
|
|
16599
16845
|
const result = await clients.jscpdClient.scan(analysisRoot, void 0, void 0, isTsProject);
|
|
@@ -16824,12 +17070,12 @@ async function fetchFreshProjectDiagnostics(cacheManager2, cwd, clients, signal,
|
|
|
16824
17070
|
const allSettled = Promise.all(tasks).then(() => "completed").catch(() => "completed");
|
|
16825
17071
|
const outcome = signal ? await Promise.race([
|
|
16826
17072
|
allSettled,
|
|
16827
|
-
new Promise((
|
|
17073
|
+
new Promise((resolve32) => {
|
|
16828
17074
|
if (signal.aborted) {
|
|
16829
|
-
|
|
17075
|
+
resolve32("aborted");
|
|
16830
17076
|
return;
|
|
16831
17077
|
}
|
|
16832
|
-
signal.addEventListener("abort", () =>
|
|
17078
|
+
signal.addEventListener("abort", () => resolve32("aborted"), {
|
|
16833
17079
|
once: true
|
|
16834
17080
|
});
|
|
16835
17081
|
})
|
|
@@ -16910,7 +17156,7 @@ function makeProgressReporter(onUpdate, label, throttleMs = 250) {
|
|
|
16910
17156
|
|
|
16911
17157
|
// dist/tools/lsp-diagnostics.js
|
|
16912
17158
|
import * as fs22 from "node:fs";
|
|
16913
|
-
import * as
|
|
17159
|
+
import * as path36 from "node:path";
|
|
16914
17160
|
var MAX_FILES = 100;
|
|
16915
17161
|
var MAX_BATCH_FILES = 100;
|
|
16916
17162
|
var MAX_DIAGNOSTICS = 200;
|
|
@@ -16993,11 +17239,11 @@ async function collectFiles(dir, extensions, maxFiles, isIgnored = () => false)
|
|
|
16993
17239
|
return;
|
|
16994
17240
|
if (entry.isSymbolicLink())
|
|
16995
17241
|
continue;
|
|
16996
|
-
const full =
|
|
17242
|
+
const full = path36.join(current, entry.name);
|
|
16997
17243
|
if (entry.isDirectory()) {
|
|
16998
17244
|
if (!isExcludedDirName(entry.name) && !isIgnored(full, true))
|
|
16999
17245
|
await walk(full);
|
|
17000
|
-
} else if (entry.isFile() && extensions.includes(
|
|
17246
|
+
} else if (entry.isFile() && extensions.includes(path36.extname(full))) {
|
|
17001
17247
|
if (isIgnored(full, false))
|
|
17002
17248
|
continue;
|
|
17003
17249
|
files.push(full);
|
|
@@ -17091,7 +17337,7 @@ function createLspDiagnosticsTool(nextWriteIndex, onConfirmedNoBlockers, getServ
|
|
|
17091
17337
|
details: {}
|
|
17092
17338
|
};
|
|
17093
17339
|
}
|
|
17094
|
-
const absPath = normalizeMapKey(
|
|
17340
|
+
const absPath = normalizeMapKey(path36.resolve(cwd, rawPath));
|
|
17095
17341
|
let stat;
|
|
17096
17342
|
try {
|
|
17097
17343
|
stat = fs22.statSync(absPath);
|
|
@@ -17272,7 +17518,7 @@ function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds) {
|
|
|
17272
17518
|
return [];
|
|
17273
17519
|
}
|
|
17274
17520
|
for (const server of servers) {
|
|
17275
|
-
const auxiliary = server
|
|
17521
|
+
const auxiliary = isAuxiliary(server);
|
|
17276
17522
|
if (auxiliary && serverScope === "primary")
|
|
17277
17523
|
continue;
|
|
17278
17524
|
if (unconfirmed.has(server.id))
|
|
@@ -17748,12 +17994,12 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
17748
17994
|
});
|
|
17749
17995
|
const result = options.signal ? await Promise.race([
|
|
17750
17996
|
bounded2,
|
|
17751
|
-
new Promise((
|
|
17997
|
+
new Promise((resolve32) => {
|
|
17752
17998
|
if (options.signal?.aborted) {
|
|
17753
|
-
|
|
17999
|
+
resolve32(void 0);
|
|
17754
18000
|
return;
|
|
17755
18001
|
}
|
|
17756
|
-
options.signal?.addEventListener("abort", () =>
|
|
18002
|
+
options.signal?.addEventListener("abort", () => resolve32(void 0), {
|
|
17757
18003
|
once: true
|
|
17758
18004
|
});
|
|
17759
18005
|
})
|
|
@@ -17812,7 +18058,7 @@ async function expandPathsToFiles(cwd, rawPaths) {
|
|
|
17812
18058
|
const directories = [];
|
|
17813
18059
|
const seenFileKeys = /* @__PURE__ */ new Set();
|
|
17814
18060
|
for (const entry of rawPaths) {
|
|
17815
|
-
const abs = normalizeMapKey(
|
|
18061
|
+
const abs = normalizeMapKey(path36.resolve(cwd, entry));
|
|
17816
18062
|
let stat;
|
|
17817
18063
|
try {
|
|
17818
18064
|
stat = fs22.statSync(abs);
|
|
@@ -18016,7 +18262,7 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18016
18262
|
outcome: result.outcome,
|
|
18017
18263
|
reason: result.tooLargeReason ?? result.inconclusiveReason ?? result.error ?? result.unavailable
|
|
18018
18264
|
}));
|
|
18019
|
-
const tooLargeLines = renderBatchOutcomeLines(outcomeDetails, (file) =>
|
|
18265
|
+
const tooLargeLines = renderBatchOutcomeLines(outcomeDetails, (file) => path36.relative(absPath, file));
|
|
18020
18266
|
let text;
|
|
18021
18267
|
if (total === 0) {
|
|
18022
18268
|
const cleanLine = unconfirmed > 0 ? `${clean} clean \xB7 ${unconfirmed} unconfirmed: ${unconfirmedReasonClause(unconfirmed, timedOut, rootFallbackReasons)} NOT the same as 0 diagnostics.` : "No diagnostics found.";
|
|
@@ -18048,7 +18294,7 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18048
18294
|
];
|
|
18049
18295
|
const toRelative = (d) => ({
|
|
18050
18296
|
...d,
|
|
18051
|
-
file:
|
|
18297
|
+
file: path36.relative(absPath, d.file)
|
|
18052
18298
|
});
|
|
18053
18299
|
if (primaryDisplay.length > 0) {
|
|
18054
18300
|
lines.push(`Primary findings (${primaryDisplay.length}):`);
|
|
@@ -18079,7 +18325,7 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
18079
18325
|
filesScanned: filesToProcess.length,
|
|
18080
18326
|
capped: wasCapped,
|
|
18081
18327
|
diagnostics: display.map((d) => ({
|
|
18082
|
-
file:
|
|
18328
|
+
file: path36.relative(absPath, d.file),
|
|
18083
18329
|
line: d.line,
|
|
18084
18330
|
character: d.character,
|
|
18085
18331
|
severity: d.severity,
|
|
@@ -18170,7 +18416,7 @@ async function findFullScanBindingMismatches(results) {
|
|
|
18170
18416
|
sinceYield += 1;
|
|
18171
18417
|
if (sinceYield >= FULL_SCAN_BINDING_YIELD_EVERY) {
|
|
18172
18418
|
sinceYield = 0;
|
|
18173
|
-
await new Promise((
|
|
18419
|
+
await new Promise((resolve32) => setImmediate(resolve32));
|
|
18174
18420
|
}
|
|
18175
18421
|
}
|
|
18176
18422
|
return mismatched;
|
|
@@ -18209,7 +18455,7 @@ function createLensDiagnosticsTool(cacheManager2, getCwd, getLspService = getLSP
|
|
|
18209
18455
|
const files2 = details.filesChecked ?? details.filesScanned ?? 0;
|
|
18210
18456
|
const noun = count === 1 ? "diagnostic" : "diagnostics";
|
|
18211
18457
|
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;
|
|
18212
|
-
const singleFile = (details?.mode === "file" || files2 === 1) && typeof filePath === "string" ? ` ${
|
|
18458
|
+
const singleFile = (details?.mode === "file" || files2 === 1) && typeof filePath === "string" ? ` ${path37.basename(filePath)}` : "";
|
|
18213
18459
|
const scope = files2 > 1 ? ` across ${files2} files` : singleFile;
|
|
18214
18460
|
if (isError)
|
|
18215
18461
|
return `lens_diagnostics lsp \u2014 ${text.split("\n")[0] ?? "error"}`;
|
|
@@ -18455,7 +18701,7 @@ function appendProjectDiagnosticsDeltaLines(groups, cwd, report, severity, inclu
|
|
|
18455
18701
|
const diagnostics = [...gated.live, ...gated.stale];
|
|
18456
18702
|
const byFile = /* @__PURE__ */ new Map();
|
|
18457
18703
|
for (const diagnostic of diagnostics) {
|
|
18458
|
-
const filePath =
|
|
18704
|
+
const filePath = path37.resolve(diagnostic.filePath);
|
|
18459
18705
|
const bucket = byFile.get(filePath) ?? [];
|
|
18460
18706
|
bucket.push(diagnostic);
|
|
18461
18707
|
byFile.set(filePath, bucket);
|
|
@@ -18515,7 +18761,10 @@ function filterDeltaReportDispositions(report, cwd, policyMap) {
|
|
|
18515
18761
|
if (!report?.diagnostics.length)
|
|
18516
18762
|
return report;
|
|
18517
18763
|
const kept = report.diagnostics.filter((d) => applyCachedDispositions([projectDiagnosticToWidget(d, d.filePath)], cwd, d.filePath).length === 1);
|
|
18518
|
-
const policyKept = applyRulePolicy(kept, policyMap
|
|
18764
|
+
const policyKept = applyRulePolicy(kept, policyMap, {
|
|
18765
|
+
root: cwd,
|
|
18766
|
+
filePath: cwd
|
|
18767
|
+
});
|
|
18519
18768
|
if (policyKept.length === report.diagnostics.length)
|
|
18520
18769
|
return report;
|
|
18521
18770
|
return { ...report, diagnostics: policyKept };
|
|
@@ -18579,7 +18828,7 @@ function applyDeltaFreshnessGate(files, cwd, generatedAt) {
|
|
|
18579
18828
|
})).filter((file) => file.warnings.length > 0);
|
|
18580
18829
|
}
|
|
18581
18830
|
function getDeltaFileGroup(groups, cwd, filePath) {
|
|
18582
|
-
const rel =
|
|
18831
|
+
const rel = path37.relative(cwd, filePath);
|
|
18583
18832
|
let group = groups.get(rel);
|
|
18584
18833
|
if (!group) {
|
|
18585
18834
|
group = {
|
|
@@ -18607,7 +18856,7 @@ function formatDeltaMode(cacheManager2, cwd, severity, pathsScope) {
|
|
|
18607
18856
|
// #2504 r4 (F1): carried through, so a merged report's older
|
|
18608
18857
|
// entries keep their own age all the way to the freshness gate.
|
|
18609
18858
|
generatedAt: file.generatedAt,
|
|
18610
|
-
warnings: applyRulePolicy(applyCachedDispositions(file.warnings ?? [], cwd, file.filePath), policyMap)
|
|
18859
|
+
warnings: applyRulePolicy(applyCachedDispositions(file.warnings ?? [], cwd, file.filePath), policyMap, { root: cwd, filePath: file.filePath })
|
|
18611
18860
|
})).filter((file) => file.warnings.length > 0);
|
|
18612
18861
|
const actionableFiles = applyDeltaFreshnessGate(visibleWarningFiles(actionable?.files), cwd, actionable?.generatedAt);
|
|
18613
18862
|
const qualityFiles = applyDeltaFreshnessGate(visibleWarningFiles(quality?.files), cwd, quality?.generatedAt);
|
|
@@ -18676,7 +18925,7 @@ function formatDeltaMode(cacheManager2, cwd, severity, pathsScope) {
|
|
|
18676
18925
|
let text = `No ${severity === "all" ? "" : severity + " "}issues in the current turn delta.`;
|
|
18677
18926
|
const carried = getFileDiagnosticSummaries().filter((f) => includeFile(f.filePath)).map((f) => ({
|
|
18678
18927
|
...f,
|
|
18679
|
-
diagnostics: applyRulePolicy(applyCachedDispositions(f.diagnostics, cwd, f.filePath), policyMap)
|
|
18928
|
+
diagnostics: applyRulePolicy(applyCachedDispositions(f.diagnostics, cwd, f.filePath), policyMap, { root: cwd, filePath: f.filePath })
|
|
18680
18929
|
})).filter((f) => f.diagnostics.length > 0);
|
|
18681
18930
|
const carriedIssues = carried.reduce((n, f) => n + f.diagnostics.length, 0);
|
|
18682
18931
|
if (carried.length > 0) {
|
|
@@ -18703,7 +18952,7 @@ Summary (turn delta): ${aw} actionable warning${aw === 1 ? "" : "s"} \xB7 ${cq}
|
|
|
18703
18952
|
function createCurrentIgnoreFilter(cwd) {
|
|
18704
18953
|
try {
|
|
18705
18954
|
const matcher = getProjectIgnoreMatcher(cwd);
|
|
18706
|
-
return (filePath) => !matcher.isIgnored(
|
|
18955
|
+
return (filePath) => !matcher.isIgnored(path37.resolve(filePath), false);
|
|
18707
18956
|
} catch {
|
|
18708
18957
|
return () => true;
|
|
18709
18958
|
}
|
|
@@ -18714,7 +18963,7 @@ function resolvePathsScope(cwd, rawPaths) {
|
|
|
18714
18963
|
if (rawPaths.length > MAX_PATHS_ENTRIES) {
|
|
18715
18964
|
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.`);
|
|
18716
18965
|
}
|
|
18717
|
-
const entries = rawPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) =>
|
|
18966
|
+
const entries = rawPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) => path37.resolve(path37.isAbsolute(entry) ? entry : path37.resolve(cwd, entry)));
|
|
18718
18967
|
const missing = [];
|
|
18719
18968
|
const fileEntries = [];
|
|
18720
18969
|
const existingEntries = [];
|
|
@@ -18737,9 +18986,9 @@ function resolvePathsScope(cwd, rawPaths) {
|
|
|
18737
18986
|
}
|
|
18738
18987
|
const fileKeys = new Set(fileEntries.map((f) => normalizeFilePath(f)));
|
|
18739
18988
|
const dirPrefixes = dirEntries.map((d) => normalizeFilePath(d));
|
|
18740
|
-
const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(
|
|
18989
|
+
const includeExplicitFile = (filePath) => fileKeys.has(normalizeFilePath(path37.resolve(filePath)));
|
|
18741
18990
|
const includeFile = (filePath) => {
|
|
18742
|
-
const key = normalizeFilePath(
|
|
18991
|
+
const key = normalizeFilePath(path37.resolve(filePath));
|
|
18743
18992
|
if (fileKeys.has(key))
|
|
18744
18993
|
return true;
|
|
18745
18994
|
return dirPrefixes.some((prefix) => key === prefix || key.startsWith(`${prefix}/`));
|
|
@@ -18760,7 +19009,7 @@ function pathsScopeCacheOnlyNote(scope) {
|
|
|
18760
19009
|
function pathsScopeMissingNote(scope) {
|
|
18761
19010
|
if (!scope || scope.missing.length === 0)
|
|
18762
19011
|
return "";
|
|
18763
|
-
const shown2 = scope.missing.slice(0, 10).map((p) =>
|
|
19012
|
+
const shown2 = scope.missing.slice(0, 10).map((p) => path37.basename(p));
|
|
18764
19013
|
const more = scope.missing.length > shown2.length ? ` (+${scope.missing.length - shown2.length} more)` : "";
|
|
18765
19014
|
return `
|
|
18766
19015
|
|
|
@@ -18792,12 +19041,15 @@ function filterProjectDiagnosticsDeltaReport(report, includeFile) {
|
|
|
18792
19041
|
diagnostics: report.diagnostics.filter((d) => includeFile(d.filePath))
|
|
18793
19042
|
};
|
|
18794
19043
|
}
|
|
18795
|
-
function applyProjectRulePolicy(value, policyMap) {
|
|
19044
|
+
function applyProjectRulePolicy(value, policyMap, root) {
|
|
18796
19045
|
if (!value)
|
|
18797
19046
|
return void 0;
|
|
18798
19047
|
return {
|
|
18799
19048
|
...value,
|
|
18800
|
-
diagnostics: applyRulePolicy(value.diagnostics, policyMap
|
|
19049
|
+
diagnostics: applyRulePolicy(value.diagnostics, policyMap, {
|
|
19050
|
+
root,
|
|
19051
|
+
filePath: value.diagnostics[0]?.filePath ?? root
|
|
19052
|
+
})
|
|
18801
19053
|
};
|
|
18802
19054
|
}
|
|
18803
19055
|
function isErrorLike(d) {
|
|
@@ -18888,7 +19140,7 @@ function projectDiagnosticToWidget(diagnostic, filePath) {
|
|
|
18888
19140
|
}
|
|
18889
19141
|
function diagnosticDedupKey(filePath, diagnostic) {
|
|
18890
19142
|
const ruleId = normalizeRuleId(diagnostic.rule ?? diagnostic.tool ?? "");
|
|
18891
|
-
return [
|
|
19143
|
+
return [path37.resolve(filePath), diagnostic.line ?? "?", ruleId].join(":");
|
|
18892
19144
|
}
|
|
18893
19145
|
function runnerIdOf(diagnostic) {
|
|
18894
19146
|
return diagnostic.tool ?? diagnostic.rule?.split(":", 1)[0] ?? "";
|
|
@@ -18902,8 +19154,8 @@ function runnerRetirementDecision(diagnostic, filePath, authoritativeRunnerIds,
|
|
|
18902
19154
|
const realFilePath = realpathOrResolve(filePath);
|
|
18903
19155
|
for (const entry of coverage) {
|
|
18904
19156
|
const root = entry.root;
|
|
18905
|
-
const relative9 =
|
|
18906
|
-
const underRoot = relative9 === "" || !relative9.startsWith("..") && !
|
|
19157
|
+
const relative9 = path37.relative(root, realFilePath);
|
|
19158
|
+
const underRoot = relative9 === "" || !relative9.startsWith("..") && !path37.isAbsolute(relative9);
|
|
18907
19159
|
if (!underRoot)
|
|
18908
19160
|
continue;
|
|
18909
19161
|
if (entry.files.has(realFilePath)) {
|
|
@@ -19027,7 +19279,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19027
19279
|
const byFile = /* @__PURE__ */ new Map();
|
|
19028
19280
|
const seen = /* @__PURE__ */ new Set();
|
|
19029
19281
|
for (const summary of widgetSummaries) {
|
|
19030
|
-
const filePath =
|
|
19282
|
+
const filePath = path37.resolve(summary.filePath);
|
|
19031
19283
|
if (authoritativeLspFiles?.has(filePath))
|
|
19032
19284
|
continue;
|
|
19033
19285
|
const retained = summary.diagnostics ?? [];
|
|
@@ -19055,7 +19307,7 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19055
19307
|
byFile.set(filePath, summarizeDiagnostics(filePath, diagnostics, existing?.hasFinalSnapshot ?? true));
|
|
19056
19308
|
};
|
|
19057
19309
|
for (const result of lspResults) {
|
|
19058
|
-
const filePath =
|
|
19310
|
+
const filePath = path37.resolve(result.filePath);
|
|
19059
19311
|
for (const diagnostic of result.diagnostics ?? []) {
|
|
19060
19312
|
addDiagnostic(filePath, {
|
|
19061
19313
|
...lspDiagnosticToWidget(diagnostic),
|
|
@@ -19075,12 +19327,12 @@ function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projec
|
|
|
19075
19327
|
});
|
|
19076
19328
|
}
|
|
19077
19329
|
for (const diagnostic of projectSnapshot?.diagnostics ?? []) {
|
|
19078
|
-
addDiagnostic(
|
|
19330
|
+
addDiagnostic(path37.resolve(diagnostic.filePath), projectDiagnosticToWidget(diagnostic, diagnostic.filePath));
|
|
19079
19331
|
}
|
|
19080
19332
|
for (const diagnostic of deltaDiagnostics) {
|
|
19081
19333
|
const widget = projectDiagnosticToWidget(diagnostic, diagnostic.filePath);
|
|
19082
19334
|
const observedAt = widget.observedAt ?? deltaObservedAt;
|
|
19083
|
-
addDiagnostic(
|
|
19335
|
+
addDiagnostic(path37.resolve(diagnostic.filePath), {
|
|
19084
19336
|
...widget,
|
|
19085
19337
|
...observedAt !== void 0 && { observedAt }
|
|
19086
19338
|
});
|
|
@@ -19095,7 +19347,10 @@ async function applyInlineSuppressionsToSummaries(summaries, cwd, policyMap) {
|
|
|
19095
19347
|
try {
|
|
19096
19348
|
content = await fs23.readFile(summary.filePath, "utf8");
|
|
19097
19349
|
} catch {
|
|
19098
|
-
const policyKept2 = applyRulePolicy(summary.diagnostics, policyMap
|
|
19350
|
+
const policyKept2 = applyRulePolicy(summary.diagnostics, policyMap, {
|
|
19351
|
+
root: cwd,
|
|
19352
|
+
filePath: summary.filePath
|
|
19353
|
+
});
|
|
19099
19354
|
return policyKept2.length === summary.diagnostics.length ? summary : summarizeDiagnostics(summary.filePath, policyKept2, summary.hasFinalSnapshot);
|
|
19100
19355
|
}
|
|
19101
19356
|
const { kept: policyKept } = applyFindingPolicy(summary.diagnostics, {
|
|
@@ -19280,20 +19535,20 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19280
19535
|
result2.observedAt
|
|
19281
19536
|
);
|
|
19282
19537
|
if (retired === true) {
|
|
19283
|
-
authoritativeLspFiles.add(
|
|
19538
|
+
authoritativeLspFiles.add(path37.resolve(result2.filePath));
|
|
19284
19539
|
} else {
|
|
19285
|
-
unreconciledFiles.add(
|
|
19540
|
+
unreconciledFiles.add(path37.resolve(result2.filePath));
|
|
19286
19541
|
recordDegradationOnce({
|
|
19287
19542
|
kind: "diagnostic-retained-unreconciled",
|
|
19288
|
-
subject: `${
|
|
19543
|
+
subject: `${path37.resolve(result2.filePath)}:lsp`,
|
|
19289
19544
|
reason: "confirmed diagnostic result could not replace retained widget state"
|
|
19290
19545
|
});
|
|
19291
19546
|
}
|
|
19292
19547
|
} catch {
|
|
19293
|
-
unreconciledFiles.add(
|
|
19548
|
+
unreconciledFiles.add(path37.resolve(result2.filePath));
|
|
19294
19549
|
recordDegradationOnce({
|
|
19295
19550
|
kind: "diagnostic-retained-unreconciled",
|
|
19296
|
-
subject: `${
|
|
19551
|
+
subject: `${path37.resolve(result2.filePath)}:lsp`,
|
|
19297
19552
|
reason: "confirmed diagnostic result failed during widget reconciliation"
|
|
19298
19553
|
});
|
|
19299
19554
|
}
|
|
@@ -19303,9 +19558,9 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19303
19558
|
const authoritativeRunnerIds = new Set(extracted.analyzed ?? []);
|
|
19304
19559
|
const authoritativeRunnerCoverage = extracted.authoritativeCoverage ?? [];
|
|
19305
19560
|
const foldedProjectSnapshot = foldExtraDiagnosticsIntoSnapshot(scannedSnapshot, extracted.diagnostics.filter((d) => includeFile(d.filePath)), extracted.runners, cwd);
|
|
19306
|
-
const projectSnapshot = applyProjectRulePolicy(foldedProjectSnapshot, policyMap);
|
|
19307
|
-
const projectDelta = applyProjectRulePolicy(filterProjectDiagnosticsDeltaReport(loadProjectDiagnosticsDeltaReport(cwd), includeFile), policyMap);
|
|
19308
|
-
const authoritativeRetiredCount = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath) && authoritativeLspFiles.has(
|
|
19561
|
+
const projectSnapshot = applyProjectRulePolicy(foldedProjectSnapshot, policyMap, cwd);
|
|
19562
|
+
const projectDelta = applyProjectRulePolicy(filterProjectDiagnosticsDeltaReport(loadProjectDiagnosticsDeltaReport(cwd), includeFile), policyMap, cwd);
|
|
19563
|
+
const authoritativeRetiredCount = getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath) && authoritativeLspFiles.has(path37.resolve(summary.filePath)) && (summary.diagnostics?.length ?? 0) > 0).length;
|
|
19309
19564
|
if (authoritativeRetiredCount > 0) {
|
|
19310
19565
|
logLatency({
|
|
19311
19566
|
type: "phase",
|
|
@@ -19360,7 +19615,7 @@ async function formatFullMode(cwd, severity, lspService, cacheManager2, options
|
|
|
19360
19615
|
}
|
|
19361
19616
|
let summaries = await applyInlineSuppressionsToSummaries(mergeDiagnosticsWithWidgetSummaries(getFileDiagnosticSummaries().filter((summary) => includeFile(summary.filePath)), confirmedLspResults, projectSnapshot, projectDelta, authoritativeLspFiles, authoritativeRunnerIds, authoritativeRunnerCoverage), cwd, policyMap);
|
|
19362
19617
|
if (unreconciledFiles.size > 0) {
|
|
19363
|
-
summaries = summaries.map((summary) => unreconciledFiles.has(
|
|
19618
|
+
summaries = summaries.map((summary) => unreconciledFiles.has(path37.resolve(summary.filePath)) ? summarizeDiagnostics(summary.filePath, markUnreconciledFindings(summary.diagnostics), summary.hasFinalSnapshot) : summary);
|
|
19364
19619
|
}
|
|
19365
19620
|
const parsedProjectScanObservedAt = projectSnapshot?.scannedAt ? Date.parse(projectSnapshot.scannedAt) : void 0;
|
|
19366
19621
|
const projectScanObservedAt = parsedProjectScanObservedAt !== void 0 && Number.isFinite(parsedProjectScanObservedAt) ? parsedProjectScanObservedAt : void 0;
|
|
@@ -19579,7 +19834,10 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19579
19834
|
const dispositioned = isFullMode ? summaries : summaries.map((s) => {
|
|
19580
19835
|
const diagnostics = s.diagnostics ?? [];
|
|
19581
19836
|
const kept = applyCachedDispositions(diagnostics, cwd, s.filePath);
|
|
19582
|
-
const policyKept = applyRulePolicy(kept, policyMap
|
|
19837
|
+
const policyKept = applyRulePolicy(kept, policyMap, {
|
|
19838
|
+
root: cwd,
|
|
19839
|
+
filePath: s.filePath
|
|
19840
|
+
});
|
|
19583
19841
|
if (policyKept.length === kept.length && kept.length === diagnostics.length)
|
|
19584
19842
|
return s;
|
|
19585
19843
|
return summarizeDiagnostics(s.filePath, policyKept, s.hasFinalSnapshot);
|
|
@@ -19624,7 +19882,7 @@ async function formatAllMode(cwd, severity, summaries = getFileDiagnosticSummari
|
|
|
19624
19882
|
let totalWarnings = 0;
|
|
19625
19883
|
let totalAdvisories = 0;
|
|
19626
19884
|
for (const s of rendered) {
|
|
19627
|
-
const rel =
|
|
19885
|
+
const rel = path37.relative(cwd, s.filePath);
|
|
19628
19886
|
const parts = [];
|
|
19629
19887
|
if (s.blocking > 0)
|
|
19630
19888
|
parts.push(`\u{1F534} ${s.blocking} blocking`);
|
|
@@ -19692,7 +19950,7 @@ Summary (${visibleSummaries.length} files diagnosed this session):`,
|
|
|
19692
19950
|
|
|
19693
19951
|
// dist/tools/lsp-navigation.js
|
|
19694
19952
|
import * as nodeFs2 from "node:fs";
|
|
19695
|
-
import * as
|
|
19953
|
+
import * as path38 from "node:path";
|
|
19696
19954
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
19697
19955
|
|
|
19698
19956
|
// dist/tools/lsp-structured-output.js
|
|
@@ -20402,7 +20660,7 @@ function collectSearchReadsForOperation(operation, result, callHierarchyItem) {
|
|
|
20402
20660
|
}
|
|
20403
20661
|
function formatCapabilities(snapshots, filePath) {
|
|
20404
20662
|
if (snapshots.length === 0) {
|
|
20405
|
-
return filePath ? `No active LSP server for ${
|
|
20663
|
+
return filePath ? `No active LSP server for ${path38.basename(filePath)}. Open/touch the file first or run another LSP operation to start the server.` : "No active LSP servers in this session.";
|
|
20406
20664
|
}
|
|
20407
20665
|
const rows = [
|
|
20408
20666
|
["definition", (s) => !!s.operationSupport.definition],
|
|
@@ -20432,7 +20690,7 @@ function formatCapabilities(snapshots, filePath) {
|
|
|
20432
20690
|
];
|
|
20433
20691
|
const lines = [];
|
|
20434
20692
|
for (const snapshot of snapshots) {
|
|
20435
|
-
const label = filePath ? `${snapshot.serverId} (${
|
|
20693
|
+
const label = filePath ? `${snapshot.serverId} (${path38.basename(filePath)})` : `${snapshot.serverId} (${snapshot.root})`;
|
|
20436
20694
|
lines.push(label);
|
|
20437
20695
|
for (const [name, supported, note] of rows) {
|
|
20438
20696
|
const suffix = note ? ` (${note})` : "";
|
|
@@ -20723,7 +20981,12 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
20723
20981
|
const mutationSource = operation === "executeCommand" ? "lsp-execute-command" : "lsp-rename";
|
|
20724
20982
|
mutationContext = {
|
|
20725
20983
|
cwd,
|
|
20984
|
+
sessionId: ctx.sessionManager?.getSessionId?.(),
|
|
20726
20985
|
correlationId: newLspMutationCorrelationId(_toolCallId),
|
|
20986
|
+
// #4187 R4-1: the call whose `tool_call` licensed the paths it
|
|
20987
|
+
// named; the workspace edit's other files (a rename's importers)
|
|
20988
|
+
// are unlicensed, so they end an authorship instead of advancing it.
|
|
20989
|
+
toolCallId: _toolCallId,
|
|
20727
20990
|
tool: `lsp_navigation:${operation}`,
|
|
20728
20991
|
source: mutationSource,
|
|
20729
20992
|
...mutationDeps,
|
|
@@ -20767,7 +21030,7 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
20767
21030
|
resultCount: 0
|
|
20768
21031
|
});
|
|
20769
21032
|
}
|
|
20770
|
-
const filePath = rawPath ?
|
|
21033
|
+
const filePath = rawPath ? path38.isAbsolute(rawPath) ? rawPath : path38.resolve(ctx.cwd || ".", rawPath) : "";
|
|
20771
21034
|
let filePathIsDirectory = false;
|
|
20772
21035
|
if (filePath) {
|
|
20773
21036
|
try {
|
|
@@ -20803,7 +21066,7 @@ function createLspNavigationTool(getFlag, mutationDeps) {
|
|
|
20803
21066
|
content: [
|
|
20804
21067
|
{
|
|
20805
21068
|
type: "text",
|
|
20806
|
-
text: `No LSP server available for ${
|
|
21069
|
+
text: `No LSP server available for ${path38.basename(filePath)}. Check that the language server is installed.`
|
|
20807
21070
|
}
|
|
20808
21071
|
],
|
|
20809
21072
|
isError: true
|
|
@@ -20904,7 +21167,7 @@ ${JSON.stringify(result2)}`
|
|
|
20904
21167
|
content: [
|
|
20905
21168
|
{
|
|
20906
21169
|
type: "text",
|
|
20907
|
-
text: `No LSP server available for ${
|
|
21170
|
+
text: `No LSP server available for ${path38.basename(filePath)}. Check that the language server is installed.`
|
|
20908
21171
|
}
|
|
20909
21172
|
],
|
|
20910
21173
|
isError: true
|
|
@@ -20923,7 +21186,7 @@ ${JSON.stringify(result2)}`
|
|
|
20923
21186
|
content: [
|
|
20924
21187
|
{
|
|
20925
21188
|
type: "text",
|
|
20926
|
-
text: `LSP server for ${
|
|
21189
|
+
text: `LSP server for ${path38.basename(filePath)} does not advertise support for ${operation}`
|
|
20927
21190
|
}
|
|
20928
21191
|
],
|
|
20929
21192
|
isError: true,
|
|
@@ -20977,7 +21240,7 @@ ${JSON.stringify(result2)}`
|
|
|
20977
21240
|
const msg = err instanceof Error ? err.message : String(err);
|
|
20978
21241
|
if (rawPath && /No Project/i.test(msg)) {
|
|
20979
21242
|
await openFileBestEffort(lspService, filePath);
|
|
20980
|
-
await new Promise((
|
|
21243
|
+
await new Promise((resolve32) => setTimeout(resolve32, 120));
|
|
20981
21244
|
const retryRaw = await lspService.workspaceSymbol(query ?? "", filePath);
|
|
20982
21245
|
const retrySymbols = (Array.isArray(retryRaw) ? retryRaw : [retryRaw]).filter((s) => typeof s === "object" && s !== null);
|
|
20983
21246
|
return dedupeWorkspaceSymbols(retrySymbols);
|
|
@@ -21052,7 +21315,7 @@ ${JSON.stringify(result2)}`
|
|
|
21052
21315
|
if (!newFilePath || newFilePath.trim().length === 0) {
|
|
21053
21316
|
throw new Error("__BADINPUT__ newFilePath parameter required for rename_file");
|
|
21054
21317
|
}
|
|
21055
|
-
const resolvedNewFilePath =
|
|
21318
|
+
const resolvedNewFilePath = path38.isAbsolute(newFilePath) ? newFilePath : path38.resolve(ctx.cwd || ".", newFilePath);
|
|
21056
21319
|
const result2 = await lspService.renameFile(filePath, resolvedNewFilePath, {
|
|
21057
21320
|
cwd: ctx.cwd || ".",
|
|
21058
21321
|
apply: apply ?? false,
|
|
@@ -21196,7 +21459,7 @@ ${JSON.stringify(result2)}`
|
|
|
21196
21459
|
}, { operation, filePath, failureKind: "lsp_error", resultCount: 0 });
|
|
21197
21460
|
}
|
|
21198
21461
|
const isEmpty = !result || Array.isArray(result) && result.length === 0;
|
|
21199
|
-
const fileCtx = filePath ? " at " +
|
|
21462
|
+
const fileCtx = filePath ? " at " + path38.basename(filePath) : "";
|
|
21200
21463
|
const lineCtx = line ? ":" + line + ":" + character : "";
|
|
21201
21464
|
let output = isEmpty ? "No results for " + operation + fileCtx + lineCtx : JSON.stringify(result);
|
|
21202
21465
|
if (isEmpty && operation === "workspaceSymbol" && !rawPath) {
|
|
@@ -21438,11 +21701,11 @@ function resolveDefaultCwd() {
|
|
|
21438
21701
|
const fromArg = process.argv.find((arg) => arg.startsWith("--cwd="))?.slice("--cwd=".length);
|
|
21439
21702
|
return fromArg ?? process.env.PI_LENS_MCP_CWD ?? process.cwd();
|
|
21440
21703
|
}
|
|
21441
|
-
var DEFAULT_CWD =
|
|
21704
|
+
var DEFAULT_CWD = path39.resolve(resolveDefaultCwd());
|
|
21442
21705
|
var lspReadyCwds = /* @__PURE__ */ new Set();
|
|
21443
21706
|
var SERVER_FILE = fileURLToPath3(import.meta.url);
|
|
21444
|
-
var SERVER_DIR =
|
|
21445
|
-
var WORKER_PATH =
|
|
21707
|
+
var SERVER_DIR = path39.dirname(SERVER_FILE);
|
|
21708
|
+
var WORKER_PATH = path39.join(SERVER_DIR, "worker.js");
|
|
21446
21709
|
var REBUILD_SCRIPT = resolveRebuildScript(SERVER_FILE);
|
|
21447
21710
|
var STALENESS_STAT_PATH = process.env.PI_LENS_MCP_STALENESS_STAT_PATH ?? SERVER_FILE;
|
|
21448
21711
|
var BUILD_STAMP = computeBuildStamp(STALENESS_STAT_PATH);
|
|
@@ -21464,7 +21727,7 @@ function isWarmBuildStale() {
|
|
|
21464
21727
|
function findRepoRoot(start) {
|
|
21465
21728
|
let dir = start;
|
|
21466
21729
|
for (let depth = 0; depth < 6; depth++) {
|
|
21467
|
-
const pkgPath =
|
|
21730
|
+
const pkgPath = path39.join(dir, "package.json");
|
|
21468
21731
|
if (fs25.existsSync(pkgPath)) {
|
|
21469
21732
|
try {
|
|
21470
21733
|
const pkg = JSON.parse(fs25.readFileSync(pkgPath, "utf8"));
|
|
@@ -21473,16 +21736,16 @@ function findRepoRoot(start) {
|
|
|
21473
21736
|
} catch {
|
|
21474
21737
|
}
|
|
21475
21738
|
}
|
|
21476
|
-
const parent =
|
|
21739
|
+
const parent = path39.dirname(dir);
|
|
21477
21740
|
if (parent === dir)
|
|
21478
21741
|
break;
|
|
21479
21742
|
dir = parent;
|
|
21480
21743
|
}
|
|
21481
|
-
return
|
|
21744
|
+
return path39.resolve(start, "..", "..");
|
|
21482
21745
|
}
|
|
21483
|
-
var REPO_ROOT = process.env.PI_LENS_MCP_REPO_ROOT ?
|
|
21746
|
+
var REPO_ROOT = process.env.PI_LENS_MCP_REPO_ROOT ? path39.resolve(process.env.PI_LENS_MCP_REPO_ROOT) : findRepoRoot(SERVER_DIR);
|
|
21484
21747
|
async function ensureReady(cwd) {
|
|
21485
|
-
const normalized =
|
|
21748
|
+
const normalized = path39.resolve(cwd);
|
|
21486
21749
|
if (!shouldInitializeSessionRoot(normalized, lspReadyCwds)) {
|
|
21487
21750
|
return;
|
|
21488
21751
|
}
|
|
@@ -21528,14 +21791,14 @@ function getAutoSessionStatus() {
|
|
|
21528
21791
|
}
|
|
21529
21792
|
var IPC_PATH = ipcPathForCwd(DEFAULT_CWD);
|
|
21530
21793
|
function rejectForeignTurnCwd(route, cwd) {
|
|
21531
|
-
const message = `${route} cwd outside this server's workspace: ${
|
|
21794
|
+
const message = `${route} cwd outside this server's workspace: ${path39.resolve(cwd)} not within ${DEFAULT_CWD}`;
|
|
21532
21795
|
console.error(`[pi-lens-mcp] rejected ${message}`);
|
|
21533
21796
|
return message;
|
|
21534
21797
|
}
|
|
21535
21798
|
function isWithinServerWorkspace(cwd) {
|
|
21536
|
-
const target =
|
|
21537
|
-
const rel =
|
|
21538
|
-
return !rel.startsWith("..") && !
|
|
21799
|
+
const target = path39.resolve(cwd);
|
|
21800
|
+
const rel = path39.relative(DEFAULT_CWD, target);
|
|
21801
|
+
return !rel.startsWith("..") && !path39.isAbsolute(rel);
|
|
21539
21802
|
}
|
|
21540
21803
|
function startIpcServer() {
|
|
21541
21804
|
if (process.platform !== "win32") {
|
|
@@ -21685,6 +21948,12 @@ function graphStalenessNote(builtAtIso, label) {
|
|
|
21685
21948
|
return void 0;
|
|
21686
21949
|
return `${label} last updated ${formatRelativeAge(ageMs)}; run pilens_analyze on recently-changed files, pilens_session_start, or pilens_rebuild to refresh it.`;
|
|
21687
21950
|
}
|
|
21951
|
+
setProjectTrustState("trusted");
|
|
21952
|
+
logExtension({
|
|
21953
|
+
subsystem: "project-trust",
|
|
21954
|
+
level: "debug",
|
|
21955
|
+
message: "mcp: workspace trust belongs to the MCP client; pi trust not consulted"
|
|
21956
|
+
});
|
|
21688
21957
|
var cacheManager = new CacheManager();
|
|
21689
21958
|
var isLensGuardEnabled = () => Boolean(createMcpHost(void 0, DEFAULT_CWD).getFlag("lens-guard"));
|
|
21690
21959
|
var lensDiagnosticsTool = createLensDiagnosticsTool(
|
|
@@ -22024,7 +22293,7 @@ function enabledToolsForCwd(cwd) {
|
|
|
22024
22293
|
}
|
|
22025
22294
|
function formatAnalyze(result, cwd, mode, servedBy) {
|
|
22026
22295
|
const lspNote = result.lsp ? ` \xB7 lsp ${result.lsp.diagnosticCount} (${result.lsp.status}${result.lsp.failureKind ? `: ${result.lsp.failureKind}` : ""}, ${result.lsp.durationMs}ms)` : "";
|
|
22027
|
-
const summary = `${
|
|
22296
|
+
const summary = `${path39.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 ? `
|
|
22028
22297
|
|
|
22029
22298
|
servedBy: ${servedBy}` : "");
|
|
22030
22299
|
return renderToolText(summary, servedBy ? { ...result, servedBy } : result);
|
|
@@ -22158,7 +22427,7 @@ ${outcome.output}`, {
|
|
|
22158
22427
|
}
|
|
22159
22428
|
const { deduped, byRule, byFile } = summarizeScan(snapshot.diagnostics);
|
|
22160
22429
|
const topRules = Object.entries(byRule).sort((a, b) => b[1] - a[1]);
|
|
22161
|
-
const topFiles = Object.entries(byFile).sort((a, b) => b[1] - a[1]).slice(0, 15).map(([file, count]) => ({ file:
|
|
22430
|
+
const topFiles = Object.entries(byFile).sort((a, b) => b[1] - a[1]).slice(0, 15).map(([file, count]) => ({ file: path39.relative(cwd, file), count }));
|
|
22162
22431
|
const summaryLines = [
|
|
22163
22432
|
`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)` : ""),
|
|
22164
22433
|
...topRules.slice(0, 12).map(([rule, count]) => ` ${count}\xD7 ${rule}`)
|
|
@@ -22211,7 +22480,7 @@ ${stalenessNote}` : ""), {
|
|
|
22211
22480
|
}
|
|
22212
22481
|
const lines = [
|
|
22213
22482
|
`Top ${results.length} file(s) for "${query}":`,
|
|
22214
|
-
...results.map((result, i) => ` ${i + 1}. ${
|
|
22483
|
+
...results.map((result, i) => ` ${i + 1}. ${path39.relative(cwd, result.file)} (score ${result.score.toFixed(2)}, ${result.hits} hit(s), line ${result.startLine})`),
|
|
22215
22484
|
...stalenessNote ? ["", stalenessNote] : [],
|
|
22216
22485
|
...coverage ? [
|
|
22217
22486
|
`Index covers ${coverage.files} files${coverage.truncated ? " (capped \u2014 results may be incomplete)" : ""}.`
|
|
@@ -22221,7 +22490,7 @@ ${stalenessNote}` : ""), {
|
|
|
22221
22490
|
query,
|
|
22222
22491
|
coverage,
|
|
22223
22492
|
results: results.map((result) => {
|
|
22224
|
-
const relFile =
|
|
22493
|
+
const relFile = path39.relative(cwd, result.file);
|
|
22225
22494
|
return {
|
|
22226
22495
|
file: relFile,
|
|
22227
22496
|
score: result.score,
|
|
@@ -22260,12 +22529,12 @@ ${stalenessNote}` : ""), {
|
|
|
22260
22529
|
});
|
|
22261
22530
|
if (!report.available) {
|
|
22262
22531
|
return {
|
|
22263
|
-
...renderToolText(`No module report for ${
|
|
22532
|
+
...renderToolText(`No module report for ${path39.relative(cwd, path39.resolve(cwd, file))} \u2014 not a symbol-bearing file, or unreadable.`, report, true),
|
|
22264
22533
|
isError: true
|
|
22265
22534
|
};
|
|
22266
22535
|
}
|
|
22267
22536
|
const graphStaleness = graphStalenessNote(report.graphBuiltAt, "Review graph");
|
|
22268
|
-
const summary = `${
|
|
22537
|
+
const summary = `${path39.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 ? `
|
|
22269
22538
|
|
|
22270
22539
|
${graphStaleness}` : "");
|
|
22271
22540
|
if (view === "compact") {
|
|
@@ -22326,7 +22595,7 @@ ${graphStaleness}` : "");
|
|
|
22326
22595
|
if (!result.found) {
|
|
22327
22596
|
const suggestionSuffix = result.suggestions?.length ? ` Did you mean: ${result.suggestions.join(", ")}?` : " Use pilens_module_report to list symbols.";
|
|
22328
22597
|
return {
|
|
22329
|
-
...renderToolText(`Symbol "${symbol}" not found in ${
|
|
22598
|
+
...renderToolText(`Symbol "${symbol}" not found in ${path39.basename(file)}.${suggestionSuffix}`, {
|
|
22330
22599
|
found: false,
|
|
22331
22600
|
...result.suggestions ? { suggestions: result.suggestions } : {}
|
|
22332
22601
|
}),
|
|
@@ -22335,7 +22604,7 @@ ${graphStaleness}` : "");
|
|
|
22335
22604
|
}
|
|
22336
22605
|
const sigSuffix = result.signature ? ` ${result.signature}` : "";
|
|
22337
22606
|
const ambiguityNote = result.ambiguous ? ` (${result.ambiguous.count} matches \u2014 returned the ${result.kind}; pass \`kind\` to disambiguate: ${result.ambiguous.kinds.join(", ")})` : "";
|
|
22338
|
-
const header = `${result.kind} ${result.name}${ambiguityNote}${sigSuffix} ${
|
|
22607
|
+
const header = `${result.kind} ${result.name}${ambiguityNote}${sigSuffix} ${path39.relative(cwd, result.path)}:${result.startLine}-${result.endLine}`;
|
|
22339
22608
|
return {
|
|
22340
22609
|
content: [
|
|
22341
22610
|
{
|
|
@@ -22373,14 +22642,14 @@ ${result.source ?? ""}`
|
|
|
22373
22642
|
|
|
22374
22643
|
Nested outline:
|
|
22375
22644
|
${JSON.stringify(result.outline)}` : "";
|
|
22376
|
-
const text = result.error ? `Could not read enclosing range in ${
|
|
22645
|
+
const text = result.error ? `Could not read enclosing range in ${path39.basename(file)}:${result.line}: ${result.error}${warningSuffix}${outlineSuffix}` : `No enclosing symbol/callback found in ${path39.basename(file)}:${result.line}.${warningSuffix}`;
|
|
22377
22646
|
return {
|
|
22378
22647
|
...renderToolText(text, { found: false, line: result.line }),
|
|
22379
22648
|
isError: true
|
|
22380
22649
|
};
|
|
22381
22650
|
}
|
|
22382
22651
|
const range = result.partial ? `${result.startLine}-${result.endLine} (partial of ${result.enclosingStartLine}-${result.enclosingEndLine})` : `${result.startLine}-${result.endLine}`;
|
|
22383
|
-
const header = `${result.kind} ${result.name} ${
|
|
22652
|
+
const header = `${result.kind} ${result.name} ${path39.relative(cwd, result.path)}:${range}`;
|
|
22384
22653
|
return {
|
|
22385
22654
|
content: [
|
|
22386
22655
|
{
|
|
@@ -22415,7 +22684,7 @@ ${result.source ?? ""}`
|
|
|
22415
22684
|
]),
|
|
22416
22685
|
...renderLspBrokenStatusLines(brokenServers),
|
|
22417
22686
|
...renderDegradationLines(degradations),
|
|
22418
|
-
last ? `Last dispatch: ${
|
|
22687
|
+
last ? `Last dispatch: ${path39.basename(last.filePath)} \u2014 ${last.totalDurationMs}ms, ${last.totalDiagnostics} diagnostic(s)` : "Last dispatch: none yet",
|
|
22419
22688
|
`Diagnostics this session: ${stats.totalShown} shown \xB7 ${stats.totalAutoFixed} auto-fixed \xB7 ${stats.totalUnresolved} unresolved`,
|
|
22420
22689
|
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)",
|
|
22421
22690
|
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)",
|
|
@@ -22481,7 +22750,7 @@ ${result.source ?? ""}`
|
|
|
22481
22750
|
const limit = typeof args.limit === "number" && Number.isFinite(args.limit) ? Math.max(1, Math.floor(args.limit)) : 5;
|
|
22482
22751
|
const fileFilter = typeof args.file === "string" ? args.file : void 0;
|
|
22483
22752
|
const recent = recentLatency(limit, fileFilter);
|
|
22484
|
-
const summary = recent.length === 0 ? "No dispatch latency reports yet." : recent.map((report) => `${
|
|
22753
|
+
const summary = recent.length === 0 ? "No dispatch latency reports yet." : recent.map((report) => `${path39.basename(report.filePath)}: ${report.totalDurationMs}ms (${report.totalDiagnostics} diag${report.stoppedEarly ? ", stopped early" : ""})`).join("\n");
|
|
22485
22754
|
return renderToolText(summary, recent);
|
|
22486
22755
|
}
|
|
22487
22756
|
if (name === "pilens_session_start") {
|