flycode-mcp 1.14.5 → 1.14.7

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.
@@ -74,7 +74,7 @@ Python / Node(或 curl / psql / 其他语言)直接打 APaaS 平台 HTTP 接
74
74
  | **form** | `get_form` | 只读 | 查表单完整详情(88KB 级,含 `view` 控件树 / `presenter` 事件 / `businessmodel`) |
75
75
  | **form** | `get_form_outline` | 只读 | 表单轻量骨架(2–4KB):节点树 + handlers/interfaces 清单 + 逻辑名 |
76
76
  | **form** | `get_form_fragment` | 只读 | 表单局部内容(按 `nodeCode`/`handlerCode`/`section` 取几 KB) |
77
- | **form** | `patch_form` | 写 | 局部改表单(11 类 ops:控件属性/数组项增删/action 内数组绑定/插删移节点/改脚本/增删 businessmodel) |
77
+ | **form** | `patch_form` | 写 | 局部改表单(14 类 ops:控件属性/数组项增删/action 增删改/action 内数组绑定/插删移节点/改脚本/增删 businessmodel) |
78
78
  | **form** | `save_form` | 写 | 整页重构时才用:回传完整 `FormResult` 全量保存 |
79
79
  | **h5** | `page_h5_form` | 只读 | 分页搜 H5 表单(智慧100 引擎) |
80
80
  | **h5** | `get_h5_form` | 只读 | 查 H5 表单详情(核心 `confjson` 含 Vue 代码) |
@@ -169,7 +169,7 @@ flycode-mcp 默认开启 `PROGRESSIVE_DISCLOSURE=on`:连接后客户端只看
169
169
  | 加/删 input 或 output 参数、加/改字段属性 | `patch_model_logic` |
170
170
  | 改逻辑标题/描述/`actiontype` 等顶层元数据 | `patch_model_logic`(`set_meta`) |
171
171
  | 改导出类(`actioncategory=5`)的导出列 | `patch_model_logic`(5 类导出 op,**勿用 `set_meta` 碰 `bindjson`**) |
172
- | 给表单加/删/移控件、改控件属性、改 UI 脚本、改 action 内数组绑定 | `patch_form`(11 类 ops) |
172
+ | 给表单加/删/移控件、改控件属性、改 UI 脚本、增删改 action、改 action 内数组绑定 | `patch_form`(14 类 ops) |
173
173
  | 整页重构表单布局 | `save_form`(回传完整 `FormResult`) |
174
174
  | **新建**一条业务逻辑(首次创建) | `save_model_logic`(配 `generate_unique_code` 生成 `modellogiccode`) |
175
175
  | 已有逻辑全量 JSON 很小(如微服务) | `save_model_logic` 全量保存 |
@@ -203,11 +203,13 @@ flycode-mcp 默认开启 `PROGRESSIVE_DISCLOSURE=on`:连接后客户端只看
203
203
 
204
204
  | 改的内容 | 选 |
205
205
  | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
206
- | 局部:改控件属性、数组内单元素(列 `options`/样式)、插/删/移节点、改某 action 脚本、增删 businessmodel、**把界面输出绑定到控件(改 `datarequest.setter`)** | **`patch_form`**(11 类 ops;view 树数组用 `patch_node_array_item`(merge/append/insert/remove),handler action 内数组用 `patch_action_array_item`,避免 `set_attrs` 整段覆盖大数组) |
206
+ | 局部:改控件属性、数组内单元素(列 `options`/样式)、插/删/移节点、改某 action 脚本、**增删改 action 本身**、增删 businessmodel、**把界面输出绑定到控件(改 `datarequest.setter`)** | **`patch_form`**(14 类 ops;view 树数组用 `patch_node_array_item`,handler action 内数组用 `patch_action_array_item`,action 本身增删改用 `add_action`/`patch_action`/`remove_action`,避免 `set_attrs` 整段覆盖大数组) |
207
207
  | 整页重构(重排布局、模板迁移) | **`save_form`**(回传完整 `FormResult`) |
208
208
 
209
209
  > 数组元素级改动一律用 `patch_node_array_item`(view 树节点数组,如单列 `options`/`cols`,支持 merge/append/insert/remove)或 `patch_action_array_item`(presenter.handlers/initial 的 action 内数组,如 `datarequest.setter` 绑定输出到控件、`param.properties`,支持四种模式)。**`set_attrs` 默认禁止整段覆盖数组**(`patch` 含数组属性会直接阻断并要求显式 `overwriteArray:true`),因其大 payload 曾触发调用方 stringify bug 致 36 列丢失;且 `set_attrs` 只覆盖 view 树节点/controls,够不到 action 结构。
