@wairon/cli 5.1.1-dev.97 → 5.1.1-dev.98
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 +1914 -855
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1717 -659
- package/dist/index.js.map +1 -1
- package/dist/templates/skills/sdd-architect.md +1 -0
- package/package.json +6 -3
- package/schemas/design-export-1.json +1168 -0
package/dist/index.js
CHANGED
|
@@ -1672,15 +1672,15 @@ var require_node = __commonJS({
|
|
|
1672
1672
|
var slzh = function(d, b) {
|
|
1673
1673
|
return b + 30 + b2(d, b + 26) + b2(d, b + 28);
|
|
1674
1674
|
};
|
|
1675
|
-
var zh = function(d, b,
|
|
1675
|
+
var zh = function(d, b, z13) {
|
|
1676
1676
|
var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;
|
|
1677
|
-
var _a2 = z64hs(d, es, efl,
|
|
1677
|
+
var _a2 = z64hs(d, es, efl, z13, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a2[0], su = _a2[1], off = _a2[2];
|
|
1678
1678
|
return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];
|
|
1679
1679
|
};
|
|
1680
|
-
var z64hs = function(d, b, l,
|
|
1680
|
+
var z64hs = function(d, b, l, z13, sc, su, off) {
|
|
1681
1681
|
var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;
|
|
1682
1682
|
var nf = nsc + nsu + noff;
|
|
1683
|
-
if (
|
|
1683
|
+
if (z13 && nf) {
|
|
1684
1684
|
for (; b + 4 < e; b += 4 + b2(d, b + 2)) {
|
|
1685
1685
|
if (b2(d, b) == 1) {
|
|
1686
1686
|
return [
|
|
@@ -1691,7 +1691,7 @@ var require_node = __commonJS({
|
|
|
1691
1691
|
];
|
|
1692
1692
|
}
|
|
1693
1693
|
}
|
|
1694
|
-
if (
|
|
1694
|
+
if (z13 < 2)
|
|
1695
1695
|
err(13);
|
|
1696
1696
|
}
|
|
1697
1697
|
return [sc, su, off, 0];
|
|
@@ -2300,18 +2300,18 @@ var require_node = __commonJS({
|
|
|
2300
2300
|
if (lft) {
|
|
2301
2301
|
var c = lft;
|
|
2302
2302
|
var o = b4(data, e + 16);
|
|
2303
|
-
var
|
|
2304
|
-
if (
|
|
2303
|
+
var z13 = b4(data, e - 20) == 117853008;
|
|
2304
|
+
if (z13) {
|
|
2305
2305
|
var ze = b4(data, e - 12);
|
|
2306
|
-
|
|
2307
|
-
if (
|
|
2306
|
+
z13 = b4(data, ze) == 101075792;
|
|
2307
|
+
if (z13) {
|
|
2308
2308
|
c = lft = b4(data, ze + 32);
|
|
2309
2309
|
o = b4(data, ze + 48);
|
|
2310
2310
|
}
|
|
2311
2311
|
}
|
|
2312
2312
|
var fltr = opts && opts.filter;
|
|
2313
2313
|
var _loop_3 = function(i3) {
|
|
2314
|
-
var _a2 = zh(data, o,
|
|
2314
|
+
var _a2 = zh(data, o, z13), c_1 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);
|
|
2315
2315
|
o = no;
|
|
2316
2316
|
var cbl = function(e2, d) {
|
|
2317
2317
|
if (e2) {
|
|
@@ -2366,18 +2366,18 @@ var require_node = __commonJS({
|
|
|
2366
2366
|
if (!c)
|
|
2367
2367
|
return {};
|
|
2368
2368
|
var o = b4(data, e + 16);
|
|
2369
|
-
var
|
|
2370
|
-
if (
|
|
2369
|
+
var z13 = b4(data, e - 20) == 117853008;
|
|
2370
|
+
if (z13) {
|
|
2371
2371
|
var ze = b4(data, e - 12);
|
|
2372
|
-
|
|
2373
|
-
if (
|
|
2372
|
+
z13 = b4(data, ze) == 101075792;
|
|
2373
|
+
if (z13) {
|
|
2374
2374
|
c = b4(data, ze + 32);
|
|
2375
2375
|
o = b4(data, ze + 48);
|
|
2376
2376
|
}
|
|
2377
2377
|
}
|
|
2378
2378
|
var fltr = opts && opts.filter;
|
|
2379
2379
|
for (var i2 = 0; i2 < c; ++i2) {
|
|
2380
|
-
var _a2 = zh(data, o,
|
|
2380
|
+
var _a2 = zh(data, o, z13), c_2 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);
|
|
2381
2381
|
o = no;
|
|
2382
2382
|
if (!fltr || fltr({
|
|
2383
2383
|
name: fn,
|
|
@@ -3414,9 +3414,30 @@ __export(src_exports, {
|
|
|
3414
3414
|
CustomTargetConfigSchema: () => CustomTargetConfigSchema,
|
|
3415
3415
|
CustomTargetSchema: () => CustomTargetSchema,
|
|
3416
3416
|
DEFAULT_TARGET_DIRS: () => DEFAULT_TARGET_DIRS,
|
|
3417
|
+
DESIGN_APPROVALS: () => DESIGN_APPROVALS,
|
|
3418
|
+
DESIGN_DEPENDENCY_ROLES: () => DESIGN_DEPENDENCY_ROLES,
|
|
3419
|
+
DESIGN_FORMAT: () => DESIGN_FORMAT,
|
|
3420
|
+
DESIGN_FORMAT_VERSION: () => DESIGN_FORMAT_VERSION,
|
|
3417
3421
|
DatabaseSpecSchema: () => DatabaseSpecSchema,
|
|
3418
3422
|
DependencyClassSchema: () => DependencyClassSchema,
|
|
3423
|
+
DesignApprovalSchema: () => DesignApprovalSchema,
|
|
3424
|
+
DesignComponentSchema: () => DesignComponentSchema,
|
|
3425
|
+
DesignDependencyRoleSchema: () => DesignDependencyRoleSchema,
|
|
3426
|
+
DesignDependencySchema: () => DesignDependencySchema,
|
|
3419
3427
|
DesignDepthSchema: () => DesignDepthSchema,
|
|
3428
|
+
DesignExportEntrySchema: () => DesignExportEntrySchema,
|
|
3429
|
+
DesignExportSchema: () => DesignExportSchema,
|
|
3430
|
+
DesignFieldSchema: () => DesignFieldSchema,
|
|
3431
|
+
DesignImplementationSchema: () => DesignImplementationSchema,
|
|
3432
|
+
DesignInterfaceSchema: () => DesignInterfaceSchema,
|
|
3433
|
+
DesignMethodBodySchema: () => DesignMethodBodySchema,
|
|
3434
|
+
DesignMethodSchema: () => DesignMethodSchema,
|
|
3435
|
+
DesignParamSchema: () => DesignParamSchema,
|
|
3436
|
+
DesignProjectSchema: () => DesignProjectSchema,
|
|
3437
|
+
DesignSourceSchema: () => DesignSourceSchema,
|
|
3438
|
+
DesignSubsystemSchema: () => DesignSubsystemSchema,
|
|
3439
|
+
DesignTypeRefSchema: () => DesignTypeRefSchema,
|
|
3440
|
+
DesignTypeSchema: () => DesignTypeSchema,
|
|
3420
3441
|
DiagramConfigSchema: () => DiagramConfigSchema,
|
|
3421
3442
|
DispatchBindingSchema: () => DispatchBindingSchema,
|
|
3422
3443
|
DoctorOptionsError: () => DoctorOptionsError,
|
|
@@ -3476,6 +3497,8 @@ __export(src_exports, {
|
|
|
3476
3497
|
PortalAuthSchemeSchema: () => PortalAuthSchemeSchema,
|
|
3477
3498
|
PortalMountSchema: () => PortalMountSchema,
|
|
3478
3499
|
PortalTypeSchema: () => PortalTypeSchema,
|
|
3500
|
+
PreviousIdsSchema: () => PreviousIdsSchema,
|
|
3501
|
+
PreviousNamesSchema: () => PreviousNamesSchema,
|
|
3479
3502
|
ProfileSelectionSubjectSchema: () => ProfileSelectionSubjectSchema,
|
|
3480
3503
|
ProjectConfigSchema: () => ProjectConfigSchema,
|
|
3481
3504
|
ProjectNotInitializedError: () => ProjectNotInitializedError,
|
|
@@ -3519,6 +3542,7 @@ __export(src_exports, {
|
|
|
3519
3542
|
TopologyConfigSchema: () => TopologyConfigSchema,
|
|
3520
3543
|
TransportSchema: () => TransportSchema,
|
|
3521
3544
|
TrustedLinkSchema: () => TrustedLinkSchema,
|
|
3545
|
+
TypeExpressionSchema: () => TypeExpressionSchema,
|
|
3522
3546
|
TypeFieldSchema: () => TypeFieldSchema,
|
|
3523
3547
|
TypeKindSchema: () => TypeKindSchema,
|
|
3524
3548
|
TypeMethodSchema: () => TypeMethodSchema,
|
|
@@ -3606,6 +3630,7 @@ __export(src_exports, {
|
|
|
3606
3630
|
ensureDir: () => ensureDir,
|
|
3607
3631
|
ensureProjectInitialized: () => ensureProjectInitialized,
|
|
3608
3632
|
excerptParent: () => excerpt,
|
|
3633
|
+
exportDesign: () => exportDesign3,
|
|
3609
3634
|
exportSpecTree: () => exportSpecTree,
|
|
3610
3635
|
exportTargetKey: () => exportTargetKey,
|
|
3611
3636
|
exportUsage: () => exportUsage,
|
|
@@ -3755,6 +3780,7 @@ __export(src_exports, {
|
|
|
3755
3780
|
renameComponent: () => renameComponent,
|
|
3756
3781
|
renameId: () => renameProjectId,
|
|
3757
3782
|
renameMethod: () => renameMethod,
|
|
3783
|
+
renameType: () => renameType,
|
|
3758
3784
|
renderDiagram: () => renderDiagram,
|
|
3759
3785
|
repairForeignStepFields: () => repairForeignStepFields,
|
|
3760
3786
|
repairSignatures: () => repairSignatures,
|
|
@@ -3794,6 +3820,7 @@ __export(src_exports, {
|
|
|
3794
3820
|
settledSpecPaths: () => settledSpecPaths,
|
|
3795
3821
|
signatureFacts: () => signatureFacts,
|
|
3796
3822
|
signatureTypeRefs: () => signatureTypeRefs,
|
|
3823
|
+
specIndexRetiredBy: () => specIndexRetiredBy,
|
|
3797
3824
|
specPathsInScope: () => specPathsInScope,
|
|
3798
3825
|
splitNamespace: () => splitNamespace,
|
|
3799
3826
|
stepConfigVerdict: () => stepConfigVerdict,
|
|
@@ -6996,6 +7023,22 @@ var PortalMountSchema = import_zod8.z.object({
|
|
|
6996
7023
|
*/
|
|
6997
7024
|
via: import_zod8.z.string().optional()
|
|
6998
7025
|
});
|
|
7026
|
+
var PreviousIdsSchema = import_zod8.z.array(import_zod8.z.string().min(1));
|
|
7027
|
+
var PreviousNamesSchema = import_zod8.z.array(import_zod8.z.string().min(1));
|
|
7028
|
+
function specIndexRetiredBy(index, kind, id) {
|
|
7029
|
+
const holders = kind === "component" ? index.components : kind === "interface" ? index.interfaces : kind === "implementation" ? index.implementations : kind === "type" ? index.types : [];
|
|
7030
|
+
for (const holder of holders) {
|
|
7031
|
+
if (!holder.previousIds?.length) continue;
|
|
7032
|
+
const key = kind === "type" && holder.subsystem && !holder.id.startsWith(`${holder.subsystem}::`) ? `${holder.subsystem}::${holder.id}` : holder.id;
|
|
7033
|
+
const cut = key.lastIndexOf("::");
|
|
7034
|
+
const namespace = cut >= 0 ? key.slice(0, cut + 2) : "";
|
|
7035
|
+
for (const previous of holder.previousIds) {
|
|
7036
|
+
const previousKey = previous.includes("::") ? previous : namespace + previous;
|
|
7037
|
+
if (previousKey === id) return key;
|
|
7038
|
+
}
|
|
7039
|
+
}
|
|
7040
|
+
return void 0;
|
|
7041
|
+
}
|
|
6999
7042
|
var ComponentSpecSchema = import_zod8.z.object({
|
|
7000
7043
|
id: SpecIdSchema,
|
|
7001
7044
|
name: import_zod8.z.string(),
|
|
@@ -7039,6 +7082,8 @@ var ComponentSpecSchema = import_zod8.z.object({
|
|
|
7039
7082
|
* satisfies the source requirement for a source-less implementation (suppresses
|
|
7040
7083
|
* MISSING_SOURCE_PATH); `informative` links are context only. */
|
|
7041
7084
|
externalLinks: import_zod8.z.array(ExternalLinkSchema).optional(),
|
|
7085
|
+
/** The rename trace (see PreviousIdsSchema). */
|
|
7086
|
+
previousIds: PreviousIdsSchema.optional(),
|
|
7042
7087
|
/** Per-spec lint suppressions (see LintConfigSchema). */
|
|
7043
7088
|
lint: LintConfigSchema.optional(),
|
|
7044
7089
|
/** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */
|
|
@@ -7206,6 +7251,8 @@ var MethodSignatureSchema = import_zod8.z.object({
|
|
|
7206
7251
|
seen.add(finding2.code);
|
|
7207
7252
|
});
|
|
7208
7253
|
}).optional(),
|
|
7254
|
+
/** The method's rename trace (see PreviousNamesSchema). */
|
|
7255
|
+
previousNames: PreviousNamesSchema.optional(),
|
|
7209
7256
|
/** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */
|
|
7210
7257
|
ext: ExtDataSchema.optional()
|
|
7211
7258
|
});
|
|
@@ -7273,6 +7320,8 @@ var InterfaceSpecSchema = import_zod8.z.object({
|
|
|
7273
7320
|
component: import_zod8.z.string(),
|
|
7274
7321
|
// References L2 Component id
|
|
7275
7322
|
methods: import_zod8.z.array(StoredMethodSignatureSchema).default([]),
|
|
7323
|
+
/** The rename trace (see PreviousIdsSchema). */
|
|
7324
|
+
previousIds: PreviousIdsSchema.optional(),
|
|
7276
7325
|
/** Per-spec lint suppressions (see LintConfigSchema). */
|
|
7277
7326
|
lint: LintConfigSchema.optional(),
|
|
7278
7327
|
/** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */
|
|
@@ -7563,6 +7612,8 @@ var ImplementationSpecSchema = import_zod8.z.object({
|
|
|
7563
7612
|
detail: NarrativeDetailSchema.optional(),
|
|
7564
7613
|
/** Spec-level conformance tier default (each method may override). */
|
|
7565
7614
|
conformance: ConformanceTierSchema.optional(),
|
|
7615
|
+
/** The rename trace (see PreviousIdsSchema). */
|
|
7616
|
+
previousIds: PreviousIdsSchema.optional(),
|
|
7566
7617
|
/** Per-spec lint suppressions (see LintConfigSchema). */
|
|
7567
7618
|
lint: LintConfigSchema.optional(),
|
|
7568
7619
|
/** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */
|
|
@@ -7738,6 +7789,8 @@ var TypeSpecSchema = import_zod8.z.object({
|
|
|
7738
7789
|
* as `InvoiceLine`.
|
|
7739
7790
|
*/
|
|
7740
7791
|
symbol: import_zod8.z.string().optional(),
|
|
7792
|
+
/** The rename trace (see PreviousIdsSchema): ids this type held within its owner. */
|
|
7793
|
+
previousIds: PreviousIdsSchema.optional(),
|
|
7741
7794
|
/** Per-spec lint suppressions (see LintConfigSchema). */
|
|
7742
7795
|
lint: LintConfigSchema.optional(),
|
|
7743
7796
|
/** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */
|
|
@@ -9387,12 +9440,12 @@ function exportTargetKey(e) {
|
|
|
9387
9440
|
|
|
9388
9441
|
// src/models/project-family.ts
|
|
9389
9442
|
var path10 = __toESM(require("path"));
|
|
9390
|
-
function walkMemberPath(
|
|
9443
|
+
function walkMemberPath(byKey3, start, segments) {
|
|
9391
9444
|
let node = start;
|
|
9392
9445
|
for (const segment of segments.slice(0, -1)) {
|
|
9393
9446
|
const next = node.aliases.get(segment);
|
|
9394
9447
|
if (next !== void 0) {
|
|
9395
|
-
const found =
|
|
9448
|
+
const found = byKey3.get(next);
|
|
9396
9449
|
if (!found) return null;
|
|
9397
9450
|
node = found;
|
|
9398
9451
|
continue;
|
|
@@ -9404,13 +9457,13 @@ function walkMemberPath(byKey2, start, segments) {
|
|
|
9404
9457
|
return { project: node, name: segments[segments.length - 1] };
|
|
9405
9458
|
}
|
|
9406
9459
|
function landReference(projects, reference, from) {
|
|
9407
|
-
const
|
|
9408
|
-
const origin =
|
|
9409
|
-
const root =
|
|
9460
|
+
const byKey3 = new Map(projects.map((p) => [p.namespace, p]));
|
|
9461
|
+
const origin = byKey3.get(from);
|
|
9462
|
+
const root = byKey3.get("");
|
|
9410
9463
|
if (!reference.includes("::")) return { kind: "project", project: from, name: reference };
|
|
9411
9464
|
const land = (form, start, segments2) => {
|
|
9412
9465
|
if (!start) return { kind: "unresolved", form };
|
|
9413
|
-
const walked = walkMemberPath(
|
|
9466
|
+
const walked = walkMemberPath(byKey3, start, segments2);
|
|
9414
9467
|
if (walked === "outside") return { kind: "outside", form };
|
|
9415
9468
|
if (walked) return { kind: "project", form, project: walked.project.namespace, name: walked.name };
|
|
9416
9469
|
return { kind: "unresolved", form };
|
|
@@ -9422,7 +9475,7 @@ function landReference(projects, reference, from) {
|
|
|
9422
9475
|
while (segments[0] === "super") {
|
|
9423
9476
|
segments.shift();
|
|
9424
9477
|
if (!node || node.parent === void 0) return { kind: "outside", form: "super" };
|
|
9425
|
-
node =
|
|
9478
|
+
node = byKey3.get(node.parent);
|
|
9426
9479
|
}
|
|
9427
9480
|
if (segments.length === 0 || !node) return { kind: "unresolved", form: "super" };
|
|
9428
9481
|
return land("super", node, segments);
|
|
@@ -9434,11 +9487,11 @@ function landReference(projects, reference, from) {
|
|
|
9434
9487
|
return land(segments.length === 2 ? "alias" : "path", origin, segments);
|
|
9435
9488
|
}
|
|
9436
9489
|
if (origin.subsystems.has(first)) return { kind: "project", project: from, name: segments[segments.length - 1] };
|
|
9437
|
-
const fromRoot = root ? walkMemberPath(
|
|
9490
|
+
const fromRoot = root ? walkMemberPath(byKey3, root, segments) : null;
|
|
9438
9491
|
if (fromRoot && fromRoot !== "outside") return { kind: "project", form: "path", project: fromRoot.project.namespace, name: fromRoot.name };
|
|
9439
9492
|
const byId = projects.filter((p) => p.id === first || p.namespace !== "" && p.namespace === first);
|
|
9440
9493
|
if (byId.length === 1) {
|
|
9441
|
-
const walked = walkMemberPath(
|
|
9494
|
+
const walked = walkMemberPath(byKey3, byId[0], segments.slice(1));
|
|
9442
9495
|
if (walked === "outside") return { kind: "outside", form: "path" };
|
|
9443
9496
|
if (walked) return { kind: "project", form: "path", project: walked.project.namespace, name: walked.name };
|
|
9444
9497
|
}
|
|
@@ -9578,6 +9631,188 @@ function selectsFamily(options, declaresMembers) {
|
|
|
9578
9631
|
return declaresMembers && options?.memberDepth !== 0;
|
|
9579
9632
|
}
|
|
9580
9633
|
|
|
9634
|
+
// src/models/design-export.ts
|
|
9635
|
+
var import_zod9 = require("zod");
|
|
9636
|
+
var DESIGN_FORMAT = "wairon-design";
|
|
9637
|
+
var DESIGN_FORMAT_VERSION = "1.0";
|
|
9638
|
+
var DESIGN_APPROVALS = ["locked", "stale", "unlocked", "unjudged"];
|
|
9639
|
+
var DesignApprovalSchema = import_zod9.z.enum(DESIGN_APPROVALS);
|
|
9640
|
+
var DESIGN_DEPENDENCY_ROLES = ["member", "external"];
|
|
9641
|
+
var DesignDependencyRoleSchema = import_zod9.z.enum(DESIGN_DEPENDENCY_ROLES);
|
|
9642
|
+
var ExtSchema = import_zod9.z.record(import_zod9.z.unknown());
|
|
9643
|
+
var TypeExpressionSchema = import_zod9.z.lazy(
|
|
9644
|
+
() => import_zod9.z.object({
|
|
9645
|
+
form: import_zod9.z.enum(["primitive", "named", "list", "set", "map", "optional", "union", "async", "applied"]),
|
|
9646
|
+
name: import_zod9.z.string().optional(),
|
|
9647
|
+
args: import_zod9.z.array(TypeExpressionSchema)
|
|
9648
|
+
}).passthrough()
|
|
9649
|
+
);
|
|
9650
|
+
var DesignTypeRefSchema = import_zod9.z.object({
|
|
9651
|
+
text: import_zod9.z.string(),
|
|
9652
|
+
expression: TypeExpressionSchema.optional()
|
|
9653
|
+
}).passthrough();
|
|
9654
|
+
var DesignParamSchema = import_zod9.z.object({
|
|
9655
|
+
name: import_zod9.z.string(),
|
|
9656
|
+
type: DesignTypeRefSchema,
|
|
9657
|
+
optional: import_zod9.z.boolean(),
|
|
9658
|
+
description: import_zod9.z.string().optional()
|
|
9659
|
+
}).passthrough();
|
|
9660
|
+
var DesignFieldSchema = import_zod9.z.object({
|
|
9661
|
+
name: import_zod9.z.string(),
|
|
9662
|
+
type: DesignTypeRefSchema,
|
|
9663
|
+
optional: import_zod9.z.boolean(),
|
|
9664
|
+
description: import_zod9.z.string().optional(),
|
|
9665
|
+
key: import_zod9.z.string().optional(),
|
|
9666
|
+
references: import_zod9.z.string().optional()
|
|
9667
|
+
}).passthrough();
|
|
9668
|
+
var DeclaredInvocationSchema = MethodSignatureSchema.shape.invokedBy.unwrap().passthrough();
|
|
9669
|
+
var DesignMethodSchema = import_zod9.z.object({
|
|
9670
|
+
key: import_zod9.z.string(),
|
|
9671
|
+
name: import_zod9.z.string(),
|
|
9672
|
+
description: import_zod9.z.string().optional(),
|
|
9673
|
+
params: import_zod9.z.array(DesignParamSchema),
|
|
9674
|
+
returns: DesignTypeRefSchema,
|
|
9675
|
+
signature: import_zod9.z.string(),
|
|
9676
|
+
signatureType: import_zod9.z.string().optional(),
|
|
9677
|
+
effect: import_zod9.z.string().optional(),
|
|
9678
|
+
guarantees: import_zod9.z.array(import_zod9.z.string()),
|
|
9679
|
+
invokedBy: DeclaredInvocationSchema.optional(),
|
|
9680
|
+
endpoint: import_zod9.z.record(import_zod9.z.string()).optional(),
|
|
9681
|
+
formerly: import_zod9.z.array(import_zod9.z.string()),
|
|
9682
|
+
ext: ExtSchema.optional()
|
|
9683
|
+
}).passthrough();
|
|
9684
|
+
var DesignExportEntrySchema = import_zod9.z.object({
|
|
9685
|
+
publicName: import_zod9.z.string(),
|
|
9686
|
+
targetKind: import_zod9.z.string(),
|
|
9687
|
+
target: import_zod9.z.string(),
|
|
9688
|
+
audience: import_zod9.z.string().optional(),
|
|
9689
|
+
version: import_zod9.z.string().optional(),
|
|
9690
|
+
stability: import_zod9.z.string().optional()
|
|
9691
|
+
}).passthrough();
|
|
9692
|
+
var DesignDependencySchema = import_zod9.z.object({
|
|
9693
|
+
alias: import_zod9.z.string(),
|
|
9694
|
+
projectId: import_zod9.z.string(),
|
|
9695
|
+
role: DesignDependencyRoleSchema,
|
|
9696
|
+
digest: import_zod9.z.string().optional(),
|
|
9697
|
+
uses: import_zod9.z.array(import_zod9.z.string())
|
|
9698
|
+
}).passthrough();
|
|
9699
|
+
var DesignSourceSchema = import_zod9.z.object({
|
|
9700
|
+
projectId: import_zod9.z.string(),
|
|
9701
|
+
stateId: import_zod9.z.string(),
|
|
9702
|
+
approved: import_zod9.z.boolean(),
|
|
9703
|
+
approval: DesignApprovalSchema
|
|
9704
|
+
}).passthrough();
|
|
9705
|
+
var DesignProjectSchema = import_zod9.z.object({
|
|
9706
|
+
name: import_zod9.z.string(),
|
|
9707
|
+
vision: import_zod9.z.string(),
|
|
9708
|
+
boundaries: import_zod9.z.array(import_zod9.z.string()),
|
|
9709
|
+
requirements: import_zod9.z.array(import_zod9.z.string()),
|
|
9710
|
+
targetLanguage: import_zod9.z.string().optional(),
|
|
9711
|
+
exports: import_zod9.z.array(DesignExportEntrySchema)
|
|
9712
|
+
}).passthrough();
|
|
9713
|
+
var DesignSubsystemSchema = import_zod9.z.object({
|
|
9714
|
+
key: import_zod9.z.string(),
|
|
9715
|
+
name: import_zod9.z.string(),
|
|
9716
|
+
description: import_zod9.z.string(),
|
|
9717
|
+
status: import_zod9.z.string(),
|
|
9718
|
+
profile: import_zod9.z.string().optional(),
|
|
9719
|
+
targetLanguage: import_zod9.z.string().optional(),
|
|
9720
|
+
lifecycle: import_zod9.z.array(LifecycleEntrypointSchema.passthrough()),
|
|
9721
|
+
exports: import_zod9.z.array(DesignExportEntrySchema),
|
|
9722
|
+
trustedLinks: import_zod9.z.array(import_zod9.z.string()),
|
|
9723
|
+
ext: ExtSchema.optional()
|
|
9724
|
+
}).passthrough();
|
|
9725
|
+
var DesignComponentSchema = import_zod9.z.object({
|
|
9726
|
+
key: import_zod9.z.string(),
|
|
9727
|
+
name: import_zod9.z.string(),
|
|
9728
|
+
description: import_zod9.z.string(),
|
|
9729
|
+
status: import_zod9.z.string(),
|
|
9730
|
+
subsystem: import_zod9.z.string(),
|
|
9731
|
+
stereotype: import_zod9.z.string(),
|
|
9732
|
+
variant: import_zod9.z.string().optional(),
|
|
9733
|
+
dependencyClass: import_zod9.z.string().optional(),
|
|
9734
|
+
durability: import_zod9.z.string().optional(),
|
|
9735
|
+
portalType: import_zod9.z.string().optional(),
|
|
9736
|
+
owns: import_zod9.z.array(import_zod9.z.string()),
|
|
9737
|
+
dependsOn: import_zod9.z.array(import_zod9.z.string()),
|
|
9738
|
+
emits: import_zod9.z.array(EventBindingSchema.passthrough()),
|
|
9739
|
+
subscribesTo: import_zod9.z.array(EventBindingSchema.passthrough()),
|
|
9740
|
+
auth: PortalAuthSchema.passthrough().optional(),
|
|
9741
|
+
basePath: import_zod9.z.string().optional(),
|
|
9742
|
+
dispatch: import_zod9.z.array(DispatchBindingSchema.passthrough()),
|
|
9743
|
+
/** A listener's mounts as declared, each portal as a key: entrypoint facts. */
|
|
9744
|
+
mounts: import_zod9.z.array(PortalMountSchema.passthrough()),
|
|
9745
|
+
/** The pack-declared patterns the component realizes, as declared. */
|
|
9746
|
+
patterns: import_zod9.z.array(PatternRefSchema.passthrough()),
|
|
9747
|
+
/** The opaque external references the component documents, as declared. */
|
|
9748
|
+
externalLinks: import_zod9.z.array(ExternalLinkSchema.passthrough()),
|
|
9749
|
+
formerly: import_zod9.z.array(import_zod9.z.string()),
|
|
9750
|
+
ext: ExtSchema.optional()
|
|
9751
|
+
}).passthrough();
|
|
9752
|
+
var DesignInterfaceSchema = import_zod9.z.object({
|
|
9753
|
+
key: import_zod9.z.string(),
|
|
9754
|
+
component: import_zod9.z.string(),
|
|
9755
|
+
name: import_zod9.z.string(),
|
|
9756
|
+
description: import_zod9.z.string(),
|
|
9757
|
+
status: import_zod9.z.string(),
|
|
9758
|
+
methods: import_zod9.z.array(DesignMethodSchema),
|
|
9759
|
+
formerly: import_zod9.z.array(import_zod9.z.string()),
|
|
9760
|
+
ext: ExtSchema.optional()
|
|
9761
|
+
}).passthrough();
|
|
9762
|
+
var DesignMethodBodySchema = import_zod9.z.object({
|
|
9763
|
+
method: import_zod9.z.string(),
|
|
9764
|
+
detail: import_zod9.z.string(),
|
|
9765
|
+
intent: import_zod9.z.string().optional(),
|
|
9766
|
+
calls: import_zod9.z.array(import_zod9.z.string()),
|
|
9767
|
+
narrative: import_zod9.z.array(NarrativeStepSchema.passthrough())
|
|
9768
|
+
}).passthrough();
|
|
9769
|
+
var DesignImplementationSchema = import_zod9.z.object({
|
|
9770
|
+
key: import_zod9.z.string(),
|
|
9771
|
+
contract: import_zod9.z.string(),
|
|
9772
|
+
component: import_zod9.z.string(),
|
|
9773
|
+
name: import_zod9.z.string(),
|
|
9774
|
+
description: import_zod9.z.string(),
|
|
9775
|
+
status: import_zod9.z.string(),
|
|
9776
|
+
technologies: import_zod9.z.array(import_zod9.z.string()),
|
|
9777
|
+
sourcePath: import_zod9.z.string().optional(),
|
|
9778
|
+
methods: import_zod9.z.array(DesignMethodBodySchema),
|
|
9779
|
+
formerly: import_zod9.z.array(import_zod9.z.string()),
|
|
9780
|
+
ext: ExtSchema.optional()
|
|
9781
|
+
}).passthrough();
|
|
9782
|
+
var DesignTypeSchema = import_zod9.z.object({
|
|
9783
|
+
key: import_zod9.z.string(),
|
|
9784
|
+
kind: import_zod9.z.string(),
|
|
9785
|
+
name: import_zod9.z.string(),
|
|
9786
|
+
description: import_zod9.z.string().optional(),
|
|
9787
|
+
status: import_zod9.z.string().optional(),
|
|
9788
|
+
fields: import_zod9.z.array(DesignFieldSchema),
|
|
9789
|
+
methods: import_zod9.z.array(DesignMethodSchema),
|
|
9790
|
+
params: import_zod9.z.array(DesignParamSchema),
|
|
9791
|
+
returns: DesignTypeRefSchema.optional(),
|
|
9792
|
+
values: import_zod9.z.array(EnumValueSchema.passthrough()),
|
|
9793
|
+
holds: import_zod9.z.string().optional(),
|
|
9794
|
+
invariants: import_zod9.z.array(InvariantSchema.passthrough()),
|
|
9795
|
+
componentClass: import_zod9.z.string().optional(),
|
|
9796
|
+
database: import_zod9.z.string().optional(),
|
|
9797
|
+
table: import_zod9.z.string().optional(),
|
|
9798
|
+
linkedEntity: import_zod9.z.string().optional(),
|
|
9799
|
+
formerly: import_zod9.z.array(import_zod9.z.string()),
|
|
9800
|
+
ext: ExtSchema.optional()
|
|
9801
|
+
}).passthrough();
|
|
9802
|
+
var DesignExportSchema = import_zod9.z.object({
|
|
9803
|
+
format: import_zod9.z.literal(DESIGN_FORMAT),
|
|
9804
|
+
formatVersion: import_zod9.z.string().regex(/^\d+\.\d+$/),
|
|
9805
|
+
generator: import_zod9.z.string(),
|
|
9806
|
+
source: DesignSourceSchema,
|
|
9807
|
+
project: DesignProjectSchema,
|
|
9808
|
+
dependencies: import_zod9.z.array(DesignDependencySchema),
|
|
9809
|
+
subsystems: import_zod9.z.array(DesignSubsystemSchema),
|
|
9810
|
+
components: import_zod9.z.array(DesignComponentSchema),
|
|
9811
|
+
interfaces: import_zod9.z.array(DesignInterfaceSchema),
|
|
9812
|
+
implementations: import_zod9.z.array(DesignImplementationSchema),
|
|
9813
|
+
types: import_zod9.z.array(DesignTypeSchema)
|
|
9814
|
+
}).passthrough();
|
|
9815
|
+
|
|
9581
9816
|
// src/core/narrative-labels.ts
|
|
9582
9817
|
var SCALAR_REFS = [
|
|
9583
9818
|
["onTrueLabel", "onTrueStep"],
|
|
@@ -14791,7 +15026,7 @@ var MODEL = __MODEL_JSON__;
|
|
|
14791
15026
|
|
|
14792
15027
|
// src/core/surfaces.ts
|
|
14793
15028
|
var fs9 = __toESM(require("fs"));
|
|
14794
|
-
var
|
|
15029
|
+
var path14 = __toESM(require("path"));
|
|
14795
15030
|
|
|
14796
15031
|
// src/utils/filenames.ts
|
|
14797
15032
|
function safeFilenamePart(value) {
|
|
@@ -14939,10 +15174,477 @@ function unpin(alias) {
|
|
|
14939
15174
|
// src/core/openapi.ts
|
|
14940
15175
|
var yaml2 = __toESM(require("js-yaml"));
|
|
14941
15176
|
|
|
15177
|
+
// src/config/defaults.ts
|
|
15178
|
+
var os2 = __toESM(require("os"));
|
|
15179
|
+
var path13 = __toESM(require("path"));
|
|
15180
|
+
var DEFAULT_TARGET_DIRS = {
|
|
15181
|
+
claude: ".claude/agents",
|
|
15182
|
+
gemini: ".gemini/agents",
|
|
15183
|
+
agy: ".gemini/agents",
|
|
15184
|
+
cursor: ".cursor/rules",
|
|
15185
|
+
copilot: ".github/prompts",
|
|
15186
|
+
codex: ".codex/agents"
|
|
15187
|
+
};
|
|
15188
|
+
function defaultTargetConfig(type) {
|
|
15189
|
+
return {
|
|
15190
|
+
type,
|
|
15191
|
+
outputDir: DEFAULT_TARGET_DIRS[type],
|
|
15192
|
+
enabled: true
|
|
15193
|
+
};
|
|
15194
|
+
}
|
|
15195
|
+
var WAIRON_VERSION = "5.1.1-dev.98";
|
|
15196
|
+
var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
15197
|
+
var ARCHITECT_AGENT_ID = "agent-architect";
|
|
15198
|
+
var ARCHITECT_TEMPLATE_ID = "architect";
|
|
15199
|
+
function globalTemplatesDir(projectOverride) {
|
|
15200
|
+
if (process.env.WAIRON_TEMPLATES_DIR) {
|
|
15201
|
+
return process.env.WAIRON_TEMPLATES_DIR;
|
|
15202
|
+
}
|
|
15203
|
+
if (projectOverride) {
|
|
15204
|
+
return projectOverride;
|
|
15205
|
+
}
|
|
15206
|
+
return path13.join(os2.homedir(), ".wairon", "templates");
|
|
15207
|
+
}
|
|
15208
|
+
var BACKEND_COMMANDS = {
|
|
15209
|
+
claude: "claude",
|
|
15210
|
+
gemini: "gemini"
|
|
15211
|
+
};
|
|
15212
|
+
function backendCommand(backend) {
|
|
15213
|
+
return BACKEND_COMMANDS[backend] ?? backend;
|
|
15214
|
+
}
|
|
15215
|
+
var SUPPORTED_ALIASES = ["wai"];
|
|
15216
|
+
var SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
15217
|
+
"node_modules",
|
|
15218
|
+
"dist",
|
|
15219
|
+
"build",
|
|
15220
|
+
"out",
|
|
15221
|
+
".git",
|
|
15222
|
+
".cache",
|
|
15223
|
+
"coverage",
|
|
15224
|
+
"__pycache__",
|
|
15225
|
+
".venv",
|
|
15226
|
+
"venv",
|
|
15227
|
+
"target",
|
|
15228
|
+
// Rust
|
|
15229
|
+
"vendor"
|
|
15230
|
+
]);
|
|
15231
|
+
|
|
15232
|
+
// src/core/design-export.ts
|
|
15233
|
+
var NoSystemSpecError = class extends Error {
|
|
15234
|
+
constructor() {
|
|
15235
|
+
super("no-system: the tree has no L0 system spec to export (.wai/specs holds no system spec).");
|
|
15236
|
+
this.code = "no-system";
|
|
15237
|
+
this.name = "NoSystemSpecError";
|
|
15238
|
+
}
|
|
15239
|
+
};
|
|
15240
|
+
var isOwn = (spec) => !spec.id.includes("::");
|
|
15241
|
+
var byKey = (a, b) => compareOrdinal(a.key, b.key);
|
|
15242
|
+
var KeyTable = class {
|
|
15243
|
+
constructor(components, interfaces, types, members = []) {
|
|
15244
|
+
this.components = /* @__PURE__ */ new Set();
|
|
15245
|
+
/** component key → the interfaces it declares. */
|
|
15246
|
+
this.interfacesOf = /* @__PURE__ */ new Map();
|
|
15247
|
+
this.typeRefCache = /* @__PURE__ */ new Map();
|
|
15248
|
+
/** bound key → `alias::publicName`, over every direct member. */
|
|
15249
|
+
this.publicNames = /* @__PURE__ */ new Map();
|
|
15250
|
+
/** alias → the public names this projection wrote a reference to. */
|
|
15251
|
+
this.used = /* @__PURE__ */ new Map();
|
|
15252
|
+
for (const m of members) for (const [bound2, name] of m.names) if (!this.publicNames.has(bound2)) this.publicNames.set(bound2, name);
|
|
15253
|
+
for (const c of components) this.components.add(c.id);
|
|
15254
|
+
for (const i of [...interfaces].sort((a, b) => compareOrdinal(a.id, b.id))) {
|
|
15255
|
+
const list = this.interfacesOf.get(i.component) ?? [];
|
|
15256
|
+
list.push(i);
|
|
15257
|
+
this.interfacesOf.set(i.component, list);
|
|
15258
|
+
}
|
|
15259
|
+
this.types = [...types].sort((a, b) => compareOrdinal(qualifiedTypeId(a), qualifiedTypeId(b)));
|
|
15260
|
+
}
|
|
15261
|
+
/** A contract method's key: `<interface key>.<name>` on the first of the component's interfaces declaring it, else the name as written. */
|
|
15262
|
+
methodKey(component, method) {
|
|
15263
|
+
if (!component) return method;
|
|
15264
|
+
const intf = (this.interfacesOf.get(component) ?? []).find((i) => i.methods.some((m) => m.name === method));
|
|
15265
|
+
return intf ? `${intf.id}.${method}` : method;
|
|
15266
|
+
}
|
|
15267
|
+
/** Whether `component.method` names a contract method of an own component — a method signature source. */
|
|
15268
|
+
isMethodSource(value) {
|
|
15269
|
+
const dot = value.lastIndexOf(".");
|
|
15270
|
+
if (dot <= 0 || dot === value.length - 1) return false;
|
|
15271
|
+
const head2 = value.slice(0, dot);
|
|
15272
|
+
const tail = value.slice(dot + 1);
|
|
15273
|
+
return this.components.has(head2) && (this.interfacesOf.get(head2) ?? []).some((i) => i.methods.some((m) => m.name === tail));
|
|
15274
|
+
}
|
|
15275
|
+
/**
|
|
15276
|
+
* The key of the own type a written name resolves to — same subsystem first,
|
|
15277
|
+
* then system-level, then any, ordinal by key within a rank — or null when
|
|
15278
|
+
* no own type answers to it (a generic parameter, or a name in another project).
|
|
15279
|
+
*/
|
|
15280
|
+
typeKey(name, owner, kind) {
|
|
15281
|
+
const cacheKey = `${owner ?? ""}|${kind ?? ""}|${name}`;
|
|
15282
|
+
if (this.typeRefCache.has(cacheKey)) return this.typeRefCache.get(cacheKey);
|
|
15283
|
+
const rank = (t) => t.subsystem === owner ? 0 : t.subsystem === void 0 ? 1 : 2;
|
|
15284
|
+
const hit = this.types.filter((t) => (kind === void 0 || t.kind === kind) && (t.id === name || qualifiedTypeId(t) === name || typeMatchesRef(t, name))).sort((a, b) => rank(a) - rank(b))[0];
|
|
15285
|
+
const key = hit ? qualifiedTypeId(hit) : null;
|
|
15286
|
+
this.typeRefCache.set(cacheKey, key);
|
|
15287
|
+
return key;
|
|
15288
|
+
}
|
|
15289
|
+
/** A reference to a type field (`Type.field`) or a type, resolved to its key; as written when it resolves to nothing. */
|
|
15290
|
+
typeFieldRef(ref, owner) {
|
|
15291
|
+
const whole = this.typeKey(ref, owner);
|
|
15292
|
+
if (whole) return whole;
|
|
15293
|
+
const dot = ref.lastIndexOf(".");
|
|
15294
|
+
if (dot > 0) {
|
|
15295
|
+
const head2 = this.typeKey(ref.slice(0, dot), owner);
|
|
15296
|
+
if (head2) return `${head2}.${ref.slice(dot + 1)}`;
|
|
15297
|
+
const outside = this.external(ref.slice(0, dot));
|
|
15298
|
+
if (outside !== ref.slice(0, dot)) return `${outside}.${ref.slice(dot + 1)}`;
|
|
15299
|
+
}
|
|
15300
|
+
return this.external(ref);
|
|
15301
|
+
}
|
|
15302
|
+
/**
|
|
15303
|
+
* A reference as a consumer resolves it: a bound key of an item a direct
|
|
15304
|
+
* member exports as `alias::publicName` (recorded as used), anything else as
|
|
15305
|
+
* written — an own key, an external's reference (already `alias::name`), or
|
|
15306
|
+
* one binding no exported name, which the gate reports.
|
|
15307
|
+
*/
|
|
15308
|
+
external(ref) {
|
|
15309
|
+
const name = this.publicNames.get(ref);
|
|
15310
|
+
if (name === void 0) return ref;
|
|
15311
|
+
const cut = name.indexOf("::");
|
|
15312
|
+
const alias = name.slice(0, cut);
|
|
15313
|
+
const set = this.used.get(alias) ?? /* @__PURE__ */ new Set();
|
|
15314
|
+
set.add(name.slice(cut + 2));
|
|
15315
|
+
this.used.set(alias, set);
|
|
15316
|
+
return name;
|
|
15317
|
+
}
|
|
15318
|
+
/** A component reference: an own component's key, or another project's item by its public name. */
|
|
15319
|
+
componentRef(ref) {
|
|
15320
|
+
return this.components.has(ref) ? ref : this.external(ref);
|
|
15321
|
+
}
|
|
15322
|
+
};
|
|
15323
|
+
function resolveExpression(expr, keys, owner) {
|
|
15324
|
+
const args = expr.args.map((a) => resolveExpression(a, keys, owner));
|
|
15325
|
+
if ((expr.form === "named" || expr.form === "applied") && expr.name !== void 0) {
|
|
15326
|
+
return { form: expr.form, name: keys.typeKey(expr.name, owner) ?? keys.external(expr.name), args };
|
|
15327
|
+
}
|
|
15328
|
+
return expr.name !== void 0 ? { form: expr.form, name: expr.name, args } : { form: expr.form, args };
|
|
15329
|
+
}
|
|
15330
|
+
function typeRef(text3, position, keys, owner) {
|
|
15331
|
+
const parse = parseTypeExpression(text3, position);
|
|
15332
|
+
if (!parse.expression) return { text: text3 };
|
|
15333
|
+
const expression = resolveExpression(parse.expression, keys, owner);
|
|
15334
|
+
return { text: canonicalTypeText(expression), expression };
|
|
15335
|
+
}
|
|
15336
|
+
function projectParams(params, position, keys, owner) {
|
|
15337
|
+
return (params ?? []).map((p) => ({
|
|
15338
|
+
name: p.name,
|
|
15339
|
+
type: typeRef(p.type, position, keys, owner),
|
|
15340
|
+
optional: p.optional === true,
|
|
15341
|
+
...p.description !== void 0 ? { description: p.description } : {}
|
|
15342
|
+
}));
|
|
15343
|
+
}
|
|
15344
|
+
function exportEntry(e, keys) {
|
|
15345
|
+
const target = e.kind === "type" ? { targetKind: "type", target: keys.typeKey(String(e.typeDef), e.source) ?? keys.external(String(e.typeDef)) } : e.interface ? { targetKind: "interface", target: keys.external(e.interface) } : { targetKind: "component", target: keys.componentRef(String(e.component)) };
|
|
15346
|
+
return {
|
|
15347
|
+
publicName: e.publicName,
|
|
15348
|
+
...target,
|
|
15349
|
+
...e.audience !== void 0 ? { audience: e.audience } : {},
|
|
15350
|
+
...e.version !== void 0 ? { version: e.version } : {},
|
|
15351
|
+
...e.stability !== void 0 ? { stability: e.stability } : {}
|
|
15352
|
+
};
|
|
15353
|
+
}
|
|
15354
|
+
function exportRows(entries, keys) {
|
|
15355
|
+
return entries.map((e) => exportEntry(e, keys)).sort((a, b) => compareOrdinal(a.publicName, b.publicName) || compareOrdinal(`${a.targetKind}:${a.target}`, `${b.targetKind}:${b.target}`));
|
|
15356
|
+
}
|
|
15357
|
+
var boundaryText = (b) => typeof b === "string" ? b : b.description ? `${b.name}: ${b.description}` : b.name;
|
|
15358
|
+
var requirementText = (r) => typeof r === "string" ? r : r.description;
|
|
15359
|
+
function projectSection(system, table, keys) {
|
|
15360
|
+
return {
|
|
15361
|
+
name: system.name,
|
|
15362
|
+
vision: system.vision,
|
|
15363
|
+
boundaries: system.boundaries.map(boundaryText),
|
|
15364
|
+
requirements: system.globalRequirements.map(requirementText),
|
|
15365
|
+
...system.targetLanguage !== void 0 ? { targetLanguage: system.targetLanguage } : {},
|
|
15366
|
+
exports: exportRows(table, keys)
|
|
15367
|
+
};
|
|
15368
|
+
}
|
|
15369
|
+
function dependency(binding, lock, keys) {
|
|
15370
|
+
const alias = binding.external.alias;
|
|
15371
|
+
const digest3 = lock?.externals[alias]?.digest;
|
|
15372
|
+
return {
|
|
15373
|
+
alias,
|
|
15374
|
+
projectId: binding.external.project,
|
|
15375
|
+
role: binding.external.role,
|
|
15376
|
+
...digest3 !== void 0 ? { digest: digest3 } : {},
|
|
15377
|
+
uses: [.../* @__PURE__ */ new Set([...(binding.usage?.used ?? []).map((u) => u.publicName), ...keys.used.get(alias) ?? []])].sort(compareOrdinal)
|
|
15378
|
+
};
|
|
15379
|
+
}
|
|
15380
|
+
function memberDependency(member, lock, keys) {
|
|
15381
|
+
const digest3 = lock?.externals[member.alias]?.digest;
|
|
15382
|
+
return {
|
|
15383
|
+
alias: member.alias,
|
|
15384
|
+
projectId: member.projectId,
|
|
15385
|
+
role: "member",
|
|
15386
|
+
...digest3 !== void 0 ? { digest: digest3 } : {},
|
|
15387
|
+
uses: [...keys.used.get(member.alias) ?? []].sort(compareOrdinal)
|
|
15388
|
+
};
|
|
15389
|
+
}
|
|
15390
|
+
function directMembers(family) {
|
|
15391
|
+
return family.nodes.filter((n) => n.parent === "" && n.namespace !== "").map((n) => {
|
|
15392
|
+
const alias = n.mountAlias ?? n.namespace;
|
|
15393
|
+
const names = /* @__PURE__ */ new Map();
|
|
15394
|
+
const bound2 = (key) => {
|
|
15395
|
+
const local = key.startsWith(`${n.namespace}::`) ? key : `${n.namespace}::${key}`;
|
|
15396
|
+
const last = `${n.namespace}::${key.split("::").pop() ?? key}`;
|
|
15397
|
+
return [.../* @__PURE__ */ new Set([local, last])];
|
|
15398
|
+
};
|
|
15399
|
+
const rows = [...resolveProjectExports(n.namespace).entries].sort((a, b) => compareOrdinal(a.publicName, b.publicName));
|
|
15400
|
+
for (const e of rows) {
|
|
15401
|
+
const name = `${alias}::${e.publicName}`;
|
|
15402
|
+
const targets = e.kind === "type" ? [e.typeDef] : e.interface !== void 0 ? [e.interface, e.component] : [e.component];
|
|
15403
|
+
for (const target of targets) {
|
|
15404
|
+
if (target === void 0) continue;
|
|
15405
|
+
for (const key of bound2(target)) if (!names.has(key)) names.set(key, name);
|
|
15406
|
+
}
|
|
15407
|
+
}
|
|
15408
|
+
return { alias, projectId: n.id ?? alias, names };
|
|
15409
|
+
}).sort((a, b) => compareOrdinal(a.alias, b.alias));
|
|
15410
|
+
}
|
|
15411
|
+
function subsystemSection(s, table, keys) {
|
|
15412
|
+
return {
|
|
15413
|
+
key: s.id,
|
|
15414
|
+
name: s.name,
|
|
15415
|
+
description: s.description,
|
|
15416
|
+
status: s.status,
|
|
15417
|
+
...s.profile !== void 0 ? { profile: s.profile } : {},
|
|
15418
|
+
...s.targetLanguage !== void 0 ? { targetLanguage: s.targetLanguage } : {},
|
|
15419
|
+
lifecycle: (s.lifecycle ?? []).map((l) => ({ ...l, component: keys.componentRef(l.component) })),
|
|
15420
|
+
exports: exportRows(table, keys),
|
|
15421
|
+
trustedLinks: s.trustedLinks.map((t) => t.subsystem),
|
|
15422
|
+
...s.ext !== void 0 ? { ext: s.ext } : {}
|
|
15423
|
+
};
|
|
15424
|
+
}
|
|
15425
|
+
function componentSection(c, keys) {
|
|
15426
|
+
return {
|
|
15427
|
+
key: c.id,
|
|
15428
|
+
name: c.name,
|
|
15429
|
+
description: c.description,
|
|
15430
|
+
status: c.status,
|
|
15431
|
+
subsystem: c.subsystem,
|
|
15432
|
+
stereotype: c.componentType,
|
|
15433
|
+
...c.variant !== void 0 ? { variant: c.variant } : {},
|
|
15434
|
+
...c.dependencyClass !== void 0 ? { dependencyClass: c.dependencyClass } : {},
|
|
15435
|
+
...c.durability !== void 0 ? { durability: c.durability } : {},
|
|
15436
|
+
...c.portalType !== void 0 ? { portalType: c.portalType } : {},
|
|
15437
|
+
owns: c.owns.map((o) => keys.componentRef(o)),
|
|
15438
|
+
dependsOn: c.dependsOn.map((d) => keys.componentRef(d)),
|
|
15439
|
+
emits: (c.emits ?? []).map((e) => ({ ...e })),
|
|
15440
|
+
subscribesTo: (c.subscribesTo ?? []).map((e) => ({ ...e })),
|
|
15441
|
+
...c.auth !== void 0 ? { auth: c.auth } : {},
|
|
15442
|
+
...c.basePath !== void 0 ? { basePath: c.basePath } : {},
|
|
15443
|
+
dispatch: (c.dispatch ?? []).map((d) => ({ ...d, component: keys.componentRef(d.component) })),
|
|
15444
|
+
mounts: (c.mounts ?? []).map((m) => ({ ...m, portal: keys.componentRef(m.portal) })),
|
|
15445
|
+
patterns: (c.patterns ?? []).map((p) => ({ ...p })),
|
|
15446
|
+
externalLinks: (c.externalLinks ?? []).map((l) => ({ ...l })),
|
|
15447
|
+
formerly: [...c.previousIds ?? []],
|
|
15448
|
+
...c.ext !== void 0 ? { ext: c.ext } : {}
|
|
15449
|
+
};
|
|
15450
|
+
}
|
|
15451
|
+
function contractMethod(intf, m, keys, owner) {
|
|
15452
|
+
const signatureType = m.signatureFrom !== void 0 && !keys.isMethodSource(m.signatureFrom) ? keys.typeKey(m.signatureFrom, owner, "signature") ?? void 0 : void 0;
|
|
15453
|
+
return {
|
|
15454
|
+
key: `${intf.id}.${m.name}`,
|
|
15455
|
+
name: m.name,
|
|
15456
|
+
description: m.description,
|
|
15457
|
+
params: projectParams(m.params, "param", keys, owner),
|
|
15458
|
+
returns: typeRef(m.returns, "returns", keys, owner),
|
|
15459
|
+
signature: m.signature,
|
|
15460
|
+
...signatureType !== void 0 ? { signatureType } : {},
|
|
15461
|
+
...m.effect !== void 0 ? { effect: m.effect } : {},
|
|
15462
|
+
guarantees: [...m.guarantees ?? []],
|
|
15463
|
+
...m.invokedBy !== void 0 ? { invokedBy: { ...m.invokedBy } } : {},
|
|
15464
|
+
...m.endpoint !== void 0 ? { endpoint: endpointFields(m.endpoint) } : {},
|
|
15465
|
+
formerly: [...m.previousNames ?? []],
|
|
15466
|
+
...m.ext !== void 0 ? { ext: m.ext } : {}
|
|
15467
|
+
};
|
|
15468
|
+
}
|
|
15469
|
+
function endpointFields(endpoint) {
|
|
15470
|
+
const out = {};
|
|
15471
|
+
for (const [k, v] of Object.entries(endpoint)) if (v !== void 0) out[k] = String(v);
|
|
15472
|
+
return out;
|
|
15473
|
+
}
|
|
15474
|
+
function interfaceSection(intf, keys, owner) {
|
|
15475
|
+
return {
|
|
15476
|
+
key: intf.id,
|
|
15477
|
+
component: intf.component,
|
|
15478
|
+
name: intf.name,
|
|
15479
|
+
description: intf.description,
|
|
15480
|
+
status: intf.status,
|
|
15481
|
+
methods: intf.methods.map((m) => contractMethod(intf, m, keys, owner)),
|
|
15482
|
+
formerly: [...intf.previousIds ?? []],
|
|
15483
|
+
...intf.ext !== void 0 ? { ext: intf.ext } : {}
|
|
15484
|
+
};
|
|
15485
|
+
}
|
|
15486
|
+
function stepWithKeys(step, keys) {
|
|
15487
|
+
const out = { ...step };
|
|
15488
|
+
if (step.targetMethod !== void 0) out.targetMethod = keys.methodKey(step.targetComponent, step.targetMethod);
|
|
15489
|
+
if (step.targetComponent !== void 0) out.targetComponent = keys.componentRef(step.targetComponent);
|
|
15490
|
+
const from = step.auth?.from;
|
|
15491
|
+
if (from !== void 0 && from.startsWith("component:")) {
|
|
15492
|
+
out.auth = { ...step.auth, from: `component:${keys.componentRef(from.slice("component:".length))}` };
|
|
15493
|
+
}
|
|
15494
|
+
return out;
|
|
15495
|
+
}
|
|
15496
|
+
function callKey(ref, keys) {
|
|
15497
|
+
const dot = ref.lastIndexOf(".");
|
|
15498
|
+
if (dot <= 0) return ref;
|
|
15499
|
+
const key = keys.methodKey(ref.slice(0, dot), ref.slice(dot + 1));
|
|
15500
|
+
return key.includes(".") ? key : `${keys.componentRef(ref.slice(0, dot))}.${ref.slice(dot + 1)}`;
|
|
15501
|
+
}
|
|
15502
|
+
function implementationSection(impl, contract, component, keys) {
|
|
15503
|
+
const methods = impl.methods.map((m) => ({
|
|
15504
|
+
method: `${impl.contract}.${m.name}`,
|
|
15505
|
+
detail: effectiveDetail(m, impl, component).level,
|
|
15506
|
+
...m.intent !== void 0 ? { intent: m.intent } : {},
|
|
15507
|
+
calls: (m.calls ?? []).map((c) => callKey(c, keys)),
|
|
15508
|
+
narrative: m.narrative.map((s) => stepWithKeys(s, keys))
|
|
15509
|
+
}));
|
|
15510
|
+
return {
|
|
15511
|
+
key: impl.id,
|
|
15512
|
+
contract: impl.contract,
|
|
15513
|
+
component: contract?.component ?? component?.id ?? "",
|
|
15514
|
+
name: impl.name,
|
|
15515
|
+
description: impl.description,
|
|
15516
|
+
status: impl.status,
|
|
15517
|
+
technologies: (impl.technologies ?? []).map(technologyName),
|
|
15518
|
+
...impl.sourcePath !== void 0 ? { sourcePath: impl.sourcePath } : {},
|
|
15519
|
+
methods,
|
|
15520
|
+
formerly: [...impl.previousIds ?? []],
|
|
15521
|
+
...impl.ext !== void 0 ? { ext: impl.ext } : {}
|
|
15522
|
+
};
|
|
15523
|
+
}
|
|
15524
|
+
function typeSection(t, keys) {
|
|
15525
|
+
const key = qualifiedTypeId(t);
|
|
15526
|
+
const owner = t.subsystem;
|
|
15527
|
+
return {
|
|
15528
|
+
key,
|
|
15529
|
+
kind: t.kind,
|
|
15530
|
+
name: t.name,
|
|
15531
|
+
...t.description !== void 0 ? { description: t.description } : {},
|
|
15532
|
+
fields: t.fields.map((f) => ({
|
|
15533
|
+
name: f.name,
|
|
15534
|
+
type: typeRef(f.type, "field", keys, owner),
|
|
15535
|
+
optional: f.optional === true,
|
|
15536
|
+
...f.description !== void 0 ? { description: f.description } : {},
|
|
15537
|
+
...f.key !== void 0 ? { key: f.key } : {},
|
|
15538
|
+
...f.references !== void 0 ? { references: keys.typeFieldRef(f.references, owner) } : {}
|
|
15539
|
+
})),
|
|
15540
|
+
methods: t.methods.map((m) => ({
|
|
15541
|
+
key: `${key}.${m.name}`,
|
|
15542
|
+
name: m.name,
|
|
15543
|
+
...m.description !== void 0 ? { description: m.description } : {},
|
|
15544
|
+
params: projectParams(m.params, "type-method-param", keys, owner),
|
|
15545
|
+
returns: typeRef(m.returns, "type-method-returns", keys, owner),
|
|
15546
|
+
signature: m.signature,
|
|
15547
|
+
guarantees: [],
|
|
15548
|
+
formerly: []
|
|
15549
|
+
})),
|
|
15550
|
+
params: t.kind === "signature" ? projectParams(t.params, "signature-param", keys, owner) : [],
|
|
15551
|
+
...t.kind === "signature" && t.returns !== void 0 ? { returns: typeRef(t.returns, "signature-returns", keys, owner) } : {},
|
|
15552
|
+
values: (t.values ?? []).map((v) => ({ ...v })),
|
|
15553
|
+
...t.holds !== void 0 ? { holds: t.holds } : {},
|
|
15554
|
+
invariants: (t.invariants ?? []).map((i) => ({ ...i })),
|
|
15555
|
+
...t.componentClass !== void 0 ? { componentClass: keys.componentRef(t.componentClass) } : {},
|
|
15556
|
+
...t.database !== void 0 ? { database: t.database } : {},
|
|
15557
|
+
...t.table !== void 0 ? { table: t.table } : {},
|
|
15558
|
+
...t.linkedEntity !== void 0 ? { linkedEntity: keys.typeKey(t.linkedEntity, owner) ?? keys.external(t.linkedEntity) } : {},
|
|
15559
|
+
formerly: [...t.previousIds ?? []],
|
|
15560
|
+
...t.ext !== void 0 ? { ext: t.ext } : {}
|
|
15561
|
+
};
|
|
15562
|
+
}
|
|
15563
|
+
function sortedKeys(value) {
|
|
15564
|
+
if (Array.isArray(value)) return value.map(sortedKeys);
|
|
15565
|
+
if (value && typeof value === "object") {
|
|
15566
|
+
const src = value;
|
|
15567
|
+
const out = {};
|
|
15568
|
+
for (const k of Object.keys(src).sort(compareOrdinal)) {
|
|
15569
|
+
if (src[k] !== void 0) out[k] = sortedKeys(src[k]);
|
|
15570
|
+
}
|
|
15571
|
+
return out;
|
|
15572
|
+
}
|
|
15573
|
+
return value;
|
|
15574
|
+
}
|
|
15575
|
+
function projectIdOf(system) {
|
|
15576
|
+
try {
|
|
15577
|
+
const config = loadProjectConfig();
|
|
15578
|
+
return (config ? effectiveProjectId(config) : null) ?? system.name;
|
|
15579
|
+
} catch {
|
|
15580
|
+
return system.name;
|
|
15581
|
+
}
|
|
15582
|
+
}
|
|
15583
|
+
function exportDesign(approval) {
|
|
15584
|
+
const system = loadSystemSpec();
|
|
15585
|
+
if (!system) throw new NoSystemSpecError();
|
|
15586
|
+
const subsystems = loadSubsystemSpecs().filter(isOwn);
|
|
15587
|
+
const components = loadComponentSpecs().filter(isOwn);
|
|
15588
|
+
const interfaces = loadInterfaceSpecs().filter(isOwn);
|
|
15589
|
+
const implementations = loadImplementationSpecs().filter(isOwn);
|
|
15590
|
+
const types = loadTypeSpecs().filter(isOwn);
|
|
15591
|
+
const projectTable = resolveProjectExports();
|
|
15592
|
+
const subsystemTables = new Map(subsystems.map((s) => [s.id, resolveSubsystemExports(s.id).entries]));
|
|
15593
|
+
const projectId = projectIdOf(system);
|
|
15594
|
+
const bindings = resolveDeclared();
|
|
15595
|
+
const members = directMembers(graph());
|
|
15596
|
+
let lock = null;
|
|
15597
|
+
try {
|
|
15598
|
+
lock = externalsRepository.readLock();
|
|
15599
|
+
} catch {
|
|
15600
|
+
lock = null;
|
|
15601
|
+
}
|
|
15602
|
+
const stateId = computeStateId();
|
|
15603
|
+
const state = approval ?? "unjudged";
|
|
15604
|
+
const source = {
|
|
15605
|
+
projectId,
|
|
15606
|
+
stateId: `${stateId.algorithm}:${stateId.digest}`,
|
|
15607
|
+
approval: state,
|
|
15608
|
+
approved: state === "locked"
|
|
15609
|
+
};
|
|
15610
|
+
const keys = new KeyTable(components, interfaces, types, members);
|
|
15611
|
+
const componentById = new Map(components.map((c) => [c.id, c]));
|
|
15612
|
+
const interfaceById = new Map(interfaces.map((i) => [i.id, i]));
|
|
15613
|
+
const ownerOf4 = (componentId) => componentId !== void 0 ? componentById.get(componentId)?.subsystem : void 0;
|
|
15614
|
+
const project = projectSection(system, projectTable.entries, keys);
|
|
15615
|
+
const subsystemSections = subsystems.map((s) => subsystemSection(s, subsystemTables.get(s.id) ?? [], keys)).sort(byKey);
|
|
15616
|
+
const componentSections = components.map((c) => componentSection(c, keys)).sort(byKey);
|
|
15617
|
+
const interfaceSections = interfaces.map((i) => interfaceSection(i, keys, ownerOf4(i.component))).sort(byKey);
|
|
15618
|
+
const implementationSections = implementations.map((impl) => {
|
|
15619
|
+
const contract = interfaceById.get(impl.contract);
|
|
15620
|
+
return implementationSection(impl, contract, contract ? componentById.get(contract.component) : void 0, keys);
|
|
15621
|
+
}).sort(byKey);
|
|
15622
|
+
const typeSections = types.map((t) => typeSection(t, keys)).sort(byKey);
|
|
15623
|
+
const externalAliases = new Set(bindings.map((b) => b.external.alias));
|
|
15624
|
+
const dependencies = [
|
|
15625
|
+
...bindings.map((b) => dependency(b, lock, keys)),
|
|
15626
|
+
...members.filter((m) => !externalAliases.has(m.alias)).map((m) => memberDependency(m, lock, keys))
|
|
15627
|
+
].sort((a, b) => compareOrdinal(a.alias, b.alias));
|
|
15628
|
+
const design = {
|
|
15629
|
+
format: DESIGN_FORMAT,
|
|
15630
|
+
formatVersion: DESIGN_FORMAT_VERSION,
|
|
15631
|
+
generator: WAIRON_VERSION,
|
|
15632
|
+
source,
|
|
15633
|
+
project,
|
|
15634
|
+
dependencies,
|
|
15635
|
+
subsystems: subsystemSections,
|
|
15636
|
+
components: componentSections,
|
|
15637
|
+
interfaces: interfaceSections,
|
|
15638
|
+
implementations: implementationSections,
|
|
15639
|
+
types: typeSections
|
|
15640
|
+
};
|
|
15641
|
+
return sortedKeys(design);
|
|
15642
|
+
}
|
|
15643
|
+
|
|
14942
15644
|
// src/core/surfaces.ts
|
|
14943
15645
|
var SURFACES_DIRNAME = "surfaces";
|
|
14944
15646
|
function surfacesDir(rootDir) {
|
|
14945
|
-
return
|
|
15647
|
+
return path14.join(rootDir, ".wai", SURFACES_DIRNAME);
|
|
14946
15648
|
}
|
|
14947
15649
|
function audienceRank(audience) {
|
|
14948
15650
|
const idx = SURFACE_AUDIENCES.indexOf(audience ?? "instance");
|
|
@@ -15021,7 +15723,7 @@ function boundProjectId() {
|
|
|
15021
15723
|
}
|
|
15022
15724
|
}
|
|
15023
15725
|
function contractEntry(entry, comp, interfaces) {
|
|
15024
|
-
const methods = interfaces.filter((i) => i.component === comp.id && (!entry.interface || i.id === entry.interface)).flatMap((i) => i.methods).map(({ signatureFrom: _source, ...method }) => method);
|
|
15726
|
+
const methods = interfaces.filter((i) => i.component === comp.id && (!entry.interface || i.id === entry.interface)).flatMap((i) => i.methods).map(({ signatureFrom: _source, previousNames: _trace, ...method }) => method);
|
|
15025
15727
|
return {
|
|
15026
15728
|
id: entry.publicName,
|
|
15027
15729
|
name: entry.name ?? comp.name,
|
|
@@ -15106,7 +15808,7 @@ function listSnapshots() {
|
|
|
15106
15808
|
for (const file of fs9.readdirSync(dir)) {
|
|
15107
15809
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
15108
15810
|
try {
|
|
15109
|
-
out.push(SurfaceSnapshotSchema.parse(readYamlFile(
|
|
15811
|
+
out.push(SurfaceSnapshotSchema.parse(readYamlFile(path14.join(dir, file))));
|
|
15110
15812
|
} catch {
|
|
15111
15813
|
}
|
|
15112
15814
|
}
|
|
@@ -15117,7 +15819,7 @@ function snapshotFilename(projectName) {
|
|
|
15117
15819
|
}
|
|
15118
15820
|
function removeSnapshot(projectName) {
|
|
15119
15821
|
const dir = surfacesDir(getProjectRoot());
|
|
15120
|
-
const direct =
|
|
15822
|
+
const direct = path14.join(dir, snapshotFilename(projectName));
|
|
15121
15823
|
if (fs9.existsSync(direct)) {
|
|
15122
15824
|
fs9.unlinkSync(direct);
|
|
15123
15825
|
return true;
|
|
@@ -15125,7 +15827,7 @@ function removeSnapshot(projectName) {
|
|
|
15125
15827
|
if (!fs9.existsSync(dir)) return false;
|
|
15126
15828
|
for (const file of fs9.readdirSync(dir)) {
|
|
15127
15829
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
15128
|
-
const p =
|
|
15830
|
+
const p = path14.join(dir, file);
|
|
15129
15831
|
try {
|
|
15130
15832
|
const snap = SurfaceSnapshotSchema.parse(readYamlFile(p));
|
|
15131
15833
|
if (snap.projectName === projectName) {
|
|
@@ -15164,6 +15866,32 @@ function listPinnedExternals() {
|
|
|
15164
15866
|
return { alias, project: entry.project, entry, snapshot };
|
|
15165
15867
|
});
|
|
15166
15868
|
}
|
|
15869
|
+
function withSortedKeys(value) {
|
|
15870
|
+
if (Array.isArray(value)) return value.map(withSortedKeys);
|
|
15871
|
+
if (value && typeof value === "object") {
|
|
15872
|
+
const src = value;
|
|
15873
|
+
const out = {};
|
|
15874
|
+
for (const k of Object.keys(src).sort(compareOrdinal)) if (src[k] !== void 0) out[k] = withSortedKeys(src[k]);
|
|
15875
|
+
return out;
|
|
15876
|
+
}
|
|
15877
|
+
return value;
|
|
15878
|
+
}
|
|
15879
|
+
function writeDesignTo(targetPath, design) {
|
|
15880
|
+
const resolved = path14.resolve(targetPath);
|
|
15881
|
+
try {
|
|
15882
|
+
fs9.mkdirSync(path14.dirname(resolved), { recursive: true });
|
|
15883
|
+
fs9.writeFileSync(resolved, `${JSON.stringify(withSortedKeys(design), null, 2)}
|
|
15884
|
+
`, "utf8");
|
|
15885
|
+
} catch (e) {
|
|
15886
|
+
throw new Error(`Cannot write the design export to ${resolved}: ${e.message}`);
|
|
15887
|
+
}
|
|
15888
|
+
return resolved;
|
|
15889
|
+
}
|
|
15890
|
+
function exportDesign2(outPath, approval) {
|
|
15891
|
+
const design = exportDesign(approval);
|
|
15892
|
+
if (outPath) writeDesignTo(outPath, design);
|
|
15893
|
+
return design;
|
|
15894
|
+
}
|
|
15167
15895
|
function listFamilyPins() {
|
|
15168
15896
|
const snapshots = listSnapshots();
|
|
15169
15897
|
const pins = snapshots.filter((snapshot) => snapshot.origin === "generated").map((snapshot) => ({
|
|
@@ -15182,8 +15910,8 @@ var UnknownExternalAliasError = class extends Error {
|
|
|
15182
15910
|
};
|
|
15183
15911
|
var OUT_OF_REACH = "its root is outside the request's reach";
|
|
15184
15912
|
function isWithinDir(dir, target) {
|
|
15185
|
-
const rel2 =
|
|
15186
|
-
return rel2 === "" || !rel2.startsWith("..") && !
|
|
15913
|
+
const rel2 = path14.relative(path14.resolve(dir), path14.resolve(target));
|
|
15914
|
+
return rel2 === "" || !rel2.startsWith("..") && !path14.isAbsolute(rel2);
|
|
15187
15915
|
}
|
|
15188
15916
|
function producerUnreadable(external) {
|
|
15189
15917
|
const directory = external.directory;
|
|
@@ -15436,6 +16164,9 @@ function listExternals() {
|
|
|
15436
16164
|
}
|
|
15437
16165
|
|
|
15438
16166
|
// src/core/surface-portal.ts
|
|
16167
|
+
function exportDesign3(outPath, approval) {
|
|
16168
|
+
return exportDesign2(outPath, approval);
|
|
16169
|
+
}
|
|
15439
16170
|
function listSnapshots2() {
|
|
15440
16171
|
return listSnapshots();
|
|
15441
16172
|
}
|
|
@@ -15469,7 +16200,7 @@ function pinnedParent2() {
|
|
|
15469
16200
|
|
|
15470
16201
|
// src/core/family-validation.ts
|
|
15471
16202
|
var fs10 = __toESM(require("fs"));
|
|
15472
|
-
var
|
|
16203
|
+
var path15 = __toESM(require("path"));
|
|
15473
16204
|
|
|
15474
16205
|
// src/models/pack-impact.ts
|
|
15475
16206
|
function packSettings(manifest, profile) {
|
|
@@ -15646,7 +16377,7 @@ function referencedOf(nodes) {
|
|
|
15646
16377
|
if (e.sourceKind === "hosted") {
|
|
15647
16378
|
const lookup2 = getHostedLookup();
|
|
15648
16379
|
const root = lookup2 && e.hosted !== void 0 ? lookup2(e.hosted) : null;
|
|
15649
|
-
if (root) directory =
|
|
16380
|
+
if (root) directory = path15.resolve(root);
|
|
15650
16381
|
else problem = lookup2 ? `the hosted member \`${e.hosted}\` is unknown or outside this request's reach` : `hosted-only member \`${e.hosted}\`: available only through the hosted server`;
|
|
15651
16382
|
}
|
|
15652
16383
|
if (directory !== void 0 && !fs10.existsSync(directory)) {
|
|
@@ -15710,7 +16441,7 @@ function notSelectedHint(left) {
|
|
|
15710
16441
|
}
|
|
15711
16442
|
function run(options) {
|
|
15712
16443
|
const family = graph();
|
|
15713
|
-
const root =
|
|
16444
|
+
const root = path15.resolve(getProjectRoot());
|
|
15714
16445
|
const ceiling = reachCeiling(root, options.family);
|
|
15715
16446
|
const selected = selectProjects(family, options);
|
|
15716
16447
|
const issues = [];
|
|
@@ -15930,7 +16661,7 @@ function pinOf(parent, alias, subject) {
|
|
|
15930
16661
|
}
|
|
15931
16662
|
function projectApprovals(depth) {
|
|
15932
16663
|
const family = graph();
|
|
15933
|
-
const root =
|
|
16664
|
+
const root = path15.resolve(getProjectRoot());
|
|
15934
16665
|
const limit = depth ?? Infinity;
|
|
15935
16666
|
const selected = family.nodes.filter((n) => depthOf(family, n) <= limit);
|
|
15936
16667
|
const directoryOf = new Map(family.nodes.map((n) => [n.namespace, n.directory]));
|
|
@@ -15983,7 +16714,7 @@ function projectApprovals(depth) {
|
|
|
15983
16714
|
function requiredBy(key) {
|
|
15984
16715
|
return key === "" ? "the family root" : `"${key}"`;
|
|
15985
16716
|
}
|
|
15986
|
-
function
|
|
16717
|
+
function requirementText2(requirement) {
|
|
15987
16718
|
return `"${requirement.pack}" ${requirement.version}${requirement.profile ? ` (profile "${requirement.profile}")` : ""}`;
|
|
15988
16719
|
}
|
|
15989
16720
|
function isBelow(family, node, ancestor) {
|
|
@@ -16038,7 +16769,7 @@ function judgeAdoption(requiring, member, requirements) {
|
|
|
16038
16769
|
const out = [];
|
|
16039
16770
|
const who = `The member ${named(member)}`;
|
|
16040
16771
|
for (const requirement of requirements) {
|
|
16041
|
-
const wanted = `${
|
|
16772
|
+
const wanted = `${requirementText2(requirement)}, required by ${requiredBy(requiring)}`;
|
|
16042
16773
|
const adopted = entryFor(config, loaded, requirement.pack);
|
|
16043
16774
|
if (!adopted) {
|
|
16044
16775
|
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));
|
|
@@ -16130,69 +16861,12 @@ var fs12 = __toESM(require("fs"));
|
|
|
16130
16861
|
var os3 = __toESM(require("os"));
|
|
16131
16862
|
var path17 = __toESM(require("path"));
|
|
16132
16863
|
var import_module = require("module");
|
|
16133
|
-
var
|
|
16864
|
+
var import_zod10 = require("zod");
|
|
16134
16865
|
|
|
16135
16866
|
// src/core/packstore.ts
|
|
16136
16867
|
var crypto3 = __toESM(require("crypto"));
|
|
16137
16868
|
var fs11 = __toESM(require("fs"));
|
|
16138
16869
|
var path16 = __toESM(require("path"));
|
|
16139
|
-
|
|
16140
|
-
// src/config/defaults.ts
|
|
16141
|
-
var os2 = __toESM(require("os"));
|
|
16142
|
-
var path15 = __toESM(require("path"));
|
|
16143
|
-
var DEFAULT_TARGET_DIRS = {
|
|
16144
|
-
claude: ".claude/agents",
|
|
16145
|
-
gemini: ".gemini/agents",
|
|
16146
|
-
agy: ".gemini/agents",
|
|
16147
|
-
cursor: ".cursor/rules",
|
|
16148
|
-
copilot: ".github/prompts",
|
|
16149
|
-
codex: ".codex/agents"
|
|
16150
|
-
};
|
|
16151
|
-
function defaultTargetConfig(type) {
|
|
16152
|
-
return {
|
|
16153
|
-
type,
|
|
16154
|
-
outputDir: DEFAULT_TARGET_DIRS[type],
|
|
16155
|
-
enabled: true
|
|
16156
|
-
};
|
|
16157
|
-
}
|
|
16158
|
-
var WAIRON_VERSION = "5.1.1-dev.97";
|
|
16159
|
-
var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
16160
|
-
var ARCHITECT_AGENT_ID = "agent-architect";
|
|
16161
|
-
var ARCHITECT_TEMPLATE_ID = "architect";
|
|
16162
|
-
function globalTemplatesDir(projectOverride) {
|
|
16163
|
-
if (process.env.WAIRON_TEMPLATES_DIR) {
|
|
16164
|
-
return process.env.WAIRON_TEMPLATES_DIR;
|
|
16165
|
-
}
|
|
16166
|
-
if (projectOverride) {
|
|
16167
|
-
return projectOverride;
|
|
16168
|
-
}
|
|
16169
|
-
return path15.join(os2.homedir(), ".wairon", "templates");
|
|
16170
|
-
}
|
|
16171
|
-
var BACKEND_COMMANDS = {
|
|
16172
|
-
claude: "claude",
|
|
16173
|
-
gemini: "gemini"
|
|
16174
|
-
};
|
|
16175
|
-
function backendCommand(backend) {
|
|
16176
|
-
return BACKEND_COMMANDS[backend] ?? backend;
|
|
16177
|
-
}
|
|
16178
|
-
var SUPPORTED_ALIASES = ["wai"];
|
|
16179
|
-
var SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
16180
|
-
"node_modules",
|
|
16181
|
-
"dist",
|
|
16182
|
-
"build",
|
|
16183
|
-
"out",
|
|
16184
|
-
".git",
|
|
16185
|
-
".cache",
|
|
16186
|
-
"coverage",
|
|
16187
|
-
"__pycache__",
|
|
16188
|
-
".venv",
|
|
16189
|
-
"venv",
|
|
16190
|
-
"target",
|
|
16191
|
-
// Rust
|
|
16192
|
-
"vendor"
|
|
16193
|
-
]);
|
|
16194
|
-
|
|
16195
|
-
// src/core/packstore.ts
|
|
16196
16870
|
var UNVERSIONED = "0.0.0-unversioned";
|
|
16197
16871
|
var INSTALL_RECORD = ".install.yaml";
|
|
16198
16872
|
var DIGEST_EXCLUDED = /* @__PURE__ */ new Set([INSTALL_RECORD, ".git", "node_modules", ".DS_Store"]);
|
|
@@ -16360,10 +17034,10 @@ function uninstallPack(name, version) {
|
|
|
16360
17034
|
}
|
|
16361
17035
|
|
|
16362
17036
|
// src/core/extensions.ts
|
|
16363
|
-
var ProfileDefSchema =
|
|
16364
|
-
family:
|
|
16365
|
-
forbiddenStereotypes:
|
|
16366
|
-
discouragedStereotypes:
|
|
17037
|
+
var ProfileDefSchema = import_zod10.z.object({
|
|
17038
|
+
family: import_zod10.z.enum(["backend-like", "frontend-like", "neutral"]).default("neutral"),
|
|
17039
|
+
forbiddenStereotypes: import_zod10.z.array(import_zod10.z.object({ types: import_zod10.z.array(import_zod10.z.string()).min(1), reason: import_zod10.z.string().min(1) })).default([]),
|
|
17040
|
+
discouragedStereotypes: import_zod10.z.array(import_zod10.z.object({ types: import_zod10.z.array(import_zod10.z.string()).min(1), reason: import_zod10.z.string().min(1) })).default([]),
|
|
16367
17041
|
/**
|
|
16368
17042
|
* Edge deltas — the ALLOW half of the profile-scoped dependency matrix. An
|
|
16369
17043
|
* entry LICENSES intra-subsystem dependsOn edges the builtin stereotype
|
|
@@ -16373,20 +17047,20 @@ var ProfileDefSchema = import_zod9.z.object({
|
|
|
16373
17047
|
* boundary rules and pattern containment are never relaxable. The DENY
|
|
16374
17048
|
* half is a `forbid-edge` declarative assertion.
|
|
16375
17049
|
*/
|
|
16376
|
-
allowedEdges:
|
|
16377
|
-
from:
|
|
16378
|
-
to:
|
|
16379
|
-
reason:
|
|
17050
|
+
allowedEdges: import_zod10.z.array(import_zod10.z.object({
|
|
17051
|
+
from: import_zod10.z.array(import_zod10.z.string().min(1)).min(1),
|
|
17052
|
+
to: import_zod10.z.array(import_zod10.z.string().min(1)).min(1),
|
|
17053
|
+
reason: import_zod10.z.string().min(1)
|
|
16380
17054
|
})).default([]),
|
|
16381
17055
|
rules: RulesConfigSchema.partial().optional()
|
|
16382
17056
|
});
|
|
16383
|
-
var LanguagePackDefSchema =
|
|
16384
|
-
unsupportedFlow:
|
|
16385
|
-
foreignBuiltins:
|
|
17057
|
+
var LanguagePackDefSchema = import_zod10.z.object({
|
|
17058
|
+
unsupportedFlow: import_zod10.z.record(import_zod10.z.string()).default({}),
|
|
17059
|
+
foreignBuiltins: import_zod10.z.array(import_zod10.z.string()).optional()
|
|
16386
17060
|
});
|
|
16387
|
-
var PackSkillSchema =
|
|
17061
|
+
var PackSkillSchema = import_zod10.z.object({
|
|
16388
17062
|
/** A NEW skill, installed namespaced as `<pack-id>-<id>`. Mutually exclusive with `extends`. */
|
|
16389
|
-
id:
|
|
17063
|
+
id: import_zod10.z.string().min(1).optional(),
|
|
16390
17064
|
/**
|
|
16391
17065
|
* EXTEND a builtin skill (`sdd-architect` | `sdd-narrative` | `sdd-auditor` |
|
|
16392
17066
|
* `sdd-implement`) instead of standing beside it.
|
|
@@ -16398,90 +17072,90 @@ var PackSkillSchema = import_zod9.z.object({
|
|
|
16398
17072
|
* appended under `## Platform: <pack>`; the builtin stays wairon's, so an
|
|
16399
17073
|
* upgrade still updates it.
|
|
16400
17074
|
*/
|
|
16401
|
-
extends:
|
|
16402
|
-
source:
|
|
16403
|
-
targets:
|
|
17075
|
+
extends: import_zod10.z.string().min(1).optional(),
|
|
17076
|
+
source: import_zod10.z.string().min(1),
|
|
17077
|
+
targets: import_zod10.z.array(import_zod10.z.string()).default([])
|
|
16404
17078
|
}).refine((s) => s.id === void 0 !== (s.extends === void 0), {
|
|
16405
17079
|
message: "a pack skill declares either `id` (a new skill) or `extends` (a section appended to a builtin), not both and not neither"
|
|
16406
17080
|
});
|
|
16407
|
-
var PackInstructionBlockSchema =
|
|
17081
|
+
var PackInstructionBlockSchema = import_zod10.z.union([
|
|
16408
17082
|
// Scalar shorthand: `instructions: >- …` — the common case, unscoped.
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
text:
|
|
16412
|
-
profile:
|
|
17083
|
+
import_zod10.z.string().min(1).transform((text3) => ({ text: text3 })),
|
|
17084
|
+
import_zod10.z.object({
|
|
17085
|
+
text: import_zod10.z.string().min(1),
|
|
17086
|
+
profile: import_zod10.z.array(import_zod10.z.string().min(1)).min(1).optional()
|
|
16413
17087
|
})
|
|
16414
17088
|
]);
|
|
16415
|
-
var PackInstructionsSchema =
|
|
17089
|
+
var PackInstructionsSchema = import_zod10.z.preprocess(
|
|
16416
17090
|
(raw) => raw === void 0 || raw === null ? [] : Array.isArray(raw) ? raw : [raw],
|
|
16417
|
-
|
|
17091
|
+
import_zod10.z.array(PackInstructionBlockSchema)
|
|
16418
17092
|
);
|
|
16419
|
-
var PatternDefSchema =
|
|
16420
|
-
id:
|
|
16421
|
-
version:
|
|
16422
|
-
description:
|
|
16423
|
-
metadata:
|
|
17093
|
+
var PatternDefSchema = import_zod10.z.object({
|
|
17094
|
+
id: import_zod10.z.string().min(1),
|
|
17095
|
+
version: import_zod10.z.string().min(1),
|
|
17096
|
+
description: import_zod10.z.string().optional(),
|
|
17097
|
+
metadata: import_zod10.z.record(import_zod10.z.unknown()).optional()
|
|
16424
17098
|
});
|
|
16425
|
-
var AssertionSelectorSchema =
|
|
16426
|
-
componentType:
|
|
16427
|
-
profile:
|
|
16428
|
-
id:
|
|
17099
|
+
var AssertionSelectorSchema = import_zod10.z.object({
|
|
17100
|
+
componentType: import_zod10.z.array(import_zod10.z.string().min(1)).optional(),
|
|
17101
|
+
profile: import_zod10.z.array(import_zod10.z.string().min(1)).optional(),
|
|
17102
|
+
id: import_zod10.z.string().min(1).optional()
|
|
16429
17103
|
});
|
|
16430
17104
|
var assertionBase = {
|
|
16431
17105
|
/** Pack-local code; surfaced namespaced as <PACK_NAME>_<CODE>. */
|
|
16432
|
-
code:
|
|
16433
|
-
severity:
|
|
17106
|
+
code: import_zod10.z.string().min(1),
|
|
17107
|
+
severity: import_zod10.z.enum(["warning", "error"]).default("warning"),
|
|
16434
17108
|
/** The doctrine, stated for the finding message. */
|
|
16435
|
-
reason:
|
|
17109
|
+
reason: import_zod10.z.string().min(1)
|
|
16436
17110
|
};
|
|
16437
|
-
var PackAssertionSchema =
|
|
16438
|
-
|
|
16439
|
-
kind:
|
|
17111
|
+
var PackAssertionSchema = import_zod10.z.discriminatedUnion("kind", [
|
|
17112
|
+
import_zod10.z.object({
|
|
17113
|
+
kind: import_zod10.z.literal("forbid-edge"),
|
|
16440
17114
|
...assertionBase,
|
|
16441
17115
|
from: AssertionSelectorSchema,
|
|
16442
17116
|
to: AssertionSelectorSchema,
|
|
16443
|
-
relation:
|
|
17117
|
+
relation: import_zod10.z.array(import_zod10.z.enum(["dependsOn", "owns"])).default(["dependsOn", "owns"])
|
|
16444
17118
|
}),
|
|
16445
|
-
|
|
16446
|
-
kind:
|
|
17119
|
+
import_zod10.z.object({
|
|
17120
|
+
kind: import_zod10.z.literal("require-field"),
|
|
16447
17121
|
...assertionBase,
|
|
16448
17122
|
on: AssertionSelectorSchema,
|
|
16449
|
-
level:
|
|
17123
|
+
level: import_zod10.z.enum(["component", "interface", "implementation"]).default("component"),
|
|
16450
17124
|
/** A top-level spec field name, or one `ext.*` path — nothing else is addressable. */
|
|
16451
|
-
field:
|
|
17125
|
+
field: import_zod10.z.string().min(1),
|
|
16452
17126
|
/** Optional closed value set (string equality). */
|
|
16453
|
-
values:
|
|
17127
|
+
values: import_zod10.z.array(import_zod10.z.string()).optional()
|
|
16454
17128
|
}),
|
|
16455
|
-
|
|
16456
|
-
kind:
|
|
17129
|
+
import_zod10.z.object({
|
|
17130
|
+
kind: import_zod10.z.literal("endpoint-shape"),
|
|
16457
17131
|
...assertionBase,
|
|
16458
17132
|
on: AssertionSelectorSchema,
|
|
16459
17133
|
/** Optional transport allowlist. */
|
|
16460
|
-
transport:
|
|
17134
|
+
transport: import_zod10.z.array(import_zod10.z.string().min(1)).optional(),
|
|
16461
17135
|
/** Optional anchored regex over the transport's address field (path/topic/command/…). */
|
|
16462
|
-
pathPattern:
|
|
17136
|
+
pathPattern: import_zod10.z.string().min(1).optional()
|
|
16463
17137
|
})
|
|
16464
17138
|
]);
|
|
16465
17139
|
function assertionFullCode(packName, code) {
|
|
16466
17140
|
const norm = (s) => s.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
16467
17141
|
return `${norm(packName)}_${norm(code)}`;
|
|
16468
17142
|
}
|
|
16469
|
-
var DeclarativePackSchema =
|
|
16470
|
-
name:
|
|
16471
|
-
version:
|
|
16472
|
-
profiles:
|
|
16473
|
-
languages:
|
|
16474
|
-
skills:
|
|
16475
|
-
patterns:
|
|
17143
|
+
var DeclarativePackSchema = import_zod10.z.object({
|
|
17144
|
+
name: import_zod10.z.string().min(1),
|
|
17145
|
+
version: import_zod10.z.string().optional(),
|
|
17146
|
+
profiles: import_zod10.z.record(ProfileDefSchema).default({}),
|
|
17147
|
+
languages: import_zod10.z.record(LanguagePackDefSchema).default({}),
|
|
17148
|
+
skills: import_zod10.z.array(PackSkillSchema).default([]),
|
|
17149
|
+
patterns: import_zod10.z.array(PatternDefSchema).default([]),
|
|
16476
17150
|
/** Declarative rule assertions — instances of closed kinds, hosted-safe. */
|
|
16477
|
-
assertions:
|
|
17151
|
+
assertions: import_zod10.z.array(PackAssertionSchema).default([]),
|
|
16478
17152
|
/**
|
|
16479
17153
|
* Semantic guarantee tokens this pack adds to the builtin vocabulary
|
|
16480
17154
|
* (SEMANTIC_GUARANTEES). Declaring a token makes it legal on L3 method
|
|
16481
17155
|
* `guarantees` and narrative `assertsGuarantees`; referenced tokens outside
|
|
16482
17156
|
* builtin + declared are flagged UNKNOWN_GUARANTEE by the validator.
|
|
16483
17157
|
*/
|
|
16484
|
-
guarantees:
|
|
17158
|
+
guarantees: import_zod10.z.array(import_zod10.z.string().min(1)).default([]),
|
|
16485
17159
|
/**
|
|
16486
17160
|
* Connecting-agent guidance appended to wairon's own MCP `initialize`
|
|
16487
17161
|
* instructions, attributed to this pack, in pack load order.
|
|
@@ -16496,7 +17170,7 @@ var DeclarativePackSchema = import_zod9.z.object({
|
|
|
16496
17170
|
* explicit in the new project's `project.yaml` where it is visible in review
|
|
16497
17171
|
* and removable — never silent authority over projects that never mentioned it.
|
|
16498
17172
|
*/
|
|
16499
|
-
applyByDefault:
|
|
17173
|
+
applyByDefault: import_zod10.z.boolean().default(false)
|
|
16500
17174
|
});
|
|
16501
17175
|
var EXTENDABLE_BUILTIN_SKILLS = ["sdd-architect", "sdd-narrative", "sdd-auditor", "sdd-implement", "sdd-delegate"];
|
|
16502
17176
|
function skillExtendErrors(skills) {
|
|
@@ -17916,6 +18590,66 @@ var namedScalarTypesRule = {
|
|
|
17916
18590
|
}
|
|
17917
18591
|
};
|
|
17918
18592
|
|
|
18593
|
+
// src/core/rules/integrity/rename-traces.ts
|
|
18594
|
+
var CODE = "RENAME_TRACE_CONFLICT";
|
|
18595
|
+
function namespaceOf(key) {
|
|
18596
|
+
const cut = key.lastIndexOf("::");
|
|
18597
|
+
return cut >= 0 ? key.slice(0, cut + 2) : "";
|
|
18598
|
+
}
|
|
18599
|
+
function judgeKind(ctx, noun, live, holders, qualify) {
|
|
18600
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
18601
|
+
for (const holder of holders) {
|
|
18602
|
+
for (const entry of holder.trace) {
|
|
18603
|
+
const key = qualify(entry, holder);
|
|
18604
|
+
const other = claimed.get(key);
|
|
18605
|
+
if (live.has(key) && key !== holder.key) {
|
|
18606
|
+
report(ctx, holder, `${holder.label} lists "${entry}" in its rename trace, but a live ${noun} has that key \u2014 a consumer of the design export would read the live ${noun} as this one renamed. Rename the newcomer, or unset the trace entry and accept that a consumer reads a delete plus an add.`);
|
|
18607
|
+
} else if (live.has(key)) {
|
|
18608
|
+
report(ctx, holder, `${holder.label} lists its own key "${entry}" in its rename trace \u2014 a rename never records the name it keeps. Unset the entry.`);
|
|
18609
|
+
} else if (other && other !== holder) {
|
|
18610
|
+
report(ctx, holder, `${holder.label} and ${other.label} both list "${entry}" in their rename traces \u2014 a consumer holding the old key cannot tell which one it became. Unset the entry on the one that was not renamed from it.`);
|
|
18611
|
+
}
|
|
18612
|
+
if (!other) claimed.set(key, holder);
|
|
18613
|
+
}
|
|
18614
|
+
}
|
|
18615
|
+
}
|
|
18616
|
+
function report(ctx, holder, message) {
|
|
18617
|
+
if (!ctx.isSpecInScope(holder.specId)) return;
|
|
18618
|
+
ctx.addIssue("warning", CODE, message, holder.specId);
|
|
18619
|
+
}
|
|
18620
|
+
var inNamespace = (entry, holder) => entry.includes("::") ? entry : namespaceOf(holder.key) + entry;
|
|
18621
|
+
var renameTracesRule = {
|
|
18622
|
+
name: "rename-traces",
|
|
18623
|
+
judges: "design",
|
|
18624
|
+
description: "A rename trace (a spec's previousIds, a contract method's previousNames) names keys that no longer exist, and is what lets a consumer of the design export tell a rename from a delete plus an add; it must therefore be unambiguous. Reported: a trace entry equal to a live key of the same kind (a component, interface or implementation id; a type id within the same owner; `<interface>.<method>` of a declared method), and one former key claimed by two elements of the same kind. The rename tools and the gated write refuse both (id-retired, name-retired), so a finding means a hand edit; the message names both holders and the way out \u2014 rename the newcomer, or unset the trace entry and accept the delete plus an add a consumer will read.",
|
|
18625
|
+
codes: [
|
|
18626
|
+
{ code: CODE, defaultSeverity: "warning", summary: "A rename-trace entry equals a live key of the same kind, or two elements claim one former key" }
|
|
18627
|
+
],
|
|
18628
|
+
check(ctx) {
|
|
18629
|
+
const specHolders = (specs, noun) => specs.filter((s) => s.previousIds?.length).map((s) => ({ key: s.id, specId: s.id, label: `${noun} "${s.id}"`, trace: s.previousIds }));
|
|
18630
|
+
judgeKind(ctx, "component", new Set(ctx.components.map((c) => c.id)), specHolders(ctx.components, "Component"), inNamespace);
|
|
18631
|
+
judgeKind(ctx, "interface", new Set(ctx.interfaces.map((i) => i.id)), specHolders(ctx.interfaces, "Interface"), inNamespace);
|
|
18632
|
+
judgeKind(ctx, "implementation", new Set(ctx.implementations.map((i) => i.id)), specHolders(ctx.implementations, "Implementation"), inNamespace);
|
|
18633
|
+
judgeKind(
|
|
18634
|
+
ctx,
|
|
18635
|
+
"type",
|
|
18636
|
+
new Set(ctx.types.map((t) => qualifiedTypeId(t))),
|
|
18637
|
+
ctx.types.filter((t) => t.previousIds?.length).map((t) => ({ key: qualifiedTypeId(t), specId: t.id, label: `Type "${qualifiedTypeId(t)}"`, trace: t.previousIds })),
|
|
18638
|
+
inNamespace
|
|
18639
|
+
);
|
|
18640
|
+
const methodHolders = [];
|
|
18641
|
+
const liveMethods = /* @__PURE__ */ new Set();
|
|
18642
|
+
for (const intf of ctx.interfaces) {
|
|
18643
|
+
for (const m of intf.methods) {
|
|
18644
|
+
const key = `${intf.id}.${m.name}`;
|
|
18645
|
+
liveMethods.add(key);
|
|
18646
|
+
if (m.previousNames?.length) methodHolders.push({ key, specId: intf.id, label: `Method "${key}"`, trace: m.previousNames });
|
|
18647
|
+
}
|
|
18648
|
+
}
|
|
18649
|
+
judgeKind(ctx, "contract method", liveMethods, methodHolders, inNamespace);
|
|
18650
|
+
}
|
|
18651
|
+
};
|
|
18652
|
+
|
|
17919
18653
|
// src/core/rules/integrity/public-surface-binding.ts
|
|
17920
18654
|
var publicSurfaceBindingRule = {
|
|
17921
18655
|
name: "public-surface-binding",
|
|
@@ -18504,12 +19238,12 @@ var contractSymmetryRule = {
|
|
|
18504
19238
|
);
|
|
18505
19239
|
}
|
|
18506
19240
|
}
|
|
18507
|
-
for (const
|
|
18508
|
-
if (!implMethodNames.has(
|
|
19241
|
+
for (const contractMethod2 of contract.methods) {
|
|
19242
|
+
if (!implMethodNames.has(contractMethod2.name)) {
|
|
18509
19243
|
ctx.addIssue(
|
|
18510
19244
|
"error",
|
|
18511
19245
|
"MISSING_IMPLEMENTATION_METHOD",
|
|
18512
|
-
`Implementation "${impl.id}" is missing implementation for contract method "${
|
|
19246
|
+
`Implementation "${impl.id}" is missing implementation for contract method "${contractMethod2.name}" from interface "${contract.id}".`,
|
|
18513
19247
|
impl.id,
|
|
18514
19248
|
isDraftCtx
|
|
18515
19249
|
);
|
|
@@ -19309,8 +20043,8 @@ var narrativeDetailRule = {
|
|
|
19309
20043
|
const component = ctx.componentMap.get(contract.component);
|
|
19310
20044
|
const isDraftCtx = ctx.isImplementationDraft(impl);
|
|
19311
20045
|
for (const implMethod of impl.methods) {
|
|
19312
|
-
const
|
|
19313
|
-
if (!
|
|
20046
|
+
const contractMethod2 = contract.methods.find((m) => m.name === implMethod.name);
|
|
20047
|
+
if (!contractMethod2) continue;
|
|
19314
20048
|
if (implMethod.narrative.length > 0) continue;
|
|
19315
20049
|
const eff = effectiveDetail(implMethod, impl, component);
|
|
19316
20050
|
if (eff.level === "full") {
|
|
@@ -19323,7 +20057,7 @@ var narrativeDetailRule = {
|
|
|
19323
20057
|
);
|
|
19324
20058
|
continue;
|
|
19325
20059
|
}
|
|
19326
|
-
const prose = implMethod.intent ??
|
|
20060
|
+
const prose = implMethod.intent ?? contractMethod2.description;
|
|
19327
20061
|
if (!passesIntentFloor(prose, implMethod.name)) {
|
|
19328
20062
|
ctx.addIssue(
|
|
19329
20063
|
eff.explicit ? "error" : "warning",
|
|
@@ -21765,10 +22499,10 @@ function familyAliases(family) {
|
|
|
21765
22499
|
}
|
|
21766
22500
|
return out;
|
|
21767
22501
|
}
|
|
21768
|
-
function typeRefReadings(
|
|
21769
|
-
const [first, ...rest] =
|
|
21770
|
-
if (!rest.length) return [
|
|
21771
|
-
return [
|
|
22502
|
+
function typeRefReadings(typeRef2, aliases) {
|
|
22503
|
+
const [first, ...rest] = typeRef2.split(/::|\./);
|
|
22504
|
+
if (!rest.length) return [typeRef2];
|
|
22505
|
+
return [typeRef2, ...(aliases.get(first) ?? []).map((key) => `${key}::${rest.join("::")}`)];
|
|
21772
22506
|
}
|
|
21773
22507
|
function resolveInvariantRef(ref, types, aliases = /* @__PURE__ */ new Map()) {
|
|
21774
22508
|
const parts = splitInvariantRef(ref);
|
|
@@ -23238,8 +23972,8 @@ var asyncConformanceRule = {
|
|
|
23238
23972
|
check(ctx) {
|
|
23239
23973
|
const code = ctx.codeIndex();
|
|
23240
23974
|
for (const { implementation, method, sourceFile, draftContext: draftContext4 } of ctx.implementationMethods()) {
|
|
23241
|
-
const
|
|
23242
|
-
if (!
|
|
23975
|
+
const contractMethod2 = ctx.interfaceMap.get(implementation.contract)?.methods.find((m) => m.name === method.name);
|
|
23976
|
+
if (!contractMethod2 || typeof contractMethod2.returns !== "string" || !sourceFile) continue;
|
|
23243
23977
|
const file = pathKey(sourceFile);
|
|
23244
23978
|
const facts = code.factsAt(file);
|
|
23245
23979
|
if (!facts || facts.status !== "analyzed" || facts.analysisGrade !== "exact") continue;
|
|
@@ -23248,7 +23982,7 @@ var asyncConformanceRule = {
|
|
|
23248
23982
|
if (!signatures || !Object.prototype.hasOwnProperty.call(signatures, symbol)) continue;
|
|
23249
23983
|
const bodies = signatures[symbol].length;
|
|
23250
23984
|
if (bodies === 0) continue;
|
|
23251
|
-
const returns = parseTypeExpression(
|
|
23985
|
+
const returns = parseTypeExpression(contractMethod2.returns, "returns");
|
|
23252
23986
|
if (!returns.expression) continue;
|
|
23253
23987
|
const contractAsync = returns.expression.form === "async";
|
|
23254
23988
|
const asyncBodies = (facts.asyncFunctions ?? []).filter((name) => name === symbol).length;
|
|
@@ -23257,7 +23991,7 @@ var asyncConformanceRule = {
|
|
|
23257
23991
|
ctx.addIssue(
|
|
23258
23992
|
"warning",
|
|
23259
23993
|
"ASYNC_MISMATCH",
|
|
23260
|
-
`Method "${method.name}" of contract "${implementation.contract}" returns "${
|
|
23994
|
+
`Method "${method.name}" of contract "${implementation.contract}" returns "${contractMethod2.returns}", which completes later, but ${subject} completes now \u2014 it is neither declared async nor annotated to return a Promise. Every caller is told to await a call that answers at once. Make the code async, or drop \`async\` from the returns.`,
|
|
23261
23995
|
implementation.id,
|
|
23262
23996
|
draftContext4,
|
|
23263
23997
|
void 0,
|
|
@@ -23267,7 +24001,7 @@ var asyncConformanceRule = {
|
|
|
23267
24001
|
ctx.addIssue(
|
|
23268
24002
|
"warning",
|
|
23269
24003
|
"ASYNC_MISMATCH",
|
|
23270
|
-
`Method "${method.name}" of contract "${implementation.contract}" returns "${
|
|
24004
|
+
`Method "${method.name}" of contract "${implementation.contract}" returns "${contractMethod2.returns}", which completes now, but ${subject} completes later (declared async, or annotated to return a Promise). Every caller built from the contract forgets to await it. Write the returns as "async ${contractMethod2.returns}" \u2014 or, if the code is async by accident, make it complete now.`,
|
|
23271
24005
|
implementation.id,
|
|
23272
24006
|
draftContext4,
|
|
23273
24007
|
void 0,
|
|
@@ -24812,6 +25546,8 @@ var SDD_RULES = [
|
|
|
24812
25546
|
typeExpressionsRule,
|
|
24813
25547
|
enumTypesRule,
|
|
24814
25548
|
namedScalarTypesRule,
|
|
25549
|
+
// The rename traces: a former key a consumer resolves must name one element.
|
|
25550
|
+
renameTracesRule,
|
|
24815
25551
|
// Contracts and the targets narratives name, in four questions with one
|
|
24816
25552
|
// owner each: does the implementation mirror its contract, does a target
|
|
24817
25553
|
// inside this tree resolve, does a target that leaves it pin to exactly one
|
|
@@ -26918,12 +27654,12 @@ function measure(candidate) {
|
|
|
26918
27654
|
// src/core/rules/gate-identity.ts
|
|
26919
27655
|
var crypto4 = __toESM(require("crypto"));
|
|
26920
27656
|
var GATE_ALGORITHM = "sha256+content+doctrine+inputs+members";
|
|
26921
|
-
var
|
|
27657
|
+
var byKey2 = (items, key) => [...items].sort((a, b) => compareOrdinal(key(a), key(b)));
|
|
26922
27658
|
function ruleIdentities(rules) {
|
|
26923
|
-
return
|
|
27659
|
+
return byKey2(
|
|
26924
27660
|
rules.map((r) => ({
|
|
26925
27661
|
name: r.name,
|
|
26926
|
-
codes:
|
|
27662
|
+
codes: byKey2(r.codes.map((c) => ({ code: c.code, severity: c.defaultSeverity })), (c) => c.code)
|
|
26927
27663
|
})),
|
|
26928
27664
|
(r) => r.name
|
|
26929
27665
|
);
|
|
@@ -26971,7 +27707,7 @@ function doctrineIdentity(doctrine2, builtinRules, gate) {
|
|
|
26971
27707
|
* changed requirement stales the requiring project's lock.
|
|
26972
27708
|
*/
|
|
26973
27709
|
composition: gate.composition ?? null,
|
|
26974
|
-
packs:
|
|
27710
|
+
packs: byKey2(
|
|
26975
27711
|
doctrine2.packs.map((p) => ({ name: p.name, version: p.version ?? null, scope: p.scope })),
|
|
26976
27712
|
(p) => `${p.name}@${p.version ?? ""}#${p.scope}`
|
|
26977
27713
|
),
|
|
@@ -26979,13 +27715,13 @@ function doctrineIdentity(doctrine2, builtinRules, gate) {
|
|
|
26979
27715
|
// the identity — a load-order change that flips a collision winner shows up here.
|
|
26980
27716
|
profiles: doctrine2.profiles,
|
|
26981
27717
|
languages: doctrine2.languages,
|
|
26982
|
-
patterns:
|
|
27718
|
+
patterns: byKey2(
|
|
26983
27719
|
doctrine2.patterns.map((p) => ({ id: p.id, version: p.version, pack: p.pack })),
|
|
26984
27720
|
(p) => `${p.pack}/${p.id}@${p.version}`
|
|
26985
27721
|
),
|
|
26986
27722
|
guarantees: [...doctrine2.guarantees].sort(),
|
|
26987
|
-
assertions:
|
|
26988
|
-
rules:
|
|
27723
|
+
assertions: byKey2(doctrine2.assertions.map((a) => ({ ...a })), (a) => a.fullCode),
|
|
27724
|
+
rules: byKey2(
|
|
26989
27725
|
doctrine2.rules.map((r) => ({ name: r.name, codes: r.codes.map((c) => c.code).sort() })),
|
|
26990
27726
|
(r) => r.name
|
|
26991
27727
|
)
|
|
@@ -26996,7 +27732,7 @@ function computeGateIdentity(content, doctrine2, builtinRules, inputs, gate, mem
|
|
|
26996
27732
|
content: content.digest,
|
|
26997
27733
|
doctrine: doctrineIdentity(doctrine2, builtinRules, gate),
|
|
26998
27734
|
inputs: [...inputs].sort(compareOrdinal),
|
|
26999
|
-
members:
|
|
27735
|
+
members: byKey2(Object.entries(members), ([alias]) => alias).map(([alias, subject]) => ({ alias, subject }))
|
|
27000
27736
|
};
|
|
27001
27737
|
const digest3 = crypto4.createHash("sha256").update(canonicalize(payload)).digest("hex");
|
|
27002
27738
|
return { algorithm: GATE_ALGORITHM, digest: digest3 };
|
|
@@ -27341,8 +28077,8 @@ function judgePartAlone(config, scopeSubsystem) {
|
|
|
27341
28077
|
issues.push(issue("warning", "EXTERNAL_CHECK_UNAVAILABLE", `The parent "${parentId}" governs its parts with a pack this machine cannot load at its pinned version, so its rules were not run here: ${failure}`));
|
|
27342
28078
|
}
|
|
27343
28079
|
const ownIds = new Set([...own.subsystems, ...own.components, ...own.interfaces, ...own.implementations, ...own.types].map((s) => s.id));
|
|
27344
|
-
const
|
|
27345
|
-
issues.push(...getLoaderIssues().filter((e) => !e.specId ||
|
|
28080
|
+
const isOwn2 = (id) => ownIds.has(id);
|
|
28081
|
+
issues.push(...getLoaderIssues().filter((e) => !e.specId || isOwn2(e.specId)));
|
|
27346
28082
|
for (const [key, by] of namedKeys(own)) {
|
|
27347
28083
|
if (ownIds.has(key) || context.ids.has(key)) continue;
|
|
27348
28084
|
issues.push(issue("warning", "EXTERNAL_CHECK_UNAVAILABLE", `"${by}" names "${key}", which neither this part nor its pinned excerpt of "${parentId}" holds \u2014 used since the pin: re-pin with \`wairon externals pin\` while the parent is on disk.`, by));
|
|
@@ -27350,8 +28086,8 @@ function judgePartAlone(config, scopeSubsystem) {
|
|
|
27350
28086
|
const ownSignatures = signatureFacts();
|
|
27351
28087
|
const ownTypeSpellings = typeSpellingFacts();
|
|
27352
28088
|
const partTypeSpellings = {
|
|
27353
|
-
respellings: ownTypeSpellings.respellings.filter((r) =>
|
|
27354
|
-
problems: ownTypeSpellings.problems.filter((p) => p.specId === void 0 ||
|
|
28089
|
+
respellings: ownTypeSpellings.respellings.filter((r) => isOwn2(r.specId)),
|
|
28090
|
+
problems: ownTypeSpellings.problems.filter((p) => p.specId === void 0 || isOwn2(p.specId))
|
|
27355
28091
|
};
|
|
27356
28092
|
const resolved = resolveSignatures(
|
|
27357
28093
|
[...own.interfaces, ...context.interfaces],
|
|
@@ -27398,7 +28134,7 @@ function judgePartAlone(config, scopeSubsystem) {
|
|
|
27398
28134
|
packRequirements: [],
|
|
27399
28135
|
surfaceSnapshots: [],
|
|
27400
28136
|
codeModel,
|
|
27401
|
-
roundTripIssues: dryRunSerializeSpecs(
|
|
28137
|
+
roundTripIssues: dryRunSerializeSpecs(isOwn2),
|
|
27402
28138
|
knownIssueCodes: knownCodes,
|
|
27403
28139
|
carryableIssueCodes: new Set(knownIssueCodes().filter((rc) => rc.carryable).map((rc) => rc.code)),
|
|
27404
28140
|
issues
|
|
@@ -28431,10 +29167,10 @@ function settle(owner, level, candidates, problems) {
|
|
|
28431
29167
|
detail: `"${name}" is bound to ${targets.length} different targets (${targets.join(", ")}) by ${explicit.length ? "explicit entries" : "wildcard re-exports"}; it is left out of the table`
|
|
28432
29168
|
});
|
|
28433
29169
|
}
|
|
28434
|
-
const
|
|
28435
|
-
for (const e of entries)
|
|
29170
|
+
const byKey3 = /* @__PURE__ */ new Map();
|
|
29171
|
+
for (const e of entries) byKey3.set(nameKey(e.publicName), [...byKey3.get(nameKey(e.publicName)) ?? [], e]);
|
|
28436
29172
|
const clashing = /* @__PURE__ */ new Set();
|
|
28437
|
-
for (const group of
|
|
29173
|
+
for (const group of byKey3.values()) {
|
|
28438
29174
|
const targets = [...new Set(group.map((e) => exportTargetKey(e)))];
|
|
28439
29175
|
if (group.length < 2 || targets.length < 2) continue;
|
|
28440
29176
|
group.forEach((e) => clashing.add(e));
|
|
@@ -28752,7 +29488,7 @@ function pinnedUsageOf(consumer, alias) {
|
|
|
28752
29488
|
function emptySignatureFacts() {
|
|
28753
29489
|
return { sources: [], staleTexts: [] };
|
|
28754
29490
|
}
|
|
28755
|
-
function
|
|
29491
|
+
function namespaceOf2(key) {
|
|
28756
29492
|
const at = key.lastIndexOf("::");
|
|
28757
29493
|
return at === -1 ? "" : key.slice(0, at);
|
|
28758
29494
|
}
|
|
@@ -28780,7 +29516,7 @@ function methodReading(tables, intf, value) {
|
|
|
28780
29516
|
if (dot <= 0 || dot === value.length - 1) return null;
|
|
28781
29517
|
const head2 = value.slice(0, dot);
|
|
28782
29518
|
const tail = value.slice(dot + 1);
|
|
28783
|
-
const ns =
|
|
29519
|
+
const ns = namespaceOf2(intf.id);
|
|
28784
29520
|
const keys = [head2, ...ns && !head2.startsWith(`${ns}::`) ? [`${ns}::${head2}`] : []];
|
|
28785
29521
|
for (const key of keys) {
|
|
28786
29522
|
if (!tables.componentKeys.has(key)) continue;
|
|
@@ -28792,8 +29528,8 @@ function methodReading(tables, intf, value) {
|
|
|
28792
29528
|
function typeReading(tables, intf, value) {
|
|
28793
29529
|
const bound2 = value.includes("::") ? tables.boundTypes.get(`${intf.id}|${value}`) : void 0;
|
|
28794
29530
|
const named2 = bound2 !== void 0 ? tables.types.filter((t) => t.id === bound2) : tables.types.filter((t) => t.id === value || typeMatchesRef(t, value));
|
|
28795
|
-
const ns =
|
|
28796
|
-
const local = (t) =>
|
|
29531
|
+
const ns = namespaceOf2(intf.id);
|
|
29532
|
+
const local = (t) => namespaceOf2(t.id) === ns ? 0 : 1;
|
|
28797
29533
|
const ranked = [...named2].sort((a, b) => local(a) - local(b));
|
|
28798
29534
|
return { signature: ranked.find((t) => t.kind === "signature"), other: ranked.find((t) => t.kind !== "signature") };
|
|
28799
29535
|
}
|
|
@@ -29546,7 +30282,7 @@ function keyedSystem(system, key, subsystems) {
|
|
|
29546
30282
|
};
|
|
29547
30283
|
}
|
|
29548
30284
|
function resolveFamilyTables(raws) {
|
|
29549
|
-
const
|
|
30285
|
+
const byKey3 = new Map(raws.map((r) => [r.record.namespace, r]));
|
|
29550
30286
|
const done = /* @__PURE__ */ new Set();
|
|
29551
30287
|
const resolving = /* @__PURE__ */ new Set();
|
|
29552
30288
|
const resolve41 = (raw) => {
|
|
@@ -29563,7 +30299,7 @@ function resolveFamilyTables(raws) {
|
|
|
29563
30299
|
const source = e.from ?? e.subsystem;
|
|
29564
30300
|
const producerKey = source !== void 0 ? raw.record.aliases.get(source) : void 0;
|
|
29565
30301
|
if (producerKey === void 0 || producerTables.has(producerKey)) continue;
|
|
29566
|
-
const producer =
|
|
30302
|
+
const producer = byKey3.get(producerKey);
|
|
29567
30303
|
producerTables.set(producerKey, producer ? resolve41(producer) : null);
|
|
29568
30304
|
audienceOf.set(producerKey, "project");
|
|
29569
30305
|
}
|
|
@@ -33249,6 +33985,14 @@ var SpecWorkspace = class {
|
|
|
33249
33985
|
}
|
|
33250
33986
|
const receiving = this.moveTargetContract(to, ofTarget);
|
|
33251
33987
|
if (typeof receiving === "string") return receiving;
|
|
33988
|
+
if (receiving) {
|
|
33989
|
+
for (const name of methods) {
|
|
33990
|
+
const holder2 = receiving.methods.find((m) => (m.previousNames ?? []).includes(`${receiving.id}.${name}`));
|
|
33991
|
+
if (holder2) {
|
|
33992
|
+
return `name-retired: "${receiving.id}" retired the name "${name}" \u2014 its method "${holder2.name}" lists "${receiving.id}.${name}" in its previousNames. Unsetting that previousNames releases the name.`;
|
|
33993
|
+
}
|
|
33994
|
+
}
|
|
33995
|
+
}
|
|
33252
33996
|
const contractId = receiving?.id ?? `i${to}`;
|
|
33253
33997
|
const holder = contracts.find((i) => i.id === contractId);
|
|
33254
33998
|
if (!receiving && holder) {
|
|
@@ -33302,7 +34046,7 @@ var SpecWorkspace = class {
|
|
|
33302
34046
|
for (const contract of contracts.filter((i) => i.component === source.id)) {
|
|
33303
34047
|
const leaving = contract.methods.filter((m) => methods.includes(m.name));
|
|
33304
34048
|
if (leaving.length === 0) continue;
|
|
33305
|
-
arriving.push(...cloneSpec(leaving));
|
|
34049
|
+
arriving.push(...cloneSpec(leaving).map((m) => ({ ...m, previousNames: [...m.previousNames ?? [], `${contract.id}.${m.name}`] })));
|
|
33306
34050
|
const remaining = cloneSpec(contract);
|
|
33307
34051
|
remaining.methods = remaining.methods.filter((m) => !methods.includes(m.name));
|
|
33308
34052
|
this.stageMoveEdit(plan6, "interface", contract.id, contract, remaining);
|
|
@@ -33485,9 +34229,9 @@ var SpecWorkspace = class {
|
|
|
33485
34229
|
const reports = moveChangeReports(edits, false);
|
|
33486
34230
|
const written = [];
|
|
33487
34231
|
try {
|
|
33488
|
-
for (const
|
|
33489
|
-
const edit4 = edits.find((e) => e.kind ===
|
|
33490
|
-
|
|
34232
|
+
for (const report3 of reports) {
|
|
34233
|
+
const edit4 = edits.find((e) => e.kind === report3.kind && e.id === report3.id);
|
|
34234
|
+
report3.notices.push(...this.saveMovedSpec(edit4.kind, edit4.after));
|
|
33491
34235
|
written.push(edit4);
|
|
33492
34236
|
}
|
|
33493
34237
|
finish?.();
|
|
@@ -33728,6 +34472,9 @@ function getInterfacePath(id, componentId) {
|
|
|
33728
34472
|
function getImplementationPath(id, contractId) {
|
|
33729
34473
|
return current().getImplementationPath(id, contractId);
|
|
33730
34474
|
}
|
|
34475
|
+
function getTypePath(id, subsystemId, group) {
|
|
34476
|
+
return current().getTypePath(id, subsystemId, group);
|
|
34477
|
+
}
|
|
33731
34478
|
function loadSystemSpec() {
|
|
33732
34479
|
return current().loadSystemSpec();
|
|
33733
34480
|
}
|
|
@@ -35640,6 +36387,11 @@ function renameComponent(componentId, newId) {
|
|
|
35640
36387
|
if (taken.length > 0) {
|
|
35641
36388
|
throw new WaironError(`id-taken: the new id, or an id it implies, is already in use: ${taken.join(", ")}.`);
|
|
35642
36389
|
}
|
|
36390
|
+
refuseRetiredIds([
|
|
36391
|
+
{ kind: "component", id: newId },
|
|
36392
|
+
{ kind: "interface", id: interfaceId },
|
|
36393
|
+
{ kind: "implementation", id: implementationId }
|
|
36394
|
+
]);
|
|
35643
36395
|
const contracts = interfaces.filter((i) => i.component === componentId);
|
|
35644
36396
|
const movingInterface = contracts.find((i) => i.id === `i${componentId}`);
|
|
35645
36397
|
const movingImplementation = implementations.find((impl) => impl.id === `${componentId}_impl` && contracts.some((i) => i.id === impl.contract));
|
|
@@ -35661,18 +36413,21 @@ function renameComponent(componentId, newId) {
|
|
|
35661
36413
|
return ref;
|
|
35662
36414
|
};
|
|
35663
36415
|
const specsDir = aiPathsAt(getProjectRoot()).specsDir();
|
|
36416
|
+
const derivesName = (entry) => entry.interface !== void 0 ? movingInterface !== void 0 && entry.interface === movingInterface.id : entry.typeDef === void 0 && entry.component === componentId;
|
|
36417
|
+
const keptDry = keepPublicNames(specsDir, derivesName, true);
|
|
35664
36418
|
assertSpecsInReach(
|
|
35665
|
-
[...renamed.map(({ kind, from }) => ({ kind, id: from })), ...rewriteRefFields(specsDir, remap, void 0, true), ...rekeyLintAllows(specsDir, rename, true)],
|
|
36419
|
+
[...renamed.map(({ kind, from }) => ({ kind, id: from })), ...keptDry.specs, ...rewriteRefFields(specsDir, remap, void 0, true), ...rekeyLintAllows(specsDir, rename, true)],
|
|
35666
36420
|
`renaming component "${componentId}"`,
|
|
35667
36421
|
Array.isArray(registerEdits) && registerEdits.length > 0
|
|
35668
36422
|
);
|
|
35669
|
-
const
|
|
36423
|
+
const kept = keepPublicNames(specsDir, derivesName);
|
|
36424
|
+
const rewrittenRefs = [...kept.specs, ...rewriteRefFields(specsDir, remap)];
|
|
35670
36425
|
const allowsRekeyed = rekeyLintAllows(specsDir, rename);
|
|
35671
36426
|
const rewritten = [...new Set([...rewrittenRefs, ...allowsRekeyed].filter((spec) => !renamed.some((moved) => moved.kind === spec.kind && moved.from === spec.id)).map((spec) => spec.id))];
|
|
35672
36427
|
invalidateSpecCache();
|
|
35673
36428
|
moveRenamedSpecs(componentId, newId, component, movingInterface, movingImplementation);
|
|
35674
36429
|
const carried = projectConfigRepository.rekeyCarried(rename);
|
|
35675
|
-
return { renamed, rewritten, carried };
|
|
36430
|
+
return { renamed, rewritten, carried, keptPublicNames: kept.names };
|
|
35676
36431
|
}
|
|
35677
36432
|
function moveRenamedSpecs(componentId, newId, component, movingInterface, movingImplementation) {
|
|
35678
36433
|
const interfaceId = `i${newId}`;
|
|
@@ -35680,20 +36435,69 @@ function moveRenamedSpecs(componentId, newId, component, movingInterface, moving
|
|
|
35680
36435
|
const movedComponent2 = loadComponentSpec(componentId) ?? component;
|
|
35681
36436
|
const movedInterface = movingInterface ? loadInterfaceSpec(movingInterface.id) ?? movingInterface : null;
|
|
35682
36437
|
const movedImplementation = movingImplementation ? loadImplementationSpec(movingImplementation.id) ?? movingImplementation : null;
|
|
35683
|
-
saveComponentSpec({ ...movedComponent2, id: newId });
|
|
35684
|
-
if (movedInterface)
|
|
36438
|
+
saveComponentSpec({ ...movedComponent2, id: newId, previousIds: traced(movedComponent2.previousIds, componentId) });
|
|
36439
|
+
if (movedInterface) {
|
|
36440
|
+
saveInterfaceSpec({ ...movedInterface, id: interfaceId, component: newId, previousIds: traced(movedInterface.previousIds, movedInterface.id) });
|
|
36441
|
+
}
|
|
35685
36442
|
if (movedImplementation) {
|
|
35686
36443
|
const oldFile = getImplementationPath(movedImplementation.id);
|
|
35687
36444
|
if (path25.resolve(getImplementationPath(implementationId, movedImplementation.contract)) === path25.resolve(oldFile)) {
|
|
35688
36445
|
fs16.unlinkSync(oldFile);
|
|
35689
36446
|
}
|
|
35690
|
-
saveImplementationSpec({ ...movedImplementation, id: implementationId });
|
|
36447
|
+
saveImplementationSpec({ ...movedImplementation, id: implementationId, previousIds: traced(movedImplementation.previousIds, movedImplementation.id) });
|
|
35691
36448
|
}
|
|
35692
36449
|
removeSpecFile2(getComponentPath(componentId), componentId);
|
|
35693
36450
|
if (movingInterface) removeSpecFile2(getInterfacePath(movingInterface.id), movingInterface.id);
|
|
35694
36451
|
if (movingImplementation) removeSpecFile2(getImplementationPath(movingImplementation.id), movingImplementation.id);
|
|
35695
36452
|
invalidateSpecCache();
|
|
35696
36453
|
}
|
|
36454
|
+
function traced(trace, former) {
|
|
36455
|
+
const out = [...trace ?? []];
|
|
36456
|
+
if (!out.includes(former)) out.push(former);
|
|
36457
|
+
return out;
|
|
36458
|
+
}
|
|
36459
|
+
function refuseRetiredIds(wanted) {
|
|
36460
|
+
const index = scanAllSpecs({ memberDepth: 0 });
|
|
36461
|
+
const retired = wanted.flatMap(({ kind, id }) => {
|
|
36462
|
+
const holder = specIndexRetiredBy(index, kind, id);
|
|
36463
|
+
return holder ? [`${kind} "${id}" is listed in the previousIds of "${holder}"`] : [];
|
|
36464
|
+
});
|
|
36465
|
+
if (retired.length > 0) {
|
|
36466
|
+
throw new WaironError(
|
|
36467
|
+
`id-retired: ${retired.join("; ")}. A consumer holding the old key would read the new spec as the renamed one; unsetting the holder's previousIds (sdd_update_spec unset) releases the id.`
|
|
36468
|
+
);
|
|
36469
|
+
}
|
|
36470
|
+
}
|
|
36471
|
+
function keepPublicNames(specsDir, derives, dryRun = false) {
|
|
36472
|
+
const names = [];
|
|
36473
|
+
const specs = [];
|
|
36474
|
+
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
36475
|
+
let raw;
|
|
36476
|
+
try {
|
|
36477
|
+
raw = readYamlFile(file);
|
|
36478
|
+
} catch {
|
|
36479
|
+
continue;
|
|
36480
|
+
}
|
|
36481
|
+
if (!raw || typeof raw !== "object") continue;
|
|
36482
|
+
const kind = specKind(raw);
|
|
36483
|
+
if (kind !== "subsystem" && kind !== "system" || !Array.isArray(raw.publicInterfaces)) continue;
|
|
36484
|
+
let changed = false;
|
|
36485
|
+
for (const entry of raw.publicInterfaces) {
|
|
36486
|
+
if (!entry || typeof entry !== "object" || entry.as !== void 0 || entry.id !== void 0) continue;
|
|
36487
|
+
if (!derives(entry)) continue;
|
|
36488
|
+
const source = entry.interface ?? entry.component ?? entry.typeDef;
|
|
36489
|
+
if (typeof source !== "string") continue;
|
|
36490
|
+
const name = source.split("::").pop() ?? source;
|
|
36491
|
+
entry.as = name;
|
|
36492
|
+
names.push(name);
|
|
36493
|
+
changed = true;
|
|
36494
|
+
}
|
|
36495
|
+
if (!changed) continue;
|
|
36496
|
+
if (!dryRun) writeYamlFile(file, raw);
|
|
36497
|
+
specs.push({ kind, id: kind === "system" ? "system" : String(raw.id) });
|
|
36498
|
+
}
|
|
36499
|
+
return { names: [...new Set(names)], specs };
|
|
36500
|
+
}
|
|
35697
36501
|
function removeSpecFile2(file, id) {
|
|
35698
36502
|
if (!fs16.existsSync(file)) return;
|
|
35699
36503
|
try {
|
|
@@ -35742,6 +36546,12 @@ function renameMethod(componentId, methodName, newName, pinSymbol) {
|
|
|
35742
36546
|
if (taken.length > 0) {
|
|
35743
36547
|
throw new WaironError(`name-taken: ${taken.join(", ")} already declares a method under the name "${newName}".`);
|
|
35744
36548
|
}
|
|
36549
|
+
const retiredOn = moving.flatMap((i) => i.methods.filter((m) => (m.previousNames ?? []).includes(`${i.id}.${newName}`)).map((m) => `"${i.id}.${m.name}"`));
|
|
36550
|
+
if (retiredOn.length > 0) {
|
|
36551
|
+
throw new WaironError(
|
|
36552
|
+
`name-retired: ${retiredOn.join(", ")} lists "${newName}" in its previousNames \u2014 the name is retired on that contract. Unsetting that previousNames releases it.`
|
|
36553
|
+
);
|
|
36554
|
+
}
|
|
35745
36555
|
const implementations = loadImplementationSpecs();
|
|
35746
36556
|
const movingContracts = new Set(moving.map((i) => i.id));
|
|
35747
36557
|
const renamed = [];
|
|
@@ -35775,6 +36585,7 @@ function renameMethod(componentId, methodName, newName, pinSymbol) {
|
|
|
35775
36585
|
methods: contract.methods.map((m) => m.name === methodName ? {
|
|
35776
36586
|
...m,
|
|
35777
36587
|
name: newName,
|
|
36588
|
+
previousNames: traced(m.previousNames, `${contract.id}.${methodName}`),
|
|
35778
36589
|
...m.params === void 0 && m.signatureFrom === void 0 ? { signature: renameInSignature(m.signature, methodName, newName) } : {}
|
|
35779
36590
|
} : m)
|
|
35780
36591
|
});
|
|
@@ -35799,6 +36610,7 @@ function renameMethod(componentId, methodName, newName, pinSymbol) {
|
|
|
35799
36610
|
const allowsRekeyed = rekeyLintAllows(specsDir, rename);
|
|
35800
36611
|
const rewritten = [...new Set([...retargeted, ...allowsRekeyed].map((spec) => spec.id))];
|
|
35801
36612
|
const mentions = collectMentions(specsDir, methodName, moving);
|
|
36613
|
+
const publishedIn = exportsPublishing(componentId, new Set(moving.map((i) => i.id)));
|
|
35802
36614
|
const carried = projectConfigRepository.rekeyCarried(rename);
|
|
35803
36615
|
return {
|
|
35804
36616
|
component: componentId,
|
|
@@ -35808,9 +36620,25 @@ function renameMethod(componentId, methodName, newName, pinSymbol) {
|
|
|
35808
36620
|
rewritten,
|
|
35809
36621
|
mentions,
|
|
35810
36622
|
...pinnedSymbol ? { pinnedSymbol } : {},
|
|
35811
|
-
carried
|
|
36623
|
+
carried,
|
|
36624
|
+
publishedIn
|
|
35812
36625
|
};
|
|
35813
36626
|
}
|
|
36627
|
+
function exportsPublishing(componentId, contracts) {
|
|
36628
|
+
const names = /* @__PURE__ */ new Set();
|
|
36629
|
+
const tables = [
|
|
36630
|
+
...loadSubsystemSpecs().filter((s) => !s.id.includes("::")).map((s) => resolveSubsystemExports(s.id)),
|
|
36631
|
+
resolveProjectExports()
|
|
36632
|
+
];
|
|
36633
|
+
for (const table of tables) {
|
|
36634
|
+
for (const entry of table.entries) {
|
|
36635
|
+
if (entry.kind !== "component" || entry.component !== componentId) continue;
|
|
36636
|
+
if (entry.interface !== void 0 && !contracts.has(entry.interface)) continue;
|
|
36637
|
+
names.add(entry.publicName);
|
|
36638
|
+
}
|
|
36639
|
+
}
|
|
36640
|
+
return [...names].sort();
|
|
36641
|
+
}
|
|
35814
36642
|
function renameInSignature(signature, from, to) {
|
|
35815
36643
|
return signature.replace(identifierPattern(from), to);
|
|
35816
36644
|
}
|
|
@@ -35846,6 +36674,150 @@ function collectMentions(specsDir, methodName, moved) {
|
|
|
35846
36674
|
function identifierPattern(methodName) {
|
|
35847
36675
|
return new RegExp(`(?<![A-Za-z0-9_])${methodName}(?![A-Za-z0-9_])`);
|
|
35848
36676
|
}
|
|
36677
|
+
function respellLike(written, oldId, newId) {
|
|
36678
|
+
const words2 = (id) => id.split(/[_-]+/).filter(Boolean);
|
|
36679
|
+
const pascal = (id) => words2(id).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
36680
|
+
const camel = (id) => {
|
|
36681
|
+
const p = pascal(id);
|
|
36682
|
+
return p.charAt(0).toLowerCase() + p.slice(1);
|
|
36683
|
+
};
|
|
36684
|
+
const kebab = (id) => words2(id).join("-");
|
|
36685
|
+
if (written === oldId) return newId;
|
|
36686
|
+
if (written === pascal(oldId)) return pascal(newId);
|
|
36687
|
+
if (written === camel(oldId)) return camel(newId);
|
|
36688
|
+
if (written === kebab(oldId)) return kebab(newId);
|
|
36689
|
+
if (written.includes("-")) return kebab(newId);
|
|
36690
|
+
return /^[A-Z]/.test(written) ? pascal(newId) : newId;
|
|
36691
|
+
}
|
|
36692
|
+
function renameType(typeId, newId) {
|
|
36693
|
+
const all = loadTypeSpecs();
|
|
36694
|
+
const cut = typeId.lastIndexOf("::");
|
|
36695
|
+
const qualifier = cut >= 0 ? typeId.slice(0, cut) : void 0;
|
|
36696
|
+
const ownSubsystem = qualifier !== void 0 && loadSubsystemSpecs().some((s) => s.id === qualifier);
|
|
36697
|
+
if (qualifier !== void 0 && !ownSubsystem) {
|
|
36698
|
+
throw new WaironError(`chained-type: "${typeId}" lives in another project; rename it from that project's own root.`);
|
|
36699
|
+
}
|
|
36700
|
+
const type = qualifier !== void 0 ? all.find((t) => t.id === typeId.slice(cut + 2) && t.subsystem === qualifier) ?? null : loadTypeSpec(typeId);
|
|
36701
|
+
if (!type) throw new WaironError(`type-missing: no type has the id "${typeId}".`);
|
|
36702
|
+
if (type.id.includes("::")) {
|
|
36703
|
+
throw new WaironError(`chained-type: "${type.id}" lives in another project; rename it from that project's own root.`);
|
|
36704
|
+
}
|
|
36705
|
+
const oldId = type.id;
|
|
36706
|
+
if (!SpecIdSchema.safeParse(newId).success) {
|
|
36707
|
+
throw new WaironError(`invalid-id: "${newId}" is not a lowercase identifier with no namespace separator.`);
|
|
36708
|
+
}
|
|
36709
|
+
const sameOwner = (t) => (t.subsystem ?? "") === (type.subsystem ?? "");
|
|
36710
|
+
if (all.some((t) => t !== type && t.id === newId && sameOwner(t))) {
|
|
36711
|
+
throw new WaironError(`id-taken: another type of ${type.subsystem ? `"${type.subsystem}"` : "the system"} already has the id "${newId}".`);
|
|
36712
|
+
}
|
|
36713
|
+
refuseRetiredIds([{ kind: "type", id: qualifiedTypeId({ id: newId, subsystem: type.subsystem }) }]);
|
|
36714
|
+
const rename = { specs: [{ from: oldId, to: newId }] };
|
|
36715
|
+
const registerEdits = projectConfigRepository.rekeyCarried(rename, true);
|
|
36716
|
+
const components = new Map(loadComponentSpecs().map((c) => [c.id, c.subsystem]));
|
|
36717
|
+
const others = all.filter((t) => t !== type);
|
|
36718
|
+
const namesType = (token, owner) => {
|
|
36719
|
+
if (!typeMatchesRef(type, token)) return false;
|
|
36720
|
+
if (!others.some((t) => typeMatchesRef(t, token))) return true;
|
|
36721
|
+
return (owner ?? "") === (type.subsystem ?? "");
|
|
36722
|
+
};
|
|
36723
|
+
const respellText = (text3, owner) => {
|
|
36724
|
+
if (typeof text3 !== "string") return text3;
|
|
36725
|
+
return text3.replace(/[A-Za-z_][A-Za-z0-9_-]*(?:(?:::|\.)[A-Za-z_][A-Za-z0-9_-]*)*/g, (token) => {
|
|
36726
|
+
if (!namesType(token, owner)) return token;
|
|
36727
|
+
const parts = token.split(/(::|\.)/);
|
|
36728
|
+
parts[parts.length - 1] = respellLike(parts[parts.length - 1], oldId, newId);
|
|
36729
|
+
return parts.join("");
|
|
36730
|
+
});
|
|
36731
|
+
};
|
|
36732
|
+
const specsDir = aiPathsAt(getProjectRoot()).specsDir();
|
|
36733
|
+
const derivesName = (entry) => entry.interface === void 0 && entry.component === void 0 && typeof entry.typeDef === "string" && namesType(entry.typeDef, void 0);
|
|
36734
|
+
const respellSpec = (raw) => {
|
|
36735
|
+
const kind = specKind(raw);
|
|
36736
|
+
const before = JSON.stringify(raw);
|
|
36737
|
+
const at = (holder, key, owner) => {
|
|
36738
|
+
if (holder && typeof holder[key] === "string") holder[key] = respellText(holder[key], owner);
|
|
36739
|
+
};
|
|
36740
|
+
const methodPositions = (method, owner, sourced) => {
|
|
36741
|
+
if (!method || typeof method !== "object") return;
|
|
36742
|
+
for (const p of Array.isArray(method.params) ? method.params : []) at(p, "type", owner);
|
|
36743
|
+
at(method, "returns", owner);
|
|
36744
|
+
if (sourced && typeof method.signatureFrom === "string" && namesType(method.signatureFrom, owner)) at(method, "signatureFrom", owner);
|
|
36745
|
+
if (typeof method.signature === "string") {
|
|
36746
|
+
if (Array.isArray(method.params)) method.signature = deriveMethodSignature(method) ?? method.signature;
|
|
36747
|
+
else {
|
|
36748
|
+
const close2 = method.signature.lastIndexOf(")");
|
|
36749
|
+
if (close2 >= 0) method.signature = method.signature.slice(0, close2 + 1) + respellText(method.signature.slice(close2 + 1), owner);
|
|
36750
|
+
}
|
|
36751
|
+
}
|
|
36752
|
+
};
|
|
36753
|
+
if (kind === "interface") {
|
|
36754
|
+
const owner = components.get(String(raw.component));
|
|
36755
|
+
for (const m of Array.isArray(raw.methods) ? raw.methods : []) methodPositions(m, owner, true);
|
|
36756
|
+
} else if (kind === "type") {
|
|
36757
|
+
const owner = typeof raw.subsystem === "string" ? raw.subsystem : void 0;
|
|
36758
|
+
for (const f of Array.isArray(raw.fields) ? raw.fields : []) {
|
|
36759
|
+
at(f, "type", owner);
|
|
36760
|
+
if (typeof f?.references === "string") {
|
|
36761
|
+
const [head2, ...rest] = f.references.split(".");
|
|
36762
|
+
if (namesType(head2, owner)) f.references = [respellText(head2, owner), ...rest].join(".");
|
|
36763
|
+
}
|
|
36764
|
+
}
|
|
36765
|
+
for (const p of Array.isArray(raw.params) ? raw.params : []) at(p, "type", owner);
|
|
36766
|
+
at(raw, "returns", owner);
|
|
36767
|
+
if (typeof raw.linkedEntity === "string" && namesType(raw.linkedEntity, owner)) at(raw, "linkedEntity", owner);
|
|
36768
|
+
for (const m of Array.isArray(raw.methods) ? raw.methods : []) methodPositions(m, owner, false);
|
|
36769
|
+
} else if (kind === "subsystem" || kind === "system") {
|
|
36770
|
+
const owner = kind === "subsystem" ? String(raw.id) : void 0;
|
|
36771
|
+
for (const e of Array.isArray(raw.publicInterfaces) ? raw.publicInterfaces : []) {
|
|
36772
|
+
if (e && typeof e.typeDef === "string" && namesType(e.typeDef, owner)) at(e, "typeDef", owner);
|
|
36773
|
+
}
|
|
36774
|
+
}
|
|
36775
|
+
return JSON.stringify(raw) !== before;
|
|
36776
|
+
};
|
|
36777
|
+
const respellAll = (dryRun) => {
|
|
36778
|
+
const out = [];
|
|
36779
|
+
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
36780
|
+
let raw;
|
|
36781
|
+
try {
|
|
36782
|
+
raw = readYamlFile(file);
|
|
36783
|
+
} catch {
|
|
36784
|
+
continue;
|
|
36785
|
+
}
|
|
36786
|
+
const kind = raw && typeof raw === "object" ? specKind(raw) : void 0;
|
|
36787
|
+
if (!kind || !respellSpec(raw)) continue;
|
|
36788
|
+
if (!dryRun) writeYamlFile(file, raw);
|
|
36789
|
+
out.push({ kind, id: kind === "system" ? "system" : String(raw.id) });
|
|
36790
|
+
}
|
|
36791
|
+
return out;
|
|
36792
|
+
};
|
|
36793
|
+
assertSpecsInReach(
|
|
36794
|
+
[{ kind: "type", id: oldId }, ...keepPublicNames(specsDir, derivesName, true).specs, ...respellAll(true), ...rekeyLintAllows(specsDir, rename, true)],
|
|
36795
|
+
`renaming type "${typeId}"`,
|
|
36796
|
+
Array.isArray(registerEdits) && registerEdits.length > 0
|
|
36797
|
+
);
|
|
36798
|
+
const kept = keepPublicNames(specsDir, derivesName);
|
|
36799
|
+
const respelled = respellAll(false);
|
|
36800
|
+
const allowsRekeyed = rekeyLintAllows(specsDir, rename);
|
|
36801
|
+
const rewritten = [...new Set([...kept.specs, ...respelled, ...allowsRekeyed].filter((spec) => !(spec.kind === "type" && spec.id === oldId)).map((spec) => spec.id))];
|
|
36802
|
+
invalidateSpecCache();
|
|
36803
|
+
const moved = loadTypeSpecs().find((t) => t.id === oldId && (t.subsystem ?? "") === (type.subsystem ?? "")) ?? type;
|
|
36804
|
+
saveSpec("type", { ...moved, id: newId, previousIds: traced(moved.previousIds, oldId) });
|
|
36805
|
+
invalidateSpecCache();
|
|
36806
|
+
removeSpecFile2(typeFileOf(oldId, type), oldId);
|
|
36807
|
+
if (loadTypeSpecs().some((t) => t.id === oldId && (t.subsystem ?? "") === (type.subsystem ?? ""))) deleteSpec("type", oldId);
|
|
36808
|
+
invalidateSpecCache();
|
|
36809
|
+
const carried = projectConfigRepository.rekeyCarried(rename);
|
|
36810
|
+
return {
|
|
36811
|
+
from: qualifiedTypeId(type),
|
|
36812
|
+
to: qualifiedTypeId({ id: newId, subsystem: type.subsystem }),
|
|
36813
|
+
rewritten,
|
|
36814
|
+
keptPublicNames: kept.names,
|
|
36815
|
+
carried
|
|
36816
|
+
};
|
|
36817
|
+
}
|
|
36818
|
+
function typeFileOf(id, type) {
|
|
36819
|
+
return getTypePath(id, type.subsystem, type.group);
|
|
36820
|
+
}
|
|
35849
36821
|
function moveMountToMembers(alias) {
|
|
35850
36822
|
const family = graph();
|
|
35851
36823
|
const member = family.nodes.find((n) => n.parent === "" && n.mountAlias === alias);
|
|
@@ -36031,18 +37003,18 @@ function normalizePath(p) {
|
|
|
36031
37003
|
var fs18 = __toESM(require("fs"));
|
|
36032
37004
|
var os4 = __toESM(require("os"));
|
|
36033
37005
|
var path27 = __toESM(require("path"));
|
|
36034
|
-
var
|
|
36035
|
-
var VariantDefSchema =
|
|
37006
|
+
var import_zod11 = require("zod");
|
|
37007
|
+
var VariantDefSchema = import_zod11.z.object({
|
|
36036
37008
|
/** Variant id referenced by a component's `variant` (e.g. "publisher", "org/external-config-adapter"). */
|
|
36037
|
-
id:
|
|
37009
|
+
id: import_zod11.z.string().min(1),
|
|
36038
37010
|
/** The core stereotype this variant specializes — authoritative for generic semantics (Adapter, Orchestrator, …). */
|
|
36039
|
-
base:
|
|
37011
|
+
base: import_zod11.z.string().min(1),
|
|
36040
37012
|
/** How to implement a component of this variant — the recipe the implementer follows and reuses across same-variant components. */
|
|
36041
|
-
guidance:
|
|
37013
|
+
guidance: import_zod11.z.string().min(1),
|
|
36042
37014
|
/** Optional: this variant only applies for the given target language (else it applies everywhere). */
|
|
36043
|
-
target:
|
|
37015
|
+
target: import_zod11.z.string().optional(),
|
|
36044
37016
|
/** Optional: this variant only applies under the given architectural profile. */
|
|
36045
|
-
profile:
|
|
37017
|
+
profile: import_zod11.z.string().optional()
|
|
36046
37018
|
});
|
|
36047
37019
|
function globalVariantsDir() {
|
|
36048
37020
|
return process.env.WAIRON_VARIANTS_DIR ?? path27.join(os4.homedir(), ".wairon", "variants");
|
|
@@ -37205,19 +38177,19 @@ function retireSpecialists(apply3) {
|
|
|
37205
38177
|
if (decision === void 0) return "pending";
|
|
37206
38178
|
return decision === "unset" ? "neither" : decision;
|
|
37207
38179
|
}
|
|
37208
|
-
const
|
|
37209
|
-
if (
|
|
37210
|
-
if (
|
|
38180
|
+
const dependency2 = byId.get(id);
|
|
38181
|
+
if (dependency2?.componentType === "Orchestrator" && dependency2.dependencyClass) return dependency2.dependencyClass;
|
|
38182
|
+
if (dependency2 && DATA_FACADES.has(dependency2.componentType)) return "facade";
|
|
37211
38183
|
return "neither";
|
|
37212
38184
|
};
|
|
37213
38185
|
const described = (id) => {
|
|
37214
|
-
const
|
|
38186
|
+
const dependency2 = byId.get(id);
|
|
37215
38187
|
const fit = fitOf(id);
|
|
37216
38188
|
let what;
|
|
37217
|
-
if (!
|
|
38189
|
+
if (!dependency2) what = "missing";
|
|
37218
38190
|
else if (fit === "pure" || fit === "read") what = fit;
|
|
37219
|
-
else if (
|
|
37220
|
-
else what =
|
|
38191
|
+
else if (dependency2.componentType === "Orchestrator" || specialistIds.has(id)) what = "workflow";
|
|
38192
|
+
else what = dependency2.componentType;
|
|
37221
38193
|
return `${id} (${what})`;
|
|
37222
38194
|
};
|
|
37223
38195
|
const reasonFor = (specialist, decision, settled2) => {
|
|
@@ -38402,7 +39374,7 @@ function buildServerInstructions2() {
|
|
|
38402
39374
|
// src/mcp/server.ts
|
|
38403
39375
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
38404
39376
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
38405
|
-
var
|
|
39377
|
+
var import_zod12 = require("zod");
|
|
38406
39378
|
var import_types12 = require("@modelcontextprotocol/sdk/types.js");
|
|
38407
39379
|
var path48 = __toESM(require("path"));
|
|
38408
39380
|
var crypto10 = __toESM(require("crypto"));
|
|
@@ -38514,6 +39486,7 @@ function refuseUnknownOwner(kind, merged, storedOwner) {
|
|
|
38514
39486
|
}
|
|
38515
39487
|
var STORE_MANAGED_FIELDS = /* @__PURE__ */ new Set(["status", "updatedAt"]);
|
|
38516
39488
|
var ALWAYS_CARRIED_FIELDS = /* @__PURE__ */ new Set(["ext"]);
|
|
39489
|
+
var TRACED_KINDS = /* @__PURE__ */ new Set(["component", "interface", "implementation", "type"]);
|
|
38517
39490
|
var STATUS_ORDER = ["draft", "design", "complete"];
|
|
38518
39491
|
var STATUSED_KINDS = /* @__PURE__ */ new Set(["subsystem", "component", "interface", "implementation"]);
|
|
38519
39492
|
var MISSING_PARENT = {
|
|
@@ -38560,6 +39533,10 @@ function applyRestatement(restatement, loaded, parent) {
|
|
|
38560
39533
|
const carried = carryInto(restatement, existing, candidate);
|
|
38561
39534
|
const cleared = clearedByOmission(existing, candidate, restatement.fields);
|
|
38562
39535
|
stampLifecycle(candidate, existing, status.status);
|
|
39536
|
+
if (restatement.kind === "interface") {
|
|
39537
|
+
const retired = retiredMethodNames(existing, candidate);
|
|
39538
|
+
if (retired) return refused(restatement, replacedExisting, `${retired} Nothing was written.`);
|
|
39539
|
+
}
|
|
38563
39540
|
if (restatement.kind === "interface") {
|
|
38564
39541
|
const restated = restatedSources(candidate.methods);
|
|
38565
39542
|
if (restated.length) return refused(restatement, replacedExisting, `${restatedSourceRefusal(String(candidate.id), restated)} Nothing was written.`);
|
|
@@ -38654,9 +39631,32 @@ function carryInto(restatement, existing, candidate) {
|
|
|
38654
39631
|
for (const field of carryUnexpressed(prev, method, restatement.memberFields)) carried.push(`${field} (${String(method.name)})`);
|
|
38655
39632
|
}
|
|
38656
39633
|
}
|
|
39634
|
+
if (restatement.kind === "interface" && !restatement.memberFields && Array.isArray(candidate.methods)) {
|
|
39635
|
+
const stored = existing.methods ?? [];
|
|
39636
|
+
for (const method of candidate.methods) {
|
|
39637
|
+
const prev = stored.find((p) => p.name === method.name);
|
|
39638
|
+
if (prev?.previousNames === void 0 || method.previousNames !== void 0) continue;
|
|
39639
|
+
method.previousNames = prev.previousNames;
|
|
39640
|
+
carried.push(`previousNames (${String(method.name)})`);
|
|
39641
|
+
}
|
|
39642
|
+
}
|
|
38657
39643
|
carried.push(...carryUnexpressed(existing, candidate, [...restatement.fields, "createdAt"]));
|
|
38658
39644
|
return carried;
|
|
38659
39645
|
}
|
|
39646
|
+
function retiredMethodNames(existing, candidate) {
|
|
39647
|
+
const id = String(candidate.id);
|
|
39648
|
+
const storedNames = new Set((existing?.methods ?? []).map((m) => m.name));
|
|
39649
|
+
const methods = Array.isArray(candidate.methods) ? candidate.methods : [];
|
|
39650
|
+
const holders = [...methods, ...existing?.methods ?? []];
|
|
39651
|
+
for (const method of methods) {
|
|
39652
|
+
if (storedNames.has(method.name)) continue;
|
|
39653
|
+
const holder = holders.find((m) => m !== method && (m.previousNames ?? []).includes(`${id}.${method.name}`));
|
|
39654
|
+
if (holder) {
|
|
39655
|
+
return `Refusing to write interface "${id}": name-retired \u2014 the new method "${method.name}" takes a name this contract retired ("${holder.name}" lists "${id}.${method.name}" in its previousNames). Unsetting that previousNames releases the name.`;
|
|
39656
|
+
}
|
|
39657
|
+
}
|
|
39658
|
+
return void 0;
|
|
39659
|
+
}
|
|
38660
39660
|
function carryUnexpressed(existing, next, expressed) {
|
|
38661
39661
|
if (!existing) return [];
|
|
38662
39662
|
const carried = [];
|
|
@@ -38763,6 +39763,16 @@ function writeSpec(restatement) {
|
|
|
38763
39763
|
const parent = parentRef ? loadSpec(parentRef.kind, parentRef.id) : null;
|
|
38764
39764
|
const id = restatement.kind === "system" ? "system" : restatement.spec.id;
|
|
38765
39765
|
const existing = loadSpec(restatement.kind, id);
|
|
39766
|
+
if (!existing && TRACED_KINDS.has(restatement.kind)) {
|
|
39767
|
+
const spec = restatement.spec;
|
|
39768
|
+
const key = restatement.kind === "type" ? qualifiedTypeId(spec) : spec.id;
|
|
39769
|
+
const holder = specIndexRetiredBy(scanAllSpecs({ memberDepth: 0 }), restatement.kind, key);
|
|
39770
|
+
if (holder) {
|
|
39771
|
+
throw new Error(
|
|
39772
|
+
`id-retired: ${restatement.kind} "${spec.id}" is listed in the previousIds of "${holder}", which was renamed from it. Left alone, a consumer holding the old key would read the new spec as the renamed one. Unsetting the holder's previousIds (sdd_update_spec with {"unset": ["previousIds"]}) releases the id, at the cost that such a consumer reads a delete and an add. Nothing was written.`
|
|
39773
|
+
);
|
|
39774
|
+
}
|
|
39775
|
+
}
|
|
38766
39776
|
const application = applyRestatement(restatement, existing, parent);
|
|
38767
39777
|
if (application.refusal !== void 0) throw new Error(application.refusal);
|
|
38768
39778
|
const gateNotices = restatement.kind === "component" ? judgeComponent(application.spec, bound2) : [];
|
|
@@ -38832,17 +39842,17 @@ function updateSpecGated(kind, id, delta, dryRun) {
|
|
|
38832
39842
|
const testRoots = bound2.rules?.conformance?.testRoots ?? [];
|
|
38833
39843
|
const stored = loadSpec(kind, id);
|
|
38834
39844
|
const gate = componentCandidateGate(bound2, stored?.subsystem, stored);
|
|
38835
|
-
const
|
|
38836
|
-
const changed = changedMethods(
|
|
39845
|
+
const report3 = updateSpec(kind, id, delta, gate, dryRun);
|
|
39846
|
+
const changed = changedMethods(report3);
|
|
38837
39847
|
if (changed.length > 0 && testRoots.length > 0) {
|
|
38838
39848
|
const written = Array.isArray(delta?.methods) ? delta.methods : [];
|
|
38839
|
-
|
|
39849
|
+
report3.testsToRevisit = testsInvalidatedBy(kind, id, changed, [stored], bound2, written);
|
|
38840
39850
|
}
|
|
38841
|
-
return
|
|
39851
|
+
return report3;
|
|
38842
39852
|
}
|
|
38843
|
-
function changedMethods(
|
|
39853
|
+
function changedMethods(report3) {
|
|
38844
39854
|
const named2 = /* @__PURE__ */ new Set();
|
|
38845
|
-
for (const change of
|
|
39855
|
+
for (const change of report3.changes) {
|
|
38846
39856
|
const [field, name] = change.path.split(".");
|
|
38847
39857
|
if (field === "methods" && name) named2.add(name);
|
|
38848
39858
|
}
|
|
@@ -39633,10 +40643,10 @@ function addPin(ctx, consumer, alias) {
|
|
|
39633
40643
|
function planEntry(ctx, producer, ref, table, reason) {
|
|
39634
40644
|
const target = targetOf(ref);
|
|
39635
40645
|
if (!target) {
|
|
39636
|
-
return
|
|
40646
|
+
return report2(ctx, "target-missing", ref, `${ref.specId} names "${ref.target}", but ${label3(producer.namespace)} declares no component, subsystem-owned type or project-level type of that id \u2014 the reference is wrong`);
|
|
39637
40647
|
}
|
|
39638
40648
|
if (target.kind === "subsystem") {
|
|
39639
|
-
return
|
|
40649
|
+
return report2(ctx, "subsystem-reference", ref, `${ref.specId} re-exports ${label3(producer.namespace)}'s subsystem "${target.id}" wholesale \u2014 no L0 entry short of exporting it expresses that; rewrite the reference to name the items it uses`);
|
|
39640
40650
|
}
|
|
39641
40651
|
if (target.source === void 0) return decideOwnType(ctx, producer, ref, target, table, reason);
|
|
39642
40652
|
return decideEntry(ctx, producer, ref, target, table, resolveSubsystemExports(target.source), reason);
|
|
@@ -39658,7 +40668,7 @@ function decideOwnType(ctx, producer, ref, target, table, reason) {
|
|
|
39658
40668
|
const local = localIn3(producer.namespace, target.id);
|
|
39659
40669
|
const taken = table.entries.find((e) => e.publicName === local && exportTargetKey(e) !== key) ?? entryOf(ctx, producer).exports.find((e) => e.publicName === local && (e.component ?? e.typeDef) !== local);
|
|
39660
40670
|
if (taken) {
|
|
39661
|
-
return
|
|
40671
|
+
return report2(ctx, "name-taken", ref, `"${local}" already names another item in ${label3(producer.namespace)} \u2014 export the type "${target.id}" under a name a person chooses`);
|
|
39662
40672
|
}
|
|
39663
40673
|
mergeEntry(entryOf(ctx, producer), target, void 0, local, local, ref, reason);
|
|
39664
40674
|
return "planned";
|
|
@@ -39667,18 +40677,18 @@ function decideEntry(ctx, producer, ref, target, table, published, reason) {
|
|
|
39667
40677
|
const key = targetKey(target);
|
|
39668
40678
|
const at = published.entries.filter((e) => exportTargetKey({ ...e, interface: void 0 }) === key);
|
|
39669
40679
|
if (at.length === 0) {
|
|
39670
|
-
return
|
|
40680
|
+
return report2(ctx, "target-unpublished", ref, `"${target.id}" is not in its subsystem's L1 table, so no L0 re-export can follow it \u2014 publish it at L1 first, or the reference is wrong`);
|
|
39671
40681
|
}
|
|
39672
40682
|
const exported = table.entries.filter((e) => exportTargetKey({ ...e, interface: void 0 }) === key);
|
|
39673
40683
|
if (exported.length > 0 && reachableThrough(exported, ref)) return "present";
|
|
39674
40684
|
if (exported.length > 0 || !reachableThrough(at, ref)) {
|
|
39675
|
-
return
|
|
40685
|
+
return report2(ctx, "narrowed", ref, `"${target.id}" is exported under a narrowing that does not declare "${ref.member ?? "what the reference reaches"}" \u2014 widen the narrowing or reach another member`);
|
|
39676
40686
|
}
|
|
39677
40687
|
const local = localIn3(producer.namespace, target.id);
|
|
39678
40688
|
const publicName = local.split("::").pop();
|
|
39679
40689
|
const taken = table.entries.find((e) => e.publicName === publicName && exportTargetKey({ ...e, interface: void 0 }) !== key) ?? entryOf(ctx, producer).exports.find((e) => e.publicName === publicName && (e.component ?? e.typeDef) !== local);
|
|
39680
40690
|
if (taken) {
|
|
39681
|
-
return
|
|
40691
|
+
return report2(ctx, "name-taken", ref, `"${publicName}" already names another item in ${label3(producer.namespace)} \u2014 export "${target.id}" under a name a person chooses`);
|
|
39682
40692
|
}
|
|
39683
40693
|
mergeEntry(entryOf(ctx, producer), target, localIn3(producer.namespace, target.source), local, publicName, ref, reason);
|
|
39684
40694
|
return "planned";
|
|
@@ -39719,7 +40729,7 @@ function addSorted(list, value) {
|
|
|
39719
40729
|
list.sort();
|
|
39720
40730
|
}
|
|
39721
40731
|
}
|
|
39722
|
-
function
|
|
40732
|
+
function report2(ctx, kind, ref, detail) {
|
|
39723
40733
|
ctx.findings.push({ kind, project: ref.producer, detail, reference: ref, blocking: false });
|
|
39724
40734
|
return "refused";
|
|
39725
40735
|
}
|
|
@@ -42260,30 +43270,30 @@ function structured(content, data) {
|
|
|
42260
43270
|
return { content: [{ type: "text", text: content }], structuredContent: data };
|
|
42261
43271
|
}
|
|
42262
43272
|
function migrationTool(request, dryRun) {
|
|
42263
|
-
let
|
|
43273
|
+
let report3;
|
|
42264
43274
|
try {
|
|
42265
|
-
|
|
43275
|
+
report3 = run2(request, dryRun);
|
|
42266
43276
|
} catch (e) {
|
|
42267
43277
|
return errMessage(e);
|
|
42268
43278
|
}
|
|
42269
|
-
const view = migrationView(
|
|
43279
|
+
const view = migrationView(report3, dryRun === true);
|
|
42270
43280
|
const body = JSON.stringify(view, null, 2);
|
|
42271
|
-
if (
|
|
43281
|
+
if (report3.plan.refusals.length > 0) return errText(`the ${request.verb} migration is refused; nothing was written.
|
|
42272
43282
|
${body}`);
|
|
42273
|
-
if (!
|
|
42274
|
-
const how =
|
|
42275
|
-
return errText(`the ${request.verb} migration failed (${
|
|
43283
|
+
if (!report3.applied && report3.outcome) {
|
|
43284
|
+
const how = report3.outcome.restored ? "the family was restored exactly as before" : "some files could not be restored: a person must run `wairon doctor --fix` in the project";
|
|
43285
|
+
return errText(`the ${request.verb} migration failed (${report3.outcome.failure ?? "unknown failure"}) and ${how}.
|
|
42276
43286
|
${body}`);
|
|
42277
43287
|
}
|
|
42278
43288
|
return structured(body, view);
|
|
42279
43289
|
}
|
|
42280
|
-
function migrationView(
|
|
42281
|
-
const plan6 =
|
|
43290
|
+
function migrationView(report3, dryRun) {
|
|
43291
|
+
const plan6 = report3.plan;
|
|
42282
43292
|
return {
|
|
42283
43293
|
dryRun,
|
|
42284
|
-
applied:
|
|
42285
|
-
relock:
|
|
42286
|
-
...
|
|
43294
|
+
applied: report3.applied,
|
|
43295
|
+
relock: report3.applied ? report3.relock : plan6.relock,
|
|
43296
|
+
...report3.outcome ? { outcome: { committed: report3.outcome.committed, restored: report3.outcome.restored, unrestored: report3.outcome.unrestored, ...report3.outcome.failure ? { failure: report3.outcome.failure } : {} } } : {},
|
|
42287
43297
|
plan: {
|
|
42288
43298
|
verb: plan6.request.verb,
|
|
42289
43299
|
familyRoot: plan6.familyRoot,
|
|
@@ -42299,69 +43309,69 @@ function jsonStructured(value) {
|
|
|
42299
43309
|
return structured(JSON.stringify(value, null, 2), value);
|
|
42300
43310
|
}
|
|
42301
43311
|
var staleServerOutput = {
|
|
42302
|
-
staleServer:
|
|
43312
|
+
staleServer: import_zod12.z.boolean().optional().describe(
|
|
42303
43313
|
"True when the wairon build on disk changed after this server started \u2014 the structured twin of the text answer's STALE SERVER banner. When the rebuild left the spec and tool schemas alone, writes still go through; reconnect to run the new code."
|
|
42304
43314
|
),
|
|
42305
|
-
writesRefused:
|
|
43315
|
+
writesRefused: import_zod12.z.boolean().optional().describe(
|
|
42306
43316
|
"True when the rebuild changed a spec or tool schema (or its schemas could not be compared): every spec write through this server is refused and writes nothing, because it would silently drop the fields only the new build knows. The human has to reconnect the server (/mcp reconnect wairon)."
|
|
42307
43317
|
)
|
|
42308
43318
|
};
|
|
42309
43319
|
var externalPinsOutput = {
|
|
42310
|
-
pins:
|
|
42311
|
-
alias:
|
|
42312
|
-
outcome:
|
|
42313
|
-
project:
|
|
42314
|
-
snapshot:
|
|
42315
|
-
digest:
|
|
42316
|
-
usedNames:
|
|
42317
|
-
unexported:
|
|
42318
|
-
detail:
|
|
43320
|
+
pins: import_zod12.z.array(import_zod12.z.object({
|
|
43321
|
+
alias: import_zod12.z.string(),
|
|
43322
|
+
outcome: import_zod12.z.enum(["pinned", "unchanged", "unresolved", "unreachable"]),
|
|
43323
|
+
project: import_zod12.z.string().optional(),
|
|
43324
|
+
snapshot: import_zod12.z.string().optional(),
|
|
43325
|
+
digest: import_zod12.z.string().optional(),
|
|
43326
|
+
usedNames: import_zod12.z.number(),
|
|
43327
|
+
unexported: import_zod12.z.array(import_zod12.z.record(import_zod12.z.unknown())),
|
|
43328
|
+
detail: import_zod12.z.string().optional()
|
|
42319
43329
|
})).describe("One outcome per alias pinned, in declaration order, with its unexported references."),
|
|
42320
43330
|
...staleServerOutput
|
|
42321
43331
|
};
|
|
42322
43332
|
var externalStatusesOutput = {
|
|
42323
|
-
statuses:
|
|
42324
|
-
alias:
|
|
42325
|
-
project:
|
|
42326
|
-
sourceKind:
|
|
42327
|
-
pinned:
|
|
42328
|
-
reachable:
|
|
42329
|
-
stale:
|
|
42330
|
-
drifted:
|
|
42331
|
-
uses:
|
|
42332
|
-
detail:
|
|
42333
|
-
outOfReach:
|
|
42334
|
-
pinnedDigest:
|
|
42335
|
-
pinnedCommit:
|
|
43333
|
+
statuses: import_zod12.z.array(import_zod12.z.object({
|
|
43334
|
+
alias: import_zod12.z.string(),
|
|
43335
|
+
project: import_zod12.z.string(),
|
|
43336
|
+
sourceKind: import_zod12.z.string(),
|
|
43337
|
+
pinned: import_zod12.z.boolean(),
|
|
43338
|
+
reachable: import_zod12.z.boolean(),
|
|
43339
|
+
stale: import_zod12.z.boolean(),
|
|
43340
|
+
drifted: import_zod12.z.boolean().optional(),
|
|
43341
|
+
uses: import_zod12.z.array(import_zod12.z.record(import_zod12.z.unknown())),
|
|
43342
|
+
detail: import_zod12.z.string().optional(),
|
|
43343
|
+
outOfReach: import_zod12.z.boolean().optional(),
|
|
43344
|
+
pinnedDigest: import_zod12.z.string().optional().describe("The content digest the lock recorded; provenance, never compared here."),
|
|
43345
|
+
pinnedCommit: import_zod12.z.string().optional().describe("The producer commit the lock recorded, for one in another repository; provenance only.")
|
|
42336
43346
|
})).describe("One status per declared external, in declaration order; EXTERNAL_CHECK_UNAVAILABLE marks what could not be compared."),
|
|
42337
43347
|
...staleServerOutput
|
|
42338
43348
|
};
|
|
42339
|
-
function renderChangeReport(
|
|
42340
|
-
const lines = [
|
|
42341
|
-
for (const change of
|
|
43349
|
+
function renderChangeReport(report3) {
|
|
43350
|
+
const lines = [report3.dryRun ? `DRY RUN \u2014 nothing was written. ${report3.summary}` : report3.summary];
|
|
43351
|
+
for (const change of report3.changes) {
|
|
42342
43352
|
const to = change.after === void 0 ? "" : `: ${JSON.stringify(change.after)}`;
|
|
42343
43353
|
const from = change.before === void 0 ? "" : ` (was ${JSON.stringify(change.before)})`;
|
|
42344
|
-
lines.push(`- ${change.path} ${
|
|
43354
|
+
lines.push(`- ${change.path} ${report3.dryRun ? `would be ${change.change}` : change.change}${to}${from}`);
|
|
42345
43355
|
}
|
|
42346
|
-
if (
|
|
42347
|
-
lines.push("", "NO EFFECT:", ...
|
|
43356
|
+
if (report3.ineffective.length) {
|
|
43357
|
+
lines.push("", "NO EFFECT:", ...report3.ineffective.map((i) => `- ${i}`));
|
|
42348
43358
|
}
|
|
42349
|
-
if (
|
|
42350
|
-
if (
|
|
42351
|
-
lines.push("", `DROPPED FROM THE STORED FILE (${
|
|
43359
|
+
if (report3.notices.length) lines.push("", "NOTICE:", ...report3.notices.map((n) => `- ${n}`));
|
|
43360
|
+
if (report3.strippedKeys?.length) {
|
|
43361
|
+
lines.push("", `DROPPED FROM THE STORED FILE (${report3.dryRun ? "would be " : ""}removed \u2014 the schema does not know them):`, ...report3.strippedKeys.map((k) => `- ${k}`));
|
|
42352
43362
|
}
|
|
42353
|
-
lines.push(...renderRespellings(
|
|
42354
|
-
lines.push(...renderTestsToRevisit(
|
|
43363
|
+
lines.push(...renderRespellings(report3.respellings));
|
|
43364
|
+
lines.push(...renderTestsToRevisit(report3.testsToRevisit));
|
|
42355
43365
|
return lines.join("\n");
|
|
42356
43366
|
}
|
|
42357
43367
|
var SPEC_KINDS = ["system", "subsystem", "component", "interface", "implementation", "type"];
|
|
42358
43368
|
var STATUS_VALUES = ["draft", "design", "complete"];
|
|
42359
|
-
var testsToRevisitOutput =
|
|
42360
|
-
method:
|
|
42361
|
-
symbol:
|
|
42362
|
-
imported:
|
|
42363
|
-
mentioned:
|
|
42364
|
-
indiscriminate:
|
|
43369
|
+
var testsToRevisitOutput = import_zod12.z.array(import_zod12.z.object({
|
|
43370
|
+
method: import_zod12.z.string().describe("The contract method this write changed or deleted."),
|
|
43371
|
+
symbol: import_zod12.z.string().describe("The code-level name searched for: the method's `symbol` when it declares one, else its name."),
|
|
43372
|
+
imported: import_zod12.z.array(import_zod12.z.string()).describe("Test files that IMPORT that symbol \u2014 the high-confidence list, because an import is a binding and not a coincidence."),
|
|
43373
|
+
mentioned: import_zod12.z.array(import_zod12.z.string()).describe("Test files that name the symbol without importing it \u2014 usually a test driving it through a portal. Empty when `indiscriminate` is true."),
|
|
43374
|
+
indiscriminate: import_zod12.z.boolean().describe("True when the bare name matched more than a tenth of the test suite, so the mention list was withheld as noise.")
|
|
42365
43375
|
})).describe(
|
|
42366
43376
|
"The tests that encode a method this write changed or deleted, one entry per such method. Empty when the write touched no method, when the project declares no `rules.conformance.testRoots`, or when nothing references them. Read it before promising that existing tests still pass."
|
|
42367
43377
|
);
|
|
@@ -42378,31 +43388,31 @@ function renderTestsToRevisit(entries) {
|
|
|
42378
43388
|
}
|
|
42379
43389
|
return lines;
|
|
42380
43390
|
}
|
|
42381
|
-
var typeRespellingOutput =
|
|
42382
|
-
specId:
|
|
42383
|
-
kind:
|
|
42384
|
-
path:
|
|
42385
|
-
written:
|
|
42386
|
-
stored:
|
|
43391
|
+
var typeRespellingOutput = import_zod12.z.object({
|
|
43392
|
+
specId: import_zod12.z.string().describe("The interface or type holding the position."),
|
|
43393
|
+
kind: import_zod12.z.enum(["interface", "type"]).describe("interface | type."),
|
|
43394
|
+
path: import_zod12.z.string().describe("Where in the spec: methods.save.params.key, methods.save.returns, fields.createdAt, params.listener."),
|
|
43395
|
+
written: import_zod12.z.string().describe("The text the input (or the stored file) held."),
|
|
43396
|
+
stored: import_zod12.z.string().describe("The canonical spelling, which is what is stored and shown.")
|
|
42387
43397
|
});
|
|
42388
43398
|
function renderRespellings(entries) {
|
|
42389
43399
|
if (!entries.length) return [];
|
|
42390
43400
|
return ["", "RESPELLED (stored canonical):", ...entries.map((r) => `- ${r.path}: "${r.written}" \u2192 "${r.stored}"`)];
|
|
42391
43401
|
}
|
|
42392
43402
|
var specWriteReceiptOutput = {
|
|
42393
|
-
kind:
|
|
42394
|
-
id:
|
|
42395
|
-
name:
|
|
42396
|
-
replacedExisting:
|
|
43403
|
+
kind: import_zod12.z.enum(SPEC_KINDS).describe("The spec kind written."),
|
|
43404
|
+
id: import_zod12.z.string().describe('The id the spec is stored under; "system" for the L0 singleton.'),
|
|
43405
|
+
name: import_zod12.z.string().describe("The spec's display name as written."),
|
|
43406
|
+
replacedExisting: import_zod12.z.boolean().describe(
|
|
42397
43407
|
"True when a spec already held this id and the call re-authored it in place rather than adding one. The notices then say what was carried forward, removed or cleared by the restatement."
|
|
42398
43408
|
),
|
|
42399
|
-
status:
|
|
43409
|
+
status: import_zod12.z.enum(STATUS_VALUES).optional().describe(
|
|
42400
43410
|
"The lifecycle status written. Absent for the L0 and a type, which carry none."
|
|
42401
43411
|
),
|
|
42402
|
-
notices:
|
|
43412
|
+
notices: import_zod12.z.array(import_zod12.z.string()).describe(
|
|
42403
43413
|
"The notice lines the text answer lists, one per entry: what was carried forward, what a restatement removed, what an omission cleared, and every gate warning the write raised. Empty for a clean create."
|
|
42404
43414
|
),
|
|
42405
|
-
respellings:
|
|
43415
|
+
respellings: import_zod12.z.array(typeRespellingOutput).describe(
|
|
42406
43416
|
"Each type position the write normalised: what the input wrote against the canonical spelling stored. Aliases are accepted, never refused, and this list is how an author learns the canonical form. Empty when every position was already canonical."
|
|
42407
43417
|
),
|
|
42408
43418
|
testsToRevisit: testsToRevisitOutput,
|
|
@@ -42420,86 +43430,86 @@ ${respelledBlock}` : ""}${testsBlock ? `
|
|
|
42420
43430
|
${testsBlock}` : ""}`, receipt);
|
|
42421
43431
|
}
|
|
42422
43432
|
var specDeletionOutput = {
|
|
42423
|
-
kind:
|
|
42424
|
-
id:
|
|
42425
|
-
deleted:
|
|
43433
|
+
kind: import_zod12.z.enum(SPEC_KINDS).describe("The spec kind deleted."),
|
|
43434
|
+
id: import_zod12.z.string().describe("The id the spec was stored under."),
|
|
43435
|
+
deleted: import_zod12.z.boolean().describe("True when a spec document was removed."),
|
|
42426
43436
|
testsToRevisit: testsToRevisitOutput,
|
|
42427
43437
|
...staleServerOutput
|
|
42428
43438
|
};
|
|
42429
43439
|
var specChangeOutput = {
|
|
42430
|
-
path:
|
|
42431
|
-
change:
|
|
43440
|
+
path: import_zod12.z.string().describe("The dotted path the change addresses, with names and indexes."),
|
|
43441
|
+
change: import_zod12.z.enum(["set", "added", "removed", "cleared", "renumbered", "relocated"]).describe(
|
|
42432
43442
|
"What happened at that path. A narrative is compared by step identity: `renumbered` is a run of unchanged steps shifted by an insert or delete (before/after name the ranges), `relocated` a jump field that followed its target to the target's new number."
|
|
42433
43443
|
),
|
|
42434
|
-
before:
|
|
42435
|
-
after:
|
|
43444
|
+
before: import_zod12.z.string().optional().describe("The previous value, summarized; absent when there was none."),
|
|
43445
|
+
after: import_zod12.z.string().optional().describe("The new value, summarized; absent when there is none.")
|
|
42436
43446
|
};
|
|
42437
43447
|
var specChangeReportOutput = {
|
|
42438
|
-
kind:
|
|
42439
|
-
id:
|
|
42440
|
-
written:
|
|
42441
|
-
dryRun:
|
|
43448
|
+
kind: import_zod12.z.enum(SPEC_KINDS).describe("The spec kind written."),
|
|
43449
|
+
id: import_zod12.z.string().describe("The stored spec's id."),
|
|
43450
|
+
written: import_zod12.z.boolean().describe("False when the merged spec equals what is stored: nothing reached disk."),
|
|
43451
|
+
dryRun: import_zod12.z.boolean().describe(
|
|
42442
43452
|
"True when the caller asked what the delta WOULD do. `written` is false for a dry run exactly as it is for a delta that changed nothing, and only this field tells the two apart."
|
|
42443
43453
|
),
|
|
42444
|
-
changes:
|
|
43454
|
+
changes: import_zod12.z.array(import_zod12.z.object(specChangeOutput)).describe(
|
|
42445
43455
|
"Every change the write made; empty exactly when `written` is false."
|
|
42446
43456
|
),
|
|
42447
|
-
ineffective:
|
|
43457
|
+
ineffective: import_zod12.z.array(import_zod12.z.string()).describe(
|
|
42448
43458
|
"Every path the delta named that the write did not act on, each with why. Read it: a nested typo the permissive delta cannot refuse shows up here and nowhere else."
|
|
42449
43459
|
),
|
|
42450
|
-
notices:
|
|
42451
|
-
respellings:
|
|
43460
|
+
notices: import_zod12.z.array(import_zod12.z.string()).describe("Store placement notices, gate warnings and delta notices."),
|
|
43461
|
+
respellings: import_zod12.z.array(typeRespellingOutput).describe(
|
|
42452
43462
|
"Each type position the write normalised (or, on a dry run, would): what the delta or the stored file wrote against the canonical spelling stored. Aliases are accepted and respelled, never refused \u2014 this is how the canonical form is taught. Empty when every position was already canonical."
|
|
42453
43463
|
),
|
|
42454
|
-
summary:
|
|
43464
|
+
summary: import_zod12.z.string().describe("One line for people."),
|
|
42455
43465
|
testsToRevisit: testsToRevisitOutput,
|
|
42456
|
-
strippedKeys:
|
|
43466
|
+
strippedKeys: import_zod12.z.array(import_zod12.z.string()).optional().describe(
|
|
42457
43467
|
"Keys the stored file carries that the level's schema does not know, each as `path: value`, which this write drops (or, on a dry run, would drop). Absent when there are none."
|
|
42458
43468
|
),
|
|
42459
43469
|
...staleServerOutput
|
|
42460
43470
|
};
|
|
42461
43471
|
var validationIssueOutput = {
|
|
42462
|
-
severity:
|
|
42463
|
-
code:
|
|
42464
|
-
message:
|
|
42465
|
-
agentId:
|
|
42466
|
-
specId:
|
|
42467
|
-
draftContext:
|
|
43472
|
+
severity: import_zod12.z.enum(["error", "warning", "notice"]).describe("The finding's severity after project overrides."),
|
|
43473
|
+
code: import_zod12.z.string().describe("The rule code, UPPER_SNAKE \u2014 the stable handle to filter and suppress by."),
|
|
43474
|
+
message: import_zod12.z.string().describe("What is wrong, named."),
|
|
43475
|
+
agentId: import_zod12.z.string().optional().describe("The agent the finding concerns, when it concerns one."),
|
|
43476
|
+
specId: import_zod12.z.string().optional().describe("The spec the finding concerns, when it concerns one."),
|
|
43477
|
+
draftContext: import_zod12.z.boolean().optional().describe(
|
|
42468
43478
|
"True when the finding was raised against a draft/design spec \u2014 what the --ci gate waives."
|
|
42469
43479
|
),
|
|
42470
|
-
resolution:
|
|
42471
|
-
outcome:
|
|
42472
|
-
owner:
|
|
42473
|
-
callSite:
|
|
42474
|
-
canonicalTarget:
|
|
42475
|
-
inputDigest:
|
|
42476
|
-
reason:
|
|
42477
|
-
importedVia:
|
|
43480
|
+
resolution: import_zod12.z.object({
|
|
43481
|
+
outcome: import_zod12.z.enum(["resolved", "missing", "ambiguous", "unavailable", "forbidden"]).describe("How the owner's gate resolved the reference, decided before the severity."),
|
|
43482
|
+
owner: import_zod12.z.string().describe("The referring project's id: the one project whose gate judges the reference."),
|
|
43483
|
+
callSite: import_zod12.z.string().describe("Where the reference is written: the referring spec and the position in it."),
|
|
43484
|
+
canonicalTarget: import_zod12.z.string().optional().describe("The target in producer-id form, `<producer id>::<public name>`."),
|
|
43485
|
+
inputDigest: import_zod12.z.string().optional().describe("The digest of the input the reference was judged against (a pin, or a member's live table)."),
|
|
43486
|
+
reason: import_zod12.z.string().describe("One sentence saying why the outcome is what it is."),
|
|
43487
|
+
importedVia: import_zod12.z.string().optional().describe("For a bare name resolved through a `use` import: the alias that supplied it.")
|
|
42478
43488
|
}).optional().describe(
|
|
42479
43489
|
"On a finding about a cross-project reference: how the owner's gate resolved it, decided before the severity."
|
|
42480
43490
|
),
|
|
42481
|
-
project:
|
|
43491
|
+
project: import_zod12.z.string().optional().describe(
|
|
42482
43492
|
"In a family run: the key of the project whose gate the finding belongs to ('' for the family root)."
|
|
42483
43493
|
)
|
|
42484
43494
|
};
|
|
42485
43495
|
var memberCreationOutput = {
|
|
42486
|
-
configCreated:
|
|
42487
|
-
adopted:
|
|
42488
|
-
name:
|
|
42489
|
-
version:
|
|
42490
|
-
integrity:
|
|
42491
|
-
source:
|
|
42492
|
-
bundle:
|
|
43496
|
+
configCreated: import_zod12.z.boolean().describe("Whether this call created the member's configuration; only then were the declaring project's required packs scaffolded."),
|
|
43497
|
+
adopted: import_zod12.z.array(import_zod12.z.object({
|
|
43498
|
+
name: import_zod12.z.string(),
|
|
43499
|
+
version: import_zod12.z.string().optional(),
|
|
43500
|
+
integrity: import_zod12.z.string().optional(),
|
|
43501
|
+
source: import_zod12.z.string().optional(),
|
|
43502
|
+
bundle: import_zod12.z.boolean().optional()
|
|
42493
43503
|
})).describe("The selections written into the new member's extensions.packs, each pinned to the highest installed version its requirement admits."),
|
|
42494
|
-
unadopted:
|
|
42495
|
-
pack:
|
|
42496
|
-
version:
|
|
42497
|
-
profile:
|
|
43504
|
+
unadopted: import_zod12.z.array(import_zod12.z.object({
|
|
43505
|
+
pack: import_zod12.z.string(),
|
|
43506
|
+
version: import_zod12.z.string(),
|
|
43507
|
+
profile: import_zod12.z.string().optional()
|
|
42498
43508
|
})).describe("Requirements no installed version satisfies: nothing was written for them, and the next family run reports each as POLICY_NOT_ADOPTED."),
|
|
42499
|
-
projectType:
|
|
42500
|
-
as:
|
|
42501
|
-
storage:
|
|
42502
|
-
commit:
|
|
43509
|
+
projectType: import_zod12.z.string().optional().describe("The profile written as the new member's projectType, when exactly one adopted requirement names one."),
|
|
43510
|
+
as: import_zod12.z.string().describe("part | project: what was created (stage 8; a part by default)."),
|
|
43511
|
+
storage: import_zod12.z.string().describe("contained | path | git: where its files live."),
|
|
43512
|
+
commit: import_zod12.z.string().optional().describe("git: the commit the member was pinned at."),
|
|
42503
43513
|
...staleServerOutput
|
|
42504
43514
|
};
|
|
42505
43515
|
function describeMemberPacks(creation) {
|
|
@@ -42514,36 +43524,36 @@ function describeMemberPacks(creation) {
|
|
|
42514
43524
|
}
|
|
42515
43525
|
return parts.join("");
|
|
42516
43526
|
}
|
|
42517
|
-
var doctrineChangeOutput =
|
|
42518
|
-
axis:
|
|
42519
|
-
change:
|
|
42520
|
-
subject:
|
|
42521
|
-
profile:
|
|
42522
|
-
from:
|
|
42523
|
-
to:
|
|
42524
|
-
reason:
|
|
43527
|
+
var doctrineChangeOutput = import_zod12.z.object({
|
|
43528
|
+
axis: import_zod12.z.enum(["rule", "concept"]),
|
|
43529
|
+
change: import_zod12.z.string().describe("loosened | raised | off | added | depth | inert | redefined | removed | discouraged | licensed | gated \u2014 stated, never judged."),
|
|
43530
|
+
subject: import_zod12.z.string(),
|
|
43531
|
+
profile: import_zod12.z.string().optional(),
|
|
43532
|
+
from: import_zod12.z.string().optional(),
|
|
43533
|
+
to: import_zod12.z.string().optional(),
|
|
43534
|
+
reason: import_zod12.z.string().optional()
|
|
42525
43535
|
});
|
|
42526
|
-
var impactTotalsOutput =
|
|
42527
|
-
key:
|
|
42528
|
-
id:
|
|
42529
|
-
directory:
|
|
42530
|
-
valid:
|
|
42531
|
-
errors:
|
|
42532
|
-
warnings:
|
|
42533
|
-
notices:
|
|
43536
|
+
var impactTotalsOutput = import_zod12.z.object({
|
|
43537
|
+
key: import_zod12.z.string(),
|
|
43538
|
+
id: import_zod12.z.string().optional(),
|
|
43539
|
+
directory: import_zod12.z.string(),
|
|
43540
|
+
valid: import_zod12.z.boolean(),
|
|
43541
|
+
errors: import_zod12.z.number(),
|
|
43542
|
+
warnings: import_zod12.z.number(),
|
|
43543
|
+
notices: import_zod12.z.number()
|
|
42534
43544
|
});
|
|
42535
43545
|
var packImpactOutput = {
|
|
42536
|
-
pack:
|
|
42537
|
-
version:
|
|
42538
|
-
replaces:
|
|
42539
|
-
direction:
|
|
42540
|
-
doctrine:
|
|
42541
|
-
previousDoctrine:
|
|
42542
|
-
governing:
|
|
42543
|
-
findings:
|
|
42544
|
-
introduced:
|
|
42545
|
-
resolved:
|
|
42546
|
-
regraded:
|
|
43546
|
+
pack: import_zod12.z.string().describe("The pack measured."),
|
|
43547
|
+
version: import_zod12.z.string().optional().describe("The version the candidate resolves to; absent for an unversioned pack."),
|
|
43548
|
+
replaces: import_zod12.z.string().optional().describe("The version applied now under the same name, when the selection would replace it."),
|
|
43549
|
+
direction: import_zod12.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."),
|
|
43550
|
+
doctrine: import_zod12.z.array(doctrineChangeOutput).describe("The pack's changes against wairon's defaults. Nothing in it is a finding."),
|
|
43551
|
+
previousDoctrine: import_zod12.z.array(doctrineChangeOutput).optional().describe("On an update: the replaced version's changes against the same defaults."),
|
|
43552
|
+
governing: import_zod12.z.array(import_zod12.z.string()).describe("The pack's profiles that would govern something in this project."),
|
|
43553
|
+
findings: import_zod12.z.object({
|
|
43554
|
+
introduced: import_zod12.z.array(import_zod12.z.object(validationIssueOutput)),
|
|
43555
|
+
resolved: import_zod12.z.array(import_zod12.z.object(validationIssueOutput)),
|
|
43556
|
+
regraded: import_zod12.z.array(import_zod12.z.object({ finding: import_zod12.z.object(validationIssueOutput), from: import_zod12.z.string() }))
|
|
42547
43557
|
}).describe("The owner's-gate findings that differ between the current and the candidate configuration."),
|
|
42548
43558
|
before: impactTotalsOutput.describe("The current configuration's totals."),
|
|
42549
43559
|
after: impactTotalsOutput.describe("The candidate configuration's totals."),
|
|
@@ -42577,57 +43587,57 @@ function pendingBanner() {
|
|
|
42577
43587
|
}
|
|
42578
43588
|
}
|
|
42579
43589
|
var validateTreeOutput = {
|
|
42580
|
-
valid:
|
|
42581
|
-
errors:
|
|
42582
|
-
warnings:
|
|
42583
|
-
notices:
|
|
43590
|
+
valid: import_zod12.z.boolean().describe("False when the tree holds at least one error; warnings and notices never make it false."),
|
|
43591
|
+
errors: import_zod12.z.array(import_zod12.z.object(validationIssueOutput)).describe("Every finding of severity error."),
|
|
43592
|
+
warnings: import_zod12.z.array(import_zod12.z.object(validationIssueOutput)).describe("Every finding of severity warning."),
|
|
43593
|
+
notices: import_zod12.z.array(import_zod12.z.object(validationIssueOutput)).describe(
|
|
42584
43594
|
"Every finding of severity notice: reported, never a failure \u2014 they never make the tree invalid and never fail `wairon validate --ci`."
|
|
42585
43595
|
),
|
|
42586
|
-
hint:
|
|
43596
|
+
hint: import_zod12.z.string().optional().describe(
|
|
42587
43597
|
"The owner's gate: present when the project declares externals \u2014 they were judged against their pins alone, and `wairon validate --family` composes them against their live producers. A family run: present when externals were left out because their producers lie outside the run's reach."
|
|
42588
43598
|
),
|
|
42589
|
-
projects:
|
|
42590
|
-
key:
|
|
42591
|
-
id:
|
|
42592
|
-
directory:
|
|
42593
|
-
valid:
|
|
42594
|
-
errors:
|
|
42595
|
-
warnings:
|
|
42596
|
-
notices:
|
|
43599
|
+
projects: import_zod12.z.array(import_zod12.z.object({
|
|
43600
|
+
key: import_zod12.z.string().describe("The project's key in the family root's scan ('' for the root itself)."),
|
|
43601
|
+
id: import_zod12.z.string().optional().describe("The project's effective id."),
|
|
43602
|
+
directory: import_zod12.z.string().describe("The project's root directory."),
|
|
43603
|
+
valid: import_zod12.z.boolean().describe("Whether its own gate found no error."),
|
|
43604
|
+
errors: import_zod12.z.number().describe("Its own gate's error count."),
|
|
43605
|
+
warnings: import_zod12.z.number().describe("Its own gate's warning count."),
|
|
43606
|
+
notices: import_zod12.z.number().describe("Its own gate's notice count.")
|
|
42597
43607
|
})).optional().describe(
|
|
42598
43608
|
"A family run only: one line per selected project (the root first) with its own gate's totals. Absent on the owner's gate."
|
|
42599
43609
|
),
|
|
42600
43610
|
...staleServerOutput
|
|
42601
43611
|
};
|
|
42602
43612
|
var getSpecOutput = {
|
|
42603
|
-
kind:
|
|
42604
|
-
id:
|
|
42605
|
-
spec:
|
|
43613
|
+
kind: import_zod12.z.enum(SPEC_KINDS).describe("The kind of spec read."),
|
|
43614
|
+
id: import_zod12.z.string().describe("The id it was read by."),
|
|
43615
|
+
spec: import_zod12.z.record(import_zod12.z.unknown()).describe(
|
|
42606
43616
|
"The stored spec, exactly as the text block renders it \u2014 minus the two derived markers below, which the text folds in and this answer keeps separate so nothing derived can be mistaken for stored."
|
|
42607
43617
|
),
|
|
42608
|
-
partialResult:
|
|
42609
|
-
shown:
|
|
42610
|
-
omitted:
|
|
42611
|
-
warning:
|
|
43618
|
+
partialResult: import_zod12.z.object({
|
|
43619
|
+
shown: import_zod12.z.array(import_zod12.z.string()).describe("The method names this answer carries."),
|
|
43620
|
+
omitted: import_zod12.z.number().describe("How many of the spec's methods are NOT in it."),
|
|
43621
|
+
warning: import_zod12.z.string().describe("Why it must never be re-authored from.")
|
|
42612
43622
|
}).optional().describe(
|
|
42613
43623
|
"Present only when `methods` filtered the read. A filtered spec is a partial one: sdd_define_interface and sdd_write_narrative REPLACE the method list, so re-authoring from it would delete every method left out."
|
|
42614
43624
|
),
|
|
42615
|
-
variantGuidance:
|
|
42616
|
-
variant:
|
|
42617
|
-
base:
|
|
42618
|
-
guidance:
|
|
42619
|
-
siblings:
|
|
42620
|
-
target:
|
|
42621
|
-
profile:
|
|
43625
|
+
variantGuidance: import_zod12.z.object({
|
|
43626
|
+
variant: import_zod12.z.string().describe("The variant id the component declares."),
|
|
43627
|
+
base: import_zod12.z.string().describe("The core stereotype it specializes."),
|
|
43628
|
+
guidance: import_zod12.z.string().describe("How to implement a component of this variant."),
|
|
43629
|
+
siblings: import_zod12.z.array(import_zod12.z.string()).describe("Other components of the same variant, to implement alike."),
|
|
43630
|
+
target: import_zod12.z.string().optional().describe("The target language the variant scopes itself to, if any."),
|
|
43631
|
+
profile: import_zod12.z.string().optional().describe("The architectural profile it scopes itself to, if any.")
|
|
42622
43632
|
}).optional().describe(
|
|
42623
43633
|
"Derived, read-only guidance for a variant-tagged component \u2014 resolved from the variant registry, not part of the spec. Never write it back."
|
|
42624
43634
|
),
|
|
42625
|
-
resolvedSignatures:
|
|
42626
|
-
method:
|
|
42627
|
-
signatureFrom:
|
|
42628
|
-
signature:
|
|
42629
|
-
params:
|
|
42630
|
-
returns:
|
|
43635
|
+
resolvedSignatures: import_zod12.z.array(import_zod12.z.object({
|
|
43636
|
+
method: import_zod12.z.string().describe("The contract method that takes its signature from a source."),
|
|
43637
|
+
signatureFrom: import_zod12.z.string().describe("The source it names, as the spec holds it."),
|
|
43638
|
+
signature: import_zod12.z.string().describe("The text it shows, derived from the resolved params and returns."),
|
|
43639
|
+
params: import_zod12.z.array(import_zod12.z.record(import_zod12.z.unknown())).optional().describe("The params the source supplies; absent when it supplies none (unresolved, ambiguous or chained)."),
|
|
43640
|
+
returns: import_zod12.z.string().describe("The returns the source supplies (`unknown` when it supplies none).")
|
|
42631
43641
|
})).optional().describe(
|
|
42632
43642
|
"Derived, read-only: for a contract whose methods take their signature from a source, each such method's RESOLVED params, returns and text. The spec carries those methods in stored form (the signatureFrom alone) so it can be re-authored from as it is; never write these back beside the source."
|
|
42633
43643
|
),
|
|
@@ -42790,6 +43800,7 @@ var SPEC_WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
|
42790
43800
|
"sdd_rename_member_alias",
|
|
42791
43801
|
"sdd_rename_component",
|
|
42792
43802
|
"sdd_rename_method",
|
|
43803
|
+
"sdd_rename_type",
|
|
42793
43804
|
"sdd_add_component",
|
|
42794
43805
|
"sdd_define_interface",
|
|
42795
43806
|
"sdd_set_endpoints",
|
|
@@ -42811,10 +43822,10 @@ function reg(server, name, config, cb) {
|
|
|
42811
43822
|
if (result.isError !== true && SPEC_WRITE_TOOLS.has(name)) listChangedEmitters.get(server)?.();
|
|
42812
43823
|
return result;
|
|
42813
43824
|
};
|
|
42814
|
-
const strictConfig = config.inputSchema ? { ...config, inputSchema:
|
|
43825
|
+
const strictConfig = config.inputSchema ? { ...config, inputSchema: import_zod12.z.object(config.inputSchema).strict() } : config;
|
|
42815
43826
|
server.registerTool(name, strictConfig, guarded2);
|
|
42816
43827
|
}
|
|
42817
|
-
var statusInput =
|
|
43828
|
+
var statusInput = import_zod12.z.enum(STATUS_VALUES).optional().describe(
|
|
42818
43829
|
"The spec's lifecycle status. Omitted means draft for a NEW spec and the status already stored for a re-authoring, so a restatement never reopens a frozen spec. State it to author straight at design or complete instead of promoting afterwards. A status that would LOWER the stored one is refused \u2014 reopening a spec for revision is sdd_update_spec's job, which sets the demotion deliberately."
|
|
42819
43830
|
);
|
|
42820
43831
|
function createBareMcpServer(options = {}) {
|
|
@@ -42841,7 +43852,7 @@ function createBareMcpServer(options = {}) {
|
|
|
42841
43852
|
"listAgents",
|
|
42842
43853
|
{
|
|
42843
43854
|
description: "List all AI agents registered in this project. Returns id, name, description, domainRoot, template, tags, and status for each agent. Filter by domainId to scope to one domain.",
|
|
42844
|
-
inputSchema: { domainId:
|
|
43855
|
+
inputSchema: { domainId: import_zod12.z.string().optional() }
|
|
42845
43856
|
},
|
|
42846
43857
|
({ domainId }) => {
|
|
42847
43858
|
try {
|
|
@@ -42866,7 +43877,7 @@ function createBareMcpServer(options = {}) {
|
|
|
42866
43877
|
"getAgent",
|
|
42867
43878
|
{
|
|
42868
43879
|
description: "Get full details of a specific agent by id, including ownership rules, context, and output targets.",
|
|
42869
|
-
inputSchema: { id:
|
|
43880
|
+
inputSchema: { id: import_zod12.z.string() }
|
|
42870
43881
|
},
|
|
42871
43882
|
({ id }) => {
|
|
42872
43883
|
try {
|
|
@@ -42899,7 +43910,7 @@ function createBareMcpServer(options = {}) {
|
|
|
42899
43910
|
{
|
|
42900
43911
|
description: "Validate the project's agent topology. Returns errors, warnings and notices (duplicate ids, overlapping ownership, missing paths, etc.). Supports optional subsystem scoping.",
|
|
42901
43912
|
inputSchema: {
|
|
42902
|
-
subsystem:
|
|
43913
|
+
subsystem: import_zod12.z.string().optional().describe("Only validate topology for agents under the specified subsystem")
|
|
42903
43914
|
}
|
|
42904
43915
|
},
|
|
42905
43916
|
({ subsystem }) => {
|
|
@@ -42942,11 +43953,11 @@ function createBareMcpServer(options = {}) {
|
|
|
42942
43953
|
}
|
|
42943
43954
|
);
|
|
42944
43955
|
const systemInput = {
|
|
42945
|
-
name:
|
|
42946
|
-
vision:
|
|
42947
|
-
boundaries:
|
|
42948
|
-
globalRequirements:
|
|
42949
|
-
targetLanguage:
|
|
43956
|
+
name: import_zod12.z.string().describe("Overarching name of the project/system"),
|
|
43957
|
+
vision: import_zod12.z.string().describe("Vision, mission, and core goals of the system"),
|
|
43958
|
+
boundaries: import_zod12.z.array(import_zod12.z.union([import_zod12.z.string(), import_zod12.z.object({ name: import_zod12.z.string(), description: import_zod12.z.string().optional() }).strict()])).optional().describe("System boundary rules or scope statements (strings or name/description objects)"),
|
|
43959
|
+
globalRequirements: import_zod12.z.array(import_zod12.z.union([import_zod12.z.string(), import_zod12.z.object({ description: import_zod12.z.string() }).strict()])).optional().describe("Global functional and non-functional requirements (strings or description objects)"),
|
|
43960
|
+
targetLanguage: import_zod12.z.string().optional().describe('Default implementation language for the system (e.g. "typescript", "rust", "python"). Subsystems may override. Enables language-aware validation.')
|
|
42950
43961
|
};
|
|
42951
43962
|
const systemInputFields = Object.keys(systemInput);
|
|
42952
43963
|
reg(
|
|
@@ -42980,34 +43991,34 @@ function createBareMcpServer(options = {}) {
|
|
|
42980
43991
|
}
|
|
42981
43992
|
}
|
|
42982
43993
|
);
|
|
42983
|
-
const publicInterfaceItemInput =
|
|
42984
|
-
type:
|
|
42985
|
-
details:
|
|
42986
|
-
component:
|
|
42987
|
-
interface:
|
|
42988
|
-
consumers:
|
|
42989
|
-
from:
|
|
42990
|
-
typeDef:
|
|
42991
|
-
as:
|
|
43994
|
+
const publicInterfaceItemInput = import_zod12.z.object({
|
|
43995
|
+
type: import_zod12.z.enum(["REST", "GraphQL", "MessageBus", "RPC", "Custom"]).optional().describe("Transport kind of an own item (required on an own component item); a re-export inherits its target's"),
|
|
43996
|
+
details: import_zod12.z.string().optional().describe("Consumer-facing description of an own item (required on an own component item); a re-export inherits its target's"),
|
|
43997
|
+
component: import_zod12.z.string().optional().describe("For an own item, the L2 component that realizes it (this subsystem's published surface); for a re-export, the component re-exported from `from`"),
|
|
43998
|
+
interface: import_zod12.z.string().optional().describe("Optional L3 interface id the entry narrows to"),
|
|
43999
|
+
consumers: import_zod12.z.array(import_zod12.z.string()).optional().describe("The subsystem ids this surface is published to. Absent, any subsystem may depend on the component; present, only these may \u2014 when every entry publishing the component names consumers, the union of the lists is the whole set, and a dependency from any other subsystem is CROSS_SUBSYSTEM_UNLISTED_CONSUMER. Every id must name a subsystem of the tree (PUBLIC_INTERFACE_UNKNOWN_CONSUMER)."),
|
|
44000
|
+
from: import_zod12.z.string().optional().describe("Re-export source: another subsystem of this project. With neither component nor typeDef, the entry re-exports everything that subsystem exports (a wildcard)"),
|
|
44001
|
+
typeDef: import_zod12.z.string().optional().describe("A type exported as is: owned by this subsystem, or re-exported from `from`"),
|
|
44002
|
+
as: import_zod12.z.string().optional().describe("The public name; defaults to the narrowed interface, then the component or type id. Must fit [a-z0-9-_]+ (EXPORT_INVALID otherwise)")
|
|
42992
44003
|
}).strict();
|
|
42993
44004
|
const subsystemInput = {
|
|
42994
|
-
id:
|
|
42995
|
-
name:
|
|
42996
|
-
description:
|
|
42997
|
-
publicInterfaces:
|
|
42998
|
-
projectPath:
|
|
42999
|
-
targetLanguage:
|
|
43000
|
-
profile:
|
|
43001
|
-
designDepth:
|
|
43002
|
-
trustedLinks:
|
|
43003
|
-
subsystem:
|
|
43004
|
-
reason:
|
|
44005
|
+
id: import_zod12.z.string().describe("Lowercase identifier for the subsystem"),
|
|
44006
|
+
name: import_zod12.z.string().describe("Human-readable display name"),
|
|
44007
|
+
description: import_zod12.z.string().describe("Purpose and details of the subsystem"),
|
|
44008
|
+
publicInterfaces: import_zod12.z.array(publicInterfaceItemInput).optional().describe("The subsystem's export table: its own entrypoints, each bound to a realizing component, and re-exports of what other subsystems of this project export"),
|
|
44009
|
+
projectPath: import_zod12.z.string().optional().describe("REFUSED: the legacy L1 mount form. A subsystem is never a mount \u2014 declare a member project with sdd_add_member instead"),
|
|
44010
|
+
targetLanguage: import_zod12.z.string().optional().describe("Override of the system-level targetLanguage for this subsystem"),
|
|
44011
|
+
profile: import_zod12.z.string().optional().describe("Architectural profile override for this subsystem (built-ins: backend, frontend-reactive, frontend-controller, lowlevel-os, game-ecs, realtime-embedded, plc-cyclic; extension packs may add more \u2014 unknown names get UNKNOWN_PROFILE)"),
|
|
44012
|
+
designDepth: import_zod12.z.enum(["components", "interfaces", "implementations", "narratives"]).optional().describe("How deep THIS subsystem commits to designing (overrides project rules.designDepth; default narratives = full depth). Expectation checks below the depth are gated \u2014 soundness of authored content always applies."),
|
|
44013
|
+
trustedLinks: import_zod12.z.array(import_zod12.z.object({
|
|
44014
|
+
subsystem: import_zod12.z.string().describe("Peer subsystem id"),
|
|
44015
|
+
reason: import_zod12.z.string().describe('Why the coupling is sanctioned (e.g. "dispatch latency fast lane")')
|
|
43005
44016
|
}).strict()).optional().describe("Sanctioned tight couplings with peers \u2014 required to acknowledge a mutual subsystem dependency; the Adapter \u2192 published Portal shape still applies."),
|
|
43006
|
-
lifecycle:
|
|
43007
|
-
phase:
|
|
43008
|
-
component:
|
|
43009
|
-
method:
|
|
43010
|
-
description:
|
|
44017
|
+
lifecycle: import_zod12.z.array(import_zod12.z.object({
|
|
44018
|
+
phase: import_zod12.z.enum(["init", "shutdown", "cyclic", "interrupt", "scheduled"]).describe("Which lifecycle/execution flow this roots (cyclic = every scan/tick, interrupt = hardware/OS interrupt, scheduled = timer/cron)"),
|
|
44019
|
+
component: import_zod12.z.string().describe("Component id whose method the runtime invokes at this phase"),
|
|
44020
|
+
method: import_zod12.z.string().describe("Method name on that component's interface"),
|
|
44021
|
+
description: import_zod12.z.string().optional()
|
|
43011
44022
|
}).strict()).optional().describe("Declared execution-flow roots \u2014 reachability entrypoints alongside Portals/Observers. Only init flows feed the durable-Store hydration check (MISSING_HYDRATION); cyclic/interrupt/scheduled root non-request/response execution models (PLC scan, ISR, cron)."),
|
|
43012
44023
|
status: statusInput
|
|
43013
44024
|
};
|
|
@@ -43052,8 +44063,8 @@ function createBareMcpServer(options = {}) {
|
|
|
43052
44063
|
{
|
|
43053
44064
|
description: "Set (replace) an existing subsystem's export table (its publicInterfaces). An OWN item binds type + details to the component (and optional interface) that realizes it, or exports a type the subsystem owns (typeDef). A RE-EXPORT names another subsystem of the project in `from` and one component (optionally narrowed with `interface`) or one typeDef from what it exports, optionally renamed with `as` \u2014 `from` alone re-exports everything it exports; type and details are optional on a re-export, which inherits its target's. Use this to backfill bindings once the subsystem's components exist \u2014 cross-subsystem dependencies may only target a component its owning subsystem publishes; a re-export is a name, not a licence. A replacement, not a merge: an entry left out is removed. An own entry's identity is its component and interface, a re-export's its source, item and name, so a list naming one identity twice is refused. Written through the authoring seam as one gated delta, and answered with the change report \u2014 every entry added, changed or removed, or that nothing changed \u2014 as structured content beside the sentence.",
|
|
43054
44065
|
inputSchema: {
|
|
43055
|
-
subsystem:
|
|
43056
|
-
publicInterfaces:
|
|
44066
|
+
subsystem: import_zod12.z.string().describe("The L1 subsystem id to update"),
|
|
44067
|
+
publicInterfaces: import_zod12.z.array(publicInterfaceItemInput).describe("The full replacement list of the subsystem's export table: own items and re-exports")
|
|
43057
44068
|
},
|
|
43058
44069
|
outputSchema: specChangeReportOutput
|
|
43059
44070
|
},
|
|
@@ -43063,11 +44074,11 @@ function createBareMcpServer(options = {}) {
|
|
|
43063
44074
|
if (!sub) return errText(`Subsystem "${subsystem}" does not exist.`);
|
|
43064
44075
|
const delta = publicInterfacesReplacement(subsystem, sub.publicInterfaces ?? [], publicInterfaces);
|
|
43065
44076
|
if (typeof delta === "string") return errText(delta);
|
|
43066
|
-
const
|
|
44077
|
+
const report3 = updateSpecGated("subsystem", subsystem, delta);
|
|
43067
44078
|
return structured(
|
|
43068
44079
|
`Updated public interfaces for subsystem "${subsystem}" (${publicInterfaces.length} ${publicInterfaces.length === 1 ? "entry" : "entries"}).
|
|
43069
|
-
${renderChangeReport(
|
|
43070
|
-
|
|
44080
|
+
${renderChangeReport(report3)}`,
|
|
44081
|
+
report3
|
|
43071
44082
|
);
|
|
43072
44083
|
} catch (e) {
|
|
43073
44084
|
return errMessage(e);
|
|
@@ -43080,10 +44091,10 @@ ${renderChangeReport(report2)}`,
|
|
|
43080
44091
|
{
|
|
43081
44092
|
description: "Create a member of the bound project at `source`, in the one members grammar: `services/scheduler` (contained), `../admin` (a sibling checkout), `git@host:acme/payments.git` (a git repository, pinned at its default branch head unless `#<commit>` is given). By default a PART (stage 8): a piece of this project stored in another folder or repository, whose subsystems are this project's own (local ids, the ordinary subsystem rules, this project's lock); it gets only a specs folder, plus a configuration naming this project when it is not contained. With `as: project` an independent PROJECT instead: its project content is created \u2014 a project.yaml declaring the alias as its id, its L0, and the bound project's required packs (composition.requirePolicies) once \u2014 and it is reached only as `alias::name` through its L0 exports. What a member is follows from that content. A git member is not scaffolded; the repository's content decides what it is. Boundaries are earned: create a part unless the piece needs its own team, release, approval or public surface; sdd_promote_member makes one later. Idempotent \u2014 the same call again writes nothing; a different member under the alias is refused.",
|
|
43082
44093
|
inputSchema: {
|
|
43083
|
-
alias:
|
|
43084
|
-
source:
|
|
43085
|
-
description:
|
|
43086
|
-
as:
|
|
44094
|
+
alias: import_zod12.z.string().describe("The member's alias ([a-z0-9-_]+); a project's new id"),
|
|
44095
|
+
source: import_zod12.z.string().describe("A contained path, a `../` sibling path, or a git URL (optionally `#<commit>`)"),
|
|
44096
|
+
description: import_zod12.z.string().optional().describe("What the member is to this project; also the vision of a bootstrapped project L0"),
|
|
44097
|
+
as: import_zod12.z.enum(["part", "project"]).optional().describe("project to create the project content; omitted creates a part")
|
|
43087
44098
|
},
|
|
43088
44099
|
outputSchema: memberCreationOutput
|
|
43089
44100
|
},
|
|
@@ -43104,8 +44115,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43104
44115
|
{
|
|
43105
44116
|
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`.",
|
|
43106
44117
|
inputSchema: {
|
|
43107
|
-
pack:
|
|
43108
|
-
version:
|
|
44118
|
+
pack: import_zod12.z.string().describe("The pack name"),
|
|
44119
|
+
version: import_zod12.z.string().optional().describe("An exact version; omitted, the latest installed")
|
|
43109
44120
|
},
|
|
43110
44121
|
outputSchema: packImpactOutput
|
|
43111
44122
|
},
|
|
@@ -43130,8 +44141,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43130
44141
|
{
|
|
43131
44142
|
description: "Relocate a member's directory on disk and point its `members` entry there in one step (a member still declared in the legacy L1 form is moved into `members` first). Errors if the alias declares no member, or the new path escapes the project or already exists.",
|
|
43132
44143
|
inputSchema: {
|
|
43133
|
-
alias:
|
|
43134
|
-
newPath:
|
|
44144
|
+
alias: import_zod12.z.string().describe("The member's alias"),
|
|
44145
|
+
newPath: import_zod12.z.string().describe("The member's new root, relative to the bound project")
|
|
43135
44146
|
}
|
|
43136
44147
|
},
|
|
43137
44148
|
({ alias, newPath }) => {
|
|
@@ -43143,16 +44154,16 @@ ${renderChangeReport(report2)}`,
|
|
|
43143
44154
|
}
|
|
43144
44155
|
}
|
|
43145
44156
|
);
|
|
43146
|
-
const dryRunArg =
|
|
44157
|
+
const dryRunArg = import_zod12.z.boolean().optional().describe("Answer the plan and write nothing \u2014 run this first and show the plan");
|
|
43147
44158
|
reg(
|
|
43148
44159
|
server,
|
|
43149
44160
|
"sdd_externalize_subsystem",
|
|
43150
44161
|
{
|
|
43151
44162
|
description: "Move an internal subsystem out to the path. By default (stage 8) into a PART \u2014 a storage move: the subsystem's specs move to that directory (a new part, or the existing part there), and nothing else changes: no reference, export, external or lock entry, the same verdict. With `as: project`, into a member PROJECT instead, family-wide and all-or-nothing \u2014 the move followed by a promote: what crosses the new boundary exported and imported, references respelled `alias::name`, the new member's external for this project pinned, and every other family project's references checked to still resolve (a reference that would need a component made public refuses the plan). Source code is not moved. dryRun answers the plan and writes nothing; run it first and show the plan. Never locks: the answer names the projects to re-lock.",
|
|
43152
44163
|
inputSchema: {
|
|
43153
|
-
subsystem:
|
|
43154
|
-
path:
|
|
43155
|
-
as:
|
|
44164
|
+
subsystem: import_zod12.z.string().describe("The subsystem to move out"),
|
|
44165
|
+
path: import_zod12.z.string().describe("The part's root, relative to the bound project (a new directory, or an existing part's)"),
|
|
44166
|
+
as: import_zod12.z.enum(["part", "project"]).optional().describe("part (default) or project"),
|
|
43156
44167
|
dryRun: dryRunArg
|
|
43157
44168
|
}
|
|
43158
44169
|
},
|
|
@@ -43164,8 +44175,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43164
44175
|
{
|
|
43165
44176
|
description: "Promote a part of the bound project to an independent project in place (stage 8) \u2014 its files stay where they are; it gets an id, an L0 exporting exactly what the rest of the project uses of it, its references across the new boundary respelled `alias::name`, the parent declared as its external, and pins on both sides. Refused (each reason listed) for a part fetched from git, a trusted link that would cross the new boundary, a used component its subsystem does not publish, or an id already taken. All-or-nothing; dryRun answers the plan and writes nothing \u2014 run it first and show the plan. Never locks: the answer names the project to re-lock and the new one to lock.",
|
|
43166
44177
|
inputSchema: {
|
|
43167
|
-
alias:
|
|
43168
|
-
id:
|
|
44178
|
+
alias: import_zod12.z.string().describe("The part's alias"),
|
|
44179
|
+
id: import_zod12.z.string().optional().describe("The new project's id (default: the alias)"),
|
|
43169
44180
|
dryRun: dryRunArg
|
|
43170
44181
|
}
|
|
43171
44182
|
},
|
|
@@ -43177,11 +44188,11 @@ ${renderChangeReport(report2)}`,
|
|
|
43177
44188
|
{
|
|
43178
44189
|
description: "Demote a project member of the bound project to a part in place (stage 8) \u2014 sdd_promote_member's inverse: its files stay where they are; its own metadata goes to the homes the destination names (as sdd_internalize_member sends it), its L0, lock and pins end, its references across the old boundary become local ids, and its configuration is reduced to naming its parent. Refused while another family project consumes it (a part has no exports \u2014 each consumer listed), for a member fetched from git, or for internalize's reasons. All-or-nothing; dryRun answers the plan and writes nothing \u2014 run it first and show the plan. Never locks.",
|
|
43179
44190
|
inputSchema: {
|
|
43180
|
-
alias:
|
|
43181
|
-
destination:
|
|
43182
|
-
home:
|
|
43183
|
-
packs:
|
|
43184
|
-
exports:
|
|
44191
|
+
alias: import_zod12.z.string().describe("The project member's alias"),
|
|
44192
|
+
destination: import_zod12.z.object({
|
|
44193
|
+
home: import_zod12.z.string().optional().describe("The subsystem that receives the member's L0 vision"),
|
|
44194
|
+
packs: import_zod12.z.enum(["adopt", "drop"]).optional().describe("adopt | drop: packs only the member selects"),
|
|
44195
|
+
exports: import_zod12.z.array(import_zod12.z.string()).optional().describe("Public names of the member the bound project exports afterwards")
|
|
43185
44196
|
}).optional().describe("Where its own metadata goes (its home subsystem, packs to adopt or drop)"),
|
|
43186
44197
|
dryRun: dryRunArg
|
|
43187
44198
|
}
|
|
@@ -43198,10 +44209,10 @@ ${renderChangeReport(report2)}`,
|
|
|
43198
44209
|
{
|
|
43199
44210
|
description: "Fold a member \u2014 every subsystem of it \u2014 back into the bound project, sending its own metadata to the destination (its L0 vision to the `into` subsystem's description; its requirements, boundaries and databases to the bound L0; its language, profile and depth onto the moved subsystems; its members and externals to the bound project's; its packs adopted or dropped as `packs` says) and re-pointing every other family project that consumed it at the bound project. What has no home \u2014 its lock, pins, derived outputs \u2014 is listed as deleted. Refused for a member carrying conformance debt, a pack only it selects with no `packs` answer, or a name collision. All-or-nothing; dryRun answers the plan and writes nothing; run it first and show the plan. Never locks.",
|
|
43200
44211
|
inputSchema: {
|
|
43201
|
-
alias:
|
|
43202
|
-
into:
|
|
43203
|
-
packs:
|
|
43204
|
-
exports:
|
|
44212
|
+
alias: import_zod12.z.string().describe("The member's alias"),
|
|
44213
|
+
into: import_zod12.z.string().optional().describe("The home subsystem for the member's L0 vision; required when it holds several subsystems"),
|
|
44214
|
+
packs: import_zod12.z.enum(["adopt", "drop"]).optional().describe("adopt | drop: packs only the member selects"),
|
|
44215
|
+
exports: import_zod12.z.array(import_zod12.z.string()).optional().describe("Extra public names of the member the bound project exports afterwards"),
|
|
43205
44216
|
dryRun: dryRunArg
|
|
43206
44217
|
}
|
|
43207
44218
|
},
|
|
@@ -43217,9 +44228,9 @@ ${renderChangeReport(report2)}`,
|
|
|
43217
44228
|
{
|
|
43218
44229
|
description: "Make an existing project at the path a member of the bound project, keeping its L0, subsystems, packs and lock (sdd_add_member scaffolds a new one instead). Refused when its id collides with a family project's. All-or-nothing; dryRun answers the plan and writes nothing. Never locks.",
|
|
43219
44230
|
inputSchema: {
|
|
43220
|
-
alias:
|
|
43221
|
-
path:
|
|
43222
|
-
description:
|
|
44231
|
+
alias: import_zod12.z.string().describe("The alias to declare ([a-z0-9-_]+)"),
|
|
44232
|
+
path: import_zod12.z.string().describe("The project's root, relative to the bound project"),
|
|
44233
|
+
description: import_zod12.z.string().optional().describe("What the member is to this project"),
|
|
43223
44234
|
dryRun: dryRunArg
|
|
43224
44235
|
}
|
|
43225
44236
|
},
|
|
@@ -43231,8 +44242,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43231
44242
|
{
|
|
43232
44243
|
description: "Move a project's id \u2014 the bound project's, or a member's named by its alias path \u2014 and every reference to the old id across the family (aliases that were the id, their references and re-exports, externals naming it, pins). The whole family must be in reach. Every project it writes must be re-locked; the answer names them. All-or-nothing; dryRun answers the plan and writes nothing; run it first and show the plan.",
|
|
43233
44244
|
inputSchema: {
|
|
43234
|
-
newId:
|
|
43235
|
-
project:
|
|
44245
|
+
newId: import_zod12.z.string().describe("The new project id"),
|
|
44246
|
+
project: import_zod12.z.string().optional().describe("The member's alias path from the bound project (e.g. billing/payments); the bound project when omitted"),
|
|
43236
44247
|
dryRun: dryRunArg
|
|
43237
44248
|
}
|
|
43238
44249
|
},
|
|
@@ -43244,8 +44255,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43244
44255
|
{
|
|
43245
44256
|
description: "Rename one alias of the bound project (a member or an external) and respell the bound project's references through it; nothing in any member or sibling changes. All-or-nothing; dryRun answers the plan and writes nothing. Never locks.",
|
|
43246
44257
|
inputSchema: {
|
|
43247
|
-
alias:
|
|
43248
|
-
newAlias:
|
|
44258
|
+
alias: import_zod12.z.string().describe("The alias as declared now"),
|
|
44259
|
+
newAlias: import_zod12.z.string().describe("The new alias"),
|
|
43249
44260
|
dryRun: dryRunArg
|
|
43250
44261
|
}
|
|
43251
44262
|
},
|
|
@@ -43257,8 +44268,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43257
44268
|
{
|
|
43258
44269
|
description: "Take a member out of the family; the bound project and every family consumer then reach it as an external by path, pinned. No reference text changes. Refused (audience-too-narrow, each export named with its users) while a family project uses an export the member gives the family alone, unless widen is set: then exactly those used exports are widened to the instance audience in the member's L0, each shown in the plan. All-or-nothing; dryRun answers the plan and writes nothing. Never locks.",
|
|
43259
44270
|
inputSchema: {
|
|
43260
|
-
alias:
|
|
43261
|
-
widen:
|
|
44271
|
+
alias: import_zod12.z.string().describe("The member's alias"),
|
|
44272
|
+
widen: import_zod12.z.boolean().optional().describe("Widen the used family-only exports to the instance audience instead of refusing"),
|
|
43262
44273
|
dryRun: dryRunArg
|
|
43263
44274
|
}
|
|
43264
44275
|
},
|
|
@@ -43270,8 +44281,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43270
44281
|
{
|
|
43271
44282
|
description: "Make the bound project's external a member \u2014 sdd_detach_member's inverse. Locally the external is found by a path inside the bound project and adopted where it is; on a hosted instance it names a project by source.hosted and `path` says where to adopt it (the hosting server relocates it there). All-or-nothing; dryRun answers the plan and writes nothing. Never locks.",
|
|
43272
44283
|
inputSchema: {
|
|
43273
|
-
alias:
|
|
43274
|
-
path:
|
|
44284
|
+
alias: import_zod12.z.string().describe("The external's alias"),
|
|
44285
|
+
path: import_zod12.z.string().optional().describe("Hosted: the member path to adopt a source.hosted external at, relative to the bound project; a source.path external is adopted where it is"),
|
|
43275
44286
|
dryRun: dryRunArg
|
|
43276
44287
|
}
|
|
43277
44288
|
},
|
|
@@ -43283,8 +44294,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43283
44294
|
{
|
|
43284
44295
|
description: "Rename a component and rewrite every reference to it in the bound tree: dependsOn, owns and dispatch entries, lifecycle entrypoints, published interfaces at L1 and L0, narrative call/dispatch/register targets, an interface's component, an implementation's contract and an entity's componentClass. The interface named i<id> and the implementation named <id>_impl move to the new ids and files; interfaces and implementations named otherwise keep their ids. Findings keyed on the component follow it too: every lint allow naming it on an edge site or in a covered unit, and every entry of the debt register (.wai/project.yaml rules.conformance.carried) anchored on a renamed spec or naming the component in its site or units \u2014 rewritten in place, every comment and all other formatting of the register kept, so unchanged debt never reads as paid and new at once. A register that cannot be rewritten that precisely is refused before the first write. Display names are left as they are. Refuses, writing nothing: a component that does not exist (component-missing), one inside a chained subproject (chained-component \u2014 rename it from that project's own root), a new id that is not a lowercase identifier without a namespace separator (invalid-id), and a new id \u2014 or i<newId> or <newId>_impl \u2014 already in use (id-taken). Returns the specs moved, each with its old and new id, the ids of the other specs rewritten (lint allows included), and `carried`: each register edit \u2014 the entry by code, spec and site as it stood, the key changed (spec, at or covers), from and to.",
|
|
43285
44296
|
inputSchema: {
|
|
43286
|
-
id:
|
|
43287
|
-
newId:
|
|
44297
|
+
id: import_zod12.z.string().describe("The component to rename (namespaced if needed)"),
|
|
44298
|
+
newId: import_zod12.z.string().describe("Its new id: a lowercase identifier with no namespace separator")
|
|
43288
44299
|
}
|
|
43289
44300
|
},
|
|
43290
44301
|
({ id, newId }) => {
|
|
@@ -43301,10 +44312,10 @@ ${renderChangeReport(report2)}`,
|
|
|
43301
44312
|
{
|
|
43302
44313
|
description: "Rename a contract method and retarget every reference to it in the bound tree. The method moves on every interface of the component that declares it \u2014 its name, and the name inside its signature \u2014 and on the implementations of those contracts, carrying narrative, sourcePath, symbol, detail, intent and findings unchanged; an implementation that declared no symbol is pinned to the old name unless pinSymbol is false, so the function it already binds to keeps binding. Narrative call, register and dispatch steps naming this component and method, dispatch-table bindings and lifecycle entrypoints are retargeted, and so are the findings keyed on it: a lint allow at the method on a spec it moved in or covering `<component>.<method>`, and every debt-register entry (.wai/project.yaml rules.conformance.carried) keyed the same way \u2014 rewritten in place with every comment and all other formatting kept (a register that cannot be rewritten that precisely is refused before the first write). Prose is never rewritten and a gRPC endpoint binding keeps its wire method \u2014 renaming a contract method must not silently rename an RPC; both are reported as mentions. Refuses, writing nothing: a component that does not exist (component-missing), one inside a chained subproject (chained-component \u2014 rename its method from that project's own root), a new name that is not a camel-case identifier (invalid-name), a method the component does not declare (method-missing), and a name a moving contract already declares (name-taken). Returns the specs the method moved in, the specs retargeted (lint allows included), the specs whose prose still names it, the pinned symbol when one was set, and `carried`: each register edit.",
|
|
43303
44314
|
inputSchema: {
|
|
43304
|
-
id:
|
|
43305
|
-
method:
|
|
43306
|
-
newName:
|
|
43307
|
-
pinSymbol:
|
|
44315
|
+
id: import_zod12.z.string().describe("The component whose method is renamed (namespaced if needed)"),
|
|
44316
|
+
method: import_zod12.z.string().describe("The method name as it stands"),
|
|
44317
|
+
newName: import_zod12.z.string().describe("Its new name: a camel-case identifier"),
|
|
44318
|
+
pinSymbol: import_zod12.z.boolean().optional().describe("Whether an implementation that declares no symbol is pinned to the old name so its function still binds; true when omitted")
|
|
43308
44319
|
}
|
|
43309
44320
|
},
|
|
43310
44321
|
({ id, method, newName, pinSymbol }) => {
|
|
@@ -43315,16 +44326,36 @@ ${renderChangeReport(report2)}`,
|
|
|
43315
44326
|
}
|
|
43316
44327
|
}
|
|
43317
44328
|
);
|
|
44329
|
+
reg(
|
|
44330
|
+
server,
|
|
44331
|
+
"sdd_rename_type",
|
|
44332
|
+
{
|
|
44333
|
+
description: "Rename a type and rewrite every reference to it in the bound tree: every type position naming it (contract and type-method params and returns, fields, signature-type params and returns), a signatureFrom naming it as a signature type, and an L1 or L0 export entry's typeDef. Only the named members of a type expression that name this type are respelled, in the style they were written (`Invoice` \u2192 `Bill`, `invoice` \u2192 `bill`); the rest of the text stays as written. The type moves to the new id and file under the same owner, and its old id joins its rename trace (previousIds) so a consumer of the design export reads the rename as a rename; an export entry that derived its public name from the old id gets `as: <that name>` first, so the published name and every consumer's pin stay. Rename traces are never rewritten. Findings keyed on the type follow it: lint allows naming it, and every debt-register entry anchored on it, rewritten in place (a register that cannot be rewritten that precisely is refused before the first write). The display name is left as it is. Refuses, writing nothing: a type that does not exist (type-missing), one in another project (chained-type), a new id that is not a lowercase identifier (invalid-id), and a new id another type of the same owner holds (id-taken) or retired (id-retired \u2014 unsetting the holder's previousIds releases it). Returns from and to, the specs rewritten, keptPublicNames and `carried`: each register edit.",
|
|
44334
|
+
inputSchema: {
|
|
44335
|
+
id: import_zod12.z.string().describe("The type to rename (qualified by its owning subsystem if needed, `subsystem::id`)"),
|
|
44336
|
+
newId: import_zod12.z.string().describe("Its new id: a lowercase identifier with no namespace separator")
|
|
44337
|
+
}
|
|
44338
|
+
},
|
|
44339
|
+
({ id, newId }) => {
|
|
44340
|
+
try {
|
|
44341
|
+
const bare = id.startsWith("::") ? id.slice(2) : id;
|
|
44342
|
+
const resolved = loadTypeSpec(bare) ? bare : id;
|
|
44343
|
+
return json(renameType(resolved, newId));
|
|
44344
|
+
} catch (e) {
|
|
44345
|
+
return errText(String(e));
|
|
44346
|
+
}
|
|
44347
|
+
}
|
|
44348
|
+
);
|
|
43318
44349
|
reg(
|
|
43319
44350
|
server,
|
|
43320
44351
|
"sdd_move_methods",
|
|
43321
44352
|
{
|
|
43322
44353
|
description: "Move contract methods from one component to another, carrying each method's narrative, calls and bindings, and re-pointing every reference that named the old home: narrative call/register/dispatch steps, dispatch-table bindings, lifecycle entrypoints and `calls` entries. The target gains the dependencies the moved narratives call. Findings keyed on a moved method follow it: a lint allow anchored at it moves to the receiving spec, one covering `<from>.<method>` names `<to>.<method>`, and the debt register (.wai/project.yaml rules.conformance.carried) is rekeyed the same way in place, every comment and all other formatting kept \u2014 the report's `carried` lists each register edit, and a register that cannot be rewritten that precisely is refused before the first write. ONE all-or-nothing gated write: if a rule refuses the move nothing is written and the report names the rule plus where these methods could live instead, cheapest legal home first, with the requested target among them so its shortfall reads beside the others. Prose is never rewritten and a wire endpoint keeps its address \u2014 moving a method between components must not silently re-address an RPC; both are reported as mentions. A target that declares no contract yet receives one, i<target>, and when implementation entries travel and no implementation realizes the receiving contract, <target>_impl is created for them, inheriting the source implementation's sourcePath; the report's `created` names every spec the move created. Refuses before the first write (unmovable request): a component or method that does not exist, a method name already declared on the target, a source and target that are the same component, a target with several contracts none named i<target>, a contract or implementation to create whose id another spec already holds, and a component inside a chained subproject (move it from that project's own root). A dry run runs the whole move, gate included, and reports what it would have done.",
|
|
43323
44354
|
inputSchema: {
|
|
43324
|
-
from:
|
|
43325
|
-
to:
|
|
43326
|
-
methods:
|
|
43327
|
-
dryRun:
|
|
44355
|
+
from: import_zod12.z.string().describe("The component the methods belong to (namespaced if needed)"),
|
|
44356
|
+
to: import_zod12.z.string().describe("The component that should receive them (namespaced if needed)"),
|
|
44357
|
+
methods: import_zod12.z.array(import_zod12.z.string()).describe("The method names to move; every one must exist on the source contract"),
|
|
44358
|
+
dryRun: import_zod12.z.boolean().optional().describe("Answer with what the move would do and write nothing")
|
|
43328
44359
|
}
|
|
43329
44360
|
},
|
|
43330
44361
|
({ from, to, methods, dryRun }) => {
|
|
@@ -43340,39 +44371,39 @@ ${renderChangeReport(report2)}`,
|
|
|
43340
44371
|
}
|
|
43341
44372
|
);
|
|
43342
44373
|
const componentInput = {
|
|
43343
|
-
id:
|
|
43344
|
-
name:
|
|
43345
|
-
description:
|
|
43346
|
-
subsystem:
|
|
43347
|
-
componentType:
|
|
43348
|
-
owns:
|
|
43349
|
-
dependsOn:
|
|
43350
|
-
portalType:
|
|
43351
|
-
basePath:
|
|
43352
|
-
dispatch:
|
|
43353
|
-
capability:
|
|
43354
|
-
component:
|
|
43355
|
-
method:
|
|
43356
|
-
description:
|
|
44374
|
+
id: import_zod12.z.string().describe("Lowercase identifier for the component"),
|
|
44375
|
+
name: import_zod12.z.string().describe("Human-readable display name"),
|
|
44376
|
+
description: import_zod12.z.string().describe("Responsibility / internal architecture details"),
|
|
44377
|
+
subsystem: import_zod12.z.string().describe("The L1 subsystem ID this component belongs to"),
|
|
44378
|
+
componentType: import_zod12.z.enum(["Portal", "Orchestrator", "Supervisor", "Actor", "Store", "Index", "Query", "Registry", "Adapter", "Observer", "Repository"]).describe("The building block, or the pattern Repository. Specialist and Gateway are retired and cannot be authored: logic is an Orchestrator with a dependencyClass, a gateway is a Portal with the gateway variant"),
|
|
44379
|
+
owns: import_zod12.z.array(import_zod12.z.string()).optional().describe("Member block ids privately owned by this component (patterns only)"),
|
|
44380
|
+
dependsOn: import_zod12.z.array(import_zod12.z.string()).optional().describe("IDs of other components this collaborates with (facades or standalone blocks)"),
|
|
44381
|
+
portalType: import_zod12.z.enum(["HTTP_API", "gRPC", "GraphQL", "MessageBus", "CLI", "NamedPipe", "IPC", "Custom"]).optional().describe("Portal-only, and expected on every Portal. OMIT IT on any other componentType \u2014 passing it there is refused at the write (UNEXPECTED_PORTAL_FIELD), nothing is saved."),
|
|
44382
|
+
basePath: import_zod12.z.string().optional().describe("Portal-only: base path/prefix all the portal's endpoints mount under. OMIT IT on any other componentType \u2014 passing it there is refused at the write (UNEXPECTED_PORTAL_FIELD), nothing is saved."),
|
|
44383
|
+
dispatch: import_zod12.z.array(import_zod12.z.object({
|
|
44384
|
+
capability: import_zod12.z.string().describe('Capability name exactly as dispatched at runtime (e.g. "shadow_module.get")'),
|
|
44385
|
+
component: import_zod12.z.string().describe("Component id serving this capability (must also appear under dependsOn/owns)"),
|
|
44386
|
+
method: import_zod12.z.string().describe("Method name on the serving component's interface"),
|
|
44387
|
+
description: import_zod12.z.string().optional()
|
|
43357
44388
|
}).strict()).optional().describe("Portal-only: capability \u2192 component.method dispatch table for generic-handle portals. Gives the reachability walker real edges and is validated against target interfaces (UNSERVED_CAPABILITY)."),
|
|
43358
|
-
mounts:
|
|
43359
|
-
portal:
|
|
43360
|
-
prefixes:
|
|
43361
|
-
via:
|
|
44389
|
+
mounts: import_zod12.z.array(import_zod12.z.object({
|
|
44390
|
+
portal: import_zod12.z.string().describe("The mounted Portal's component id"),
|
|
44391
|
+
prefixes: import_zod12.z.array(import_zod12.z.string()).describe('The path prefixes this listener routes to the portal. A path lies under a prefix when it equals it or continues it past a slash, so "/" covers only the root itself'),
|
|
44392
|
+
via: import_zod12.z.string().optional().describe("The router entry the listener calls to hand the portal its request, exported by the PORTAL's own file (held to it: UNREALIZED_EXPORT_HANDLE). Omit when the listener calls the portal's contract methods directly, route by route")
|
|
43362
44393
|
}).strict()).optional().describe("Portal-only: the portals this LISTENER serves, each under its path prefixes and through its router entry. Declaring the field \u2014 even as an empty array \u2014 marks this portal as a listener, the one kind of portal nothing else needs to mount. Checked by portal-mounts: a mount must name a Portal (MOUNT_TARGET_NOT_PORTAL), every HTTP endpoint of a mounted portal must lie under one of its prefixes (ENDPOINT_OUTSIDE_MOUNT), and a portal with HTTP endpoints that is neither a listener nor mounted by one is reported (UNMOUNTED_PORTAL)."),
|
|
43363
|
-
durability:
|
|
43364
|
-
dependencyClass:
|
|
43365
|
-
emits:
|
|
43366
|
-
topic:
|
|
43367
|
-
event:
|
|
43368
|
-
description:
|
|
44394
|
+
durability: import_zod12.z.enum(["ram-projection", "durable", "read-through", "cache"]).optional().describe("Store-only \u2014 OMIT IT on any other componentType, where it is refused at the write (DURABILITY_ON_NON_STORE) and nothing is saved. Every Store should declare one (MISSING_DURABILITY): durable = persisted RAM projection (hydration read-back from a lifecycle init entrypoint required \u2014 MISSING_HYDRATION); read-through = persisted with no RAM copy (every read is the read-back, hydration exempt); ram-projection = rebuilt not restored; cache = evictable loss-safe memo state."),
|
|
44395
|
+
dependencyClass: import_zod12.z.enum(["pure", "read"]).optional().describe("Orchestrator-only \u2014 OMIT IT on any other componentType, where it is refused at the write (DEPENDENCY_CLASS_ON_NON_ORCHESTRATOR) and nothing is saved. Declares what logic may depend on, enforced as a Store's durability is (DEPENDENCY_CLASS_VIOLATION): pure = depends only on pure Orchestrators (a computation over the values it is handed, e.g. an arbiter or codec); read = also on read Orchestrators, Repositories, Indexes and Adapters, never calling their write methods; unset = a workflow."),
|
|
44396
|
+
emits: import_zod12.z.array(import_zod12.z.object({
|
|
44397
|
+
topic: import_zod12.z.string().describe("Topic/channel name exactly as used on the bus"),
|
|
44398
|
+
event: import_zod12.z.string().optional().describe("Optional event name within the topic (informational; pairing is by topic)"),
|
|
44399
|
+
description: import_zod12.z.string().optional()
|
|
43369
44400
|
}).strict()).optional().describe("Topics this component publishes \u2014 every emitted topic needs a subscriber somewhere in the tree (UNCONSUMED_TOPIC)."),
|
|
43370
|
-
subscribesTo:
|
|
43371
|
-
topic:
|
|
43372
|
-
event:
|
|
43373
|
-
description:
|
|
44401
|
+
subscribesTo: import_zod12.z.array(import_zod12.z.object({
|
|
44402
|
+
topic: import_zod12.z.string().describe("Topic/channel name exactly as used on the bus"),
|
|
44403
|
+
event: import_zod12.z.string().optional(),
|
|
44404
|
+
description: import_zod12.z.string().optional()
|
|
43374
44405
|
}).strict()).optional().describe("Topics this component consumes (typical on Observers) \u2014 every subscription needs an emitter somewhere in the tree (UNSOURCED_SUBSCRIPTION)."),
|
|
43375
|
-
ext:
|
|
44406
|
+
ext: import_zod12.z.record(import_zod12.z.unknown()).optional().describe('Opaque pack/tool extension data (namespaced keys, e.g. "mypack:priority") \u2014 preserved verbatim, never validated or interpreted by the core'),
|
|
43376
44407
|
status: statusInput
|
|
43377
44408
|
};
|
|
43378
44409
|
const componentInputFields = Object.keys(componentInput);
|
|
@@ -43420,45 +44451,45 @@ ${renderChangeReport(report2)}`,
|
|
|
43420
44451
|
}
|
|
43421
44452
|
}
|
|
43422
44453
|
);
|
|
43423
|
-
const methodParamItem =
|
|
43424
|
-
name:
|
|
43425
|
-
type:
|
|
43426
|
-
description:
|
|
43427
|
-
optional:
|
|
44454
|
+
const methodParamItem = import_zod12.z.object({
|
|
44455
|
+
name: import_zod12.z.string(),
|
|
44456
|
+
type: import_zod12.z.string().describe(TYPE_REF_GRAMMAR("The parameter's type")),
|
|
44457
|
+
description: import_zod12.z.string().optional(),
|
|
44458
|
+
optional: import_zod12.z.boolean().optional().describe(
|
|
43428
44459
|
'Whether the parameter may be OMITTED by a caller. It is not nullability: a parameter that must be passed but may be passed as nothing is a required parameter whose type says so \u2014 "ProjectConfig?". Say whichever is true; they are different contracts (both together: may be left out, and may be none).'
|
|
43429
44460
|
)
|
|
43430
44461
|
}).strict();
|
|
43431
44462
|
const interfaceMethodShape = {
|
|
43432
|
-
name:
|
|
43433
|
-
description:
|
|
43434
|
-
signature:
|
|
44463
|
+
name: import_zod12.z.string(),
|
|
44464
|
+
description: import_zod12.z.string(),
|
|
44465
|
+
signature: import_zod12.z.string().optional().describe(
|
|
43435
44466
|
"Prose signature \u2014 only for a method WITHOUT params. With params the server derives and writes the text (`name(a: T, b?: U): R`) and ignores this one (a notice names one that differed); a method with a signatureFrom states none."
|
|
43436
44467
|
),
|
|
43437
|
-
returns:
|
|
43438
|
-
signatureFrom:
|
|
44468
|
+
returns: import_zod12.z.string().optional().describe(TYPE_REF_GRAMMAR("The type the method answers with. Required unless signatureFrom is set, whose source supplies it")),
|
|
44469
|
+
signatureFrom: import_zod12.z.string().min(1).optional().describe(
|
|
43439
44470
|
"Take this method's params and returns from ONE source instead of stating them: a signature type id (`billing.change_listener`, `alias::name`) or a contract method `component.method` whose component this one names in dependsOn or owns (no chains). State it ALONE \u2014 params or returns beside it are refused (SIGNATURE_SOURCE_RESTATED). A value that names both a method and a signature type is ambiguous: qualify it."
|
|
43440
44471
|
),
|
|
43441
|
-
params:
|
|
43442
|
-
guarantees:
|
|
43443
|
-
effect:
|
|
43444
|
-
invokedBy:
|
|
43445
|
-
kind:
|
|
43446
|
-
caller:
|
|
44472
|
+
params: import_zod12.z.array(methodParamItem).optional().describe("Structured parameters \u2014 authoritative for type checking, and the signature text is derived from them. Strongly preferred."),
|
|
44473
|
+
guarantees: import_zod12.z.array(import_zod12.z.string().min(1)).optional().describe("Semantic guarantees the method promises (combinable); any guarantee a narrative step asserts must be declared here. Builtin tokens: idempotent | atomic | transactional | exactly-once; extension packs may declare more (any other token is UNKNOWN_GUARANTEE)"),
|
|
44474
|
+
effect: import_zod12.z.enum(["read", "write", "lifecycle"]).optional().describe("What the method does to the component's held state: read observes it; write modifies an entity's domain fields; lifecycle creates, destroys, or (un)registers an entity's existence or membership without modifying its fields, and calls only read and lifecycle methods (LIFECYCLE_CALLS_WRITE). Required on a durable Store's contract methods so the durability round-trip rule can pair mutations with hydration read-backs; a Supervisor may call a data component it does not own only through read and lifecycle methods (SUPERVISOR_WRITE_SHORTCUT)"),
|
|
44475
|
+
invokedBy: import_zod12.z.object({
|
|
44476
|
+
kind: import_zod12.z.enum(["runtime", "external", "sibling-subsystem"]).describe("Who owns the out-of-graph invocation: runtime (timer/signal/shutdown hook), external (a system outside this project), sibling-subsystem (a modeled sibling whose edge is not narrated here)"),
|
|
44477
|
+
caller: import_zod12.z.string().optional().describe("WHO invokes it and when, as reviewable prose \u2014 missing or placeholder-thin prose is INVOKED_BY_UNDESCRIBED")
|
|
43447
44478
|
}).strict().optional().describe("Typed acknowledgment of a real caller OUTSIDE the modeled narrative graph. Unused-detection seeds the method as an entrypoint so reachability propagates through its narrative (unlike lint.allow); a method the internal walk already reaches is flagged stale (INVOKED_BY_REDUNDANT). Prefer a `register` narrative step when the wiring is internal."),
|
|
43448
|
-
findings:
|
|
43449
|
-
code:
|
|
43450
|
-
severity:
|
|
43451
|
-
summary:
|
|
44479
|
+
findings: import_zod12.z.array(import_zod12.z.object({
|
|
44480
|
+
code: import_zod12.z.string().describe("UPPER_SNAKE finding code, unique within the method; a pack's codes carry the pack prefix (<PACK>_<CODE>)"),
|
|
44481
|
+
severity: import_zod12.z.enum(["error", "warning", "notice"]).describe("Default severity, before project severity overrides and draft-context downgrades. A notice is reported but never fails the gate"),
|
|
44482
|
+
summary: import_zod12.z.string().describe("One line saying what the finding means")
|
|
43452
44483
|
}).strict()).optional().describe("The finding codes this method can report, each with its default severity and summary. Each declared code must be anchored in the method's source file, as a string literal or a property-access name (UNREALIZED_FINDING). A code is declared once per method; sdd_update_spec upserts and deletes findings by code."),
|
|
43453
|
-
ext:
|
|
44484
|
+
ext: import_zod12.z.record(import_zod12.z.unknown()).optional().describe("Opaque pack/tool extension data for this method (namespaced keys) \u2014 preserved verbatim")
|
|
43454
44485
|
};
|
|
43455
44486
|
const interfaceMethodInputFields = Object.keys(interfaceMethodShape);
|
|
43456
44487
|
const interfaceInput = {
|
|
43457
|
-
id:
|
|
43458
|
-
name:
|
|
43459
|
-
description:
|
|
43460
|
-
component:
|
|
43461
|
-
methods:
|
|
44488
|
+
id: import_zod12.z.string().describe('Lowercase identifier prefixed with "i", e.g. "istorage"'),
|
|
44489
|
+
name: import_zod12.z.string().describe("Human-readable contract name"),
|
|
44490
|
+
description: import_zod12.z.string().describe("Contract description and obligations"),
|
|
44491
|
+
component: import_zod12.z.string().describe("The L2 component ID this interface belongs to"),
|
|
44492
|
+
methods: import_zod12.z.array(import_zod12.z.object(interfaceMethodShape).strict()).optional().describe("List of method signature contracts"),
|
|
43462
44493
|
status: statusInput
|
|
43463
44494
|
};
|
|
43464
44495
|
const interfaceInputFields = Object.keys(interfaceInput);
|
|
@@ -43495,24 +44526,24 @@ ${renderChangeReport(report2)}`,
|
|
|
43495
44526
|
{
|
|
43496
44527
|
description: "Bind concrete wire endpoints to existing L3 interface methods (required for every Portal). Pick `transport` and fill that transport's address fields. Run after sdd_define_interface. Written through the authoring seam as one gated delta, and answered with the change report \u2014 every binding set or changed, or that nothing changed \u2014 as structured content beside the sentence.",
|
|
43497
44528
|
inputSchema: {
|
|
43498
|
-
interface:
|
|
43499
|
-
endpoints:
|
|
43500
|
-
method:
|
|
43501
|
-
transport:
|
|
43502
|
-
httpMethod:
|
|
43503
|
-
path:
|
|
43504
|
-
service:
|
|
43505
|
-
rpcMethod:
|
|
43506
|
-
operation:
|
|
43507
|
-
field:
|
|
43508
|
-
topic:
|
|
43509
|
-
event:
|
|
43510
|
-
queue:
|
|
43511
|
-
direction:
|
|
43512
|
-
pipe:
|
|
43513
|
-
channel:
|
|
43514
|
-
command:
|
|
43515
|
-
address:
|
|
44529
|
+
interface: import_zod12.z.string().describe('The L3 interface ID (e.g. "ibilling-gateway")'),
|
|
44530
|
+
endpoints: import_zod12.z.array(import_zod12.z.object({
|
|
44531
|
+
method: import_zod12.z.string().describe("The NAME of the interface method to bind (not the HTTP verb)"),
|
|
44532
|
+
transport: import_zod12.z.enum(["HTTP", "gRPC", "GraphQL", "MessageBus", "NamedPipe", "IPC", "CLI", "Custom"]).describe("Wire protocol; must match the Portal's portalType"),
|
|
44533
|
+
httpMethod: import_zod12.z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"]).optional().describe("HTTP: verb"),
|
|
44534
|
+
path: import_zod12.z.string().optional().describe('HTTP: route path, e.g. "/v1/checkout"'),
|
|
44535
|
+
service: import_zod12.z.string().optional().describe("gRPC: service name"),
|
|
44536
|
+
rpcMethod: import_zod12.z.string().optional().describe("gRPC: rpc method name"),
|
|
44537
|
+
operation: import_zod12.z.enum(["query", "mutation", "subscription"]).optional().describe("GraphQL: operation kind"),
|
|
44538
|
+
field: import_zod12.z.string().optional().describe("GraphQL: root field name"),
|
|
44539
|
+
topic: import_zod12.z.string().optional().describe("MessageBus: topic"),
|
|
44540
|
+
event: import_zod12.z.string().optional().describe("MessageBus: event name"),
|
|
44541
|
+
queue: import_zod12.z.string().optional().describe("MessageBus: optional queue/consumer group"),
|
|
44542
|
+
direction: import_zod12.z.enum(["subscribe", "publish"]).optional().describe("MessageBus: subscribe (default) or publish"),
|
|
44543
|
+
pipe: import_zod12.z.string().optional().describe('NamedPipe: pipe name, e.g. "\\\\.\\pipe\\gk-events"'),
|
|
44544
|
+
channel: import_zod12.z.string().optional().describe("IPC: channel name"),
|
|
44545
|
+
command: import_zod12.z.string().optional().describe("CLI: command/subcommand"),
|
|
44546
|
+
address: import_zod12.z.string().optional().describe("Custom: free-form address")
|
|
43516
44547
|
}).strict()).describe("One binding per method")
|
|
43517
44548
|
},
|
|
43518
44549
|
outputSchema: specChangeReportOutput
|
|
@@ -43554,80 +44585,80 @@ ${renderChangeReport(report2)}`,
|
|
|
43554
44585
|
methods.push({ name: e.method, endpoint: parsed.data });
|
|
43555
44586
|
bound2.push(`${e.method}\u2192${e.transport}`);
|
|
43556
44587
|
}
|
|
43557
|
-
const
|
|
44588
|
+
const report3 = updateSpecGated("interface", interfaceId, { methods });
|
|
43558
44589
|
return structured(
|
|
43559
44590
|
`Bound ${bound2.length} endpoint(s) on "${interfaceId}": ${bound2.join(", ")}.
|
|
43560
|
-
${renderChangeReport(
|
|
43561
|
-
|
|
44591
|
+
${renderChangeReport(report3)}`,
|
|
44592
|
+
report3
|
|
43562
44593
|
);
|
|
43563
44594
|
} catch (e) {
|
|
43564
44595
|
return errMessage(e);
|
|
43565
44596
|
}
|
|
43566
44597
|
}
|
|
43567
44598
|
);
|
|
43568
|
-
const stepNo = () =>
|
|
43569
|
-
const labelRef = () =>
|
|
43570
|
-
const narrativeStepInput =
|
|
44599
|
+
const stepNo = () => import_zod12.z.number().int().positive();
|
|
44600
|
+
const labelRef = () => import_zod12.z.string().min(1);
|
|
44601
|
+
const narrativeStepInput = import_zod12.z.object({
|
|
43571
44602
|
stepNumber: stepNo().optional().describe("Defaults to the 1-based array position \u2014 jump fields reference these numbers"),
|
|
43572
44603
|
label: labelRef().optional().describe("Optional symbolic anchor for this step (unique per narrative). Every jump-by-number field has a *Label twin resolved against these anchors at write time \u2014 prefer labels over hand-counted step numbers"),
|
|
43573
|
-
description:
|
|
43574
|
-
type:
|
|
43575
|
-
targetComponent:
|
|
43576
|
-
targetMethod:
|
|
43577
|
-
auth:
|
|
43578
|
-
detach:
|
|
43579
|
-
capability:
|
|
43580
|
-
assertsGuarantees:
|
|
43581
|
-
assertsInvariants:
|
|
43582
|
-
condition:
|
|
44604
|
+
description: import_zod12.z.string(),
|
|
44605
|
+
type: import_zod12.z.enum(["local", "call", "dispatch", "register", "branch", "switch", "loop", "try", "parallel", "jump", "return", "throw"]),
|
|
44606
|
+
targetComponent: import_zod12.z.string().optional().describe("call/register/dispatch: L2 component id (for dispatch, the Portal routed through)"),
|
|
44607
|
+
targetMethod: import_zod12.z.string().optional().describe("call/register: method name on the target. A register step hands the target method to the runtime as a callback (timer, event listener, shutdown hook): reachability follows the edge, but it is never an invocation \u2014 exempt from call-graph conformance, call-cycle detection, and the durability boot walk"),
|
|
44608
|
+
auth: import_zod12.z.object({ from: import_zod12.z.string(), note: import_zod12.z.string().optional() }).strict().optional().describe("call/dispatch: the credential this step presents to an AUTHED callee Portal and WHERE it loads from (`from`). Opaque form (env:API_KEY, a config key, vault:path) = a design note wairon never resolves; modeled form `component:<id>` references the Adapter/Store that provides the secret and is validated (must resolve, be an Adapter/Store, and be wired to the presenter). Absence on a call into a Portal whose auth \u2260 none warns (PORTAL_AUTH_UNMET). The authenticated call itself should be made by an Adapter (AUTH_PRESENTER_NOT_ADAPTER)."),
|
|
44609
|
+
detach: import_zod12.z.boolean().optional().describe("call/dispatch: fire-and-forget \u2014 issue the call and continue without awaiting the result (no later step consumes it)"),
|
|
44610
|
+
capability: import_zod12.z.string().optional().describe("dispatch: the capability routed through the target Portal's dispatch table (validated against it \u2014 UNSERVED_CAPABILITY)"),
|
|
44611
|
+
assertsGuarantees: import_zod12.z.array(import_zod12.z.string().min(1)).optional().describe("Semantic guarantees this step relies on \u2014 each must be declared in the called method's L3 guarantees (NARRATIVE_SEMANTIC_UNBACKED otherwise). Builtin tokens: idempotent | atomic | transactional | exactly-once; extension packs may declare more (any other token is UNKNOWN_GUARANTEE)"),
|
|
44612
|
+
assertsInvariants: import_zod12.z.array(import_zod12.z.string()).optional().describe(`Declared entity invariants this step upholds, as "<type-id>.<invariant-id>" refs (UNKNOWN_INVARIANT_REF when unresolved); write-effect methods of the entity's componentClass must carry one per declared invariant (UNASSERTED_INVARIANT)`),
|
|
44613
|
+
condition: import_zod12.z.string().optional().describe("branch / while / doWhile"),
|
|
43583
44614
|
onTrueStep: stepNo().optional().describe("branch: default = next step"),
|
|
43584
44615
|
onTrueLabel: labelRef().optional().describe("branch: symbolic alternative to onTrueStep"),
|
|
43585
44616
|
onFalseStep: stepNo().optional().describe("branch: required (or onFalseLabel)"),
|
|
43586
44617
|
onFalseLabel: labelRef().optional().describe("branch: symbolic alternative to onFalseStep"),
|
|
43587
|
-
on:
|
|
43588
|
-
cases:
|
|
44618
|
+
on: import_zod12.z.string().optional().describe("switch: the dispatched value"),
|
|
44619
|
+
cases: import_zod12.z.array(import_zod12.z.object({ value: import_zod12.z.string(), step: stepNo().optional(), label: labelRef().optional() }).strict()).optional().describe("switch: required; each case targets its region by step number or label"),
|
|
43589
44620
|
defaultStep: stepNo().optional().describe("switch: default = next step"),
|
|
43590
44621
|
defaultLabel: labelRef().optional().describe("switch: symbolic alternative to defaultStep"),
|
|
43591
|
-
loopKind:
|
|
43592
|
-
over:
|
|
44622
|
+
loopKind: import_zod12.z.enum(["forEach", "for", "while", "doWhile"]).optional().describe('loop: default forEach when "over" is set, else while'),
|
|
44623
|
+
over: import_zod12.z.string().optional().describe("loop forEach/for: iteration source"),
|
|
43593
44624
|
endStep: stepNo().optional().describe("loop/try: last step of the body region (required, or endLabel)"),
|
|
43594
44625
|
endLabel: labelRef().optional().describe("loop/try: symbolic alternative to endStep"),
|
|
43595
|
-
catches:
|
|
44626
|
+
catches: import_zod12.z.array(import_zod12.z.object({ error: import_zod12.z.string(), step: stepNo().optional(), label: labelRef().optional() }).strict()).optional().describe("try: handler regions, each targeted by step number or label"),
|
|
43596
44627
|
finallyStep: stepNo().optional().describe("try: first step of the always-runs region"),
|
|
43597
44628
|
finallyLabel: labelRef().optional().describe("try: symbolic alternative to finallyStep"),
|
|
43598
|
-
branches:
|
|
44629
|
+
branches: import_zod12.z.array(import_zod12.z.object({ step: stepNo().optional(), label: labelRef().optional(), name: import_zod12.z.string().optional() }).strict()).optional().describe("parallel: >= 2 arm entries (step number or label), ascending, first = the step after the header; arms are contiguous sub-regions of body next..endStep, joining after endStep once ALL complete"),
|
|
43599
44630
|
toStep: stepNo().optional().describe("jump: required (break/continue/rejoin), or toLabel"),
|
|
43600
44631
|
toLabel: labelRef().optional().describe("jump: symbolic alternative to toStep \u2014 resolves to the labeled step at write time"),
|
|
43601
|
-
outcome:
|
|
43602
|
-
error:
|
|
44632
|
+
outcome: import_zod12.z.string().optional().describe('return: e.g. "success", "not found"'),
|
|
44633
|
+
error: import_zod12.z.string().optional().describe("throw: the raised error")
|
|
43603
44634
|
}).strict();
|
|
43604
|
-
const detailEnum =
|
|
43605
|
-
const conformanceEnum =
|
|
44635
|
+
const detailEnum = import_zod12.z.enum(["full", "calls-only", "intent"]);
|
|
44636
|
+
const conformanceEnum = import_zod12.z.enum(["declared", "anchored", "off"]);
|
|
43606
44637
|
const implMethodShape = {
|
|
43607
|
-
name:
|
|
43608
|
-
sourcePath:
|
|
44638
|
+
name: import_zod12.z.string(),
|
|
44639
|
+
sourcePath: import_zod12.z.string().optional().describe("Optional: the source file realizing THIS method when it is not the implementation's sourcePath (e.g. a command whose body lives in its own file); the implementation's sourcePath is the default. Relative to project root \u2014 for a chained subproject's implementation (qualified id), relative to that subproject's root; a path given relative to this root that lands inside the subproject is re-expressed for you"),
|
|
43609
44640
|
detail: detailEnum.optional().describe("Detail level for this method (overrides the spec default)"),
|
|
43610
|
-
intent:
|
|
44641
|
+
intent: import_zod12.z.string().optional().describe("detail: intent \u2014 behavioral prose (what it does and how it fails); substitute for a narrative"),
|
|
43611
44642
|
conformance: conformanceEnum.optional().describe("Conformance tier for this method (overrides the spec default)"),
|
|
43612
|
-
symbol:
|
|
43613
|
-
exportedVia:
|
|
43614
|
-
ext:
|
|
43615
|
-
narrative:
|
|
43616
|
-
calls:
|
|
44643
|
+
symbol: import_zod12.z.string().optional().describe("Code-level name realizing this contract method in the sourcePath file, when it legitimately differs from the intent-language contract name (e.g. put realized by saveSnapshot)"),
|
|
44644
|
+
exportedVia: import_zod12.z.string().optional().describe("The exported binding a consumer imports to REACH this method, when the realization is published as a value that composes it rather than exported in its own right (a rule module publishes callConformanceRule, and the method is the check inside it). Not symbol, which names the function itself: this names the route to it, so the surface check reads that export as promised. A handle the method's own source file does not actually export is reported (UNREALIZED_EXPORT_HANDLE) and allows nothing"),
|
|
44645
|
+
ext: import_zod12.z.record(import_zod12.z.unknown()).optional().describe("Opaque pack/tool extension data for this method (namespaced keys) \u2014 preserved verbatim"),
|
|
44646
|
+
narrative: import_zod12.z.array(narrativeStepInput).optional(),
|
|
44647
|
+
calls: import_zod12.z.array(import_zod12.z.string().min(1)).optional().describe('The calls this method makes, when its narrative does not show them (detail: intent, or calls-only with no steps authored) \u2014 each as "<component>.<method>", the spelling the debt register and lint allows name a unit with. The narrative walk takes exactly these edges and no others, so an undeclared collaborator is NOT reached: this is what keeps unused-detection honest at a lower detail dial. Each entry is validated like a call step (the component resolves, this component declares it, the method is on its contract). Refused beside a non-empty narrative \u2014 add the call step there instead')
|
|
43617
44648
|
};
|
|
43618
44649
|
const implMethodInputFields = Object.keys(implMethodShape);
|
|
43619
44650
|
const implInput = {
|
|
43620
|
-
id:
|
|
43621
|
-
name:
|
|
43622
|
-
description:
|
|
43623
|
-
contract:
|
|
43624
|
-
sourcePath:
|
|
43625
|
-
simPath:
|
|
43626
|
-
technologies:
|
|
43627
|
-
injectedParams:
|
|
44651
|
+
id: import_zod12.z.string().describe('Lowercase identifier, e.g. "vfs_storage"'),
|
|
44652
|
+
name: import_zod12.z.string().describe("Human-readable implementation name"),
|
|
44653
|
+
description: import_zod12.z.string().describe("Implementation details"),
|
|
44654
|
+
contract: import_zod12.z.string().describe("The L3 Interface contract ID this implements"),
|
|
44655
|
+
sourcePath: import_zod12.z.string().optional().describe("Optional: target source code file path relative to project root \u2014 for a chained subproject's implementation (qualified id), relative to that subproject's root; a path given relative to this root that lands inside the subproject is re-expressed for you"),
|
|
44656
|
+
simPath: import_zod12.z.string().optional().describe("Optional: the committed integration-sim harness file (project-relative; N:1 sharing allowed). The validator proves it exists and its import graph wires the REAL modules (this component + each direct dependency; technology adapters may stay faked) \u2014 running it is CI's job. Declaring the first simPath in a subsystem activates MISSING_INTEGRATION_SIM for its other complete non-leaf implementations"),
|
|
44657
|
+
technologies: import_zod12.z.array(import_zod12.z.union([import_zod12.z.string(), import_zod12.z.object({ name: import_zod12.z.string(), matches: import_zod12.z.array(import_zod12.z.string()).min(1).describe("The tokens the leakage and contract checks match INSTEAD of the name \u2014 for a technology whose name is also an ordinary word of the tree (the yaml package, the YAML format)") }).strict()])).optional().describe(`External technologies this implementation binds to (e.g. ["mysql"], or [{ "name": "yaml", "matches": ["yaml package", "parseDocument"] }] when the bare name would match a common word) \u2014 declares this component's ownership tree as the technology's home; references outside it are flagged (TECH_LEAKAGE) and contract identifiers must stay intent-language. Only for Adapter/Store/Registry/Index components.`),
|
|
44658
|
+
injectedParams: import_zod12.z.array(import_zod12.z.string()).optional().describe("The parameter names this realization takes BEFORE the ones its contract declares \u2014 a config object, a data root, the transport handles a portal is handed. Supplied by whatever wires the component up, never by the caller the contract describes, which is why they belong here and not to the contract: another realization may hold them as fields instead. Declared rather than guessed, because a leading parameter the contract does not name cannot be told from one it named under a different name (`seed(config)` realized as `bootstrapInstance(cfg)`); a leading parameter this list does not name is reported (UNDECLARED_PARAM). Only a LEADING run is dropped \u2014 one of these names appearing after the contract's own parameters is an argument in the middle of the caller's list, not wiring"),
|
|
43628
44659
|
detail: detailEnum.optional().describe("Spec-level narrative detail default for all methods"),
|
|
43629
44660
|
conformance: conformanceEnum.optional().describe("Spec-level conformance tier default: declared | anchored | off (omitted = stereotype default: Portal \u2192 anchored, else declared)"),
|
|
43630
|
-
methods:
|
|
44661
|
+
methods: import_zod12.z.array(import_zod12.z.object(implMethodShape).strict()).optional().describe("Method implementations containing L5 narratives"),
|
|
43631
44662
|
status: statusInput
|
|
43632
44663
|
};
|
|
43633
44664
|
const implInputFields = Object.keys(implInput);
|
|
@@ -43674,46 +44705,46 @@ ${renderChangeReport(report2)}`,
|
|
|
43674
44705
|
}
|
|
43675
44706
|
);
|
|
43676
44707
|
const typeInput = {
|
|
43677
|
-
kind:
|
|
43678
|
-
id:
|
|
43679
|
-
name:
|
|
43680
|
-
description:
|
|
43681
|
-
subsystem:
|
|
43682
|
-
group:
|
|
43683
|
-
fields:
|
|
43684
|
-
name:
|
|
43685
|
-
type:
|
|
43686
|
-
description:
|
|
43687
|
-
optional:
|
|
43688
|
-
key:
|
|
43689
|
-
references:
|
|
44708
|
+
kind: import_zod12.z.enum(["entity", "value-object", "signature", "enum"]).describe("entity (owned by a subsystem), value-object (often system-level shared), signature \u2014 a named function type: params and returns, nothing else \u2014 or enum: a closed, ordered set of named values"),
|
|
44709
|
+
id: import_zod12.z.string().describe("Lowercase identifier"),
|
|
44710
|
+
name: import_zod12.z.string().describe("Human-readable name"),
|
|
44711
|
+
description: import_zod12.z.string().optional(),
|
|
44712
|
+
subsystem: import_zod12.z.string().optional().describe("Owning subsystem id; omit for a system-level shared value object. A subsystem the tree does not have is refused and nothing is written"),
|
|
44713
|
+
group: import_zod12.z.string().optional().describe("Optional logical group ID to organize this type in subfolders"),
|
|
44714
|
+
fields: import_zod12.z.array(import_zod12.z.object({
|
|
44715
|
+
name: import_zod12.z.string(),
|
|
44716
|
+
type: import_zod12.z.string().describe(TYPE_REF_GRAMMAR("The field's type")),
|
|
44717
|
+
description: import_zod12.z.string().optional(),
|
|
44718
|
+
optional: import_zod12.z.boolean().optional(),
|
|
44719
|
+
key: import_zod12.z.enum(["primary", "unique", "foreign"]).optional().describe("Identity marker (PK/unique/FK) for ERD and database schema derivation"),
|
|
44720
|
+
references: import_zod12.z.string().optional().describe('For foreign keys, the referenced type/table id and optional field, e.g. "invoice.id"')
|
|
43690
44721
|
}).strict()).optional().describe('Data fields (type is a primitive or a qualified type id, e.g. "billing.Invoice")'),
|
|
43691
|
-
methods:
|
|
43692
|
-
name:
|
|
43693
|
-
signature:
|
|
43694
|
-
params:
|
|
43695
|
-
returns:
|
|
43696
|
-
description:
|
|
43697
|
-
sourcePath:
|
|
43698
|
-
symbol:
|
|
44722
|
+
methods: import_zod12.z.array(import_zod12.z.object({
|
|
44723
|
+
name: import_zod12.z.string(),
|
|
44724
|
+
signature: import_zod12.z.string().optional().describe("Prose signature \u2014 only for a method WITHOUT params; with params the server derives and writes the text"),
|
|
44725
|
+
params: import_zod12.z.array(methodParamItem).optional().describe("Structured parameters \u2014 authoritative for type checking; the signature text is derived from them"),
|
|
44726
|
+
returns: import_zod12.z.string().describe(TYPE_REF_GRAMMAR("The type the method answers with")),
|
|
44727
|
+
description: import_zod12.z.string().optional(),
|
|
44728
|
+
sourcePath: import_zod12.z.string().optional().describe("Source file realizing this method when the type's own sourcePath does not hold it \u2014 a pure type method often lives apart from the declaration"),
|
|
44729
|
+
symbol: import_zod12.z.string().optional().describe("Code-level name realizing this method when it differs from the method name, e.g. narrative_step.foreignFields realized by narrativeStepForeignFields")
|
|
43699
44730
|
}).strict()).optional().describe("Pure intrinsic methods only"),
|
|
43700
|
-
componentClass:
|
|
43701
|
-
invariants:
|
|
43702
|
-
id:
|
|
43703
|
-
description:
|
|
44731
|
+
componentClass: import_zod12.z.string().optional().describe("Optional component id that implements or owns this logical entity"),
|
|
44732
|
+
invariants: import_zod12.z.array(import_zod12.z.object({
|
|
44733
|
+
id: import_zod12.z.string().describe("Stable invariant id, unique within the entity"),
|
|
44734
|
+
description: import_zod12.z.string().describe("The property that must hold, stated precisely")
|
|
43704
44735
|
}).strict()).optional().describe("Declared domain invariants (entities): every write-effect method of the componentClass must carry a narrative step asserting each (assertsInvariants) \u2014 declarations checked, enforcement never proven"),
|
|
43705
|
-
database:
|
|
43706
|
-
table:
|
|
43707
|
-
linkedEntity:
|
|
43708
|
-
sourcePath:
|
|
43709
|
-
symbol:
|
|
43710
|
-
params:
|
|
43711
|
-
returns:
|
|
43712
|
-
values:
|
|
43713
|
-
name:
|
|
43714
|
-
description:
|
|
44736
|
+
database: import_zod12.z.string().optional().describe("Optional database id for table-schema types"),
|
|
44737
|
+
table: import_zod12.z.string().optional().describe("Optional database table name for table-schema types"),
|
|
44738
|
+
linkedEntity: import_zod12.z.string().optional().describe("Optional logical entity id represented by this table-schema type"),
|
|
44739
|
+
sourcePath: import_zod12.z.string().optional().describe("Source file holding the declaration of this type (project-relative). Naming one turns the type into a claim on code: the file must resolve and the declaration must be anchored in it (UNREALIZED_TYPE)"),
|
|
44740
|
+
symbol: import_zod12.z.string().optional().describe('Code-level name realizing the declaration when it differs from name, e.g. a type named "Invoice Line" declared as InvoiceLine'),
|
|
44741
|
+
params: import_zod12.z.array(methodParamItem).optional().describe("kind signature only: the function type's parameters, in declared order (SIGNATURE_TYPE_MEMBERS on any other kind)"),
|
|
44742
|
+
returns: import_zod12.z.string().optional().describe(TYPE_REF_GRAMMAR("kind signature only, and required there: the function type's one output")),
|
|
44743
|
+
values: import_zod12.z.array(import_zod12.z.object({
|
|
44744
|
+
name: import_zod12.z.string().min(1).describe(`The value's name, exactly as data carries it ("stable", "local_only")`),
|
|
44745
|
+
description: import_zod12.z.string().optional().describe("What the value means")
|
|
43715
44746
|
}).strict()).optional().describe("kind enum only, and required there: the values in declared order \u2014 the order is part of the design (a narrowest-first track list means something). Unique by name ignoring case and separators; no ordinals and no separate wire value"),
|
|
43716
|
-
holds:
|
|
44747
|
+
holds: import_zod12.z.string().optional().describe('kind value-object only: makes it a NAMED SCALAR \u2014 one primitive under a name (string, int, float, bool, bytes, date, datetime or duration), a newtype or type alias in every language (`type PackPath = string`), declared in place of fields. Not a union, not a named type, not any; fields beside it, or holds on another kind, is NAMED_SCALAR_MEMBERS. Aliases are respelled (boolean \u2192 bool) and number is refused ("int or float?")')
|
|
43717
44748
|
};
|
|
43718
44749
|
const typeInputFields = Object.keys(typeInput);
|
|
43719
44750
|
reg(
|
|
@@ -43770,9 +44801,9 @@ ${renderChangeReport(report2)}`,
|
|
|
43770
44801
|
{
|
|
43771
44802
|
description: "Validate the SDD spec tree, checking parent references, contract compatibility, narratives, and component type boundaries. Supports scoping and recursion controls. Findings come back as structured content too, under the schema this tool declares \u2014 errors, warnings and notices already split into three lists (a notice never makes the tree invalid and never fails --ci), each with its code, severity, message and the spec it concerns \u2014 so a caller filters them as objects instead of parsing the JSON text block and hoping its shape holds.",
|
|
43772
44803
|
inputSchema: {
|
|
43773
|
-
subsystem:
|
|
43774
|
-
recursive:
|
|
43775
|
-
family:
|
|
44804
|
+
subsystem: import_zod12.z.string().optional().describe("Only validate the specified subsystem (granular)"),
|
|
44805
|
+
recursive: import_zod12.z.boolean().optional().describe("At a project that declares members: the family run (true, the default) or the owner's gate alone (false)"),
|
|
44806
|
+
family: import_zod12.z.boolean().optional().describe("Ask for the family run explicitly: every member's own gate, and this project's externals composed against their live producers within the request's reach (`wairon validate --family`)")
|
|
43776
44807
|
},
|
|
43777
44808
|
outputSchema: validateTreeOutput
|
|
43778
44809
|
},
|
|
@@ -43813,9 +44844,9 @@ ${renderChangeReport(report2)}`,
|
|
|
43813
44844
|
{
|
|
43814
44845
|
description: `Get/read the parsed JSON contents of a specific spec from the spec tree. Returns structural contents without file system path searching. Pass "methods" to read only the named methods of a contract, an implementation or a type \u2014 a 45-method spec fetched whole to look at one of them is the read side of the same waste a restatement is on the write side; the answer then carries a "partialResult" marker naming what was left out, and must never be re-authored from. For a variant-tagged COMPONENT the result also carries a derived, read-only "variantGuidance" (the variant's base, its implementation guidance, and the same-variant sibling components to implement alike) \u2014 it is resolved from the variant registry, not part of the spec, so never write it back. A contract's methods come back in their STORED form \u2014 a method that takes its signature from a source carries its signatureFrom, not the params the loader resolves into it \u2014 so the answer can be re-authored from as it is; the resolved params, returns and text of each such method come back as a derived, read-only "resolvedSignatures" marker. The structured content carries the same answer with the derived markers KEPT SEPARATE from the stored spec ({kind, id, spec, partialResult?, variantGuidance?, resolvedSignatures?}), so nothing derived can be mistaken for something stored; the text block folds them in as it always has.`,
|
|
43815
44846
|
inputSchema: {
|
|
43816
|
-
kind:
|
|
43817
|
-
id:
|
|
43818
|
-
methods:
|
|
44847
|
+
kind: import_zod12.z.enum(["system", "subsystem", "component", "interface", "implementation", "type"]).describe("The kind of specification"),
|
|
44848
|
+
id: import_zod12.z.string().describe('The identifier of the spec to fetch (the L0 system spec is a singleton \u2014 pass the system name or "system")'),
|
|
44849
|
+
methods: import_zod12.z.array(import_zod12.z.string().min(1)).optional().describe("Return only these methods by name; every other field of the spec comes back unchanged. Only an interface, an implementation or a type declares methods \u2014 asking for one elsewhere is refused, as is a name the spec does not declare (the answer names the ones it does). Omit it for the whole spec.")
|
|
43819
44850
|
},
|
|
43820
44851
|
outputSchema: getSpecOutput
|
|
43821
44852
|
},
|
|
@@ -43900,8 +44931,8 @@ ${renderChangeReport(report2)}`,
|
|
|
43900
44931
|
{
|
|
43901
44932
|
description: "Delete a specification file from the spec tree and clean up any empty parent directories. Answers with a structured deletion beside the sentence: whether a spec was removed, and the tests that encode a method the deletion took away (when the project declares test roots).",
|
|
43902
44933
|
inputSchema: {
|
|
43903
|
-
kind:
|
|
43904
|
-
id:
|
|
44934
|
+
kind: import_zod12.z.enum(["subsystem", "component", "interface", "implementation", "type"]).describe("The kind of spec to delete"),
|
|
44935
|
+
id: import_zod12.z.string().describe("The ID of the spec to delete")
|
|
43905
44936
|
},
|
|
43906
44937
|
outputSchema: specDeletionOutput
|
|
43907
44938
|
},
|
|
@@ -43923,17 +44954,17 @@ ${testsBlock}` : ""}`, deletion);
|
|
|
43923
44954
|
{
|
|
43924
44955
|
description: "Update/patch an existing SDD specification (subsystem, component, interface, implementation, or type) using a granular delta. Updates fields, appends/merges array elements, or inserts/deletes narrative steps. Answers with exactly what changed, and with every path the delta named that the write did not act on. Type positions (the type of a param, a returns, the type of a field, the params and returns of a signature) are written in the neutral type grammar: an alias the delta writes (string[], T | null, boolean, Promise<T>) is stored canonical and listed under `respellings`, and a stored alias at a position the write keeps is respelled with it; a position the delta writes that has no canonical spelling (number \u2014 int or float?, an inline object or function type, a literal union, a union mixing in a primitive) is refused, naming the replacement, while one the stored spec already held is left alone. Pass dryRun to be told what it would do without writing it.",
|
|
43925
44956
|
inputSchema: {
|
|
43926
|
-
kind:
|
|
43927
|
-
id:
|
|
43928
|
-
delta:
|
|
43929
|
-
dryRun:
|
|
44957
|
+
kind: import_zod12.z.enum(["system", "subsystem", "component", "interface", "implementation", "type"]).describe("The spec kind to update (system = the singleton L0 \u2014 vision, boundaries, globalRequirements, databases, and publicInterfaces: the project export table, each entry a re-export {from, component, interface, typeDef, as, name, type, details, audience: project|department|instance|partner|external} \u2014 from alone re-exports everything a subsystem exports, and a legacy {id, subsystem} reads as {as, from})"),
|
|
44958
|
+
id: import_zod12.z.string().describe("The ID of the spec to update (namespaced if needed)"),
|
|
44959
|
+
delta: import_zod12.z.record(import_zod12.z.any()).describe(`The partial fields to merge into the spec. ARRAYS UPSERT, they do not replace: an array whose elements carry an identity is merged element-by-element, so a delta naming ONE element leaves the others intact. Identity is "name" or "id" by default, and per field: dispatch by "capability", a listener's mounts by "portal", lifecycle by phase+component+method, emits/subscribesTo by topic+event, trustedLinks by "subsystem", a subsystem's publicInterfaces by component+interface (or type+details for an entry not yet bound to a component, and by from+item+interface+as for a re-export or a type export), invariants and patterns by "id", lint.allow by "code" AND "at" (an allow covers one occurrence, so several may share a code on one spec), an interface method's findings by "code", boundaries by "name", globalRequirements by "description", switch cases by "value", try catches by "error". Identity merging applies at EVERY depth, including an array INSIDE an element (a method's params, a step's catches). Add "action: 'delete'" (or "remove: true") alongside that identity to REMOVE an element \u2014 including a stale lint allow. Arrays of plain STRINGS (owns, dependsOn, guarantees) carry no per-element identity and are replaced wholesale; pass [] to clear any array outright. To REMOVE an optional field entirely, list it in "unset": e.g. {"unset": ["basePath", "variant"]} \u2014 passing null/undefined means "no change" (they are skipped), and writing "" would leave the field present but empty, which is a different and usually wrong spec. Unsetting a required field is refused by schema validation, which names it. For narrative steps, match by "stepNumber" and use "action: 'insert'" (shifts subsequent steps up) or "action: 'delete'" (shifts subsequent steps down and removes it). Step entries apply in ASCENDING stepNumber order, each against the numbering the earlier entries of the SAME delta left behind \u2014 delete step 3 and step 7 becomes step 6 \u2014 so prefer labels, and restate the step's "label" or "description" on a delete to have it checked against the step actually addressed. Renumbering RELOCATES every flow jump field (onTrueStep/onFalseStep/cases.step/defaultStep/endStep/catches.step/finallyStep/toStep) in the same narrative. Only STORED jumps relocate: a jump the delta itself writes (on an inserted, appended or edited step) names its target in the numbering the WHOLE delta leaves behind, after all of its inserts and deletes, and no later step of the same delta moves it. A method the delta ADDS without a narrative is an intent-level method with none ([]). An element the delta NAMES merges field by field: a field it leaves out, or passes as null, keeps its stored value at EVERY depth (a method named without "narrative" keeps its steps, a step named without "catches" keeps them), while "narrative": [] CLEARS that method's steps \u2014 so leave a method you are not editing out of the delta. A delete is REJECTED when the narrative has no such step, when a jump still targets it (retarget the referrers first), when a restated label/description does not match, or when it is a loop/try/parallel header whose body would be left standing (retype the header first to dissolve the region, then delete it). Changing a step's "type" REBUILDS it for the new type: its description and label are kept and every field the new type cannot carry is dropped (returned as a NOTICE); a delta that retypes AND sets such a field is refused. A step delta is also refused when it carries a marker the merge does not recognise: a non-boolean "remove", an "action" that is neither "insert" nor "delete", a "captureJumps" outside an insert, or no "stepNumber" to address. Inserting AT a jump target relocates those jumps past the inserted step by default (a NOTICE is returned) \u2014 add "captureJumps": true on the inserted step to retarget entry jumps onto it (loop/try endStep region tails always relocate with the body and are never captured). Every jump field has a "*Label" twin (toLabel, onFalseLabel, endLabel, \u2026, and "label" on a cases/catches entry) resolved against step labels AFTER the merge, so a delta may anchor on a label only pre-existing steps carry; a label the delta supplies REPLACES the stored number it twins, while setting the number and its label together in one delta is refused as a contradiction. Reference ids in deltas may use LOCAL names \u2014 they are qualified against the spec's namespace exactly as the loader would. Per-spec lint suppression: set "lint: { allow: [{ code, at, covers, reason }] }" to silence a WARNING or NOTICE code on this spec only (errors always surface; stale allows are flagged). An allow covers EXACTLY the occurrence it names: "at" is the site the finding names (a contract method, an import edge "from -> to", a declared edge "component -> target") and is REQUIRED for a code whose findings report one, while a finding that reports no site is covered only by an allow that names none; "covers" lists the units an aggregating finding reports, and the allow silences it only when every one is listed. This delta is deliberately OPEN below its top level \u2014 the shapes nest further than a schema here should restate \u2014 so a key that is not a field at its depth is not refused, it is NAMED BACK under NO EFFECT in the answer, together with any value the spec already held and any "unset" that removed nothing. Read that list: it is where a nested typo shows up.`),
|
|
44960
|
+
dryRun: import_zod12.z.boolean().optional().describe("Ask what this delta WOULD do instead of doing it. The whole write runs, the candidate gate included, and the answer is the change report it would have produced \u2014 marked DRY RUN, with nothing stamped and not one byte of the stored file moved. Use it before a delta that renumbers a long narrative.")
|
|
43930
44961
|
},
|
|
43931
44962
|
outputSchema: specChangeReportOutput
|
|
43932
44963
|
},
|
|
43933
44964
|
({ kind, id, delta, dryRun }) => {
|
|
43934
44965
|
try {
|
|
43935
|
-
const
|
|
43936
|
-
return structured(renderChangeReport(
|
|
44966
|
+
const report3 = updateSpecGated(kind, id, delta, dryRun);
|
|
44967
|
+
return structured(renderChangeReport(report3), report3);
|
|
43937
44968
|
} catch (e) {
|
|
43938
44969
|
return errText(String(e));
|
|
43939
44970
|
}
|
|
@@ -43945,8 +44976,8 @@ ${testsBlock}` : ""}`, deletion);
|
|
|
43945
44976
|
{
|
|
43946
44977
|
description: "Get the completeness status dashboard of the SDD spec tree. Supports scoping and recursion controls.",
|
|
43947
44978
|
inputSchema: {
|
|
43948
|
-
subsystem:
|
|
43949
|
-
recursive:
|
|
44979
|
+
subsystem: import_zod12.z.string().optional().describe("Only show status for the specified subsystem"),
|
|
44980
|
+
recursive: import_zod12.z.boolean().optional().describe("Whether to descend into the members this project declares (default: true)")
|
|
43950
44981
|
}
|
|
43951
44982
|
},
|
|
43952
44983
|
({ subsystem, recursive }) => {
|
|
@@ -43960,14 +44991,14 @@ ${testsBlock}` : ""}`, deletion);
|
|
|
43960
44991
|
} catch {
|
|
43961
44992
|
approvals = void 0;
|
|
43962
44993
|
}
|
|
43963
|
-
const
|
|
44994
|
+
const report3 = getStatusReport({
|
|
43964
44995
|
subsystem,
|
|
43965
44996
|
memberDepth,
|
|
43966
44997
|
approvals
|
|
43967
44998
|
});
|
|
43968
44999
|
const family = statusFamilyContext();
|
|
43969
45000
|
const verdict = approvalVerdict(approvals);
|
|
43970
|
-
return text2(`${banner}${family}${
|
|
45001
|
+
return text2(`${banner}${family}${report3.text}${verdict.text}`);
|
|
43971
45002
|
} catch (e) {
|
|
43972
45003
|
return errText(`${banner}${String(e)}`);
|
|
43973
45004
|
}
|
|
@@ -43979,7 +45010,7 @@ ${testsBlock}` : ""}`, deletion);
|
|
|
43979
45010
|
{
|
|
43980
45011
|
description: "Pin the bound project's declared externals (.wai/project.yaml `externals`) \u2014 the named aliases, else all \u2014 into .wai/externals/<alias>.yaml and .wai/externals.lock.yaml, recording the signature digest of every member the project's references use. Answers one outcome per alias (pinned, unchanged, unresolved, unreachable) with the references that land on no public name of the producer (export them from its L0 to pin them). A tree-scoped write: a producer the request may not read is reported unreachable, never read.",
|
|
43981
45012
|
inputSchema: {
|
|
43982
|
-
aliases:
|
|
45013
|
+
aliases: import_zod12.z.array(import_zod12.z.string()).optional().describe("The aliases to pin; all declared externals when omitted")
|
|
43983
45014
|
},
|
|
43984
45015
|
outputSchema: externalPinsOutput
|
|
43985
45016
|
},
|
|
@@ -44016,7 +45047,7 @@ ${testsBlock}` : ""}`, deletion);
|
|
|
44016
45047
|
{
|
|
44017
45048
|
description: "Compose the LIVE delegation brief for one resolved agent: the fully rendered instruction body plus the ownedPaths/readPaths scope fence \u2014 the dynamic replacement for generated per-component agent files. Fetch a brief and spawn a generic subagent with it: always fresh after a re-lock, no session restart needed. List agent ids via listAgents or resources/list (the wairon-agent:// entries).",
|
|
44018
45049
|
inputSchema: {
|
|
44019
|
-
agentId:
|
|
45050
|
+
agentId: import_zod12.z.string().describe("The resolved agent id (list via listAgents or resources/list)")
|
|
44020
45051
|
}
|
|
44021
45052
|
},
|
|
44022
45053
|
({ agentId }) => {
|
|
@@ -44078,9 +45109,30 @@ function loadProjectConfig3() {
|
|
|
44078
45109
|
CustomTargetConfigSchema,
|
|
44079
45110
|
CustomTargetSchema,
|
|
44080
45111
|
DEFAULT_TARGET_DIRS,
|
|
45112
|
+
DESIGN_APPROVALS,
|
|
45113
|
+
DESIGN_DEPENDENCY_ROLES,
|
|
45114
|
+
DESIGN_FORMAT,
|
|
45115
|
+
DESIGN_FORMAT_VERSION,
|
|
44081
45116
|
DatabaseSpecSchema,
|
|
44082
45117
|
DependencyClassSchema,
|
|
45118
|
+
DesignApprovalSchema,
|
|
45119
|
+
DesignComponentSchema,
|
|
45120
|
+
DesignDependencyRoleSchema,
|
|
45121
|
+
DesignDependencySchema,
|
|
44083
45122
|
DesignDepthSchema,
|
|
45123
|
+
DesignExportEntrySchema,
|
|
45124
|
+
DesignExportSchema,
|
|
45125
|
+
DesignFieldSchema,
|
|
45126
|
+
DesignImplementationSchema,
|
|
45127
|
+
DesignInterfaceSchema,
|
|
45128
|
+
DesignMethodBodySchema,
|
|
45129
|
+
DesignMethodSchema,
|
|
45130
|
+
DesignParamSchema,
|
|
45131
|
+
DesignProjectSchema,
|
|
45132
|
+
DesignSourceSchema,
|
|
45133
|
+
DesignSubsystemSchema,
|
|
45134
|
+
DesignTypeRefSchema,
|
|
45135
|
+
DesignTypeSchema,
|
|
44084
45136
|
DiagramConfigSchema,
|
|
44085
45137
|
DispatchBindingSchema,
|
|
44086
45138
|
DoctorOptionsError,
|
|
@@ -44140,6 +45192,8 @@ function loadProjectConfig3() {
|
|
|
44140
45192
|
PortalAuthSchemeSchema,
|
|
44141
45193
|
PortalMountSchema,
|
|
44142
45194
|
PortalTypeSchema,
|
|
45195
|
+
PreviousIdsSchema,
|
|
45196
|
+
PreviousNamesSchema,
|
|
44143
45197
|
ProfileSelectionSubjectSchema,
|
|
44144
45198
|
ProjectConfigSchema,
|
|
44145
45199
|
ProjectNotInitializedError,
|
|
@@ -44183,6 +45237,7 @@ function loadProjectConfig3() {
|
|
|
44183
45237
|
TopologyConfigSchema,
|
|
44184
45238
|
TransportSchema,
|
|
44185
45239
|
TrustedLinkSchema,
|
|
45240
|
+
TypeExpressionSchema,
|
|
44186
45241
|
TypeFieldSchema,
|
|
44187
45242
|
TypeKindSchema,
|
|
44188
45243
|
TypeMethodSchema,
|
|
@@ -44270,6 +45325,7 @@ function loadProjectConfig3() {
|
|
|
44270
45325
|
ensureDir,
|
|
44271
45326
|
ensureProjectInitialized,
|
|
44272
45327
|
excerptParent,
|
|
45328
|
+
exportDesign,
|
|
44273
45329
|
exportSpecTree,
|
|
44274
45330
|
exportTargetKey,
|
|
44275
45331
|
exportUsage,
|
|
@@ -44419,6 +45475,7 @@ function loadProjectConfig3() {
|
|
|
44419
45475
|
renameComponent,
|
|
44420
45476
|
renameId,
|
|
44421
45477
|
renameMethod,
|
|
45478
|
+
renameType,
|
|
44422
45479
|
renderDiagram,
|
|
44423
45480
|
repairForeignStepFields,
|
|
44424
45481
|
repairSignatures,
|
|
@@ -44458,6 +45515,7 @@ function loadProjectConfig3() {
|
|
|
44458
45515
|
settledSpecPaths,
|
|
44459
45516
|
signatureFacts,
|
|
44460
45517
|
signatureTypeRefs,
|
|
45518
|
+
specIndexRetiredBy,
|
|
44461
45519
|
specPathsInScope,
|
|
44462
45520
|
splitNamespace,
|
|
44463
45521
|
stepConfigVerdict,
|