@qingflow-tech/qingflow-app-builder-mcp 1.0.10 → 1.0.12
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 +6 -3
- package/docs/local-agent-install.md +54 -3
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-skills.mjs +5 -0
- package/npm/lib/runtime.mjs +304 -13
- package/npm/scripts/postinstall.mjs +1 -5
- package/package.json +3 -2
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +12 -12
- package/skills/qingflow-app-builder/references/create-app.md +3 -3
- package/skills/qingflow-app-builder/references/environments.md +1 -1
- package/skills/qingflow-app-builder/references/gotchas.md +1 -1
- package/skills/qingflow-app-builder/references/public-surface-sync.md +75 -0
- package/skills/qingflow-app-builder/references/tool-selection.md +6 -5
- package/skills/qingflow-app-builder/references/update-views.md +1 -1
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +3 -3
- package/skills/qingflow-app-builder-code-integrations/references/code-block.md +1 -1
- package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +1 -1
- package/src/qingflow_mcp/__main__.py +6 -2
- package/src/qingflow_mcp/builder_facade/models.py +41 -2
- package/src/qingflow_mcp/builder_facade/service.py +2743 -423
- package/src/qingflow_mcp/cli/commands/app.py +3 -16
- package/src/qingflow_mcp/cli/commands/builder.py +30 -4
- package/src/qingflow_mcp/cli/commands/exports.py +2 -2
- package/src/qingflow_mcp/cli/commands/imports.py +1 -1
- package/src/qingflow_mcp/cli/commands/record.py +54 -11
- package/src/qingflow_mcp/cli/context.py +0 -3
- package/src/qingflow_mcp/cli/formatters.py +238 -8
- package/src/qingflow_mcp/cli/main.py +47 -3
- package/src/qingflow_mcp/errors.py +43 -2
- package/src/qingflow_mcp/public_surface.py +24 -16
- package/src/qingflow_mcp/response_trim.py +119 -12
- package/src/qingflow_mcp/server.py +17 -14
- package/src/qingflow_mcp/server_app_builder.py +29 -7
- package/src/qingflow_mcp/server_app_user.py +23 -24
- package/src/qingflow_mcp/solution/compiler/icon_utils.py +294 -0
- package/src/qingflow_mcp/solution/executor.py +112 -15
- package/src/qingflow_mcp/tools/ai_builder_tools.py +497 -65
- package/src/qingflow_mcp/tools/app_tools.py +237 -51
- package/src/qingflow_mcp/tools/approval_tools.py +196 -34
- package/src/qingflow_mcp/tools/auth_tools.py +92 -16
- package/src/qingflow_mcp/tools/code_block_tools.py +296 -39
- package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
- package/src/qingflow_mcp/tools/directory_tools.py +236 -72
- package/src/qingflow_mcp/tools/export_tools.py +230 -33
- package/src/qingflow_mcp/tools/file_tools.py +7 -3
- package/src/qingflow_mcp/tools/import_tools.py +293 -40
- package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
- package/src/qingflow_mcp/tools/package_tools.py +134 -8
- package/src/qingflow_mcp/tools/portal_tools.py +39 -3
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
- package/src/qingflow_mcp/tools/record_tools.py +2305 -442
- package/src/qingflow_mcp/tools/resource_read_tools.py +191 -39
- package/src/qingflow_mcp/tools/role_tools.py +80 -9
- package/src/qingflow_mcp/tools/solution_tools.py +57 -15
- package/src/qingflow_mcp/tools/task_context_tools.py +569 -119
- package/src/qingflow_mcp/tools/task_tools.py +113 -29
- package/src/qingflow_mcp/tools/view_tools.py +106 -3
- package/src/qingflow_mcp/tools/workflow_tools.py +17 -1
- package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
|
@@ -13,30 +13,17 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
13
13
|
app_subparsers = parser.add_subparsers(dest="app_command", required=True)
|
|
14
14
|
|
|
15
15
|
list_parser = app_subparsers.add_parser("list", help="列出可见应用")
|
|
16
|
+
list_parser.add_argument("--query", default="", help="按关键词在可见应用列表中本地过滤")
|
|
17
|
+
list_parser.add_argument("--keyword", default="", help="兼容别名;建议使用 --query")
|
|
16
18
|
list_parser.set_defaults(handler=_handle_list, format_hint="app_list")
|
|
17
19
|
|
|
18
|
-
search = app_subparsers.add_parser("search", help="搜索应用")
|
|
19
|
-
search.add_argument("--keyword", default="")
|
|
20
|
-
search.add_argument("--page", type=int, default=1)
|
|
21
|
-
search.add_argument("--page-size", type=int, default=50)
|
|
22
|
-
search.set_defaults(handler=_handle_search, format_hint="app_search")
|
|
23
|
-
|
|
24
20
|
get = app_subparsers.add_parser("get", help="读取应用可访问视图与导入能力")
|
|
25
21
|
get.add_argument("--app-key", help="不传时在交互终端中选择应用")
|
|
26
22
|
get.set_defaults(handler=_handle_get, format_hint="app_get")
|
|
27
23
|
|
|
28
24
|
|
|
29
25
|
def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
30
|
-
return context.app.app_list(profile=args.profile)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _handle_search(args: argparse.Namespace, context: CliContext) -> dict:
|
|
34
|
-
return context.app.app_search(
|
|
35
|
-
profile=args.profile,
|
|
36
|
-
keyword=args.keyword,
|
|
37
|
-
page_num=args.page,
|
|
38
|
-
page_size=args.page_size,
|
|
39
|
-
)
|
|
26
|
+
return context.app.app_list(profile=args.profile, query=args.query, keyword=args.keyword)
|
|
40
27
|
|
|
41
28
|
|
|
42
29
|
def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
@@ -42,10 +42,15 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
42
42
|
contract.add_argument("--tool-name", required=True)
|
|
43
43
|
contract.set_defaults(handler=_handle_contract, format_hint="builder_summary")
|
|
44
44
|
|
|
45
|
+
icon = builder_subparsers.add_parser("icon", help="工作区图标目录")
|
|
46
|
+
icon_subparsers = icon.add_subparsers(dest="builder_icon_command", required=True)
|
|
47
|
+
icon_catalog = icon_subparsers.add_parser("catalog", help="读取应用、应用包、门户可用图标目录")
|
|
48
|
+
icon_catalog.set_defaults(handler=_handle_icon_catalog, format_hint="builder_summary")
|
|
49
|
+
|
|
45
50
|
member = builder_subparsers.add_parser("member", help="成员目录")
|
|
46
51
|
member_subparsers = member.add_subparsers(dest="builder_member_command", required=True)
|
|
47
52
|
member_search = member_subparsers.add_parser("search", help="搜索成员")
|
|
48
|
-
member_search.add_argument("--query",
|
|
53
|
+
member_search.add_argument("--query", required=True)
|
|
49
54
|
member_search.add_argument("--page-num", type=int, default=1)
|
|
50
55
|
member_search.add_argument("--page-size", type=int, default=20)
|
|
51
56
|
member_search.add_argument("--contain-disable", action=argparse.BooleanOptionalAction, default=False)
|
|
@@ -54,7 +59,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
54
59
|
role = builder_subparsers.add_parser("role", help="角色目录")
|
|
55
60
|
role_subparsers = role.add_subparsers(dest="builder_role_command", required=True)
|
|
56
61
|
role_search = role_subparsers.add_parser("search", help="搜索角色")
|
|
57
|
-
role_search.add_argument("--keyword",
|
|
62
|
+
role_search.add_argument("--keyword", required=True)
|
|
58
63
|
role_search.add_argument("--page-num", type=int, default=1)
|
|
59
64
|
role_search.add_argument("--page-size", type=int, default=20)
|
|
60
65
|
role_search.set_defaults(handler=_handle_role_search, format_hint="builder_summary")
|
|
@@ -78,6 +83,11 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
78
83
|
solution_install.add_argument("--solution-source", default="solutionDetail")
|
|
79
84
|
solution_install.set_defaults(handler=_handle_solution_install, format_hint="builder_summary")
|
|
80
85
|
|
|
86
|
+
package_list = package_subparsers.add_parser("list", help="列出应用包")
|
|
87
|
+
package_list.add_argument("--trial-status", default="all")
|
|
88
|
+
package_list.add_argument("--query", default="")
|
|
89
|
+
package_list.set_defaults(handler=_handle_package_list, format_hint="builder_summary")
|
|
90
|
+
|
|
81
91
|
package_get = package_subparsers.add_parser("get", help="读取应用包详情")
|
|
82
92
|
package_get.add_argument("--package-id", type=int, required=True)
|
|
83
93
|
package_get.set_defaults(handler=_handle_package_get, format_hint="builder_summary")
|
|
@@ -157,7 +167,9 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
157
167
|
portal_apply.add_argument("--dash-name", default="")
|
|
158
168
|
portal_apply.add_argument("--package-id", type=int)
|
|
159
169
|
portal_apply.add_argument("--publish", action=argparse.BooleanOptionalAction, default=True)
|
|
170
|
+
portal_apply.add_argument("--payload-file")
|
|
160
171
|
portal_apply.add_argument("--sections-file")
|
|
172
|
+
portal_apply.add_argument("--layout-preset", default="")
|
|
161
173
|
portal_apply.add_argument("--visibility-file")
|
|
162
174
|
portal_apply.add_argument("--auth-file")
|
|
163
175
|
portal_apply.add_argument("--icon")
|
|
@@ -277,6 +289,10 @@ def _handle_contract(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
277
289
|
return context.builder.builder_tool_contract(tool_name=args.tool_name)
|
|
278
290
|
|
|
279
291
|
|
|
292
|
+
def _handle_icon_catalog(args: argparse.Namespace, context: CliContext) -> dict:
|
|
293
|
+
return context.builder.workspace_icon_catalog_get(profile=args.profile)
|
|
294
|
+
|
|
295
|
+
|
|
280
296
|
def _handle_member_search(args: argparse.Namespace, context: CliContext) -> dict:
|
|
281
297
|
return context.builder.member_search(
|
|
282
298
|
profile=args.profile,
|
|
@@ -320,6 +336,10 @@ def _handle_package_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
320
336
|
return context.builder.package_get(profile=args.profile, package_id=args.package_id)
|
|
321
337
|
|
|
322
338
|
|
|
339
|
+
def _handle_package_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
340
|
+
return context.builder.package_list(profile=args.profile, trial_status=args.trial_status, query=args.query)
|
|
341
|
+
|
|
342
|
+
|
|
323
343
|
def _handle_package_apply(args: argparse.Namespace, context: CliContext) -> dict:
|
|
324
344
|
config = load_object_arg(args.config_file, option_name="--config-file")
|
|
325
345
|
if not isinstance(config, dict):
|
|
@@ -557,9 +577,13 @@ def _handle_charts_apply(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
557
577
|
|
|
558
578
|
|
|
559
579
|
def _handle_portal_apply(args: argparse.Namespace, context: CliContext) -> dict:
|
|
580
|
+
payload = load_object_arg(args.payload_file, option_name="--payload-file") if getattr(args, "payload_file", None) else None
|
|
581
|
+
payload_obj = payload if isinstance(payload, dict) else {}
|
|
582
|
+
effective_dash_name = (args.dash_name or str(payload_obj.get("dash_name") or payload_obj.get("dashName") or payload_obj.get("name") or "")).strip()
|
|
583
|
+
effective_package_id = args.package_id if args.package_id is not None else payload_obj.get("package_id") or payload_obj.get("packageId") or payload_obj.get("package_tag_id")
|
|
560
584
|
has_dash_key = bool((args.dash_key or "").strip())
|
|
561
|
-
has_dash_name = bool(
|
|
562
|
-
has_package_id =
|
|
585
|
+
has_dash_name = bool(effective_dash_name)
|
|
586
|
+
has_package_id = effective_package_id is not None
|
|
563
587
|
if has_dash_key and has_package_id:
|
|
564
588
|
raise_config_error(
|
|
565
589
|
"portal apply accepts exactly one selector mode.",
|
|
@@ -578,6 +602,7 @@ def _handle_portal_apply(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
578
602
|
package_id=args.package_id,
|
|
579
603
|
publish=bool(args.publish),
|
|
580
604
|
sections=sections,
|
|
605
|
+
layout_preset=args.layout_preset,
|
|
581
606
|
visibility=load_object_arg(args.visibility_file, option_name="--visibility-file"),
|
|
582
607
|
auth=load_object_arg(args.auth_file, option_name="--auth-file"),
|
|
583
608
|
icon=args.icon,
|
|
@@ -585,6 +610,7 @@ def _handle_portal_apply(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
585
610
|
hide_copyright=args.hide_copyright,
|
|
586
611
|
dash_global_config=load_object_arg(args.dash_global_config_file, option_name="--dash-global-config-file"),
|
|
587
612
|
config=load_object_arg(args.config_file, option_name="--config-file"),
|
|
613
|
+
payload=payload,
|
|
588
614
|
)
|
|
589
615
|
|
|
590
616
|
|
|
@@ -12,7 +12,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
12
12
|
|
|
13
13
|
start = export_subparsers.add_parser("start", help="启动导出")
|
|
14
14
|
start.add_argument("--app-key", required=True)
|
|
15
|
-
start.add_argument("--view-id",
|
|
15
|
+
start.add_argument("--view-id", required=True)
|
|
16
16
|
start.add_argument("--column", dest="columns", action="append", type=int, default=[], help="只导出这些 field_id;不传时导出当前视图全部字段")
|
|
17
17
|
start.add_argument("--columns-file", help="JSON/YAML list,内容与 --column 语义一致")
|
|
18
18
|
start.add_argument("--where-file", help="JSON/YAML list,内容与 record list 的 where DSL 一致;内部先查命中 record_id 再走原生导出")
|
|
@@ -33,7 +33,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
33
33
|
|
|
34
34
|
direct = export_subparsers.add_parser("direct", help="直接导出并下载")
|
|
35
35
|
direct.add_argument("--app-key", required=True)
|
|
36
|
-
direct.add_argument("--view-id",
|
|
36
|
+
direct.add_argument("--view-id", required=True)
|
|
37
37
|
direct.add_argument("--column", dest="columns", action="append", type=int, default=[], help="只导出这些 field_id;不传时导出当前视图全部字段")
|
|
38
38
|
direct.add_argument("--columns-file", help="JSON/YAML list,内容与 --column 语义一致")
|
|
39
39
|
direct.add_argument("--where-file", help="JSON/YAML list,内容与 record list 的 where DSL 一致;内部先查命中 record_id 再走原生导出")
|
|
@@ -13,7 +13,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
13
13
|
template = import_subparsers.add_parser("template", help="下载导入模板")
|
|
14
14
|
template.add_argument("--app-key", required=True)
|
|
15
15
|
template.add_argument("--download-to-path")
|
|
16
|
-
template.set_defaults(handler=_handle_template, format_hint="")
|
|
16
|
+
template.set_defaults(handler=_handle_template, format_hint="import_template")
|
|
17
17
|
|
|
18
18
|
verify = import_subparsers.add_parser("verify", help="校验导入文件")
|
|
19
19
|
verify.add_argument("--app-key", required=True)
|
|
@@ -13,17 +13,25 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
13
13
|
record_subparsers = parser.add_subparsers(
|
|
14
14
|
dest="record_command",
|
|
15
15
|
required=True,
|
|
16
|
-
metavar="{schema,list,access,get,insert,update,delete,member-candidates,department-candidates,code-block-run}",
|
|
16
|
+
metavar="{schema,list,access,get,logs,insert,update,delete,member-candidates,department-candidates,code-block-run}",
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
schema = record_subparsers.add_parser("schema", help="读取记录相关表结构")
|
|
20
20
|
schema.add_argument("--mode", dest="legacy_mode", help=argparse.SUPPRESS)
|
|
21
|
-
schema_subparsers = schema.add_subparsers(
|
|
21
|
+
schema_subparsers = schema.add_subparsers(
|
|
22
|
+
dest="record_schema_command",
|
|
23
|
+
metavar="{browse,insert,update,import,code-block}",
|
|
24
|
+
)
|
|
22
25
|
schema.set_defaults(handler=_handle_schema_root, format_hint="")
|
|
23
26
|
|
|
24
|
-
schema_applicant = schema_subparsers.add_parser("applicant", help=
|
|
27
|
+
schema_applicant = schema_subparsers.add_parser("applicant", help=argparse.SUPPRESS)
|
|
25
28
|
schema_applicant.add_argument("--app-key", required=True)
|
|
26
29
|
schema_applicant.set_defaults(handler=_handle_schema_applicant, format_hint="")
|
|
30
|
+
schema_subparsers._choices_actions = [ # type: ignore[attr-defined]
|
|
31
|
+
action
|
|
32
|
+
for action in schema_subparsers._choices_actions # type: ignore[attr-defined]
|
|
33
|
+
if getattr(action, "dest", None) != "applicant"
|
|
34
|
+
]
|
|
27
35
|
|
|
28
36
|
schema_browse = schema_subparsers.add_parser("browse", help="读取浏览视图表结构")
|
|
29
37
|
schema_browse.add_argument("--app-key", required=True)
|
|
@@ -37,6 +45,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
37
45
|
schema_update = schema_subparsers.add_parser("update", help="读取更新记录表结构")
|
|
38
46
|
schema_update.add_argument("--app-key", required=True)
|
|
39
47
|
schema_update.add_argument("--record-id", required=True)
|
|
48
|
+
schema_update.add_argument("--view-id")
|
|
40
49
|
schema_update.set_defaults(handler=_handle_schema_update, format_hint="")
|
|
41
50
|
|
|
42
51
|
schema_import = schema_subparsers.add_parser("import", help="读取导入表结构")
|
|
@@ -102,27 +111,36 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
102
111
|
get.add_argument("--view-id")
|
|
103
112
|
get.set_defaults(handler=_handle_get, format_hint="record_get")
|
|
104
113
|
|
|
114
|
+
logs = record_subparsers.add_parser("logs", help="读取单条记录全量日志并写入本地 JSONL")
|
|
115
|
+
logs.add_argument("--app-key", required=True)
|
|
116
|
+
logs.add_argument("--record-id", required=True)
|
|
117
|
+
logs.add_argument("--view-id", required=True)
|
|
118
|
+
logs.set_defaults(handler=_handle_logs, format_hint="record_logs")
|
|
119
|
+
|
|
105
120
|
insert = record_subparsers.add_parser("insert", help="新增记录")
|
|
106
121
|
insert.add_argument("--app-key", required=True)
|
|
107
122
|
insert.add_argument("--fields-file", help=argparse.SUPPRESS)
|
|
108
123
|
insert.add_argument("--items-file")
|
|
109
124
|
insert.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
|
|
110
|
-
insert.set_defaults(handler=_handle_insert, format_hint="")
|
|
125
|
+
insert.set_defaults(handler=_handle_insert, format_hint="record_write")
|
|
111
126
|
|
|
112
127
|
update = record_subparsers.add_parser("update", help="更新记录")
|
|
113
128
|
update.add_argument("--app-key", required=True)
|
|
114
129
|
update.add_argument("--record-id")
|
|
115
130
|
update.add_argument("--fields-file")
|
|
116
131
|
update.add_argument("--items-file")
|
|
132
|
+
update.add_argument("--view-id")
|
|
117
133
|
update.add_argument("--dry-run", action=argparse.BooleanOptionalAction, default=False)
|
|
118
134
|
update.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
|
|
119
|
-
update.set_defaults(handler=_handle_update, format_hint="")
|
|
135
|
+
update.set_defaults(handler=_handle_update, format_hint="record_write")
|
|
120
136
|
|
|
121
137
|
delete = record_subparsers.add_parser("delete", help="删除记录")
|
|
122
138
|
delete.add_argument("--app-key", required=True)
|
|
123
139
|
delete.add_argument("--record-id")
|
|
124
140
|
delete.add_argument("--record-ids-file")
|
|
125
|
-
delete.
|
|
141
|
+
delete.add_argument("--view-id")
|
|
142
|
+
delete.add_argument("--list-type", dest="legacy_list_type", type=int, help=argparse.SUPPRESS)
|
|
143
|
+
delete.set_defaults(handler=_handle_delete, format_hint="record_delete")
|
|
126
144
|
|
|
127
145
|
analyze = record_subparsers.add_parser("analyze", help=argparse.SUPPRESS)
|
|
128
146
|
record_subparsers._choices_actions = [ # type: ignore[attr-defined]
|
|
@@ -147,6 +165,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
147
165
|
code_block.add_argument("--app-key", required=True)
|
|
148
166
|
code_block.add_argument("--record-id", required=True)
|
|
149
167
|
code_block.add_argument("--code-block-field", required=True)
|
|
168
|
+
code_block.add_argument("--view-id")
|
|
150
169
|
code_block.add_argument("--role", type=int, default=1)
|
|
151
170
|
code_block.add_argument("--workflow-node-id", type=int)
|
|
152
171
|
code_block.add_argument("--answers-file")
|
|
@@ -155,7 +174,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
155
174
|
code_block.add_argument("--apply-writeback", action=argparse.BooleanOptionalAction, default=True)
|
|
156
175
|
code_block.add_argument("--verify-writeback", action=argparse.BooleanOptionalAction, default=True)
|
|
157
176
|
code_block.add_argument("--force-refresh-form", action="store_true")
|
|
158
|
-
code_block.set_defaults(handler=_handle_code_block_run, format_hint="")
|
|
177
|
+
code_block.set_defaults(handler=_handle_code_block_run, format_hint="code_block_run")
|
|
159
178
|
|
|
160
179
|
|
|
161
180
|
def _columns(args: argparse.Namespace) -> list[Any]:
|
|
@@ -176,20 +195,20 @@ def _handle_schema_root(args: argparse.Namespace, _context: CliContext) -> dict:
|
|
|
176
195
|
mode = (args.legacy_mode or "").strip()
|
|
177
196
|
if mode:
|
|
178
197
|
replacement = {
|
|
179
|
-
"applicant": "record schema
|
|
198
|
+
"applicant": "record schema insert --app-key APP_KEY",
|
|
180
199
|
"browse": "record schema browse --app-key APP_KEY --view-id VIEW_ID",
|
|
181
200
|
"insert": "record schema insert --app-key APP_KEY",
|
|
182
|
-
"update": "record schema update --app-key APP_KEY --record-id RECORD_ID",
|
|
201
|
+
"update": "record schema update --app-key APP_KEY --record-id RECORD_ID [--view-id VIEW_ID]",
|
|
183
202
|
"import": "record schema import --app-key APP_KEY",
|
|
184
203
|
"code-block": "record schema code-block --app-key APP_KEY",
|
|
185
|
-
}.get(mode, "record schema <
|
|
204
|
+
}.get(mode, "record schema <browse|insert|update|import|code-block> ...")
|
|
186
205
|
raise_config_error(
|
|
187
206
|
"record schema --mode is no longer accepted.",
|
|
188
207
|
fix_hint=f"Use `{replacement}` instead.",
|
|
189
208
|
)
|
|
190
209
|
raise_config_error(
|
|
191
210
|
"record schema requires an explicit subcommand.",
|
|
192
|
-
fix_hint="Use one of: `record schema
|
|
211
|
+
fix_hint="Use one of: `record schema browse`, `record schema insert`, `record schema update`, `record schema import`, or `record schema code-block`.",
|
|
193
212
|
)
|
|
194
213
|
|
|
195
214
|
|
|
@@ -218,6 +237,7 @@ def _handle_schema_update(args: argparse.Namespace, context: CliContext) -> dict
|
|
|
218
237
|
profile=args.profile,
|
|
219
238
|
app_key=args.app_key,
|
|
220
239
|
record_id=args.record_id,
|
|
240
|
+
view_id=args.view_id,
|
|
221
241
|
)
|
|
222
242
|
|
|
223
243
|
|
|
@@ -328,6 +348,15 @@ def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
328
348
|
)
|
|
329
349
|
|
|
330
350
|
|
|
351
|
+
def _handle_logs(args: argparse.Namespace, context: CliContext) -> dict:
|
|
352
|
+
return context.record.record_logs_get(
|
|
353
|
+
profile=args.profile,
|
|
354
|
+
app_key=args.app_key,
|
|
355
|
+
record_id=args.record_id,
|
|
356
|
+
view_id=args.view_id,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
|
|
331
360
|
def _handle_insert(args: argparse.Namespace, context: CliContext) -> dict:
|
|
332
361
|
if args.items_file:
|
|
333
362
|
if args.fields_file:
|
|
@@ -367,6 +396,7 @@ def _handle_update(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
367
396
|
record_id=None,
|
|
368
397
|
fields=None,
|
|
369
398
|
items=require_list_arg(args.items_file, option_name="--items-file"),
|
|
399
|
+
view_id=args.view_id,
|
|
370
400
|
dry_run=bool(args.dry_run),
|
|
371
401
|
verify_write=bool(args.verify_write),
|
|
372
402
|
)
|
|
@@ -385,17 +415,29 @@ def _handle_update(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
385
415
|
app_key=args.app_key,
|
|
386
416
|
record_id=args.record_id,
|
|
387
417
|
fields=require_object_arg(args.fields_file, option_name="--fields-file"),
|
|
418
|
+
view_id=args.view_id,
|
|
388
419
|
verify_write=bool(args.verify_write),
|
|
389
420
|
)
|
|
390
421
|
|
|
391
422
|
|
|
392
423
|
def _handle_delete(args: argparse.Namespace, context: CliContext) -> dict:
|
|
424
|
+
if args.legacy_list_type is not None:
|
|
425
|
+
raise_config_error(
|
|
426
|
+
"record delete no longer accepts list_type.",
|
|
427
|
+
fix_hint="Call `app_get` first and pass an accessible system `view_id`, for example `--view-id system:all`.",
|
|
428
|
+
)
|
|
429
|
+
if not (args.view_id or "").strip():
|
|
430
|
+
raise_config_error(
|
|
431
|
+
"record delete requires --view-id.",
|
|
432
|
+
fix_hint="Use a system view_id from app get accessible_views, for example `--view-id system:all`; custom views are not supported for deletion.",
|
|
433
|
+
)
|
|
393
434
|
record_ids = load_list_arg(args.record_ids_file, option_name="--record-ids-file")
|
|
394
435
|
return context.record.record_delete_public(
|
|
395
436
|
profile=args.profile,
|
|
396
437
|
app_key=args.app_key,
|
|
397
438
|
record_id=args.record_id,
|
|
398
439
|
record_ids=record_ids,
|
|
440
|
+
view_id=args.view_id,
|
|
399
441
|
)
|
|
400
442
|
|
|
401
443
|
|
|
@@ -431,6 +473,7 @@ def _handle_code_block_run(args: argparse.Namespace, context: CliContext) -> dic
|
|
|
431
473
|
app_key=args.app_key,
|
|
432
474
|
record_id=args.record_id,
|
|
433
475
|
code_block_field=args.code_block_field,
|
|
476
|
+
view_id=args.view_id,
|
|
434
477
|
role=args.role,
|
|
435
478
|
workflow_node_id=args.workflow_node_id,
|
|
436
479
|
answers=load_list_arg(args.answers_file, option_name="--answers-file"),
|
|
@@ -13,7 +13,6 @@ from ..tools.feedback_tools import FeedbackTools
|
|
|
13
13
|
from ..tools.file_tools import FileTools
|
|
14
14
|
from ..tools.import_tools import ImportTools
|
|
15
15
|
from ..tools.record_tools import RecordTools
|
|
16
|
-
from ..tools.repository_dev_tools import RepositoryDevTools
|
|
17
16
|
from ..tools.resource_read_tools import ResourceReadTools
|
|
18
17
|
from ..tools.task_context_tools import TaskContextTools
|
|
19
18
|
from ..tools.workspace_tools import WorkspaceTools
|
|
@@ -35,7 +34,6 @@ class CliContext:
|
|
|
35
34
|
files: FileTools
|
|
36
35
|
builder_feedback: FeedbackTools
|
|
37
36
|
builder: AiBuilderTools
|
|
38
|
-
repo: RepositoryDevTools
|
|
39
37
|
|
|
40
38
|
def close(self) -> None:
|
|
41
39
|
self.backend.close()
|
|
@@ -59,5 +57,4 @@ def build_cli_context() -> CliContext:
|
|
|
59
57
|
files=FileTools(sessions, backend),
|
|
60
58
|
builder_feedback=FeedbackTools(backend, mcp_side="App Builder MCP"),
|
|
61
59
|
builder=AiBuilderTools(sessions, backend),
|
|
62
|
-
repo=RepositoryDevTools(sessions, backend),
|
|
63
60
|
)
|