@josephyan/qingflow-cli 1.1.4 → 1.1.6

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 (154) hide show
  1. package/README.md +7 -3
  2. package/docs/local-agent-install.md +57 -6
  3. package/entry_point.py +1 -1
  4. package/npm/bin/qingflow-skills.mjs +5 -0
  5. package/npm/bin/qingflow.mjs +1 -34
  6. package/npm/lib/runtime.mjs +21 -101
  7. package/npm/scripts/postinstall.mjs +1 -10
  8. package/package.json +3 -2
  9. package/pyproject.toml +1 -1
  10. package/skills/qingflow-cli/SKILL.md +58 -44
  11. package/skills/qingflow-cli/manifest.yaml +1 -1
  12. package/skills/qingflow-cli/reference/00-INDEX.md +35 -0
  13. package/skills/qingflow-cli/reference/builder/10-build-single-app.md +38 -0
  14. package/skills/qingflow-cli/reference/builder/20-build-complete-system.md +39 -0
  15. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md → builder/30-schema-fields.md} +52 -10
  16. package/skills/qingflow-cli/reference/builder/40-layout.md +52 -0
  17. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_VIEWS_WORKFLOW.md → builder/50-views.md} +39 -15
  18. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_CHARTS_WORKFLOW.md → builder/60-charts.md} +36 -13
  19. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_PORTAL_WORKFLOW.md → builder/70-portal.md} +36 -13
  20. package/skills/qingflow-cli/reference/builder/80-buttons-associated-resources.md +41 -0
  21. package/skills/qingflow-cli/reference/builder/90-workflow.md +34 -0
  22. package/skills/qingflow-cli/reference/builder/99-publish-verify.md +46 -0
  23. package/skills/qingflow-cli/reference/builder/README.md +41 -0
  24. package/skills/qingflow-cli/reference/builder/code-integrations/README.md +130 -0
  25. package/skills/qingflow-cli/reference/builder/code-integrations/code-block.md +66 -0
  26. package/skills/qingflow-cli/reference/builder/code-integrations/q-linker.md +77 -0
  27. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_APP_DELIVERY_WORKFLOW.md → builder/reference/app-delivery-sop.md} +26 -16
  28. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/README.md +293 -0
  29. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/build-complete-system.md +809 -0
  30. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/build-single-app.md +830 -0
  31. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/complete-system-development-guide.md +123 -0
  32. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/create-app.md +182 -0
  33. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/environments.md +63 -0
  34. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/flow-actors-and-permissions.md +142 -0
  35. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/gotchas.md +108 -0
  36. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/match-rules.md +114 -0
  37. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/public-surface-sync.md +75 -0
  38. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/single-app-development-guide.md +58 -0
  39. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/solution-playbooks.md +52 -0
  40. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/tool-selection.md +107 -0
  41. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-flow.md +7 -0
  42. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-layout.md +7 -0
  43. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-schema.md +7 -0
  44. package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-views.md +7 -0
  45. package/skills/qingflow-cli/reference/builder/workflow/01-overview.md +45 -0
  46. package/skills/qingflow-cli/reference/builder/workflow/02-update-mode.md +53 -0
  47. package/skills/qingflow-cli/reference/builder/workflow/03-flow-patterns.md +57 -0
  48. package/skills/qingflow-cli/reference/builder/workflow/04-stage1-business-modeling.md +131 -0
  49. package/skills/qingflow-cli/reference/builder/workflow/05-stage2-members-roles.md +29 -0
  50. package/skills/qingflow-cli/reference/builder/workflow/06-stage3-build-spec.md +165 -0
  51. package/skills/qingflow-cli/reference/builder/workflow/07-stage4-validate-spec.md +33 -0
  52. package/skills/qingflow-cli/reference/builder/workflow/08-stage5-apply-verify.md +51 -0
  53. package/skills/qingflow-cli/reference/builder/workflow/09-stage6-summary.md +88 -0
  54. package/skills/qingflow-cli/reference/builder/workflow/10-node-config-reference.md +93 -0
  55. package/skills/qingflow-cli/reference/builder/workflow/11-troubleshooting.md +15 -0
  56. package/skills/qingflow-cli/reference/builder/workflow/README.md +88 -0
  57. package/skills/qingflow-cli/reference/builder/workflow/workflow-schema.json +1754 -0
  58. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_ADMIN_CHEATSHEET.md → core/QINGFLOW_CLI_ADMIN_CHEATSHEET.md} +3 -3
  59. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md → core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md} +6 -6
  60. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_EXPLORATION_REPORT.md → core/QINGFLOW_CLI_EXPLORATION_REPORT.md} +2 -2
  61. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_FIELD_DATA_TYPES.md → core/QINGFLOW_CLI_FIELD_DATA_TYPES.md} +11 -11
  62. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_MEMBER_CHEATSHEET.md → core/QINGFLOW_CLI_MEMBER_CHEATSHEET.md} +4 -4
  63. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md → core/QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md} +4 -4
  64. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md} +3 -3
  65. package/skills/qingflow-cli/reference/record/QINGFLOW_CLI_RECORD_DELETE_WORKFLOW.md +31 -0
  66. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md} +4 -4
  67. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md} +7 -7
  68. package/skills/qingflow-cli/reference/record/analysis/README.md +130 -0
  69. package/skills/qingflow-cli/reference/record/analysis/analysis-gotchas.md +91 -0
  70. package/skills/qingflow-cli/reference/record/analysis/analysis-patterns.md +112 -0
  71. package/skills/qingflow-cli/reference/record/analysis/business-context.md +74 -0
  72. package/skills/qingflow-cli/reference/record/analysis/confidence-reporting.md +69 -0
  73. package/skills/qingflow-cli/reference/record/analysis/data-access-playbook.md +106 -0
  74. package/skills/qingflow-cli/reference/record/analysis/pandas-recipes.md +172 -0
  75. package/skills/qingflow-cli/reference/record/analysis/report-format.md +76 -0
  76. package/skills/qingflow-cli/reference/record/insert/README.md +75 -0
  77. package/skills/qingflow-cli/reference/{QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md → task/QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md} +5 -5
  78. package/skills/qingflow-cli/reference/task/ops/README.md +131 -0
  79. package/skills/qingflow-cli/reference/task/ops/environments.md +43 -0
  80. package/skills/qingflow-cli/reference/task/ops/workflow-usage.md +26 -0
  81. package/skills/qingflow-cli/scripts/validate_system_build_summary.py +124 -0
  82. package/skills/qingflow-cli/scripts/workflow/diff_flow_spec.py +275 -0
  83. package/skills/qingflow-cli/scripts/workflow/validate_flow_spec.py +605 -0
  84. package/skills/qingflow-mcp-setup/SKILL.md +115 -0
  85. package/skills/qingflow-mcp-setup/agents/openai.yaml +4 -0
  86. package/skills/qingflow-mcp-setup/references/claude-desktop.md +34 -0
  87. package/skills/qingflow-mcp-setup/references/environments.md +62 -0
  88. package/skills/qingflow-mcp-setup/references/generic-stdio.md +32 -0
  89. package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +38 -0
  90. package/src/qingflow_mcp/__init__.py +1 -1
  91. package/src/qingflow_mcp/__main__.py +6 -2
  92. package/src/qingflow_mcp/builder_facade/models.py +282 -102
  93. package/src/qingflow_mcp/builder_facade/service.py +4192 -935
  94. package/src/qingflow_mcp/cli/commands/builder.py +316 -298
  95. package/src/qingflow_mcp/cli/commands/chart.py +1 -1
  96. package/src/qingflow_mcp/cli/commands/common.py +12 -3
  97. package/src/qingflow_mcp/cli/commands/exports.py +2 -2
  98. package/src/qingflow_mcp/cli/commands/imports.py +3 -3
  99. package/src/qingflow_mcp/cli/commands/portal.py +2 -2
  100. package/src/qingflow_mcp/cli/commands/record.py +101 -27
  101. package/src/qingflow_mcp/cli/commands/task.py +28 -47
  102. package/src/qingflow_mcp/cli/commands/view.py +1 -1
  103. package/src/qingflow_mcp/cli/context.py +0 -3
  104. package/src/qingflow_mcp/cli/formatters.py +784 -16
  105. package/src/qingflow_mcp/cli/main.py +117 -33
  106. package/src/qingflow_mcp/errors.py +43 -2
  107. package/src/qingflow_mcp/public_surface.py +26 -17
  108. package/src/qingflow_mcp/response_trim.py +81 -17
  109. package/src/qingflow_mcp/server.py +14 -12
  110. package/src/qingflow_mcp/server_app_builder.py +65 -21
  111. package/src/qingflow_mcp/server_app_user.py +22 -16
  112. package/src/qingflow_mcp/session_store.py +11 -7
  113. package/src/qingflow_mcp/solution/compiler/__init__.py +3 -1
  114. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
  115. package/src/qingflow_mcp/solution/executor.py +245 -18
  116. package/src/qingflow_mcp/tools/ai_builder_tools.py +1780 -406
  117. package/src/qingflow_mcp/tools/app_tools.py +184 -43
  118. package/src/qingflow_mcp/tools/approval_tools.py +197 -35
  119. package/src/qingflow_mcp/tools/auth_tools.py +92 -16
  120. package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
  121. package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
  122. package/src/qingflow_mcp/tools/directory_tools.py +236 -72
  123. package/src/qingflow_mcp/tools/export_tools.py +244 -34
  124. package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
  125. package/src/qingflow_mcp/tools/file_tools.py +9 -3
  126. package/src/qingflow_mcp/tools/import_tools.py +336 -49
  127. package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
  128. package/src/qingflow_mcp/tools/package_tools.py +118 -6
  129. package/src/qingflow_mcp/tools/portal_tools.py +39 -3
  130. package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
  131. package/src/qingflow_mcp/tools/record_tools.py +1141 -356
  132. package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
  133. package/src/qingflow_mcp/tools/role_tools.py +80 -9
  134. package/src/qingflow_mcp/tools/solution_tools.py +59 -45
  135. package/src/qingflow_mcp/tools/task_context_tools.py +662 -158
  136. package/src/qingflow_mcp/tools/task_tools.py +113 -29
  137. package/src/qingflow_mcp/tools/view_tools.py +106 -3
  138. package/src/qingflow_mcp/tools/workflow_tools.py +48 -4
  139. package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
  140. /package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_MATCH_RULES.md → builder/reference/match-rules.md} +0 -0
  141. /package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_WORKSPACE_ICONS.md → builder/reference/workspace-icons.md} +0 -0
  142. /package/skills/qingflow-cli/reference/{charts_remove.example.json → examples/charts/charts_remove.example.json} +0 -0
  143. /package/skills/qingflow-cli/reference/{charts_reorder.example.json → examples/charts/charts_reorder.example.json} +0 -0
  144. /package/skills/qingflow-cli/reference/{charts_upsert_bar.example.json → examples/charts/charts_upsert_bar.example.json} +0 -0
  145. /package/skills/qingflow-cli/reference/{charts_upsert_dashboard_starter.example.json → examples/charts/charts_upsert_dashboard_starter.example.json} +0 -0
  146. /package/skills/qingflow-cli/reference/{charts_upsert_minimal.example.json → examples/charts/charts_upsert_minimal.example.json} +0 -0
  147. /package/skills/qingflow-cli/reference/{portal_sections_all_types.example.json → examples/portal/portal_sections_all_types.example.json} +0 -0
  148. /package/skills/qingflow-cli/reference/{portal_sections_five_types.example.json → examples/portal/portal_sections_five_types.example.json} +0 -0
  149. /package/skills/qingflow-cli/reference/{portal_sections_standard_workbench.example.json → examples/portal/portal_sections_standard_workbench.example.json} +0 -0
  150. /package/skills/qingflow-cli/reference/{_batch_schema_complex.json → examples/schema/_batch_schema_complex.json} +0 -0
  151. /package/skills/qingflow-cli/reference/{_batch_schema_scalar.json → examples/schema/_batch_schema_scalar.json} +0 -0
  152. /package/skills/qingflow-cli/reference/{schema_add_fields_minimal.example.json → examples/schema/schema_add_fields_minimal.example.json} +0 -0
  153. /package/skills/qingflow-cli/reference/{schema_apply_add_fields_all_types.json → examples/schema/schema_apply_add_fields_all_types.json} +0 -0
  154. /package/skills/qingflow-cli/reference/{views_upsert_table_minimal.example.json → examples/views/views_upsert_table_minimal.example.json} +0 -0
@@ -11,7 +11,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
11
11
 
12
12
  get_parser = chart_subparsers.add_parser("get", help="读取报表数据")
13
13
  get_parser.add_argument("--chart-id", required=True)
14
- get_parser.set_defaults(handler=_handle_get, format_hint="generic")
14
+ get_parser.set_defaults(handler=_handle_get, format_hint="chart_get")
15
15
 
16
16
 
17
17
  def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
@@ -48,14 +48,23 @@ def read_secret_arg(value: str | None, *, stdin_enabled: bool, label: str) -> st
48
48
  raise QingflowApiError.config_error(f"{label} is required")
49
49
 
50
50
 
51
- def raise_config_error(message: str, *, fix_hint: str) -> None:
51
+ def raise_config_error(
52
+ message: str,
53
+ *,
54
+ fix_hint: str | None = None,
55
+ error_code: str = "CONFIG_ERROR",
56
+ details: dict[str, Any] | None = None,
57
+ ) -> None:
58
+ error_details: dict[str, Any] = {"fix_hint": fix_hint or message}
59
+ if details:
60
+ error_details.update(details)
52
61
  raise RuntimeError(
53
62
  json.dumps(
54
63
  {
55
64
  "category": "config",
56
65
  "message": message,
57
- "error_code": "CONFIG_ERROR",
58
- "details": {"fix_hint": fix_hint},
66
+ "error_code": error_code,
67
+ "details": error_details,
59
68
  },
60
69
  ensure_ascii=False,
61
70
  )
@@ -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", default="system:all")
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", default="system:all")
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)
@@ -25,14 +25,14 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
25
25
  repair.add_argument("--authorized-file-modification", action="store_true")
