@josephyan/qingflow-cli 0.2.0-beta.984 → 0.2.0-beta.986

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 (43) hide show
  1. package/README.md +2 -2
  2. package/docs/local-agent-install.md +70 -11
  3. package/package.json +1 -1
  4. package/pyproject.toml +1 -1
  5. package/src/qingflow_mcp/__init__.py +1 -1
  6. package/src/qingflow_mcp/builder_facade/service.py +47 -21
  7. package/src/qingflow_mcp/cli/commands/auth.py +14 -43
  8. package/src/qingflow_mcp/cli/commands/task.py +4 -1
  9. package/src/qingflow_mcp/cli/commands/workspace.py +0 -8
  10. package/src/qingflow_mcp/cli/formatters.py +0 -21
  11. package/src/qingflow_mcp/config.py +39 -0
  12. package/src/qingflow_mcp/errors.py +2 -2
  13. package/src/qingflow_mcp/public_surface.py +2 -6
  14. package/src/qingflow_mcp/response_trim.py +1 -8
  15. package/src/qingflow_mcp/server.py +1 -1
  16. package/src/qingflow_mcp/server_app_builder.py +4 -28
  17. package/src/qingflow_mcp/server_app_user.py +4 -28
  18. package/src/qingflow_mcp/session_store.py +31 -5
  19. package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
  20. package/src/qingflow_mcp/tools/app_tools.py +51 -1
  21. package/src/qingflow_mcp/tools/approval_tools.py +82 -1
  22. package/src/qingflow_mcp/tools/auth_tools.py +258 -288
  23. package/src/qingflow_mcp/tools/base.py +204 -4
  24. package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
  25. package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
  26. package/src/qingflow_mcp/tools/directory_tools.py +28 -1
  27. package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
  28. package/src/qingflow_mcp/tools/file_tools.py +25 -1
  29. package/src/qingflow_mcp/tools/import_tools.py +40 -1
  30. package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
  31. package/src/qingflow_mcp/tools/package_tools.py +37 -1
  32. package/src/qingflow_mcp/tools/portal_tools.py +28 -1
  33. package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
  34. package/src/qingflow_mcp/tools/record_tools.py +255 -2
  35. package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
  36. package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
  37. package/src/qingflow_mcp/tools/role_tools.py +19 -1
  38. package/src/qingflow_mcp/tools/solution_tools.py +56 -1
  39. package/src/qingflow_mcp/tools/task_context_tools.py +205 -6
  40. package/src/qingflow_mcp/tools/task_tools.py +49 -3
  41. package/src/qingflow_mcp/tools/view_tools.py +56 -1
  42. package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
  43. package/src/qingflow_mcp/tools/workspace_tools.py +14 -225
@@ -7,7 +7,7 @@ from mcp.server.fastmcp import FastMCP
7
7
  from ..config import DEFAULT_PROFILE
8
8
  from ..errors import QingflowApiError, raise_tool_error
9
9
  from ..list_type_labels import get_record_list_type_label, get_task_type_label
10
- from .base import ToolBase
10
+ from .base import ToolBase, tool_cn_name
11
11
 
