opencode-swarm 7.26.1 → 7.27.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.
- package/dist/cli/index.js +37 -1
- package/dist/index.js +151 -60
- package/dist/plan/checkpoint.d.ts +10 -0
- package/dist/test-impact/failure-classifier.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -34,7 +34,7 @@ var package_default;
|
|
|
34
34
|
var init_package = __esm(() => {
|
|
35
35
|
package_default = {
|
|
36
36
|
name: "opencode-swarm",
|
|
37
|
-
version: "7.
|
|
37
|
+
version: "7.27.0",
|
|
38
38
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
39
39
|
main: "dist/index.js",
|
|
40
40
|
types: "dist/index.d.ts",
|
|
@@ -47117,10 +47117,31 @@ function stringHash(str) {
|
|
|
47117
47117
|
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
47118
47118
|
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16);
|
|
47119
47119
|
}
|
|
47120
|
+
function isInfrastructureFailure(currentResult) {
|
|
47121
|
+
const errorMessage = currentResult.errorMessage || "";
|
|
47122
|
+
const stackPrefix = currentResult.stackPrefix || "";
|
|
47123
|
+
if (/\bassertionerror\b/i.test(errorMessage)) {
|
|
47124
|
+
return false;
|
|
47125
|
+
}
|
|
47126
|
+
const combinedText = `${errorMessage}
|
|
47127
|
+
${stackPrefix}`;
|
|
47128
|
+
return INFRASTRUCTURE_FAILURE_PATTERNS.some((pattern) => pattern.test(combinedText));
|
|
47129
|
+
}
|
|
47120
47130
|
function classifyFailure(currentResult, history) {
|
|
47121
47131
|
const normalizedFile = currentResult.testFile.toLowerCase();
|
|
47122
47132
|
const normalizedName = currentResult.testName.toLowerCase();
|
|
47123
47133
|
const testHistory = history.filter((r) => r.testFile.toLowerCase() === normalizedFile && r.testName.toLowerCase() === normalizedName).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
47134
|
+
if (isInfrastructureFailure(currentResult)) {
|
|
47135
|
+
return {
|
|
47136
|
+
testFile: currentResult.testFile,
|
|
47137
|
+
testName: currentResult.testName,
|
|
47138
|
+
classification: "infrastructure_failure",
|
|
47139
|
+
errorMessage: currentResult.errorMessage,
|
|
47140
|
+
stackPrefix: currentResult.stackPrefix,
|
|
47141
|
+
durationMs: currentResult.durationMs,
|
|
47142
|
+
confidence: computeConfidence2(testHistory.length)
|
|
47143
|
+
};
|
|
47144
|
+
}
|
|
47124
47145
|
const lastThree = testHistory.slice(0, 3);
|
|
47125
47146
|
const lastTen = testHistory.slice(0, 10);
|
|
47126
47147
|
const normalizedTestFile = currentResult.testFile.toLowerCase();
|
|
@@ -47220,6 +47241,20 @@ function classifyAndCluster(testResults, history) {
|
|
|
47220
47241
|
const clusters = clusterFailures(classified);
|
|
47221
47242
|
return { classified, clusters };
|
|
47222
47243
|
}
|
|
47244
|
+
var MAX_INFRA_CONTEXT_CHARS = 80, INFRASTRUCTURE_FAILURE_PATTERNS;
|
|
47245
|
+
var init_failure_classifier = __esm(() => {
|
|
47246
|
+
INFRASTRUCTURE_FAILURE_PATTERNS = [
|
|
47247
|
+
/\boutofmemoryerror\b/i,
|
|
47248
|
+
/(?:^|\n|\bcommand failed:\s*)\s*killed(?:\s*(?:[-:]\s*)?(?:out of memory|oom|by signal|signal|sigkill).*)?\s*(?:\n|$)/i,
|
|
47249
|
+
/(?:^|\n)\s*etimedout\b/i,
|
|
47250
|
+
new RegExp(`\\b(?:connect|connection|request|socket|network)\\b[^\\n]{0,${MAX_INFRA_CONTEXT_CHARS}}\\betimedout\\b`, "i"),
|
|
47251
|
+
/(?:^|\n)\s*econnrefused\b/i,
|
|
47252
|
+
new RegExp(`\\b(?:connect|connection|socket)\\b[^\\n]{0,${MAX_INFRA_CONTEXT_CHARS}}\\beconnrefused\\b`, "i"),
|
|
47253
|
+
/(?:^|\n)\s*enotfound\b/i,
|
|
47254
|
+
new RegExp(`\\b(?:getaddrinfo|dns|lookup)\\b[^\\n]{0,${MAX_INFRA_CONTEXT_CHARS}}\\benotfound\\b`, "i"),
|
|
47255
|
+
/\bexit(?:ed)?(?:\s+with)?(?:\s+code)?\s*[:=]?\s*137\b/i
|
|
47256
|
+
];
|
|
47257
|
+
});
|
|
47223
47258
|
|
|
47224
47259
|
// src/test-impact/flaky-detector.ts
|
|
47225
47260
|
function detectFlakyTests(allHistory) {
|
|
@@ -48964,6 +48999,7 @@ var init_test_runner = __esm(() => {
|
|
|
48964
48999
|
init_zod();
|
|
48965
49000
|
init_discovery();
|
|
48966
49001
|
init_analyzer();
|
|
49002
|
+
init_failure_classifier();
|
|
48967
49003
|
init_history_store();
|
|
48968
49004
|
init_bun_compat();
|
|
48969
49005
|
init_path_security();
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var package_default;
|
|
|
33
33
|
var init_package = __esm(() => {
|
|
34
34
|
package_default = {
|
|
35
35
|
name: "opencode-swarm",
|
|
36
|
-
version: "7.
|
|
36
|
+
version: "7.27.0",
|
|
37
37
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
38
38
|
main: "dist/index.js",
|
|
39
39
|
types: "dist/index.d.ts",
|
|
@@ -57509,10 +57509,31 @@ function stringHash(str) {
|
|
|
57509
57509
|
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
57510
57510
|
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16);
|
|
57511
57511
|
}
|
|
57512
|
+
function isInfrastructureFailure(currentResult) {
|
|
57513
|
+
const errorMessage = currentResult.errorMessage || "";
|
|
57514
|
+
const stackPrefix = currentResult.stackPrefix || "";
|
|
57515
|
+
if (/\bassertionerror\b/i.test(errorMessage)) {
|
|
57516
|
+
return false;
|
|
57517
|
+
}
|
|
57518
|
+
const combinedText = `${errorMessage}
|
|
57519
|
+
${stackPrefix}`;
|
|
57520
|
+
return INFRASTRUCTURE_FAILURE_PATTERNS.some((pattern) => pattern.test(combinedText));
|
|
57521
|
+
}
|
|
57512
57522
|
function classifyFailure(currentResult, history) {
|
|
57513
57523
|
const normalizedFile = currentResult.testFile.toLowerCase();
|
|
57514
57524
|
const normalizedName = currentResult.testName.toLowerCase();
|
|
57515
57525
|
const testHistory = history.filter((r) => r.testFile.toLowerCase() === normalizedFile && r.testName.toLowerCase() === normalizedName).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
57526
|
+
if (isInfrastructureFailure(currentResult)) {
|
|
57527
|
+
return {
|
|
57528
|
+
testFile: currentResult.testFile,
|
|
57529
|
+
testName: currentResult.testName,
|
|
57530
|
+
classification: "infrastructure_failure",
|
|
57531
|
+
errorMessage: currentResult.errorMessage,
|
|
57532
|
+
stackPrefix: currentResult.stackPrefix,
|
|
57533
|
+
durationMs: currentResult.durationMs,
|
|
57534
|
+
confidence: computeConfidence2(testHistory.length)
|
|
57535
|
+
};
|
|
57536
|
+
}
|
|
57516
57537
|
const lastThree = testHistory.slice(0, 3);
|
|
57517
57538
|
const lastTen = testHistory.slice(0, 10);
|
|
57518
57539
|
const normalizedTestFile = currentResult.testFile.toLowerCase();
|
|
@@ -57612,6 +57633,20 @@ function classifyAndCluster(testResults, history) {
|
|
|
57612
57633
|
const clusters = clusterFailures(classified);
|
|
57613
57634
|
return { classified, clusters };
|
|
57614
57635
|
}
|
|
57636
|
+
var MAX_INFRA_CONTEXT_CHARS = 80, INFRASTRUCTURE_FAILURE_PATTERNS;
|
|
57637
|
+
var init_failure_classifier = __esm(() => {
|
|
57638
|
+
INFRASTRUCTURE_FAILURE_PATTERNS = [
|
|
57639
|
+
/\boutofmemoryerror\b/i,
|
|
57640
|
+
/(?:^|\n|\bcommand failed:\s*)\s*killed(?:\s*(?:[-:]\s*)?(?:out of memory|oom|by signal|signal|sigkill).*)?\s*(?:\n|$)/i,
|
|
57641
|
+
/(?:^|\n)\s*etimedout\b/i,
|
|
57642
|
+
new RegExp(`\\b(?:connect|connection|request|socket|network)\\b[^\\n]{0,${MAX_INFRA_CONTEXT_CHARS}}\\betimedout\\b`, "i"),
|
|
57643
|
+
/(?:^|\n)\s*econnrefused\b/i,
|
|
57644
|
+
new RegExp(`\\b(?:connect|connection|socket)\\b[^\\n]{0,${MAX_INFRA_CONTEXT_CHARS}}\\beconnrefused\\b`, "i"),
|
|
57645
|
+
/(?:^|\n)\s*enotfound\b/i,
|
|
57646
|
+
new RegExp(`\\b(?:getaddrinfo|dns|lookup)\\b[^\\n]{0,${MAX_INFRA_CONTEXT_CHARS}}\\benotfound\\b`, "i"),
|
|
57647
|
+
/\bexit(?:ed)?(?:\s+with)?(?:\s+code)?\s*[:=]?\s*137\b/i
|
|
57648
|
+
];
|
|
57649
|
+
});
|
|
57615
57650
|
|
|
57616
57651
|
// src/test-impact/flaky-detector.ts
|
|
57617
57652
|
function detectFlakyTests(allHistory) {
|
|
@@ -59356,6 +59391,7 @@ var init_test_runner = __esm(() => {
|
|
|
59356
59391
|
init_zod();
|
|
59357
59392
|
init_discovery();
|
|
59358
59393
|
init_analyzer();
|
|
59394
|
+
init_failure_classifier();
|
|
59359
59395
|
init_history_store();
|
|
59360
59396
|
init_bun_compat();
|
|
59361
59397
|
init_path_security();
|
|
@@ -73572,7 +73608,7 @@ var init_curator_drift = __esm(() => {
|
|
|
73572
73608
|
var exports_project_context = {};
|
|
73573
73609
|
__export(exports_project_context, {
|
|
73574
73610
|
buildProjectContext: () => buildProjectContext,
|
|
73575
|
-
_internals: () =>
|
|
73611
|
+
_internals: () => _internals57,
|
|
73576
73612
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
73577
73613
|
});
|
|
73578
73614
|
import * as fs112 from "node:fs";
|
|
@@ -73656,7 +73692,7 @@ function selectLintCommand(backend, directory) {
|
|
|
73656
73692
|
return null;
|
|
73657
73693
|
}
|
|
73658
73694
|
async function buildProjectContext(directory) {
|
|
73659
|
-
const backend = await
|
|
73695
|
+
const backend = await _internals57.pickBackend(directory);
|
|
73660
73696
|
if (!backend)
|
|
73661
73697
|
return null;
|
|
73662
73698
|
const ctx = emptyProjectContext();
|
|
@@ -73687,16 +73723,16 @@ async function buildProjectContext(directory) {
|
|
|
73687
73723
|
if (backend.prompts.reviewerChecklist.length > 0) {
|
|
73688
73724
|
ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
|
|
73689
73725
|
}
|
|
73690
|
-
const profiles =
|
|
73726
|
+
const profiles = _internals57.pickedProfiles(directory);
|
|
73691
73727
|
if (profiles.length > 1) {
|
|
73692
73728
|
ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
|
|
73693
73729
|
}
|
|
73694
73730
|
return ctx;
|
|
73695
73731
|
}
|
|
73696
|
-
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300,
|
|
73732
|
+
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals57;
|
|
73697
73733
|
var init_project_context = __esm(() => {
|
|
73698
73734
|
init_dispatch();
|
|
73699
|
-
|
|
73735
|
+
_internals57 = {
|
|
73700
73736
|
pickBackend,
|
|
73701
73737
|
pickedProfiles
|
|
73702
73738
|
};
|
|
@@ -92261,10 +92297,61 @@ async function writeCheckpoint(directory) {
|
|
|
92261
92297
|
fs81.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
92262
92298
|
const md = derivePlanMarkdown(plan);
|
|
92263
92299
|
fs81.writeFileSync(mdPath, md, "utf8");
|
|
92300
|
+
for (const legacyPath of [
|
|
92301
|
+
path108.join(directory, "SWARM_PLAN.json"),
|
|
92302
|
+
path108.join(directory, "SWARM_PLAN.md")
|
|
92303
|
+
]) {
|
|
92304
|
+
try {
|
|
92305
|
+
if (_internals43.existsSyncForCleanup(legacyPath)) {
|
|
92306
|
+
_internals43.unlinkSyncForCleanup(legacyPath);
|
|
92307
|
+
}
|
|
92308
|
+
} catch {}
|
|
92309
|
+
}
|
|
92264
92310
|
} catch (error93) {
|
|
92265
92311
|
console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
92266
92312
|
}
|
|
92267
92313
|
}
|
|
92314
|
+
async function importCheckpoint(directory, source) {
|
|
92315
|
+
try {
|
|
92316
|
+
const swarmDirPath = path108.join(directory, ".swarm", "SWARM_PLAN.json");
|
|
92317
|
+
const rootPath = path108.join(directory, "SWARM_PLAN.json");
|
|
92318
|
+
let checkpointPath;
|
|
92319
|
+
let rawContent;
|
|
92320
|
+
if (fs81.existsSync(swarmDirPath)) {
|
|
92321
|
+
checkpointPath = swarmDirPath;
|
|
92322
|
+
rawContent = fs81.readFileSync(checkpointPath, "utf8");
|
|
92323
|
+
} else if (fs81.existsSync(rootPath)) {
|
|
92324
|
+
checkpointPath = rootPath;
|
|
92325
|
+
rawContent = fs81.readFileSync(checkpointPath, "utf8");
|
|
92326
|
+
console.warn("[checkpoint] importCheckpoint: using legacy root-level SWARM_PLAN.json. Consider running /swarm close to migrate.");
|
|
92327
|
+
} else {
|
|
92328
|
+
return {
|
|
92329
|
+
success: false,
|
|
92330
|
+
error: "SWARM_PLAN.json not found in .swarm/ or project root"
|
|
92331
|
+
};
|
|
92332
|
+
}
|
|
92333
|
+
const parsed = JSON.parse(rawContent);
|
|
92334
|
+
const plan = PlanSchema.parse(parsed);
|
|
92335
|
+
await savePlanWithAutoAcknowledgedRemovals(directory, plan, "import_checkpoint", "import external checkpoint");
|
|
92336
|
+
await appendLedgerEvent(directory, {
|
|
92337
|
+
event_type: "plan_rebuilt",
|
|
92338
|
+
source: source ?? "external_reseed",
|
|
92339
|
+
plan_id: derivePlanId(plan)
|
|
92340
|
+
});
|
|
92341
|
+
return { success: true, plan };
|
|
92342
|
+
} catch (error93) {
|
|
92343
|
+
return {
|
|
92344
|
+
success: false,
|
|
92345
|
+
error: error93 instanceof Error ? error93.message : String(error93)
|
|
92346
|
+
};
|
|
92347
|
+
}
|
|
92348
|
+
}
|
|
92349
|
+
var _internals43 = {
|
|
92350
|
+
writeCheckpoint,
|
|
92351
|
+
importCheckpoint,
|
|
92352
|
+
existsSyncForCleanup: fs81.existsSync,
|
|
92353
|
+
unlinkSyncForCleanup: fs81.unlinkSync
|
|
92354
|
+
};
|
|
92268
92355
|
|
|
92269
92356
|
// src/tools/phase-complete.ts
|
|
92270
92357
|
init_ledger();
|
|
@@ -92467,7 +92554,7 @@ function listLaneEvidenceSync(directory, phase) {
|
|
|
92467
92554
|
}
|
|
92468
92555
|
return laneIds;
|
|
92469
92556
|
}
|
|
92470
|
-
var
|
|
92557
|
+
var _internals44 = {
|
|
92471
92558
|
listActiveLocks,
|
|
92472
92559
|
readPersisted: readPersisted2,
|
|
92473
92560
|
readPlanJson: defaultReadPlanJson,
|
|
@@ -92528,7 +92615,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92528
92615
|
reason: "Lean Turbo state unreadable or missing"
|
|
92529
92616
|
};
|
|
92530
92617
|
}
|
|
92531
|
-
const persisted =
|
|
92618
|
+
const persisted = _internals44.readPersisted(directory);
|
|
92532
92619
|
if (!persisted) {
|
|
92533
92620
|
return {
|
|
92534
92621
|
ok: false,
|
|
@@ -92592,7 +92679,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92592
92679
|
}
|
|
92593
92680
|
}
|
|
92594
92681
|
if (runState.lanes.length > 0) {
|
|
92595
|
-
const evidenceLaneIds = new Set(
|
|
92682
|
+
const evidenceLaneIds = new Set(_internals44.listLaneEvidenceSync(directory, phase));
|
|
92596
92683
|
for (const lane of runState.lanes) {
|
|
92597
92684
|
if ((lane.status === "completed" || lane.status === "failed") && !evidenceLaneIds.has(lane.laneId)) {
|
|
92598
92685
|
return {
|
|
@@ -92602,7 +92689,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92602
92689
|
}
|
|
92603
92690
|
}
|
|
92604
92691
|
}
|
|
92605
|
-
const activeLocks =
|
|
92692
|
+
const activeLocks = _internals44.listActiveLocks(directory);
|
|
92606
92693
|
const phaseLaneIds = new Set(laneIds);
|
|
92607
92694
|
for (const lock of activeLocks) {
|
|
92608
92695
|
if (lock.laneId && phaseLaneIds.has(lock.laneId)) {
|
|
@@ -92622,7 +92709,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92622
92709
|
}
|
|
92623
92710
|
const serialDegradedTasks = runState.degradedTasks.filter((dt) => !laneTaskIds.has(dt.taskId));
|
|
92624
92711
|
if (serialDegradedTasks.length > 0) {
|
|
92625
|
-
const plan =
|
|
92712
|
+
const plan = _internals44.readPlanJson(directory);
|
|
92626
92713
|
if (!plan) {
|
|
92627
92714
|
return {
|
|
92628
92715
|
ok: false,
|
|
@@ -92666,7 +92753,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92666
92753
|
}
|
|
92667
92754
|
const serializedTasks = runState.serializedTasks;
|
|
92668
92755
|
if (Array.isArray(serializedTasks) && serializedTasks.length > 0) {
|
|
92669
|
-
const plan =
|
|
92756
|
+
const plan = _internals44.readPlanJson(directory);
|
|
92670
92757
|
if (!plan) {
|
|
92671
92758
|
return {
|
|
92672
92759
|
ok: false,
|
|
@@ -92725,7 +92812,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92725
92812
|
}
|
|
92726
92813
|
let reviewerVerdict = runState.lastReviewerVerdict;
|
|
92727
92814
|
if (!reviewerVerdict) {
|
|
92728
|
-
const evidence =
|
|
92815
|
+
const evidence = _internals44.readReviewerEvidence(directory, phase);
|
|
92729
92816
|
reviewerVerdict = evidence?.verdict ?? undefined;
|
|
92730
92817
|
}
|
|
92731
92818
|
if (mergedConfig.phase_reviewer) {
|
|
@@ -92738,7 +92825,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
92738
92825
|
}
|
|
92739
92826
|
let criticVerdict = runState.lastCriticVerdict;
|
|
92740
92827
|
if (!criticVerdict) {
|
|
92741
|
-
const evidence =
|
|
92828
|
+
const evidence = _internals44.readCriticEvidence(directory, phase);
|
|
92742
92829
|
criticVerdict = evidence?.verdict ?? undefined;
|
|
92743
92830
|
}
|
|
92744
92831
|
if (mergedConfig.phase_critic) {
|
|
@@ -93661,7 +93748,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
93661
93748
|
phase_critic: leanConfig.phase_critic,
|
|
93662
93749
|
integrated_diff_required: leanConfig.integrated_diff_required
|
|
93663
93750
|
} : undefined;
|
|
93664
|
-
const leanCheck =
|
|
93751
|
+
const leanCheck = _internals44.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
|
|
93665
93752
|
if (!leanCheck.ok) {
|
|
93666
93753
|
return JSON.stringify({
|
|
93667
93754
|
success: false,
|
|
@@ -95849,11 +95936,11 @@ var quality_budget = createSwarmTool({
|
|
|
95849
95936
|
}).optional().describe("Quality budget thresholds")
|
|
95850
95937
|
},
|
|
95851
95938
|
async execute(args2, directory) {
|
|
95852
|
-
const result = await
|
|
95939
|
+
const result = await _internals45.qualityBudget(args2, directory);
|
|
95853
95940
|
return JSON.stringify(result);
|
|
95854
95941
|
}
|
|
95855
95942
|
});
|
|
95856
|
-
var
|
|
95943
|
+
var _internals45 = {
|
|
95857
95944
|
qualityBudget
|
|
95858
95945
|
};
|
|
95859
95946
|
|
|
@@ -96582,7 +96669,7 @@ import * as path114 from "node:path";
|
|
|
96582
96669
|
var semgrepAvailableCache = null;
|
|
96583
96670
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
96584
96671
|
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
96585
|
-
var
|
|
96672
|
+
var _internals46 = {
|
|
96586
96673
|
isSemgrepAvailable,
|
|
96587
96674
|
checkSemgrepAvailable,
|
|
96588
96675
|
resetSemgrepCache,
|
|
@@ -96607,7 +96694,7 @@ function isSemgrepAvailable() {
|
|
|
96607
96694
|
}
|
|
96608
96695
|
}
|
|
96609
96696
|
async function checkSemgrepAvailable() {
|
|
96610
|
-
return
|
|
96697
|
+
return _internals46.isSemgrepAvailable();
|
|
96611
96698
|
}
|
|
96612
96699
|
function resetSemgrepCache() {
|
|
96613
96700
|
semgrepAvailableCache = null;
|
|
@@ -96704,12 +96791,12 @@ async function runSemgrep(options) {
|
|
|
96704
96791
|
const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS3;
|
|
96705
96792
|
if (files.length === 0) {
|
|
96706
96793
|
return {
|
|
96707
|
-
available:
|
|
96794
|
+
available: _internals46.isSemgrepAvailable(),
|
|
96708
96795
|
findings: [],
|
|
96709
96796
|
engine: "tier_a"
|
|
96710
96797
|
};
|
|
96711
96798
|
}
|
|
96712
|
-
if (!
|
|
96799
|
+
if (!_internals46.isSemgrepAvailable()) {
|
|
96713
96800
|
return {
|
|
96714
96801
|
available: false,
|
|
96715
96802
|
findings: [],
|
|
@@ -96868,7 +96955,7 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
96868
96955
|
}
|
|
96869
96956
|
const occIdx = countMap.get(baseKey) ?? 0;
|
|
96870
96957
|
countMap.set(baseKey, occIdx + 1);
|
|
96871
|
-
const fp =
|
|
96958
|
+
const fp = _internals47.fingerprintFinding(finding, directory, occIdx);
|
|
96872
96959
|
return {
|
|
96873
96960
|
finding,
|
|
96874
96961
|
index: occIdx,
|
|
@@ -96937,7 +97024,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
96937
97024
|
}
|
|
96938
97025
|
} catch {}
|
|
96939
97026
|
const scannedRelFiles = new Set(scannedFiles.map((f) => normalizeFindingPath(directory, f)));
|
|
96940
|
-
const indexed =
|
|
97027
|
+
const indexed = _internals47.assignOccurrenceIndices(findings, directory);
|
|
96941
97028
|
if (existing && !opts?.force) {
|
|
96942
97029
|
const prunedFingerprints = existing.fingerprints.filter((fp) => {
|
|
96943
97030
|
const relFile = fp.slice(0, fp.indexOf("|"));
|
|
@@ -97077,7 +97164,7 @@ function loadBaseline(directory, phase) {
|
|
|
97077
97164
|
};
|
|
97078
97165
|
}
|
|
97079
97166
|
}
|
|
97080
|
-
var
|
|
97167
|
+
var _internals47 = {
|
|
97081
97168
|
fingerprintFinding,
|
|
97082
97169
|
assignOccurrenceIndices,
|
|
97083
97170
|
captureOrMergeBaseline,
|
|
@@ -97487,11 +97574,11 @@ var sast_scan = createSwarmTool({
|
|
|
97487
97574
|
capture_baseline: safeArgs.capture_baseline,
|
|
97488
97575
|
phase: safeArgs.phase
|
|
97489
97576
|
};
|
|
97490
|
-
const result = await
|
|
97577
|
+
const result = await _internals48.sastScan(input, directory);
|
|
97491
97578
|
return JSON.stringify(result, null, 2);
|
|
97492
97579
|
}
|
|
97493
97580
|
});
|
|
97494
|
-
var
|
|
97581
|
+
var _internals48 = {
|
|
97495
97582
|
sastScan,
|
|
97496
97583
|
sast_scan
|
|
97497
97584
|
};
|
|
@@ -101403,7 +101490,7 @@ import {
|
|
|
101403
101490
|
mkdirSync as mkdirSync31,
|
|
101404
101491
|
readFileSync as readFileSync63,
|
|
101405
101492
|
renameSync as renameSync20,
|
|
101406
|
-
unlinkSync as
|
|
101493
|
+
unlinkSync as unlinkSync16,
|
|
101407
101494
|
writeFileSync as writeFileSync25
|
|
101408
101495
|
} from "node:fs";
|
|
101409
101496
|
import path125 from "node:path";
|
|
@@ -101637,7 +101724,7 @@ function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
|
101637
101724
|
renameSync20(tempFile, evidenceFile);
|
|
101638
101725
|
} finally {
|
|
101639
101726
|
if (existsSync72(tempFile)) {
|
|
101640
|
-
|
|
101727
|
+
unlinkSync16(tempFile);
|
|
101641
101728
|
}
|
|
101642
101729
|
}
|
|
101643
101730
|
}
|
|
@@ -102006,6 +102093,10 @@ var suggestPatch = createSwarmTool({
|
|
|
102006
102093
|
}, null, 2);
|
|
102007
102094
|
}
|
|
102008
102095
|
});
|
|
102096
|
+
|
|
102097
|
+
// src/tools/index.ts
|
|
102098
|
+
init_failure_classifier();
|
|
102099
|
+
|
|
102009
102100
|
// src/tools/generate-mutants.ts
|
|
102010
102101
|
init_zod();
|
|
102011
102102
|
|
|
@@ -102815,7 +102906,7 @@ function resolveDefaultReviewerAgent(generatedAgentNames) {
|
|
|
102815
102906
|
}
|
|
102816
102907
|
async function compileReviewPackage(directory, phase, sessionID, requireDiffSummary) {
|
|
102817
102908
|
const lanes = await listLaneEvidence(directory, phase);
|
|
102818
|
-
const persisted =
|
|
102909
|
+
const persisted = _internals49.readPersisted?.(directory) ?? null;
|
|
102819
102910
|
if (persisted) {
|
|
102820
102911
|
let matchingRunState = null;
|
|
102821
102912
|
for (const sessionState of Object.values(persisted.sessions)) {
|
|
@@ -103007,7 +103098,7 @@ Be specific and evidence-based. Do not approve a phase with unresolved degraded
|
|
|
103007
103098
|
client.session.delete({ path: { id: sessionId } }).catch(() => {});
|
|
103008
103099
|
}
|
|
103009
103100
|
}
|
|
103010
|
-
var
|
|
103101
|
+
var _internals49 = {
|
|
103011
103102
|
compileReviewPackage,
|
|
103012
103103
|
parseReviewerVerdict,
|
|
103013
103104
|
writeReviewerEvidence,
|
|
@@ -103024,28 +103115,28 @@ async function dispatchPhaseReviewer(directory, phase, sessionID, config3) {
|
|
|
103024
103115
|
};
|
|
103025
103116
|
const generatedAgentNames = swarmState.generatedAgentNames;
|
|
103026
103117
|
const agentName = mergedConfig.reviewerAgent || resolveDefaultReviewerAgent(generatedAgentNames);
|
|
103027
|
-
const pkg = await
|
|
103118
|
+
const pkg = await _internals49.compileReviewPackage(directory, phase, sessionID, mergedConfig.requireDiffSummary);
|
|
103028
103119
|
let responseText;
|
|
103029
103120
|
try {
|
|
103030
|
-
responseText = await
|
|
103121
|
+
responseText = await _internals49.dispatchReviewerAgent(directory, pkg, agentName, mergedConfig.timeoutMs);
|
|
103031
103122
|
} catch (error93) {
|
|
103032
|
-
const evidencePath2 = await
|
|
103123
|
+
const evidencePath2 = await _internals49.writeReviewerEvidence(directory, phase, "REJECTED", error93 instanceof Error ? error93.message : String(error93));
|
|
103033
103124
|
return {
|
|
103034
103125
|
verdict: "REJECTED",
|
|
103035
103126
|
reason: `Reviewer dispatch failed: ${error93 instanceof Error ? error93.message : String(error93)}`,
|
|
103036
103127
|
evidencePath: evidencePath2
|
|
103037
103128
|
};
|
|
103038
103129
|
}
|
|
103039
|
-
const parsed =
|
|
103130
|
+
const parsed = _internals49.parseReviewerVerdict(responseText);
|
|
103040
103131
|
if (!parsed) {
|
|
103041
|
-
const evidencePath2 = await
|
|
103132
|
+
const evidencePath2 = await _internals49.writeReviewerEvidence(directory, phase, "REJECTED", "Reviewer response could not be parsed");
|
|
103042
103133
|
return {
|
|
103043
103134
|
verdict: "REJECTED",
|
|
103044
103135
|
reason: "Reviewer response could not be parsed",
|
|
103045
103136
|
evidencePath: evidencePath2
|
|
103046
103137
|
};
|
|
103047
103138
|
}
|
|
103048
|
-
const evidencePath = await
|
|
103139
|
+
const evidencePath = await _internals49.writeReviewerEvidence(directory, phase, parsed.verdict, parsed.reason);
|
|
103049
103140
|
return {
|
|
103050
103141
|
verdict: parsed.verdict,
|
|
103051
103142
|
reason: parsed.reason,
|
|
@@ -103551,7 +103642,7 @@ ${fileList}
|
|
|
103551
103642
|
|
|
103552
103643
|
// src/tools/lean-turbo-run-phase.ts
|
|
103553
103644
|
init_create_tool();
|
|
103554
|
-
var
|
|
103645
|
+
var _internals50 = {
|
|
103555
103646
|
LeanTurboRunner,
|
|
103556
103647
|
loadPluginConfigWithMeta
|
|
103557
103648
|
};
|
|
@@ -103561,9 +103652,9 @@ async function executeLeanTurboRunPhase(args2) {
|
|
|
103561
103652
|
let runError = null;
|
|
103562
103653
|
let runner = null;
|
|
103563
103654
|
try {
|
|
103564
|
-
const { config: config3 } =
|
|
103655
|
+
const { config: config3 } = _internals50.loadPluginConfigWithMeta(directory);
|
|
103565
103656
|
const leanConfig = config3.turbo?.strategy === "lean" ? config3.turbo.lean : undefined;
|
|
103566
|
-
runner = new
|
|
103657
|
+
runner = new _internals50.LeanTurboRunner({
|
|
103567
103658
|
directory,
|
|
103568
103659
|
sessionID,
|
|
103569
103660
|
opencodeClient: swarmState.opencodeClient ?? null,
|
|
@@ -103844,7 +103935,7 @@ import * as path132 from "node:path";
|
|
|
103844
103935
|
|
|
103845
103936
|
// src/mutation/engine.ts
|
|
103846
103937
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
103847
|
-
import { unlinkSync as
|
|
103938
|
+
import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync26 } from "node:fs";
|
|
103848
103939
|
import * as path131 from "node:path";
|
|
103849
103940
|
|
|
103850
103941
|
// src/mutation/equivalence.ts
|
|
@@ -103917,7 +104008,7 @@ function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
|
103917
104008
|
const strippedMutated = stripCode(mutatedCode);
|
|
103918
104009
|
return strippedOriginal === strippedMutated;
|
|
103919
104010
|
}
|
|
103920
|
-
var
|
|
104011
|
+
var _internals51 = {
|
|
103921
104012
|
isStaticallyEquivalent,
|
|
103922
104013
|
checkEquivalence,
|
|
103923
104014
|
batchCheckEquivalence
|
|
@@ -103957,7 +104048,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
|
|
|
103957
104048
|
const results = [];
|
|
103958
104049
|
for (const { patch, originalCode, mutatedCode } of patches) {
|
|
103959
104050
|
try {
|
|
103960
|
-
const result = await
|
|
104051
|
+
const result = await _internals51.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
|
|
103961
104052
|
results.push(result);
|
|
103962
104053
|
} catch (err3) {
|
|
103963
104054
|
results.push({
|
|
@@ -103976,7 +104067,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
|
|
|
103976
104067
|
var MUTATION_TIMEOUT_MS = 30000;
|
|
103977
104068
|
var TOTAL_BUDGET_MS = 300000;
|
|
103978
104069
|
var GIT_APPLY_TIMEOUT_MS = 5000;
|
|
103979
|
-
var
|
|
104070
|
+
var _internals52 = {
|
|
103980
104071
|
executeMutation,
|
|
103981
104072
|
computeReport,
|
|
103982
104073
|
executeMutationSuite,
|
|
@@ -104008,7 +104099,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
104008
104099
|
};
|
|
104009
104100
|
}
|
|
104010
104101
|
try {
|
|
104011
|
-
const applyResult =
|
|
104102
|
+
const applyResult = _internals52.spawnSync("git", ["apply", "--", patchFile], {
|
|
104012
104103
|
cwd: workingDir,
|
|
104013
104104
|
timeout: GIT_APPLY_TIMEOUT_MS,
|
|
104014
104105
|
stdio: "pipe"
|
|
@@ -104037,7 +104128,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
104037
104128
|
}
|
|
104038
104129
|
let testPassed = false;
|
|
104039
104130
|
try {
|
|
104040
|
-
const spawnResult =
|
|
104131
|
+
const spawnResult = _internals52.spawnSync(testCommand[0], testCommand.slice(1), {
|
|
104041
104132
|
cwd: workingDir,
|
|
104042
104133
|
timeout: MUTATION_TIMEOUT_MS,
|
|
104043
104134
|
stdio: "pipe"
|
|
@@ -104070,7 +104161,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
104070
104161
|
} finally {
|
|
104071
104162
|
if (patchFile) {
|
|
104072
104163
|
try {
|
|
104073
|
-
const revertResult =
|
|
104164
|
+
const revertResult = _internals52.spawnSync("git", ["apply", "-R", "--", patchFile], {
|
|
104074
104165
|
cwd: workingDir,
|
|
104075
104166
|
timeout: GIT_APPLY_TIMEOUT_MS,
|
|
104076
104167
|
stdio: "pipe"
|
|
@@ -104089,7 +104180,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
104089
104180
|
revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
|
|
104090
104181
|
}
|
|
104091
104182
|
try {
|
|
104092
|
-
|
|
104183
|
+
unlinkSync17(patchFile);
|
|
104093
104184
|
} catch (_unlinkErr) {}
|
|
104094
104185
|
}
|
|
104095
104186
|
}
|
|
@@ -104263,7 +104354,7 @@ async function executeMutationSuite(patches, testCommand, testFiles, workingDir,
|
|
|
104263
104354
|
}
|
|
104264
104355
|
|
|
104265
104356
|
// src/mutation/gate.ts
|
|
104266
|
-
var
|
|
104357
|
+
var _internals53 = {
|
|
104267
104358
|
evaluateMutationGate,
|
|
104268
104359
|
buildTestImprovementPrompt,
|
|
104269
104360
|
buildMessage
|
|
@@ -104284,8 +104375,8 @@ function evaluateMutationGate(report, passThreshold = PASS_THRESHOLD, warnThresh
|
|
|
104284
104375
|
} else {
|
|
104285
104376
|
verdict = "fail";
|
|
104286
104377
|
}
|
|
104287
|
-
const testImprovementPrompt =
|
|
104288
|
-
const message =
|
|
104378
|
+
const testImprovementPrompt = _internals53.buildTestImprovementPrompt(report, passThreshold, verdict);
|
|
104379
|
+
const message = _internals53.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
|
|
104289
104380
|
return {
|
|
104290
104381
|
verdict,
|
|
104291
104382
|
killRate: report.killRate,
|
|
@@ -104902,7 +104993,7 @@ import * as path136 from "node:path";
|
|
|
104902
104993
|
init_bun_compat();
|
|
104903
104994
|
import * as fs104 from "node:fs";
|
|
104904
104995
|
import * as path135 from "node:path";
|
|
104905
|
-
var
|
|
104996
|
+
var _internals54 = { bunSpawn };
|
|
104906
104997
|
var _swarmGitExcludedChecked = false;
|
|
104907
104998
|
function fileCoversSwarm(content) {
|
|
104908
104999
|
for (const rawLine of content.split(`
|
|
@@ -104935,7 +105026,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
104935
105026
|
checkIgnoreExitCode
|
|
104936
105027
|
] = await Promise.all([
|
|
104937
105028
|
(async () => {
|
|
104938
|
-
const proc =
|
|
105029
|
+
const proc = _internals54.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
|
|
104939
105030
|
try {
|
|
104940
105031
|
return await Promise.all([proc.exited, proc.stdout.text()]);
|
|
104941
105032
|
} finally {
|
|
@@ -104945,7 +105036,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
104945
105036
|
}
|
|
104946
105037
|
})(),
|
|
104947
105038
|
(async () => {
|
|
104948
|
-
const proc =
|
|
105039
|
+
const proc = _internals54.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
|
|
104949
105040
|
try {
|
|
104950
105041
|
return await Promise.all([proc.exited, proc.stdout.text()]);
|
|
104951
105042
|
} finally {
|
|
@@ -104955,7 +105046,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
104955
105046
|
}
|
|
104956
105047
|
})(),
|
|
104957
105048
|
(async () => {
|
|
104958
|
-
const proc =
|
|
105049
|
+
const proc = _internals54.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
|
|
104959
105050
|
try {
|
|
104960
105051
|
return await proc.exited;
|
|
104961
105052
|
} finally {
|
|
@@ -104994,7 +105085,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
104994
105085
|
}
|
|
104995
105086
|
} catch {}
|
|
104996
105087
|
}
|
|
104997
|
-
const trackedProc =
|
|
105088
|
+
const trackedProc = _internals54.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
|
|
104998
105089
|
let trackedExitCode;
|
|
104999
105090
|
let trackedOutput;
|
|
105000
105091
|
try {
|
|
@@ -105019,7 +105110,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
105019
105110
|
}
|
|
105020
105111
|
|
|
105021
105112
|
// src/hooks/diff-scope.ts
|
|
105022
|
-
var
|
|
105113
|
+
var _internals55 = { bunSpawn };
|
|
105023
105114
|
function getDeclaredScope(taskId, directory) {
|
|
105024
105115
|
try {
|
|
105025
105116
|
const planPath = path136.join(directory, ".swarm", "plan.json");
|
|
@@ -105054,7 +105145,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
|
|
|
105054
105145
|
};
|
|
105055
105146
|
async function getChangedFiles(directory) {
|
|
105056
105147
|
try {
|
|
105057
|
-
const proc =
|
|
105148
|
+
const proc = _internals55.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
|
|
105058
105149
|
cwd: directory,
|
|
105059
105150
|
...GIT_DIFF_SPAWN_OPTIONS
|
|
105060
105151
|
});
|
|
@@ -105071,7 +105162,7 @@ async function getChangedFiles(directory) {
|
|
|
105071
105162
|
return stdout.trim().split(`
|
|
105072
105163
|
`).map((f) => f.trim()).filter((f) => f.length > 0);
|
|
105073
105164
|
}
|
|
105074
|
-
const proc2 =
|
|
105165
|
+
const proc2 = _internals55.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
|
|
105075
105166
|
cwd: directory,
|
|
105076
105167
|
...GIT_DIFF_SPAWN_OPTIONS
|
|
105077
105168
|
});
|
|
@@ -105129,7 +105220,7 @@ init_telemetry();
|
|
|
105129
105220
|
init_file_locks();
|
|
105130
105221
|
import * as fs106 from "node:fs";
|
|
105131
105222
|
import * as path137 from "node:path";
|
|
105132
|
-
var
|
|
105223
|
+
var _internals56 = {
|
|
105133
105224
|
listActiveLocks,
|
|
105134
105225
|
verifyLeanTurboTaskCompletion
|
|
105135
105226
|
};
|
|
@@ -105271,7 +105362,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
105271
105362
|
}
|
|
105272
105363
|
};
|
|
105273
105364
|
}
|
|
105274
|
-
const activeLocks =
|
|
105365
|
+
const activeLocks = _internals56.listActiveLocks(directory);
|
|
105275
105366
|
const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
|
|
105276
105367
|
if (laneLocks.length > 0) {
|
|
105277
105368
|
return {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint artifact writer.
|
|
3
|
+
* Writes SWARM_PLAN.md and SWARM_PLAN.json inside .swarm/.
|
|
4
|
+
* Export-only — not a live runtime source of truth.
|
|
5
|
+
* Called on: save_plan, phase completion, /swarm close.
|
|
6
|
+
* NOT called on every task update.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'node:fs';
|
|
1
9
|
import { type Plan } from '../config/plan-schema';
|
|
2
10
|
/**
|
|
3
11
|
* Write SWARM_PLAN.json and SWARM_PLAN.md inside the .swarm/ directory under the project root.
|
|
@@ -26,4 +34,6 @@ export declare function importCheckpoint(directory: string, source?: string): Pr
|
|
|
26
34
|
export declare const _internals: {
|
|
27
35
|
writeCheckpoint: typeof writeCheckpoint;
|
|
28
36
|
importCheckpoint: typeof importCheckpoint;
|
|
37
|
+
existsSyncForCleanup: typeof fs.existsSync;
|
|
38
|
+
unlinkSyncForCleanup: typeof fs.unlinkSync;
|
|
29
39
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TestRunRecord } from './history-store.js';
|
|
2
|
-
export type FailureClassification = 'new_regression' | 'pre_existing' | 'flaky' | 'unknown';
|
|
2
|
+
export type FailureClassification = 'new_regression' | 'pre_existing' | 'flaky' | 'infrastructure_failure' | 'unknown';
|
|
3
3
|
export interface ClassifiedFailure {
|
|
4
4
|
testFile: string;
|
|
5
5
|
testName: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.27.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|