26
26
  repair.add_argument("--output-path")
27
27
  repair.add_argument("--repair", dest="selected_repairs", action="append", default=[])
28
- repair.set_defaults(handler=_handle_repair, format_hint="")
28
+ repair.set_defaults(handler=_handle_repair, format_hint="import_repair")
29
29
 
30
30
  start = import_subparsers.add_parser("start", help="启动导入")
31
31
  start.add_argument("--app-key", required=True)
32
32
  start.add_argument("--verification-id", required=True)
33
33
  start.add_argument("--being-enter-auditing", type=parse_bool_text, required=True)
34
34
  start.add_argument("--view-key")
35
- start.set_defaults(handler=_handle_start, format_hint="")
35
+ start.set_defaults(handler=_handle_start, format_hint="import_start")
36
36
 
37
37
  status = import_subparsers.add_parser("status", help="查询导入状态")
38
38
  status.add_argument("--app-key")
@@ -10,11 +10,11 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
10
10
  portal_subparsers = parser.add_subparsers(dest="portal_command", required=True)
11
11
 
12
12
  list_parser = portal_subparsers.add_parser("list", help="列出当前用户可访问的门户")
13
- list_parser.set_defaults(handler=_handle_list, format_hint="generic")
13
+ list_parser.set_defaults(handler=_handle_list, format_hint="portal_list")
14
14
 
