@thinkingai/ae-cli 6.0.22 → 6.0.27

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 (172) hide show
  1. package/dist/{auth-RDN6D5HU.js → auth-7TQRGLBC.js} +13 -15
  2. package/dist/auth-MEJ642P4.js +13 -0
  3. package/dist/chunk-2NDGFQHW.js +190 -0
  4. package/dist/{chunk-5FBLRSMU.js → chunk-7QQ4233A.js} +3 -3
  5. package/dist/{chunk-U6QPKCN3.js → chunk-AJTH7LT3.js} +10 -116
  6. package/dist/chunk-BXMXMUD7.js +254 -0
  7. package/dist/chunk-C4DH76LX.js +59 -0
  8. package/dist/chunk-GWZ5MYWE.js +209 -0
  9. package/dist/{chunk-E34XH4GW.js → chunk-KCA6BA5D.js} +8 -8
  10. package/dist/{chunk-XE2PI5DS.js → chunk-KGJQCYVC.js} +1 -1
  11. package/dist/chunk-LG5YT7P7.js +59 -0
  12. package/dist/{chunk-2W7HULUD.js → chunk-MDJGDI6K.js} +2 -2
  13. package/dist/{chunk-H52CSLJW.js → chunk-R77JT7XD.js} +53 -6
  14. package/dist/{chunk-WPXHCP4A.js → chunk-YCLVYFK7.js} +52 -9
  15. package/dist/{chunk-4EUZRJPO.js → chunk-YNQFYBDB.js} +102 -14
  16. package/dist/{chunk-YACCPUNQ.js → chunk-ZAOL36CG.js} +1 -1
  17. package/dist/cli-token-TVQRSE46.js +18 -0
  18. package/dist/{client-VTJMUZ4O.js → client-2643Z5AG.js} +3 -3
  19. package/dist/{config-2SDTLGOC.js → config-ZVPARN4R.js} +4 -9
  20. package/dist/index.js +27 -24
  21. package/dist/{metadata-JZ2OTWBK.js → metadata-IPSPQBX3.js} +56 -65
  22. package/dist/metadata-N5REJ7R7.js +411 -0
  23. package/dist/{model-ZYMRN4VS.js → model-T3KZJWLW.js} +2 -2
  24. package/dist/{raw-NGYHAL3F.js → raw-OHSUK42D.js} +4 -4
  25. package/dist/{sync-JVLX6TGW.js → sync-ULT5SECP.js} +3 -3
  26. package/dist/{te-agent-QPZTLHPH.js → te-agent-QLIVKRUN.js} +1146 -61
  27. package/dist/{te-analysis-WWX3Z6RP.js → te-analysis-2U5EPXQC.js} +1213 -341
  28. package/dist/te-analysis-QMZ2UH7F.js +2419 -0
  29. package/dist/{te-audience-UXGHUVBB.js → te-audience-PVMKQAFH.js} +5 -5
  30. package/dist/te-audience-XMRMVD2V.js +599 -0
  31. package/dist/{te-common-7XXH73MF.js → te-common-CFGQXTFV.js} +5 -5
  32. package/dist/te-common-SDB3O2QG.js +130 -0
  33. package/dist/{te-community-QKE67HR2.js → te-community-6A7LKYUH.js} +5 -5
  34. package/dist/te-community-GMWFGILT.js +687 -0
  35. package/dist/te-dataops-6LIPYNGH.js +1864 -0
  36. package/dist/{te-dataops-6W7NNYST.js → te-dataops-Z53CTG2U.js} +90 -68
  37. package/dist/{te-engage-NCFAQFX3.js → te-engage-AGREUOW7.js} +30 -15
  38. package/dist/te-engage-MIIUKY6M.js +1525 -0
  39. package/dist/{te-kb-K5BQYUCM.js → te-kb-KQJ53M3A.js} +4 -4
  40. package/dist/{te-meta-LJZBOSMO.js → te-meta-QLANJ4B4.js} +5 -5
  41. package/dist/te-meta-TOA6FWDE.js +595 -0
  42. package/dist/{te-team-DHK5R7MV.js → te-team-TQGMNHQQ.js} +5 -5
  43. package/package.json +3 -1
  44. package/skills/ae-agent/SKILL.md +158 -189
  45. package/skills/ae-agent/references/accept-skill-share.md +39 -0
  46. package/skills/ae-agent/references/add-attachment.md +57 -0
  47. package/skills/ae-agent/references/add-mcp.md +75 -0
  48. package/skills/ae-agent/references/add-model.md +70 -0
  49. package/skills/ae-agent/references/add-skill.md +71 -0
  50. package/skills/ae-agent/references/approve-skill.md +41 -0
  51. package/skills/ae-agent/references/attachment-stats.md +50 -0
  52. package/skills/ae-agent/references/auto-provision-mcp-credentials.md +57 -0
  53. package/skills/ae-agent/references/cancel-skill-submission.md +39 -0
  54. package/skills/ae-agent/references/copy-skill.md +53 -0
  55. package/skills/ae-agent/references/create-agent.md +71 -0
  56. package/skills/ae-agent/references/create-automation.md +99 -0
  57. package/skills/ae-agent/references/del-agent.md +38 -0
  58. package/skills/ae-agent/references/del-attachment.md +35 -0
  59. package/skills/ae-agent/references/del-mcp.md +35 -0
  60. package/skills/ae-agent/references/del-model.md +37 -0
  61. package/skills/ae-agent/references/del-skill-asset.md +41 -0
  62. package/skills/ae-agent/references/del-skill-reference.md +41 -0
  63. package/skills/ae-agent/references/del-skill-script.md +41 -0
  64. package/skills/ae-agent/references/del-skill.md +36 -0
  65. package/skills/ae-agent/references/edit-skill.md +64 -0
  66. package/skills/ae-agent/references/get-agent.md +37 -0
  67. package/skills/ae-agent/references/get-skill-content.md +36 -0
  68. package/skills/ae-agent/references/list-agents.md +40 -0
  69. package/skills/ae-agent/references/list-attachments.md +42 -0
  70. package/skills/ae-agent/references/list-automations.md +41 -0
  71. package/skills/ae-agent/references/list-mcp-credentials.md +65 -0
  72. package/skills/ae-agent/references/list-mcp-market.md +58 -0
  73. package/skills/ae-agent/references/list-mcps.md +37 -0
  74. package/skills/ae-agent/references/list-models.md +38 -0
  75. package/skills/ae-agent/references/list-skill-assets.md +35 -0
  76. package/skills/ae-agent/references/list-skill-market.md +59 -0
  77. package/skills/ae-agent/references/list-skill-references.md +36 -0
  78. package/skills/ae-agent/references/list-skill-scripts.md +35 -0
  79. package/skills/ae-agent/references/list-skill-shares.md +49 -0
  80. package/skills/ae-agent/references/list-skill-submissions.md +45 -0
  81. package/skills/ae-agent/references/list-skills.md +37 -0
  82. package/skills/ae-agent/references/mcp-auth-disconnect.md +50 -0
  83. package/skills/ae-agent/references/mcp-auth-start.md +61 -0
  84. package/skills/ae-agent/references/mcp-auth-status.md +56 -0
  85. package/skills/ae-agent/references/mcp-stats.md +68 -0
  86. package/skills/ae-agent/references/mcp-token.md +63 -0
  87. package/skills/ae-agent/references/mcp-tools.md +55 -0
  88. package/skills/ae-agent/references/read-skill-asset.md +51 -0
  89. package/skills/ae-agent/references/read-skill-reference.md +50 -0
  90. package/skills/ae-agent/references/read-skill-script.md +51 -0
  91. package/skills/ae-agent/references/reject-skill-share.md +37 -0
  92. package/skills/ae-agent/references/reject-skill.md +42 -0
  93. package/skills/ae-agent/references/rescan-skills.md +44 -0
  94. package/skills/ae-agent/references/set-mcp-credential.md +67 -0
  95. package/skills/ae-agent/references/set-mcp-meta.md +52 -0
  96. package/skills/ae-agent/references/set-skill-meta.md +51 -0
  97. package/skills/ae-agent/references/share-skill.md +50 -0
  98. package/skills/ae-agent/references/submit-skill.md +51 -0
  99. package/skills/ae-agent/references/test-model.md +61 -0
  100. package/skills/ae-agent/references/toggle-mcp.md +39 -0
  101. package/skills/ae-agent/references/toggle-model.md +37 -0
  102. package/skills/ae-agent/references/toggle-skill.md +37 -0
  103. package/skills/ae-agent/references/update-agent.md +71 -0
  104. package/skills/ae-agent/references/update-automation.md +83 -0
  105. package/skills/ae-agent/references/update-mcp.md +79 -0
  106. package/skills/ae-agent/references/update-model.md +77 -0
  107. package/skills/ae-agent/references/upload-skill-asset.md +49 -0
  108. package/skills/ae-agent/references/upload-skill-reference.md +51 -0
  109. package/skills/ae-agent/references/upload-skill-script.md +49 -0
  110. package/skills/ae-agent/references/upload-skill.md +89 -0
  111. package/skills/ae-analysis/SKILL.md +53 -25
  112. package/skills/ae-analysis/references/analysis_gateway_assets.md +129 -0
  113. package/skills/ae-analysis/references/artifact_download.md +17 -0
  114. package/skills/ae-analysis/references/bi_panel_copy.md +15 -0
  115. package/skills/ae-analysis/references/bi_panel_create.md +15 -0
  116. package/skills/ae-analysis/references/bi_panel_delete.md +15 -0
  117. package/skills/ae-analysis/references/bi_panel_get.md +18 -0
  118. package/skills/ae-analysis/references/bi_panel_list.md +15 -0
  119. package/skills/ae-analysis/references/bi_panel_page_data_export.md +25 -0
  120. package/skills/ae-analysis/references/bi_panel_page_data_run.md +15 -0
  121. package/skills/ae-analysis/references/bi_panel_share.md +15 -0
  122. package/skills/ae-analysis/references/bi_panel_update.md +15 -0
  123. package/skills/ae-analysis/references/dashboard_abnormal_get.md +15 -0
  124. package/skills/ae-analysis/references/dashboard_copy.md +17 -0
  125. package/skills/ae-analysis/references/dashboard_create.md +15 -0
  126. package/skills/ae-analysis/references/dashboard_daily_report_send.md +17 -0
  127. package/skills/ae-analysis/references/dashboard_daily_report_update.md +17 -0
  128. package/skills/ae-analysis/references/dashboard_definition_export.md +33 -0
  129. package/skills/ae-analysis/references/dashboard_definition_import.md +15 -0
  130. package/skills/ae-analysis/references/dashboard_delete.md +15 -0
  131. package/skills/ae-analysis/references/dashboard_freeze.md +15 -0
  132. package/skills/ae-analysis/references/dashboard_get.md +15 -0
  133. package/skills/ae-analysis/references/dashboard_handover.md +15 -0
  134. package/skills/ae-analysis/references/dashboard_list.md +15 -0
  135. package/skills/ae-analysis/references/dashboard_report_data_export.md +25 -0
  136. package/skills/ae-analysis/references/dashboard_report_data_run.md +15 -0
  137. package/skills/ae-analysis/references/dashboard_share.md +15 -0
  138. package/skills/ae-analysis/references/dashboard_share_info.md +15 -0
  139. package/skills/ae-analysis/references/dashboard_task_status.md +15 -0
  140. package/skills/ae-analysis/references/dashboard_update.md +16 -0
  141. package/skills/ae-analysis/references/favorite_add.md +15 -0
  142. package/skills/ae-analysis/references/favorite_remove.md +15 -0
  143. package/skills/ae-analysis/references/folder_create.md +15 -0
  144. package/skills/ae-analysis/references/folder_delete.md +15 -0
  145. package/skills/ae-analysis/references/folder_members.md +15 -0
  146. package/skills/ae-analysis/references/folder_share.md +15 -0
  147. package/skills/ae-analysis/references/project_space_create.md +15 -0
  148. package/skills/ae-analysis/references/project_space_delete.md +15 -0
  149. package/skills/ae-analysis/references/project_space_get.md +18 -0
  150. package/skills/ae-analysis/references/project_space_list.md +15 -0
  151. package/skills/ae-analysis/references/project_space_members.md +15 -0
  152. package/skills/ae-analysis/references/project_space_share.md +15 -0
  153. package/skills/ae-analysis/references/public_link_create.md +15 -0
  154. package/skills/ae-analysis/references/public_link_delete.md +15 -0
  155. package/skills/ae-analysis/references/public_link_list.md +15 -0
  156. package/skills/ae-analysis/references/public_link_offline.md +15 -0
  157. package/skills/ae-analysis/references/public_link_update.md +15 -0
  158. package/skills/ae-analysis/references/query_cancel.md +15 -0
  159. package/skills/ae-analysis/references/run_inspect.md +22 -0
  160. package/skills/ae-dataops/references/dataops-flow-create.md +2 -2
  161. package/skills/ae-dataops/references/dataops-flow-monitor.md +3 -3
  162. package/skills/ae-dataops/references/dataops-integration.md +1 -0
  163. package/skills/ae-engage/references/flow-node-config-schema.md +32 -8
  164. package/skills/ae-engage/references/save-flow.md +65 -29
  165. package/skills/ae-engage/references/validate-flow-node-config.md +28 -10
  166. package/skills/ae-generate-tracking-plan/SKILL.md +9 -7
  167. package/skills/ae-metadata/references/metadata_data_table_csv_write.md +5 -3
  168. package/skills/ae-metadata/references/metadata_data_table_sql_write.md +5 -4
  169. package/skills/ae-metadata/references/metadata_property_dimension_table_create_and_bind_csv.md +5 -3
  170. package/dist/auth-I2G7OAU2.js +0 -19
  171. package/dist/chunk-FPE5LGVU.js +0 -105
  172. package/dist/cli-token-6AGEDJF4.js +0 -14
