@josephyan/qingflow-cli 1.1.4 → 1.1.5

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 (154) hide show
  1. package/README.md +7 -3
  2. package/docs/local-agent-install.md +57 -6
  3. package/entry_point.py +1 -1
  4. package/npm/bin/qingflow-skills.mjs +5 -0
  5. package/npm/bin/qingflow.mjs +1 -34
  6. package/npm/lib/runtime.mjs +21 -101
  7. package/npm/scripts/postinstall.mjs +1 -10
  8. package/package.json +3 -2
  9. package/pyproject.toml +1 -1
  10. package/skills/qingflow-cli/SKILL.md +58 -44
  11. package/skills/qingflow-cli/manifest.yaml +1 -1
  12. package/skills/qingflow-cli/reference/00-INDEX.md +35 -0
  13. package/skills/qingflow-cli/reference/builder/10-build-single-app.md +38 -0
  14. package/skills/qingflow-cli/reference/builder/20-build-complete-system.md +39 -0
  15. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md → builder/30-schema-fields.md} +52 -10
  16. package/skills/qingflow-cli/reference/builder/40-layout.md +52 -0
  17. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_VIEWS_WORKFLOW.md → builder/50-views.md} +39 -15
  18. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_CHARTS_WORKFLOW.md → builder/60-charts.md} +36 -13
  19. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_PORTAL_WORKFLOW.md → builder/70-portal.md} +36 -13
  20. package/skills/qingflow-cli/reference/builder/80-buttons-associated-resources.md +41 -0
  21. package/skills/qingflow-cli/reference/builder/90-workflow.md +34 -0
  22. package/skills/qingflow-cli/reference/builder/99-publish-verify.md +46 -0
  23. package/skills/qingflow-cli/reference/builder/README.md +41 -0
  24. package/skills/qingflow-cli/reference/builder/code-integrations/README.md +130 -0
  25. package/skills/qingflow-cli/reference/builder/code-integrations/code-block.md +66 -0
  26. package/skills/qingflow-cli/reference/builder/code-integrations/q-linker.md +77 -0
  27. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_APP_DELIVERY_WORKFLOW.md → builder/reference/app-delivery-sop.md} +26 -16
  28. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/README.md +293 -0
  29. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/build-complete-system.md +809 -0
  30. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/build-single-app.md +830 -0
  31. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/complete-system-development-guide.md +123 -0
  32. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/create-app.md +182 -0
  33. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/environments.md +63 -0
  34. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/flow-actors-and-permissions.md +142 -0
  35. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/gotchas.md +108 -0
  36. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/match-rules.md +114 -0
  37. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/public-surface-sync.md +75 -0
  38. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/single-app-development-guide.md +58 -0
  39. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/solution-playbooks.md +52 -0
  40. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/tool-selection.md +107 -0
  41. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-flow.md +7 -0
  42. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-layout.md +7 -0
  43. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-schema.md +7 -0
  44. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-views.md +7 -0
  45. package/skills/qingflow-cli/reference/builder/workflow/01-overview.md +45 -0
  46. package/skills/qingflow-cli/reference/builder/workflow/02-update-mode.md +53 -0
  47. package/skills/qingflow-cli/reference/builder/workflow/03-flow-patterns.md +57 -0
  48. package/skills/qingflow-cli/reference/builder/workflow/04-stage1-business-modeling.md +131 -0
  49. package/skills/qingflow-cli/reference/builder/workflow/05-stage2-members-roles.md +29 -0
  50. package/skills/qingflow-cli/reference/builder/workflow/06-stage3-build-spec.md +165 -0
  51. package/skills/qingflow-cli/reference/builder/workflow/07-stage4-validate-spec.md +33 -0
  52. package/skills/qingflow-cli/reference/builder/workflow/08-stage5-apply-verify.md +51 -0
  53. package/skills/qingflow-cli/reference/builder/workflow/09-stage6-summary.md +88 -0
  54. package/skills/qingflow-cli/reference/builder/workflow/10-node-config-reference.md +93 -0
  55. package/skills/qingflow-cli/reference/builder/workflow/11-troubleshooting.md +15 -0
  56. package/skills/qingflow-cli/reference/builder/workflow/README.md +88 -0
  57. package/skills/qingflow-cli/reference/builder/workflow/workflow-schema.json +1754 -0
  58. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_ADMIN_CHEATSHEET.md → core/QINGFLOW_CLI_ADMIN_CHEATSHEET.md} +3 -3
  59. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md → core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md} +6 -6
  60. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_EXPLORATION_REPORT.md → core/QINGFLOW_CLI_EXPLORATION_REPORT.md} +2 -2
  61. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_FIELD_DATA_TYPES.md → core/QINGFLOW_CLI_FIELD_DATA_TYPES.md} +11 -11
  62. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_MEMBER_CHEATSHEET.md → core/QINGFLOW_CLI_MEMBER_CHEATSHEET.md} +4 -4
  63. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md → core/QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md} +4 -4
  64. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md} +3 -3
  65. package/skills/qingflow-cli/reference/record/QINGFLOW_CLI_RECORD_DELETE_WORKFLOW.md +31 -0
  66. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md} +4 -4
  67. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md} +7 -7
  68. package/skills/qingflow-cli/reference/record/analysis/README.md +130 -0
  69. package/skills/qingflow-cli/reference/record/analysis/analysis-gotchas.md +91 -0
  70. package/skills/qingflow-cli/reference/record/analysis/analysis-patterns.md +112 -0
  71. package/skills/qingflow-cli/reference/record/analysis/business-context.md +74 -0
  72. package/skills/qingflow-cli/reference/record/analysis/confidence-reporting.md +69 -0
  73. package/skills/qingflow-cli/reference/record/analysis/data-access-playbook.md +106 -0
  74. package/skills/qingflow-cli/reference/record/analysis/pandas-recipes.md +172 -0
  75. package/skills/qingflow-cli/reference/record/analysis/report-format.md +76 -0
  76. package/skills/qingflow-cli/reference/record/insert/README.md +75 -0
  77. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md → task/QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md} +5 -5
  78. package/skills/qingflow-cli/reference/task/ops/README.md +131 -0
  79. package/skills/qingflow-cli/reference/task/ops/environments.md +43 -0
  80. package/skills/qingflow-cli/reference/task/ops/workflow-usage.md +26 -0
  81. package/skills/qingflow-cli/scripts/validate_system_build_summary.py +124 -0
  82. package/skills/qingflow-cli/scripts/workflow/diff_flow_spec.py +275 -0
  83. package/skills/qingflow-cli/scripts/workflow/validate_flow_spec.py +605 -0
  84. package/skills/qingflow-mcp-setup/SKILL.md +115 -0
  85. package/skills/qingflow-mcp-setup/agents/openai.yaml +4 -0
  86. package/skills/qingflow-mcp-setup/references/claude-desktop.md +34 -0
  87. package/skills/qingflow-mcp-setup/references/environments.md +62 -0
  88. package/skills/qingflow-mcp-setup/references/generic-stdio.md +32 -0
  89. package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +38 -0
  90. package/src/qingflow_mcp/__init__.py +1 -1
  91. package/src/qingflow_mcp/__main__.py +6 -2
  92. package/src/qingflow_mcp/builder_facade/models.py +282 -102
  93. package/src/qingflow_mcp/builder_facade/service.py +4166 -929
  94. package/src/qingflow_mcp/cli/commands/builder.py +316 -298
  95. package/src/qingflow_mcp/cli/commands/chart.py +1 -1
  96. package/src/qingflow_mcp/cli/commands/common.py +12 -3
  97. package/src/qingflow_mcp/cli/commands/exports.py +2 -2
  98. package/src/qingflow_mcp/cli/commands/imports.py +3 -3
  99. package/src/qingflow_mcp/cli/commands/portal.py +2 -2
  100. package/src/qingflow_mcp/cli/commands/record.py +101 -27
  101. package/src/qingflow_mcp/cli/commands/task.py +28 -47
  102. package/src/qingflow_mcp/cli/commands/view.py +1 -1
  103. package/src/qingflow_mcp/cli/context.py +0 -3
  104. package/src/qingflow_mcp/cli/formatters.py +784 -16
  105. package/src/qingflow_mcp/cli/main.py +117 -33
  106. package/src/qingflow_mcp/errors.py +43 -2
  107. package/src/qingflow_mcp/public_surface.py +26 -17
  108. package/src/qingflow_mcp/response_trim.py +81 -17
  109. package/src/qingflow_mcp/server.py +14 -12
  110. package/src/qingflow_mcp/server_app_builder.py +65 -21
  111. package/src/qingflow_mcp/server_app_user.py +22 -16
  112. package/src/qingflow_mcp/session_store.py +11 -7
  113. package/src/qingflow_mcp/solution/compiler/__init__.py +3 -1
  114. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
  115. package/src/qingflow_mcp/solution/executor.py +245 -18
  116. package/src/qingflow_mcp/tools/ai_builder_tools.py +1780 -406
  117. package/src/qingflow_mcp/tools/app_tools.py +184 -43
  118. package/src/qingflow_mcp/tools/approval_tools.py +197 -35
  119. package/src/qingflow_mcp/tools/auth_tools.py +92 -16
  120. package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
  121. package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
  122. package/src/qingflow_mcp/tools/directory_tools.py +236 -72
  123. package/src/qingflow_mcp/tools/export_tools.py +244 -34
  124. package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
  125. package/src/qingflow_mcp/tools/file_tools.py +9 -3
  126. package/src/qingflow_mcp/tools/import_tools.py +336 -49
  127. package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
  128. package/src/qingflow_mcp/tools/package_tools.py +118 -6
  129. package/src/qingflow_mcp/tools/portal_tools.py +39 -3
  130. package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
  131. package/src/qingflow_mcp/tools/record_tools.py +1141 -356
  132. package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
  133. package/src/qingflow_mcp/tools/role_tools.py +80 -9
  134. package/src/qingflow_mcp/tools/solution_tools.py +59 -45
  135. package/src/qingflow_mcp/tools/task_context_tools.py +662 -158
  136. package/src/qingflow_mcp/tools/task_tools.py +113 -29
  137. package/src/qingflow_mcp/tools/view_tools.py +106 -3
  138. package/src/qingflow_mcp/tools/workflow_tools.py +48 -4
  139. package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
  140. /package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_MATCH_RULES.md → builder/reference/match-rules.md} +0 -0
  141. /package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_WORKSPACE_ICONS.md → builder/reference/workspace-icons.md} +0 -0
  142. /package/skills/qingflow-cli/reference/{charts_remove.example.json → examples/charts/charts_remove.example.json} +0 -0
  143. /package/skills/qingflow-cli/reference/{charts_reorder.example.json → examples/charts/charts_reorder.example.json} +0 -0
  144. /package/skills/qingflow-cli/reference/{charts_upsert_bar.example.json → examples/charts/charts_upsert_bar.example.json} +0 -0
  145. /package/skills/qingflow-cli/reference/{charts_upsert_dashboard_starter.example.json → examples/charts/charts_upsert_dashboard_starter.example.json} +0 -0
  146. /package/skills/qingflow-cli/reference/{charts_upsert_minimal.example.json → examples/charts/charts_upsert_minimal.example.json} +0 -0
  147. /package/skills/qingflow-cli/reference/{portal_sections_all_types.example.json → examples/portal/portal_sections_all_types.example.json} +0 -0
  148. /package/skills/qingflow-cli/reference/{portal_sections_five_types.example.json → examples/portal/portal_sections_five_types.example.json} +0 -0
  149. /package/skills/qingflow-cli/reference/{portal_sections_standard_workbench.example.json → examples/portal/portal_sections_standard_workbench.example.json} +0 -0
  150. /package/skills/qingflow-cli/reference/{_batch_schema_complex.json → examples/schema/_batch_schema_complex.json} +0 -0
  151. /package/skills/qingflow-cli/reference/{_batch_schema_scalar.json → examples/schema/_batch_schema_scalar.json} +0 -0
  152. /package/skills/qingflow-cli/reference/{schema_add_fields_minimal.example.json → examples/schema/schema_add_fields_minimal.example.json} +0 -0
  153. /package/skills/qingflow-cli/reference/{schema_apply_add_fields_all_types.json → examples/schema/schema_apply_add_fields_all_types.json} +0 -0
  154. /package/skills/qingflow-cli/reference/{views_upsert_table_minimal.example.json → examples/views/views_upsert_table_minimal.example.json} +0 -0