15
15
  get_parser = portal_subparsers.add_parser("get", help="读取门户内容清单")
16
16
  get_parser.add_argument("--dash-key", required=True)
17
- get_parser.set_defaults(handler=_handle_get, format_hint="generic")
17
+ get_parser.set_defaults(handler=_handle_get, format_hint="portal_get")
18
18
 
19
19
 
20
20
  def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
@@ -18,34 +18,43 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
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(dest="record_schema_command")
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
- schema_applicant.set_defaults(handler=_handle_schema_applicant, format_hint="")
29
+ schema_applicant.set_defaults(handler=_handle_schema_applicant, format_hint="record_schema")
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)
30
38
  schema_browse.add_argument("--view-id", required=True)
31
- schema_browse.set_defaults(handler=_handle_schema_browse, format_hint="")
39
+ schema_browse.set_defaults(handler=_handle_schema_browse, format_hint="record_schema")
32
40
 
33
41
  schema_insert = schema_subparsers.add_parser("insert", help="读取新增记录表结构")
34
42
  schema_insert.add_argument("--app-key", required=True)
35
- schema_insert.set_defaults(handler=_handle_schema_insert, format_hint="")
43
+ schema_insert.set_defaults(handler=_handle_schema_insert, format_hint="record_schema")
36
44
 
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)
40
- schema_update.set_defaults(handler=_handle_schema_update, format_hint="")
48
+ schema_update.add_argument("--view-id")
49
+ schema_update.set_defaults(handler=_handle_schema_update, format_hint="record_schema")
41
50
 
42
51
  schema_import = schema_subparsers.add_parser("import", help="读取导入表结构")
43
52
  schema_import.add_argument("--app-key", required=True)
44
- schema_import.set_defaults(handler=_handle_schema_import, format_hint="")
53
+ schema_import.set_defaults(handler=_handle_schema_import, format_hint="record_schema")
45
54
 
46
55
  schema_code_block = schema_subparsers.add_parser("code-block", help="读取代码块执行表结构")
47
56
  schema_code_block.add_argument("--app-key", required=True)
48
- schema_code_block.set_defaults(handler=_handle_schema_code_block, format_hint="")
57
+ schema_code_block.set_defaults(handler=_handle_schema_code_block, format_hint="record_schema")
49
58
 
50
59
  member_candidates = record_subparsers.add_parser("member-candidates", help="读取成员字段候选项")
51
60
  member_candidates.add_argument("--app-key", required=True)
@@ -56,7 +65,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
56
65
  member_candidates.add_argument("--record-id")
57
66
  member_candidates.add_argument("--workflow-node-id", type=int)
58
67
  member_candidates.add_argument("--fields-file")
59
- member_candidates.set_defaults(handler=_handle_member_candidates, format_hint="")
68
+ member_candidates.set_defaults(handler=_handle_member_candidates, format_hint="record_candidates")
60
69
 
61
70
  department_candidates = record_subparsers.add_parser("department-candidates", help="读取部门字段候选项")
62
71
  department_candidates.add_argument("--app-key", required=True)
@@ -67,18 +76,41 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
67
76
  department_candidates.add_argument("--record-id")
68
77
  department_candidates.add_argument("--workflow-node-id", type=int)
69
78
  department_candidates.add_argument("--fields-file")
70
- department_candidates.set_defaults(handler=_handle_department_candidates, format_hint="")
79
+ department_candidates.set_defaults(handler=_handle_department_candidates, format_hint="record_candidates")
71
80
 
72
81
  list_parser = record_subparsers.add_parser("list", help="列出记录")
73
82
  list_parser.add_argument("--app-key", required=True)
74
- list_parser.add_argument("--column", dest="columns", action="append", type=int, default=[])
75
- list_parser.add_argument("--columns-file")
83
+ list_parser.add_argument(
84
+ "--column",
85
+ dest="columns",
86
+ action="append",
87
+ type=int,
88
+ default=[],
89
+ metavar="FIELD_ID",
90
+ help="只返回这些 field_id;可重复传",
91
+ )
92
+ list_parser.add_argument(
93
+ "--columns-file",
94
+ help="JSON/YAML list;元素为 field_id 整数/整数字符串或 {'field_id': ...}",
95
+ )
76
96
  list_parser.add_argument("--query")
77
- list_parser.add_argument("--query-field", dest="query_fields", action="append", type=int, default=[])
78
- list_parser.add_argument("--query-fields-file")
97
+ list_parser.add_argument(
98
+ "--query-field",
99
+ dest="query_fields",
100
+ action="append",
101
+ type=int,
102
+ default=[],
103
+ metavar="FIELD_ID",
104
+ help="全文搜索范围 field_id;可重复传",
105
+ )
106
+ list_parser.add_argument(
107
+ "--query-fields-file",
108
+ help="JSON/YAML list;元素为 field_id 整数/整数字符串或 {'field_id': ...}",
109
+ )
79
110
  list_parser.add_argument("--where-file")
