opencode-swarm 7.56.0 → 7.56.1
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 +326 -247
- package/dist/index.js +1791 -1454
- package/dist/lang/backends/php.d.ts +29 -0
- package/dist/lang/index.d.ts +1 -1
- package/dist/lang/runtime.d.ts +9 -1
- package/dist/sast/semgrep.d.ts +19 -0
- package/dist/tools/repo-graph/builder.d.ts +1 -8
- package/dist/tools/test-runner.d.ts +16 -0
- package/package.json +1 -1
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.56.
|
|
55
|
+
version: "7.56.1",
|
|
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",
|
|
@@ -42920,7 +42920,7 @@ var init_profiles = __esm(() => {
|
|
|
42920
42920
|
detectFiles: ["Cargo.toml"],
|
|
42921
42921
|
frameworks: [
|
|
42922
42922
|
{
|
|
42923
|
-
name: "cargo
|
|
42923
|
+
name: "cargo",
|
|
42924
42924
|
detect: "Cargo.toml",
|
|
42925
42925
|
cmd: "cargo test",
|
|
42926
42926
|
priority: 10
|
|
@@ -42992,7 +42992,7 @@ var init_profiles = __esm(() => {
|
|
|
42992
42992
|
test: {
|
|
42993
42993
|
detectFiles: ["go.mod"],
|
|
42994
42994
|
frameworks: [
|
|
42995
|
-
{ name: "go
|
|
42995
|
+
{ name: "go-test", detect: "go.mod", cmd: "go test ./...", priority: 10 }
|
|
42996
42996
|
]
|
|
42997
42997
|
},
|
|
42998
42998
|
lint: {
|
|
@@ -43067,13 +43067,13 @@ var init_profiles = __esm(() => {
|
|
|
43067
43067
|
detectFiles: ["pom.xml", "build.gradle", "build.gradle.kts"],
|
|
43068
43068
|
frameworks: [
|
|
43069
43069
|
{
|
|
43070
|
-
name: "maven
|
|
43070
|
+
name: "maven",
|
|
43071
43071
|
detect: "pom.xml",
|
|
43072
43072
|
cmd: "mvn test -q",
|
|
43073
43073
|
priority: 10
|
|
43074
43074
|
},
|
|
43075
43075
|
{
|
|
43076
|
-
name: "gradle
|
|
43076
|
+
name: "gradle",
|
|
43077
43077
|
detect: "build.gradle",
|
|
43078
43078
|
cmd: "gradle test -q",
|
|
43079
43079
|
priority: 9
|
|
@@ -43151,13 +43151,13 @@ var init_profiles = __esm(() => {
|
|
|
43151
43151
|
detectFiles: ["build.gradle.kts", "build.gradle"],
|
|
43152
43152
|
frameworks: [
|
|
43153
43153
|
{
|
|
43154
|
-
name: "gradle
|
|
43154
|
+
name: "gradle",
|
|
43155
43155
|
detect: "build.gradle.kts",
|
|
43156
43156
|
cmd: "gradle test -q",
|
|
43157
43157
|
priority: 10
|
|
43158
43158
|
},
|
|
43159
43159
|
{
|
|
43160
|
-
name: "gradle
|
|
43160
|
+
name: "gradle",
|
|
43161
43161
|
detect: "build.gradle",
|
|
43162
43162
|
cmd: "gradle test -q",
|
|
43163
43163
|
priority: 9
|
|
@@ -43165,11 +43165,11 @@ var init_profiles = __esm(() => {
|
|
|
43165
43165
|
]
|
|
43166
43166
|
},
|
|
43167
43167
|
lint: {
|
|
43168
|
-
detectFiles: [".
|
|
43168
|
+
detectFiles: ["build.gradle.kts", "build.gradle"],
|
|
43169
43169
|
linters: [
|
|
43170
43170
|
{
|
|
43171
43171
|
name: "ktlint",
|
|
43172
|
-
detect: ".
|
|
43172
|
+
detect: "build.gradle.kts",
|
|
43173
43173
|
cmd: "ktlint --format",
|
|
43174
43174
|
priority: 10
|
|
43175
43175
|
}
|
|
@@ -43229,7 +43229,7 @@ var init_profiles = __esm(() => {
|
|
|
43229
43229
|
detectFiles: ["*.csproj", "*.sln"],
|
|
43230
43230
|
frameworks: [
|
|
43231
43231
|
{
|
|
43232
|
-
name: "dotnet
|
|
43232
|
+
name: "dotnet-test",
|
|
43233
43233
|
detect: "*.csproj",
|
|
43234
43234
|
cmd: "dotnet test",
|
|
43235
43235
|
priority: 10
|
|
@@ -43380,7 +43380,7 @@ var init_profiles = __esm(() => {
|
|
|
43380
43380
|
detectFiles: ["Package.swift", "*.xcodeproj"],
|
|
43381
43381
|
frameworks: [
|
|
43382
43382
|
{
|
|
43383
|
-
name: "swift
|
|
43383
|
+
name: "swift-test",
|
|
43384
43384
|
detect: "Package.swift",
|
|
43385
43385
|
cmd: "swift test",
|
|
43386
43386
|
priority: 10
|
|
@@ -43707,8 +43707,14 @@ async function detectProjectLanguages(projectDir) {
|
|
|
43707
43707
|
}
|
|
43708
43708
|
for (const profile of LANGUAGE_REGISTRY.getAll()) {
|
|
43709
43709
|
for (const detectFile of profile.build.detectFiles) {
|
|
43710
|
-
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
43710
|
+
if (detectFile.includes("*") || detectFile.includes("?")) {
|
|
43711
|
+
const regex = new RegExp(`^${detectFile.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
|
|
43712
|
+
if (entries.some((name) => regex.test(name))) {
|
|
43713
|
+
detected.add(profile.id);
|
|
43714
|
+
break;
|
|
43715
|
+
}
|
|
43711
43716
|
continue;
|
|
43717
|
+
}
|
|
43712
43718
|
try {
|
|
43713
43719
|
await access3(join24(dir, detectFile));
|
|
43714
43720
|
detected.add(profile.id);
|
|
@@ -53161,12 +53167,85 @@ var init_registry_backend = __esm(() => {
|
|
|
53161
53167
|
LANGUAGE_BACKEND_REGISTRY = new LanguageBackendRegistry;
|
|
53162
53168
|
});
|
|
53163
53169
|
|
|
53164
|
-
// src/lang/
|
|
53170
|
+
// src/lang/framework-detector.ts
|
|
53165
53171
|
import * as fs21 from "fs";
|
|
53166
53172
|
import * as path43 from "path";
|
|
53173
|
+
function detectLaravelProject(directory) {
|
|
53174
|
+
const signals = getLaravelSignals(directory);
|
|
53175
|
+
const signalCount = [
|
|
53176
|
+
signals.hasArtisanFile,
|
|
53177
|
+
signals.hasLaravelFrameworkDep,
|
|
53178
|
+
signals.hasConfigApp
|
|
53179
|
+
].filter(Boolean).length;
|
|
53180
|
+
return signalCount >= 2;
|
|
53181
|
+
}
|
|
53182
|
+
function getLaravelSignals(directory) {
|
|
53183
|
+
const hasArtisanFile = checkArtisanFile(directory);
|
|
53184
|
+
const hasLaravelFrameworkDep = checkLaravelFrameworkDep(directory);
|
|
53185
|
+
const hasConfigApp = checkConfigApp(directory);
|
|
53186
|
+
return { hasArtisanFile, hasLaravelFrameworkDep, hasConfigApp };
|
|
53187
|
+
}
|
|
53188
|
+
function checkArtisanFile(directory) {
|
|
53189
|
+
const artisanPath = path43.join(directory, "artisan");
|
|
53190
|
+
if (!fs21.existsSync(artisanPath))
|
|
53191
|
+
return false;
|
|
53192
|
+
try {
|
|
53193
|
+
return fs21.statSync(artisanPath).isFile();
|
|
53194
|
+
} catch {
|
|
53195
|
+
return false;
|
|
53196
|
+
}
|
|
53197
|
+
}
|
|
53198
|
+
function checkLaravelFrameworkDep(directory) {
|
|
53199
|
+
const composerPath = path43.join(directory, "composer.json");
|
|
53200
|
+
if (!fs21.existsSync(composerPath))
|
|
53201
|
+
return false;
|
|
53202
|
+
try {
|
|
53203
|
+
const content = fs21.readFileSync(composerPath, "utf-8");
|
|
53204
|
+
const parsed = JSON.parse(content);
|
|
53205
|
+
const require2 = parsed?.require ?? {};
|
|
53206
|
+
return typeof require2["laravel/framework"] === "string";
|
|
53207
|
+
} catch {
|
|
53208
|
+
return false;
|
|
53209
|
+
}
|
|
53210
|
+
}
|
|
53211
|
+
function checkConfigApp(directory) {
|
|
53212
|
+
return fs21.existsSync(path43.join(directory, "config", "app.php"));
|
|
53213
|
+
}
|
|
53214
|
+
var init_framework_detector = () => {};
|
|
53215
|
+
|
|
53216
|
+
// src/lang/backends/php.ts
|
|
53217
|
+
async function selectFramework3(dir) {
|
|
53218
|
+
if (detectLaravelProject(dir)) {
|
|
53219
|
+
return {
|
|
53220
|
+
name: "laravel",
|
|
53221
|
+
detectedVia: "Laravel signals (artisan / composer.json / config/app.php)"
|
|
53222
|
+
};
|
|
53223
|
+
}
|
|
53224
|
+
return null;
|
|
53225
|
+
}
|
|
53226
|
+
function buildPhpBackend() {
|
|
53227
|
+
const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
|
|
53228
|
+
if (!profile) {
|
|
53229
|
+
throw new Error("buildPhpBackend: php profile not in LANGUAGE_REGISTRY. " + "profiles.ts must be imported before this backend.");
|
|
53230
|
+
}
|
|
53231
|
+
return {
|
|
53232
|
+
...defaultBackendFor(profile),
|
|
53233
|
+
selectFramework: selectFramework3
|
|
53234
|
+
};
|
|
53235
|
+
}
|
|
53236
|
+
var PROFILE_ID3 = "php";
|
|
53237
|
+
var init_php = __esm(() => {
|
|
53238
|
+
init_default_backend();
|
|
53239
|
+
init_framework_detector();
|
|
53240
|
+
init_profiles();
|
|
53241
|
+
});
|
|
53242
|
+
|
|
53243
|
+
// src/lang/backends/typescript.ts
|
|
53244
|
+
import * as fs22 from "fs";
|
|
53245
|
+
import * as path44 from "path";
|
|
53167
53246
|
function readPackageJsonRaw(dir) {
|
|
53168
53247
|
try {
|
|
53169
|
-
const content =
|
|
53248
|
+
const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
|
|
53170
53249
|
return JSON.parse(content);
|
|
53171
53250
|
} catch {
|
|
53172
53251
|
return null;
|
|
@@ -53216,7 +53295,7 @@ function selectionFromFramework(profile, fwName, dir, detectedVia) {
|
|
|
53216
53295
|
};
|
|
53217
53296
|
}
|
|
53218
53297
|
async function selectTestFramework(dir) {
|
|
53219
|
-
const profile = LANGUAGE_REGISTRY.get(
|
|
53298
|
+
const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
|
|
53220
53299
|
if (!profile)
|
|
53221
53300
|
return null;
|
|
53222
53301
|
const pkg = readPackageJson(dir);
|
|
@@ -53238,7 +53317,7 @@ async function selectTestFramework(dir) {
|
|
|
53238
53317
|
return defaultSelectTestFramework(profile, dir);
|
|
53239
53318
|
}
|
|
53240
53319
|
function buildTestCommand(framework, files, dir, opts) {
|
|
53241
|
-
const profile = LANGUAGE_REGISTRY.get(
|
|
53320
|
+
const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
|
|
53242
53321
|
if (!profile)
|
|
53243
53322
|
return null;
|
|
53244
53323
|
return defaultBuildTestCommand(profile, framework, files, dir, opts);
|
|
@@ -53246,7 +53325,7 @@ function buildTestCommand(framework, files, dir, opts) {
|
|
|
53246
53325
|
function parseTestOutput(framework, stdout, stderr, exitCode) {
|
|
53247
53326
|
return defaultParseTestOutput(framework, stdout, stderr, exitCode);
|
|
53248
53327
|
}
|
|
53249
|
-
async function
|
|
53328
|
+
async function selectFramework4(dir) {
|
|
53250
53329
|
const pkg = readPackageJson(dir);
|
|
53251
53330
|
if (!pkg)
|
|
53252
53331
|
return null;
|
|
@@ -53315,19 +53394,19 @@ function extractImports4(_sourceFile, source) {
|
|
|
53315
53394
|
return [...out];
|
|
53316
53395
|
}
|
|
53317
53396
|
async function selectBuildCommand(dir) {
|
|
53318
|
-
const profile = LANGUAGE_REGISTRY.get(
|
|
53397
|
+
const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
|
|
53319
53398
|
if (!profile)
|
|
53320
53399
|
return null;
|
|
53321
53400
|
return defaultSelectBuildCommand(profile, dir);
|
|
53322
53401
|
}
|
|
53323
53402
|
async function testFilesFor(sourceFile, dir) {
|
|
53324
|
-
const profile = LANGUAGE_REGISTRY.get(
|
|
53403
|
+
const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
|
|
53325
53404
|
if (!profile)
|
|
53326
53405
|
return [];
|
|
53327
53406
|
return defaultTestFilesFor(profile, sourceFile, dir);
|
|
53328
53407
|
}
|
|
53329
53408
|
function buildTypescriptBackend() {
|
|
53330
|
-
const profile = LANGUAGE_REGISTRY.get(
|
|
53409
|
+
const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
|
|
53331
53410
|
if (!profile) {
|
|
53332
53411
|
throw new Error("buildTypescriptBackend: typescript profile not in LANGUAGE_REGISTRY. " + "profiles.ts must be imported before this backend.");
|
|
53333
53412
|
}
|
|
@@ -53339,11 +53418,11 @@ function buildTypescriptBackend() {
|
|
|
53339
53418
|
extractImports: extractImports4,
|
|
53340
53419
|
selectBuildCommand,
|
|
53341
53420
|
testFilesFor,
|
|
53342
|
-
selectFramework:
|
|
53421
|
+
selectFramework: selectFramework4,
|
|
53343
53422
|
selectEntryPoints: selectEntryPoints3
|
|
53344
53423
|
};
|
|
53345
53424
|
}
|
|
53346
|
-
var
|
|
53425
|
+
var PROFILE_ID4 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals28;
|
|
53347
53426
|
var init_typescript = __esm(() => {
|
|
53348
53427
|
init_default_backend();
|
|
53349
53428
|
init_profiles();
|
|
@@ -53366,12 +53445,14 @@ function registerAllBackends() {
|
|
|
53366
53445
|
LANGUAGE_BACKEND_REGISTRY.register(buildTypescriptBackend());
|
|
53367
53446
|
LANGUAGE_BACKEND_REGISTRY.register(buildPythonBackend());
|
|
53368
53447
|
LANGUAGE_BACKEND_REGISTRY.register(buildGoBackend());
|
|
53448
|
+
LANGUAGE_BACKEND_REGISTRY.register(buildPhpBackend());
|
|
53369
53449
|
registered = true;
|
|
53370
53450
|
}
|
|
53371
53451
|
var registered = false;
|
|
53372
53452
|
var init_backends = __esm(() => {
|
|
53373
53453
|
init_registry_backend();
|
|
53374
53454
|
init_go();
|
|
53455
|
+
init_php();
|
|
53375
53456
|
init_python();
|
|
53376
53457
|
init_typescript();
|
|
53377
53458
|
registerAllBackends();
|
|
@@ -53385,11 +53466,11 @@ __export(exports_dispatch, {
|
|
|
53385
53466
|
clearDispatchCache: () => clearDispatchCache,
|
|
53386
53467
|
_internals: () => _internals29
|
|
53387
53468
|
});
|
|
53388
|
-
import * as
|
|
53389
|
-
import * as
|
|
53469
|
+
import * as fs23 from "fs";
|
|
53470
|
+
import * as path45 from "path";
|
|
53390
53471
|
function safeReaddirSet(dir) {
|
|
53391
53472
|
try {
|
|
53392
|
-
return new Set(
|
|
53473
|
+
return new Set(fs23.readdirSync(dir));
|
|
53393
53474
|
} catch {
|
|
53394
53475
|
return new Set;
|
|
53395
53476
|
}
|
|
@@ -53403,14 +53484,14 @@ function manifestHash(dir) {
|
|
|
53403
53484
|
if (!entries.has(name))
|
|
53404
53485
|
continue;
|
|
53405
53486
|
try {
|
|
53406
|
-
const stat4 =
|
|
53487
|
+
const stat4 = fs23.statSync(path45.join(dir, name));
|
|
53407
53488
|
parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
|
|
53408
53489
|
} catch {}
|
|
53409
53490
|
}
|
|
53410
53491
|
return parts.join("|");
|
|
53411
53492
|
}
|
|
53412
53493
|
function findManifestRoot(start) {
|
|
53413
|
-
const resolved =
|
|
53494
|
+
const resolved = path45.resolve(start);
|
|
53414
53495
|
const cached3 = manifestRootCache.get(resolved);
|
|
53415
53496
|
if (cached3 !== undefined)
|
|
53416
53497
|
return cached3;
|
|
@@ -53429,7 +53510,7 @@ function findManifestRoot(start) {
|
|
|
53429
53510
|
return cur;
|
|
53430
53511
|
}
|
|
53431
53512
|
}
|
|
53432
|
-
const parent =
|
|
53513
|
+
const parent = path45.dirname(cur);
|
|
53433
53514
|
if (parent === cur)
|
|
53434
53515
|
break;
|
|
53435
53516
|
cur = parent;
|
|
@@ -53538,14 +53619,14 @@ var init_dispatch = __esm(() => {
|
|
|
53538
53619
|
});
|
|
53539
53620
|
|
|
53540
53621
|
// src/tools/test-runner.ts
|
|
53541
|
-
import * as
|
|
53542
|
-
import * as
|
|
53622
|
+
import * as fs24 from "fs";
|
|
53623
|
+
import * as path46 from "path";
|
|
53543
53624
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
53544
53625
|
try {
|
|
53545
53626
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
53546
53627
|
const uniqueTestFiles = new Set;
|
|
53547
53628
|
for (const sourceFile of sourceFiles) {
|
|
53548
|
-
const resolvedPath =
|
|
53629
|
+
const resolvedPath = path46.resolve(cwd, sourceFile);
|
|
53549
53630
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
53550
53631
|
const testFiles = impactMap[normalizedPath];
|
|
53551
53632
|
if (testFiles) {
|
|
@@ -53627,19 +53708,19 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
53627
53708
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
53628
53709
|
}
|
|
53629
53710
|
function detectGoTest(cwd) {
|
|
53630
|
-
return
|
|
53711
|
+
return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
53631
53712
|
}
|
|
53632
53713
|
function detectJavaMaven(cwd) {
|
|
53633
|
-
return
|
|
53714
|
+
return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
53634
53715
|
}
|
|
53635
53716
|
function detectGradle(cwd) {
|
|
53636
|
-
const hasBuildFile =
|
|
53637
|
-
const hasGradlew =
|
|
53717
|
+
const hasBuildFile = fs24.existsSync(path46.join(cwd, "build.gradle")) || fs24.existsSync(path46.join(cwd, "build.gradle.kts"));
|
|
53718
|
+
const hasGradlew = fs24.existsSync(path46.join(cwd, "gradlew")) || fs24.existsSync(path46.join(cwd, "gradlew.bat"));
|
|
53638
53719
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
53639
53720
|
}
|
|
53640
53721
|
function detectDotnetTest(cwd) {
|
|
53641
53722
|
try {
|
|
53642
|
-
const files =
|
|
53723
|
+
const files = fs24.readdirSync(cwd);
|
|
53643
53724
|
const hasCsproj = files.some((f) => f.endsWith(".csproj"));
|
|
53644
53725
|
return hasCsproj && isCommandAvailable("dotnet");
|
|
53645
53726
|
} catch {
|
|
@@ -53647,25 +53728,25 @@ function detectDotnetTest(cwd) {
|
|
|
53647
53728
|
}
|
|
53648
53729
|
}
|
|
53649
53730
|
function detectCTest(cwd) {
|
|
53650
|
-
const hasSource =
|
|
53651
|
-
const hasBuildCache =
|
|
53731
|
+
const hasSource = fs24.existsSync(path46.join(cwd, "CMakeLists.txt"));
|
|
53732
|
+
const hasBuildCache = fs24.existsSync(path46.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path46.join(cwd, "build", "CMakeCache.txt"));
|
|
53652
53733
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
53653
53734
|
}
|
|
53654
53735
|
function detectSwiftTest(cwd) {
|
|
53655
|
-
return
|
|
53736
|
+
return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
53656
53737
|
}
|
|
53657
53738
|
function detectDartTest(cwd) {
|
|
53658
|
-
return
|
|
53739
|
+
return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
53659
53740
|
}
|
|
53660
53741
|
function detectRSpec(cwd) {
|
|
53661
|
-
const hasRSpecFile =
|
|
53662
|
-
const hasGemfile =
|
|
53663
|
-
const hasSpecDir =
|
|
53742
|
+
const hasRSpecFile = fs24.existsSync(path46.join(cwd, ".rspec"));
|
|
53743
|
+
const hasGemfile = fs24.existsSync(path46.join(cwd, "Gemfile"));
|
|
53744
|
+
const hasSpecDir = fs24.existsSync(path46.join(cwd, "spec"));
|
|
53664
53745
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
53665
53746
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
53666
53747
|
}
|
|
53667
53748
|
function detectMinitest(cwd) {
|
|
53668
|
-
return
|
|
53749
|
+
return fs24.existsSync(path46.join(cwd, "test")) && (fs24.existsSync(path46.join(cwd, "Gemfile")) || fs24.existsSync(path46.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
53669
53750
|
}
|
|
53670
53751
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
53671
53752
|
try {
|
|
@@ -53728,9 +53809,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
53728
53809
|
async function detectTestFramework(cwd) {
|
|
53729
53810
|
const baseDir = cwd;
|
|
53730
53811
|
try {
|
|
53731
|
-
const packageJsonPath =
|
|
53732
|
-
if (
|
|
53733
|
-
const content =
|
|
53812
|
+
const packageJsonPath = path46.join(baseDir, "package.json");
|
|
53813
|
+
if (fs24.existsSync(packageJsonPath)) {
|
|
53814
|
+
const content = fs24.readFileSync(packageJsonPath, "utf-8");
|
|
53734
53815
|
const pkg = JSON.parse(content);
|
|
53735
53816
|
const _deps = pkg.dependencies || {};
|
|
53736
53817
|
const devDeps = pkg.devDependencies || {};
|
|
@@ -53749,38 +53830,38 @@ async function detectTestFramework(cwd) {
|
|
|
53749
53830
|
return "jest";
|
|
53750
53831
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
53751
53832
|
return "mocha";
|
|
53752
|
-
if (
|
|
53833
|
+
if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
|
|
53753
53834
|
if (scripts.test?.includes("bun"))
|
|
53754
53835
|
return "bun";
|
|
53755
53836
|
}
|
|
53756
53837
|
}
|
|
53757
53838
|
} catch {}
|
|
53758
53839
|
try {
|
|
53759
|
-
const pyprojectTomlPath =
|
|
53760
|
-
const setupCfgPath =
|
|
53761
|
-
const requirementsTxtPath =
|
|
53762
|
-
if (
|
|
53763
|
-
const content =
|
|
53840
|
+
const pyprojectTomlPath = path46.join(baseDir, "pyproject.toml");
|
|
53841
|
+
const setupCfgPath = path46.join(baseDir, "setup.cfg");
|
|
53842
|
+
const requirementsTxtPath = path46.join(baseDir, "requirements.txt");
|
|
53843
|
+
if (fs24.existsSync(pyprojectTomlPath)) {
|
|
53844
|
+
const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
|
|
53764
53845
|
if (content.includes("[tool.pytest"))
|
|
53765
53846
|
return "pytest";
|
|
53766
53847
|
if (content.includes("pytest"))
|
|
53767
53848
|
return "pytest";
|
|
53768
53849
|
}
|
|
53769
|
-
if (
|
|
53770
|
-
const content =
|
|
53850
|
+
if (fs24.existsSync(setupCfgPath)) {
|
|
53851
|
+
const content = fs24.readFileSync(setupCfgPath, "utf-8");
|
|
53771
53852
|
if (content.includes("[pytest]"))
|
|
53772
53853
|
return "pytest";
|
|
53773
53854
|
}
|
|
53774
|
-
if (
|
|
53775
|
-
const content =
|
|
53855
|
+
if (fs24.existsSync(requirementsTxtPath)) {
|
|
53856
|
+
const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
|
|
53776
53857
|
if (content.includes("pytest"))
|
|
53777
53858
|
return "pytest";
|
|
53778
53859
|
}
|
|
53779
53860
|
} catch {}
|
|
53780
53861
|
try {
|
|
53781
|
-
const cargoTomlPath =
|
|
53782
|
-
if (
|
|
53783
|
-
const content =
|
|
53862
|
+
const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
|
|
53863
|
+
if (fs24.existsSync(cargoTomlPath)) {
|
|
53864
|
+
const content = fs24.readFileSync(cargoTomlPath, "utf-8");
|
|
53784
53865
|
if (content.includes("[dev-dependencies]")) {
|
|
53785
53866
|
if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
|
|
53786
53867
|
return "cargo";
|
|
@@ -53789,10 +53870,10 @@ async function detectTestFramework(cwd) {
|
|
|
53789
53870
|
}
|
|
53790
53871
|
} catch {}
|
|
53791
53872
|
try {
|
|
53792
|
-
const pesterConfigPath =
|
|
53793
|
-
const pesterConfigJsonPath =
|
|
53794
|
-
const pesterPs1Path =
|
|
53795
|
-
if (
|
|
53873
|
+
const pesterConfigPath = path46.join(baseDir, "pester.config.ps1");
|
|
53874
|
+
const pesterConfigJsonPath = path46.join(baseDir, "pester.config.ps1.json");
|
|
53875
|
+
const pesterPs1Path = path46.join(baseDir, "tests.ps1");
|
|
53876
|
+
if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
|
|
53796
53877
|
return "pester";
|
|
53797
53878
|
}
|
|
53798
53879
|
} catch {}
|
|
@@ -53820,12 +53901,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
53820
53901
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
53821
53902
|
}
|
|
53822
53903
|
function resolveWorkspacePath(file3, workingDir) {
|
|
53823
|
-
return
|
|
53904
|
+
return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
|
|
53824
53905
|
}
|
|
53825
53906
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
53826
53907
|
if (!preferRelative)
|
|
53827
53908
|
return absolutePath;
|
|
53828
|
-
return
|
|
53909
|
+
return path46.relative(workingDir, absolutePath);
|
|
53829
53910
|
}
|
|
53830
53911
|
function dedupePush(target, value) {
|
|
53831
53912
|
if (!target.includes(value)) {
|
|
@@ -53862,18 +53943,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
53862
53943
|
}
|
|
53863
53944
|
}
|
|
53864
53945
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
53865
|
-
const relativeDir =
|
|
53946
|
+
const relativeDir = path46.dirname(relativePath);
|
|
53866
53947
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
53867
53948
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
53868
|
-
const rootDir =
|
|
53869
|
-
return nestedRelativeDir ? [rootDir,
|
|
53949
|
+
const rootDir = path46.join(workingDir, dirName);
|
|
53950
|
+
return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
53870
53951
|
});
|
|
53871
53952
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
53872
53953
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
53873
|
-
directories.push(
|
|
53954
|
+
directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
53874
53955
|
}
|
|
53875
53956
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
53876
|
-
directories.push(
|
|
53957
|
+
directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
53877
53958
|
}
|
|
53878
53959
|
return [...new Set(directories)];
|
|
53879
53960
|
}
|
|
@@ -53901,23 +53982,23 @@ function isLanguageSpecificTestFile(basename7) {
|
|
|
53901
53982
|
}
|
|
53902
53983
|
function isConventionTestFilePath(filePath) {
|
|
53903
53984
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
53904
|
-
const basename7 =
|
|
53985
|
+
const basename7 = path46.basename(filePath);
|
|
53905
53986
|
return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
|
|
53906
53987
|
}
|
|
53907
53988
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
53908
53989
|
const testFiles = [];
|
|
53909
53990
|
for (const file3 of sourceFiles) {
|
|
53910
53991
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
53911
|
-
const relativeFile =
|
|
53912
|
-
const basename7 =
|
|
53913
|
-
const dirname23 =
|
|
53914
|
-
const preferRelativeOutput = !
|
|
53992
|
+
const relativeFile = path46.relative(workingDir, absoluteFile);
|
|
53993
|
+
const basename7 = path46.basename(absoluteFile);
|
|
53994
|
+
const dirname23 = path46.dirname(absoluteFile);
|
|
53995
|
+
const preferRelativeOutput = !path46.isAbsolute(file3);
|
|
53915
53996
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
53916
53997
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
53917
53998
|
continue;
|
|
53918
53999
|
}
|
|
53919
54000
|
const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
|
|
53920
|
-
const ext =
|
|
54001
|
+
const ext = path46.extname(basename7);
|
|
53921
54002
|
const genericTestNames = [
|
|
53922
54003
|
`${nameWithoutExt}.spec${ext}`,
|
|
53923
54004
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -53926,7 +54007,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
53926
54007
|
const colocatedCandidates = [
|
|
53927
54008
|
...genericTestNames,
|
|
53928
54009
|
...languageSpecificTestNames
|
|
53929
|
-
].map((candidateName) =>
|
|
54010
|
+
].map((candidateName) => path46.join(dirname23, candidateName));
|
|
53930
54011
|
const testDirectoryNames = [
|
|
53931
54012
|
basename7,
|
|
53932
54013
|
...genericTestNames,
|
|
@@ -53935,11 +54016,11 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
53935
54016
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
53936
54017
|
const possibleTestFiles = [
|
|
53937
54018
|
...colocatedCandidates,
|
|
53938
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
53939
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
54019
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path46.join(dirname23, dirName, candidateName))),
|
|
54020
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path46.join(candidateDir, candidateName)))
|
|
53940
54021
|
];
|
|
53941
54022
|
for (const testFile of possibleTestFiles) {
|
|
53942
|
-
if (
|
|
54023
|
+
if (fs24.existsSync(testFile)) {
|
|
53943
54024
|
dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
|
|
53944
54025
|
}
|
|
53945
54026
|
}
|
|
@@ -53956,8 +54037,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53956
54037
|
for (const testFile of candidateTestFiles) {
|
|
53957
54038
|
try {
|
|
53958
54039
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
53959
|
-
const content =
|
|
53960
|
-
const testDir =
|
|
54040
|
+
const content = fs24.readFileSync(absoluteTestFile, "utf-8");
|
|
54041
|
+
const testDir = path46.dirname(absoluteTestFile);
|
|
53961
54042
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
53962
54043
|
let match;
|
|
53963
54044
|
match = importRegex.exec(content);
|
|
@@ -53965,8 +54046,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53965
54046
|
const importPath = match[1];
|
|
53966
54047
|
let resolvedImport;
|
|
53967
54048
|
if (importPath.startsWith(".")) {
|
|
53968
|
-
resolvedImport =
|
|
53969
|
-
const existingExt =
|
|
54049
|
+
resolvedImport = path46.resolve(testDir, importPath);
|
|
54050
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53970
54051
|
if (!existingExt) {
|
|
53971
54052
|
for (const extToTry of [
|
|
53972
54053
|
".ts",
|
|
@@ -53977,7 +54058,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53977
54058
|
".cjs"
|
|
53978
54059
|
]) {
|
|
53979
54060
|
const withExt = resolvedImport + extToTry;
|
|
53980
|
-
if (absoluteSourceFiles.includes(withExt) ||
|
|
54061
|
+
if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
|
|
53981
54062
|
resolvedImport = withExt;
|
|
53982
54063
|
break;
|
|
53983
54064
|
}
|
|
@@ -53986,12 +54067,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53986
54067
|
} else {
|
|
53987
54068
|
continue;
|
|
53988
54069
|
}
|
|
53989
|
-
const importBasename =
|
|
53990
|
-
const importDir =
|
|
54070
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
54071
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53991
54072
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53992
|
-
const sourceDir =
|
|
53993
|
-
const sourceBasename =
|
|
53994
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
54073
|
+
const sourceDir = path46.dirname(sourceFile);
|
|
54074
|
+
const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
|
|
54075
|
+
const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
|
|
53995
54076
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53996
54077
|
dedupePush(testFiles, testFile);
|
|
53997
54078
|
break;
|
|
@@ -54004,8 +54085,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
54004
54085
|
while (match !== null) {
|
|
54005
54086
|
const importPath = match[1];
|
|
54006
54087
|
if (importPath.startsWith(".")) {
|
|
54007
|
-
let resolvedImport =
|
|
54008
|
-
const existingExt =
|
|
54088
|
+
let resolvedImport = path46.resolve(testDir, importPath);
|
|
54089
|
+
const existingExt = path46.extname(resolvedImport);
|
|
54009
54090
|
if (!existingExt) {
|
|
54010
54091
|
for (const extToTry of [
|
|
54011
54092
|
".ts",
|
|
@@ -54016,18 +54097,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
54016
54097
|
".cjs"
|
|
54017
54098
|
]) {
|
|
54018
54099
|
const withExt = resolvedImport + extToTry;
|
|
54019
|
-
if (absoluteSourceFiles.includes(withExt) ||
|
|
54100
|
+
if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
|
|
54020
54101
|
resolvedImport = withExt;
|
|
54021
54102
|
break;
|
|
54022
54103
|
}
|
|
54023
54104
|
}
|
|
54024
54105
|
}
|
|
54025
|
-
const importDir =
|
|
54026
|
-
const importBasename =
|
|
54106
|
+
const importDir = path46.dirname(resolvedImport);
|
|
54107
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
54027
54108
|
for (const sourceFile of absoluteSourceFiles) {
|
|
54028
|
-
const sourceDir =
|
|
54029
|
-
const sourceBasename =
|
|
54030
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
54109
|
+
const sourceDir = path46.dirname(sourceFile);
|
|
54110
|
+
const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
|
|
54111
|
+
const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
|
|
54031
54112
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
54032
54113
|
dedupePush(testFiles, testFile);
|
|
54033
54114
|
break;
|
|
@@ -54147,8 +54228,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir, bail) {
|
|
|
54147
54228
|
return ["mvn", "test"];
|
|
54148
54229
|
case "gradle": {
|
|
54149
54230
|
const isWindows = process.platform === "win32";
|
|
54150
|
-
const hasGradlewBat =
|
|
54151
|
-
const hasGradlew =
|
|
54231
|
+
const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
|
|
54232
|
+
const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
|
|
54152
54233
|
if (hasGradlewBat && isWindows)
|
|
54153
54234
|
return ["gradlew.bat", "test"];
|
|
54154
54235
|
if (hasGradlew)
|
|
@@ -54165,7 +54246,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir, bail) {
|
|
|
54165
54246
|
"cmake-build-release",
|
|
54166
54247
|
"out"
|
|
54167
54248
|
];
|
|
54168
|
-
const actualBuildDir = buildDirCandidates.find((d) =>
|
|
54249
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
54169
54250
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
54170
54251
|
}
|
|
54171
54252
|
case "swift-test":
|
|
@@ -54599,13 +54680,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
54599
54680
|
};
|
|
54600
54681
|
}
|
|
54601
54682
|
const startTime = Date.now();
|
|
54602
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
54683
|
+
const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
54603
54684
|
try {
|
|
54604
54685
|
if (vitestJsonOutputPath) {
|
|
54605
54686
|
try {
|
|
54606
|
-
|
|
54607
|
-
if (
|
|
54608
|
-
|
|
54687
|
+
fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
|
|
54688
|
+
if (fs24.existsSync(vitestJsonOutputPath)) {
|
|
54689
|
+
fs24.unlinkSync(vitestJsonOutputPath);
|
|
54609
54690
|
}
|
|
54610
54691
|
} catch {}
|
|
54611
54692
|
}
|
|
@@ -54631,8 +54712,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
54631
54712
|
}
|
|
54632
54713
|
if (vitestJsonOutputPath) {
|
|
54633
54714
|
try {
|
|
54634
|
-
if (
|
|
54635
|
-
const vitestJsonOutput =
|
|
54715
|
+
if (fs24.existsSync(vitestJsonOutputPath)) {
|
|
54716
|
+
const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
|
|
54636
54717
|
if (vitestJsonOutput.trim().length > 0) {
|
|
54637
54718
|
output += (output ? `
|
|
54638
54719
|
` : "") + vitestJsonOutput;
|
|
@@ -54719,10 +54800,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
54719
54800
|
}
|
|
54720
54801
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
54721
54802
|
const normalized = testFile.replace(/\\/g, "/");
|
|
54722
|
-
if (!
|
|
54803
|
+
if (!path46.isAbsolute(testFile))
|
|
54723
54804
|
return normalized;
|
|
54724
|
-
const relative9 =
|
|
54725
|
-
if (relative9.startsWith("..") ||
|
|
54805
|
+
const relative9 = path46.relative(workingDir, testFile);
|
|
54806
|
+
if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
|
|
54726
54807
|
return normalized;
|
|
54727
54808
|
}
|
|
54728
54809
|
return relative9.replace(/\\/g, "/");
|
|
@@ -54829,28 +54910,26 @@ var init_test_runner = __esm(() => {
|
|
|
54829
54910
|
init_resolve_working_directory();
|
|
54830
54911
|
POWERSHELL_METACHARACTERS = /[|;&`$(){}[\]<>"'#*?\x00-\x1f]/;
|
|
54831
54912
|
DISPATCH_FRAMEWORK_MAP = {
|
|
54832
|
-
"bun:test": "bun",
|
|
54833
54913
|
bun: "bun",
|
|
54834
54914
|
vitest: "vitest",
|
|
54835
54915
|
jest: "jest",
|
|
54836
54916
|
mocha: "mocha",
|
|
54837
54917
|
pytest: "pytest",
|
|
54838
|
-
"cargo test": "cargo",
|
|
54839
54918
|
cargo: "cargo",
|
|
54840
54919
|
pester: "pester",
|
|
54841
|
-
"go
|
|
54842
|
-
|
|
54843
|
-
|
|
54844
|
-
"
|
|
54845
|
-
"gradle-kts": "gradle",
|
|
54846
|
-
"dotnet test": "dotnet-test",
|
|
54920
|
+
"go-test": "go-test",
|
|
54921
|
+
maven: "maven",
|
|
54922
|
+
gradle: "gradle",
|
|
54923
|
+
"dotnet-test": "dotnet-test",
|
|
54847
54924
|
ctest: "ctest",
|
|
54848
|
-
"swift
|
|
54925
|
+
"swift-test": "swift-test",
|
|
54926
|
+
"dart-test": "dart-test",
|
|
54927
|
+
rspec: "rspec",
|
|
54928
|
+
minitest: "minitest",
|
|
54929
|
+
"bun:test": "bun",
|
|
54849
54930
|
"xcodebuild-test": "swift-test",
|
|
54850
54931
|
"flutter test": "dart-test",
|
|
54851
|
-
"dart test": "dart-test"
|
|
54852
|
-
rspec: "rspec",
|
|
54853
|
-
minitest: "minitest"
|
|
54932
|
+
"dart test": "dart-test"
|
|
54854
54933
|
};
|
|
54855
54934
|
COMPOUND_TEST_EXTENSIONS = [
|
|
54856
54935
|
".test.ts",
|
|
@@ -55062,7 +55141,7 @@ var init_test_runner = __esm(() => {
|
|
|
55062
55141
|
const sourceFiles = args.files.filter((file3) => {
|
|
55063
55142
|
if (directTestFiles.includes(file3))
|
|
55064
55143
|
return false;
|
|
55065
|
-
const ext =
|
|
55144
|
+
const ext = path46.extname(file3).toLowerCase();
|
|
55066
55145
|
return SOURCE_EXTENSIONS.has(ext);
|
|
55067
55146
|
});
|
|
55068
55147
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -55108,7 +55187,7 @@ var init_test_runner = __esm(() => {
|
|
|
55108
55187
|
if (isConventionTestFilePath(f)) {
|
|
55109
55188
|
return false;
|
|
55110
55189
|
}
|
|
55111
|
-
const ext =
|
|
55190
|
+
const ext = path46.extname(f).toLowerCase();
|
|
55112
55191
|
return SOURCE_EXTENSIONS.has(ext);
|
|
55113
55192
|
});
|
|
55114
55193
|
if (sourceFiles.length === 0) {
|
|
@@ -55158,7 +55237,7 @@ var init_test_runner = __esm(() => {
|
|
|
55158
55237
|
if (isConventionTestFilePath(f)) {
|
|
55159
55238
|
return false;
|
|
55160
55239
|
}
|
|
55161
|
-
const ext =
|
|
55240
|
+
const ext = path46.extname(f).toLowerCase();
|
|
55162
55241
|
return SOURCE_EXTENSIONS.has(ext);
|
|
55163
55242
|
});
|
|
55164
55243
|
if (sourceFiles.length === 0) {
|
|
@@ -55210,8 +55289,8 @@ var init_test_runner = __esm(() => {
|
|
|
55210
55289
|
}
|
|
55211
55290
|
if (impactResult.impactedTests.length > 0) {
|
|
55212
55291
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
55213
|
-
const relativePath =
|
|
55214
|
-
return
|
|
55292
|
+
const relativePath = path46.relative(workingDir, absPath);
|
|
55293
|
+
return path46.isAbsolute(relativePath) ? absPath : relativePath;
|
|
55215
55294
|
});
|
|
55216
55295
|
} else {
|
|
55217
55296
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -55289,8 +55368,8 @@ var init_test_runner = __esm(() => {
|
|
|
55289
55368
|
});
|
|
55290
55369
|
|
|
55291
55370
|
// src/services/preflight-service.ts
|
|
55292
|
-
import * as
|
|
55293
|
-
import * as
|
|
55371
|
+
import * as fs25 from "fs";
|
|
55372
|
+
import * as path47 from "path";
|
|
55294
55373
|
function validateDirectoryPath(dir) {
|
|
55295
55374
|
if (!dir || typeof dir !== "string") {
|
|
55296
55375
|
throw new Error("Directory path is required");
|
|
@@ -55298,8 +55377,8 @@ function validateDirectoryPath(dir) {
|
|
|
55298
55377
|
if (dir.includes("..")) {
|
|
55299
55378
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
55300
55379
|
}
|
|
55301
|
-
const normalized =
|
|
55302
|
-
const absolutePath =
|
|
55380
|
+
const normalized = path47.normalize(dir);
|
|
55381
|
+
const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
|
|
55303
55382
|
return absolutePath;
|
|
55304
55383
|
}
|
|
55305
55384
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -55322,9 +55401,9 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
55322
55401
|
}
|
|
55323
55402
|
function getPackageVersion(dir) {
|
|
55324
55403
|
try {
|
|
55325
|
-
const packagePath =
|
|
55326
|
-
if (
|
|
55327
|
-
const content =
|
|
55404
|
+
const packagePath = path47.join(dir, "package.json");
|
|
55405
|
+
if (fs25.existsSync(packagePath)) {
|
|
55406
|
+
const content = fs25.readFileSync(packagePath, "utf-8");
|
|
55328
55407
|
const pkg = JSON.parse(content);
|
|
55329
55408
|
return pkg.version ?? null;
|
|
55330
55409
|
}
|
|
@@ -55333,9 +55412,9 @@ function getPackageVersion(dir) {
|
|
|
55333
55412
|
}
|
|
55334
55413
|
function getChangelogVersion(dir) {
|
|
55335
55414
|
try {
|
|
55336
|
-
const changelogPath =
|
|
55337
|
-
if (
|
|
55338
|
-
const content =
|
|
55415
|
+
const changelogPath = path47.join(dir, "CHANGELOG.md");
|
|
55416
|
+
if (fs25.existsSync(changelogPath)) {
|
|
55417
|
+
const content = fs25.readFileSync(changelogPath, "utf-8");
|
|
55339
55418
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
55340
55419
|
if (match) {
|
|
55341
55420
|
return match[1];
|
|
@@ -55347,10 +55426,10 @@ function getChangelogVersion(dir) {
|
|
|
55347
55426
|
function getVersionFileVersion(dir) {
|
|
55348
55427
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
55349
55428
|
for (const file3 of possibleFiles) {
|
|
55350
|
-
const filePath =
|
|
55351
|
-
if (
|
|
55429
|
+
const filePath = path47.join(dir, file3);
|
|
55430
|
+
if (fs25.existsSync(filePath)) {
|
|
55352
55431
|
try {
|
|
55353
|
-
const content =
|
|
55432
|
+
const content = fs25.readFileSync(filePath, "utf-8").trim();
|
|
55354
55433
|
const match = content.match(/(\d+\.\d+\.\d+)/);
|
|
55355
55434
|
if (match) {
|
|
55356
55435
|
return match[1];
|
|
@@ -55689,8 +55768,8 @@ async function runEvidenceCheck(dir) {
|
|
|
55689
55768
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
55690
55769
|
const startTime = Date.now();
|
|
55691
55770
|
try {
|
|
55692
|
-
const specPath =
|
|
55693
|
-
if (!
|
|
55771
|
+
const specPath = path47.join(dir, ".swarm", "spec.md");
|
|
55772
|
+
if (!fs25.existsSync(specPath)) {
|
|
55694
55773
|
return {
|
|
55695
55774
|
type: "req_coverage",
|
|
55696
55775
|
status: "skip",
|
|
@@ -56806,8 +56885,8 @@ var init_manager3 = __esm(() => {
|
|
|
56806
56885
|
});
|
|
56807
56886
|
|
|
56808
56887
|
// src/commands/reset.ts
|
|
56809
|
-
import * as
|
|
56810
|
-
import * as
|
|
56888
|
+
import * as fs26 from "fs";
|
|
56889
|
+
import * as path48 from "path";
|
|
56811
56890
|
async function handleResetCommand(directory, args) {
|
|
56812
56891
|
const hasConfirm = args.includes("--confirm");
|
|
56813
56892
|
if (!hasConfirm) {
|
|
@@ -56835,8 +56914,8 @@ async function handleResetCommand(directory, args) {
|
|
|
56835
56914
|
for (const filename of filesToReset) {
|
|
56836
56915
|
try {
|
|
56837
56916
|
const resolvedPath = validateSwarmPath(directory, filename);
|
|
56838
|
-
if (
|
|
56839
|
-
|
|
56917
|
+
if (fs26.existsSync(resolvedPath)) {
|
|
56918
|
+
fs26.unlinkSync(resolvedPath);
|
|
56840
56919
|
results.push(`- \u2705 Deleted ${filename}`);
|
|
56841
56920
|
} else {
|
|
56842
56921
|
results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
|
|
@@ -56847,9 +56926,9 @@ async function handleResetCommand(directory, args) {
|
|
|
56847
56926
|
}
|
|
56848
56927
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
56849
56928
|
try {
|
|
56850
|
-
const rootPath =
|
|
56851
|
-
if (
|
|
56852
|
-
|
|
56929
|
+
const rootPath = path48.join(directory, filename);
|
|
56930
|
+
if (fs26.existsSync(rootPath)) {
|
|
56931
|
+
fs26.unlinkSync(rootPath);
|
|
56853
56932
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
56854
56933
|
}
|
|
56855
56934
|
} catch {}
|
|
@@ -56862,8 +56941,8 @@ async function handleResetCommand(directory, args) {
|
|
|
56862
56941
|
}
|
|
56863
56942
|
try {
|
|
56864
56943
|
const summariesPath = validateSwarmPath(directory, "summaries");
|
|
56865
|
-
if (
|
|
56866
|
-
|
|
56944
|
+
if (fs26.existsSync(summariesPath)) {
|
|
56945
|
+
fs26.rmSync(summariesPath, { recursive: true, force: true });
|
|
56867
56946
|
results.push("- \u2705 Deleted summaries/ directory");
|
|
56868
56947
|
} else {
|
|
56869
56948
|
results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
|
|
@@ -56886,14 +56965,14 @@ var init_reset = __esm(() => {
|
|
|
56886
56965
|
});
|
|
56887
56966
|
|
|
56888
56967
|
// src/commands/reset-session.ts
|
|
56889
|
-
import * as
|
|
56890
|
-
import * as
|
|
56968
|
+
import * as fs27 from "fs";
|
|
56969
|
+
import * as path49 from "path";
|
|
56891
56970
|
async function handleResetSessionCommand(directory, _args) {
|
|
56892
56971
|
const results = [];
|
|
56893
56972
|
try {
|
|
56894
56973
|
const statePath = validateSwarmPath(directory, "session/state.json");
|
|
56895
|
-
if (
|
|
56896
|
-
|
|
56974
|
+
if (fs27.existsSync(statePath)) {
|
|
56975
|
+
fs27.unlinkSync(statePath);
|
|
56897
56976
|
results.push("\u2705 Deleted .swarm/session/state.json");
|
|
56898
56977
|
} else {
|
|
56899
56978
|
results.push("\u23ED\uFE0F state.json not found (already clean)");
|
|
@@ -56902,15 +56981,15 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
56902
56981
|
results.push("\u274C Failed to delete state.json");
|
|
56903
56982
|
}
|
|
56904
56983
|
try {
|
|
56905
|
-
const sessionDir =
|
|
56906
|
-
if (
|
|
56907
|
-
const files =
|
|
56984
|
+
const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
56985
|
+
if (fs27.existsSync(sessionDir)) {
|
|
56986
|
+
const files = fs27.readdirSync(sessionDir);
|
|
56908
56987
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
56909
56988
|
let deletedCount = 0;
|
|
56910
56989
|
for (const file3 of otherFiles) {
|
|
56911
|
-
const filePath =
|
|
56912
|
-
if (
|
|
56913
|
-
|
|
56990
|
+
const filePath = path49.join(sessionDir, file3);
|
|
56991
|
+
if (fs27.lstatSync(filePath).isFile()) {
|
|
56992
|
+
fs27.unlinkSync(filePath);
|
|
56914
56993
|
deletedCount++;
|
|
56915
56994
|
}
|
|
56916
56995
|
}
|
|
@@ -56940,7 +57019,7 @@ var init_reset_session = __esm(() => {
|
|
|
56940
57019
|
});
|
|
56941
57020
|
|
|
56942
57021
|
// src/summaries/manager.ts
|
|
56943
|
-
import * as
|
|
57022
|
+
import * as path50 from "path";
|
|
56944
57023
|
function sanitizeSummaryId(id) {
|
|
56945
57024
|
if (!id || id.length === 0) {
|
|
56946
57025
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -56963,7 +57042,7 @@ function sanitizeSummaryId(id) {
|
|
|
56963
57042
|
}
|
|
56964
57043
|
async function loadFullOutput(directory, id) {
|
|
56965
57044
|
const sanitizedId = sanitizeSummaryId(id);
|
|
56966
|
-
const relativePath =
|
|
57045
|
+
const relativePath = path50.join("summaries", `${sanitizedId}.json`);
|
|
56967
57046
|
validateSwarmPath(directory, relativePath);
|
|
56968
57047
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
56969
57048
|
if (content === null) {
|
|
@@ -57025,18 +57104,18 @@ var init_retrieve = __esm(() => {
|
|
|
57025
57104
|
});
|
|
57026
57105
|
|
|
57027
57106
|
// src/commands/rollback.ts
|
|
57028
|
-
import * as
|
|
57029
|
-
import * as
|
|
57107
|
+
import * as fs28 from "fs";
|
|
57108
|
+
import * as path51 from "path";
|
|
57030
57109
|
async function handleRollbackCommand(directory, args) {
|
|
57031
57110
|
const phaseArg = args[0];
|
|
57032
57111
|
if (!phaseArg) {
|
|
57033
57112
|
const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
57034
|
-
if (!
|
|
57113
|
+
if (!fs28.existsSync(manifestPath2)) {
|
|
57035
57114
|
return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
|
|
57036
57115
|
}
|
|
57037
57116
|
let manifest2;
|
|
57038
57117
|
try {
|
|
57039
|
-
manifest2 = JSON.parse(
|
|
57118
|
+
manifest2 = JSON.parse(fs28.readFileSync(manifestPath2, "utf-8"));
|
|
57040
57119
|
} catch {
|
|
57041
57120
|
return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
|
|
57042
57121
|
}
|
|
@@ -57058,12 +57137,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
57058
57137
|
return "Error: Phase number must be a positive integer.";
|
|
57059
57138
|
}
|
|
57060
57139
|
const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
57061
|
-
if (!
|
|
57140
|
+
if (!fs28.existsSync(manifestPath)) {
|
|
57062
57141
|
return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
|
|
57063
57142
|
}
|
|
57064
57143
|
let manifest;
|
|
57065
57144
|
try {
|
|
57066
|
-
manifest = JSON.parse(
|
|
57145
|
+
manifest = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
57067
57146
|
} catch {
|
|
57068
57147
|
return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
|
|
57069
57148
|
}
|
|
@@ -57073,10 +57152,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
57073
57152
|
return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
|
|
57074
57153
|
}
|
|
57075
57154
|
const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
|
|
57076
|
-
if (!
|
|
57155
|
+
if (!fs28.existsSync(checkpointDir)) {
|
|
57077
57156
|
return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
|
|
57078
57157
|
}
|
|
57079
|
-
const checkpointFiles =
|
|
57158
|
+
const checkpointFiles = fs28.readdirSync(checkpointDir);
|
|
57080
57159
|
if (checkpointFiles.length === 0) {
|
|
57081
57160
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
57082
57161
|
}
|
|
@@ -57091,10 +57170,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
57091
57170
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
57092
57171
|
continue;
|
|
57093
57172
|
}
|
|
57094
|
-
const src =
|
|
57095
|
-
const dest =
|
|
57173
|
+
const src = path51.join(checkpointDir, file3);
|
|
57174
|
+
const dest = path51.join(swarmDir, file3);
|
|
57096
57175
|
try {
|
|
57097
|
-
|
|
57176
|
+
fs28.cpSync(src, dest, { recursive: true, force: true });
|
|
57098
57177
|
successes.push(file3);
|
|
57099
57178
|
} catch (error93) {
|
|
57100
57179
|
failures.push({ file: file3, error: error93.message });
|
|
@@ -57111,14 +57190,14 @@ async function handleRollbackCommand(directory, args) {
|
|
|
57111
57190
|
].join(`
|
|
57112
57191
|
`);
|
|
57113
57192
|
}
|
|
57114
|
-
const existingLedgerPath =
|
|
57115
|
-
if (
|
|
57116
|
-
|
|
57193
|
+
const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
|
|
57194
|
+
if (fs28.existsSync(existingLedgerPath)) {
|
|
57195
|
+
fs28.unlinkSync(existingLedgerPath);
|
|
57117
57196
|
}
|
|
57118
57197
|
try {
|
|
57119
|
-
const planJsonPath =
|
|
57120
|
-
if (
|
|
57121
|
-
const planRaw =
|
|
57198
|
+
const planJsonPath = path51.join(swarmDir, "plan.json");
|
|
57199
|
+
if (fs28.existsSync(planJsonPath)) {
|
|
57200
|
+
const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
|
|
57122
57201
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
57123
57202
|
const planId = derivePlanId(plan);
|
|
57124
57203
|
const planHash = computePlanHash(plan);
|
|
@@ -57145,7 +57224,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
57145
57224
|
timestamp: new Date().toISOString()
|
|
57146
57225
|
};
|
|
57147
57226
|
try {
|
|
57148
|
-
|
|
57227
|
+
fs28.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
57149
57228
|
`);
|
|
57150
57229
|
} catch (error93) {
|
|
57151
57230
|
console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
|
|
@@ -57206,11 +57285,11 @@ Ensure this is a git repository with commit history.`;
|
|
|
57206
57285
|
const report = reportLines.filter(Boolean).join(`
|
|
57207
57286
|
`);
|
|
57208
57287
|
try {
|
|
57209
|
-
const
|
|
57210
|
-
const
|
|
57211
|
-
const reportPath =
|
|
57212
|
-
await
|
|
57213
|
-
await
|
|
57288
|
+
const fs29 = await import("fs/promises");
|
|
57289
|
+
const path52 = await import("path");
|
|
57290
|
+
const reportPath = path52.join(directory, ".swarm", "simulate-report.md");
|
|
57291
|
+
await fs29.mkdir(path52.dirname(reportPath), { recursive: true });
|
|
57292
|
+
await fs29.writeFile(reportPath, report, "utf-8");
|
|
57214
57293
|
} catch (err) {
|
|
57215
57294
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
57216
57295
|
warn(`simulate: failed to write report to ${directory}/.swarm/simulate-report.md`, writeErr);
|
|
@@ -57232,15 +57311,15 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
57232
57311
|
}
|
|
57233
57312
|
|
|
57234
57313
|
// src/turbo/lean/state.ts
|
|
57235
|
-
import * as
|
|
57236
|
-
import * as
|
|
57314
|
+
import * as fs29 from "fs";
|
|
57315
|
+
import * as path52 from "path";
|
|
57237
57316
|
function nowISO2() {
|
|
57238
57317
|
return new Date().toISOString();
|
|
57239
57318
|
}
|
|
57240
57319
|
function ensureSwarmDir2(directory) {
|
|
57241
|
-
const swarmDir =
|
|
57242
|
-
if (!
|
|
57243
|
-
|
|
57320
|
+
const swarmDir = path52.resolve(directory, ".swarm");
|
|
57321
|
+
if (!fs29.existsSync(swarmDir)) {
|
|
57322
|
+
fs29.mkdirSync(swarmDir, { recursive: true });
|
|
57244
57323
|
}
|
|
57245
57324
|
return swarmDir;
|
|
57246
57325
|
}
|
|
@@ -57282,17 +57361,17 @@ function markStateUnreadable2(directory, reason) {
|
|
|
57282
57361
|
}
|
|
57283
57362
|
function readPersisted2(directory) {
|
|
57284
57363
|
try {
|
|
57285
|
-
const filePath =
|
|
57286
|
-
if (!
|
|
57364
|
+
const filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
57365
|
+
if (!fs29.existsSync(filePath)) {
|
|
57287
57366
|
const seed = emptyPersisted2();
|
|
57288
57367
|
try {
|
|
57289
57368
|
ensureSwarmDir2(directory);
|
|
57290
|
-
|
|
57369
|
+
fs29.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
|
|
57291
57370
|
`, "utf-8");
|
|
57292
57371
|
} catch {}
|
|
57293
57372
|
return seed;
|
|
57294
57373
|
}
|
|
57295
|
-
const raw =
|
|
57374
|
+
const raw = fs29.readFileSync(filePath, "utf-8");
|
|
57296
57375
|
const parsed = JSON.parse(raw);
|
|
57297
57376
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
|
|
57298
57377
|
markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
|
|
@@ -57318,7 +57397,7 @@ function writePersisted2(directory, persisted) {
|
|
|
57318
57397
|
let payload;
|
|
57319
57398
|
try {
|
|
57320
57399
|
ensureSwarmDir2(directory);
|
|
57321
|
-
filePath =
|
|
57400
|
+
filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
57322
57401
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
57323
57402
|
persisted.updatedAt = nowISO2();
|
|
57324
57403
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -57329,14 +57408,14 @@ function writePersisted2(directory, persisted) {
|
|
|
57329
57408
|
throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
|
|
57330
57409
|
}
|
|
57331
57410
|
try {
|
|
57332
|
-
|
|
57333
|
-
|
|
57411
|
+
fs29.writeFileSync(tmpPath, payload, "utf-8");
|
|
57412
|
+
fs29.renameSync(tmpPath, filePath);
|
|
57334
57413
|
} catch (error93) {
|
|
57335
57414
|
const msg = error93 instanceof Error ? error93.message : String(error93);
|
|
57336
57415
|
error(`[turbo/lean/state] Failed to persist ${STATE_FILE2} atomically: ${msg}`);
|
|
57337
57416
|
try {
|
|
57338
|
-
if (
|
|
57339
|
-
|
|
57417
|
+
if (fs29.existsSync(tmpPath)) {
|
|
57418
|
+
fs29.unlinkSync(tmpPath);
|
|
57340
57419
|
}
|
|
57341
57420
|
} catch {}
|
|
57342
57421
|
throw new Error(`Lean Turbo state persistence failed: ${msg}`);
|
|
@@ -57445,10 +57524,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
57445
57524
|
|
|
57446
57525
|
// src/services/status-service.ts
|
|
57447
57526
|
import * as fsSync2 from "fs";
|
|
57448
|
-
import * as
|
|
57527
|
+
import * as path53 from "path";
|
|
57449
57528
|
function readSpecStalenessSnapshot(directory) {
|
|
57450
57529
|
try {
|
|
57451
|
-
const p =
|
|
57530
|
+
const p = path53.join(directory, ".swarm", "spec-staleness.json");
|
|
57452
57531
|
if (!fsSync2.existsSync(p))
|
|
57453
57532
|
return { stale: false };
|
|
57454
57533
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -57973,8 +58052,8 @@ var init_write_retro2 = __esm(() => {
|
|
|
57973
58052
|
});
|
|
57974
58053
|
|
|
57975
58054
|
// src/commands/command-dispatch.ts
|
|
57976
|
-
import
|
|
57977
|
-
import
|
|
58055
|
+
import fs30 from "fs";
|
|
58056
|
+
import path54 from "path";
|
|
57978
58057
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
57979
58058
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
57980
58059
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -58010,11 +58089,11 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
58010
58089
|
`);
|
|
58011
58090
|
}
|
|
58012
58091
|
function maybeMarkFirstRun(directory) {
|
|
58013
|
-
const sentinelPath =
|
|
58092
|
+
const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
|
|
58014
58093
|
try {
|
|
58015
|
-
const swarmDir =
|
|
58016
|
-
|
|
58017
|
-
|
|
58094
|
+
const swarmDir = path54.join(directory, ".swarm");
|
|
58095
|
+
fs30.mkdirSync(swarmDir, { recursive: true });
|
|
58096
|
+
fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
58018
58097
|
`, { flag: "wx" });
|
|
58019
58098
|
return true;
|
|
58020
58099
|
} catch {
|
|
@@ -58762,24 +58841,24 @@ function validateAliases() {
|
|
|
58762
58841
|
}
|
|
58763
58842
|
aliasTargets.get(target).push(name);
|
|
58764
58843
|
const visited = new Set;
|
|
58765
|
-
const
|
|
58844
|
+
const path55 = [];
|
|
58766
58845
|
let current = target;
|
|
58767
58846
|
while (current) {
|
|
58768
58847
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
58769
58848
|
if (!currentEntry)
|
|
58770
58849
|
break;
|
|
58771
58850
|
if (visited.has(current)) {
|
|
58772
|
-
const cycleStart =
|
|
58851
|
+
const cycleStart = path55.indexOf(current);
|
|
58773
58852
|
const fullChain = [
|
|
58774
58853
|
name,
|
|
58775
|
-
...
|
|
58854
|
+
...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
|
|
58776
58855
|
current
|
|
58777
58856
|
].join(" \u2192 ");
|
|
58778
58857
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
58779
58858
|
break;
|
|
58780
58859
|
}
|
|
58781
58860
|
visited.add(current);
|
|
58782
|
-
|
|
58861
|
+
path55.push(current);
|
|
58783
58862
|
current = currentEntry.aliasOf || "";
|
|
58784
58863
|
}
|
|
58785
58864
|
}
|
|
@@ -59398,68 +59477,68 @@ init_package();
|
|
|
59398
59477
|
init_registry();
|
|
59399
59478
|
init_cache_paths();
|
|
59400
59479
|
init_constants();
|
|
59401
|
-
import * as
|
|
59480
|
+
import * as fs31 from "fs";
|
|
59402
59481
|
import * as os8 from "os";
|
|
59403
|
-
import * as
|
|
59482
|
+
import * as path55 from "path";
|
|
59404
59483
|
var { version: version5 } = package_default;
|
|
59405
59484
|
var CONFIG_DIR = getPluginConfigDir();
|
|
59406
|
-
var OPENCODE_CONFIG_PATH =
|
|
59407
|
-
var PLUGIN_CONFIG_PATH =
|
|
59408
|
-
var PROMPTS_DIR =
|
|
59485
|
+
var OPENCODE_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode.json");
|
|
59486
|
+
var PLUGIN_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode-swarm.json");
|
|
59487
|
+
var PROMPTS_DIR = path55.join(CONFIG_DIR, "opencode-swarm");
|
|
59409
59488
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
59410
59489
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
59411
59490
|
function isSafeCachePath(p) {
|
|
59412
|
-
const resolved =
|
|
59413
|
-
const home =
|
|
59491
|
+
const resolved = path55.resolve(p);
|
|
59492
|
+
const home = path55.resolve(os8.homedir());
|
|
59414
59493
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
59415
59494
|
return false;
|
|
59416
59495
|
}
|
|
59417
|
-
const segments = resolved.split(
|
|
59496
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
59418
59497
|
if (segments.length < 4) {
|
|
59419
59498
|
return false;
|
|
59420
59499
|
}
|
|
59421
|
-
const leaf =
|
|
59500
|
+
const leaf = path55.basename(resolved);
|
|
59422
59501
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
59423
59502
|
return false;
|
|
59424
59503
|
}
|
|
59425
|
-
const parent =
|
|
59504
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
59426
59505
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
59427
59506
|
return false;
|
|
59428
59507
|
}
|
|
59429
|
-
const grandparent =
|
|
59508
|
+
const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
|
|
59430
59509
|
if (grandparent !== "opencode") {
|
|
59431
59510
|
return false;
|
|
59432
59511
|
}
|
|
59433
59512
|
return true;
|
|
59434
59513
|
}
|
|
59435
59514
|
function isSafeLockFilePath(p) {
|
|
59436
|
-
const resolved =
|
|
59437
|
-
const home =
|
|
59515
|
+
const resolved = path55.resolve(p);
|
|
59516
|
+
const home = path55.resolve(os8.homedir());
|
|
59438
59517
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
59439
59518
|
return false;
|
|
59440
59519
|
}
|
|
59441
|
-
const segments = resolved.split(
|
|
59520
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
59442
59521
|
if (segments.length < 4) {
|
|
59443
59522
|
return false;
|
|
59444
59523
|
}
|
|
59445
|
-
const leaf =
|
|
59524
|
+
const leaf = path55.basename(resolved);
|
|
59446
59525
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
59447
59526
|
return false;
|
|
59448
59527
|
}
|
|
59449
|
-
const parent =
|
|
59528
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
59450
59529
|
if (parent !== "opencode") {
|
|
59451
59530
|
return false;
|
|
59452
59531
|
}
|
|
59453
59532
|
return true;
|
|
59454
59533
|
}
|
|
59455
59534
|
function ensureDir(dir) {
|
|
59456
|
-
if (!
|
|
59457
|
-
|
|
59535
|
+
if (!fs31.existsSync(dir)) {
|
|
59536
|
+
fs31.mkdirSync(dir, { recursive: true });
|
|
59458
59537
|
}
|
|
59459
59538
|
}
|
|
59460
59539
|
function loadJson(filepath) {
|
|
59461
59540
|
try {
|
|
59462
|
-
const content =
|
|
59541
|
+
const content = fs31.readFileSync(filepath, "utf-8");
|
|
59463
59542
|
const stripped = content.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (match, comment) => comment ? "" : match).replace(/,(\s*[}\]])/g, "$1");
|
|
59464
59543
|
return JSON.parse(stripped);
|
|
59465
59544
|
} catch {
|
|
@@ -59467,14 +59546,14 @@ function loadJson(filepath) {
|
|
|
59467
59546
|
}
|
|
59468
59547
|
}
|
|
59469
59548
|
function saveJson(filepath, data) {
|
|
59470
|
-
|
|
59549
|
+
fs31.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
|
|
59471
59550
|
`, "utf-8");
|
|
59472
59551
|
}
|
|
59473
59552
|
function writeProjectConfigIfMissing(cwd) {
|
|
59474
59553
|
try {
|
|
59475
|
-
const opencodeDir =
|
|
59476
|
-
const projectConfigPath =
|
|
59477
|
-
if (
|
|
59554
|
+
const opencodeDir = path55.join(cwd, ".opencode");
|
|
59555
|
+
const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
|
|
59556
|
+
if (fs31.existsSync(projectConfigPath)) {
|
|
59478
59557
|
return;
|
|
59479
59558
|
}
|
|
59480
59559
|
ensureDir(opencodeDir);
|
|
@@ -59490,7 +59569,7 @@ async function install() {
|
|
|
59490
59569
|
`);
|
|
59491
59570
|
ensureDir(CONFIG_DIR);
|
|
59492
59571
|
ensureDir(PROMPTS_DIR);
|
|
59493
|
-
const LEGACY_CONFIG_PATH =
|
|
59572
|
+
const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
|
|
59494
59573
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
59495
59574
|
if (!opencodeConfig) {
|
|
59496
59575
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|
|
@@ -59537,7 +59616,7 @@ async function install() {
|
|
|
59537
59616
|
console.warn(`\u26A0 Could not clear opencode lock file \u2014 you may need to delete it manually:
|
|
59538
59617
|
${failed}`);
|
|
59539
59618
|
}
|
|
59540
|
-
if (!
|
|
59619
|
+
if (!fs31.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
59541
59620
|
const defaultConfig = {
|
|
59542
59621
|
agents: { ...DEFAULT_AGENT_CONFIGS },
|
|
59543
59622
|
max_iterations: 5
|
|
@@ -59616,14 +59695,14 @@ function evictPluginCaches() {
|
|
|
59616
59695
|
const cleared = [];
|
|
59617
59696
|
const failed = [];
|
|
59618
59697
|
for (const cachePath of OPENCODE_PLUGIN_CACHE_PATHS) {
|
|
59619
|
-
if (!
|
|
59698
|
+
if (!fs31.existsSync(cachePath))
|
|
59620
59699
|
continue;
|
|
59621
59700
|
if (!isSafeCachePath(cachePath)) {
|
|
59622
59701
|
failed.push(`${cachePath} (refused: failed safety check)`);
|
|
59623
59702
|
continue;
|
|
59624
59703
|
}
|
|
59625
59704
|
try {
|
|
59626
|
-
|
|
59705
|
+
fs31.rmSync(cachePath, { recursive: true, force: true });
|
|
59627
59706
|
cleared.push(cachePath);
|
|
59628
59707
|
} catch (err) {
|
|
59629
59708
|
failed.push(`${cachePath} (${err instanceof Error ? err.message : String(err)})`);
|
|
@@ -59635,14 +59714,14 @@ function evictLockFiles() {
|
|
|
59635
59714
|
const cleared = [];
|
|
59636
59715
|
const failed = [];
|
|
59637
59716
|
for (const lockPath of OPENCODE_PLUGIN_LOCK_FILE_PATHS) {
|
|
59638
|
-
if (!
|
|
59717
|
+
if (!fs31.existsSync(lockPath))
|
|
59639
59718
|
continue;
|
|
59640
59719
|
if (!isSafeLockFilePath(lockPath)) {
|
|
59641
59720
|
failed.push(`${lockPath} (refused: failed safety check)`);
|
|
59642
59721
|
continue;
|
|
59643
59722
|
}
|
|
59644
59723
|
try {
|
|
59645
|
-
|
|
59724
|
+
fs31.unlinkSync(lockPath);
|
|
59646
59725
|
cleared.push(lockPath);
|
|
59647
59726
|
} catch (err) {
|
|
59648
59727
|
const code = err?.code;
|
|
@@ -59661,7 +59740,7 @@ async function uninstall() {
|
|
|
59661
59740
|
`);
|
|
59662
59741
|
const opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
59663
59742
|
if (!opencodeConfig) {
|
|
59664
|
-
if (
|
|
59743
|
+
if (fs31.existsSync(OPENCODE_CONFIG_PATH)) {
|
|
59665
59744
|
console.log(`\u2717 Could not parse opencode config at: ${OPENCODE_CONFIG_PATH}`);
|
|
59666
59745
|
return 1;
|
|
59667
59746
|
} else {
|
|
@@ -59693,13 +59772,13 @@ async function uninstall() {
|
|
|
59693
59772
|
console.log("\u2713 Re-enabled default OpenCode agents (explore, general)");
|
|
59694
59773
|
if (process.argv.includes("--clean")) {
|
|
59695
59774
|
let cleaned = false;
|
|
59696
|
-
if (
|
|
59697
|
-
|
|
59775
|
+
if (fs31.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
59776
|
+
fs31.unlinkSync(PLUGIN_CONFIG_PATH);
|
|
59698
59777
|
console.log(`\u2713 Removed plugin config: ${PLUGIN_CONFIG_PATH}`);
|
|
59699
59778
|
cleaned = true;
|
|
59700
59779
|
}
|
|
59701
|
-
if (
|
|
59702
|
-
|
|
59780
|
+
if (fs31.existsSync(PROMPTS_DIR)) {
|
|
59781
|
+
fs31.rmSync(PROMPTS_DIR, { recursive: true });
|
|
59703
59782
|
console.log(`\u2713 Removed custom prompts: ${PROMPTS_DIR}`);
|
|
59704
59783
|
cleaned = true;
|
|
59705
59784
|
}
|