@josephyan/qingflow-cli 0.2.0-beta.57 → 0.2.0-beta.59

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 (34) hide show
  1. package/README.md +3 -2
  2. package/docs/local-agent-install.md +9 -0
  3. package/npm/bin/qingflow.mjs +1 -1
  4. package/npm/lib/runtime.mjs +156 -21
  5. package/package.json +1 -1
  6. package/pyproject.toml +1 -1
  7. package/src/qingflow_mcp/builder_facade/service.py +137 -5
  8. package/src/qingflow_mcp/cli/commands/app.py +16 -16
  9. package/src/qingflow_mcp/cli/commands/auth.py +19 -16
  10. package/src/qingflow_mcp/cli/commands/builder.py +124 -162
  11. package/src/qingflow_mcp/cli/commands/common.py +21 -95
  12. package/src/qingflow_mcp/cli/commands/imports.py +42 -34
  13. package/src/qingflow_mcp/cli/commands/record.py +131 -133
  14. package/src/qingflow_mcp/cli/commands/task.py +43 -44
  15. package/src/qingflow_mcp/cli/commands/workspace.py +10 -10
  16. package/src/qingflow_mcp/cli/context.py +35 -32
  17. package/src/qingflow_mcp/cli/formatters.py +124 -121
  18. package/src/qingflow_mcp/cli/main.py +52 -17
  19. package/src/qingflow_mcp/server_app_builder.py +122 -190
  20. package/src/qingflow_mcp/server_app_user.py +63 -662
  21. package/src/qingflow_mcp/tools/solution_tools.py +95 -3
  22. package/src/qingflow_mcp/ops/__init__.py +0 -3
  23. package/src/qingflow_mcp/ops/apps.py +0 -64
  24. package/src/qingflow_mcp/ops/auth.py +0 -121
  25. package/src/qingflow_mcp/ops/base.py +0 -290
  26. package/src/qingflow_mcp/ops/builder.py +0 -323
  27. package/src/qingflow_mcp/ops/context.py +0 -120
  28. package/src/qingflow_mcp/ops/directory.py +0 -171
  29. package/src/qingflow_mcp/ops/feedback.py +0 -49
  30. package/src/qingflow_mcp/ops/files.py +0 -78
  31. package/src/qingflow_mcp/ops/imports.py +0 -140
  32. package/src/qingflow_mcp/ops/records.py +0 -415
  33. package/src/qingflow_mcp/ops/tasks.py +0 -171
  34. package/src/qingflow_mcp/ops/workspace.py +0 -76
@@ -5,200 +5,198 @@ from typing import Any
5
5
 
6
6
  from ...errors import QingflowApiError
7
7
  from ..context import CliContext
8
- from .common import add_field_args, add_file_arg, add_stdin_json_flag, load_list_input, load_object_input, merge_object_inputs
8
+ from .common import load_list_arg, load_object_arg, require_list_arg, require_object_arg
9
9
 
10
10
 
11
11
  def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
12
- parser = subparsers.add_parser("records", help="记录与表结构")
13
- record_subparsers = parser.add_subparsers(dest="records_command", required=True)
12
+ parser = subparsers.add_parser("record", help="记录与表结构")
13
+ record_subparsers = parser.add_subparsers(dest="record_command", required=True)
14
14
 
15
- schema = record_subparsers.add_parser("schema", help="读取记录表结构")
16
- schema.add_argument("--app", required=True)
15
+ schema = record_subparsers.add_parser("schema", help="读取记录相关表结构")
16
+ schema.add_argument("--app-key", required=True)
17
17
  schema.add_argument("--mode", choices=["applicant", "browse", "insert", "update", "import", "code-block"], default="applicant")
18
- schema.add_argument("--view")
19
- schema.add_argument("--record", type=int)
20
- schema.set_defaults(handler=_handle_schema, format_hint="record_schema")
18
+ schema.add_argument("--view-id")
19
+ schema.add_argument("--record-id", type=int)
20
+ schema.set_defaults(handler=_handle_schema, format_hint="")
21
21
 
22
22
  list_parser = record_subparsers.add_parser("list", help="列出记录")
23
- list_parser.add_argument("--app", required=True)
24
- list_parser.add_argument("--view")
23
+ list_parser.add_argument("--app-key", required=True)
25
24
  list_parser.add_argument("--column", dest="columns", action="append", type=int, default=[])