210
210
 
211
+ > **action 本身的增删改**不走上面两个数组 op(`patch_action_array_item` 只管 action **内部**的数组):新增用 `add_action`(按 `type` 自动补平台空骨架,`initial` 仅允许 `flycode`/`receivelink`),改字段用 `patch_action`(浅合并任意字段,但**不能改 `type`/`code`**),删除用 `remove_action`(删空保留 `actions: []`)。定位一律用 `actionCode`,`actionIndex` 会随同批次增删漂移。详见 `tools/form.md`。
212
+
211
213
  > **常见陷阱:界面输出绑定的两种真实落点必须先用 `get_form_fragment` 核对**。① 字段级绑定在 `datarequest.setter` **顶层**(如部分表单的 `pack5_barcode`/`status`,`setter` 直接是 `[{name, ctrl:{code}}]`);② 模型级属性映射在 `datarequest.setter[*].properties` **嵌套数组**(如 `kx_kq_product` 的 67 条 `properties`)。patch 前应 `get_form_fragment({handlerCode})` 看清到底是哪一层:**若落点在嵌套数组,用 `patch_action_array_item` + `itemKey`/`itemKeyValue` 定位外层元素(如 `name="kx_kq_product"`)+ `elementArrayProp:"properties"` 钻进去**,单个 op 即可写一条新绑定,无需内联整段 setter。误把嵌套数组当成顶层 `append` 会被 `ARRAY_NOT_FOUND` 阻断(默认 fail-closed,防误造平行 orphan `datarequest.setter`),不会污染表单。
212
214
 
213
215
  ### 4.3 实体层:create_entity vs patch_entity
@@ -249,7 +251,8 @@ flycode-mcp 默认开启 `PROGRESSIVE_DISCLOSURE=on`:连接后客户端只看
249
251
  - **校验口径(2026-09-22 修正)**:`verify:false` / `VERIFY_FAILED` **视为真实未生效信号**(旧版「换行假阴性」已由 MCP 修复)。`applied:true`+`verified:false` 且报「新内容未出现」时,用 `get_form_fragment`/`get_model_logic` 实际回读确认,不要凭错误码重复提交;确需字节严格校验给 op 设 `matchMode:'exact'`。
250
252
  - **导出列专用 ops**:`patch_model_logic` 改导出列(`actioncategory=5`)用 5 类导出 op;**切勿用 `set_meta` 碰 `bindjson`**(会整体覆盖顶层字段、丢失导出列定义),改用 `set_bind_meta`。
251
253
  - **空串不是定位键**:自定义字段 `propertycode`/`objectcode` 恒为 `""`,传 `""` 安全且推荐(不会误判重复);但 `remove_property`/`replace_property` 只传空串 `propertyCode` 而无 `propertyName` 会报 `INVALID_PARAMS`。
252
- - **表单 `initial` vs `handlers`**:页面初始类事件(如「页面初始-参数接收」)在 `presenter.initial[]`,**不在 `handlers[]`**;`patch_form` 的 `replace_script` 会在两块容器都检索,`handlerCode` 同名跨容器须加 `handlerScope` 消歧;`get_form_outline` 会一并列出并标 `scope='initial'`。
254
+ - **表单 `initial` vs `handlers`**:页面初始类事件(如「页面初始-参数接收」)在 `presenter.initial[]`,**不在 `handlers[]`**;`patch_form` 的 `replace_script` / `add_action` / `patch_action` / `remove_action` / `patch_action_array_item` 都会在两块容器检索,`handlerCode` 同名跨容器须消歧 —— 参数名是 **`scope`**(`handlers`/`initial`),**也接受等价别名 `handlerScope`**(与 `get_form_fragment` 同名,任传其一;都传且取值不同报 `INVALID_PARAMS`);`get_form_outline` 会一并列出并标 `scope='initial'`。
255
+ - **动作(action)增删改的三条硬约束**:① **类型按容器分域**——`initial`(页面初始化)只允许 `flycode`/`receivelink`,其余 24 种只能加到 `handlers`,越界报 `TYPE_NOT_ALLOWED`;② **定位一律用 `actionCode`**,不用 `actionIndex`(同批次前序 op 增删会让下标漂移,回读校验会打到邻居身上);③ `patch_action` 的 `patch` **不能含 `type`/`code`**(`type` 是字段骨架锚点、`code` 是定位键),换类型或改名一律 `remove_action` + `add_action`。另:数据提交是 `datasubmit`(不是 `datacommit`);「数据字典绑定」不是独立 type,是 `datarequest` 的 `_type_spe:"dictbind"` 变体。
253
256
  - **新建逻辑用官方 ID(且勿带 prefix)**:`modellogiccode`/`modellogicstepcode` 必须调 `generate_unique_code` 获取,**调用时不要传 `prefix`**(返回纯 18 位纯数字 ID),不要自写脚本按 epoch 算(官方现 18 位、旧「19 位」约定已过期,硬编码会落到平台雪花方案外)。带字母前缀的 `code` 会被后端 `saveModelLogic` 判 `modellogiccode不能为空` 拒绝。新建逻辑顶层对象**不要带** `metamodelcode`/`confsource`。