@@ -4,9 +4,9 @@ Create, edit, preview, or commit a flow canvas draft.
4
4
 
5
5
  Mapped command: `ae-cli engage +save_flow --project_id <projectId> --req '<req-json>'`
6
6
 
7
- > **Protocol v2 (current).** `save_flow` is now **operation-based**. The `--req` object must carry an `operation` of `build`, `preview`, or `commit`. Do **not** use the old `nodeList` / `edgeList` field names send `nodes` / `edges` instead. Posting a legacy `nodeList`/`edgeList` payload (or omitting `operation`) makes the backend reject the call with `Unsupported save_flow operation: null`.
7
+ > **Protocol v2 (current).** `save_flow` is now **operation-based**. The `--req` object must carry an `operation` of `build`, `preview`, or `commit`. Do **not** use the old `nodeList` / `edgeList` field names -- send `nodes` / `edges` instead. Posting a legacy `nodeList`/`edgeList` payload (or omitting `operation`) makes the backend reject the call with `Unsupported save_flow operation: null`.
8
8
 
9
- The CLI passes your `--req` straight through to the backend (it only injects `projectId`). So everything in this document is about building the correct `req` object.
9
+ The CLI injects `projectId` and rejects missing/unsupported `operation` values, legacy `nodeList`/`edgeList` fields, and the removed `sourceFlowUuid` clone mode; otherwise it passes your `--req` through to the backend. So everything in this document is about building the correct `req` object.
10
10
 
