projscan 1.9.0 → 1.11.0

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.
Files changed (41) hide show
  1. package/README.md +47 -21
  2. package/dist/cli/_shared.d.ts +2 -0
  3. package/dist/cli/_shared.js +33 -0
  4. package/dist/cli/_shared.js.map +1 -1
  5. package/dist/cli/commands/analyze.js +4 -1
  6. package/dist/cli/commands/analyze.js.map +1 -1
  7. package/dist/cli/commands/ci.js +19 -2
  8. package/dist/cli/commands/ci.js.map +1 -1
  9. package/dist/cli/commands/doctor.js +6 -1
  10. package/dist/cli/commands/doctor.js.map +1 -1
  11. package/dist/cli/commands/plugin.d.ts +6 -0
  12. package/dist/cli/commands/plugin.js +111 -0
  13. package/dist/cli/commands/plugin.js.map +1 -0
  14. package/dist/cli/index.js +2 -0
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/core/applyFix.d.ts +9 -0
  17. package/dist/core/applyFix.js +71 -0
  18. package/dist/core/applyFix.js.map +1 -1
  19. package/dist/core/codeGraph.js +8 -1
  20. package/dist/core/codeGraph.js.map +1 -1
  21. package/dist/core/issueEngine.js +12 -0
  22. package/dist/core/issueEngine.js.map +1 -1
  23. package/dist/core/plugins.d.ts +146 -0
  24. package/dist/core/plugins.js +399 -0
  25. package/dist/core/plugins.js.map +1 -0
  26. package/dist/core/taint.js +27 -4
  27. package/dist/core/taint.js.map +1 -1
  28. package/dist/core/watcher.d.ts +8 -0
  29. package/dist/core/watcher.js +48 -18
  30. package/dist/core/watcher.js.map +1 -1
  31. package/dist/mcp/tools/costSummary.js +259 -49
  32. package/dist/mcp/tools/costSummary.js.map +1 -1
  33. package/dist/mcp/tools/plugin.d.ts +13 -0
  34. package/dist/mcp/tools/plugin.js +72 -0
  35. package/dist/mcp/tools/plugin.js.map +1 -0
  36. package/dist/mcp/tools.js +2 -0
  37. package/dist/mcp/tools.js.map +1 -1
  38. package/dist/tool-manifest.json +44 -5
  39. package/dist/utils/changedFiles.js +25 -0
  40. package/dist/utils/changedFiles.js.map +1 -1
  41. package/package.json +2 -2
@@ -1,4 +1,7 @@
1
1
  import { loadSession } from '../../core/session.js';
2
+ const DEFAULT_STREAM_INTERVAL_S = 10;
3
+ const MIN_STREAM_INTERVAL_S = 2;
4
+ const MAX_STREAM_INTERVAL_S = 600;
2
5
  /**
3
6
  * 1.7+ — `projscan_cost_summary`. Aggregate token-cost analytics
4
7
  * derived from the session event log. Builds on the `_cost` sidecar
@@ -25,68 +28,275 @@ import { loadSession } from '../../core/session.js';
25
28
  */
