@josephyan/qingflow-app-builder-mcp 1.1.25 → 1.1.27

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 (100) hide show
  1. package/README.md +6 -6
  2. package/docs/local-agent-install.md +6 -57
  3. package/entry_point.py +1 -1
  4. package/npm/bin/qingflow-app-builder-mcp.mjs +33 -2
  5. package/npm/lib/runtime.mjs +101 -21
  6. package/npm/scripts/postinstall.mjs +10 -1
  7. package/package.json +2 -3
  8. package/pyproject.toml +1 -1
  9. package/skills/qingflow-app-builder/SKILL.md +51 -164
  10. package/skills/qingflow-app-builder/references/build-complete-system.md +234 -0
  11. package/skills/qingflow-app-builder/references/build-single-app.md +138 -0
  12. package/skills/qingflow-app-builder/references/create-app.md +24 -31
  13. package/skills/qingflow-app-builder/references/environments.md +1 -1
  14. package/skills/qingflow-app-builder/references/gotchas.md +13 -39
  15. package/skills/qingflow-app-builder/references/match-rules.md +18 -29
  16. package/skills/qingflow-app-builder/references/public-surface-sync.md +2 -2
  17. package/skills/qingflow-app-builder/references/solution-playbooks.md +0 -10
  18. package/skills/qingflow-app-builder/references/tool-selection.md +25 -42
  19. package/skills/qingflow-app-builder/references/update-flow.md +38 -22
  20. package/skills/qingflow-app-builder/references/update-schema.md +0 -14
  21. package/skills/qingflow-app-builder/references/update-views.md +14 -83
  22. package/skills/qingflow-app-builder-code-integrations/SKILL.md +3 -5
  23. package/skills/qingflow-app-builder-code-integrations/references/code-block.md +1 -1
  24. package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +1 -1
  25. package/skills/qingflow-mcp-setup/SKILL.md +111 -0
  26. package/skills/qingflow-mcp-setup/agents/openai.yaml +4 -0
  27. package/skills/qingflow-mcp-setup/references/claude-desktop.md +34 -0
  28. package/skills/qingflow-mcp-setup/references/environments.md +61 -0
  29. package/skills/qingflow-mcp-setup/references/generic-stdio.md +31 -0
  30. package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +38 -0
  31. package/skills/qingflow-workflow-builder/SKILL.md +96 -0
  32. package/skills/qingflow-workflow-builder/manifest.yaml +8 -0
  33. package/skills/qingflow-workflow-builder/references/01-overview.md +45 -0
  34. package/skills/qingflow-workflow-builder/references/02-update-mode.md +53 -0
  35. package/skills/qingflow-workflow-builder/references/03-flow-patterns.md +57 -0
  36. package/skills/qingflow-workflow-builder/references/04-stage1-business-modeling.md +131 -0
  37. package/skills/qingflow-workflow-builder/references/05-stage2-members-roles.md +29 -0
  38. package/skills/qingflow-workflow-builder/references/06-stage3-build-spec.md +165 -0
  39. package/skills/qingflow-workflow-builder/references/07-stage4-validate-spec.md +33 -0
  40. package/skills/qingflow-workflow-builder/references/08-stage5-apply-verify.md +51 -0
  41. package/skills/qingflow-workflow-builder/references/09-stage6-summary.md +88 -0
  42. package/skills/qingflow-workflow-builder/references/10-node-config-reference.md +93 -0
  43. package/skills/qingflow-workflow-builder/references/11-troubleshooting.md +15 -0
  44. package/skills/qingflow-workflow-builder/scripts/diff_flow_spec.py +275 -0
  45. package/skills/qingflow-workflow-builder/scripts/validate_flow_spec.py +605 -0
  46. package/src/qingflow_mcp/__init__.py +1 -1
  47. package/src/qingflow_mcp/__main__.py +2 -6
  48. package/src/qingflow_mcp/builder_facade/models.py +49 -330
  49. package/src/qingflow_mcp/builder_facade/service.py +1621 -6149
  50. package/src/qingflow_mcp/cli/commands/builder.py +366 -322
  51. package/src/qingflow_mcp/cli/commands/chart.py +1 -1
  52. package/src/qingflow_mcp/cli/commands/common.py +3 -12
  53. package/src/qingflow_mcp/cli/commands/exports.py +2 -2
  54. package/src/qingflow_mcp/cli/commands/imports.py +3 -3
  55. package/src/qingflow_mcp/cli/commands/portal.py +2 -2
  56. package/src/qingflow_mcp/cli/commands/record.py +27 -101
  57. package/src/qingflow_mcp/cli/commands/task.py +47 -28
  58. package/src/qingflow_mcp/cli/commands/view.py +1 -1
  59. package/src/qingflow_mcp/cli/context.py +3 -0
  60. package/src/qingflow_mcp/cli/formatters.py +16 -784
  61. package/src/qingflow_mcp/cli/main.py +41 -120
  62. package/src/qingflow_mcp/errors.py +2 -43
  63. package/src/qingflow_mcp/public_surface.py +17 -26
  64. package/src/qingflow_mcp/response_trim.py +17 -81
  65. package/src/qingflow_mcp/server.py +12 -14
  66. package/src/qingflow_mcp/server_app_builder.py +39 -81
  67. package/src/qingflow_mcp/server_app_user.py +16 -22
  68. package/src/qingflow_mcp/session_store.py +7 -11
  69. package/src/qingflow_mcp/solution/compiler/__init__.py +1 -3
  70. package/src/qingflow_mcp/solution/executor.py +18 -245
  71. package/src/qingflow_mcp/tools/ai_builder_tools.py +1483 -3139
  72. package/src/qingflow_mcp/tools/app_tools.py +43 -184
  73. package/src/qingflow_mcp/tools/approval_tools.py +35 -197
  74. package/src/qingflow_mcp/tools/auth_tools.py +16 -92
  75. package/src/qingflow_mcp/tools/code_block_tools.py +40 -298
  76. package/src/qingflow_mcp/tools/custom_button_tools.py +10 -64
  77. package/src/qingflow_mcp/tools/directory_tools.py +72 -236
  78. package/src/qingflow_mcp/tools/export_tools.py +34 -244
  79. package/src/qingflow_mcp/tools/feedback_tools.py +0 -9
  80. package/src/qingflow_mcp/tools/file_tools.py +3 -9
  81. package/src/qingflow_mcp/tools/import_tools.py +49 -336
  82. package/src/qingflow_mcp/tools/navigation_tools.py +12 -91
  83. package/src/qingflow_mcp/tools/package_tools.py +6 -118
  84. package/src/qingflow_mcp/tools/portal_tools.py +3 -39
  85. package/src/qingflow_mcp/tools/qingbi_report_tools.py +7 -116
  86. package/src/qingflow_mcp/tools/record_tools.py +360 -1145
  87. package/src/qingflow_mcp/tools/resource_read_tools.py +39 -188
  88. package/src/qingflow_mcp/tools/role_tools.py +9 -80
  89. package/src/qingflow_mcp/tools/solution_tools.py +45 -59
  90. package/src/qingflow_mcp/tools/task_context_tools.py +158 -662
  91. package/src/qingflow_mcp/tools/task_tools.py +29 -113
  92. package/src/qingflow_mcp/tools/view_tools.py +3 -106
  93. package/src/qingflow_mcp/tools/workflow_tools.py +4 -48
  94. package/src/qingflow_mcp/tools/workspace_tools.py +3 -71
  95. package/src/qingflow_mcp/version.py +2 -0
  96. package/npm/bin/qingflow-skills.mjs +0 -5
  97. package/skills/qingflow-app-builder/references/complete-system-development-guide.md +0 -172
  98. package/skills/qingflow-app-builder/references/single-app-development-guide.md +0 -87
  99. package/skills/qingflow-app-builder/scripts/validate_system_build_summary.py +0 -124
  100. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +0 -173
