opencode-swarm 7.50.3 → 7.51.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/README.md +5 -0
- package/dist/cli/index.js +64 -16
- package/dist/index.js +1357 -578
- package/dist/lang/backend.d.ts +1 -0
- package/dist/tools/git-blame.d.ts +21 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/manifest.d.ts +1 -0
- package/dist/tools/suggest-patch.d.ts +1 -0
- package/dist/tools/test-runner.d.ts +3 -2
- package/dist/tools/tool-metadata.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -735,6 +735,11 @@ Swarm provides tools for managing generated skill lifecycles:
|
|
|
735
735
|
| mutation_test | Applies LLM-generated mutation patches to source files and runs tests to measure kill rate; verdict is pass/warn/fail based on configurable thresholds; used by the mutation_test gate (opt-in, off by default) |
|
|
736
736
|
| generate_mutants | Architect-only: generates LLM-based mutation patches (5–10 per function across 6 types: off-by-one, null substitution, operator swap, guard removal, branch swap, side-effect deletion) for direct consumption by the mutation_test tool; returns SKIP verdict on LLM failure rather than throwing |
|
|
737
737
|
| write_mutation_evidence | Architect-only: writes mutation gate results atomically to `.swarm/evidence/{phase}/mutation-gate.json`; accepts verdict (PASS/WARN/FAIL/SKIP), kill rate metrics, and optional survived mutant details; normalizes uppercase-to-lowercase before persisting |
|
|
738
|
+
| git_blame | Per-line git blame metadata (sha, author, date, summary) via `git blame --porcelain`; supports optional line range filtering |
|
|
739
|
+
| diff | Structured git diff with contract change detection; supports `summaryOnly` mode returning file list with additions/deletions counts |
|
|
740
|
+
| suggest_patch | Reviewer-safe structured patch suggestion; supports `format` parameter ('json' or 'unified') where unified outputs valid unified diff with `diff --git` headers, hunks, and context |
|
|
741
|
+
| test_runner | Auto-detect and run tests; supports `bail` parameter to inject framework-specific bail flags for early exit on first failure |
|
|
742
|
+
| symbols | Extract exported symbols from source files; supports `workspace` (boolean) and `name` (string) parameters for multi-file symbol search |
|
|
738
743
|
|
|
739
744
|
|
|
740
745
|
All tools run locally. No Docker, no network calls, no external APIs.
|
package/dist/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "opencode-swarm",
|
|
55
|
-
version: "7.
|
|
55
|
+
version: "7.51.0",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
|
@@ -16499,7 +16499,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
16499
16499
|
agents: ["architect", "reviewer", "critic_oversight"]
|
|
16500
16500
|
},
|
|
16501
16501
|
syntax_check: {
|
|
16502
|
-
description: "syntax
|
|
16502
|
+
description: "check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",
|
|
16503
16503
|
agents: ["architect", "coder", "test_engineer"]
|
|
16504
16504
|
},
|
|
16505
16505
|
placeholder_scan: {
|
|
@@ -16507,7 +16507,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
16507
16507
|
agents: ["architect", "reviewer"]
|
|
16508
16508
|
},
|
|
16509
16509
|
imports: {
|
|
16510
|
-
description: "
|
|
16510
|
+
description: "find all consumers that import from a given file \u2014 use before refactoring shared modules to avoid breaking unseen dependents",
|
|
16511
16511
|
agents: [
|
|
16512
16512
|
"architect",
|
|
16513
16513
|
"sme",
|
|
@@ -16525,11 +16525,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
16525
16525
|
]
|
|
16526
16526
|
},
|
|
16527
16527
|
lint: {
|
|
16528
|
-
description: "
|
|
16528
|
+
description: "run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",
|
|
16529
16529
|
agents: ["architect", "reviewer", "coder"]
|
|
16530
16530
|
},
|
|
16531
16531
|
secretscan: {
|
|
16532
|
-
description: "
|
|
16532
|
+
description: "scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",
|
|
16533
16533
|
agents: ["architect", "reviewer", "critic_oversight"]
|
|
16534
16534
|
},
|
|
16535
16535
|
sast_scan: {
|
|
@@ -16537,7 +16537,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
16537
16537
|
agents: ["architect", "reviewer", "critic_oversight"]
|
|
16538
16538
|
},
|
|
16539
16539
|
build_check: {
|
|
16540
|
-
description: "build
|
|
16540
|
+
description: "discover and run build, typecheck, and test commands for various project ecosystems in the working directory",
|
|
16541
16541
|
agents: ["architect", "coder", "test_engineer"]
|
|
16542
16542
|
},
|
|
16543
16543
|
pre_check_batch: {
|
|
@@ -16549,7 +16549,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
16549
16549
|
agents: ["architect"]
|
|
16550
16550
|
},
|
|
16551
16551
|
symbols: {
|
|
16552
|
-
description: "
|
|
16552
|
+
description: "extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",
|
|
16553
16553
|
agents: [
|
|
16554
16554
|
"architect",
|
|
16555
16555
|
"sme",
|
|
@@ -16620,7 +16620,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
16620
16620
|
agents: ["architect"]
|
|
16621
16621
|
},
|
|
16622
16622
|
checkpoint: {
|
|
16623
|
-
description: "
|
|
16623
|
+
description: "create named git checkpoints for save, restore, and delete \u2014 use before risky operations to enable rollback",
|
|
16624
16624
|
agents: ["architect"]
|
|
16625
16625
|
},
|
|
16626
16626
|
pkg_audit: {
|
|
@@ -16664,6 +16664,10 @@ var init_tool_metadata = __esm(() => {
|
|
|
16664
16664
|
"explorer"
|
|
16665
16665
|
]
|
|
16666
16666
|
},
|
|
16667
|
+
git_blame: {
|
|
16668
|
+
description: "per-line git blame metadata: sha, author, date, summary for each line in a file",
|
|
16669
|
+
agents: ["reviewer", "explorer", "architect"]
|
|
16670
|
+
},
|
|
16667
16671
|
gitingest: {
|
|
16668
16672
|
description: "fetch a GitHub repository full content via gitingest.com",
|
|
16669
16673
|
agents: ["architect", "docs", "explorer"]
|
|
@@ -21701,8 +21705,9 @@ var init_guardrails = __esm(() => {
|
|
|
21701
21705
|
function clearPendingCoderScope() {
|
|
21702
21706
|
pendingCoderScopeByTaskId.clear();
|
|
21703
21707
|
}
|
|
21704
|
-
var pendingCoderScopeByTaskId, ACTIVE_PARALLEL_TASK_STATES;
|
|
21708
|
+
var EvidenceTaskIdPlanSchema, pendingCoderScopeByTaskId, ACTIVE_PARALLEL_TASK_STATES;
|
|
21705
21709
|
var init_delegation_gate = __esm(() => {
|
|
21710
|
+
init_zod();
|
|
21706
21711
|
init_schema();
|
|
21707
21712
|
init_manager();
|
|
21708
21713
|
init_state();
|
|
@@ -21712,6 +21717,14 @@ var init_delegation_gate = __esm(() => {
|
|
|
21712
21717
|
init_guardrails();
|
|
21713
21718
|
init_normalize_tool_name();
|
|
21714
21719
|
init_utils2();
|
|
21720
|
+
EvidenceTaskIdPlanSchema = exports_external.object({
|
|
21721
|
+
phases: exports_external.array(exports_external.object({
|
|
21722
|
+
tasks: exports_external.array(exports_external.object({
|
|
21723
|
+
id: exports_external.string(),
|
|
21724
|
+
status: exports_external.string().optional()
|
|
21725
|
+
}).passthrough()).optional()
|
|
21726
|
+
}).passthrough()).optional()
|
|
21727
|
+
}).passthrough();
|
|
21715
21728
|
pendingCoderScopeByTaskId = new Map;
|
|
21716
21729
|
ACTIVE_PARALLEL_TASK_STATES = new Set([
|
|
21717
21730
|
"coder_delegated",
|
|
@@ -51206,11 +51219,14 @@ async function defaultSelectTestFramework(profile, dir) {
|
|
|
51206
51219
|
function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}) {
|
|
51207
51220
|
const scope = opts.scope ?? "all";
|
|
51208
51221
|
const coverage = opts.coverage ?? false;
|
|
51222
|
+
const bail = opts.bail ?? false;
|
|
51209
51223
|
switch (framework) {
|
|
51210
51224
|
case "bun": {
|
|
51211
51225
|
const args = ["bun", "test"];
|
|
51212
51226
|
if (coverage)
|
|
51213
51227
|
args.push("--coverage");
|
|
51228
|
+
if (bail)
|
|
51229
|
+
args.push("--bail");
|
|
51214
51230
|
if (scope !== "all" && files.length > 0)
|
|
51215
51231
|
args.push(...files);
|
|
51216
51232
|
return args;
|
|
@@ -51226,6 +51242,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
51226
51242
|
];
|
|
51227
51243
|
if (coverage)
|
|
51228
51244
|
args.push("--coverage");
|
|
51245
|
+
if (bail)
|
|
51246
|
+
args.push("--bail");
|
|
51229
51247
|
if (scope !== "all" && files.length > 0)
|
|
51230
51248
|
args.push(...files);
|
|
51231
51249
|
return args;
|
|
@@ -51234,12 +51252,16 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
51234
51252
|
const args = ["npx", "jest", "--json"];
|
|
51235
51253
|
if (coverage)
|
|
51236
51254
|
args.push("--coverage");
|
|
51255
|
+
if (bail)
|
|
51256
|
+
args.push("--bail");
|
|
51237
51257
|
if (scope !== "all" && files.length > 0)
|
|
51238
51258
|
args.push(...files);
|
|
51239
51259
|
return args;
|
|
51240
51260
|
}
|
|
51241
51261
|
case "mocha": {
|
|
51242
51262
|
const args = ["npx", "mocha"];
|
|
51263
|
+
if (bail)
|
|
51264
|
+
args.push("--bail");
|
|
51243
51265
|
if (scope !== "all" && files.length > 0)
|
|
51244
51266
|
args.push(...files);
|
|
51245
51267
|
return args;
|
|
@@ -51249,6 +51271,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
51249
51271
|
const args = isWindows ? ["python", "-m", "pytest"] : ["python3", "-m", "pytest"];
|
|
51250
51272
|
if (coverage)
|
|
51251
51273
|
args.push("--cov=.", "--cov-report=term-missing");
|
|
51274
|
+
if (bail)
|
|
51275
|
+
args.push("-x");
|
|
51252
51276
|
if (scope !== "all" && files.length > 0)
|
|
51253
51277
|
args.push(...files);
|
|
51254
51278
|
return args;
|
|
@@ -51302,6 +51326,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
51302
51326
|
return isCommandAvailable("flutter") ? ["flutter", "test", ...files] : ["dart", "test", ...files];
|
|
51303
51327
|
case "rspec": {
|
|
51304
51328
|
const args = isCommandAvailable("bundle") ? ["bundle", "exec", "rspec"] : ["rspec"];
|
|
51329
|
+
if (bail)
|
|
51330
|
+
args.push("--fail-fast");
|
|
51305
51331
|
if (scope !== "all" && files.length > 0)
|
|
51306
51332
|
args.push(...files);
|
|
51307
51333
|
return args;
|
|
@@ -53276,6 +53302,10 @@ function validateArgs2(args) {
|
|
|
53276
53302
|
if (typeof obj.coverage !== "boolean")
|
|
53277
53303
|
return false;
|
|
53278
53304
|
}
|
|
53305
|
+
if (obj.bail !== undefined) {
|
|
53306
|
+
if (typeof obj.bail !== "boolean")
|
|
53307
|
+
return false;
|
|
53308
|
+
}
|
|
53279
53309
|
if (obj.timeout_ms !== undefined) {
|
|
53280
53310
|
if (typeof obj.timeout_ms !== "number")
|
|
53281
53311
|
return false;
|
|
@@ -53351,7 +53381,7 @@ async function detectTestFrameworkViaDispatch(cwd) {
|
|
|
53351
53381
|
return "none";
|
|
53352
53382
|
}
|
|
53353
53383
|
}
|
|
53354
|
-
async function buildTestCommandViaDispatch(framework, scope, files, coverage, baseDir) {
|
|
53384
|
+
async function buildTestCommandViaDispatch(framework, scope, files, coverage, baseDir, bail) {
|
|
53355
53385
|
if (framework === "none")
|
|
53356
53386
|
return null;
|
|
53357
53387
|
try {
|
|
@@ -53360,7 +53390,8 @@ async function buildTestCommandViaDispatch(framework, scope, files, coverage, ba
|
|
|
53360
53390
|
if (backend?.buildTestCommand) {
|
|
53361
53391
|
const cmd = backend.buildTestCommand(framework, files, baseDir, {
|
|
53362
53392
|
scope,
|
|
53363
|
-
coverage
|
|
53393
|
+
coverage,
|
|
53394
|
+
bail
|
|
53364
53395
|
});
|
|
53365
53396
|
if (cmd)
|
|
53366
53397
|
return cmd;
|
|
@@ -53729,12 +53760,14 @@ function getTargetedExecutionUnsupportedReason(framework) {
|
|
|
53729
53760
|
return null;
|
|
53730
53761
|
}
|
|
53731
53762
|
}
|
|
53732
|
-
function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
53763
|
+
function buildTestCommand2(framework, scope, files, coverage, baseDir, bail) {
|
|
53733
53764
|
switch (framework) {
|
|
53734
53765
|
case "bun": {
|
|
53735
53766
|
const args = ["bun", "test"];
|
|
53736
53767
|
if (coverage)
|
|
53737
53768
|
args.push("--coverage");
|
|
53769
|
+
if (bail)
|
|
53770
|
+
args.push("--bail");
|
|
53738
53771
|
if (scope !== "all" && files.length > 0) {
|
|
53739
53772
|
args.push(...files);
|
|
53740
53773
|
}
|
|
@@ -53751,6 +53784,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53751
53784
|
];
|
|
53752
53785
|
if (coverage)
|
|
53753
53786
|
args.push("--coverage");
|
|
53787
|
+
if (bail)
|
|
53788
|
+
args.push("--bail=1");
|
|
53754
53789
|
if (scope !== "all" && files.length > 0) {
|
|
53755
53790
|
args.push(...files);
|
|
53756
53791
|
}
|
|
@@ -53760,6 +53795,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53760
53795
|
const args = ["npx", "jest", "--json"];
|
|
53761
53796
|
if (coverage)
|
|
53762
53797
|
args.push("--coverage");
|
|
53798
|
+
if (bail)
|
|
53799
|
+
args.push("--bail");
|
|
53763
53800
|
if (scope !== "all" && files.length > 0) {
|
|
53764
53801
|
args.push(...files);
|
|
53765
53802
|
}
|
|
@@ -53767,6 +53804,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53767
53804
|
}
|
|
53768
53805
|
case "mocha": {
|
|
53769
53806
|
const args = ["npx", "mocha"];
|
|
53807
|
+
if (bail)
|
|
53808
|
+
args.push("--bail");
|
|
53770
53809
|
if (scope !== "all" && files.length > 0) {
|
|
53771
53810
|
args.push(...files);
|
|
53772
53811
|
}
|
|
@@ -53777,6 +53816,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53777
53816
|
const args = isWindows ? ["python", "-m", "pytest"] : ["python3", "-m", "pytest"];
|
|
53778
53817
|
if (coverage)
|
|
53779
53818
|
args.push("--cov=.", "--cov-report=term-missing");
|
|
53819
|
+
if (bail)
|
|
53820
|
+
args.push("-x");
|
|
53780
53821
|
if (scope !== "all" && files.length > 0) {
|
|
53781
53822
|
args.push(...files);
|
|
53782
53823
|
}
|
|
@@ -53833,6 +53874,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53833
53874
|
return isCommandAvailable("flutter") ? ["flutter", "test", ...files] : ["dart", "test", ...files];
|
|
53834
53875
|
case "rspec": {
|
|
53835
53876
|
const args = isCommandAvailable("bundle") ? ["bundle", "exec", "rspec"] : ["rspec"];
|
|
53877
|
+
if (bail)
|
|
53878
|
+
args.push("--fail-fast");
|
|
53836
53879
|
if (scope !== "all" && files.length > 0) {
|
|
53837
53880
|
args.push(...files);
|
|
53838
53881
|
}
|
|
@@ -54218,7 +54261,7 @@ async function readBoundedStream(stream, maxBytes) {
|
|
|
54218
54261
|
}
|
|
54219
54262
|
return { text: decoder.decode(combined), truncated };
|
|
54220
54263
|
}
|
|
54221
|
-
async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
54264
|
+
async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail) {
|
|
54222
54265
|
if (scope !== "all" && files.length > 0) {
|
|
54223
54266
|
const unsupportedReason = getTargetedExecutionUnsupportedReason(framework);
|
|
54224
54267
|
if (unsupportedReason) {
|
|
@@ -54233,7 +54276,7 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
54233
54276
|
}
|
|
54234
54277
|
}
|
|
54235
54278
|
const useDispatchBuild = process.env.SWARM_LANG_BACKEND !== "legacy";
|
|
54236
|
-
const command = useDispatchBuild ? await buildTestCommandViaDispatch(framework, scope, files, coverage, cwd) ?? buildTestCommand2(framework, scope, files, coverage, cwd) : buildTestCommand2(framework, scope, files, coverage, cwd);
|
|
54279
|
+
const command = useDispatchBuild ? await buildTestCommandViaDispatch(framework, scope, files, coverage, cwd, bail) ?? buildTestCommand2(framework, scope, files, coverage, cwd, bail) : buildTestCommand2(framework, scope, files, coverage, cwd, bail);
|
|
54237
54280
|
if (!command) {
|
|
54238
54281
|
return {
|
|
54239
54282
|
success: false,
|
|
@@ -54581,6 +54624,7 @@ var init_test_runner = __esm(() => {
|
|
|
54581
54624
|
scope: exports_external.enum(["all", "convention", "graph", "impact"]).optional().describe('Test scope: "all" runs full suite, "convention" accepts direct test files or maps source files to tests by naming, "graph" finds related tests via imports from source files, "impact" finds tests covering changed source files via test-impact analysis'),
|
|
54582
54625
|
files: exports_external.array(exports_external.string()).optional().describe('Specific files to test. For "convention", pass source files or direct test files. For "graph" and "impact", pass source files only.'),
|
|
54583
54626
|
coverage: exports_external.boolean().optional().describe("Enable coverage reporting if supported"),
|
|
54627
|
+
bail: exports_external.boolean().optional().describe("Stop running tests after the first failure. Default false. Note: coverage may be incomplete when bail=true with coverage=true."),
|
|
54584
54628
|
timeout_ms: exports_external.number().optional().describe("Timeout in milliseconds (default 60000, max 300000)"),
|
|
54585
54629
|
allow_full_suite: exports_external.boolean().optional().describe('Explicit opt-in for scope "all". Required because full-suite output can destabilize SSE streaming.'),
|
|
54586
54630
|
working_directory: exports_external.string().optional().describe("Explicit project root directory. When provided, tests run relative to this path instead of the plugin context directory. Use this when CWD differs from the actual project root.")
|
|
@@ -54681,6 +54725,7 @@ var init_test_runner = __esm(() => {
|
|
|
54681
54725
|
}
|
|
54682
54726
|
const _files = args.files || [];
|
|
54683
54727
|
const coverage = args.coverage || false;
|
|
54728
|
+
const bail = args.bail || false;
|
|
54684
54729
|
const timeout_ms = Math.min(args.timeout_ms || DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
|
54685
54730
|
const useDispatch = process.env.SWARM_LANG_BACKEND !== "legacy";
|
|
54686
54731
|
let framework;
|
|
@@ -54919,7 +54964,7 @@ var init_test_runner = __esm(() => {
|
|
|
54919
54964
|
};
|
|
54920
54965
|
return JSON.stringify(errorResult, null, 2);
|
|
54921
54966
|
}
|
|
54922
|
-
const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir);
|
|
54967
|
+
const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir, bail);
|
|
54923
54968
|
recordAndAnalyzeResults(result, testFiles, workingDir, _files.length > 0 ? _files : undefined, result.testCases);
|
|
54924
54969
|
let historyReport;
|
|
54925
54970
|
if (!result.success && result.totals && result.totals.failed > 0) {
|
|
@@ -54935,6 +54980,9 @@ var init_test_runner = __esm(() => {
|
|
|
54935
54980
|
if (graphFallbackReason && result.message) {
|
|
54936
54981
|
result.message = `${result.message} (${graphFallbackReason})`;
|
|
54937
54982
|
}
|
|
54983
|
+
if (bail && coverage && result.message) {
|
|
54984
|
+
result.message = `${result.message} (coverage may be incomplete: bail=true stopped early)`;
|
|
54985
|
+
}
|
|
54938
54986
|
return JSON.stringify(result, null, 2);
|
|
54939
54987
|
}
|
|
54940
54988
|
});
|
|
@@ -55139,7 +55187,7 @@ async function runLintCheck(dir, linter, timeoutMs) {
|
|
|
55139
55187
|
async function runTestsCheck(_dir, scope, timeoutMs) {
|
|
55140
55188
|
const startTime = Date.now();
|
|
55141
55189
|
try {
|
|
55142
|
-
const result = await runTests("none", scope, [], false, timeoutMs, _dir);
|
|
55190
|
+
const result = await runTests("none", scope, [], false, timeoutMs, _dir, false);
|
|
55143
55191
|
if (!result.success) {
|
|
55144
55192
|
return {
|
|
55145
55193
|
type: "tests",
|