@wairon/cli 5.0.2-dev.13 → 5.0.2-dev.15
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 +1239 -716
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +286 -76
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -148,7 +148,7 @@ var init_domain = __esm({
|
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
// src/models/project.ts
|
|
151
|
-
var import_zod3, BuiltinTargetConfigSchema, CustomTargetConfigSchema, TargetConfigSchema, NamingRuleConfigSchema, DocumentationRuleConfigSchema, ComplexityRuleConfigSchema, DesignDepthSchema, RulesConfigSchema, PathsConfigSchema, ProjectConfigSchema;
|
|
151
|
+
var import_zod3, BuiltinTargetConfigSchema, CustomTargetConfigSchema, TargetConfigSchema, NamingRuleConfigSchema, DocumentationRuleConfigSchema, ComplexityRuleConfigSchema, DesignDepthSchema, RulesConfigSchema, PathsConfigSchema, ProfileSelectionSubjectSchema, ProjectProfileSelectionSchema, ProjectConfigSchema;
|
|
152
152
|
var init_project = __esm({
|
|
153
153
|
"src/models/project.ts"() {
|
|
154
154
|
"use strict";
|
|
@@ -272,6 +272,24 @@ var init_project = __esm({
|
|
|
272
272
|
/** Base directory containing SDD specification files, relative to project root */
|
|
273
273
|
specsDir: import_zod3.z.string().default(".wai/specs")
|
|
274
274
|
});
|
|
275
|
+
ProfileSelectionSubjectSchema = import_zod3.z.object({
|
|
276
|
+
userId: import_zod3.z.string(),
|
|
277
|
+
kind: import_zod3.z.string(),
|
|
278
|
+
issuer: import_zod3.z.string(),
|
|
279
|
+
externalSubject: import_zod3.z.string().optional(),
|
|
280
|
+
displayName: import_zod3.z.string().optional(),
|
|
281
|
+
email: import_zod3.z.string().optional()
|
|
282
|
+
});
|
|
283
|
+
ProjectProfileSelectionSchema = import_zod3.z.object({
|
|
284
|
+
/** Selected architectural profile ids. The first resolvable one is applied as projectType. */
|
|
285
|
+
profileIds: import_zod3.z.array(import_zod3.z.string()).default([]),
|
|
286
|
+
/** Pack names the governing policy requires for this project. */
|
|
287
|
+
requiredPackNames: import_zod3.z.array(import_zod3.z.string()).default([]),
|
|
288
|
+
/** Pack names applied by default unless explicitly overridden. */
|
|
289
|
+
defaultPackNames: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
290
|
+
selectedBy: ProfileSelectionSubjectSchema.optional(),
|
|
291
|
+
selectedAt: import_zod3.z.string()
|
|
292
|
+
});
|
|
275
293
|
ProjectConfigSchema = import_zod3.z.object({
|
|
276
294
|
/**
|
|
277
295
|
* Schema version — used to detect incompatible config formats in future
|
|
@@ -312,6 +330,13 @@ var init_project = __esm({
|
|
|
312
330
|
useGlobalPacks: import_zod3.z.boolean().default(true)
|
|
313
331
|
}).optional(),
|
|
314
332
|
paths: PathsConfigSchema.default({}),
|
|
333
|
+
/**
|
|
334
|
+
* The profile/pack selection a hosted policy workflow applied to this project.
|
|
335
|
+
* The RECORD of what was chosen; `projectType` above is what actually governs
|
|
336
|
+
* validation. Modeled so the parse/write round trip preserves it (see
|
|
337
|
+
* ProjectProfileSelectionSchema).
|
|
338
|
+
*/
|
|
339
|
+
profileSelection: ProjectProfileSelectionSchema.optional(),
|
|
315
340
|
/**
|
|
316
341
|
* Path to a directory containing org/user-level default templates.
|
|
317
342
|
* Resolved before built-in templates but after project-local templates.
|
|
@@ -1260,6 +1285,47 @@ var init_errors = __esm({
|
|
|
1260
1285
|
}
|
|
1261
1286
|
});
|
|
1262
1287
|
|
|
1288
|
+
// src/core/statehash.ts
|
|
1289
|
+
function computeStateId() {
|
|
1290
|
+
const tree = {
|
|
1291
|
+
system: loadSystemSpec(),
|
|
1292
|
+
subsystems: loadSubsystemSpecs(),
|
|
1293
|
+
components: loadComponentSpecs(),
|
|
1294
|
+
interfaces: loadInterfaceSpecs(),
|
|
1295
|
+
implementations: loadImplementationSpecs(),
|
|
1296
|
+
types: loadTypeSpecs()
|
|
1297
|
+
};
|
|
1298
|
+
const digest = crypto.createHash("sha256").update(canonicalize(tree)).digest("hex");
|
|
1299
|
+
return { algorithm: "sha256", digest };
|
|
1300
|
+
}
|
|
1301
|
+
function stateIdEquals(a, b) {
|
|
1302
|
+
return !!a && !!b && a.algorithm === b.algorithm && a.digest === b.digest;
|
|
1303
|
+
}
|
|
1304
|
+
function canonicalize(value) {
|
|
1305
|
+
return JSON.stringify(sortKeys(value));
|
|
1306
|
+
}
|
|
1307
|
+
function sortKeys(v) {
|
|
1308
|
+
if (Array.isArray(v)) return v.map(sortKeys);
|
|
1309
|
+
if (v && typeof v === "object") {
|
|
1310
|
+
const src = v;
|
|
1311
|
+
const out = {};
|
|
1312
|
+
for (const k of Object.keys(src).sort()) {
|
|
1313
|
+
if (k === "createdAt" || k === "updatedAt") continue;
|
|
1314
|
+
out[k] = sortKeys(src[k]);
|
|
1315
|
+
}
|
|
1316
|
+
return out;
|
|
1317
|
+
}
|
|
1318
|
+
return v;
|
|
1319
|
+
}
|
|
1320
|
+
var crypto;
|
|
1321
|
+
var init_statehash = __esm({
|
|
1322
|
+
"src/core/statehash.ts"() {
|
|
1323
|
+
"use strict";
|
|
1324
|
+
crypto = __toESM(require("crypto"));
|
|
1325
|
+
init_specs2();
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
|
|
1263
1329
|
// src/core/narrative-labels.ts
|
|
1264
1330
|
function resolveNarrativeLabels(methodName, steps) {
|
|
1265
1331
|
const errors = [];
|
|
@@ -6621,7 +6687,7 @@ var init_extensions = __esm({
|
|
|
6621
6687
|
});
|
|
6622
6688
|
|
|
6623
6689
|
// src/core/rules/types.ts
|
|
6624
|
-
var BUILTIN_PROFILES;
|
|
6690
|
+
var BUILTIN_PROFILES, PROJECT_KINDS;
|
|
6625
6691
|
var init_types = __esm({
|
|
6626
6692
|
"src/core/rules/types.ts"() {
|
|
6627
6693
|
"use strict";
|
|
@@ -6634,6 +6700,7 @@ var init_types = __esm({
|
|
|
6634
6700
|
"realtime-embedded",
|
|
6635
6701
|
"plc-cyclic"
|
|
6636
6702
|
];
|
|
6703
|
+
PROJECT_KINDS = ["fullstack", "system-of-systems", "monorepo"];
|
|
6637
6704
|
}
|
|
6638
6705
|
});
|
|
6639
6706
|
|
|
@@ -6824,47 +6891,6 @@ var init_filenames = __esm({
|
|
|
6824
6891
|
}
|
|
6825
6892
|
});
|
|
6826
6893
|
|
|
6827
|
-
// src/core/statehash.ts
|
|
6828
|
-
function computeStateId() {
|
|
6829
|
-
const tree = {
|
|
6830
|
-
system: loadSystemSpec(),
|
|
6831
|
-
subsystems: loadSubsystemSpecs(),
|
|
6832
|
-
components: loadComponentSpecs(),
|
|
6833
|
-
interfaces: loadInterfaceSpecs(),
|
|
6834
|
-
implementations: loadImplementationSpecs(),
|
|
6835
|
-
types: loadTypeSpecs()
|
|
6836
|
-
};
|
|
6837
|
-
const digest = crypto.createHash("sha256").update(canonicalize(tree)).digest("hex");
|
|
6838
|
-
return { algorithm: "sha256", digest };
|
|
6839
|
-
}
|
|
6840
|
-
function stateIdEquals(a, b) {
|
|
6841
|
-
return !!a && !!b && a.algorithm === b.algorithm && a.digest === b.digest;
|
|
6842
|
-
}
|
|
6843
|
-
function canonicalize(value) {
|
|
6844
|
-
return JSON.stringify(sortKeys(value));
|
|
6845
|
-
}
|
|
6846
|
-
function sortKeys(v) {
|
|
6847
|
-
if (Array.isArray(v)) return v.map(sortKeys);
|
|
6848
|
-
if (v && typeof v === "object") {
|
|
6849
|
-
const src = v;
|
|
6850
|
-
const out = {};
|
|
6851
|
-
for (const k of Object.keys(src).sort()) {
|
|
6852
|
-
if (k === "createdAt" || k === "updatedAt") continue;
|
|
6853
|
-
out[k] = sortKeys(src[k]);
|
|
6854
|
-
}
|
|
6855
|
-
return out;
|
|
6856
|
-
}
|
|
6857
|
-
return v;
|
|
6858
|
-
}
|
|
6859
|
-
var crypto;
|
|
6860
|
-
var init_statehash = __esm({
|
|
6861
|
-
"src/core/statehash.ts"() {
|
|
6862
|
-
"use strict";
|
|
6863
|
-
crypto = __toESM(require("crypto"));
|
|
6864
|
-
init_specs2();
|
|
6865
|
-
}
|
|
6866
|
-
});
|
|
6867
|
-
|
|
6868
6894
|
// src/core/openapi.ts
|
|
6869
6895
|
function schemaFor(typeRef, closureIds) {
|
|
6870
6896
|
const trimmed = typeRef.trim().replace(/^promise\s*<(.+)>$/i, "$1").trim();
|
|
@@ -7322,6 +7348,57 @@ function projectOwnSurface(maxAudience) {
|
|
|
7322
7348
|
function projectChildSurface() {
|
|
7323
7349
|
return projectOwnSurface("project");
|
|
7324
7350
|
}
|
|
7351
|
+
function localName(id) {
|
|
7352
|
+
return id.split("::").pop();
|
|
7353
|
+
}
|
|
7354
|
+
function projectSubsystemSurface(subsystemId) {
|
|
7355
|
+
const system = loadSystemSpec();
|
|
7356
|
+
if (!system) {
|
|
7357
|
+
throw new Error("Cannot project a subsystem surface: the L0 system spec is missing.");
|
|
7358
|
+
}
|
|
7359
|
+
const subsystems = loadSubsystemSpecs();
|
|
7360
|
+
const target = subsystems.find((s) => s.id === subsystemId);
|
|
7361
|
+
if (!target) {
|
|
7362
|
+
throw new Error(`Cannot project a subsystem surface: subsystem "${subsystemId}" does not exist.`);
|
|
7363
|
+
}
|
|
7364
|
+
const components = loadComponentSpecs();
|
|
7365
|
+
const interfaces = loadInterfaceSpecs();
|
|
7366
|
+
const types = loadTypeSpecs();
|
|
7367
|
+
const entries = [];
|
|
7368
|
+
for (const pub of target.publicInterfaces ?? []) {
|
|
7369
|
+
if (!pub.component) continue;
|
|
7370
|
+
const comp = components.find((c) => c.id === pub.component || c.id === `${subsystemId}::${pub.component}`);
|
|
7371
|
+
if (!comp) continue;
|
|
7372
|
+
if (comp.componentType !== "Portal") continue;
|
|
7373
|
+
const compInterfaces = interfaces.filter((i) => i.component === comp.id && (!pub.interface || i.id === pub.interface || i.id === `${subsystemId}::${pub.interface}`));
|
|
7374
|
+
const methods = compInterfaces.flatMap((i) => i.methods);
|
|
7375
|
+
entries.push({
|
|
7376
|
+
id: localName(pub.interface ?? comp.id),
|
|
7377
|
+
name: comp.name,
|
|
7378
|
+
// Family ceiling: a sibling surface is consumable by the system family only.
|
|
7379
|
+
audience: "project",
|
|
7380
|
+
type: pub.type ?? "Custom",
|
|
7381
|
+
// The snapshot carries the LOCAL portal name — consumers resolve cross-tree
|
|
7382
|
+
// refs by their final segment.
|
|
7383
|
+
component: localName(comp.id),
|
|
7384
|
+
methods,
|
|
7385
|
+
...comp.dispatch && comp.dispatch.length ? { dispatch: comp.dispatch } : {},
|
|
7386
|
+
// Project the backing Portal's auth + basePath so the codec can emit
|
|
7387
|
+
// OpenAPI security + per-portal servers self-contained from the snapshot.
|
|
7388
|
+
...comp.auth && comp.auth.scheme !== "none" ? { auth: comp.auth } : {},
|
|
7389
|
+
...comp.basePath ? { basePath: comp.basePath } : {},
|
|
7390
|
+
details: pub.details ?? ""
|
|
7391
|
+
});
|
|
7392
|
+
}
|
|
7393
|
+
return SurfaceSnapshotSchema.parse({
|
|
7394
|
+
projectName: `${system.name}::${subsystemId}`,
|
|
7395
|
+
origin: "generated",
|
|
7396
|
+
stateId: stateIdString(),
|
|
7397
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7398
|
+
interfaces: entries,
|
|
7399
|
+
types: computeTypeClosure(entries, types)
|
|
7400
|
+
});
|
|
7401
|
+
}
|
|
7325
7402
|
function listSnapshots(rootDir = getProjectRoot()) {
|
|
7326
7403
|
const dir = surfacesDir(rootDir);
|
|
7327
7404
|
if (!fs4.existsSync(dir)) return [];
|
|
@@ -7338,18 +7415,37 @@ function listSnapshots(rootDir = getProjectRoot()) {
|
|
|
7338
7415
|
function getSnapshot(projectName, rootDir = getProjectRoot()) {
|
|
7339
7416
|
return listSnapshots(rootDir).find((s) => s.projectName === projectName) ?? null;
|
|
7340
7417
|
}
|
|
7418
|
+
function snapshotFilename(projectName) {
|
|
7419
|
+
return `${safeFilenamePart(projectName)}.yaml`;
|
|
7420
|
+
}
|
|
7341
7421
|
function saveSnapshot(snapshot, rootDir = getProjectRoot()) {
|
|
7342
7422
|
const dir = surfacesDir(rootDir);
|
|
7343
7423
|
fs4.mkdirSync(dir, { recursive: true });
|
|
7344
|
-
const p = path5.join(dir,
|
|
7424
|
+
const p = path5.join(dir, snapshotFilename(snapshot.projectName));
|
|
7345
7425
|
writeYamlFile(p, SurfaceSnapshotSchema.parse(snapshot));
|
|
7346
7426
|
return p;
|
|
7347
7427
|
}
|
|
7348
7428
|
function removeSnapshot(projectName, rootDir = getProjectRoot()) {
|
|
7349
|
-
const
|
|
7350
|
-
|
|
7351
|
-
fs4.
|
|
7352
|
-
|
|
7429
|
+
const dir = surfacesDir(rootDir);
|
|
7430
|
+
const direct = path5.join(dir, snapshotFilename(projectName));
|
|
7431
|
+
if (fs4.existsSync(direct)) {
|
|
7432
|
+
fs4.unlinkSync(direct);
|
|
7433
|
+
return true;
|
|
7434
|
+
}
|
|
7435
|
+
if (!fs4.existsSync(dir)) return false;
|
|
7436
|
+
for (const file of fs4.readdirSync(dir)) {
|
|
7437
|
+
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
7438
|
+
const p = path5.join(dir, file);
|
|
7439
|
+
try {
|
|
7440
|
+
const snap = SurfaceSnapshotSchema.parse(readYamlFile(p));
|
|
7441
|
+
if (snap.projectName === projectName) {
|
|
7442
|
+
fs4.unlinkSync(p);
|
|
7443
|
+
return true;
|
|
7444
|
+
}
|
|
7445
|
+
} catch {
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
return false;
|
|
7353
7449
|
}
|
|
7354
7450
|
function loadSurfaceSnapshots() {
|
|
7355
7451
|
return listSnapshots();
|
|
@@ -7420,17 +7516,54 @@ function importSurface(sourcePath, origin) {
|
|
|
7420
7516
|
return snapshot;
|
|
7421
7517
|
}
|
|
7422
7518
|
function generateChildSnapshots(rootDir = getProjectRoot()) {
|
|
7423
|
-
const
|
|
7519
|
+
const topLevel = loadSubsystemSpecs().filter((s) => !s.id.includes("::"));
|
|
7520
|
+
const children = topLevel.filter((s) => s.projectPath);
|
|
7424
7521
|
if (!children.length) return [];
|
|
7425
|
-
const
|
|
7522
|
+
const familySnapshot = projectChildSurface();
|
|
7523
|
+
const siblingSnapshots = /* @__PURE__ */ new Map();
|
|
7524
|
+
const siblingSurface = (subsystemId) => {
|
|
7525
|
+
let snap = siblingSnapshots.get(subsystemId);
|
|
7526
|
+
if (!snap) {
|
|
7527
|
+
snap = projectSubsystemSurface(subsystemId);
|
|
7528
|
+
siblingSnapshots.set(subsystemId, snap);
|
|
7529
|
+
}
|
|
7530
|
+
return snap;
|
|
7531
|
+
};
|
|
7426
7532
|
const written = [];
|
|
7427
7533
|
for (const child of children) {
|
|
7428
7534
|
const childDir = path5.resolve(rootDir, child.projectPath);
|
|
7429
7535
|
if (!fs4.existsSync(childDir)) continue;
|
|
7430
|
-
written.push(saveSnapshot(
|
|
7536
|
+
written.push(saveSnapshot(familySnapshot, childDir));
|
|
7537
|
+
for (const sibling of topLevel) {
|
|
7538
|
+
if (sibling.id === child.id) continue;
|
|
7539
|
+
written.push(saveSnapshot(siblingSurface(sibling.id), childDir));
|
|
7540
|
+
}
|
|
7431
7541
|
}
|
|
7432
7542
|
return written;
|
|
7433
7543
|
}
|
|
7544
|
+
function computeParentStateId(parentRoot) {
|
|
7545
|
+
return computeStateIdAt(parentRoot);
|
|
7546
|
+
}
|
|
7547
|
+
function listExternalInterfaces() {
|
|
7548
|
+
const snapshots = listSnapshots();
|
|
7549
|
+
const chainingParent = resolveChainingParent();
|
|
7550
|
+
const parentStateId = chainingParent ? computeParentStateId(chainingParent.parentRoot) : null;
|
|
7551
|
+
return snapshots.map((snapshot) => {
|
|
7552
|
+
const generated = snapshot.origin === "generated";
|
|
7553
|
+
const sourceKind = !generated ? "foreign" : snapshot.projectName.includes("::") ? "sibling" : "parent";
|
|
7554
|
+
const freshness = generated && parentStateId ? snapshot.stateId === parentStateId ? "fresh" : "stale" : "unverifiable";
|
|
7555
|
+
return {
|
|
7556
|
+
projectName: snapshot.projectName,
|
|
7557
|
+
origin: snapshot.origin,
|
|
7558
|
+
sourceKind,
|
|
7559
|
+
generatedAt: snapshot.generatedAt,
|
|
7560
|
+
...snapshot.stateId ? { stateId: snapshot.stateId } : {},
|
|
7561
|
+
...snapshot.version ? { version: snapshot.version } : {},
|
|
7562
|
+
freshness,
|
|
7563
|
+
interfaceIds: snapshot.interfaces.map((e) => e.id)
|
|
7564
|
+
};
|
|
7565
|
+
});
|
|
7566
|
+
}
|
|
7434
7567
|
function surfaceContentKey(snapshot) {
|
|
7435
7568
|
const { stateId, generatedAt, origin, ...content } = snapshot;
|
|
7436
7569
|
return JSON.stringify(content);
|
|
@@ -7639,7 +7772,8 @@ var init_contracts = __esm({
|
|
|
7639
7772
|
"SURFACE_REF_NOT_EXPOSED",
|
|
7640
7773
|
`Method "${implMethod.name}" in implementation "${impl.id}" dispatches capability "${step.capability}" through cross-tree portal "${step.targetComponent}" (step ${step.stepNumber}), but the surface snapshot of "${resolved.snapshot.projectName}" does not serve that capability on "${resolved.entry.id}".`,
|
|
7641
7774
|
impl.id,
|
|
7642
|
-
isDraftCtx
|
|
7775
|
+
isDraftCtx,
|
|
7776
|
+
true
|
|
7643
7777
|
);
|
|
7644
7778
|
}
|
|
7645
7779
|
continue;
|
|
@@ -7696,7 +7830,8 @@ var init_contracts = __esm({
|
|
|
7696
7830
|
"SURFACE_REF_NOT_EXPOSED",
|
|
7697
7831
|
`Method "${implMethod.name}" in implementation "${impl.id}" calls "${step.targetMethod}" on cross-tree component "${step.targetComponent}" (step ${step.stepNumber}), but the surface snapshot of "${resolved.snapshot.projectName}" does not expose that method on "${resolved.entry.id}".`,
|
|
7698
7832
|
impl.id,
|
|
7699
|
-
isDraftCtx
|
|
7833
|
+
isDraftCtx,
|
|
7834
|
+
true
|
|
7700
7835
|
);
|
|
7701
7836
|
} else if (step.assertsGuarantees) {
|
|
7702
7837
|
const declared = new Set(surfaceMethod.guarantees ?? []);
|
|
@@ -7707,7 +7842,8 @@ var init_contracts = __esm({
|
|
|
7707
7842
|
"NARRATIVE_SEMANTIC_UNBACKED",
|
|
7708
7843
|
`Step ${step.stepNumber} of "${implMethod.name}" in implementation "${impl.id}" asserts guarantee "${g}", but the surface snapshot of "${resolved.snapshot.projectName}" does not declare it on "${resolved.entry.id}.${step.targetMethod}".`,
|
|
7709
7844
|
impl.id,
|
|
7710
|
-
isDraftCtx
|
|
7845
|
+
isDraftCtx,
|
|
7846
|
+
true
|
|
7711
7847
|
);
|
|
7712
7848
|
}
|
|
7713
7849
|
}
|
|
@@ -9195,7 +9331,8 @@ var init_stereotype_deps = __esm({
|
|
|
9195
9331
|
"CROSS_SUBSYSTEM_NON_ADAPTER",
|
|
9196
9332
|
`Boundary violation: ${comp.componentType} "${comp.id}" depends directly on "${depId}", a surface of project "${resolved.snapshot.projectName}". Only a local client Adapter may cross a project boundary \u2014 route this hop through an Adapter.`,
|
|
9197
9333
|
comp.id,
|
|
9198
|
-
isDraftCtx
|
|
9334
|
+
isDraftCtx,
|
|
9335
|
+
true
|
|
9199
9336
|
);
|
|
9200
9337
|
}
|
|
9201
9338
|
continue;
|
|
@@ -9773,14 +9910,14 @@ var init_declarative_assertions = __esm({
|
|
|
9773
9910
|
});
|
|
9774
9911
|
|
|
9775
9912
|
// src/core/rules/profiles.ts
|
|
9776
|
-
var BACKEND_LIKE, FRONTEND_LIKE,
|
|
9913
|
+
var BACKEND_LIKE, FRONTEND_LIKE, PROJECT_KINDS2, profilesRule;
|
|
9777
9914
|
var init_profiles = __esm({
|
|
9778
9915
|
"src/core/rules/profiles.ts"() {
|
|
9779
9916
|
"use strict";
|
|
9780
9917
|
init_types();
|
|
9781
9918
|
BACKEND_LIKE = /* @__PURE__ */ new Set(["backend", "lowlevel-os", "game-ecs", "realtime-embedded", "plc-cyclic"]);
|
|
9782
9919
|
FRONTEND_LIKE = /* @__PURE__ */ new Set(["frontend-reactive", "frontend-controller"]);
|
|
9783
|
-
|
|
9920
|
+
PROJECT_KINDS2 = new Set(PROJECT_KINDS);
|
|
9784
9921
|
profilesRule = {
|
|
9785
9922
|
name: "architectural-profiles",
|
|
9786
9923
|
description: "Per-profile stereotype constraints: View/FeatureComponent/RouterComponent only in frontend profiles; Actor/Supervisor forbidden in plc-cyclic (single scan cycle); Actor/Supervisor in frontend profiles warned. Extension packs may register custom profiles (family + forbidden/discouraged stereotype lists); unknown profile names are flagged.",
|
|
@@ -9804,7 +9941,7 @@ var init_profiles = __esm({
|
|
|
9804
9941
|
);
|
|
9805
9942
|
}
|
|
9806
9943
|
}
|
|
9807
|
-
if (!registered.has(ctx.projectType) && !
|
|
9944
|
+
if (!registered.has(ctx.projectType) && !PROJECT_KINDS2.has(ctx.projectType)) {
|
|
9808
9945
|
ctx.addIssue(
|
|
9809
9946
|
"warning",
|
|
9810
9947
|
"UNKNOWN_PROFILE",
|
|
@@ -12453,9 +12590,15 @@ function buildRuleContext(opts) {
|
|
|
12453
12590
|
...[...SDD_RULES, ...extensions.rules].flatMap((r) => r.codes.map((c) => c.code)),
|
|
12454
12591
|
// Declarative assertions bring their own namespaced codes — lint.allow
|
|
12455
12592
|
// and severity overrides treat them exactly like builtins.
|
|
12456
|
-
...extensions.assertions.map((a) => a.fullCode)
|
|
12593
|
+
...extensions.assertions.map((a) => a.fullCode),
|
|
12594
|
+
// Entry-point emitted codes: validateSddTree's chained-subproject pass
|
|
12595
|
+
// raises these AFTER the rule run (it post-processes the aggregated issue
|
|
12596
|
+
// list), so no registered rule declares them — but lint.allow validation
|
|
12597
|
+
// must still recognize them as real codes.
|
|
12598
|
+
"CHAINED_SUBPROJECT_CONTEXT",
|
|
12599
|
+
"UNVERIFIED_EXTERNAL_REF"
|
|
12457
12600
|
]);
|
|
12458
|
-
const addIssue = (defaultSeverity, code, message, specId, isDraftContext) => {
|
|
12601
|
+
const addIssue = (defaultSeverity, code, message, specId, isDraftContext, surfaceResolved) => {
|
|
12459
12602
|
if (scopeSubsystem && specId && !isSpecInScope(specId)) {
|
|
12460
12603
|
return;
|
|
12461
12604
|
}
|
|
@@ -12473,7 +12616,14 @@ function buildRuleContext(opts) {
|
|
|
12473
12616
|
if (severity === "warning") return;
|
|
12474
12617
|
}
|
|
12475
12618
|
}
|
|
12476
|
-
issues.push({
|
|
12619
|
+
issues.push({
|
|
12620
|
+
severity,
|
|
12621
|
+
code,
|
|
12622
|
+
message,
|
|
12623
|
+
specId,
|
|
12624
|
+
...isDraftContext ? { draftContext: true } : {},
|
|
12625
|
+
...surfaceResolved ? { surfaceResolved: true } : {}
|
|
12626
|
+
});
|
|
12477
12627
|
};
|
|
12478
12628
|
return {
|
|
12479
12629
|
system,
|
|
@@ -12951,24 +13101,54 @@ function validateSddTree(rulesOrOptions, projectType = "backend") {
|
|
|
12951
13101
|
for (const rule of ruleSequence()) {
|
|
12952
13102
|
rule.check(ctx);
|
|
12953
13103
|
}
|
|
12954
|
-
const hasCrossTreeSuspects = issues.some(
|
|
13104
|
+
const hasCrossTreeSuspects = issues.some(
|
|
13105
|
+
(i) => SUBPROJECT_REFERENCE_CODES.has(i.code) || SUBPROJECT_CONFORMANCE_CODES.has(i.code)
|
|
13106
|
+
);
|
|
12955
13107
|
const chainingParent = hasCrossTreeSuspects ? findChainingParent(getProjectRoot()) : null;
|
|
12956
13108
|
if (chainingParent) {
|
|
13109
|
+
let unverified = 0;
|
|
12957
13110
|
let downgraded = 0;
|
|
12958
|
-
for (
|
|
12959
|
-
|
|
12960
|
-
if (iss.
|
|
12961
|
-
|
|
12962
|
-
|
|
13111
|
+
for (let at = 0; at < issues.length; at++) {
|
|
13112
|
+
const iss = issues[at];
|
|
13113
|
+
if (SUBPROJECT_REFERENCE_CODES.has(iss.code) && !iss.surfaceResolved) {
|
|
13114
|
+
issues[at] = {
|
|
13115
|
+
severity: "warning",
|
|
13116
|
+
code: "UNVERIFIED_EXTERNAL_REF",
|
|
13117
|
+
crossTreeContext: true,
|
|
13118
|
+
// --ci waives it (parent root is authoritative)
|
|
13119
|
+
specId: iss.specId,
|
|
13120
|
+
...iss.agentId ? { agentId: iss.agentId } : {},
|
|
13121
|
+
...iss.draftContext ? { draftContext: true } : {},
|
|
13122
|
+
message: `Unverified external reference (${iss.code}): ${iss.message} No vendored surface snapshot covers this reference, so it cannot be verified from this chained subproject standalone \u2014 re-lock the parent so fresh family/sibling snapshots ship, or inspect what this project can consume via \`wairon surface externals\` / sdd_list_external_interfaces.`
|
|
13123
|
+
};
|
|
13124
|
+
unverified++;
|
|
13125
|
+
continue;
|
|
13126
|
+
}
|
|
13127
|
+
if (SUBPROJECT_CONFORMANCE_CODES.has(iss.code)) {
|
|
13128
|
+
if (iss.severity === "error") {
|
|
13129
|
+
iss.severity = "warning";
|
|
13130
|
+
downgraded++;
|
|
13131
|
+
}
|
|
13132
|
+
iss.crossTreeContext = true;
|
|
12963
13133
|
}
|
|
12964
|
-
iss.crossTreeContext = true;
|
|
12965
13134
|
}
|
|
12966
|
-
if (downgraded > 0) {
|
|
13135
|
+
if (unverified > 0 || downgraded > 0) {
|
|
13136
|
+
const notes = [];
|
|
13137
|
+
if (unverified > 0) {
|
|
13138
|
+
notes.push(
|
|
13139
|
+
`${unverified} cross-tree reference(s) have no vendored surface snapshot covering them and were reported as UNVERIFIED_EXTERNAL_REF warnings \u2014 re-lock the parent so fresh family/sibling snapshots ship, or inspect via \`wairon surface externals\` / sdd_list_external_interfaces.`
|
|
13140
|
+
);
|
|
13141
|
+
}
|
|
13142
|
+
if (downgraded > 0) {
|
|
13143
|
+
notes.push(
|
|
13144
|
+
`${downgraded} code\u2194spec conformance finding(s) (parent-root-relative source paths) were downgraded to warnings.`
|
|
13145
|
+
);
|
|
13146
|
+
}
|
|
12967
13147
|
issues.unshift({
|
|
12968
13148
|
severity: "warning",
|
|
12969
13149
|
code: "CHAINED_SUBPROJECT_CONTEXT",
|
|
12970
13150
|
crossTreeContext: true,
|
|
12971
|
-
message: `This project is a chained subproject ("${chainingParent.subsystemId}") of the parent project at "${chainingParent.parentRoot}". ${
|
|
13151
|
+
message: `This project is a chained subproject ("${chainingParent.subsystemId}") of the parent project at "${chainingParent.parentRoot}". ${notes.join(" ")} Full cross-tree verification runs from the parent root.`
|
|
12972
13152
|
});
|
|
12973
13153
|
}
|
|
12974
13154
|
}
|
|
@@ -12985,7 +13165,7 @@ function validateSddTree(rulesOrOptions, projectType = "backend") {
|
|
|
12985
13165
|
function validateAsComplete(options) {
|
|
12986
13166
|
return validateSddTree({ ...options ?? {}, treatAllAsComplete: true });
|
|
12987
13167
|
}
|
|
12988
|
-
var
|
|
13168
|
+
var SUBPROJECT_REFERENCE_CODES, SUBPROJECT_CONFORMANCE_CODES;
|
|
12989
13169
|
var init_validation = __esm({
|
|
12990
13170
|
"src/core/validation.ts"() {
|
|
12991
13171
|
"use strict";
|
|
@@ -12998,8 +13178,7 @@ var init_validation = __esm({
|
|
|
12998
13178
|
init_source_analysis();
|
|
12999
13179
|
init_specs2();
|
|
13000
13180
|
init_fs();
|
|
13001
|
-
|
|
13002
|
-
// reference resolution
|
|
13181
|
+
SUBPROJECT_REFERENCE_CODES = /* @__PURE__ */ new Set([
|
|
13003
13182
|
"UNDEFINED_TYPE_REFERENCE",
|
|
13004
13183
|
"INVALID_DEPENDENCY_REFERENCE",
|
|
13005
13184
|
"INVALID_TARGET_COMPONENT_REFERENCE",
|
|
@@ -13007,8 +13186,9 @@ var init_validation = __esm({
|
|
|
13007
13186
|
"UNDECLARED_DEPENDENCY_CALL",
|
|
13008
13187
|
"INVALID_TRUSTED_LINK",
|
|
13009
13188
|
"CROSS_SUBSYSTEM_NON_ADAPTER",
|
|
13010
|
-
"CROSS_TREE_REF_UNRESOLVED"
|
|
13011
|
-
|
|
13189
|
+
"CROSS_TREE_REF_UNRESOLVED"
|
|
13190
|
+
]);
|
|
13191
|
+
SUBPROJECT_CONFORMANCE_CODES = /* @__PURE__ */ new Set([
|
|
13012
13192
|
"MISSING_SOURCE_FILE",
|
|
13013
13193
|
"SOURCE_PATH_ESCAPES_ROOT",
|
|
13014
13194
|
"MISSING_SOURCE_PATH",
|
|
@@ -13931,6 +14111,19 @@ function dryRunSerializeSpecs(include) {
|
|
|
13931
14111
|
function buildProjectGraph(level) {
|
|
13932
14112
|
return buildGraphModel(level);
|
|
13933
14113
|
}
|
|
14114
|
+
function resolveChainingParent() {
|
|
14115
|
+
return findChainingParent(getProjectRoot());
|
|
14116
|
+
}
|
|
14117
|
+
function computeStateIdAt(root) {
|
|
14118
|
+
const resolved = path10.resolve(root);
|
|
14119
|
+
return runWithProjectRoot(resolved, () => {
|
|
14120
|
+
workspaceFor(resolved).invalidate();
|
|
14121
|
+
const system = loadSystemSpec();
|
|
14122
|
+
if (!system) return null;
|
|
14123
|
+
const s = computeStateId();
|
|
14124
|
+
return `${s.algorithm}:${s.digest}`;
|
|
14125
|
+
});
|
|
14126
|
+
}
|
|
13934
14127
|
function deleteTypeSpec(id) {
|
|
13935
14128
|
return current().deleteTypeSpec(id);
|
|
13936
14129
|
}
|
|
@@ -13974,6 +14167,7 @@ var init_specs2 = __esm({
|
|
|
13974
14167
|
path10 = __toESM(require("path"));
|
|
13975
14168
|
init_loader();
|
|
13976
14169
|
init_fs();
|
|
14170
|
+
init_statehash();
|
|
13977
14171
|
init_yaml();
|
|
13978
14172
|
init_models();
|
|
13979
14173
|
init_narrative_labels();
|
|
@@ -16068,6 +16262,7 @@ __export(src_exports, {
|
|
|
16068
16262
|
OutputTargetSchema: () => OutputTargetSchema,
|
|
16069
16263
|
PACK_DIR_ENTRIES: () => PACK_DIR_ENTRIES,
|
|
16070
16264
|
PATTERN_TYPES: () => PATTERN_TYPES,
|
|
16265
|
+
PROJECT_KINDS: () => PROJECT_KINDS,
|
|
16071
16266
|
PackAssertionSchema: () => PackAssertionSchema,
|
|
16072
16267
|
PackSkillSchema: () => PackSkillSchema,
|
|
16073
16268
|
ParallelBranchSchema: () => ParallelBranchSchema,
|
|
@@ -16078,8 +16273,10 @@ __export(src_exports, {
|
|
|
16078
16273
|
PortalAuthSchemeSchema: () => PortalAuthSchemeSchema,
|
|
16079
16274
|
PortalTypeSchema: () => PortalTypeSchema,
|
|
16080
16275
|
ProfileDefSchema: () => ProfileDefSchema,
|
|
16276
|
+
ProfileSelectionSubjectSchema: () => ProfileSelectionSubjectSchema,
|
|
16081
16277
|
ProjectConfigSchema: () => ProjectConfigSchema,
|
|
16082
16278
|
ProjectNotInitializedError: () => ProjectNotInitializedError,
|
|
16279
|
+
ProjectProfileSelectionSchema: () => ProjectProfileSelectionSchema,
|
|
16083
16280
|
PublicInterfaceSchema: () => PublicInterfaceSchema,
|
|
16084
16281
|
PublicInterfaceTypeSchema: () => PublicInterfaceTypeSchema,
|
|
16085
16282
|
RegistrySchema: () => RegistrySchema,
|
|
@@ -16138,7 +16335,9 @@ __export(src_exports, {
|
|
|
16138
16335
|
clearLoaderIssues: () => clearLoaderIssues,
|
|
16139
16336
|
collectPromotableSpecs: () => collectPromotableSpecs,
|
|
16140
16337
|
composeRuleSequence: () => composeRuleSequence,
|
|
16338
|
+
computeParentStateId: () => computeParentStateId,
|
|
16141
16339
|
computeStateId: () => computeStateId,
|
|
16340
|
+
computeStateIdAt: () => computeStateIdAt,
|
|
16142
16341
|
contextDir: () => contextDir,
|
|
16143
16342
|
createAgentRecord: () => createAgentRecord,
|
|
16144
16343
|
createChainedSubsystem: () => createChainedSubsystem,
|
|
@@ -16204,6 +16403,7 @@ __export(src_exports, {
|
|
|
16204
16403
|
isOpenApiDocument: () => isOpenApiDocument,
|
|
16205
16404
|
isProjectInitialized: () => isProjectInitialized,
|
|
16206
16405
|
listDirectChainedSubprojects: () => listDirectChainedSubprojects,
|
|
16406
|
+
listExternalInterfaces: () => listExternalInterfaces,
|
|
16207
16407
|
listFiles: () => listFiles,
|
|
16208
16408
|
listFilesRecursive: () => listFilesRecursive,
|
|
16209
16409
|
listFreeStandingDomains: () => listFreeStandingDomains,
|
|
@@ -16249,6 +16449,7 @@ __export(src_exports, {
|
|
|
16249
16449
|
pathExists: () => pathExists,
|
|
16250
16450
|
projectChildSurface: () => projectChildSurface,
|
|
16251
16451
|
projectOwnSurface: () => projectOwnSurface,
|
|
16452
|
+
projectSubsystemSurface: () => projectSubsystemSurface,
|
|
16252
16453
|
promoteAllComplete: () => promoteAllComplete,
|
|
16253
16454
|
provisionProject: () => provisionProject,
|
|
16254
16455
|
readArchitectureContext: () => readArchitectureContext,
|
|
@@ -16268,6 +16469,7 @@ __export(src_exports, {
|
|
|
16268
16469
|
renderTemplateInstructions: () => renderTemplateInstructions,
|
|
16269
16470
|
renderWaironGuide: () => renderWaironGuide,
|
|
16270
16471
|
resolveAgentTopology: () => resolveAgentTopology,
|
|
16472
|
+
resolveChainingParent: () => resolveChainingParent,
|
|
16271
16473
|
resolveDomains: () => resolveDomains,
|
|
16272
16474
|
resolvePackRef: () => resolvePackRef,
|
|
16273
16475
|
resolveSubprojectForNamespace: () => resolveSubprojectForNamespace,
|
|
@@ -16331,7 +16533,7 @@ function defaultTargetConfig(type) {
|
|
|
16331
16533
|
enabled: true
|
|
16332
16534
|
};
|
|
16333
16535
|
}
|
|
16334
|
-
var WAIRON_VERSION = "5.0.2-dev.
|
|
16536
|
+
var WAIRON_VERSION = "5.0.2-dev.15";
|
|
16335
16537
|
var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
16336
16538
|
var ARCHITECT_AGENT_ID = "agent-architect";
|
|
16337
16539
|
var ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -17655,6 +17857,7 @@ init_yaml();
|
|
|
17655
17857
|
OutputTargetSchema,
|
|
17656
17858
|
PACK_DIR_ENTRIES,
|
|
17657
17859
|
PATTERN_TYPES,
|
|
17860
|
+
PROJECT_KINDS,
|
|
17658
17861
|
PackAssertionSchema,
|
|
17659
17862
|
PackSkillSchema,
|
|
17660
17863
|
ParallelBranchSchema,
|
|
@@ -17665,8 +17868,10 @@ init_yaml();
|
|
|
17665
17868
|
PortalAuthSchemeSchema,
|
|
17666
17869
|
PortalTypeSchema,
|
|
17667
17870
|
ProfileDefSchema,
|
|
17871
|
+
ProfileSelectionSubjectSchema,
|
|
17668
17872
|
ProjectConfigSchema,
|
|
17669
17873
|
ProjectNotInitializedError,
|
|
17874
|
+
ProjectProfileSelectionSchema,
|
|
17670
17875
|
PublicInterfaceSchema,
|
|
17671
17876
|
PublicInterfaceTypeSchema,
|
|
17672
17877
|
RegistrySchema,
|
|
@@ -17725,7 +17930,9 @@ init_yaml();
|
|
|
17725
17930
|
clearLoaderIssues,
|
|
17726
17931
|
collectPromotableSpecs,
|
|
17727
17932
|
composeRuleSequence,
|
|
17933
|
+
computeParentStateId,
|
|
17728
17934
|
computeStateId,
|
|
17935
|
+
computeStateIdAt,
|
|
17729
17936
|
contextDir,
|
|
17730
17937
|
createAgentRecord,
|
|
17731
17938
|
createChainedSubsystem,
|
|
@@ -17791,6 +17998,7 @@ init_yaml();
|
|
|
17791
17998
|
isOpenApiDocument,
|
|
17792
17999
|
isProjectInitialized,
|
|
17793
18000
|
listDirectChainedSubprojects,
|
|
18001
|
+
listExternalInterfaces,
|
|
17794
18002
|
listFiles,
|
|
17795
18003
|
listFilesRecursive,
|
|
17796
18004
|
listFreeStandingDomains,
|
|
@@ -17836,6 +18044,7 @@ init_yaml();
|
|
|
17836
18044
|
pathExists,
|
|
17837
18045
|
projectChildSurface,
|
|
17838
18046
|
projectOwnSurface,
|
|
18047
|
+
projectSubsystemSurface,
|
|
17839
18048
|
promoteAllComplete,
|
|
17840
18049
|
provisionProject,
|
|
17841
18050
|
readArchitectureContext,
|
|
@@ -17855,6 +18064,7 @@ init_yaml();
|
|
|
17855
18064
|
renderTemplateInstructions,
|
|
17856
18065
|
renderWaironGuide,
|
|
17857
18066
|
resolveAgentTopology,
|
|
18067
|
+
resolveChainingParent,
|
|
17858
18068
|
resolveDomains,
|
|
17859
18069
|
resolvePackRef,
|
|
17860
18070
|
resolveSubprojectForNamespace,
|