@josephyan/qingflow-app-builder-mcp 1.1.30 → 1.1.33

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 (88) hide show
  1. package/README.md +6 -4
  2. package/docs/local-agent-install.md +57 -6
  3. package/entry_point.py +1 -1
  4. package/npm/bin/qingflow-app-builder-mcp.mjs +1 -1
  5. package/npm/bin/qingflow-skills.mjs +5 -0
  6. package/npm/lib/runtime.mjs +20 -59
  7. package/npm/scripts/postinstall.mjs +1 -10
  8. package/package.json +3 -2
  9. package/pyproject.toml +1 -1
  10. package/skills/qingflow-app-builder/SKILL.md +111 -55
  11. package/skills/qingflow-app-builder/references/complete-system-development-guide.md +169 -0
  12. package/skills/qingflow-app-builder/references/create-app.md +31 -24
  13. package/skills/qingflow-app-builder/references/environments.md +1 -1
  14. package/skills/qingflow-app-builder/references/gotchas.md +40 -14
  15. package/skills/qingflow-app-builder/references/match-rules.md +196 -85
  16. package/skills/qingflow-app-builder/references/public-surface-sync.md +2 -2
  17. package/skills/qingflow-app-builder/references/single-app-development-guide.md +84 -0
  18. package/skills/qingflow-app-builder/references/solution-playbooks.md +10 -0
  19. package/skills/qingflow-app-builder/references/tool-selection.md +40 -25
  20. package/skills/qingflow-app-builder/references/update-flow.md +27 -52
  21. package/skills/qingflow-app-builder/references/update-schema.md +14 -0
  22. package/skills/qingflow-app-builder/references/update-views.md +101 -32
  23. package/skills/qingflow-app-builder/scripts/validate_system_build_summary.py +124 -0
  24. package/skills/qingflow-app-builder-code-integrations/SKILL.md +5 -3
  25. package/skills/qingflow-app-builder-code-integrations/references/code-block.md +1 -1
  26. package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +1 -1
  27. package/skills/qingflow-mcp-setup/SKILL.md +13 -9
  28. package/skills/qingflow-mcp-setup/references/claude-desktop.md +1 -1
  29. package/skills/qingflow-mcp-setup/references/environments.md +2 -1
  30. package/skills/qingflow-mcp-setup/references/generic-stdio.md +6 -5
  31. package/skills/qingflow-workflow-builder/SKILL.md +9 -7
  32. package/skills/qingflow-workflow-builder/references/01-overview.md +4 -2
  33. package/skills/qingflow-workflow-builder/references/03-flow-patterns.md +2 -0
  34. package/skills/qingflow-workflow-builder/references/06-stage3-build-spec.md +59 -7
  35. package/skills/qingflow-workflow-builder/references/07-stage4-validate-spec.md +14 -5
  36. package/skills/qingflow-workflow-builder/references/08-stage5-apply-verify.md +19 -3
  37. package/skills/qingflow-workflow-builder/references/11-troubleshooting.md +2 -0
  38. package/src/qingflow_mcp/__main__.py +6 -2
  39. package/src/qingflow_mcp/builder_facade/models.py +473 -138
  40. package/src/qingflow_mcp/builder_facade/service.py +6356 -1866
  41. package/src/qingflow_mcp/cli/commands/builder.py +358 -355
  42. package/src/qingflow_mcp/cli/commands/chart.py +1 -1
  43. package/src/qingflow_mcp/cli/commands/common.py +12 -3
  44. package/src/qingflow_mcp/cli/commands/exports.py +2 -2
  45. package/src/qingflow_mcp/cli/commands/imports.py +3 -3
  46. package/src/qingflow_mcp/cli/commands/portal.py +2 -2
  47. package/src/qingflow_mcp/cli/commands/record.py +101 -27
  48. package/src/qingflow_mcp/cli/commands/task.py +28 -47
  49. package/src/qingflow_mcp/cli/commands/view.py +1 -1
  50. package/src/qingflow_mcp/cli/context.py +0 -3
  51. package/src/qingflow_mcp/cli/formatters.py +784 -16
  52. package/src/qingflow_mcp/cli/main.py +120 -41
  53. package/src/qingflow_mcp/errors.py +43 -2
  54. package/src/qingflow_mcp/public_surface.py +26 -17
  55. package/src/qingflow_mcp/response_trim.py +81 -17
  56. package/src/qingflow_mcp/server.py +14 -12
  57. package/src/qingflow_mcp/server_app_builder.py +83 -39
  58. package/src/qingflow_mcp/server_app_user.py +22 -16
  59. package/src/qingflow_mcp/session_store.py +11 -7
  60. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
  61. package/src/qingflow_mcp/solution/executor.py +114 -15
  62. package/src/qingflow_mcp/tools/ai_builder_tools.py +3571 -1473
  63. package/src/qingflow_mcp/tools/app_tools.py +184 -43
  64. package/src/qingflow_mcp/tools/approval_tools.py +197 -35
  65. package/src/qingflow_mcp/tools/auth_tools.py +92 -16
  66. package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
  67. package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
  68. package/src/qingflow_mcp/tools/directory_tools.py +236 -72
  69. package/src/qingflow_mcp/tools/export_tools.py +244 -34
  70. package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
  71. package/src/qingflow_mcp/tools/file_tools.py +9 -3
  72. package/src/qingflow_mcp/tools/import_tools.py +336 -49
  73. package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
  74. package/src/qingflow_mcp/tools/package_tools.py +118 -6
  75. package/src/qingflow_mcp/tools/portal_tools.py +39 -3
  76. package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
  77. package/src/qingflow_mcp/tools/record_tools.py +1141 -356
  78. package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
  79. package/src/qingflow_mcp/tools/role_tools.py +80 -9
  80. package/src/qingflow_mcp/tools/solution_tools.py +57 -15
  81. package/src/qingflow_mcp/tools/task_context_tools.py +687 -159
  82. package/src/qingflow_mcp/tools/task_tools.py +113 -29
  83. package/src/qingflow_mcp/tools/view_tools.py +106 -3
  84. package/src/qingflow_mcp/tools/workflow_tools.py +17 -1
  85. package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
  86. package/src/qingflow_mcp/version.py +0 -2
  87. package/skills/qingflow-app-builder/references/build-complete-system.md +0 -234
  88. package/skills/qingflow-app-builder/references/build-single-app.md +0 -138
@@ -1,22 +1,23 @@
1
1
  ---
2
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.
3
+ description: Build, configure, and modify Qingflow apps and systems using the current Wingent Momo runtime MCP session. 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
4
  metadata:
5
5
  short-description: Build and modify Qingflow apps and systems
6
6
  ---
7
7
 
8
8
  # Qingflow App Builder
9
9
 
10
- > **Skill 版本**:`qingflow-skills-2026.06.30.1`
10
+ > **Skill 版本**:`qingflow-skills-2026.06.30.10`(入口文档版本;CLI 实际执行包以 `qingflow --json version` 返回的 `package / version / package_root / skill_version` 为准)。
11
11
 
12
12
  ## Overview
13
13
 
14
14
  This skill is for the current **public builder surface**, not for legacy low-level builder writes.
15
- Assumes MCP is already connected, authenticated, and on the correct workspace.
15
+ In Wingent Momo runtime, trust the injected MCP session, credentials, workspace, and route context until a tool explicitly reports otherwise.
16
16
 
17
17
  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`.
18
18
 
19
19
  Before choosing a route, skim the shared maintenance baseline: [public-surface-sync.md](references/public-surface-sync.md).
20
+ Then pick the matching development guide: [single-app-development-guide.md](references/single-app-development-guide.md) for one app, or [complete-system-development-guide.md](references/complete-system-development-guide.md) for app packages/systems.
20
21
 
21
22
  ## Current Public Mental Model
22
23
 
@@ -34,13 +35,45 @@ Default modeling rules:
34
35
  - Another business object -> a separate app, not a text field
35
36
  - Cross-object links -> relation fields, not text fields
36
37
 
38
+ ## Route First
39
+
40
+ Before any builder write, classify the request:
41
+
42
+ - **Complete system / app package**: the user asks for a system, package, workspace module set, or several related forms/apps. Use `package_apply` for the package, then one `app_schema_apply(package_id=..., apps=[...])` for the app shells and fields. This is the main path for complete systems, not a bulk shortcut to abandon after the first slow response. Do not squeeze several business objects into one app.
43
+ - **Single app**: the user names one form/app or gives one `app_key`. Use `app_resolve`/`app_get`, then `app_schema_apply` and the app-scoped apply tools.
44
+ - **Record/user operation**: the user wants to add, edit, delete, approve, or analyze data. Route to the record/task skills instead of builder tools.
45
+
46
+ For complete systems, `apps[]` should use stable `client_key` values. Same-call relation fields should use `target_app_ref` for another `apps[].client_key`; use `target_app_key` only when the target app already exists or has been confirmed by readback. Create the related apps with one multi-app schema apply; do not create each app separately just to collect app keys and then patch relations afterward.
47
+
48
+ If a complete-system `app_schema_apply` times out, returns `partial_success`, returns `write_executed=true`, has `safe_to_retry=false`, or has incomplete readback, treat it as an uncertain write, not as a failed create. The next action is always `readback_before_retry`: read the package/app/fields first, compare intended `client_key`/`app_name`/relations against reality, and only then repair the missing slice. Do not retry the whole multi-app create, create `V2`/`测试`/random-suffix apps, or split the system into single-app rebuilds to bypass a duplicate/conflict.
49
+
50
+ Before any write, apply this decision gate:
51
+
52
+ | Evidence | Action |
53
+ | --- | --- |
54
+ | Exact `app_key`, `view_key`, `chart_id`, `dash_key`, or `package_id` is provided | Update that existing target unless the user explicitly asks for a new one |
55
+ | Several forms/modules or a “system/package” are requested | Use the complete-system path; do not compress them into one app |
56
+ | Same/similar package or app already exists and user did not say extend/replace/new | Stop and ask which target strategy to use |
57
+ | Readback already contains part of the requested build | Patch only verified missing or incorrect slices |
58
+ | Write state is uncertain | Read back before retrying; do not create duplicate names with suffixes |
59
+
60
+ Builder schema inputs should follow agent-intuitive semantics:
61
+
62
+ - choose field type by business intent first: title/short text -> `text`; notes/description -> `multiline`; status/type/stage -> `select` with `options`; labels/multiple choices -> `multi_select`; quantities/ratios/scores/durations -> `number`; money -> `amount`; cross-app link -> `relation`
63
+ - field types in drafts may use intuitive aliases: `multiline -> long_text`, `select -> single_select`, `multi_select -> multi_select`, `amount -> amount`, `phone -> phone`; readback returns canonical types and that is not a schema mismatch
64
+ - primary icon syntax is `icon + color`, for example `icon: "table", color: "blue"`; `icon_name/icon_color`, `icon_config`, and `icon: {name, color}` are compatibility aliases only
65
+ - select-style field `options` may be strings or objects such as `{label, value}`; tools normalize to option labels
66
+ - relation fields need a target plus object selectors: same-batch `target_app_ref`, existing app `target_app_key`, `display_field: {"name": "..."}`, and `visible_fields: [{"name": "..."}]`
67
+ - do not impose an artificial one-relation-field-per-app limit; create the relation fields the business model needs, then rely on backend validation and readback
68
+ - do not create built-in system fields as form fields: `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, `流程标题`. They are platform-generated; only reference supported system fields where a tool explicitly says so, such as button `source_field: "数据ID"`
69
+
37
70
  ## Public Tools You Should Think In
38
71
 
39
72
  - Package: `package_get`, `package_apply`
40
- - App reads: `app_resolve`, `app_get`, `app_get_fields`, `app_get_layout`, `app_get_views`, `app_get_flow`, `app_get_charts`, `app_get_associated_resources`
73
+ - App reads: `app_resolve`, `app_get`, `app_get_fields`, `app_get_layout`, `app_get_views`, `app_get_flow`, `app_get_charts`
41
74
  - Builder reads: `portal_list`, `portal_get`, `view_get`, `chart_get`, `builder_tool_contract`
