@wairon/cli 5.1.1-dev.20 → 5.1.1-dev.22

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 CHANGED
@@ -65,7 +65,7 @@ var init_defaults = __esm({
65
65
  copilot: ".github/prompts",
66
66
  codex: ".codex/agents"
67
67
  };
68
- WAIRON_VERSION = "5.1.1-dev.20";
68
+ WAIRON_VERSION = "5.1.1-dev.22";
69
69
  GITHUB_REPO = "SYW-Apps/Waffle-AIron";
70
70
  SUPPORTED_ALIASES = ["wai"];
71
71
  SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
@@ -15185,7 +15185,8 @@ __export(provision_exports, {
15185
15185
  listDirectChainedSubprojects: () => listDirectChainedSubprojects,
15186
15186
  moveSubsystemProject: () => moveSubsystemProject,
15187
15187
  provisionProject: () => provisionProject,
15188
- renameComponent: () => renameComponent
15188
+ renameComponent: () => renameComponent,
15189
+ renameMethod: () => renameMethod
15189
15190
  });
15190
15191
  function defaultProjectConfig(name, now) {
15191
15192
  return {
@@ -15518,6 +15519,15 @@ function componentIdsUnder(dir) {
15518
15519
  }
15519
15520
  return ids;
15520
15521
  }
15522
+ function specKind(raw) {
15523
+ if ("componentType" in raw) return "component";
15524
+ if ("parentSystem" in raw) return "subsystem";
15525
+ if ("vision" in raw) return "system";
15526
+ if ("component" in raw && Array.isArray(raw.methods)) return "interface";
15527
+ if ("contract" in raw && Array.isArray(raw.methods)) return "implementation";
15528
+ if ("kind" in raw && Array.isArray(raw.fields)) return "type";
15529
+ return void 0;
15530
+ }
15521
15531
  function rewriteRefFields(specsDir, remap, excludeDir) {
15522
15532
  const rewritten = [];
15523
15533
  for (const file of listFilesRecursive(specsDir, ".yaml")) {
@@ -15539,6 +15549,15 @@ function rewriteRefFields(specsDir, remap, excludeDir) {
15539
15549
  changed = true;
15540
15550
  }
15541
15551
  };
15552
+ const rewriteMethod = (holder, key, owner) => {
15553
+ const name = holder?.[key];
15554
+ if (typeof name !== "string" || typeof owner !== "string") return;
15555
+ const next = remap(name, "method", owner);
15556
+ if (next !== name) {
15557
+ holder[key] = next;
15558
+ changed = true;
15559
+ }
15560
+ };
15542
15561
  const entries = (list2) => Array.isArray(list2) ? list2 : [];
15543
15562
  const rewriteEach = (list2, position) => {
15544
15563
  entries(list2).forEach((_, i) => rewrite(list2, i, position));
@@ -15549,30 +15568,32 @@ function rewriteRefFields(specsDir, remap, excludeDir) {
15549
15568
  rewrite(published, "interface", "interface");
15550
15569
  }
15551
15570
  };
15552
- let kind;
15553
- if ("componentType" in raw) {
15554
- kind = "component";
15571
+ const kind = specKind(raw);
15572
+ if (kind === "component") {
15555
15573
  rewriteEach(raw.dependsOn, "component");
15556
15574
  rewriteEach(raw.owns, "component");
15557
- for (const binding of entries(raw.dispatch)) rewrite(binding, "component", "component");
15558
- } else if ("parentSystem" in raw) {
15559
- kind = "subsystem";
15560
- for (const entrypoint of entries(raw.lifecycle)) rewrite(entrypoint, "component", "component");
15575
+ for (const binding of entries(raw.dispatch)) {
15576
+ rewriteMethod(binding, "method", binding?.component);
15577
+ rewrite(binding, "component", "component");
15578
+ }
15579
+ } else if (kind === "subsystem") {
15580
+ for (const entrypoint of entries(raw.lifecycle)) {
15581
+ rewriteMethod(entrypoint, "method", entrypoint?.component);
15582
+ rewrite(entrypoint, "component", "component");
15583
+ }
15561
15584
  rewritePublished(raw.publicInterfaces);
15562
- } else if ("vision" in raw) {
15563
- kind = "system";
15585
+ } else if (kind === "system") {
15564
15586
  rewritePublished(raw.publicInterfaces);
15565
- } else if ("component" in raw && Array.isArray(raw.methods)) {
15566
- kind = "interface";
15587
+ } else if (kind === "interface") {
15567
15588
  rewrite(raw, "component", "component");
15568
15589
  for (const method2 of raw.methods) {
15569
15590
  for (const param of entries(method2?.params)) rewrite(param, "type", "type");
15570
15591
  }
15571
- } else if ("contract" in raw && Array.isArray(raw.methods)) {
15572
- kind = "implementation";
15592
+ } else if (kind === "implementation") {
15573
15593
  rewrite(raw, "contract", "interface");
15574
15594
  for (const method2 of raw.methods) {
15575
15595
  for (const step of entries(method2?.narrative)) {
15596
+ rewriteMethod(step, "targetMethod", step?.targetComponent);
15576
15597
  rewrite(step, "targetComponent", "component");
15577
15598
  const source = step?.auth?.from;
15578
15599
  if (typeof source === "string" && source.startsWith(COMPONENT_AUTH_SOURCE)) {
@@ -15585,8 +15606,7 @@ function rewriteRefFields(specsDir, remap, excludeDir) {
15585
15606
  }
15586
15607
  }
15587
15608
  }
15588
- } else if ("kind" in raw && Array.isArray(raw.fields)) {
15589
- kind = "type";
15609
+ } else if (kind === "type") {
15590
15610
  rewrite(raw, "componentClass", "entity-class");
15591
15611
  for (const field of raw.fields) rewrite(field, "type", "type");
15592
15612
  }
@@ -15706,7 +15726,101 @@ function removeSpecFile(file, id) {
15706
15726
  fs13.rmdirSync(dir);
15707
15727
  }
15708
15728
  }
15709
- var fs13, path17, COMPONENT_AUTH_SOURCE;
15729
+ function renameMethod(componentId, methodName, newName, pinSymbol) {
15730
+ const component = loadComponentSpec(componentId);
15731
+ if (!component) {
15732
+ throw new WaironError(`component-missing: no component has the id "${componentId}".`);
15733
+ }
15734
+ if (componentId.includes("::")) {
15735
+ throw new WaironError(
15736
+ `chained-component: "${componentId}" lives in a chained subproject; rename its method from that project's own root.`
15737
+ );
15738
+ }
15739
+ if (!METHOD_NAME.test(newName)) {
15740
+ throw new WaironError(`invalid-name: "${newName}" is not a camel-case identifier.`);
15741
+ }
15742
+ const contracts = loadInterfaceSpecs().filter((i) => i.component === componentId);
15743
+ const moving = contracts.filter((i) => i.methods.some((m) => m.name === methodName));
15744
+ if (moving.length === 0) {
15745
+ throw new WaironError(`method-missing: no contract of "${componentId}" declares the method "${methodName}".`);
15746
+ }
15747
+ const taken = moving.filter((i) => i.methods.some((m) => m.name === newName)).map((i) => `"${i.id}"`);
15748
+ if (taken.length > 0) {
15749
+ throw new WaironError(`name-taken: ${taken.join(", ")} already declares a method under the name "${newName}".`);
15750
+ }
15751
+ const implementations = loadImplementationSpecs();
15752
+ const movingContracts = new Set(moving.map((i) => i.id));
15753
+ const renamed = [];
15754
+ for (const contract of moving) {
15755
+ saveInterfaceSpec({
15756
+ ...contract,
15757
+ methods: contract.methods.map((m) => m.name === methodName ? { ...m, name: newName, signature: renameInSignature(m.signature, methodName, newName) } : m)
15758
+ });
15759
+ renamed.push(contract.id);
15760
+ }
15761
+ let pinnedSymbol;
15762
+ for (const implementation of implementations) {
15763
+ if (!movingContracts.has(implementation.contract)) continue;
15764
+ const realization = implementation.methods.find((m) => m.name === methodName);
15765
+ if (!realization) continue;
15766
+ const pin = realization.symbol === void 0 && pinSymbol !== false;
15767
+ if (pin) pinnedSymbol = methodName;
15768
+ saveImplementationSpec({
15769
+ ...implementation,
15770
+ methods: implementation.methods.map((m) => m.name === methodName ? { ...m, name: newName, ...pin ? { symbol: methodName } : {} } : m)
15771
+ });
15772
+ renamed.push(implementation.id);
15773
+ }
15774
+ invalidateSpecCache();
15775
+ const specsDir = aiPathsAt(getProjectRoot()).specsDir();
15776
+ const rewritten = rewriteRefFields(specsDir, (ref, position, owner) => position === "method" && owner === componentId && ref === methodName ? newName : ref).map((spec) => spec.id);
15777
+ const mentions = collectMentions(specsDir, methodName, moving);
15778
+ return {
15779
+ component: componentId,
15780
+ from: methodName,
15781
+ to: newName,
15782
+ renamed,
15783
+ rewritten,
15784
+ mentions,
15785
+ ...pinnedSymbol ? { pinnedSymbol } : {}
15786
+ };
15787
+ }
15788
+ function renameInSignature(signature, from, to) {
15789
+ return signature.replace(identifierPattern(from), to);
15790
+ }
15791
+ function collectMentions(specsDir, methodName, moved) {
15792
+ const mentions = /* @__PURE__ */ new Set();
15793
+ for (const contract of moved) {
15794
+ const wireBound = contract.methods.some((m) => {
15795
+ const endpoint = m.endpoint;
15796
+ return endpoint?.transport === "gRPC" && endpoint.method === methodName;
15797
+ });
15798
+ if (wireBound) mentions.add(contract.id);
15799
+ }
15800
+ const named = identifierPattern(methodName);
15801
+ const namesMethod = (value) => {
15802
+ if (Array.isArray(value)) return value.some(namesMethod);
15803
+ if (!value || typeof value !== "object") return false;
15804
+ return Object.entries(value).some(([key, nested]) => typeof nested === "string" ? PROSE_FIELDS.has(key) && named.test(nested) : namesMethod(nested));
15805
+ };
15806
+ for (const file of listFilesRecursive(specsDir, ".yaml")) {
15807
+ let raw;
15808
+ try {
15809
+ raw = readYamlFile(file);
15810
+ } catch {
15811
+ continue;
15812
+ }
15813
+ if (!raw || typeof raw !== "object") continue;
15814
+ const kind = specKind(raw);
15815
+ if (!kind || !namesMethod(raw)) continue;
15816
+ mentions.add(kind === "system" ? "system" : String(raw.id));
15817
+ }
15818
+ return [...mentions];
15819
+ }
15820
+ function identifierPattern(methodName) {
15821
+ return new RegExp(`(?<![A-Za-z0-9_])${methodName}(?![A-Za-z0-9_])`);
15822
+ }
15823
+ var fs13, path17, COMPONENT_AUTH_SOURCE, METHOD_NAME, PROSE_FIELDS;
15710
15824
  var init_provision = __esm({
15711
15825
  "src/core/provision.ts"() {
15712
15826
  "use strict";
@@ -15720,6 +15834,18 @@ var init_provision = __esm({
15720
15834
  init_errors();
15721
15835
  init_models();
15722
15836
  COMPONENT_AUTH_SOURCE = "component:";
15837
+ METHOD_NAME = /^[a-z][a-zA-Z0-9]*$/;
15838
+ PROSE_FIELDS = /* @__PURE__ */ new Set([
15839
+ "description",
15840
+ "intent",
15841
+ "summary",
15842
+ "condition",
15843
+ "over",
15844
+ "outcome",
15845
+ "error",
15846
+ "note",
15847
+ "caller"
15848
+ ]);
15723
15849
  }
15724
15850
  });
15725
15851
 
@@ -25058,6 +25184,9 @@ function loadProjectConfig5() {
25058
25184
  function renameComponent2(componentId, newId) {
25059
25185
  return renameComponent(componentId, newId);
25060
25186
  }
25187
+ function renameMethod2(componentId, methodName, newName, pinSymbol) {
25188
+ return renameMethod(componentId, methodName, newName, pinSymbol);
25189
+ }
25061
25190
  function qualifiedComponentId(id) {
25062
25191
  const ids = loadComponentSpecs().map((c) => c.id);
25063
25192
  if (ids.includes(id)) return id;
@@ -25661,6 +25790,26 @@ NOTICE:
25661
25790
  }
25662
25791
  }
25663
25792
  );
25793
+ reg(
25794
+ server,
25795
+ "sdd_rename_method",
25796
+ {
25797
+ 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. 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, the specs whose prose still names it, and the pinned symbol when one was set.",
25798
+ inputSchema: {
25799
+ id: import_zod11.z.string().describe("The component whose method is renamed (namespaced if needed)"),
25800
+ method: import_zod11.z.string().describe("The method name as it stands"),
25801
+ newName: import_zod11.z.string().describe("Its new name: a camel-case identifier"),
25802
+ pinSymbol: import_zod11.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")
25803
+ }
25804
+ },
25805
+ ({ id, method: method2, newName, pinSymbol }) => {
25806
+ try {
25807
+ return json(renameMethod2(qualifiedComponentId(id), method2, newName, pinSymbol));
25808
+ } catch (e) {
25809
+ return errText(String(e));
25810
+ }
25811
+ }
25812
+ );
25664
25813
  const componentInput = {
25665
25814
  id: import_zod11.z.string().describe("Lowercase identifier for the component"),
25666
25815
  name: import_zod11.z.string().describe("Human-readable display name"),
@@ -26507,6 +26656,7 @@ var init_server = __esm({
26507
26656
  "sdd_externalize_subsystem",
26508
26657
  "sdd_internalize_subsystem",
26509
26658
  "sdd_rename_component",
26659
+ "sdd_rename_method",
26510
26660
  "sdd_add_component",
26511
26661
  "sdd_define_interface",
26512
26662
  "sdd_set_endpoints",
@@ -41842,7 +41992,8 @@ var WRITE_TOOL_PREFIXES = [
41842
41992
  "sdd_initialize_",
41843
41993
  "sdd_externalize_",
41844
41994
  "sdd_internalize_",
41845
- "sdd_move_"
41995
+ "sdd_move_",
41996
+ "sdd_rename_"
41846
41997
  ];
41847
41998
  var READ_TOOL_PREFIXES = ["sdd_get_", "sdd_validate_"];
41848
41999
  var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
@@ -41853,12 +42004,8 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
41853
42004
  "validateTopology",
41854
42005
  "getProjectConfig"
41855
42006
  ]);
41856
- var WRITE_TOOL_NAMES = /* @__PURE__ */ new Set([
41857
- "sdd_rename_component"
41858
- ]);
41859
42007
  function requiredDataPlaneCapability(toolName) {
41860
42008
  if (READ_TOOL_NAMES.has(toolName) || READ_TOOL_PREFIXES.some((p) => toolName.startsWith(p))) return "project:read";
41861
- if (WRITE_TOOL_NAMES.has(toolName) || WRITE_TOOL_PREFIXES.some((p) => toolName.startsWith(p))) return "project:write";
41862
42009
  return "project:write";
41863
42010
  }
41864
42011
  var TREE_SCOPED_HOST_TOOLS = /* @__PURE__ */ new Set([
@@ -41868,7 +42015,7 @@ var TREE_SCOPED_HOST_TOOLS = /* @__PURE__ */ new Set([
41868
42015
  function toolScope(toolName) {
41869
42016
  if (PROJECT_RECORD_TOOLS.has(toolName)) return "record";
41870
42017
  if (TREE_SCOPED_HOST_TOOLS.has(toolName)) return "tree";
41871
- if (READ_TOOL_NAMES.has(toolName) || READ_TOOL_PREFIXES.some((p) => toolName.startsWith(p)) || WRITE_TOOL_NAMES.has(toolName) || WRITE_TOOL_PREFIXES.some((p) => toolName.startsWith(p))) {
42018
+ if (READ_TOOL_NAMES.has(toolName) || READ_TOOL_PREFIXES.some((p) => toolName.startsWith(p)) || WRITE_TOOL_PREFIXES.some((p) => toolName.startsWith(p))) {
41872
42019
  return "tree";
41873
42020
  }
41874
42021
  return void 0;