claude-crap 0.3.0 → 0.3.1
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 +13 -0
- package/dist/scanner/auto-scan.d.ts.map +1 -1
- package/dist/scanner/auto-scan.js +12 -0
- package/dist/scanner/auto-scan.js.map +1 -1
- package/dist/scanner/bootstrap.d.ts +1 -1
- package/dist/scanner/bootstrap.d.ts.map +1 -1
- package/dist/scanner/bootstrap.js +52 -4
- package/dist/scanner/bootstrap.js.map +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/bundle/mcp-server.mjs +172 -116
- package/plugin/bundle/mcp-server.mjs.map +4 -4
- package/plugin/package.json +1 -1
- package/src/scanner/auto-scan.ts +15 -0
- package/src/scanner/bootstrap.ts +56 -4
package/plugin/package.json
CHANGED
package/src/scanner/auto-scan.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import type { Logger } from "pino";
|
|
23
23
|
import { detectScanners, type ScannerDetection } from "./detector.js";
|
|
24
24
|
import { runScanner, type ScannerRunResult } from "./runner.js";
|
|
25
|
+
import { bootstrapScanner } from "./bootstrap.js";
|
|
25
26
|
import { adaptScannerOutput, type KnownScanner } from "../adapters/index.js";
|
|
26
27
|
import type { SarifStore } from "../sarif/sarif-store.js";
|
|
27
28
|
|
|
@@ -106,6 +107,20 @@ export async function autoScan(
|
|
|
106
107
|
);
|
|
107
108
|
|
|
108
109
|
if (available.length === 0) {
|
|
110
|
+
// No scanners configured — try to bootstrap one automatically.
|
|
111
|
+
logger.info("auto-scan: no scanners found, attempting bootstrap");
|
|
112
|
+
try {
|
|
113
|
+
const bootstrapResult = await bootstrapScanner(workspaceRoot, sarifStore, logger);
|
|
114
|
+
if (bootstrapResult.autoScanResult) {
|
|
115
|
+
return bootstrapResult.autoScanResult;
|
|
116
|
+
}
|
|
117
|
+
} catch (err) {
|
|
118
|
+
logger.warn(
|
|
119
|
+
{ err: (err as Error).message },
|
|
120
|
+
"auto-scan: bootstrap failed — continuing with empty results",
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
return {
|
|
110
125
|
detected,
|
|
111
126
|
results: [],
|
package/src/scanner/bootstrap.ts
CHANGED
|
@@ -27,8 +27,10 @@ import { join } from "node:path";
|
|
|
27
27
|
import { execFile } from "node:child_process";
|
|
28
28
|
import type { Logger } from "pino";
|
|
29
29
|
import type { KnownScanner } from "../adapters/common.js";
|
|
30
|
+
import { adaptScannerOutput } from "../adapters/index.js";
|
|
30
31
|
import { detectScanners } from "./detector.js";
|
|
31
|
-
import {
|
|
32
|
+
import { runScanner } from "./runner.js";
|
|
33
|
+
import type { AutoScanResult, ScannerResult } from "./auto-scan.js";
|
|
32
34
|
import type { SarifStore } from "../sarif/sarif-store.js";
|
|
33
35
|
|
|
34
36
|
// ── Types ──────────────────────────────────────────────────────────
|
|
@@ -341,17 +343,67 @@ export async function bootstrapScanner(
|
|
|
341
343
|
});
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
// 4. Run
|
|
346
|
+
// 4. Run scanner directly if installation succeeded (inline scan
|
|
347
|
+
// to avoid circular dependency — autoScan calls bootstrapScanner)
|
|
345
348
|
const installSucceeded = steps.every((s) => s.success);
|
|
346
349
|
let autoScanResult: AutoScanResult | null = null;
|
|
347
350
|
|
|
348
351
|
if (installSucceeded && recommendation.canAutoInstall) {
|
|
349
352
|
try {
|
|
350
|
-
|
|
353
|
+
const scanStart = Date.now();
|
|
354
|
+
const postDetections = await detectScanners(workspaceRoot);
|
|
355
|
+
const postAvailable = postDetections.filter((d) => d.available);
|
|
356
|
+
const scanResults: ScannerResult[] = [];
|
|
357
|
+
let scanFindings = 0;
|
|
358
|
+
|
|
359
|
+
const settled = await Promise.allSettled(
|
|
360
|
+
postAvailable.map((d) => runScanner(d.scanner, workspaceRoot)),
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
for (let i = 0; i < postAvailable.length; i++) {
|
|
364
|
+
const det = postAvailable[i]!;
|
|
365
|
+
const res = settled[i]!;
|
|
366
|
+
|
|
367
|
+
if (res.status === "rejected" || !res.value.success) {
|
|
368
|
+
scanResults.push({
|
|
369
|
+
scanner: det.scanner,
|
|
370
|
+
success: false,
|
|
371
|
+
findingsIngested: 0,
|
|
372
|
+
durationMs: res.status === "fulfilled" ? res.value.durationMs : 0,
|
|
373
|
+
error: res.status === "rejected"
|
|
374
|
+
? String(res.reason)
|
|
375
|
+
: res.value.error ?? "unknown error",
|
|
376
|
+
});
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const runResult = res.value;
|
|
381
|
+
let parsed: unknown;
|
|
382
|
+
try { parsed = JSON.parse(runResult.rawOutput); } catch { parsed = runResult.rawOutput; }
|
|
383
|
+
const adapted = adaptScannerOutput(runResult.scanner, parsed);
|
|
384
|
+
const stats = sarifStore.ingestRun(adapted.document, adapted.sourceTool);
|
|
385
|
+
scanFindings += stats.accepted;
|
|
386
|
+
|
|
387
|
+
scanResults.push({
|
|
388
|
+
scanner: runResult.scanner,
|
|
389
|
+
success: true,
|
|
390
|
+
findingsIngested: stats.accepted,
|
|
391
|
+
durationMs: runResult.durationMs,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (scanFindings > 0) await sarifStore.persist();
|
|
396
|
+
|
|
397
|
+
autoScanResult = {
|
|
398
|
+
detected: postDetections,
|
|
399
|
+
results: scanResults,
|
|
400
|
+
totalFindings: scanFindings,
|
|
401
|
+
totalDurationMs: Date.now() - scanStart,
|
|
402
|
+
};
|
|
351
403
|
} catch (err) {
|
|
352
404
|
logger.warn(
|
|
353
405
|
{ err: (err as Error).message },
|
|
354
|
-
"bootstrap:
|
|
406
|
+
"bootstrap: scan after install failed",
|
|
355
407
|
);
|
|
356
408
|
}
|
|
357
409
|
}
|