42
75
  - Directory: `member_search`, `role_search`, `role_create`
43
- - Writes: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_associated_resources_apply`, `app_charts_apply`, `portal_apply`, `app_release_edit_lock_if_mine`
76
+ - Writes: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_custom_buttons_apply`, `app_associated_resources_apply`, `app_charts_apply`, `portal_apply`, `app_release_edit_lock_if_mine`
44
77
  - Verification: `app_publish_verify`
45
78
  - Cross-cutting escalation: `feedback_submit` after explicit user confirmation when the public builder surface still cannot satisfy the user's need
46
79
 
@@ -52,100 +85,126 @@ Treat these as the official surface. Do not default to `package_create`, `packag
52
85
  - use `package_get(package_id=...)` to read one known package
53
86
  - use `package_apply(...)` for package creation, rename, icon, visibility, grouping, ordering, and app/portal layout
54
87
  - Multi-app schema work:
55
- - use one `app_schema_apply(apps=[...])` / CLI `builder schema apply --apps-file` when creating several apps in one package
56
- - put form layout directly in `apps[].form.sections`; the CLI writes it in the same schema save as fields and relations
57
- - same-call relation fields may use `target_app_ref` to point at another `apps[].client_key`
88
+ - use one `app_schema_apply(package_id=..., apps=[...])` / CLI `builder schema apply --apps-file` when creating several apps in one package
89
+ - every `apps[]` item should carry its own `client_key`, `app_name`, `icon`, `color`, and `add_fields`
90
+ - same-call relation fields should use `target_app_ref` to point at another `apps[].client_key`; use `target_app` only when the app name is unique and stable, and use `target_app_key` only after the target app already exists or readback has confirmed it
91
+ - timeout / `partial_success` / `write_executed=true` / `safe_to_retry=false` means `readback_before_retry`; do not directly downgrade to single-app creation
58
92
  - App base permissions:
59
93
  - trust `app_get.editability.can_edit_app_base` for app base-info writes like app name, icon, and visibility
60
94
  - `can_edit_form` only means schema/form-route capability; it no longer implies app base-info write capability
61
95
  - Partial update rule:
62
- - for existing views, associated resources, and charts, prefer `patch_views` / `patch_resources` / `patch_charts`
63
- - each patch item uses the object's real selector field (`view_key` / `associated_item_id` / `chart_id`, or unique name where supported) plus `set` and optional `unset`; do not send a literal `selector` key for these tools
96
+ - for existing views, prefer `app_views_apply.views[]` with `operation="patch"`; for custom buttons, associated resources, and charts, prefer `patch_buttons` / `patch_resources` / `patch_charts`
97
+ - each patch item uses the object's real selector field (`view_key` / `button_id` / `associated_item_id` / `chart_id`, or unique name where supported) plus `set` and optional `unset`; do not send a literal `selector` key for these tools
64
98
  - use `upsert_*` for creation or full target configuration; do not send a partial `upsert_*` and expect the backend to merge missing required fields
65
99
  - Portal work:
66
100
  - `portal_apply` is the public write path
67
- - complete-system portals create QingBI charts inline through `sections[].chart`; do not pre-create charts as the standard route
68
101
  - in edit mode, omitting `sections` means “preserve existing layout and update base info only”
69
102
  - supplying `sections` means full replace semantics for sections
70
- - portal sections use a 24-column PC grid; all components sharing the same `y` coordinate must have identical `rows` values and their `cols` must sum to exactly 24; mixing `rows` in the same row causes height misalignment, and a `cols` sum under 24 leaves blank space at the row end; the next row's `y` must equal the previous row's `y` + `rows`
71
- - Standalone chart maintenance:
103
+ - `patch_sections[]` is the preferred path for changing one existing portal block
104
+ - do not confuse form layout with portal layout: form layout uses field-name `rows`; portal layout uses component `position.pc.x/y/cols/rows`
105
+ - portal PC layout uses a 24-column grid; components with the same `y` must share the same `rows`, and their `cols` should sum to 24 unless the user explicitly wants blank space
106
+ - standard workbench heights: metric cards `rows=5`, BI charts `rows=7`, data views `rows=11`
107
+ - business-entry grid sections must include real `config.items[]`; do not submit an empty grid container
108
+ - build portals only after referenced apps, raw `view_key`s, and chart ids/keys are known by readback
109
+ - standard order is business entry -> metric cards -> BI charts -> concrete data views
110
+ - do not use platform default views such as `全部数据` / `我的数据` as the main portal views
111
+ - do not use `source_type: "filter"` as the normal automation path; portal filter is raw/unstable and not part of the unified filter DSL
112
+ - Chart work:
72
113
  - `app_charts_apply` is the public write path for app-source QingBI report bodies/configs; it creates/updates reports with `dataSourceType=qingflow`
73
- - do not use it as the standard complete-system route; complete-system portals should inline QingBI charts through `portal_apply sections[].chart`
74
114
  - dataset BI reports are not created or edited by `app_charts_apply` yet; create them in QingBI first, then attach the existing report with `app_associated_resources_apply` and `report_source="dataset"`
75
115
  - it does not attach the report to the Qingflow app associated-resource display; use `app_associated_resources_apply` for that
116
+ - use `app_get_fields.chart_fields` as the source for dimensions, metrics, and filters; normal record/form fields are not enough
117
+ - choose chart type by goal: `target/indicator` for one KPI, `bar/columnar/pie` for distribution, `line/area` for trend, `table/detail/summary` for tabular summaries, `dualaxes` for two-metric comparison
118
+ - use semantic metrics: `count(*)`, `sum(金额)`, `avg(工时)`, `group_by`, `where`; do not handwrite raw `indicator_field_ids`, `selectedMetrics`, or QingBI filter matrices on the main path
119
+ - do not use `summary` for a single metric card; use `target` / `indicator`
76
120
  - supported `chart_type` values include legacy public aliases `target`, `table` and QingBI types such as `summary`, `columnar`, `area`, `stacked_area`, `funnel`, `waterfall`, `gauge`, `heatmap`, `histogram`, `treemap`, `radar`, `stacked_bar`, `stacked_column`, `scatter`, `ring`, `rose`, `dualaxes`, `map`, and `timeline`
121
+ - chart `filters` use the unified fixed-filter DSL: `field_name + operator + value/values`; the tool compiles them to QingBI string judge types
122
+ - for complete systems, keep chart payloads business-scoped, commonly 4-8 `upsert_charts` by app or topic. Larger calls are accepted; if `CHART_UPSERT_BATCH_SIZE_RECOMMENDED` appears, read back before retrying and only repair failed items.
77
123
  - use `patch_charts` for changing a chart name, visibility, filters, or one config fragment on an existing chart
78
124
  - `visibility` is a public capability and should be treated as a base-only permission update
79
125
  - do not model chart visibility changes as raw config rewrites
80
126
  - View action work:
81
- - declare button configuration only inside `app_views_apply` view items with `action_buttons`
82
- - design the view and its available actions together
83
- - use `field_mappings` for dynamic current-record values, including system fields such as `数据ID` and `编号`
127
+ - for view-specific business buttons, use `app_views_apply.views[].action_buttons`; for existing views use `operation="patch"` with `set.action_buttons`
128
+ - choose by user intent first: current record -> downstream record uses `add_data`; global independent entry uses `header`; URL/SOP/help uses `link`; approval/status transition/close task is workflow/task/automation, not a fake button
129
+ - use `field_mappings` for dynamic current-record values, including system fields such as `数据ID` (`field_id=-17`) and `编号` (`field_id=0`)
130
+ - to prefill a target relation field with the current source record, map `{"source_field": "数据ID", "target_field": "目标引用字段"}`; use `default_values` only for static constants
131
+ - placement choice: `header` is global and has no current-row context; `list` is row/list action and maps to backend `INSIDE`; `detail` is the safest current-record context action. Do not use current-record `field_mappings` on `header`
84
132
  - if field type compatibility is unclear, read [references/match-rules.md](references/match-rules.md)
133
+ - `app_custom_buttons_apply` is not a main build path; use it only after an explicit maintenance request for existing standalone buttons, cross-view binding, deletion, or exact advanced automation config
85
134
  - Associated resources:
86
135
  - `app_associated_resources_apply` is the public write path for the Qingflow app-level associated report/view pool and per-view display config
87
- - for multi-app systems, use `apps[]` to batch associated-resource writes; each item carries its own `app_key` plus `upsert_resources` / `patch_resources` / `view_configs`
88
136
  - it attaches existing BI reports/views for in-app display; it does not create or edit QingBI report bodies/configs, including dataset reports
89
137
  - use `patch_resources` for changing match rules or other existing associated-resource parameters; the tool preserves backend-required raw fields internally
90
138
  - `associated_item_id` is the backend internal associated-resource id; for `view_configs`, `remove_associated_item_ids`, and `reorder_associated_item_ids`, you may pass `associated_item_id` or an existing resource's `chart_id`/`chart_key`/`view_key`, and the tool resolves it to the internal id
91
139
  - before creating a resource, check `app_get.associated_resources` for the same `target_app_key + view_key/chart_key`; if it already exists, use `patch_resources` with that `associated_item_id`
92
140
  - `client_key` is only a same-call reference for `view_configs[].associated_item_refs`; it is not saved and cannot deduplicate later calls
93
141
  - do not pass backend raw `sourceType`; view resources infer the internal Qingflow view source, report/chart resources default to BI app reports, and existing dataset reports use `report_source="dataset"`
94
- - use `match_mappings` for associated view/report filters; dynamic conditions use `source_field`, static conditions use `value`
142
+ - use `match_mappings` for associated view/report filters; dynamic context matches use `source_field`, static filters use `value`; do not handwrite raw `matchRules`
95
143
  - if field type compatibility is unclear, read [references/match-rules.md](references/match-rules.md)
96
144
  - Views and flows:
97
145
  - stay on `app_views_apply` / `app_flow_apply`
98
- - new views use top-level `views[]`; the same batch may mix same-app and cross-app views
99
- - buttons belong in view `action_buttons`
100
- - use `patch_views` for existing-view parameter changes such as `query_conditions`, `filters`, `columns`, or visibility
146
+ - before building approval/fill/copy flows, make sure the app schema has an explicit business status `select` field such as `状态` / `处理状态` / `审批状态`; do not create platform workflow system fields such as `当前流程状态`
147
+ - use `views[]` with `operation="patch"` for existing-view parameter changes such as `query_conditions`, `filters`, `columns`, or visibility
101
148
  - builder view writes use raw `view_key` values from `app_get.views`; `custom:<viewKey>` is a record-data `view_id` form, not a builder `view_key`
149
+ - do not create platform default/system views named `全部数据`, `我的数据`, `我发起的`, `待办`, `已办`, or `抄送`; they are built in. New views must use business-specific names. To change a built-in view, patch by its existing raw `view_key`
102
150
  - use `builder_tool_contract` whenever the minimal legal shape is unclear
103
- - keep view `filters` and `query_conditions` separate: `filters` are fixed saved filters; `query_conditions` configure the frontend query panel fields and only take effect after users enter query values
104
- - when creating any new table or card view, always include `query_conditions` with `enabled: true`; populate `rows` with the fields most useful for searching — 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
151
+ - keep view `filters` and `query_conditions` separate: `filters` use `field_name + operator + value/values` and are fixed saved filters; `query_conditions` configure the frontend query panel fields and only take effect after users enter query values
152
+ - choose condition/matching surface by intent: fixed saved filters -> `filters`; frontend query panel -> `query_conditions.rows`; current-record associated report/view filtering -> `match_mappings`; current-record add-data prefill -> `field_mappings`; button visibility -> `visible_when` / `button_limit`
153
+ - keep relation/attachment/subtable/address/Q-Linker/code-block fields out of `query_conditions`; member/department fields may be used as query-panel fields when readback supports them. Use `filters` for fixed filters or associated-resource `match_mappings` for current-record related report/view matching
105
154
  - new views default the associated report/view display area to visible with `limit_type="all"`; existing views preserve their current associated-resource display unless `associated_resources` is explicitly patched
106
155
  - configure associated reports/views through `app_associated_resources_apply`, not through `app_views_apply`
107
156
 
108
157
  ## Standard Operating Order
109
158
 
110
- 1. Ensure auth exists
111
- 2. Ensure workspace is selected
112
- 3. Confirm whether the task is read-only or write-impacting
159
+ 1. Trust the current MCP/session when it is already injected by the runtime; only run auth/workspace recovery after a tool explicitly reports an auth, credential, or workspace error
160
+ 2. Confirm whether the task is read-only or write-impacting
161
+ 3. Classify the build scope:
162
+ - complete system/package -> `package_apply` or `package_get`, then one `app_schema_apply(package_id=..., apps=[...])`
163
+ - single app -> `app_resolve` / `app_get`, then app-scoped apply tools
164
+ - record/task/data request -> leave builder and use the matching record/task skill
113
165
  4. Resolve the smallest stable target:
114
166
  - app-scoped work -> `app_resolve`
115
167
  - package-scoped work with known id -> `package_get`
116
168
  - portal inventory -> `portal_list`
117
169
  5. Read only the smallest config slice needed:
118
- - app map -> `app_get` (default entry; includes compact views, charts, and associated resource pool)
170
+ - app map -> `app_get` (default entry; includes compact views, charts, custom buttons, and associated resource pool)
119
171
  - fields -> `app_get_fields`
120
172
  - layout -> `app_get_layout`
121
173
  - views -> `app_get_views` only when the app_get compact list is not enough
122
- - flow -> `app_get_flow`
174
+ - flow -> `app_get_flow` only when the task involves approval, fill/copy, reminders, process routing, task handling, or flow repair
123
175
  - charts -> `app_get_charts` only when the app_get compact list is not enough
124
176
  - portal -> `portal_get`
125
177
  6. If the public shape is unclear, call `builder_tool_contract`
126
178
  7. Apply the smallest patch tool that fits:
127
- - fields and form layout -> `app_schema_apply`
128
- - layout-only maintenance -> `app_layout_apply`
129
- - flow -> `app_flow_apply`
130
- - existing views -> `app_views_apply.patch_views`; new/full views -> `app_views_apply.upsert_views`
179
+ - fields -> `app_schema_apply`
180
+ - layout -> `app_layout_apply`
181
+ - flow -> `app_flow_apply` only when workflow is requested or clearly required
182
+ - views -> `app_views_apply(views=[...])`; use `operation="upsert"` for new/full views and `operation="patch"` for existing-view parameter changes
183
+ - view-specific business buttons -> put `action_buttons` on the same `views[]` item; use `set.action_buttons` for patch
184
+ - standalone button maintenance explicitly requested by the user -> `app_custom_buttons_apply`
131
185
  - existing associated resources -> `app_associated_resources_apply.patch_resources`; new/full resources -> `app_associated_resources_apply.upsert_resources`
132
186
  - existing charts -> `app_charts_apply.patch_charts`; new/full charts -> `app_charts_apply.upsert_charts`
133
187
  - portal -> `portal_apply`
134
188
  - package metadata/layout -> `package_apply`
135
189
  8. Use `app_publish_verify` only when the user explicitly wants final publish/live verification or you need a dedicated verification pass
190
+ 9. For complete-system builds, write `tmp/qingflow_system_build_summary.json` before the final response and make the final report match that file
136
191
 
137
192
  ## Safe Usage Rules
138
193
 
139
194
  - Do not guess package identity from a loose name. Public package work assumes a known `package_id`, or an explicit create/update intent through `package_apply`.
195
+ - Do not perform routine auth probes before every builder action in runtime contexts with injected MCP credentials; recover auth only after an actual auth/workspace failure.
140
196
  - If `package_id` is unknown, derive it from related app/portal readback when possible; otherwise ask the user instead of falling back to hidden package lookup tools.
197
+ - Do not bypass package/app-name conflicts by inventing `V2`, `测试`, timestamp, or random suffix apps in a real business package. Read back and decide whether to update the existing app, create only a truly missing app, or ask the user.
198
+ - After any uncertain schema write, do `readback_before_retry` with `package_get` / `app_resolve` / `app_get_fields`; retry only the verified missing or failed slice.
141
199
  - Do not use `package_create` or `package_attach_app` as a public default path. If they still appear in low-level code, treat them as internal/legacy implementation details.
142
200
  - Do not use raw `portal_*` writes or raw `qingbi_report_*` writes as the default builder strategy.
143
- - Always pass `publish: true` (or CLI `--publish`) explicitly on `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, and `portal_apply` when those tools are used directly. `app_associated_resources_apply` publishes automatically after at least one write succeeds and does not accept a `publish` parameter. `app_charts_apply` is immediate-live without a publish step.
201
+ - `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default; `app_custom_buttons_apply` and `app_associated_resources_apply` publish after at least one write succeeds and do not accept a draft-only `publish` parameter; `app_charts_apply` is immediate-live without publish.
144
202
  - When creating or updating fields, configure the app data title/cover directly in field JSON: `as_data_title: true` is required on exactly one readable top-level title field; `as_data_cover: true` is optional and only valid on one top-level `attachment` field.
145
- - When any tool returns `error_code` or `VALIDATION_ERROR`, read the `message` field verbatim first before guessing at parameter or CLI parsing issues. A clear `message` like "relation field requires visible_fields" is the root cause do not redirect to unrelated hypotheses such as `create_if_missing` parsing or flag conflicts.
203
+ - Do not add platform system fields to `add_fields`; if the user asks for record id, number, applicant, creation/update time, or workflow status, use the built-in data/list/readback fields instead of creating duplicate controls.
146
204
  - If the same validation error repeats twice, stop guessing and re-read `builder_tool_contract`.
205
+ - Do not create workflows just to make a build look complete. If no approval/fill/copy/reminder/process-routing requirement exists, report workflow as not requested/not configured.
147
206
  - For workflow assignees, prefer `role_search` over explicit members unless the user explicitly wants named members.
148
- - Public flow building is still intentionally limited to stable linear workflows. If a requirement sounds like branches/conditions, explain the limitation instead of freehanding unsupported graph shapes.
207
+ - Workflow work should prefer `app_flow_get_schema` / `app_get_flow` readback plus `app_flow_apply(spec=...)` for full WorkflowSpec writes, or `patch_nodes` for targeted existing-node edits. Legacy `nodes/transitions` is only for simple linear flows.
149
208
  - Respect collaborative edit locks. Only use `app_release_edit_lock_if_mine` when the lock owner is the current authenticated user.
150
209
  - If the supported builder surface is still awkward or blocked after reasonable use, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation.
151
210
 
@@ -156,10 +215,18 @@ Treat these as the official surface. Do not default to `package_create`, `packag
156
215
  - For UI cards or quick narration, read `resources[]` first. Each resource has `resource_type`, `operation`, `status`, `id`, `key`, `name`, typed `ids`, and `parent`.