26
29
  export const costSummaryTool = {
27
30
  name: 'projscan_cost_summary',
28
- description: 'Aggregate token-cost analytics from the current session\'s tool-call history. Returns total tokens spent, top spenders, per-tool typical/p95 estimates, and a static expected-cost catalog so the agent can budget pre-call. Pairs with the `_cost` sidecar attached to every tool result. Read-only. Note: the session event log is bounded at 500 entries, so the view reflects recent activity rather than the full lifetime of the session — for long-running sessions, older calls are dropped.',
31
+ description: 'Aggregate token-cost analytics from the current session\'s tool-call history. action:"snapshot" (default) returns total tokens spent, top spenders, per-tool typical/p95 estimates, and a static expected-cost catalog so the agent can budget pre-call. 1.10+: action:"start_stream" / "stop_stream" / "list_streams" turns this into a live cost dashboard — the server polls the session log on an interval and emits notifications/projscan/cost_delta whenever new tool calls have accrued, with the per-tool deltas and the new cumulative totals inline. Pairs with the `_cost` sidecar attached to every tool result. Read-only. Note: the session event log is bounded at 500 entries — for long-running sessions, older calls are dropped from the snapshot.',
29
32
  inputSchema: {
30
33
  type: 'object',
31
34
  properties: {
35
+ action: {
36
+ type: 'string',
37
+ enum: ['snapshot', 'start_stream', 'stop_stream', 'list_streams'],
38
+ description: '"snapshot" (default) returns the current aggregate. "start_stream" begins a live cost-delta watch. "stop_stream" cancels by stream_id. "list_streams" enumerates active streams.',
39
+ },
32
40
  top: {
33
41
  type: 'number',
34
- description: 'Optional. Number of top spenders to return. Default: 10.',
42
+ description: 'Optional. Number of top spenders to return. Default: 10. (snapshot + start_stream)',
43
+ },
44
+ interval_seconds: {
45
+ type: 'number',
46
+ description: `Stream poll interval in seconds. Default: ${DEFAULT_STREAM_INTERVAL_S}. Min: ${MIN_STREAM_INTERVAL_S}, max: ${MAX_STREAM_INTERVAL_S}. (start_stream only)`,
47
+ },
48
+ stream_id: {
49
+ type: 'string',
50
+ description: 'Stream identifier returned by a previous start_stream. (stop_stream only)',
35
51
  },
36
52
  },
37
53
  },
38
- handler: async (args, rootPath) => {
39
- const top = typeof args.top === 'number' && Number.isFinite(args.top) && args.top > 0
40
- ? Math.min(50, Math.floor(args.top))
41
- : 10;
42
- const { session } = await loadSession(rootPath);
43
- const buckets = bucketize(session.events);
44
- let totalCalls = 0;
45
- let totalEstimatedTokens = 0;
46
- for (const bucket of buckets.values()) {
47
- totalCalls += bucket.callCount;
48
- totalEstimatedTokens += bucket.totalTokens;
54
+ handler: async (args, rootPath, context) => {
55
+ const action = typeof args.action === 'string' ? args.action : 'snapshot';
56
+ switch (action) {
57
+ case 'snapshot':
58
+ return computeSnapshot(rootPath, args);
59
+ case 'start_stream':
60
+ return startStream(rootPath, args, context);
61
+ case 'stop_stream':
62
+ return stopStream(args, context);
63
+ case 'list_streams':
64
+ return listStreams();
65
+ default:
66
+ throw new Error(`Unknown action "${action}". Known: snapshot, start_stream, stop_stream, list_streams.`);
49
67
  }
50
- const ranked = [...buckets.values()].sort((a, b) => b.totalTokens - a.totalTokens);
51
- const topSpenders = ranked.slice(0, top).map((b) => ({
68
+ },
69
+ };
70
+ const streams = new Map();
71
+ async function computeSnapshot(rootPath, args) {
72
+ const top = typeof args.top === 'number' && Number.isFinite(args.top) && args.top > 0
73
+ ? Math.min(50, Math.floor(args.top))
74
+ : 10;
75
+ const { session } = await loadSession(rootPath);
76
+ const buckets = bucketize(session.events);
77
+ let totalCalls = 0;
78
+ let totalEstimatedTokens = 0;
79
+ for (const bucket of buckets.values()) {
80
+ totalCalls += bucket.callCount;
81
+ totalEstimatedTokens += bucket.totalTokens;
82
+ }
83
+ const ranked = [...buckets.values()].sort((a, b) => b.totalTokens - a.totalTokens);
84
+ const topSpenders = ranked.slice(0, top).map((b) => ({
85
+ tool: b.tool,
86
+ totalTokens: b.totalTokens,
87
+ callCount: b.callCount,
88
+ averageTokens: b.callCount > 0 ? Math.round(b.totalTokens / b.callCount) : 0,
89
+ }));
90
+ // 1.8+ — only report a real p95 when we have enough samples for it
91
+ // to be meaningful. With < MIN_P95_SAMPLES, sorted[len*0.95] just
92
+ // returns the observed maximum, which agents misinterpret as a
93
+ // representative high-water mark for budgeting. We surface null and
94
+ // an explicit `insufficientSamples: true` flag so the agent knows
95
+ // to fall back to expectedTokens or wait for more data.
96
+ const MIN_P95_SAMPLES = 20;
97
+ const perToolCatalog = ranked.map((b) => {
98
+ const sorted = [...b.tokenSamples].sort((x, y) => x - y);
99
+ const median = sorted.length === 0 ? 0 : sorted[Math.floor(sorted.length / 2)];
100
+ const hasEnoughForP95 = sorted.length >= MIN_P95_SAMPLES;
101
+ const p95 = hasEnoughForP95
102
+ ? sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95))]
103
+ : null;
104
+ return {
52
105
  tool: b.tool,
53
- totalTokens: b.totalTokens,
106
+ observedTypicalTokens: median,
107
+ observedP95Tokens: p95,
108
+ observedP95InsufficientSamples: !hasEnoughForP95,
54
109
  callCount: b.callCount,
55
- averageTokens: b.callCount > 0 ? Math.round(b.totalTokens / b.callCount) : 0,
56
- }));
57
- // 1.8+ — only report a real p95 when we have enough samples for it
58
- // to be meaningful. With < MIN_P95_SAMPLES, sorted[len*0.95] just
59
- // returns the observed maximum, which agents misinterpret as a
60
- // representative high-water mark for budgeting. We surface null and
61
- // an explicit `insufficientSamples: true` flag so the agent knows
62
- // to fall back to expectedTokens or wait for more data.
63
- const MIN_P95_SAMPLES = 20;
64
- const perToolCatalog = ranked.map((b) => {
65
- const sorted = [...b.tokenSamples].sort((x, y) => x - y);
66
- const median = sorted.length === 0 ? 0 : sorted[Math.floor(sorted.length / 2)];
67
- const hasEnoughForP95 = sorted.length >= MIN_P95_SAMPLES;
68
- const p95 = hasEnoughForP95
69
- ? sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95))]
70
- : null;
71
- return {
72
- tool: b.tool,
73
- observedTypicalTokens: median,
74
- observedP95Tokens: p95,
75
- observedP95InsufficientSamples: !hasEnoughForP95,
76
- callCount: b.callCount,
77
- expectedTokens: STATIC_EXPECTED_TOKENS[b.tool] ?? null,
78
- };
79
- });
110
+ expectedTokens: STATIC_EXPECTED_TOKENS[b.tool] ?? null,
111
+ };
112
+ });
113
+ return {
114
+ sessionId: session.id,
115
+ totalCalls,
116
+ totalEstimatedTokens,
117
+ averageTokens: totalCalls > 0 ? Math.round(totalEstimatedTokens / totalCalls) : 0,
118
+ topSpenders,
119
+ perToolCatalog,
120
+ };
121
+ }
122
+ async function startStream(rootPath, args, context) {
123
+ const requested = typeof args.interval_seconds === 'number' && Number.isFinite(args.interval_seconds)
124
+ ? args.interval_seconds
125
+ : DEFAULT_STREAM_INTERVAL_S;
126
+ const intervalSeconds = clamp(requested, MIN_STREAM_INTERVAL_S, MAX_STREAM_INTERVAL_S);
127
+ const intervalMs = Math.round(intervalSeconds * 1000);
128
+ // Seed last-seen counts so the first tick after start reports only NEW
129
+ // calls — the initial snapshot is the baseline. Without this, every
130
+ // existing event in the session log would be reported as a delta.
131
+ const { session } = await loadSession(rootPath);
132
+ const initialBuckets = bucketize(session.events);
133
+ const lastSeenCalls = {};
134
+ let lastTotalCalls = 0;
135
+ let lastTotalTokens = 0;
136
+ for (const b of initialBuckets.values()) {
137
+ lastSeenCalls[b.tool] = b.callCount;
138
+ lastTotalCalls += b.callCount;
139
+ lastTotalTokens += b.totalTokens;
140
+ }
141
+ if (!context?.registerWatch || !context.notify) {
80
142
  return {
81
- sessionId: session.id,
82
- totalCalls,
83
- totalEstimatedTokens,
84
- averageTokens: totalCalls > 0 ? Math.round(totalEstimatedTokens / totalCalls) : 0,
85
- topSpenders,
86
- perToolCatalog,
143
+ action: 'start_stream',
144
+ streamId: null,
145
+ registered: false,
146
+ reason: 'No notify channel server was started without one (or this is a non-MCP caller). Subscribe to the MCP notify channel to receive cost_delta updates.',
147
+ intervalSeconds,
148
+ baseline: { totalCalls: lastTotalCalls, totalEstimatedTokens: lastTotalTokens },
87
149
  };
88
- },
89
- };
150
+ }
151
+ let timer = null;
152
+ const streamId = context.registerWatch(() => {
153
+ if (timer)
154
+ clearInterval(timer);
155
+ timer = null;
156
+ streams.delete(streamId);
157
+ });
158
+ streams.set(streamId, {
159
+ streamId,
160
+ intervalMs,
161
+ startedAt: new Date().toISOString(),
162
+ ticks: 0,
163
+ lastSeenCalls,
164
+ lastTotalTokens,
165
+ lastTotalCalls,
166
+ inFlight: false,
167
+ });
168
+ const tick = () => {
169
+ void runCostTick(rootPath, streamId, context);
170
+ };
171
+ timer = setInterval(tick, intervalMs);
172
+ // Don't keep the process alive on the polling timer alone.
173
+ if (typeof timer.unref === 'function')
174
+ timer.unref();
175
+ return {
176
+ action: 'start_stream',
177
+ streamId,
178
+ registered: true,
179
+ intervalSeconds,
180
+ baseline: { totalCalls: lastTotalCalls, totalEstimatedTokens: lastTotalTokens },
181
+ };
182
+ }
183
+ async function runCostTick(rootPath, streamId, context) {
184
+ const state = streams.get(streamId);
185
+ if (!state)
186
+ return;
187
+ // Single-flight guard. Session reads are fast but disk hiccups (slow
188
+ // NFS, contended writes) could overlap; we don't queue, the next tick
189
+ // picks up the latest state.
190
+ if (state.inFlight)
191
+ return;
192
+ state.inFlight = true;
193
+ state.ticks += 1;
194
+ try {
195
+ let session;
196
+ try {
197
+ const loaded = await loadSession(rootPath);
198
+ session = loaded.session;
199
+ }
200
+ catch (err) {
201
+ context.notify?.('notifications/projscan/cost_stream_error', {
202
+ streamId,
203
+ error: err instanceof Error ? err.message : String(err),
204
+ });
205
+ return;
206
+ }
207
+ const buckets = bucketize(session.events);
208
+ const perToolDelta = [];
209
+ let newTotalCalls = 0;
210
+ let newTotalTokens = 0;
211
+ const seen = new Set();
212
+ for (const b of buckets.values()) {
213
+ seen.add(b.tool);
214
+ newTotalCalls += b.callCount;
215
+ newTotalTokens += b.totalTokens;
216
+ const prevCalls = state.lastSeenCalls[b.tool] ?? 0;
217
+ const callsAdded = b.callCount - prevCalls;
218
+ if (callsAdded > 0) {
219
+ // The session log is bounded to 500 entries — a per-tool count can
220
+ // also DECREASE when old events for that tool roll off. We only
221
+ // surface positive deltas (new calls); a decrease just adjusts
222
+ // the running baseline without firing a delta event.
223
+ const tokensAdded = b.totalTokens - (prevToolTokens(state, b, prevCalls) ?? 0);
224
+ perToolDelta.push({
225
+ tool: b.tool,
226
+ callsAdded,
227
+ tokensAdded: Math.max(0, tokensAdded),
228
+ cumulativeCalls: b.callCount,
229
+ cumulativeTokens: b.totalTokens,
230
+ });
231
+ }
232
+ state.lastSeenCalls[b.tool] = b.callCount;
233
+ }
234
+ // Drop tools that have fully aged out of the log so the state map
235
+ // doesn't grow forever.
236
+ for (const tool of Object.keys(state.lastSeenCalls)) {
237
+ if (!seen.has(tool))
238
+ delete state.lastSeenCalls[tool];
239
+ }
240
+ if (perToolDelta.length === 0)
241
+ return; // nothing new — silent tick
242
+ state.lastTotalCalls = newTotalCalls;
243
+ state.lastTotalTokens = newTotalTokens;
244
+ context.notify?.('notifications/projscan/cost_delta', {
245
+ streamId,
246
+ sessionId: session.id,
247
+ perTool: perToolDelta,
248
+ cumulative: {
249
+ totalCalls: newTotalCalls,
250
+ totalEstimatedTokens: newTotalTokens,
251
+ },
252
+ });
253
+ }
254
+ finally {
255
+ state.inFlight = false;
256
+ }
257
+ }
258
+ /**
259
+ * The session event log is bounded; we don't carry per-tool token history
260
+ * across ticks beyond a single call count. Approximating tokens-added by
261
+ * (current total - prior average × prior count) is fragile, so we just
262
+ * round up using the bucket's own token-per-call ratio. Good enough for
263
+ * an at-a-glance dashboard; downstream agents that need exact attribution
264
+ * can call action:"snapshot" for the canonical view.
265
+ */
266
+ function prevToolTokens(state, bucket, prevCalls) {
267
+ if (bucket.callCount === 0 || prevCalls === 0)
268
+ return 0;
269
+ return Math.round((bucket.totalTokens / bucket.callCount) * prevCalls);
270
+ }
271
+ function stopStream(args, context) {
272
+ const streamId = typeof args.stream_id === 'string' ? args.stream_id : '';
273
+ if (!streamId)
274
+ throw new Error('stop_stream action requires a "stream_id" argument');
275
+ const knownLocally = streams.has(streamId);
276
+ // The server's registerWatch cancel callback already deletes from `streams`.
277
+ const cancelled = context?.unregisterWatch?.(streamId) ?? false;
278
+ // If the server didn't know about the watch (e.g., cross-transport),
279
+ // make sure our local map is also clean.
280
+ if (streams.has(streamId))
281
+ streams.delete(streamId);
282
+ return { action: 'stop_stream', streamId, cancelled: cancelled || knownLocally };
283
+ }
284
+ function listStreams() {
285
+ return {
286
+ action: 'list_streams',
287
+ streams: [...streams.values()].map((s) => ({
288
+ streamId: s.streamId,
289
+ startedAt: s.startedAt,
290
+ intervalMs: s.intervalMs,
291
+ ticks: s.ticks,
292
+ lastTotalCalls: s.lastTotalCalls,
293
+ lastTotalTokens: s.lastTotalTokens,
294
+ })),
295
+ };
296
+ }
297
+ function clamp(v, lo, hi) {
298
+ return Math.max(lo, Math.min(hi, v));
299
+ }
90
300
  function bucketize(events) {
91
301
  const buckets = new Map();
92
302
  for (const ev of events) {
@@ -1 +1 @@
1
- {"version":3,"file":"costSummary.js","sourceRoot":"","sources":["../../../src/mcp/tools/costSummary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAqB,MAAM,uBAAuB,CAAC;AAGvE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,seAAse;IACxe,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0DAA0D;aACxE;SACF;KACF;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QAChC,MAAM,GAAG,GACP,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC;YACvE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC,CAAC,EAAE,CAAC;QAET,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1C,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,oBAAoB,GAAG,CAAC,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACtC,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC;YAC/B,oBAAoB,IAAI,MAAM,CAAC,WAAW,CAAC;QAC7C,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;QACnF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,aAAa,EAAE,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SAC7E,CAAC,CAAC,CAAC;QAEJ,mEAAmE;QACnE,kEAAkE;QAClE,+DAA+D;QAC/D,oEAAoE;QACpE,kEAAkE;QAClE,wDAAwD;QACxD,MAAM,eAAe,GAAG,EAAE,CAAC;QAC3B,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACtC,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/E,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;YACzD,MAAM,GAAG,GAAG,eAAe;gBACzB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;gBACvE,CAAC,CAAC,IAAI,CAAC;YACT,OAAO;gBACL,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,qBAAqB,EAAE,MAAM;gBAC7B,iBAAiB,EAAE,GAAG;gBACtB,8BAA8B,EAAE,CAAC,eAAe;gBAChD,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,cAAc,EAAE,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI;aACvD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,UAAU;YACV,oBAAoB;YACpB,aAAa,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACjF,WAAW;YACX,cAAc;SACf,CAAC;IACJ,CAAC;CACF,CAAC;AASF,SAAS,SAAS,CAAC,MAAmC;IACpD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC9C,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,SAAS;QAChD,MAAM,MAAM,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,MAAM,KAAK,IAAI;YAAE,SAAS,CAAC,iDAAiD;QAChF,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;QACtB,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC;QAC7B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,mBAAmB,CAAC,EAAgB;IAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,IAAiD,CAAC;IAClE,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,sBAAsB,GAA2B;IACrD,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;IACtB,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,IAAI;IACrB,wBAAwB,EAAE,IAAI;IAC9B,mBAAmB,EAAE,IAAI;IACzB,iBAAiB,EAAE,IAAI;IACvB,iBAAiB,EAAE,IAAI;IACvB,iBAAiB,EAAE,IAAI;IACvB,qBAAqB,EAAE,IAAI;IAC3B,iBAAiB,EAAE,IAAI;IACvB,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,IAAI;IACpB,kBAAkB,EAAE,IAAI;IACxB,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,IAAI;IACtB,sBAAsB,EAAE,GAAG;IAC3B,oBAAoB,EAAE,GAAG;IACzB,kBAAkB,EAAE,IAAI;IACxB,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,GAAG;IACrB,eAAe,EAAE,IAAI;IACrB,qBAAqB,EAAE,IAAI;CAC5B,CAAC"}
1
+ {"version":3,"file":"costSummary.js","sourceRoot":"","sources":["../../../src/mcp/tools/costSummary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { McpTool } from './_shared.js';
2
+ /**
3
+ * `projscan_plugin` (1.10+ preview) — discover and validate third-party
4
+ * plugins under `<root>/.projscan-plugins/*.projscan-plugin.json`.
5
+ *
6
+ * Behind the PROJSCAN_PLUGINS_PREVIEW=1 feature flag. The tool is always
7
+ * registered (so agents can probe for it), but `action:"list"` returns
8
+ * `enabled:false` and an empty list when the flag is off, so callers can
9
+ * detect that the preview is dark without an extra `enabled` check.
10
+ *
11
+ * The plugin schema and discovery path may still change before 2.0.
12
+ */
13
+ export declare const pluginTool: McpTool;
@@ -0,0 +1,72 @@
1
+ import path from 'node:path';
2
+ import { PLUGIN_PREVIEW_FLAG, discoverPluginManifests, pluginsEnabled, readPluginManifestFile, } from '../../core/plugins.js';
3
+ /**
4
+ * `projscan_plugin` (1.10+ preview) — discover and validate third-party
5
+ * plugins under `<root>/.projscan-plugins/*.projscan-plugin.json`.
6
+ *
7
+ * Behind the PROJSCAN_PLUGINS_PREVIEW=1 feature flag. The tool is always
8
+ * registered (so agents can probe for it), but `action:"list"` returns
9
+ * `enabled:false` and an empty list when the flag is off, so callers can
10
+ * detect that the preview is dark without an extra `enabled` check.
11
+ *
12
+ * The plugin schema and discovery path may still change before 2.0.
13
+ */
14
+ export const pluginTool = {
15
+ name: 'projscan_plugin',
16
+ description: '1.10+ preview. Discover and validate third-party analyzer and reporter plugins under .projscan-plugins/. Gated by the PROJSCAN_PLUGINS_PREVIEW=1 env flag; the schema is preview-only and may shift before 2.0. Use action:"list" to see what is discoverable today, action:"validate" to check a manifest before committing it.',
17
+ inputSchema: {
18
+ type: 'object',
19
+ properties: {
20
+ action: {
21
+ type: 'string',
22
+ enum: ['list', 'validate'],
23
+ description: '"list" enumerates manifests under <root>/.projscan-plugins/ with discovery status. "validate" lints a manifest at the given path against the 1.10 schema.',
24
+ },
25
+ manifest_path: {
26
+ type: 'string',
27
+ description: '"validate" only — repo-relative or absolute path to a *.projscan-plugin.json file.',
28
+ },
29
+ },
30
+ },
31
+ handler: async (args, rootPath) => {
32
+ const action = typeof args.action === 'string' ? args.action : 'list';
33
+ switch (action) {
34
+ case 'list': {
35
+ const entries = await discoverPluginManifests(rootPath);
36
+ return {
37
+ enabled: pluginsEnabled(),
38
+ envFlag: PLUGIN_PREVIEW_FLAG,
39
+ count: entries.length,
40
+ plugins: entries.map((e) => ({
41
+ manifestPath: e.manifestPath,
42
+ ok: e.manifest !== null,
43
+ ...(e.manifest
44
+ ? {
45
+ name: e.manifest.name,
46
+ kind: e.manifest.kind,
47
+ module: e.manifest.module,
48
+ ...(e.manifest.kind === 'analyzer'
49
+ ? { category: e.manifest.category }
50
+ : { commands: e.manifest.commands }),
51
+ description: e.manifest.description,
52
+ }
53
+ : { error: e.error, diagnostic: e.diagnostic }),
54
+ })),
55
+ };
56
+ }
57
+ case 'validate': {
58
+ const p = typeof args.manifest_path === 'string' ? args.manifest_path : '';
59
+ if (!p)
60
+ throw new Error('validate action requires a "manifest_path" argument');
61
+ const manifestPath = path.isAbsolute(p) ? p : path.resolve(rootPath, p);
62
+ const result = await readPluginManifestFile(manifestPath);
63
+ return result.ok
64
+ ? { ok: true, manifest: result.manifest }
65
+ : { ok: false, error: result.reason, diagnostic: result.diagnostic };
66
+ }
67
+ default:
68
+ throw new Error(`Unknown action "${action}". Known: list, validate.`);
69
+ }
70
+ },
71
+ };
72
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/mcp/tools/plugin.ts"],"names":[],"mappings":"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"}
package/dist/mcp/tools.js CHANGED
@@ -35,6 +35,7 @@ import { applyFixTool } from './tools/applyFix.js';
35
35
  import { taintTool } from './tools/taint.js';
36
36
  import { costSummaryTool } from './tools/costSummary.js';
37
37
  import { reviewWatchTool } from './tools/reviewWatch.js';
38
+ import { pluginTool } from './tools/plugin.js';
38
39
  const tools = [
39
40
  analyzeTool,
40
41
  doctorTool,
@@ -63,6 +64,7 @@ const tools = [
63
64
  taintTool,
64
65
  costSummaryTool,
65
66
  reviewWatchTool,
67
+ pluginTool,
66
68
  ];
67
69
  export function getToolDefinitions() {
68
70
  return tools.map(({ name, description, inputSchema }) => ({ name, description, inputSchema }));
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAMzD,MAAM,KAAK,GAAc;IACvB,WAAW;IACX,UAAU;IACV,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,aAAa;IACb,gBAAgB;IAChB,YAAY;IACZ,SAAS;IACT,WAAW;IACX,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,cAAc;IACd,UAAU;IACV,UAAU;IACV,cAAc;IACd,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,WAAW;IACX,UAAU;IACV,kBAAkB;IAClB,YAAY;IACZ,SAAS;IACT,eAAe;IACf,eAAe;CAChB,CAAC;AAEF,MAAM,UAAU,kBAAkB;IAChC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,OAAO,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM/C,MAAM,KAAK,GAAc;IACvB,WAAW;IACX,UAAU;IACV,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,aAAa;IACb,gBAAgB;IAChB,YAAY;IACZ,SAAS;IACT,WAAW;IACX,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,cAAc;IACd,UAAU;IACV,UAAU;IACV,cAAc;IACd,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,WAAW;IACX,UAAU;IACV,kBAAkB;IAClB,YAAY;IACZ,SAAS;IACT,eAAe;IACf,eAAe;IACf,UAAU;CACX,CAAC;AAEF,MAAM,UAAU,kBAAkB;IAChC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,OAAO,CAAC;AACrD,CAAC"}
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "projscan",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "mcpProtocolVersion": "2025-03-26",
5
- "generatedAt": "2026-05-12T21:05:38.638Z",
6
- "toolCount": 27,
5
+ "generatedAt": "2026-05-18T09:59:21.665Z",
6
+ "toolCount": 28,
7
7
  "tools": [
8
8
  {
9
9
  "name": "projscan_analyze",
@@ -649,13 +649,31 @@
649
649
  },
650
650
  {
651
651
  "name": "projscan_cost_summary",
652
- "description": "Aggregate token-cost analytics from the current session's tool-call history. Returns total tokens spent, top spenders, per-tool typical/p95 estimates, and a static expected-cost catalog so the agent can budget pre-call. Pairs with the `_cost` sidecar attached to every tool result. Read-only. Note: the session event log is bounded at 500 entries, so the view reflects recent activity rather than the full lifetime of the session — for long-running sessions, older calls are dropped.",
652
+ "description": "Aggregate token-cost analytics from the current session's tool-call history. action:\"snapshot\" (default) returns total tokens spent, top spenders, per-tool typical/p95 estimates, and a static expected-cost catalog so the agent can budget pre-call. 1.10+: action:\"start_stream\" / \"stop_stream\" / \"list_streams\" turns this into a live cost dashboard — the server polls the session log on an interval and emits notifications/projscan/cost_delta whenever new tool calls have accrued, with the per-tool deltas and the new cumulative totals inline. Pairs with the `_cost` sidecar attached to every tool result. Read-only. Note: the session event log is bounded at 500 entries — for long-running sessions, older calls are dropped from the snapshot.",
653
653
  "inputSchema": {
654
654
  "type": "object",
655
655
  "properties": {
656
+ "action": {
657
+ "type": "string",
658
+ "enum": [
659
+ "snapshot",
660
+ "start_stream",
661
+ "stop_stream",
662
+ "list_streams"
663
+ ],
664
+ "description": "\"snapshot\" (default) returns the current aggregate. \"start_stream\" begins a live cost-delta watch. \"stop_stream\" cancels by stream_id. \"list_streams\" enumerates active streams."
665
+ },
656
666
  "top": {
657
667
  "type": "number",
658
- "description": "Optional. Number of top spenders to return. Default: 10."
668
+ "description": "Optional. Number of top spenders to return. Default: 10. (snapshot + start_stream)"
669
+ },
670
+ "interval_seconds": {
671
+ "type": "number",
672
+ "description": "Stream poll interval in seconds. Default: 10. Min: 2, max: 600. (start_stream only)"
673
+ },
674
+ "stream_id": {
675
+ "type": "string",
676
+ "description": "Stream identifier returned by a previous start_stream. (stop_stream only)"
659
677
  }
660
678
  }
661
679
  }
@@ -693,6 +711,27 @@
693
711
  }
694
712
  }
695
713
  }
714
+ },
715
+ {
716
+ "name": "projscan_plugin",
717
+ "description": "1.10+ preview. Discover and validate third-party analyzer and reporter plugins under .projscan-plugins/. Gated by the PROJSCAN_PLUGINS_PREVIEW=1 env flag; the schema is preview-only and may shift before 2.0. Use action:\"list\" to see what is discoverable today, action:\"validate\" to check a manifest before committing it.",
718
+ "inputSchema": {
719
+ "type": "object",
720
+ "properties": {
721
+ "action": {
722
+ "type": "string",
723
+ "enum": [
724
+ "list",
725
+ "validate"
726
+ ],
727
+ "description": "\"list\" enumerates manifests under <root>/.projscan-plugins/ with discovery status. \"validate\" lints a manifest at the given path against the 1.10 schema."
728
+ },
729
+ "manifest_path": {
730
+ "type": "string",
731
+ "description": "\"validate\" only — repo-relative or absolute path to a *.projscan-plugin.json file."
732
+ }
733
+ }
734
+ }
696
735
  }
697
736
  ]
698
737
  }
@@ -33,6 +33,21 @@ export async function getChangedFiles(rootPath, explicitBaseRef) {
33
33
  return { available: true, baseRef: ref, files };
34
34
  }
35
35
  catch (err) {
36
+ // 1.10+ — surface stdio-too-large explicitly instead of letting it
37
+ // fall through to the generic "no usable base ref" path. The ref
38
+ // exists; the diff against it is just too big to fit in our 10MB
39
+ // buffer (typical when HEAD has diverged from the base by 100K+
40
+ // files). The user needs a closer base ref or a streaming reader,
41
+ // not a missing-ref diagnosis.
42
+ if (isMaxBufferError(err)) {
43
+ return {
44
+ available: false,
45
+ reason: `git diff against "${ref}" exceeded the 10MB output buffer ` +
46
+ '(typically > 100K files changed). Use --base-ref to pin a closer ref.',
47
+ baseRef: null,
48
+ files: [],
49
+ };
50
+ }
36
51
  lastError = err instanceof Error ? err.message : String(err);
37
52
  }
38
53
  }
@@ -110,4 +125,14 @@ async function statusNames(rootPath) {
110
125
  function normalizePath(p) {
111
126
  return p.split(path.sep).join('/');
112
127
  }
128
+ function isMaxBufferError(err) {
129
+ if (!err || typeof err !== 'object')
130
+ return false;
131
+ const e = err;
132
+ if (e.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER')
133
+ return true;
134
+ if (typeof e.message === 'string' && /maxBuffer length exceeded/i.test(e.message))
135
+ return true;
136
+ return false;
137
+ }
113
138
  //# sourceMappingURL=changedFiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"changedFiles.js","sourceRoot":"","sources":["../../src/utils/changedFiles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"changedFiles.js","sourceRoot":"","sources":["../../src/utils/changedFiles.ts"],"names":[],"mappings":"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"}