@qingflow-tech/qingflow-app-user-mcp 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/qingflow_mcp/builder_facade/models.py +41 -2
- package/src/qingflow_mcp/builder_facade/service.py +1261 -141
- package/src/qingflow_mcp/cli/commands/app.py +3 -16
- package/src/qingflow_mcp/cli/commands/builder.py +28 -2
- package/src/qingflow_mcp/cli/commands/record.py +16 -1
- package/src/qingflow_mcp/cli/formatters.py +32 -1
- package/src/qingflow_mcp/public_surface.py +3 -1
- package/src/qingflow_mcp/response_trim.py +55 -3
- package/src/qingflow_mcp/server.py +10 -9
- package/src/qingflow_mcp/server_app_builder.py +26 -5
- package/src/qingflow_mcp/server_app_user.py +12 -15
- package/src/qingflow_mcp/solution/compiler/icon_utils.py +294 -0
- package/src/qingflow_mcp/tools/ai_builder_tools.py +461 -54
- package/src/qingflow_mcp/tools/app_tools.py +53 -8
- package/src/qingflow_mcp/tools/package_tools.py +16 -2
- package/src/qingflow_mcp/tools/record_tools.py +1262 -103
- package/src/qingflow_mcp/tools/resource_read_tools.py +3 -0
|
@@ -5,6 +5,215 @@ import re
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
DEFAULT_ICON_COLOR = "qing-orange"
|
|
8
|
+
WORKSPACE_ICON_COLORS: tuple[str, ...] = (
|
|
9
|
+
"qing-orange",
|
|
10
|
+
"yellow",
|
|
11
|
+
"green",
|
|
12
|
+
"emerald",
|
|
13
|
+
"blue",
|
|
14
|
+
"azure",
|
|
15
|
+
"indigo",
|
|
16
|
+
"qing-purple",
|
|
17
|
+
"purple",
|
|
18
|
+
"pink",
|
|
19
|
+
"red",
|
|
20
|
+
"orange",
|
|
21
|
+
)
|
|
22
|
+
WORKSPACE_ICON_NAMES: tuple[str, ...] = (
|
|
23
|
+
"user",
|
|
24
|
+
"user-group",
|
|
25
|
+
"user-remove",
|
|
26
|
+
"user-add",
|
|
27
|
+
"user-circle",
|
|
28
|
+
"base-camera",
|
|
29
|
+
"view-grid",
|
|
30
|
+
"inbox",
|
|
31
|
+
"inbox-in",
|
|
32
|
+
"share",
|
|
33
|
+
"sitemap",
|
|
34
|
+
"airplane",
|
|
35
|
+
"template",
|
|
36
|
+
"music-note",
|
|
37
|
+
"movie-play",
|
|
38
|
+
"clock",
|
|
39
|
+
"document",
|
|
40
|
+
"document-search",
|
|
41
|
+
"clipboard-check",
|
|
42
|
+
"document-download",
|
|
43
|
+
"document-text",
|
|
44
|
+
"clipboard-copy",
|
|
45
|
+
"presentation-chart-bar",
|
|
46
|
+
"chart-square-bar",
|
|
47
|
+
"database",
|
|
48
|
+
"server",
|
|
49
|
+
"calendar",
|
|
50
|
+
"mail",
|
|
51
|
+
"annotation",
|
|
52
|
+
"chat",
|
|
53
|
+
"bell",
|
|
54
|
+
"key",
|
|
55
|
+
"shopping-bag",
|
|
56
|
+
"download",
|
|
57
|
+
"eye",
|
|
58
|
+
"eye-off",
|
|
59
|
+
"emoji-happy",
|
|
60
|
+
"emoji-sad",
|
|
61
|
+
"sun",
|
|
62
|
+
"moon",
|
|
63
|
+
"cloud",
|
|
64
|
+
"lightning-bolt",
|
|
65
|
+
"fire",
|
|
66
|
+
"star",
|
|
67
|
+
"sparkles",
|
|
68
|
+
"heart",
|
|
69
|
+
"cake",
|
|
70
|
+
"gift",
|
|
71
|
+
"light-bulb",
|
|
72
|
+
"exclamation",
|
|
73
|
+
"cog",
|
|
74
|
+
"thumb-up",
|
|
75
|
+
"thumb-down",
|
|
76
|
+
"cloud-download",
|
|
77
|
+
"cloud-upload",
|
|
78
|
+
"printer",
|
|
79
|
+
"phone-incoming",
|
|
80
|
+
"phone-missed-call",
|
|
81
|
+
"terminal",
|
|
82
|
+
"search-circle",
|
|
83
|
+
"x-circle",
|
|
84
|
+
"check-circle",
|
|
85
|
+
"exclamation-circle",
|
|
86
|
+
"question-mark-circle",
|
|
87
|
+
"information-circle",
|
|
88
|
+
"academic-cap",
|
|
89
|
+
"briefcase",
|
|
90
|
+
"home",
|
|
91
|
+
"phone",
|
|
92
|
+
"photograph",
|
|
93
|
+
"puzzle",
|
|
94
|
+
"color-swatch",
|
|
95
|
+
"lock-open",
|
|
96
|
+
"lock-closed",
|
|
97
|
+
"shield-check",
|
|
98
|
+
"shield-exclamation",
|
|
99
|
+
"currency-dollar",
|
|
100
|
+
"currency-yen",
|
|
101
|
+
"globe",
|
|
102
|
+
"at-symbol",
|
|
103
|
+
"slack",
|
|
104
|
+
"microphone",
|
|
105
|
+
"speakerphone",
|
|
106
|
+
"trash",
|
|
107
|
+
"book-open",
|
|
108
|
+
"truck",
|
|
109
|
+
"filter",
|
|
110
|
+
"essetional-filter-search",
|
|
111
|
+
"essetional-filter-tick",
|
|
112
|
+
"table",
|
|
113
|
+
"calculator",
|
|
114
|
+
"location-radar",
|
|
115
|
+
"essetional-weight",
|
|
116
|
+
"school-award",
|
|
117
|
+
"comp-cloud-connection",
|
|
118
|
+
"comp-cloud-remove",
|
|
119
|
+
"comp-cpu-charge",
|
|
120
|
+
"comp-cpu-setting",
|
|
121
|
+
"comp-cpu",
|
|
122
|
+
"comp-devices",
|
|
123
|
+
"comp-driver-2",
|
|
124
|
+
"comp-driver-refresh",
|
|
125
|
+
"location-global",
|
|
126
|
+
"location-location",
|
|
127
|
+
"location-map",
|
|
128
|
+
"location-gps",
|
|
129
|
+
"essetional-ranking",
|
|
130
|
+
"chart-bar",
|
|
131
|
+
"business-graph",
|
|
132
|
+
"business-status-up",
|
|
133
|
+
"business-trend-down",
|
|
134
|
+
"business-trend-up",
|
|
135
|
+
"business-presention-chart",
|
|
136
|
+
"business-favorite-chart",
|
|
137
|
+
"business-health",
|
|
138
|
+
"receipt-refund",
|
|
139
|
+
"receipt-tax",
|
|
140
|
+
"money-receipt-2-1",
|
|
141
|
+
"money-transaction-minus",
|
|
142
|
+
"action-hourglass-full",
|
|
143
|
+
"action-work",
|
|
144
|
+
"bug-f",
|
|
145
|
+
"essetional-pet",
|
|
146
|
+
"files-folder",
|
|
147
|
+
"badge-check",
|
|
148
|
+
"money-wallet-1",
|
|
149
|
+
"money-ticket",
|
|
150
|
+
"money-money",
|
|
151
|
+
"money-tag",
|
|
152
|
+
"money-wallet-2",
|
|
153
|
+
"business-personalcard",
|
|
154
|
+
"car-airplane",
|
|
155
|
+
"car-bus",
|
|
156
|
+
"car-car",
|
|
157
|
+
"car-driving",
|
|
158
|
+
"car-gas-station",
|
|
159
|
+
"car-smart-car",
|
|
160
|
+
"car-ship",
|
|
161
|
+
"location-map-1",
|
|
162
|
+
"location-route-square",
|
|
163
|
+
"cone",
|
|
164
|
+
"design-brush-4",
|
|
165
|
+
"paint-roll",
|
|
166
|
+
"wrench-f",
|
|
167
|
+
"essetional-reserve",
|
|
168
|
+
"essetional-broom",
|
|
169
|
+
"design-brush-2",
|
|
170
|
+
"essetional-judge",
|
|
171
|
+
"design-bucket",
|
|
172
|
+
"palette",
|
|
173
|
+
"comp-electricity",
|
|
174
|
+
"vial",
|
|
175
|
+
"beaker",
|
|
176
|
+
"leaf-f",
|
|
177
|
+
"cursor-click",
|
|
178
|
+
"solid-search-alt-2",
|
|
179
|
+
"md-library",
|
|
180
|
+
"building-3",
|
|
181
|
+
"office-building",
|
|
182
|
+
"building-hospital",
|
|
183
|
+
"school",
|
|
184
|
+
"store",
|
|
185
|
+
"video-camera-vintage-f",
|
|
186
|
+
"comp-monitor",
|
|
187
|
+
"delivery-truck",
|
|
188
|
+
"delivery-box-1",
|
|
189
|
+
"delivery-box-add",
|
|
190
|
+
"delivery-box-remove",
|
|
191
|
+
"settings-setting-3",
|
|
192
|
+
"document-duplicate",
|
|
193
|
+
"essetional-flag-2",
|
|
194
|
+
"flag",
|
|
195
|
+
"icon-currency-dollar",
|
|
196
|
+
"clipboard-list",
|
|
197
|
+
"save-as",
|
|
198
|
+
"wifi",
|
|
199
|
+
"status-online",
|
|
200
|
+
"scissors",
|
|
201
|
+
"globe-alt",
|
|
202
|
+
"ban",
|
|
203
|
+
"finger-print",
|
|
204
|
+
"qrcode",
|
|
205
|
+
"paper-clip",
|
|
206
|
+
"translate",
|
|
207
|
+
"cube-transparent",
|
|
208
|
+
"variable",
|
|
209
|
+
"switch-vertical",
|
|
210
|
+
"sports-baseball",
|
|
211
|
+
"sports-basketball",
|
|
212
|
+
"sports-soccer",
|
|
213
|
+
"sports-football",
|
|
214
|
+
"sports-volleyball",
|
|
215
|
+
)
|
|
216
|
+
GENERIC_WORKSPACE_ICON_NAMES: tuple[str, ...] = ("template",)
|
|
8
217
|
DEFAULT_ICON_STYLE_POOL: tuple[tuple[str, str], ...] = (
|
|
9
218
|
("briefcase", "qing-orange"),
|
|
10
219
|
("calendar", "emerald"),
|
|
@@ -115,6 +324,91 @@ def parse_workspace_icon(value: str | None) -> tuple[str | None, str | None, str
|
|
|
115
324
|
return normalize_workspace_icon_name(stripped), None, None
|
|
116
325
|
|
|
117
326
|
|
|
327
|
+
def workspace_icon_config(value: str | None) -> dict[str, str | None]:
|
|
328
|
+
icon_name, icon_color, icon_text = parse_workspace_icon(value)
|
|
329
|
+
raw = str(value).strip() if value not in (None, "") else None
|
|
330
|
+
return {
|
|
331
|
+
"icon_name": icon_name,
|
|
332
|
+
"icon_color": icon_color,
|
|
333
|
+
"icon_text": icon_text,
|
|
334
|
+
"raw": raw,
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def workspace_icon_catalog_payload() -> dict[str, object]:
|
|
339
|
+
return {
|
|
340
|
+
"icon_names": list(WORKSPACE_ICON_NAMES),
|
|
341
|
+
"icon_colors": list(WORKSPACE_ICON_COLORS),
|
|
342
|
+
"generic_icon_names": list(GENERIC_WORKSPACE_ICON_NAMES),
|
|
343
|
+
"notes": [
|
|
344
|
+
"Use explicit icon + color for app/package/portal creation.",
|
|
345
|
+
"Do not use template for newly created workspace resources.",
|
|
346
|
+
"The CLI validates candidates only; it does not infer an icon from business names.",
|
|
347
|
+
],
|
|
348
|
+
"common_examples": {
|
|
349
|
+
"employee": ["business-personalcard", "user-group", "user"],
|
|
350
|
+
"task": ["clipboard-check", "action-work"],
|
|
351
|
+
"worklog": ["clock", "action-hourglass-full"],
|
|
352
|
+
"order": ["delivery-box-1", "shopping-bag"],
|
|
353
|
+
"payment": ["money-receipt-2-1", "money-wallet-1"],
|
|
354
|
+
"opportunity": ["business-graph", "business-trend-up"],
|
|
355
|
+
"dashboard": ["view-grid", "chart-square-bar", "presentation-chart-bar"],
|
|
356
|
+
},
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def validate_workspace_icon_choice(
|
|
361
|
+
*,
|
|
362
|
+
icon: str | None,
|
|
363
|
+
color: str | None,
|
|
364
|
+
require_explicit: bool,
|
|
365
|
+
disallow_generic: bool,
|
|
366
|
+
) -> tuple[bool, str | None, str | None, dict[str, object]]:
|
|
367
|
+
normalized_icon = _normalize_workspace_icon_candidate(icon)
|
|
368
|
+
normalized_color = str(color or "").strip() or None
|
|
369
|
+
details: dict[str, object] = {
|
|
370
|
+
"icon": icon,
|
|
371
|
+
"normalized_icon": normalized_icon,
|
|
372
|
+
"color": color,
|
|
373
|
+
"icon_catalog_command": "qingflow --json builder icon catalog",
|
|
374
|
+
}
|
|
375
|
+
if require_explicit and not normalized_icon:
|
|
376
|
+
return False, "WORKSPACE_ICON_REQUIRED", "icon is required when creating a workspace resource", details
|
|
377
|
+
if require_explicit and not normalized_color:
|
|
378
|
+
return False, "WORKSPACE_ICON_COLOR_REQUIRED", "color is required when creating a workspace resource", details
|
|
379
|
+
if normalized_icon and normalized_icon not in WORKSPACE_ICON_NAMES:
|
|
380
|
+
details["allowed_icon_names"] = list(WORKSPACE_ICON_NAMES)
|
|
381
|
+
return False, "WORKSPACE_ICON_NOT_FOUND", "icon is not in the workspace icon catalog", details
|
|
382
|
+
if normalized_color and normalized_color not in WORKSPACE_ICON_COLORS:
|
|
383
|
+
details["allowed_icon_colors"] = list(WORKSPACE_ICON_COLORS)
|
|
384
|
+
return False, "WORKSPACE_ICON_COLOR_NOT_FOUND", "color is not in the workspace icon color catalog", details
|
|
385
|
+
if disallow_generic and normalized_icon in GENERIC_WORKSPACE_ICON_NAMES:
|
|
386
|
+
details["generic_icon_names"] = list(GENERIC_WORKSPACE_ICON_NAMES)
|
|
387
|
+
return False, "GENERIC_WORKSPACE_ICON_NOT_ALLOWED", "template is a generic icon and is not allowed for new workspace resources", details
|
|
388
|
+
return True, None, None, details
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def _normalize_workspace_icon_candidate(icon: str | None) -> str | None:
|
|
392
|
+
if not icon:
|
|
393
|
+
return None
|
|
394
|
+
raw = str(icon).strip()
|
|
395
|
+
if not raw:
|
|
396
|
+
return None
|
|
397
|
+
if _looks_like_icon_json(raw):
|
|
398
|
+
try:
|
|
399
|
+
payload = json.loads(raw)
|
|
400
|
+
except Exception:
|
|
401
|
+
return None
|
|
402
|
+
return _normalize_workspace_icon_candidate(payload.get("iconName"))
|
|
403
|
+
normalized = raw.lower()
|
|
404
|
+
if normalized in WORKSPACE_ICON_NAMES:
|
|
405
|
+
return normalized
|
|
406
|
+
legacy = LEGACY_EX_ICON_MAP.get(normalized)
|
|
407
|
+
if legacy in WORKSPACE_ICON_NAMES:
|
|
408
|
+
return legacy
|
|
409
|
+
return normalized
|
|
410
|
+
|
|
411
|
+
|
|
118
412
|
def encode_workspace_icon_with_defaults(
|
|
119
413
|
*,
|
|
120
414
|
icon: str | None,
|