80
111
  list_parser.add_argument("--order-by-file")
81
112
  list_parser.add_argument("--page", type=int, default=1)
113
+ list_parser.add_argument("--page-size", type=int, default=10)
82
114
  list_parser.add_argument("--view-id")
83
115
  list_parser.add_argument("--list-type", dest="legacy_list_type", type=int, help=argparse.SUPPRESS)
84
116
  list_parser.add_argument("--view-key", dest="legacy_view_key", help=argparse.SUPPRESS)
@@ -87,8 +119,19 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
87
119
 
88
120
  access_parser = record_subparsers.add_parser("access", help="访问记录并写入本地 CSV 分片")
89
121
  access_parser.add_argument("--app-key", required=True)
90
- access_parser.add_argument("--column", dest="columns", action="append", type=int, default=[])
91
- access_parser.add_argument("--columns-file")
122
+ access_parser.add_argument(
123
+ "--column",
124
+ dest="columns",
125
+ action="append",
126
+ type=int,
127
+ default=[],
128
+ metavar="FIELD_ID",
129
+ help="导出这些 field_id 到 CSV;可重复传",
130
+ )
131
+ access_parser.add_argument(
132
+ "--columns-file",
133
+ help="JSON/YAML list;元素为 field_id 整数/整数字符串或 {'field_id': ...}",
134
+ )
92
135
  access_parser.add_argument("--where-file")
93
136
  access_parser.add_argument("--order-by-file")
94
137
  access_parser.add_argument("--view-id", required=True)
@@ -97,15 +140,26 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
97
140
  get = record_subparsers.add_parser("get", help="读取单条记录")
98
141
  get.add_argument("--app-key", required=True)
99
142
  get.add_argument("--record-id", required=True)
100
- get.add_argument("--column", dest="columns", action="append", type=int, default=[])
101
- get.add_argument("--columns-file")
143
+ get.add_argument(
144
+ "--column",
145
+ dest="columns",
146
+ action="append",
147
+ type=int,
148
+ default=[],
149
+ metavar="FIELD_ID",
150
+ help="聚焦这些 field_id;可重复传",
151
+ )
152
+ get.add_argument(
153
+ "--columns-file",
154
+ help="JSON/YAML list;元素为 field_id 整数/整数字符串或 {'field_id': ...}",
155
+ )
102
156
  get.add_argument("--view-id")
103
157
  get.set_defaults(handler=_handle_get, format_hint="record_get")
104
158
 
105
159
  logs = record_subparsers.add_parser("logs", help="读取单条记录全量日志并写入本地 JSONL")
106
160
  logs.add_argument("--app-key", required=True)
107
161
  logs.add_argument("--record-id", required=True)
108
- logs.add_argument("--view-id")
162
+ logs.add_argument("--view-id", required=True)
109
163
  logs.set_defaults(handler=_handle_logs, format_hint="record_logs")
110
164
 
111
165
  insert = record_subparsers.add_parser("insert", help="新增记录")
@@ -113,22 +167,25 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
113
167
  insert.add_argument("--fields-file", help=argparse.SUPPRESS)
114
168
  insert.add_argument("--items-file")
115
169
  insert.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
116
- insert.set_defaults(handler=_handle_insert, format_hint="")
170
+ insert.set_defaults(handler=_handle_insert, format_hint="record_write")
117
171
 
118
172
  update = record_subparsers.add_parser("update", help="更新记录")
119
173
  update.add_argument("--app-key", required=True)
120
174
  update.add_argument("--record-id")
121
175
  update.add_argument("--fields-file")
122
176
  update.add_argument("--items-file")
177
+ update.add_argument("--view-id")
123
178
  update.add_argument("--dry-run", action=argparse.BooleanOptionalAction, default=False)
124
179
  update.add_argument("--verify-write", action=argparse.BooleanOptionalAction, default=True)
125
- update.set_defaults(handler=_handle_update, format_hint="")
180
+ update.set_defaults(handler=_handle_update, format_hint="record_write")
126
181
 
127
182
  delete = record_subparsers.add_parser("delete", help="删除记录")
128
183
  delete.add_argument("--app-key", required=True)
129
184
  delete.add_argument("--record-id")
130
185
  delete.add_argument("--record-ids-file")
131
- delete.set_defaults(handler=_handle_delete, format_hint="")
186
+ delete.add_argument("--view-id")
187
+ delete.add_argument("--list-type", dest="legacy_list_type", type=int, help=argparse.SUPPRESS)
188
+ delete.set_defaults(handler=_handle_delete, format_hint="record_delete")
132
189
 
133
190
  analyze = record_subparsers.add_parser("analyze", help=argparse.SUPPRESS)
