@qingflow-tech/qingflow-app-user-mcp 1.0.10 → 1.0.11

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 @qingflow-tech/qingflow-app-user-mcp@1.0.10
6
+ npm install @qingflow-tech/qingflow-app-user-mcp@1.0.11
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @qingflow-tech/qingflow-app-user-mcp@1.0.10 qingflow-app-user-mcp
12
+ npx -y -p @qingflow-tech/qingflow-app-user-mcp@1.0.11 qingflow-app-user-mcp
13
13
  ```
14
14
 
15
15
  Environment:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qingflow-tech/qingflow-app-user-mcp",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Operational end-user MCP for Qingflow records, tasks, comments, and directory workflows.",
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 = "1.0.10"
7
+ version = "1.0.11"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1893,8 +1893,9 @@ class PortalComponentPositionPatch(StrictModel):
1893
1893
  pc_h: int = Field(default=8, validation_alias=AliasChoices("pc_h", "pcH", "h"))
1894
1894
  mobile_x: int = Field(default=0, validation_alias=AliasChoices("mobile_x", "mobileX"))
1895
1895
  mobile_y: int = Field(default=0, validation_alias=AliasChoices("mobile_y", "mobileY"))
1896
- mobile_w: int = Field(default=12, validation_alias=AliasChoices("mobile_w", "mobileW"))
1896
+ mobile_w: int = Field(default=6, validation_alias=AliasChoices("mobile_w", "mobileW"))
1897
1897
  mobile_h: int = Field(default=8, validation_alias=AliasChoices("mobile_h", "mobileH"))
1898
+ mobile_provided: bool = Field(default=False, exclude=True)
1898
1899
 
1899
1900
  @model_validator(mode="before")
1900
1901
  @classmethod
@@ -1904,6 +1905,8 @@ class PortalComponentPositionPatch(StrictModel):
1904
1905
  payload = dict(value)
1905
1906
  pc = payload.pop("pc", None)
1906
1907
  mobile = payload.pop("mobile", None)
1908
+ mobile_keys = {"mobile_x", "mobileX", "mobile_y", "mobileY", "mobile_w", "mobileW", "mobile_h", "mobileH"}
1909
+ mobile_provided = isinstance(mobile, dict) or any(key in payload for key in mobile_keys)
1907
1910
  if isinstance(pc, dict):
1908
1911
  if "pc_x" not in payload and "x" in pc:
1909
1912
  payload["pc_x"] = pc.get("x")
@@ -1922,6 +1925,7 @@ class PortalComponentPositionPatch(StrictModel):
1922
1925
  payload["mobile_w"] = mobile.get("cols")
1923
1926
  if "mobile_h" not in payload and "rows" in mobile:
1924
1927
  payload["mobile_h"] = mobile.get("rows")
1928
+ payload["mobile_provided"] = mobile_provided
1925
1929
  return payload
1926
1930
 
1927
1931
 
@@ -2003,9 +2007,10 @@ class PortalSectionPatch(StrictModel):
2003
2007
  class PortalApplyRequest(StrictModel):
2004
2008
  dash_key: str | None = None
2005
2009
  dash_name: str | None = None
2006
- package_tag_id: int | None = None
2010
+ package_tag_id: int | None = Field(default=None, validation_alias=AliasChoices("package_tag_id", "packageTagId", "package_id", "packageId"))
2007
2011
  publish: bool = True
2008
2012
  sections: list[PortalSectionPatch] = Field(default_factory=list)
2013
+ layout_preset: str | None = Field(default=None, validation_alias=AliasChoices("layout_preset", "layoutPreset"))
2009
2014
  visibility: VisibilityPatch | None = None
2010
2015
  auth: dict[str, Any] | None = None
2011
2016
  icon: str | None = None
@@ -2014,6 +2019,33 @@ class PortalApplyRequest(StrictModel):
2014
2019
  dash_global_config: dict[str, Any] | None = Field(default=None, validation_alias=AliasChoices("dash_global_config", "dashGlobalConfig"))
2015
2020
  config: dict[str, Any] = Field(default_factory=dict)
2016
2021
 
2022
+ @model_validator(mode="before")
2023
+ @classmethod
2024
+ def normalize_compat_payload(cls, value: Any) -> Any:
2025
+ if not isinstance(value, dict):
2026
+ return value
2027
+ payload = dict(value)
2028
+ if "dash_name" not in payload and "dashName" not in payload and "name" in payload:
2029
+ payload["dash_name"] = payload.pop("name")
2030
+ if "sections" not in payload and "pages" in payload:
2031
+ pages = payload.pop("pages")
2032
+ if not isinstance(pages, list):
2033
+ raise ValueError("portal pages must be a list")
2034
+ if len(pages) != 1:
2035
+ raise ValueError("portal_apply currently supports a single page; pass one page or flatten components into sections")
2036
+ page = pages[0]
2037
+ if not isinstance(page, dict):
2038
+ raise ValueError("portal pages[0] must be an object")
2039
+ components = page.get("components")
2040
+ if not isinstance(components, list) or not components:
2041
+ raise ValueError("portal pages[0].components must be a non-empty list")
2042
+ payload["sections"] = components
2043
+ if "theme" in payload:
2044
+ payload.pop("theme")
2045
+ if "type" in payload:
2046
+ payload.pop("type")
2047
+ return payload
2048
+
2017
2049
  @model_validator(mode="after")
2018
2050
  def validate_shape(self) -> "PortalApplyRequest":
2019
2051
  if not self.dash_key and not self.package_tag_id:
@@ -2024,6 +2056,8 @@ class PortalApplyRequest(StrictModel):
2024
2056
  raise ValueError("portal apply requires a non-empty sections list when creating a portal")
2025
2057
  if self.visibility is not None and self.auth is not None:
2026
2058
  raise ValueError("visibility and auth cannot be provided together")
2059
+ if self.layout_preset is not None and self.layout_preset not in {"auto", "dashboard_2col", "dashboard_3col"}:
2060
+ raise ValueError("layout_preset must be one of: auto, dashboard_2col, dashboard_3col")
2027
2061
  return self
2028
2062
 
2029
2063
 
@@ -2038,6 +2072,7 @@ class AppGetResponse(StrictModel):
2038
2072
  name: str | None = None
2039
2073
  title: str | None = None
2040
2074
  app_icon: str | None = None
2075
+ icon_config: dict[str, Any] = Field(default_factory=dict)
2041
2076
  visibility: dict[str, Any] = Field(default_factory=dict)
2042
2077
  tag_ids: list[int] = Field(default_factory=list)
2043
2078
  publish_status: int | None = None
@@ -2062,6 +2097,8 @@ class AppGetFieldsResponse(StrictModel):
2062
2097
  app_key: str
2063
2098
  fields: list[dict[str, Any]] = Field(default_factory=list)
2064
2099
  field_count: int = 0
2100
+ chart_fields: list[dict[str, Any]] = Field(default_factory=list)
2101
+ chart_field_count: int = 0
2065
2102
  form_settings: dict[str, Any] = Field(default_factory=dict)
2066
2103
 
2067
2104
 
@@ -2109,6 +2146,7 @@ class PortalReadSummaryResponse(StrictModel):
2109
2146
  dash_name: str | None = None
2110
2147
  package_tag_ids: list[int] = Field(default_factory=list)
2111
2148
  dash_icon: str | None = None
2149
+ icon_config: dict[str, Any] = Field(default_factory=dict)
2112
2150
  hide_copyright: bool | None = None
2113
2151
  config_keys: list[str] = Field(default_factory=list)
2114
2152
  dash_global_config_keys: list[str] = Field(default_factory=list)
@@ -2122,6 +2160,7 @@ class PortalGetResponse(StrictModel):
2122
2160
  dash_name: str | None = None
2123
2161
  package_tag_ids: list[int] = Field(default_factory=list)
2124
2162
  dash_icon: str | None = None
2163
+ icon_config: dict[str, Any] = Field(default_factory=dict)
2125
2164
  hide_copyright: bool | None = None
2126
2165
  visibility: dict[str, Any] = Field(default_factory=dict)
2127
2166
  auth: dict[str, Any] = Field(default_factory=dict)