12
12
  TASK_BOX_TO_TYPE = {
13
13
  "todo": 1,
@@ -31,7 +31,9 @@ FLOW_STATUS_TO_PROCESS_STATUS = {
31
31
 
32
32
 
33
33
  class TaskTools(ToolBase):
34
- """任务中心(待办/已办)相关工具
34
+ """任务中心工具(中文名:任务列表与操作)
35
+
36
+ 类型:流程任务运营工具。
35
37
 
36
38
  提供对工作流任务的管理功能,包括:
37
39
  - 查询待办/已办列表
@@ -59,6 +61,7 @@ class TaskTools(ToolBase):
59
61
  """
60
62
 
61
63
  def register(self, mcp: FastMCP) -> None:
64
+ """注册当前工具到 MCP 服务。"""
62
65
  @mcp.tool()
63
66
  def task_summary(
64
67
  profile: str = DEFAULT_PROFILE,
@@ -139,12 +142,14 @@ class TaskTools(ToolBase):
139
142
  ) -> dict[str, Any]:
140
143
  return self.task_urge_public(profile=profile, app_key=app_key, record_id=record_id)
141
144
 
145
+ @tool_cn_name("任务摘要")
142
146
  def task_summary(
143
147
  self,
144
148
  *,
145
149
  profile: str,
146
150
  app_key: str | None,
147
151
  ) -> dict[str, Any]:
152
+ """执行任务相关逻辑。"""
148
153
  raw = self.task_statistics(profile=profile, app_key=app_key)
149
154
  statistics = raw.get("statistics", {})
150
155
  summary = self._normalize_task_summary_payload(statistics)
@@ -160,6 +165,7 @@ class TaskTools(ToolBase):
160
165
  },
161
166
  }
162
167
 
168
+ @tool_cn_name("任务列表")
163
169
  def task_list_public(
164
170
  self,
165
171
  *,
@@ -174,6 +180,7 @@ class TaskTools(ToolBase):
174
180
  sort_by: str | None,
175
181
  sort_direction: str,
176
182
  ) -> dict[str, Any]:
183
+ """执行任务相关逻辑。"""
177
184
  normalized_type = self._task_box_to_type(task_box)
178
185
  normalized_status = self._flow_status_to_process_status(flow_status)
179
186
  create_time_asc = self._task_sort_to_create_time_asc(sort_by, sort_direction)
@@ -216,6 +223,7 @@ class TaskTools(ToolBase):
216
223
  },
217
224
  }
218
225
 
226
+ @tool_cn_name("任务分面统计")
219
227
  def task_facets(
220
228
  self,
221
229
  *,
@@ -227,6 +235,7 @@ class TaskTools(ToolBase):
227
235
  query: str | None,
228
236
  limit: int,
229
237
  ) -> dict[str, Any]:
238
+ """执行任务相关逻辑。"""
230
239
  normalized_type = self._task_box_to_type(task_box)
231
240
  normalized_status = self._flow_status_to_process_status(flow_status)
232
241
  if dimension not in {"worksheet", "workflow_node"}:
@@ -288,6 +297,7 @@ class TaskTools(ToolBase):
288
297
  },
289
298
  }
290
299
 
300
+ @tool_cn_name("任务标记已读")
291
301
  def task_mark_read_public(
292
302
  self,
293
303
  *,
@@ -296,6 +306,7 @@ class TaskTools(ToolBase):
296
306
  task_id: int,
297
307
  task_box: str,
298
308
  ) -> dict[str, Any]:
309
+ """执行任务相关逻辑。"""
299
310
  raw = self.task_mark_read(profile=profile, app_key=app_key, id=task_id, type=self._task_box_to_type(task_box))
300
311
  return self._public_task_action_response(
301
312
  raw,
@@ -304,12 +315,14 @@ class TaskTools(ToolBase):
304
315
  selection={"task_box": task_box},
305
316
  )
306
317
 
318
+ @tool_cn_name("抄送全部已读")
307
319
  def task_mark_all_cc_read_public(
308
320
  self,
309
321
  *,
310
322
  profile: str,
311
323
  flow_status: str,
312
324
  ) -> dict[str, Any]:
325
+ """执行任务相关逻辑。"""
313
326
  raw = self.task_mark_all_cc_read(profile=profile, type=TASK_BOX_TO_TYPE["cc"], process_status=self._flow_status_to_process_status(flow_status))
314
327
  return self._public_task_action_response(
315
328
  raw,
@@ -318,6 +331,7 @@ class TaskTools(ToolBase):
318
331
  selection={"task_box": "cc", "flow_status": flow_status},
319
332
  )
320
333
 
334
+ @tool_cn_name("任务催办")
321
335
  def task_urge_public(
322
336
  self,
323
337
  *,
@@ -325,6 +339,7 @@ class TaskTools(ToolBase):
325
339
  app_key: str,
326
340
  record_id: int,
327
341
  ) -> dict[str, Any]:
342
+ """执行任务相关逻辑。"""
328
343
  raw = self.task_urge(profile=profile, app_key=app_key, row_record_id=record_id)
329
344
  return self._public_task_action_response(
330
345
  raw,
@@ -333,6 +348,7 @@ class TaskTools(ToolBase):
333
348
  selection={},
334
349
  )
335
350
 
351
+ @tool_cn_name("任务列表(兼容)")
336
352
  def task_list(
337
353
  self,
338
354
  *,
@@ -346,9 +362,9 @@ class TaskTools(ToolBase):
346
362
  page_size: int,
347
363
  create_time_asc: bool | None,
348
364
  ) -> dict[str, Any]:
365
+ """执行任务相关逻辑。"""
349
366
  self._validate_type(type)
350
367
  self._validate_process_status(process_status)
351
-
352
368
  def runner(session_profile, context):
353
369
  payload: dict[str, Any] = {
354
370
  "type": type,
@@ -379,6 +395,7 @@ class TaskTools(ToolBase):
379
395
 
380
396
  return self._run(profile, runner)
381
397
 
398
+ @tool_cn_name("任务分组列表")
382
399
  def task_list_grouped(
383
400
  self,
384
401
  *,
@@ -391,6 +408,7 @@ class TaskTools(ToolBase):
391
408
  page_num: int,
392
409
  page_size: int,
393
410
  ) -> dict[str, Any]:
411
+ """执行任务相关逻辑。"""
394
412
  self._validate_type(type)
395
413
  self._validate_process_status(process_status)
396
414
 
@@ -422,12 +440,14 @@ class TaskTools(ToolBase):
422
440
 
423
441
  return self._run(profile, runner)
424
442
 
443
+ @tool_cn_name("任务统计")
425
444
  def task_statistics(
426
445
  self,
427
446
  *,
428
447
  profile: str,
429
448
  app_key: str | None,
430
449
  ) -> dict[str, Any]:
450
+ """执行任务相关逻辑。"""
431
451
  def runner(session_profile, context):
432
452
  params: dict[str, Any] = {}
433
453
  if app_key:
@@ -443,6 +463,7 @@ class TaskTools(ToolBase):
443
463
 
444
464
  return self._run(profile, runner)
445
465
 
466
+ @tool_cn_name("任务流程节点")
446
467
  def task_workflow_nodes(
447
468
  self,
448
469
  *,
@@ -454,6 +475,7 @@ class TaskTools(ToolBase):
454
475
  page_num: int,
455
476
  page_size: int,
456
477
  ) -> dict[str, Any]:
478
+ """执行任务相关逻辑。"""
457
479
  self._validate_type(type)
458
480
 
459
481
  def runner(session_profile, context):
@@ -482,6 +504,7 @@ class TaskTools(ToolBase):
482
504
 
483
505
  return self._run(profile, runner)
484
506
 
507
+ @tool_cn_name("任务节点统计")
485
508
  def task_node_statistics(
486
509
  self,
487
510
  *,
@@ -490,6 +513,7 @@ class TaskTools(ToolBase):
490
513
  type: int,
491
514
  search_key: str | None,
492
515
  ) -> dict[str, Any]:
516
+ """执行任务相关逻辑。"""
493
517
  self._validate_type(type)
494
518
  if not app_key:
495
519
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
@@ -516,6 +540,7 @@ class TaskTools(ToolBase):
516
540
 
517
541
  return self._run(profile, runner)
518
542
 
543
+ @tool_cn_name("任务应用统计")
519
544
  def task_worksheet_statistics(
520
545
  self,
521
546
  *,
@@ -525,6 +550,7 @@ class TaskTools(ToolBase):
525
550
  page_num: int,
526
551
  page_size: int,
527
552
  ) -> dict[str, Any]:
553
+ """执行任务相关逻辑。"""
528
554
  self._validate_type(type)
529
555
 
530
556
  def runner(session_profile, context):
@@ -549,6 +575,7 @@ class TaskTools(ToolBase):
549
575
 
550
576
  return self._run(profile, runner)
551
577
 
578
+ @tool_cn_name("任务已读(兼容)")
552
579
  def task_mark_read(
553
580
  self,
554
581
  *,
@@ -557,6 +584,7 @@ class TaskTools(ToolBase):
557
584
  id: int,
558
585
  type: int,
559
586
  ) -> dict[str, Any]:
587
+ """执行任务相关逻辑。"""
560
588
  if not app_key:
561
589
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
562
590
  if id <= 0:
@@ -583,6 +611,7 @@ class TaskTools(ToolBase):
583
611
 
584
612
  return self._run(profile, runner)
585
613
 
614
+ @tool_cn_name("抄送已读(兼容)")
586
615
  def task_mark_all_cc_read(
587
616
  self,
588
617
  *,
@@ -590,6 +619,7 @@ class TaskTools(ToolBase):
590
619
  type: int,
591
620
  process_status: int,
592
621
  ) -> dict[str, Any]:
622
+ """执行任务相关逻辑。"""
593
623
  self._validate_type(type)
594
624
  self._validate_process_status(process_status)
595
625
 
@@ -612,6 +642,7 @@ class TaskTools(ToolBase):
612
642
 
613
643
  return self._run(profile, runner)
614
644
 
645
+ @tool_cn_name("任务催办(兼容)")
615
646
  def task_urge(
616
647
  self,
617
648
  *,
@@ -619,6 +650,7 @@ class TaskTools(ToolBase):
619
650
  app_key: str,
620
651
  row_record_id: int,
621
652
  ) -> dict[str, Any]:
653
+ """执行任务相关逻辑。"""
622
654
  if not app_key:
623
655
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
624
656
  if row_record_id <= 0:
@@ -641,6 +673,7 @@ class TaskTools(ToolBase):
641
673
 
642
674
  return self._run(profile, runner)
643
675
 
676
+ @tool_cn_name("任务分组详情")
644
677
  def task_group_detail(
645
678
  self,
646
679
  *,
@@ -648,6 +681,7 @@ class TaskTools(ToolBase):
648
681
  app_key: str,
649
682
  group_id: int,
650
683
  ) -> dict[str, Any]:
684
+ """执行任务相关逻辑。"""
651
685
  if not app_key:
652
686
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
653
687
  if group_id <= 0:
@@ -670,6 +704,7 @@ class TaskTools(ToolBase):
670
704
 
671
705
  return self._run(profile, runner)
672
706
 
707
+ @tool_cn_name("批处理任务数量")
673
708
  def task_batch_processing_amount(
674
709
  self,
675
710
  *,
@@ -678,6 +713,7 @@ class TaskTools(ToolBase):
678
713
  list_type: int,
679
714
  task_center_filter: dict[str, Any] | None,
680
715
  ) -> dict[str, Any]:
716
+ """执行任务相关逻辑。"""
681
717
  if not app_key:
682
718
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
683
719
 
@@ -707,6 +743,7 @@ class TaskTools(ToolBase):
707
743
  return self._run(profile, runner)
708
744
 
709
745
  def _validate_type(self, type: int) -> None:
746
+ """执行内部辅助逻辑。"""
710
747
  valid_types = [1, 2, 3, 5] # TODO, INITIATED, CC, DONE
711
748
  if type not in valid_types:
712
749
  raise_tool_error(
@@ -716,6 +753,7 @@ class TaskTools(ToolBase):
716
753
  )
717
754
 
718
755
  def _validate_process_status(self, process_status: int) -> None:
756
+ """执行内部辅助逻辑。"""
719
757
  valid_statuses = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
720
758
  if process_status not in valid_statuses:
721
759
  raise_tool_error(
@@ -725,12 +763,14 @@ class TaskTools(ToolBase):
725
763
  )
726
764
 
727
765
  def _task_box_to_type(self, task_box: str) -> int:
766
+ """执行内部辅助逻辑。"""
728
767
  normalized = (task_box or "").strip().lower()
729
768
  if normalized not in TASK_BOX_TO_TYPE:
730
769
  raise_tool_error(QingflowApiError.config_error("task_box must be todo, initiated, cc, or done"))
731
770
  return TASK_BOX_TO_TYPE[normalized]
732
771
 
733
772
  def _flow_status_to_process_status(self, flow_status: str) -> int:
773
+ """执行内部辅助逻辑。"""
734
774
  normalized = (flow_status or "").strip().lower()
735
775
  if normalized not in FLOW_STATUS_TO_PROCESS_STATUS:
736
776
  raise_tool_error(
@@ -741,6 +781,7 @@ class TaskTools(ToolBase):
741
781
  return FLOW_STATUS_TO_PROCESS_STATUS[normalized]
742
782
 
743
783
  def _task_sort_to_create_time_asc(self, sort_by: str | None, sort_direction: str) -> bool | None:
784
+ """执行内部辅助逻辑。"""
744
785
  normalized_sort_by = (sort_by or "").strip().lower() if sort_by is not None else ""
745
786
  normalized_direction = (sort_direction or "desc").strip().lower()
746
787
  if normalized_direction not in {"asc", "desc"}:
@@ -752,11 +793,13 @@ class TaskTools(ToolBase):
752
793
  return normalized_direction == "asc"
753
794
 
754
795
  def _task_applied_sort(self, sort_by: str | None, sort_direction: str) -> list[dict[str, Any]]:
796
+ """执行内部辅助逻辑。"""
755
797
  if not sort_by:
756
798
  return []
757
799
  return [{"by": "created_at", "order": (sort_direction or "desc").strip().lower()}]
758
800
 
759
801
  def _normalize_task_summary_payload(self, payload: Any) -> dict[str, Any]:
802
+ """执行内部辅助逻辑。"""
760
803
  if not isinstance(payload, dict):
761
804
  return {}
762
805
  return {
@@ -769,6 +812,7 @@ class TaskTools(ToolBase):
769
812
  }
770
813
 
771
814
  def _normalize_task_facets(self, payload: Any) -> list[dict[str, Any]]:
815
+ """执行内部辅助逻辑。"""
772
816
  items = _task_page_items(payload)
773
817
  groups: list[dict[str, Any]] = []
774
818
  for item in items:
@@ -788,6 +832,7 @@ class TaskTools(ToolBase):
788
832
  resource: dict[str, Any],
789
833
  selection: dict[str, Any],
790
834
  ) -> dict[str, Any]:
835
+ """执行内部辅助逻辑。"""
791
836
  response = dict(raw)
792
837
  response["ok"] = bool(raw.get("ok", True))
793
838
  response["warnings"] = []
@@ -801,6 +846,7 @@ class TaskTools(ToolBase):
801
846
  return response
802
847
 
803
848
  def _request_route_payload(self, context) -> dict[str, Any]: # type: ignore[no-untyped-def]
849
+ """执行内部辅助逻辑。"""
804
850
  describe_route = getattr(self.backend, "describe_route", None)
805
851
  if callable(describe_route):
806
852
  payload = describe_route(context)
@@ -5,11 +5,21 @@ from mcp.server.fastmcp import FastMCP
5
5
  from ..config import DEFAULT_PROFILE
6
6
  from ..errors import QingflowApiError, raise_tool_error
7
7
  from ..json_types import JSONObject, JSONValue
8
- from .base import ToolBase
8
+ from .base import ToolBase, tool_cn_name
9
9
 
10
10
 
11
11
  class ViewTools(ToolBase):
12
+ """视图工具(中文名:视图查询与配置读取)。
13
+
14
+ 类型:视图配置工具。
15
+ 主要职责:
16
+ 1. 查询应用视图列表;
17
+ 2. 获取视图配置与结构信息;
18
+ 3. 为记录查询和分析提供视图侧元数据。
19
+ """
20
+
12
21
  def register(self, mcp: FastMCP) -> None:
22
+ """注册当前工具到 MCP 服务。"""
13
23
  @mcp.tool()
14
24
  def view_list(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
15
25
  return self.view_list(profile=profile, app_key=app_key)
@@ -46,15 +56,21 @@ class ViewTools(ToolBase):
46
56
  def view_get_workflow_status(profile: str = DEFAULT_PROFILE, viewgraph_key: str = "", row_record_id: int = 0) -> JSONObject:
47
57
  return self.view_get_workflow_status(profile=profile, viewgraph_key=viewgraph_key, row_record_id=row_record_id)
48
58
 
59
+ @tool_cn_name("视图列表")
49
60
  def view_list(self, *, profile: str, app_key: str) -> JSONObject:
61
+ """执行视图相关逻辑。"""
50
62
  self._require_app_key(app_key)
51
63
  return self._request(profile, "GET", f"/app/{app_key}/view/viewList", app_key=app_key)
52
64
 
65
+ @tool_cn_name("视图列表(扁平)")
53
66
  def view_list_flat(self, *, profile: str, app_key: str) -> JSONObject:
67
+ """执行视图相关逻辑。"""
54
68
  self._require_app_key(app_key)
55
69
  return self._request(profile, "GET", f"/app/{app_key}/view/views", app_key=app_key)
56
70
 
71
+ @tool_cn_name("视图排序")
57
72
  def view_reorder(self, *, profile: str, app_key: str, payload: list[JSONObject]) -> JSONObject:
73
+ """执行视图相关逻辑。"""
58
74
  self._require_app_key(app_key)
59
75
  if not isinstance(payload, list) or not payload:
60
76
  raise_tool_error(QingflowApiError.config_error("payload must be a non-empty array"))
@@ -66,26 +82,36 @@ class ViewTools(ToolBase):
66
82
  json_body=self._normalize_reorder_payload(payload),
67
83
  )
68
84
 
85
+ @tool_cn_name("设置视图列宽")
69
86
  def view_set_column_width(self, *, profile: str, app_key: str, payload: JSONObject) -> JSONObject:
87
+ """执行视图相关逻辑。"""
70
88
  self._require_app_key(app_key)
71
89
  body = self._require_dict(payload)
72
90
  return self._request(profile, "POST", f"/app/{app_key}/view/que/width", app_key=app_key, json_body=body)
73
91
 
92
+ @tool_cn_name("创建视图")
74
93
  def view_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
94
+ """执行视图相关逻辑。"""
75
95
  body = self._require_dict(payload)
76
96
  app_key = str(body.get("appKey") or "")
77
97
  return self._request(profile, "POST", "/view/viewConfig", app_key=app_key, json_body=body)
78
98
 
99
+ @tool_cn_name("视图配置")
79
100
  def view_get_config(self, *, profile: str, viewgraph_key: str) -> JSONObject:
101
+ """执行视图相关逻辑。"""
80
102
  self._require_viewgraph_key(viewgraph_key)
81
103
  return self._request(profile, "GET", f"/view/{viewgraph_key}/viewConfig", viewgraph_key=viewgraph_key)
82
104
 
105
+ @tool_cn_name("视图基础信息")
83
106
  def view_get_base_info(self, *, profile: str, viewgraph_key: str, passcode: str | None) -> JSONObject:
107
+ """执行视图相关逻辑。"""
84
108
  self._require_viewgraph_key(viewgraph_key)
85
109
  params = {"pass": passcode} if passcode else None
86
110
  return self._request(profile, "GET", f"/view/{viewgraph_key}/viewConfig/baseInfo", viewgraph_key=viewgraph_key, params=params)
87
111
 
112
+ @tool_cn_name("更新视图配置")
88
113
  def view_update(self, *, profile: str, viewgraph_key: str, payload: JSONObject) -> JSONObject:
114
+ """执行视图相关逻辑。"""
89
115
  self._require_viewgraph_key(viewgraph_key)
90
116
  body = self._require_dict(payload)
91
117
  return self._request(
@@ -98,7 +124,9 @@ class ViewTools(ToolBase):
98
124
  risk_target="view configuration",
99
125
  )
100
126
 
127
+ @tool_cn_name("删除视图")
101
128
  def view_delete(self, *, profile: str, viewgraph_key: str) -> JSONObject:
129
+ """执行视图相关逻辑。"""
102
130
  self._require_viewgraph_key(viewgraph_key)
103
131
  return self._request(
104
132
  profile,
@@ -109,19 +137,27 @@ class ViewTools(ToolBase):
109
137
  risk_target="view configuration",
110
138
  )
111
139
 
140
+ @tool_cn_name("复制视图")
112
141
  def view_copy(self, *, profile: str, viewgraph_key: str) -> JSONObject:
142
+ """执行视图相关逻辑。"""
113
143
  self._require_viewgraph_key(viewgraph_key)
114
144
  return self._request(profile, "POST", f"/view/{viewgraph_key}/copy", viewgraph_key=viewgraph_key)
115
145
 
146
+ @tool_cn_name("视图字段列表")
116
147
  def view_list_questions(self, *, profile: str, viewgraph_key: str) -> JSONObject:
148
+ """执行视图相关逻辑。"""
117
149
  self._require_viewgraph_key(viewgraph_key)
118
150
  return self._request(profile, "GET", f"/view/{viewgraph_key}/question", viewgraph_key=viewgraph_key)
119
151
 
152
+ @tool_cn_name("视图关联列表")
120
153
  def view_list_associations(self, *, profile: str, viewgraph_key: str) -> JSONObject:
154
+ """执行视图相关逻辑。"""
121
155
  self._require_viewgraph_key(viewgraph_key)
122
156
  return self._request(profile, "GET", f"/view/{viewgraph_key}/association", viewgraph_key=viewgraph_key)
123
157
 
158
+ @tool_cn_name("更新视图成员配置")
124
159
  def view_update_member_config(self, *, profile: str, viewgraph_key: str, payload: JSONObject) -> JSONObject:
160
+ """执行视图相关逻辑。"""
125
161
  self._require_viewgraph_key(viewgraph_key)
126
162
  body = self._require_dict(payload)
127
163
  return self._request(
@@ -134,7 +170,9 @@ class ViewTools(ToolBase):
134
170
  risk_target="view member visibility",
135
171
  )
136
172
 
173
+ @tool_cn_name("更新视图数据配置")
137
174
  def view_update_apply_config(self, *, profile: str, viewgraph_key: str, payload: JSONObject) -> JSONObject:
175
+ """执行视图相关逻辑。"""
138
176
  self._require_viewgraph_key(viewgraph_key)
139
177
  body = self._require_dict(payload)
140
178
  return self._request(
@@ -147,7 +185,9 @@ class ViewTools(ToolBase):
147
185
  risk_target="view apply visibility",
148
186
  )
149
187
 
188
+ @tool_cn_name("看板泳道配置")
150
189
  def view_board_set_lane_config(self, *, profile: str, viewgraph_key: str, payload: JSONObject) -> JSONObject:
190
+ """执行视图相关逻辑。"""
151
191
  self._require_viewgraph_key(viewgraph_key)
152
192
  body = self._require_dict(payload)
153
193
  return self._request(
@@ -160,7 +200,9 @@ class ViewTools(ToolBase):
160
200
  risk_target="board lane configuration",
161
201
  )
162
202
 
203
+ @tool_cn_name("看板泳道基础信息")
163
204
  def view_board_get_lane_base_info(self, *, profile: str, viewgraph_key: str, page_num: int, page_size: int) -> JSONObject:
205
+ """执行视图相关逻辑。"""
164
206
  self._require_viewgraph_key(viewgraph_key)
165
207
  return self._request(
166
208
  profile,
@@ -170,7 +212,9 @@ class ViewTools(ToolBase):
170
212
  params={"pageNum": page_num, "pageSize": page_size},
171
213
  )
172
214
 
215
+ @tool_cn_name("甘特图自动校准")
173
216
  def view_gantt_switch_auto_calibration(self, *, profile: str, viewgraph_key: str, payload: JSONObject) -> JSONObject:
217
+ """执行视图相关逻辑。"""
174
218
  self._require_viewgraph_key(viewgraph_key)
175
219
  body = self._require_dict(payload)
176
220
  return self._request(
@@ -183,7 +227,9 @@ class ViewTools(ToolBase):
183
227
  risk_target="gantt auto calibration settings",
184
228
  )
185
229
 
230
+ @tool_cn_name("甘特图批量更新时间")
186
231
  def view_gantt_batch_update_time(self, *, profile: str, viewgraph_key: str, payload: JSONObject) -> JSONObject:
232
+ """执行视图相关逻辑。"""
187
233
  self._require_viewgraph_key(viewgraph_key)
188
234
  body = self._require_dict(payload)
189
235
  return self._request(
@@ -196,7 +242,9 @@ class ViewTools(ToolBase):
196
242
  risk_target="gantt task timing",
197
243
  )
198
244
 
245
+ @tool_cn_name("视图后续节点")
199
246
  def view_get_future_nodes(self, *, profile: str, viewgraph_key: str, apply_id: int, app_key: str) -> JSONObject:
247
+ """执行视图相关逻辑。"""
200
248
  self._require_viewgraph_key(viewgraph_key)
201
249
  self._require_app_key(app_key)
202
250
  self._require_positive("apply_id", apply_id)
@@ -210,7 +258,9 @@ class ViewTools(ToolBase):
210
258
  params={"appKey": app_key},
211
259
  )
212
260
 
261
+ @tool_cn_name("视图流程状态")
213
262
  def view_get_workflow_status(self, *, profile: str, viewgraph_key: str, row_record_id: int) -> JSONObject:
263
+ """执行视图相关逻辑。"""
214
264
  self._require_viewgraph_key(viewgraph_key)
215
265
  self._require_positive("row_record_id", row_record_id)
216
266
  return self._request(profile, "GET", f"/view/{viewgraph_key}/workflow/status/{row_record_id}", viewgraph_key=viewgraph_key, row_record_id=row_record_id)
@@ -227,6 +277,7 @@ class ViewTools(ToolBase):
227
277
  risk_target: str | None = None,
228
278
  **extra: JSONValue,
229
279
  ) -> JSONObject:
280
+ """执行内部辅助逻辑。"""
230
281
  def runner(session_profile, context):
231
282
  result = self.backend.request(method, context, path, json_body=json_body, params=params)
232
283
  response: JSONObject = {"profile": profile, "ws_id": session_profile.selected_ws_id, "result": result}
@@ -238,18 +289,22 @@ class ViewTools(ToolBase):
238
289
  return self._run(profile, runner)
239
290
 
240
291
  def _require_app_key(self, app_key: str) -> None:
292
+ """执行内部辅助逻辑。"""
241
293
  if not app_key:
242
294
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
243
295
 
244
296
  def _require_viewgraph_key(self, viewgraph_key: str) -> None:
297
+ """执行内部辅助逻辑。"""
245
298
  if not viewgraph_key:
246
299
  raise_tool_error(QingflowApiError.config_error("viewgraph_key is required"))
247
300
 
248
301
  def _require_positive(self, field_name: str, value: int) -> None:
302
+ """执行内部辅助逻辑。"""
249
303
  if value <= 0:
250
304
  raise_tool_error(QingflowApiError.config_error(f"{field_name} must be positive"))
251
305
 
252
306
  def _normalize_reorder_payload(self, payload: list[JSONObject]) -> list[JSONObject]:
307
+ """执行内部辅助逻辑。"""
253
308
  first_item = payload[0]
254
309
  if "ordinalType" in first_item and "viewKeyList" in first_item:
255
310
  return payload