134
191
  record_subparsers._choices_actions = [ # type: ignore[attr-defined]
@@ -153,6 +210,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
153
210
  code_block.add_argument("--app-key", required=True)
154
211
  code_block.add_argument("--record-id", required=True)
155
212
  code_block.add_argument("--code-block-field", required=True)
213
+ code_block.add_argument("--view-id")
156
214
  code_block.add_argument("--role", type=int, default=1)
157
215
  code_block.add_argument("--workflow-node-id", type=int)
158
216
  code_block.add_argument("--answers-file")
@@ -161,7 +219,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
161
219
  code_block.add_argument("--apply-writeback", action=argparse.BooleanOptionalAction, default=True)
162
220
  code_block.add_argument("--verify-writeback", action=argparse.BooleanOptionalAction, default=True)
163
221
  code_block.add_argument("--force-refresh-form", action="store_true")
164
- code_block.set_defaults(handler=_handle_code_block_run, format_hint="")
222
+ code_block.set_defaults(handler=_handle_code_block_run, format_hint="code_block_run")
165
223
 
166
224
 
167
225
  def _columns(args: argparse.Namespace) -> list[Any]:
@@ -182,20 +240,20 @@ def _handle_schema_root(args: argparse.Namespace, _context: CliContext) -> dict:
182
240
  mode = (args.legacy_mode or "").strip()
183
241
  if mode:
184
242
  replacement = {
185
- "applicant": "record schema applicant --app-key APP_KEY",
243
+ "applicant": "record schema insert --app-key APP_KEY",
186
244
  "browse": "record schema browse --app-key APP_KEY --view-id VIEW_ID",
187
245
  "insert": "record schema insert --app-key APP_KEY",
188
- "update": "record schema update --app-key APP_KEY --record-id RECORD_ID",
246
+ "update": "record schema update --app-key APP_KEY --record-id RECORD_ID [--view-id VIEW_ID]",
189
247
  "import": "record schema import --app-key APP_KEY",
190
248
  "code-block": "record schema code-block --app-key APP_KEY",
191
- }.get(mode, "record schema <applicant|browse|insert|update|import|code-block> ...")
249
+ }.get(mode, "record schema <browse|insert|update|import|code-block> ...")
192
250
  raise_config_error(
193
251
  "record schema --mode is no longer accepted.",
194
252
  fix_hint=f"Use `{replacement}` instead.",
195
253
  )
196
254
  raise_config_error(
197
255
  "record schema requires an explicit subcommand.",
198
- fix_hint="Use one of: `record schema applicant`, `record schema browse`, `record schema insert`, `record schema update`, `record schema import`, or `record schema code-block`.",
256
+ fix_hint="Use one of: `record schema browse`, `record schema insert`, `record schema update`, `record schema import`, or `record schema code-block`.",
199
257
  )
200
258
 
201
259
 
@@ -224,6 +282,7 @@ def _handle_schema_update(args: argparse.Namespace, context: CliContext) -> dict
224
282
  profile=args.profile,
225
283
  app_key=args.app_key,
226
284
  record_id=args.record_id,
285
+ view_id=args.view_id,
227
286
  )
228
287
 
229
288
 
@@ -309,6 +368,7 @@ def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
309
368
  where=load_list_arg(args.where_file, option_name="--where-file"),
310
369
  order_by=load_list_arg(args.order_by_file, option_name="--order-by-file"),
311
370
  page=args.page,
371
+ page_size=args.page_size,
312
372
  view_id=args.view_id,
313
373
  )
314
374
 
@@ -382,6 +442,7 @@ def _handle_update(args: argparse.Namespace, context: CliContext) -> dict:
382
442
  record_id=None,
383
443
  fields=None,
384
444
  items=require_list_arg(args.items_file, option_name="--items-file"),
445
+ view_id=args.view_id,
385
446
  dry_run=bool(args.dry_run),
386
447
  verify_write=bool(args.verify_write),
387
448
  )
@@ -400,17 +461,29 @@ def _handle_update(args: argparse.Namespace, context: CliContext) -> dict:
400
461
  app_key=args.app_key,
401
462
  record_id=args.record_id,
402
463
  fields=require_object_arg(args.fields_file, option_name="--fields-file"),
464
+ view_id=args.view_id,
403
465
  verify_write=bool(args.verify_write),
404
466
  )
405
467
 
406
468
 
407
469
  def _handle_delete(args: argparse.Namespace, context: CliContext) -> dict:
470
+ if args.legacy_list_type is not None:
471
+ raise_config_error(
472
+ "record delete no longer accepts list_type.",
473
+ fix_hint="Call `app_get` first and pass an accessible system `view_id`, for example `--view-id system:all`.",
474
+ )
475
+ if not (args.view_id or "").strip():
476
+ raise_config_error(
477
+ "record delete requires --view-id.",
478
+ 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.",
479
+ )
408
480
  record_ids = load_list_arg(args.record_ids_file, option_name="--record-ids-file")
409
481
  return context.record.record_delete_public(
410
482
  profile=args.profile,
411
483
  app_key=args.app_key,
412
484
  record_id=args.record_id,
413
485
  record_ids=record_ids,
486
+ view_id=args.view_id,
414
487
  )
415
488
 
416
489
 
@@ -446,6 +519,7 @@ def _handle_code_block_run(args: argparse.Namespace, context: CliContext) -> dic
446
519
  app_key=args.app_key,
