@josephyan/qingflow-cli 0.2.0-beta.72 → 0.2.0-beta.74

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.
@@ -90,6 +90,20 @@ class AiBuilderTools(ToolBase):
90
90
  ) -> JSONObject:
91
91
  return self.package_create(profile=profile, package_name=package_name, icon=icon, color=color)
92
92
 
93
+ @mcp.tool()
94
+ def solution_install(
95
+ profile: str = DEFAULT_PROFILE,
96
+ solution_key: str = "",
97
+ being_copy_data: bool = True,
98
+ solution_source: str = "solutionDetail",
99
+ ) -> JSONObject:
100
+ return self.solution_install(
101
+ profile=profile,
102
+ solution_key=solution_key,
103
+ being_copy_data=being_copy_data,
104
+ solution_source=solution_source,
105
+ )
106
+
93
107
  @mcp.tool()
94
108
  def member_search(
95
109
  profile: str = DEFAULT_PROFILE,
@@ -216,6 +230,15 @@ class AiBuilderTools(ToolBase):
216
230
  def app_get_fields(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
217
231
  return self.app_get_fields(profile=profile, app_key=app_key)
218
232
 
233
+ @mcp.tool()
234
+ def app_repair_code_blocks(
235
+ profile: str = DEFAULT_PROFILE,
236
+ app_key: str = "",
237
+ field: str | None = None,
238
+ apply: bool = False,
239
+ ) -> JSONObject:
240
+ return self.app_repair_code_blocks(profile=profile, app_key=app_key, field=field, apply=apply)
241
+
219
242
  @mcp.tool()
220
243
  def app_get_layout(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
221
244
  return self.app_get_layout(profile=profile, app_key=app_key)
@@ -519,6 +542,31 @@ class AiBuilderTools(ToolBase):
519
542
  },
520
543
  )
521
544
 
545
+ def solution_install(
546
+ self,
547
+ *,
548
+ profile: str,
549
+ solution_key: str,
550
+ being_copy_data: bool = True,
551
+ solution_source: str = "solutionDetail",
552
+ ) -> JSONObject:
553
+ normalized_args = {
554
+ "solution_key": solution_key,
555
+ "being_copy_data": being_copy_data,
556
+ "solution_source": solution_source,
557
+ }
558
+ return _safe_tool_call(
559
+ lambda: self._facade.solution_install(
560
+ profile=profile,
561
+ solution_key=solution_key,
562
+ being_copy_data=being_copy_data,
563
+ solution_source=solution_source,
564
+ ),
565
+ error_code="SOLUTION_INSTALL_FAILED",
566
+ normalized_args=normalized_args,
567
+ suggested_next_call={"tool_name": "solution_install", "arguments": {"profile": profile, **normalized_args}},
568
+ )
569
+
522
570
  def member_search(
523
571
  self,
524
572
  *,
@@ -768,6 +816,22 @@ class AiBuilderTools(ToolBase):
768
816
  suggested_next_call={"tool_name": "app_get_fields", "arguments": {"profile": profile, "app_key": app_key}},
769
817
  )
770
818
 
819
+ def app_repair_code_blocks(
820
+ self,
821
+ *,
822
+ profile: str,
823
+ app_key: str,
824
+ field: str | None = None,
825
+ apply: bool = False,
826
+ ) -> JSONObject:
827
+ normalized_args = {"app_key": app_key, "field": field, "apply": apply}
828
+ return _safe_tool_call(
829
+ lambda: self._facade.app_repair_code_blocks(profile=profile, app_key=app_key, field=field, apply=apply),
830
+ error_code="APP_REPAIR_CODE_BLOCKS_FAILED",
831
+ normalized_args=normalized_args,
832
+ suggested_next_call={"tool_name": "app_repair_code_blocks", "arguments": {"profile": profile, **normalized_args}},
833
+ )
834
+
771
835
  def app_read_layout_summary(self, *, profile: str, app_key: str) -> JSONObject:
772
836
  normalized_args = {"app_key": app_key}
773
837
  return _safe_tool_call(
@@ -1889,6 +1953,7 @@ def _public_error_message(error_code: str, error: QingflowApiError) -> str:
1889
1953
  mapping = {
1890
1954
  "PACKAGE_LIST_FAILED": "package list is unavailable in the current route",
1891
1955
  "PACKAGE_RESOLVE_FAILED": "package resolution is unavailable in the current route",
1956
+ "SOLUTION_INSTALL_FAILED": "solution install could not complete because the app creation route or solution source is unavailable",
1892
1957
  "PACKAGE_ATTACH_FAILED": "package attachment could not be verified in the current route",
1893
1958
  "APP_RESOLVE_FAILED": "app resolution is unavailable in the current route",
1894
1959
  "CUSTOM_BUTTON_LIST_FAILED": "custom button list is unavailable in the current route",
@@ -1917,6 +1982,50 @@ def _public_error_message(error_code: str, error: QingflowApiError) -> str:
1917
1982
 
1918
1983
 
1919
1984
  _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
1985
+ "file_upload_local": {
1986
+ "allowed_keys": ["upload_kind", "file_path", "upload_mark", "content_type", "bucket_type", "path_id", "file_related_url"],
1987
+ "aliases": {},
1988
+ "allowed_values": {"upload_kind": ["attachment", "login"]},
1989
+ "execution_notes": [
1990
+ "returns upload metadata plus attachment-ready values for later builder or user writes",
1991
+ "upload_kind=attachment may fall back to login upload info when the backend rejects attachment upload info",
1992
+ "upload_mark is recommended for attachment uploads because it affects the remote storage path",
1993
+ ],
1994
+ "minimal_example": {
1995
+ "profile": "default",
1996
+ "upload_kind": "attachment",
1997
+ "file_path": "/absolute/path/to/local-file.txt",
1998
+ "upload_mark": "APP_KEY",
1999
+ },
2000
+ },
2001
+ "feedback_submit": {
2002
+ "allowed_keys": [
2003
+ "category",
2004
+ "title",
2005
+ "description",
2006
+ "expected_behavior",
2007
+ "actual_behavior",
2008
+ "impact_scope",
2009
+ "tool_name",
2010
+ "app_key",
2011
+ "record_id",
2012
+ "workflow_node_id",
2013
+ "note",
2014
+ ],
2015
+ "aliases": {},
2016
+ "allowed_values": {"category": ["bug", "missing_capability", "awkward_workflow", "ux", "docs"]},
2017
+ "execution_notes": [
2018
+ "submit feedback only after explicit user confirmation",
2019
+ "use this when the current builder capability is unsupported or awkward after reasonable attempts",
2020
+ "requires feedback qsource configuration but does not require Qingflow login or workspace selection",
2021
+ ],
2022
+ "minimal_example": {
2023
+ "category": "missing_capability",
2024
+ "title": "builder chart data read gap",
2025
+ "description": "The current builder capability cannot satisfy the requested workflow.",
2026
+ "tool_name": "chart_get",
2027
+ },
2028
+ },
1920
2029
  "package_list": {
1921
2030
  "allowed_keys": ["trial_status"],
1922
2031
  "aliases": {"trialStatus": "trial_status"},
@@ -1950,6 +2059,32 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
1950
2059
  "color": "azure",
1951
2060
  },
1952
2061
  },
2062
+ "solution_install": {
2063
+ "allowed_keys": ["solution_key", "being_copy_data", "solution_source"],
2064
+ "aliases": {
2065
+ "solutionKey": "solution_key",
2066
+ "beingCopyData": "being_copy_data",
2067
+ "copy_data": "being_copy_data",
2068
+ "copyData": "being_copy_data",
2069
+ "solutionSource": "solution_source",
2070
+ "source": "solution_source",
2071
+ },
2072
+ "allowed_values": {
2073
+ "being_copy_data": [True, False],
2074
+ "solution_source": ["solutionDetail"],
2075
+ },
2076
+ "execution_notes": [
2077
+ "solution_install calls the backend app creation route with a solutionKey payload",
2078
+ "this is a write operation that may create multiple apps at once",
2079
+ "app_keys are verified from the backend response when available",
2080
+ ],
2081
+ "minimal_example": {
2082
+ "profile": "default",
2083
+ "solution_key": "cfqrhth99401",
2084
+ "being_copy_data": True,
2085
+ "solution_source": "solutionDetail",
2086
+ },
2087
+ },
1953
2088
  "member_search": {
1954
2089
  "allowed_keys": ["query", "page_num", "page_size", "contain_disable"],
1955
2090
  "aliases": {},
@@ -2019,6 +2154,22 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
2019
2154
  "package_tag_id": 1001,
2020
2155
  },
2021
2156
  },
2157
+ "app_release_edit_lock_if_mine": {
2158
+ "allowed_keys": ["app_key", "lock_owner_email", "lock_owner_name"],
2159
+ "aliases": {},
2160
+ "allowed_values": {},
2161
+ "execution_notes": [
2162
+ "use this only after a builder write fails with APP_EDIT_LOCKED and the lock belongs to the current user",
2163
+ "supply the lock owner details from the failed write result for a safe release attempt",
2164
+ "after a successful release, retry the blocked builder write or publish verification call",
2165
+ ],
2166
+ "minimal_example": {
2167
+ "profile": "default",
2168
+ "app_key": "APP_KEY",
2169
+ "lock_owner_email": "user@example.com",
2170
+ "lock_owner_name": "当前用户",
2171
+ },
2172
+ },
2022
2173
  "app_custom_button_list": {
2023
2174
  "allowed_keys": ["app_key"],
2024
2175
  "aliases": {},
@@ -2213,6 +2364,8 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
2213
2364
  "q_linker_binding lets you declare request config, dynamic inputs, alias parsing, and target-field bindings in one step; builder writes remoteLookupConfig plus the existing backend relation-default and questionRelations structures",
2214
2365
  "code_block_binding lets you declare inputs, code, alias parsing, and target-field bindings in one step; builder writes codeBlockConfig plus the existing backend relation-default and questionRelations structures",
2215
2366
  "builder configures code blocks only; it does not execute or trigger code blocks",
2367
+ "code block outputs must be emitted through qf_output assignment; use qf_output = {...} or assign qf_output after building the result object, never const/let qf_output =",
2368
+ "builder automatically normalizes const/let qf_output assignments on write and rejects output-bound code blocks that still do not contain a valid qf_output assignment",
2216
2369
  "code_block_binding and q_linker_binding target fields are limited to text, long_text, number, amount, date, datetime, single_select, multi_select, and boolean",
2217
2370
  ],
2218
2371
  "minimal_example": {
@@ -2475,6 +2628,9 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
2475
2628
  "view.buttons.button_type": ["SYSTEM", "CUSTOM"],
2476
2629
  "view.buttons.config_type": ["TOP", "DETAIL"],
2477
2630
  },
2631
+ "execution_notes": [
2632
+ "for multi-value operators such as in, pass values as a list; value may also be used as an alias when it already contains a list",
2633
+ ],
2478
2634
  "minimal_example": {
2479
2635
  "profile": "default",
2480
2636
  "app_key": "APP_KEY",
@@ -2534,6 +2690,7 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
2534
2690
  "read back app_get_views after any failed or partial view apply",
2535
2691
  "view existence verification and saved-filter verification are separate; treat filters as unverified until verification.view_filters_verified is true",
2536
2692
  "buttons omitted preserves existing button config; buttons=[] clears all buttons; buttons=[...] replaces the full button config",
2693
+ "for multi-value operators such as in, pass values as a list; value may also be used as an alias when it already contains a list",
2537
2694
  ],
2538
2695
  "minimal_example": {
2539
2696
  "profile": "default",
@@ -2779,6 +2936,38 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
2779
2936
  },
2780
2937
  },
