@josephyan/qingflow-app-builder-mcp 0.2.0-beta.10 → 0.2.0-beta.12

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 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.10
6
+ npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.12
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.10 qingflow-app-builder-mcp
12
+ npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.12 qingflow-app-builder-mcp
13
13
  ```
14
14
 
15
15
  Environment:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyan/qingflow-app-builder-mcp",
3
- "version": "0.2.0-beta.10",
3
+ "version": "0.2.0-beta.12",
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.0b10"
7
+ version = "0.2.0b12"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -19,9 +19,9 @@ Pick the smallest tool layer that can finish the task.
19
19
 
20
20
  - Authentication and workspace: `auth_*`, `workspace_*`
21
21
  - File upload: `file_upload_local`
22
- - Resource resolve/read: `package_list`, `package_resolve`, `package_create`, `builder_tool_contract`, `app_resolve`, `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`
22
+ - Resource resolve/read: `package_list`, `package_resolve`, `package_create`, `builder_tool_contract`, `member_search`, `role_search`, `app_resolve`, `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`
23
23
  - Resource plan: `app_schema_plan`, `app_layout_plan`, `app_flow_plan`, `app_views_plan`
24
- - Resource patch: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `package_attach_app`, `app_release_edit_lock_if_mine`
24
+ - Resource patch: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `package_attach_app`, `app_release_edit_lock_if_mine`, `role_create`
25
25
  - Publish and verify: `app_publish_verify`
26
26
 
27
27
  Note:
@@ -34,12 +34,17 @@ Note:
34
34
  - For flow presets, map natural language to canonical values before calling MCP:
35
35
  - “默认审批/基础审批/普通审批” -> `basic_approval`
36
36
  - “先填报再审批/提交后审批” -> `basic_fill_then_approve`
37
+ - 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.
38
+ - For workflow assignees, prefer roles over explicit members:
39
+ - use `role_search` first
40
+ - use `member_search` only when the user explicitly names members or no stable role exists
41
+ - use `role_create` when the business owner wants a reusable directory role instead of hard-coded members
37
42
  - On any `VALIDATION_ERROR`, inspect `suggested_next_call` first and prefer reusing the MCP-normalized arguments over re-guessing from the original natural language.
38
43
 
39
44
  Default policy:
40
45
 
41
46
  - Creating or updating one app inside an existing package: resolve the package/app, read compact state, plan patches on the server, then apply schema/layout/flow/views patches explicitly.
42
- - Do not create a new package unless the user explicitly asks for package separation.
47
+ - If package creation looks necessary or beneficial, ask the user to confirm before calling `package_create`.
43
48
 
44
49
  ## Standard Operating Order
45
50
 
@@ -51,7 +56,7 @@ Before any business tool:
51
56
 
52
57
  For builder work:
53
58
 
54
- 1. If the user explicitly wants a new package, create it first with `package_create`. Otherwise resolve the target package with `package_resolve`; if resolution is ambiguous or you need a read-only fallback, use `package_list`.
59
+ 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`.
55
60
  2. Resolve the target app with `app_resolve` if the request is an update.
56
61
  3. Read only the smallest summary you need: `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`.
57
62
  4. Use `app_schema_plan`, `app_layout_plan`, `app_flow_plan`, or `app_views_plan` before any non-trivial write.
@@ -59,25 +64,35 @@ For builder work:
59
64
  6. If the app must belong to a package, use `package_attach_app` explicitly after schema work unless readback already shows the target `tag_id`.
60
65
  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.
61
66
  8. Use `app_flow_apply` after schema exists. It publishes by default.
62
- 9. Use `app_views_apply` when the user wants explicit list/card/board views. It publishes by default.
67
+ 9. Use `app_views_apply` when the user wants explicit table/card/board/gantt views. It publishes by default.
63
68
  10. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need an explicit verification pass.
64
69
  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.
65
70
 
66
71
  For view work, keep the order strict:
67
72
 