254
257
  - **`run_sql` 只读**:仅 SELECT、一次一条;不支持 INSERT/UPDATE/DELETE。
255
258
  - **数据字典文本**:实体字典字段存 `dickey`(bigint,全局唯一),翻译一律 `LEFT JOIN pl_dictionary d ON d.dickey=k.<col>`,不必拼 `dictionarycode`;字典编码 >2^53 用字符串常量。
@@ -163,19 +163,19 @@
163
163
 
164
164
  ## `patch_form` — 局部补丁修改表单(写)
165
165
 
166
- 以 delta ops 局部修改表单,无需回传完整 JSON。**11 类 ops**,事务性预演,失败整批回滚。改初始化脚本(presenter.initial)与改按钮事件用法一致。
166
+ 以 delta ops 局部修改表单,无需回传完整 JSON。**14 类 ops**,事务性预演,失败整批回滚。改初始化脚本(presenter.initial)与改按钮事件用法一致。
167
167
 
168
168
  ### 输入
169
169
 
170
170
  | 参数 | 类型 | 必填 | 说明 |
171
171
  | --- | --- | --- | --- |
172
172
  | `code` | string | 是 | 目标表单/页面唯一编码 |
173
- | `ops` | array | 是 | 补丁操作数组,至少 1 个;按顺序依次作用于上一步结果。11 类 op 见下 |
173
+ | `ops` | array | 是 | 补丁操作数组,至少 1 个;按顺序依次作用于上一步结果。14 类 op 见下 |
174
174
  | `commitMessage` | object | 是 | 提交信息,整批 ops 共用一个 |
175
175
  | `dryRun` | boolean | 否 | 只预演并输出 diff、不落库,**默认 false** |
176
176
  | `verify` | boolean | 否 | 保存后回读校验,**默认 true** |
177
177
 
178
- ### 11 类 op 一览
178
+ ### 14 类 op 一览
179
179
 
180
180
  | op | 定位 | 关键字段 | 说明 |
181
181
  | --- | --- | --- | --- |
@@ -183,11 +183,14 @@
183
183
  | `set_attrs` | view 树节点/controls | `code`、`patch`、`overwriteArray?` | 按 code 定位节点**浅合并属性**。⚠️ 仅限 view 树节点与 controls 数组(action 结构改用 patch_action_array_item)。⚠️ **patch 含数组属性默认阻断**(ARRAY_OVERWRITE_BLOCKED,防误改丢列——曾致 36 列丢失);确要整段覆盖须显式 `overwriteArray:true`,否则改用 patch_node_array_item / patch_action_array_item 做元素级增改删 |
184
184
  | `patch_node_array_item` | 节点内数组 | `nodeCode`、`arrayProp`(如 `cols`/`options`/`content`)、`mode`、其余见下 | view 树节点内**数组元素级**操作,四种模式 + 两级嵌套,详见下节 |
185
185
  | `patch_action_array_item` | handler action 内数组 | `handlerCode`、`arrayProp`(如 `setter`)、`mode`、其余见下 | presenter.handlers/initial 中某 **action 内部数组**(如 `datarequest.setter` 界面输出绑定到控件、`param.properties`),四种模式 + 两级嵌套 |