@@ -19,40 +19,27 @@ Before picking tools, decide which layer the request targets:
19
19
 
20
20
  If the user asks for multiple forms/modules that relate to each other, this is a package-level multi-app task, not a single-app create.
21
21
 
22
- Use this split consistently:
23
-
24
- - Complete system/package: `package_apply` first, then one `app_schema_apply(package_id=..., apps=[...])`.
25
- - Single app: `app_resolve/app_get` first, then app-scoped apply tools.
26
- - Record/task/data operation: leave builder and use record/task skills.
27
-
28
- Decision gate before writing:
29
-
30
- | Evidence | Action |
31
- | --- | --- |
32
- | User gives an `app_key`, `view_key`, `chart_id`, `dash_key`, or exact `package_id` | Treat the task as an update to that existing target unless the user explicitly asks for a new one |
33
- | User names several forms/modules or asks for a system/package | Use the complete-system path; do not compress them into one app |
34
- | Same or very similar package/app already exists and the user did not say extend/replace/new | Stop and ask whether to extend existing, repair missing parts, or create a new target |
35
- | Existing readback already contains part of the requested system | List verified existing resources, identify gaps, and patch only missing or incorrect slices |
36
- | A write is uncertain: timeout, `partial_success`, `write_executed=true`, or `safe_to_retry=false` | Read back before retrying; do not create `V2`, `测试`, timestamp, or random-suffix resources |
37
-
38
22
  ## Resolve
39
23
 
40
- - `package_get`: read one known package by `package_id`; it reads package `baseInfo` first and may warn `PACKAGE_DETAIL_READ_DEGRADED` when the richer detail endpoint needs package edit/add-app permission. Treat that warning as degraded detail, not as package-read failure.
41
- - `package_apply`: create or update one package; `package_name` without `package_id` creates a package; layout/group/order changes require package edit permission because they call the backend package ordering route
24
+ - `package_get`: read one known package by `package_id`
25
+ - `package_apply`: create or update one package; use `create_if_missing=true` only after explicit user intent
42
26
  - `member_search`: resolve named people from the directory
43
27
  - `role_search`: resolve reusable roles from the directory
44
28
  - `role_create`: create a reusable role when the business owner wants role-based routing
45
- - `app_resolve`: locate an existing app by exactly one selector mode: `app_key`, or `app_name + package_id`; by-name resolution checks package detail/current visible apps before using broader admin-style app search, so a `/app/item` permission miss is not a frontend-visible-app failure
29
+ - `app_resolve`: locate an existing app by exactly one selector mode: `app_key`, or `app_name + package_id`
46
30
 
47
31
  ## Summary reads
48
32
 
33
+ All `app_get_*` tools accept either `app_key` (single) or `app_keys[]` (batch). Batch returns `{status, apps[], errors[]}` — prefer batch when reading multiple apps in one step.
34
+
49
35
  - `app_get`: overall app config health, publish state, counts, and builder editability
50
36
  - `app_get_fields`: field names, types, required flags, section ids
51
37
  - `app_get_layout`: sections, rows, unplaced fields
52
38
  - `app_get_views`: current view names, types, columns, group-by
53
- - `app_get_flow`: workflow enabled state, nodes, transitions
39
+ - `app_get_flow`: workflow enabled state, full spec (nodes + transitions)
54
40
  - `app_get_charts`: current chart ids, names, types, order
55
- - `chart_get`: one chart's base/config detail; base info is read through the Qingflow/qflow visible route first, and config may degrade from chart data when the CHART_SEE config endpoint is unavailable. Treat degraded config as a read-mode warning, not as proof the user cannot see the chart.
41
+ - `app_get_associated_resources`: current associated resource pool (draft state)
42
+ - `app_publish_verify`: publish state and package tag verification — accepts `app_keys[]` for multi-app batch
56
43
  - `portal_get`: current portal config detail and component inventory
57
44
 
58
45
  ## Apply tools
@@ -60,15 +47,14 @@ Decision gate before writing:
60
47
  These execute normalized patches. Some app apply tools publish by default and still accept `publish=false`; custom button and associated-resource apply publish after at least one write succeeds and do not expose that switch.
61
48
 
