@josephyan/qingflow-cli 0.2.0-beta.985 → 0.2.0-beta.986

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 (42) hide show
  1. package/README.md +2 -2
  2. package/docs/local-agent-install.md +70 -11
  3. package/package.json +1 -1
  4. package/pyproject.toml +1 -1
  5. package/src/qingflow_mcp/__init__.py +1 -1
  6. package/src/qingflow_mcp/builder_facade/service.py +1 -1
  7. package/src/qingflow_mcp/cli/commands/auth.py +14 -43
  8. package/src/qingflow_mcp/cli/commands/workspace.py +0 -8
  9. package/src/qingflow_mcp/cli/formatters.py +0 -21
  10. package/src/qingflow_mcp/config.py +39 -0
  11. package/src/qingflow_mcp/errors.py +2 -2
  12. package/src/qingflow_mcp/public_surface.py +2 -6
  13. package/src/qingflow_mcp/response_trim.py +1 -8
  14. package/src/qingflow_mcp/server.py +1 -1
  15. package/src/qingflow_mcp/server_app_builder.py +4 -28
  16. package/src/qingflow_mcp/server_app_user.py +4 -28
  17. package/src/qingflow_mcp/session_store.py +31 -5
  18. package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
  19. package/src/qingflow_mcp/tools/app_tools.py +51 -1
  20. package/src/qingflow_mcp/tools/approval_tools.py +82 -1
  21. package/src/qingflow_mcp/tools/auth_tools.py +258 -288
  22. package/src/qingflow_mcp/tools/base.py +204 -4
  23. package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
  24. package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
  25. package/src/qingflow_mcp/tools/directory_tools.py +28 -1
  26. package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
  27. package/src/qingflow_mcp/tools/file_tools.py +25 -1
  28. package/src/qingflow_mcp/tools/import_tools.py +40 -1
  29. package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
  30. package/src/qingflow_mcp/tools/package_tools.py +37 -1
  31. package/src/qingflow_mcp/tools/portal_tools.py +28 -1
  32. package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
  33. package/src/qingflow_mcp/tools/record_tools.py +255 -2
  34. package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
  35. package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
  36. package/src/qingflow_mcp/tools/role_tools.py +19 -1
  37. package/src/qingflow_mcp/tools/solution_tools.py +56 -1
  38. package/src/qingflow_mcp/tools/task_context_tools.py +72 -1
  39. package/src/qingflow_mcp/tools/task_tools.py +49 -3
  40. package/src/qingflow_mcp/tools/view_tools.py +56 -1
  41. package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
  42. package/src/qingflow_mcp/tools/workspace_tools.py +14 -225
@@ -29,6 +29,9 @@ class SessionProfile:
29
29
  base_url: str
30
30
  qf_version: str | None
31
31
  qf_version_source: str | None
32
+ token: str | None
33
+ login_token: str | None
34
+ credential: str | None
32
35
  uid: int
33
36
  email: str | None
34
37
  nick_name: str | None
@@ -45,6 +48,9 @@ class SessionProfile:
45
48
  base_url=value["base_url"],
46
49
  qf_version=value.get("qf_version"),
47
50
  qf_version_source=value.get("qf_version_source"),
51
+ token=value.get("token"),
52
+ login_token=value.get("login_token"),
53
+ credential=value.get("credential"),
48
54
  uid=value["uid"],
49
55
  email=value.get("email"),
50
56
  nick_name=value.get("nick_name"),
@@ -60,6 +66,7 @@ class SessionProfile:
60
66
  class BackendSession:
61
67
  token: str
62
68
  login_token: str | None
69
+ credential: str | None
63
70
  profile: str
64
71
  base_url: str
65
72
  qf_version: str | None
@@ -85,6 +92,7 @@ class SessionStore:
85
92
  qf_version_source: str | None = None,
86
93
  token: str,
87
94
  login_token: str | None,
