@qingflow-tech/qingflow-app-builder-mcp 1.0.2 → 1.0.4

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 (53) hide show
  1. package/README.md +2 -2
  2. package/docs/local-agent-install.md +9 -3
  3. package/npm/lib/runtime.mjs +10 -3
  4. package/package.json +1 -1
  5. package/pyproject.toml +1 -1
  6. package/skills/qingflow-app-builder/SKILL.md +88 -184
  7. package/skills/qingflow-app-builder/references/create-app.md +15 -34
  8. package/skills/qingflow-app-builder/references/gotchas.md +3 -3
  9. package/skills/qingflow-app-builder/references/solution-playbooks.md +1 -2
  10. package/skills/qingflow-app-builder/references/tool-selection.md +9 -10
  11. package/src/qingflow_mcp/__init__.py +33 -1
  12. package/src/qingflow_mcp/backend_client.py +109 -0
  13. package/src/qingflow_mcp/builder_facade/button_style_catalog.py +282 -0
  14. package/src/qingflow_mcp/builder_facade/models.py +58 -9
  15. package/src/qingflow_mcp/builder_facade/service.py +1711 -240
  16. package/src/qingflow_mcp/cli/commands/__init__.py +2 -1
  17. package/src/qingflow_mcp/cli/commands/app.py +47 -1
  18. package/src/qingflow_mcp/cli/commands/auth.py +63 -0
  19. package/src/qingflow_mcp/cli/commands/builder.py +11 -3
  20. package/src/qingflow_mcp/cli/commands/exports.py +111 -0
  21. package/src/qingflow_mcp/cli/commands/record.py +5 -5
  22. package/src/qingflow_mcp/cli/commands/task.py +701 -27
  23. package/src/qingflow_mcp/cli/commands/workspace.py +84 -0
  24. package/src/qingflow_mcp/cli/context.py +3 -0
  25. package/src/qingflow_mcp/cli/formatters.py +424 -50
  26. package/src/qingflow_mcp/cli/interaction.py +72 -0
  27. package/src/qingflow_mcp/cli/main.py +11 -1
  28. package/src/qingflow_mcp/cli/qingflow_login.py +116 -0
  29. package/src/qingflow_mcp/cli/terminal_ui.py +218 -0
  30. package/src/qingflow_mcp/config.py +1 -1
  31. package/src/qingflow_mcp/errors.py +4 -4
  32. package/src/qingflow_mcp/export_store.py +14 -0
  33. package/src/qingflow_mcp/id_utils.py +49 -0
  34. package/src/qingflow_mcp/public_surface.py +16 -1
  35. package/src/qingflow_mcp/response_trim.py +394 -9
  36. package/src/qingflow_mcp/server.py +26 -0
  37. package/src/qingflow_mcp/server_app_builder.py +15 -1
  38. package/src/qingflow_mcp/server_app_user.py +113 -0
  39. package/src/qingflow_mcp/session_store.py +126 -21
  40. package/src/qingflow_mcp/solution/compiler/form_compiler.py +2 -2
  41. package/src/qingflow_mcp/solution/executor.py +2 -2
  42. package/src/qingflow_mcp/tools/ai_builder_tools.py +107 -34
  43. package/src/qingflow_mcp/tools/app_tools.py +1 -0
  44. package/src/qingflow_mcp/tools/auth_tools.py +243 -9
  45. package/src/qingflow_mcp/tools/base.py +6 -2
  46. package/src/qingflow_mcp/tools/code_block_tools.py +2 -2
  47. package/src/qingflow_mcp/tools/custom_button_tools.py +0 -2
  48. package/src/qingflow_mcp/tools/export_tools.py +1565 -0
  49. package/src/qingflow_mcp/tools/import_tools.py +78 -4
  50. package/src/qingflow_mcp/tools/record_tools.py +551 -165
  51. package/src/qingflow_mcp/tools/resource_read_tools.py +154 -33
  52. package/src/qingflow_mcp/tools/task_context_tools.py +917 -141
  53. package/src/qingflow_mcp/tools/workspace_tools.py +141 -0
package/README.md CHANGED
@@ -3,13 +3,13 @@
3
3
  Install:
4
4
 
5
5
  ```bash
6
- npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.2
6
+ npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.4
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.2 qingflow-app-builder-mcp
12
+ npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.4 qingflow-app-builder-mcp
13
13
  ```
14
14
 
15
15
  Environment:
@@ -20,6 +20,12 @@
20
20
 
21
21
  `auth_use_credential` 是本地唯一鉴权主路径。
22
22
 
23
+ 补充说明:
24
+
25
+ - 对 stdio MCP 来说,主路径仍然只有 `auth_use_credential`。
26
+ - 如果你是在终端里直接使用 `qingflow` CLI,可以额外使用 `qingflow auth login` 作为“人类登录”入口;默认会提示轻流邮箱和隐藏密码,拿到 `token` 后建立本地 CLI 会话。
27
+ - 也就是说,这次新增的是 CLI 的登录入口,不是给 MCP 增加第二套会话模型。
28
+
23
29
  ## npm 安装器适用场景
24
30
 
25
31
  适合这类本地 agent / gateway:
@@ -211,7 +217,7 @@ qingflow-app-builder-mcp
211
217
  "command": "npx",
212
218
  "args": [
213
219
  "-y",
214
- "@qingflow-tech/qingflow-app-user-mcp"
220
+ "@josephyan/qingflow-app-user-mcp"
215
221
  ],
216
222
  "env": {
217
223
  "QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
@@ -224,7 +230,7 @@ qingflow-app-builder-mcp
224
230
  "command": "npx",
225
231
  "args": [
226
232
  "-y",
227
- "@qingflow-tech/qingflow-app-builder-mcp"
233
+ "@josephyan/qingflow-app-builder-mcp"
228
234
  ],
229
235
  "env": {
230
236
  "QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
@@ -266,7 +272,7 @@ npm install
266
272
 
267
273
  如果 MCP 客户端一调用工具就报 `Transport closed`,优先检查这几件事:
268
274
 
269
- 1. 不要混用不同版本的 `@qingflow-tech/qingflow-cli`、`@qingflow-tech/qingflow-app-user-mcp`、`@qingflow-tech/qingflow-app-builder-mcp`
275
+ 1. 不要混用不同版本的 `@josephyan/qingflow-cli`、`@josephyan/qingflow-app-user-mcp`、`@josephyan/qingflow-app-builder-mcp`
270
276
  2. 删除安装目录下的 `.npm-python`
271
277
  3. 重新执行 `npm install` 或重新安装对应 tgz/npm 包
272
278
  4. 再启动 MCP 客户端
@@ -287,7 +287,12 @@ function forwardSignal(child, signal) {
287
287
  });
288
288
  }
289
289
 
