@josephyan/qingflow-app-builder-mcp 0.2.0-beta.984 → 0.2.0-beta.986
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.
- package/README.md +2 -2
- package/docs/local-agent-install.md +70 -11
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +86 -184
- package/skills/qingflow-app-builder/references/create-app.md +15 -34
- package/skills/qingflow-app-builder/references/gotchas.md +3 -3
- package/skills/qingflow-app-builder/references/solution-playbooks.md +1 -2
- package/skills/qingflow-app-builder/references/tool-selection.md +9 -10
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/builder_facade/service.py +47 -21
- package/src/qingflow_mcp/cli/commands/auth.py +14 -43
- package/src/qingflow_mcp/cli/commands/task.py +4 -1
- package/src/qingflow_mcp/cli/commands/workspace.py +0 -8
- package/src/qingflow_mcp/cli/formatters.py +0 -21
- package/src/qingflow_mcp/config.py +39 -0
- package/src/qingflow_mcp/errors.py +2 -2
- package/src/qingflow_mcp/public_surface.py +2 -6
- package/src/qingflow_mcp/response_trim.py +1 -8
- package/src/qingflow_mcp/server.py +1 -1
- package/src/qingflow_mcp/server_app_builder.py +4 -28
- package/src/qingflow_mcp/server_app_user.py +4 -28
- package/src/qingflow_mcp/session_store.py +31 -5
- package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
- package/src/qingflow_mcp/tools/app_tools.py +51 -1
- package/src/qingflow_mcp/tools/approval_tools.py +82 -1
- package/src/qingflow_mcp/tools/auth_tools.py +258 -288
- package/src/qingflow_mcp/tools/base.py +204 -4
- package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
- package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
- package/src/qingflow_mcp/tools/directory_tools.py +28 -1
- package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
- package/src/qingflow_mcp/tools/file_tools.py +25 -1
- package/src/qingflow_mcp/tools/import_tools.py +40 -1
- package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
- package/src/qingflow_mcp/tools/package_tools.py +37 -1
- package/src/qingflow_mcp/tools/portal_tools.py +28 -1
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
- package/src/qingflow_mcp/tools/record_tools.py +255 -2
- package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
- package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
- package/src/qingflow_mcp/tools/role_tools.py +19 -1
- package/src/qingflow_mcp/tools/solution_tools.py +56 -1
- package/src/qingflow_mcp/tools/task_context_tools.py +205 -6
- package/src/qingflow_mcp/tools/task_tools.py +49 -3
- package/src/qingflow_mcp/tools/view_tools.py +56 -1
- package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
- package/src/qingflow_mcp/tools/workspace_tools.py +14 -225
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.
|
|
6
|
+
npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.986
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.
|
|
12
|
+
npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.986 qingflow-app-builder-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
2. 记录/待办优先的 `qingflow-app-user-mcp`
|
|
7
7
|
3. 精简 builder 的 `qingflow-app-builder-mcp`
|
|
8
8
|
|
|
9
|
+
## 本地鉴权推荐方案
|
|
10
|
+
|
|
11
|
+
本地模式现在推荐优先使用 `credential` 建立会话,而不是直接注入 `token`。
|
|
12
|
+
|
|
13
|
+
推荐链路:
|
|
14
|
+
|
|
15
|
+
1. createClaw 或其它本地宿主为当前实例保存 `credential`
|
|
16
|
+
2. 本地 MCP 调用 `auth_use_credential`
|
|
17
|
+
3. MCP 用该 `credential` 请求 apaas `/mcp/auth/context`
|
|
18
|
+
4. 解析并保存 `token / wsId / qfVersion / uid`
|
|
19
|
+
5. 业务工具直接使用这份上下文
|
|
20
|
+
|
|
21
|
+
`auth_use_credential` 是本地唯一鉴权主路径。
|
|
22
|
+
|
|
9
23
|
## npm 安装器适用场景
|
|
10
24
|
|
|
11
25
|
适合这类本地 agent / gateway:
|
|
@@ -63,17 +77,17 @@ npm run pack:npm
|
|
|
63
77
|
会生成:
|
|
64
78
|
|
|
65
79
|
```bash
|
|
66
|
-
dist/npm/
|
|
67
|
-
dist/npm/
|
|
68
|
-
dist/npm/
|
|
80
|
+
dist/npm/qingflow-tech-qingflow-cli-<version>.tgz
|
|
81
|
+
dist/npm/qingflow-tech-qingflow-app-user-mcp-<version>.tgz
|
|
82
|
+
dist/npm/qingflow-tech-qingflow-app-builder-mcp-<version>.tgz
|
|
69
83
|
```
|
|
70
84
|
|
|
71
85
|
然后在目标机器安装:
|
|
72
86
|
|
|
73
87
|
```bash
|
|
74
|
-
npm install /absolute/path/to/dist/npm/
|
|
75
|
-
npm install /absolute/path/to/dist/npm/
|
|
76
|
-
npm install /absolute/path/to/dist/npm/
|
|
88
|
+
npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-cli-<version>.tgz
|
|
89
|
+
npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-app-user-mcp-<version>.tgz
|
|
90
|
+
npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-app-builder-mcp-<version>.tgz
|
|
77
91
|
```
|
|
78
92
|
|
|
79
93
|
安装时会自动:
|
|
@@ -136,7 +150,10 @@ qingflow-app-builder-mcp
|
|
|
136
150
|
],
|
|
137
151
|
"env": {
|
|
138
152
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
139
|
-
"QINGFLOW_MCP_HOME": "/absolute/path/to/.qingflow-mcp"
|
|
153
|
+
"QINGFLOW_MCP_HOME": "/absolute/path/to/.qingflow-mcp",
|
|
154
|
+
"QINGFLOW_MCP_CREDIT_METER_ENABLED": "true",
|
|
155
|
+
"QINGFLOW_MCP_CREDIT_APAAS_BASE_URL": "https://apaas.internal.example.com",
|
|
156
|
+
"QINGFLOW_MCP_CREDIT_APAAS_PATH": "/user/credit/usage"
|
|
140
157
|
}
|
|
141
158
|
}
|
|
142
159
|
}
|
|
@@ -153,7 +170,10 @@ qingflow-app-builder-mcp
|
|
|
153
170
|
"args": [],
|
|
154
171
|
"env": {
|
|
155
172
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
156
|
-
"QINGFLOW_MCP_HOME": "/absolute/path/to/.qingflow-mcp"
|
|
173
|
+
"QINGFLOW_MCP_HOME": "/absolute/path/to/.qingflow-mcp",
|
|
174
|
+
"QINGFLOW_MCP_CREDIT_METER_ENABLED": "true",
|
|
175
|
+
"QINGFLOW_MCP_CREDIT_APAAS_BASE_URL": "https://apaas.internal.example.com",
|
|
176
|
+
"QINGFLOW_MCP_CREDIT_APAAS_PATH": "/user/credit/usage"
|
|
157
177
|
}
|
|
158
178
|
}
|
|
159
179
|
}
|
|
@@ -170,7 +190,10 @@ qingflow-app-builder-mcp
|
|
|
170
190
|
"args": [],
|
|
171
191
|
"env": {
|
|
172
192
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
173
|
-
"QINGFLOW_MCP_HOME": "/absolute/path/to/.qingflow-mcp"
|
|
193
|
+
"QINGFLOW_MCP_HOME": "/absolute/path/to/.qingflow-mcp",
|
|
194
|
+
"QINGFLOW_MCP_CREDIT_METER_ENABLED": "true",
|
|
195
|
+
"QINGFLOW_MCP_CREDIT_APAAS_BASE_URL": "https://apaas.internal.example.com",
|
|
196
|
+
"QINGFLOW_MCP_CREDIT_APAAS_PATH": "/user/credit/usage"
|
|
174
197
|
}
|
|
175
198
|
}
|
|
176
199
|
}
|
|
@@ -191,7 +214,10 @@ qingflow-app-builder-mcp
|
|
|
191
214
|
"@josephyan/qingflow-app-user-mcp"
|
|
192
215
|
],
|
|
193
216
|
"env": {
|
|
194
|
-
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api"
|
|
217
|
+
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
218
|
+
"QINGFLOW_MCP_CREDIT_METER_ENABLED": "true",
|
|
219
|
+
"QINGFLOW_MCP_CREDIT_APAAS_BASE_URL": "https://apaas.internal.example.com",
|
|
220
|
+
"QINGFLOW_MCP_CREDIT_APAAS_PATH": "/user/credit/usage"
|
|
195
221
|
}
|
|
196
222
|
},
|
|
197
223
|
"qingflow-builder": {
|
|
@@ -201,7 +227,10 @@ qingflow-app-builder-mcp
|
|
|
201
227
|
"@josephyan/qingflow-app-builder-mcp"
|
|
202
228
|
],
|
|
203
229
|
"env": {
|
|
204
|
-
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api"
|
|
230
|
+
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
231
|
+
"QINGFLOW_MCP_CREDIT_METER_ENABLED": "true",
|
|
232
|
+
"QINGFLOW_MCP_CREDIT_APAAS_BASE_URL": "https://apaas.internal.example.com",
|
|
233
|
+
"QINGFLOW_MCP_CREDIT_APAAS_PATH": "/user/credit/usage"
|
|
205
234
|
}
|
|
206
235
|
}
|
|
207
236
|
}
|
|
@@ -212,6 +241,7 @@ qingflow-app-builder-mcp
|
|
|
212
241
|
- 源码目录 `npm install` 不会把命令加到全局 PATH;这种模式请用 `node ./npm/bin/qingflow.mjs`、`node ./npm/bin/qingflow-app-user-mcp.mjs` 或 `node ./npm/bin/qingflow-app-builder-mcp.mjs`
|
|
213
242
|
- `npx` 方式适合临时安装或容器化本地 agent
|
|
214
243
|
- 全局安装方式更适合长期固定使用的本机开发环境
|
|
244
|
+
- 计费接口使用当前登录会话的 `token` 与 `wsId` 请求头,可通过 `QINGFLOW_MCP_CREDIT_APAAS_BASE_URL/PATH` 覆盖调用记录接口地址
|
|
215
245
|
|
|
216
246
|
## 排障
|
|
217
247
|
|
|
@@ -242,3 +272,32 @@ npm install
|
|
|
242
272
|
4. 再启动 MCP 客户端
|
|
243
273
|
|
|
244
274
|
现在 stdio MCP 入口会拒绝在启动瞬间“边启动边重建 Python 运行时”,因为安装日志一旦写进 stdout,就会破坏 MCP 握手并表现成 `Transport closed`。如果运行时缺失或版本不一致,入口会直接报错并提示重装,而不是静默自修复。
|
|
275
|
+
|
|
276
|
+
## createClaw 本地接入示例
|
|
277
|
+
|
|
278
|
+
如果 createClaw 已经为当前本地实例保存了 `credential`,推荐在首次建链时调用:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
qingflow auth use-credential \
|
|
282
|
+
--base-url https://qingflow.com/api \
|
|
283
|
+
--credential-stdin
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
然后把 `credential` 写到 stdin。
|
|
287
|
+
|
|
288
|
+
等价 MCP 工具调用参数:
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{
|
|
292
|
+
"profile": "default",
|
|
293
|
+
"base_url": "https://qingflow.com/api",
|
|
294
|
+
"credential": "1602853_277941",
|
|
295
|
+
"persist": false
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
说明:
|
|
300
|
+
|
|
301
|
+
- 本地会把解析后的 `token` 和原始 `credential` 写入 profile 文件,用于后续 CLI 命令恢复会话
|
|
302
|
+
- `persist=true` 时,本地还会优先把解析后的 `token` 和原始 `credential` 同步写入系统 keychain
|
|
303
|
+
- 当前工作区以 `/mcp/auth/context` 返回的 `wsId` 为准,不再通过本地 MCP 显式切换
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -9,36 +9,22 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
12
|
-
This skill
|
|
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
|
-
|
|
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
|
-
|
|
19
|
+
## Current Public Mental Model
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
Model builder requests in four layers and keep them separate:
|
|
21
22
|
|
|
22
|
-
- `
|
|
23
|
-
-
|
|
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,93 @@ 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
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
- `
|
|
64
|
-
- `
|
|
65
|
-
-
|
|
66
|
-
- `
|
|
67
|
-
- `
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
- `
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
- `
|
|
78
|
-
- `
|
|
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
|
+
|
|
44
|
+
Treat these as the official surface. Do not default to `package_create`, `package_attach_app`, raw `portal_*` writes, or raw `qingbi_report_*` writes.
|
|
45
|
+
|
|
46
|
+
## Current Public Defaults
|
|
47
|
+
|
|
48
|
+
- Package work:
|
|
49
|
+
- use `package_get(package_id=...)` to read one known package
|
|
50
|
+
- use `package_apply(...)` for package creation, rename, icon, visibility, grouping, ordering, and app/portal layout
|
|
51
|
+
- App base permissions:
|
|
52
|
+
- trust `app_get.editability.can_edit_app_base` for app base-info writes like app name, icon, and visibility
|
|
53
|
+
- `can_edit_form` only means schema/form-route capability; it no longer implies app base-info write capability
|
|
54
|
+
- Portal work:
|
|
55
|
+
- `portal_apply` is the public write path
|
|
56
|
+
- in edit mode, omitting `sections` means “preserve existing layout and update base info only”
|
|
57
|
+
- supplying `sections` means full replace semantics for sections
|
|
58
|
+
- Chart work:
|
|
59
|
+
- `app_charts_apply` is the public write path
|
|
60
|
+
- `visibility` is a public capability and should be treated as a base-only permission update
|
|
61
|
+
- do not model chart visibility changes as raw config rewrites
|
|
62
|
+
- Views and flows:
|
|
63
|
+
- stay on `app_views_apply` / `app_flow_apply`
|
|
64
|
+
- use `builder_tool_contract` whenever the minimal legal shape is unclear
|
|
94
65
|
|
|
95
66
|
## Standard Operating Order
|
|
96
67
|
|
|
97
|
-
Before any business tool:
|
|
98
|
-
|
|
99
68
|
1. Ensure auth exists
|
|
100
69
|
2. Ensure workspace is selected
|
|
101
70
|
3. Confirm whether the task is read-only or write-impacting
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
|
71
|
+
4. Resolve the smallest stable target:
|
|
72
|
+
- app-scoped work -> `app_resolve`
|
|
73
|
+
- package-scoped work with known id -> `package_get`
|
|
74
|
+
- portal inventory -> `portal_list`
|
|
75
|
+
5. Read only the smallest config slice needed:
|
|
76
|
+
- app summary -> `app_get`
|
|
77
|
+
- fields -> `app_get_fields`
|
|
78
|
+
- layout -> `app_get_layout`
|
|
79
|
+
- views -> `app_get_views`
|
|
80
|
+
- flow -> `app_get_flow`
|
|
81
|
+
- charts -> `app_get_charts`
|
|
82
|
+
- portal -> `portal_get`
|
|
83
|
+
6. If the public shape is unclear, call `builder_tool_contract`
|
|
84
|
+
7. Apply the smallest patch tool that fits:
|
|
85
|
+
- fields -> `app_schema_apply`
|
|
86
|
+
- layout -> `app_layout_apply`
|
|
87
|
+
- flow -> `app_flow_apply`
|
|
88
|
+
- views -> `app_views_apply`
|
|
89
|
+
- charts -> `app_charts_apply`
|
|
90
|
+
- portal -> `portal_apply`
|
|
91
|
+
- package metadata/layout -> `package_apply`
|
|
92
|
+
8. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need a dedicated verification pass
|
|
157
93
|
|
|
158
94
|
## Safe Usage Rules
|
|
159
95
|
|
|
160
|
-
-
|
|
161
|
-
- `
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
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.
|
|
96
|
+
- 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`.
|
|
97
|
+
- 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.
|
|
98
|
+
- 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.
|
|
99
|
+
- Do not use raw `portal_*` writes or raw `qingbi_report_*` writes as the default builder strategy.
|
|
100
|
+
- `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default; `app_charts_apply` is immediate-live without publish.
|
|
101
|
+
- If the same validation error repeats twice, stop guessing and re-read `builder_tool_contract`.
|
|
102
|
+
- For workflow assignees, prefer `role_search` over explicit members unless the user explicitly wants named members.
|
|
103
|
+
- 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.
|
|
104
|
+
- Respect collaborative edit locks. Only use `app_release_edit_lock_if_mine` when the lock owner is the current authenticated user.
|
|
187
105
|
|
|
188
106
|
## Response Interpretation
|
|
189
107
|
|
|
190
|
-
-
|
|
191
|
-
- `
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
- For
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
- For
|
|
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.
|
|
108
|
+
- Treat post-write readback as the source of truth, not just write status codes.
|
|
109
|
+
- `success` means write and verification completed; `partial_success` means the write landed but verification is incomplete.
|
|
110
|
+
- For portals, distinguish clearly between:
|
|
111
|
+
- base-info-only update with layout preserved
|
|
112
|
+
- full sections replace
|
|
113
|
+
- For charts, distinguish clearly between:
|
|
114
|
+
- base / visibility change
|
|
115
|
+
- real chart-config change
|
|
116
|
+
- For app permissions, report `can_edit_app_base` separately from `can_edit_form / can_edit_flow / can_edit_views / can_edit_charts`.
|
|
212
117
|
|
|
213
118
|
## Practical Patterns
|
|
214
119
|
|
|
215
|
-
-
|
|
216
|
-
-
|
|
217
|
-
- Create one package: `package_create`
|
|
218
|
-
- Read one public tool contract: `builder_tool_contract`
|
|
120
|
+
- Read one package: `package_get`
|
|
121
|
+
- Create or update one package: `package_apply`
|
|
219
122
|
- Resolve one app: `app_resolve`
|
|
220
123
|
- Read one app summary: `app_get`
|
|
221
124
|
- Read fields only: `app_get_fields`
|
|
@@ -224,21 +127,20 @@ For additive work on existing systems:
|
|
|
224
127
|
- Read flow summary: `app_get_flow`
|
|
225
128
|
- Read chart summary: `app_get_charts`
|
|
226
129
|
- Read portal config: `portal_get`
|
|
227
|
-
- Search members
|
|
228
|
-
-
|
|
229
|
-
- Create reusable workflow role: `role_create`
|
|
130
|
+
- Search members or roles: `member_search`, `role_search`
|
|
131
|
+
- Create reusable role: `role_create`
|
|
230
132
|
- Add/update/remove fields: `app_schema_apply`
|
|
231
133
|
- Merge or replace layout: `app_layout_apply`
|
|
232
134
|
- Replace workflow: `app_flow_apply`
|
|
233
135
|
- Upsert/remove views: `app_views_apply`
|
|
234
|
-
- Upsert/remove/reorder
|
|
235
|
-
- Create or
|
|
236
|
-
- Attach one app to a package: `package_attach_app`
|
|
136
|
+
- Upsert/remove/reorder charts: `app_charts_apply`
|
|
137
|
+
- Create or update portal pages: `portal_apply`
|
|
237
138
|
- Release your own stale edit lock: `app_release_edit_lock_if_mine`
|
|
238
|
-
-
|
|
139
|
+
- Final publish verification: `app_publish_verify`
|
|
239
140
|
|
|
240
|
-
|
|
141
|
+
## Resources
|
|
241
142
|
|
|
143
|
+
- Shared public-surface baseline: [public-surface-sync.md](../qingflow-app-user/references/public-surface-sync.md)
|
|
242
144
|
- Environment switching: [references/environments.md](references/environments.md)
|
|
243
145
|
- Tool choice and sequencing: [references/tool-selection.md](references/tool-selection.md)
|
|
244
146
|
- 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.
|
|
8
|
+
1. read or create the package through `package_get` / `package_apply`
|
|
8
9
|
2. create each app separately
|
|
9
|
-
3.
|
|
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,
|
|
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. `
|
|
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. `
|
|
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. `
|
|
40
|
-
2. for each app name, run `app_schema_apply
|
|
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": "
|
|
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
|
-
|
|
58
|
+
Read the package when `package_id` is already known:
|
|
58
59
|
|
|
59
60
|
```json
|
|
60
61
|
{
|
|
61
|
-
"tool_name": "
|
|
62
|
+
"tool_name": "package_get",
|
|
62
63
|
"arguments": {
|
|
63
64
|
"profile": "default",
|
|
64
|
-
"
|
|
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
|
-
"
|
|
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:
|