@12inch-glorysoft/dsh-ad-form 0.0.0-stage → 1.0.0-beta.2

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.
Files changed (255) hide show
  1. package/README.md +127 -2
  2. package/cordis.yml +3 -0
  3. package/dist/client/client.js +229 -0
  4. package/dist/server/_virtual/_rolldown/runtime.js +13 -0
  5. package/dist/server/agents/plan-preset.js +17 -0
  6. package/dist/server/agents/plan-review.js +60 -0
  7. package/dist/server/agents/plan-schema.js +21 -0
  8. package/dist/server/agents/plan.js +80 -0
  9. package/dist/server/agents/util.js +16 -0
  10. package/dist/server/converter/components/actions/button.js +39 -0
  11. package/dist/server/converter/components/actions/index.js +2 -0
  12. package/dist/server/converter/components/composites/entity-form.js +14 -0
  13. package/dist/server/converter/components/composites/filter-table.js +24 -0
  14. package/dist/server/converter/components/composites/index.js +3 -0
  15. package/dist/server/converter/components/custom/form-inspector.js +13 -0
  16. package/dist/server/converter/components/custom/index.js +7 -0
  17. package/dist/server/converter/components/custom/item-gallery.js +30 -0
  18. package/dist/server/converter/components/custom/kpi-tile.js +19 -0
  19. package/dist/server/converter/components/custom/master-detail-table.js +16 -0
  20. package/dist/server/converter/components/custom/message-console.js +26 -0
  21. package/dist/server/converter/components/custom/tree-hierarchy.js +16 -0
  22. package/dist/server/converter/components/display/hidden.js +8 -0
  23. package/dist/server/converter/components/display/image.js +32 -0
  24. package/dist/server/converter/components/display/index.js +5 -0
  25. package/dist/server/converter/components/display/separator.js +8 -0
  26. package/dist/server/converter/components/display/text.js +15 -0
  27. package/dist/server/converter/components/index.js +11 -0
  28. package/dist/server/converter/components/inputs/checkbox.js +8 -0
  29. package/dist/server/converter/components/inputs/date-range.js +8 -0
  30. package/dist/server/converter/components/inputs/date.js +8 -0
  31. package/dist/server/converter/components/inputs/datetime-range.js +8 -0
  32. package/dist/server/converter/components/inputs/datetime.js +8 -0
  33. package/dist/server/converter/components/inputs/index.js +11 -0
  34. package/dist/server/converter/components/inputs/number-range.js +8 -0
  35. package/dist/server/converter/components/inputs/number.js +8 -0
  36. package/dist/server/converter/components/inputs/password.js +8 -0
  37. package/dist/server/converter/components/inputs/text.js +8 -0
  38. package/dist/server/converter/components/inputs/textarea.js +8 -0
  39. package/dist/server/converter/components/layouts/card.js +11 -0
  40. package/dist/server/converter/components/layouts/grid.js +11 -0
  41. package/dist/server/converter/components/layouts/index.js +8 -0
  42. package/dist/server/converter/components/layouts/panel.js +11 -0
  43. package/dist/server/converter/components/layouts/section.js +15 -0
  44. package/dist/server/converter/components/layouts/split-view.js +11 -0
  45. package/dist/server/converter/components/layouts/tab-item.js +11 -0
  46. package/dist/server/converter/components/layouts/tabs.js +8 -0
  47. package/dist/server/converter/components/pickers/derived-text.js +19 -0
  48. package/dist/server/converter/components/pickers/entity-multi.js +8 -0
  49. package/dist/server/converter/components/pickers/entity-single.js +8 -0
  50. package/dist/server/converter/components/pickers/index.js +5 -0
  51. package/dist/server/converter/components/pickers/modal-table.js +8 -0
  52. package/dist/server/converter/components/selects/dict-dynamic-input.js +8 -0
  53. package/dist/server/converter/components/selects/dict-dynamic.js +8 -0
  54. package/dist/server/converter/components/selects/dict-static-input.js +8 -0
  55. package/dist/server/converter/components/selects/dict-static.js +8 -0
  56. package/dist/server/converter/components/selects/index.js +10 -0
  57. package/dist/server/converter/components/selects/lookup-table-input.js +8 -0
  58. package/dist/server/converter/components/selects/lookup-table.js +8 -0
  59. package/dist/server/converter/components/selects/lookup-user.js +8 -0
  60. package/dist/server/converter/components/selects/radio-group.js +8 -0
  61. package/dist/server/converter/components/selects/transfer.js +12 -0
  62. package/dist/server/converter/components/template/entity-crud.js +11 -0
  63. package/dist/server/converter/components/template/index.js +3 -0
  64. package/dist/server/converter/components/template/master-detail-tree.js +11 -0
  65. package/dist/server/converter/components/views/index.js +5 -0
  66. package/dist/server/converter/components/views/table-editor.js +21 -0
  67. package/dist/server/converter/components/views/table-grid.js +25 -0
  68. package/dist/server/converter/components/views/table-list.js +14 -0
  69. package/dist/server/converter/components/views/table-select.js +17 -0
  70. package/dist/server/converter/context.js +80 -0
  71. package/dist/server/converter/import-design.js +19 -0
  72. package/dist/server/converter/index.js +73 -0
  73. package/dist/server/converter/normalize-ir.js +18 -0
  74. package/dist/server/converter/registry.js +41 -0
  75. package/dist/server/converter/types.js +90 -0
  76. package/dist/server/converter/utils/bitmask.js +127 -0
  77. package/dist/server/converter/utils/derived-reference.js +11 -0
  78. package/dist/server/converter/utils/id.js +51 -0
  79. package/dist/server/converter/utils/index.js +6 -0
  80. package/dist/server/converter/utils/lookup.js +12 -0
  81. package/dist/server/converter/utils/node.js +91 -0
  82. package/dist/server/converter/utils/normalizer.js +218 -0
  83. package/dist/server/converter/utils/xml-builder.js +230 -0
  84. package/dist/server/converter/xml-common.js +286 -0
  85. package/dist/server/converter/xml-converter/format-attributes.js +418 -0
  86. package/dist/server/converter/xml-converter/table-common.js +107 -0
  87. package/dist/server/converter/xml-converter/tags/ad-button.js +33 -0
  88. package/dist/server/converter/xml-converter/tags/ad-field.js +179 -0
  89. package/dist/server/converter/xml-converter/tags/ad-form.js +69 -0
  90. package/dist/server/converter/xml-converter/tags/ad-tab.js +66 -0
  91. package/dist/server/converter/xml-converter/tags/index.js +5 -0
  92. package/dist/server/converter/xml-converter/xml-context.js +100 -0
  93. package/dist/server/converter/xml-converter/xml-registry.js +38 -0
  94. package/dist/server/converter/xml-converter/xml-util.js +119 -0
  95. package/dist/server/converter/xml-tags.js +176 -0
  96. package/dist/server/data-source/index.js +1 -0
  97. package/dist/server/data-source/registry.js +59 -0
  98. package/dist/server/db/config.js +41 -0
  99. package/dist/server/db/database.js +82 -0
  100. package/dist/server/db/index.js +4 -0
  101. package/dist/server/db/query.js +56 -0
  102. package/dist/server/dictionary/index.js +1 -0
  103. package/dist/server/dictionary/registry.js +135 -0
  104. package/dist/server/entity/index.js +4 -0
  105. package/dist/server/entity/retrieve.js +797 -0
  106. package/dist/server/entity/rg.js +42 -0
  107. package/dist/server/entity/scan.js +134 -0
  108. package/dist/server/entry.js +43 -0
  109. package/dist/server/icon/catalog.js +41 -0
  110. package/dist/server/icon/catalog.json +651 -0
  111. package/dist/server/icon/index.js +56 -0
  112. package/dist/server/icon/workspace.js +102 -0
  113. package/dist/server/ir/operations-spec.js +119 -0
  114. package/dist/server/ir/operations.js +124 -0
  115. package/dist/server/ir/query.js +27 -0
  116. package/dist/server/listener/index.js +7 -0
  117. package/dist/server/listener/ir-change.js +125 -0
  118. package/dist/server/listener/task-change.js +41 -0
  119. package/dist/server/package.js +171 -0
  120. package/dist/server/plan/build-plan.js +20 -0
  121. package/dist/server/plan/render-plan-confirmation.js +49 -0
  122. package/dist/server/plan/review-spec.js +58 -0
  123. package/dist/server/plan/skeleton.js +61 -0
  124. package/dist/server/plan/spec.js +82 -0
  125. package/dist/server/plugin.js +59 -0
  126. package/dist/server/prompt/completion-check.js +25 -0
  127. package/dist/server/prompt/context.js +14 -0
  128. package/dist/server/prompt/design-state.js +36 -0
  129. package/dist/server/prompt/guide.js +59 -0
  130. package/dist/server/prompt/plan.js +112 -0
  131. package/dist/server/prompt/render.js +11 -0
  132. package/dist/server/runtime.js +82 -0
  133. package/dist/server/service.js +98 -0
  134. package/dist/server/skills/ad-form/SKILL.md +22 -0
  135. package/dist/server/skills/ad-form/references/create.md +7 -0
  136. package/dist/server/skills/ad-form/references/edit.md +54 -0
  137. package/dist/server/skills/ad-form/references/import.md +11 -0
  138. package/dist/server/skills/ad-form/references/scope.md +7 -0
  139. package/dist/server/spec/assembler.js +250 -0
  140. package/dist/server/spec/components/action-button.md +45 -0
  141. package/dist/server/spec/components/composite-entity-form.md +25 -0
  142. package/dist/server/spec/components/composite-filter-table.md +105 -0
  143. package/dist/server/spec/components/custom-form-inspector.md +16 -0
  144. package/dist/server/spec/components/custom-item-gallery.md +49 -0
  145. package/dist/server/spec/components/custom-kpi-tile.md +23 -0
  146. package/dist/server/spec/components/custom-master-detail-table.md +21 -0
  147. package/dist/server/spec/components/custom-message-console.md +29 -0
  148. package/dist/server/spec/components/custom-tree-hierarchy.md +25 -0
  149. package/dist/server/spec/components/display-hidden.md +37 -0
  150. package/dist/server/spec/components/display-image.md +42 -0
  151. package/dist/server/spec/components/display-separator.md +35 -0
  152. package/dist/server/spec/components/display-text.md +37 -0
  153. package/dist/server/spec/components/input-checkbox.md +32 -0
  154. package/dist/server/spec/components/input-date-range.md +34 -0
  155. package/dist/server/spec/components/input-date.md +50 -0
  156. package/dist/server/spec/components/input-datetime-range.md +35 -0
  157. package/dist/server/spec/components/input-datetime.md +34 -0
  158. package/dist/server/spec/components/input-number-range.md +36 -0
  159. package/dist/server/spec/components/input-number.md +36 -0
  160. package/dist/server/spec/components/input-password.md +35 -0
  161. package/dist/server/spec/components/input-text.md +89 -0
  162. package/dist/server/spec/components/input-textarea.md +53 -0
  163. package/dist/server/spec/components/layout-card.md +39 -0
  164. package/dist/server/spec/components/layout-grid.md +36 -0
  165. package/dist/server/spec/components/layout-panel.md +35 -0
  166. package/dist/server/spec/components/layout-section.md +150 -0
  167. package/dist/server/spec/components/layout-split-view.md +43 -0
  168. package/dist/server/spec/components/layout-tab-item.md +25 -0
  169. package/dist/server/spec/components/layout-tabs.md +80 -0
  170. package/dist/server/spec/components/picker-derived-text.md +67 -0
  171. package/dist/server/spec/components/picker-entity-multi.md +46 -0
  172. package/dist/server/spec/components/picker-entity-single.md +46 -0
  173. package/dist/server/spec/components/picker-modal-table.md +36 -0
  174. package/dist/server/spec/components/select-dict-dynamic-input.md +39 -0
  175. package/dist/server/spec/components/select-dict-dynamic.md +39 -0
  176. package/dist/server/spec/components/select-dict-static-input.md +39 -0
  177. package/dist/server/spec/components/select-dict-static.md +39 -0
  178. package/dist/server/spec/components/select-lookup-table-input.md +38 -0
  179. package/dist/server/spec/components/select-lookup-table.md +38 -0
  180. package/dist/server/spec/components/select-lookup-user.md +36 -0
  181. package/dist/server/spec/components/select-radio-group.md +37 -0
  182. package/dist/server/spec/components/select-transfer.md +38 -0
  183. package/dist/server/spec/components/template-entity-crud.md +85 -0
  184. package/dist/server/spec/components/template-master-detail-tree.md +41 -0
  185. package/dist/server/spec/components/view-table-editor.md +47 -0
  186. package/dist/server/spec/components/view-table-grid.md +85 -0
  187. package/dist/server/spec/components/view-table-list.md +30 -0
  188. package/dist/server/spec/components/view-table-select.md +50 -0
  189. package/dist/server/spec/ir-schema.json +456 -0
  190. package/dist/server/state/constants.js +19 -0
  191. package/dist/server/state/domain.js +81 -0
  192. package/dist/server/state/draft.js +36 -0
  193. package/dist/server/state/index.js +7 -0
  194. package/dist/server/state/session.js +265 -0
  195. package/dist/server/state/store.js +76 -0
  196. package/dist/server/state/task-view-spec.js +76 -0
  197. package/dist/server/state/task-view.js +42 -0
  198. package/dist/server/state/tasks.js +23 -0
  199. package/dist/server/state/types.js +16 -0
  200. package/dist/server/tool-access.js +64 -0
  201. package/dist/server/tools/catalog.js +23 -0
  202. package/dist/server/tools/complete-task/execute.js +33 -0
  203. package/dist/server/tools/complete-task/index.js +56 -0
  204. package/dist/server/tools/complete-task/schema.js +37 -0
  205. package/dist/server/tools/confirm-plan/execute.js +88 -0
  206. package/dist/server/tools/confirm-plan/index.js +33 -0
  207. package/dist/server/tools/confirm-plan/schema.js +38 -0
  208. package/dist/server/tools/create-task/execute.js +21 -0
  209. package/dist/server/tools/create-task/index.js +29 -0
  210. package/dist/server/tools/create-task/schema.js +43 -0
  211. package/dist/server/tools/get-component-spec/index.js +52 -0
  212. package/dist/server/tools/get-component-spec/schema.js +27 -0
  213. package/dist/server/tools/get-design-state/index.js +59 -0
  214. package/dist/server/tools/get-design-state/schema.js +60 -0
  215. package/dist/server/tools/get-entity-attributes/index.js +79 -0
  216. package/dist/server/tools/get-entity-attributes/schema.js +69 -0
  217. package/dist/server/tools/get-ir/execute.js +35 -0
  218. package/dist/server/tools/get-ir/index.js +32 -0
  219. package/dist/server/tools/get-ir/schema.js +37 -0
  220. package/dist/server/tools/import-design/execute.js +51 -0
  221. package/dist/server/tools/import-design/index.js +29 -0
  222. package/dist/server/tools/import-design/schema.js +34 -0
  223. package/dist/server/tools/index.js +39 -0
  224. package/dist/server/tools/run-plan-subagent/execute.js +68 -0
  225. package/dist/server/tools/run-plan-subagent/index.js +33 -0
  226. package/dist/server/tools/run-plan-subagent/schema.js +45 -0
  227. package/dist/server/tools/search-data-source/index.js +89 -0
  228. package/dist/server/tools/search-data-source/schema.js +49 -0
  229. package/dist/server/tools/search-dictionary/index.js +109 -0
  230. package/dist/server/tools/search-dictionary/schema.js +98 -0
  231. package/dist/server/tools/search-entity/index.js +82 -0
  232. package/dist/server/tools/search-entity/schema.js +65 -0
  233. package/dist/server/tools/search-icon/index.js +98 -0
  234. package/dist/server/tools/search-icon/schema.js +66 -0
  235. package/dist/server/tools/start-new-design/index.js +50 -0
  236. package/dist/server/tools/start-new-design/schema.js +21 -0
  237. package/dist/server/tools/update-ir/execute.js +23 -0
  238. package/dist/server/tools/update-ir/index.js +29 -0
  239. package/dist/server/tools/update-ir/schema.js +25 -0
  240. package/dist/server/tools/update-task/execute.js +25 -0
  241. package/dist/server/tools/update-task/index.js +29 -0
  242. package/dist/server/tools/update-task/schema.js +44 -0
  243. package/dist/server/tools/validate-plan/index.js +47 -0
  244. package/dist/server/tools/validate-plan/schema.js +31 -0
  245. package/dist/server/util/compose.js +15 -0
  246. package/dist/server/util/database-search.js +69 -0
  247. package/dist/server/util/file.js +13 -0
  248. package/dist/server/util/json.js +44 -0
  249. package/dist/server/util/message.js +88 -0
  250. package/dist/server/util/search-limit.js +18 -0
  251. package/dist/server/util/text.js +15 -0
  252. package/dist/server/validate/ir-config.js +139 -0
  253. package/dist/server/validate/ir.js +42 -0
  254. package/dist/server/validate/util.js +137 -0
  255. package/package.json +154 -3