62
49
  - `app_schema_apply`: create app shell or change fields
63
- - `app_layout_apply`: merge or replace layout
64
- - `app_flow_apply`: replace workflow
65
- - `app_views_apply`: use `patch_views` for existing-view parameter replacement; use `upsert_views` for creation or full target config; remove views by key; for normal view-specific business buttons, declare `action_buttons` in the view object or `patch_views[].set`; new views default associated report/view display to visible with `limit_type="all"`
66
- - `app_custom_buttons_apply`: advanced custom-button maintenance only: style/icon changes, cross-view reuse, deleting button bodies, bulk reordering bindings, or exact qRobot/wings configs. Use `patch_buttons` for existing-button parameter replacement; use `upsert_buttons` for creation or full target config; bind buttons to header/detail/list view positions; `placement=list` maps to the backend `INSIDE` row/list button position; merge-mode view configs require `buttons`; use `view_configs[].mode="replace"` or `buttons=[]` to clear a view's custom button bindings. For child-record creation linked to the current source record, map `source_field: "数据ID"` to the target relation field.
67
- - `app_associated_resources_apply`: attach existing BI reports/views to the Qingflow app associated-resource pool and per-view display area; it does not create or edit QingBI report bodies/configs. Permission is split like the backend: resource pool writes use EditAppAuth, while `view_configs` uses the view config/DataManageAuth path. Use `patch_resources` for existing associated-resource parameter replacement; use `upsert_resources` for creation or full target config; `view_configs`, remove, and reorder may reference existing resources by internal `associated_item_id` or by `chart_id`/`chart_key`/`view_key`; use `match_mappings` with `target_field + operator + source_field/value` for associated view/report filters; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only to attach an existing BI dataset report. Before `upsert_resources`, read `app_get.associated_resources` and reuse an existing matching `target_app_key + view_key/chart_key`; repeated upsert can create duplicates because `client_key` is only valid inside one apply call.
68
- - `app_charts_apply`: create/edit/remove/reorder app-source QingBI report bodies/configs with `dataSourceType=qingflow`; it does not create/edit dataset BI reports and does not attach reports to Qingflow app associated-resource display. Use `app_get_fields.chart_fields` as the source for dimensions, metrics, and filters. Use semantic `metric`, `metrics`, `group_by`, and `where`: `target/indicator` for one KPI, `bar/columnar/pie` for distribution, `line/area` for trend, `table/detail/summary` for tabular summaries, and `dualaxes` for two-metric comparison. Do not use `summary` for a single metric card. Use `filters` with `field_name + operator + value/values`; the tool compiles them to QingBI string judge types. Use `patch_charts` for existing-chart parameter replacement; use `upsert_charts` for creation or full target config; avoid raw `indicator_field_ids`, `selectedMetrics`, and QingBI filter matrices on the main path; charts are immediate-live and do not publish; use `chart_id` when names are not unique; for complete systems, keep chart writes business-scoped, commonly 4-8 upserts by app or topic. Larger calls are accepted; if `CHART_UPSERT_BATCH_SIZE_RECOMMENDED` appears, read back before retrying and only repair failed items.
69
- - `portal_apply`: create or replace-update portal pages; use `dash_key` for update mode or `package_id + dash_name` for create mode; create mode only prechecks package add_app, matching backend portal creation; edit mode may omit `sections` for base-info-only updates; when sections are supplied they still use replace semantics. Build portals only after referenced apps, raw `view_key`s, and chart ids/keys are known. PC layout uses 24 columns: components with the same `y` must have the same `rows`, same-row `cols` should sum to 24, metric cards use `rows=5`, BI charts use `rows=7`, data views use `rows=11`, and business-entry grids must include real `config.items[]`. Use business entry -> metrics -> BI charts -> concrete data views; do not use platform default views or raw `source_type: "filter"` as the main path.
50
+ - `app_layout_apply`: layout-only maintenance for existing apps; new app layout belongs in `app_schema_apply` `form.sections`
51
+ - `app_flow_apply`: replace full workflow spec; use `patch_nodes[]` (`{id, set, unset}`) to update specific nodes without rewriting the full spec
52
+ - `app_views_apply`: use top-level `views[]` for same-app/cross-app batch create, patch, and remove; view business actions belong in each view item's `action_buttons`
53
+ - `app_associated_resources_apply`: attach existing BI reports/views to the Qingflow app associated-resource pool and per-view display area; it does not create or edit QingBI report bodies/configs. Use `patch_resources` for existing associated-resource parameter replacement; use `upsert_resources` for creation or full target config; `view_configs`, remove, and reorder may reference existing resources by internal `associated_item_id` or by `chart_id`/`chart_key`/`view_key`; use `match_mappings` for associated view/report filters; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only to attach an existing BI dataset report. Before `upsert_resources`, read `app_get.associated_resources` and reuse an existing matching `target_app_key + view_key/chart_key`; repeated upsert can create duplicates because `client_key` is only valid inside one apply call. Use `apps[]` for multi-app batch.
54
+ - `app_charts_apply`: create/edit/remove/reorder app-source QingBI report bodies/configs with `dataSourceType=qingflow`; it does not create/edit dataset BI reports and does not attach reports to Qingflow app associated-resource display. Use `patch_charts` for existing-chart parameter replacement; use `upsert_charts` for creation or full target config; supports `target/table` aliases plus QingBI chart types such as `summary`, `columnar`, `area`, `funnel`, `radar`, `scatter`, `dualaxes`, and `map`; charts are immediate-live and do not publish; use `chart_id` when names are not unique; use `apps[]` for multi-app batch
55
+ - `portal_apply`: create or replace-update portal pages; use `dash_key` for update mode or `package_id + dash_name` for create mode; edit mode may omit `sections` for base-info-only updates; when sections are supplied they still use replace semantics; sections use a 24-column PC grid all components in the same row (same `y`) must share the same `rows` value and their `cols` must sum to exactly 24; mismatched `rows` causes height misalignment, `cols` under 24 leaves trailing blank space; use `patch_sections[]` (`{chart/view_ref/order, set, unset}`) to update individual sections without replacing all
70
56
 
