vscode-behavior3 2.3.0 → 2.5.0

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/extension.js CHANGED
@@ -212530,6 +212530,12 @@ var Node = class _Node {
212530
212530
  info(msg) {
212531
212531
  console.info(`${this.cfg.tree.name}->${this.name}#${this.id}: ${msg}`);
212532
212532
  }
212533
+ /**
212534
+ * use console.log to print log message
212535
+ */
212536
+ log(msg) {
212537
+ console.log(`${this.cfg.tree.name}->${this.name}#${this.id}: ${msg}`);
212538
+ }
212533
212539
  _checkOneof(inputIndex, argValue, defaultValue) {
212534
212540
  const inputValue = this.input[inputIndex];
212535
212541
  const inputName = this.cfg.input[inputIndex];
@@ -212768,17 +212774,24 @@ var Context = class {
212768
212774
  return Node.create(this, treeCfg.root);
212769
212775
  }
212770
212776
  };
212771
- var Stack = class {
212777
+ var StackSlice = class {
212772
212778
  _nodes = [];
212773
- _tree;
212774
- constructor(tree) {
212775
- this._tree = tree;
212776
- }
212777
212779
  get length() {
212778
212780
  return this._nodes.length;
212779
212781
  }
212780
- indexOf(node) {
212781
- return this._nodes.indexOf(node);
212782
+ move(dest, start) {
212783
+ const count = this._nodes.length - start;
212784
+ dest._nodes.push(...this._nodes.splice(start, count));
212785
+ }
212786
+ clear() {
212787
+ this._nodes.length = 0;
212788
+ }
212789
+ };
212790
+ var Stack = class extends StackSlice {
212791
+ _tree;
212792
+ constructor(tree) {
212793
+ super();
212794
+ this._tree = tree;
212782
212795
  }
212783
212796
  top() {
212784
212797
  const nodes = this._nodes;
@@ -212799,9 +212812,6 @@ var Stack = class {
212799
212812
  this.pop();
212800
212813
  }
212801
212814
  }
212802
- move(dest, start, count) {
212803
- dest._nodes.push(...this._nodes.splice(start, count));
212804
- }
212805
212815
  clear() {
212806
212816
  this.popTo(0);
212807
212817
  }
@@ -213710,7 +213720,7 @@ var Parallel = class extends (_a17 = Node) {
213710
213720
  if (childStack === void 0) {
213711
213721
  status = children[i].tick(tree);
213712
213722
  } else if (childStack.length > 0) {
213713
- childStack.move(stack, 0, childStack.length);
213723
+ childStack.move(stack, 0);
213714
213724
  while (stack.length > level) {
213715
213725
  status = stack.top().tick(tree);
213716
213726
  if (status === "running") {
@@ -213722,9 +213732,9 @@ var Parallel = class extends (_a17 = Node) {
213722
213732
  }
213723
213733
  if (status === "running") {
213724
213734
  if (childStack === void 0) {
213725
- childStack = new Stack(tree);
213735
+ childStack = new StackSlice();
213726
213736
  }
213727
- stack.move(childStack, level, stack.length - level);
213737
+ stack.move(childStack, level);
213728
213738
  } else {
213729
213739
  count++;
213730
213740
  childStack = EMPTY_STACK$1;
@@ -213770,7 +213780,7 @@ var Race = class extends (_a18 = Node) {
213770
213780
  if (childStack === void 0) {
213771
213781
  status = children[i].tick(tree);
213772
213782
  } else if (childStack.length > 0) {
213773
- childStack.move(stack, 0, childStack.length);
213783
+ childStack.move(stack, 0);
213774
213784
  while (stack.length > level) {
213775
213785
  status = stack.top().tick(tree);
213776
213786
  if (status === "running") {
@@ -213780,9 +213790,9 @@ var Race = class extends (_a18 = Node) {
213780
213790
  }
213781
213791
  if (status === "running") {
213782
213792
  if (childStack === void 0) {
213783
- childStack = new Stack(tree);
213793
+ childStack = new StackSlice();
213784
213794
  }
213785
- stack.move(childStack, level, stack.length - level);
213795
+ stack.move(childStack, level);
213786
213796
  } else if (status === "success") {
213787
213797
  last.forEach((v) => v !== EMPTY_STACK && v.clear());
213788
213798
  return "success";
@@ -214018,7 +214028,7 @@ var Watchdog = class extends (_a23 = Node) {
214018
214028
  } else if (last === void 0) {
214019
214029
  status = this.children[1].tick(tree);
214020
214030
  } else {
214021
- last.move(tree.stack, 0, last.length);
214031
+ last.move(tree.stack, 0);
214022
214032
  while (tree.stack.length > level) {
214023
214033
  const child = tree.stack.top();
214024
214034
  status = child.tick(tree);
@@ -214029,9 +214039,9 @@ var Watchdog = class extends (_a23 = Node) {
214029
214039
  }
214030
214040
  if (status === "running") {
214031
214041
  if (last === void 0) {
214032
- last = new Stack(tree);
214042
+ last = new StackSlice();
214033
214043
  }
214034
- tree.stack.move(last, level, tree.stack.length - level);
214044
+ tree.stack.move(last, level);
214035
214045
  return tree.yield(this, last);
214036
214046
  } else {
214037
214047
  return status;
@@ -214857,7 +214867,7 @@ var Timeout = class extends (_a41 = Node) {
214857
214867
  last.stack.clear();
214858
214868
  return "failure";
214859
214869
  } else {
214860
- last.stack.move(stack, 0, last.stack.length);
214870
+ last.stack.move(stack, 0);
214861
214871
  while (stack.length > level) {
214862
214872
  const child = stack.top();
214863
214873
  status = child.tick(tree);
@@ -214870,11 +214880,11 @@ var Timeout = class extends (_a41 = Node) {
214870
214880
  if (last === void 0) {
214871
214881
  const time = this._checkOneof(0, this.args.time, 0);
214872
214882
  last = {
214873
- stack: new Stack(tree),
214883
+ stack: new StackSlice(),
214874
214884
  expired: context.time + time
214875
214885
  };
214876
214886
  }
214877
- stack.move(last.stack, level, stack.length - level);
214887
+ stack.move(last.stack, level);
214878
214888
  return tree.yield(this, last);
214879
214889
  } else {
214880
214890
  return status;
@@ -214897,6 +214907,7 @@ var Timeout = class extends (_a41 = Node) {
214897
214907
  }
214898
214908
  ],
214899
214909
  doc: `
214910
+ + \u5728\u9650\u5B9A\u65F6\u95F4\u5185\u6267\u884C\u5B50\u8282\u70B9\uFF0C\u8D85\u65F6\u5219\u5931\u8D25
214900
214911
  + \u53EA\u80FD\u6709\u4E00\u4E2A\u5B50\u8282\u70B9\uFF0C\u591A\u4E2A\u4EC5\u6267\u884C\u7B2C\u4E00\u4E2A
214901
214912
  + \u5F53\u5B50\u8282\u70B9\u6267\u884C\u8D85\u65F6\u6216\u8FD4\u56DE \`failure\` \u65F6\uFF0C\u8FD4\u56DE \`failure\`
214902
214913
  + \u5176\u4F59\u60C5\u51B5\u8FD4\u56DE\u5B50\u8282\u70B9\u7684\u6267\u884C\u72B6\u6001
@@ -215264,10 +215275,7 @@ function customAlphabet(alphabet, size = 21) {
215264
215275
 
215265
215276
  // webview/shared/stable-id.ts
215266
215277
  var UUID_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
215267
- var generateUuid = customAlphabet(
215268
- UUID_ALPHABET,
215269
- 10
215270
- );
215278
+ var generateUuid = customAlphabet(UUID_ALPHABET, 10);
215271
215279
  var hashString = (value) => {
215272
215280
  let hash = 2166136261;
215273
215281
  for (let index = 0; index < value.length; index += 1) {
@@ -215281,7 +215289,7 @@ var generateDeterministicUuid = (seed) => {
215281
215289
  let result = "";
215282
215290
  for (let index = 0; index < 10; index += 1) {
215283
215291
  state = Math.imul(state ^ state >>> 16, 2246822519) >>> 0;
215284
- state ^= hashString(`${seed}:${index}`);
215292
+ state = (state ^ hashString(`${seed}:${index}`)) >>> 0;
215285
215293
  result += UUID_ALPHABET[state % UUID_ALPHABET.length];
215286
215294
  }
215287
215295
  return result;
@@ -215375,6 +215383,12 @@ var asRequiredString = (value, label) => {
215375
215383
  }
215376
215384
  return value;
215377
215385
  };
215386
+ var normalizeTreeVersion = (value) => {
215387
+ if (value === void 0) {
215388
+ return DOCUMENT_VERSION;
215389
+ }
215390
+ return asRequiredString(value, "tree file version");
215391
+ };
215378
215392
  var asStringArray = (value, label) => {
215379
215393
  if (value === void 0) {
215380
215394
  return [];
@@ -215389,6 +215403,34 @@ var asStringArray = (value, label) => {
215389
215403
  return entry;
215390
215404
  });
215391
215405
  };
215406
+ var normalizeNodeLabel = (label, record) => {
215407
+ const rawNodeName = record.name;
215408
+ if (typeof rawNodeName !== "string" || !rawNodeName.trim()) {
215409
+ return label;
215410
+ }
215411
+ return `${label}(${rawNodeName.trim()})`;
215412
+ };
215413
+ var normalizeNodeSlotEntry = (value, label) => {
215414
+ if (typeof value === "string") {
215415
+ return asRequiredString(value, label);
215416
+ }
215417
+ const record = expectPlainRecord(value, label);
215418
+ return {
215419
+ name: asRequiredString(record.name, `${label}.name`),
215420
+ checker: asOptionalNonEmptyString(record.checker, `${label}.checker`),
215421
+ visible: asOptionalNonEmptyString(record.visible, `${label}.visible`)
215422
+ };
215423
+ };
215424
+ var normalizeNodeSlots = (value, label) => {
215425
+ if (value === void 0) {
215426
+ return void 0;
215427
+ }
215428
+ if (!Array.isArray(value)) {
215429
+ throw new Error(`${label} must be an array`);
215430
+ }
215431
+ const slots = value.map((entry, index) => normalizeNodeSlotEntry(entry, `${label}[${index}]`));
215432
+ return slots.length > 0 ? slots : void 0;
215433
+ };
215392
215434
  var asWorkdirRelativeJsonPathArray = (value, label) => {
215393
215435
  const entries = asStringArray(value, label);
215394
215436
  return entries.map((entry, index) => {
@@ -215499,44 +215541,43 @@ var normalizeNodeArgs = (value, label) => {
215499
215541
  oneof: asOptionalString(record.oneof),
215500
215542
  default: record.default,
215501
215543
  options: normalizeNodeArgOptions(record.options, `${label}[${index}].options`),
215502
- checker: asOptionalNonEmptyString(record.checker, `${label}[${index}].checker`)
215544
+ checker: asOptionalNonEmptyString(record.checker, `${label}[${index}].checker`),
215545
+ visible: asOptionalNonEmptyString(record.visible, `${label}[${index}].visible`)
215503
215546
  };
215504
215547
  });
215505
215548
  };
215506
215549
  var normalizeNodeDef = (value, label) => {
215507
215550
  const record = expectPlainRecord(value, label);
215508
- const type = asRequiredString(record.type, `${label}.type`);
215551
+ const nodeLabel = normalizeNodeLabel(label, record);
215552
+ const name = asRequiredString(record.name, `${nodeLabel}.name`);
215553
+ const type = asRequiredString(record.type, `${nodeLabel}.type`);
215509
215554
  if (!NODE_DEF_TYPES.has(type)) {
215510
- throw new Error(`${label}.type must be one of ${Array.from(NODE_DEF_TYPES).join(", ")}`);
215555
+ throw new Error(
215556
+ `${nodeLabel}.type must be one of ${Array.from(NODE_DEF_TYPES).join(", ")}`
215557
+ );
215511
215558
  }
215512
215559
  const groupValue = record.group;
215513
215560
  const group = groupValue === void 0 ? void 0 : Array.isArray(groupValue) ? groupValue.map(
215514
- (entry, index) => asRequiredString(entry, `${label}.group[${index}]`)
215515
- ) : [asRequiredString(groupValue, `${label}.group`)];
215561
+ (entry, index) => asRequiredString(entry, `${nodeLabel}.group[${index}]`)
215562
+ ) : [asRequiredString(groupValue, `${nodeLabel}.group`)];
215516
215563
  const childrenValue = record.children;
215517
215564
  if (childrenValue !== void 0 && !CHILDREN_ARITIES.has(childrenValue)) {
215518
- throw new Error(`${label}.children must be one of -1, 0, 1, 2, 3`);
215565
+ throw new Error(`${nodeLabel}.children must be one of -1, 0, 1, 2, 3`);
215519
215566
  }
215520
215567
  const statusValue = record.status;
215521
- const status = statusValue === void 0 ? void 0 : asStringArray(statusValue, `${label}.status`).map((entry) => {
215568
+ const status = statusValue === void 0 ? void 0 : asStringArray(statusValue, `${nodeLabel}.status`).map((entry) => {
215522
215569
  if (!NODE_STATUS_VALUES.has(entry)) {
215523
- throw new Error(`${label}.status contains unsupported value: ${entry}`);
215570
+ throw new Error(`${nodeLabel}.status contains unsupported value: ${entry}`);
215524
215571
  }
215525
215572
  return entry;
215526
215573
  });
215527
215574
  return {
215528
- name: asRequiredString(record.name, `${label}.name`),
215575
+ name,
215529
215576
  type,
215530
215577
  desc: asOptionalString(record.desc) ?? "",
215531
- input: (() => {
215532
- const input = asStringArray(record.input, `${label}.input`);
215533
- return input.length > 0 ? input : void 0;
215534
- })(),
215535
- output: (() => {
215536
- const output = asStringArray(record.output, `${label}.output`);
215537
- return output.length > 0 ? output : void 0;
215538
- })(),
215539
- args: normalizeNodeArgs(record.args, `${label}.args`),
215578
+ input: normalizeNodeSlots(record.input, `${nodeLabel}.input`),
215579
+ output: normalizeNodeSlots(record.output, `${nodeLabel}.output`),
215580
+ args: normalizeNodeArgs(record.args, `${nodeLabel}.args`),
215540
215581
  doc: asOptionalString(record.doc),
215541
215582
  icon: asOptionalString(record.icon),
215542
215583
  color: asOptionalString(record.color),
@@ -215693,7 +215734,7 @@ var normalizeTreeData = (value, opts) => {
215693
215734
  const variablesValue = record.variables;
215694
215735
  const variablesRecord = variablesValue === void 0 ? void 0 : expectPlainRecord(variablesValue, "tree file variables");
215695
215736
  return {
215696
- version: asRequiredString(record.version, "tree file version"),
215737
+ version: normalizeTreeVersion(record.version),
215697
215738
  name: asRequiredString(record.name, "tree file name"),
215698
215739
  prefix: asOptionalString(record.prefix) ?? "",
215699
215740
  desc: asOptionalString(record.desc),
@@ -215948,10 +215989,10 @@ var applyMainTreeDisplayIds = (root, idsByStableId) => {
215948
215989
  }
215949
215990
  });
215950
215991
  };
215951
- var hasMissingStableIds = (content) => {
215992
+ var needsLegacyTreeWriteback = (content) => {
215952
215993
  try {
215953
215994
  const parsed = JSON.parse(content);
215954
- return subtreeNeedsMissingIds(parsed.root) || parsed.$override !== void 0 || parsed.import !== void 0 || parsed.vars !== void 0;
215995
+ return parsed.version === void 0 || subtreeNeedsMissingIds(parsed.root) || parsed.$override !== void 0 || parsed.import !== void 0 || parsed.vars !== void 0;
215955
215996
  } catch {
215956
215997
  return false;
215957
215998
  }
@@ -215974,7 +216015,7 @@ var loadSubtreeSourceCache = async (params) => {
215974
216015
  return;
215975
216016
  }
215976
216017
  try {
215977
- const needsWriteback = hasMissingStableIds(content);
216018
+ const needsWriteback = needsLegacyTreeWriteback(content);
215978
216019
  const tree = parsePersistedTreeContent(content, normalizedPath);
215979
216020
  cache[normalizedPath] = tree;
215980
216021
  await params.onTreeLoaded?.({
@@ -216143,16 +216184,22 @@ var findNodeDef = (nodeDefMap, nodeName) => {
216143
216184
  return nodeDefMap.get(nodeName) ?? null;
216144
216185
  };
216145
216186
  var cleanSlotLabel = (value) => value.replace(/\.\.\.$/, "").replace(/\?/g, "");
216187
+ var isStructuredSlotDefinition = (slot) => Boolean(slot && typeof slot === "object" && !Array.isArray(slot));
216146
216188
  var parseSlotDefinition = (slot, slotDefs, index) => {
216147
- const raw = slot ?? "";
216189
+ const raw = typeof slot === "string" ? slot : slot?.name ?? "";
216148
216190
  const hasOptionalMarker = raw.includes("?");
216149
216191
  const hasVariadicMarker = raw.endsWith("...");
216150
216192
  const variadic = hasVariadicMarker && (slotDefs && index !== void 0 ? index === slotDefs.length - 1 : true);
216193
+ const checker = isStructuredSlotDefinition(slot) ? slot.checker?.trim() || void 0 : void 0;
216194
+ const visible = isStructuredSlotDefinition(slot) ? slot.visible?.trim() || void 0 : void 0;
216151
216195
  return {
216152
216196
  raw,
216197
+ name: cleanSlotLabel(raw),
216153
216198
  label: cleanSlotLabel(raw),
216154
216199
  required: !hasOptionalMarker,
216155
- variadic
216200
+ variadic,
216201
+ checker,
216202
+ visible
216156
216203
  };
216157
216204
  };
216158
216205
  var getNodeArgRawType = (arg) => {
@@ -216475,6 +216522,8 @@ var BUILD_HOOK_MARKER = "__behavior3BuildHook";
216475
216522
  var BATCH_HOOK_MARKER = "__behavior3BatchHook";
216476
216523
  var CHECK_HOOK_MARKER = "__behavior3CheckHook";
216477
216524
  var CHECK_HOOK_NAME = "__behavior3CheckName";
216525
+ var VISIBLE_HOOK_MARKER = "__behavior3VisibleHook";
216526
+ var VISIBLE_HOOK_NAME = "__behavior3VisibleName";
216478
216527
  var markBuildHook = (ctor) => {
216479
216528
  Object.defineProperty(ctor, BUILD_HOOK_MARKER, {
216480
216529
  value: true,
@@ -216501,15 +216550,34 @@ var markCheckCtor = (ctor, explicitName) => {
216501
216550
  });
216502
216551
  return ctor;
216503
216552
  };
216553
+ var markVisibleCtor = (ctor, explicitName) => {
216554
+ const name = explicitName?.trim() || ctor.name;
216555
+ Object.defineProperty(ctor, VISIBLE_HOOK_MARKER, {
216556
+ value: true,
216557
+ configurable: false
216558
+ });
216559
+ Object.defineProperty(ctor, VISIBLE_HOOK_NAME, {
216560
+ value: name,
216561
+ configurable: false
216562
+ });
216563
+ return ctor;
216564
+ };
216504
216565
  var markCheckHook = (nameOrCtor, _context) => {
216505
216566
  if (typeof nameOrCtor === "function") {
216506
216567
  return markCheckCtor(nameOrCtor);
216507
216568
  }
216508
216569
  return (ctor) => markCheckCtor(ctor, nameOrCtor);
216509
216570
  };
216571
+ var markVisibleHook = (nameOrCtor, _context) => {
216572
+ if (typeof nameOrCtor === "function") {
216573
+ return markVisibleCtor(nameOrCtor);
216574
+ }
216575
+ return (ctor) => markVisibleCtor(ctor, nameOrCtor);
216576
+ };
216510
216577
  var isDecoratedBuildHookCtor = (value) => typeof value === "function" && value[BUILD_HOOK_MARKER] === true;
216511
216578
  var isDecoratedBatchHookCtor = (value) => typeof value === "function" && value[BATCH_HOOK_MARKER] === true;
216512
216579
  var isDecoratedCheckCtor = (value) => typeof value === "function" && value[CHECK_HOOK_MARKER] === true;
216580
+ var isDecoratedVisibleCtor = (value) => typeof value === "function" && value[VISIBLE_HOOK_MARKER] === true;
216513
216581
  var findDecoratedBuildHookCtor = (moduleRecord) => {
216514
216582
  const decorated = Array.from(new Set(Object.values(moduleRecord))).filter(
216515
216583
  isDecoratedBuildHookCtor
@@ -216541,6 +216609,7 @@ var findDecoratedBatchHookCtor = (moduleRecord) => {
216541
216609
  return legacyDecorated[0];
216542
216610
  };
216543
216611
  var findDecoratedCheckCtors = (moduleRecord) => Array.from(new Set(Object.values(moduleRecord))).filter(isDecoratedCheckCtor);
216612
+ var findDecoratedVisibleCtors = (moduleRecord) => Array.from(new Set(Object.values(moduleRecord))).filter(isDecoratedVisibleCtor);
216544
216613
  var createBuildHooks = (moduleExports, env2, reportMissing = true) => {
216545
216614
  if (!moduleExports || typeof moduleExports !== "object") {
216546
216615
  return void 0;
@@ -216591,7 +216660,7 @@ var createBatchHooks = (moduleExports, env2, reportMissing = true) => {
216591
216660
  }
216592
216661
  return void 0;
216593
216662
  };
216594
- var createNodeArgCheckers = (moduleExports, env2) => {
216663
+ var createNodeFieldCheckers = (moduleExports, env2) => {
216595
216664
  const checkers = /* @__PURE__ */ new Map();
216596
216665
  let hasError = false;
216597
216666
  if (!moduleExports || typeof moduleExports !== "object") {
@@ -216626,10 +216695,70 @@ var createNodeArgCheckers = (moduleExports, env2) => {
216626
216695
  }
216627
216696
  return { checkers, hasError, hasCheckers: decorated.length > 0 };
216628
216697
  };
216698
+ var normalizeNodeFieldVisibleResult = (result) => result !== false;
216699
+ var createNodeFieldVisibles = (moduleExports, env2) => {
216700
+ const visibles = /* @__PURE__ */ new Map();
216701
+ let hasError = false;
216702
+ if (!moduleExports || typeof moduleExports !== "object") {
216703
+ return { visibles, hasError, hasVisibles: false };
216704
+ }
216705
+ const moduleRecord = moduleExports;
216706
+ const decorated = findDecoratedVisibleCtors(moduleRecord);
216707
+ for (const ctor of decorated) {
216708
+ const name = ctor[VISIBLE_HOOK_NAME]?.trim() || ctor.name;
216709
+ if (!name) {
216710
+ logger.error("visible class must have a non-empty @behavior3.visible name");
216711
+ hasError = true;
216712
+ continue;
216713
+ }
216714
+ if (visibles.has(name)) {
216715
+ logger.error(`duplicate @behavior3.visible registration: ${name}`);
216716
+ hasError = true;
216717
+ continue;
216718
+ }
216719
+ try {
216720
+ const instance = new ctor(env2);
216721
+ if (typeof instance.visible !== "function") {
216722
+ logger.error(`visible '${name}' must provide a visible(value, ctx) method`);
216723
+ hasError = true;
216724
+ continue;
216725
+ }
216726
+ visibles.set(name, instance);
216727
+ } catch (error) {
216728
+ logger.error(`failed to instantiate visible '${name}'`, error);
216729
+ hasError = true;
216730
+ }
216731
+ }
216732
+ return { visibles, hasError, hasVisibles: decorated.length > 0 };
216733
+ };
216734
+ var createNodeFieldVisibleRuntimeWithCheckModules = (buildScriptModule, checkScriptModules, env2) => {
216735
+ const nodeFieldVisibles = /* @__PURE__ */ new Map();
216736
+ let hasError = false;
216737
+ const mergeModuleVisibles = (moduleExports) => {
216738
+ const visibleResult = createNodeFieldVisibles(moduleExports, env2);
216739
+ hasError = hasError || visibleResult.hasError;
216740
+ for (const [name, visible] of visibleResult.visibles) {
216741
+ if (nodeFieldVisibles.has(name)) {
216742
+ logger.error(`duplicate @behavior3.visible registration: ${name}`);
216743
+ hasError = true;
216744
+ continue;
216745
+ }
216746
+ nodeFieldVisibles.set(name, visible);
216747
+ }
216748
+ };
216749
+ mergeModuleVisibles(buildScriptModule);
216750
+ for (const checkScript of checkScriptModules) {
216751
+ mergeModuleVisibles(checkScript.moduleExports);
216752
+ }
216753
+ return {
216754
+ nodeFieldVisibles,
216755
+ hasError
216756
+ };
216757
+ };
216629
216758
  var createBuildScriptRuntime = (moduleExports, env2) => {
216630
216759
  if (!moduleExports || typeof moduleExports !== "object") {
216631
216760
  return {
216632
- nodeArgCheckers: /* @__PURE__ */ new Map(),
216761
+ nodeFieldCheckers: /* @__PURE__ */ new Map(),
216633
216762
  hasError: false,
216634
216763
  hasEntries: false
216635
216764
  };
@@ -216637,7 +216766,7 @@ var createBuildScriptRuntime = (moduleExports, env2) => {
216637
216766
  const moduleRecord = moduleExports;
216638
216767
  const hasBuildHookCandidate = typeof moduleRecord.BuildHook === "function" || typeof moduleRecord.Hook === "function" || Object.values(moduleRecord).some(isDecoratedBuildHookCtor) || typeof moduleRecord.default === "function" && !isDecoratedCheckCtor(moduleRecord.default) && !isDecoratedBatchHookCtor(moduleRecord.default);
216639
216768
  const buildScript = createBuildHooks(moduleExports, env2, false);
216640
- const checkerResult = createNodeArgCheckers(moduleExports, env2);
216769
+ const checkerResult = createNodeFieldCheckers(moduleExports, env2);
216641
216770
  const hasEntries = Boolean(buildScript) || checkerResult.hasCheckers;
216642
216771
  if (!hasEntries) {
216643
216772
  logger.error(
@@ -216646,39 +216775,35 @@ var createBuildScriptRuntime = (moduleExports, env2) => {
216646
216775
  }
216647
216776
  return {
216648
216777
  buildScript,
216649
- nodeArgCheckers: checkerResult.checkers,
216778
+ nodeFieldCheckers: checkerResult.checkers,
216650
216779
  hasError: checkerResult.hasError || !hasEntries || hasBuildHookCandidate && !buildScript,
216651
216780
  hasEntries
216652
216781
  };
216653
216782
  };
216654
216783
  var createBuildScriptRuntimeWithCheckModules = (buildScriptModule, checkScriptModules, env2) => {
216655
216784
  const runtime = createBuildScriptRuntime(buildScriptModule, env2);
216656
- const nodeArgCheckers = new Map(runtime.nodeArgCheckers);
216785
+ const nodeFieldCheckers = new Map(runtime.nodeFieldCheckers);
216657
216786
  let hasError = runtime.hasError;
216658
216787
  let hasCheckEntries = false;
216659
216788
  for (const checkScript of checkScriptModules) {
216660
- const checkerResult = createNodeArgCheckers(checkScript.moduleExports, env2);
216789
+ const checkerResult = createNodeFieldCheckers(checkScript.moduleExports, env2);
216661
216790
  if (!checkerResult.hasCheckers) {
216662
- logger.error(
216663
- `check script must export at least one @behavior3.check class: ${checkScript.path}`
216664
- );
216665
- hasError = true;
216666
216791
  continue;
216667
216792
  }
216668
216793
  hasCheckEntries = true;
216669
216794
  hasError = hasError || checkerResult.hasError;
216670
216795
  for (const [name, checker] of checkerResult.checkers) {
216671
- if (nodeArgCheckers.has(name)) {
216796
+ if (nodeFieldCheckers.has(name)) {
216672
216797
  logger.error(`duplicate @behavior3.check registration: ${name}`);
216673
216798
  hasError = true;
216674
216799
  continue;
216675
216800
  }
216676
- nodeArgCheckers.set(name, checker);
216801
+ nodeFieldCheckers.set(name, checker);
216677
216802
  }
216678
216803
  }
216679
216804
  return {
216680
216805
  ...runtime,
216681
- nodeArgCheckers,
216806
+ nodeFieldCheckers,
216682
216807
  hasError,
216683
216808
  hasEntries: runtime.hasEntries || hasCheckEntries
216684
216809
  };
@@ -216824,7 +216949,12 @@ var processBatchTree = (tree, treePath, batch, errors) => {
216824
216949
  }
216825
216950
  return tree;
216826
216951
  };
216827
- var normalizeNodeArgCheckResult = (result) => {
216952
+ var createEmptyNodeFieldVisibilityState = () => ({
216953
+ args: {},
216954
+ input: {},
216955
+ output: {}
216956
+ });
216957
+ var normalizeNodeFieldCheckResult = (result) => {
216828
216958
  if (Array.isArray(result)) {
216829
216959
  return result.filter((entry) => typeof entry === "string" && entry.trim());
216830
216960
  }
@@ -216842,7 +216972,105 @@ var walkTreeNodes = (node, visit) => {
216842
216972
  walkTreeNodes(child, visit);
216843
216973
  }
216844
216974
  };
216845
- var collectNodeArgCheckDiagnostics = (params) => {
216975
+ var buildNodeSlotField = (slot, slotDefs, index) => {
216976
+ const parsed = parseSlotDefinition(slot, slotDefs, index);
216977
+ return {
216978
+ name: parsed.name,
216979
+ label: parsed.label,
216980
+ required: parsed.required,
216981
+ variadic: parsed.variadic,
216982
+ checker: parsed.checker,
216983
+ visible: parsed.visible
216984
+ };
216985
+ };
216986
+ var getSlotValue = (values, slotDefs, index) => {
216987
+ const slotField = parseSlotDefinition(slotDefs?.[index] ?? "", slotDefs, index);
216988
+ return slotField.variadic ? values?.slice(index) ?? [] : values?.[index];
216989
+ };
216990
+ var formatFieldLocator = (node, fieldKind, fieldName, fieldIndex) => {
216991
+ if (fieldKind === "arg") {
216992
+ return `${node.id}|${node.name}.${fieldName}`;
216993
+ }
216994
+ return `${node.id}|${node.name}.${fieldKind}[${fieldIndex ?? 0}:${fieldName}]`;
216995
+ };
216996
+ var getNodeSlotContext = (params) => {
216997
+ if (!isStructuredSlotDefinition(params.slot)) {
216998
+ return null;
216999
+ }
217000
+ return {
217001
+ node: params.node,
217002
+ tree: params.tree,
217003
+ nodeDef: params.nodeDef,
217004
+ fieldKind: params.fieldKind,
217005
+ fieldName: buildNodeSlotField(params.slot, params.slotDefs, params.index).name,
217006
+ fieldIndex: params.index,
217007
+ slot: params.fieldKind === "input" ? params.slot : params.slot,
217008
+ slotField: buildNodeSlotField(params.slot, params.slotDefs, params.index),
217009
+ treePath: params.treePath,
217010
+ env: params.env
217011
+ };
217012
+ };
217013
+ var visitCustomNodeFields = (params) => {
217014
+ for (const arg of params.nodeDef.args ?? []) {
217015
+ const checkerName = arg.checker?.trim() || void 0;
217016
+ const visibleName = arg.visible?.trim() || void 0;
217017
+ if (!(checkerName || visibleName)) {
217018
+ continue;
217019
+ }
217020
+ const ctx = {
217021
+ node: params.node,
217022
+ tree: params.tree,
217023
+ nodeDef: params.nodeDef,
217024
+ fieldKind: "arg",
217025
+ fieldName: arg.name,
217026
+ arg,
217027
+ treePath: params.treePath,
217028
+ env: params.env
217029
+ };
217030
+ params.onArg?.({
217031
+ fieldName: arg.name,
217032
+ checkerName,
217033
+ visibleName,
217034
+ value: params.node.args?.[arg.name],
217035
+ ctx
217036
+ });
217037
+ }
217038
+ for (const [fieldKind, slotDefs, values, visitor] of [
217039
+ ["input", params.nodeDef.input, params.node.input, params.onInput],
217040
+ ["output", params.nodeDef.output, params.node.output, params.onOutput]
217041
+ ]) {
217042
+ for (let index = 0; index < (slotDefs?.length ?? 0); index += 1) {
217043
+ const slot = slotDefs?.[index] ?? "";
217044
+ const slotField = buildNodeSlotField(slot, slotDefs, index);
217045
+ if (!(slotField.checker || slotField.visible)) {
217046
+ continue;
217047
+ }
217048
+ const ctx = getNodeSlotContext({
217049
+ fieldKind,
217050
+ node: params.node,
217051
+ tree: params.tree,
217052
+ nodeDef: params.nodeDef,
217053
+ slotDefs,
217054
+ slot,
217055
+ index,
217056
+ treePath: params.treePath,
217057
+ env: params.env
217058
+ });
217059
+ if (!ctx) {
217060
+ continue;
217061
+ }
217062
+ visitor?.({
217063
+ fieldName: slotField.name,
217064
+ fieldIndex: index,
217065
+ checkerName: slotField.checker,
217066
+ visibleName: slotField.visible,
217067
+ value: getSlotValue(values, slotDefs, index),
217068
+ ctx
217069
+ });
217070
+ }
217071
+ }
217072
+ };
217073
+ var collectNodeFieldCheckDiagnostics = (params) => {
216846
217074
  const diagnostics = [];
216847
217075
  const targets = params.targets ?? [];
216848
217076
  const entries = targets.length ? targets : (() => {
@@ -216856,47 +217084,182 @@ var collectNodeArgCheckDiagnostics = (params) => {
216856
217084
  if (!nodeDef) {
216857
217085
  continue;
216858
217086
  }
216859
- for (const arg of nodeDef.args ?? []) {
216860
- const checkerName = arg.checker?.trim();
216861
- if (!checkerName) {
216862
- continue;
217087
+ visitCustomNodeFields({
217088
+ node,
217089
+ tree: params.tree,
217090
+ nodeDef,
217091
+ treePath: target.treePath ?? params.treePath,
217092
+ env: params.env,
217093
+ onArg: ({ fieldName, checkerName, value, ctx }) => {
217094
+ if (!checkerName) {
217095
+ return;
217096
+ }
217097
+ const pushDiagnostic = (message) => {
217098
+ diagnostics.push({
217099
+ instanceKey: target.instanceKey,
217100
+ nodeId: node.id,
217101
+ nodeName: node.name,
217102
+ fieldKind: "arg",
217103
+ fieldName,
217104
+ checker: checkerName,
217105
+ message
217106
+ });
217107
+ };
217108
+ const checker = params.checkers.get(checkerName);
217109
+ if (!checker) {
217110
+ pushDiagnostic(`checker '${checkerName}' is not registered`);
217111
+ return;
217112
+ }
217113
+ try {
217114
+ const messages = normalizeNodeFieldCheckResult(checker.validate(value, ctx));
217115
+ messages.forEach(pushDiagnostic);
217116
+ } catch (error) {
217117
+ pushDiagnostic(`checker '${checkerName}' failed: ${formatRuntimeError(error)}`);
217118
+ }
217119
+ },
217120
+ onInput: ({ fieldName, fieldIndex, checkerName, value, ctx }) => {
217121
+ if (!checkerName) {
217122
+ return;
217123
+ }
217124
+ const pushDiagnostic = (message) => {
217125
+ diagnostics.push({
217126
+ instanceKey: target.instanceKey,
217127
+ nodeId: node.id,
217128
+ nodeName: node.name,
217129
+ fieldKind: "input",
217130
+ fieldName,
217131
+ fieldIndex,
217132
+ checker: checkerName,
217133
+ message
217134
+ });
217135
+ };
217136
+ const checker = params.checkers.get(checkerName);
217137
+ if (!checker) {
217138
+ pushDiagnostic(`checker '${checkerName}' is not registered`);
217139
+ return;
217140
+ }
217141
+ try {
217142
+ const messages = normalizeNodeFieldCheckResult(checker.validate(value, ctx));
217143
+ messages.forEach(pushDiagnostic);
217144
+ } catch (error) {
217145
+ pushDiagnostic(`checker '${checkerName}' failed: ${formatRuntimeError(error)}`);
217146
+ }
217147
+ },
217148
+ onOutput: ({ fieldName, fieldIndex, checkerName, value, ctx }) => {
217149
+ if (!checkerName) {
217150
+ return;
217151
+ }
217152
+ const pushDiagnostic = (message) => {
217153
+ diagnostics.push({
217154
+ instanceKey: target.instanceKey,
217155
+ nodeId: node.id,
217156
+ nodeName: node.name,
217157
+ fieldKind: "output",
217158
+ fieldName,
217159
+ fieldIndex,
217160
+ checker: checkerName,
217161
+ message
217162
+ });
217163
+ };
217164
+ const checker = params.checkers.get(checkerName);
217165
+ if (!checker) {
217166
+ pushDiagnostic(`checker '${checkerName}' is not registered`);
217167
+ return;
217168
+ }
217169
+ try {
217170
+ const messages = normalizeNodeFieldCheckResult(checker.validate(value, ctx));
217171
+ messages.forEach(pushDiagnostic);
217172
+ } catch (error) {
217173
+ pushDiagnostic(`checker '${checkerName}' failed: ${formatRuntimeError(error)}`);
217174
+ }
216863
217175
  }
216864
- const pushDiagnostic = (message) => {
216865
- diagnostics.push({
216866
- instanceKey: target.instanceKey,
216867
- nodeId: node.id,
216868
- nodeName: node.name,
216869
- argName: arg.name,
216870
- checker: checkerName,
216871
- message
216872
- });
216873
- };
216874
- const checker = params.checkers.get(checkerName);
216875
- if (!checker) {
216876
- pushDiagnostic(`checker '${checkerName}' is not registered`);
216877
- continue;
217176
+ });
217177
+ }
217178
+ return diagnostics;
217179
+ };
217180
+ var resolveNodeFieldVisibility = (params) => {
217181
+ const visibility = createEmptyNodeFieldVisibilityState();
217182
+ const node = params.target;
217183
+ const nodeDef = params.env.nodeDefs.get(node.name);
217184
+ if (!nodeDef) {
217185
+ return visibility;
217186
+ }
217187
+ visitCustomNodeFields({
217188
+ node,
217189
+ tree: params.tree,
217190
+ nodeDef,
217191
+ treePath: params.targetTreePath ?? params.treePath,
217192
+ env: params.env,
217193
+ onArg: ({ fieldName, visibleName, value, ctx }) => {
217194
+ if (!visibleName) {
217195
+ return;
217196
+ }
217197
+ const visible = params.visibles.get(visibleName);
217198
+ if (!visible) {
217199
+ params.env.logger.warn(
217200
+ `visible '${visibleName}' is not registered for ${formatFieldLocator(node, "arg", fieldName)}`
217201
+ );
217202
+ return;
216878
217203
  }
216879
217204
  try {
216880
- const messages = normalizeNodeArgCheckResult(
216881
- checker.validate(node.args?.[arg.name], {
216882
- node,
216883
- tree: params.tree,
216884
- nodeDef,
216885
- arg,
216886
- argName: arg.name,
216887
- treePath: target.treePath ?? params.treePath,
216888
- env: params.env
216889
- })
217205
+ visibility.args[fieldName] = normalizeNodeFieldVisibleResult(
217206
+ visible.visible(value, ctx)
217207
+ );
217208
+ } catch (error) {
217209
+ params.env.logger.warn(
217210
+ `visible '${visibleName}' failed for ${formatFieldLocator(node, "arg", fieldName)}: ${formatRuntimeError(error)}`
217211
+ );
217212
+ visibility.args[fieldName] = true;
217213
+ }
217214
+ },
217215
+ onInput: ({ fieldName, fieldIndex, visibleName, value, ctx }) => {
217216
+ if (!visibleName) {
217217
+ return;
217218
+ }
217219
+ const visible = params.visibles.get(visibleName);
217220
+ if (!visible) {
217221
+ params.env.logger.warn(
217222
+ `visible '${visibleName}' is not registered for ${formatFieldLocator(node, "input", fieldName, fieldIndex)}`
217223
+ );
217224
+ return;
217225
+ }
217226
+ try {
217227
+ visibility.input[fieldIndex] = normalizeNodeFieldVisibleResult(
217228
+ visible.visible(value, ctx)
216890
217229
  );
216891
- messages.forEach(pushDiagnostic);
216892
217230
  } catch (error) {
216893
- pushDiagnostic(`checker '${checkerName}' failed: ${formatRuntimeError(error)}`);
217231
+ params.env.logger.warn(
217232
+ `visible '${visibleName}' failed for ${formatFieldLocator(node, "input", fieldName, fieldIndex)}: ${formatRuntimeError(error)}`
217233
+ );
217234
+ visibility.input[fieldIndex] = true;
217235
+ }
217236
+ },
217237
+ onOutput: ({ fieldName, fieldIndex, visibleName, value, ctx }) => {
217238
+ if (!visibleName) {
217239
+ return;
217240
+ }
217241
+ const visible = params.visibles.get(visibleName);
217242
+ if (!visible) {
217243
+ params.env.logger.warn(
217244
+ `visible '${visibleName}' is not registered for ${formatFieldLocator(node, "output", fieldName, fieldIndex)}`
217245
+ );
217246
+ return;
217247
+ }
217248
+ try {
217249
+ visibility.output[fieldIndex] = normalizeNodeFieldVisibleResult(
217250
+ visible.visible(value, ctx)
217251
+ );
217252
+ } catch (error) {
217253
+ params.env.logger.warn(
217254
+ `visible '${visibleName}' failed for ${formatFieldLocator(node, "output", fieldName, fieldIndex)}: ${formatRuntimeError(error)}`
217255
+ );
217256
+ visibility.output[fieldIndex] = true;
216894
217257
  }
216895
217258
  }
216896
- }
216897
- return diagnostics;
217259
+ });
217260
+ return visibility;
216898
217261
  };
216899
- var formatNodeArgCheckBuildDiagnostic = (diagnostic) => `check ${diagnostic.nodeId}|${diagnostic.nodeName}: ${diagnostic.argName}: ${diagnostic.message}`;
217262
+ var formatNodeFieldCheckBuildDiagnostic = (diagnostic) => diagnostic.fieldKind === "arg" ? `check ${diagnostic.nodeId}|${diagnostic.nodeName}: ${diagnostic.fieldName}: ${diagnostic.message}` : `check ${diagnostic.nodeId}|${diagnostic.nodeName}: ${diagnostic.fieldKind}[${diagnostic.fieldIndex ?? 0}:${diagnostic.fieldName}]: ${diagnostic.message}`;
216900
217263
  var syncFilesFromDiskWithContext = (files, parsedVarDecl, workdir) => {
216901
217264
  if (!hasFs()) {
216902
217265
  return;
@@ -217063,7 +217426,8 @@ var applyBehavior3DecoratorGlobal = () => {
217063
217426
  ...decoratorGlobalState.previousBehavior3 && typeof decoratorGlobalState.previousBehavior3 === "object" ? decoratorGlobalState.previousBehavior3 : {},
217064
217427
  build: markBuildHook,
217065
217428
  batch: markBatchHook,
217066
- check: markCheckHook
217429
+ check: markCheckHook,
217430
+ visible: markVisibleHook
217067
217431
  };
217068
217432
  };
217069
217433
  var restoreBehavior3DecoratorGlobal = () => {
@@ -217373,16 +217737,16 @@ var buildProjectWithContext = async (project, buildDir, context) => {
217373
217737
  if (!context.checkNodeData(tree.root, (message) => errors.push(message))) {
217374
217738
  hasError = true;
217375
217739
  }
217376
- const checkDiagnostics = collectNodeArgCheckDiagnostics({
217740
+ const checkDiagnostics = collectNodeFieldCheckDiagnostics({
217377
217741
  tree,
217378
217742
  treePath: candidatePath,
217379
217743
  env: scriptEnv,
217380
- checkers: buildRuntime.nodeArgCheckers
217744
+ checkers: buildRuntime.nodeFieldCheckers
217381
217745
  });
217382
217746
  if (checkDiagnostics.length) {
217383
217747
  hasError = true;
217384
217748
  checkDiagnostics.forEach(
217385
- (diagnostic) => errors.push(formatNodeArgCheckBuildDiagnostic(diagnostic))
217749
+ (diagnostic) => errors.push(formatNodeFieldCheckBuildDiagnostic(diagnostic))
217386
217750
  );
217387
217751
  }
217388
217752
  if (errors.length) {
@@ -217564,6 +217928,14 @@ var validateExpressionEntries = (entries, usingVars, checkExpr) => {
217564
217928
  return null;
217565
217929
  };
217566
217930
  var getArgLabel = (arg) => arg.desc || arg.name;
217931
+ var findNodeArgOneofInputIndex = (arg, inputDefs) => {
217932
+ if (!arg.oneof || !inputDefs?.length) {
217933
+ return -1;
217934
+ }
217935
+ return inputDefs.findIndex(
217936
+ (input, index) => parseSlotDefinition(input, inputDefs, index).label === arg.oneof
217937
+ );
217938
+ };
217567
217939
  var isRequiredNodeArgValueMissing = (arg, value) => {
217568
217940
  if (isNodeArgOptional(arg)) {
217569
217941
  return false;
@@ -217678,6 +218050,28 @@ var validateNodeArgValue = (params) => {
217678
218050
  }
217679
218051
  return validateNodeArgScalarValue(arg, value, args, validateOptions);
217680
218052
  };
218053
+ var validateNodeArgOneof = (params) => {
218054
+ const { arg, argValue, inputValues, inputDefs } = params;
218055
+ if (!arg.oneof) {
218056
+ return null;
218057
+ }
218058
+ const relatedInputIndex = findNodeArgOneofInputIndex(arg, inputDefs);
218059
+ if (relatedInputIndex < 0) {
218060
+ return {
218061
+ code: "missing-oneof-input",
218062
+ argName: arg.name,
218063
+ inputLabel: arg.oneof
218064
+ };
218065
+ }
218066
+ if (checkOneof(arg, argValue, inputValues?.[relatedInputIndex])) {
218067
+ return null;
218068
+ }
218069
+ return {
218070
+ code: "oneof-conflict",
218071
+ argName: arg.name,
218072
+ inputLabel: arg.oneof
218073
+ };
218074
+ };
217681
218075
 
217682
218076
  // webview/shared/b3build-context.ts
217683
218077
  var unknownNodeDef = {
@@ -217761,6 +218155,10 @@ var formatBuildDiagnostic = (diagnostic) => {
217761
218155
  return `intput field '${diagnostic.label}' is required`;
217762
218156
  case "required-output":
217763
218157
  return `output field '${diagnostic.label}' is required`;
218158
+ case "missing-oneof-input":
218159
+ return `missing oneof input slot '${diagnostic.inputLabel}' for arg '${diagnostic.argName}'`;
218160
+ case "oneof-conflict":
218161
+ return `only one of arg '${diagnostic.argName}' and input '${diagnostic.inputLabel}' can be set`;
217764
218162
  case "invalid-arg-value": {
217765
218163
  const value = JSON.stringify(diagnostic.value);
217766
218164
  switch (diagnostic.expected) {
@@ -217801,14 +218199,15 @@ var checkNodeArg = (data, conf, i, printer) => {
217801
218199
  const diagnostics = validateNodeArgValue({ arg, value, args: data.args ?? {} });
217802
218200
  let hasError = diagnostics.length > 0;
217803
218201
  diagnostics.forEach((diagnostic) => error(formatBuildDiagnostic(diagnostic)));
217804
- if (arg.oneof !== void 0) {
217805
- const idx = conf.input?.findIndex((v) => v.startsWith(arg.oneof)) ?? -1;
217806
- if (!checkOneof(arg, data.args?.[arg.name], data.input?.[idx])) {
217807
- error(
217808
- `only one is allowed for between argument '${arg.name}' and input '${data.input?.[idx]}'`
217809
- );
217810
- hasError = true;
217811
- }
218202
+ const oneofDiagnostic = validateNodeArgOneof({
218203
+ arg,
218204
+ argValue: value,
218205
+ inputValues: data.input,
218206
+ inputDefs: conf.input
218207
+ });
218208
+ if (oneofDiagnostic) {
218209
+ error(formatBuildDiagnostic(oneofDiagnostic));
218210
+ hasError = true;
217812
218211
  }
217813
218212
  return !hasError;
217814
218213
  };
@@ -217880,6 +218279,7 @@ var checkNodeDataWithState = (data, printer, state) => {
217880
218279
  let hasVaridicInput = false;
217881
218280
  if (conf.input) {
217882
218281
  for (let i = 0; i < conf.input.length; i++) {
218282
+ const slotDefinition = parseSlotDefinition(conf.input[i] ?? "", conf.input, i);
217883
218283
  if (!data.input) {
217884
218284
  data.input = [];
217885
218285
  }
@@ -217887,7 +218287,7 @@ var checkNodeDataWithState = (data, printer, state) => {
217887
218287
  data.input[i] = "";
217888
218288
  }
217889
218289
  if (!isValidInputOrOutput(conf.input, data.input, i)) {
217890
- error(`intput field '${conf.input[i]}' is required`);
218290
+ error(`intput field '${slotDefinition.label}' is required`);
217891
218291
  hasError = true;
217892
218292
  }
217893
218293
  if (i === conf.input.length - 1 && isVariadic(conf.input, -1)) {
@@ -217901,6 +218301,7 @@ var checkNodeDataWithState = (data, printer, state) => {
217901
218301
  let hasVaridicOutput = false;
217902
218302
  if (conf.output) {
217903
218303
  for (let i = 0; i < conf.output.length; i++) {
218304
+ const slotDefinition = parseSlotDefinition(conf.output[i] ?? "", conf.output, i);
217904
218305
  if (!data.output) {
217905
218306
  data.output = [];
217906
218307
  }
@@ -217908,7 +218309,7 @@ var checkNodeDataWithState = (data, printer, state) => {
217908
218309
  data.output[i] = "";
217909
218310
  }
217910
218311
  if (!isValidInputOrOutput(conf.output, data.output, i)) {
217911
- error(`output field '${conf.output[i]}' is required`);
218312
+ error(`output field '${slotDefinition.label}' is required`);
217912
218313
  hasError = true;
217913
218314
  }
217914
218315
  if (i === conf.output.length - 1 && isVariadic(conf.output, -1)) {
@@ -220548,6 +220949,37 @@ var computeNodeOverride = (original, edited, def) => {
220548
220949
  }
220549
220950
  return hasDiff ? diff : null;
220550
220951
  };
220952
+ var pruneNodeArgsByDefinition = (args, nodeDef) => {
220953
+ if (!args || !nodeDef) {
220954
+ return args;
220955
+ }
220956
+ const argDefs = nodeDef.args ?? [];
220957
+ if (argDefs.length === 0) {
220958
+ return void 0;
220959
+ }
220960
+ const declaredNames = new Set(argDefs.map((arg) => arg.name));
220961
+ const nextEntries = Object.entries(args).filter(([argName]) => declaredNames.has(argName));
220962
+ if (nextEntries.length === Object.keys(args).length) {
220963
+ return args;
220964
+ }
220965
+ return nextEntries.length > 0 ? Object.fromEntries(nextEntries) : void 0;
220966
+ };
220967
+ var pruneNodeSlotsByDefinition = (slots, slotDefs) => {
220968
+ if (!slots) {
220969
+ return slots;
220970
+ }
220971
+ if (!slotDefs?.length) {
220972
+ return void 0;
220973
+ }
220974
+ const lastIndex = slotDefs.length - 1;
220975
+ const keepVariadicTail = parseSlotDefinition(
220976
+ slotDefs[lastIndex] ?? "",
220977
+ slotDefs,
220978
+ lastIndex
220979
+ ).variadic;
220980
+ const nextSlots = keepVariadicTail ? slots.slice(0) : slots.slice(0, slotDefs.length);
220981
+ return isJsonEqual(nextSlots, slots) ? slots : nextSlots;
220982
+ };
220551
220983
  var matchesSelectedNodeTarget = (selectedNode, payload) => {
220552
220984
  return selectedNode.ref.structuralStableId === payload.target.structuralStableId && selectedNode.ref.sourceStableId === payload.target.sourceStableId && selectedNode.ref.sourceTreePath === payload.target.sourceTreePath;
220553
220985
  };
@@ -220641,9 +221073,9 @@ var reduceUpdateNode = (mutation, context) => {
220641
221073
  }
220642
221074
  const nextDebug = payload.data.debug ? true : void 0;
220643
221075
  const nextDisabled = payload.data.disabled ? true : void 0;
220644
- const nextInput = payload.data.input;
220645
- const nextOutput = payload.data.output;
220646
- const nextArgs = payload.data.args;
221076
+ const nextInput = pruneNodeSlotsByDefinition(payload.data.input, nextNodeDef?.input);
221077
+ const nextOutput = pruneNodeSlotsByDefinition(payload.data.output, nextNodeDef?.output);
221078
+ const nextArgs = pruneNodeArgsByDefinition(payload.data.args, nextNodeDef);
220647
221079
  if (nextName === selectedNode.data.name && nextDesc === selectedNode.data.desc && nextPath === selectedNode.data.path && nextDebug === selectedNode.data.debug && nextDisabled === selectedNode.data.disabled && isJsonEqual(nextInput ?? [], selectedNode.data.input ?? []) && isJsonEqual(nextOutput ?? [], selectedNode.data.output ?? []) && isJsonEqual(nextArgs ?? {}, selectedNode.data.args ?? {})) {
220648
221080
  return { status: "noop" };
220649
221081
  }
@@ -221273,7 +221705,8 @@ function createSessionDispatcher({
221273
221705
  handleSaveDocumentMessage,
221274
221706
  handleRevertDocumentMessage,
221275
221707
  refreshSettings,
221276
- handleValidateNodeChecksMessage,
221708
+ handleValidateNodeFieldsMessage,
221709
+ handleResolveNodeFieldVisibilityMessage,
221277
221710
  fileRequestHandlers
221278
221711
  }) {
221279
221712
  const dispatchEditorMessage = async (msg, reply = postMessage, source = "editor") => {
@@ -221321,8 +221754,11 @@ function createSessionDispatcher({
221321
221754
  case "runInspectorCommand":
221322
221755
  void vscode14.commands.executeCommand(msg.command).then(void 0, logAsyncRuntimeError(`command:${msg.command}`));
221323
221756
  return;
221324
- case "validateNodeChecks":
221325
- await handleValidateNodeChecksMessage(msg, reply);
221757
+ case "validateNodeFields":
221758
+ await handleValidateNodeFieldsMessage(msg, reply);
221759
+ return;
221760
+ case "resolveNodeFieldVisibility":
221761
+ await handleResolveNodeFieldVisibilityMessage(msg, reply);
221326
221762
  return;
221327
221763
  case "webviewLog":
221328
221764
  writeWebviewLogMessage(msg);
@@ -221534,6 +221970,7 @@ async function createSessionNodeCheckRuntime({
221534
221970
  null,
221535
221971
  createSessionBuildScriptEnv(workspaceFolderUri.fsPath, nodeDefs)
221536
221972
  ),
221973
+ nodeFieldVisibleHandlers: /* @__PURE__ */ new Map(),
221537
221974
  treePath: workspaceFolderUri.fsPath
221538
221975
  };
221539
221976
  }
@@ -221570,11 +222007,17 @@ async function createSessionNodeCheckRuntime({
221570
222007
  checkScriptModules,
221571
222008
  env2
221572
222009
  );
222010
+ const visibleRuntime = createNodeFieldVisibleRuntimeWithCheckModules(
222011
+ buildScriptModule,
222012
+ checkScriptModules,
222013
+ env2
222014
+ );
221573
222015
  return {
221574
222016
  buildScriptRuntime: {
221575
222017
  ...buildScriptRuntime,
221576
222018
  hasError: buildScriptRuntime.hasError || hasRuntimeLoadError
221577
222019
  },
222020
+ nodeFieldVisibleHandlers: visibleRuntime.nodeFieldVisibles,
221578
222021
  treePath: workdir
221579
222022
  };
221580
222023
  }
@@ -221591,15 +222034,15 @@ function createSessionNodeChecks(context) {
221591
222034
  readWorkspaceFileContent
221592
222035
  });
221593
222036
  };
221594
- const handleValidateNodeChecksMessage = async (msg, reply = postMessage) => {
222037
+ const handleValidateNodeFieldsMessage = async (msg, reply = postMessage) => {
221595
222038
  try {
221596
222039
  const runtimeResult = await createNodeCheckRuntime();
221597
222040
  const tree = JSON.parse(msg.content);
221598
- const diagnostics = collectNodeArgCheckDiagnostics({
222041
+ const diagnostics = collectNodeFieldCheckDiagnostics({
221599
222042
  tree,
221600
222043
  treePath: msg.treePath || runtimeResult.treePath,
221601
222044
  env: createSessionBuildScriptEnv(runtimeResult.treePath, state.nodeDefs),
221602
- checkers: runtimeResult.buildScriptRuntime.nodeArgCheckers,
222045
+ checkers: runtimeResult.buildScriptRuntime.nodeFieldCheckers,
221603
222046
  targets: msg.nodes.map((entry) => ({
221604
222047
  instanceKey: entry.instanceKey,
221605
222048
  treePath: entry.treePath,
@@ -221607,13 +222050,15 @@ function createSessionNodeChecks(context) {
221607
222050
  }))
221608
222051
  });
221609
222052
  await reply({
221610
- type: "validateNodeChecksResult",
222053
+ type: "validateNodeFieldsResult",
221611
222054
  requestId: msg.requestId,
221612
222055
  diagnostics: diagnostics.filter(
221613
222056
  (diagnostic) => typeof diagnostic.instanceKey === "string"
221614
222057
  ).map((diagnostic) => ({
221615
222058
  instanceKey: diagnostic.instanceKey,
221616
- argName: diagnostic.argName,
222059
+ fieldKind: diagnostic.fieldKind,
222060
+ fieldName: diagnostic.fieldName,
222061
+ fieldIndex: diagnostic.fieldIndex,
221617
222062
  checker: diagnostic.checker,
221618
222063
  message: diagnostic.message
221619
222064
  })),
@@ -221624,15 +222069,42 @@ function createSessionNodeChecks(context) {
221624
222069
  });
221625
222070
  } catch (error) {
221626
222071
  await reply({
221627
- type: "validateNodeChecksResult",
222072
+ type: "validateNodeFieldsResult",
221628
222073
  requestId: msg.requestId,
221629
222074
  diagnostics: [],
221630
222075
  error: String(error)
221631
222076
  });
221632
222077
  }
221633
222078
  };
222079
+ const handleResolveNodeFieldVisibilityMessage = async (msg, reply = postMessage) => {
222080
+ try {
222081
+ const runtimeResult = await createNodeCheckRuntime();
222082
+ const tree = JSON.parse(msg.content);
222083
+ const visibility = resolveNodeFieldVisibility({
222084
+ tree,
222085
+ treePath: msg.treePath || runtimeResult.treePath,
222086
+ env: createSessionBuildScriptEnv(runtimeResult.treePath, state.nodeDefs),
222087
+ visibles: runtimeResult.nodeFieldVisibleHandlers,
222088
+ target: toNodeData(msg.target.node),
222089
+ targetTreePath: msg.target.treePath
222090
+ });
222091
+ await reply({
222092
+ type: "resolveNodeFieldVisibilityResult",
222093
+ requestId: msg.requestId,
222094
+ visibility
222095
+ });
222096
+ } catch (error) {
222097
+ await reply({
222098
+ type: "resolveNodeFieldVisibilityResult",
222099
+ requestId: msg.requestId,
222100
+ visibility: { args: {}, input: {}, output: {} },
222101
+ error: String(error)
222102
+ });
222103
+ }
222104
+ };
221634
222105
  return {
221635
- handleValidateNodeChecksMessage
222106
+ handleValidateNodeFieldsMessage,
222107
+ handleResolveNodeFieldVisibilityMessage
221636
222108
  };
221637
222109
  }
221638
222110
 
@@ -221964,10 +222436,7 @@ async function resolveTreeEditorSession(params) {
221964
222436
  const inspectorSync = createSessionInspectorSync(context);
221965
222437
  const subtreeTracking = createSessionSubtreeTracking(context, inspectorSync);
221966
222438
  const fileVersionGuard = createFileVersionGuard(context);
221967
- const {
221968
- getActiveNewerFileEditMessage,
221969
- getExistingNewerFileEditMessage
221970
- } = fileVersionGuard;
222439
+ const { getActiveNewerFileEditMessage, getExistingNewerFileEditMessage } = fileVersionGuard;
221971
222440
  const { refreshSettings } = createSessionSettingsSync(context, inspectorSync);
221972
222441
  const selectionSync = createSessionSelectionSync(context, inspectorSync);
221973
222442
  const { handleSelectTreeMessage, handleSelectNodeMessage } = selectionSync;
@@ -221983,7 +222452,7 @@ async function resolveTreeEditorSession(params) {
221983
222452
  handleRevertDocumentMessage,
221984
222453
  handleMainDocumentFileChange
221985
222454
  } = createSessionDocumentLifecycle(context, inspectorSync, subtreeTracking, fileVersionGuard);
221986
- const { handleValidateNodeChecksMessage } = createSessionNodeChecks(context);
222455
+ const { handleValidateNodeFieldsMessage, handleResolveNodeFieldVisibilityMessage } = createSessionNodeChecks(context);
221987
222456
  const fileRequestHandlers = createSessionFileRequestHandlers({
221988
222457
  projectRootUri,
221989
222458
  viewType,
@@ -222010,7 +222479,8 @@ async function resolveTreeEditorSession(params) {
222010
222479
  handleSaveDocumentMessage,
222011
222480
  handleRevertDocumentMessage,
222012
222481
  refreshSettings,
222013
- handleValidateNodeChecksMessage,
222482
+ handleValidateNodeFieldsMessage,
222483
+ handleResolveNodeFieldVisibilityMessage,
222014
222484
  fileRequestHandlers
222015
222485
  });
222016
222486
  const activeWebviewEntry = {
@@ -222974,14 +223444,22 @@ var InspectorSidebarCoordinator = class {
222974
223444
  error
222975
223445
  });
222976
223446
  return;
222977
- case "validateNodeChecks":
223447
+ case "validateNodeFields":
222978
223448
  await reply({
222979
- type: "validateNodeChecksResult",
223449
+ type: "validateNodeFieldsResult",
222980
223450
  requestId: message.requestId,
222981
223451
  diagnostics: [],
222982
223452
  error
222983
223453
  });
222984
223454
  return;
223455
+ case "resolveNodeFieldVisibility":
223456
+ await reply({
223457
+ type: "resolveNodeFieldVisibilityResult",
223458
+ requestId: message.requestId,
223459
+ visibility: { args: {}, input: {}, output: {} },
223460
+ error
223461
+ });
223462
+ return;
222985
223463
  case "ready":
222986
223464
  case "undo":
222987
223465
  case "redo":
@@ -223128,19 +223606,19 @@ function createCheckerScriptContent(baseName) {
223128
223606
  const className = ensureSuffix(toPascalIdentifier(baseName), "Checker");
223129
223607
  const checkerName = toCheckerRegistrationName(baseName);
223130
223608
  return [
223131
- 'import type { NodeArgCheckContext } from "vscode-behavior3/build";',
223609
+ 'import type { NodeFieldCheckContext } from "vscode-behavior3/build";',
223132
223610
  "",
223133
223611
  `@behavior3.check("${checkerName}")`,
223134
223612
  `export class ${className} {`,
223135
- " validate(value: unknown, ctx: NodeArgCheckContext) {",
223613
+ " validate(value: unknown, ctx: NodeFieldCheckContext) {",
223136
223614
  ' if (value === undefined || value === null || value === "") {',
223137
223615
  " return;",
223138
223616
  " }",
223139
223617
  ' if (typeof value !== "number") {',
223140
- " return `${ctx.argName} must be a number`;",
223618
+ " return `${ctx.fieldName} must be a number`;",
223141
223619
  " }",
223142
223620
  " if (value <= 0) {",
223143
- " return `${ctx.argName} must be greater than 0`;",
223621
+ " return `${ctx.fieldName} must be greater than 0`;",
223144
223622
  " }",
223145
223623
  " }",
223146
223624
  "}",