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

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.61
6
+ npm install @josephyan/qingflow-cli@0.2.0-beta.63
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @josephyan/qingflow-cli@0.2.0-beta.61 qingflow
12
+ npx -y -p @josephyan/qingflow-cli@0.2.0-beta.63 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.61",
3
+ "version": "0.2.0-beta.63",
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.0b61"
7
+ version = "0.2.0b63"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -74,6 +74,23 @@ class PublicViewType(str, Enum):
74
74
  gantt = "gantt"
75
75
 
76
76
 
77
+ class PublicButtonTriggerAction(str, Enum):
78
+ add_data = "addData"
79
+ link = "link"
80
+ qrobot = "qRobot"
81
+ wings = "wings"
82
+
83
+
84
+ class PublicViewButtonType(str, Enum):
85
+ system = "SYSTEM"
86
+ custom = "CUSTOM"
87
+
88
+
89
+ class PublicViewButtonConfigType(str, Enum):
90
+ top = "TOP"
91
+ detail = "DETAIL"
92
+
93
+
77
94
  class PublicChartType(str, Enum):
78
95
  target = "target"
79
96
  pie = "pie"
@@ -473,6 +490,7 @@ class ViewUpsertPatch(StrictModel):
473
490
  start_field: str | None = Field(default=None, validation_alias=AliasChoices("start_field", "startField"))
474
491
  end_field: str | None = Field(default=None, validation_alias=AliasChoices("end_field", "endField"))
475
492
  title_field: str | None = Field(default=None, validation_alias=AliasChoices("title_field", "titleField"))
493
+ buttons: list["ViewButtonBindingPatch"] | None = None
476
494
 
477
495
  @model_validator(mode="before")
478
496
  @classmethod
@@ -514,6 +532,207 @@ class ViewUpsertPatch(StrictModel):
514
532
  return self
515
533
 
516
534
 