@@ -0,0 +1,66 @@
1
+ # Code Block Builder Notes
2
+
3
+ ## What Builder Should Configure
4
+
5
+ - code block field type
6
+ - code content
7
+ - inserted input fields inside code content
8
+ - alias parsing
9
+ - auto trigger
10
+ - custom button text
11
+
12
+ ## Stable Writing Rules
13
+
14
+ - Always emit `qf_output = {...}`
15
+ - Never emit `const qf_output = {...}`
16
+ - Never emit `let qf_output = {...}`
17
+
18
+ ## Useful CRM Pattern
19
+
20
+ Inputs:
21
+ - customer name
22
+ - source
23
+ - budget
24
+ - timing
25
+ - decision-maker flag
26
+
27
+ Outputs:
28
+ - score
29
+ - level
30
+ - priority
31
+ - summary
32
+ - next follow date
33
+
34
+ ## Target Field Rules
35
+
36
+ Required:
37
+ - every `outputs[*].target_field` must point to an existing field
38
+
39
+ Allowed target field types:
40
+ - text
41
+ - long text
42
+ - number
43
+ - amount
44
+ - date
45
+ - datetime
46
+ - single select
47
+ - multi select
48
+ - boolean
49
+
50
+ Do not bind code block outputs to:
51
+ - q_linker
52
+ - code_block
53
+ - relation
54
+ - subtable
55
+ - attachment
56
+ - member
57
+ - department
58
+ - address
59
+
60
+ ## Safe Verification
61
+
62
+ - `qingflow builder app get ... fields`
63
+ - `qingflow record schema insert`
64
+ - optional `record_code_block_run`
65
+
66
+ Treat configuration verification and runtime verification as separate checks.
@@ -0,0 +1,77 @@
1
+ # Q-Linker Builder Notes
2
+
3
+ ## What Builder Should Configure
4
+
5
+ - `remoteLookupConfig`
6
+ - alias parsing
7
+ - target field binding
8
+ - auto trigger
9
+ - custom button text
10
+
11
+ ## Current Supported Scope
12
+
13
+ - custom mode only
14
+ - standard request fields
15
+ - alias path parsing
16
+ - target field binding to existing ordinary fields
17
+
18
+ ## Recommended Public APIs For Samples
19
+
20
+ ### Httpbin
21
+
22
+ - URL: `https://httpbin.org/get`
23
+ - Good for:
24
+ - query echo
25
+ - request URL echo
26
+
27
+ Useful paths:
28
+ - `$.args.keyword`
29
+ - `$.url`
30
+
31
+ ### Open-Meteo Geocoding
32
+
33
+ - URL: `https://geocoding-api.open-meteo.com/v1/search`
34
+ - Good for:
35
+ - place normalization
36
+ - country
37
+ - lat/lng summary
38
+
39
+ Useful paths:
40
+ - `$.results[0].name`
41
+ - `$.results[0].country`
42
+ - `$.results[0].latitude`
43
+ - `$.results[0].longitude`
44
+
45
+ ## Target Field Rules
46
+
47
+ Required:
48
+ - every `outputs[*].target_field` must point to an existing field
49
+
50
+ Prefer:
51
+ - text
52
+ - long text
53
+ - number
54
+ - amount
55
+ - date
56
+ - datetime
57
+ - single select
58
+ - multi select
59
+ - boolean
60
+
61
+ Avoid:
62
+ - q_linker
63
+ - code_block
64
+ - relation
65
+ - subtable
66
+ - attachment
67
+ - member
68
+ - department
69
+ - address
70
+
71
+ ## Safe Verification
72
+
73
+ - `qingflow builder app get ... fields`
74
+ - `qingflow record schema insert`
75
+ - `record_insert`
76
+
77
+ This verifies that the configuration does not break the form page, even before runtime execution is tested.
@@ -1,6 +1,6 @@
1
1
  # Builder 应用交付重流程 SOP:分组 → 应用定位 → 读场 → 改场 → 发布校验
