@qingflow-tech/qingflow-app-builder-mcp 1.0.18 → 1.0.20
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
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.
|
|
6
|
+
npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.20
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.
|
|
12
|
+
npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.20 qingflow-app-builder-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -20,7 +20,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
20
20
|
file_upload_local.add_argument("--bucket-type")
|
|
21
21
|
file_upload_local.add_argument("--path-id", type=int)
|
|
22
22
|
file_upload_local.add_argument("--file-related-url")
|
|
23
|
-
file_upload_local.set_defaults(handler=_handle_file_upload_local, format_hint="
|
|
23
|
+
file_upload_local.set_defaults(handler=_handle_file_upload_local, format_hint="file_upload_local")
|
|
24
24
|
|
|
25
25
|
feedback = builder_subparsers.add_parser("feedback", help="builder 侧反馈提交")
|
|
26
26
|
feedback_subparsers = feedback.add_subparsers(dest="builder_feedback_command", required=True)
|
|
@@ -82,7 +82,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
82
82
|
|
|
83
83
|
log = task_subparsers.add_parser("log", help="读取流程日志;--task-id 必须来自 task list 的 data.items[].task_id")
|
|
84
84
|
log.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
|
|
85
|
-
log.set_defaults(handler=_handle_log, format_hint="", app_key="", record_id="", workflow_node_id=0)
|
|
85
|
+
log.set_defaults(handler=_handle_log, format_hint="task_workflow_log_get", app_key="", record_id="", workflow_node_id=0)
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
@@ -566,6 +566,50 @@ def _format_task_get(result: dict[str, Any]) -> str:
|
|
|
566
566
|
return "\n".join(lines) + "\n"
|
|
567
567
|
|
|
568
568
|
|
|
569
|
+
def _format_task_workflow_log(result: dict[str, Any]) -> str:
|
|
570
|
+
data = result.get("data") if isinstance(result.get("data"), dict) else {}
|
|
571
|
+
selection = data.get("selection") if isinstance(data.get("selection"), dict) else {}
|
|
572
|
+
visibility = data.get("visibility") if isinstance(data.get("visibility"), dict) else {}
|
|
573
|
+
items = data.get("items") if isinstance(data.get("items"), list) else []
|
|
574
|
+
lines: list[str] = []
|
|
575
|
+
if selection.get("task_id") not in (None, ""):
|
|
576
|
+
lines.append(f"Task ID: {selection.get('task_id')}")
|
|
577
|
+
locator = " / ".join(
|
|
578
|
+
str(value or "-")
|
|
579
|
+
for value in (
|
|
580
|
+
selection.get("app_key"),
|
|
581
|
+
selection.get("record_id"),
|
|
582
|
+
selection.get("workflow_node_id"),
|
|
583
|
+
)
|
|
584
|
+
)
|
|
585
|
+
if locator != "- / - / -":
|
|
586
|
+
lines.append(f"Locator: {locator}")
|
|
587
|
+
if visibility:
|
|
588
|
+
lines.append(
|
|
589
|
+
"Visibility: "
|
|
590
|
+
f"audit_record={visibility.get('audit_record_visible')} / "
|
|
591
|
+
f"qrobot_record={visibility.get('qrobot_record_visible')}"
|
|
592
|
+
)
|
|
593
|
+
lines.append(f"Workflow Logs: {len(items)}")
|
|
594
|
+
for item in items[:20]:
|
|
595
|
+
if not isinstance(item, dict):
|
|
596
|
+
continue
|
|
597
|
+
operator = item.get("operator") if isinstance(item.get("operator"), dict) else {}
|
|
598
|
+
operator_name = operator.get("name") or operator.get("email") or operator.get("uid") or "-"
|
|
599
|
+
parts = [
|
|
600
|
+
str(item.get("operation_time") or "-"),
|
|
601
|
+
str(item.get("node_name") or item.get("node_id") or "-"),
|
|
602
|
+
str(operator_name),
|
|
603
|
+
str(item.get("remark") or item.get("operation") or "-"),
|
|
604
|
+
]
|
|
605
|
+
lines.append("- " + " / ".join(parts))
|
|
606
|
+
if len(items) > 20:
|
|
607
|
+
lines.append(f"... {len(items) - 20} more")
|
|
608
|
+
_append_warnings(lines, result.get("warnings"))
|
|
609
|
+
_append_verification(lines, result.get("verification"))
|
|
610
|
+
return "\n".join(lines) + "\n"
|
|
611
|
+
|
|
612
|
+
|
|
569
613
|
def _format_task_action(result: dict[str, Any]) -> str:
|
|
570
614
|
data = result.get("data") if isinstance(result.get("data"), dict) else {}
|
|
571
615
|
action = str(data.get("action") or "").strip().lower()
|
|
@@ -882,6 +926,47 @@ def _format_builder_summary(result: dict[str, Any]) -> str:
|
|
|
882
926
|
return "\n".join(lines) + "\n"
|
|
883
927
|
|
|
884
928
|
|
|
929
|
+
def _format_file_upload_local(result: dict[str, Any]) -> str:
|
|
930
|
+
lines = [
|
|
931
|
+
f"Upload Kind: {result.get('upload_kind') or result.get('requested_upload_kind') or '-'}",
|
|
932
|
+
f"Effective Upload Kind: {result.get('effective_upload_kind') or result.get('upload_kind') or '-'}",
|
|
933
|
+
]
|
|
934
|
+
if "upload_fallback_applied" in result:
|
|
935
|
+
lines.append(f"Fallback Applied: {result.get('upload_fallback_applied')}")
|
|
936
|
+
if result.get("upload_fallback_reason"):
|
|
937
|
+
lines.append(f"Fallback Reason: {result.get('upload_fallback_reason')}")
|
|
938
|
+
if result.get("file_name"):
|
|
939
|
+
lines.append(f"File: {result.get('file_name')}")
|
|
940
|
+
if result.get("file_size") is not None:
|
|
941
|
+
lines.append(f"Size: {result.get('file_size')}")
|
|
942
|
+
if result.get("content_type"):
|
|
943
|
+
lines.append(f"Content Type: {result.get('content_type')}")
|
|
944
|
+
if result.get("upload_protocol"):
|
|
945
|
+
lines.append(f"Protocol: {result.get('upload_protocol')}")
|
|
946
|
+
if result.get("download_url"):
|
|
947
|
+
lines.append(f"Download URL: {result.get('download_url')}")
|
|
948
|
+
|
|
949
|
+
attachment_value = result.get("attachment_value") if isinstance(result.get("attachment_value"), dict) else {}
|
|
950
|
+
if attachment_value:
|
|
951
|
+
lines.append("Attachment Value:")
|
|
952
|
+
for key in ("value", "name", "otherInfo"):
|
|
953
|
+
value = attachment_value.get(key)
|
|
954
|
+
if value not in (None, ""):
|
|
955
|
+
lines.append(f"- {key}: {value}")
|
|
956
|
+
|
|
957
|
+
comment_file_info = result.get("comment_file_info") if isinstance(result.get("comment_file_info"), dict) else {}
|
|
958
|
+
if comment_file_info:
|
|
959
|
+
lines.append("Comment File:")
|
|
960
|
+
for key in ("url", "name", "uploadFileSize"):
|
|
961
|
+
value = comment_file_info.get(key)
|
|
962
|
+
if value not in (None, ""):
|
|
963
|
+
lines.append(f"- {key}: {value}")
|
|
964
|
+
|
|
965
|
+
_append_warnings(lines, result.get("warnings"))
|
|
966
|
+
_append_verification(lines, result.get("verification"))
|
|
967
|
+
return "\n".join(lines) + "\n"
|
|
968
|
+
|
|
969
|
+
|
|
885
970
|
def emit_json_result(result: dict[str, Any], *, stream: TextIO) -> None:
|
|
886
971
|
json.dump(result, stream, ensure_ascii=False, indent=2)
|
|
887
972
|
stream.write("\n")
|
|
@@ -1078,6 +1163,7 @@ _FORMATTERS = {
|
|
|
1078
1163
|
"task_list": _format_task_list,
|
|
1079
1164
|
"task_workbench": _format_task_workbench,
|
|
1080
1165
|
"task_get": _format_task_get,
|
|
1166
|
+
"task_workflow_log_get": _format_task_workflow_log,
|
|
1081
1167
|
"task_action_execute": _format_task_action,
|
|
1082
1168
|
"task_associated_report_detail_get": _format_task_associated_report_detail,
|
|
1083
1169
|
"import_template": _format_import_template,
|
|
@@ -1090,4 +1176,5 @@ _FORMATTERS = {
|
|
|
1090
1176
|
"export_get": _format_export_get,
|
|
1091
1177
|
"export_direct": _format_export_direct,
|
|
1092
1178
|
"builder_summary": _format_builder_summary,
|
|
1179
|
+
"file_upload_local": _format_file_upload_local,
|
|
1093
1180
|
}
|