@josephyan/qingflow-cli 0.2.0-beta.60 → 0.2.0-beta.61

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 CHANGED
@@ -3,13 +3,13 @@
3
3
  Install:
4
4
 
5
5
  ```bash
6
- npm install @josephyan/qingflow-cli@0.2.0-beta.60
6
+ npm install @josephyan/qingflow-cli@0.2.0-beta.61
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @josephyan/qingflow-cli@0.2.0-beta.60 qingflow
12
+ npx -y -p @josephyan/qingflow-cli@0.2.0-beta.61 qingflow
13
13
  ```
14
14
 
15
15
  Environment:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyan/qingflow-cli",
3
- "version": "0.2.0-beta.60",
3
+ "version": "0.2.0-beta.61",
4
4
  "description": "Human-friendly Qingflow command line interface for auth, record operations, import, tasks, and stable builder flows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "0.2.0b60"
7
+ version = "0.2.0b61"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -2955,19 +2955,24 @@ class AiBuilderFacade:
2955
2955
  warnings: list[dict[str, Any]] = []
2956
2956
  if not layout_summary_verified:
2957
2957
  warnings.append(_warning("LAYOUT_SUMMARY_UNVERIFIED", "layout summary is incomplete relative to raw schema readback"))
2958
+ if fallback_applied is not None and layout_verified and layout_summary_verified:
2959
+ warnings.append(_warning("LAYOUT_FALLBACK_APPLIED", "layout readback normalized sectioned layout into flat layout while preserving field placement"))
2958
2960
  response = {
2959
- "status": "success" if layout_verified and layout_summary_verified and fallback_applied is None else "partial_success",
2961
+ "status": "success" if layout_verified and layout_summary_verified else "partial_success",
2960
2962
  "error_code": (
2961
2963
  None
2962
- if layout_verified and layout_summary_verified and fallback_applied is None
2964
+ if layout_verified and layout_summary_verified
2963
2965
  else "LAYOUT_SUMMARY_UNVERIFIED"
2964
2966
  if not layout_summary_verified
2965
2967
  else "LAYOUT_READBACK_MISMATCH"
2966
2968
  ),
2967
- "recoverable": not (layout_verified and layout_summary_verified and fallback_applied is None),
2969
+ "recoverable": not (layout_verified and layout_summary_verified),
2968
2970
  "message": (
2971
+ "applied app layout with flattened section fallback"
2972
+ if layout_verified and layout_summary_verified and fallback_applied is not None
2973
+ else
2969
2974
  "applied app layout"
2970
- if layout_verified and layout_summary_verified and fallback_applied is None
2975
+ if layout_verified and layout_summary_verified
2971
2976
  else "applied app layout; raw layout verified but compact summary is incomplete"
2972
2977
  if layout_verified and not layout_summary_verified
2973
2978
  else "applied app layout with flattened section fallback"
@@ -7291,17 +7296,22 @@ def _workflow_branch_structure_verified(*, current_workflow: Any, requested_node
7291
7296
 
7292
7297
  def _workflow_nodes_semantically_equal(*, current_workflow: Any, requested_nodes: list[dict[str, Any]]) -> bool:
7293
7298
  current_nodes = _summarize_workflow_nodes(current_workflow)
7299
+ current_effective = [
7300
+ node
7301
+ for node in current_nodes
7302
+ if _normalize_existing_workflow_node_type(node.get("type"), node.get("deal_type")) not in {"start", "end"}
7303
+ ]
7294
7304
  requested_effective = [
7295
7305
  node for node in requested_nodes if str(node.get("type") or "") not in {"start", "end"}
7296
7306
  ]
7297
- if not current_nodes or not requested_effective or len(current_nodes) != len(requested_effective):
7307
+ if not current_effective or not requested_effective or len(current_effective) != len(requested_effective):
7298
7308
  return False
7299
7309
  current_signatures = sorted(
7300
7310
  (
7301
7311
  _normalize_existing_workflow_node_type(node.get("type"), node.get("deal_type")),
7302
7312
  str(node.get("name") or "").strip(),
7303
7313
  )
7304
- for node in current_nodes
7314
+ for node in current_effective
7305
7315
  )
7306
7316
  requested_signatures = sorted(
7307
7317
  (
@@ -7314,7 +7324,7 @@ def _workflow_nodes_semantically_equal(*, current_workflow: Any, requested_nodes
7314
7324
 
7315
7325
 
7316
7326
  def _normalize_existing_workflow_node_type(raw_type: Any, deal_type: Any) -> str:
7317
- normalized = str(raw_type or "").strip().lower()
7327
+ normalized = "" if raw_type is None else str(raw_type).strip().lower()
7318
7328
  if normalized in {"audit", "approve"}:
7319
7329
  return "approve"
7320
7330
  if normalized in {"fill", "copy", "branch", "condition", "webhook", "start", "end"}: