@josephyan/qingflow-cli 0.2.0-beta.71 → 0.2.0-beta.73
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/backend_client.py +1 -0
- package/src/qingflow_mcp/builder_facade/models.py +22 -11
- package/src/qingflow_mcp/builder_facade/service.py +183 -121
- package/src/qingflow_mcp/cli/commands/__init__.py +4 -1
- package/src/qingflow_mcp/cli/commands/builder.py +81 -64
- package/src/qingflow_mcp/cli/commands/chart.py +18 -0
- package/src/qingflow_mcp/cli/commands/portal.py +25 -0
- package/src/qingflow_mcp/cli/commands/view.py +18 -0
- package/src/qingflow_mcp/cli/context.py +9 -0
- package/src/qingflow_mcp/response_trim.py +219 -178
- package/src/qingflow_mcp/server_app_builder.py +18 -42
- package/src/qingflow_mcp/server_app_user.py +21 -1
- package/src/qingflow_mcp/tools/ai_builder_tools.py +244 -124
- package/src/qingflow_mcp/tools/app_tools.py +0 -4
- package/src/qingflow_mcp/tools/resource_read_tools.py +399 -0
|
@@ -2,13 +2,16 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
|
|
5
|
-
from . import app, auth, builder, imports, record, task, workspace
|
|
5
|
+
from . import app, auth, builder, chart, imports, portal, record, task, view, workspace
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def register_all_commands(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
|
|
9
9
|
auth.register(subparsers)
|
|
10
10
|
workspace.register(subparsers)
|
|
11
11
|
app.register(subparsers)
|
|
12
|
+
portal.register(subparsers)
|
|
13
|
+
view.register(subparsers)
|
|
14
|
+
chart.register(subparsers)
|
|
12
15
|
record.register(subparsers)
|
|
13
16
|
imports.register(subparsers)
|
|
14
17
|
task.register(subparsers)
|
|
@@ -10,6 +10,34 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
10
10
|
parser = subparsers.add_parser("builder", aliases=["build"], help="稳定 builder 命令")
|
|
11
11
|
builder_subparsers = parser.add_subparsers(dest="builder_command", required=True)
|
|
12
12
|
|
|
13
|
+
file_parser = builder_subparsers.add_parser("file", help="builder 侧文件上传")
|
|
14
|
+
file_subparsers = file_parser.add_subparsers(dest="builder_file_command", required=True)
|
|
15
|
+
file_upload_local = file_subparsers.add_parser("upload-local", help="上传本地文件并返回附件值")
|
|
16
|
+
file_upload_local.add_argument("--upload-kind", default="attachment")
|
|
17
|
+
file_upload_local.add_argument("--file-path", required=True)
|
|
18
|
+
file_upload_local.add_argument("--upload-mark")
|
|
19
|
+
file_upload_local.add_argument("--content-type")
|
|
20
|
+
file_upload_local.add_argument("--bucket-type")
|
|
21
|
+
file_upload_local.add_argument("--path-id", type=int)
|
|
22
|
+
file_upload_local.add_argument("--file-related-url")
|
|
23
|
+
file_upload_local.set_defaults(handler=_handle_file_upload_local, format_hint="generic")
|
|
24
|
+
|
|
25
|
+
feedback = builder_subparsers.add_parser("feedback", help="builder 侧反馈提交")
|
|
26
|
+
feedback_subparsers = feedback.add_subparsers(dest="builder_feedback_command", required=True)
|
|
27
|
+
feedback_submit = feedback_subparsers.add_parser("submit", help="提交 builder 能力反馈")
|
|
28
|
+
feedback_submit.add_argument("--category", required=True)
|
|
29
|
+
feedback_submit.add_argument("--title", required=True)
|
|
30
|
+
feedback_submit.add_argument("--description", required=True)
|
|
31
|
+
feedback_submit.add_argument("--expected-behavior")
|
|
32
|
+
feedback_submit.add_argument("--actual-behavior")
|
|
33
|
+
feedback_submit.add_argument("--impact-scope")
|
|
34
|
+
feedback_submit.add_argument("--tool-name")
|
|
35
|
+
feedback_submit.add_argument("--app-key")
|
|
36
|
+
feedback_submit.add_argument("--record-id")
|
|
37
|
+
feedback_submit.add_argument("--workflow-node-id")
|
|
38
|
+
feedback_submit.add_argument("--note")
|
|
39
|
+
feedback_submit.set_defaults(handler=_handle_feedback_submit, format_hint="generic")
|
|
40
|
+
|
|
13
41
|
contract = builder_subparsers.add_parser("contract", help="读取 builder tool 合约")
|
|
14
42
|
contract.add_argument("--tool-name", required=True)
|
|
15
43
|
contract.set_defaults(handler=_handle_contract, format_hint="builder_summary")
|
|
@@ -76,6 +104,16 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
76
104
|
app_release_lock.add_argument("--lock-owner-name", required=True)
|
|
77
105
|
app_release_lock.set_defaults(handler=_handle_app_release_edit_lock_if_mine, format_hint="builder_summary")
|
|
78
106
|
|
|
107
|
+
app_get = app_subparsers.add_parser("get", help="读取应用配置")
|
|
108
|
+
app_get.add_argument(
|
|
109
|
+
"builder_app_get_section",
|
|
110
|
+
nargs="?",
|
|
111
|
+
choices=["summary", "fields", "layout", "views", "flow", "charts"],
|
|
112
|
+
default="summary",
|
|
113
|
+
)
|
|
114
|
+
app_get.add_argument("--app-key", required=True)
|
|
115
|
+
app_get.set_defaults(handler=_handle_app_get, format_hint="builder_summary")
|
|
116
|
+
|
|
79
117
|
button = builder_subparsers.add_parser("button", help="自定义按钮")
|
|
80
118
|
button_subparsers = button.add_subparsers(dest="builder_button_command", required=True)
|
|
81
119
|
|
|
@@ -104,18 +142,6 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
104
142
|
button_delete.add_argument("--button-id", type=int, required=True)
|
|
105
143
|
button_delete.set_defaults(handler=_handle_button_delete, format_hint="builder_summary")
|
|
106
144
|
|
|
107
|
-
for name, help_text, handler in [
|
|
108
|
-
("read-summary", "读取应用摘要", _handle_app_read_summary),
|
|
109
|
-
("read-fields", "读取字段摘要", _handle_app_read_fields),
|
|
110
|
-
("read-layout", "读取布局摘要", _handle_app_read_layout),
|
|
111
|
-
("read-views", "读取视图摘要", _handle_app_read_views),
|
|
112
|
-
("read-flow", "读取流程摘要", _handle_app_read_flow),
|
|
113
|
-
("read-charts", "读取报表摘要", _handle_app_read_charts),
|
|
114
|
-
]:
|
|
115
|
-
sub = app_subparsers.add_parser(name, help=help_text)
|
|
116
|
-
sub.add_argument("--app-key", required=True)
|
|
117
|
-
sub.set_defaults(handler=handler, format_hint="builder_summary")
|
|
118
|
-
|
|
119
145
|
portal = builder_subparsers.add_parser("portal", help="门户")
|
|
120
146
|
portal_subparsers = portal.add_subparsers(dest="builder_portal_command", required=True)
|
|
121
147
|
portal_list = portal_subparsers.add_parser("list", help="列出可访问门户")
|
|
@@ -126,11 +152,6 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
126
152
|
portal_get.add_argument("--being-draft", action=argparse.BooleanOptionalAction, default=True)
|
|
127
153
|
portal_get.set_defaults(handler=_handle_portal_get, format_hint="builder_summary")
|
|
128
154
|
|
|
129
|
-
portal_read = portal_subparsers.add_parser("read-summary", help="读取门户摘要")
|
|
130
|
-
portal_read.add_argument("--dash-key", required=True)
|
|
131
|
-
portal_read.add_argument("--being-draft", action=argparse.BooleanOptionalAction, default=True)
|
|
132
|
-
portal_read.set_defaults(handler=_handle_portal_read_summary, format_hint="builder_summary")
|
|
133
|
-
|
|
134
155
|
portal_apply = portal_subparsers.add_parser("apply", help="更新门户")
|
|
135
156
|
portal_apply.add_argument("--dash-key", default="")
|
|
136
157
|
portal_apply.add_argument("--dash-name", default="")
|
|
@@ -208,18 +229,13 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
208
229
|
view = builder_subparsers.add_parser("view", help="视图详情")
|
|
209
230
|
view_subparsers = view.add_subparsers(dest="builder_view_command", required=True)
|
|
210
231
|
view_get = view_subparsers.add_parser("get", help="读取视图详情")
|
|
211
|
-
view_get.add_argument("--
|
|
232
|
+
view_get.add_argument("--view-key", required=True)
|
|
212
233
|
view_get.set_defaults(handler=_handle_view_get, format_hint="builder_summary")
|
|
213
234
|
|
|
214
235
|
chart = builder_subparsers.add_parser("chart", help="报表详情")
|
|
215
236
|
chart_subparsers = chart.add_subparsers(dest="builder_chart_command", required=True)
|
|
216
|
-
chart_get = chart_subparsers.add_parser("get", help="
|
|
237
|
+
chart_get = chart_subparsers.add_parser("get", help="读取报表配置详情")
|
|
217
238
|
chart_get.add_argument("--chart-id", required=True)
|
|
218
|
-
chart_get.add_argument("--data-payload-file")
|
|
219
|
-
chart_get.add_argument("--page-num", type=int)
|
|
220
|
-
chart_get.add_argument("--page-size", type=int)
|
|
221
|
-
chart_get.add_argument("--page-num-y", type=int)
|
|
222
|
-
chart_get.add_argument("--page-size-y", type=int)
|
|
223
239
|
chart_get.set_defaults(handler=_handle_chart_get, format_hint="builder_summary")
|
|
224
240
|
|
|
225
241
|
|
|
@@ -227,6 +243,35 @@ def _handle_package_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
227
243
|
return context.builder.package_list(profile=args.profile, trial_status=args.trial_status)
|
|
228
244
|
|
|
229
245
|
|
|
246
|
+
def _handle_file_upload_local(args: argparse.Namespace, context: CliContext) -> dict:
|
|
247
|
+
return context.files.file_upload_local(
|
|
248
|
+
profile=args.profile,
|
|
249
|
+
upload_kind=args.upload_kind,
|
|
250
|
+
file_path=args.file_path,
|
|
251
|
+
upload_mark=args.upload_mark,
|
|
252
|
+
content_type=args.content_type,
|
|
253
|
+
bucket_type=args.bucket_type,
|
|
254
|
+
path_id=args.path_id,
|
|
255
|
+
file_related_url=args.file_related_url,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _handle_feedback_submit(args: argparse.Namespace, context: CliContext) -> dict:
|
|
260
|
+
return context.builder_feedback.feedback_submit(
|
|
261
|
+
category=args.category,
|
|
262
|
+
title=args.title,
|
|
263
|
+
description=args.description,
|
|
264
|
+
expected_behavior=args.expected_behavior,
|
|
265
|
+
actual_behavior=args.actual_behavior,
|
|
266
|
+
impact_scope=args.impact_scope,
|
|
267
|
+
tool_name=args.tool_name,
|
|
268
|
+
app_key=args.app_key,
|
|
269
|
+
record_id=args.record_id,
|
|
270
|
+
workflow_node_id=args.workflow_node_id,
|
|
271
|
+
note=args.note,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
|
|
230
275
|
def _handle_contract(args: argparse.Namespace, context: CliContext) -> dict:
|
|
231
276
|
return context.builder.builder_tool_contract(tool_name=args.tool_name)
|
|
232
277
|
|
|
@@ -347,28 +392,16 @@ def _handle_button_delete(args: argparse.Namespace, context: CliContext) -> dict
|
|
|
347
392
|
return context.builder.app_custom_button_delete(profile=args.profile, app_key=args.app_key, button_id=args.button_id)
|
|
348
393
|
|
|
349
394
|
|
|
350
|
-
def
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
def _handle_app_read_views(args: argparse.Namespace, context: CliContext) -> dict:
|
|
363
|
-
return context.builder.app_read_views_summary(profile=args.profile, app_key=args.app_key)
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
def _handle_app_read_flow(args: argparse.Namespace, context: CliContext) -> dict:
|
|
367
|
-
return context.builder.app_read_flow_summary(profile=args.profile, app_key=args.app_key)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
def _handle_app_read_charts(args: argparse.Namespace, context: CliContext) -> dict:
|
|
371
|
-
return context.builder.app_read_charts_summary(profile=args.profile, app_key=args.app_key)
|
|
395
|
+
def _handle_app_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
396
|
+
handlers = {
|
|
397
|
+
"summary": context.builder.app_get,
|
|
398
|
+
"fields": context.builder.app_get_fields,
|
|
399
|
+
"layout": context.builder.app_get_layout,
|
|
400
|
+
"views": context.builder.app_get_views,
|
|
401
|
+
"flow": context.builder.app_get_flow,
|
|
402
|
+
"charts": context.builder.app_get_charts,
|
|
403
|
+
}
|
|
404
|
+
return handlers[args.builder_app_get_section](profile=args.profile, app_key=args.app_key)
|
|
372
405
|
|
|
373
406
|
|
|
374
407
|
def _handle_portal_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
@@ -379,28 +412,12 @@ def _handle_portal_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
379
412
|
return context.builder.portal_get(profile=args.profile, dash_key=args.dash_key, being_draft=bool(args.being_draft))
|
|
380
413
|
|
|
381
414
|
|
|
382
|
-
def _handle_portal_read_summary(args: argparse.Namespace, context: CliContext) -> dict:
|
|
383
|
-
return context.builder.portal_read_summary(
|
|
384
|
-
profile=args.profile,
|
|
385
|
-
dash_key=args.dash_key,
|
|
386
|
-
being_draft=bool(args.being_draft),
|
|
387
|
-
)
|
|
388
|
-
|
|
389
|
-
|
|
390
415
|
def _handle_view_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
391
|
-
return context.builder.view_get(profile=args.profile,
|
|
416
|
+
return context.builder.view_get(profile=args.profile, view_key=args.view_key)
|
|
392
417
|
|
|
393
418
|
|
|
394
419
|
def _handle_chart_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
395
|
-
return context.builder.chart_get(
|
|
396
|
-
profile=args.profile,
|
|
397
|
-
chart_id=args.chart_id,
|
|
398
|
-
data_payload=load_object_arg(args.data_payload_file, option_name="--data-payload-file") if args.data_payload_file else {},
|
|
399
|
-
page_num=args.page_num,
|
|
400
|
-
page_size=args.page_size,
|
|
401
|
-
page_num_y=args.page_num_y,
|
|
402
|
-
page_size_y=args.page_size_y,
|
|
403
|
-
)
|
|
420
|
+
return context.builder.chart_get(profile=args.profile, chart_id=args.chart_id)
|
|
404
421
|
|
|
405
422
|
|
|
406
423
|
def _handle_schema_apply(args: argparse.Namespace, context: CliContext) -> dict:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
from ..context import CliContext
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
|
|
9
|
+
parser = subparsers.add_parser("chart", help="报表访问")
|
|
10
|
+
chart_subparsers = parser.add_subparsers(dest="chart_command", required=True)
|
|
11
|
+
|
|
12
|
+
get_parser = chart_subparsers.add_parser("get", help="读取报表数据")
|
|
13
|
+
get_parser.add_argument("--chart-id", required=True)
|
|
14
|
+
get_parser.set_defaults(handler=_handle_get, format_hint="generic")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
18
|
+
return context.resource.chart_get(profile=args.profile, chart_id=args.chart_id)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
from ..context import CliContext
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
|
|
9
|
+
parser = subparsers.add_parser("portal", help="门户访问")
|
|
10
|
+
portal_subparsers = parser.add_subparsers(dest="portal_command", required=True)
|
|
11
|
+
|
|
12
|
+
list_parser = portal_subparsers.add_parser("list", help="列出当前用户可访问的门户")
|
|
13
|
+
list_parser.set_defaults(handler=_handle_list, format_hint="generic")
|
|
14
|
+
|
|
15
|
+
get_parser = portal_subparsers.add_parser("get", help="读取门户内容清单")
|
|
16
|
+
get_parser.add_argument("--dash-key", required=True)
|
|
17
|
+
get_parser.set_defaults(handler=_handle_get, format_hint="generic")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
21
|
+
return context.resource.portal_list(profile=args.profile)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
25
|
+
return context.resource.portal_get(profile=args.profile, dash_key=args.dash_key)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
from ..context import CliContext
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
|
|
9
|
+
parser = subparsers.add_parser("view", help="视图访问")
|
|
10
|
+
view_subparsers = parser.add_subparsers(dest="view_command", required=True)
|
|
11
|
+
|
|
12
|
+
get_parser = view_subparsers.add_parser("get", help="读取视图资源描述")
|
|
13
|
+
get_parser.add_argument("--view-id", required=True)
|
|
14
|
+
get_parser.set_defaults(handler=_handle_get, format_hint="generic")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
18
|
+
return context.resource.view_get(profile=args.profile, view_id=args.view_id)
|
|
@@ -8,8 +8,11 @@ from ..tools.ai_builder_tools import AiBuilderTools
|
|
|
8
8
|
from ..tools.app_tools import AppTools
|
|
9
9
|
from ..tools.auth_tools import AuthTools
|
|
10
10
|
from ..tools.code_block_tools import CodeBlockTools
|
|
11
|
+
from ..tools.feedback_tools import FeedbackTools
|
|
12
|
+
from ..tools.file_tools import FileTools
|
|
11
13
|
from ..tools.import_tools import ImportTools
|
|
12
14
|
from ..tools.record_tools import RecordTools
|
|
15
|
+
from ..tools.resource_read_tools import ResourceReadTools
|
|
13
16
|
from ..tools.task_context_tools import TaskContextTools
|
|
14
17
|
from ..tools.workspace_tools import WorkspaceTools
|
|
15
18
|
|
|
@@ -21,10 +24,13 @@ class CliContext:
|
|
|
21
24
|
auth: AuthTools
|
|
22
25
|
workspace: WorkspaceTools
|
|
23
26
|
app: AppTools
|
|
27
|
+
resource: ResourceReadTools
|
|
24
28
|
record: RecordTools
|
|
25
29
|
code_block: CodeBlockTools
|
|
26
30
|
imports: ImportTools
|
|
27
31
|
task: TaskContextTools
|
|
32
|
+
files: FileTools
|
|
33
|
+
builder_feedback: FeedbackTools
|
|
28
34
|
builder: AiBuilderTools
|
|
29
35
|
|
|
30
36
|
def close(self) -> None:
|
|
@@ -40,9 +46,12 @@ def build_cli_context() -> CliContext:
|
|
|
40
46
|
auth=AuthTools(sessions, backend),
|
|
41
47
|
workspace=WorkspaceTools(sessions, backend),
|
|
42
48
|
app=AppTools(sessions, backend),
|
|
49
|
+
resource=ResourceReadTools(sessions, backend),
|
|
43
50
|
record=RecordTools(sessions, backend),
|
|
44
51
|
code_block=CodeBlockTools(sessions, backend),
|
|
45
52
|
imports=ImportTools(sessions, backend),
|
|
46
53
|
task=TaskContextTools(sessions, backend),
|
|
54
|
+
files=FileTools(sessions, backend),
|
|
55
|
+
builder_feedback=FeedbackTools(backend, mcp_side="App Builder MCP"),
|
|
47
56
|
builder=AiBuilderTools(sessions, backend),
|
|
48
57
|
)
|