@wubaoqi/guancopilot 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/NOTICE.md +17 -0
  2. package/README.md +146 -2
  3. package/assets/coreutils.wasm +0 -0
  4. package/assets/find.wasm +0 -0
  5. package/assets/guanbi.wasm +4 -0
  6. package/assets/guancli.wasm +0 -0
  7. package/assets/guanhelm.wasm +0 -0
  8. package/assets/jq.wasm +0 -0
  9. package/assets/openskills.wasm +0 -0
  10. package/assets/rg.wasm +0 -0
  11. package/assets/sed.wasm +0 -0
  12. package/bin/guancopilot +0 -0
  13. package/bin/guanvm +0 -0
  14. package/bin/platforms.cjs +6 -0
  15. package/bin/run.cjs +39 -0
  16. package/bin/runtime.cjs +44 -0
  17. package/licenses/Go-LICENSE +27 -0
  18. package/licenses/browser-_speed-highlight_core-LICENSE +121 -0
  19. package/licenses/browser-_speed-highlight_core-package.json +14 -0
  20. package/licenses/browser-dompurify-LICENSE +202 -0
  21. package/licenses/browser-dompurify-LICENSE-MPL +373 -0
  22. package/licenses/browser-dompurify-package.json +10 -0
  23. package/licenses/browser-marked-LICENSE +44 -0
  24. package/licenses/browser-marked-package.json +10 -0
  25. package/licenses/coreutils-LICENSE +18 -0
  26. package/licenses/findutils-LICENSE +18 -0
  27. package/licenses/github.com_BurntSushi_toml_v1.6.0-COPYING +21 -0
  28. package/licenses/github.com_dustin_go-humanize_v1.0.1-LICENSE +21 -0
  29. package/licenses/github.com_google_jsonschema-go_v0.4.3-LICENSE +21 -0
  30. package/licenses/github.com_google_uuid_v1.6.0-LICENSE +27 -0
  31. package/licenses/github.com_jackc_pgpassfile_v1.0.0-LICENSE +22 -0
  32. package/licenses/github.com_jackc_pgservicefile_v0.0.0-20240606120523-5a60cdf6a761-LICENSE +22 -0
  33. package/licenses/github.com_jackc_pgx_v5_v5.11.0-LICENSE +22 -0
  34. package/licenses/github.com_jackc_puddle_v2_v2.2.2-LICENSE +22 -0
  35. package/licenses/github.com_mattn_go-isatty_v0.0.20-LICENSE +9 -0
  36. package/licenses/github.com_modelcontextprotocol_go-sdk_v1.8.0-LICENSE +216 -0
  37. package/licenses/github.com_ncruces_go-strftime_v1.0.0-LICENSE +21 -0
  38. package/licenses/github.com_remyoudompheng_bigfft_v0.0.0-20230129092748-24d4a6f8daec-LICENSE +27 -0
  39. package/licenses/github.com_santhosh-tekuri_jsonschema_v6_v6.0.3-LICENSE +175 -0
  40. package/licenses/github.com_segmentio_asm_v1.1.3-LICENSE +21 -0
  41. package/licenses/github.com_segmentio_encoding_v0.5.4-LICENSE +21 -0
  42. package/licenses/github.com_tetratelabs_wazero_v1.12.0-LICENSE +201 -0
  43. package/licenses/github.com_tetratelabs_wazero_v1.12.0-NOTICE +2 -0
  44. package/licenses/github.com_yosida95_uritemplate_v3_v3.0.2-LICENSE +25 -0
  45. package/licenses/golang.org_x_image_v0.44.0-LICENSE +27 -0
  46. package/licenses/golang.org_x_net_v0.58.0-LICENSE +27 -0
  47. package/licenses/golang.org_x_oauth2_v0.36.0-LICENSE +27 -0
  48. package/licenses/golang.org_x_sync_v0.22.0-LICENSE +27 -0
  49. package/licenses/golang.org_x_sys_v0.47.0-LICENSE +27 -0
  50. package/licenses/golang.org_x_text_v0.41.0-LICENSE +27 -0
  51. package/licenses/golang.org_x_time_v0.15.0-LICENSE +27 -0
  52. package/licenses/guanbi-skills-LICENSE +133 -0
  53. package/licenses/guanbi-skills-LICENSE.README.md +28 -0
  54. package/licenses/guanbi-skills-LICENSE.zh-CN +82 -0
  55. package/licenses/jq-COPYING +176 -0
  56. package/licenses/modernc.org_libc_v1.73.4-LICENSE +27 -0
  57. package/licenses/modernc.org_libc_v1.73.4-LICENSE-3RD-PARTY.md +305 -0
  58. package/licenses/modernc.org_mathutil_v1.7.1-LICENSE +27 -0
  59. package/licenses/modernc.org_memory_v1.11.0-LICENSE +27 -0
  60. package/licenses/modernc.org_memory_v1.11.0-LICENSE-GO +27 -0
  61. package/licenses/modernc.org_memory_v1.11.0-LICENSE-LOGO +1 -0
  62. package/licenses/modernc.org_memory_v1.11.0-LICENSE-MMAP-GO +25 -0
  63. package/licenses/modernc.org_sqlite_v1.53.0-LICENSE +26 -0
  64. package/licenses/mvdan.cc_sh_v3_v3.13.1-LICENSE +27 -0
  65. package/licenses/ripgrep-COPYING +3 -0
  66. package/licenses/ripgrep-LICENSE-MIT +21 -0
  67. package/licenses/sed-LICENSE +21 -0
  68. package/manifest.json +972 -0
  69. package/package.json +30 -4
  70. package/plugin/guancopilot.js +193 -0
  71. package/skills-bundle/.guanvm-skills-bundle +0 -0
  72. package/skills-bundle/_recipes/dashboard/gates/page_check.js +16 -0
  73. package/skills-bundle/_recipes/dashboard/gates/report_check.js +4 -0
  74. package/skills-bundle/_recipes/dashboard/knowledge/01.md +1 -0
  75. package/skills-bundle/_recipes/dashboard/knowledge/02.md +1 -0
  76. package/skills-bundle/_recipes/dashboard/knowledge/03.md +1 -0
  77. package/skills-bundle/_recipes/dashboard/knowledge/04.md +1 -0
  78. package/skills-bundle/_recipes/dashboard/knowledge/05.md +1 -0
  79. package/skills-bundle/_recipes/dashboard/knowledge/06.md +1 -0
  80. package/skills-bundle/_recipes/dashboard/template.json +41 -0
  81. package/skills-bundle/_recipes/etl/gates/etl_live_check.js +10 -0
  82. package/skills-bundle/_recipes/etl/gates/etl_report_check.js +3 -0
  83. package/skills-bundle/_recipes/etl/knowledge/01.md +1 -0
  84. package/skills-bundle/_recipes/etl/knowledge/02.md +9 -0
  85. package/skills-bundle/_recipes/etl/knowledge/03.md +1 -0
  86. package/skills-bundle/_recipes/etl/knowledge/04.md +1 -0
  87. package/skills-bundle/_recipes/etl/knowledge/05.md +1 -0
  88. package/skills-bundle/_recipes/etl/template.json +39 -0
  89. package/skills-bundle/_recipes/hints.json +46 -0
  90. package/skills-bundle/guancli/.commandface.json +155 -0
  91. package/skills-bundle/guancli/SKILL.md +342 -0
  92. package/skills-bundle/guancli/evals/evals.json +156 -0
  93. package/skills-bundle/guancli/evals/fixtures/metric-candidate-empty-search.json +13 -0
  94. package/skills-bundle/guancli/evals/fixtures/metric-candidate-prior-request.json +13 -0
  95. package/skills-bundle/guancli/evals/fixtures/metric-consumption-columns.json +46 -0
  96. package/skills-bundle/guancli/evals/fixtures/metric-consumption-metadata.json +36 -0
  97. package/skills-bundle/guancli/evals/fixtures/metric-consumption-query.json +18 -0
  98. package/skills-bundle/guancli/references/analysis-primitives.md +95 -0
  99. package/skills-bundle/guancli/references/auth-and-config.md +131 -0
  100. package/skills-bundle/guancli/references/examples/metric-date-in.json +7 -0
  101. package/skills-bundle/guancli/references/examples/metric-query-rows.py +83 -0
  102. package/skills-bundle/guancli/references/examples/metric-query.sh +6 -0
  103. package/skills-bundle/guancli/references/form-chatbi.md +199 -0
  104. package/skills-bundle/guancli/references/gateway.md +148 -0
  105. package/skills-bundle/guancli/references/metric-batch-query.md +82 -0
  106. package/skills-bundle/guancli/references/metric-commands.md +562 -0
  107. package/skills-bundle/guancli/references/metric-generic-query.md +215 -0
  108. package/skills-bundle/guancli/references/metric-json-migration.md +18 -0
  109. package/skills-bundle/guancli/references/metric-query-recipes.md +358 -0
  110. package/skills-bundle/guancli/references/preview-and-output.md +192 -0
  111. package/skills-bundle/guancli/references/resource-query.md +101 -0
  112. package/skills-bundle/guands/SKILL.md +281 -0
  113. package/skills-bundle/guands/references/calc-fields-boundaries-and-pitfalls.md +160 -0
  114. package/skills-bundle/guands/references/command-reference.md +267 -0
  115. package/skills-bundle/guands/references/incremental-and-schedule.md +157 -0
  116. package/skills-bundle/guands/references/workflows.md +256 -0
  117. package/skills-bundle/guanetl/SKILL.md +391 -0
  118. package/skills-bundle/guanetl/evals/evals.json +41 -0
  119. package/skills-bundle/guanetl/references/ETL_AI_DEVELOP.md +456 -0
  120. package/skills-bundle/guanmetric/SKILL.md +144 -0
  121. package/skills-bundle/guanmetric/evals/evals.json +117 -0
  122. package/skills-bundle/guanmetric/evals/fixtures/atomic-detail-read-model.json +18 -0
  123. package/skills-bundle/guanmetric/evals/fixtures/confirmed-template-summary.json +12 -0
  124. package/skills-bundle/guanmetric/evals/fixtures/create-result-unknown-state.json +13 -0
  125. package/skills-bundle/guanmetric/evals/forward-eval-2026-09-21.json +62 -0
  126. package/skills-bundle/guanmetric/references/metric-api-contract-examples.json +690 -0
  127. package/skills-bundle/guanmetric/references/metric-api-contract.schema.json +349 -0
  128. package/skills-bundle/guanmetric/references/metric-api-contracts.md +436 -0
  129. package/skills-bundle/guanmetric/references/metric-atomic-mutation.md +238 -0
  130. package/skills-bundle/guanmetric/references/metric-batch-status.md +71 -0
  131. package/skills-bundle/guanmetric/references/metric-business-dictionary-api-contract-examples.json +53 -0
  132. package/skills-bundle/guanmetric/references/metric-business-dictionary-api-contract.schema.json +26 -0
  133. package/skills-bundle/guanmetric/references/metric-business-dictionary.md +76 -0
  134. package/skills-bundle/guanmetric/references/metric-common-fields.md +246 -0
  135. package/skills-bundle/guanmetric/references/metric-composite-mutation.md +165 -0
  136. package/skills-bundle/guanmetric/references/metric-delete-mutation.md +70 -0
  137. package/skills-bundle/guanmetric/references/metric-derived-mutation.md +453 -0
  138. package/skills-bundle/guanmetric/references/metric-excel-template.md +365 -0
  139. package/skills-bundle/guanmetric/references/metric-expression-rules.md +146 -0
  140. package/skills-bundle/guanmetric/references/metric-flow-generate-example.json +79 -0
  141. package/skills-bundle/guanmetric/references/metric-flow-generate.schema.json +93 -0
  142. package/skills-bundle/guanmetric/references/metric-flow.md +218 -0
  143. package/skills-bundle/guanmetric/references/metric-hierarchy-api-contract-examples.json +171 -0
  144. package/skills-bundle/guanmetric/references/metric-hierarchy-api-contract.schema.json +167 -0
  145. package/skills-bundle/guanmetric/references/metric-hierarchy-api-contracts.md +193 -0
  146. package/skills-bundle/guanmetric/references/metric-mutation.md +155 -0
  147. package/skills-bundle/guanmetric/references/metric-public-dimension-api-contract-examples.json +62 -0
  148. package/skills-bundle/guanmetric/references/metric-public-dimension-api-contract.schema.json +47 -0
  149. package/skills-bundle/guanmetric/references/metric-public-dimension.md +155 -0
  150. package/skills-bundle/guanmetric/references/metric-tree-api-contract-examples.json +277 -0
  151. package/skills-bundle/guanmetric/references/metric-tree-api-contract.schema.json +263 -0
  152. package/skills-bundle/guanmetric/references/metric-tree-api-contracts.md +53 -0
  153. package/skills-bundle/guanmetric/references/metric-tree-mutation.md +500 -0
  154. package/skills-bundle/guanmetric/references/metric-validation-ownership.md +74 -0
  155. package/skills-bundle/guanvis/SKILL.md +333 -0
  156. package/skills-bundle/guanvis/evals/china_map/card_01_basic_map.js +13 -0
  157. package/skills-bundle/guanvis/evals/china_map/card_02_world_map.js +10 -0
  158. package/skills-bundle/guanvis/evals/china_map/card_03_point_map.js +12 -0
  159. package/skills-bundle/guanvis/evals/china_map/page.js +10 -0
  160. package/skills-bundle/guanvis/evals/china_map/schema.js +10 -0
  161. package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/README.md +30 -0
  162. package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/card_01_comparative_mvp.js +72 -0
  163. package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/page.js +6 -0
  164. package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/schema.js +22 -0
  165. package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/verify_default_roundtrip.sh +92 -0
  166. package/skills-bundle/guanvis/evals/complex_report_pro/card_01_monthly.js +63 -0
  167. package/skills-bundle/guanvis/evals/complex_report_pro/page.js +6 -0
  168. package/skills-bundle/guanvis/evals/complex_report_pro/schema.js +6 -0
  169. package/skills-bundle/guanvis/evals/custom_chart_echarts/card_01_bar.js +13 -0
  170. package/skills-bundle/guanvis/evals/custom_chart_echarts/card_02_pie.js +13 -0
  171. package/skills-bundle/guanvis/evals/custom_chart_echarts/charts/bar.js +11 -0
  172. package/skills-bundle/guanvis/evals/custom_chart_echarts/charts/pie.js +15 -0
  173. package/skills-bundle/guanvis/evals/custom_chart_echarts/page.js +5 -0
  174. package/skills-bundle/guanvis/evals/custom_chart_echarts/schema.js +9 -0
  175. package/skills-bundle/guanvis/evals/custom_chart_sdk/card_01_level_nodes.js +19 -0
  176. package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.css +51 -0
  177. package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.html +1 -0
  178. package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.js +28 -0
  179. package/skills-bundle/guanvis/evals/custom_chart_sdk/page.js +5 -0
  180. package/skills-bundle/guanvis/evals/custom_chart_sdk/schema.js +7 -0
  181. package/skills-bundle/guanvis/evals/dynamic_fields/card_01_dynamic_dataset.js +20 -0
  182. package/skills-bundle/guanvis/evals/dynamic_fields/card_02_dynamic_metric_chart.js +16 -0
  183. package/skills-bundle/guanvis/evals/dynamic_fields/metrics.js +19 -0
  184. package/skills-bundle/guanvis/evals/dynamic_fields/page.js +9 -0
  185. package/skills-bundle/guanvis/evals/dynamic_fields/schema.js +7 -0
  186. package/skills-bundle/guanvis/evals/dynamic_fields/verify_default_roundtrip.sh +137 -0
  187. package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/README.md +26 -0
  188. package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/card_01_percentage_advcalc.js +44 -0
  189. package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/card_02_scroll_percentage.js +12 -0
  190. package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/page.js +6 -0
  191. package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/schema.js +22 -0
  192. package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/README.md +28 -0
  193. package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/card_01_rank_advcalc.js +59 -0
  194. package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/page.js +6 -0
  195. package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/schema.js +22 -0
  196. package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/verify_default_roundtrip.sh +135 -0
  197. package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/README.md +15 -0
  198. package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/card_01_running_total_advcalc.js +74 -0
  199. package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/page.js +6 -0
  200. package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/schema.js +22 -0
  201. package/skills-bundle/guanvis/evals/sales_dashboard/card_01_revenue_column.js +10 -0
  202. package/skills-bundle/guanvis/evals/sales_dashboard/card_02_trend_line.js +9 -0
  203. package/skills-bundle/guanvis/evals/sales_dashboard/card_03_kpi.js +6 -0
  204. package/skills-bundle/guanvis/evals/sales_dashboard/card_04_pie.js +9 -0
  205. package/skills-bundle/guanvis/evals/sales_dashboard/card_05_calc_field_test.js +12 -0
  206. package/skills-bundle/guanvis/evals/sales_dashboard/page.js +11 -0
  207. package/skills-bundle/guanvis/evals/sales_dashboard/schema.js +14 -0
  208. package/skills-bundle/guanvis/evals/sales_dashboard/selector_01_region.js +10 -0
  209. package/skills-bundle/guanvis/evals/split_charts/card_01_column_split.js +10 -0
  210. package/skills-bundle/guanvis/evals/split_charts/card_02_line_split.js +10 -0
  211. package/skills-bundle/guanvis/evals/split_charts/card_03_combo_split.js +11 -0
  212. package/skills-bundle/guanvis/evals/split_charts/page.js +10 -0
  213. package/skills-bundle/guanvis/evals/split_charts/schema.js +14 -0
  214. package/skills-bundle/guanvis/evals/tab_layout/card_00_total_revenue.js +6 -0
  215. package/skills-bundle/guanvis/evals/tab_layout/card_01_revenue.js +10 -0
  216. package/skills-bundle/guanvis/evals/tab_layout/card_02_trend.js +9 -0
  217. package/skills-bundle/guanvis/evals/tab_layout/card_03_story.js +11 -0
  218. package/skills-bundle/guanvis/evals/tab_layout/page.js +23 -0
  219. package/skills-bundle/guanvis/evals/tab_layout/schema.js +11 -0
  220. package/skills-bundle/guanvis/evals/tab_layout/selector_01_region.js +8 -0
  221. package/skills-bundle/guanvis/references/api-reference.md +476 -0
  222. package/skills-bundle/guanvis/references/builder-reference.md +1676 -0
  223. package/skills-bundle/guanvis/references/chart-properties.md +2101 -0
  224. package/skills-bundle/guanvis/references/checkout-editing.md +53 -0
  225. package/skills-bundle/guanvis/references/complex-report-pro-patterns.md +398 -0
  226. package/skills-bundle/guanvis/references/dir-and-page-management.md +48 -0
  227. package/skills-bundle/guanvis/references/metric-chart-reference.md +258 -0
  228. package/skills-bundle/guanvis/references/publish-and-constraints.md +60 -0
  229. package/skills-bundle/guanvis/references/selector-reference.md +431 -0
  230. package/skills-bundle/guanvis/references/tableau-migration.md +73 -0
  231. package/skills-bundle/guanvis/references/theme.md +123 -0
  232. package/skills-bundle/guanvis/references/troubleshooting.md +25 -0
  233. package/skills-bundle/guanvis/references/validation-and-chart-patterns.md +205 -0
  234. package/skills-bundle/guanwf/SKILL.md +543 -0
  235. package/skills-bundle/guanwf/references/ETL_AI_DEVELOP.md +456 -0
  236. package/skills-bundle/guanwf/references/TASK_NODE_CONTRACTS.md +64 -0
  237. package/skills-bundle/guanwf/references/WORKFLOW_DSL.md +536 -0
  238. package/skills-bundle/guanwf/references/WORKFLOW_NODES.md +166 -0
  239. package/skills-bundle/js/SKILL.md +145 -0