157
216
  - Use legacy fields such as `field_diff`, `views_diff`, `chart_results`, `created/updated/removed`, and `verification` only for compatibility and troubleshooting.
158
217
  - Treat post-write readback as the source of truth, not just write status codes.
159
- - `success` means write and verification completed; `partial_success` means the write landed but verification is incomplete.
218
+ - `success` means write and verification completed; `partial_success` means the write landed or may have landed but verification is incomplete. If `write_executed=true`, `safe_to_retry=false`, or readback is unavailable, do `readback_before_retry` before any create retry.
219
+ - Final status rule:
220
+ - write result answers whether the write was attempted
221
+ - readback answers what actually exists
222
+ - publish/portal verification answers whether it is front-end visible
223
+ - validation/contract error with `write_executed=false` is a real failure and can be fixed/retried
224
+ - `partial_success`, timeout, post-write 40002/404, or readback unavailable is not enough to call the write failed; read back first and patch only proven gaps
160
225
  - For portals, distinguish clearly between:
161
226
  - base-info-only update with layout preserved
162
227
  - full sections replace
228
+ - patching one section with `patch_sections[]`
229
+ - layout validity: same-row `rows`, same-row `cols` sum, and non-empty grid `items`
163
230
  - For object apply tools, distinguish clearly between:
164
231
  - `patch_*`: public partial parameter replacement; the tool hydrates current config and full-saves internally
165
232
  - `upsert_*`: create or full target configuration; omitted fields may mean default/clear depending on that object
@@ -183,30 +250,19 @@ Treat these as the official surface. Do not default to `package_create`, `packag
183
250
  - Search members or roles: `member_search`, `role_search`
184
251
  - Create reusable role: `role_create`
185
252
  - Add/update/remove fields: `app_schema_apply`
186
- - Merge or replace layout-only changes on an existing app: `app_layout_apply`
253
+ - Merge or replace layout: `app_layout_apply`
187
254
  - Replace workflow: `app_flow_apply`
188
- - Upsert/patch/remove views: `app_views_apply`
255
+ - Upsert/patch/remove views, including view-specific `action_buttons`: `app_views_apply(views=[...])`
256
+ - Advanced standalone button maintenance only when explicitly requested: `app_custom_buttons_apply`
189
257
  - Upsert/patch/remove app associated reports/views and per-view display: `app_associated_resources_apply`
190
258
  - Upsert/patch/remove/reorder charts: `app_charts_apply`
191
259
  - Create or update portal pages: `portal_apply`
192
260
  - Release your own stale edit lock: `app_release_edit_lock_if_mine`
193
261
  - Final publish verification: `app_publish_verify`
194
262
 
195
- ## Playbook Selection
196
-
197
- Before starting any build or create task, route to the right reference first:
198
-
199
- | User intent | Signal phrases | Playbook |
200
- |-------------|---------------|---------|
201
- | Multi-app business system with cross-app relations and a portal workbench | "建一套系统"、"包含 N 个模块"、"这几个表单之间建立关联"、"完整的业务系统" | [build-complete-system.md](references/build-complete-system.md) |
202
- | Single app end-to-end: schema, form layout, views, view actions, optional workflow, and verification | "建一个应用"、"帮我搭一个XX管理"、"从零开始建一个XX"、"我需要一个管理XX的应用" | [build-single-app.md](references/build-single-app.md) |
203
- | Add one new app inside an existing package | "在这个包里加一个表单"、"现有系统里新增一个模块" | [create-app.md](references/create-app.md) |
204
- | Update fields or schema only | "加一个字段"、"改字段名"、"删除字段" | [update-schema.md](references/update-schema.md) |
205
- | Update layout only | "调整分组"、"改排列顺序" | [update-layout.md](references/update-layout.md) |
206
- | Update workflow only | "修改审批流"、"加一个审批节点" | [update-flow.md](references/update-flow.md) |
207
- | Update views only | "加一个看板"、"改筛选条件"、"新增视图" | [update-views.md](references/update-views.md) |
263
+ ## Standalone Button Boundary
208
264
 
209
- Decision rule: if the user mentions **multiple related apps or a portal**, use `build-complete-system.md`. If it is **one app** with a from-scratch setup request, use `build-single-app.md`. If the target app already exists and the user only wants to change one layer, use the matching single-layer playbook.
265
+ For ordinary business builds, do not start from `app_custom_buttons_apply`. Put buttons in the view with `action_buttons`; see [references/update-views.md](references/update-views.md).
210
266
 
211
267
  ## Resources
212
268
 
@@ -215,6 +271,8 @@ Decision rule: if the user mentions **multiple related apps or a portal**, use `
215
271
  - Tool choice and sequencing: [references/tool-selection.md](references/tool-selection.md)
