opencode-swarm 7.43.0 → 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 +615 -379
- 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 +2162 -2032
- 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 +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
var __returnValue = (v) => v;
|
|
35
|
+
function __exportSetter(name, newValue) {
|
|
36
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
+
}
|
|
20
38
|
var __export = (target, all) => {
|
|
21
39
|
for (var name in all)
|
|
22
40
|
__defProp(target, name, {
|
|
23
41
|
get: all[name],
|
|
24
42
|
enumerable: true,
|
|
25
43
|
configurable: true,
|
|
26
|
-
set: (
|
|
44
|
+
set: __exportSetter.bind(all, name)
|
|
27
45
|
});
|
|
28
46
|
};
|
|
29
47
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -34,7 +52,7 @@ var package_default;
|
|
|
34
52
|
var init_package = __esm(() => {
|
|
35
53
|
package_default = {
|
|
36
54
|
name: "opencode-swarm",
|
|
37
|
-
version: "7.
|
|
55
|
+
version: "7.44.0",
|
|
38
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
39
57
|
main: "dist/index.js",
|
|
40
58
|
types: "dist/index.d.ts",
|
|
@@ -80,6 +98,7 @@ var init_package = __esm(() => {
|
|
|
80
98
|
format: "biome format . --write",
|
|
81
99
|
check: "biome check --write .",
|
|
82
100
|
dev: "bun run build && opencode",
|
|
101
|
+
"package:smoke": "node scripts/package-smoke.mjs",
|
|
83
102
|
prepublishOnly: "bun run build",
|
|
84
103
|
"repro:704": "node scripts/repro-704.mjs"
|
|
85
104
|
},
|
|
@@ -16503,6 +16522,8 @@ var init_tool_names = __esm(() => {
|
|
|
16503
16522
|
"skill_improve",
|
|
16504
16523
|
"spec_write",
|
|
16505
16524
|
"knowledge_ack",
|
|
16525
|
+
"knowledge_receipt",
|
|
16526
|
+
"knowledge_archive",
|
|
16506
16527
|
"swarm_memory_recall",
|
|
16507
16528
|
"swarm_memory_propose",
|
|
16508
16529
|
"swarm_command",
|
|
@@ -16747,6 +16768,7 @@ var init_constants = __esm(() => {
|
|
|
16747
16768
|
"knowledge_add",
|
|
16748
16769
|
"knowledge_recall",
|
|
16749
16770
|
"knowledge_remove",
|
|
16771
|
+
"knowledge_archive",
|
|
16750
16772
|
"co_change_analyzer",
|
|
16751
16773
|
"suggest_patch",
|
|
16752
16774
|
"repo_map",
|
|
@@ -16763,6 +16785,7 @@ var init_constants = __esm(() => {
|
|
|
16763
16785
|
"skill_retire",
|
|
16764
16786
|
"skill_improve",
|
|
16765
16787
|
"knowledge_ack",
|
|
16788
|
+
"knowledge_receipt",
|
|
16766
16789
|
"summarize_work",
|
|
16767
16790
|
"write_architecture_supervisor_evidence",
|
|
16768
16791
|
"swarm_command",
|
|
@@ -16803,6 +16826,7 @@ var init_constants = __esm(() => {
|
|
|
16803
16826
|
"syntax_check",
|
|
16804
16827
|
"knowledge_add",
|
|
16805
16828
|
"knowledge_recall",
|
|
16829
|
+
"knowledge_receipt",
|
|
16806
16830
|
"repo_map",
|
|
16807
16831
|
"summarize_work",
|
|
16808
16832
|
"swarm_command"
|
|
@@ -17026,6 +17050,7 @@ var init_constants = __esm(() => {
|
|
|
17026
17050
|
knowledge_add: "store a new lesson in the knowledge base",
|
|
17027
17051
|
knowledge_recall: "search the knowledge base for relevant past decisions",
|
|
17028
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",
|
|
17029
17054
|
knowledge_query: "query swarm or hive knowledge with optional filters",
|
|
17030
17055
|
co_change_analyzer: "detect hidden couplings by analyzing git history",
|
|
17031
17056
|
check_gate_status: "check the gate status of a specific task",
|
|
@@ -17059,6 +17084,7 @@ var init_constants = __esm(() => {
|
|
|
17059
17084
|
skill_retire: "retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",
|
|
17060
17085
|
spec_write: "author or update .swarm/spec.md for the current project",
|
|
17061
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",
|
|
17062
17088
|
swarm_memory_recall: "recall scoped Swarm memory for the current repository as untrusted background",
|
|
17063
17089
|
swarm_memory_propose: "create a pending Swarm memory proposal; does not write durable memory directly",
|
|
17064
17090
|
swarm_command: "run supported /swarm commands through the canonical command registry",
|
|
@@ -35850,8 +35876,12 @@ function normalizeEntry(raw) {
|
|
|
35850
35876
|
const obj = raw;
|
|
35851
35877
|
if (!("retrieval_outcomes" in obj))
|
|
35852
35878
|
return raw;
|
|
35853
|
-
|
|
35854
|
-
if (ro
|
|
35879
|
+
let ro = obj.retrieval_outcomes;
|
|
35880
|
+
if (!ro || typeof ro !== "object") {
|
|
35881
|
+
ro = {};
|
|
35882
|
+
obj.retrieval_outcomes = ro;
|
|
35883
|
+
}
|
|
35884
|
+
{
|
|
35855
35885
|
if (typeof ro.shown_count !== "number") {
|
|
35856
35886
|
ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
|
|
35857
35887
|
}
|
|
@@ -35864,6 +35894,8 @@ function normalizeEntry(raw) {
|
|
|
35864
35894
|
ro.ignored_count = 0;
|
|
35865
35895
|
if (typeof ro.violated_count !== "number")
|
|
35866
35896
|
ro.violated_count = 0;
|
|
35897
|
+
if (typeof ro.contradicted_count !== "number")
|
|
35898
|
+
ro.contradicted_count = 0;
|
|
35867
35899
|
if (typeof ro.succeeded_after_shown_count !== "number") {
|
|
35868
35900
|
ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
|
|
35869
35901
|
}
|
|
@@ -35901,6 +35933,9 @@ function normalizeEntry(raw) {
|
|
|
35901
35933
|
delete obj[f];
|
|
35902
35934
|
}
|
|
35903
35935
|
}
|
|
35936
|
+
if (!Array.isArray(obj.tags)) {
|
|
35937
|
+
obj.tags = [];
|
|
35938
|
+
}
|
|
35904
35939
|
return raw;
|
|
35905
35940
|
}
|
|
35906
35941
|
async function readRejectedLessons(directory) {
|
|
@@ -35990,7 +36025,8 @@ async function appendRejectedLesson(directory, lesson) {
|
|
|
35990
36025
|
}
|
|
35991
36026
|
}
|
|
35992
36027
|
function normalize2(text) {
|
|
35993
|
-
|
|
36028
|
+
const s = typeof text === "string" ? text : String(text ?? "");
|
|
36029
|
+
return s.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
35994
36030
|
}
|
|
35995
36031
|
function wordBigrams(text) {
|
|
35996
36032
|
const words = normalize2(text).split(" ").filter(Boolean);
|
|
@@ -36022,6 +36058,16 @@ function computeConfidence(confirmedByCount, autoGenerated) {
|
|
|
36022
36058
|
score += 0.1;
|
|
36023
36059
|
return Math.min(score, 1);
|
|
36024
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
|
+
}
|
|
36025
36071
|
function inferTags(lesson) {
|
|
36026
36072
|
const lower = lesson.toLowerCase();
|
|
36027
36073
|
const tags = [];
|
|
@@ -36117,7 +36163,7 @@ async function applyConfidenceDeltas(filePath, deltas) {
|
|
|
36117
36163
|
}
|
|
36118
36164
|
}
|
|
36119
36165
|
}
|
|
36120
|
-
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;
|
|
36121
36167
|
var init_knowledge_store = __esm(() => {
|
|
36122
36168
|
init_task_file();
|
|
36123
36169
|
import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
@@ -37551,6 +37597,9 @@ async function runAutoPromotion(directory, config3) {
|
|
|
37551
37597
|
for (const entry of entries) {
|
|
37552
37598
|
if (entry.status === "promoted")
|
|
37553
37599
|
continue;
|
|
37600
|
+
if (computeOutcomeSignal(entry.retrieval_outcomes) <= OUTCOME_PROMOTION_BLOCK) {
|
|
37601
|
+
continue;
|
|
37602
|
+
}
|
|
37554
37603
|
const distinctPhases = new Set((entry.confirmed_by ?? []).map((c) => c.phase_number)).size;
|
|
37555
37604
|
if (entry.status === "candidate" && distinctPhases >= 3) {
|
|
37556
37605
|
entry.status = "established";
|
|
@@ -37648,7 +37697,7 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
37648
37697
|
};
|
|
37649
37698
|
return safeHook(handler);
|
|
37650
37699
|
}
|
|
37651
|
-
var seenRetroSections, _internals11;
|
|
37700
|
+
var seenRetroSections, OUTCOME_PROMOTION_BLOCK = -0.3, _internals11;
|
|
37652
37701
|
var init_knowledge_curator = __esm(() => {
|
|
37653
37702
|
init_knowledge_store();
|
|
37654
37703
|
init_knowledge_validator();
|
|
@@ -40222,24 +40271,63 @@ var init_gate_bridge = __esm(() => {
|
|
|
40222
40271
|
};
|
|
40223
40272
|
});
|
|
40224
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
|
+
|
|
40225
40313
|
// src/services/version-check.ts
|
|
40226
|
-
import { existsSync as
|
|
40314
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
40227
40315
|
import { homedir as homedir5 } from "os";
|
|
40228
|
-
import { join as
|
|
40316
|
+
import { join as join22 } from "path";
|
|
40229
40317
|
function cacheDir() {
|
|
40230
40318
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
40231
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
40232
|
-
return
|
|
40319
|
+
const base = xdg && xdg.length > 0 ? xdg : join22(homedir5(), ".cache");
|
|
40320
|
+
return join22(base, "opencode-swarm");
|
|
40233
40321
|
}
|
|
40234
40322
|
function cacheFile() {
|
|
40235
|
-
return
|
|
40323
|
+
return join22(cacheDir(), "version-check.json");
|
|
40236
40324
|
}
|
|
40237
40325
|
function readVersionCache() {
|
|
40238
40326
|
try {
|
|
40239
|
-
const
|
|
40240
|
-
if (!
|
|
40327
|
+
const path24 = cacheFile();
|
|
40328
|
+
if (!existsSync13(path24))
|
|
40241
40329
|
return null;
|
|
40242
|
-
const raw = readFileSync8(
|
|
40330
|
+
const raw = readFileSync8(path24, "utf-8");
|
|
40243
40331
|
const parsed = JSON.parse(raw);
|
|
40244
40332
|
if (typeof parsed?.checkedAt !== "number")
|
|
40245
40333
|
return null;
|
|
@@ -40276,10 +40364,156 @@ var init_version_check = __esm(() => {
|
|
|
40276
40364
|
CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
40277
40365
|
});
|
|
40278
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
|
+
|
|
40279
40513
|
// src/services/diagnose-service.ts
|
|
40280
40514
|
import * as child_process4 from "child_process";
|
|
40281
|
-
import { existsSync as
|
|
40282
|
-
import
|
|
40515
|
+
import { existsSync as existsSync15, readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync7 } from "fs";
|
|
40516
|
+
import path24 from "path";
|
|
40283
40517
|
import { fileURLToPath } from "url";
|
|
40284
40518
|
function validateTaskDag(plan) {
|
|
40285
40519
|
const allTaskIds = new Set;
|
|
@@ -40526,7 +40760,7 @@ async function checkConfigBackups(directory) {
|
|
|
40526
40760
|
}
|
|
40527
40761
|
async function checkGitRepository(directory) {
|
|
40528
40762
|
try {
|
|
40529
|
-
if (!
|
|
40763
|
+
if (!existsSync15(directory) || !statSync7(directory).isDirectory()) {
|
|
40530
40764
|
return {
|
|
40531
40765
|
name: "Git Repository",
|
|
40532
40766
|
status: "\u274C",
|
|
@@ -40590,8 +40824,8 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
40590
40824
|
};
|
|
40591
40825
|
}
|
|
40592
40826
|
async function checkConfigParseability(directory) {
|
|
40593
|
-
const configPath =
|
|
40594
|
-
if (!
|
|
40827
|
+
const configPath = path24.join(directory, ".opencode/opencode-swarm.json");
|
|
40828
|
+
if (!existsSync15(configPath)) {
|
|
40595
40829
|
return {
|
|
40596
40830
|
name: "Config Parseability",
|
|
40597
40831
|
status: "\u2705",
|
|
@@ -40619,7 +40853,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
40619
40853
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
40620
40854
|
const isSource = normalized.endsWith("/src/services");
|
|
40621
40855
|
const isCliBundle = normalized.endsWith("/cli");
|
|
40622
|
-
return isSource || isCliBundle ?
|
|
40856
|
+
return isSource || isCliBundle ? path24.join(thisDir, "..", "lang", "grammars") : path24.join(thisDir, "lang", "grammars");
|
|
40623
40857
|
}
|
|
40624
40858
|
async function checkGrammarWasmFiles() {
|
|
40625
40859
|
const grammarFiles = [
|
|
@@ -40643,14 +40877,14 @@ async function checkGrammarWasmFiles() {
|
|
|
40643
40877
|
"tree-sitter-ini.wasm",
|
|
40644
40878
|
"tree-sitter-regex.wasm"
|
|
40645
40879
|
];
|
|
40646
|
-
const thisDir =
|
|
40880
|
+
const thisDir = path24.dirname(fileURLToPath(import.meta.url));
|
|
40647
40881
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
40648
40882
|
const missing = [];
|
|
40649
|
-
if (!
|
|
40883
|
+
if (!existsSync15(path24.join(grammarDir, "tree-sitter.wasm"))) {
|
|
40650
40884
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
40651
40885
|
}
|
|
40652
40886
|
for (const file3 of grammarFiles) {
|
|
40653
|
-
if (!
|
|
40887
|
+
if (!existsSync15(path24.join(grammarDir, file3))) {
|
|
40654
40888
|
missing.push(file3);
|
|
40655
40889
|
}
|
|
40656
40890
|
}
|
|
@@ -40668,8 +40902,8 @@ async function checkGrammarWasmFiles() {
|
|
|
40668
40902
|
};
|
|
40669
40903
|
}
|
|
40670
40904
|
async function checkCheckpointManifest(directory) {
|
|
40671
|
-
const manifestPath =
|
|
40672
|
-
if (!
|
|
40905
|
+
const manifestPath = path24.join(directory, ".swarm/checkpoints.json");
|
|
40906
|
+
if (!existsSync15(manifestPath)) {
|
|
40673
40907
|
return {
|
|
40674
40908
|
name: "Checkpoint Manifest",
|
|
40675
40909
|
status: "\u2705",
|
|
@@ -40720,8 +40954,8 @@ async function checkCheckpointManifest(directory) {
|
|
|
40720
40954
|
}
|
|
40721
40955
|
}
|
|
40722
40956
|
async function checkEventStreamIntegrity(directory) {
|
|
40723
|
-
const eventsPath =
|
|
40724
|
-
if (!
|
|
40957
|
+
const eventsPath = path24.join(directory, ".swarm/events.jsonl");
|
|
40958
|
+
if (!existsSync15(eventsPath)) {
|
|
40725
40959
|
return {
|
|
40726
40960
|
name: "Event Stream",
|
|
40727
40961
|
status: "\u2705",
|
|
@@ -40761,8 +40995,8 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
40761
40995
|
}
|
|
40762
40996
|
}
|
|
40763
40997
|
async function checkSteeringDirectives(directory) {
|
|
40764
|
-
const eventsPath =
|
|
40765
|
-
if (!
|
|
40998
|
+
const eventsPath = path24.join(directory, ".swarm/events.jsonl");
|
|
40999
|
+
if (!existsSync15(eventsPath)) {
|
|
40766
41000
|
return {
|
|
40767
41001
|
name: "Steering Directives",
|
|
40768
41002
|
status: "\u2705",
|
|
@@ -40817,8 +41051,8 @@ async function checkCurator(directory) {
|
|
|
40817
41051
|
detail: "Disabled (enable via curator.enabled)"
|
|
40818
41052
|
};
|
|
40819
41053
|
}
|
|
40820
|
-
const summaryPath =
|
|
40821
|
-
if (!
|
|
41054
|
+
const summaryPath = path24.join(directory, ".swarm/curator-summary.json");
|
|
41055
|
+
if (!existsSync15(summaryPath)) {
|
|
40822
41056
|
return {
|
|
40823
41057
|
name: "Curator",
|
|
40824
41058
|
status: "\u2705",
|
|
@@ -40862,16 +41096,16 @@ async function checkCurator(directory) {
|
|
|
40862
41096
|
async function getDiagnoseData(directory) {
|
|
40863
41097
|
const checks5 = [];
|
|
40864
41098
|
const versionCache = readVersionCache();
|
|
40865
|
-
let versionDetail =
|
|
41099
|
+
let versionDetail = version4;
|
|
40866
41100
|
let versionStatus = "\u2705";
|
|
40867
41101
|
if (versionCache?.npmLatest) {
|
|
40868
41102
|
const ageMs = Date.now() - versionCache.checkedAt;
|
|
40869
41103
|
const ageMin = Math.max(0, Math.round(ageMs / 60000));
|
|
40870
|
-
if (compareVersions(versionCache.npmLatest,
|
|
41104
|
+
if (compareVersions(versionCache.npmLatest, version4) > 0) {
|
|
40871
41105
|
versionStatus = "\u26A0\uFE0F";
|
|
40872
|
-
versionDetail = `${
|
|
41106
|
+
versionDetail = `${version4} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago) ` + "\u2014 run `bunx opencode-swarm update` to refresh";
|
|
40873
41107
|
} else {
|
|
40874
|
-
versionDetail = `${
|
|
41108
|
+
versionDetail = `${version4} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago)`;
|
|
40875
41109
|
}
|
|
40876
41110
|
}
|
|
40877
41111
|
checks5.push({
|
|
@@ -40982,9 +41216,10 @@ async function getDiagnoseData(directory) {
|
|
|
40982
41216
|
checks5.push(await checkEventStreamIntegrity(directory));
|
|
40983
41217
|
checks5.push(await checkSteeringDirectives(directory));
|
|
40984
41218
|
checks5.push(await checkCurator(directory));
|
|
41219
|
+
checks5.push(await checkKnowledgeHealth(directory));
|
|
40985
41220
|
try {
|
|
40986
|
-
const evidenceDir =
|
|
40987
|
-
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")) : [];
|
|
40988
41223
|
if (snapshotFiles.length > 0) {
|
|
40989
41224
|
const latest = snapshotFiles.sort().pop();
|
|
40990
41225
|
checks5.push({
|
|
@@ -41017,11 +41252,11 @@ async function getDiagnoseData(directory) {
|
|
|
41017
41252
|
const cacheRows = [];
|
|
41018
41253
|
for (const cachePath of cachePaths) {
|
|
41019
41254
|
try {
|
|
41020
|
-
if (!
|
|
41255
|
+
if (!existsSync15(cachePath)) {
|
|
41021
41256
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
41022
41257
|
continue;
|
|
41023
41258
|
}
|
|
41024
|
-
const pkgJsonPath =
|
|
41259
|
+
const pkgJsonPath = path24.join(cachePath, "package.json");
|
|
41025
41260
|
try {
|
|
41026
41261
|
const raw = readFileSync9(pkgJsonPath, "utf-8");
|
|
41027
41262
|
const parsed = JSON.parse(raw);
|
|
@@ -41036,10 +41271,10 @@ async function getDiagnoseData(directory) {
|
|
|
41036
41271
|
}
|
|
41037
41272
|
const hasCacheEntry = cacheRows.some((r) => r.startsWith("\u2705"));
|
|
41038
41273
|
const hasCacheWarning = cacheRows.some((r) => r.startsWith("\u26A0\uFE0F"));
|
|
41039
|
-
const
|
|
41274
|
+
const cacheStatus2 = hasCacheWarning ? "\u26A0\uFE0F" : hasCacheEntry ? "\u2705" : "\u2B1C";
|
|
41040
41275
|
checks5.push({
|
|
41041
41276
|
name: "Plugin Caches",
|
|
41042
|
-
status:
|
|
41277
|
+
status: cacheStatus2,
|
|
41043
41278
|
detail: cacheRows.join(" | ")
|
|
41044
41279
|
});
|
|
41045
41280
|
const passCount = checks5.filter((c) => c.status === "\u2705" || c.status === "\u2B1C").length;
|
|
@@ -41075,7 +41310,7 @@ async function handleDiagnoseCommand(directory, _args) {
|
|
|
41075
41310
|
const diagnoseData = await getDiagnoseData(directory);
|
|
41076
41311
|
return formatDiagnoseMarkdown(diagnoseData);
|
|
41077
41312
|
}
|
|
41078
|
-
var
|
|
41313
|
+
var version4;
|
|
41079
41314
|
var init_diagnose_service = __esm(() => {
|
|
41080
41315
|
init_package();
|
|
41081
41316
|
init_cache_paths();
|
|
@@ -41084,9 +41319,10 @@ var init_diagnose_service = __esm(() => {
|
|
|
41084
41319
|
init_manager2();
|
|
41085
41320
|
init_utils2();
|
|
41086
41321
|
init_manager();
|
|
41322
|
+
init_knowledge_diagnostics();
|
|
41087
41323
|
init_version_check();
|
|
41088
41324
|
init_warning_buffer();
|
|
41089
|
-
({ version:
|
|
41325
|
+
({ version: version4 } = package_default);
|
|
41090
41326
|
});
|
|
41091
41327
|
|
|
41092
41328
|
// src/commands/diagnose.ts
|
|
@@ -41112,13 +41348,13 @@ __export(exports_config_doctor, {
|
|
|
41112
41348
|
import * as crypto4 from "crypto";
|
|
41113
41349
|
import * as fs9 from "fs";
|
|
41114
41350
|
import * as os6 from "os";
|
|
41115
|
-
import * as
|
|
41351
|
+
import * as path25 from "path";
|
|
41116
41352
|
function getUserConfigDir3() {
|
|
41117
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
41353
|
+
return process.env.XDG_CONFIG_HOME || path25.join(os6.homedir(), ".config");
|
|
41118
41354
|
}
|
|
41119
41355
|
function getConfigPaths(directory) {
|
|
41120
|
-
const userConfigPath =
|
|
41121
|
-
const projectConfigPath =
|
|
41356
|
+
const userConfigPath = path25.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
41357
|
+
const projectConfigPath = path25.join(directory, ".opencode", "opencode-swarm.json");
|
|
41122
41358
|
return { userConfigPath, projectConfigPath };
|
|
41123
41359
|
}
|
|
41124
41360
|
function computeHash(content) {
|
|
@@ -41143,9 +41379,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
41143
41379
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
41144
41380
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
41145
41381
|
try {
|
|
41146
|
-
const resolvedConfig =
|
|
41147
|
-
const resolvedUser =
|
|
41148
|
-
const resolvedProject =
|
|
41382
|
+
const resolvedConfig = path25.resolve(configPath);
|
|
41383
|
+
const resolvedUser = path25.resolve(normalizedUser);
|
|
41384
|
+
const resolvedProject = path25.resolve(normalizedProject);
|
|
41149
41385
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
41150
41386
|
} catch {
|
|
41151
41387
|
return false;
|
|
@@ -41185,12 +41421,12 @@ function createConfigBackup(directory) {
|
|
|
41185
41421
|
};
|
|
41186
41422
|
}
|
|
41187
41423
|
function writeBackupArtifact(directory, backup) {
|
|
41188
|
-
const swarmDir =
|
|
41424
|
+
const swarmDir = path25.join(directory, ".swarm");
|
|
41189
41425
|
if (!fs9.existsSync(swarmDir)) {
|
|
41190
41426
|
fs9.mkdirSync(swarmDir, { recursive: true });
|
|
41191
41427
|
}
|
|
41192
41428
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
41193
|
-
const backupPath =
|
|
41429
|
+
const backupPath = path25.join(swarmDir, backupFilename);
|
|
41194
41430
|
const artifact = {
|
|
41195
41431
|
createdAt: backup.createdAt,
|
|
41196
41432
|
configPath: backup.configPath,
|
|
@@ -41220,7 +41456,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
41220
41456
|
return null;
|
|
41221
41457
|
}
|
|
41222
41458
|
const targetPath = artifact.configPath;
|
|
41223
|
-
const targetDir =
|
|
41459
|
+
const targetDir = path25.dirname(targetPath);
|
|
41224
41460
|
if (!fs9.existsSync(targetDir)) {
|
|
41225
41461
|
fs9.mkdirSync(targetDir, { recursive: true });
|
|
41226
41462
|
}
|
|
@@ -41251,9 +41487,9 @@ function readConfigFromFile(directory) {
|
|
|
41251
41487
|
return null;
|
|
41252
41488
|
}
|
|
41253
41489
|
}
|
|
41254
|
-
function validateConfigKey(
|
|
41490
|
+
function validateConfigKey(path26, value, _config) {
|
|
41255
41491
|
const findings = [];
|
|
41256
|
-
switch (
|
|
41492
|
+
switch (path26) {
|
|
41257
41493
|
case "agents": {
|
|
41258
41494
|
if (value !== undefined) {
|
|
41259
41495
|
findings.push({
|
|
@@ -41490,27 +41726,27 @@ function validateConfigKey(path25, value, _config) {
|
|
|
41490
41726
|
}
|
|
41491
41727
|
return findings;
|
|
41492
41728
|
}
|
|
41493
|
-
function walkConfigAndValidate(obj,
|
|
41729
|
+
function walkConfigAndValidate(obj, path26, config3, findings) {
|
|
41494
41730
|
if (obj === null || obj === undefined) {
|
|
41495
41731
|
return;
|
|
41496
41732
|
}
|
|
41497
|
-
if (
|
|
41498
|
-
const keyFindings = validateConfigKey(
|
|
41733
|
+
if (path26 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
41734
|
+
const keyFindings = validateConfigKey(path26, obj, config3);
|
|
41499
41735
|
findings.push(...keyFindings);
|
|
41500
41736
|
}
|
|
41501
41737
|
if (typeof obj !== "object") {
|
|
41502
|
-
const keyFindings = validateConfigKey(
|
|
41738
|
+
const keyFindings = validateConfigKey(path26, obj, config3);
|
|
41503
41739
|
findings.push(...keyFindings);
|
|
41504
41740
|
return;
|
|
41505
41741
|
}
|
|
41506
41742
|
if (Array.isArray(obj)) {
|
|
41507
41743
|
obj.forEach((item, index) => {
|
|
41508
|
-
walkConfigAndValidate(item, `${
|
|
41744
|
+
walkConfigAndValidate(item, `${path26}[${index}]`, config3, findings);
|
|
41509
41745
|
});
|
|
41510
41746
|
return;
|
|
41511
41747
|
}
|
|
41512
41748
|
for (const [key, value] of Object.entries(obj)) {
|
|
41513
|
-
const newPath =
|
|
41749
|
+
const newPath = path26 ? `${path26}.${key}` : key;
|
|
41514
41750
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
41515
41751
|
}
|
|
41516
41752
|
}
|
|
@@ -41630,7 +41866,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
41630
41866
|
}
|
|
41631
41867
|
}
|
|
41632
41868
|
if (appliedFixes.length > 0) {
|
|
41633
|
-
const configDir =
|
|
41869
|
+
const configDir = path25.dirname(configPath);
|
|
41634
41870
|
if (!fs9.existsSync(configDir)) {
|
|
41635
41871
|
fs9.mkdirSync(configDir, { recursive: true });
|
|
41636
41872
|
}
|
|
@@ -41640,12 +41876,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
41640
41876
|
return { appliedFixes, updatedConfigPath };
|
|
41641
41877
|
}
|
|
41642
41878
|
function writeDoctorArtifact(directory, result) {
|
|
41643
|
-
const swarmDir =
|
|
41879
|
+
const swarmDir = path25.join(directory, ".swarm");
|
|
41644
41880
|
if (!fs9.existsSync(swarmDir)) {
|
|
41645
41881
|
fs9.mkdirSync(swarmDir, { recursive: true });
|
|
41646
41882
|
}
|
|
41647
41883
|
const artifactFilename = "config-doctor.json";
|
|
41648
|
-
const artifactPath =
|
|
41884
|
+
const artifactPath = path25.join(swarmDir, artifactFilename);
|
|
41649
41885
|
const guiOutput = {
|
|
41650
41886
|
timestamp: result.timestamp,
|
|
41651
41887
|
summary: result.summary,
|
|
@@ -41741,17 +41977,17 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
41741
41977
|
if (!entry.isDirectory())
|
|
41742
41978
|
continue;
|
|
41743
41979
|
const name = entry.name;
|
|
41744
|
-
const fullPath =
|
|
41980
|
+
const fullPath = path25.join(dir, name);
|
|
41745
41981
|
if (SKIP_DIRS.has(name))
|
|
41746
41982
|
continue;
|
|
41747
|
-
const gitPath =
|
|
41983
|
+
const gitPath = path25.join(fullPath, ".git");
|
|
41748
41984
|
try {
|
|
41749
41985
|
const gitStat = fs9.statSync(gitPath);
|
|
41750
41986
|
if (gitStat.isFile() || gitStat.isDirectory())
|
|
41751
41987
|
continue;
|
|
41752
41988
|
} catch {}
|
|
41753
41989
|
if (name === ".swarm") {
|
|
41754
|
-
const parentDir =
|
|
41990
|
+
const parentDir = path25.dirname(fullPath);
|
|
41755
41991
|
if (parentDir === projectRoot)
|
|
41756
41992
|
continue;
|
|
41757
41993
|
let contents = [];
|
|
@@ -41761,7 +41997,7 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
41761
41997
|
contents = ["<unreadable>"];
|
|
41762
41998
|
}
|
|
41763
41999
|
findings.push({
|
|
41764
|
-
path:
|
|
42000
|
+
path: path25.relative(projectRoot, fullPath).replace(/\\/g, "/"),
|
|
41765
42001
|
absolutePath: fullPath,
|
|
41766
42002
|
contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
|
|
41767
42003
|
totalEntries: contents.length
|
|
@@ -41779,21 +42015,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
|
|
|
41779
42015
|
let canonicalStray;
|
|
41780
42016
|
try {
|
|
41781
42017
|
canonicalRoot = fs9.realpathSync(projectRoot);
|
|
41782
|
-
canonicalStray = fs9.realpathSync(
|
|
42018
|
+
canonicalStray = fs9.realpathSync(path25.isAbsolute(strayPath) ? strayPath : path25.resolve(projectRoot, strayPath));
|
|
41783
42019
|
} catch (err) {
|
|
41784
42020
|
return {
|
|
41785
42021
|
success: false,
|
|
41786
42022
|
message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
|
|
41787
42023
|
};
|
|
41788
42024
|
}
|
|
41789
|
-
const rootSwarm =
|
|
42025
|
+
const rootSwarm = path25.join(canonicalRoot, ".swarm");
|
|
41790
42026
|
if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
|
|
41791
42027
|
return {
|
|
41792
42028
|
success: false,
|
|
41793
42029
|
message: "Refusing to remove root .swarm/ directory"
|
|
41794
42030
|
};
|
|
41795
42031
|
}
|
|
41796
|
-
if (!canonicalStray.startsWith(canonicalRoot +
|
|
42032
|
+
if (!canonicalStray.startsWith(canonicalRoot + path25.sep)) {
|
|
41797
42033
|
return {
|
|
41798
42034
|
success: false,
|
|
41799
42035
|
message: "Path is outside project root \u2014 refusing to remove"
|
|
@@ -42882,7 +43118,7 @@ var init_profiles = __esm(() => {
|
|
|
42882
43118
|
|
|
42883
43119
|
// src/lang/detector.ts
|
|
42884
43120
|
import { access as access3, readdir as readdir2 } from "fs/promises";
|
|
42885
|
-
import { extname as extname2, join as
|
|
43121
|
+
import { extname as extname2, join as join24 } from "path";
|
|
42886
43122
|
async function detectProjectLanguages(projectDir) {
|
|
42887
43123
|
const detected = new Set;
|
|
42888
43124
|
async function scanDir(dir) {
|
|
@@ -42898,7 +43134,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
42898
43134
|
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
42899
43135
|
continue;
|
|
42900
43136
|
try {
|
|
42901
|
-
await access3(
|
|
43137
|
+
await access3(join24(dir, detectFile));
|
|
42902
43138
|
detected.add(profile.id);
|
|
42903
43139
|
break;
|
|
42904
43140
|
} catch {}
|
|
@@ -42919,7 +43155,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
42919
43155
|
const topEntries = await readdir2(projectDir, { withFileTypes: true });
|
|
42920
43156
|
for (const entry of topEntries) {
|
|
42921
43157
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
42922
|
-
await scanDir(
|
|
43158
|
+
await scanDir(join24(projectDir, entry.name));
|
|
42923
43159
|
}
|
|
42924
43160
|
}
|
|
42925
43161
|
} catch {}
|
|
@@ -42938,7 +43174,7 @@ var init_detector = __esm(() => {
|
|
|
42938
43174
|
|
|
42939
43175
|
// src/build/discovery.ts
|
|
42940
43176
|
import * as fs10 from "fs";
|
|
42941
|
-
import * as
|
|
43177
|
+
import * as path26 from "path";
|
|
42942
43178
|
function isCommandAvailable(command) {
|
|
42943
43179
|
if (toolchainCache.has(command)) {
|
|
42944
43180
|
return toolchainCache.get(command);
|
|
@@ -42973,11 +43209,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
42973
43209
|
const regex = simpleGlobToRegex(pattern);
|
|
42974
43210
|
const matches = files.filter((f) => regex.test(f));
|
|
42975
43211
|
if (matches.length > 0) {
|
|
42976
|
-
return
|
|
43212
|
+
return path26.join(dir, matches[0]);
|
|
42977
43213
|
}
|
|
42978
43214
|
} catch {}
|
|
42979
43215
|
} else {
|
|
42980
|
-
const filePath =
|
|
43216
|
+
const filePath = path26.join(workingDir, pattern);
|
|
42981
43217
|
if (fs10.existsSync(filePath)) {
|
|
42982
43218
|
return filePath;
|
|
42983
43219
|
}
|
|
@@ -42986,7 +43222,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
42986
43222
|
return null;
|
|
42987
43223
|
}
|
|
42988
43224
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
42989
|
-
const packageJsonPath =
|
|
43225
|
+
const packageJsonPath = path26.join(workingDir, "package.json");
|
|
42990
43226
|
if (!fs10.existsSync(packageJsonPath)) {
|
|
42991
43227
|
return [];
|
|
42992
43228
|
}
|
|
@@ -43027,7 +43263,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
43027
43263
|
const regex = simpleGlobToRegex(pattern);
|
|
43028
43264
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
43029
43265
|
} else {
|
|
43030
|
-
const filePath =
|
|
43266
|
+
const filePath = path26.join(workingDir, pattern);
|
|
43031
43267
|
if (fs10.existsSync(filePath)) {
|
|
43032
43268
|
allBuildFiles.add(filePath);
|
|
43033
43269
|
}
|
|
@@ -43040,7 +43276,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
43040
43276
|
try {
|
|
43041
43277
|
const entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
43042
43278
|
for (const entry of entries) {
|
|
43043
|
-
const fullPath =
|
|
43279
|
+
const fullPath = path26.join(dir, entry.name);
|
|
43044
43280
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
43045
43281
|
findFilesRecursive(fullPath, regex, results);
|
|
43046
43282
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -43063,7 +43299,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
43063
43299
|
let foundCommand = false;
|
|
43064
43300
|
for (const cmd of sortedCommands) {
|
|
43065
43301
|
if (cmd.detectFile) {
|
|
43066
|
-
const detectFilePath =
|
|
43302
|
+
const detectFilePath = path26.join(workingDir, cmd.detectFile);
|
|
43067
43303
|
if (!fs10.existsSync(detectFilePath)) {
|
|
43068
43304
|
continue;
|
|
43069
43305
|
}
|
|
@@ -43304,7 +43540,7 @@ var init_discovery = __esm(() => {
|
|
|
43304
43540
|
|
|
43305
43541
|
// src/services/tool-doctor.ts
|
|
43306
43542
|
import * as fs11 from "fs";
|
|
43307
|
-
import * as
|
|
43543
|
+
import * as path27 from "path";
|
|
43308
43544
|
function extractRegisteredToolKeys(indexPath) {
|
|
43309
43545
|
const registeredKeys = new Set;
|
|
43310
43546
|
try {
|
|
@@ -43359,8 +43595,8 @@ function checkBinaryReadiness() {
|
|
|
43359
43595
|
}
|
|
43360
43596
|
function runToolDoctor(_directory, pluginRoot) {
|
|
43361
43597
|
const findings = [];
|
|
43362
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
43363
|
-
const indexPath =
|
|
43598
|
+
const resolvedPluginRoot = pluginRoot ?? path27.resolve(import.meta.dir, "..", "..");
|
|
43599
|
+
const indexPath = path27.join(resolvedPluginRoot, "src", "index.ts");
|
|
43364
43600
|
if (!fs11.existsSync(indexPath)) {
|
|
43365
43601
|
return {
|
|
43366
43602
|
findings: [
|
|
@@ -44118,12 +44354,12 @@ var init_export = __esm(() => {
|
|
|
44118
44354
|
|
|
44119
44355
|
// src/full-auto/state.ts
|
|
44120
44356
|
import * as fs12 from "fs";
|
|
44121
|
-
import * as
|
|
44357
|
+
import * as path28 from "path";
|
|
44122
44358
|
function nowISO() {
|
|
44123
44359
|
return new Date().toISOString();
|
|
44124
44360
|
}
|
|
44125
44361
|
function ensureSwarmDir(directory) {
|
|
44126
|
-
const swarmDir =
|
|
44362
|
+
const swarmDir = path28.resolve(directory, ".swarm");
|
|
44127
44363
|
if (!fs12.existsSync(swarmDir)) {
|
|
44128
44364
|
fs12.mkdirSync(swarmDir, { recursive: true });
|
|
44129
44365
|
}
|
|
@@ -44824,7 +45060,7 @@ var init_handoff_service = __esm(() => {
|
|
|
44824
45060
|
|
|
44825
45061
|
// src/session/snapshot-writer.ts
|
|
44826
45062
|
import { closeSync as closeSync4, fsyncSync as fsyncSync2, mkdirSync as mkdirSync12, openSync as openSync4, renameSync as renameSync8 } from "fs";
|
|
44827
|
-
import * as
|
|
45063
|
+
import * as path29 from "path";
|
|
44828
45064
|
function serializeAgentSession(s) {
|
|
44829
45065
|
const gateLog = {};
|
|
44830
45066
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -44924,7 +45160,7 @@ async function writeSnapshot(directory, state) {
|
|
|
44924
45160
|
}
|
|
44925
45161
|
const content = JSON.stringify(snapshot, null, 2);
|
|
44926
45162
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
44927
|
-
const dir =
|
|
45163
|
+
const dir = path29.dirname(resolvedPath);
|
|
44928
45164
|
mkdirSync12(dir, { recursive: true });
|
|
44929
45165
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
44930
45166
|
await bunWrite(tempPath, content);
|
|
@@ -45384,9 +45620,9 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
45384
45620
|
|
|
45385
45621
|
// src/hooks/knowledge-migrator.ts
|
|
45386
45622
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
45387
|
-
import { existsSync as
|
|
45388
|
-
import { mkdir as
|
|
45389
|
-
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";
|
|
45390
45626
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
45391
45627
|
return {
|
|
45392
45628
|
migrated: false,
|
|
@@ -45397,10 +45633,10 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
45397
45633
|
};
|
|
45398
45634
|
}
|
|
45399
45635
|
async function migrateContextToKnowledge(directory, config3) {
|
|
45400
|
-
const sentinelPath =
|
|
45401
|
-
const contextPath =
|
|
45636
|
+
const sentinelPath = path30.join(directory, ".swarm", ".knowledge-migrated");
|
|
45637
|
+
const contextPath = path30.join(directory, ".swarm", "context.md");
|
|
45402
45638
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
45403
|
-
if (
|
|
45639
|
+
if (existsSync20(sentinelPath)) {
|
|
45404
45640
|
return {
|
|
45405
45641
|
migrated: false,
|
|
45406
45642
|
entriesMigrated: 0,
|
|
@@ -45409,7 +45645,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
45409
45645
|
skippedReason: "sentinel-exists"
|
|
45410
45646
|
};
|
|
45411
45647
|
}
|
|
45412
|
-
if (!
|
|
45648
|
+
if (!existsSync20(contextPath)) {
|
|
45413
45649
|
return {
|
|
45414
45650
|
migrated: false,
|
|
45415
45651
|
entriesMigrated: 0,
|
|
@@ -45418,7 +45654,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
45418
45654
|
skippedReason: "no-context-file"
|
|
45419
45655
|
};
|
|
45420
45656
|
}
|
|
45421
|
-
const contextContent = await
|
|
45657
|
+
const contextContent = await readFile9(contextPath, "utf-8");
|
|
45422
45658
|
if (contextContent.trim().length === 0) {
|
|
45423
45659
|
return {
|
|
45424
45660
|
migrated: false,
|
|
@@ -45594,8 +45830,8 @@ function truncateLesson(text) {
|
|
|
45594
45830
|
return `${text.slice(0, 277)}...`;
|
|
45595
45831
|
}
|
|
45596
45832
|
function inferProjectName(directory) {
|
|
45597
|
-
const packageJsonPath =
|
|
45598
|
-
if (
|
|
45833
|
+
const packageJsonPath = path30.join(directory, "package.json");
|
|
45834
|
+
if (existsSync20(packageJsonPath)) {
|
|
45599
45835
|
try {
|
|
45600
45836
|
const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
|
|
45601
45837
|
if (pkg.name && typeof pkg.name === "string") {
|
|
@@ -45603,7 +45839,7 @@ function inferProjectName(directory) {
|
|
|
45603
45839
|
}
|
|
45604
45840
|
} catch {}
|
|
45605
45841
|
}
|
|
45606
|
-
return
|
|
45842
|
+
return path30.basename(directory);
|
|
45607
45843
|
}
|
|
45608
45844
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
45609
45845
|
const sentinel = {
|
|
@@ -45615,7 +45851,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
45615
45851
|
schema_version: 1,
|
|
45616
45852
|
migration_tool: "knowledge-migrator.ts"
|
|
45617
45853
|
};
|
|
45618
|
-
await
|
|
45854
|
+
await mkdir8(path30.dirname(sentinelPath), { recursive: true });
|
|
45619
45855
|
await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
45620
45856
|
}
|
|
45621
45857
|
var _internals19;
|
|
@@ -45637,7 +45873,7 @@ var init_knowledge_migrator = __esm(() => {
|
|
|
45637
45873
|
});
|
|
45638
45874
|
|
|
45639
45875
|
// src/commands/knowledge.ts
|
|
45640
|
-
import { join as
|
|
45876
|
+
import { join as join28 } from "path";
|
|
45641
45877
|
function resolveEntryByPrefix(entries, inputId) {
|
|
45642
45878
|
const exact = entries.find((e) => e.id === inputId);
|
|
45643
45879
|
if (exact)
|
|
@@ -45688,7 +45924,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
45688
45924
|
return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
|
|
45689
45925
|
}
|
|
45690
45926
|
try {
|
|
45691
|
-
const quarantinePath =
|
|
45927
|
+
const quarantinePath = join28(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
45692
45928
|
const entries = await readKnowledge(quarantinePath);
|
|
45693
45929
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
45694
45930
|
if ("error" in resolved) {
|
|
@@ -46663,15 +46899,15 @@ var init_scoring = __esm(() => {
|
|
|
46663
46899
|
|
|
46664
46900
|
// src/memory/local-jsonl-provider.ts
|
|
46665
46901
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
46666
|
-
import { existsSync as
|
|
46902
|
+
import { existsSync as existsSync21 } from "fs";
|
|
46667
46903
|
import {
|
|
46668
|
-
appendFile as
|
|
46669
|
-
mkdir as
|
|
46670
|
-
readFile as
|
|
46904
|
+
appendFile as appendFile5,
|
|
46905
|
+
mkdir as mkdir9,
|
|
46906
|
+
readFile as readFile10,
|
|
46671
46907
|
rename as rename6,
|
|
46672
46908
|
writeFile as writeFile9
|
|
46673
46909
|
} from "fs/promises";
|
|
46674
|
-
import * as
|
|
46910
|
+
import * as path31 from "path";
|
|
46675
46911
|
|
|
46676
46912
|
class LocalJsonlMemoryProvider {
|
|
46677
46913
|
name = "local-jsonl";
|
|
@@ -46687,7 +46923,7 @@ class LocalJsonlMemoryProvider {
|
|
|
46687
46923
|
pathFor(file3) {
|
|
46688
46924
|
const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
|
|
46689
46925
|
const filename = file3 === "memories" ? "memories.jsonl" : file3 === "proposals" ? "proposals.jsonl" : "audit.jsonl";
|
|
46690
|
-
return validateSwarmPath(this.rootDirectory,
|
|
46926
|
+
return validateSwarmPath(this.rootDirectory, path31.join(storageDir, filename));
|
|
46691
46927
|
}
|
|
46692
46928
|
async initialize() {
|
|
46693
46929
|
if (this.initialized)
|
|
@@ -47014,9 +47250,9 @@ function validateLoadedProposals(values, config3) {
|
|
|
47014
47250
|
return { records, invalidCount };
|
|
47015
47251
|
}
|
|
47016
47252
|
async function readJsonl(filePath) {
|
|
47017
|
-
if (!
|
|
47253
|
+
if (!existsSync21(filePath))
|
|
47018
47254
|
return [];
|
|
47019
|
-
const content = await
|
|
47255
|
+
const content = await readFile10(filePath, "utf-8");
|
|
47020
47256
|
const records = [];
|
|
47021
47257
|
for (const line of content.split(`
|
|
47022
47258
|
`)) {
|
|
@@ -47070,12 +47306,12 @@ function parseRecallUsageEvent(event) {
|
|
|
47070
47306
|
}
|
|
47071
47307
|
}
|
|
47072
47308
|
async function appendJsonl(filePath, value) {
|
|
47073
|
-
await
|
|
47074
|
-
await
|
|
47309
|
+
await mkdir9(path31.dirname(filePath), { recursive: true });
|
|
47310
|
+
await appendFile5(filePath, `${JSON.stringify(value)}
|
|
47075
47311
|
`, "utf-8");
|
|
47076
47312
|
}
|
|
47077
47313
|
async function writeJsonlAtomic(filePath, values) {
|
|
47078
|
-
await
|
|
47314
|
+
await mkdir9(path31.dirname(filePath), { recursive: true });
|
|
47079
47315
|
const tmp = `${filePath}.tmp.${randomUUID4()}`;
|
|
47080
47316
|
const content = values.map((value) => JSON.stringify(value)).join(`
|
|
47081
47317
|
`) + (values.length > 0 ? `
|
|
@@ -47100,9 +47336,9 @@ var init_prompt_block = __esm(() => {
|
|
|
47100
47336
|
});
|
|
47101
47337
|
|
|
47102
47338
|
// src/memory/jsonl-migration.ts
|
|
47103
|
-
import { existsSync as
|
|
47104
|
-
import { copyFile, mkdir as
|
|
47105
|
-
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";
|
|
47106
47342
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
47107
47343
|
const resolved = resolveConfig(config3);
|
|
47108
47344
|
const storageDir = resolved.storageDir.replace(/^\.swarm[/\\]?/, "");
|
|
@@ -47116,8 +47352,8 @@ function resolveSqliteDatabasePath(rootDirectory, config3 = {}) {
|
|
|
47116
47352
|
async function readLegacyJsonl(rootDirectory, config3 = {}) {
|
|
47117
47353
|
const resolved = resolveConfig(config3);
|
|
47118
47354
|
const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
|
|
47119
|
-
const memoryLoad = await readMemoryJsonl(
|
|
47120
|
-
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);
|
|
47121
47357
|
return {
|
|
47122
47358
|
memories: memoryLoad.records,
|
|
47123
47359
|
proposals: proposalLoad.records,
|
|
@@ -47127,15 +47363,15 @@ async function readLegacyJsonl(rootDirectory, config3 = {}) {
|
|
|
47127
47363
|
}
|
|
47128
47364
|
async function backupLegacyJsonl(rootDirectory, config3 = {}) {
|
|
47129
47365
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
|
|
47130
|
-
const backupDir =
|
|
47131
|
-
await
|
|
47366
|
+
const backupDir = path32.join(storageDir, "backups");
|
|
47367
|
+
await mkdir10(backupDir, { recursive: true });
|
|
47132
47368
|
const results = [];
|
|
47133
47369
|
for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
|
|
47134
|
-
const source =
|
|
47135
|
-
if (!
|
|
47370
|
+
const source = path32.join(storageDir, filename);
|
|
47371
|
+
if (!existsSync22(source))
|
|
47136
47372
|
continue;
|
|
47137
|
-
const backup =
|
|
47138
|
-
if (
|
|
47373
|
+
const backup = path32.join(backupDir, `${filename}.pre-sqlite-migration`);
|
|
47374
|
+
if (existsSync22(backup)) {
|
|
47139
47375
|
results.push({ source, backup, created: false });
|
|
47140
47376
|
continue;
|
|
47141
47377
|
}
|
|
@@ -47145,27 +47381,27 @@ async function backupLegacyJsonl(rootDirectory, config3 = {}) {
|
|
|
47145
47381
|
return results;
|
|
47146
47382
|
}
|
|
47147
47383
|
async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
|
|
47148
|
-
const exportDir =
|
|
47149
|
-
await
|
|
47150
|
-
const memoriesPath =
|
|
47151
|
-
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");
|
|
47152
47388
|
await writeFile10(memoriesPath, toJsonl(memories), "utf-8");
|
|
47153
47389
|
await writeFile10(proposalsPath, toJsonl(proposals), "utf-8");
|
|
47154
47390
|
return { directory: exportDir, memoriesPath, proposalsPath };
|
|
47155
47391
|
}
|
|
47156
47392
|
async function writeMigrationReport(rootDirectory, report, config3 = {}) {
|
|
47157
|
-
const reportPath =
|
|
47158
|
-
await
|
|
47393
|
+
const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
47394
|
+
await mkdir10(path32.dirname(reportPath), { recursive: true });
|
|
47159
47395
|
await writeFile10(reportPath, `${JSON.stringify(report, null, 2)}
|
|
47160
47396
|
`, "utf-8");
|
|
47161
47397
|
return reportPath;
|
|
47162
47398
|
}
|
|
47163
47399
|
async function readMigrationReport(rootDirectory, config3 = {}) {
|
|
47164
|
-
const reportPath =
|
|
47165
|
-
if (!
|
|
47400
|
+
const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
47401
|
+
if (!existsSync22(reportPath))
|
|
47166
47402
|
return null;
|
|
47167
47403
|
try {
|
|
47168
|
-
return JSON.parse(await
|
|
47404
|
+
return JSON.parse(await readFile11(reportPath, "utf-8"));
|
|
47169
47405
|
} catch {
|
|
47170
47406
|
return null;
|
|
47171
47407
|
}
|
|
@@ -47174,15 +47410,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
|
|
|
47174
47410
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
|
|
47175
47411
|
const statuses = [];
|
|
47176
47412
|
for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
|
|
47177
|
-
const filePath =
|
|
47413
|
+
const filePath = path32.join(storageDir, file3);
|
|
47178
47414
|
let sizeBytes = 0;
|
|
47179
|
-
if (
|
|
47415
|
+
if (existsSync22(filePath)) {
|
|
47180
47416
|
sizeBytes = (await stat3(filePath)).size;
|
|
47181
47417
|
}
|
|
47182
47418
|
statuses.push({
|
|
47183
47419
|
file: file3,
|
|
47184
47420
|
path: filePath,
|
|
47185
|
-
exists:
|
|
47421
|
+
exists: existsSync22(filePath),
|
|
47186
47422
|
sizeBytes
|
|
47187
47423
|
});
|
|
47188
47424
|
}
|
|
@@ -47263,10 +47499,10 @@ async function readProposalJsonl(filePath, config3) {
|
|
|
47263
47499
|
return { records, invalidRows, totalRows: rows.totalRows };
|
|
47264
47500
|
}
|
|
47265
47501
|
async function readJsonlRows(filePath) {
|
|
47266
|
-
if (!
|
|
47502
|
+
if (!existsSync22(filePath)) {
|
|
47267
47503
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
47268
47504
|
}
|
|
47269
|
-
const content = await
|
|
47505
|
+
const content = await readFile11(filePath, "utf-8");
|
|
47270
47506
|
const rows = [];
|
|
47271
47507
|
const invalidRows = [];
|
|
47272
47508
|
let totalRows = 0;
|
|
@@ -47303,7 +47539,7 @@ var init_jsonl_migration = __esm(() => {
|
|
|
47303
47539
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
47304
47540
|
import { mkdirSync as mkdirSync13 } from "fs";
|
|
47305
47541
|
import { createRequire as createRequire2 } from "module";
|
|
47306
|
-
import * as
|
|
47542
|
+
import * as path33 from "path";
|
|
47307
47543
|
function loadDatabaseCtor2() {
|
|
47308
47544
|
if (_DatabaseCtor2)
|
|
47309
47545
|
return _DatabaseCtor2;
|
|
@@ -47361,7 +47597,7 @@ class SQLiteMemoryProvider {
|
|
|
47361
47597
|
if (this.initialized)
|
|
47362
47598
|
return;
|
|
47363
47599
|
const dbPath = this.databasePath();
|
|
47364
|
-
mkdirSync13(
|
|
47600
|
+
mkdirSync13(path33.dirname(dbPath), { recursive: true });
|
|
47365
47601
|
const Db = loadDatabaseCtor2();
|
|
47366
47602
|
this.db = new Db(dbPath);
|
|
47367
47603
|
this.db.run("PRAGMA journal_mode = WAL;");
|
|
@@ -47626,8 +47862,8 @@ class SQLiteMemoryProvider {
|
|
|
47626
47862
|
const row = this.requireDb().query("SELECT version, name FROM schema_migrations WHERE name = ? LIMIT 1").get(name);
|
|
47627
47863
|
return Boolean(row);
|
|
47628
47864
|
}
|
|
47629
|
-
markMigration(
|
|
47630
|
-
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]);
|
|
47631
47867
|
}
|
|
47632
47868
|
selectRecallCandidates(request, scopedRecords) {
|
|
47633
47869
|
const ftsQuery = buildFtsQuery(request);
|
|
@@ -48247,9 +48483,9 @@ var init_gateway = __esm(() => {
|
|
|
48247
48483
|
// src/memory/evaluation.ts
|
|
48248
48484
|
import * as fs13 from "fs/promises";
|
|
48249
48485
|
import * as os7 from "os";
|
|
48250
|
-
import * as
|
|
48486
|
+
import * as path34 from "path";
|
|
48251
48487
|
async function evaluateMemoryRecallFixtures(options) {
|
|
48252
|
-
const fixtureDirectory =
|
|
48488
|
+
const fixtureDirectory = path34.resolve(options.fixtureDirectory);
|
|
48253
48489
|
const providers = options.providers ?? DEFAULT_PROVIDERS;
|
|
48254
48490
|
const modes = options.modes ?? DEFAULT_MODES;
|
|
48255
48491
|
const generatedAt = new Date().toISOString();
|
|
@@ -48258,7 +48494,7 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
48258
48494
|
for (const fixture of fixtures) {
|
|
48259
48495
|
const materialized = materializeFixture(fixture);
|
|
48260
48496
|
for (const providerName of providers) {
|
|
48261
|
-
const tempRoot = await fs13.realpath(await fs13.mkdtemp(
|
|
48497
|
+
const tempRoot = await fs13.realpath(await fs13.mkdtemp(path34.join(os7.tmpdir(), "swarm-memory-eval-")));
|
|
48262
48498
|
const provider = createEvaluationProvider(providerName, tempRoot);
|
|
48263
48499
|
try {
|
|
48264
48500
|
await provider.initialize?.();
|
|
@@ -48302,7 +48538,7 @@ async function loadRecallEvaluationFixtures(fixtureDirectory) {
|
|
|
48302
48538
|
const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
48303
48539
|
const fixtures = [];
|
|
48304
48540
|
for (const file3 of files) {
|
|
48305
|
-
const raw = await fs13.readFile(
|
|
48541
|
+
const raw = await fs13.readFile(path34.join(fixtureDirectory, file3), "utf-8");
|
|
48306
48542
|
fixtures.push(validateFixture(JSON.parse(raw), file3));
|
|
48307
48543
|
}
|
|
48308
48544
|
return fixtures;
|
|
@@ -48640,8 +48876,8 @@ var init_memory = __esm(() => {
|
|
|
48640
48876
|
});
|
|
48641
48877
|
|
|
48642
48878
|
// src/commands/memory.ts
|
|
48643
|
-
import { existsSync as
|
|
48644
|
-
import * as
|
|
48879
|
+
import { existsSync as existsSync23 } from "fs";
|
|
48880
|
+
import * as path35 from "path";
|
|
48645
48881
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
48646
48882
|
async function handleMemoryCommand(_directory, _args) {
|
|
48647
48883
|
return [
|
|
@@ -48672,7 +48908,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
48672
48908
|
`- Provider: \`${config3.provider}\``,
|
|
48673
48909
|
`- Storage: \`${storageDir}\``,
|
|
48674
48910
|
`- SQLite path: \`${sqlitePath}\``,
|
|
48675
|
-
`- SQLite database exists: \`${
|
|
48911
|
+
`- SQLite database exists: \`${existsSync23(sqlitePath)}\``,
|
|
48676
48912
|
`- Automatic destructive cleanup: \`disabled\``,
|
|
48677
48913
|
"",
|
|
48678
48914
|
"### Legacy JSONL"
|
|
@@ -48911,7 +49147,7 @@ function resolveCommandMemoryConfig(directory) {
|
|
|
48911
49147
|
}
|
|
48912
49148
|
function parseEvaluateArgs(directory, args) {
|
|
48913
49149
|
let json3 = false;
|
|
48914
|
-
let fixtureDirectory =
|
|
49150
|
+
let fixtureDirectory = path35.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
|
|
48915
49151
|
for (let i = 0;i < args.length; i++) {
|
|
48916
49152
|
const arg = args[i];
|
|
48917
49153
|
if (arg === "--json") {
|
|
@@ -48925,7 +49161,7 @@ function parseEvaluateArgs(directory, args) {
|
|
|
48925
49161
|
error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
|
|
48926
49162
|
};
|
|
48927
49163
|
}
|
|
48928
|
-
fixtureDirectory =
|
|
49164
|
+
fixtureDirectory = path35.resolve(directory, next);
|
|
48929
49165
|
i++;
|
|
48930
49166
|
continue;
|
|
48931
49167
|
}
|
|
@@ -48958,15 +49194,15 @@ function parseMaintenanceArgs(args, options) {
|
|
|
48958
49194
|
return { limit, confirm };
|
|
48959
49195
|
}
|
|
48960
49196
|
function resolvePackageRootFromModule(modulePath) {
|
|
48961
|
-
const moduleDir =
|
|
48962
|
-
const leaf =
|
|
49197
|
+
const moduleDir = path35.dirname(modulePath);
|
|
49198
|
+
const leaf = path35.basename(moduleDir);
|
|
48963
49199
|
if (leaf === "commands" || leaf === "cli") {
|
|
48964
|
-
return
|
|
49200
|
+
return path35.resolve(moduleDir, "..", "..");
|
|
48965
49201
|
}
|
|
48966
49202
|
if (leaf === "dist") {
|
|
48967
|
-
return
|
|
49203
|
+
return path35.resolve(moduleDir, "..");
|
|
48968
49204
|
}
|
|
48969
|
-
return
|
|
49205
|
+
return path35.resolve(moduleDir, "..");
|
|
48970
49206
|
}
|
|
48971
49207
|
function formatMigrationResult(label, report) {
|
|
48972
49208
|
if (!report) {
|
|
@@ -49085,7 +49321,7 @@ var PACKAGE_ROOT;
|
|
|
49085
49321
|
var init_memory2 = __esm(() => {
|
|
49086
49322
|
init_loader();
|
|
49087
49323
|
init_memory();
|
|
49088
|
-
PACKAGE_ROOT =
|
|
49324
|
+
PACKAGE_ROOT = path35.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
|
|
49089
49325
|
});
|
|
49090
49326
|
|
|
49091
49327
|
// src/services/plan-service.ts
|
|
@@ -49473,7 +49709,7 @@ var init_path_security = () => {};
|
|
|
49473
49709
|
|
|
49474
49710
|
// src/tools/lint.ts
|
|
49475
49711
|
import * as fs14 from "fs";
|
|
49476
|
-
import * as
|
|
49712
|
+
import * as path36 from "path";
|
|
49477
49713
|
function validateArgs(args) {
|
|
49478
49714
|
if (typeof args !== "object" || args === null)
|
|
49479
49715
|
return false;
|
|
@@ -49484,9 +49720,9 @@ function validateArgs(args) {
|
|
|
49484
49720
|
}
|
|
49485
49721
|
function getLinterCommand(linter, mode, projectDir) {
|
|
49486
49722
|
const isWindows = process.platform === "win32";
|
|
49487
|
-
const binDir =
|
|
49488
|
-
const biomeBin = isWindows ?
|
|
49489
|
-
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");
|
|
49490
49726
|
switch (linter) {
|
|
49491
49727
|
case "biome":
|
|
49492
49728
|
if (mode === "fix") {
|
|
@@ -49502,7 +49738,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
49502
49738
|
}
|
|
49503
49739
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
49504
49740
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
49505
|
-
const gradlew = fs14.existsSync(
|
|
49741
|
+
const gradlew = fs14.existsSync(path36.join(cwd, gradlewName)) ? path36.join(cwd, gradlewName) : null;
|
|
49506
49742
|
switch (linter) {
|
|
49507
49743
|
case "ruff":
|
|
49508
49744
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -49536,10 +49772,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
49536
49772
|
}
|
|
49537
49773
|
}
|
|
49538
49774
|
function detectRuff(cwd) {
|
|
49539
|
-
if (fs14.existsSync(
|
|
49775
|
+
if (fs14.existsSync(path36.join(cwd, "ruff.toml")))
|
|
49540
49776
|
return isCommandAvailable("ruff");
|
|
49541
49777
|
try {
|
|
49542
|
-
const pyproject =
|
|
49778
|
+
const pyproject = path36.join(cwd, "pyproject.toml");
|
|
49543
49779
|
if (fs14.existsSync(pyproject)) {
|
|
49544
49780
|
const content = fs14.readFileSync(pyproject, "utf-8");
|
|
49545
49781
|
if (content.includes("[tool.ruff]"))
|
|
@@ -49549,19 +49785,19 @@ function detectRuff(cwd) {
|
|
|
49549
49785
|
return false;
|
|
49550
49786
|
}
|
|
49551
49787
|
function detectClippy(cwd) {
|
|
49552
|
-
return fs14.existsSync(
|
|
49788
|
+
return fs14.existsSync(path36.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
49553
49789
|
}
|
|
49554
49790
|
function detectGolangciLint(cwd) {
|
|
49555
|
-
return fs14.existsSync(
|
|
49791
|
+
return fs14.existsSync(path36.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
49556
49792
|
}
|
|
49557
49793
|
function detectCheckstyle(cwd) {
|
|
49558
|
-
const hasMaven = fs14.existsSync(
|
|
49559
|
-
const hasGradle = fs14.existsSync(
|
|
49560
|
-
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"));
|
|
49561
49797
|
return (hasMaven || hasGradle) && hasBinary;
|
|
49562
49798
|
}
|
|
49563
49799
|
function detectKtlint(cwd) {
|
|
49564
|
-
const hasKotlin = fs14.existsSync(
|
|
49800
|
+
const hasKotlin = fs14.existsSync(path36.join(cwd, "build.gradle.kts")) || fs14.existsSync(path36.join(cwd, "build.gradle")) || (() => {
|
|
49565
49801
|
try {
|
|
49566
49802
|
return fs14.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
49567
49803
|
} catch {
|
|
@@ -49580,11 +49816,11 @@ function detectDotnetFormat(cwd) {
|
|
|
49580
49816
|
}
|
|
49581
49817
|
}
|
|
49582
49818
|
function detectCppcheck(cwd) {
|
|
49583
|
-
if (fs14.existsSync(
|
|
49819
|
+
if (fs14.existsSync(path36.join(cwd, "CMakeLists.txt"))) {
|
|
49584
49820
|
return isCommandAvailable("cppcheck");
|
|
49585
49821
|
}
|
|
49586
49822
|
try {
|
|
49587
|
-
const dirsToCheck = [cwd,
|
|
49823
|
+
const dirsToCheck = [cwd, path36.join(cwd, "src")];
|
|
49588
49824
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
49589
49825
|
try {
|
|
49590
49826
|
return fs14.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -49598,13 +49834,13 @@ function detectCppcheck(cwd) {
|
|
|
49598
49834
|
}
|
|
49599
49835
|
}
|
|
49600
49836
|
function detectSwiftlint(cwd) {
|
|
49601
|
-
return fs14.existsSync(
|
|
49837
|
+
return fs14.existsSync(path36.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
49602
49838
|
}
|
|
49603
49839
|
function detectDartAnalyze(cwd) {
|
|
49604
|
-
return fs14.existsSync(
|
|
49840
|
+
return fs14.existsSync(path36.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
49605
49841
|
}
|
|
49606
49842
|
function detectRubocop(cwd) {
|
|
49607
|
-
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"));
|
|
49608
49844
|
}
|
|
49609
49845
|
function detectAdditionalLinter(cwd) {
|
|
49610
49846
|
if (detectRuff(cwd))
|
|
@@ -49632,10 +49868,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
49632
49868
|
function findBinInAncestors(startDir, binName) {
|
|
49633
49869
|
let dir = startDir;
|
|
49634
49870
|
while (true) {
|
|
49635
|
-
const candidate =
|
|
49871
|
+
const candidate = path36.join(dir, "node_modules", ".bin", binName);
|
|
49636
49872
|
if (fs14.existsSync(candidate))
|
|
49637
49873
|
return candidate;
|
|
49638
|
-
const parent =
|
|
49874
|
+
const parent = path36.dirname(dir);
|
|
49639
49875
|
if (parent === dir)
|
|
49640
49876
|
break;
|
|
49641
49877
|
dir = parent;
|
|
@@ -49644,10 +49880,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
49644
49880
|
}
|
|
49645
49881
|
function findBinInEnvPath(binName) {
|
|
49646
49882
|
const searchPath = process.env.PATH ?? "";
|
|
49647
|
-
for (const dir of searchPath.split(
|
|
49883
|
+
for (const dir of searchPath.split(path36.delimiter)) {
|
|
49648
49884
|
if (!dir)
|
|
49649
49885
|
continue;
|
|
49650
|
-
const candidate =
|
|
49886
|
+
const candidate = path36.join(dir, binName);
|
|
49651
49887
|
if (fs14.existsSync(candidate))
|
|
49652
49888
|
return candidate;
|
|
49653
49889
|
}
|
|
@@ -49660,13 +49896,13 @@ async function detectAvailableLinter(directory) {
|
|
|
49660
49896
|
return null;
|
|
49661
49897
|
const projectDir = directory;
|
|
49662
49898
|
const isWindows = process.platform === "win32";
|
|
49663
|
-
const biomeBin = isWindows ?
|
|
49664
|
-
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");
|
|
49665
49901
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
49666
49902
|
if (localResult)
|
|
49667
49903
|
return localResult;
|
|
49668
|
-
const biomeAncestor = findBinInAncestors(
|
|
49669
|
-
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");
|
|
49670
49906
|
if (biomeAncestor || eslintAncestor) {
|
|
49671
49907
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
49672
49908
|
}
|
|
@@ -49889,7 +50125,7 @@ For Rust: rustup component add clippy`
|
|
|
49889
50125
|
|
|
49890
50126
|
// src/tools/secretscan.ts
|
|
49891
50127
|
import * as fs15 from "fs";
|
|
49892
|
-
import * as
|
|
50128
|
+
import * as path37 from "path";
|
|
49893
50129
|
function calculateShannonEntropy(str) {
|
|
49894
50130
|
if (str.length === 0)
|
|
49895
50131
|
return 0;
|
|
@@ -49937,7 +50173,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
49937
50173
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
49938
50174
|
}
|
|
49939
50175
|
function loadSecretScanIgnore(scanDir) {
|
|
49940
|
-
const ignorePath =
|
|
50176
|
+
const ignorePath = path37.join(scanDir, ".secretscanignore");
|
|
49941
50177
|
try {
|
|
49942
50178
|
if (!fs15.existsSync(ignorePath))
|
|
49943
50179
|
return [];
|
|
@@ -49960,7 +50196,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
49960
50196
|
if (exactNames.has(entry))
|
|
49961
50197
|
return true;
|
|
49962
50198
|
for (const pattern of globPatterns) {
|
|
49963
|
-
if (
|
|
50199
|
+
if (path37.matchesGlob(relPath, pattern))
|
|
49964
50200
|
return true;
|
|
49965
50201
|
}
|
|
49966
50202
|
return false;
|
|
@@ -49981,7 +50217,7 @@ function validateDirectoryInput(dir) {
|
|
|
49981
50217
|
return null;
|
|
49982
50218
|
}
|
|
49983
50219
|
function isBinaryFile(filePath, buffer) {
|
|
49984
|
-
const ext =
|
|
50220
|
+
const ext = path37.extname(filePath).toLowerCase();
|
|
49985
50221
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
49986
50222
|
return true;
|
|
49987
50223
|
}
|
|
@@ -50117,9 +50353,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
50117
50353
|
return false;
|
|
50118
50354
|
}
|
|
50119
50355
|
function isPathWithinScope(realPath, scanDir) {
|
|
50120
|
-
const resolvedScanDir =
|
|
50121
|
-
const resolvedRealPath =
|
|
50122
|
-
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}\\`);
|
|
50123
50359
|
}
|
|
50124
50360
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
50125
50361
|
skippedDirs: 0,
|
|
@@ -50145,8 +50381,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
50145
50381
|
return a.localeCompare(b);
|
|
50146
50382
|
});
|
|
50147
50383
|
for (const entry of entries) {
|
|
50148
|
-
const fullPath =
|
|
50149
|
-
const relPath =
|
|
50384
|
+
const fullPath = path37.join(dir, entry);
|
|
50385
|
+
const relPath = path37.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
50150
50386
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
50151
50387
|
stats.skippedDirs++;
|
|
50152
50388
|
continue;
|
|
@@ -50181,7 +50417,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
50181
50417
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
50182
50418
|
files.push(...subFiles);
|
|
50183
50419
|
} else if (lstat.isFile()) {
|
|
50184
|
-
const ext =
|
|
50420
|
+
const ext = path37.extname(fullPath).toLowerCase();
|
|
50185
50421
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
50186
50422
|
files.push(fullPath);
|
|
50187
50423
|
} else {
|
|
@@ -50441,7 +50677,7 @@ var init_secretscan = __esm(() => {
|
|
|
50441
50677
|
}
|
|
50442
50678
|
}
|
|
50443
50679
|
try {
|
|
50444
|
-
const _scanDirRaw =
|
|
50680
|
+
const _scanDirRaw = path37.resolve(directory);
|
|
50445
50681
|
const scanDir = (() => {
|
|
50446
50682
|
try {
|
|
50447
50683
|
return fs15.realpathSync(_scanDirRaw);
|
|
@@ -50588,7 +50824,7 @@ var init_secretscan = __esm(() => {
|
|
|
50588
50824
|
|
|
50589
50825
|
// src/lang/default-backend.ts
|
|
50590
50826
|
import * as fs16 from "fs";
|
|
50591
|
-
import * as
|
|
50827
|
+
import * as path38 from "path";
|
|
50592
50828
|
function detectFileExists(dir, pattern) {
|
|
50593
50829
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
50594
50830
|
try {
|
|
@@ -50600,7 +50836,7 @@ function detectFileExists(dir, pattern) {
|
|
|
50600
50836
|
}
|
|
50601
50837
|
}
|
|
50602
50838
|
try {
|
|
50603
|
-
fs16.accessSync(
|
|
50839
|
+
fs16.accessSync(path38.join(dir, pattern));
|
|
50604
50840
|
return true;
|
|
50605
50841
|
} catch {
|
|
50606
50842
|
return false;
|
|
@@ -50728,8 +50964,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
50728
50964
|
return ["mvn", "test"];
|
|
50729
50965
|
case "gradle": {
|
|
50730
50966
|
const isWindows = process.platform === "win32";
|
|
50731
|
-
const hasGradlewBat = fs16.existsSync(
|
|
50732
|
-
const hasGradlew = fs16.existsSync(
|
|
50967
|
+
const hasGradlewBat = fs16.existsSync(path38.join(dir, "gradlew.bat"));
|
|
50968
|
+
const hasGradlew = fs16.existsSync(path38.join(dir, "gradlew"));
|
|
50733
50969
|
if (hasGradlewBat && isWindows)
|
|
50734
50970
|
return ["gradlew.bat", "test"];
|
|
50735
50971
|
if (hasGradlew)
|
|
@@ -50746,7 +50982,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
50746
50982
|
"cmake-build-release",
|
|
50747
50983
|
"out"
|
|
50748
50984
|
];
|
|
50749
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(
|
|
50985
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path38.join(dir, d, "CMakeCache.txt"))) ?? "build";
|
|
50750
50986
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
50751
50987
|
}
|
|
50752
50988
|
case "swift-test":
|
|
@@ -51033,17 +51269,17 @@ async function defaultSelectBuildCommand(profile, dir) {
|
|
|
51033
51269
|
return null;
|
|
51034
51270
|
}
|
|
51035
51271
|
async function defaultTestFilesFor(profile, sourceFile, dir) {
|
|
51036
|
-
const ext =
|
|
51272
|
+
const ext = path38.extname(sourceFile);
|
|
51037
51273
|
if (!profile.extensions.includes(ext))
|
|
51038
51274
|
return [];
|
|
51039
|
-
const base =
|
|
51040
|
-
const rel =
|
|
51041
|
-
const relDir =
|
|
51275
|
+
const base = path38.basename(sourceFile, ext);
|
|
51276
|
+
const rel = path38.relative(dir, sourceFile);
|
|
51277
|
+
const relDir = path38.dirname(rel);
|
|
51042
51278
|
const stripSrc = relDir.replace(/^src(\/|\\)/, "");
|
|
51043
51279
|
const candidates = new Set;
|
|
51044
51280
|
for (const tDir of ["tests", "test", "__tests__", "spec"]) {
|
|
51045
51281
|
for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
|
|
51046
|
-
candidates.add(
|
|
51282
|
+
candidates.add(path38.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
|
|
51047
51283
|
}
|
|
51048
51284
|
}
|
|
51049
51285
|
const existing = [];
|
|
@@ -51084,7 +51320,7 @@ var init_default_backend = __esm(() => {
|
|
|
51084
51320
|
|
|
51085
51321
|
// src/lang/backends/go.ts
|
|
51086
51322
|
import * as fs17 from "fs";
|
|
51087
|
-
import * as
|
|
51323
|
+
import * as path39 from "path";
|
|
51088
51324
|
function extractImports(_sourceFile, source) {
|
|
51089
51325
|
const out = new Set;
|
|
51090
51326
|
IMPORT_REGEX_SINGLE.lastIndex = 0;
|
|
@@ -51110,7 +51346,7 @@ function extractImports(_sourceFile, source) {
|
|
|
51110
51346
|
async function selectFramework(dir) {
|
|
51111
51347
|
let content;
|
|
51112
51348
|
try {
|
|
51113
|
-
content = fs17.readFileSync(
|
|
51349
|
+
content = fs17.readFileSync(path39.join(dir, "go.mod"), "utf-8");
|
|
51114
51350
|
} catch {
|
|
51115
51351
|
return null;
|
|
51116
51352
|
}
|
|
@@ -51131,16 +51367,16 @@ async function selectFramework(dir) {
|
|
|
51131
51367
|
async function selectEntryPoints(dir) {
|
|
51132
51368
|
const points = [];
|
|
51133
51369
|
try {
|
|
51134
|
-
fs17.accessSync(
|
|
51370
|
+
fs17.accessSync(path39.join(dir, "main.go"));
|
|
51135
51371
|
points.push("main.go");
|
|
51136
51372
|
} catch {}
|
|
51137
51373
|
try {
|
|
51138
|
-
const cmdDir =
|
|
51374
|
+
const cmdDir = path39.join(dir, "cmd");
|
|
51139
51375
|
const subdirs = fs17.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
51140
51376
|
for (const sub of subdirs) {
|
|
51141
|
-
const main =
|
|
51377
|
+
const main = path39.join("cmd", sub.name, "main.go");
|
|
51142
51378
|
try {
|
|
51143
|
-
fs17.accessSync(
|
|
51379
|
+
fs17.accessSync(path39.join(dir, main));
|
|
51144
51380
|
points.push(main);
|
|
51145
51381
|
} catch {}
|
|
51146
51382
|
}
|
|
@@ -51171,7 +51407,7 @@ var init_go = __esm(() => {
|
|
|
51171
51407
|
|
|
51172
51408
|
// src/lang/backends/python.ts
|
|
51173
51409
|
import * as fs18 from "fs";
|
|
51174
|
-
import * as
|
|
51410
|
+
import * as path40 from "path";
|
|
51175
51411
|
function parseImportTargets(rawTargets) {
|
|
51176
51412
|
const cleaned = rawTargets.replace(/[()]/g, "").split(`
|
|
51177
51413
|
`).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
|
|
@@ -51231,7 +51467,7 @@ async function selectFramework2(dir) {
|
|
|
51231
51467
|
];
|
|
51232
51468
|
for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
|
|
51233
51469
|
try {
|
|
51234
|
-
const content = fs18.readFileSync(
|
|
51470
|
+
const content = fs18.readFileSync(path40.join(dir, candidate), "utf-8");
|
|
51235
51471
|
const lower = content.toLowerCase();
|
|
51236
51472
|
for (const [pkg, name] of candidates) {
|
|
51237
51473
|
if (lower.includes(pkg)) {
|
|
@@ -51245,7 +51481,7 @@ async function selectFramework2(dir) {
|
|
|
51245
51481
|
async function selectEntryPoints2(dir) {
|
|
51246
51482
|
const points = new Set;
|
|
51247
51483
|
try {
|
|
51248
|
-
const content = fs18.readFileSync(
|
|
51484
|
+
const content = fs18.readFileSync(path40.join(dir, "pyproject.toml"), "utf-8");
|
|
51249
51485
|
const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
|
|
51250
51486
|
if (scriptsBlock) {
|
|
51251
51487
|
for (const line of scriptsBlock[0].split(`
|
|
@@ -51260,7 +51496,7 @@ async function selectEntryPoints2(dir) {
|
|
|
51260
51496
|
} catch {}
|
|
51261
51497
|
for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
|
|
51262
51498
|
try {
|
|
51263
|
-
fs18.accessSync(
|
|
51499
|
+
fs18.accessSync(path40.join(dir, name));
|
|
51264
51500
|
points.add(name);
|
|
51265
51501
|
} catch {}
|
|
51266
51502
|
}
|
|
@@ -51289,7 +51525,7 @@ var init_python = __esm(() => {
|
|
|
51289
51525
|
|
|
51290
51526
|
// src/test-impact/analyzer.ts
|
|
51291
51527
|
import fs19 from "fs";
|
|
51292
|
-
import
|
|
51528
|
+
import path41 from "path";
|
|
51293
51529
|
function normalizePath(p) {
|
|
51294
51530
|
return p.replace(/\\/g, "/");
|
|
51295
51531
|
}
|
|
@@ -51310,8 +51546,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
51310
51546
|
if (!importPath.startsWith(".")) {
|
|
51311
51547
|
return null;
|
|
51312
51548
|
}
|
|
51313
|
-
const resolved =
|
|
51314
|
-
if (
|
|
51549
|
+
const resolved = path41.resolve(fromDir, importPath);
|
|
51550
|
+
if (path41.extname(resolved)) {
|
|
51315
51551
|
if (fs19.existsSync(resolved) && fs19.statSync(resolved).isFile()) {
|
|
51316
51552
|
return normalizePath(resolved);
|
|
51317
51553
|
}
|
|
@@ -51331,20 +51567,20 @@ function resolvePythonImport(fromDir, module) {
|
|
|
51331
51567
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
51332
51568
|
let baseDir = fromDir;
|
|
51333
51569
|
for (let i = 1;i < leadingDots; i++) {
|
|
51334
|
-
baseDir =
|
|
51570
|
+
baseDir = path41.dirname(baseDir);
|
|
51335
51571
|
}
|
|
51336
51572
|
const rest = module.slice(leadingDots);
|
|
51337
51573
|
if (rest.length === 0) {
|
|
51338
|
-
const initPath =
|
|
51574
|
+
const initPath = path41.join(baseDir, "__init__.py");
|
|
51339
51575
|
if (fs19.existsSync(initPath) && fs19.statSync(initPath).isFile()) {
|
|
51340
51576
|
return normalizePath(initPath);
|
|
51341
51577
|
}
|
|
51342
51578
|
return null;
|
|
51343
51579
|
}
|
|
51344
|
-
const subpath = rest.replace(/\./g,
|
|
51580
|
+
const subpath = rest.replace(/\./g, path41.sep);
|
|
51345
51581
|
const candidates = [
|
|
51346
|
-
`${
|
|
51347
|
-
|
|
51582
|
+
`${path41.join(baseDir, subpath)}.py`,
|
|
51583
|
+
path41.join(baseDir, subpath, "__init__.py")
|
|
51348
51584
|
];
|
|
51349
51585
|
for (const c of candidates) {
|
|
51350
51586
|
if (fs19.existsSync(c) && fs19.statSync(c).isFile())
|
|
@@ -51353,7 +51589,7 @@ function resolvePythonImport(fromDir, module) {
|
|
|
51353
51589
|
return null;
|
|
51354
51590
|
}
|
|
51355
51591
|
function findGoModule(fromDir) {
|
|
51356
|
-
const resolved =
|
|
51592
|
+
const resolved = path41.resolve(fromDir);
|
|
51357
51593
|
let cur = resolved;
|
|
51358
51594
|
const walked = [];
|
|
51359
51595
|
for (let i = 0;i < 16; i++) {
|
|
@@ -51365,7 +51601,7 @@ function findGoModule(fromDir) {
|
|
|
51365
51601
|
}
|
|
51366
51602
|
walked.push(cur);
|
|
51367
51603
|
try {
|
|
51368
|
-
const goMod =
|
|
51604
|
+
const goMod = path41.join(cur, "go.mod");
|
|
51369
51605
|
const content = fs19.readFileSync(goMod, "utf-8");
|
|
51370
51606
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
51371
51607
|
if (moduleMatch) {
|
|
@@ -51376,10 +51612,10 @@ function findGoModule(fromDir) {
|
|
|
51376
51612
|
}
|
|
51377
51613
|
} catch {}
|
|
51378
51614
|
try {
|
|
51379
|
-
fs19.accessSync(
|
|
51615
|
+
fs19.accessSync(path41.join(cur, ".git"));
|
|
51380
51616
|
break;
|
|
51381
51617
|
} catch {}
|
|
51382
|
-
const parent =
|
|
51618
|
+
const parent = path41.dirname(cur);
|
|
51383
51619
|
if (parent === cur)
|
|
51384
51620
|
break;
|
|
51385
51621
|
cur = parent;
|
|
@@ -51391,12 +51627,12 @@ function findGoModule(fromDir) {
|
|
|
51391
51627
|
function resolveGoImport(fromDir, importPath) {
|
|
51392
51628
|
let dir = null;
|
|
51393
51629
|
if (importPath.startsWith(".")) {
|
|
51394
|
-
dir =
|
|
51630
|
+
dir = path41.resolve(fromDir, importPath);
|
|
51395
51631
|
} else {
|
|
51396
51632
|
const mod = findGoModule(fromDir);
|
|
51397
51633
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
51398
51634
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
51399
|
-
dir =
|
|
51635
|
+
dir = path41.join(mod.moduleRoot, subpath);
|
|
51400
51636
|
}
|
|
51401
51637
|
}
|
|
51402
51638
|
if (dir === null)
|
|
@@ -51404,7 +51640,7 @@ function resolveGoImport(fromDir, importPath) {
|
|
|
51404
51640
|
if (!fs19.existsSync(dir) || !fs19.statSync(dir).isDirectory())
|
|
51405
51641
|
return [];
|
|
51406
51642
|
try {
|
|
51407
|
-
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)));
|
|
51408
51644
|
} catch {
|
|
51409
51645
|
return [];
|
|
51410
51646
|
}
|
|
@@ -51443,15 +51679,15 @@ function findTestFilesSync(cwd) {
|
|
|
51443
51679
|
for (const entry of entries) {
|
|
51444
51680
|
if (entry.isDirectory()) {
|
|
51445
51681
|
if (!skipDirs.has(entry.name)) {
|
|
51446
|
-
walk(
|
|
51682
|
+
walk(path41.join(dir, entry.name), visitedInodes);
|
|
51447
51683
|
}
|
|
51448
51684
|
} else if (entry.isFile()) {
|
|
51449
51685
|
const name = entry.name;
|
|
51450
51686
|
const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
|
|
51451
|
-
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");
|
|
51452
51688
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
51453
51689
|
if (isTsTest || isPyTest || isGoTest) {
|
|
51454
|
-
testFiles.push(normalizePath(
|
|
51690
|
+
testFiles.push(normalizePath(path41.join(dir, entry.name)));
|
|
51455
51691
|
}
|
|
51456
51692
|
}
|
|
51457
51693
|
}
|
|
@@ -51476,8 +51712,8 @@ function extractImports3(content) {
|
|
|
51476
51712
|
];
|
|
51477
51713
|
}
|
|
51478
51714
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
51479
|
-
const ext =
|
|
51480
|
-
const testDir =
|
|
51715
|
+
const ext = path41.extname(testFile).toLowerCase();
|
|
51716
|
+
const testDir = path41.dirname(testFile);
|
|
51481
51717
|
function addEdge(source) {
|
|
51482
51718
|
if (!impactMap[source])
|
|
51483
51719
|
impactMap[source] = [];
|
|
@@ -51536,7 +51772,7 @@ async function buildImpactMap(cwd) {
|
|
|
51536
51772
|
return impactMap;
|
|
51537
51773
|
}
|
|
51538
51774
|
async function loadImpactMap(cwd, options) {
|
|
51539
|
-
const cachePath =
|
|
51775
|
+
const cachePath = path41.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
51540
51776
|
if (fs19.existsSync(cachePath)) {
|
|
51541
51777
|
try {
|
|
51542
51778
|
const content = fs19.readFileSync(cachePath, "utf-8");
|
|
@@ -51569,12 +51805,12 @@ async function loadImpactMap(cwd, options) {
|
|
|
51569
51805
|
return _internals25.buildImpactMap(cwd);
|
|
51570
51806
|
}
|
|
51571
51807
|
async function saveImpactMap(cwd, impactMap) {
|
|
51572
|
-
if (!
|
|
51808
|
+
if (!path41.isAbsolute(cwd)) {
|
|
51573
51809
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
51574
51810
|
}
|
|
51575
51811
|
_internals25.validateProjectRoot(cwd);
|
|
51576
|
-
const cacheDir2 =
|
|
51577
|
-
const cachePath =
|
|
51812
|
+
const cacheDir2 = path41.join(cwd, ".swarm", "cache");
|
|
51813
|
+
const cachePath = path41.join(cacheDir2, "impact-map.json");
|
|
51578
51814
|
if (!fs19.existsSync(cacheDir2)) {
|
|
51579
51815
|
fs19.mkdirSync(cacheDir2, { recursive: true });
|
|
51580
51816
|
}
|
|
@@ -51606,7 +51842,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
51606
51842
|
budgetExceeded = true;
|
|
51607
51843
|
break;
|
|
51608
51844
|
}
|
|
51609
|
-
const normalizedChanged = normalizePath(
|
|
51845
|
+
const normalizedChanged = normalizePath(path41.resolve(changedFile));
|
|
51610
51846
|
const tests = impactMap[normalizedChanged];
|
|
51611
51847
|
if (tests && tests.length > 0) {
|
|
51612
51848
|
for (const test of tests) {
|
|
@@ -51899,15 +52135,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
|
|
|
51899
52135
|
|
|
51900
52136
|
// src/test-impact/history-store.ts
|
|
51901
52137
|
import fs20 from "fs";
|
|
51902
|
-
import
|
|
52138
|
+
import path42 from "path";
|
|
51903
52139
|
function getHistoryPath(workingDir) {
|
|
51904
52140
|
if (!workingDir) {
|
|
51905
52141
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
51906
52142
|
}
|
|
51907
|
-
if (!
|
|
52143
|
+
if (!path42.isAbsolute(workingDir)) {
|
|
51908
52144
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
51909
52145
|
}
|
|
51910
|
-
return
|
|
52146
|
+
return path42.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
51911
52147
|
}
|
|
51912
52148
|
function sanitizeErrorMessage(errorMessage) {
|
|
51913
52149
|
if (errorMessage === undefined) {
|
|
@@ -51994,7 +52230,7 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
51994
52230
|
}
|
|
51995
52231
|
}
|
|
51996
52232
|
const historyPath = getHistoryPath(workingDir);
|
|
51997
|
-
const historyDir =
|
|
52233
|
+
const historyDir = path42.dirname(historyPath);
|
|
51998
52234
|
_internals26.validateProjectRoot(workingDir);
|
|
51999
52235
|
if (!fs20.existsSync(historyDir)) {
|
|
52000
52236
|
fs20.mkdirSync(historyDir, { recursive: true });
|
|
@@ -52090,7 +52326,7 @@ var init_history_store = __esm(() => {
|
|
|
52090
52326
|
|
|
52091
52327
|
// src/tools/resolve-working-directory.ts
|
|
52092
52328
|
import * as fs21 from "fs";
|
|
52093
|
-
import * as
|
|
52329
|
+
import * as path43 from "path";
|
|
52094
52330
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
52095
52331
|
if (workingDirectory == null || workingDirectory === "") {
|
|
52096
52332
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -52110,15 +52346,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52110
52346
|
};
|
|
52111
52347
|
}
|
|
52112
52348
|
}
|
|
52113
|
-
const normalizedDir =
|
|
52114
|
-
const pathParts = normalizedDir.split(
|
|
52349
|
+
const normalizedDir = path43.normalize(workingDirectory);
|
|
52350
|
+
const pathParts = normalizedDir.split(path43.sep);
|
|
52115
52351
|
if (pathParts.includes("..")) {
|
|
52116
52352
|
return {
|
|
52117
52353
|
success: false,
|
|
52118
52354
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
52119
52355
|
};
|
|
52120
52356
|
}
|
|
52121
|
-
const resolvedDir =
|
|
52357
|
+
const resolvedDir = path43.resolve(normalizedDir);
|
|
52122
52358
|
let statResult;
|
|
52123
52359
|
try {
|
|
52124
52360
|
statResult = fs21.statSync(resolvedDir);
|
|
@@ -52134,7 +52370,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52134
52370
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
52135
52371
|
};
|
|
52136
52372
|
}
|
|
52137
|
-
const resolvedFallback =
|
|
52373
|
+
const resolvedFallback = path43.resolve(fallbackDirectory);
|
|
52138
52374
|
let fallbackExists = false;
|
|
52139
52375
|
try {
|
|
52140
52376
|
fs21.statSync(resolvedFallback);
|
|
@@ -52144,7 +52380,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
52144
52380
|
}
|
|
52145
52381
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
52146
52382
|
if (fallbackExists) {
|
|
52147
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
52383
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path43.sep);
|
|
52148
52384
|
if (isSubdirectory) {
|
|
52149
52385
|
return {
|
|
52150
52386
|
success: false,
|
|
@@ -52199,10 +52435,10 @@ var init_registry_backend = __esm(() => {
|
|
|
52199
52435
|
|
|
52200
52436
|
// src/lang/backends/typescript.ts
|
|
52201
52437
|
import * as fs22 from "fs";
|
|
52202
|
-
import * as
|
|
52438
|
+
import * as path44 from "path";
|
|
52203
52439
|
function readPackageJsonRaw(dir) {
|
|
52204
52440
|
try {
|
|
52205
|
-
const content = fs22.readFileSync(
|
|
52441
|
+
const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
|
|
52206
52442
|
return JSON.parse(content);
|
|
52207
52443
|
} catch {
|
|
52208
52444
|
return null;
|
|
@@ -52422,7 +52658,7 @@ __export(exports_dispatch, {
|
|
|
52422
52658
|
_internals: () => _internals28
|
|
52423
52659
|
});
|
|
52424
52660
|
import * as fs23 from "fs";
|
|
52425
|
-
import * as
|
|
52661
|
+
import * as path45 from "path";
|
|
52426
52662
|
function safeReaddirSet(dir) {
|
|
52427
52663
|
try {
|
|
52428
52664
|
return new Set(fs23.readdirSync(dir));
|
|
@@ -52439,14 +52675,14 @@ function manifestHash(dir) {
|
|
|
52439
52675
|
if (!entries.has(name))
|
|
52440
52676
|
continue;
|
|
52441
52677
|
try {
|
|
52442
|
-
const stat4 = fs23.statSync(
|
|
52678
|
+
const stat4 = fs23.statSync(path45.join(dir, name));
|
|
52443
52679
|
parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
|
|
52444
52680
|
} catch {}
|
|
52445
52681
|
}
|
|
52446
52682
|
return parts.join("|");
|
|
52447
52683
|
}
|
|
52448
52684
|
function findManifestRoot(start) {
|
|
52449
|
-
const resolved =
|
|
52685
|
+
const resolved = path45.resolve(start);
|
|
52450
52686
|
const cached3 = manifestRootCache.get(resolved);
|
|
52451
52687
|
if (cached3 !== undefined)
|
|
52452
52688
|
return cached3;
|
|
@@ -52465,7 +52701,7 @@ function findManifestRoot(start) {
|
|
|
52465
52701
|
return cur;
|
|
52466
52702
|
}
|
|
52467
52703
|
}
|
|
52468
|
-
const parent =
|
|
52704
|
+
const parent = path45.dirname(cur);
|
|
52469
52705
|
if (parent === cur)
|
|
52470
52706
|
break;
|
|
52471
52707
|
cur = parent;
|
|
@@ -52575,13 +52811,13 @@ var init_dispatch = __esm(() => {
|
|
|
52575
52811
|
|
|
52576
52812
|
// src/tools/test-runner.ts
|
|
52577
52813
|
import * as fs24 from "fs";
|
|
52578
|
-
import * as
|
|
52814
|
+
import * as path46 from "path";
|
|
52579
52815
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
52580
52816
|
try {
|
|
52581
52817
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
52582
52818
|
const uniqueTestFiles = new Set;
|
|
52583
52819
|
for (const sourceFile of sourceFiles) {
|
|
52584
|
-
const resolvedPath =
|
|
52820
|
+
const resolvedPath = path46.resolve(cwd, sourceFile);
|
|
52585
52821
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
52586
52822
|
const testFiles = impactMap[normalizedPath];
|
|
52587
52823
|
if (testFiles) {
|
|
@@ -52659,14 +52895,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
52659
52895
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
52660
52896
|
}
|
|
52661
52897
|
function detectGoTest(cwd) {
|
|
52662
|
-
return fs24.existsSync(
|
|
52898
|
+
return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
52663
52899
|
}
|
|
52664
52900
|
function detectJavaMaven(cwd) {
|
|
52665
|
-
return fs24.existsSync(
|
|
52901
|
+
return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
52666
52902
|
}
|
|
52667
52903
|
function detectGradle(cwd) {
|
|
52668
|
-
const hasBuildFile = fs24.existsSync(
|
|
52669
|
-
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"));
|
|
52670
52906
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
52671
52907
|
}
|
|
52672
52908
|
function detectDotnetTest(cwd) {
|
|
@@ -52679,25 +52915,25 @@ function detectDotnetTest(cwd) {
|
|
|
52679
52915
|
}
|
|
52680
52916
|
}
|
|
52681
52917
|
function detectCTest(cwd) {
|
|
52682
|
-
const hasSource = fs24.existsSync(
|
|
52683
|
-
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"));
|
|
52684
52920
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
52685
52921
|
}
|
|
52686
52922
|
function detectSwiftTest(cwd) {
|
|
52687
|
-
return fs24.existsSync(
|
|
52923
|
+
return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
52688
52924
|
}
|
|
52689
52925
|
function detectDartTest(cwd) {
|
|
52690
|
-
return fs24.existsSync(
|
|
52926
|
+
return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
52691
52927
|
}
|
|
52692
52928
|
function detectRSpec(cwd) {
|
|
52693
|
-
const hasRSpecFile = fs24.existsSync(
|
|
52694
|
-
const hasGemfile = fs24.existsSync(
|
|
52695
|
-
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"));
|
|
52696
52932
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
52697
52933
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
52698
52934
|
}
|
|
52699
52935
|
function detectMinitest(cwd) {
|
|
52700
|
-
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");
|
|
52701
52937
|
}
|
|
52702
52938
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
52703
52939
|
try {
|
|
@@ -52759,7 +52995,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
52759
52995
|
async function detectTestFramework(cwd) {
|
|
52760
52996
|
const baseDir = cwd;
|
|
52761
52997
|
try {
|
|
52762
|
-
const packageJsonPath =
|
|
52998
|
+
const packageJsonPath = path46.join(baseDir, "package.json");
|
|
52763
52999
|
if (fs24.existsSync(packageJsonPath)) {
|
|
52764
53000
|
const content = fs24.readFileSync(packageJsonPath, "utf-8");
|
|
52765
53001
|
const pkg = JSON.parse(content);
|
|
@@ -52780,16 +53016,16 @@ async function detectTestFramework(cwd) {
|
|
|
52780
53016
|
return "jest";
|
|
52781
53017
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
52782
53018
|
return "mocha";
|
|
52783
|
-
if (fs24.existsSync(
|
|
53019
|
+
if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
|
|
52784
53020
|
if (scripts.test?.includes("bun"))
|
|
52785
53021
|
return "bun";
|
|
52786
53022
|
}
|
|
52787
53023
|
}
|
|
52788
53024
|
} catch {}
|
|
52789
53025
|
try {
|
|
52790
|
-
const pyprojectTomlPath =
|
|
52791
|
-
const setupCfgPath =
|
|
52792
|
-
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");
|
|
52793
53029
|
if (fs24.existsSync(pyprojectTomlPath)) {
|
|
52794
53030
|
const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
|
|
52795
53031
|
if (content.includes("[tool.pytest"))
|
|
@@ -52809,7 +53045,7 @@ async function detectTestFramework(cwd) {
|
|
|
52809
53045
|
}
|
|
52810
53046
|
} catch {}
|
|
52811
53047
|
try {
|
|
52812
|
-
const cargoTomlPath =
|
|
53048
|
+
const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
|
|
52813
53049
|
if (fs24.existsSync(cargoTomlPath)) {
|
|
52814
53050
|
const content = fs24.readFileSync(cargoTomlPath, "utf-8");
|
|
52815
53051
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -52820,9 +53056,9 @@ async function detectTestFramework(cwd) {
|
|
|
52820
53056
|
}
|
|
52821
53057
|
} catch {}
|
|
52822
53058
|
try {
|
|
52823
|
-
const pesterConfigPath =
|
|
52824
|
-
const pesterConfigJsonPath =
|
|
52825
|
-
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");
|
|
52826
53062
|
if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
|
|
52827
53063
|
return "pester";
|
|
52828
53064
|
}
|
|
@@ -52851,12 +53087,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
52851
53087
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
52852
53088
|
}
|
|
52853
53089
|
function resolveWorkspacePath(file3, workingDir) {
|
|
52854
|
-
return
|
|
53090
|
+
return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
|
|
52855
53091
|
}
|
|
52856
53092
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
52857
53093
|
if (!preferRelative)
|
|
52858
53094
|
return absolutePath;
|
|
52859
|
-
return
|
|
53095
|
+
return path46.relative(workingDir, absolutePath);
|
|
52860
53096
|
}
|
|
52861
53097
|
function dedupePush(target, value) {
|
|
52862
53098
|
if (!target.includes(value)) {
|
|
@@ -52893,18 +53129,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
52893
53129
|
}
|
|
52894
53130
|
}
|
|
52895
53131
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
52896
|
-
const relativeDir =
|
|
53132
|
+
const relativeDir = path46.dirname(relativePath);
|
|
52897
53133
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
52898
53134
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
52899
|
-
const rootDir =
|
|
52900
|
-
return nestedRelativeDir ? [rootDir,
|
|
53135
|
+
const rootDir = path46.join(workingDir, dirName);
|
|
53136
|
+
return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
52901
53137
|
});
|
|
52902
53138
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
52903
53139
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
52904
|
-
directories.push(
|
|
53140
|
+
directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
52905
53141
|
}
|
|
52906
53142
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
52907
|
-
directories.push(
|
|
53143
|
+
directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
52908
53144
|
}
|
|
52909
53145
|
return [...new Set(directories)];
|
|
52910
53146
|
}
|
|
@@ -52932,23 +53168,23 @@ function isLanguageSpecificTestFile(basename7) {
|
|
|
52932
53168
|
}
|
|
52933
53169
|
function isConventionTestFilePath(filePath) {
|
|
52934
53170
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
52935
|
-
const basename7 =
|
|
53171
|
+
const basename7 = path46.basename(filePath);
|
|
52936
53172
|
return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
|
|
52937
53173
|
}
|
|
52938
53174
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
52939
53175
|
const testFiles = [];
|
|
52940
53176
|
for (const file3 of sourceFiles) {
|
|
52941
53177
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
52942
|
-
const relativeFile =
|
|
52943
|
-
const basename7 =
|
|
52944
|
-
const
|
|
52945
|
-
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);
|
|
52946
53182
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
52947
53183
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
52948
53184
|
continue;
|
|
52949
53185
|
}
|
|
52950
53186
|
const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
|
|
52951
|
-
const ext =
|
|
53187
|
+
const ext = path46.extname(basename7);
|
|
52952
53188
|
const genericTestNames = [
|
|
52953
53189
|
`${nameWithoutExt}.spec${ext}`,
|
|
52954
53190
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -52957,7 +53193,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
52957
53193
|
const colocatedCandidates = [
|
|
52958
53194
|
...genericTestNames,
|
|
52959
53195
|
...languageSpecificTestNames
|
|
52960
|
-
].map((candidateName) =>
|
|
53196
|
+
].map((candidateName) => path46.join(dirname23, candidateName));
|
|
52961
53197
|
const testDirectoryNames = [
|
|
52962
53198
|
basename7,
|
|
52963
53199
|
...genericTestNames,
|
|
@@ -52966,8 +53202,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
52966
53202
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
52967
53203
|
const possibleTestFiles = [
|
|
52968
53204
|
...colocatedCandidates,
|
|
52969
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
52970
|
-
...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)))
|
|
52971
53207
|
];
|
|
52972
53208
|
for (const testFile of possibleTestFiles) {
|
|
52973
53209
|
if (fs24.existsSync(testFile)) {
|
|
@@ -52988,7 +53224,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
52988
53224
|
try {
|
|
52989
53225
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
52990
53226
|
const content = fs24.readFileSync(absoluteTestFile, "utf-8");
|
|
52991
|
-
const testDir =
|
|
53227
|
+
const testDir = path46.dirname(absoluteTestFile);
|
|
52992
53228
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
52993
53229
|
let match;
|
|
52994
53230
|
match = importRegex.exec(content);
|
|
@@ -52996,8 +53232,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
52996
53232
|
const importPath = match[1];
|
|
52997
53233
|
let resolvedImport;
|
|
52998
53234
|
if (importPath.startsWith(".")) {
|
|
52999
|
-
resolvedImport =
|
|
53000
|
-
const existingExt =
|
|
53235
|
+
resolvedImport = path46.resolve(testDir, importPath);
|
|
53236
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53001
53237
|
if (!existingExt) {
|
|
53002
53238
|
for (const extToTry of [
|
|
53003
53239
|
".ts",
|
|
@@ -53017,12 +53253,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53017
53253
|
} else {
|
|
53018
53254
|
continue;
|
|
53019
53255
|
}
|
|
53020
|
-
const importBasename =
|
|
53021
|
-
const importDir =
|
|
53256
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
53257
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53022
53258
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53023
|
-
const sourceDir =
|
|
53024
|
-
const sourceBasename =
|
|
53025
|
-
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");
|
|
53026
53262
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53027
53263
|
dedupePush(testFiles, testFile);
|
|
53028
53264
|
break;
|
|
@@ -53035,8 +53271,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53035
53271
|
while (match !== null) {
|
|
53036
53272
|
const importPath = match[1];
|
|
53037
53273
|
if (importPath.startsWith(".")) {
|
|
53038
|
-
let resolvedImport =
|
|
53039
|
-
const existingExt =
|
|
53274
|
+
let resolvedImport = path46.resolve(testDir, importPath);
|
|
53275
|
+
const existingExt = path46.extname(resolvedImport);
|
|
53040
53276
|
if (!existingExt) {
|
|
53041
53277
|
for (const extToTry of [
|
|
53042
53278
|
".ts",
|
|
@@ -53053,12 +53289,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
53053
53289
|
}
|
|
53054
53290
|
}
|
|
53055
53291
|
}
|
|
53056
|
-
const importDir =
|
|
53057
|
-
const importBasename =
|
|
53292
|
+
const importDir = path46.dirname(resolvedImport);
|
|
53293
|
+
const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
|
|
53058
53294
|
for (const sourceFile of absoluteSourceFiles) {
|
|
53059
|
-
const sourceDir =
|
|
53060
|
-
const sourceBasename =
|
|
53061
|
-
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");
|
|
53062
53298
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
53063
53299
|
dedupePush(testFiles, testFile);
|
|
53064
53300
|
break;
|
|
@@ -53168,8 +53404,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53168
53404
|
return ["mvn", "test"];
|
|
53169
53405
|
case "gradle": {
|
|
53170
53406
|
const isWindows = process.platform === "win32";
|
|
53171
|
-
const hasGradlewBat = fs24.existsSync(
|
|
53172
|
-
const hasGradlew = fs24.existsSync(
|
|
53407
|
+
const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
|
|
53408
|
+
const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
|
|
53173
53409
|
if (hasGradlewBat && isWindows)
|
|
53174
53410
|
return ["gradlew.bat", "test"];
|
|
53175
53411
|
if (hasGradlew)
|
|
@@ -53186,7 +53422,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
53186
53422
|
"cmake-build-release",
|
|
53187
53423
|
"out"
|
|
53188
53424
|
];
|
|
53189
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(
|
|
53425
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
53190
53426
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
53191
53427
|
}
|
|
53192
53428
|
case "swift-test":
|
|
@@ -53618,11 +53854,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
53618
53854
|
};
|
|
53619
53855
|
}
|
|
53620
53856
|
const startTime = Date.now();
|
|
53621
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
53857
|
+
const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
53622
53858
|
try {
|
|
53623
53859
|
if (vitestJsonOutputPath) {
|
|
53624
53860
|
try {
|
|
53625
|
-
fs24.mkdirSync(
|
|
53861
|
+
fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
|
|
53626
53862
|
if (fs24.existsSync(vitestJsonOutputPath)) {
|
|
53627
53863
|
fs24.unlinkSync(vitestJsonOutputPath);
|
|
53628
53864
|
}
|
|
@@ -53738,10 +53974,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
53738
53974
|
}
|
|
53739
53975
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
53740
53976
|
const normalized = testFile.replace(/\\/g, "/");
|
|
53741
|
-
if (!
|
|
53977
|
+
if (!path46.isAbsolute(testFile))
|
|
53742
53978
|
return normalized;
|
|
53743
|
-
const relative9 =
|
|
53744
|
-
if (relative9.startsWith("..") ||
|
|
53979
|
+
const relative9 = path46.relative(workingDir, testFile);
|
|
53980
|
+
if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
|
|
53745
53981
|
return normalized;
|
|
53746
53982
|
}
|
|
53747
53983
|
return relative9.replace(/\\/g, "/");
|
|
@@ -54079,7 +54315,7 @@ var init_test_runner = __esm(() => {
|
|
|
54079
54315
|
const sourceFiles = args.files.filter((file3) => {
|
|
54080
54316
|
if (directTestFiles.includes(file3))
|
|
54081
54317
|
return false;
|
|
54082
|
-
const ext =
|
|
54318
|
+
const ext = path46.extname(file3).toLowerCase();
|
|
54083
54319
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54084
54320
|
});
|
|
54085
54321
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -54125,7 +54361,7 @@ var init_test_runner = __esm(() => {
|
|
|
54125
54361
|
if (isConventionTestFilePath(f)) {
|
|
54126
54362
|
return false;
|
|
54127
54363
|
}
|
|
54128
|
-
const ext =
|
|
54364
|
+
const ext = path46.extname(f).toLowerCase();
|
|
54129
54365
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54130
54366
|
});
|
|
54131
54367
|
if (sourceFiles.length === 0) {
|
|
@@ -54175,7 +54411,7 @@ var init_test_runner = __esm(() => {
|
|
|
54175
54411
|
if (isConventionTestFilePath(f)) {
|
|
54176
54412
|
return false;
|
|
54177
54413
|
}
|
|
54178
|
-
const ext =
|
|
54414
|
+
const ext = path46.extname(f).toLowerCase();
|
|
54179
54415
|
return SOURCE_EXTENSIONS.has(ext);
|
|
54180
54416
|
});
|
|
54181
54417
|
if (sourceFiles.length === 0) {
|
|
@@ -54227,8 +54463,8 @@ var init_test_runner = __esm(() => {
|
|
|
54227
54463
|
}
|
|
54228
54464
|
if (impactResult.impactedTests.length > 0) {
|
|
54229
54465
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
54230
|
-
const relativePath =
|
|
54231
|
-
return
|
|
54466
|
+
const relativePath = path46.relative(workingDir, absPath);
|
|
54467
|
+
return path46.isAbsolute(relativePath) ? absPath : relativePath;
|
|
54232
54468
|
});
|
|
54233
54469
|
} else {
|
|
54234
54470
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -54304,7 +54540,7 @@ var init_test_runner = __esm(() => {
|
|
|
54304
54540
|
|
|
54305
54541
|
// src/services/preflight-service.ts
|
|
54306
54542
|
import * as fs25 from "fs";
|
|
54307
|
-
import * as
|
|
54543
|
+
import * as path47 from "path";
|
|
54308
54544
|
function validateDirectoryPath(dir) {
|
|
54309
54545
|
if (!dir || typeof dir !== "string") {
|
|
54310
54546
|
throw new Error("Directory path is required");
|
|
@@ -54312,8 +54548,8 @@ function validateDirectoryPath(dir) {
|
|
|
54312
54548
|
if (dir.includes("..")) {
|
|
54313
54549
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
54314
54550
|
}
|
|
54315
|
-
const normalized =
|
|
54316
|
-
const absolutePath =
|
|
54551
|
+
const normalized = path47.normalize(dir);
|
|
54552
|
+
const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
|
|
54317
54553
|
return absolutePath;
|
|
54318
54554
|
}
|
|
54319
54555
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -54336,7 +54572,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
54336
54572
|
}
|
|
54337
54573
|
function getPackageVersion(dir) {
|
|
54338
54574
|
try {
|
|
54339
|
-
const packagePath =
|
|
54575
|
+
const packagePath = path47.join(dir, "package.json");
|
|
54340
54576
|
if (fs25.existsSync(packagePath)) {
|
|
54341
54577
|
const content = fs25.readFileSync(packagePath, "utf-8");
|
|
54342
54578
|
const pkg = JSON.parse(content);
|
|
@@ -54347,7 +54583,7 @@ function getPackageVersion(dir) {
|
|
|
54347
54583
|
}
|
|
54348
54584
|
function getChangelogVersion(dir) {
|
|
54349
54585
|
try {
|
|
54350
|
-
const changelogPath =
|
|
54586
|
+
const changelogPath = path47.join(dir, "CHANGELOG.md");
|
|
54351
54587
|
if (fs25.existsSync(changelogPath)) {
|
|
54352
54588
|
const content = fs25.readFileSync(changelogPath, "utf-8");
|
|
54353
54589
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -54361,7 +54597,7 @@ function getChangelogVersion(dir) {
|
|
|
54361
54597
|
function getVersionFileVersion(dir) {
|
|
54362
54598
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
54363
54599
|
for (const file3 of possibleFiles) {
|
|
54364
|
-
const filePath =
|
|
54600
|
+
const filePath = path47.join(dir, file3);
|
|
54365
54601
|
if (fs25.existsSync(filePath)) {
|
|
54366
54602
|
try {
|
|
54367
54603
|
const content = fs25.readFileSync(filePath, "utf-8").trim();
|
|
@@ -54703,7 +54939,7 @@ async function runEvidenceCheck(dir) {
|
|
|
54703
54939
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
54704
54940
|
const startTime = Date.now();
|
|
54705
54941
|
try {
|
|
54706
|
-
const specPath =
|
|
54942
|
+
const specPath = path47.join(dir, ".swarm", "spec.md");
|
|
54707
54943
|
if (!fs25.existsSync(specPath)) {
|
|
54708
54944
|
return {
|
|
54709
54945
|
type: "req_coverage",
|
|
@@ -55821,7 +56057,7 @@ var init_manager3 = __esm(() => {
|
|
|
55821
56057
|
|
|
55822
56058
|
// src/commands/reset.ts
|
|
55823
56059
|
import * as fs26 from "fs";
|
|
55824
|
-
import * as
|
|
56060
|
+
import * as path48 from "path";
|
|
55825
56061
|
async function handleResetCommand(directory, args) {
|
|
55826
56062
|
const hasConfirm = args.includes("--confirm");
|
|
55827
56063
|
if (!hasConfirm) {
|
|
@@ -55861,7 +56097,7 @@ async function handleResetCommand(directory, args) {
|
|
|
55861
56097
|
}
|
|
55862
56098
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
55863
56099
|
try {
|
|
55864
|
-
const rootPath =
|
|
56100
|
+
const rootPath = path48.join(directory, filename);
|
|
55865
56101
|
if (fs26.existsSync(rootPath)) {
|
|
55866
56102
|
fs26.unlinkSync(rootPath);
|
|
55867
56103
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
@@ -55901,7 +56137,7 @@ var init_reset = __esm(() => {
|
|
|
55901
56137
|
|
|
55902
56138
|
// src/commands/reset-session.ts
|
|
55903
56139
|
import * as fs27 from "fs";
|
|
55904
|
-
import * as
|
|
56140
|
+
import * as path49 from "path";
|
|
55905
56141
|
async function handleResetSessionCommand(directory, _args) {
|
|
55906
56142
|
const results = [];
|
|
55907
56143
|
try {
|
|
@@ -55916,13 +56152,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
55916
56152
|
results.push("\u274C Failed to delete state.json");
|
|
55917
56153
|
}
|
|
55918
56154
|
try {
|
|
55919
|
-
const sessionDir =
|
|
56155
|
+
const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
55920
56156
|
if (fs27.existsSync(sessionDir)) {
|
|
55921
56157
|
const files = fs27.readdirSync(sessionDir);
|
|
55922
56158
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
55923
56159
|
let deletedCount = 0;
|
|
55924
56160
|
for (const file3 of otherFiles) {
|
|
55925
|
-
const filePath =
|
|
56161
|
+
const filePath = path49.join(sessionDir, file3);
|
|
55926
56162
|
if (fs27.lstatSync(filePath).isFile()) {
|
|
55927
56163
|
fs27.unlinkSync(filePath);
|
|
55928
56164
|
deletedCount++;
|
|
@@ -55954,7 +56190,7 @@ var init_reset_session = __esm(() => {
|
|
|
55954
56190
|
});
|
|
55955
56191
|
|
|
55956
56192
|
// src/summaries/manager.ts
|
|
55957
|
-
import * as
|
|
56193
|
+
import * as path50 from "path";
|
|
55958
56194
|
function sanitizeSummaryId(id) {
|
|
55959
56195
|
if (!id || id.length === 0) {
|
|
55960
56196
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -55977,7 +56213,7 @@ function sanitizeSummaryId(id) {
|
|
|
55977
56213
|
}
|
|
55978
56214
|
async function loadFullOutput(directory, id) {
|
|
55979
56215
|
const sanitizedId = sanitizeSummaryId(id);
|
|
55980
|
-
const relativePath =
|
|
56216
|
+
const relativePath = path50.join("summaries", `${sanitizedId}.json`);
|
|
55981
56217
|
validateSwarmPath(directory, relativePath);
|
|
55982
56218
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
55983
56219
|
if (content === null) {
|
|
@@ -56040,7 +56276,7 @@ var init_retrieve = __esm(() => {
|
|
|
56040
56276
|
|
|
56041
56277
|
// src/commands/rollback.ts
|
|
56042
56278
|
import * as fs28 from "fs";
|
|
56043
|
-
import * as
|
|
56279
|
+
import * as path51 from "path";
|
|
56044
56280
|
async function handleRollbackCommand(directory, args) {
|
|
56045
56281
|
const phaseArg = args[0];
|
|
56046
56282
|
if (!phaseArg) {
|
|
@@ -56105,8 +56341,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
56105
56341
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
56106
56342
|
continue;
|
|
56107
56343
|
}
|
|
56108
|
-
const src =
|
|
56109
|
-
const dest =
|
|
56344
|
+
const src = path51.join(checkpointDir, file3);
|
|
56345
|
+
const dest = path51.join(swarmDir, file3);
|
|
56110
56346
|
try {
|
|
56111
56347
|
fs28.cpSync(src, dest, { recursive: true, force: true });
|
|
56112
56348
|
successes.push(file3);
|
|
@@ -56125,12 +56361,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
56125
56361
|
].join(`
|
|
56126
56362
|
`);
|
|
56127
56363
|
}
|
|
56128
|
-
const existingLedgerPath =
|
|
56364
|
+
const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
|
|
56129
56365
|
if (fs28.existsSync(existingLedgerPath)) {
|
|
56130
56366
|
fs28.unlinkSync(existingLedgerPath);
|
|
56131
56367
|
}
|
|
56132
56368
|
try {
|
|
56133
|
-
const planJsonPath =
|
|
56369
|
+
const planJsonPath = path51.join(swarmDir, "plan.json");
|
|
56134
56370
|
if (fs28.existsSync(planJsonPath)) {
|
|
56135
56371
|
const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
|
|
56136
56372
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -56221,9 +56457,9 @@ Ensure this is a git repository with commit history.`;
|
|
|
56221
56457
|
`);
|
|
56222
56458
|
try {
|
|
56223
56459
|
const fs29 = await import("fs/promises");
|
|
56224
|
-
const
|
|
56225
|
-
const reportPath =
|
|
56226
|
-
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 });
|
|
56227
56463
|
await fs29.writeFile(reportPath, report, "utf-8");
|
|
56228
56464
|
} catch (err) {
|
|
56229
56465
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
@@ -56247,12 +56483,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
56247
56483
|
|
|
56248
56484
|
// src/turbo/lean/state.ts
|
|
56249
56485
|
import * as fs29 from "fs";
|
|
56250
|
-
import * as
|
|
56486
|
+
import * as path52 from "path";
|
|
56251
56487
|
function nowISO2() {
|
|
56252
56488
|
return new Date().toISOString();
|
|
56253
56489
|
}
|
|
56254
56490
|
function ensureSwarmDir2(directory) {
|
|
56255
|
-
const swarmDir =
|
|
56491
|
+
const swarmDir = path52.resolve(directory, ".swarm");
|
|
56256
56492
|
if (!fs29.existsSync(swarmDir)) {
|
|
56257
56493
|
fs29.mkdirSync(swarmDir, { recursive: true });
|
|
56258
56494
|
}
|
|
@@ -56296,7 +56532,7 @@ function markStateUnreadable2(directory, reason) {
|
|
|
56296
56532
|
}
|
|
56297
56533
|
function readPersisted2(directory) {
|
|
56298
56534
|
try {
|
|
56299
|
-
const filePath =
|
|
56535
|
+
const filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
56300
56536
|
if (!fs29.existsSync(filePath)) {
|
|
56301
56537
|
const seed = emptyPersisted2();
|
|
56302
56538
|
try {
|
|
@@ -56332,7 +56568,7 @@ function writePersisted2(directory, persisted) {
|
|
|
56332
56568
|
let payload;
|
|
56333
56569
|
try {
|
|
56334
56570
|
ensureSwarmDir2(directory);
|
|
56335
|
-
filePath =
|
|
56571
|
+
filePath = path52.join(directory, ".swarm", STATE_FILE2);
|
|
56336
56572
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
56337
56573
|
persisted.updatedAt = nowISO2();
|
|
56338
56574
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -56459,10 +56695,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
56459
56695
|
|
|
56460
56696
|
// src/services/status-service.ts
|
|
56461
56697
|
import * as fsSync2 from "fs";
|
|
56462
|
-
import * as
|
|
56698
|
+
import * as path53 from "path";
|
|
56463
56699
|
function readSpecStalenessSnapshot(directory) {
|
|
56464
56700
|
try {
|
|
56465
|
-
const p =
|
|
56701
|
+
const p = path53.join(directory, ".swarm", "spec-staleness.json");
|
|
56466
56702
|
if (!fsSync2.existsSync(p))
|
|
56467
56703
|
return { stale: false };
|
|
56468
56704
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -56988,7 +57224,7 @@ var init_write_retro2 = __esm(() => {
|
|
|
56988
57224
|
|
|
56989
57225
|
// src/commands/command-dispatch.ts
|
|
56990
57226
|
import fs30 from "fs";
|
|
56991
|
-
import
|
|
57227
|
+
import path54 from "path";
|
|
56992
57228
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
56993
57229
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
56994
57230
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -57024,9 +57260,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
57024
57260
|
`);
|
|
57025
57261
|
}
|
|
57026
57262
|
function maybeMarkFirstRun(directory) {
|
|
57027
|
-
const sentinelPath =
|
|
57263
|
+
const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
|
|
57028
57264
|
try {
|
|
57029
|
-
const swarmDir =
|
|
57265
|
+
const swarmDir = path54.join(directory, ".swarm");
|
|
57030
57266
|
fs30.mkdirSync(swarmDir, { recursive: true });
|
|
57031
57267
|
fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
57032
57268
|
`, { flag: "wx" });
|
|
@@ -57768,24 +58004,24 @@ function validateAliases() {
|
|
|
57768
58004
|
}
|
|
57769
58005
|
aliasTargets.get(target).push(name);
|
|
57770
58006
|
const visited = new Set;
|
|
57771
|
-
const
|
|
58007
|
+
const path55 = [];
|
|
57772
58008
|
let current = target;
|
|
57773
58009
|
while (current) {
|
|
57774
58010
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
57775
58011
|
if (!currentEntry)
|
|
57776
58012
|
break;
|
|
57777
58013
|
if (visited.has(current)) {
|
|
57778
|
-
const cycleStart =
|
|
58014
|
+
const cycleStart = path55.indexOf(current);
|
|
57779
58015
|
const fullChain = [
|
|
57780
58016
|
name,
|
|
57781
|
-
...
|
|
58017
|
+
...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
|
|
57782
58018
|
current
|
|
57783
58019
|
].join(" \u2192 ");
|
|
57784
58020
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
57785
58021
|
break;
|
|
57786
58022
|
}
|
|
57787
58023
|
visited.add(current);
|
|
57788
|
-
|
|
58024
|
+
path55.push(current);
|
|
57789
58025
|
current = currentEntry.aliasOf || "";
|
|
57790
58026
|
}
|
|
57791
58027
|
}
|
|
@@ -58383,53 +58619,53 @@ init_cache_paths();
|
|
|
58383
58619
|
init_constants();
|
|
58384
58620
|
import * as fs31 from "fs";
|
|
58385
58621
|
import * as os8 from "os";
|
|
58386
|
-
import * as
|
|
58387
|
-
var { version:
|
|
58622
|
+
import * as path55 from "path";
|
|
58623
|
+
var { version: version5 } = package_default;
|
|
58388
58624
|
var CONFIG_DIR = getPluginConfigDir();
|
|
58389
|
-
var OPENCODE_CONFIG_PATH =
|
|
58390
|
-
var PLUGIN_CONFIG_PATH =
|
|
58391
|
-
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");
|
|
58392
58628
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
58393
58629
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
58394
58630
|
function isSafeCachePath(p) {
|
|
58395
|
-
const resolved =
|
|
58396
|
-
const home =
|
|
58631
|
+
const resolved = path55.resolve(p);
|
|
58632
|
+
const home = path55.resolve(os8.homedir());
|
|
58397
58633
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
58398
58634
|
return false;
|
|
58399
58635
|
}
|
|
58400
|
-
const segments = resolved.split(
|
|
58636
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
58401
58637
|
if (segments.length < 4) {
|
|
58402
58638
|
return false;
|
|
58403
58639
|
}
|
|
58404
|
-
const leaf =
|
|
58640
|
+
const leaf = path55.basename(resolved);
|
|
58405
58641
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
58406
58642
|
return false;
|
|
58407
58643
|
}
|
|
58408
|
-
const parent =
|
|
58644
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
58409
58645
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
58410
58646
|
return false;
|
|
58411
58647
|
}
|
|
58412
|
-
const grandparent =
|
|
58648
|
+
const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
|
|
58413
58649
|
if (grandparent !== "opencode") {
|
|
58414
58650
|
return false;
|
|
58415
58651
|
}
|
|
58416
58652
|
return true;
|
|
58417
58653
|
}
|
|
58418
58654
|
function isSafeLockFilePath(p) {
|
|
58419
|
-
const resolved =
|
|
58420
|
-
const home =
|
|
58655
|
+
const resolved = path55.resolve(p);
|
|
58656
|
+
const home = path55.resolve(os8.homedir());
|
|
58421
58657
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
58422
58658
|
return false;
|
|
58423
58659
|
}
|
|
58424
|
-
const segments = resolved.split(
|
|
58660
|
+
const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
|
|
58425
58661
|
if (segments.length < 4) {
|
|
58426
58662
|
return false;
|
|
58427
58663
|
}
|
|
58428
|
-
const leaf =
|
|
58664
|
+
const leaf = path55.basename(resolved);
|
|
58429
58665
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
58430
58666
|
return false;
|
|
58431
58667
|
}
|
|
58432
|
-
const parent =
|
|
58668
|
+
const parent = path55.basename(path55.dirname(resolved));
|
|
58433
58669
|
if (parent !== "opencode") {
|
|
58434
58670
|
return false;
|
|
58435
58671
|
}
|
|
@@ -58455,8 +58691,8 @@ function saveJson(filepath, data) {
|
|
|
58455
58691
|
}
|
|
58456
58692
|
function writeProjectConfigIfMissing(cwd) {
|
|
58457
58693
|
try {
|
|
58458
|
-
const opencodeDir =
|
|
58459
|
-
const projectConfigPath =
|
|
58694
|
+
const opencodeDir = path55.join(cwd, ".opencode");
|
|
58695
|
+
const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
|
|
58460
58696
|
if (fs31.existsSync(projectConfigPath)) {
|
|
58461
58697
|
return;
|
|
58462
58698
|
}
|
|
@@ -58473,7 +58709,7 @@ async function install() {
|
|
|
58473
58709
|
`);
|
|
58474
58710
|
ensureDir(CONFIG_DIR);
|
|
58475
58711
|
ensureDir(PROMPTS_DIR);
|
|
58476
|
-
const LEGACY_CONFIG_PATH =
|
|
58712
|
+
const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
|
|
58477
58713
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
58478
58714
|
if (!opencodeConfig) {
|
|
58479
58715
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|
|
@@ -58748,7 +58984,7 @@ Examples:
|
|
|
58748
58984
|
async function main() {
|
|
58749
58985
|
const args = process.argv.slice(2);
|
|
58750
58986
|
if (args.includes("-v") || args.includes("--version")) {
|
|
58751
|
-
console.log(`opencode-swarm ${
|
|
58987
|
+
console.log(`opencode-swarm ${version5}`);
|
|
58752
58988
|
process.exit(0);
|
|
58753
58989
|
}
|
|
58754
58990
|
if (args.includes("-h") || args.includes("--help")) {
|