2
2
 
3
- 本文对齐 **MCP / AiBuilder** 工具链命名,并给出 **稳定 CLI**(`qingflow builder` / `qingflow build`)等价写法。编写前已 **阅读** `qingflow_mcp` 中 `builder_facade/service.py`、`cli/commands/builder.py`、`ai_builder_tools.py`,并对 **`ead8ims5i401`** **实跑**:`app resolve`、`app get fields|layout|flow`、`publish verify`。
3
+ 本文以 **稳定 CLI**(`qingflow builder` / `qingflow build`)为唯一公开入口。编写前已阅读实现中的 `builder_facade/service.py`、`cli/commands/builder.py`、`ai_builder_tools.py`,并对 **`ead8ims5i401`** 实跑:`app resolve`、`app get fields|layout|flow`、`publish verify`。
4
4
 
5
5
  > **权限**:应用基础信息(`app_name` / 图标 / 可见性)、表单、流程、自定义按钮本体、应用级关联资源池走 **应用搭建 / EditAppAuth**;视图更新/删除、按钮的视图位置配置(`view_configs`)和视图内关联资源展示配置走 **视图管理 / ViewManagementAuth**(后端 `beingViewManageStatus`;未开启高级应用权限时等价回落到 DataManageAuth);**新建视图**额外需要 **DataManageAuth**;报表走 **数据管理 / DataManageAuth**。失败码常见 **40002 / 40161 / 编辑锁** 等,见主技能与 **ADMIN** 速查。
6
6
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  ## 1. 推荐阶段顺序(与工具名对齐)
20
20
 
21
- | 阶段 | MCP / 编排常用名 | 稳定 CLI(有则列出) | 作用 |
21
+ | 阶段 | 目标资源 | 稳定 CLI(有则列出) | 作用 |
22
22
  |------|------------------|----------------------|------|
23
23
  | A | **`package_list`** | `qingflow --json builder package list [--query <关键词>]` | 列出当前 Builder 权限可见的应用包,返回 **`package_id/package_name`**、包权限和应用数量 |
24
24
  | A′ | **`package_resolve`** | 不再作为 CLI 默认入口;用 `package list --query` 后人工/智能体确认 `package_id` | 同名包、空包都以 `package_list` 返回为准 |
@@ -34,7 +34,15 @@
34
34
  | G″ | **`app_associated_resources_apply`** | `qingflow builder associated-resource apply …` | 管理应用级关联视图/报表池,并配置视图详情侧边栏展示 |
35
35
  | H | **`app_publish_verify`** | `qingflow builder publish verify --app-key …` | 确认 **已发布**、包挂载、视图等校验位 |
36
36
 