68
- 1. `app_read_fields`
69
- 2. `app_read_views_summary`
70
- 3. `app_views_plan`
71
- 4. `app_views_apply`
73
+ 1. `builder_tool_contract`
74
+ 2. `app_read_fields`
75
+ 3. `app_read_views_summary`
76
+ 4. `app_views_plan`
77
+ 5. `app_views_apply`
78
+ 6. `app_read_views_summary` again whenever `app_views_apply` returns `failed` or `partial_success`
72
79
 
73
80
  For flow work, keep the order strict:
74
81
 
75
- 1. `app_read_fields`
76
- 2. `app_read_flow_summary`
77
- 3. Start from a canonical preset when possible
78
- 4. Use patch-style edits to that skeleton instead of freehand full-graph generation
79
- 5. `app_flow_plan`
80
- 6. `app_flow_apply`
82
+ 1. `builder_tool_contract`
83
+ 2. `app_read_fields`
84
+ 3. `app_read_flow_summary`
85
+ 4. `role_search` or `member_search` if assignees need to come from the directory
86
+ 5. `role_create` if the user wants a reusable role and no suitable role exists yet
87
+ 6. Start from a canonical preset when possible
88
+ 7. Use patch-style edits to that skeleton instead of freehand full-graph generation
89
+ 8. Declare approver/fill/copy assignees explicitly:
90
+ - prefer `assignees.role_names`
91
+ - support `assignees.member_names` / `assignees.member_emails` / `assignees.member_uids`
92
+ 9. When a node must edit specific fields, declare `permissions.editable_fields`
93
+ 10. `app_flow_plan`
94
+ 11. `app_flow_apply`
95
+ 12. `app_read_flow_summary` after apply whenever the user asked for verification or apply returns `partial_success`
81
96
 
82
97
  In `prod`, keep `plan` and `apply` as separate phases unless the user explicitly asks for a direct live execution.
83
98
 
@@ -97,6 +112,14 @@ For additive work on existing systems:
97
112
  - For flexible workflow requests, split the work into two steps:
98
113
  1. create a base skeleton with a preset
99
114
  2. apply explicit business-specific changes as patchable nodes/transitions
115
+ - Approval, fill, and copy nodes must declare at least one assignee. Treat this as a hard requirement, not an optional detail.
116
+ - For workflow nodes, use the canonical public shape:
117
+ - `assignees.role_names`
118
+ - `assignees.member_names`
119
+ - `permissions.editable_fields`
120
+ - Reuse `app_flow_plan` output directly when it succeeds. Do not rewrite it into internal keys such as `role_entries` or `editable_que_ids`.
121
+ - Reuse `app_views_plan` output directly when it succeeds. Do not re-expand aliases such as `column_names`.
122
+ - Do not guess role ids or member ids. Resolve them from the directory first.
100
123
  - `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.
101
124
  - `package_attach_app` is the source of truth for package ownership; do not assume app creation or publish implicitly attaches the app.
102
125
  - `relation` and `subtable` must be explicit; do not infer them from vague natural language.
@@ -109,7 +132,11 @@ For additive work on existing systems:
109
132
  - `app_publish_verify` is the publish source of truth.
110
133
  - If readback mismatches the UI, compare `request_route` and do not assume the builder hit the same `qf_version` as the browser
111
134
  - Treat post-write readback as the source of truth, not just write status codes
135
+ - 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.
112
136
  - In final user-facing summaries, distinguish clearly between:
137
+ - contract is visible / canonical shape is known
138
+ - plan succeeded
139
+ - apply landed and readback verified it
113
140
  - base template/skeleton applied
114
141
  - business-specific rules completed
115
142
  - remaining gaps or follow-up patches
@@ -131,6 +158,9 @@ For additive work on existing systems:
131
158
  - Plan layout patch: `app_layout_plan`
132
159
  - Plan workflow patch: `app_flow_plan`
133
160
  - Plan view patch: `app_views_plan`
161
+ - Search members for workflow assignees: `member_search`
162
+ - Search roles for workflow assignees: `role_search`
163
+ - Create reusable workflow role: `role_create`
134
164
  - Add/update/remove fields: `app_schema_apply`
135
165
  - Merge or replace layout: `app_layout_apply`
136
166
  - Replace workflow: `app_flow_apply`
@@ -148,5 +178,6 @@ Detailed playbooks:
148
178
  - Update fields only: [references/update-schema.md](references/update-schema.md)
149
179
  - Update layout only: [references/update-layout.md](references/update-layout.md)
150
180
  - Update workflow only: [references/update-flow.md](references/update-flow.md)
181
+ - Workflow assignees and node permissions: [references/flow-actors-and-permissions.md](references/flow-actors-and-permissions.md)
151
182
  - Update views only: [references/update-views.md](references/update-views.md)
152
183
  - Standard end-to-end builder sequences: [references/solution-playbooks.md](references/solution-playbooks.md)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Use this when the user wants one new app inside an existing package.
4
4
 
5
- If the user explicitly wants a brand new package first, call `package_create` before this sequence.
5
+ If creating a brand new package would help, ask the user to confirm package creation first. After confirmation, call `package_create` before this sequence.
6
6
 
7
7
  ## Minimal sequence
8
8
 
@@ -15,7 +15,7 @@ If the user explicitly wants a brand new package first, call `package_create` be
15
15
 
16
16
  ## Example
17
17
 
18
- Create a new package only when the user asked for package separation:
18
+ Create a new package only after the user confirms package creation:
19
19
 
20
20
  ```json
