opencode-swarm 7.19.1 → 7.19.3
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 -4
- package/dist/index.js +135 -16
- package/dist/tools/test-runner.d.ts +1 -0
- 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.19.
|
|
37
|
+
version: "7.19.3",
|
|
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",
|
|
@@ -48754,7 +48754,7 @@ function analyzeFailures(workingDir) {
|
|
|
48754
48754
|
} catch {}
|
|
48755
48755
|
return report;
|
|
48756
48756
|
}
|
|
48757
|
-
var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, POWERSHELL_METACHARACTERS, DISPATCH_FRAMEWORK_MAP, COMPOUND_TEST_EXTENSIONS, TEST_DIRECTORY_NAMES, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
|
|
48757
|
+
var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, MAX_SAFE_SOURCE_FILES = 1, POWERSHELL_METACHARACTERS, DISPATCH_FRAMEWORK_MAP, COMPOUND_TEST_EXTENSIONS, TEST_DIRECTORY_NAMES, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
|
|
48758
48758
|
var init_test_runner = __esm(() => {
|
|
48759
48759
|
init_zod();
|
|
48760
48760
|
init_discovery();
|
|
@@ -48941,8 +48941,8 @@ var init_test_runner = __esm(() => {
|
|
|
48941
48941
|
success: false,
|
|
48942
48942
|
framework: "none",
|
|
48943
48943
|
scope: "all",
|
|
48944
|
-
error: 'scope "all" is
|
|
48945
|
-
message: '
|
|
48944
|
+
error: 'scope "all" is blocked for agent use. Use scope "convention" with specific test files, or scope "graph" with exactly one source file.',
|
|
48945
|
+
message: 'The full test suite is blocked in agent context. Use scope "convention" with specific test files, or scope "graph" with exactly one source file. Example: { scope: "convention", files: ["src/tools/test-runner.ts"] }',
|
|
48946
48946
|
outcome: "error"
|
|
48947
48947
|
};
|
|
48948
48948
|
return JSON.stringify(errorResult, null, 2);
|
|
@@ -49023,6 +49023,17 @@ var init_test_runner = __esm(() => {
|
|
|
49023
49023
|
};
|
|
49024
49024
|
return JSON.stringify(errorResult, null, 2);
|
|
49025
49025
|
}
|
|
49026
|
+
if (sourceFiles.length > MAX_SAFE_SOURCE_FILES) {
|
|
49027
|
+
const errorResult = {
|
|
49028
|
+
success: false,
|
|
49029
|
+
framework,
|
|
49030
|
+
scope,
|
|
49031
|
+
error: `scope "convention" accepts at most ${MAX_SAFE_SOURCE_FILES} source file for discovery (got ${sourceFiles.length}). Treat this as SKIP without retry.`,
|
|
49032
|
+
message: `Too many source files for scope "convention" discovery (${sourceFiles.length} provided, limit is ${MAX_SAFE_SOURCE_FILES}). Call test_runner once per source file, or pass direct test file paths instead of source files.`,
|
|
49033
|
+
outcome: "scope_exceeded"
|
|
49034
|
+
};
|
|
49035
|
+
return JSON.stringify(errorResult, null, 2);
|
|
49036
|
+
}
|
|
49026
49037
|
testFiles = [
|
|
49027
49038
|
...directTestFiles,
|
|
49028
49039
|
...getTestFilesFromConvention(sourceFiles, workingDir)
|
|
@@ -49046,6 +49057,17 @@ var init_test_runner = __esm(() => {
|
|
|
49046
49057
|
};
|
|
49047
49058
|
return JSON.stringify(errorResult, null, 2);
|
|
49048
49059
|
}
|
|
49060
|
+
if (sourceFiles.length > MAX_SAFE_SOURCE_FILES) {
|
|
49061
|
+
const errorResult = {
|
|
49062
|
+
success: false,
|
|
49063
|
+
framework,
|
|
49064
|
+
scope,
|
|
49065
|
+
error: `scope "graph" accepts at most ${MAX_SAFE_SOURCE_FILES} source file (got ${sourceFiles.length}). Treat this as SKIP without retry.`,
|
|
49066
|
+
message: `Too many source files for scope "graph" (${sourceFiles.length} provided, limit is ${MAX_SAFE_SOURCE_FILES}). Call test_runner once per source file, or use scope "convention" with direct test file paths.`,
|
|
49067
|
+
outcome: "scope_exceeded"
|
|
49068
|
+
};
|
|
49069
|
+
return JSON.stringify(errorResult, null, 2);
|
|
49070
|
+
}
|
|
49049
49071
|
const graphTestFiles = await getTestFilesFromGraph(sourceFiles, workingDir);
|
|
49050
49072
|
if (graphTestFiles.length > 0) {
|
|
49051
49073
|
testFiles = graphTestFiles;
|
|
@@ -49073,6 +49095,17 @@ var init_test_runner = __esm(() => {
|
|
|
49073
49095
|
};
|
|
49074
49096
|
return JSON.stringify(errorResult, null, 2);
|
|
49075
49097
|
}
|
|
49098
|
+
if (sourceFiles.length > MAX_SAFE_SOURCE_FILES) {
|
|
49099
|
+
const errorResult = {
|
|
49100
|
+
success: false,
|
|
49101
|
+
framework,
|
|
49102
|
+
scope,
|
|
49103
|
+
error: `scope "impact" accepts at most ${MAX_SAFE_SOURCE_FILES} source file (got ${sourceFiles.length}). Treat this as SKIP without retry.`,
|
|
49104
|
+
message: `Too many source files for scope "impact" (${sourceFiles.length} provided, limit is ${MAX_SAFE_SOURCE_FILES}). Call test_runner once per source file, or use scope "convention" with direct test file paths.`,
|
|
49105
|
+
outcome: "scope_exceeded"
|
|
49106
|
+
};
|
|
49107
|
+
return JSON.stringify(errorResult, null, 2);
|
|
49108
|
+
}
|
|
49076
49109
|
try {
|
|
49077
49110
|
const impactResult = await analyzeImpact(sourceFiles, workingDir);
|
|
49078
49111
|
if (impactResult.impactedTests.length > 0) {
|
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.19.
|
|
36
|
+
version: "7.19.3",
|
|
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",
|
|
@@ -24183,6 +24183,91 @@ function extractStatusCode(errorMsg) {
|
|
|
24183
24183
|
}
|
|
24184
24184
|
return null;
|
|
24185
24185
|
}
|
|
24186
|
+
function isPlainObject2(value) {
|
|
24187
|
+
return typeof value === "object" && value !== null && (value.constructor === Object || Object.getPrototypeOf(value) === null);
|
|
24188
|
+
}
|
|
24189
|
+
function readSignalField(source, key) {
|
|
24190
|
+
try {
|
|
24191
|
+
return source[key];
|
|
24192
|
+
} catch {
|
|
24193
|
+
return;
|
|
24194
|
+
}
|
|
24195
|
+
}
|
|
24196
|
+
function pushSignalValue(parts2, value) {
|
|
24197
|
+
if (typeof value === "string") {
|
|
24198
|
+
parts2.push(value);
|
|
24199
|
+
return;
|
|
24200
|
+
}
|
|
24201
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
24202
|
+
parts2.push(String(value));
|
|
24203
|
+
}
|
|
24204
|
+
}
|
|
24205
|
+
function appendSelectedFields(parts2, source, keys) {
|
|
24206
|
+
for (const key of keys) {
|
|
24207
|
+
pushSignalValue(parts2, readSignalField(source, key));
|
|
24208
|
+
}
|
|
24209
|
+
}
|
|
24210
|
+
function appendNestedErrorSignal(parts2, value) {
|
|
24211
|
+
if (typeof value === "string") {
|
|
24212
|
+
parts2.push(value);
|
|
24213
|
+
return;
|
|
24214
|
+
}
|
|
24215
|
+
if (value instanceof Error) {
|
|
24216
|
+
parts2.push(value.name, value.message);
|
|
24217
|
+
appendSelectedFields(parts2, value, [
|
|
24218
|
+
"code",
|
|
24219
|
+
"status",
|
|
24220
|
+
"statusCode"
|
|
24221
|
+
]);
|
|
24222
|
+
return;
|
|
24223
|
+
}
|
|
24224
|
+
if (!isPlainObject2(value))
|
|
24225
|
+
return;
|
|
24226
|
+
appendSelectedFields(parts2, value, [
|
|
24227
|
+
"code",
|
|
24228
|
+
"status",
|
|
24229
|
+
"statusCode",
|
|
24230
|
+
"message",
|
|
24231
|
+
"error_type"
|
|
24232
|
+
]);
|
|
24233
|
+
}
|
|
24234
|
+
function extractErrorSignal(errorContent) {
|
|
24235
|
+
if (typeof errorContent === "string")
|
|
24236
|
+
return errorContent;
|
|
24237
|
+
if (errorContent == null)
|
|
24238
|
+
return "";
|
|
24239
|
+
const parts2 = [];
|
|
24240
|
+
try {
|
|
24241
|
+
if (errorContent instanceof Error) {
|
|
24242
|
+
parts2.push(errorContent.name, errorContent.message);
|
|
24243
|
+
appendSelectedFields(parts2, errorContent, ["code", "status", "statusCode"]);
|
|
24244
|
+
return parts2.join(" ");
|
|
24245
|
+
}
|
|
24246
|
+
if (!isPlainObject2(errorContent))
|
|
24247
|
+
return "";
|
|
24248
|
+
appendSelectedFields(parts2, errorContent, [
|
|
24249
|
+
"code",
|
|
24250
|
+
"status",
|
|
24251
|
+
"statusCode",
|
|
24252
|
+
"message",
|
|
24253
|
+
"error_type"
|
|
24254
|
+
]);
|
|
24255
|
+
appendNestedErrorSignal(parts2, readSignalField(errorContent, "error"));
|
|
24256
|
+
const metadata2 = readSignalField(errorContent, "metadata");
|
|
24257
|
+
if (isPlainObject2(metadata2)) {
|
|
24258
|
+
appendSelectedFields(parts2, metadata2, [
|
|
24259
|
+
"code",
|
|
24260
|
+
"status",
|
|
24261
|
+
"statusCode",
|
|
24262
|
+
"error_type"
|
|
24263
|
+
]);
|
|
24264
|
+
}
|
|
24265
|
+
appendNestedErrorSignal(parts2, readSignalField(errorContent, "cause"));
|
|
24266
|
+
} catch {
|
|
24267
|
+
return parts2.join(" ");
|
|
24268
|
+
}
|
|
24269
|
+
return parts2.join(" ");
|
|
24270
|
+
}
|
|
24186
24271
|
function getStoredInputArgs(callID) {
|
|
24187
24272
|
return storedInputArgs.get(callID);
|
|
24188
24273
|
}
|
|
@@ -25392,16 +25477,17 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
|
|
|
25392
25477
|
if (hasError) {
|
|
25393
25478
|
const outputStr = typeof output.output === "string" ? output.output : "";
|
|
25394
25479
|
const errorContent = output.error ?? outputStr;
|
|
25395
|
-
const
|
|
25480
|
+
const errorSignal = extractErrorSignal(errorContent);
|
|
25481
|
+
const extractedStatus = extractStatusCode(errorSignal);
|
|
25396
25482
|
const isTransientStatusCode = extractedStatus !== null && TRANSIENT_STATUS_CODES.has(extractedStatus);
|
|
25397
|
-
const isTransientPatternMatch =
|
|
25483
|
+
const isTransientPatternMatch = TRANSIENT_MODEL_ERROR_PATTERN.test(errorSignal);
|
|
25398
25484
|
const isTransientMatch = isTransientStatusCode || isTransientPatternMatch;
|
|
25399
25485
|
const isTransient = !!session && isTransientMatch && window2.transientRetryCount < cfg.max_transient_retries;
|
|
25400
|
-
const isDegraded = !isTransient &&
|
|
25486
|
+
const isDegraded = !isTransient && DEGRADED_ERROR_PATTERN.test(errorSignal);
|
|
25401
25487
|
if (isTransient) {
|
|
25402
25488
|
window2.transientRetryCount++;
|
|
25403
25489
|
} else if (isDegraded) {
|
|
25404
|
-
const isContentFilter =
|
|
25490
|
+
const isContentFilter = CONTENT_FILTER_PATTERN.test(errorSignal);
|
|
25405
25491
|
if (session && !session.modelFallbackExhausted) {
|
|
25406
25492
|
session.model_fallback_index++;
|
|
25407
25493
|
const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
|
|
@@ -26058,7 +26144,7 @@ var init_guardrails = __esm(() => {
|
|
|
26058
26144
|
]);
|
|
26059
26145
|
storedInputArgs = new Map;
|
|
26060
26146
|
TRANSIENT_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504, 529]);
|
|
26061
|
-
TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|500|502|503|504|529|timeout|overloaded|model.?not.?found|temporarily.?unavailable|server.?error|connection.?(refused|reset|timeout)|bad.?gateway|gateway.?timeout|internal.?server.?error|service.?unavailable/i;
|
|
26147
|
+
TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|500|502|503|504|529|timeout|overloaded|model.?not.?found|temporarily.?unavailable|provider.?unavailable|server.?error|connection.?(refused|reset|timeout|lost)|bad.?gateway|gateway.?timeout|internal.?server.?error|service.?unavailable/i;
|
|
26062
26148
|
DEGRADED_ERROR_PATTERN = /context.?length|token.?(limit|budget)|input.?too.?long|content.?filter|exceeds?.?(maximum.?)?tokens|maximum.?context|context.?window|too.?many.?tokens|prompt.?too.?long|message.?too.?long|request.?too.?large|max.?tokens/i;
|
|
26063
26149
|
CONTENT_FILTER_PATTERN = /content.?filter/i;
|
|
26064
26150
|
toolCallsSinceLastWrite = new Map;
|
|
@@ -28257,7 +28343,7 @@ __export(exports_util2, {
|
|
|
28257
28343
|
jsonStringifyReplacer: () => jsonStringifyReplacer2,
|
|
28258
28344
|
joinValues: () => joinValues2,
|
|
28259
28345
|
issue: () => issue2,
|
|
28260
|
-
isPlainObject: () =>
|
|
28346
|
+
isPlainObject: () => isPlainObject3,
|
|
28261
28347
|
isObject: () => isObject2,
|
|
28262
28348
|
hexToUint8Array: () => hexToUint8Array2,
|
|
28263
28349
|
getSizableOrigin: () => getSizableOrigin2,
|
|
@@ -28425,7 +28511,7 @@ function esc2(str) {
|
|
|
28425
28511
|
function isObject2(data) {
|
|
28426
28512
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
28427
28513
|
}
|
|
28428
|
-
function
|
|
28514
|
+
function isPlainObject3(o) {
|
|
28429
28515
|
if (isObject2(o) === false)
|
|
28430
28516
|
return false;
|
|
28431
28517
|
const ctor = o.constructor;
|
|
@@ -28440,7 +28526,7 @@ function isPlainObject2(o) {
|
|
|
28440
28526
|
return true;
|
|
28441
28527
|
}
|
|
28442
28528
|
function shallowClone2(o) {
|
|
28443
|
-
if (
|
|
28529
|
+
if (isPlainObject3(o))
|
|
28444
28530
|
return { ...o };
|
|
28445
28531
|
if (Array.isArray(o))
|
|
28446
28532
|
return [...o];
|
|
@@ -28566,7 +28652,7 @@ function omit2(schema, mask) {
|
|
|
28566
28652
|
return clone2(schema, def);
|
|
28567
28653
|
}
|
|
28568
28654
|
function extend2(schema, shape) {
|
|
28569
|
-
if (!
|
|
28655
|
+
if (!isPlainObject3(shape)) {
|
|
28570
28656
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
28571
28657
|
}
|
|
28572
28658
|
const checks3 = schema._zod.def.checks;
|
|
@@ -28585,7 +28671,7 @@ function extend2(schema, shape) {
|
|
|
28585
28671
|
return clone2(schema, def);
|
|
28586
28672
|
}
|
|
28587
28673
|
function safeExtend2(schema, shape) {
|
|
28588
|
-
if (!
|
|
28674
|
+
if (!isPlainObject3(shape)) {
|
|
28589
28675
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
28590
28676
|
}
|
|
28591
28677
|
const def = {
|
|
@@ -29968,7 +30054,7 @@ function mergeValues2(a, b) {
|
|
|
29968
30054
|
if (a instanceof Date && b instanceof Date && +a === +b) {
|
|
29969
30055
|
return { valid: true, data: a };
|
|
29970
30056
|
}
|
|
29971
|
-
if (
|
|
30057
|
+
if (isPlainObject3(a) && isPlainObject3(b)) {
|
|
29972
30058
|
const bKeys = Object.keys(b);
|
|
29973
30059
|
const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
|
29974
30060
|
const newObj = { ...a, ...b };
|
|
@@ -31065,7 +31151,7 @@ var init_schemas3 = __esm(() => {
|
|
|
31065
31151
|
$ZodType2.init(inst, def);
|
|
31066
31152
|
inst._zod.parse = (payload, ctx) => {
|
|
31067
31153
|
const input = payload.value;
|
|
31068
|
-
if (!
|
|
31154
|
+
if (!isPlainObject3(input)) {
|
|
31069
31155
|
payload.issues.push({
|
|
31070
31156
|
expected: "record",
|
|
31071
31157
|
code: "invalid_type",
|
|
@@ -57290,7 +57376,7 @@ function analyzeFailures(workingDir) {
|
|
|
57290
57376
|
} catch {}
|
|
57291
57377
|
return report;
|
|
57292
57378
|
}
|
|
57293
|
-
var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, POWERSHELL_METACHARACTERS, DISPATCH_FRAMEWORK_MAP, COMPOUND_TEST_EXTENSIONS, TEST_DIRECTORY_NAMES, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
|
|
57379
|
+
var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, MAX_SAFE_SOURCE_FILES = 1, POWERSHELL_METACHARACTERS, DISPATCH_FRAMEWORK_MAP, COMPOUND_TEST_EXTENSIONS, TEST_DIRECTORY_NAMES, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
|
|
57294
57380
|
var init_test_runner = __esm(() => {
|
|
57295
57381
|
init_zod();
|
|
57296
57382
|
init_discovery();
|
|
@@ -57477,8 +57563,8 @@ var init_test_runner = __esm(() => {
|
|
|
57477
57563
|
success: false,
|
|
57478
57564
|
framework: "none",
|
|
57479
57565
|
scope: "all",
|
|
57480
|
-
error: 'scope "all" is
|
|
57481
|
-
message: '
|
|
57566
|
+
error: 'scope "all" is blocked for agent use. Use scope "convention" with specific test files, or scope "graph" with exactly one source file.',
|
|
57567
|
+
message: 'The full test suite is blocked in agent context. Use scope "convention" with specific test files, or scope "graph" with exactly one source file. Example: { scope: "convention", files: ["src/tools/test-runner.ts"] }',
|
|
57482
57568
|
outcome: "error"
|
|
57483
57569
|
};
|
|
57484
57570
|
return JSON.stringify(errorResult, null, 2);
|
|
@@ -57559,6 +57645,17 @@ var init_test_runner = __esm(() => {
|
|
|
57559
57645
|
};
|
|
57560
57646
|
return JSON.stringify(errorResult, null, 2);
|
|
57561
57647
|
}
|
|
57648
|
+
if (sourceFiles.length > MAX_SAFE_SOURCE_FILES) {
|
|
57649
|
+
const errorResult = {
|
|
57650
|
+
success: false,
|
|
57651
|
+
framework,
|
|
57652
|
+
scope,
|
|
57653
|
+
error: `scope "convention" accepts at most ${MAX_SAFE_SOURCE_FILES} source file for discovery (got ${sourceFiles.length}). Treat this as SKIP without retry.`,
|
|
57654
|
+
message: `Too many source files for scope "convention" discovery (${sourceFiles.length} provided, limit is ${MAX_SAFE_SOURCE_FILES}). Call test_runner once per source file, or pass direct test file paths instead of source files.`,
|
|
57655
|
+
outcome: "scope_exceeded"
|
|
57656
|
+
};
|
|
57657
|
+
return JSON.stringify(errorResult, null, 2);
|
|
57658
|
+
}
|
|
57562
57659
|
testFiles = [
|
|
57563
57660
|
...directTestFiles,
|
|
57564
57661
|
...getTestFilesFromConvention(sourceFiles, workingDir)
|
|
@@ -57582,6 +57679,17 @@ var init_test_runner = __esm(() => {
|
|
|
57582
57679
|
};
|
|
57583
57680
|
return JSON.stringify(errorResult, null, 2);
|
|
57584
57681
|
}
|
|
57682
|
+
if (sourceFiles.length > MAX_SAFE_SOURCE_FILES) {
|
|
57683
|
+
const errorResult = {
|
|
57684
|
+
success: false,
|
|
57685
|
+
framework,
|
|
57686
|
+
scope,
|
|
57687
|
+
error: `scope "graph" accepts at most ${MAX_SAFE_SOURCE_FILES} source file (got ${sourceFiles.length}). Treat this as SKIP without retry.`,
|
|
57688
|
+
message: `Too many source files for scope "graph" (${sourceFiles.length} provided, limit is ${MAX_SAFE_SOURCE_FILES}). Call test_runner once per source file, or use scope "convention" with direct test file paths.`,
|
|
57689
|
+
outcome: "scope_exceeded"
|
|
57690
|
+
};
|
|
57691
|
+
return JSON.stringify(errorResult, null, 2);
|
|
57692
|
+
}
|
|
57585
57693
|
const graphTestFiles = await getTestFilesFromGraph(sourceFiles, workingDir);
|
|
57586
57694
|
if (graphTestFiles.length > 0) {
|
|
57587
57695
|
testFiles = graphTestFiles;
|
|
@@ -57609,6 +57717,17 @@ var init_test_runner = __esm(() => {
|
|
|
57609
57717
|
};
|
|
57610
57718
|
return JSON.stringify(errorResult, null, 2);
|
|
57611
57719
|
}
|
|
57720
|
+
if (sourceFiles.length > MAX_SAFE_SOURCE_FILES) {
|
|
57721
|
+
const errorResult = {
|
|
57722
|
+
success: false,
|
|
57723
|
+
framework,
|
|
57724
|
+
scope,
|
|
57725
|
+
error: `scope "impact" accepts at most ${MAX_SAFE_SOURCE_FILES} source file (got ${sourceFiles.length}). Treat this as SKIP without retry.`,
|
|
57726
|
+
message: `Too many source files for scope "impact" (${sourceFiles.length} provided, limit is ${MAX_SAFE_SOURCE_FILES}). Call test_runner once per source file, or use scope "convention" with direct test file paths.`,
|
|
57727
|
+
outcome: "scope_exceeded"
|
|
57728
|
+
};
|
|
57729
|
+
return JSON.stringify(errorResult, null, 2);
|
|
57730
|
+
}
|
|
57612
57731
|
try {
|
|
57613
57732
|
const impactResult = await analyzeImpact(sourceFiles, workingDir);
|
|
57614
57733
|
if (impactResult.impactedTests.length > 0) {
|
|
@@ -4,6 +4,7 @@ export declare const MAX_COMMAND_LENGTH = 500;
|
|
|
4
4
|
export declare const DEFAULT_TIMEOUT_MS = 60000;
|
|
5
5
|
export declare const MAX_TIMEOUT_MS = 300000;
|
|
6
6
|
export declare const MAX_SAFE_TEST_FILES = 50;
|
|
7
|
+
export declare const MAX_SAFE_SOURCE_FILES = 1;
|
|
7
8
|
export declare const SUPPORTED_FRAMEWORKS: readonly ["bun", "vitest", "jest", "mocha", "pytest", "cargo", "pester", "go-test", "maven", "gradle", "dotnet-test", "ctest", "swift-test", "dart-test", "rspec", "minitest"];
|
|
8
9
|
export type TestFramework = (typeof SUPPORTED_FRAMEWORKS)[number] | 'none';
|
|
9
10
|
export interface TestRunnerArgs {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.19.
|
|
3
|
+
"version": "7.19.3",
|
|
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",
|