2781
2938
  },
2939
+ "app_publish_verify": {
2940
+ "allowed_keys": ["app_key", "expected_package_tag_id"],
2941
+ "aliases": {},
2942
+ "allowed_values": {},
2943
+ "execution_notes": [
2944
+ "verifies that the current app draft has been published and is readable through the builder surface",
2945
+ "expected_package_tag_id is optional and adds an extra package consistency check",
2946
+ "when verification fails because of an edit lock owned by the current user, retry after app_release_edit_lock_if_mine",
2947
+ ],
2948
+ "minimal_example": {
2949
+ "profile": "default",
2950
+ "app_key": "APP_KEY",
2951
+ "expected_package_tag_id": 1001,
2952
+ },
2953
+ },
2954
+ "app_repair_code_blocks": {
2955
+ "allowed_keys": ["app_key", "field", "apply"],
2956
+ "aliases": {},
2957
+ "allowed_values": {},
2958
+ "execution_notes": [
2959
+ "scan existing code_block fields for qf_output shadowing, missing output assignment, and broken writeback defaults",
2960
+ "apply=false is a dry-run and returns a repair plan without writing builder config",
2961
+ "apply=true rewrites only safe cases: const/let qf_output shadowing and stale relation-default output bindings reconstructed from readable code_block_binding config",
2962
+ "this tool does not invent missing output aliases or guess missing target bindings when only low-level codeBlockConfig is present",
2963
+ ],
2964
+ "minimal_example": {
2965
+ "profile": "default",
2966
+ "app_key": "APP_KEY",
2967
+ "field": "线索价值评估",
2968
+ "apply": False,
2969
+ },
2970
+ },
2782
2971
  }
2783
2972
 
2784
2973
  _PRIVATE_BUILDER_TOOL_CONTRACTS = {