25
+ list_parser.add_argument("--columns-file")
26
+ list_parser.add_argument("--where-file")
27
+ list_parser.add_argument("--order-by-file")
26
28
  list_parser.add_argument("--limit", type=int, default=20)
27
29
  list_parser.add_argument("--page", type=int, default=1)
28
- add_file_arg(list_parser)
29
- add_stdin_json_flag(list_parser)
30
- list_parser.set_defaults(handler=_handle_list, format_hint="records_list")
30
+ list_parser.add_argument("--view-id")
31
+ list_parser.set_defaults(handler=_handle_list, format_hint="record_list")
31
32
 
32
33
  get = record_subparsers.add_parser("get", help="读取单条记录")
33
- get.add_argument("--app", required=True)
34
- get.add_argument("--record", required=True, type=int)
35
- get.add_argument("--view")
34
+ get.add_argument("--app-key", required=True)
35
+ get.add_argument("--record-id", required=True, type=int)
36
36
  get.add_argument("--column", dest="columns", action="append", type=int, default=[])
37
- get.set_defaults(handler=_handle_get, format_hint="record_show")
37
+ get.add_argument("--columns-file")
38
+ get.add_argument("--view-id")
39
+ get.set_defaults(handler=_handle_get, format_hint="")
38
40
 
39
- create = record_subparsers.add_parser("create", help="新增记录")
40
- create.add_argument("--app", required=True)
41
- add_field_args(create)
42
- add_file_arg(create)
43
- add_stdin_json_flag(create)
44
- create.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
45
- create.set_defaults(handler=_handle_create, format_hint="record_write")
41
+ insert = record_subparsers.add_parser("insert", help="新增记录")
42
+ insert.add_argument("--app-key", required=True)
43
+ insert.add_argument("--fields-file", required=True)
44
+ insert.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
45
+ insert.set_defaults(handler=_handle_insert, format_hint="")
46
46
 
47
47
  update = record_subparsers.add_parser("update", help="更新记录")
48
- update.add_argument("--app", required=True)
49
- update.add_argument("--record", required=True, type=int)
50
- add_field_args(update)
51
- add_file_arg(update)
52
- add_stdin_json_flag(update)
48
+ update.add_argument("--app-key", required=True)
49
+ update.add_argument("--record-id", required=True, type=int)
50
+ update.add_argument("--fields-file", required=True)
53
51
  update.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
54
- update.set_defaults(handler=_handle_update, format_hint="record_write")
52
+ update.set_defaults(handler=_handle_update, format_hint="")
55
53
 
56
54
  delete = record_subparsers.add_parser("delete", help="删除记录")
57
- delete.add_argument("--app", required=True)
58
- delete.add_argument("--record", type=int)
59
- add_file_arg(delete)
60
- add_stdin_json_flag(delete)
61
- delete.set_defaults(handler=_handle_delete, format_hint="record_write")
55
+ delete.add_argument("--app-key", required=True)
56
+ delete.add_argument("--record-id", type=int)
57
+ delete.add_argument("--record-ids-file")
58
+ delete.set_defaults(handler=_handle_delete, format_hint="")
62
59
 
63
60
  analyze = record_subparsers.add_parser("analyze", help="分析记录数据")
64
- analyze.add_argument("--app", required=True)
65
- analyze.add_argument("--view")
61
+ analyze.add_argument("--app-key", required=True)
62
+ analyze.add_argument("--dimensions-file")
63
+ analyze.add_argument("--metrics-file")
64
+ analyze.add_argument("--filters-file")
65
+ analyze.add_argument("--sort-file")
66
66
  analyze.add_argument("--limit", type=int, default=20)
67
67
  analyze.add_argument("--strict-full", action=argparse.BooleanOptionalAction, default=False)