11
11
  ---
12
12
 
@@ -22,10 +22,11 @@ build ──► status = ready_to_preview ──► preview ──► commit
22
22
 
23
23
  You still organize user requirements into an intermediate intent first, then map the intent to `nodes` / `edges`, then run the lifecycle.
24
24
 
25
- - `build`: assemble/edit a draft from `nodes` + `edges` (or `dsl`, or clone). Returns `ready_to_preview` (with `draftId`, `draftVersion`, `confirmToken`, `preview.mainPath`) or `need_input` (one more slot required).
25
+ - `build`: assemble/edit a draft from `nodes` + `edges` (or topology-only `dsl`). Returns `ready_to_preview` (with `draftId`, `draftVersion`, `confirmToken`, `preview.mainPath`) or `need_input` (one more slot required).
26
26
  - `preview`: validate the draft; **re-issues** a fresh `draftVersion` + `confirmToken`.
27
27
  - `commit`: finalize the draft into a flow version using the **preview** `draftVersion` + `confirmToken`; returns the final `flowUuid`.
28
28
  - Always verify with `ae-cli engage +flow_detail --project_id <projectId> --flow_uuid <flowUuid>`.
29
+ - To copy an existing flow, first call `+flow_detail`, convert the returned `nodeList` / `edgeList` into compact `nodes` / `edges`, then call `operation=build` as normal creation input. Do not pass `sourceFlowUuid`.
29
30
 
30
31
  ---
31
32
 
@@ -34,8 +35,9 @@ You still organize user requirements into an intermediate intent first, then map
34
35
  1. Identify the flow intent from the user input and produce a unified intent JSON.
35
36
  2. Run `ae-cli analysis_audience +get_cluster_definition_schema --cluster_type condition` to obtain the condition cluster definition schema for assembling condition-related fields later.
36
37
  3. Run `ae-cli engage +channel_list --project_id <projectId>` to get the available channels and match real `channelId` values for touchpoint nodes. For `webhook_push`, also run `ae-cli engage +channel_detail` and use `data.config.paramsList` to build `contentList`.
37
- 4. Map the intent JSON to `nodes` and `edges` (compact form, see §7 / §8).
38
- 5. `build` resolve any `need_input` slot `preview` `commit`, then verify with `+flow_detail`.
38
+ 4. Query `ae-cli engage +flow_node_config_schema --node_type <type>` before constructing each non-trivial node config, then run `ae-cli engage +validate_flow_node_config --node_type <type> --operation_mode save_flow --config '<config-json-string>'` before placing the config into `nodes` or `nodeConfigs`.
39
+ 5. Map the intent JSON to `nodes` and `edges` (compact form, see §7 / §8).
40
+ 6. `build` → resolve any `need_input` slot → `preview` → `commit`, then verify with `+flow_detail`.
39
41
 
40
42
  ---
41
43
 
@@ -54,7 +56,6 @@ You still organize user requirements into an intermediate intent first, then map
54
56
  | `nodes` | array | build | Compact nodes for structured build (see §7) |
55
57
  | `edges` | array | build | Compact edges for structured build (see §8) |
56
58
  | `dsl` | string | build | Topology-only: lines `node <id> <type>` and `edge <source> -> <target>` |
57
- | `sourceFlowUuid` | string | build | Clone an existing flow into a new draft |
58
59
  | `flowUuid` | string | build | Draft flow UUID for update-draft mode |
59
60
  | `parentFlowUuid` | string | build | Base version flow UUID for new-version mode |
60
61
  | `userIntent` | string | build | Natural-language intent (optional) |
@@ -69,6 +70,23 @@ You still organize user requirements into an intermediate intent first, then map
69
70
 
70
71
  `flowUuid` and `parentFlowUuid` are mutually exclusive; when creating a brand-new draft, provide neither.
71
72
 
73
+ ### Response Fields
74
+
75
+ Common response fields include:
76
+
77
+ | Field | Meaning |
78
+ |---|---|
79
+ | `status` | Draft state, such as `need_input`, `ready_to_preview`, `previewed`, or `committed` |
80
+ | `draftId` / `draftVersion` | Server draft identity and version |
81
+ | `selectedMode` | Server-selected authoring mode, such as structured build, wizard, or draft edit |
82
+ | `confidence` / `reason` | Router confidence and explanation for the selected mode |
83
+ | `nextSlot` | One missing slot to answer when `status=need_input` |
84
+ | `preview` | Human-readable preview; use it for user confirmation |
85
+ | `confirmToken` | Token returned by `preview`; required for `commit` |
86
+ | `warnings` / `errors` | Soft warnings and hard validation failures |
87
+ | `supportedOperations` | Server-advertised `build`, `preview`, and `commit` contract |
88
+ | `result` | Commit result, including the final `flowUuid` when committed |
89
+
72
90
  ### Compact node (`nodes[]`)
73
91
 
74
92
  | Field | Required | Description |
@@ -86,7 +104,7 @@ You still organize user requirements into an intermediate intent first, then map
86
104
  | `source` | Yes | Upstream node ID |
87
105
  | `target` | Yes | Downstream node ID |
88
106
  | `edgeId` | No | Edge ID, unique within the canvas |
89
- | `sourceBranchId` | No | Branch ID for edges leaving a split/judge node |
107
+ | `sourceBranchId` | No | Branch ID for edges leaving a split/judge node, or a push action node with two branch outgoing edges |
90
108
  | `config` | No | Edge business config as JSON string |
91
109
 
92
110
  ---
@@ -217,36 +235,47 @@ Inside action nodes: `channel_name` → real `channelId`; `content` → `content
217
235
  2. Any `branchId` later referenced by `edge.sourceBranchId` must be declared in that node's `config` first.
218
236
  3. Every path must eventually end at `exit_flow`.
219
237
  4. `config` may be a JSON object or a JSON string. (`targetClusterQp` inside it is usually a `JSON.stringify`'d string — see §9.)
238
+ 5. The backend normalizes some compatible input forms before validation: leading apostrophes on field names are stripped, property names are matched case-insensitively when unambiguous, `enableChannelTouchLimits` booleans become `1`/`0`, `targetClusterQp` relation strings `"0"`/`"1"` become numeric values inside the JSON string, and `clusterPredictCount: null` becomes `0`.
220
239
 
221
240
  ### 7.2 Common Node Types
222
241
 
223
242
  `single_trigger`, `repeat_trigger`, `event_trigger`, `event_split_flow`, `feature_split_flow`, `ab_split_flow`, `event_judge`, `feature_judge`, `message_push`, `wechat_push`, `webhook_push`, `time_control`, `exit_flow`.
224
243
 
244
+ Before writing any config below, call `+flow_node_config_schema` for the exact node type. The backend schema is the source of truth for required fields, defaults, allowed enum values, submit-time requirements, and examples.
245
+
225
246
  ### 7.3 Common `config` Templates
226
247
 
248
+ #### `single_trigger`
249
+
250
+ ```json
251
+ { "targetUserType": 2, "triggerTime": "<YYYY-MM-DD HH:mm>", "flowEndDate": "<YYYY-MM-DD HH:mm>", "targetClusterName": "<existing clusterName>" }
252
+ ```
253
+
254
+ For custom users, use `targetUserType=1` and fill `targetClusterQp` with the QP JSON string returned by the cluster QP workflow. For existing clusters (`targetUserType=2`), fill `targetClusterName` from a real current-project cluster list queried with the flow `tzOffset`; do not fill `targetClusterQp`. `clusterPredictCount` defaults to `0` and `clusterPredictTime` defaults to `""` when omitted.
255
+
227
256
  #### `repeat_trigger`
228
257
 
229
258
  ```json