95
+ credential: str | None = None,
88
96
  uid: int,
89
97
  email: str | None,
90
98
  nick_name: str | None,
@@ -99,14 +107,22 @@ class SessionStore:
99
107
  self._set_secret(self._login_token_key(profile), login_token)
100
108
  else:
101
109
  self._delete_secret(self._login_token_key(profile))
110
+ if credential:
111
+ self._set_secret(self._credential_key(profile), credential)
112
+ else:
113
+ self._delete_secret(self._credential_key(profile))
102
114
  else:
103
115
  self._delete_secret(self._token_key(profile))
104
116
  self._delete_secret(self._login_token_key(profile))
117
+ self._delete_secret(self._credential_key(profile))
105
118
  session_profile = SessionProfile(
106
119
  profile=profile,
107
120
  base_url=normalize_base_url(base_url) or base_url,
108
121
  qf_version=(str(qf_version).strip() or None) if qf_version is not None else None,
109
122
  qf_version_source=(str(qf_version_source).strip() or None) if qf_version_source is not None else None,
123
+ token=str(token).strip() or None,
124
+ login_token=(str(login_token).strip() or None) if login_token is not None else None,
125
+ credential=(str(credential).strip() or None) if credential is not None else None,
110
126
  uid=uid,
111
127
  email=email,
112
128
  nick_name=nick_name,
@@ -117,8 +133,9 @@ class SessionStore:
117
133
  updated_at=now,
118
134
  )
119
135
  self._memory_sessions[profile] = BackendSession(
120
- token=token,
121
- login_token=login_token,
136
+ token=session_profile.token or token,
137
+ login_token=session_profile.login_token,
138
+ credential=session_profile.credential,
122
139
  profile=profile,
123
140
  base_url=session_profile.base_url,
124
141
  qf_version=session_profile.qf_version,
@@ -146,14 +163,19 @@ class SessionStore:
146
163
  memory_session.qf_version = session_profile.qf_version
147
164
  memory_session.qf_version_source = session_profile.qf_version_source
148
165
  return memory_session
149
- if not session_profile or not session_profile.persisted:
166
+ if not session_profile:
150
167
  return None
151
- token = self._get_secret(self._token_key(profile))
168
+ token = self._get_secret(self._token_key(profile)) if session_profile.persisted else None
169
+ if not token:
170
+ token = session_profile.token
152
171
  if not token:
153
172
  return None
173
+ login_token = self._get_secret(self._login_token_key(profile)) if session_profile.persisted else None
174
+ credential = self._get_secret(self._credential_key(profile)) if session_profile.persisted else None
154
175
  backend_session = BackendSession(
155
176
  token=token,
156
- login_token=self._get_secret(self._login_token_key(profile)),
177
+ login_token=login_token or session_profile.login_token,
178
+ credential=credential or session_profile.credential,
157
179
  profile=profile,
158
180
  base_url=session_profile.base_url,
159
181
  qf_version=session_profile.qf_version,
@@ -234,6 +256,7 @@ class SessionStore:
234
256
  self._logged_out_profiles.discard(profile)
235
257
  self._delete_secret(self._token_key(profile))
236
258
  self._delete_secret(self._login_token_key(profile))
259
+ self._delete_secret(self._credential_key(profile))
237
260
  payload = self._load_profiles()
238
261
  profiles = payload.get("profiles", {})
239
262
  if profile in profiles:
@@ -249,6 +272,9 @@ class SessionStore:
249
272
  def _login_token_key(self, profile: str) -> str:
250
273
  return f"{profile}:login-token"
251
274
 
275
+ def _credential_key(self, profile: str) -> str:
276
+ return f"{profile}:credential"
277
+
252
278
  def _upsert_profile(self, profile: SessionProfile) -> None:
253
279
  payload = self._load_profiles()
254
280
  payload.setdefault("profiles", {})[profile.profile] = asdict(profile)