68
- add_file_arg(analyze, required=False, help_text="读取分析 JSON,支持 dimensions/metrics/filters/sort")
69
- add_stdin_json_flag(analyze)
70
- analyze.set_defaults(handler=_handle_analyze, format_hint="record_analyze")
71
-
72
- run_code = record_subparsers.add_parser("run-code", help="执行代码块字段")
73
- run_code.add_argument("--app", required=True)
74
- run_code.add_argument("--record", required=True, type=int)
75
- run_code.add_argument("--field-selector", required=True)
76
- run_code.add_argument("--role", type=int, default=1)
77
- run_code.add_argument("--node", dest="workflow_node_id", type=int)
78
- add_file_arg(run_code, required=False, help_text="读取执行 JSON,支持 answers/fields")
79
- add_stdin_json_flag(run_code)
80
- run_code.add_argument("--manual", action=argparse.BooleanOptionalAction, default=True)
81
- run_code.add_argument("--verify-writeback", action=argparse.BooleanOptionalAction, default=True)
82
- run_code.add_argument("--force-refresh-form", action="store_true")
83
- run_code.set_defaults(handler=_handle_run_code, format_hint="record_run_code")
68
+ analyze.add_argument("--view-id")
69
+ analyze.set_defaults(handler=_handle_analyze, format_hint="")
70
+
71
+ code_block = record_subparsers.add_parser("code-block-run", help="执行代码块字段")
72
+ code_block.add_argument("--app-key", required=True)
73
+ code_block.add_argument("--record-id", required=True, type=int)
74
+ code_block.add_argument("--code-block-field", required=True)
75
+ code_block.add_argument("--role", type=int, default=1)
76
+ code_block.add_argument("--workflow-node-id", type=int)
77
+ code_block.add_argument("--answers-file")
78
+ code_block.add_argument("--fields-file")
79
+ code_block.add_argument("--manual", action=argparse.BooleanOptionalAction, default=True)
80
+ code_block.add_argument("--verify-writeback", action=argparse.BooleanOptionalAction, default=True)
81
+ code_block.add_argument("--force-refresh-form", action="store_true")
82
+ code_block.set_defaults(handler=_handle_code_block_run, format_hint="")
83
+
84
+
85
+ def _columns(args: argparse.Namespace) -> list[Any]:
86
+ columns: list[Any] = list(args.columns or [])
87
+ if args.columns_file:
88
+ columns.extend(require_list_arg(args.columns_file, option_name="--columns-file"))
89
+ return columns
84
90
 
85
91
 
86
92
  def _handle_schema(args: argparse.Namespace, context: CliContext) -> dict:
87
- if args.mode == "browse" and not args.view:
88
- raise QingflowApiError.config_error("--view is required when --mode browse")
89
- if args.mode == "update" and not args.record:
90
- raise QingflowApiError.config_error("--record is required when --mode update")
91
- return context.records.schema(
92
- profile=args.profile,
93
- app_key=args.app,
94
- mode=args.mode,
95
- view_id=args.view,
96
- record_id=args.record,
97
- )
93
+ mode = args.mode
94
+ if mode == "applicant":
95
+ return context.record.record_schema_get(
96
+ profile=args.profile,
97
+ app_key=args.app_key,
98
+ schema_mode="applicant",
99
+ )
100
+ if mode == "browse":
101
+ if not args.view_id:
102
+ raise QingflowApiError.config_error("--view-id is required when --mode browse")
103
+ return context.record.record_browse_schema_get_public(
104
+ profile=args.profile,
105
+ app_key=args.app_key,
106
+ view_id=args.view_id,
107
+ )
108
+ if mode == "insert":
109
+ return context.record.record_insert_schema_get_public(profile=args.profile, app_key=args.app_key)
110
+ if mode == "update":
111
+ if not args.record_id:
112
+ raise QingflowApiError.config_error("--record-id is required when --mode update")
113
+ return context.record.record_update_schema_get_public(
114
+ profile=args.profile,
115
+ app_key=args.app_key,
116
+ record_id=args.record_id,
117
+ )
118
+ if mode == "import":
119
+ return context.imports.record_import_schema_get(profile=args.profile, app_key=args.app_key)
120
+ return context.code_block.record_code_block_schema_get_public(profile=args.profile, app_key=args.app_key)
98
121
 
99
122
 
100
123
  def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
