opencode-swarm 6.25.2 → 6.25.4

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 CHANGED
@@ -33858,6 +33858,7 @@ var MAX_OUTPUT_BYTES3 = 512000;
33858
33858
  var MAX_COMMAND_LENGTH2 = 500;
33859
33859
  var DEFAULT_TIMEOUT_MS = 60000;
33860
33860
  var MAX_TIMEOUT_MS = 300000;
33861
+ var MAX_SAFE_TEST_FILES = 50;
33861
33862
  function containsPathTraversal2(str) {
33862
33863
  if (/\.\.[/\\]/.test(str))
33863
33864
  return true;
@@ -34714,35 +34715,6 @@ var SKIP_DIRECTORIES = new Set([
34714
34715
  ".bundle",
34715
34716
  ".tox"
34716
34717
  ]);
34717
- function findSourceFiles(dir, files = []) {
34718
- let entries;
34719
- try {
34720
- entries = fs5.readdirSync(dir);
34721
- } catch {
34722
- return files;
34723
- }
34724
- entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
34725
- for (const entry of entries) {
34726
- if (SKIP_DIRECTORIES.has(entry))
34727
- continue;
34728
- const fullPath = path13.join(dir, entry);
34729
- let stat2;
34730
- try {
34731
- stat2 = fs5.statSync(fullPath);
34732
- } catch {
34733
- continue;
34734
- }
34735
- if (stat2.isDirectory()) {
34736
- findSourceFiles(fullPath, files);
34737
- } else if (stat2.isFile()) {
34738
- const ext = path13.extname(fullPath).toLowerCase();
34739
- if (SOURCE_EXTENSIONS.has(ext)) {
34740
- files.push(fullPath);
34741
- }
34742
- }
34743
- }
34744
- return files;
34745
- }
34746
34718
  var test_runner = createSwarmTool({
34747
34719
  description: 'Run project tests with framework detection. Supports bun, vitest, jest, mocha, pytest, cargo, pester, go-test, maven, gradle, dotnet-test, ctest, swift-test, dart-test, rspec, and minitest. Returns deterministic normalized JSON with framework, scope, command, totals, coverage, duration, success status, and failures. Use scope "all" for full suite, "convention" to map source files to test files, or "graph" to find related tests via imports.',
34748
34720
  args: {
@@ -34800,6 +34772,26 @@ var test_runner = createSwarmTool({
34800
34772
  return JSON.stringify(errorResult, null, 2);
34801
34773
  }
34802
34774
  const scope = args.scope || "all";
34775
+ if (scope === "all") {
34776
+ const errorResult = {
34777
+ success: false,
34778
+ framework: "none",
34779
+ scope: "all",
34780
+ error: 'Full-suite test execution (scope: "all") is prohibited in interactive sessions',
34781
+ message: 'Use scope "convention" or "graph" with explicit files to run targeted tests in interactive mode. Full-suite runs are restricted to prevent excessive resource consumption.'
34782
+ };
34783
+ return JSON.stringify(errorResult, null, 2);
34784
+ }
34785
+ if ((scope === "convention" || scope === "graph") && (!args.files || args.files.length === 0)) {
34786
+ const errorResult = {
34787
+ success: false,
34788
+ framework: "none",
34789
+ scope,
34790
+ error: 'scope "convention" and "graph" require explicit files array - omitting files causes unsafe full-project discovery',
34791
+ message: 'When using scope "convention" or "graph", you must provide a non-empty "files" array. Use scope "all" for full project test suite without specifying files.'
34792
+ };
34793
+ return JSON.stringify(errorResult, null, 2);
34794
+ }
34803
34795
  const _files = args.files || [];
34804
34796
  const coverage = args.coverage || false;
34805
34797
  const timeout_ms = Math.min(args.timeout_ms || DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);
@@ -34823,19 +34815,37 @@ var test_runner = createSwarmTool({
34823
34815
  let testFiles = [];
34824
34816
  let graphFallbackReason;
34825
34817
  let effectiveScope = scope;
34826
- if (scope === "all") {
34827
- testFiles = [];
34828
- } else if (scope === "convention") {
34829
- const sourceFiles = args.files && args.files.length > 0 ? args.files.filter((f) => {
34818
+ if (scope === "convention") {
34819
+ const sourceFiles = args.files.filter((f) => {
34830
34820
  const ext = path13.extname(f).toLowerCase();
34831
34821
  return SOURCE_EXTENSIONS.has(ext);
34832
- }) : findSourceFiles(workingDir);
34822
+ });
34823
+ if (sourceFiles.length === 0) {
34824
+ const errorResult = {
34825
+ success: false,
34826
+ framework,
34827
+ scope,
34828
+ error: "Provided files contain no source files with recognized extensions",
34829
+ message: "The files array must contain at least one source file with a recognized extension (.ts, .tsx, .js, .jsx, .py, .rs, .ps1, etc.). Non-source files like README.md or config.json are not valid for test discovery."
34830
+ };
34831
+ return JSON.stringify(errorResult, null, 2);
34832
+ }
34833
34833
  testFiles = getTestFilesFromConvention(sourceFiles);
34834
34834
  } else if (scope === "graph") {
34835
- const sourceFiles = args.files && args.files.length > 0 ? args.files.filter((f) => {
34835
+ const sourceFiles = args.files.filter((f) => {
34836
34836
  const ext = path13.extname(f).toLowerCase();
34837
34837
  return SOURCE_EXTENSIONS.has(ext);
34838
- }) : findSourceFiles(workingDir);
34838
+ });
34839
+ if (sourceFiles.length === 0) {
34840
+ const errorResult = {
34841
+ success: false,
34842
+ framework,
34843
+ scope,
34844
+ error: "Provided files contain no source files with recognized extensions",
34845
+ message: "The files array must contain at least one source file with a recognized extension (.ts, .tsx, .js, .jsx, .py, .rs, .ps1, etc.). Non-source files like README.md or config.json are not valid for test discovery."
34846
+ };
34847
+ return JSON.stringify(errorResult, null, 2);
34848
+ }
34839
34849
  const graphTestFiles = await getTestFilesFromGraph(sourceFiles);
34840
34850
  if (graphTestFiles.length > 0) {
34841
34851
  testFiles = graphTestFiles;
@@ -34845,6 +34855,27 @@ var test_runner = createSwarmTool({
34845
34855
  testFiles = getTestFilesFromConvention(sourceFiles);
34846
34856
  }
34847
34857
  }
34858
+ if (testFiles.length === 0) {
34859
+ const errorResult = {
34860
+ success: false,
34861
+ framework,
34862
+ scope: effectiveScope,
34863
+ error: "Provided source files resolved to zero test files",
34864
+ message: "No matching test files found for the provided source files. Check that test files exist with matching naming conventions (.spec.*, .test.*, __tests__/, tests/, test/)."
34865
+ };
34866
+ return JSON.stringify(errorResult, null, 2);
34867
+ }
34868
+ if (testFiles.length > MAX_SAFE_TEST_FILES) {
34869
+ const sampleFiles = testFiles.slice(0, 5);
34870
+ const errorResult = {
34871
+ success: false,
34872
+ framework,
34873
+ scope: effectiveScope,
34874
+ error: `Resolved test file count (${testFiles.length}) exceeds safe maximum (${MAX_SAFE_TEST_FILES})`,
34875
+ message: `Too many test files resolved (${testFiles.length}). Maximum allowed is ${MAX_SAFE_TEST_FILES}. Provide more specific source files to narrow down test scope. First few resolved: ${sampleFiles.join(", ")}`
34876
+ };
34877
+ return JSON.stringify(errorResult, null, 2);
34878
+ }
34848
34879
  const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir);
34849
34880
  if (graphFallbackReason && result.message) {
34850
34881
  result.message = `${result.message} (${graphFallbackReason})`;
package/dist/index.js CHANGED
@@ -35070,36 +35070,7 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
35070
35070
  };
35071
35071
  }
35072
35072
  }
35073
- function findSourceFiles(dir, files = []) {
35074
- let entries;
35075
- try {
35076
- entries = fs10.readdirSync(dir);
35077
- } catch {
35078
- return files;
35079
- }
35080
- entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
35081
- for (const entry of entries) {
35082
- if (SKIP_DIRECTORIES.has(entry))
35083
- continue;
35084
- const fullPath = path22.join(dir, entry);
35085
- let stat2;
35086
- try {
35087
- stat2 = fs10.statSync(fullPath);
35088
- } catch {
35089
- continue;
35090
- }
35091
- if (stat2.isDirectory()) {
35092
- findSourceFiles(fullPath, files);
35093
- } else if (stat2.isFile()) {
35094
- const ext = path22.extname(fullPath).toLowerCase();
35095
- if (SOURCE_EXTENSIONS.has(ext)) {
35096
- files.push(fullPath);
35097
- }
35098
- }
35099
- }
35100
- return files;
35101
- }
35102
- var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, POWERSHELL_METACHARACTERS, TEST_PATTERNS, COMPOUND_TEST_EXTENSIONS, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
35073
+ var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, POWERSHELL_METACHARACTERS, TEST_PATTERNS, COMPOUND_TEST_EXTENSIONS, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
35103
35074
  var init_test_runner = __esm(() => {
35104
35075
  init_dist();
35105
35076
  init_discovery();
@@ -35233,6 +35204,26 @@ var init_test_runner = __esm(() => {
35233
35204
  return JSON.stringify(errorResult, null, 2);
35234
35205
  }
35235
35206
  const scope = args2.scope || "all";
35207
+ if (scope === "all") {
35208
+ const errorResult = {
35209
+ success: false,
35210
+ framework: "none",
35211
+ scope: "all",
35212
+ error: 'Full-suite test execution (scope: "all") is prohibited in interactive sessions',
35213
+ message: 'Use scope "convention" or "graph" with explicit files to run targeted tests in interactive mode. Full-suite runs are restricted to prevent excessive resource consumption.'
35214
+ };
35215
+ return JSON.stringify(errorResult, null, 2);
35216
+ }
35217
+ if ((scope === "convention" || scope === "graph") && (!args2.files || args2.files.length === 0)) {
35218
+ const errorResult = {
35219
+ success: false,
35220
+ framework: "none",
35221
+ scope,
35222
+ error: 'scope "convention" and "graph" require explicit files array - omitting files causes unsafe full-project discovery',
35223
+ message: 'When using scope "convention" or "graph", you must provide a non-empty "files" array. Use scope "all" for full project test suite without specifying files.'
35224
+ };
35225
+ return JSON.stringify(errorResult, null, 2);
35226
+ }
35236
35227
  const _files = args2.files || [];
35237
35228
  const coverage = args2.coverage || false;
35238
35229
  const timeout_ms = Math.min(args2.timeout_ms || DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);
@@ -35256,19 +35247,37 @@ var init_test_runner = __esm(() => {
35256
35247
  let testFiles = [];
35257
35248
  let graphFallbackReason;
35258
35249
  let effectiveScope = scope;
35259
- if (scope === "all") {
35260
- testFiles = [];
35261
- } else if (scope === "convention") {
35262
- const sourceFiles = args2.files && args2.files.length > 0 ? args2.files.filter((f) => {
35250
+ if (scope === "convention") {
35251
+ const sourceFiles = args2.files.filter((f) => {
35263
35252
  const ext = path22.extname(f).toLowerCase();
35264
35253
  return SOURCE_EXTENSIONS.has(ext);
35265
- }) : findSourceFiles(workingDir);
35254
+ });
35255
+ if (sourceFiles.length === 0) {
35256
+ const errorResult = {
35257
+ success: false,
35258
+ framework,
35259
+ scope,
35260
+ error: "Provided files contain no source files with recognized extensions",
35261
+ message: "The files array must contain at least one source file with a recognized extension (.ts, .tsx, .js, .jsx, .py, .rs, .ps1, etc.). Non-source files like README.md or config.json are not valid for test discovery."
35262
+ };
35263
+ return JSON.stringify(errorResult, null, 2);
35264
+ }
35266
35265
  testFiles = getTestFilesFromConvention(sourceFiles);
35267
35266
  } else if (scope === "graph") {
35268
- const sourceFiles = args2.files && args2.files.length > 0 ? args2.files.filter((f) => {
35267
+ const sourceFiles = args2.files.filter((f) => {
35269
35268
  const ext = path22.extname(f).toLowerCase();
35270
35269
  return SOURCE_EXTENSIONS.has(ext);
35271
- }) : findSourceFiles(workingDir);
35270
+ });
35271
+ if (sourceFiles.length === 0) {
35272
+ const errorResult = {
35273
+ success: false,
35274
+ framework,
35275
+ scope,
35276
+ error: "Provided files contain no source files with recognized extensions",
35277
+ message: "The files array must contain at least one source file with a recognized extension (.ts, .tsx, .js, .jsx, .py, .rs, .ps1, etc.). Non-source files like README.md or config.json are not valid for test discovery."
35278
+ };
35279
+ return JSON.stringify(errorResult, null, 2);
35280
+ }
35272
35281
  const graphTestFiles = await getTestFilesFromGraph(sourceFiles);
35273
35282
  if (graphTestFiles.length > 0) {
35274
35283
  testFiles = graphTestFiles;
@@ -35278,6 +35287,27 @@ var init_test_runner = __esm(() => {
35278
35287
  testFiles = getTestFilesFromConvention(sourceFiles);
35279
35288
  }
35280
35289
  }
35290
+ if (testFiles.length === 0) {
35291
+ const errorResult = {
35292
+ success: false,
35293
+ framework,
35294
+ scope: effectiveScope,
35295
+ error: "Provided source files resolved to zero test files",
35296
+ message: "No matching test files found for the provided source files. Check that test files exist with matching naming conventions (.spec.*, .test.*, __tests__/, tests/, test/)."
35297
+ };
35298
+ return JSON.stringify(errorResult, null, 2);
35299
+ }
35300
+ if (testFiles.length > MAX_SAFE_TEST_FILES) {
35301
+ const sampleFiles = testFiles.slice(0, 5);
35302
+ const errorResult = {
35303
+ success: false,
35304
+ framework,
35305
+ scope: effectiveScope,
35306
+ error: `Resolved test file count (${testFiles.length}) exceeds safe maximum (${MAX_SAFE_TEST_FILES})`,
35307
+ message: `Too many test files resolved (${testFiles.length}). Maximum allowed is ${MAX_SAFE_TEST_FILES}. Provide more specific source files to narrow down test scope. First few resolved: ${sampleFiles.join(", ")}`
35308
+ };
35309
+ return JSON.stringify(errorResult, null, 2);
35310
+ }
35281
35311
  const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir);
35282
35312
  if (graphFallbackReason && result.message) {
35283
35313
  result.message = `${result.message} (${graphFallbackReason})`;
@@ -41343,12 +41373,30 @@ When tests fail:
41343
41373
  OUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):
41344
41374
  Begin directly with the VERDICT line. Do NOT prepend "Here's my analysis..." or any conversational preamble.
41345
41375
 
41346
- VERDICT: PASS [N/N tests passed] | FAIL [N passed, M failed]
41347
- TESTS: [total count] tests, [pass count] passed, [fail count] failed
41376
+ VERDICT: PASS [N/N tests passed] | FAIL [N passed, M failed] | SKIPPED [reason]
41377
+ TESTS: [total count] tests, [pass count] passed, [fail count] failed, [skip count] skipped
41348
41378
  FAILURES: [list of failed test names + error messages, if any]
41349
41379
  COVERAGE: [X]% of public functions \u2014 [areas covered]
41350
41380
  BUGS FOUND: [list any source code bugs discovered during testing, or "none"]
41351
41381
 
41382
+ ## SKIP CONDITIONS
41383
+
41384
+ Use \`VERDICT: SKIPPED [reason]\` when tests CANNOT be executed due to environment or configuration issues \u2014 NOT when tests can run but fail. SKIPPED is not a bypass to avoid reporting real failures.
41385
+
41386
+ SKIP CONDITIONS (any of these justifies SKIPPED):
41387
+ 1. PROHIBITED SCOPE: test_runner refuses scope: "all" \u2014 this is blocked for safety
41388
+ 2. EXCESSIVE FILE COUNT: resolved test file count exceeds safe threshold (exceeds MAX_FILES limit)
41389
+ 3. FRAMEWORK DETECTION NONE: test_runner reports framework detection returns "none"
41390
+ 4. MISSING TEST FILE: test file does not exist after write (write failed or path error)
41391
+ 5. SESSION INSTABILITY: timeout, spawn failure, or runner crash that prevents execution
41392
+
41393
+ SKIPPED is NOT appropriate when:
41394
+ - Tests exist and can run but produce failures (use FAIL verdict)
41395
+ - Tests pass but coverage is low (use PASS verdict, note coverage warning)
41396
+ - You chose not to write tests (write them or explain why impossible)
41397
+
41398
+ When reporting SKIPPED, include the specific reason from the conditions above.
41399
+
41352
41400
  COVERAGE REPORTING:
41353
41401
  - After running tests, report the line/branch coverage percentage if the test runner provides it.
41354
41402
  - Format: COVERAGE_PCT: [N]% (or "N/A" if not available)
@@ -49144,6 +49192,15 @@ function extractPlanTaskId(text) {
49144
49192
  function getSeedTaskId(session) {
49145
49193
  return session.currentTaskId ?? session.lastCoderDelegationTaskId;
49146
49194
  }
49195
+ function getEvidenceTaskId(session) {
49196
+ const primary = session.currentTaskId ?? session.lastCoderDelegationTaskId;
49197
+ if (primary)
49198
+ return primary;
49199
+ if (session.taskWorkflowStates && session.taskWorkflowStates.size > 0) {
49200
+ return session.taskWorkflowStates.keys().next().value ?? null;
49201
+ }
49202
+ return null;
49203
+ }
49147
49204
  function createDelegationGateHook(config3, directory) {
49148
49205
  const enabled = config3.hooks?.delegation_gate !== false;
49149
49206
  const delegationMaxChars = config3.hooks?.delegation_max_chars ?? 4000;
@@ -49234,7 +49291,7 @@ function createDelegationGateHook(config3, directory) {
49234
49291
  }
49235
49292
  }
49236
49293
  if (typeof subagentType === "string") {
49237
- const evidenceTaskId = session.currentTaskId ?? session.lastCoderDelegationTaskId;
49294
+ const evidenceTaskId = getEvidenceTaskId(session);
49238
49295
  if (evidenceTaskId) {
49239
49296
  try {
49240
49297
  const gateAgents = [
@@ -49242,7 +49299,9 @@ function createDelegationGateHook(config3, directory) {
49242
49299
  "test_engineer",
49243
49300
  "docs",
49244
49301
  "designer",
49245
- "critic"
49302
+ "critic",
49303
+ "explorer",
49304
+ "sme"
49246
49305
  ];
49247
49306
  const targetAgentForEvidence = stripKnownSwarmPrefix(subagentType);
49248
49307
  if (gateAgents.includes(targetAgentForEvidence)) {
@@ -49350,16 +49409,16 @@ function createDelegationGateHook(config3, directory) {
49350
49409
  }
49351
49410
  }
49352
49411
  {
49353
- const evidenceTaskId = session.currentTaskId ?? session.lastCoderDelegationTaskId;
49412
+ const evidenceTaskId = getEvidenceTaskId(session);
49354
49413
  if (evidenceTaskId) {
49355
49414
  try {
49356
49415
  if (hasReviewer) {
49357
49416
  const { recordGateEvidence: recordGateEvidence2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
49358
- await recordGateEvidence2(directory, evidenceTaskId, "reviewer", input.sessionID);
49417
+ await recordGateEvidence2(process.cwd(), evidenceTaskId, "reviewer", input.sessionID);
49359
49418
  }
49360
49419
  if (hasTestEngineer) {
49361
49420
  const { recordGateEvidence: recordGateEvidence2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
49362
- await recordGateEvidence2(directory, evidenceTaskId, "test_engineer", input.sessionID);
49421
+ await recordGateEvidence2(process.cwd(), evidenceTaskId, "test_engineer", input.sessionID);
49363
49422
  }
49364
49423
  } catch (err2) {
49365
49424
  console.warn(`[delegation-gate] evidence write failed for task ${evidenceTaskId}: ${err2 instanceof Error ? err2.message : String(err2)}`);
@@ -54837,7 +54896,7 @@ var SKIP_DIRECTORIES2 = new Set([
54837
54896
  ".svn",
54838
54897
  ".hg"
54839
54898
  ]);
54840
- function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
54899
+ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
54841
54900
  let entries;
54842
54901
  try {
54843
54902
  entries = fs25.readdirSync(dir);
@@ -54866,7 +54925,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
54866
54925
  continue;
54867
54926
  }
54868
54927
  if (stat2.isDirectory()) {
54869
- findSourceFiles2(fullPath, files, stats);
54928
+ findSourceFiles(fullPath, files, stats);
54870
54929
  } else if (stat2.isFile()) {
54871
54930
  const ext = path38.extname(fullPath).toLowerCase();
54872
54931
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
@@ -54952,7 +55011,7 @@ var imports = tool({
54952
55011
  skippedFiles: 0,
54953
55012
  fileErrors: []
54954
55013
  };
54955
- const sourceFiles = findSourceFiles2(baseDir, [], scanStats);
55014
+ const sourceFiles = findSourceFiles(baseDir, [], scanStats);
54956
55015
  const filesToScan = sourceFiles.filter((f) => f !== targetFile).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).slice(0, MAX_CONSUMERS * 10);
54957
55016
  const consumers = [];
54958
55017
  let skippedFileCount = 0;
@@ -61429,7 +61488,7 @@ function isSupportedExtension(filePath) {
61429
61488
  const ext = path48.extname(filePath).toLowerCase();
61430
61489
  return SUPPORTED_EXTENSIONS2.has(ext);
61431
61490
  }
61432
- function findSourceFiles3(dir, files = []) {
61491
+ function findSourceFiles2(dir, files = []) {
61433
61492
  let entries;
61434
61493
  try {
61435
61494
  entries = fs35.readdirSync(dir);
@@ -61449,7 +61508,7 @@ function findSourceFiles3(dir, files = []) {
61449
61508
  continue;
61450
61509
  }
61451
61510
  if (stat2.isDirectory()) {
61452
- findSourceFiles3(fullPath, files);
61511
+ findSourceFiles2(fullPath, files);
61453
61512
  } else if (stat2.isFile()) {
61454
61513
  if (isSupportedExtension(fullPath)) {
61455
61514
  files.push(fullPath);
@@ -61561,7 +61620,7 @@ var todo_extract = createSwarmTool({
61561
61620
  return JSON.stringify(errorResult, null, 2);
61562
61621
  }
61563
61622
  } else {
61564
- findSourceFiles3(scanPath, filesToScan);
61623
+ findSourceFiles2(scanPath, filesToScan);
61565
61624
  }
61566
61625
  const allEntries = [];
61567
61626
  for (const filePath of filesToScan) {
@@ -3,6 +3,7 @@ export declare const MAX_OUTPUT_BYTES = 512000;
3
3
  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
+ export declare const MAX_SAFE_TEST_FILES = 50;
6
7
  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"];
7
8
  export type TestFramework = (typeof SUPPORTED_FRAMEWORKS)[number] | 'none';
8
9
  export interface TestRunnerArgs {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.25.2",
3
+ "version": "6.25.4",
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",