@wairon/cli 5.1.1-dev.84 → 5.1.1-dev.85
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 +2158 -987
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1273 -510
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2510,8 +2510,8 @@ var require_dist = __commonJS({
|
|
|
2510
2510
|
maxCompressionRatio: 100,
|
|
2511
2511
|
maxDepth: 16
|
|
2512
2512
|
};
|
|
2513
|
-
function parseManifest(
|
|
2514
|
-
const raw = (0, import_js_yaml.load)(
|
|
2513
|
+
function parseManifest(text3) {
|
|
2514
|
+
const raw = (0, import_js_yaml.load)(text3);
|
|
2515
2515
|
const manifest = validateEnvelope(raw);
|
|
2516
2516
|
if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {
|
|
2517
2517
|
throw new Error("unsupported pack-archive formatVersion (newer than this wairon understands)");
|
|
@@ -2597,7 +2597,7 @@ var require_dist = __commonJS({
|
|
|
2597
2597
|
if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {
|
|
2598
2598
|
return false;
|
|
2599
2599
|
}
|
|
2600
|
-
if (manifest.minWaironVersion &&
|
|
2600
|
+
if (manifest.minWaironVersion && isBelow2(waironVersion, manifest.minWaironVersion)) {
|
|
2601
2601
|
return false;
|
|
2602
2602
|
}
|
|
2603
2603
|
return true;
|
|
@@ -2662,7 +2662,7 @@ var require_dist = __commonJS({
|
|
|
2662
2662
|
function sha2562(data) {
|
|
2663
2663
|
return (0, import_crypto3.createHash)("sha256").update(data).digest("hex");
|
|
2664
2664
|
}
|
|
2665
|
-
function
|
|
2665
|
+
function isBelow2(running, minimum) {
|
|
2666
2666
|
const [rMaj, rMin, rPat] = parseSemverCore(running);
|
|
2667
2667
|
const [mMaj, mMin, mPat] = parseSemverCore(minimum);
|
|
2668
2668
|
if (rMaj !== mMaj) return rMaj < mMaj;
|
|
@@ -2689,8 +2689,8 @@ var require_dist = __commonJS({
|
|
|
2689
2689
|
var DERIVED_ROOTS = ["generated", "docs"];
|
|
2690
2690
|
var EXECUTABLE_EXT_RE = /\.(c|m)?js$/i;
|
|
2691
2691
|
var WAI_SEGMENT = ".wai";
|
|
2692
|
-
function parseTreeManifest(
|
|
2693
|
-
const raw = (0, import_js_yaml2.load)(
|
|
2692
|
+
function parseTreeManifest(text3) {
|
|
2693
|
+
const raw = (0, import_js_yaml2.load)(text3);
|
|
2694
2694
|
const manifest = validateEnvelope2(raw);
|
|
2695
2695
|
if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION2) {
|
|
2696
2696
|
throw new Error("unsupported tree-archive formatVersion (newer than this wairon understands)");
|
|
@@ -2791,7 +2791,7 @@ var require_dist = __commonJS({
|
|
|
2791
2791
|
if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION2) {
|
|
2792
2792
|
return false;
|
|
2793
2793
|
}
|
|
2794
|
-
if (manifest.minWaironVersion &&
|
|
2794
|
+
if (manifest.minWaironVersion && isBelow22(waironVersion, manifest.minWaironVersion)) {
|
|
2795
2795
|
return false;
|
|
2796
2796
|
}
|
|
2797
2797
|
return true;
|
|
@@ -2864,7 +2864,7 @@ var require_dist = __commonJS({
|
|
|
2864
2864
|
function sha25622(data) {
|
|
2865
2865
|
return (0, import_crypto22.createHash)("sha256").update(data).digest("hex");
|
|
2866
2866
|
}
|
|
2867
|
-
function
|
|
2867
|
+
function isBelow22(running, minimum) {
|
|
2868
2868
|
const [rMaj, rMin, rPat] = parseSemverCore2(running);
|
|
2869
2869
|
const [mMaj, mMin, mPat] = parseSemverCore2(minimum);
|
|
2870
2870
|
if (rMaj !== mMaj) return rMaj < mMaj;
|
|
@@ -3061,7 +3061,7 @@ var require_dist = __commonJS({
|
|
|
3061
3061
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
3062
3062
|
}
|
|
3063
3063
|
var fs21 = __toESM2(require("fs"));
|
|
3064
|
-
var
|
|
3064
|
+
var path38 = __toESM2(require("path"));
|
|
3065
3065
|
var import_fflate = require_node();
|
|
3066
3066
|
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".hg", ".svn"]);
|
|
3067
3067
|
function listEntries(archive) {
|
|
@@ -3099,8 +3099,8 @@ var require_dist = __commonJS({
|
|
|
3099
3099
|
}
|
|
3100
3100
|
function writeTree(destDir, files) {
|
|
3101
3101
|
for (const file of files) {
|
|
3102
|
-
const absolute =
|
|
3103
|
-
fs21.mkdirSync(
|
|
3102
|
+
const absolute = path38.join(destDir, file.path);
|
|
3103
|
+
fs21.mkdirSync(path38.dirname(absolute), { recursive: true });
|
|
3104
3104
|
fs21.writeFileSync(absolute, file.contents);
|
|
3105
3105
|
}
|
|
3106
3106
|
}
|
|
@@ -3113,10 +3113,10 @@ var require_dist = __commonJS({
|
|
|
3113
3113
|
for (const entry of fs21.readdirSync(current2, { withFileTypes: true })) {
|
|
3114
3114
|
if (entry.isDirectory()) {
|
|
3115
3115
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
3116
|
-
walkPackDir(root,
|
|
3116
|
+
walkPackDir(root, path38.join(current2, entry.name), out);
|
|
3117
3117
|
} else if (entry.isFile()) {
|
|
3118
|
-
const absolute =
|
|
3119
|
-
const relative22 =
|
|
3118
|
+
const absolute = path38.join(current2, entry.name);
|
|
3119
|
+
const relative22 = path38.relative(root, absolute).split(path38.sep).join("/");
|
|
3120
3120
|
out.push({ path: relative22, contents: fs21.readFileSync(absolute) });
|
|
3121
3121
|
}
|
|
3122
3122
|
}
|
|
@@ -3176,8 +3176,8 @@ var require_dist = __commonJS({
|
|
|
3176
3176
|
throw new Error("pack build requires a wairon-pack.yaml envelope (run `wairon pack init` to scaffold one)");
|
|
3177
3177
|
}
|
|
3178
3178
|
const manifest = parseManifest(decode(envelope.contents));
|
|
3179
|
-
const
|
|
3180
|
-
verifyIdentity(manifest,
|
|
3179
|
+
const identity2 = readInnerIdentity(files, manifest);
|
|
3180
|
+
verifyIdentity(manifest, identity2.name, identity2.version);
|
|
3181
3181
|
const sealed = sealIntegrity(manifest, files, `@wairon/sdk@${SDK_VERSION}`, (/* @__PURE__ */ new Date()).toISOString());
|
|
3182
3182
|
const sealedText = serializeManifest(sealed);
|
|
3183
3183
|
const finalFiles = upsertEnvelope(files, sealedText);
|
|
@@ -3408,6 +3408,7 @@ __export(src_exports, {
|
|
|
3408
3408
|
ComplexityRuleConfigSchema: () => ComplexityRuleConfigSchema,
|
|
3409
3409
|
ComponentSpecSchema: () => ComponentSpecSchema,
|
|
3410
3410
|
ComponentTypeSchema: () => ComponentTypeSchema,
|
|
3411
|
+
CompositionConfigSchema: () => CompositionConfigSchema,
|
|
3411
3412
|
ConfigValidationError: () => ConfigValidationError,
|
|
3412
3413
|
ConformanceRuleConfigSchema: () => ConformanceRuleConfigSchema,
|
|
3413
3414
|
ConformanceTierSchema: () => ConformanceTierSchema,
|
|
@@ -3462,6 +3463,7 @@ __export(src_exports, {
|
|
|
3462
3463
|
PROJECT_ID_RE: () => PROJECT_ID_RE,
|
|
3463
3464
|
PROJECT_KINDS: () => PROJECT_KINDS,
|
|
3464
3465
|
PUBLIC_NAME_RE: () => PUBLIC_NAME_RE,
|
|
3466
|
+
PackRequirementSchema: () => PackRequirementSchema,
|
|
3465
3467
|
PackSelectionSchema: () => PackSelectionSchema,
|
|
3466
3468
|
ParallelBranchSchema: () => ParallelBranchSchema,
|
|
3467
3469
|
PathsConfigSchema: () => PathsConfigSchema,
|
|
@@ -3517,6 +3519,7 @@ __export(src_exports, {
|
|
|
3517
3519
|
WaironError: () => WaironError,
|
|
3518
3520
|
activeTargetTypes: () => activeTargetTypes2,
|
|
3519
3521
|
addDomain: () => addDomain,
|
|
3522
|
+
admits: () => admits,
|
|
3520
3523
|
aiDir: () => aiDir,
|
|
3521
3524
|
aiDirAt: () => aiDirAt,
|
|
3522
3525
|
aiPathsAt: () => aiPathsAt,
|
|
@@ -3639,6 +3642,7 @@ __export(src_exports, {
|
|
|
3639
3642
|
loadComponentSpecs: () => loadComponentSpecs,
|
|
3640
3643
|
loadExtensionPacks: () => loadExtensionPacks,
|
|
3641
3644
|
loadExtensions: () => loadExtensions,
|
|
3645
|
+
loadExtensionsFor: () => loadFor,
|
|
3642
3646
|
loadImplementationSpec: () => loadImplementationSpec,
|
|
3643
3647
|
loadImplementationSpecs: () => loadImplementationSpecs,
|
|
3644
3648
|
loadInterfaceSpec: () => loadInterfaceSpec,
|
|
@@ -3678,7 +3682,9 @@ __export(src_exports, {
|
|
|
3678
3682
|
packDirEntry: () => packDirEntry,
|
|
3679
3683
|
packEntryLabel: () => packEntryLabel,
|
|
3680
3684
|
packEntryRef: () => packEntryRef,
|
|
3685
|
+
packManifest: () => manifestOf,
|
|
3681
3686
|
packStoreDir: () => packStoreDir,
|
|
3687
|
+
parseDeclarativePack: () => parseDeclarativePack,
|
|
3682
3688
|
parseDeclaredCall: () => parseDeclaredCall,
|
|
3683
3689
|
parseYaml: () => parseYaml,
|
|
3684
3690
|
passesIntentFloor: () => passesIntentFloor,
|
|
@@ -3691,6 +3697,7 @@ __export(src_exports, {
|
|
|
3691
3697
|
projectIdentity: () => projectIdentity,
|
|
3692
3698
|
provisionProject: () => provisionProject,
|
|
3693
3699
|
qualifiedTypeId: () => qualifiedTypeId,
|
|
3700
|
+
rangeProblem: () => rangeProblem,
|
|
3694
3701
|
readFileOrNull: () => readFileOrNull,
|
|
3695
3702
|
readJsonFile: () => readJsonFile,
|
|
3696
3703
|
readLockRecord: () => readLockRecord,
|
|
@@ -3707,6 +3714,7 @@ __export(src_exports, {
|
|
|
3707
3714
|
renameMethod: () => renameMethod,
|
|
3708
3715
|
renderDiagram: () => renderDiagram,
|
|
3709
3716
|
repairForeignStepFields: () => repairForeignStepFields,
|
|
3717
|
+
requiredPolicies: () => requiredPolicies,
|
|
3710
3718
|
resolveAgentTopology: () => resolveAgentTopology,
|
|
3711
3719
|
resolveBudget: () => resolveBudget,
|
|
3712
3720
|
resolveChainingParent: () => resolveChainingParent,
|
|
@@ -3751,6 +3759,7 @@ __export(src_exports, {
|
|
|
3751
3759
|
upsertPackSelection: () => upsertPackSelection,
|
|
3752
3760
|
validateFamily: () => validateFamily,
|
|
3753
3761
|
validateProject: () => validateProject,
|
|
3762
|
+
withPack: () => withPack,
|
|
3754
3763
|
writeFile: () => writeFile,
|
|
3755
3764
|
writeFileIfChanged: () => writeFileIfChanged,
|
|
3756
3765
|
writeJsonFile: () => writeJsonFile,
|
|
@@ -4192,7 +4201,7 @@ var AgentBriefSchema = import_zod2.z.object({
|
|
|
4192
4201
|
profile: ExecutionProfileSchema.optional(),
|
|
4193
4202
|
budget: ExecutionBudgetSchema.optional()
|
|
4194
4203
|
});
|
|
4195
|
-
function createAgentRecord(
|
|
4204
|
+
function createAgentRecord(partial2) {
|
|
4196
4205
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4197
4206
|
return AgentRecordSchema.parse({
|
|
4198
4207
|
description: "",
|
|
@@ -4205,10 +4214,32 @@ function createAgentRecord(partial) {
|
|
|
4205
4214
|
targets: ["claude"],
|
|
4206
4215
|
createdAt: now,
|
|
4207
4216
|
updatedAt: now,
|
|
4208
|
-
...
|
|
4217
|
+
...partial2
|
|
4209
4218
|
});
|
|
4210
4219
|
}
|
|
4211
4220
|
|
|
4221
|
+
// src/utils/version.ts
|
|
4222
|
+
function isNewerVersion(current2, candidate) {
|
|
4223
|
+
const baseVersion = (v) => v.replace(/-.*$/, "");
|
|
4224
|
+
const preRelease = (v) => {
|
|
4225
|
+
const match = v.match(/-(.+)\.(\d+)$/);
|
|
4226
|
+
return match ? { label: match[1], n: parseInt(match[2], 10) } : null;
|
|
4227
|
+
};
|
|
4228
|
+
const parse = (v) => baseVersion(v).split(".").map((n) => parseInt(n, 10) || 0);
|
|
4229
|
+
const [cMaj, cMin, cPat] = parse(current2);
|
|
4230
|
+
const [nMaj, nMin, nPat] = parse(candidate);
|
|
4231
|
+
if (nMaj !== cMaj) return nMaj > cMaj;
|
|
4232
|
+
if (nMin !== cMin) return nMin > cMin;
|
|
4233
|
+
if (nPat !== cPat) return nPat > cPat;
|
|
4234
|
+
const cPre = preRelease(current2);
|
|
4235
|
+
const nPre = preRelease(candidate);
|
|
4236
|
+
if (!cPre && !nPre) return false;
|
|
4237
|
+
if (!cPre && nPre) return false;
|
|
4238
|
+
if (cPre && !nPre) return true;
|
|
4239
|
+
if (cPre && nPre) return nPre.n > cPre.n;
|
|
4240
|
+
return false;
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4212
4243
|
// src/models/project.ts
|
|
4213
4244
|
var BuiltinTargetConfigSchema = import_zod3.z.object({
|
|
4214
4245
|
type: import_zod3.z.enum(["claude", "gemini", "agy", "cursor", "copilot", "codex"]),
|
|
@@ -4541,6 +4572,15 @@ var MemberDeclarationSchema = import_zod3.z.object({
|
|
|
4541
4572
|
/** The member's public names this project imports, exactly as an external's `use`. */
|
|
4542
4573
|
use: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
4543
4574
|
});
|
|
4575
|
+
var plainString = import_zod3.z.preprocess((v) => v === void 0 || v === null ? "" : String(v), import_zod3.z.string());
|
|
4576
|
+
var PackRequirementSchema = import_zod3.z.object({
|
|
4577
|
+
pack: plainString,
|
|
4578
|
+
version: plainString,
|
|
4579
|
+
profile: import_zod3.z.string().optional()
|
|
4580
|
+
});
|
|
4581
|
+
var CompositionConfigSchema = import_zod3.z.object({
|
|
4582
|
+
requirePolicies: import_zod3.z.array(PackRequirementSchema).optional()
|
|
4583
|
+
});
|
|
4544
4584
|
var ProjectConfigSchema = import_zod3.z.object({
|
|
4545
4585
|
/**
|
|
4546
4586
|
* Schema version — used to detect incompatible config formats in future
|
|
@@ -4577,6 +4617,15 @@ var ProjectConfigSchema = import_zod3.z.object({
|
|
|
4577
4617
|
* `projectPath` mount still loads for one release (DEPRECATED_MOUNT_FORM).
|
|
4578
4618
|
*/
|
|
4579
4619
|
members: import_zod3.z.record(import_zod3.z.union([import_zod3.z.string(), MemberDeclarationSchema])).optional(),
|
|
4620
|
+
/**
|
|
4621
|
+
* What this project requires of the projects it contains when they are
|
|
4622
|
+
* composed: `requirePolicies`, the packs each member must select (by semver
|
|
4623
|
+
* range, optionally one profile). This project's own gate judges only its
|
|
4624
|
+
* syntax (POLICY_REQUIREMENT_INVALID); the family run judges members against
|
|
4625
|
+
* it, and createMember reads it once when it scaffolds a new member. No
|
|
4626
|
+
* member's own gate reads it. Written by hand.
|
|
4627
|
+
*/
|
|
4628
|
+
composition: CompositionConfigSchema.optional(),
|
|
4580
4629
|
/**
|
|
4581
4630
|
* The type/profile of the project, which configures targeted guidelines, rules,
|
|
4582
4631
|
* templates, and validation constraints. Open string: built-ins are backend,
|
|
@@ -4684,6 +4733,135 @@ function declaredPackNames(config) {
|
|
|
4684
4733
|
function declaredProfileIds(config) {
|
|
4685
4734
|
return [...new Set(config.profileSelection?.profileIds ?? [])];
|
|
4686
4735
|
}
|
|
4736
|
+
function withPack(config, entry, remove = false) {
|
|
4737
|
+
const packs = config.extensions?.packs ?? [];
|
|
4738
|
+
const same = (e) => typeof entry === "string" ? e === entry : typeof e !== "string" && e.name === entry.name;
|
|
4739
|
+
const others = packs.filter((e) => !same(e));
|
|
4740
|
+
let next;
|
|
4741
|
+
if (remove) next = others;
|
|
4742
|
+
else if (typeof entry === "string") next = packs.includes(entry) ? packs : [...packs, entry];
|
|
4743
|
+
else next = [...others, entry];
|
|
4744
|
+
return { ...config, extensions: { useGlobalPacks: false, ...config.extensions, packs: next } };
|
|
4745
|
+
}
|
|
4746
|
+
function requiredPolicies(config) {
|
|
4747
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4748
|
+
const out = [];
|
|
4749
|
+
for (const requirement of config.composition?.requirePolicies ?? []) {
|
|
4750
|
+
if (seen.has(requirement.pack)) continue;
|
|
4751
|
+
seen.add(requirement.pack);
|
|
4752
|
+
out.push(requirement);
|
|
4753
|
+
}
|
|
4754
|
+
return out;
|
|
4755
|
+
}
|
|
4756
|
+
var CONCRETE_RE = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
4757
|
+
var PARTIAL_RE = /^v?(\d+|[xX*])(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
4758
|
+
var OPERATOR_RE = /^(>=|<=|>|<|=|\^|~)/;
|
|
4759
|
+
function concrete(v) {
|
|
4760
|
+
const m = CONCRETE_RE.exec(v.trim());
|
|
4761
|
+
if (!m) return null;
|
|
4762
|
+
return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]), ...m[4] ? { pre: m[4] } : {} };
|
|
4763
|
+
}
|
|
4764
|
+
var text = (v) => `${v.major}.${v.minor}.${v.patch}${v.pre ? `-${v.pre}` : ""}`;
|
|
4765
|
+
function compare(a, b) {
|
|
4766
|
+
if (isNewerVersion(text(a), text(b))) return -1;
|
|
4767
|
+
if (isNewerVersion(text(b), text(a))) return 1;
|
|
4768
|
+
return 0;
|
|
4769
|
+
}
|
|
4770
|
+
function partial(v) {
|
|
4771
|
+
const m = PARTIAL_RE.exec(v);
|
|
4772
|
+
if (!m) return null;
|
|
4773
|
+
const num = (s) => s === void 0 || /^[xX*]$/.test(s) ? null : Number(s);
|
|
4774
|
+
const major = num(m[1]);
|
|
4775
|
+
const minor = major === null ? null : num(m[2]);
|
|
4776
|
+
const patch = minor === null ? null : num(m[3]);
|
|
4777
|
+
if (m[4] && patch === null) return null;
|
|
4778
|
+
return { major, minor, patch, ...m[4] ? { pre: m[4] } : {} };
|
|
4779
|
+
}
|
|
4780
|
+
var cv = (major, minor, patch, pre) => ({ major, minor, patch, ...pre ? { pre } : {} });
|
|
4781
|
+
function nextOf(p) {
|
|
4782
|
+
if (p.minor === null) return cv(p.major + 1, 0, 0);
|
|
4783
|
+
return cv(p.major, p.minor + 1, 0);
|
|
4784
|
+
}
|
|
4785
|
+
function expand(token) {
|
|
4786
|
+
const opMatch = OPERATOR_RE.exec(token);
|
|
4787
|
+
const op = opMatch ? opMatch[1] : "";
|
|
4788
|
+
const p = partial(token.slice(op.length));
|
|
4789
|
+
if (!p) return null;
|
|
4790
|
+
const low = cv(p.major ?? 0, p.minor ?? 0, p.patch ?? 0, p.pre);
|
|
4791
|
+
const exact = p.patch !== null;
|
|
4792
|
+
if (p.major === null) return op === "<" || op === ">" ? [{ op: "<", version: cv(0, 0, 0) }] : [];
|
|
4793
|
+
switch (op) {
|
|
4794
|
+
case "":
|
|
4795
|
+
case "=":
|
|
4796
|
+
return exact ? [{ op: "=", version: low }] : [{ op: ">=", version: low }, { op: "<", version: nextOf(p) }];
|
|
4797
|
+
case "^": {
|
|
4798
|
+
const upper = p.major > 0 || p.minor === null ? cv(p.major + 1, 0, 0) : p.minor > 0 || p.patch === null ? cv(0, p.minor + 1, 0) : cv(0, 0, p.patch + 1);
|
|
4799
|
+
return [{ op: ">=", version: low }, { op: "<", version: upper }];
|
|
4800
|
+
}
|
|
4801
|
+
case "~":
|
|
4802
|
+
return [{ op: ">=", version: low }, { op: "<", version: p.minor === null ? cv(p.major + 1, 0, 0) : cv(p.major, p.minor + 1, 0) }];
|
|
4803
|
+
case ">=":
|
|
4804
|
+
return [{ op: ">=", version: low }];
|
|
4805
|
+
case "<":
|
|
4806
|
+
return [{ op: "<", version: low }];
|
|
4807
|
+
case ">":
|
|
4808
|
+
return exact ? [{ op: ">", version: low }] : [{ op: ">=", version: nextOf(p) }];
|
|
4809
|
+
case "<=":
|
|
4810
|
+
return exact ? [{ op: "<=", version: low }] : [{ op: "<", version: nextOf(p) }];
|
|
4811
|
+
default:
|
|
4812
|
+
return null;
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4815
|
+
function readRange(range) {
|
|
4816
|
+
if (range.trim() === "") return { problem: "the range is empty" };
|
|
4817
|
+
const alternatives = [];
|
|
4818
|
+
for (const raw of range.split("||")) {
|
|
4819
|
+
const tokens = raw.trim().split(/\s+/).filter((t) => t !== "");
|
|
4820
|
+
const joined = [];
|
|
4821
|
+
for (const t of tokens) {
|
|
4822
|
+
if (joined.length > 0 && /^(>=|<=|>|<|=|\^|~)$/.test(joined[joined.length - 1])) joined[joined.length - 1] += t;
|
|
4823
|
+
else joined.push(t);
|
|
4824
|
+
}
|
|
4825
|
+
const comparators = [];
|
|
4826
|
+
for (const token of joined) {
|
|
4827
|
+
const expanded = expand(token);
|
|
4828
|
+
if (!expanded) return { problem: `"${token}" is neither a version, an x-range nor a comparator` };
|
|
4829
|
+
comparators.push(...expanded);
|
|
4830
|
+
}
|
|
4831
|
+
alternatives.push({ comparators, any: joined.length === 0 || joined.length === 1 && /^[xX*]$/.test(joined[0]) });
|
|
4832
|
+
}
|
|
4833
|
+
return { alternatives };
|
|
4834
|
+
}
|
|
4835
|
+
function satisfies(version, c) {
|
|
4836
|
+
const d = compare(version, c.version);
|
|
4837
|
+
switch (c.op) {
|
|
4838
|
+
case "=":
|
|
4839
|
+
return d === 0;
|
|
4840
|
+
case ">=":
|
|
4841
|
+
return d >= 0;
|
|
4842
|
+
case ">":
|
|
4843
|
+
return d > 0;
|
|
4844
|
+
case "<":
|
|
4845
|
+
return d < 0;
|
|
4846
|
+
case "<=":
|
|
4847
|
+
return d <= 0;
|
|
4848
|
+
}
|
|
4849
|
+
}
|
|
4850
|
+
function rangeProblem(requirement) {
|
|
4851
|
+
const read = readRange(requirement.version);
|
|
4852
|
+
return "problem" in read ? read.problem : null;
|
|
4853
|
+
}
|
|
4854
|
+
function admits(requirement, version) {
|
|
4855
|
+
const read = readRange(requirement.version);
|
|
4856
|
+
if ("problem" in read) return false;
|
|
4857
|
+
if (version === void 0 || version.trim() === "") return read.alternatives.some((a) => a.any);
|
|
4858
|
+
const v = concrete(version);
|
|
4859
|
+
if (!v) return false;
|
|
4860
|
+
return read.alternatives.some((alt) => {
|
|
4861
|
+
if (v.pre && !alt.comparators.some((c) => c.version.pre && c.version.major === v.major && c.version.minor === v.minor && c.version.patch === v.patch)) return false;
|
|
4862
|
+
return alt.comparators.every((c) => satisfies(v, c));
|
|
4863
|
+
});
|
|
4864
|
+
}
|
|
4687
4865
|
var PROJECT_ID_RE = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/;
|
|
4688
4866
|
function slugifyProjectName(name) {
|
|
4689
4867
|
const slug = name.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[^a-z0-9]+/, "").replace(/[^a-z0-9]+$/, "");
|
|
@@ -4779,12 +4957,12 @@ function projectConfigFsAdapterAt(rootDir) {
|
|
|
4779
4957
|
return readYamlFile(file());
|
|
4780
4958
|
},
|
|
4781
4959
|
writeDocument(document) {
|
|
4782
|
-
const
|
|
4783
|
-
if (
|
|
4960
|
+
const text3 = readFileOrNull(file());
|
|
4961
|
+
if (text3 === null) {
|
|
4784
4962
|
writeYamlFile(file(), document);
|
|
4785
4963
|
return;
|
|
4786
4964
|
}
|
|
4787
|
-
writeFile(file(), editDocumentText(
|
|
4965
|
+
writeFile(file(), editDocumentText(text3, document, root));
|
|
4788
4966
|
},
|
|
4789
4967
|
documentExists() {
|
|
4790
4968
|
return fs2.existsSync(file());
|
|
@@ -4792,8 +4970,8 @@ function projectConfigFsAdapterAt(rootDir) {
|
|
|
4792
4970
|
readText() {
|
|
4793
4971
|
return readFileOrNull(file());
|
|
4794
4972
|
},
|
|
4795
|
-
writeText(
|
|
4796
|
-
writeFile(file(),
|
|
4973
|
+
writeText(text3) {
|
|
4974
|
+
writeFile(file(), text3);
|
|
4797
4975
|
}
|
|
4798
4976
|
};
|
|
4799
4977
|
}
|
|
@@ -4822,9 +5000,9 @@ function storeOver(adapter, root) {
|
|
|
4822
5000
|
},
|
|
4823
5001
|
rewriteScalars(edits, dryRun = false) {
|
|
4824
5002
|
if (edits.length === 0) return;
|
|
4825
|
-
const
|
|
4826
|
-
if (
|
|
4827
|
-
const next = rewriteScalarsInText(
|
|
5003
|
+
const text3 = adapter.readText();
|
|
5004
|
+
if (text3 === null) throw new ProjectNotInitializedError();
|
|
5005
|
+
const next = rewriteScalarsInText(text3, edits, root);
|
|
4828
5006
|
if (!dryRun) adapter.writeText(next);
|
|
4829
5007
|
}
|
|
4830
5008
|
};
|
|
@@ -4879,21 +5057,21 @@ function childrenOf(tokens, index) {
|
|
|
4879
5057
|
}
|
|
4880
5058
|
return out;
|
|
4881
5059
|
}
|
|
4882
|
-
function locateScalar(tokens,
|
|
5060
|
+
function locateScalar(tokens, path38) {
|
|
4883
5061
|
let region = tokens;
|
|
4884
|
-
for (let k = 0; k <
|
|
4885
|
-
const segment =
|
|
4886
|
-
if (region.length === 0) return `nothing is nested at ${
|
|
5062
|
+
for (let k = 0; k < path38.length; k += 1) {
|
|
5063
|
+
const segment = path38[k];
|
|
5064
|
+
if (region.length === 0) return `nothing is nested at ${path38.slice(0, k).join(".")}`;
|
|
4887
5065
|
const base = Math.min(...region.map((t) => t.col));
|
|
4888
|
-
const last = k ===
|
|
5066
|
+
const last = k === path38.length - 1;
|
|
4889
5067
|
let at;
|
|
4890
5068
|
if (typeof segment === "string") {
|
|
4891
5069
|
at = region.findIndex((t) => t.kind === "key" && t.col === base && t.name === segment);
|
|
4892
|
-
if (at < 0) return `no block key "${segment}" at ${
|
|
5070
|
+
if (at < 0) return `no block key "${segment}" at ${path38.slice(0, k).join(".") || "the document root"}`;
|
|
4893
5071
|
if (last) return region[at].valueStart !== void 0 ? region[at] : `"${segment}" holds no inline scalar`;
|
|
4894
5072
|
} else {
|
|
4895
5073
|
const items = region.map((t, i) => ({ t, i })).filter(({ t }) => t.kind === "item" && t.col === base);
|
|
4896
|
-
if (segment >= items.length) return `no block sequence item ${segment} at ${
|
|
5074
|
+
if (segment >= items.length) return `no block sequence item ${segment} at ${path38.slice(0, k).join(".")}`;
|
|
4897
5075
|
at = items[segment].i;
|
|
4898
5076
|
if (last) {
|
|
4899
5077
|
const value = region[at + 1];
|
|
@@ -4905,26 +5083,26 @@ function locateScalar(tokens, path37) {
|
|
|
4905
5083
|
}
|
|
4906
5084
|
return "an empty path addresses no scalar";
|
|
4907
5085
|
}
|
|
4908
|
-
function readScalar(
|
|
4909
|
-
if (
|
|
5086
|
+
function readScalar(text3) {
|
|
5087
|
+
if (text3.startsWith("'")) {
|
|
4910
5088
|
let i = 1;
|
|
4911
5089
|
let value = "";
|
|
4912
|
-
while (i <
|
|
4913
|
-
if (
|
|
4914
|
-
if (
|
|
5090
|
+
while (i < text3.length) {
|
|
5091
|
+
if (text3[i] === "'") {
|
|
5092
|
+
if (text3[i + 1] === "'") {
|
|
4915
5093
|
value += "'";
|
|
4916
5094
|
i += 2;
|
|
4917
5095
|
continue;
|
|
4918
5096
|
}
|
|
4919
5097
|
return { value, style: "single", end: i + 1 };
|
|
4920
5098
|
}
|
|
4921
|
-
value +=
|
|
5099
|
+
value += text3[i];
|
|
4922
5100
|
i += 1;
|
|
4923
5101
|
}
|
|
4924
5102
|
return null;
|
|
4925
5103
|
}
|
|
4926
|
-
if (
|
|
4927
|
-
const closing = /^"(?:[^"\\]|\\.)*"/.exec(
|
|
5104
|
+
if (text3.startsWith('"')) {
|
|
5105
|
+
const closing = /^"(?:[^"\\]|\\.)*"/.exec(text3);
|
|
4928
5106
|
if (!closing) return null;
|
|
4929
5107
|
try {
|
|
4930
5108
|
return { value: JSON.parse(closing[0]), style: "double", end: closing[0].length };
|
|
@@ -4932,8 +5110,8 @@ function readScalar(text2) {
|
|
|
4932
5110
|
return null;
|
|
4933
5111
|
}
|
|
4934
5112
|
}
|
|
4935
|
-
const comment =
|
|
4936
|
-
const body = (comment < 0 ?
|
|
5113
|
+
const comment = text3.search(/\s#/);
|
|
5114
|
+
const body = (comment < 0 ? text3 : text3.slice(0, comment)).trimEnd();
|
|
4937
5115
|
return { value: body, style: "plain", end: body.length };
|
|
4938
5116
|
}
|
|
4939
5117
|
function writeScalar(value, style) {
|
|
@@ -4941,18 +5119,18 @@ function writeScalar(value, style) {
|
|
|
4941
5119
|
if (style === "plain" && /^[A-Za-z0-9_][A-Za-z0-9_./-]*$/.test(value)) return value;
|
|
4942
5120
|
return `'${value.replace(/'/g, "''")}'`;
|
|
4943
5121
|
}
|
|
4944
|
-
function setAt(document,
|
|
5122
|
+
function setAt(document, path38, value) {
|
|
4945
5123
|
let node = document;
|
|
4946
|
-
for (const segment of
|
|
4947
|
-
node[
|
|
5124
|
+
for (const segment of path38.slice(0, -1)) node = node[segment];
|
|
5125
|
+
node[path38[path38.length - 1]] = value;
|
|
4948
5126
|
}
|
|
4949
|
-
function rewriteScalarsInText(
|
|
5127
|
+
function rewriteScalarsInText(text3, edits, root) {
|
|
4950
5128
|
const refuse = (why) => {
|
|
4951
5129
|
throw new WaironError(`Cannot rewrite .wai/project.yaml at ${root} without disturbing its formatting: ${why}. Nothing was written.`);
|
|
4952
5130
|
};
|
|
4953
|
-
const lines =
|
|
5131
|
+
const lines = text3.split(/(?<=\n)/);
|
|
4954
5132
|
const tokens = tokenize(lines);
|
|
4955
|
-
const expected = parseYaml(
|
|
5133
|
+
const expected = parseYaml(text3);
|
|
4956
5134
|
for (const edit of edits) {
|
|
4957
5135
|
const where = edit.path.join(".");
|
|
4958
5136
|
const token = locateScalar(tokens, edit.path);
|
|
@@ -4994,17 +5172,17 @@ function sameValue(a, b) {
|
|
|
4994
5172
|
}
|
|
4995
5173
|
return a === b;
|
|
4996
5174
|
}
|
|
4997
|
-
function lineStartOf(
|
|
4998
|
-
return
|
|
5175
|
+
function lineStartOf(text3, pos) {
|
|
5176
|
+
return text3.lastIndexOf("\n", pos - 1) + 1;
|
|
4999
5177
|
}
|
|
5000
|
-
function lineEndFrom(
|
|
5001
|
-
if (pos === 0 ||
|
|
5002
|
-
const newline =
|
|
5003
|
-
return newline < 0 ?
|
|
5178
|
+
function lineEndFrom(text3, pos) {
|
|
5179
|
+
if (pos === 0 || text3[pos - 1] === "\n") return pos;
|
|
5180
|
+
const newline = text3.indexOf("\n", pos);
|
|
5181
|
+
return newline < 0 ? text3.length : newline + 1;
|
|
5004
5182
|
}
|
|
5005
|
-
function indentBlock(
|
|
5183
|
+
function indentBlock(text3, col) {
|
|
5006
5184
|
const pad = " ".repeat(col);
|
|
5007
|
-
const body =
|
|
5185
|
+
const body = text3.endsWith("\n") ? text3 : `${text3}
|
|
5008
5186
|
`;
|
|
5009
5187
|
return body.split("\n").map((line, i, all) => line === "" || i === all.length - 1 ? line : pad + line).join("\n");
|
|
5010
5188
|
}
|
|
@@ -5037,12 +5215,12 @@ function schemaFieldOrder(at) {
|
|
|
5037
5215
|
function inlineScalar(value, style) {
|
|
5038
5216
|
if (value !== null && typeof value === "object") return null;
|
|
5039
5217
|
const quoting = style === "QUOTE_SINGLE" || style === "QUOTE_DOUBLE" ? style : "PLAIN";
|
|
5040
|
-
const
|
|
5041
|
-
return
|
|
5218
|
+
const text3 = YAML.stringify(value, { ...FRESH_TEXT_OPTIONS, lineWidth: 0, defaultStringType: quoting }).replace(/\n$/, "");
|
|
5219
|
+
return text3.includes("\n") ? null : text3;
|
|
5042
5220
|
}
|
|
5043
5221
|
var DocumentReconciler = class {
|
|
5044
|
-
constructor(
|
|
5045
|
-
this.text =
|
|
5222
|
+
constructor(text3, doc) {
|
|
5223
|
+
this.text = text3;
|
|
5046
5224
|
this.doc = doc;
|
|
5047
5225
|
this.splices = [];
|
|
5048
5226
|
}
|
|
@@ -5151,18 +5329,18 @@ var DocumentReconciler = class {
|
|
|
5151
5329
|
}
|
|
5152
5330
|
}
|
|
5153
5331
|
};
|
|
5154
|
-
function applySplices(
|
|
5332
|
+
function applySplices(text3, splices) {
|
|
5155
5333
|
const ordered = [...splices].sort((a, b) => b.start - a.start || b.end - a.end || b.rank - a.rank);
|
|
5156
|
-
let out =
|
|
5334
|
+
let out = text3;
|
|
5157
5335
|
for (const splice of ordered) out = out.slice(0, splice.start) + splice.text + out.slice(splice.end);
|
|
5158
5336
|
return out;
|
|
5159
5337
|
}
|
|
5160
|
-
function editDocumentText(
|
|
5338
|
+
function editDocumentText(text3, document, root) {
|
|
5161
5339
|
const refuse = (why) => {
|
|
5162
5340
|
throw new WaironError(`Cannot write .wai/project.yaml at ${root} as an edit of the file: ${why}. Nothing was written.`);
|
|
5163
5341
|
};
|
|
5164
|
-
const crlf =
|
|
5165
|
-
const source = crlf ?
|
|
5342
|
+
const crlf = text3.includes("\r\n");
|
|
5343
|
+
const source = crlf ? text3.replace(/\r\n/g, "\n") : text3;
|
|
5166
5344
|
const doc = YAML.parseDocument(source, PARSE_OPTIONS);
|
|
5167
5345
|
if (doc.errors.length > 0) refuse(`the file does not parse (${doc.errors[0].message})`);
|
|
5168
5346
|
const reconciler = new DocumentReconciler(source, doc);
|
|
@@ -5271,19 +5449,21 @@ function registryOver(store, root) {
|
|
|
5271
5449
|
}
|
|
5272
5450
|
save(config);
|
|
5273
5451
|
},
|
|
5452
|
+
// The four pack writes read the change through project_config.withPack —
|
|
5453
|
+
// the same reading a pack impact's dry run measures, so the report and the
|
|
5454
|
+
// write cannot disagree about what the configuration becomes.
|
|
5274
5455
|
upsertPackSelection(selection) {
|
|
5275
5456
|
const config = current2();
|
|
5276
5457
|
const existing = packsOf(config);
|
|
5277
|
-
const
|
|
5278
|
-
save(withPacks(config,
|
|
5279
|
-
return
|
|
5458
|
+
const replaced = existing.some((entry) => typeof entry !== "string" && entry.name === selection.name);
|
|
5459
|
+
save(withPacks(config, packsOf(withPack(config, selection))));
|
|
5460
|
+
return replaced;
|
|
5280
5461
|
},
|
|
5281
5462
|
removePackSelection(packName) {
|
|
5282
5463
|
const config = current2();
|
|
5283
5464
|
const existing = packsOf(config);
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
save(withPacks(config, remaining));
|
|
5465
|
+
if (!existing.some((entry) => typeof entry !== "string" && entry.name === packName)) return false;
|
|
5466
|
+
save(withPacks(config, packsOf(withPack(config, { name: packName }, true))));
|
|
5287
5467
|
return true;
|
|
5288
5468
|
},
|
|
5289
5469
|
setProjectType(projectType) {
|
|
@@ -5298,17 +5478,14 @@ function registryOver(store, root) {
|
|
|
5298
5478
|
},
|
|
5299
5479
|
registerPackRef(ref) {
|
|
5300
5480
|
const config = current2();
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
save(withPacks(config, [...packs, ref]));
|
|
5481
|
+
if (packsOf(config).includes(ref)) return false;
|
|
5482
|
+
save(withPacks(config, packsOf(withPack(config, ref))));
|
|
5304
5483
|
return true;
|
|
5305
5484
|
},
|
|
5306
5485
|
deregisterPackRef(ref) {
|
|
5307
5486
|
const config = current2();
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
if (remaining.length === packs.length) return false;
|
|
5311
|
-
save(withPacks(config, remaining));
|
|
5487
|
+
if (!packsOf(config).includes(ref)) return false;
|
|
5488
|
+
save(withPacks(config, packsOf(withPack(config, ref, true))));
|
|
5312
5489
|
return true;
|
|
5313
5490
|
},
|
|
5314
5491
|
markSelectionsBundled(bundled) {
|
|
@@ -5338,9 +5515,9 @@ function registryOver(store, root) {
|
|
|
5338
5515
|
const next = rekeyAnchor(rename, { spec: entry.spec, at, covers });
|
|
5339
5516
|
const base = ["rules", "conformance", "carried", g, "findings", f];
|
|
5340
5517
|
const named2 = { code: String(entry.code), spec: entry.spec, at: at ?? "" };
|
|
5341
|
-
const change = (
|
|
5518
|
+
const change = (path38, field, from, to) => {
|
|
5342
5519
|
if (from === to) return;
|
|
5343
|
-
edits.push({ path: [...base, ...
|
|
5520
|
+
edits.push({ path: [...base, ...path38], from, to });
|
|
5344
5521
|
rekeys.push({ ...named2, field, from, to });
|
|
5345
5522
|
};
|
|
5346
5523
|
change(["spec"], "spec", entry.spec, next.spec);
|
|
@@ -5652,11 +5829,11 @@ var projectConfigRepository = {
|
|
|
5652
5829
|
};
|
|
5653
5830
|
|
|
5654
5831
|
// src/core/domain_projector.ts
|
|
5655
|
-
var
|
|
5832
|
+
var path20 = __toESM(require("path"));
|
|
5656
5833
|
|
|
5657
5834
|
// src/core/specs.ts
|
|
5658
5835
|
var fs12 = __toESM(require("fs"));
|
|
5659
|
-
var
|
|
5836
|
+
var path19 = __toESM(require("path"));
|
|
5660
5837
|
|
|
5661
5838
|
// src/config/paths.ts
|
|
5662
5839
|
var fs3 = __toESM(require("fs"));
|
|
@@ -6437,9 +6614,9 @@ var MethodSignatureSchema = import_zod8.z.object({
|
|
|
6437
6614
|
ext: ExtDataSchema.optional()
|
|
6438
6615
|
});
|
|
6439
6616
|
var INTENT_FLOOR_MIN_CHARS = 40;
|
|
6440
|
-
function passesIntentFloor(
|
|
6441
|
-
if (!
|
|
6442
|
-
const t =
|
|
6617
|
+
function passesIntentFloor(text3, methodName) {
|
|
6618
|
+
if (!text3) return false;
|
|
6619
|
+
const t = text3.trim();
|
|
6443
6620
|
if (t.length < INTENT_FLOOR_MIN_CHARS) return false;
|
|
6444
6621
|
const norm = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
6445
6622
|
if (norm(t) === norm(methodName)) return false;
|
|
@@ -7205,7 +7382,7 @@ function stepGraph(method) {
|
|
|
7205
7382
|
for (const s of steps) byNum.set(s.stepNumber, s);
|
|
7206
7383
|
const nums = [...byNum.keys()].sort((a, b) => a - b);
|
|
7207
7384
|
const indexOf = new Map(nums.map((n, i) => [n, i]));
|
|
7208
|
-
const
|
|
7385
|
+
const nextOf2 = (n) => {
|
|
7209
7386
|
const i = indexOf.get(n);
|
|
7210
7387
|
return i !== void 0 && i + 1 < nums.length ? nums[i + 1] : void 0;
|
|
7211
7388
|
};
|
|
@@ -7214,7 +7391,7 @@ function stepGraph(method) {
|
|
|
7214
7391
|
return i !== void 0 && i > 0 ? nums[i - 1] : void 0;
|
|
7215
7392
|
};
|
|
7216
7393
|
const armEndJoin = /* @__PURE__ */ new Map();
|
|
7217
|
-
const fallNext = (n) => armEndJoin.has(n) ? armEndJoin.get(n) :
|
|
7394
|
+
const fallNext = (n) => armEndJoin.has(n) ? armEndJoin.get(n) : nextOf2(n);
|
|
7218
7395
|
for (const n of nums) {
|
|
7219
7396
|
const s = byNum.get(n);
|
|
7220
7397
|
if (s.type !== "parallel" || s.endStep === void 0 || !s.branches?.length) continue;
|
|
@@ -7243,11 +7420,11 @@ function stepGraph(method) {
|
|
|
7243
7420
|
succ.push(...(s.cases ?? []).map((c) => c.step), s.defaultStep ?? fallNext(n));
|
|
7244
7421
|
break;
|
|
7245
7422
|
case "loop":
|
|
7246
|
-
succ.push(
|
|
7423
|
+
succ.push(nextOf2(n), s.endStep !== void 0 ? fallNext(s.endStep) : void 0);
|
|
7247
7424
|
break;
|
|
7248
7425
|
case "try":
|
|
7249
7426
|
succ.push(
|
|
7250
|
-
|
|
7427
|
+
nextOf2(n),
|
|
7251
7428
|
...(s.catches ?? []).map((c) => c.step),
|
|
7252
7429
|
s.finallyStep,
|
|
7253
7430
|
s.endStep !== void 0 ? fallNext(s.endStep) : void 0
|
|
@@ -7265,7 +7442,7 @@ function stepGraph(method) {
|
|
|
7265
7442
|
}
|
|
7266
7443
|
return [...new Set(succ.filter((t) => t !== void 0 && byNum.has(t)))];
|
|
7267
7444
|
};
|
|
7268
|
-
return { stepNumbers: nums, stepAt: (n) => byNum.get(n), nextOf, successorsOf };
|
|
7445
|
+
return { stepNumbers: nums, stepAt: (n) => byNum.get(n), nextOf: nextOf2, successorsOf };
|
|
7269
7446
|
}
|
|
7270
7447
|
|
|
7271
7448
|
// src/models/step-config.ts
|
|
@@ -7362,7 +7539,7 @@ function stepConfigVerdict(method) {
|
|
|
7362
7539
|
}
|
|
7363
7540
|
const nums = [...byNum.keys()].sort((a, b) => a - b);
|
|
7364
7541
|
const indexOf = new Map(nums.map((n, i) => [n, i]));
|
|
7365
|
-
const
|
|
7542
|
+
const nextOf2 = (n) => {
|
|
7366
7543
|
const i = indexOf.get(n);
|
|
7367
7544
|
return i !== void 0 && i + 1 < nums.length ? nums[i + 1] : void 0;
|
|
7368
7545
|
};
|
|
@@ -7414,7 +7591,7 @@ function stepConfigVerdict(method) {
|
|
|
7414
7591
|
const sorted = [...entries].sort((a, b) => a - b);
|
|
7415
7592
|
if (entries.some((e, i) => e !== sorted[i])) malformed(s.stepNumber, `parallel step ${s.stepNumber} "branches" must list arm entries in ascending order \u2014 arms are contiguous sub-regions of the body.`);
|
|
7416
7593
|
if (new Set(entries).size !== entries.length) malformed(s.stepNumber, `parallel step ${s.stepNumber} "branches" lists the same entry step twice.`);
|
|
7417
|
-
const bodyStart =
|
|
7594
|
+
const bodyStart = nextOf2(s.stepNumber);
|
|
7418
7595
|
if (bodyStart !== void 0 && sorted[0] !== bodyStart) malformed(s.stepNumber, `parallel step ${s.stepNumber}: the first arm must start at the body's first step (${bodyStart}), got ${sorted[0]} \u2014 steps before the first arm would belong to no arm.`);
|
|
7419
7596
|
if (s.endStep !== void 0 && sorted.some((e) => e > s.endStep)) malformed(s.stepNumber, `parallel step ${s.stepNumber}: every arm entry must lie within the body (..${s.endStep}).`);
|
|
7420
7597
|
}
|
|
@@ -7524,8 +7701,8 @@ function ambiguityMessage(resolution, subject, ref) {
|
|
|
7524
7701
|
const local = ref.split("::").filter((seg) => seg && seg !== "super").pop() ?? ref;
|
|
7525
7702
|
return `${subject} cross-tree component "${ref}", which the surface snapshots of ${providers.map((p) => `"${p}"`).join(", ")} expose with different contracts \u2014 the reference matches more than one declared contract, so none of them can judge it. Name the provider it means (super::<provider>::${local}), or remove the snapshot that no longer applies.`;
|
|
7526
7703
|
}
|
|
7527
|
-
function sha256(
|
|
7528
|
-
return `sha256:${(0, import_crypto.createHash)("sha256").update(
|
|
7704
|
+
function sha256(text3) {
|
|
7705
|
+
return `sha256:${(0, import_crypto.createHash)("sha256").update(text3).digest("hex")}`;
|
|
7529
7706
|
}
|
|
7530
7707
|
var TYPE_IDENTIFIER = /(?:::)?[A-Za-z0-9_][A-Za-z0-9_-]*(?:(?:::|\.)[A-Za-z0-9_][A-Za-z0-9_-]*)*/g;
|
|
7531
7708
|
function closureTypeOf(snapshot, identifier) {
|
|
@@ -7781,9 +7958,9 @@ function shortestPath(from, to, members, edges, rank) {
|
|
|
7781
7958
|
const v = queue.shift();
|
|
7782
7959
|
for (const w of [...edges.get(v) ?? []].filter((x) => members.has(x)).sort((a, b) => rank(a) - rank(b))) {
|
|
7783
7960
|
if (w === to) {
|
|
7784
|
-
const
|
|
7785
|
-
for (let at = v; at !== from; at = prev.get(at))
|
|
7786
|
-
return
|
|
7961
|
+
const path38 = [w];
|
|
7962
|
+
for (let at = v; at !== from; at = prev.get(at)) path38.unshift(at);
|
|
7963
|
+
return path38;
|
|
7787
7964
|
}
|
|
7788
7965
|
if (seen.has(w)) continue;
|
|
7789
7966
|
seen.add(w);
|
|
@@ -8198,12 +8375,12 @@ function buildExcalidrawScene(model, L) {
|
|
|
8198
8375
|
locked: false
|
|
8199
8376
|
};
|
|
8200
8377
|
}
|
|
8201
|
-
function boundLabel(rect,
|
|
8378
|
+
function boundLabel(rect, text3, fontSize, verticalAlign) {
|
|
8202
8379
|
const id = rect.id + "-label";
|
|
8203
8380
|
const label2 = base(id, "text", { x: rect.x + 8, y: rect.y + 6, w: rect.width - 16, h: 20 });
|
|
8204
8381
|
label2.roundness = null;
|
|
8205
|
-
label2.text =
|
|
8206
|
-
label2.originalText =
|
|
8382
|
+
label2.text = text3;
|
|
8383
|
+
label2.originalText = text3;
|
|
8207
8384
|
label2.fontSize = fontSize;
|
|
8208
8385
|
label2.fontFamily = 1;
|
|
8209
8386
|
label2.textAlign = "center";
|
|
@@ -12742,10 +12919,10 @@ function lockPath2(root) {
|
|
|
12742
12919
|
function snapshotPath(root, alias) {
|
|
12743
12920
|
return path9.join(root, ".wai", "externals", `${alias}.yaml`);
|
|
12744
12921
|
}
|
|
12745
|
-
function writeAtomically(file,
|
|
12922
|
+
function writeAtomically(file, text3) {
|
|
12746
12923
|
fs7.mkdirSync(path9.dirname(file), { recursive: true });
|
|
12747
12924
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
12748
|
-
fs7.writeFileSync(tmp,
|
|
12925
|
+
fs7.writeFileSync(tmp, text3);
|
|
12749
12926
|
fs7.renameSync(tmp, file);
|
|
12750
12927
|
}
|
|
12751
12928
|
function sortedLock(lock) {
|
|
@@ -13214,6 +13391,109 @@ function listPinnedExternals2() {
|
|
|
13214
13391
|
|
|
13215
13392
|
// src/core/family-validation.ts
|
|
13216
13393
|
var path11 = __toESM(require("path"));
|
|
13394
|
+
|
|
13395
|
+
// src/models/pack-impact.ts
|
|
13396
|
+
function packSettings(manifest, profile) {
|
|
13397
|
+
const severities = {};
|
|
13398
|
+
for (const rule of manifest.rules) {
|
|
13399
|
+
for (const code of rule.codes) severities[code.code] = code.defaultSeverity;
|
|
13400
|
+
}
|
|
13401
|
+
for (const assertion of manifest.assertions) severities[assertionCode(manifest.name, assertion.code)] = assertion.severity;
|
|
13402
|
+
const def = profile !== null ? manifest.profiles[profile] : void 0;
|
|
13403
|
+
if (!def) return { pack: manifest.name, severities };
|
|
13404
|
+
Object.assign(severities, def.rules?.sddRuleSeverity ?? {});
|
|
13405
|
+
const rules = def.rules;
|
|
13406
|
+
return {
|
|
13407
|
+
pack: manifest.name,
|
|
13408
|
+
profile,
|
|
13409
|
+
severities,
|
|
13410
|
+
...rules?.designDepth ? { designDepth: rules.designDepth } : {},
|
|
13411
|
+
...rules?.naming ? { naming: rules.naming } : {},
|
|
13412
|
+
...rules?.complexity ? { complexity: rules.complexity } : {},
|
|
13413
|
+
...rules?.documentation ? { documentation: rules.documentation } : {}
|
|
13414
|
+
};
|
|
13415
|
+
}
|
|
13416
|
+
function assertionCode(packName, code) {
|
|
13417
|
+
const norm = (s) => s.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
13418
|
+
return `${norm(packName)}_${norm(code)}`;
|
|
13419
|
+
}
|
|
13420
|
+
var RANK = { notice: 1, warning: 2, error: 3 };
|
|
13421
|
+
function severityChange(code, to, profile, baseline, packCodes) {
|
|
13422
|
+
const from = baseline.ruleDefaults[code];
|
|
13423
|
+
if (from === void 0) {
|
|
13424
|
+
return { axis: "rule", change: packCodes.has(code) ? "added" : "inert", subject: code, profile, to };
|
|
13425
|
+
}
|
|
13426
|
+
if (from === to) return null;
|
|
13427
|
+
if (to === "off") return { axis: "rule", change: "off", subject: code, profile, from, to };
|
|
13428
|
+
return { axis: "rule", change: (RANK[to] ?? 0) < (RANK[from] ?? 0) ? "loosened" : "raised", subject: code, profile, from, to };
|
|
13429
|
+
}
|
|
13430
|
+
function profileChanges(id, manifest, baseline, packCodes) {
|
|
13431
|
+
const def = manifest.profiles[id];
|
|
13432
|
+
const out = [{ axis: "concept", change: baseline.profiles.includes(id) ? "redefined" : "added", subject: id, profile: id }];
|
|
13433
|
+
for (const [code, to] of Object.entries(def.rules?.sddRuleSeverity ?? {})) {
|
|
13434
|
+
const change = severityChange(code, to, id, baseline, packCodes);
|
|
13435
|
+
if (change) out.push(change);
|
|
13436
|
+
}
|
|
13437
|
+
const depth = def.rules?.designDepth;
|
|
13438
|
+
if (depth && depth !== baseline.designDepth) out.push({ axis: "rule", change: "depth", subject: "designDepth", profile: id, from: baseline.designDepth, to: depth });
|
|
13439
|
+
for (const f of def.forbiddenStereotypes) for (const t of f.types) out.push({ axis: "concept", change: "removed", subject: t, profile: id, reason: f.reason });
|
|
13440
|
+
for (const d of def.discouragedStereotypes) for (const t of d.types) out.push({ axis: "concept", change: "discouraged", subject: t, profile: id, reason: d.reason });
|
|
13441
|
+
for (const e of def.allowedEdges) {
|
|
13442
|
+
for (const from of e.from) for (const to of e.to) out.push({ axis: "concept", change: "licensed", subject: `${from} \u2192 ${to}`, profile: id, reason: e.reason });
|
|
13443
|
+
}
|
|
13444
|
+
return out;
|
|
13445
|
+
}
|
|
13446
|
+
function packWideChanges(manifest, baseline) {
|
|
13447
|
+
const out = [];
|
|
13448
|
+
for (const a of manifest.assertions) {
|
|
13449
|
+
out.push({ axis: "rule", change: "added", subject: assertionCode(manifest.name, a.code), to: a.severity, reason: a.reason });
|
|
13450
|
+
}
|
|
13451
|
+
for (const rule of manifest.rules) {
|
|
13452
|
+
for (const code of rule.codes) out.push({ axis: "rule", change: "added", subject: code.code, to: code.defaultSeverity });
|
|
13453
|
+
}
|
|
13454
|
+
for (const p of manifest.patterns) out.push({ axis: "concept", change: "added", subject: `pattern ${p.id}@${p.version}` });
|
|
13455
|
+
for (const g of manifest.guarantees) {
|
|
13456
|
+
if (!baseline.guarantees.includes(g)) out.push({ axis: "concept", change: "added", subject: `guarantee ${g}` });
|
|
13457
|
+
}
|
|
13458
|
+
for (const [lang, def] of Object.entries(manifest.languages)) {
|
|
13459
|
+
out.push({ axis: "concept", change: "added", subject: `language ${lang}` });
|
|
13460
|
+
for (const [construct, guidance] of Object.entries(def.unsupportedFlow)) {
|
|
13461
|
+
out.push({ axis: "concept", change: "gated", subject: `${lang}: ${construct}`, reason: guidance });
|
|
13462
|
+
}
|
|
13463
|
+
}
|
|
13464
|
+
return out;
|
|
13465
|
+
}
|
|
13466
|
+
function doctrineChanges(manifest, baseline) {
|
|
13467
|
+
const packCodes = /* @__PURE__ */ new Set([
|
|
13468
|
+
...manifest.assertions.map((a) => assertionCode(manifest.name, a.code)),
|
|
13469
|
+
...manifest.rules.flatMap((r) => r.codes.map((c) => c.code))
|
|
13470
|
+
]);
|
|
13471
|
+
const perProfile = Object.keys(manifest.profiles).flatMap((id) => profileChanges(id, manifest, baseline, packCodes));
|
|
13472
|
+
return [...perProfile, ...packWideChanges(manifest, baseline)];
|
|
13473
|
+
}
|
|
13474
|
+
function identity(issue2) {
|
|
13475
|
+
const message = issue2.message.replace(/\b(error|warning|notice)s?\b/gi, "").replace(/\s+/g, " ").trim();
|
|
13476
|
+
return [issue2.code, issue2.project ?? "", issue2.specId ?? "", message].join("\0");
|
|
13477
|
+
}
|
|
13478
|
+
function findingChanges(before, after) {
|
|
13479
|
+
const pending = /* @__PURE__ */ new Map();
|
|
13480
|
+
for (const issue2 of before.issues) {
|
|
13481
|
+
const key = identity(issue2);
|
|
13482
|
+
pending.set(key, [...pending.get(key) ?? [], issue2]);
|
|
13483
|
+
}
|
|
13484
|
+
const introduced = [];
|
|
13485
|
+
const regraded = [];
|
|
13486
|
+
for (const issue2 of after.issues) {
|
|
13487
|
+
const matches = pending.get(identity(issue2));
|
|
13488
|
+
const earlier = matches?.shift();
|
|
13489
|
+
if (!earlier) introduced.push(issue2);
|
|
13490
|
+
else if (earlier.severity !== issue2.severity) regraded.push({ finding: issue2, from: earlier.severity });
|
|
13491
|
+
}
|
|
13492
|
+
const resolved = [...pending.values()].flat();
|
|
13493
|
+
return { introduced, resolved, regraded };
|
|
13494
|
+
}
|
|
13495
|
+
|
|
13496
|
+
// src/core/family-validation.ts
|
|
13217
13497
|
var FAMILY_SEVERITY = {
|
|
13218
13498
|
EXTERNAL_INCOMPATIBLE: "error",
|
|
13219
13499
|
EXTERNAL_DRIFTED: "notice",
|
|
@@ -13224,7 +13504,11 @@ var FAMILY_SEVERITY = {
|
|
|
13224
13504
|
MEMBER_UNAPPROVED: "warning",
|
|
13225
13505
|
MEMBER_DRIFTED: "warning",
|
|
13226
13506
|
PROJECT_ID_DEFAULTED: "notice",
|
|
13227
|
-
PROJECT_ID_AMBIGUOUS: "warning"
|
|
13507
|
+
PROJECT_ID_AMBIGUOUS: "warning",
|
|
13508
|
+
// Governance: a required pack not adopted blocks; a member's deviation from
|
|
13509
|
+
// an adopted pack's settings is visible and never fails --ci.
|
|
13510
|
+
POLICY_NOT_ADOPTED: "error",
|
|
13511
|
+
POLICY_DEVIATION: "notice"
|
|
13228
13512
|
};
|
|
13229
13513
|
function configOrNull() {
|
|
13230
13514
|
try {
|
|
@@ -13326,6 +13610,7 @@ function run(options) {
|
|
|
13326
13610
|
left.push(...judged.composed.notSelected.map((alias) => ({ project: node.namespace, alias })));
|
|
13327
13611
|
}
|
|
13328
13612
|
issues.push(...within(root, ceiling, () => checkMembers(narrowed(family, selected))));
|
|
13613
|
+
issues.push(...within(root, ceiling, () => checkPolicies(narrowed(family, selected))));
|
|
13329
13614
|
const hint = notSelectedHint(left);
|
|
13330
13615
|
return {
|
|
13331
13616
|
valid: issues.every((i) => i.severity !== "error"),
|
|
@@ -13476,6 +13761,147 @@ function checkMembers(family) {
|
|
|
13476
13761
|
}
|
|
13477
13762
|
return out.filter((f) => f !== null);
|
|
13478
13763
|
}
|
|
13764
|
+
function requiredBy(key) {
|
|
13765
|
+
return key === "" ? "the family root" : `"${key}"`;
|
|
13766
|
+
}
|
|
13767
|
+
function requirementText(requirement) {
|
|
13768
|
+
return `"${requirement.pack}" ${requirement.version}${requirement.profile ? ` (profile "${requirement.profile}")` : ""}`;
|
|
13769
|
+
}
|
|
13770
|
+
function isBelow(family, node, ancestor) {
|
|
13771
|
+
let at = node;
|
|
13772
|
+
while (at && at.parent !== void 0) {
|
|
13773
|
+
if (at.parent === ancestor) return true;
|
|
13774
|
+
at = familyNode(family, at.parent);
|
|
13775
|
+
}
|
|
13776
|
+
return false;
|
|
13777
|
+
}
|
|
13778
|
+
function policyIssue(code, message, member, specId) {
|
|
13779
|
+
return { severity: FAMILY_SEVERITY[code], code, message, project: member, ...specId !== void 0 ? { specId } : {} };
|
|
13780
|
+
}
|
|
13781
|
+
function tunedBy(config, issues) {
|
|
13782
|
+
const out = [];
|
|
13783
|
+
for (const issue2 of issues) {
|
|
13784
|
+
const tuned = finding(config, issue2.code, issue2.message, issue2.project ?? "", issue2.specId);
|
|
13785
|
+
if (tuned) out.push(tuned);
|
|
13786
|
+
}
|
|
13787
|
+
return out;
|
|
13788
|
+
}
|
|
13789
|
+
function checkPolicies(family) {
|
|
13790
|
+
const out = [];
|
|
13791
|
+
for (const requirer of family.nodes) {
|
|
13792
|
+
const members = family.nodes.filter((n) => isBelow(family, n, requirer.namespace));
|
|
13793
|
+
if (members.length === 0) continue;
|
|
13794
|
+
const config = runWithProjectRoot(requirer.directory, configOrNull);
|
|
13795
|
+
const valid = config ? requiredPolicies(config).filter((r) => r.pack.trim() !== "" && rangeProblem(r) === null) : [];
|
|
13796
|
+
if (valid.length === 0) continue;
|
|
13797
|
+
const caused = [];
|
|
13798
|
+
for (const member of members) {
|
|
13799
|
+
caused.push(...runWithProjectRoot(member.directory, () => judgeAdoption(requirer.namespace, member.namespace, valid)));
|
|
13800
|
+
}
|
|
13801
|
+
out.push(...tunedBy(config, caused));
|
|
13802
|
+
}
|
|
13803
|
+
return out;
|
|
13804
|
+
}
|
|
13805
|
+
function entryFor(config, loaded, pack) {
|
|
13806
|
+
const entries = config.extensions?.packs ?? [];
|
|
13807
|
+
const selection = entries.find((e) => typeof e !== "string" && e.name === pack);
|
|
13808
|
+
if (selection) return { entry: selection, ...selection.version ? { version: selection.version } : {}, label: selection.version ? `${selection.name}@${selection.version}` : selection.name };
|
|
13809
|
+
for (const ref of entries.filter((e) => typeof e === "string")) {
|
|
13810
|
+
const committed = loaded.packs.find((p) => p.scope === "project" && p.ref === ref && p.name === pack);
|
|
13811
|
+
if (committed) return { entry: ref, ...committed.version ? { version: committed.version } : {}, label: `${ref} (${committed.name}${committed.version ? `@${committed.version}` : ", unversioned"})` };
|
|
13812
|
+
}
|
|
13813
|
+
return null;
|
|
13814
|
+
}
|
|
13815
|
+
function judgeAdoption(requiring, member, requirements) {
|
|
13816
|
+
const config = configOrNull();
|
|
13817
|
+
if (!config) return [];
|
|
13818
|
+
const loaded = loadProjectExtensions();
|
|
13819
|
+
const out = [];
|
|
13820
|
+
const who = `The member ${named(member)}`;
|
|
13821
|
+
for (const requirement of requirements) {
|
|
13822
|
+
const wanted = `${requirementText(requirement)}, required by ${requiredBy(requiring)}`;
|
|
13823
|
+
const adopted = entryFor(config, loaded, requirement.pack);
|
|
13824
|
+
if (!adopted) {
|
|
13825
|
+
out.push(policyIssue("POLICY_NOT_ADOPTED", `${who} does not select the pack ${wanted}. Select it in the member's own configuration (\`wairon pack use ${requirement.pack}@<version> --pin\` at its root).`, member));
|
|
13826
|
+
continue;
|
|
13827
|
+
}
|
|
13828
|
+
if (typeof adopted.entry !== "string" && !adopted.entry.version) {
|
|
13829
|
+
out.push(policyIssue("POLICY_NOT_ADOPTED", `${who} selects "${adopted.label}" for the pack ${wanted}, unpinned \u2014 a family cannot judge a floating selection; pin a version (\`wairon pack use ${requirement.pack}@<version> --pin\`).`, member));
|
|
13830
|
+
continue;
|
|
13831
|
+
}
|
|
13832
|
+
if (!admits(requirement, adopted.version)) {
|
|
13833
|
+
out.push(policyIssue("POLICY_NOT_ADOPTED", `${who} selects "${adopted.label}", outside the range of the pack ${wanted}: ${adopted.version ? `version ${adopted.version} is not admitted by "${requirement.version}"` : `an unversioned pack is admitted by "*" only`}.`, member));
|
|
13834
|
+
continue;
|
|
13835
|
+
}
|
|
13836
|
+
if (requirement.profile && config.projectType !== requirement.profile) {
|
|
13837
|
+
out.push(policyIssue("POLICY_NOT_ADOPTED", `${who} selects "${adopted.label}" for the pack ${wanted}, but is governed by "${config.projectType}", not the required profile "${requirement.profile}". Set its projectType to "${requirement.profile}".`, member));
|
|
13838
|
+
continue;
|
|
13839
|
+
}
|
|
13840
|
+
const manifest = manifestOf(adopted.entry);
|
|
13841
|
+
if (!manifest) continue;
|
|
13842
|
+
const governing = requirement.profile ?? (config.projectType in manifest.profiles ? config.projectType : null);
|
|
13843
|
+
out.push(...policyDeviations(member, requirement, packSettings(manifest, governing)));
|
|
13844
|
+
}
|
|
13845
|
+
return out;
|
|
13846
|
+
}
|
|
13847
|
+
function shown(value) {
|
|
13848
|
+
return typeof value === "string" ? `"${value}"` : JSON.stringify(value);
|
|
13849
|
+
}
|
|
13850
|
+
function keyDeviations(label2, packValues, memberValues) {
|
|
13851
|
+
const out = [];
|
|
13852
|
+
for (const [key, value] of Object.entries(packValues ?? {})) {
|
|
13853
|
+
if (value === void 0 || key === "stereotypes") continue;
|
|
13854
|
+
const mine = memberValues?.[key];
|
|
13855
|
+
if (mine !== void 0 && JSON.stringify(mine) !== JSON.stringify(value)) out.push({ setting: `${label2}.${key}`, pack: value, member: mine });
|
|
13856
|
+
}
|
|
13857
|
+
return out;
|
|
13858
|
+
}
|
|
13859
|
+
function lintAllows() {
|
|
13860
|
+
const specs = [
|
|
13861
|
+
...loadSubsystemSpecs(),
|
|
13862
|
+
...loadComponentSpecs(),
|
|
13863
|
+
...loadInterfaceSpecs(),
|
|
13864
|
+
...loadImplementationSpecs(),
|
|
13865
|
+
...loadTypeSpecs()
|
|
13866
|
+
];
|
|
13867
|
+
return specs.flatMap((s) => (s.lint?.allow ?? []).map((a) => ({ specId: s.id, code: a.code, ...a.at !== void 0 ? { at: a.at } : {} })));
|
|
13868
|
+
}
|
|
13869
|
+
function policyDeviations(member, requirement, settings) {
|
|
13870
|
+
const rules = configOrNull()?.rules;
|
|
13871
|
+
const subsystems = loadSubsystemSpecs();
|
|
13872
|
+
const allows = lintAllows();
|
|
13873
|
+
const under = settings.profile ? `under its profile "${settings.profile}"` : "with none of its profiles governing";
|
|
13874
|
+
const about = `the pack "${requirement.pack}" (required ${requirement.version})`;
|
|
13875
|
+
const deviation = (setting, pack, mine, specId) => policyIssue("POLICY_DEVIATION", `The member ${named(member)} adopted ${about} but changes ${setting}: the pack sets ${shown(pack)} ${under}, the member ${shown(mine)}. Visible, not blocking \u2014 the member's own configuration decides.`, member, specId);
|
|
13876
|
+
const out = [];
|
|
13877
|
+
for (const [code, severity] of Object.entries(rules?.sddRuleSeverity ?? {})) {
|
|
13878
|
+
const packs = settings.severities[code];
|
|
13879
|
+
if (packs !== void 0 && packs !== severity) out.push(deviation(`rules.sddRuleSeverity.${code}`, packs, severity));
|
|
13880
|
+
}
|
|
13881
|
+
if (settings.designDepth) {
|
|
13882
|
+
if (rules?.designDepth && rules.designDepth !== settings.designDepth) out.push(deviation("rules.designDepth", settings.designDepth, rules.designDepth));
|
|
13883
|
+
for (const s of subsystems) {
|
|
13884
|
+
if (s.designDepth && s.designDepth !== settings.designDepth) out.push(deviation(`the designDepth of subsystem "${s.id}"`, settings.designDepth, s.designDepth, s.id));
|
|
13885
|
+
}
|
|
13886
|
+
}
|
|
13887
|
+
const overlays = [
|
|
13888
|
+
...keyDeviations("rules.naming", settings.naming, rules?.naming),
|
|
13889
|
+
...keyDeviations("rules.naming.stereotypes", settings.naming?.stereotypes, rules?.naming?.stereotypes),
|
|
13890
|
+
...keyDeviations("rules.complexity", settings.complexity, rules?.complexity),
|
|
13891
|
+
...keyDeviations("rules.documentation", settings.documentation, rules?.documentation)
|
|
13892
|
+
];
|
|
13893
|
+
for (const o of overlays) out.push(deviation(o.setting, o.pack, o.member));
|
|
13894
|
+
if (settings.profile) {
|
|
13895
|
+
for (const s of subsystems) {
|
|
13896
|
+
if (s.profile && s.profile !== settings.profile) out.push(deviation(`the profile of subsystem "${s.id}"`, settings.profile, s.profile, s.id));
|
|
13897
|
+
}
|
|
13898
|
+
}
|
|
13899
|
+
for (const allow of allows) {
|
|
13900
|
+
if (settings.severities[allow.code] === void 0) continue;
|
|
13901
|
+
out.push(deviation(`a lint.allow of ${allow.code}${allow.at ? ` at "${allow.at}"` : ""} on "${allow.specId}"`, settings.severities[allow.code], "allowed", allow.specId));
|
|
13902
|
+
}
|
|
13903
|
+
return out;
|
|
13904
|
+
}
|
|
13479
13905
|
|
|
13480
13906
|
// src/core/rules/index.ts
|
|
13481
13907
|
var import_crypto2 = require("crypto");
|
|
@@ -13487,28 +13913,6 @@ var path14 = __toESM(require("path"));
|
|
|
13487
13913
|
var import_module = require("module");
|
|
13488
13914
|
var import_zod9 = require("zod");
|
|
13489
13915
|
|
|
13490
|
-
// src/utils/version.ts
|
|
13491
|
-
function isNewerVersion(current2, candidate) {
|
|
13492
|
-
const baseVersion = (v) => v.replace(/-.*$/, "");
|
|
13493
|
-
const preRelease = (v) => {
|
|
13494
|
-
const match = v.match(/-(.+)\.(\d+)$/);
|
|
13495
|
-
return match ? { label: match[1], n: parseInt(match[2], 10) } : null;
|
|
13496
|
-
};
|
|
13497
|
-
const parse = (v) => baseVersion(v).split(".").map((n) => parseInt(n, 10) || 0);
|
|
13498
|
-
const [cMaj, cMin, cPat] = parse(current2);
|
|
13499
|
-
const [nMaj, nMin, nPat] = parse(candidate);
|
|
13500
|
-
if (nMaj !== cMaj) return nMaj > cMaj;
|
|
13501
|
-
if (nMin !== cMin) return nMin > cMin;
|
|
13502
|
-
if (nPat !== cPat) return nPat > cPat;
|
|
13503
|
-
const cPre = preRelease(current2);
|
|
13504
|
-
const nPre = preRelease(candidate);
|
|
13505
|
-
if (!cPre && !nPre) return false;
|
|
13506
|
-
if (!cPre && nPre) return false;
|
|
13507
|
-
if (cPre && !nPre) return true;
|
|
13508
|
-
if (cPre && nPre) return nPre.n > cPre.n;
|
|
13509
|
-
return false;
|
|
13510
|
-
}
|
|
13511
|
-
|
|
13512
13916
|
// src/core/packstore.ts
|
|
13513
13917
|
var crypto2 = __toESM(require("crypto"));
|
|
13514
13918
|
var fs9 = __toESM(require("fs"));
|
|
@@ -13532,7 +13936,7 @@ function defaultTargetConfig(type) {
|
|
|
13532
13936
|
enabled: true
|
|
13533
13937
|
};
|
|
13534
13938
|
}
|
|
13535
|
-
var WAIRON_VERSION = "5.1.1-dev.
|
|
13939
|
+
var WAIRON_VERSION = "5.1.1-dev.85";
|
|
13536
13940
|
var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
13537
13941
|
var ARCHITECT_AGENT_ID = "agent-architect";
|
|
13538
13942
|
var ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -13783,7 +14187,7 @@ var PackSkillSchema = import_zod9.z.object({
|
|
|
13783
14187
|
});
|
|
13784
14188
|
var PackInstructionBlockSchema = import_zod9.z.union([
|
|
13785
14189
|
// Scalar shorthand: `instructions: >- …` — the common case, unscoped.
|
|
13786
|
-
import_zod9.z.string().min(1).transform((
|
|
14190
|
+
import_zod9.z.string().min(1).transform((text3) => ({ text: text3 })),
|
|
13787
14191
|
import_zod9.z.object({
|
|
13788
14192
|
text: import_zod9.z.string().min(1),
|
|
13789
14193
|
profile: import_zod9.z.array(import_zod9.z.string().min(1)).min(1).optional()
|
|
@@ -13884,6 +14288,11 @@ function checkDeclarativePack(manifest) {
|
|
|
13884
14288
|
const result = DeclarativePackSchema.safeParse(manifest);
|
|
13885
14289
|
return result.success ? null : result.error.issues[0]?.message ?? "shape mismatch";
|
|
13886
14290
|
}
|
|
14291
|
+
function parseDeclarativePack(manifest) {
|
|
14292
|
+
const result = DeclarativePackSchema.safeParse(manifest);
|
|
14293
|
+
if (!result.success) throw new Error(result.error.issues[0]?.message ?? "shape mismatch");
|
|
14294
|
+
return { ...result.data, rules: [] };
|
|
14295
|
+
}
|
|
13887
14296
|
function globalPacksEnabled(config) {
|
|
13888
14297
|
return config.extensions?.useGlobalPacks ?? GLOBAL_PACKS_DEFAULT;
|
|
13889
14298
|
}
|
|
@@ -14004,32 +14413,57 @@ function readManifest(target, projectRoot) {
|
|
|
14004
14413
|
}
|
|
14005
14414
|
function loadExtensionPacks(refs, projectRoot) {
|
|
14006
14415
|
const out = emptyExtensions();
|
|
14007
|
-
for (const
|
|
14008
|
-
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
|
|
14416
|
+
for (const ref of refs) loadRefInto(out, ref, projectRoot);
|
|
14417
|
+
return out;
|
|
14418
|
+
}
|
|
14419
|
+
function loadRefInto(out, { ref, scope, manifest: supplied }, projectRoot) {
|
|
14420
|
+
try {
|
|
14421
|
+
if (supplied) {
|
|
14422
|
+
mergePack(out, supplied, ref, scope, path14.resolve(projectRoot, ref));
|
|
14423
|
+
for (const r of supplied.rules) out.rules.push(r);
|
|
14424
|
+
return;
|
|
14015
14425
|
}
|
|
14426
|
+
const target = resolvePackRef(ref, projectRoot);
|
|
14427
|
+
const manifest = readManifest(target, projectRoot);
|
|
14428
|
+
mergePack(out, manifest, ref, scope, path14.dirname(target));
|
|
14429
|
+
for (const r of manifest.rules) out.rules.push(r);
|
|
14430
|
+
} catch (e) {
|
|
14431
|
+
out.errors.push(`Extension pack "${ref}" failed to load: ${e instanceof Error ? e.message : String(e)}`);
|
|
14016
14432
|
}
|
|
14017
|
-
return out;
|
|
14018
14433
|
}
|
|
14019
14434
|
function loadExtensions(packRefs, projectRoot) {
|
|
14020
14435
|
return loadExtensionPacks(packRefs.map((ref) => ({ ref, scope: "project" })), projectRoot);
|
|
14021
14436
|
}
|
|
14022
14437
|
function loadProjectExtensions() {
|
|
14438
|
+
let config;
|
|
14439
|
+
try {
|
|
14440
|
+
config = projectConfigRepository.load();
|
|
14441
|
+
} catch {
|
|
14442
|
+
config = null;
|
|
14443
|
+
}
|
|
14444
|
+
if (!config) return emptyExtensions();
|
|
14445
|
+
return loadFor(config);
|
|
14446
|
+
}
|
|
14447
|
+
function isCandidateEntry(entry, candidate) {
|
|
14448
|
+
const target = candidate?.entry;
|
|
14449
|
+
if (target === void 0) return false;
|
|
14450
|
+
if (typeof target === "string") return entry === target;
|
|
14451
|
+
return typeof entry !== "string" && entry.name === target.name;
|
|
14452
|
+
}
|
|
14453
|
+
function loadFor(config, candidate) {
|
|
14023
14454
|
try {
|
|
14024
|
-
const config = projectConfigRepository.load();
|
|
14025
|
-
if (!config) return emptyExtensions();
|
|
14026
14455
|
const projectRoot = getProjectRoot();
|
|
14027
14456
|
const refs = [];
|
|
14028
14457
|
const unresolved = [];
|
|
14458
|
+
const supplied = candidate?.manifest && !candidate.remove ? candidate.manifest : void 0;
|
|
14029
14459
|
if (globalPacksEnabled(config)) {
|
|
14030
14460
|
for (const ref of discoverPacks(globalPacksDir())) refs.push({ ref, scope: "global" });
|
|
14031
14461
|
}
|
|
14032
14462
|
for (const entry of config.extensions?.packs ?? []) {
|
|
14463
|
+
if (supplied && isCandidateEntry(entry, candidate)) {
|
|
14464
|
+
refs.push({ ref: packEntryLabel(entry), scope: "project", manifest: supplied });
|
|
14465
|
+
continue;
|
|
14466
|
+
}
|
|
14033
14467
|
if (typeof entry === "string") {
|
|
14034
14468
|
refs.push({ ref: entry, scope: "project" });
|
|
14035
14469
|
continue;
|
|
@@ -14039,7 +14473,8 @@ function loadProjectExtensions() {
|
|
|
14039
14473
|
if (resolution.failure) unresolved.push(resolution.failure);
|
|
14040
14474
|
}
|
|
14041
14475
|
if (refs.length === 0 && unresolved.length === 0) return emptyExtensions();
|
|
14042
|
-
const loaded =
|
|
14476
|
+
const loaded = emptyExtensions();
|
|
14477
|
+
for (const item of refs) loadRefInto(loaded, item, projectRoot);
|
|
14043
14478
|
for (const problem of skillExtendErrors(loaded.skills)) loaded.errors.push(problem);
|
|
14044
14479
|
loaded.selectionFailures.push(...unresolved);
|
|
14045
14480
|
return loaded;
|
|
@@ -14047,6 +14482,23 @@ function loadProjectExtensions() {
|
|
|
14047
14482
|
return emptyExtensions();
|
|
14048
14483
|
}
|
|
14049
14484
|
}
|
|
14485
|
+
function manifestOf(entry) {
|
|
14486
|
+
const projectRoot = getProjectRoot();
|
|
14487
|
+
let ref;
|
|
14488
|
+
if (typeof entry !== "string") {
|
|
14489
|
+
const resolution = resolveSelection(entry, projectRoot);
|
|
14490
|
+
if (!resolution.ref) return null;
|
|
14491
|
+
ref = resolution.ref;
|
|
14492
|
+
} else {
|
|
14493
|
+
ref = entry;
|
|
14494
|
+
}
|
|
14495
|
+
try {
|
|
14496
|
+
const target = resolvePackRef(ref, projectRoot);
|
|
14497
|
+
return readManifest(target, projectRoot);
|
|
14498
|
+
} catch {
|
|
14499
|
+
return null;
|
|
14500
|
+
}
|
|
14501
|
+
}
|
|
14050
14502
|
function defaultPackSelections() {
|
|
14051
14503
|
try {
|
|
14052
14504
|
const out = [];
|
|
@@ -14243,21 +14695,21 @@ function buildCodeIndex(model) {
|
|
|
14243
14695
|
const declarations = /* @__PURE__ */ new Map();
|
|
14244
14696
|
const anchors = /* @__PURE__ */ new Map();
|
|
14245
14697
|
const findingAnchors = /* @__PURE__ */ new Map();
|
|
14246
|
-
const namesAt = (cache,
|
|
14247
|
-
const cached = cache.get(
|
|
14698
|
+
const namesAt = (cache, path38, make) => {
|
|
14699
|
+
const cached = cache.get(path38);
|
|
14248
14700
|
if (cached) return cached;
|
|
14249
|
-
const f = facts.get(
|
|
14701
|
+
const f = facts.get(path38);
|
|
14250
14702
|
if (!f) return NO_NAMES;
|
|
14251
14703
|
const built = make(f);
|
|
14252
|
-
cache.set(
|
|
14704
|
+
cache.set(path38, built);
|
|
14253
14705
|
return built;
|
|
14254
14706
|
};
|
|
14255
14707
|
const republished = /* @__PURE__ */ new Map();
|
|
14256
|
-
const republishedFrom = (
|
|
14257
|
-
const cached = republished.get(
|
|
14708
|
+
const republishedFrom = (path38) => {
|
|
14709
|
+
const cached = republished.get(path38);
|
|
14258
14710
|
if (cached) return cached;
|
|
14259
|
-
const out = /* @__PURE__ */ new Set([
|
|
14260
|
-
const queue = [
|
|
14711
|
+
const out = /* @__PURE__ */ new Set([path38]);
|
|
14712
|
+
const queue = [path38];
|
|
14261
14713
|
while (queue.length) {
|
|
14262
14714
|
const from = queue.pop();
|
|
14263
14715
|
const f = facts.get(from);
|
|
@@ -14270,7 +14722,7 @@ function buildCodeIndex(model) {
|
|
|
14270
14722
|
}
|
|
14271
14723
|
}
|
|
14272
14724
|
}
|
|
14273
|
-
republished.set(
|
|
14725
|
+
republished.set(path38, out);
|
|
14274
14726
|
return out;
|
|
14275
14727
|
};
|
|
14276
14728
|
const NO_ORIGIN = /* @__PURE__ */ new Set();
|
|
@@ -14279,9 +14731,9 @@ function buildCodeIndex(model) {
|
|
|
14279
14731
|
return to ? republishedFrom(to) : NO_ORIGIN;
|
|
14280
14732
|
};
|
|
14281
14733
|
const scopeOf = (site, from) => {
|
|
14282
|
-
const
|
|
14283
|
-
const f = facts.get(
|
|
14284
|
-
return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path:
|
|
14734
|
+
const path38 = pathKey(site.from ?? from);
|
|
14735
|
+
const f = facts.get(path38);
|
|
14736
|
+
return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path: path38, facts: f } : void 0;
|
|
14285
14737
|
};
|
|
14286
14738
|
const originOf2 = (site, from) => {
|
|
14287
14739
|
const resolved = scopeOf(site, from);
|
|
@@ -14320,7 +14772,7 @@ function buildCodeIndex(model) {
|
|
|
14320
14772
|
if (site.via) for (const typeName of localTypesOf(f, site.via)) widenThroughType(typeName);
|
|
14321
14773
|
return out;
|
|
14322
14774
|
};
|
|
14323
|
-
const declarationsAt = (
|
|
14775
|
+
const declarationsAt = (path38) => namesAt(declarations, pathKey(path38), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames]));
|
|
14324
14776
|
const forwardsOf = (start, name) => {
|
|
14325
14777
|
const out = [];
|
|
14326
14778
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -14346,10 +14798,10 @@ function buildCodeIndex(model) {
|
|
|
14346
14798
|
return {
|
|
14347
14799
|
paths,
|
|
14348
14800
|
exactPaths,
|
|
14349
|
-
factsAt: (
|
|
14801
|
+
factsAt: (path38) => facts.get(pathKey(path38)),
|
|
14350
14802
|
declarationsAt,
|
|
14351
|
-
anchorsAt: (
|
|
14352
|
-
findingAnchorsAt: (
|
|
14803
|
+
anchorsAt: (path38) => namesAt(anchors, pathKey(path38), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames, ...f.anchoredNames])),
|
|
14804
|
+
findingAnchorsAt: (path38) => namesAt(findingAnchors, pathKey(path38), (f) => new Set(f.anchoredNames)),
|
|
14353
14805
|
originOf: originOf2,
|
|
14354
14806
|
possibleOriginsOf,
|
|
14355
14807
|
forwardsOf
|
|
@@ -14388,10 +14840,10 @@ function buildRealizationIndex(ctx) {
|
|
|
14388
14840
|
return {
|
|
14389
14841
|
paths,
|
|
14390
14842
|
implementationsOf: (compId) => implsByComponent.get(compId) ?? NONE_IMPL,
|
|
14391
|
-
implementationsAt: (
|
|
14843
|
+
implementationsAt: (path38) => implsByPath.get(pathKey(path38)) ?? NONE_IMPL,
|
|
14392
14844
|
filesOf: (compId) => filesByComponent.get(compId) ?? NONE_PATH,
|
|
14393
14845
|
filesIn: (subsystemId) => filesBySubsystem.get(subsystemId) ?? NONE_PATH,
|
|
14394
|
-
componentsAt: (
|
|
14846
|
+
componentsAt: (path38) => componentsByPath.get(pathKey(path38)) ?? NONE_COMP
|
|
14395
14847
|
};
|
|
14396
14848
|
}
|
|
14397
14849
|
function buildImportGraph(index, universe) {
|
|
@@ -14403,22 +14855,22 @@ function buildImportGraph(index, universe) {
|
|
|
14403
14855
|
if (to && to !== from) into.add(to);
|
|
14404
14856
|
}
|
|
14405
14857
|
};
|
|
14406
|
-
const importsOf = (
|
|
14407
|
-
const cached = imports.get(
|
|
14858
|
+
const importsOf = (path38) => {
|
|
14859
|
+
const cached = imports.get(path38);
|
|
14408
14860
|
if (cached) return cached;
|
|
14409
|
-
const facts = index.factsAt(
|
|
14861
|
+
const facts = index.factsAt(path38);
|
|
14410
14862
|
const out = /* @__PURE__ */ new Set();
|
|
14411
|
-
if (facts?.status === "analyzed") resolveAll(
|
|
14412
|
-
imports.set(
|
|
14863
|
+
if (facts?.status === "analyzed") resolveAll(path38, facts.imports, out);
|
|
14864
|
+
imports.set(path38, out);
|
|
14413
14865
|
return out;
|
|
14414
14866
|
};
|
|
14415
|
-
const tracesOf = (
|
|
14416
|
-
const cached = traces.get(
|
|
14867
|
+
const tracesOf = (path38) => {
|
|
14868
|
+
const cached = traces.get(path38);
|
|
14417
14869
|
if (cached) return cached;
|
|
14418
|
-
const facts = index.factsAt(
|
|
14419
|
-
const out = new Set(importsOf(
|
|
14420
|
-
if (facts?.status === "analyzed") resolveAll(
|
|
14421
|
-
traces.set(
|
|
14870
|
+
const facts = index.factsAt(path38);
|
|
14871
|
+
const out = new Set(importsOf(path38));
|
|
14872
|
+
if (facts?.status === "analyzed") resolveAll(path38, facts.reexports, out);
|
|
14873
|
+
traces.set(path38, out);
|
|
14422
14874
|
return out;
|
|
14423
14875
|
};
|
|
14424
14876
|
return {
|
|
@@ -14698,17 +15150,17 @@ var projectIdentityRule = {
|
|
|
14698
15150
|
{ code: "PROJECT_ID_DEFAULTED", defaultSeverity: "notice", summary: "Project declares no id; it answers to one derived from its display name" }
|
|
14699
15151
|
],
|
|
14700
15152
|
check(ctx) {
|
|
14701
|
-
const
|
|
14702
|
-
if (
|
|
15153
|
+
const identity2 = ctx.projectIdentity;
|
|
15154
|
+
if (identity2) judgeOwnIdentity(ctx, identity2);
|
|
14703
15155
|
}
|
|
14704
15156
|
};
|
|
14705
|
-
function judgeOwnIdentity(ctx,
|
|
14706
|
-
const problem = (kind) =>
|
|
15157
|
+
function judgeOwnIdentity(ctx, identity2) {
|
|
15158
|
+
const problem = (kind) => identity2.problems.find((p) => p.kind === kind);
|
|
14707
15159
|
if (problem("defaulted")) {
|
|
14708
15160
|
ctx.addIssue(
|
|
14709
15161
|
"notice",
|
|
14710
15162
|
"PROJECT_ID_DEFAULTED",
|
|
14711
|
-
`Project "${
|
|
15163
|
+
`Project "${identity2.name}" declares no id in .wai/project.yaml, so it answers to "${identity2.id}", derived from its display name \u2014 renaming the project would move it. No save writes it for you; declare it with \`id: ${identity2.id}\` (stage 3 requires an explicit id).`
|
|
14712
15164
|
);
|
|
14713
15165
|
}
|
|
14714
15166
|
const ambiguous = problem("ambiguous");
|
|
@@ -14716,15 +15168,15 @@ function judgeOwnIdentity(ctx, identity) {
|
|
|
14716
15168
|
ctx.addIssue(
|
|
14717
15169
|
"warning",
|
|
14718
15170
|
"PROJECT_ID_AMBIGUOUS",
|
|
14719
|
-
`Project "${
|
|
15171
|
+
`Project "${identity2.name}" has no usable id: ${ambiguous.detail}. A project id is lower-case letters, digits, "-", "_" and ".", starting and ending with a letter or a digit \u2014 declare one in .wai/project.yaml.`
|
|
14720
15172
|
);
|
|
14721
15173
|
}
|
|
14722
15174
|
if (problem("changed")) {
|
|
14723
|
-
const now =
|
|
15175
|
+
const now = identity2.id === void 0 ? "no id at all" : `"${identity2.id}"`;
|
|
14724
15176
|
ctx.addIssue(
|
|
14725
15177
|
"error",
|
|
14726
15178
|
"PROJECT_ID_CHANGED",
|
|
14727
|
-
`Project "${
|
|
15179
|
+
`Project "${identity2.name}" now resolves to ${now}, but its lock approved "${identity2.lockedId}" \u2014 everything keyed on the approved id no longer finds this project. Restore \`id: ${identity2.lockedId}\` in .wai/project.yaml, or rename deliberately and re-lock.`
|
|
14728
15180
|
);
|
|
14729
15181
|
}
|
|
14730
15182
|
}
|
|
@@ -15848,7 +16300,7 @@ var narrativeJumpEdgesRule = {
|
|
|
15848
16300
|
const byNum = /* @__PURE__ */ new Map();
|
|
15849
16301
|
for (const s of steps) byNum.set(s.stepNumber, s);
|
|
15850
16302
|
const nums = [...byNum.keys()].sort((a, b) => a - b);
|
|
15851
|
-
const
|
|
16303
|
+
const nextOf2 = (n) => {
|
|
15852
16304
|
const i = nums.indexOf(n);
|
|
15853
16305
|
return i !== -1 && i + 1 < nums.length ? nums[i + 1] : void 0;
|
|
15854
16306
|
};
|
|
@@ -15857,7 +16309,7 @@ var narrativeJumpEdgesRule = {
|
|
|
15857
16309
|
const handlerStarts = new Set((s.catches ?? []).map((c) => c.step));
|
|
15858
16310
|
if (s.finallyStep !== void 0) handlerStarts.add(s.finallyStep);
|
|
15859
16311
|
const last = byNum.get(s.endStep);
|
|
15860
|
-
const nxt =
|
|
16312
|
+
const nxt = nextOf2(s.endStep);
|
|
15861
16313
|
if (last && (last.type === "local" || last.type === "call" || last.type === "register" || last.type === "dispatch") && nxt !== void 0 && handlerStarts.has(nxt)) {
|
|
15862
16314
|
ctx.addIssue(
|
|
15863
16315
|
"warning",
|
|
@@ -16155,11 +16607,11 @@ var unconditionalCallCyclesRule = {
|
|
|
16155
16607
|
const memberEdges = keys.flatMap((k) => (adjacency.get(k) ?? []).filter((e) => inScc.has(e.toKey)));
|
|
16156
16608
|
if (memberEdges.length === 0) continue;
|
|
16157
16609
|
const anchor = [...memberEdges].sort((a, b) => byCodeUnit(a.fromKey, b.fromKey) || byCodeUnit(a.impl.id, b.impl.id) || a.stepNumber - b.stepNumber)[0];
|
|
16158
|
-
const
|
|
16610
|
+
const path38 = [...keys].sort(byCodeUnit).join(" \u2192 ");
|
|
16159
16611
|
ctx.addIssue(
|
|
16160
16612
|
"warning",
|
|
16161
16613
|
"UNCONDITIONAL_CALL_CYCLE",
|
|
16162
|
-
`Call cycle with no guard: ${
|
|
16614
|
+
`Call cycle with no guard: ${path38} \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.`,
|
|
16163
16615
|
anchor.impl.id,
|
|
16164
16616
|
memberEdges.some((e) => ctx.isImplementationDraft(e.impl))
|
|
16165
16617
|
);
|
|
@@ -17604,6 +18056,27 @@ var reproducibilityRule = {
|
|
|
17604
18056
|
}
|
|
17605
18057
|
};
|
|
17606
18058
|
|
|
18059
|
+
// src/core/rules/extension/pack-requirements.ts
|
|
18060
|
+
var packRequirementsRule = {
|
|
18061
|
+
name: "pack-requirements",
|
|
18062
|
+
description: "Every requirement in the bound project's own composition.requirePolicies must be readable: a pack name and a semver range that parses (pack_requirement.rangeProblem). One that does not is POLICY_REQUIREMENT_INVALID, quoting the range and the unreadable token \u2014 an error on the requiring project's own gate, because the requirement is its own configuration and the family run cannot judge a member against it. It judges only the syntax: whether members adopt the requirement is the family run's question (family_validator.adoption), and nothing here reads a parent's requirements.",
|
|
18063
|
+
codes: [
|
|
18064
|
+
{ code: "POLICY_REQUIREMENT_INVALID", defaultSeverity: "error", summary: "A project's composition.requirePolicies names a pack range that does not parse" }
|
|
18065
|
+
],
|
|
18066
|
+
check(ctx) {
|
|
18067
|
+
for (const requirement of ctx.ext.packRequirements) {
|
|
18068
|
+
const problem = requirement.pack.trim() === "" ? "it names no pack" : rangeProblem(requirement);
|
|
18069
|
+
if (problem === null) continue;
|
|
18070
|
+
const which = requirement.pack.trim() === "" ? "A requirement" : `The requirement for pack "${requirement.pack}"`;
|
|
18071
|
+
ctx.addIssue(
|
|
18072
|
+
"error",
|
|
18073
|
+
"POLICY_REQUIREMENT_INVALID",
|
|
18074
|
+
`${which} in composition.requirePolicies cannot be read: range "${requirement.version}" \u2014 ${problem}. The family run cannot judge any member against it until it parses; write an exact version (1.2.0), a caret or tilde range (^1.2, ~1.2.3), an x-range (1.x, *), a comparator set (>=1.2.0 <2.0.0) or alternatives joined by \`||\`.`
|
|
18075
|
+
);
|
|
18076
|
+
}
|
|
18077
|
+
}
|
|
18078
|
+
};
|
|
18079
|
+
|
|
17607
18080
|
// src/core/rules/wiring/dependency-cycles.ts
|
|
17608
18081
|
var cyclesRule = {
|
|
17609
18082
|
name: "dependency-cycles",
|
|
@@ -17844,8 +18317,8 @@ var lifecycleRule = {
|
|
|
17844
18317
|
};
|
|
17845
18318
|
|
|
17846
18319
|
// src/core/rules/wiring/portal-mounts.ts
|
|
17847
|
-
function liesUnder(
|
|
17848
|
-
return
|
|
18320
|
+
function liesUnder(path38, prefix) {
|
|
18321
|
+
return path38 === prefix || path38.startsWith(prefix + "/");
|
|
17849
18322
|
}
|
|
17850
18323
|
var portalMountsRule = {
|
|
17851
18324
|
name: "portal-mounts",
|
|
@@ -18298,8 +18771,8 @@ function componentOfImpl(ctx, implContract) {
|
|
|
18298
18771
|
}
|
|
18299
18772
|
var CLAIM_PHRASES = /\b(persist(s|ed|ent|ing|ence)?|survives?\s+(a\s+)?restart|writ(es?|ten)\s+to\s+disk|registered\s+into|durabl[ey])\b/i;
|
|
18300
18773
|
var QUOTED_SPAN = /"[^"]*"|“[^”]*”|`[^`]*`|(?<![\p{L}\p{N}])['‘](?:[^'‘’]|(?<=[\p{L}\p{N}])['’](?=[\p{L}\p{N}]))*['’](?![\p{L}\p{N}])/gu;
|
|
18301
|
-
function withoutQuotedText(
|
|
18302
|
-
return
|
|
18774
|
+
function withoutQuotedText(text3) {
|
|
18775
|
+
return text3.replace(QUOTED_SPAN, " ");
|
|
18303
18776
|
}
|
|
18304
18777
|
var proseClaimRule = {
|
|
18305
18778
|
name: "prose-claims",
|
|
@@ -19052,11 +19525,11 @@ var hiddenStateRule = {
|
|
|
19052
19525
|
byPath.set(key, list);
|
|
19053
19526
|
}
|
|
19054
19527
|
}
|
|
19055
|
-
for (const
|
|
19056
|
-
const facts = code.factsAt(
|
|
19528
|
+
for (const path38 of code.exactPaths) {
|
|
19529
|
+
const facts = code.factsAt(path38);
|
|
19057
19530
|
const bindings = facts.topLevelMutableBindings ?? [];
|
|
19058
19531
|
if (bindings.length === 0) continue;
|
|
19059
|
-
const mapped = byPath.get(
|
|
19532
|
+
const mapped = byPath.get(path38) ?? [];
|
|
19060
19533
|
if (mapped.length === 0) continue;
|
|
19061
19534
|
if (!mapped.every((m) => isStatelessLogic(m.component))) continue;
|
|
19062
19535
|
const anchor = [...mapped].sort((a, b) => a.impl.id.localeCompare(b.impl.id))[0];
|
|
@@ -19122,7 +19595,7 @@ var dependencyConformanceRule = {
|
|
|
19122
19595
|
}
|
|
19123
19596
|
return false;
|
|
19124
19597
|
};
|
|
19125
|
-
const draftAt = (
|
|
19598
|
+
const draftAt = (path38) => realization.implementationsAt(path38).some((impl) => ctx.isImplementationDraft(impl));
|
|
19126
19599
|
for (const fromPath of mappedPaths) {
|
|
19127
19600
|
const fromComponents = realization.componentsAt(fromPath);
|
|
19128
19601
|
for (const toPath of graph2.importsOf(fromPath)) {
|
|
@@ -19207,7 +19680,7 @@ var portalImportsRule = {
|
|
|
19207
19680
|
}
|
|
19208
19681
|
return files;
|
|
19209
19682
|
};
|
|
19210
|
-
const draftAt = (
|
|
19683
|
+
const draftAt = (path38) => realization.implementationsAt(path38).some((impl) => ctx.isImplementationDraft(impl));
|
|
19211
19684
|
for (const fromPath of mappedPaths) {
|
|
19212
19685
|
const fromSubsystems = new Set(realization.componentsAt(fromPath).map((c) => c.subsystem));
|
|
19213
19686
|
for (const toPath of graph2.importsOf(fromPath)) {
|
|
@@ -19668,7 +20141,7 @@ var paramConformanceRule = {
|
|
|
19668
20141
|
codeNameOf.set(type.id, named2);
|
|
19669
20142
|
if (type.subsystem) codeNameOf.set(`${type.subsystem}.${type.id}`, named2);
|
|
19670
20143
|
}
|
|
19671
|
-
const normalize3 = (
|
|
20144
|
+
const normalize3 = (text3) => text3.replace(/\s+/g, " ").trim();
|
|
19672
20145
|
const typeAgrees = (declared, realized) => {
|
|
19673
20146
|
if (!realized.type) return false;
|
|
19674
20147
|
const stated = normalize3(declared.type);
|
|
@@ -19743,8 +20216,8 @@ var paramConformanceRule = {
|
|
|
19743
20216
|
};
|
|
19744
20217
|
|
|
19745
20218
|
// src/core/rules/conformance/route-coverage.ts
|
|
19746
|
-
function liesUnder2(
|
|
19747
|
-
return
|
|
20219
|
+
function liesUnder2(path38, prefix) {
|
|
20220
|
+
return path38 === prefix || path38.startsWith(prefix + "/");
|
|
19748
20221
|
}
|
|
19749
20222
|
function normalizeSegment(segment) {
|
|
19750
20223
|
return /^\{.+\}$/.test(segment) || segment.startsWith(":") ? "*" : segment;
|
|
@@ -20499,9 +20972,9 @@ function makeMatcher(tech) {
|
|
|
20499
20972
|
const joined = parts.join("");
|
|
20500
20973
|
if (joined.length < 3) return null;
|
|
20501
20974
|
const n = parts.length;
|
|
20502
|
-
return (
|
|
20503
|
-
if (!
|
|
20504
|
-
const words2 =
|
|
20975
|
+
return (text3) => {
|
|
20976
|
+
if (!text3) return false;
|
|
20977
|
+
const words2 = text3.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
20505
20978
|
if (words2.some((w) => w.includes(joined))) return true;
|
|
20506
20979
|
if (n < 2) return false;
|
|
20507
20980
|
for (let i = 0; i + n <= words2.length; i++) {
|
|
@@ -21425,6 +21898,10 @@ var SDD_RULES = [
|
|
|
21425
21898
|
// elsewhere?) rather than spec content.
|
|
21426
21899
|
packResolutionRule,
|
|
21427
21900
|
reproducibilityRule,
|
|
21901
|
+
// The syntax of this project's own composition.requirePolicies (governance
|
|
21902
|
+
// stage): configuration too, and the family run cannot judge a member against
|
|
21903
|
+
// a requirement that does not parse.
|
|
21904
|
+
packRequirementsRule,
|
|
21428
21905
|
// MUST run last, in this order: each audits what the earlier rules did
|
|
21429
21906
|
// with a declared exception. The debt register first (which carried
|
|
21430
21907
|
// findings the conformance family actually matched), then the allows
|
|
@@ -21590,8 +22067,8 @@ LANGUAGE_PATTERNS.cpp = LANGUAGE_PATTERNS.c;
|
|
|
21590
22067
|
var PATTERN_ANALYSIS_MAX_BYTES = 1e6;
|
|
21591
22068
|
var IDENTIFIER_RE = /[A-Za-z_$][\w$]*/g;
|
|
21592
22069
|
var STRING_RE = /'([^'\\\n]*(?:\\.[^'\\\n]*)*)'|"([^"\\\n]*(?:\\.[^"\\\n]*)*)"|`([^`\\]*(?:\\.[^`\\]*)*)`/g;
|
|
21593
|
-
function stripComments(
|
|
21594
|
-
let out =
|
|
22070
|
+
function stripComments(text3, patterns) {
|
|
22071
|
+
let out = text3;
|
|
21595
22072
|
for (const [open, close] of patterns.blockComments) {
|
|
21596
22073
|
const re = new RegExp(`${escapeRe(open)}[\\s\\S]*?${escapeRe(close)}`, "g");
|
|
21597
22074
|
out = out.replace(re, " ");
|
|
@@ -21617,16 +22094,16 @@ function boundNames(captured, localOnly) {
|
|
|
21617
22094
|
}
|
|
21618
22095
|
return names;
|
|
21619
22096
|
}
|
|
21620
|
-
function collectStrings(
|
|
22097
|
+
function collectStrings(text3) {
|
|
21621
22098
|
const anchors = /* @__PURE__ */ new Set();
|
|
21622
|
-
for (const m of
|
|
22099
|
+
for (const m of text3.matchAll(STRING_RE)) {
|
|
21623
22100
|
const value = m[1] ?? m[2] ?? m[3];
|
|
21624
22101
|
if (value) anchors.add(value);
|
|
21625
22102
|
}
|
|
21626
22103
|
return anchors;
|
|
21627
22104
|
}
|
|
21628
|
-
function analyzeWithPatterns(
|
|
21629
|
-
const stripped = stripComments(
|
|
22105
|
+
function analyzeWithPatterns(text3, patterns) {
|
|
22106
|
+
const stripped = stripComments(text3, patterns);
|
|
21630
22107
|
const declared = /* @__PURE__ */ new Set();
|
|
21631
22108
|
const exported = /* @__PURE__ */ new Set();
|
|
21632
22109
|
const imports = /* @__PURE__ */ new Set();
|
|
@@ -21654,7 +22131,7 @@ function analyzeWithPatterns(text2, patterns) {
|
|
|
21654
22131
|
}
|
|
21655
22132
|
}
|
|
21656
22133
|
}
|
|
21657
|
-
const anchors = collectStrings(
|
|
22134
|
+
const anchors = collectStrings(text3);
|
|
21658
22135
|
for (const m of stripped.matchAll(IDENTIFIER_RE)) anchors.add(m[0]);
|
|
21659
22136
|
return {
|
|
21660
22137
|
analysisGrade: "pattern",
|
|
@@ -21665,11 +22142,11 @@ function analyzeWithPatterns(text2, patterns) {
|
|
|
21665
22142
|
reexports: []
|
|
21666
22143
|
};
|
|
21667
22144
|
}
|
|
21668
|
-
function analyzeGeneric(
|
|
22145
|
+
function analyzeGeneric(text3) {
|
|
21669
22146
|
const words2 = /* @__PURE__ */ new Set();
|
|
21670
|
-
for (const m of
|
|
22147
|
+
for (const m of text3.matchAll(IDENTIFIER_RE)) words2.add(m[0]);
|
|
21671
22148
|
const anchors = new Set(words2);
|
|
21672
|
-
for (const s of collectStrings(
|
|
22149
|
+
for (const s of collectStrings(text3)) anchors.add(s);
|
|
21673
22150
|
return {
|
|
21674
22151
|
analysisGrade: "generic",
|
|
21675
22152
|
declaredNames: [...words2],
|
|
@@ -22239,14 +22716,14 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
|
|
|
22239
22716
|
files.push({ path: sourcePath, status: "unreadable", ...empty });
|
|
22240
22717
|
continue;
|
|
22241
22718
|
}
|
|
22242
|
-
const
|
|
22719
|
+
const text3 = buffer.toString("utf8");
|
|
22243
22720
|
const language = EXTENSION_LANGUAGE[path15.extname(sourcePath).toLowerCase()];
|
|
22244
22721
|
let analyzed;
|
|
22245
22722
|
if (language === "typescript" || language === "javascript") {
|
|
22246
22723
|
const ts = resolveTypeScript(projectRoot);
|
|
22247
22724
|
if (ts) {
|
|
22248
22725
|
try {
|
|
22249
|
-
const facts = walkExact(ts,
|
|
22726
|
+
const facts = walkExact(ts, text3, absolute);
|
|
22250
22727
|
chaseReexports(ts, facts, absolute, projectRoot, /* @__PURE__ */ new Set([absolute]), exactCache);
|
|
22251
22728
|
analyzed = {
|
|
22252
22729
|
analysisGrade: "exact",
|
|
@@ -22272,15 +22749,15 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
|
|
|
22272
22749
|
reexportOnly: facts.reexportOnly
|
|
22273
22750
|
};
|
|
22274
22751
|
} catch {
|
|
22275
|
-
analyzed = analyzeGeneric(
|
|
22752
|
+
analyzed = analyzeGeneric(text3);
|
|
22276
22753
|
}
|
|
22277
22754
|
} else {
|
|
22278
|
-
analyzed = analyzeWithPatterns(
|
|
22755
|
+
analyzed = analyzeWithPatterns(text3, LANGUAGE_PATTERNS[language]);
|
|
22279
22756
|
}
|
|
22280
|
-
} else if (language && LANGUAGE_PATTERNS[language] &&
|
|
22281
|
-
analyzed = analyzeWithPatterns(
|
|
22757
|
+
} else if (language && LANGUAGE_PATTERNS[language] && text3.length <= PATTERN_ANALYSIS_MAX_BYTES) {
|
|
22758
|
+
analyzed = analyzeWithPatterns(text3, LANGUAGE_PATTERNS[language]);
|
|
22282
22759
|
} else {
|
|
22283
|
-
analyzed = analyzeGeneric(
|
|
22760
|
+
analyzed = analyzeGeneric(text3);
|
|
22284
22761
|
}
|
|
22285
22762
|
files.push({ path: sourcePath, status: "analyzed", language, ...analyzed });
|
|
22286
22763
|
}
|
|
@@ -22311,24 +22788,24 @@ function clauseBindings(clause, specifier) {
|
|
|
22311
22788
|
function readTestFiles(testRoots, projectRoot) {
|
|
22312
22789
|
const scanned = [];
|
|
22313
22790
|
for (const key of walkDeclaredRoots(testRoots, [], projectRoot)) {
|
|
22314
|
-
let
|
|
22791
|
+
let text3;
|
|
22315
22792
|
try {
|
|
22316
22793
|
const buffer = fs11.readFileSync(path15.resolve(projectRoot, key));
|
|
22317
22794
|
if (looksBinary(buffer)) continue;
|
|
22318
|
-
|
|
22795
|
+
text3 = buffer.toString("utf8");
|
|
22319
22796
|
} catch {
|
|
22320
22797
|
continue;
|
|
22321
22798
|
}
|
|
22322
22799
|
const imports = /* @__PURE__ */ new Set();
|
|
22323
|
-
for (const m of
|
|
22800
|
+
for (const m of text3.matchAll(NAMED_IMPORT_BINDINGS_RE)) {
|
|
22324
22801
|
for (const name of boundNames(m[1] ?? "", false)) imports.add(name);
|
|
22325
22802
|
}
|
|
22326
|
-
const code = stripComments(
|
|
22803
|
+
const code = stripComments(text3, JS_PATTERNS);
|
|
22327
22804
|
const bindings = [];
|
|
22328
22805
|
for (const m of code.matchAll(IMPORT_FROM_RE)) bindings.push(...clauseBindings(m[1], m[2]));
|
|
22329
22806
|
for (const m of code.matchAll(DYNAMIC_IMPORT_RE)) bindings.push(...clauseBindings(`{${m[1].replace(/:/g, " as ")}}`, m[2]));
|
|
22330
22807
|
const words2 = /* @__PURE__ */ new Set();
|
|
22331
|
-
for (const m of
|
|
22808
|
+
for (const m of text3.matchAll(IDENTIFIER_RE)) words2.add(m[0]);
|
|
22332
22809
|
scanned.push({ path: key, imports, bindings, words: words2 });
|
|
22333
22810
|
}
|
|
22334
22811
|
return scanned;
|
|
@@ -22745,8 +23222,8 @@ function buildRuleContext(opts) {
|
|
|
22745
23222
|
};
|
|
22746
23223
|
const authoredIndex = /* @__PURE__ */ new Map();
|
|
22747
23224
|
for (const r of family?.authoredReferences ?? []) {
|
|
22748
|
-
for (const
|
|
22749
|
-
const k = `${r.specId}\0${r.position}\0${
|
|
23225
|
+
for (const text3 of [r.authored, r.resolved]) {
|
|
23226
|
+
const k = `${r.specId}\0${r.position}\0${text3}`;
|
|
22750
23227
|
if (!authoredIndex.has(k)) authoredIndex.set(k, r);
|
|
22751
23228
|
}
|
|
22752
23229
|
}
|
|
@@ -22926,12 +23403,12 @@ function buildRuleContext(opts) {
|
|
|
22926
23403
|
}
|
|
22927
23404
|
return defaultSeverity;
|
|
22928
23405
|
};
|
|
22929
|
-
const
|
|
23406
|
+
const lintAllows2 = [];
|
|
22930
23407
|
const allowLookup = /* @__PURE__ */ new Map();
|
|
22931
23408
|
const collectAllows = (specId, lint) => {
|
|
22932
23409
|
for (const a of lint?.allow ?? []) {
|
|
22933
23410
|
const entry = { specId, code: a.code, at: a.at, covers: a.covers, reason: a.reason, used: false };
|
|
22934
|
-
|
|
23411
|
+
lintAllows2.push(entry);
|
|
22935
23412
|
if (!allowLookup.has(specId)) allowLookup.set(specId, /* @__PURE__ */ new Map());
|
|
22936
23413
|
const forSpec = allowLookup.get(specId);
|
|
22937
23414
|
const forCode = forSpec.get(a.code) ?? [];
|
|
@@ -22981,7 +23458,7 @@ function buildRuleContext(opts) {
|
|
|
22981
23458
|
}
|
|
22982
23459
|
const severity = getRuleSeverity(code, defaultSeverity, isDraftContext, owner);
|
|
22983
23460
|
if (severity === "off") return;
|
|
22984
|
-
let
|
|
23461
|
+
let text3 = message;
|
|
22985
23462
|
if (specId) {
|
|
22986
23463
|
const key = `${specId}\0${code}`;
|
|
22987
23464
|
let seen = sitesSeen.get(key);
|
|
@@ -22999,7 +23476,7 @@ function buildRuleContext(opts) {
|
|
|
22999
23476
|
if (grew.length === 0) {
|
|
23000
23477
|
if (severity !== "error") return;
|
|
23001
23478
|
} else {
|
|
23002
|
-
|
|
23479
|
+
text3 = `${text3} A lint.allow covers this site, but not ${grew.length} part(s) of it \u2014 ${grew.map((u) => `"${u}"`).join("; ")} ${grew.length === 1 ? "is" : "are"} new. Decide on them: add them to the allow's \`covers\` with a reason that is actually true, or fix them.`;
|
|
23003
23480
|
}
|
|
23004
23481
|
}
|
|
23005
23482
|
}
|
|
@@ -23014,13 +23491,13 @@ function buildRuleContext(opts) {
|
|
|
23014
23491
|
else grew.push(unit);
|
|
23015
23492
|
}
|
|
23016
23493
|
if (grew.length === 0) return;
|
|
23017
|
-
|
|
23494
|
+
text3 = `${text3} The conformance debt register carries this finding, but not ${grew.length} part(s) of it \u2014 ${grew.map((u) => `"${u}"`).join("; ")} ${grew.length === 1 ? "is" : "are"} new. Fix them, or add them to the entry's \`covers\` with a reason that is actually true.`;
|
|
23018
23495
|
}
|
|
23019
23496
|
}
|
|
23020
23497
|
issues.push({
|
|
23021
23498
|
severity,
|
|
23022
23499
|
code,
|
|
23023
|
-
message:
|
|
23500
|
+
message: text3,
|
|
23024
23501
|
specId,
|
|
23025
23502
|
...isDraftContext ? { draftContext: true } : {},
|
|
23026
23503
|
...resolution ? { resolution } : {}
|
|
@@ -23089,7 +23566,7 @@ function buildRuleContext(opts) {
|
|
|
23089
23566
|
documentationConfigFor,
|
|
23090
23567
|
namingConfigFor,
|
|
23091
23568
|
isBuiltinType,
|
|
23092
|
-
ext: { profiles: extensions.profiles, languages: extensions.languages, patterns: extensions.patterns, guarantees: extensions.guarantees, assertions: extensions.assertions, packSelections: opts.packSelections ?? [], selectionFailures: extensions.selectionFailures ?? [] },
|
|
23569
|
+
ext: { profiles: extensions.profiles, languages: extensions.languages, patterns: extensions.patterns, guarantees: extensions.guarantees, assertions: extensions.assertions, packSelections: opts.packSelections ?? [], selectionFailures: extensions.selectionFailures ?? [], packRequirements: opts.packRequirements ?? [] },
|
|
23093
23570
|
variants: opts.variants ?? [],
|
|
23094
23571
|
surfaceSnapshots,
|
|
23095
23572
|
...opts.projectIdentity ? { projectIdentity: opts.projectIdentity } : {},
|
|
@@ -23099,7 +23576,7 @@ function buildRuleContext(opts) {
|
|
|
23099
23576
|
pinnedExternals,
|
|
23100
23577
|
codeModel: opts.codeModel ?? emptyCodeModel(),
|
|
23101
23578
|
roundTripIssues: opts.roundTripIssues,
|
|
23102
|
-
lintAllows,
|
|
23579
|
+
lintAllows: lintAllows2,
|
|
23103
23580
|
sitesReported,
|
|
23104
23581
|
knownIssueCodes: opts.knownIssueCodes,
|
|
23105
23582
|
carriedFindings,
|
|
@@ -23158,10 +23635,103 @@ function validateComponentCandidate(candidate, opts = {}) {
|
|
|
23158
23635
|
};
|
|
23159
23636
|
}
|
|
23160
23637
|
|
|
23638
|
+
// src/core/pack-impact.ts
|
|
23639
|
+
var path16 = __toESM(require("path"));
|
|
23640
|
+
function authorableStereotypes() {
|
|
23641
|
+
return ComponentTypeSchema.options.filter((t) => !RETIRED_STEREOTYPES.has(t));
|
|
23642
|
+
}
|
|
23643
|
+
function defaultsBaseline() {
|
|
23644
|
+
registerBuiltinRules();
|
|
23645
|
+
const ruleDefaults = {};
|
|
23646
|
+
for (const code of knownIssueCodes()) ruleDefaults[code.code] = code.defaultSeverity;
|
|
23647
|
+
return {
|
|
23648
|
+
ruleDefaults,
|
|
23649
|
+
profiles: builtinProfileIds(),
|
|
23650
|
+
projectKinds: builtinProjectKinds(),
|
|
23651
|
+
stereotypes: authorableStereotypes(),
|
|
23652
|
+
guarantees: [...SEMANTIC_GUARANTEES],
|
|
23653
|
+
designDepth: "narratives"
|
|
23654
|
+
};
|
|
23655
|
+
}
|
|
23656
|
+
function sameEntry(a, b) {
|
|
23657
|
+
if (typeof b === "string") return a === b;
|
|
23658
|
+
return typeof a !== "string" && a.name === b.name;
|
|
23659
|
+
}
|
|
23660
|
+
function entryName(entry) {
|
|
23661
|
+
return typeof entry === "string" ? path16.basename(entry).replace(/\.(ya?ml|cjs|js)$/i, "") : entry.name;
|
|
23662
|
+
}
|
|
23663
|
+
function unresolvedReason(config, entry) {
|
|
23664
|
+
const alone = { ...config, extensions: { useGlobalPacks: false, packs: [entry] } };
|
|
23665
|
+
const loaded = loadFor(alone);
|
|
23666
|
+
const failure = loaded.selectionFailures[0];
|
|
23667
|
+
if (failure) return `[${failure.code}] ${failure.message}`;
|
|
23668
|
+
return loaded.errors[0] ?? `the pack "${entryName(entry)}" does not resolve`;
|
|
23669
|
+
}
|
|
23670
|
+
function totals(config, result) {
|
|
23671
|
+
const count = (severity) => result.issues.filter((i) => i.severity === severity).length;
|
|
23672
|
+
const id = effectiveProjectId(config);
|
|
23673
|
+
return {
|
|
23674
|
+
key: "",
|
|
23675
|
+
...id !== null ? { id } : {},
|
|
23676
|
+
directory: getProjectRoot(),
|
|
23677
|
+
valid: result.valid,
|
|
23678
|
+
errors: count("error"),
|
|
23679
|
+
warnings: count("warning"),
|
|
23680
|
+
notices: count("notice")
|
|
23681
|
+
};
|
|
23682
|
+
}
|
|
23683
|
+
function governingProfiles(manifest, config) {
|
|
23684
|
+
if (!manifest) return [];
|
|
23685
|
+
const named2 = [config.projectType, ...loadSubsystemSpecs().map((s) => s.profile ?? "")];
|
|
23686
|
+
return [...new Set(named2.filter((p) => p !== "" && p in manifest.profiles))];
|
|
23687
|
+
}
|
|
23688
|
+
function measure(candidate) {
|
|
23689
|
+
const config = loadProjectConfig();
|
|
23690
|
+
if (!config) throw new Error("Not inside a wairon project: a pack impact is measured on a project \u2014 run `wairon init` first.");
|
|
23691
|
+
const entry = candidate.entry;
|
|
23692
|
+
const remove = candidate.remove === true;
|
|
23693
|
+
let next = entry !== void 0 ? withPack(config, entry, remove) : config;
|
|
23694
|
+
if (candidate.projectType !== void 0) next = { ...next, projectType: candidate.projectType };
|
|
23695
|
+
const current2 = entry !== void 0 ? (config.extensions?.packs ?? []).find((e) => sameEntry(e, entry)) : void 0;
|
|
23696
|
+
let manifest = null;
|
|
23697
|
+
if (candidate.manifest && !remove || entry === void 0) {
|
|
23698
|
+
manifest = candidate.manifest ?? null;
|
|
23699
|
+
} else {
|
|
23700
|
+
const measured = remove ? current2 ?? entry : entry;
|
|
23701
|
+
manifest = manifestOf(measured);
|
|
23702
|
+
if (!manifest) throw new Error(`Cannot measure the pack: ${unresolvedReason(config, measured)}`);
|
|
23703
|
+
}
|
|
23704
|
+
const previous = !remove && current2 !== void 0 ? manifestOf(current2) : null;
|
|
23705
|
+
const baseline = defaultsBaseline();
|
|
23706
|
+
const doctrine2 = manifest ? doctrineChanges(manifest, baseline) : [];
|
|
23707
|
+
const previousDoctrine = previous ? doctrineChanges(previous, baseline) : void 0;
|
|
23708
|
+
const before = validateProject({ rules: config.rules, projectType: config.projectType });
|
|
23709
|
+
const extensions = loadFor(next, candidate);
|
|
23710
|
+
const after = validateProject({
|
|
23711
|
+
rules: next.rules,
|
|
23712
|
+
projectType: next.projectType,
|
|
23713
|
+
extensions,
|
|
23714
|
+
packSelections: (next.extensions?.packs ?? []).filter((e) => typeof e !== "string")
|
|
23715
|
+
});
|
|
23716
|
+
const replaces = previous?.version ?? (current2 !== void 0 && typeof current2 !== "string" ? current2.version : void 0);
|
|
23717
|
+
return {
|
|
23718
|
+
pack: manifest?.name ?? (entry !== void 0 ? entryName(entry) : `projectType ${next.projectType}`),
|
|
23719
|
+
...manifest?.version ? { version: manifest.version } : {},
|
|
23720
|
+
...!remove && current2 !== void 0 && replaces ? { replaces } : {},
|
|
23721
|
+
direction: remove ? "remove" : "apply",
|
|
23722
|
+
doctrine: doctrine2,
|
|
23723
|
+
...previousDoctrine && !remove ? { previousDoctrine } : {},
|
|
23724
|
+
governing: governingProfiles(manifest, remove ? config : next),
|
|
23725
|
+
findings: findingChanges(before, after),
|
|
23726
|
+
before: totals(config, before),
|
|
23727
|
+
after: totals(next, after)
|
|
23728
|
+
};
|
|
23729
|
+
}
|
|
23730
|
+
|
|
23161
23731
|
// src/core/rules/gate-identity.ts
|
|
23162
23732
|
var crypto3 = __toESM(require("crypto"));
|
|
23163
23733
|
var GATE_ALGORITHM = "sha256+content+doctrine+inputs";
|
|
23164
|
-
function doctrineIdentity(
|
|
23734
|
+
function doctrineIdentity(doctrine2, builtinRules, gate) {
|
|
23165
23735
|
const byKey = (items, key) => [...items].sort((a, b) => compareOrdinal(key(a), key(b)));
|
|
23166
23736
|
return {
|
|
23167
23737
|
/**
|
|
@@ -23194,29 +23764,29 @@ function doctrineIdentity(doctrine, builtinRules, gate) {
|
|
|
23194
23764
|
projectType: gate.projectType ?? null,
|
|
23195
23765
|
rulesConfig: gate.rules ?? null,
|
|
23196
23766
|
packs: byKey(
|
|
23197
|
-
|
|
23767
|
+
doctrine2.packs.map((p) => ({ name: p.name, version: p.version ?? null, scope: p.scope })),
|
|
23198
23768
|
(p) => `${p.name}@${p.version ?? ""}#${p.scope}`
|
|
23199
23769
|
),
|
|
23200
23770
|
// Merged records already encode pack precedence, so their resolved content is
|
|
23201
23771
|
// the identity — a load-order change that flips a collision winner shows up here.
|
|
23202
|
-
profiles:
|
|
23203
|
-
languages:
|
|
23772
|
+
profiles: doctrine2.profiles,
|
|
23773
|
+
languages: doctrine2.languages,
|
|
23204
23774
|
patterns: byKey(
|
|
23205
|
-
|
|
23775
|
+
doctrine2.patterns.map((p) => ({ id: p.id, version: p.version, pack: p.pack })),
|
|
23206
23776
|
(p) => `${p.pack}/${p.id}@${p.version}`
|
|
23207
23777
|
),
|
|
23208
|
-
guarantees: [...
|
|
23209
|
-
assertions: byKey(
|
|
23778
|
+
guarantees: [...doctrine2.guarantees].sort(),
|
|
23779
|
+
assertions: byKey(doctrine2.assertions.map((a) => ({ ...a })), (a) => a.fullCode),
|
|
23210
23780
|
rules: byKey(
|
|
23211
|
-
|
|
23781
|
+
doctrine2.rules.map((r) => ({ name: r.name, codes: r.codes.map((c) => c.code).sort() })),
|
|
23212
23782
|
(r) => r.name
|
|
23213
23783
|
)
|
|
23214
23784
|
};
|
|
23215
23785
|
}
|
|
23216
|
-
function computeGateIdentity(content,
|
|
23786
|
+
function computeGateIdentity(content, doctrine2, builtinRules, inputs, gate) {
|
|
23217
23787
|
const payload = {
|
|
23218
23788
|
content: content.digest,
|
|
23219
|
-
doctrine: doctrineIdentity(
|
|
23789
|
+
doctrine: doctrineIdentity(doctrine2, builtinRules, gate),
|
|
23220
23790
|
inputs: [...inputs].sort()
|
|
23221
23791
|
};
|
|
23222
23792
|
const digest2 = crypto3.createHash("sha256").update(canonicalize(payload)).digest("hex");
|
|
@@ -23224,7 +23794,7 @@ function computeGateIdentity(content, doctrine, builtinRules, inputs, gate) {
|
|
|
23224
23794
|
}
|
|
23225
23795
|
|
|
23226
23796
|
// src/core/validation.ts
|
|
23227
|
-
var
|
|
23797
|
+
var path17 = __toESM(require("path"));
|
|
23228
23798
|
function projectPackSelections() {
|
|
23229
23799
|
try {
|
|
23230
23800
|
return (loadProjectConfig()?.extensions?.packs ?? []).filter((e) => typeof e !== "string");
|
|
@@ -23232,6 +23802,14 @@ function projectPackSelections() {
|
|
|
23232
23802
|
return [];
|
|
23233
23803
|
}
|
|
23234
23804
|
}
|
|
23805
|
+
function boundPackRequirements() {
|
|
23806
|
+
try {
|
|
23807
|
+
const config = loadProjectConfig();
|
|
23808
|
+
return config ? requiredPolicies(config) : [];
|
|
23809
|
+
} catch {
|
|
23810
|
+
return [];
|
|
23811
|
+
}
|
|
23812
|
+
}
|
|
23235
23813
|
function boundProjectIdentity() {
|
|
23236
23814
|
let config;
|
|
23237
23815
|
try {
|
|
@@ -23324,13 +23902,15 @@ function validateProject(rulesOrOptions, projectType = "backend") {
|
|
|
23324
23902
|
let scopeSubsystem;
|
|
23325
23903
|
let extensions;
|
|
23326
23904
|
let treatAllAsComplete = false;
|
|
23327
|
-
|
|
23905
|
+
let packSelections;
|
|
23906
|
+
if (rulesOrOptions && ("scopeSubsystem" in rulesOrOptions || "recursive" in rulesOrOptions || "rules" in rulesOrOptions || "projectType" in rulesOrOptions || "extensions" in rulesOrOptions || "treatAllAsComplete" in rulesOrOptions || "family" in rulesOrOptions || "packSelections" in rulesOrOptions)) {
|
|
23328
23907
|
const opts = rulesOrOptions;
|
|
23329
23908
|
rules = opts.rules;
|
|
23330
23909
|
projectType = opts.projectType ?? "backend";
|
|
23331
23910
|
scopeSubsystem = opts.scopeSubsystem;
|
|
23332
23911
|
extensions = opts.extensions;
|
|
23333
23912
|
treatAllAsComplete = opts.treatAllAsComplete ?? false;
|
|
23913
|
+
packSelections = opts.packSelections;
|
|
23334
23914
|
}
|
|
23335
23915
|
extensions ??= loadProjectExtensions();
|
|
23336
23916
|
scanAllSpecs({ recursive: true });
|
|
@@ -23429,8 +24009,11 @@ function validateProject(rulesOrOptions, projectType = "backend") {
|
|
|
23429
24009
|
projectFamily: family,
|
|
23430
24010
|
exportUsages,
|
|
23431
24011
|
pinnedExternals,
|
|
23432
|
-
// By-name selections only: a legacy path ref pins nothing to check.
|
|
23433
|
-
|
|
24012
|
+
// By-name selections only: a legacy path ref pins nothing to check. A dry
|
|
24013
|
+
// run supplies its candidate's; otherwise the stored ones.
|
|
24014
|
+
packSelections: packSelections ?? projectPackSelections(),
|
|
24015
|
+
// The bound project's own requirements, for their syntax only.
|
|
24016
|
+
packRequirements: boundPackRequirements(),
|
|
23434
24017
|
projectIdentity: boundProjectIdentity(),
|
|
23435
24018
|
surfaceSnapshots,
|
|
23436
24019
|
codeModel,
|
|
@@ -23465,7 +24048,7 @@ function settledStatusBearing(loaded) {
|
|
|
23465
24048
|
if (!settled || settled.size === 0) return [];
|
|
23466
24049
|
const root = getProjectRoot();
|
|
23467
24050
|
const index = scanAllSpecs();
|
|
23468
|
-
const rel2 = (abs) =>
|
|
24051
|
+
const rel2 = (abs) => path17.relative(root, abs).split(path17.sep).join("/");
|
|
23469
24052
|
const out = [];
|
|
23470
24053
|
const take = (specs, paths) => {
|
|
23471
24054
|
for (const spec of specs) {
|
|
@@ -23482,6 +24065,15 @@ function settledStatusBearing(loaded) {
|
|
|
23482
24065
|
function validateFamily(options) {
|
|
23483
24066
|
return run(options);
|
|
23484
24067
|
}
|
|
24068
|
+
function measurePackImpact(candidate) {
|
|
24069
|
+
return measure(candidate);
|
|
24070
|
+
}
|
|
24071
|
+
function builtinProfileIds() {
|
|
24072
|
+
return [...BUILTIN_PROFILES];
|
|
24073
|
+
}
|
|
24074
|
+
function builtinProjectKinds() {
|
|
24075
|
+
return [...PROJECT_KINDS];
|
|
24076
|
+
}
|
|
23485
24077
|
function computeGateStateId() {
|
|
23486
24078
|
const content = computeStateId();
|
|
23487
24079
|
const extensions = loadProjectExtensions();
|
|
@@ -23646,11 +24238,11 @@ var IdPool = class {
|
|
|
23646
24238
|
return candidate;
|
|
23647
24239
|
}
|
|
23648
24240
|
};
|
|
23649
|
-
function escapeLabel(
|
|
23650
|
-
return
|
|
24241
|
+
function escapeLabel(text3) {
|
|
24242
|
+
return text3.replace(/"/g, "#quot;");
|
|
23651
24243
|
}
|
|
23652
|
-
function truncate(
|
|
23653
|
-
const clean =
|
|
24244
|
+
function truncate(text3, max) {
|
|
24245
|
+
const clean = text3.replace(/\s+/g, " ").trim();
|
|
23654
24246
|
return clean.length <= max ? clean : `${clean.slice(0, max - 1)}\u2026`;
|
|
23655
24247
|
}
|
|
23656
24248
|
function nodeDecl(id, label2, comp) {
|
|
@@ -24024,10 +24616,10 @@ function diagramSetIndex(files, systemName) {
|
|
|
24024
24616
|
}
|
|
24025
24617
|
|
|
24026
24618
|
// src/core/project-family.ts
|
|
24027
|
-
var
|
|
24619
|
+
var path18 = __toESM(require("path"));
|
|
24028
24620
|
var memo = /* @__PURE__ */ new WeakMap();
|
|
24029
24621
|
function dirKey(dir) {
|
|
24030
|
-
const resolved =
|
|
24622
|
+
const resolved = path18.resolve(dir);
|
|
24031
24623
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
24032
24624
|
}
|
|
24033
24625
|
function makeNodes(roots) {
|
|
@@ -24101,7 +24693,7 @@ function bindExternals(node, root, nodes) {
|
|
|
24101
24693
|
const unresolved = (problem) => ({ alias: decl.alias, project: decl.project, sourceKind: "unresolved", audience: "instance", problem });
|
|
24102
24694
|
if (decl.problem) return unresolved(decl.problem);
|
|
24103
24695
|
if (decl.sourcePath !== void 0) {
|
|
24104
|
-
const directory =
|
|
24696
|
+
const directory = path18.resolve(node.directory, decl.sourcePath);
|
|
24105
24697
|
const found = nodes.find((n) => dirKey(n.directory) === dirKey(directory));
|
|
24106
24698
|
if (!found) return { alias: decl.alias, project: decl.project, sourceKind: "path", directory, audience: "instance" };
|
|
24107
24699
|
if (found.id !== decl.project) {
|
|
@@ -24717,42 +25309,42 @@ function emptyIndex() {
|
|
|
24717
25309
|
};
|
|
24718
25310
|
}
|
|
24719
25311
|
function isWithin(dir, file) {
|
|
24720
|
-
const d =
|
|
24721
|
-
const f =
|
|
24722
|
-
return f === d || f.startsWith(d +
|
|
25312
|
+
const d = path19.resolve(dir);
|
|
25313
|
+
const f = path19.resolve(file);
|
|
25314
|
+
return f === d || f.startsWith(d + path19.sep);
|
|
24723
25315
|
}
|
|
24724
25316
|
function canonicalPath(target) {
|
|
24725
|
-
let existing =
|
|
25317
|
+
let existing = path19.resolve(target);
|
|
24726
25318
|
const rest = [];
|
|
24727
25319
|
for (; ; ) {
|
|
24728
25320
|
try {
|
|
24729
25321
|
fs12.lstatSync(existing);
|
|
24730
25322
|
break;
|
|
24731
25323
|
} catch {
|
|
24732
|
-
const up =
|
|
24733
|
-
if (up === existing) return
|
|
24734
|
-
rest.unshift(
|
|
25324
|
+
const up = path19.dirname(existing);
|
|
25325
|
+
if (up === existing) return path19.resolve(target);
|
|
25326
|
+
rest.unshift(path19.basename(existing));
|
|
24735
25327
|
existing = up;
|
|
24736
25328
|
}
|
|
24737
25329
|
}
|
|
24738
25330
|
try {
|
|
24739
|
-
return
|
|
25331
|
+
return path19.join(fs12.realpathSync.native(existing), ...rest);
|
|
24740
25332
|
} catch {
|
|
24741
25333
|
return null;
|
|
24742
25334
|
}
|
|
24743
25335
|
}
|
|
24744
25336
|
function chainDirKey(dir) {
|
|
24745
|
-
return canonicalPath(dir) ??
|
|
25337
|
+
return canonicalPath(dir) ?? path19.resolve(dir);
|
|
24746
25338
|
}
|
|
24747
25339
|
function projectPathEscapesRoot(projectRoot, projectPath, resolvedChildDir) {
|
|
24748
|
-
if (
|
|
25340
|
+
if (path19.isAbsolute(projectPath) || !isWithin(projectRoot, resolvedChildDir)) return true;
|
|
24749
25341
|
const root = canonicalPath(projectRoot);
|
|
24750
25342
|
const child = canonicalPath(resolvedChildDir);
|
|
24751
25343
|
return root === null || child === null || !isWithin(root, child);
|
|
24752
25344
|
}
|
|
24753
25345
|
function assertContainedProjectPath(projectRoot, projectPath) {
|
|
24754
|
-
const root =
|
|
24755
|
-
const resolved =
|
|
25346
|
+
const root = path19.resolve(projectRoot);
|
|
25347
|
+
const resolved = path19.resolve(root, projectPath);
|
|
24756
25348
|
if (projectPathEscapesRoot(root, projectPath, resolved)) {
|
|
24757
25349
|
throw new Error(
|
|
24758
25350
|
`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.`
|
|
@@ -24822,19 +25414,19 @@ function memberDeclarationsAt(dir) {
|
|
|
24822
25414
|
function findChainingParent(childRoot, ceiling) {
|
|
24823
25415
|
let childResolved;
|
|
24824
25416
|
try {
|
|
24825
|
-
childResolved =
|
|
25417
|
+
childResolved = path19.resolve(childRoot);
|
|
24826
25418
|
} catch {
|
|
24827
25419
|
return null;
|
|
24828
25420
|
}
|
|
24829
|
-
const bound2 = ceiling ?
|
|
24830
|
-
let dir =
|
|
25421
|
+
const bound2 = ceiling ? path19.resolve(ceiling) : void 0;
|
|
25422
|
+
let dir = path19.dirname(childResolved);
|
|
24831
25423
|
for (let hops = 0; hops < 32; hops++) {
|
|
24832
25424
|
if (bound2 && !isWithin(bound2, dir)) break;
|
|
24833
25425
|
if (pathExists(aiPathsAt(dir).specsDir()) || pathExists(aiPathsAt(dir).projectConfig())) {
|
|
24834
25426
|
for (const member of memberDeclarationsAt(dir)) {
|
|
24835
25427
|
if (member.problem || member.path.trim() === "") continue;
|
|
24836
25428
|
try {
|
|
24837
|
-
const memberDir =
|
|
25429
|
+
const memberDir = path19.resolve(dir, member.path);
|
|
24838
25430
|
if (chainDirKey(memberDir) === chainDirKey(childResolved) && !projectPathEscapesRoot(dir, member.path, memberDir)) {
|
|
24839
25431
|
return { parentRoot: dir, alias: member.alias, form: member.form };
|
|
24840
25432
|
}
|
|
@@ -24842,14 +25434,14 @@ function findChainingParent(childRoot, ceiling) {
|
|
|
24842
25434
|
}
|
|
24843
25435
|
}
|
|
24844
25436
|
}
|
|
24845
|
-
const up =
|
|
25437
|
+
const up = path19.dirname(dir);
|
|
24846
25438
|
if (up === dir) break;
|
|
24847
25439
|
dir = up;
|
|
24848
25440
|
}
|
|
24849
25441
|
return null;
|
|
24850
25442
|
}
|
|
24851
25443
|
function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
24852
|
-
const root =
|
|
25444
|
+
const root = path19.resolve(rootDir);
|
|
24853
25445
|
const inspection = { roots: [], skipped: [] };
|
|
24854
25446
|
const listed = /* @__PURE__ */ new Set();
|
|
24855
25447
|
const walk2 = (projectDir, prefix, ancestors, depth) => {
|
|
@@ -24857,11 +25449,11 @@ function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
|
24857
25449
|
const key = prefix ? `${prefix}::${member.alias}` : member.alias;
|
|
24858
25450
|
let childDir;
|
|
24859
25451
|
try {
|
|
24860
|
-
childDir =
|
|
25452
|
+
childDir = path19.resolve(projectDir, member.path);
|
|
24861
25453
|
} catch {
|
|
24862
25454
|
continue;
|
|
24863
25455
|
}
|
|
24864
|
-
if (member.problem && !
|
|
25456
|
+
if (member.problem && !path19.isAbsolute(member.path)) continue;
|
|
24865
25457
|
let reason;
|
|
24866
25458
|
if (projectPathEscapesRoot(projectDir, member.path, childDir)) reason = "escapes";
|
|
24867
25459
|
else if (ancestors.has(chainDirKey(childDir))) reason = "cyclic";
|
|
@@ -24874,7 +25466,7 @@ function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
|
24874
25466
|
const dirKey3 = chainDirKey(childDir);
|
|
24875
25467
|
if (listed.has(dirKey3)) continue;
|
|
24876
25468
|
listed.add(dirKey3);
|
|
24877
|
-
inspection.roots.push(
|
|
25469
|
+
inspection.roots.push(path19.relative(root, childDir).split(path19.sep).join("/"));
|
|
24878
25470
|
walk2(childDir, key, /* @__PURE__ */ new Set([...ancestors, dirKey3]), depth + 1);
|
|
24879
25471
|
}
|
|
24880
25472
|
};
|
|
@@ -25079,9 +25671,9 @@ function mapRawReferences(kind, spec, map) {
|
|
|
25079
25671
|
}
|
|
25080
25672
|
function childRelativeFilePaths(spec, authoringRoot, childRoot) {
|
|
25081
25673
|
const reexpress = (p) => {
|
|
25082
|
-
if (
|
|
25083
|
-
const rel2 =
|
|
25084
|
-
const inside = rel2 !== "" && rel2 !== ".." && !rel2.startsWith(`..${
|
|
25674
|
+
if (path19.isAbsolute(p)) return p;
|
|
25675
|
+
const rel2 = path19.relative(childRoot, path19.resolve(authoringRoot, p));
|
|
25676
|
+
const inside = rel2 !== "" && rel2 !== ".." && !rel2.startsWith(`..${path19.sep}`) && !path19.isAbsolute(rel2);
|
|
25085
25677
|
return inside ? rel2.replace(/\\/g, "/") : p;
|
|
25086
25678
|
};
|
|
25087
25679
|
return {
|
|
@@ -25335,9 +25927,9 @@ function findOwner(id, components) {
|
|
|
25335
25927
|
}) ?? null;
|
|
25336
25928
|
}
|
|
25337
25929
|
function moveComponentFolder(fromDir, toDir) {
|
|
25338
|
-
if (
|
|
25930
|
+
if (path19.normalize(fromDir) === path19.normalize(toDir)) return false;
|
|
25339
25931
|
if (!fs12.existsSync(fromDir) || fs12.existsSync(toDir)) return false;
|
|
25340
|
-
ensureDir(
|
|
25932
|
+
ensureDir(path19.dirname(toDir));
|
|
25341
25933
|
fs12.renameSync(fromDir, toDir);
|
|
25342
25934
|
return true;
|
|
25343
25935
|
}
|
|
@@ -25475,8 +26067,8 @@ function rewriteSpecRefs(raw, remap) {
|
|
|
25475
26067
|
}
|
|
25476
26068
|
function summarizeValue(value) {
|
|
25477
26069
|
if (value === void 0) return "";
|
|
25478
|
-
const
|
|
25479
|
-
return
|
|
26070
|
+
const text3 = typeof value === "string" ? value : JSON.stringify(value) ?? String(value);
|
|
26071
|
+
return text3.length > 120 ? `${text3.slice(0, 117)}...` : text3;
|
|
25480
26072
|
}
|
|
25481
26073
|
function identityKeyOf(field, item) {
|
|
25482
26074
|
if (item === null || typeof item !== "object") return null;
|
|
@@ -25799,13 +26391,13 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
|
25799
26391
|
const isPlain = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
25800
26392
|
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
25801
26393
|
const at = (prefix, key) => prefix ? `${prefix}.${key}` : key;
|
|
25802
|
-
const say = (
|
|
25803
|
-
out.push(`${
|
|
26394
|
+
const say = (path38, why) => {
|
|
26395
|
+
out.push(`${path38} \u2014 ${why}`);
|
|
25804
26396
|
};
|
|
25805
|
-
const walkValue = (d, m, s,
|
|
26397
|
+
const walkValue = (d, m, s, path38, field) => {
|
|
25806
26398
|
if (Array.isArray(d)) {
|
|
25807
26399
|
if (!Array.isArray(m)) {
|
|
25808
|
-
say(
|
|
26400
|
+
say(path38, "the level does not have this field, so the write dropped it");
|
|
25809
26401
|
return;
|
|
25810
26402
|
}
|
|
25811
26403
|
if (field === "narrative" && d.some(carriesEditMarker)) return;
|
|
@@ -25813,32 +26405,32 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
|
25813
26405
|
if (carriesEditMarker(element)) continue;
|
|
25814
26406
|
const key = reportIdentityOf(field, element);
|
|
25815
26407
|
if (key === null) {
|
|
25816
|
-
if (!same(m, d)) say(
|
|
25817
|
-
else if (same(s, d)) say(
|
|
26408
|
+
if (!same(m, d)) say(path38, "the level does not keep this value, so the write dropped it");
|
|
26409
|
+
else if (same(s, d)) say(path38, "the stored spec already held this value");
|
|
25818
26410
|
return;
|
|
25819
26411
|
}
|
|
25820
26412
|
const mMatch = m.find((i) => reportIdentityOf(field, i) === key);
|
|
25821
26413
|
const sMatch = Array.isArray(s) ? s.find((i) => reportIdentityOf(field, i) === key) : void 0;
|
|
25822
26414
|
if (mMatch === void 0) {
|
|
25823
|
-
say(at(
|
|
26415
|
+
say(at(path38, key), "the write did not store this element");
|
|
25824
26416
|
continue;
|
|
25825
26417
|
}
|
|
25826
|
-
walk2(element, mMatch, sMatch, at(
|
|
26418
|
+
walk2(element, mMatch, sMatch, at(path38, key), field);
|
|
25827
26419
|
}
|
|
25828
26420
|
return;
|
|
25829
26421
|
}
|
|
25830
26422
|
if (isPlain(d)) {
|
|
25831
26423
|
if (!isPlain(m)) {
|
|
25832
|
-
say(
|
|
26424
|
+
say(path38, "the level does not have this field, so the write dropped it");
|
|
25833
26425
|
return;
|
|
25834
26426
|
}
|
|
25835
|
-
walk2(d, m, s,
|
|
26427
|
+
walk2(d, m, s, path38, field);
|
|
25836
26428
|
return;
|
|
25837
26429
|
}
|
|
25838
|
-
if (!same(m, d)) say(
|
|
25839
|
-
else if (same(s, d)) say(
|
|
26430
|
+
if (!same(m, d)) say(path38, "the write did not store it \u2014 the level's schema does not keep this value");
|
|
26431
|
+
else if (same(s, d)) say(path38, "the stored spec already held this value");
|
|
25840
26432
|
};
|
|
25841
|
-
function walk2(d, m, s,
|
|
26433
|
+
function walk2(d, m, s, path38, container) {
|
|
25842
26434
|
for (const [key, value] of Object.entries(d)) {
|
|
25843
26435
|
if (DELTA_VERBS.has(key) || JUMP_LABEL_TWINS.has(key)) continue;
|
|
25844
26436
|
if (key === "label" && LABEL_TWIN_CONTAINERS.has(container)) continue;
|
|
@@ -25848,13 +26440,13 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
|
25848
26440
|
if (typeof name !== "string") continue;
|
|
25849
26441
|
const had = isPlain(s) && s[name] !== void 0;
|
|
25850
26442
|
const still = isPlain(m) && m[name] !== void 0;
|
|
25851
|
-
if (!had) say(at(
|
|
25852
|
-
else if (still) say(at(
|
|
26443
|
+
if (!had) say(at(path38, name), "unset named a field the stored spec did not have");
|
|
26444
|
+
else if (still) say(at(path38, name), "unset did not remove it");
|
|
25853
26445
|
}
|
|
25854
26446
|
continue;
|
|
25855
26447
|
}
|
|
25856
26448
|
if (value === void 0 || value === null) continue;
|
|
25857
|
-
const here = at(
|
|
26449
|
+
const here = at(path38, key);
|
|
25858
26450
|
const mValue = isPlain(m) ? m[key] : void 0;
|
|
25859
26451
|
const sValue = isPlain(s) ? s[key] : void 0;
|
|
25860
26452
|
if (mValue === void 0) {
|
|
@@ -25885,7 +26477,7 @@ var SpecWorkspace = class {
|
|
|
25885
26477
|
/** Set while normalizeReferences writes: every reference in its canonical form, no authored text carried. */
|
|
25886
26478
|
this.carryDisabled = false;
|
|
25887
26479
|
this.loaderIssues = [];
|
|
25888
|
-
this.rootDir =
|
|
26480
|
+
this.rootDir = path19.resolve(rootDir);
|
|
25889
26481
|
this.paths = aiPathsAt(this.rootDir);
|
|
25890
26482
|
}
|
|
25891
26483
|
/**
|
|
@@ -25948,8 +26540,8 @@ var SpecWorkspace = class {
|
|
|
25948
26540
|
* itself — so scoping a validate to a member keeps it.
|
|
25949
26541
|
*/
|
|
25950
26542
|
loaderIssueSpecId(file, rawId, key) {
|
|
25951
|
-
const stem =
|
|
25952
|
-
const local = rawId ?? (stem.startsWith(".") ?
|
|
26543
|
+
const stem = path19.basename(file, ".yaml");
|
|
26544
|
+
const local = rawId ?? (stem.startsWith(".") ? path19.basename(path19.dirname(file)) : stem);
|
|
25953
26545
|
return keyIn(key, local);
|
|
25954
26546
|
}
|
|
25955
26547
|
/**
|
|
@@ -25999,7 +26591,7 @@ var SpecWorkspace = class {
|
|
|
25999
26591
|
...member ? { mountAlias: member.alias, mountForm: member.form } : {},
|
|
26000
26592
|
legacyMount: member?.legacyMount ?? null,
|
|
26001
26593
|
...member?.description !== void 0 ? { memberDescription: member.description } : {},
|
|
26002
|
-
directory:
|
|
26594
|
+
directory: path19.resolve(dir),
|
|
26003
26595
|
system: null,
|
|
26004
26596
|
config,
|
|
26005
26597
|
aliases: /* @__PURE__ */ new Map(),
|
|
@@ -26012,7 +26604,7 @@ var SpecWorkspace = class {
|
|
|
26012
26604
|
const raw = {
|
|
26013
26605
|
record,
|
|
26014
26606
|
aliasPath,
|
|
26015
|
-
dir:
|
|
26607
|
+
dir: path19.resolve(dir),
|
|
26016
26608
|
index: emptyIndex(),
|
|
26017
26609
|
mounts: [],
|
|
26018
26610
|
members: [],
|
|
@@ -26042,14 +26634,14 @@ var SpecWorkspace = class {
|
|
|
26042
26634
|
followableMember(raw, decl, ancestors) {
|
|
26043
26635
|
const memberKey = keyIn(raw.record.namespace, decl.alias);
|
|
26044
26636
|
const by = decl.form === "mount" ? "subsystem" : "member";
|
|
26045
|
-
const absolute =
|
|
26637
|
+
const absolute = path19.isAbsolute(decl.path) || path19.win32.isAbsolute(decl.path);
|
|
26046
26638
|
if (decl.problem && !absolute) {
|
|
26047
26639
|
if (decl.problem.includes("`externals`")) {
|
|
26048
26640
|
raw.record.problems.push({ kind: "alias-conflict", id: decl.alias, projects: [raw.record.namespace], detail: decl.problem });
|
|
26049
26641
|
}
|
|
26050
26642
|
return null;
|
|
26051
26643
|
}
|
|
26052
|
-
const childDir =
|
|
26644
|
+
const childDir = path19.resolve(raw.dir, decl.path);
|
|
26053
26645
|
if (projectPathEscapesRoot(raw.dir, decl.path, childDir)) {
|
|
26054
26646
|
this.loaderIssues.push({
|
|
26055
26647
|
severity: "error",
|
|
@@ -26086,7 +26678,7 @@ var SpecWorkspace = class {
|
|
|
26086
26678
|
const specsDir = projectPaths.specsDir();
|
|
26087
26679
|
this.scanVisitedSpecDirs.push(specsDir);
|
|
26088
26680
|
if (!pathExists(specsDir)) return;
|
|
26089
|
-
const systemYaml =
|
|
26681
|
+
const systemYaml = path19.normalize(projectPaths.specsSystem());
|
|
26090
26682
|
if (pathExists(systemYaml)) {
|
|
26091
26683
|
try {
|
|
26092
26684
|
raw.rawSystem = SystemSpecSchema.parse(readSpecFile(systemYaml));
|
|
@@ -26110,7 +26702,7 @@ var SpecWorkspace = class {
|
|
|
26110
26702
|
index.paths[kind][spec.id] = file;
|
|
26111
26703
|
};
|
|
26112
26704
|
for (const file of listSpecFiles(specsDir)) {
|
|
26113
|
-
if (
|
|
26705
|
+
if (path19.normalize(file) === systemYaml) continue;
|
|
26114
26706
|
let detectedType = "spec";
|
|
26115
26707
|
let rawId;
|
|
26116
26708
|
try {
|
|
@@ -26140,7 +26732,7 @@ var SpecWorkspace = class {
|
|
|
26140
26732
|
} else if ("contract" in doc) {
|
|
26141
26733
|
detectedType = "implementation";
|
|
26142
26734
|
const parsed = ImplementationSpecSchema.parse(doc);
|
|
26143
|
-
const normalizeSourcePath = (p) =>
|
|
26735
|
+
const normalizeSourcePath = (p) => path19.relative(raw.dir, path19.resolve(raw.dir, p)).replace(/\\/g, "/");
|
|
26144
26736
|
if (parsed.sourcePath) parsed.sourcePath = normalizeSourcePath(parsed.sourcePath);
|
|
26145
26737
|
for (const method of parsed.methods) {
|
|
26146
26738
|
if (method.sourcePath) method.sourcePath = normalizeSourcePath(method.sourcePath);
|
|
@@ -26279,7 +26871,7 @@ var SpecWorkspace = class {
|
|
|
26279
26871
|
const others = raws.filter((r) => r !== raw);
|
|
26280
26872
|
let producer;
|
|
26281
26873
|
if (decl.sourcePath !== void 0) {
|
|
26282
|
-
const at = chainDirKey(
|
|
26874
|
+
const at = chainDirKey(path19.resolve(raw.dir, decl.sourcePath));
|
|
26283
26875
|
producer = others.find((r) => chainDirKey(r.dir) === at && idOf(r) === decl.project);
|
|
26284
26876
|
} else {
|
|
26285
26877
|
const holders = others.filter((r) => idOf(r) === decl.project);
|
|
@@ -26431,9 +27023,9 @@ var SpecWorkspace = class {
|
|
|
26431
27023
|
return index.paths.subsystem[matches[0]];
|
|
26432
27024
|
}
|
|
26433
27025
|
if (pathExists(this.paths.specsSubsystemsDir()) && listFiles(this.paths.specsSubsystemsDir(), ".yaml").length > 0) {
|
|
26434
|
-
return
|
|
27026
|
+
return path19.join(this.paths.specsSubsystemsDir(), `${id}.yaml`);
|
|
26435
27027
|
}
|
|
26436
|
-
return
|
|
27028
|
+
return path19.join(this.paths.specsDir(), id, ".index.yaml");
|
|
26437
27029
|
}
|
|
26438
27030
|
getComponentPath(id, subsystemId) {
|
|
26439
27031
|
const index = this.scanAll();
|
|
@@ -26453,21 +27045,21 @@ var SpecWorkspace = class {
|
|
|
26453
27045
|
if (owner) {
|
|
26454
27046
|
const ownerPath = index.paths.component[owner.id];
|
|
26455
27047
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
26456
|
-
return
|
|
27048
|
+
return path19.join(path19.dirname(ownerPath), id, ".index.yaml");
|
|
26457
27049
|
}
|
|
26458
27050
|
}
|
|
26459
27051
|
if (subsystemId) {
|
|
26460
27052
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
26461
|
-
const subDir =
|
|
27053
|
+
const subDir = path19.dirname(subPath);
|
|
26462
27054
|
if (subPath.endsWith(".index.yaml")) {
|
|
26463
|
-
return
|
|
27055
|
+
return path19.join(subDir, id, ".index.yaml");
|
|
26464
27056
|
}
|
|
26465
27057
|
}
|
|
26466
27058
|
if (pathExists(this.paths.specsComponentsDir()) && listFiles(this.paths.specsComponentsDir(), ".yaml").length > 0) {
|
|
26467
|
-
return
|
|
27059
|
+
return path19.join(this.paths.specsComponentsDir(), `${id}.yaml`);
|
|
26468
27060
|
}
|
|
26469
27061
|
const targetSubsystem = subsystemId || "default";
|
|
26470
|
-
return
|
|
27062
|
+
return path19.join(this.paths.specsDir(), targetSubsystem, id, ".index.yaml");
|
|
26471
27063
|
}
|
|
26472
27064
|
getInterfacePath(id, componentId) {
|
|
26473
27065
|
const index = this.scanAll();
|
|
@@ -26493,16 +27085,16 @@ var SpecWorkspace = class {
|
|
|
26493
27085
|
}
|
|
26494
27086
|
if (componentId) {
|
|
26495
27087
|
const compPath = this.getComponentPath(componentId);
|
|
26496
|
-
const compDir =
|
|
27088
|
+
const compDir = path19.dirname(compPath);
|
|
26497
27089
|
if (compPath.endsWith(".index.yaml")) {
|
|
26498
|
-
return
|
|
27090
|
+
return path19.join(compDir, ".interface.yaml");
|
|
26499
27091
|
}
|
|
26500
27092
|
}
|
|
26501
27093
|
if (pathExists(this.paths.specsInterfacesDir()) && listFiles(this.paths.specsInterfacesDir(), ".yaml").length > 0) {
|
|
26502
|
-
return
|
|
27094
|
+
return path19.join(this.paths.specsInterfacesDir(), `${id}.yaml`);
|
|
26503
27095
|
}
|
|
26504
27096
|
const targetComponent = componentId || "default";
|
|
26505
|
-
return
|
|
27097
|
+
return path19.join(this.paths.specsDir(), "default", targetComponent, ".interface.yaml");
|
|
26506
27098
|
}
|
|
26507
27099
|
getImplementationPath(id, contractId) {
|
|
26508
27100
|
const index = this.scanAll();
|
|
@@ -26528,16 +27120,16 @@ var SpecWorkspace = class {
|
|
|
26528
27120
|
}
|
|
26529
27121
|
if (contractId) {
|
|
26530
27122
|
const intfPath = this.getInterfacePath(contractId);
|
|
26531
|
-
const intfDir =
|
|
27123
|
+
const intfDir = path19.dirname(intfPath);
|
|
26532
27124
|
if (intfPath.endsWith(".interface.yaml")) {
|
|
26533
|
-
return
|
|
27125
|
+
return path19.join(intfDir, ".implementation.yaml");
|
|
26534
27126
|
}
|
|
26535
27127
|
}
|
|
26536
27128
|
if (pathExists(this.paths.specsImplementationsDir()) && listFiles(this.paths.specsImplementationsDir(), ".yaml").length > 0) {
|
|
26537
|
-
return
|
|
27129
|
+
return path19.join(this.paths.specsImplementationsDir(), `${id}.yaml`);
|
|
26538
27130
|
}
|
|
26539
27131
|
const targetContract = contractId ? contractId.replace(/^i/, "") : "default";
|
|
26540
|
-
return
|
|
27132
|
+
return path19.join(this.paths.specsDir(), "default", targetContract, ".implementation.yaml");
|
|
26541
27133
|
}
|
|
26542
27134
|
getTypePath(id, subsystemId, group) {
|
|
26543
27135
|
const index = this.scanAll();
|
|
@@ -26568,7 +27160,7 @@ var SpecWorkspace = class {
|
|
|
26568
27160
|
const groupPath = index.paths.group[targetGroup] || index.paths.group[plainGroup];
|
|
26569
27161
|
if (groupPath) {
|
|
26570
27162
|
const localId2 = id.split("::").pop();
|
|
26571
|
-
return
|
|
27163
|
+
return path19.join(path19.dirname(groupPath), `${localId2}.yaml`);
|
|
26572
27164
|
}
|
|
26573
27165
|
}
|
|
26574
27166
|
let localId = id;
|
|
@@ -26581,12 +27173,12 @@ var SpecWorkspace = class {
|
|
|
26581
27173
|
}
|
|
26582
27174
|
if (subsystemId) {
|
|
26583
27175
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
26584
|
-
const subDir =
|
|
27176
|
+
const subDir = path19.dirname(subPath);
|
|
26585
27177
|
if (subPath.endsWith(".index.yaml")) {
|
|
26586
|
-
return
|
|
27178
|
+
return path19.join(subDir, "types", `${localId}.yaml`);
|
|
26587
27179
|
}
|
|
26588
27180
|
}
|
|
26589
|
-
return
|
|
27181
|
+
return path19.join(this.paths.specsTypesDir(), `${localId}.yaml`);
|
|
26590
27182
|
}
|
|
26591
27183
|
getGroupPath(id, subsystemId) {
|
|
26592
27184
|
const index = this.scanAll();
|
|
@@ -26620,12 +27212,12 @@ var SpecWorkspace = class {
|
|
|
26620
27212
|
}
|
|
26621
27213
|
if (subsystemId) {
|
|
26622
27214
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
26623
|
-
const subDir =
|
|
27215
|
+
const subDir = path19.dirname(subPath);
|
|
26624
27216
|
if (subPath.endsWith(".index.yaml")) {
|
|
26625
|
-
return
|
|
27217
|
+
return path19.join(subDir, "types", localId, ".index.yaml");
|
|
26626
27218
|
}
|
|
26627
27219
|
}
|
|
26628
|
-
return
|
|
27220
|
+
return path19.join(this.paths.specsTypesDir(), localId, ".index.yaml");
|
|
26629
27221
|
}
|
|
26630
27222
|
// -------------------------------------------------------------------------
|
|
26631
27223
|
// Level 0: System
|
|
@@ -26648,7 +27240,7 @@ var SpecWorkspace = class {
|
|
|
26648
27240
|
}
|
|
26649
27241
|
saveSystemSpec(spec) {
|
|
26650
27242
|
const p = this.paths.specsSystem();
|
|
26651
|
-
ensureDir(
|
|
27243
|
+
ensureDir(path19.dirname(p));
|
|
26652
27244
|
writeSpecFile(p, parseOrThrow(SystemSpecSchema, spec, "system", spec.name));
|
|
26653
27245
|
invalidateSpecCache();
|
|
26654
27246
|
}
|
|
@@ -26769,7 +27361,7 @@ var SpecWorkspace = class {
|
|
|
26769
27361
|
*/
|
|
26770
27362
|
writeSubsystemSpec(spec, opts) {
|
|
26771
27363
|
const p = this.getSubsystemPath(spec.id);
|
|
26772
|
-
ensureDir(
|
|
27364
|
+
ensureDir(path19.dirname(p));
|
|
26773
27365
|
const { prefix } = splitNamespace(spec.id);
|
|
26774
27366
|
let specToWrite = this.prepareSubsystemForWrite(spec);
|
|
26775
27367
|
if (prefix) {
|
|
@@ -26833,7 +27425,7 @@ var SpecWorkspace = class {
|
|
|
26833
27425
|
saveComponentSpec(spec, opts) {
|
|
26834
27426
|
const notices = [];
|
|
26835
27427
|
const p = this.getComponentPath(spec.id, spec.subsystem);
|
|
26836
|
-
ensureDir(
|
|
27428
|
+
ensureDir(path19.dirname(p));
|
|
26837
27429
|
const specToWrite = this.prepareComponentForWrite(spec);
|
|
26838
27430
|
const existing = this.loadComponentSpec(spec.id);
|
|
26839
27431
|
if (existing) {
|
|
@@ -26850,7 +27442,7 @@ var SpecWorkspace = class {
|
|
|
26850
27442
|
const subsystemChanged = existing && existing.subsystem !== spec.subsystem && splitNamespace(existing.subsystem).localId !== splitNamespace(spec.subsystem).localId;
|
|
26851
27443
|
if (subsystemChanged && !p.endsWith(".index.yaml")) {
|
|
26852
27444
|
notices.push(
|
|
26853
|
-
`component "${spec.id}" already exists at ${
|
|
27445
|
+
`component "${spec.id}" already exists at ${path19.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}").`
|
|
26854
27446
|
);
|
|
26855
27447
|
}
|
|
26856
27448
|
specToWrite.updatedAt = opts?.preserveUpdatedAt && existing?.updatedAt ? existing.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -26874,12 +27466,12 @@ var SpecWorkspace = class {
|
|
|
26874
27466
|
if (owner) {
|
|
26875
27467
|
const ownerPath = index.paths.component[owner.id];
|
|
26876
27468
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
26877
|
-
const ownerSubDir =
|
|
26878
|
-
return
|
|
27469
|
+
const ownerSubDir = path19.dirname(this.getSubsystemPath(owner.subsystem));
|
|
27470
|
+
return path19.join(ownerSubDir, owner.id, comp.id);
|
|
26879
27471
|
}
|
|
26880
27472
|
}
|
|
26881
|
-
const subDir =
|
|
26882
|
-
return
|
|
27473
|
+
const subDir = path19.dirname(this.getSubsystemPath(comp.subsystem));
|
|
27474
|
+
return path19.join(subDir, comp.id);
|
|
26883
27475
|
}
|
|
26884
27476
|
/**
|
|
26885
27477
|
* Move component folders so the physical tree mirrors ownership: each owned
|
|
@@ -26895,7 +27487,7 @@ var SpecWorkspace = class {
|
|
|
26895
27487
|
if (!currentPath) continue;
|
|
26896
27488
|
const desiredDir = this.desiredComponentDir(comp, index);
|
|
26897
27489
|
if (!desiredDir) continue;
|
|
26898
|
-
if (moveComponentFolder(
|
|
27490
|
+
if (moveComponentFolder(path19.dirname(currentPath), desiredDir)) moved.push(comp.id);
|
|
26899
27491
|
}
|
|
26900
27492
|
if (moved.length) invalidateSpecCache();
|
|
26901
27493
|
return moved;
|
|
@@ -26951,7 +27543,7 @@ var SpecWorkspace = class {
|
|
|
26951
27543
|
if (!occupantId) return;
|
|
26952
27544
|
if (occupantId === id || splitNamespace(occupantId).localId === splitNamespace(id).localId) return;
|
|
26953
27545
|
throw new Error(
|
|
26954
|
-
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${
|
|
27546
|
+
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${path19.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.`
|
|
26955
27547
|
);
|
|
26956
27548
|
}
|
|
26957
27549
|
/** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */
|
|
@@ -26959,12 +27551,12 @@ var SpecWorkspace = class {
|
|
|
26959
27551
|
const notices = [];
|
|
26960
27552
|
const p = this.getInterfacePath(spec.id, spec.component);
|
|
26961
27553
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "interface", `component "${spec.component}"`);
|
|
26962
|
-
ensureDir(
|
|
27554
|
+
ensureDir(path19.dirname(p));
|
|
26963
27555
|
const specToWrite = this.prepareInterfaceForWrite(spec);
|
|
26964
27556
|
const existing = this.loadInterfaceSpec(spec.id);
|
|
26965
27557
|
if (existing && existing.component !== spec.component && splitNamespace(existing.component).localId !== splitNamespace(spec.component).localId) {
|
|
26966
27558
|
notices.push(
|
|
26967
|
-
`interface "${spec.id}" already exists at ${
|
|
27559
|
+
`interface "${spec.id}" already exists at ${path19.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.`
|
|
26968
27560
|
);
|
|
26969
27561
|
}
|
|
26970
27562
|
if (existing) {
|
|
@@ -27021,12 +27613,12 @@ var SpecWorkspace = class {
|
|
|
27021
27613
|
const notices = [];
|
|
27022
27614
|
const p = this.getImplementationPath(spec.id, spec.contract);
|
|
27023
27615
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "implementation", `contract "${spec.contract}"`);
|
|
27024
|
-
ensureDir(
|
|
27616
|
+
ensureDir(path19.dirname(p));
|
|
27025
27617
|
const specToWrite = this.prepareImplementationForWrite(spec);
|
|
27026
27618
|
const existing = this.loadImplementationSpec(spec.id);
|
|
27027
27619
|
if (existing && existing.contract !== spec.contract && splitNamespace(existing.contract).localId !== splitNamespace(spec.contract).localId) {
|
|
27028
27620
|
notices.push(
|
|
27029
|
-
`implementation "${spec.id}" already exists at ${
|
|
27621
|
+
`implementation "${spec.id}" already exists at ${path19.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.`
|
|
27030
27622
|
);
|
|
27031
27623
|
}
|
|
27032
27624
|
if (existing) {
|
|
@@ -27067,11 +27659,11 @@ var SpecWorkspace = class {
|
|
|
27067
27659
|
const existing = this.loadTypeSpec(spec.id);
|
|
27068
27660
|
const group = spec.group || (existing ? existing.group : void 0);
|
|
27069
27661
|
const p = this.getTypePath(spec.id, spec.subsystem, group);
|
|
27070
|
-
ensureDir(
|
|
27662
|
+
ensureDir(path19.dirname(p));
|
|
27071
27663
|
const subsystemChanged = existing && (existing.subsystem ?? "") !== (spec.subsystem ?? "") && splitNamespace(existing.subsystem ?? "").localId !== splitNamespace(spec.subsystem ?? "").localId;
|
|
27072
27664
|
if (subsystemChanged) {
|
|
27073
27665
|
notices.push(
|
|
27074
|
-
`type "${spec.id}" already exists at ${
|
|
27666
|
+
`type "${spec.id}" already exists at ${path19.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)"}").`
|
|
27075
27667
|
);
|
|
27076
27668
|
}
|
|
27077
27669
|
if (spec.subsystem && (!existing || subsystemChanged) && !this.getSubsystemPath(spec.subsystem).endsWith(".index.yaml")) {
|
|
@@ -27109,7 +27701,7 @@ var SpecWorkspace = class {
|
|
|
27109
27701
|
}
|
|
27110
27702
|
saveGroupSpec(spec, opts) {
|
|
27111
27703
|
const p = this.getGroupPath(spec.id);
|
|
27112
|
-
ensureDir(
|
|
27704
|
+
ensureDir(path19.dirname(p));
|
|
27113
27705
|
const specToWrite = this.prepareGroupForWrite(spec);
|
|
27114
27706
|
const existing = this.loadGroupSpec(spec.id);
|
|
27115
27707
|
if (existing) {
|
|
@@ -27360,7 +27952,7 @@ var SpecWorkspace = class {
|
|
|
27360
27952
|
};
|
|
27361
27953
|
const out = /* @__PURE__ */ new Set();
|
|
27362
27954
|
const add = (p) => {
|
|
27363
|
-
if (p) out.add(
|
|
27955
|
+
if (p) out.add(path19.resolve(p));
|
|
27364
27956
|
};
|
|
27365
27957
|
for (const s of this.loadSubsystemSpecs()) {
|
|
27366
27958
|
if (!scopeSubsystem || s.id === scopeSubsystem || s.id.startsWith(`${scopeSubsystem}::`)) {
|
|
@@ -27431,11 +28023,11 @@ var SpecWorkspace = class {
|
|
|
27431
28023
|
const files = /* @__PURE__ */ new Set();
|
|
27432
28024
|
const sysPath = this.paths.specsSystem();
|
|
27433
28025
|
if (pathExists(sysPath)) {
|
|
27434
|
-
files.add(
|
|
28026
|
+
files.add(path19.resolve(sysPath));
|
|
27435
28027
|
}
|
|
27436
28028
|
for (const group of Object.values(index.paths)) {
|
|
27437
28029
|
for (const file of Object.values(group)) {
|
|
27438
|
-
files.add(
|
|
28030
|
+
files.add(path19.resolve(file));
|
|
27439
28031
|
}
|
|
27440
28032
|
}
|
|
27441
28033
|
for (const file of files) {
|
|
@@ -27454,20 +28046,20 @@ var SpecWorkspace = class {
|
|
|
27454
28046
|
const files = listSpecFiles(specsDir);
|
|
27455
28047
|
const legacy = [];
|
|
27456
28048
|
for (const f of files) {
|
|
27457
|
-
const base =
|
|
27458
|
-
const dir =
|
|
28049
|
+
const base = path19.basename(f);
|
|
28050
|
+
const dir = path19.dirname(f);
|
|
27459
28051
|
if (base === "system.yaml") {
|
|
27460
|
-
legacy.push({ path: f, expected:
|
|
28052
|
+
legacy.push({ path: f, expected: path19.join(dir, ".index.yaml") });
|
|
27461
28053
|
} else if (base === "subsystem.yaml") {
|
|
27462
|
-
legacy.push({ path: f, expected:
|
|
28054
|
+
legacy.push({ path: f, expected: path19.join(dir, ".index.yaml") });
|
|
27463
28055
|
} else if (base === "component.yaml") {
|
|
27464
|
-
legacy.push({ path: f, expected:
|
|
28056
|
+
legacy.push({ path: f, expected: path19.join(dir, ".index.yaml") });
|
|
27465
28057
|
} else if (base === "group.yaml") {
|
|
27466
|
-
legacy.push({ path: f, expected:
|
|
28058
|
+
legacy.push({ path: f, expected: path19.join(dir, ".index.yaml") });
|
|
27467
28059
|
} else if (base === "interface.yaml") {
|
|
27468
|
-
legacy.push({ path: f, expected:
|
|
28060
|
+
legacy.push({ path: f, expected: path19.join(dir, ".interface.yaml") });
|
|
27469
28061
|
} else if (base === "implementation.yaml") {
|
|
27470
|
-
legacy.push({ path: f, expected:
|
|
28062
|
+
legacy.push({ path: f, expected: path19.join(dir, ".implementation.yaml") });
|
|
27471
28063
|
}
|
|
27472
28064
|
}
|
|
27473
28065
|
return legacy;
|
|
@@ -28644,7 +29236,7 @@ function refusedMoveSummary(from, to, methods, refusals, alternatives) {
|
|
|
28644
29236
|
}
|
|
28645
29237
|
var workspaces = /* @__PURE__ */ new Map();
|
|
28646
29238
|
function workspaceFor(rootDir) {
|
|
28647
|
-
const key =
|
|
29239
|
+
const key = path19.resolve(rootDir);
|
|
28648
29240
|
let ws = workspaces.get(key);
|
|
28649
29241
|
if (!ws) {
|
|
28650
29242
|
ws = new SpecWorkspace(key);
|
|
@@ -28771,7 +29363,7 @@ function snapshotInputsIn(dir, kind) {
|
|
|
28771
29363
|
for (const file of fs12.readdirSync(dir).sort()) {
|
|
28772
29364
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
28773
29365
|
try {
|
|
28774
|
-
keys.push(`${kind}:${snapshotInputKey(SurfaceSnapshotSchema.parse(readYamlFile(
|
|
29366
|
+
keys.push(`${kind}:${snapshotInputKey(SurfaceSnapshotSchema.parse(readYamlFile(path19.join(dir, file))))}`);
|
|
28775
29367
|
} catch {
|
|
28776
29368
|
}
|
|
28777
29369
|
}
|
|
@@ -28779,10 +29371,10 @@ function snapshotInputsIn(dir, kind) {
|
|
|
28779
29371
|
}
|
|
28780
29372
|
function consumedSurfaceInputsAt(rootDir) {
|
|
28781
29373
|
const keys = [
|
|
28782
|
-
...snapshotInputsIn(
|
|
28783
|
-
...snapshotInputsIn(
|
|
29374
|
+
...snapshotInputsIn(path19.join(rootDir, ".wai", "surfaces"), "surface"),
|
|
29375
|
+
...snapshotInputsIn(path19.join(rootDir, ".wai", "externals"), "external")
|
|
28784
29376
|
];
|
|
28785
|
-
const lock =
|
|
29377
|
+
const lock = path19.join(rootDir, ".wai", "externals.lock.yaml");
|
|
28786
29378
|
if (pathExists(lock)) {
|
|
28787
29379
|
try {
|
|
28788
29380
|
keys.push(`lock:${canonicalize(readYamlFile(lock))}`);
|
|
@@ -28793,7 +29385,7 @@ function consumedSurfaceInputsAt(rootDir) {
|
|
|
28793
29385
|
}
|
|
28794
29386
|
function consumedContractInputs() {
|
|
28795
29387
|
const root = getProjectRoot();
|
|
28796
|
-
const roots = [root, ...listChainedRoots(root).map((rel2) =>
|
|
29388
|
+
const roots = [root, ...listChainedRoots(root).map((rel2) => path19.join(root, rel2))];
|
|
28797
29389
|
return roots.flatMap(consumedSurfaceInputsAt);
|
|
28798
29390
|
}
|
|
28799
29391
|
function readLockState(current2) {
|
|
@@ -28838,7 +29430,7 @@ function importNames(alias, names) {
|
|
|
28838
29430
|
return projectConfigRepository.importNames(alias, names);
|
|
28839
29431
|
}
|
|
28840
29432
|
function computeStateIdAt(root) {
|
|
28841
|
-
const resolved =
|
|
29433
|
+
const resolved = path19.resolve(root);
|
|
28842
29434
|
return runWithProjectRoot(resolved, () => {
|
|
28843
29435
|
workspaceFor(resolved).invalidate();
|
|
28844
29436
|
const system = loadSystemSpec();
|
|
@@ -28927,7 +29519,7 @@ function loadConfig() {
|
|
|
28927
29519
|
|
|
28928
29520
|
// src/core/domain_projector.ts
|
|
28929
29521
|
function rel(p) {
|
|
28930
|
-
return
|
|
29522
|
+
return path20.relative(process.cwd(), p).replace(/\\/g, "/");
|
|
28931
29523
|
}
|
|
28932
29524
|
function deriveSubsystemDomains() {
|
|
28933
29525
|
const subsystems = loadSubsystemSpecs();
|
|
@@ -28968,9 +29560,9 @@ function unregisterDomain(id) {
|
|
|
28968
29560
|
}
|
|
28969
29561
|
|
|
28970
29562
|
// src/core/external-producers.ts
|
|
28971
|
-
var
|
|
29563
|
+
var path21 = __toESM(require("path"));
|
|
28972
29564
|
function dirKey2(dir) {
|
|
28973
|
-
const resolved =
|
|
29565
|
+
const resolved = path21.resolve(dir);
|
|
28974
29566
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
28975
29567
|
}
|
|
28976
29568
|
function climb(bound2) {
|
|
@@ -28978,7 +29570,7 @@ function climb(bound2) {
|
|
|
28978
29570
|
for (; ; ) {
|
|
28979
29571
|
const parent = runWithProjectRoot(top, () => resolveChainingParent());
|
|
28980
29572
|
if (!parent) break;
|
|
28981
|
-
top =
|
|
29573
|
+
top = path21.resolve(parent.parentRoot);
|
|
28982
29574
|
}
|
|
28983
29575
|
const reach2 = getRequestParentReach();
|
|
28984
29576
|
const stoppedAtNarrowedCeiling = !!reach2?.narrowed && reach2.topRoot !== void 0 && dirKey2(top) === dirKey2(reach2.topRoot);
|
|
@@ -28988,7 +29580,7 @@ function consumerNode(family, bound2) {
|
|
|
28988
29580
|
return family.nodes.find((n) => dirKey2(n.directory) === dirKey2(bound2));
|
|
28989
29581
|
}
|
|
28990
29582
|
function resolveDeclared() {
|
|
28991
|
-
const bound2 =
|
|
29583
|
+
const bound2 = path21.resolve(getProjectRoot());
|
|
28992
29584
|
const { top, whole } = climb(bound2);
|
|
28993
29585
|
const answer = (root) => runWithProjectRoot(root, () => {
|
|
28994
29586
|
const family = graph();
|
|
@@ -29005,7 +29597,7 @@ function resolveDeclared() {
|
|
|
29005
29597
|
|
|
29006
29598
|
// src/core/provision.ts
|
|
29007
29599
|
var fs13 = __toESM(require("fs"));
|
|
29008
|
-
var
|
|
29600
|
+
var path22 = __toESM(require("path"));
|
|
29009
29601
|
function defaultProjectConfig(name, now, id) {
|
|
29010
29602
|
const declared = id ?? effectiveProjectId({ name });
|
|
29011
29603
|
return {
|
|
@@ -29109,7 +29701,7 @@ function memberDeclarationsAt2(dir) {
|
|
|
29109
29701
|
function walkMembers(projectRoot, onMember) {
|
|
29110
29702
|
const visited = /* @__PURE__ */ new Set();
|
|
29111
29703
|
const walk2 = (dir) => {
|
|
29112
|
-
const resolved =
|
|
29704
|
+
const resolved = path22.resolve(dir);
|
|
29113
29705
|
if (visited.has(resolved)) return;
|
|
29114
29706
|
visited.add(resolved);
|
|
29115
29707
|
for (const member of memberDeclarationsAt2(dir)) {
|
|
@@ -29160,25 +29752,65 @@ function backfillChainedSubprojectConfigs(projectRoot) {
|
|
|
29160
29752
|
});
|
|
29161
29753
|
return backfilled;
|
|
29162
29754
|
}
|
|
29163
|
-
|
|
29164
|
-
|
|
29755
|
+
var FETCHABLE_RE = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
29756
|
+
function scaffoldRequirements(requirements, installed) {
|
|
29757
|
+
const adopted = [];
|
|
29758
|
+
const unadopted = [];
|
|
29759
|
+
const profiles = [];
|
|
29760
|
+
for (const requirement of requirements) {
|
|
29761
|
+
let best = null;
|
|
29762
|
+
for (const pack of installed) {
|
|
29763
|
+
if (pack.name !== requirement.pack || !admits(requirement, pack.version)) continue;
|
|
29764
|
+
if (!best || isNewerVersion(best.version, pack.version)) best = pack;
|
|
29765
|
+
}
|
|
29766
|
+
if (!best) {
|
|
29767
|
+
unadopted.push(requirement);
|
|
29768
|
+
continue;
|
|
29769
|
+
}
|
|
29770
|
+
adopted.push({
|
|
29771
|
+
name: best.name,
|
|
29772
|
+
version: best.version,
|
|
29773
|
+
integrity: best.digest,
|
|
29774
|
+
...best.origin && FETCHABLE_RE.test(best.origin) ? { source: best.origin } : {}
|
|
29775
|
+
});
|
|
29776
|
+
if (requirement.profile) profiles.push(requirement.profile);
|
|
29777
|
+
}
|
|
29778
|
+
return { adopted, unadopted, ...profiles.length === 1 ? { projectType: profiles[0] } : {} };
|
|
29779
|
+
}
|
|
29780
|
+
function createMember(alias, path38, description) {
|
|
29781
|
+
if (!EXTERNAL_ALIAS_RE.test(alias) || typeof path38 !== "string" || path38.trim() === "") {
|
|
29165
29782
|
throw new WaironError(
|
|
29166
29783
|
`an alias and a path are required to create a member: the alias must fit [a-z0-9-_]+ (got "${alias}") and the path must not be empty.`
|
|
29167
29784
|
);
|
|
29168
29785
|
}
|
|
29169
|
-
const relPath = toPosixPath(
|
|
29786
|
+
const relPath = toPosixPath(path38);
|
|
29170
29787
|
const memberDir = assertContainedProjectPath(getProjectRoot(), relPath);
|
|
29788
|
+
const requirements = requiredPolicies(projectConfigRepository.load() ?? {});
|
|
29171
29789
|
const parentName = loadSystemSpec()?.name;
|
|
29172
29790
|
const vision = description ?? `Member ${alias} of ${parentName ? `the ${parentName} project` : "its parent project"}`;
|
|
29173
|
-
runWithProjectRoot(memberDir, () => {
|
|
29791
|
+
const creation = runWithProjectRoot(memberDir, () => {
|
|
29174
29792
|
ensureDir(aiPathsAt(memberDir).specsDir());
|
|
29793
|
+
if (projectConfigRepository.exists()) {
|
|
29794
|
+
ensureProjectInitialized(alias, alias, vision);
|
|
29795
|
+
return { configCreated: false, adopted: [], unadopted: [] };
|
|
29796
|
+
}
|
|
29797
|
+
const scaffold = scaffoldRequirements(requirements, listInstalledPacks());
|
|
29798
|
+
const name = loadSystemSpec()?.name ?? alias;
|
|
29799
|
+
const config = defaultProjectConfig(name, (/* @__PURE__ */ new Date()).toISOString(), alias);
|
|
29800
|
+
projectConfigRepository.create({
|
|
29801
|
+
...config,
|
|
29802
|
+
...scaffold.projectType ? { projectType: scaffold.projectType } : {},
|
|
29803
|
+
...scaffold.adopted.length > 0 ? { extensions: { packs: scaffold.adopted, useGlobalPacks: false } } : {}
|
|
29804
|
+
});
|
|
29175
29805
|
ensureProjectInitialized(alias, alias, vision);
|
|
29806
|
+
return { configCreated: true, ...scaffold };
|
|
29176
29807
|
});
|
|
29177
29808
|
projectConfigRepository.declareMember(alias, {
|
|
29178
29809
|
path: relPath,
|
|
29179
29810
|
...description !== void 0 ? { description } : {}
|
|
29180
29811
|
});
|
|
29181
29812
|
invalidateSpecCache();
|
|
29813
|
+
return creation;
|
|
29182
29814
|
}
|
|
29183
29815
|
function moveMember(alias, newPath) {
|
|
29184
29816
|
const member = graph().nodes.find((n) => n.parent === "" && n.mountAlias === alias);
|
|
@@ -29207,7 +29839,7 @@ function moveMember(alias, newPath) {
|
|
|
29207
29839
|
if (fs13.existsSync(newDir)) {
|
|
29208
29840
|
throw new WaironError(`Target directory already exists: ${newDir}`);
|
|
29209
29841
|
}
|
|
29210
|
-
ensureDir(
|
|
29842
|
+
ensureDir(path22.dirname(newDir));
|
|
29211
29843
|
fs13.renameSync(oldDir, newDir);
|
|
29212
29844
|
}
|
|
29213
29845
|
projectConfigRepository.setMemberPath(alias, nextPath);
|
|
@@ -29229,9 +29861,9 @@ function toPosixPath(p) {
|
|
|
29229
29861
|
return p.replace(/\\/g, "/");
|
|
29230
29862
|
}
|
|
29231
29863
|
function isWithinDir2(dir, file) {
|
|
29232
|
-
const d =
|
|
29233
|
-
const f =
|
|
29234
|
-
return f === d || f.startsWith(d +
|
|
29864
|
+
const d = path22.resolve(dir);
|
|
29865
|
+
const f = path22.resolve(file);
|
|
29866
|
+
return f === d || f.startsWith(d + path22.sep);
|
|
29235
29867
|
}
|
|
29236
29868
|
var MOVED_REF_POSITIONS = /* @__PURE__ */ new Set(["component", "interface"]);
|
|
29237
29869
|
var INTO_MEMBER_POSITIONS = /* @__PURE__ */ new Set([...MOVED_REF_POSITIONS, "type"]);
|
|
@@ -29245,13 +29877,13 @@ function externalizeSubsystem(subsystemId, memberPath) {
|
|
|
29245
29877
|
}
|
|
29246
29878
|
const parentRoot = getProjectRoot();
|
|
29247
29879
|
const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
|
|
29248
|
-
const fooDir =
|
|
29880
|
+
const fooDir = path22.join(parentSpecsDir, subsystemId);
|
|
29249
29881
|
if (!fs13.existsSync(fooDir)) {
|
|
29250
29882
|
throw new WaironError(`subsystem specs directory not found: ${fooDir}`);
|
|
29251
29883
|
}
|
|
29252
29884
|
const relPath = toPosixPath(memberPath);
|
|
29253
29885
|
const memberDir = assertContainedProjectPath(parentRoot, relPath);
|
|
29254
|
-
const memberFooDir =
|
|
29886
|
+
const memberFooDir = path22.join(aiPathsAt(memberDir).specsDir(), subsystemId);
|
|
29255
29887
|
if (fs13.existsSync(memberFooDir)) {
|
|
29256
29888
|
throw new WaironError(`target already contains a "${subsystemId}" subsystem: ${memberFooDir}`);
|
|
29257
29889
|
}
|
|
@@ -29275,10 +29907,10 @@ function externalizeSubsystem(subsystemId, memberPath) {
|
|
|
29275
29907
|
ensureDir(aiPathsAt(memberDir).specsDir());
|
|
29276
29908
|
saveSystemSpec(bootstrapSystemSpec(memberName, now));
|
|
29277
29909
|
});
|
|
29278
|
-
ensureDir(
|
|
29910
|
+
ensureDir(path22.dirname(memberFooDir));
|
|
29279
29911
|
fs13.renameSync(fooDir, memberFooDir);
|
|
29280
29912
|
rebaseImplementationPaths(memberFooDir, parentRoot, memberDir);
|
|
29281
|
-
patchSubsystemIndex(
|
|
29913
|
+
patchSubsystemIndex(path22.join(memberFooDir, ".index.yaml"), (s) => {
|
|
29282
29914
|
s.parentSystem = memberName;
|
|
29283
29915
|
delete s.projectPath;
|
|
29284
29916
|
});
|
|
@@ -29376,16 +30008,16 @@ function internalizeMember(alias) {
|
|
|
29376
30008
|
}
|
|
29377
30009
|
const parentRoot = getProjectRoot();
|
|
29378
30010
|
const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
|
|
29379
|
-
const memberDir = assertContainedProjectPath(parentRoot,
|
|
30011
|
+
const memberDir = assertContainedProjectPath(parentRoot, path22.relative(parentRoot, member.directory) || ".");
|
|
29380
30012
|
const memberSpecsDir = aiPathsAt(memberDir).specsDir();
|
|
29381
30013
|
const localSub = subsystems[0].id.slice(member.namespace.length + 2);
|
|
29382
30014
|
const intoMember = crossingReferences(family, "", member.namespace);
|
|
29383
30015
|
const backOut = crossingReferences(family, member.namespace, "");
|
|
29384
30016
|
deleteMount(alias);
|
|
29385
|
-
const movedFiles = moveTreeInto(memberSpecsDir, parentSpecsDir, /* @__PURE__ */ new Set([
|
|
30017
|
+
const movedFiles = moveTreeInto(memberSpecsDir, parentSpecsDir, /* @__PURE__ */ new Set([path22.resolve(aiPathsAt(memberDir).specsSystem())]));
|
|
29386
30018
|
rebaseImplementationPaths(parentSpecsDir, memberDir, parentRoot, movedFiles);
|
|
29387
30019
|
const parentSystemName = loadSystemSpec()?.name;
|
|
29388
|
-
patchSubsystemIndex(
|
|
30020
|
+
patchSubsystemIndex(path22.join(parentSpecsDir, localSub, ".index.yaml"), (s) => {
|
|
29389
30021
|
if (parentSystemName) s.parentSystem = parentSystemName;
|
|
29390
30022
|
delete s.projectPath;
|
|
29391
30023
|
});
|
|
@@ -29393,7 +30025,7 @@ function internalizeMember(alias) {
|
|
|
29393
30025
|
...rewriteRefFields(parentSpecsDir, (ref) => intoMember.get(ref) ?? backOut.get(ref) ?? ref)
|
|
29394
30026
|
];
|
|
29395
30027
|
projectConfigRepository.removeMember(alias);
|
|
29396
|
-
fs13.rmSync(
|
|
30028
|
+
fs13.rmSync(path22.join(memberDir, ".wai"), { recursive: true, force: true });
|
|
29397
30029
|
invalidateSpecCache();
|
|
29398
30030
|
for (const spec of rewritten) if (spec.kind !== "system") normalizeReferences(spec.kind, spec.id);
|
|
29399
30031
|
restateReExports(alias, localSub);
|
|
@@ -29477,14 +30109,14 @@ function referencesUnder(dir, matches) {
|
|
|
29477
30109
|
}
|
|
29478
30110
|
function moveTreeInto(src, dst, skip) {
|
|
29479
30111
|
if (!fs13.existsSync(src)) return [];
|
|
29480
|
-
const files = listFilesRecursive(src, "").filter((f) => !skip.has(
|
|
29481
|
-
const targets = files.map((f) =>
|
|
30112
|
+
const files = listFilesRecursive(src, "").filter((f) => !skip.has(path22.resolve(f)));
|
|
30113
|
+
const targets = files.map((f) => path22.join(dst, path22.relative(src, f)));
|
|
29482
30114
|
const taken = targets.filter((t) => fs13.existsSync(t));
|
|
29483
30115
|
if (taken.length > 0) {
|
|
29484
|
-
throw new WaironError(`cannot internalize: the member's specs would overwrite ${taken.map((t) =>
|
|
30116
|
+
throw new WaironError(`cannot internalize: the member's specs would overwrite ${taken.map((t) => path22.relative(dst, t)).join(", ")} in this project.`);
|
|
29485
30117
|
}
|
|
29486
30118
|
files.forEach((file, i) => {
|
|
29487
|
-
ensureDir(
|
|
30119
|
+
ensureDir(path22.dirname(targets[i]));
|
|
29488
30120
|
fs13.renameSync(file, targets[i]);
|
|
29489
30121
|
});
|
|
29490
30122
|
return targets;
|
|
@@ -29564,8 +30196,8 @@ function rebaseImplementationPaths(specsDir, fromRoot, toRoot, only) {
|
|
|
29564
30196
|
let changed = false;
|
|
29565
30197
|
const rebase = (holder, key) => {
|
|
29566
30198
|
const p = holder[key];
|
|
29567
|
-
if (typeof p !== "string" || p === "" ||
|
|
29568
|
-
const next = toPosixPath(
|
|
30199
|
+
if (typeof p !== "string" || p === "" || path22.isAbsolute(p)) return;
|
|
30200
|
+
const next = toPosixPath(path22.relative(toRoot, path22.resolve(fromRoot, p)));
|
|
29569
30201
|
if (next !== p) {
|
|
29570
30202
|
holder[key] = next;
|
|
29571
30203
|
changed = true;
|
|
@@ -29650,7 +30282,7 @@ function moveRenamedSpecs(componentId, newId, component, movingInterface, moving
|
|
|
29650
30282
|
if (movedInterface) saveInterfaceSpec({ ...movedInterface, id: interfaceId, component: newId });
|
|
29651
30283
|
if (movedImplementation) {
|
|
29652
30284
|
const oldFile = getImplementationPath(movedImplementation.id);
|
|
29653
|
-
if (
|
|
30285
|
+
if (path22.resolve(getImplementationPath(implementationId, movedImplementation.contract)) === path22.resolve(oldFile)) {
|
|
29654
30286
|
fs13.unlinkSync(oldFile);
|
|
29655
30287
|
}
|
|
29656
30288
|
saveImplementationSpec({ ...movedImplementation, id: implementationId });
|
|
@@ -29668,8 +30300,8 @@ function removeSpecFile2(file, id) {
|
|
|
29668
30300
|
return;
|
|
29669
30301
|
}
|
|
29670
30302
|
fs13.unlinkSync(file);
|
|
29671
|
-
const specsRoot =
|
|
29672
|
-
for (let dir =
|
|
30303
|
+
const specsRoot = path22.resolve(aiPathsAt(getProjectRoot()).specsDir());
|
|
30304
|
+
for (let dir = path22.dirname(path22.resolve(file)); dir !== specsRoot && isWithinDir2(specsRoot, dir); dir = path22.dirname(dir)) {
|
|
29673
30305
|
if (fs13.readdirSync(dir).length > 0) break;
|
|
29674
30306
|
fs13.rmdirSync(dir);
|
|
29675
30307
|
}
|
|
@@ -29818,7 +30450,7 @@ function normalizeReferences2(kind, id) {
|
|
|
29818
30450
|
|
|
29819
30451
|
// src/core/detection.ts
|
|
29820
30452
|
var fs14 = __toESM(require("fs"));
|
|
29821
|
-
var
|
|
30453
|
+
var path23 = __toESM(require("path"));
|
|
29822
30454
|
var PACKAGE_MARKERS = [
|
|
29823
30455
|
"package.json",
|
|
29824
30456
|
"pyproject.toml",
|
|
@@ -29891,7 +30523,7 @@ function parseGitmodules(filePath) {
|
|
|
29891
30523
|
return entries;
|
|
29892
30524
|
}
|
|
29893
30525
|
function detectGitSubmodules(projectRoot) {
|
|
29894
|
-
const gitmodulesPath =
|
|
30526
|
+
const gitmodulesPath = path23.join(projectRoot, ".gitmodules");
|
|
29895
30527
|
if (!fs14.existsSync(gitmodulesPath)) return [];
|
|
29896
30528
|
return parseGitmodules(gitmodulesPath).map((entry) => ({
|
|
29897
30529
|
suggestedId: pathToId(entry.path),
|
|
@@ -29917,10 +30549,10 @@ function walkForGit(projectRoot, currentDir, depth, results) {
|
|
|
29917
30549
|
for (const entry of entries) {
|
|
29918
30550
|
if (!entry.isDirectory()) continue;
|
|
29919
30551
|
if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
|
|
29920
|
-
const fullPath =
|
|
29921
|
-
const relPath = normalizePath(
|
|
30552
|
+
const fullPath = path23.join(currentDir, entry.name);
|
|
30553
|
+
const relPath = normalizePath(path23.relative(projectRoot, fullPath));
|
|
29922
30554
|
if (relPath === "" || relPath === ".") continue;
|
|
29923
|
-
const gitPath =
|
|
30555
|
+
const gitPath = path23.join(fullPath, ".git");
|
|
29924
30556
|
if (fs14.existsSync(gitPath)) {
|
|
29925
30557
|
results.push({
|
|
29926
30558
|
suggestedId: pathToId(relPath),
|
|
@@ -29950,10 +30582,10 @@ function walkForPackages(projectRoot, currentDir, depth, results) {
|
|
|
29950
30582
|
for (const entry of entries) {
|
|
29951
30583
|
if (!entry.isDirectory()) continue;
|
|
29952
30584
|
if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
|
|
29953
|
-
const fullPath =
|
|
29954
|
-
const relPath = normalizePath(
|
|
30585
|
+
const fullPath = path23.join(currentDir, entry.name);
|
|
30586
|
+
const relPath = normalizePath(path23.relative(projectRoot, fullPath));
|
|
29955
30587
|
if (relPath === "" || relPath === ".") continue;
|
|
29956
|
-
const hasMarker = PACKAGE_MARKERS.some((m) => fs14.existsSync(
|
|
30588
|
+
const hasMarker = PACKAGE_MARKERS.some((m) => fs14.existsSync(path23.join(fullPath, m)));
|
|
29957
30589
|
if (hasMarker) {
|
|
29958
30590
|
results.push({
|
|
29959
30591
|
suggestedId: pathToId(relPath),
|
|
@@ -29967,8 +30599,8 @@ function walkForPackages(projectRoot, currentDir, depth, results) {
|
|
|
29967
30599
|
}
|
|
29968
30600
|
}
|
|
29969
30601
|
function pathToId(relPath) {
|
|
29970
|
-
const
|
|
29971
|
-
return
|
|
30602
|
+
const basename11 = path23.basename(relPath);
|
|
30603
|
+
return basename11.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
29972
30604
|
}
|
|
29973
30605
|
function pathToName(relPath) {
|
|
29974
30606
|
const id = pathToId(relPath);
|
|
@@ -29981,7 +30613,7 @@ function normalizePath(p) {
|
|
|
29981
30613
|
// src/core/variants.ts
|
|
29982
30614
|
var fs15 = __toESM(require("fs"));
|
|
29983
30615
|
var os3 = __toESM(require("os"));
|
|
29984
|
-
var
|
|
30616
|
+
var path24 = __toESM(require("path"));
|
|
29985
30617
|
var import_zod10 = require("zod");
|
|
29986
30618
|
var VariantDefSchema = import_zod10.z.object({
|
|
29987
30619
|
/** Variant id referenced by a component's `variant` (e.g. "publisher", "org/external-config-adapter"). */
|
|
@@ -29996,19 +30628,19 @@ var VariantDefSchema = import_zod10.z.object({
|
|
|
29996
30628
|
profile: import_zod10.z.string().optional()
|
|
29997
30629
|
});
|
|
29998
30630
|
function globalVariantsDir() {
|
|
29999
|
-
return process.env.WAIRON_VARIANTS_DIR ??
|
|
30631
|
+
return process.env.WAIRON_VARIANTS_DIR ?? path24.join(os3.homedir(), ".wairon", "variants");
|
|
30000
30632
|
}
|
|
30001
30633
|
function builtinVariantsDir() {
|
|
30002
30634
|
const candidates = [
|
|
30003
|
-
|
|
30635
|
+
path24.resolve(__dirname, "..", "templates", "variants"),
|
|
30004
30636
|
// src/core & dist/cli
|
|
30005
|
-
|
|
30637
|
+
path24.resolve(__dirname, "templates", "variants")
|
|
30006
30638
|
// dist (library entry)
|
|
30007
30639
|
];
|
|
30008
30640
|
return candidates.find((dir) => fs15.existsSync(dir)) ?? candidates[0];
|
|
30009
30641
|
}
|
|
30010
30642
|
function projectVariantsDir() {
|
|
30011
|
-
return
|
|
30643
|
+
return path24.join(getProjectRoot(), ".wai", "variants");
|
|
30012
30644
|
}
|
|
30013
30645
|
function variantFiles(dir) {
|
|
30014
30646
|
let entries;
|
|
@@ -30017,7 +30649,7 @@ function variantFiles(dir) {
|
|
|
30017
30649
|
} catch {
|
|
30018
30650
|
return [];
|
|
30019
30651
|
}
|
|
30020
|
-
return entries.filter((e) => e.isFile() && /\.ya?ml$/i.test(e.name)).sort((a, b) => a.name.localeCompare(b.name)).map((e) =>
|
|
30652
|
+
return entries.filter((e) => e.isFile() && /\.ya?ml$/i.test(e.name)).sort((a, b) => a.name.localeCompare(b.name)).map((e) => path24.join(dir, e.name));
|
|
30021
30653
|
}
|
|
30022
30654
|
function parseVariants(raw) {
|
|
30023
30655
|
if (raw == null) return [];
|
|
@@ -30128,18 +30760,18 @@ function rebasedText(content, fromBase, toBase, rebasedContent) {
|
|
|
30128
30760
|
}
|
|
30129
30761
|
|
|
30130
30762
|
// src/core/agent_resolver.ts
|
|
30131
|
-
var
|
|
30763
|
+
var path26 = __toESM(require("path"));
|
|
30132
30764
|
var fs16 = __toESM(require("fs"));
|
|
30133
30765
|
|
|
30134
30766
|
// src/core/templates.ts
|
|
30135
|
-
var
|
|
30767
|
+
var path25 = __toESM(require("path"));
|
|
30136
30768
|
function builtinTemplatesDir() {
|
|
30137
|
-
return
|
|
30769
|
+
return path25.resolve(__dirname, "..", "templates");
|
|
30138
30770
|
}
|
|
30139
30771
|
function loadTemplate(id, globalOverride) {
|
|
30140
30772
|
const dirs = templateSearchDirs(globalOverride);
|
|
30141
30773
|
for (const dir of dirs) {
|
|
30142
|
-
const filePath =
|
|
30774
|
+
const filePath = path25.join(dir, `${id}.yaml`);
|
|
30143
30775
|
if (pathExists(filePath)) {
|
|
30144
30776
|
const raw = readYamlFile(filePath);
|
|
30145
30777
|
return { ...TemplateSchema.parse(raw), templateName: id };
|
|
@@ -30148,7 +30780,7 @@ function loadTemplate(id, globalOverride) {
|
|
|
30148
30780
|
throw new TemplateNotFoundError(id);
|
|
30149
30781
|
}
|
|
30150
30782
|
function loadAgentOverride(agentId) {
|
|
30151
|
-
const filePath =
|
|
30783
|
+
const filePath = path25.join(AI_PATHS.root(), "agents", `${agentId}.md`);
|
|
30152
30784
|
return readFileOrNull(filePath);
|
|
30153
30785
|
}
|
|
30154
30786
|
function templateSearchDirs(globalOverride) {
|
|
@@ -30300,7 +30932,7 @@ function resolveBudget(profile, config, agentId) {
|
|
|
30300
30932
|
var projectFilesCache = /* @__PURE__ */ new Map();
|
|
30301
30933
|
function listFilesRecursiveSafe(dirPath, ext) {
|
|
30302
30934
|
if (!fs16.existsSync(dirPath)) return [];
|
|
30303
|
-
const nameLower =
|
|
30935
|
+
const nameLower = path26.basename(dirPath).toLowerCase();
|
|
30304
30936
|
const IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
30305
30937
|
"node_modules",
|
|
30306
30938
|
"target",
|
|
@@ -30318,7 +30950,7 @@ function listFilesRecursiveSafe(dirPath, ext) {
|
|
|
30318
30950
|
const entries = fs16.readdirSync(dirPath, { withFileTypes: true });
|
|
30319
30951
|
const files = [];
|
|
30320
30952
|
for (const entry of entries) {
|
|
30321
|
-
const fullPath =
|
|
30953
|
+
const fullPath = path26.join(dirPath, entry.name);
|
|
30322
30954
|
if (entry.isDirectory()) {
|
|
30323
30955
|
files.push(...listFilesRecursiveSafe(fullPath, ext));
|
|
30324
30956
|
} else if (entry.isFile() && entry.name.endsWith(ext)) {
|
|
@@ -30331,8 +30963,8 @@ function getProjectFiles(projectDir) {
|
|
|
30331
30963
|
let files = projectFilesCache.get(projectDir);
|
|
30332
30964
|
if (!files) {
|
|
30333
30965
|
files = [];
|
|
30334
|
-
const srcDir =
|
|
30335
|
-
const legacySrcDir =
|
|
30966
|
+
const srcDir = path26.join(projectDir, "src");
|
|
30967
|
+
const legacySrcDir = path26.join(projectDir, "legacy-src");
|
|
30336
30968
|
let searchDir = projectDir;
|
|
30337
30969
|
if (pathExists(srcDir)) {
|
|
30338
30970
|
searchDir = srcDir;
|
|
@@ -30347,7 +30979,7 @@ function getProjectFiles(projectDir) {
|
|
|
30347
30979
|
files.push(...listFilesRecursiveSafe(searchDir, ext));
|
|
30348
30980
|
}
|
|
30349
30981
|
const rootDir = getProjectRoot();
|
|
30350
|
-
files = files.map((f) =>
|
|
30982
|
+
files = files.map((f) => path26.relative(rootDir, f).replace(/\\/g, "/"));
|
|
30351
30983
|
projectFilesCache.set(projectDir, files);
|
|
30352
30984
|
}
|
|
30353
30985
|
return files;
|
|
@@ -30372,8 +31004,8 @@ function inferSourcePathForComponent(comp, subsystems) {
|
|
|
30372
31004
|
let bestFile = null;
|
|
30373
31005
|
let bestScore = -1;
|
|
30374
31006
|
for (const f of files) {
|
|
30375
|
-
const ext =
|
|
30376
|
-
const base =
|
|
31007
|
+
const ext = path26.extname(f);
|
|
31008
|
+
const base = path26.basename(f, ext).toLowerCase();
|
|
30377
31009
|
if (candidates.has(base)) {
|
|
30378
31010
|
let score = 0;
|
|
30379
31011
|
const normalizedPath = f.toLowerCase();
|
|
@@ -30428,8 +31060,8 @@ function inferSourcePathForComponent(comp, subsystems) {
|
|
|
30428
31060
|
return null;
|
|
30429
31061
|
}
|
|
30430
31062
|
}
|
|
30431
|
-
function summarize2(
|
|
30432
|
-
const clean =
|
|
31063
|
+
function summarize2(text3, max = 140) {
|
|
31064
|
+
const clean = text3.replace(/\s+/g, " ").trim();
|
|
30433
31065
|
const period = clean.indexOf(". ");
|
|
30434
31066
|
const firstSentence = period > 0 ? clean.slice(0, period + 1) : clean;
|
|
30435
31067
|
if (firstSentence.length <= max) return firstSentence;
|
|
@@ -30446,7 +31078,7 @@ function resolveAgentTopology() {
|
|
|
30446
31078
|
const members = graph().nodes.filter((n) => n.parent === "" && n.mountAlias !== void 0).map((n) => ({
|
|
30447
31079
|
id: n.mountAlias,
|
|
30448
31080
|
name: n.mountAlias,
|
|
30449
|
-
projectPath:
|
|
31081
|
+
projectPath: path26.relative(getProjectRoot(), n.directory).replace(/\\/g, "/"),
|
|
30450
31082
|
form: n.mountForm,
|
|
30451
31083
|
createdAt: n.legacyMount?.createdAt ?? system.createdAt,
|
|
30452
31084
|
updatedAt: n.legacyMount?.updatedAt ?? system.updatedAt
|
|
@@ -30481,7 +31113,7 @@ function resolveAgentTopology() {
|
|
|
30481
31113
|
});
|
|
30482
31114
|
for (const sub of subsystems) {
|
|
30483
31115
|
if (sub.projectPath) {
|
|
30484
|
-
const mountSpecPath = sub.form === "members" ? `${sub.projectPath}/**` :
|
|
31116
|
+
const mountSpecPath = sub.form === "members" ? `${sub.projectPath}/**` : path26.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/");
|
|
30485
31117
|
agents.push({
|
|
30486
31118
|
id: `${sub.id}-owner`,
|
|
30487
31119
|
name: `${sub.name} (member project)`,
|
|
@@ -30503,9 +31135,9 @@ function resolveAgentTopology() {
|
|
|
30503
31135
|
}
|
|
30504
31136
|
const subComponents = components.filter((c) => c.subsystem === sub.id);
|
|
30505
31137
|
const ownedPaths = [];
|
|
30506
|
-
ownedPaths.push(
|
|
31138
|
+
ownedPaths.push(path26.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/"));
|
|
30507
31139
|
for (const c of subComponents) {
|
|
30508
|
-
ownedPaths.push(
|
|
31140
|
+
ownedPaths.push(path26.relative(getProjectRoot(), getComponentPath(c.id, sub.id)).replace(/\\/g, "/"));
|
|
30509
31141
|
}
|
|
30510
31142
|
if (!config.rules.generateComponentImplementers) {
|
|
30511
31143
|
for (const comp of subComponents) {
|
|
@@ -30581,10 +31213,10 @@ function resolveAgentTopology() {
|
|
|
30581
31213
|
}
|
|
30582
31214
|
const dependencies = comp.dependsOn.map((depId) => `${depId}-implementer`);
|
|
30583
31215
|
const readPaths = [
|
|
30584
|
-
|
|
30585
|
-
|
|
30586
|
-
...compInterfaces.map((i) =>
|
|
30587
|
-
...compImpls.map((impl) =>
|
|
31216
|
+
path26.relative(getProjectRoot(), AI_PATHS.specsSystem()).replace(/\\/g, "/"),
|
|
31217
|
+
path26.relative(getProjectRoot(), getComponentPath(comp.id, comp.subsystem)).replace(/\\/g, "/"),
|
|
31218
|
+
...compInterfaces.map((i) => path26.relative(getProjectRoot(), getInterfacePath(i.id, comp.id)).replace(/\\/g, "/")),
|
|
31219
|
+
...compImpls.map((impl) => path26.relative(getProjectRoot(), getImplementationPath(impl.id, impl.contract)).replace(/\\/g, "/"))
|
|
30588
31220
|
];
|
|
30589
31221
|
agents.push({
|
|
30590
31222
|
id: `${comp.id}-implementer`,
|
|
@@ -30690,10 +31322,10 @@ function loadRegistry() {
|
|
|
30690
31322
|
}
|
|
30691
31323
|
|
|
30692
31324
|
// src/exporters/generate.ts
|
|
30693
|
-
var
|
|
31325
|
+
var path30 = __toESM(require("path"));
|
|
30694
31326
|
|
|
30695
31327
|
// src/exporters/claude.ts
|
|
30696
|
-
var
|
|
31328
|
+
var path27 = __toESM(require("path"));
|
|
30697
31329
|
var MODEL_BY_TIER = {
|
|
30698
31330
|
small: "haiku",
|
|
30699
31331
|
standard: "sonnet",
|
|
@@ -30732,7 +31364,7 @@ var ClaudeExporter = class {
|
|
|
30732
31364
|
outputPath(ctx) {
|
|
30733
31365
|
const { agent, target, projectRoot } = ctx;
|
|
30734
31366
|
const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
|
|
30735
|
-
return
|
|
31367
|
+
return path27.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
30736
31368
|
}
|
|
30737
31369
|
export(ctx) {
|
|
30738
31370
|
const { agent, renderedInstructions, budget } = ctx;
|
|
@@ -30757,7 +31389,7 @@ var ClaudeExporter = class {
|
|
|
30757
31389
|
};
|
|
30758
31390
|
|
|
30759
31391
|
// src/exporters/custom.ts
|
|
30760
|
-
var
|
|
31392
|
+
var path28 = __toESM(require("path"));
|
|
30761
31393
|
var CustomExporter = class {
|
|
30762
31394
|
constructor() {
|
|
30763
31395
|
this.targetType = "custom";
|
|
@@ -30767,7 +31399,7 @@ var CustomExporter = class {
|
|
|
30767
31399
|
if (!("outputDir" in target)) {
|
|
30768
31400
|
throw new Error("CustomExporter requires target.outputDir");
|
|
30769
31401
|
}
|
|
30770
|
-
return
|
|
31402
|
+
return path28.resolve(projectRoot, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
30771
31403
|
}
|
|
30772
31404
|
export(ctx) {
|
|
30773
31405
|
const { agent, target, renderedInstructions } = ctx;
|
|
@@ -30790,7 +31422,7 @@ var CustomExporter = class {
|
|
|
30790
31422
|
};
|
|
30791
31423
|
|
|
30792
31424
|
// src/exporters/gemini.ts
|
|
30793
|
-
var
|
|
31425
|
+
var path29 = __toESM(require("path"));
|
|
30794
31426
|
var GeminiExporter = class {
|
|
30795
31427
|
constructor() {
|
|
30796
31428
|
this.targetType = "gemini";
|
|
@@ -30798,7 +31430,7 @@ var GeminiExporter = class {
|
|
|
30798
31430
|
outputPath(ctx) {
|
|
30799
31431
|
const { agent, target, projectRoot } = ctx;
|
|
30800
31432
|
const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
|
|
30801
|
-
return
|
|
31433
|
+
return path29.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
|
|
30802
31434
|
}
|
|
30803
31435
|
export(ctx) {
|
|
30804
31436
|
const { agent, renderedInstructions } = ctx;
|
|
@@ -30895,7 +31527,7 @@ function resolveExpectedOutputPaths(agents, projectConfig, projectRoot = getProj
|
|
|
30895
31527
|
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
30896
31528
|
if (!targetConfig) continue;
|
|
30897
31529
|
const ctx = { agent, projectRoot, target: targetConfig };
|
|
30898
|
-
expected.add(
|
|
31530
|
+
expected.add(path30.resolve(getExporter(targetConfig).outputPath(ctx)));
|
|
30899
31531
|
}
|
|
30900
31532
|
}
|
|
30901
31533
|
return expected;
|
|
@@ -30910,7 +31542,7 @@ function resolveTargetConfig(agentTarget, projectConfig) {
|
|
|
30910
31542
|
|
|
30911
31543
|
// src/core/treetransfer.ts
|
|
30912
31544
|
var fs17 = __toESM(require("fs"));
|
|
30913
|
-
var
|
|
31545
|
+
var path31 = __toESM(require("path"));
|
|
30914
31546
|
var sdkPortal = __toESM(require_dist());
|
|
30915
31547
|
var STAGING_PREFIX = ".wai-staging-";
|
|
30916
31548
|
var BACKUP_DIR = ".wai-backups";
|
|
@@ -30936,39 +31568,39 @@ function hasAuthoredSpecs(root) {
|
|
|
30936
31568
|
if (!pathExists(specsDir)) {
|
|
30937
31569
|
return false;
|
|
30938
31570
|
}
|
|
30939
|
-
const systemIndex =
|
|
31571
|
+
const systemIndex = path31.resolve(paths.specsSystem());
|
|
30940
31572
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
30941
|
-
if (
|
|
31573
|
+
if (path31.resolve(file) !== systemIndex) {
|
|
30942
31574
|
return true;
|
|
30943
31575
|
}
|
|
30944
31576
|
}
|
|
30945
31577
|
return false;
|
|
30946
31578
|
}
|
|
30947
31579
|
function createStagingDir(destDir) {
|
|
30948
|
-
const root =
|
|
31580
|
+
const root = path31.resolve(destDir);
|
|
30949
31581
|
fs17.mkdirSync(root, { recursive: true });
|
|
30950
|
-
const stagingDir = fs17.mkdtempSync(
|
|
31582
|
+
const stagingDir = fs17.mkdtempSync(path31.join(root, STAGING_PREFIX));
|
|
30951
31583
|
return stagingDir;
|
|
30952
31584
|
}
|
|
30953
31585
|
function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
|
|
30954
|
-
const root =
|
|
30955
|
-
const backupDir =
|
|
31586
|
+
const root = path31.resolve(destDir);
|
|
31587
|
+
const backupDir = path31.join(root, BACKUP_DIR, timestampSlug());
|
|
30956
31588
|
let backedUp = false;
|
|
30957
31589
|
for (const rootRel of roots) {
|
|
30958
31590
|
const relative12 = rootRel === "." ? "" : rootRel;
|
|
30959
|
-
const stagedSpecDir =
|
|
31591
|
+
const stagedSpecDir = path31.join(stagingDir, relative12, ".wai");
|
|
30960
31592
|
if (!fs17.existsSync(stagedSpecDir)) continue;
|
|
30961
|
-
const liveSpecDir = liveSpecDirFor(
|
|
31593
|
+
const liveSpecDir = liveSpecDirFor(path31.join(root, relative12));
|
|
30962
31594
|
if (backupExisting && liveSpecDir && fs17.existsSync(liveSpecDir)) {
|
|
30963
|
-
const backupTarget =
|
|
30964
|
-
fs17.mkdirSync(
|
|
31595
|
+
const backupTarget = path31.join(backupDir, relative12, path31.basename(liveSpecDir));
|
|
31596
|
+
fs17.mkdirSync(path31.dirname(backupTarget), { recursive: true });
|
|
30965
31597
|
fs17.renameSync(liveSpecDir, backupTarget);
|
|
30966
31598
|
backedUp = true;
|
|
30967
31599
|
} else if (liveSpecDir && fs17.existsSync(liveSpecDir)) {
|
|
30968
31600
|
fs17.rmSync(liveSpecDir, { recursive: true, force: true });
|
|
30969
31601
|
}
|
|
30970
|
-
const target =
|
|
30971
|
-
fs17.mkdirSync(
|
|
31602
|
+
const target = path31.join(root, relative12, ".wai");
|
|
31603
|
+
fs17.mkdirSync(path31.dirname(target), { recursive: true });
|
|
30972
31604
|
if (fs17.existsSync(target)) fs17.rmSync(target, { recursive: true, force: true });
|
|
30973
31605
|
fs17.renameSync(stagedSpecDir, target);
|
|
30974
31606
|
}
|
|
@@ -30993,7 +31625,7 @@ function exportSpecTree(includeDerived, allowPartial) {
|
|
|
30993
31625
|
const skipped = inspection.skipped.map(({ mount, projectPath, reason }) => ({ mount, projectPath, reason }));
|
|
30994
31626
|
const roots = [{ relativePath: ".", waiDir: aiPathsAt(root).root() }];
|
|
30995
31627
|
for (const rel2 of inspection.roots) {
|
|
30996
|
-
const waiDir = aiPathsAt(
|
|
31628
|
+
const waiDir = aiPathsAt(path31.resolve(root, rel2)).root();
|
|
30997
31629
|
if (pathExists(waiDir)) {
|
|
30998
31630
|
roots.push({ relativePath: rel2, waiDir });
|
|
30999
31631
|
} else {
|
|
@@ -31024,7 +31656,7 @@ function importSpecTree(archive, options) {
|
|
|
31024
31656
|
if (!info.compatible) {
|
|
31025
31657
|
throw new Error("incompatible .waitree archive (format or minimum wairon version)");
|
|
31026
31658
|
}
|
|
31027
|
-
const destDir =
|
|
31659
|
+
const destDir = path31.resolve(options.destDir ?? getProjectRoot());
|
|
31028
31660
|
const occupied = hasSpecTree(destDir);
|
|
31029
31661
|
const authored = hasAuthoredSpecs(destDir);
|
|
31030
31662
|
if (authored && options.replaceExisting !== true) {
|
|
@@ -31055,9 +31687,9 @@ function importSpecTree(archive, options) {
|
|
|
31055
31687
|
return result;
|
|
31056
31688
|
}
|
|
31057
31689
|
function liveSpecDirFor(rootDir) {
|
|
31058
|
-
const modern =
|
|
31690
|
+
const modern = path31.join(rootDir, ".wai");
|
|
31059
31691
|
if (fs17.existsSync(modern)) return modern;
|
|
31060
|
-
const legacy =
|
|
31692
|
+
const legacy = path31.join(rootDir, ".wairon");
|
|
31061
31693
|
if (fs17.existsSync(legacy)) return legacy;
|
|
31062
31694
|
return null;
|
|
31063
31695
|
}
|
|
@@ -31199,7 +31831,7 @@ function repairForeignStepFields(apply) {
|
|
|
31199
31831
|
|
|
31200
31832
|
// src/core/approval.ts
|
|
31201
31833
|
var crypto4 = __toESM(require("crypto"));
|
|
31202
|
-
var
|
|
31834
|
+
var path32 = __toESM(require("path"));
|
|
31203
31835
|
|
|
31204
31836
|
// src/models/lock.ts
|
|
31205
31837
|
function describeApprover(who) {
|
|
@@ -31216,12 +31848,12 @@ function digest(content) {
|
|
|
31216
31848
|
return crypto4.createHash("sha256").update(normalized, "utf8").digest("hex");
|
|
31217
31849
|
}
|
|
31218
31850
|
function currentSpecDigests(root = getProjectRoot()) {
|
|
31219
|
-
const mountDirs = graph().nodes.filter((n) => n.namespace !== "").map((n) => `${
|
|
31851
|
+
const mountDirs = graph().nodes.filter((n) => n.namespace !== "").map((n) => `${path32.resolve(n.directory).split(path32.sep).join("/")}/`);
|
|
31220
31852
|
const out = {};
|
|
31221
31853
|
for (const [abs, content] of snapshotSpecFiles()) {
|
|
31222
|
-
const normalized =
|
|
31854
|
+
const normalized = path32.resolve(abs).split(path32.sep).join("/");
|
|
31223
31855
|
if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
|
|
31224
|
-
out[
|
|
31856
|
+
out[path32.relative(root, abs).split(path32.sep).join("/")] = digest(content);
|
|
31225
31857
|
}
|
|
31226
31858
|
return out;
|
|
31227
31859
|
}
|
|
@@ -31279,7 +31911,7 @@ function currentChildPins(mounts, root = getProjectRoot()) {
|
|
|
31279
31911
|
const pins = {};
|
|
31280
31912
|
for (const mount of mounts) {
|
|
31281
31913
|
if (!mount.projectPath || mount.id.includes("::")) continue;
|
|
31282
|
-
const child = readLockRecordAt(
|
|
31914
|
+
const child = readLockRecordAt(path32.resolve(root, mount.projectPath));
|
|
31283
31915
|
if (child) pins[mount.id] = pinOf(child.stateId);
|
|
31284
31916
|
}
|
|
31285
31917
|
return pins;
|
|
@@ -31296,7 +31928,7 @@ function movedChildren(mounts, root = getProjectRoot()) {
|
|
|
31296
31928
|
return moved;
|
|
31297
31929
|
}
|
|
31298
31930
|
function memberMounts(root = getProjectRoot()) {
|
|
31299
|
-
return graph().nodes.filter((n) => n.parent === "" && n.mountAlias !== void 0).map((n) => ({ id: n.mountAlias, projectPath:
|
|
31931
|
+
return graph().nodes.filter((n) => n.parent === "" && n.mountAlias !== void 0).map((n) => ({ id: n.mountAlias, projectPath: path32.relative(root, n.directory).split(path32.sep).join("/") }));
|
|
31300
31932
|
}
|
|
31301
31933
|
function approvalVerdict() {
|
|
31302
31934
|
const quiet = { text: "", drifted: false };
|
|
@@ -31384,7 +32016,7 @@ function localApprover() {
|
|
|
31384
32016
|
// src/utils/ai-guide.ts
|
|
31385
32017
|
var fs18 = __toESM(require("fs"));
|
|
31386
32018
|
var os5 = __toESM(require("os"));
|
|
31387
|
-
var
|
|
32019
|
+
var path33 = __toESM(require("path"));
|
|
31388
32020
|
|
|
31389
32021
|
// src/core/stamp.ts
|
|
31390
32022
|
function versionStamp() {
|
|
@@ -31444,13 +32076,13 @@ This project uses **wairon**. System specs live under \`.wai/specs/\` (L0 System
|
|
|
31444
32076
|
* **Variants**: \`gateway\`, a Portal that authenticates, authorizes, validates or rate-limits before it dispatches. Logic is an Orchestrator, and \`dependencyClass: pure | read\` bounds what it may depend on (unset = a workflow). Specialist and Gateway are retired stereotypes.
|
|
31445
32077
|
* Use \`owns\` for private member containment (exactly one hop) and \`dependsOn\` for collaborators. Never use generic suffixes like "Manager", "Helper", or "Utils".`;
|
|
31446
32078
|
function globalGuideFilePath(targetType) {
|
|
31447
|
-
if (targetType === "claude") return
|
|
31448
|
-
if (targetType === "gemini") return
|
|
32079
|
+
if (targetType === "claude") return path33.join(process.env["CLAUDE_CONFIG_DIR"] || path33.join(os5.homedir(), ".claude"), "CLAUDE.md");
|
|
32080
|
+
if (targetType === "gemini") return path33.join(process.env["GEMINI_CONFIG_DIR"] || path33.join(os5.homedir(), ".gemini"), "GEMINI.md");
|
|
31449
32081
|
return null;
|
|
31450
32082
|
}
|
|
31451
32083
|
function localGuideFilePath(projectRoot, targetType) {
|
|
31452
|
-
if (targetType === "claude") return
|
|
31453
|
-
if (targetType === "gemini" || targetType === "agy") return
|
|
32084
|
+
if (targetType === "claude") return path33.join(projectRoot, ".claude", "CLAUDE.md");
|
|
32085
|
+
if (targetType === "gemini" || targetType === "agy") return path33.join(projectRoot, ".gemini", "GEMINI.md");
|
|
31454
32086
|
return null;
|
|
31455
32087
|
}
|
|
31456
32088
|
function injectGuide(filePath, scope) {
|
|
@@ -31465,7 +32097,7 @@ ${GUIDE_MARKER_END}
|
|
|
31465
32097
|
const existing = fs18.existsSync(filePath) ? fs18.readFileSync(filePath, "utf-8") : "";
|
|
31466
32098
|
const stripped = stripGuideSection(existing);
|
|
31467
32099
|
const newContent = stripped.trimEnd() + section;
|
|
31468
|
-
fs18.mkdirSync(
|
|
32100
|
+
fs18.mkdirSync(path33.dirname(filePath), { recursive: true });
|
|
31469
32101
|
fs18.writeFileSync(filePath, newContent, "utf-8");
|
|
31470
32102
|
}
|
|
31471
32103
|
function stripGuideSection(content) {
|
|
@@ -31476,7 +32108,7 @@ function stripGuideSection(content) {
|
|
|
31476
32108
|
}
|
|
31477
32109
|
function writeRootGuideDelegator(projectRoot, targetType) {
|
|
31478
32110
|
if (targetType === "claude") {
|
|
31479
|
-
const filePath =
|
|
32111
|
+
const filePath = path33.join(projectRoot, "CLAUDE.md");
|
|
31480
32112
|
const content = `@.claude/CLAUDE.md
|
|
31481
32113
|
|
|
31482
32114
|
# Wairon SDD Project
|
|
@@ -31491,7 +32123,7 @@ the \`wairon\` CLI is the human developer's tool, not yours.
|
|
|
31491
32123
|
`;
|
|
31492
32124
|
fs18.writeFileSync(filePath, content, "utf-8");
|
|
31493
32125
|
} else if (targetType === "gemini" || targetType === "agy") {
|
|
31494
|
-
const filePath =
|
|
32126
|
+
const filePath = path33.join(projectRoot, "GEMINI.md");
|
|
31495
32127
|
const content = `# Wairon SDD Project
|
|
31496
32128
|
${GUIDE_MARKER_START}
|
|
31497
32129
|
${versionStamp()}
|
|
@@ -31500,7 +32132,7 @@ ${GUIDE_MARKER_END}
|
|
|
31500
32132
|
`;
|
|
31501
32133
|
fs18.writeFileSync(filePath, content, "utf-8");
|
|
31502
32134
|
} else if (targetType === "cursor") {
|
|
31503
|
-
const filePath =
|
|
32135
|
+
const filePath = path33.join(projectRoot, ".cursorrules");
|
|
31504
32136
|
const content = `# Wairon SDD Project
|
|
31505
32137
|
|
|
31506
32138
|
This project uses the Wairon Spec-Driven Development (SDD) framework.
|
|
@@ -31509,8 +32141,8 @@ Refer to the rules in [.cursor/rules/](.cursor/rules/) for full instructions.
|
|
|
31509
32141
|
`;
|
|
31510
32142
|
fs18.writeFileSync(filePath, content, "utf-8");
|
|
31511
32143
|
} else if (targetType === "copilot") {
|
|
31512
|
-
const filePath =
|
|
31513
|
-
fs18.mkdirSync(
|
|
32144
|
+
const filePath = path33.join(projectRoot, ".github", "copilot-instructions.md");
|
|
32145
|
+
fs18.mkdirSync(path33.dirname(filePath), { recursive: true });
|
|
31514
32146
|
const content = `# Wairon SDD Project
|
|
31515
32147
|
|
|
31516
32148
|
This project uses the Wairon Spec-Driven Development (SDD) framework.
|
|
@@ -31519,7 +32151,7 @@ Refer to the prompts in [.github/prompts/](.github/prompts/) for instructions.
|
|
|
31519
32151
|
`;
|
|
31520
32152
|
fs18.writeFileSync(filePath, content, "utf-8");
|
|
31521
32153
|
} else if (targetType === "codex") {
|
|
31522
|
-
const filePath =
|
|
32154
|
+
const filePath = path33.join(projectRoot, ".codexrules");
|
|
31523
32155
|
const content = `# Wairon SDD Project
|
|
31524
32156
|
|
|
31525
32157
|
Refer to [.codex/agents/](.codex/agents/) for full instructions.
|
|
@@ -31676,14 +32308,14 @@ function syncContextFiles() {
|
|
|
31676
32308
|
}
|
|
31677
32309
|
|
|
31678
32310
|
// src/core/status.ts
|
|
31679
|
-
var
|
|
31680
|
-
var asWritten = (
|
|
32311
|
+
var path34 = __toESM(require("path"));
|
|
32312
|
+
var asWritten = (text3) => text3;
|
|
31681
32313
|
function fillDecor(decor) {
|
|
31682
32314
|
return {
|
|
31683
32315
|
structure: decor?.structure ?? asWritten,
|
|
31684
32316
|
emphasis: decor?.emphasis ?? asWritten,
|
|
31685
|
-
layer: decor?.layer ?? ((_kind,
|
|
31686
|
-
score: decor?.score ?? ((_pct,
|
|
32317
|
+
layer: decor?.layer ?? ((_kind, text3) => text3),
|
|
32318
|
+
score: decor?.score ?? ((_pct, text3) => text3),
|
|
31687
32319
|
draft: decor?.draft ?? asWritten,
|
|
31688
32320
|
present: decor?.present ?? asWritten,
|
|
31689
32321
|
missing: decor?.missing ?? asWritten
|
|
@@ -31765,7 +32397,7 @@ function getStatusReport(options = {}, decor) {
|
|
|
31765
32397
|
const sourceExists = (specId, file) => {
|
|
31766
32398
|
const owner = ownerOf3(specId);
|
|
31767
32399
|
const dir = owner === "" ? void 0 : family.nodes.find((n) => n.namespace === owner)?.directory;
|
|
31768
|
-
return pathExists(dir ?
|
|
32400
|
+
return pathExists(dir ? path34.resolve(dir, file) : fromProjectRoot(file));
|
|
31769
32401
|
};
|
|
31770
32402
|
const holdsShown = (ns) => subsystems.some((s) => ownerOf3(s.id) === ns) || family.nodes.some((n) => n.parent === ns && n.namespace !== ns && holdsShown(n.namespace));
|
|
31771
32403
|
const renderSubsystem = (sub, label2, indent, isLastSub) => {
|
|
@@ -31929,7 +32561,7 @@ var logger = {
|
|
|
31929
32561
|
};
|
|
31930
32562
|
|
|
31931
32563
|
// src/core/skills.ts
|
|
31932
|
-
var
|
|
32564
|
+
var path35 = __toESM(require("path"));
|
|
31933
32565
|
var fs19 = __toESM(require("fs"));
|
|
31934
32566
|
|
|
31935
32567
|
// src/core/instructions.ts
|
|
@@ -32085,10 +32717,10 @@ function readFrontmatter(raw, fallbackName) {
|
|
|
32085
32717
|
return { name: field("name") || fallbackName, description: field("description") };
|
|
32086
32718
|
}
|
|
32087
32719
|
function builtinSkillsDir() {
|
|
32088
|
-
return
|
|
32720
|
+
return path35.resolve(__dirname, "..", "templates", "skills");
|
|
32089
32721
|
}
|
|
32090
32722
|
function skillTemplatePath(name) {
|
|
32091
|
-
return
|
|
32723
|
+
return path35.join(builtinSkillsDir(), `${name}.md`);
|
|
32092
32724
|
}
|
|
32093
32725
|
function activeTargetTypes2() {
|
|
32094
32726
|
const config = loadProjectConfig();
|
|
@@ -32156,7 +32788,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
32156
32788
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
32157
32789
|
var import_zod11 = require("zod");
|
|
32158
32790
|
var import_types4 = require("@modelcontextprotocol/sdk/types.js");
|
|
32159
|
-
var
|
|
32791
|
+
var path37 = __toESM(require("path"));
|
|
32160
32792
|
var crypto5 = __toESM(require("crypto"));
|
|
32161
32793
|
|
|
32162
32794
|
// src/core/adapters/authoring-core.ts
|
|
@@ -32551,7 +33183,7 @@ function moveMethods2(from, to, methods, dryRun) {
|
|
|
32551
33183
|
|
|
32552
33184
|
// src/mcp/build.ts
|
|
32553
33185
|
var fs20 = __toESM(require("fs"));
|
|
32554
|
-
var
|
|
33186
|
+
var path36 = __toESM(require("path"));
|
|
32555
33187
|
var import_child_process2 = require("child_process");
|
|
32556
33188
|
function captureBuildStamp(entryPath) {
|
|
32557
33189
|
try {
|
|
@@ -32595,21 +33227,21 @@ function readBuildFingerprint(stamp) {
|
|
|
32595
33227
|
return printed;
|
|
32596
33228
|
}
|
|
32597
33229
|
function fingerprintModuleFor(entryPath) {
|
|
32598
|
-
let dir =
|
|
33230
|
+
let dir = path36.dirname(entryPath);
|
|
32599
33231
|
for (; ; ) {
|
|
32600
|
-
const manifest =
|
|
33232
|
+
const manifest = path36.join(dir, "package.json");
|
|
32601
33233
|
if (fs20.existsSync(manifest)) {
|
|
32602
33234
|
try {
|
|
32603
33235
|
const pkg = JSON.parse(fs20.readFileSync(manifest, "utf8"));
|
|
32604
|
-
const inDist =
|
|
32605
|
-
if (pkg.name === "@wairon/cli" && pkg.main && !inDist.startsWith("..") && !
|
|
32606
|
-
return
|
|
33236
|
+
const inDist = path36.relative(path36.join(dir, "dist"), entryPath);
|
|
33237
|
+
if (pkg.name === "@wairon/cli" && pkg.main && !inDist.startsWith("..") && !path36.isAbsolute(inDist)) {
|
|
33238
|
+
return path36.resolve(dir, pkg.main);
|
|
32607
33239
|
}
|
|
32608
33240
|
} catch {
|
|
32609
33241
|
}
|
|
32610
33242
|
return entryPath;
|
|
32611
33243
|
}
|
|
32612
|
-
const parent =
|
|
33244
|
+
const parent = path36.dirname(dir);
|
|
32613
33245
|
if (parent === dir) return entryPath;
|
|
32614
33246
|
dir = parent;
|
|
32615
33247
|
}
|
|
@@ -32635,7 +33267,7 @@ function statusFamilyContext() {
|
|
|
32635
33267
|
const members = listDirectChainedSubprojects(root);
|
|
32636
33268
|
if (members.length > 0) {
|
|
32637
33269
|
const described = members.map((m) => {
|
|
32638
|
-
const rel2 =
|
|
33270
|
+
const rel2 = path37.relative(root, m.dir).split(path37.sep).join("/") || ".";
|
|
32639
33271
|
return `${m.alias} (${rel2}${m.form === "mount" ? ", legacy L1 mount" : ""})`;
|
|
32640
33272
|
});
|
|
32641
33273
|
lines.push(`Family: member projects declared here \u2014 ${described.join(", ")}.`);
|
|
@@ -32660,7 +33292,7 @@ function qualifiedComponentId(id) {
|
|
|
32660
33292
|
return chained.length === 1 ? chained[0] : id;
|
|
32661
33293
|
}
|
|
32662
33294
|
function publicInterfacesReplacement(subsystem, stored, list) {
|
|
32663
|
-
const
|
|
33295
|
+
const identity2 = (pi) => {
|
|
32664
33296
|
if (pi.from || pi.typeDef) {
|
|
32665
33297
|
const item = pi.typeDef ? `type ${pi.typeDef}` : pi.component ?? "*";
|
|
32666
33298
|
return `${pi.from ? `${pi.from}:` : ""}${item}${pi.interface ? `.${pi.interface}` : ""}${pi.as ? ` as ${pi.as}` : ""}`;
|
|
@@ -32668,7 +33300,7 @@ function publicInterfacesReplacement(subsystem, stored, list) {
|
|
|
32668
33300
|
return pi.component ? `${pi.component}${pi.interface ? `.${pi.interface}` : ""}` : `${pi.type} ${pi.details}`;
|
|
32669
33301
|
};
|
|
32670
33302
|
const restated = /* @__PURE__ */ new Map();
|
|
32671
|
-
for (const pi of list) restated.set(
|
|
33303
|
+
for (const pi of list) restated.set(identity2(pi), (restated.get(identity2(pi)) ?? 0) + 1);
|
|
32672
33304
|
const twice = [...restated].filter(([, n]) => n > 1).map(([key]) => `"${key}"`);
|
|
32673
33305
|
if (twice.length) {
|
|
32674
33306
|
return `Refusing to set the public interfaces of subsystem "${subsystem}": the list names ${twice.join(", ")} more than once. An entry is identified by the component and interface it is bound to \u2014 or, not yet bound, by its type and details \u2014 so two entries sharing one are the same entry stated twice. Drop the duplicate. Nothing was written.`;
|
|
@@ -32676,24 +33308,24 @@ function publicInterfacesReplacement(subsystem, stored, list) {
|
|
|
32676
33308
|
const seen = /* @__PURE__ */ new Map();
|
|
32677
33309
|
const deletes = [];
|
|
32678
33310
|
for (const pi of stored) {
|
|
32679
|
-
const key =
|
|
33311
|
+
const key = identity2(pi);
|
|
32680
33312
|
seen.set(key, (seen.get(key) ?? 0) + 1);
|
|
32681
33313
|
if (seen.get(key) > (restated.get(key) ?? 0)) {
|
|
32682
33314
|
deletes.push(pi.from || pi.typeDef ? { from: pi.from, component: pi.component, interface: pi.interface, typeDef: pi.typeDef, as: pi.as, action: "delete" } : pi.component ? { component: pi.component, interface: pi.interface, action: "delete" } : { type: pi.type, details: pi.details, action: "delete" });
|
|
32683
33315
|
}
|
|
32684
33316
|
}
|
|
32685
33317
|
const restatedEntries = list.map((pi) => {
|
|
32686
|
-
const prev = stored.find((s) =>
|
|
33318
|
+
const prev = stored.find((s) => identity2(s) === identity2(pi));
|
|
32687
33319
|
const dropped = prev ? Object.keys(prev).filter((f) => prev[f] !== void 0 && pi[f] === void 0) : [];
|
|
32688
33320
|
return dropped.length ? { ...pi, unset: dropped } : pi;
|
|
32689
33321
|
});
|
|
32690
33322
|
return { publicInterfaces: [...deletes, ...restatedEntries] };
|
|
32691
33323
|
}
|
|
32692
|
-
function
|
|
33324
|
+
function text2(content) {
|
|
32693
33325
|
return { content: [{ type: "text", text: content }] };
|
|
32694
33326
|
}
|
|
32695
33327
|
function json(value) {
|
|
32696
|
-
return
|
|
33328
|
+
return text2(JSON.stringify(value, null, 2));
|
|
32697
33329
|
}
|
|
32698
33330
|
function errText(message) {
|
|
32699
33331
|
return { content: [{ type: "text", text: `Error: ${message.replace(/^(?:\s*Error:\s*)+/, "")}` }], isError: true };
|
|
@@ -32869,6 +33501,90 @@ var validationIssueOutput = {
|
|
|
32869
33501
|
"In a family run: the key of the project whose gate the finding belongs to ('' for the family root)."
|
|
32870
33502
|
)
|
|
32871
33503
|
};
|
|
33504
|
+
var memberCreationOutput = {
|
|
33505
|
+
configCreated: import_zod11.z.boolean().describe("Whether this call created the member's configuration; only then were the declaring project's required packs scaffolded."),
|
|
33506
|
+
adopted: import_zod11.z.array(import_zod11.z.object({
|
|
33507
|
+
name: import_zod11.z.string(),
|
|
33508
|
+
version: import_zod11.z.string().optional(),
|
|
33509
|
+
integrity: import_zod11.z.string().optional(),
|
|
33510
|
+
source: import_zod11.z.string().optional(),
|
|
33511
|
+
bundle: import_zod11.z.boolean().optional()
|
|
33512
|
+
})).describe("The selections written into the new member's extensions.packs, each pinned to the highest installed version its requirement admits."),
|
|
33513
|
+
unadopted: import_zod11.z.array(import_zod11.z.object({
|
|
33514
|
+
pack: import_zod11.z.string(),
|
|
33515
|
+
version: import_zod11.z.string(),
|
|
33516
|
+
profile: import_zod11.z.string().optional()
|
|
33517
|
+
})).describe("Requirements no installed version satisfies: nothing was written for them, and the next family run reports each as POLICY_NOT_ADOPTED."),
|
|
33518
|
+
projectType: import_zod11.z.string().optional().describe("The profile written as the new member's projectType, when exactly one adopted requirement names one."),
|
|
33519
|
+
...staleServerOutput
|
|
33520
|
+
};
|
|
33521
|
+
function describeMemberPacks(creation) {
|
|
33522
|
+
if (!creation.configCreated) return "";
|
|
33523
|
+
const parts = [];
|
|
33524
|
+
if (creation.adopted.length > 0) {
|
|
33525
|
+
parts.push(` Applied the required pack(s) ${creation.adopted.map((s) => `${s.name}@${s.version}`).join(", ")} to its new configuration (an unattended write: no impact report was shown).`);
|
|
33526
|
+
}
|
|
33527
|
+
if (creation.projectType) parts.push(` Set its projectType to "${creation.projectType}".`);
|
|
33528
|
+
if (creation.unadopted.length > 0) {
|
|
33529
|
+
parts.push(` No installed version satisfies ${creation.unadopted.map((r) => `"${r.pack}" ${r.version}`).join(", ")}: nothing was written for ${creation.unadopted.length === 1 ? "it" : "them"}, and the family run reports POLICY_NOT_ADOPTED until the member selects ${creation.unadopted.length === 1 ? "it" : "them"} (\`wairon pack install <source>\`, then \`wairon pack use <name>@<version> --pin\` at the member's root).`);
|
|
33530
|
+
}
|
|
33531
|
+
return parts.join("");
|
|
33532
|
+
}
|
|
33533
|
+
var doctrineChangeOutput = import_zod11.z.object({
|
|
33534
|
+
axis: import_zod11.z.enum(["rule", "concept"]),
|
|
33535
|
+
change: import_zod11.z.string().describe("loosened | raised | off | added | depth | inert | redefined | removed | discouraged | licensed | gated \u2014 stated, never judged."),
|
|
33536
|
+
subject: import_zod11.z.string(),
|
|
33537
|
+
profile: import_zod11.z.string().optional(),
|
|
33538
|
+
from: import_zod11.z.string().optional(),
|
|
33539
|
+
to: import_zod11.z.string().optional(),
|
|
33540
|
+
reason: import_zod11.z.string().optional()
|
|
33541
|
+
});
|
|
33542
|
+
var impactTotalsOutput = import_zod11.z.object({
|
|
33543
|
+
key: import_zod11.z.string(),
|
|
33544
|
+
id: import_zod11.z.string().optional(),
|
|
33545
|
+
directory: import_zod11.z.string(),
|
|
33546
|
+
valid: import_zod11.z.boolean(),
|
|
33547
|
+
errors: import_zod11.z.number(),
|
|
33548
|
+
warnings: import_zod11.z.number(),
|
|
33549
|
+
notices: import_zod11.z.number()
|
|
33550
|
+
});
|
|
33551
|
+
var packImpactOutput = {
|
|
33552
|
+
pack: import_zod11.z.string().describe("The pack measured."),
|
|
33553
|
+
version: import_zod11.z.string().optional().describe("The version the candidate resolves to; absent for an unversioned pack."),
|
|
33554
|
+
replaces: import_zod11.z.string().optional().describe("The version applied now under the same name, when the selection would replace it."),
|
|
33555
|
+
direction: import_zod11.z.enum(["apply", "remove"]).describe("remove when the pack is already applied exactly as asked: the findings then read as what the pack accounts for now."),
|
|
33556
|
+
doctrine: import_zod11.z.array(doctrineChangeOutput).describe("The pack's changes against wairon's defaults. Nothing in it is a finding."),
|
|
33557
|
+
previousDoctrine: import_zod11.z.array(doctrineChangeOutput).optional().describe("On an update: the replaced version's changes against the same defaults."),
|
|
33558
|
+
governing: import_zod11.z.array(import_zod11.z.string()).describe("The pack's profiles that would govern something in this project."),
|
|
33559
|
+
findings: import_zod11.z.object({
|
|
33560
|
+
introduced: import_zod11.z.array(import_zod11.z.object(validationIssueOutput)),
|
|
33561
|
+
resolved: import_zod11.z.array(import_zod11.z.object(validationIssueOutput)),
|
|
33562
|
+
regraded: import_zod11.z.array(import_zod11.z.object({ finding: import_zod11.z.object(validationIssueOutput), from: import_zod11.z.string() }))
|
|
33563
|
+
}).describe("The owner's-gate findings that differ between the current and the candidate configuration."),
|
|
33564
|
+
before: impactTotalsOutput.describe("The current configuration's totals."),
|
|
33565
|
+
after: impactTotalsOutput.describe("The candidate configuration's totals."),
|
|
33566
|
+
...staleServerOutput
|
|
33567
|
+
};
|
|
33568
|
+
function renderPackImpact(impact) {
|
|
33569
|
+
const lines = [];
|
|
33570
|
+
const removal = impact.direction === "remove";
|
|
33571
|
+
lines.push(`Pack impact: ${impact.pack}${impact.version ? ` v${impact.version}` : ""}${impact.replaces ? ` (replaces v${impact.replaces})` : ""} \u2014 ${removal ? "already applied exactly as asked; measured as removed, so the findings are what the pack accounts for now" : "measured as applied"}. Nothing was written.`);
|
|
33572
|
+
lines.push("", "Doctrine against wairon's defaults (stated, never judged):");
|
|
33573
|
+
if (impact.doctrine.length === 0) lines.push(" (no changes)");
|
|
33574
|
+
for (const c of impact.doctrine) {
|
|
33575
|
+
const range = c.from !== void 0 || c.to !== void 0 ? ` (${c.from ?? "-"} -> ${c.to ?? "-"})` : "";
|
|
33576
|
+
lines.push(` ${c.profile ? `[${c.profile}] ` : ""}${c.axis} ${c.change}: ${c.subject}${range}${c.reason ? ` \u2014 ${c.reason}` : ""}`);
|
|
33577
|
+
}
|
|
33578
|
+
lines.push("", `Governing here: ${impact.governing.length > 0 ? impact.governing.join(", ") : "none of its profiles"}`);
|
|
33579
|
+
const f = impact.findings;
|
|
33580
|
+
lines.push("", `Findings: ${f.introduced.length} introduced, ${f.resolved.length} resolved, ${f.regraded.length} regraded.`);
|
|
33581
|
+
for (const i of f.introduced) lines.push(` + [${i.severity}] ${i.code}${i.specId ? ` (${i.specId})` : ""}: ${i.message}`);
|
|
33582
|
+
for (const i of f.resolved) lines.push(` - [${i.severity}] ${i.code}${i.specId ? ` (${i.specId})` : ""}: ${i.message}`);
|
|
33583
|
+
for (const r of f.regraded) lines.push(` ~ [${r.from} -> ${r.finding.severity}] ${r.finding.code}${r.finding.specId ? ` (${r.finding.specId})` : ""}`);
|
|
33584
|
+
const totals2 = (v) => `${v.errors} error(s), ${v.warnings} warning(s), ${v.notices} notice(s)`;
|
|
33585
|
+
lines.push("", `Before: ${totals2(impact.before)}. After: ${totals2(impact.after)}.`);
|
|
33586
|
+
return lines.join(String.fromCharCode(10));
|
|
33587
|
+
}
|
|
32872
33588
|
var validateTreeOutput = {
|
|
32873
33589
|
valid: import_zod11.z.boolean().describe("False when the tree holds at least one error; warnings and notices never make it false."),
|
|
32874
33590
|
errors: import_zod11.z.array(import_zod11.z.object(validationIssueOutput)).describe("Every finding of severity error."),
|
|
@@ -33451,22 +34167,53 @@ ${renderChangeReport(report)}`,
|
|
|
33451
34167
|
server,
|
|
33452
34168
|
"sdd_add_member",
|
|
33453
34169
|
{
|
|
33454
|
-
description: "Create a member of the bound project: scaffold the member project at the path (its project.yaml declaring the alias as its project id, and its L0), each part only when absent, and declare it in the bound project's project.yaml `members` with the description. Nothing is written into the bound project's spec tree: a member is reached only as `alias::name` through its own L0 exports. Idempotent \u2014 the same call again writes nothing; a different member under the alias is refused.",
|
|
34170
|
+
description: "Create a member of the bound project: scaffold the member project at the path (its project.yaml declaring the alias as its project id, and its L0), each part only when absent, and declare it in the bound project's project.yaml `members` with the description. A newly created member configuration also selects the bound project's required packs (composition.requirePolicies), once, each pinned to the highest installed version its range admits; the answer states what was applied and which requirements nothing installed satisfies. Nothing is written into the bound project's spec tree: a member is reached only as `alias::name` through its own L0 exports. Idempotent \u2014 the same call again writes nothing; a different member under the alias is refused.",
|
|
33455
34171
|
inputSchema: {
|
|
33456
34172
|
alias: import_zod11.z.string().describe("The member's alias and new project id ([a-z0-9-_]+)"),
|
|
33457
34173
|
path: import_zod11.z.string().describe("The member's root, relative to the bound project"),
|
|
33458
34174
|
description: import_zod11.z.string().optional().describe("What the member is to this project; also the vision of a bootstrapped L0")
|
|
33459
|
-
}
|
|
34175
|
+
},
|
|
34176
|
+
outputSchema: memberCreationOutput
|
|
33460
34177
|
},
|
|
33461
34178
|
({ alias, path: memberPath, description }) => {
|
|
33462
34179
|
try {
|
|
33463
|
-
createMember(alias, memberPath, description);
|
|
33464
|
-
return
|
|
34180
|
+
const creation = createMember(alias, memberPath, description);
|
|
34181
|
+
return structured(
|
|
34182
|
+
`Added member "${alias}" at ${memberPath} (declared in project.yaml \`members\`).${describeMemberPacks(creation)} Design it from its own root and export what others consume from its L0; reference it here as ${alias}::<name>.`,
|
|
34183
|
+
creation
|
|
34184
|
+
);
|
|
33465
34185
|
} catch (e) {
|
|
33466
34186
|
return errText(String(e));
|
|
33467
34187
|
}
|
|
33468
34188
|
}
|
|
33469
34189
|
);
|
|
34190
|
+
if (!options.hostedTools) {
|
|
34191
|
+
reg(
|
|
34192
|
+
server,
|
|
34193
|
+
"sdd_pack_impact",
|
|
34194
|
+
{
|
|
34195
|
+
description: "What selecting (or updating to) an installed pack would change on the bound project, writing nothing \u2014 the pack's doctrine against wairon's defaults (rules loosened, raised, turned off or added; profiles, stereotype fencing, edge licenses, patterns, guarantees and language tables added, redefined or removed), which of its profiles would govern, and the findings that change here. A pack the project already applies exactly as asked is measured as removed, so the findings read as what it accounts for now. Nothing in it is a finding: packs exist to adjust wairon's checks, and a loosening is stated like any other change. Apply a pack with `wairon pack use`.",
|
|
34196
|
+
inputSchema: {
|
|
34197
|
+
pack: import_zod11.z.string().describe("The pack name"),
|
|
34198
|
+
version: import_zod11.z.string().optional().describe("An exact version; omitted, the latest installed")
|
|
34199
|
+
},
|
|
34200
|
+
outputSchema: packImpactOutput
|
|
34201
|
+
},
|
|
34202
|
+
({ pack, version }) => {
|
|
34203
|
+
try {
|
|
34204
|
+
const config = loadProjectConfig();
|
|
34205
|
+
if (!config) throw new ProjectNotInitializedError();
|
|
34206
|
+
const stored = (config.extensions?.packs ?? []).find((e) => typeof e !== "string" && e.name === pack);
|
|
34207
|
+
const exact = stored !== void 0 && typeof stored !== "string" && (stored.version ?? "") === (version ?? "");
|
|
34208
|
+
const candidate = exact ? { entry: stored, remove: true } : { entry: { name: pack, ...version ? { version } : {} } };
|
|
34209
|
+
const impact = measurePackImpact(candidate);
|
|
34210
|
+
return structured(renderPackImpact(impact), impact);
|
|
34211
|
+
} catch (e) {
|
|
34212
|
+
return errMessage(e);
|
|
34213
|
+
}
|
|
34214
|
+
}
|
|
34215
|
+
);
|
|
34216
|
+
}
|
|
33470
34217
|
reg(
|
|
33471
34218
|
server,
|
|
33472
34219
|
"sdd_move_member",
|
|
@@ -33480,7 +34227,7 @@ ${renderChangeReport(report)}`,
|
|
|
33480
34227
|
({ alias, newPath }) => {
|
|
33481
34228
|
try {
|
|
33482
34229
|
moveMember(alias, newPath);
|
|
33483
|
-
return
|
|
34230
|
+
return text2(`Moved member "${alias}" to: ${newPath}`);
|
|
33484
34231
|
} catch (e) {
|
|
33485
34232
|
return errText(String(e));
|
|
33486
34233
|
}
|
|
@@ -33499,7 +34246,7 @@ ${renderChangeReport(report)}`,
|
|
|
33499
34246
|
({ subsystem, path: memberPath }) => {
|
|
33500
34247
|
try {
|
|
33501
34248
|
externalizeSubsystem(subsystem, memberPath);
|
|
33502
|
-
return
|
|
34249
|
+
return text2(`Externalized subsystem "${subsystem}" into the member project at ${memberPath}. Move its source code there, run \`wairon doctor --fix\` for the exports either side now needs, and re-validate.`);
|
|
33503
34250
|
} catch (e) {
|
|
33504
34251
|
return errText(String(e));
|
|
33505
34252
|
}
|
|
@@ -33517,7 +34264,7 @@ ${renderChangeReport(report)}`,
|
|
|
33517
34264
|
({ alias }) => {
|
|
33518
34265
|
try {
|
|
33519
34266
|
internalizeMember(alias);
|
|
33520
|
-
return
|
|
34267
|
+
return text2(`Internalized member "${alias}" into this project (its .wai project removed).`);
|
|
33521
34268
|
} catch (e) {
|
|
33522
34269
|
return errText(String(e));
|
|
33523
34270
|
}
|
|
@@ -34044,7 +34791,7 @@ ${renderChangeReport(report)}`,
|
|
|
34044
34791
|
({ kind, id, methods }) => {
|
|
34045
34792
|
try {
|
|
34046
34793
|
let result = null;
|
|
34047
|
-
let
|
|
34794
|
+
let partial2 = null;
|
|
34048
34795
|
switch (kind) {
|
|
34049
34796
|
case "system":
|
|
34050
34797
|
result = loadSystemSpec();
|
|
@@ -34081,7 +34828,7 @@ ${renderChangeReport(report)}`,
|
|
|
34081
34828
|
);
|
|
34082
34829
|
}
|
|
34083
34830
|
const kept = declared.filter((m) => methods.includes(String(m?.name)));
|
|
34084
|
-
|
|
34831
|
+
partial2 = {
|
|
34085
34832
|
shown: kept.map((m) => String(m?.name)),
|
|
34086
34833
|
omitted: names.length - kept.length,
|
|
34087
34834
|
warning: `PARTIAL: ${names.length - kept.length} of this spec's ${names.length} methods are not in this answer. Never re-author from it \u2014 sdd_define_interface and sdd_write_narrative REPLACE the method list, so every method missing here would be removed from the spec.`
|
|
@@ -34091,14 +34838,14 @@ ${renderChangeReport(report)}`,
|
|
|
34091
34838
|
const guidance = kind === "component" ? resolveComponentVariantGuidance(result) : null;
|
|
34092
34839
|
const folded = {
|
|
34093
34840
|
...result,
|
|
34094
|
-
...
|
|
34841
|
+
...partial2 ? { partialResult: partial2 } : {},
|
|
34095
34842
|
...guidance ? { variantGuidance: guidance } : {}
|
|
34096
34843
|
};
|
|
34097
34844
|
return structured(JSON.stringify(folded, null, 2), {
|
|
34098
34845
|
kind,
|
|
34099
34846
|
id,
|
|
34100
34847
|
spec: result,
|
|
34101
|
-
...
|
|
34848
|
+
...partial2 ? { partialResult: partial2 } : {},
|
|
34102
34849
|
...guidance ? { variantGuidance: guidance } : {}
|
|
34103
34850
|
});
|
|
34104
34851
|
} catch (e) {
|
|
@@ -34169,7 +34916,7 @@ ${testsBlock}` : ""}`, deletion);
|
|
|
34169
34916
|
});
|
|
34170
34917
|
const family = statusFamilyContext();
|
|
34171
34918
|
const verdict = approvalVerdict();
|
|
34172
|
-
return
|
|
34919
|
+
return text2(`${family}${report.text}${verdict.text}`);
|
|
34173
34920
|
} catch (e) {
|
|
34174
34921
|
return errText(String(e));
|
|
34175
34922
|
}
|
|
@@ -34299,6 +35046,13 @@ function advertiseHostedTools(server, options) {
|
|
|
34299
35046
|
content: import_zod11.z.string().describe("The declarative pack YAML content")
|
|
34300
35047
|
}
|
|
34301
35048
|
}, hostedStub);
|
|
35049
|
+
reg(server, "sdd_host_pack_impact", {
|
|
35050
|
+
description: "Hosted project ops: measure, writing nothing, what installing a DECLARATIVE pack (content given) or adopting the server-global pack of that name (content omitted) would change on the BOUND project \u2014 the pack's doctrine against wairon's defaults (rules loosened, raised, turned off or added; profiles and concepts added, redefined or removed), which of its profiles would govern, and the findings that change. Show it to your human before sdd_host_pack_install, which applies without it. Nothing in it is a finding: packs exist to adjust wairon's checks. Requires project:read over the project.",
|
|
35051
|
+
inputSchema: {
|
|
35052
|
+
name: import_zod11.z.string().describe("Pack name (letters, digits, dot, underscore, hyphen); the server-global pack to adopt when content is omitted"),
|
|
35053
|
+
content: import_zod11.z.string().optional().describe("The declarative pack YAML an install would upload; omitted, the server-global pack an adoption would vendor")
|
|
35054
|
+
}
|
|
35055
|
+
}, hostedStub);
|
|
34302
35056
|
reg(server, "sdd_host_policy_evaluate", {
|
|
34303
35057
|
description: "Hosted project ops: evaluate the BOUND project's packs and profile selection against the instance pack policy \u2014 compliance without side effects (requires project:write over it).",
|
|
34304
35058
|
inputSchema: {}
|
|
@@ -34365,6 +35119,7 @@ function loadProjectConfig3() {
|
|
|
34365
35119
|
ComplexityRuleConfigSchema,
|
|
34366
35120
|
ComponentSpecSchema,
|
|
34367
35121
|
ComponentTypeSchema,
|
|
35122
|
+
CompositionConfigSchema,
|
|
34368
35123
|
ConfigValidationError,
|
|
34369
35124
|
ConformanceRuleConfigSchema,
|
|
34370
35125
|
ConformanceTierSchema,
|
|
@@ -34419,6 +35174,7 @@ function loadProjectConfig3() {
|
|
|
34419
35174
|
PROJECT_ID_RE,
|
|
34420
35175
|
PROJECT_KINDS,
|
|
34421
35176
|
PUBLIC_NAME_RE,
|
|
35177
|
+
PackRequirementSchema,
|
|
34422
35178
|
PackSelectionSchema,
|
|
34423
35179
|
ParallelBranchSchema,
|
|
34424
35180
|
PathsConfigSchema,
|
|
@@ -34474,6 +35230,7 @@ function loadProjectConfig3() {
|
|
|
34474
35230
|
WaironError,
|
|
34475
35231
|
activeTargetTypes,
|
|
34476
35232
|
addDomain,
|
|
35233
|
+
admits,
|
|
34477
35234
|
aiDir,
|
|
34478
35235
|
aiDirAt,
|
|
34479
35236
|
aiPathsAt,
|
|
@@ -34596,6 +35353,7 @@ function loadProjectConfig3() {
|
|
|
34596
35353
|
loadComponentSpecs,
|
|
34597
35354
|
loadExtensionPacks,
|
|
34598
35355
|
loadExtensions,
|
|
35356
|
+
loadExtensionsFor,
|
|
34599
35357
|
loadImplementationSpec,
|
|
34600
35358
|
loadImplementationSpecs,
|
|
34601
35359
|
loadInterfaceSpec,
|
|
@@ -34635,7 +35393,9 @@ function loadProjectConfig3() {
|
|
|
34635
35393
|
packDirEntry,
|
|
34636
35394
|
packEntryLabel,
|
|
34637
35395
|
packEntryRef,
|
|
35396
|
+
packManifest,
|
|
34638
35397
|
packStoreDir,
|
|
35398
|
+
parseDeclarativePack,
|
|
34639
35399
|
parseDeclaredCall,
|
|
34640
35400
|
parseYaml,
|
|
34641
35401
|
passesIntentFloor,
|
|
@@ -34648,6 +35408,7 @@ function loadProjectConfig3() {
|
|
|
34648
35408
|
projectIdentity,
|
|
34649
35409
|
provisionProject,
|
|
34650
35410
|
qualifiedTypeId,
|
|
35411
|
+
rangeProblem,
|
|
34651
35412
|
readFileOrNull,
|
|
34652
35413
|
readJsonFile,
|
|
34653
35414
|
readLockRecord,
|
|
@@ -34664,6 +35425,7 @@ function loadProjectConfig3() {
|
|
|
34664
35425
|
renameMethod,
|
|
34665
35426
|
renderDiagram,
|
|
34666
35427
|
repairForeignStepFields,
|
|
35428
|
+
requiredPolicies,
|
|
34667
35429
|
resolveAgentTopology,
|
|
34668
35430
|
resolveBudget,
|
|
34669
35431
|
resolveChainingParent,
|
|
@@ -34708,6 +35470,7 @@ function loadProjectConfig3() {
|
|
|
34708
35470
|
upsertPackSelection,
|
|
34709
35471
|
validateFamily,
|
|
34710
35472
|
validateProject,
|
|
35473
|
+
withPack,
|
|
34711
35474
|
writeFile,
|
|
34712
35475
|
writeFileIfChanged,
|
|
34713
35476
|
writeJsonFile,
|