216
272
  - Field matching rules: [references/match-rules.md](references/match-rules.md)
217
273
  - Result semantics and gotchas: [references/gotchas.md](references/gotchas.md)
274
+ - Single app development guide: [references/single-app-development-guide.md](references/single-app-development-guide.md)
275
+ - Complete system development guide: [references/complete-system-development-guide.md](references/complete-system-development-guide.md)
218
276
  - Create one app in an existing package: [references/create-app.md](references/create-app.md)
219
277
  - Update fields only: [references/update-schema.md](references/update-schema.md)
220
278
  - Update layout only: [references/update-layout.md](references/update-layout.md)
@@ -222,5 +280,3 @@ Decision rule: if the user mentions **multiple related apps or a portal**, use `
222
280
  - Workflow assignees and node permissions: [references/flow-actors-and-permissions.md](references/flow-actors-and-permissions.md)
223
281
  - Update views only: [references/update-views.md](references/update-views.md)
224
282
  - Standard end-to-end builder sequences: [references/solution-playbooks.md](references/solution-playbooks.md)
225
- - Build a complete multi-app system from scratch: [references/build-complete-system.md](references/build-complete-system.md)
226
- - Build a single app end-to-end (schema + form layout + views + view actions + optional workflow + verification): [references/build-single-app.md](references/build-single-app.md)
@@ -0,0 +1,169 @@
1
+ # Complete System Development Guide
2
+
3
+ Use this when the user asks for a system, app package, workspace module set, or several related apps/forms.
4
+ Do not compress several business objects into one app.
5
+
6
+ ## Recommended Completeness
7
+
8
+ Required:
9
+
10
+ - package exists or is created through `package_apply`
11
+ - core business objects are modeled as separate apps
12
+ - all new apps are created in one multi-app `app_schema_apply(package_id=..., apps=[...])`
13
+ - every app has stable `client_key`, `app_name`, `icon`, `color`, and one readable `as_data_title: true`
14
+ - no app creates platform system fields such as `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`
15
+ - same-call relations use `target_app_ref` to point to another `apps[].client_key`
16
+ - basic operating views exist for each core app
17
+ - package/apps/fields/relations are read back before repair or retry
18
+
19
+ Strongly recommended:
20
+
21
+ - cross-app relation fields for the main business links
22
+ - core operating views declare needed business actions directly in `app_views_apply.views[].action_buttons`
23
+ - portal chart sections declare needed QingBI charts inline through `sections[].chart`
24
+ - a standard portal: business entry area, core metrics, BI charts, then concrete data views
25
+ - portal grid/business-entry sections contain real `config.items[]`, not empty containers
26
+
27
+ Workflow preflight:
28
+
29
+ - If an app will have approval/fill/copy workflow nodes, create an explicit business status `select` field in schema first, such as `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`.
30
+ - Do not create platform workflow system fields such as `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`.
31
+ - If `app_flow_apply` returns `FLOW_DEPENDENCY_MISSING`, fix schema with the returned `suggested_next_call`, read fields back, then retry the flow. Do not skip the workflow silently.
32
+
33
+ Optional:
34
+
35
+ - workflow, reminders, buttons, associated resources, sample data, roles, and permissions when the user asks for them or the business process clearly depends on them
36
+
37
+ ## Standard Path
38
+
39
+ 1. Resolve or create package: `package_get` / `package_apply`.
40
+ 2. Draft all apps and relations with stable `client_key` values.
41
+ 3. Run one multi-app `app_schema_apply` with `apps[]`.
42
+ 4. If write result is uncertain, run readback before retrying.
43
+ 5. Treat field layout as part of `apps[].form`; only use layout maintenance later when repairing an existing app.
44
+ 6. Apply workflow with the new complete chain when the user asks for approval, fill, copy, reminders, or process routing: read flow schema/current flow, build a WorkflowSpec for full flow writes or `patch_nodes` for targeted edits, call `app_flow_apply`, then read back flow. Do not use legacy `nodes/transitions` except for deliberately simple linear compatibility.
45
+ 7. Apply views; put view-specific business actions in `action_buttons` while designing the core operating views.
46
+ 8. Create the portal after referenced apps and views are known; create or reuse QingBI charts inline in portal sections with `chart`.
47
+ 9. Before the final response, write the complete-system delivery summary file described below.
48
+
49
+ ## Field Modeling Rules
50
+
51
+ - Use agent-friendly field types in drafts: `text`, `multiline`, `select`, `multi_select`, `number`, `amount`, `date`, `datetime`, `member`, `department`, `attachment`, `relation`. The tool normalizes aliases such as `multiline -> long_text` and `select -> single_select`.
52
+ - Readback may show canonical field types such as `long_text` or `single_select`; do not rewrite fields just because aliases were normalized.
53
+ - Create only business fields. Do not create platform system fields listed in Required; reference them only where a tool explicitly supports system fields, such as button `source_field: "数据ID"`.
54
+ - Use `number` for ratios, completion rates, scores, percentages, durations, and quantities that may need decimals. Use `amount` only for currency/money semantics. This prevents sample data from producing decimal values for a field that the backend treats as integer money.
55
+ - For select fields, define the option set during schema design. Later sample data must use only those option labels or ids.
56
+ - Relation fields must include `target_app_ref` for same-batch apps or `target_app_key` for existing apps, plus `display_field: {"name": "..."}` and `visible_fields: [{"name": "..."}]`; do not write bare strings for display/visible field selectors.
57
+ - Do not impose a one-relation-field-per-app limit. Model the real business links and let backend validation/readback decide whether a specific relation is unsupported.
58
+
59
+ ## View Query Rules
60
+
61
+ - Use `filters` for fixed saved filters that apply when the view opens.
62
+ - Use `query_conditions` only for the frontend query panel layout. It is not another filter DSL and it does not express OR.
63
+ - `query_conditions.rows` should contain query-panel fields such as text, long text, number, amount, date/datetime, select, member, department, phone, email, or boolean.
64
+ - Do not put relation, attachment, subtable/subfield, address, Q-Linker, or code-block fields in `query_conditions`.
65
+ - For current-record related views/reports, use `app_associated_resources_apply.match_mappings`, not `query_conditions`.
66
+
67
+ ## Portal Chart Rules
68
+
69
+ - For complete systems, do not make chart creation a separate main step. When the portal needs metrics or BI blocks, declare them in `portal_apply.sections[].chart`.
70
+ - Read `app_get_fields.chart_fields` before writing portal chart sections; normal form fields are not enough for QingBI dimensions, metrics, or filters.
71
+ - Use semantic chart input first: `metric`, `metrics`, `group_by`, and `where`.
72
+ - One KPI card uses `target` / `indicator` with `metric: "count(*)"` or `metric: "sum(金额)"`.
73
+ - Grouped distribution uses `bar` / `columnar` / `pie` with `group_by + metric`.
74
+ - Trend uses `line` / `area` / `columnar` with a date/month `group_by`.
75
+ - Two-metric comparison uses `dualaxes` with `left_metric` and `right_metric`.
76
+ - Do not use `summary` for a single KPI; `summary` is for table-style grouped summaries.
77
+ - Do not handwrite raw `indicator_field_ids`, `selectedMetrics`, or QingBI filter matrices on the main path.
78
+ - Keep portal chart definitions business-scoped, commonly 4-8 charts by app or topic. Larger calls are accepted but should be read back before retrying.
79
+
80
+ ## View Action Rules
81
+
82
+ - Design business buttons only with the view: `app_views_apply.views[].action_buttons`; for existing views use `operation="patch"` with `set.action_buttons`.
83
+ - Use `add_data` when a current record creates a downstream/child record, such as order -> acceptance, work order -> inspection, or customer -> follow-up. Configure `target_app_key + field_mappings`; map `source_field: "数据ID"` to the target relation/reference field when linking back to the source record.
84
+ - Use `link` only for SOP, help, external system, or fixed URL navigation. Do not use `link` to fake approval, status transition, or data writeback.
85
+ - Prefer `detail` for current-record add-data actions, `list` for row actions, and `header` for global actions with no current-row context. Do not use current-record `field_mappings` on `header`.
86
+ - Approval, rejection, close-task, and status transition should be modeled as workflow/task behavior or existing automation; they are not generic custom-button types.
87
+ - Do not claim a complete operational system if all core operating views have no buttons and no reason is given.
88
+
89
+ ## Delivery Summary File
90
+
91
+ For complete-system builds, create or update one local JSON file before the final response:
92
+
93
+ `tmp/qingflow_system_build_summary.json`
94
+
95
+ Use this file as the structured source of truth for the final report. Include at least:
96
+
97
+ ```json
98
+ {
99
+ "package_id": 0,
100
+ "package_name": "",
101
+ "portal_dash_key": "",
102
+ "portal_live_status": "verified | unverified | not_created",
103
+ "front_end_visible": true,
104
+ "apps": [
105
+ {
106
+ "app_key": "",
107
+ "app_name": "",
108
+ "fields_count": 0,
109
+ "views_count": 0,
110
+ "flows_count": 0,
111
+ "charts_count": 0,
112
+ "publish_verify_status": "verified | unverified | failed"
113
+ }
114
+ ],
115
+ "warnings": [],
116
+ "partial_items": [],
117
+ "needs_followup": []
118
+ }
119
+ ```
120
+
121
+ Rules:
122
+
123
+ - Populate IDs and counts from readback, not from intended payload only.
124
+ - If a required resource is not verified, put it in `partial_items` or `needs_followup` instead of reporting the system as fully complete.
125
+ - If the user later adds a data-entry task, keep that separate from the system-build summary unless the user explicitly wants one combined report.
126
+ - The final response should match this file: completed resources, unverified items, frontend visibility, and follow-up needs must not contradict the JSON.
127
+ - `front_end_visible=true` only when the relevant portal/app publish or live readback proves it. Backend write success alone is not enough.
128
+ - Do not mark workflow as missing when the user did not ask for approval, fill, copy, reminders, or process routing. Report it as "not requested/not configured".
129
+ - If `partial_items` or `needs_followup` is non-empty, the final status is partial, not complete.
130
+ - When running from the CLI repo or a test harness, validate the file with:
131
+ `python scripts/validate_system_build_summary.py tmp/qingflow_system_build_summary.json`.
132
+
133
+ Final response shape:
134
+
135
+ ```text
136
+ 已完成:...
137
+ 未验证/待确认:...
138
+ 前端可见:是/否/未确认
139
+ 需要继续修复:是/否;原因...
140
+ ```
141
+
142
+ ## Recovery Rules
143
+
144
+ - Timeout, `partial_success`, `write_executed=true`, `safe_to_retry=false`, or incomplete readback means `write_may_have_succeeded`.
145
+ - Next action is always `readback_before_retry`: read package, resolve intended apps, then read fields/relations.
146
+ - Retry only verified missing apps, fields, or relations.
147
+ - Do not rebuild the system as separate single-app creates.
148
+ - Do not create `V2`, `测试`, timestamp, or random-suffix apps to bypass duplicate names.
149
+
150
+ ## Portal Template
151
+
152
+ - Top area: one business entry grid plus one todo/common/frequent component when useful.
153
+ - Metrics: one row of 4-6 indicator/target cards with portal section `role: "metric"`; recommended height 5.
154
+ - BI charts: one row of 2-3 charts, 1-2 rows; recommended height 7.
155
+ - Data views: one row of 1-2 concrete views, 1-2 rows; recommended height 11.
156
+ - PC layout uses 24 columns. Components in the same row share the same `y`, must have the same `rows`, and their `cols` should sum to 24.
157
+ - Business-entry grid components must include real `config.items[]` entries linking to apps or portals; never submit an empty grid container.
158
+ - Build the portal only after referenced apps, raw `view_key`s, and chart ids/keys have been read back.
159
+ - Standard section order is business entry -> metric cards -> BI charts -> concrete business views.
160
+ - Do not reference platform default views such as `全部数据` / `我的数据` as main portal data views.
161
+ - Do not use portal `source_type: "filter"` as the normal automation path; it is raw/unstable and not part of the unified filter DSL.
162
+
163
+ ## Stop Conditions
164
+
165
+ - If the user only asked for one app, switch to the single-app guide.
166
+ - If a same/similar package or app set already exists and the user did not say whether to extend, repair, replace, or create new, stop and ask. Do not start probing with new names.
167
+ - If readback shows part of the requested system already exists, list existing apps/fields/views/charts/portal, identify gaps, and patch only the missing or incorrect slices.
168
+ - If required package/app/field/relation readback contradicts the intended model, repair the specific missing slice before building dependent resources.
169
+ - If a public tool cannot express a needed business feature, state the gap and ask before using any fallback or submitting feedback.