186
+ | `add_action` | handler 的 `actions[]` | `handlerCode`、`scope?`、`type?`(默认 `flycode`)、`code?`、`desc?`、`condition?`、`position?`、`script?`、`fields?` | **追加一条动作**,按 type 自动补平台空骨架;`initial` 仅允许 `flycode`/`receivelink`;`code` 默认 `action_<handlerCode 末8位>`(同 handler 内重复自动加 `_2`/`_3`)。详见「动作的增/改/删」 |
187
+ | `patch_action` | handler 的单条 action | `handlerCode`、`scope?`、`actionCode?`/`actionIndex?`、`patch` | **浅合并任意字段**(`desc`/`condition`/`message`/`url`/`logiccode`/`queue`…,`script` 仅 flycode 可写)。⚠️ 不能含 `type`/`code`(换类型或改名走 `remove_action` + `add_action`) |
188
+ | `remove_action` | 同上 | 同上(无 `patch`) | **删除一条动作**;删空后保留 `actions: []`(不删属性,与平台形态一致) |
186
189
  | `insert_node` | view 树 | `parentCode`、`node`(新节点对象)、`position?`(默认末尾) | 插入新节点 |
187
190
  | `remove_node` | view 树 | `code`、`checkRefs?`(默认 true:存在事件/handler 引用时拒绝删除) | 删除节点 |
188
191
  | `move_node` | view 树 | `code`、`newParentCode`、`position?` | 移动节点到新父节点 |
189
192
  | `set_section` | 整段 | `section`(`view`/`presenter`/`controls`/`pageswitch`)、`value` | 整段替换(大 payload,慎用) |
190
- | `replace_script` | handler 的脚本字段 | `handlerCode`、`actionIndex?`/`actionCode?`、`field?`(`script`(默认)/`condition`/`expression`)、`scope?`(`handlers`/`initial`)、`replacement?` 或 `ops[]` | 改 UI 脚本。`replacement` 整段替换优先于 `ops`;`ops[]` 每项 `{ oldString(唯一命中), newString(空串=删除), replaceAll?, occurrence?, matchMode?, label? }`。⚠️ handlerCode 同名跨容器须加 `scope` 消歧 |
193
+ | `replace_script` | handler 的脚本字段 | `handlerCode`、`actionIndex?`/`actionCode?`、`field?`(`script`(默认)/`condition`/`expression`)、`scope?`(`handlers`/`initial`)、`replacement?` 或 `ops[]` | 改 UI 脚本。`replacement` 整段替换优先于 `ops`;`ops[]` 每项 `{ oldString(唯一命中), newString(空串=删除), replaceAll?, occurrence?, matchMode?, label? }`。⚠️ handlerCode 同名跨容器须加 `scope`(或等价别名 `handlerScope`)消歧 |
191
194
  | `add_businessmodel` | — | `modellogiccode`、`overwrite?` | **MCP 自动拉取该逻辑完整 JSON** 追加到 businessmodel(无需传大段逻辑 JSON);已存在时默认跳过,`overwrite:true` 覆盖 |
192
195
  | `remove_businessmodel` | — | `modellogiccode`、`checkRefs?`(默认 true) | 移除引用 |
193
196
 
@@ -208,10 +211,57 @@
208
211
  | 字段 | 类型 | 说明 |
209
212
  | --- | --- | --- |
210
213
  | `ok` / `applied` / `verified` / `message` | — | 同 patch_model_logic 口径 |
211
- | `errorCode` | string | `OK` / `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` |
214
+ | `errorCode` | string | `OK` / `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` |
212
215
  | `diff` | string | 全部 op 的 diff 片段(超长截断;只回改动摘要不回整份表单) |
213
216
  | `ops` | array | 每个 op 的结果:`{ index, op, status, errorCode, message, hunk?(replace_script 才有), suggestions?(NOT_FOUND 时的相似候选 [{startLine, score, preview}]) }` |
214
217
 