21
21
  {
@@ -43,7 +43,7 @@ Builder behavior in prod:
43
43
  - always identify the target package or app set before changing anything
44
44
  - default to `preflight` or `plan` before any `apply`
45
45
  - additive requirements should modify the existing package with ordinary tools by default
46
- - do not create a new package unless the user explicitly wants package separation
46
+ - if creating a new package seems necessary in prod, ask the user to confirm package creation first
47
47
  - do not seed mock data unless the user explicitly approves it for production
48
48
  - verify is mandatory after writes
49
49
 
@@ -0,0 +1,124 @@
1
+ # Flow Actors And Permissions
2
+
3
+ Use this when the workflow needs real assignees or node-level editable field permissions.
4
+
5
+ ## Canonical policy
6
+
7
+ - Approval, fill, and copy nodes must declare at least one assignee.
8
+ - Prefer roles over explicit members.
9
+ - Resolve directory actors before calling `app_flow_plan` or `app_flow_apply`.
10
+ - Use canonical keys only:
11
+ - `assignees.role_names`
12
+ - `assignees.role_ids`
13
+ - `assignees.member_names`
14
+ - `assignees.member_emails`
15
+ - `assignees.member_uids`
16
+ - `permissions.editable_fields`
17
+
18
+ ## Recommended order
19
+
20
+ 1. `app_read_fields`
21
+ 2. `app_read_flow_summary`
22
+ 3. `role_search`
23
+ 4. `member_search` when the user explicitly names people
24
+ 5. `role_create` when no reusable role exists and the user wants role-based routing
25
+ 6. `app_flow_plan`
26
+ 7. `app_flow_apply`
27
+
28
+ ## Examples
29
+
30
+ ### Route an approval node to a reusable role
31
+
32
+ ```json
33
+ {
34
+ "tool_name": "app_flow_plan",
35
+ "arguments": {
36
+ "profile": "default",
37
+ "app_key": "APP_123",
38
+ "preset": "basic_approval",
39
+ "nodes": [
40
+ {
41
+ "id": "approve_1",
42
+ "type": "approve",
43
+ "name": "部门审批",
44
+ "assignees": {
45
+ "role_names": ["项目经理"]
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### Route to explicit members when the user names people
54
+
55
+ ```json
56
+ {
57
+ "tool_name": "app_flow_plan",
58
+ "arguments": {
59
+ "profile": "default",
60
+ "app_key": "APP_123",
61
+ "preset": "basic_approval",
62
+ "nodes": [
63
+ {
64
+ "id": "approve_1",
65
+ "type": "approve",
66
+ "name": "部门审批",
67
+ "assignees": {
68
+ "member_names": ["严琪东", "张三"]
69
+ }
70
+ }
71
+ ]
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### Let one node edit selected fields only
77
+
78
+ ```json
79
+ {
80
+ "tool_name": "app_flow_apply",
81
+ "arguments": {
82
+ "profile": "default",
83
+ "app_key": "APP_123",
84
+ "mode": "replace",
85
+ "publish": true,
86
+ "nodes": [
87
+ {"id": "start", "type": "start", "name": "发起"},
88
+ {
89
+ "id": "approve_1",
90
+ "type": "approve",
91
+ "name": "部门审批",
92
+ "assignees": {
93
+ "role_names": ["项目经理"]
94
+ },
95
+ "permissions": {
96
+ "editable_fields": ["状态", "审批意见", "项目负责人"]
97
+ }
98
+ },
99
+ {"id": "end", "type": "end", "name": "结束"}
100
+ ],
101
+ "transitions": [
102
+ {"from": "start", "to": "approve_1"},
103
+ {"from": "approve_1", "to": "end"}
104
+ ]
105
+ }
106
+ }
107
+ ```
108
+
109
+ ## Common recovery
110
+
111
+ ### `ROLE_NOT_FOUND` / `AMBIGUOUS_ROLE`
112
+
113
+ - retry with `role_search`
114
+ - if the business wants a reusable route and no exact role exists, create one with `role_create`
115
+
116
+ ### `MEMBER_NOT_FOUND` / `AMBIGUOUS_MEMBER`
117
+
118
+ - retry with `member_search`
119
+ - do not guess user ids
120
+
121
+ ### `UNKNOWN_FLOW_FIELD`
122
+
123
+ - reread fields with `app_read_fields`
124
+ - only pass real current field names to `permissions.editable_fields`
@@ -28,6 +28,10 @@
28
28
  ## Workflow dependencies
29
29
 
30
30
  - Approval-style flows usually require an explicit status field
31
+ - Approval, fill, and copy nodes also require at least one assignee
32
+ - Prefer roles over explicit members unless the user explicitly names people
33
+ - Resolve assignees with `role_search` / `member_search` before flow apply
34
+ - Use `permissions.editable_fields` for node-level editable field permissions; do not guess field ids
31
35
  - If `app_flow_plan` reports `FLOW_DEPENDENCY_MISSING`, fix schema first
32
36
  - Do not switch to hidden `solution_*` tools from public builder flows
33
37
 
@@ -37,6 +41,10 @@
37
41
  - Do not repeat create steps after `app_key` already exists
38
42
  - For backend rejects, keep the retry narrow: retry only the failed tool, not the whole chain
39
43
  - For `VALIDATION_ERROR`, do not keep guessing. Reuse `suggested_next_call`, `canonical_arguments`, `allowed_keys`, and `allowed_values` first.
44
+ - For flow work, do not replay internal keys from old logs or plan outputs. Public builder calls should stay on:
45
+ - `assignees.role_ids` / `assignees.member_uids` / `assignees.member_emails`
46
+ - `permissions.editable_fields`
47
+ - For view work, treat `columns` as the only canonical public key. `app_read_views_summary` and `app_views_plan/apply` should all be read and written in that shape.
40
48
  - If a view or flow write fails, report the smallest next action:
41
49
  - wrong key -> switch to canonical key
42
50
  - unsupported preset -> switch to allowed canonical preset
@@ -30,10 +30,13 @@ Prefer `mode=merge`. Use `mode=replace` only when every field placement is inten
30
30
 
31
31
  1. `app_read_fields`
32
32
  2. `app_read_flow_summary`
33
- 3. `app_flow_plan`
34
- 4. `app_flow_apply`
33
+ 3. `role_search` or `member_search`
34
+ 4. `role_create` if the business wants a reusable role and no good exact role exists
35
+ 5. `app_flow_plan`
36
+ 6. `app_flow_apply`
35
37
 
36
38
  If `app_flow_plan` reports `FLOW_DEPENDENCY_MISSING`, fix schema first.
39
+ If it reports `FLOW_ASSIGNEE_REQUIRED`, resolve roles or members first and retry with canonical `assignees.*`.
37
40
 
38
41
  ## Add or update views
39
42
 
@@ -10,9 +10,12 @@ Use `plan` before `apply` unless the patch is trivial and already normalized.
10
10
 
11
11
  ## Resolve
12
12
 
13
- - `package_create`: create a new package only when the user explicitly asked for one; exact-name duplicates return `noop=true`
13
+ - `package_create`: create a new package only after the user confirms package creation; exact-name duplicates return `noop=true`
14
14
  - `package_resolve`: exact package lookup by name
15
15
  - `package_list`: read-only fallback when package resolution is ambiguous
16
+ - `member_search`: resolve named people from the directory
17
+ - `role_search`: resolve reusable roles from the directory
18
+ - `role_create`: create a reusable role when the business owner wants role-based routing
16
19
  - `app_resolve`: locate an existing app by `app_key` or `app_name`
17
20
 
18
21
  ## Summary reads
@@ -59,15 +62,18 @@ These execute normalized patches and publish by default unless `publish=false`.
59
62
  - Tidy layout:
60
63
  `app_read_layout_summary -> app_layout_plan -> app_layout_apply`
61
64
  - Add workflow:
62
- `app_read_fields -> app_read_flow_summary -> app_flow_plan -> app_flow_apply`
65
+ `builder_tool_contract -> app_read_fields -> app_read_flow_summary -> role_search/member_search -> app_flow_plan -> app_flow_apply -> app_read_flow_summary`
63
66
  - Add views:
64
- `app_read_fields -> app_read_views_summary -> app_views_plan -> app_views_apply`
67
+ `builder_tool_contract -> app_read_fields -> app_read_views_summary -> app_views_plan -> app_views_apply -> app_read_views_summary`
65
68
 
66
69
  ## Avoid
67
70
 
68
71
  - Do not handcraft raw Qingflow schema payloads
69
72
  - Do not rely on internal `solution_*` tools in public builder flows
70
- - Do not create a new package unless the user explicitly asks for package separation
73
+ - Do not create a new package without first asking the user to confirm package creation
71
74
  - Do not skip summary reads before flow or view work
72
75
  - Do not emit `column_names`; always use `columns`
76
+ - Do not reuse internal flow keys such as `role_entries` or `editable_que_ids` in public builder calls
73
77
  - Do not pass natural-language preset guesses such as `default_approval`; map them to canonical preset values first
78
+ - Do not omit assignees on approval/fill/copy nodes
79
+ - Do not guess role ids, member ids, or editable field ids; resolve names first
@@ -4,11 +4,16 @@ Use this when the app already exists and the task is only about workflow.
4
4
 
5
5
  ## Minimal sequence
6
6
 
7
- 1. `app_read_fields`
8
- 2. `app_read_flow_summary`
9
- 3. start from a canonical preset when possible
10
- 4. `app_flow_plan`
11
- 5. `app_flow_apply`
7
+ 1. `builder_tool_contract(tool_name="app_flow_plan")`
8
+ 2. `app_read_fields`
9
+ 3. `app_read_flow_summary`
10
+ 4. `role_search` or `member_search`
11
+ 5. `role_create` if the user wants a reusable directory role and no good role exists
12
+ 6. start from a canonical preset when possible
13
+ 7. patch the skeleton instead of freehanding a full graph
14
+ 8. `app_flow_plan`
15
+ 9. `app_flow_apply`
16
+ 10. `app_read_flow_summary` when apply returns `partial_success` or the user asked for verification
12
17
 
13
18
  If you are unsure about presets or node shapes, call `builder_tool_contract(tool_name="app_flow_apply")` before guessing.
14
19
 
@@ -19,7 +24,7 @@ Canonical preset mapping:
19
24
  - “默认审批/基础审批/普通审批” -> `basic_approval`
20
25
  - “先填报再审批/提交后审批” -> `basic_fill_then_approve`
21
26
 
22
- Plan a simple approval flow:
27
+ Plan a simple approval flow with a role assignee and node-level editable fields:
23
28
 
24
29
  ```json
25
30
  {
@@ -27,7 +32,20 @@ Plan a simple approval flow:
27
32
  "arguments": {
28
33
  "profile": "default",
29
34
  "app_key": "APP_123",
30
- "preset": "basic_approval"
35
+ "preset": "basic_approval",
36
+ "nodes": [
37
+ {
38
+ "id": "approve_1",
39
+ "type": "approve",
40
+ "name": "部门审批",
41
+ "assignees": {
42
+ "role_names": ["项目经理"]
43
+ },
44
+ "permissions": {
45
+ "editable_fields": ["状态", "审批意见"]
46
+ }
47
+ }
48
+ ]
31
49
  }
32
50
  }
33
51
  ```
@@ -38,39 +56,133 @@ For flexible business requirements, do not jump straight to a full custom graph.
38
56
  2. identify the business-specific changes
39
57
  3. patch nodes/transitions explicitly
40
58
 
41
- Only after that should you use explicit nodes:
59
+ For branch flows, keep the public shape canonical:
60
+
61
+ 1. add a `branch` node
62
+ 2. add one or more `condition` nodes as branch lanes
63
+ 3. put filter rules on the `condition` nodes with `conditions` or `condition_groups`
64
+ 4. use an empty `condition` node as the default branch when needed
65
+
66
+ Canonical branch example:
42
67
 
43
68
  ```json
44
69
  {
45
- "tool_name": "app_flow_apply",
70
+ "tool_name": "app_flow_plan",
46
71
  "arguments": {
47
72
  "profile": "default",
48
73
  "app_key": "APP_123",
49
74
  "mode": "replace",
50
- "publish": true,
51
75
  "nodes": [
52
76
  {"id": "start", "type": "start", "name": "发起"},
53
- {"id": "approve_1", "type": "approve", "name": "审批"},
77
+ {"id": "route", "type": "branch", "name": "金额分支"},
78
+ {
79
+ "id": "high_amount",
80
+ "type": "condition",
81
+ "name": "金额大于等于一万",
82
+ "conditions": [
83
+ {"field_name": "预计金额", "operator": "gte", "value": 10000}
84
+ ]
85
+ },
86
+ {
87
+ "id": "approve_finance",
88
+ "type": "approve",
89
+ "name": "财务审批",
90
+ "assignees": {"role_names": ["财务负责人"]}
91
+ },
92
+ {"id": "default_lane", "type": "condition", "name": "其他情况"},
93
+ {
94
+ "id": "approve_manager",
95
+ "type": "approve",
96
+ "name": "部门审批",
97
+ "assignees": {"role_names": ["项目经理"]}
98
+ },
54
99
  {"id": "end", "type": "end", "name": "结束"}
55
100
  ],
56
101
  "transitions": [
57
- {"from": "start", "to": "approve_1"},
58
- {"from": "approve_1", "to": "end"}
102
+ {"from": "start", "to": "route"},
103
+ {"from": "route", "to": "high_amount"},
104
+ {"from": "high_amount", "to": "approve_finance"},
105
+ {"from": "route", "to": "default_lane"},
106
+ {"from": "default_lane", "to": "approve_manager"},
107
+ {"from": "approve_finance", "to": "end"},
108
+ {"from": "approve_manager", "to": "end"}
59
109
  ]
60
110
  }
61
111
  }
62
112
  ```
63
113
 
114
+ Only after that should you use explicit nodes:
115
+
116
+ ```json
117
+ {
118
+ "tool_name": "app_flow_apply",
119
+ "arguments": {
120
+ "profile": "default",
121
+ "app_key": "APP_123",
122
+ "mode": "replace",
123
+ "publish": true,
124
+ "nodes": [
125
+ {"id": "start", "type": "start", "name": "发起"},
126
+ {
127
+ "id": "approve_1",
128
+ "type": "approve",
129
+ "name": "部门审批",
130
+ "assignees": {
131
+ "role_names": ["项目经理"]
132
+ },
133
+ "permissions": {
134
+ "editable_fields": ["状态", "审批意见"]
135
+ }
136
+ },
137
+ {"id": "end", "type": "end", "name": "结束"}
138
+ ],
139
+ "transitions": [
140
+ {"from": "start", "to": "approve_1"},
141
+ {"from": "approve_1", "to": "end"}
142
+ ]
143
+ }
144
+ }
145
+ ```
146
+
147
+ After `app_flow_plan` succeeds, prefer reusing its `suggested_next_call.arguments` directly. Do not rewrite the result into internal fields such as `role_entries` or `editable_que_ids`.
148
+
64
149
  ## Common failures
65
150
 
151
+ ### `FLOW_ASSIGNEE_REQUIRED`
152
+
153
+ Approval, fill, and copy nodes must declare at least one assignee.
154
+
155
+ Preferred fix order:
156
+
157
+ 1. `role_search`
158
+ 2. `member_search` only if the user explicitly named members
159
+ 3. `role_create` if the business needs a reusable role
160
+ 4. retry `app_flow_plan` or `app_flow_apply` with canonical `assignees.*`
161
+
66
162
  ### `FLOW_DEPENDENCY_MISSING`
67
163
 
68
164
  The workflow depends on fields that do not exist yet, usually `status`. Fix schema first.
69
165
 
166
+ Preferred recovery:
167
+
168
+ 1. use the returned `suggested_next_call`
169
+ 2. apply the minimal schema patch
170
+ 3. rerun `app_read_fields`
171
+ 4. rerun `app_flow_plan`
172
+
70
173
  ### `INVALID_FLOW_EDGE`
71
174
 
72
175
  One or more transitions reference unknown nodes or create an invalid graph.
73
176
 
177
+ ### `UNKNOWN_FLOW_FIELD`
178
+
179
+ The workflow referenced a field name that does not exist, often in:
180
+
181
+ - `permissions.editable_fields`
182
+ - branch `conditions`
183
+
184
+ Call `app_read_fields` and retry with the exact field names returned by the app.
185
+
74
186
  ### `STATUS_FIELD_REQUIRED`
75
187
 
76
188
  The app has no explicit status field recognized by the internal workflow compiler. Add one with `app_schema_apply`, then retry.
@@ -87,11 +199,22 @@ Do not keep guessing preset names or node shapes. First:
87
199
  2. reuse `canonical_arguments` if present
88
200
  3. check `allowed_values`
89
201
  4. retry with canonical preset or canonical node types
202
+ 5. for workflow actors and permissions, always convert to:
203
+ - `assignees.role_names`
204
+ - `assignees.member_names`
205
+ - `permissions.editable_fields`
206
+
207
+ Do not copy internal keys from old plan outputs or logs, including:
208
+
209
+ - `role_entries`
210
+ - `editable_que_ids`
90
211
 
91
212
  ## Notes
92
213
 
93
214
  - `mode=replace` is the only supported flow apply mode
94
215
  - `app_flow_apply` publishes by default
216
+ - Prefer roles over explicit members unless the user explicitly asks for named members
217
+ - `basic_approval` and `basic_fill_then_approve` are skeletons, not complete business workflows
95
218
  - Report results precisely:
96
219
  - “基础流程骨架已创建” when only the preset landed
97
220
  - “业务定制规则已补齐” only after the patch phase is complete