101
- query = _load_query_payload(args)
102
- return context.records.list(
124
+ return context.record.record_list(
103
125
  profile=args.profile,
104
- app_key=args.app,
105
- columns=list(args.columns or []) + _coerce_list(query.get("columns")),
106
- where=_coerce_list(query.get("where")),
107
- order_by=_coerce_list(query.get("order_by")),
108
- limit=int(query.get("limit") or args.limit),
109
- page=int(query.get("page") or args.page),
110
- view_id=str(query.get("view_id") or args.view or "") or None,
111
- list_type=None,
112
- view_key=None,
113
- view_name=None,
126
+ app_key=args.app_key,
127
+ columns=_columns(args),
128
+ where=load_list_arg(args.where_file, option_name="--where-file"),
129
+ order_by=load_list_arg(args.order_by_file, option_name="--order-by-file"),
130
+ limit=args.limit,
131
+ page=args.page,
132
+ view_id=args.view_id,
114
133
  )
115
134
 
116
135
 
117
136
  def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
118
- return context.records.get(
137
+ return context.record.record_get_public(
119
138
  profile=args.profile,
120
- app_key=args.app,
121
- record_id=args.record,
122
- columns=list(args.columns or []),
123
- view_id=args.view,
124
- workflow_node_id=None,
139
+ app_key=args.app_key,
140
+ record_id=args.record_id,
141
+ columns=_columns(args),
142
+ view_id=args.view_id,
125
143
  )
126
144
 
127
145
 
128
- def _handle_create(args: argparse.Namespace, context: CliContext) -> dict:
129
- return context.records.create(
146
+ def _handle_insert(args: argparse.Namespace, context: CliContext) -> dict:
147
+ return context.record.record_insert_public(
130
148
  profile=args.profile,
131
- app_key=args.app,
132
- fields=merge_object_inputs(args),
149
+ app_key=args.app_key,
150
+ fields=require_object_arg(args.fields_file, option_name="--fields-file"),
133
151
  verify_write=bool(args.verify_write),
134
152
  )
135
153
 
136
154
 
137
155
  def _handle_update(args: argparse.Namespace, context: CliContext) -> dict:
138
- return context.records.update(
156
+ return context.record.record_update_public(
139
157
  profile=args.profile,
140
- app_key=args.app,
141
- record_id=args.record,
142
- fields=merge_object_inputs(args),
158
+ app_key=args.app_key,
159
+ record_id=args.record_id,
160
+ fields=require_object_arg(args.fields_file, option_name="--fields-file"),
143
161
  verify_write=bool(args.verify_write),
144
162
  )
145
163
 
146
164
 
147
165
  def _handle_delete(args: argparse.Namespace, context: CliContext) -> dict:
148
- record_ids = []
149
- if args.stdin_json or args.file:
150
- payload = load_list_input(args, required=False)
151
- record_ids = [item for item in payload if isinstance(item, int)]
152
- return context.records.delete(
166
+ record_ids = load_list_arg(args.record_ids_file, option_name="--record-ids-file")
167
+ return context.record.record_delete_public(
153
168
  profile=args.profile,
154
- app_key=args.app,
155
- record_id=args.record,
169
+ app_key=args.app_key,
170
+ record_id=args.record_id,
156
171
  record_ids=record_ids,
157
172
  )
158
173
 
159
174
 
160
175
  def _handle_analyze(args: argparse.Namespace, context: CliContext) -> dict:
161
- payload = load_object_input(args, required=False)
162
- return context.records.analyze(
176
+ return context.record.record_analyze(
163
177
  profile=args.profile,
164
- app_key=args.app,
165
- dimensions=_coerce_list(payload.get("dimensions")),
166
- metrics=_coerce_list(payload.get("metrics")),
167
- filters=_coerce_list(payload.get("filters")),
168
- sort=_coerce_list(payload.get("sort")),
169
- limit=int(payload.get("limit") or args.limit),
170
- strict_full=bool(payload.get("strict_full", args.strict_full)),
171
- view_id=str(payload.get("view_id") or args.view or "") or None,
172
- list_type=None,
173
- view_key=None,
174
- view_name=None,
178
+ app_key=args.app_key,
179
+ dimensions=load_list_arg(args.dimensions_file, option_name="--dimensions-file"),
180
+ metrics=load_list_arg(args.metrics_file, option_name="--metrics-file"),
181
+ filters=load_list_arg(args.filters_file, option_name="--filters-file"),
182
+ sort=load_list_arg(args.sort_file, option_name="--sort-file"),
183
+ limit=args.limit,
184
+ strict_full=bool(args.strict_full),
185
+ view_id=args.view_id,
175
186
  )
176
187
 
177
188
 
178
- def _handle_run_code(args: argparse.Namespace, context: CliContext) -> dict:
179
- payload = load_object_input(args, required=False)
180
- return context.records.run_code(
189
+ def _handle_code_block_run(args: argparse.Namespace, context: CliContext) -> dict:
190
+ return context.code_block.record_code_block_run(
181
191
  profile=args.profile,
182
- app_key=args.app,
183
- record_id=args.record,
184
- code_block_field=args.field_selector,
192
+ app_key=args.app_key,
193
+ record_id=args.record_id,
194
+ code_block_field=args.code_block_field,
185
195
  role=args.role,
186
196
  workflow_node_id=args.workflow_node_id,
187
- answers=_coerce_list(payload.get("answers")),
188
- fields=payload.get("fields") if isinstance(payload.get("fields"), dict) else {},
189
- manual=bool(payload.get("manual", args.manual)),
190
- verify_writeback=bool(payload.get("verify_writeback", args.verify_writeback)),
191
- force_refresh_form=bool(payload.get("force_refresh_form", args.force_refresh_form)),
197
+ answers=load_list_arg(args.answers_file, option_name="--answers-file"),
198
+ fields=load_object_arg(args.fields_file, option_name="--fields-file") or {},
199
+ manual=bool(args.manual),
200
+ verify_writeback=bool(args.verify_writeback),
201
+ force_refresh_form=bool(args.force_refresh_form),
192
202
  )
193
-
194
-
195
- def _load_query_payload(args: argparse.Namespace) -> dict[str, Any]:
196
- if args.stdin_json or args.file:
197
- payload = load_object_input(args, required=False)
198
- if payload:
199
- return payload
200
- return {}
201
-
202
-
203
- def _coerce_list(value: Any) -> list[Any]:
204
- return value if isinstance(value, list) else []
@@ -3,53 +3,52 @@ from __future__ import annotations
3
3
  import argparse
4
4
 
5
5
  from ..context import CliContext
6
- from .common import add_file_arg, add_stdin_json_flag, load_object_input
6
+ from .common import load_object_arg
7
7
 
8
8
 
9
9
  def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
10
- parser = subparsers.add_parser("tasks", help="待办与流程上下文")
11
- task_subparsers = parser.add_subparsers(dest="tasks_command", required=True)
10
+ parser = subparsers.add_parser("task", help="待办与流程上下文")
11
+ task_subparsers = parser.add_subparsers(dest="task_command", required=True)
12
12
 
13
13
  list_parser = task_subparsers.add_parser("list", help="列出待办")
14
14
  list_parser.add_argument("--task-box", default="todo")
15
15
  list_parser.add_argument("--flow-status", default="all")
16
- list_parser.add_argument("--app")
17
- list_parser.add_argument("--node", dest="workflow_node_id", type=int)
16
+ list_parser.add_argument("--app-key")
17
+ list_parser.add_argument("--workflow-node-id", type=int)
18
18
  list_parser.add_argument("--query")
19
19
  list_parser.add_argument("--page", type=int, default=1)
20
20
  list_parser.add_argument("--page-size", type=int, default=20)
21
- list_parser.set_defaults(handler=_handle_list, format_hint="tasks_list")
22
-
23
- show = task_subparsers.add_parser("show", help="读取待办详情")
24
- show.add_argument("--app", required=True)
25
- show.add_argument("--record", required=True, type=int)
26
- show.add_argument("--node", required=True, type=int)
27
- show.add_argument("--include-candidates", action=argparse.BooleanOptionalAction, default=True)
28
- show.add_argument("--include-associated-reports", action=argparse.BooleanOptionalAction, default=True)
29
- show.set_defaults(handler=_handle_show, format_hint="task_show")
30
-
31
- act = task_subparsers.add_parser("act", help="执行待办动作")
32
- act.add_argument("--app", required=True)
33
- act.add_argument("--record", required=True, type=int)
34
- act.add_argument("--node", required=True, type=int)
35
- act.add_argument("--action", required=True)
36
- add_file_arg(act)
37
- add_stdin_json_flag(act)
38
- act.set_defaults(handler=_handle_act, format_hint="task_action")
21
+ list_parser.set_defaults(handler=_handle_list, format_hint="task_list")
22
+
23
+ get = task_subparsers.add_parser("get", help="读取待办详情")
24
+ get.add_argument("--app-key", required=True)
25
+ get.add_argument("--record-id", required=True, type=int)
26
+ get.add_argument("--workflow-node-id", required=True, type=int)
27
+ get.add_argument("--include-candidates", action=argparse.BooleanOptionalAction, default=True)
28
+ get.add_argument("--include-associated-reports", action=argparse.BooleanOptionalAction, default=True)
29
+ get.set_defaults(handler=_handle_get, format_hint="")
30
+
31
+ action = task_subparsers.add_parser("action", help="执行待办动作")
32
+ action.add_argument("--app-key", required=True)
33
+ action.add_argument("--record-id", required=True, type=int)
34
+ action.add_argument("--workflow-node-id", required=True, type=int)
35
+ action.add_argument("--action", required=True)
36
+ action.add_argument("--payload-file")
37
+ action.set_defaults(handler=_handle_action, format_hint="")
39
38
 
40
39
  log = task_subparsers.add_parser("log", help="读取流程日志")
41
- log.add_argument("--app", required=True)
42
- log.add_argument("--record", required=True, type=int)
43
- log.add_argument("--node", required=True, type=int)
44
- log.set_defaults(handler=_handle_log, format_hint="task_log")
40
+ log.add_argument("--app-key", required=True)
41
+ log.add_argument("--record-id", required=True, type=int)
42
+ log.add_argument("--workflow-node-id", required=True, type=int)
43
+ log.set_defaults(handler=_handle_log, format_hint="")
45
44
 
46
45
 
47
46
  def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
48
- return context.tasks.list(
47
+ return context.task.task_list(
49
48
  profile=args.profile,
50
49
  task_box=args.task_box,
51
50
  flow_status=args.flow_status,
52
- app_key=args.app,
51
+ app_key=args.app_key,
53
52
  workflow_node_id=args.workflow_node_id,
54
53
  query=args.query,
55
54
  page=args.page,
@@ -57,32 +56,32 @@ def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
57
56
  )
58
57
 
59
58
 
60
- def _handle_show(args: argparse.Namespace, context: CliContext) -> dict:
61
- return context.tasks.show(
59
+ def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
60
+ return context.task.task_get(
62
61
  profile=args.profile,
63
- app_key=args.app,
64
- record_id=args.record,
65
- workflow_node_id=args.node,
62
+ app_key=args.app_key,
63
+ record_id=args.record_id,
64
+ workflow_node_id=args.workflow_node_id,
66
65
  include_candidates=bool(args.include_candidates),
67
66
  include_associated_reports=bool(args.include_associated_reports),
68
67
  )
69
68
 
70
69
 
71
- def _handle_act(args: argparse.Namespace, context: CliContext) -> dict:
72
- return context.tasks.act(
70
+ def _handle_action(args: argparse.Namespace, context: CliContext) -> dict:
71
+ return context.task.task_action_execute(
73
72
  profile=args.profile,
74
- app_key=args.app,
75
- record_id=args.record,
76
- workflow_node_id=args.node,
73
+ app_key=args.app_key,
74
+ record_id=args.record_id,
75
+ workflow_node_id=args.workflow_node_id,
77
76
  action=args.action,
78
- payload=load_object_input(args, required=False),
77
+ payload=load_object_arg(args.payload_file, option_name="--payload-file") or {},
79
78
  )
80
79
 
81
80
 
82
81
  def _handle_log(args: argparse.Namespace, context: CliContext) -> dict:
83
- return context.tasks.log(
82
+ return context.task.task_workflow_log_get(
84
83
  profile=args.profile,
85
- app_key=args.app,
86
- record_id=args.record,
87
- workflow_node_id=args.node,
84
+ app_key=args.app_key,
85
+ record_id=args.record_id,
86
+ workflow_node_id=args.workflow_node_id,
88
87
  )
@@ -6,22 +6,22 @@ from ..context import CliContext
6
6
 
7
7
 
8
8
  def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
9
- parser = subparsers.add_parser("ws", help="工作区操作")
10
- ws_subparsers = parser.add_subparsers(dest="ws_command", required=True)
9
+ parser = subparsers.add_parser("workspace", help="工作区")
10
+ workspace_subparsers = parser.add_subparsers(dest="workspace_command", required=True)
11
11
 
12
- list_parser = ws_subparsers.add_parser("list", help="列出工作区")
12
+ list_parser = workspace_subparsers.add_parser("list", help="列出工作区")
13
13
  list_parser.add_argument("--page", type=int, default=1)
14
14
  list_parser.add_argument("--page-size", type=int, default=20)
15
15
  list_parser.add_argument("--include-external", action="store_true")
16
- list_parser.set_defaults(handler=_handle_list, format_hint="ws_list")
16
+ list_parser.set_defaults(handler=_handle_list, format_hint="workspace_list")
17
17
 
18
- use = ws_subparsers.add_parser("use", help="切换工作区")
19
- use.add_argument("--ws-id", type=int, required=True)
20
- use.set_defaults(handler=_handle_use, format_hint="ws_use")
18
+ select = workspace_subparsers.add_parser("select", help="切换工作区")
19
+ select.add_argument("--ws-id", type=int, required=True)
20
+ select.set_defaults(handler=_handle_select, format_hint="")
21
21
 
22
22
 
23
23
  def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
24
- return context.workspace.list(
24
+ return context.workspace.workspace_list(
25
25
  profile=args.profile,
26
26
  page_num=args.page,
27
27
  page_size=args.page_size,
@@ -29,5 +29,5 @@ def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
29
29
  )
30
30
 
31
31
 
32
- def _handle_use(args: argparse.Namespace, context: CliContext) -> dict:
33
- return context.workspace.use(profile=args.profile, ws_id=args.ws_id)
32
+ def _handle_select(args: argparse.Namespace, context: CliContext) -> dict:
33
+ return context.workspace.workspace_select(profile=args.profile, ws_id=args.ws_id)
@@ -2,44 +2,47 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
4
 
5
- from ..ops.context import OperationsRuntime, build_operations_runtime
5
+ from ..backend_client import BackendClient
6
+ from ..session_store import SessionStore
7
+ from ..tools.ai_builder_tools import AiBuilderTools
8
+ from ..tools.app_tools import AppTools
9
+ from ..tools.auth_tools import AuthTools
10
+ from ..tools.code_block_tools import CodeBlockTools
11
+ from ..tools.import_tools import ImportTools
12
+ from ..tools.record_tools import RecordTools
13
+ from ..tools.task_context_tools import TaskContextTools
14
+ from ..tools.workspace_tools import WorkspaceTools
6
15
 
7
16
 
8
17
  @dataclass(slots=True)
9
18
  class CliContext:
10
- runtime: OperationsRuntime
11
-
12
- @property
13
- def auth(self):
14
- return self.runtime.auth
15
-
16
- @property
17
- def workspace(self):
18
- return self.runtime.workspace
19
-
20
- @property
21
- def apps(self):
22
- return self.runtime.apps
23
-
24
- @property
25
- def records(self):
26
- return self.runtime.records
27
-
28
- @property
29
- def imports(self):
30
- return self.runtime.imports
31
-
32
- @property
33
- def tasks(self):
34
- return self.runtime.tasks
35
-
36
- @property
37
- def build(self):
38
- return self.runtime.builder
19
+ sessions: SessionStore
20
+ backend: BackendClient
21
+ auth: AuthTools
22
+ workspace: WorkspaceTools
23
+ app: AppTools
24
+ record: RecordTools
25
+ code_block: CodeBlockTools
26
+ imports: ImportTools
27
+ task: TaskContextTools
28
+ builder: AiBuilderTools
39
29
 
40
30
  def close(self) -> None:
41
- self.runtime.close()
31
+ self.backend.close()
42
32
 
43
33
 
44
34
  def build_cli_context() -> CliContext:
45
- return CliContext(runtime=build_operations_runtime())
35
+ sessions = SessionStore()
36
+ backend = BackendClient()
37
+ return CliContext(
38
+ sessions=sessions,
39
+ backend=backend,
40
+ auth=AuthTools(sessions, backend),
41
+ workspace=WorkspaceTools(sessions, backend),
42
+ app=AppTools(sessions, backend),
43
+ record=RecordTools(sessions, backend),
44
+ code_block=CodeBlockTools(sessions, backend),
45
+ imports=ImportTools(sessions, backend),
46
+ task=TaskContextTools(sessions, backend),
47
+ builder=AiBuilderTools(sessions, backend),
48
+ )