230
- { "targetUserType": 1, "startDate": "<YYYY-MM-DD>", "endDate": "<YYYY-MM-DD>", "flowEndDate": "<YYYY-MM-DD HH:mm>", "crontab": "0 00 09 * * ?", "entryControlLimits": { "enableMultEntry": false, "disableConcurrentEntry": false }, "targetClusterName": null, "clusterPredictCount": null, "clusterPredictTime": "<YYYY-MM-DD HH:mm:ss>", "targetClusterQp": "<JSON.stringify(qp)>" }
259
+ { "targetUserType": 1, "startDate": "<YYYY-MM-DD>", "endDate": "<YYYY-MM-DD>", "flowEndDate": "<YYYY-MM-DD HH:mm>", "crontab": "0 00 09 * * ?", "entryControlLimits": { "enableMultEntry": false, "disableConcurrentEntry": false }, "targetClusterName": null, "targetClusterQp": "<JSON.stringify(qp)>" }
231
260
  ```
232
261
 
233
- `entry.segment` → `targetClusterQp`; `entry.schedule` → `crontab` (common default `0 00 09 * * ?`).
262
+ `entry.segment` → `targetClusterQp`; `entry.schedule` → `crontab` (common default `0 00 09 * * ?`). `clusterPredictCount` defaults to `0` and `clusterPredictTime` defaults to `""` when omitted. For existing clusters (`targetUserType=2`), fill `targetClusterName` from a real current-project cluster list queried with the flow `tzOffset`; do not fill `targetClusterQp`.
234
263
 
235
264
  #### `event_trigger`
236
265
 
237
266
  ```json
238
- { "triggerType": 3, "targetUserType": 1, "realtime": 0, "clusterRefresh": 12, "clusterRefreshTime": null, "startDate": "<YYYY-MM-DD HH:mm>", "endDate": "<YYYY-MM-DD HH:mm>", "flowEndDate": "<YYYY-MM-DD HH:mm>", "clusterPredictCount": null, "clusterPredictTime": "<YYYY-MM-DD HH:mm:ss>", "triggerRule": [ { "periodStart": "<startDate>", "periodEnd": "<endDate>", "periodTimeSymbol": "TS02", "dayStartTime": null, "startDay": null, "eventTriggerType": 0, "zoneoffset": 8, "events": [] } ], "entryControlLimits": { "enableMultEntry": false, "disableConcurrentEntry": false }, "targetClusterQp": "<JSON.stringify(qp) or null>" }
267
+ { "triggerType": 3, "targetUserType": 1, "startDate": "<YYYY-MM-DD HH:mm>", "endDate": "<YYYY-MM-DD HH:mm>", "flowEndDate": "<YYYY-MM-DD HH:mm>", "triggerRule": [ { "periodStart": "<startDate>", "periodEnd": "<endDate>", "periodTimeSymbol": "TS02", "eventTriggerType": 0, "events": [] } ], "entryControlLimits": { "enableMultEntry": false, "disableConcurrentEntry": false }, "targetClusterQp": "<JSON.stringify(qp) or null>" }
239
268
  ```
240
269
 
241
- `entry.trigger_event` → `triggerRule[0].events`; generate `targetClusterQp` only when `entry.segment` exists.
270
+ `entry.trigger_event` → `triggerRule[0].events`; generate `targetClusterQp` only when `entry.segment` exists. `triggerType` supports `3`, `4`, and `5`; `targetUserType=2` existing cluster is not supported for `event_trigger`; use `1` custom or `3` all users. For non-branch trigger rules, use `periodStart` / `periodEnd` / `periodTimeSymbol`. `realtime`, `clusterRefresh`, `clusterRefreshTime`, `clusterPredictTime`, and `triggerRule[].zoneoffset` can be omitted and are defaulted by the backend.
242
271
 
243
272
  #### `event_split_flow`
244
273
 
245
274
  ```json
246
- { "splitFlowType": 1, "branchList": [ { "branchId": "<branchId>", "branchName": "<label>", "branchType": 1, "triggerRule": [ { "delayTimeSymbol": "<minute|hour|day>", "delayTime": "<number>", "eventTriggerType": "<0 or -1>", "zoneoffset": 8, "events": [] } ] } ] }
275
+ { "splitFlowType": 1, "branchList": [ { "branchId": "<branchId>", "branchName": "<label>", "branchType": 1, "targetClusterType": 3, "triggerRule": [ { "delayTimeSymbol": "<minute|hour|day>", "delayTime": "<number>", "eventTriggerType": "<0|-1|1|2>", "events": [] } ] } ] }
247
276
  ```
248
277
 
249
- `time_limit` → `delayTimeSymbol` + `delayTime`; `0` = happened, `-1` = not happened. Fallback branch keeps only `{ "branchId": "<branchId>", "branchType": 2 }`.
278
+ `time_limit` → `delayTimeSymbol` + `delayTime`; `0` = happened, `-1` = not happened. For `branchType=1`, fill `targetClusterType`; use `3` for all users. If `targetClusterType` is not `3`, fill `clusterKey`. `occasionKeys` is optional, but each item must contain at least four colon-separated parts. Fallback branch keeps only `{ "branchId": "<branchId>", "branchType": 2 }` and must omit `triggerRule`.
250
279
 
251
280
  #### `feature_split_flow`
252
281
 
@@ -265,10 +294,10 @@ Fallback branch keeps only `branchId` + `branchType: 2`.
265
294
  #### `event_judge`
266
295
 
267
296
  ```json
268
- { "transferType": 1, "meetBranchId": "<meetBranchId>", "notMeetBranchId": "<notMeetBranchId>", "triggerRule": [ { "delayTimeSymbol": "<minute|hour|day>", "delayTime": "<number>", "eventTriggerType": 0, "zoneoffset": 8, "events": [] } ] }
297
+ { "transferType": 1, "meetBranchId": "<meetBranchId>", "notMeetBranchId": "<notMeetBranchId>", "triggerRule": [ { "periodStart": "<YYYY-MM-DD HH:mm>", "periodEnd": "<YYYY-MM-DD HH:mm>", "periodTimeSymbol": "TS02", "eventTriggerType": 0, "events": [] } ] }
269
298
  ```
270
299
 
271
- `wait_time` `delayTimeSymbol` + `delayTime` (default `30 minute` if unspecified).
300
+ `event_judge` is a non-branch flow task. Use `periodStart`, `periodEnd`, and `periodTimeSymbol` in the A segment; use `delayTime` / `delayTimeSymbol` only for a B segment when the schema/example requires it. `eventTriggerType` supports `0`, `1`, and `2`.
272
301
 
273
302
  #### `feature_judge`
274
303
 
@@ -279,10 +308,10 @@ Fallback branch keeps only `branchId` + `branchType: 2`.
279
308
  #### `message_push` / `webhook_push`
280
309
 
281
310
  ```json
