flycode-mcp 1.14.6 → 1.14.8

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.js CHANGED
@@ -724,7 +724,7 @@ var init_gateway = __esm({
724
724
  });
725
725
 
726
726
  // src/tools/enum-reference.ts
727
- var COMMON_ENUM, LOGIC_ENUM, PROPERTY_TYPE_ENUM, ENTITY_ENUM, FORM_ENUM, FUNCTION_ENUM;
727
+ var COMMON_ENUM, LOGIC_ENUM, PROPERTY_TYPE_ENUM, ENTITY_ENUM, FORM_ENUM, FORM_ACTION_ENUM, FUNCTION_ENUM;
728
728
  var init_enum_reference = __esm({
729
729
  "src/tools/enum-reference.ts"() {
730
730
  "use strict";
@@ -733,6 +733,7 @@ var init_enum_reference = __esm({
733
733
  PROPERTY_TYPE_ENUM = `properties[].propertytypecode\uFF08\u5B57\u6BB5\u7C7B\u578B\uFF09\uFF1A1-\u4E3B\u952E(int8) / 2-\u540D\u79F0(200) / 3-\u6587\u672C(200) / 4-\u957F\u6587\u672C / 5-\u6574\u6570(int4) / 6-\u957F\u6574\u6570(int8) / 10-\u6570\u5B57(numeric) / 7-\u65E5\u671F\u65F6\u95F4(ts) / 29-\u5E74\u6708\u65E5(date) / 30-\u65F6\u95F4\u8303\u56F4 / 18-\u72B6\u6001(int4) / 16-\u56FE\u7247 / 26-\u9644\u4EF6 / 17-\u5B9A\u4F4D / 19-\u9009\u9879\u96C6 / 8-\u521B\u5EFA\u4EBA / 9-\u4FEE\u6539\u4EBA / 11-\u521B\u5EFA\u65F6\u95F4 / 12-\u4FEE\u6539\u65F6\u95F4 / 31-\u62FC\u97F3 / 100-\u662F\u5426\u9ED8\u8BA4 / 13-\u624B\u673A\u53F7 / 15-\u56FA\u5B9A\u7535\u8BDD / 14-\u90AE\u7BB1 / 27-\u90AE\u7F16 / 20-\u6392\u5E8F / 200000000000-\u5173\u8054\u5BF9\u8C61 / 100000000000-\u4E1A\u52A1\u5BF9\u8C61 / 10000000000-\u5B57\u5178\u5BF9\u8C61 / 300000000000-\u590D\u6742\u5173\u8054\u5BF9\u8C61 / 1000000000-\u672C\u5BF9\u8C61\u3002`;
734
734
  ENTITY_ENUM = `\u3010entity \u679A\u4E3E\u3011datapattern\uFF08\u5B9E\u4F53\u7C7B\u578B\uFF09\uFF1A1-\u539F\u751F / 2-\u884D\u751F / 3-\u89C6\u56FE / 4-\u8D85\u7EA7\u8868\u5355\u3002objecttypecode\uFF08\u5206\u7C7B\uFF09\uFF1A1-\u57FA\u672C / 2-\u6811\u5F62 / 3-\u6570\u636E\u5B57\u5178 / 4-\u5173\u8054\u3002objectcatgory\uFF1A1-\u6743\u9650\u5BF9\u8C61 / 2-\u5426\u3002publishstatus\uFF1A1-\u5DF2\u53D1\u5E03 / 2-\u672A\u53D1\u5E03\u3002hasoffline\uFF1A1-\u6709 / 0-\u65E0\u3002properties[].idxtype\uFF08\u7D22\u5F15\uFF09\uFF1A1-\u65E0 / 2-\u4E3B\u952E\u7D22\u5F15\u3002`;
735
735
  FORM_ENUM = `\u3010form \u679A\u4E3E\u3011type\uFF08\u9875\u9762\u7C7B\u578B\uFF09\uFF1A5-\u5217\u8868\u67E5\u8BE2 / 1-\u666E\u901A\u9875\u9762 / 99-\u4E8C\u5F00 / 10-switchpage / 11-\u6811\u5BFC\u822A\u5217\u8868 / 100-\u539F\u751F / 101-\u7A7A\u767D / 7-\u62A5\u8868 / 12-\u6392\u5E8F / 300-\u6B65\u9AA4\u7BA1\u7406 / 1000-\u5168\u5C40\u51FD\u6570\u3002clientcategorycode\uFF08\u7528\u6237\u7AEF\uFF09\uFF1A1-web / 2-app / 6-\u5C0F\u7A0B\u5E8F\u3002`;
736
+ FORM_ACTION_ENUM = `\u3010action \u7C7B\u578B\u3011flycode / datarequest(\u6570\u636E\u8BF7\u6C42) / datasubmit(\u6570\u636E\u63D0\u4EA4) / dataimport(\u5BFC\u5165\u884C\u4E3A) / dataexport(\u5BFC\u51FA\u884C\u4E3A) / datatransfer(\u6570\u636E\u8F6C\u79FB) / dataserialize(\u6570\u636E\u5E8F\u5217\u5316) / smartrequest(\u667A\u6167\u573A\u666F\u8BF7\u6C42) / link(\u94FE\u63A5) / call(\u4E8B\u4EF6\u547C\u53EB) / return(\u8FD4\u56DE) / af_preaddflow(\u6D41\u7A0B\u53D1\u8D77) / af_handleflow(\u5904\u7406\u5BA1\u6279) / af_flowdetail(\u6D41\u7A0B\u8282\u70B9\u8BE6\u60C5) / ctrlevent(\u8C03\u7528\u63A7\u4EF6\u4E8B\u4EF6) / receivelink(\u63A5\u6536\u53C2\u6570) / eventlink(\u4E8B\u4EF6\u76D1\u542C) / attributeevaluate(\u5C5E\u6027\u8868\u8FBE\u5F0F) / alert(\u63D0\u793A\u5F39\u7A97) / toast(\u8F7B\u63D0\u793A) / share(\u5206\u4EAB\u884C\u4E3A) / popsubview(\u6253\u5F00popview) / closesubview(\u5173\u95EDpopview) / print(\u6253\u5370\u4E8B\u4EF6) / urllink(URL\u94FE\u63A5) / runevent(\u6267\u884C\u4E8B\u4EF6)\u3002\u6CE8\u610F\uFF1Ainitial\uFF08\u9875\u9762\u521D\u59CB\u5316\uFF09\u4EC5\u652F\u6301 flycode / receivelink\uFF0C\u5176\u4F59\u7C7B\u578B\u53EA\u80FD\u52A0\u5230 handlers \u4E8B\u4EF6\uFF1B\u300C\u6570\u636E\u5B57\u5178\u7ED1\u5B9A\u300D\u65E0\u72EC\u7ACB type\uFF0C\u7528 datarequest + fields:{"_type_spe":"dictbind","logiccode":"100000000001100001"}\u3002`;
736
737
  FUNCTION_ENUM = `\u3010function \u679A\u4E3E\u3011dddlayer\uFF08\u51FD\u6570\u5C42\u7EA7\uFF09\uFF1A\u56FA\u5B9A\u4F20 "3"\uFF08\u51FD\u6570\u7C7B\uFF09\u3002\u6570\u636E\u5E93\u51FD\u6570 publishstatus\uFF1A1-\u672A\u53D1\u5E03 / 2-\u5DF2\u53D1\u5E03\u3002`;
737
738
  }
738
739
  });
@@ -3711,6 +3712,51 @@ function findViewNode(root, code) {
3711
3712
  }
3712
3713
  return null;
3713
3714
  }
3715
+ function viewRoots(form) {
3716
+ const roots = [];
3717
+ if (form.view?.body) roots.push(form.view.body);
3718
+ for (const sub of rawSubViews(form) ?? []) {
3719
+ if (sub && typeof sub === "object") roots.push(sub);
3720
+ }
3721
+ return roots;
3722
+ }
3723
+ function rawSubViews(form) {
3724
+ const subs = form.view?.subviews;
3725
+ return Array.isArray(subs) ? subs : null;
3726
+ }
3727
+ function findViewNodeInForm(form, code) {
3728
+ for (const root of viewRoots(form)) {
3729
+ const found = findViewNode(root, code);
3730
+ if (found) return found;
3731
+ }
3732
+ return null;
3733
+ }
3734
+ function viewNodeContainers(form) {
3735
+ const out = [];
3736
+ const walk = (node) => {
3737
+ if (!node) return;
3738
+ if (Array.isArray(node.content)) {
3739
+ out.push(node.content);
3740
+ node.content.forEach(walk);
3741
+ }
3742
+ };
3743
+ for (const root of viewRoots(form)) walk(root);
3744
+ const subs = rawSubViews(form);
3745
+ if (subs) out.push(subs);
3746
+ if (Array.isArray(form.controls)) out.push(form.controls);
3747
+ return out;
3748
+ }
3749
+ function locateViewNode(form, code) {
3750
+ for (const arr of viewNodeContainers(form)) {
3751
+ for (let i = 0; i < arr.length; i++) {
3752
+ const it = arr[i];
3753
+ if (it && typeof it === "object" && it.code === code) {
3754
+ return { node: it, siblings: arr, index: i };
3755
+ }
3756
+ }
3757
+ }
3758
+ return null;
3759
+ }
3714
3760
  function collectAllNodes(form) {
3715
3761
  const out = [];
3716
3762
  const walk = (node) => {
@@ -3718,7 +3764,7 @@ function collectAllNodes(form) {
3718
3764
  out.push(node);
3719
3765
  if (Array.isArray(node.content)) node.content.forEach(walk);
3720
3766
  };
3721
- walk(form.view?.body ?? null);
3767
+ for (const root of viewRoots(form)) walk(root);
3722
3768
  if (Array.isArray(form.controls)) form.controls.forEach((c) => {
3723
3769
  if (c) out.push(c);
3724
3770
  });
@@ -3743,30 +3789,11 @@ function findElementByCodeDeep(node, code) {
3743
3789
  }
3744
3790
  return null;
3745
3791
  }
3746
- function detachViewNode(root, code) {
3747
- if (!root?.content) return null;
3748
- const idx = root.content.findIndex((c) => c?.code === code);
3749
- if (idx >= 0) {
3750
- const [n] = root.content.splice(idx, 1);
3751
- return n ?? null;
3752
- }
3753
- for (const child of root.content) {
3754
- const found = detachViewNode(child, code);
3755
- if (found) return found;
3756
- }
3757
- return null;
3758
- }
3759
3792
  function detachNodeAnywhere(form, code) {
3760
- const fromTree = detachViewNode(form.view?.body ?? null, code);
3761
- if (fromTree) return fromTree;
3762
- if (Array.isArray(form.controls)) {
3763
- const i = form.controls.findIndex((c) => c?.code === code);
3764
- if (i >= 0) {
3765
- const [n] = form.controls.splice(i, 1);
3766
- return n ?? null;
3767
- }
3768
- }
3769
- return null;
3793
+ const loc = locateViewNode(form, code);
3794
+ if (!loc) return null;
3795
+ const [n] = loc.siblings.splice(loc.index, 1);
3796
+ return n ?? null;
3770
3797
  }
3771
3798
  function collectReferencedCodes(form) {
3772
3799
  const set = /* @__PURE__ */ new Set();
@@ -3776,10 +3803,13 @@ function collectReferencedCodes(form) {
3776
3803
  if (Array.isArray(node.content)) node.content.forEach(walk);
3777
3804
  };
3778
3805
  walk(form.view?.body ?? null);
3806
+ for (const root of viewRoots(form)) walk(root);
3779
3807
  for (const h of form.presenter?.handlers ?? []) {
3780
3808
  for (const a of h?.actions ?? []) {
3781
3809
  if (a?.handler) set.add(a.handler);
3782
3810
  if (a?.logiccode) set.add(a.logiccode);
3811
+ const viewcode = a?.viewcode;
3812
+ if (viewcode) set.add(viewcode);
3783
3813
  }
3784
3814
  for (const e of h?.eventlist ?? []) if (e?.handler) set.add(e.handler);
3785
3815
  }
@@ -3787,11 +3817,17 @@ function collectReferencedCodes(form) {
3787
3817
  for (const a of h?.actions ?? []) {
3788
3818
  if (a?.handler) set.add(a.handler);
3789
3819
  if (a?.logiccode) set.add(a.logiccode);
3820
+ const viewcode = a?.viewcode;
3821
+ if (viewcode) set.add(viewcode);
3790
3822
  }
3791
3823
  for (const e of h?.eventlist ?? []) if (e?.handler) set.add(e.handler);
3792
3824
  }
3793
3825
  for (const i of form.presenter?.interface ?? []) {
3794
- for (const a of i?.actions ?? []) if (a?.handler) set.add(a.handler);
3826
+ for (const a of i?.actions ?? []) {
3827
+ if (a?.handler) set.add(a.handler);
3828
+ const viewcode = a?.viewcode;
3829
+ if (viewcode) set.add(viewcode);
3830
+ }
3795
3831
  }
3796
3832
  return set;
3797
3833
  }
@@ -3853,6 +3889,8 @@ async function getFormOutline(code) {
3853
3889
  marktype: form.pageinfo?.marktype ?? null,
3854
3890
  versionnum: form.pageinfo?.versionnum ?? null,
3855
3891
  viewTree: form.view?.body ? [buildViewTree(form.view.body)] : [],
3892
+ // 弹窗单列一段:viewTree 保持「页面主体」的既有语义不变,避免调用方把弹窗当成 body 子节点
3893
+ subviews: (rawSubViews(form) ?? []).filter((s) => Boolean(s) && typeof s === "object").map((s) => buildViewTree(s)),
3856
3894
  handlers,
3857
3895
  interfaces,
3858
3896
  businessModels,
@@ -3868,8 +3906,11 @@ async function getFormFragment(code, opts) {
3868
3906
  let section;
3869
3907
  let fragmentMessage = form.message ?? null;
3870
3908
  if (opts.nodeCode) {
3871
- node = findViewNode(form.view?.body ?? null, opts.nodeCode) ?? form.controls?.find((c) => c?.code === opts.nodeCode) ?? null;
3872
- if (node && opts.itemCode) {
3909
+ node = findViewNodeInForm(form, opts.nodeCode) ?? form.controls?.find((c) => c?.code === opts.nodeCode) ?? null;
3910
+ if (!node) {
3911
+ const subviewCount = rawSubViews(form)?.length ?? 0;
3912
+ fragmentMessage = `\u672A\u627E\u5230 code=${opts.nodeCode} \u7684\u8282\u70B9\uFF08\u5DF2\u68C0\u7D22 view.body \u6811\u3001view.subviews \u5F39\u7A97 ${subviewCount} \u4E2A\u3001controls\uFF09`;
3913
+ } else if (opts.itemCode) {
3873
3914
  const elem = findElementByCodeDeep(node, opts.itemCode);
3874
3915
  if (elem) {
3875
3916
  node = elem;
@@ -3886,10 +3927,13 @@ async function getFormFragment(code, opts) {
3886
3927
  } else if (found.length > 1) {
3887
3928
  handler = null;
3888
3929
  fragmentMessage = `handlerCode=${opts.handlerCode} \u5728 handlers \u4E0E initial \u4E2D\u540C\u65F6\u51FA\u73B0\uFF0C\u8BF7\u7528 handlerScope \u6307\u5B9A\u552F\u4E00\u5BB9\u5668`;
3930
+ } else {
3931
+ handler = null;
3932
+ fragmentMessage = `\u672A\u627E\u5230 handlerCode=${opts.handlerCode} \u7684\u5904\u7406\u5668\uFF08\u5DF2\u68C0\u7D22 handlers \u4E0E initial${opts.handlerScope ? `\uFF0C\u672C\u6B21\u9650\u5B9A ${opts.handlerScope}` : ""}\uFF09`;
3889
3933
  }
3890
3934
  }
3891
3935
  if (opts.section) {
3892
- section = form[opts.section] ?? null;
3936
+ section = opts.section === "subviews" ? rawSubViews(form) ?? null : form[opts.section] ?? null;
3893
3937
  }
3894
3938
  const actionIndex = handler?.actions ? handler.actions.map((a, i) => ({
3895
3939
  index: i,
@@ -3908,7 +3952,57 @@ async function getFormFragment(code, opts) {
3908
3952
  message: fragmentMessage
3909
3953
  };
3910
3954
  }
3911
- async function applyFormOp(form, op, index) {
3955
+ function buildAction(input) {
3956
+ const { type } = input;
3957
+ const base = structuredClone(ACTION_TEMPLATES[type] ?? {});
3958
+ const action = {
3959
+ code: input.code,
3960
+ type,
3961
+ desc: input.desc ?? ACTION_TYPE_LABELS[type],
3962
+ condition: input.condition ?? "",
3963
+ ...base
3964
+ };
3965
+ if (type === "flycode" && input.script != null) action.script = input.script;
3966
+ if (input.fields) Object.assign(action, input.fields);
3967
+ return action;
3968
+ }
3969
+ function nextActionCode(handlerCode, actions) {
3970
+ const suffix = handlerCode.replace(/[^0-9A-Za-z_]/g, "").slice(-8) || "action";
3971
+ const used = new Set(actions.map((a) => a?.code).filter((c) => Boolean(c)));
3972
+ const base = `action_${suffix}`;
3973
+ if (!used.has(base)) return base;
3974
+ let n = 2;
3975
+ while (used.has(`${base}_${n}`)) n++;
3976
+ return `${base}_${n}`;
3977
+ }
3978
+ function locateAction(actions, actionCode, actionIndex) {
3979
+ if (actionCode != null && actionCode !== "") {
3980
+ const found = actions.find((a) => a?.code === actionCode);
3981
+ if (!found) return { error: "NODE_NOT_FOUND", message: `\u672A\u627E\u5230 actionCode=${actionCode}\uFF08\u8BE5 handler \u4E0B\u73B0\u6709 code\uFF1A${actions.map((a) => a?.code ?? "(\u7A7A)").join(", ") || "\u65E0"}\uFF09` };
3982
+ return { action: found };
3983
+ }
3984
+ const ai = actionIndex ?? 0;
3985
+ if (!Number.isInteger(ai) || ai < 0 || ai >= actions.length) {
3986
+ return { error: "NO_TARGET", message: `actionIndex=${ai} \u8D8A\u754C\uFF0C\u8BE5 handler \u5171\u6709 ${actions.length} \u4E2A action` };
3987
+ }
3988
+ const target = actions[ai];
3989
+ if (!target) return { error: "NODE_NOT_FOUND", message: `actionIndex=${ai} \u5904\u4E3A\u7A7A` };
3990
+ return { action: target };
3991
+ }
3992
+ function locateActionForVerify(form2, baseline, op, resolvedCode) {
3993
+ const actions = findPresenterHandlers(form2, op.handlerCode, op.scope)[0]?.handler.actions ?? [];
3994
+ const code = resolvedCode || (op.actionCode != null && op.actionCode !== "" ? op.actionCode : "");
3995
+ if (code) {
3996
+ return actions.find((a) => a?.code === code) ?? void 0;
3997
+ }
3998
+ const idx = op.actionIndex ?? 0;
3999
+ if (baseline) {
4000
+ const baseAct = (findPresenterHandlers(baseline, op.handlerCode, op.scope)[0]?.handler.actions ?? [])[idx];
4001
+ if (baseAct?.code) return actions.find((a) => a?.code === baseAct.code) ?? void 0;
4002
+ }
4003
+ return actions[idx] ?? void 0;
4004
+ }
4005
+ async function applyFormOp(form, op, index, resolvedActionCodes) {
3912
4006
  const ok = (extra = {}) => ({
3913
4007
  index,
3914
4008
  op: op.op,
@@ -4042,6 +4136,32 @@ async function applyFormOp(form, op, index) {
4042
4136
  label: `\u8282\u70B9 ${op.nodeCode}`
4043
4137
  });
4044
4138
  }
4139
+ case "patch_view_array_item": {
4140
+ const view = form.view;
4141
+ if (!view) return fail("NODE_NOT_FOUND", "\u8868\u5355\u6CA1\u6709 view \u7ED3\u6784\uFF0C\u65E0\u6CD5\u64CD\u4F5C view \u7EA7\u6570\u7EC4");
4142
+ if ((op.mode ?? "merge") === "remove" && op.arrayProp === "subviews" && op.elementArrayProp == null && op.checkRefs !== false) {
4143
+ const target = op.itemKeyValue;
4144
+ if (typeof target === "string" && collectReferencedCodes(form).has(target)) {
4145
+ return fail("REF_VIOLATION", `\u4ECD\u6709\u4E8B\u4EF6/action \u7684 viewcode \u6307\u5411\u5F39\u7A97 ${target}\uFF0C\u79FB\u9664\u524D\u8BF7\u5148\u89E3\u9664\u5F15\u7528\uFF08\u6216 checkRefs=false \u5F3A\u5236\u5220\u9664\uFF09`);
4146
+ }
4147
+ }
4148
+ return applyArrayItem({
4149
+ base: view,
4150
+ arrayProp: op.arrayProp,
4151
+ elementArrayProp: op.elementArrayProp,
4152
+ mode: op.mode ?? "merge",
4153
+ itemKey: op.itemKey,
4154
+ itemKeyValue: op.itemKeyValue,
4155
+ elementItemKey: op.elementItemKey,
4156
+ elementItemKeyValue: op.elementItemKeyValue,
4157
+ item: op.item,
4158
+ position: op.position,
4159
+ patch: op.patch,
4160
+ createIfMissing: op.createIfMissing,
4161
+ // label 只给 "view":applyArrayItem 内部会拼 `label.arrayProp`,给成 view.subviews 会重复
4162
+ label: "view"
4163
+ });
4164
+ }
4045
4165
  case "patch_action_array_item": {
4046
4166
  const found = findPresenterHandlers(form, op.handlerCode, op.scope);
4047
4167
  if (found.length === 0) {
@@ -4097,9 +4217,116 @@ async function applyFormOp(form, op, index) {
4097
4217
  label: `action ${op.actionCode ?? op.actionIndex ?? 0}`
4098
4218
  });
4099
4219
  }
4220
+ case "add_action": {
4221
+ const found = findPresenterHandlers(form, op.handlerCode, op.scope);
4222
+ if (found.length === 0) {
4223
+ return fail("NODE_NOT_FOUND", `\u672A\u5728 presenter\uFF08handlers \u4E0E initial\uFF09\u4E2D\u627E\u5230 handlerCode=${op.handlerCode}`);
4224
+ }
4225
+ if (found.length > 1) {
4226
+ return fail("DUP_CODE", `handlerCode=${op.handlerCode} \u5728 handlers \u4E0E initial \u4E2D\u540C\u65F6\u51FA\u73B0\uFF0C\u8BF7\u7528 scope \u6307\u5B9A\u552F\u4E00\u5BB9\u5668`);
4227
+ }
4228
+ const { handler, scope } = found[0];
4229
+ const type = op.type ?? "flycode";
4230
+ if (!FORM_ACTION_TYPES.includes(type)) {
4231
+ return fail("INVALID_PARAMS", `\u672A\u77E5 action type=${String(type)}\uFF0C\u53EF\u9009\u503C\u89C1 FORM_ACTION_TYPES`);
4232
+ }
4233
+ if (scope === "initial" && !INITIAL_ACTION_TYPES.includes(type)) {
4234
+ return fail(
4235
+ "TYPE_NOT_ALLOWED",
4236
+ `\u521D\u59CB\u5316\u4E8B\u4EF6\uFF08initial\uFF09\u4E2D\u7684 action \u4EC5\u652F\u6301 flycode / receivelink\uFF08\u63A5\u6536\u53C2\u6570\uFF09\uFF0C\u4E0D\u652F\u6301 type=${type}\uFF1B\u8BE5\u7C7B\u52A8\u4F5C\u8BF7\u52A0\u5230 handlers \u4E8B\u4EF6\u4E2D`
4237
+ );
4238
+ }
4239
+ if (op.script != null && type !== "flycode") {
4240
+ return fail("INVALID_PARAMS", `script \u4EC5\u9002\u7528\u4E8E type="flycode"\uFF1Btype=${type} \u8BF7\u6539\u7528 fields \u4F20\u8BE5\u7C7B\u578B\u5B57\u6BB5\uFF08\u5982 urllink \u7684 url\u3001toast \u7684 message\uFF09`);
4241
+ }
4242
+ if (op.fields && Object.prototype.hasOwnProperty.call(op.fields, "type")) {
4243
+ return fail("INVALID_PARAMS", "fields \u4E0D\u80FD\u8986\u76D6 type\uFF0C\u8BF7\u7528 type \u53C2\u6570\u6307\u5B9A\u52A8\u4F5C\u7C7B\u578B");
4244
+ }
4245
+ const actions = handler.actions ?? (handler.actions = []);
4246
+ const code = op.code ?? nextActionCode(op.handlerCode, actions);
4247
+ if (!code) return fail("INVALID_PARAMS", "action code \u4E0D\u80FD\u4E3A\u7A7A");
4248
+ if (actions.some((a) => a?.code === code)) {
4249
+ return fail("DUP_CODE", `handler ${op.handlerCode} \u4E2D\u5DF2\u5B58\u5728 code=${code} \u7684 action\uFF0C\u8BF7\u6362\u4E00\u4E2A code`);
4250
+ }
4251
+ const action = buildAction({
4252
+ type,
4253
+ code,
4254
+ desc: op.desc,
4255
+ condition: op.condition,
4256
+ script: op.script,
4257
+ fields: op.fields
4258
+ });
4259
+ const pos = op.position ?? actions.length;
4260
+ actions.splice(pos, 0, action);
4261
+ return ok({
4262
+ message: `\u5DF2\u5728 ${scope} \u7684 handler ${op.handlerCode} \u7684 position=${pos} \u63D2\u5165 action code=${code}\uFF08type=${type}\uFF0Cdesc=${String(action.desc)}\uFF09`
4263
+ });
4264
+ }
4265
+ case "patch_action": {
4266
+ const found = findPresenterHandlers(form, op.handlerCode, op.scope);
4267
+ if (found.length === 0) {
4268
+ return fail("NODE_NOT_FOUND", `\u672A\u5728 presenter\uFF08handlers \u4E0E initial\uFF09\u4E2D\u627E\u5230 handlerCode=${op.handlerCode}`);
4269
+ }
4270
+ if (found.length > 1) {
4271
+ return fail("DUP_CODE", `handlerCode=${op.handlerCode} \u5728 handlers \u4E0E initial \u4E2D\u540C\u65F6\u51FA\u73B0\uFF0C\u8BF7\u7528 scope \u6307\u5B9A\u552F\u4E00\u5BB9\u5668`);
4272
+ }
4273
+ const { handler, scope } = found[0];
4274
+ const actions = handler.actions ?? [];
4275
+ const located = locateAction(actions, op.actionCode, op.actionIndex);
4276
+ if ("error" in located) return fail(located.error, located.message);
4277
+ const act = located.action;
4278
+ const patch = op.patch ?? {};
4279
+ const keys = Object.keys(patch);
4280
+ if (keys.length === 0) return fail("INVALID_PARAMS", "patch \u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u8BF7\u7ED9\u51FA\u8981\u4FEE\u6539\u7684\u5B57\u6BB5");
4281
+ if (keys.includes("type")) {
4282
+ return fail(
4283
+ "INVALID_PARAMS",
4284
+ `patch \u4E0D\u80FD\u8986\u76D6 type\uFF08\u5F53\u524D ${String(act.type)}\uFF09\uFF1Atype \u51B3\u5B9A\u8BE5\u52A8\u4F5C\u7684\u5B57\u6BB5\u9AA8\u67B6\uFF0C\u76F4\u63A5\u6539\u4F1A\u6B8B\u7559\u65E7\u7C7B\u578B\u5B57\u6BB5\uFF1B\u6362\u7C7B\u578B\u8BF7 remove_action + add_action`
4285
+ );
4286
+ }
4287
+ if (keys.includes("code")) {
4288
+ return fail(
4289
+ "INVALID_PARAMS",
4290
+ "patch \u4E0D\u80FD\u8986\u76D6 code\uFF1Aaction code \u662F\u540E\u7EED\u5B9A\u4F4D\uFF08replace_script / patch_action_array_item\uFF09\u4E0E\u56DE\u8BFB\u6821\u9A8C\u7684\u952E\uFF0C\u91CD\u547D\u540D\u8BF7 remove_action + add_action"
4291
+ );
4292
+ }
4293
+ if (keys.includes("script")) {
4294
+ if (act.type !== "flycode") {
4295
+ return fail("INVALID_PARAMS", `script \u4EC5\u9002\u7528\u4E8E type="flycode"\uFF1B\u5F53\u524D action type=${String(act.type)}\uFF0C\u5176\u5B57\u6BB5\u8BF7\u76F4\u63A5\u5199\u8FDB patch`);
4296
+ }
4297
+ if (typeof patch.script !== "string") {
4298
+ return fail("INVALID_PARAMS", "patch.script \u5FC5\u987B\u662F\u5B57\u7B26\u4E32");
4299
+ }
4300
+ }
4301
+ Object.assign(act, patch);
4302
+ resolvedActionCodes?.set(index, act.code == null ? null : String(act.code));
4303
+ return ok({
4304
+ message: `\u5DF2\u66F4\u65B0 ${scope} \u7684 handler ${op.handlerCode} \u4E2D action code=${String(act.code)} \u7684 ${keys.join(", ")}`
4305
+ });
4306
+ }
4307
+ case "remove_action": {
4308
+ const found = findPresenterHandlers(form, op.handlerCode, op.scope);
4309
+ if (found.length === 0) {
4310
+ return fail("NODE_NOT_FOUND", `\u672A\u5728 presenter\uFF08handlers \u4E0E initial\uFF09\u4E2D\u627E\u5230 handlerCode=${op.handlerCode}`);
4311
+ }
4312
+ if (found.length > 1) {
4313
+ return fail("DUP_CODE", `handlerCode=${op.handlerCode} \u5728 handlers \u4E0E initial \u4E2D\u540C\u65F6\u51FA\u73B0\uFF0C\u8BF7\u7528 scope \u6307\u5B9A\u552F\u4E00\u5BB9\u5668`);
4314
+ }
4315
+ const { handler, scope } = found[0];
4316
+ const actions = handler.actions ?? [];
4317
+ const located = locateAction(actions, op.actionCode, op.actionIndex);
4318
+ if ("error" in located) return fail(located.error, located.message);
4319
+ const idx = actions.indexOf(located.action);
4320
+ const removedCode = located.action.code ?? "";
4321
+ actions.splice(idx, 1);
4322
+ resolvedActionCodes?.set(index, removedCode || null);
4323
+ return ok({
4324
+ message: `\u5DF2\u4ECE ${scope} \u7684 handler ${op.handlerCode} \u5220\u9664 action code=${removedCode || `#${idx}`}\uFF08type=${String(located.action.type)}\uFF09\uFF0C\u5269\u4F59 ${actions.length} \u4E2A`
4325
+ });
4326
+ }
4100
4327
  case "insert_node": {
4101
- const parent = findViewNode(form.view?.body ?? null, op.parentCode);
4102
- if (!parent) return fail("NODE_NOT_FOUND", `\u672A\u5728 view \u6811\u4E2D\u627E\u5230 parentCode=${op.parentCode} \u7684\u7236\u8282\u70B9`);
4328
+ const parent = findViewNodeInForm(form, op.parentCode);
4329
+ if (!parent) return fail("NODE_NOT_FOUND", `\u672A\u5728 view \u6811\uFF08\u542B subviews \u5F39\u7A97\uFF09\u4E2D\u627E\u5230 parentCode=${op.parentCode} \u7684\u7236\u8282\u70B9`);
4103
4330
  if (!parent.content) parent.content = [];
4104
4331
  const pos = op.position ?? parent.content.length;
4105
4332
  parent.content.splice(pos, 0, op.node);
@@ -4117,6 +4344,8 @@ async function applyFormOp(form, op, index) {
4117
4344
  }
4118
4345
  const detached = detachNodeAnywhere(form, op.code);
4119
4346
  if (!detached) return fail("NODE_NOT_FOUND", `\u8282\u70B9 ${op.code} \u6458\u9664\u5931\u8D25`);
4347
+ const remainSubs = rawSubViews(form);
4348
+ if (remainSubs && remainSubs.length === 0) delete form.view.subviews;
4120
4349
  return ok({ message: `\u5DF2\u79FB\u9664\u8282\u70B9 ${op.code}` });
4121
4350
  }
4122
4351
  case "move_node": {
@@ -4125,8 +4354,8 @@ async function applyFormOp(form, op, index) {
4125
4354
  if (matches.length > 1) return fail("DUP_CODE", `code=${op.code} \u5728\u8868\u5355\u4E2D\u51FA\u73B0 ${matches.length} \u6B21\uFF0C\u4E0D\u552F\u4E00`);
4126
4355
  const detached = detachNodeAnywhere(form, op.code);
4127
4356
  if (!detached) return fail("NODE_NOT_FOUND", `\u8282\u70B9 ${op.code} \u6458\u9664\u5931\u8D25`);
4128
- const parent = findViewNode(form.view?.body ?? null, op.newParentCode);
4129
- if (!parent) return fail("NODE_NOT_FOUND", `\u672A\u5728 view \u6811\u4E2D\u627E\u5230 newParentCode=${op.newParentCode} \u7684\u7236\u8282\u70B9`);
4357
+ const parent = findViewNodeInForm(form, op.newParentCode);
4358
+ if (!parent) return fail("NODE_NOT_FOUND", `\u672A\u5728 view \u6811\uFF08\u542B subviews \u5F39\u7A97\uFF09\u4E2D\u627E\u5230 newParentCode=${op.newParentCode} \u7684\u7236\u8282\u70B9`);
4130
4359
  if (!parent.content) parent.content = [];
4131
4360
  const pos = op.position ?? parent.content.length;
4132
4361
  parent.content.splice(pos, 0, detached);
@@ -4244,7 +4473,53 @@ function drillToArray(base, arrayProp, elementArrayProp, itemKey, itemKeyValue,
4244
4473
  if (!Array.isArray(nested)) return { error: `${arrayProp}[${itemKey}=${String(itemKeyValue)}].${elementArrayProp} \u975E\u6570\u7EC4` };
4245
4474
  return { finalArr: nested, finalProp: `${arrayProp}[${itemKey}=${String(itemKeyValue)}].${elementArrayProp}` };
4246
4475
  }
4247
- function verifyPatch(form2, ops) {
4476
+ function verifyArrayItemOnBase(base, op, label, i, problems) {
4477
+ const mode = op.mode ?? "merge";
4478
+ const locKey = op.elementArrayProp != null ? op.elementItemKey ?? "code" : op.itemKey ?? "code";
4479
+ const locValue = op.elementArrayProp != null ? op.elementItemKeyValue : op.itemKeyValue;
4480
+ if (mode === "remove") {
4481
+ const outer = base[op.arrayProp];
4482
+ let target = null;
4483
+ if (op.elementArrayProp != null) {
4484
+ if (Array.isArray(outer)) {
4485
+ const outerElem = outer.find((it) => it && typeof it === "object" && it[op.itemKey ?? "code"] === op.itemKeyValue);
4486
+ target = outerElem ? outerElem[op.elementArrayProp] ?? null : null;
4487
+ }
4488
+ } else {
4489
+ target = Array.isArray(outer) ? outer : null;
4490
+ }
4491
+ if (target == null) return;
4492
+ if (target.some((it) => it && typeof it === "object" && it[locKey] === locValue)) {
4493
+ problems.push(`ops[${i}] ${label} remove \u5143\u7D20 ${locKey}=${String(locValue)} \u4ECD\u5B58\u5728`);
4494
+ }
4495
+ return;
4496
+ }
4497
+ const drilled = drillToArray(base, op.arrayProp, op.elementArrayProp, op.itemKey, op.itemKeyValue, op.elementItemKey, op.elementItemKeyValue);
4498
+ if ("error" in drilled) {
4499
+ problems.push(`ops[${i}] ${label} ${drilled.error}`);
4500
+ return;
4501
+ }
4502
+ const arr = drilled.finalArr;
4503
+ if (mode === "append" || mode === "insert") {
4504
+ if (!op.item) {
4505
+ problems.push(`ops[${i}] ${label} ${mode} \u7F3A item`);
4506
+ return;
4507
+ }
4508
+ if (!arrayContains(arr, op.item)) problems.push(`ops[${i}] ${label} ${mode} \u5143\u7D20\u672A\u51FA\u73B0`);
4509
+ return;
4510
+ }
4511
+ const elem = arr.find((it) => it && typeof it === "object" && it[locKey] === locValue);
4512
+ if (!elem) {
4513
+ problems.push(`ops[${i}] ${label} \u5143\u7D20 ${locKey}=${String(locValue)} \u672A\u627E\u5230`);
4514
+ return;
4515
+ }
4516
+ for (const [k, v] of Object.entries(op.patch ?? {})) {
4517
+ if (JSON.stringify(elem[k]) !== JSON.stringify(v)) {
4518
+ problems.push(`ops[${i}] ${label}.${k} \u672A\u751F\u6548`);
4519
+ }
4520
+ }
4521
+ }
4522
+ function verifyPatch(form2, ops, baseline, resolvedActionCodes) {
4248
4523
  const problems = [];
4249
4524
  const nodes = collectAllNodes(form2);
4250
4525
  const codeSet = new Set(nodes.map((n) => n.code).filter((c) => Boolean(c)));
@@ -4277,51 +4552,16 @@ function verifyPatch(form2, ops) {
4277
4552
  problems.push(`ops[${i}] patch_node_array_item \u8282\u70B9 ${op.nodeCode} \u6D88\u5931`);
4278
4553
  break;
4279
4554
  }
4280
- const base = n;
4281
- const mode = op.mode ?? "merge";
4282
- const locKey = op.elementArrayProp != null ? op.elementItemKey ?? "code" : op.itemKey ?? "code";
4283
- const locValue = op.elementArrayProp != null ? op.elementItemKeyValue : op.itemKeyValue;
4284
- if (mode === "remove") {
4285
- const outer = base[op.arrayProp];
4286
- let target = null;
4287
- if (op.elementArrayProp != null) {
4288
- if (Array.isArray(outer)) {
4289
- const outerElem = outer.find((it) => it && typeof it === "object" && it[op.itemKey ?? "code"] === op.itemKeyValue);
4290
- target = outerElem ? outerElem[op.elementArrayProp] ?? null : null;
4291
- }
4292
- } else {
4293
- target = Array.isArray(outer) ? outer : null;
4294
- }
4295
- if (target == null) break;
4296
- if (target.some((it) => it && typeof it === "object" && it[locKey] === locValue)) {
4297
- problems.push(`ops[${i}] patch_node_array_item remove \u5143\u7D20 ${locKey}=${String(locValue)} \u4ECD\u5B58\u5728`);
4298
- }
4299
- break;
4300
- }
4301
- const drilled = drillToArray(base, op.arrayProp, op.elementArrayProp, op.itemKey, op.itemKeyValue, op.elementItemKey, op.elementItemKeyValue);
4302
- if ("error" in drilled) {
4303
- problems.push(`ops[${i}] patch_node_array_item ${drilled.error}`);
4304
- break;
4305
- }
4306
- const arr = drilled.finalArr;
4307
- if (mode === "append" || mode === "insert") {
4308
- if (!op.item) {
4309
- problems.push(`ops[${i}] patch_node_array_item ${mode} \u7F3A item`);
4310
- break;
4311
- }
4312
- if (!arrayContains(arr, op.item)) problems.push(`ops[${i}] patch_node_array_item ${mode} \u5143\u7D20\u672A\u51FA\u73B0`);
4313
- break;
4314
- }
4315
- const elem = arr.find((it) => it && typeof it === "object" && it[locKey] === locValue);
4316
- if (!elem) {
4317
- problems.push(`ops[${i}] patch_node_array_item \u5143\u7D20 ${locKey}=${String(locValue)} \u672A\u627E\u5230`);
4555
+ verifyArrayItemOnBase(n, op, "patch_node_array_item", i, problems);
4556
+ break;
4557
+ }
4558
+ case "patch_view_array_item": {
4559
+ const v = form2.view;
4560
+ if (!v) {
4561
+ problems.push(`ops[${i}] patch_view_array_item \u8868\u5355\u6CA1\u6709 view \u7ED3\u6784`);
4318
4562
  break;
4319
4563
  }
4320
- for (const [k, v] of Object.entries(op.patch ?? {})) {
4321
- if (JSON.stringify(elem[k]) !== JSON.stringify(v)) {
4322
- problems.push(`ops[${i}] patch_node_array_item.${k} \u672A\u751F\u6548`);
4323
- }
4324
- }
4564
+ verifyArrayItemOnBase(v, op, "patch_view_array_item", i, problems);
4325
4565
  break;
4326
4566
  }
4327
4567
  case "patch_action_array_item": {
@@ -4384,6 +4624,87 @@ function verifyPatch(form2, ops) {
4384
4624
  }
4385
4625
  break;
4386
4626
  }
4627
+ case "add_action": {
4628
+ const found = findPresenterHandlers(form2, op.handlerCode, op.scope);
4629
+ if (found.length !== 1) {
4630
+ problems.push(`ops[${i}] add_action handler \u672A\u627E\u5230\u6216\u5B58\u5728\u540C\u540D\u6B67\u4E49`);
4631
+ break;
4632
+ }
4633
+ const actions = found[0].handler.actions ?? [];
4634
+ const type = op.type ?? "flycode";
4635
+ let target;
4636
+ if (op.code) {
4637
+ target = actions.find((a) => a?.code === op.code);
4638
+ } else if (baseline) {
4639
+ const baseHandler = findPresenterHandlers(baseline, op.handlerCode, op.scope)[0]?.handler;
4640
+ const baseCodes = new Set(
4641
+ (baseHandler?.actions ?? []).map((a) => a?.code).filter((c) => Boolean(c))
4642
+ );
4643
+ target = actions.filter((a) => a?.code && !baseCodes.has(a.code)).find((a) => a.type === type);
4644
+ } else {
4645
+ const idx = op.position ?? actions.length - 1;
4646
+ const cand = actions[idx];
4647
+ if (cand && cand.type === type) target = cand;
4648
+ }
4649
+ if (!target) {
4650
+ problems.push(`ops[${i}] add_action \u65B0 action \u672A\u51FA\u73B0\uFF08handler ${op.handlerCode}\uFF09`);
4651
+ break;
4652
+ }
4653
+ if (target.type !== type) {
4654
+ problems.push(`ops[${i}] add_action.type \u672A\u751F\u6548\uFF08\u671F\u671B ${type}\uFF0C\u5B9E\u9645 ${String(target.type)}\uFF09`);
4655
+ }
4656
+ if (type === "flycode" && op.script != null) {
4657
+ if (normalizeText(String(target.script ?? "")) !== normalizeText(op.script)) {
4658
+ problems.push(`ops[${i}] add_action.script \u672A\u751F\u6548`);
4659
+ }
4660
+ }
4661
+ for (const [k, v] of Object.entries(op.fields ?? {})) {
4662
+ if (JSON.stringify(target[k]) !== JSON.stringify(v)) {
4663
+ problems.push(`ops[${i}] add_action.${k} \u672A\u751F\u6548`);
4664
+ }
4665
+ }
4666
+ break;
4667
+ }
4668
+ case "patch_action": {
4669
+ const found = findPresenterHandlers(form2, op.handlerCode, op.scope);
4670
+ if (found.length !== 1) {
4671
+ problems.push(`ops[${i}] patch_action handler \u672A\u627E\u5230\u6216\u5B58\u5728\u540C\u540D\u6B67\u4E49`);
4672
+ break;
4673
+ }
4674
+ const act = locateActionForVerify(form2, baseline, op, resolvedActionCodes?.get(i));
4675
+ if (!act) {
4676
+ problems.push(`ops[${i}] patch_action action \u672A\u627E\u5230\uFF08handler ${op.handlerCode}\uFF09`);
4677
+ break;
4678
+ }
4679
+ const rec = act;
4680
+ for (const [k, v] of Object.entries(op.patch ?? {})) {
4681
+ const same = k === "script" && typeof v === "string" ? normalizeText(String(rec.script ?? "")) === normalizeText(v) : JSON.stringify(rec[k]) === JSON.stringify(v);
4682
+ if (!same) problems.push(`ops[${i}] patch_action.${k} \u672A\u751F\u6548`);
4683
+ }
4684
+ break;
4685
+ }
4686
+ case "remove_action": {
4687
+ const found = findPresenterHandlers(form2, op.handlerCode, op.scope);
4688
+ if (found.length !== 1) {
4689
+ problems.push(`ops[${i}] remove_action handler \u672A\u627E\u5230\u6216\u5B58\u5728\u540C\u540D\u6B67\u4E49`);
4690
+ break;
4691
+ }
4692
+ const actions = found[0].handler.actions ?? [];
4693
+ let code = resolvedActionCodes?.get(i) ?? "";
4694
+ if (!code && op.actionCode != null && op.actionCode !== "") code = op.actionCode;
4695
+ if (!code && baseline) {
4696
+ const baseAct = (findPresenterHandlers(baseline, op.handlerCode, op.scope)[0]?.handler.actions ?? [])[op.actionIndex ?? 0];
4697
+ code = baseAct?.code ?? "";
4698
+ }
4699
+ if (!code) {
4700
+ problems.push(`ops[${i}] remove_action \u65E0\u6CD5\u786E\u5B9A\u88AB\u5220\u9664\u7684 action\uFF08\u672A\u7ED9 actionCode\uFF0C\u843D\u5E93\u524D\u57FA\u7EBF\u5BF9\u5E94\u4E0B\u6807\u4E5F\u6CA1\u6709 code\uFF09`);
4701
+ break;
4702
+ }
4703
+ if (actions.some((a) => a?.code === code)) {
4704
+ problems.push(`ops[${i}] remove_action \u52A8\u4F5C ${code} \u4ECD\u5B58\u5728`);
4705
+ }
4706
+ break;
4707
+ }
4387
4708
  case "insert_node":
4388
4709
  if (!codeSet.has(op.node.code)) problems.push(`ops[${i}] insert_node \u8282\u70B9\u672A\u51FA\u73B0`);
4389
4710
  break;
@@ -4448,6 +4769,28 @@ function verifyPatch(form2, ops) {
4448
4769
  }
4449
4770
  return { verified: problems.length === 0, problems };
4450
4771
  }
4772
+ function normalizeOpScope(ops) {
4773
+ const out = [];
4774
+ for (let i = 0; i < ops.length; i++) {
4775
+ const raw = ops[i];
4776
+ const alias = raw.handlerScope;
4777
+ if (alias !== "handlers" && alias !== "initial") {
4778
+ out.push(ops[i]);
4779
+ continue;
4780
+ }
4781
+ const explicit = raw.scope;
4782
+ if ((explicit === "handlers" || explicit === "initial") && explicit !== alias) {
4783
+ return {
4784
+ ops,
4785
+ error: `ops[${i}]\uFF08op=${String(raw.op)}\uFF09\u540C\u65F6\u7ED9\u4E86 scope="${explicit}" \u4E0E handlerScope="${alias}"\uFF0C\u4E24\u8005\u542B\u4E49\u76F8\u540C\u4F46\u53D6\u503C\u51B2\u7A81\uFF1B\u8BF7\u53EA\u4FDD\u7559\u4E00\u4E2A`
4786
+ };
4787
+ }
4788
+ const next = { ...raw, scope: alias };
4789
+ delete next.handlerScope;
4790
+ out.push(next);
4791
+ }
4792
+ return { ops: out };
4793
+ }
4451
4794
  async function patchForm(code, ops, commitMessage, options = {}) {
4452
4795
  const dryRun = options.dryRun ?? false;
4453
4796
  const verify = options.verify ?? true;
@@ -4463,6 +4806,11 @@ async function patchForm(code, ops, commitMessage, options = {}) {
4463
4806
  if (!Array.isArray(ops) || ops.length === 0) {
4464
4807
  return abort("EMPTY_OPS", "ops \u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5143\u7D20");
4465
4808
  }
4809
+ const scopeNormalized = normalizeOpScope(ops);
4810
+ if (scopeNormalized.error) {
4811
+ return abort("INVALID_PARAMS", scopeNormalized.error);
4812
+ }
4813
+ ops = scopeNormalized.ops;
4466
4814
  let form;
4467
4815
  try {
4468
4816
  const res = await getForm({ code });
@@ -4475,10 +4823,11 @@ async function patchForm(code, ops, commitMessage, options = {}) {
4475
4823
  }
4476
4824
  const work = structuredClone(form);
4477
4825
  const opResults = [];
4826
+ const resolvedActionCodes = /* @__PURE__ */ new Map();
4478
4827
  let failed = false;
4479
4828
  for (let i = 0; i < ops.length; i++) {
4480
4829
  try {
4481
- const r = await applyFormOp(work, ops[i], i);
4830
+ const r = await applyFormOp(work, ops[i], i, resolvedActionCodes);
4482
4831
  opResults.push(r);
4483
4832
  if (r.status === "FAILED") failed = true;
4484
4833
  } catch (e) {
@@ -4545,7 +4894,7 @@ async function patchForm(code, ops, commitMessage, options = {}) {
4545
4894
  verified = false;
4546
4895
  message = `${savedText} | \u56DE\u8BFB\u6821\u9A8C\u5931\u8D25\uFF1A\u91CD\u65B0\u67E5\u8BE2\u4E3A\u7A7A`;
4547
4896
  } else {
4548
- const v = verifyPatch(form2, ops);
4897
+ const v = verifyPatch(form2, ops, form, resolvedActionCodes);
4549
4898
  verified = v.verified;
4550
4899
  if (!v.verified) message = `${savedText} | \u56DE\u8BFB\u6821\u9A8C\u672A\u901A\u8FC7\uFF1A${v.problems.join("\uFF1B")}`;
4551
4900
  }
@@ -4575,7 +4924,7 @@ async function saveForm2(form, commitMessage) {
4575
4924
  return { ok: false, code: form.pageinfo?.code ?? void 0, message: extractError(e) };
4576
4925
  }
4577
4926
  }
4578
- var MAX_DIFF_LINES2;
4927
+ var FORM_ACTION_TYPES, INITIAL_ACTION_TYPES, ACTION_TYPE_LABELS, ACTION_TEMPLATES, MAX_DIFF_LINES2;
4579
4928
  var init_form2 = __esm({
4580
4929
  "src/service/form.ts"() {
4581
4930
  "use strict";
@@ -4585,13 +4934,236 @@ var init_form2 = __esm({
4585
4934
  init_error();
4586
4935
  init_str_replace();
4587
4936
  init_directory2();
4937
+ FORM_ACTION_TYPES = [
4938
+ "flycode",
4939
+ "datarequest",
4940
+ "datasubmit",
4941
+ "dataimport",
4942
+ "dataexport",
4943
+ "datatransfer",
4944
+ "dataserialize",
4945
+ "smartrequest",
4946
+ "link",
4947
+ "call",
4948
+ "return",
4949
+ "af_preaddflow",
4950
+ "af_handleflow",
4951
+ "af_flowdetail",
4952
+ "ctrlevent",
4953
+ "receivelink",
4954
+ "eventlink",
4955
+ "attributeevaluate",
4956
+ "alert",
4957
+ "toast",
4958
+ "share",
4959
+ "popsubview",
4960
+ "closesubview",
4961
+ "print",
4962
+ "urllink",
4963
+ "runevent"
4964
+ ];
4965
+ INITIAL_ACTION_TYPES = ["flycode", "receivelink"];
4966
+ ACTION_TYPE_LABELS = {
4967
+ flycode: "flycode",
4968
+ datarequest: "\u6570\u636E\u8BF7\u6C42",
4969
+ datasubmit: "\u6570\u636E\u63D0\u4EA4",
4970
+ dataimport: "\u5BFC\u5165\u884C\u4E3A",
4971
+ dataexport: "\u5BFC\u51FA\u884C\u4E3A",
4972
+ datatransfer: "\u6570\u636E\u8F6C\u79FB",
4973
+ dataserialize: "\u6570\u636E\u5E8F\u5217\u5316",
4974
+ smartrequest: "\u667A\u6167\u573A\u666F\u8BF7\u6C42",
4975
+ link: "\u94FE\u63A5",
4976
+ call: "\u4E8B\u4EF6\u547C\u53EB",
4977
+ return: "\u8FD4\u56DE",
4978
+ af_preaddflow: "\u6D41\u7A0B\u53D1\u8D77",
4979
+ af_handleflow: "\u5904\u7406\u5BA1\u6279",
4980
+ af_flowdetail: "\u6D41\u7A0B\u8282\u70B9\u8BE6\u60C5",
4981
+ ctrlevent: "\u8C03\u7528\u63A7\u4EF6\u4E8B\u4EF6",
4982
+ receivelink: "\u63A5\u6536\u53C2\u6570",
4983
+ eventlink: "\u4E8B\u4EF6\u76D1\u542C",
4984
+ attributeevaluate: "\u5C5E\u6027\u8868\u8FBE\u5F0F\u884C\u4E3A",
4985
+ alert: "\u63D0\u793A\u5F39\u7A97",
4986
+ toast: "\u8F7B\u63D0\u793A",
4987
+ share: "\u5206\u4EAB\u884C\u4E3A",
4988
+ popsubview: "\u6253\u5F00popview",
4989
+ closesubview: "\u5173\u95EDpopview",
4990
+ print: "\u6253\u5370\u4E8B\u4EF6",
4991
+ urllink: "URL\u94FE\u63A5",
4992
+ runevent: "\u6267\u884C\u4E8B\u4EF6"
4993
+ };
4994
+ ACTION_TEMPLATES = {
4995
+ flycode: { script: "" },
4996
+ datarequest: {
4997
+ logiccode: "",
4998
+ mode: "1",
4999
+ queue: "0",
5000
+ pagesize: "",
5001
+ pagesource: "",
5002
+ hasextraparams: "",
5003
+ sorter: "",
5004
+ getter: [],
5005
+ setter: []
5006
+ },
5007
+ datasubmit: { logiccode: "", queue: "0", mode: "1", getter: [], setter: [] },
5008
+ dataimport: {
5009
+ logiccode: "",
5010
+ mode: "1",
5011
+ servicetype: "background",
5012
+ microclass: "",
5013
+ template: "",
5014
+ templatename: "",
5015
+ extraparam: [{
5016
+ title: "\u5F53\u6570\u636E\u91CD\u590D\u65F6\u5982\u4F55\u5904\u7406",
5017
+ paramkey: "_dataaddmode",
5018
+ requesturl: "",
5019
+ options: [
5020
+ { text: "\u8986\u76D6", key: "1", isselected: "" },
5021
+ { text: "\u8FFD\u52A0", key: "2", isselected: "" },
5022
+ { text: "\u653E\u5F03", key: "3", isselected: "" }
5023
+ ]
5024
+ }],
5025
+ getter: [],
5026
+ setter: [],
5027
+ onsuccess: ""
5028
+ },
5029
+ dataexport: {
5030
+ logiccode: "",
5031
+ servicetype: "",
5032
+ dynamicparmsource: "",
5033
+ microclass: "",
5034
+ colselectable: "",
5035
+ sheetname: "",
5036
+ filename: "",
5037
+ mode: "1",
5038
+ getter: [],
5039
+ setter: [],
5040
+ extraparam: [{ requesturl: "" }],
5041
+ extconfig: {
5042
+ filetype: ["1"],
5043
+ exportcontent: ["excel", "link", "photo"],
5044
+ iscompress: "1",
5045
+ imagetype: "origin",
5046
+ imagesizepercolumn: "5",
5047
+ imageheightcm: "2.0",
5048
+ filewatermark: "0",
5049
+ filewatermarkvalue: "1"
5050
+ },
5051
+ enableattachmentexport: "",
5052
+ attachmentexportsetting: {
5053
+ attachmentfields: [],
5054
+ foldernamefields: [],
5055
+ attachmentnamefields: [],
5056
+ separator: "_"
5057
+ }
5058
+ },
5059
+ datatransfer: { getter: [], setter: [] },
5060
+ dataserialize: { targetname: "", param: { datatype: "0", ctrl: { code: "", scope: "" }, properties: [] } },
5061
+ smartrequest: {
5062
+ agentcode: "",
5063
+ agent_id: "",
5064
+ agent_name: "",
5065
+ agent_version_name: "",
5066
+ agent_version_id: "",
5067
+ queue: "",
5068
+ streaming: "",
5069
+ smartctrl: "",
5070
+ getter: [{ name: "scene_param", datatype: "0", ctrl: { code: "", scope: "" }, properties: [] }],
5071
+ setter: [{ name: "scene_data", datatype: "0", ctrlcode: "", properties: [] }]
5072
+ },
5073
+ link: {
5074
+ title: "",
5075
+ pagecode: "",
5076
+ mode: "popup",
5077
+ closeicon: "1",
5078
+ closewindowicon: "1",
5079
+ onreturn: "",
5080
+ pagesize: { width: "", height: "" },
5081
+ pagesizeWidth: "",
5082
+ pagesizeHeight: "",
5083
+ param: { name: "__linkparam", datatype: "0", ctrl: { code: "", scope: "" }, properties: [] }
5084
+ },
5085
+ call: {
5086
+ pagecode: "",
5087
+ "event-key": "",
5088
+ key: "",
5089
+ isbroadcast: "0",
5090
+ param: { name: "__linkparam", datatype: "0", ctrl: { code: "", scope: "" }, properties: [] }
5091
+ },
5092
+ return: { pagecode: "", pagecount: "" },
5093
+ af_preaddflow: {
5094
+ af_processdefinekey: "",
5095
+ title: "",
5096
+ mode: "popup",
5097
+ pagesizeWidth: "",
5098
+ pagesizeHeight: "",
5099
+ pagesize: { width: "", height: "" },
5100
+ newversion: "1",
5101
+ param: { name: "__linkparam", datatype: "0", ctrl: { code: "", scope: "" }, properties: [] }
5102
+ },
5103
+ af_handleflow: {
5104
+ processinfo: [
5105
+ { name: "af_processdefineid", value: "", ctrl: { code: "", component: "" } },
5106
+ { name: "af_processinstanceid", value: "", ctrl: { code: "", component: "" } },
5107
+ { name: "af_taskid", value: "", ctrl: { code: "", component: "" } },
5108
+ { name: "af_taskkey", value: "", ctrl: { code: "", component: "" } },
5109
+ { name: "af_processinstancename", value: "", ctrl: { code: "", component: "" } }
5110
+ ],
5111
+ newversion: "1",
5112
+ param: { name: "__linkparam", datatype: "0", ctrl: { code: "", scope: "" }, properties: [] }
5113
+ },
5114
+ af_flowdetail: {
5115
+ param: {
5116
+ name: "__linkparam",
5117
+ datatype: "0",
5118
+ ctrl: { code: "", scope: "" },
5119
+ properties: [
5120
+ { name: "af_processinstanceid", value: "", ctrl: { code: "", component: "" } },
5121
+ { name: "af_processdefinekey", value: "", ctrl: { code: "", component: "" } },
5122
+ { name: "af_processinstancename", value: "", ctrl: { code: "", component: "" } }
5123
+ ]
5124
+ }
5125
+ },
5126
+ ctrlevent: { ctrlcode: "", trigger: "" },
5127
+ receivelink: {
5128
+ param: {
5129
+ name: "__linkparam",
5130
+ datatype: "0",
5131
+ ctrlcode: "",
5132
+ properties: [{ name: "__pagestatus", paramtype: "1", ctrl: { code: "", component: "" } }]
5133
+ }
5134
+ },
5135
+ eventlink: {
5136
+ key: "",
5137
+ handler: "",
5138
+ param: {
5139
+ name: "__linkparam",
5140
+ datatype: "0",
5141
+ ctrlcode: "",
5142
+ properties: [{ name: "__pagestatus", paramtype: "1", ctrl: { code: "", component: "" } }]
5143
+ }
5144
+ },
5145
+ attributeevaluate: { ctrlcode: "", attribute: "", expression: "" },
5146
+ alert: {
5147
+ noticestyle: "warning",
5148
+ message: "",
5149
+ buttons: "",
5150
+ choices: [{ title: "\u786E\u5B9A", handler: "" }, { title: "\u53D6\u6D88", handler: "" }]
5151
+ },
5152
+ toast: { message: "", title: "", noticestyle: "info", duration: "3", position: "top" },
5153
+ share: { provider: "", imagewidth: "" },
5154
+ popsubview: { viewcode: "", viewwidth: "", viewheight: "", viewtitle: "", popupmode: "center" },
5155
+ closesubview: {},
5156
+ print: { pagecode: "", ctrlcode: "", printmode: "image", printermodel: "custom", printerinfo: "" },
5157
+ urllink: { url: "", mode: "", targetctrl: "", queryparams: "", bodyparams: "" },
5158
+ runevent: { handler: "" }
5159
+ };
4588
5160
  MAX_DIFF_LINES2 = 150;
4589
5161
  }
4590
5162
  });
4591
5163
 
4592
5164
  // src/tools/form/read.ts
4593
5165
  import { z as z9 } from "zod";
4594
- var formPageResultShape, formResultShape, readTools3;
5166
+ var outlineViewNodeSchema, formPageResultShape, formResultShape, readTools3;
4595
5167
  var init_read3 = __esm({
4596
5168
  "src/tools/form/read.ts"() {
4597
5169
  "use strict";
@@ -4599,6 +5171,17 @@ var init_read3 = __esm({
4599
5171
  init_form();
4600
5172
  init_form2();
4601
5173
  init_result();
5174
+ outlineViewNodeSchema = z9.object({
5175
+ code: z9.union([z9.string(), z9.null()]).optional(),
5176
+ type: z9.union([z9.string(), z9.null()]).optional(),
5177
+ title: z9.union([z9.string(), z9.null()]).optional(),
5178
+ children: z9.array(z9.object({
5179
+ code: z9.union([z9.string(), z9.null()]).optional(),
5180
+ type: z9.union([z9.string(), z9.null()]).optional(),
5181
+ title: z9.union([z9.string(), z9.null()]).optional(),
5182
+ children: z9.array(z9.unknown()).optional()
5183
+ })).optional()
5184
+ });
4602
5185
  formPageResultShape = z9.object({
4603
5186
  createtime: z9.union([z9.string(), z9.null()]).optional().describe("\u521B\u5EFA\u65F6\u95F4"),
4604
5187
  createaccountcode: z9.union([z9.string(), z9.null()]).optional().describe("\u521B\u5EFA\u4EBA\u7684\u8D26\u53F7\u7F16\u7801"),
@@ -4821,7 +5404,7 @@ ${FORM_ENUM}`,
4821
5404
  name: "get_form_outline",
4822
5405
  config: {
4823
5406
  title: "\u67E5\u8BE2\u8868\u5355/\u9875\u9762\u9AA8\u67B6",
4824
- description: `\u83B7\u53D6\u8868\u5355\u8F7B\u91CF\u9AA8\u67B6\uFF08\u7EA6 2\u20134KB\uFF09\uFF1Apageinfo \u5173\u952E\u5B57\u6BB5\u3001view \u6811\u9AA8\u67B6\u3001presenter \u7684 handlers \u4E0E initial \u5904\u7406\u5668\u6E05\u5355\uFF08\u6BCF\u9879\u5E26 scope \u6807\u6CE8\uFF09\u3001businessmodel \u903B\u8F91\u540D\u3002\u7528\u4E8E\u62FF\u5168\u8C8C\u4E0E\u6240\u6709\u53EF\u6539\u5BF9\u8C61 code\uFF0C\u907F\u514D\u76F2\u6539\u3002\u6CE8\u610F\u9875\u9762\u521D\u59CB\u5316\u811A\u672C\u5728 presenter.initial\uFF08scope='initial'\uFF09\u3002
5407
+ description: `\u83B7\u53D6\u8868\u5355\u8F7B\u91CF\u9AA8\u67B6\uFF08\u6570 KB\uFF0C\u968F\u63A7\u4EF6\u6570\u91CF\u589E\u957F\uFF09\uFF1Apageinfo \u5173\u952E\u5B57\u6BB5\u3001view \u6811\u9AA8\u67B6\uFF08body\uFF09\u3001\u5F39\u7A97\u89C6\u56FE\u9AA8\u67B6\uFF08subviews\uFF0C\u5143\u7D20 type=popview\uFF09\u3001presenter \u7684 handlers \u4E0E initial \u5904\u7406\u5668\u6E05\u5355\uFF08\u6BCF\u9879\u5E26 scope \u6807\u6CE8\uFF09\u3001businessmodel \u903B\u8F91\u540D\u3002\u7528\u4E8E\u62FF\u5168\u8C8C\u4E0E\u6240\u6709\u53EF\u6539\u5BF9\u8C61 code\uFF0C\u907F\u514D\u76F2\u6539\u3002\u6CE8\u610F\u9875\u9762\u521D\u59CB\u5316\u811A\u672C\u5728 presenter.initial\uFF08scope='initial'\uFF09\uFF1B\u5F39\u7A97\u53CA\u5176\u5185\u90E8\u63A7\u4EF6\u7684 code \u53EA\u51FA\u73B0\u5728 subviews \u91CC\uFF0C\u4E0D\u5728 viewTree \u4E2D\u3002
4825
5408
 
4826
5409
  ${FORM_ENUM}`,
4827
5410
  inputSchema: {
@@ -4835,17 +5418,8 @@ ${FORM_ENUM}`,
4835
5418
  clientcategorycode: z9.union([z9.string(), z9.null()]).optional().describe("\u7528\u6237\u7AEF\u5206\u7C7B"),
4836
5419
  marktype: z9.union([z9.string(), z9.null()]).optional().describe("\u521B\u5EFA\u6807\u8BB0"),
4837
5420
  versionnum: z9.union([z9.string(), z9.null()]).optional().describe("\u7248\u672C\u53F7"),
4838
- viewTree: z9.array(z9.lazy(() => z9.object({
4839
- code: z9.union([z9.string(), z9.null()]).optional(),
4840
- type: z9.union([z9.string(), z9.null()]).optional(),
4841
- title: z9.union([z9.string(), z9.null()]).optional(),
4842
- children: z9.array(z9.lazy(() => z9.object({
4843
- code: z9.union([z9.string(), z9.null()]).optional(),
4844
- type: z9.union([z9.string(), z9.null()]).optional(),
4845
- title: z9.union([z9.string(), z9.null()]).optional(),
4846
- children: z9.array(z9.unknown()).optional()
4847
- }))).optional()
4848
- }))).optional().describe("view \u6811\u9AA8\u67B6\uFF08\u9012\u5F52\uFF0C\u4EC5 code/type/title + children\uFF09"),
5421
+ viewTree: z9.array(outlineViewNodeSchema).optional().describe("view \u6811\u9AA8\u67B6\uFF08body \u9875\u9762\u4E3B\u4F53\uFF0C\u9012\u5F52\uFF0C\u4EC5 code/type/title + children\uFF09"),
5422
+ subviews: z9.array(outlineViewNodeSchema).optional().describe("\u5F39\u7A97\u89C6\u56FE\u9AA8\u67B6\uFF08view.subviews\uFF0C\u5143\u7D20 type=popview\uFF09\uFF0C\u6BCF\u9879\u4E00\u68F5\u4E0E viewTree \u540C\u6784\u7684\u6811\uFF1B\u5F39\u7A97\u53CA\u5176\u5185\u90E8\u63A7\u4EF6\u7684 code \u53EA\u80FD\u4ECE\u8FD9\u91CC\u62FF\u5230"),
4849
5423
  handlers: z9.array(z9.object({
4850
5424
  code: z9.union([z9.string(), z9.null()]).optional(),
4851
5425
  name: z9.union([z9.string(), z9.null()]).optional(),
@@ -4893,16 +5467,16 @@ ${FORM_ENUM}`,
4893
5467
  name: "get_form_fragment",
4894
5468
  config: {
4895
5469
  title: "\u67E5\u8BE2\u8868\u5355/\u9875\u9762\u5C40\u90E8\u5185\u5BB9",
4896
- description: `\u6309 code \u53D6\u8868\u5355\u5C40\u90E8\u5185\u5BB9\uFF08\u51E0 KB\uFF09\uFF1AnodeCode \u8282\u70B9\u5B50\u6811\uFF08\u53EF\u914D itemCode \u94BB\u53D6\u67D0\u6570\u7EC4\u5143\u7D20\uFF09\u3001handlerCode \u5904\u7406\u5668\u5B9A\u4E49\u4E0E actionIndex \u6E05\u5355\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF09\u3001section \u6574\u6BB5\u3002\u914D\u5408 patch_form \u4F7F\u7528\u3002
5470
+ description: `\u6309 code \u53D6\u8868\u5355\u5C40\u90E8\u5185\u5BB9\uFF08\u51E0 KB\uFF09\uFF1AnodeCode \u8282\u70B9\u5B50\u6811\uFF08\u53EF\u914D itemCode \u94BB\u53D6\u67D0\u6570\u7EC4\u5143\u7D20\uFF1BnodeCode \u4E5F\u652F\u6301 view.subviews \u91CC\u7684\u5F39\u7A97\u53CA\u5176\u5185\u90E8\u63A7\u4EF6\uFF0C\u672A\u547D\u4E2D\u4F1A\u5728 message \u660E\u786E\u8BF4\u660E\uFF09\u3001handlerCode \u5904\u7406\u5668\u5B9A\u4E49\u4E0E actionIndex \u6E05\u5355\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF09\u3001section \u6574\u6BB5\uFF08section='subviews' \u53EA\u53D6\u5F39\u7A97\u6570\u7EC4\uFF09\u3002\u914D\u5408 patch_form \u4F7F\u7528\u3002
4897
5471
 
4898
5472
  ${FORM_ENUM}`,
4899
5473
  inputSchema: {
4900
5474
  code: z9.string().describe("\u8868\u5355/\u9875\u9762\u7684\u552F\u4E00\u7F16\u7801"),
4901
- nodeCode: z9.string().optional().describe("\u76EE\u6807\u63A7\u4EF6/\u8282\u70B9\u7F16\u7801\uFF0C\u8FD4\u56DE\u5176\u5B8C\u6574\u5B50\u6811"),
5475
+ nodeCode: z9.string().optional().describe("\u76EE\u6807\u63A7\u4EF6/\u8282\u70B9\u7F16\u7801\uFF08\u542B view.subviews \u5F39\u7A97\u8282\u70B9\u53CA\u5176\u5185\u90E8\u63A7\u4EF6\uFF09\uFF0C\u8FD4\u56DE\u5176\u5B8C\u6574\u5B50\u6811\uFF1B\u672A\u547D\u4E2D\u65F6 message \u4F1A\u8BF4\u660E\u5DF2\u68C0\u7D22\u7684\u8303\u56F4"),
4902
5476
  itemCode: z9.string().optional().describe("\u5728 nodeCode \u547D\u4E2D\u7684\u8282\u70B9\u5185\u90E8\uFF0C\u6309 code \u6DF1\u5EA6\u4F18\u5148\u94BB\u53D6\u67D0\u4E2A\u6570\u7EC4\u5143\u7D20\uFF08\u5982\u8868\u683C\u7684\u67D0\u4E00\u5217\uFF09\u5E76\u8FD4\u56DE\u8BE5\u5143\u7D20\uFF0C\u800C\u975E\u6574\u68F5\u5B50\u6811\uFF1B\u672A\u627E\u5230\u65F6\u5728 message \u63D0\u793A"),
4903
5477
  handlerCode: z9.string().optional().describe("\u76EE\u6807 presenter \u5904\u7406\u5668\u7F16\u7801\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF09\uFF0C\u8FD4\u56DE\u5176\u5B8C\u6574\u5B9A\u4E49\u4E0E actionIndex \u6E05\u5355"),
4904
5478
  handlerScope: z9.enum(["handlers", "initial"]).optional().describe("\u9650\u5B9A\u5904\u7406\u5668\u5BB9\u5668\uFF1B\u9ED8\u8BA4\u540C\u65F6\u68C0\u7D22 handlers \u4E0E initial\uFF0C\u540C\u540D\u8DE8\u5BB9\u5668\u65F6\u987B\u6307\u5B9A\u4EE5\u6D88\u6B67"),
4905
- section: z9.enum(["pageinfo", "view", "presenter", "controls", "pageswitch", "businessmodel"]).optional().describe("\u8FD4\u56DE\u6574\u6BB5\u5185\u5BB9\uFF08\u4EC5\u6838\u5BF9\u5F15\u7528\u7528\uFF09")
5479
+ section: z9.enum(["pageinfo", "view", "presenter", "controls", "pageswitch", "businessmodel", "subviews"]).optional().describe("\u8FD4\u56DE\u6574\u6BB5\u5185\u5BB9\uFF08\u4EC5\u6838\u5BF9\u5F15\u7528\u7528\uFF09\uFF1Bsubviews=\u53EA\u53D6\u5F39\u7A97\u6570\u7EC4")
4906
5480
  },
4907
5481
  outputSchema: {
4908
5482
  code: z9.string().describe("\u8868\u5355\u7F16\u7801"),
@@ -4929,9 +5503,9 @@ ${FORM_ENUM}`,
4929
5503
  }
4930
5504
  },
4931
5505
  handler: async (args) => {
4932
- const { code, nodeCode, itemCode, handlerCode, section } = args;
5506
+ const { code, nodeCode, itemCode, handlerCode, handlerScope, section } = args;
4933
5507
  try {
4934
- const fragment = await getFormFragment(code, { nodeCode, itemCode, handlerCode, section });
5508
+ const fragment = await getFormFragment(code, { nodeCode, itemCode, handlerCode, handlerScope, section });
4935
5509
  return okResult(fragment);
4936
5510
  } catch (e) {
4937
5511
  return errResult(e);
@@ -4960,13 +5534,13 @@ var init_write3 = __esm({
4960
5534
  }),
4961
5535
  z10.object({
4962
5536
  op: z10.literal("set_attrs"),
4963
- code: z10.string().describe("\u76EE\u6807\u63A7\u4EF6/\u8282\u70B9\u7F16\u7801\uFF08\u6574\u4E2A\u8868\u5355\u552F\u4E00\uFF0C\u4EC5\u9650 view \u6811\u8282\u70B9\u4E0E controls \u6570\u7EC4\uFF1Bpresenter/interface \u7684 action \u7ED3\u6784\u6539\u8BF7\u7528 patch_action_array_item\uFF09"),
5537
+ code: z10.string().describe("\u76EE\u6807\u63A7\u4EF6/\u8282\u70B9\u7F16\u7801\uFF08\u6574\u4E2A\u8868\u5355\u552F\u4E00\uFF0C\u542B view.subviews \u5F39\u7A97\u53CA\u5176\u5185\u90E8\u63A7\u4EF6\uFF1Bpresenter/interface \u7684 action \u7ED3\u6784\u6539\u8BF7\u7528 patch_action_array_item\uFF09"),
4964
5538
  patch: z10.record(z10.string(), z10.unknown()).describe('\u8981\u6539\u7684\u5C5E\u6027\u952E\u503C\uFF0C\u6309 code \u5B9A\u4F4D\u540E\u6D45\u5408\u5E76\uFF0C\u5982 { "hidden": "1" }\u3002\u6CE8\u610F\uFF1A\u82E5 patch \u542B\u6570\u7EC4\u5C5E\u6027\u4F1A**\u6574\u4F53\u8986\u76D6**\u8BE5\u6570\u7EC4\uFF0C\u4E14 set_attrs \u9ED8\u8BA4\u7981\u6B62\u6574\u6BB5\u8986\u76D6\u6570\u7EC4\uFF08\u907F\u514D\u8BEF\u6539\u4E22\u5217/\u4E22\u7ED1\u5B9A\uFF0C\u66FE\u81F4\u6574\u5217\u4E22\u5931\uFF09\uFF0C\u5982\u9700\u6574\u4F53\u66FF\u6362\u8BF7\u663E\u5F0F\u4F20 overwriteArray:true\uFF0C\u5426\u5219\u8BF7\u6539\u7528 patch_node_array_item / patch_action_array_item \u505A\u5143\u7D20\u7EA7\u589E\u6539\u5220'),
4965
5539
  overwriteArray: z10.boolean().optional().describe("patch \u542B\u6570\u7EC4\u5C5E\u6027\u65F6\u662F\u5426\u5141\u8BB8\u6574\u6BB5\u8986\u76D6\uFF0C\u9ED8\u8BA4 false\uFF08\u8986\u76D6\u5373\u963B\u65AD\u5E76\u63D0\u793A\u6539\u7528\u6570\u7EC4\u5143\u7D20\u7EA7 op\uFF09")
4966
5540
  }),
4967
5541
  z10.object({
4968
5542
  op: z10.literal("patch_node_array_item"),
4969
- nodeCode: z10.string().describe("\u7236\u8282\u70B9 code\uFF08\u5982\u8868\u683C\u8282\u70B9 infotable-table-...\uFF09"),
5543
+ nodeCode: z10.string().describe("\u7236\u8282\u70B9 code\uFF08\u5982\u8868\u683C\u8282\u70B9 infotable-table-...\uFF1B\u4E5F\u53EF\u4EE5\u662F view.subviews \u91CC\u7684\u5F39\u7A97 code\uFF0C\u7528\u4E8E\u6539\u5F39\u7A97\u5185\u90E8\u6570\u7EC4\uFF09"),
4970
5544
  arrayProp: z10.string().describe('\u8981\u6539\u7684\u6570\u7EC4\u5C5E\u6027\u540D\uFF0C\u5982 "cols" / "options" / "content"'),
4971
5545
  itemKey: z10.string().optional().describe('\u6570\u7EC4\u5143\u7D20\u5B9A\u4F4D\u952E\u5B57\u6BB5\u540D\uFF0C\u9ED8\u8BA4 "code"\uFF08merge/remove \u6A21\u5F0F\u3001\u4EE5\u53CA\u4E24\u7EA7\u6A21\u5F0F\u5B9A\u4F4D\u5916\u5C42\u5143\u7D20\u65F6\u7528\uFF09'),
4972
5546
  itemKeyValue: z10.unknown().optional().describe("\u8981\u5B9A\u4F4D / \u5220\u9664\u7684\u5143\u7D20\u952E\u503C\uFF08merge/remove \u6A21\u5F0F\u7528\uFF09\uFF0C\u5982 dms_status \u5217\u7684 code=890419529224687617"),
@@ -4979,12 +5553,28 @@ var init_write3 = __esm({
4979
5553
  elementItemKeyValue: z10.unknown().optional().describe("\u4E24\u7EA7\u6A21\u5F0F\u4E0B\u5B9A\u4F4D\u5D4C\u5957\u6570\u7EC4\u5185\u67D0\u5B50\u5143\u7D20\u7684\u952E\u503C\uFF08merge/remove \u6A21\u5F0F\u7528\uFF09"),
4980
5554
  createIfMissing: z10.boolean().optional().describe("append/insert \u65F6\u82E5\u76EE\u6807\u6570\u7EC4\uFF08\u542B\u4E24\u7EA7\u5D4C\u5957\u76EE\u6807\uFF09\u4E0D\u5B58\u5728\uFF0C\u662F\u5426\u5141\u8BB8\u81EA\u52A8\u65B0\u5EFA\uFF0C\u9ED8\u8BA4 false\u2014\u2014\u9ED8\u8BA4 fail-closed \u62A5 ARRAY_NOT_FOUND \u4EE5\u907F\u514D\u8BEF\u9020\u5E73\u884C orphan \u7ED3\u6784\uFF1B\u786E\u9700\u65B0\u5EFA\u624D\u7F6E true")
4981
5555
  }),
5556
+ z10.object({
5557
+ op: z10.literal("patch_view_array_item"),
5558
+ arrayProp: z10.string().describe('view \u5C42\u7EA7\u7684\u6570\u7EC4\u5C5E\u6027\u540D\uFF0C\u5F39\u7A97\u8BF7\u7528 "subviews"\uFF08\u5143\u7D20 type=popview\uFF09'),
5559
+ itemKey: z10.string().optional().describe('\u6570\u7EC4\u5143\u7D20\u5B9A\u4F4D\u952E\u5B57\u6BB5\u540D\uFF0C\u9ED8\u8BA4 "code"\uFF08merge/remove \u6A21\u5F0F\u3001\u4EE5\u53CA\u4E24\u7EA7\u6A21\u5F0F\u5B9A\u4F4D\u5916\u5C42\u5143\u7D20\u65F6\u7528\uFF09'),
5560
+ itemKeyValue: z10.unknown().optional().describe("\u8981\u5B9A\u4F4D / \u5220\u9664\u7684\u5143\u7D20\u952E\u503C\uFF08merge/remove \u6A21\u5F0F\u7528\uFF09\uFF0C\u5982\u5F39\u7A97 code=1501119668772016226"),
5561
+ mode: z10.enum(["merge", "append", "insert", "remove"]).optional().describe("\u64CD\u4F5C\u6A21\u5F0F\uFF1Amerge=\u6D45\u5408\u5E76\u5230\u5DF2\u5B58\u5728\u5143\u7D20(\u9ED8\u8BA4)\uFF1Bappend=\u5728\u6570\u7EC4\u672B\u5C3E\u8FFD\u52A0 item\uFF08\u65B0\u5EFA\u5F39\u7A97\uFF09\uFF1Binsert=\u6309 position \u63D2\u5165 item\uFF1Bremove=\u6309 itemKey \u5220\u9664\u5143\u7D20\uFF08\u5220\u9664\u5F39\u7A97\uFF09"),
5562
+ item: z10.record(z10.string(), z10.unknown()).optional().describe("append/insert \u6A21\u5F0F\u4E0B\u8981\u52A0\u5165\u7684\u65B0\u5143\u7D20\u5BF9\u8C61\uFF08\u65B0\u5EFA\u5F39\u7A97\u65F6\u4F20\u5B8C\u6574 popview \u8282\u70B9\uFF09"),
5563
+ position: z10.number().int().nonnegative().optional().describe("insert \u6A21\u5F0F\u4E0B\u7684\u63D2\u5165\u4E0B\u6807\uFF0C\u9ED8\u8BA4\u672B\u5C3E"),
5564
+ patch: z10.record(z10.string(), z10.unknown()).optional().describe('merge \u6A21\u5F0F\u4E0B\u6D45\u5408\u5E76\u5230\u8BE5\u5143\u7D20\u7684\u5C5E\u6027\uFF0C\u5982 { "title": "\u8D27\u8865", "needconfirm": "0" }'),
5565
+ elementArrayProp: z10.string().optional().describe("\u3010\u4E24\u7EA7\u5D4C\u5957\u3011\u82E5\u76EE\u6807\u5728\u300C\u6570\u7EC4\u5185\u67D0\u5143\u7D20\u7684\u5D4C\u5957\u6570\u7EC4\u300D\u4E2D\uFF0C\u586B\u6B64\u5904\u5B50\u6570\u7EC4\u540D\uFF1B\u9700\u914D\u5408 itemKey/itemKeyValue \u5148\u5B9A\u4F4D\u5916\u5C42\u5143\u7D20"),
5566
+ elementItemKey: z10.string().optional().describe('\u4E24\u7EA7\u6A21\u5F0F\u4E0B\u5B9A\u4F4D\u5D4C\u5957\u6570\u7EC4\u5185\u67D0\u5B50\u5143\u7D20\u7684\u952E\uFF0C\u9ED8\u8BA4 "code"'),
5567
+ elementItemKeyValue: z10.unknown().optional().describe("\u4E24\u7EA7\u6A21\u5F0F\u4E0B\u5B9A\u4F4D\u5D4C\u5957\u6570\u7EC4\u5185\u67D0\u5B50\u5143\u7D20\u7684\u952E\u503C"),
5568
+ createIfMissing: z10.boolean().optional().describe("append/insert \u65F6\u82E5\u76EE\u6807\u6570\u7EC4\uFF08\u542B\u4E24\u7EA7\u5D4C\u5957\u76EE\u6807\uFF09\u4E0D\u5B58\u5728\uFF0C\u662F\u5426\u5141\u8BB8\u81EA\u52A8\u65B0\u5EFA\uFF0C\u9ED8\u8BA4 false\u3002\u8868\u5355\u9996\u6B21\u52A0\u5F39\u7A97\u65F6 view.subviews \u901A\u5E38\u4E0D\u5B58\u5728\uFF0C\u987B\u663E\u5F0F\u7F6E true"),
5569
+ checkRefs: z10.boolean().optional().describe("remove \u5220\u9664\u9876\u5C42\u5F39\u7A97\u65F6\u662F\u5426\u6821\u9A8C\u5F15\u7528\uFF08popsubview/closesubview \u7684 viewcode\uFF09\uFF0C\u9ED8\u8BA4 true\uFF1B\u4ECD\u88AB\u6253\u5F00\u52A8\u4F5C\u6307\u5411\u7684\u5F39\u7A97\u4F1A\u62A5 REF_VIOLATION\uFF0C\u786E\u9700\u5F3A\u5220\u624D\u7F6E false\u3002\u5220\u5F39\u7A97\u5185\u5D4C\u5957\u5143\u7D20\u65F6\u4E0D\u751F\u6548")
5570
+ }),
4982
5571
  z10.object({
4983
5572
  op: z10.literal("patch_action_array_item"),
4984
5573
  handlerCode: z10.string().describe("presenter \u5904\u7406\u5668 code\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF0C\u4E0E replace_script \u540C\uFF09"),
4985
5574
  actionIndex: z10.number().int().nonnegative().optional().describe("\u7B2C\u51E0\u4E2A action\uFF0C\u9ED8\u8BA4 0\uFF1B\u4E0E actionCode \u4E8C\u9009\u4E00"),
4986
5575
  actionCode: z10.string().optional().describe("\u4EE5 action code \u5B9A\u4F4D\uFF08\u4E0E actionIndex \u4E8C\u9009\u4E00\uFF09"),
4987
5576
  scope: z10.enum(["handlers", "initial"]).optional().describe("\u9650\u5B9A\u5904\u7406\u5668\u5BB9\u5668\uFF1B\u9ED8\u8BA4\u540C\u65F6\u68C0\u7D22 handlers \u4E0E initial\uFF0C\u540C\u540D\u8DE8\u5BB9\u5668\u65F6\u987B\u6307\u5B9A\u4EE5\u6D88\u6B67"),
5577
+ handlerScope: z10.enum(["handlers", "initial"]).optional().describe("scope \u7684\u7B49\u4EF7\u522B\u540D\uFF08\u4E0E get_form_fragment \u7684 handlerScope \u540C\u540D\uFF0C\u4E24\u8005\u4EFB\u4F20\u5176\u4E00\u5373\u53EF\uFF1B\u90FD\u4F20\u4E14\u53D6\u503C\u4E0D\u540C\u4F1A\u62A5 INVALID_PARAMS\uFF09"),
4988
5578
  parentProp: z10.string().optional().describe('\u6570\u7EC4\u6240\u5728\u7684\u5BB9\u5668\u5BF9\u8C61\u5C5E\u6027\u540D\uFF0C\u5982 "datarequest"\uFF08setter \u5728\u5176\u4E0B\uFF09\uFF1B\u7701\u7565\u8868\u793A\u6570\u7EC4\u76F4\u63A5\u6302\u5728 action \u4E0A'),
4989
5579
  arrayProp: z10.string().describe('\u8981\u6539\u7684\u6570\u7EC4\u5C5E\u6027\u540D\uFF0C\u5982 "setter"\uFF08datarequest.setter\uFF0C\u754C\u9762\u8F93\u51FA\u7ED1\u5B9A\u5230\u63A7\u4EF6\uFF09/ "properties"\uFF08receivelink \u7684 param.properties\uFF09'),
4990
5580
  mode: z10.enum(["merge", "append", "insert", "remove"]).describe("\u64CD\u4F5C\u6A21\u5F0F\uFF1Amerge=\u6D45\u5408\u5E76\u5230\u5DF2\u5B58\u5728\u5143\u7D20\uFF1Bappend=\u672B\u5C3E\u8FFD\u52A0 item\uFF1Binsert=\u6309 position \u63D2\u5165 item\uFF1Bremove=\u6309 itemKey \u5220\u9664\u5143\u7D20"),
@@ -4998,16 +5588,46 @@ var init_write3 = __esm({
4998
5588
  elementItemKeyValue: z10.unknown().optional().describe("\u4E24\u7EA7\u6A21\u5F0F\u4E0B\u5B9A\u4F4D\u5D4C\u5957\u6570\u7EC4\u5185\u67D0\u5B50\u5143\u7D20\u7684\u952E\u503C\uFF08merge/remove \u6A21\u5F0F\u7528\uFF09"),
4999
5589
  createIfMissing: z10.boolean().optional().describe("append/insert \u65F6\u82E5\u76EE\u6807\u5BB9\u5668/\u6570\u7EC4\uFF08\u542B\u4E24\u7EA7\u5D4C\u5957\u76EE\u6807\uFF09\u4E0D\u5B58\u5728\uFF0C\u662F\u5426\u5141\u8BB8\u81EA\u52A8\u65B0\u5EFA\uFF0C\u9ED8\u8BA4 false\u2014\u2014\u9ED8\u8BA4 fail-closed \u62A5 ARRAY_NOT_FOUND \u4EE5\u907F\u514D\u628A datarequest.setter \u8BEF\u5EFA\u5230\u9519\u8BEF\u5C42\u7EA7\uFF1B\u786E\u9700\u65B0\u5EFA\u624D\u7F6E true")
5000
5590
  }),
5591
+ z10.object({
5592
+ op: z10.literal("add_action"),
5593
+ handlerCode: z10.string().describe("presenter \u5904\u7406\u5668 code\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF09"),
5594
+ scope: z10.enum(["handlers", "initial"]).optional().describe("\u9650\u5B9A\u5904\u7406\u5668\u5BB9\u5668\uFF1B\u9ED8\u8BA4\u540C\u65F6\u68C0\u7D22 handlers \u4E0E initial\uFF0C\u540C\u540D\u8DE8\u5BB9\u5668\u65F6\u987B\u6307\u5B9A\u4EE5\u6D88\u6B67"),
5595
+ handlerScope: z10.enum(["handlers", "initial"]).optional().describe("scope \u7684\u7B49\u4EF7\u522B\u540D\uFF08\u4E0E get_form_fragment \u7684 handlerScope \u540C\u540D\uFF0C\u4E24\u8005\u4EFB\u4F20\u5176\u4E00\u5373\u53EF\uFF1B\u90FD\u4F20\u4E14\u53D6\u503C\u4E0D\u540C\u4F1A\u62A5 INVALID_PARAMS\uFF09"),
5596
+ type: z10.enum(FORM_ACTION_TYPES).optional().describe("\u52A8\u4F5C\u7C7B\u578B\uFF0C\u9ED8\u8BA4 flycode\u3002initial\uFF08\u9875\u9762\u521D\u59CB\u5316\uFF09\u4EC5\u5141\u8BB8 flycode / receivelink\uFF1B\u5176\u4F59\u7C7B\u578B\u53EA\u80FD\u52A0\u5230 handlers \u4E8B\u4EF6\u91CC"),
5597
+ code: z10.string().optional().describe("\u52A8\u4F5C code\uFF0C\u9ED8\u8BA4 action_<handlerCode \u672B8\u4F4D>\uFF08\u540C handler \u5185\u91CD\u590D\u65F6\u81EA\u52A8\u8FFD\u52A0 _2/_3\uFF09\uFF1B\u540C\u4E00 handler \u5185\u5FC5\u987B\u552F\u4E00"),
5598
+ desc: z10.string().optional().describe("\u52A8\u4F5C\u663E\u793A\u540D\uFF0C\u9ED8\u8BA4\u53D6\u8BE5 type \u7684\u5E73\u53F0\u9ED8\u8BA4\u540D\uFF08\u5982 \u6570\u636E\u8BF7\u6C42 / \u8F7B\u63D0\u793A / \u63A5\u6536\u53C2\u6570\uFF09"),
5599
+ condition: z10.string().optional().describe("\u6267\u884C\u6761\u4EF6\uFF08flycode \u8868\u8FBE\u5F0F\uFF09\uFF0C\u9ED8\u8BA4\u7A7A\u4E32"),
5600
+ position: z10.number().int().nonnegative().optional().describe("\u63D2\u5165\u4F4D\u7F6E\u4E0B\u6807\uFF0C\u9ED8\u8BA4\u672B\u5C3E\u3002\u4E8B\u4EF6\u5185 action \u6309\u6570\u7EC4\u987A\u5E8F\u4E32\u884C\u6267\u884C"),
5601
+ script: z10.string().optional().describe('\u4EC5 type="flycode"\uFF1A\u811A\u672C\u5168\u6587\uFF1B\u5176\u5B83\u7C7B\u578B\u8BF7\u7528 fields'),
5602
+ fields: z10.record(z10.string(), z10.unknown()).optional().describe('\u5728\u7C7B\u578B\u6A21\u677F\u4E0A\u6D45\u5408\u5E76\u7684\u5B57\u6BB5\uFF0C\u5982 toast \u7684 { "message": "\u4FDD\u5B58\u6210\u529F" }\u3001urllink \u7684 { "url": "https://..." }\uFF1B\u4E0D\u80FD\u8986\u76D6 type')
5603
+ }),
5604
+ z10.object({
5605
+ op: z10.literal("patch_action"),
5606
+ handlerCode: z10.string().describe("presenter \u5904\u7406\u5668 code\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF09"),
5607
+ actionCode: z10.string().optional().describe("\u8981\u6539\u7684 action code\uFF08\u4E0E actionIndex \u4E8C\u9009\u4E00\uFF0C\u4F18\u5148\uFF09\uFF1B\u6279\u91CF\u5220\u6539\u540E\u4E0B\u6807\u4F1A\u6F02\u79FB\uFF0C\u5EFA\u8BAE\u59CB\u7EC8\u7528 actionCode"),
5608
+ actionIndex: z10.number().int().nonnegative().optional().describe("\u8981\u6539\u7684 action \u4E0B\u6807\uFF0C\u9ED8\u8BA4 0\uFF1B\u4EC5\u5728\u65E0\u6CD5\u786E\u5B9A code \u65F6\u4F7F\u7528"),
5609
+ scope: z10.enum(["handlers", "initial"]).optional().describe("\u9650\u5B9A\u5904\u7406\u5668\u5BB9\u5668\uFF1B\u9ED8\u8BA4\u540C\u65F6\u68C0\u7D22 handlers \u4E0E initial\uFF0C\u540C\u540D\u8DE8\u5BB9\u5668\u65F6\u987B\u6307\u5B9A\u4EE5\u6D88\u6B67"),
5610
+ handlerScope: z10.enum(["handlers", "initial"]).optional().describe("scope \u7684\u7B49\u4EF7\u522B\u540D\uFF08\u4E0E get_form_fragment \u7684 handlerScope \u540C\u540D\uFF0C\u4E24\u8005\u4EFB\u4F20\u5176\u4E00\u5373\u53EF\uFF1B\u90FD\u4F20\u4E14\u53D6\u503C\u4E0D\u540C\u4F1A\u62A5 INVALID_PARAMS\uFF09"),
5611
+ patch: z10.record(z10.string(), z10.unknown()).describe('\u6D45\u5408\u5E76\u5230 action \u9876\u5C42\u7684\u5B57\u6BB5\uFF0C\u5982 { desc: "\u56FA\u5B9A\u5E95\u90E8" }\u3001{ message: "\u4FDD\u5B58\u6210\u529F" }\u3001{ logiccode: "L1", queue: "1" }\u3001{ condition: "a==1" }\u3002\u4E0D\u80FD\u542B type / code\uFF08\u6362\u7C7B\u578B\u6216\u6539\u540D\u8BF7 remove_action + add_action\uFF09\uFF1Bscript \u4EC5 type="flycode" \u53EF\u5199')
5612
+ }),
5613
+ z10.object({
5614
+ op: z10.literal("remove_action"),
5615
+ handlerCode: z10.string().describe("presenter \u5904\u7406\u5668 code\uFF08handlers \u4E0E initial \u5747\u68C0\u7D22\uFF09"),
5616
+ actionCode: z10.string().optional().describe("\u8981\u5220\u9664\u7684 action code\uFF08\u4E0E actionIndex \u4E8C\u9009\u4E00\uFF0C\u4F18\u5148\uFF09\uFF1B\u7F3A\u7701\u4E14\u53EA\u7ED9\u4E0B\u6807\u65F6\uFF0C\u56DE\u8BFB\u6821\u9A8C\u4F1A\u7528\u843D\u5E93\u524D\u57FA\u7EBF\u6309\u4E0B\u6807\u89E3\u6790 code"),
5617
+ actionIndex: z10.number().int().nonnegative().optional().describe("\u8981\u5220\u9664\u7684 action \u4E0B\u6807\uFF0C\u9ED8\u8BA4 0\uFF1B\u4EC5\u5728\u65E0\u6CD5\u786E\u5B9A code \u65F6\u4F7F\u7528"),
5618
+ scope: z10.enum(["handlers", "initial"]).optional().describe("\u9650\u5B9A\u5904\u7406\u5668\u5BB9\u5668\uFF1B\u9ED8\u8BA4\u540C\u65F6\u68C0\u7D22 handlers \u4E0E initial\uFF0C\u540C\u540D\u8DE8\u5BB9\u5668\u65F6\u987B\u6307\u5B9A\u4EE5\u6D88\u6B67"),
5619
+ handlerScope: z10.enum(["handlers", "initial"]).optional().describe("scope \u7684\u7B49\u4EF7\u522B\u540D\uFF08\u4E0E get_form_fragment \u7684 handlerScope \u540C\u540D\uFF0C\u4E24\u8005\u4EFB\u4F20\u5176\u4E00\u5373\u53EF\uFF1B\u90FD\u4F20\u4E14\u53D6\u503C\u4E0D\u540C\u4F1A\u62A5 INVALID_PARAMS\uFF09")
5620
+ }),
5001
5621
  z10.object({
5002
5622
  op: z10.literal("insert_node"),
5003
- parentCode: z10.string().describe("\u7236\u8282\u70B9 code\uFF08view \u6811\u4E2D\uFF09"),
5623
+ parentCode: z10.string().describe("\u7236\u8282\u70B9 code\uFF08view \u6811\uFF0C\u542B subviews \u5F39\u7A97\u8282\u70B9\uFF1B\u4F20\u5F39\u7A97 code \u5373\u5F80\u5F39\u7A97\u5185\u52A0\u63A7\u4EF6\uFF09"),
5004
5624
  position: z10.number().int().nonnegative().optional().describe("\u63D2\u5165\u4F4D\u7F6E\u4E0B\u6807\uFF0C\u9ED8\u8BA4\u672B\u5C3E"),
5005
5625
  node: z10.record(z10.string(), z10.unknown()).describe("\u65B0\u8282\u70B9\u5BF9\u8C61\uFF08\u542B type/code/title/content \u7B49\uFF09\uFF0C\u540C view \u6811\u8282\u70B9\u7ED3\u6784")
5006
5626
  }),
5007
5627
  z10.object({
5008
5628
  op: z10.literal("remove_node"),
5009
- code: z10.string().describe("\u8981\u5220\u9664\u7684\u8282\u70B9 code"),
5010
- checkRefs: z10.boolean().optional().describe("\u524D\u7F6E\u5F15\u7528\u6821\u9A8C\uFF0C\u9ED8\u8BA4 true\uFF1B\u5B58\u5728\u4E8B\u4EF6/handler \u5F15\u7528\u65F6\u62D2\u7EDD\u5220\u9664\uFF0C\u7F6E false \u8DF3\u8FC7\u6821\u9A8C")
5629
+ code: z10.string().describe("\u8981\u5220\u9664\u7684\u8282\u70B9 code\uFF08\u5F39\u7A97\u6839\u8282\u70B9\u4E5F\u53EF\uFF1A\u5B83\u5728 view.subviews \u91CC\uFF09"),
5630
+ checkRefs: z10.boolean().optional().describe("\u524D\u7F6E\u5F15\u7528\u6821\u9A8C\uFF0C\u9ED8\u8BA4 true\uFF1B\u5B58\u5728\u4E8B\u4EF6/handler \u5F15\u7528\uFF08\u542B popsubview/closesubview \u7684 viewcode \u6307\u5411\u8BE5\u5F39\u7A97\uFF09\u65F6\u62D2\u7EDD\u5220\u9664\uFF0C\u7F6E false \u8DF3\u8FC7\u6821\u9A8C")
5011
5631
  }),
5012
5632
  z10.object({
5013
5633
  op: z10.literal("move_node"),
@@ -5027,6 +5647,7 @@ var init_write3 = __esm({
5027
5647
  actionCode: z10.string().optional().describe("\u4EE5 action code \u5B9A\u4F4D\uFF08\u4E0E actionIndex \u4E8C\u9009\u4E00\uFF09"),
5028
5648
  field: z10.enum(["script", "condition", "expression"]).optional().describe("\u76EE\u6807\u5B57\u7B26\u4E32\u5B57\u6BB5\uFF0C\u9ED8\u8BA4 script"),
5029
5649
  scope: z10.enum(["handlers", "initial"]).optional().describe("\u9650\u5B9A\u5904\u7406\u5668\u5BB9\u5668\uFF1B\u9ED8\u8BA4\u540C\u65F6\u68C0\u7D22 handlers \u4E0E initial\uFF0C\u540C\u540D\u8DE8\u5BB9\u5668\u65F6\u987B\u6307\u5B9A\u4EE5\u6D88\u6B67"),
5650
+ handlerScope: z10.enum(["handlers", "initial"]).optional().describe("scope \u7684\u7B49\u4EF7\u522B\u540D\uFF08\u4E0E get_form_fragment \u7684 handlerScope \u540C\u540D\uFF0C\u4E24\u8005\u4EFB\u4F20\u5176\u4E00\u5373\u53EF\uFF1B\u90FD\u4F20\u4E14\u53D6\u503C\u4E0D\u540C\u4F1A\u62A5 INVALID_PARAMS\uFF09"),
5030
5651
  replacement: z10.string().optional().describe("\u6574\u6BB5\u66FF\u6362\u6A21\u5F0F\uFF1A\u76F4\u63A5\u7ED9\u76EE\u6807\u5B57\u6BB5\u7684\u65B0\u5168\u6587\uFF0C\u4F18\u5148\u7EA7\u9AD8\u4E8E ops\uFF08\u9002\u5408\u6574\u6BB5\u91CD\u5199 action\uFF09"),
5031
5652
  ops: z10.array(z10.object({
5032
5653
  oldString: z10.string().describe("\u5F85\u66FF\u6362\u7684\u539F\u6587\u7247\u6BB5\uFF0C\u5FC5\u987B\u975E\u7A7A\u4E14\u552F\u4E00\u547D\u4E2D\uFF1B\u8BF7\u4ECE\u67E5\u8BE2\u5230\u7684\u811A\u672C\u539F\u6587\u539F\u6837\u590D\u5236\uFF08\u542B\u7F29\u8FDB\u4E0E\u6362\u884C\uFF09"),
@@ -5053,10 +5674,19 @@ var init_write3 = __esm({
5053
5674
  name: "patch_form",
5054
5675
  config: {
5055
5676
  title: "\u5C40\u90E8\u8865\u4E01\u4FEE\u6539\u8868\u5355/\u9875\u9762",
5056
- description: `\u4EE5 delta ops \u5C40\u90E8\u4FEE\u6539\u8868\u5355\uFF0C\u65E0\u9700\u56DE\u4F20\u5B8C\u6574 JSON\u300211 \u7C7B ops\uFF1Aset_pageinfo/set_attrs/patch_node_array_item/insert_node/remove_node/move_node/set_section/replace_script/add_businessmodel/remove_businessmodel/patch_action_array_item\u3002\u63A8\u8350\u6D41\u7A0B\uFF1Aget_form_outline \u62FF code \u2192 get_form_fragment \u786E\u8BA4\u771F\u5B9E\u5C5E\u6027\u540D/\u811A\u672C \u2192 patch_form\u3002ops \u4E8B\u52A1\u6027\u9884\u6F14\uFF0C\u5931\u8D25\u6574\u6279\u56DE\u6EDA\uFF1B\u6539\u521D\u59CB\u5316\u811A\u672C\uFF08presenter.initial\uFF09\u4E0E\u6539\u6309\u94AE\u4E8B\u4EF6\u7528\u6CD5\u4E00\u81F4\u3002
5677
+ description: `\u4EE5 delta ops \u5C40\u90E8\u4FEE\u6539\u8868\u5355\uFF0C\u65E0\u9700\u56DE\u4F20\u5B8C\u6574 JSON\u300215 \u7C7B ops\uFF1Aset_pageinfo/set_attrs/patch_node_array_item/patch_view_array_item/patch_action_array_item/add_action/patch_action/remove_action/insert_node/remove_node/move_node/set_section/replace_script/add_businessmodel/remove_businessmodel\u3002\u63A8\u8350\u6D41\u7A0B\uFF1Aget_form_outline \u62FF code \u2192 get_form_fragment \u786E\u8BA4\u771F\u5B9E\u5C5E\u6027\u540D/\u811A\u672C \u2192 patch_form\u3002ops \u4E8B\u52A1\u6027\u9884\u6F14\uFF0C\u5931\u8D25\u6574\u6279\u56DE\u6EDA\uFF1B\u6539\u521D\u59CB\u5316\u811A\u672C\uFF08presenter.initial\uFF09\u4E0E\u6539\u6309\u94AE\u4E8B\u4EF6\u7528\u6CD5\u4E00\u81F4\u3002
5678
+
5679
+ **\u5F39\u7A97\uFF08popview\uFF09**\uFF1A\u5E73\u53F0\u7684\u5F39\u7A97\u6302\u5728 view.subviews\uFF08\u4E0E view.body \u5E73\u7EA7\u7684\u6570\u7EC4\uFF0C\u5143\u7D20 type=popview\uFF09\uFF0C\u5F39\u7A97\u5185\u63A7\u4EF6\u5728\u5F39\u7A97\u8282\u70B9\u7684 content \u4E0B\u3002view \u6811\u904D\u5386\u5DF2\u8986\u76D6 subviews\uFF0C\u56E0\u6B64\uFF1A\u6539\u5F39\u7A97\u5C5E\u6027\u6216\u5728\u5F39\u7A97\u5185\u52A0/\u5220\u63A7\u4EF6\uFF0C\u76F4\u63A5\u7528 set_attrs / insert_node\uFF08parentCode=\u5F39\u7A97 code\uFF09/ remove_node / move_node / patch_node_array_item\uFF08\u542B\u5F39\u7A97\u5185\u90E8\u8282\u70B9\u7684 eventlist\uFF09\uFF1B\u800C\u300C\u5F39\u7A97\u6839\u8282\u70B9\u81EA\u8EAB\u5728 subviews \u6570\u7EC4\u91CC\u3001\u6CA1\u6709\u7236\u8282\u70B9\u300D\u7684\u589E\u5220\u6539\uFF0C\u7528 patch_view_array_item\uFF08base=view\uFF09\uFF1Aappend \u65B0\u5EFA\u5F39\u7A97\uFF08\u8868\u5355\u9996\u6B21\u52A0\u5F39\u7A97\u987B createIfMissing:true\uFF09\u3001merge \u6539 title/needconfirm \u7B49\u3001remove \u5220\u9664\u5F39\u7A97\u3002\u5220\u5F39\u7A97\u4E24\u6761\u8DEF\u7B49\u4EF7\uFF1Aremove_node{code=\u5F39\u7A97code} \u6216 patch_view_array_item{arrayProp:"subviews",mode:"remove",itemKeyValue:\u5F39\u7A97code}\uFF0C\u4E24\u8005\u90FD\u9ED8\u8BA4\u6821\u9A8C popsubview/closesubview \u7684 viewcode \u5F15\u7528\uFF08\u62A5 REF_VIOLATION\uFF09\uFF0C\u786E\u9700\u5F3A\u5220\u4F20 checkRefs:false\uFF1B\u5220\u6389\u6700\u540E\u4E00\u4E2A\u5F39\u7A97\u540E subviews \u5C5E\u6027\u4F1A\u88AB\u6E05\u6389\uFF0C\u4E0D\u7559\u7A7A\u6570\u7EC4\u3002\u6253\u5F00\u5F39\u7A97\u4ECD\u7528 add_action type="popsubview"\uFF08fields:{viewcode,viewwidth,viewheight,popupmode}\uFF09\u3002\u7EA2\u7EBF\uFF1A\u5F39\u7A97\u5185\u63A7\u4EF6 code \u5E38\u88AB datarequest.setter \u5F15\u7528\uFF0C\u52FF\u6539 code\u3001\u52FF\u5220\u4ECD\u88AB\u5F15\u7528\u7684\u8282\u70B9\u3002
5057
5680
 
5058
5681
  \u6570\u7EC4\u5143\u7D20\u7EA7\u6539\u52A8\uFF1Apatch_node_array_item \u652F\u6301 merge(\u9ED8\u8BA4)/append/insert/remove \u56DB\u79CD\u6A21\u5F0F\uFF0C\u4F5C\u7528\u4E8E view \u6811\u8282\u70B9\u7684 cols/options/content \u7B49\uFF1Bpatch_action_array_item \u7528\u4E8E presenter.handlers/initial \u4E2D\u67D0 action \u5185\u90E8\u6570\u7EC4\uFF08\u5982 datarequest.setter\u300C\u754C\u9762\u8F93\u51FA\u7ED1\u5B9A\u5230\u63A7\u4EF6\u300D\u3001param.properties\uFF09\uFF0C\u540C\u6837\u652F\u6301\u56DB\u79CD\u6A21\u5F0F\u3002\u4E24\u8005\u90FD\u652F\u6301\u300C\u4E24\u7EA7\u5D4C\u5957\u300D\uFF08elementArrayProp\uFF09\uFF1A\u5F53\u771F\u5B9E\u7ED1\u5B9A\u5728\u300C\u6570\u7EC4\u5185\u67D0\u5143\u7D20\u7684\u5D4C\u5957\u6570\u7EC4\u300D\uFF08\u5982 datarequest.setter[0].properties \u6A21\u578B\u7EA7\u5C5E\u6027\u6620\u5C04\uFF09\u65F6\uFF0C\u7528 itemKey/itemKeyValue \u5148\u5B9A\u4F4D\u5916\u5C42\u5143\u7D20\u3001\u518D\u586B elementArrayProp \u94BB\u5230\u5D4C\u5957\u6570\u7EC4\u64CD\u4F5C\uFF0C\u65E0\u9700\u56DE\u4F20\u6574\u6BB5\u6570\u7EC4\u3002append/insert \u76EE\u6807\u6570\u7EC4\u4E0D\u5B58\u5728\u65F6\u9ED8\u8BA4 fail-closed \u62A5 ARRAY_NOT_FOUND\uFF08\u987B\u663E\u5F0F createIfMissing:true \u624D\u65B0\u5EFA\uFF09\uFF0C\u907F\u514D\u8BEF\u9020\u5E73\u884C orphan \u7ED3\u6784\uFF1Bremove \u6E05\u7A7A\u8C03\u5219\u5220\u9664\u8BE5\u6570\u7EC4\u5C5E\u6027\u907F\u514D\u7A7A\u58F3\u3002set_attrs \u9ED8\u8BA4\u7981\u6B62\u6574\u6BB5\u8986\u76D6\u6570\u7EC4\uFF08\u542B\u6570\u7EC4\u5C5E\u6027\u987B\u663E\u5F0F overwriteArray:true\uFF0C\u5426\u5219\u6539\u7528\u4E0A\u8FF0\u4E24 op\uFF09\u3002
5059
5682
 
5683
+ **\u52A0\u4E00\u4E2A\u65B0\u52A8\u4F5C**\uFF08\u6B64\u524D\u53EA\u80FD\u6574\u6BB5 set_section \u6216\u5168\u91CF save_form\uFF09\uFF1A\u7528 add_action \u5F80\u67D0 handler \u7684 actions \u8FFD\u52A0\u4E00\u6761\uFF0C\u6309 type \u81EA\u52A8\u8865\u5E73\u53F0\u7A7A\u9AA8\u67B6\uFF0C\u53EA\u9700\u4F20\u5173\u952E\u5B57\u6BB5\u3002\u4F8B\uFF1A\u7ED9\u521D\u59CB\u5316\u4E8B\u4EF6\u8FFD\u52A0\u811A\u672C {handlerCode, script:"..."}\uFF1B\u7ED9\u4E8B\u4EF6\u52A0\u8F7B\u63D0\u793A {handlerCode, type:"toast", fields:{message:"\u4FDD\u5B58\u6210\u529F"}}\u3002initial \u4EC5\u652F\u6301 flycode / receivelink\u3002
5684
+
5685
+ **\u6539/\u5220\u5DF2\u6709\u52A8\u4F5C**\uFF1Apatch_action \u6D45\u5408\u5E76\u4EFB\u610F\u5B57\u6BB5\uFF08desc / condition / message / url / logiccode / queue \u7B49\uFF0Cscript \u4EC5 flycode\uFF09\uFF0C\u4E0D\u80FD\u6539 type \u4E0E code\uFF1B\u6362\u7C7B\u578B\u6216\u6539\u540D\u7528 remove_action + add_action\u3002replace_script \u53EA\u7BA1 script/condition/expression \u4E09\u4E2A\u5B57\u7B26\u4E32\u5B57\u6BB5\u7684\u6587\u672C\u66FF\u6362\uFF0C\u6539\u5176\u5B83\u5B57\u6BB5\u7528 patch_action\u3002\u5220\u9664\u540E\u4FDD\u7559 actions: []\u3002\u5B9A\u4F4D\u4E00\u5F8B\u7528 actionCode\uFF08\u4E0B\u6807\u4F1A\u968F\u540C\u6279\u6B21\u589E\u5220\u6F02\u79FB\uFF09\u3002
5686
+
5687
+ **\u5BB9\u5668\u6D88\u6B67\u53C2\u6570**\uFF1A\u9700\u8981\u9650\u5B9A handlers / initial \u7684 op\uFF08patch_action_array_item / replace_script / add_action / patch_action / remove_action\uFF09\u540C\u65F6\u63A5\u53D7 scope \u4E0E handlerScope\uFF0C\u4E24\u8005\u7B49\u4EF7\uFF08\u8BFB\u5DE5\u5177 get_form_fragment \u7528\u7684\u662F handlerScope\uFF09\uFF1B\u90FD\u4F20\u4E14\u53D6\u503C\u4E0D\u540C\u4F1A\u62A5 INVALID_PARAMS\u3002
5688
+
5689
+ ${FORM_ACTION_ENUM}
5060
5690
  ${FORM_ENUM}`,
5061
5691
  inputSchema: {
5062
5692
  code: z10.string().describe("\u76EE\u6807\u8868\u5355/\u9875\u9762\u7684\u552F\u4E00\u7F16\u7801"),
@@ -5070,7 +5700,7 @@ ${FORM_ENUM}`,
5070
5700
  ok: z10.boolean().describe("\u6574\u4F53\u662F\u5426\u6210\u529F\uFF08dryRun \u6210\u529F\u4E5F\u4E3A true\uFF0C\u4F46 applied=false\uFF09"),
5071
5701
  applied: z10.boolean().describe("\u662F\u5426\u5DF2\u843D\u5E93\uFF1BdryRun \u6216\u4EFB\u4E00 op \u9884\u6F14\u5931\u8D25\u65F6\u4E3A false"),
5072
5702
  verified: z10.boolean().nullable().describe("\u4FDD\u5B58\u540E\u56DE\u8BFB\u6821\u9A8C\u7ED3\u679C\uFF1Atrue \u5168\u90E8\u751F\u6548\u3001false \u5B58\u5728\u5F02\u5E38\u3001null \u672A\u843D\u5E93\u6216\u672A\u5F00\u542F\u6821\u9A8C"),
5073
- errorCode: z10.string().describe("\u9519\u8BEF\u7801\uFF1AOK / DRY_RUN / EMPTY_OPS / FETCH_FAILED / NODE_NOT_FOUND / DUP_CODE / REF_VIOLATION / OPS_FAILED / SAVE_FAILED / VERIFY_FAILED / ARRAY_OVERWRITE_BLOCKED / ARRAY_NOT_FOUND / NO_TARGET / INVALID_PARAMS"),
5703
+ errorCode: z10.string().describe("\u9519\u8BEF\u7801\uFF1AOK / DRY_RUN / EMPTY_OPS / FETCH_FAILED / NODE_NOT_FOUND / DUP_CODE / REF_VIOLATION / OPS_FAILED / SAVE_FAILED / VERIFY_FAILED / ARRAY_OVERWRITE_BLOCKED / ARRAY_NOT_FOUND / TYPE_NOT_ALLOWED / NO_TARGET / INVALID_PARAMS"),
5074
5704
  message: z10.string().describe("\u7ED3\u679C\u8BF4\u660E\uFF1B\u5931\u8D25\u65F6\u7ED9\u51FA\u53EF\u76F4\u63A5\u6267\u884C\u7684\u5904\u7406\u5EFA\u8BAE"),
5075
5705
  diff: z10.string().describe("\u5168\u90E8 op \u7684 diff \u7247\u6BB5\uFF0C\u8D85\u957F\u4F1A\u622A\u65AD\uFF1B\u53EA\u56DE\u6539\u52A8\u6458\u8981\uFF0C\u4E0D\u56DE\u6574\u4EFD\u8868\u5355"),
5076
5706
  ops: z10.array(z10.object({