@wairon/cli 5.1.1-dev.6 → 5.1.1-dev.7
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/README.md +1 -0
- package/dist/cli/index.js +1034 -870
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +404 -240
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1211,7 +1211,7 @@ var init_defaults = __esm({
|
|
|
1211
1211
|
copilot: ".github/prompts",
|
|
1212
1212
|
codex: ".codex/agents"
|
|
1213
1213
|
};
|
|
1214
|
-
WAIRON_VERSION = "5.1.1-dev.
|
|
1214
|
+
WAIRON_VERSION = "5.1.1-dev.7";
|
|
1215
1215
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
1216
1216
|
ARCHITECT_AGENT_ID = "agent-architect";
|
|
1217
1217
|
ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -3361,9 +3361,9 @@ var init_surfaces = __esm({
|
|
|
3361
3361
|
// src/core/rules/namespace.ts
|
|
3362
3362
|
function isExternalNamespaceRef(ctx, ref) {
|
|
3363
3363
|
if (ref.startsWith("::") || ref.startsWith("super::")) return true;
|
|
3364
|
-
const
|
|
3365
|
-
if (
|
|
3366
|
-
return !ctx.subsystemIds.has(ref.slice(0,
|
|
3364
|
+
const sep6 = ref.indexOf("::");
|
|
3365
|
+
if (sep6 === -1) return false;
|
|
3366
|
+
return !ctx.subsystemIds.has(ref.slice(0, sep6));
|
|
3367
3367
|
}
|
|
3368
3368
|
function resolveSurfaceRef(ctx, ref) {
|
|
3369
3369
|
const local = ref.split("::").filter((seg) => seg && seg !== "super").pop();
|
|
@@ -3700,10 +3700,10 @@ function stepGraph(steps) {
|
|
|
3700
3700
|
const s = byNum.get(n);
|
|
3701
3701
|
if (s.type !== "parallel" || s.endStep === void 0 || !s.branches?.length) continue;
|
|
3702
3702
|
const entries = s.branches.map((b) => b.step).sort((a, b) => a - b);
|
|
3703
|
-
const
|
|
3703
|
+
const join16 = fallNext(s.endStep);
|
|
3704
3704
|
for (let i = 0; i < entries.length; i++) {
|
|
3705
3705
|
const armEnd = i + 1 < entries.length ? prevOf(entries[i + 1]) : s.endStep;
|
|
3706
|
-
if (armEnd !== void 0 && armEnd >= entries[i]) armEndJoin.set(armEnd,
|
|
3706
|
+
if (armEnd !== void 0 && armEnd >= entries[i]) armEndJoin.set(armEnd, join16);
|
|
3707
3707
|
}
|
|
3708
3708
|
}
|
|
3709
3709
|
const successorsOf = (n) => {
|
|
@@ -3777,7 +3777,8 @@ var init_narrative_flow = __esm({
|
|
|
3777
3777
|
{ code: "REGION_OVERLAP", defaultSeverity: "error", summary: "loop/try regions interleave \u2014 regions must nest or be disjoint to map onto structured code" },
|
|
3778
3778
|
{ code: "JUMP_INTO_REGION", defaultSeverity: "warning", summary: "Jump lands in the middle of a loop/try body from outside \u2014 regions are entered through their header" },
|
|
3779
3779
|
{ code: "FALLTHROUGH_INTO_HANDLER", defaultSeverity: "warning", summary: "try body falls through into its own catch/finally region on the success path" },
|
|
3780
|
-
{ code: "BACKWARD_JUMP", defaultSeverity: "warning", summary: "Backward jump that is not a continue to an enclosing loop header \u2014 model repetition with a loop step" }
|
|
3780
|
+
{ code: "BACKWARD_JUMP", defaultSeverity: "warning", summary: "Backward jump that is not a continue to an enclosing loop header \u2014 model repetition with a loop step" },
|
|
3781
|
+
{ code: "DUPLICATE_STEP_LABEL", defaultSeverity: "error", summary: "Two steps in one narrative share a label \u2014 the symbolic anchor later deltas address by" }
|
|
3781
3782
|
],
|
|
3782
3783
|
check(ctx) {
|
|
3783
3784
|
for (const impl of ctx.implementations) {
|
|
@@ -3786,6 +3787,23 @@ var init_narrative_flow = __esm({
|
|
|
3786
3787
|
const steps = implMethod.narrative;
|
|
3787
3788
|
if (!steps.length) continue;
|
|
3788
3789
|
const where = `Method "${implMethod.name}" in implementation "${impl.id}": `;
|
|
3790
|
+
const labelled = /* @__PURE__ */ new Map();
|
|
3791
|
+
for (const step of steps) {
|
|
3792
|
+
const label = step.label;
|
|
3793
|
+
if (!label) continue;
|
|
3794
|
+
const first = labelled.get(label);
|
|
3795
|
+
if (first !== void 0) {
|
|
3796
|
+
ctx.addIssue(
|
|
3797
|
+
"error",
|
|
3798
|
+
"DUPLICATE_STEP_LABEL",
|
|
3799
|
+
`${where}steps ${first} and ${step.stepNumber} share the label "${label}". A label anchors one step for later deltas to address; two steps holding it makes every symbolic reference ambiguous and blocks all further edits to this implementation. Rename one.`,
|
|
3800
|
+
impl.id,
|
|
3801
|
+
isDraftCtx
|
|
3802
|
+
);
|
|
3803
|
+
} else {
|
|
3804
|
+
labelled.set(label, step.stepNumber);
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3789
3807
|
let sound = true;
|
|
3790
3808
|
const malformed = (msg) => {
|
|
3791
3809
|
sound = false;
|
|
@@ -7011,11 +7029,11 @@ var init_narrative_antipatterns = __esm({
|
|
|
7011
7029
|
const memberEdges = keys.flatMap((k) => (adjacency.get(k) ?? []).filter((e) => inScc.has(e.toKey)));
|
|
7012
7030
|
if (memberEdges.length === 0) continue;
|
|
7013
7031
|
const anchor = [...memberEdges].sort((a, b) => a.fromKey.localeCompare(b.fromKey))[0];
|
|
7014
|
-
const
|
|
7032
|
+
const path26 = [...keys].sort().join(" \u2192 ");
|
|
7015
7033
|
ctx.addIssue(
|
|
7016
7034
|
"warning",
|
|
7017
7035
|
"UNCONDITIONAL_CALL_CYCLE",
|
|
7018
|
-
`Call cycle with no guard: ${
|
|
7036
|
+
`Call cycle with no guard: ${path26} \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.`,
|
|
7019
7037
|
anchor.impl.id,
|
|
7020
7038
|
memberEdges.some((e) => ctx.isImplementationDraft(e.impl))
|
|
7021
7039
|
);
|
|
@@ -13881,6 +13899,77 @@ var init_variants = __esm({
|
|
|
13881
13899
|
}
|
|
13882
13900
|
});
|
|
13883
13901
|
|
|
13902
|
+
// src/core/baseline.ts
|
|
13903
|
+
function baselineDir() {
|
|
13904
|
+
return process.env["WAIRON_BASELINE_DIR"] || path13.join(os4.homedir(), ".wairon", "baselines");
|
|
13905
|
+
}
|
|
13906
|
+
function keyFor(root) {
|
|
13907
|
+
const normalized = path13.resolve(root).replace(/\\/g, "/").toLowerCase();
|
|
13908
|
+
return crypto3.createHash("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
13909
|
+
}
|
|
13910
|
+
function baselinePath(root) {
|
|
13911
|
+
return path13.join(baselineDir(), `${keyFor(root)}.json`);
|
|
13912
|
+
}
|
|
13913
|
+
function readBaseline(root = getProjectRoot()) {
|
|
13914
|
+
const p = baselinePath(root);
|
|
13915
|
+
if (!pathExists(p)) return null;
|
|
13916
|
+
try {
|
|
13917
|
+
return JSON.parse(fs9.readFileSync(p, "utf8"));
|
|
13918
|
+
} catch {
|
|
13919
|
+
return null;
|
|
13920
|
+
}
|
|
13921
|
+
}
|
|
13922
|
+
function currentSpecs(root) {
|
|
13923
|
+
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${path13.resolve(root, s.projectPath).split(path13.sep).join("/")}/`);
|
|
13924
|
+
const out = {};
|
|
13925
|
+
for (const [abs, content] of snapshotSpecFiles()) {
|
|
13926
|
+
const normalized = path13.resolve(abs).split(path13.sep).join("/");
|
|
13927
|
+
if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
|
|
13928
|
+
out[path13.relative(root, abs).split(path13.sep).join("/")] = content;
|
|
13929
|
+
}
|
|
13930
|
+
return out;
|
|
13931
|
+
}
|
|
13932
|
+
function diffAgainstBaseline(root = getProjectRoot()) {
|
|
13933
|
+
const baseline = readBaseline(root);
|
|
13934
|
+
if (!baseline) return null;
|
|
13935
|
+
const current2 = currentSpecs(root);
|
|
13936
|
+
const added = [];
|
|
13937
|
+
const changed = [];
|
|
13938
|
+
const removed = [];
|
|
13939
|
+
const unchangedPaths = [];
|
|
13940
|
+
for (const [rel2, content] of Object.entries(current2)) {
|
|
13941
|
+
const before = baseline.specs[rel2];
|
|
13942
|
+
if (before === void 0) added.push(rel2);
|
|
13943
|
+
else if (before !== content) changed.push(rel2);
|
|
13944
|
+
else unchangedPaths.push(rel2);
|
|
13945
|
+
}
|
|
13946
|
+
for (const rel2 of Object.keys(baseline.specs)) {
|
|
13947
|
+
if (current2[rel2] === void 0) removed.push(rel2);
|
|
13948
|
+
}
|
|
13949
|
+
return {
|
|
13950
|
+
added: added.sort(),
|
|
13951
|
+
changed: changed.sort(),
|
|
13952
|
+
removed: removed.sort(),
|
|
13953
|
+
unchangedPaths: unchangedPaths.sort()
|
|
13954
|
+
};
|
|
13955
|
+
}
|
|
13956
|
+
function settledSpecPaths(root = getProjectRoot()) {
|
|
13957
|
+
const diff = diffAgainstBaseline(root);
|
|
13958
|
+
return diff ? new Set(diff.unchangedPaths) : null;
|
|
13959
|
+
}
|
|
13960
|
+
var fs9, os4, path13, crypto3;
|
|
13961
|
+
var init_baseline = __esm({
|
|
13962
|
+
"src/core/baseline.ts"() {
|
|
13963
|
+
"use strict";
|
|
13964
|
+
fs9 = __toESM(require("fs"));
|
|
13965
|
+
os4 = __toESM(require("os"));
|
|
13966
|
+
path13 = __toESM(require("path"));
|
|
13967
|
+
crypto3 = __toESM(require("crypto"));
|
|
13968
|
+
init_fs();
|
|
13969
|
+
init_specs2();
|
|
13970
|
+
}
|
|
13971
|
+
});
|
|
13972
|
+
|
|
13884
13973
|
// src/core/validation.ts
|
|
13885
13974
|
function projectPackSelections() {
|
|
13886
13975
|
try {
|
|
@@ -14003,7 +14092,7 @@ function validateSddTree(rulesOrOptions, projectType = "backend") {
|
|
|
14003
14092
|
const types = loadTypeSpecs();
|
|
14004
14093
|
const surfaceSnapshots = loadSurfaceSnapshots();
|
|
14005
14094
|
const codeModel = buildCodeModel(implementations, getProjectRoot());
|
|
14006
|
-
const statusBearing = treatAllAsComplete ? [...subsystems, ...components, ...interfaces, ...implementations] :
|
|
14095
|
+
const statusBearing = treatAllAsComplete ? [...subsystems, ...components, ...interfaces, ...implementations] : settledStatusBearing({ subsystems, components, interfaces, implementations });
|
|
14007
14096
|
const statusSnapshot = statusBearing.map((s) => s.status);
|
|
14008
14097
|
for (const s of statusBearing) s.status = "complete";
|
|
14009
14098
|
try {
|
|
@@ -14125,10 +14214,34 @@ function validateSddTree(rulesOrOptions, projectType = "backend") {
|
|
|
14125
14214
|
});
|
|
14126
14215
|
}
|
|
14127
14216
|
}
|
|
14217
|
+
function settledStatusBearing(loaded) {
|
|
14218
|
+
let settled;
|
|
14219
|
+
try {
|
|
14220
|
+
settled = settledSpecPaths();
|
|
14221
|
+
} catch {
|
|
14222
|
+
return [];
|
|
14223
|
+
}
|
|
14224
|
+
if (!settled || settled.size === 0) return [];
|
|
14225
|
+
const root = getProjectRoot();
|
|
14226
|
+
const index = scanAllSpecs();
|
|
14227
|
+
const rel2 = (abs) => path14.relative(root, abs).split(path14.sep).join("/");
|
|
14228
|
+
const out = [];
|
|
14229
|
+
const take = (specs, paths) => {
|
|
14230
|
+
for (const spec of specs) {
|
|
14231
|
+
const p = paths[spec.id];
|
|
14232
|
+
if (p && settled.has(rel2(p))) out.push(spec);
|
|
14233
|
+
}
|
|
14234
|
+
};
|
|
14235
|
+
take(loaded.subsystems, index.paths.subsystem);
|
|
14236
|
+
take(loaded.components, index.paths.component);
|
|
14237
|
+
take(loaded.interfaces, index.paths.interface);
|
|
14238
|
+
take(loaded.implementations, index.paths.implementation);
|
|
14239
|
+
return out;
|
|
14240
|
+
}
|
|
14128
14241
|
function validateAsComplete(options) {
|
|
14129
14242
|
return validateSddTree({ ...options ?? {}, treatAllAsComplete: true });
|
|
14130
14243
|
}
|
|
14131
|
-
var SUBPROJECT_REFERENCE_CODES, SUBPROJECT_CONFORMANCE_CODES;
|
|
14244
|
+
var path14, SUBPROJECT_REFERENCE_CODES, SUBPROJECT_CONFORMANCE_CODES;
|
|
14132
14245
|
var init_validation = __esm({
|
|
14133
14246
|
"src/core/validation.ts"() {
|
|
14134
14247
|
"use strict";
|
|
@@ -14142,6 +14255,8 @@ var init_validation = __esm({
|
|
|
14142
14255
|
init_source_analysis();
|
|
14143
14256
|
init_specs2();
|
|
14144
14257
|
init_fs();
|
|
14258
|
+
path14 = __toESM(require("path"));
|
|
14259
|
+
init_baseline();
|
|
14145
14260
|
SUBPROJECT_REFERENCE_CODES = /* @__PURE__ */ new Set([
|
|
14146
14261
|
"UNDEFINED_TYPE_REFERENCE",
|
|
14147
14262
|
"INVALID_DEPENDENCY_REFERENCE",
|
|
@@ -14471,8 +14586,8 @@ function generateSequenceDiagram(componentId, methodName, options) {
|
|
|
14471
14586
|
const steps = [...methodImpl.narrative].sort((a, b) => a.stepNumber - b.stepNumber);
|
|
14472
14587
|
for (const step of steps) {
|
|
14473
14588
|
for (const par of parallelArms) {
|
|
14474
|
-
const
|
|
14475
|
-
if (
|
|
14589
|
+
const sep6 = par.sepByStep.get(step.stepNumber);
|
|
14590
|
+
if (sep6 !== void 0) lines.push(` and ${escapeLabel(sep6)}`);
|
|
14476
14591
|
}
|
|
14477
14592
|
switch (step.type) {
|
|
14478
14593
|
case "local":
|
|
@@ -14766,16 +14881,16 @@ function relativizeId(id, prefix) {
|
|
|
14766
14881
|
return `${"super::".repeat(prefixParts.length - common)}${idParts.slice(common).join("::")}`;
|
|
14767
14882
|
}
|
|
14768
14883
|
function isWithin(dir, file) {
|
|
14769
|
-
const d =
|
|
14770
|
-
const f =
|
|
14771
|
-
return f === d || f.startsWith(d +
|
|
14884
|
+
const d = path15.resolve(dir);
|
|
14885
|
+
const f = path15.resolve(file);
|
|
14886
|
+
return f === d || f.startsWith(d + path15.sep);
|
|
14772
14887
|
}
|
|
14773
14888
|
function projectPathEscapesRoot(projectRoot, projectPath, resolvedChildDir) {
|
|
14774
|
-
return
|
|
14889
|
+
return path15.isAbsolute(projectPath) || !isWithin(projectRoot, resolvedChildDir);
|
|
14775
14890
|
}
|
|
14776
14891
|
function assertContainedProjectPath(projectRoot, projectPath) {
|
|
14777
|
-
const root =
|
|
14778
|
-
const resolved =
|
|
14892
|
+
const root = path15.resolve(projectRoot);
|
|
14893
|
+
const resolved = path15.resolve(root, projectPath);
|
|
14779
14894
|
if (projectPathEscapesRoot(root, projectPath, resolved)) {
|
|
14780
14895
|
throw new Error(
|
|
14781
14896
|
`projectPath "${projectPath}" must resolve within the project root "${root}", but resolves to "${resolved}"; absolute paths and ../-escaping paths are rejected so a chained subproject is always contained by its parent.`
|
|
@@ -14786,11 +14901,11 @@ function assertContainedProjectPath(projectRoot, projectPath) {
|
|
|
14786
14901
|
function findChainingParent(childRoot) {
|
|
14787
14902
|
let childResolved;
|
|
14788
14903
|
try {
|
|
14789
|
-
childResolved =
|
|
14904
|
+
childResolved = path15.resolve(childRoot);
|
|
14790
14905
|
} catch {
|
|
14791
14906
|
return null;
|
|
14792
14907
|
}
|
|
14793
|
-
let dir =
|
|
14908
|
+
let dir = path15.dirname(childResolved);
|
|
14794
14909
|
for (let hops = 0; hops < 32; hops++) {
|
|
14795
14910
|
const specsDir = aiPathsAt(dir).specsDir();
|
|
14796
14911
|
if (pathExists(specsDir)) {
|
|
@@ -14805,7 +14920,7 @@ function findChainingParent(childRoot) {
|
|
|
14805
14920
|
const projectPath = raw.projectPath;
|
|
14806
14921
|
if (typeof projectPath === "string" && projectPath.trim() !== "") {
|
|
14807
14922
|
try {
|
|
14808
|
-
if (
|
|
14923
|
+
if (path15.resolve(dir, projectPath) === childResolved) {
|
|
14809
14924
|
const id = raw.id;
|
|
14810
14925
|
return { parentRoot: dir, subsystemId: typeof id === "string" ? id : "?" };
|
|
14811
14926
|
}
|
|
@@ -14815,7 +14930,7 @@ function findChainingParent(childRoot) {
|
|
|
14815
14930
|
}
|
|
14816
14931
|
}
|
|
14817
14932
|
}
|
|
14818
|
-
const up =
|
|
14933
|
+
const up = path15.dirname(dir);
|
|
14819
14934
|
if (up === dir) break;
|
|
14820
14935
|
dir = up;
|
|
14821
14936
|
}
|
|
@@ -14920,18 +15035,18 @@ function findOwner(id, components) {
|
|
|
14920
15035
|
}) ?? null;
|
|
14921
15036
|
}
|
|
14922
15037
|
function moveComponentFolder(fromDir, toDir) {
|
|
14923
|
-
if (
|
|
14924
|
-
if (!
|
|
14925
|
-
ensureDir(
|
|
14926
|
-
|
|
15038
|
+
if (path15.normalize(fromDir) === path15.normalize(toDir)) return false;
|
|
15039
|
+
if (!fs10.existsSync(fromDir) || fs10.existsSync(toDir)) return false;
|
|
15040
|
+
ensureDir(path15.dirname(toDir));
|
|
15041
|
+
fs10.renameSync(fromDir, toDir);
|
|
14927
15042
|
return true;
|
|
14928
15043
|
}
|
|
14929
15044
|
function cleanEmptyDirs(filePath, specsRoot) {
|
|
14930
|
-
let dir =
|
|
15045
|
+
let dir = path15.dirname(filePath);
|
|
14931
15046
|
while (dir !== specsRoot && dir.startsWith(specsRoot)) {
|
|
14932
|
-
if (
|
|
14933
|
-
|
|
14934
|
-
dir =
|
|
15047
|
+
if (fs10.existsSync(dir) && fs10.readdirSync(dir).length === 0) {
|
|
15048
|
+
fs10.rmdirSync(dir);
|
|
15049
|
+
dir = path15.dirname(dir);
|
|
14935
15050
|
} else {
|
|
14936
15051
|
break;
|
|
14937
15052
|
}
|
|
@@ -14950,13 +15065,13 @@ function parseOrThrow(schema, value, kind, id) {
|
|
|
14950
15065
|
function computeSpecTreeSignature(dirs) {
|
|
14951
15066
|
const parts = [];
|
|
14952
15067
|
for (const dir of dirs) {
|
|
14953
|
-
if (!
|
|
15068
|
+
if (!fs10.existsSync(dir)) {
|
|
14954
15069
|
parts.push(`${dir}:missing`);
|
|
14955
15070
|
continue;
|
|
14956
15071
|
}
|
|
14957
15072
|
for (const f of listFilesRecursive(dir, ".yaml")) {
|
|
14958
15073
|
try {
|
|
14959
|
-
const st =
|
|
15074
|
+
const st = fs10.statSync(f);
|
|
14960
15075
|
parts.push(`${f}:${st.mtimeMs}:${st.size}`);
|
|
14961
15076
|
} catch {
|
|
14962
15077
|
parts.push(`${f}:gone`);
|
|
@@ -14966,7 +15081,7 @@ function computeSpecTreeSignature(dirs) {
|
|
|
14966
15081
|
return parts.join("|");
|
|
14967
15082
|
}
|
|
14968
15083
|
function workspaceFor(rootDir) {
|
|
14969
|
-
const key =
|
|
15084
|
+
const key = path15.resolve(rootDir);
|
|
14970
15085
|
let ws = workspaces.get(key);
|
|
14971
15086
|
if (!ws) {
|
|
14972
15087
|
ws = new SpecWorkspace(key);
|
|
@@ -15105,7 +15220,7 @@ function readLockState() {
|
|
|
15105
15220
|
return { state: stateIdEquals(record.stateId, current2) ? "locked" : "stale", record, current: current2 };
|
|
15106
15221
|
}
|
|
15107
15222
|
function computeStateIdAt(root) {
|
|
15108
|
-
const resolved =
|
|
15223
|
+
const resolved = path15.resolve(root);
|
|
15109
15224
|
return runWithProjectRoot(resolved, () => {
|
|
15110
15225
|
workspaceFor(resolved).invalidate();
|
|
15111
15226
|
const system = loadSystemSpec();
|
|
@@ -15135,12 +15250,15 @@ function collectPromotableSpecs(scopeSubsystem) {
|
|
|
15135
15250
|
function applySpecStatus(kind, id, status) {
|
|
15136
15251
|
current().applySpecStatus(kind, id, status);
|
|
15137
15252
|
}
|
|
15253
|
+
function specPathsInScope(scopeSubsystem) {
|
|
15254
|
+
return current().specPathsInScope(scopeSubsystem);
|
|
15255
|
+
}
|
|
15138
15256
|
function snapshotSpecFiles() {
|
|
15139
15257
|
return current().snapshotSpecFiles();
|
|
15140
15258
|
}
|
|
15141
15259
|
function restoreSpecFiles(snapshot) {
|
|
15142
15260
|
for (const [file, content] of snapshot) {
|
|
15143
|
-
|
|
15261
|
+
fs10.writeFileSync(file, content);
|
|
15144
15262
|
}
|
|
15145
15263
|
}
|
|
15146
15264
|
function findLegacySpecFiles() {
|
|
@@ -15149,12 +15267,12 @@ function findLegacySpecFiles() {
|
|
|
15149
15267
|
function updateSpec(kind, id, delta, hooks) {
|
|
15150
15268
|
return current().updateSpec(kind, id, delta, hooks);
|
|
15151
15269
|
}
|
|
15152
|
-
var
|
|
15270
|
+
var fs10, path15, SIGNATURE_TTL_MS, SpecWorkspace, workspaces;
|
|
15153
15271
|
var init_specs2 = __esm({
|
|
15154
15272
|
"src/core/specs.ts"() {
|
|
15155
15273
|
"use strict";
|
|
15156
|
-
|
|
15157
|
-
|
|
15274
|
+
fs10 = __toESM(require("fs"));
|
|
15275
|
+
path15 = __toESM(require("path"));
|
|
15158
15276
|
init_loader();
|
|
15159
15277
|
init_fs();
|
|
15160
15278
|
init_statehash();
|
|
@@ -15175,7 +15293,7 @@ var init_specs2 = __esm({
|
|
|
15175
15293
|
this.rootSubsystems = /* @__PURE__ */ new Set();
|
|
15176
15294
|
this.scanVisitedSpecDirs = [];
|
|
15177
15295
|
this.loaderIssues = [];
|
|
15178
|
-
this.rootDir =
|
|
15296
|
+
this.rootDir = path15.resolve(rootDir);
|
|
15179
15297
|
this.paths = aiPathsAt(this.rootDir);
|
|
15180
15298
|
}
|
|
15181
15299
|
invalidate() {
|
|
@@ -15202,7 +15320,7 @@ var init_specs2 = __esm({
|
|
|
15202
15320
|
this.rootSubsystems.clear();
|
|
15203
15321
|
this.cachedRecursive = recursive;
|
|
15204
15322
|
this.scanVisitedSpecDirs = [];
|
|
15205
|
-
const visited = /* @__PURE__ */ new Set([
|
|
15323
|
+
const visited = /* @__PURE__ */ new Set([path15.resolve(this.rootDir)]);
|
|
15206
15324
|
const maxDepth = typeof recursive === "number" ? recursive : recursive ? Infinity : 0;
|
|
15207
15325
|
this.cachedIndex = this.scanSpecsForProject(this.rootDir, "", visited, maxDepth, 0);
|
|
15208
15326
|
this.cachedSpecDirs = this.scanVisitedSpecDirs;
|
|
@@ -15217,10 +15335,10 @@ var init_specs2 = __esm({
|
|
|
15217
15335
|
this.scanVisitedSpecDirs.push(specsDir);
|
|
15218
15336
|
if (!pathExists(specsDir)) return index;
|
|
15219
15337
|
const files = listFilesRecursive(specsDir, ".yaml");
|
|
15220
|
-
const systemYaml =
|
|
15338
|
+
const systemYaml = path15.normalize(projectPaths.specsSystem());
|
|
15221
15339
|
const localSubprojects = [];
|
|
15222
15340
|
for (const file of files) {
|
|
15223
|
-
const normFile =
|
|
15341
|
+
const normFile = path15.normalize(file);
|
|
15224
15342
|
if (normFile === systemYaml) continue;
|
|
15225
15343
|
let detectedType = "spec";
|
|
15226
15344
|
try {
|
|
@@ -15230,7 +15348,7 @@ var init_specs2 = __esm({
|
|
|
15230
15348
|
severity: "error",
|
|
15231
15349
|
code: "INVALID_YAML",
|
|
15232
15350
|
message: `Spec file "${file}" is not a valid YAML object or is empty.`,
|
|
15233
|
-
specId:
|
|
15351
|
+
specId: path15.basename(file, ".yaml")
|
|
15234
15352
|
});
|
|
15235
15353
|
continue;
|
|
15236
15354
|
}
|
|
@@ -15262,8 +15380,8 @@ var init_specs2 = __esm({
|
|
|
15262
15380
|
detectedType = "implementation";
|
|
15263
15381
|
const parsed = ImplementationSpecSchema.parse(raw);
|
|
15264
15382
|
if (parsed.sourcePath) {
|
|
15265
|
-
const absSourcePath =
|
|
15266
|
-
parsed.sourcePath =
|
|
15383
|
+
const absSourcePath = path15.resolve(projectDir, parsed.sourcePath);
|
|
15384
|
+
parsed.sourcePath = path15.relative(projectDir, absSourcePath).replace(/\\/g, "/");
|
|
15267
15385
|
}
|
|
15268
15386
|
index.implementations.push(parsed);
|
|
15269
15387
|
index.paths.implementation[parsed.id] = file;
|
|
@@ -15285,11 +15403,11 @@ var init_specs2 = __esm({
|
|
|
15285
15403
|
severity: "error",
|
|
15286
15404
|
code: "UNKNOWN_SPEC_TYPE",
|
|
15287
15405
|
message: `Spec file "${file}" does not match any recognized L1-L4 schema structure.`,
|
|
15288
|
-
specId:
|
|
15406
|
+
specId: path15.basename(file, ".yaml")
|
|
15289
15407
|
});
|
|
15290
15408
|
}
|
|
15291
15409
|
} catch (e) {
|
|
15292
|
-
const filename =
|
|
15410
|
+
const filename = path15.basename(file, ".yaml");
|
|
15293
15411
|
this.loaderIssues.push({
|
|
15294
15412
|
severity: "error",
|
|
15295
15413
|
code: "SCHEMA_VALIDATION_ERROR",
|
|
@@ -15387,7 +15505,7 @@ var init_specs2 = __esm({
|
|
|
15387
15505
|
}
|
|
15388
15506
|
if (currentDepth < maxDepth) {
|
|
15389
15507
|
for (const subproj of localSubprojects) {
|
|
15390
|
-
const childDir =
|
|
15508
|
+
const childDir = path15.resolve(projectDir, subproj.projectPath);
|
|
15391
15509
|
if (projectPathEscapesRoot(this.rootDir, subproj.projectPath, childDir)) {
|
|
15392
15510
|
this.loaderIssues.push({
|
|
15393
15511
|
severity: "error",
|
|
@@ -15406,7 +15524,7 @@ var init_specs2 = __esm({
|
|
|
15406
15524
|
});
|
|
15407
15525
|
continue;
|
|
15408
15526
|
}
|
|
15409
|
-
if (!
|
|
15527
|
+
if (!fs10.existsSync(childDir)) {
|
|
15410
15528
|
this.loaderIssues.push({
|
|
15411
15529
|
severity: "error",
|
|
15412
15530
|
code: "SUBPROJECT_NOT_FOUND",
|
|
@@ -15449,7 +15567,7 @@ var init_specs2 = __esm({
|
|
|
15449
15567
|
const index = this.scanAll();
|
|
15450
15568
|
const sub = index.subsystems.find((s) => s.id === currentPrefix);
|
|
15451
15569
|
if (sub && sub.projectPath) {
|
|
15452
|
-
const nextDir =
|
|
15570
|
+
const nextDir = path15.resolve(currentDir, sub.projectPath);
|
|
15453
15571
|
if (projectPathEscapesRoot(this.rootDir, sub.projectPath, nextDir)) {
|
|
15454
15572
|
this.loaderIssues.push({
|
|
15455
15573
|
severity: "error",
|
|
@@ -15501,9 +15619,9 @@ var init_specs2 = __esm({
|
|
|
15501
15619
|
return index.paths.subsystem[matches2[0]];
|
|
15502
15620
|
}
|
|
15503
15621
|
if (pathExists(this.paths.specsSubsystemsDir()) && listFiles(this.paths.specsSubsystemsDir(), ".yaml").length > 0) {
|
|
15504
|
-
return
|
|
15622
|
+
return path15.join(this.paths.specsSubsystemsDir(), `${id}.yaml`);
|
|
15505
15623
|
}
|
|
15506
|
-
return
|
|
15624
|
+
return path15.join(this.paths.specsDir(), id, ".index.yaml");
|
|
15507
15625
|
}
|
|
15508
15626
|
getComponentPath(id, subsystemId) {
|
|
15509
15627
|
const index = this.scanAll();
|
|
@@ -15523,21 +15641,21 @@ var init_specs2 = __esm({
|
|
|
15523
15641
|
if (owner) {
|
|
15524
15642
|
const ownerPath = index.paths.component[owner.id];
|
|
15525
15643
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
15526
|
-
return
|
|
15644
|
+
return path15.join(path15.dirname(ownerPath), id, ".index.yaml");
|
|
15527
15645
|
}
|
|
15528
15646
|
}
|
|
15529
15647
|
if (subsystemId) {
|
|
15530
15648
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
15531
|
-
const subDir =
|
|
15649
|
+
const subDir = path15.dirname(subPath);
|
|
15532
15650
|
if (subPath.endsWith(".index.yaml")) {
|
|
15533
|
-
return
|
|
15651
|
+
return path15.join(subDir, id, ".index.yaml");
|
|
15534
15652
|
}
|
|
15535
15653
|
}
|
|
15536
15654
|
if (pathExists(this.paths.specsComponentsDir()) && listFiles(this.paths.specsComponentsDir(), ".yaml").length > 0) {
|
|
15537
|
-
return
|
|
15655
|
+
return path15.join(this.paths.specsComponentsDir(), `${id}.yaml`);
|
|
15538
15656
|
}
|
|
15539
15657
|
const targetSubsystem = subsystemId || "default";
|
|
15540
|
-
return
|
|
15658
|
+
return path15.join(this.paths.specsDir(), targetSubsystem, id, ".index.yaml");
|
|
15541
15659
|
}
|
|
15542
15660
|
getInterfacePath(id, componentId) {
|
|
15543
15661
|
const index = this.scanAll();
|
|
@@ -15563,16 +15681,16 @@ var init_specs2 = __esm({
|
|
|
15563
15681
|
}
|
|
15564
15682
|
if (componentId) {
|
|
15565
15683
|
const compPath = this.getComponentPath(componentId);
|
|
15566
|
-
const compDir =
|
|
15684
|
+
const compDir = path15.dirname(compPath);
|
|
15567
15685
|
if (compPath.endsWith(".index.yaml")) {
|
|
15568
|
-
return
|
|
15686
|
+
return path15.join(compDir, ".interface.yaml");
|
|
15569
15687
|
}
|
|
15570
15688
|
}
|
|
15571
15689
|
if (pathExists(this.paths.specsInterfacesDir()) && listFiles(this.paths.specsInterfacesDir(), ".yaml").length > 0) {
|
|
15572
|
-
return
|
|
15690
|
+
return path15.join(this.paths.specsInterfacesDir(), `${id}.yaml`);
|
|
15573
15691
|
}
|
|
15574
15692
|
const targetComponent = componentId || "default";
|
|
15575
|
-
return
|
|
15693
|
+
return path15.join(this.paths.specsDir(), "default", targetComponent, ".interface.yaml");
|
|
15576
15694
|
}
|
|
15577
15695
|
getImplementationPath(id, contractId) {
|
|
15578
15696
|
const index = this.scanAll();
|
|
@@ -15598,16 +15716,16 @@ var init_specs2 = __esm({
|
|
|
15598
15716
|
}
|
|
15599
15717
|
if (contractId) {
|
|
15600
15718
|
const intfPath = this.getInterfacePath(contractId);
|
|
15601
|
-
const intfDir =
|
|
15719
|
+
const intfDir = path15.dirname(intfPath);
|
|
15602
15720
|
if (intfPath.endsWith(".interface.yaml")) {
|
|
15603
|
-
return
|
|
15721
|
+
return path15.join(intfDir, ".implementation.yaml");
|
|
15604
15722
|
}
|
|
15605
15723
|
}
|
|
15606
15724
|
if (pathExists(this.paths.specsImplementationsDir()) && listFiles(this.paths.specsImplementationsDir(), ".yaml").length > 0) {
|
|
15607
|
-
return
|
|
15725
|
+
return path15.join(this.paths.specsImplementationsDir(), `${id}.yaml`);
|
|
15608
15726
|
}
|
|
15609
15727
|
const targetContract = contractId ? contractId.replace(/^i/, "") : "default";
|
|
15610
|
-
return
|
|
15728
|
+
return path15.join(this.paths.specsDir(), "default", targetContract, ".implementation.yaml");
|
|
15611
15729
|
}
|
|
15612
15730
|
getTypePath(id, subsystemId, group) {
|
|
15613
15731
|
const index = this.scanAll();
|
|
@@ -15638,7 +15756,7 @@ var init_specs2 = __esm({
|
|
|
15638
15756
|
const groupPath = index.paths.group[targetGroup] || index.paths.group[plainGroup];
|
|
15639
15757
|
if (groupPath) {
|
|
15640
15758
|
const localId2 = id.split("::").pop();
|
|
15641
|
-
return
|
|
15759
|
+
return path15.join(path15.dirname(groupPath), `${localId2}.yaml`);
|
|
15642
15760
|
}
|
|
15643
15761
|
}
|
|
15644
15762
|
let localId = id;
|
|
@@ -15651,12 +15769,12 @@ var init_specs2 = __esm({
|
|
|
15651
15769
|
}
|
|
15652
15770
|
if (subsystemId) {
|
|
15653
15771
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
15654
|
-
const subDir =
|
|
15772
|
+
const subDir = path15.dirname(subPath);
|
|
15655
15773
|
if (subPath.endsWith(".index.yaml")) {
|
|
15656
|
-
return
|
|
15774
|
+
return path15.join(subDir, "types", `${localId}.yaml`);
|
|
15657
15775
|
}
|
|
15658
15776
|
}
|
|
15659
|
-
return
|
|
15777
|
+
return path15.join(this.paths.specsTypesDir(), `${localId}.yaml`);
|
|
15660
15778
|
}
|
|
15661
15779
|
getGroupPath(id, subsystemId) {
|
|
15662
15780
|
const index = this.scanAll();
|
|
@@ -15690,12 +15808,12 @@ var init_specs2 = __esm({
|
|
|
15690
15808
|
}
|
|
15691
15809
|
if (subsystemId) {
|
|
15692
15810
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
15693
|
-
const subDir =
|
|
15811
|
+
const subDir = path15.dirname(subPath);
|
|
15694
15812
|
if (subPath.endsWith(".index.yaml")) {
|
|
15695
|
-
return
|
|
15813
|
+
return path15.join(subDir, "types", localId, ".index.yaml");
|
|
15696
15814
|
}
|
|
15697
15815
|
}
|
|
15698
|
-
return
|
|
15816
|
+
return path15.join(this.paths.specsTypesDir(), localId, ".index.yaml");
|
|
15699
15817
|
}
|
|
15700
15818
|
// -------------------------------------------------------------------------
|
|
15701
15819
|
// Level 0: System
|
|
@@ -15718,7 +15836,7 @@ var init_specs2 = __esm({
|
|
|
15718
15836
|
}
|
|
15719
15837
|
saveSystemSpec(spec) {
|
|
15720
15838
|
const p = this.paths.specsSystem();
|
|
15721
|
-
ensureDir(
|
|
15839
|
+
ensureDir(path15.dirname(p));
|
|
15722
15840
|
writeYamlFile(p, parseOrThrow(SystemSpecSchema, spec, "system", spec.name));
|
|
15723
15841
|
invalidateSpecCache();
|
|
15724
15842
|
}
|
|
@@ -15836,7 +15954,7 @@ var init_specs2 = __esm({
|
|
|
15836
15954
|
}
|
|
15837
15955
|
saveSubsystemSpec(spec) {
|
|
15838
15956
|
const p = this.getSubsystemPath(spec.id);
|
|
15839
|
-
ensureDir(
|
|
15957
|
+
ensureDir(path15.dirname(p));
|
|
15840
15958
|
const { prefix } = splitNamespace(spec.id);
|
|
15841
15959
|
if (!prefix && spec.projectPath && spec.projectPath.trim() !== "") {
|
|
15842
15960
|
assertContainedProjectPath(this.rootDir, spec.projectPath);
|
|
@@ -15867,9 +15985,9 @@ var init_specs2 = __esm({
|
|
|
15867
15985
|
}
|
|
15868
15986
|
deleteSubsystemSpec(id) {
|
|
15869
15987
|
const p = this.getSubsystemPath(id);
|
|
15870
|
-
if (!
|
|
15871
|
-
|
|
15872
|
-
cleanEmptyDirs(p,
|
|
15988
|
+
if (!fs10.existsSync(p)) return false;
|
|
15989
|
+
fs10.unlinkSync(p);
|
|
15990
|
+
cleanEmptyDirs(p, path15.resolve(this.paths.specsDir()));
|
|
15873
15991
|
invalidateSpecCache();
|
|
15874
15992
|
return true;
|
|
15875
15993
|
}
|
|
@@ -15902,7 +16020,7 @@ var init_specs2 = __esm({
|
|
|
15902
16020
|
saveComponentSpec(spec, opts) {
|
|
15903
16021
|
const notices = [];
|
|
15904
16022
|
const p = this.getComponentPath(spec.id, spec.subsystem);
|
|
15905
|
-
ensureDir(
|
|
16023
|
+
ensureDir(path15.dirname(p));
|
|
15906
16024
|
const specToWrite = this.prepareComponentForWrite(spec);
|
|
15907
16025
|
const existing = this.loadComponentSpec(spec.id);
|
|
15908
16026
|
if (existing) {
|
|
@@ -15919,7 +16037,7 @@ var init_specs2 = __esm({
|
|
|
15919
16037
|
const subsystemChanged = existing && existing.subsystem !== spec.subsystem && splitNamespace(existing.subsystem).localId !== splitNamespace(spec.subsystem).localId;
|
|
15920
16038
|
if (subsystemChanged && !p.endsWith(".index.yaml")) {
|
|
15921
16039
|
notices.push(
|
|
15922
|
-
`component "${spec.id}" already exists at ${
|
|
16040
|
+
`component "${spec.id}" already exists at ${path15.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}").`
|
|
15923
16041
|
);
|
|
15924
16042
|
}
|
|
15925
16043
|
specToWrite.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -15930,9 +16048,9 @@ var init_specs2 = __esm({
|
|
|
15930
16048
|
}
|
|
15931
16049
|
deleteComponentSpec(id) {
|
|
15932
16050
|
const p = this.getComponentPath(id);
|
|
15933
|
-
if (!
|
|
15934
|
-
|
|
15935
|
-
cleanEmptyDirs(p,
|
|
16051
|
+
if (!fs10.existsSync(p)) return false;
|
|
16052
|
+
fs10.unlinkSync(p);
|
|
16053
|
+
cleanEmptyDirs(p, path15.resolve(this.paths.specsDir()));
|
|
15936
16054
|
invalidateSpecCache();
|
|
15937
16055
|
return true;
|
|
15938
16056
|
}
|
|
@@ -15945,12 +16063,12 @@ var init_specs2 = __esm({
|
|
|
15945
16063
|
if (owner) {
|
|
15946
16064
|
const ownerPath = index.paths.component[owner.id];
|
|
15947
16065
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
15948
|
-
const ownerSubDir =
|
|
15949
|
-
return
|
|
16066
|
+
const ownerSubDir = path15.dirname(this.getSubsystemPath(owner.subsystem));
|
|
16067
|
+
return path15.join(ownerSubDir, owner.id, comp.id);
|
|
15950
16068
|
}
|
|
15951
16069
|
}
|
|
15952
|
-
const subDir =
|
|
15953
|
-
return
|
|
16070
|
+
const subDir = path15.dirname(this.getSubsystemPath(comp.subsystem));
|
|
16071
|
+
return path15.join(subDir, comp.id);
|
|
15954
16072
|
}
|
|
15955
16073
|
/**
|
|
15956
16074
|
* Move component folders so the physical tree mirrors ownership: each owned
|
|
@@ -15966,7 +16084,7 @@ var init_specs2 = __esm({
|
|
|
15966
16084
|
if (!currentPath) continue;
|
|
15967
16085
|
const desiredDir = this.desiredComponentDir(comp, index);
|
|
15968
16086
|
if (!desiredDir) continue;
|
|
15969
|
-
if (moveComponentFolder(
|
|
16087
|
+
if (moveComponentFolder(path15.dirname(currentPath), desiredDir)) moved.push(comp.id);
|
|
15970
16088
|
}
|
|
15971
16089
|
if (moved.length) invalidateSpecCache();
|
|
15972
16090
|
return moved;
|
|
@@ -16022,7 +16140,7 @@ var init_specs2 = __esm({
|
|
|
16022
16140
|
if (!occupantId) return;
|
|
16023
16141
|
if (occupantId === id || splitNamespace(occupantId).localId === splitNamespace(id).localId) return;
|
|
16024
16142
|
throw new Error(
|
|
16025
|
-
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${
|
|
16143
|
+
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${path15.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.`
|
|
16026
16144
|
);
|
|
16027
16145
|
}
|
|
16028
16146
|
/** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */
|
|
@@ -16030,12 +16148,12 @@ var init_specs2 = __esm({
|
|
|
16030
16148
|
const notices = [];
|
|
16031
16149
|
const p = this.getInterfacePath(spec.id, spec.component);
|
|
16032
16150
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "interface", `component "${spec.component}"`);
|
|
16033
|
-
ensureDir(
|
|
16151
|
+
ensureDir(path15.dirname(p));
|
|
16034
16152
|
const specToWrite = this.prepareInterfaceForWrite(spec);
|
|
16035
16153
|
const existing = this.loadInterfaceSpec(spec.id);
|
|
16036
16154
|
if (existing && existing.component !== spec.component && splitNamespace(existing.component).localId !== splitNamespace(spec.component).localId) {
|
|
16037
16155
|
notices.push(
|
|
16038
|
-
`interface "${spec.id}" already exists at ${
|
|
16156
|
+
`interface "${spec.id}" already exists at ${path15.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.`
|
|
16039
16157
|
);
|
|
16040
16158
|
}
|
|
16041
16159
|
if (existing) {
|
|
@@ -16058,9 +16176,9 @@ var init_specs2 = __esm({
|
|
|
16058
16176
|
}
|
|
16059
16177
|
deleteInterfaceSpec(id) {
|
|
16060
16178
|
const p = this.getInterfacePath(id);
|
|
16061
|
-
if (!
|
|
16062
|
-
|
|
16063
|
-
cleanEmptyDirs(p,
|
|
16179
|
+
if (!fs10.existsSync(p)) return false;
|
|
16180
|
+
fs10.unlinkSync(p);
|
|
16181
|
+
cleanEmptyDirs(p, path15.resolve(this.paths.specsDir()));
|
|
16064
16182
|
invalidateSpecCache();
|
|
16065
16183
|
return true;
|
|
16066
16184
|
}
|
|
@@ -16094,12 +16212,12 @@ var init_specs2 = __esm({
|
|
|
16094
16212
|
const notices = [];
|
|
16095
16213
|
const p = this.getImplementationPath(spec.id, spec.contract);
|
|
16096
16214
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "implementation", `contract "${spec.contract}"`);
|
|
16097
|
-
ensureDir(
|
|
16215
|
+
ensureDir(path15.dirname(p));
|
|
16098
16216
|
const specToWrite = this.prepareImplementationForWrite(spec);
|
|
16099
16217
|
const existing = this.loadImplementationSpec(spec.id);
|
|
16100
16218
|
if (existing && existing.contract !== spec.contract && splitNamespace(existing.contract).localId !== splitNamespace(spec.contract).localId) {
|
|
16101
16219
|
notices.push(
|
|
16102
|
-
`implementation "${spec.id}" already exists at ${
|
|
16220
|
+
`implementation "${spec.id}" already exists at ${path15.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.`
|
|
16103
16221
|
);
|
|
16104
16222
|
}
|
|
16105
16223
|
if (existing) {
|
|
@@ -16115,9 +16233,9 @@ var init_specs2 = __esm({
|
|
|
16115
16233
|
}
|
|
16116
16234
|
deleteImplementationSpec(id) {
|
|
16117
16235
|
const p = this.getImplementationPath(id);
|
|
16118
|
-
if (!
|
|
16119
|
-
|
|
16120
|
-
cleanEmptyDirs(p,
|
|
16236
|
+
if (!fs10.existsSync(p)) return false;
|
|
16237
|
+
fs10.unlinkSync(p);
|
|
16238
|
+
cleanEmptyDirs(p, path15.resolve(this.paths.specsDir()));
|
|
16121
16239
|
invalidateSpecCache();
|
|
16122
16240
|
return true;
|
|
16123
16241
|
}
|
|
@@ -16142,11 +16260,11 @@ var init_specs2 = __esm({
|
|
|
16142
16260
|
const existing = this.loadTypeSpec(spec.id);
|
|
16143
16261
|
const group = spec.group || (existing ? existing.group : void 0);
|
|
16144
16262
|
const p = this.getTypePath(spec.id, spec.subsystem, group);
|
|
16145
|
-
ensureDir(
|
|
16263
|
+
ensureDir(path15.dirname(p));
|
|
16146
16264
|
const subsystemChanged = existing && (existing.subsystem ?? "") !== (spec.subsystem ?? "") && splitNamespace(existing.subsystem ?? "").localId !== splitNamespace(spec.subsystem ?? "").localId;
|
|
16147
16265
|
if (subsystemChanged) {
|
|
16148
16266
|
notices.push(
|
|
16149
|
-
`type "${spec.id}" already exists at ${
|
|
16267
|
+
`type "${spec.id}" already exists at ${path15.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)"}").`
|
|
16150
16268
|
);
|
|
16151
16269
|
}
|
|
16152
16270
|
if (spec.subsystem && (!existing || subsystemChanged) && !this.getSubsystemPath(spec.subsystem).endsWith(".index.yaml")) {
|
|
@@ -16169,9 +16287,9 @@ var init_specs2 = __esm({
|
|
|
16169
16287
|
deleteTypeSpec(id) {
|
|
16170
16288
|
const spec = this.loadTypeSpec(id);
|
|
16171
16289
|
const p = this.getTypePath(id, spec?.subsystem, spec?.group);
|
|
16172
|
-
if (!
|
|
16173
|
-
|
|
16174
|
-
cleanEmptyDirs(p,
|
|
16290
|
+
if (!fs10.existsSync(p)) return false;
|
|
16291
|
+
fs10.unlinkSync(p);
|
|
16292
|
+
cleanEmptyDirs(p, path15.resolve(this.paths.specsDir()));
|
|
16175
16293
|
invalidateSpecCache();
|
|
16176
16294
|
return true;
|
|
16177
16295
|
}
|
|
@@ -16186,7 +16304,7 @@ var init_specs2 = __esm({
|
|
|
16186
16304
|
}
|
|
16187
16305
|
saveGroupSpec(spec) {
|
|
16188
16306
|
const p = this.getGroupPath(spec.id);
|
|
16189
|
-
ensureDir(
|
|
16307
|
+
ensureDir(path15.dirname(p));
|
|
16190
16308
|
const specToWrite = this.prepareGroupForWrite(spec);
|
|
16191
16309
|
const existing = this.loadGroupSpec(spec.id);
|
|
16192
16310
|
if (existing) {
|
|
@@ -16198,9 +16316,9 @@ var init_specs2 = __esm({
|
|
|
16198
16316
|
}
|
|
16199
16317
|
deleteGroupSpec(id) {
|
|
16200
16318
|
const p = this.getGroupPath(id);
|
|
16201
|
-
if (!
|
|
16202
|
-
|
|
16203
|
-
cleanEmptyDirs(p,
|
|
16319
|
+
if (!fs10.existsSync(p)) return false;
|
|
16320
|
+
fs10.unlinkSync(p);
|
|
16321
|
+
cleanEmptyDirs(p, path15.resolve(this.paths.specsDir()));
|
|
16204
16322
|
invalidateSpecCache();
|
|
16205
16323
|
return true;
|
|
16206
16324
|
}
|
|
@@ -16248,6 +16366,50 @@ var init_specs2 = __esm({
|
|
|
16248
16366
|
}
|
|
16249
16367
|
return out;
|
|
16250
16368
|
}
|
|
16369
|
+
/**
|
|
16370
|
+
* Every spec FILE inside a subsystem scope (absolute paths), regardless of
|
|
16371
|
+
* status. `collectPromotableSpecs` answers a different question — which specs
|
|
16372
|
+
* are not yet complete — so it cannot stand in for this: a scoped approval
|
|
16373
|
+
* must cover the specs it approves whether or not they were already settled.
|
|
16374
|
+
*/
|
|
16375
|
+
specPathsInScope(scopeSubsystem) {
|
|
16376
|
+
const index = this.scanAll();
|
|
16377
|
+
const components = this.loadComponentSpecs();
|
|
16378
|
+
const interfaces = this.loadInterfaceSpecs();
|
|
16379
|
+
const implementations = this.loadImplementationSpecs();
|
|
16380
|
+
const inScope = (specSubsystem) => {
|
|
16381
|
+
if (!scopeSubsystem) return true;
|
|
16382
|
+
if (!specSubsystem) return false;
|
|
16383
|
+
return specSubsystem === scopeSubsystem || specSubsystem.startsWith(`${scopeSubsystem}::`);
|
|
16384
|
+
};
|
|
16385
|
+
const out = /* @__PURE__ */ new Set();
|
|
16386
|
+
const add = (p) => {
|
|
16387
|
+
if (p) out.add(path15.resolve(p));
|
|
16388
|
+
};
|
|
16389
|
+
for (const s of this.loadSubsystemSpecs()) {
|
|
16390
|
+
if (!scopeSubsystem || s.id === scopeSubsystem || s.id.startsWith(`${scopeSubsystem}::`)) {
|
|
16391
|
+
add(index.paths.subsystem[s.id]);
|
|
16392
|
+
}
|
|
16393
|
+
}
|
|
16394
|
+
for (const c of components) {
|
|
16395
|
+
if (inScope(c.subsystem)) add(index.paths.component[c.id]);
|
|
16396
|
+
}
|
|
16397
|
+
for (const i of interfaces) {
|
|
16398
|
+
const comp = components.find((c) => c.id === i.component);
|
|
16399
|
+
if (comp && inScope(comp.subsystem)) add(index.paths.interface[i.id]);
|
|
16400
|
+
}
|
|
16401
|
+
for (const m of implementations) {
|
|
16402
|
+
const intf = interfaces.find((i) => i.id === m.contract);
|
|
16403
|
+
const comp = intf ? components.find((c) => c.id === intf.component) : null;
|
|
16404
|
+
if (comp && inScope(comp.subsystem)) add(index.paths.implementation[m.id]);
|
|
16405
|
+
}
|
|
16406
|
+
if (!scopeSubsystem) {
|
|
16407
|
+
add(this.paths.specsSystem());
|
|
16408
|
+
for (const p of Object.values(index.paths.type)) add(p);
|
|
16409
|
+
for (const p of Object.values(index.paths.group)) add(p);
|
|
16410
|
+
}
|
|
16411
|
+
return [...out];
|
|
16412
|
+
}
|
|
16251
16413
|
/** Set a single spec's status (bumps updatedAt). Caller invalidates the cache. */
|
|
16252
16414
|
applySpecStatus(kind, id, status) {
|
|
16253
16415
|
switch (kind) {
|
|
@@ -16285,16 +16447,16 @@ var init_specs2 = __esm({
|
|
|
16285
16447
|
const files = /* @__PURE__ */ new Set();
|
|
16286
16448
|
const sysPath = this.paths.specsSystem();
|
|
16287
16449
|
if (pathExists(sysPath)) {
|
|
16288
|
-
files.add(
|
|
16450
|
+
files.add(path15.resolve(sysPath));
|
|
16289
16451
|
}
|
|
16290
16452
|
for (const group of Object.values(index.paths)) {
|
|
16291
16453
|
for (const file of Object.values(group)) {
|
|
16292
|
-
files.add(
|
|
16454
|
+
files.add(path15.resolve(file));
|
|
16293
16455
|
}
|
|
16294
16456
|
}
|
|
16295
16457
|
for (const file of files) {
|
|
16296
|
-
if (
|
|
16297
|
-
snapshot.set(file,
|
|
16458
|
+
if (fs10.existsSync(file)) {
|
|
16459
|
+
snapshot.set(file, fs10.readFileSync(file, "utf8"));
|
|
16298
16460
|
}
|
|
16299
16461
|
}
|
|
16300
16462
|
return snapshot;
|
|
@@ -16308,20 +16470,20 @@ var init_specs2 = __esm({
|
|
|
16308
16470
|
const files = listFilesRecursive(specsDir, ".yaml");
|
|
16309
16471
|
const legacy = [];
|
|
16310
16472
|
for (const f of files) {
|
|
16311
|
-
const base =
|
|
16312
|
-
const dir =
|
|
16473
|
+
const base = path15.basename(f);
|
|
16474
|
+
const dir = path15.dirname(f);
|
|
16313
16475
|
if (base === "system.yaml") {
|
|
16314
|
-
legacy.push({ path: f, expected:
|
|
16476
|
+
legacy.push({ path: f, expected: path15.join(dir, ".index.yaml") });
|
|
16315
16477
|
} else if (base === "subsystem.yaml") {
|
|
16316
|
-
legacy.push({ path: f, expected:
|
|
16478
|
+
legacy.push({ path: f, expected: path15.join(dir, ".index.yaml") });
|
|
16317
16479
|
} else if (base === "component.yaml") {
|
|
16318
|
-
legacy.push({ path: f, expected:
|
|
16480
|
+
legacy.push({ path: f, expected: path15.join(dir, ".index.yaml") });
|
|
16319
16481
|
} else if (base === "group.yaml") {
|
|
16320
|
-
legacy.push({ path: f, expected:
|
|
16482
|
+
legacy.push({ path: f, expected: path15.join(dir, ".index.yaml") });
|
|
16321
16483
|
} else if (base === "interface.yaml") {
|
|
16322
|
-
legacy.push({ path: f, expected:
|
|
16484
|
+
legacy.push({ path: f, expected: path15.join(dir, ".interface.yaml") });
|
|
16323
16485
|
} else if (base === "implementation.yaml") {
|
|
16324
|
-
legacy.push({ path: f, expected:
|
|
16486
|
+
legacy.push({ path: f, expected: path15.join(dir, ".implementation.yaml") });
|
|
16325
16487
|
}
|
|
16326
16488
|
}
|
|
16327
16489
|
return legacy;
|
|
@@ -16768,8 +16930,8 @@ __export(agent_resolver_exports, {
|
|
|
16768
16930
|
resolveAgentTopology: () => resolveAgentTopology
|
|
16769
16931
|
});
|
|
16770
16932
|
function listFilesRecursiveSafe(dirPath, ext) {
|
|
16771
|
-
if (!
|
|
16772
|
-
const nameLower =
|
|
16933
|
+
if (!fs11.existsSync(dirPath)) return [];
|
|
16934
|
+
const nameLower = path16.basename(dirPath).toLowerCase();
|
|
16773
16935
|
const IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
16774
16936
|
"node_modules",
|
|
16775
16937
|
"target",
|
|
@@ -16784,10 +16946,10 @@ function listFilesRecursiveSafe(dirPath, ext) {
|
|
|
16784
16946
|
".vscode"
|
|
16785
16947
|
]);
|
|
16786
16948
|
if (IGNORED_DIRS.has(nameLower)) return [];
|
|
16787
|
-
const entries =
|
|
16949
|
+
const entries = fs11.readdirSync(dirPath, { withFileTypes: true });
|
|
16788
16950
|
const files = [];
|
|
16789
16951
|
for (const entry of entries) {
|
|
16790
|
-
const fullPath =
|
|
16952
|
+
const fullPath = path16.join(dirPath, entry.name);
|
|
16791
16953
|
if (entry.isDirectory()) {
|
|
16792
16954
|
files.push(...listFilesRecursiveSafe(fullPath, ext));
|
|
16793
16955
|
} else if (entry.isFile() && entry.name.endsWith(ext)) {
|
|
@@ -16800,8 +16962,8 @@ function getProjectFiles(projectDir) {
|
|
|
16800
16962
|
let files = projectFilesCache.get(projectDir);
|
|
16801
16963
|
if (!files) {
|
|
16802
16964
|
files = [];
|
|
16803
|
-
const srcDir =
|
|
16804
|
-
const legacySrcDir =
|
|
16965
|
+
const srcDir = path16.join(projectDir, "src");
|
|
16966
|
+
const legacySrcDir = path16.join(projectDir, "legacy-src");
|
|
16805
16967
|
let searchDir = projectDir;
|
|
16806
16968
|
if (pathExists(srcDir)) {
|
|
16807
16969
|
searchDir = srcDir;
|
|
@@ -16816,7 +16978,7 @@ function getProjectFiles(projectDir) {
|
|
|
16816
16978
|
files.push(...listFilesRecursiveSafe(searchDir, ext));
|
|
16817
16979
|
}
|
|
16818
16980
|
const rootDir = getProjectRoot();
|
|
16819
|
-
files = files.map((f) =>
|
|
16981
|
+
files = files.map((f) => path16.relative(rootDir, f).replace(/\\/g, "/"));
|
|
16820
16982
|
projectFilesCache.set(projectDir, files);
|
|
16821
16983
|
}
|
|
16822
16984
|
return files;
|
|
@@ -16841,8 +17003,8 @@ function inferSourcePathForComponent(comp, subsystems) {
|
|
|
16841
17003
|
let bestFile = null;
|
|
16842
17004
|
let bestScore = -1;
|
|
16843
17005
|
for (const f of files) {
|
|
16844
|
-
const ext =
|
|
16845
|
-
const base =
|
|
17006
|
+
const ext = path16.extname(f);
|
|
17007
|
+
const base = path16.basename(f, ext).toLowerCase();
|
|
16846
17008
|
if (candidates.has(base)) {
|
|
16847
17009
|
let score = 0;
|
|
16848
17010
|
const normalizedPath = f.toLowerCase();
|
|
@@ -16938,7 +17100,7 @@ function resolveAgentTopology() {
|
|
|
16938
17100
|
});
|
|
16939
17101
|
for (const sub of subsystems) {
|
|
16940
17102
|
if (sub.projectPath) {
|
|
16941
|
-
const mountSpecPath =
|
|
17103
|
+
const mountSpecPath = path16.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/");
|
|
16942
17104
|
agents.push({
|
|
16943
17105
|
id: `${sub.id}-owner`,
|
|
16944
17106
|
name: `${sub.name} (chained subproject)`,
|
|
@@ -16960,9 +17122,9 @@ function resolveAgentTopology() {
|
|
|
16960
17122
|
}
|
|
16961
17123
|
const subComponents = components.filter((c) => c.subsystem === sub.id);
|
|
16962
17124
|
const ownedPaths = [];
|
|
16963
|
-
ownedPaths.push(
|
|
17125
|
+
ownedPaths.push(path16.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/"));
|
|
16964
17126
|
for (const c of subComponents) {
|
|
16965
|
-
ownedPaths.push(
|
|
17127
|
+
ownedPaths.push(path16.relative(getProjectRoot(), getComponentPath(c.id, sub.id)).replace(/\\/g, "/"));
|
|
16966
17128
|
}
|
|
16967
17129
|
if (!config.rules.generateComponentImplementers) {
|
|
16968
17130
|
for (const comp of subComponents) {
|
|
@@ -17035,10 +17197,10 @@ function resolveAgentTopology() {
|
|
|
17035
17197
|
}
|
|
17036
17198
|
const dependencies = comp.dependsOn.map((depId) => `${depId}-implementer`);
|
|
17037
17199
|
const readPaths = [
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
...compInterfaces.map((i) =>
|
|
17041
|
-
...compImpls.map((impl) =>
|
|
17200
|
+
path16.relative(getProjectRoot(), AI_PATHS.specsSystem()).replace(/\\/g, "/"),
|
|
17201
|
+
path16.relative(getProjectRoot(), getComponentPath(comp.id, comp.subsystem)).replace(/\\/g, "/"),
|
|
17202
|
+
...compInterfaces.map((i) => path16.relative(getProjectRoot(), getInterfacePath(i.id, comp.id)).replace(/\\/g, "/")),
|
|
17203
|
+
...compImpls.map((impl) => path16.relative(getProjectRoot(), getImplementationPath(impl.id, impl.contract)).replace(/\\/g, "/"))
|
|
17042
17204
|
];
|
|
17043
17205
|
agents.push({
|
|
17044
17206
|
id: `${comp.id}-implementer`,
|
|
@@ -17121,12 +17283,12 @@ ${guidance.trim()}
|
|
|
17121
17283
|
variantGuidance: record.variantGuidance || void 0
|
|
17122
17284
|
};
|
|
17123
17285
|
}
|
|
17124
|
-
var
|
|
17286
|
+
var path16, fs11, projectFilesCache, UnknownAgentError;
|
|
17125
17287
|
var init_agent_resolver = __esm({
|
|
17126
17288
|
"src/core/agent_resolver.ts"() {
|
|
17127
17289
|
"use strict";
|
|
17128
|
-
|
|
17129
|
-
|
|
17290
|
+
path16 = __toESM(require("path"));
|
|
17291
|
+
fs11 = __toESM(require("fs"));
|
|
17130
17292
|
init_loader();
|
|
17131
17293
|
init_fs();
|
|
17132
17294
|
init_errors();
|
|
@@ -17157,12 +17319,12 @@ __export(loader_exports, {
|
|
|
17157
17319
|
saveTopologyConfig: () => saveTopologyConfig
|
|
17158
17320
|
});
|
|
17159
17321
|
function aiPathsAt(rootDir) {
|
|
17160
|
-
const resolvedRoot =
|
|
17322
|
+
const resolvedRoot = path17.resolve(rootDir);
|
|
17161
17323
|
const aiDirAt = (...segments) => {
|
|
17162
|
-
const waiPath =
|
|
17163
|
-
const waironPath =
|
|
17164
|
-
const base = !
|
|
17165
|
-
return
|
|
17324
|
+
const waiPath = path17.join(resolvedRoot, ".wai");
|
|
17325
|
+
const waironPath = path17.join(resolvedRoot, ".wairon");
|
|
17326
|
+
const base = !fs12.existsSync(waiPath) && fs12.existsSync(waironPath) ? waironPath : waiPath;
|
|
17327
|
+
return path17.join(base, ...segments);
|
|
17166
17328
|
};
|
|
17167
17329
|
const specsDir = () => {
|
|
17168
17330
|
try {
|
|
@@ -17170,7 +17332,7 @@ function aiPathsAt(rootDir) {
|
|
|
17170
17332
|
if (pathExists(projConfig)) {
|
|
17171
17333
|
const raw = readYamlFile(projConfig);
|
|
17172
17334
|
if (raw && raw.paths && raw.paths.specsDir) {
|
|
17173
|
-
return
|
|
17335
|
+
return path17.resolve(resolvedRoot, raw.paths.specsDir);
|
|
17174
17336
|
}
|
|
17175
17337
|
}
|
|
17176
17338
|
} catch {
|
|
@@ -17191,12 +17353,12 @@ function aiPathsAt(rootDir) {
|
|
|
17191
17353
|
contextDomainsMd: () => aiDirAt("context", "domains.md"),
|
|
17192
17354
|
contextWaironGuideMd: () => aiDirAt("context", "wairon-guide.md"),
|
|
17193
17355
|
specsDir,
|
|
17194
|
-
specsSystem: () =>
|
|
17195
|
-
specsSubsystemsDir: () =>
|
|
17196
|
-
specsComponentsDir: () =>
|
|
17197
|
-
specsInterfacesDir: () =>
|
|
17198
|
-
specsImplementationsDir: () =>
|
|
17199
|
-
specsTypesDir: () =>
|
|
17356
|
+
specsSystem: () => path17.join(specsDir(), ".index.yaml"),
|
|
17357
|
+
specsSubsystemsDir: () => path17.join(specsDir(), "subsystems"),
|
|
17358
|
+
specsComponentsDir: () => path17.join(specsDir(), "components"),
|
|
17359
|
+
specsInterfacesDir: () => path17.join(specsDir(), "interfaces"),
|
|
17360
|
+
specsImplementationsDir: () => path17.join(specsDir(), "implementations"),
|
|
17361
|
+
specsTypesDir: () => path17.join(specsDir(), "types")
|
|
17200
17362
|
};
|
|
17201
17363
|
}
|
|
17202
17364
|
function isProjectInitialized() {
|
|
@@ -17239,12 +17401,12 @@ function loadTopologyConfig() {
|
|
|
17239
17401
|
function saveTopologyConfig(config) {
|
|
17240
17402
|
writeYamlFile(AI_PATHS.topologyConfig(), config);
|
|
17241
17403
|
}
|
|
17242
|
-
var
|
|
17404
|
+
var fs12, path17, AI_PATHS;
|
|
17243
17405
|
var init_loader = __esm({
|
|
17244
17406
|
"src/config/loader.ts"() {
|
|
17245
17407
|
"use strict";
|
|
17246
|
-
|
|
17247
|
-
|
|
17408
|
+
fs12 = __toESM(require("fs"));
|
|
17409
|
+
path17 = __toESM(require("path"));
|
|
17248
17410
|
init_fs();
|
|
17249
17411
|
init_yaml();
|
|
17250
17412
|
init_errors();
|
|
@@ -17284,7 +17446,7 @@ __export(domains_exports, {
|
|
|
17284
17446
|
resolveDomains: () => resolveDomains
|
|
17285
17447
|
});
|
|
17286
17448
|
function rel(p) {
|
|
17287
|
-
return
|
|
17449
|
+
return path19.relative(process.cwd(), p).replace(/\\/g, "/");
|
|
17288
17450
|
}
|
|
17289
17451
|
function deriveSubsystemDomains() {
|
|
17290
17452
|
const subsystems = loadSubsystemSpecs();
|
|
@@ -17334,11 +17496,11 @@ function removeFreeStandingDomain(id) {
|
|
|
17334
17496
|
config.domains.splice(idx, 1);
|
|
17335
17497
|
saveTopologyConfig(config);
|
|
17336
17498
|
}
|
|
17337
|
-
var
|
|
17499
|
+
var path19;
|
|
17338
17500
|
var init_domains = __esm({
|
|
17339
17501
|
"src/core/domains.ts"() {
|
|
17340
17502
|
"use strict";
|
|
17341
|
-
|
|
17503
|
+
path19 = __toESM(require("path"));
|
|
17342
17504
|
init_loader();
|
|
17343
17505
|
init_specs2();
|
|
17344
17506
|
init_errors();
|
|
@@ -17669,6 +17831,7 @@ __export(src_exports, {
|
|
|
17669
17831
|
skillExtendErrors: () => skillExtendErrors,
|
|
17670
17832
|
skillsDirForTarget: () => skillsDirForTarget,
|
|
17671
17833
|
snapshotSpecFiles: () => snapshotSpecFiles,
|
|
17834
|
+
specPathsInScope: () => specPathsInScope,
|
|
17672
17835
|
splitNamespace: () => splitNamespace,
|
|
17673
17836
|
stateIdEquals: () => stateIdEquals,
|
|
17674
17837
|
stateIdString: () => stateIdString,
|
|
@@ -17699,8 +17862,8 @@ init_defaults();
|
|
|
17699
17862
|
init_loader();
|
|
17700
17863
|
|
|
17701
17864
|
// src/core/detection.ts
|
|
17702
|
-
var
|
|
17703
|
-
var
|
|
17865
|
+
var fs13 = __toESM(require("fs"));
|
|
17866
|
+
var path18 = __toESM(require("path"));
|
|
17704
17867
|
init_defaults();
|
|
17705
17868
|
var PACKAGE_MARKERS = [
|
|
17706
17869
|
"package.json",
|
|
@@ -17752,7 +17915,7 @@ function deduplicateIds(candidates, existingIds = /* @__PURE__ */ new Set()) {
|
|
|
17752
17915
|
});
|
|
17753
17916
|
}
|
|
17754
17917
|
function parseGitmodules(filePath) {
|
|
17755
|
-
const content =
|
|
17918
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
17756
17919
|
const entries = [];
|
|
17757
17920
|
let current2 = {};
|
|
17758
17921
|
for (const line of content.split("\n")) {
|
|
@@ -17774,8 +17937,8 @@ function parseGitmodules(filePath) {
|
|
|
17774
17937
|
return entries;
|
|
17775
17938
|
}
|
|
17776
17939
|
function detectGitSubmodules(projectRoot) {
|
|
17777
|
-
const gitmodulesPath =
|
|
17778
|
-
if (!
|
|
17940
|
+
const gitmodulesPath = path18.join(projectRoot, ".gitmodules");
|
|
17941
|
+
if (!fs13.existsSync(gitmodulesPath)) return [];
|
|
17779
17942
|
return parseGitmodules(gitmodulesPath).map((entry) => ({
|
|
17780
17943
|
suggestedId: pathToId(entry.path),
|
|
17781
17944
|
suggestedName: pathToName(entry.path),
|
|
@@ -17793,18 +17956,18 @@ function walkForGit(projectRoot, currentDir, depth, results) {
|
|
|
17793
17956
|
if (depth > MAX_SCAN_DEPTH) return;
|
|
17794
17957
|
let entries;
|
|
17795
17958
|
try {
|
|
17796
|
-
entries =
|
|
17959
|
+
entries = fs13.readdirSync(currentDir, { withFileTypes: true });
|
|
17797
17960
|
} catch {
|
|
17798
17961
|
return;
|
|
17799
17962
|
}
|
|
17800
17963
|
for (const entry of entries) {
|
|
17801
17964
|
if (!entry.isDirectory()) continue;
|
|
17802
17965
|
if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
|
|
17803
|
-
const fullPath =
|
|
17804
|
-
const relPath = normalizePath3(
|
|
17966
|
+
const fullPath = path18.join(currentDir, entry.name);
|
|
17967
|
+
const relPath = normalizePath3(path18.relative(projectRoot, fullPath));
|
|
17805
17968
|
if (relPath === "" || relPath === ".") continue;
|
|
17806
|
-
const gitPath =
|
|
17807
|
-
if (
|
|
17969
|
+
const gitPath = path18.join(fullPath, ".git");
|
|
17970
|
+
if (fs13.existsSync(gitPath)) {
|
|
17808
17971
|
results.push({
|
|
17809
17972
|
suggestedId: pathToId(relPath),
|
|
17810
17973
|
suggestedName: pathToName(relPath),
|
|
@@ -17826,17 +17989,17 @@ function walkForPackages(projectRoot, currentDir, depth, results) {
|
|
|
17826
17989
|
if (depth > MAX_SCAN_DEPTH) return;
|
|
17827
17990
|
let entries;
|
|
17828
17991
|
try {
|
|
17829
|
-
entries =
|
|
17992
|
+
entries = fs13.readdirSync(currentDir, { withFileTypes: true });
|
|
17830
17993
|
} catch {
|
|
17831
17994
|
return;
|
|
17832
17995
|
}
|
|
17833
17996
|
for (const entry of entries) {
|
|
17834
17997
|
if (!entry.isDirectory()) continue;
|
|
17835
17998
|
if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
|
|
17836
|
-
const fullPath =
|
|
17837
|
-
const relPath = normalizePath3(
|
|
17999
|
+
const fullPath = path18.join(currentDir, entry.name);
|
|
18000
|
+
const relPath = normalizePath3(path18.relative(projectRoot, fullPath));
|
|
17838
18001
|
if (relPath === "" || relPath === ".") continue;
|
|
17839
|
-
const hasMarker = PACKAGE_MARKERS.some((m) =>
|
|
18002
|
+
const hasMarker = PACKAGE_MARKERS.some((m) => fs13.existsSync(path18.join(fullPath, m)));
|
|
17840
18003
|
if (hasMarker) {
|
|
17841
18004
|
results.push({
|
|
17842
18005
|
suggestedId: pathToId(relPath),
|
|
@@ -17850,8 +18013,8 @@ function walkForPackages(projectRoot, currentDir, depth, results) {
|
|
|
17850
18013
|
}
|
|
17851
18014
|
}
|
|
17852
18015
|
function pathToId(relPath) {
|
|
17853
|
-
const
|
|
17854
|
-
return
|
|
18016
|
+
const basename10 = path18.basename(relPath);
|
|
18017
|
+
return basename10.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
17855
18018
|
}
|
|
17856
18019
|
function pathToName(relPath) {
|
|
17857
18020
|
const id = pathToId(relPath);
|
|
@@ -17871,8 +18034,8 @@ init_rules();
|
|
|
17871
18034
|
init_specs2();
|
|
17872
18035
|
|
|
17873
18036
|
// src/core/provision.ts
|
|
17874
|
-
var
|
|
17875
|
-
var
|
|
18037
|
+
var fs14 = __toESM(require("fs"));
|
|
18038
|
+
var path20 = __toESM(require("path"));
|
|
17876
18039
|
init_specs2();
|
|
17877
18040
|
init_loader();
|
|
17878
18041
|
init_fs();
|
|
@@ -17920,7 +18083,7 @@ function provisionProject(name) {
|
|
|
17920
18083
|
function ensureProjectInitialized(fallbackName) {
|
|
17921
18084
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
17922
18085
|
const paths = aiPathsAt(getProjectRoot());
|
|
17923
|
-
const hasSystem =
|
|
18086
|
+
const hasSystem = fs14.existsSync(paths.specsSystem());
|
|
17924
18087
|
let name = fallbackName;
|
|
17925
18088
|
if (hasSystem) {
|
|
17926
18089
|
const existing = loadSystemSpec();
|
|
@@ -17928,7 +18091,7 @@ function ensureProjectInitialized(fallbackName) {
|
|
|
17928
18091
|
}
|
|
17929
18092
|
let wroteConfig = false;
|
|
17930
18093
|
let wroteSystem = false;
|
|
17931
|
-
if (!
|
|
18094
|
+
if (!fs14.existsSync(paths.projectConfig())) {
|
|
17932
18095
|
saveProjectConfig(defaultProjectConfig(name, now));
|
|
17933
18096
|
wroteConfig = true;
|
|
17934
18097
|
}
|
|
@@ -17957,11 +18120,11 @@ function promoteAllComplete() {
|
|
|
17957
18120
|
function walkChainedSubprojects(projectRoot, onChild) {
|
|
17958
18121
|
const visited = /* @__PURE__ */ new Set();
|
|
17959
18122
|
const walk = (dir) => {
|
|
17960
|
-
const resolved =
|
|
18123
|
+
const resolved = path20.resolve(dir);
|
|
17961
18124
|
if (visited.has(resolved)) return;
|
|
17962
18125
|
visited.add(resolved);
|
|
17963
18126
|
const specsDir = aiPathsAt(dir).specsDir();
|
|
17964
|
-
if (!
|
|
18127
|
+
if (!fs14.existsSync(specsDir)) return;
|
|
17965
18128
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
17966
18129
|
let raw;
|
|
17967
18130
|
try {
|
|
@@ -17979,7 +18142,7 @@ function walkChainedSubprojects(projectRoot, onChild) {
|
|
|
17979
18142
|
continue;
|
|
17980
18143
|
}
|
|
17981
18144
|
const id = raw.id;
|
|
17982
|
-
onChild(childDir, typeof id === "string" ? id :
|
|
18145
|
+
onChild(childDir, typeof id === "string" ? id : path20.basename(childDir));
|
|
17983
18146
|
walk(childDir);
|
|
17984
18147
|
}
|
|
17985
18148
|
};
|
|
@@ -17988,7 +18151,7 @@ function walkChainedSubprojects(projectRoot, onChild) {
|
|
|
17988
18151
|
function listDirectChainedSubprojects(projectRoot) {
|
|
17989
18152
|
const out = [];
|
|
17990
18153
|
const specsDir = aiPathsAt(projectRoot).specsDir();
|
|
17991
|
-
if (!
|
|
18154
|
+
if (!fs14.existsSync(specsDir)) return out;
|
|
17992
18155
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
17993
18156
|
let raw;
|
|
17994
18157
|
try {
|
|
@@ -18006,12 +18169,12 @@ function listDirectChainedSubprojects(projectRoot) {
|
|
|
18006
18169
|
continue;
|
|
18007
18170
|
}
|
|
18008
18171
|
const id = raw.id;
|
|
18009
|
-
out.push({ dir, subsystemId: typeof id === "string" ? id :
|
|
18172
|
+
out.push({ dir, subsystemId: typeof id === "string" ? id : path20.basename(dir) });
|
|
18010
18173
|
}
|
|
18011
18174
|
return out;
|
|
18012
18175
|
}
|
|
18013
18176
|
function childHasSpecsButNoConfig(childDir) {
|
|
18014
|
-
return
|
|
18177
|
+
return fs14.existsSync(aiPathsAt(childDir).specsDir()) && !fs14.existsSync(aiPathsAt(childDir).projectConfig());
|
|
18015
18178
|
}
|
|
18016
18179
|
function findChainingSubprojectsMissingConfig(projectRoot) {
|
|
18017
18180
|
const missing = [];
|
|
@@ -18060,14 +18223,14 @@ function moveSubsystemProject(subsystemId, newProjectPath) {
|
|
|
18060
18223
|
const oldDir = assertContainedProjectPath(root, sub.projectPath);
|
|
18061
18224
|
const newDir = assertContainedProjectPath(root, nextPath);
|
|
18062
18225
|
if (oldDir !== newDir) {
|
|
18063
|
-
if (!
|
|
18226
|
+
if (!fs14.existsSync(oldDir)) {
|
|
18064
18227
|
throw new WaironError(`Subproject directory not found at its current path: ${oldDir}`);
|
|
18065
18228
|
}
|
|
18066
|
-
if (
|
|
18229
|
+
if (fs14.existsSync(newDir)) {
|
|
18067
18230
|
throw new WaironError(`Target directory already exists: ${newDir}`);
|
|
18068
18231
|
}
|
|
18069
|
-
ensureDir(
|
|
18070
|
-
|
|
18232
|
+
ensureDir(path20.dirname(newDir));
|
|
18233
|
+
fs14.renameSync(oldDir, newDir);
|
|
18071
18234
|
}
|
|
18072
18235
|
saveSubsystemSpec({ ...sub, projectPath: nextPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
18073
18236
|
invalidateSpecCache();
|
|
@@ -18076,9 +18239,9 @@ function toPosixPath(p) {
|
|
|
18076
18239
|
return p.replace(/\\/g, "/");
|
|
18077
18240
|
}
|
|
18078
18241
|
function isWithinDir(dir, file) {
|
|
18079
|
-
const d =
|
|
18080
|
-
const f =
|
|
18081
|
-
return f === d || f.startsWith(d +
|
|
18242
|
+
const d = path20.resolve(dir);
|
|
18243
|
+
const f = path20.resolve(file);
|
|
18244
|
+
return f === d || f.startsWith(d + path20.sep);
|
|
18082
18245
|
}
|
|
18083
18246
|
function externalizeSubsystem(subsystemId, projectPath) {
|
|
18084
18247
|
if (subsystemId.includes("::")) {
|
|
@@ -18090,14 +18253,14 @@ function externalizeSubsystem(subsystemId, projectPath) {
|
|
|
18090
18253
|
}
|
|
18091
18254
|
const parentRoot = getProjectRoot();
|
|
18092
18255
|
const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
|
|
18093
|
-
const fooDir =
|
|
18094
|
-
if (!
|
|
18256
|
+
const fooDir = path20.join(parentSpecsDir, subsystemId);
|
|
18257
|
+
if (!fs14.existsSync(fooDir)) {
|
|
18095
18258
|
throw new WaironError(`subsystem specs directory not found: ${fooDir}`);
|
|
18096
18259
|
}
|
|
18097
18260
|
const relPath = toPosixPath(projectPath);
|
|
18098
18261
|
const childDir = assertContainedProjectPath(parentRoot, relPath);
|
|
18099
|
-
const childFooDir =
|
|
18100
|
-
if (
|
|
18262
|
+
const childFooDir = path20.join(childDir, ".wai", "specs", subsystemId);
|
|
18263
|
+
if (fs14.existsSync(childFooDir)) {
|
|
18101
18264
|
throw new WaironError(`target already contains a "${subsystemId}" subsystem: ${childFooDir}`);
|
|
18102
18265
|
}
|
|
18103
18266
|
const renameMap = buildRenameMap(
|
|
@@ -18107,17 +18270,17 @@ function externalizeSubsystem(subsystemId, projectPath) {
|
|
|
18107
18270
|
);
|
|
18108
18271
|
const childSystemName = foo.name || subsystemId;
|
|
18109
18272
|
runWithProjectRoot(childDir, () => {
|
|
18110
|
-
ensureDir(
|
|
18273
|
+
ensureDir(path20.join(childDir, ".wai", "specs"));
|
|
18111
18274
|
provisionProject(childSystemName);
|
|
18112
18275
|
});
|
|
18113
|
-
ensureDir(
|
|
18114
|
-
|
|
18115
|
-
patchSubsystemIndex(
|
|
18276
|
+
ensureDir(path20.dirname(childFooDir));
|
|
18277
|
+
fs14.renameSync(fooDir, childFooDir);
|
|
18278
|
+
patchSubsystemIndex(path20.join(childFooDir, ".index.yaml"), (s) => {
|
|
18116
18279
|
s.parentSystem = childSystemName;
|
|
18117
18280
|
delete s.projectPath;
|
|
18118
18281
|
});
|
|
18119
18282
|
ensureDir(fooDir);
|
|
18120
|
-
writeYamlFile(
|
|
18283
|
+
writeYamlFile(path20.join(fooDir, ".index.yaml"), {
|
|
18121
18284
|
id: subsystemId,
|
|
18122
18285
|
name: foo.name,
|
|
18123
18286
|
description: foo.description,
|
|
@@ -18143,9 +18306,9 @@ function internalizeSubsystem(subsystemId) {
|
|
|
18143
18306
|
const parentRoot = getProjectRoot();
|
|
18144
18307
|
const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
|
|
18145
18308
|
const childDir = assertContainedProjectPath(parentRoot, foo.projectPath);
|
|
18146
|
-
const childWai =
|
|
18147
|
-
const childFooDir =
|
|
18148
|
-
if (!
|
|
18309
|
+
const childWai = path20.join(childDir, ".wai");
|
|
18310
|
+
const childFooDir = path20.join(childDir, ".wai", "specs", subsystemId);
|
|
18311
|
+
if (!fs14.existsSync(childFooDir)) {
|
|
18149
18312
|
throw new WaironError(`external subproject missing subsystem "${subsystemId}": ${childFooDir}`);
|
|
18150
18313
|
}
|
|
18151
18314
|
const childOwnSubs = runWithProjectRoot(childDir, () => loadSubsystemSpecs()).filter((s) => !s.id.includes("::"));
|
|
@@ -18158,15 +18321,15 @@ function internalizeSubsystem(subsystemId) {
|
|
|
18158
18321
|
false
|
|
18159
18322
|
);
|
|
18160
18323
|
const parentSystemName = loadSystemSpec()?.name ?? foo.parentSystem;
|
|
18161
|
-
const fooDir =
|
|
18162
|
-
|
|
18163
|
-
ensureDir(
|
|
18164
|
-
|
|
18165
|
-
patchSubsystemIndex(
|
|
18324
|
+
const fooDir = path20.join(parentSpecsDir, subsystemId);
|
|
18325
|
+
fs14.rmSync(fooDir, { recursive: true, force: true });
|
|
18326
|
+
ensureDir(path20.dirname(fooDir));
|
|
18327
|
+
fs14.renameSync(childFooDir, fooDir);
|
|
18328
|
+
patchSubsystemIndex(path20.join(fooDir, ".index.yaml"), (s) => {
|
|
18166
18329
|
s.parentSystem = parentSystemName;
|
|
18167
18330
|
delete s.projectPath;
|
|
18168
18331
|
});
|
|
18169
|
-
|
|
18332
|
+
fs14.rmSync(childWai, { recursive: true, force: true });
|
|
18170
18333
|
rewriteRefsInDir(parentSpecsDir, renameMap, fooDir);
|
|
18171
18334
|
invalidateSpecCache();
|
|
18172
18335
|
}
|
|
@@ -18263,7 +18426,7 @@ function rewriteRefsInDir(specsDir, renameMap, excludeDir) {
|
|
|
18263
18426
|
}
|
|
18264
18427
|
}
|
|
18265
18428
|
function patchSubsystemIndex(indexPath, mutate) {
|
|
18266
|
-
if (!
|
|
18429
|
+
if (!fs14.existsSync(indexPath)) return;
|
|
18267
18430
|
const raw = readYamlFile(indexPath);
|
|
18268
18431
|
mutate(raw);
|
|
18269
18432
|
raw.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -18277,8 +18440,8 @@ init_statehash();
|
|
|
18277
18440
|
init_agent_resolver();
|
|
18278
18441
|
|
|
18279
18442
|
// src/core/skills.ts
|
|
18280
|
-
var
|
|
18281
|
-
var
|
|
18443
|
+
var path21 = __toESM(require("path"));
|
|
18444
|
+
var fs15 = __toESM(require("fs"));
|
|
18282
18445
|
init_fs();
|
|
18283
18446
|
init_defaults();
|
|
18284
18447
|
init_extensions();
|
|
@@ -18412,16 +18575,16 @@ function packNamespace(pack) {
|
|
|
18412
18575
|
return pack.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
18413
18576
|
}
|
|
18414
18577
|
function extensionsFor(builtin, packSkills) {
|
|
18415
|
-
return packSkills.filter((s) => s.extends === builtin &&
|
|
18578
|
+
return packSkills.filter((s) => s.extends === builtin && fs15.existsSync(s.sourcePath));
|
|
18416
18579
|
}
|
|
18417
18580
|
function composeBuiltinSkill(name, packSkills) {
|
|
18418
18581
|
const srcPath = skillTemplatePath(name);
|
|
18419
|
-
const base =
|
|
18582
|
+
const base = fs15.existsSync(srcPath) ? fs15.readFileSync(srcPath, "utf-8") : "";
|
|
18420
18583
|
const sections = extensionsFor(name, packSkills);
|
|
18421
18584
|
if (sections.length === 0) return base;
|
|
18422
18585
|
const parts = [base.trimEnd()];
|
|
18423
18586
|
for (const section of sections) {
|
|
18424
|
-
const body =
|
|
18587
|
+
const body = fs15.readFileSync(section.sourcePath, "utf-8").replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "");
|
|
18425
18588
|
parts.push(`## Platform: ${section.pack}`, body.trim());
|
|
18426
18589
|
}
|
|
18427
18590
|
return `${parts.join("\n\n")}
|
|
@@ -18437,16 +18600,16 @@ function readFrontmatter(raw, fallbackName) {
|
|
|
18437
18600
|
return { name: field("name") || fallbackName, description: field("description") };
|
|
18438
18601
|
}
|
|
18439
18602
|
function builtinSkillsDir() {
|
|
18440
|
-
return
|
|
18603
|
+
return path21.resolve(__dirname, "..", "templates", "skills");
|
|
18441
18604
|
}
|
|
18442
18605
|
function skillTemplatePath(name) {
|
|
18443
|
-
return
|
|
18606
|
+
return path21.join(builtinSkillsDir(), `${name}.md`);
|
|
18444
18607
|
}
|
|
18445
18608
|
function skillDestPath(type, destDir, name) {
|
|
18446
18609
|
if (type === "claude" || type === "codex" || type === "gemini" || type === "agy") {
|
|
18447
|
-
return
|
|
18610
|
+
return path21.join(destDir, name, "SKILL.md");
|
|
18448
18611
|
}
|
|
18449
|
-
return
|
|
18612
|
+
return path21.join(destDir, `${name}.md`);
|
|
18450
18613
|
}
|
|
18451
18614
|
function skillsDirForTarget(type) {
|
|
18452
18615
|
switch (type) {
|
|
@@ -18481,22 +18644,22 @@ function exportSddSkills(targetTypes) {
|
|
|
18481
18644
|
ensureDir(destDir);
|
|
18482
18645
|
destinations.push(destDir);
|
|
18483
18646
|
for (const name of SKILL_NAMES) {
|
|
18484
|
-
if (!
|
|
18647
|
+
if (!fs15.existsSync(skillTemplatePath(name))) continue;
|
|
18485
18648
|
const content = composeBuiltinSkill(name, packSkills.filter((s) => s.targets.includes(type)));
|
|
18486
18649
|
const destPath = skillDestPath(type, destDir, name);
|
|
18487
|
-
ensureDir(
|
|
18488
|
-
|
|
18650
|
+
ensureDir(path21.dirname(destPath));
|
|
18651
|
+
fs15.writeFileSync(destPath, content, "utf-8");
|
|
18489
18652
|
fileCount++;
|
|
18490
18653
|
}
|
|
18491
18654
|
for (const skill of packSkills) {
|
|
18492
18655
|
if (skill.extends !== void 0) continue;
|
|
18493
18656
|
if (!skill.targets.includes(type)) continue;
|
|
18494
|
-
if (!
|
|
18657
|
+
if (!fs15.existsSync(skill.sourcePath)) continue;
|
|
18495
18658
|
const id = packSkillId(skill);
|
|
18496
|
-
const content =
|
|
18659
|
+
const content = fs15.readFileSync(skill.sourcePath, "utf-8");
|
|
18497
18660
|
const destPath = skillDestPath(type, destDir, id);
|
|
18498
|
-
ensureDir(
|
|
18499
|
-
|
|
18661
|
+
ensureDir(path21.dirname(destPath));
|
|
18662
|
+
fs15.writeFileSync(destPath, content, "utf-8");
|
|
18500
18663
|
fileCount++;
|
|
18501
18664
|
}
|
|
18502
18665
|
}
|
|
@@ -18509,12 +18672,12 @@ function checkSkillFreshness(type) {
|
|
|
18509
18672
|
const packSkills = loadProjectExtensions2().skills.filter((s) => s.targets.includes(type));
|
|
18510
18673
|
for (const name of SKILL_NAMES) {
|
|
18511
18674
|
const destPath = skillDestPath(type, dir, name);
|
|
18512
|
-
if (!
|
|
18675
|
+
if (!fs15.existsSync(destPath)) {
|
|
18513
18676
|
result.missing.push(name);
|
|
18514
18677
|
continue;
|
|
18515
18678
|
}
|
|
18516
18679
|
const want = composeBuiltinSkill(name, packSkills);
|
|
18517
|
-
const have =
|
|
18680
|
+
const have = fs15.readFileSync(destPath, "utf-8");
|
|
18518
18681
|
if (have === want) result.ok.push(name);
|
|
18519
18682
|
else result.stale.push(name);
|
|
18520
18683
|
}
|
|
@@ -18534,7 +18697,7 @@ var SkillResourceNotFoundError = class extends Error {
|
|
|
18534
18697
|
}
|
|
18535
18698
|
};
|
|
18536
18699
|
function readSkillFrontmatter(name) {
|
|
18537
|
-
return readFrontmatter(
|
|
18700
|
+
return readFrontmatter(fs15.readFileSync(skillTemplatePath(name), "utf-8"), name);
|
|
18538
18701
|
}
|
|
18539
18702
|
function listSkillResources() {
|
|
18540
18703
|
const builtin = RESOURCE_SKILL_IDS.map((id) => {
|
|
@@ -18548,9 +18711,9 @@ function listSkillResources() {
|
|
|
18548
18711
|
defaultForHostedMcp: true
|
|
18549
18712
|
};
|
|
18550
18713
|
});
|
|
18551
|
-
const pack = loadProjectExtensions2().skills.filter((s) => s.extends === void 0 &&
|
|
18714
|
+
const pack = loadProjectExtensions2().skills.filter((s) => s.extends === void 0 && fs15.existsSync(s.sourcePath)).map((skill) => {
|
|
18552
18715
|
const id = packSkillId(skill);
|
|
18553
|
-
const fm = readFrontmatter(
|
|
18716
|
+
const fm = readFrontmatter(fs15.readFileSync(skill.sourcePath, "utf-8"), id);
|
|
18554
18717
|
return {
|
|
18555
18718
|
id,
|
|
18556
18719
|
name: fm.name,
|
|
@@ -18566,8 +18729,8 @@ function readSkillResource(resourceId) {
|
|
|
18566
18729
|
const packSkills = loadProjectExtensions2().skills;
|
|
18567
18730
|
if (SKILL_NAMES.includes(resourceId)) return composeBuiltinSkill(resourceId, packSkills);
|
|
18568
18731
|
const packSkill = packSkills.find((s) => s.extends === void 0 && packSkillId(s) === resourceId);
|
|
18569
|
-
if (packSkill) return
|
|
18570
|
-
return
|
|
18732
|
+
if (packSkill) return fs15.readFileSync(packSkill.sourcePath, "utf-8");
|
|
18733
|
+
return fs15.readFileSync(skillTemplatePath(resourceId), "utf-8");
|
|
18571
18734
|
}
|
|
18572
18735
|
function listResources() {
|
|
18573
18736
|
return listSkillResources();
|
|
@@ -18756,7 +18919,7 @@ var WAIRON_MANAGED_MARKER = "wairon:managed";
|
|
|
18756
18919
|
var WAIRON_MANAGED_BANNER = `<!-- ${WAIRON_MANAGED_MARKER} \u2014 generated by \`wairon generate\`; do not edit, changes are overwritten -->`;
|
|
18757
18920
|
|
|
18758
18921
|
// src/exporters/claude.ts
|
|
18759
|
-
var
|
|
18922
|
+
var path22 = __toESM(require("path"));
|
|
18760
18923
|
init_fs();
|
|
18761
18924
|
var ClaudeExporter = class {
|
|
18762
18925
|
constructor() {
|
|
@@ -18765,7 +18928,7 @@ var ClaudeExporter = class {
|
|
|
18765
18928
|
outputPath(ctx) {
|
|
18766
18929
|
const { agent, target, projectRoot } = ctx;
|
|
18767
18930
|
const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
|
|
18768
|
-
return
|
|
18931
|
+
return path22.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
18769
18932
|
}
|
|
18770
18933
|
export(ctx) {
|
|
18771
18934
|
const { agent, renderedInstructions } = ctx;
|
|
@@ -18786,7 +18949,7 @@ var ClaudeExporter = class {
|
|
|
18786
18949
|
};
|
|
18787
18950
|
|
|
18788
18951
|
// src/exporters/custom.ts
|
|
18789
|
-
var
|
|
18952
|
+
var path23 = __toESM(require("path"));
|
|
18790
18953
|
init_fs();
|
|
18791
18954
|
var CustomExporter = class {
|
|
18792
18955
|
constructor() {
|
|
@@ -18797,7 +18960,7 @@ var CustomExporter = class {
|
|
|
18797
18960
|
if (!("outputDir" in target)) {
|
|
18798
18961
|
throw new Error("CustomExporter requires target.outputDir");
|
|
18799
18962
|
}
|
|
18800
|
-
return
|
|
18963
|
+
return path23.resolve(projectRoot, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
18801
18964
|
}
|
|
18802
18965
|
export(ctx) {
|
|
18803
18966
|
const { agent, target, renderedInstructions } = ctx;
|
|
@@ -18820,7 +18983,7 @@ var CustomExporter = class {
|
|
|
18820
18983
|
};
|
|
18821
18984
|
|
|
18822
18985
|
// src/exporters/gemini.ts
|
|
18823
|
-
var
|
|
18986
|
+
var path24 = __toESM(require("path"));
|
|
18824
18987
|
init_fs();
|
|
18825
18988
|
var GeminiExporter = class {
|
|
18826
18989
|
constructor() {
|
|
@@ -18829,7 +18992,7 @@ var GeminiExporter = class {
|
|
|
18829
18992
|
outputPath(ctx) {
|
|
18830
18993
|
const { agent, target, projectRoot } = ctx;
|
|
18831
18994
|
const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
|
|
18832
|
-
return
|
|
18995
|
+
return path24.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
|
|
18833
18996
|
}
|
|
18834
18997
|
export(ctx) {
|
|
18835
18998
|
const { agent, renderedInstructions } = ctx;
|
|
@@ -18854,7 +19017,7 @@ function yamlString(value) {
|
|
|
18854
19017
|
}
|
|
18855
19018
|
|
|
18856
19019
|
// src/exporters/generate.ts
|
|
18857
|
-
var
|
|
19020
|
+
var path25 = __toESM(require("path"));
|
|
18858
19021
|
init_fs();
|
|
18859
19022
|
|
|
18860
19023
|
// src/exporters/registry.ts
|
|
@@ -18921,7 +19084,7 @@ function resolveExpectedOutputPaths(agents, projectConfig, projectRoot = getProj
|
|
|
18921
19084
|
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
18922
19085
|
if (!targetConfig) continue;
|
|
18923
19086
|
const ctx = { agent, projectRoot, target: targetConfig };
|
|
18924
|
-
expected.add(
|
|
19087
|
+
expected.add(path25.resolve(getExporter(targetConfig).outputPath(ctx)));
|
|
18925
19088
|
}
|
|
18926
19089
|
}
|
|
18927
19090
|
return expected;
|
|
@@ -19316,6 +19479,7 @@ init_yaml();
|
|
|
19316
19479
|
skillExtendErrors,
|
|
19317
19480
|
skillsDirForTarget,
|
|
19318
19481
|
snapshotSpecFiles,
|
|
19482
|
+
specPathsInScope,
|
|
19319
19483
|
splitNamespace,
|
|
19320
19484
|
stateIdEquals,
|
|
19321
19485
|
stateIdString,
|