282
- { "channelId": "<matched channelId>", "channelType": "<matched channelType>", "enableChannelTouchLimits": false, "isOccasionUp": false, "contentList": [ { "pushLanguageCode": "default", "content": [] } ], "processType": 1 }
311
+ { "channelId": "<matched channelId>", "channelType": "<matched channelType>", "contentList": [ { "pushLanguageCode": "default", "content": [] } ] }
283
312
  ```
284
313
 
285
- `channel_name` → real `channelId`; `content` → the param that best matches body text. When the param `type = TEXT`, also add `{ "config": "[{\"type\":\"paragraph\",\"children\":[{\"text\":\"<same as value>\"}]}]" }`. First `contentList` entry must use `"pushLanguageCode": "default"`; generate extra languages per `languages`.
314
+ `channel_name` → real `channelId`; `content` → the param that best matches body text. `processType` defaults to `1`, `enableChannelTouchLimits` defaults to `0`, and `isOccasionUp` defaults to `false`. `enableChannelTouchLimits` may be supplied as a boolean for compatibility, but `normalizedConfigObject` will convert it to `1` or `0`. When the param `type = TEXT`, also add `{ "config": "[{\"type\":\"paragraph\",\"children\":[{\"text\":\"<same as value>\"}]}]" }`. `contentList[].content` should be a JSON array; validation also accepts a JSON-stringified array for compatibility. When the param `type = OBJ_ARRAY`, `value` must be a JSON array, and the item must copy the complete child field definition from `query_channel_detail data.config.paramsList[].objArray`. First `contentList` entry must use `"pushLanguageCode": "default"`; generate extra languages per `languages`.
286
315
 
287
316
  #### `wechat_push`
288
317
 
@@ -296,6 +325,8 @@ Fallback branch keeps only `branchId` + `branchType: 2`.
296
325
  { "controlType": 1, "timeUnit": "<minute|hour|day>", "timeUnitNum": "<number>" }
297
326
  ```
298
327
 
328
+ `controlType=1` requires `timeUnit` + `timeUnitNum`; `2` requires `timePointStr`; `3` requires `rollTimeDayNum` + `timePointStr`; `4` requires `fixedDay` + `timePointStr`; `5` requires `relativeMonthLastDayNum` + `timePointStr`.
329
+
299
330
  `30 minutes` → `minute`+`30`; `2 hours` → `hour`+`2`; `1 day` → `day`+`1`.
300
331
 
301
332
  #### `exit_flow`
@@ -325,14 +356,17 @@ Minimum usable `config`: `{}`.
325
356
  | `single_trigger` / `repeat_trigger` / `event_trigger` | 1 | do not provide |
326
357
  | `event_split_flow` / `feature_split_flow` / `ab_split_flow` | one per branch | the corresponding `branchList[].branchId` |
327
358
  | `event_judge` / `feature_judge` | 2 | `meetBranchId` and `notMeetBranchId` |
328
- | `message_push` / `wechat_push` / `webhook_push` / `time_control` | 1 | do not provide |
359
+ | `message_push` / `wechat_push` / `webhook_push` | 1 or 2 | omit for 1 outgoing edge; for 2 outgoing edges, use the node config's `meetBranchId` and `notMeetBranchId` |
360
+ | `time_control` | 1 | do not provide |
329
361
  | `exit_flow` | 0 | do not provide |
330
362
 
331
363
  ### 8.4 Rules
332
364
 
333
365
  1. `source` / `target` must reference existing `node.id` values.
334
- 2. Only edges leaving split/judge nodes carry `sourceBranchId`, and it must be a `branchId` already declared in the upstream node `config`.
335
- 3. The graph must be a DAG (no cycles).
366
+ 2. Edges leaving split/judge nodes carry `sourceBranchId`. Push action nodes (`message_push`, `wechat_push`, `webhook_push`) may also carry `sourceBranchId` when they have exactly two outgoing edges.
367
+ 3. For push action nodes with one outgoing edge, omit `meetBranchId` / `notMeetBranchId`; if present, the backend ignores them.
368
+ 4. For push action nodes with two outgoing edges, set both `config.meetBranchId` and `config.notMeetBranchId`, and make the two `edge.sourceBranchId` values match them.
369
+ 5. The graph must be a DAG (no cycles).
336
370
 
337
371
  ---
338
372
 
@@ -436,7 +470,7 @@ ae-cli engage +save_flow --project_id 1 --req '{
436
470
  "flowDesc": "New user welcome flow",
437
471
  "groupId": 0, "tzOffset": 8, "versionType": 1,
438
472
  "nodes": [
439
- { "id": "n1", "type": "single_trigger", "name": "Enter", "config": {} },
473
+ { "id": "n1", "type": "single_trigger", "name": "Enter", "config": { "targetUserType": 2, "triggerTime": "2026-03-31 19:00", "flowEndDate": "2026-04-04 18:00", "targetClusterName": "cohort_20260331_182643" } },
440
474
  { "id": "n2", "type": "exit_flow", "name": "End", "config": {} }
441
475
  ],
442
476
  "edges": [ { "source": "n1", "target": "n2" } ]
@@ -483,6 +517,7 @@ Output the complete `req` JSON for debugging plus a clear failure reason.
483
517
  | Symptom | Cause | Fix |
484
518
  |---|---|---|
485
519
  | `Unsupported save_flow operation: null` | Legacy `nodeList`/`edgeList` payload, or `operation` missing | Put `operation` = `build`/`preview`/`commit` in `req`, use `nodes`/`edges` |
520
+ | `Flag --req.sourceFlowUuid is no longer supported` | Removed clone mode from an older protocol | Call `+flow_detail`, convert detail `nodeList`/`edgeList` into compact `nodes`/`edges`, then create with `operation=build` |
486
521
  | operation rejected (`SAVE`/`DRAFT`/`SUBMIT`/`mode`/`action`…) | Wrong field or wrong enum | `operation` is at `req.operation`; enum is only `build`/`preview`/`commit` |
487
522
  | `invalid_qp_relation: QP relation must be number 0 or 1` | `relation` sent as string | Use integer `0`/`1` |
488
523
  | `invalid_qp_leaf: QP property leaf must contain columnType/columnDesc` | userCondition leaf missing fields | Add `columnType` + `columnDesc` |
@@ -499,16 +534,17 @@ Output the complete `req` JSON for debugging plus a clear failure reason.
499
534
  ## 13. Most Common Mistakes
500
535
 
501
536
  1. **Legacy `nodeList`/`edgeList`** — use `nodes`/`edges` with `operation=build`.
502
- 2. **Time units must be lowercase** — `day`, `hour`, `minute`, `week`, `month` (not `DAY`/`HOUR`).
503
- 3. **Do not invent `channelId`**get it from `ae-cli engage +channel_list`.
504
- 4. **Define branch IDs before referencing them** `edge.sourceBranchId` must already exist in the upstream node `config`.
505
- 5. **`targetClusterQp` is usually a string** — `JSON.stringify` the QP object.
506
- 6. **TEXT rich-text `config` must also be a string** — not an object.
507
- 7. **`commit` uses preview's token/version** — not build's.
508
- 8. **Do not merge branches again when `splitFlowType = 2`**.
537
+ 2. **Removed clone mode** — do not pass `sourceFlowUuid`; copy flows via `+flow_detail` and a fresh `operation=build` request.
538
+ 3. **Time units must be lowercase** `day`, `hour`, `minute`, `week`, `month` (not `DAY`/`HOUR`).
539
+ 4. **Do not invent `channelId`**get it from `ae-cli engage +channel_list`.
540
+ 5. **Define branch IDs before referencing them** — `edge.sourceBranchId` must already exist in the upstream node `config`; for two-edge push action nodes, use `meetBranchId` and `notMeetBranchId`.
541
+ 6. **`targetClusterQp` is usually a string** — `JSON.stringify` the QP object.
542
+ 7. **TEXT rich-text `config` must also be a string** — not an object.
543
+ 8. **`commit` uses preview's token/version** not build's.
544
+ 9. **Do not merge branches again when `splitFlowType = 2`**.
509
545
 