37
- **说明**:**`app_charts_apply`**(CLI **`builder charts apply`**)不在上表骨架内,但同属交付闭环;详见 **[QINGFLOW_CLI_BUILDER_CHARTS_WORKFLOW.md](./QINGFLOW_CLI_BUILDER_CHARTS_WORKFLOW.md)**;**视图**、**门户** 见同目录另文;其余另读 **`builder contract --tool-name …`**。`app_custom_buttons_apply` 与 `app_associated_resources_apply` 有成功写入时会自动发布,不暴露 draft-only `publish` 参数。
37
+ **说明**:**`app_charts_apply`**(CLI **`builder charts apply`**)不在上表骨架内,但同属交付闭环;详见 **[60-charts.md](../60-charts.md)**;**视图**、**门户** 见同目录另文;其余另读 **`builder contract --tool-name …`**。`app_custom_buttons_apply` 与 `app_associated_resources_apply` 有成功写入时会自动发布,不暴露 draft-only `publish` 参数。
38
+
39
+ ### 1.1 批量读、批量写、局部改归位
40
+
41
+ 这些不是独立流程,而是读、写、改三个动作的多资源形态:
42
+
43
+ - **批量读**:读多个应用时优先用 `--app-keys`,例如 `builder app get --app-keys a,b fields`、`builder app get --app-keys a,b views`、`builder button get --app-keys a,b`、`builder associated-resource get --app-keys a,b`、`builder publish verify --app-keys a,b`。读结果同时看成功项和 `errors[]`,不要因单个应用失败否定全批。
44
+ - **批量写**:写多个应用时使用各资源自己的 `--apps-file`,例如 `schema/layout/views/button/associated-resource/charts apply --apps-file ...`。`apps[]` 每项都必须带自己的 `app_key` 或多应用 schema 的 `client_key/app_name`。
45
+ - **局部改**:只改已存在资源的少量参数时用对应 patch 文件;`patch_*` 内只写目标定位字段和 `set/unset`,不要用不完整 `upsert_*` 伪装局部更新。
38
46
 
39
47
  ---
40
48
 
@@ -238,13 +246,13 @@ qingflow --json builder app get --app-key "<APP_KEY>" flow
238
246
 
239
247
  ### 5.1 字段:`builder schema apply`
240
248
 
241
- **一键可复制「仅新增字段」示例**(**`add_fields` 数组文件**):[schema_add_fields_minimal.example.json](./schema_add_fields_minimal.example.json)
249
+ **一键可复制「仅新增字段」示例**(**`add_fields` 数组文件**):[schema_add_fields_minimal.example.json](../../examples/schema/schema_add_fields_minimal.example.json)
242
250
 
243
251
  ```bash
244
252
  qingflow builder schema apply \
245
253
  --app-key "<APP_KEY>" \
246
254
  --no-publish \
247
- --add-fields-file ./reference/schema_add_fields_minimal.example.json
255
+ --add-fields-file ./reference/examples/schema/schema_add_fields_minimal.example.json
248
256
  ```
249
257
  (路径以 `qingflow-cli/` 技能根目录为基准;执行时可解析为该技能目录下的实际文件。)
250
258
 
@@ -263,7 +271,7 @@ qingflow builder schema apply \
263
271
  - **`--publish` / `--no-publish`**:默认发布;`--no-publish` 仅草稿/预检语义(见 `server_app_builder` 总述:**schema/layout/views/flow** 的 noop 与发布关系以契约为准)。
264
272
  - **文件体形状**:与 **`app_schema_apply`** 契约一致;顶层 **`add_fields` / `update_fields` / `remove_fields`** 数组。
265
273
  - **标题/封面**:只在字段 JSON 中直接标记,例如 `{"name":"项目名称","type":"text","required":true,"as_data_title":true}`、`{"name":"项目封面","type":"attachment","as_data_cover":true}`。
266
- - **本仓实测**(`ead8ims5i401`,`--no-publish`,`name` 改为未存在过的 **`CLI搭建探针字段_可删`**):`field_diff.added` 成功;同一 **`name`** 不可重复添加,后续请改用 **[schema_add_fields_minimal.example.json](./schema_add_fields_minimal.example.json)** 内模板名或自改唯一名。
274
+ - **本仓实测**(`ead8ims5i401`,`--no-publish`,`name` 改为未存在过的 **`CLI搭建探针字段_可删`**):`field_diff.added` 成功;同一 **`name`** 不可重复添加,后续请改用 **[schema_add_fields_minimal.example.json](../../examples/schema/schema_add_fields_minimal.example.json)** 内模板名或自改唯一名。
267
275
 
268
276
  ### 5.2 布局:`builder layout apply`
269
277
 
@@ -345,7 +353,7 @@ qingflow builder flow apply \
345
353
 
346
354
  **`remove_fields` 项**:**`que_id` / `field_id` / `name`** 之一。
347
355
 
348
- **完整类型表、`schema apply` 场景矩阵、探针结论**:见 **[QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md](./QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md)**。**19 种搭建 `type` 单文件 `add_fields`(推荐新建应用一次成功)**:[schema_apply_add_fields_all_types.json](./schema_apply_add_fields_all_types.json)。
356
+ **完整类型表、`schema apply` 场景矩阵、探针结论**:见 **[30-schema-fields.md](../30-schema-fields.md)**。**19 种搭建 `type` 单文件 `add_fields`(推荐新建应用一次成功)**:[schema_apply_add_fields_all_types.json](../../examples/schema/schema_apply_add_fields_all_types.json)。
349
357
 
350
358
  ---
351
359
 
@@ -357,8 +365,10 @@ qingflow builder flow apply \
357
365
  - 已有按钮:`builder button apply --patch-buttons-file`
358
366
  - 已有关联资源:`builder associated-resource apply --patch-resources-file`
359
367
  - 已有报表:`builder charts apply --patch-file`
368
+ - 已有流程节点:`builder flow apply --patch-nodes-file`
369
+ - 已有门户组件:`builder portal apply --patch-sections-file`
360
370
 
361
- `patch_*` 的语义是:你只写要替换的参数,工具内部读取当前配置、补齐后端必填字段,再整份保存。每个 patch 项直接使用对象真实定位字段 + `set` / 可选 `unset`,不要写字面量 `selector` key。示例:`{"view_key": "VIEW_KEY", "set": {"query_conditions": {...}}}`、`{"button_id": 1001, "set": {"button_text": "新名称"}}`、`{"associated_item_id": 123, "set": {"match_mappings": [...]}}`、`{"chart_id": 456, "set": {"name": "新报表名"}}`。
371
+ `patch_*` 的语义是:你只写要替换的参数,工具内部读取当前配置、补齐后端必填字段,再整份保存。每个 patch 项直接使用对象真实定位字段 + `set` / 可选 `unset`,不要写字面量 `selector` key。示例:`{"view_key": "VIEW_KEY", "set": {"query_conditions": {...}}}`、`{"button_id": 1001, "set": {"button_text": "新名称"}}`、`{"associated_item_id": 123, "set": {"match_mappings": [...]}}`、`{"chart_id": 456, "set": {"name": "新报表名"}}`、`{"id": "node_1", "set": {"name": "主管审批"}}`、`{"chart_ref": {"chart_key": "xxx"}, "set": {"rows": 7}}`。
362
372
 
363
373
  `upsert_*` 用于创建或提供完整目标配置;不要只给 `name/type/query_conditions` 这类局部片段然后期待后端自动合并。
364
374
 
@@ -419,7 +429,7 @@ qingflow builder button apply \
419
429
  - `button_ref` 可以引用同次 `upsert_buttons[].client_key`,也可以引用已有 `button_id`。
