@josephyan/qingflow-cli 0.2.0-beta.1000
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/docs/local-agent-install.md +309 -0
- package/entry_point.py +13 -0
- package/npm/bin/qingflow.mjs +5 -0
- package/npm/lib/runtime.mjs +346 -0
- package/npm/scripts/postinstall.mjs +16 -0
- package/package.json +34 -0
- package/pyproject.toml +67 -0
- package/qingflow +15 -0
- package/src/qingflow_mcp/__init__.py +37 -0
- package/src/qingflow_mcp/__main__.py +5 -0
- package/src/qingflow_mcp/backend_client.py +649 -0
- package/src/qingflow_mcp/builder_facade/__init__.py +3 -0
- package/src/qingflow_mcp/builder_facade/models.py +1846 -0
- package/src/qingflow_mcp/builder_facade/service.py +16502 -0
- package/src/qingflow_mcp/cli/__init__.py +1 -0
- package/src/qingflow_mcp/cli/commands/__init__.py +18 -0
- package/src/qingflow_mcp/cli/commands/app.py +40 -0
- package/src/qingflow_mcp/cli/commands/auth.py +112 -0
- package/src/qingflow_mcp/cli/commands/builder.py +539 -0
- package/src/qingflow_mcp/cli/commands/chart.py +18 -0
- package/src/qingflow_mcp/cli/commands/common.py +62 -0
- package/src/qingflow_mcp/cli/commands/imports.py +96 -0
- package/src/qingflow_mcp/cli/commands/portal.py +25 -0
- package/src/qingflow_mcp/cli/commands/record.py +331 -0
- package/src/qingflow_mcp/cli/commands/repo.py +80 -0
- package/src/qingflow_mcp/cli/commands/task.py +141 -0
- package/src/qingflow_mcp/cli/commands/view.py +18 -0
- package/src/qingflow_mcp/cli/commands/workspace.py +110 -0
- package/src/qingflow_mcp/cli/context.py +60 -0
- package/src/qingflow_mcp/cli/formatters.py +573 -0
- package/src/qingflow_mcp/cli/json_io.py +50 -0
- package/src/qingflow_mcp/cli/main.py +186 -0
- package/src/qingflow_mcp/cli/qingflow_login.py +116 -0
- package/src/qingflow_mcp/cli/terminal_ui.py +173 -0
- package/src/qingflow_mcp/config.py +407 -0
- package/src/qingflow_mcp/errors.py +66 -0
- package/src/qingflow_mcp/id_utils.py +49 -0
- package/src/qingflow_mcp/import_store.py +121 -0
- package/src/qingflow_mcp/json_types.py +18 -0
- package/src/qingflow_mcp/list_type_labels.py +76 -0
- package/src/qingflow_mcp/public_surface.py +243 -0
- package/src/qingflow_mcp/repository_store.py +71 -0
- package/src/qingflow_mcp/response_trim.py +841 -0
- package/src/qingflow_mcp/server.py +216 -0
- package/src/qingflow_mcp/server_app_builder.py +543 -0
- package/src/qingflow_mcp/server_app_user.py +386 -0
- package/src/qingflow_mcp/session_store.py +369 -0
- package/src/qingflow_mcp/solution/__init__.py +6 -0
- package/src/qingflow_mcp/solution/build_assembly_store.py +181 -0
- package/src/qingflow_mcp/solution/compiler/__init__.py +282 -0
- package/src/qingflow_mcp/solution/compiler/chart_compiler.py +96 -0
- package/src/qingflow_mcp/solution/compiler/form_compiler.py +495 -0
- package/src/qingflow_mcp/solution/compiler/icon_utils.py +187 -0
- package/src/qingflow_mcp/solution/compiler/navigation_compiler.py +57 -0
- package/src/qingflow_mcp/solution/compiler/package_compiler.py +19 -0
- package/src/qingflow_mcp/solution/compiler/portal_compiler.py +60 -0
- package/src/qingflow_mcp/solution/compiler/view_compiler.py +51 -0
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
- package/src/qingflow_mcp/solution/design_session.py +222 -0
- package/src/qingflow_mcp/solution/design_store.py +100 -0
- package/src/qingflow_mcp/solution/executor.py +2398 -0
- package/src/qingflow_mcp/solution/normalizer.py +23 -0
- package/src/qingflow_mcp/solution/requirements_builder.py +536 -0
- package/src/qingflow_mcp/solution/run_store.py +244 -0
- package/src/qingflow_mcp/solution/spec_models.py +855 -0
- package/src/qingflow_mcp/tools/__init__.py +1 -0
- package/src/qingflow_mcp/tools/ai_builder_tools.py +3449 -0
- package/src/qingflow_mcp/tools/app_tools.py +926 -0
- package/src/qingflow_mcp/tools/approval_tools.py +1062 -0
- package/src/qingflow_mcp/tools/auth_tools.py +1133 -0
- package/src/qingflow_mcp/tools/base.py +281 -0
- package/src/qingflow_mcp/tools/code_block_tools.py +777 -0
- package/src/qingflow_mcp/tools/custom_button_tools.py +202 -0
- package/src/qingflow_mcp/tools/directory_tools.py +675 -0
- package/src/qingflow_mcp/tools/feedback_tools.py +238 -0
- package/src/qingflow_mcp/tools/file_tools.py +409 -0
- package/src/qingflow_mcp/tools/import_tools.py +2223 -0
- package/src/qingflow_mcp/tools/navigation_tools.py +210 -0
- package/src/qingflow_mcp/tools/package_tools.py +326 -0
- package/src/qingflow_mcp/tools/portal_tools.py +158 -0
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +374 -0
- package/src/qingflow_mcp/tools/record_tools.py +14291 -0
- package/src/qingflow_mcp/tools/repository_dev_tools.py +552 -0
- package/src/qingflow_mcp/tools/resource_read_tools.py +503 -0
- package/src/qingflow_mcp/tools/role_tools.py +112 -0
- package/src/qingflow_mcp/tools/solution_tools.py +4054 -0
- package/src/qingflow_mcp/tools/task_context_tools.py +2986 -0
- package/src/qingflow_mcp/tools/task_tools.py +889 -0
- package/src/qingflow_mcp/tools/view_tools.py +335 -0
- package/src/qingflow_mcp/tools/workflow_tools.py +376 -0
- package/src/qingflow_mcp/tools/workspace_tools.py +266 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from copy import deepcopy
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from ..config import get_mcp_home
|
|
11
|
+
from .design_session import DesignStage
|
|
12
|
+
from .run_store import resolve_storage_path, utc_now
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_design_sessions_path() -> Path:
|
|
16
|
+
custom_home = os.getenv("QINGFLOW_MCP_DESIGN_HOME")
|
|
17
|
+
if custom_home:
|
|
18
|
+
return Path(custom_home).expanduser()
|
|
19
|
+
return get_mcp_home() / "design-sessions"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(slots=True)
|
|
23
|
+
class DesignSessionStore:
|
|
24
|
+
path: Path
|
|
25
|
+
data: dict[str, Any]
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def open(cls, *, session_id: str, metadata: dict[str, Any] | None = None) -> "DesignSessionStore":
|
|
29
|
+
base_dir = get_design_sessions_path()
|
|
30
|
+
base_dir.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
path = resolve_storage_path(base_dir, key=session_id, id_field="session_id")
|
|
32
|
+
if path.exists():
|
|
33
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
34
|
+
stored_session_id = data.get("session_id")
|
|
35
|
+
if stored_session_id != session_id:
|
|
36
|
+
raise ValueError(f"existing design session at '{path}' belongs to '{stored_session_id}', not '{session_id}'")
|
|
37
|
+
else:
|
|
38
|
+
data = {
|
|
39
|
+
"session_id": session_id,
|
|
40
|
+
"status": "active",
|
|
41
|
+
"current_stage": DesignStage.discover.value,
|
|
42
|
+
"metadata": metadata or {},
|
|
43
|
+
"stage_payloads": {
|
|
44
|
+
DesignStage.discover.value: {},
|
|
45
|
+
DesignStage.design.value: {},
|
|
46
|
+
DesignStage.experience.value: {},
|
|
47
|
+
},
|
|
48
|
+
"stage_results": {},
|
|
49
|
+
"merged_design_spec": {},
|
|
50
|
+
"normalized_solution_spec": None,
|
|
51
|
+
"execution_plan": None,
|
|
52
|
+
"created_at": utc_now(),
|
|
53
|
+
"updated_at": utc_now(),
|
|
54
|
+
}
|
|
55
|
+
path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
56
|
+
return cls(path=path, data=data)
|
|
57
|
+
|
|
58
|
+
def set_metadata(self, metadata: dict[str, Any]) -> None:
|
|
59
|
+
if metadata:
|
|
60
|
+
self.data["metadata"] = deepcopy(metadata)
|
|
61
|
+
self._flush()
|
|
62
|
+
|
|
63
|
+
def set_stage_payload(self, stage: str, payload: dict[str, Any]) -> None:
|
|
64
|
+
self.data.setdefault("stage_payloads", {})
|
|
65
|
+
self.data["stage_payloads"][stage] = deepcopy(payload)
|
|
66
|
+
self._flush()
|
|
67
|
+
|
|
68
|
+
def get_stage_payload(self, stage: str) -> dict[str, Any]:
|
|
69
|
+
return deepcopy(self.data.get("stage_payloads", {}).get(stage, {}))
|
|
70
|
+
|
|
71
|
+
def update_progress(self, *, status: str, current_stage: str, stage_results: dict[str, Any], merged_design_spec: dict[str, Any]) -> None:
|
|
72
|
+
self.data["status"] = status
|
|
73
|
+
self.data["current_stage"] = current_stage
|
|
74
|
+
self.data["stage_results"] = deepcopy(stage_results)
|
|
75
|
+
self.data["merged_design_spec"] = deepcopy(merged_design_spec)
|
|
76
|
+
self._flush()
|
|
77
|
+
|
|
78
|
+
def mark_finalized(self, *, normalized_solution_spec: dict[str, Any], execution_plan: dict[str, Any]) -> None:
|
|
79
|
+
self.data["status"] = "finalized"
|
|
80
|
+
self.data["current_stage"] = DesignStage.finalize.value
|
|
81
|
+
self.data["normalized_solution_spec"] = deepcopy(normalized_solution_spec)
|
|
82
|
+
self.data["execution_plan"] = deepcopy(execution_plan)
|
|
83
|
+
self._flush()
|
|
84
|
+
|
|
85
|
+
def summary(self) -> dict[str, Any]:
|
|
86
|
+
return {
|
|
87
|
+
"session_id": self.data["session_id"],
|
|
88
|
+
"status": self.data["status"],
|
|
89
|
+
"current_stage": self.data["current_stage"],
|
|
90
|
+
"metadata": deepcopy(self.data.get("metadata", {})),
|
|
91
|
+
"stage_results": deepcopy(self.data.get("stage_results", {})),
|
|
92
|
+
"merged_design_spec": deepcopy(self.data.get("merged_design_spec", {})),
|
|
93
|
+
"normalized_solution_spec": deepcopy(self.data.get("normalized_solution_spec")),
|
|
94
|
+
"execution_plan": deepcopy(self.data.get("execution_plan")),
|
|
95
|
+
"session_path": str(self.path),
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
def _flush(self) -> None:
|
|
99
|
+
self.data["updated_at"] = utc_now()
|
|
100
|
+
self.path.write_text(json.dumps(self.data, ensure_ascii=False, indent=2), encoding="utf-8")
|