510
546
  ---
511
547
 
512
548
  ## 14. One-Sentence Summary
513
549
 
514
- Drive `+save_flow` as a state machine — `build` (`nodes`/`edges`, not `nodeList`/`edgeList`) → resolve any `need_input` slots → `preview` (take its fresh `draftVersion` + `confirmToken`) → `commit` → verify with `+flow_detail`; keep QP `relation` integer, fill `columnType`/`columnDesc` on userCondition leaves and `quotaDesc`/`quota`/`analysisParams` on `taPropQuota`, and ensure touchpoint channels are enabled before referencing them.
550
+ Drive `+save_flow` as a state machine — `build` (`nodes`/`edges`, not `nodeList`/`edgeList` or `sourceFlowUuid`) → resolve any `need_input` slots → `preview` (take its fresh `draftVersion` + `confirmToken`) → `commit` → verify with `+flow_detail`; keep QP `relation` integer, fill `columnType`/`columnDesc` on userCondition leaves and `quotaDesc`/`quota`/`analysisParams` on `taPropQuota`, and ensure touchpoint channels are enabled before referencing them.
@@ -1,7 +1,7 @@
1
1
  # ae-engage +validate_flow_node_config
2
2
 
3
3
 
4
- Validate a single node configuration before saving a flow.
4
+ Validate and normalize a single node configuration before placing it into a `save_flow` request.
5
5
 
6
6
  Mapped command: `ae-cli engage +validate_flow_node_config`
7
7
 
@@ -9,15 +9,38 @@ Mapped command: `ae-cli engage +validate_flow_node_config`
9
9
 
10
10
  | Flag | Type | Required | Description |
11
11
  |------|------|------|------|
12
- | `--node_type` | string | Yes | node type |
13
- | `--config` | string | Yes | node config JSON string |
14
- | `--operation_mode` | string | Yes | validation mode |
12
+ | `--node_type` | string | Yes | Flow node type |
13
+ | `--config` | string | Yes | Node config JSON object encoded as a string |
14
+ | `--operation_mode` | string | Yes | Validation mode |
15
+
16
+ ## When To Use
17
+
18
+ Use this after `+flow_node_config_schema` and before passing a config into `+save_flow`.
19
+
20
+ The command validates one node config only; it does not validate the full canvas topology. It returns:
21
+
22
+ - `valid`: whether the candidate config passed validation
23
+ - `normalizedConfigObject`: backend-normalized config with defaulted fields
24
+ - `errors`: hard validation failures to fix before calling `+save_flow`
25
+ - `warnings`: issues that depend on live channel/template/config data
26
+
27
+ Use `--operation_mode save_flow` for the current exposed MCP protocol. Use `save_submit_flow` only when you intentionally want stricter submit-time checks.
28
+
29
+ Important current rules:
30
+
31
+ - `event_trigger` / `event_judge` A segment: use `periodStart`, `periodEnd`, `periodTimeSymbol`; do not use branch-style `delayTime`.
32
+ - `event_split_flow` branch segment: use `delayTime`, `delayTimeSymbol`, `targetClusterType`; omit `triggerRule` on default branches.
33
+ - `event_trigger targetUserType=2` is invalid.
34
+ - Push `OBJ_ARRAY.value` must be a JSON array, not a stringified array.
35
+ - Push `contentList[].content` should be a JSON array, but a JSON-stringified array is accepted for compatibility.
36
+ - Compatible inputs are normalized before validation: apostrophe-prefixed field aliases, case-insensitive property aliases, `enableChannelTouchLimits` booleans, string `"0"`/`"1"` QP relations inside `targetClusterQp`, and `clusterPredictCount: null`.
37
+ - Missing defaults such as `clusterPredictCount`, `clusterPredictTime`, `processType`, and `zoneoffset` may be filled in `normalizedConfigObject`.
15
38
 
16
39
  ## Enum Notes
17
40
 
18
41
  ### `--node_type`
19
42
 
20
- Common node types include:
43
+ Schema-backed node types include:
21
44
 
22
45
  - `single_trigger`
23
46
  - `repeat_trigger`
@@ -27,15 +50,10 @@ Common node types include:
27
50
  - `message_push`
28
51
  - `wechat_push`
29
52
  - `webhook_push`
30
- - `config_push`
31
- - `tag`
32
53
  - `time_control`
33
54
  - `feature_split_flow`
34
55
  - `event_split_flow`
35
- - `trigger_prop_split_flow`
36
- - `percent_split_flow`
37
56
  - `ab_split_flow`
38
- - `race_split_flow`
39
57
  - `exit_flow`
40
58
 
41
59
  ### `--operation_mode`
@@ -94,14 +94,14 @@ After user responds, record to `meta.scenario` and generate `meta.plan_name`.
94
94
 
95
95
  Before asking, decide whether the current runtime is an agent sandbox. The agent may judge this from runtime context such as sandbox-provisioned `cli-token.json`, restricted filesystem access, or absence of the user's local files. Do not ask the user just to decide sandbox visibility.
96
96
 
97
- Product document and Codebase are local-material options. **Hide both options in sandbox environments**. When options are hidden, renumber the visible list contiguously from 1; never show skipped numbers.
97
+ Product document is available in sandbox environments **only for files that are readable inside the sandbox workspace**, including files the user attaches/uploads into the conversation workspace. It cannot read arbitrary local paths outside the sandbox unless those files are mounted or attached. Codebase is a local-material option and must be hidden in sandbox environments unless the codebase is already present in the readable workspace. When options are hidden, renumber the visible list contiguously from 1; never show skipped numbers.
98
98
 
99
99
  If **not** in a sandbox environment, ask exactly:
100
100
 
101
101
  ```text
102
102
  Choose your source material (up to 2):
103
103
 
104
- 1 - Product document (local path, image file, or folder; hidden in sandbox) — Extract events and properties from product docs; supports md/pdf/docx/URL/images (png/jpg/jpeg/webp)
104
+ 1 - Product document (local path, image file, or folder) — Extract events and properties from product docs; supports md/pdf/docx/URL/images (png/jpg/jpeg/webp)
105
105
  2 - Detailed description (conversational) — Describe app business flow, core features, user behaviors, monetization model, etc.
106
106
  3 - Codebase (local project path; hidden in sandbox) — Analyze source code to extract events and properties
107
107
  4 - Pre-built template (built-in industry and game genre templates) — Select a built-in template
@@ -114,10 +114,11 @@ If in a sandbox environment, ask exactly:
114
114
  ```text
115
115
  Choose your source material (up to 2):
116
116
 
