opencode-swarm 7.43.1 → 7.44.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 +638 -390
- package/dist/hooks/knowledge-events.d.ts +193 -0
- package/dist/hooks/knowledge-reader.d.ts +3 -10
- package/dist/hooks/knowledge-store.d.ts +4 -1
- package/dist/hooks/knowledge-types.d.ts +2 -0
- package/dist/hooks/search-knowledge.d.ts +74 -0
- package/dist/index.js +2064 -1460
- package/dist/services/knowledge-diagnostics.d.ts +46 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/knowledge-archive.d.ts +18 -0
- package/dist/tools/knowledge-receipt.d.ts +19 -0
- package/dist/tools/tool-names.d.ts +1 -1
- 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.
|
|
55
|
+
version: "7.44.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",
|
|
@@ -16522,6 +16522,8 @@ var init_tool_names = __esm(() => {
|
|
|
16522
16522
|
"skill_improve",
|
|
16523
16523
|
"spec_write",
|
|
16524
16524
|
"knowledge_ack",
|
|
16525
|
+
"knowledge_receipt",
|
|
16526
|
+
"knowledge_archive",
|
|
16525
16527
|
"swarm_memory_recall",
|
|
16526
16528
|
"swarm_memory_propose",
|
|
16527
16529
|
"swarm_command",
|
|
@@ -16766,6 +16768,7 @@ var init_constants = __esm(() => {
|
|
|
16766
16768
|
"knowledge_add",
|
|
16767
16769
|
"knowledge_recall",
|
|
16768
16770
|
"knowledge_remove",
|
|
16771
|
+
"knowledge_archive",
|
|
16769
16772
|
"co_change_analyzer",
|
|
16770
16773
|
"suggest_patch",
|
|
16771
16774
|
"repo_map",
|
|
@@ -16782,6 +16785,7 @@ var init_constants = __esm(() => {
|
|
|
16782
16785
|
"skill_retire",
|
|
16783
16786
|
"skill_improve",
|
|
16784
16787
|
"knowledge_ack",
|
|
16788
|
+
"knowledge_receipt",
|
|
16785
16789
|
"summarize_work",
|
|
16786
16790
|
"write_architecture_supervisor_evidence",
|
|
16787
16791
|
"swarm_command",
|
|
@@ -16822,6 +16826,7 @@ var init_constants = __esm(() => {
|
|
|
16822
16826
|
"syntax_check",
|
|
16823
16827
|
"knowledge_add",
|
|
16824
16828
|
"knowledge_recall",
|
|
16829
|
+
"knowledge_receipt",
|
|
16825
16830
|
"repo_map",
|
|
16826
16831
|
"summarize_work",
|
|
16827
16832
|
"swarm_command"
|
|
@@ -17045,6 +17050,7 @@ var init_constants = __esm(() => {
|
|
|
17045
17050
|
knowledge_add: "store a new lesson in the knowledge base",
|
|
17046
17051
|
knowledge_recall: "search the knowledge base for relevant past decisions",
|
|
17047
17052
|
knowledge_remove: "delete an outdated swarm knowledge entry by ID (swarm tier only)",
|
|
17053
|
+
knowledge_archive: "archive (default), quarantine, or purge a swarm knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
|
|
17048
17054
|
knowledge_query: "query swarm or hive knowledge with optional filters",
|
|
17049
17055
|
co_change_analyzer: "detect hidden couplings by analyzing git history",
|
|
17050
17056
|
check_gate_status: "check the gate status of a specific task",
|
|
@@ -17078,6 +17084,7 @@ var init_constants = __esm(() => {
|
|
|
17078
17084
|
skill_retire: "retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",
|
|
17079
17085
|
spec_write: "author or update .swarm/spec.md for the current project",
|
|
17080
17086
|
knowledge_ack: "record an explicit KNOWLEDGE_APPLIED/IGNORED/VIOLATED acknowledgment",
|
|
17087
|
+
knowledge_receipt: "file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",
|
|
17081
17088
|
swarm_memory_recall: "recall scoped Swarm memory for the current repository as untrusted background",
|
|
17082
17089
|
swarm_memory_propose: "create a pending Swarm memory proposal; does not write durable memory directly",
|
|
17083
17090
|
swarm_command: "run supported /swarm commands through the canonical command registry",
|
|
@@ -35869,8 +35876,12 @@ function normalizeEntry(raw) {
|
|
|
35869
35876
|
const obj = raw;
|
|
35870
35877
|
if (!("retrieval_outcomes" in obj))
|
|
35871
35878
|
return raw;
|
|
35872
|
-
|
|
35873
|
-
if (ro
|
|
35879
|
+
let ro = obj.retrieval_outcomes;
|
|
35880
|
+
if (!ro || typeof ro !== "object") {
|
|
35881
|
+
ro = {};
|
|
35882
|
+
obj.retrieval_outcomes = ro;
|
|
35883
|
+
}
|
|
35884
|
+
{
|
|
35874
35885
|
if (typeof ro.shown_count !== "number") {
|
|
35875
35886
|
ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
|
|
35876
35887
|
}
|
|
@@ -35883,6 +35894,8 @@ function normalizeEntry(raw) {
|
|
|
35883
35894
|
ro.ignored_count = 0;
|
|
35884
35895
|
if (typeof ro.violated_count !== "number")
|
|
35885
35896
|
ro.violated_count = 0;
|
|
35897
|
+
if (typeof ro.contradicted_count !== "number")
|
|
35898
|
+
ro.contradicted_count = 0;
|
|
35886
35899
|
if (typeof ro.succeeded_after_shown_count !== "number") {
|
|
35887
35900
|
ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
|
|
35888
35901
|
}
|
|
@@ -35920,6 +35933,9 @@ function normalizeEntry(raw) {
|
|
|
35920
35933
|
delete obj[f];
|
|
35921
35934
|
}
|
|
35922
35935
|
}
|
|
35936
|
+
if (!Array.isArray(obj.tags)) {
|
|
35937
|
+
obj.tags = [];
|
|
35938
|
+
}
|
|
35923
35939
|
return raw;
|
|
35924
35940
|
}
|
|
35925
35941
|
async function readRejectedLessons(directory) {
|
|
@@ -36009,7 +36025,8 @@ async function appendRejectedLesson(directory, lesson) {
|
|
|
36009
36025
|
}
|
|
36010
36026
|
}
|
|
36011
36027
|
function normalize2(text) {
|
|
36012
|
-
|
|
36028
|
+
const s = typeof text === "string" ? text : String(text ?? "");
|
|
36029
|
+
return s.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
36013
36030
|
}
|
|
36014
36031
|
function wordBigrams(text) {
|
|
36015
36032
|
const words = normalize2(text).split(" ").filter(Boolean);
|
|
@@ -36041,6 +36058,16 @@ function computeConfidence(confirmedByCount, autoGenerated) {
|
|
|
36041
36058
|
score += 0.1;
|
|
36042
36059
|
return Math.min(score, 1);
|
|
36043
36060
|
}
|
|
36061
|
+
function computeOutcomeSignal(outcomes) {
|
|
36062
|
+
if (!outcomes)
|
|
36063
|
+
return 0;
|
|
36064
|
+
const positives = (outcomes.applied_explicit_count ?? 0) + (outcomes.succeeded_after_shown_count ?? 0);
|
|
36065
|
+
const negatives = (outcomes.ignored_count ?? 0) + (outcomes.violated_count ?? 0) + (outcomes.contradicted_count ?? 0) + (outcomes.failed_after_shown_count ?? 0);
|
|
36066
|
+
const total = positives + negatives;
|
|
36067
|
+
if (total === 0)
|
|
36068
|
+
return 0;
|
|
36069
|
+
return (positives - negatives) / (total + OUTCOME_SIGNAL_SMOOTHING);
|
|
36070
|
+
}
|
|
36044
36071
|
function inferTags(lesson) {
|
|
36045
36072
|
const lower = lesson.toLowerCase();
|
|
36046
36073
|
const tags = [];
|
|
@@ -36136,7 +36163,7 @@ async function applyConfidenceDeltas(filePath, deltas) {
|
|
|
36136
36163
|
}
|
|
36137
36164
|
}
|
|
36138
36165
|
}
|
|
36139
|
-
var import_proper_lockfile3, CONFIDENCE_FLOOR = 0.1, CONFIDENCE_CEILING = 1;
|
|
36166
|
+
var import_proper_lockfile3, OUTCOME_SIGNAL_SMOOTHING = 4, CONFIDENCE_FLOOR = 0.1, CONFIDENCE_CEILING = 1;
|
|
36140
36167
|
var init_knowledge_store = __esm(() => {
|
|
36141
36168
|
init_task_file();
|
|
36142
36169
|
import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
@@ -37570,6 +37597,9 @@ async function runAutoPromotion(directory, config3) {
|
|
|
37570
37597
|
for (const entry of entries) {
|
|
37571
37598
|
if (entry.status === "promoted")
|
|
37572
37599
|
continue;
|
|
37600
|
+
if (computeOutcomeSignal(entry.retrieval_outcomes) <= OUTCOME_PROMOTION_BLOCK) {
|
|
37601
|
+
continue;
|
|
37602
|
+
}
|
|
37573
37603
|
const distinctPhases = new Set((entry.confirmed_by ?? []).map((c) => c.phase_number)).size;
|
|
37574
37604
|
if (entry.status === "candidate" && distinctPhases >= 3) {
|
|
37575
37605
|
entry.status = "established";
|
|
@@ -37667,7 +37697,7 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
37667
37697
|
};
|
|
37668
37698
|
return safeHook(handler);
|
|
37669
37699
|
}
|
|
37670
|
-
var seenRetroSections, _internals11;
|
|
37700
|
+
var seenRetroSections, OUTCOME_PROMOTION_BLOCK = -0.3, _internals11;
|
|
37671
37701
|
var init_knowledge_curator = __esm(() => {
|
|
37672
37702
|
init_knowledge_store();
|
|
37673
37703
|
init_knowledge_validator();
|
|
@@ -40241,24 +40271,63 @@ var init_gate_bridge = __esm(() => {
|
|
|
40241
40271
|
};
|
|
40242
40272
|
});
|
|
40243
40273
|
|
|
40274
|
+
// src/hooks/knowledge-events.ts
|
|
40275
|
+
import { existsSync as existsSync12 } from "fs";
|
|
40276
|
+
import { appendFile as appendFile4, mkdir as mkdir7, readFile as readFile7 } from "fs/promises";
|
|
40277
|
+
import * as path23 from "path";
|
|
40278
|
+
function resolveKnowledgeEventsPath(directory) {
|
|
40279
|
+
return path23.join(directory, ".swarm", "knowledge-events.jsonl");
|
|
40280
|
+
}
|
|
40281
|
+
async function readKnowledgeEvents(directory) {
|
|
40282
|
+
const filePath = resolveKnowledgeEventsPath(directory);
|
|
40283
|
+
if (!existsSync12(filePath))
|
|
40284
|
+
return [];
|
|
40285
|
+
const content = await readFile7(filePath, "utf-8");
|
|
40286
|
+
const out = [];
|
|
40287
|
+
for (const line of content.split(`
|
|
40288
|
+
`)) {
|
|
40289
|
+
const trimmed = line.trim();
|
|
40290
|
+
if (!trimmed)
|
|
40291
|
+
continue;
|
|
40292
|
+
try {
|
|
40293
|
+
out.push(JSON.parse(trimmed));
|
|
40294
|
+
} catch {
|
|
40295
|
+
warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
|
|
40296
|
+
}
|
|
40297
|
+
}
|
|
40298
|
+
return out;
|
|
40299
|
+
}
|
|
40300
|
+
var RECEIPT_EVENT_TYPES;
|
|
40301
|
+
var init_knowledge_events = __esm(() => {
|
|
40302
|
+
init_logger();
|
|
40303
|
+
init_knowledge_store();
|
|
40304
|
+
RECEIPT_EVENT_TYPES = new Set([
|
|
40305
|
+
"acknowledged",
|
|
40306
|
+
"applied",
|
|
40307
|
+
"ignored",
|
|
40308
|
+
"contradicted",
|
|
40309
|
+
"violated"
|
|
40310
|
+
]);
|
|
40311
|
+
});
|
|
40312
|
+
|
|
40244
40313
|
// src/services/version-check.ts
|
|
40245
|
-
import { existsSync as
|
|
40314
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
40246
40315
|
import { homedir as homedir5 } from "os";
|
|
40247
|
-
import { join as
|
|
40316
|
+
import { join as join22 } from "path";
|
|
40248
40317
|
function cacheDir() {
|
|
40249
40318
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
40250
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
40251
|
-
return
|
|
40319
|
+
const base = xdg && xdg.length > 0 ? xdg : join22(homedir5(), ".cache");
|
|
40320
|
+
return join22(base, "opencode-swarm");
|
|
40252
40321
|
}
|
|
40253
40322
|
function cacheFile() {
|
|
40254
|
-
return
|
|
40323
|
+
return join22(cacheDir(), "version-check.json");
|
|
40255
40324
|
}
|
|
40256
40325
|
function readVersionCache() {
|
|
40257
40326
|
try {
|
|
40258
|
-
const
|
|
40259
|
-
if (!
|
|
40327
|
+
const path24 = cacheFile();
|
|
40328
|
+
if (!existsSync13(path24))
|
|
40260
40329
|
return null;
|
|
40261
|
-
const raw = readFileSync8(
|
|
40330
|
+
const raw = readFileSync8(path24, "utf-8");
|
|
40262
40331
|
const parsed = JSON.parse(raw);
|
|
40263
40332
|
if (typeof parsed?.checkedAt !== "number")
|
|
40264
40333
|
return null;
|
|
@@ -40295,10 +40364,156 @@ var init_version_check = __esm(() => {
|
|
|
40295
40364
|
CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
40296
40365
|
});
|
|
40297
40366
|
|
|
40367
|
+
// src/services/knowledge-diagnostics.ts
|
|
40368
|
+
import { existsSync as existsSync14 } from "fs";
|
|
40369
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
40370
|
+
async function readRawLines(filePath) {
|
|
40371
|
+
if (!existsSync14(filePath))
|
|
40372
|
+
return { entries: [], corrupt: 0 };
|
|
40373
|
+
const content = await readFile8(filePath, "utf-8");
|
|
40374
|
+
const entries = [];
|
|
40375
|
+
let corrupt = 0;
|
|
40376
|
+
for (const line of content.split(`
|
|
40377
|
+
`)) {
|
|
40378
|
+
const trimmed = line.trim();
|
|
40379
|
+
if (!trimmed)
|
|
40380
|
+
continue;
|
|
40381
|
+
try {
|
|
40382
|
+
entries.push(JSON.parse(trimmed));
|
|
40383
|
+
} catch {
|
|
40384
|
+
corrupt++;
|
|
40385
|
+
}
|
|
40386
|
+
}
|
|
40387
|
+
return { entries, corrupt };
|
|
40388
|
+
}
|
|
40389
|
+
function hasV2Counters(entry) {
|
|
40390
|
+
const ro = entry.retrieval_outcomes;
|
|
40391
|
+
if (!ro || typeof ro !== "object")
|
|
40392
|
+
return false;
|
|
40393
|
+
return typeof ro.shown_count === "number" && typeof ro.applied_explicit_count === "number" && typeof ro.ignored_count === "number";
|
|
40394
|
+
}
|
|
40395
|
+
function cacheStatus() {
|
|
40396
|
+
const cache = readVersionCache();
|
|
40397
|
+
if (!cache?.npmLatest)
|
|
40398
|
+
return "unknown";
|
|
40399
|
+
return compareVersions(cache.npmLatest, version3) > 0 ? "stale" : "fresh";
|
|
40400
|
+
}
|
|
40401
|
+
async function computeKnowledgeDebug(directory) {
|
|
40402
|
+
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
40403
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
40404
|
+
const eventsPath = resolveKnowledgeEventsPath(directory);
|
|
40405
|
+
const [swarmRaw, hiveRaw] = await Promise.all([
|
|
40406
|
+
readRawLines(swarmPath),
|
|
40407
|
+
readRawLines(hivePath)
|
|
40408
|
+
]);
|
|
40409
|
+
const rawEntries = [...swarmRaw.entries, ...hiveRaw.entries];
|
|
40410
|
+
const corrupt = swarmRaw.corrupt + hiveRaw.corrupt;
|
|
40411
|
+
const schemaVersions = {};
|
|
40412
|
+
let missingV2 = 0;
|
|
40413
|
+
for (const e of rawEntries) {
|
|
40414
|
+
const sv = String(typeof e.schema_version === "number" ? e.schema_version : "unknown");
|
|
40415
|
+
schemaVersions[sv] = (schemaVersions[sv] ?? 0) + 1;
|
|
40416
|
+
if (!hasV2Counters(e))
|
|
40417
|
+
missingV2++;
|
|
40418
|
+
}
|
|
40419
|
+
let normalizedCount = 0;
|
|
40420
|
+
let active = 0;
|
|
40421
|
+
let archived = 0;
|
|
40422
|
+
let quarantined = 0;
|
|
40423
|
+
try {
|
|
40424
|
+
const swarm = await readKnowledge(swarmPath);
|
|
40425
|
+
const hive = await readKnowledge(hivePath);
|
|
40426
|
+
for (const e of [...swarm, ...hive]) {
|
|
40427
|
+
normalizedCount++;
|
|
40428
|
+
if (e.status === "archived")
|
|
40429
|
+
archived++;
|
|
40430
|
+
else if (e.status === "quarantined")
|
|
40431
|
+
quarantined++;
|
|
40432
|
+
else
|
|
40433
|
+
active++;
|
|
40434
|
+
}
|
|
40435
|
+
} catch {}
|
|
40436
|
+
let rejected = 0;
|
|
40437
|
+
try {
|
|
40438
|
+
rejected = (await readRejectedLessons(directory)).length;
|
|
40439
|
+
} catch {}
|
|
40440
|
+
let eventCount = 0;
|
|
40441
|
+
let retrieval7d = 0;
|
|
40442
|
+
try {
|
|
40443
|
+
const events = await readKnowledgeEvents(directory);
|
|
40444
|
+
eventCount = events.length;
|
|
40445
|
+
const cutoff = Date.now() - SEVEN_DAYS_MS;
|
|
40446
|
+
for (const ev of events) {
|
|
40447
|
+
if (ev.type !== "retrieved")
|
|
40448
|
+
continue;
|
|
40449
|
+
const t = Date.parse(ev.timestamp);
|
|
40450
|
+
if (!Number.isNaN(t) && t >= cutoff)
|
|
40451
|
+
retrieval7d++;
|
|
40452
|
+
}
|
|
40453
|
+
} catch {}
|
|
40454
|
+
return {
|
|
40455
|
+
plugin_version: version3,
|
|
40456
|
+
directory,
|
|
40457
|
+
swarm_path: swarmPath,
|
|
40458
|
+
hive_path: hivePath,
|
|
40459
|
+
events_path: eventsPath,
|
|
40460
|
+
raw_entry_count: rawEntries.length,
|
|
40461
|
+
normalized_entry_count: normalizedCount,
|
|
40462
|
+
corrupt_line_count: corrupt,
|
|
40463
|
+
schema_versions: schemaVersions,
|
|
40464
|
+
entries_missing_v2_counters: missingV2,
|
|
40465
|
+
status_breakdown: { active, archived, quarantined, rejected },
|
|
40466
|
+
event_count: eventCount,
|
|
40467
|
+
retrieval_events_7d: retrieval7d,
|
|
40468
|
+
cache_status: cacheStatus()
|
|
40469
|
+
};
|
|
40470
|
+
}
|
|
40471
|
+
async function checkKnowledgeHealth(directory) {
|
|
40472
|
+
let debug;
|
|
40473
|
+
try {
|
|
40474
|
+
debug = await computeKnowledgeDebug(directory);
|
|
40475
|
+
} catch {
|
|
40476
|
+
return {
|
|
40477
|
+
name: "Knowledge health",
|
|
40478
|
+
status: "\u26A0\uFE0F",
|
|
40479
|
+
detail: "Could not compute knowledge diagnostics"
|
|
40480
|
+
};
|
|
40481
|
+
}
|
|
40482
|
+
const sb = debug.status_breakdown;
|
|
40483
|
+
const summary = `active=${sb.active} archived=${sb.archived} quarantined=${sb.quarantined} ` + `rejected=${sb.rejected} | events=${debug.event_count} (retrieved/7d=${debug.retrieval_events_7d}) | ` + `schema=${JSON.stringify(debug.schema_versions)}`;
|
|
40484
|
+
const warnings = [];
|
|
40485
|
+
if (debug.corrupt_line_count > 0) {
|
|
40486
|
+
warnings.push(`${debug.corrupt_line_count} corrupt JSONL line(s) (raw=${debug.raw_entry_count} vs normalized=${debug.normalized_entry_count})`);
|
|
40487
|
+
}
|
|
40488
|
+
if (debug.entries_missing_v2_counters > 0) {
|
|
40489
|
+
warnings.push(`${debug.entries_missing_v2_counters} entr(y/ies) missing v2 counters (normalized on read)`);
|
|
40490
|
+
}
|
|
40491
|
+
if (debug.cache_status === "stale") {
|
|
40492
|
+
warnings.push("stale plugin cache \u2014 run `bunx opencode-swarm update` (knowledge tools may be running old code)");
|
|
40493
|
+
}
|
|
40494
|
+
if (warnings.length > 0) {
|
|
40495
|
+
return {
|
|
40496
|
+
name: "Knowledge health",
|
|
40497
|
+
status: "\u26A0\uFE0F",
|
|
40498
|
+
detail: `${summary} \u2014 ${warnings.join("; ")}`
|
|
40499
|
+
};
|
|
40500
|
+
}
|
|
40501
|
+
return { name: "Knowledge health", status: "\u2705", detail: summary };
|
|
40502
|
+
}
|
|
40503
|
+
var version3, SEVEN_DAYS_MS;
|
|
40504
|
+
var init_knowledge_diagnostics = __esm(() => {
|
|
40505
|
+
init_package();
|
|
40506
|
+
init_knowledge_events();
|
|
40507
|
+
init_knowledge_store();
|
|
40508
|
+
init_version_check();
|
|
40509
|
+
({ version: version3 } = package_default);
|
|
40510
|
+
SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
|
|
40511
|
+
});
|
|
40512
|
+
|
|
40298
40513
|
// src/services/diagnose-service.ts
|
|
40299
40514
|
import * as child_process4 from "child_process";
|
|
40300
|
-
import { existsSync as
|
|
40301
|
-
import
|
|
40515
|
+
import { existsSync as existsSync15, readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync7 } from "fs";
|
|
40516
|
+
import path24 from "path";
|
|
40302
40517
|
import { fileURLToPath } from "url";
|
|
40303
40518
|
function validateTaskDag(plan) {
|
|
40304
40519
|
const allTaskIds = new Set;
|
|
@@ -40545,7 +40760,7 @@ async function checkConfigBackups(directory) {
|
|
|
40545
40760
|
}
|
|
40546
40761
|
async function checkGitRepository(directory) {
|
|
40547
40762
|
try {
|
|
40548
|
-
if (!
|
|
40763
|
+
if (!existsSync15(directory) || !statSync7(directory).isDirectory()) {
|
|
40549
40764
|
return {
|
|
40550
40765
|
name: "Git Repository",
|
|
40551
40766
|
status: "\u274C",
|
|
@@ -40609,8 +40824,8 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
40609
40824
|
};
|
|
40610
40825
|
}
|
|
40611
40826
|
async function checkConfigParseability(directory) {
|
|
40612
|
-
const configPath =
|
|
40613
|
-
if (!
|
|
40827
|
+
const configPath = path24.join(directory, ".opencode/opencode-swarm.json");
|
|
40828
|
+
if (!existsSync15(configPath)) {
|
|
40614
40829
|
return {
|
|
40615
40830
|
name: "Config Parseability",
|
|
40616
40831
|
status: "\u2705",
|
|
@@ -40638,7 +40853,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
40638
40853
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
40639
40854
|
const isSource = normalized.endsWith("/src/services");
|
|
40640
40855
|
const isCliBundle = normalized.endsWith("/cli");
|
|
40641
|
-
return isSource || isCliBundle ?
|
|
40856
|
+
return isSource || isCliBundle ? path24.join(thisDir, "..", "lang", "grammars") : path24.join(thisDir, "lang", "grammars");
|
|
40642
40857
|
}
|
|
40643
40858
|
async function checkGrammarWasmFiles() {
|
|
40644
40859
|
const grammarFiles = [
|
|
@@ -40662,14 +40877,14 @@ async function checkGrammarWasmFiles() {
|
|
|
40662
40877
|
"tree-sitter-ini.wasm",
|
|
40663
40878
|
"tree-sitter-regex.wasm"
|
|
40664
40879
|
];
|
|
40665
|
-
const thisDir =
|
|
40880
|
+
const thisDir = path24.dirname(fileURLToPath(import.meta.url));
|
|
40666
40881
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
40667
40882
|
const missing = [];
|
|
40668
|
-
if (!
|
|
40883
|
+
if (!existsSync15(path24.join(grammarDir, "tree-sitter.wasm"))) {
|
|
40669
40884
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
40670
40885
|
}
|
|
40671
40886
|
for (const file3 of grammarFiles) {
|
|
40672
|
-
if (!
|
|
40887
|
+
if (!existsSync15(path24.join(grammarDir, file3))) {
|
|
40673
40888
|
missing.push(file3);
|
|
40674
40889
|
}
|
|
40675
40890
|
}
|
|
@@ -40687,8 +40902,8 @@ async function checkGrammarWasmFiles() {
|
|
|
40687
40902
|
};
|
|
40688
40903
|
}
|
|
40689
40904
|
async function checkCheckpointManifest(directory) {
|
|
40690
|
-
const manifestPath =
|
|
40691
|
-
if (!
|
|
40905
|
+
const manifestPath = path24.join(directory, ".swarm/checkpoints.json");
|
|
40906
|
+
if (!existsSync15(manifestPath)) {
|
|
40692
40907
|
return {
|
|
40693
40908
|
name: "Checkpoint Manifest",
|
|
40694
40909
|
status: "\u2705",
|
|
@@ -40739,8 +40954,8 @@ async function checkCheckpointManifest(directory) {
|
|
|
40739
40954
|
}
|
|
40740
40955
|
}
|
|
40741
40956
|
async function checkEventStreamIntegrity(directory) {
|
|
40742
|
-
const eventsPath =
|
|
40743
|
-
if (!
|
|
40957
|
+
const eventsPath = path24.join(directory, ".swarm/events.jsonl");
|
|
40958
|
+
if (!existsSync15(eventsPath)) {
|
|
40744
40959
|
return {
|
|
40745
40960
|
name: "Event Stream",
|
|
40746
40961
|
status: "\u2705",
|
|
@@ -40780,8 +40995,8 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
40780
40995
|
}
|
|
40781
40996
|
}
|
|
40782
40997
|
async function checkSteeringDirectives(directory) {
|
|
40783
|
-
const eventsPath =
|
|
40784
|
-
if (!
|
|
40998
|
+
const eventsPath = path24.join(directory, ".swarm/events.jsonl");
|
|
40999
|
+
if (!existsSync15(eventsPath)) {
|
|
40785
41000
|
return {
|
|
40786
41001
|
name: "Steering Directives",
|
|
40787
41002
|
status: "\u2705",
|
|
@@ -40836,8 +41051,8 @@ async function checkCurator(directory) {
|
|
|
40836
41051
|
detail: "Disabled (enable via curator.enabled)"
|
|
40837
41052
|
};
|
|
40838
41053
|
}
|
|
40839
|
-
const summaryPath =
|
|
40840
|
-
if (!
|
|
41054
|
+
const summaryPath = path24.join(directory, ".swarm/curator-summary.json");
|
|
41055
|
+
if (!existsSync15(summaryPath)) {
|
|
40841
41056
|
return {
|
|
40842
41057
|
name: "Curator",
|
|
40843
41058
|
status: "\u2705",
|
|
@@ -40881,16 +41096,16 @@ async function checkCurator(directory) {
|
|
|
40881
41096
|
async function getDiagnoseData(directory) {
|
|
40882
41097
|
const checks5 = [];
|
|
40883
41098
|
const versionCache = readVersionCache();
|
|
40884
|
-
let versionDetail =
|
|
41099
|
+
let versionDetail = version4;
|
|
40885
41100
|
let versionStatus = "\u2705";
|
|
40886
41101
|
if (versionCache?.npmLatest) {
|
|
40887
41102
|
const ageMs = Date.now() - versionCache.checkedAt;
|
|
40888
41103
|
const ageMin = Math.max(0, Math.round(ageMs / 60000));
|
|
40889
|
-
if (compareVersions(versionCache.npmLatest,
|
|
41104
|
+
if (compareVersions(versionCache.npmLatest, version4) > 0) {
|
|
40890
41105
|
versionStatus = "\u26A0\uFE0F";
|
|
40891
|
-
versionDetail = `${
|
|
41106
|
+
versionDetail = `${version4} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago) ` + "\u2014 run `bunx opencode-swarm update` to refresh";
|
|
40892
41107
|
} else {
|
|
40893
|
-
versionDetail = `${
|
|
41108
|
+
versionDetail = `${version4} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago)`;
|
|
40894
41109
|
}
|
|
40895
41110
|
}
|
|
40896
41111
|
checks5.push({
|
|
@@ -41001,9 +41216,10 @@ async function getDiagnoseData(directory) {
|
|
|
41001
41216
|
checks5.push(await checkEventStreamIntegrity(directory));
|
|
41002
41217
|
checks5.push(await checkSteeringDirectives(directory));
|
|
41003
41218
|
checks5.push(await checkCurator(directory));
|
|
41219
|
+
checks5.push(await checkKnowledgeHealth(directory));
|
|
41004
41220
|
try {
|
|
41005
|
-
const evidenceDir =
|
|
41006
|
-
const snapshotFiles =
|
|
41221
|
+
const evidenceDir = path24.join(directory, ".swarm", "evidence");
|
|
41222
|
+
const snapshotFiles = existsSync15(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
41007
41223
|
if (snapshotFiles.length > 0) {
|
|
41008
41224
|
const latest = snapshotFiles.sort().pop();
|
|
41009
41225
|
checks5.push({
|
|
@@ -41036,11 +41252,11 @@ async function getDiagnoseData(directory) {
|
|
|
41036
41252
|
const cacheRows = [];
|
|
41037
41253
|
for (const cachePath of cachePaths) {
|
|
41038
41254
|
try {
|
|
41039
|
-
if (!
|
|
41255
|
+
if (!existsSync15(cachePath)) {
|
|
41040
41256
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
41041
41257
|
continue;
|
|
41042
41258
|
}
|
|
41043
|
-
const pkgJsonPath =
|
|
41259
|
+
const pkgJsonPath = path24.join(cachePath, "package.json");
|
|
41044
41260
|
try {
|
|
41045
41261
|
const raw = readFileSync9(pkgJsonPath, "utf-8");
|
|
41046
41262
|
const parsed = JSON.parse(raw);
|
|
@@ -41055,10 +41271,10 @@ async function getDiagnoseData(directory) {
|
|
|
41055
41271
|
}
|
|
41056
41272
|
const hasCacheEntry = cacheRows.some((r) => r.startsWith("\u2705"));
|
|
41057
41273
|
const hasCacheWarning = cacheRows.some((r) => r.startsWith("\u26A0\uFE0F"));
|
|
41058
|
-
const
|
|
41274
|
+
const cacheStatus2 = hasCacheWarning ? "\u26A0\uFE0F" : hasCacheEntry ? "\u2705" : "\u2B1C";
|
|
41059
41275
|
checks5.push({
|
|
41060
41276
|
name: "Plugin Caches",
|
|
41061
|
-
status:
|
|
41277
|
+
status: cacheStatus2,
|
|
41062
41278
|
detail: cacheRows.join(" | ")
|
|
41063
41279
|
});
|
|
41064
41280
|
const passCount = checks5.filter((c) => c.status === "\u2705" || c.status === "\u2B1C").length;
|
|
@@ -41094,7 +41310,7 @@ async function handleDiagnoseCommand(directory, _args) {
|
|
|
41094
41310
|
const diagnoseData = await getDiagnoseData(directory);
|
|
41095
41311
|
return formatDiagnoseMarkdown(diagnoseData);
|
|
41096
41312
|
}
|
|
41097
|
-
var
|
|
41313
|
+
var version4;
|
|
41098
41314
|
var init_diagnose_service = __esm(() => {
|
|
41099
41315
|
init_package();
|
|
41100
41316
|
init_cache_paths();
|
|
@@ -41103,9 +41319,10 @@ var init_diagnose_service = __esm(() => {
|
|
|
41103
41319
|
init_manager2();
|
|
41104
41320
|
init_utils2();
|
|
41105
41321
|
init_manager();
|
|
41322
|
+
init_knowledge_diagnostics();
|
|
41106
41323
|
init_version_check();
|
|
41107
41324
|
init_warning_buffer();
|
|
41108
|
-
({ version:
|
|
41325
|
+
({ version: version4 } = package_default);
|
|
41109
41326
|
});
|
|
41110
41327
|
|
|
41111
41328
|
// src/commands/diagnose.ts
|
|
@@ -41131,13 +41348,13 @@ __export(exports_config_doctor, {
|
|
|
41131
41348
|
import * as crypto4 from "crypto";
|
|
41132
41349
|
import * as fs9 from "fs";
|
|
41133
41350
|
import * as os6 from "os";
|
|
41134
|
-
import * as
|
|
41351
|
+
import * as path25 from "path";
|
|
41135
41352
|
function getUserConfigDir3() {
|
|
41136
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
41353
|
+
return process.env.XDG_CONFIG_HOME || path25.join(os6.homedir(), ".config");
|
|
41137
41354
|
}
|
|
41138
41355
|
function getConfigPaths(directory) {
|
|
41139
|
-
const userConfigPath =
|
|
41140
|
-
const projectConfigPath =
|
|
41356
|
+
const userConfigPath = path25.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
41357
|
+
const projectConfigPath = path25.join(directory, ".opencode", "opencode-swarm.json");
|
|
41141
41358
|
return { userConfigPath, projectConfigPath };
|
|
41142
41359
|
}
|
|
41143
41360
|
function computeHash(content) {
|
|
@@ -41162,9 +41379,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
41162
41379
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
41163
41380
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
41164
41381
|
try {
|
|
41165
|
-
const resolvedConfig =
|
|
41166
|
-
const resolvedUser =
|
|
41167
|
-
const resolvedProject =
|
|
41382
|
+
const resolvedConfig = path25.resolve(configPath);
|
|
41383
|
+
const resolvedUser = path25.resolve(normalizedUser);
|
|
41384
|
+
const resolvedProject = path25.resolve(normalizedProject);
|
|
41168
41385
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
41169
41386
|
} catch {
|
|
41170
41387
|
return false;
|
|
@@ -41204,12 +41421,12 @@ function createConfigBackup(directory) {
|
|
|
41204
41421
|
};
|
|
41205
41422
|
}
|
|
41206
41423
|
function writeBackupArtifact(directory, backup) {
|
|
41207
|
-
const swarmDir =
|
|
41424
|
+
const swarmDir = path25.join(directory, ".swarm");
|
|
41208
41425
|
if (!fs9.existsSync(swarmDir)) {
|
|
41209
41426
|
fs9.mkdirSync(swarmDir, { recursive: true });
|
|
41210
41427
|
}
|
|
41211
41428
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
41212
|
-
const backupPath =
|
|
41429
|
+
const backupPath = path25.join(swarmDir, backupFilename);
|
|
41213
41430
|
const artifact = {
|
|
41214
41431
|
createdAt: backup.createdAt,
|
|
41215
41432
|
configPath: backup.configPath,
|
|
@@ -41239,7 +41456,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
41239
41456
|
return null;
|
|
41240
41457
|
}
|
|
41241
41458
|
const targetPath = artifact.configPath;
|
|
41242
|
-
const targetDir =
|
|
41459
|
+
const targetDir = path25.dirname(targetPath);
|
|
41243
41460
|
if (!fs9.existsSync(targetDir)) {
|
|
41244
41461
|
fs9.mkdirSync(targetDir, { recursive: true });
|
|
41245
41462
|
}
|
|
@@ -41270,9 +41487,9 @@ function readConfigFromFile(directory) {
|
|
|
41270
41487
|
return null;
|
|
41271
41488
|
}
|
|
41272
41489
|
}
|
|
41273
|
-
function validateConfigKey(
|
|
41490
|
+
function validateConfigKey(path26, value, _config) {
|
|
41274
41491
|
const findings = [];
|
|
41275
|
-
switch (
|
|
41492
|
+
switch (path26) {
|
|
41276
41493
|
case "agents": {
|
|
41277
41494
|
if (value !== undefined) {
|
|
41278
41495
|
findings.push({
|
|
@@ -41509,27 +41726,27 @@ function validateConfigKey(path25, value, _config) {
|
|
|
41509
41726
|
}
|
|
41510
41727
|
return findings;
|
|
41511
41728
|
}
|
|
41512
|
-
function walkConfigAndValidate(obj,
|
|
41729
|
+
function walkConfigAndValidate(obj, path26, config3, findings) {
|
|
41513
41730
|
if (obj === null || obj === undefined) {
|
|
41514
41731
|
return;
|
|
41515
41732
|
}
|
|
41516
|
-
if (
|
|
41517
|
-
const keyFindings = validateConfigKey(
|
|
41733
|
+
if (path26 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
41734
|
+
const keyFindings = validateConfigKey(path26, obj, config3);
|
|
41518
41735
|
findings.push(...keyFindings);
|
|
41519
41736
|
}
|
|
41520
41737
|
if (typeof obj !== "object") {
|
|
41521
|
-
const keyFindings = validateConfigKey(
|
|
41738
|
+
const keyFindings = validateConfigKey(path26, obj, config3);
|
|
41522
41739
|
findings.push(...keyFindings);
|
|
41523
41740
|
return;
|
|
41524
41741
|
}
|
|
41525
41742
|
if (Array.isArray(obj)) {
|
|
41526
41743
|
obj.forEach((item, index) => {
|
|
41527
|
-
walkConfigAndValidate(item, `${
|
|
41744
|
+
walkConfigAndValidate(item, `${path26}[${index}]`, config3, findings);
|
|
41528
41745
|
});
|
|
41529
41746
|
return;
|
|
41530
41747
|
}
|
|
41531
41748
|
for (const [key, value] of Object.entries(obj)) {
|
|
41532
|
-
const newPath =
|
|
41749
|
+
const newPath = path26 ? `${path26}.${key}` : key;
|
|
41533
41750
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
41534
41751
|
}
|
|
41535
41752
|
}
|
|
@@ -41649,7 +41866,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
41649
41866
|
}
|
|
41650
41867
|
}
|
|
41651
41868
|
if (appliedFixes.length > 0) {
|
|
41652
|
-
const configDir =
|
|
41869
|
+
const configDir = path25.dirname(configPath);
|
|
41653
41870
|
if (!fs9.existsSync(configDir)) {
|
|
41654
41871
|
fs9.mkdirSync(configDir, { recursive: true });
|
|
41655
41872
|
}
|
|
@@ -41659,12 +41876,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
41659
41876
|
return { appliedFixes, updatedConfigPath };
|
|
41660
41877
|
}
|
|
41661
41878
|
function writeDoctorArtifact(directory, result) {
|
|
41662
|
-
const swarmDir =
|
|
41879
|
+
const swarmDir = path25.join(directory, ".swarm");
|
|
41663
41880
|
if (!fs9.existsSync(swarmDir)) {
|
|
41664
41881
|
fs9.mkdirSync(swarmDir, { recursive: true });
|
|
41665
41882
|
}
|
|
41666
41883
|
const artifactFilename = "config-doctor.json";
|
|
41667
|
-
const artifactPath =
|
|
41884
|
+
const artifactPath = path25.join(swarmDir, artifactFilename);
|
|
41668
41885
|
const guiOutput = {
|
|
41669
41886
|
timestamp: result.timestamp,
|
|
41670
41887
|
summary: result.summary,
|
|
@@ -41760,17 +41977,17 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
41760
41977
|
if (!entry.isDirectory())
|
|
41761
41978
|
continue;
|
|
41762
41979
|
const name = entry.name;
|
|
41763
|
-
const fullPath =
|
|
41980
|
+
const fullPath = path25.join(dir, name);
|
|
41764
41981
|
if (SKIP_DIRS.has(name))
|
|
41765
41982
|
continue;
|
|
41766
|
-
const gitPath =
|
|
41983
|
+
const gitPath = path25.join(fullPath, ".git");
|
|
41767
41984
|
try {
|
|
41768
41985
|
const gitStat = fs9.statSync(gitPath);
|
|
41769
41986
|
if (gitStat.isFile() || gitStat.isDirectory())
|
|
41770
41987
|
continue;
|
|
41771
41988
|
} catch {}
|
|
41772
41989
|
if (name === ".swarm") {
|
|
41773
|
-
const parentDir =
|
|
41990
|
+
const parentDir = path25.dirname(fullPath);
|
|
41774
41991
|
if (parentDir === projectRoot)
|
|
41775
41992
|
continue;
|
|
41776
41993
|
let contents = [];
|
|
@@ -41780,7 +41997,7 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
41780
41997
|
contents = ["<unreadable>"];
|
|
41781
41998
|
}
|
|
41782
41999
|
findings.push({
|
|
41783
|
-
path:
|
|
42000
|
+
path: path25.relative(projectRoot, fullPath).replace(/\\/g, "/"),
|
|
41784
42001
|
absolutePath: fullPath,
|
|
41785
42002
|
contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
|
|
41786
42003
|
totalEntries: contents.length
|
|
@@ -41798,21 +42015,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
|
|
|
41798
42015
|
let canonicalStray;
|
|
41799
42016
|
try {
|
|
41800
42017
|
canonicalRoot = fs9.realpathSync(projectRoot);
|
|
41801
|
-
canonicalStray = fs9.realpathSync(
|
|
42018
|
+
canonicalStray = fs9.realpathSync(path25.isAbsolute(strayPath) ? strayPath : path25.resolve(projectRoot, strayPath));
|
|
41802
42019
|
} catch (err) {
|
|
41803
42020
|
return {
|
|
41804
42021
|
success: false,
|
|
41805
42022
|
message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
|
|
41806
42023
|
};
|
|
41807
42024
|
}
|
|
41808
|
-
const rootSwarm =
|
|
42025
|
+
const rootSwarm = path25.join(canonicalRoot, ".swarm");
|
|
41809
42026
|
if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
|
|
41810
42027
|
return {
|
|
41811
42028
|
success: false,
|
|
41812
42029
|
message: "Refusing to remove root .swarm/ directory"
|
|
41813
42030
|
};
|
|
41814
42031
|
}
|
|
41815
|
-
if (!canonicalStray.startsWith(canonicalRoot +
|
|
42032
|
+
if (!canonicalStray.startsWith(canonicalRoot + path25.sep)) {
|
|
41816
42033
|
return {
|
|
41817
42034
|
success: false,
|
|
41818
42035
|
message: "Path is outside project root \u2014 refusing to remove"
|
|
@@ -42901,7 +43118,7 @@ var init_profiles = __esm(() => {
|
|
|
42901
43118
|
|
|
42902
43119
|
// src/lang/detector.ts
|
|
42903
43120
|
import { access as access3, readdir as readdir2 } from "fs/promises";
|
|
42904
|
-
import { extname as extname2, join as
|
|
43121
|
+
import { extname as extname2, join as join24 } from "path";
|
|
42905
43122
|
async function detectProjectLanguages(projectDir) {
|
|
42906
43123
|
const detected = new Set;
|
|
42907
43124
|
async function scanDir(dir) {
|
|
@@ -42917,7 +43134,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
42917
43134
|
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
42918
43135
|
continue;
|
|
42919
43136
|
try {
|
|
42920
|
-
await access3(
|
|
43137
|
+
await access3(join24(dir, detectFile));
|
|
42921
43138
|
detected.add(profile.id);
|
|
42922
43139
|
break;
|
|
42923
43140
|
} catch {}
|
|
@@ -42938,7 +43155,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
42938
43155
|
const topEntries = await readdir2(projectDir, { withFileTypes: true });
|
|
42939
43156
|
for (const entry of topEntries) {
|
|
42940
43157
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
42941
|
-
await scanDir(
|
|
43158
|
+
await scanDir(join24(projectDir, entry.name));
|
|
42942
43159
|
}
|
|
42943
43160
|
}
|
|
42944
43161
|
} catch {}
|
|
@@ -42957,7 +43174,7 @@ var init_detector = __esm(() => {
|
|
|
42957
43174
|
|
|
42958
43175
|
// src/build/discovery.ts
|
|
42959
43176
|
import * as fs10 from "fs";
|
|
42960
|
-
import * as
|
|
43177
|
+
import * as path26 from "path";
|
|
42961
43178
|
function isCommandAvailable(command) {
|
|
42962
43179
|
if (toolchainCache.has(command)) {
|
|
42963
43180
|
return toolchainCache.get(command);
|
|
@@ -42992,11 +43209,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
42992
43209
|
const regex = simpleGlobToRegex(pattern);
|
|
42993
43210
|
const matches = files.filter((f) => regex.test(f));
|
|
42994
43211
|
if (matches.length > 0) {
|
|
42995
|
-
return
|
|
43212
|
+
return path26.join(dir, matches[0]);
|
|
42996
43213
|
}
|
|
42997
43214
|
} catch {}
|
|
42998
43215
|
} else {
|
|
42999
|
-
const filePath =
|
|
43216
|
+
const filePath = path26.join(workingDir, pattern);
|
|
43000
43217
|
if (fs10.existsSync(filePath)) {
|
|
43001
43218
|
return filePath;
|
|
43002
43219
|
}
|
|
@@ -43005,7 +43222,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
43005
43222
|
return null;
|
|
43006
43223
|
}
|
|
43007
43224
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
43008
|
-
const packageJsonPath =
|
|
43225
|
+
const packageJsonPath = path26.join(workingDir, "package.json");
|
|
43009
43226
|
if (!fs10.existsSync(packageJsonPath)) {
|
|
43010
43227
|
return [];
|
|
43011
43228
|
}
|
|
@@ -43046,7 +43263,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
43046
43263
|
const regex = simpleGlobToRegex(pattern);
|
|
43047
43264
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
43048
43265
|
} else {
|
|
43049
|
-
const filePath =
|
|
43266
|
+
const filePath = path26.join(workingDir, pattern);
|
|
43050
43267
|
if (fs10.existsSync(filePath)) {
|
|
43051
43268
|
allBuildFiles.add(filePath);
|
|
43052
43269
|
}
|
|
@@ -43059,7 +43276,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
43059
43276
|
try {
|
|
43060
43277
|
const entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
43061
43278
|
for (const entry of entries) {
|
|
43062
|
-
const fullPath =
|
|
43279
|
+
const fullPath = path26.join(dir, entry.name);
|
|
43063
43280
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
43064
43281
|
findFilesRecursive(fullPath, regex, results);
|
|
43065
43282
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -43082,7 +43299,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
43082
43299
|
let foundCommand = false;
|
|
43083
43300
|
for (const cmd of sortedCommands) {
|
|
43084
43301
|
if (cmd.detectFile) {
|
|
43085
|
-
const detectFilePath =
|
|
43302
|
+
const detectFilePath = path26.join(workingDir, cmd.detectFile);
|
|
43086
43303
|
if (!fs10.existsSync(detectFilePath)) {
|
|
43087
43304
|
continue;
|
|
43088
43305
|
}
|
|
@@ -43323,7 +43540,7 @@ var init_discovery = __esm(() => {
|
|
|
43323
43540
|
|
|
43324
43541
|
// src/services/tool-doctor.ts
|
|
43325
43542
|
import * as fs11 from "fs";
|
|
43326
|
-
import * as
|
|
43543
|
+
import * as path27 from "path";
|
|
43327
43544
|
function extractRegisteredToolKeys(indexPath) {
|
|
43328
43545
|
const registeredKeys = new Set;
|
|
43329
43546
|
try {
|
|
@@ -43378,8 +43595,8 @@ function checkBinaryReadiness() {
|
|
|
43378
43595
|
}
|
|
43379
43596
|
function runToolDoctor(_directory, pluginRoot) {
|
|
43380
43597
|
const findings = [];
|
|
43381
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
43382
|
-
const indexPath =
|
|
43598
|
+
const resolvedPluginRoot = pluginRoot ?? path27.resolve(import.meta.dir, "..", "..");
|
|
43599
|
+
const indexPath = path27.join(resolvedPluginRoot, "src", "index.ts");
|
|
43383
43600
|
if (!fs11.existsSync(indexPath)) {
|
|
43384
43601
|
return {
|
|
43385
43602
|
findings: [
|
|
@@ -44137,12 +44354,12 @@ var init_export = __esm(() => {
|
|
|
44137
44354
|
|
|
44138
44355
|
// src/full-auto/state.ts
|
|
44139
44356
|
import * as fs12 from "fs";
|
|
44140
|
-
import * as
|
|
44357
|
+
import * as path28 from "path";
|
|
44141
44358
|
function nowISO() {
|
|
44142
44359
|
return new Date().toISOString();
|
|
44143
44360
|
}
|
|
44144
44361
|
function ensureSwarmDir(directory) {
|
|
44145
|
-
const swarmDir =
|
|
44362
|
+
const swarmDir = path28.resolve(directory, ".swarm");
|
|
44146
44363
|
if (!fs12.existsSync(swarmDir)) {
|
|
44147
44364
|
fs12.mkdirSync(swarmDir, { recursive: true });
|
|
44148
44365
|
}
|
|
@@ -44843,7 +45060,7 @@ var init_handoff_service = __esm(() => {
|
|
|
44843
45060
|
|
|
44844
45061
|
// src/session/snapshot-writer.ts
|
|
44845
45062
|
import { closeSync as closeSync4, fsyncSync as fsyncSync2, mkdirSync as mkdirSync12, openSync as openSync4, renameSync as renameSync8 } from "fs";
|
|
44846
|
-
import * as
|
|
45063
|
+
import * as path29 from "path";
|
|
44847
45064
|
function serializeAgentSession(s) {
|
|
44848
45065
|
const gateLog = {};
|
|
44849
45066
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -44943,7 +45160,7 @@ async function writeSnapshot(directory, state) {
|
|
|
44943
45160
|
}
|
|
44944
45161
|
const content = JSON.stringify(snapshot, null, 2);
|
|
44945
45162
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
44946
|
-
const dir =
|
|
45163
|
+
const dir = path29.dirname(resolvedPath);
|
|
44947
45164
|
mkdirSync12(dir, { recursive: true });
|
|
44948
45165
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
44949
45166
|
await bunWrite(tempPath, content);
|
|
@@ -45403,9 +45620,9 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
45403
45620
|
|
|
45404
45621
|
// src/hooks/knowledge-migrator.ts
|
|
45405
45622
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
45406
|
-
import { existsSync as
|
|
45407
|
-
import { mkdir as
|
|
45408
|
-
import * as
|
|
45623
|
+
import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
|
|
45624
|
+
import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile8 } from "fs/promises";
|
|
45625
|
+
import * as path30 from "path";
|
|
45409
45626
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
45410
45627
|
return {
|
|
45411
45628
|
migrated: false,
|
|
@@ -45416,10 +45633,10 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
45416
45633
|
};
|
|
45417
45634
|
}
|
|
45418
45635
|
async function migrateContextToKnowledge(directory, config3) {
|
|
45419
|
-
const sentinelPath =
|
|
45420
|
-
const contextPath =
|
|
45636
|
+
const sentinelPath = path30.join(directory, ".swarm", ".knowledge-migrated");
|
|
45637
|
+
const contextPath = path30.join(directory, ".swarm", "context.md");
|
|
45421
45638
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
45422
|
-
if (
|
|
45639
|
+
if (existsSync20(sentinelPath)) {
|
|
45423
45640
|
return {
|
|
45424
45641
|
migrated: false,
|
|
45425
45642
|
entriesMigrated: 0,
|
|
@@ -45428,7 +45645,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
45428
45645
|
skippedReason: "sentinel-exists"
|
|
45429
45646
|
};
|
|
45430
45647
|
}
|
|
45431
|
-
if (!
|
|
45648
|
+
if (!existsSync20(contextPath)) {
|
|
45432
45649
|
return {
|
|
45433
45650
|
migrated: false,
|
|
45434
45651
|
entriesMigrated: 0,
|
|
@@ -45437,7 +45654,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
45437
45654
|
skippedReason: "no-context-file"
|
|
45438
45655
|
};
|
|
45439
45656
|
}
|
|
45440
|
-
const contextContent = await
|
|
45657
|
+
const contextContent = await readFile9(contextPath, "utf-8");
|
|
45441
45658
|
if (contextContent.trim().length === 0) {
|
|
45442
45659
|
return {
|
|
45443
45660
|
migrated: false,
|
|
@@ -45613,8 +45830,8 @@ function truncateLesson(text) {
|
|
|
45613
45830
|
return `${text.slice(0, 277)}...`;
|
|
45614
45831
|
}
|
|
45615
45832
|
function inferProjectName(directory) {
|
|
45616
|
-
const packageJsonPath =
|
|
45617
|
-
if (
|
|
45833
|
+
const packageJsonPath = path30.join(directory, "package.json");
|
|
45834
|
+
if (existsSync20(packageJsonPath)) {
|
|
45618
45835
|
try {
|
|
45619
45836
|
const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
|
|
45620
45837
|
if (pkg.name && typeof pkg.name === "string") {
|
|
@@ -45622,7 +45839,7 @@ function inferProjectName(directory) {
|
|
|
45622
45839
|
}
|
|
45623
45840
|
} catch {}
|
|
45624
45841
|
}
|
|
45625
|
-
return
|
|
45842
|
+
return path30.basename(directory);
|
|
45626
45843
|
}
|
|
45627
45844
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
45628
45845
|
const sentinel = {
|
|
@@ -45634,7 +45851,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
45634
45851
|
schema_version: 1,
|
|
45635
45852
|
migration_tool: "knowledge-migrator.ts"
|
|
45636
45853
|
};
|
|
45637
|
-
await
|
|
45854
|
+
await mkdir8(path30.dirname(sentinelPath), { recursive: true });
|
|
45638
45855
|
await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
45639
45856
|
}
|
|
45640
45857
|
var _internals19;
|
|
@@ -45656,7 +45873,7 @@ var init_knowledge_migrator = __esm(() => {
|
|
|
45656
45873
|
});
|
|
45657
45874
|
|
|
45658
45875
|
// src/commands/knowledge.ts
|
|
45659
|
-
import { join as
|
|
45876
|
+
import { join as join28 } from "path";
|
|
45660
45877
|
function resolveEntryByPrefix(entries, inputId) {
|
|
45661
45878
|
const exact = entries.find((e) => e.id === inputId);
|
|
45662
45879
|
if (exact)
|
|
@@ -45707,7 +45924,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
45707
45924
|
return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
|
|
45708
45925
|
}
|
|
45709
45926
|
try {
|
|
45710
|
-
const quarantinePath =
|
|
45927
|
+
const quarantinePath = join28(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
45711
45928
|
const entries = await readKnowledge(quarantinePath);
|
|
45712
45929
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
45713
45930
|
if ("error" in resolved) {
|
|
@@ -46682,15 +46899,15 @@ var init_scoring = __esm(() => {
|
|
|
46682
46899
|
|
|
46683
46900
|
// src/memory/local-jsonl-provider.ts
|
|
46684
46901
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
46685
|
-
import { existsSync as
|
|
46902
|
+
import { existsSync as existsSync21 } from "fs";
|
|
46686
46903
|
import {
|
|
46687
|
-
appendFile as
|
|
46688
|
-
mkdir as
|
|
46689
|
-
readFile as
|
|
46904
|
+
appendFile as appendFile5,
|
|
46905
|
+
mkdir as mkdir9,
|
|
46906
|
+
readFile as readFile10,
|
|
46690
46907
|
rename as rename6,
|
|
46691
46908
|
writeFile as writeFile9
|
|
46692
46909
|
} from "fs/promises";
|
|
46693
|
-
import * as
|
|
46910
|
+
import * as path31 from "path";
|
|
46694
46911
|
|
|
46695
46912
|
class LocalJsonlMemoryProvider {
|
|
46696
46913
|
name = "local-jsonl";
|
|
@@ -46706,7 +46923,7 @@ class LocalJsonlMemoryProvider {
|
|
|
46706
46923
|
pathFor(file3) {
|
|
46707
46924
|
const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
|
|
46708
46925
|
const filename = file3 === "memories" ? "memories.jsonl" : file3 === "proposals" ? "proposals.jsonl" : "audit.jsonl";
|
|
46709
|
-
return validateSwarmPath(this.rootDirectory,
|
|
46926
|
+
return validateSwarmPath(this.rootDirectory, path31.join(storageDir, filename));
|
|
46710
46927
|
}
|
|
46711
46928
|
async initialize() {
|
|
46712
46929
|
if (this.initialized)
|
|
@@ -47033,9 +47250,9 @@ function validateLoadedProposals(values, config3) {
|
|
|
47033
47250
|
return { records, invalidCount };
|
|
47034
47251
|
}
|
|
47035
47252
|
async function readJsonl(filePath) {
|
|
47036
|
-
if (!
|
|
47253
|
+
if (!existsSync21(filePath))
|
|
47037
47254
|
return [];
|
|
47038
|
-
const content = await
|
|
47255
|
+
const content = await readFile10(filePath, "utf-8");
|
|
47039
47256
|
const records = [];
|
|
47040
47257
|
for (const line of content.split(`
|
|
47041
47258
|
`)) {
|
|
@@ -47089,12 +47306,12 @@ function parseRecallUsageEvent(event) {
|
|
|
47089
47306
|
}
|
|
47090
47307
|
}
|
|
47091
47308
|
async function appendJsonl(filePath, value) {
|
|
47092
|
-
await
|
|
47093
|
-
await
|
|
47309
|
+
await mkdir9(path31.dirname(filePath), { recursive: true });
|
|
47310
|
+
await appendFile5(filePath, `${JSON.stringify(value)}
|
|
47094
47311
|
`, "utf-8");
|
|
47095
47312
|
}
|
|
47096
47313
|
async function writeJsonlAtomic(filePath, values) {
|
|
47097
|
-
await
|
|
47314
|
+
await mkdir9(path31.dirname(filePath), { recursive: true });
|
|
47098
47315
|
const tmp = `${filePath}.tmp.${randomUUID4()}`;
|
|
47099
47316
|
const content = values.map((value) => JSON.stringify(value)).join(`
|
|
47100
47317
|
`) + (values.length > 0 ? `
|
|
@@ -47119,9 +47336,9 @@ var init_prompt_block = __esm(() => {
|
|
|
47119
47336
|
});
|
|
47120
47337
|
|
|
47121
47338
|
// src/memory/jsonl-migration.ts
|
|
47122
|
-
import { existsSync as
|
|
47123
|
-
import { copyFile, mkdir as
|
|
47124
|
-
import * as
|
|
47339
|
+
import { existsSync as existsSync22 } from "fs";
|
|
47340
|
+
import { copyFile, mkdir as mkdir10, readFile as readFile11, stat as stat3, writeFile as writeFile10 } from "fs/promises";
|
|
47341
|
+
import * as path32 from "path";
|
|
47125
47342
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
47126
47343
|
const resolved = resolveConfig(config3);
|
|
47127
47344
|
const storageDir = resolved.storageDir.replace(/^\.swarm[/\\]?/, "");
|
|
@@ -47135,8 +47352,8 @@ function resolveSqliteDatabasePath(rootDirectory, config3 = {}) {
|
|
|
47135
47352
|
async function readLegacyJsonl(rootDirectory, config3 = {}) {
|
|
47136
47353
|
const resolved = resolveConfig(config3);
|
|
47137
47354
|
const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
|
|
47138
|
-
const memoryLoad = await readMemoryJsonl(
|
|
47139
|
-
const proposalLoad = await readProposalJsonl(
|
|
47355
|
+
const memoryLoad = await readMemoryJsonl(path32.join(storageDir, "memories.jsonl"), resolved);
|
|
47356
|
+
const proposalLoad = await readProposalJsonl(path32.join(storageDir, "proposals.jsonl"), resolved);
|
|
47140
47357
|
return {
|
|
47141
47358
|
memories: memoryLoad.records,
|
|
47142
47359
|
proposals: proposalLoad.records,
|
|
@@ -47146,15 +47363,15 @@ async function readLegacyJsonl(rootDirectory, config3 = {}) {
|
|
|
47146
47363
|
}
|
|
47147
47364
|
async function backupLegacyJsonl(rootDirectory, config3 = {}) {
|
|
47148
47365
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
|
|
47149
|
-
const backupDir =
|
|
47150
|
-
await
|
|
47366
|
+
const backupDir = path32.join(storageDir, "backups");
|
|
47367
|
+
await mkdir10(backupDir, { recursive: true });
|
|
47151
47368
|
const results = [];
|
|
47152
47369
|
for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
|
|
47153
|
-
const source =
|
|
47154
|
-
if (!
|
|
47370
|
+
const source = path32.join(storageDir, filename);
|
|
47371
|
+
if (!existsSync22(source))
|
|
47155
47372
|
continue;
|
|
47156
|
-
const backup =
|
|
47157
|
-
if (
|
|
47373
|
+
const backup = path32.join(backupDir, `${filename}.pre-sqlite-migration`);
|
|
47374
|
+
if (existsSync22(backup)) {
|
|
47158
47375
|
results.push({ source, backup, created: false });
|
|
47159
47376
|
continue;
|
|
47160
47377
|
}
|
|
@@ -47164,27 +47381,27 @@ async function backupLegacyJsonl(rootDirectory, config3 = {}) {
|
|
|
47164
47381
|
return results;
|
|
47165
47382
|
}
|
|
47166
47383
|
async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
|
|
47167
|
-
const exportDir =
|
|
47168
|
-
await
|
|
47169
|
-
const memoriesPath =
|
|
47170
|
-
const proposalsPath =
|
|
47384
|
+
const exportDir = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "export");
|
|
47385
|
+
await mkdir10(exportDir, { recursive: true });
|
|
47386
|
+
const memoriesPath = path32.join(exportDir, "memories.jsonl");
|
|
47387
|
+
const proposalsPath = path32.join(exportDir, "proposals.jsonl");
|
|
47171
47388
|
await writeFile10(memoriesPath, toJsonl(memories), "utf-8");
|
|
47172
47389
|
await writeFile10(proposalsPath, toJsonl(proposals), "utf-8");
|
|
47173
47390
|
return { directory: exportDir, memoriesPath, proposalsPath };
|
|
47174
47391
|
}
|
|
47175
47392
|
async function writeMigrationReport(rootDirectory, report, config3 = {}) {
|
|
47176
|
-
const reportPath =
|
|
47177
|
-
await
|
|
47393
|
+
const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
47394
|
+
await mkdir10(path32.dirname(reportPath), { recursive: true });
|
|
47178
47395
|
await writeFile10(reportPath, `${JSON.stringify(report, null, 2)}
|
|
47179
47396
|
`, "utf-8");
|
|
47180
47397
|
return reportPath;
|
|
47181
47398
|
}
|
|
47182
47399
|
async function readMigrationReport(rootDirectory, config3 = {}) {
|
|
47183
|
-
const reportPath =
|
|
47184
|
-
if (!
|
|
47400
|
+
const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
47401
|
+
if (!existsSync22(reportPath))
|
|
47185
47402
|
return null;
|
|
47186
47403
|
try {
|
|
47187
|
-
return JSON.parse(await
|
|
47404
|
+
return JSON.parse(await readFile11(reportPath, "utf-8"));
|
|
47188
47405
|
} catch {
|
|
47189
47406
|
return null;
|
|
47190
47407
|
}
|
|
@@ -47193,15 +47410,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
|
|
|
47193
47410
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
|
|
47194
47411
|
const statuses = [];
|
|
47195
47412
|
for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
|
|
47196
|
-
const filePath =
|
|
47413
|
+
const filePath = path32.join(storageDir, file3);
|
|
47197
47414
|
let sizeBytes = 0;
|
|
47198
|
-
if (
|
|
47415
|
+
if (existsSync22(filePath)) {
|
|
47199
47416
|
sizeBytes = (await stat3(filePath)).size;
|
|
47200
47417
|
}
|
|
47201
47418
|
statuses.push({
|
|
47202
47419
|
file: file3,
|
|
47203
47420
|
path: filePath,
|
|
47204
|
-
exists:
|
|
47421
|
+
exists: existsSync22(filePath),
|
|
47205
47422
|
sizeBytes
|
|
47206
47423
|
});
|
|
47207
47424
|
}
|
|
@@ -47282,10 +47499,10 @@ async function readProposalJsonl(filePath, config3) {
|
|
|
47282
47499
|
return { records, invalidRows, totalRows: rows.totalRows };
|
|
47283
47500
|
}
|
|
47284
47501
|
async function readJsonlRows(filePath) {
|
|
47285
|
-
if (!
|
|
47502
|
+
if (!existsSync22(filePath)) {
|
|
47286
47503
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
47287
47504
|
}
|
|
47288
|
-
const content = await
|
|
47505
|
+
const content = await readFile11(filePath, "utf-8");
|
|
47289
47506
|
const rows = [];
|
|
47290
47507
|
const invalidRows = [];
|
|
47291
47508
|
let totalRows = 0;
|
|
@@ -47322,7 +47539,7 @@ var init_jsonl_migration = __esm(() => {
|
|
|
47322
47539
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
47323
47540
|
import { mkdirSync as mkdirSync13 } from "fs";
|
|
47324
47541
|
import { createRequire as createRequire2 } from "module";
|
|
47325
|
-
import * as
|
|
47542
|
+
import * as path33 from "path";
|
|
47326
47543
|
function loadDatabaseCtor2() {
|
|
47327
47544
|
if (_DatabaseCtor2)
|
|
47328
47545
|
return _DatabaseCtor2;
|
|
@@ -47380,7 +47597,7 @@ class SQLiteMemoryProvider {
|
|
|
47380
47597
|
if (this.initialized)
|
|
47381
47598
|
return;
|
|
47382
47599
|
const dbPath = this.databasePath();
|
|
47383
|
-
mkdirSync13(
|
|
47600
|
+
mkdirSync13(path33.dirname(dbPath), { recursive: true });
|
|
47384
47601
|
const Db = loadDatabaseCtor2();
|
|
47385
47602
|
this.db = new Db(dbPath);
|
|
47386
47603
|
this.db.run("PRAGMA journal_mode = WAL;");
|
|
@@ -47645,8 +47862,8 @@ class SQLiteMemoryProvider {
|
|
|
47645
47862
|
const row = this.requireDb().query("SELECT version, name FROM schema_migrations WHERE name = ? LIMIT 1").get(name);
|
|
47646
47863
|
return Boolean(row);
|
|
47647
47864
|
}
|
|
47648
|
-
markMigration(
|
|
47649
|
-
this.requireDb().run("INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (?, ?)", [
|
|
47865
|
+
markMigration(version5, name) {
|
|
47866
|
+
this.requireDb().run("INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (?, ?)", [version5, name]);
|
|
47650
47867
|
}
|
|
47651
47868
|
selectRecallCandidates(request, scopedRecords) {
|
|
47652
47869
|
const ftsQuery = buildFtsQuery(request);
|
|
@@ -48266,9 +48483,9 @@ var init_gateway = __esm(() => {
|
|
|
48266
48483
|
// src/memory/evaluation.ts
|
|
48267
48484
|
import * as fs13 from "fs/promises";
|
|
48268
48485
|
import * as os7 from "os";
|
|
48269
|
-
import * as
|
|
48486
|
+
import * as path34 from "path";
|
|
48270
48487
|
async function evaluateMemoryRecallFixtures(options) {
|
|
48271
|
-
const fixtureDirectory =
|
|
48488
|
+
const fixtureDirectory = path34.resolve(options.fixtureDirectory);
|
|
48272
48489
|
const providers = options.providers ?? DEFAULT_PROVIDERS;
|
|
48273
48490
|
const modes = options.modes ?? DEFAULT_MODES;
|
|
48274
48491
|
const generatedAt = new Date().toISOString();
|
|
@@ -48277,7 +48494,7 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
48277
48494
|
for (const fixture of fixtures) {
|
|
48278
48495
|
const materialized = materializeFixture(fixture);
|
|
48279
48496
|
for (const providerName of providers) {
|
|
48280
|
-
const tempRoot = await fs13.realpath(await fs13.mkdtemp(
|
|
48497
|
+
const tempRoot = await fs13.realpath(await fs13.mkdtemp(path34.join(os7.tmpdir(), "swarm-memory-eval-")));
|
|
48281
48498
|
const provider = createEvaluationProvider(providerName, tempRoot);
|
|
48282
48499
|
try {
|
|
48283
48500
|
await provider.initialize?.();
|
|
@@ -48321,7 +48538,7 @@ async function loadRecallEvaluationFixtures(fixtureDirectory) {
|
|
|
48321
48538
|
const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
48322
48539
|
const fixtures = [];
|
|
48323
48540
|
for (const file3 of files) {
|
|
48324
|
-
const raw = await fs13.readFile(
|
|
48541
|
+
const raw = await fs13.readFile(path34.join(fixtureDirectory, file3), "utf-8");
|
|
48325
48542
|
fixtures.push(validateFixture(JSON.parse(raw), file3));
|
|
48326
48543
|
}
|
|
48327
48544
|
return fixtures;
|
|
@@ -48659,8 +48876,8 @@ var init_memory = __esm(() => {
|
|
|
48659
48876
|
});
|
|
48660
48877
|
|
|
48661
48878
|
// src/commands/memory.ts
|
|
48662
|
-
import { existsSync as
|
|
48663
|
-
import * as
|
|
48879
|
+
import { existsSync as existsSync23 } from "fs";
|
|
48880
|
+
import * as path35 from "path";
|
|
48664
48881
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
48665
48882
|
async function handleMemoryCommand(_directory, _args) {
|
|
48666
48883
|
return [
|
|
@@ -48691,7 +48908,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
48691
48908
|
`- Provider: \`${config3.provider}\``,
|
|
48692
48909
|
`- Storage: \`${storageDir}\``,
|
|
48693
48910
|
`- SQLite path: \`${sqlitePath}\``,
|
|
48694
|
-
`- SQLite database exists: \`${
|
|
48911
|
+
`- SQLite database exists: \`${existsSync23(sqlitePath)}\``,
|
|
48695
48912
|
`- Automatic destructive cleanup: \`disabled\``,
|
|
48696
48913
|
"",
|
|
48697
48914
|
"### Legacy JSONL"
|
|
@@ -48930,7 +49147,7 @@ function resolveCommandMemoryConfig(directory) {
|
|
|
48930
49147
|
}
|
|
48931
49148
|
function parseEvaluateArgs(directory, args) {
|
|
48932
49149
|
let json3 = false;
|
|
48933
|
-
let fixtureDirectory =
|
|
49150
|
+
let fixtureDirectory = path35.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
|
|
48934
49151
|
for (let i = 0;i < args.length; i++) {
|
|
48935
49152
|
const arg = args[i];
|
|
48936
49153
|
if (arg === "--json") {
|
|
@@ -48944,7 +49161,7 @@ function parseEvaluateArgs(directory, args) {
|
|
|
48944
49161
|
error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
|
|
48945
49162
|
};
|
|
48946
49163
|
}
|
|
48947
|
-
fixtureDirectory =
|
|
49164
|
+
fixtureDirectory = path35.resolve(directory, next);
|
|
48948
49165
|
i++;
|
|
48949
49166
|
continue;
|
|
48950
49167
|
}
|
|
@@ -48977,15 +49194,15 @@ function parseMaintenanceArgs(args, options) {
|
|
|
48977
49194
|
return { limit, confirm };
|
|
48978
49195
|
}
|
|
48979
49196
|
function resolvePackageRootFromModule(modulePath) {
|
|
48980
|
-
const moduleDir =
|
|
48981
|
-
const leaf =
|
|
49197
|
+
const moduleDir = path35.dirname(modulePath);
|
|
49198
|
+
const leaf = path35.basename(moduleDir);
|
|
48982
49199
|
if (leaf === "commands" || leaf === "cli") {
|
|
48983
|
-
return
|
|
49200
|
+
return path35.resolve(moduleDir, "..", "..");
|
|
48984
49201
|
}
|
|
48985
49202
|
if (leaf === "dist") {
|
|
48986
|
-
return
|
|
49203
|
+
return path35.resolve(moduleDir, "..");
|
|
48987
49204
|
}
|
|
48988
|
-
return
|
|
49205
|
+
return path35.resolve(moduleDir, "..");
|
|
48989
49206
|
}
|
|
48990
49207
|
function formatMigrationResult(label, report) {
|
|
48991
49208
|
if (!report) {
|
|
@@ -49104,7 +49321,7 @@ var PACKAGE_ROOT;
|
|
|
49104
49321
|
var init_memory2 = __esm(() => {
|
|
49105
49322
|
init_loader();
|
|
49106
49323
|
init_memory();
|
|
49107
|
-
PACKAGE_ROOT =
|
|
49324
|
+
PACKAGE_ROOT = path35.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
|
|
49108
49325
|
});
|
|
49109
49326
|
|
|
49110
49327
|
// src/services/plan-service.ts
|
|
@@ -49492,7 +49709,7 @@ var init_path_security = () => {};
|
|
|
49492
49709
|
|
|
49493
49710
|
// src/tools/lint.ts
|
|
49494
49711
|
import * as fs14 from "fs";
|
|
49495
|
-
import * as
|
|
49712
|
+
import * as path36 from "path";
|
|
49496
49713
|
function validateArgs(args) {
|
|
49497
49714
|
if (typeof args !== "object" || args === null)
|
|
49498
49715
|
return false;
|
|
@@ -49503,9 +49720,9 @@ function validateArgs(args) {
|
|
|
49503
49720
|
}
|
|
49504
49721
|
function getLinterCommand(linter, mode, projectDir) {
|
|
49505
49722
|
const isWindows = process.platform === "win32";
|
|
49506
|
-
const binDir =
|
|
49507
|
-
const biomeBin = isWindows ?
|
|
49508
|
-
const eslintBin = isWindows ?
|
|
49723
|
+
const binDir = path36.join(projectDir, "node_modules", ".bin");
|
|
49724
|
+
const biomeBin = isWindows ? path36.join(binDir, "biome.EXE") : path36.join(binDir, "biome");
|
|
49725
|
+
const eslintBin = isWindows ? path36.join(binDir, "eslint.cmd") : path36.join(binDir, "eslint");
|
|
49509
49726
|
switch (linter) {
|
|
49510
49727
|
case "biome":
|
|
49511
49728
|
if (mode === "fix") {
|
|
@@ -49521,7 +49738,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
49521
49738
|
}
|
|
49522
49739
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
49523
49740
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
49524
|
-
const gradlew = fs14.existsSync(
|
|
49741
|
+
const gradlew = fs14.existsSync(path36.join(cwd, gradlewName)) ? path36.join(cwd, gradlewName) : null;
|
|
49525
49742
|
switch (linter) {
|
|
49526
49743
|
case "ruff":
|
|
49527
49744
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -49555,10 +49772,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
49555
49772
|
}
|
|
49556
49773
|
}
|
|
49557
49774
|
function detectRuff(cwd) {
|
|
49558
|
-
if (fs14.existsSync(
|
|
49775
|
+
if (fs14.existsSync(path36.join(cwd, "ruff.toml")))
|
|
49559
49776
|
return isCommandAvailable("ruff");
|
|
49560
49777
|
try {
|
|
49561
|
-
const pyproject =
|
|
49778
|
+
const pyproject = path36.join(cwd, "pyproject.toml");
|
|
49562
49779
|
if (fs14.existsSync(pyproject)) {
|
|
49563
49780
|
const content = fs14.readFileSync(pyproject, "utf-8");
|
|
49564
49781
|
if (content.includes("[tool.ruff]"))
|
|
@@ -49568,19 +49785,19 @@ function detectRuff(cwd) {
|
|
|
49568
49785
|
return false;
|
|
49569
49786
|
}
|
|
49570
49787
|
function detectClippy(cwd) {
|
|
49571
|
-
return fs14.existsSync(
|
|
49788
|
+
return fs14.existsSync(path36.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
49572
49789
|
}
|
|
49573
49790
|
function detectGolangciLint(cwd) {
|
|
49574
|
-
return fs14.existsSync(
|
|
49791
|
+
return fs14.existsSync(path36.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
49575
49792
|
}
|
|
49576
49793
|
function detectCheckstyle(cwd) {
|
|
49577
|
-
const hasMaven = fs14.existsSync(
|
|
49578
|
-
const hasGradle = fs14.existsSync(
|
|
49579
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs14.existsSync(
|
|
49794
|
+
const hasMaven = fs14.existsSync(path36.join(cwd, "pom.xml"));
|
|
49795
|
+
const hasGradle = fs14.existsSync(path36.join(cwd, "build.gradle")) || fs14.existsSync(path36.join(cwd, "build.gradle.kts"));
|
|
49796
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs14.existsSync(path36.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
49580
49797
|
return (hasMaven || hasGradle) && hasBinary;
|
|
49581
49798
|
}
|
|
49582
49799
|
function detectKtlint(cwd) {
|
|
49583
|
-
const hasKotlin = fs14.existsSync(
|
|
49800
|
+
const hasKotlin = fs14.existsSync(path36.join(cwd, "build.gradle.kts")) || fs14.existsSync(path36.join(cwd, "build.gradle")) || (() => {
|
|
49584
49801
|
try {
|
|
49585
49802
|
return fs14.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
49586
49803
|
} catch {
|
|
@@ -49599,11 +49816,11 @@ function detectDotnetFormat(cwd) {
|
|
|
49599
49816
|
}
|
|
49600
49817
|
}
|
|
49601
49818
|
function detectCppcheck(cwd) {
|
|
49602
|
-
if (fs14.existsSync(
|
|
49819
|
+
if (fs14.existsSync(path36.join(cwd, "CMakeLists.txt"))) {
|
|
49603
49820
|
return isCommandAvailable("cppcheck");
|
|
49604
49821
|
}
|
|
49605
49822
|
try {
|
|
49606
|
-
const dirsToCheck = [cwd,
|
|
49823
|
+
const dirsToCheck = [cwd, path36.join(cwd, "src")];
|
|
49607
49824
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
49608
49825
|
try {
|
|
49609
49826
|
return fs14.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -49617,13 +49834,13 @@ function detectCppcheck(cwd) {
|
|
|
49617
49834
|
}
|
|
49618
49835
|
}
|
|
49619
49836
|
function detectSwiftlint(cwd) {
|
|
49620
|
-
return fs14.existsSync(
|
|
49837
|
+
return fs14.existsSync(path36.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
49621
49838
|
}
|
|
49622
49839
|
function detectDartAnalyze(cwd) {
|
|
49623
|
-
return fs14.existsSync(
|
|
49840
|
+
return fs14.existsSync(path36.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
49624
49841
|
}
|
|
49625
49842
|
function detectRubocop(cwd) {
|
|
49626
|
-
return (fs14.existsSync(
|
|
49843
|
+
return (fs14.existsSync(path36.join(cwd, "Gemfile")) || fs14.existsSync(path36.join(cwd, "gems.rb")) || fs14.existsSync(path36.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
|
|
49627
49844
|
}
|
|
49628
49845
|
function detectAdditionalLinter(cwd) {
|
|
49629
49846
|
if (detectRuff(cwd))
|
|
@@ -49651,10 +49868,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
49651
49868
|
function findBinInAncestors(startDir, binName) {
|
|
49652
49869
|
let dir = startDir;
|
|
49653
49870
|
while (true) {
|
|
49654
|
-
const candidate =
|
|
49871
|
+
const candidate = path36.join(dir, "node_modules", ".bin", binName);
|
|
49655
49872
|
if (fs14.existsSync(candidate))
|
|
49656
49873
|
return candidate;
|
|
49657
|
-
const parent =
|
|
49874
|
+
const parent = path36.dirname(dir);
|
|
49658
49875
|
if (parent === dir)
|
|
49659
49876
|
break;
|
|
49660
49877
|
dir = parent;
|
|
@@ -49663,10 +49880,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
49663
49880
|
}
|
|
49664
49881
|
function findBinInEnvPath(binName) {
|
|
49665
49882
|
const searchPath = process.env.PATH ?? "";
|
|
49666
|
-
for (const dir of searchPath.split(
|
|
49883
|
+
for (const dir of searchPath.split(path36.delimiter)) {
|
|
49667
49884
|
if (!dir)
|
|
49668
49885
|
continue;
|
|
49669
|
-
const candidate =
|
|
49886
|
+
const candidate = path36.join(dir, binName);
|
|
49670
49887
|
if (fs14.existsSync(candidate))
|
|
49671
49888
|
return candidate;
|
|
49672
49889
|
}
|
|
@@ -49679,13 +49896,13 @@ async function detectAvailableLinter(directory) {
|
|
|
49679
49896
|
return null;
|
|
49680
49897
|
const projectDir = directory;
|
|
49681
49898
|
const isWindows = process.platform === "win32";
|
|
49682
|
-
const biomeBin = isWindows ?
|
|
49683
|
-
const eslintBin = isWindows ?
|
|
49899
|
+
const biomeBin = isWindows ? path36.join(projectDir, "node_modules", ".bin", "biome.EXE") : path36.join(projectDir, "node_modules", ".bin", "biome");
|
|
49900
|
+
const eslintBin = isWindows ? path36.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path36.join(projectDir, "node_modules", ".bin", "eslint");
|
|
49684
49901
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
49685
49902
|
if (localResult)
|
|
49686
49903
|
return localResult;
|
|
49687
|
-
const biomeAncestor = findBinInAncestors(
|
|
49688
|
-
const eslintAncestor = findBinInAncestors(
|
|
49904
|
+
const biomeAncestor = findBinInAncestors(path36.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
49905
|
+
const eslintAncestor = findBinInAncestors(path36.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
49689
49906
|
if (biomeAncestor || eslintAncestor) {
|
|
49690
49907
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
49691
49908
|
}
|
|
@@ -49908,7 +50125,7 @@ For Rust: rustup component add clippy`
|
|
|
49908
50125
|
|
|
49909
50126
|
// src/tools/secretscan.ts
|
|
49910
50127
|
import * as fs15 from "fs";
|
|
49911
|
-
import * as
|
|
50128
|
+
import * as path37 from "path";
|
|
49912
50129
|
function calculateShannonEntropy(str) {
|
|
49913
50130
|
if (str.length === 0)
|
|
49914
50131
|
return 0;
|
|
@@ -49956,7 +50173,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
49956
50173
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
49957
50174
|
}
|
|
49958
50175
|
function loadSecretScanIgnore(scanDir) {
|
|
49959
|
-
const ignorePath =
|
|
50176
|
+
const ignorePath = path37.join(scanDir, ".secretscanignore");
|
|
49960
50177
|
try {
|
|
49961
50178
|
if (!fs15.existsSync(ignorePath))
|
|
49962
50179
|
return [];
|
|
@@ -49979,7 +50196,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
49979
50196
|
if (exactNames.has(entry))
|
|
49980
50197
|
return true;
|
|
49981
50198
|
for (const pattern of globPatterns) {
|
|
49982
|
-
if (
|
|
50199
|
+
if (path37.matchesGlob(relPath, pattern))
|
|
49983
50200
|
return true;
|
|
49984
50201
|
}
|
|
49985
50202
|
return false;
|
|
@@ -50000,7 +50217,7 @@ function validateDirectoryInput(dir) {
|
|
|
50000
50217
|
return null;
|
|
50001
50218
|
}
|
|
50002
50219
|
function isBinaryFile(filePath, buffer) {
|
|
50003
|
-
const ext =
|
|
50220
|
+
const ext = path37.extname(filePath).toLowerCase();
|
|
50004
50221
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
50005
50222
|
return true;
|
|
50006
50223
|
}
|
|
@@ -50136,9 +50353,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
50136
50353
|
return false;
|
|
50137
50354
|
}
|
|
50138
50355
|
function isPathWithinScope(realPath, scanDir) {
|
|
50139
|
-
const resolvedScanDir =
|
|
50140
|
-
const resolvedRealPath =
|
|
50141
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
50356
|
+
const resolvedScanDir = path37.resolve(scanDir);
|
|
50357
|
+
const resolvedRealPath = path37.resolve(realPath);
|
|
50358
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path37.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
50142
50359
|
}
|
|
50143
50360
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
50144
50361
|
skippedDirs: 0,
|
|
@@ -50164,8 +50381,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
50164
50381
|
return a.localeCompare(b);
|
|
50165
50382
|
});
|
|
50166
50383
|
for (const entry of entries) {
|
|
50167
|
-
const fullPath =
|
|
50168
|
-
const relPath =
|
|
50384
|
+
const fullPath = path37.join(dir, entry);
|
|
50385
|
+
const relPath = path37.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
50169
50386
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
50170
50387
|
stats.skippedDirs++;
|
|
50171
50388
|
continue;
|
|
@@ -50200,7 +50417,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
50200
50417
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
50201
50418
|
files.push(...subFiles);
|
|
50202
50419
|
} else if (lstat.isFile()) {
|
|
50203
|
-
const ext =
|
|
50420
|
+
const ext = path37.extname(fullPath).toLowerCase();
|
|
50204
50421
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
50205
50422
|
files.push(fullPath);
|
|
50206
50423
|
} else {
|
|
@@ -50460,7 +50677,7 @@ var init_secretscan = __esm(() => {
|
|
|
50460
50677
|
}
|
|
50461
50678
|
}
|
|
50462
50679
|
try {
|
|
50463
|
-
const _scanDirRaw =
|
|
50680
|
+
const _scanDirRaw = path37.resolve(directory);
|
|
50464
50681
|
const scanDir = (() => {
|
|
50465
50682
|
try {
|
|
50466
50683
|
return fs15.realpathSync(_scanDirRaw);
|
|
@@ -50607,7 +50824,7 @@ var init_secretscan = __esm(() => {
|
|
|
50607
50824
|
|
|
50608
50825
|
// src/lang/default-backend.ts
|
|
50609
50826
|
import * as fs16 from "fs";
|
|
50610
|
-
import * as
|
|
50827
|
+
import * as path38 from "path";
|
|
50611
50828
|
function detectFileExists(dir, pattern) {
|
|
50612
50829
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
50613
50830
|
try {
|
|
@@ -50619,7 +50836,7 @@ function detectFileExists(dir, pattern) {
|
|
|
50619
50836
|
}
|
|
50620
50837
|
}
|
|
50621
50838
|
try {
|
|
50622
|
-
fs16.accessSync(
|
|
50839
|
+
fs16.accessSync(path38.join(dir, pattern));
|
|
50623
50840
|
return true;
|
|
50624
50841
|
} catch {
|
|
50625
50842
|
return false;
|
|
@@ -50747,8 +50964,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
50747
50964
|
return ["mvn", "test"];
|
|
50748
50965
|
case "gradle": {
|
|
50749
50966
|
const isWindows = process.platform === "win32";
|
|
50750
|
-
const hasGradlewBat = fs16.existsSync(
|
|
50751
|
-
const hasGradlew = fs16.existsSync(
|
|
50967
|
+
const hasGradlewBat = fs16.existsSync(path38.join(dir, "gradlew.bat"));
|
|
50968
|
+
const hasGradlew = fs16.existsSync(path38.join(dir, "gradlew"));
|
|
50752
50969
|
if (hasGradlewBat && isWindows)
|
|
50753
50970
|
return ["gradlew.bat", "test"];
|
|
50754
50971
|
if (hasGradlew)
|
|
@@ -50765,7 +50982,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
50765
50982
|
"cmake-build-release",
|
|
50766
50983
|
"out"
|
|
50767
50984
|
];
|
|
50768
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(
|
|
50985
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path38.join(dir, d, "CMakeCache.txt"))) ?? "build";
|
|
50769
50986
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
50770
50987
|
}
|
|
50771
50988
|
case "swift-test":
|
|
@@ -51052,17 +51269,17 @@ async function defaultSelectBuildCommand(profile, dir) {
|
|
|
51052
51269
|
return null;
|
|
51053
51270
|
}
|
|
51054
51271
|
async function defaultTestFilesFor(profile, sourceFile, dir) {
|
|
51055
|
-
const ext =
|
|
51272
|
+
const ext = path38.extname(sourceFile);
|
|
51056
51273
|
if (!profile.extensions.includes(ext))
|
|
51057
51274
|
return [];
|
|
51058
|
-
const base =
|
|
51059
|
-
const rel =
|
|
51060
|
-
const relDir =
|
|
51275
|
+
const base = path38.basename(sourceFile, ext);
|
|
51276
|
+
const rel = path38.relative(dir, sourceFile);
|
|
51277
|
+
const relDir = path38.dirname(rel);
|
|
51061
51278
|
const stripSrc = relDir.replace(/^src(\/|\\)/, "");
|
|
51062
51279
|
const candidates = new Set;
|
|
51063
51280
|
for (const tDir of ["tests", "test", "__tests__", "spec"]) {
|
|
51064
51281
|
for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
|
|
51065
|
-
candidates.add(
|
|
51282
|
+
candidates.add(path38.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
|
|
51066
51283
|
}
|
|
51067
51284
|
}
|
|
51068
51285
|
const existing = [];
|
|
@@ -51103,7 +51320,7 @@ var init_default_backend = __esm(() => {
|
|
|
51103
51320
|
|
|
51104
51321
|
// src/lang/backends/go.ts
|
|
51105
51322
|
import * as fs17 from "fs";
|
|
51106
|
-
import * as
|
|
51323
|
+
import * as path39 from "path";
|
|
51107
51324
|
function extractImports(_sourceFile, source) {
|
|
51108
51325
|
const out = new Set;
|
|
51109
51326
|
IMPORT_REGEX_SINGLE.lastIndex = 0;
|
|
@@ -51129,7 +51346,7 @@ function extractImports(_sourceFile, source) {
|
|
|
51129
51346
|
async function selectFramework(dir) {
|
|
51130
51347
|
let content;
|
|
51131
51348
|
try {
|
|
51132
|
-
content = fs17.readFileSync(
|
|
51349
|
+
content = fs17.readFileSync(path39.join(dir, "go.mod"), "utf-8");
|
|
51133
51350
|
} catch {
|
|
51134
51351
|
return null;
|
|
51135
51352
|
}
|
|
@@ -51150,16 +51367,16 @@ async function selectFramework(dir) {
|
|
|
51150
51367
|
async function selectEntryPoints(dir) {
|
|
51151
51368
|
const points = [];
|
|
51152
51369
|
try {
|
|
51153
|
-
fs17.accessSync(
|
|
51370
|
+
fs17.accessSync(path39.join(dir, "main.go"));
|
|
51154
51371
|
points.push("main.go");
|
|
51155
51372
|
} catch {}
|
|
51156
51373
|
try {
|
|
51157
|
-
const cmdDir =
|
|
51374
|
+
const cmdDir = path39.join(dir, "cmd");
|
|
51158
51375
|
const subdirs = fs17.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
51159
51376
|
for (const sub of subdirs) {
|
|
51160
|
-
const main =
|
|
51377
|
+
const main = path39.join("cmd", sub.name, "main.go");
|
|
51161
51378
|
try {
|
|
51162
|
-
fs17.accessSync(
|
|
51379
|
+
fs17.accessSync(path39.join(dir, main));
|
|
51163
51380
|
points.push(main);
|
|
51164
51381
|
} catch {}
|
|
51165
51382
|
}
|
|
@@ -51190,7 +51407,7 @@ var init_go = __esm(() => {
|
|
|
51190
51407
|
|
|
51191
51408
|
// src/lang/backends/python.ts
|
|
51192
51409
|
import * as fs18 from "fs";
|
|
51193
|
-
import * as
|
|
51410
|
+
import * as path40 from "path";
|
|
51194
51411
|
function parseImportTargets(rawTargets) {
|
|
51195
51412
|
const cleaned = rawTargets.replace(/[()]/g, "").split(`
|
|
51196
51413
|
`).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
|
|
@@ -51250,7 +51467,7 @@ async function selectFramework2(dir) {
|
|
|
51250
51467
|
];
|
|
51251
51468
|
for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
|
|
51252
51469
|
try {
|
|
51253
|
-
const content = fs18.readFileSync(
|
|
51470
|
+
const content = fs18.readFileSync(path40.join(dir, candidate), "utf-8");
|
|
51254
51471
|
const lower = content.toLowerCase();
|
|
51255
51472
|
for (const [pkg, name] of candidates) {
|
|
51256
51473
|
if (lower.includes(pkg)) {
|
|
@@ -51264,7 +51481,7 @@ async function selectFramework2(dir) {
|
|
|
51264
51481
|
async function selectEntryPoints2(dir) {
|
|
51265
51482
|
const points = new Set;
|
|
51266
51483
|
try {
|
|
51267
|
-
const content = fs18.readFileSync(
|
|
51484
|
+
const content = fs18.readFileSync(path40.join(dir, "pyproject.toml"), "utf-8");
|
|
51268
51485
|
const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
|
|
51269
51486
|
if (scriptsBlock) {
|
|
51270
51487
|
for (const line of scriptsBlock[0].split(`
|
|
@@ -51279,7 +51496,7 @@ async function selectEntryPoints2(dir) {
|
|
|
51279
51496
|
} catch {}
|
|
51280
51497
|
for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
|
|
51281
51498
|
try {
|
|
51282
|
-
fs18.accessSync(
|
|
51499
|
+
fs18.accessSync(path40.join(dir, name));
|
|
51283
51500
|
points.add(name);
|
|
51284
51501
|
} catch {}
|
|
51285
51502
|
}
|
|
@@ -51308,10 +51525,23 @@ var init_python = __esm(() => {
|
|
|
51308
51525
|
|
|
51309
51526
|
// src/test-impact/analyzer.ts
|
|
51310
51527
|
import fs19 from "fs";
|
|
51311
|
-
import
|
|
51528
|
+
import path41 from "path";
|
|
51312
51529
|
function normalizePath(p) {
|
|
51313
51530
|
return p.replace(/\\/g, "/");
|
|
51314
51531
|
}
|
|
51532
|
+
function sharedTrailingSegments(a, b) {
|
|
51533
|
+
const aParts = normalizePath(a).split("/").filter(Boolean);
|
|
51534
|
+
const bParts = normalizePath(b).split("/").filter(Boolean);
|
|
51535
|
+
let i = aParts.length - 1;
|
|
51536
|
+
let j = bParts.length - 1;
|
|
51537
|
+
let shared = 0;
|
|
51538
|
+
while (i >= 0 && j >= 0 && aParts[i] === bParts[j]) {
|
|
51539
|
+
shared++;
|
|
51540
|
+
i--;
|
|
51541
|
+
j--;
|
|
51542
|
+
}
|
|
51543
|
+
return shared;
|
|
51544
|
+
}
|
|
51315
51545
|
function isCacheStale(impactMap, generatedAtMs) {
|
|
51316
51546
|
for (const sourcePath of Object.keys(impactMap)) {
|
|
51317
51547
|
try {
|
|
@@ -51329,8 +51559,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
51329
51559
|
if (!importPath.startsWith(".")) {
|
|
51330
51560
|
return null;
|
|
51331
51561
|
}
|
|
51332
|
-
const resolved =
|
|
51333
|
-
if (
|
|
51562
|
+
const resolved = path41.resolve(fromDir, importPath);
|
|
51563
|
+
if (path41.extname(resolved)) {
|
|
51334
51564
|
if (fs19.existsSync(resolved) && fs19.statSync(resolved).isFile()) {
|
|
51335
51565
|
return normalizePath(resolved);
|
|
51336
51566
|
}
|
|
@@ -51350,20 +51580,20 @@ function resolvePythonImport(fromDir, module) {
|
|
|
51350
51580
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
51351
51581
|
let baseDir = fromDir;
|
|
51352
51582
|
for (let i = 1;i < leadingDots; i++) {
|
|
51353
|
-
baseDir =
|
|
51583
|
+
baseDir = path41.dirname(baseDir);
|
|
51354
51584
|
}
|
|
51355
51585
|
const rest = module.slice(leadingDots);
|
|
51356
51586
|
if (rest.length === 0) {
|
|
51357
|
-
const initPath =
|
|
51587
|
+
const initPath = path41.join(baseDir, "__init__.py");
|
|
51358
51588
|
if (fs19.existsSync(initPath) && fs19.statSync(initPath).isFile()) {
|
|
51359
51589
|
return normalizePath(initPath);
|
|
51360
51590
|
}
|
|
51361
51591
|
return null;
|
|
51362
51592
|
}
|
|
51363
|
-
const subpath = rest.replace(/\./g,
|
|
51593
|
+
const subpath = rest.replace(/\./g, path41.sep);
|
|
51364
51594
|
const candidates = [
|
|
51365
|
-
`${
|
|
51366
|
-
|
|
51595
|
+
`${path41.join(baseDir, subpath)}.py`,
|
|
51596
|
+
path41.join(baseDir, subpath, "__init__.py")
|
|
51367
51597
|
];
|
|
51368
51598
|
for (const c of candidates) {
|
|
51369
51599
|
if (fs19.existsSync(c) && fs19.statSync(c).isFile())
|
|
@@ -51372,7 +51602,7 @@ function resolvePythonImport(fromDir, module) {
|
|
|
51372
51602
|
return null;
|
|
51373
51603
|
}
|
|
51374
51604
|
function findGoModule(fromDir) {
|
|
51375
|
-
const resolved =
|
|
51605
|
+
const resolved = path41.resolve(fromDir);
|
|
51376
51606
|
let cur = resolved;
|
|
51377
51607
|
const walked = [];
|
|
51378
51608
|
for (let i = 0;i < 16; i++) {
|
|
@@ -51384,7 +51614,7 @@ function findGoModule(fromDir) {
|
|
|
51384
51614
|
}
|
|
51385
51615
|
walked.push(cur);
|
|
51386
51616
|
try {
|
|
51387
|
-
const goMod =
|
|
51617
|
+
const goMod = path41.join(cur, "go.mod");
|
|
51388
51618
|
const content = fs19.readFileSync(goMod, "utf-8");
|
|
51389
51619
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
51390
51620
|
if (moduleMatch) {
|
|
@@ -51395,10 +51625,10 @@ function findGoModule(fromDir) {
|
|
|
51395
51625
|
}
|
|
51396
51626
|
} catch {}
|
|
51397
51627
|
try {
|
|
51398
|
-
fs19.accessSync(
|
|
51628
|
+
fs19.accessSync(path41.join(cur, ".git"));
|
|
51399
51629
|
break;
|
|
51400
51630
|
} catch {}
|
|
51401
|
-
const parent =
|
|
51631
|
+
const parent = path41.dirname(cur);
|
|
51402
51632
|
if (parent === cur)
|
|
51403
51633
|
break;
|
|
51404
51634
|
cur = parent;
|
|
@@ -51410,12 +51640,12 @@ function findGoModule(fromDir) {
|
|
|
51410
51640
|
function resolveGoImport(fromDir, importPath) {
|
|
51411
51641
|
let dir = null;
|
|
51412
51642
|
if (importPath.startsWith(".")) {
|
|
51413
|
-
dir =
|
|
51643
|
+
dir = path41.resolve(fromDir, importPath);
|
|
51414
51644
|
} else {
|
|
51415
51645
|
const mod = findGoModule(fromDir);
|
|
51416
51646
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
51417
51647
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
51418
|
-
dir =
|
|
51648
|
+
dir = path41.join(mod.moduleRoot, subpath);
|
|
51419
51649
|
}
|
|
51420
51650
|
}
|
|
51421
51651
|
if (dir === null)
|
|
@@ -51423,7 +51653,7 @@ function resolveGoImport(fromDir, importPath) {
|
|
|
51423
51653
|
if (!fs19.existsSync(dir) || !fs19.statSync(dir).isDirectory())
|
|
51424
51654
|
return [];
|
|
51425
51655
|
try {
|
|
51426
|
-
return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(
|
|
51656
|
+
return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path41.join(dir, f)));
|
|
51427
51657
|
} catch {
|
|
51428
51658
|
return [];
|
|
51429
51659
|
}
|
|
@@ -51462,15 +51692,15 @@ function findTestFilesSync(cwd) {
|
|
|
51462
51692
|
for (const entry of entries) {
|
|
51463
51693
|
if (entry.isDirectory()) {
|
|
51464
51694
|
if (!skipDirs.has(entry.name)) {
|
|
51465
|
-
walk(
|
|
51695
|
+
walk(path41.join(dir, entry.name), visitedInodes);
|
|
51466
51696
|
}
|
|
51467
51697
|
} else if (entry.isFile()) {
|
|
51468
51698
|
const name = entry.name;
|
|
51469
51699
|
const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
|
|
51470
|
-
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${
|
|
51700
|
+
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path41.sep}tests${path41.sep}`) && name.endsWith(".py");
|
|
51471
51701
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
51472
51702
|
if (isTsTest || isPyTest || isGoTest) {
|
|
51473
|
-
testFiles.push(normalizePath(
|
|
51703
|
+
testFiles.push(normalizePath(path41.join(dir, entry.name)));
|
|
51474
51704
|
}
|
|
51475
51705
|
}
|
|
51476
51706
|
}
|
|
@@ -51495,8 +51725,8 @@ function extractImports3(content) {
|
|
|
51495
51725
|
];
|
|
51496
51726
|
}
|
|
51497
51727
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
51498
|
-
const ext =
|
|
51499
|
-
const testDir =
|
|
51728
|
+
const ext = path41.extname(testFile).toLowerCase();
|
|
51729
|
+
const testDir = path41.dirname(testFile);
|
|
51500
51730
|
function addEdge(source) {
|
|
51501
51731
|
if (!impactMap[source])
|
|
51502
51732
|
impactMap[source] = [];
|
|
@@ -51555,7 +51785,7 @@ async function buildImpactMap(cwd) {
|
|
|
51555
51785
|
return impactMap;
|
|
51556
51786
|
}
|
|
51557
51787
|
async function loadImpactMap(cwd, options) {
|
|
51558
|
-
const cachePath =
|
|
51788
|
+
const cachePath = path41.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
51559
51789
|
if (fs19.existsSync(cachePath)) {
|
|
51560
51790
|
try {
|
|
51561
51791
|
const content = fs19.readFileSync(cachePath, "utf-8");
|
|
@@ -51588,12 +51818,12 @@ async function loadImpactMap(cwd, options) {
|
|
|
51588
51818
|
return _internals25.buildImpactMap(cwd);
|
|
51589
51819
|
}
|
|
51590
51820
|
async function saveImpactMap(cwd, impactMap) {
|
|
51591
|
-
if (!
|
|
51821
|
+
if (!path41.isAbsolute(cwd)) {
|
|
51592
51822
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
51593
51823
|
}
|
|
51594
51824
|
_internals25.validateProjectRoot(cwd);
|
|
51595
|
-
const cacheDir2 =
|
|
51596
|
-
const cachePath =
|
|
51825
|
+
const cacheDir2 = path41.join(cwd, ".swarm", "cache");
|
|
51826
|
+
const cachePath = path41.join(cacheDir2, "impact-map.json");
|
|
51597
51827
|
if (!fs19.existsSync(cacheDir2)) {
|
|
51598
51828
|
fs19.mkdirSync(cacheDir2, { recursive: true });
|
|
51599
51829
|
}
|
|
@@ -51625,7 +51855,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
51625
51855
|
budgetExceeded = true;
|
|
51626
51856
|
break;
|
|
51627
51857
|
}
|
|
51628
|
-
const normalizedChanged = normalizePath(
|
|
51858
|
+
const normalizedChanged = normalizePath(path41.resolve(changedFile));
|
|
51629
51859
|
const tests = impactMap[normalizedChanged];
|
|
51630
51860
|
if (tests && tests.length > 0) {
|
|
51631
51861
|
for (const test of tests) {
|
|
@@ -51639,25 +51869,43 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
51639
51869
|
if (budgetExceeded)
|
|
51640
51870
|
break;
|
|
51641
51871
|
} else {
|
|
51642
|
-
|
|
51643
|
-
|
|
51872
|
+
const changedDir = normalizePath(path41.dirname(normalizedChanged));
|
|
51873
|
+
const changedInputDir = normalizePath(path41.dirname(changedFile));
|
|
51874
|
+
const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
|
|
51875
|
+
return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
|
|
51876
|
+
}).sort(([sourceA], [sourceB]) => {
|
|
51877
|
+
const sourceDirA = normalizePath(path41.dirname(sourceA));
|
|
51878
|
+
const sourceDirB = normalizePath(path41.dirname(sourceB));
|
|
51879
|
+
const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
|
|
51880
|
+
const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
|
|
51881
|
+
if (exactA !== exactB)
|
|
51882
|
+
return exactA ? -1 : 1;
|
|
51883
|
+
const sharedA = Math.max(sharedTrailingSegments(sourceDirA, changedDir), changedInputDir === "." ? 0 : sharedTrailingSegments(sourceDirA, changedInputDir));
|
|
51884
|
+
const sharedB = Math.max(sharedTrailingSegments(sourceDirB, changedDir), changedInputDir === "." ? 0 : sharedTrailingSegments(sourceDirB, changedInputDir));
|
|
51885
|
+
const nearestA = sharedA > 0;
|
|
51886
|
+
const nearestB = sharedB > 0;
|
|
51887
|
+
if (nearestA !== nearestB)
|
|
51888
|
+
return nearestA ? -1 : 1;
|
|
51889
|
+
if (sharedA !== sharedB)
|
|
51890
|
+
return sharedB - sharedA;
|
|
51891
|
+
return sourceA.localeCompare(sourceB);
|
|
51892
|
+
});
|
|
51893
|
+
const found = suffixMatches.length > 0;
|
|
51894
|
+
for (const [, tests2] of suffixMatches) {
|
|
51644
51895
|
if (budget !== undefined && visitedCount >= budget) {
|
|
51645
51896
|
budgetExceeded = true;
|
|
51646
51897
|
break;
|
|
51647
51898
|
}
|
|
51648
|
-
|
|
51649
|
-
|
|
51650
|
-
|
|
51651
|
-
budgetExceeded = true;
|
|
51652
|
-
break;
|
|
51653
|
-
}
|
|
51654
|
-
impactedTestsSet.add(test);
|
|
51655
|
-
visitedCount++;
|
|
51656
|
-
}
|
|
51657
|
-
if (budgetExceeded)
|
|
51899
|
+
for (const test of tests2) {
|
|
51900
|
+
if (budget !== undefined && visitedCount >= budget) {
|
|
51901
|
+
budgetExceeded = true;
|
|
51658
51902
|
break;
|
|
51659
|
-
|
|
51903
|
+
}
|
|
51904
|
+
impactedTestsSet.add(test);
|
|
51905
|
+
visitedCount++;
|
|
51660
51906
|
}
|
|
51907
|
+
if (budgetExceeded)
|
|
51908
|
+
break;
|
|
51661
51909
|
}
|
|
51662
51910
|
if (budgetExceeded)
|
|
51663
51911
|
break;
|
|
@@ -51918,15 +52166,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
|
|
|
51918
52166
|
|
|
51919
52167
|
// src/test-impact/history-store.ts
|
|
51920
52168
|
import fs20 from "fs";
|
|
51921
|
-
import
|
|
52169
|
+
import path42 from "path";
|
|
51922
52170
|
function getHistoryPath(workingDir) {
|
|
51923
52171
|
if (!workingDir) {
|
|
51924
52172
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
51925
52173
|
}
|
|
51926
|
-
if (!
|
|
52174
|
+
if (!path42.isAbsolute(workingDir)) {
|
|
51927
52175
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
51928
52176
|
}
|
|
51929
|
-
return
|
|
52177
|
+
return path42.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
51930
52178
|
}
|
|
51931
52179
|
function sanitizeErrorMessage(errorMessage) {
|
|
51932
52180
|
if (errorMessage === undefined) {
|
|
@@ -52013,7 +52261,7 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
52013
52261
|
}
|
|
52014
52262
|
}
|
|
52015
52263
|
const historyPath = getHistoryPath(workingDir);
|
|
52016
|
-
const historyDir =
|
|
52264
|
+
const historyDir = path42.dirname(historyPath);
|
|
52017
52265
|
_internals26.validateProjectRoot(workingDir);
|
|
52018
52266
|
if (!fs20.existsSync(historyDir)) {
|
|
52019
52267
|
fs20.mkdirSync(historyDir, { recursive: true });
|
|
@@ -52109,7 +52357,7 @@ var init_history_store = __esm(() => {
|
|
|
52109
52357
|
|
|
52110
52358
|
// src/tools/resolve-working-directory.ts
|
|
52111
52359
|
import * as fs21 from "fs";
|
|
52112
|
-
import * as
|
|
52360
|
+
import * as path43 from "path";
|
|
52113
52361
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
52114
52362
|
if (workingDirectory == null || workingDirectory === "") {
|
|
52115
52363
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -52129,15 +52377,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52129
52377
|
};
|
|
52130
52378
|
}
|
|
52131
52379
|
}
|
|
52132
|
-
const normalizedDir =
|
|
52133
|
-
const pathParts = normalizedDir.split(
|
|
52380
|
+
const normalizedDir = path43.normalize(workingDirectory);
|
|
52381
|
+
const pathParts = normalizedDir.split(path43.sep);
|
|
52134
52382
|
if (pathParts.includes("..")) {
|
|
52135
52383
|
return {
|
|
52136
52384
|
success: false,
|
|
52137
52385
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
52138
52386
|
};
|
|
52139
52387
|
}
|
|
52140
|
-
const resolvedDir =
|
|
52388
|
+
const resolvedDir = path43.resolve(normalizedDir);
|
|
52141
52389
|
let statResult;
|
|
52142
52390
|
try {
|
|
52143
52391
|
statResult = fs21.statSync(resolvedDir);
|
|
@@ -52153,7 +52401,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52153
52401
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
52154
52402
|
};
|
|
52155
52403
|
}
|
|
52156
|
-
const resolvedFallback =
|
|
52404
|
+
const resolvedFallback = path43.resolve(fallbackDirectory);
|
|
52157
52405
|
let fallbackExists = false;
|
|
52158
52406
|
try {
|
|
52159
52407
|
fs21.statSync(resolvedFallback);
|
|
@@ -52163,7 +52411,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52163
52411
|
}
|
|
52164
52412
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
52165
52413
|
if (fallbackExists) {
|
|
52166
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
52414
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path43.sep);
|
|
52167
52415
|
if (isSubdirectory) {
|
|
52168
52416
|
return {
|
|
52169
52417
|
success: false,
|
|
@@ -52218,10 +52466,10 @@ var init_registry_backend = __esm(() => {
|
|
|
52218
52466
|
|
|
52219
52467
|
// src/lang/backends/typescript.ts
|
|
52220
52468
|
import * as fs22 from "fs";
|
|
52221
|
-
import * as
|
|
52469
|
+
import * as path44 from "path";
|
|
52222
52470
|
function readPackageJsonRaw(dir) {
|
|
52223
52471
|
try {
|
|
52224
|
-
const content = fs22.readFileSync(
|
|
52472
|
+
const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
|
|
52225
52473
|
return JSON.parse(content);
|
|
52226
52474
|
} catch {
|
|
52227
52475
|
return null;
|
|
@@ -52441,7 +52689,7 @@ __export(exports_dispatch, {
|
|
|
52441
52689
|
_internals: () => _internals28
|
|
52442
52690
|
});
|
|
52443
52691
|
import * as fs23 from "fs";
|
|
52444
|
-
import * as
|
|
52692
|
+
import * as path45 from "path";
|
|
52445
52693
|
function safeReaddirSet(dir) {
|
|
52446
52694
|
try {
|
|
52447
52695
|
return new Set(fs23.readdirSync(dir));
|
|
@@ -52458,14 +52706,14 @@ function manifestHash(dir) {
|
|
|
52458
52706
|
if (!entries.has(name))
|
|
52459
52707
|
continue;
|
|
52460
52708
|
try {
|
|
52461
|
-
const stat4 = fs23.statSync(
|
|
52709
|
+
const stat4 = fs23.statSync(path45.join(dir, name));
|
|
52462
52710
|
parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
|
|
52463
52711
|
} catch {}
|
|
52464
52712
|
}
|
|
52465
52713
|
return parts.join("|");
|
|
52466
52714
|
}
|
|
52467
52715
|
function findManifestRoot(start) {
|
|
52468
|
-
const resolved =
|
|
52716
|
+
const resolved = path45.resolve(start);
|
|
52469
52717
|
const cached3 = manifestRootCache.get(resolved);
|
|
52470
52718
|
if (cached3 !== undefined)
|
|
52471
52719
|
return cached3;
|
|
@@ -52484,7 +52732,7 @@ function findManifestRoot(start) {
|
|
|
52484
52732
|
return cur;
|
|
52485
52733
|
}
|
|
52486
52734
|
}
|
|
52487
|
-
const parent =
|
|
52735
|
+
const parent = path45.dirname(cur);
|
|
52488
52736
|
if (parent === cur)
|
|
52489
52737
|
break;
|
|
52490
52738
|
cur = parent;
|
|
@@ -52594,13 +52842,13 @@ var init_dispatch = __esm(() => {
|
|
|
52594
52842
|
|
|
52595
52843
|
// src/tools/test-runner.ts
|
|
52596
52844
|
import * as fs24 from "fs";
|
|
52597
|
-
import * as
|
|
52845
|
+
import * as path46 from "path";
|
|
52598
52846
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
52599
52847
|
try {
|
|
52600
52848
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
52601
52849
|
const uniqueTestFiles = new Set;
|
|
52602
52850
|
for (const sourceFile of sourceFiles) {
|
|
52603
|
-
const resolvedPath =
|
|
52851
|
+
const resolvedPath = path46.resolve(cwd, sourceFile);
|
|
52604
52852
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
52605
52853
|
const testFiles = impactMap[normalizedPath];
|
|
52606
52854
|
if (testFiles) {
|
|
@@ -52678,14 +52926,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
52678
52926
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
52679
52927
|
}
|
|
52680
52928
|
function detectGoTest(cwd) {
|
|
52681
|
-
return fs24.existsSync(
|
|
52929
|
+
return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
52682
52930
|
}
|
|
52683
52931
|
function detectJavaMaven(cwd) {
|
|
52684
|
-
return fs24.existsSync(
|
|
52932
|
+
return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
52685
52933
|
}
|
|
52686
52934
|
function detectGradle(cwd) {
|
|
52687
|
-
const hasBuildFile = fs24.existsSync(
|
|
52688
|
-
const hasGradlew = fs24.existsSync(
|
|
52935
|
+
const hasBuildFile = fs24.existsSync(path46.join(cwd, "build.gradle")) || fs24.existsSync(path46.join(cwd, "build.gradle.kts"));
|
|
52936
|
+
const hasGradlew = fs24.existsSync(path46.join(cwd, "gradlew")) || fs24.existsSync(path46.join(cwd, "gradlew.bat"));
|
|
52689
52937
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
52690
52938
|
}
|
|
52691
52939
|
function detectDotnetTest(cwd) {
|
|
@@ -52698,25 +52946,25 @@ function detectDotnetTest(cwd) {
|
|
|
52698
52946
|
}
|
|
52699
52947
|
}
|
|
52700
52948
|
function detectCTest(cwd) {
|
|
52701
|
-
const hasSource = fs24.existsSync(
|
|
52702
|
-
const hasBuildCache = fs24.existsSync(
|
|
52949
|
+
const hasSource = fs24.existsSync(path46.join(cwd, "CMakeLists.txt"));
|
|
52950
|
+
const hasBuildCache = fs24.existsSync(path46.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path46.join(cwd, "build", "CMakeCache.txt"));
|
|
52703
52951
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
52704
52952
|
}
|
|
52705
52953
|
function detectSwiftTest(cwd) {
|
|
52706
|
-
return fs24.existsSync(
|
|
52954
|
+
return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
52707
52955
|
}
|
|
52708
52956
|
function detectDartTest(cwd) {
|
|
52709
|
-
return fs24.existsSync(
|
|
52957
|
+
return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
52710
52958
|
}
|
|
52711
52959
|
function detectRSpec(cwd) {
|
|
52712
|
-
const hasRSpecFile = fs24.existsSync(
|
|
52713
|
-
const hasGemfile = fs24.existsSync(
|
|
52714
|
-
const hasSpecDir = fs24.existsSync(
|
|
52960
|
+
const hasRSpecFile = fs24.existsSync(path46.join(cwd, ".rspec"));
|
|
52961
|
+
const hasGemfile = fs24.existsSync(path46.join(cwd, "Gemfile"));
|
|
52962
|
+
const hasSpecDir = fs24.existsSync(path46.join(cwd, "spec"));
|
|
52715
52963
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
52716
52964
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
52717
52965
|
}
|
|
52718
52966
|
function detectMinitest(cwd) {
|
|
52719
|
-
return fs24.existsSync(
|
|
52967
|
+
return fs24.existsSync(path46.join(cwd, "test")) && (fs24.existsSync(path46.join(cwd, "Gemfile")) || fs24.existsSync(path46.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
52720
52968
|
}
|
|
52721
52969
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
52722
52970
|
try {
|
|
@@ -52778,7 +53026,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
52778
53026
|
async function detectTestFramework(cwd) {
|
|
52779
53027
|
const baseDir = cwd;
|
|
52780
53028
|
try {
|
|
52781
|
-
const packageJsonPath =
|
|
53029
|
+
const packageJsonPath = path46.join(baseDir, "package.json");
|
|
52782
53030
|
if (fs24.existsSync(packageJsonPath)) {
|
|
52783
53031
|
const content = fs24.readFileSync(packageJsonPath, "utf-8");
|
|
52784
53032
|
const pkg = JSON.parse(content);
|
|
@@ -52799,16 +53047,16 @@ async function detectTestFramework(cwd) {
|
|
|
52799
53047
|
return "jest";
|
|
52800
53048
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
52801
53049
|
return "mocha";
|
|
52802
|
-
if (fs24.existsSync(
|
|
53050
|
+
if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
|
|
52803
53051
|
if (scripts.test?.includes("bun"))
|
|
52804
53052
|
return "bun";
|
|
52805
53053
|
}
|
|
52806
53054
|
}
|
|
52807
53055
|
} catch {}
|
|
52808
53056
|
try {
|
|
52809
|
-
const pyprojectTomlPath =
|
|
52810
|
-
const setupCfgPath =
|
|
52811
|
-
const requirementsTxtPath =
|
|
53057
|
+
const pyprojectTomlPath = path46.join(baseDir, "pyproject.toml");
|
|
53058
|
+
const setupCfgPath = path46.join(baseDir, "setup.cfg");
|
|
53059
|
+
const requirementsTxtPath = path46.join(baseDir, "requirements.txt");
|
|
52812
53060
|
if (fs24.existsSync(pyprojectTomlPath)) {
|
|
52813
53061
|
const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
|
|
52814
53062
|
if (content.includes("[tool.pytest"))
|
|
@@ -52828,7 +53076,7 @@ async function detectTestFramework(cwd) {
|
|
|
52828
53076
|
}
|
|
52829
53077
|
} catch {}
|
|
52830
53078
|
try {
|
|
52831
|
-
const cargoTomlPath =
|
|
53079
|
+
const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
|
|
52832
53080
|
if (fs24.existsSync(cargoTomlPath)) {
|
|
52833
53081
|
const content = fs24.readFileSync(cargoTomlPath, "utf-8");
|
|
52834
53082
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -52839,9 +53087,9 @@ async function detectTestFramework(cwd) {
|
|
|
52839
53087
|
}
|
|
52840
53088
|
} catch {}
|
|
52841
53089
|
try {
|
|
52842
|
-
const pesterConfigPath =
|
|
52843
|
-
const pesterConfigJsonPath =
|
|
52844
|
-
const pesterPs1Path =
|
|
53090
|
+
const pesterConfigPath = path46.join(baseDir, "pester.config.ps1");
|
|
53091
|
+
const pesterConfigJsonPath = path46.join(baseDir, "pester.config.ps1.json");
|
|
53092
|
+
const pesterPs1Path = path46.join(baseDir, "tests.ps1");
|
|
52845
53093
|
if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
|
|
52846
53094
|
return "pester";
|
|
52847
53095
|
}
|
|
@@ -52870,12 +53118,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
52870
53118
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
52871
53119
|
}
|
|
52872
53120
|
function resolveWorkspacePath(file3, workingDir) {
|
|
52873
|
-
return
|
|
53121
|
+
return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
|
|
52874
53122
|
}
|
|
52875
53123
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
52876
53124
|
if (!preferRelative)
|
|
52877
53125
|
return absolutePath;
|
|
52878
|
-
return
|
|
53126
|
+
return path46.relative(workingDir, absolutePath);
|
|
52879
53127
|
}
|
|
52880
53128
|
function dedupePush(target, value) {
|
|
52881
53129
|
if (!target.includes(value)) {
|
|
@@ -52912,18 +53160,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
52912
53160
|
}
|
|
52913
53161
|
}
|
|
52914
53162
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
52915
|
-
const relativeDir =
|
|
53163
|
+
const relativeDir = path46.dirname(relativePath);
|
|
52916
53164
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
52917
53165
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
52918
|
-
const rootDir =
|
|
52919
|
-
return nestedRelativeDir ? [rootDir,
|
|
53166
|
+
const rootDir = path46.join(workingDir, dirName);
|
|
53167
|
+
return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
52920
53168
|
});
|
|
52921
53169
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
52922
53170
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
52923
|
-
directories.push(
|
|
53171
|
+
directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
52924
53172
|
}
|
|
52925
53173
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
52926
|
-
directories.push(
|
|
53174
|
+
directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
52927
53175
|
}
|
|
52928
53176
|
return [...new Set(directories)];
|
|
52929
53177
|
}
|
|
@@ -52951,23 +53199,23 @@ function isLanguageSpecificTestFile(basename7) {
|
|
|
52951
53199
|
}
|
|
52952
53200
|
function isConventionTestFilePath(filePath) {
|
|
52953
53201
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
52954
|
-
const basename7 =
|
|
53202
|
+
const basename7 = path46.basename(filePath);
|
|
52955
53203
|
return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
|
|
52956
53204
|
}
|
|
52957
53205
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
52958
53206
|
const testFiles = [];
|
|
52959
53207
|
for (const file3 of sourceFiles) {
|
|
52960
53208
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
52961
|
-
const relativeFile =
|
|
52962
|
-
const basename7 =
|
|
52963
|
-
const
|
|
52964
|
-
const preferRelativeOutput = !
|
|
53209
|
+
const relativeFile = path46.relative(workingDir, absoluteFile);
|
|
53210
|
+
const basename7 = path46.basename(absoluteFile);
|
|
53211
|
+
const dirname23 = path46.dirname(absoluteFile);
|
|
53212
|
+
const preferRelativeOutput = !path46.isAbsolute(file3);
|
|
52965
53213
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
52966
53214
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
52967
53215
|
continue;
|
|
52968
53216
|
}
|
|
52969
53217
|
const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
|
|
52970
|
-
const ext =
|
|
53218
|
+
const ext = path46.extname(basename7);
|
|
52971
53219
|
const genericTestNames = [
|
|
52972
53220
|
`${nameWithoutExt}.spec${ext}`,
|
|
52973
53221
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -52976,7 +53224,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
52976
53224
|
const colocatedCandidates = [
|
|
52977
53225
|
...genericTestNames,
|
|
52978
53226
|
...languageSpecificTestNames
|
|
52979
|
-
].map((candidateName) =>
|
|
53227
|
+
].map((candidateName) => path46.join(dirname23, candidateName));
|
|
52980
53228
|
const testDirectoryNames = [
|
|
52981
53229
|
basename7,
|
|
52982
53230
|
...genericTestNames,
|
|
@@ -52985,8 +53233,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
52985
53233
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
52986
53234
|
const possibleTestFiles = [
|
|
52987
53235
|
...colocatedCandidates,
|
|
52988
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
52989
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
53236
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path46.join(dirname23, dirName, candidateName))),
|
|
53237
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path46.join(candidateDir, candidateName)))
|
|
52990
53238
|
];
|
|
52991
53239
|
for (const testFile of possibleTestFiles) {
|
|
52992
53240
|
if (fs24.existsSync(testFile)) {
|
|
@@ -53007,7 +53255,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53007
53255
|
try {
|
|
53008
53256
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
53009
53257
|
const content = fs24.readFileSync(absoluteTestFile, "utf-8");
|
|
53010
|
-
const testDir =
|
|
53258
|
+
const testDir = path46.dirname(absoluteTestFile);
|
|
53011
53259
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
53012
53260
|
let match;
|
|
53013
53261
|
match = importRegex.exec(content);
|
|
@@ -53015,8 +53263,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53015
53263
|
const importPath = match[1];
|
|
53016
53264
|
let resolvedImport;
|
|
53017
53265
|
if (importPath.startsWith(".")) {
|
|
53018
|
-
resolvedImport =
|
|
53019
|
-
const existingExt =
|
|
53266
|
+
resolvedImport = path46.resolve(testDir, importPath);
|
|
53267
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53020
53268
|
if (!existingExt) {
|
|
53021
53269
|
for (const extToTry of [
|
|
53022
53270
|
".ts",
|
|
@@ -53036,12 +53284,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53036
53284
|
} else {
|
|
53037
53285
|
continue;
|
|
53038
53286
|
}
|
|
53039
|
-
const importBasename =
|
|
53040
|
-
const importDir =
|
|
53287
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
53288
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53041
53289
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53042
|
-
const sourceDir =
|
|
53043
|
-
const sourceBasename =
|
|
53044
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
53290
|
+
const sourceDir = path46.dirname(sourceFile);
|
|
53291
|
+
const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
|
|
53292
|
+
const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
|
|
53045
53293
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53046
53294
|
dedupePush(testFiles, testFile);
|
|
53047
53295
|
break;
|
|
@@ -53054,8 +53302,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53054
53302
|
while (match !== null) {
|
|
53055
53303
|
const importPath = match[1];
|
|
53056
53304
|
if (importPath.startsWith(".")) {
|
|
53057
|
-
let resolvedImport =
|
|
53058
|
-
const existingExt =
|
|
53305
|
+
let resolvedImport = path46.resolve(testDir, importPath);
|
|
53306
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53059
53307
|
if (!existingExt) {
|
|
53060
53308
|
for (const extToTry of [
|
|
53061
53309
|
".ts",
|
|
@@ -53072,12 +53320,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53072
53320
|
}
|
|
53073
53321
|
}
|
|
53074
53322
|
}
|
|
53075
|
-
const importDir =
|
|
53076
|
-
const importBasename =
|
|
53323
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53324
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
53077
53325
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53078
|
-
const sourceDir =
|
|
53079
|
-
const sourceBasename =
|
|
53080
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
53326
|
+
const sourceDir = path46.dirname(sourceFile);
|
|
53327
|
+
const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
|
|
53328
|
+
const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
|
|
53081
53329
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53082
53330
|
dedupePush(testFiles, testFile);
|
|
53083
53331
|
break;
|
|
@@ -53187,8 +53435,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53187
53435
|
return ["mvn", "test"];
|
|
53188
53436
|
case "gradle": {
|
|
53189
53437
|
const isWindows = process.platform === "win32";
|
|
53190
|
-
const hasGradlewBat = fs24.existsSync(
|
|
53191
|
-
const hasGradlew = fs24.existsSync(
|
|
53438
|
+
const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
|
|
53439
|
+
const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
|
|
53192
53440
|
if (hasGradlewBat && isWindows)
|
|
53193
53441
|
return ["gradlew.bat", "test"];
|
|
53194
53442
|
if (hasGradlew)
|
|
@@ -53205,7 +53453,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53205
53453
|
"cmake-build-release",
|
|
53206
53454
|
"out"
|
|
53207
53455
|
];
|
|
53208
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(
|
|
53456
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
53209
53457
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
53210
53458
|
}
|
|
53211
53459
|
case "swift-test":
|
|
@@ -53637,11 +53885,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
53637
53885
|
};
|
|
53638
53886
|
}
|
|
53639
53887
|
const startTime = Date.now();
|
|
53640
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
53888
|
+
const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
53641
53889
|
try {
|
|
53642
53890
|
if (vitestJsonOutputPath) {
|
|
53643
53891
|
try {
|
|
53644
|
-
fs24.mkdirSync(
|
|
53892
|
+
fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
|
|
53645
53893
|
if (fs24.existsSync(vitestJsonOutputPath)) {
|
|
53646
53894
|
fs24.unlinkSync(vitestJsonOutputPath);
|
|
53647
53895
|
}
|
|
@@ -53757,10 +54005,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
53757
54005
|
}
|
|
53758
54006
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
53759
54007
|
const normalized = testFile.replace(/\\/g, "/");
|
|
53760
|
-
if (!
|
|
54008
|
+
if (!path46.isAbsolute(testFile))
|
|
53761
54009
|
return normalized;
|
|
53762
|
-
const relative9 =
|
|
53763
|
-
if (relative9.startsWith("..") ||
|
|
54010
|
+
const relative9 = path46.relative(workingDir, testFile);
|
|
54011
|
+
if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
|
|
53764
54012
|
return normalized;
|
|
53765
54013
|
}
|
|
53766
54014
|
return relative9.replace(/\\/g, "/");
|
|
@@ -54098,7 +54346,7 @@ var init_test_runner = __esm(() => {
|
|
|
54098
54346
|
const sourceFiles = args.files.filter((file3) => {
|
|
54099
54347
|
if (directTestFiles.includes(file3))
|
|
54100
54348
|
return false;
|
|
54101
|
-
const ext =
|
|
54349
|
+
const ext = path46.extname(file3).toLowerCase();
|
|
54102
54350
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54103
54351
|
});
|
|
54104
54352
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -54144,7 +54392,7 @@ var init_test_runner = __esm(() => {
|
|
|
54144
54392
|
if (isConventionTestFilePath(f)) {
|
|
54145
54393
|
return false;
|
|
54146
54394
|
}
|
|
54147
|
-
const ext =
|
|
54395
|
+
const ext = path46.extname(f).toLowerCase();
|
|
54148
54396
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54149
54397
|
});
|
|
54150
54398
|
if (sourceFiles.length === 0) {
|
|
@@ -54194,7 +54442,7 @@ var init_test_runner = __esm(() => {
|
|
|
54194
54442
|
if (isConventionTestFilePath(f)) {
|
|
54195
54443
|
return false;
|
|
54196
54444
|
}
|
|
54197
|
-
const ext =
|
|
54445
|
+
const ext = path46.extname(f).toLowerCase();
|
|
54198
54446
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54199
54447
|
});
|
|
54200
54448
|
if (sourceFiles.length === 0) {
|
|
@@ -54246,8 +54494,8 @@ var init_test_runner = __esm(() => {
|
|
|
54246
54494
|
}
|
|
54247
54495
|
if (impactResult.impactedTests.length > 0) {
|
|
54248
54496
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
54249
|
-
const relativePath =
|
|
54250
|
-
return
|
|
54497
|
+
const relativePath = path46.relative(workingDir, absPath);
|
|
54498
|
+
return path46.isAbsolute(relativePath) ? absPath : relativePath;
|
|
54251
54499
|
});
|
|
54252
54500
|
} else {
|
|
54253
54501
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -54323,7 +54571,7 @@ var init_test_runner = __esm(() => {
|
|
|
54323
54571
|
|
|
54324
54572
|
// src/services/preflight-service.ts
|
|
54325
54573
|
import * as fs25 from "fs";
|
|
54326
|
-
import * as
|
|
54574
|
+
import * as path47 from "path";
|
|
54327
54575
|
function validateDirectoryPath(dir) {
|
|
54328
54576
|
if (!dir || typeof dir !== "string") {
|
|
54329
54577
|
throw new Error("Directory path is required");
|
|
@@ -54331,8 +54579,8 @@ function validateDirectoryPath(dir) {
|
|
|
54331
54579
|
if (dir.includes("..")) {
|
|
54332
54580
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
54333
54581
|
}
|
|
54334
|
-
const normalized =
|
|
54335
|
-
const absolutePath =
|
|
54582
|
+
const normalized = path47.normalize(dir);
|
|
54583
|
+
const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
|
|
54336
54584
|
return absolutePath;
|
|
54337
54585
|
}
|
|
54338
54586
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -54355,7 +54603,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
54355
54603
|
}
|
|
54356
54604
|
function getPackageVersion(dir) {
|
|
54357
54605
|
try {
|
|
54358
|
-
const packagePath =
|
|
54606
|
+
const packagePath = path47.join(dir, "package.json");
|
|
54359
54607
|
if (fs25.existsSync(packagePath)) {
|
|
54360
54608
|
const content = fs25.readFileSync(packagePath, "utf-8");
|
|
54361
54609
|
const pkg = JSON.parse(content);
|
|
@@ -54366,7 +54614,7 @@ function getPackageVersion(dir) {
|
|
|
54366
54614
|
}
|
|
54367
54615
|
function getChangelogVersion(dir) {
|
|
54368
54616
|
try {
|
|
54369
|
-
const changelogPath =
|
|
54617
|
+
const changelogPath = path47.join(dir, "CHANGELOG.md");
|
|
54370
54618
|
if (fs25.existsSync(changelogPath)) {
|
|
54371
54619
|
const content = fs25.readFileSync(changelogPath, "utf-8");
|
|
54372
54620
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -54380,7 +54628,7 @@ function getChangelogVersion(dir) {
|
|
|
54380
54628
|
function getVersionFileVersion(dir) {
|
|
54381
54629
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
54382
54630
|
for (const file3 of possibleFiles) {
|
|
54383
|
-
const filePath =
|
|
54631
|
+
const filePath = path47.join(dir, file3);
|
|
54384
54632
|
if (fs25.existsSync(filePath)) {
|
|
54385
54633
|
try {
|
|
54386
54634
|
const content = fs25.readFileSync(filePath, "utf-8").trim();
|
|
@@ -54722,7 +54970,7 @@ async function runEvidenceCheck(dir) {
|
|
|
54722
54970
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
54723
54971
|
const startTime = Date.now();
|
|
54724
54972
|
try {
|
|
54725
|
-
const specPath =
|
|
54973
|
+
const specPath = path47.join(dir, ".swarm", "spec.md");
|
|
54726
54974
|
if (!fs25.existsSync(specPath)) {
|
|
54727
54975
|
return {
|
|
54728
54976
|
type: "req_coverage",
|
|
@@ -55840,7 +56088,7 @@ var init_manager3 = __esm(() => {
|
|
|
55840
56088
|
|
|
55841
56089
|
// src/commands/reset.ts
|
|
55842
56090
|
import * as fs26 from "fs";
|
|
55843
|
-
import * as
|
|
56091
|
+
import * as path48 from "path";
|
|
55844
56092
|
async function handleResetCommand(directory, args) {
|
|
55845
56093
|
const hasConfirm = args.includes("--confirm");
|
|
55846
56094
|
if (!hasConfirm) {
|
|
@@ -55880,7 +56128,7 @@ async function handleResetCommand(directory, args) {
|
|
|
55880
56128
|
}
|
|
55881
56129
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
55882
56130
|
try {
|
|
55883
|
-
const rootPath =
|
|
56131
|
+
const rootPath = path48.join(directory, filename);
|
|
55884
56132
|
if (fs26.existsSync(rootPath)) {
|
|
55885
56133
|
fs26.unlinkSync(rootPath);
|
|
55886
56134
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
@@ -55920,7 +56168,7 @@ var init_reset = __esm(() => {
|
|
|
55920
56168
|
|
|
55921
56169
|
// src/commands/reset-session.ts
|
|
55922
56170
|
import * as fs27 from "fs";
|
|
55923
|
-
import * as
|
|
56171
|
+
import * as path49 from "path";
|
|
55924
56172
|
async function handleResetSessionCommand(directory, _args) {
|
|
55925
56173
|
const results = [];
|
|
55926
56174
|
try {
|
|
@@ -55935,13 +56183,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
55935
56183
|
results.push("\u274C Failed to delete state.json");
|
|
55936
56184
|
}
|
|
55937
56185
|
try {
|
|
55938
|
-
const sessionDir =
|
|
56186
|
+
const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
55939
56187
|
if (fs27.existsSync(sessionDir)) {
|
|
55940
56188
|
const files = fs27.readdirSync(sessionDir);
|
|
55941
56189
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
55942
56190
|
let deletedCount = 0;
|
|
55943
56191
|
for (const file3 of otherFiles) {
|
|
55944
|
-
const filePath =
|
|
56192
|
+
const filePath = path49.join(sessionDir, file3);
|
|
55945
56193
|
if (fs27.lstatSync(filePath).isFile()) {
|
|
55946
56194
|
fs27.unlinkSync(filePath);
|
|
55947
56195
|
deletedCount++;
|
|
@@ -55973,7 +56221,7 @@ var init_reset_session = __esm(() => {
|
|
|
55973
56221
|
});
|
|
55974
56222
|
|
|
55975
56223
|
// src/summaries/manager.ts
|
|
55976
|
-
import * as
|
|
56224
|
+
import * as path50 from "path";
|
|
55977
56225
|
function sanitizeSummaryId(id) {
|
|
55978
56226
|
if (!id || id.length === 0) {
|
|
55979
56227
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -55996,7 +56244,7 @@ function sanitizeSummaryId(id) {
|
|
|
55996
56244
|
}
|
|
55997
56245
|
async function loadFullOutput(directory, id) {
|
|
55998
56246
|
const sanitizedId = sanitizeSummaryId(id);
|
|
55999
|
-
const relativePath =
|
|
56247
|
+
const relativePath = path50.join("summaries", `${sanitizedId}.json`);
|
|
56000
56248
|
validateSwarmPath(directory, relativePath);
|
|
56001
56249
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
56002
56250
|
if (content === null) {
|
|
@@ -56059,7 +56307,7 @@ var init_retrieve = __esm(() => {
|
|
|
56059
56307
|
|
|
56060
56308
|
// src/commands/rollback.ts
|
|
56061
56309
|
import * as fs28 from "fs";
|
|
56062
|
-
import * as
|
|
56310
|
+
import * as path51 from "path";
|
|
56063
56311
|
async function handleRollbackCommand(directory, args) {
|
|
56064
56312
|
const phaseArg = args[0];
|
|
56065
56313
|
if (!phaseArg) {
|
|
@@ -56124,8 +56372,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
56124
56372
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
56125
56373
|
continue;
|
|
56126
56374
|
}
|
|
56127
|
-
const src =
|
|
56128
|
-
const dest =
|
|
56375
|
+
const src = path51.join(checkpointDir, file3);
|
|
56376
|
+
const dest = path51.join(swarmDir, file3);
|
|
56129
56377
|
try {
|
|
56130
56378
|
fs28.cpSync(src, dest, { recursive: true, force: true });
|
|
56131
56379
|
successes.push(file3);
|
|
@@ -56144,12 +56392,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
56144
56392
|
].join(`
|
|
56145
56393
|
`);
|
|
56146
56394
|
}
|
|
56147
|
-
const existingLedgerPath =
|
|
56395
|
+
const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
|
|
56148
56396
|
if (fs28.existsSync(existingLedgerPath)) {
|
|
56149
56397
|
fs28.unlinkSync(existingLedgerPath);
|
|
56150
56398
|
}
|
|
56151
56399
|
try {
|
|
56152
|
-
const planJsonPath =
|
|
56400
|
+
const planJsonPath = path51.join(swarmDir, "plan.json");
|
|
56153
56401
|
if (fs28.existsSync(planJsonPath)) {
|
|
56154
56402
|
const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
|
|
56155
56403
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -56240,9 +56488,9 @@ Ensure this is a git repository with commit history.`;
|
|
|
56240
56488
|
`);
|
|
56241
56489
|
try {
|
|
56242
56490
|
const fs29 = await import("fs/promises");
|
|
56243
|
-
const
|
|
56244
|
-
const reportPath =
|
|
56245
|
-
await fs29.mkdir(
|
|
56491
|
+
const path52 = await import("path");
|
|
56492
|
+
const reportPath = path52.join(directory, ".swarm", "simulate-report.md");
|
|
56493
|
+
await fs29.mkdir(path52.dirname(reportPath), { recursive: true });
|
|
56246
56494
|
await fs29.writeFile(reportPath, report, "utf-8");
|
|
56247
56495
|
} catch (err) {
|
|
56248
56496
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
@@ -56266,12 +56514,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
56266
56514
|
|
|
56267
56515
|
// src/turbo/lean/state.ts
|
|
56268
56516
|
import * as fs29 from "fs";
|
|
56269
|
-
import * as
|
|
56517
|
+
import * as path52 from "path";
|
|
56270
56518
|
function nowISO2() {
|
|
56271
56519
|
return new Date().toISOString();
|
|
56272
56520
|
}
|
|
56273
56521
|
function ensureSwarmDir2(directory) {
|
|
56274
|
-
const swarmDir =
|
|
56522
|
+
const swarmDir = path52.resolve(directory, ".swarm");
|
|
56275
56523
|
if (!fs29.existsSync(swarmDir)) {
|
|
56276
56524
|
fs29.mkdirSync(swarmDir, { recursive: true });
|
|
56277
56525
|
}
|
|
@@ -56315,7 +56563,7 @@ function markStateUnreadable2(directory, reason) {
|
|
|
56315
56563
|
}
|
|
56316
56564
|
function readPersisted2(directory) {
|
|
56317
56565
|
try {
|
|
56318
|
-
const filePath =
|
|
56566
|
+
const filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
56319
56567
|
if (!fs29.existsSync(filePath)) {
|
|
56320
56568
|
const seed = emptyPersisted2();
|
|
56321
56569
|
try {
|
|
@@ -56351,7 +56599,7 @@ function writePersisted2(directory, persisted) {
|
|
|
56351
56599
|
let payload;
|
|
56352
56600
|
try {
|
|
56353
56601
|
ensureSwarmDir2(directory);
|
|
56354
|
-
filePath =
|
|
56602
|
+
filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
56355
56603
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
56356
56604
|
persisted.updatedAt = nowISO2();
|
|
56357
56605
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -56478,10 +56726,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
56478
56726
|
|
|
56479
56727
|
// src/services/status-service.ts
|
|
56480
56728
|
import * as fsSync2 from "fs";
|
|
56481
|
-
import * as
|
|
56729
|
+
import * as path53 from "path";
|
|
56482
56730
|
function readSpecStalenessSnapshot(directory) {
|
|
56483
56731
|
try {
|
|
56484
|
-
const p =
|
|
56732
|
+
const p = path53.join(directory, ".swarm", "spec-staleness.json");
|
|
56485
56733
|
if (!fsSync2.existsSync(p))
|
|
56486
56734
|
return { stale: false };
|
|
56487
56735
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -57007,7 +57255,7 @@ var init_write_retro2 = __esm(() => {
|
|
|
57007
57255
|
|
|
57008
57256
|
// src/commands/command-dispatch.ts
|
|
57009
57257
|
import fs30 from "fs";
|
|
57010
|
-
import
|
|
57258
|
+
import path54 from "path";
|
|
57011
57259
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
57012
57260
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
57013
57261
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -57043,9 +57291,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
57043
57291
|
`);
|
|
57044
57292
|
}
|
|
57045
57293
|
function maybeMarkFirstRun(directory) {
|
|
57046
|
-
const sentinelPath =
|
|
57294
|
+
const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
|
|
57047
57295
|
try {
|
|
57048
|
-
const swarmDir =
|
|
57296
|
+
const swarmDir = path54.join(directory, ".swarm");
|
|
57049
57297
|
fs30.mkdirSync(swarmDir, { recursive: true });
|
|
57050
57298
|
fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
57051
57299
|
`, { flag: "wx" });
|
|
@@ -57787,24 +58035,24 @@ function validateAliases() {
|
|
|
57787
58035
|
}
|
|
57788
58036
|
aliasTargets.get(target).push(name);
|
|
57789
58037
|
const visited = new Set;
|
|
57790
|
-
const
|
|
58038
|
+
const path55 = [];
|
|
57791
58039
|
let current = target;
|
|
57792
58040
|
while (current) {
|
|
57793
58041
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
57794
58042
|
if (!currentEntry)
|
|
57795
58043
|
break;
|
|
57796
58044
|
if (visited.has(current)) {
|
|
57797
|
-
const cycleStart =
|
|
58045
|
+
const cycleStart = path55.indexOf(current);
|
|
57798
58046
|
const fullChain = [
|
|
57799
58047
|
name,
|
|
57800
|
-
...
|
|
58048
|
+
...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
|
|
57801
58049
|
current
|
|
57802
58050
|
].join(" \u2192 ");
|
|
57803
58051
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
57804
58052
|
break;
|
|
57805
58053
|
}
|
|
57806
58054
|
visited.add(current);
|
|
57807
|
-
|
|
58055
|
+
path55.push(current);
|
|
57808
58056
|
current = currentEntry.aliasOf || "";
|
|
57809
58057
|
}
|
|
57810
58058
|
}
|
|
@@ -58402,53 +58650,53 @@ init_cache_paths();
|
|
|
58402
58650
|
init_constants();
|
|
58403
58651
|
import * as fs31 from "fs";
|
|
58404
58652
|
import * as os8 from "os";
|
|
58405
|
-
import * as
|
|
58406
|
-
var { version:
|
|
58653
|
+
import * as path55 from "path";
|
|
58654
|
+
var { version: version5 } = package_default;
|
|
58407
58655
|
var CONFIG_DIR = getPluginConfigDir();
|
|
58408
|
-
var OPENCODE_CONFIG_PATH =
|
|
58409
|
-
var PLUGIN_CONFIG_PATH =
|
|
58410
|
-
var PROMPTS_DIR =
|
|
58656
|
+
var OPENCODE_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode.json");
|
|
58657
|
+
var PLUGIN_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode-swarm.json");
|
|
58658
|
+
var PROMPTS_DIR = path55.join(CONFIG_DIR, "opencode-swarm");
|
|
58411
58659
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
58412
58660
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
58413
58661
|
function isSafeCachePath(p) {
|
|
58414
|
-
const resolved =
|
|
58415
|
-
const home =
|
|
58662
|
+
const resolved = path55.resolve(p);
|
|
58663
|
+
const home = path55.resolve(os8.homedir());
|
|
58416
58664
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
58417
58665
|
return false;
|
|
58418
58666
|
}
|
|
58419
|
-
const segments = resolved.split(
|
|
58667
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
58420
58668
|
if (segments.length < 4) {
|
|
58421
58669
|
return false;
|
|
58422
58670
|
}
|
|
58423
|
-
const leaf =
|
|
58671
|
+
const leaf = path55.basename(resolved);
|
|
58424
58672
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
58425
58673
|
return false;
|
|
58426
58674
|
}
|
|
58427
|
-
const parent =
|
|
58675
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
58428
58676
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
58429
58677
|
return false;
|
|
58430
58678
|
}
|
|
58431
|
-
const grandparent =
|
|
58679
|
+
const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
|
|
58432
58680
|
if (grandparent !== "opencode") {
|
|
58433
58681
|
return false;
|
|
58434
58682
|
}
|
|
58435
58683
|
return true;
|
|
58436
58684
|
}
|
|
58437
58685
|
function isSafeLockFilePath(p) {
|
|
58438
|
-
const resolved =
|
|
58439
|
-
const home =
|
|
58686
|
+
const resolved = path55.resolve(p);
|
|
58687
|
+
const home = path55.resolve(os8.homedir());
|
|
58440
58688
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
58441
58689
|
return false;
|
|
58442
58690
|
}
|
|
58443
|
-
const segments = resolved.split(
|
|
58691
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
58444
58692
|
if (segments.length < 4) {
|
|
58445
58693
|
return false;
|
|
58446
58694
|
}
|
|
58447
|
-
const leaf =
|
|
58695
|
+
const leaf = path55.basename(resolved);
|
|
58448
58696
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
58449
58697
|
return false;
|
|
58450
58698
|
}
|
|
58451
|
-
const parent =
|
|
58699
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
58452
58700
|
if (parent !== "opencode") {
|
|
58453
58701
|
return false;
|
|
58454
58702
|
}
|
|
@@ -58474,8 +58722,8 @@ function saveJson(filepath, data) {
|
|
|
58474
58722
|
}
|
|
58475
58723
|
function writeProjectConfigIfMissing(cwd) {
|
|
58476
58724
|
try {
|
|
58477
|
-
const opencodeDir =
|
|
58478
|
-
const projectConfigPath =
|
|
58725
|
+
const opencodeDir = path55.join(cwd, ".opencode");
|
|
58726
|
+
const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
|
|
58479
58727
|
if (fs31.existsSync(projectConfigPath)) {
|
|
58480
58728
|
return;
|
|
58481
58729
|
}
|
|
@@ -58492,7 +58740,7 @@ async function install() {
|
|
|
58492
58740
|
`);
|
|
58493
58741
|
ensureDir(CONFIG_DIR);
|
|
58494
58742
|
ensureDir(PROMPTS_DIR);
|
|
58495
|
-
const LEGACY_CONFIG_PATH =
|
|
58743
|
+
const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
|
|
58496
58744
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
58497
58745
|
if (!opencodeConfig) {
|
|
58498
58746
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|
|
@@ -58767,7 +59015,7 @@ Examples:
|
|
|
58767
59015
|
async function main() {
|
|
58768
59016
|
const args = process.argv.slice(2);
|
|
58769
59017
|
if (args.includes("-v") || args.includes("--version")) {
|
|
58770
|
-
console.log(`opencode-swarm ${
|
|
59018
|
+
console.log(`opencode-swarm ${version5}`);
|
|
58771
59019
|
process.exit(0);
|
|
58772
59020
|
}
|
|
58773
59021
|
if (args.includes("-h") || args.includes("--help")) {
|