71
- For object-level updates, the safe partial syntax is `patch_*` with the object's real selector field plus `set` and optional `unset`. `selector` is only a concept, not a literal key. Examples: `patch_views: [{"view_key": "VIEW_KEY", "set": {...}}]`, `patch_buttons: [{"button_id": 1001, "set": {...}}]`, `patch_resources: [{"associated_item_id": 123, "set": {...}}]`, `patch_charts: [{"chart_id": 456, "set": {...}}]`. The tool reads the current backend config, merges the patch, then submits the full backend payload internally. Do not send a partial `upsert_*` and expect missing required fields to be preserved.
57
+ For object-level updates, the safe partial syntax is `patch_*` with the object's real selector field plus `set` and optional `unset`. `selector` is only a concept, not a literal key. Examples: `patch_views: [{"view_key": "VIEW_KEY", "set": {...}}]`, `patch_resources: [{"associated_item_id": 123, "set": {...}}]`, `patch_charts: [{"chart_id": 456, "set": {...}}]`, `patch_nodes: [{"id": "approve_1", "set": {...}}]`, `patch_sections: [{"chart": {"chart_key": "ck_001"}, "set": {"title": "新标题"}}]`. The tool reads the current backend config, merges the patch, then submits the full backend payload internally. Do not send a partial `upsert_*` and expect missing required fields to be preserved.
72
58
 
73
59
  ## Explicit post-apply tools
74
60
 
@@ -79,29 +65,27 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
79
65
  - Create one app inside an existing package:
80
66
  `package_get -> app_resolve -> app_schema_apply`
81
67
  - Create a brand new package, then create one app in it:
82
- `package_apply(package_name, icon, color) -> app_schema_apply`
68
+ `package_apply(create_if_missing=true) -> app_schema_apply`
83
69
  - Create a brand new multi-app system/package:
84
- `package_apply(package_name, icon, color) -> app_schema_apply(apps[])`; use `apps[].client_key` plus `target_app_ref`, or `target_app` when referencing by app name
70
+ `package_apply(create_if_missing=true) -> app_schema_apply(apps[] with form.sections)`
85
71
  - Update fields on an existing app:
86
72
  `app_resolve -> app_get_fields -> app_schema_apply`
87
73
  - Tidy layout:
88
- `app_get_fields -> app_get_layout -> builder_tool_contract (if shape is unclear) -> app_layout_apply`
74
+ `app_get_fields -> app_get_layout -> app_layout_apply`
89
75
  - Add workflow:
90
76
  `builder_tool_contract -> app_get_fields -> app_get_flow -> role_search/member_search -> app_flow_apply -> app_get_flow`
77
+ - Update specific flow nodes:
78
+ `app_get_flow -> app_flow_apply.patch_nodes[]`
91
79
  - Add views:
92
- `builder_tool_contract -> app_get_fields -> app_get_views -> app_views_apply.patch_views/upsert_views -> app_get_views`
93
- - Add ordinary view buttons:
94
- `app_get_views -> app_views_apply.patch_views/upsert_views with action_buttons -> app_get_views`
95
- - Maintain advanced custom buttons:
96
- `app_get -> app_custom_buttons_apply.patch_buttons/upsert_buttons + view_configs -> app_get_views`
97
- - Add QingBI charts:
98
- `builder_tool_contract -> app_get_fields -> app_get_charts -> app_charts_apply.patch_charts/upsert_charts -> app_get_charts`
80
+ `app_get_fields -> app_get_views -> app_views_apply.views[] -> app_get_views`
81
+ - Add QingBI charts for a portal:
82
+ `portal_apply.sections[].chart`
99
83
  - Show an existing QingBI chart inside a Qingflow app/view:
100
84
  `app_get -> app_associated_resources_apply.upsert_resources/patch_resources + view_configs -> app_get`
101
85
  - Create or update a portal:
102
86
  `builder_tool_contract -> portal_get -> portal_apply -> portal_get`
103
- - Patch one portal section:
104
- `portal_get -> portal_apply.patch_sections[] -> portal_get`
87
+ - Update portal section(s) without replacing all:
88
+ `portal_get -> portal_apply.patch_sections[]`
105
89
 
106
90
  ## Avoid
107
91
 
@@ -119,4 +103,3 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
119
103
  - Do not omit assignees on approval/fill/copy nodes
120
104
  - Do not patch preset flows with brand new approval/fill node ids unless you are intentionally replacing the skeleton; reuse preset ids like `approve_1` and `fill_1`
121
105
  - Do not guess role ids, member ids, or editable field ids; resolve names first
122
- - Do not force agent-authored schema into backend-internal names when public keys exist: write icons as `icon + color` first; `icon_config` / `icon:{name,color}` are compatibility aliases only. Options may use `{label,value}`, and same-call relation targets may use `target_app_ref` / `target_app`.
@@ -6,19 +6,18 @@ Use this when the app already exists and the task is only about workflow.
6
6
 
7
7
  1. `builder_tool_contract(tool_name="app_flow_apply")`
8
8
  2. `app_get_fields`
9
- 3. Confirm the app has one explicit business status field, usually a `select` named `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`
10
- 4. `app_get_flow`
11
- 5. `role_search` or `member_search`
12
- 6. `role_create` if the user wants a reusable directory role and no good role exists
13
- 7. start from a canonical preset when possible
14
- 8. patch the skeleton instead of freehanding a full graph
15
- 9. reuse preset node ids when patching:
9
+ 3. `app_get_flow`
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. reuse preset node ids when patching:
16
15
  - `basic_approval` -> patch `approve_1`
17
16
  - `basic_fill_then_approve` -> patch `fill_1` and `approve_1`
18
17
  Do not add a second approval/fill node with a new id unless you are intentionally replacing the skeleton.
19
18
  The MCP now auto-aligns the simplest single-node preset overrides, but still prefer explicit preset ids so the merged graph stays predictable.