420
430
  - `view_configs[].view_key` 使用 `builder app get --app-key APP_KEY` 返回的 raw `view_key`,不要加 `custom:`。
421
431
  - `view_configs[].mode` 默认 `merge`,merge 模式必须传 `buttons`;清空用 `mode="replace"` 或显式 `buttons: []`。
422
- - 字段兼容与 `数据ID` / `编号` 规则见 **[QINGFLOW_CLI_BUILDER_MATCH_RULES.md](./QINGFLOW_CLI_BUILDER_MATCH_RULES.md)**。
432
+ - 字段兼容与 `数据ID` / `编号` 规则见 **[match-rules.md](./match-rules.md)**。
423
433
  - 删除按钮时优先传 **`button_id`**;若用 **`button_text`** 必须能唯一匹配。DELETE 发出后会按单个 **`button_id`** 回读验证,结果看 **`removed[].delete_executed/readback_status/safe_to_retry_delete`**。只要 **`delete_executed=true`**,就不要盲目重复删除;**`readback_status=unavailable|still_exists`** 表示回读待确认。
424
434
  - 该工具有成功写入时自动发布;全阻断、全失败或无变化不会额外发布。
425
435
 
@@ -453,7 +463,7 @@ qingflow builder associated-resource apply \
453
463
  - `client_key` 只用于同一次 apply 内给 `view_configs[].associated_item_refs` 引用,后端不会保存,不能用于后续去重。
454
464
  - 每个主应用都要生成自己的 upsert/view-config payload,不要复用其他应用的 tmp JSON;命令中 `--app-key` 只写一次,且必须与 payload 的主应用一致。
455
465
  - 成功后必须用 `builder app get --app-key ...` 回读:确认 `associated_resources[].associated_item_id` 已生成,并确认目标视图的详情配置中已绑定对应资源。若只看到资源池有记录、视图详情无绑定,继续补 `view_configs`,不能宣称完成。
456
- - 关联筛选优先用 `match_mappings`,不要手写 raw `match_rules`;字段兼容规则见 **[QINGFLOW_CLI_BUILDER_MATCH_RULES.md](./QINGFLOW_CLI_BUILDER_MATCH_RULES.md)**。
466
+ - 关联筛选优先用 `match_mappings`,不要手写 raw `match_rules`;字段兼容规则见 **[match-rules.md](./match-rules.md)**。
457
467
  - 删除关联资源时传 **`associated_item_id`**,也可传已有资源的 `chart_id/chart_key/view_key` 让工具解析为内部 id。后端暂无确认可用的单项关联资源 GET,所以工具只做一次资源池回读验证;结果看 **`removed[].delete_executed/readback_status/safe_to_retry_delete`**。只要 **`delete_executed=true`**,就不要盲目重复删除;**`readback_status=unavailable|still_exists`** 表示回读待确认。
458
468
  - 该工具有成功写入时自动发布;不提供 `--no-publish`。
459
469
 
@@ -483,9 +493,9 @@ qingflow builder publish verify \
483
493
 
484
494
  ## 10. 交叉引用
485
495
 