535
+ class CustomButtonJudgeValuePatch(StrictModel):
536
+ id: int | str | None = None
537
+ value: Any | None = None
538
+
539
+ @model_validator(mode="before")
540
+ @classmethod
541
+ def normalize_aliases(cls, value: Any) -> Any:
542
+ if not isinstance(value, dict):
543
+ return value
544
+ payload = dict(value)
545
+ if "opt_id" in payload and "id" not in payload:
546
+ payload["id"] = payload.pop("opt_id")
547
+ if "member_id" in payload and "id" not in payload:
548
+ payload["id"] = payload.pop("member_id")
549
+ return payload
550
+
551
+
552
+ class CustomButtonQuestionRefPatch(StrictModel):
553
+ que_id: int = Field(validation_alias=AliasChoices("que_id", "queId"))
554
+ que_title: str | None = Field(default=None, validation_alias=AliasChoices("que_title", "queTitle"))
555
+ que_type: int | None = Field(default=None, validation_alias=AliasChoices("que_type", "queType"))
556
+
557
+
558
+ class CustomButtonMatchRulePatch(StrictModel):
559
+ que_id: int = Field(validation_alias=AliasChoices("que_id", "queId"))
560
+ que_title: str | None = Field(default=None, validation_alias=AliasChoices("que_title", "queTitle"))
561
+ que_type: int | None = Field(default=None, validation_alias=AliasChoices("que_type", "queType"))
562
+ date_type: int | None = Field(default=None, validation_alias=AliasChoices("date_type", "dateType"))
563
+ judge_type: int | None = Field(default=None, validation_alias=AliasChoices("judge_type", "judgeType"))
564
+ match_type: int | None = Field(default=None, validation_alias=AliasChoices("match_type", "matchType"))
565
+ judge_values: list[str] = Field(default_factory=list, validation_alias=AliasChoices("judge_values", "judgeValues"))
566
+ judge_que_type: int | None = Field(default=None, validation_alias=AliasChoices("judge_que_type", "judgeQueType"))
567
+ judge_que_id: int | None = Field(default=None, validation_alias=AliasChoices("judge_que_id", "judgeQueId"))
568
+ judge_que_detail: CustomButtonQuestionRefPatch | None = Field(
569
+ default=None,
570
+ validation_alias=AliasChoices("judge_que_detail", "judgeQueDetail"),
571
+ )
572
+ judge_value_details: list[CustomButtonJudgeValuePatch] = Field(
573
+ default_factory=list,
574
+ validation_alias=AliasChoices("judge_value_details", "judgeValueDetails"),
575
+ )
576
+ path_value: str | None = Field(default=None, validation_alias=AliasChoices("path_value", "pathValue"))
577
+ table_update_type: int | None = Field(default=None, validation_alias=AliasChoices("table_update_type", "tableUpdateType"))
578
+ multi_value: bool | None = Field(default=None, validation_alias=AliasChoices("multi_value", "multiValue"))
579
+ add_rule: str | None = Field(default=None, validation_alias=AliasChoices("add_rule", "addRule"))
580
+ filter_condition: list[list["CustomButtonMatchRulePatch"]] = Field(
581
+ default_factory=list,
582
+ validation_alias=AliasChoices("filter_condition", "filterCondition"),
583
+ )
584
+ field_id_prefix: str | None = Field(default=None, validation_alias=AliasChoices("field_id_prefix", "fieldIdPrefix"))
585
+
586
+ @model_validator(mode="before")
587
+ @classmethod
588
+ def normalize_aliases(cls, value: Any) -> Any:
589
+ if not isinstance(value, dict):
590
+ return value
591
+ payload = dict(value)
592
+ if "judgeValue" in payload and "judge_values" not in payload and "judgeValues" not in payload:
593
+ payload["judge_values"] = [payload.pop("judgeValue")]
594
+ return payload
595
+
596
+
597
+ class CustomButtonAddDataConfigPatch(StrictModel):
598
+ related_app_key: str | None = Field(default=None, validation_alias=AliasChoices("related_app_key", "relatedAppKey"))
599
+ related_app_name: str | None = Field(default=None, validation_alias=AliasChoices("related_app_name", "relatedAppName"))
600
+ que_relation: list[CustomButtonMatchRulePatch] = Field(
601
+ default_factory=list,
602
+ validation_alias=AliasChoices("que_relation", "queRelation"),
603
+ )
604
+
605
+
606
+ class CustomButtonExternalQRobotConfigPatch(StrictModel):
607
+ external_qrobot_config_id: int | None = Field(
608
+ default=None,
609
+ validation_alias=AliasChoices("external_qrobot_config_id", "externalQRobotConfigId"),
610
+ )
611
+ triggered_text: str | None = Field(default=None, validation_alias=AliasChoices("triggered_text", "triggeredText"))
612
+
613
+
614
+ class CustomButtonWingsConfigPatch(StrictModel):
615
+ wings_agent_id: int | None = Field(default=None, validation_alias=AliasChoices("wings_agent_id", "wingsAgentId"))
616
+ wings_agent_name: str | None = Field(default=None, validation_alias=AliasChoices("wings_agent_name", "wingsAgentName"))
617
+ bind_que_id_list: list[int] = Field(default_factory=list, validation_alias=AliasChoices("bind_que_id_list", "bindQueIdList"))
618
+ bind_file_que_id_list: list[int] = Field(
619
+ default_factory=list,
620
+ validation_alias=AliasChoices("bind_file_que_id_list", "bindFileQueIdList"),
621
+ )
622
+ default_prompt: str | None = Field(default=None, validation_alias=AliasChoices("default_prompt", "defaultPrompt"))
623
+ being_auto_send: bool | None = Field(default=None, validation_alias=AliasChoices("being_auto_send", "beingAutoSend"))
624
+
625
+ @model_validator(mode="before")
626
+ @classmethod
627
+ def normalize_aliases(cls, value: Any) -> Any:
628
+ if not isinstance(value, dict):
629
+ return value
630
+ payload = dict(value)
631
+ raw_agent_id = payload.get("wings_agent_id", payload.get("wingsAgentId"))
632
+ if isinstance(raw_agent_id, str) and raw_agent_id.strip().isdigit():
633
+ payload["wings_agent_id"] = int(raw_agent_id.strip())
634
+ return payload
635
+
636
+
637
+ class CustomButtonPatch(StrictModel):
638
+ button_text: str = Field(validation_alias=AliasChoices("button_text", "buttonText"))
639
+ background_color: str = Field(validation_alias=AliasChoices("background_color", "backgroundColor"))
640
+ text_color: str = Field(validation_alias=AliasChoices("text_color", "textColor"))
641
+ button_icon: str = Field(validation_alias=AliasChoices("button_icon", "buttonIcon"))
642
+ trigger_action: PublicButtonTriggerAction = Field(validation_alias=AliasChoices("trigger_action", "triggerAction"))
643
+ trigger_link_url: str | None = Field(default=None, validation_alias=AliasChoices("trigger_link_url", "triggerLinkUrl"))
644
+ trigger_add_data_config: CustomButtonAddDataConfigPatch | None = Field(
645
+ default=None,
646
+ validation_alias=AliasChoices("trigger_add_data_config", "triggerAddDataConfig"),
647
+ )
648
+ external_qrobot_config: CustomButtonExternalQRobotConfigPatch | None = Field(
649
+ default=None,
650
+ validation_alias=AliasChoices(
651
+ "external_qrobot_config",
652
+ "externalQrobotConfig",
653
+ "custom_button_external_qrobot_relation_vo",
654
+ "customButtonExternalQRobotRelationVO",
655
+ ),
656
+ )
657
+ trigger_wings_config: CustomButtonWingsConfigPatch | None = Field(
658
+ default=None,
659
+ validation_alias=AliasChoices("trigger_wings_config", "triggerWingsConfig"),
660
+ )
661
+
662
+ @model_validator(mode="after")
663
+ def validate_shape(self) -> "CustomButtonPatch":
664
+ if self.trigger_action == PublicButtonTriggerAction.link and not str(self.trigger_link_url or "").strip():
665
+ raise ValueError("link buttons require trigger_link_url")
666
+ if self.trigger_action == PublicButtonTriggerAction.add_data and self.trigger_add_data_config is None:
667
+ raise ValueError("addData buttons require trigger_add_data_config")
668
+ if self.trigger_action == PublicButtonTriggerAction.qrobot and self.external_qrobot_config is None:
669
+ raise ValueError("qRobot buttons require external_qrobot_config")
670
+ if self.trigger_action == PublicButtonTriggerAction.wings and self.trigger_wings_config is None:
671
+ raise ValueError("wings buttons require trigger_wings_config")
672
+ return self
673
+
674
+
675
+ class ViewButtonBindingPatch(StrictModel):
676
+ button_type: PublicViewButtonType = Field(validation_alias=AliasChoices("button_type", "buttonType"))
677
+ config_type: PublicViewButtonConfigType = Field(validation_alias=AliasChoices("config_type", "configType"))
678
+ button_id: int = Field(validation_alias=AliasChoices("button_id", "buttonId", "id"))
679
+ button_text: str | None = Field(default=None, validation_alias=AliasChoices("button_text", "buttonText"))
680
+ button_icon: str | None = Field(default=None, validation_alias=AliasChoices("button_icon", "buttonIcon"))
681
+ background_color: str | None = Field(default=None, validation_alias=AliasChoices("background_color", "backgroundColor"))
682
+ text_color: str | None = Field(default=None, validation_alias=AliasChoices("text_color", "textColor"))
683
+ trigger_action: str | None = Field(default=None, validation_alias=AliasChoices("trigger_action", "triggerAction"))
684
+ print_tpls: list[Any] = Field(default_factory=list, validation_alias=AliasChoices("print_tpls", "printTpls"))
685
+ being_main: bool = Field(default=False, validation_alias=AliasChoices("being_main", "beingMain"))
686
+ button_limit: list[list[ViewFilterRulePatch]] = Field(
687
+ default_factory=list,
688
+ validation_alias=AliasChoices("button_limit", "buttonLimit"),
689
+ )
690
+ button_formula: str | None = Field(default=None, validation_alias=AliasChoices("button_formula", "buttonFormula"))
691
+ button_formula_type: int = Field(default=1, validation_alias=AliasChoices("button_formula_type", "buttonFormulaType"))
692
+
693
+ @model_validator(mode="before")
694
+ @classmethod
695
+ def normalize_aliases(cls, value: Any) -> Any:
696
+ if not isinstance(value, dict):
697
+ return value
698
+ payload = dict(value)
699
+ raw_button_type = payload.get("button_type", payload.get("buttonType"))
700
+ if isinstance(raw_button_type, str):
701
+ normalized_type = raw_button_type.strip().lower()
702
+ if normalized_type == "system":
703
+ payload["button_type"] = "SYSTEM"
704
+ elif normalized_type == "custom":
705
+ payload["button_type"] = "CUSTOM"
706
+ raw_config_type = payload.get("config_type", payload.get("configType"))
707
+ if isinstance(raw_config_type, str):
708
+ normalized_config = raw_config_type.strip().lower()
709
+ if normalized_config == "top":
710
+ payload["config_type"] = "TOP"
711
+ elif normalized_config == "detail":
712
+ payload["config_type"] = "DETAIL"
713
+ raw_limits = payload.get("button_limit", payload.get("buttonLimit"))
714
+ if isinstance(raw_limits, list) and raw_limits and all(isinstance(item, dict) for item in raw_limits):
715
+ payload["button_limit"] = [raw_limits]
716
+ return payload
717
+
718
+ @model_validator(mode="after")
719
+ def validate_shape(self) -> "ViewButtonBindingPatch":
720
+ if self.button_type == PublicViewButtonType.system:
721
+ missing = [
722
+ field_name
723
+ for field_name, value in (
724
+ ("button_icon", self.button_icon),
725
+ ("background_color", self.background_color),
726
+ ("text_color", self.text_color),
727
+ ("trigger_action", self.trigger_action),
728
+ )
729
+ if not str(value or "").strip()
730
+ ]
731
+ if missing:
732
+ raise ValueError(f"system button bindings require {', '.join(missing)}")
733
+ return self
734
+
735
+
517
736
  class ChartFilterRulePatch(StrictModel):
518
737
  field_name: str = Field(validation_alias=AliasChoices("field_name", "fieldName", "field", "name"))
519
738
  operator: ViewFilterOperator = Field(validation_alias=AliasChoices("operator", "op"))
@@ -983,3 +1202,9 @@ def _normalize_public_relation_mode(value: Any) -> str | None:
983
1202
  }
984
1203
  return aliases.get(normalized, normalized or None)
985
1204
  return None
1205
+
1206
+
1207
+ CustomButtonMatchRulePatch.model_rebuild()
1208
+ CustomButtonAddDataConfigPatch.model_rebuild()
1209
+ ViewButtonBindingPatch.model_rebuild()
1210
+ ViewUpsertPatch.model_rebuild()