20
- 10. `app_flow_apply`
21
- 11. `app_get_flow` when apply returns `partial_success` or the user asked for verification
19
+ 9. `app_flow_apply`
20
+ 10. `app_get_flow` when apply returns `partial_success` or the user asked for verification
22
21
 
23
22
  If you are unsure about presets or node shapes, call `builder_tool_contract(tool_name="app_flow_apply")` before guessing.
24
23
 
@@ -62,6 +61,34 @@ For flexible business requirements, do not jump straight to a full custom graph.
62
61
  2. identify the business-specific changes
63
62
  3. patch nodes/transitions explicitly
64
63
 
64
+ ## Targeted node updates
65
+
66
+ To change one or a few nodes without rewriting the full spec, use `patch_nodes[]` instead of `spec`:
67
+
68
+ ```json
69
+ {
70
+ "tool_name": "app_flow_apply",
71
+ "arguments": {
72
+ "profile": "default",
73
+ "app_key": "APP_123",
74
+ "publish": true,
75
+ "patch_nodes": [
76
+ {
77
+ "id": "approve_1",
78
+ "set": {
79
+ "name": "总监审批",
80
+ "assignees": {"role_names": ["总监"]}
81
+ }
82
+ }
83
+ ]
84
+ }
85
+ }
86
+ ```
87
+
88
+ `patch_nodes[]` reads the current flow, merges `set` keys and removes `unset` keys on the matched node, then writes the full spec back. It returns `FLOW_NODE_NOT_FOUND` if the `id` does not match any existing node — call `app_get_flow` first to confirm ids.
89
+
90
+ Do NOT use `patch_nodes` and `spec` together in the same call.
91
+
65
92
  Public flow building is intentionally limited to linear workflows. Use only:
66
93
 
67
94
  - `start`
@@ -97,18 +124,7 @@ Preferred fix order:
97
124
 
98
125
  ### `FLOW_DEPENDENCY_MISSING`
99
126
 
100
- The workflow depends on fields that do not exist yet, usually an explicit business status field. Fix schema first.
101
-
102
- Do:
103
-
104
- - add a business field such as `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`
105
- - use type `select` / `single_select`
106
- - use business options such as `草稿`, `进行中`, `已完成`
107
-
108
- Do not:
109
-
110
- - create platform workflow system fields such as `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`
111
- - skip the flow and still report workflow completion
127
+ The workflow depends on fields that do not exist yet, usually `status`. Fix schema first.
112
128
 
113
129
  Preferred recovery:
114
130
 
@@ -161,7 +177,7 @@ Do not copy internal keys from old plan outputs or logs, including:
161
177
 
162
178
  ## Notes
163
179
 
164
- - `mode=replace` is the only supported flow apply mode
180
+ - `mode=replace` is the only supported flow apply mode when using `spec`; `patch_nodes[]` does not require a `mode`
165
181
  - `app_flow_apply` publishes by default
166
182
  - Prefer roles over explicit members unless the user explicitly asks for named members
167
183
  - `basic_approval` and `basic_fill_then_approve` are skeletons, not complete business workflows
@@ -10,18 +10,6 @@ Use this when the app already exists and the task is only about fields.
10
10
 
11
11
  ## Example
12
12
 
13
- Do not add platform system fields as form controls: `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, `流程标题`. They are generated by Qingflow; use readback/list fields when you need them.
14
-
15
- Field patch rules:
16
-
17
- - Re-read fields first, then choose `add_fields`, `update_fields`, or `remove_fields`. If a field already exists, use `update_fields` instead of adding a duplicate.
18
- - Drafts may use intuitive type aliases: `multiline -> long_text`, `select -> single_select`, `checkbox -> multi_select`, `currency -> amount`, `mobile -> phone`. Readback canonical types are normal and do not prove a failed update.
19
- - `title` and `label` are accepted aliases for `name`, but the preferred public key is `name`.
20
- - Keep exactly one top-level data title field after the patch. `as_data_cover` is optional and only valid on top-level `attachment`.
21
- - Select fields must keep a clear `options` set. Sample data and filters should use those option labels or ids.
22
- - Relation fields must use `target_app_key` for existing apps, or `target_app_ref` only in same-batch app creation. `display_field` and `visible_fields` are selector objects such as `{"name": "客户名称"}`, not bare strings.
23
- - Do not impose a one-relation-field limit when updating schema; add the relation fields the business needs and rely on backend validation/readback.
24
-
25
13
  Read current fields first:
26
14
 
27
15
  ```json
@@ -76,11 +64,9 @@ Treat it as uncertain write state. Read back with `app_get_fields` before retryi
76
64
 
77
65
  - `title` and `label` are accepted aliases for `name`
78
66
  - `textarea -> long_text`
79
- - `multiline` / `multiline_text -> long_text`
80
67
  - `currency -> amount`
81
68
  - `mobile -> phone`
82
69
  - `select/radio -> single_select`
83
70
  - `checkbox -> multi_select`
84
71
  - `as_data_title: true` marks the app data title; the final form must have exactly one top-level data title field
85
72
  - `as_data_cover: true` marks the app data cover; the cover is optional and must be a top-level `attachment` field
86
- - `数据ID`, `编号`, applicant/creation/update time, and workflow status fields are system-generated and must not appear in `add_fields`
@@ -28,25 +28,17 @@ Canonical rules before any example:
28
28
  - Always use `columns`
29
29
  - Do not emit `column_names`
30
30
  - Treat `fields` only as a legacy alias the MCP may normalize, not as the preferred shape
31
- - Use `filters` with the unified fixed-filter DSL: `field_name`, `operator`, `value`/`values`; do not write raw `judgeType` / `judgeValues`
31
+ - Use `filters` with canonical keys `field_name`, `operator`, `value`/`values`
32
32
  - Use `query_conditions` for the frontend query panel. Do not put query-panel fields into `filters`.