117
- 1 - Detailed description (conversational) Describe app business flow, core features, user behaviors, monetization model, etc.
118
- 2 - Pre-built template (built-in industry and game genre templates) Select a built-in template
117
+ 1 - Product document (sandbox workspace path, uploaded attachment, URL, image file, or folder) Extract events and properties from product docs; supports md/pdf/docx/URL/images (png/jpg/jpeg/webp). You can attach/upload relevant files here.
118
+ 2 - Detailed description (conversational) Describe app business flow, core features, user behaviors, monetization model, etc.
119
+ 3 - Pre-built template (built-in industry and game genre templates) — Select a built-in template
119
120
 
120
- Reply with number(s), e.g. 1 or 1,2. Select up to 2.
121
+ Reply with number(s), e.g. 1 or 1,3. Select up to 2.
121
122
  ```
122
123
 
123
124
  Do not rewrite this source material list as unnumbered bullets, cards, or prose. The user must be able to reply with the visible numbers.
@@ -126,7 +127,7 @@ User can multi-select (max 2). Interpret numbers by the **visible list shown to
126
127
 
127
128
  Canonical source material options:
128
129
 
129
- - **Product document** (local path, image file, or folder; hidden in sandbox) — Extract events and properties from product docs; supports md/pdf/docx/URL/images (png/jpg/jpeg/webp)
130
+ - **Product document** (local path, sandbox workspace path, uploaded attachment, URL, image file, or folder) — Extract events and properties from product docs; supports md/pdf/docx/URL/images (png/jpg/jpeg/webp)
130
131
  - **Detailed description** (conversational) — Describe app business flow, core features, user behaviors, monetization model, etc.
131
132
  - **Codebase** (local project path; hidden in sandbox) — Analyze source code to extract events and properties
132
133
  - **Pre-built template** (built-in industry and game genre templates) — Select a built-in template (run `AE_LANG=<user_lang> ae-cli tracking plan list-templates --json` to see available templates)
@@ -142,7 +143,8 @@ Based on user selection, determine source material type and record to `meta.sour
142
143
  | Any two-item combo | Join two types with `_` | First as baseline, second as supplement (priority: template → codebase → prd → chat) |
143
144
 
144
145
  **Follow-up questions** (ask in selection order):
145
- - Product doc → ask **"What is the product document path? You can provide one or more paths, separated by commas or newlines (local paths, URLs, image files, or folders)"**
146
+ - Product doc → if not in a sandbox environment, ask **"What is the product document path? You can provide one or more paths, separated by commas or newlines (local paths, URLs, image files, or folders)"**
147
+ - Product doc → if in a sandbox environment, ask **"What is the product document path? You can provide one or more sandbox workspace paths, uploaded attachment paths, URLs, image files, or folders. You can also attach/upload relevant files here, and I will read them from the sandbox workspace if available."**
146
148
  - Detailed description → If too vague, follow up on core features, user behaviors, business flows, monetization
147
149
  - Codebase → ask **"What is the project directory path?"**, then scan source to extract business logic
148
150
  - Pre-built template → display matching templates for user confirmation
@@ -5,7 +5,7 @@
5
5
  ## Command
6
6
 
7
7
  ```bash
8
- ae-cli metadata data-table csv-write --project-id <project_id> --operation create --input-file-id <input_file_id> --data-table-name <name> --columns '<columns_json>' --yes
8
+ ae-cli metadata data-table csv-write --project-id <project_id> --operation create --input-file-id <input_file_id> --data-table-name datatable_<project_id>_<name> --columns '<columns_json>' --yes
9
9
  ae-cli metadata data-table csv-write --project-id <project_id> --operation incremental_update --data-table-id <id> --input-file-id <input_file_id> --yes
10
10
  ae-cli metadata data-table csv-write --project-id <project_id> --operation replace_update --data-table-id <id> --input-file-id <input_file_id> --yes
11
11
  ```
@@ -18,12 +18,14 @@ ae-cli metadata data-table csv-write --project-id <project_id> --operation repla
18
18
  | `--operation` | Yes | `create`, `incremental_update`, or `replace_update`. |
19
19
  | `--input-file-id` | Yes | ID returned by `metadata input-file upload`. |
20
20
  | `--data-table-id` | For updates | Existing data table ID. |
21
- | `--data-table-name` | For create | Technical data table name. |
21
+ | `--data-table-name` | No | Optional technical data table name. If supplied, use `datatable_<project_id>_<name>`. |
22
22
  | `--display-name` | No | Human-readable table name. |
23
23
  | `--description` | No | Table description. |
24
- | `--columns` | No | Column definitions JSON array. |
24
+ | `--columns` | No | Column definitions JSON array. Preferred fields are `column_name`, `select_type`, and `column_desc`; CLI also accepts `name`, `type`, and `display_name` aliases. |
25
25
 
26
26
  ## Decision Rules
27
27
 
28
28
  - Upload the CSV first with `metadata input-file upload --purpose data_table.csv`.
29
+ - Do not invent `input_file_id` or `data_table_id`; use upload/list outputs.
30
+ - If you provide `--data-table-name`, it must include the project segment, for example `datatable_2_orders`.
29
31
  - This is a write command; use `--dry-run` before non-dry-run and pass `--yes` when executing.
@@ -5,7 +5,7 @@
5
5
  ## Command
6
6
 
7
7
  ```bash
8
- ae-cli metadata data-table sql-write --project-id <project_id> --operation create --table-name <name> --columns '<columns_json>' --qp '<qp_json>' --strategy overwrite --yes
8
+ ae-cli metadata data-table sql-write --project-id <project_id> --operation create --table-name datatable_<project_id>_<name> --columns '<columns_json>' --qp '<qp_json>' --zone-offset 8 --strategy overwrite --yes
9
9
  ae-cli metadata data-table sql-write --project-id <project_id> --operation update --data-table-id <id> --columns '<columns_json>' --qp '<qp_json>' --yes
10
10
  ```
11
11
 
@@ -15,13 +15,13 @@ ae-cli metadata data-table sql-write --project-id <project_id> --operation updat
15
15
  |---|---|---|
16
16
  | `--project-id` / `-p` | Yes | Numeric project ID. |
17
17
  | `--operation` | Yes | `create` or `update`. |
18
- | `--columns` | Yes | Column definitions JSON array. |
18
+ | `--columns` | Yes | Column definitions JSON array. Preferred fields are `column_name`, `column_type`, and `column_desc`; CLI also accepts `name`, `type`, and `display_name` aliases. |
19
19
  | `--qp` | Yes | SQL data table query plan JSON. |
20
20
  | `--data-table-id` | For update | Existing data table ID. |
21
- | `--table-name` | For create | Technical table name. |
21
+ | `--table-name` | For create | Technical table name. Use `datatable_<project_id>_<name>`. |
22
22
  | `--display-name` | No | Human-readable name. |
23
23
  | `--remarks` | No | Table remarks. |
24
- | `--zone-offset` | No | Time zone offset such as `+08:00`. |
24
+ | `--zone-offset` | No | Time zone offset in hours. For example, UTC+8 is `8` and UTC-5 is `-5`. Valid range: -12 to 14. |
25
25
  | `--strategy` | No | `overwrite` or `insert`. |
26
26
  | `--update-cron` | No | Scheduled update cron. |
27
27
 
@@ -29,3 +29,4 @@ ae-cli metadata data-table sql-write --project-id <project_id> --operation updat
29
29
 
30
30
  - This is a write command; use `--dry-run` before non-dry-run and pass `--yes` when executing.
31
31
  - Keep `columns` and `qp` as valid JSON; do not pass raw SQL unless the server schema requires it inside `qp`.
