@wairon/cli 5.1.1-dev.35 → 5.1.1-dev.37
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 +437 -128
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +312 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1113,7 +1113,7 @@ var init_defaults = __esm({
|
|
|
1113
1113
|
copilot: ".github/prompts",
|
|
1114
1114
|
codex: ".codex/agents"
|
|
1115
1115
|
};
|
|
1116
|
-
WAIRON_VERSION = "5.1.1-dev.
|
|
1116
|
+
WAIRON_VERSION = "5.1.1-dev.37";
|
|
1117
1117
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
1118
1118
|
ARCHITECT_AGENT_ID = "agent-architect";
|
|
1119
1119
|
ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -2530,13 +2530,34 @@ var init_step_graph = __esm({
|
|
|
2530
2530
|
});
|
|
2531
2531
|
|
|
2532
2532
|
// src/models/step-config.ts
|
|
2533
|
+
function stepFieldsFor(type) {
|
|
2534
|
+
const own = STEP_TYPE_FIELDS[type] ?? [];
|
|
2535
|
+
const allowed = /* @__PURE__ */ new Set([...STEP_COMMON_FIELDS, ...own]);
|
|
2536
|
+
for (const field of own) {
|
|
2537
|
+
const twin = STEP_LABEL_TWINS[field];
|
|
2538
|
+
if (twin) allowed.add(twin);
|
|
2539
|
+
}
|
|
2540
|
+
return allowed;
|
|
2541
|
+
}
|
|
2542
|
+
function isSet(step, field) {
|
|
2543
|
+
const v = step[field];
|
|
2544
|
+
if (v === void 0 || v === null) return false;
|
|
2545
|
+
if (Array.isArray(v) && v.length === 0) return false;
|
|
2546
|
+
return true;
|
|
2547
|
+
}
|
|
2533
2548
|
function flowConfigOn(step) {
|
|
2534
|
-
return FLOW_FIELDS.filter((f) =>
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2549
|
+
return FLOW_FIELDS.filter((f) => isSet(step, f));
|
|
2550
|
+
}
|
|
2551
|
+
function narrativeStepForeignFields(step) {
|
|
2552
|
+
const type = step.type;
|
|
2553
|
+
if (!Object.prototype.hasOwnProperty.call(STEP_TYPE_FIELDS, type)) return [];
|
|
2554
|
+
const allowed = stepFieldsFor(type);
|
|
2555
|
+
return Object.keys(step).filter((f) => !allowed.has(f) && isSet(step, f));
|
|
2556
|
+
}
|
|
2557
|
+
function listFields(fields) {
|
|
2558
|
+
const quoted = fields.map((f) => `"${f}"`);
|
|
2559
|
+
if (quoted.length === 1) return quoted[0];
|
|
2560
|
+
return `${quoted.slice(0, -1).join(", ")} and ${quoted[quoted.length - 1]}`;
|
|
2540
2561
|
}
|
|
2541
2562
|
function stepConfigVerdict(method) {
|
|
2542
2563
|
const steps = method.narrative ?? [];
|
|
@@ -2573,8 +2594,10 @@ function stepConfigVerdict(method) {
|
|
|
2573
2594
|
return i !== void 0 && i + 1 < nums.length ? nums[i + 1] : void 0;
|
|
2574
2595
|
};
|
|
2575
2596
|
for (const s of steps) {
|
|
2597
|
+
const alreadyNamed = /* @__PURE__ */ new Set();
|
|
2576
2598
|
if (s.detach && s.type !== "call" && s.type !== "dispatch") {
|
|
2577
2599
|
malformed(s.stepNumber, `step ${s.stepNumber} (${s.type}) carries "detach" \u2014 fire-and-forget applies to call/dispatch steps only.`);
|
|
2600
|
+
alreadyNamed.add("detach");
|
|
2578
2601
|
}
|
|
2579
2602
|
switch (s.type) {
|
|
2580
2603
|
case "local":
|
|
@@ -2582,7 +2605,10 @@ function stepConfigVerdict(method) {
|
|
|
2582
2605
|
case "register":
|
|
2583
2606
|
case "dispatch": {
|
|
2584
2607
|
const extra = flowConfigOn(s);
|
|
2585
|
-
if (extra.length)
|
|
2608
|
+
if (extra.length) {
|
|
2609
|
+
malformed(s.stepNumber, `step ${s.stepNumber} (${s.type}) carries flow config (${extra.join(", ")}) \u2014 use a flow step type instead.`);
|
|
2610
|
+
for (const f of extra) alreadyNamed.add(f);
|
|
2611
|
+
}
|
|
2586
2612
|
break;
|
|
2587
2613
|
}
|
|
2588
2614
|
case "branch":
|
|
@@ -2625,6 +2651,14 @@ function stepConfigVerdict(method) {
|
|
|
2625
2651
|
if (s.toStep === void 0) malformed(s.stepNumber, `jump step ${s.stepNumber} requires "toStep".`);
|
|
2626
2652
|
break;
|
|
2627
2653
|
}
|
|
2654
|
+
const foreign = narrativeStepForeignFields(s).filter((f) => !alreadyNamed.has(f));
|
|
2655
|
+
if (foreign.length) {
|
|
2656
|
+
problems.push({
|
|
2657
|
+
stepNumber: s.stepNumber,
|
|
2658
|
+
code: "FOREIGN_STEP_FIELD",
|
|
2659
|
+
detail: `step ${s.stepNumber} (${s.type}) carries ${listFields(foreign)}, which a ${s.type} step cannot \u2014 left over from an edit that changed the step's type, configuring nothing. \`wairon doctor --fix\` drops them; give the step the type that carries them instead if that is what it does.`
|
|
2660
|
+
});
|
|
2661
|
+
}
|
|
2628
2662
|
for (const [field, target] of jumpFieldsOf(s)) {
|
|
2629
2663
|
if (byNum.has(target)) continue;
|
|
2630
2664
|
sound = false;
|
|
@@ -2650,24 +2684,43 @@ function jumpFieldsOf(s) {
|
|
|
2650
2684
|
(s.branches ?? []).forEach((b, i) => fields.push([`branches[${i}].step`, b.step]));
|
|
2651
2685
|
return fields;
|
|
2652
2686
|
}
|
|
2653
|
-
var FLOW_FIELDS;
|
|
2687
|
+
var STEP_TYPE_FIELDS, STEP_COMMON_FIELDS, STEP_LABEL_TWINS, FLOW_STEP_TYPES, FLOW_FIELDS;
|
|
2654
2688
|
var init_step_config = __esm({
|
|
2655
2689
|
"src/models/step-config.ts"() {
|
|
2656
2690
|
"use strict";
|
|
2691
|
+
STEP_TYPE_FIELDS = {
|
|
2692
|
+
local: [],
|
|
2693
|
+
call: ["targetComponent", "targetMethod", "auth", "detach"],
|
|
2694
|
+
register: ["targetComponent", "targetMethod"],
|
|
2695
|
+
dispatch: ["targetComponent", "capability", "auth", "detach"],
|
|
2696
|
+
branch: ["condition", "onTrueStep", "onFalseStep"],
|
|
2697
|
+
switch: ["on", "cases", "defaultStep"],
|
|
2698
|
+
loop: ["loopKind", "over", "condition", "endStep"],
|
|
2699
|
+
try: ["endStep", "catches", "finallyStep"],
|
|
2700
|
+
parallel: ["endStep", "branches"],
|
|
2701
|
+
jump: ["toStep"],
|
|
2702
|
+
return: ["outcome"],
|
|
2703
|
+
throw: ["error"]
|
|
2704
|
+
};
|
|
2705
|
+
STEP_COMMON_FIELDS = [
|
|
2706
|
+
"stepNumber",
|
|
2707
|
+
"label",
|
|
2708
|
+
"description",
|
|
2709
|
+
"type",
|
|
2710
|
+
"assertsGuarantees",
|
|
2711
|
+
"assertsInvariants"
|
|
2712
|
+
];
|
|
2713
|
+
STEP_LABEL_TWINS = {
|
|
2714
|
+
onTrueStep: "onTrueLabel",
|
|
2715
|
+
onFalseStep: "onFalseLabel",
|
|
2716
|
+
defaultStep: "defaultLabel",
|
|
2717
|
+
endStep: "endLabel",
|
|
2718
|
+
finallyStep: "finallyLabel",
|
|
2719
|
+
toStep: "toLabel"
|
|
2720
|
+
};
|
|
2721
|
+
FLOW_STEP_TYPES = ["branch", "switch", "loop", "try", "parallel", "jump"];
|
|
2657
2722
|
FLOW_FIELDS = [
|
|
2658
|
-
|
|
2659
|
-
"onTrueStep",
|
|
2660
|
-
"onFalseStep",
|
|
2661
|
-
"on",
|
|
2662
|
-
"cases",
|
|
2663
|
-
"defaultStep",
|
|
2664
|
-
"loopKind",
|
|
2665
|
-
"over",
|
|
2666
|
-
"endStep",
|
|
2667
|
-
"catches",
|
|
2668
|
-
"finallyStep",
|
|
2669
|
-
"branches",
|
|
2670
|
-
"toStep"
|
|
2723
|
+
...new Set(FLOW_STEP_TYPES.flatMap((t) => [...STEP_TYPE_FIELDS[t]]))
|
|
2671
2724
|
];
|
|
2672
2725
|
}
|
|
2673
2726
|
});
|
|
@@ -9744,20 +9797,22 @@ var init_narrative_step_config = __esm({
|
|
|
9744
9797
|
init_models();
|
|
9745
9798
|
narrativeStepConfigRule = {
|
|
9746
9799
|
name: "narrative-step-config",
|
|
9747
|
-
description: 'The step configuration of L5 narratives: every flow step (branch, switch, loop, try, parallel, jump) carries the config its type requires and no simple step carries flow config, "detach" (fire-and-forget) is legal on call/dispatch steps only, a parallel body is covered by contiguous, ordered arms (>= 2), no two steps share a step number or a label, and every jump field targets an existing step number in the same narrative.',
|
|
9800
|
+
description: 'The step configuration of L5 narratives: every flow step (branch, switch, loop, try, parallel, jump) carries the config its type requires and no simple step carries flow config, "detach" (fire-and-forget) is legal on call/dispatch steps only, no step carries a field foreign to its type, a parallel body is covered by contiguous, ordered arms (>= 2), no two steps share a step number or a label, and every jump field targets an existing step number in the same narrative.',
|
|
9748
9801
|
codes: [
|
|
9749
9802
|
{ code: "MALFORMED_FLOW_STEP", defaultSeverity: "error", summary: "Flow step missing required config (or flow config on a local/call step)" },
|
|
9750
9803
|
{ code: "INVALID_STEP_JUMP", defaultSeverity: "error", summary: "Jump field targets a step number that does not exist in the narrative" },
|
|
9751
|
-
{ code: "DUPLICATE_STEP_LABEL", defaultSeverity: "error", summary: "Two steps in one narrative share a label \u2014 the symbolic anchor later deltas address by" }
|
|
9804
|
+
{ code: "DUPLICATE_STEP_LABEL", defaultSeverity: "error", summary: "Two steps in one narrative share a label \u2014 the symbolic anchor later deltas address by" },
|
|
9805
|
+
{ code: "FOREIGN_STEP_FIELD", defaultSeverity: "warning", summary: "Step carries a field its own type cannot have \u2014 a leftover of an edit, meaning nothing" }
|
|
9752
9806
|
],
|
|
9753
9807
|
check(ctx) {
|
|
9808
|
+
const severityOf = new Map(narrativeStepConfigRule.codes.map((c) => [c.code, c.defaultSeverity]));
|
|
9754
9809
|
for (const impl of ctx.implementations) {
|
|
9755
9810
|
const isDraftCtx = ctx.isImplementationDraft(impl);
|
|
9756
9811
|
for (const implMethod of impl.methods) {
|
|
9757
9812
|
if (!implMethod.narrative.length) continue;
|
|
9758
9813
|
const where = `Method "${implMethod.name}" in implementation "${impl.id}": `;
|
|
9759
9814
|
for (const problem of stepConfigVerdict(implMethod).problems) {
|
|
9760
|
-
ctx.addIssue("error", problem.code, where + problem.detail, impl.id, isDraftCtx);
|
|
9815
|
+
ctx.addIssue(severityOf.get(problem.code) ?? "error", problem.code, where + problem.detail, impl.id, isDraftCtx);
|
|
9761
9816
|
}
|
|
9762
9817
|
}
|
|
9763
9818
|
}
|
|
@@ -12348,15 +12403,16 @@ var init_unused_types = __esm({
|
|
|
12348
12403
|
init_models();
|
|
12349
12404
|
unusedTypesRule = {
|
|
12350
12405
|
name: "unused-types",
|
|
12351
|
-
description: "Flags types no field of any type and no
|
|
12406
|
+
description: "Flags types no field of any type, no interface method signature and no other type's method signature references. References are matched through the type-reference grammar (generic arguments, collections, qualified ids), and the declaring type's own generic parameters are left out \u2014 a type parameter is not a reference to a type. A type named only by its OWN methods stays unused, the way a function that only calls itself is.",
|
|
12352
12407
|
codes: [
|
|
12353
|
-
{ code: "UNUSED_TYPE", defaultSeverity: "warning", summary: "Type never referenced by fields or
|
|
12408
|
+
{ code: "UNUSED_TYPE", defaultSeverity: "warning", summary: "Type never referenced by fields, signatures or type methods" }
|
|
12354
12409
|
],
|
|
12355
12410
|
check(ctx) {
|
|
12356
12411
|
const referencedTypes = /* @__PURE__ */ new Set();
|
|
12357
|
-
const markTypeReferenced = (ref) => {
|
|
12412
|
+
const markTypeReferenced = (ref, exceptId) => {
|
|
12358
12413
|
if (ctx.isBuiltinType(ref)) return;
|
|
12359
12414
|
for (const spec of ctx.types) {
|
|
12415
|
+
if (spec.id === exceptId) continue;
|
|
12360
12416
|
if (typeMatchesRef(spec, ref)) {
|
|
12361
12417
|
referencedTypes.add(spec.id);
|
|
12362
12418
|
}
|
|
@@ -12378,6 +12434,14 @@ var init_unused_types = __esm({
|
|
|
12378
12434
|
}
|
|
12379
12435
|
}
|
|
12380
12436
|
}
|
|
12437
|
+
for (const t of ctx.types) {
|
|
12438
|
+
for (const m of t.methods) {
|
|
12439
|
+
const refs = methodTypeRefs(m);
|
|
12440
|
+
for (const ref of refs) {
|
|
12441
|
+
markTypeReferenced(ref, t.id);
|
|
12442
|
+
}
|
|
12443
|
+
}
|
|
12444
|
+
}
|
|
12381
12445
|
for (const t of ctx.types) {
|
|
12382
12446
|
if (!ctx.isSpecInScope(t.id)) continue;
|
|
12383
12447
|
if (!referencedTypes.has(t.id)) {
|
|
@@ -12386,7 +12450,7 @@ var init_unused_types = __esm({
|
|
|
12386
12450
|
ctx.addIssue(
|
|
12387
12451
|
"warning",
|
|
12388
12452
|
"UNUSED_TYPE",
|
|
12389
|
-
`Type "${t.id}" is defined but never referenced by any type
|
|
12453
|
+
`Type "${t.id}" is defined but never referenced by any type field, interface method or other type's method.`,
|
|
12390
12454
|
t.id,
|
|
12391
12455
|
isDraftCtx
|
|
12392
12456
|
);
|
|
@@ -18360,15 +18424,6 @@ function identityKeyOf(field, item) {
|
|
|
18360
18424
|
return str(o.name) ?? str(o.id);
|
|
18361
18425
|
}
|
|
18362
18426
|
}
|
|
18363
|
-
function stepFieldsFor(type) {
|
|
18364
|
-
const own = STEP_TYPE_FIELDS[type] ?? [];
|
|
18365
|
-
const allowed = /* @__PURE__ */ new Set([...STEP_COMMON_FIELDS, ...own]);
|
|
18366
|
-
for (const field of own) {
|
|
18367
|
-
const twin = STEP_LABEL_TWINS[field];
|
|
18368
|
-
if (twin) allowed.add(twin);
|
|
18369
|
-
}
|
|
18370
|
-
return allowed;
|
|
18371
|
-
}
|
|
18372
18427
|
function reportIdentityOf(field, item) {
|
|
18373
18428
|
if (item !== null && typeof item === "object") {
|
|
18374
18429
|
const step = item.stepNumber;
|
|
@@ -18416,6 +18471,117 @@ function specChanges(before, after, prefix = "") {
|
|
|
18416
18471
|
if (JSON.stringify(before) === JSON.stringify(after)) return [];
|
|
18417
18472
|
return [{ path: prefix, change: "set", before: summarizeValue(before), after: summarizeValue(after) }];
|
|
18418
18473
|
}
|
|
18474
|
+
function identityFieldsOf(field) {
|
|
18475
|
+
switch (field) {
|
|
18476
|
+
case "dispatch":
|
|
18477
|
+
return ["capability"];
|
|
18478
|
+
case "lifecycle":
|
|
18479
|
+
return ["phase", "component", "method"];
|
|
18480
|
+
case "emits":
|
|
18481
|
+
case "subscribesTo":
|
|
18482
|
+
return ["topic", "event"];
|
|
18483
|
+
case "trustedLinks":
|
|
18484
|
+
return ["subsystem"];
|
|
18485
|
+
case "allow":
|
|
18486
|
+
case "findings":
|
|
18487
|
+
return ["code"];
|
|
18488
|
+
case "invariants":
|
|
18489
|
+
case "patterns":
|
|
18490
|
+
return ["id"];
|
|
18491
|
+
case "boundaries":
|
|
18492
|
+
return ["name"];
|
|
18493
|
+
case "globalRequirements":
|
|
18494
|
+
return ["description"];
|
|
18495
|
+
case "databases":
|
|
18496
|
+
return ["id", "name"];
|
|
18497
|
+
case "cases":
|
|
18498
|
+
return ["value"];
|
|
18499
|
+
case "catches":
|
|
18500
|
+
return ["error"];
|
|
18501
|
+
case "narrative":
|
|
18502
|
+
return ["stepNumber"];
|
|
18503
|
+
default:
|
|
18504
|
+
return ["name", "id"];
|
|
18505
|
+
}
|
|
18506
|
+
}
|
|
18507
|
+
function carriesEditMarker(item) {
|
|
18508
|
+
if (item === null || typeof item !== "object") return false;
|
|
18509
|
+
const o = item;
|
|
18510
|
+
return o.action !== void 0 || o.remove !== void 0;
|
|
18511
|
+
}
|
|
18512
|
+
function ineffectiveDeltaPaths(delta, merged, stored) {
|
|
18513
|
+
const out = [];
|
|
18514
|
+
const isPlain = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
18515
|
+
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
18516
|
+
const at = (prefix, key) => prefix ? `${prefix}.${key}` : key;
|
|
18517
|
+
const say = (path27, why) => {
|
|
18518
|
+
out.push(`${path27} \u2014 ${why}`);
|
|
18519
|
+
};
|
|
18520
|
+
const walkValue = (d, m, s, path27, field) => {
|
|
18521
|
+
if (Array.isArray(d)) {
|
|
18522
|
+
if (!Array.isArray(m)) {
|
|
18523
|
+
say(path27, "the level does not have this field, so the write dropped it");
|
|
18524
|
+
return;
|
|
18525
|
+
}
|
|
18526
|
+
if (field === "narrative" && d.some(carriesEditMarker)) return;
|
|
18527
|
+
for (const element of d) {
|
|
18528
|
+
if (carriesEditMarker(element)) continue;
|
|
18529
|
+
const key = reportIdentityOf(field, element);
|
|
18530
|
+
if (key === null) {
|
|
18531
|
+
if (!same(m, d)) say(path27, "the level does not keep this value, so the write dropped it");
|
|
18532
|
+
else if (same(s, d)) say(path27, "the stored spec already held this value");
|
|
18533
|
+
return;
|
|
18534
|
+
}
|
|
18535
|
+
const mMatch = m.find((i) => reportIdentityOf(field, i) === key);
|
|
18536
|
+
const sMatch = Array.isArray(s) ? s.find((i) => reportIdentityOf(field, i) === key) : void 0;
|
|
18537
|
+
if (mMatch === void 0) {
|
|
18538
|
+
say(at(path27, key), "the write did not store this element");
|
|
18539
|
+
continue;
|
|
18540
|
+
}
|
|
18541
|
+
walk2(element, mMatch, sMatch, at(path27, key), field);
|
|
18542
|
+
}
|
|
18543
|
+
return;
|
|
18544
|
+
}
|
|
18545
|
+
if (isPlain(d)) {
|
|
18546
|
+
if (!isPlain(m)) {
|
|
18547
|
+
say(path27, "the level does not have this field, so the write dropped it");
|
|
18548
|
+
return;
|
|
18549
|
+
}
|
|
18550
|
+
walk2(d, m, s, path27, field);
|
|
18551
|
+
return;
|
|
18552
|
+
}
|
|
18553
|
+
if (!same(m, d)) say(path27, "the write did not store it \u2014 the level's schema does not keep this value");
|
|
18554
|
+
else if (same(s, d)) say(path27, "the stored spec already held this value");
|
|
18555
|
+
};
|
|
18556
|
+
function walk2(d, m, s, path27, container) {
|
|
18557
|
+
for (const [key, value] of Object.entries(d)) {
|
|
18558
|
+
if (DELTA_VERBS.has(key) || JUMP_LABEL_TWINS.has(key)) continue;
|
|
18559
|
+
if (key === "label" && LABEL_TWIN_CONTAINERS.has(container)) continue;
|
|
18560
|
+
if (identityFieldsOf(container).includes(key)) continue;
|
|
18561
|
+
if (key === "unset") {
|
|
18562
|
+
for (const name of Array.isArray(value) ? value : []) {
|
|
18563
|
+
if (typeof name !== "string") continue;
|
|
18564
|
+
const had = isPlain(s) && s[name] !== void 0;
|
|
18565
|
+
const still = isPlain(m) && m[name] !== void 0;
|
|
18566
|
+
if (!had) say(at(path27, name), "unset named a field the stored spec did not have");
|
|
18567
|
+
else if (still) say(at(path27, name), "unset did not remove it");
|
|
18568
|
+
}
|
|
18569
|
+
continue;
|
|
18570
|
+
}
|
|
18571
|
+
if (value === void 0 || value === null) continue;
|
|
18572
|
+
const here = at(path27, key);
|
|
18573
|
+
const mValue = isPlain(m) ? m[key] : void 0;
|
|
18574
|
+
const sValue = isPlain(s) ? s[key] : void 0;
|
|
18575
|
+
if (mValue === void 0) {
|
|
18576
|
+
say(here, "the level does not have this field, so the write dropped it");
|
|
18577
|
+
continue;
|
|
18578
|
+
}
|
|
18579
|
+
walkValue(value, mValue, sValue, here, key);
|
|
18580
|
+
}
|
|
18581
|
+
}
|
|
18582
|
+
walk2(delta, merged, stored, "", "");
|
|
18583
|
+
return out;
|
|
18584
|
+
}
|
|
18419
18585
|
function workspaceFor(rootDir) {
|
|
18420
18586
|
const key = path16.resolve(rootDir);
|
|
18421
18587
|
let ws = workspaces.get(key);
|
|
@@ -18641,10 +18807,10 @@ function restoreSpecFiles(snapshot) {
|
|
|
18641
18807
|
function findLegacySpecFiles() {
|
|
18642
18808
|
return current().findLegacySpecFiles();
|
|
18643
18809
|
}
|
|
18644
|
-
function updateSpec(kind, id, delta, hooks) {
|
|
18645
|
-
return current().updateSpec(kind, id, delta, hooks);
|
|
18810
|
+
function updateSpec(kind, id, delta, hooks, dryRun) {
|
|
18811
|
+
return current().updateSpec(kind, id, delta, hooks, dryRun);
|
|
18646
18812
|
}
|
|
18647
|
-
var fs11, path16, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS,
|
|
18813
|
+
var fs11, path16, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, DELTA_VERBS, JUMP_LABEL_TWINS, LABEL_TWIN_CONTAINERS, SpecWorkspace, workspaces;
|
|
18648
18814
|
var init_specs2 = __esm({
|
|
18649
18815
|
"src/core/specs.ts"() {
|
|
18650
18816
|
"use strict";
|
|
@@ -18662,36 +18828,16 @@ var init_specs2 = __esm({
|
|
|
18662
18828
|
init_diagram();
|
|
18663
18829
|
NO_ROOT_SUBSYSTEMS = /* @__PURE__ */ new Set();
|
|
18664
18830
|
SIGNATURE_TTL_MS = 2e3;
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
jump: ["toStep"],
|
|
18676
|
-
return: ["outcome"],
|
|
18677
|
-
throw: ["error"]
|
|
18678
|
-
};
|
|
18679
|
-
STEP_COMMON_FIELDS = [
|
|
18680
|
-
"stepNumber",
|
|
18681
|
-
"label",
|
|
18682
|
-
"description",
|
|
18683
|
-
"type",
|
|
18684
|
-
"assertsGuarantees",
|
|
18685
|
-
"assertsInvariants"
|
|
18686
|
-
];
|
|
18687
|
-
STEP_LABEL_TWINS = {
|
|
18688
|
-
onTrueStep: "onTrueLabel",
|
|
18689
|
-
onFalseStep: "onFalseLabel",
|
|
18690
|
-
defaultStep: "defaultLabel",
|
|
18691
|
-
endStep: "endLabel",
|
|
18692
|
-
finallyStep: "finallyLabel",
|
|
18693
|
-
toStep: "toLabel"
|
|
18694
|
-
};
|
|
18831
|
+
DELTA_VERBS = /* @__PURE__ */ new Set(["action", "remove", "captureJumps"]);
|
|
18832
|
+
JUMP_LABEL_TWINS = /* @__PURE__ */ new Set([
|
|
18833
|
+
"onTrueLabel",
|
|
18834
|
+
"onFalseLabel",
|
|
18835
|
+
"defaultLabel",
|
|
18836
|
+
"endLabel",
|
|
18837
|
+
"finallyLabel",
|
|
18838
|
+
"toLabel"
|
|
18839
|
+
]);
|
|
18840
|
+
LABEL_TWIN_CONTAINERS = /* @__PURE__ */ new Set(["cases", "catches", "branches"]);
|
|
18695
18841
|
SpecWorkspace = class {
|
|
18696
18842
|
constructor(rootDir) {
|
|
18697
18843
|
this.cachedIndex = null;
|
|
@@ -19407,6 +19553,9 @@ var init_specs2 = __esm({
|
|
|
19407
19553
|
const existing = this.loadSubsystemSpec(spec.id);
|
|
19408
19554
|
if (existing) {
|
|
19409
19555
|
specToWrite.createdAt = existing.createdAt;
|
|
19556
|
+
if (!opts?.allowStatusDemotion && existing.status && (!spec.status || spec.status === "draft")) {
|
|
19557
|
+
specToWrite.status = existing.status;
|
|
19558
|
+
}
|
|
19410
19559
|
}
|
|
19411
19560
|
specToWrite.updatedAt = opts?.preserveUpdatedAt && existing?.updatedAt ? existing.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
19412
19561
|
writeYamlFile(p, parseOrThrow(SubsystemSpecSchema, specToWrite, "subsystem", spec.id));
|
|
@@ -19955,15 +20104,22 @@ var init_specs2 = __esm({
|
|
|
19955
20104
|
* carry, and a label in the delta retargets the stored numeric jump it
|
|
19956
20105
|
* twins. An unresolved reference aborts the whole update.
|
|
19957
20106
|
* 7. COMPARE with what is stored, both read through the level's canonical
|
|
19958
|
-
* schema. Equal means nothing is written and `written` is false.
|
|
19959
|
-
*
|
|
20107
|
+
* schema. Equal means nothing is written and `written` is false. The same
|
|
20108
|
+
* comparison names every delta path the write did NOT act on — one the
|
|
20109
|
+
* schema drops at a depth the permissive delta cannot refuse, one the
|
|
20110
|
+
* stored spec already held, an `unset` that removed nothing.
|
|
20111
|
+
* 8. GATE the merged spec through the caller's hook. A DRY RUN stops here
|
|
20112
|
+
* and answers with the report it would have produced — after the gate, so
|
|
20113
|
+
* it accounts for a write that would really be accepted, and before the
|
|
20114
|
+
* stamp, so not one byte of the stored file moves.
|
|
20115
|
+
* 9. STAMP updatedAt and SAVE.
|
|
19960
20116
|
*
|
|
19961
20117
|
* Returns the change report, whose `notices` carry the non-fatal effects (an
|
|
19962
20118
|
* insert whose position was a jump target, so the relocated jumps now bypass
|
|
19963
20119
|
* the inserted step; the fields a retype dropped) — empty when the merge had
|
|
19964
20120
|
* nothing to say.
|
|
19965
20121
|
*/
|
|
19966
|
-
updateSpec(kind, id, delta, hooks) {
|
|
20122
|
+
updateSpec(kind, id, delta, hooks, dryRun = false) {
|
|
19967
20123
|
const notices = [];
|
|
19968
20124
|
const result = (() => {
|
|
19969
20125
|
switch (kind) {
|
|
@@ -20442,7 +20598,8 @@ var init_specs2 = __esm({
|
|
|
20442
20598
|
const unsetFields = Array.isArray(delta.unset) ? delta.unset.filter((f) => typeof f === "string") : [];
|
|
20443
20599
|
const { unset: _unset, ...mergeableDelta } = delta;
|
|
20444
20600
|
const storedBefore = JSON.parse(JSON.stringify(result));
|
|
20445
|
-
const
|
|
20601
|
+
const qualifiedDelta = qualifyDeltaRefs(mergeableDelta);
|
|
20602
|
+
const mergedResult = mergeDelta(result, qualifiedDelta);
|
|
20446
20603
|
for (const field of unsetFields) delete mergedResult[field];
|
|
20447
20604
|
if (kind === "implementation" && Array.isArray(mergedResult.methods)) {
|
|
20448
20605
|
const labelErrors = [];
|
|
@@ -20460,20 +20617,41 @@ var init_specs2 = __esm({
|
|
|
20460
20617
|
delete value.updatedAt;
|
|
20461
20618
|
return value;
|
|
20462
20619
|
};
|
|
20463
|
-
const
|
|
20620
|
+
const canonicalStored = canonical(storedBefore);
|
|
20621
|
+
const canonicalMerged = canonical(mergedResult);
|
|
20622
|
+
const changes = specChanges(canonicalStored, canonicalMerged);
|
|
20623
|
+
const ineffective = ineffectiveDeltaPaths(
|
|
20624
|
+
{ ...qualifiedDelta, ...unsetFields.length ? { unset: unsetFields } : {} },
|
|
20625
|
+
canonicalMerged,
|
|
20626
|
+
canonicalStored
|
|
20627
|
+
);
|
|
20464
20628
|
if (changes.length === 0) {
|
|
20465
20629
|
return {
|
|
20466
20630
|
kind,
|
|
20467
20631
|
id,
|
|
20468
20632
|
written: false,
|
|
20633
|
+
dryRun,
|
|
20469
20634
|
changes,
|
|
20635
|
+
ineffective,
|
|
20470
20636
|
notices,
|
|
20471
|
-
summary: `No change to ${kind} "${id}" \u2014 the delta matches what is stored, so nothing was written.`
|
|
20637
|
+
summary: `No change to ${kind} "${id}" \u2014 the delta matches what is stored, so nothing ${dryRun ? "would be" : "was"} written.`
|
|
20472
20638
|
};
|
|
20473
20639
|
}
|
|
20474
|
-
mergedResult.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20475
20640
|
const gateNotices = hooks?.gate?.(kind, mergedResult);
|
|
20476
20641
|
if (gateNotices?.length) notices.push(...gateNotices);
|
|
20642
|
+
if (dryRun) {
|
|
20643
|
+
return {
|
|
20644
|
+
kind,
|
|
20645
|
+
id,
|
|
20646
|
+
written: false,
|
|
20647
|
+
dryRun: true,
|
|
20648
|
+
changes,
|
|
20649
|
+
ineffective,
|
|
20650
|
+
notices,
|
|
20651
|
+
summary: `Dry run on ${kind} "${id}": ${changes.length} change${changes.length === 1 ? "" : "s"} would be made. Nothing was written.`
|
|
20652
|
+
};
|
|
20653
|
+
}
|
|
20654
|
+
mergedResult.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20477
20655
|
const opts = {
|
|
20478
20656
|
allowStatusDemotion: Object.prototype.hasOwnProperty.call(delta, "status")
|
|
20479
20657
|
};
|
|
@@ -20482,7 +20660,7 @@ var init_specs2 = __esm({
|
|
|
20482
20660
|
this.saveSystemSpec(mergedResult);
|
|
20483
20661
|
break;
|
|
20484
20662
|
case "subsystem":
|
|
20485
|
-
this.saveSubsystemSpec(mergedResult);
|
|
20663
|
+
this.saveSubsystemSpec(mergedResult, opts);
|
|
20486
20664
|
break;
|
|
20487
20665
|
case "component":
|
|
20488
20666
|
notices.push(...this.saveComponentSpec(mergedResult, opts));
|
|
@@ -20501,7 +20679,9 @@ var init_specs2 = __esm({
|
|
|
20501
20679
|
kind,
|
|
20502
20680
|
id,
|
|
20503
20681
|
written: true,
|
|
20682
|
+
dryRun: false,
|
|
20504
20683
|
changes,
|
|
20684
|
+
ineffective,
|
|
20505
20685
|
notices,
|
|
20506
20686
|
summary: `Updated ${kind} "${id}": ${changes.length} change${changes.length === 1 ? "" : "s"}.`
|
|
20507
20687
|
};
|
|
@@ -25872,6 +26052,44 @@ var init_stereotype_migration = __esm({
|
|
|
25872
26052
|
}
|
|
25873
26053
|
});
|
|
25874
26054
|
|
|
26055
|
+
// src/core/narrative-repair.ts
|
|
26056
|
+
function repairForeignStepFields(apply) {
|
|
26057
|
+
const implementations = loadImplementationSpecs();
|
|
26058
|
+
const repairs = [];
|
|
26059
|
+
const changed = [];
|
|
26060
|
+
for (const impl of implementations) {
|
|
26061
|
+
let touched = false;
|
|
26062
|
+
for (const method of impl.methods) {
|
|
26063
|
+
for (const step of method.narrative) {
|
|
26064
|
+
const fields = narrativeStepForeignFields(step);
|
|
26065
|
+
if (!fields.length) continue;
|
|
26066
|
+
repairs.push({
|
|
26067
|
+
implementation: impl.id,
|
|
26068
|
+
method: method.name,
|
|
26069
|
+
stepNumber: step.stepNumber,
|
|
26070
|
+
stepType: step.type,
|
|
26071
|
+
fields
|
|
26072
|
+
});
|
|
26073
|
+
for (const field of fields) delete step[field];
|
|
26074
|
+
touched = true;
|
|
26075
|
+
}
|
|
26076
|
+
}
|
|
26077
|
+
if (touched) changed.push(impl);
|
|
26078
|
+
}
|
|
26079
|
+
if (apply && changed.length) {
|
|
26080
|
+
for (const impl of changed) saveImplementationSpec(impl);
|
|
26081
|
+
invalidateSpecCache();
|
|
26082
|
+
}
|
|
26083
|
+
return repairs;
|
|
26084
|
+
}
|
|
26085
|
+
var init_narrative_repair = __esm({
|
|
26086
|
+
"src/core/narrative-repair.ts"() {
|
|
26087
|
+
"use strict";
|
|
26088
|
+
init_specs2();
|
|
26089
|
+
init_models();
|
|
26090
|
+
}
|
|
26091
|
+
});
|
|
26092
|
+
|
|
25875
26093
|
// src/core/approver.ts
|
|
25876
26094
|
function gitConfig(key) {
|
|
25877
26095
|
try {
|
|
@@ -25952,6 +26170,7 @@ var init_core = __esm({
|
|
|
25952
26170
|
init_treetransfer();
|
|
25953
26171
|
init_provision();
|
|
25954
26172
|
init_stereotype_migration();
|
|
26173
|
+
init_narrative_repair();
|
|
25955
26174
|
init_approval();
|
|
25956
26175
|
init_approver();
|
|
25957
26176
|
init_specs2();
|
|
@@ -26056,6 +26275,9 @@ __export(src_exports, {
|
|
|
26056
26275
|
SCAN_EXCLUDE_DIRS: () => SCAN_EXCLUDE_DIRS,
|
|
26057
26276
|
SDD_RULES: () => SDD_RULES,
|
|
26058
26277
|
SEMANTIC_GUARANTEES: () => SEMANTIC_GUARANTEES,
|
|
26278
|
+
STEP_COMMON_FIELDS: () => STEP_COMMON_FIELDS,
|
|
26279
|
+
STEP_LABEL_TWINS: () => STEP_LABEL_TWINS,
|
|
26280
|
+
STEP_TYPE_FIELDS: () => STEP_TYPE_FIELDS,
|
|
26059
26281
|
SUPPORTED_ALIASES: () => SUPPORTED_ALIASES,
|
|
26060
26282
|
SURFACE_AUDIENCES: () => SURFACE_AUDIENCES,
|
|
26061
26283
|
SkillResourceNotFoundError: () => SkillResourceNotFoundError,
|
|
@@ -26207,6 +26429,7 @@ __export(src_exports, {
|
|
|
26207
26429
|
implementationSourceFiles: () => implementationSourceFiles,
|
|
26208
26430
|
importSpecTree: () => importSpecTree,
|
|
26209
26431
|
importSurface: () => importSurface,
|
|
26432
|
+
ineffectiveDeltaPaths: () => ineffectiveDeltaPaths,
|
|
26210
26433
|
inspectChainedRoots: () => inspectChainedRoots,
|
|
26211
26434
|
inspectTreeArchive: () => inspectTreeArchive2,
|
|
26212
26435
|
installPackFromDirectory: () => installPackFromDirectory,
|
|
@@ -26269,6 +26492,7 @@ __export(src_exports, {
|
|
|
26269
26492
|
methodSourceFile: () => methodSourceFile,
|
|
26270
26493
|
methodTypeRefs: () => methodTypeRefs,
|
|
26271
26494
|
moveSubsystemProject: () => moveSubsystemProject,
|
|
26495
|
+
narrativeStepForeignFields: () => narrativeStepForeignFields,
|
|
26272
26496
|
normalizeApprover: () => normalizeApprover,
|
|
26273
26497
|
normalizeComponentLayout: () => normalizeComponentLayout,
|
|
26274
26498
|
packDirEntry: () => packDirEntry,
|
|
@@ -26313,6 +26537,7 @@ __export(src_exports, {
|
|
|
26313
26537
|
renderDomainsDoc: () => renderDomainsDoc,
|
|
26314
26538
|
renderTemplateInstructions: () => renderTemplateInstructions,
|
|
26315
26539
|
renderWaironGuide: () => renderWaironGuide,
|
|
26540
|
+
repairForeignStepFields: () => repairForeignStepFields,
|
|
26316
26541
|
resolveAgentTopology: () => resolveAgentTopology,
|
|
26317
26542
|
resolveChainingParent: () => resolveChainingParent,
|
|
26318
26543
|
resolveDomains: () => resolveDomains,
|
|
@@ -26351,6 +26576,7 @@ __export(src_exports, {
|
|
|
26351
26576
|
stateIdEquals: () => stateIdEquals,
|
|
26352
26577
|
stateIdString: () => stateIdString,
|
|
26353
26578
|
stepConfigVerdict: () => stepConfigVerdict,
|
|
26579
|
+
stepFieldsFor: () => stepFieldsFor,
|
|
26354
26580
|
stepGraph: () => stepGraph,
|
|
26355
26581
|
syncContextFiles: () => syncContextFiles,
|
|
26356
26582
|
toMarkdown: () => toMarkdown,
|
|
@@ -26777,6 +27003,9 @@ function loadProjectConfig4() {
|
|
|
26777
27003
|
SCAN_EXCLUDE_DIRS,
|
|
26778
27004
|
SDD_RULES,
|
|
26779
27005
|
SEMANTIC_GUARANTEES,
|
|
27006
|
+
STEP_COMMON_FIELDS,
|
|
27007
|
+
STEP_LABEL_TWINS,
|
|
27008
|
+
STEP_TYPE_FIELDS,
|
|
26780
27009
|
SUPPORTED_ALIASES,
|
|
26781
27010
|
SURFACE_AUDIENCES,
|
|
26782
27011
|
SkillResourceNotFoundError,
|
|
@@ -26928,6 +27157,7 @@ function loadProjectConfig4() {
|
|
|
26928
27157
|
implementationSourceFiles,
|
|
26929
27158
|
importSpecTree,
|
|
26930
27159
|
importSurface,
|
|
27160
|
+
ineffectiveDeltaPaths,
|
|
26931
27161
|
inspectChainedRoots,
|
|
26932
27162
|
inspectTreeArchive,
|
|
26933
27163
|
installPackFromDirectory,
|
|
@@ -26990,6 +27220,7 @@ function loadProjectConfig4() {
|
|
|
26990
27220
|
methodSourceFile,
|
|
26991
27221
|
methodTypeRefs,
|
|
26992
27222
|
moveSubsystemProject,
|
|
27223
|
+
narrativeStepForeignFields,
|
|
26993
27224
|
normalizeApprover,
|
|
26994
27225
|
normalizeComponentLayout,
|
|
26995
27226
|
packDirEntry,
|
|
@@ -27034,6 +27265,7 @@ function loadProjectConfig4() {
|
|
|
27034
27265
|
renderDomainsDoc,
|
|
27035
27266
|
renderTemplateInstructions,
|
|
27036
27267
|
renderWaironGuide,
|
|
27268
|
+
repairForeignStepFields,
|
|
27037
27269
|
resolveAgentTopology,
|
|
27038
27270
|
resolveChainingParent,
|
|
27039
27271
|
resolveDomains,
|
|
@@ -27072,6 +27304,7 @@ function loadProjectConfig4() {
|
|
|
27072
27304
|
stateIdEquals,
|
|
27073
27305
|
stateIdString,
|
|
27074
27306
|
stepConfigVerdict,
|
|
27307
|
+
stepFieldsFor,
|
|
27075
27308
|
stepGraph,
|
|
27076
27309
|
syncContextFiles,
|
|
27077
27310
|
toMarkdown,
|