33
- - Do not create views named `全部数据`, `我的数据`, `我发起的`, `待办`, `已办`, or `抄送`. These are built-in default/system views. New views must use business-specific names such as `订单台账视图`, `客户跟进视图`, or `逾期任务看板`.
34
- - To change a built-in default/system view, first read the existing raw `view_key` from `app_get.views` or `app_get_views`, then use `patch_views` or a full `upsert_views` item with that `view_key`.
33
+ - When creating any new table or card view, always include `query_conditions` with `enabled: true`. In `rows`, list the fields users would most commonly search by — typically the data-title field, any status/type select fields, date fields, and member fields. Do not omit `query_conditions` or leave `rows` empty on a new view.
35
34
  - New views created by `app_views_apply` default the frontend associated report/view area to visible with `limit_type="all"`. Existing views preserve their current associated-resource display unless `associated_resources` is explicitly patched.
36
- - Use `app_associated_resources_apply` for the associated report/view resource pool, selected resources, and match rules. Permission is split like the backend: resource pool writes use EditAppAuth, while `view_configs` uses the view config/DataManageAuth path. `associated_item_id` is the internal associated-resource id from `app_get.associated_resources`; `view_configs`, remove, and reorder may also pass an existing resource's `chart_id`/`chart_key`/`view_key`, which the tool resolves to the internal id. Do not write backend raw `sourceType`; reports default to BI app reports, and dataset reports use `report_source="dataset"`. Use `match_mappings` with `target_field + operator + source_field/value` for associated view/report filters; read `match-rules.md` if field type compatibility is unclear.
35
+ - Use `app_associated_resources_apply` for the associated report/view resource pool, selected resources, and match rules. `associated_item_id` is the internal associated-resource id from `app_get.associated_resources`; `view_configs`, remove, and reorder may also pass an existing resource's `chart_id`/`chart_key`/`view_key`, which the tool resolves to the internal id. Do not write backend raw `sourceType`; reports default to BI app reports, and dataset reports use `report_source="dataset"`. Use `match_mappings` for associated view/report filters; read `match-rules.md` if field type compatibility is unclear.
37
36
  - For gantt, use `start_field`, `end_field`, and optionally `title_field`
38
37
  - If `app_get.views` or `app_get_views` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
39
38
  - Builder view writes always use the raw `view_key` from `app_get.views[].view_key`, such as `emsrao25rs02`. Do not pass `custom:emsrao25rs02`; that prefixed form is only for record-data `view_id`.
40
39
  - For an existing view, prefer `patch_views` for parameter replacement. Do not send a partial `upsert_views` object such as only `name/type/query_conditions`; backend view saves require other type-specific fields, and the patch path preserves them for you.
41
- - For ordinary view-specific business buttons, declare `action_buttons` inside `upsert_views[]` or `patch_views[].set`. Use `app_custom_buttons_apply` only for style/icon changes, cross-view reuse, deleting button bodies, bulk binding reorder, or exact qRobot/wings configs.
42
- - Choose the button by user intent before choosing a trigger type:
43
- - current record -> downstream/related record: `add_data` with `target_app_key + field_mappings`
44
- - global independent entry: `add_data` on `header` without current-record `source_field`
45
- - URL/SOP/help page: `link` with `url`
46
- - approval/status transition/close task: do not fake it with a normal button; use workflow/task action or exact existing automation config
47
- - Button placement choice: `header` is global and has no current-row context; `list` is row/list action; `detail` is the safest current-record context action. Do not use current-record `field_mappings` on `header`.
48
40
 
49
- Apply a business table view:
41
+ Apply a default table view:
50
42
 
51
43
  ```json
52
44
  {
@@ -57,10 +49,16 @@ Apply a business table view:
57
49
  "publish": true,
58
50
  "upsert_views": [
59
51
  {
60
- "name": "订单台账视图",
52
+ "name": "全部订单",
61
53
  "view_key": "VIEW_KEY_IF_DUPLICATE_NAMES_EXIST",
62
54
  "type": "table",
63
- "columns": ["订单编号", "客户名称", "订单金额", "状态"]
55
+ "columns": ["订单编号", "客户名称", "订单金额", "状态", "负责人", "创建时间"],
56
+ "query_conditions": {
57
+ "enabled": true,
58
+ "exact": false,
59
+ "hide_before_query": false,
60
+ "rows": [["订单编号", "客户名称"], ["状态", "负责人"], ["创建时间"]]
61
+ }
64
62
  }
65
63
  ],
66
64
  "remove_views": []
@@ -69,48 +67,6 @@ Apply a business table view:
69
67
  ```
70
68
  After `app_views_apply` returns canonical arguments or blocking issues, prefer reusing its `suggested_next_call.arguments` directly. Do not rewrite aliases back into non-canonical keys such as `column_names`.
71
69
 
72
- Create a table view with ordinary business buttons:
73
-
74
- ```json
75
- {
76
- "tool_name": "app_views_apply",
77
- "arguments": {
78
- "profile": "default",
79
- "app_key": "APP_123",
80
- "publish": true,
81
- "upsert_views": [
82
- {
83
- "name": "工单执行视图",
84
- "type": "table",
85
- "columns": ["工单编号", "产品", "状态", "负责人"],
86
- "action_buttons": [
87
- {
88
- "text": "创建质检单",
89
- "action": "add_data",
90
- "target_app_key": "QUALITY_APP",
91
- "field_mappings": [
92
- {"source_field": "数据ID", "target_field": "关联工单"}
93
- ],
94
- "default_values": {"处理状态": "待处理"},
95
- "placement": "detail",
96
- "visible_when": [
97
- {"field_name": "状态", "operator": "eq", "value": "已完工"}
98
- ]
99
- },
100
- {
101
- "text": "查看作业说明",
102
- "action": "link",
103
- "url": "https://example.com/sop",
104
- "placement": "header"
105
- }
106
- ]
107
- }
108
- ],
109
- "remove_views": []
110
- }
111
- }
112
- ```
113
-
114
70
  Existing table view: replace only frontend query conditions:
115
71
 