290
- export function spawnServer(packageRoot, args, commandName = "qingflow-mcp", { allowRuntimeBootstrap = false } = {}) {
290
+ export function spawnServer(
291
+ packageRoot,
292
+ args,
293
+ commandName = "qingflow-mcp",
294
+ { allowRuntimeBootstrap = false, stdio = "proxy" } = {},
295
+ ) {
291
296
  let runtime = inspectPythonEnv(packageRoot, commandName);
292
297
  let serverCommand = runtime.serverCommand;
293
298
 
@@ -315,12 +320,14 @@ export function spawnServer(packageRoot, args, commandName = "qingflow-mcp", { a
315
320
  }
316
321
 
317
322
  const child = spawn(serverCommand, args, {
318
- stdio: ["pipe", "pipe", "pipe"],
323
+ stdio: stdio === "inherit" ? "inherit" : ["pipe", "pipe", "pipe"],
319
324
  env: process.env,
320
325
  windowsHide: true,
321
326
  });
322
327
 
323
- proxyStreams(child);
328
+ if (stdio !== "inherit") {
329
+ proxyStreams(child);
330
+ }
324
331
  forwardSignal(child, "SIGINT");
325
332
  forwardSignal(child, "SIGTERM");
326
333
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qingflow-tech/qingflow-app-builder-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Builder MCP for Qingflow app/package/system design and staged solution workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "0.2.0b87"
7
+ version = "1.0.4"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -9,36 +9,22 @@ metadata:
9
9
 
10
10
  ## Overview
11
11
 
12
- This skill helps a system builder use the AI-native Qingflow builder surface safely. It assumes the MCP is already connected and authenticated. If not, switch to `$qingflow-mcp-setup` first.
12
+ This skill is for the current **public builder surface**, not for legacy low-level builder writes.
13
+ Assumes MCP is already connected, authenticated, and on the correct workspace.
13
14
 
14
15
  Before any write or verification flow, identify whether the task targets `test` or `prod` and read [references/environments.md](references/environments.md). If the user did not specify one, default to `prod`.
15
16
 
16
- ## Tool Selection
17
+ Before choosing a route, skim the shared maintenance baseline: [public-surface-sync.md](../qingflow-app-user/references/public-surface-sync.md).
17
18
 
18
- Pick the smallest tool layer that can finish the task.
19
+ ## Current Public Mental Model
19
20
 
20
- ## Shared Helper
21
+ Model builder requests in four layers and keep them separate:
21
22
 
22
- - `feedback_submit` is a cross-cutting helper for product feedback submission
23
- - It does not require Qingflow login or workspace selection
24
- - If builder capability is unsupported or still cannot satisfy the need after reasonable use, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation.
25
-
26
- ## Mental Model
27
-
28
- Model builder requests in four layers. Do not flatten them.
29
-
30
- - `package`: the solution container or app bundle, for example “研发项目管理” or “费控管理系统”
31
- - `app`: one form/app inside that package, for example “项目”, “需求”, “任务”, “缺陷”, “团队”
23
+ - `package`: the app bundle or solution container
24
+ - `app`: one form/app inside that package
32
25
  - `field`: one field inside one app
33
26
  - `relation`: a field that links one app to another app
34
27
 
35
- Interpret user intent with this hierarchy:
36
-
37
- - If the user says “应用包”, “系统”, “包含多个表单”, “多个模块”, or asks for several named forms that relate to each other, treat it as a `package` with multiple `apps`
38
- - Do not compress a multi-app system into one app with several text fields
39
- - Names like “项目/需求/任务/缺陷/团队” or “费用申请/预算管理/报销审批” are usually separate apps, not text fields
40
- - Build the apps first, then add `relation` fields to connect them
41
-
42
28
  Default modeling rules:
43
29
 
44
30
  - One business object -> one app
@@ -46,176 +32,95 @@ Default modeling rules:
46
32
  - Another business object -> a separate app, not a text field
47
33
  - Cross-object links -> relation fields, not text fields
48
34
 
49
- - Authentication and workspace: `auth_*`, `workspace_*`
50
- - File upload: `file_upload_local`
51
- - Resource resolve/read: `package_list`, `package_resolve`, `package_create`, `builder_tool_contract`, `member_search`, `role_search`, `app_resolve`, `app_get`, `app_get_fields`, `app_get_layout`, `app_get_views`, `app_get_flow`, `app_get_charts`, `portal_list`, `portal_get`, `view_get`, `chart_get`
52
- - Resource patch: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_charts_apply`, `portal_apply`, `package_attach_app`, `app_release_edit_lock_if_mine`, `role_create`
53
- - Publish and verify: `app_publish_verify`
54
-
55
- Note:
56
- - Do not try to handcraft raw Qingflow schema or internal solution payloads.
57
- - Do not rely on low-level `view_*`, `workflow_*`, `qingbi_report_*`, or `portal_*` write payloads from public builder flows.
58
- - Public builder work should stay on the resource path: `resolve -> summary read -> apply -> attach -> publish_verify`.
59
- - `app_schema_apply` / `app_layout_apply` / `app_flow_apply` / `app_views_apply` publish by default; pass `publish=false` only when you intentionally want to leave changes in draft.
60
- - `app_charts_apply` is immediate-live and does not publish; it resolves targets by `chart_id` first and then exact unique chart name.
61
- - `portal_apply` uses replace semantics for sections; remove a section by omitting it from the next full sections list. `publish=false` only guarantees draft/base-info updates, and `chart_ref/view_ref` resolve by `id/key` first and exact unique name second.
62
- - `app_get_charts` is the compact discovery path for current chart inventory; use it before `app_charts_apply` when you need exact `chart_id` values.
63
- - `chart_get` returns one chart's base info and config only; public builder flows should treat data reads as user-side access, not builder config access.
64
- - `portal_list` is the discovery path for builder-configurable portals.
65
- - `portal_get` returns portal-level config detail plus a component inventory; it does not inline chart/view detail or user-side chart/view data.
66
- - `view_get` returns one view's definition detail only; use `record_list` separately when you need rows from that view.
67
- - `app_schema_apply` / `app_layout_apply` / `app_flow_apply` / `app_views_apply` now perform planning, normalization, and dependency checks internally; when prechecks block, read the returned blocking issues and `suggested_next_call` directly from the apply result.
68
- - If you are unsure about a public builder tool's keys, aliases, presets, or minimal legal shape, call `builder_tool_contract` instead of guessing.
69
- - For views, always write the canonical key `columns`. Do not emit `column_names`; treat `fields` only as a tolerated legacy alias, not the preferred shape.
70
- - For flow presets, map natural language to canonical values before calling MCP:
71
- - “默认审批/基础审批/普通审批” -> `basic_approval`
72
- - “先填报再审批/提交后审批” -> `basic_fill_then_approve`
73
- - Public flow building is intentionally limited to linear workflows:
74
- - `start`
75
- - `approve`
76
- - `fill`
77
- - `copy`
78
- - `webhook`
79
- - `end`
80
- Do not generate `branch` or `condition` nodes in the public builder surface. The backend workflow route is not front-end stable for those node types.
81
- - For first-time flow or view work in a session, read `builder_tool_contract` before planning so keys, aliases, presets, and minimal examples come from MCP instead of memory.
82
- - For workflow assignees, prefer roles over explicit members:
83
- - use `role_search` first
84
- - use `member_search` only when the user explicitly names members or no stable role exists
85
- - use `role_create` when the business owner wants a reusable directory role instead of hard-coded members
86
- - On any `VALIDATION_ERROR`, inspect `suggested_next_call` first and prefer reusing the MCP-normalized arguments over re-guessing from the original natural language.
87
- - If the current MCP capability is unsupported, the workflow is awkward, or the user's need still cannot be satisfied after reasonable use, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation.
88
-
89
- Default policy:
90
-
91
- - Creating or updating one app inside an existing package: resolve the package/app, read compact state, then apply schema/layout/flow/views patches explicitly.
92
- - If package creation looks necessary or beneficial, ask the user to confirm before calling `package_create`.
93
- - If the user describes a system/package with multiple forms or modules, do not start with `app_schema_apply` on the package name. Resolve or create the package first, then create each app separately.
35
+ ## Public Tools You Should Think In
36
+
37
+ - Package: `package_get`, `package_apply`
38
+ - App reads: `app_resolve`, `app_get`, `app_get_fields`, `app_get_layout`, `app_get_views`, `app_get_flow`, `app_get_charts`
39
+ - Builder reads: `portal_list`, `portal_get`, `view_get`, `chart_get`, `builder_tool_contract`
40
+ - Directory: `member_search`, `role_search`, `role_create`
41
+ - Writes: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_charts_apply`, `portal_apply`, `app_release_edit_lock_if_mine`
42
+ - Verification: `app_publish_verify`
43
+ - Cross-cutting escalation: `feedback_submit` after explicit user confirmation when the public builder surface still cannot satisfy the user's need
44
+
45
+ Treat these as the official surface. Do not default to `package_create`, `package_attach_app`, raw `portal_*` writes, or raw `qingbi_report_*` writes.
46
+
47
+ ## Current Public Defaults
48
+
49
+ - Package work:
50
+ - use `package_get(package_id=...)` to read one known package
51
+ - use `package_apply(...)` for package creation, rename, icon, visibility, grouping, ordering, and app/portal layout
52
+ - App base permissions:
53
+ - trust `app_get.editability.can_edit_app_base` for app base-info writes like app name, icon, and visibility
54
+ - `can_edit_form` only means schema/form-route capability; it no longer implies app base-info write capability
55
+ - Portal work:
56
+ - `portal_apply` is the public write path
57
+ - in edit mode, omitting `sections` means “preserve existing layout and update base info only”
58
+ - supplying `sections` means full replace semantics for sections
59
+ - Chart work:
60
+ - `app_charts_apply` is the public write path
61
+ - `visibility` is a public capability and should be treated as a base-only permission update
62
+ - do not model chart visibility changes as raw config rewrites
63
+ - Views and flows:
64
+ - stay on `app_views_apply` / `app_flow_apply`
65
+ - use `builder_tool_contract` whenever the minimal legal shape is unclear
94
66
 
95
67
  ## Standard Operating Order
96
68
 
97
- Before any business tool:
98
-
99
69
  1. Ensure auth exists
100
70
  2. Ensure workspace is selected
101
71
  3. Confirm whether the task is read-only or write-impacting
102
-
103
- For builder work:
104
-
105
- 1. Resolve the target package with `package_resolve`; if resolution is ambiguous or you need a read-only fallback, use `package_list`. If you believe a new package should be created, ask the user to confirm before calling `package_create`.
106
- 2. Decide whether the target is one app or a multi-app package:
107
- - one app: continue with `app_resolve`
108
- - multi-app package/system: create or resolve the package, then create each app separately before adding relations
109
- 3. Resolve the target app with `app_resolve` if the request is an update. Use exactly one selector mode: `app_key`, or `app_name + package_tag_id`.
110
- 4. Read only the smallest config slice you need: `app_get`, `app_get_fields`, `app_get_layout`, `app_get_views`, `app_get_flow`, `app_get_charts`, `portal_get`.
111
- 5. Use `app_schema_apply` for create/upsert/remove field work. It publishes by default after the patch lands; noop schema requests do not publish.
112
- 6. If the app must belong to a package, use `package_attach_app` explicitly after schema work with `tag_id + app_key` unless readback already shows the target `tag_id`.
113
- 7. Use `app_layout_apply` only when the user is explicitly changing layout. Prefer the default `mode=merge`; use `mode=replace` only when you intend to place every field explicitly. It publishes by default after the patch lands; noop layout requests do not publish.
114
- 8. Use `app_flow_apply` after schema exists. It publishes by default; pass `publish=false` when you only want draft/precheck behavior.
115
- 9. Use `app_views_apply` when the user wants explicit table/card/board/gantt views. It publishes by default after the patch lands; noop view requests do not publish.
116
- 10. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need an explicit verification pass.
117
- 11. If a write fails with `APP_EDIT_LOCKED`, stop normal writes. Only use `app_release_edit_lock_if_mine` when the failed result shows the lock owner is the current logged-in user.
118
-
119
- For view work, keep the order strict:
120
-
121
- 1. `builder_tool_contract`
122
- 2. `app_get_fields`
123
- 3. `app_get_views`
124
- 4. `app_views_apply`
125
- 5. `app_get_views` again whenever `app_views_apply` returns `failed` or `partial_success`
126
-
127
- For flow work, keep the order strict:
128
-
129
- 1. `builder_tool_contract`
130
- 2. `app_get_fields`
131
- 3. `app_get_flow`
132
- 4. `role_search` or `member_search` if assignees need to come from the directory
133
- 5. `role_create` if the user wants a reusable role and no suitable role exists yet
134
- 6. Start from a canonical preset when possible
135
- 7. Use patch-style edits to that skeleton instead of freehand full-graph generation
136
- 8. When patching a preset skeleton, reuse the preset node ids:
137
- - `basic_approval` -> patch `approve_1`
138
- - `basic_fill_then_approve` -> patch `fill_1` and `approve_1`
139
- Do not invent a second approval/fill node id unless you are intentionally replacing the skeleton and removing the preset node.
140
- 9. Declare approver/fill/copy assignees explicitly:
141
- - prefer `assignees.role_names`
142
- - support `assignees.member_names` / `assignees.member_emails` / `assignees.member_uids`
143
- 10. When a node must edit specific fields, declare `permissions.editable_fields`
144
- 11. `app_flow_apply`
145
- 12. `app_get_flow` after apply whenever the user asked for verification or apply returns `partial_success`
146
- 13. Use `app_get_charts` before chart work whenever exact current `chart_id` values matter
147
- 14. Use `app_charts_apply` for QingBI chart creation and updates, not raw `qingbi_report_*` writes
148
- 15. Use `portal_get` before portal work whenever exact current portal config and section inventory matter
149
- 16. Use `portal_apply` for builder-side portal work; treat sections as a full replacement list
150
-
151
- For additive work on existing systems:
152
-
153
- 1. Confirm the target package or existing apps
154
- 2. Avoid creating a new package unless the user explicitly wants a separate solution
155
- 3. Use ordinary low-level tools for incremental change
156
- 4. Re-verify the affected apps, views, workflows, or portal after modification
72
+ 4. Resolve the smallest stable target:
73
+ - app-scoped work -> `app_resolve`
74
+ - package-scoped work with known id -> `package_get`
75
+ - portal inventory -> `portal_list`
76
+ 5. Read only the smallest config slice needed:
77
+ - app summary -> `app_get`
78
+ - fields -> `app_get_fields`
79
+ - layout -> `app_get_layout`
80
+ - views -> `app_get_views`
81
+ - flow -> `app_get_flow`
82
+ - charts -> `app_get_charts`
83
+ - portal -> `portal_get`
84
+ 6. If the public shape is unclear, call `builder_tool_contract`
85
+ 7. Apply the smallest patch tool that fits:
86
+ - fields -> `app_schema_apply`
87
+ - layout -> `app_layout_apply`
88
+ - flow -> `app_flow_apply`
89
+ - views -> `app_views_apply`
90
+ - charts -> `app_charts_apply`
91
+ - portal -> `portal_apply`
92
+ - package metadata/layout -> `package_apply`
93
+ 8. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need a dedicated verification pass
157
94
 
158
95
  ## Safe Usage Rules
159
96
 
160
- - When using `package_name`, expect deterministic resolution only on a unique exact package name match; if multiple packages match, stop and resolve the ambiguity instead of guessing
161
- - `app_schema_apply` is the only public patch tool allowed to create an app shell; `app_layout_apply`, `app_flow_apply`, and `app_views_apply` require an existing app.
162
- - Prefer reading compact state plus `builder_tool_contract` before `*_apply`; apply already performs server-side normalization and returns blocking issues or the next executable call shape when needed.
163
- - For abstract requests like “默认视图”, “基础审批流”, “灵活流程”, or “美观布局”, first translate the intent into a stable preset or explicit patch. Do not send those phrases to MCP unchanged.
164
- - If the user asks for a business system or package that contains several forms, do not use the system/package name as `app_name` and do not try to store the child app names as text fields.
165
- - For flexible workflow requests, split the work into two steps:
166
- 1. create a base skeleton with a preset
167
- 2. apply explicit business-specific changes as patchable nodes/transitions
168
- - For preset-based flows, treat preset node ids as part of the public contract. Patch the skeleton nodes by the same ids instead of creating a parallel node with a new id and leaving the preset node unassigned.
169
- - Approval, fill, and copy nodes must declare at least one assignee. Treat this as a hard requirement, not an optional detail.
170
- - For workflow nodes, use the canonical public shape:
171
- - `assignees.role_names`
172
- - `assignees.member_names`
173
- - `permissions.editable_fields`
174
- - For layout work, keep the public section shape canonical:
175
- - `title`
176
- - `rows`
177
- Do not invent top-level layout `columns`, and do not prefer `fields` or `field_ids` once `rows` is known.
178
- - Translate natural language like “一行四个字段 / 四列布局 / 每行放四个” into `rows` matrices, not guessed layout parameters.
179
- - If the same layout-shape `VALIDATION_ERROR` repeats twice, stop guessing and re-read `builder_tool_contract(app_layout_apply)` or the layout reference before trying again.
180
- - Do not guess role ids or member ids. Resolve them from the directory first.
181
- - `app_schema_apply` does not treat package attachment as success criteria; if package ownership matters, verify `tag_ids_after` and call `package_attach_app` explicitly.
182
- - `package_attach_app` is the source of truth for package ownership; do not assume app creation or publish implicitly attaches the app.
183
- - `relation` and `subtable` must be explicit; do not infer them from vague natural language.
184
- - Another app is not a field. If two business objects should both have their own records, build two apps and connect them with relation fields.
185
- - In `prod`, prefer explicit patch tools and avoid any speculative create flow.
186
- - Never try to bypass collaborative edit locks. `app_release_edit_lock_if_mine` is only for the case where the lock owner is the current authenticated user.
97
+ - 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`.
98
+ - 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.
99
+ - 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.
100
+ - Do not use raw `portal_*` writes or raw `qingbi_report_*` writes as the default builder strategy.
101
+ - `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default; `app_charts_apply` is immediate-live without publish.
102
+ - If the same validation error repeats twice, stop guessing and re-read `builder_tool_contract`.
103
+ - For workflow assignees, prefer `role_search` over explicit members unless the user explicitly wants named members.
104
+ - 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.
105
+ - Respect collaborative edit locks. Only use `app_release_edit_lock_if_mine` when the lock owner is the current authenticated user.
106
+ - 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.
187
107
 
188
108
  ## Response Interpretation
189
109
 
190
- - low-level list totals from the backend may report `0` while rows are present; prefer summary or aggregate readbacks for final conclusions
191
- - `app_publish_verify` is the publish source of truth.
192
- - All public builder tools expose top-level `warnings`, `verification`, and `verified`. Read them before deciding whether a run is fully done.
193
- - For read tools, `status=success` can still pair with `verified=false` when some optional readback is unavailable; in that case prefer `warnings` and `verification` over the bare status code.
194
- - For `app_charts_apply`, `portal_apply`, and `app_publish_verify`, treat `success` as “write and verification completed” and `partial_success` as “write executed but verification is incomplete”.
195
- - For `app_schema_apply`, multiple relation fields are a known high-risk backend area. If you see `RELATION_FIELD_LIMIT_RISK` or `verification.relation_field_limit_verified=false`, do not describe the schema as fully safe.
196
- - For `app_layout_apply`, trust `verification.layout_verified` first and `verification.layout_summary_verified` second. `LAYOUT_SUMMARY_UNVERIFIED` means the raw form readback is more trustworthy than the compact summary.
197
- - For `app_views_apply`, treat `verification.views_verified` and `verification.view_filters_verified` separately. A created view with unverified filters is not a finished business view.
198
- - For `app_flow_apply`, treat only linear node structure as publicly supported. If you see `FLOW_NODE_TYPE_UNSUPPORTED`, redesign the workflow as a stable linear flow instead of retrying branch/condition nodes.
199
- - If readback mismatches the UI, compare `request_route` and do not assume the builder hit the same `qf_version` as the browser
200
- - Treat post-write readback as the source of truth, not just write status codes
201
- - For views, a top-level `VIEW_APPLY_FAILED` does not prove all requested views failed. Read back the view list and verify which views actually landed.
202
- - For views, “view exists” is not the same as “filters are active”. If `app_views_apply` returns `partial_success`, `views_verified=false`, or `details.filter_mismatches`, report the view as created but the filters as unverified until readback confirms them.
203
- - If multiple views share the same name, do not guess which one to update. Read `view_key` from `app_get_views` and pass it explicitly in `upsert_views[]`.
204
- - In final user-facing summaries, distinguish clearly between:
205
- - contract is visible / canonical shape is known
206
- - apply precheck succeeded
207
- - apply landed and readback verified it
208
- - base template/skeleton applied
209
- - business-specific rules completed
210
- - remaining gaps or follow-up patches
211
- - Do not report “流程已满足业务需求” when only a preset skeleton has landed.
110
+ - Treat post-write readback as the source of truth, not just write status codes.
111
+ - `success` means write and verification completed; `partial_success` means the write landed but verification is incomplete.
112
+ - For portals, distinguish clearly between:
113
+ - base-info-only update with layout preserved
114
+ - full sections replace
115
+ - For charts, distinguish clearly between:
116
+ - base / visibility change
117
+ - real chart-config change
118
+ - For app permissions, report `can_edit_app_base` separately from `can_edit_form / can_edit_flow / can_edit_views / can_edit_charts`.
212
119
 
213
120
  ## Practical Patterns
214
121
 
215
- - List packages: `package_list`
216
- - Resolve one package: `package_resolve`
217
- - Create one package: `package_create`
218
- - Read one public tool contract: `builder_tool_contract`
122
+ - Read one package: `package_get`
123
+ - Create or update one package: `package_apply`
219
124
  - Resolve one app: `app_resolve`
220
125
  - Read one app summary: `app_get`
221
126
  - Read fields only: `app_get_fields`
@@ -224,21 +129,20 @@ For additive work on existing systems:
224
129
  - Read flow summary: `app_get_flow`
225
130
  - Read chart summary: `app_get_charts`
226
131
  - Read portal config: `portal_get`
227
- - Search members for workflow assignees: `member_search`
228
- - Search roles for workflow assignees: `role_search`
229
- - Create reusable workflow role: `role_create`
132
+ - Search members or roles: `member_search`, `role_search`
133
+ - Create reusable role: `role_create`
230
134
  - Add/update/remove fields: `app_schema_apply`
231
135
  - Merge or replace layout: `app_layout_apply`
232
136
  - Replace workflow: `app_flow_apply`
233
137
  - Upsert/remove views: `app_views_apply`
234
- - Upsert/remove/reorder QingBI charts: `app_charts_apply`
235
- - Create or replace-update portal pages: `portal_apply`
236
- - Attach one app to a package: `package_attach_app`
138
+ - Upsert/remove/reorder charts: `app_charts_apply`
139
+ - Create or update portal pages: `portal_apply`
237
140
  - Release your own stale edit lock: `app_release_edit_lock_if_mine`
238
- - Publish and verify: `app_publish_verify` when you need a separate verification pass beyond the default auto-publish behavior in apply tools
141
+ - Final publish verification: `app_publish_verify`
239
142
 
240
- Detailed playbooks:
143
+ ## Resources
241
144
 
145
+ - Shared public-surface baseline: [public-surface-sync.md](../qingflow-app-user/references/public-surface-sync.md)
242
146
  - Environment switching: [references/environments.md](references/environments.md)
243
147
  - Tool choice and sequencing: [references/tool-selection.md](references/tool-selection.md)
244
148
  - Result semantics and gotchas: [references/gotchas.md](references/gotchas.md)
@@ -1,12 +1,13 @@
1
1
  # Create App
2
2
 
3
3
  Use this when the user wants one new app inside an existing package.
4
+ This playbook follows the current public builder surface, not legacy package helper tools.
4
5
 
5
6
  Do not use this playbook when the user is really asking for a system/package with multiple forms or modules. In that case:
6
7
 
7
- 1. resolve or create the package
8
+ 1. read or create the package through `package_get` / `package_apply`
8
9
  2. create each app separately
9
- 3. attach each app to the package
10
+ 3. keep package ownership on the public `package_id` path instead of a separate attach step
10
11
  4. add relation fields between apps
11
12
 
12
13
  Hierarchy reminder:
@@ -14,15 +15,14 @@ Hierarchy reminder:
14
15
  - package -> app -> field -> relation
15
16
  - another business object is another app, not a text field
16
17
 
17
- If creating a brand new package would help, ask the user to confirm package creation first. After confirmation, call `package_create` before this sequence.
18
+ If creating a brand new package would help, ask the user to confirm package creation first. After confirmation, create it through `package_apply(create_if_missing=true, package_name=...)`.
18
19
 
19
20
  ## Minimal sequence
20
21
 
21
- 1. `package_resolve`
22
+ 1. `package_get` if `package_id` is already known; otherwise derive the package from related readback or ask the user for the id
22
23
  2. `app_resolve`
23
24
  3. `app_schema_apply`
24
- 4. `package_attach_app`
25
- 5. `app_publish_verify` only when the user asks for explicit final verification
25
+ 4. `app_publish_verify` only when the user asks for explicit final verification
26
26
 
27
27
  ## Multi-app systems are different
28
28
 
@@ -36,8 +36,8 @@ then do not treat that as one app.
36
36
 
37
37
  Use this pattern instead:
38
38
 
39
- 1. `package_resolve` or `package_create`
40
- 2. for each app name, run `app_schema_apply -> package_attach_app`
39
+ 1. `package_get` or `package_apply(create_if_missing=true, package_name=...)`
40
+ 2. for each app name, run `app_schema_apply`
41
41
  3. once the apps exist, add `relation` fields between them
42
42
 
43
43
  ## Example
@@ -46,22 +46,23 @@ Create a new package only after the user confirms package creation:
46
46
 
47
47
  ```json
48
48
  {
49
- "tool_name": "package_create",
49
+ "tool_name": "package_apply",
50
50
  "arguments": {
51
51
  "profile": "default",
52
- "package_name": "研发项目管理"
52
+ "package_name": "研发项目管理",
53
+ "create_if_missing": true
53
54
  }
54
55
  }
55
56
  ```
56
57
 
57
- Resolve the package:
58
+ Read the package when `package_id` is already known:
58
59
 
59
60
  ```json
60
61
  {
61
- "tool_name": "package_resolve",
62
+ "tool_name": "package_get",
62
63
  "arguments": {
63
64
  "profile": "default",
64
- "package_name": "测试应用包"
65
+ "package_id": 1218950
65
66
  }
66
67
  }
67
68
  ```
@@ -74,7 +75,7 @@ Apply schema for a new app:
74
75
  "arguments": {
75
76
  "profile": "default",
76
77
  "app_name": "客户订单",
77
- "package_tag_id": 1218950,
78
+ "package_id": 1218950,
78
79
  "create_if_missing": true,
79
80
  "publish": true,
80
81
  "add_fields": [
@@ -87,22 +88,6 @@ Apply schema for a new app:
87
88
  "remove_fields": []
88
89
  }
89
90
  }
90
- ```
91
- }
92
- }
93
- ```
94
-
95
- Attach explicitly if `tag_ids_after` does not yet contain the package:
96
-
97
- ```json
98
- {
99
- "tool_name": "package_attach_app",
100
- "arguments": {
101
- "profile": "default",
102
- "tag_id": 1218950,
103
- "app_key": "APP_KEY_FROM_SCHEMA_APPLY"
104
- }
105
- }
106
91
  ```
107
92
 
108
93
  ## Common failures
@@ -115,10 +100,6 @@ Expected on create. Continue with `create_if_missing=true`.
115
100
 
116
101
  The create route did not resolve in the current backend route context. Re-run `workspace_select`, then retry the same `app_schema_apply`.
117
102
 
118
- ### `PACKAGE_ATTACH_FAILED`
119
-
120
- Do not retry schema creation. Re-run only `package_attach_app`, then verify with `app_get`.
121
-
122
103
  ### Hierarchy modeling mistake
123
104
 
124
105
  If the user asked for several named forms/apps but the draft patch turns them into text fields inside one app, stop and remodel the task as:
@@ -7,9 +7,9 @@
7
7
 
8
8
  ## Package ownership
9
9
 
10
- - App creation and publish do not guarantee package attachment
11
- - Treat `package_attach_app` as the source of truth for package ownership
12
- - Check `tag_ids_after` after schema writes
10
+ - Public package work should stay on `package_get / package_apply`
11
+ - Do not treat `package_attach_app` as the public default story anymore; if it still exists in low-level code, treat it as internal/legacy
12
+ - Check package-related readback after schema writes instead of assuming package ownership from the write alone
13
13
 
14
14
  ## Package vs app vs field
15
15
 
@@ -4,10 +4,9 @@ Use these when you need a quick reminder of the standard v2 builder sequences.
4
4
 
5
5
  ## Create a new app in an existing package
6
6
 
7
- 1. `package_resolve`
7
+ 1. `package_get`
8
8
  2. `app_resolve`
9
9
  3. `app_schema_apply`
10
- 4. `package_attach_app`
11
10
  5. `app_publish_verify` only if the user asks for explicit live verification
12
11
 
13
12
  ## Update fields on an existing app