@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.
Files changed (92) hide show
  1. package/README.md +31 -0
  2. package/docs/local-agent-install.md +309 -0
  3. package/entry_point.py +13 -0
  4. package/npm/bin/qingflow.mjs +5 -0
  5. package/npm/lib/runtime.mjs +346 -0
  6. package/npm/scripts/postinstall.mjs +16 -0
  7. package/package.json +34 -0
  8. package/pyproject.toml +67 -0
  9. package/qingflow +15 -0
  10. package/src/qingflow_mcp/__init__.py +37 -0
  11. package/src/qingflow_mcp/__main__.py +5 -0
  12. package/src/qingflow_mcp/backend_client.py +649 -0
  13. package/src/qingflow_mcp/builder_facade/__init__.py +3 -0
  14. package/src/qingflow_mcp/builder_facade/models.py +1846 -0
  15. package/src/qingflow_mcp/builder_facade/service.py +16502 -0
  16. package/src/qingflow_mcp/cli/__init__.py +1 -0
  17. package/src/qingflow_mcp/cli/commands/__init__.py +18 -0
  18. package/src/qingflow_mcp/cli/commands/app.py +40 -0
  19. package/src/qingflow_mcp/cli/commands/auth.py +112 -0
  20. package/src/qingflow_mcp/cli/commands/builder.py +539 -0
  21. package/src/qingflow_mcp/cli/commands/chart.py +18 -0
  22. package/src/qingflow_mcp/cli/commands/common.py +62 -0
  23. package/src/qingflow_mcp/cli/commands/imports.py +96 -0
  24. package/src/qingflow_mcp/cli/commands/portal.py +25 -0
  25. package/src/qingflow_mcp/cli/commands/record.py +331 -0
  26. package/src/qingflow_mcp/cli/commands/repo.py +80 -0
  27. package/src/qingflow_mcp/cli/commands/task.py +141 -0
  28. package/src/qingflow_mcp/cli/commands/view.py +18 -0
  29. package/src/qingflow_mcp/cli/commands/workspace.py +110 -0
  30. package/src/qingflow_mcp/cli/context.py +60 -0
  31. package/src/qingflow_mcp/cli/formatters.py +573 -0
  32. package/src/qingflow_mcp/cli/json_io.py +50 -0
  33. package/src/qingflow_mcp/cli/main.py +186 -0
  34. package/src/qingflow_mcp/cli/qingflow_login.py +116 -0
  35. package/src/qingflow_mcp/cli/terminal_ui.py +173 -0
  36. package/src/qingflow_mcp/config.py +407 -0
  37. package/src/qingflow_mcp/errors.py +66 -0
  38. package/src/qingflow_mcp/id_utils.py +49 -0
  39. package/src/qingflow_mcp/import_store.py +121 -0
  40. package/src/qingflow_mcp/json_types.py +18 -0
  41. package/src/qingflow_mcp/list_type_labels.py +76 -0
  42. package/src/qingflow_mcp/public_surface.py +243 -0
  43. package/src/qingflow_mcp/repository_store.py +71 -0
  44. package/src/qingflow_mcp/response_trim.py +841 -0
  45. package/src/qingflow_mcp/server.py +216 -0
  46. package/src/qingflow_mcp/server_app_builder.py +543 -0
  47. package/src/qingflow_mcp/server_app_user.py +386 -0
  48. package/src/qingflow_mcp/session_store.py +369 -0
  49. package/src/qingflow_mcp/solution/__init__.py +6 -0
  50. package/src/qingflow_mcp/solution/build_assembly_store.py +181 -0
  51. package/src/qingflow_mcp/solution/compiler/__init__.py +282 -0
  52. package/src/qingflow_mcp/solution/compiler/chart_compiler.py +96 -0
  53. package/src/qingflow_mcp/solution/compiler/form_compiler.py +495 -0
  54. package/src/qingflow_mcp/solution/compiler/icon_utils.py +187 -0
  55. package/src/qingflow_mcp/solution/compiler/navigation_compiler.py +57 -0
  56. package/src/qingflow_mcp/solution/compiler/package_compiler.py +19 -0
  57. package/src/qingflow_mcp/solution/compiler/portal_compiler.py +60 -0
  58. package/src/qingflow_mcp/solution/compiler/view_compiler.py +51 -0
  59. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
  60. package/src/qingflow_mcp/solution/design_session.py +222 -0
  61. package/src/qingflow_mcp/solution/design_store.py +100 -0
  62. package/src/qingflow_mcp/solution/executor.py +2398 -0
  63. package/src/qingflow_mcp/solution/normalizer.py +23 -0
  64. package/src/qingflow_mcp/solution/requirements_builder.py +536 -0
  65. package/src/qingflow_mcp/solution/run_store.py +244 -0
  66. package/src/qingflow_mcp/solution/spec_models.py +855 -0
  67. package/src/qingflow_mcp/tools/__init__.py +1 -0
  68. package/src/qingflow_mcp/tools/ai_builder_tools.py +3449 -0
  69. package/src/qingflow_mcp/tools/app_tools.py +926 -0
  70. package/src/qingflow_mcp/tools/approval_tools.py +1062 -0
  71. package/src/qingflow_mcp/tools/auth_tools.py +1133 -0
  72. package/src/qingflow_mcp/tools/base.py +281 -0
  73. package/src/qingflow_mcp/tools/code_block_tools.py +777 -0
  74. package/src/qingflow_mcp/tools/custom_button_tools.py +202 -0
  75. package/src/qingflow_mcp/tools/directory_tools.py +675 -0
  76. package/src/qingflow_mcp/tools/feedback_tools.py +238 -0
  77. package/src/qingflow_mcp/tools/file_tools.py +409 -0
  78. package/src/qingflow_mcp/tools/import_tools.py +2223 -0
  79. package/src/qingflow_mcp/tools/navigation_tools.py +210 -0
  80. package/src/qingflow_mcp/tools/package_tools.py +326 -0
  81. package/src/qingflow_mcp/tools/portal_tools.py +158 -0
  82. package/src/qingflow_mcp/tools/qingbi_report_tools.py +374 -0
  83. package/src/qingflow_mcp/tools/record_tools.py +14291 -0
  84. package/src/qingflow_mcp/tools/repository_dev_tools.py +552 -0
  85. package/src/qingflow_mcp/tools/resource_read_tools.py +503 -0
  86. package/src/qingflow_mcp/tools/role_tools.py +112 -0
  87. package/src/qingflow_mcp/tools/solution_tools.py +4054 -0
  88. package/src/qingflow_mcp/tools/task_context_tools.py +2986 -0
  89. package/src/qingflow_mcp/tools/task_tools.py +889 -0
  90. package/src/qingflow_mcp/tools/view_tools.py +335 -0
  91. package/src/qingflow_mcp/tools/workflow_tools.py +376 -0
  92. 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")