opencode-swarm 6.86.8 → 6.86.10
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 +282 -218
- package/dist/config/cache-paths.d.ts +11 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +741 -686
- package/dist/services/diagnose-service.d.ts +1 -1
- package/package.json +1 -1
- package/dist/tools/check-gate-status.prefix.test.d.ts +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -17669,14 +17669,14 @@ __export(exports_config_doctor, {
|
|
|
17669
17669
|
});
|
|
17670
17670
|
import * as crypto3 from "crypto";
|
|
17671
17671
|
import * as fs8 from "fs";
|
|
17672
|
-
import * as
|
|
17673
|
-
import * as
|
|
17672
|
+
import * as os6 from "os";
|
|
17673
|
+
import * as path19 from "path";
|
|
17674
17674
|
function getUserConfigDir3() {
|
|
17675
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
17675
|
+
return process.env.XDG_CONFIG_HOME || path19.join(os6.homedir(), ".config");
|
|
17676
17676
|
}
|
|
17677
17677
|
function getConfigPaths(directory) {
|
|
17678
|
-
const userConfigPath =
|
|
17679
|
-
const projectConfigPath =
|
|
17678
|
+
const userConfigPath = path19.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
17679
|
+
const projectConfigPath = path19.join(directory, ".opencode", "opencode-swarm.json");
|
|
17680
17680
|
return { userConfigPath, projectConfigPath };
|
|
17681
17681
|
}
|
|
17682
17682
|
function computeHash(content) {
|
|
@@ -17701,9 +17701,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
17701
17701
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
17702
17702
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
17703
17703
|
try {
|
|
17704
|
-
const resolvedConfig =
|
|
17705
|
-
const resolvedUser =
|
|
17706
|
-
const resolvedProject =
|
|
17704
|
+
const resolvedConfig = path19.resolve(configPath);
|
|
17705
|
+
const resolvedUser = path19.resolve(normalizedUser);
|
|
17706
|
+
const resolvedProject = path19.resolve(normalizedProject);
|
|
17707
17707
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
17708
17708
|
} catch {
|
|
17709
17709
|
return false;
|
|
@@ -17743,12 +17743,12 @@ function createConfigBackup(directory) {
|
|
|
17743
17743
|
};
|
|
17744
17744
|
}
|
|
17745
17745
|
function writeBackupArtifact(directory, backup) {
|
|
17746
|
-
const swarmDir =
|
|
17746
|
+
const swarmDir = path19.join(directory, ".swarm");
|
|
17747
17747
|
if (!fs8.existsSync(swarmDir)) {
|
|
17748
17748
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
17749
17749
|
}
|
|
17750
17750
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
17751
|
-
const backupPath =
|
|
17751
|
+
const backupPath = path19.join(swarmDir, backupFilename);
|
|
17752
17752
|
const artifact = {
|
|
17753
17753
|
createdAt: backup.createdAt,
|
|
17754
17754
|
configPath: backup.configPath,
|
|
@@ -17778,7 +17778,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
17778
17778
|
return null;
|
|
17779
17779
|
}
|
|
17780
17780
|
const targetPath = artifact.configPath;
|
|
17781
|
-
const targetDir =
|
|
17781
|
+
const targetDir = path19.dirname(targetPath);
|
|
17782
17782
|
if (!fs8.existsSync(targetDir)) {
|
|
17783
17783
|
fs8.mkdirSync(targetDir, { recursive: true });
|
|
17784
17784
|
}
|
|
@@ -17809,9 +17809,9 @@ function readConfigFromFile(directory) {
|
|
|
17809
17809
|
return null;
|
|
17810
17810
|
}
|
|
17811
17811
|
}
|
|
17812
|
-
function validateConfigKey(
|
|
17812
|
+
function validateConfigKey(path20, value, _config) {
|
|
17813
17813
|
const findings = [];
|
|
17814
|
-
switch (
|
|
17814
|
+
switch (path20) {
|
|
17815
17815
|
case "agents": {
|
|
17816
17816
|
if (value !== undefined) {
|
|
17817
17817
|
findings.push({
|
|
@@ -18058,27 +18058,27 @@ function validateConfigKey(path19, value, _config) {
|
|
|
18058
18058
|
}
|
|
18059
18059
|
return findings;
|
|
18060
18060
|
}
|
|
18061
|
-
function walkConfigAndValidate(obj,
|
|
18061
|
+
function walkConfigAndValidate(obj, path20, config3, findings) {
|
|
18062
18062
|
if (obj === null || obj === undefined) {
|
|
18063
18063
|
return;
|
|
18064
18064
|
}
|
|
18065
|
-
if (
|
|
18066
|
-
const keyFindings = validateConfigKey(
|
|
18065
|
+
if (path20 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
18066
|
+
const keyFindings = validateConfigKey(path20, obj, config3);
|
|
18067
18067
|
findings.push(...keyFindings);
|
|
18068
18068
|
}
|
|
18069
18069
|
if (typeof obj !== "object") {
|
|
18070
|
-
const keyFindings = validateConfigKey(
|
|
18070
|
+
const keyFindings = validateConfigKey(path20, obj, config3);
|
|
18071
18071
|
findings.push(...keyFindings);
|
|
18072
18072
|
return;
|
|
18073
18073
|
}
|
|
18074
18074
|
if (Array.isArray(obj)) {
|
|
18075
18075
|
obj.forEach((item, index) => {
|
|
18076
|
-
walkConfigAndValidate(item, `${
|
|
18076
|
+
walkConfigAndValidate(item, `${path20}[${index}]`, config3, findings);
|
|
18077
18077
|
});
|
|
18078
18078
|
return;
|
|
18079
18079
|
}
|
|
18080
18080
|
for (const [key, value] of Object.entries(obj)) {
|
|
18081
|
-
const newPath =
|
|
18081
|
+
const newPath = path20 ? `${path20}.${key}` : key;
|
|
18082
18082
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
18083
18083
|
}
|
|
18084
18084
|
}
|
|
@@ -18198,7 +18198,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
18198
18198
|
}
|
|
18199
18199
|
}
|
|
18200
18200
|
if (appliedFixes.length > 0) {
|
|
18201
|
-
const configDir =
|
|
18201
|
+
const configDir = path19.dirname(configPath);
|
|
18202
18202
|
if (!fs8.existsSync(configDir)) {
|
|
18203
18203
|
fs8.mkdirSync(configDir, { recursive: true });
|
|
18204
18204
|
}
|
|
@@ -18208,12 +18208,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
18208
18208
|
return { appliedFixes, updatedConfigPath };
|
|
18209
18209
|
}
|
|
18210
18210
|
function writeDoctorArtifact(directory, result) {
|
|
18211
|
-
const swarmDir =
|
|
18211
|
+
const swarmDir = path19.join(directory, ".swarm");
|
|
18212
18212
|
if (!fs8.existsSync(swarmDir)) {
|
|
18213
18213
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
18214
18214
|
}
|
|
18215
18215
|
const artifactFilename = "config-doctor.json";
|
|
18216
|
-
const artifactPath =
|
|
18216
|
+
const artifactPath = path19.join(swarmDir, artifactFilename);
|
|
18217
18217
|
const guiOutput = {
|
|
18218
18218
|
timestamp: result.timestamp,
|
|
18219
18219
|
summary: result.summary,
|
|
@@ -18575,12 +18575,12 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
18575
18575
|
|
|
18576
18576
|
// src/cli/index.ts
|
|
18577
18577
|
import * as fs21 from "fs";
|
|
18578
|
-
import * as
|
|
18579
|
-
import * as
|
|
18578
|
+
import * as os7 from "os";
|
|
18579
|
+
import * as path33 from "path";
|
|
18580
18580
|
// package.json
|
|
18581
18581
|
var package_default = {
|
|
18582
18582
|
name: "opencode-swarm",
|
|
18583
|
-
version: "6.86.
|
|
18583
|
+
version: "6.86.10",
|
|
18584
18584
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
18585
18585
|
main: "dist/index.js",
|
|
18586
18586
|
types: "dist/index.d.ts",
|
|
@@ -20170,6 +20170,7 @@ function getEffectiveGates(profile, sessionOverrides) {
|
|
|
20170
20170
|
|
|
20171
20171
|
// src/hooks/delegation-gate.ts
|
|
20172
20172
|
init_telemetry();
|
|
20173
|
+
init_logger();
|
|
20173
20174
|
|
|
20174
20175
|
// node_modules/quick-lru/index.js
|
|
20175
20176
|
class QuickLRU extends Map {
|
|
@@ -20533,6 +20534,7 @@ function clearAllScopes(directory) {
|
|
|
20533
20534
|
// src/hooks/guardrails.ts
|
|
20534
20535
|
init_telemetry();
|
|
20535
20536
|
init_utils();
|
|
20537
|
+
init_logger();
|
|
20536
20538
|
|
|
20537
20539
|
// src/hooks/conflict-resolution.ts
|
|
20538
20540
|
init_telemetry();
|
|
@@ -35625,6 +35627,7 @@ function getGlobalEventBus() {
|
|
|
35625
35627
|
|
|
35626
35628
|
// src/hooks/curator.ts
|
|
35627
35629
|
init_manager();
|
|
35630
|
+
init_logger();
|
|
35628
35631
|
init_utils2();
|
|
35629
35632
|
|
|
35630
35633
|
// src/hooks/hive-promoter.ts
|
|
@@ -36269,31 +36272,49 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
36269
36272
|
// src/services/diagnose-service.ts
|
|
36270
36273
|
import * as child_process4 from "child_process";
|
|
36271
36274
|
import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync5 } from "fs";
|
|
36272
|
-
import
|
|
36275
|
+
import path18 from "path";
|
|
36273
36276
|
import { fileURLToPath } from "url";
|
|
36277
|
+
|
|
36278
|
+
// src/config/cache-paths.ts
|
|
36279
|
+
import * as os5 from "os";
|
|
36280
|
+
import * as path17 from "path";
|
|
36281
|
+
function getPluginConfigDir() {
|
|
36282
|
+
return path17.join(process.env.XDG_CONFIG_HOME || path17.join(os5.homedir(), ".config"), "opencode");
|
|
36283
|
+
}
|
|
36284
|
+
function getPluginCachePaths() {
|
|
36285
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path17.join(os5.homedir(), ".cache");
|
|
36286
|
+
const configDir = getPluginConfigDir();
|
|
36287
|
+
return [
|
|
36288
|
+
path17.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
|
|
36289
|
+
path17.join(configDir, "node_modules", "opencode-swarm"),
|
|
36290
|
+
path17.join(cacheBase, "opencode", "node_modules", "opencode-swarm")
|
|
36291
|
+
];
|
|
36292
|
+
}
|
|
36293
|
+
|
|
36294
|
+
// src/services/diagnose-service.ts
|
|
36274
36295
|
init_manager2();
|
|
36275
36296
|
init_utils2();
|
|
36276
36297
|
init_manager();
|
|
36277
36298
|
|
|
36278
36299
|
// src/services/version-check.ts
|
|
36279
36300
|
import { existsSync as existsSync8, mkdirSync as mkdirSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
36280
|
-
import { homedir as
|
|
36281
|
-
import { join as
|
|
36301
|
+
import { homedir as homedir5 } from "os";
|
|
36302
|
+
import { join as join15 } from "path";
|
|
36282
36303
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
36283
36304
|
function cacheDir() {
|
|
36284
36305
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
36285
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
36286
|
-
return
|
|
36306
|
+
const base = xdg && xdg.length > 0 ? xdg : join15(homedir5(), ".cache");
|
|
36307
|
+
return join15(base, "opencode-swarm");
|
|
36287
36308
|
}
|
|
36288
36309
|
function cacheFile() {
|
|
36289
|
-
return
|
|
36310
|
+
return join15(cacheDir(), "version-check.json");
|
|
36290
36311
|
}
|
|
36291
36312
|
function readVersionCache() {
|
|
36292
36313
|
try {
|
|
36293
|
-
const
|
|
36294
|
-
if (!existsSync8(
|
|
36314
|
+
const path18 = cacheFile();
|
|
36315
|
+
if (!existsSync8(path18))
|
|
36295
36316
|
return null;
|
|
36296
|
-
const raw = readFileSync5(
|
|
36317
|
+
const raw = readFileSync5(path18, "utf-8");
|
|
36297
36318
|
const parsed = JSON.parse(raw);
|
|
36298
36319
|
if (typeof parsed?.checkedAt !== "number")
|
|
36299
36320
|
return null;
|
|
@@ -36623,7 +36644,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
36623
36644
|
};
|
|
36624
36645
|
}
|
|
36625
36646
|
async function checkConfigParseability(directory) {
|
|
36626
|
-
const configPath =
|
|
36647
|
+
const configPath = path18.join(directory, ".opencode/opencode-swarm.json");
|
|
36627
36648
|
if (!existsSync9(configPath)) {
|
|
36628
36649
|
return {
|
|
36629
36650
|
name: "Config Parseability",
|
|
@@ -36652,7 +36673,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
36652
36673
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
36653
36674
|
const isSource = normalized.endsWith("/src/services");
|
|
36654
36675
|
const isCliBundle = normalized.endsWith("/cli");
|
|
36655
|
-
return isSource || isCliBundle ?
|
|
36676
|
+
return isSource || isCliBundle ? path18.join(thisDir, "..", "lang", "grammars") : path18.join(thisDir, "lang", "grammars");
|
|
36656
36677
|
}
|
|
36657
36678
|
async function checkGrammarWasmFiles() {
|
|
36658
36679
|
const grammarFiles = [
|
|
@@ -36676,14 +36697,14 @@ async function checkGrammarWasmFiles() {
|
|
|
36676
36697
|
"tree-sitter-ini.wasm",
|
|
36677
36698
|
"tree-sitter-regex.wasm"
|
|
36678
36699
|
];
|
|
36679
|
-
const thisDir =
|
|
36700
|
+
const thisDir = path18.dirname(fileURLToPath(import.meta.url));
|
|
36680
36701
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
36681
36702
|
const missing = [];
|
|
36682
|
-
if (!existsSync9(
|
|
36703
|
+
if (!existsSync9(path18.join(grammarDir, "tree-sitter.wasm"))) {
|
|
36683
36704
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
36684
36705
|
}
|
|
36685
36706
|
for (const file3 of grammarFiles) {
|
|
36686
|
-
if (!existsSync9(
|
|
36707
|
+
if (!existsSync9(path18.join(grammarDir, file3))) {
|
|
36687
36708
|
missing.push(file3);
|
|
36688
36709
|
}
|
|
36689
36710
|
}
|
|
@@ -36701,7 +36722,7 @@ async function checkGrammarWasmFiles() {
|
|
|
36701
36722
|
};
|
|
36702
36723
|
}
|
|
36703
36724
|
async function checkCheckpointManifest(directory) {
|
|
36704
|
-
const manifestPath =
|
|
36725
|
+
const manifestPath = path18.join(directory, ".swarm/checkpoints.json");
|
|
36705
36726
|
if (!existsSync9(manifestPath)) {
|
|
36706
36727
|
return {
|
|
36707
36728
|
name: "Checkpoint Manifest",
|
|
@@ -36753,7 +36774,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
36753
36774
|
}
|
|
36754
36775
|
}
|
|
36755
36776
|
async function checkEventStreamIntegrity(directory) {
|
|
36756
|
-
const eventsPath =
|
|
36777
|
+
const eventsPath = path18.join(directory, ".swarm/events.jsonl");
|
|
36757
36778
|
if (!existsSync9(eventsPath)) {
|
|
36758
36779
|
return {
|
|
36759
36780
|
name: "Event Stream",
|
|
@@ -36794,7 +36815,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
36794
36815
|
}
|
|
36795
36816
|
}
|
|
36796
36817
|
async function checkSteeringDirectives(directory) {
|
|
36797
|
-
const eventsPath =
|
|
36818
|
+
const eventsPath = path18.join(directory, ".swarm/events.jsonl");
|
|
36798
36819
|
if (!existsSync9(eventsPath)) {
|
|
36799
36820
|
return {
|
|
36800
36821
|
name: "Steering Directives",
|
|
@@ -36850,7 +36871,7 @@ async function checkCurator(directory) {
|
|
|
36850
36871
|
detail: "Disabled (enable via curator.enabled)"
|
|
36851
36872
|
};
|
|
36852
36873
|
}
|
|
36853
|
-
const summaryPath =
|
|
36874
|
+
const summaryPath = path18.join(directory, ".swarm/curator-summary.json");
|
|
36854
36875
|
if (!existsSync9(summaryPath)) {
|
|
36855
36876
|
return {
|
|
36856
36877
|
name: "Curator",
|
|
@@ -37016,7 +37037,7 @@ async function getDiagnoseData(directory) {
|
|
|
37016
37037
|
checks5.push(await checkSteeringDirectives(directory));
|
|
37017
37038
|
checks5.push(await checkCurator(directory));
|
|
37018
37039
|
try {
|
|
37019
|
-
const evidenceDir =
|
|
37040
|
+
const evidenceDir = path18.join(directory, ".swarm", "evidence");
|
|
37020
37041
|
const snapshotFiles = existsSync9(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
37021
37042
|
if (snapshotFiles.length > 0) {
|
|
37022
37043
|
const latest = snapshotFiles.sort().pop();
|
|
@@ -37046,7 +37067,36 @@ async function getDiagnoseData(directory) {
|
|
|
37046
37067
|
detail: `${deferredWarnings.length} warning(s) deferred from init (run with verbose logs for details)`
|
|
37047
37068
|
});
|
|
37048
37069
|
}
|
|
37049
|
-
const
|
|
37070
|
+
const cachePaths = getPluginCachePaths();
|
|
37071
|
+
const cacheRows = [];
|
|
37072
|
+
for (const cachePath of cachePaths) {
|
|
37073
|
+
try {
|
|
37074
|
+
if (!existsSync9(cachePath)) {
|
|
37075
|
+
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
37076
|
+
continue;
|
|
37077
|
+
}
|
|
37078
|
+
const pkgJsonPath = path18.join(cachePath, "package.json");
|
|
37079
|
+
try {
|
|
37080
|
+
const raw = readFileSync6(pkgJsonPath, "utf-8");
|
|
37081
|
+
const parsed = JSON.parse(raw);
|
|
37082
|
+
const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
|
|
37083
|
+
cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
|
|
37084
|
+
} catch {
|
|
37085
|
+
cacheRows.push(`\u26A0\uFE0F ${cachePath} \u2014 present (package.json unreadable)`);
|
|
37086
|
+
}
|
|
37087
|
+
} catch {
|
|
37088
|
+
cacheRows.push(`\u26A0\uFE0F ${cachePath} \u2014 status unknown (read error)`);
|
|
37089
|
+
}
|
|
37090
|
+
}
|
|
37091
|
+
const hasCacheEntry = cacheRows.some((r) => r.startsWith("\u2705"));
|
|
37092
|
+
const hasCacheWarning = cacheRows.some((r) => r.startsWith("\u26A0\uFE0F"));
|
|
37093
|
+
const cacheStatus = hasCacheWarning ? "\u26A0\uFE0F" : hasCacheEntry ? "\u2705" : "\u2B1C";
|
|
37094
|
+
checks5.push({
|
|
37095
|
+
name: "Plugin Caches",
|
|
37096
|
+
status: cacheStatus,
|
|
37097
|
+
detail: cacheRows.join(" | ")
|
|
37098
|
+
});
|
|
37099
|
+
const passCount = checks5.filter((c) => c.status === "\u2705" || c.status === "\u2B1C").length;
|
|
37050
37100
|
const totalCount = checks5.length;
|
|
37051
37101
|
const allPassed = passCount === totalCount;
|
|
37052
37102
|
return {
|
|
@@ -37084,15 +37134,15 @@ init_config_doctor();
|
|
|
37084
37134
|
|
|
37085
37135
|
// src/services/tool-doctor.ts
|
|
37086
37136
|
import * as fs10 from "fs";
|
|
37087
|
-
import * as
|
|
37137
|
+
import * as path21 from "path";
|
|
37088
37138
|
|
|
37089
37139
|
// src/build/discovery.ts
|
|
37090
37140
|
import * as fs9 from "fs";
|
|
37091
|
-
import * as
|
|
37141
|
+
import * as path20 from "path";
|
|
37092
37142
|
|
|
37093
37143
|
// src/lang/detector.ts
|
|
37094
37144
|
import { access as access2, readdir as readdir2 } from "fs/promises";
|
|
37095
|
-
import { extname as extname2, join as
|
|
37145
|
+
import { extname as extname2, join as join17 } from "path";
|
|
37096
37146
|
|
|
37097
37147
|
// src/lang/profiles.ts
|
|
37098
37148
|
class LanguageRegistry {
|
|
@@ -38072,7 +38122,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
38072
38122
|
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
38073
38123
|
continue;
|
|
38074
38124
|
try {
|
|
38075
|
-
await access2(
|
|
38125
|
+
await access2(join17(dir, detectFile));
|
|
38076
38126
|
detected.add(profile.id);
|
|
38077
38127
|
break;
|
|
38078
38128
|
} catch {}
|
|
@@ -38093,7 +38143,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
38093
38143
|
const topEntries = await readdir2(projectDir, { withFileTypes: true });
|
|
38094
38144
|
for (const entry of topEntries) {
|
|
38095
38145
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
38096
|
-
await scanDir(
|
|
38146
|
+
await scanDir(join17(projectDir, entry.name));
|
|
38097
38147
|
}
|
|
38098
38148
|
}
|
|
38099
38149
|
} catch {}
|
|
@@ -38252,11 +38302,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
38252
38302
|
const regex = simpleGlobToRegex(pattern);
|
|
38253
38303
|
const matches = files.filter((f) => regex.test(f));
|
|
38254
38304
|
if (matches.length > 0) {
|
|
38255
|
-
return
|
|
38305
|
+
return path20.join(dir, matches[0]);
|
|
38256
38306
|
}
|
|
38257
38307
|
} catch {}
|
|
38258
38308
|
} else {
|
|
38259
|
-
const filePath =
|
|
38309
|
+
const filePath = path20.join(workingDir, pattern);
|
|
38260
38310
|
if (fs9.existsSync(filePath)) {
|
|
38261
38311
|
return filePath;
|
|
38262
38312
|
}
|
|
@@ -38265,7 +38315,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
38265
38315
|
return null;
|
|
38266
38316
|
}
|
|
38267
38317
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
38268
|
-
const packageJsonPath =
|
|
38318
|
+
const packageJsonPath = path20.join(workingDir, "package.json");
|
|
38269
38319
|
if (!fs9.existsSync(packageJsonPath)) {
|
|
38270
38320
|
return [];
|
|
38271
38321
|
}
|
|
@@ -38306,7 +38356,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
38306
38356
|
const regex = simpleGlobToRegex(pattern);
|
|
38307
38357
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
38308
38358
|
} else {
|
|
38309
|
-
const filePath =
|
|
38359
|
+
const filePath = path20.join(workingDir, pattern);
|
|
38310
38360
|
if (fs9.existsSync(filePath)) {
|
|
38311
38361
|
allBuildFiles.add(filePath);
|
|
38312
38362
|
}
|
|
@@ -38319,7 +38369,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
38319
38369
|
try {
|
|
38320
38370
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
38321
38371
|
for (const entry of entries) {
|
|
38322
|
-
const fullPath =
|
|
38372
|
+
const fullPath = path20.join(dir, entry.name);
|
|
38323
38373
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
38324
38374
|
findFilesRecursive(fullPath, regex, results);
|
|
38325
38375
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -38342,7 +38392,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
38342
38392
|
let foundCommand = false;
|
|
38343
38393
|
for (const cmd of sortedCommands) {
|
|
38344
38394
|
if (cmd.detectFile) {
|
|
38345
|
-
const detectFilePath =
|
|
38395
|
+
const detectFilePath = path20.join(workingDir, cmd.detectFile);
|
|
38346
38396
|
if (!fs9.existsSync(detectFilePath)) {
|
|
38347
38397
|
continue;
|
|
38348
38398
|
}
|
|
@@ -38517,8 +38567,8 @@ function checkBinaryReadiness() {
|
|
|
38517
38567
|
}
|
|
38518
38568
|
function runToolDoctor(_directory, pluginRoot) {
|
|
38519
38569
|
const findings = [];
|
|
38520
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
38521
|
-
const indexPath =
|
|
38570
|
+
const resolvedPluginRoot = pluginRoot ?? path21.resolve(import.meta.dir, "..", "..");
|
|
38571
|
+
const indexPath = path21.join(resolvedPluginRoot, "src", "index.ts");
|
|
38522
38572
|
if (!fs10.existsSync(indexPath)) {
|
|
38523
38573
|
return {
|
|
38524
38574
|
findings: [
|
|
@@ -39438,13 +39488,14 @@ async function handleHistoryCommand(directory, _args) {
|
|
|
39438
39488
|
return formatHistoryMarkdown(historyData);
|
|
39439
39489
|
}
|
|
39440
39490
|
// src/hooks/knowledge-migrator.ts
|
|
39491
|
+
init_logger();
|
|
39441
39492
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
39442
39493
|
import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
|
|
39443
39494
|
import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
39444
|
-
import * as
|
|
39495
|
+
import * as path22 from "path";
|
|
39445
39496
|
async function migrateContextToKnowledge(directory, config3) {
|
|
39446
|
-
const sentinelPath =
|
|
39447
|
-
const contextPath =
|
|
39497
|
+
const sentinelPath = path22.join(directory, ".swarm", ".knowledge-migrated");
|
|
39498
|
+
const contextPath = path22.join(directory, ".swarm", "context.md");
|
|
39448
39499
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
39449
39500
|
if (existsSync13(sentinelPath)) {
|
|
39450
39501
|
return {
|
|
@@ -39535,7 +39586,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
39535
39586
|
await rewriteKnowledge(knowledgePath, existing);
|
|
39536
39587
|
}
|
|
39537
39588
|
await writeSentinel(sentinelPath, migrated, dropped);
|
|
39538
|
-
|
|
39589
|
+
log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
|
|
39539
39590
|
return {
|
|
39540
39591
|
migrated: true,
|
|
39541
39592
|
entriesMigrated: migrated,
|
|
@@ -39640,7 +39691,7 @@ function truncateLesson(text) {
|
|
|
39640
39691
|
return `${text.slice(0, 277)}...`;
|
|
39641
39692
|
}
|
|
39642
39693
|
function inferProjectName(directory) {
|
|
39643
|
-
const packageJsonPath =
|
|
39694
|
+
const packageJsonPath = path22.join(directory, "package.json");
|
|
39644
39695
|
if (existsSync13(packageJsonPath)) {
|
|
39645
39696
|
try {
|
|
39646
39697
|
const pkg = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
@@ -39649,7 +39700,7 @@ function inferProjectName(directory) {
|
|
|
39649
39700
|
}
|
|
39650
39701
|
} catch {}
|
|
39651
39702
|
}
|
|
39652
|
-
return
|
|
39703
|
+
return path22.basename(directory);
|
|
39653
39704
|
}
|
|
39654
39705
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
39655
39706
|
const sentinel = {
|
|
@@ -39661,7 +39712,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
39661
39712
|
schema_version: 1,
|
|
39662
39713
|
migration_tool: "knowledge-migrator.ts"
|
|
39663
39714
|
};
|
|
39664
|
-
await mkdir3(
|
|
39715
|
+
await mkdir3(path22.dirname(sentinelPath), { recursive: true });
|
|
39665
39716
|
await writeFile4(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
39666
39717
|
}
|
|
39667
39718
|
|
|
@@ -39898,12 +39949,12 @@ async function handlePlanCommand(directory, args) {
|
|
|
39898
39949
|
init_manager2();
|
|
39899
39950
|
init_manager();
|
|
39900
39951
|
import * as fs17 from "fs";
|
|
39901
|
-
import * as
|
|
39952
|
+
import * as path29 from "path";
|
|
39902
39953
|
|
|
39903
39954
|
// src/tools/lint.ts
|
|
39904
39955
|
init_zod();
|
|
39905
39956
|
import * as fs11 from "fs";
|
|
39906
|
-
import * as
|
|
39957
|
+
import * as path23 from "path";
|
|
39907
39958
|
init_utils();
|
|
39908
39959
|
|
|
39909
39960
|
// src/utils/path-security.ts
|
|
@@ -39949,9 +40000,9 @@ function validateArgs(args) {
|
|
|
39949
40000
|
}
|
|
39950
40001
|
function getLinterCommand(linter, mode, projectDir) {
|
|
39951
40002
|
const isWindows = process.platform === "win32";
|
|
39952
|
-
const binDir =
|
|
39953
|
-
const biomeBin = isWindows ?
|
|
39954
|
-
const eslintBin = isWindows ?
|
|
40003
|
+
const binDir = path23.join(projectDir, "node_modules", ".bin");
|
|
40004
|
+
const biomeBin = isWindows ? path23.join(binDir, "biome.EXE") : path23.join(binDir, "biome");
|
|
40005
|
+
const eslintBin = isWindows ? path23.join(binDir, "eslint.cmd") : path23.join(binDir, "eslint");
|
|
39955
40006
|
switch (linter) {
|
|
39956
40007
|
case "biome":
|
|
39957
40008
|
if (mode === "fix") {
|
|
@@ -39967,7 +40018,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
39967
40018
|
}
|
|
39968
40019
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
39969
40020
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
39970
|
-
const gradlew = fs11.existsSync(
|
|
40021
|
+
const gradlew = fs11.existsSync(path23.join(cwd, gradlewName)) ? path23.join(cwd, gradlewName) : null;
|
|
39971
40022
|
switch (linter) {
|
|
39972
40023
|
case "ruff":
|
|
39973
40024
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -40001,10 +40052,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
40001
40052
|
}
|
|
40002
40053
|
}
|
|
40003
40054
|
function detectRuff(cwd) {
|
|
40004
|
-
if (fs11.existsSync(
|
|
40055
|
+
if (fs11.existsSync(path23.join(cwd, "ruff.toml")))
|
|
40005
40056
|
return isCommandAvailable("ruff");
|
|
40006
40057
|
try {
|
|
40007
|
-
const pyproject =
|
|
40058
|
+
const pyproject = path23.join(cwd, "pyproject.toml");
|
|
40008
40059
|
if (fs11.existsSync(pyproject)) {
|
|
40009
40060
|
const content = fs11.readFileSync(pyproject, "utf-8");
|
|
40010
40061
|
if (content.includes("[tool.ruff]"))
|
|
@@ -40014,19 +40065,19 @@ function detectRuff(cwd) {
|
|
|
40014
40065
|
return false;
|
|
40015
40066
|
}
|
|
40016
40067
|
function detectClippy(cwd) {
|
|
40017
|
-
return fs11.existsSync(
|
|
40068
|
+
return fs11.existsSync(path23.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
40018
40069
|
}
|
|
40019
40070
|
function detectGolangciLint(cwd) {
|
|
40020
|
-
return fs11.existsSync(
|
|
40071
|
+
return fs11.existsSync(path23.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
40021
40072
|
}
|
|
40022
40073
|
function detectCheckstyle(cwd) {
|
|
40023
|
-
const hasMaven = fs11.existsSync(
|
|
40024
|
-
const hasGradle = fs11.existsSync(
|
|
40025
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(
|
|
40074
|
+
const hasMaven = fs11.existsSync(path23.join(cwd, "pom.xml"));
|
|
40075
|
+
const hasGradle = fs11.existsSync(path23.join(cwd, "build.gradle")) || fs11.existsSync(path23.join(cwd, "build.gradle.kts"));
|
|
40076
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(path23.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
40026
40077
|
return (hasMaven || hasGradle) && hasBinary;
|
|
40027
40078
|
}
|
|
40028
40079
|
function detectKtlint(cwd) {
|
|
40029
|
-
const hasKotlin = fs11.existsSync(
|
|
40080
|
+
const hasKotlin = fs11.existsSync(path23.join(cwd, "build.gradle.kts")) || fs11.existsSync(path23.join(cwd, "build.gradle")) || (() => {
|
|
40030
40081
|
try {
|
|
40031
40082
|
return fs11.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
40032
40083
|
} catch {
|
|
@@ -40045,11 +40096,11 @@ function detectDotnetFormat(cwd) {
|
|
|
40045
40096
|
}
|
|
40046
40097
|
}
|
|
40047
40098
|
function detectCppcheck(cwd) {
|
|
40048
|
-
if (fs11.existsSync(
|
|
40099
|
+
if (fs11.existsSync(path23.join(cwd, "CMakeLists.txt"))) {
|
|
40049
40100
|
return isCommandAvailable("cppcheck");
|
|
40050
40101
|
}
|
|
40051
40102
|
try {
|
|
40052
|
-
const dirsToCheck = [cwd,
|
|
40103
|
+
const dirsToCheck = [cwd, path23.join(cwd, "src")];
|
|
40053
40104
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
40054
40105
|
try {
|
|
40055
40106
|
return fs11.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -40063,13 +40114,13 @@ function detectCppcheck(cwd) {
|
|
|
40063
40114
|
}
|
|
40064
40115
|
}
|
|
40065
40116
|
function detectSwiftlint(cwd) {
|
|
40066
|
-
return fs11.existsSync(
|
|
40117
|
+
return fs11.existsSync(path23.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
40067
40118
|
}
|
|
40068
40119
|
function detectDartAnalyze(cwd) {
|
|
40069
|
-
return fs11.existsSync(
|
|
40120
|
+
return fs11.existsSync(path23.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
40070
40121
|
}
|
|
40071
40122
|
function detectRubocop(cwd) {
|
|
40072
|
-
return (fs11.existsSync(
|
|
40123
|
+
return (fs11.existsSync(path23.join(cwd, "Gemfile")) || fs11.existsSync(path23.join(cwd, "gems.rb")) || fs11.existsSync(path23.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
|
|
40073
40124
|
}
|
|
40074
40125
|
function detectAdditionalLinter(cwd) {
|
|
40075
40126
|
if (detectRuff(cwd))
|
|
@@ -40097,10 +40148,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
40097
40148
|
function findBinInAncestors(startDir, binName) {
|
|
40098
40149
|
let dir = startDir;
|
|
40099
40150
|
while (true) {
|
|
40100
|
-
const candidate =
|
|
40151
|
+
const candidate = path23.join(dir, "node_modules", ".bin", binName);
|
|
40101
40152
|
if (fs11.existsSync(candidate))
|
|
40102
40153
|
return candidate;
|
|
40103
|
-
const parent =
|
|
40154
|
+
const parent = path23.dirname(dir);
|
|
40104
40155
|
if (parent === dir)
|
|
40105
40156
|
break;
|
|
40106
40157
|
dir = parent;
|
|
@@ -40109,10 +40160,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
40109
40160
|
}
|
|
40110
40161
|
function findBinInEnvPath(binName) {
|
|
40111
40162
|
const searchPath = process.env.PATH ?? "";
|
|
40112
|
-
for (const dir of searchPath.split(
|
|
40163
|
+
for (const dir of searchPath.split(path23.delimiter)) {
|
|
40113
40164
|
if (!dir)
|
|
40114
40165
|
continue;
|
|
40115
|
-
const candidate =
|
|
40166
|
+
const candidate = path23.join(dir, binName);
|
|
40116
40167
|
if (fs11.existsSync(candidate))
|
|
40117
40168
|
return candidate;
|
|
40118
40169
|
}
|
|
@@ -40125,13 +40176,13 @@ async function detectAvailableLinter(directory) {
|
|
|
40125
40176
|
return null;
|
|
40126
40177
|
const projectDir = directory;
|
|
40127
40178
|
const isWindows = process.platform === "win32";
|
|
40128
|
-
const biomeBin = isWindows ?
|
|
40129
|
-
const eslintBin = isWindows ?
|
|
40179
|
+
const biomeBin = isWindows ? path23.join(projectDir, "node_modules", ".bin", "biome.EXE") : path23.join(projectDir, "node_modules", ".bin", "biome");
|
|
40180
|
+
const eslintBin = isWindows ? path23.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path23.join(projectDir, "node_modules", ".bin", "eslint");
|
|
40130
40181
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
40131
40182
|
if (localResult)
|
|
40132
40183
|
return localResult;
|
|
40133
|
-
const biomeAncestor = findBinInAncestors(
|
|
40134
|
-
const eslintAncestor = findBinInAncestors(
|
|
40184
|
+
const biomeAncestor = findBinInAncestors(path23.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
40185
|
+
const eslintAncestor = findBinInAncestors(path23.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
40135
40186
|
if (biomeAncestor || eslintAncestor) {
|
|
40136
40187
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
40137
40188
|
}
|
|
@@ -40340,7 +40391,7 @@ For Rust: rustup component add clippy`
|
|
|
40340
40391
|
// src/tools/secretscan.ts
|
|
40341
40392
|
init_zod();
|
|
40342
40393
|
import * as fs12 from "fs";
|
|
40343
|
-
import * as
|
|
40394
|
+
import * as path24 from "path";
|
|
40344
40395
|
var MAX_FILE_PATH_LENGTH = 500;
|
|
40345
40396
|
var MAX_FILE_SIZE_BYTES = 512 * 1024;
|
|
40346
40397
|
var MAX_FILES_SCANNED = 1000;
|
|
@@ -40567,7 +40618,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
40567
40618
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
40568
40619
|
}
|
|
40569
40620
|
function loadSecretScanIgnore(scanDir) {
|
|
40570
|
-
const ignorePath =
|
|
40621
|
+
const ignorePath = path24.join(scanDir, ".secretscanignore");
|
|
40571
40622
|
try {
|
|
40572
40623
|
if (!fs12.existsSync(ignorePath))
|
|
40573
40624
|
return [];
|
|
@@ -40590,7 +40641,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
40590
40641
|
if (exactNames.has(entry))
|
|
40591
40642
|
return true;
|
|
40592
40643
|
for (const pattern of globPatterns) {
|
|
40593
|
-
if (
|
|
40644
|
+
if (path24.matchesGlob(relPath, pattern))
|
|
40594
40645
|
return true;
|
|
40595
40646
|
}
|
|
40596
40647
|
return false;
|
|
@@ -40611,7 +40662,7 @@ function validateDirectoryInput(dir) {
|
|
|
40611
40662
|
return null;
|
|
40612
40663
|
}
|
|
40613
40664
|
function isBinaryFile(filePath, buffer) {
|
|
40614
|
-
const ext =
|
|
40665
|
+
const ext = path24.extname(filePath).toLowerCase();
|
|
40615
40666
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
40616
40667
|
return true;
|
|
40617
40668
|
}
|
|
@@ -40748,9 +40799,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
40748
40799
|
return false;
|
|
40749
40800
|
}
|
|
40750
40801
|
function isPathWithinScope(realPath, scanDir) {
|
|
40751
|
-
const resolvedScanDir =
|
|
40752
|
-
const resolvedRealPath =
|
|
40753
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
40802
|
+
const resolvedScanDir = path24.resolve(scanDir);
|
|
40803
|
+
const resolvedRealPath = path24.resolve(realPath);
|
|
40804
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path24.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
40754
40805
|
}
|
|
40755
40806
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
40756
40807
|
skippedDirs: 0,
|
|
@@ -40776,8 +40827,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
40776
40827
|
return a.localeCompare(b);
|
|
40777
40828
|
});
|
|
40778
40829
|
for (const entry of entries) {
|
|
40779
|
-
const fullPath =
|
|
40780
|
-
const relPath =
|
|
40830
|
+
const fullPath = path24.join(dir, entry);
|
|
40831
|
+
const relPath = path24.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
40781
40832
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
40782
40833
|
stats.skippedDirs++;
|
|
40783
40834
|
continue;
|
|
@@ -40812,7 +40863,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
40812
40863
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
40813
40864
|
files.push(...subFiles);
|
|
40814
40865
|
} else if (lstat.isFile()) {
|
|
40815
|
-
const ext =
|
|
40866
|
+
const ext = path24.extname(fullPath).toLowerCase();
|
|
40816
40867
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
40817
40868
|
files.push(fullPath);
|
|
40818
40869
|
} else {
|
|
@@ -40878,7 +40929,7 @@ var secretscan = createSwarmTool({
|
|
|
40878
40929
|
}
|
|
40879
40930
|
}
|
|
40880
40931
|
try {
|
|
40881
|
-
const _scanDirRaw =
|
|
40932
|
+
const _scanDirRaw = path24.resolve(directory);
|
|
40882
40933
|
const scanDir = (() => {
|
|
40883
40934
|
try {
|
|
40884
40935
|
return fs12.realpathSync(_scanDirRaw);
|
|
@@ -41038,11 +41089,11 @@ async function runSecretscan(directory) {
|
|
|
41038
41089
|
// src/tools/test-runner.ts
|
|
41039
41090
|
init_zod();
|
|
41040
41091
|
import * as fs16 from "fs";
|
|
41041
|
-
import * as
|
|
41092
|
+
import * as path28 from "path";
|
|
41042
41093
|
|
|
41043
41094
|
// src/test-impact/analyzer.ts
|
|
41044
41095
|
import fs13 from "fs";
|
|
41045
|
-
import
|
|
41096
|
+
import path25 from "path";
|
|
41046
41097
|
var IMPORT_REGEX_ES = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
41047
41098
|
var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
41048
41099
|
var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
@@ -41067,8 +41118,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
41067
41118
|
if (!importPath.startsWith(".")) {
|
|
41068
41119
|
return null;
|
|
41069
41120
|
}
|
|
41070
|
-
const resolved =
|
|
41071
|
-
if (
|
|
41121
|
+
const resolved = path25.resolve(fromDir, importPath);
|
|
41122
|
+
if (path25.extname(resolved)) {
|
|
41072
41123
|
if (fs13.existsSync(resolved) && fs13.statSync(resolved).isFile()) {
|
|
41073
41124
|
return normalizePath(resolved);
|
|
41074
41125
|
}
|
|
@@ -41113,12 +41164,12 @@ function findTestFilesSync(cwd) {
|
|
|
41113
41164
|
for (const entry of entries) {
|
|
41114
41165
|
if (entry.isDirectory()) {
|
|
41115
41166
|
if (!skipDirs.has(entry.name)) {
|
|
41116
|
-
walk(
|
|
41167
|
+
walk(path25.join(dir, entry.name), visitedInodes);
|
|
41117
41168
|
}
|
|
41118
41169
|
} else if (entry.isFile()) {
|
|
41119
41170
|
const name = entry.name;
|
|
41120
41171
|
if (/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name)) {
|
|
41121
|
-
testFiles.push(normalizePath(
|
|
41172
|
+
testFiles.push(normalizePath(path25.join(dir, entry.name)));
|
|
41122
41173
|
}
|
|
41123
41174
|
}
|
|
41124
41175
|
}
|
|
@@ -41156,7 +41207,7 @@ async function buildImpactMapInternal(cwd) {
|
|
|
41156
41207
|
continue;
|
|
41157
41208
|
}
|
|
41158
41209
|
const imports = extractImports(content);
|
|
41159
|
-
const testDir =
|
|
41210
|
+
const testDir = path25.dirname(testFile);
|
|
41160
41211
|
for (const importPath of imports) {
|
|
41161
41212
|
const resolvedSource = resolveRelativeImport(testDir, importPath);
|
|
41162
41213
|
if (resolvedSource === null) {
|
|
@@ -41178,7 +41229,7 @@ async function buildImpactMap(cwd) {
|
|
|
41178
41229
|
return impactMap;
|
|
41179
41230
|
}
|
|
41180
41231
|
async function loadImpactMap(cwd) {
|
|
41181
|
-
const cachePath =
|
|
41232
|
+
const cachePath = path25.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
41182
41233
|
if (fs13.existsSync(cachePath)) {
|
|
41183
41234
|
try {
|
|
41184
41235
|
const content = fs13.readFileSync(cachePath, "utf-8");
|
|
@@ -41193,8 +41244,8 @@ async function loadImpactMap(cwd) {
|
|
|
41193
41244
|
return buildImpactMap(cwd);
|
|
41194
41245
|
}
|
|
41195
41246
|
async function saveImpactMap(cwd, impactMap) {
|
|
41196
|
-
const cacheDir2 =
|
|
41197
|
-
const cachePath =
|
|
41247
|
+
const cacheDir2 = path25.join(cwd, ".swarm", "cache");
|
|
41248
|
+
const cachePath = path25.join(cacheDir2, "impact-map.json");
|
|
41198
41249
|
if (!fs13.existsSync(cacheDir2)) {
|
|
41199
41250
|
fs13.mkdirSync(cacheDir2, { recursive: true });
|
|
41200
41251
|
}
|
|
@@ -41220,7 +41271,7 @@ async function analyzeImpact(changedFiles, cwd) {
|
|
|
41220
41271
|
const impactedTestsSet = new Set;
|
|
41221
41272
|
const untestedFiles = [];
|
|
41222
41273
|
for (const changedFile of validFiles) {
|
|
41223
|
-
const normalizedChanged = normalizePath(
|
|
41274
|
+
const normalizedChanged = normalizePath(path25.resolve(changedFile));
|
|
41224
41275
|
const tests = impactMap[normalizedChanged];
|
|
41225
41276
|
if (tests && tests.length > 0) {
|
|
41226
41277
|
for (const test of tests) {
|
|
@@ -41467,13 +41518,13 @@ function detectFlakyTests(allHistory) {
|
|
|
41467
41518
|
|
|
41468
41519
|
// src/test-impact/history-store.ts
|
|
41469
41520
|
import fs14 from "fs";
|
|
41470
|
-
import
|
|
41521
|
+
import path26 from "path";
|
|
41471
41522
|
var MAX_HISTORY_PER_TEST = 20;
|
|
41472
41523
|
var MAX_ERROR_LENGTH = 500;
|
|
41473
41524
|
var MAX_STACK_LENGTH = 200;
|
|
41474
41525
|
var MAX_CHANGED_FILES = 50;
|
|
41475
41526
|
function getHistoryPath(workingDir) {
|
|
41476
|
-
return
|
|
41527
|
+
return path26.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
|
|
41477
41528
|
}
|
|
41478
41529
|
function sanitizeErrorMessage(errorMessage) {
|
|
41479
41530
|
if (errorMessage === undefined) {
|
|
@@ -41533,7 +41584,7 @@ function appendTestRun(record3, workingDir) {
|
|
|
41533
41584
|
changedFiles: sanitizeChangedFiles(record3.changedFiles || [])
|
|
41534
41585
|
};
|
|
41535
41586
|
const historyPath = getHistoryPath(workingDir);
|
|
41536
|
-
const historyDir =
|
|
41587
|
+
const historyDir = path26.dirname(historyPath);
|
|
41537
41588
|
if (!fs14.existsSync(historyDir)) {
|
|
41538
41589
|
fs14.mkdirSync(historyDir, { recursive: true });
|
|
41539
41590
|
}
|
|
@@ -41607,7 +41658,7 @@ function getAllHistory(workingDir) {
|
|
|
41607
41658
|
|
|
41608
41659
|
// src/tools/resolve-working-directory.ts
|
|
41609
41660
|
import * as fs15 from "fs";
|
|
41610
|
-
import * as
|
|
41661
|
+
import * as path27 from "path";
|
|
41611
41662
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
41612
41663
|
if (workingDirectory == null || workingDirectory === "") {
|
|
41613
41664
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -41627,15 +41678,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
41627
41678
|
};
|
|
41628
41679
|
}
|
|
41629
41680
|
}
|
|
41630
|
-
const normalizedDir =
|
|
41631
|
-
const pathParts = normalizedDir.split(
|
|
41681
|
+
const normalizedDir = path27.normalize(workingDirectory);
|
|
41682
|
+
const pathParts = normalizedDir.split(path27.sep);
|
|
41632
41683
|
if (pathParts.includes("..")) {
|
|
41633
41684
|
return {
|
|
41634
41685
|
success: false,
|
|
41635
41686
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
41636
41687
|
};
|
|
41637
41688
|
}
|
|
41638
|
-
const resolvedDir =
|
|
41689
|
+
const resolvedDir = path27.resolve(normalizedDir);
|
|
41639
41690
|
let statResult;
|
|
41640
41691
|
try {
|
|
41641
41692
|
statResult = fs15.statSync(resolvedDir);
|
|
@@ -41651,7 +41702,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
41651
41702
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
41652
41703
|
};
|
|
41653
41704
|
}
|
|
41654
|
-
const resolvedFallback =
|
|
41705
|
+
const resolvedFallback = path27.resolve(fallbackDirectory);
|
|
41655
41706
|
let fallbackExists = false;
|
|
41656
41707
|
try {
|
|
41657
41708
|
fs15.statSync(resolvedFallback);
|
|
@@ -41661,7 +41712,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
41661
41712
|
}
|
|
41662
41713
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
41663
41714
|
if (fallbackExists) {
|
|
41664
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
41715
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path27.sep);
|
|
41665
41716
|
if (isSubdirectory) {
|
|
41666
41717
|
return {
|
|
41667
41718
|
success: false,
|
|
@@ -41751,14 +41802,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
41751
41802
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
41752
41803
|
}
|
|
41753
41804
|
function detectGoTest(cwd) {
|
|
41754
|
-
return fs16.existsSync(
|
|
41805
|
+
return fs16.existsSync(path28.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
41755
41806
|
}
|
|
41756
41807
|
function detectJavaMaven(cwd) {
|
|
41757
|
-
return fs16.existsSync(
|
|
41808
|
+
return fs16.existsSync(path28.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
41758
41809
|
}
|
|
41759
41810
|
function detectGradle(cwd) {
|
|
41760
|
-
const hasBuildFile = fs16.existsSync(
|
|
41761
|
-
const hasGradlew = fs16.existsSync(
|
|
41811
|
+
const hasBuildFile = fs16.existsSync(path28.join(cwd, "build.gradle")) || fs16.existsSync(path28.join(cwd, "build.gradle.kts"));
|
|
41812
|
+
const hasGradlew = fs16.existsSync(path28.join(cwd, "gradlew")) || fs16.existsSync(path28.join(cwd, "gradlew.bat"));
|
|
41762
41813
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
41763
41814
|
}
|
|
41764
41815
|
function detectDotnetTest(cwd) {
|
|
@@ -41771,30 +41822,30 @@ function detectDotnetTest(cwd) {
|
|
|
41771
41822
|
}
|
|
41772
41823
|
}
|
|
41773
41824
|
function detectCTest(cwd) {
|
|
41774
|
-
const hasSource = fs16.existsSync(
|
|
41775
|
-
const hasBuildCache = fs16.existsSync(
|
|
41825
|
+
const hasSource = fs16.existsSync(path28.join(cwd, "CMakeLists.txt"));
|
|
41826
|
+
const hasBuildCache = fs16.existsSync(path28.join(cwd, "CMakeCache.txt")) || fs16.existsSync(path28.join(cwd, "build", "CMakeCache.txt"));
|
|
41776
41827
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
41777
41828
|
}
|
|
41778
41829
|
function detectSwiftTest(cwd) {
|
|
41779
|
-
return fs16.existsSync(
|
|
41830
|
+
return fs16.existsSync(path28.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
41780
41831
|
}
|
|
41781
41832
|
function detectDartTest(cwd) {
|
|
41782
|
-
return fs16.existsSync(
|
|
41833
|
+
return fs16.existsSync(path28.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
41783
41834
|
}
|
|
41784
41835
|
function detectRSpec(cwd) {
|
|
41785
|
-
const hasRSpecFile = fs16.existsSync(
|
|
41786
|
-
const hasGemfile = fs16.existsSync(
|
|
41787
|
-
const hasSpecDir = fs16.existsSync(
|
|
41836
|
+
const hasRSpecFile = fs16.existsSync(path28.join(cwd, ".rspec"));
|
|
41837
|
+
const hasGemfile = fs16.existsSync(path28.join(cwd, "Gemfile"));
|
|
41838
|
+
const hasSpecDir = fs16.existsSync(path28.join(cwd, "spec"));
|
|
41788
41839
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
41789
41840
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
41790
41841
|
}
|
|
41791
41842
|
function detectMinitest(cwd) {
|
|
41792
|
-
return fs16.existsSync(
|
|
41843
|
+
return fs16.existsSync(path28.join(cwd, "test")) && (fs16.existsSync(path28.join(cwd, "Gemfile")) || fs16.existsSync(path28.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
41793
41844
|
}
|
|
41794
41845
|
async function detectTestFramework(cwd) {
|
|
41795
41846
|
const baseDir = cwd;
|
|
41796
41847
|
try {
|
|
41797
|
-
const packageJsonPath =
|
|
41848
|
+
const packageJsonPath = path28.join(baseDir, "package.json");
|
|
41798
41849
|
if (fs16.existsSync(packageJsonPath)) {
|
|
41799
41850
|
const content = fs16.readFileSync(packageJsonPath, "utf-8");
|
|
41800
41851
|
const pkg = JSON.parse(content);
|
|
@@ -41815,16 +41866,16 @@ async function detectTestFramework(cwd) {
|
|
|
41815
41866
|
return "jest";
|
|
41816
41867
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
41817
41868
|
return "mocha";
|
|
41818
|
-
if (fs16.existsSync(
|
|
41869
|
+
if (fs16.existsSync(path28.join(baseDir, "bun.lockb")) || fs16.existsSync(path28.join(baseDir, "bun.lock"))) {
|
|
41819
41870
|
if (scripts.test?.includes("bun"))
|
|
41820
41871
|
return "bun";
|
|
41821
41872
|
}
|
|
41822
41873
|
}
|
|
41823
41874
|
} catch {}
|
|
41824
41875
|
try {
|
|
41825
|
-
const pyprojectTomlPath =
|
|
41826
|
-
const setupCfgPath =
|
|
41827
|
-
const requirementsTxtPath =
|
|
41876
|
+
const pyprojectTomlPath = path28.join(baseDir, "pyproject.toml");
|
|
41877
|
+
const setupCfgPath = path28.join(baseDir, "setup.cfg");
|
|
41878
|
+
const requirementsTxtPath = path28.join(baseDir, "requirements.txt");
|
|
41828
41879
|
if (fs16.existsSync(pyprojectTomlPath)) {
|
|
41829
41880
|
const content = fs16.readFileSync(pyprojectTomlPath, "utf-8");
|
|
41830
41881
|
if (content.includes("[tool.pytest"))
|
|
@@ -41844,7 +41895,7 @@ async function detectTestFramework(cwd) {
|
|
|
41844
41895
|
}
|
|
41845
41896
|
} catch {}
|
|
41846
41897
|
try {
|
|
41847
|
-
const cargoTomlPath =
|
|
41898
|
+
const cargoTomlPath = path28.join(baseDir, "Cargo.toml");
|
|
41848
41899
|
if (fs16.existsSync(cargoTomlPath)) {
|
|
41849
41900
|
const content = fs16.readFileSync(cargoTomlPath, "utf-8");
|
|
41850
41901
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -41855,9 +41906,9 @@ async function detectTestFramework(cwd) {
|
|
|
41855
41906
|
}
|
|
41856
41907
|
} catch {}
|
|
41857
41908
|
try {
|
|
41858
|
-
const pesterConfigPath =
|
|
41859
|
-
const pesterConfigJsonPath =
|
|
41860
|
-
const pesterPs1Path =
|
|
41909
|
+
const pesterConfigPath = path28.join(baseDir, "pester.config.ps1");
|
|
41910
|
+
const pesterConfigJsonPath = path28.join(baseDir, "pester.config.ps1.json");
|
|
41911
|
+
const pesterPs1Path = path28.join(baseDir, "tests.ps1");
|
|
41861
41912
|
if (fs16.existsSync(pesterConfigPath) || fs16.existsSync(pesterConfigJsonPath) || fs16.existsSync(pesterPs1Path)) {
|
|
41862
41913
|
return "pester";
|
|
41863
41914
|
}
|
|
@@ -41900,12 +41951,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
41900
41951
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
41901
41952
|
}
|
|
41902
41953
|
function resolveWorkspacePath(file3, workingDir) {
|
|
41903
|
-
return
|
|
41954
|
+
return path28.isAbsolute(file3) ? path28.resolve(file3) : path28.resolve(workingDir, file3);
|
|
41904
41955
|
}
|
|
41905
41956
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
41906
41957
|
if (!preferRelative)
|
|
41907
41958
|
return absolutePath;
|
|
41908
|
-
return
|
|
41959
|
+
return path28.relative(workingDir, absolutePath);
|
|
41909
41960
|
}
|
|
41910
41961
|
function dedupePush(target, value) {
|
|
41911
41962
|
if (!target.includes(value)) {
|
|
@@ -41942,18 +41993,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
41942
41993
|
}
|
|
41943
41994
|
}
|
|
41944
41995
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
41945
|
-
const relativeDir =
|
|
41996
|
+
const relativeDir = path28.dirname(relativePath);
|
|
41946
41997
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
41947
41998
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
41948
|
-
const rootDir =
|
|
41949
|
-
return nestedRelativeDir ? [rootDir,
|
|
41999
|
+
const rootDir = path28.join(workingDir, dirName);
|
|
42000
|
+
return nestedRelativeDir ? [rootDir, path28.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
41950
42001
|
});
|
|
41951
42002
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
41952
42003
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
41953
|
-
directories.push(
|
|
42004
|
+
directories.push(path28.join(workingDir, "src/test/java", path28.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
41954
42005
|
}
|
|
41955
42006
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
41956
|
-
directories.push(
|
|
42007
|
+
directories.push(path28.join(workingDir, "src/test/kotlin", path28.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
41957
42008
|
}
|
|
41958
42009
|
return [...new Set(directories)];
|
|
41959
42010
|
}
|
|
@@ -41981,23 +42032,23 @@ function isLanguageSpecificTestFile(basename4) {
|
|
|
41981
42032
|
}
|
|
41982
42033
|
function isConventionTestFilePath(filePath) {
|
|
41983
42034
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
41984
|
-
const basename4 =
|
|
42035
|
+
const basename4 = path28.basename(filePath);
|
|
41985
42036
|
return hasCompoundTestExtension(basename4) || basename4.includes(".spec.") || basename4.includes(".test.") || isLanguageSpecificTestFile(basename4) || isTestDirectoryPath(normalizedPath);
|
|
41986
42037
|
}
|
|
41987
42038
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
41988
42039
|
const testFiles = [];
|
|
41989
42040
|
for (const file3 of sourceFiles) {
|
|
41990
42041
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
41991
|
-
const relativeFile =
|
|
41992
|
-
const basename4 =
|
|
41993
|
-
const dirname11 =
|
|
41994
|
-
const preferRelativeOutput = !
|
|
42042
|
+
const relativeFile = path28.relative(workingDir, absoluteFile);
|
|
42043
|
+
const basename4 = path28.basename(absoluteFile);
|
|
42044
|
+
const dirname11 = path28.dirname(absoluteFile);
|
|
42045
|
+
const preferRelativeOutput = !path28.isAbsolute(file3);
|
|
41995
42046
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
41996
42047
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
41997
42048
|
continue;
|
|
41998
42049
|
}
|
|
41999
42050
|
const nameWithoutExt = basename4.replace(/\.[^.]+$/, "");
|
|
42000
|
-
const ext =
|
|
42051
|
+
const ext = path28.extname(basename4);
|
|
42001
42052
|
const genericTestNames = [
|
|
42002
42053
|
`${nameWithoutExt}.spec${ext}`,
|
|
42003
42054
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -42006,7 +42057,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
42006
42057
|
const colocatedCandidates = [
|
|
42007
42058
|
...genericTestNames,
|
|
42008
42059
|
...languageSpecificTestNames
|
|
42009
|
-
].map((candidateName) =>
|
|
42060
|
+
].map((candidateName) => path28.join(dirname11, candidateName));
|
|
42010
42061
|
const testDirectoryNames = [
|
|
42011
42062
|
basename4,
|
|
42012
42063
|
...genericTestNames,
|
|
@@ -42015,8 +42066,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
42015
42066
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
42016
42067
|
const possibleTestFiles = [
|
|
42017
42068
|
...colocatedCandidates,
|
|
42018
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
42019
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
42069
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path28.join(dirname11, dirName, candidateName))),
|
|
42070
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path28.join(candidateDir, candidateName)))
|
|
42020
42071
|
];
|
|
42021
42072
|
for (const testFile of possibleTestFiles) {
|
|
42022
42073
|
if (fs16.existsSync(testFile)) {
|
|
@@ -42037,7 +42088,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
42037
42088
|
try {
|
|
42038
42089
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
42039
42090
|
const content = fs16.readFileSync(absoluteTestFile, "utf-8");
|
|
42040
|
-
const testDir =
|
|
42091
|
+
const testDir = path28.dirname(absoluteTestFile);
|
|
42041
42092
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
42042
42093
|
let match;
|
|
42043
42094
|
match = importRegex.exec(content);
|
|
@@ -42045,8 +42096,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
42045
42096
|
const importPath = match[1];
|
|
42046
42097
|
let resolvedImport;
|
|
42047
42098
|
if (importPath.startsWith(".")) {
|
|
42048
|
-
resolvedImport =
|
|
42049
|
-
const existingExt =
|
|
42099
|
+
resolvedImport = path28.resolve(testDir, importPath);
|
|
42100
|
+
const existingExt = path28.extname(resolvedImport);
|
|
42050
42101
|
if (!existingExt) {
|
|
42051
42102
|
for (const extToTry of [
|
|
42052
42103
|
".ts",
|
|
@@ -42066,12 +42117,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
42066
42117
|
} else {
|
|
42067
42118
|
continue;
|
|
42068
42119
|
}
|
|
42069
|
-
const importBasename =
|
|
42070
|
-
const importDir =
|
|
42120
|
+
const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
|
|
42121
|
+
const importDir = path28.dirname(resolvedImport);
|
|
42071
42122
|
for (const sourceFile of absoluteSourceFiles) {
|
|
42072
|
-
const sourceDir =
|
|
42073
|
-
const sourceBasename =
|
|
42074
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
42123
|
+
const sourceDir = path28.dirname(sourceFile);
|
|
42124
|
+
const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
|
|
42125
|
+
const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test") || importDir === path28.join(sourceDir, "spec");
|
|
42075
42126
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
42076
42127
|
dedupePush(testFiles, testFile);
|
|
42077
42128
|
break;
|
|
@@ -42084,8 +42135,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
42084
42135
|
while (match !== null) {
|
|
42085
42136
|
const importPath = match[1];
|
|
42086
42137
|
if (importPath.startsWith(".")) {
|
|
42087
|
-
let resolvedImport =
|
|
42088
|
-
const existingExt =
|
|
42138
|
+
let resolvedImport = path28.resolve(testDir, importPath);
|
|
42139
|
+
const existingExt = path28.extname(resolvedImport);
|
|
42089
42140
|
if (!existingExt) {
|
|
42090
42141
|
for (const extToTry of [
|
|
42091
42142
|
".ts",
|
|
@@ -42102,12 +42153,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
42102
42153
|
}
|
|
42103
42154
|
}
|
|
42104
42155
|
}
|
|
42105
|
-
const importDir =
|
|
42106
|
-
const importBasename =
|
|
42156
|
+
const importDir = path28.dirname(resolvedImport);
|
|
42157
|
+
const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
|
|
42107
42158
|
for (const sourceFile of absoluteSourceFiles) {
|
|
42108
|
-
const sourceDir =
|
|
42109
|
-
const sourceBasename =
|
|
42110
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
42159
|
+
const sourceDir = path28.dirname(sourceFile);
|
|
42160
|
+
const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
|
|
42161
|
+
const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test") || importDir === path28.join(sourceDir, "spec");
|
|
42111
42162
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
42112
42163
|
dedupePush(testFiles, testFile);
|
|
42113
42164
|
break;
|
|
@@ -42210,8 +42261,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
|
|
|
42210
42261
|
return ["mvn", "test"];
|
|
42211
42262
|
case "gradle": {
|
|
42212
42263
|
const isWindows = process.platform === "win32";
|
|
42213
|
-
const hasGradlewBat = fs16.existsSync(
|
|
42214
|
-
const hasGradlew = fs16.existsSync(
|
|
42264
|
+
const hasGradlewBat = fs16.existsSync(path28.join(baseDir, "gradlew.bat"));
|
|
42265
|
+
const hasGradlew = fs16.existsSync(path28.join(baseDir, "gradlew"));
|
|
42215
42266
|
if (hasGradlewBat && isWindows)
|
|
42216
42267
|
return ["gradlew.bat", "test"];
|
|
42217
42268
|
if (hasGradlew)
|
|
@@ -42228,7 +42279,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
|
|
|
42228
42279
|
"cmake-build-release",
|
|
42229
42280
|
"out"
|
|
42230
42281
|
];
|
|
42231
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(
|
|
42282
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path28.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
42232
42283
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
42233
42284
|
}
|
|
42234
42285
|
case "swift-test":
|
|
@@ -42856,7 +42907,7 @@ var test_runner = createSwarmTool({
|
|
|
42856
42907
|
const sourceFiles = args.files.filter((file3) => {
|
|
42857
42908
|
if (directTestFiles.includes(file3))
|
|
42858
42909
|
return false;
|
|
42859
|
-
const ext =
|
|
42910
|
+
const ext = path28.extname(file3).toLowerCase();
|
|
42860
42911
|
return SOURCE_EXTENSIONS.has(ext);
|
|
42861
42912
|
});
|
|
42862
42913
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -42891,7 +42942,7 @@ var test_runner = createSwarmTool({
|
|
|
42891
42942
|
if (isConventionTestFilePath(f)) {
|
|
42892
42943
|
return false;
|
|
42893
42944
|
}
|
|
42894
|
-
const ext =
|
|
42945
|
+
const ext = path28.extname(f).toLowerCase();
|
|
42895
42946
|
return SOURCE_EXTENSIONS.has(ext);
|
|
42896
42947
|
});
|
|
42897
42948
|
if (sourceFiles.length === 0) {
|
|
@@ -42918,7 +42969,7 @@ var test_runner = createSwarmTool({
|
|
|
42918
42969
|
if (isConventionTestFilePath(f)) {
|
|
42919
42970
|
return false;
|
|
42920
42971
|
}
|
|
42921
|
-
const ext =
|
|
42972
|
+
const ext = path28.extname(f).toLowerCase();
|
|
42922
42973
|
return SOURCE_EXTENSIONS.has(ext);
|
|
42923
42974
|
});
|
|
42924
42975
|
if (sourceFiles.length === 0) {
|
|
@@ -42936,8 +42987,8 @@ var test_runner = createSwarmTool({
|
|
|
42936
42987
|
const impactResult = await analyzeImpact(sourceFiles, workingDir);
|
|
42937
42988
|
if (impactResult.impactedTests.length > 0) {
|
|
42938
42989
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
42939
|
-
const relativePath =
|
|
42940
|
-
return
|
|
42990
|
+
const relativePath = path28.relative(workingDir, absPath);
|
|
42991
|
+
return path28.isAbsolute(relativePath) ? absPath : relativePath;
|
|
42941
42992
|
});
|
|
42942
42993
|
} else {
|
|
42943
42994
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -43030,8 +43081,8 @@ function validateDirectoryPath(dir) {
|
|
|
43030
43081
|
if (dir.includes("..")) {
|
|
43031
43082
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
43032
43083
|
}
|
|
43033
|
-
const normalized =
|
|
43034
|
-
const absolutePath =
|
|
43084
|
+
const normalized = path29.normalize(dir);
|
|
43085
|
+
const absolutePath = path29.isAbsolute(normalized) ? normalized : path29.resolve(normalized);
|
|
43035
43086
|
return absolutePath;
|
|
43036
43087
|
}
|
|
43037
43088
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -43054,7 +43105,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
43054
43105
|
}
|
|
43055
43106
|
function getPackageVersion(dir) {
|
|
43056
43107
|
try {
|
|
43057
|
-
const packagePath =
|
|
43108
|
+
const packagePath = path29.join(dir, "package.json");
|
|
43058
43109
|
if (fs17.existsSync(packagePath)) {
|
|
43059
43110
|
const content = fs17.readFileSync(packagePath, "utf-8");
|
|
43060
43111
|
const pkg = JSON.parse(content);
|
|
@@ -43065,7 +43116,7 @@ function getPackageVersion(dir) {
|
|
|
43065
43116
|
}
|
|
43066
43117
|
function getChangelogVersion(dir) {
|
|
43067
43118
|
try {
|
|
43068
|
-
const changelogPath =
|
|
43119
|
+
const changelogPath = path29.join(dir, "CHANGELOG.md");
|
|
43069
43120
|
if (fs17.existsSync(changelogPath)) {
|
|
43070
43121
|
const content = fs17.readFileSync(changelogPath, "utf-8");
|
|
43071
43122
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -43079,7 +43130,7 @@ function getChangelogVersion(dir) {
|
|
|
43079
43130
|
function getVersionFileVersion(dir) {
|
|
43080
43131
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
43081
43132
|
for (const file3 of possibleFiles) {
|
|
43082
|
-
const filePath =
|
|
43133
|
+
const filePath = path29.join(dir, file3);
|
|
43083
43134
|
if (fs17.existsSync(filePath)) {
|
|
43084
43135
|
try {
|
|
43085
43136
|
const content = fs17.readFileSync(filePath, "utf-8").trim();
|
|
@@ -43406,7 +43457,7 @@ async function runEvidenceCheck(dir) {
|
|
|
43406
43457
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
43407
43458
|
const startTime = Date.now();
|
|
43408
43459
|
try {
|
|
43409
|
-
const specPath =
|
|
43460
|
+
const specPath = path29.join(dir, ".swarm", "spec.md");
|
|
43410
43461
|
if (!fs17.existsSync(specPath)) {
|
|
43411
43462
|
return {
|
|
43412
43463
|
type: "req_coverage",
|
|
@@ -44529,7 +44580,7 @@ async function handleResetCommand(directory, args) {
|
|
|
44529
44580
|
// src/commands/reset-session.ts
|
|
44530
44581
|
init_utils2();
|
|
44531
44582
|
import * as fs19 from "fs";
|
|
44532
|
-
import * as
|
|
44583
|
+
import * as path30 from "path";
|
|
44533
44584
|
async function handleResetSessionCommand(directory, _args) {
|
|
44534
44585
|
const results = [];
|
|
44535
44586
|
try {
|
|
@@ -44544,13 +44595,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
44544
44595
|
results.push("\u274C Failed to delete state.json");
|
|
44545
44596
|
}
|
|
44546
44597
|
try {
|
|
44547
|
-
const sessionDir =
|
|
44598
|
+
const sessionDir = path30.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
44548
44599
|
if (fs19.existsSync(sessionDir)) {
|
|
44549
44600
|
const files = fs19.readdirSync(sessionDir);
|
|
44550
44601
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
44551
44602
|
let deletedCount = 0;
|
|
44552
44603
|
for (const file3 of otherFiles) {
|
|
44553
|
-
const filePath =
|
|
44604
|
+
const filePath = path30.join(sessionDir, file3);
|
|
44554
44605
|
if (fs19.lstatSync(filePath).isFile()) {
|
|
44555
44606
|
fs19.unlinkSync(filePath);
|
|
44556
44607
|
deletedCount++;
|
|
@@ -44580,7 +44631,7 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
44580
44631
|
// src/summaries/manager.ts
|
|
44581
44632
|
init_utils2();
|
|
44582
44633
|
init_utils();
|
|
44583
|
-
import * as
|
|
44634
|
+
import * as path31 from "path";
|
|
44584
44635
|
var SUMMARY_ID_REGEX = /^S\d+$/;
|
|
44585
44636
|
function sanitizeSummaryId(id) {
|
|
44586
44637
|
if (!id || id.length === 0) {
|
|
@@ -44604,7 +44655,7 @@ function sanitizeSummaryId(id) {
|
|
|
44604
44655
|
}
|
|
44605
44656
|
async function loadFullOutput(directory, id) {
|
|
44606
44657
|
const sanitizedId = sanitizeSummaryId(id);
|
|
44607
|
-
const relativePath =
|
|
44658
|
+
const relativePath = path31.join("summaries", `${sanitizedId}.json`);
|
|
44608
44659
|
validateSwarmPath(directory, relativePath);
|
|
44609
44660
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
44610
44661
|
if (content === null) {
|
|
@@ -44660,7 +44711,7 @@ init_plan_schema();
|
|
|
44660
44711
|
init_utils2();
|
|
44661
44712
|
init_ledger();
|
|
44662
44713
|
import * as fs20 from "fs";
|
|
44663
|
-
import * as
|
|
44714
|
+
import * as path32 from "path";
|
|
44664
44715
|
async function handleRollbackCommand(directory, args) {
|
|
44665
44716
|
const phaseArg = args[0];
|
|
44666
44717
|
if (!phaseArg) {
|
|
@@ -44725,8 +44776,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
44725
44776
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
44726
44777
|
continue;
|
|
44727
44778
|
}
|
|
44728
|
-
const src =
|
|
44729
|
-
const dest =
|
|
44779
|
+
const src = path32.join(checkpointDir, file3);
|
|
44780
|
+
const dest = path32.join(swarmDir, file3);
|
|
44730
44781
|
try {
|
|
44731
44782
|
fs20.cpSync(src, dest, { recursive: true, force: true });
|
|
44732
44783
|
successes.push(file3);
|
|
@@ -44745,12 +44796,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
44745
44796
|
].join(`
|
|
44746
44797
|
`);
|
|
44747
44798
|
}
|
|
44748
|
-
const existingLedgerPath =
|
|
44799
|
+
const existingLedgerPath = path32.join(swarmDir, "plan-ledger.jsonl");
|
|
44749
44800
|
if (fs20.existsSync(existingLedgerPath)) {
|
|
44750
44801
|
fs20.unlinkSync(existingLedgerPath);
|
|
44751
44802
|
}
|
|
44752
44803
|
try {
|
|
44753
|
-
const planJsonPath =
|
|
44804
|
+
const planJsonPath = path32.join(swarmDir, "plan.json");
|
|
44754
44805
|
if (fs20.existsSync(planJsonPath)) {
|
|
44755
44806
|
const planRaw = fs20.readFileSync(planJsonPath, "utf-8");
|
|
44756
44807
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -44823,9 +44874,9 @@ async function handleSimulateCommand(directory, args) {
|
|
|
44823
44874
|
const report = reportLines.filter(Boolean).join(`
|
|
44824
44875
|
`);
|
|
44825
44876
|
const fs21 = await import("fs/promises");
|
|
44826
|
-
const
|
|
44827
|
-
const reportPath =
|
|
44828
|
-
await fs21.mkdir(
|
|
44877
|
+
const path33 = await import("path");
|
|
44878
|
+
const reportPath = path33.join(directory, ".swarm", "simulate-report.md");
|
|
44879
|
+
await fs21.mkdir(path33.dirname(reportPath), { recursive: true });
|
|
44829
44880
|
await fs21.writeFile(reportPath, report, "utf-8");
|
|
44830
44881
|
return `${darkMatterPairs.length} hidden coupling pairs detected`;
|
|
44831
44882
|
}
|
|
@@ -45360,21 +45411,34 @@ function resolveCommand(tokens) {
|
|
|
45360
45411
|
|
|
45361
45412
|
// src/cli/index.ts
|
|
45362
45413
|
var { version: version4 } = package_default;
|
|
45363
|
-
var CONFIG_DIR =
|
|
45364
|
-
var OPENCODE_CONFIG_PATH =
|
|
45365
|
-
var PLUGIN_CONFIG_PATH =
|
|
45366
|
-
var PROMPTS_DIR =
|
|
45367
|
-
var OPENCODE_PLUGIN_CACHE_PATHS =
|
|
45368
|
-
path32.join(process.env.XDG_CACHE_HOME || path32.join(os6.homedir(), ".cache"), "opencode", "packages", "opencode-swarm@latest"),
|
|
45369
|
-
path32.join(CONFIG_DIR, "node_modules", "opencode-swarm")
|
|
45370
|
-
];
|
|
45414
|
+
var CONFIG_DIR = getPluginConfigDir();
|
|
45415
|
+
var OPENCODE_CONFIG_PATH = path33.join(CONFIG_DIR, "opencode.json");
|
|
45416
|
+
var PLUGIN_CONFIG_PATH = path33.join(CONFIG_DIR, "opencode-swarm.json");
|
|
45417
|
+
var PROMPTS_DIR = path33.join(CONFIG_DIR, "opencode-swarm");
|
|
45418
|
+
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
45371
45419
|
function isSafeCachePath(p) {
|
|
45372
|
-
const resolved =
|
|
45373
|
-
const home =
|
|
45374
|
-
if (resolved === "/" || resolved === home || resolved.length <= home.length)
|
|
45420
|
+
const resolved = path33.resolve(p);
|
|
45421
|
+
const home = path33.resolve(os7.homedir());
|
|
45422
|
+
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
45423
|
+
return false;
|
|
45424
|
+
}
|
|
45425
|
+
const segments = resolved.split(path33.sep).filter((s) => s.length > 0);
|
|
45426
|
+
if (segments.length < 4) {
|
|
45375
45427
|
return false;
|
|
45376
|
-
|
|
45377
|
-
|
|
45428
|
+
}
|
|
45429
|
+
const leaf = path33.basename(resolved);
|
|
45430
|
+
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
45431
|
+
return false;
|
|
45432
|
+
}
|
|
45433
|
+
const parent = path33.basename(path33.dirname(resolved));
|
|
45434
|
+
if (parent !== "packages" && parent !== "node_modules") {
|
|
45435
|
+
return false;
|
|
45436
|
+
}
|
|
45437
|
+
const grandparent = path33.basename(path33.dirname(path33.dirname(resolved)));
|
|
45438
|
+
if (grandparent !== "opencode") {
|
|
45439
|
+
return false;
|
|
45440
|
+
}
|
|
45441
|
+
return true;
|
|
45378
45442
|
}
|
|
45379
45443
|
function ensureDir(dir) {
|
|
45380
45444
|
if (!fs21.existsSync(dir)) {
|
|
@@ -45396,8 +45460,8 @@ function saveJson(filepath, data) {
|
|
|
45396
45460
|
}
|
|
45397
45461
|
function writeProjectConfigIfMissing(cwd) {
|
|
45398
45462
|
try {
|
|
45399
|
-
const opencodeDir =
|
|
45400
|
-
const projectConfigPath =
|
|
45463
|
+
const opencodeDir = path33.join(cwd, ".opencode");
|
|
45464
|
+
const projectConfigPath = path33.join(opencodeDir, "opencode-swarm.json");
|
|
45401
45465
|
if (fs21.existsSync(projectConfigPath)) {
|
|
45402
45466
|
return;
|
|
45403
45467
|
}
|
|
@@ -45415,7 +45479,7 @@ async function install() {
|
|
|
45415
45479
|
`);
|
|
45416
45480
|
ensureDir(CONFIG_DIR);
|
|
45417
45481
|
ensureDir(PROMPTS_DIR);
|
|
45418
|
-
const LEGACY_CONFIG_PATH =
|
|
45482
|
+
const LEGACY_CONFIG_PATH = path33.join(CONFIG_DIR, "config.json");
|
|
45419
45483
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
45420
45484
|
if (!opencodeConfig) {
|
|
45421
45485
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|