32
+ - If you provide a table name, it must include the project segment, for example `datatable_2_orders_sql`.
@@ -5,7 +5,7 @@
5
5
  ## Command
6
6
 
7
7
  ```bash
8
- ae-cli metadata property create-and-bind-csv-dimension-table --project-id <project_id> --property-name <name> --property-scope user --input-file-id <input_file_id> --data-table-name <table_name> --columns '<columns_json>' --yes
8
+ ae-cli metadata property create-and-bind-csv-dimension-table --project-id <project_id> --property-name <name> --property-scope user --input-file-id <input_file_id> --data-table-name datatable_<project_id>_<name> --columns '<columns_json>' --yes
9
9
  ```
10
10
 
11
11
  ## Parameters
@@ -16,15 +16,17 @@ ae-cli metadata property create-and-bind-csv-dimension-table --project-id <proje
16
16
  | `--property-name` | Yes | Property technical name. |
17
17
  | `--property-scope` | Yes | Property owner table, for example `event` or `user`. |
18
18
  | `--input-file-id` | Yes | ID returned by `metadata input-file upload`. |
19
- | `--data-table-name` | No | Technical data table name. |
19
+ | `--data-table-name` | No | Optional technical data table name. If supplied, use `datatable_<project_id>_<name>`. |
20
20
  | `--display-name` | No | Human-readable table name. |
21
21
  | `--description` | No | Table description. |
22
- | `--columns` | No | Column definitions JSON array. |
22
+ | `--columns` | No | Column definitions JSON array. Preferred fields are `column_name`, `select_type`, and `column_desc`; CLI also accepts `name`, `type`, and `display_name` aliases. |
23
23
  | `--timestamp-join-format` | No | Timestamp join format. |
24
24
  | `--dict-columns` | No | Dictionary column names JSON array. |
25
25
 
26
26
  ## Decision Rules
27
27
 
28
28
  - Upload the CSV first with `metadata input-file upload --purpose data_table.csv`.
29
+ - Do not invent `input_file_id`; use the value returned by upload.
30
+ - If you provide `--data-table-name`, it must include the project segment, for example `datatable_2_user_dict`.
29
31
  - Use this one-step command when the user wants a new CSV dimension table bound to a property.
30
32
  - This is a write command; use `--dry-run` before non-dry-run and pass `--yes` when executing.
@@ -1,19 +0,0 @@
1
- import {
2
- clearToken,
3
- getAuthStatus,
4
- getToken,
5
- loadToken,
6
- resolveHost,
7
- saveToken,
8
- validateToken
9
- } from "./chunk-U6QPKCN3.js";
10
- import "./chunk-WPXHCP4A.js";
11
- export {
12
- clearToken,
13
- getAuthStatus,
14
- getToken,
15
- loadToken,
16
- resolveHost,
17
- saveToken,
18
- validateToken
19
- };
@@ -1,105 +0,0 @@
1
- import {
2
- getToken,
3
- load,
4
- loadCliToken,
5
- save
6
- } from "./chunk-U6QPKCN3.js";
7
- import {
8
- getActiveHost,
9
- getFallbackCliToken,
10
- listHosts,
11
- logger,
12
- safeJsonParse
13
- } from "./chunk-WPXHCP4A.js";
14
-
15
- // src/core/cli-token.ts
16
- var CLI_TOKEN_GENERATE_PATH = "/v1/ta/cli/token/generate";
17
- var _cliTokenCache = /* @__PURE__ */ new Map();
18
- async function generateCliToken(hostUrl) {
19
- const accessToken = await getToken(hostUrl);
20
- const base = hostUrl.replace(/\/+$/, "");
21
- const url = `${base}${CLI_TOKEN_GENERATE_PATH}`;
22
- const resp = await fetch(url, {
23
- method: "GET",
24
- headers: {
25
- "Authorization": `bearer ${accessToken}`
26
- }
27
- });
28
- if (!resp.ok) {
29
- throw new Error(`CLI token generate HTTP error: ${resp.status} ${resp.statusText}`);
30
- }
31
- const data = safeJsonParse(await resp.text());
32
- if (data.return_code !== 0) {
33
- throw new Error(`CLI token generate error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
34
- }
35
- const cliToken = data.data?.userSecret;
36
- if (!cliToken) {
37
- throw new Error("CLI token generate error: empty userSecret in response");
38
- }
39
- return cliToken;
40
- }
41
- function persistCliTokenIfPossible(hostUrl, cliToken) {
42
- const existing = load(hostUrl);
43
- if (!existing) {
44
- logger.info(`cli-token: no secure-store session for ${hostUrl}, keeping token in-process only`);
45
- return;
46
- }
47
- save(hostUrl, { ...existing, cliToken });
48
- }
49
- function clearPersistedCliToken(hostUrl) {
50
- const existing = load(hostUrl);
51
- if (existing?.cliToken) {
52
- save(hostUrl, { ...existing, cliToken: void 0 });
53
- }
54
- }
55
- async function getCliToken(hostOverride) {
56
- const hostUrl = hostOverride || getActiveHost();
57
- const cached = _cliTokenCache.get(hostUrl);
58
- if (cached) {
59
- return cached;
60
- }
61
- const storedToken = loadCliToken(hostUrl);
62
- if (storedToken) {
63
- _cliTokenCache.set(hostUrl, storedToken);
64
- logger.info(`Using persisted CLI token (secure-store) for ${hostUrl}`);
65
- return storedToken;
66
- }
67
- const fallbackToken = getFallbackCliToken(hostUrl);
68
- if (fallbackToken) {
69
- _cliTokenCache.set(hostUrl, fallbackToken);
70
- logger.info(`Using sandbox-provisioned CLI token (fallback file) for ${hostUrl}`);
71
- return fallbackToken;
72
- }
73
- return mintCliToken(hostUrl);
74
- }
75
- async function mintCliToken(hostUrl) {
76
- logger.info(`Generating CLI token for ${hostUrl}`);
77
- const cliToken = await generateCliToken(hostUrl);
78
- _cliTokenCache.set(hostUrl, cliToken);
79
- persistCliTokenIfPossible(hostUrl, cliToken);
80
- logger.info(`CLI token generated, cached, and persisted for ${hostUrl}`);
81
- return cliToken;
82
- }
83
- function clearCliToken(hostUrl) {
84
- if (hostUrl) {
85
- _cliTokenCache.delete(hostUrl);
86
- clearPersistedCliToken(hostUrl);
87
- return;
88
- }
89
- _cliTokenCache.clear();
90
- for (const { url } of listHosts()) {
91
- clearPersistedCliToken(url);
92
- }
93
- }
94
- function setCliTokenManual(token, hostUrl) {
95
- _cliTokenCache.set(hostUrl, token);
96
- persistCliTokenIfPossible(hostUrl, token);
97
- logger.info(`CLI token set for ${hostUrl}`);
98
- }
99
-
100
- export {
101
- getCliToken,
102
- mintCliToken,
103
- clearCliToken,
104
- setCliTokenManual
105
- };
@@ -1,14 +0,0 @@
1
- import {
2
- clearCliToken,
3
- getCliToken,
4
- mintCliToken,
5
- setCliTokenManual
6
- } from "./chunk-FPE5LGVU.js";
7
- import "./chunk-U6QPKCN3.js";
8
- import "./chunk-WPXHCP4A.js";
9
- export {
10
- clearCliToken,
11
- getCliToken,
12
- mintCliToken,
13
- setCliTokenManual
14
- };