@qingflow-tech/qingflow-cli 1.1.61-beta.4 → 1.1.61-beta.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 (61) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/pyproject.toml +2 -1
  4. package/skills/qingflow-cli/reference/QINGFLOW_CLI_BUILDER_CHARTS_WORKFLOW.md +1 -1
  5. package/skills/qingflow-cli/reference/QINGFLOW_CLI_BUILDER_PORTAL_WORKFLOW.md +6 -258
  6. package/skills/qingflow-cli/reference/builder/30-schema-fields.md +13 -0
  7. package/skills/qingflow-cli/reference/builder/70-portal.md +38 -17
  8. package/skills/qingflow-cli/reference/examples/portal/portal_apply_v1alpha1.example.json +100 -0
  9. package/skills/qingflow-cli/reference/examples/portal/portal_sections_all_types.example.json +6 -7
  10. package/src/qingflow_mcp/app_form_validator.py +20 -3
  11. package/src/qingflow_mcp/builder_facade/app_form.py +137 -17
  12. package/src/qingflow_mcp/builder_facade/models.py +177 -15
  13. package/src/qingflow_mcp/builder_facade/portals_schema.py +397 -0
  14. package/src/qingflow_mcp/builder_facade/schemas/app_form/manifest.json +14 -1
  15. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/complete.json +49 -9
  16. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/address.json +27 -0
  17. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_content_classification.json +146 -0
  18. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_content_extraction.json +146 -0
  19. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_content_generation.json +146 -0
  20. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_document_parsing.json +146 -0
  21. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_image_generation.json +146 -0
  22. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_image_recognition.json +146 -0
  23. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_machine_translation.json +146 -0
  24. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_text_summary.json +146 -0
  25. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/amount.json +2 -2
  26. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/attachment.json +27 -0
  27. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/date_duration.json +146 -0
  28. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/embed_field.json +146 -0
  29. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/image_select.json +146 -0
  30. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/location.json +146 -0
  31. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/number.json +2 -2
  32. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ocr.json +146 -0
  33. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/q_linker.json +2 -2
  34. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/relation.json +27 -0
  35. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/subtable.json +29 -2
  36. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/summary.json +20 -7
  37. package/src/qingflow_mcp/builder_facade/schemas/portals/manifest.json +59 -0
  38. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/complete.json +1397 -0
  39. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/carousel.json +193 -0
  40. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/chart.json +643 -0
  41. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/favourite.json +203 -0
  42. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/filter.json +268 -0
  43. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/grid.json +265 -0
  44. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/link.json +131 -0
  45. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/task.json +199 -0
  46. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/text.json +123 -0
  47. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/view.json +196 -0
  48. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/summary.json +800 -0
  49. package/src/qingflow_mcp/builder_facade/schemas/views/v1alpha1/complete.json +1 -1
  50. package/src/qingflow_mcp/builder_facade/schemas/views/v1alpha1/details/display.json +1 -1
  51. package/src/qingflow_mcp/builder_facade/schemas/views/v1alpha1/summary.json +1 -1
  52. package/src/qingflow_mcp/builder_facade/service.py +1251 -88
  53. package/src/qingflow_mcp/cli/commands/builder.py +132 -5
  54. package/src/qingflow_mcp/public_surface.py +2 -0
  55. package/src/qingflow_mcp/server_app_builder.py +34 -3
  56. package/src/qingflow_mcp/solution/compiler/icon_utils.py +73 -0
  57. package/src/qingflow_mcp/solution/executor.py +5 -2
  58. package/src/qingflow_mcp/tools/ai_builder_tools.py +118 -12
  59. package/src/qingflow_mcp/tools/portal_tools.py +4 -54
  60. package/src/qingflow_mcp/tools/portal_writer.py +59 -0
  61. package/src/qingflow_mcp/tools/solution_tools.py +2 -0
@@ -14,8 +14,10 @@ class PortalTools(ToolBase):
14
14
  类型:门户配置工具。