@@ -0,0 +1,192 @@
1
+ # guancli 数据预览、卡片预览与输出格式
2
+
3
+ ## 4. 预览数据集数据
4
+
5
+ ```bash
6
+ guancli ds preview <ds_id> # 预览数据集数据 (表格格式)
7
+ guancli ds preview <ds_id> --limit 20 # 限制预览行数
8
+ guancli ds preview <ds_id> --raw # 输出原始 JSON
9
+ guancli ds execute-sql -inputs <ds_id> -sql 'SELECT * FROM `数据集名称` LIMIT 20' # 用 SQL 查询数据集(需目标 BI 满足 8.2.0-hf12+,并在 BI 管理后台 - 域设置打开高级 SQL 查询开关)
10
+ guancli ds execute-sql -inputs <ds_id> --sql-file query.sql # 从文件读取 SQL
11
+ guancli ds execute-sql -inputs <ds_id> --sql-file - < query.sql # 从 stdin 读取 SQL
12
+ # SQL 中请使用数据集名称作为临时表名;名称包含中文、空格或特殊字符时,请使用反引号包裹。可先执行 `ds get <ds_id> --brief` 查看数据集名称和字段列表。
13
+ `execute-sql` 的旧版 public-api fallback 不支持 disable-cache;`--limit` 在非 raw 输出渲染前本地截断,`--raw` 保持后端原始响应。
14
+ ```
15
+
16
+ 程序比对结果时用 `-f json --typed`:NULL 输出 `null`,数值列(按后端 `columns[].fdType`)输出 JSON 数字(原样保留后端的数字文本,长整数和小数位不丢)。不加 `--typed` 的 `-f json` 保持旧格式:所有值都是字符串、NULL 为空串 `""`,分不清 NULL、空串与数字。
17
+
18
+ `--sql` 与 `--sql-file` 二选一。SQL 较长、包含多层引号或由模型生成时,优先写入 `.sql` 文件再传 `--sql-file`;传 `--sql-file -` 时从 stdin 读取,不会把终端中的普通空输入当作 SQL。
19
+
20
+ 数据集 ID (dsId) 可通过 `ds tree` 或 `ds search` 获取。
21
+
22
+ 如果用户给的是业务目录名而不是数据集名,优先先 `ds tree` 定位目录,再在目录内按真实表名搜索,或从已有 `page/card` 反查 `dsId`。
23
+
24
+ ### 带筛选条件预览
25
+
26
+ 通过 `--filter` 参数传入筛选条件,每个 `--filter` 值的格式为 `"列名 操作符 [值]"`。
27
+ 列名中包含空格时无需特殊处理,解析器会智能定位操作符。
28
+
29
+ ```bash
30
+ guancli ds preview <ds_id> --filter "name EQ 张三"
31
+ guancli ds preview <ds_id> --filter "age GT 18" --filter "city IN 北京,上海,广州"
32
+ guancli ds preview <ds_id> --filter "score BT 60,100"
33
+ guancli ds preview <ds_id> --filter "status IS_NULL"
34
+ guancli ds preview <ds_id> --filter "销售 金额 GT 100" --combine-type OR
35
+ ```
36
+
37
+ 支持的操作符:
38
+ - 比较:`EQ`(等于)、`NE`(不等于)、`LT`(小于)、`LE`(小于等于)、`GT`(大于)、`GE`(大于等于)
39
+ - 区间:`BT`(between,两个值逗号分隔)
40
+ - 集合:`IN`(多值逗号分隔)
41
+ - 空值:`IS_NULL`、`NOT_NULL`
42
+ - 字符串:`CONTAINS`、`NOT_CONTAINS`、`STARTSWITH`、`NOT_STARTSWITH`、`ENDSWITH`、`NOT_ENDSWITH`
43
+
44
+ `--combine-type` 控制多条件组合方式,默认 `AND`,可设为 `OR`。
45
+ 字段类型会自动从数据集 schema 推断,无需手动指定。
46
+
47
+ ### 日期粒度筛选(SUB_DATE)
48
+
49
+ 对 DATE/TIMESTAMP 字段,可用 `toYear`/`toQuarter`/`toMonth`/`toWeek`/`toDate` 修饰符按粒度筛选。
50
+ 语法:`"列名 toGranularity OPERATOR value"`,值使用标准格式,CLI 自动转换为 BI API 格式。
51
+
52
+ ```bash
53
+ guancli card preview <cd_id> --filter "日期字段 toQuarter IN 2026-Q1"
54
+ guancli card preview <cd_id> --filter "日期字段 toQuarter IN 2026-Q1,2026-Q2"
55
+ guancli card preview <cd_id> --filter "日期字段 toYear EQ 2026"
56
+ guancli card preview <cd_id> --filter "日期字段 toMonth EQ 2026-01"
57
+ guancli card preview <cd_id> --filter "日期字段 toWeek EQ 2026-W01"
58
+ guancli card preview <cd_id> --filter "日期字段 toDate EQ 2026-01-15"
59
+ ```
60
+
61
+ 值格式规范:
62
+
63
+ | 粒度 | 修饰符 | 值格式 | 示例 |
64
+ |------|--------|--------|------|
65
+ | 年 | `toYear` | `YYYY` | `2026` |
66
+ | 季度 | `toQuarter` | `YYYY-QN` | `2026-Q1` |
67
+ | 月 | `toMonth` | `YYYY-MM` | `2026-01` |
68
+ | 周 | `toWeek` | `YYYY-WNN` 或 `YYYY WNN` | `2026-W01` |
69
+ | 日期 | `toDate` | `YYYY-MM-DD` | `2026-01-15` |
70
+
71
+ 可配合 `--filter "维度字段 EQ 值"` 同时使用多个筛选条件。
72
+
73
+ ### 排序和列筛选
74
+
75
+ 所有 preview 命令(ds/card)都支持排序和列筛选:
76
+
77
+ ```bash
78
+ guancli ds preview <ds_id> --sort-asc name # 按 name 升序 (API 层面排序)
79
+ guancli ds preview <ds_id> --sort-desc id # 按 id 降序 (API 层面排序)
80
+ guancli ds preview <ds_id> --columns "id,name,status" # 只显示指定列
81
+ guancli ds preview <ds_id> --filter "status EQ FAILED" --sort-desc id --columns "id,task_name"
82
+ ```
83
+
84
+ - `--sort-asc` / `--sort-desc`: 互斥,只能指定一个列。ds preview 的排序通过 API 在数据库层面执行;card preview 的排序在 Go 端对本次取数范围执行,排序取数下限为 10000 行,若卡片总行数超过本次取数范围,不承诺全量 Top N。
85
+ - `--columns`: 逗号分隔的列名列表,只显示指定列(Go 端执行)。
86
+
87
+ ## 5. 获取卡片数据
88
+
89
+ ```bash
90
+ guancli card get <cd_id> # 获取卡片元信息
91
+ guancli card preview <cd_id> # 预览卡片数据 (图表默认最多 10000 行;选择器未排序时保留服务端默认)
92
+ guancli card preview <cd_id> --limit 20 # 限制预览行数
93
+ guancli card preview <cd_id> -f csv # 导出 CSV 到 stdout
94
+ guancli card preview <cd_id> -f csv -o card.csv # 导出 CSV 到文件
95
+ guancli card preview <cd_id> -f excel -o card.xls # 导出 Excel 可打开文件
96
+ guancli card preview <cd_id> --value-format raw -f csv # 保留原始数值,适合 AI 后续计算
97
+ guancli card preview <cd_id> --with-default-filters # 应用所在页面关联选择器的默认条件
98
+ ```
99
+
100
+ 卡片 ID (cdId) 可通过 `page get` 命令查看页面详情获取。
101
+ 图表卡片内部会按 BI 预览接口的分页能力自动取数;选择器/树状选择器仍使用服务端单次返回。图表卡片数值默认使用 `--value-format formatted`,按卡片返回的数值格式输出(小数位、千分位、货币、百分比、单位等);需要保留原始数值用于 AI 后续计算时,使用 `--value-format raw`。无卡片格式时 `--precision` 作为兜底最大精度,默认 6 位。任意卡片预览结果在未指定 `-o/--output` 且超过 1000 行时,默认写入 `card_<cdId>_<timestamp>.<ext>` 文件,避免把大结果直接塞入上下文。该能力不对接 BI 导出任务接口。
102
+
103
+ 当图表卡片返回同环比、日期层级或其他多层列表头时,默认输出和 `-f table` 会逐层显示完整表头。JSON、CSV、Excel 等结构化输出使用 `父级 > 子级 > 叶子` 形式的完整路径作为列名,避免只保留末级标题后出现重名或含义丢失。标题自身包含的每个 `>` 会编码为 `\>`,从而与层级分隔符区分;完整路径仍重复时,后续列会追加稳定后缀(如 ` [2]`),保证结构化键唯一且可被筛选、排序。`--columns` 和 `--sort-*` 优先接受大小写精确的完整路径;为了兼容旧命令,末级标题唯一时仍可使用末级标题,存在同名末级标题时会明确提示改用完整路径。
104
+
105
+ 复杂报表 Pro 卡片会自动切换为 xlsx 下载模式,只支持写入文件,不支持 `--raw`、`-f/--format`、`--limit`、排序、列筛选、精度、数值输出格式、动态参数和动态维度。未指定 `-o/--output` 时默认写入 `complex_report_pro_<cdId>_<timestamp>.xlsx`。
106
+
107
+ ### 带筛选条件预览卡片
108
+
109
+ 卡片 preview 同样支持 `--filter` 参数,语法与数据集 preview 一致(含日期粒度筛选)。
110
+ 筛选条件会通过 API 传递给后端,适用于 CHART、SELECTOR、TREE_SELECTOR 三种卡片类型。复杂报表 Pro 首版也使用 `--filter`,CLI 会基于页面普通选择器的 `asFilter.columnMappings` 自动映射为子卡 `childFilters`;映射不唯一、树/组合筛选器、动态参数 target 等复杂情况会直接报错。
111
+
112
+ ```bash
113
+ guancli card preview <cd_id> --filter "name EQ 张三"
114
+ guancli card preview <cd_id> --filter "age GT 18" --filter "city IN 北京,上海"
115
+ guancli card preview <cd_id> --filter "利润中心 EQ 华南" --filter "季度(日期) toQuarter IN 2026-Q1"
116
+ guancli card preview <complex_report_pro_cd_id> --filter "周 toWeek EQ 2026-W01" -o report.xlsx
117
+ ```
118
+
119
+ 字段类型会自动从卡片关联的数据集 schema 推断。日期粒度筛选需配合 `card get` 查看字段配置中的筛选器字段名和粒度。
120
+
121
+ ### 应用页面关联筛选器的默认条件
122
+
123
+ 图表卡片默认只按卡片自身配置取数,不会隐式继承页面筛选上下文。需要得到与页面首次打开时一致的结果,可显式传入 `--with-default-filters`。CLI 会读取卡片所属页面,优先找出通过 `asFilter.columnMappings` 关联到该卡片的选择器;若选择器启用 `autoLink`(或 `asFilter` 未显式关闭 autoLink),则按选择器源字段与目标卡片字段的同名匹配推断目标字段,并将默认字段筛选或动态参数一并传给卡片数据接口;整个过程只依赖卡片和页面元信息,不会查询需要数据集管理权限的全局动态参数接口。
124
+
125
+ ```bash
126
+ guancli card preview <cd_id> --with-default-filters
127
+ guancli card preview <cd_id> --with-default-filters --page-id <pg_id>
128
+ guancli card preview <cd_id> --with-default-filters --filter "区域 EQ 华南"
129
+ guancli card preview <cd_id> --with-default-filters --dynamic-param "结束日期=2026-07-24"
130
+ ```
131
+
132
+ - 卡片元信息只关联一个页面时自动使用该页面;关联多个页面时必须用 `--page-id` 明确上下文。
133
+ - 显式 `--filter` 或 `--dynamic-param` 会覆盖相同 `fdId` 或 `dpId` 的页面默认值,其他默认条件仍然保留。
134
+ - 支持普通固定值、多选、日期范围、后端已经解析出实际区间的时间宏,以及动态参数选择器。
135
+ - `FIRST_PICK`(取首个候选值)和日历 `MAX`(取最新日期)在页面详情里没有具体值,CLI 会与 BI 前端打开页面时一样调用 `POST /api/page/first-pick` 运行态求值;选择器级联时按上游→下游分层求值,同一层的选择器合并为一个请求(请求次数等于级联深度,无级联时 1 次),并把上游默认值作为候选值筛选条件传入;单次命令最多运行态求值 20 个选择器,循环级联直接报错。stderr 提示行的 `runtimeResolved=` 列出经运行态求值的选择器。\n- 每次 `card preview` 的表格页脚(写文件时为“已写入”后的一行)都有 `筛选:`,列出本次真正生效的条件及来源:`[--filter]`/`[--dynamic-param]` 为显式指定,`[页面默认·<选择器名>]` 为页面筛选器默认值,带 `·运行态求值` 表示 FIRST_PICK/MAX 求值结果;没有任何条件时写明是否应用了页面默认值(选择器等不支持该参数的卡片只显示“无”)。`-f json/csv/excel` 的 stdout 只含数据,条件说明只在 stderr。
136
+ - 树、组合、聚合/结果级映射、必填但无默认值,以及无法从页面元信息确定实际值或目标映射的默认条件均 fail closed:CLI 在查询卡片数据前明确报错,不会静默忽略后继续执行。`autoLink` 会先按同名字段推断目标字段,推断不到时才 fail closed。
137
+ - 多个选择器写入同一字段或动态参数、时间宏目标形态不明确、动态参数默认值包含逗号等可能产生歧义的情况同样会停止查询。
138
+ - 该参数仅适用于 CHART 图表卡片;复杂报表 Pro、选择器和其他卡片类型暂不支持。
139
+
140
+ ### 带动态参数预览图表卡片
141
+
142
+ 图表卡片 preview 支持通过 `--dynamic-param` 覆盖 BI 全局动态参数,格式为 `参数名=值` 或 `dpId=值`,可多次指定。
143
+ CLI 优先从当前卡片元数据补全参数,并把完整 `dynamicParams` 传给 `/api/card/{cdId}/data`。卡片已声明动态参数时,只接受当前卡片实际使用的参数;仅对完全没有内嵌参数元数据的旧卡片,才兼容回退查询 `/api/dynamic-parameter/query`。因此普通查看账号可直接覆盖当前卡片实际使用的动态参数,不依赖全局参数管理权限,也不会把同名或近似名称的无关全局参数静默传给卡片。
144
+ 该能力仅支持 CHART 图表卡片;数据集 preview 当前后端接口不消费动态参数,暂不支持。
145
+ 多选参数值沿用 BI 前端约定,使用英文逗号拼接成一个字符串传入。
146
+
147
+ ```bash
148
+ guancli card preview <cd_id> --dynamic-param "结束时间={{{today}}}"
149
+ guancli card preview <cd_id> --dynamic-param "11=999" --raw
150
+ guancli card preview <cd_id> --dynamic-param "品类=鞋,服,包"
151
+ guancli card preview <cd_id> --dynamic-param "DATE_RANGE_PARAM_LEFT=2026-05-01" --dynamic-param "DATE_RANGE_PARAM_RIGHT={{{today}}}"
152
+ ```
153
+
154
+ ### 带动态维度预览图表卡片
155
+
156
+ 图表卡片 preview 支持通过 `--dynamic-field` 覆盖当前卡片自身的动态维度选择;参数名沿用历史/API 命名,语义上表示动态维度。
157
+ 格式为 `动态维度名=字段名`、`dzId=fdId`、`dzId=key`,也兼容旧写法 `dzId:key`。
158
+ 动态维度名、dzId、字段名、fdId、key 先用 `card get <cd_id>` 查看;如果动态维度没有配置名称,只能使用 dzId。
159
+ 单选动态维度只能指定一个字段;`multiSelect: true` 的动态维度可用英文逗号传多个字段,或重复指定同一个动态维度,CLI 会合并去重。
160
+ 字段名本身包含英文逗号时,CLI 会优先按完整字段名匹配;也可用 CSV 引号写法,例如 `"维度=\"门店,二店\""`。
161
+ 该能力仅支持当前卡片自身的动态维度,不支持带 `sourceDzIds` 的来源动态维度;参数只影响本次运行态取数,不修改卡片配置。
162
+
163
+ ```bash
164
+ guancli card get <cd_id> # 查看动态维度配置、dzId、可选字段、fdId、key
165
+ guancli card preview <cd_id> --dynamic-field "维度=区域"
166
+ guancli card preview <cd_id> --dynamic-field "维度=区域,门店" --dynamic-field "数值=销售额,利润"
167
+ guancli card preview <cd_id> --dynamic-field "维度=区域" --dynamic-field "维度=门店"
168
+ guancli card preview <cd_id> --dynamic-field "dz_region=province_fd,city_fd"
169
+ guancli card preview <cd_id> --dynamic-field "dz_region=province_key,city_key"
170
+ guancli card preview <cd_id> --dynamic-field "dz_region:city_key"
171
+ ```
172
+
173
+ ## 8. 输出格式控制
174
+
175
+ `--format` / `-f` 控制 preview 命令的输出格式:
176
+
177
+ ```bash
178
+ guancli ds preview <ds_id> # auto: 对齐表格,列>10 或行>20 时自动截断
179
+ guancli ds preview <ds_id> -f csv # CSV 格式
180
+ guancli ds preview <ds_id> -f excel # Excel 2003 XML 格式
181
+ guancli ds preview <ds_id> -f expanded # PG 风格竖排
182
+ guancli ds preview <ds_id> -f table # 对齐表格
183
+ guancli ds preview <ds_id> -f json # JSON 行记录数组
184
+ guancli ds preview <ds_id> -f json | jq '.[0]' # 配合 jq
185
+ ```
186
+
187
+ `--raw` 输出 API 原始 JSON(不经过解析):
188
+
189
+ ```bash
190
+ guancli --raw etl tree
191
+ guancli --raw etl get <id>
192
+ ```
@@ -0,0 +1,101 @@
1
+ # guancli 资源查询与标准分析流程
2
+
3
+ ## 1. 拉取目录树
4
+
5
+ ```bash
6
+ guancli etl tree
7
+ guancli ds tree
8
+ guancli page tree
9
+ ```
10
+
11
+ ## 2. 搜索资源
12
+
13
+ ```bash
14
+ guancli etl search # 搜索所有 ETL
15
+ guancli etl search 关键词 # 按关键词搜索
16
+ guancli etl search 关键词 -d <dir_id> # 在指定目录中搜索
17
+ guancli ds search 关键词 # 搜索数据集
18
+ guancli ds search --limit 500 --offset 500 # 分页扫描数据集
19
+ guancli ds search --id <dsId> # 按数据集 ID 精确查找并返回单个数据集详情
20
+ guancli ds search 关键词 --id <dsId> # 按名称 + ID 组合查找
21
+ guancli page search 关键词 # 搜索页面
22
+ guancli search 资源名 # 全局搜索,默认每种资源类型返回前 50 条
23
+ guancli search 资源名 --limit 100 --offset 100 # 按每种资源类型分页
24
+ ```
25
+
26
+ `ds search` 默认返回前 500 条,环境数据集较多时用 `--limit` 和 `--offset` 分页扫描;`ds search --id` 会直接按数据集 ID 获取单个数据集详情,`--limit` 和 `--offset` 在 `--id` 模式下忽略。
27
+
28
+ `guancli search <资源名>` 调用 `/api/global-search` 并传 `{"keyword":"<资源名>","resourceType":"ALL","isMobile":false,"limit":50,"offset":0}` 做全局搜索,适合资源类型不确定、需要像 MCP `global_search` 一样先定位资源 ID 的场景。`--limit` 和 `--offset` 在 `ALL` 模式下分别作用于每种资源类型;如果某一类型的匹配数超过当前窗口,继续增加 `--offset` 翻页。已知类型时仍优先用 `ds/page/etl search` 获取类型专属字段。
29
+
30
+ ## 3. 获取详情(含血缘)
31
+
32
+ ```bash
33
+ guancli etl get <resource_id> # ETL 详情(含节点、SQL、血缘)
34
+ guancli ds get <resource_id> # 数据集详情(含字段结构、血缘)
35
+ guancli ds get <resource_id> --brief # 数据集轻量输出(省略 Malloy、血缘、公式详情,节省 token)
36
+ guancli ds get <resource_id> --assoc # 附加显示关联关系摘要(ETL、融合等)
37
+ guancli ds get <resource_id> --validate-downstream # 验证血缘中的下游资源是否仍存在
38
+ guancli ds get <resource_id> --raw --validate-downstream # 在 lineage.downstreamValidation 返回结构化报告
39
+ guancli page get <resource_id> # 页面详情(含卡片列表、血缘)
40
+ ```
41
+
42
+ **`--brief` 模式**:省略 Malloy 定义、血缘关系、计算字段公式等高 token 内容。`ds get` 省略 Malloy/血缘/公式详情;`page get` 省略各卡片的 Malloy 定义与血缘;`etl get` 仅省略血缘;`card get` 输出本身已精简,该选项无额外效果。
43
+
44
+ **`--assoc` 模式**(仅 `ds get`):在详情末尾追加数据集关联关系摘要,显示关联的 ETL、数据融合等资源。
45
+
46
+ **`--validate-downstream` 模式**(仅 `ds get`):按血缘返回顺序串行调用数据集、ETL、页面或卡片详情接口,确认每个下游 ID 当前是否仍存在。只有业务状态 `1002` 或 HTTP 404 会记为 `not_found`;认证失败、其他 HTTP 错误、JSON 解析失败和响应 ID 不一致都会让命令失败,不会误报为“不存在”。未知资源类型记为 `unsupported`,并令报告的 `complete=false`。原始 `lineage.downstream` 不会被删除或改写;`--raw` 下新增的 `lineage.downstreamValidation` 包含 `complete`、`allValid`、`checked`、`valid`、`notFound`、`unsupported` 和逐项 `items`。默认不启用,因此现有 `ds get` / `ds get --raw` 输出保持不变。
47
+
48
+ 该验证单次最多处理 100 个下游资源,按服务端血缘顺序执行,单请求超时 10 秒、总超时 30 秒。它验证的是“血缘 ID 对应资源详情当前可读取”,不替代服务端删除接口对真实依赖、权限和并发变化的最终校验;不能与跳过血缘的 `--brief` 同时使用。
49
+
50
+ 使用 Personal Access Token 时,血缘、页面和卡片详情使用 `BASE/read`;数据集详情使用 `DATASET/read`;ETL 详情使用 `ETL/read`。PAT 创建时权限列表默认为空,`BASE` 基础读取仍按账号角色校验,但数据集和 ETL 读取权限必须显式选入 PAT scope;缺少权限时验证会返回真实鉴权错误并终止。
51
+
52
+ ## 4. 获取资源具体 URL
53
+
54
+ ```bash
55
+ guancli url page <page_id> # 仪表板页面前端 URL + API URL
56
+ guancli url card <cd_id> --page-id <page_id> # 卡片所在页面 anchor URL + 卡片 API URL
57
+ guancli url ds <ds_id> # 自动反查父目录并生成数据集详情页 URL
58
+ guancli url ds <ds_id> --parent-id <dataset_dir_id>
59
+ guancli url ds-dir <dataset_dir_id> # 数据集目录 URL
60
+ guancli url etl <etl_or_dir_id> # ETL/数据流基础前端 URL + API URL
61
+ guancli url etl <etl_id> # 普通 ETL 会自动从详情接口获取父目录并生成详情页 URL
62
+ guancli url etl <etl_id> --parent-id <dir_id> # 自动获取失败时手动指定父目录
63
+ guancli url metric-dir <metric_dir_id> # 自动反查指标主题并生成指标目录 URL
64
+ guancli url metric-dir <metric_dir_id> --project-id <metric_project_id>
65
+ guancli url metric-tree <metric_tree_id> # 指标树编辑页面 URL
66
+ guancli -f json url page <page_id> # 结构化输出,便于自动提取 webUrl/apiUrl
67
+ ```
68
+
69
+ `url` 命令读取本地 profile 的 `base_url`。页面 URL 是稳定前端直达链接;卡片没有独立页面,但传 `--page-id` 后会生成 `/page/<pageId>?anchor=<cardId>` 定位具体卡片;数据集会优先读取详情中的 `parentDirId`,自动生成 `/data-center/data-sets/<parentDirId>/<dsId>/details/overview?limit=50`,自动获取失败时再手动传 `--parent-id`;数据集目录使用 `/data-center/data-sets/<dataset_dir_id>`;ETL/数据流会优先读取 ETL 详情中的 `parentDirId`,普通 ETL 自动生成 `/data-center/data-flow/<parentDirId>/<etlId>/details/datasets?limit=50`;详情接口不可用时回退查询 ETL 目录树,目录节点使用 `/data-center/data-flow/<id>`;自动获取失败时再手动传 `--parent-id`。
70
+
71
+ ## 输出说明
72
+
73
+ - **目录树**:树形结构(├── └──),包含名称和 ID
74
+ - **搜索结果**:表格式列表,包含名称、ID、状态、路径、调度信息、时间
75
+ - **ETL 详情**:流程摘要 + 节点详细信息(含 Sources/UsedBy 引用)+ 等价 SQL + 血缘关系
76
+ - **数据集详情**:基本信息 + 字段结构(维度/度量/计算字段分类)+ Malloy source 定义 + 血缘关系
77
+ - **页面详情**:页面信息 + 卡片列表(含筛选器配置、交互联动、Malloy 查询)+ 血缘关系
78
+ - **数据集预览**:表格格式预览(列名 + 数据行),显示数据集基本信息和行列统计
79
+ - **卡片数据**:表格格式预览(维度 + 度量),自动检测卡片类型(图表/筛选器/树状筛选器)
80
+ - **表单列表**:表格式列表,包含 fmId、名称、类型、创建者、更新时间
81
+ - **表单结构**:字段定义表格,包含 fdId、名称、类型、必填/可编辑、选项(LLM 消费核心);TABLE 类型字段显示 subFmId
82
+ - **表单数据**:表格格式,首列为 rowId(用于 update/delete),后续为字段列;子表查询结果额外包含 `subId` 列(子行主键,update/delete 时用作 rowId 参数)
83
+ - **表单写操作**(add/update/delete):默认输出 `✓ ...` 文本;`-f json` 时输出结构化 JSON:`{"ok":true,"action":"add","rowId":"...","count":N,"total":N,"failed":N}`。批量插入部分失败时 `ok=false` 且 exit code 非零
84
+ - **ChatBI 主题列表**:markdown 表格,包含 `theme_id`、`theme_name`
85
+ - **ChatBI 问数/洞察**:markdown 文本;图表块会被自动转成表格,便于继续总结
86
+
87
+ ## 故障排查
88
+
89
+ ### ETL preview 返回 0 行
90
+
91
+ 0 行是合法结果,不一定是错误。排查顺序:
92
+ 1. 确认输入数据集有数据:`guancli ds preview <dsId> --limit 5`
93
+ 2. 如果节点有 FILTER_ROWS 或 WHERE 条件,临时简化后再 preview
94
+
95
+ ### Token 过期 / API 401
96
+
97
+ 密码登录方式会自动刷新。如果仍然失败,重新登录:
98
+
99
+ ```bash
100
+ guancli auth login
101
+ ```
@@ -0,0 +1,281 @@
1
+ ---
2
+ name: guands
3
+ description: 当用户要管理观远 BI / Guandata 的数据连接(MySQL/PostgreSQL/Oracle 等连接器和账号)、批量创建/移动/删除/重命名数据集、配置增量更新(增量 SQL / 先删后插 preClean / 主键去重)、配置数据集定时刷新调度(daily/hourly/weekly/monthly)、添加/修改/删除计算字段、从 CSV/Excel 导入数据、替换/追加/清理数据集数据、从 SQL 或表名批量建抽取/直连数据集、用基础控件创建或原地编辑 SurveyEngine 填报表单(加/删控件、字段改名、表单改名;数据行与未删除字段的已填报数据保留,删除控件会连带删除该列历史数据)、管理表单目录(创建/重命名/移动/删除目录、移动表单到目录,自动探测环境是否开启目录功能)、源端表结构变更后同步数据集 schema(加列/删列/改名字段映射)、查看数据集行列权限、等待数据集刷新或首次抽数完成、管目录树时,优先使用这个 skill。即使用户只说"连个 MySQL""把销售表导进来""批量改成每天凌晨刷新""加一个利润率计算字段""源表加了两列同步一下""往这个数据集追加昨天的数据""把 2023 年以前的数据清掉""创建一个门店巡检表""给巡检表加个字段""建个表单目录把巡检表挪进去""看看这个数据集配了什么行权限""等这个数据集刷新完再告诉我""把这堆 ds 移到新目录""按这份清单批量建 ODS 抽取并配增量",也要主动使用。它通过 BI HTTP API 做 Connector/Account/DataSource/Directory/SurveyEngine Form 的 CRUD、增量与调度配置。只读查询/分析数据集字段、血缘走 guancli;新建/改卡片走 guanvis。认证复用 guancli 共享配置。
4
+ compatibility: "Requires Node.js 14+. Install via npm link --foreground-scripts (local) or npm install -g --foreground-scripts @guandata/guands (from internal Nexus registry) so the AI skill refresh result is visible. CLI command: guands."
5
+ ---
6
+
7
+ # guands
8
+
9
+ guands 是执行型 skill,用于管理观远 BI 的数据源基础设施:Connector、Account、DataSource、Directory、增量更新、定时调度、计算字段、数据维护、schema 同步、行列权限查询和异步任务。ETL 分析、页面/仪表板内容优先用 `guancli`;新建/改卡片走 `guanvis`。
10
+
11
+ ## 何时使用
12
+
13
+ - 查看系统支持的连接器类型,创建、测试、原地重命名、刷新或删除数据库连接账号。
14
+ - 浏览数据库 Schema、表、列,预览数据库表数据或 SQL 查询结果。
15
+ - 搜索、查看、刷新、重命名、移动、删除、另存为数据集。
16
+ - 从 DB 表、自定义 SQL、CSV、Excel 或填报表单创建数据集。
17
+ - 替换、追加或清理已有数据集数据,包含按主键去重 upsert 和危险清理预览。
18
+ - 源端表结构或关联 Form 结构变化后同步数据集 schema,包含加列、删列、字段改名映射和数据库类数据集的 auto-sync-schema。
19
+ - 查看数据集行/列权限配置及关联的行列权限模板。
20
+ - 配置增量更新(增量 SQL、先删后插 preClean、主键去重)和定时更新调度。
21
+ - 添加、修改、删除数据集计算字段。
22
+ - 等待数据集刷新、导入或首次抽数完成(`refresh --wait`、`create-db --wait`、`import` 默认等待),结果以数据集自身状态为准。
23
+ - 管理数据集目录结构,批量管理数据集。
24
+ - 查看哪些卡片使用了某个数据集。
25
+ - 按清单批量创建 ODS 抽取数据集并配置增量。
26
+ - 用基础控件创建填报表单、巡检表、登记表、回访表;原地编辑已有表单结构(加/删控件、字段改名、表单改名),数据行与未删除字段的已填报数据保留;删除控件会连带删除该列历史数据(不可恢复)。
27
+
28
+ ## 固定工作方式
29
+
30
+ 1. 确认底层 CLI 认证正常:guancli 用户跑 `guancli auth status`;若由上游托管 OIDC Token,则确保当前进程同时设置 `GUANCLI_OIDC_BASE_URL` 和 `GUANCLI_OIDC_ACCESS_TOKEN`,无需本地 profile;guancli-lite 用户确认 `GUANCLI_BASE_URL` 和 `GUANCLI_TOKEN` 环境变量已设置。
31
+ 2. 先分场景:连接器/账号用 `connector/account`;数据集管理用 `dataset`;增量更新用 `dataset update-setting`;去重主键用 `dataset primary-key`;调度用 `dataset schedule`;目录用 `dir`。
32
+ 3. 缺 acId / dsId / 目录 ID 时先查,不要猜:`guands connector list`、`guands account list`、`guands dataset list 关键词`、`guands dir tree`。
33
+ 4. 写操作必须有明确目标。涉及创建、导入、替换/追加/清理、schema 同步、增量/调度配置、批量删除时,优先先跑 `--dry-run`、`--preview` 或 `plan` 看影响范围和请求体,再执行真实写入。
34
+ 5. `--dry-run` 输出稳定 JSON plan;其中 `create-db/create-query/import` 的 columns、selectedSheets、dsInfos 需要真实 preview/upload 后才能解析,plan 会把这些在线步骤标成占位。确认 plan 后再去掉 `--dry-run` 执行,删除/清理/追加/替换类操作仍需 `--yes`。
35
+ 6. **创建数据集前必须先让用户明确存储目录**(`import` / `create-db` / `create-query` / `create-form` 的 `--dir-id` 为必填,CLI 对缺省直接拒绝)。用户没说目录时先问,不得自行选根目录、猜目录或新建目录代替确认;用户明确要放根目录时,把 `guands dir tree` 首行的根目录 ID 显式传给 `--dir-id`。创建成功后把输出的链接和路径交给用户核对。
36
+ 7. **追加、替换、清理、删除数据前必须得到用户明确确认**:先不带 `--yes` 跑一遍(`append-data` / `replace-data` / 各类 `delete` 不带 `--yes` 只打印操作对象、影响范围和风险并以非零退出码结束;`clear-data` 不带 `--yes` 只做清理预览,退出码为 0,不要把它当成已清理),把这段计划交给用户,用户明确同意后才允许加 `--yes` 重跑。不得为了省一轮交互自行补 `--yes`,也不得把"没执行"的那次当作已完成。
37
+
38
+ ## 按需读取资料
39
+
40
+ | 场景 | 先读 |
41
+ |---|---|
42
+ | connector/account/dataset/task/dir 常用命令、替换/追加/清理、schema 同步、行列权限、输出格式 | `references/command-reference.md` |
43
+ | 创建数据库连接、批量整理数据集、从 DB/SQL/CSV/Excel/Form 创建或替换数据集、schema 同步工作流、create-db vs create-query | `references/workflows.md` |
44
+ | ODS 批量抽取、增量配置、时间宏、preClean、主键去重、定时调度 | `references/incremental-and-schedule.md` |
45
+ | 数据集计算字段、guands 与 guancli 边界、AI 易错点 | `references/calc-fields-boundaries-and-pitfalls.md` |
46
+
47
+ ## 常用入口
48
+
49
+ ```bash
50
+ guands connector list
51
+ guands account list
52
+ guands account get <ac_id>
53
+ guands account test <cn_id> --config '{...}'
54
+ guands account create <cn_id> --config '{...}'
55
+ guands account rename <ac_id> --name "新名称"
56
+ guands account update <ac_id> --host 10.0.0.8 --password 'secret' --dry-run
57
+ guands dataset list 关键词
58
+ guands dataset get <ds_id>
59
+ guands dataset fields <ds_id>
60
+ guands dataset cards <ds_id>
61
+ guands dataset permission get <ds_id>
62
+ guands dataset create-db --ac-id <acId> --tables "t1,t2" --dry-run --dir-id <dirId>
63
+ guands dataset create-query --ac-id <acId> --name "自定义查询" --sql "SELECT ..." --dry-run --dir-id <dirId>
64
+ guands dataset create-form <fmId> --dir-id <dirId>
65
+ # fmId 也可为主表 TABLE 字段下的 subFmId;按表单 ID 匹配,不按同名表单猜测。
66
+ guands dataset import ./data.csv --preview --dir-id <dirId>
67
+ guands dataset replace-data <dsId> ./fixed.csv # 不带 --yes 只打印计划;用户确认后加 --yes 执行
68
+ guands dataset append-data <dsId> ./new_rows.csv --yes # 用户已确认
69
+ guands dataset clear-data <dsId> --where "日期 < 2024-01-01"
70
+ guands dataset sync-schema plan <dsId>
71
+ guands dataset update-setting <dsId> --incremental --incremental-sql "SELECT ..." --dry-run
72
+ guands dataset primary-key set <dsId> --columns "id" --dry-run
73
+ guands dataset primary-key clear <dsId> --dry-run
74
+ guands dataset schedule <dsId> --cron-type daily --hour 2 --minute 0 --dry-run
75
+ guands form validate form.js
76
+ guands form create form.js --dry-run
77
+ guands form list
78
+ guands form export <fmId> --out form.js
79
+ guands form update <fmId> form.js --dry-run
80
+ guands form rename <fmId> --name "新名称"
81
+ guands form folder status
82
+ guands form folder tree
83
+ guands form folder create --name "巡检" --parent 0
84
+ guands form move <fmId> --to <folderId>
85
+ guands dataset create-db --ac-id <acId> --tables "t1,t2" --wait --timeout 900 --dir-id <dirId>
86
+ guands dir tree
87
+ guands dir tree -k ODS --max-depth 3
88
+ guands dir create --name "ODS" --parent <parent_dir_id>
89
+ guands dir rename <dir_id> --name "新名称"
90
+ guands dir delete <dir_id> --yes
91
+ ```
92
+
93
+ ## 关键规则
94
+
95
+ - `dataset list/get` 返回的 rowCount 是后端元数据快照,不应作为数据完整性校验依据。
96
+ - **WebService(API) 数据集(`displayType=WEB_SERVICE`)暂不支持任何写操作**:CLI 不提供其创建、预览、连接测试入口,`refresh` / `schedule` / `update-setting` / `sync-schema` / `save-as` 读到该类型会直接拒绝并不提交请求;这几条命令提交前统一校验详情:读不到、解析失败、详情为空、缺少 `displayType` 或 `hasPermission=false` 时同样不提交(fail-closed),不会再“读取失败仍继续提交”。原因是该链路仍依赖网页端内部契约,服务端执行时会向数据集配置里的 URL 发请求,且 Content-Type、分页、类型转换和错误包装等多处尚未收口。用户要操作 WebService 数据集时明确告知只能在 BI 网页端完成;不要用删除重建、`import`/`create-db` 等其他类型命令替代,也不要直接调用网页端内部 API。需要追加历史或动态 schema 的场景改用版本化快照数据集加下游 ETL。
97
+ - `dataset refresh` 提交前会检查数据集当前 `status`:已有更新时普通 refresh 不重复提交,`--wait` 会等待已有更新完成;预检与提交之间的毫秒级并发通常由服务端拒绝(通用码 5001,文案随 Accept-Language 变化),CLI 由 clifetch 统一分类后回读数据集状态确认,再加入已有任务;文案无法确认为冲突时保留原始报错并提示当前 taskId,不会转成成功。服务端在极窄窗口内仍可能接受两次提交产生两个 taskId(demo 实测),调用方需要严格互斥时应自行保存首次 taskId 并串行调用;清理数据/修改主键/schema 变更等互斥操作只会阻塞 refresh,不会被当成已有更新成功;`--overwrite` 不会合并到未知模式的已有任务,也不会用其他普通任务的成功替代覆盖更新成功。本次更新任务 `FAILED/CANCELED` 时,普通 `refresh --wait` 会在能识别到数据集有后续更新任务时继续按数据集最新状态收敛。CLI 不提供按任务 ID 查询、等待或取消任务的命令;任务 ID 只在进程内部使用。
98
+ - `dataset list --dir-id <dirId>` 是子树递归语义,返回该目录及所有子目录下的数据集;该表格型命令的程序化解析用 `-f json`。`--raw` 是后端原始 JSON,不承诺跨子命令统一 schema。
99
+ - CSV 服务端只认第 1 行为表头;表头前有标题/空行时必须先预处理或转为 xlsx。Excel 可用 `--header-row N` 指定表头行。
100
+ - `dataset import` 每次只接受一个 CSV/Excel 文件并且最多创建一个数据集;Excel 单 Sheet 自动选择,多 Sheet 必须用 `--sheet <名称>` 指定一个。Sheet 列表来自 BI 上传接口,不在 CLI 本地解析 Excel。命令会在上传前识别伪装成 `.csv` 的 Excel/ZIP/OLE 容器,并默认等待本次导入到终态;任务 `FAILED/CANCELED` 或等待超时都会返回非零。大文件可用 `--timeout` 调整等待时间。
101
+ - `dataset append-data` 和 `dataset replace-data` 同样禁止隐式合并 Excel Sheet:单 Sheet 自动选择,多 Sheet 必须用 `--sheet <名称>` 指定一个。最终请求的 `selectedSheets` 只包含该 Sheet;CSV 不接受 `--sheet`。
102
+ - import 时不支持直接配置去重主键,需建集后用 `dataset primary-key set <dsId> --columns "id"` 补充。主键修改会触发异步数据重写,命令默认等待任务完成并回读验证;清空使用 `dataset primary-key clear`。
103
+ - `append-data --distinct-by` 按指定物理列去重,重复时保留新数据;追加前自动校验文件列名与数据集一致。
104
+ - `clear-data` 是危险操作,必须显式选择 `--where` 或 `--all`;默认只预览,真实清理必须加 `--yes`。
105
+ - `permission get` 只读;设置/修改行列权限仍需走 BI 网页端。
106
+ - schema 同步先跑 `sync-schema plan`,确认字段映射后再 `apply`;数据库 SQL 数据集改查询语句时在 plan 阶段传 `--sql`。GUAN_FORM 会按 `config.tableId` 读取当前 Form 字段,不接受 `--sql`;普通 `dataset refresh` 只刷新数据,不会演进 Form 对应的数据集模型结构。
107
+ - `sync-schema apply` 的 `--mode` 必填,GUAN_FORM 默认优先 `schema-only`,未经用户明确授权不得使用 `reset`。提交后 CLI 会严格回读最终物理字段集合、保留/改名字段 fdId、确认删除字段、新增字段、字段类型和数据集状态;回读或验收失败返回非零。此时远端变更可能已经生效,必须先 `dataset fields` 回读并重新 plan,禁止直接重试旧 plan。`rowCount` 不作为数据完整性门禁;新增字段最终用 `guancli ds preview <dsId> --columns "字段名" --limit 20` 从真实下游查询。
108
+ - 增量 SQL 和 preClean 规则必须使用 BI 时间宏 `{{{ expression }}}`,不要用 `CURDATE()`、`NOW()`、`CURRENT_DATE` 等数据库函数。
109
+ - 主键去重要求主键列非空且唯一;时间窗口增量没有 DELETE 语义;抽取数据集 schema 在建集时冻结。详细限制见 `references/incremental-and-schedule.md`。
110
+ - 数据集计算字段公式中用 `[字段名]` 方括号引用字段;抽取/上传数据集使用 Spark SQL,直连数据集使用目标数据库 SQL。详细选择规则见 `references/calc-fields-boundaries-and-pitfalls.md`。
111
+ - 数据账户改名必须使用 `account rename` 原地更新并保留 acId;如果底层返回不支持或回读不一致,直接报错,禁止删除后重建。
112
+ - `dir rename` 与"移动目录"在服务端是同一个接口(`POST /api/oriput/directory/<dirId>`)且 `parentDirId` 必填,只传 `name` 会直接 500。CLI 会先回读该目录当前的父目录一并提交,写后再回读目录树确认新名称已生效**且父目录没被顺带改掉**——所以改名不会把目录挪到别处。`dir create` / `dir delete` 同样带写前预检(父目录/目标目录必须真实存在且是目录节点、根目录拒绝操作)和写后回读。
113
+
114
+ ## 编辑红线:编辑 ≠ 删除重建
115
+
116
+ 用户要求**编辑/重命名/修改**已有资源时,只能使用原地更新命令;CLI 没有对应原地能力时,直接停止并告知用户该操作 CLI 暂不支持。**严禁**用"删除旧资源 + 新建同名资源"来模拟编辑或改名:BI 资源除了名字还有大量服务端状态——资源 ID 的下游引用、权限/授权配置、增量与调度配置、历史数据——其中权限等配置本 skill 无法读取和回写,删除重建会静默丢失且无法恢复。只有用户**明确指示**"先新建一个替代、再删除旧的"时才允许,且执行前必须列出会丢失的内容(下游引用断链、权限、历史数据等)并获得用户确认。
117
+
118
+ | 资源 | 编辑用什么 | 删除重建会丢什么 |
119
+ |---|---|---|
120
+ | 数据账号 Account | 改名用 `account rename`;修改连接配置(host/端口/库名/用户/密码)用 `account update`,当前激活且必填的敏感字段(常规账号的密码)必须随命令重新提供,密码托管等模式下不生效的字段不要传 | acId 变化,引用它的数据集全部断链;账号上的授权/权限配置丢失 |
121
+ | 数据集 Dataset | 改名 `dataset rename`、移动 `dataset move`、schema 变更 `sync-schema`、显示名 `alias`、字段 `calc-field update` | dsId 变化,下游卡片/ETL 输入/指标全部断链;行列权限、增量配置、定时调度、已抽取数据和更新历史丢失 |
122
+ | 计算字段 | `calc-field update <ds_id> --fd-id <fd_id>`(保留 fdId) | delete + add 生成新 fdId,引用该字段的卡片断链 |
123
+ | 表单 Form | 改名用 `form rename`;结构编辑用 `form export` 导出 DSL 后 `form update`(merge 语义,带 fdId 锚点原地更新);换目录用 `form move` | fmId 和字段 fdId 变化;**已填报数据全部丢失** |
124
+ | 数据集目录 Dir | 改名用 `dir rename <dir_id> --name`(保留目录 ID、内容和父目录);CLI **不提供**移动数据集目录的能力,要换位置只能在 BI 网页端操作,不要用"新建 + 搬数据集 + 删旧目录"代替 | 目录 ID 变化,需逐个迁移子资源,目录权限配置丢失;且目录删除是物理删除、不进回收站,删错无从恢复 |
125
+ | 表单目录 Form Folder | 改名用 `form folder rename`;换位置用 `form folder move` | 目录 ID 变化,需逐个迁移目录下表单 |
126
+
127
+ ## 表单(SurveyEngine Form)
128
+
129
+ 表单支持**创建**和**原地编辑**。编辑已有表单(加/删控件、改名、改设置)必须走 `export → update` 闭环,**禁止**删除表单后按理解的结构重建——fmId 变化会导致关联数据集和引用断链,且**已填报数据会全部丢失**。
130
+
131
+ 表单创建使用 JS DSL 作为事实源,支持基础控件:
132
+
133
+ - `STRING` 单行文本
134
+ - `TEXT` 多行文本
135
+ - `VALUE_CHOOSER` 单选
136
+ - `MULTI_VALUE_CHOOSER` 多选
137
+ - `NUMBER` 数字
138
+ - `DATE_TIME` 日期/日期时间
139
+ - `IMAGE_SHEET` 图片控件
140
+
141
+ `TABLE` 主从明细子表**支持创建**(`createSubTable(...)` + `.addTable(detail, { keyId, required, editable, description })`,服务端为子表生成独立子 Form,TABLE 字段回读的 fdId 即 subFmId),**不支持编辑**(`form export` 导出为 `keepField(...)` 占位,update 原样保留)。子表内只允许基础控件,不可嵌套 TABLE。keyId 唯一性按 form 分域(主表一个域、每个子表各一个域,与服务端"每个 TABLE 是独立子 Form"的模型一致):主表与子表、不同子表之间可以复用同一确定性 keyId,同一 form 内重复才拒绝。
142
+
143
+ 不支持:`MATRIX_TABLE`、`RELATED_VIEW`、`RELATED_TABLE`。
144
+ `IMAGE_SHEET` 只支持创建图片控件,不承诺 CLI 图片数据填报。
145
+ 单选/多选默认要求选项非空(空选项对人工用户几乎必然是笔误);程序化迁移需要保真搬运源端无静态选项的下拉列时,用字段选项 `allowEmptyOptions: true` 显式放行(`form export` 对线上空选项字段自动带该标志,保证 export→update 闭环)。
146
+ 字段名与系统保留名(`row_id`、`parent_id`、`创建者名称`、`修改者名称`、`创建者uid`、`修改者uid`、`创建时间`、`修改时间`)同名时默认拒绝(人工手写几乎必然是误用,且与内置展示列同名在数据展示上有歧义);服务端实际允许创建且数据链路正常(业务字段按名解析优先于内置列),程序化迁移保真沿用源列名时用字段选项 `allowReservedName: true` 显式放行(`form export` 对线上保留名字段自动带该标志)。
147
+
148
+ ```bash
149
+ guands form preview form.js # 本地执行 DSL,输出最终请求体
150
+ guands form validate form.js # 本地校验 DSL
151
+ guands form create form.js --dry-run # 输出稳定 JSON plan,不创建
152
+ guands form create form.js # 创建表单,创建后回读校验结构
153
+ guands form list # 列出表单
154
+ guands form get <fmId> # 获取表单详情
155
+ guands form export <fmId> --out form.js # 导出线上表单为可编辑 DSL(字段带 fdId 锚点)
156
+ guands form update <fmId> form.js --dry-run # 预览结构变更计划(merge 语义)
157
+ guands form update <fmId> form.js # 原地更新结构,保留 fmId/fdId;删除字段会删除该列数据,需显式确认
158
+ guands form rename <fmId> --name "新名" # 重命名表单(字段和数据不动)
159
+ guands form folder status # 查看当前环境目录功能是否开启(-f json 输出 {"folderEnabled": bool})
160
+ guands form folder tree # 查看表单目录树(两种环境都可用)
161
+ guands form folder create --name "巡检" --parent 0 # 创建目录
162
+ guands form folder rename <folderId> --name "新名" # 重命名目录(保留 ID 与内容)
163
+ guands form folder move <folderId> --to <targetId> # 移动目录(--to 0 表示根目录)
164
+ guands form folder delete <folderId> --yes # 删除空目录
165
+ guands form move <fmId1> <fmId2> --to <folderId> # 移动表单到目录
166
+ ```
167
+
168
+ ### 表单目录(Form Folder):两种环境
169
+
170
+ SurveyEngine 的目录功能由服务端配置 `custom.function.access.folder` 控制,**不同 BI 环境可能开启或关闭**。CLI 通过 survey-engine 用户 profile 的 `functionAccess.folder` 自动探测,无需人工判断:
171
+
172
+ - **已开启**:`form folder create/rename/move/delete`、`form move`、`form create` DSL 的 `setFolderId` 全部可用。
173
+ - **未开启**:所有表单都在根目录(folderId=0)。`form folder tree` 仍可用(单层树);folder 写命令和 `form move` 会在发请求前被 CLI 直接拒绝并给出开启方法;`form create` 使用非 0 的 `setFolderId` 也会被拒绝(关闭环境下 folderId 会写库但指向不存在的目录,一旦该环境将来开启目录功能,这些表单会从 UI 目录树中消失)。
174
+ - 不确定时先跑 `guands form folder status`;批量操作前跑一次即可。
175
+
176
+ 目录操作细节:
177
+
178
+ - `folder rename` / `folder move` 会先从目录树回读节点(拿当前名称和父目录),再提交并回读确认。
179
+ - `folder move` 禁止把目录移动到自身或其子目录下(服务端无环检测,成环会导致整棵子树从目录树消失)。
180
+ - `folder delete` 只能删空目录,且必须加 `--yes`;CLI 会先检查目录内容再发请求。
181
+ - `form move` 支持多个 fmId,逐个移动并逐个报告成败(非表单 owner、目标目录有同名表单会失败);移动后回读确认 folderId 生效。
182
+ - 同级目录不允许同名;表单在开启目录的环境按目录内查重名,未开启时全局查重名。
183
+
184
+ ### 编辑已有表单(export → update 闭环)
185
+
186
+ 编辑永远从 `form export` 开始,不要凭记忆手写已有字段:
187
+
188
+ 1. `guands form export <fmId> --out form.js` 导出当前结构,每个字段带 `{ fdId: "..." }` 锚点。
189
+ 2. 编辑 form.js:**改名/改配置**直接改字段调用并保留 fdId 锚点(fdId 是字段身份,改名必须依赖它;丢了锚点的新名字会被当作新增一列而不是改名);**新增字段**追加不带 fdId 的 `add*` 调用;**删除字段**换成 `removeField("字段名")`。
190
+ 3. `guands form update <fmId> form.js --dry-run` 查看变更计划(added/updated/kept/removed);确认 added 里没有本想改名的字段。
191
+ 4. 确认后去掉 `--dry-run` 执行;删除字段必须加 `--allow-remove-fields`(删除会连同该列已填报数据,不可恢复)。
192
+
193
+ update 是 **merge 语义**:DSL 未声明的线上字段原样保留,绝不隐式删除;带 fdId 的字段原地更新(已填报数据保留);不带 fdId 时按字段名匹配线上字段。主键自动沿用线上配置并跟随字段改名,export 只以注释形式提示当前主键,**仅当需要变更主键时**才写 `.setPrimaryKeys([...])`(按更新后的字段名)。字段描述沿用线上值,显式写 `description: ""` 才会清空。CLI 暂不支持编辑的高级控件(TABLE/MATRIX_TABLE/RELATED_VIEW/RELATED_TABLE)导出为 `keepField(...)` 占位,原样保留即可。不支持修改字段类型和移动目录。更新后 CLI 会回读校验结构并对比前后数据行数。表单结构变更会重置审批状态(后端行为)。
194
+
195
+ 字段选项支持 `keyId`(create/update 均可),供程序化调用方(如批量迁移工具)用确定性标识实现跨次执行的幂等复用;普通场景不需要关心。
196
+
197
+ DSL 示例:
198
+
199
+ ```js
200
+ var form = createForm("门店巡检表")
201
+ .setDescription("门店每日巡检")
202
+ .setFolderId("0")
203
+ .addString("巡检编号", { required: true })
204
+ .addSingleSelect("状态", ["正常", "异常"], {
205
+ style: "RADIO",
206
+ defaultValue: "正常"
207
+ })
208
+ // 选项展示标签与存储值不同时用对象形式:{ label: "正常营业", value: "1" }
209
+ .addMultiSelect("问题类型", ["陈列", "卫生", "库存"], {
210
+ style: "CHECKBOX",
211
+ defaultValue: ["陈列"]
212
+ })
213
+ .addNumber("分数", {
214
+ format: "DOUBLE",
215
+ digits: 2,
216
+ range: [0, 100]
217
+ })
218
+ .addDate("巡检日期") // 纯日期,固定 YYYY-MM-DD
219
+ .addDateTime("巡检时间") // 日期时间,固定 YYYY-MM-DD HH:mm:ss
220
+ // 日期格式由构造器决定,addDate 传 format: "YYYY-MM-DD HH:mm:ss" 会直接报错;
221
+ // 把已有日期字段升级为日期时间时,保留 fdId 并把构造器改为 addDateTime
222
+ .addImage("现场照片", {
223
+ maxCount: 3,
224
+ maxSizePerImage: 5
225
+ })
226
+ .setPrimaryKeys(["巡检编号"]);
227
+
228
+ registerForm(form.build());
229
+ ```
230
+
231
+ 主从明细子表(TABLE)示例:
232
+
233
+ ```js
234
+ var detail = createSubTable("设备明细")
235
+ .addString("设备名", { required: true })
236
+ .addNumber("数量", { format: "INT" })
237
+ .addDate("采购日期");
238
+
239
+ var form = createForm("设备台账")
240
+ .addString("单号", { required: true })
241
+ .addTable(detail, {})
242
+ .setPrimaryKeys(["单号"]);
243
+
244
+ registerForm(form.build());
245
+ ```
246
+
247
+ 写入前先执行 `preview` / `validate` / `--dry-run`。真实创建会调用
248
+ `POST /survey-engine/api/form/add`,成功后再 `GET /survey-engine/api/form/{fmId}`
249
+ 回读并校验字段数量、字段类型、关键 settings 和后端生成的 `fdId`。
250
+
251
+ ## 硬约束
252
+
253
+ - 带 `--dir-id` 的写命令(import / create-db / create-query / create-form / move / batch-move / save-as)会先拉 DATA_SET 授权目录树做预校验,通过后输出 `目标目录: <路径> (<id>)`;拉不到目录树会直接阻断而不是继续写入(路径来自目录树,读不到就无法交给用户确认),先确认账号有数据集目录读取权限再重试。与 guanetl、guanvis 的目录预检口径一致。
254
+ - 删除操作(account delete / dataset delete / dir delete / form folder delete)必须加 `--yes` 确认;批量删除同样需要 `--yes`;删除命令只用于用户明确要求删除该资源本身,不得作为"编辑/改名"的实现手段(见「编辑红线」)。
255
+ - 清理数据(clear-data)会删除数据且不可恢复,真实执行必须加 `--yes`;追加/替换数据(append-data / replace-data)同样必须加 `--yes`,不加只打印执行计划并以非零退出码结束。任何 `--yes` 都必须来自用户对该次操作对象与影响范围的明确确认。
256
+ - 建集类命令(import / create-db / create-query / create-form)`--dir-id` 必填,缺省直接拒绝;不要用根目录 ID 绕过,除非用户明确要求放根目录。
257
+ - 创建账号前建议先 `account test` 验证连接。
258
+ - 目录删除要求目录为空(无子目录、无数据集),且是**物理删除,不进回收站、不可恢复**——与页面删除不同(页面是软删,进回收站,但没有 CLI 恢复命令,只能在 BI 网页端人工还原)。目录树只列目录节点,CLI 只能在写前拦住"还有子目录","目录里还有数据集"由服务端 deleteCheck 拒绝。
259
+ - 禁止自动上传自定义驱动:不要尝试通过 API 或任何方式自动上传数据库驱动(JDBC driver)。观远 BI 已内置绝大多数常用数据库驱动;如确需特殊驱动,必须由人工在管理后台手动上传。
260
+
261
+ ## 最后怎么向用户汇报
262
+
263
+ 至少说明执行了什么操作,涉及哪些资源(acId/dsId/dirId),操作结果(成功/失败及原因);如果是查询,给出关键信息摘要。
264
+
265
+ 涉及**明确数据集或目录**(新建、导入、另存为、移动、改名、定位到某个数据集/目录)时,必须把 CLI 输出的 `链接:` 和 `路径:` 原样带给用户:普通用户拿到 dsId 并不知道去 BI 哪里找。CLI 在这些写命令成功后会回读详情并输出访问链接(`<BI 地址>/data-source/<dsId>/details/overview`,目录为 `<BI 地址>/data-center/data-sets/<dirId>`)和存储路径(`根目录>目录>子目录`);同一批创建多个数据集时每个都给链接、路径只给一次。`路径: 回读失败` 表示写操作本身已成功但详情回读失败,如实转述即可。列表类结果(`dataset list`)不必逐条展开链接。
266
+
267
+
268
+ ---
269
+
270
+ ## VM 环境差异(观远 BI 工作站)
271
+
272
+ 本技能在 MCP 虚拟工作站中运行,与本地 CLI 有以下差异:
273
+
274
+ - 命令名直接可用:在工作站里直接执行 `guancli` / `guanetl` / `guanvis` / `guands` / `guanmetric` / `guanwf`(无需安装)。
275
+ - 认证:BI 凭证由网关注入,**不要**执行 `auth login` 或设置 token,直接运行业务命令即可。
276
+ - 文件路径一律用以 `/` 开头的绝对路径(`/` 即工作区根,跨会话持久)。
277
+ - 本技能的参考文档在 `/skills/<技能名>/references/` 下、示例工程在 `/skills/<技能名>/evals/` 下(均只读),用 read_file 工具或 `cat` 按需阅读;正文引用 `references/xxx` / `evals/xxx` 时按此路径解析。
278
+ - 图片文件(png/jpg/gif/webp)用 read_file 工具读取,**不要**用 `cat`/`head` 读图片。默认部署下图片以图像内容返回、模型可直接查看;若 read_file 返回"当前部署已关闭图像内容返回"的提示(部署方接入的模型不支持图像理解),则只有文本元信息,此时不要做任何依赖看图的验证,改用数据类命令核对。
279
+ - 不支持 `cd`、`$VAR` 展开、命令替换 `$(...)`、glob 展开;需要组合时把中间结果写入文件。
280
+ - 文本搜索用 `rg`(工作站内无独立 grep 二进制,`grep`/`egrep`/`fgrep` 会自动转成 `rg` 执行,无需绕路)。
281
+ - `install-skill` / profile 切换 / npm 相关步骤在工作站内不适用,忽略即可。