@wairon/cli 5.1.1-dev.35 → 5.1.1-dev.36

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/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.35";
1116
+ WAIRON_VERSION = "5.1.1-dev.36";
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
- const v = step[f];
2536
- if (v === void 0) return false;
2537
- if (Array.isArray(v) && v.length === 0) return false;
2538
- return true;
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) malformed(s.stepNumber, `step ${s.stepNumber} (${s.type}) carries flow config (${extra.join(", ")}) \u2014 use a flow step type instead.`);
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
- "condition",
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 interface 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.",
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 signatures" }
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 fields or interface methods.`,
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;
@@ -18644,7 +18699,7 @@ function findLegacySpecFiles() {
18644
18699
  function updateSpec(kind, id, delta, hooks) {
18645
18700
  return current().updateSpec(kind, id, delta, hooks);
18646
18701
  }
18647
- var fs11, path16, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, STEP_TYPE_FIELDS, STEP_COMMON_FIELDS, STEP_LABEL_TWINS, SpecWorkspace, workspaces;
18702
+ var fs11, path16, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, SpecWorkspace, workspaces;
18648
18703
  var init_specs2 = __esm({
18649
18704
  "src/core/specs.ts"() {
18650
18705
  "use strict";
@@ -18662,36 +18717,6 @@ var init_specs2 = __esm({
18662
18717
  init_diagram();
18663
18718
  NO_ROOT_SUBSYSTEMS = /* @__PURE__ */ new Set();
18664
18719
  SIGNATURE_TTL_MS = 2e3;
18665
- STEP_TYPE_FIELDS = {
18666
- local: [],
18667
- call: ["targetComponent", "targetMethod", "auth", "detach"],
18668
- register: ["targetComponent", "targetMethod"],
18669
- dispatch: ["targetComponent", "capability", "auth", "detach"],
18670
- branch: ["condition", "onTrueStep", "onFalseStep"],
18671
- switch: ["on", "cases", "defaultStep"],
18672
- loop: ["loopKind", "over", "condition", "endStep"],
18673
- try: ["endStep", "catches", "finallyStep"],
18674
- parallel: ["endStep", "branches"],
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
- };
18695
18720
  SpecWorkspace = class {
18696
18721
  constructor(rootDir) {
18697
18722
  this.cachedIndex = null;
@@ -25872,6 +25897,44 @@ var init_stereotype_migration = __esm({
25872
25897
  }
25873
25898
  });
25874
25899
 
25900
+ // src/core/narrative-repair.ts
25901
+ function repairForeignStepFields(apply) {
25902
+ const implementations = loadImplementationSpecs();
25903
+ const repairs = [];
25904
+ const changed = [];
25905
+ for (const impl of implementations) {
25906
+ let touched = false;
25907
+ for (const method of impl.methods) {
25908
+ for (const step of method.narrative) {
25909
+ const fields = narrativeStepForeignFields(step);
25910
+ if (!fields.length) continue;
25911
+ repairs.push({
25912
+ implementation: impl.id,
25913
+ method: method.name,
25914
+ stepNumber: step.stepNumber,
25915
+ stepType: step.type,
25916
+ fields
25917
+ });
25918
+ for (const field of fields) delete step[field];
25919
+ touched = true;
25920
+ }
25921
+ }
25922
+ if (touched) changed.push(impl);
25923
+ }
25924
+ if (apply && changed.length) {
25925
+ for (const impl of changed) saveImplementationSpec(impl);
25926
+ invalidateSpecCache();
25927
+ }
25928
+ return repairs;
25929
+ }
25930
+ var init_narrative_repair = __esm({
25931
+ "src/core/narrative-repair.ts"() {
25932
+ "use strict";
25933
+ init_specs2();
25934
+ init_models();
25935
+ }
25936
+ });
25937
+
25875
25938
  // src/core/approver.ts
25876
25939
  function gitConfig(key) {
25877
25940
  try {
@@ -25952,6 +26015,7 @@ var init_core = __esm({
25952
26015
  init_treetransfer();
25953
26016
  init_provision();
25954
26017
  init_stereotype_migration();
26018
+ init_narrative_repair();
25955
26019
  init_approval();
25956
26020
  init_approver();
25957
26021
  init_specs2();
@@ -26056,6 +26120,9 @@ __export(src_exports, {
26056
26120
  SCAN_EXCLUDE_DIRS: () => SCAN_EXCLUDE_DIRS,
26057
26121
  SDD_RULES: () => SDD_RULES,
26058
26122
  SEMANTIC_GUARANTEES: () => SEMANTIC_GUARANTEES,
26123
+ STEP_COMMON_FIELDS: () => STEP_COMMON_FIELDS,
26124
+ STEP_LABEL_TWINS: () => STEP_LABEL_TWINS,
26125
+ STEP_TYPE_FIELDS: () => STEP_TYPE_FIELDS,
26059
26126
  SUPPORTED_ALIASES: () => SUPPORTED_ALIASES,
26060
26127
  SURFACE_AUDIENCES: () => SURFACE_AUDIENCES,
26061
26128
  SkillResourceNotFoundError: () => SkillResourceNotFoundError,
@@ -26269,6 +26336,7 @@ __export(src_exports, {
26269
26336
  methodSourceFile: () => methodSourceFile,
26270
26337
  methodTypeRefs: () => methodTypeRefs,
26271
26338
  moveSubsystemProject: () => moveSubsystemProject,
26339
+ narrativeStepForeignFields: () => narrativeStepForeignFields,
26272
26340
  normalizeApprover: () => normalizeApprover,
26273
26341
  normalizeComponentLayout: () => normalizeComponentLayout,
26274
26342
  packDirEntry: () => packDirEntry,
@@ -26313,6 +26381,7 @@ __export(src_exports, {
26313
26381
  renderDomainsDoc: () => renderDomainsDoc,
26314
26382
  renderTemplateInstructions: () => renderTemplateInstructions,
26315
26383
  renderWaironGuide: () => renderWaironGuide,
26384
+ repairForeignStepFields: () => repairForeignStepFields,
26316
26385
  resolveAgentTopology: () => resolveAgentTopology,
26317
26386
  resolveChainingParent: () => resolveChainingParent,
26318
26387
  resolveDomains: () => resolveDomains,
@@ -26351,6 +26420,7 @@ __export(src_exports, {
26351
26420
  stateIdEquals: () => stateIdEquals,
26352
26421
  stateIdString: () => stateIdString,
26353
26422
  stepConfigVerdict: () => stepConfigVerdict,
26423
+ stepFieldsFor: () => stepFieldsFor,
26354
26424
  stepGraph: () => stepGraph,
26355
26425
  syncContextFiles: () => syncContextFiles,
26356
26426
  toMarkdown: () => toMarkdown,
@@ -26777,6 +26847,9 @@ function loadProjectConfig4() {
26777
26847
  SCAN_EXCLUDE_DIRS,
26778
26848
  SDD_RULES,
26779
26849
  SEMANTIC_GUARANTEES,
26850
+ STEP_COMMON_FIELDS,
26851
+ STEP_LABEL_TWINS,
26852
+ STEP_TYPE_FIELDS,
26780
26853
  SUPPORTED_ALIASES,
26781
26854
  SURFACE_AUDIENCES,
26782
26855
  SkillResourceNotFoundError,
@@ -26990,6 +27063,7 @@ function loadProjectConfig4() {
26990
27063
  methodSourceFile,
26991
27064
  methodTypeRefs,
26992
27065
  moveSubsystemProject,
27066
+ narrativeStepForeignFields,
26993
27067
  normalizeApprover,
26994
27068
  normalizeComponentLayout,
26995
27069
  packDirEntry,
@@ -27034,6 +27108,7 @@ function loadProjectConfig4() {
27034
27108
  renderDomainsDoc,
27035
27109
  renderTemplateInstructions,
27036
27110
  renderWaironGuide,
27111
+ repairForeignStepFields,
27037
27112
  resolveAgentTopology,
27038
27113
  resolveChainingParent,
27039
27114
  resolveDomains,
@@ -27072,6 +27147,7 @@ function loadProjectConfig4() {
27072
27147
  stateIdEquals,
27073
27148
  stateIdString,
27074
27149
  stepConfigVerdict,
27150
+ stepFieldsFor,
27075
27151
  stepGraph,
27076
27152
  syncContextFiles,
27077
27153
  toMarkdown,