15
15
  主要职责:
16
16
  1. 查询门户列表与详情;
17
- 2. 维护门户基础信息与配置;
18
- 3. 执行门户发布与删除操作。
17
+ 2. 执行门户发布与删除操作。
18
+
19
+ 创建/更新写入已下沉 ``PortalWriter``(tools/portal_writer.py),
20
+ 公开层唯一入口是 ``builder portal apply`` / ``portal_apply``。
19
21
  """
20
22
 
21
23
  def register(self, mcp: FastMCP) -> None:
@@ -32,18 +34,6 @@ class PortalTools(ToolBase):
32
34
  def portal_get_base_info(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> JSONObject:
33
35
  return self.portal_get_base_info(profile=profile, dash_key=dash_key)
34
36
 
35
- @mcp.tool()
36
- def portal_create(profile: str = DEFAULT_PROFILE, payload: JSONObject | None = None) -> JSONObject:
37
- return self.portal_create(profile=profile, payload=payload or {})
38
-
39
- @mcp.tool(description=self._high_risk_tool_description(operation="update", target="portal base settings"))
40
- def portal_update_base_info(profile: str = DEFAULT_PROFILE, dash_key: str = "", payload: JSONObject | None = None) -> JSONObject:
41
- return self.portal_update_base_info(profile=profile, dash_key=dash_key, payload=payload or {})
42
-
43
- @mcp.tool(description=self._high_risk_tool_description(operation="update", target="portal configuration"))
44
- def portal_update(profile: str = DEFAULT_PROFILE, dash_key: str = "", payload: JSONObject | None = None) -> JSONObject:
45
- return self.portal_update(profile=profile, dash_key=dash_key, payload=payload or {})
46
-
47
37
  @mcp.tool(description=self._high_risk_tool_description(operation="delete", target="portal configuration"))
48
38
  def portal_delete(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> JSONObject:
49
39
  return self.portal_delete(profile=profile, dash_key=dash_key)
@@ -70,16 +60,6 @@ class PortalTools(ToolBase):
70
60
 
71
61
  return self._run(profile, runner, tool_name='门户详情')
72
62
 
73
- def portal_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
74
- """执行门户相关逻辑。"""
75
- body = self._require_dict(payload)
76
-
77
- def runner(session_profile, context):
78
- result = self.backend.request("POST", context, "/dash", json_body=body)
79
- return {"profile": profile, "ws_id": session_profile.selected_ws_id, "result": result}
80
-
81
- return self._run(profile, runner, tool_name='创建门户')
82
-
83
63
  def portal_get_base_info(self, *, profile: str, dash_key: str) -> JSONObject:
84
64
  """执行门户相关逻辑。"""
85
65
  self._require_dash_key(dash_key)
@@ -119,36 +99,6 @@ class PortalTools(ToolBase):
119
99
 
120
100
  return self._run(profile, runner, tool_name='门户基础信息')
121
101
 
122
- def portal_update_base_info(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
123
- """执行门户相关逻辑。"""
124
- self._require_dash_key(dash_key)
125
- body = self._require_dict(payload)
126
-
127
- def runner(session_profile, context):
128
- result = self.backend.request("POST", context, f"/dash/{dash_key}/baseInfo", json_body=body)
129
- return self._attach_human_review_notice(
130
- {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result},
131
- operation="update",
132
- target="portal base settings",
133
- )
134
-
135
- return self._run(profile, runner, tool_name='更新门户基础信息')
136
-
137
- def portal_update(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
138
- """执行门户相关逻辑。"""
139
- self._require_dash_key(dash_key)
140
- body = self._require_dict(payload)
141
-
142
- def runner(session_profile, context):
143
- result = self.backend.request("POST", context, f"/dash/{dash_key}", json_body=body)
144
- return self._attach_human_review_notice(
145
- {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result},
146
- operation="update",
147
- target="portal configuration",
148
- )
149
-
150
- return self._run(profile, runner, tool_name='更新门户配置')
151
-
152
102
  def portal_delete(self, *, profile: str, dash_key: str) -> JSONObject:
153
103
  """执行门户相关逻辑。"""
154
104
  self._require_dash_key(dash_key)
@@ -0,0 +1,59 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from ..errors import QingflowApiError, raise_tool_error
6
+ from ..json_types import JSONObject, JSONValue
7
+ from .base import ToolBase
8
+
9
+
10
+ class PortalWriter(ToolBase):
11
+ """门户写手——POST /dash、POST /dash/{dashKey}、POST /dash/{dashKey}/baseInfo 的唯一落点。
12
+
13
+ 仅限 builder facade 与 solution executor 内部使用;
14
+ 不注册 MCP 工具、不进 public_surface、不暴露 CLI。
15
+ 公开层的门户创建/更新唯一入口是 ``builder portal apply`` / ``portal_apply``。
16
+ """
17
+
18
+ def create_portal(self, *, profile: str, payload: JSONObject) -> JSONObject:
19
+ """创建门户(内部 writer;公开入口请走 builder portal apply)。"""
20
+ body = self._require_dict(payload)
21
+ return self._request(profile, "POST", "/dash", tool_name="创建门户", json_body=body)
22
+
23
+ def update_portal(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
24
+ """更新门户配置(内部 writer;公开入口请走 builder portal apply)。"""
25
+ self._require_dash_key(dash_key)
26
+ body = self._require_dict(payload)
27
+ return self._request(profile, "POST", f"/dash/{dash_key}", tool_name="更新门户配置", json_body=body)
28
+
29
+ def update_portal_base_info(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
30
+ """更新门户基础信息(内部 writer;公开入口请走 builder portal apply)。"""
31
+ self._require_dash_key(dash_key)
32
+ body = self._require_dict(payload)
33
+ return self._request(profile, "POST", f"/dash/{dash_key}/baseInfo", tool_name="更新门户基础信息", json_body=body)
34
+
35
+ def _require_dash_key(self, dash_key: str) -> None:
36
+ if not dash_key:
37
+ raise_tool_error(QingflowApiError.config_error("dash_key is required"))
38
+
39
+ def _request(
40
+ self,
41
+ profile: str,
42
+ method: str,
43
+ path: str,
44
+ *,
45
+ json_body: JSONValue = None,
46
+ params: JSONObject | None = None,
47
+ tool_name: str,
48
+ **extra: Any,
49
+ ) -> JSONObject:
50
+ def runner(session_profile, context):
51
+ result = self.backend.request(method, context, path, json_body=json_body, params=params)
52
+ response: JSONObject = {"profile": profile, "ws_id": session_profile.selected_ws_id, "result": result}
53
+ response.update(extra)
54
+ return response
55
+
56
+ return self._run(profile, runner, tool_name=tool_name)
57
+
58
+
59
+ __all__ = ["PortalWriter", "QingflowApiError", "raise_tool_error"]
@@ -39,6 +39,7 @@ from .record_tools import RecordTools
39
39
  from .role_tools import RoleTools
40
40
  from .view_tools import ViewTools
41
41
  from .view_writer import ViewWriter
42
+ from .portal_writer import PortalWriter
42
43
  from .workspace_tools import WorkspaceTools
43
44
 
44
45
  STAGED_BUILD_MODES = {"preflight", "plan", "apply", "repair"}
@@ -1431,6 +1432,7 @@ class SolutionTools(ToolBase):
1431
1432
  view_writer=ViewWriter(self.sessions, self.backend),
1432
1433
  chart_tools=QingbiReportTools(self.sessions, self.backend),
1433
1434
  portal_tools=PortalTools(self.sessions, self.backend),
1435
+ portal_writer=PortalWriter(self.sessions, self.backend),
1434
1436
  navigation_tools=NavigationTools(self.sessions, self.backend),
1435
1437
  )
1436
1438