218
+ ### 动作(action)的增 / 改 / 删
219
+
220
+ 动作(action)= presenter 里 handler 的 `actions[]` 元素。**先按「想改什么」选 op,四个层次别混**:
221
+
222
+ | 想做的事 | 用哪个 op |
223
+ | --- | --- |
224
+ | 追加一条动作(新脚本 / 新 toast / 新数据请求…) | `add_action` |
225
+ | 改**其它任意字段**(`desc`、`condition`、`message`、`url`、`logiccode`、`queue`、非字符串值) | `patch_action`(`patch` 浅合并) |
226
+ | 只改 `script` / `condition` / `expression` 的**文本片段** | `replace_script`(`ops[]` 局部替换,`normalized` 容忍 CRLF) |
227
+ | 换动作类型、改 action `code` | `remove_action` + `add_action`(组合) |
228
+ | 改 action **内部数组**(`datarequest.setter`/`getter`、`param.properties`、`alert.choices`) | `patch_action_array_item`(**管不到 action 自身字段**) |
229
+
230
+ ```jsonc
231
+ // 给页面初始化事件追加一段脚本(此前只能整段 set_section 回传整个 presenter)
232
+ { "op": "add_action", "handlerCode": "initial_receivelink_event", "scope": "initial", "script": "(function(){...})();" }
233
+
234
+ // 给事件加一条轻提示:空骨架自动补齐,只传关键字段
235
+ { "op": "add_action", "handlerCode": "handler_xxx", "type": "toast", "fields": { "message": "保存成功" } }
236
+
237
+ // 插到首位(先执行)
238
+ { "op": "add_action", "handlerCode": "initial_xxx", "scope": "initial", "script": "...", "position": 0 }
239
+
240
+ // 改字段:replace_script 的 field 枚举覆盖不到 desc / message / url / logiccode
241
+ { "op": "patch_action", "handlerCode": "handler_xxx", "actionCode": "action_yyy", "patch": { "desc": "固定底部", "condition": "a==1" } }
242
+
243
+ // 删一条
244
+ { "op": "remove_action", "handlerCode": "initial_sticky_footer", "scope": "initial", "actionCode": "action_probe" }
245
+ ```
246
+
247
+ **action 的真实字段集**(平台实测,2120689842231840806):公共字段只有 `code` / `type` / `desc` / `condition` 四个,其余按 type 各异;`code` 是**语义化自定义名**(如 `action_sticky_footer`),不是雪花 ID。平台**不会**为代码写入的 action 补全缺失字段,`add_action` 因此内建各类型的空骨架模板。
248
+
249
+ **26 种 type**(`add_action` 的 `type` 走严格枚举,写错直接 schema 报错):
250
+
251
+ | 分组 | type |
252
+ | --- | --- |
253
+ | 数据处理 | `flycode`、`datarequest`(数据请求)、`datasubmit`(数据提交)、`dataimport`、`dataexport`、`datatransfer`、`dataserialize`、`smartrequest`(智慧场景请求) |
254
+ | 表单行为 | `link`(链接)、`call`(事件呼叫)、`return`、`ctrlevent`(调用控件事件)、`receivelink`(接收参数)、`eventlink`(事件监听)、`attributeevaluate`(属性表达式)、`alert`(提示弹窗)、`toast`(轻提示)、`share`、`popsubview`、`closesubview`、`print`、`urllink`(URL链接)、`runevent`(执行事件) |
255
+ | 流程 | `af_preaddflow`(流程发起)、`af_handleflow`(处理审批)、`af_flowdetail`(流程节点详情) |
256
+
257
+ ⚠️ **类型按容器分域**:`initial`(页面初始化)**只允许 `flycode` / `receivelink` 两种**,其余 24 种加到 initial 会报 `TYPE_NOT_ALLOWED`(fail-closed,避免写出设计器打不开的动作)。
258
+
259
+ ⚠️ **易错字面值**:数据提交是 `datasubmit`(**不是** `datacommit`);「数据字典绑定」**不是独立 type**,它是 `datarequest` 的变体 —— `{"type":"datarequest","_type_spe":"dictbind","logiccode":"100000000001100001","binddic":"","bind":""}`,用 `type:"datarequest"` + `fields:{"_type_spe":"dictbind",...}` 构造。
260
+
261
+ **定位铁律**:一律用 `actionCode`。`actionIndex` 在同批次前面有增删时会漂移(前序 op 删了一条,后面的下标就偏了),回读校验也会因此打到邻居身上。
262
+
263
+ **容器消歧参数 `scope` / `handlerScope`**:所有需要限定 `handlers`/`initial` 的 op(`patch_action_array_item` / `replace_script` / `add_action` / `patch_action` / `remove_action`)**两者等价、任传其一**(读工具 `get_form_fragment` 用的是 `handlerScope`)。同时传且取值不同会报 `INVALID_PARAMS`——不会静默二选一。
264
+
215
265
  ### ⚠️ 高频陷阱:界面输出绑定的两种真实落点,patch 前必须先核对
216
266
 
217
267
  字段级绑定与模型级属性映射落点不同,**patch 前必须先 `get_form_fragment({ handlerCode })` 看清是哪一层**:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flycode-mcp",
3
- "version": "1.14.5",
3
+ "version": "1.14.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/flycode-mcp.min.js",