@josephyan/qingflow-app-builder-mcp 0.2.0-beta.1 → 0.2.0-beta.11

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 (29) hide show
  1. package/README.md +11 -2
  2. package/npm/lib/runtime.mjs +37 -0
  3. package/npm/scripts/postinstall.mjs +5 -1
  4. package/package.json +3 -2
  5. package/pyproject.toml +1 -1
  6. package/skills/qingflow-app-builder/SKILL.md +172 -0
  7. package/skills/qingflow-app-builder/agents/openai.yaml +4 -0
  8. package/skills/qingflow-app-builder/references/create-app.md +112 -0
  9. package/skills/qingflow-app-builder/references/environments.md +63 -0
  10. package/skills/qingflow-app-builder/references/flow-actors-and-permissions.md +124 -0
  11. package/skills/qingflow-app-builder/references/gotchas.md +48 -0
  12. package/skills/qingflow-app-builder/references/solution-playbooks.md +58 -0
  13. package/skills/qingflow-app-builder/references/tool-selection.md +78 -0
  14. package/skills/qingflow-app-builder/references/update-flow.md +204 -0
  15. package/skills/qingflow-app-builder/references/update-layout.md +81 -0
  16. package/skills/qingflow-app-builder/references/update-schema.md +90 -0
  17. package/skills/qingflow-app-builder/references/update-views.md +157 -0
  18. package/src/qingflow_mcp/__init__.py +1 -1
  19. package/src/qingflow_mcp/builder_facade/models.py +242 -0
  20. package/src/qingflow_mcp/builder_facade/service.py +2055 -195
  21. package/src/qingflow_mcp/server_app_builder.py +82 -4
  22. package/src/qingflow_mcp/solution/compiler/form_compiler.py +1 -1
  23. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +21 -2
  24. package/src/qingflow_mcp/solution/executor.py +34 -7
  25. package/src/qingflow_mcp/tools/ai_builder_tools.py +1001 -30
  26. package/src/qingflow_mcp/tools/app_tools.py +40 -2
  27. package/src/qingflow_mcp/tools/auth_tools.py +2 -1
  28. package/src/qingflow_mcp/tools/workflow_tools.py +78 -4
  29. package/src/qingflow_mcp/tools/workspace_tools.py +6 -1
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.1
6
+ npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.11
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.1 qingflow-app-builder-mcp
12
+ npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.11 qingflow-app-builder-mcp
13
13
  ```
14
14
 
15
15
  Environment:
@@ -19,3 +19,12 @@ Environment:
19
19
  - `QINGFLOW_MCP_HOME`
20
20
 
21
21
  This package bootstraps a local Python runtime on first install and then starts the `qingflow-app-builder-mcp` stdio MCP server.
22
+
23
+ Bundled skill:
24
+
25
+ - `skills/qingflow-app-builder`
26
+
27
+ Note:
28
+
29
+ - The skill files are included in the npm package.
30
+ - On install, the package copies them to `$CODEX_HOME/skills` (or `~/.codex/skills` if `CODEX_HOME` is unset).
@@ -29,6 +29,43 @@ export function getPackageRoot(metaUrl) {
29
29
  return path.resolve(path.dirname(fileURLToPath(metaUrl)), "..", "..");
30
30
  }
31
31
 
32
+ export function getCodexHome() {
33
+ const configured = process.env.CODEX_HOME?.trim();
34
+ if (configured) {
35
+ return path.resolve(configured);
36
+ }
37
+ const home = process.env.HOME || process.env.USERPROFILE;
38
+ if (!home) {
39
+ throw new Error("Cannot resolve CODEX_HOME because HOME is not set.");
40
+ }
41
+ return path.join(home, ".codex");
42
+ }
43
+
44
+ export function installBundledSkills(packageRoot) {
45
+ const skillsSrc = path.join(packageRoot, "skills");
46
+ if (!fs.existsSync(skillsSrc)) {
47
+ return { installed: [], skipped: true, destination: null };
48
+ }
49
+
50
+ const codexHome = getCodexHome();
51
+ const skillsDestRoot = path.join(codexHome, "skills");
52
+ fs.mkdirSync(skillsDestRoot, { recursive: true });
53
+
54
+ const installed = [];
55
+ for (const entry of fs.readdirSync(skillsSrc, { withFileTypes: true })) {
56
+ if (!entry.isDirectory()) {
57
+ continue;
58
+ }
59
+ const src = path.join(skillsSrc, entry.name);
60
+ const dest = path.join(skillsDestRoot, entry.name);
61
+ fs.rmSync(dest, { recursive: true, force: true });
62
+ fs.cpSync(src, dest, { recursive: true });
63
+ installed.push(entry.name);
64
+ }
65
+
66
+ return { installed, skipped: false, destination: skillsDestRoot };
67
+ }
68
+
32
69
  export function getVenvDir(packageRoot) {
33
70
  return path.join(packageRoot, ".npm-python");
34
71
  }
@@ -1,4 +1,4 @@
1
- import { ensurePythonEnv, getPackageRoot } from "../lib/runtime.mjs";
1
+ import { ensurePythonEnv, getPackageRoot, installBundledSkills } from "../lib/runtime.mjs";
2
2
 
3
3
  const packageRoot = getPackageRoot(import.meta.url);
4
4
 
@@ -6,6 +6,10 @@ try {
6
6
  console.log("[qingflow-mcp] Bootstrapping Python runtime...");
7
7
  ensurePythonEnv(packageRoot, { commandName: "qingflow-app-builder-mcp" });
8
8
  console.log("[qingflow-mcp] Python runtime is ready.");
9
+ const skills = installBundledSkills(packageRoot);
10
+ if (!skills.skipped) {
11
+ console.log(`[qingflow-mcp] Installed skills to ${skills.destination}: ${skills.installed.join(", ")}`);
12
+ }
9
13
  } catch (error) {
10
14
  console.error(`[qingflow-mcp] postinstall failed: ${error.message}`);
11
15
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyan/qingflow-app-builder-mcp",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.0-beta.11",
4
4
  "description": "Builder MCP for Qingflow app/package/system design and staged solution workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,8 @@
18
18
  "src/qingflow_mcp/py.typed",
19
19
  "qingflow-app-builder-mcp",
20
20
  "npm/",
21
- "docs/local-agent-install.md"
21
+ "docs/local-agent-install.md",
22
+ "skills/"
22
23
  ],
23
24
  "engines": {
24
25
  "node": ">=16.16.0"
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.0b1"
7
+ version = "0.2.0b11"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: qingflow-app-builder
3
+ description: Build, configure, and modify Qingflow apps and systems after the MCP is already connected and authenticated. Use when the user wants to apply or repair an existing SolutionSpec, modify an existing package with app, view, workflow, portal, navigation, or reporting tools, verify builder-side results, or troubleshoot system-building behavior. Do not use this skill to install the MCP or to author a brand new SolutionSpec from scratch.
4
+ metadata:
5
+ short-description: Build and modify Qingflow apps and systems
6
+ ---
7
+
8
+ # Qingflow App Builder
9
+
10
+ ## Overview
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.
13
+
14
+ 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
+ ## Tool Selection
17
+
18
+ Pick the smallest tool layer that can finish the task.
19
+
20
+ - Authentication and workspace: `auth_*`, `workspace_*`
21
+ - File upload: `file_upload_local`
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
+ - 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`, `role_create`
25
+ - Publish and verify: `app_publish_verify`
26
+
27
+ Note:
28
+ - Do not try to handcraft raw Qingflow schema or internal solution payloads.
29
+ - Do not rely on low-level `view_*`, `workflow_*`, or `qingbi_report_*` write payloads from public builder flows.
30
+ - Public builder work should stay on the resource path: `resolve -> summary read -> plan -> apply -> attach -> publish_verify`.
31
+ - `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.
32
+ - If you are unsure about a public builder tool's keys, aliases, presets, or minimal legal shape, call `builder_tool_contract` instead of guessing.
33
+ - 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.
34
+ - For flow presets, map natural language to canonical values before calling MCP:
35
+ - “默认审批/基础审批/普通审批” -> `basic_approval`
36
+ - “先填报再审批/提交后审批” -> `basic_fill_then_approve`
37
+ - For workflow assignees, prefer roles over explicit members:
38
+ - use `role_search` first
39
+ - use `member_search` only when the user explicitly names members or no stable role exists
40
+ - use `role_create` when the business owner wants a reusable directory role instead of hard-coded members
41
+ - On any `VALIDATION_ERROR`, inspect `suggested_next_call` first and prefer reusing the MCP-normalized arguments over re-guessing from the original natural language.
42
+
43
+ Default policy:
44
+
45
+ - 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.
46
+ - If package creation looks necessary or beneficial, ask the user to confirm before calling `package_create`.
47
+
48
+ ## Standard Operating Order
49
+
50
+ Before any business tool:
51
+
52
+ 1. Ensure auth exists
53
+ 2. Ensure workspace is selected
54
+ 3. Confirm whether the task is read-only or write-impacting
55
+
56
+ For builder work:
57
+
58
+ 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`.
59
+ 2. Resolve the target app with `app_resolve` if the request is an update.
60
+ 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`.
61
+ 4. Use `app_schema_plan`, `app_layout_plan`, `app_flow_plan`, or `app_views_plan` before any non-trivial write.
62
+ 5. Use `app_schema_apply` for create/upsert/remove field work. It publishes by default after the patch lands.
63
+ 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`.
64
+ 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.
65
+ 8. Use `app_flow_apply` after schema exists. It publishes by default.
66
+ 9. Use `app_views_apply` when the user wants explicit table/card/board/gantt views. It publishes by default.
67
+ 10. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need an explicit verification pass.
68
+ 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.
69
+
70
+ For view work, keep the order strict:
71
+
72
+ 1. `app_read_fields`
73
+ 2. `app_read_views_summary`
74
+ 3. `app_views_plan`
75
+ 4. `app_views_apply`
76
+
77
+ For flow work, keep the order strict:
78
+
79
+ 1. `app_read_fields`
80
+ 2. `app_read_flow_summary`
81
+ 3. `role_search` or `member_search` if assignees need to come from the directory
82
+ 4. `role_create` if the user wants a reusable role and no suitable role exists yet
83
+ 5. Start from a canonical preset when possible
84
+ 6. Use patch-style edits to that skeleton instead of freehand full-graph generation
85
+ 7. Declare approver/fill/copy assignees explicitly:
86
+ - prefer `assignees.role_names`
87
+ - support `assignees.member_names` / `assignees.member_emails` / `assignees.member_uids`
88
+ 8. When a node must edit specific fields, declare `permissions.editable_fields`
89
+ 9. `app_flow_plan`
90
+ 10. `app_flow_apply`
91
+
92
+ In `prod`, keep `plan` and `apply` as separate phases unless the user explicitly asks for a direct live execution.
93
+
94
+ For additive work on existing systems:
95
+
96
+ 1. Confirm the target package or existing apps
97
+ 2. Avoid creating a new package unless the user explicitly wants a separate solution
98
+ 3. Use ordinary low-level tools for incremental change
99
+ 4. Re-verify the affected apps, views, workflows, or portal after modification
100
+
101
+ ## Safe Usage Rules
102
+
103
+ - 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
104
+ - `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.
105
+ - Prefer `*_plan` before `*_apply`; the plan tools do server-side normalization and return the next executable call skeleton.
106
+ - For abstract requests like “默认视图”, “基础审批流”, “灵活流程”, or “美观布局”, first translate the intent into a stable preset or explicit patch. Do not send those phrases to MCP unchanged.
107
+ - For flexible workflow requests, split the work into two steps:
108
+ 1. create a base skeleton with a preset
109
+ 2. apply explicit business-specific changes as patchable nodes/transitions
110
+ - Approval, fill, and copy nodes must declare at least one assignee. Treat this as a hard requirement, not an optional detail.
111
+ - For workflow nodes, use the canonical public shape:
112
+ - `assignees.role_names`
113
+ - `assignees.member_names`
114
+ - `permissions.editable_fields`
115
+ - Do not guess role ids or member ids. Resolve them from the directory first.
116
+ - `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.
117
+ - `package_attach_app` is the source of truth for package ownership; do not assume app creation or publish implicitly attaches the app.
118
+ - `relation` and `subtable` must be explicit; do not infer them from vague natural language.
119
+ - In `prod`, prefer explicit patch tools and avoid any speculative create flow.
120
+ - 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.
121
+
122
+ ## Response Interpretation
123
+
124
+ - low-level list totals from the backend may report `0` while rows are present; prefer summary or aggregate readbacks for final conclusions
125
+ - `app_publish_verify` is the publish source of truth.
126
+ - If readback mismatches the UI, compare `request_route` and do not assume the builder hit the same `qf_version` as the browser
127
+ - Treat post-write readback as the source of truth, not just write status codes
128
+ - In final user-facing summaries, distinguish clearly between:
129
+ - base template/skeleton applied
130
+ - business-specific rules completed
131
+ - remaining gaps or follow-up patches
132
+ - Do not report “流程已满足业务需求” when only a preset skeleton has landed.
133
+
134
+ ## Practical Patterns
135
+
136
+ - List packages: `package_list`
137
+ - Resolve one package: `package_resolve`
138
+ - Create one package: `package_create`
139
+ - Read one public tool contract: `builder_tool_contract`
140
+ - Resolve one app: `app_resolve`
141
+ - Read one app summary: `app_read_summary`
142
+ - Read fields only: `app_read_fields`
143
+ - Read layout summary: `app_read_layout_summary`
144
+ - Read views summary: `app_read_views_summary`
145
+ - Read flow summary: `app_read_flow_summary`
146
+ - Plan schema patch: `app_schema_plan`
147
+ - Plan layout patch: `app_layout_plan`
148
+ - Plan workflow patch: `app_flow_plan`
149
+ - Plan view patch: `app_views_plan`
150
+ - Search members for workflow assignees: `member_search`
151
+ - Search roles for workflow assignees: `role_search`
152
+ - Create reusable workflow role: `role_create`
153
+ - Add/update/remove fields: `app_schema_apply`
154
+ - Merge or replace layout: `app_layout_apply`
155
+ - Replace workflow: `app_flow_apply`
156
+ - Upsert/remove views: `app_views_apply`
157
+ - Attach one app to a package: `package_attach_app`
158
+ - Release your own stale edit lock: `app_release_edit_lock_if_mine`
159
+ - Publish and verify: `app_publish_verify` when you need a separate verification pass beyond the default auto-publish behavior in apply tools
160
+
161
+ Detailed playbooks:
162
+
163
+ - Environment switching: [references/environments.md](references/environments.md)
164
+ - Tool choice and sequencing: [references/tool-selection.md](references/tool-selection.md)
165
+ - Result semantics and gotchas: [references/gotchas.md](references/gotchas.md)
166
+ - Create one app in an existing package: [references/create-app.md](references/create-app.md)
167
+ - Update fields only: [references/update-schema.md](references/update-schema.md)
168
+ - Update layout only: [references/update-layout.md](references/update-layout.md)
169
+ - Update workflow only: [references/update-flow.md](references/update-flow.md)
170
+ - Workflow assignees and node permissions: [references/flow-actors-and-permissions.md](references/flow-actors-and-permissions.md)
171
+ - Update views only: [references/update-views.md](references/update-views.md)
172
+ - Standard end-to-end builder sequences: [references/solution-playbooks.md](references/solution-playbooks.md)
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Qingflow App Builder"
3
+ short_description: "Build and modify Qingflow apps and systems"
4
+ default_prompt: "Use $qingflow-app-builder to build or modify a Qingflow app or system safely, and verify environment routing and post-write readbacks when builder flows touch live data."
@@ -0,0 +1,112 @@
1
+ # Create App
2
+
3
+ Use this when the user wants one new app inside an existing package.
4
+
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
+
7
+ ## Minimal sequence
8
+
9
+ 1. `package_resolve`
10
+ 2. `app_resolve`
11
+ 3. `app_schema_plan`
12
+ 4. `app_schema_apply`
13
+ 5. `package_attach_app`
14
+ 6. `app_publish_verify` only when the user asks for explicit final verification
15
+
16
+ ## Example
17
+
18
+ Create a new package only after the user confirms package creation:
19
+
20
+ ```json
21
+ {
22
+ "tool_name": "package_create",
23
+ "arguments": {
24
+ "profile": "default",
25
+ "package_name": "研发项目管理"
26
+ }
27
+ }
28
+ ```
29
+
30
+ Resolve the package:
31
+
32
+ ```json
33
+ {
34
+ "tool_name": "package_resolve",
35
+ "arguments": {
36
+ "profile": "default",
37
+ "package_name": "测试应用包"
38
+ }
39
+ }
40
+ ```
41
+
42
+ Plan schema for a new app:
43
+
44
+ ```json
45
+ {
46
+ "tool_name": "app_schema_plan",
47
+ "arguments": {
48
+ "profile": "default",
49
+ "app_name": "客户订单",
50
+ "package_tag_id": 1218950,
51
+ "create_if_missing": true,
52
+ "add_fields": [
53
+ {"name": "订单编号", "type": "text", "required": true},
54
+ {"name": "客户名称", "type": "text", "required": true},
55
+ {"name": "订单金额", "type": "amount"},
56
+ {"name": "状态", "type": "single_select", "options": ["草稿", "进行中", "已完成"], "required": true}
57
+ ],
58
+ "update_fields": [],
59
+ "remove_fields": []
60
+ }
61
+ }
62
+ ```
63
+
64
+ Apply schema. This publishes by default:
65
+
66
+ ```json
67
+ {
68
+ "tool_name": "app_schema_apply",
69
+ "arguments": {
70
+ "profile": "default",
71
+ "app_name": "客户订单",
72
+ "package_tag_id": 1218950,
73
+ "create_if_missing": true,
74
+ "publish": true,
75
+ "add_fields": [
76
+ {"name": "订单编号", "type": "text", "required": true},
77
+ {"name": "客户名称", "type": "text", "required": true},
78
+ {"name": "订单金额", "type": "amount"},
79
+ {"name": "状态", "type": "single_select", "options": ["草稿", "进行中", "已完成"], "required": true}
80
+ ],
81
+ "update_fields": [],
82
+ "remove_fields": []
83
+ }
84
+ }
85
+ ```
86
+
87
+ Attach explicitly if `tag_ids_after` does not yet contain the package:
88
+
89
+ ```json
90
+ {
91
+ "tool_name": "package_attach_app",
92
+ "arguments": {
93
+ "profile": "default",
94
+ "tag_id": 1218950,
95
+ "app_key": "APP_KEY_FROM_SCHEMA_APPLY"
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## Common failures
101
+
102
+ ### `APP_NOT_FOUND`
103
+
104
+ Expected on create. Continue with `create_if_missing=true`.
105
+
106
+ ### `CREATE_APP_ROUTE_NOT_FOUND`
107
+
108
+ The create route did not resolve in the current backend route context. Re-run `workspace_select`, then retry the same `app_schema_apply`.
109
+
110
+ ### `PACKAGE_ATTACH_FAILED`
111
+
112
+ Do not retry schema creation. Re-run only `package_attach_app`, then verify with `app_read_summary`.
@@ -0,0 +1,63 @@
1
+ # Environment Switching
2
+
3
+ Use this reference before any builder-side write, repair, or verification flow.
4
+
5
+ ## Step 1: Resolve the active environment
6
+
7
+ Decide explicitly whether the task targets:
8
+
9
+ - `test`: build validation, mock data, trial package creation, safe iteration
10
+ - `prod`: formal business system changes in the live environment
11
+
12
+ If the user did not specify an environment, default to `prod`.
13
+
14
+ ## Test Environment
15
+
16
+ Use test for:
17
+
18
+ - first application of a new `SolutionSpec`
19
+ - trying `solution_build_all(..., verify=true)`
20
+ - package initialization and schema evolution experiments
21
+ - mock data creation, with at least `5` records per relevant entity unless the user asks for fewer
22
+
23
+ Builder behavior in test:
24
+
25
+ - `preflight` or `plan` is still preferred, but fast `apply` is acceptable when the user explicitly wants an end-to-end smoke test
26
+ - package creation is acceptable
27
+ - verify should read back apps, views, portal, navigation, and sample records
28
+
29
+ Known current test backend:
30
+
31
+ - use an explicitly provided non-production backend
32
+
33
+ ## Production Environment
34
+
35
+ Use production for:
36
+
37
+ - changes to real business systems
38
+ - additive modifications to live packages and apps
39
+ - controlled rollout of approved solution specs
40
+
41
+ Builder behavior in prod:
42
+
43
+ - always identify the target package or app set before changing anything
44
+ - default to `preflight` or `plan` before any `apply`
45
+ - additive requirements should modify the existing package with ordinary tools by default
46
+ - if creating a new package seems necessary in prod, ask the user to confirm package creation first
47
+ - do not seed mock data unless the user explicitly approves it for production
48
+ - verify is mandatory after writes
49
+
50
+ Production guardrails:
51
+
52
+ - restate the target workspace and target package before any write
53
+ - call out whether the action creates, mutates, or deletes builder-side configuration
54
+ - if a safer read-only inspection can answer the request, do that first
55
+
56
+ ## Reporting Rule
57
+
58
+ For builder work, always report:
59
+
60
+ - active environment
61
+ - target workspace
62
+ - whether the operation is `plan`, `apply`, `repair`, or `verify`
63
+ - whether it touches an existing package or creates a new one
@@ -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`
@@ -0,0 +1,48 @@
1
+ # Builder Gotchas
2
+
3
+ ## Auth and workspace
4
+
5
+ - `auth_*` success does not mean a workspace is selected
6
+ - Re-run `workspace_select` after auth changes or route changes
7
+
8
+ ## Package ownership
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
13
+
14
+ ## Auto publish
15
+
16
+ - `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default
17
+ - Pass `publish=false` only when the user explicitly wants to leave changes in draft
18
+ - `app_publish_verify` is for explicit final verification, not the default next step after every write
19
+
20
+ ## Readback scope
21
+
22
+ - Prefer summary reads over large raw payloads
23
+ - Use `app_read_fields` before schema or view work
24
+ - Use `app_read_layout_summary` before layout work
25
+ - Use `app_read_flow_summary` before workflow work
26
+ - Use `app_read_views_summary` before view work
27
+
28
+ ## Workflow dependencies
29
+
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
35
+ - If `app_flow_plan` reports `FLOW_DEPENDENCY_MISSING`, fix schema first
36
+ - Do not switch to hidden `solution_*` tools from public builder flows
37
+
38
+ ## Retry discipline
39
+
40
+ - If a write returns `partial_success`, read back before retrying
41
+ - Do not repeat create steps after `app_key` already exists
42
+ - For backend rejects, keep the retry narrow: retry only the failed tool, not the whole chain
43
+ - For `VALIDATION_ERROR`, do not keep guessing. Reuse `suggested_next_call`, `canonical_arguments`, `allowed_keys`, and `allowed_values` first.
44
+ - If a view or flow write fails, report the smallest next action:
45
+ - wrong key -> switch to canonical key
46
+ - unsupported preset -> switch to allowed canonical preset
47
+ - backend reject -> re-read summary and retry only the failed patch
48
+ - Do not translate abstract user phrases like “灵活流程” or “默认视图” directly into MCP arguments. First convert them to a preset or explicit patch plan.