447
520
  record_id=args.record_id,
448
521
  code_block_field=args.code_block_field,
522
+ view_id=args.view_id,
449
523
  role=args.role,
450
524
  workflow_node_id=args.workflow_node_id,
451
525
  answers=load_list_arg(args.answers_file, option_name="--answers-file"),
@@ -47,20 +47,14 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
47
47
  list_parser.add_argument("--page-size", type=int, default=20)
48
48
  list_parser.set_defaults(handler=_handle_list, format_hint="task_list")
49
49
 
50
- get = task_subparsers.add_parser("get", help="读取待办详情;推荐直接传 --task-id")
51
- get.add_argument("--task-id")
52
- get.add_argument("--app-key")
53
- get.add_argument("--record-id")
54
- get.add_argument("--workflow-node-id", type=int)
50
+ get = task_subparsers.add_parser("get", help="读取待办详情;--task-id 必须来自 task list 的 data.items[].task_id")
51
+ get.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
55
52
  get.add_argument("--include-candidates", action=argparse.BooleanOptionalAction, default=True)
56
53
  get.add_argument("--include-associated-reports", action=argparse.BooleanOptionalAction, default=True)
57
- get.set_defaults(handler=_handle_get, format_hint="task_get")
54
+ get.set_defaults(handler=_handle_get, format_hint="task_get", app_key="", record_id="", workflow_node_id=0)
58
55
 
59
- action = task_subparsers.add_parser("action", help="执行待办动作")
60
- action.add_argument("--task-id")
61
- action.add_argument("--app-key")
62
- action.add_argument("--record-id")
63
- action.add_argument("--workflow-node-id", type=int)
56
+ action = task_subparsers.add_parser("action", help="执行待办动作;--task-id 必须来自 task list 的 data.items[].task_id")
57
+ action.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
64
58
  action.add_argument("--action", help="不传时在交互终端中选择当前待办可执行动作")
65
59
  action.add_argument("--payload-file")
66
60
  action.add_argument("--fields-file")
@@ -68,24 +62,27 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
68
62
  handler=_handle_action,
69
63
  format_hint="task_action_execute",
70
64
  hide_effective_context_line=True,
65
+ app_key="",
66
+ record_id="",
67
+ workflow_node_id=0,
71
68
  )
72
69
 
73
- report = task_subparsers.add_parser("report", help="读取待办关联报表详情;推荐直接传 --task-id")
74
- report.add_argument("--task-id")
75
- report.add_argument("--app-key")
76
- report.add_argument("--record-id")
77
- report.add_argument("--workflow-node-id", type=int)
70
+ report = task_subparsers.add_parser("report", help="读取待办关联报表详情;--task-id 必须来自 task list 的 data.items[].task_id")
71
+ report.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
78
72
  report.add_argument("--report-id", type=int, help="不传时在交互终端中选择关联报表")
79
73
  report.add_argument("--page", type=int, default=1)
80
74
  report.add_argument("--page-size", type=int, default=20)
81
- report.set_defaults(handler=_handle_report, format_hint="task_associated_report_detail_get")
75
+ report.set_defaults(
76
+ handler=_handle_report,
77
+ format_hint="task_associated_report_detail_get",
78
+ app_key="",
79
+ record_id="",
80
+ workflow_node_id=0,
81
+ )
82
82
 
83
- log = task_subparsers.add_parser("log", help="读取流程日志;推荐直接传 --task-id")
84
- log.add_argument("--task-id")
85
- log.add_argument("--app-key")
86
- log.add_argument("--record-id")
87
- log.add_argument("--workflow-node-id", type=int)
88
- log.set_defaults(handler=_handle_log, format_hint="")
83
+ log = task_subparsers.add_parser("log", help="读取流程日志;--task-id 必须来自 task list 的 data.items[].task_id")
84
+ log.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
85
+ log.set_defaults(handler=_handle_log, format_hint="task_workflow_log_get", app_key="", record_id="", workflow_node_id=0)
89
86
 
90
87
 
91
88
  def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
