opencode-swarm 7.43.1 → 7.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +594 -377
- 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 +2020 -1447
- 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.0",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
|
@@ -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,7 +51525,7 @@ 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
|
}
|
|
@@ -51329,8 +51546,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
51329
51546
|
if (!importPath.startsWith(".")) {
|
|
51330
51547
|
return null;
|
|
51331
51548
|
}
|
|
51332
|
-
const resolved =
|
|
51333
|
-
if (
|
|
51549
|
+
const resolved = path41.resolve(fromDir, importPath);
|
|
51550
|
+
if (path41.extname(resolved)) {
|
|
51334
51551
|
if (fs19.existsSync(resolved) && fs19.statSync(resolved).isFile()) {
|
|
51335
51552
|
return normalizePath(resolved);
|
|
51336
51553
|
}
|
|
@@ -51350,20 +51567,20 @@ function resolvePythonImport(fromDir, module) {
|
|
|
51350
51567
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
51351
51568
|
let baseDir = fromDir;
|
|
51352
51569
|
for (let i = 1;i < leadingDots; i++) {
|
|
51353
|
-
baseDir =
|
|
51570
|
+
baseDir = path41.dirname(baseDir);
|
|
51354
51571
|
}
|
|
51355
51572
|
const rest = module.slice(leadingDots);
|
|
51356
51573
|
if (rest.length === 0) {
|
|
51357
|
-
const initPath =
|
|
51574
|
+
const initPath = path41.join(baseDir, "__init__.py");
|
|
51358
51575
|
if (fs19.existsSync(initPath) && fs19.statSync(initPath).isFile()) {
|
|
51359
51576
|
return normalizePath(initPath);
|
|
51360
51577
|
}
|
|
51361
51578
|
return null;
|
|
51362
51579
|
}
|
|
51363
|
-
const subpath = rest.replace(/\./g,
|
|
51580
|
+
const subpath = rest.replace(/\./g, path41.sep);
|
|
51364
51581
|
const candidates = [
|
|
51365
|
-
`${
|
|
51366
|
-
|
|
51582
|
+
`${path41.join(baseDir, subpath)}.py`,
|
|
51583
|
+
path41.join(baseDir, subpath, "__init__.py")
|
|
51367
51584
|
];
|
|
51368
51585
|
for (const c of candidates) {
|
|
51369
51586
|
if (fs19.existsSync(c) && fs19.statSync(c).isFile())
|
|
@@ -51372,7 +51589,7 @@ function resolvePythonImport(fromDir, module) {
|
|
|
51372
51589
|
return null;
|
|
51373
51590
|
}
|
|
51374
51591
|
function findGoModule(fromDir) {
|
|
51375
|
-
const resolved =
|
|
51592
|
+
const resolved = path41.resolve(fromDir);
|
|
51376
51593
|
let cur = resolved;
|
|
51377
51594
|
const walked = [];
|
|
51378
51595
|
for (let i = 0;i < 16; i++) {
|
|
@@ -51384,7 +51601,7 @@ function findGoModule(fromDir) {
|
|
|
51384
51601
|
}
|
|
51385
51602
|
walked.push(cur);
|
|
51386
51603
|
try {
|
|
51387
|
-
const goMod =
|
|
51604
|
+
const goMod = path41.join(cur, "go.mod");
|
|
51388
51605
|
const content = fs19.readFileSync(goMod, "utf-8");
|
|
51389
51606
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
51390
51607
|
if (moduleMatch) {
|
|
@@ -51395,10 +51612,10 @@ function findGoModule(fromDir) {
|
|
|
51395
51612
|
}
|
|
51396
51613
|
} catch {}
|
|
51397
51614
|
try {
|
|
51398
|
-
fs19.accessSync(
|
|
51615
|
+
fs19.accessSync(path41.join(cur, ".git"));
|
|
51399
51616
|
break;
|
|
51400
51617
|
} catch {}
|
|
51401
|
-
const parent =
|
|
51618
|
+
const parent = path41.dirname(cur);
|
|
51402
51619
|
if (parent === cur)
|
|
51403
51620
|
break;
|
|
51404
51621
|
cur = parent;
|
|
@@ -51410,12 +51627,12 @@ function findGoModule(fromDir) {
|
|
|
51410
51627
|
function resolveGoImport(fromDir, importPath) {
|
|
51411
51628
|
let dir = null;
|
|
51412
51629
|
if (importPath.startsWith(".")) {
|
|
51413
|
-
dir =
|
|
51630
|
+
dir = path41.resolve(fromDir, importPath);
|
|
51414
51631
|
} else {
|
|
51415
51632
|
const mod = findGoModule(fromDir);
|
|
51416
51633
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
51417
51634
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
51418
|
-
dir =
|
|
51635
|
+
dir = path41.join(mod.moduleRoot, subpath);
|
|
51419
51636
|
}
|
|
51420
51637
|
}
|
|
51421
51638
|
if (dir === null)
|
|
@@ -51423,7 +51640,7 @@ function resolveGoImport(fromDir, importPath) {
|
|
|
51423
51640
|
if (!fs19.existsSync(dir) || !fs19.statSync(dir).isDirectory())
|
|
51424
51641
|
return [];
|
|
51425
51642
|
try {
|
|
51426
|
-
return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(
|
|
51643
|
+
return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path41.join(dir, f)));
|
|
51427
51644
|
} catch {
|
|
51428
51645
|
return [];
|
|
51429
51646
|
}
|
|
@@ -51462,15 +51679,15 @@ function findTestFilesSync(cwd) {
|
|
|
51462
51679
|
for (const entry of entries) {
|
|
51463
51680
|
if (entry.isDirectory()) {
|
|
51464
51681
|
if (!skipDirs.has(entry.name)) {
|
|
51465
|
-
walk(
|
|
51682
|
+
walk(path41.join(dir, entry.name), visitedInodes);
|
|
51466
51683
|
}
|
|
51467
51684
|
} else if (entry.isFile()) {
|
|
51468
51685
|
const name = entry.name;
|
|
51469
51686
|
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(`${
|
|
51687
|
+
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path41.sep}tests${path41.sep}`) && name.endsWith(".py");
|
|
51471
51688
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
51472
51689
|
if (isTsTest || isPyTest || isGoTest) {
|
|
51473
|
-
testFiles.push(normalizePath(
|
|
51690
|
+
testFiles.push(normalizePath(path41.join(dir, entry.name)));
|
|
51474
51691
|
}
|
|
51475
51692
|
}
|
|
51476
51693
|
}
|
|
@@ -51495,8 +51712,8 @@ function extractImports3(content) {
|
|
|
51495
51712
|
];
|
|
51496
51713
|
}
|
|
51497
51714
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
51498
|
-
const ext =
|
|
51499
|
-
const testDir =
|
|
51715
|
+
const ext = path41.extname(testFile).toLowerCase();
|
|
51716
|
+
const testDir = path41.dirname(testFile);
|
|
51500
51717
|
function addEdge(source) {
|
|
51501
51718
|
if (!impactMap[source])
|
|
51502
51719
|
impactMap[source] = [];
|
|
@@ -51555,7 +51772,7 @@ async function buildImpactMap(cwd) {
|
|
|
51555
51772
|
return impactMap;
|
|
51556
51773
|
}
|
|
51557
51774
|
async function loadImpactMap(cwd, options) {
|
|
51558
|
-
const cachePath =
|
|
51775
|
+
const cachePath = path41.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
51559
51776
|
if (fs19.existsSync(cachePath)) {
|
|
51560
51777
|
try {
|
|
51561
51778
|
const content = fs19.readFileSync(cachePath, "utf-8");
|
|
@@ -51588,12 +51805,12 @@ async function loadImpactMap(cwd, options) {
|
|
|
51588
51805
|
return _internals25.buildImpactMap(cwd);
|
|
51589
51806
|
}
|
|
51590
51807
|
async function saveImpactMap(cwd, impactMap) {
|
|
51591
|
-
if (!
|
|
51808
|
+
if (!path41.isAbsolute(cwd)) {
|
|
51592
51809
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
51593
51810
|
}
|
|
51594
51811
|
_internals25.validateProjectRoot(cwd);
|
|
51595
|
-
const cacheDir2 =
|
|
51596
|
-
const cachePath =
|
|
51812
|
+
const cacheDir2 = path41.join(cwd, ".swarm", "cache");
|
|
51813
|
+
const cachePath = path41.join(cacheDir2, "impact-map.json");
|
|
51597
51814
|
if (!fs19.existsSync(cacheDir2)) {
|
|
51598
51815
|
fs19.mkdirSync(cacheDir2, { recursive: true });
|
|
51599
51816
|
}
|
|
@@ -51625,7 +51842,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
51625
51842
|
budgetExceeded = true;
|
|
51626
51843
|
break;
|
|
51627
51844
|
}
|
|
51628
|
-
const normalizedChanged = normalizePath(
|
|
51845
|
+
const normalizedChanged = normalizePath(path41.resolve(changedFile));
|
|
51629
51846
|
const tests = impactMap[normalizedChanged];
|
|
51630
51847
|
if (tests && tests.length > 0) {
|
|
51631
51848
|
for (const test of tests) {
|
|
@@ -51918,15 +52135,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
|
|
|
51918
52135
|
|
|
51919
52136
|
// src/test-impact/history-store.ts
|
|
51920
52137
|
import fs20 from "fs";
|
|
51921
|
-
import
|
|
52138
|
+
import path42 from "path";
|
|
51922
52139
|
function getHistoryPath(workingDir) {
|
|
51923
52140
|
if (!workingDir) {
|
|
51924
52141
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
51925
52142
|
}
|
|
51926
|
-
if (!
|
|
52143
|
+
if (!path42.isAbsolute(workingDir)) {
|
|
51927
52144
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
51928
52145
|
}
|
|
51929
|
-
return
|
|
52146
|
+
return path42.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
51930
52147
|
}
|
|
51931
52148
|
function sanitizeErrorMessage(errorMessage) {
|
|
51932
52149
|
if (errorMessage === undefined) {
|
|
@@ -52013,7 +52230,7 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
52013
52230
|
}
|
|
52014
52231
|
}
|
|
52015
52232
|
const historyPath = getHistoryPath(workingDir);
|
|
52016
|
-
const historyDir =
|
|
52233
|
+
const historyDir = path42.dirname(historyPath);
|
|
52017
52234
|
_internals26.validateProjectRoot(workingDir);
|
|
52018
52235
|
if (!fs20.existsSync(historyDir)) {
|
|
52019
52236
|
fs20.mkdirSync(historyDir, { recursive: true });
|
|
@@ -52109,7 +52326,7 @@ var init_history_store = __esm(() => {
|
|
|
52109
52326
|
|
|
52110
52327
|
// src/tools/resolve-working-directory.ts
|
|
52111
52328
|
import * as fs21 from "fs";
|
|
52112
|
-
import * as
|
|
52329
|
+
import * as path43 from "path";
|
|
52113
52330
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
52114
52331
|
if (workingDirectory == null || workingDirectory === "") {
|
|
52115
52332
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -52129,15 +52346,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52129
52346
|
};
|
|
52130
52347
|
}
|
|
52131
52348
|
}
|
|
52132
|
-
const normalizedDir =
|
|
52133
|
-
const pathParts = normalizedDir.split(
|
|
52349
|
+
const normalizedDir = path43.normalize(workingDirectory);
|
|
52350
|
+
const pathParts = normalizedDir.split(path43.sep);
|
|
52134
52351
|
if (pathParts.includes("..")) {
|
|
52135
52352
|
return {
|
|
52136
52353
|
success: false,
|
|
52137
52354
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
52138
52355
|
};
|
|
52139
52356
|
}
|
|
52140
|
-
const resolvedDir =
|
|
52357
|
+
const resolvedDir = path43.resolve(normalizedDir);
|
|
52141
52358
|
let statResult;
|
|
52142
52359
|
try {
|
|
52143
52360
|
statResult = fs21.statSync(resolvedDir);
|
|
@@ -52153,7 +52370,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52153
52370
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
52154
52371
|
};
|
|
52155
52372
|
}
|
|
52156
|
-
const resolvedFallback =
|
|
52373
|
+
const resolvedFallback = path43.resolve(fallbackDirectory);
|
|
52157
52374
|
let fallbackExists = false;
|
|
52158
52375
|
try {
|
|
52159
52376
|
fs21.statSync(resolvedFallback);
|
|
@@ -52163,7 +52380,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52163
52380
|
}
|
|
52164
52381
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
52165
52382
|
if (fallbackExists) {
|
|
52166
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
52383
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path43.sep);
|
|
52167
52384
|
if (isSubdirectory) {
|
|
52168
52385
|
return {
|
|
52169
52386
|
success: false,
|
|
@@ -52218,10 +52435,10 @@ var init_registry_backend = __esm(() => {
|
|
|
52218
52435
|
|
|
52219
52436
|
// src/lang/backends/typescript.ts
|
|
52220
52437
|
import * as fs22 from "fs";
|
|
52221
|
-
import * as
|
|
52438
|
+
import * as path44 from "path";
|
|
52222
52439
|
function readPackageJsonRaw(dir) {
|
|
52223
52440
|
try {
|
|
52224
|
-
const content = fs22.readFileSync(
|
|
52441
|
+
const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
|
|
52225
52442
|
return JSON.parse(content);
|
|
52226
52443
|
} catch {
|
|
52227
52444
|
return null;
|
|
@@ -52441,7 +52658,7 @@ __export(exports_dispatch, {
|
|
|
52441
52658
|
_internals: () => _internals28
|
|
52442
52659
|
});
|
|
52443
52660
|
import * as fs23 from "fs";
|
|
52444
|
-
import * as
|
|
52661
|
+
import * as path45 from "path";
|
|
52445
52662
|
function safeReaddirSet(dir) {
|
|
52446
52663
|
try {
|
|
52447
52664
|
return new Set(fs23.readdirSync(dir));
|
|
@@ -52458,14 +52675,14 @@ function manifestHash(dir) {
|
|
|
52458
52675
|
if (!entries.has(name))
|
|
52459
52676
|
continue;
|
|
52460
52677
|
try {
|
|
52461
|
-
const stat4 = fs23.statSync(
|
|
52678
|
+
const stat4 = fs23.statSync(path45.join(dir, name));
|
|
52462
52679
|
parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
|
|
52463
52680
|
} catch {}
|
|
52464
52681
|
}
|
|
52465
52682
|
return parts.join("|");
|
|
52466
52683
|
}
|
|
52467
52684
|
function findManifestRoot(start) {
|
|
52468
|
-
const resolved =
|
|
52685
|
+
const resolved = path45.resolve(start);
|
|
52469
52686
|
const cached3 = manifestRootCache.get(resolved);
|
|
52470
52687
|
if (cached3 !== undefined)
|
|
52471
52688
|
return cached3;
|
|
@@ -52484,7 +52701,7 @@ function findManifestRoot(start) {
|
|
|
52484
52701
|
return cur;
|
|
52485
52702
|
}
|
|
52486
52703
|
}
|
|
52487
|
-
const parent =
|
|
52704
|
+
const parent = path45.dirname(cur);
|
|
52488
52705
|
if (parent === cur)
|
|
52489
52706
|
break;
|
|
52490
52707
|
cur = parent;
|
|
@@ -52594,13 +52811,13 @@ var init_dispatch = __esm(() => {
|
|
|
52594
52811
|
|
|
52595
52812
|
// src/tools/test-runner.ts
|
|
52596
52813
|
import * as fs24 from "fs";
|
|
52597
|
-
import * as
|
|
52814
|
+
import * as path46 from "path";
|
|
52598
52815
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
52599
52816
|
try {
|
|
52600
52817
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
52601
52818
|
const uniqueTestFiles = new Set;
|
|
52602
52819
|
for (const sourceFile of sourceFiles) {
|
|
52603
|
-
const resolvedPath =
|
|
52820
|
+
const resolvedPath = path46.resolve(cwd, sourceFile);
|
|
52604
52821
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
52605
52822
|
const testFiles = impactMap[normalizedPath];
|
|
52606
52823
|
if (testFiles) {
|
|
@@ -52678,14 +52895,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
52678
52895
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
52679
52896
|
}
|
|
52680
52897
|
function detectGoTest(cwd) {
|
|
52681
|
-
return fs24.existsSync(
|
|
52898
|
+
return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
52682
52899
|
}
|
|
52683
52900
|
function detectJavaMaven(cwd) {
|
|
52684
|
-
return fs24.existsSync(
|
|
52901
|
+
return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
52685
52902
|
}
|
|
52686
52903
|
function detectGradle(cwd) {
|
|
52687
|
-
const hasBuildFile = fs24.existsSync(
|
|
52688
|
-
const hasGradlew = fs24.existsSync(
|
|
52904
|
+
const hasBuildFile = fs24.existsSync(path46.join(cwd, "build.gradle")) || fs24.existsSync(path46.join(cwd, "build.gradle.kts"));
|
|
52905
|
+
const hasGradlew = fs24.existsSync(path46.join(cwd, "gradlew")) || fs24.existsSync(path46.join(cwd, "gradlew.bat"));
|
|
52689
52906
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
52690
52907
|
}
|
|
52691
52908
|
function detectDotnetTest(cwd) {
|
|
@@ -52698,25 +52915,25 @@ function detectDotnetTest(cwd) {
|
|
|
52698
52915
|
}
|
|
52699
52916
|
}
|
|
52700
52917
|
function detectCTest(cwd) {
|
|
52701
|
-
const hasSource = fs24.existsSync(
|
|
52702
|
-
const hasBuildCache = fs24.existsSync(
|
|
52918
|
+
const hasSource = fs24.existsSync(path46.join(cwd, "CMakeLists.txt"));
|
|
52919
|
+
const hasBuildCache = fs24.existsSync(path46.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path46.join(cwd, "build", "CMakeCache.txt"));
|
|
52703
52920
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
52704
52921
|
}
|
|
52705
52922
|
function detectSwiftTest(cwd) {
|
|
52706
|
-
return fs24.existsSync(
|
|
52923
|
+
return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
52707
52924
|
}
|
|
52708
52925
|
function detectDartTest(cwd) {
|
|
52709
|
-
return fs24.existsSync(
|
|
52926
|
+
return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
52710
52927
|
}
|
|
52711
52928
|
function detectRSpec(cwd) {
|
|
52712
|
-
const hasRSpecFile = fs24.existsSync(
|
|
52713
|
-
const hasGemfile = fs24.existsSync(
|
|
52714
|
-
const hasSpecDir = fs24.existsSync(
|
|
52929
|
+
const hasRSpecFile = fs24.existsSync(path46.join(cwd, ".rspec"));
|
|
52930
|
+
const hasGemfile = fs24.existsSync(path46.join(cwd, "Gemfile"));
|
|
52931
|
+
const hasSpecDir = fs24.existsSync(path46.join(cwd, "spec"));
|
|
52715
52932
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
52716
52933
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
52717
52934
|
}
|
|
52718
52935
|
function detectMinitest(cwd) {
|
|
52719
|
-
return fs24.existsSync(
|
|
52936
|
+
return fs24.existsSync(path46.join(cwd, "test")) && (fs24.existsSync(path46.join(cwd, "Gemfile")) || fs24.existsSync(path46.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
52720
52937
|
}
|
|
52721
52938
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
52722
52939
|
try {
|
|
@@ -52778,7 +52995,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
52778
52995
|
async function detectTestFramework(cwd) {
|
|
52779
52996
|
const baseDir = cwd;
|
|
52780
52997
|
try {
|
|
52781
|
-
const packageJsonPath =
|
|
52998
|
+
const packageJsonPath = path46.join(baseDir, "package.json");
|
|
52782
52999
|
if (fs24.existsSync(packageJsonPath)) {
|
|
52783
53000
|
const content = fs24.readFileSync(packageJsonPath, "utf-8");
|
|
52784
53001
|
const pkg = JSON.parse(content);
|
|
@@ -52799,16 +53016,16 @@ async function detectTestFramework(cwd) {
|
|
|
52799
53016
|
return "jest";
|
|
52800
53017
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
52801
53018
|
return "mocha";
|
|
52802
|
-
if (fs24.existsSync(
|
|
53019
|
+
if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
|
|
52803
53020
|
if (scripts.test?.includes("bun"))
|
|
52804
53021
|
return "bun";
|
|
52805
53022
|
}
|
|
52806
53023
|
}
|
|
52807
53024
|
} catch {}
|
|
52808
53025
|
try {
|
|
52809
|
-
const pyprojectTomlPath =
|
|
52810
|
-
const setupCfgPath =
|
|
52811
|
-
const requirementsTxtPath =
|
|
53026
|
+
const pyprojectTomlPath = path46.join(baseDir, "pyproject.toml");
|
|
53027
|
+
const setupCfgPath = path46.join(baseDir, "setup.cfg");
|
|
53028
|
+
const requirementsTxtPath = path46.join(baseDir, "requirements.txt");
|
|
52812
53029
|
if (fs24.existsSync(pyprojectTomlPath)) {
|
|
52813
53030
|
const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
|
|
52814
53031
|
if (content.includes("[tool.pytest"))
|
|
@@ -52828,7 +53045,7 @@ async function detectTestFramework(cwd) {
|
|
|
52828
53045
|
}
|
|
52829
53046
|
} catch {}
|
|
52830
53047
|
try {
|
|
52831
|
-
const cargoTomlPath =
|
|
53048
|
+
const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
|
|
52832
53049
|
if (fs24.existsSync(cargoTomlPath)) {
|
|
52833
53050
|
const content = fs24.readFileSync(cargoTomlPath, "utf-8");
|
|
52834
53051
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -52839,9 +53056,9 @@ async function detectTestFramework(cwd) {
|
|
|
52839
53056
|
}
|
|
52840
53057
|
} catch {}
|
|
52841
53058
|
try {
|
|
52842
|
-
const pesterConfigPath =
|
|
52843
|
-
const pesterConfigJsonPath =
|
|
52844
|
-
const pesterPs1Path =
|
|
53059
|
+
const pesterConfigPath = path46.join(baseDir, "pester.config.ps1");
|
|
53060
|
+
const pesterConfigJsonPath = path46.join(baseDir, "pester.config.ps1.json");
|
|
53061
|
+
const pesterPs1Path = path46.join(baseDir, "tests.ps1");
|
|
52845
53062
|
if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
|
|
52846
53063
|
return "pester";
|
|
52847
53064
|
}
|
|
@@ -52870,12 +53087,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
52870
53087
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
52871
53088
|
}
|
|
52872
53089
|
function resolveWorkspacePath(file3, workingDir) {
|
|
52873
|
-
return
|
|
53090
|
+
return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
|
|
52874
53091
|
}
|
|
52875
53092
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
52876
53093
|
if (!preferRelative)
|
|
52877
53094
|
return absolutePath;
|
|
52878
|
-
return
|
|
53095
|
+
return path46.relative(workingDir, absolutePath);
|
|
52879
53096
|
}
|
|
52880
53097
|
function dedupePush(target, value) {
|
|
52881
53098
|
if (!target.includes(value)) {
|
|
@@ -52912,18 +53129,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
52912
53129
|
}
|
|
52913
53130
|
}
|
|
52914
53131
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
52915
|
-
const relativeDir =
|
|
53132
|
+
const relativeDir = path46.dirname(relativePath);
|
|
52916
53133
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
52917
53134
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
52918
|
-
const rootDir =
|
|
52919
|
-
return nestedRelativeDir ? [rootDir,
|
|
53135
|
+
const rootDir = path46.join(workingDir, dirName);
|
|
53136
|
+
return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
52920
53137
|
});
|
|
52921
53138
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
52922
53139
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
52923
|
-
directories.push(
|
|
53140
|
+
directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
52924
53141
|
}
|
|
52925
53142
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
52926
|
-
directories.push(
|
|
53143
|
+
directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
52927
53144
|
}
|
|
52928
53145
|
return [...new Set(directories)];
|
|
52929
53146
|
}
|
|
@@ -52951,23 +53168,23 @@ function isLanguageSpecificTestFile(basename7) {
|
|
|
52951
53168
|
}
|
|
52952
53169
|
function isConventionTestFilePath(filePath) {
|
|
52953
53170
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
52954
|
-
const basename7 =
|
|
53171
|
+
const basename7 = path46.basename(filePath);
|
|
52955
53172
|
return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
|
|
52956
53173
|
}
|
|
52957
53174
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
52958
53175
|
const testFiles = [];
|
|
52959
53176
|
for (const file3 of sourceFiles) {
|
|
52960
53177
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
52961
|
-
const relativeFile =
|
|
52962
|
-
const basename7 =
|
|
52963
|
-
const
|
|
52964
|
-
const preferRelativeOutput = !
|
|
53178
|
+
const relativeFile = path46.relative(workingDir, absoluteFile);
|
|
53179
|
+
const basename7 = path46.basename(absoluteFile);
|
|
53180
|
+
const dirname23 = path46.dirname(absoluteFile);
|
|
53181
|
+
const preferRelativeOutput = !path46.isAbsolute(file3);
|
|
52965
53182
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
52966
53183
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
52967
53184
|
continue;
|
|
52968
53185
|
}
|
|
52969
53186
|
const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
|
|
52970
|
-
const ext =
|
|
53187
|
+
const ext = path46.extname(basename7);
|
|
52971
53188
|
const genericTestNames = [
|
|
52972
53189
|
`${nameWithoutExt}.spec${ext}`,
|
|
52973
53190
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -52976,7 +53193,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
52976
53193
|
const colocatedCandidates = [
|
|
52977
53194
|
...genericTestNames,
|
|
52978
53195
|
...languageSpecificTestNames
|
|
52979
|
-
].map((candidateName) =>
|
|
53196
|
+
].map((candidateName) => path46.join(dirname23, candidateName));
|
|
52980
53197
|
const testDirectoryNames = [
|
|
52981
53198
|
basename7,
|
|
52982
53199
|
...genericTestNames,
|
|
@@ -52985,8 +53202,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
52985
53202
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
52986
53203
|
const possibleTestFiles = [
|
|
52987
53204
|
...colocatedCandidates,
|
|
52988
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
52989
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
53205
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path46.join(dirname23, dirName, candidateName))),
|
|
53206
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path46.join(candidateDir, candidateName)))
|
|
52990
53207
|
];
|
|
52991
53208
|
for (const testFile of possibleTestFiles) {
|
|
52992
53209
|
if (fs24.existsSync(testFile)) {
|
|
@@ -53007,7 +53224,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53007
53224
|
try {
|
|
53008
53225
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
53009
53226
|
const content = fs24.readFileSync(absoluteTestFile, "utf-8");
|
|
53010
|
-
const testDir =
|
|
53227
|
+
const testDir = path46.dirname(absoluteTestFile);
|
|
53011
53228
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
53012
53229
|
let match;
|
|
53013
53230
|
match = importRegex.exec(content);
|
|
@@ -53015,8 +53232,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53015
53232
|
const importPath = match[1];
|
|
53016
53233
|
let resolvedImport;
|
|
53017
53234
|
if (importPath.startsWith(".")) {
|
|
53018
|
-
resolvedImport =
|
|
53019
|
-
const existingExt =
|
|
53235
|
+
resolvedImport = path46.resolve(testDir, importPath);
|
|
53236
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53020
53237
|
if (!existingExt) {
|
|
53021
53238
|
for (const extToTry of [
|
|
53022
53239
|
".ts",
|
|
@@ -53036,12 +53253,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53036
53253
|
} else {
|
|
53037
53254
|
continue;
|
|
53038
53255
|
}
|
|
53039
|
-
const importBasename =
|
|
53040
|
-
const importDir =
|
|
53256
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
53257
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53041
53258
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53042
|
-
const sourceDir =
|
|
53043
|
-
const sourceBasename =
|
|
53044
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
53259
|
+
const sourceDir = path46.dirname(sourceFile);
|
|
53260
|
+
const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
|
|
53261
|
+
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
53262
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53046
53263
|
dedupePush(testFiles, testFile);
|
|
53047
53264
|
break;
|
|
@@ -53054,8 +53271,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53054
53271
|
while (match !== null) {
|
|
53055
53272
|
const importPath = match[1];
|
|
53056
53273
|
if (importPath.startsWith(".")) {
|
|
53057
|
-
let resolvedImport =
|
|
53058
|
-
const existingExt =
|
|
53274
|
+
let resolvedImport = path46.resolve(testDir, importPath);
|
|
53275
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53059
53276
|
if (!existingExt) {
|
|
53060
53277
|
for (const extToTry of [
|
|
53061
53278
|
".ts",
|
|
@@ -53072,12 +53289,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53072
53289
|
}
|
|
53073
53290
|
}
|
|
53074
53291
|
}
|
|
53075
|
-
const importDir =
|
|
53076
|
-
const importBasename =
|
|
53292
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53293
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
53077
53294
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53078
|
-
const sourceDir =
|
|
53079
|
-
const sourceBasename =
|
|
53080
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
53295
|
+
const sourceDir = path46.dirname(sourceFile);
|
|
53296
|
+
const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
|
|
53297
|
+
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
53298
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53082
53299
|
dedupePush(testFiles, testFile);
|
|
53083
53300
|
break;
|
|
@@ -53187,8 +53404,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53187
53404
|
return ["mvn", "test"];
|
|
53188
53405
|
case "gradle": {
|
|
53189
53406
|
const isWindows = process.platform === "win32";
|
|
53190
|
-
const hasGradlewBat = fs24.existsSync(
|
|
53191
|
-
const hasGradlew = fs24.existsSync(
|
|
53407
|
+
const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
|
|
53408
|
+
const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
|
|
53192
53409
|
if (hasGradlewBat && isWindows)
|
|
53193
53410
|
return ["gradlew.bat", "test"];
|
|
53194
53411
|
if (hasGradlew)
|
|
@@ -53205,7 +53422,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53205
53422
|
"cmake-build-release",
|
|
53206
53423
|
"out"
|
|
53207
53424
|
];
|
|
53208
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(
|
|
53425
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
53209
53426
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
53210
53427
|
}
|
|
53211
53428
|
case "swift-test":
|
|
@@ -53637,11 +53854,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
53637
53854
|
};
|
|
53638
53855
|
}
|
|
53639
53856
|
const startTime = Date.now();
|
|
53640
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
53857
|
+
const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
53641
53858
|
try {
|
|
53642
53859
|
if (vitestJsonOutputPath) {
|
|
53643
53860
|
try {
|
|
53644
|
-
fs24.mkdirSync(
|
|
53861
|
+
fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
|
|
53645
53862
|
if (fs24.existsSync(vitestJsonOutputPath)) {
|
|
53646
53863
|
fs24.unlinkSync(vitestJsonOutputPath);
|
|
53647
53864
|
}
|
|
@@ -53757,10 +53974,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
53757
53974
|
}
|
|
53758
53975
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
53759
53976
|
const normalized = testFile.replace(/\\/g, "/");
|
|
53760
|
-
if (!
|
|
53977
|
+
if (!path46.isAbsolute(testFile))
|
|
53761
53978
|
return normalized;
|
|
53762
|
-
const relative9 =
|
|
53763
|
-
if (relative9.startsWith("..") ||
|
|
53979
|
+
const relative9 = path46.relative(workingDir, testFile);
|
|
53980
|
+
if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
|
|
53764
53981
|
return normalized;
|
|
53765
53982
|
}
|
|
53766
53983
|
return relative9.replace(/\\/g, "/");
|
|
@@ -54098,7 +54315,7 @@ var init_test_runner = __esm(() => {
|
|
|
54098
54315
|
const sourceFiles = args.files.filter((file3) => {
|
|
54099
54316
|
if (directTestFiles.includes(file3))
|
|
54100
54317
|
return false;
|
|
54101
|
-
const ext =
|
|
54318
|
+
const ext = path46.extname(file3).toLowerCase();
|
|
54102
54319
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54103
54320
|
});
|
|
54104
54321
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -54144,7 +54361,7 @@ var init_test_runner = __esm(() => {
|
|
|
54144
54361
|
if (isConventionTestFilePath(f)) {
|
|
54145
54362
|
return false;
|
|
54146
54363
|
}
|
|
54147
|
-
const ext =
|
|
54364
|
+
const ext = path46.extname(f).toLowerCase();
|
|
54148
54365
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54149
54366
|
});
|
|
54150
54367
|
if (sourceFiles.length === 0) {
|
|
@@ -54194,7 +54411,7 @@ var init_test_runner = __esm(() => {
|
|
|
54194
54411
|
if (isConventionTestFilePath(f)) {
|
|
54195
54412
|
return false;
|
|
54196
54413
|
}
|
|
54197
|
-
const ext =
|
|
54414
|
+
const ext = path46.extname(f).toLowerCase();
|
|
54198
54415
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54199
54416
|
});
|
|
54200
54417
|
if (sourceFiles.length === 0) {
|
|
@@ -54246,8 +54463,8 @@ var init_test_runner = __esm(() => {
|
|
|
54246
54463
|
}
|
|
54247
54464
|
if (impactResult.impactedTests.length > 0) {
|
|
54248
54465
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
54249
|
-
const relativePath =
|
|
54250
|
-
return
|
|
54466
|
+
const relativePath = path46.relative(workingDir, absPath);
|
|
54467
|
+
return path46.isAbsolute(relativePath) ? absPath : relativePath;
|
|
54251
54468
|
});
|
|
54252
54469
|
} else {
|
|
54253
54470
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -54323,7 +54540,7 @@ var init_test_runner = __esm(() => {
|
|
|
54323
54540
|
|
|
54324
54541
|
// src/services/preflight-service.ts
|
|
54325
54542
|
import * as fs25 from "fs";
|
|
54326
|
-
import * as
|
|
54543
|
+
import * as path47 from "path";
|
|
54327
54544
|
function validateDirectoryPath(dir) {
|
|
54328
54545
|
if (!dir || typeof dir !== "string") {
|
|
54329
54546
|
throw new Error("Directory path is required");
|
|
@@ -54331,8 +54548,8 @@ function validateDirectoryPath(dir) {
|
|
|
54331
54548
|
if (dir.includes("..")) {
|
|
54332
54549
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
54333
54550
|
}
|
|
54334
|
-
const normalized =
|
|
54335
|
-
const absolutePath =
|
|
54551
|
+
const normalized = path47.normalize(dir);
|
|
54552
|
+
const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
|
|
54336
54553
|
return absolutePath;
|
|
54337
54554
|
}
|
|
54338
54555
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -54355,7 +54572,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
54355
54572
|
}
|
|
54356
54573
|
function getPackageVersion(dir) {
|
|
54357
54574
|
try {
|
|
54358
|
-
const packagePath =
|
|
54575
|
+
const packagePath = path47.join(dir, "package.json");
|
|
54359
54576
|
if (fs25.existsSync(packagePath)) {
|
|
54360
54577
|
const content = fs25.readFileSync(packagePath, "utf-8");
|
|
54361
54578
|
const pkg = JSON.parse(content);
|
|
@@ -54366,7 +54583,7 @@ function getPackageVersion(dir) {
|
|
|
54366
54583
|
}
|
|
54367
54584
|
function getChangelogVersion(dir) {
|
|
54368
54585
|
try {
|
|
54369
|
-
const changelogPath =
|
|
54586
|
+
const changelogPath = path47.join(dir, "CHANGELOG.md");
|
|
54370
54587
|
if (fs25.existsSync(changelogPath)) {
|
|
54371
54588
|
const content = fs25.readFileSync(changelogPath, "utf-8");
|
|
54372
54589
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -54380,7 +54597,7 @@ function getChangelogVersion(dir) {
|
|
|
54380
54597
|
function getVersionFileVersion(dir) {
|
|
54381
54598
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
54382
54599
|
for (const file3 of possibleFiles) {
|
|
54383
|
-
const filePath =
|
|
54600
|
+
const filePath = path47.join(dir, file3);
|
|
54384
54601
|
if (fs25.existsSync(filePath)) {
|
|
54385
54602
|
try {
|
|
54386
54603
|
const content = fs25.readFileSync(filePath, "utf-8").trim();
|
|
@@ -54722,7 +54939,7 @@ async function runEvidenceCheck(dir) {
|
|
|
54722
54939
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
54723
54940
|
const startTime = Date.now();
|
|
54724
54941
|
try {
|
|
54725
|
-
const specPath =
|
|
54942
|
+
const specPath = path47.join(dir, ".swarm", "spec.md");
|
|
54726
54943
|
if (!fs25.existsSync(specPath)) {
|
|
54727
54944
|
return {
|
|
54728
54945
|
type: "req_coverage",
|
|
@@ -55840,7 +56057,7 @@ var init_manager3 = __esm(() => {
|
|
|
55840
56057
|
|
|
55841
56058
|
// src/commands/reset.ts
|
|
55842
56059
|
import * as fs26 from "fs";
|
|
55843
|
-
import * as
|
|
56060
|
+
import * as path48 from "path";
|
|
55844
56061
|
async function handleResetCommand(directory, args) {
|
|
55845
56062
|
const hasConfirm = args.includes("--confirm");
|
|
55846
56063
|
if (!hasConfirm) {
|
|
@@ -55880,7 +56097,7 @@ async function handleResetCommand(directory, args) {
|
|
|
55880
56097
|
}
|
|
55881
56098
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
55882
56099
|
try {
|
|
55883
|
-
const rootPath =
|
|
56100
|
+
const rootPath = path48.join(directory, filename);
|
|
55884
56101
|
if (fs26.existsSync(rootPath)) {
|
|
55885
56102
|
fs26.unlinkSync(rootPath);
|
|
55886
56103
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
@@ -55920,7 +56137,7 @@ var init_reset = __esm(() => {
|
|
|
55920
56137
|
|
|
55921
56138
|
// src/commands/reset-session.ts
|
|
55922
56139
|
import * as fs27 from "fs";
|
|
55923
|
-
import * as
|
|
56140
|
+
import * as path49 from "path";
|
|
55924
56141
|
async function handleResetSessionCommand(directory, _args) {
|
|
55925
56142
|
const results = [];
|
|
55926
56143
|
try {
|
|
@@ -55935,13 +56152,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
55935
56152
|
results.push("\u274C Failed to delete state.json");
|
|
55936
56153
|
}
|
|
55937
56154
|
try {
|
|
55938
|
-
const sessionDir =
|
|
56155
|
+
const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
55939
56156
|
if (fs27.existsSync(sessionDir)) {
|
|
55940
56157
|
const files = fs27.readdirSync(sessionDir);
|
|
55941
56158
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
55942
56159
|
let deletedCount = 0;
|
|
55943
56160
|
for (const file3 of otherFiles) {
|
|
55944
|
-
const filePath =
|
|
56161
|
+
const filePath = path49.join(sessionDir, file3);
|
|
55945
56162
|
if (fs27.lstatSync(filePath).isFile()) {
|
|
55946
56163
|
fs27.unlinkSync(filePath);
|
|
55947
56164
|
deletedCount++;
|
|
@@ -55973,7 +56190,7 @@ var init_reset_session = __esm(() => {
|
|
|
55973
56190
|
});
|
|
55974
56191
|
|
|
55975
56192
|
// src/summaries/manager.ts
|
|
55976
|
-
import * as
|
|
56193
|
+
import * as path50 from "path";
|
|
55977
56194
|
function sanitizeSummaryId(id) {
|
|
55978
56195
|
if (!id || id.length === 0) {
|
|
55979
56196
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -55996,7 +56213,7 @@ function sanitizeSummaryId(id) {
|
|
|
55996
56213
|
}
|
|
55997
56214
|
async function loadFullOutput(directory, id) {
|
|
55998
56215
|
const sanitizedId = sanitizeSummaryId(id);
|
|
55999
|
-
const relativePath =
|
|
56216
|
+
const relativePath = path50.join("summaries", `${sanitizedId}.json`);
|
|
56000
56217
|
validateSwarmPath(directory, relativePath);
|
|
56001
56218
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
56002
56219
|
if (content === null) {
|
|
@@ -56059,7 +56276,7 @@ var init_retrieve = __esm(() => {
|
|
|
56059
56276
|
|
|
56060
56277
|
// src/commands/rollback.ts
|
|
56061
56278
|
import * as fs28 from "fs";
|
|
56062
|
-
import * as
|
|
56279
|
+
import * as path51 from "path";
|
|
56063
56280
|
async function handleRollbackCommand(directory, args) {
|
|
56064
56281
|
const phaseArg = args[0];
|
|
56065
56282
|
if (!phaseArg) {
|
|
@@ -56124,8 +56341,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
56124
56341
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
56125
56342
|
continue;
|
|
56126
56343
|
}
|
|
56127
|
-
const src =
|
|
56128
|
-
const dest =
|
|
56344
|
+
const src = path51.join(checkpointDir, file3);
|
|
56345
|
+
const dest = path51.join(swarmDir, file3);
|
|
56129
56346
|
try {
|
|
56130
56347
|
fs28.cpSync(src, dest, { recursive: true, force: true });
|
|
56131
56348
|
successes.push(file3);
|
|
@@ -56144,12 +56361,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
56144
56361
|
].join(`
|
|
56145
56362
|
`);
|
|
56146
56363
|
}
|
|
56147
|
-
const existingLedgerPath =
|
|
56364
|
+
const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
|
|
56148
56365
|
if (fs28.existsSync(existingLedgerPath)) {
|
|
56149
56366
|
fs28.unlinkSync(existingLedgerPath);
|
|
56150
56367
|
}
|
|
56151
56368
|
try {
|
|
56152
|
-
const planJsonPath =
|
|
56369
|
+
const planJsonPath = path51.join(swarmDir, "plan.json");
|
|
56153
56370
|
if (fs28.existsSync(planJsonPath)) {
|
|
56154
56371
|
const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
|
|
56155
56372
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -56240,9 +56457,9 @@ Ensure this is a git repository with commit history.`;
|
|
|
56240
56457
|
`);
|
|
56241
56458
|
try {
|
|
56242
56459
|
const fs29 = await import("fs/promises");
|
|
56243
|
-
const
|
|
56244
|
-
const reportPath =
|
|
56245
|
-
await fs29.mkdir(
|
|
56460
|
+
const path52 = await import("path");
|
|
56461
|
+
const reportPath = path52.join(directory, ".swarm", "simulate-report.md");
|
|
56462
|
+
await fs29.mkdir(path52.dirname(reportPath), { recursive: true });
|
|
56246
56463
|
await fs29.writeFile(reportPath, report, "utf-8");
|
|
56247
56464
|
} catch (err) {
|
|
56248
56465
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
@@ -56266,12 +56483,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
56266
56483
|
|
|
56267
56484
|
// src/turbo/lean/state.ts
|
|
56268
56485
|
import * as fs29 from "fs";
|
|
56269
|
-
import * as
|
|
56486
|
+
import * as path52 from "path";
|
|
56270
56487
|
function nowISO2() {
|
|
56271
56488
|
return new Date().toISOString();
|
|
56272
56489
|
}
|
|
56273
56490
|
function ensureSwarmDir2(directory) {
|
|
56274
|
-
const swarmDir =
|
|
56491
|
+
const swarmDir = path52.resolve(directory, ".swarm");
|
|
56275
56492
|
if (!fs29.existsSync(swarmDir)) {
|
|
56276
56493
|
fs29.mkdirSync(swarmDir, { recursive: true });
|
|
56277
56494
|
}
|
|
@@ -56315,7 +56532,7 @@ function markStateUnreadable2(directory, reason) {
|
|
|
56315
56532
|
}
|
|
56316
56533
|
function readPersisted2(directory) {
|
|
56317
56534
|
try {
|
|
56318
|
-
const filePath =
|
|
56535
|
+
const filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
56319
56536
|
if (!fs29.existsSync(filePath)) {
|
|
56320
56537
|
const seed = emptyPersisted2();
|
|
56321
56538
|
try {
|
|
@@ -56351,7 +56568,7 @@ function writePersisted2(directory, persisted) {
|
|
|
56351
56568
|
let payload;
|
|
56352
56569
|
try {
|
|
56353
56570
|
ensureSwarmDir2(directory);
|
|
56354
|
-
filePath =
|
|
56571
|
+
filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
56355
56572
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
56356
56573
|
persisted.updatedAt = nowISO2();
|
|
56357
56574
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -56478,10 +56695,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
56478
56695
|
|
|
56479
56696
|
// src/services/status-service.ts
|
|
56480
56697
|
import * as fsSync2 from "fs";
|
|
56481
|
-
import * as
|
|
56698
|
+
import * as path53 from "path";
|
|
56482
56699
|
function readSpecStalenessSnapshot(directory) {
|
|
56483
56700
|
try {
|
|
56484
|
-
const p =
|
|
56701
|
+
const p = path53.join(directory, ".swarm", "spec-staleness.json");
|
|
56485
56702
|
if (!fsSync2.existsSync(p))
|
|
56486
56703
|
return { stale: false };
|
|
56487
56704
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -57007,7 +57224,7 @@ var init_write_retro2 = __esm(() => {
|
|
|
57007
57224
|
|
|
57008
57225
|
// src/commands/command-dispatch.ts
|
|
57009
57226
|
import fs30 from "fs";
|
|
57010
|
-
import
|
|
57227
|
+
import path54 from "path";
|
|
57011
57228
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
57012
57229
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
57013
57230
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -57043,9 +57260,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
57043
57260
|
`);
|
|
57044
57261
|
}
|
|
57045
57262
|
function maybeMarkFirstRun(directory) {
|
|
57046
|
-
const sentinelPath =
|
|
57263
|
+
const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
|
|
57047
57264
|
try {
|
|
57048
|
-
const swarmDir =
|
|
57265
|
+
const swarmDir = path54.join(directory, ".swarm");
|
|
57049
57266
|
fs30.mkdirSync(swarmDir, { recursive: true });
|
|
57050
57267
|
fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
57051
57268
|
`, { flag: "wx" });
|
|
@@ -57787,24 +58004,24 @@ function validateAliases() {
|
|
|
57787
58004
|
}
|
|
57788
58005
|
aliasTargets.get(target).push(name);
|
|
57789
58006
|
const visited = new Set;
|
|
57790
|
-
const
|
|
58007
|
+
const path55 = [];
|
|
57791
58008
|
let current = target;
|
|
57792
58009
|
while (current) {
|
|
57793
58010
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
57794
58011
|
if (!currentEntry)
|
|
57795
58012
|
break;
|
|
57796
58013
|
if (visited.has(current)) {
|
|
57797
|
-
const cycleStart =
|
|
58014
|
+
const cycleStart = path55.indexOf(current);
|
|
57798
58015
|
const fullChain = [
|
|
57799
58016
|
name,
|
|
57800
|
-
...
|
|
58017
|
+
...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
|
|
57801
58018
|
current
|
|
57802
58019
|
].join(" \u2192 ");
|
|
57803
58020
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
57804
58021
|
break;
|
|
57805
58022
|
}
|
|
57806
58023
|
visited.add(current);
|
|
57807
|
-
|
|
58024
|
+
path55.push(current);
|
|
57808
58025
|
current = currentEntry.aliasOf || "";
|
|
57809
58026
|
}
|
|
57810
58027
|
}
|
|
@@ -58402,53 +58619,53 @@ init_cache_paths();
|
|
|
58402
58619
|
init_constants();
|
|
58403
58620
|
import * as fs31 from "fs";
|
|
58404
58621
|
import * as os8 from "os";
|
|
58405
|
-
import * as
|
|
58406
|
-
var { version:
|
|
58622
|
+
import * as path55 from "path";
|
|
58623
|
+
var { version: version5 } = package_default;
|
|
58407
58624
|
var CONFIG_DIR = getPluginConfigDir();
|
|
58408
|
-
var OPENCODE_CONFIG_PATH =
|
|
58409
|
-
var PLUGIN_CONFIG_PATH =
|
|
58410
|
-
var PROMPTS_DIR =
|
|
58625
|
+
var OPENCODE_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode.json");
|
|
58626
|
+
var PLUGIN_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode-swarm.json");
|
|
58627
|
+
var PROMPTS_DIR = path55.join(CONFIG_DIR, "opencode-swarm");
|
|
58411
58628
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
58412
58629
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
58413
58630
|
function isSafeCachePath(p) {
|
|
58414
|
-
const resolved =
|
|
58415
|
-
const home =
|
|
58631
|
+
const resolved = path55.resolve(p);
|
|
58632
|
+
const home = path55.resolve(os8.homedir());
|
|
58416
58633
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
58417
58634
|
return false;
|
|
58418
58635
|
}
|
|
58419
|
-
const segments = resolved.split(
|
|
58636
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
58420
58637
|
if (segments.length < 4) {
|
|
58421
58638
|
return false;
|
|
58422
58639
|
}
|
|
58423
|
-
const leaf =
|
|
58640
|
+
const leaf = path55.basename(resolved);
|
|
58424
58641
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
58425
58642
|
return false;
|
|
58426
58643
|
}
|
|
58427
|
-
const parent =
|
|
58644
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
58428
58645
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
58429
58646
|
return false;
|
|
58430
58647
|
}
|
|
58431
|
-
const grandparent =
|
|
58648
|
+
const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
|
|
58432
58649
|
if (grandparent !== "opencode") {
|
|
58433
58650
|
return false;
|
|
58434
58651
|
}
|
|
58435
58652
|
return true;
|
|
58436
58653
|
}
|
|
58437
58654
|
function isSafeLockFilePath(p) {
|
|
58438
|
-
const resolved =
|
|
58439
|
-
const home =
|
|
58655
|
+
const resolved = path55.resolve(p);
|
|
58656
|
+
const home = path55.resolve(os8.homedir());
|
|
58440
58657
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
58441
58658
|
return false;
|
|
58442
58659
|
}
|
|
58443
|
-
const segments = resolved.split(
|
|
58660
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
58444
58661
|
if (segments.length < 4) {
|
|
58445
58662
|
return false;
|
|
58446
58663
|
}
|
|
58447
|
-
const leaf =
|
|
58664
|
+
const leaf = path55.basename(resolved);
|
|
58448
58665
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
58449
58666
|
return false;
|
|
58450
58667
|
}
|
|
58451
|
-
const parent =
|
|
58668
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
58452
58669
|
if (parent !== "opencode") {
|
|
58453
58670
|
return false;
|
|
58454
58671
|
}
|
|
@@ -58474,8 +58691,8 @@ function saveJson(filepath, data) {
|
|
|
58474
58691
|
}
|
|
58475
58692
|
function writeProjectConfigIfMissing(cwd) {
|
|
58476
58693
|
try {
|
|
58477
|
-
const opencodeDir =
|
|
58478
|
-
const projectConfigPath =
|
|
58694
|
+
const opencodeDir = path55.join(cwd, ".opencode");
|
|
58695
|
+
const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
|
|
58479
58696
|
if (fs31.existsSync(projectConfigPath)) {
|
|
58480
58697
|
return;
|
|
58481
58698
|
}
|
|
@@ -58492,7 +58709,7 @@ async function install() {
|
|
|
58492
58709
|
`);
|
|
58493
58710
|
ensureDir(CONFIG_DIR);
|
|
58494
58711
|
ensureDir(PROMPTS_DIR);
|
|
58495
|
-
const LEGACY_CONFIG_PATH =
|
|
58712
|
+
const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
|
|
58496
58713
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
58497
58714
|
if (!opencodeConfig) {
|
|
58498
58715
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|
|
@@ -58767,7 +58984,7 @@ Examples:
|
|
|
58767
58984
|
async function main() {
|
|
58768
58985
|
const args = process.argv.slice(2);
|
|
58769
58986
|
if (args.includes("-v") || args.includes("--version")) {
|
|
58770
|
-
console.log(`opencode-swarm ${
|
|
58987
|
+
console.log(`opencode-swarm ${version5}`);
|
|
58771
58988
|
process.exit(0);
|
|
58772
58989
|
}
|
|
58773
58990
|
if (args.includes("-h") || args.includes("--help")) {
|