486
- - **最小 `add_fields` 示例**:[schema_add_fields_minimal.example.json](./schema_add_fields_minimal.example.json)
487
- - **19 种搭建 type 一次性 `add_fields`**:[schema_apply_add_fields_all_types.json](./schema_apply_add_fields_all_types.json)
488
- - **类型与场景总表**:[QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md](./QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md)
489
- - [SKILL.md](../SKILL.md):`builder` 命令边界、**ADMIN** 指向。
490
- - [QINGFLOW_CLI_FIELD_DATA_TYPES.md](./QINGFLOW_CLI_FIELD_DATA_TYPES.md):成员侧 **记录读写** 的 `kind` / 值形态(与 **搭建 `type`** 名称不同系,但可对照理解业务)。
491
- - [QINGFLOW_CLI_ADMIN_CHEATSHEET.md](./QINGFLOW_CLI_ADMIN_CHEATSHEET.md):`package apply`、权限类 **`IMPORT_*` / 40002**。
496
+ - **最小 `add_fields` 示例**:[schema_add_fields_minimal.example.json](../../examples/schema/schema_add_fields_minimal.example.json)
497
+ - **19 种搭建 type 一次性 `add_fields`**:[schema_apply_add_fields_all_types.json](../../examples/schema/schema_apply_add_fields_all_types.json)
498
+ - **类型与场景总表**:[30-schema-fields.md](../30-schema-fields.md)
499
+ - [SKILL.md](../../../SKILL.md):`builder` 命令边界、**ADMIN** 指向。
500
+ - [QINGFLOW_CLI_FIELD_DATA_TYPES.md](../../core/QINGFLOW_CLI_FIELD_DATA_TYPES.md):成员侧 **记录读写** 的 `kind` / 值形态(与 **搭建 `type`** 名称不同系,但可对照理解业务)。
501
+ - [QINGFLOW_CLI_ADMIN_CHEATSHEET.md](../../core/QINGFLOW_CLI_ADMIN_CHEATSHEET.md):`package apply`、权限类 **`IMPORT_*` / 40002**。
@@ -0,0 +1,293 @@
1
+ # Qingflow CLI App Builder Playbooks
2
+
3
+ ## Overview
4
+
5
+ This section is for the current **public builder surface** through `qingflow builder ...`, not for legacy low-level builder writes.
6
+
7
+ Before any write or verification flow, identify whether the task targets `test` or `prod` and read [environments.md](./environments.md). If the user did not specify one, default to `prod`.
8
+
9
+ Before choosing a route, skim the shared maintenance baseline: [public-surface-sync.md](./public-surface-sync.md).
10
+
11
+ ## CLI-only Execution Rule
12
+
13
+ Examples in this directory are CLI payload examples and workflow notes. Execute through the matching `qingflow` command from [SKILL.md](../../../../SKILL.md), the command index, or the canonical builder reference files; do not call internal tool JSON.
14
+
15
+ ## Current Public Mental Model
16
+
17
+ Model builder requests in four layers and keep them separate:
18
+
19
+ - `package`: the app bundle or solution container
20
+ - `app`: one form/app inside that package
21
+ - `field`: one field inside one app
22
+ - `relation`: a field that links one app to another app
23
+
24
+ Default modeling rules:
25
+
26
+ - One business object -> one app
27
+ - Attributes of that object -> fields inside that app
28
+ - Another business object -> a separate app, not a text field
29
+ - Cross-object links -> relation fields, not text fields
30
+
31
+ ## Public Tools You Should Think In
32
+
33
+ - Package: `qingflow builder package get/apply`
34
+ - App reads: `qingflow builder app resolve/get`, including batch `--app-keys`
35
+ - Builder reads: `qingflow builder portal/view/chart/contract`
36
+ - Directory: `qingflow builder member/role`
37
+ - Writes: `qingflow builder schema/layout/flow/views/button/associated-resource/charts/portal apply`
38
+ - Verification: `qingflow builder publish verify`
39
+
40
+ Treat these as the official surface. Do not default to `package_create`, `package_attach_app`, raw `portal_*` writes, or raw `qingbi_report_*` writes.
41
+
42
+ ## Current Public Defaults
43
+
44
+ - Package work:
45
+ - use `package_get(package_id=...)` to read one known package
46
+ - use `package_apply(...)` for package creation, rename, icon, visibility, grouping, ordering, and app/portal layout
47
+ - Multi-app schema work:
48
+ - use one CLI `builder schema apply --apps-file` when creating several apps in one package
49
+ - same-call relation fields may use `target_app_ref` to point at another `apps[].client_key`
50
+ - Batch reads:
51
+ - `builder app get`, `button get`, `associated-resource get`, and `publish verify` accept `--app-keys`
52
+ - when reading several apps, prefer one batch read and inspect both `apps[]` and `errors[]`
53
+ - Batch writes:
54
+ - `builder layout/views/button/associated-resource/charts apply --apps-file` accepts multi-app batch writes
55
+ - each `apps[]` item carries its own `app_key` plus that tool's normal single-app payload
56
+ - App base permissions:
57
+ - trust `app_get.editability.can_edit_app_base` for app base-info writes like app name, icon, and visibility
58
+ - `can_edit_form` only means schema/form-route capability; it no longer implies app base-info write capability
59
+ - Partial update rule:
60
+ - for existing views, custom buttons, associated resources, and charts, prefer `patch_views` / `patch_buttons` / `patch_resources` / `patch_charts`
61
+ - for existing workflow nodes, use `builder flow apply --patch-nodes-file` instead of rewriting the full `spec`
62
+ - for existing portal sections, use `builder portal apply --patch-sections-file` instead of replacing all `sections`
63
+ - each patch item uses the object's real selector field (`view_key` / `button_id` / `associated_item_id` / `chart_id`, or unique name where supported) plus `set` and optional `unset`; do not send a literal `selector` key for these tools
64
+ - use `upsert_*` for creation or full target configuration; do not send a partial `upsert_*` and expect the backend to merge missing required fields
65
+ - Portal work:
66
+ - `portal_apply` is the public write path
67
+ - in edit mode, omitting `sections` means “preserve existing layout and update base info only”
68
+ - supplying `sections` means full replace semantics for sections
69
+ - portal sections use a 24-column PC grid; all components sharing the same `y` coordinate must have identical `rows` values and their `cols` must sum to exactly 24; mixing `rows` in the same row causes height misalignment, and a `cols` sum under 24 leaves blank space at the row end; the next row's `y` must equal the previous row's `y` + `rows`
70
+ - Chart work:
71
+ - `app_charts_apply` is the public write path for app-source QingBI report bodies/configs; it creates/updates reports with `dataSourceType=qingflow`
72
+ - dataset BI reports are not created or edited by `app_charts_apply` yet; create them in QingBI first, then attach the existing report with `app_associated_resources_apply` and `report_source="dataset"`
73
+ - it does not attach the report to the Qingflow app associated-resource display; use `app_associated_resources_apply` for that
74
+ - supported `chart_type` values include legacy public aliases `target`, `table` and QingBI types such as `summary`, `columnar`, `area`, `stacked_area`, `funnel`, `waterfall`, `gauge`, `heatmap`, `histogram`, `treemap`, `radar`, `stacked_bar`, `stacked_column`, `scatter`, `ring`, `rose`, `dualaxes`, `map`, and `timeline`
75
+ - use `patch_charts` for changing a chart name, visibility, filters, or one config fragment on an existing chart
76
+ - `visibility` is a public capability and should be treated as a base-only permission update
77
+ - do not model chart visibility changes as raw config rewrites
78
+ - Button work:
79
+ - `app_custom_buttons_apply` is the public write path for custom button bodies and view placement
80
+ - use `patch_buttons` for changing a single existing button parameter such as URL, text, icon, style, or add-data mapping
81
+ - for add-data buttons, use `trigger_add_data_config.target_app_key + field_mappings/default_values`; do not handwrite raw `que_relation`
82
+ - use `field_mappings` for dynamic current-record values, including system fields such as `数据ID` (`field_id=-17`) and `编号` (`field_id=0`)
83
+ - to prefill a target relation field with the current source record, map `{"source_field": "数据ID", "target_field": "目标引用字段"}`; use `default_values` only for static constants
84
+ - if field type compatibility is unclear, read [match-rules.md](./match-rules.md)
85
+ - bind buttons to views through `view_configs[].buttons[]`; default to `placement`: `header` or `detail`
86
+ - builder `view_configs[].view_key` uses the raw key from `app_get.views[].view_key`, without a `custom:` prefix
87
+ - `buttons` is required in merge mode; do not send a view config with only `view_key`
88
+ - `view_configs[].mode` defaults to `merge`; use `mode: "replace"` or an explicit empty `buttons: []` to clear a view's custom button bindings
89
+ - `placement=list` configures row/list buttons and maps to the backend `INSIDE` button position
90
+ - advanced bindings may use `button_limit`, `button_formula`, `button_formula_type`, and `print_tpls` only when visibility or print-template behavior is required
91
+ - Associated resources:
92
+ - `app_associated_resources_apply` is the public write path for the Qingflow app-level associated report/view pool and per-view display config
93
+ - for multi-app systems, use `apps[]` to batch associated-resource writes; each item carries its own `app_key` plus `upsert_resources` / `patch_resources` / `view_configs`
94
+ - it attaches existing BI reports/views for in-app display; it does not create or edit QingBI report bodies/configs, including dataset reports
95
+ - use `patch_resources` for changing match rules or other existing associated-resource parameters; the tool preserves backend-required raw fields internally
96
+ - `associated_item_id` is the backend internal associated-resource id; for `view_configs`, `remove_associated_item_ids`, and `reorder_associated_item_ids`, you may pass `associated_item_id` or an existing resource's `chart_id`/`chart_key`/`view_key`, and the tool resolves it to the internal id
97
+ - before creating a resource, check `app_get.associated_resources` for the same `target_app_key + view_key/chart_key`; if it already exists, use `patch_resources` with that `associated_item_id`
98
+ - `client_key` is only a same-call reference for `view_configs[].associated_item_refs`; it is not saved and cannot deduplicate later calls
99
+ - do not pass backend raw `sourceType`; view resources infer the internal Qingflow view source, report/chart resources default to BI app reports, and existing dataset reports use `report_source="dataset"`
100
+ - use `match_mappings` for associated view/report filters; dynamic conditions use `source_field`, static conditions use `value`
101
+ - if field type compatibility is unclear, read [references/match-rules.md](./match-rules.md)
102
+ - Views and flows:
103
+ - stay on `app_views_apply` / `app_flow_apply`
104
+ - use `patch_views` for existing-view parameter changes such as `query_conditions`, `filters`, `columns`, or visibility
105
+ - builder view writes use raw `view_key` values from `app_get.views`; `custom:<viewKey>` is a record-data `view_id` form, not a builder `view_key`
106
+ - use `qingflow --json builder contract` whenever the minimal legal shape is unclear
107
+ - keep view `filters` and `query_conditions` separate: `filters` are fixed saved filters; `query_conditions` configure the frontend query panel fields and only take effect after users enter query values
108
+ - when creating any new table or card view, always include `query_conditions` with `enabled: true`; populate `rows` with the fields most useful for searching — typically the data-title field, any status/type select fields, date fields, and member fields; do not omit `query_conditions` or leave `rows` empty on a new view
109
+ - new views default the associated report/view display area to visible with `limit_type="all"`; existing views preserve their current associated-resource display unless `associated_resources` is explicitly patched
110
+ - configure associated reports/views through `app_associated_resources_apply`, not through `app_views_apply`
111
+
112
+ ## Standard Operating Order
113
+
114
+ 1. Ensure auth exists
115
+ 2. Ensure workspace is selected
116
+ 3. Confirm whether the task is read-only or write-impacting
117
+ 4. Resolve the smallest stable target:
118
+ - app-scoped work -> `app_resolve`
119
+ - package-scoped work with known id -> `package_get`
120
+ - portal inventory -> `portal_list`
121
+ 5. Read only the smallest config slice needed:
122
+ - app map -> `app_get` (default entry; includes compact views, charts, custom buttons, and associated resource pool)
123
+ - fields -> `app_get_fields`
124
+ - layout -> `app_get_layout`
125
+ - views -> `app_get_views` only when the app_get compact list is not enough
126
+ - flow -> `app_get_flow`
127
+ - charts -> `app_get_charts` only when the app_get compact list is not enough
128
+ - portal -> `portal_get`
129
+ 6. If the public shape is unclear, call `qingflow --json builder contract`
130
+ 7. Apply the smallest patch tool that fits:
131
+ - fields -> `app_schema_apply`
132
+ - layout -> `app_layout_apply`
133
+ - flow -> `app_flow_apply`
134
+ - existing views -> `app_views_apply.patch_views`; new/full views -> `app_views_apply.upsert_views`
135
+ - existing buttons -> `app_custom_buttons_apply.patch_buttons`; new/full buttons -> `app_custom_buttons_apply.upsert_buttons`
136
+ - existing associated resources -> `app_associated_resources_apply.patch_resources`; new/full resources -> `app_associated_resources_apply.upsert_resources`
137
+ - existing charts -> `app_charts_apply.patch_charts`; new/full charts -> `app_charts_apply.upsert_charts`
138
+ - portal -> `portal_apply`
139
+ - package metadata/layout -> `package_apply`
140
+ 8. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need a dedicated verification pass
141
+
142
+ ## Safe Usage Rules
143
+
144
+ - Do not guess package identity from a loose name. Public package work assumes a known `package_id`, or an explicit create/update intent through `package_apply`.
145
+ - If `package_id` is unknown, derive it from related app/portal readback when possible; otherwise ask the user instead of falling back to hidden package lookup tools.
146
+ - Do not use `package_create` or `package_attach_app` as a public default path. If they still appear in low-level code, treat them as internal/legacy implementation details.
147
+ - Do not use raw `portal_*` writes or raw `qingbi_report_*` writes as the default builder strategy.
148
+ - Always pass `publish: true` (or CLI `--publish`) explicitly on `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, and `portal_apply` — do not rely on the default. `app_custom_buttons_apply` and `app_associated_resources_apply` publish automatically after at least one write succeeds and do not accept a `publish` parameter. `app_charts_apply` is immediate-live without a publish step.
149
+ - When creating or updating fields, configure the app data title/cover directly in field JSON: `as_data_title: true` is required on exactly one readable top-level title field; `as_data_cover: true` is optional and only valid on one top-level `attachment` field.
150
+ - When any tool returns `error_code` or `VALIDATION_ERROR`, read the `message` field verbatim first before guessing at parameter or CLI parsing issues. A clear `message` like "relation field requires visible_fields" is the root cause — do not redirect to unrelated hypotheses such as `create_if_missing` parsing or flag conflicts.
151
+ - If the same validation error repeats twice, stop guessing and re-read `qingflow --json builder contract`.
152
+ - For workflow assignees, prefer `role_search` over explicit members unless the user explicitly wants named members.
153
+ - Public flow building is still intentionally limited to stable linear workflows. If a requirement sounds like branches/conditions, explain the limitation instead of freehanding unsupported graph shapes.
154
+ - Respect collaborative edit locks. Only use `app_release_edit_lock_if_mine` when the lock owner is the current authenticated user.
155
+ - If the supported builder surface is still awkward or blocked after reasonable use, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation.
156
+
157
+ ## Response Interpretation
158
+
159
+ - All builder apply/write tools return a standard UI envelope in addition to legacy fields:
160
+ `schema_version`, `operation`, `summary`, and `resources[]`.
161
+ - For UI cards or quick narration, read `resources[]` first. Each resource has `resource_type`, `operation`, `status`, `id`, `key`, `name`, typed `ids`, and `parent`.
162
+ - Use legacy fields such as `field_diff`, `views_diff`, `chart_results`, `created/updated/removed`, and `verification` only for compatibility and troubleshooting.
163
+ - Treat post-write readback as the source of truth, not just write status codes.
164
+ - `success` means write and verification completed; `partial_success` means the write landed but verification is incomplete.
165
+ - For portals, distinguish clearly between:
166
+ - base-info-only update with layout preserved
167
+ - full sections replace
168
+ - For object apply tools, distinguish clearly between:
169
+ - `patch_*`: public partial parameter replacement; the tool hydrates current config and full-saves internally
170
+ - `upsert_*`: create or full target configuration; omitted fields may mean default/clear depending on that object
171
+ - For charts, distinguish clearly between:
172
+ - base / visibility change
173
+ - real chart-config change
174
+ - For app permissions, report `can_edit_app_base` separately from `can_edit_form / can_edit_flow / can_edit_views / can_edit_charts`.
175
+
176
+ ## Practical Patterns
177
+
178
+ - Read one package: `package_get`
179
+ - Create or update one package: `package_apply`
180
+ - Resolve one app: `app_resolve`
181
+ - Read one app map: `app_get`
182
+ - Batch read app maps/slices: `app_get_*` with `app_keys[]`
183
+ - Read fields only: `app_get_fields`
184
+ - Read layout summary: `app_get_layout`
185
+ - Read views summary: `app_get_views`
186
+ - Read flow summary: `app_get_flow`
187
+ - Read chart summary: `app_get_charts`
188
+ - Read portal config: `portal_get`
189
+ - Search members or roles: `member_search`, `role_search`
190
+ - Create reusable role: `role_create`
191
+ - Add/update/remove fields: `app_schema_apply`
192
+ - Merge or replace layout: `app_layout_apply` (single app) or `apps[]` batch
193
+ - Replace workflow or patch nodes: `app_flow_apply`
194
+ - Upsert/patch/remove views: `app_views_apply` (single app) or `apps[]` batch
195
+ - Upsert/patch/remove custom buttons and bind them to header/detail view positions: `app_custom_buttons_apply` (single app) or `apps[]` batch
196
+ - Upsert/patch/remove app associated reports/views and per-view display: `app_associated_resources_apply`
197
+ - Upsert/patch/remove/reorder charts: `app_charts_apply` (single app) or `apps[]` batch
198
+ - Create, update, or patch portal pages: `portal_apply`
199
+ - Release your own stale edit lock: `app_release_edit_lock_if_mine`
200
+ - Final publish verification: `app_publish_verify`
201
+
202
+ ## Button Pattern
203
+
204
+ Use `app_custom_buttons_apply` for the whole custom-button path: button body, add-data mapping, default values, and placement.
205
+
206
+ > CLI-only note: this is the payload from former internal surface `app_custom_buttons_apply`. Execute it through the matching `qingflow` CLI command and `--*-file` flags from SKILL.md / builder reference; do not call internal tool JSON.
207
+
208
+ ```json
209
+ {
210
+ "app_key": "EMPLOYEE_APP",
211
+ "upsert_buttons": [
212
+ {
213
+ "client_key": "add_worklog",
214
+ "button_text": "快捷添加工时",
215
+ "style_preset": "primary_blue",
216
+ "button_icon": "ex-plus-circle",
217
+ "trigger_action": "addData",
218
+ "trigger_add_data_config": {
219
+ "target_app_key": "WORKLOG_APP",
220
+ "field_mappings": [
221
+ {
222
+ "source_field": "数据ID",
223
+ "target_field": "关联员工"
224
+ },
225
+ {
226
+ "source_field": "员工名称",
227
+ "target_field": "员工姓名"
228
+ },
229
+ {
230
+ "source_field": "所属部门",
231
+ "target_field": "部门名称"
232
+ }
233
+ ],
234
+ "default_values": {
235
+ "工时类型": "日常工作",
236
+ "状态": "待提交"
237
+ }
238
+ }
239
+ }
240
+ ],
241
+ "remove_buttons": [],
242
+ "view_configs": [
243
+ {
244
+ "view_key": "EMPLOYEE_VIEW",
245
+ "mode": "merge",
246
+ "buttons": [
247
+ {
248
+ "button_ref": "add_worklog",
249
+ "placement": "detail",
250
+ "primary": true
251
+ }
252
+ ]
253
+ }
254
+ ]
255
+ }
256
+ ```
257
+
258
+ `button_ref` may be a same-call `client_key` or an existing `button_id`. Supported placements are `header`, `detail`, and `list`; `list` maps to the backend `INSIDE` row/list button position.
259
+
260
+ For add-data buttons that create a child record linked back to the current record, map `source_field: "数据ID"` to the target relation field. Do not use raw `que_relation` unless maintaining an existing backend config.
261
+
262
+ ## Historical Playbook Selection
263
+
264
+ This file is historical supporting material. For the current main route, start from [../../README.md](../../README.md). If you still use this page, route to the current resource document first:
265
+
266
+ | User intent | Signal phrases | Playbook |
267
+ |-------------|---------------|---------|
268
+ | Multi-app business system with cross-app relations, shared workflow, and a portal dashboard | "建一套系统"、"包含 N 个模块"、"这几个表单之间建立关联"、"完整的业务系统" | [20-build-complete-system.md](../../20-build-complete-system.md) |
269
+ | Single app end-to-end: rich schema, layout, flow, multiple view types, custom buttons, in-app charts, associated resources, and sample data | "建一个应用"、"帮我搭一个XX管理"、"从零开始建一个XX"、"我需要一个管理XX的应用" | [10-build-single-app.md](../../10-build-single-app.md) |
270
+ | Add one new app inside an existing package | "在这个包里加一个表单"、"现有系统里新增一个模块" | [create-app.md](./create-app.md) |
271
+ | Update fields or schema only | "加一个字段"、"改字段名"、"删除字段" | [30-schema-fields.md](../../30-schema-fields.md) |
272
+ | Update layout only | "调整分组"、"改排列顺序" | [40-layout.md](../../40-layout.md) |
273
+ | Update workflow only | "修改审批流"、"加一个审批节点" | [90-workflow.md](../../90-workflow.md) |
274
+ | Update views only | "加一个看板"、"改筛选条件"、"新增视图" | [50-views.md](../../50-views.md) |
275
+
276
+ Decision rule: if the user mentions **multiple related apps or a portal**, use [20-build-complete-system.md](../../20-build-complete-system.md). If it is **one app** with a from-scratch setup request, use [10-build-single-app.md](../../10-build-single-app.md). If the target app already exists and the user only wants to change one layer, use the matching resource document.
277
+
278
+ ## Resources
279
+
280
+ - Shared public-surface baseline: [public-surface-sync.md](./public-surface-sync.md)
281
+ - Environment switching: [environments.md](./environments.md)
282
+ - Tool choice and sequencing: [tool-selection.md](./tool-selection.md)
283
+ - Field matching rules: [../match-rules.md](../match-rules.md)
284
+ - Result semantics and gotchas: [gotchas.md](./gotchas.md)
285
+ - Create one app in an existing package: [create-app.md](./create-app.md)
286
+ - Update fields only: [../../30-schema-fields.md](../../30-schema-fields.md)
287
+ - Update layout only: [../../40-layout.md](../../40-layout.md)
288
+ - Update workflow only: [../../90-workflow.md](../../90-workflow.md)
289
+ - Workflow assignees and node permissions: [flow-actors-and-permissions.md](./flow-actors-and-permissions.md)
290
+ - Update views only: [../../50-views.md](../../50-views.md)
291
+ - Standard end-to-end builder sequences: [solution-playbooks.md](./solution-playbooks.md)
292
+ - Build a complete multi-app system from scratch: [../../20-build-complete-system.md](../../20-build-complete-system.md)
293
+ - Build a single app end-to-end: [../../10-build-single-app.md](../../10-build-single-app.md)