@@ -165,9 +162,6 @@ def _handle_action(args: argparse.Namespace, context: CliContext) -> dict:
165
162
  return context.task.task_action_execute(
166
163
  profile=args.profile,
167
164
  task_id=args.task_id,
168
- app_key=args.app_key or "",
169
- record_id=args.record_id or "",
170
- workflow_node_id=int(args.workflow_node_id or 0),
171
165
  action=args.action,
172
166
  payload=payload,
173
167
  fields=fields,
@@ -228,9 +222,6 @@ def _run_task_workbench_task_loop(args: argparse.Namespace, context: CliContext)
228
222
  result = context.task.task_action_execute(
229
223
  profile=args.profile,
230
224
  task_id=args.task_id,
231
- app_key=args.app_key or "",
232
- record_id=args.record_id or "",
233
- workflow_node_id=int(args.workflow_node_id or 0),
234
225
  action=args.action,
235
226
  payload=payload_selection,
236
227
  fields={},
@@ -243,30 +234,20 @@ def _run_task_workbench_task_loop(args: argparse.Namespace, context: CliContext)
243
234
  def _resolve_task_locator_or_select(args: argparse.Namespace, context: CliContext, *, tool_name: str) -> dict | None:
244
235
  if (args.task_id or "").strip():
245
236
  return None
246
- has_app_key = bool((args.app_key or "").strip())
247
- has_record_id = bool((args.record_id or "").strip())
248
- has_workflow_node_id = int(args.workflow_node_id or 0) > 0
249
- if has_app_key and has_record_id and has_workflow_node_id:
250
- return None
251
- if has_app_key or has_record_id or has_workflow_node_id:
252
- raise_config_error(
253
- f"{tool_name} requires --task-id, or --app-key together with --record-id and --workflow-node-id",
254
- fix_hint="Either pass `--task-id TASK_ID`, or provide the full locator triple `--app-key --record-id --workflow-node-id`.",
255
- )
256
237
 
257
238
  selection = _choose_todo_task_interactively(args, context, tool_name=tool_name)
258
239
  if selection.status == "unavailable":
259
240
  raise_config_error(
260
- f"{tool_name} requires --task-id, or --app-key together with --record-id and --workflow-node-id",
241
+ f"{tool_name} requires --task-id from task list data.items[].task_id",
261
242
  fix_hint=(
262
243
  "Retry in an interactive terminal to choose from current todo tasks, "
263
- "or pass `--task-id TASK_ID` explicitly."
244
+ "or pass `--task-id` from `task list` explicitly."
264
245
  ),
265
246
  )
266
247
  if selection.status == "empty":
267
248
  raise_config_error(
268
249
  selection.message or f"{tool_name} could not open a selector because no current todo tasks are available.",
269
- fix_hint="Run `task list` to confirm current todo tasks, or retry later with `--task-id TASK_ID`.",
250
+ fix_hint="Run `task list` to confirm current todo tasks, then pass the selected `data.items[].task_id`.",
270
251
  )
271
252
  if selection.status == "cancelled":
272
253
  return cancelled_result(selection.message or "已取消")
@@ -327,7 +308,7 @@ def _choose_todo_task_interactively(
327
308
  args,
328
309
  title=title,
329
310
  unavailable_message=(
330
- f"{tool_name} requires --task-id, or --app-key together with --record-id and --workflow-node-id"
311
+ f"{tool_name} requires --task-id from task list data.items[].task_id"
331
312
  ),
332
313
  empty_message=f"{tool_name} could not open a selector because no current todo tasks are available.",
333
314
  load_options=load_options,
@@ -347,7 +328,7 @@ def _resolve_report_id_or_select(args: argparse.Namespace, context: CliContext)
347
328
  if selection.status == "empty":
348
329
  raise_config_error(
349
330
  selection.message or "task report could not open a selector because the selected task has no visible associated reports.",
350
- fix_hint="Run `task get --task-id TASK_ID` to inspect `extras.associated_reports`, or choose another task.",
331
+ fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect `extras.associated_reports`, or choose another task.",
351
332
  )
352
333
  if selection.status == "cancelled":
353
334
  return cancelled_result(selection.message or "已取消")
@@ -395,7 +376,7 @@ def _resolve_task_action_or_select(
395
376
  if selection.status == "empty":
396
377
  raise_config_error(
397
378
  selection.message or "task action could not open an action selector because no interactive actions are available.",
398
- fix_hint="Run `task get --task-id TASK_ID` to inspect available_actions, or pass a supported `--action` explicitly.",
379
+ fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect available_actions, or pass a supported `--action` explicitly.",
399
380
  )
400
381
  if selection.status == "cancelled":
401
382
  return cancelled_result(selection.message or "已取消")
@@ -476,7 +457,7 @@ def _resolve_action_payload_or_select(
476
457
  if selection.status == "empty":
477
458
  raise_config_error(
478
459
  selection.message or "task rollback could not open a selector because no rollback candidates are visible.",
479
- fix_hint="Run `task get --task-id TASK_ID` to inspect rollback candidates, or choose another action.",
460
+ fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect rollback candidates, or choose another action.",
480
461
  )
481
462
  if selection.status == "cancelled":
482
463
  return cancelled_result(selection.message or "已取消")
@@ -493,7 +474,7 @@ def _resolve_action_payload_or_select(
493
474
  if selection.status == "empty":
494
475
  raise_config_error(
495
476
  selection.message or "task transfer could not open a selector because no transfer candidates are visible.",
496
- fix_hint="Run `task get --task-id TASK_ID` to inspect transfer candidates, or choose another action.",
477
+ fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect transfer candidates, or choose another action.",
497
478
  )
498
479
  if selection.status == "cancelled":
499
480
  return cancelled_result(selection.message or "已取消")
@@ -11,7 +11,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
11
11
 
12
12
  get_parser = view_subparsers.add_parser("get", help="读取视图资源描述")
13
13
  get_parser.add_argument("--view-id", required=True)
14
- get_parser.set_defaults(handler=_handle_get, format_hint="generic")
14
+ get_parser.set_defaults(handler=_handle_get, format_hint="view_get")
15
15
 
16
16
 
17
17
  def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
@@ -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
  )