package/README.md CHANGED
@@ -1,3 +1,128 @@
1
- # Temporary Holding Version
1
+ # AD Form Design Agent
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 基于 dsh (DeepSeek Harness) 平台构建的智能 Agent,用于根据手绘草图和需求描述自动生成 GLC-Form (ADForm) XML 配置文件。
4
+
5
+ ## 项目背景
6
+
7
+ 现有产品为 EJB + Eclipse RCP 的 C/S 客户端架构,有一套基于 RCP 的低代码包,使用 XML Schema 绘制布局、表单和表格。本项目旨在构建一个 Agent,通过草图识别和多轮对话交互,自动化生成符合规范的 ADForm XML。
8
+
9
+ ## 使用入口
10
+
11
+ 无需开启或关闭表单能力。直接描述表单需求、上传相关图片,或引用已有 IR JSON / XML 文件,由模型结合语义选择表单 skill;也可以主动输入 `/ad-form 创建客户表单`,同时附带图片或文件。单独输入 `/ad-form` 时先澄清需求。
12
+
13
+ 继续修改时沿用当前设计,切换普通话题无需关闭。宿主需提供 `skills` 服务、原生 `skill` 工具及其用户调用入口,以及内置问询工具 `ask_user_question`;本插件负责注册 `ad-form` skill 与命令。
14
+
15
+ ## 数据库检索配置
16
+
17
+ 打开 dsh 左侧「插件」→ `@12inch-glorysoft/dsh-ad-form` → `ad-form` 条目的「配置」,填写数据库连接。插件浏览器模块注册配置页面,复用宿主的表单控件;配置读取与保存由原生 settings 和 configEditor 服务完成。
18
+
19
+ | 字段 | 用途 |
20
+ | --------------------- | -------------------------------------------- |
21
+ | `dataSource.driver` | `oracle`、`mysql` 或 `postgres` |
22
+ | `dataSource.host` | 数据库地址 |
23
+ | `dataSource.port` | 正整数端口 |
24
+ | `dataSource.database` | Oracle 服务名,或 MySQL / PostgreSQL 库名 |
25
+ | `dataSource.user` | 数据库账号 |
26
+ | `dataSource.password` | 数据库密码;按宿主秘密字段处理 |
27
+ | `dataSource.owner` | 可选的元数据 schema;留空使用账号默认 schema |
28
+
29
+ 默认不提供连接值。允许分步填写;检索时需要驱动、地址、端口、库名和账号,密码与 schema 可省略。未配置或参数不完整时,数据源与字典检索返回配置引导,其他表单设计能力仍可使用。选用数据库方言时,运行环境还需有对应驱动(Oracle 使用项目依赖中的 `oracledb`;MySQL / PostgreSQL 分别需要 `mysql2` / `pg`)。
30
+
31
+ 保存只校验字段并写入当前 profile,不主动测试数据库连接。新检索立即使用新配置并释放旧连接池;无需重启或重新创建表单设计。清空连接字段即可恢复未配置状态。密码不会随设置读取返回;只修改其他字段时由宿主保留原密码。profile 的本地持久化不代表加密存储。
32
+
33
+ ### 本地开发加载
34
+
35
+ 在项目目录安装开发依赖后,只构建前端并安装本地目录:
36
+
37
+ ```bash
38
+ pnpm install
39
+ pnpm run build:client
40
+ dsh --profile ad-form-dev --from-default-profile web --dump-config
41
+ dsh plugin --profile ad-form-dev add /home/alone/workspace/ad-form-agent
42
+ NODE_OPTIONS="$NODE_OPTIONS --conditions=development" dsh --profile ad-form-dev --no-open
43
+ ```
44
+
45
+ 首次使用专用的 `ad-form-dev` profile,可以避开既有 `web` profile 中手工插入的源码条目;安装命令由宿主维护 profile,无需手工修改 `.dsh` 文件。初始化与安装只需做一次,以后直接运行最后一条启动命令。若希望继续用已有 `web` profile,需先移除其中同 id 的源码插入指令并保留已有的 `ad-form` 配置覆盖,避免重复条目。之后不要再使用 `--patch cordis.yml`。
46
+
47
+ 本地启动时通过 Node 的 `--conditions=development` 选择 `src/plugin.ts` 入口,后端直接运行 TypeScript,可沿用原来的 TS 断点调试方式,无需后端构建或 sourcemap。未指定该条件时使用 `dist/server/plugin.js` 发布入口;开发条件仅用于已安装源码目录的本地环境。
48
+
49
+ 已有 `web` profile 安装本地目录时,在项目目录运行 `pnpm run dev`:先构建一次前端,再同时启动前端 Vite watch 和后端 dsh 源码模式。按 Ctrl+C 停止两者,任一进程退出时也会结束另一个。后端保留已有的 `NODE_OPTIONS`,可配合原来的调试器连接方式使用。只启动后端可运行 `pnpm run dev:server`。
50
+
51
+ 浏览器模块仍要求插件以裸包名 `@12inch-glorysoft/dsh-ad-form` 加载;直接引用 `src/plugin.ts` 不会加载浏览器侧页面。单独监听前端可运行 `pnpm run build:client --watch`。修改后端后重启 dsh,修改前端后刷新浏览器;宿主启用热重载时按其实际行为生效。配置保存在安装所用的 profile 中。
52
+
53
+ 也可通过 profile 配置中的 `!!js process.env.AD_FORM_DB_PASSWORD` 等表达式引用环境变量。命令行 overlay 的优先级高于 profile,应避免覆盖表单编辑的连接字段。
54
+
55
+ ### 发布与更新
56
+
57
+ 当前适配 DSH `0.2.1-rc.5`。
58
+
59
+ ```bash
60
+ pnpm login --registry=https://registry.npmjs.org/
61
+ pnpm check # lint、格式检查、类型检查
62
+ pnpm build # prebuild 检查通过后构建前后端
63
+ pnpm release:beta # 递增 Beta 版本并发布
64
+ pnpm release:stable # 转为正式版本并发布
65
+ ```
66
+
67
+ `prerelease:beta` / `prerelease:stable` 负责递增版本,`release:*` 负责上传;上传前由 `prepack → prebuild → build` 完成检查和构建。格式检查失败可运行 `pnpm fmt` 修复。
68
+
69
+ 从 `1.0.0-beta.0` 开始:
70
+
71
+ ```text
72
+ release:beta → 1.0.0-beta.1
73
+ release:beta → 1.0.0-beta.2
74
+ release:stable → 1.0.0
75
+ release:beta → 1.0.1-beta.0
76
+ ```
77
+
78
+ 首次 Beta 后可直接转正式版。从正式版运行 `release:stable` 会递增补丁版本。脚本会修改本地版本号,不创建 Git 提交或 tag;发布成功后自行提交版本变更。
79
+
80
+ 发布失败时,先查看 `package.json`:版本已递增就保留,不再运行 `release:*`。修复检查、构建、登录或权限问题后,选择对应命令重试当前版本:
81
+
82
+ ```bash
83
+ pnpm publish --tag beta --no-git-checks # Beta
84
+ pnpm publish --tag latest --no-git-checks # 正式版
85
+ ```
86
+
87
+ 若上传断网、超时或提示版本已存在,先确认是否已发布(替换为当前版本):
88
+
89
+ ```bash
90
+ pnpm view @12inch-glorysoft/dsh-ad-form@1.0.0-beta.1 version --registry=https://registry.npmjs.org/
91
+ ```
92
+
93
+ 查到版本就无需重发;确认不存在再重试。查询本身失败时,恢复网络或登录后再查。版本尚未递增时,修复问题后可重新执行 `release:*`。
94
+
95
+ 只演练、不上传也不改版本:
96
+
97
+ ```bash
98
+ pnpm publish --tag beta --dry-run --no-git-checks
99
+ ```
100
+
101
+ 不要用 `release:* --dry-run` 演练,它仍会先递增版本。
102
+
103
+ 安装或更新后重启对应 profile;Desktop 用户将 `web` 改为 `desktop`:
104
+
105
+ ```bash
106
+ dsh plugin --profile web add @12inch-glorysoft/dsh-ad-form@beta
107
+ dsh plugin --profile web add @12inch-glorysoft/dsh-ad-form@latest
108
+ ```
109
+
110
+ ## 核心流程
111
+
112
+ ```
113
+ 需求或参考图 → 主模型理解与范围确认 → 布局规划和确认 → IR 构建或编辑 → 校验并输出 XML
114
+ ```
115
+
116
+ ## 技术栈
117
+
118
+ - **平台**: dsh web (DeepSeek Harness)
119
+ - **主模型**: 支持图片输入的多模态模型,直接理解创建与修改时的参考图
120
+ - **规划子 Agent**: 接收主模型整理的有效需求、相关澄清、调整反馈与图片观察
121
+ - **中间态**: Semantic IR JSON (ComponentNode AST, Single Source of Truth)
122
+ - **插件框架**: Cordis 依赖注入 + 生命周期管理
123
+
124
+ ## 文档索引
125
+
126
+ - [全局技术方案与实施规范](docs/technical-plan.md):系统架构、Multi-Agent 协同编排流程、状态模型与演进规划
127
+ - [Semantic IR 核心架构与规范体系](docs/semantic-ir/README.md):领域元模型、组件全集、物理 XML DSL 与 ARB 避坑事实
128
+ - [DSH 消息与上下文植入机制指南](docs/message-injection.md):系统各层消息注入接缝、时序状态机与场景决策指南
package/cordis.yml ADDED
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: ad-form
3
+ name: '@12inch-glorysoft/dsh-ad-form'
@@ -0,0 +1,229 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "@12inch-glorysoft/dsh-ad-form",
3
+ factory(require) {
4
+ const module = { exports: {} };
5
+ const exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
8
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
9
+ let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region src/client/index.tsx
11
+ var fields = [
12
+ "driver",
13
+ "host",
14
+ "port",
15
+ "database",
16
+ "user",
17
+ "password",
18
+ "owner"
19
+ ];
20
+ var labels = {
21
+ host: ["数据库地址", "数据库服务器的主机名或 IP 地址"],
22
+ port: ["端口", "正整数;Oracle 常用 1521,MySQL 常用 3306,PostgreSQL 常用 5432"],
23
+ database: ["数据库", "Oracle 服务名,或 MySQL / PostgreSQL 库名"],
24
+ user: ["账号", "用于读取数据源和字典元数据的数据库账号"],
25
+ owner: ["元数据 schema", "可选;留空使用账号默认 schema"]
26
+ };
27
+ var drivers = [
28
+ {
29
+ value: "",
30
+ label: "未配置"
31
+ },
32
+ {
33
+ value: "oracle",
34
+ label: "Oracle"
35
+ },
36
+ {
37
+ value: "mysql",
38
+ label: "MySQL"
39
+ },
40
+ {
41
+ value: "postgres",
42
+ label: "PostgreSQL"
43
+ }
44
+ ];
45
+ function connectionValue(value) {
46
+ if (!value || typeof value !== "object" || !("dataSource" in value)) return {};
47
+ const source = value.dataSource;
48
+ return source && typeof source === "object" ? source : {};
49
+ }
50
+ function invalidPort(text) {
51
+ return text.trim() !== "" && (!Number.isInteger(Number(text)) || Number(text) <= 0);
52
+ }
53
+ function connectionChanges(drafts, source, overridden, clearPassword) {
54
+ const operations = [];
55
+ for (const field of fields) {
56
+ if (field === "password") continue;
57
+ const raw = drafts[field];
58
+ if (raw === void 0) continue;
59
+ const value = raw.trim();
60
+ const path = ["dataSource", field];
61
+ if (value === "") {
62
+ if (Object.hasOwn(overridden, field)) operations.push({
63
+ op: "unset",
64
+ path
65
+ });
66
+ } else {
67
+ const next = field === "port" ? Number(value) : value;
68
+ if (source[field] !== next) operations.push({
69
+ op: "set",
70
+ path,
71
+ value: next
72
+ });
73
+ }
74
+ }
75
+ if (drafts.password) operations.push({
76
+ op: "set",
77
+ path: ["dataSource", "password"],
78
+ value: drafts.password
79
+ });
80
+ else if (clearPassword) operations.push({
81
+ op: "unset",
82
+ path: ["dataSource", "password"]
83
+ });
84
+ return operations;
85
+ }
86
+ function DatabaseSettings({ view, form, usePasswordConfigured }) {
87
+ const [drafts, setDrafts] = (0, react.useState)({});
88
+ const [clearPassword, setClearPassword] = (0, react.useState)(false);
89
+ const [saving, setSaving] = (0, react.useState)(false);
90
+ const [failed, setFailed] = (0, react.useState)(false);
91
+ const [revision, setRevision] = (0, react.useState)();
92
+ const passwordConfigured = usePasswordConfigured((configured) => configured);
93
+ const source = connectionValue(form?.state.value);
94
+ const overridden = connectionValue(form?.state.user);
95
+ const text = (field) => drafts[field] ?? String(source[field] ?? "");
96
+ const edit = (field, value) => {
97
+ setRevision((current) => current ?? form?.state.revision);
98
+ setDrafts((current) => ({
99
+ ...current,
100
+ [field]: value
101
+ }));
102
+ setFailed(false);
103
+ if (field === "password" && value) setClearPassword(false);
104
+ };
105
+ const discard = () => {
106
+ setDrafts({});
107
+ setClearPassword(false);
108
+ setRevision(void 0);
109
+ setFailed(false);
110
+ };
111
+ const invalid = invalidPort(text("port"));
112
+ const operations = connectionChanges(drafts, source, overridden, clearPassword);
113
+ const dirty = operations.length > 0;
114
+ const save = async () => {
115
+ if (!form || saving || invalid || !dirty) return;
116
+ setSaving(true);
117
+ setFailed(false);
118
+ try {
119
+ if (await form.mutate(operations, revision ?? form.state.revision)) discard();
120
+ else {
121
+ setRevision(void 0);
122
+ setFailed(true);
123
+ }
124
+ } catch {
125
+ setRevision(void 0);
126
+ setFailed(true);
127
+ } finally {
128
+ setSaving(false);
129
+ }
130
+ };
131
+ if (view === "summary") return "设置表单设计所用的数据源与字典检索连接。";
132
+ const writable = form?.state.writable === true;
133
+ const disabled = !writable || saving;
134
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.SettingsForm, {
135
+ labels: {
136
+ unavailable: "插件配置当前不可用,请确认 ad-form 已启用。",
137
+ readOnly: "当前配置为只读。",
138
+ saveFailed: "配置未保存,请检查输入;如果配置已被其他页面修改,请重新打开后再试。",
139
+ save: "保存",
140
+ saving: "保存中…"
141
+ },
142
+ state: {
143
+ available: form?.state.status === "ready",
144
+ writable,
145
+ dirty,
146
+ invalid,
147
+ saving,
148
+ failed
149
+ },
150
+ onSave: () => {
151
+ save();
152
+ },
153
+ onDiscard: discard,
154
+ children: [
155
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "连接仅在检索时建立。保存后新检索使用新配置,当前表单设计会保留。" }),
156
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
157
+ id: "ad-form-driver",
158
+ label: "数据库驱动",
159
+ value: text("driver"),
160
+ options: drivers,
161
+ disabled,
162
+ onChange: (value) => edit("driver", value)
163
+ }),
164
+ Object.entries(labels).map(([key, [label, hint]]) => {
165
+ const field = key;
166
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SettingsValueField, {
167
+ id: `ad-form-${field}`,
168
+ label,
169
+ hint,
170
+ text: text(field),
171
+ overridden: drafts[field] === void 0 ? Object.hasOwn(overridden, field) : drafts[field].trim() !== "",
172
+ invalid: field === "port" && invalid,
173
+ invalidLabel: "请填写正整数端口。",
174
+ numeric: field === "port",
175
+ overriddenLabel: "已配置",
176
+ resetLabel: "清空",
177
+ disabled,
178
+ onEdit: (value) => edit(field, value),
179
+ onReset: () => edit(field, "")
180
+ }, field);
181
+ }),
182
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SettingsSecretField, {
183
+ id: "ad-form-password",
184
+ label: "密码",
185
+ hint: "留空保留已保存的密码;如需删除,请点击清除密码。",
186
+ text: drafts.password ?? "",
187
+ configured: passwordConfigured && !clearPassword,
188
+ stateLabel: clearPassword ? "保存后清除密码" : passwordConfigured ? "已设置" : "未设置",
189
+ disabled,
190
+ onEdit: (value) => edit("password", value)
191
+ }),
192
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
193
+ disabled: disabled || !passwordConfigured && !drafts.password || clearPassword,
194
+ onClick: () => {
195
+ setRevision((current) => current ?? form?.state.revision);
196
+ setDrafts((current) => ({
197
+ ...current,
198
+ password: ""
199
+ }));
200
+ if (passwordConfigured) setClearPassword(true);
201
+ setFailed(false);
202
+ },
203
+ children: "清除密码"
204
+ })
205
+ ]
206
+ });
207
+ }
208
+ var inject = ["slots", "configForms"];
209
+ function apply(ctx) {
210
+ const describe = ctx.configForms.describe();
211
+ const passwordConfigured = {
212
+ getSnapshot: () => {
213
+ return (describe.getSnapshot().view?.namespaces)?.find((item) => item.ns === "ad-form")?.secrets?.some((secret) => secret.path.length === 2 && secret.path[0] === "dataSource" && secret.path[1] === "password" && secret.set) ?? false;
214
+ },
215
+ subscribe: (listener) => describe.subscribe(listener)
216
+ };
217
+ ctx.effect(() => ctx.configForms.whileServed(["ad-form"], () => ctx.slots.inject("plugins.row.config", () => ctx.slots.register({
218
+ name: "plugins.row.config",
219
+ key: "@12inch-glorysoft/dsh-ad-form#ad-form",
220
+ inject: () => ({ hooks: { passwordConfigured } })
221
+ }, DatabaseSettings))));
222
+ }
223
+ //#endregion
224
+ exports.DatabaseSettings = DatabaseSettings;
225
+ exports.apply = apply;
226
+ exports.inject = inject;
227
+ return module.exports;
228
+ }
229
+ });
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll };
@@ -0,0 +1,17 @@
1
+ import { PLAN_PERSONA } from "../prompt/plan.js";
2
+ import { TOOL_NAMES } from "../tools/catalog.js";
3
+ import { PERSONA_PREFIX_SECTION } from "@deepseek-ai/dsh-system-prompt";
4
+ //#region src/agents/plan-preset.ts
5
+ var PLAN_PRESET_ID = "ad-form-plan";
6
+ var name = "ad-form-plan-preset";
7
+ var inject = ["systemPrompt", "tools"];
8
+ function apply(ctx) {
9
+ ctx.systemPrompt.section({
10
+ name: PERSONA_PREFIX_SECTION,
11
+ order: ctx.systemPrompt.getSectionOrder("DEPLOYMENT_PERSONA_PREFIX"),
12
+ text: PLAN_PERSONA
13
+ });
14
+ ctx.tools.restrict({ allow: [TOOL_NAMES.getComponentSpec, TOOL_NAMES.validatePlan] });
15
+ }
16
+ //#endregion
17
+ export { PLAN_PRESET_ID, apply, inject, name };
@@ -0,0 +1,60 @@
1
+ import { PLAN_REVIEW_LABELS } from "../plan/review-spec.js";
2
+ import { buildPlanReviewPrompt } from "../prompt/plan.js";
3
+ import { TOOL_NAMES } from "../tools/catalog.js";
4
+ import { VALIDATE_PLAN_SCHEMA } from "../tools/validate-plan/schema.js";
5
+ import { injectMessageWithTool } from "../util/message.js";
6
+ import { validateJsonSchemaValue } from "@deepseek-ai/dsh-tools";
7
+ import { isDeepStrictEqual } from "node:util";
8
+ import { createUserMessage } from "@deepseek-ai/dsh-llm";
9
+ //#region src/agents/plan-review.ts
10
+ var mountPlanReview = (agent, evidence, replySchema) => {
11
+ const checkReview = (value, allowUnresolved = false) => {
12
+ const shapeIssues = validateJsonSchemaValue(replySchema, value);
13
+ if (shapeIssues.length) return ["规划结果需要完整的 plan 与四项 review 结论。", ...shapeIssues];
14
+ const reply = value;
15
+ const issues = [];
16
+ if (!hook.isEnter()) issues.push("当前候选的复检任务尚未进入后续模型请求;请校验候选并读取复检任务后提交。");
17
+ if (hook.state.pending && !isDeepStrictEqual(reply.plan, hook.state.pending)) issues.push("plan 与最近通过校验的候选不一致;请校验修改后的完整计划并复检。");
18
+ const ids = new Set(reply.plan.units.map((unit) => unit.id));
19
+ const reviewKeys = Object.keys(PLAN_REVIEW_LABELS);
20
+ for (const key of reviewKeys) {
21
+ const review = reply.review[key];
22
+ if (!review) {
23
+ issues.push(`review.${key} 缺失;请提供该项复检结论。`);
24
+ continue;
25
+ }
26
+ if (!review.evidence.trim()) issues.push(`review.${key}.evidence 为空;请提供需求依据与实际节点关系的核对结论。`);
27
+ if (!review.nodeIds.length) issues.push(`review.${key}.nodeIds 为空;请引用本项核对的区域。`);
28
+ for (const id of review.nodeIds) if (!ids.has(id)) issues.push(`review.${key}.nodeIds 引用了不存在的区域 ${id};请引用当前计划节点。`);
29
+ }
30
+ if (!allowUnresolved && reply.review.unresolvedIssues.length) issues.push(...reply.review.unresolvedIssues.map((issue) => `布局复检未解决:${issue}`));
31
+ return issues;
32
+ };
33
+ const hook = injectMessageWithTool(agent, TOOL_NAMES.validatePlan, {
34
+ toolOutputSchema: VALIDATE_PLAN_SCHEMA,
35
+ when: (r) => r?.valid === true,
36
+ message: (r, exec, decision, state) => {
37
+ const task = buildPlanReviewPrompt(evidence, state.pending, state.round);
38
+ return createUserMessage({
39
+ content: [{
40
+ type: "text",
41
+ text: task
42
+ }],
43
+ source: {
44
+ kind: "ad-form-plan-review",
45
+ form: "notice",
46
+ summary: `布局复检任务(候选 ${state.round})`
47
+ }
48
+ });
49
+ },
50
+ guard: { check: (output) => {
51
+ return checkReview(output, true);
52
+ } }
53
+ });
54
+ return {
55
+ checkReview,
56
+ dispose: hook.dispose
57
+ };
58
+ };
59
+ //#endregion
60
+ export { mountPlanReview };
@@ -0,0 +1,21 @@
1
+ import { PLAN_REVIEW_SPEC } from "../plan/review-spec.js";
2
+ import { PLAN_SPEC } from "../plan/spec.js";
3
+ import { valueSchemaSpecToJsonSchema } from "@deepseek-ai/dsh-tools";
4
+ //#region src/agents/plan-schema.ts
5
+ var PLAN_REPLY_SPEC = {
6
+ type: "object",
7
+ additionalProperties: false,
8
+ properties: {
9
+ plan: {
10
+ ...PLAN_SPEC,
11
+ required: true
12
+ },
13
+ review: {
14
+ ...PLAN_REVIEW_SPEC,
15
+ required: true
16
+ }
17
+ }
18
+ };
19
+ var PLAN_REPLY_SCHEMA = valueSchemaSpecToJsonSchema(PLAN_REPLY_SPEC);
20
+ //#endregion
21
+ export { PLAN_REPLY_SCHEMA, PLAN_REPLY_SPEC };
@@ -0,0 +1,80 @@
1
+ import { buildPlanPrompt, buildPlanReviewEvidence } from "../prompt/plan.js";
2
+ import { PLAN_PRESET_ID } from "./plan-preset.js";
3
+ import { extractText } from "./util.js";
4
+ import { mountPlanReview } from "./plan-review.js";
5
+ import { PLAN_REPLY_SCHEMA } from "./plan-schema.js";
6
+ import { SessionId } from "@deepseek-ai/dsh-session";
7
+ import { randomUUID } from "node:crypto";
8
+ import { addAbortListener } from "node:events";
9
+ //#region src/agents/plan.ts
10
+ /** 在独立子会话中等待布局计划与复检记录。 */
11
+ async function runPlanSubagent(ctx, parent, signal, input, label) {
12
+ const [prompt, reviewEvidence] = await Promise.all([buildPlanPrompt(input), buildPlanReviewEvidence(input)]);
13
+ signal.throwIfAborted();
14
+ const childId = SessionId(randomUUID());
15
+ const reviewBinding = bindPlanReview(ctx, childId, reviewEvidence);
16
+ let run;
17
+ let cancellation;
18
+ try {
19
+ run = await ctx.subagents.startActivation({
20
+ provider: "spawn",
21
+ childId,
22
+ label: label ?? "布局规划",
23
+ request: {
24
+ agentPreset: PLAN_PRESET_ID,
25
+ prompt: [{
26
+ type: "text",
27
+ text: prompt
28
+ }],
29
+ parent,
30
+ outputSchema: PLAN_REPLY_SCHEMA
31
+ },
32
+ signal,
33
+ delivery: "caller"
34
+ });
35
+ cancellation = cancelPlanOnAbort(ctx, run, signal);
36
+ const review = reviewBinding.current();
37
+ if (!review) return {
38
+ stopReason: "error",
39
+ reviewIssues: ["当前规划执行未提供本地子会话,无法触发布局复检;新计划未保存。"],
40
+ text: ""
41
+ };
42
+ const result = await run.result;
43
+ return {
44
+ stopReason: result.stopReason,
45
+ structured: result.structured,
46
+ reviewIssues: review.checkReview(result.structured),
47
+ text: extractText(result.output),
48
+ diagnostic: result.diagnostic
49
+ };
50
+ } finally {
51
+ cancellation?.[Symbol.dispose]();
52
+ try {
53
+ await run?.dispose();
54
+ } finally {
55
+ reviewBinding.dispose();
56
+ }
57
+ }
58
+ }
59
+ function bindPlanReview(ctx, childId, evidence) {
60
+ let review;
61
+ const unwatch = ctx.on("agent/created", ({ agent }) => {
62
+ if (agent.id === childId) review = mountPlanReview(agent, evidence, PLAN_REPLY_SCHEMA);
63
+ });
64
+ return {
65
+ current: () => review,
66
+ dispose: () => {
67
+ unwatch();
68
+ review?.dispose();
69
+ }
70
+ };
71
+ }
72
+ function cancelPlanOnAbort(ctx, run, signal) {
73
+ return addAbortListener(signal, () => {
74
+ run.dispose().catch((error) => {
75
+ ctx.logger("ad-form-agent").error("规划子会话中断清理失败:", error);
76
+ });
77
+ });
78
+ }
79
+ //#endregion
80
+ export { runPlanSubagent };
@@ -0,0 +1,16 @@
1
+ //#region src/agents/util.ts
2
+ function extractText(blocks = []) {
3
+ return blocks.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
4
+ }
5
+ /**
6
+ * 从任务描述中提取精炼的短标题(用于 dsh label 展示),剥离 Markdown 与换行并优先取首句。
7
+ */
8
+ function cleanTaskTitle(text, fallback = "直接构建", maxLen = 14) {
9
+ if (!text || !text.trim()) return fallback;
10
+ const clean = text.replace(/^#+\s+/gm, "").replace(/^[-*+]\s+/gm, "").replace(/[`*_~]/g, "").replace(/[\r\n\t]+/g, " ").trim();
11
+ const firstSentence = clean.split(/[,。,;;!!??\n]/)[0]?.trim() || clean;
12
+ if (firstSentence.length <= maxLen) return firstSentence;
13
+ return `${firstSentence.slice(0, maxLen)}…`;
14
+ }
15
+ //#endregion
16
+ export { cleanTaskTitle, extractText };
@@ -0,0 +1,39 @@
1
+ import { BUTTON_TAG, CATEGORY_TAG, DATAFROM_TAG, FIELDRRN_TAG, FORMRRN_TAG, IMAGE_TAG, ISAUTHORITY_TAG, ISUSEDEFAULT_TAG, LABEL_TAG, LABEL_ZH_TAG, NAME_TAG, SEPARATOR_TAG, SEQNO_TAG, STYLE_TAG, TABLERRN_TAG, TABRRN_TAG } from "../../xml-tags.js";
2
+ import { XmlNode } from "../../utils/xml-builder.js";
3
+ import { toXmlBoolean } from "../../utils/normalizer.js";
4
+ import { generateNodeId } from "../../utils/id.js";
5
+ import { appendBaseMetadata } from "../../xml-common.js";
6
+ import { defineIr2Xml } from "../../registry.js";
7
+ //#region src/converter/components/actions/button.ts
8
+ /**
9
+ * 构造 <ADBUTTON> 骨架标签
10
+ */
11
+ defineIr2Xml("action:button", (node, ctx) => {
12
+ const xml = new XmlNode(BUTTON_TAG);
13
+ appendBaseMetadata(xml, ctx, generateNodeId(node));
14
+ const formRrn = ctx.currentForm?.uniqueId;
15
+ const tableRrn = ctx.currentTable?.uniqueId;
16
+ const tabRrn = ctx.currentTab?.uniqueId;
17
+ const fieldRrn = ctx.currentField?.uniqueId;
18
+ if (fieldRrn) {
19
+ xml.createRequiredChild(FIELDRRN_TAG, fieldRrn);
20
+ xml.createRequiredChild(TABLERRN_TAG, tableRrn);
21
+ } else if (tabRrn) {
22
+ xml.createRequiredChild(TABRRN_TAG, tabRrn);
23
+ xml.createRequiredChild(TABLERRN_TAG, tableRrn);
24
+ } else xml.createRequiredChild(FORMRRN_TAG, formRrn);
25
+ xml.createRequiredChild(NAME_TAG, node.id);
26
+ xml.createChildIfPresent(LABEL_TAG, node.label);
27
+ xml.createChildIfPresent(LABEL_ZH_TAG, node.labelZh);
28
+ xml.createChildIfPresent(CATEGORY_TAG, node.action?.placement === "collection" ? "Block" : "");
29
+ xml.createChildIfPresent(IMAGE_TAG, node.action?.iconSymbol);
30
+ xml.createChildIfPresent(SEQNO_TAG, node.layout?.sequenceOrder);
31
+ xml.createChildIfPresent(ISUSEDEFAULT_TAG, toXmlBoolean(node.action?.useStandardHandler ?? true));
32
+ xml.createChildIfPresent(ISAUTHORITY_TAG, toXmlBoolean(node.action?.requiresPermission ?? false));
33
+ xml.createChildIfPresent(SEPARATOR_TAG, toXmlBoolean(node.action?.isSeparator ?? false));
34
+ xml.createRequiredChild(STYLE_TAG, "0");
35
+ xml.createChildIfPresent(DATAFROM_TAG, node.action?.dataContextSource);
36
+ return xml;
37
+ });
38
+ //#endregion
39
+ export {};
@@ -0,0 +1,2 @@
1
+ import "./button.js";
2
+ export {};
@@ -0,0 +1,14 @@
1
+ import { FIELD_TABLE_TAG, NAME_TAG, REFERENCERULE_TAG } from "../../xml-tags.js";
2
+ import { buildCommonField, buildTable } from "../../xml-common.js";
3
+ import { defineIr2Xml } from "../../registry.js";
4
+ //#region src/converter/components/composites/entity-form.ts
5
+ defineIr2Xml("composite:entity-form", (node, ctx) => {
6
+ const xml = buildCommonField(node, ctx);
7
+ const fieldTable = buildTable(node, ctx);
8
+ fieldTable.tag = FIELD_TABLE_TAG;
9
+ xml.createOrReplaceChild(REFERENCERULE_TAG, fieldTable.findChild(NAME_TAG)?.getText());
10
+ xml.addChild(fieldTable);
11
+ return xml;
12
+ });
13
+ //#endregion
14
+ export {};
@@ -0,0 +1,24 @@
1
+ import { FIELD_TABLE_TAG, NAME_TAG, REFERENCERULE_TAG } from "../../xml-tags.js";
2
+ import { toXmlBoolean_YN } from "../../utils/normalizer.js";
3
+ import { buildCommonField, buildTable } from "../../xml-common.js";
4
+ import { defineIr2Xml } from "../../registry.js";
5
+ //#region src/converter/components/composites/filter-table.ts
6
+ defineIr2Xml("composite:filter-table", (node, ctx) => {
7
+ const xml = buildCommonField(node, ctx);
8
+ const fieldTable = buildTable(node, ctx);
9
+ fieldTable.tag = FIELD_TABLE_TAG;
10
+ xml.createOrReplaceChild(REFERENCERULE_TAG, fieldTable.findChild(NAME_TAG)?.getText());
11
+ xml.addChild(fieldTable);
12
+ ctx.collectFormatAttribute(node, "ShowCondition", toXmlBoolean_YN(node.props?.showCondition));
13
+ ctx.collectFormatAttribute(node, "ShowQueryButton", toXmlBoolean_YN(node.props?.showQueryButton));
14
+ ctx.collectFormatAttribute(node, "ShowProgressPanel", toXmlBoolean_YN(node.props?.showProgressPanel));
15
+ ctx.collectFormatAttribute(node, "ShowCount", toXmlBoolean_YN(node.props?.showCount));
16
+ ctx.collectFormatAttribute(node, "IsCustomQuery", toXmlBoolean_YN(node.props?.isCustomQuery));
17
+ ctx.collectFormatAttribute(node, "QueryTimeOut", node.props?.queryTimeOut);
18
+ ctx.collectFormatAttribute(node, "ShowCheckBox", toXmlBoolean_YN(node.props?.showCheckBox));
19
+ ctx.collectFormatAttribute(node, "ShowIndex", toXmlBoolean_YN(node.props?.showRowIndex));
20
+ ctx.collectFormatAttribute(node, "ItemAdapter", node.props?.itemAdapter);
21
+ return xml;
22
+ });
23
+ //#endregion
24
+ export {};
@@ -0,0 +1,3 @@
1
+ import "./entity-form.js";
2
+ import "./filter-table.js";
3
+ export {};