@wairon/cli 5.1.1-dev.50 → 5.1.1-dev.52
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 +960 -964
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +474 -481
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1233,7 +1233,7 @@ var init_defaults = __esm({
|
|
|
1233
1233
|
copilot: ".github/prompts",
|
|
1234
1234
|
codex: ".codex/agents"
|
|
1235
1235
|
};
|
|
1236
|
-
WAIRON_VERSION = "5.1.1-dev.
|
|
1236
|
+
WAIRON_VERSION = "5.1.1-dev.52";
|
|
1237
1237
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
1238
1238
|
ARCHITECT_AGENT_ID = "agent-architect";
|
|
1239
1239
|
ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -3387,10 +3387,26 @@ function writeSpecFile(filePath, document) {
|
|
|
3387
3387
|
function listSpecFiles(specsDir) {
|
|
3388
3388
|
return listFilesRecursive(specsDir, SPEC_FILE_EXTENSION);
|
|
3389
3389
|
}
|
|
3390
|
-
|
|
3390
|
+
function removeSpecFile(filePath, specsRoot) {
|
|
3391
|
+
if (!fs5.existsSync(filePath)) return false;
|
|
3392
|
+
fs5.unlinkSync(filePath);
|
|
3393
|
+
pruneEmptyDirs(path8.dirname(filePath), path8.resolve(specsRoot));
|
|
3394
|
+
return true;
|
|
3395
|
+
}
|
|
3396
|
+
function pruneEmptyDirs(dir, specsRoot) {
|
|
3397
|
+
let at = dir;
|
|
3398
|
+
while (at !== specsRoot && at.startsWith(specsRoot)) {
|
|
3399
|
+
if (!fs5.existsSync(at) || fs5.readdirSync(at).length > 0) return;
|
|
3400
|
+
fs5.rmdirSync(at);
|
|
3401
|
+
at = path8.dirname(at);
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
var fs5, path8, SPEC_FILE_EXTENSION;
|
|
3391
3405
|
var init_spec_files = __esm({
|
|
3392
3406
|
"src/core/spec-files.ts"() {
|
|
3393
3407
|
"use strict";
|
|
3408
|
+
fs5 = __toESM(require("fs"));
|
|
3409
|
+
path8 = __toESM(require("path"));
|
|
3394
3410
|
init_fs();
|
|
3395
3411
|
init_yaml();
|
|
3396
3412
|
SPEC_FILE_EXTENSION = ".yaml";
|
|
@@ -4135,14 +4151,14 @@ function embedJson(value) {
|
|
|
4135
4151
|
}
|
|
4136
4152
|
function loadCytoscapeLib() {
|
|
4137
4153
|
const candidates = [
|
|
4138
|
-
|
|
4154
|
+
path9.resolve(__dirname, "..", "templates", "canvas", "cytoscape.min.js"),
|
|
4139
4155
|
// src/core & dist/cli
|
|
4140
|
-
|
|
4156
|
+
path9.resolve(__dirname, "templates", "canvas", "cytoscape.min.js")
|
|
4141
4157
|
// dist (library entry)
|
|
4142
4158
|
];
|
|
4143
4159
|
for (const p of candidates) {
|
|
4144
|
-
if (
|
|
4145
|
-
return
|
|
4160
|
+
if (fs6.existsSync(p)) {
|
|
4161
|
+
return fs6.readFileSync(p, "utf-8").replace(/<\/script/gi, "<\\/script");
|
|
4146
4162
|
}
|
|
4147
4163
|
}
|
|
4148
4164
|
throw new Error("Vendored cytoscape bundle not found (templates/canvas/cytoscape.min.js) \u2014 the wairon installation is incomplete.");
|
|
@@ -4154,12 +4170,12 @@ function renderCanvasHtml(model) {
|
|
|
4154
4170
|
function escapeHtml(s) {
|
|
4155
4171
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
4156
4172
|
}
|
|
4157
|
-
var
|
|
4173
|
+
var fs6, path9, CANVAS_TEMPLATE;
|
|
4158
4174
|
var init_canvas = __esm({
|
|
4159
4175
|
"src/core/canvas.ts"() {
|
|
4160
4176
|
"use strict";
|
|
4161
|
-
|
|
4162
|
-
|
|
4177
|
+
fs6 = __toESM(require("fs"));
|
|
4178
|
+
path9 = __toESM(require("path"));
|
|
4163
4179
|
init_specs2();
|
|
4164
4180
|
init_models();
|
|
4165
4181
|
init_diagram_export();
|
|
@@ -8354,7 +8370,7 @@ function packStoreDir() {
|
|
|
8354
8370
|
function packFiles(dir, prefix = "") {
|
|
8355
8371
|
let entries;
|
|
8356
8372
|
try {
|
|
8357
|
-
entries =
|
|
8373
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
8358
8374
|
} catch {
|
|
8359
8375
|
return [];
|
|
8360
8376
|
}
|
|
@@ -8362,25 +8378,25 @@ function packFiles(dir, prefix = "") {
|
|
|
8362
8378
|
for (const e of entries) {
|
|
8363
8379
|
if (DIGEST_EXCLUDED.has(e.name)) continue;
|
|
8364
8380
|
const rel2 = prefix ? `${prefix}/${e.name}` : e.name;
|
|
8365
|
-
if (e.isDirectory()) out.push(...packFiles(
|
|
8381
|
+
if (e.isDirectory()) out.push(...packFiles(path10.join(dir, e.name), rel2));
|
|
8366
8382
|
else if (e.isFile()) out.push(rel2);
|
|
8367
8383
|
}
|
|
8368
8384
|
return out.sort();
|
|
8369
8385
|
}
|
|
8370
8386
|
function computePackDigest(packDir) {
|
|
8371
8387
|
const hash = crypto2.createHash("sha256");
|
|
8372
|
-
const abs =
|
|
8388
|
+
const abs = path10.resolve(packDir);
|
|
8373
8389
|
let isFile = false;
|
|
8374
8390
|
try {
|
|
8375
|
-
isFile =
|
|
8391
|
+
isFile = fs7.statSync(abs).isFile();
|
|
8376
8392
|
} catch {
|
|
8377
8393
|
}
|
|
8378
|
-
const entries = isFile ? [[
|
|
8394
|
+
const entries = isFile ? [[path10.basename(abs), abs]] : packFiles(abs).map((rel2) => [rel2, path10.join(abs, rel2)]);
|
|
8379
8395
|
for (const [rel2, full] of entries) {
|
|
8380
8396
|
hash.update(rel2);
|
|
8381
8397
|
hash.update("\0");
|
|
8382
8398
|
try {
|
|
8383
|
-
hash.update(
|
|
8399
|
+
hash.update(fs7.readFileSync(full));
|
|
8384
8400
|
} catch {
|
|
8385
8401
|
}
|
|
8386
8402
|
hash.update("\0");
|
|
@@ -8389,7 +8405,7 @@ function computePackDigest(packDir) {
|
|
|
8389
8405
|
}
|
|
8390
8406
|
function readInstallRecord(packPath) {
|
|
8391
8407
|
try {
|
|
8392
|
-
const raw = readYamlFile(
|
|
8408
|
+
const raw = readYamlFile(path10.join(packPath, INSTALL_RECORD));
|
|
8393
8409
|
return raw && typeof raw === "object" ? raw : {};
|
|
8394
8410
|
} catch {
|
|
8395
8411
|
return {};
|
|
@@ -8419,14 +8435,14 @@ function installedFrom(location, name, version) {
|
|
|
8419
8435
|
function versionedEntries(nameDir, fallbackName) {
|
|
8420
8436
|
let versions;
|
|
8421
8437
|
try {
|
|
8422
|
-
versions =
|
|
8438
|
+
versions = fs7.readdirSync(nameDir, { withFileTypes: true });
|
|
8423
8439
|
} catch {
|
|
8424
8440
|
return [];
|
|
8425
8441
|
}
|
|
8426
8442
|
const out = [];
|
|
8427
8443
|
for (const v of versions) {
|
|
8428
8444
|
if (!v.isDirectory()) continue;
|
|
8429
|
-
const versionDir =
|
|
8445
|
+
const versionDir = path10.join(nameDir, v.name);
|
|
8430
8446
|
const entryFile = packDirEntry(versionDir);
|
|
8431
8447
|
if (!entryFile) continue;
|
|
8432
8448
|
out.push(installedFrom(versionDir, declaredName(entryFile) ?? fallbackName, v.name));
|
|
@@ -8434,7 +8450,7 @@ function versionedEntries(nameDir, fallbackName) {
|
|
|
8434
8450
|
return out;
|
|
8435
8451
|
}
|
|
8436
8452
|
function storeEntryPacks(store, entry) {
|
|
8437
|
-
const full =
|
|
8453
|
+
const full = path10.join(store, entry.name);
|
|
8438
8454
|
if (entry.isFile()) {
|
|
8439
8455
|
if (!PACK_FILE_RE.test(entry.name)) return [];
|
|
8440
8456
|
const name = declaredName(full) ?? entry.name.replace(PACK_FILE_RE, "");
|
|
@@ -8449,7 +8465,7 @@ function listInstalledPacks() {
|
|
|
8449
8465
|
const store = packStoreDir();
|
|
8450
8466
|
let entries;
|
|
8451
8467
|
try {
|
|
8452
|
-
entries =
|
|
8468
|
+
entries = fs7.readdirSync(store, { withFileTypes: true });
|
|
8453
8469
|
} catch {
|
|
8454
8470
|
return [];
|
|
8455
8471
|
}
|
|
@@ -8466,17 +8482,17 @@ function resolveInstalledPack(name, version) {
|
|
|
8466
8482
|
return candidates[0];
|
|
8467
8483
|
}
|
|
8468
8484
|
function installPackFromDirectory(sourceDir, origin) {
|
|
8469
|
-
const abs =
|
|
8485
|
+
const abs = path10.resolve(sourceDir);
|
|
8470
8486
|
const entryFile = packDirEntry(abs);
|
|
8471
8487
|
if (!entryFile) {
|
|
8472
8488
|
throw new Error(`"${sourceDir}" is not a pack directory (no pack.yaml | pack.cjs | index.cjs | \u2026).`);
|
|
8473
8489
|
}
|
|
8474
|
-
const manifest = readManifest(entryFile,
|
|
8490
|
+
const manifest = readManifest(entryFile, path10.dirname(entryFile));
|
|
8475
8491
|
const version = manifest.version && manifest.version.length > 0 ? manifest.version : UNVERSIONED;
|
|
8476
|
-
const dest =
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8492
|
+
const dest = path10.join(packStoreDir(), manifest.name, version);
|
|
8493
|
+
fs7.rmSync(dest, { recursive: true, force: true });
|
|
8494
|
+
fs7.mkdirSync(path10.dirname(dest), { recursive: true });
|
|
8495
|
+
fs7.cpSync(abs, dest, { recursive: true });
|
|
8480
8496
|
const digest2 = computePackDigest(dest);
|
|
8481
8497
|
const record = {
|
|
8482
8498
|
origin,
|
|
@@ -8484,7 +8500,7 @@ function installPackFromDirectory(sourceDir, origin) {
|
|
|
8484
8500
|
waironVersion: WAIRON_VERSION,
|
|
8485
8501
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8486
8502
|
};
|
|
8487
|
-
writeYamlFile(
|
|
8503
|
+
writeYamlFile(path10.join(dest, INSTALL_RECORD), record);
|
|
8488
8504
|
return {
|
|
8489
8505
|
name: manifest.name,
|
|
8490
8506
|
version,
|
|
@@ -8499,23 +8515,23 @@ function uninstallPack(name, version) {
|
|
|
8499
8515
|
const targets = listInstalledPacks().filter((p) => p.name === name && (!version || p.version === version));
|
|
8500
8516
|
if (targets.length === 0) return false;
|
|
8501
8517
|
for (const target of targets) {
|
|
8502
|
-
|
|
8503
|
-
const parent =
|
|
8504
|
-
if (
|
|
8518
|
+
fs7.rmSync(target.path, { recursive: true, force: true });
|
|
8519
|
+
const parent = path10.dirname(target.path);
|
|
8520
|
+
if (path10.resolve(parent) === path10.resolve(packStoreDir())) continue;
|
|
8505
8521
|
try {
|
|
8506
|
-
if (
|
|
8522
|
+
if (fs7.readdirSync(parent).length === 0) fs7.rmdirSync(parent);
|
|
8507
8523
|
} catch {
|
|
8508
8524
|
}
|
|
8509
8525
|
}
|
|
8510
8526
|
return true;
|
|
8511
8527
|
}
|
|
8512
|
-
var crypto2,
|
|
8528
|
+
var crypto2, fs7, path10, UNVERSIONED, INSTALL_RECORD, DIGEST_EXCLUDED, PACK_FILE_RE;
|
|
8513
8529
|
var init_packstore = __esm({
|
|
8514
8530
|
"src/core/packstore.ts"() {
|
|
8515
8531
|
"use strict";
|
|
8516
8532
|
crypto2 = __toESM(require("crypto"));
|
|
8517
|
-
|
|
8518
|
-
|
|
8533
|
+
fs7 = __toESM(require("fs"));
|
|
8534
|
+
path10 = __toESM(require("path"));
|
|
8519
8535
|
init_yaml();
|
|
8520
8536
|
init_defaults();
|
|
8521
8537
|
init_version();
|
|
@@ -8542,26 +8558,26 @@ function emptyExtensions() {
|
|
|
8542
8558
|
return { packNames: [], packs: [], rules: [], profiles: {}, languages: {}, skills: [], patterns: [], guarantees: [], assertions: [], instructions: [], errors: [], selectionFailures: [] };
|
|
8543
8559
|
}
|
|
8544
8560
|
function globalPacksDir() {
|
|
8545
|
-
return process.env.WAIRON_PACKS_DIR ??
|
|
8561
|
+
return process.env.WAIRON_PACKS_DIR ?? path11.join(os2.homedir(), ".wairon", "packs");
|
|
8546
8562
|
}
|
|
8547
8563
|
function packDirEntry(dir) {
|
|
8548
8564
|
for (const name of PACK_DIR_ENTRIES) {
|
|
8549
|
-
const p =
|
|
8550
|
-
if (
|
|
8565
|
+
const p = path11.join(dir, name);
|
|
8566
|
+
if (fs8.existsSync(p)) return p;
|
|
8551
8567
|
}
|
|
8552
8568
|
return null;
|
|
8553
8569
|
}
|
|
8554
8570
|
function latestVersionDir(nameDir) {
|
|
8555
8571
|
let versions;
|
|
8556
8572
|
try {
|
|
8557
|
-
versions =
|
|
8573
|
+
versions = fs8.readdirSync(nameDir, { withFileTypes: true });
|
|
8558
8574
|
} catch {
|
|
8559
8575
|
return null;
|
|
8560
8576
|
}
|
|
8561
8577
|
let best = null;
|
|
8562
8578
|
for (const v of versions) {
|
|
8563
8579
|
if (!v.isDirectory()) continue;
|
|
8564
|
-
const dir =
|
|
8580
|
+
const dir = path11.join(nameDir, v.name);
|
|
8565
8581
|
if (!packDirEntry(dir)) continue;
|
|
8566
8582
|
if (!best || isNewerVersion(best.version, v.name)) best = { version: v.name, dir };
|
|
8567
8583
|
}
|
|
@@ -8570,13 +8586,13 @@ function latestVersionDir(nameDir) {
|
|
|
8570
8586
|
function discoverPacks(dir) {
|
|
8571
8587
|
let entries;
|
|
8572
8588
|
try {
|
|
8573
|
-
entries =
|
|
8589
|
+
entries = fs8.readdirSync(dir, { withFileTypes: true });
|
|
8574
8590
|
} catch {
|
|
8575
8591
|
return [];
|
|
8576
8592
|
}
|
|
8577
8593
|
const refs = [];
|
|
8578
8594
|
for (const e of entries.sort((a, b) => compareOrdinal(a.name, b.name))) {
|
|
8579
|
-
const full =
|
|
8595
|
+
const full = path11.join(dir, e.name);
|
|
8580
8596
|
if (e.isDirectory()) {
|
|
8581
8597
|
if (packDirEntry(full)) refs.push(full);
|
|
8582
8598
|
else {
|
|
@@ -8606,17 +8622,17 @@ function mergePack(out, pack, ref, scope, packDir) {
|
|
|
8606
8622
|
foreignBuiltins: [.../* @__PURE__ */ new Set([...existing.foreignBuiltins, ...def.foreignBuiltins])]
|
|
8607
8623
|
} : def;
|
|
8608
8624
|
}
|
|
8609
|
-
for (const s of pack.skills) out.skills.push({ ...s, pack: pack.name, packVersion: pack.version, sourcePath:
|
|
8625
|
+
for (const s of pack.skills) out.skills.push({ ...s, pack: pack.name, packVersion: pack.version, sourcePath: path11.resolve(packDir, s.source) });
|
|
8610
8626
|
for (const p of pack.patterns) out.patterns.push({ ...p, pack: pack.name });
|
|
8611
8627
|
out.guarantees = [.../* @__PURE__ */ new Set([...out.guarantees, ...pack.guarantees])];
|
|
8612
8628
|
for (const a of pack.assertions) out.assertions.push({ ...a, pack: pack.name, fullCode: assertionFullCode(pack.name, a.code) });
|
|
8613
8629
|
for (const b of pack.instructions) out.instructions.push({ ...b, pack: pack.name });
|
|
8614
8630
|
}
|
|
8615
8631
|
function resolvePackRef(ref, projectRoot) {
|
|
8616
|
-
const pathLike = ref.startsWith(".") ||
|
|
8632
|
+
const pathLike = ref.startsWith(".") || path11.isAbsolute(ref) || isYamlPath(ref);
|
|
8617
8633
|
if (!pathLike) return ref;
|
|
8618
|
-
const resolved =
|
|
8619
|
-
if (
|
|
8634
|
+
const resolved = path11.resolve(projectRoot, ref);
|
|
8635
|
+
if (fs8.existsSync(resolved) && fs8.statSync(resolved).isDirectory()) {
|
|
8620
8636
|
const entry = packDirEntry(resolved);
|
|
8621
8637
|
if (!entry) throw new Error(`directory pack has no entry file (${PACK_DIR_ENTRIES.join(" | ")})`);
|
|
8622
8638
|
return entry;
|
|
@@ -8629,7 +8645,7 @@ function readManifest(target, projectRoot) {
|
|
|
8629
8645
|
if (raw == null) throw new Error("file not found or empty");
|
|
8630
8646
|
return { ...DeclarativePackSchema.parse(raw), rules: [] };
|
|
8631
8647
|
}
|
|
8632
|
-
const req = (0, import_module.createRequire)(
|
|
8648
|
+
const req = (0, import_module.createRequire)(path11.join(projectRoot, "package.json"));
|
|
8633
8649
|
const modRaw = req(target);
|
|
8634
8650
|
const mod = modRaw?.default ?? modRaw;
|
|
8635
8651
|
const parsed = DeclarativePackSchema.parse({
|
|
@@ -8657,7 +8673,7 @@ function loadExtensionPacks(refs, projectRoot) {
|
|
|
8657
8673
|
try {
|
|
8658
8674
|
const target = resolvePackRef(ref, projectRoot);
|
|
8659
8675
|
const manifest = readManifest(target, projectRoot);
|
|
8660
|
-
mergePack(out, manifest, ref, scope,
|
|
8676
|
+
mergePack(out, manifest, ref, scope, path11.dirname(target));
|
|
8661
8677
|
for (const r of manifest.rules) out.rules.push(r);
|
|
8662
8678
|
} catch (e) {
|
|
8663
8679
|
out.errors.push(`Extension pack "${ref}" failed to load: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -8703,7 +8719,7 @@ function defaultPackSelections() {
|
|
|
8703
8719
|
const entry = packDirEntry(pack.path) ?? pack.path;
|
|
8704
8720
|
let manifest;
|
|
8705
8721
|
try {
|
|
8706
|
-
manifest = readManifest(entry,
|
|
8722
|
+
manifest = readManifest(entry, path11.dirname(entry));
|
|
8707
8723
|
} catch {
|
|
8708
8724
|
continue;
|
|
8709
8725
|
}
|
|
@@ -8742,7 +8758,7 @@ function diagnoseProjectPacks() {
|
|
|
8742
8758
|
const globalsApplied = [];
|
|
8743
8759
|
if (globalsOn) {
|
|
8744
8760
|
for (const ref of discoverPacks(globalPacksDir())) {
|
|
8745
|
-
const match = installed.find((p) =>
|
|
8761
|
+
const match = installed.find((p) => path11.resolve(p.path) === path11.resolve(ref));
|
|
8746
8762
|
if (match) globalsApplied.push({ name: match.name, version: match.version });
|
|
8747
8763
|
}
|
|
8748
8764
|
}
|
|
@@ -8820,7 +8836,7 @@ function verifyIntegrity(selection, packDir, where) {
|
|
|
8820
8836
|
};
|
|
8821
8837
|
}
|
|
8822
8838
|
function detectBundleStoreDrift(selection, bundleDir) {
|
|
8823
|
-
const bundledVersion =
|
|
8839
|
+
const bundledVersion = path11.basename(bundleDir);
|
|
8824
8840
|
const installed = resolveInstalledPack(selection.name, bundledVersion);
|
|
8825
8841
|
if (!installed) return void 0;
|
|
8826
8842
|
const bundleDigest = computePackDigest(bundleDir);
|
|
@@ -8834,34 +8850,34 @@ function detectBundleStoreDrift(selection, bundleDir) {
|
|
|
8834
8850
|
};
|
|
8835
8851
|
}
|
|
8836
8852
|
function findBundledPack(projectRoot, selection) {
|
|
8837
|
-
const base =
|
|
8853
|
+
const base = path11.join(projectRoot, ".wai", "packs", selection.name);
|
|
8838
8854
|
if (selection.version) {
|
|
8839
|
-
const pinned =
|
|
8855
|
+
const pinned = path11.join(base, selection.version);
|
|
8840
8856
|
return packDirEntry(pinned) ? pinned : null;
|
|
8841
8857
|
}
|
|
8842
8858
|
if (packDirEntry(base)) return base;
|
|
8843
8859
|
let versions;
|
|
8844
8860
|
try {
|
|
8845
|
-
versions =
|
|
8861
|
+
versions = fs8.readdirSync(base, { withFileTypes: true });
|
|
8846
8862
|
} catch {
|
|
8847
8863
|
return null;
|
|
8848
8864
|
}
|
|
8849
8865
|
let best = null;
|
|
8850
8866
|
for (const v of versions) {
|
|
8851
8867
|
if (!v.isDirectory()) continue;
|
|
8852
|
-
const dir =
|
|
8868
|
+
const dir = path11.join(base, v.name);
|
|
8853
8869
|
if (!packDirEntry(dir)) continue;
|
|
8854
8870
|
if (!best || isNewerVersion(best.version, v.name)) best = { version: v.name, dir };
|
|
8855
8871
|
}
|
|
8856
8872
|
return best?.dir ?? null;
|
|
8857
8873
|
}
|
|
8858
|
-
var
|
|
8874
|
+
var fs8, os2, path11, import_module, import_zod9, ProfileDefSchema, LanguagePackDefSchema, PackSkillSchema, PackInstructionBlockSchema, PackInstructionsSchema, PatternDefSchema, AssertionSelectorSchema, assertionBase, PackAssertionSchema, DeclarativePackSchema, EXTENDABLE_BUILTIN_SKILLS, GLOBAL_PACKS_DEFAULT, PACK_DIR_ENTRIES, isYamlPath;
|
|
8859
8875
|
var init_extensions = __esm({
|
|
8860
8876
|
"src/core/extensions.ts"() {
|
|
8861
8877
|
"use strict";
|
|
8862
|
-
|
|
8878
|
+
fs8 = __toESM(require("fs"));
|
|
8863
8879
|
os2 = __toESM(require("os"));
|
|
8864
|
-
|
|
8880
|
+
path11 = __toESM(require("path"));
|
|
8865
8881
|
import_module = require("module");
|
|
8866
8882
|
import_zod9 = require("zod");
|
|
8867
8883
|
init_yaml();
|
|
@@ -9053,21 +9069,21 @@ function buildCodeIndex(model) {
|
|
|
9053
9069
|
const declarations = /* @__PURE__ */ new Map();
|
|
9054
9070
|
const anchors = /* @__PURE__ */ new Map();
|
|
9055
9071
|
const findingAnchors = /* @__PURE__ */ new Map();
|
|
9056
|
-
const namesAt = (cache,
|
|
9057
|
-
const cached = cache.get(
|
|
9072
|
+
const namesAt = (cache, path28, make) => {
|
|
9073
|
+
const cached = cache.get(path28);
|
|
9058
9074
|
if (cached) return cached;
|
|
9059
|
-
const f = facts.get(
|
|
9075
|
+
const f = facts.get(path28);
|
|
9060
9076
|
if (!f) return NO_NAMES;
|
|
9061
9077
|
const built = make(f);
|
|
9062
|
-
cache.set(
|
|
9078
|
+
cache.set(path28, built);
|
|
9063
9079
|
return built;
|
|
9064
9080
|
};
|
|
9065
9081
|
const republished = /* @__PURE__ */ new Map();
|
|
9066
|
-
const republishedFrom = (
|
|
9067
|
-
const cached = republished.get(
|
|
9082
|
+
const republishedFrom = (path28) => {
|
|
9083
|
+
const cached = republished.get(path28);
|
|
9068
9084
|
if (cached) return cached;
|
|
9069
|
-
const out = /* @__PURE__ */ new Set([
|
|
9070
|
-
const queue = [
|
|
9085
|
+
const out = /* @__PURE__ */ new Set([path28]);
|
|
9086
|
+
const queue = [path28];
|
|
9071
9087
|
while (queue.length) {
|
|
9072
9088
|
const from = queue.pop();
|
|
9073
9089
|
const f = facts.get(from);
|
|
@@ -9080,7 +9096,7 @@ function buildCodeIndex(model) {
|
|
|
9080
9096
|
}
|
|
9081
9097
|
}
|
|
9082
9098
|
}
|
|
9083
|
-
republished.set(
|
|
9099
|
+
republished.set(path28, out);
|
|
9084
9100
|
return out;
|
|
9085
9101
|
};
|
|
9086
9102
|
const NO_ORIGIN = /* @__PURE__ */ new Set();
|
|
@@ -9089,9 +9105,9 @@ function buildCodeIndex(model) {
|
|
|
9089
9105
|
return to ? republishedFrom(to) : NO_ORIGIN;
|
|
9090
9106
|
};
|
|
9091
9107
|
const scopeOf = (site, from) => {
|
|
9092
|
-
const
|
|
9093
|
-
const f = facts.get(
|
|
9094
|
-
return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path:
|
|
9108
|
+
const path28 = pathKey(site.from ?? from);
|
|
9109
|
+
const f = facts.get(path28);
|
|
9110
|
+
return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path: path28, facts: f } : void 0;
|
|
9095
9111
|
};
|
|
9096
9112
|
const originOf = (site, from) => {
|
|
9097
9113
|
const resolved = scopeOf(site, from);
|
|
@@ -9130,14 +9146,14 @@ function buildCodeIndex(model) {
|
|
|
9130
9146
|
if (site.via) for (const typeName of localTypesOf(f, site.via)) widenThroughType(typeName);
|
|
9131
9147
|
return out;
|
|
9132
9148
|
};
|
|
9133
|
-
const declarationsAt = (
|
|
9149
|
+
const declarationsAt = (path28) => namesAt(declarations, pathKey(path28), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames]));
|
|
9134
9150
|
return {
|
|
9135
9151
|
paths,
|
|
9136
9152
|
exactPaths,
|
|
9137
|
-
factsAt: (
|
|
9153
|
+
factsAt: (path28) => facts.get(pathKey(path28)),
|
|
9138
9154
|
declarationsAt,
|
|
9139
|
-
anchorsAt: (
|
|
9140
|
-
findingAnchorsAt: (
|
|
9155
|
+
anchorsAt: (path28) => namesAt(anchors, pathKey(path28), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames, ...f.anchoredNames])),
|
|
9156
|
+
findingAnchorsAt: (path28) => namesAt(findingAnchors, pathKey(path28), (f) => new Set(f.anchoredNames)),
|
|
9141
9157
|
originOf,
|
|
9142
9158
|
possibleOriginsOf
|
|
9143
9159
|
};
|
|
@@ -9175,10 +9191,10 @@ function buildRealizationIndex(ctx) {
|
|
|
9175
9191
|
return {
|
|
9176
9192
|
paths,
|
|
9177
9193
|
implementationsOf: (compId) => implsByComponent.get(compId) ?? NONE_IMPL,
|
|
9178
|
-
implementationsAt: (
|
|
9194
|
+
implementationsAt: (path28) => implsByPath.get(pathKey(path28)) ?? NONE_IMPL,
|
|
9179
9195
|
filesOf: (compId) => filesByComponent.get(compId) ?? NONE_PATH,
|
|
9180
9196
|
filesIn: (subsystemId) => filesBySubsystem.get(subsystemId) ?? NONE_PATH,
|
|
9181
|
-
componentsAt: (
|
|
9197
|
+
componentsAt: (path28) => componentsByPath.get(pathKey(path28)) ?? NONE_COMP
|
|
9182
9198
|
};
|
|
9183
9199
|
}
|
|
9184
9200
|
function buildImportGraph(index, universe) {
|
|
@@ -9190,22 +9206,22 @@ function buildImportGraph(index, universe) {
|
|
|
9190
9206
|
if (to && to !== from) into.add(to);
|
|
9191
9207
|
}
|
|
9192
9208
|
};
|
|
9193
|
-
const importsOf = (
|
|
9194
|
-
const cached = imports.get(
|
|
9209
|
+
const importsOf = (path28) => {
|
|
9210
|
+
const cached = imports.get(path28);
|
|
9195
9211
|
if (cached) return cached;
|
|
9196
|
-
const facts = index.factsAt(
|
|
9212
|
+
const facts = index.factsAt(path28);
|
|
9197
9213
|
const out = /* @__PURE__ */ new Set();
|
|
9198
|
-
if (facts?.status === "analyzed") resolveAll(
|
|
9199
|
-
imports.set(
|
|
9214
|
+
if (facts?.status === "analyzed") resolveAll(path28, facts.imports, out);
|
|
9215
|
+
imports.set(path28, out);
|
|
9200
9216
|
return out;
|
|
9201
9217
|
};
|
|
9202
|
-
const tracesOf = (
|
|
9203
|
-
const cached = traces.get(
|
|
9218
|
+
const tracesOf = (path28) => {
|
|
9219
|
+
const cached = traces.get(path28);
|
|
9204
9220
|
if (cached) return cached;
|
|
9205
|
-
const facts = index.factsAt(
|
|
9206
|
-
const out = new Set(importsOf(
|
|
9207
|
-
if (facts?.status === "analyzed") resolveAll(
|
|
9208
|
-
traces.set(
|
|
9221
|
+
const facts = index.factsAt(path28);
|
|
9222
|
+
const out = new Set(importsOf(path28));
|
|
9223
|
+
if (facts?.status === "analyzed") resolveAll(path28, facts.reexports, out);
|
|
9224
|
+
traces.set(path28, out);
|
|
9209
9225
|
return out;
|
|
9210
9226
|
};
|
|
9211
9227
|
return {
|
|
@@ -10675,11 +10691,11 @@ var init_unconditional_call_cycles = __esm({
|
|
|
10675
10691
|
const memberEdges = keys.flatMap((k) => (adjacency.get(k) ?? []).filter((e) => inScc.has(e.toKey)));
|
|
10676
10692
|
if (memberEdges.length === 0) continue;
|
|
10677
10693
|
const anchor = [...memberEdges].sort((a, b) => byCodeUnit(a.fromKey, b.fromKey) || byCodeUnit(a.impl.id, b.impl.id) || a.stepNumber - b.stepNumber)[0];
|
|
10678
|
-
const
|
|
10694
|
+
const path28 = [...keys].sort(byCodeUnit).join(" \u2192 ");
|
|
10679
10695
|
ctx.addIssue(
|
|
10680
10696
|
"warning",
|
|
10681
10697
|
"UNCONDITIONAL_CALL_CYCLE",
|
|
10682
|
-
`Call cycle with no guard: ${
|
|
10698
|
+
`Call cycle with no guard: ${path28} \u2014 every call edge in this cycle is unavoidable on all paths of its narrative (e.g. step ${anchor.stepNumber} of "${anchor.methodName}" in "${anchor.impl.id}" always calls ${anchor.toLabel}). This recurses without a base case, by construction. Guard at least one edge with a branch/return before the call, or lint.allow with the termination argument.`,
|
|
10683
10699
|
anchor.impl.id,
|
|
10684
10700
|
memberEdges.some((e) => ctx.isImplementationDraft(e.impl))
|
|
10685
10701
|
);
|
|
@@ -13769,11 +13785,11 @@ var init_hidden_state = __esm({
|
|
|
13769
13785
|
byPath.set(key, list);
|
|
13770
13786
|
}
|
|
13771
13787
|
}
|
|
13772
|
-
for (const
|
|
13773
|
-
const facts = code.factsAt(
|
|
13788
|
+
for (const path28 of code.exactPaths) {
|
|
13789
|
+
const facts = code.factsAt(path28);
|
|
13774
13790
|
const bindings = facts.topLevelMutableBindings ?? [];
|
|
13775
13791
|
if (bindings.length === 0) continue;
|
|
13776
|
-
const mapped = byPath.get(
|
|
13792
|
+
const mapped = byPath.get(path28) ?? [];
|
|
13777
13793
|
if (mapped.length === 0) continue;
|
|
13778
13794
|
if (!mapped.every((m) => isStatelessLogic(m.component))) continue;
|
|
13779
13795
|
const anchor = [...mapped].sort((a, b) => a.impl.id.localeCompare(b.impl.id))[0];
|
|
@@ -13846,7 +13862,7 @@ var init_dependency_conformance = __esm({
|
|
|
13846
13862
|
}
|
|
13847
13863
|
return false;
|
|
13848
13864
|
};
|
|
13849
|
-
const draftAt = (
|
|
13865
|
+
const draftAt = (path28) => realization.implementationsAt(path28).some((impl) => ctx.isImplementationDraft(impl));
|
|
13850
13866
|
for (const fromPath of mappedPaths) {
|
|
13851
13867
|
const fromComponents = realization.componentsAt(fromPath);
|
|
13852
13868
|
for (const toPath of graph.importsOf(fromPath)) {
|
|
@@ -15857,7 +15873,7 @@ function resolveTypeScript(projectRoot) {
|
|
|
15857
15873
|
return cached.ts;
|
|
15858
15874
|
}
|
|
15859
15875
|
let ts = null;
|
|
15860
|
-
const bases = [
|
|
15876
|
+
const bases = [path12.join(projectRoot, "package.json"), __filename];
|
|
15861
15877
|
for (const base of bases) {
|
|
15862
15878
|
try {
|
|
15863
15879
|
const req = (0, import_module2.createRequire)(base);
|
|
@@ -16072,7 +16088,7 @@ function walkExact(ts, sourceText, fileName) {
|
|
|
16072
16088
|
}
|
|
16073
16089
|
function resolveRelativeModule(fromFile, specifier) {
|
|
16074
16090
|
if (!specifier.startsWith(".")) return null;
|
|
16075
|
-
const base =
|
|
16091
|
+
const base = path12.resolve(path12.dirname(fromFile), specifier);
|
|
16076
16092
|
const candidates = [
|
|
16077
16093
|
base,
|
|
16078
16094
|
base.replace(/\.js$/, ".ts"),
|
|
@@ -16080,12 +16096,12 @@ function resolveRelativeModule(fromFile, specifier) {
|
|
|
16080
16096
|
`${base}.ts`,
|
|
16081
16097
|
`${base}.tsx`,
|
|
16082
16098
|
`${base}.js`,
|
|
16083
|
-
|
|
16084
|
-
|
|
16099
|
+
path12.join(base, "index.ts"),
|
|
16100
|
+
path12.join(base, "index.js")
|
|
16085
16101
|
];
|
|
16086
16102
|
for (const c of candidates) {
|
|
16087
16103
|
try {
|
|
16088
|
-
if (
|
|
16104
|
+
if (fs9.statSync(c).isFile()) return c;
|
|
16089
16105
|
} catch {
|
|
16090
16106
|
}
|
|
16091
16107
|
}
|
|
@@ -16093,11 +16109,11 @@ function resolveRelativeModule(fromFile, specifier) {
|
|
|
16093
16109
|
}
|
|
16094
16110
|
function reexportTarget(ts, filePath, specifier, projectRoot, visited, exactCache) {
|
|
16095
16111
|
const target = resolveRelativeModule(filePath, specifier);
|
|
16096
|
-
if (!target ||
|
|
16112
|
+
if (!target || path12.relative(projectRoot, target).startsWith("..")) return null;
|
|
16097
16113
|
let targetFacts = exactCache.get(target);
|
|
16098
16114
|
if (targetFacts === void 0) {
|
|
16099
16115
|
try {
|
|
16100
|
-
targetFacts = walkExact(ts,
|
|
16116
|
+
targetFacts = walkExact(ts, fs9.readFileSync(target, "utf8"), target);
|
|
16101
16117
|
} catch {
|
|
16102
16118
|
targetFacts = null;
|
|
16103
16119
|
}
|
|
@@ -16115,7 +16131,7 @@ function carryBody(facts, target, targetPath, local, exported, projectRoot) {
|
|
|
16115
16131
|
if (score !== void 0) facts.complexity.set(exported, Math.max(facts.complexity.get(exported) ?? 0, score));
|
|
16116
16132
|
const targetCalls = target.calls.get(local);
|
|
16117
16133
|
if (!targetCalls) return;
|
|
16118
|
-
const carriedFrom = pathKey(
|
|
16134
|
+
const carriedFrom = pathKey(path12.relative(projectRoot, targetPath));
|
|
16119
16135
|
const sites = facts.calls.get(exported) ?? /* @__PURE__ */ new Map();
|
|
16120
16136
|
for (const [key, site] of targetCalls) sites.set(carriedFrom + "|" + key, { ...site, from: site.from ?? carriedFrom });
|
|
16121
16137
|
facts.calls.set(exported, sites);
|
|
@@ -16145,24 +16161,24 @@ function walkDeclaredRoots(roots, exclude, projectRoot) {
|
|
|
16145
16161
|
const excluded = exclude.map(pathKey);
|
|
16146
16162
|
const isExcluded = (key) => excluded.some((e) => key === e || key.startsWith(`${e}/`));
|
|
16147
16163
|
const record = (absolute) => {
|
|
16148
|
-
const key = pathKey(
|
|
16164
|
+
const key = pathKey(path12.relative(projectRoot, absolute));
|
|
16149
16165
|
if (seen.has(key) || isExcluded(key)) return;
|
|
16150
|
-
if (!EXTENSION_LANGUAGE[
|
|
16166
|
+
if (!EXTENSION_LANGUAGE[path12.extname(key).toLowerCase()]) return;
|
|
16151
16167
|
seen.add(key);
|
|
16152
16168
|
found.push(key);
|
|
16153
16169
|
};
|
|
16154
16170
|
const descend = (dir) => {
|
|
16155
16171
|
let entries;
|
|
16156
16172
|
try {
|
|
16157
|
-
entries =
|
|
16173
|
+
entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
16158
16174
|
} catch {
|
|
16159
16175
|
return;
|
|
16160
16176
|
}
|
|
16161
16177
|
for (const entry of entries.slice().sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
16162
|
-
const child =
|
|
16178
|
+
const child = path12.join(dir, entry.name);
|
|
16163
16179
|
if (entry.isDirectory()) {
|
|
16164
16180
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
16165
|
-
if (isExcluded(pathKey(
|
|
16181
|
+
if (isExcluded(pathKey(path12.relative(projectRoot, child)))) continue;
|
|
16166
16182
|
descend(child);
|
|
16167
16183
|
} else if (entry.isFile()) {
|
|
16168
16184
|
record(child);
|
|
@@ -16171,13 +16187,13 @@ function walkDeclaredRoots(roots, exclude, projectRoot) {
|
|
|
16171
16187
|
};
|
|
16172
16188
|
for (const root of roots) {
|
|
16173
16189
|
const key = pathKey(root);
|
|
16174
|
-
if (
|
|
16175
|
-
const absolute =
|
|
16176
|
-
if (
|
|
16190
|
+
if (path12.isAbsolute(key) || path12.normalize(key).split(path12.sep)[0] === "..") continue;
|
|
16191
|
+
const absolute = path12.resolve(projectRoot, key);
|
|
16192
|
+
if (path12.relative(projectRoot, absolute).startsWith("..")) continue;
|
|
16177
16193
|
if (isExcluded(key)) continue;
|
|
16178
16194
|
let stat;
|
|
16179
16195
|
try {
|
|
16180
|
-
stat =
|
|
16196
|
+
stat = fs9.statSync(absolute);
|
|
16181
16197
|
} catch {
|
|
16182
16198
|
continue;
|
|
16183
16199
|
}
|
|
@@ -16203,23 +16219,23 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
|
|
|
16203
16219
|
if (seen.has(sourcePath)) continue;
|
|
16204
16220
|
seen.add(sourcePath);
|
|
16205
16221
|
const empty = { declaredNames: [], anchoredNames: [], exportedNames: [], imports: [], reexports: [] };
|
|
16206
|
-
if (
|
|
16222
|
+
if (path12.isAbsolute(sourcePath) || path12.normalize(sourcePath).split(path12.sep)[0] === "..") {
|
|
16207
16223
|
files.push({ path: sourcePath, status: "escaped", ...empty });
|
|
16208
16224
|
continue;
|
|
16209
16225
|
}
|
|
16210
|
-
const absolute =
|
|
16211
|
-
if (
|
|
16226
|
+
const absolute = path12.resolve(projectRoot, sourcePath);
|
|
16227
|
+
if (path12.relative(projectRoot, absolute).startsWith("..")) {
|
|
16212
16228
|
files.push({ path: sourcePath, status: "escaped", ...empty });
|
|
16213
16229
|
continue;
|
|
16214
16230
|
}
|
|
16215
16231
|
let buffer;
|
|
16216
16232
|
try {
|
|
16217
|
-
const stat =
|
|
16233
|
+
const stat = fs9.statSync(absolute);
|
|
16218
16234
|
if (!stat.isFile()) {
|
|
16219
16235
|
files.push({ path: sourcePath, status: "missing", ...empty });
|
|
16220
16236
|
continue;
|
|
16221
16237
|
}
|
|
16222
|
-
buffer =
|
|
16238
|
+
buffer = fs9.readFileSync(absolute);
|
|
16223
16239
|
} catch {
|
|
16224
16240
|
files.push({ path: sourcePath, status: "missing", ...empty });
|
|
16225
16241
|
continue;
|
|
@@ -16229,7 +16245,7 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
|
|
|
16229
16245
|
continue;
|
|
16230
16246
|
}
|
|
16231
16247
|
const text = buffer.toString("utf8");
|
|
16232
|
-
const language = EXTENSION_LANGUAGE[
|
|
16248
|
+
const language = EXTENSION_LANGUAGE[path12.extname(sourcePath).toLowerCase()];
|
|
16233
16249
|
let analyzed;
|
|
16234
16250
|
if (language === "typescript" || language === "javascript") {
|
|
16235
16251
|
const ts = resolveTypeScript(projectRoot);
|
|
@@ -16273,7 +16289,7 @@ function readTestFiles(testRoots, projectRoot) {
|
|
|
16273
16289
|
for (const key of walkDeclaredRoots(testRoots, [], projectRoot)) {
|
|
16274
16290
|
let text;
|
|
16275
16291
|
try {
|
|
16276
|
-
const buffer =
|
|
16292
|
+
const buffer = fs9.readFileSync(path12.resolve(projectRoot, key));
|
|
16277
16293
|
if (looksBinary(buffer)) continue;
|
|
16278
16294
|
text = buffer.toString("utf8");
|
|
16279
16295
|
} catch {
|
|
@@ -16310,12 +16326,12 @@ function findTestsReferencing(methods, projectRoot, testRoots = []) {
|
|
|
16310
16326
|
}
|
|
16311
16327
|
return found;
|
|
16312
16328
|
}
|
|
16313
|
-
var
|
|
16329
|
+
var fs9, path12, import_module2, EXTENSION_LANGUAGE, C_FAMILY_COMMENTS, NAMED_IMPORT_BINDINGS_RE, JS_PATTERNS, LANGUAGE_PATTERNS, PATTERN_ANALYSIS_MAX_BYTES, IDENTIFIER_RE, STRING_RE, tsResolutionCache, TS_RESOLUTION_RETRY_MS;
|
|
16314
16330
|
var init_source_analysis = __esm({
|
|
16315
16331
|
"src/core/source-analysis.ts"() {
|
|
16316
16332
|
"use strict";
|
|
16317
|
-
|
|
16318
|
-
|
|
16333
|
+
fs9 = __toESM(require("fs"));
|
|
16334
|
+
path12 = __toESM(require("path"));
|
|
16319
16335
|
import_module2 = require("module");
|
|
16320
16336
|
init_models();
|
|
16321
16337
|
EXTENSION_LANGUAGE = {
|
|
@@ -17082,28 +17098,28 @@ var init_gate_identity = __esm({
|
|
|
17082
17098
|
|
|
17083
17099
|
// src/core/variants.ts
|
|
17084
17100
|
function globalVariantsDir() {
|
|
17085
|
-
return process.env.WAIRON_VARIANTS_DIR ??
|
|
17101
|
+
return process.env.WAIRON_VARIANTS_DIR ?? path13.join(os3.homedir(), ".wairon", "variants");
|
|
17086
17102
|
}
|
|
17087
17103
|
function builtinVariantsDir() {
|
|
17088
17104
|
const candidates = [
|
|
17089
|
-
|
|
17105
|
+
path13.resolve(__dirname, "..", "templates", "variants"),
|
|
17090
17106
|
// src/core & dist/cli
|
|
17091
|
-
|
|
17107
|
+
path13.resolve(__dirname, "templates", "variants")
|
|
17092
17108
|
// dist (library entry)
|
|
17093
17109
|
];
|
|
17094
|
-
return candidates.find((dir) =>
|
|
17110
|
+
return candidates.find((dir) => fs10.existsSync(dir)) ?? candidates[0];
|
|
17095
17111
|
}
|
|
17096
17112
|
function projectVariantsDir() {
|
|
17097
|
-
return
|
|
17113
|
+
return path13.join(getProjectRoot(), ".wai", "variants");
|
|
17098
17114
|
}
|
|
17099
17115
|
function variantFiles(dir) {
|
|
17100
17116
|
let entries;
|
|
17101
17117
|
try {
|
|
17102
|
-
entries =
|
|
17118
|
+
entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
17103
17119
|
} catch {
|
|
17104
17120
|
return [];
|
|
17105
17121
|
}
|
|
17106
|
-
return entries.filter((e) => e.isFile() && /\.ya?ml$/i.test(e.name)).sort((a, b) => a.name.localeCompare(b.name)).map((e) =>
|
|
17122
|
+
return entries.filter((e) => e.isFile() && /\.ya?ml$/i.test(e.name)).sort((a, b) => a.name.localeCompare(b.name)).map((e) => path13.join(dir, e.name));
|
|
17107
17123
|
}
|
|
17108
17124
|
function parseVariants(raw) {
|
|
17109
17125
|
if (raw == null) return [];
|
|
@@ -17212,13 +17228,13 @@ function rebasedText(content, fromBase, toBase, rebasedContent) {
|
|
|
17212
17228
|
}
|
|
17213
17229
|
return serializeYaml(rebasedContent);
|
|
17214
17230
|
}
|
|
17215
|
-
var
|
|
17231
|
+
var fs10, os3, path13, import_zod10, VariantDefSchema;
|
|
17216
17232
|
var init_variants = __esm({
|
|
17217
17233
|
"src/core/variants.ts"() {
|
|
17218
17234
|
"use strict";
|
|
17219
|
-
|
|
17235
|
+
fs10 = __toESM(require("fs"));
|
|
17220
17236
|
os3 = __toESM(require("os"));
|
|
17221
|
-
|
|
17237
|
+
path13 = __toESM(require("path"));
|
|
17222
17238
|
import_zod10 = require("zod");
|
|
17223
17239
|
init_yaml();
|
|
17224
17240
|
init_fs();
|
|
@@ -17608,7 +17624,7 @@ var init_openapi = __esm({
|
|
|
17608
17624
|
|
|
17609
17625
|
// src/core/surfaces.ts
|
|
17610
17626
|
function surfacesDir(rootDir) {
|
|
17611
|
-
return
|
|
17627
|
+
return path14.join(rootDir, ".wai", SURFACES_DIRNAME);
|
|
17612
17628
|
}
|
|
17613
17629
|
function audienceRank(audience) {
|
|
17614
17630
|
const idx = SURFACE_AUDIENCES.indexOf(audience ?? "instance");
|
|
@@ -17766,12 +17782,12 @@ function projectSubsystemSurface(subsystemId) {
|
|
|
17766
17782
|
}
|
|
17767
17783
|
function listSnapshots(rootDir = getProjectRoot()) {
|
|
17768
17784
|
const dir = surfacesDir(rootDir);
|
|
17769
|
-
if (!
|
|
17785
|
+
if (!fs11.existsSync(dir)) return [];
|
|
17770
17786
|
const out = [];
|
|
17771
|
-
for (const file of
|
|
17787
|
+
for (const file of fs11.readdirSync(dir)) {
|
|
17772
17788
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
17773
17789
|
try {
|
|
17774
|
-
out.push(SurfaceSnapshotSchema.parse(readYamlFile(
|
|
17790
|
+
out.push(SurfaceSnapshotSchema.parse(readYamlFile(path14.join(dir, file))));
|
|
17775
17791
|
} catch {
|
|
17776
17792
|
}
|
|
17777
17793
|
}
|
|
@@ -17785,10 +17801,10 @@ function snapshotFilename(projectName) {
|
|
|
17785
17801
|
}
|
|
17786
17802
|
function writeSnapshotIfChanged(snapshot, rootDir) {
|
|
17787
17803
|
const dir = surfacesDir(rootDir);
|
|
17788
|
-
|
|
17789
|
-
const p =
|
|
17804
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
17805
|
+
const p = path14.join(dir, snapshotFilename(snapshot.projectName));
|
|
17790
17806
|
const next = SurfaceSnapshotSchema.parse(snapshot);
|
|
17791
|
-
if (
|
|
17807
|
+
if (fs11.existsSync(p)) {
|
|
17792
17808
|
try {
|
|
17793
17809
|
const existing = SurfaceSnapshotSchema.parse(readYamlFile(p));
|
|
17794
17810
|
if (surfaceContentKey(existing) === surfaceContentKey(next)) {
|
|
@@ -17805,19 +17821,19 @@ function saveSnapshot(snapshot, rootDir = getProjectRoot()) {
|
|
|
17805
17821
|
}
|
|
17806
17822
|
function removeSnapshot(projectName, rootDir = getProjectRoot()) {
|
|
17807
17823
|
const dir = surfacesDir(rootDir);
|
|
17808
|
-
const direct =
|
|
17809
|
-
if (
|
|
17810
|
-
|
|
17824
|
+
const direct = path14.join(dir, snapshotFilename(projectName));
|
|
17825
|
+
if (fs11.existsSync(direct)) {
|
|
17826
|
+
fs11.unlinkSync(direct);
|
|
17811
17827
|
return true;
|
|
17812
17828
|
}
|
|
17813
|
-
if (!
|
|
17814
|
-
for (const file of
|
|
17829
|
+
if (!fs11.existsSync(dir)) return false;
|
|
17830
|
+
for (const file of fs11.readdirSync(dir)) {
|
|
17815
17831
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
17816
|
-
const p =
|
|
17832
|
+
const p = path14.join(dir, file);
|
|
17817
17833
|
try {
|
|
17818
17834
|
const snap = SurfaceSnapshotSchema.parse(readYamlFile(p));
|
|
17819
17835
|
if (snap.projectName === projectName) {
|
|
17820
|
-
|
|
17836
|
+
fs11.unlinkSync(p);
|
|
17821
17837
|
return true;
|
|
17822
17838
|
}
|
|
17823
17839
|
} catch {
|
|
@@ -17829,11 +17845,11 @@ function loadSurfaceSnapshots() {
|
|
|
17829
17845
|
return listSnapshots();
|
|
17830
17846
|
}
|
|
17831
17847
|
function listMountSnapshots(mounts) {
|
|
17832
|
-
const bound2 =
|
|
17848
|
+
const bound2 = path14.resolve(getProjectRoot());
|
|
17833
17849
|
const out = [];
|
|
17834
17850
|
for (const namespace of mounts) {
|
|
17835
17851
|
const dir = resolveSubprojectForNamespace(namespace);
|
|
17836
|
-
if (!dir ||
|
|
17852
|
+
if (!dir || path14.resolve(dir) === bound2) continue;
|
|
17837
17853
|
const snapshots = listSnapshots(dir);
|
|
17838
17854
|
if (snapshots.length > 0) out.push({ namespace, snapshots });
|
|
17839
17855
|
}
|
|
@@ -17851,24 +17867,24 @@ function selectPortalSpec(renderedSet, portalId) {
|
|
|
17851
17867
|
return [hit];
|
|
17852
17868
|
}
|
|
17853
17869
|
function perPortalPath(resolvedOut, portalId) {
|
|
17854
|
-
const ext =
|
|
17870
|
+
const ext = path14.extname(resolvedOut);
|
|
17855
17871
|
const stem = ext ? resolvedOut.slice(0, -ext.length) : resolvedOut;
|
|
17856
17872
|
return `${stem}.${safeFilenamePart(portalId)}${ext}`;
|
|
17857
17873
|
}
|
|
17858
17874
|
function writeSurfaceFile(outPath, snapshot, renderedSet) {
|
|
17859
|
-
const resolved =
|
|
17860
|
-
|
|
17875
|
+
const resolved = path14.resolve(outPath);
|
|
17876
|
+
fs11.mkdirSync(path14.dirname(resolved), { recursive: true });
|
|
17861
17877
|
if (!renderedSet || renderedSet.length === 0) {
|
|
17862
17878
|
writeYamlFile(resolved, snapshot);
|
|
17863
17879
|
return [resolved];
|
|
17864
17880
|
}
|
|
17865
17881
|
if (renderedSet.length === 1) {
|
|
17866
|
-
|
|
17882
|
+
fs11.writeFileSync(resolved, renderedSet[0].document);
|
|
17867
17883
|
return [resolved];
|
|
17868
17884
|
}
|
|
17869
17885
|
return renderedSet.map((spec) => {
|
|
17870
17886
|
const target = perPortalPath(resolved, spec.portalId);
|
|
17871
|
-
|
|
17887
|
+
fs11.writeFileSync(target, spec.document);
|
|
17872
17888
|
return target;
|
|
17873
17889
|
});
|
|
17874
17890
|
}
|
|
@@ -17890,14 +17906,14 @@ function exportSurface(maxAudience, format, outPath, portalId) {
|
|
|
17890
17906
|
return exportResult(snapshot, renderedSet, writtenPaths);
|
|
17891
17907
|
}
|
|
17892
17908
|
function importSurface(sourcePath, origin) {
|
|
17893
|
-
const resolved =
|
|
17894
|
-
if (!
|
|
17909
|
+
const resolved = path14.resolve(sourcePath);
|
|
17910
|
+
if (!fs11.existsSync(resolved)) {
|
|
17895
17911
|
throw new Error(`Surface document not found: ${resolved}`);
|
|
17896
17912
|
}
|
|
17897
|
-
const body =
|
|
17913
|
+
const body = fs11.readFileSync(resolved, "utf8");
|
|
17898
17914
|
let snapshot;
|
|
17899
17915
|
if (isOpenApiDocument(body)) {
|
|
17900
|
-
const projectName =
|
|
17916
|
+
const projectName = path14.basename(resolved).replace(/\.(json|ya?ml)$/i, "");
|
|
17901
17917
|
snapshot = fromOpenApi(body, projectName);
|
|
17902
17918
|
snapshot = { ...snapshot, origin };
|
|
17903
17919
|
} else {
|
|
@@ -17960,12 +17976,12 @@ function surfaceContentKey(snapshot) {
|
|
|
17960
17976
|
const { stateId, generatedAt, origin, ...content } = snapshot;
|
|
17961
17977
|
return JSON.stringify(content);
|
|
17962
17978
|
}
|
|
17963
|
-
var
|
|
17979
|
+
var fs11, path14, SURFACES_DIRNAME, CROSS_BOUNDARY_TARGETS;
|
|
17964
17980
|
var init_surfaces = __esm({
|
|
17965
17981
|
"src/core/surfaces.ts"() {
|
|
17966
17982
|
"use strict";
|
|
17967
|
-
|
|
17968
|
-
|
|
17983
|
+
fs11 = __toESM(require("fs"));
|
|
17984
|
+
path14 = __toESM(require("path"));
|
|
17969
17985
|
init_fs();
|
|
17970
17986
|
init_yaml();
|
|
17971
17987
|
init_filenames();
|
|
@@ -17984,12 +18000,12 @@ function digest(content) {
|
|
|
17984
18000
|
return crypto4.createHash("sha256").update(normalized, "utf8").digest("hex");
|
|
17985
18001
|
}
|
|
17986
18002
|
function currentSpecDigests(root = getProjectRoot()) {
|
|
17987
|
-
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${
|
|
18003
|
+
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${path15.resolve(root, s.projectPath).split(path15.sep).join("/")}/`);
|
|
17988
18004
|
const out = {};
|
|
17989
18005
|
for (const [abs, content] of snapshotSpecFiles()) {
|
|
17990
|
-
const normalized =
|
|
18006
|
+
const normalized = path15.resolve(abs).split(path15.sep).join("/");
|
|
17991
18007
|
if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
|
|
17992
|
-
out[
|
|
18008
|
+
out[path15.relative(root, abs).split(path15.sep).join("/")] = digest(content);
|
|
17993
18009
|
}
|
|
17994
18010
|
return out;
|
|
17995
18011
|
}
|
|
@@ -18047,17 +18063,17 @@ function currentChildPins(mounts, root = getProjectRoot()) {
|
|
|
18047
18063
|
const pins = {};
|
|
18048
18064
|
for (const mount of mounts) {
|
|
18049
18065
|
if (!mount.projectPath || mount.id.includes("::")) continue;
|
|
18050
|
-
const child = readLockRecordAt(
|
|
18066
|
+
const child = readLockRecordAt(path15.resolve(root, mount.projectPath));
|
|
18051
18067
|
if (child) pins[mount.id] = pinOf(child.stateId);
|
|
18052
18068
|
}
|
|
18053
18069
|
return pins;
|
|
18054
18070
|
}
|
|
18055
|
-
var crypto4,
|
|
18071
|
+
var crypto4, path15;
|
|
18056
18072
|
var init_approval = __esm({
|
|
18057
18073
|
"src/core/approval.ts"() {
|
|
18058
18074
|
"use strict";
|
|
18059
18075
|
crypto4 = __toESM(require("crypto"));
|
|
18060
|
-
|
|
18076
|
+
path15 = __toESM(require("path"));
|
|
18061
18077
|
init_fs();
|
|
18062
18078
|
init_specs2();
|
|
18063
18079
|
init_lockfile();
|
|
@@ -18345,13 +18361,13 @@ function validateSddTree(rulesOrOptions, projectType = "backend") {
|
|
|
18345
18361
|
function resolveThroughParent(boundRoot, treatAllAsComplete, childRules) {
|
|
18346
18362
|
const reach = getRequestParentReach();
|
|
18347
18363
|
if (reach && !reach.parentReach) return null;
|
|
18348
|
-
const ceiling = reach?.topRoot ?
|
|
18364
|
+
const ceiling = reach?.topRoot ? path16.resolve(reach.topRoot) : void 0;
|
|
18349
18365
|
const chain = [];
|
|
18350
|
-
let top =
|
|
18366
|
+
let top = path16.resolve(boundRoot);
|
|
18351
18367
|
while (top !== ceiling) {
|
|
18352
18368
|
const hop = findChainingParent(top, ceiling);
|
|
18353
18369
|
if (!hop) break;
|
|
18354
|
-
const next =
|
|
18370
|
+
const next = path16.resolve(hop.parentRoot);
|
|
18355
18371
|
if (ceiling && !isWithinOrEqual(ceiling, next)) break;
|
|
18356
18372
|
chain.unshift(hop.subsystemId);
|
|
18357
18373
|
top = next;
|
|
@@ -18398,8 +18414,8 @@ function isIdChar(ch) {
|
|
|
18398
18414
|
return ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === "-" || ch === "." || ch === ":";
|
|
18399
18415
|
}
|
|
18400
18416
|
function isWithinOrEqual(dir, target) {
|
|
18401
|
-
const rel2 =
|
|
18402
|
-
return rel2 === "" || !rel2.startsWith("..") && !
|
|
18417
|
+
const rel2 = path16.relative(dir, target);
|
|
18418
|
+
return rel2 === "" || !rel2.startsWith("..") && !path16.isAbsolute(rel2);
|
|
18403
18419
|
}
|
|
18404
18420
|
function dedupeIssues(list) {
|
|
18405
18421
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -18420,7 +18436,7 @@ function settledStatusBearing(loaded) {
|
|
|
18420
18436
|
if (!settled || settled.size === 0) return [];
|
|
18421
18437
|
const root = getProjectRoot();
|
|
18422
18438
|
const index = scanAllSpecs();
|
|
18423
|
-
const rel2 = (abs) =>
|
|
18439
|
+
const rel2 = (abs) => path16.relative(root, abs).split(path16.sep).join("/");
|
|
18424
18440
|
const out = [];
|
|
18425
18441
|
const take = (specs, paths) => {
|
|
18426
18442
|
for (const spec of specs) {
|
|
@@ -18450,7 +18466,7 @@ function computeGateStateId() {
|
|
|
18450
18466
|
registerBuiltinRules();
|
|
18451
18467
|
return computeGateIdentity(content, extensions, ruleSequence(), inputs, gate);
|
|
18452
18468
|
}
|
|
18453
|
-
var
|
|
18469
|
+
var path16, RESOLUTION_FAILURE_CODES, SEVERITY_RANK;
|
|
18454
18470
|
var init_validation = __esm({
|
|
18455
18471
|
"src/core/validation.ts"() {
|
|
18456
18472
|
"use strict";
|
|
@@ -18466,7 +18482,7 @@ var init_validation = __esm({
|
|
|
18466
18482
|
init_source_analysis();
|
|
18467
18483
|
init_specs2();
|
|
18468
18484
|
init_fs();
|
|
18469
|
-
|
|
18485
|
+
path16 = __toESM(require("path"));
|
|
18470
18486
|
init_approval();
|
|
18471
18487
|
RESOLUTION_FAILURE_CODES = /* @__PURE__ */ new Set([
|
|
18472
18488
|
"UNDEFINED_TYPE_REFERENCE",
|
|
@@ -19109,42 +19125,42 @@ function rebaseReference(ref, mount, direction, isMoved = () => false) {
|
|
|
19109
19125
|
return relativizeId(travels ? qualifyId(left, to, NO_ROOT_SUBSYSTEMS) : target, to);
|
|
19110
19126
|
}
|
|
19111
19127
|
function isWithin(dir, file) {
|
|
19112
|
-
const d =
|
|
19113
|
-
const f =
|
|
19114
|
-
return f === d || f.startsWith(d +
|
|
19128
|
+
const d = path17.resolve(dir);
|
|
19129
|
+
const f = path17.resolve(file);
|
|
19130
|
+
return f === d || f.startsWith(d + path17.sep);
|
|
19115
19131
|
}
|
|
19116
19132
|
function canonicalPath(target) {
|
|
19117
|
-
let existing =
|
|
19133
|
+
let existing = path17.resolve(target);
|
|
19118
19134
|
const rest = [];
|
|
19119
19135
|
for (; ; ) {
|
|
19120
19136
|
try {
|
|
19121
|
-
|
|
19137
|
+
fs12.lstatSync(existing);
|
|
19122
19138
|
break;
|
|
19123
19139
|
} catch {
|
|
19124
|
-
const up =
|
|
19125
|
-
if (up === existing) return
|
|
19126
|
-
rest.unshift(
|
|
19140
|
+
const up = path17.dirname(existing);
|
|
19141
|
+
if (up === existing) return path17.resolve(target);
|
|
19142
|
+
rest.unshift(path17.basename(existing));
|
|
19127
19143
|
existing = up;
|
|
19128
19144
|
}
|
|
19129
19145
|
}
|
|
19130
19146
|
try {
|
|
19131
|
-
return
|
|
19147
|
+
return path17.join(fs12.realpathSync.native(existing), ...rest);
|
|
19132
19148
|
} catch {
|
|
19133
19149
|
return null;
|
|
19134
19150
|
}
|
|
19135
19151
|
}
|
|
19136
19152
|
function chainDirKey(dir) {
|
|
19137
|
-
return canonicalPath(dir) ??
|
|
19153
|
+
return canonicalPath(dir) ?? path17.resolve(dir);
|
|
19138
19154
|
}
|
|
19139
19155
|
function projectPathEscapesRoot(projectRoot, projectPath, resolvedChildDir) {
|
|
19140
|
-
if (
|
|
19156
|
+
if (path17.isAbsolute(projectPath) || !isWithin(projectRoot, resolvedChildDir)) return true;
|
|
19141
19157
|
const root = canonicalPath(projectRoot);
|
|
19142
19158
|
const child = canonicalPath(resolvedChildDir);
|
|
19143
19159
|
return root === null || child === null || !isWithin(root, child);
|
|
19144
19160
|
}
|
|
19145
19161
|
function assertContainedProjectPath(projectRoot, projectPath) {
|
|
19146
|
-
const root =
|
|
19147
|
-
const resolved =
|
|
19162
|
+
const root = path17.resolve(projectRoot);
|
|
19163
|
+
const resolved = path17.resolve(root, projectPath);
|
|
19148
19164
|
if (projectPathEscapesRoot(root, projectPath, resolved)) {
|
|
19149
19165
|
throw new Error(
|
|
19150
19166
|
`projectPath "${projectPath}" must resolve within the project root "${root}", but resolves to "${resolved}"; absolute, ../-escaping and link-escaping paths are rejected so a chained subproject is always contained by its parent.`
|
|
@@ -19155,12 +19171,12 @@ function assertContainedProjectPath(projectRoot, projectPath) {
|
|
|
19155
19171
|
function findChainingParent(childRoot, ceiling) {
|
|
19156
19172
|
let childResolved;
|
|
19157
19173
|
try {
|
|
19158
|
-
childResolved =
|
|
19174
|
+
childResolved = path17.resolve(childRoot);
|
|
19159
19175
|
} catch {
|
|
19160
19176
|
return null;
|
|
19161
19177
|
}
|
|
19162
|
-
const bound2 = ceiling ?
|
|
19163
|
-
let dir =
|
|
19178
|
+
const bound2 = ceiling ? path17.resolve(ceiling) : void 0;
|
|
19179
|
+
let dir = path17.dirname(childResolved);
|
|
19164
19180
|
for (let hops = 0; hops < 32; hops++) {
|
|
19165
19181
|
if (bound2 && !isWithin(bound2, dir)) break;
|
|
19166
19182
|
const specsDir = aiPathsAt(dir).specsDir();
|
|
@@ -19176,7 +19192,7 @@ function findChainingParent(childRoot, ceiling) {
|
|
|
19176
19192
|
const projectPath = raw.projectPath;
|
|
19177
19193
|
if (typeof projectPath === "string" && projectPath.trim() !== "") {
|
|
19178
19194
|
try {
|
|
19179
|
-
const mountDir =
|
|
19195
|
+
const mountDir = path17.resolve(dir, projectPath);
|
|
19180
19196
|
if (mountDir === childResolved && !projectPathEscapesRoot(dir, projectPath, mountDir)) {
|
|
19181
19197
|
const id = raw.id;
|
|
19182
19198
|
return { parentRoot: dir, subsystemId: typeof id === "string" ? id : "?" };
|
|
@@ -19187,14 +19203,14 @@ function findChainingParent(childRoot, ceiling) {
|
|
|
19187
19203
|
}
|
|
19188
19204
|
}
|
|
19189
19205
|
}
|
|
19190
|
-
const up =
|
|
19206
|
+
const up = path17.dirname(dir);
|
|
19191
19207
|
if (up === dir) break;
|
|
19192
19208
|
dir = up;
|
|
19193
19209
|
}
|
|
19194
19210
|
return null;
|
|
19195
19211
|
}
|
|
19196
19212
|
function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
19197
|
-
const root =
|
|
19213
|
+
const root = path17.resolve(rootDir);
|
|
19198
19214
|
const inspection = { roots: [], skipped: [] };
|
|
19199
19215
|
const listed = /* @__PURE__ */ new Set();
|
|
19200
19216
|
const walk2 = (projectDir, prefix, ancestors, depth) => {
|
|
@@ -19213,14 +19229,14 @@ function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
|
19213
19229
|
const localId = typeof id === "string" ? id : "?";
|
|
19214
19230
|
let childDir;
|
|
19215
19231
|
try {
|
|
19216
|
-
childDir =
|
|
19232
|
+
childDir = path17.resolve(projectDir, projectPath);
|
|
19217
19233
|
} catch {
|
|
19218
19234
|
continue;
|
|
19219
19235
|
}
|
|
19220
19236
|
let reason;
|
|
19221
19237
|
if (projectPathEscapesRoot(projectDir, projectPath, childDir)) reason = "escapes";
|
|
19222
19238
|
else if (ancestors.has(chainDirKey(childDir))) reason = "cyclic";
|
|
19223
|
-
else if (!
|
|
19239
|
+
else if (!fs12.existsSync(childDir)) reason = "missing";
|
|
19224
19240
|
else if (depth >= 32) reason = "too-deep";
|
|
19225
19241
|
if (reason) {
|
|
19226
19242
|
const mount = prefix ? qualifyDeclaredId(localId, prefix, true) : localId;
|
|
@@ -19230,7 +19246,7 @@ function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
|
19230
19246
|
const key = chainDirKey(childDir);
|
|
19231
19247
|
if (listed.has(key)) continue;
|
|
19232
19248
|
listed.add(key);
|
|
19233
|
-
inspection.roots.push(
|
|
19249
|
+
inspection.roots.push(path17.relative(root, childDir).split(path17.sep).join("/"));
|
|
19234
19250
|
walk2(childDir, prefix ? `${prefix}::${localId}` : localId, /* @__PURE__ */ new Set([...ancestors, key]), depth + 1);
|
|
19235
19251
|
}
|
|
19236
19252
|
};
|
|
@@ -19316,9 +19332,9 @@ function stripNamespaceFromImplementation(spec, prefix) {
|
|
|
19316
19332
|
}
|
|
19317
19333
|
function childRelativeFilePaths(spec, authoringRoot, childRoot) {
|
|
19318
19334
|
const reexpress = (p) => {
|
|
19319
|
-
if (
|
|
19320
|
-
const rel2 =
|
|
19321
|
-
const inside = rel2 !== "" && rel2 !== ".." && !rel2.startsWith(`..${
|
|
19335
|
+
if (path17.isAbsolute(p)) return p;
|
|
19336
|
+
const rel2 = path17.relative(childRoot, path17.resolve(authoringRoot, p));
|
|
19337
|
+
const inside = rel2 !== "" && rel2 !== ".." && !rel2.startsWith(`..${path17.sep}`) && !path17.isAbsolute(rel2);
|
|
19322
19338
|
return inside ? rel2.replace(/\\/g, "/") : p;
|
|
19323
19339
|
};
|
|
19324
19340
|
return {
|
|
@@ -19353,23 +19369,12 @@ function findOwner(id, components) {
|
|
|
19353
19369
|
}) ?? null;
|
|
19354
19370
|
}
|
|
19355
19371
|
function moveComponentFolder(fromDir, toDir) {
|
|
19356
|
-
if (
|
|
19357
|
-
if (!
|
|
19358
|
-
ensureDir(
|
|
19359
|
-
|
|
19372
|
+
if (path17.normalize(fromDir) === path17.normalize(toDir)) return false;
|
|
19373
|
+
if (!fs12.existsSync(fromDir) || fs12.existsSync(toDir)) return false;
|
|
19374
|
+
ensureDir(path17.dirname(toDir));
|
|
19375
|
+
fs12.renameSync(fromDir, toDir);
|
|
19360
19376
|
return true;
|
|
19361
19377
|
}
|
|
19362
|
-
function cleanEmptyDirs(filePath, specsRoot) {
|
|
19363
|
-
let dir = path16.dirname(filePath);
|
|
19364
|
-
while (dir !== specsRoot && dir.startsWith(specsRoot)) {
|
|
19365
|
-
if (fs11.existsSync(dir) && fs11.readdirSync(dir).length === 0) {
|
|
19366
|
-
fs11.rmdirSync(dir);
|
|
19367
|
-
dir = path16.dirname(dir);
|
|
19368
|
-
} else {
|
|
19369
|
-
break;
|
|
19370
|
-
}
|
|
19371
|
-
}
|
|
19372
|
-
}
|
|
19373
19378
|
function formatZodIssues(error) {
|
|
19374
19379
|
return error.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ");
|
|
19375
19380
|
}
|
|
@@ -19383,13 +19388,13 @@ function parseOrThrow(schema, value, kind, id) {
|
|
|
19383
19388
|
function computeSpecTreeSignature(dirs) {
|
|
19384
19389
|
const parts = [];
|
|
19385
19390
|
for (const dir of dirs) {
|
|
19386
|
-
if (!
|
|
19391
|
+
if (!fs12.existsSync(dir)) {
|
|
19387
19392
|
parts.push(`${dir}:missing`);
|
|
19388
19393
|
continue;
|
|
19389
19394
|
}
|
|
19390
19395
|
for (const f of listSpecFiles(dir)) {
|
|
19391
19396
|
try {
|
|
19392
|
-
const st =
|
|
19397
|
+
const st = fs12.statSync(f);
|
|
19393
19398
|
parts.push(`${f}:${st.mtimeMs}:${st.size}`);
|
|
19394
19399
|
} catch {
|
|
19395
19400
|
parts.push(`${f}:gone`);
|
|
@@ -19634,13 +19639,13 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
|
19634
19639
|
const isPlain = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
19635
19640
|
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
19636
19641
|
const at = (prefix, key) => prefix ? `${prefix}.${key}` : key;
|
|
19637
|
-
const say = (
|
|
19638
|
-
out.push(`${
|
|
19642
|
+
const say = (path28, why) => {
|
|
19643
|
+
out.push(`${path28} \u2014 ${why}`);
|
|
19639
19644
|
};
|
|
19640
|
-
const walkValue = (d, m, s,
|
|
19645
|
+
const walkValue = (d, m, s, path28, field) => {
|
|
19641
19646
|
if (Array.isArray(d)) {
|
|
19642
19647
|
if (!Array.isArray(m)) {
|
|
19643
|
-
say(
|
|
19648
|
+
say(path28, "the level does not have this field, so the write dropped it");
|
|
19644
19649
|
return;
|
|
19645
19650
|
}
|
|
19646
19651
|
if (field === "narrative" && d.some(carriesEditMarker)) return;
|
|
@@ -19648,32 +19653,32 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
|
19648
19653
|
if (carriesEditMarker(element)) continue;
|
|
19649
19654
|
const key = reportIdentityOf(field, element);
|
|
19650
19655
|
if (key === null) {
|
|
19651
|
-
if (!same(m, d)) say(
|
|
19652
|
-
else if (same(s, d)) say(
|
|
19656
|
+
if (!same(m, d)) say(path28, "the level does not keep this value, so the write dropped it");
|
|
19657
|
+
else if (same(s, d)) say(path28, "the stored spec already held this value");
|
|
19653
19658
|
return;
|
|
19654
19659
|
}
|
|
19655
19660
|
const mMatch = m.find((i) => reportIdentityOf(field, i) === key);
|
|
19656
19661
|
const sMatch = Array.isArray(s) ? s.find((i) => reportIdentityOf(field, i) === key) : void 0;
|
|
19657
19662
|
if (mMatch === void 0) {
|
|
19658
|
-
say(at(
|
|
19663
|
+
say(at(path28, key), "the write did not store this element");
|
|
19659
19664
|
continue;
|
|
19660
19665
|
}
|
|
19661
|
-
walk2(element, mMatch, sMatch, at(
|
|
19666
|
+
walk2(element, mMatch, sMatch, at(path28, key), field);
|
|
19662
19667
|
}
|
|
19663
19668
|
return;
|
|
19664
19669
|
}
|
|
19665
19670
|
if (isPlain(d)) {
|
|
19666
19671
|
if (!isPlain(m)) {
|
|
19667
|
-
say(
|
|
19672
|
+
say(path28, "the level does not have this field, so the write dropped it");
|
|
19668
19673
|
return;
|
|
19669
19674
|
}
|
|
19670
|
-
walk2(d, m, s,
|
|
19675
|
+
walk2(d, m, s, path28, field);
|
|
19671
19676
|
return;
|
|
19672
19677
|
}
|
|
19673
|
-
if (!same(m, d)) say(
|
|
19674
|
-
else if (same(s, d)) say(
|
|
19678
|
+
if (!same(m, d)) say(path28, "the write did not store it \u2014 the level's schema does not keep this value");
|
|
19679
|
+
else if (same(s, d)) say(path28, "the stored spec already held this value");
|
|
19675
19680
|
};
|
|
19676
|
-
function walk2(d, m, s,
|
|
19681
|
+
function walk2(d, m, s, path28, container) {
|
|
19677
19682
|
for (const [key, value] of Object.entries(d)) {
|
|
19678
19683
|
if (DELTA_VERBS.has(key) || JUMP_LABEL_TWINS.has(key)) continue;
|
|
19679
19684
|
if (key === "label" && LABEL_TWIN_CONTAINERS.has(container)) continue;
|
|
@@ -19683,13 +19688,13 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
|
19683
19688
|
if (typeof name !== "string") continue;
|
|
19684
19689
|
const had = isPlain(s) && s[name] !== void 0;
|
|
19685
19690
|
const still = isPlain(m) && m[name] !== void 0;
|
|
19686
|
-
if (!had) say(at(
|
|
19687
|
-
else if (still) say(at(
|
|
19691
|
+
if (!had) say(at(path28, name), "unset named a field the stored spec did not have");
|
|
19692
|
+
else if (still) say(at(path28, name), "unset did not remove it");
|
|
19688
19693
|
}
|
|
19689
19694
|
continue;
|
|
19690
19695
|
}
|
|
19691
19696
|
if (value === void 0 || value === null) continue;
|
|
19692
|
-
const here = at(
|
|
19697
|
+
const here = at(path28, key);
|
|
19693
19698
|
const mValue = isPlain(m) ? m[key] : void 0;
|
|
19694
19699
|
const sValue = isPlain(s) ? s[key] : void 0;
|
|
19695
19700
|
if (mValue === void 0) {
|
|
@@ -19782,7 +19787,7 @@ function refusedMoveSummary(from, to, methods, refusals, alternatives) {
|
|
|
19782
19787
|
return `Refused: moving ${namedMethods(methods)} from "${from}" to "${to}" is refused by ${refusals.join(", ")}. Nothing was written. ` + (cheapest ? `The cheapest legal home is "${cheapest.component}" (${cheapest.newDependencies.length} new dependenc${cheapest.newDependencies.length === 1 ? "y" : "ies"}, ${cheapest.dependencyCount} of ${cheapest.dependencyLimit}).` : `No component of this subsystem can take them as they stand \u2014 ${alternatives.length} were weighed.`);
|
|
19783
19788
|
}
|
|
19784
19789
|
function workspaceFor(rootDir) {
|
|
19785
|
-
const key =
|
|
19790
|
+
const key = path17.resolve(rootDir);
|
|
19786
19791
|
let ws = workspaces.get(key);
|
|
19787
19792
|
if (!ws) {
|
|
19788
19793
|
ws = new SpecWorkspace(key);
|
|
@@ -19912,13 +19917,13 @@ function snapshotInputKey(snapshot) {
|
|
|
19912
19917
|
return canonicalize(content);
|
|
19913
19918
|
}
|
|
19914
19919
|
function consumedSurfaceInputsAt(rootDir) {
|
|
19915
|
-
const dir =
|
|
19920
|
+
const dir = path17.join(rootDir, ".wai", "surfaces");
|
|
19916
19921
|
if (!pathExists(dir)) return [];
|
|
19917
19922
|
const keys = [];
|
|
19918
|
-
for (const file of
|
|
19923
|
+
for (const file of fs12.readdirSync(dir)) {
|
|
19919
19924
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
19920
19925
|
try {
|
|
19921
|
-
keys.push(snapshotInputKey(SurfaceSnapshotSchema.parse(readYamlFile(
|
|
19926
|
+
keys.push(snapshotInputKey(SurfaceSnapshotSchema.parse(readYamlFile(path17.join(dir, file)))));
|
|
19922
19927
|
} catch {
|
|
19923
19928
|
}
|
|
19924
19929
|
}
|
|
@@ -19926,7 +19931,7 @@ function consumedSurfaceInputsAt(rootDir) {
|
|
|
19926
19931
|
}
|
|
19927
19932
|
function consumedContractInputs() {
|
|
19928
19933
|
const root = getProjectRoot();
|
|
19929
|
-
const roots = [root, ...listChainedRoots(root).map((rel2) =>
|
|
19934
|
+
const roots = [root, ...listChainedRoots(root).map((rel2) => path17.join(root, rel2))];
|
|
19930
19935
|
return roots.flatMap(consumedSurfaceInputsAt);
|
|
19931
19936
|
}
|
|
19932
19937
|
function readLockState(current2) {
|
|
@@ -19962,7 +19967,7 @@ function markSelectionsBundled(bundled) {
|
|
|
19962
19967
|
projectConfigRepository.markSelectionsBundled(bundled);
|
|
19963
19968
|
}
|
|
19964
19969
|
function computeStateIdAt(root) {
|
|
19965
|
-
const resolved =
|
|
19970
|
+
const resolved = path17.resolve(root);
|
|
19966
19971
|
return runWithProjectRoot(resolved, () => {
|
|
19967
19972
|
workspaceFor(resolved).invalidate();
|
|
19968
19973
|
const system = loadSystemSpec();
|
|
@@ -20000,7 +20005,7 @@ function snapshotSpecFiles() {
|
|
|
20000
20005
|
}
|
|
20001
20006
|
function restoreSpecFiles(snapshot) {
|
|
20002
20007
|
for (const [file, content] of snapshot) {
|
|
20003
|
-
|
|
20008
|
+
fs12.writeFileSync(file, content);
|
|
20004
20009
|
}
|
|
20005
20010
|
}
|
|
20006
20011
|
function findLegacySpecFiles() {
|
|
@@ -20012,12 +20017,12 @@ function updateSpec(kind, id, delta, hooks, dryRun) {
|
|
|
20012
20017
|
function moveMethods(from, to, methods, hooks, dryRun) {
|
|
20013
20018
|
return current().moveMethods(from, to, methods, hooks, dryRun);
|
|
20014
20019
|
}
|
|
20015
|
-
var
|
|
20020
|
+
var fs12, path17, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, COMPONENT_AUTH_SOURCE, DELTA_VERBS, JUMP_LABEL_TWINS, LABEL_TWIN_CONTAINERS, SpecWorkspace, DEFAULT_DEPENDENCY_LIMIT, PROSE_FIELDS, workspaces;
|
|
20016
20021
|
var init_specs2 = __esm({
|
|
20017
20022
|
"src/core/specs.ts"() {
|
|
20018
20023
|
"use strict";
|
|
20019
|
-
|
|
20020
|
-
|
|
20024
|
+
fs12 = __toESM(require("fs"));
|
|
20025
|
+
path17 = __toESM(require("path"));
|
|
20021
20026
|
init_loader();
|
|
20022
20027
|
init_project_config();
|
|
20023
20028
|
init_fs();
|
|
@@ -20052,7 +20057,7 @@ var init_specs2 = __esm({
|
|
|
20052
20057
|
this.rootSubsystems = /* @__PURE__ */ new Set();
|
|
20053
20058
|
this.scanVisitedSpecDirs = [];
|
|
20054
20059
|
this.loaderIssues = [];
|
|
20055
|
-
this.rootDir =
|
|
20060
|
+
this.rootDir = path17.resolve(rootDir);
|
|
20056
20061
|
this.paths = aiPathsAt(this.rootDir);
|
|
20057
20062
|
}
|
|
20058
20063
|
invalidate() {
|
|
@@ -20095,8 +20100,8 @@ var init_specs2 = __esm({
|
|
|
20095
20100
|
* qualifies the spec itself — so scoping a validate to a mount keeps it.
|
|
20096
20101
|
*/
|
|
20097
20102
|
loaderIssueSpecId(file, rawId, namespacePrefix) {
|
|
20098
|
-
const stem =
|
|
20099
|
-
const local = rawId ?? (stem.startsWith(".") ?
|
|
20103
|
+
const stem = path17.basename(file, ".yaml");
|
|
20104
|
+
const local = rawId ?? (stem.startsWith(".") ? path17.basename(path17.dirname(file)) : stem);
|
|
20100
20105
|
return namespacePrefix ? qualifyId(local, namespacePrefix, this.rootSubsystems) : local;
|
|
20101
20106
|
}
|
|
20102
20107
|
scanSpecsForProject(projectDir, namespacePrefix, visitedDirs, maxDepth, currentDepth) {
|
|
@@ -20106,10 +20111,10 @@ var init_specs2 = __esm({
|
|
|
20106
20111
|
this.scanVisitedSpecDirs.push(specsDir);
|
|
20107
20112
|
if (!pathExists(specsDir)) return index;
|
|
20108
20113
|
const files = listSpecFiles(specsDir);
|
|
20109
|
-
const systemYaml =
|
|
20114
|
+
const systemYaml = path17.normalize(projectPaths.specsSystem());
|
|
20110
20115
|
const localSubprojects = [];
|
|
20111
20116
|
for (const file of files) {
|
|
20112
|
-
const normFile =
|
|
20117
|
+
const normFile = path17.normalize(file);
|
|
20113
20118
|
if (normFile === systemYaml) continue;
|
|
20114
20119
|
let detectedType = "spec";
|
|
20115
20120
|
let rawId;
|
|
@@ -20153,7 +20158,7 @@ var init_specs2 = __esm({
|
|
|
20153
20158
|
} else if ("contract" in raw) {
|
|
20154
20159
|
detectedType = "implementation";
|
|
20155
20160
|
const parsed = ImplementationSpecSchema.parse(raw);
|
|
20156
|
-
const normalizeSourcePath = (p) =>
|
|
20161
|
+
const normalizeSourcePath = (p) => path17.relative(projectDir, path17.resolve(projectDir, p)).replace(/\\/g, "/");
|
|
20157
20162
|
if (parsed.sourcePath) parsed.sourcePath = normalizeSourcePath(parsed.sourcePath);
|
|
20158
20163
|
for (const method of parsed.methods) {
|
|
20159
20164
|
if (method.sourcePath) method.sourcePath = normalizeSourcePath(method.sourcePath);
|
|
@@ -20279,7 +20284,7 @@ var init_specs2 = __esm({
|
|
|
20279
20284
|
}
|
|
20280
20285
|
if (currentDepth < maxDepth) {
|
|
20281
20286
|
for (const subproj of localSubprojects) {
|
|
20282
|
-
const childDir =
|
|
20287
|
+
const childDir = path17.resolve(projectDir, subproj.projectPath);
|
|
20283
20288
|
const mountId = namespacePrefix ? qualifyDeclaredId(subproj.subsystemId, namespacePrefix, true) : subproj.subsystemId;
|
|
20284
20289
|
if (projectPathEscapesRoot(projectDir, subproj.projectPath, childDir)) {
|
|
20285
20290
|
this.loaderIssues.push({
|
|
@@ -20299,7 +20304,7 @@ var init_specs2 = __esm({
|
|
|
20299
20304
|
});
|
|
20300
20305
|
continue;
|
|
20301
20306
|
}
|
|
20302
|
-
if (!
|
|
20307
|
+
if (!fs12.existsSync(childDir)) {
|
|
20303
20308
|
this.loaderIssues.push({
|
|
20304
20309
|
severity: "error",
|
|
20305
20310
|
code: "SUBPROJECT_NOT_FOUND",
|
|
@@ -20342,7 +20347,7 @@ var init_specs2 = __esm({
|
|
|
20342
20347
|
const index = this.scanAll();
|
|
20343
20348
|
const sub = index.subsystems.find((s) => s.id === currentPrefix);
|
|
20344
20349
|
if (sub && sub.projectPath) {
|
|
20345
|
-
const nextDir =
|
|
20350
|
+
const nextDir = path17.resolve(currentDir, sub.projectPath);
|
|
20346
20351
|
if (projectPathEscapesRoot(currentDir, sub.projectPath, nextDir)) {
|
|
20347
20352
|
this.loaderIssues.push({
|
|
20348
20353
|
severity: "error",
|
|
@@ -20394,9 +20399,9 @@ var init_specs2 = __esm({
|
|
|
20394
20399
|
return index.paths.subsystem[matches[0]];
|
|
20395
20400
|
}
|
|
20396
20401
|
if (pathExists(this.paths.specsSubsystemsDir()) && listFiles(this.paths.specsSubsystemsDir(), ".yaml").length > 0) {
|
|
20397
|
-
return
|
|
20402
|
+
return path17.join(this.paths.specsSubsystemsDir(), `${id}.yaml`);
|
|
20398
20403
|
}
|
|
20399
|
-
return
|
|
20404
|
+
return path17.join(this.paths.specsDir(), id, ".index.yaml");
|
|
20400
20405
|
}
|
|
20401
20406
|
getComponentPath(id, subsystemId) {
|
|
20402
20407
|
const index = this.scanAll();
|
|
@@ -20416,21 +20421,21 @@ var init_specs2 = __esm({
|
|
|
20416
20421
|
if (owner) {
|
|
20417
20422
|
const ownerPath = index.paths.component[owner.id];
|
|
20418
20423
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
20419
|
-
return
|
|
20424
|
+
return path17.join(path17.dirname(ownerPath), id, ".index.yaml");
|
|
20420
20425
|
}
|
|
20421
20426
|
}
|
|
20422
20427
|
if (subsystemId) {
|
|
20423
20428
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
20424
|
-
const subDir =
|
|
20429
|
+
const subDir = path17.dirname(subPath);
|
|
20425
20430
|
if (subPath.endsWith(".index.yaml")) {
|
|
20426
|
-
return
|
|
20431
|
+
return path17.join(subDir, id, ".index.yaml");
|
|
20427
20432
|
}
|
|
20428
20433
|
}
|
|
20429
20434
|
if (pathExists(this.paths.specsComponentsDir()) && listFiles(this.paths.specsComponentsDir(), ".yaml").length > 0) {
|
|
20430
|
-
return
|
|
20435
|
+
return path17.join(this.paths.specsComponentsDir(), `${id}.yaml`);
|
|
20431
20436
|
}
|
|
20432
20437
|
const targetSubsystem = subsystemId || "default";
|
|
20433
|
-
return
|
|
20438
|
+
return path17.join(this.paths.specsDir(), targetSubsystem, id, ".index.yaml");
|
|
20434
20439
|
}
|
|
20435
20440
|
getInterfacePath(id, componentId) {
|
|
20436
20441
|
const index = this.scanAll();
|
|
@@ -20456,16 +20461,16 @@ var init_specs2 = __esm({
|
|
|
20456
20461
|
}
|
|
20457
20462
|
if (componentId) {
|
|
20458
20463
|
const compPath = this.getComponentPath(componentId);
|
|
20459
|
-
const compDir =
|
|
20464
|
+
const compDir = path17.dirname(compPath);
|
|
20460
20465
|
if (compPath.endsWith(".index.yaml")) {
|
|
20461
|
-
return
|
|
20466
|
+
return path17.join(compDir, ".interface.yaml");
|
|
20462
20467
|
}
|
|
20463
20468
|
}
|
|
20464
20469
|
if (pathExists(this.paths.specsInterfacesDir()) && listFiles(this.paths.specsInterfacesDir(), ".yaml").length > 0) {
|
|
20465
|
-
return
|
|
20470
|
+
return path17.join(this.paths.specsInterfacesDir(), `${id}.yaml`);
|
|
20466
20471
|
}
|
|
20467
20472
|
const targetComponent = componentId || "default";
|
|
20468
|
-
return
|
|
20473
|
+
return path17.join(this.paths.specsDir(), "default", targetComponent, ".interface.yaml");
|
|
20469
20474
|
}
|
|
20470
20475
|
getImplementationPath(id, contractId) {
|
|
20471
20476
|
const index = this.scanAll();
|
|
@@ -20491,16 +20496,16 @@ var init_specs2 = __esm({
|
|
|
20491
20496
|
}
|
|
20492
20497
|
if (contractId) {
|
|
20493
20498
|
const intfPath = this.getInterfacePath(contractId);
|
|
20494
|
-
const intfDir =
|
|
20499
|
+
const intfDir = path17.dirname(intfPath);
|
|
20495
20500
|
if (intfPath.endsWith(".interface.yaml")) {
|
|
20496
|
-
return
|
|
20501
|
+
return path17.join(intfDir, ".implementation.yaml");
|
|
20497
20502
|
}
|
|
20498
20503
|
}
|
|
20499
20504
|
if (pathExists(this.paths.specsImplementationsDir()) && listFiles(this.paths.specsImplementationsDir(), ".yaml").length > 0) {
|
|
20500
|
-
return
|
|
20505
|
+
return path17.join(this.paths.specsImplementationsDir(), `${id}.yaml`);
|
|
20501
20506
|
}
|
|
20502
20507
|
const targetContract = contractId ? contractId.replace(/^i/, "") : "default";
|
|
20503
|
-
return
|
|
20508
|
+
return path17.join(this.paths.specsDir(), "default", targetContract, ".implementation.yaml");
|
|
20504
20509
|
}
|
|
20505
20510
|
getTypePath(id, subsystemId, group) {
|
|
20506
20511
|
const index = this.scanAll();
|
|
@@ -20531,7 +20536,7 @@ var init_specs2 = __esm({
|
|
|
20531
20536
|
const groupPath = index.paths.group[targetGroup] || index.paths.group[plainGroup];
|
|
20532
20537
|
if (groupPath) {
|
|
20533
20538
|
const localId2 = id.split("::").pop();
|
|
20534
|
-
return
|
|
20539
|
+
return path17.join(path17.dirname(groupPath), `${localId2}.yaml`);
|
|
20535
20540
|
}
|
|
20536
20541
|
}
|
|
20537
20542
|
let localId = id;
|
|
@@ -20544,12 +20549,12 @@ var init_specs2 = __esm({
|
|
|
20544
20549
|
}
|
|
20545
20550
|
if (subsystemId) {
|
|
20546
20551
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
20547
|
-
const subDir =
|
|
20552
|
+
const subDir = path17.dirname(subPath);
|
|
20548
20553
|
if (subPath.endsWith(".index.yaml")) {
|
|
20549
|
-
return
|
|
20554
|
+
return path17.join(subDir, "types", `${localId}.yaml`);
|
|
20550
20555
|
}
|
|
20551
20556
|
}
|
|
20552
|
-
return
|
|
20557
|
+
return path17.join(this.paths.specsTypesDir(), `${localId}.yaml`);
|
|
20553
20558
|
}
|
|
20554
20559
|
getGroupPath(id, subsystemId) {
|
|
20555
20560
|
const index = this.scanAll();
|
|
@@ -20583,12 +20588,12 @@ var init_specs2 = __esm({
|
|
|
20583
20588
|
}
|
|
20584
20589
|
if (subsystemId) {
|
|
20585
20590
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
20586
|
-
const subDir =
|
|
20591
|
+
const subDir = path17.dirname(subPath);
|
|
20587
20592
|
if (subPath.endsWith(".index.yaml")) {
|
|
20588
|
-
return
|
|
20593
|
+
return path17.join(subDir, "types", localId, ".index.yaml");
|
|
20589
20594
|
}
|
|
20590
20595
|
}
|
|
20591
|
-
return
|
|
20596
|
+
return path17.join(this.paths.specsTypesDir(), localId, ".index.yaml");
|
|
20592
20597
|
}
|
|
20593
20598
|
// -------------------------------------------------------------------------
|
|
20594
20599
|
// Level 0: System
|
|
@@ -20611,7 +20616,7 @@ var init_specs2 = __esm({
|
|
|
20611
20616
|
}
|
|
20612
20617
|
saveSystemSpec(spec) {
|
|
20613
20618
|
const p = this.paths.specsSystem();
|
|
20614
|
-
ensureDir(
|
|
20619
|
+
ensureDir(path17.dirname(p));
|
|
20615
20620
|
writeSpecFile(p, parseOrThrow(SystemSpecSchema, spec, "system", spec.name));
|
|
20616
20621
|
invalidateSpecCache();
|
|
20617
20622
|
}
|
|
@@ -20733,7 +20738,7 @@ var init_specs2 = __esm({
|
|
|
20733
20738
|
}
|
|
20734
20739
|
saveSubsystemSpec(spec, opts) {
|
|
20735
20740
|
const p = this.getSubsystemPath(spec.id);
|
|
20736
|
-
ensureDir(
|
|
20741
|
+
ensureDir(path17.dirname(p));
|
|
20737
20742
|
const { prefix } = splitNamespace(spec.id);
|
|
20738
20743
|
if (!prefix && spec.projectPath && spec.projectPath.trim() !== "") {
|
|
20739
20744
|
assertContainedProjectPath(this.rootDir, spec.projectPath);
|
|
@@ -20767,9 +20772,7 @@ var init_specs2 = __esm({
|
|
|
20767
20772
|
}
|
|
20768
20773
|
deleteSubsystemSpec(id) {
|
|
20769
20774
|
const p = this.getSubsystemPath(id);
|
|
20770
|
-
if (!
|
|
20771
|
-
fs11.unlinkSync(p);
|
|
20772
|
-
cleanEmptyDirs(p, path16.resolve(this.paths.specsDir()));
|
|
20775
|
+
if (!removeSpecFile(p, this.paths.specsDir())) return false;
|
|
20773
20776
|
invalidateSpecCache();
|
|
20774
20777
|
return true;
|
|
20775
20778
|
}
|
|
@@ -20802,7 +20805,7 @@ var init_specs2 = __esm({
|
|
|
20802
20805
|
saveComponentSpec(spec, opts) {
|
|
20803
20806
|
const notices = [];
|
|
20804
20807
|
const p = this.getComponentPath(spec.id, spec.subsystem);
|
|
20805
|
-
ensureDir(
|
|
20808
|
+
ensureDir(path17.dirname(p));
|
|
20806
20809
|
const specToWrite = this.prepareComponentForWrite(spec);
|
|
20807
20810
|
const existing = this.loadComponentSpec(spec.id);
|
|
20808
20811
|
if (existing) {
|
|
@@ -20819,7 +20822,7 @@ var init_specs2 = __esm({
|
|
|
20819
20822
|
const subsystemChanged = existing && existing.subsystem !== spec.subsystem && splitNamespace(existing.subsystem).localId !== splitNamespace(spec.subsystem).localId;
|
|
20820
20823
|
if (subsystemChanged && !p.endsWith(".index.yaml")) {
|
|
20821
20824
|
notices.push(
|
|
20822
|
-
`component "${spec.id}" already exists at ${
|
|
20825
|
+
`component "${spec.id}" already exists at ${path17.relative(this.rootDir, p)} \u2014 the flat layout re-saves in place and never relocates the file. The subsystem field is now "${spec.subsystem}" (was "${existing.subsystem}").`
|
|
20823
20826
|
);
|
|
20824
20827
|
}
|
|
20825
20828
|
specToWrite.updatedAt = opts?.preserveUpdatedAt && existing?.updatedAt ? existing.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -20830,9 +20833,7 @@ var init_specs2 = __esm({
|
|
|
20830
20833
|
}
|
|
20831
20834
|
deleteComponentSpec(id) {
|
|
20832
20835
|
const p = this.getComponentPath(id);
|
|
20833
|
-
if (!
|
|
20834
|
-
fs11.unlinkSync(p);
|
|
20835
|
-
cleanEmptyDirs(p, path16.resolve(this.paths.specsDir()));
|
|
20836
|
+
if (!removeSpecFile(p, this.paths.specsDir())) return false;
|
|
20836
20837
|
invalidateSpecCache();
|
|
20837
20838
|
return true;
|
|
20838
20839
|
}
|
|
@@ -20845,12 +20846,12 @@ var init_specs2 = __esm({
|
|
|
20845
20846
|
if (owner) {
|
|
20846
20847
|
const ownerPath = index.paths.component[owner.id];
|
|
20847
20848
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
20848
|
-
const ownerSubDir =
|
|
20849
|
-
return
|
|
20849
|
+
const ownerSubDir = path17.dirname(this.getSubsystemPath(owner.subsystem));
|
|
20850
|
+
return path17.join(ownerSubDir, owner.id, comp.id);
|
|
20850
20851
|
}
|
|
20851
20852
|
}
|
|
20852
|
-
const subDir =
|
|
20853
|
-
return
|
|
20853
|
+
const subDir = path17.dirname(this.getSubsystemPath(comp.subsystem));
|
|
20854
|
+
return path17.join(subDir, comp.id);
|
|
20854
20855
|
}
|
|
20855
20856
|
/**
|
|
20856
20857
|
* Move component folders so the physical tree mirrors ownership: each owned
|
|
@@ -20866,7 +20867,7 @@ var init_specs2 = __esm({
|
|
|
20866
20867
|
if (!currentPath) continue;
|
|
20867
20868
|
const desiredDir = this.desiredComponentDir(comp, index);
|
|
20868
20869
|
if (!desiredDir) continue;
|
|
20869
|
-
if (moveComponentFolder(
|
|
20870
|
+
if (moveComponentFolder(path17.dirname(currentPath), desiredDir)) moved.push(comp.id);
|
|
20870
20871
|
}
|
|
20871
20872
|
if (moved.length) invalidateSpecCache();
|
|
20872
20873
|
return moved;
|
|
@@ -20922,7 +20923,7 @@ var init_specs2 = __esm({
|
|
|
20922
20923
|
if (!occupantId) return;
|
|
20923
20924
|
if (occupantId === id || splitNamespace(occupantId).localId === splitNamespace(id).localId) return;
|
|
20924
20925
|
throw new Error(
|
|
20925
|
-
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${
|
|
20926
|
+
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${path17.relative(this.rootDir, p)}, and both ids resolve to that one file. Re-author "${occupantId}" instead, or delete it first if you meant to replace it.`
|
|
20926
20927
|
);
|
|
20927
20928
|
}
|
|
20928
20929
|
/** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */
|
|
@@ -20930,12 +20931,12 @@ var init_specs2 = __esm({
|
|
|
20930
20931
|
const notices = [];
|
|
20931
20932
|
const p = this.getInterfacePath(spec.id, spec.component);
|
|
20932
20933
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "interface", `component "${spec.component}"`);
|
|
20933
|
-
ensureDir(
|
|
20934
|
+
ensureDir(path17.dirname(p));
|
|
20934
20935
|
const specToWrite = this.prepareInterfaceForWrite(spec);
|
|
20935
20936
|
const existing = this.loadInterfaceSpec(spec.id);
|
|
20936
20937
|
if (existing && existing.component !== spec.component && splitNamespace(existing.component).localId !== splitNamespace(spec.component).localId) {
|
|
20937
20938
|
notices.push(
|
|
20938
|
-
`interface "${spec.id}" already exists at ${
|
|
20939
|
+
`interface "${spec.id}" already exists at ${path17.relative(this.rootDir, p)} \u2014 re-saving updates the component binding field in place (now "${spec.component}", was "${existing.component}") and never moves the file.`
|
|
20939
20940
|
);
|
|
20940
20941
|
}
|
|
20941
20942
|
if (existing) {
|
|
@@ -20958,9 +20959,7 @@ var init_specs2 = __esm({
|
|
|
20958
20959
|
}
|
|
20959
20960
|
deleteInterfaceSpec(id) {
|
|
20960
20961
|
const p = this.getInterfacePath(id);
|
|
20961
|
-
if (!
|
|
20962
|
-
fs11.unlinkSync(p);
|
|
20963
|
-
cleanEmptyDirs(p, path16.resolve(this.paths.specsDir()));
|
|
20962
|
+
if (!removeSpecFile(p, this.paths.specsDir())) return false;
|
|
20964
20963
|
invalidateSpecCache();
|
|
20965
20964
|
return true;
|
|
20966
20965
|
}
|
|
@@ -20994,12 +20993,12 @@ var init_specs2 = __esm({
|
|
|
20994
20993
|
const notices = [];
|
|
20995
20994
|
const p = this.getImplementationPath(spec.id, spec.contract);
|
|
20996
20995
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "implementation", `contract "${spec.contract}"`);
|
|
20997
|
-
ensureDir(
|
|
20996
|
+
ensureDir(path17.dirname(p));
|
|
20998
20997
|
const specToWrite = this.prepareImplementationForWrite(spec);
|
|
20999
20998
|
const existing = this.loadImplementationSpec(spec.id);
|
|
21000
20999
|
if (existing && existing.contract !== spec.contract && splitNamespace(existing.contract).localId !== splitNamespace(spec.contract).localId) {
|
|
21001
21000
|
notices.push(
|
|
21002
|
-
`implementation "${spec.id}" already exists at ${
|
|
21001
|
+
`implementation "${spec.id}" already exists at ${path17.relative(this.rootDir, p)} \u2014 re-saving updates the contract binding field in place (now "${spec.contract}", was "${existing.contract}") and never moves the file.`
|
|
21003
21002
|
);
|
|
21004
21003
|
}
|
|
21005
21004
|
if (existing) {
|
|
@@ -21015,9 +21014,7 @@ var init_specs2 = __esm({
|
|
|
21015
21014
|
}
|
|
21016
21015
|
deleteImplementationSpec(id) {
|
|
21017
21016
|
const p = this.getImplementationPath(id);
|
|
21018
|
-
if (!
|
|
21019
|
-
fs11.unlinkSync(p);
|
|
21020
|
-
cleanEmptyDirs(p, path16.resolve(this.paths.specsDir()));
|
|
21017
|
+
if (!removeSpecFile(p, this.paths.specsDir())) return false;
|
|
21021
21018
|
invalidateSpecCache();
|
|
21022
21019
|
return true;
|
|
21023
21020
|
}
|
|
@@ -21042,11 +21039,11 @@ var init_specs2 = __esm({
|
|
|
21042
21039
|
const existing = this.loadTypeSpec(spec.id);
|
|
21043
21040
|
const group = spec.group || (existing ? existing.group : void 0);
|
|
21044
21041
|
const p = this.getTypePath(spec.id, spec.subsystem, group);
|
|
21045
|
-
ensureDir(
|
|
21042
|
+
ensureDir(path17.dirname(p));
|
|
21046
21043
|
const subsystemChanged = existing && (existing.subsystem ?? "") !== (spec.subsystem ?? "") && splitNamespace(existing.subsystem ?? "").localId !== splitNamespace(spec.subsystem ?? "").localId;
|
|
21047
21044
|
if (subsystemChanged) {
|
|
21048
21045
|
notices.push(
|
|
21049
|
-
`type "${spec.id}" already exists at ${
|
|
21046
|
+
`type "${spec.id}" already exists at ${path17.relative(this.rootDir, p)} \u2014 re-saving updates fields in place and never relocates the file. The subsystem field is now "${spec.subsystem ?? "(none)"}" (was "${existing.subsystem ?? "(none)"}").`
|
|
21050
21047
|
);
|
|
21051
21048
|
}
|
|
21052
21049
|
if (spec.subsystem && (!existing || subsystemChanged) && !this.getSubsystemPath(spec.subsystem).endsWith(".index.yaml")) {
|
|
@@ -21069,9 +21066,7 @@ var init_specs2 = __esm({
|
|
|
21069
21066
|
deleteTypeSpec(id) {
|
|
21070
21067
|
const spec = this.loadTypeSpec(id);
|
|
21071
21068
|
const p = this.getTypePath(id, spec?.subsystem, spec?.group);
|
|
21072
|
-
if (!
|
|
21073
|
-
fs11.unlinkSync(p);
|
|
21074
|
-
cleanEmptyDirs(p, path16.resolve(this.paths.specsDir()));
|
|
21069
|
+
if (!removeSpecFile(p, this.paths.specsDir())) return false;
|
|
21075
21070
|
invalidateSpecCache();
|
|
21076
21071
|
return true;
|
|
21077
21072
|
}
|
|
@@ -21086,7 +21081,7 @@ var init_specs2 = __esm({
|
|
|
21086
21081
|
}
|
|
21087
21082
|
saveGroupSpec(spec, opts) {
|
|
21088
21083
|
const p = this.getGroupPath(spec.id);
|
|
21089
|
-
ensureDir(
|
|
21084
|
+
ensureDir(path17.dirname(p));
|
|
21090
21085
|
const specToWrite = this.prepareGroupForWrite(spec);
|
|
21091
21086
|
const existing = this.loadGroupSpec(spec.id);
|
|
21092
21087
|
if (existing) {
|
|
@@ -21098,9 +21093,7 @@ var init_specs2 = __esm({
|
|
|
21098
21093
|
}
|
|
21099
21094
|
deleteGroupSpec(id) {
|
|
21100
21095
|
const p = this.getGroupPath(id);
|
|
21101
|
-
if (!
|
|
21102
|
-
fs11.unlinkSync(p);
|
|
21103
|
-
cleanEmptyDirs(p, path16.resolve(this.paths.specsDir()));
|
|
21096
|
+
if (!removeSpecFile(p, this.paths.specsDir())) return false;
|
|
21104
21097
|
invalidateSpecCache();
|
|
21105
21098
|
return true;
|
|
21106
21099
|
}
|
|
@@ -21166,7 +21159,7 @@ var init_specs2 = __esm({
|
|
|
21166
21159
|
};
|
|
21167
21160
|
const out = /* @__PURE__ */ new Set();
|
|
21168
21161
|
const add = (p) => {
|
|
21169
|
-
if (p) out.add(
|
|
21162
|
+
if (p) out.add(path17.resolve(p));
|
|
21170
21163
|
};
|
|
21171
21164
|
for (const s of this.loadSubsystemSpecs()) {
|
|
21172
21165
|
if (!scopeSubsystem || s.id === scopeSubsystem || s.id.startsWith(`${scopeSubsystem}::`)) {
|
|
@@ -21237,16 +21230,16 @@ var init_specs2 = __esm({
|
|
|
21237
21230
|
const files = /* @__PURE__ */ new Set();
|
|
21238
21231
|
const sysPath = this.paths.specsSystem();
|
|
21239
21232
|
if (pathExists(sysPath)) {
|
|
21240
|
-
files.add(
|
|
21233
|
+
files.add(path17.resolve(sysPath));
|
|
21241
21234
|
}
|
|
21242
21235
|
for (const group of Object.values(index.paths)) {
|
|
21243
21236
|
for (const file of Object.values(group)) {
|
|
21244
|
-
files.add(
|
|
21237
|
+
files.add(path17.resolve(file));
|
|
21245
21238
|
}
|
|
21246
21239
|
}
|
|
21247
21240
|
for (const file of files) {
|
|
21248
|
-
if (
|
|
21249
|
-
snapshot.set(file,
|
|
21241
|
+
if (fs12.existsSync(file)) {
|
|
21242
|
+
snapshot.set(file, fs12.readFileSync(file, "utf8"));
|
|
21250
21243
|
}
|
|
21251
21244
|
}
|
|
21252
21245
|
return snapshot;
|
|
@@ -21260,20 +21253,20 @@ var init_specs2 = __esm({
|
|
|
21260
21253
|
const files = listSpecFiles(specsDir);
|
|
21261
21254
|
const legacy = [];
|
|
21262
21255
|
for (const f of files) {
|
|
21263
|
-
const base =
|
|
21264
|
-
const dir =
|
|
21256
|
+
const base = path17.basename(f);
|
|
21257
|
+
const dir = path17.dirname(f);
|
|
21265
21258
|
if (base === "system.yaml") {
|
|
21266
|
-
legacy.push({ path: f, expected:
|
|
21259
|
+
legacy.push({ path: f, expected: path17.join(dir, ".index.yaml") });
|
|
21267
21260
|
} else if (base === "subsystem.yaml") {
|
|
21268
|
-
legacy.push({ path: f, expected:
|
|
21261
|
+
legacy.push({ path: f, expected: path17.join(dir, ".index.yaml") });
|
|
21269
21262
|
} else if (base === "component.yaml") {
|
|
21270
|
-
legacy.push({ path: f, expected:
|
|
21263
|
+
legacy.push({ path: f, expected: path17.join(dir, ".index.yaml") });
|
|
21271
21264
|
} else if (base === "group.yaml") {
|
|
21272
|
-
legacy.push({ path: f, expected:
|
|
21265
|
+
legacy.push({ path: f, expected: path17.join(dir, ".index.yaml") });
|
|
21273
21266
|
} else if (base === "interface.yaml") {
|
|
21274
|
-
legacy.push({ path: f, expected:
|
|
21267
|
+
legacy.push({ path: f, expected: path17.join(dir, ".interface.yaml") });
|
|
21275
21268
|
} else if (base === "implementation.yaml") {
|
|
21276
|
-
legacy.push({ path: f, expected:
|
|
21269
|
+
legacy.push({ path: f, expected: path17.join(dir, ".implementation.yaml") });
|
|
21277
21270
|
}
|
|
21278
21271
|
}
|
|
21279
21272
|
return legacy;
|
|
@@ -22284,8 +22277,8 @@ __export(agent_resolver_exports, {
|
|
|
22284
22277
|
resolveAgentTopology: () => resolveAgentTopology
|
|
22285
22278
|
});
|
|
22286
22279
|
function listFilesRecursiveSafe(dirPath, ext) {
|
|
22287
|
-
if (!
|
|
22288
|
-
const nameLower =
|
|
22280
|
+
if (!fs13.existsSync(dirPath)) return [];
|
|
22281
|
+
const nameLower = path18.basename(dirPath).toLowerCase();
|
|
22289
22282
|
const IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
22290
22283
|
"node_modules",
|
|
22291
22284
|
"target",
|
|
@@ -22300,10 +22293,10 @@ function listFilesRecursiveSafe(dirPath, ext) {
|
|
|
22300
22293
|
".vscode"
|
|
22301
22294
|
]);
|
|
22302
22295
|
if (IGNORED_DIRS.has(nameLower)) return [];
|
|
22303
|
-
const entries =
|
|
22296
|
+
const entries = fs13.readdirSync(dirPath, { withFileTypes: true });
|
|
22304
22297
|
const files = [];
|
|
22305
22298
|
for (const entry of entries) {
|
|
22306
|
-
const fullPath =
|
|
22299
|
+
const fullPath = path18.join(dirPath, entry.name);
|
|
22307
22300
|
if (entry.isDirectory()) {
|
|
22308
22301
|
files.push(...listFilesRecursiveSafe(fullPath, ext));
|
|
22309
22302
|
} else if (entry.isFile() && entry.name.endsWith(ext)) {
|
|
@@ -22316,8 +22309,8 @@ function getProjectFiles(projectDir) {
|
|
|
22316
22309
|
let files = projectFilesCache.get(projectDir);
|
|
22317
22310
|
if (!files) {
|
|
22318
22311
|
files = [];
|
|
22319
|
-
const srcDir =
|
|
22320
|
-
const legacySrcDir =
|
|
22312
|
+
const srcDir = path18.join(projectDir, "src");
|
|
22313
|
+
const legacySrcDir = path18.join(projectDir, "legacy-src");
|
|
22321
22314
|
let searchDir = projectDir;
|
|
22322
22315
|
if (pathExists(srcDir)) {
|
|
22323
22316
|
searchDir = srcDir;
|
|
@@ -22332,7 +22325,7 @@ function getProjectFiles(projectDir) {
|
|
|
22332
22325
|
files.push(...listFilesRecursiveSafe(searchDir, ext));
|
|
22333
22326
|
}
|
|
22334
22327
|
const rootDir = getProjectRoot();
|
|
22335
|
-
files = files.map((f) =>
|
|
22328
|
+
files = files.map((f) => path18.relative(rootDir, f).replace(/\\/g, "/"));
|
|
22336
22329
|
projectFilesCache.set(projectDir, files);
|
|
22337
22330
|
}
|
|
22338
22331
|
return files;
|
|
@@ -22357,8 +22350,8 @@ function inferSourcePathForComponent(comp, subsystems) {
|
|
|
22357
22350
|
let bestFile = null;
|
|
22358
22351
|
let bestScore = -1;
|
|
22359
22352
|
for (const f of files) {
|
|
22360
|
-
const ext =
|
|
22361
|
-
const base =
|
|
22353
|
+
const ext = path18.extname(f);
|
|
22354
|
+
const base = path18.basename(f, ext).toLowerCase();
|
|
22362
22355
|
if (candidates.has(base)) {
|
|
22363
22356
|
let score = 0;
|
|
22364
22357
|
const normalizedPath = f.toLowerCase();
|
|
@@ -22455,7 +22448,7 @@ function resolveAgentTopology() {
|
|
|
22455
22448
|
});
|
|
22456
22449
|
for (const sub of subsystems) {
|
|
22457
22450
|
if (sub.projectPath) {
|
|
22458
|
-
const mountSpecPath =
|
|
22451
|
+
const mountSpecPath = path18.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/");
|
|
22459
22452
|
agents.push({
|
|
22460
22453
|
id: `${sub.id}-owner`,
|
|
22461
22454
|
name: `${sub.name} (chained subproject)`,
|
|
@@ -22477,9 +22470,9 @@ function resolveAgentTopology() {
|
|
|
22477
22470
|
}
|
|
22478
22471
|
const subComponents = components.filter((c) => c.subsystem === sub.id);
|
|
22479
22472
|
const ownedPaths = [];
|
|
22480
|
-
ownedPaths.push(
|
|
22473
|
+
ownedPaths.push(path18.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/"));
|
|
22481
22474
|
for (const c of subComponents) {
|
|
22482
|
-
ownedPaths.push(
|
|
22475
|
+
ownedPaths.push(path18.relative(getProjectRoot(), getComponentPath(c.id, sub.id)).replace(/\\/g, "/"));
|
|
22483
22476
|
}
|
|
22484
22477
|
if (!config.rules.generateComponentImplementers) {
|
|
22485
22478
|
for (const comp of subComponents) {
|
|
@@ -22555,10 +22548,10 @@ function resolveAgentTopology() {
|
|
|
22555
22548
|
}
|
|
22556
22549
|
const dependencies = comp.dependsOn.map((depId) => `${depId}-implementer`);
|
|
22557
22550
|
const readPaths = [
|
|
22558
|
-
|
|
22559
|
-
|
|
22560
|
-
...compInterfaces.map((i) =>
|
|
22561
|
-
...compImpls.map((impl) =>
|
|
22551
|
+
path18.relative(getProjectRoot(), AI_PATHS.specsSystem()).replace(/\\/g, "/"),
|
|
22552
|
+
path18.relative(getProjectRoot(), getComponentPath(comp.id, comp.subsystem)).replace(/\\/g, "/"),
|
|
22553
|
+
...compInterfaces.map((i) => path18.relative(getProjectRoot(), getInterfacePath(i.id, comp.id)).replace(/\\/g, "/")),
|
|
22554
|
+
...compImpls.map((impl) => path18.relative(getProjectRoot(), getImplementationPath(impl.id, impl.contract)).replace(/\\/g, "/"))
|
|
22562
22555
|
];
|
|
22563
22556
|
agents.push({
|
|
22564
22557
|
id: `${comp.id}-implementer`,
|
|
@@ -22647,12 +22640,12 @@ ${guidance.trim()}
|
|
|
22647
22640
|
budget
|
|
22648
22641
|
};
|
|
22649
22642
|
}
|
|
22650
|
-
var
|
|
22643
|
+
var path18, fs13, projectFilesCache, UnknownAgentError;
|
|
22651
22644
|
var init_agent_resolver = __esm({
|
|
22652
22645
|
"src/core/agent_resolver.ts"() {
|
|
22653
22646
|
"use strict";
|
|
22654
|
-
|
|
22655
|
-
|
|
22647
|
+
path18 = __toESM(require("path"));
|
|
22648
|
+
fs13 = __toESM(require("fs"));
|
|
22656
22649
|
init_loader();
|
|
22657
22650
|
init_project_config();
|
|
22658
22651
|
init_fs();
|
|
@@ -22675,12 +22668,12 @@ var init_agent_resolver = __esm({
|
|
|
22675
22668
|
|
|
22676
22669
|
// src/config/loader.ts
|
|
22677
22670
|
function aiPathsAt(rootDir) {
|
|
22678
|
-
const resolvedRoot =
|
|
22671
|
+
const resolvedRoot = path19.resolve(rootDir);
|
|
22679
22672
|
const aiDirAt2 = (...segments) => {
|
|
22680
|
-
const waiPath =
|
|
22681
|
-
const waironPath =
|
|
22682
|
-
const base = !
|
|
22683
|
-
return
|
|
22673
|
+
const waiPath = path19.join(resolvedRoot, ".wai");
|
|
22674
|
+
const waironPath = path19.join(resolvedRoot, ".wairon");
|
|
22675
|
+
const base = !fs14.existsSync(waiPath) && fs14.existsSync(waironPath) ? waironPath : waiPath;
|
|
22676
|
+
return path19.join(base, ...segments);
|
|
22684
22677
|
};
|
|
22685
22678
|
const specsDir = () => projectConfigRepositoryAt(resolvedRoot).specsDir();
|
|
22686
22679
|
return {
|
|
@@ -22697,12 +22690,12 @@ function aiPathsAt(rootDir) {
|
|
|
22697
22690
|
contextDomainsMd: () => aiDirAt2("context", "domains.md"),
|
|
22698
22691
|
contextWaironGuideMd: () => aiDirAt2("context", "wairon-guide.md"),
|
|
22699
22692
|
specsDir,
|
|
22700
|
-
specsSystem: () =>
|
|
22701
|
-
specsSubsystemsDir: () =>
|
|
22702
|
-
specsComponentsDir: () =>
|
|
22703
|
-
specsInterfacesDir: () =>
|
|
22704
|
-
specsImplementationsDir: () =>
|
|
22705
|
-
specsTypesDir: () =>
|
|
22693
|
+
specsSystem: () => path19.join(specsDir(), ".index.yaml"),
|
|
22694
|
+
specsSubsystemsDir: () => path19.join(specsDir(), "subsystems"),
|
|
22695
|
+
specsComponentsDir: () => path19.join(specsDir(), "components"),
|
|
22696
|
+
specsInterfacesDir: () => path19.join(specsDir(), "interfaces"),
|
|
22697
|
+
specsImplementationsDir: () => path19.join(specsDir(), "implementations"),
|
|
22698
|
+
specsTypesDir: () => path19.join(specsDir(), "types")
|
|
22706
22699
|
};
|
|
22707
22700
|
}
|
|
22708
22701
|
function isProjectInitialized() {
|
|
@@ -22733,12 +22726,12 @@ function loadTopologyConfig() {
|
|
|
22733
22726
|
function saveTopologyConfig(config) {
|
|
22734
22727
|
writeYamlFile(AI_PATHS.topologyConfig(), config);
|
|
22735
22728
|
}
|
|
22736
|
-
var
|
|
22729
|
+
var fs14, path19, AI_PATHS;
|
|
22737
22730
|
var init_loader = __esm({
|
|
22738
22731
|
"src/config/loader.ts"() {
|
|
22739
22732
|
"use strict";
|
|
22740
|
-
|
|
22741
|
-
|
|
22733
|
+
fs14 = __toESM(require("fs"));
|
|
22734
|
+
path19 = __toESM(require("path"));
|
|
22742
22735
|
init_fs();
|
|
22743
22736
|
init_yaml();
|
|
22744
22737
|
init_errors();
|
|
@@ -22779,7 +22772,7 @@ __export(domains_exports, {
|
|
|
22779
22772
|
resolveDomains: () => resolveDomains
|
|
22780
22773
|
});
|
|
22781
22774
|
function rel(p) {
|
|
22782
|
-
return
|
|
22775
|
+
return path20.relative(process.cwd(), p).replace(/\\/g, "/");
|
|
22783
22776
|
}
|
|
22784
22777
|
function deriveSubsystemDomains() {
|
|
22785
22778
|
const subsystems = loadSubsystemSpecs();
|
|
@@ -22829,11 +22822,11 @@ function removeFreeStandingDomain(id) {
|
|
|
22829
22822
|
config.domains.splice(idx, 1);
|
|
22830
22823
|
saveTopologyConfig(config);
|
|
22831
22824
|
}
|
|
22832
|
-
var
|
|
22825
|
+
var path20;
|
|
22833
22826
|
var init_domains = __esm({
|
|
22834
22827
|
"src/core/domains.ts"() {
|
|
22835
22828
|
"use strict";
|
|
22836
|
-
|
|
22829
|
+
path20 = __toESM(require("path"));
|
|
22837
22830
|
init_loader();
|
|
22838
22831
|
init_specs2();
|
|
22839
22832
|
init_errors();
|
|
@@ -22888,7 +22881,7 @@ function provisionProject(name) {
|
|
|
22888
22881
|
function ensureProjectInitialized(fallbackName) {
|
|
22889
22882
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
22890
22883
|
const paths = aiPathsAt(getProjectRoot());
|
|
22891
|
-
const hasSystem =
|
|
22884
|
+
const hasSystem = fs15.existsSync(paths.specsSystem());
|
|
22892
22885
|
let name = fallbackName;
|
|
22893
22886
|
if (hasSystem) {
|
|
22894
22887
|
const existing = loadSystemSpec();
|
|
@@ -22910,11 +22903,11 @@ function ensureProjectInitialized(fallbackName) {
|
|
|
22910
22903
|
function walkChainedSubprojects(projectRoot, onChild) {
|
|
22911
22904
|
const visited = /* @__PURE__ */ new Set();
|
|
22912
22905
|
const walk2 = (dir) => {
|
|
22913
|
-
const resolved =
|
|
22906
|
+
const resolved = path21.resolve(dir);
|
|
22914
22907
|
if (visited.has(resolved)) return;
|
|
22915
22908
|
visited.add(resolved);
|
|
22916
22909
|
const specsDir = aiPathsAt(dir).specsDir();
|
|
22917
|
-
if (!
|
|
22910
|
+
if (!fs15.existsSync(specsDir)) return;
|
|
22918
22911
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
22919
22912
|
let raw;
|
|
22920
22913
|
try {
|
|
@@ -22932,7 +22925,7 @@ function walkChainedSubprojects(projectRoot, onChild) {
|
|
|
22932
22925
|
continue;
|
|
22933
22926
|
}
|
|
22934
22927
|
const id = raw.id;
|
|
22935
|
-
onChild(childDir, typeof id === "string" ? id :
|
|
22928
|
+
onChild(childDir, typeof id === "string" ? id : path21.basename(childDir));
|
|
22936
22929
|
walk2(childDir);
|
|
22937
22930
|
}
|
|
22938
22931
|
};
|
|
@@ -22941,7 +22934,7 @@ function walkChainedSubprojects(projectRoot, onChild) {
|
|
|
22941
22934
|
function listDirectChainedSubprojects(projectRoot) {
|
|
22942
22935
|
const out = [];
|
|
22943
22936
|
const specsDir = aiPathsAt(projectRoot).specsDir();
|
|
22944
|
-
if (!
|
|
22937
|
+
if (!fs15.existsSync(specsDir)) return out;
|
|
22945
22938
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
22946
22939
|
let raw;
|
|
22947
22940
|
try {
|
|
@@ -22959,12 +22952,12 @@ function listDirectChainedSubprojects(projectRoot) {
|
|
|
22959
22952
|
continue;
|
|
22960
22953
|
}
|
|
22961
22954
|
const id = raw.id;
|
|
22962
|
-
out.push({ dir, subsystemId: typeof id === "string" ? id :
|
|
22955
|
+
out.push({ dir, subsystemId: typeof id === "string" ? id : path21.basename(dir) });
|
|
22963
22956
|
}
|
|
22964
22957
|
return out;
|
|
22965
22958
|
}
|
|
22966
22959
|
function childHasSpecsButNoConfig(childDir) {
|
|
22967
|
-
return
|
|
22960
|
+
return fs15.existsSync(aiPathsAt(childDir).specsDir()) && !projectConfigRepositoryAt(childDir).exists();
|
|
22968
22961
|
}
|
|
22969
22962
|
function findChainingSubprojectsMissingConfig(projectRoot) {
|
|
22970
22963
|
const missing = [];
|
|
@@ -23013,14 +23006,14 @@ function moveSubsystemProject(subsystemId, newProjectPath) {
|
|
|
23013
23006
|
const oldDir = assertContainedProjectPath(root, sub.projectPath);
|
|
23014
23007
|
const newDir = assertContainedProjectPath(root, nextPath);
|
|
23015
23008
|
if (oldDir !== newDir) {
|
|
23016
|
-
if (!
|
|
23009
|
+
if (!fs15.existsSync(oldDir)) {
|
|
23017
23010
|
throw new WaironError(`Subproject directory not found at its current path: ${oldDir}`);
|
|
23018
23011
|
}
|
|
23019
|
-
if (
|
|
23012
|
+
if (fs15.existsSync(newDir)) {
|
|
23020
23013
|
throw new WaironError(`Target directory already exists: ${newDir}`);
|
|
23021
23014
|
}
|
|
23022
|
-
ensureDir(
|
|
23023
|
-
|
|
23015
|
+
ensureDir(path21.dirname(newDir));
|
|
23016
|
+
fs15.renameSync(oldDir, newDir);
|
|
23024
23017
|
}
|
|
23025
23018
|
saveSubsystemSpec({ ...sub, projectPath: nextPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
23026
23019
|
invalidateSpecCache();
|
|
@@ -23029,9 +23022,9 @@ function toPosixPath(p) {
|
|
|
23029
23022
|
return p.replace(/\\/g, "/");
|
|
23030
23023
|
}
|
|
23031
23024
|
function isWithinDir(dir, file) {
|
|
23032
|
-
const d =
|
|
23033
|
-
const f =
|
|
23034
|
-
return f === d || f.startsWith(d +
|
|
23025
|
+
const d = path21.resolve(dir);
|
|
23026
|
+
const f = path21.resolve(file);
|
|
23027
|
+
return f === d || f.startsWith(d + path21.sep);
|
|
23035
23028
|
}
|
|
23036
23029
|
function externalizeSubsystem(subsystemId, projectPath) {
|
|
23037
23030
|
if (subsystemId.includes("::")) {
|
|
@@ -23043,14 +23036,14 @@ function externalizeSubsystem(subsystemId, projectPath) {
|
|
|
23043
23036
|
}
|
|
23044
23037
|
const parentRoot = getProjectRoot();
|
|
23045
23038
|
const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
|
|
23046
|
-
const fooDir =
|
|
23047
|
-
if (!
|
|
23039
|
+
const fooDir = path21.join(parentSpecsDir, subsystemId);
|
|
23040
|
+
if (!fs15.existsSync(fooDir)) {
|
|
23048
23041
|
throw new WaironError(`subsystem specs directory not found: ${fooDir}`);
|
|
23049
23042
|
}
|
|
23050
23043
|
const relPath = toPosixPath(projectPath);
|
|
23051
23044
|
const childDir = assertContainedProjectPath(parentRoot, relPath);
|
|
23052
|
-
const childFooDir =
|
|
23053
|
-
if (
|
|
23045
|
+
const childFooDir = path21.join(childDir, ".wai", "specs", subsystemId);
|
|
23046
|
+
if (fs15.existsSync(childFooDir)) {
|
|
23054
23047
|
throw new WaironError(`target already contains a "${subsystemId}" subsystem: ${childFooDir}`);
|
|
23055
23048
|
}
|
|
23056
23049
|
const renameMap = buildRenameMap(
|
|
@@ -23062,18 +23055,18 @@ function externalizeSubsystem(subsystemId, projectPath) {
|
|
|
23062
23055
|
runWithProjectRoot(childDir, () => {
|
|
23063
23056
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23064
23057
|
projectConfigRepository.create(defaultProjectConfig(childSystemName, now));
|
|
23065
|
-
ensureDir(
|
|
23058
|
+
ensureDir(path21.join(childDir, ".wai", "specs"));
|
|
23066
23059
|
saveSystemSpec(bootstrapSystemSpec(childSystemName, now));
|
|
23067
23060
|
});
|
|
23068
|
-
ensureDir(
|
|
23069
|
-
|
|
23061
|
+
ensureDir(path21.dirname(childFooDir));
|
|
23062
|
+
fs15.renameSync(fooDir, childFooDir);
|
|
23070
23063
|
rebaseImplementationPaths(childFooDir, parentRoot, childDir);
|
|
23071
|
-
patchSubsystemIndex(
|
|
23064
|
+
patchSubsystemIndex(path21.join(childFooDir, ".index.yaml"), (s) => {
|
|
23072
23065
|
s.parentSystem = childSystemName;
|
|
23073
23066
|
delete s.projectPath;
|
|
23074
23067
|
});
|
|
23075
23068
|
ensureDir(fooDir);
|
|
23076
|
-
writeYamlFile(
|
|
23069
|
+
writeYamlFile(path21.join(fooDir, ".index.yaml"), {
|
|
23077
23070
|
id: subsystemId,
|
|
23078
23071
|
name: foo.name,
|
|
23079
23072
|
description: foo.description,
|
|
@@ -23100,9 +23093,9 @@ function internalizeSubsystem(subsystemId) {
|
|
|
23100
23093
|
const parentRoot = getProjectRoot();
|
|
23101
23094
|
const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
|
|
23102
23095
|
const childDir = assertContainedProjectPath(parentRoot, foo.projectPath);
|
|
23103
|
-
const childWai =
|
|
23104
|
-
const childFooDir =
|
|
23105
|
-
if (!
|
|
23096
|
+
const childWai = path21.join(childDir, ".wai");
|
|
23097
|
+
const childFooDir = path21.join(childDir, ".wai", "specs", subsystemId);
|
|
23098
|
+
if (!fs15.existsSync(childFooDir)) {
|
|
23106
23099
|
throw new WaironError(`external subproject missing subsystem "${subsystemId}": ${childFooDir}`);
|
|
23107
23100
|
}
|
|
23108
23101
|
const childOwnSubs = runWithProjectRoot(childDir, () => loadSubsystemSpecs()).filter((s) => !s.id.includes("::"));
|
|
@@ -23115,16 +23108,16 @@ function internalizeSubsystem(subsystemId) {
|
|
|
23115
23108
|
false
|
|
23116
23109
|
);
|
|
23117
23110
|
const parentSystemName = loadSystemSpec()?.name ?? foo.parentSystem;
|
|
23118
|
-
const fooDir =
|
|
23119
|
-
|
|
23120
|
-
ensureDir(
|
|
23121
|
-
|
|
23111
|
+
const fooDir = path21.join(parentSpecsDir, subsystemId);
|
|
23112
|
+
fs15.rmSync(fooDir, { recursive: true, force: true });
|
|
23113
|
+
ensureDir(path21.dirname(fooDir));
|
|
23114
|
+
fs15.renameSync(childFooDir, fooDir);
|
|
23122
23115
|
rebaseImplementationPaths(fooDir, childDir, parentRoot);
|
|
23123
|
-
patchSubsystemIndex(
|
|
23116
|
+
patchSubsystemIndex(path21.join(fooDir, ".index.yaml"), (s) => {
|
|
23124
23117
|
s.parentSystem = parentSystemName;
|
|
23125
23118
|
delete s.projectPath;
|
|
23126
23119
|
});
|
|
23127
|
-
|
|
23120
|
+
fs15.rmSync(childWai, { recursive: true, force: true });
|
|
23128
23121
|
rewriteRefsInDir(parentSpecsDir, renameMap, fooDir);
|
|
23129
23122
|
rebaseMovedRefs(fooDir, subsystemId, "outOf");
|
|
23130
23123
|
invalidateSpecCache();
|
|
@@ -23202,8 +23195,8 @@ function rebaseImplementationPaths(specsDir, fromRoot, toRoot) {
|
|
|
23202
23195
|
let changed = false;
|
|
23203
23196
|
const rebase = (holder, key) => {
|
|
23204
23197
|
const p = holder[key];
|
|
23205
|
-
if (typeof p !== "string" || p === "" ||
|
|
23206
|
-
const next = toPosixPath(
|
|
23198
|
+
if (typeof p !== "string" || p === "" || path21.isAbsolute(p)) return;
|
|
23199
|
+
const next = toPosixPath(path21.relative(toRoot, path21.resolve(fromRoot, p)));
|
|
23207
23200
|
if (next !== p) {
|
|
23208
23201
|
holder[key] = next;
|
|
23209
23202
|
changed = true;
|
|
@@ -23219,7 +23212,7 @@ function rebaseImplementationPaths(specsDir, fromRoot, toRoot) {
|
|
|
23219
23212
|
}
|
|
23220
23213
|
}
|
|
23221
23214
|
function patchSubsystemIndex(indexPath, mutate) {
|
|
23222
|
-
if (!
|
|
23215
|
+
if (!fs15.existsSync(indexPath)) return;
|
|
23223
23216
|
const raw = readYamlFile(indexPath);
|
|
23224
23217
|
mutate(raw);
|
|
23225
23218
|
raw.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -23280,28 +23273,28 @@ function moveRenamedSpecs(componentId, newId, component, movingInterface, moving
|
|
|
23280
23273
|
if (movedInterface) saveInterfaceSpec({ ...movedInterface, id: interfaceId, component: newId });
|
|
23281
23274
|
if (movedImplementation) {
|
|
23282
23275
|
const oldFile = getImplementationPath(movedImplementation.id);
|
|
23283
|
-
if (
|
|
23284
|
-
|
|
23276
|
+
if (path21.resolve(getImplementationPath(implementationId, movedImplementation.contract)) === path21.resolve(oldFile)) {
|
|
23277
|
+
fs15.unlinkSync(oldFile);
|
|
23285
23278
|
}
|
|
23286
23279
|
saveImplementationSpec({ ...movedImplementation, id: implementationId });
|
|
23287
23280
|
}
|
|
23288
|
-
|
|
23289
|
-
if (movingInterface)
|
|
23290
|
-
if (movingImplementation)
|
|
23281
|
+
removeSpecFile2(getComponentPath(componentId), componentId);
|
|
23282
|
+
if (movingInterface) removeSpecFile2(getInterfacePath(movingInterface.id), movingInterface.id);
|
|
23283
|
+
if (movingImplementation) removeSpecFile2(getImplementationPath(movingImplementation.id), movingImplementation.id);
|
|
23291
23284
|
invalidateSpecCache();
|
|
23292
23285
|
}
|
|
23293
|
-
function
|
|
23294
|
-
if (!
|
|
23286
|
+
function removeSpecFile2(file, id) {
|
|
23287
|
+
if (!fs15.existsSync(file)) return;
|
|
23295
23288
|
try {
|
|
23296
23289
|
if (readYamlFile(file)?.id !== id) return;
|
|
23297
23290
|
} catch {
|
|
23298
23291
|
return;
|
|
23299
23292
|
}
|
|
23300
|
-
|
|
23301
|
-
const specsRoot =
|
|
23302
|
-
for (let dir =
|
|
23303
|
-
if (
|
|
23304
|
-
|
|
23293
|
+
fs15.unlinkSync(file);
|
|
23294
|
+
const specsRoot = path21.resolve(aiPathsAt(getProjectRoot()).specsDir());
|
|
23295
|
+
for (let dir = path21.dirname(path21.resolve(file)); dir !== specsRoot && isWithinDir(specsRoot, dir); dir = path21.dirname(dir)) {
|
|
23296
|
+
if (fs15.readdirSync(dir).length > 0) break;
|
|
23297
|
+
fs15.rmdirSync(dir);
|
|
23305
23298
|
}
|
|
23306
23299
|
}
|
|
23307
23300
|
function renameMethod(componentId, methodName, newName, pinSymbol) {
|
|
@@ -23398,12 +23391,12 @@ function collectMentions(specsDir, methodName, moved) {
|
|
|
23398
23391
|
function identifierPattern(methodName) {
|
|
23399
23392
|
return new RegExp(`(?<![A-Za-z0-9_])${methodName}(?![A-Za-z0-9_])`);
|
|
23400
23393
|
}
|
|
23401
|
-
var
|
|
23394
|
+
var fs15, path21, METHOD_NAME, PROSE_FIELDS2;
|
|
23402
23395
|
var init_provision = __esm({
|
|
23403
23396
|
"src/core/provision.ts"() {
|
|
23404
23397
|
"use strict";
|
|
23405
|
-
|
|
23406
|
-
|
|
23398
|
+
fs15 = __toESM(require("fs"));
|
|
23399
|
+
path21 = __toESM(require("path"));
|
|
23407
23400
|
init_specs2();
|
|
23408
23401
|
init_loader();
|
|
23409
23402
|
init_project_config();
|
|
@@ -23565,16 +23558,16 @@ function packNamespace(pack) {
|
|
|
23565
23558
|
return pack.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
23566
23559
|
}
|
|
23567
23560
|
function extensionsFor(builtin, packSkills) {
|
|
23568
|
-
return packSkills.filter((s) => s.extends === builtin &&
|
|
23561
|
+
return packSkills.filter((s) => s.extends === builtin && fs16.existsSync(s.sourcePath));
|
|
23569
23562
|
}
|
|
23570
23563
|
function composeBuiltinSkill(name, packSkills) {
|
|
23571
23564
|
const srcPath = skillTemplatePath(name);
|
|
23572
|
-
const base =
|
|
23565
|
+
const base = fs16.existsSync(srcPath) ? fs16.readFileSync(srcPath, "utf-8") : "";
|
|
23573
23566
|
const sections = extensionsFor(name, packSkills);
|
|
23574
23567
|
if (sections.length === 0) return base;
|
|
23575
23568
|
const parts = [base.trimEnd()];
|
|
23576
23569
|
for (const section of sections) {
|
|
23577
|
-
const body =
|
|
23570
|
+
const body = fs16.readFileSync(section.sourcePath, "utf-8").replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "");
|
|
23578
23571
|
parts.push(`## Platform: ${section.pack}`, body.trim());
|
|
23579
23572
|
}
|
|
23580
23573
|
return `${parts.join("\n\n")}
|
|
@@ -23590,16 +23583,16 @@ function readFrontmatter(raw, fallbackName) {
|
|
|
23590
23583
|
return { name: field("name") || fallbackName, description: field("description") };
|
|
23591
23584
|
}
|
|
23592
23585
|
function builtinSkillsDir() {
|
|
23593
|
-
return
|
|
23586
|
+
return path22.resolve(__dirname, "..", "templates", "skills");
|
|
23594
23587
|
}
|
|
23595
23588
|
function skillTemplatePath(name) {
|
|
23596
|
-
return
|
|
23589
|
+
return path22.join(builtinSkillsDir(), `${name}.md`);
|
|
23597
23590
|
}
|
|
23598
23591
|
function skillDestPath(type, destDir, name) {
|
|
23599
23592
|
if (type === "claude" || type === "codex" || type === "gemini" || type === "agy") {
|
|
23600
|
-
return
|
|
23593
|
+
return path22.join(destDir, name, "SKILL.md");
|
|
23601
23594
|
}
|
|
23602
|
-
return
|
|
23595
|
+
return path22.join(destDir, `${name}.md`);
|
|
23603
23596
|
}
|
|
23604
23597
|
function skillsDirForTarget(type) {
|
|
23605
23598
|
switch (type) {
|
|
@@ -23634,22 +23627,22 @@ function exportSddSkills(targetTypes) {
|
|
|
23634
23627
|
ensureDir(destDir);
|
|
23635
23628
|
destinations.push(destDir);
|
|
23636
23629
|
for (const name of SKILL_NAMES) {
|
|
23637
|
-
if (!
|
|
23630
|
+
if (!fs16.existsSync(skillTemplatePath(name))) continue;
|
|
23638
23631
|
const content = composeBuiltinSkill(name, packSkills.filter((s) => s.targets.includes(type)));
|
|
23639
23632
|
const destPath = skillDestPath(type, destDir, name);
|
|
23640
|
-
ensureDir(
|
|
23641
|
-
|
|
23633
|
+
ensureDir(path22.dirname(destPath));
|
|
23634
|
+
fs16.writeFileSync(destPath, content, "utf-8");
|
|
23642
23635
|
fileCount++;
|
|
23643
23636
|
}
|
|
23644
23637
|
for (const skill of packSkills) {
|
|
23645
23638
|
if (skill.extends !== void 0) continue;
|
|
23646
23639
|
if (!skill.targets.includes(type)) continue;
|
|
23647
|
-
if (!
|
|
23640
|
+
if (!fs16.existsSync(skill.sourcePath)) continue;
|
|
23648
23641
|
const id = packSkillId(skill);
|
|
23649
|
-
const content =
|
|
23642
|
+
const content = fs16.readFileSync(skill.sourcePath, "utf-8");
|
|
23650
23643
|
const destPath = skillDestPath(type, destDir, id);
|
|
23651
|
-
ensureDir(
|
|
23652
|
-
|
|
23644
|
+
ensureDir(path22.dirname(destPath));
|
|
23645
|
+
fs16.writeFileSync(destPath, content, "utf-8");
|
|
23653
23646
|
fileCount++;
|
|
23654
23647
|
}
|
|
23655
23648
|
}
|
|
@@ -23662,12 +23655,12 @@ function checkSkillFreshness(type) {
|
|
|
23662
23655
|
const packSkills = loadProjectExtensions2().skills.filter((s) => s.targets.includes(type));
|
|
23663
23656
|
for (const name of SKILL_NAMES) {
|
|
23664
23657
|
const destPath = skillDestPath(type, dir, name);
|
|
23665
|
-
if (!
|
|
23658
|
+
if (!fs16.existsSync(destPath)) {
|
|
23666
23659
|
result.missing.push(name);
|
|
23667
23660
|
continue;
|
|
23668
23661
|
}
|
|
23669
23662
|
const want = composeBuiltinSkill(name, packSkills);
|
|
23670
|
-
const have =
|
|
23663
|
+
const have = fs16.readFileSync(destPath, "utf-8");
|
|
23671
23664
|
if (have === want) result.ok.push(name);
|
|
23672
23665
|
else result.stale.push(name);
|
|
23673
23666
|
}
|
|
@@ -23679,7 +23672,7 @@ function activeTargetTypes2() {
|
|
|
23679
23672
|
return activeTargetTypes(config);
|
|
23680
23673
|
}
|
|
23681
23674
|
function readSkillFrontmatter(name) {
|
|
23682
|
-
return readFrontmatter(
|
|
23675
|
+
return readFrontmatter(fs16.readFileSync(skillTemplatePath(name), "utf-8"), name);
|
|
23683
23676
|
}
|
|
23684
23677
|
function listSkillResources() {
|
|
23685
23678
|
const builtin = RESOURCE_SKILL_IDS.map((id) => {
|
|
@@ -23693,9 +23686,9 @@ function listSkillResources() {
|
|
|
23693
23686
|
defaultForHostedMcp: true
|
|
23694
23687
|
};
|
|
23695
23688
|
});
|
|
23696
|
-
const pack = loadProjectExtensions2().skills.filter((s) => s.extends === void 0 &&
|
|
23689
|
+
const pack = loadProjectExtensions2().skills.filter((s) => s.extends === void 0 && fs16.existsSync(s.sourcePath)).map((skill) => {
|
|
23697
23690
|
const id = packSkillId(skill);
|
|
23698
|
-
const fm = readFrontmatter(
|
|
23691
|
+
const fm = readFrontmatter(fs16.readFileSync(skill.sourcePath, "utf-8"), id);
|
|
23699
23692
|
return {
|
|
23700
23693
|
id,
|
|
23701
23694
|
name: fm.name,
|
|
@@ -23711,8 +23704,8 @@ function readSkillResource(resourceId) {
|
|
|
23711
23704
|
const packSkills = loadProjectExtensions2().skills;
|
|
23712
23705
|
if (SKILL_NAMES.includes(resourceId)) return composeBuiltinSkill(resourceId, packSkills);
|
|
23713
23706
|
const packSkill = packSkills.find((s) => s.extends === void 0 && packSkillId(s) === resourceId);
|
|
23714
|
-
if (packSkill) return
|
|
23715
|
-
return
|
|
23707
|
+
if (packSkill) return fs16.readFileSync(packSkill.sourcePath, "utf-8");
|
|
23708
|
+
return fs16.readFileSync(skillTemplatePath(resourceId), "utf-8");
|
|
23716
23709
|
}
|
|
23717
23710
|
function listResources() {
|
|
23718
23711
|
return listSkillResources();
|
|
@@ -23725,12 +23718,12 @@ function readResource(resourceId) {
|
|
|
23725
23718
|
if (!known) throw new SkillResourceNotFoundError(resourceId);
|
|
23726
23719
|
return readSkillResource(resourceId);
|
|
23727
23720
|
}
|
|
23728
|
-
var
|
|
23721
|
+
var path22, fs16, SKILL_NAMES, SKILL_RESOURCE_SCHEME, RESOURCE_SKILL_IDS, SkillResourceNotFoundError;
|
|
23729
23722
|
var init_skills = __esm({
|
|
23730
23723
|
"src/core/skills.ts"() {
|
|
23731
23724
|
"use strict";
|
|
23732
|
-
|
|
23733
|
-
|
|
23725
|
+
path22 = __toESM(require("path"));
|
|
23726
|
+
fs16 = __toESM(require("fs"));
|
|
23734
23727
|
init_fs();
|
|
23735
23728
|
init_defaults();
|
|
23736
23729
|
init_project();
|
|
@@ -26395,7 +26388,7 @@ var require_dist = __commonJS({
|
|
|
26395
26388
|
scaffoldPack: () => scaffoldPack2
|
|
26396
26389
|
});
|
|
26397
26390
|
module2.exports = __toCommonJS2(src_exports2);
|
|
26398
|
-
var
|
|
26391
|
+
var path28 = __toESM2(require("path"));
|
|
26399
26392
|
var import_js_yaml3 = require("js-yaml");
|
|
26400
26393
|
var import_js_yaml = require("js-yaml");
|
|
26401
26394
|
var import_crypto = require("crypto");
|
|
@@ -26958,8 +26951,8 @@ var require_dist = __commonJS({
|
|
|
26958
26951
|
function slug(name) {
|
|
26959
26952
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
26960
26953
|
}
|
|
26961
|
-
var
|
|
26962
|
-
var
|
|
26954
|
+
var fs18 = __toESM2(require("fs"));
|
|
26955
|
+
var path29 = __toESM2(require("path"));
|
|
26963
26956
|
var import_fflate = require_node();
|
|
26964
26957
|
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".hg", ".svn"]);
|
|
26965
26958
|
function listEntries(archive) {
|
|
@@ -26997,9 +26990,9 @@ var require_dist = __commonJS({
|
|
|
26997
26990
|
}
|
|
26998
26991
|
function writeTree(destDir, files) {
|
|
26999
26992
|
for (const file of files) {
|
|
27000
|
-
const absolute =
|
|
27001
|
-
|
|
27002
|
-
|
|
26993
|
+
const absolute = path29.join(destDir, file.path);
|
|
26994
|
+
fs18.mkdirSync(path29.dirname(absolute), { recursive: true });
|
|
26995
|
+
fs18.writeFileSync(absolute, file.contents);
|
|
27003
26996
|
}
|
|
27004
26997
|
}
|
|
27005
26998
|
function classifyKind(name, symlinks) {
|
|
@@ -27008,14 +27001,14 @@ var require_dist = __commonJS({
|
|
|
27008
27001
|
return "file";
|
|
27009
27002
|
}
|
|
27010
27003
|
function walkPackDir(root, current2, out) {
|
|
27011
|
-
for (const entry of
|
|
27004
|
+
for (const entry of fs18.readdirSync(current2, { withFileTypes: true })) {
|
|
27012
27005
|
if (entry.isDirectory()) {
|
|
27013
27006
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
27014
|
-
walkPackDir(root,
|
|
27007
|
+
walkPackDir(root, path29.join(current2, entry.name), out);
|
|
27015
27008
|
} else if (entry.isFile()) {
|
|
27016
|
-
const absolute =
|
|
27017
|
-
const relative22 =
|
|
27018
|
-
out.push({ path: relative22, contents:
|
|
27009
|
+
const absolute = path29.join(current2, entry.name);
|
|
27010
|
+
const relative22 = path29.relative(root, absolute).split(path29.sep).join("/");
|
|
27011
|
+
out.push({ path: relative22, contents: fs18.readFileSync(absolute) });
|
|
27019
27012
|
}
|
|
27020
27013
|
}
|
|
27021
27014
|
}
|
|
@@ -27065,7 +27058,7 @@ var require_dist = __commonJS({
|
|
|
27065
27058
|
function scaffoldPack(request) {
|
|
27066
27059
|
const files = render(request);
|
|
27067
27060
|
writeTree(request.targetDir, files);
|
|
27068
|
-
return files.map((file) =>
|
|
27061
|
+
return files.map((file) => path28.join(request.targetDir, file.path));
|
|
27069
27062
|
}
|
|
27070
27063
|
function buildPack(sourceDir) {
|
|
27071
27064
|
const files = readPackDir(sourceDir);
|
|
@@ -27122,7 +27115,7 @@ var require_dist = __commonJS({
|
|
|
27122
27115
|
}
|
|
27123
27116
|
const manifest = parseManifest(decode(envelope.contents));
|
|
27124
27117
|
verifyIntegrity2(manifest, files);
|
|
27125
|
-
const directory =
|
|
27118
|
+
const directory = path28.resolve(destDir);
|
|
27126
27119
|
writeTree(directory, files);
|
|
27127
27120
|
const result = {
|
|
27128
27121
|
directory,
|
|
@@ -27200,7 +27193,7 @@ var require_dist = __commonJS({
|
|
|
27200
27193
|
}
|
|
27201
27194
|
const manifest = parseTreeManifest(decode(envelope.contents));
|
|
27202
27195
|
verifyTreeIntegrity(manifest, files);
|
|
27203
|
-
const directory =
|
|
27196
|
+
const directory = path28.resolve(destDir);
|
|
27204
27197
|
writeTree(directory, files);
|
|
27205
27198
|
const result = {
|
|
27206
27199
|
destDir: directory,
|
|
@@ -27215,7 +27208,7 @@ var require_dist = __commonJS({
|
|
|
27215
27208
|
return normalized === "." ? ".wai/" : `${normalized}/.wai/`;
|
|
27216
27209
|
}
|
|
27217
27210
|
function normalizeRootPath(relativePath) {
|
|
27218
|
-
const posix2 = relativePath.split(
|
|
27211
|
+
const posix2 = relativePath.split(path28.sep).join("/").replace(/^\.\//, "").replace(/\/+$/, "");
|
|
27219
27212
|
return posix2 === "" || posix2 === "." ? "." : posix2;
|
|
27220
27213
|
}
|
|
27221
27214
|
function slugify(projectName) {
|
|
@@ -27303,41 +27296,41 @@ function hasAuthoredSpecs(root) {
|
|
|
27303
27296
|
if (!pathExists(specsDir)) {
|
|
27304
27297
|
return false;
|
|
27305
27298
|
}
|
|
27306
|
-
const systemIndex =
|
|
27299
|
+
const systemIndex = path23.resolve(paths.specsSystem());
|
|
27307
27300
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
27308
|
-
if (
|
|
27301
|
+
if (path23.resolve(file) !== systemIndex) {
|
|
27309
27302
|
return true;
|
|
27310
27303
|
}
|
|
27311
27304
|
}
|
|
27312
27305
|
return false;
|
|
27313
27306
|
}
|
|
27314
27307
|
function createStagingDir(destDir) {
|
|
27315
|
-
const root =
|
|
27316
|
-
|
|
27317
|
-
const stagingDir =
|
|
27308
|
+
const root = path23.resolve(destDir);
|
|
27309
|
+
fs17.mkdirSync(root, { recursive: true });
|
|
27310
|
+
const stagingDir = fs17.mkdtempSync(path23.join(root, STAGING_PREFIX));
|
|
27318
27311
|
return stagingDir;
|
|
27319
27312
|
}
|
|
27320
27313
|
function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
|
|
27321
|
-
const root =
|
|
27322
|
-
const backupDir =
|
|
27314
|
+
const root = path23.resolve(destDir);
|
|
27315
|
+
const backupDir = path23.join(root, BACKUP_DIR, timestampSlug());
|
|
27323
27316
|
let backedUp = false;
|
|
27324
27317
|
for (const rootRel of roots) {
|
|
27325
27318
|
const relative9 = rootRel === "." ? "" : rootRel;
|
|
27326
|
-
const stagedSpecDir =
|
|
27327
|
-
if (!
|
|
27328
|
-
const liveSpecDir = liveSpecDirFor(
|
|
27329
|
-
if (backupExisting && liveSpecDir &&
|
|
27330
|
-
const backupTarget =
|
|
27331
|
-
|
|
27332
|
-
|
|
27319
|
+
const stagedSpecDir = path23.join(stagingDir, relative9, ".wai");
|
|
27320
|
+
if (!fs17.existsSync(stagedSpecDir)) continue;
|
|
27321
|
+
const liveSpecDir = liveSpecDirFor(path23.join(root, relative9));
|
|
27322
|
+
if (backupExisting && liveSpecDir && fs17.existsSync(liveSpecDir)) {
|
|
27323
|
+
const backupTarget = path23.join(backupDir, relative9, path23.basename(liveSpecDir));
|
|
27324
|
+
fs17.mkdirSync(path23.dirname(backupTarget), { recursive: true });
|
|
27325
|
+
fs17.renameSync(liveSpecDir, backupTarget);
|
|
27333
27326
|
backedUp = true;
|
|
27334
|
-
} else if (liveSpecDir &&
|
|
27335
|
-
|
|
27327
|
+
} else if (liveSpecDir && fs17.existsSync(liveSpecDir)) {
|
|
27328
|
+
fs17.rmSync(liveSpecDir, { recursive: true, force: true });
|
|
27336
27329
|
}
|
|
27337
|
-
const target =
|
|
27338
|
-
|
|
27339
|
-
if (
|
|
27340
|
-
|
|
27330
|
+
const target = path23.join(root, relative9, ".wai");
|
|
27331
|
+
fs17.mkdirSync(path23.dirname(target), { recursive: true });
|
|
27332
|
+
if (fs17.existsSync(target)) fs17.rmSync(target, { recursive: true, force: true });
|
|
27333
|
+
fs17.renameSync(stagedSpecDir, target);
|
|
27341
27334
|
}
|
|
27342
27335
|
if (backedUp) {
|
|
27343
27336
|
return backupDir;
|
|
@@ -27346,7 +27339,7 @@ function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
|
|
|
27346
27339
|
}
|
|
27347
27340
|
function discardStagingDir(stagingDir) {
|
|
27348
27341
|
try {
|
|
27349
|
-
|
|
27342
|
+
fs17.rmSync(stagingDir, { recursive: true, force: true });
|
|
27350
27343
|
} catch {
|
|
27351
27344
|
}
|
|
27352
27345
|
}
|
|
@@ -27360,7 +27353,7 @@ function exportSpecTree(includeDerived, allowPartial) {
|
|
|
27360
27353
|
const skipped = [...inspection.skipped];
|
|
27361
27354
|
const roots = [{ relativePath: ".", waiDir: aiPathsAt(root).root() }];
|
|
27362
27355
|
for (const rel2 of inspection.roots) {
|
|
27363
|
-
const waiDir = aiPathsAt(
|
|
27356
|
+
const waiDir = aiPathsAt(path23.resolve(root, rel2)).root();
|
|
27364
27357
|
if (pathExists(waiDir)) {
|
|
27365
27358
|
roots.push({ relativePath: rel2, waiDir });
|
|
27366
27359
|
} else {
|
|
@@ -27391,7 +27384,7 @@ function importSpecTree(archive, options) {
|
|
|
27391
27384
|
if (!info.compatible) {
|
|
27392
27385
|
throw new Error("incompatible .waitree archive (format or minimum wairon version)");
|
|
27393
27386
|
}
|
|
27394
|
-
const destDir =
|
|
27387
|
+
const destDir = path23.resolve(options.destDir ?? getProjectRoot());
|
|
27395
27388
|
const occupied = hasSpecTree(destDir);
|
|
27396
27389
|
const authored = hasAuthoredSpecs(destDir);
|
|
27397
27390
|
if (authored && options.replaceExisting !== true) {
|
|
@@ -27422,21 +27415,21 @@ function importSpecTree(archive, options) {
|
|
|
27422
27415
|
return result;
|
|
27423
27416
|
}
|
|
27424
27417
|
function liveSpecDirFor(rootDir) {
|
|
27425
|
-
const modern =
|
|
27426
|
-
if (
|
|
27427
|
-
const legacy =
|
|
27428
|
-
if (
|
|
27418
|
+
const modern = path23.join(rootDir, ".wai");
|
|
27419
|
+
if (fs17.existsSync(modern)) return modern;
|
|
27420
|
+
const legacy = path23.join(rootDir, ".wairon");
|
|
27421
|
+
if (fs17.existsSync(legacy)) return legacy;
|
|
27429
27422
|
return null;
|
|
27430
27423
|
}
|
|
27431
27424
|
function timestampSlug() {
|
|
27432
27425
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
27433
27426
|
}
|
|
27434
|
-
var
|
|
27427
|
+
var fs17, path23, sdkPortal, STAGING_PREFIX, BACKUP_DIR;
|
|
27435
27428
|
var init_treetransfer = __esm({
|
|
27436
27429
|
"src/core/treetransfer.ts"() {
|
|
27437
27430
|
"use strict";
|
|
27438
|
-
|
|
27439
|
-
|
|
27431
|
+
fs17 = __toESM(require("fs"));
|
|
27432
|
+
path23 = __toESM(require("path"));
|
|
27440
27433
|
sdkPortal = __toESM(require_dist());
|
|
27441
27434
|
init_loader();
|
|
27442
27435
|
init_fs();
|
|
@@ -28139,7 +28132,7 @@ var WAIRON_MANAGED_MARKER = "wairon:managed";
|
|
|
28139
28132
|
var WAIRON_MANAGED_BANNER = `<!-- ${WAIRON_MANAGED_MARKER} \u2014 generated by \`wairon generate\`; do not edit, changes are overwritten -->`;
|
|
28140
28133
|
|
|
28141
28134
|
// src/exporters/claude.ts
|
|
28142
|
-
var
|
|
28135
|
+
var path24 = __toESM(require("path"));
|
|
28143
28136
|
init_fs();
|
|
28144
28137
|
var MODEL_BY_TIER = {
|
|
28145
28138
|
small: "haiku",
|
|
@@ -28179,7 +28172,7 @@ var ClaudeExporter = class {
|
|
|
28179
28172
|
outputPath(ctx) {
|
|
28180
28173
|
const { agent, target, projectRoot } = ctx;
|
|
28181
28174
|
const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
|
|
28182
|
-
return
|
|
28175
|
+
return path24.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
28183
28176
|
}
|
|
28184
28177
|
export(ctx) {
|
|
28185
28178
|
const { agent, renderedInstructions, budget } = ctx;
|
|
@@ -28204,7 +28197,7 @@ var ClaudeExporter = class {
|
|
|
28204
28197
|
};
|
|
28205
28198
|
|
|
28206
28199
|
// src/exporters/custom.ts
|
|
28207
|
-
var
|
|
28200
|
+
var path25 = __toESM(require("path"));
|
|
28208
28201
|
init_fs();
|
|
28209
28202
|
var CustomExporter = class {
|
|
28210
28203
|
constructor() {
|
|
@@ -28215,7 +28208,7 @@ var CustomExporter = class {
|
|
|
28215
28208
|
if (!("outputDir" in target)) {
|
|
28216
28209
|
throw new Error("CustomExporter requires target.outputDir");
|
|
28217
28210
|
}
|
|
28218
|
-
return
|
|
28211
|
+
return path25.resolve(projectRoot, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
28219
28212
|
}
|
|
28220
28213
|
export(ctx) {
|
|
28221
28214
|
const { agent, target, renderedInstructions } = ctx;
|
|
@@ -28238,7 +28231,7 @@ var CustomExporter = class {
|
|
|
28238
28231
|
};
|
|
28239
28232
|
|
|
28240
28233
|
// src/exporters/gemini.ts
|
|
28241
|
-
var
|
|
28234
|
+
var path26 = __toESM(require("path"));
|
|
28242
28235
|
init_fs();
|
|
28243
28236
|
var GeminiExporter = class {
|
|
28244
28237
|
constructor() {
|
|
@@ -28247,7 +28240,7 @@ var GeminiExporter = class {
|
|
|
28247
28240
|
outputPath(ctx) {
|
|
28248
28241
|
const { agent, target, projectRoot } = ctx;
|
|
28249
28242
|
const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
|
|
28250
|
-
return
|
|
28243
|
+
return path26.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
|
|
28251
28244
|
}
|
|
28252
28245
|
export(ctx) {
|
|
28253
28246
|
const { agent, renderedInstructions } = ctx;
|
|
@@ -28272,7 +28265,7 @@ function yamlString(value) {
|
|
|
28272
28265
|
}
|
|
28273
28266
|
|
|
28274
28267
|
// src/exporters/generate.ts
|
|
28275
|
-
var
|
|
28268
|
+
var path27 = __toESM(require("path"));
|
|
28276
28269
|
init_core();
|
|
28277
28270
|
init_execution_profile();
|
|
28278
28271
|
init_budget_policy();
|
|
@@ -28348,7 +28341,7 @@ function resolveExpectedOutputPaths(agents, projectConfig, projectRoot = getProj
|
|
|
28348
28341
|
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
28349
28342
|
if (!targetConfig) continue;
|
|
28350
28343
|
const ctx = { agent, projectRoot, target: targetConfig };
|
|
28351
|
-
expected.add(
|
|
28344
|
+
expected.add(path27.resolve(getExporter(targetConfig).outputPath(ctx)));
|
|
28352
28345
|
}
|
|
28353
28346
|
}
|
|
28354
28347
|
return expected;
|