opencode-swarm 7.138.0 → 7.138.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/dist/background/candidate-contract.d.ts +31 -0
- package/dist/background/pending-delegations.d.ts +7 -0
- package/dist/cli/{config-doctor-mb81xytp.js → config-doctor-hzb0bck9.js} +2 -2
- package/dist/cli/{curation-policy-qx23sc8b.js → curation-policy-aj37yvz8.js} +2 -2
- package/dist/cli/{curator-b9ascpbh.js → curator-jt6dza8y.js} +15 -15
- package/dist/cli/{curator-llm-factory-r47q1hbd.js → curator-llm-factory-m9f4h8t4.js} +15 -15
- package/dist/cli/{evidence-summary-service-1azhyeft.js → evidence-summary-service-6cttrkzw.js} +2 -2
- package/dist/cli/{guardrail-explain-ph1n3ryc.js → guardrail-explain-rks41rpx.js} +16 -16
- package/dist/cli/{guardrail-log-ghgqaw3w.js → guardrail-log-h39jxftx.js} +3 -3
- package/dist/cli/{hive-promoter-7x2zzhb7.js → hive-promoter-34y2x4vt.js} +15 -15
- package/dist/cli/{index-7wzyf4dr.js → index-49ygvqvm.js} +4 -4
- package/dist/cli/{index-sp7s1vk3.js → index-89dwrz8n.js} +712 -233
- package/dist/cli/{index-2vzgvscz.js → index-8emf08eb.js} +3 -3
- package/dist/cli/{index-9zf5gfca.js → index-bakfqtye.js} +1 -1
- package/dist/cli/{index-z55s5719.js → index-d01d4102.js} +2 -2
- package/dist/cli/{index-ca6qmxd8.js → index-da98750t.js} +1 -1
- package/dist/cli/{index-6nenabrm.js → index-exq36v6w.js} +1 -1
- package/dist/cli/{index-k5jrywpr.js → index-gprxjmm7.js} +6 -1
- package/dist/cli/{index-bf0j2wd2.js → index-gpxg7wx8.js} +2 -2
- package/dist/cli/{index-npgjk6vc.js → index-k6cq9wwh.js} +1 -1
- package/dist/cli/{index-0s4gr6qh.js → index-q344kj84.js} +2 -1
- package/dist/cli/{index-4xs9e82s.js → index-qg5smxv9.js} +3 -3
- package/dist/cli/{index-xz0zjrdr.js → index-qt3jjjw9.js} +1 -1
- package/dist/cli/{index-cdx3aqj5.js → index-r9pn41rj.js} +1 -1
- package/dist/cli/{index-ag7ppc40.js → index-s7ac0xrf.js} +17 -17
- package/dist/cli/{index-hmapndcz.js → index-xm07cqy2.js} +5 -5
- package/dist/cli/{index-fmh15wxb.js → index-y06a43sk.js} +1 -1
- package/dist/cli/{index-whf5ecbw.js → index-yxswbd1t.js} +1 -1
- package/dist/cli/{index-7kgfvt3h.js → index-ze4we97d.js} +1 -1
- package/dist/cli/index.js +15 -15
- package/dist/cli/{knowledge-escalator-pqskjp6y.js → knowledge-escalator-qmpfh5yz.js} +3 -3
- package/dist/cli/{knowledge-events-ahpxnqjd.js → knowledge-events-7neg8x0p.js} +1 -1
- package/dist/cli/{knowledge-store-27aynbeg.js → knowledge-store-a6d4625r.js} +1 -1
- package/dist/cli/{knowledge-validator-4saz53kh.js → knowledge-validator-q1qrdyvx.js} +4 -4
- package/dist/cli/{pending-delegations-ztb67amh.js → pending-delegations-7dbc0j2a.js} +1 -1
- package/dist/cli/{scan-cursor-ngykkd7f.js → scan-cursor-3tqshkb2.js} +2 -2
- package/dist/cli/{schema-p82ntfy9.js → schema-mtyaeh18.js} +1 -1
- package/dist/cli/{skill-generator-r19a1zje.js → skill-generator-t3m5qajm.js} +5 -5
- package/dist/cli/{worktree-collision-ownership-rc6pe17g.js → worktree-collision-ownership-hjrt5hx2.js} +1 -1
- package/dist/config/evidence-schema.d.ts +15 -0
- package/dist/hooks/pr-workflow-gate.d.ts +41 -1
- package/dist/index.js +41 -28
- package/dist/services/preflight-service.d.ts +2 -0
- package/dist/tools/dispatch-lanes.d.ts +7 -0
- package/dist/tools/pre-check-batch.d.ts +2 -0
- package/dist/tools/secretscan.d.ts +17 -0
- package/package.json +1 -1
|
@@ -16,13 +16,13 @@ import {
|
|
|
16
16
|
} from "./index-rrxcfxrd.js";
|
|
17
17
|
import {
|
|
18
18
|
stableCanonicalStringify
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-qt3jjjw9.js";
|
|
20
20
|
import {
|
|
21
21
|
detectStraySwarmDirs,
|
|
22
22
|
readDoctorArtifact,
|
|
23
23
|
removeStraySwarmDir,
|
|
24
24
|
runConfigDoctor
|
|
25
|
-
} from "./index-
|
|
25
|
+
} from "./index-da98750t.js";
|
|
26
26
|
import {
|
|
27
27
|
MAX_TRANSIENT_RETRIES,
|
|
28
28
|
archiveEvidence,
|
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
savePlan,
|
|
60
60
|
transientBackoff,
|
|
61
61
|
validateProjectRoot
|
|
62
|
-
} from "./index-
|
|
62
|
+
} from "./index-y06a43sk.js";
|
|
63
63
|
import {
|
|
64
64
|
EvaluationTaskV1Schema,
|
|
65
65
|
GateAuditManifestV1Schema,
|
|
@@ -114,15 +114,15 @@ import {
|
|
|
114
114
|
retireSkill,
|
|
115
115
|
selectCandidateEntries,
|
|
116
116
|
syncBundledProjectSkillsIfMissingAsync
|
|
117
|
-
} from "./index-
|
|
117
|
+
} from "./index-qg5smxv9.js";
|
|
118
118
|
import {
|
|
119
119
|
readRecentEscalations
|
|
120
|
-
} from "./index-
|
|
120
|
+
} from "./index-xm07cqy2.js";
|
|
121
121
|
import {
|
|
122
122
|
alreadyCuratedThisGeneration,
|
|
123
123
|
claimNextScanBatch,
|
|
124
124
|
resolveCohortId
|
|
125
|
-
} from "./index-
|
|
125
|
+
} from "./index-yxswbd1t.js";
|
|
126
126
|
import {
|
|
127
127
|
CURATOR_INIT_PROMPT,
|
|
128
128
|
CURATOR_PHASE_PROMPT,
|
|
@@ -175,11 +175,11 @@ import {
|
|
|
175
175
|
validateActionableFields,
|
|
176
176
|
validateLesson,
|
|
177
177
|
validateSkillPath
|
|
178
|
-
} from "./index-
|
|
178
|
+
} from "./index-d01d4102.js";
|
|
179
179
|
import {
|
|
180
180
|
authorizeCuration,
|
|
181
181
|
buildConfigFingerprintInput
|
|
182
|
-
} from "./index-
|
|
182
|
+
} from "./index-ze4we97d.js";
|
|
183
183
|
import {
|
|
184
184
|
cohortConfigFingerprint
|
|
185
185
|
} from "./index-rtry5xyf.js";
|
|
@@ -212,7 +212,7 @@ import {
|
|
|
212
212
|
transactFile,
|
|
213
213
|
transactKnowledge,
|
|
214
214
|
wordBigrams
|
|
215
|
-
} from "./index-
|
|
215
|
+
} from "./index-49ygvqvm.js";
|
|
216
216
|
import {
|
|
217
217
|
MAX_EVENT_LOG_ENTRIES,
|
|
218
218
|
_internals,
|
|
@@ -222,7 +222,7 @@ import {
|
|
|
222
222
|
recordHiveKnowledgeEvent,
|
|
223
223
|
recordKnowledgeEvent,
|
|
224
224
|
resolveKnowledgeEventsPath
|
|
225
|
-
} from "./index-
|
|
225
|
+
} from "./index-r9pn41rj.js";
|
|
226
226
|
import {
|
|
227
227
|
resolveHiveDataDir,
|
|
228
228
|
resolveHiveEventsPath,
|
|
@@ -247,10 +247,10 @@ import {
|
|
|
247
247
|
init_loader,
|
|
248
248
|
loadPluginConfig,
|
|
249
249
|
loadPluginConfigWithMeta
|
|
250
|
-
} from "./index-
|
|
250
|
+
} from "./index-k6cq9wwh.js";
|
|
251
251
|
import {
|
|
252
252
|
RetrospectiveEvidenceSchema
|
|
253
|
-
} from "./index-
|
|
253
|
+
} from "./index-gprxjmm7.js";
|
|
254
254
|
import {
|
|
255
255
|
DEFAULT_SKILL_OPT_CONFIG,
|
|
256
256
|
FALLBACK_MODELS_MAX,
|
|
@@ -263,7 +263,7 @@ import {
|
|
|
263
263
|
package_default,
|
|
264
264
|
resolveAutoReviewConfig,
|
|
265
265
|
stripKnownSwarmPrefix
|
|
266
|
-
} from "./index-
|
|
266
|
+
} from "./index-exq36v6w.js";
|
|
267
267
|
import {
|
|
268
268
|
KNOWLEDGE_SCHEMA_VERSION,
|
|
269
269
|
OUTCOME_BLOCK_THRESHOLD,
|
|
@@ -320,7 +320,7 @@ import {
|
|
|
320
320
|
import {
|
|
321
321
|
findByBatchId,
|
|
322
322
|
readDelegations
|
|
323
|
-
} from "./index-
|
|
323
|
+
} from "./index-q344kj84.js";
|
|
324
324
|
import {
|
|
325
325
|
readSwarmFileAsync,
|
|
326
326
|
safeHook,
|
|
@@ -477,6 +477,52 @@ function removeCandidateCodeFences(text) {
|
|
|
477
477
|
return lines.join(`
|
|
478
478
|
`);
|
|
479
479
|
}
|
|
480
|
+
function declaredCanonicalFamilies(source) {
|
|
481
|
+
const families = [];
|
|
482
|
+
for (const line of source.split(/\r?\n/)) {
|
|
483
|
+
const family = candidateHeaderFamily(splitPipeFields(line).map((field) => field.trim()));
|
|
484
|
+
if (family && !families.includes(family))
|
|
485
|
+
families.push(family);
|
|
486
|
+
}
|
|
487
|
+
return families;
|
|
488
|
+
}
|
|
489
|
+
function normalizeCandidateArtifact(rawText, fallbackFamily) {
|
|
490
|
+
const text = removeCandidateCodeFences(rawText);
|
|
491
|
+
const header = selectCandidateHeader(text.split(/\r?\n/));
|
|
492
|
+
if (header?.markerBearing && header.family !== null) {
|
|
493
|
+
return { text, synthesizedHeader: false };
|
|
494
|
+
}
|
|
495
|
+
if (declaredCanonicalFamilies(text).length > 0) {
|
|
496
|
+
return { text, synthesizedHeader: false };
|
|
497
|
+
}
|
|
498
|
+
if (declaredCanonicalFamilies(rawText).some((family) => family !== fallbackFamily)) {
|
|
499
|
+
return { text, synthesizedHeader: false };
|
|
500
|
+
}
|
|
501
|
+
const lines = text.split(/\r?\n/);
|
|
502
|
+
const hasSalvageableRow = lines.some((line) => {
|
|
503
|
+
if (analyzeCandidateLine(line, fallbackFamily)?.valid === true)
|
|
504
|
+
return true;
|
|
505
|
+
const fields = splitPipeFields(line).map((field) => field.trim());
|
|
506
|
+
if (fields[0] !== CLEAN_MARKER)
|
|
507
|
+
return false;
|
|
508
|
+
return analyzeCleanFields(fields, fallbackFamily).valid;
|
|
509
|
+
});
|
|
510
|
+
if (!hasSalvageableRow)
|
|
511
|
+
return { text, synthesizedHeader: false };
|
|
512
|
+
const firstSalvageableIndex = lines.findIndex((line) => {
|
|
513
|
+
const marker = splitPipeFields(line)[0]?.trim();
|
|
514
|
+
return marker === CANDIDATE_MARKER || marker === CLEAN_MARKER;
|
|
515
|
+
});
|
|
516
|
+
return {
|
|
517
|
+
text: [
|
|
518
|
+
...lines.slice(0, firstSalvageableIndex),
|
|
519
|
+
CANDIDATE_HEADERS[fallbackFamily],
|
|
520
|
+
...lines.slice(firstSalvageableIndex)
|
|
521
|
+
].join(`
|
|
522
|
+
`),
|
|
523
|
+
synthesizedHeader: true
|
|
524
|
+
};
|
|
525
|
+
}
|
|
480
526
|
function analyzeCandidateLaneContext(context) {
|
|
481
527
|
const issues = [];
|
|
482
528
|
const baseBound = Boolean(context.expected_lane || context.expected_lanes);
|
|
@@ -687,6 +733,12 @@ function analyzeCleanFields(fields, family, expectedLane) {
|
|
|
687
733
|
evidence
|
|
688
734
|
};
|
|
689
735
|
}
|
|
736
|
+
function analyzeCandidateLine(line, family) {
|
|
737
|
+
const fields = splitPipeFields(line).map((field) => field.trim());
|
|
738
|
+
if (fields[0] !== "[CANDIDATE]")
|
|
739
|
+
return null;
|
|
740
|
+
return analyzeCandidateFields(fields.slice(1), family);
|
|
741
|
+
}
|
|
690
742
|
|
|
691
743
|
// src/background/candidate-parser.ts
|
|
692
744
|
init_zod();
|
|
@@ -1276,7 +1328,7 @@ ${trimmed}`;
|
|
|
1276
1328
|
if (cleanAttestation) {
|
|
1277
1329
|
formatFamiliesDetected.add(cleanAttestation.row_format_family);
|
|
1278
1330
|
}
|
|
1279
|
-
const acceptedCandidates =
|
|
1331
|
+
const acceptedCandidates = candidates;
|
|
1280
1332
|
const parseErrors = parseErrorDetails.length;
|
|
1281
1333
|
const envelope = buildInvocationEnvelope(input, flags, Array.from(formatFamiliesDetected), acceptedCandidates.length, parseErrors, malformedRows, cleanAttestation ? 1 : 0);
|
|
1282
1334
|
const diagnostics = {
|
|
@@ -2811,6 +2863,9 @@ var _test_exports = {
|
|
|
2811
2863
|
minimumConsolidatedLaneCover,
|
|
2812
2864
|
analyzePrReviewBatchRecordIntegrity,
|
|
2813
2865
|
MAX_COVER_UNIVERSE_BITS,
|
|
2866
|
+
extractCandidateIds,
|
|
2867
|
+
parseCanonicalCandidateRows,
|
|
2868
|
+
resolvePrReviewRowFamily,
|
|
2814
2869
|
workflowGateStateRelativePath,
|
|
2815
2870
|
workflowGateStateLockRelativePath,
|
|
2816
2871
|
workflowCheckoutMutationLockRelativePath,
|
|
@@ -3138,13 +3193,13 @@ function derivePrReviewCandidateInventory(directory, state, ctx) {
|
|
|
3138
3193
|
const recordOwnedLanes = record.ownedWorkflowLanes?.length ? record.ownedWorkflowLanes : record.workflowLane ? [record.workflowLane] : undefined;
|
|
3139
3194
|
if (!artifact || !workflowArtifactHasContractMarker(directory, state, record, source.mode, record.workflowLane ?? source.workflowLane ?? source.laneId, undefined, ctx.revisionDigest, recordOwnedLanes))
|
|
3140
3195
|
continue;
|
|
3141
|
-
if (source.workflowLane && (!recordOwnedLanes?.includes(source.workflowLane) || !prReviewDiscoveryArtifactCoversLane(artifact.text, source.workflowLane, recordOwnedLanes)))
|
|
3196
|
+
if (source.workflowLane && (!recordOwnedLanes?.includes(source.workflowLane) || !prReviewDiscoveryArtifactCoversLane(artifact.text, source.workflowLane, recordOwnedLanes, source.mode)))
|
|
3142
3197
|
continue;
|
|
3143
3198
|
resolvedArtifact = true;
|
|
3144
3199
|
const laneKey = `${source.batchId}\x00${source.laneId}`;
|
|
3145
3200
|
if (!extractedLaneKeys.has(laneKey)) {
|
|
3146
3201
|
extractedLaneKeys.add(laneKey);
|
|
3147
|
-
candidateIds.push(...extractCandidateIds(artifact.text, source.mode
|
|
3202
|
+
candidateIds.push(...extractCandidateIds(artifact.text, resolvePrReviewRowFamily(source.workflowLane, source.mode), source.creditedLanes));
|
|
3148
3203
|
}
|
|
3149
3204
|
}
|
|
3150
3205
|
if (source.mode === "swarm-pr-review:micro" && !resolvedArtifact) {
|
|
@@ -3164,11 +3219,19 @@ function appendBoundedCandidateIssue(issues, message) {
|
|
|
3164
3219
|
issues.push("additional malformed candidate diagnostics omitted");
|
|
3165
3220
|
}
|
|
3166
3221
|
}
|
|
3222
|
+
function resolvePrReviewRowFamily(workflowLane, mode) {
|
|
3223
|
+
if (mode === "swarm-pr-review:base")
|
|
3224
|
+
return "base_explorer";
|
|
3225
|
+
if (mode === "swarm-pr-review:micro" || mode === "swarm-pr-review:council") {
|
|
3226
|
+
return "micro_lane";
|
|
3227
|
+
}
|
|
3228
|
+
return workflowLane !== undefined && PR_REVIEW_BASE_DIMENSION_IDS.includes(workflowLane) ? "base_explorer" : "micro_lane";
|
|
3229
|
+
}
|
|
3167
3230
|
function parseCanonicalCandidateRows(text, fallbackFamily) {
|
|
3168
3231
|
const rows = [];
|
|
3169
3232
|
const issues = [];
|
|
3170
3233
|
let headerFamily = null;
|
|
3171
|
-
for (const [index, line] of
|
|
3234
|
+
for (const [index, line] of normalizeCandidateArtifact(text, fallbackFamily).text.split(/\r?\n/).entries()) {
|
|
3172
3235
|
const fields = splitPipeFields(line).map((field) => field.trim());
|
|
3173
3236
|
const detectedHeaderFamily = candidateHeaderFamily(fields);
|
|
3174
3237
|
if (detectedHeaderFamily) {
|
|
@@ -3699,7 +3762,7 @@ function workflowArtifactHasContractMarker(directory, state, record, expectedMod
|
|
|
3699
3762
|
const coveredLanes = ownedWorkflowLanes?.length ? ownedWorkflowLanes : [expectedWorkflowLane];
|
|
3700
3763
|
const coverageAnalyses = coveredLanes.map((coveredLane) => ({
|
|
3701
3764
|
coveredLane,
|
|
3702
|
-
analysis: analyzePrReviewDiscoveryArtifact(artifact.text, coveredLane, coveredLanes)
|
|
3765
|
+
analysis: analyzePrReviewDiscoveryArtifact(artifact.text, coveredLane, coveredLanes, expectedMode)
|
|
3703
3766
|
}));
|
|
3704
3767
|
if (coverageAnalyses.some(({ analysis }) => !analysis.covered)) {
|
|
3705
3768
|
for (const { coveredLane, analysis } of coverageAnalyses) {
|
|
@@ -3715,7 +3778,7 @@ function workflowArtifactHasContractMarker(directory, state, record, expectedMod
|
|
|
3715
3778
|
if (coveredLanes.length > 1) {
|
|
3716
3779
|
const seenEvidence = new Map;
|
|
3717
3780
|
for (const coveredLane of coveredLanes) {
|
|
3718
|
-
const evidence2 = extractLaneCoverageEvidenceText(artifact.text, coveredLane, coveredLanes);
|
|
3781
|
+
const evidence2 = extractLaneCoverageEvidenceText(artifact.text, coveredLane, coveredLanes, expectedMode);
|
|
3719
3782
|
if (evidence2 === null)
|
|
3720
3783
|
continue;
|
|
3721
3784
|
const priorLane = seenEvidence.get(evidence2);
|
|
@@ -3726,10 +3789,12 @@ function workflowArtifactHasContractMarker(directory, state, record, expectedMod
|
|
|
3726
3789
|
}
|
|
3727
3790
|
return true;
|
|
3728
3791
|
}
|
|
3729
|
-
function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane]) {
|
|
3730
|
-
const fallbackFamily =
|
|
3792
|
+
function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane], mode) {
|
|
3793
|
+
const fallbackFamily = resolvePrReviewRowFamily(expectedWorkflowLane, mode);
|
|
3731
3794
|
const issues = [];
|
|
3732
|
-
const
|
|
3795
|
+
const normalized = normalizeCandidateArtifact(text, fallbackFamily);
|
|
3796
|
+
const canonicalText = normalized.text;
|
|
3797
|
+
const salvaged = normalized.synthesizedHeader;
|
|
3733
3798
|
const header = selectCandidateHeader(canonicalText.split(/\r?\n/));
|
|
3734
3799
|
if (header === null || !header.markerBearing || header.family !== fallbackFamily) {
|
|
3735
3800
|
appendBoundedCandidateIssue(issues, `field header: expected one exact canonical ${fallbackFamily} [CANDIDATE] header before discovery rows`);
|
|
@@ -3737,6 +3802,7 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3737
3802
|
covered: false,
|
|
3738
3803
|
evidence: null,
|
|
3739
3804
|
issues,
|
|
3805
|
+
salvaged,
|
|
3740
3806
|
failurePredicate: "discovery.header"
|
|
3741
3807
|
};
|
|
3742
3808
|
}
|
|
@@ -3771,11 +3837,15 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3771
3837
|
for (const detail of parsed.diagnostics.parse_error_details) {
|
|
3772
3838
|
appendBoundedCandidateIssue(issues, `row ${detail.row_index + 1} field ${detail.field}: ${detail.message}`);
|
|
3773
3839
|
}
|
|
3774
|
-
|
|
3840
|
+
const hasParseFailure = Boolean(parsed.error) || parsed.diagnostics.parse_error_details.length > 0;
|
|
3841
|
+
const extractedCandidateIds = parseCanonicalCandidateRows(canonicalText, fallbackFamily).rows.map((row) => row.candidateId);
|
|
3842
|
+
const hasDuplicateCandidateId = new Set(extractedCandidateIds).size !== extractedCandidateIds.length;
|
|
3843
|
+
if (hasDuplicateCandidateId) {
|
|
3775
3844
|
return {
|
|
3776
3845
|
covered: false,
|
|
3777
3846
|
evidence: null,
|
|
3778
3847
|
issues,
|
|
3848
|
+
salvaged,
|
|
3779
3849
|
failurePredicate: "discovery.row"
|
|
3780
3850
|
};
|
|
3781
3851
|
}
|
|
@@ -3792,7 +3862,8 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3792
3862
|
matchingCandidate.impact_context ?? matchingCandidate.invariant_violated,
|
|
3793
3863
|
matchingCandidate.confidence
|
|
3794
3864
|
].join("\x00"),
|
|
3795
|
-
issues
|
|
3865
|
+
issues,
|
|
3866
|
+
salvaged
|
|
3796
3867
|
};
|
|
3797
3868
|
}
|
|
3798
3869
|
const clean = parsed.clean_attestation;
|
|
@@ -3800,14 +3871,16 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3800
3871
|
return {
|
|
3801
3872
|
covered: true,
|
|
3802
3873
|
evidence: `${clean.coverage_scope}\x00${clean.evidence}`,
|
|
3803
|
-
issues
|
|
3874
|
+
issues,
|
|
3875
|
+
salvaged
|
|
3804
3876
|
};
|
|
3805
3877
|
}
|
|
3806
3878
|
return {
|
|
3807
3879
|
covered: false,
|
|
3808
3880
|
evidence: null,
|
|
3809
3881
|
issues,
|
|
3810
|
-
|
|
3882
|
+
salvaged,
|
|
3883
|
+
failurePredicate: hasParseFailure ? "discovery.row" : "discovery.coverage"
|
|
3811
3884
|
};
|
|
3812
3885
|
}
|
|
3813
3886
|
function validatePrReviewDiscoveryLaneCompletion(input) {
|
|
@@ -3845,8 +3918,18 @@ function validatePrReviewDiscoveryLaneCompletion(input) {
|
|
|
3845
3918
|
const artifact = input.artifact;
|
|
3846
3919
|
const analyses = ownedWorkflowLanes.map((workflowLane) => ({
|
|
3847
3920
|
workflowLane,
|
|
3848
|
-
analysis: analyzePrReviewDiscoveryArtifact(artifact.text, workflowLane, ownedWorkflowLanes)
|
|
3921
|
+
analysis: analyzePrReviewDiscoveryArtifact(artifact.text, workflowLane, ownedWorkflowLanes, input.expected.mode)
|
|
3849
3922
|
}));
|
|
3923
|
+
const salvagedLanes = [];
|
|
3924
|
+
for (const { workflowLane, analysis } of analyses) {
|
|
3925
|
+
if (!analysis.covered)
|
|
3926
|
+
continue;
|
|
3927
|
+
if (!analysis.salvaged && analysis.issues.length === 0)
|
|
3928
|
+
continue;
|
|
3929
|
+
salvagedLanes.push(workflowLane);
|
|
3930
|
+
const reason = analysis.salvaged ? `canonical ${resolvePrReviewRowFamily(workflowLane, input.expected.mode)} header was absent and was synthesized from valid marker rows` : "one or more rows were dropped as malformed or out-of-ownership";
|
|
3931
|
+
warn(`[pr-workflow-gate] discovery artifact salvaged: batch=${input.record.batchId ?? "(missing)"} lane=${input.record.laneId ?? "(missing)"} workflow_lane=${workflowLane} \u2014 ${reason}; retained coverage from the valid rows. Dropped-row diagnostics: ${analysis.issues.join("; ") || "(none)"}`);
|
|
3932
|
+
}
|
|
3850
3933
|
const failedCoverage = analyses.find(({ analysis }) => !analysis.covered);
|
|
3851
3934
|
if (failedCoverage) {
|
|
3852
3935
|
return failedLaneValidation(failedCoverage.analysis.failurePredicate ?? "discovery.coverage", `one valid ${input.expected.mode === "swarm-pr-review:base" ? "base_explorer" : "micro_lane"} [CANDIDATE] row or [CLEAN] attestation for ${failedCoverage.workflowLane}`, failedCoverage.analysis.issues.join("; ") || "no matching lane row");
|
|
@@ -3863,13 +3946,13 @@ function validatePrReviewDiscoveryLaneCompletion(input) {
|
|
|
3863
3946
|
seenEvidence.set(analysis.evidence, workflowLane);
|
|
3864
3947
|
}
|
|
3865
3948
|
}
|
|
3866
|
-
return { ok: true };
|
|
3949
|
+
return salvagedLanes.length > 0 ? { ok: true, salvaged: salvagedLanes } : { ok: true };
|
|
3867
3950
|
}
|
|
3868
|
-
function prReviewDiscoveryArtifactCoversLane(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane]) {
|
|
3869
|
-
return analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes).covered;
|
|
3951
|
+
function prReviewDiscoveryArtifactCoversLane(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane], mode) {
|
|
3952
|
+
return analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes, mode).covered;
|
|
3870
3953
|
}
|
|
3871
|
-
function extractLaneCoverageEvidenceText(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane]) {
|
|
3872
|
-
return analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes).evidence;
|
|
3954
|
+
function extractLaneCoverageEvidenceText(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane], mode) {
|
|
3955
|
+
return analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes, mode).evidence;
|
|
3873
3956
|
}
|
|
3874
3957
|
var REVIEWER_CLASSIFICATIONS = new Set([
|
|
3875
3958
|
"CONFIRMED",
|
|
@@ -18784,7 +18867,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
|
|
|
18784
18867
|
};
|
|
18785
18868
|
}
|
|
18786
18869
|
async function sweepActiveNearDuplicates(directory, options = {}) {
|
|
18787
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
18870
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8emf08eb.js");
|
|
18788
18871
|
const { config } = loadPluginConfigWithMeta2(directory);
|
|
18789
18872
|
const sweepConfig = config.learning?.dedup_sweep;
|
|
18790
18873
|
if (sweepConfig?.enabled === false)
|
|
@@ -20377,7 +20460,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
20377
20460
|
}
|
|
20378
20461
|
if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
|
|
20379
20462
|
try {
|
|
20380
|
-
const skillModule = await import("./skill-generator-
|
|
20463
|
+
const skillModule = await import("./skill-generator-t3m5qajm.js");
|
|
20381
20464
|
for (const cand of skillCandidates) {
|
|
20382
20465
|
if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
|
|
20383
20466
|
continue;
|
|
@@ -20837,7 +20920,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
20837
20920
|
} catch {}
|
|
20838
20921
|
}
|
|
20839
20922
|
if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
|
|
20840
|
-
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-
|
|
20923
|
+
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-qmpfh5yz.js");
|
|
20841
20924
|
for (const { id } of contradictedEntries) {
|
|
20842
20925
|
try {
|
|
20843
20926
|
await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
|
|
@@ -21656,7 +21739,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
21656
21739
|
warnings.push("Failed to collect knowledge summary.");
|
|
21657
21740
|
}
|
|
21658
21741
|
try {
|
|
21659
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
21742
|
+
const { getScanStatus } = await import("./scan-cursor-3tqshkb2.js");
|
|
21660
21743
|
const scanStatus = await getScanStatus(directory);
|
|
21661
21744
|
if (scanStatus.remaining_estimate > 0) {
|
|
21662
21745
|
warnings.push(`Fair scan: reviewed ${knowledgeSummary.length} entries this sweep (generation ${scanStatus.generation}); ${scanStatus.remaining_estimate} more eligible entries will be visited in future curation sweeps.`);
|
|
@@ -21828,9 +21911,9 @@ var _internals24 = {
|
|
|
21828
21911
|
verifyPostMortemKnowledgeActions,
|
|
21829
21912
|
repairPostMortemActions,
|
|
21830
21913
|
loadDefaultKnowledgeConfig: async (directory) => {
|
|
21831
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
21914
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mtyaeh18.js");
|
|
21832
21915
|
try {
|
|
21833
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
21916
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8emf08eb.js");
|
|
21834
21917
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
21835
21918
|
return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
21836
21919
|
} catch {
|
|
@@ -21838,11 +21921,11 @@ var _internals24 = {
|
|
|
21838
21921
|
}
|
|
21839
21922
|
},
|
|
21840
21923
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
21841
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
21924
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-jt6dza8y.js");
|
|
21842
21925
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
21843
21926
|
},
|
|
21844
21927
|
checkHivePromotions: async (entries, knowledgeConfig, directory) => {
|
|
21845
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
21928
|
+
const { checkHivePromotions } = await import("./hive-promoter-34y2x4vt.js");
|
|
21846
21929
|
return checkHivePromotions(entries, knowledgeConfig, directory);
|
|
21847
21930
|
},
|
|
21848
21931
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -21851,7 +21934,7 @@ var _internals24 = {
|
|
|
21851
21934
|
activateProposal,
|
|
21852
21935
|
listSkills: listSkills2,
|
|
21853
21936
|
sanitizeSlug
|
|
21854
|
-
} = await import("./skill-generator-
|
|
21937
|
+
} = await import("./skill-generator-t3m5qajm.js");
|
|
21855
21938
|
const result = {
|
|
21856
21939
|
approved: [],
|
|
21857
21940
|
rejected: [],
|
|
@@ -24478,9 +24561,9 @@ function hashContent(content) {
|
|
|
24478
24561
|
return createHash9("sha1").update(content).digest("hex");
|
|
24479
24562
|
}
|
|
24480
24563
|
async function loadConfigForPolicyCurator(directory) {
|
|
24481
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
24564
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mtyaeh18.js");
|
|
24482
24565
|
try {
|
|
24483
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
24566
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8emf08eb.js");
|
|
24484
24567
|
const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
|
|
24485
24568
|
return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
|
|
24486
24569
|
} catch {
|
|
@@ -28440,7 +28523,7 @@ async function runFinalizeStage(ctx) {
|
|
|
28440
28523
|
}
|
|
28441
28524
|
}
|
|
28442
28525
|
try {
|
|
28443
|
-
const { CuratorConfigSchema: CCS } = await import("./schema-
|
|
28526
|
+
const { CuratorConfigSchema: CCS } = await import("./schema-mtyaeh18.js");
|
|
28444
28527
|
const { config: pmLoadedConfig } = _internals36.loadPluginConfigWithMeta(ctx.directory);
|
|
28445
28528
|
const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
|
|
28446
28529
|
if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
|
|
@@ -30711,9 +30794,9 @@ var _internals41 = {
|
|
|
30711
30794
|
loadPluginConfigWithMeta,
|
|
30712
30795
|
loadCuratorDeps: async () => {
|
|
30713
30796
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
|
|
30714
|
-
import("./schema-
|
|
30715
|
-
import("./curator-
|
|
30716
|
-
import("./curator-llm-factory-
|
|
30797
|
+
import("./schema-mtyaeh18.js"),
|
|
30798
|
+
import("./curator-jt6dza8y.js"),
|
|
30799
|
+
import("./curator-llm-factory-m9f4h8t4.js")
|
|
30717
30800
|
]);
|
|
30718
30801
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
|
|
30719
30802
|
}
|
|
@@ -31618,7 +31701,7 @@ async function computeCurationDiagnostics(directory, entries) {
|
|
|
31618
31701
|
let scanCompleted = false;
|
|
31619
31702
|
let scanRemaining = 0;
|
|
31620
31703
|
try {
|
|
31621
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
31704
|
+
const { getScanStatus } = await import("./scan-cursor-3tqshkb2.js");
|
|
31622
31705
|
const status = await getScanStatus(directory);
|
|
31623
31706
|
scanGeneration = status.generation;
|
|
31624
31707
|
scanCompleted = status.completed;
|
|
@@ -31628,17 +31711,17 @@ async function computeCurationDiagnostics(directory, entries) {
|
|
|
31628
31711
|
try {
|
|
31629
31712
|
const { isLinked: isLinked2 } = await import("./knowledge-link-xc6yhxmz.js");
|
|
31630
31713
|
if (isLinked2(directory)) {
|
|
31631
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
31714
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mtyaeh18.js");
|
|
31632
31715
|
let config;
|
|
31633
31716
|
try {
|
|
31634
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
31717
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8emf08eb.js");
|
|
31635
31718
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
31636
31719
|
config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
31637
31720
|
} catch {
|
|
31638
31721
|
config = KnowledgeConfigSchema2.parse({});
|
|
31639
31722
|
}
|
|
31640
31723
|
const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
|
|
31641
|
-
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-
|
|
31724
|
+
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-aj37yvz8.js");
|
|
31642
31725
|
const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
|
|
31643
31726
|
const cohortFp = await readCohortConfigFingerprint(directory);
|
|
31644
31727
|
configMatch = cohortFp === null ? null : currentFp === cohortFp;
|
|
@@ -32849,7 +32932,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
32849
32932
|
const result = runConfigDoctor(config, directory);
|
|
32850
32933
|
let output;
|
|
32851
32934
|
if (enableAutoFix && result.hasAutoFixableIssues) {
|
|
32852
|
-
const { runConfigDoctorWithFixes } = await import("./config-doctor-
|
|
32935
|
+
const { runConfigDoctorWithFixes } = await import("./config-doctor-hzb0bck9.js");
|
|
32853
32936
|
const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
|
|
32854
32937
|
applyLossy: true
|
|
32855
32938
|
});
|
|
@@ -33686,7 +33769,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
33686
33769
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
33687
33770
|
}
|
|
33688
33771
|
async function handleEvidenceSummaryCommand(directory) {
|
|
33689
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
33772
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-6cttrkzw.js");
|
|
33690
33773
|
const artifact = await buildEvidenceSummary(directory);
|
|
33691
33774
|
if (!artifact) {
|
|
33692
33775
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -43362,10 +43445,14 @@ import * as path77 from "path";
|
|
|
43362
43445
|
var MAX_FILE_PATH_LENGTH = 500;
|
|
43363
43446
|
var MAX_FILE_SIZE_BYTES3 = 512 * 1024;
|
|
43364
43447
|
var MAX_FILES_SCANNED2 = 1000;
|
|
43448
|
+
var MAX_EXPLICIT_FILES_SCANNED = 100;
|
|
43365
43449
|
var MAX_FINDINGS2 = 100;
|
|
43366
43450
|
var MAX_OUTPUT_BYTES3 = 512000;
|
|
43367
|
-
var
|
|
43368
|
-
var
|
|
43451
|
+
var MAX_CONTEXT_CHARS = 1000;
|
|
43452
|
+
var MAX_LONG_LINE_CHARS = 1e4;
|
|
43453
|
+
var MAX_INCOMPLETE_PATHS = 25;
|
|
43454
|
+
var MAX_DISCOVERY_DIRECTORIES = 1e4;
|
|
43455
|
+
var SCAN_TIME_BUDGET_MS = 55000;
|
|
43369
43456
|
var BINARY_SIGNATURES = [
|
|
43370
43457
|
0,
|
|
43371
43458
|
2303741511,
|
|
@@ -43413,6 +43500,7 @@ var DEFAULT_EXCLUDE_EXTENSIONS = new Set([
|
|
|
43413
43500
|
".gz",
|
|
43414
43501
|
".rar",
|
|
43415
43502
|
".7z",
|
|
43503
|
+
".wasm",
|
|
43416
43504
|
".exe",
|
|
43417
43505
|
".dll",
|
|
43418
43506
|
".so",
|
|
@@ -43651,9 +43739,6 @@ function isBinaryFile(filePath, buffer) {
|
|
|
43651
43739
|
}
|
|
43652
43740
|
function scanLineForSecrets(line, _lineNum) {
|
|
43653
43741
|
const results = [];
|
|
43654
|
-
if (line.length > MAX_LINE_LENGTH) {
|
|
43655
|
-
return results;
|
|
43656
|
-
}
|
|
43657
43742
|
for (const pattern of SECRET_PATTERNS2) {
|
|
43658
43743
|
pattern.regex.lastIndex = 0;
|
|
43659
43744
|
for (let match = pattern.regex.exec(line);match !== null; match = pattern.regex.exec(line)) {
|
|
@@ -43672,8 +43757,8 @@ function scanLineForSecrets(line, _lineNum) {
|
|
|
43672
43757
|
}
|
|
43673
43758
|
}
|
|
43674
43759
|
}
|
|
43675
|
-
const valueMatch = line.match(/(?:secret|key|token|password|cred|credential)\s*[=:]\s*["']?([a-zA-Z0-9+/=_-]{20,100})["']?/i);
|
|
43676
|
-
if (valueMatch && isHighEntropyString(valueMatch[
|
|
43760
|
+
const valueMatch = line.match(/((?:secret|key|token|password|cred|credential))\s*[=:]\s*["']?([a-zA-Z0-9+/=_-]{20,100})["']?/i);
|
|
43761
|
+
if (valueMatch && isHighEntropyString(valueMatch[2])) {
|
|
43677
43762
|
const matchStart = valueMatch.index || 0;
|
|
43678
43763
|
const matchEnd = matchStart + valueMatch[0].length;
|
|
43679
43764
|
const hasOverlap = results.some((r) => !(r.matchEnd <= matchStart || r.matchStart >= matchEnd));
|
|
@@ -43682,7 +43767,7 @@ function scanLineForSecrets(line, _lineNum) {
|
|
|
43682
43767
|
type: "high_entropy",
|
|
43683
43768
|
confidence: "low",
|
|
43684
43769
|
severity: "medium",
|
|
43685
|
-
redacted: `${valueMatch[
|
|
43770
|
+
redacted: `${valueMatch[1]}=[HIGH_ENTROPY]`,
|
|
43686
43771
|
matchStart,
|
|
43687
43772
|
matchEnd
|
|
43688
43773
|
});
|
|
@@ -43692,42 +43777,95 @@ function scanLineForSecrets(line, _lineNum) {
|
|
|
43692
43777
|
}
|
|
43693
43778
|
function createRedactedContext(line, findings) {
|
|
43694
43779
|
if (findings.length === 0)
|
|
43695
|
-
return
|
|
43780
|
+
return "";
|
|
43696
43781
|
const sorted = [...findings].sort((a, b) => a.matchStart - b.matchStart);
|
|
43697
43782
|
let result = "";
|
|
43698
43783
|
let lastEnd = 0;
|
|
43699
43784
|
for (const finding of sorted) {
|
|
43700
|
-
|
|
43701
|
-
|
|
43702
|
-
|
|
43785
|
+
if (finding.matchEnd <= lastEnd)
|
|
43786
|
+
continue;
|
|
43787
|
+
if (finding.matchStart >= lastEnd) {
|
|
43788
|
+
result += line.slice(lastEnd, finding.matchStart);
|
|
43789
|
+
result += "[REDACTED]";
|
|
43790
|
+
}
|
|
43791
|
+
lastEnd = Math.max(lastEnd, finding.matchEnd);
|
|
43703
43792
|
}
|
|
43704
43793
|
result += line.slice(lastEnd);
|
|
43705
|
-
|
|
43794
|
+
if (result.length <= MAX_CONTEXT_CHARS)
|
|
43795
|
+
return result;
|
|
43796
|
+
const truncationMarker = "...[context truncated]...";
|
|
43797
|
+
const edgeLength = Math.floor((MAX_CONTEXT_CHARS - truncationMarker.length) / 2);
|
|
43798
|
+
const remaining = MAX_CONTEXT_CHARS - truncationMarker.length - edgeLength;
|
|
43799
|
+
return `${result.slice(0, edgeLength)}${truncationMarker}${result.slice(-remaining)}`;
|
|
43706
43800
|
}
|
|
43707
43801
|
var O_NOFOLLOW = process.platform !== "win32" ? fs31.constants.O_NOFOLLOW : undefined;
|
|
43708
|
-
function
|
|
43802
|
+
function readBoundedFile(filePath) {
|
|
43803
|
+
let fd;
|
|
43804
|
+
try {
|
|
43805
|
+
const flags = fs31.constants.O_RDONLY | (O_NOFOLLOW !== undefined ? O_NOFOLLOW : 0);
|
|
43806
|
+
fd = _internals64.openFile(filePath, flags);
|
|
43807
|
+
} catch {
|
|
43808
|
+
return { status: "incomplete", reason: "read_error" };
|
|
43809
|
+
}
|
|
43810
|
+
let outcome;
|
|
43811
|
+
try {
|
|
43812
|
+
const stat6 = _internals64.fstatFile(fd);
|
|
43813
|
+
const initialSize = stat6.size;
|
|
43814
|
+
if (!stat6.isFile()) {
|
|
43815
|
+
outcome = { status: "incomplete", reason: "non_file" };
|
|
43816
|
+
} else {
|
|
43817
|
+
const bufferLength = Math.min(initialSize + 1, MAX_FILE_SIZE_BYTES3 + 1);
|
|
43818
|
+
const buffer = Buffer.allocUnsafe(bufferLength);
|
|
43819
|
+
let bytesRead = 0;
|
|
43820
|
+
while (bytesRead < buffer.length) {
|
|
43821
|
+
const count = _internals64.readFileChunk(fd, buffer, bytesRead, buffer.length - bytesRead, null);
|
|
43822
|
+
if (count === 0)
|
|
43823
|
+
break;
|
|
43824
|
+
bytesRead += count;
|
|
43825
|
+
}
|
|
43826
|
+
const postStat = _internals64.fstatFile(fd);
|
|
43827
|
+
if (postStat.size !== initialSize) {
|
|
43828
|
+
outcome = {
|
|
43829
|
+
status: "incomplete",
|
|
43830
|
+
reason: postStat.size > MAX_FILE_SIZE_BYTES3 ? "oversized" : "read_error"
|
|
43831
|
+
};
|
|
43832
|
+
} else {
|
|
43833
|
+
outcome = {
|
|
43834
|
+
status: "ok",
|
|
43835
|
+
buffer: buffer.subarray(0, bytesRead),
|
|
43836
|
+
truncated: initialSize > MAX_FILE_SIZE_BYTES3
|
|
43837
|
+
};
|
|
43838
|
+
}
|
|
43839
|
+
}
|
|
43840
|
+
} catch {
|
|
43841
|
+
outcome = { status: "incomplete", reason: "read_error" };
|
|
43842
|
+
}
|
|
43843
|
+
try {
|
|
43844
|
+
_internals64.closeFile(fd);
|
|
43845
|
+
} catch {
|
|
43846
|
+
return { status: "incomplete", reason: "read_error" };
|
|
43847
|
+
}
|
|
43848
|
+
return outcome;
|
|
43849
|
+
}
|
|
43850
|
+
function scanFileForSecrets(filePath, mode) {
|
|
43709
43851
|
const findings = [];
|
|
43710
43852
|
try {
|
|
43711
43853
|
const lstat3 = fs31.lstatSync(filePath);
|
|
43712
43854
|
if (lstat3.isSymbolicLink()) {
|
|
43713
|
-
return
|
|
43855
|
+
return mode === "explicit" ? { status: "incomplete", reason: "symlink" } : { status: "skipped", reason: "symlink" };
|
|
43714
43856
|
}
|
|
43715
|
-
if (lstat3.
|
|
43716
|
-
return
|
|
43717
|
-
}
|
|
43718
|
-
let buffer;
|
|
43719
|
-
if (O_NOFOLLOW !== undefined) {
|
|
43720
|
-
const fd = fs31.openSync(filePath, "r", O_NOFOLLOW);
|
|
43721
|
-
try {
|
|
43722
|
-
buffer = fs31.readFileSync(fd);
|
|
43723
|
-
} finally {
|
|
43724
|
-
fs31.closeSync(fd);
|
|
43725
|
-
}
|
|
43726
|
-
} else {
|
|
43727
|
-
buffer = fs31.readFileSync(filePath);
|
|
43857
|
+
if (!lstat3.isFile()) {
|
|
43858
|
+
return { status: "incomplete", reason: "non_file" };
|
|
43728
43859
|
}
|
|
43860
|
+
const readOutcome = readBoundedFile(filePath);
|
|
43861
|
+
if (readOutcome.status === "incomplete")
|
|
43862
|
+
return readOutcome;
|
|
43863
|
+
const { buffer, truncated } = readOutcome;
|
|
43729
43864
|
if (isBinaryFile(filePath, buffer)) {
|
|
43730
|
-
return
|
|
43865
|
+
return { status: "skipped", reason: "binary" };
|
|
43866
|
+
}
|
|
43867
|
+
if (truncated) {
|
|
43868
|
+
return { status: "incomplete", reason: "oversized" };
|
|
43731
43869
|
}
|
|
43732
43870
|
let content;
|
|
43733
43871
|
if (buffer.length >= 3 && buffer[0] === 239 && buffer[1] === 187 && buffer[2] === 191) {
|
|
@@ -43736,13 +43874,16 @@ function scanFileForSecrets(filePath) {
|
|
|
43736
43874
|
content = buffer.toString("utf-8");
|
|
43737
43875
|
}
|
|
43738
43876
|
if (content.includes("\x00")) {
|
|
43739
|
-
return
|
|
43877
|
+
return { status: "skipped", reason: "binary" };
|
|
43740
43878
|
}
|
|
43741
|
-
const
|
|
43742
|
-
const lines = scanContent.split(`
|
|
43879
|
+
const lines = content.split(`
|
|
43743
43880
|
`);
|
|
43744
43881
|
for (let i = 0;i < lines.length; i++) {
|
|
43882
|
+
if (mode === "standalone" && lines[i].length > MAX_LONG_LINE_CHARS) {
|
|
43883
|
+
continue;
|
|
43884
|
+
}
|
|
43745
43885
|
const lineResults = scanLineForSecrets(lines[i], i + 1);
|
|
43886
|
+
const context = createRedactedContext(lines[i], lineResults);
|
|
43746
43887
|
for (const result of lineResults) {
|
|
43747
43888
|
findings.push({
|
|
43748
43889
|
path: filePath,
|
|
@@ -43751,12 +43892,43 @@ function scanFileForSecrets(filePath) {
|
|
|
43751
43892
|
confidence: result.confidence,
|
|
43752
43893
|
severity: result.severity,
|
|
43753
43894
|
redacted: result.redacted,
|
|
43754
|
-
context
|
|
43895
|
+
context
|
|
43755
43896
|
});
|
|
43756
43897
|
}
|
|
43757
43898
|
}
|
|
43758
|
-
|
|
43759
|
-
|
|
43899
|
+
return { status: "scanned", findings };
|
|
43900
|
+
} catch {
|
|
43901
|
+
return { status: "incomplete", reason: "read_error" };
|
|
43902
|
+
}
|
|
43903
|
+
}
|
|
43904
|
+
function assertNever(value) {
|
|
43905
|
+
throw new Error(`Unhandled secretscan outcome: ${String(value)}`);
|
|
43906
|
+
}
|
|
43907
|
+
async function yieldToEventLoop() {
|
|
43908
|
+
await new Promise((resolve24) => setImmediate(resolve24));
|
|
43909
|
+
}
|
|
43910
|
+
function serializeSecretscanResult(result) {
|
|
43911
|
+
let findings = result.findings;
|
|
43912
|
+
let candidate = result;
|
|
43913
|
+
let json = JSON.stringify(candidate, null, 2);
|
|
43914
|
+
while (Buffer.byteLength(json, "utf8") > MAX_OUTPUT_BYTES3 && findings.length > 0) {
|
|
43915
|
+
findings = findings.slice(0, Math.floor(findings.length / 2));
|
|
43916
|
+
candidate = {
|
|
43917
|
+
...result,
|
|
43918
|
+
findings,
|
|
43919
|
+
message: "Output truncated due to size limits."
|
|
43920
|
+
};
|
|
43921
|
+
json = JSON.stringify(candidate, null, 2);
|
|
43922
|
+
}
|
|
43923
|
+
if (Buffer.byteLength(json, "utf8") > MAX_OUTPUT_BYTES3) {
|
|
43924
|
+
candidate = {
|
|
43925
|
+
...result,
|
|
43926
|
+
findings: [],
|
|
43927
|
+
message: "Output truncated due to size limits."
|
|
43928
|
+
};
|
|
43929
|
+
json = JSON.stringify(candidate, null, 2);
|
|
43930
|
+
}
|
|
43931
|
+
return json;
|
|
43760
43932
|
}
|
|
43761
43933
|
function isSymlinkLoop(realPath, visited) {
|
|
43762
43934
|
if (visited.has(realPath)) {
|
|
@@ -43770,75 +43942,168 @@ function isPathWithinScope(realPath, scanDir) {
|
|
|
43770
43942
|
const resolvedRealPath = path77.resolve(realPath);
|
|
43771
43943
|
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path77.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
43772
43944
|
}
|
|
43773
|
-
|
|
43774
|
-
|
|
43775
|
-
|
|
43776
|
-
|
|
43777
|
-
|
|
43778
|
-
|
|
43779
|
-
|
|
43780
|
-
|
|
43781
|
-
|
|
43782
|
-
|
|
43783
|
-
|
|
43784
|
-
|
|
43785
|
-
|
|
43786
|
-
|
|
43787
|
-
|
|
43788
|
-
|
|
43789
|
-
|
|
43790
|
-
|
|
43791
|
-
|
|
43792
|
-
|
|
43793
|
-
|
|
43794
|
-
|
|
43795
|
-
|
|
43796
|
-
|
|
43797
|
-
|
|
43798
|
-
|
|
43799
|
-
|
|
43800
|
-
|
|
43801
|
-
|
|
43945
|
+
var DISCOVERY_YIELD_INTERVAL = 100;
|
|
43946
|
+
function toSafeRelativePath(rootDir, targetPath) {
|
|
43947
|
+
const relative10 = path77.relative(rootDir, targetPath).replace(/\\/g, "/");
|
|
43948
|
+
if (!relative10 || relative10 === ".")
|
|
43949
|
+
return ".";
|
|
43950
|
+
if (relative10.startsWith("..") || path77.isAbsolute(relative10)) {
|
|
43951
|
+
const basename15 = path77.basename(targetPath).replace(/\\/g, "/");
|
|
43952
|
+
return basename15 || ".";
|
|
43953
|
+
}
|
|
43954
|
+
return relative10;
|
|
43955
|
+
}
|
|
43956
|
+
function recordIncompletePath(target, rootDir, targetPath, reason) {
|
|
43957
|
+
if (target.length >= MAX_INCOMPLETE_PATHS) {
|
|
43958
|
+
target[MAX_INCOMPLETE_PATHS - 1] = { path: ".", reason: "truncated" };
|
|
43959
|
+
return;
|
|
43960
|
+
}
|
|
43961
|
+
target.push({ path: toSafeRelativePath(rootDir, targetPath), reason });
|
|
43962
|
+
}
|
|
43963
|
+
function compareFilePaths(a, b) {
|
|
43964
|
+
const aLower = a.toLowerCase();
|
|
43965
|
+
const bLower = b.toLowerCase();
|
|
43966
|
+
if (aLower < bLower)
|
|
43967
|
+
return -1;
|
|
43968
|
+
if (aLower > bLower)
|
|
43969
|
+
return 1;
|
|
43970
|
+
if (a < b)
|
|
43971
|
+
return -1;
|
|
43972
|
+
if (a > b)
|
|
43973
|
+
return 1;
|
|
43974
|
+
return 0;
|
|
43975
|
+
}
|
|
43976
|
+
function addBoundedCandidate(state, filePath) {
|
|
43977
|
+
state.totalCandidates++;
|
|
43978
|
+
const heap = state.files;
|
|
43979
|
+
if (heap.length < MAX_FILES_SCANNED2) {
|
|
43980
|
+
heap.push(filePath);
|
|
43981
|
+
let index2 = heap.length - 1;
|
|
43982
|
+
while (index2 > 0) {
|
|
43983
|
+
const parent = Math.floor((index2 - 1) / 2);
|
|
43984
|
+
if (compareFilePaths(heap[parent], heap[index2]) >= 0)
|
|
43985
|
+
break;
|
|
43986
|
+
[heap[parent], heap[index2]] = [heap[index2], heap[parent]];
|
|
43987
|
+
index2 = parent;
|
|
43988
|
+
}
|
|
43989
|
+
return;
|
|
43990
|
+
}
|
|
43991
|
+
if (compareFilePaths(filePath, heap[0]) >= 0)
|
|
43992
|
+
return;
|
|
43993
|
+
heap[0] = filePath;
|
|
43994
|
+
let index = 0;
|
|
43995
|
+
while (true) {
|
|
43996
|
+
const left = index * 2 + 1;
|
|
43997
|
+
const right = left + 1;
|
|
43998
|
+
let largest = index;
|
|
43999
|
+
if (left < heap.length && compareFilePaths(heap[left], heap[largest]) > 0) {
|
|
44000
|
+
largest = left;
|
|
43802
44001
|
}
|
|
43803
|
-
|
|
44002
|
+
if (right < heap.length && compareFilePaths(heap[right], heap[largest]) > 0) {
|
|
44003
|
+
largest = right;
|
|
44004
|
+
}
|
|
44005
|
+
if (largest === index)
|
|
44006
|
+
break;
|
|
44007
|
+
[heap[index], heap[largest]] = [heap[largest], heap[index]];
|
|
44008
|
+
index = largest;
|
|
44009
|
+
}
|
|
44010
|
+
}
|
|
44011
|
+
async function collectScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats, state) {
|
|
44012
|
+
const pending = [dir];
|
|
44013
|
+
while (pending.length > 0) {
|
|
44014
|
+
if (state.deadlineExceeded || state.cleanupFailed)
|
|
44015
|
+
return;
|
|
44016
|
+
const currentDir = pending.pop();
|
|
44017
|
+
if (!currentDir)
|
|
44018
|
+
continue;
|
|
44019
|
+
let directory;
|
|
43804
44020
|
try {
|
|
43805
|
-
|
|
44021
|
+
directory = fs31.opendirSync(currentDir);
|
|
43806
44022
|
} catch {
|
|
43807
44023
|
stats.fileErrors++;
|
|
44024
|
+
recordIncompletePath(state.incompletePaths, scanDir, currentDir, "read_error");
|
|
43808
44025
|
continue;
|
|
43809
44026
|
}
|
|
43810
|
-
|
|
43811
|
-
|
|
43812
|
-
|
|
43813
|
-
|
|
43814
|
-
|
|
43815
|
-
|
|
43816
|
-
|
|
43817
|
-
|
|
43818
|
-
|
|
43819
|
-
|
|
43820
|
-
|
|
43821
|
-
|
|
43822
|
-
|
|
43823
|
-
|
|
43824
|
-
|
|
43825
|
-
|
|
43826
|
-
|
|
43827
|
-
|
|
43828
|
-
|
|
44027
|
+
let stoppedEarly = false;
|
|
44028
|
+
try {
|
|
44029
|
+
while (true) {
|
|
44030
|
+
if (state.entriesSinceYield >= DISCOVERY_YIELD_INTERVAL) {
|
|
44031
|
+
state.entriesSinceYield = 0;
|
|
44032
|
+
await _internals64.yieldToEventLoop();
|
|
44033
|
+
if (_internals64.now() >= state.deadline) {
|
|
44034
|
+
state.deadlineExceeded = true;
|
|
44035
|
+
recordIncompletePath(state.incompletePaths, scanDir, currentDir, "deadline");
|
|
44036
|
+
stoppedEarly = true;
|
|
44037
|
+
break;
|
|
44038
|
+
}
|
|
44039
|
+
}
|
|
44040
|
+
const entry = directory.readSync();
|
|
44041
|
+
if (!entry)
|
|
44042
|
+
break;
|
|
44043
|
+
state.entriesSinceYield++;
|
|
44044
|
+
const fullPath = path77.join(currentDir, entry.name);
|
|
44045
|
+
const relPath = path77.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
44046
|
+
if (isExcluded(entry.name, relPath, excludeExact, excludeGlobs)) {
|
|
44047
|
+
stats.skippedDirs++;
|
|
44048
|
+
continue;
|
|
44049
|
+
}
|
|
44050
|
+
let lstat3;
|
|
44051
|
+
try {
|
|
44052
|
+
lstat3 = fs31.lstatSync(fullPath);
|
|
44053
|
+
} catch {
|
|
44054
|
+
stats.fileErrors++;
|
|
44055
|
+
recordIncompletePath(state.incompletePaths, scanDir, fullPath, "read_error");
|
|
44056
|
+
continue;
|
|
44057
|
+
}
|
|
44058
|
+
if (lstat3.isSymbolicLink()) {
|
|
44059
|
+
stats.symlinkSkipped++;
|
|
44060
|
+
continue;
|
|
44061
|
+
}
|
|
44062
|
+
if (lstat3.isDirectory()) {
|
|
44063
|
+
if (state.directoriesQueued >= MAX_DISCOVERY_DIRECTORIES) {
|
|
44064
|
+
state.unexaminedDirectories++;
|
|
44065
|
+
recordIncompletePath(state.incompletePaths, scanDir, fullPath, "directory_limit");
|
|
44066
|
+
continue;
|
|
44067
|
+
}
|
|
44068
|
+
let realPath;
|
|
44069
|
+
try {
|
|
44070
|
+
realPath = fs31.realpathSync(fullPath);
|
|
44071
|
+
} catch {
|
|
44072
|
+
stats.fileErrors++;
|
|
44073
|
+
recordIncompletePath(state.incompletePaths, scanDir, fullPath, "read_error");
|
|
44074
|
+
continue;
|
|
44075
|
+
}
|
|
44076
|
+
if (isSymlinkLoop(realPath, visited) || !isPathWithinScope(realPath, scanDir)) {
|
|
44077
|
+
stats.symlinkSkipped++;
|
|
44078
|
+
continue;
|
|
44079
|
+
}
|
|
44080
|
+
pending.push(fullPath);
|
|
44081
|
+
state.directoriesQueued++;
|
|
44082
|
+
} else if (lstat3.isFile()) {
|
|
44083
|
+
const ext = path77.extname(fullPath).toLowerCase();
|
|
44084
|
+
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
44085
|
+
addBoundedCandidate(state, fullPath);
|
|
44086
|
+
} else {
|
|
44087
|
+
stats.skippedFiles++;
|
|
44088
|
+
}
|
|
44089
|
+
} else {
|
|
44090
|
+
stats.fileErrors++;
|
|
44091
|
+
recordIncompletePath(state.incompletePaths, scanDir, fullPath, "non_file");
|
|
44092
|
+
}
|
|
43829
44093
|
}
|
|
43830
|
-
|
|
43831
|
-
|
|
43832
|
-
|
|
43833
|
-
|
|
43834
|
-
|
|
43835
|
-
|
|
43836
|
-
|
|
43837
|
-
|
|
44094
|
+
} finally {
|
|
44095
|
+
try {
|
|
44096
|
+
_internals64.closeDirectory(directory);
|
|
44097
|
+
} catch (error2) {
|
|
44098
|
+
if (error2.code !== "ERR_DIR_CLOSED") {
|
|
44099
|
+
state.cleanupFailed = true;
|
|
44100
|
+
recordIncompletePath(state.incompletePaths, scanDir, currentDir, "cleanup_failed");
|
|
44101
|
+
}
|
|
43838
44102
|
}
|
|
43839
44103
|
}
|
|
44104
|
+
if (stoppedEarly)
|
|
44105
|
+
break;
|
|
43840
44106
|
}
|
|
43841
|
-
return files;
|
|
43842
44107
|
}
|
|
43843
44108
|
var secretscan = createSwarmTool({
|
|
43844
44109
|
description: "Scan directory for potential secrets (API keys, tokens, passwords) using regex patterns and entropy heuristics. Returns metadata-only findings with redacted previews - NEVER returns raw secrets. Excludes common directories (node_modules, .git, dist, etc.) by default. Supports glob patterns (e.g. **/.svelte-kit/**, **/*.test.ts) and reads .secretscanignore at the scan root.",
|
|
@@ -43896,17 +44161,21 @@ var secretscan = createSwarmTool({
|
|
|
43896
44161
|
}
|
|
43897
44162
|
}
|
|
43898
44163
|
try {
|
|
43899
|
-
const
|
|
44164
|
+
const scanDirRaw = path77.resolve(directory);
|
|
43900
44165
|
const scanDir = (() => {
|
|
43901
44166
|
try {
|
|
43902
|
-
return fs31.realpathSync(
|
|
44167
|
+
return fs31.realpathSync(scanDirRaw);
|
|
43903
44168
|
} catch {
|
|
43904
|
-
return
|
|
44169
|
+
return scanDirRaw;
|
|
43905
44170
|
}
|
|
43906
44171
|
})();
|
|
43907
|
-
|
|
44172
|
+
let dirStat;
|
|
44173
|
+
try {
|
|
44174
|
+
dirStat = fs31.lstatSync(scanDir);
|
|
44175
|
+
} catch (error2) {
|
|
44176
|
+
const err = error2;
|
|
43908
44177
|
const errorResult = {
|
|
43909
|
-
error: "directory not found"
|
|
44178
|
+
error: err.code === "ENOENT" ? "directory not found" : `scan failed: ${err.message || "unable to inspect directory"}`,
|
|
43910
44179
|
scan_dir: directory,
|
|
43911
44180
|
findings: [],
|
|
43912
44181
|
count: 0,
|
|
@@ -43915,7 +44184,6 @@ var secretscan = createSwarmTool({
|
|
|
43915
44184
|
};
|
|
43916
44185
|
return JSON.stringify(errorResult, null, 2);
|
|
43917
44186
|
}
|
|
43918
|
-
const dirStat = fs31.statSync(scanDir);
|
|
43919
44187
|
if (!dirStat.isDirectory()) {
|
|
43920
44188
|
const errorResult = {
|
|
43921
44189
|
error: "target must be a directory, not a file",
|
|
@@ -43947,36 +44215,74 @@ var secretscan = createSwarmTool({
|
|
|
43947
44215
|
symlinkSkipped: 0
|
|
43948
44216
|
};
|
|
43949
44217
|
const visited = new Set;
|
|
43950
|
-
const
|
|
43951
|
-
|
|
43952
|
-
|
|
43953
|
-
|
|
43954
|
-
|
|
43955
|
-
|
|
43956
|
-
|
|
43957
|
-
|
|
43958
|
-
|
|
43959
|
-
|
|
43960
|
-
|
|
44218
|
+
const deadline = _internals64.now() + SCAN_TIME_BUDGET_MS;
|
|
44219
|
+
const discovery = {
|
|
44220
|
+
files: [],
|
|
44221
|
+
totalCandidates: 0,
|
|
44222
|
+
deadline,
|
|
44223
|
+
deadlineExceeded: false,
|
|
44224
|
+
cleanupFailed: false,
|
|
44225
|
+
entriesSinceYield: 0,
|
|
44226
|
+
incompletePaths: [],
|
|
44227
|
+
directoriesQueued: 1,
|
|
44228
|
+
unexaminedDirectories: 0
|
|
44229
|
+
};
|
|
44230
|
+
await _internals64.yieldToEventLoop();
|
|
44231
|
+
await collectScannableFiles(scanDir, excludeExact, excludeGlobs, scanDir, visited, stats, discovery);
|
|
44232
|
+
const files = discovery.files;
|
|
44233
|
+
files.sort(compareFilePaths);
|
|
44234
|
+
const filesToScan = files;
|
|
44235
|
+
if (discovery.totalCandidates > filesToScan.length) {
|
|
44236
|
+
recordIncompletePath(discovery.incompletePaths, scanDir, scanDir, "max_files");
|
|
44237
|
+
}
|
|
44238
|
+
if (discovery.deadlineExceeded) {
|
|
44239
|
+
recordIncompletePath(discovery.incompletePaths, scanDir, scanDir, "deadline");
|
|
44240
|
+
}
|
|
44241
|
+
if (discovery.cleanupFailed) {
|
|
44242
|
+
recordIncompletePath(discovery.incompletePaths, scanDir, scanDir, "cleanup_failed");
|
|
44243
|
+
}
|
|
43961
44244
|
const allFindings = [];
|
|
43962
44245
|
let filesScanned = 0;
|
|
43963
44246
|
let skippedFiles = stats.skippedFiles;
|
|
43964
|
-
|
|
43965
|
-
|
|
44247
|
+
let incompleteFiles = stats.fileErrors + Math.max(0, discovery.totalCandidates - filesToScan.length) + (discovery.deadlineExceeded || discovery.cleanupFailed ? 1 : 0) + discovery.unexaminedDirectories;
|
|
44248
|
+
for (let index = 0;index < filesToScan.length; index++) {
|
|
44249
|
+
if (_internals64.now() >= deadline) {
|
|
44250
|
+
for (const remaining of filesToScan.slice(index)) {
|
|
44251
|
+
recordIncompletePath(discovery.incompletePaths, scanDir, remaining, "deadline");
|
|
44252
|
+
}
|
|
44253
|
+
incompleteFiles += filesToScan.length - index;
|
|
43966
44254
|
break;
|
|
43967
|
-
|
|
43968
|
-
|
|
43969
|
-
|
|
43970
|
-
|
|
44255
|
+
}
|
|
44256
|
+
if (allFindings.length >= MAX_FINDINGS2) {
|
|
44257
|
+
recordIncompletePath(discovery.incompletePaths, scanDir, scanDir, "truncated");
|
|
44258
|
+
incompleteFiles += filesToScan.length - index;
|
|
44259
|
+
break;
|
|
44260
|
+
}
|
|
44261
|
+
const outcome = scanFileForSecrets(filesToScan[index], "standalone");
|
|
44262
|
+
switch (outcome.status) {
|
|
44263
|
+
case "scanned":
|
|
44264
|
+
filesScanned++;
|
|
44265
|
+
break;
|
|
44266
|
+
case "skipped":
|
|
43971
44267
|
skippedFiles++;
|
|
43972
|
-
continue;
|
|
43973
|
-
}
|
|
43974
|
-
} catch {}
|
|
43975
|
-
filesScanned++;
|
|
43976
|
-
for (const finding of fileFindings) {
|
|
43977
|
-
if (allFindings.length >= MAX_FINDINGS2)
|
|
43978
44268
|
break;
|
|
43979
|
-
|
|
44269
|
+
case "incomplete":
|
|
44270
|
+
skippedFiles++;
|
|
44271
|
+
incompleteFiles++;
|
|
44272
|
+
recordIncompletePath(discovery.incompletePaths, scanDir, filesToScan[index], outcome.reason);
|
|
44273
|
+
break;
|
|
44274
|
+
default:
|
|
44275
|
+
assertNever(outcome);
|
|
44276
|
+
}
|
|
44277
|
+
if (outcome.status === "scanned") {
|
|
44278
|
+
for (const finding of outcome.findings) {
|
|
44279
|
+
if (allFindings.length >= MAX_FINDINGS2)
|
|
44280
|
+
break;
|
|
44281
|
+
allFindings.push(finding);
|
|
44282
|
+
}
|
|
44283
|
+
}
|
|
44284
|
+
if (index + 1 < filesToScan.length) {
|
|
44285
|
+
await _internals64.yieldToEventLoop();
|
|
43980
44286
|
}
|
|
43981
44287
|
}
|
|
43982
44288
|
allFindings.sort((a, b) => {
|
|
@@ -43997,31 +44303,33 @@ var secretscan = createSwarmTool({
|
|
|
43997
44303
|
findings: allFindings,
|
|
43998
44304
|
count: allFindings.length,
|
|
43999
44305
|
files_scanned: filesScanned,
|
|
44000
|
-
skipped_files: skippedFiles + stats.fileErrors + stats.symlinkSkipped
|
|
44306
|
+
skipped_files: skippedFiles + stats.fileErrors + stats.symlinkSkipped,
|
|
44307
|
+
incomplete_files: incompleteFiles,
|
|
44308
|
+
incomplete_paths: discovery.incompletePaths
|
|
44001
44309
|
};
|
|
44002
44310
|
const parts = [];
|
|
44003
|
-
if (
|
|
44004
|
-
parts.push(`Found ${
|
|
44311
|
+
if (discovery.totalCandidates > MAX_FILES_SCANNED2) {
|
|
44312
|
+
parts.push(`Found ${discovery.totalCandidates} files, selected ${MAX_FILES_SCANNED2}`);
|
|
44313
|
+
}
|
|
44314
|
+
if (discovery.deadlineExceeded) {
|
|
44315
|
+
parts.push("Discovery stopped at the scan deadline");
|
|
44316
|
+
}
|
|
44317
|
+
if (discovery.cleanupFailed) {
|
|
44318
|
+
parts.push("Discovery directory cleanup failed");
|
|
44005
44319
|
}
|
|
44006
44320
|
if (allFindings.length >= MAX_FINDINGS2) {
|
|
44007
44321
|
parts.push(`Results limited to ${MAX_FINDINGS2} findings`);
|
|
44008
44322
|
}
|
|
44323
|
+
if (incompleteFiles > 0) {
|
|
44324
|
+
parts.push(`${incompleteFiles} files were not completely scanned`);
|
|
44325
|
+
}
|
|
44009
44326
|
if (skippedFiles > 0 || stats.fileErrors > 0 || stats.symlinkSkipped > 0) {
|
|
44010
44327
|
parts.push(`${skippedFiles + stats.fileErrors + stats.symlinkSkipped} files skipped (binary/oversized/symlinks/errors)`);
|
|
44011
44328
|
}
|
|
44012
44329
|
if (parts.length > 0) {
|
|
44013
44330
|
result.message = `${parts.join("; ")}.`;
|
|
44014
44331
|
}
|
|
44015
|
-
|
|
44016
|
-
if (jsonOutput.length > MAX_OUTPUT_BYTES3) {
|
|
44017
|
-
const truncatedResult = {
|
|
44018
|
-
...result,
|
|
44019
|
-
findings: result.findings.slice(0, Math.floor(MAX_OUTPUT_BYTES3 * 0.8 / 200)),
|
|
44020
|
-
message: "Output truncated due to size limits."
|
|
44021
|
-
};
|
|
44022
|
-
jsonOutput = JSON.stringify(truncatedResult, null, 2);
|
|
44023
|
-
}
|
|
44024
|
-
return jsonOutput;
|
|
44332
|
+
return serializeSecretscanResult(result);
|
|
44025
44333
|
} catch (e) {
|
|
44026
44334
|
const errorResult = {
|
|
44027
44335
|
error: e instanceof Error ? `scan failed: ${e.message || "internal error"}` : "scan failed: unknown error",
|
|
@@ -44057,14 +44365,89 @@ async function runSecretscanOnFiles(files, directory) {
|
|
|
44057
44365
|
const findings = [];
|
|
44058
44366
|
let filesScanned = 0;
|
|
44059
44367
|
let skippedFiles = 0;
|
|
44060
|
-
|
|
44368
|
+
const incompletePaths = [];
|
|
44369
|
+
const rawRoot = path77.resolve(directory);
|
|
44370
|
+
const canonicalRoot = (() => {
|
|
44371
|
+
try {
|
|
44372
|
+
return fs31.realpathSync(rawRoot);
|
|
44373
|
+
} catch {
|
|
44374
|
+
return rawRoot;
|
|
44375
|
+
}
|
|
44376
|
+
})();
|
|
44377
|
+
let rootStat;
|
|
44378
|
+
try {
|
|
44379
|
+
rootStat = fs31.lstatSync(canonicalRoot);
|
|
44380
|
+
} catch (error2) {
|
|
44381
|
+
const err = error2;
|
|
44382
|
+
return {
|
|
44383
|
+
error: err.code === "ENOENT" ? "directory not found" : `scan failed: ${err.message || "unable to inspect directory"}`,
|
|
44384
|
+
scan_dir: directory,
|
|
44385
|
+
findings: [],
|
|
44386
|
+
count: 0,
|
|
44387
|
+
files_scanned: 0,
|
|
44388
|
+
skipped_files: 0
|
|
44389
|
+
};
|
|
44390
|
+
}
|
|
44391
|
+
if (!rootStat.isDirectory()) {
|
|
44392
|
+
throw new Error("target must be a directory");
|
|
44393
|
+
}
|
|
44394
|
+
const filesToScan = files.slice(0, MAX_EXPLICIT_FILES_SCANNED);
|
|
44395
|
+
let incompleteFiles = Math.max(0, files.length - filesToScan.length);
|
|
44396
|
+
if (files.length > filesToScan.length) {
|
|
44397
|
+
recordIncompletePath(incompletePaths, canonicalRoot, canonicalRoot, "max_files");
|
|
44398
|
+
}
|
|
44399
|
+
const deadline = _internals64.now() + SCAN_TIME_BUDGET_MS;
|
|
44400
|
+
await _internals64.yieldToEventLoop();
|
|
44401
|
+
for (let index = 0;index < filesToScan.length; index++) {
|
|
44402
|
+
if (_internals64.now() >= deadline) {
|
|
44403
|
+
for (const remaining of filesToScan.slice(index)) {
|
|
44404
|
+
const remainingPath = path77.isAbsolute(remaining) ? path77.resolve(remaining) : path77.resolve(rawRoot, remaining);
|
|
44405
|
+
recordIncompletePath(incompletePaths, canonicalRoot, remainingPath, "deadline");
|
|
44406
|
+
}
|
|
44407
|
+
incompleteFiles += filesToScan.length - index;
|
|
44408
|
+
break;
|
|
44409
|
+
}
|
|
44410
|
+
if (findings.length >= MAX_FINDINGS2) {
|
|
44411
|
+
recordIncompletePath(incompletePaths, canonicalRoot, canonicalRoot, "truncated");
|
|
44412
|
+
incompleteFiles += filesToScan.length - index;
|
|
44413
|
+
break;
|
|
44414
|
+
}
|
|
44415
|
+
const file = filesToScan[index];
|
|
44061
44416
|
if (typeof file !== "string") {
|
|
44062
44417
|
skippedFiles++;
|
|
44063
44418
|
continue;
|
|
44064
44419
|
}
|
|
44065
|
-
const resolvedPath = path77.isAbsolute(file) ? path77.resolve(file) : path77.resolve(
|
|
44066
|
-
if (!isPathWithinScope(resolvedPath,
|
|
44420
|
+
const resolvedPath = path77.isAbsolute(file) ? path77.resolve(file) : path77.resolve(rawRoot, file);
|
|
44421
|
+
if (!isPathWithinScope(resolvedPath, rawRoot)) {
|
|
44067
44422
|
skippedFiles++;
|
|
44423
|
+
incompleteFiles++;
|
|
44424
|
+
recordIncompletePath(incompletePaths, canonicalRoot, resolvedPath, "scope_escape");
|
|
44425
|
+
continue;
|
|
44426
|
+
}
|
|
44427
|
+
let lstat3;
|
|
44428
|
+
try {
|
|
44429
|
+
lstat3 = _internals64.lstatFile(resolvedPath);
|
|
44430
|
+
} catch (error2) {
|
|
44431
|
+
const err = error2;
|
|
44432
|
+
if (err.code === "ENOENT") {
|
|
44433
|
+
skippedFiles++;
|
|
44434
|
+
continue;
|
|
44435
|
+
}
|
|
44436
|
+
skippedFiles++;
|
|
44437
|
+
incompleteFiles++;
|
|
44438
|
+
recordIncompletePath(incompletePaths, canonicalRoot, resolvedPath, "read_error");
|
|
44439
|
+
continue;
|
|
44440
|
+
}
|
|
44441
|
+
if (lstat3.isSymbolicLink()) {
|
|
44442
|
+
skippedFiles++;
|
|
44443
|
+
incompleteFiles++;
|
|
44444
|
+
recordIncompletePath(incompletePaths, canonicalRoot, resolvedPath, "symlink");
|
|
44445
|
+
continue;
|
|
44446
|
+
}
|
|
44447
|
+
if (!lstat3.isFile()) {
|
|
44448
|
+
skippedFiles++;
|
|
44449
|
+
incompleteFiles++;
|
|
44450
|
+
recordIncompletePath(incompletePaths, canonicalRoot, resolvedPath, "non_file");
|
|
44068
44451
|
continue;
|
|
44069
44452
|
}
|
|
44070
44453
|
const ext = path77.extname(resolvedPath).toLowerCase();
|
|
@@ -44072,16 +44455,47 @@ async function runSecretscanOnFiles(files, directory) {
|
|
|
44072
44455
|
skippedFiles++;
|
|
44073
44456
|
continue;
|
|
44074
44457
|
}
|
|
44075
|
-
|
|
44458
|
+
let scanPath = resolvedPath;
|
|
44459
|
+
try {
|
|
44460
|
+
scanPath = fs31.realpathSync(resolvedPath);
|
|
44461
|
+
} catch (error2) {
|
|
44462
|
+
const err = error2;
|
|
44463
|
+
if (err.code === "ENOENT") {
|
|
44464
|
+
skippedFiles++;
|
|
44465
|
+
continue;
|
|
44466
|
+
}
|
|
44076
44467
|
skippedFiles++;
|
|
44468
|
+
incompleteFiles++;
|
|
44469
|
+
recordIncompletePath(incompletePaths, canonicalRoot, resolvedPath, "read_error");
|
|
44077
44470
|
continue;
|
|
44078
44471
|
}
|
|
44079
|
-
|
|
44080
|
-
|
|
44081
|
-
|
|
44082
|
-
|
|
44083
|
-
|
|
44084
|
-
|
|
44472
|
+
if (!isPathWithinScope(scanPath, canonicalRoot)) {
|
|
44473
|
+
skippedFiles++;
|
|
44474
|
+
incompleteFiles++;
|
|
44475
|
+
recordIncompletePath(incompletePaths, canonicalRoot, scanPath, "scope_escape");
|
|
44476
|
+
continue;
|
|
44477
|
+
}
|
|
44478
|
+
const outcome = scanFileForSecrets(scanPath, "explicit");
|
|
44479
|
+
switch (outcome.status) {
|
|
44480
|
+
case "scanned":
|
|
44481
|
+
filesScanned++;
|
|
44482
|
+
findings.push(...outcome.findings);
|
|
44483
|
+
if (findings.length > MAX_FINDINGS2)
|
|
44484
|
+
findings.length = MAX_FINDINGS2;
|
|
44485
|
+
break;
|
|
44486
|
+
case "skipped":
|
|
44487
|
+
skippedFiles++;
|
|
44488
|
+
break;
|
|
44489
|
+
case "incomplete":
|
|
44490
|
+
skippedFiles++;
|
|
44491
|
+
incompleteFiles++;
|
|
44492
|
+
recordIncompletePath(incompletePaths, canonicalRoot, scanPath, outcome.reason);
|
|
44493
|
+
break;
|
|
44494
|
+
default:
|
|
44495
|
+
assertNever(outcome);
|
|
44496
|
+
}
|
|
44497
|
+
if (index + 1 < filesToScan.length) {
|
|
44498
|
+
await _internals64.yieldToEventLoop();
|
|
44085
44499
|
}
|
|
44086
44500
|
}
|
|
44087
44501
|
findings.sort((a, b) => {
|
|
@@ -44096,7 +44510,9 @@ async function runSecretscanOnFiles(files, directory) {
|
|
|
44096
44510
|
findings,
|
|
44097
44511
|
count: findings.length,
|
|
44098
44512
|
files_scanned: filesScanned,
|
|
44099
|
-
skipped_files: skippedFiles
|
|
44513
|
+
skipped_files: skippedFiles,
|
|
44514
|
+
incomplete_files: incompleteFiles,
|
|
44515
|
+
incomplete_paths: incompletePaths
|
|
44100
44516
|
};
|
|
44101
44517
|
} catch (e) {
|
|
44102
44518
|
return {
|
|
@@ -44113,7 +44529,15 @@ var _internals64 = {
|
|
|
44113
44529
|
secretscan,
|
|
44114
44530
|
runSecretscan,
|
|
44115
44531
|
runSecretscanOnFiles,
|
|
44116
|
-
SECRET_PATTERNS: SECRET_PATTERNS2
|
|
44532
|
+
SECRET_PATTERNS: SECRET_PATTERNS2,
|
|
44533
|
+
now: Date.now,
|
|
44534
|
+
yieldToEventLoop,
|
|
44535
|
+
openFile: fs31.openSync,
|
|
44536
|
+
fstatFile: fs31.fstatSync,
|
|
44537
|
+
readFileChunk: fs31.readSync,
|
|
44538
|
+
closeFile: fs31.closeSync,
|
|
44539
|
+
lstatFile: fs31.lstatSync,
|
|
44540
|
+
closeDirectory: (directory) => directory.closeSync()
|
|
44117
44541
|
};
|
|
44118
44542
|
|
|
44119
44543
|
// src/tools/test-runner.ts
|
|
@@ -45362,21 +45786,21 @@ function hasCompoundTestExtension(filename) {
|
|
|
45362
45786
|
const lower = filename.toLowerCase();
|
|
45363
45787
|
return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
45364
45788
|
}
|
|
45365
|
-
function isLanguageSpecificTestFile(
|
|
45366
|
-
const lower =
|
|
45789
|
+
function isLanguageSpecificTestFile(basename16) {
|
|
45790
|
+
const lower = basename16.toLowerCase();
|
|
45367
45791
|
if (lower.endsWith("_test.go"))
|
|
45368
45792
|
return true;
|
|
45369
45793
|
if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
|
|
45370
45794
|
return true;
|
|
45371
45795
|
if (lower.endsWith("_spec.rb"))
|
|
45372
45796
|
return true;
|
|
45373
|
-
if (lower.endsWith(".java") && (/^Test[A-Z]/.test(
|
|
45797
|
+
if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename16) || basename16.endsWith("Test.java") || basename16.endsWith("Tests.java") || lower.endsWith("it.java")))
|
|
45374
45798
|
return true;
|
|
45375
45799
|
if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
|
|
45376
45800
|
return true;
|
|
45377
|
-
if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(
|
|
45801
|
+
if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename16) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
|
|
45378
45802
|
return true;
|
|
45379
|
-
if (lower.endsWith(".php") && (/^Test[A-Z]/.test(
|
|
45803
|
+
if (lower.endsWith(".php") && (/^Test[A-Z]/.test(basename16) || basename16.endsWith("Test.php") || basename16.endsWith("Tests.php")))
|
|
45380
45804
|
return true;
|
|
45381
45805
|
if (lower.endsWith(".tests.ps1"))
|
|
45382
45806
|
return true;
|
|
@@ -45384,23 +45808,23 @@ function isLanguageSpecificTestFile(basename15) {
|
|
|
45384
45808
|
}
|
|
45385
45809
|
function isConventionTestFilePath(filePath) {
|
|
45386
45810
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
45387
|
-
const
|
|
45388
|
-
return hasCompoundTestExtension(
|
|
45811
|
+
const basename16 = path81.basename(filePath);
|
|
45812
|
+
return hasCompoundTestExtension(basename16) || basename16.includes(".spec.") || basename16.includes(".test.") || isLanguageSpecificTestFile(basename16) || isTestDirectoryPath(normalizedPath);
|
|
45389
45813
|
}
|
|
45390
45814
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
45391
45815
|
const testFiles = [];
|
|
45392
45816
|
for (const file of sourceFiles) {
|
|
45393
45817
|
const absoluteFile = resolveWorkspacePath(file, workingDir);
|
|
45394
45818
|
const relativeFile = path81.relative(workingDir, absoluteFile);
|
|
45395
|
-
const
|
|
45819
|
+
const basename16 = path81.basename(absoluteFile);
|
|
45396
45820
|
const dirname30 = path81.dirname(absoluteFile);
|
|
45397
45821
|
const preferRelativeOutput = !path81.isAbsolute(file);
|
|
45398
45822
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
|
|
45399
45823
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
45400
45824
|
continue;
|
|
45401
45825
|
}
|
|
45402
|
-
const nameWithoutExt =
|
|
45403
|
-
const ext = path81.extname(
|
|
45826
|
+
const nameWithoutExt = basename16.replace(/\.[^.]+$/, "");
|
|
45827
|
+
const ext = path81.extname(basename16);
|
|
45404
45828
|
const genericTestNames = [
|
|
45405
45829
|
`${nameWithoutExt}.spec${ext}`,
|
|
45406
45830
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -45411,7 +45835,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
45411
45835
|
...languageSpecificTestNames
|
|
45412
45836
|
].map((candidateName) => path81.join(dirname30, candidateName));
|
|
45413
45837
|
const testDirectoryNames = [
|
|
45414
|
-
|
|
45838
|
+
basename16,
|
|
45415
45839
|
...genericTestNames,
|
|
45416
45840
|
...languageSpecificTestNames
|
|
45417
45841
|
];
|
|
@@ -46782,6 +47206,13 @@ var DEFAULT_CONFIG = {
|
|
|
46782
47206
|
testScope: "convention",
|
|
46783
47207
|
linter: "biome"
|
|
46784
47208
|
};
|
|
47209
|
+
function formatSecretscanIncompletePaths(incompletePaths, maxEntries = 3) {
|
|
47210
|
+
const visible = incompletePaths.slice(0, maxEntries).map((entry) => {
|
|
47211
|
+
return `${entry.path} (${entry.reason})`;
|
|
47212
|
+
});
|
|
47213
|
+
const suffix = incompletePaths.length > maxEntries ? ` (+${incompletePaths.length - maxEntries} more)` : "";
|
|
47214
|
+
return `${visible.join("; ")}${suffix}`;
|
|
47215
|
+
}
|
|
46785
47216
|
function validateDirectoryPath(dir) {
|
|
46786
47217
|
if (!dir || typeof dir !== "string") {
|
|
46787
47218
|
throw new Error("Directory path is required");
|
|
@@ -47045,28 +47476,72 @@ async function runTestsCheck(_dir, scope, timeoutMs) {
|
|
|
47045
47476
|
async function runSecretsCheck(dir, timeoutMs) {
|
|
47046
47477
|
const startTime = Date.now();
|
|
47047
47478
|
try {
|
|
47048
|
-
const secretsPromise = runSecretscan(dir);
|
|
47479
|
+
const secretsPromise = _internals68.runSecretscan(dir);
|
|
47049
47480
|
const timeoutPromise = new Promise((_, reject) => {
|
|
47050
47481
|
setTimeout(() => {
|
|
47051
47482
|
reject(new Error(`Secrets check timed out after ${timeoutMs}ms`));
|
|
47052
47483
|
}, timeoutMs);
|
|
47053
47484
|
});
|
|
47054
|
-
const result = await Promise.race([
|
|
47055
|
-
|
|
47056
|
-
|
|
47057
|
-
|
|
47058
|
-
|
|
47485
|
+
const result = await Promise.race([secretsPromise, timeoutPromise]);
|
|
47486
|
+
if ("error" in result) {
|
|
47487
|
+
return {
|
|
47488
|
+
type: "secrets",
|
|
47489
|
+
status: "fail",
|
|
47490
|
+
message: `Secrets check failed: ${result.error}`,
|
|
47491
|
+
details: {
|
|
47492
|
+
error: result.error,
|
|
47493
|
+
filesScanned: result.files_scanned,
|
|
47494
|
+
incompleteFiles: 0,
|
|
47495
|
+
incompletePaths: []
|
|
47496
|
+
},
|
|
47497
|
+
durationMs: Date.now() - startTime
|
|
47498
|
+
};
|
|
47499
|
+
}
|
|
47500
|
+
const findingsCount = Math.max(result.count, result.findings.length);
|
|
47501
|
+
if (typeof result.incomplete_files !== "number" || !Array.isArray(result.incomplete_paths)) {
|
|
47502
|
+
return {
|
|
47503
|
+
type: "secrets",
|
|
47504
|
+
status: "fail",
|
|
47505
|
+
message: "Secrets check failed: scanner returned incomplete coverage metadata",
|
|
47506
|
+
details: { filesScanned: result.files_scanned },
|
|
47507
|
+
durationMs: Date.now() - startTime
|
|
47508
|
+
};
|
|
47509
|
+
}
|
|
47510
|
+
const incompleteFiles = result.incomplete_files;
|
|
47511
|
+
const incompletePaths = result.incomplete_paths;
|
|
47512
|
+
const hasCountMismatch = result.count !== result.findings.length;
|
|
47513
|
+
const hasIncompleteCoverage = incompleteFiles > 0 || incompletePaths.length > 0;
|
|
47514
|
+
const hasZeroCoverage = result.files_scanned === 0;
|
|
47515
|
+
const failures = [];
|
|
47516
|
+
if (findingsCount > 0) {
|
|
47059
47517
|
const critical = result.findings.filter((f) => f.severity === "critical").length;
|
|
47060
47518
|
const high = result.findings.filter((f) => f.severity === "high").length;
|
|
47519
|
+
failures.push(`Found ${findingsCount} secret(s): ${critical} critical, ${high} high`);
|
|
47520
|
+
}
|
|
47521
|
+
if (hasIncompleteCoverage) {
|
|
47522
|
+
const incompleteSummary = incompletePaths.length > 0 ? `; incomplete paths: ${formatSecretscanIncompletePaths(incompletePaths)}` : "";
|
|
47523
|
+
failures.push(`${incompleteFiles} incomplete file(s)${incompleteSummary}`);
|
|
47524
|
+
}
|
|
47525
|
+
if (hasCountMismatch) {
|
|
47526
|
+
failures.push(`findings/count mismatch (reported ${result.count}, actual ${result.findings.length})`);
|
|
47527
|
+
}
|
|
47528
|
+
if (hasZeroCoverage) {
|
|
47529
|
+
failures.push("zero requested files scanned");
|
|
47530
|
+
}
|
|
47531
|
+
if (failures.length > 0) {
|
|
47061
47532
|
return {
|
|
47062
47533
|
type: "secrets",
|
|
47063
47534
|
status: "fail",
|
|
47064
|
-
message: `
|
|
47535
|
+
message: `Secrets check failed: ${failures.join("; ")}`,
|
|
47065
47536
|
details: {
|
|
47066
|
-
count:
|
|
47067
|
-
|
|
47068
|
-
|
|
47069
|
-
|
|
47537
|
+
count: findingsCount,
|
|
47538
|
+
reportedCount: result.count,
|
|
47539
|
+
critical: result.findings.filter((f) => f.severity === "critical").length,
|
|
47540
|
+
high: result.findings.filter((f) => f.severity === "high").length,
|
|
47541
|
+
filesScanned: result.files_scanned,
|
|
47542
|
+
skippedFiles: result.skipped_files,
|
|
47543
|
+
incompleteFiles,
|
|
47544
|
+
incompletePaths
|
|
47070
47545
|
},
|
|
47071
47546
|
durationMs: Date.now() - startTime
|
|
47072
47547
|
};
|
|
@@ -47076,7 +47551,10 @@ async function runSecretsCheck(dir, timeoutMs) {
|
|
|
47076
47551
|
status: "pass",
|
|
47077
47552
|
message: "No secrets detected",
|
|
47078
47553
|
details: {
|
|
47079
|
-
filesScanned: result.files_scanned
|
|
47554
|
+
filesScanned: result.files_scanned,
|
|
47555
|
+
skippedFiles: result.skipped_files,
|
|
47556
|
+
incompleteFiles,
|
|
47557
|
+
incompletePaths
|
|
47080
47558
|
},
|
|
47081
47559
|
durationMs: Date.now() - startTime
|
|
47082
47560
|
};
|
|
@@ -47404,6 +47882,7 @@ var _internals68 = {
|
|
|
47404
47882
|
runVersionCheck,
|
|
47405
47883
|
runLintCheck,
|
|
47406
47884
|
runTestsCheck,
|
|
47885
|
+
runSecretscan,
|
|
47407
47886
|
runSecretsCheck,
|
|
47408
47887
|
runEvidenceCheck,
|
|
47409
47888
|
runRequirementCoverageCheck
|
|
@@ -52403,7 +52882,7 @@ import {
|
|
|
52403
52882
|
openSync as openSync12,
|
|
52404
52883
|
readFileSync as readFileSync39,
|
|
52405
52884
|
renameSync as renameSync18,
|
|
52406
|
-
statSync as
|
|
52885
|
+
statSync as statSync15,
|
|
52407
52886
|
unlinkSync as unlinkSync20,
|
|
52408
52887
|
writeFileSync as writeFileSync17,
|
|
52409
52888
|
writeFileSync as writeFileSyncAsync
|
|
@@ -52493,7 +52972,7 @@ var _internals78 = {
|
|
|
52493
52972
|
renameSync: renameSync18,
|
|
52494
52973
|
unlinkSync: unlinkSync20,
|
|
52495
52974
|
existsSync: existsSync53,
|
|
52496
|
-
statSync:
|
|
52975
|
+
statSync: statSync15
|
|
52497
52976
|
};
|
|
52498
52977
|
async function appendEvent(directory, eventInput) {
|
|
52499
52978
|
if (!isValidSkillSlug(eventInput.skillSlug)) {
|
|
@@ -55596,7 +56075,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
55596
56075
|
async function handleHelpCommand(ctx) {
|
|
55597
56076
|
const targetCommand = ctx.args.join(" ");
|
|
55598
56077
|
if (!targetCommand) {
|
|
55599
|
-
const { buildHelpText } = await import("./index-
|
|
56078
|
+
const { buildHelpText } = await import("./index-s7ac0xrf.js");
|
|
55600
56079
|
return buildHelpText();
|
|
55601
56080
|
}
|
|
55602
56081
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -55605,7 +56084,7 @@ async function handleHelpCommand(ctx) {
|
|
|
55605
56084
|
return _internals14.buildDetailedHelp(resolved.key, resolved.entry);
|
|
55606
56085
|
}
|
|
55607
56086
|
const similar = _internals14.findSimilarCommands(targetCommand);
|
|
55608
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
56087
|
+
const { buildHelpText: fullHelp } = await import("./index-s7ac0xrf.js");
|
|
55609
56088
|
if (similar.length > 0) {
|
|
55610
56089
|
return `Command '/swarm ${targetCommand}' not found.
|
|
55611
56090
|
|
|
@@ -55782,7 +56261,7 @@ var COMMAND_REGISTRY = {
|
|
|
55782
56261
|
},
|
|
55783
56262
|
"guardrail explain": {
|
|
55784
56263
|
handler: async (ctx) => {
|
|
55785
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
56264
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-rks41rpx.js");
|
|
55786
56265
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
55787
56266
|
},
|
|
55788
56267
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -55792,7 +56271,7 @@ var COMMAND_REGISTRY = {
|
|
|
55792
56271
|
},
|
|
55793
56272
|
"guardrail-explain": {
|
|
55794
56273
|
handler: async (ctx) => {
|
|
55795
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
56274
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-rks41rpx.js");
|
|
55796
56275
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
55797
56276
|
},
|
|
55798
56277
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -55802,7 +56281,7 @@ var COMMAND_REGISTRY = {
|
|
|
55802
56281
|
},
|
|
55803
56282
|
"guardrail-log": {
|
|
55804
56283
|
handler: async (ctx) => {
|
|
55805
|
-
const { handleGuardrailLog } = await import("./guardrail-log-
|
|
56284
|
+
const { handleGuardrailLog } = await import("./guardrail-log-h39jxftx.js");
|
|
55806
56285
|
return handleGuardrailLog(ctx.directory, ctx.args);
|
|
55807
56286
|
},
|
|
55808
56287
|
description: "Read the guardrail decision log (use --blocks-only for blocks)",
|