116
72
  ```json
@@ -321,32 +277,7 @@ At least one `query_conditions.rows` field does not exist on the app.
321
277
 
322
278
  ### `INVALID_QUERY_CONDITION_FIELD`
323
279
 
324
- The field exists but cannot be used in the frontend query-condition panel.
325
-
326
- Supported `query_conditions.rows` fields are query-panel fields:
327
-
328
- - text / long text
329
- - number / amount
330
- - date / datetime
331
- - single select / multi select
332
- - member / department
333
- - phone / email
334
- - boolean
335
-
336
- Do not use these fields in `query_conditions`:
337
-
338
- - relation
339
- - attachment
340
- - subtable or subtable subfield
341
- - address/location
342
- - Q-Linker
343
- - code block
344
-
345
- Fix path:
346
-
347
- - If you wanted a saved filter that opens with the view, use `filters`.
348
- - If you wanted a related report/view to match the current record, use `app_associated_resources_apply.match_mappings`.
349
- - If you only need frontend search fields, remove unsupported fields from `query_conditions.rows` and keep query-panel supported fields only.
280
+ The field exists but cannot be used in the frontend query-condition panel, such as attachment, relation, Q-Linker, code block, location/address, or subtable/subfield selections.
350
281
 
351
282
  ## Notes
352
283
 
@@ -355,6 +286,6 @@ Fix path:
355
286
  - `app_get_views` should be treated as canonical readback and now returns `columns`
356
287
  - If `app_views_apply` returns `AMBIGUOUS_VIEW`, stop and re-run `app_get_views`; then retry with the exact `view_key`
357
288
  - `filters` are ANDed together as one flat condition group
358
- - `query_conditions.rows` does not mean OR; it controls frontend query-field layout and should only contain query-panel supported fields
289
+ - `query_conditions.rows` does not mean OR; it controls frontend query-field layout
359
290
  - `app_views_apply` publishes by default
360
291
  - For select-style filters, success means the backend preserved the option value in readback, not just that the view name now exists
@@ -1,14 +1,12 @@
1
1
  ---
2
2
  name: qingflow-app-builder-code-integrations
3
- description: Configure Qingflow code block and Q-Linker fields through the builder surface when the task involves input field insertion, alias parsing, target field binding, or troubleshooting broken code/q-linker form configurations. In Wingent Momo runtime, use the injected MCP session and recover auth/workspace only after a tool error.
3
+ description: Configure Qingflow code block and Q-Linker fields through the builder surface when the task involves input field insertion, alias parsing, target field binding, or troubleshooting broken code/q-linker form configurations. Use after MCP is connected and authenticated, especially for CRM-style scoring, lookup, and enrichment forms.
4
4
  metadata:
5
5
  short-description: Configure Qingflow code blocks and Q-Linkers safely
6
6
  ---
7
7
 
8
8
  # Qingflow App Builder Code Integrations
9
9
 
10
- > **Skill 版本**:`qingflow-skills-2026.06.24.2`(入口文档版本;如需确认 CLI 包版本,使用 `qingflow --version` 或 `qingflow --json version`)。
11
-
12
10
  Use this skill when the user wants to build or repair:
13
11
  - `code_block` fields
14
12
  - `q_linker` fields
@@ -60,7 +58,7 @@ For code block or Q-Linker work, use this order:
60
58
 
61
59
  1. Resolve the app and read fields:
62
60
  - `app_resolve`
63
- - `app_get_fields`
61
+ - `app_read_fields`
64
62
  2. Confirm the target field set already exists.
65
63
  3. Apply schema updates with `app_schema_apply`.
66
64
  4. Read fields again and verify:
@@ -117,7 +115,7 @@ Hard rules:
117
115
 
118
116
  After each code block or Q-Linker change, verify all of these:
119
117
 
120
- - `app_get_fields` shows the intended field type
118
+ - `app_read_fields` shows the intended field type
121
119
  - the high-level config is readable and stable
122
120
  - target fields still have valid types
123
121
  - insert schema can be opened
@@ -59,7 +59,7 @@ Do not bind code block outputs to:
59
59
 
60
60
  ## Safe Verification
61
61
 
62
- - `app_get_fields`
62
+ - `app_read_fields`
63
63
  - `record_insert_schema_get`
64
64
  - optional `record_code_block_run`
65
65
 
@@ -70,7 +70,7 @@ Avoid:
70
70
 
71
71
  ## Safe Verification
72
72
 
73
- - `app_get_fields`
73
+ - `app_read_fields`
74
74
  - `record_insert_schema_get`
75
75
  - `record_insert`
76
76
 
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: qingflow-mcp-setup
3
+ description: Install, connect, authenticate, and troubleshoot the Qingflow MCP server in local AI clients such as Claude Desktop or any stdio-compatible MCP client. Use when the user wants to configure the MCP, verify local startup, log in with token/password, select a workspace, or fix connection/authentication issues.
4
+ metadata:
5
+ short-description: Install and connect the Qingflow MCP locally
6
+ ---
7
+
8
+ # Qingflow MCP Setup
9
+
10
+ ## Overview
11
+
12
+ This skill sets up the local Qingflow MCP server, connects it to a local AI client, and verifies authentication and workspace selection. Use it for installation, client configuration, token login, and connection troubleshooting.
13
+
14
+ ## Workflow
15
+
16
+ Follow these steps in order.
17
+
18
+ `feedback_submit` is also available as a cross-cutting helper when setup or MCP capability gaps still block the user after reasonable troubleshooting. It does not require Qingflow login or workspace selection, and should be called only after explicit user confirmation.
19
+
20
+ Before configuration or live calls, identify the target environment explicitly as `test` or `prod`, then read [references/environments.md](references/environments.md). If the user did not specify one, default to `prod`.
21
+
22
+ ### Step 1: Verify the local project path
23
+
24
+ Resolve the repository root first. In this repo, the MCP server should live at:
25
+
26
+ - `<repo_root>/qingflow-support/mcp-server`
27
+
28
+ Key entrypoint:
29
+
30
+ - `<repo_root>/qingflow-support/mcp-server/qingflow-mcp`
31
+
32
+ If the path differs, stop and update all client config snippets before proceeding.
33
+ If the skill is installed under `$CODEX_HOME/skills` instead of the repo-local `.codex/skills`, set `QINGFLOW_MCP_ROOT=<repo_root>/qingflow-support/mcp-server` before running `scripts/check_local_server.sh`.
34
+
35
+ ### Step 2: Install local dependencies
36
+
37
+ Run:
38
+
39
+ ```bash
40
+ cd <repo_root>/qingflow-support/mcp-server
41
+ python3 -m venv .venv
42
+ ./.venv/bin/pip install -e '.[dev]'
43
+ ```
44
+
45
+ Use `scripts/check_local_server.sh` to verify the entrypoint and virtualenv. The script will first try `QINGFLOW_MCP_ROOT`, then the current git repo, then a repo-local `.codex/skills` layout.
46
+
47
+ ### Step 3: Configure the local AI client
48
+
49
+ For any stdio-compatible MCP client, map these values:
50
+
51
+ - `command`: `<repo_root>/qingflow-support/mcp-server/qingflow-mcp`
52
+ - `args`: `[]`
53
+ - `env.QINGFLOW_MCP_DEFAULT_BASE_URL`: the target backend URL for the active environment
54
+ - `env.QINGFLOW_MCP_DEFAULT_QF_VERSION`: set this when the environment must route to a specific version such as `canary`
55
+
56
+ Client-specific snippets:
57
+
58
+ - Claude Desktop: read [references/claude-desktop.md](references/claude-desktop.md)
59
+ - Generic stdio MCP clients: read [references/generic-stdio.md](references/generic-stdio.md)
60
+
61
+ When both test and production are in play, keep separate config snippets or clearly labeled `env` blocks so the user can switch without ambiguity.
62
+
63
+ ### Step 4: Validate startup
64
+
65
+ The server is a stdio MCP process. A direct terminal launch may print nothing and wait for a client. That is normal.
66
+
67
+ Manual startup command:
68
+
69
+ ```bash
70
+ cd <repo_root>/qingflow-support/mcp-server
71
+ ./qingflow-mcp
72
+ ```
73
+
74
+ Prefer validating through the client after config is added.
75
+
76
+ ### Step 5: Authenticate and select workspace
77
+
78
+ Recommended order inside the client:
79
+
80
+ 1. `auth_use_token` or `auth_login`
81
+ 2. `workspace_list`
82
+ 3. `workspace_select`
83
+ 4. Only then use business tools
84
+
85
+ If the user already knows the target workspace, prefer `auth_use_token(..., ws_id=<id>)`.
86
+ After auth, prefer one read-only tool call that returns `request_route` so you can confirm the live `base_url` and `qf_version` before proceeding.
87
+ `auth_use_token` is a tool call, not a custom HTTP header. The runtime injects `token`, `wsId`, and when needed `Cookie: qfVersion=...` after the session is established.
88
+ Do not skip `workspace_select` on production paths. If `/user` does not return a version lane, the session now falls back to the workspace `systemVersion`.
89
+
90
+ ### Step 6: Troubleshoot in the right layer
91
+
92
+ - If the client cannot launch the server, check path, execute permission, and `.venv`
93
+ - If tools return `auth required`, re-run `auth_use_token` or `auth_login`
94
+ - If tools return `workspace not selected`, call `workspace_list` and `workspace_select`
95
+ - If calls fail after a working session, assume token expiry and re-authenticate
96
+ - If the browser shows data but MCP does not, compare `request_route` against the browser environment and check whether `qf_version` should be `canary`
97
+
98
+ ## Guardrails
99
+
100
+ - Never write tokens into the skill files
101
+ - Never assume a workspace is selected until `auth_whoami` or `workspace_select` confirms it
102
+ - When debugging, distinguish server startup issues from Qingflow auth issues
103
+ - When the user mentions production, restate the exact `base_url`, `qf_version`, and workspace before any live validation
104
+ - If setup is complete but the current MCP capability is still unsupported or the user's need still cannot be satisfied, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation
105
+
106
+ ## Resources
107
+
108
+ - Environment switching: [references/environments.md](references/environments.md)
109
+ - Claude Desktop config: [references/claude-desktop.md](references/claude-desktop.md)
110
+ - Generic stdio config: [references/generic-stdio.md](references/generic-stdio.md)
111
+ - Local checks: [scripts/check_local_server.sh](scripts/check_local_server.sh)
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Qingflow MCP Setup"
3
+ short_description: "Install and connect the Qingflow MCP locally"
4
+ default_prompt: "Use $qingflow-mcp-setup to install and connect the Qingflow MCP in a local AI client, and to verify the active base_url, qf_version, auth state, and workspace selection."
@@ -0,0 +1,34 @@
1
+ # Claude Desktop
2
+
3
+ Use this when the user wants to install Qingflow MCP in Claude Desktop.
4
+
5
+ ## Config snippet
6
+
7
+ ```json
8
+ {
9
+ "mcpServers": {
10
+ "qingflow": {
11
+ "command": "<ABSOLUTE_PATH_TO_REPO>/qingflow-support/mcp-server/qingflow-mcp",
12
+ "args": [],
13
+ "env": {
14
+ "QINGFLOW_MCP_DEFAULT_BASE_URL": "<QINGFLOW_BASE_URL>"
15
+ }
16
+ }
17
+ }
18
+ }
19
+ ```
20
+
21
+ ## Environment examples
22
+
23
+ - `prod` (default): set `QINGFLOW_MCP_DEFAULT_BASE_URL` to `https://qingflow.com/api`
24
+ - `test`: if needed, set `QINGFLOW_MCP_DEFAULT_BASE_URL` to the explicitly provided non-production backend
25
+
26
+ Keep separate snippets for `test` and `prod` so switching environments does not require editing values in-place under pressure.
27
+
28
+ ## Notes
29
+
30
+ - After updating the config, restart Claude Desktop
31
+ - Replace `<ABSOLUTE_PATH_TO_REPO>` with the real checkout path on the current machine
32
+ - If the server path changes, update the `command` field
33
+ - The server is local stdio MCP, so no remote URL is required
34
+ - Do not store Qingflow token in Claude Desktop config; pass it through `auth_use_token` inside the chat