@thinkingai/ae-cli 1.0.30 → 6.0.16

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 (355) hide show
  1. package/dist/{auth-U25QJU5D.js → auth-DYC2BGLM.js} +2 -3
  2. package/dist/{auth-H3GJD55A.js → auth-GHBMJ5ZR.js} +33 -17
  3. package/dist/{chunk-CLJF7MQA.js → chunk-2DUEAXV3.js} +1 -1
  4. package/dist/{chunk-SF3KTPIC.js → chunk-5OC7CYCG.js} +2 -2
  5. package/dist/{chunk-SRJIAOBN.js → chunk-6W4QOZAL.js} +10 -0
  6. package/dist/{chunk-I42JGQ2J.js → chunk-BJX3GXWC.js} +3 -5
  7. package/dist/{chunk-GLNZSDKO.js → chunk-DMMEPCST.js} +4 -6
  8. package/dist/{chunk-VJFUB3H3.js → chunk-I5CRVM2S.js} +3 -3
  9. package/dist/{chunk-GSJGPNKK.js → chunk-PN3OS34E.js} +1 -1
  10. package/dist/{chunk-JM34JPCO.js → chunk-RSHMZ3LG.js} +178 -4
  11. package/dist/{client-IN42F223.js → client-2UJ63MVQ.js} +3 -4
  12. package/dist/{config-64G36TJL.js → config-NCUGK6NS.js} +3 -3
  13. package/dist/index.js +2526 -28
  14. package/dist/{model-VZCYNIOG.js → model-SJSOZTRS.js} +2 -2
  15. package/dist/{raw-WJIWC6YP.js → raw-7NVWSVJP.js} +5 -7
  16. package/dist/{sync-NVASAISS.js → sync-GRVO4K3U.js} +3 -3
  17. package/dist/{te-agent-YV4DXEXK.js → te-agent-KZRIEN4N.js} +468 -46
  18. package/dist/{te-analysis-CB3DA5I5.js → te-analysis-VAR4KUOK.js} +144 -29
  19. package/dist/{te-audience-W7SCQFC7.js → te-audience-KMKYI2YJ.js} +22 -15
  20. package/dist/{te-common-FBXVWBSI.js → te-common-WNCZB7R7.js} +4 -5
  21. package/dist/{te-community-LNVDZSGW.js → te-community-JEEFXPB3.js} +10 -11
  22. package/dist/{te-dataops-IPCSSWYH.js → te-dataops-GD3XBYCS.js} +11 -12
  23. package/dist/{te-engage-KARARMIR.js → te-engage-4XHCTS6I.js} +4 -5
  24. package/dist/{te-kb-2Z2CARN3.js → te-kb-B62KFP2A.js} +96 -8
  25. package/dist/{te-meta-PDKLMWXN.js → te-meta-EPZGQN56.js} +9 -10
  26. package/dist/{te-team-SW5B7DHO.js → te-team-YY24VORI.js} +6 -7
  27. package/dist/tracking/i18n/resources/cli/en.json +153 -0
  28. package/dist/tracking/i18n/resources/cli/ja.json +153 -0
  29. package/dist/tracking/i18n/resources/cli/ko.json +153 -0
  30. package/dist/tracking/i18n/resources/cli/zh.json +153 -0
  31. package/package.json +9 -3
  32. package/skills/ae-agent/SKILL.md +65 -25
  33. package/skills/ae-analysis/SKILL.md +108 -8
  34. package/skills/ae-analysis/references/cancel_query.md +39 -0
  35. package/skills/ae-analysis/references/drilldown_user_events.md +4 -2
  36. package/skills/ae-analysis/references/drilldown_users.md +4 -2
  37. package/skills/ae-analysis/references/get_bi_panel_detail.md +35 -0
  38. package/skills/ae-analysis/references/list_alerts.md +1 -1
  39. package/skills/ae-analysis/references/list_bi_panels.md +35 -0
  40. package/skills/ae-analysis/references/list_cluster_members.md +4 -1
  41. package/skills/ae-analysis/references/list_dashboards.md +1 -1
  42. package/skills/ae-analysis/references/list_entities.md +1 -1
  43. package/skills/ae-analysis/references/list_events.md +1 -1
  44. package/skills/ae-analysis/references/list_metrics.md +1 -1
  45. package/skills/ae-analysis/references/list_project_mark_times.md +1 -1
  46. package/skills/ae-analysis/references/list_properties.md +1 -1
  47. package/skills/ae-analysis/references/list_public_access_links.md +1 -1
  48. package/skills/ae-analysis/references/list_reports.md +1 -1
  49. package/skills/ae-analysis/references/list_tag_members.md +4 -1
  50. package/skills/ae-analysis/references/query_adhoc.md +6 -5
  51. package/skills/ae-analysis/references/query_bi_panel_data.md +58 -0
  52. package/skills/ae-analysis/references/query_dashboard_report_data.md +4 -1
  53. package/skills/ae-analysis/references/query_entity_details.md +5 -2
  54. package/skills/ae-analysis/references/query_event_details.md +4 -1
  55. package/skills/ae-analysis/references/query_report_data.md +2 -2
  56. package/skills/ae-analysis-global/SKILL.md +3 -1
  57. package/skills/ae-analysis-intent/SKILL.md +132 -0
  58. package/skills/ae-data-integration-helper/SKILL.md +242 -0
  59. package/skills/ae-data-integration-helper/references/android_sdk_faq.md +179 -0
  60. package/skills/ae-data-integration-helper/references/c_sdk_compilation.md +83 -0
  61. package/skills/ae-data-integration-helper/references/c_sdk_faq.md +416 -0
  62. package/skills/ae-data-integration-helper/references/cocoscreator_sdk_faq.md +123 -0
  63. package/skills/ae-data-integration-helper/references/cpp_server_sdk_faq.md +365 -0
  64. package/skills/ae-data-integration-helper/references/index.md +56 -0
  65. package/skills/ae-data-integration-helper/references/ios_sdk_faq.md +118 -0
  66. package/skills/ae-data-integration-helper/references/java_sdk_faq.md +406 -0
  67. package/skills/ae-data-integration-helper/references/javascript_sdk_faq.md +129 -0
  68. package/skills/ae-data-integration-helper/references/logbus2_guide.md +309 -0
  69. package/skills/ae-data-integration-helper/references/logbus2_parser_plugin.md +348 -0
  70. package/skills/ae-data-integration-helper/references/minigame_sdk_faq.md +115 -0
  71. package/skills/ae-data-integration-helper/references/miniprogram_sdk_faq.md +118 -0
  72. package/skills/ae-data-integration-helper/references/python_sdk_faq.md +232 -0
  73. package/skills/ae-data-integration-helper/references/restful_api_notes.md +74 -0
  74. package/skills/ae-data-integration-helper/references/sdk_log_guide.md +316 -0
  75. package/skills/ae-data-integration-helper/references/sdk_usage_notes.md +107 -0
  76. package/skills/ae-data-integration-helper/references/unity_sdk_faq.md +115 -0
  77. package/skills/ae-generate-tracking-code/SKILL.md +629 -0
  78. package/skills/ae-generate-tracking-code/references/autotrack-enum.md +183 -0
  79. package/skills/ae-generate-tracking-code/references/client-sdk-insert.md +202 -0
  80. package/skills/ae-generate-tracking-code/references/datax-config.md +43 -0
  81. package/skills/ae-generate-tracking-code/references/debug-script.md +102 -0
  82. package/skills/ae-generate-tracking-code/references/logbus-config.md +200 -0
  83. package/skills/ae-generate-tracking-code/references/modes.md +83 -0
  84. package/skills/ae-generate-tracking-code/references/restful-call.md +36 -0
  85. package/skills/ae-generate-tracking-code/references/sdk-index.md +128 -0
  86. package/skills/ae-generate-tracking-code/references/server-sdk-insert.md +206 -0
  87. package/skills/ae-generate-tracking-code/references/snippet-delivery.md +394 -0
  88. package/skills/ae-generate-tracking-code/references/te-api.md +181 -0
  89. package/skills/ae-generate-tracking-plan/SKILL.md +1083 -0
  90. package/skills/ae-generate-tracking-plan/references/autotrack-events.md +273 -0
  91. package/skills/ae-generate-tracking-plan/references/business-dimension-mapping.md +425 -0
  92. package/skills/ae-generate-tracking-plan/references/te-api.md +100 -0
  93. package/skills/ae-generate-tracking-plan/references/xlsx-schema.md +152 -0
  94. package/skills/ae-kb/SKILL.md +38 -5
  95. package/tracking-plan-template/MMO/346/211/213/346/270/270/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +104 -0
  96. package/tracking-plan-template/MMO/346/211/213/346/270/270/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  97. package/tracking-plan-template/MMO/351/241/265/346/270/270/345/237/213/347/202/271/346/250/241/346/235/277_v2.md +117 -0
  98. package/tracking-plan-template/MMO/351/241/265/346/270/270/345/237/213/347/202/271/346/250/241/346/235/277_v2.xlsx +0 -0
  99. package/tracking-plan-template/RPG/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +72 -0
  100. package/tracking-plan-template/RPG/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  101. package/tracking-plan-template/SLG/346/270/270/346/210/217/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +86 -0
  102. package/tracking-plan-template/SLG/346/270/270/346/210/217/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  103. package/tracking-plan-template/Slots/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +80 -0
  104. package/tracking-plan-template/Slots/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  105. package/tracking-plan-template/TE /345/237/213/347/202/271/347/244/272/344/276/213/346/250/241/346/235/277.md" +40 -0
  106. package/tracking-plan-template/TE /345/237/213/347/202/271/347/244/272/344/276/213/346/250/241/346/235/277.xlsx +0 -0
  107. package/tracking-plan-template/TE/345/256/230/346/226/271/346/250/241/346/235/277_dataTrackSample.md +40 -0
  108. package/tracking-plan-template/TE/345/256/230/346/226/271/346/250/241/346/235/277_dataTrackSample.xlsx +0 -0
  109. package/tracking-plan-template//344/274/221/351/227/262/345/205/273/346/210/220/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v2.md +92 -0
  110. package/tracking-plan-template//344/274/221/351/227/262/345/205/273/346/210/220/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v2.xlsx +0 -0
  111. package/tracking-plan-template//345/215/241/347/211/214/346/270/270/346/210/217/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +119 -0
  112. package/tracking-plan-template//345/215/241/347/211/214/346/270/270/346/210/217/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  113. package/tracking-plan-template//345/241/224/351/230/262/345/205/273/346/210/220/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_V1.md +130 -0
  114. package/tracking-plan-template//345/241/224/351/230/262/345/205/273/346/210/220/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_V1.xlsx +0 -0
  115. package/tracking-plan-template//345/276/256/344/277/241/345/260/217/346/270/270/346/210/217/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +52 -0
  116. package/tracking-plan-template//345/276/256/344/277/241/345/260/217/346/270/270/346/210/217/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  117. package/tracking-plan-template//346/215/225/351/261/274/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +68 -0
  118. package/tracking-plan-template//346/215/225/351/261/274/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  119. package/tracking-plan-template//346/224/276/347/275/256/347/261/273/345/215/241/347/211/214/346/270/270/346/210/217_/345/237/213/347/202/271/346/250/241/347/211/210v1.md +108 -0
  120. package/tracking-plan-template//346/224/276/347/275/256/347/261/273/345/215/241/347/211/214/346/270/270/346/210/217_/345/237/213/347/202/271/346/250/241/347/211/210v1.xlsx +0 -0
  121. package/tracking-plan-template//346/224/276/347/275/256/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +119 -0
  122. package/tracking-plan-template//346/224/276/347/275/256/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  123. package/tracking-plan-template//346/243/213/347/211/214/347/261/273/357/274/210/346/226/227/345/234/260/344/270/273/357/274/211/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +63 -0
  124. package/tracking-plan-template//346/243/213/347/211/214/347/261/273/357/274/210/346/226/227/345/234/260/344/270/273/357/274/211/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  125. package/tracking-plan-template//346/243/213/347/211/214/347/261/273/357/274/210/351/272/273/345/260/206/357/274/211/345/237/213/347/202/271/346/250/241/346/235/277_v2.md +101 -0
  126. package/tracking-plan-template//346/243/213/347/211/214/347/261/273/357/274/210/351/272/273/345/260/206/357/274/211/345/237/213/347/202/271/346/250/241/346/235/277_v2.xlsx +0 -0
  127. package/tracking-plan-template//347/224/265/345/225/206/345/237/213/347/202/271/346/226/271/346/241/210/346/250/241/346/235/277_v1.md +84 -0
  128. package/tracking-plan-template//347/224/265/345/225/206/345/237/213/347/202/271/346/226/271/346/241/210/346/250/241/346/235/277_v1.xlsx +0 -0
  129. package/tracking-plan-template//347/237/255/345/211/247/344/272/247/345/223/201/345/237/213/347/202/271/346/226/271/346/241/210/346/250/241/346/235/277_v1.md +79 -0
  130. package/tracking-plan-template//347/237/255/345/211/247/344/272/247/345/223/201/345/237/213/347/202/271/346/226/271/346/241/210/346/250/241/346/235/277_v1.xlsx +0 -0
  131. package/tracking-plan-template//347/244/276/344/272/244/350/201/212/345/244/251/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +105 -0
  132. package/tracking-plan-template//347/244/276/344/272/244/350/201/212/345/244/251/347/261/273/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  133. package/tracking-plan-template//351/230/205/350/257/273/347/261/273APP/345/237/213/347/202/271/346/250/241/346/235/277_v1.md +83 -0
  134. package/tracking-plan-template//351/230/205/350/257/273/347/261/273APP/345/237/213/347/202/271/346/250/241/346/235/277_v1.xlsx +0 -0
  135. package/wiki/te-docs/index.md +225 -0
  136. package/wiki/te-docs/raw/advanced-data-type/first-event-check.md +66 -0
  137. package/wiki/te-docs/raw/advanced-data-type/updated-event.md +87 -0
  138. package/wiki/te-docs/raw/advanced-data-type.md +16 -0
  139. package/wiki/te-docs/raw/data-ingestion-guide/about-gdpr.md +55 -0
  140. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/android-advanced/automatic-event-tracking.md +431 -0
  141. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/android-advanced/debugging-and-logging.md +49 -0
  142. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/android-advanced/multi-instance.md +66 -0
  143. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/android-advanced/preset-properties.md +466 -0
  144. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/android-advanced/third-party-integration.md +127 -0
  145. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/android-advanced.md +513 -0
  146. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/compliance.md +24 -0
  147. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android/release-notes.md +177 -0
  148. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/android.md +228 -0
  149. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/c/c-advanced.md +419 -0
  150. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/c/release-notes.md +45 -0
  151. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/c.md +110 -0
  152. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/client-side-sdk-faq.md +52 -0
  153. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cpp/cpp-advanced.md +366 -0
  154. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cpp/release-notes.md +103 -0
  155. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cpp.md +201 -0
  156. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter/compliance.md +26 -0
  157. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter/flutter-advanced/automatically-track-events.md +117 -0
  158. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter/flutter-advanced/debugging-and-logging.md +47 -0
  159. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter/flutter-advanced/preset-properties.md +52 -0
  160. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter/flutter-advanced.md +267 -0
  161. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter/release-notes.md +82 -0
  162. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/flutter.md +139 -0
  163. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native/compliance.md +26 -0
  164. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native/reactnative-advanced/automatically-track-events.md +121 -0
  165. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native/reactnative-advanced/debugging-and-logging.md +54 -0
  166. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native/reactnative-advanced/preset-properties.md +18 -0
  167. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native/reactnative-advanced.md +305 -0
  168. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native/release-notes.md +79 -0
  169. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/react-native.md +137 -0
  170. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/release-notes.md +24 -0
  171. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/uniapp-advanced/automatically-track-events.md +54 -0
  172. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/uniapp-advanced/debugging-and-logging.md +53 -0
  173. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/uniapp-advanced/multi-instance.md +42 -0
  174. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/uniapp-advanced/preset-properties.md +119 -0
  175. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/uniapp-advanced/support-native.md +81 -0
  176. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app/uniapp-advanced.md +331 -0
  177. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform/uni-app.md +156 -0
  178. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/cross-platform.md +12 -0
  179. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/cocos2d-x-advanced/automatic-event-tracking.md +29 -0
  180. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/cocos2d-x-advanced/debugging-and-logging.md +47 -0
  181. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/cocos2d-x-advanced/multi-instance.md +21 -0
  182. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/cocos2d-x-advanced/preset-properties.md +249 -0
  183. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/cocos2d-x-advanced.md +301 -0
  184. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/compliance.md +24 -0
  185. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x/release-notes.md +51 -0
  186. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocos2d-x.md +281 -0
  187. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/cocoscreator-advance/automatic-event-tracking.md +70 -0
  188. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/cocoscreator-advance/debugging-and-logging.md +57 -0
  189. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/cocoscreator-advance/native-support.md +104 -0
  190. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/cocoscreator-advance/preset-properties.md +91 -0
  191. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/cocoscreator-advance.md +374 -0
  192. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/compliance.md +35 -0
  193. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator/release-notes.md +109 -0
  194. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/cocoscreator.md +170 -0
  195. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona/compliance.md +28 -0
  196. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona/corona-advanced/automatic-event-tracking.md +29 -0
  197. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona/corona-advanced/debugging-and-logging.md +58 -0
  198. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona/corona-advanced/preset-properties.md +43 -0
  199. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona/corona-advanced.md +204 -0
  200. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona/release-notes.md +29 -0
  201. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/corona.md +269 -0
  202. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/compliance.md +24 -0
  203. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/release-notes.md +177 -0
  204. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced/automatic-event-tracking.md +119 -0
  205. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced/debugging-and-logging.md +47 -0
  206. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced/multi-instance.md +50 -0
  207. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced/native-pluggable.md +43 -0
  208. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced/preset-properties.md +212 -0
  209. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced/third-party-integration.md +77 -0
  210. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity/unity-advanced.md +396 -0
  211. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unity.md +176 -0
  212. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/compliance.md +24 -0
  213. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/release-notes.md +81 -0
  214. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/unreal-advanced/automatic-event-tracking.md +79 -0
  215. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/unreal-advanced/debugging-and-logging.md +31 -0
  216. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/unreal-advanced/preset-properties.md +25 -0
  217. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/unreal-advanced/third-party-integrations.md +141 -0
  218. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal/unreal-advanced.md +278 -0
  219. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine/unreal.md +190 -0
  220. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/game-engine.md +14 -0
  221. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/h5-and-app-sdk-connection.md +147 -0
  222. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/instant-app-and-game.md +24 -0
  223. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/compliance.md +24 -0
  224. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/ios-advanced/automatic-event-tracking.md +272 -0
  225. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/ios-advanced/debugging-and-logging.md +77 -0
  226. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/ios-advanced/multi-instance.md +142 -0
  227. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/ios-advanced/preset-properties.md +484 -0
  228. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/ios-advanced/third-party-integrations.md +132 -0
  229. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/ios-advanced.md +682 -0
  230. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios/release-notes.md +163 -0
  231. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/ios.md +304 -0
  232. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/compliance.md +29 -0
  233. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/javascript-advanced/automatic-event-tracking.md +136 -0
  234. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/javascript-advanced/debugging-and-logging.md +48 -0
  235. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/javascript-advanced/multi-instance.md +50 -0
  236. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/javascript-advanced/preset-properties.md +132 -0
  237. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/javascript-advanced.md +462 -0
  238. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript/release-notes.md +107 -0
  239. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/javascript.md +208 -0
  240. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/macos/macos-advanced/debugging-and-logging.md +62 -0
  241. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/macos/macos-advanced/preset-properties.md +118 -0
  242. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/macos/macos-advanced.md +556 -0
  243. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk/macos.md +231 -0
  244. package/wiki/te-docs/raw/data-ingestion-guide/client-sdk.md +25 -0
  245. package/wiki/te-docs/raw/data-ingestion-guide/data-import-tools/filebeat-logstash-user-guide.md +610 -0
  246. package/wiki/te-docs/raw/data-ingestion-guide/data-import-tools/logbus2-user-guide.md +1215 -0
  247. package/wiki/te-docs/raw/data-ingestion-guide/data-import-tools/ta-datax-writer-plugin-user-guide.md +278 -0
  248. package/wiki/te-docs/raw/data-ingestion-guide/data-import-tools.md +15 -0
  249. package/wiki/te-docs/raw/data-ingestion-guide/privacy-policy.md +38 -0
  250. package/wiki/te-docs/raw/data-ingestion-guide/restful-api-user-guide.md +155 -0
  251. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced/debugging-and-logging-FM9Cwz.md +37 -0
  252. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced/debugging-and-logging-RSyfw7.md +41 -0
  253. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced/debugging-and-logging.md +89 -0
  254. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced/preset-properties-OxzWw.md +126 -0
  255. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced/preset-properties-VuE3wr.md +126 -0
  256. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced/preset-properties.md +126 -0
  257. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced-IauKwI.md +175 -0
  258. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced-YAilwk.md +210 -0
  259. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/c-advanced.md +211 -0
  260. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/release-notes-PVazwa.md +62 -0
  261. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/release-notes-TADbwY.md +50 -0
  262. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c/release-notes.md +69 -0
  263. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c-V2W3wv.md +131 -0
  264. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c-Zf9Jwl.md +179 -0
  265. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/c.md +189 -0
  266. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/erlang/erlang-advanced/debugging-and-logging.md +38 -0
  267. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/erlang/erlang-advanced/preset-properties.md +126 -0
  268. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/erlang/erlang-advanced.md +113 -0
  269. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/erlang/release-notes.md +34 -0
  270. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/erlang.md +155 -0
  271. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/golang/golang-advanced/debugging-and-logging.md +42 -0
  272. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/golang/golang-advanced/preset-properties.md +126 -0
  273. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/golang/golang-advanced.md +157 -0
  274. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/golang/release-notes.md +72 -0
  275. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/golang.md +148 -0
  276. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/java/java-advanced/debugging-and-logging.md +49 -0
  277. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/java/java-advanced/preset-properties.md +126 -0
  278. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/java/java-advanced.md +223 -0
  279. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/java/release-notes.md +88 -0
  280. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/java.md +174 -0
  281. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/lua/lua-advanced/debugging-and-logging.md +46 -0
  282. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/lua/lua-advanced/preset-properties.md +126 -0
  283. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/lua/lua-advanced.md +182 -0
  284. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/lua/release-notes.md +61 -0
  285. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/lua.md +121 -0
  286. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/nodejs/nodejs-advanced/debugging-and-logging.md +55 -0
  287. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/nodejs/nodejs-advanced/preset-properties.md +126 -0
  288. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/nodejs/nodejs-advanced.md +225 -0
  289. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/nodejs/release-notes.md +45 -0
  290. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/nodejs.md +141 -0
  291. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/php/php-advanced/debugging-and-logging.md +41 -0
  292. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/php/php-advanced/preset-properties.md +126 -0
  293. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/php/php-advanced.md +216 -0
  294. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/php/release-notes.md +45 -0
  295. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/php.md +173 -0
  296. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/python/python-advanced/debugging-and-logging.md +40 -0
  297. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/python/python-advanced/preset-properties.md +126 -0
  298. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/python/python-advanced.md +206 -0
  299. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/python/release-notes.md +51 -0
  300. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/python.md +116 -0
  301. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/ruby/release-notes.md +44 -0
  302. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/ruby/ruby-advanced/debugging-and-logging.md +47 -0
  303. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/ruby/ruby-advanced/preset-properties.md +126 -0
  304. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/ruby/ruby-advanced.md +189 -0
  305. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk/ruby.md +142 -0
  306. package/wiki/te-docs/raw/data-ingestion-guide/server-sdk.md +22 -0
  307. package/wiki/te-docs/raw/data-ingestion-guide/thinkingdata-privacy-policy.md +37 -0
  308. package/wiki/te-docs/raw/data-ingestion-guide.md +48 -0
  309. package/wiki/te-docs/raw/preparations-before-data-ingestion/data-rules.md +396 -0
  310. package/wiki/te-docs/raw/preparations-before-data-ingestion/preset-properties-and-system-fields.md +957 -0
  311. package/wiki/te-docs/raw/preparations-before-data-ingestion/user-identification-rules.md +723 -0
  312. package/wiki/te-docs/raw/preparations-before-data-ingestion.md +203 -0
  313. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony//345/220/210/350/247/204/346/214/207/345/215/227.md +96 -0
  314. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony//346/233/264/346/226/260/346/227/245/345/277/227.md +97 -0
  315. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony//350/277/233/351/230/266/346/214/207/345/215/227//345/244/232/345/256/236/344/276/213.md +52 -0
  316. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony//350/277/233/351/230/266/346/214/207/345/215/227//345/256/236/346/227/266/350/260/203/350/257/225.md +48 -0
  317. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony//350/277/233/351/230/266/346/214/207/345/215/227//351/242/204/347/275/256/345/261/236/346/200/247.md +447 -0
  318. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony//350/277/233/351/230/266/346/214/207/345/215/227.md +370 -0
  319. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk/openharmony.md +172 -0
  320. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//345/220/210/350/247/204/346/214/207/345/215/227.md +37 -0
  321. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//346/233/264/346/226/260/346/227/245/345/277/227.md +209 -0
  322. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//350/277/233/351/230/266/346/214/207/345/215/227//345/244/232/345/256/236/344/276/213.md +71 -0
  323. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//350/277/233/351/230/266/346/214/207/345/215/227//345/256/236/346/227/266/350/260/203/350/257/225.md +49 -0
  324. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//350/277/233/351/230/266/346/214/207/345/215/227//350/207/252/345/212/250/351/207/207/351/233/206.md +125 -0
  325. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//350/277/233/351/230/266/346/214/207/345/215/227//351/242/204/347/275/256/345/261/236/346/200/247.md +498 -0
  326. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217//350/277/233/351/230/266/346/214/207/345/215/227.md +612 -0
  327. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//345/260/217/347/250/213/345/272/217/345/260/217/346/270/270/346/210/217.md +373 -0
  328. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua//345/220/210/350/247/204/346/214/207/345/215/227.md +26 -0
  329. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua//346/233/264/346/226/260/346/227/245/345/277/227.md +32 -0
  330. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua//350/277/233/351/230/266/346/214/207/345/215/227//345/256/236/346/227/266/350/260/203/350/257/225.md +48 -0
  331. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua//350/277/233/351/230/266/346/214/207/345/215/227//350/207/252/345/212/250/351/207/207/351/233/206.md +30 -0
  332. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua//350/277/233/351/230/266/346/214/207/345/215/227//351/242/204/347/275/256/345/261/236/346/200/247.md +61 -0
  333. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua//350/277/233/351/230/266/346/214/207/345/215/227.md +236 -0
  334. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/cocos2d-lua.md +200 -0
  335. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret//346/233/264/346/226/260/346/227/245/345/277/227.md +83 -0
  336. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret//350/277/233/351/230/266/346/214/207/345/215/227/native/346/224/257/346/214/201.md +66 -0
  337. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret//350/277/233/351/230/266/346/214/207/345/215/227//345/256/236/346/227/266/350/260/203/350/257/225.md +54 -0
  338. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret//350/277/233/351/230/266/346/214/207/345/215/227//350/207/252/345/212/250/351/207/207/351/233/206.md +62 -0
  339. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret//350/277/233/351/230/266/346/214/207/345/215/227//351/242/204/347/275/256/345/261/236/346/200/247.md +358 -0
  340. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret//350/277/233/351/230/266/346/214/207/345/215/227.md +615 -0
  341. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/egret.md +166 -0
  342. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair//346/233/264/346/226/260/346/227/245/345/277/227.md +87 -0
  343. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair//350/277/233/351/230/266/346/214/207/345/215/227/native/346/224/257/346/214/201.md +71 -0
  344. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair//350/277/233/351/230/266/346/214/207/345/215/227//345/256/236/346/227/266/350/260/203/350/257/225.md +54 -0
  345. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair//350/277/233/351/230/266/346/214/207/345/215/227//350/207/252/345/212/250/351/207/207/351/233/206.md +61 -0
  346. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair//350/277/233/351/230/266/346/214/207/345/215/227//351/242/204/347/275/256/345/261/236/346/200/247.md +406 -0
  347. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair//350/277/233/351/230/266/346/214/207/345/215/227.md +597 -0
  348. package/wiki/te-docs/raw//345/256/242/346/210/267/347/253/257-sdk//346/270/270/346/210/217/345/274/225/346/223/216/layaair.md +179 -0
  349. package/wiki/te-docs/schema.md +16 -0
  350. package/wiki/te-docs/synthesis/batch-ingest-comparison.md +324 -0
  351. package/wiki/te-docs/synthesis/js-sdk-cheatsheet.md +538 -0
  352. package/wiki/te-docs/synthesis/restful-api-reference.md +363 -0
  353. package/wiki/te-docs/synthesis/sdk-selection.md +372 -0
  354. package/wiki/te-docs/synthesis/server-sdk-overview.md +449 -0
  355. package/dist/chunk-U6TKB3IV.js +0 -171
package/dist/index.js CHANGED
@@ -1,22 +1,28 @@
1
1
  import {
2
2
  TeAgentApiError,
3
3
  TeAgentCredentialsError
4
- } from "./chunk-VJFUB3H3.js";
4
+ } from "./chunk-I5CRVM2S.js";
5
5
  import {
6
6
  printError,
7
7
  printOutput
8
- } from "./chunk-CLJF7MQA.js";
8
+ } from "./chunk-2DUEAXV3.js";
9
+ import {
10
+ httpGet
11
+ } from "./chunk-BJX3GXWC.js";
9
12
  import {
10
13
  PermissionError
11
14
  } from "./chunk-NOO24N7W.js";
12
15
  import {
13
- SecureStoreAuthError
14
- } from "./chunk-JM34JPCO.js";
16
+ SecureStoreAuthError,
17
+ getToken,
18
+ resolveHost
19
+ } from "./chunk-RSHMZ3LG.js";
15
20
  import {
16
21
  getActiveHost,
22
+ getConfigDir,
17
23
  logger,
18
24
  safeJsonParse
19
- } from "./chunk-SRJIAOBN.js";
25
+ } from "./chunk-6W4QOZAL.js";
20
26
 
21
27
  // src/index.ts
22
28
  import { Command as CommanderCommand } from "commander";
@@ -41,6 +47,20 @@ async function runCommand(cmd, opts, globalOpts) {
41
47
  if (cmd.validate) {
42
48
  cmd.validate(ctx);
43
49
  }
50
+ const LIMIT_FLAG_PATTERNS = [/limit/i, /page_size/i, /pagesize/i, /row_limit/i, /block_limit/i, /top[-_]?k/i];
51
+ for (const flag of cmd.flags) {
52
+ const isLimitFlag = LIMIT_FLAG_PATTERNS.some((p) => p.test(flag.name));
53
+ if (isLimitFlag && flag.type === "number") {
54
+ const val = opts[camelCase(flag.name)];
55
+ if (val !== void 0 && val !== null) {
56
+ const num = Number(val);
57
+ if (!Number.isInteger(num) || num < 1 || num > 1e4) {
58
+ printError("validation", `--${flag.name} must be an integer between 1 and 10000 (got: ${val})`);
59
+ process.exit(1);
60
+ }
61
+ }
62
+ }
63
+ }
44
64
  if (globalOpts.dryRun) {
45
65
  if (cmd.dryRun) {
46
66
  const dryResult = cmd.dryRun(ctx);
@@ -93,7 +113,7 @@ function createRuntimeContext(cmd, opts, globalOpts) {
93
113
  let _clientModule = null;
94
114
  async function getClient() {
95
115
  if (!_clientModule) {
96
- _clientModule = await import("./client-IN42F223.js");
116
+ _clientModule = await import("./client-2UJ63MVQ.js");
97
117
  }
98
118
  return _clientModule;
99
119
  }
@@ -119,12 +139,12 @@ function createRuntimeContext(cmd, opts, globalOpts) {
119
139
  process.exit(1);
120
140
  }
121
141
  },
122
- async api(method, path2, params, data) {
142
+ async api(method, path5, params, data) {
123
143
  const client = await getClient();
124
144
  if (method.toUpperCase() === "GET") {
125
- return client.httpGet(path2, params, ctx.host());
145
+ return client.httpGet(path5, params, ctx.host());
126
146
  } else {
127
- return client.httpRequest(method, path2, params, data, ctx.host());
147
+ return client.httpRequest(method, path5, params, data, ctx.host());
128
148
  }
129
149
  },
130
150
  async querySql(projectId, sql) {
@@ -136,8 +156,8 @@ function createRuntimeContext(cmd, opts, globalOpts) {
136
156
  return client.queryReportData(projectId, reportId, qp, eventModel, options, ctx.host());
137
157
  },
138
158
  async token() {
139
- const { getToken } = await import("./auth-U25QJU5D.js");
140
- return getToken(ctx.host());
159
+ const { getToken: getToken2 } = await import("./auth-DYC2BGLM.js");
160
+ return getToken2(ctx.host());
141
161
  },
142
162
  host() {
143
163
  if (globalOpts.host) return globalOpts.host;
@@ -160,10 +180,10 @@ function camelCase(str) {
160
180
  }
161
181
  async function confirm(message) {
162
182
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
163
- return new Promise((resolve) => {
183
+ return new Promise((resolve2) => {
164
184
  rl.question(`${message} [y/N] `, (answer) => {
165
185
  rl.close();
166
- resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
186
+ resolve2(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
167
187
  });
168
188
  });
169
189
  }
@@ -376,6 +396,2483 @@ function notifyIfUpdateAvailable(pkg2) {
376
396
  });
377
397
  }
378
398
 
399
+ // src/commands/tracking/plan.ts
400
+ import { readFile, writeFile, cp } from "fs/promises";
401
+ import path3, { resolve } from "path";
402
+
403
+ // src/tracking/xlsx/write.ts
404
+ import ExcelJS from "exceljs";
405
+
406
+ // src/tracking/i18n/locale.ts
407
+ var VALID_LOCALES = /* @__PURE__ */ new Set(["zh", "en", "ja", "ko"]);
408
+ function normalize(raw) {
409
+ const lower = raw.trim().toLowerCase();
410
+ if (lower.startsWith("zh") || lower.startsWith("cn")) return "zh";
411
+ if (lower.startsWith("ja") || lower.startsWith("jp")) return "ja";
412
+ if (lower.startsWith("ko") || lower.startsWith("kr")) return "ko";
413
+ if (lower.startsWith("en")) return "en";
414
+ if (VALID_LOCALES.has(lower)) return lower;
415
+ return "en";
416
+ }
417
+ var _cliLocale;
418
+ function detectCliLocale() {
419
+ if (_cliLocale) return _cliLocale;
420
+ if (process.env.AE_LANG) {
421
+ _cliLocale = normalize(process.env.AE_LANG);
422
+ return _cliLocale;
423
+ }
424
+ const sys = (process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || "").toLowerCase();
425
+ if (sys) {
426
+ _cliLocale = normalize(sys);
427
+ return _cliLocale;
428
+ }
429
+ _cliLocale = "en";
430
+ return _cliLocale;
431
+ }
432
+
433
+ // src/tracking/i18n/resources/xlsx/sheets.ts
434
+ var SHEET_NAMES = {
435
+ event_data: {
436
+ zh: "#\u4E8B\u4EF6\u6570\u636E",
437
+ en: "#event data",
438
+ ja: "#\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF",
439
+ ko: "#\uC774\uBCA4\uD2B8 \uB370\uC774\uD130"
440
+ },
441
+ common_props: {
442
+ zh: "#\u516C\u5171\u4E8B\u4EF6\u5C5E\u6027",
443
+ en: "#super property",
444
+ ja: "#\u30D1\u30D6\u30EA\u30C3\u30AF\u30A4\u30D9\u30F3\u30C8\u30D7\u30ED\u30D1\u30C6\u30A3",
445
+ ko: "#\uACF5\uD1B5 \uC774\uBCA4\uD2B8 \uC18D\uC131"
446
+ },
447
+ user_data: {
448
+ zh: "#\u7528\u6237\u6570\u636E",
449
+ en: "#user data",
450
+ ja: "#\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF",
451
+ ko: "#\uC720\uC800 \uB370\uC774\uD130"
452
+ },
453
+ user_id: {
454
+ zh: "#\u7528\u6237ID\u4F53\u7CFB",
455
+ en: "#ID mapping rule",
456
+ ja: "#\u30E6\u30FC\u30B6\u30FCID\u30B7\u30B9\u30C6\u30E0",
457
+ ko: "#\uC720\uC800 ID \uCCB4\uACC4"
458
+ }
459
+ };
460
+ function sheetName(key, locale) {
461
+ return SHEET_NAMES[key][locale];
462
+ }
463
+ function allSheetNames(key) {
464
+ return Object.values(SHEET_NAMES[key]);
465
+ }
466
+
467
+ // src/tracking/i18n/resources/xlsx/headers.ts
468
+ var HEADERS = {
469
+ // === #事件数据 (9 列) ===
470
+ event_name: {
471
+ zh: "\u4E8B\u4EF6\u540D\uFF08\u5FC5\u586B\uFF09",
472
+ en: "Event Name",
473
+ ja: "\u30A4\u30D9\u30F3\u30C8\u540D\uFF08\u5FC5\u9808\uFF09",
474
+ ko: "\uC774\uBCA4\uD2B8 \uC774\uB984 (\uD544\uC218)"
475
+ },
476
+ event_display_name: {
477
+ zh: "\u4E8B\u4EF6\u663E\u793A\u540D",
478
+ en: "Event Display Name",
479
+ ja: "\u30A4\u30D9\u30F3\u30C8\u8868\u793A\u540D",
480
+ ko: "\uC774\uBCA4\uD2B8 \uD45C\uC2DC \uC774\uB984"
481
+ },
482
+ event_desc: {
483
+ zh: "\u4E8B\u4EF6\u8BF4\u660E",
484
+ en: "Event Description",
485
+ ja: "\u30A4\u30D9\u30F3\u30C8\u8AAC\u660E",
486
+ ko: "\uC774\uBCA4\uD2B8 \uC124\uBA85"
487
+ },
488
+ event_tag: {
489
+ zh: "\u4E8B\u4EF6\u6807\u7B7E",
490
+ en: "Event Tag",
491
+ ja: "\u30AB\u30C6\u30B4\u30EA",
492
+ ko: "\uC774\uBCA4\uD2B8 \uD0DC\uADF8"
493
+ },
494
+ platform: {
495
+ zh: "\u91C7\u96C6\u7AEF",
496
+ en: "Platform",
497
+ ja: "\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0",
498
+ ko: "\uD50C\uB7AB\uD3FC"
499
+ },
500
+ prop_name: {
501
+ zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
502
+ en: "Property Name",
503
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
504
+ ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
505
+ },
506
+ prop_display_name: {
507
+ zh: "\u5C5E\u6027\u663E\u793A\u540D",
508
+ en: "Property Display Name",
509
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
510
+ ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
511
+ },
512
+ prop_type: {
513
+ zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
514
+ en: "Data Type",
515
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
516
+ ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
517
+ },
518
+ prop_desc: {
519
+ zh: "\u5C5E\u6027\u8BF4\u660E",
520
+ en: "Property Description",
521
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
522
+ ko: "\uC18D\uC131 \uC124\uBA85"
523
+ },
524
+ // === #公共事件属性 (4 列) ===
525
+ common_prop_name: {
526
+ zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
527
+ en: "Property Name",
528
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
529
+ ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
530
+ },
531
+ common_prop_display_name: {
532
+ zh: "\u5C5E\u6027\u663E\u793A\u540D",
533
+ en: "Property Display Name",
534
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
535
+ ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
536
+ },
537
+ common_prop_type: {
538
+ zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
539
+ en: "Data Type",
540
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
541
+ ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
542
+ },
543
+ common_prop_desc: {
544
+ zh: "\u5C5E\u6027\u8BF4\u660E",
545
+ en: "Property Description",
546
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
547
+ ko: "\uC18D\uC131 \uC124\uBA85"
548
+ },
549
+ // === #用户数据 (6 列) ===
550
+ user_prop_name: {
551
+ zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
552
+ en: "Property Name",
553
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
554
+ ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
555
+ },
556
+ user_prop_display_name: {
557
+ zh: "\u5C5E\u6027\u663E\u793A\u540D",
558
+ en: "Property Display Name",
559
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
560
+ ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
561
+ },
562
+ user_prop_type: {
563
+ zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
564
+ en: "Data Type",
565
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
566
+ ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
567
+ },
568
+ update_type: {
569
+ zh: "\u66F4\u65B0\u65B9\u5F0F",
570
+ en: "Update Type",
571
+ ja: "\u66F4\u65B0\u65B9\u6CD5",
572
+ ko: "\uC5C5\uB370\uC774\uD2B8 \uBC29\uC2DD"
573
+ },
574
+ user_prop_desc: {
575
+ zh: "\u5C5E\u6027\u8BF4\u660E",
576
+ en: "Property Description",
577
+ ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
578
+ ko: "\uC18D\uC131 \uC124\uBA85"
579
+ },
580
+ prop_tag: {
581
+ zh: "\u5C5E\u6027\u6807\u7B7E",
582
+ en: "Property Tag",
583
+ ja: "\u30AB\u30C6\u30B4\u30EA",
584
+ ko: "\uC18D\uC131 \uD0DC\uADF8"
585
+ },
586
+ // === #用户ID体系 (4 列,不含"游戏类型"前置列) ===
587
+ user_id_prop_name: {
588
+ zh: "\u5C5E\u6027\u540D",
589
+ en: "Property",
590
+ ja: "\u5C5E\u6027\u540D",
591
+ ko: "\uC18D\uC131 \uC774\uB984"
592
+ },
593
+ user_id_display_name: {
594
+ zh: "\u5C5E\u6027\u663E\u793A\u540D",
595
+ en: "Display Name",
596
+ ja: "\u5C5E\u6027\u8868\u793A\u540D",
597
+ ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
598
+ },
599
+ user_id_desc: {
600
+ zh: "\u5C5E\u6027\u8BF4\u660E",
601
+ en: "Description",
602
+ ja: "\u5C5E\u6027\u8AAC\u660E",
603
+ ko: "\uC18D\uC131 \uC124\uBA85"
604
+ },
605
+ user_id_value_desc: {
606
+ zh: "\u8D4B\u503C\u8BF4\u660E",
607
+ en: "Value Description",
608
+ ja: "\u4EE3\u5165\u8AAC\u660E",
609
+ ko: "\uAC12 \uC124\uBA85"
610
+ }
611
+ };
612
+ function headerName(key, locale) {
613
+ return HEADERS[key][locale];
614
+ }
615
+ function allHeaderNames(key) {
616
+ return Object.values(HEADERS[key]);
617
+ }
618
+
619
+ // src/tracking/i18n/resources/xlsx/types.ts
620
+ var PROP_TYPE_DISPLAY = {
621
+ string: { zh: "\u6587\u672C", en: "string", ja: "\u30B9\u30C8\u30EA\u30F3\u30B0", ko: "string" },
622
+ number: { zh: "\u6570\u503C", en: "number", ja: "\u6570\u5024", ko: "number" },
623
+ bool: { zh: "\u5E03\u5C14", en: "boolean", ja: "\u30D6\u30FC\u30EB\u5024", ko: "boolean" },
624
+ datetime: { zh: "\u65F6\u95F4", en: "datetime", ja: "\u6642\u9593", ko: "time" },
625
+ object: { zh: "\u5BF9\u8C61", en: "object", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8", ko: "object" },
626
+ array_row: { zh: "\u5BF9\u8C61\u7EC4", en: "object[]", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u914D\u5217", ko: "object_array" },
627
+ array_string: { zh: "\u5217\u8868", en: "string[]", ja: "\u914D\u5217", ko: "string_array" }
628
+ };
629
+ function typeToDisplay(type, locale) {
630
+ return PROP_TYPE_DISPLAY[type][locale];
631
+ }
632
+ var ALL_DISPLAY_TO_TYPE = {};
633
+ for (const [canonical, locales] of Object.entries(PROP_TYPE_DISPLAY)) {
634
+ for (const val of Object.values(locales)) {
635
+ ALL_DISPLAY_TO_TYPE[val] = canonical;
636
+ }
637
+ }
638
+ var ALIASES = {
639
+ // zh alias(行业模板)
640
+ "\u5B57\u7B26\u4E32": "string",
641
+ "\u5BF9\u8C61": "object",
642
+ // en alias
643
+ "String": "string",
644
+ "Number": "number",
645
+ "Boolean": "bool",
646
+ "Bool": "bool",
647
+ "DateTime": "datetime",
648
+ "Time": "datetime",
649
+ "Object": "object",
650
+ "Row": "object",
651
+ "Object Array": "array_row",
652
+ "List": "array_string",
653
+ "String Array": "array_string",
654
+ // ja alias
655
+ "\u6587\u5B57\u5217": "string",
656
+ "\u30C6\u30AD\u30B9\u30C8": "string",
657
+ "\u30D6\u30FC\u30EB": "bool",
658
+ "\u65E5\u6642": "datetime",
659
+ // ko alias
660
+ "\uD14D\uC2A4\uD2B8": "string",
661
+ "\uBB38\uC790\uC5F4": "string",
662
+ "\uC22B\uC790": "number",
663
+ "\uBD80\uC6B8": "bool",
664
+ "\uB0A0\uC9DC\uC2DC\uAC04": "datetime",
665
+ "\uAC1D\uCCB4 \uBC30\uC5F4": "array_row",
666
+ "\uB9AC\uC2A4\uD2B8": "array_string"
667
+ };
668
+ Object.assign(ALL_DISPLAY_TO_TYPE, ALIASES);
669
+ function displayToType(raw) {
670
+ const trimmed = raw.trim();
671
+ return ALL_DISPLAY_TO_TYPE[trimmed] ?? null;
672
+ }
673
+
674
+ // src/tracking/i18n/translate.ts
675
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
676
+ import { join as join2 } from "path";
677
+
678
+ // src/tracking/paths.ts
679
+ import { existsSync, readFileSync } from "fs";
680
+ import { dirname, join } from "path";
681
+ import { fileURLToPath } from "url";
682
+ function getPackageRoot() {
683
+ let cur = dirname(fileURLToPath(import.meta.url));
684
+ while (cur !== dirname(cur)) {
685
+ const pj = join(cur, "package.json");
686
+ if (existsSync(pj)) {
687
+ try {
688
+ const pkg2 = JSON.parse(readFileSync(pj, "utf8"));
689
+ if (pkg2.name === "@tant/ae-cli") return cur;
690
+ } catch {
691
+ }
692
+ }
693
+ cur = dirname(cur);
694
+ }
695
+ throw new Error("Could not locate ae-cli package root");
696
+ }
697
+
698
+ // src/tracking/i18n/translate.ts
699
+ var loaded = /* @__PURE__ */ new Map();
700
+ function i18nFile(locale) {
701
+ const root = getPackageRoot();
702
+ const candidates = [
703
+ join2(root, "dist", "tracking", "i18n", "resources", "cli", `${locale}.json`),
704
+ join2(root, "src", "tracking", "i18n", "resources", "cli", `${locale}.json`)
705
+ ];
706
+ for (const p of candidates) {
707
+ if (existsSync2(p)) return p;
708
+ }
709
+ return candidates[candidates.length - 1];
710
+ }
711
+ function loadSync(locale) {
712
+ if (loaded.has(locale)) return loaded.get(locale);
713
+ try {
714
+ const raw = readFileSync2(i18nFile(locale), "utf8");
715
+ const tree = JSON.parse(raw);
716
+ loaded.set(locale, tree);
717
+ return tree;
718
+ } catch {
719
+ if (locale !== "en") {
720
+ return loadSync("en");
721
+ }
722
+ loaded.set("en", {});
723
+ return {};
724
+ }
725
+ }
726
+ function t(key, params, locale) {
727
+ const loc = locale ?? detectCliLocale();
728
+ const tree = loadSync(loc);
729
+ const parts = key.split(".");
730
+ let node = tree;
731
+ for (const part of parts) {
732
+ if (typeof node !== "object" || node === null) return key;
733
+ node = node[part];
734
+ }
735
+ if (typeof node !== "string") return key;
736
+ if (params) {
737
+ return node.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? `{${name}}`));
738
+ }
739
+ return node;
740
+ }
741
+
742
+ // src/tracking/xlsx/write.ts
743
+ var PLATFORM_TO_XLSX = {
744
+ "client": "client",
745
+ "server": "server",
746
+ "both": "client,server"
747
+ };
748
+ var VALID_PROP_TYPES = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
749
+ var VALID_UPDATE_TYPES = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
750
+ var SNAKE_CASE_RE = /^[a-z][a-z0-9_]*$/;
751
+ var PROP_NAME_RE = /^[a-zA-Z#][a-zA-Z0-9_.]*$/;
752
+ function validateDraft(d) {
753
+ const errors = [];
754
+ const eventNames = /* @__PURE__ */ new Set();
755
+ for (const evt of d.events) {
756
+ if (!SNAKE_CASE_RE.test(evt.event_name)) {
757
+ errors.push(`Event name "${evt.event_name}" does not match snake_case pattern`);
758
+ }
759
+ if (eventNames.has(evt.event_name)) {
760
+ errors.push(`Duplicate event_name: "${evt.event_name}"`);
761
+ }
762
+ eventNames.add(evt.event_name);
763
+ }
764
+ const eventProps = d.event_properties ?? d.common_properties ?? [];
765
+ const eventPropNames = /* @__PURE__ */ new Set();
766
+ const compositeProps = new Set(
767
+ eventProps.filter((p) => p.type === "array_row" || p.type === "object").map((p) => p.name)
768
+ );
769
+ for (const prop of eventProps) {
770
+ if (!PROP_NAME_RE.test(prop.name)) {
771
+ errors.push(`Event property name "${prop.name}" has invalid characters`);
772
+ }
773
+ if (prop.name.includes(".")) {
774
+ const parent = prop.name.split(".")[0];
775
+ if (!compositeProps.has(parent)) {
776
+ errors.push(`Nested property "${prop.name}" references non-composite parent "${parent}"`);
777
+ }
778
+ }
779
+ if (!VALID_PROP_TYPES.has(prop.type)) {
780
+ errors.push(`Event property "${prop.name}" has invalid type: "${prop.type}"`);
781
+ }
782
+ if (eventPropNames.has(prop.name)) {
783
+ errors.push(`Duplicate event property name: "${prop.name}"`);
784
+ }
785
+ eventPropNames.add(prop.name);
786
+ }
787
+ const commonProps = d.common_event_properties ?? d.common_properties ?? [];
788
+ const commonPropNames = /* @__PURE__ */ new Set();
789
+ for (const prop of commonProps) {
790
+ if (!VALID_PROP_TYPES.has(prop.type)) {
791
+ errors.push(`Common event property "${prop.name}" has invalid type: "${prop.type}"`);
792
+ }
793
+ if (commonPropNames.has(prop.name)) {
794
+ errors.push(`Duplicate common event property name: "${prop.name}"`);
795
+ }
796
+ commonPropNames.add(prop.name);
797
+ }
798
+ const userPropNames = /* @__PURE__ */ new Set();
799
+ for (const prop of d.user_properties) {
800
+ if (!VALID_PROP_TYPES.has(prop.type)) {
801
+ errors.push(`User property "${prop.name}" has invalid type: "${prop.type}"`);
802
+ }
803
+ if (prop.update_type && !VALID_UPDATE_TYPES.has(prop.update_type)) {
804
+ errors.push(`User property "${prop.name}" has invalid update_type: "${prop.update_type}"`);
805
+ }
806
+ if (userPropNames.has(prop.name)) {
807
+ errors.push(`Duplicate user property name: "${prop.name}"`);
808
+ }
809
+ userPropNames.add(prop.name);
810
+ }
811
+ for (const evt of d.events) {
812
+ if (!evt.prop_names) continue;
813
+ for (const propName of evt.prop_names) {
814
+ if (propName.startsWith("#")) continue;
815
+ if (!eventPropNames.has(propName)) {
816
+ errors.push(`Event "${evt.event_name}" references unknown event property "${propName}"`);
817
+ }
818
+ }
819
+ }
820
+ const eventDisplayNames = /* @__PURE__ */ new Map();
821
+ for (const prop of eventProps) {
822
+ if (prop.display_name) {
823
+ const names = eventDisplayNames.get(prop.display_name) || [];
824
+ names.push(prop.name);
825
+ eventDisplayNames.set(prop.display_name, names);
826
+ }
827
+ }
828
+ for (const [displayName, names] of eventDisplayNames) {
829
+ if (names.length > 1) {
830
+ errors.push(`Display name "${displayName}" is used by multiple event properties: ${names.join(", ")}`);
831
+ }
832
+ }
833
+ const commonDisplayNames = /* @__PURE__ */ new Map();
834
+ for (const prop of commonProps) {
835
+ if (prop.display_name) {
836
+ const names = commonDisplayNames.get(prop.display_name) || [];
837
+ names.push(prop.name);
838
+ commonDisplayNames.set(prop.display_name, names);
839
+ }
840
+ }
841
+ for (const [displayName, names] of commonDisplayNames) {
842
+ if (names.length > 1) {
843
+ errors.push(`Display name "${displayName}" is used by multiple common properties: ${names.join(", ")}`);
844
+ }
845
+ }
846
+ const userDisplayNames = /* @__PURE__ */ new Map();
847
+ for (const prop of d.user_properties) {
848
+ if (prop.display_name) {
849
+ const names = userDisplayNames.get(prop.display_name) || [];
850
+ names.push(prop.name);
851
+ userDisplayNames.set(prop.display_name, names);
852
+ }
853
+ }
854
+ for (const [displayName, names] of userDisplayNames) {
855
+ if (names.length > 1) {
856
+ errors.push(`Display name "${displayName}" is used by multiple user properties: ${names.join(", ")}`);
857
+ }
858
+ }
859
+ const compositeChildren = /* @__PURE__ */ new Map();
860
+ for (const prop of eventProps) {
861
+ if (prop.type === "array_row" || prop.type === "object") {
862
+ compositeChildren.set(prop.name, /* @__PURE__ */ new Set());
863
+ }
864
+ }
865
+ for (const prop of eventProps) {
866
+ if (prop.name.includes(".")) {
867
+ const parent = prop.name.split(".")[0];
868
+ const children = compositeChildren.get(parent);
869
+ if (children) {
870
+ children.add(prop.name);
871
+ }
872
+ }
873
+ }
874
+ for (const evt of d.events) {
875
+ if (!evt.prop_names) continue;
876
+ for (const parentName of compositeProps) {
877
+ if (evt.prop_names.includes(parentName)) {
878
+ const eventChildren = evt.prop_names.filter((p) => p.startsWith(parentName + "."));
879
+ const expectedChildren = compositeChildren.get(parentName);
880
+ if (expectedChildren && eventChildren.length > 0) {
881
+ for (const child of expectedChildren) {
882
+ if (!eventChildren.includes(child)) {
883
+ errors.push(`Event "${evt.event_name}" uses "${parentName}" but missing child "${child}"`);
884
+ }
885
+ }
886
+ }
887
+ }
888
+ }
889
+ }
890
+ const childPropTypes = /* @__PURE__ */ new Map();
891
+ for (const prop of eventProps) {
892
+ if (prop.name.includes(".")) {
893
+ const childName = prop.name;
894
+ const existing = childPropTypes.get(childName);
895
+ if (existing) {
896
+ if (existing.type !== prop.type) {
897
+ errors.push(`Child property "${childName}" has inconsistent types: "${existing.type}" vs "${prop.type}" (used in events: ${existing.events.join(", ")})`);
898
+ }
899
+ } else {
900
+ childPropTypes.set(childName, { type: prop.type, events: [] });
901
+ }
902
+ }
903
+ }
904
+ if (errors.length > 0) {
905
+ throw new Error(`Draft validation failed:
906
+ ${errors.map((e) => " - " + e).join("\n")}`);
907
+ }
908
+ }
909
+ async function writeDraftXlsx(d, outPath, locale = "zh") {
910
+ validateDraft(d);
911
+ const workbook = new ExcelJS.Workbook();
912
+ const eventSheet = workbook.addWorksheet(sheetName("event_data", locale));
913
+ eventSheet.addRow([
914
+ headerName("event_name", locale),
915
+ headerName("event_display_name", locale),
916
+ headerName("event_desc", locale),
917
+ headerName("event_tag", locale),
918
+ headerName("platform", locale),
919
+ headerName("prop_name", locale),
920
+ headerName("prop_display_name", locale),
921
+ headerName("prop_type", locale),
922
+ headerName("prop_desc", locale)
923
+ ]);
924
+ const propByName = new Map(d.event_properties.map((p) => [p.name, p]));
925
+ for (const evt of d.events) {
926
+ const startRow = eventSheet.rowCount + 1;
927
+ const platformStr = evt.platform ? PLATFORM_TO_XLSX[evt.platform] : "";
928
+ if (evt.prop_names.length === 0) {
929
+ eventSheet.addRow([
930
+ evt.event_name,
931
+ evt.display_name ?? "",
932
+ evt.event_desc ?? "",
933
+ evt.event_tag ?? "",
934
+ platformStr,
935
+ "",
936
+ "",
937
+ "",
938
+ ""
939
+ ]);
940
+ } else {
941
+ for (const propName of evt.prop_names) {
942
+ const prop = propByName.get(propName);
943
+ eventSheet.addRow([
944
+ evt.event_name,
945
+ evt.display_name ?? "",
946
+ evt.event_desc ?? "",
947
+ evt.event_tag ?? "",
948
+ platformStr,
949
+ prop?.name ?? propName,
950
+ prop?.display_name ?? "",
951
+ prop ? typeToDisplay(prop.type, locale) : "",
952
+ prop?.desc ?? ""
953
+ ]);
954
+ }
955
+ const endRow = eventSheet.rowCount;
956
+ if (endRow > startRow) {
957
+ for (const col of ["A", "B", "C", "D", "E"]) {
958
+ eventSheet.mergeCells(`${col}${startRow}:${col}${endRow}`);
959
+ }
960
+ }
961
+ }
962
+ }
963
+ const commonSheet = workbook.addWorksheet(sheetName("common_props", locale));
964
+ commonSheet.addRow([
965
+ headerName("common_prop_name", locale),
966
+ headerName("common_prop_display_name", locale),
967
+ headerName("common_prop_type", locale),
968
+ headerName("common_prop_desc", locale)
969
+ ]);
970
+ for (const prop of d.common_event_properties) {
971
+ commonSheet.addRow([
972
+ prop.name,
973
+ prop.display_name ?? "",
974
+ typeToDisplay(prop.type, locale),
975
+ prop.desc ?? ""
976
+ ]);
977
+ }
978
+ const userSheet = workbook.addWorksheet(sheetName("user_data", locale));
979
+ userSheet.addRow([
980
+ headerName("user_prop_name", locale),
981
+ headerName("user_prop_display_name", locale),
982
+ headerName("user_prop_type", locale),
983
+ headerName("update_type", locale),
984
+ headerName("user_prop_desc", locale),
985
+ headerName("prop_tag", locale)
986
+ ]);
987
+ for (const prop of d.user_properties) {
988
+ userSheet.addRow([
989
+ prop.name,
990
+ prop.display_name ?? "",
991
+ typeToDisplay(prop.type, locale),
992
+ prop.update_type ?? "user_set",
993
+ // 默认 user_set
994
+ prop.desc ?? "",
995
+ prop.prop_tag ?? ""
996
+ ]);
997
+ }
998
+ const userIdSheet = workbook.addWorksheet(sheetName("user_id", locale));
999
+ userIdSheet.addRow([
1000
+ headerName("user_id_prop_name", locale),
1001
+ headerName("user_id_display_name", locale),
1002
+ headerName("user_id_desc", locale),
1003
+ headerName("user_id_value_desc", locale)
1004
+ ]);
1005
+ userIdSheet.addRow(["#account_id", t("user_id.account_id_display", {}, locale), t("user_id.system_property", {}, locale), t("user_id.set_to", { field: d.meta.user_identity?.account_id_field ?? "account ID" }, locale)]);
1006
+ userIdSheet.addRow(["#distinct_id", t("user_id.distinct_id_display", {}, locale), t("user_id.system_property", {}, locale), t("user_id.auto_generated", {}, locale)]);
1007
+ await workbook.xlsx.writeFile(outPath);
1008
+ }
1009
+
1010
+ // src/tracking/i18n/ae-locale.ts
1011
+ function aeLocaleToCli(raw) {
1012
+ const normalized = raw.trim().replace("-", "_").toLowerCase();
1013
+ if (normalized.startsWith("zh")) return "zh";
1014
+ if (normalized.startsWith("en")) return "en";
1015
+ if (normalized.startsWith("ja")) return "ja";
1016
+ if (normalized.startsWith("ko")) return "ko";
1017
+ return null;
1018
+ }
1019
+ function cliLocaleToAE(locale) {
1020
+ switch (locale) {
1021
+ case "zh":
1022
+ return "zh_CN";
1023
+ case "en":
1024
+ return "en_US";
1025
+ case "ja":
1026
+ return "ja_JP";
1027
+ case "ko":
1028
+ return "ko_KR";
1029
+ }
1030
+ }
1031
+
1032
+ // src/core/tracking-client.ts
1033
+ var DEBUG_BASE = "/v1/ta/bury/manage/debug";
1034
+ function buildUrl(host, modulePath, params = {}) {
1035
+ const base = host.replace(/\/$/, "");
1036
+ const p = modulePath.startsWith("/") ? modulePath : `/${modulePath}`;
1037
+ const url = new URL(`${base}${p}`);
1038
+ for (const [k, v] of Object.entries(params)) {
1039
+ if (v !== void 0 && v !== null) url.searchParams.set(k, String(v));
1040
+ }
1041
+ return url.toString();
1042
+ }
1043
+ function extractLangFromConfig(data) {
1044
+ if (!data) return null;
1045
+ const raw = typeof data.lang === "string" && data.lang || typeof data.umi_locale === "string" && data.umi_locale || typeof data.locale === "string" && data.locale || null;
1046
+ return raw ? aeLocaleToCli(raw) : null;
1047
+ }
1048
+ var TrackingClient = class {
1049
+ constructor(host, token) {
1050
+ this.host = host;
1051
+ this.token = token;
1052
+ }
1053
+ host;
1054
+ token;
1055
+ async resolveToken() {
1056
+ return this.token ?? getToken(this.host);
1057
+ }
1058
+ async getProgram(projectId) {
1059
+ const data = await httpGet(
1060
+ "/v1/ta/bury/manage/program/query",
1061
+ { projectId, "@t": Date.now() },
1062
+ this.host
1063
+ );
1064
+ return data ?? null;
1065
+ }
1066
+ async deleteProgram(projectId) {
1067
+ const token = await this.resolveToken();
1068
+ const url = buildUrl(this.host, "/v1/ta/bury/manage/program/delete", {
1069
+ projectId,
1070
+ "@t": Date.now()
1071
+ });
1072
+ const resp = await fetch(url, {
1073
+ method: "GET",
1074
+ headers: {
1075
+ authorization: `bearer ${token}`,
1076
+ accept: "application/json"
1077
+ }
1078
+ });
1079
+ const env = safeJsonParse(await resp.text());
1080
+ if (env.return_code !== 0) {
1081
+ throw new Error(env.return_message || `AE API error (code: ${env.return_code})`);
1082
+ }
1083
+ return { return_code: env.return_code, return_message: env.return_message };
1084
+ }
1085
+ async uploadProgramExcel(args) {
1086
+ const token = await this.resolveToken();
1087
+ const form = new FormData();
1088
+ form.append(
1089
+ "file",
1090
+ new Blob([new Uint8Array(args.file)], {
1091
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1092
+ }),
1093
+ args.filename
1094
+ );
1095
+ form.append("projectId", String(args.projectId));
1096
+ form.append("access_token", token);
1097
+ const url = buildUrl(this.host, "/v1/ta/bury/manage/program/excel-save");
1098
+ const resp = await fetch(url, { method: "POST", body: form });
1099
+ const env = safeJsonParse(await resp.text());
1100
+ if (env.return_code !== 0 && env.return_code !== void 0 && !env.data?.eventErrorMap && !env.data?.userErrorMap) {
1101
+ logger.error(`Upload failed: ${env.return_message || `AE API error (code: ${env.return_code})`}`);
1102
+ }
1103
+ return env;
1104
+ }
1105
+ async getUserAutoConfig() {
1106
+ const data = await httpGet(
1107
+ "/v1/ta/auto/config/getUserAutoConfig",
1108
+ { "@t": Date.now() },
1109
+ this.host
1110
+ );
1111
+ if (data && typeof data === "object") {
1112
+ return data;
1113
+ }
1114
+ return null;
1115
+ }
1116
+ async getServerLang() {
1117
+ const config = await this.getUserAutoConfig();
1118
+ return extractLangFromConfig(config);
1119
+ }
1120
+ /** lang format: zh_CN, en_US, ja_JP, ko_KR */
1121
+ async saveUserAutoConfig(langCode) {
1122
+ await httpGet("/v1/ta/auto/config/getUserAutoConfig", { "@t": Date.now(), lang: langCode }, this.host);
1123
+ }
1124
+ async debugGet(path5, params) {
1125
+ const data = await httpGet(`${DEBUG_BASE}${path5}`, { ...params, "@t": Date.now() }, this.host);
1126
+ return data;
1127
+ }
1128
+ async listDevice(projectId) {
1129
+ const data = await this.debugGet("/listDevice", { projectId });
1130
+ return data?.deviceList ?? [];
1131
+ }
1132
+ async addDevice(projectId, deviceId, deviceName) {
1133
+ await this.debugGet("/saveDevice", { deviceId, deviceName, projectId });
1134
+ }
1135
+ async selectDevice(projectId, deviceId) {
1136
+ await this.debugGet("/chooseDevice", { deviceId, projectId });
1137
+ }
1138
+ async removeDevice(projectId, deviceId) {
1139
+ await this.debugGet("/deleteDevice", { deviceId, projectId });
1140
+ }
1141
+ async listDeviceData(projectId, deviceId, startTime) {
1142
+ const data = await this.debugGet("/listDeviceData", {
1143
+ deviceID: deviceId,
1144
+ projectId,
1145
+ startTime
1146
+ });
1147
+ return data ?? { eventList: [], deviceDataList: [] };
1148
+ }
1149
+ };
1150
+ async function createTrackingClient(host) {
1151
+ const token = await getToken(host);
1152
+ return new TrackingClient(host, token);
1153
+ }
1154
+
1155
+ // src/tracking/te-plan/fetch.ts
1156
+ async function fetchPlan({ projectId, host }) {
1157
+ const client = await createTrackingClient(host);
1158
+ const data = await client.getProgram(projectId);
1159
+ if (!data) {
1160
+ throw new Error(t("error.fetch_no_data", { host }));
1161
+ }
1162
+ return normalize2(data);
1163
+ }
1164
+ function normalize2(data) {
1165
+ return {
1166
+ meta: { app_type: "unknown", sdk_integration_mode: "client_only", plan_name: "from-te" },
1167
+ events: (data.events ?? []).map((e) => ({
1168
+ event_name: e.eventName,
1169
+ display_name: e.displayName,
1170
+ event_tag: e.eventTag,
1171
+ event_desc: e.eventDesc,
1172
+ source: "chat",
1173
+ prop_names: e.props ?? []
1174
+ })),
1175
+ event_properties: (data.eventProps ?? []).map((p) => ({
1176
+ name: p.name,
1177
+ display_name: p.displayName,
1178
+ type: p.type?.toLowerCase() ?? "string",
1179
+ desc: p.desc,
1180
+ source: "chat"
1181
+ })),
1182
+ common_event_properties: (data.commonEventProps ?? []).map((p) => ({
1183
+ name: p.name,
1184
+ display_name: p.displayName,
1185
+ type: p.type?.toLowerCase() ?? "string",
1186
+ desc: p.desc,
1187
+ source: "chat"
1188
+ })),
1189
+ user_properties: (data.userProps ?? []).map((p) => ({
1190
+ name: p.name,
1191
+ display_name: p.displayName,
1192
+ type: p.type?.toLowerCase() ?? "string",
1193
+ desc: p.desc,
1194
+ update_type: p.updateType ?? "user_set",
1195
+ prop_tag: p.propTag,
1196
+ source: "chat"
1197
+ }))
1198
+ };
1199
+ }
1200
+
1201
+ // src/tracking/plan/draft.ts
1202
+ import fs2 from "fs";
1203
+ import path2 from "path";
1204
+
1205
+ // src/tracking/plan/autotrack.ts
1206
+ var TAG = {
1207
+ zh: "\u7CFB\u7EDF\u4E8B\u4EF6",
1208
+ en: "System Event",
1209
+ ja: "\u30B7\u30B9\u30C6\u30E0\u30A4\u30D9\u30F3\u30C8",
1210
+ ko: "\uC2DC\uC2A4\uD15C \uC774\uBCA4\uD2B8"
1211
+ };
1212
+ var AUTOTRACK_I18N = {
1213
+ // --- Android/iOS 通用 ---
1214
+ ta_app_install: {
1215
+ display_name: { zh: "APP \u5B89\u88C5", en: "App Install", ja: "\u30A2\u30D7\u30EA\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB", ko: "\uC571 \uC124\uCE58" },
1216
+ desc: { zh: "APP \u9996\u6B21\u5B89\u88C5\u65F6\u4E0A\u62A5\uFF0C\u5347\u7EA7\u4E0D\u89E6\u53D1\uFF0C\u5220\u9664\u91CD\u88C5\u4F1A\u89E6\u53D1", en: "Triggered on first app install; not on upgrade; re-triggered on reinstall", ja: "\u30A2\u30D7\u30EA\u521D\u56DE\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u6642\u306B\u5831\u544A\u3002\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u3067\u306F\u767A\u751F\u305B\u305A\u3001\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3067\u518D\u767A\u751F", ko: "\uC571 \uCD5C\uCD08 \uC124\uCE58 \uC2DC \uBCF4\uACE0\uB429\uB2C8\uB2E4. \uC5C5\uADF8\uB808\uC774\uB4DC \uC2DC\uC5D0\uB294 \uBC1C\uC0DD\uD558\uC9C0 \uC54A\uC73C\uBA70 \uC7AC\uC124\uCE58 \uC2DC \uB2E4\uC2DC \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1217
+ },
1218
+ ta_app_start: {
1219
+ display_name: { zh: "APP \u542F\u52A8", en: "App Start", ja: "\u30A2\u30D7\u30EA\u8D77\u52D5", ko: "\uC571 \uC2DC\uC791" },
1220
+ desc: { zh: "\u7528\u6237\u5F00\u542F APP \u6216\u4ECE\u540E\u53F0\u5524\u9192\u65F6\u89E6\u53D1", en: "Triggered when user opens the app or brings it from background", ja: "\u30E6\u30FC\u30B6\u30FC\u304C\u30A2\u30D7\u30EA\u3092\u958B\u304F\u304B\u3001\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u304B\u3089\u5FA9\u5E30\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uC0AC\uC6A9\uC790\uAC00 \uC571\uC744 \uC5F4\uAC70\uB098 \uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C \uAC00\uC838\uC62C \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1221
+ },
1222
+ ta_app_end: {
1223
+ display_name: { zh: "APP \u5173\u95ED", en: "App End", ja: "\u30A2\u30D7\u30EA\u7D42\u4E86", ko: "\uC571 \uC885\uB8CC" },
1224
+ desc: { zh: "\u7528\u6237\u5173\u95ED APP \u6216\u5C06 APP \u8C03\u81F3\u540E\u53F0\u65F6\u89E6\u53D1", en: "Triggered when user closes the app or moves it to background", ja: "\u30E6\u30FC\u30B6\u30FC\u304C\u30A2\u30D7\u30EA\u3092\u9589\u3058\u308B\u304B\u3001\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306B\u79FB\u52D5\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uC0AC\uC6A9\uC790\uAC00 \uC571\uC744 \uB2EB\uAC70\uB098 \uBC31\uADF8\uB77C\uC6B4\uB4DC\uB85C \uC774\uB3D9\uD560 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1225
+ },
1226
+ ta_app_view: {
1227
+ display_name: { zh: "APP \u9875\u9762\u6D4F\u89C8", en: "App Page View", ja: "\u30A2\u30D7\u30EA\u30DA\u30FC\u30B8\u30D3\u30E5\u30FC", ko: "\uC571 \uD398\uC774\uC9C0 \uC870\uD68C" },
1228
+ desc: { zh: "\u7528\u6237\u6D4F\u89C8\u9875\u9762\uFF08Activity/ViewController\uFF09\u65F6\u89E6\u53D1", en: "Triggered when user views a page (Activity/ViewController)", ja: "\u30E6\u30FC\u30B6\u30FC\u304C\u30DA\u30FC\u30B8\uFF08Activity/ViewController\uFF09\u3092\u95B2\u89A7\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uC0AC\uC6A9\uC790\uAC00 \uD398\uC774\uC9C0(Activity/ViewController)\uB97C \uC870\uD68C\uD560 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1229
+ },
1230
+ ta_app_click: {
1231
+ display_name: { zh: "APP \u63A7\u4EF6\u70B9\u51FB", en: "App Control Click", ja: "\u30A2\u30D7\u30EA\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30AF\u30EA\u30C3\u30AF", ko: "\uC571 \uCEE8\uD2B8\uB864 \uD074\uB9AD" },
1232
+ desc: { zh: "\u7528\u6237\u70B9\u51FB\u63A7\u4EF6\u65F6\u89E6\u53D1", en: "Triggered when user clicks a UI control", ja: "\u30E6\u30FC\u30B6\u30FC\u304CUI\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uC0AC\uC6A9\uC790\uAC00 UI \uCEE8\uD2B8\uB864\uC744 \uD074\uB9AD\uD560 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1233
+ },
1234
+ ta_app_crash: {
1235
+ display_name: { zh: "APP \u5D29\u6E83", en: "App Crash", ja: "\u30A2\u30D7\u30EA\u30AF\u30E9\u30C3\u30B7\u30E5", ko: "\uC571 \uCDA9\uB3CC" },
1236
+ desc: { zh: "APP \u51FA\u73B0\u672A\u6355\u83B7\u5F02\u5E38\u65F6\u4E0A\u62A5", en: "Reported when the app encounters an uncaught exception", ja: "\u30A2\u30D7\u30EA\u304C\u30AD\u30E3\u30C3\u30C1\u3055\u308C\u306A\u3044\u4F8B\u5916\u306B\u906D\u9047\u3057\u305F\u6642\u306B\u5831\u544A", ko: "\uC571\uC774 \uCC98\uB9AC\uB418\uC9C0 \uC54A\uC740 \uC608\uC678\uB97C \uB9CC\uB0AC\uC744 \uB54C \uBCF4\uACE0\uB429\uB2C8\uB2E4" }
1237
+ },
1238
+ // --- JavaScript (Web/H5) ---
1239
+ ta_pageview: {
1240
+ display_name: { zh: "\u9875\u9762\u6D4F\u89C8", en: "Page View", ja: "\u30DA\u30FC\u30B8\u30D3\u30E5\u30FC", ko: "\uD398\uC774\uC9C0 \uC870\uD68C" },
1241
+ desc: { zh: '\u8C03\u7528 ta.quick("autoTrack") \u65F6\u4E0A\u62A5', en: 'Reported when ta.quick("autoTrack") is called', ja: 'ta.quick("autoTrack") \u547C\u3073\u51FA\u3057\u6642\u306B\u5831\u544A', ko: 'ta.quick("autoTrack") \uD638\uCD9C \uC2DC \uBCF4\uACE0\uB429\uB2C8\uB2E4' }
1242
+ },
1243
+ ta_page_show: {
1244
+ display_name: { zh: "\u9875\u9762\u663E\u793A", en: "Page Show", ja: "\u30DA\u30FC\u30B8\u8868\u793A", ko: "\uD398\uC774\uC9C0 \uD45C\uC2DC" },
1245
+ desc: { zh: "\u9875\u9762\u663E\u793A\u65F6\u89E6\u53D1\uFF08\u9700\u5F00\u542F\u914D\u7F6E\uFF09", en: "Triggered when page is shown (requires config)", ja: "\u30DA\u30FC\u30B8\u8868\u793A\u6642\u306B\u767A\u751F\uFF08\u8A2D\u5B9A\u304C\u5FC5\u8981\uFF09", ko: "\uD398\uC774\uC9C0\uAC00 \uD45C\uC2DC\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4 (\uC124\uC815 \uD544\uC694)" }
1246
+ },
1247
+ ta_page_hide: {
1248
+ display_name: { zh: "\u9875\u9762\u9690\u85CF", en: "Page Hide", ja: "\u30DA\u30FC\u30B8\u975E\u8868\u793A", ko: "\uD398\uC774\uC9C0 \uC228\uAE40" },
1249
+ desc: { zh: "\u9875\u9762\u9690\u85CF\u65F6\u89E6\u53D1\uFF08\u9700\u5F00\u542F\u914D\u7F6E\uFF09", en: "Triggered when page is hidden (requires config)", ja: "\u30DA\u30FC\u30B8\u975E\u8868\u793A\u6642\u306B\u767A\u751F\uFF08\u8A2D\u5B9A\u304C\u5FC5\u8981\uFF09", ko: "\uD398\uC774\uC9C0\uAC00 \uC228\uACA8\uC9C8 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4 (\uC124\uC815 \uD544\uC694)" }
1250
+ },
1251
+ // --- 微信小程序 ---
1252
+ ta_mp_launch: {
1253
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u521D\u59CB\u5316", en: "Mini Program Launch", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u521D\u671F\u5316", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uCD08\uAE30\uD654" },
1254
+ desc: { zh: "\u5C0F\u7A0B\u5E8F\u88AB\u9996\u6B21\u6253\u5F00\u65F6\u89E6\u53D1\uFF0C\u8FDB\u7A0B\u751F\u547D\u5468\u671F\u5185\u53EA\u89E6\u53D1\u4E00\u6B21", en: "Triggered on first launch of mini program; only once per process lifecycle", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u521D\u56DE\u8D77\u52D5\u6642\u306B\u767A\u751F\u3002\u30D7\u30ED\u30BB\u30B9\u30E9\u30A4\u30D5\u30B5\u30A4\u30AF\u30EB\u5185\u30671\u56DE\u306E\u307F", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uCD5C\uCD08 \uC2E4\uD589 \uC2DC \uBC1C\uC0DD\uD569\uB2C8\uB2E4. \uD504\uB85C\uC138\uC2A4 \uC218\uBA85 \uC8FC\uAE30 \uB0B4 \uD55C \uBC88\uB9CC \uBC1C\uC0DD" }
1255
+ },
1256
+ ta_mp_show: {
1257
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u542F\u52A8", en: "Mini Program Show", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u8D77\u52D5", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uC2DC\uC791" },
1258
+ desc: { zh: "\u5C0F\u7A0B\u5E8F\u88AB\u542F\u52A8\u6216\u4ECE\u540E\u53F0\u8C03\u56DE\u524D\u53F0\u65F6\u89E6\u53D1", en: "Triggered when mini program is launched or brought to foreground", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u304C\u8D77\u52D5\u307E\u305F\u306F\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u304B\u3089\u30D5\u30A9\u30A2\u30B0\u30E9\u30A6\u30F3\u30C9\u306B\u5FA9\u5E30\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8\uC774 \uC2DC\uC791\uB418\uAC70\uB098 \uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C \uD3EC\uADF8\uB77C\uC6B4\uB4DC\uB85C \uC804\uD658\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1259
+ },
1260
+ ta_mp_hide: {
1261
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u9690\u85CF", en: "Mini Program Hide", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u975E\u8868\u793A", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uC228\uAE40" },
1262
+ desc: { zh: "\u5C0F\u7A0B\u5E8F\u88AB\u8C03\u5165\u540E\u53F0\u65F6\u89E6\u53D1", en: "Triggered when mini program is moved to background", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u304C\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306B\u79FB\u52D5\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8\uC774 \uBC31\uADF8\uB77C\uC6B4\uB4DC\uB85C \uC774\uB3D9\uD560 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1263
+ },
1264
+ ta_mp_view: {
1265
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u9875\u9762\u6D4F\u89C8", en: "Mini Program Page View", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u30DA\u30FC\u30B8\u30D3\u30E5\u30FC", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uD398\uC774\uC9C0 \uC870\uD68C" },
1266
+ desc: { zh: "\u9875\u9762\u88AB\u6253\u5F00\u6216\u4ECE\u540E\u53F0\u8C03\u56DE\u524D\u53F0\u65F6\u89E6\u53D1", en: "Triggered when page is opened or brought to foreground", ja: "\u30DA\u30FC\u30B8\u304C\u958B\u304B\u308C\u308B\u304B\u3001\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u304B\u3089\u30D5\u30A9\u30A2\u30B0\u30E9\u30A6\u30F3\u30C9\u306B\u5FA9\u5E30\u3057\u305F\u6642\u306B\u767A\u751F", ko: "\uD398\uC774\uC9C0\uAC00 \uC5F4\uB9AC\uAC70\uB098 \uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C \uD3EC\uADF8\uB77C\uC6B4\uB4DC\uB85C \uC804\uD658\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1267
+ },
1268
+ ta_mp_share: {
1269
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u8F6C\u53D1\u5206\u4EAB", en: "Mini Program Share", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u5171\u6709", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uACF5\uC720" },
1270
+ desc: { zh: "\u8F6C\u53D1\u6309\u94AE\u88AB\u70B9\u51FB\u65F6\u89E6\u53D1", en: "Triggered when the share button is clicked", ja: "\u5171\u6709\u30DC\u30BF\u30F3\u304C\u30AF\u30EA\u30C3\u30AF\u3055\u308C\u305F\u6642\u306B\u767A\u751F", ko: "\uACF5\uC720 \uBC84\uD2BC\uC774 \uD074\uB9AD\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1271
+ },
1272
+ ta_page_leave: {
1273
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u9875\u9762\u5378\u8F7D", en: "Mini Program Page Unload", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u30DA\u30FC\u30B8\u30A2\u30F3\u30ED\u30FC\u30C9", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uD398\uC774\uC9C0 \uC5B8\uB85C\uB4DC" },
1274
+ desc: { zh: "\u9875\u9762\u5378\u8F7D\u65F6\u89E6\u53D1", en: "Triggered when the page is unloaded", ja: "\u30DA\u30FC\u30B8\u304C\u30A2\u30F3\u30ED\u30FC\u30C9\u3055\u308C\u305F\u6642\u306B\u767A\u751F", ko: "\uD398\uC774\uC9C0\uAC00 \uC5B8\uB85C\uB4DC\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1275
+ },
1276
+ ta_add_favorite: {
1277
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u9875\u9762\u6536\u85CF", en: "Mini Program Favorite", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u304A\u6C17\u306B\u5165\u308A", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uC990\uACA8\uCC3E\uAE30" },
1278
+ desc: { zh: "\u9875\u9762\u88AB\u6536\u85CF\u65F6\u89E6\u53D1", en: "Triggered when the page is bookmarked", ja: "\u30DA\u30FC\u30B8\u304C\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF\u3055\u308C\u305F\u6642\u306B\u767A\u751F", ko: "\uD398\uC774\uC9C0\uAC00 \uC990\uACA8\uCC3E\uAE30\uC5D0 \uCD94\uAC00\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1279
+ },
1280
+ ta_mp_click: {
1281
+ display_name: { zh: "\u5C0F\u7A0B\u5E8F\u5143\u7D20\u70B9\u51FB", en: "Mini Program Element Click", ja: "\u30DF\u30CB\u30D7\u30ED\u30B0\u30E9\u30E0\u8981\u7D20\u30AF\u30EA\u30C3\u30AF", ko: "\uBBF8\uB2C8\uD504\uB85C\uADF8\uB7A8 \uC694\uC18C \uD074\uB9AD" },
1282
+ desc: { zh: "\u9875\u9762\u5143\u7D20\u88AB\u70B9\u51FB\u65F6\u89E6\u53D1", en: "Triggered when a page element is clicked", ja: "\u30DA\u30FC\u30B8\u8981\u7D20\u304C\u30AF\u30EA\u30C3\u30AF\u3055\u308C\u305F\u6642\u306B\u767A\u751F", ko: "\uD398\uC774\uC9C0 \uC694\uC18C\uAC00 \uD074\uB9AD\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1283
+ },
1284
+ // --- Unity 微信小游戏 ---
1285
+ ta_mg_launch: {
1286
+ display_name: { zh: "\u5C0F\u6E38\u620F\u521D\u59CB\u5316", en: "Mini Game Launch", ja: "\u30DF\u30CB\u30B2\u30FC\u30E0\u521D\u671F\u5316", ko: "\uBBF8\uB2C8\uAC8C\uC784 \uCD08\uAE30\uD654" },
1287
+ desc: { zh: "\u5C0F\u6E38\u620F\u9996\u6B21\u6253\u5F00\u65F6\u89E6\u53D1", en: "Triggered on first launch of mini game", ja: "\u30DF\u30CB\u30B2\u30FC\u30E0\u521D\u56DE\u8D77\u52D5\u6642\u306B\u767A\u751F", ko: "\uBBF8\uB2C8\uAC8C\uC784 \uCD5C\uCD08 \uC2E4\uD589 \uC2DC \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1288
+ },
1289
+ ta_mg_show: {
1290
+ display_name: { zh: "\u5C0F\u6E38\u620F\u542F\u52A8", en: "Mini Game Show", ja: "\u30DF\u30CB\u30B2\u30FC\u30E0\u8D77\u52D5", ko: "\uBBF8\uB2C8\uAC8C\uC784 \uC2DC\uC791" },
1291
+ desc: { zh: "\u5C0F\u6E38\u620F\u8FDB\u5165\u524D\u53F0\u65F6\u89E6\u53D1", en: "Triggered when mini game enters foreground", ja: "\u30DF\u30CB\u30B2\u30FC\u30E0\u304C\u30D5\u30A9\u30A2\u30B0\u30E9\u30A6\u30F3\u30C9\u306B\u5165\u3063\u305F\u6642\u306B\u767A\u751F", ko: "\uBBF8\uB2C8\uAC8C\uC784\uC774 \uD3EC\uADF8\uB77C\uC6B4\uB4DC\uB85C \uC9C4\uC785\uD560 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1292
+ },
1293
+ ta_mg_hide: {
1294
+ display_name: { zh: "\u5C0F\u6E38\u620F\u9690\u85CF", en: "Mini Game Hide", ja: "\u30DF\u30CB\u30B2\u30FC\u30E0\u975E\u8868\u793A", ko: "\uBBF8\uB2C8\uAC8C\uC784 \uC228\uAE40" },
1295
+ desc: { zh: "\u5C0F\u6E38\u620F\u8FDB\u5165\u540E\u53F0\u65F6\u89E6\u53D1", en: "Triggered when mini game enters background", ja: "\u30DF\u30CB\u30B2\u30FC\u30E0\u304C\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306B\u5165\u3063\u305F\u6642\u306B\u767A\u751F", ko: "\uBBF8\uB2C8\uAC8C\uC784\uC774 \uBC31\uADF8\uB77C\uC6B4\uB4DC\uB85C \uC9C4\uC785\uD560 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1296
+ },
1297
+ // --- Unity 场景事件(optional) ---
1298
+ ta_scene_loaded: {
1299
+ display_name: { zh: "\u573A\u666F\u52A0\u8F7D", en: "Scene Load", ja: "\u30B7\u30FC\u30F3\u30ED\u30FC\u30C9", ko: "\uC52C \uB85C\uB4DC" },
1300
+ desc: { zh: "\u6E38\u620F\u573A\u666F\uFF08Scene\uFF09\u52A0\u8F7D\u65F6\u89E6\u53D1", en: "Triggered when a game scene is loaded", ja: "\u30B2\u30FC\u30E0\u30B7\u30FC\u30F3\uFF08Scene\uFF09\u306E\u30ED\u30FC\u30C9\u6642\u306B\u767A\u751F", ko: "\uAC8C\uC784 \uC52C(Scene)\uC774 \uB85C\uB4DC\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1301
+ },
1302
+ ta_scene_unloaded: {
1303
+ display_name: { zh: "\u573A\u666F\u5378\u8F7D", en: "Scene Unload", ja: "\u30B7\u30FC\u30F3\u30A2\u30F3\u30ED\u30FC\u30C9", ko: "\uC52C \uC5B8\uB85C\uB4DC" },
1304
+ desc: { zh: "\u6E38\u620F\u573A\u666F\uFF08Scene\uFF09\u5378\u8F7D\u65F6\u89E6\u53D1", en: "Triggered when a game scene is unloaded", ja: "\u30B2\u30FC\u30E0\u30B7\u30FC\u30F3\uFF08Scene\uFF09\u306E\u30A2\u30F3\u30ED\u30FC\u30C9\u6642\u306B\u767A\u751F", ko: "\uAC8C\uC784 \uC52C(Scene)\uC774 \uC5B8\uB85C\uB4DC\uB420 \uB54C \uBC1C\uC0DD\uD569\uB2C8\uB2E4" }
1305
+ }
1306
+ };
1307
+ function makeAutotrackEvent(eventName, locale) {
1308
+ const i18n = AUTOTRACK_I18N[eventName];
1309
+ return {
1310
+ event_name: eventName,
1311
+ display_name: i18n?.display_name[locale] ?? eventName,
1312
+ event_tag: TAG[locale],
1313
+ event_desc: i18n?.desc[locale] ?? "",
1314
+ source: "autotrack",
1315
+ prop_names: []
1316
+ };
1317
+ }
1318
+ var SDK_RECOMMENDED = {
1319
+ nativeApp: ["ta_app_install", "ta_app_start", "ta_app_end"],
1320
+ js: ["ta_page_show", "ta_page_hide"],
1321
+ wechatMp: ["ta_mp_launch", "ta_mp_show", "ta_mp_hide", "ta_mp_view", "ta_mp_share"],
1322
+ wechatMg: ["ta_mp_launch", "ta_mp_show", "ta_mp_hide"],
1323
+ unity: ["ta_app_install", "ta_app_start", "ta_app_end"],
1324
+ unityWxmg: ["ta_mg_launch", "ta_mg_show", "ta_mg_hide"],
1325
+ gameEngine: ["ta_app_install", "ta_app_start", "ta_app_end"]
1326
+ };
1327
+ function getAutotrackEvents(sdkType, locale = "zh") {
1328
+ let group;
1329
+ switch (sdkType) {
1330
+ case "android":
1331
+ case "ios":
1332
+ case "react_native":
1333
+ case "flutter":
1334
+ case "uniapp_app":
1335
+ group = "nativeApp";
1336
+ break;
1337
+ case "javascript":
1338
+ case "uniapp_h5":
1339
+ group = "js";
1340
+ break;
1341
+ case "wechat_mp":
1342
+ case "douyin_mp":
1343
+ case "alipay_mp":
1344
+ case "other_mp":
1345
+ case "uniapp_mp":
1346
+ group = "wechatMp";
1347
+ break;
1348
+ case "wechat_mg":
1349
+ group = "wechatMg";
1350
+ break;
1351
+ case "unity":
1352
+ group = "unity";
1353
+ break;
1354
+ case "unity_wxmg":
1355
+ group = "unityWxmg";
1356
+ break;
1357
+ case "cocos2dx":
1358
+ case "cocoscreator":
1359
+ case "layaair":
1360
+ case "unreal":
1361
+ group = "gameEngine";
1362
+ break;
1363
+ default:
1364
+ return [];
1365
+ }
1366
+ return (SDK_RECOMMENDED[group] ?? []).map((name) => makeAutotrackEvent(name, locale));
1367
+ }
1368
+
1369
+ // src/tracking/plan/draft.ts
1370
+ function injectAutotrackEvents(draft, locale = "zh") {
1371
+ const mode = draft.meta.sdk_integration_mode;
1372
+ if (mode === "server_only") {
1373
+ return draft;
1374
+ }
1375
+ const platforms = draft.meta.client_platforms;
1376
+ const sdkType = draft.meta.client_sdk_type || draft.meta.sdk_type;
1377
+ if (!platforms?.length && !sdkType) {
1378
+ return draft;
1379
+ }
1380
+ let autotrackEvents = [];
1381
+ const sdkTypeOrPlatforms = platforms && platforms.length >= 2 ? platforms : sdkType || platforms;
1382
+ if (Array.isArray(sdkTypeOrPlatforms)) {
1383
+ const allEvents = sdkTypeOrPlatforms.map((t2) => getAutotrackEvents(t2, locale)).flat();
1384
+ const seen = /* @__PURE__ */ new Set();
1385
+ autotrackEvents = allEvents.filter((e) => {
1386
+ if (seen.has(e.event_name)) return false;
1387
+ seen.add(e.event_name);
1388
+ return true;
1389
+ });
1390
+ } else {
1391
+ autotrackEvents = getAutotrackEvents(sdkTypeOrPlatforms, locale);
1392
+ }
1393
+ const existingNames = new Set(draft.events.map((e) => e.event_name));
1394
+ const newEvents = autotrackEvents.filter((e) => !existingNames.has(e.event_name));
1395
+ const eventsWithPlatform = newEvents.map((e) => ({
1396
+ ...e,
1397
+ platform: "client"
1398
+ }));
1399
+ draft.events.push(...eventsWithPlatform);
1400
+ return draft;
1401
+ }
1402
+
1403
+ // src/tracking/plan/fix.ts
1404
+ function extractErrors(response) {
1405
+ const errors = [];
1406
+ if (response.data?.eventErrorMap) {
1407
+ for (const [errorType, items] of Object.entries(response.data.eventErrorMap)) {
1408
+ for (const item of items) {
1409
+ errors.push({ ...item, errorType });
1410
+ }
1411
+ }
1412
+ }
1413
+ if (response.data?.userErrorMap) {
1414
+ for (const [errorType, items] of Object.entries(response.data.userErrorMap)) {
1415
+ for (const item of items) {
1416
+ errors.push({ ...item, errorType });
1417
+ }
1418
+ }
1419
+ }
1420
+ return errors;
1421
+ }
1422
+ function fixDisplayDuplicate(draft, errors) {
1423
+ const duplicateDisplayNames = /* @__PURE__ */ new Map();
1424
+ for (const error of errors) {
1425
+ if (error.errorType === "event_prop_display_duplicate") {
1426
+ const names = duplicateDisplayNames.get(error.value) || [];
1427
+ names.push(error.value);
1428
+ duplicateDisplayNames.set(error.value, names);
1429
+ }
1430
+ }
1431
+ for (const prop of draft.event_properties) {
1432
+ if (duplicateDisplayNames.has(prop.display_name || "")) {
1433
+ const eventsUsingProp = draft.events.filter((e) => e.prop_names.includes(prop.name));
1434
+ if (prop.name.includes(".")) {
1435
+ prop.display_name = `\u660E\u7EC6${prop.display_name}`;
1436
+ } else if (eventsUsingProp.length > 0) {
1437
+ prop.display_name = `${prop.display_name}${t("fix.detail_suffix")}`;
1438
+ }
1439
+ }
1440
+ }
1441
+ }
1442
+ function fixArrayRowConsistency(draft, errors) {
1443
+ const compositeChildren = /* @__PURE__ */ new Map();
1444
+ const evProps = draft.event_properties ?? draft.common_properties ?? [];
1445
+ for (const prop of evProps) {
1446
+ if (prop.type === "array_row" || prop.type === "object") {
1447
+ compositeChildren.set(prop.name, []);
1448
+ }
1449
+ }
1450
+ for (const prop of evProps) {
1451
+ if (prop.name.includes(".")) {
1452
+ const parent = prop.name.split(".")[0];
1453
+ const children = compositeChildren.get(parent);
1454
+ if (children) {
1455
+ children.push(prop.name);
1456
+ }
1457
+ }
1458
+ }
1459
+ for (const event of draft.events) {
1460
+ if (!event.prop_names) continue;
1461
+ const propNamesSet = new Set(event.prop_names);
1462
+ for (const [parentName, children] of compositeChildren) {
1463
+ if (propNamesSet.has(parentName)) {
1464
+ for (const child of children) {
1465
+ if (!propNamesSet.has(child)) {
1466
+ event.prop_names.push(child);
1467
+ }
1468
+ }
1469
+ const parentProps = event.prop_names.filter(
1470
+ (p) => p === parentName || p.startsWith(parentName + ".")
1471
+ );
1472
+ const sorted = [parentName, ...children.filter((c) => event.prop_names.includes(c))];
1473
+ event.prop_names = event.prop_names.filter(
1474
+ (p) => !p.startsWith(parentName) || p === parentName
1475
+ );
1476
+ const idx = event.prop_names.indexOf(parentName);
1477
+ if (idx >= 0) {
1478
+ event.prop_names.splice(idx, 1, ...sorted);
1479
+ }
1480
+ }
1481
+ }
1482
+ }
1483
+ }
1484
+ function fixUnknownPropRefs(draft) {
1485
+ const fixed = [];
1486
+ const props = draft.event_properties ?? draft.common_properties ?? [];
1487
+ const eventPropNames = new Set(props.map((p) => p.name));
1488
+ for (const event of draft.events) {
1489
+ if (!event.prop_names) continue;
1490
+ const removed = [];
1491
+ event.prop_names = event.prop_names.filter((pn) => {
1492
+ if (pn.startsWith("#")) return true;
1493
+ if (eventPropNames.has(pn)) return true;
1494
+ removed.push(pn);
1495
+ return false;
1496
+ });
1497
+ if (removed.length > 0) {
1498
+ fixed.push(...removed.map((r) => `Removed unknown prop "${r}" from event "${event.event_name}"`));
1499
+ }
1500
+ }
1501
+ return fixed;
1502
+ }
1503
+ function fixDisplayNameDuplicates(draft) {
1504
+ const fixed = [];
1505
+ const pools = [
1506
+ { name: "event_properties", items: draft.event_properties ?? draft.common_properties ?? [] },
1507
+ { name: "common_event_properties", items: draft.common_event_properties ?? draft.common_properties ?? [] },
1508
+ { name: "user_properties", items: draft.user_properties ?? [] }
1509
+ ];
1510
+ for (const pool of pools) {
1511
+ const displayMap = /* @__PURE__ */ new Map();
1512
+ for (let i = 0; i < pool.items.length; i++) {
1513
+ const dn = pool.items[i].display_name;
1514
+ if (!dn) continue;
1515
+ const list = displayMap.get(dn) || [];
1516
+ list.push(i);
1517
+ displayMap.set(dn, list);
1518
+ }
1519
+ for (const [displayName, indices] of displayMap) {
1520
+ if (indices.length <= 1) continue;
1521
+ for (let j = 1; j < indices.length; j++) {
1522
+ const prop = pool.items[indices[j]];
1523
+ const newDisplayName = `${displayName} (${prop.name})`;
1524
+ prop.display_name = newDisplayName;
1525
+ fixed.push(`Disambiguated display name "${displayName}" \u2192 "${newDisplayName}" in ${pool.name}`);
1526
+ }
1527
+ }
1528
+ }
1529
+ return fixed;
1530
+ }
1531
+ function fixEventPropNameInvalid(draft, errors) {
1532
+ const invalidNames = /* @__PURE__ */ new Set();
1533
+ for (const error of errors) {
1534
+ if (error.errorType === "event_prop_name_invalid") {
1535
+ invalidNames.add(error.value);
1536
+ }
1537
+ }
1538
+ for (const prop of draft.event_properties) {
1539
+ if (invalidNames.has(prop.name)) {
1540
+ const fixedName = prop.name.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase();
1541
+ const oldName = prop.name;
1542
+ prop.name = fixedName;
1543
+ for (const event of draft.events) {
1544
+ const idx = event.prop_names.indexOf(oldName);
1545
+ if (idx >= 0) {
1546
+ event.prop_names[idx] = fixedName;
1547
+ }
1548
+ }
1549
+ if (prop.display_name && !prop.display_name.includes("(")) {
1550
+ prop.display_name = `${prop.display_name}${t("fix.auto_fix_suffix")}`;
1551
+ }
1552
+ }
1553
+ }
1554
+ }
1555
+ function fixEventNameDuplicate(draft, errors) {
1556
+ const duplicateEvents = /* @__PURE__ */ new Set();
1557
+ for (const error of errors) {
1558
+ if (error.errorType === "event_name_duplicate") {
1559
+ duplicateEvents.add(error.value);
1560
+ }
1561
+ }
1562
+ const seen = /* @__PURE__ */ new Set();
1563
+ draft.events = draft.events.filter((event) => {
1564
+ if (duplicateEvents.has(event.event_name)) {
1565
+ if (seen.has(event.event_name)) {
1566
+ return false;
1567
+ }
1568
+ seen.add(event.event_name);
1569
+ }
1570
+ return true;
1571
+ });
1572
+ }
1573
+ function fixDraft(draft, response) {
1574
+ const errors = extractErrors(response);
1575
+ const fixed = [];
1576
+ if (errors.length === 0) {
1577
+ return fixed;
1578
+ }
1579
+ const errorTypes = new Set(errors.map((e) => e.errorType));
1580
+ if (errorTypes.has("event_prop_display_duplicate")) {
1581
+ fixDisplayDuplicate(draft, errors);
1582
+ fixed.push(t("fix.display_name_dedup"));
1583
+ }
1584
+ if (errorTypes.has("complex_event_property_should_has_same_child_property")) {
1585
+ fixArrayRowConsistency(draft, errors);
1586
+ fixed.push(t("fix.array_row_consistency"));
1587
+ }
1588
+ if (errorTypes.has("event_prop_name_invalid")) {
1589
+ fixEventPropNameInvalid(draft, errors);
1590
+ fixed.push(t("fix.event_prop_name_invalid"));
1591
+ }
1592
+ if (errorTypes.has("event_name_duplicate")) {
1593
+ fixEventNameDuplicate(draft, errors);
1594
+ fixed.push(t("fix.event_name_duplicate"));
1595
+ }
1596
+ return fixed;
1597
+ }
1598
+ function validateAndFix(draft) {
1599
+ const fixed = [];
1600
+ const unknownFixes = fixUnknownPropRefs(draft);
1601
+ if (unknownFixes.length > 0) {
1602
+ fixed.push(t("fix.unknown_prop_ref"));
1603
+ }
1604
+ const displayFixes = fixDisplayNameDuplicates(draft);
1605
+ if (displayFixes.length > 0) {
1606
+ fixed.push(t("fix.display_name_dedup"));
1607
+ }
1608
+ const compositeChildren = /* @__PURE__ */ new Map();
1609
+ const evProps = draft.event_properties ?? draft.common_properties ?? [];
1610
+ for (const prop of evProps) {
1611
+ if (prop.type === "array_row" || prop.type === "object") {
1612
+ compositeChildren.set(prop.name, []);
1613
+ }
1614
+ }
1615
+ for (const prop of evProps) {
1616
+ if (prop.name.includes(".")) {
1617
+ const parent = prop.name.split(".")[0];
1618
+ const children = compositeChildren.get(parent);
1619
+ if (children) {
1620
+ children.push(prop.name);
1621
+ }
1622
+ }
1623
+ }
1624
+ let needFix = false;
1625
+ for (const event of draft.events) {
1626
+ if (!event.prop_names) continue;
1627
+ for (const [parentName, children] of compositeChildren) {
1628
+ if (event.prop_names.includes(parentName)) {
1629
+ for (const child of children) {
1630
+ if (!event.prop_names.includes(child)) {
1631
+ needFix = true;
1632
+ }
1633
+ }
1634
+ }
1635
+ }
1636
+ }
1637
+ if (needFix) {
1638
+ fixArrayRowConsistency(draft, []);
1639
+ fixed.push(t("fix.array_row_consistency"));
1640
+ }
1641
+ return fixed;
1642
+ }
1643
+
1644
+ // src/tracking/plan/conflict.ts
1645
+ function detectConflicts(newDraft, existingDraft) {
1646
+ const conflicts = [];
1647
+ for (const newProp of newDraft.event_properties) {
1648
+ const existingProp = existingDraft.event_properties.find((p) => p.name === newProp.name);
1649
+ if (existingProp && existingProp.type !== newProp.type) {
1650
+ conflicts.push({
1651
+ type: "property_type_conflict",
1652
+ severity: "error",
1653
+ name: newProp.name,
1654
+ existingType: existingProp.type,
1655
+ newType: newProp.type
1656
+ });
1657
+ }
1658
+ }
1659
+ for (const newProp of newDraft.common_event_properties) {
1660
+ const existingProp = existingDraft.common_event_properties.find((p) => p.name === newProp.name);
1661
+ if (existingProp && existingProp.type !== newProp.type) {
1662
+ conflicts.push({
1663
+ type: "property_type_conflict",
1664
+ severity: "error",
1665
+ name: newProp.name,
1666
+ existingType: existingProp.type,
1667
+ newType: newProp.type
1668
+ });
1669
+ }
1670
+ }
1671
+ for (const newProp of newDraft.user_properties) {
1672
+ const existingProp = existingDraft.user_properties.find((p) => p.name === newProp.name);
1673
+ if (existingProp && existingProp.type !== newProp.type) {
1674
+ conflicts.push({
1675
+ type: "property_type_conflict",
1676
+ severity: "error",
1677
+ name: newProp.name,
1678
+ existingType: existingProp.type,
1679
+ newType: newProp.type
1680
+ });
1681
+ }
1682
+ }
1683
+ for (const newEvent of newDraft.events) {
1684
+ const existingEvent = existingDraft.events.find((e) => e.event_name === newEvent.event_name);
1685
+ if (existingEvent) {
1686
+ conflicts.push({
1687
+ type: "event_exists",
1688
+ severity: "warning",
1689
+ name: newEvent.event_name,
1690
+ existingPropCount: existingEvent.prop_names.length,
1691
+ newPropCount: newEvent.prop_names.length
1692
+ });
1693
+ }
1694
+ }
1695
+ return {
1696
+ hasErrors: conflicts.some((c) => c.severity === "error"),
1697
+ hasWarnings: conflicts.some((c) => c.severity === "warning"),
1698
+ conflicts
1699
+ };
1700
+ }
1701
+ function formatConflictReport(result, existingSummary) {
1702
+ const lines = [];
1703
+ lines.push(t("conflict.existing_plan_title"));
1704
+ lines.push(t("conflict.events_count", { count: existingSummary.events }));
1705
+ lines.push(t("conflict.event_props_count", { count: existingSummary.eventProps }));
1706
+ lines.push(t("conflict.common_props_count", { count: existingSummary.commonProps }));
1707
+ lines.push(t("conflict.user_props_count", { count: existingSummary.userProps }));
1708
+ lines.push("");
1709
+ if (result.hasErrors) {
1710
+ lines.push(t("conflict.severe_conflict_title"));
1711
+ lines.push("");
1712
+ lines.push(t("conflict.type_conflict_explanation"));
1713
+ lines.push("");
1714
+ lines.push(t("conflict.type_conflict_table_header"));
1715
+ lines.push("|---|---|---|");
1716
+ for (const c of result.conflicts.filter((c2) => c2.type === "property_type_conflict")) {
1717
+ lines.push(`| ${c.name} | ${c.existingType} | ${c.newType} |`);
1718
+ }
1719
+ lines.push("");
1720
+ lines.push(t("conflict.suggestion"));
1721
+ lines.push(t("conflict.suggestion_fix_types"));
1722
+ lines.push(t("conflict.suggestion_use_replace"));
1723
+ }
1724
+ if (result.hasWarnings && !result.hasErrors) {
1725
+ lines.push(t("conflict.warning_event_exists_title"));
1726
+ lines.push("");
1727
+ for (const c of result.conflicts.filter((c2) => c2.type === "event_exists")) {
1728
+ lines.push(t("conflict.event_exists_detail", { name: c.name, existingCount: c.existingPropCount ?? 0, newCount: c.newPropCount ?? 0 }));
1729
+ }
1730
+ lines.push("");
1731
+ lines.push(t("conflict.append_note"));
1732
+ lines.push(t("conflict.append_note_1"));
1733
+ lines.push(t("conflict.append_note_2"));
1734
+ lines.push(t("conflict.append_note_3"));
1735
+ }
1736
+ return lines.join("\n");
1737
+ }
1738
+
1739
+ // src/commands/tracking/plan.ts
1740
+ import { readdir } from "fs/promises";
1741
+ import { existsSync as existsSync4 } from "fs";
1742
+
1743
+ // src/commands/tracking/shared.ts
1744
+ import { existsSync as existsSync3, statSync } from "fs";
1745
+ var HOST_OPTION_DESC = "Override active AE host URL";
1746
+ function resolveTrackingHost(program2, opts) {
1747
+ const root = program2.root ?? program2;
1748
+ const globalHost = root.opts()?.host;
1749
+ const host = resolveHost(opts.host || globalHost);
1750
+ if (!host) {
1751
+ throw new Error("No active AE host configured. Run: ae-cli auth login");
1752
+ }
1753
+ return host;
1754
+ }
1755
+ function isExistingDirectory(path5) {
1756
+ if (!existsSync3(path5)) return false;
1757
+ try {
1758
+ return statSync(path5).isDirectory();
1759
+ } catch {
1760
+ return false;
1761
+ }
1762
+ }
1763
+ function assertOutputFilePath(path5, optionName = "--out") {
1764
+ const trimmed = path5.trim();
1765
+ if (trimmed.endsWith("/") || trimmed.endsWith("\\") || isExistingDirectory(trimmed)) {
1766
+ console.error(t("error.output_path_is_directory", { path: trimmed, option: optionName }));
1767
+ process.exit(1);
1768
+ }
1769
+ }
1770
+ function assertInputFilePath(path5, optionName = "--in") {
1771
+ const trimmed = path5.trim();
1772
+ if (!existsSync3(trimmed)) {
1773
+ console.error(t("error.input_path_not_found", { path: trimmed, option: optionName }));
1774
+ process.exit(1);
1775
+ }
1776
+ if (isExistingDirectory(trimmed)) {
1777
+ console.error(t("error.input_path_is_directory", { path: trimmed, option: optionName }));
1778
+ process.exit(1);
1779
+ }
1780
+ }
1781
+
1782
+ // src/commands/tracking/plan.ts
1783
+ var MAX_FIX_RETRIES = 3;
1784
+ var TEMPLATE_DIRS = [
1785
+ resolve(getPackageRoot(), "tracking-plan-template"),
1786
+ resolve(getConfigDir(), "templates")
1787
+ ];
1788
+ function registerPlan(cmd, rootProgram) {
1789
+ cmd.description("manage AE tracking plans");
1790
+ cmd.command("draft").description("Generate xlsx from draft.json (inject autotrack events; use --fix to auto-repair validation errors)").requiredOption("--in <path>", "draft JSON input").requiredOption("--out <path>", "xlsx output").option("--fix", "auto fix validation errors", false).action(async (opts) => {
1791
+ assertInputFilePath(opts.in, "--in");
1792
+ assertOutputFilePath(opts.out, "--out");
1793
+ const draft = JSON.parse(await readFile(opts.in, "utf8"));
1794
+ const locale = draft.meta.lang ?? detectCliLocale();
1795
+ injectAutotrackEvents(draft, locale);
1796
+ if (opts.fix) {
1797
+ const fixed = validateAndFix(draft);
1798
+ if (fixed.length > 0) {
1799
+ console.log(t("plan.draft_autofixed", { items: fixed.join(", ") }));
1800
+ await writeFile(opts.in, JSON.stringify(draft, null, 2), "utf8");
1801
+ }
1802
+ }
1803
+ try {
1804
+ validateDraft(draft);
1805
+ } catch (e) {
1806
+ if (!opts.fix) {
1807
+ throw e;
1808
+ }
1809
+ console.log(t("plan.draft_validation_failed_attempting_fix"));
1810
+ for (let retry = 0; retry < MAX_FIX_RETRIES; retry++) {
1811
+ const fixed = validateAndFix(draft);
1812
+ if (fixed.length === 0) {
1813
+ console.error(t("plan.no_auto_fix_available"));
1814
+ console.error(e instanceof Error ? e.message : String(e));
1815
+ process.exit(1);
1816
+ }
1817
+ console.log(t("plan.draft_fixed", { items: fixed.join(", ") }));
1818
+ await writeFile(opts.in, JSON.stringify(draft, null, 2), "utf8");
1819
+ try {
1820
+ validateDraft(draft);
1821
+ break;
1822
+ } catch (retryErr) {
1823
+ if (retry === MAX_FIX_RETRIES - 1) {
1824
+ console.error(t("plan.validate_still_errors_after_fix", {
1825
+ error: retryErr instanceof Error ? retryErr.message : String(retryErr)
1826
+ }));
1827
+ console.error(t("plan.max_fix_retries"));
1828
+ process.exit(1);
1829
+ }
1830
+ }
1831
+ }
1832
+ }
1833
+ await writeDraftXlsx(draft, opts.out, locale);
1834
+ const counts = `events=${draft.events.length}, event_props=${draft.event_properties.length}, common=${draft.common_event_properties.length}, user=${draft.user_properties.length}`;
1835
+ console.log(t("plan.wrote_xlsx", { path: opts.out, counts }));
1836
+ });
1837
+ cmd.command("validate").description("Validate draft.json structure and field rules").requiredOption("--in <path>", "draft JSON input").option("--fix", "auto fix validation errors", false).action(async (opts) => {
1838
+ assertInputFilePath(opts.in, "--in");
1839
+ const draft = JSON.parse(await readFile(opts.in, "utf8"));
1840
+ try {
1841
+ validateDraft(draft);
1842
+ console.log(t("plan.validate_passed"));
1843
+ } catch (e) {
1844
+ const errorMsg = e instanceof Error ? e.message : String(e);
1845
+ console.log(t("plan.validate_failed") + "\n" + errorMsg);
1846
+ if (opts.fix) {
1847
+ console.log("\n" + t("plan.attempting_auto_fix") + "...");
1848
+ const fixed = validateAndFix(draft);
1849
+ if (fixed.length > 0) {
1850
+ console.log(t("plan.fixed_items", { items: fixed.join(", ") }));
1851
+ await writeFile(opts.in, JSON.stringify(draft, null, 2), "utf8");
1852
+ console.log(t("plan.updated_file", { path: opts.in }));
1853
+ try {
1854
+ validateDraft(draft);
1855
+ console.log(t("plan.validate_passed_after_fix"));
1856
+ } catch (e2) {
1857
+ console.log(t("plan.validate_still_errors_after_fix", { error: e2 instanceof Error ? e2.message : String(e2) }));
1858
+ }
1859
+ } else {
1860
+ console.log(t("plan.no_auto_fix_available"));
1861
+ }
1862
+ }
1863
+ }
1864
+ });
1865
+ cmd.command("upload").description("Upload xlsx tracking plan to AE (conflict check, auto-fix retry, optional --switch-lang)").requiredOption("-p, --project <id>", "AE projectId", (v) => parseInt(v, 10)).requiredOption("--xlsx <path>", "xlsx file").requiredOption("--draft <path>", "draft JSON (for auto-fix)").option("--host <url>", HOST_OPTION_DESC).option("--lang <locale>", "xlsx language: zh / en / ja / ko").option("--replace", "delete existing plan first", false).option("--auto-fix", "auto fix upload errors and retry", true).option("--switch-lang", "auto switch AE project language to match xlsx", false).action(async (opts) => {
1866
+ assertInputFilePath(opts.draft, "--draft");
1867
+ assertInputFilePath(opts.xlsx, "--xlsx");
1868
+ const host = resolveTrackingHost(rootProgram, opts);
1869
+ let client = await createTrackingClient(host);
1870
+ const draftPre = JSON.parse(await readFile(opts.draft, "utf8"));
1871
+ const xlsxLocale = opts.lang ?? draftPre.meta.lang ?? detectCliLocale();
1872
+ const aeLocale = await client.getServerLang();
1873
+ if (aeLocale && aeLocale !== xlsxLocale) {
1874
+ console.log("\n" + t("plan.ae_lang_mismatch", { aeLang: aeLocale, xlsxLang: xlsxLocale }));
1875
+ if (opts.switchLang) {
1876
+ const aeLangCode = cliLocaleToAE(xlsxLocale);
1877
+ await client.saveUserAutoConfig(aeLangCode);
1878
+ console.log(t("plan.ae_lang_switched", { aeLang: aeLangCode }));
1879
+ await new Promise((r) => setTimeout(r, 2e3));
1880
+ client = await createTrackingClient(host);
1881
+ } else {
1882
+ console.log(t("plan.ae_lang_switch_hint"));
1883
+ process.exit(13);
1884
+ }
1885
+ }
1886
+ if (!opts.replace) {
1887
+ console.log(t("plan.checking_conflicts"));
1888
+ try {
1889
+ const existingDraft = await fetchPlan({ projectId: opts.project, host });
1890
+ const conflictResult = detectConflicts(draftPre, existingDraft);
1891
+ if (conflictResult.hasErrors) {
1892
+ const existingSummary = {
1893
+ events: existingDraft.events.length,
1894
+ eventProps: existingDraft.event_properties.length,
1895
+ commonProps: existingDraft.common_event_properties.length,
1896
+ userProps: existingDraft.user_properties.length
1897
+ };
1898
+ console.log("\n" + formatConflictReport(conflictResult, existingSummary));
1899
+ console.log("\n" + t("plan.cannot_append_mode"));
1900
+ return;
1901
+ }
1902
+ if (conflictResult.hasWarnings) {
1903
+ const existingSummary = {
1904
+ events: existingDraft.events.length,
1905
+ eventProps: existingDraft.event_properties.length,
1906
+ commonProps: existingDraft.common_event_properties.length,
1907
+ userProps: existingDraft.user_properties.length
1908
+ };
1909
+ console.log("\n" + formatConflictReport(conflictResult, existingSummary));
1910
+ console.log("\n" + t("plan.append_continue_note") + "\n");
1911
+ }
1912
+ } catch (e) {
1913
+ const errorMsg = e instanceof Error ? e.message : String(e);
1914
+ if (errorMsg.includes("return_code -1001") || errorMsg.includes("token expired") || errorMsg.includes("Session expired")) {
1915
+ console.log(t("plan.token_expired_refreshing"));
1916
+ client = await createTrackingClient(host);
1917
+ } else {
1918
+ console.log(t("plan.no_existing_plan"));
1919
+ }
1920
+ }
1921
+ }
1922
+ if (opts.replace) {
1923
+ const del = await client.deleteProgram(opts.project);
1924
+ console.log(t("plan.deleted_existing_plan", { message: del.return_message }));
1925
+ await new Promise((resolve2) => setTimeout(resolve2, 5e3));
1926
+ }
1927
+ let retryCount = 0;
1928
+ let draft = JSON.parse(await readFile(opts.draft, "utf8"));
1929
+ const locale = opts.lang ?? draft.meta.lang ?? "zh";
1930
+ let tokenRefreshed = false;
1931
+ let lastRes = null;
1932
+ while (retryCount < MAX_FIX_RETRIES) {
1933
+ const file = await readFile(opts.xlsx);
1934
+ lastRes = await client.uploadProgramExcel({
1935
+ projectId: opts.project,
1936
+ file,
1937
+ filename: path3.basename(opts.xlsx)
1938
+ });
1939
+ console.log(JSON.stringify(lastRes, null, 2));
1940
+ if (lastRes.return_code === -1001 && !tokenRefreshed) {
1941
+ console.log("[auth] token expired during upload, refreshing session...");
1942
+ client = await createTrackingClient(host);
1943
+ tokenRefreshed = true;
1944
+ continue;
1945
+ }
1946
+ const errors = extractErrors(lastRes);
1947
+ if (errors.length === 0 || lastRes.return_code !== 0) {
1948
+ break;
1949
+ }
1950
+ if (!opts.autoFix) {
1951
+ console.log("\n" + t("plan.upload_has_validation_errors"));
1952
+ break;
1953
+ }
1954
+ console.log("\n" + t("plan.auto_fixing_retry", { current: retryCount + 1, max: MAX_FIX_RETRIES }) + "...");
1955
+ const fixed = fixDraft(draft, lastRes);
1956
+ if (fixed.length === 0) {
1957
+ console.log(t("plan.no_auto_fix_upload"));
1958
+ break;
1959
+ }
1960
+ console.log(t("plan.fixed_items", { items: fixed.join(", ") }));
1961
+ await writeFile(opts.draft, JSON.stringify(draft, null, 2), "utf8");
1962
+ injectAutotrackEvents(draft, locale);
1963
+ await writeDraftXlsx(draft, opts.xlsx, locale);
1964
+ console.log(t("plan.regenerated_xlsx", { path: opts.xlsx }));
1965
+ retryCount++;
1966
+ }
1967
+ if (retryCount >= MAX_FIX_RETRIES) {
1968
+ console.log("\n" + t("plan.max_fix_retries"));
1969
+ }
1970
+ const msg = lastRes?.return_message ?? "";
1971
+ const isLangMismatch = msg.includes("\u65E0\u6CD5\u8BC6\u522B\u8868\u683C\u5185\u5BB9") || msg.includes("The content of the form cannot be recognized") || msg.includes("\u30C6\u30FC\u30D6\u30EB\u306E\u5185\u5BB9\u3092\u8A8D\u8B58\u3067\u304D\u307E\u305B\u3093") || msg.includes("\uD2B8\uB798\uD0B9 \uBC29\uC548\uC744 \uC2E4\uBCC4 \uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1972
+ if (lastRes && lastRes.return_code !== 0 && isLangMismatch) {
1973
+ const xlsxLocale2 = opts.lang ?? draft.meta.lang ?? detectCliLocale();
1974
+ console.log("\n" + t("plan.language_mismatch_hint", { locale: xlsxLocale2 }));
1975
+ }
1976
+ });
1977
+ cmd.command("fetch").description("Fetch tracking plan from AE and output draft.json").requiredOption("-p, --project <id>", "AE projectId", (v) => parseInt(v, 10)).option("--host <url>", HOST_OPTION_DESC).option("--out <path>", "write to file instead of stdout").action(async (opts) => {
1978
+ if (opts.out) assertOutputFilePath(opts.out, "--out");
1979
+ const host = resolveTrackingHost(rootProgram, opts);
1980
+ const draft = await fetchPlan({ projectId: opts.project, host });
1981
+ const s = JSON.stringify(draft, null, 2) + "\n";
1982
+ if (opts.out) {
1983
+ await writeFile(opts.out, s, "utf8");
1984
+ } else process.stdout.write(s);
1985
+ });
1986
+ cmd.command("archive").description("Copy draft.xlsx to plans/ and record archive metadata in draft.json").requiredOption("--draft <path>", "draft.json path").requiredOption("--xlsx <path>", "draft.xlsx path").requiredOption("--name <name>", "plan name for filename").option("--plans-dir <dir>", "plans output directory", resolve(process.cwd(), "plans")).action(async (opts) => {
1987
+ assertInputFilePath(opts.draft, "--draft");
1988
+ assertInputFilePath(opts.xlsx, "--xlsx");
1989
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1990
+ const dest = resolve(opts.plansDir, `${stamp}-${opts.name}.xlsx`);
1991
+ if (existsSync4(dest)) {
1992
+ console.error(t("plan.archive_exists", { path: dest }));
1993
+ console.error(t("plan.remove_or_rename"));
1994
+ return;
1995
+ }
1996
+ try {
1997
+ await cp(opts.xlsx, dest);
1998
+ } catch (e) {
1999
+ if (e.code === "EEXIST") {
2000
+ console.error(t("plan.archive_exists", { path: dest }));
2001
+ console.error(t("plan.remove_or_rename"));
2002
+ return;
2003
+ }
2004
+ throw e;
2005
+ }
2006
+ const draft = JSON.parse(await readFile(opts.draft, "utf8"));
2007
+ draft.meta.archived_at = stamp;
2008
+ draft.meta.archived_path = dest;
2009
+ await writeFile(opts.draft, JSON.stringify(draft, null, 2), "utf8");
2010
+ console.log(t("plan.archived_to", { path: dest }));
2011
+ console.log(t("plan.draft_updated_archived", { stamp }));
2012
+ });
2013
+ cmd.command("delete").description("Delete the entire tracking plan from an AE project").requiredOption("-p, --project <id>", "AE projectId", (v) => parseInt(v, 10)).option("--host <url>", HOST_OPTION_DESC).action(async (opts) => {
2014
+ const host = resolveTrackingHost(rootProgram, opts);
2015
+ const client = await createTrackingClient(host);
2016
+ const res = await client.deleteProgram(opts.project);
2017
+ console.log(JSON.stringify(res, null, 2));
2018
+ });
2019
+ cmd.command("list-templates").description("List bundled and user tracking plan templates (xlsx/md)").action(async () => {
2020
+ const found = [];
2021
+ for (const dir of TEMPLATE_DIRS) {
2022
+ if (!existsSync4(dir)) continue;
2023
+ let entries = [];
2024
+ try {
2025
+ entries = await readdir(dir);
2026
+ } catch {
2027
+ continue;
2028
+ }
2029
+ for (const f of entries) {
2030
+ if (!f.endsWith(".xlsx")) continue;
2031
+ const base = f.replace(/\.xlsx$/i, "");
2032
+ const mdPath = resolve(dir, base + ".md");
2033
+ const hasMd = existsSync4(mdPath);
2034
+ found.push({
2035
+ path: hasMd ? mdPath : resolve(dir, f),
2036
+ name: base,
2037
+ hasMd
2038
+ });
2039
+ }
2040
+ }
2041
+ if (found.length === 0) {
2042
+ console.log(t("plan.no_templates_found", { dirs: TEMPLATE_DIRS.join(", ") }));
2043
+ return;
2044
+ }
2045
+ console.log(t("plan.templates_found", { count: found.length }) + "\n");
2046
+ for (const tmpl of found) {
2047
+ const mdNote = tmpl.hasMd ? t("plan.template_md_label") : t("plan.template_xlsx_label");
2048
+ console.log(` ${tmpl.name}${mdNote}`);
2049
+ console.log(` ${tmpl.path}`);
2050
+ }
2051
+ });
2052
+ }
2053
+
2054
+ // src/commands/tracking/code.ts
2055
+ import { readFile as readFile4, writeFile as writeFile2, mkdir } from "fs/promises";
2056
+ import { dirname as dirname2 } from "path";
2057
+
2058
+ // src/tracking/project-detect/detect.ts
2059
+ import { readFile as readFile2, readdir as readdir2, stat } from "fs/promises";
2060
+ import { join as join3 } from "path";
2061
+ async function exists(p) {
2062
+ try {
2063
+ await stat(p);
2064
+ return true;
2065
+ } catch {
2066
+ return false;
2067
+ }
2068
+ }
2069
+ async function readJson(p) {
2070
+ try {
2071
+ return JSON.parse(await readFile2(p, "utf8"));
2072
+ } catch {
2073
+ return null;
2074
+ }
2075
+ }
2076
+ async function classifyDir(cwd) {
2077
+ if (await exists(join3(cwd, "project.config.json"))) {
2078
+ const cfg = await readJson(join3(cwd, "project.config.json"));
2079
+ if (cfg && "miniprogramRoot" in cfg) return "mini-program";
2080
+ }
2081
+ if (await exists(join3(cwd, "ProjectSettings/ProjectVersion.txt"))) return "unity";
2082
+ if (await exists(join3(cwd, "Podfile"))) return "ios";
2083
+ if (await exists(join3(cwd, "build.gradle")) || await exists(join3(cwd, "settings.gradle"))) return "android";
2084
+ const pkg2 = await readJson(join3(cwd, "package.json"));
2085
+ if (pkg2) {
2086
+ const deps = { ...pkg2.dependencies ?? {}, ...pkg2.devDependencies ?? {} };
2087
+ if (deps.astro) return "web-astro";
2088
+ if (deps.next) return "web-nextjs";
2089
+ if (deps.react) return "web-react";
2090
+ if (deps.vue) return "web-vue";
2091
+ if (deps.express || deps.fastify || deps.koa) return "node-server";
2092
+ return "web-vanilla";
2093
+ }
2094
+ if (await exists(join3(cwd, "go.mod"))) return "go-server";
2095
+ if (await exists(join3(cwd, "pom.xml"))) return "java-server";
2096
+ if (await exists(join3(cwd, "pyproject.toml")) || await exists(join3(cwd, "requirements.txt"))) return "python-server";
2097
+ return "unknown";
2098
+ }
2099
+ async function classify(cwd) {
2100
+ const direct = await classifyDir(cwd);
2101
+ if (direct !== "unknown") return { appType: direct, subPath: void 0 };
2102
+ let entries;
2103
+ try {
2104
+ entries = await readdir2(cwd, { withFileTypes: true });
2105
+ } catch {
2106
+ return { appType: "unknown", subPath: void 0 };
2107
+ }
2108
+ const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules").slice(0, 20);
2109
+ let vanillaMatch;
2110
+ for (const d of dirs) {
2111
+ const sub = await classifyDir(join3(cwd, d.name));
2112
+ if (sub !== "unknown" && sub !== "web-vanilla") {
2113
+ return { appType: sub, subPath: d.name };
2114
+ }
2115
+ if (sub === "web-vanilla" && !vanillaMatch) {
2116
+ vanillaMatch = { appType: sub, subPath: d.name };
2117
+ }
2118
+ }
2119
+ if (vanillaMatch) return vanillaMatch;
2120
+ return { appType: "unknown", subPath: void 0 };
2121
+ }
2122
+ function recommend(appType) {
2123
+ switch (appType) {
2124
+ case "web-react":
2125
+ case "web-vue":
2126
+ case "web-nextjs":
2127
+ case "web-vanilla":
2128
+ case "web-astro":
2129
+ case "ios":
2130
+ case "android":
2131
+ case "mini-program":
2132
+ case "unity":
2133
+ return ["A", "F"];
2134
+ case "node-server":
2135
+ case "python-server":
2136
+ case "go-server":
2137
+ case "java-server":
2138
+ return ["E", "F"];
2139
+ case "unknown":
2140
+ default:
2141
+ return ["B", "E"];
2142
+ }
2143
+ }
2144
+ async function detectProject(cwd) {
2145
+ const { appType, subPath } = await classify(cwd);
2146
+ return {
2147
+ appType,
2148
+ subPath,
2149
+ entryFiles: [],
2150
+ existingTracking: [],
2151
+ recommendedModes: recommend(appType)
2152
+ };
2153
+ }
2154
+
2155
+ // src/tracking/xlsx/read.ts
2156
+ import XLSXMod from "xlsx";
2157
+ import path4 from "path";
2158
+ var XLSX = XLSXMod.default ?? XLSXMod;
2159
+ var VALID_PROP_TYPES2 = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
2160
+ var VALID_UPDATE_TYPES2 = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
2161
+ function normalizeHeader(h) {
2162
+ return h.trim().replace(/[((]\s*(?:必填|必須|필수|required|Required)\s*[))]/g, "").trim().replace(/名称$/g, "\u540D");
2163
+ }
2164
+ function buildHeaderMap(headerRow) {
2165
+ const map = /* @__PURE__ */ new Map();
2166
+ headerRow.forEach((cell, i) => {
2167
+ if (cell === null || cell === void 0) return;
2168
+ const norm = normalizeHeader(String(cell));
2169
+ if (norm !== "") {
2170
+ map.set(norm, i);
2171
+ }
2172
+ });
2173
+ return map;
2174
+ }
2175
+ function colIdx(headerMap, ...candidates) {
2176
+ for (const c of candidates) {
2177
+ const norm = normalizeHeader(c);
2178
+ if (headerMap.has(norm)) return headerMap.get(norm);
2179
+ }
2180
+ return -1;
2181
+ }
2182
+ function cellStr(row, idx) {
2183
+ if (idx < 0 || idx >= row.length) return "";
2184
+ const v = row[idx];
2185
+ if (v === null || v === void 0) return "";
2186
+ return String(v).trim();
2187
+ }
2188
+ function parsePropType(raw, propName, sheetCtx) {
2189
+ const canonical = displayToType(raw);
2190
+ if (canonical) return canonical;
2191
+ if (VALID_PROP_TYPES2.has(raw)) return raw;
2192
+ process.stderr.write(
2193
+ `[read] unknown type "${raw}" on ${sheetCtx}:${propName}, defaulting to string
2194
+ `
2195
+ );
2196
+ return "string";
2197
+ }
2198
+ function parseUpdateType(raw, propName) {
2199
+ if (VALID_UPDATE_TYPES2.has(raw)) return raw;
2200
+ process.stderr.write(
2201
+ `[xlsx/read] Warning: unknown update_type "${raw}" for user property "${propName}", falling back to "user_set"
2202
+ `
2203
+ );
2204
+ return "user_set";
2205
+ }
2206
+ function shouldSkipRow(row, firstColIdx) {
2207
+ const first = cellStr(row, firstColIdx);
2208
+ if (!first) return true;
2209
+ if (!/^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(first)) return true;
2210
+ return false;
2211
+ }
2212
+ function parseEventSheet(rows, source, sheetName2) {
2213
+ const eventsMap = /* @__PURE__ */ new Map();
2214
+ const propsMap = /* @__PURE__ */ new Map();
2215
+ const eventsOrder = [];
2216
+ if (rows.length < 2) return { events: [], event_properties: [] };
2217
+ const headerRow = rows[0];
2218
+ const hMap = buildHeaderMap(headerRow);
2219
+ let eventNameCol = colIdx(hMap, ...allHeaderNames("event_name"), "\u4E8B\u4EF6\u540D\u79F0");
2220
+ let eventDisplayCol = colIdx(hMap, ...allHeaderNames("event_display_name"));
2221
+ let eventDescCol = colIdx(hMap, ...allHeaderNames("event_desc"));
2222
+ let eventTagCol = colIdx(hMap, ...allHeaderNames("event_tag"));
2223
+ let eventPlatformCol = colIdx(hMap, ...allHeaderNames("platform"));
2224
+ let propNameCol = colIdx(hMap, ...allHeaderNames("prop_name"), "\u5C5E\u6027\u540D\u79F0");
2225
+ let propDisplayCol = colIdx(hMap, ...allHeaderNames("prop_display_name"));
2226
+ let propTypeCol = colIdx(hMap, ...allHeaderNames("prop_type"));
2227
+ let propDescCol = colIdx(hMap, ...allHeaderNames("prop_desc"));
2228
+ if (eventNameCol === -1 && eventDisplayCol !== -1) {
2229
+ const candidateCol = eventDisplayCol - 1;
2230
+ if (candidateCol >= 0) {
2231
+ const candidateHeader = headerRow[candidateCol];
2232
+ if (candidateHeader === null || candidateHeader === "" || candidateHeader === void 0) {
2233
+ eventNameCol = candidateCol;
2234
+ }
2235
+ }
2236
+ }
2237
+ if (eventNameCol === -1) {
2238
+ eventNameCol = hMap.has(normalizeHeader("\u4E8B\u4EF6\u6A21\u5757")) ? 1 : 0;
2239
+ }
2240
+ if (propNameCol === -1 && propDisplayCol !== -1) {
2241
+ const candidateCol = propDisplayCol - 1;
2242
+ if (candidateCol >= 0) {
2243
+ const candidateHeader = headerRow[candidateCol];
2244
+ if (candidateHeader === null || candidateHeader === "" || candidateHeader === void 0) {
2245
+ propNameCol = candidateCol;
2246
+ }
2247
+ }
2248
+ }
2249
+ if (propTypeCol === -1 && propDisplayCol !== -1 && propDescCol !== -1) {
2250
+ const candidateCol = propDescCol - 1;
2251
+ if (candidateCol > propDisplayCol) {
2252
+ const candidateHeader = headerRow[candidateCol];
2253
+ if (candidateHeader === null || candidateHeader === "" || candidateHeader === void 0) {
2254
+ propTypeCol = candidateCol;
2255
+ }
2256
+ }
2257
+ }
2258
+ if (propNameCol === -1) {
2259
+ propNameCol = hMap.has(normalizeHeader("\u4E8B\u4EF6\u6A21\u5757")) ? 4 : 4;
2260
+ }
2261
+ if (propTypeCol === -1) {
2262
+ propTypeCol = hMap.has(normalizeHeader("\u4E8B\u4EF6\u6A21\u5757")) ? 6 : 6;
2263
+ }
2264
+ const isIdent = (s) => /^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(s);
2265
+ let lastEventName = "";
2266
+ for (let i = 1; i < rows.length; i++) {
2267
+ let parsePlatform2 = function(raw) {
2268
+ if (!raw) return void 0;
2269
+ const normalized = raw.trim().toLowerCase();
2270
+ if (normalized === "client" || normalized === "server" || normalized === "both") {
2271
+ return normalized;
2272
+ }
2273
+ if (normalized.includes("client") && normalized.includes("server")) return "both";
2274
+ if (normalized.includes("\u5BA2\u6237\u7AEF") && normalized.includes("\u670D\u52A1\u7AEF")) return "both";
2275
+ if (normalized.includes("\u670D\u52A1\u7AEF")) return "server";
2276
+ if (normalized.includes("\u5BA2\u6237\u7AEF")) return "client";
2277
+ return void 0;
2278
+ };
2279
+ var parsePlatform = parsePlatform2;
2280
+ const row = rows[i];
2281
+ const rawEventName = cellStr(row, eventNameCol);
2282
+ const propName = propNameCol >= 0 ? cellStr(row, propNameCol) : "";
2283
+ if (!rawEventName && !propName) continue;
2284
+ if (rawEventName && !isIdent(rawEventName)) continue;
2285
+ const eventName = rawEventName || lastEventName;
2286
+ if (!eventName) continue;
2287
+ const eventDisplayName = rawEventName && eventDisplayCol >= 0 ? cellStr(row, eventDisplayCol) : "";
2288
+ const eventDesc = rawEventName && eventDescCol >= 0 ? cellStr(row, eventDescCol) : "";
2289
+ const eventTag = rawEventName && eventTagCol >= 0 ? cellStr(row, eventTagCol) : "";
2290
+ const eventPlatformRaw = rawEventName && eventPlatformCol >= 0 ? cellStr(row, eventPlatformCol) : "";
2291
+ const propDisplayName = propDisplayCol >= 0 ? cellStr(row, propDisplayCol) : "";
2292
+ const propTypeRaw = propTypeCol >= 0 ? cellStr(row, propTypeCol) : "";
2293
+ const propDesc = propDescCol >= 0 ? cellStr(row, propDescCol) : "";
2294
+ if (rawEventName) lastEventName = rawEventName;
2295
+ if (!eventsMap.has(eventName)) {
2296
+ const evt = {
2297
+ event_name: eventName,
2298
+ source,
2299
+ prop_names: []
2300
+ };
2301
+ if (eventDisplayName) evt.display_name = eventDisplayName;
2302
+ if (eventDesc) evt.event_desc = eventDesc;
2303
+ if (eventTag) evt.event_tag = eventTag;
2304
+ if (eventPlatformRaw) evt.platform = parsePlatform2(eventPlatformRaw);
2305
+ eventsMap.set(eventName, evt);
2306
+ eventsOrder.push(eventName);
2307
+ }
2308
+ if (propName && /^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(propName)) {
2309
+ const evt = eventsMap.get(eventName);
2310
+ if (!evt.prop_names.includes(propName)) {
2311
+ evt.prop_names.push(propName);
2312
+ }
2313
+ if (!propsMap.has(propName)) {
2314
+ const propType = parsePropType(propTypeRaw, propName, sheetName2);
2315
+ const prop = {
2316
+ name: propName,
2317
+ type: propType,
2318
+ source
2319
+ };
2320
+ if (propDisplayName) prop.display_name = propDisplayName;
2321
+ if (propDesc) prop.desc = propDesc;
2322
+ propsMap.set(propName, prop);
2323
+ } else {
2324
+ const existing = propsMap.get(propName);
2325
+ const newType = parsePropType(propTypeRaw, propName, sheetName2);
2326
+ if (propTypeRaw && existing.type !== newType) {
2327
+ process.stderr.write(
2328
+ `[xlsx/read] Warning: property "${propName}" has conflicting types: "${existing.type}" vs "${newType}". Keeping first.
2329
+ `
2330
+ );
2331
+ }
2332
+ }
2333
+ }
2334
+ }
2335
+ const events = eventsOrder.map((name) => eventsMap.get(name));
2336
+ const event_properties = Array.from(propsMap.values());
2337
+ return { events, event_properties };
2338
+ }
2339
+ function parseCommonEventSheet(rows, source, sheetName2) {
2340
+ const props = [];
2341
+ const seen = /* @__PURE__ */ new Set();
2342
+ if (rows.length < 2) return props;
2343
+ const headerRow = rows[0];
2344
+ const hMap = buildHeaderMap(headerRow);
2345
+ let propNameCol = colIdx(hMap, ...allHeaderNames("common_prop_name"), "\u5C5E\u6027\u540D\u79F0");
2346
+ const propDisplayCol = colIdx(hMap, ...allHeaderNames("common_prop_display_name"));
2347
+ let propTypeCol = colIdx(hMap, ...allHeaderNames("common_prop_type"));
2348
+ const propDescCol = colIdx(hMap, ...allHeaderNames("common_prop_desc"));
2349
+ if (propNameCol === -1 && propDisplayCol !== -1) {
2350
+ const candidateCol = propDisplayCol - 1;
2351
+ if (candidateCol >= 0) {
2352
+ const h = headerRow[candidateCol];
2353
+ if (h === null || h === "" || h === void 0) propNameCol = candidateCol;
2354
+ }
2355
+ }
2356
+ if (propNameCol === -1) propNameCol = 0;
2357
+ if (propTypeCol === -1 && propDisplayCol !== -1 && propDescCol !== -1) {
2358
+ const candidateCol = propDescCol - 1;
2359
+ if (candidateCol > propDisplayCol) {
2360
+ const h = headerRow[candidateCol];
2361
+ if (h === null || h === "" || h === void 0) propTypeCol = candidateCol;
2362
+ }
2363
+ }
2364
+ if (propTypeCol === -1 && propDisplayCol !== -1) {
2365
+ const candidateCol = propDisplayCol + 1;
2366
+ if (candidateCol < headerRow.length) {
2367
+ const h = headerRow[candidateCol];
2368
+ if (h === null || h === "" || h === void 0) propTypeCol = candidateCol;
2369
+ }
2370
+ }
2371
+ if (propTypeCol === -1) propTypeCol = 2;
2372
+ for (let i = 1; i < rows.length; i++) {
2373
+ const row = rows[i];
2374
+ if (shouldSkipRow(row, propNameCol)) continue;
2375
+ const name = cellStr(row, propNameCol);
2376
+ const displayName = propDisplayCol >= 0 ? cellStr(row, propDisplayCol) : "";
2377
+ const typeRaw = cellStr(row, propTypeCol);
2378
+ const desc = propDescCol >= 0 ? cellStr(row, propDescCol) : "";
2379
+ if (seen.has(name)) continue;
2380
+ seen.add(name);
2381
+ const prop = {
2382
+ name,
2383
+ type: parsePropType(typeRaw, name, sheetName2),
2384
+ source
2385
+ };
2386
+ if (displayName) prop.display_name = displayName;
2387
+ if (desc) prop.desc = desc;
2388
+ props.push(prop);
2389
+ }
2390
+ return props;
2391
+ }
2392
+ function parseUserDataSheet(rows, source, sheetName2) {
2393
+ const props = [];
2394
+ const seen = /* @__PURE__ */ new Set();
2395
+ if (rows.length < 2) return props;
2396
+ const headerRow = rows[0];
2397
+ const hMap = buildHeaderMap(headerRow);
2398
+ let propNameCol = colIdx(hMap, ...allHeaderNames("user_prop_name"), "\u5C5E\u6027\u540D\u79F0");
2399
+ const propDisplayCol = colIdx(hMap, ...allHeaderNames("user_prop_display_name"));
2400
+ let propTypeCol = colIdx(hMap, ...allHeaderNames("user_prop_type"));
2401
+ const updateTypeCol = colIdx(hMap, ...allHeaderNames("update_type"));
2402
+ const propDescCol = colIdx(hMap, ...allHeaderNames("user_prop_desc"));
2403
+ const propTagCol = colIdx(hMap, ...allHeaderNames("prop_tag"));
2404
+ if (propNameCol === -1 && propDisplayCol !== -1) {
2405
+ const candidateCol = propDisplayCol - 1;
2406
+ if (candidateCol >= 0) {
2407
+ const h = headerRow[candidateCol];
2408
+ if (h === null || h === "" || h === void 0) propNameCol = candidateCol;
2409
+ }
2410
+ }
2411
+ if (propNameCol === -1) propNameCol = 0;
2412
+ if (propTypeCol === -1 && propDisplayCol !== -1 && updateTypeCol !== -1) {
2413
+ const candidateCol = updateTypeCol - 1;
2414
+ if (candidateCol > propDisplayCol) {
2415
+ const h = headerRow[candidateCol];
2416
+ if (h === null || h === "" || h === void 0) propTypeCol = candidateCol;
2417
+ }
2418
+ }
2419
+ if (propTypeCol === -1) propTypeCol = 2;
2420
+ for (let i = 1; i < rows.length; i++) {
2421
+ const row = rows[i];
2422
+ if (shouldSkipRow(row, propNameCol)) continue;
2423
+ const name = cellStr(row, propNameCol);
2424
+ const displayName = propDisplayCol >= 0 ? cellStr(row, propDisplayCol) : "";
2425
+ const typeRaw = cellStr(row, propTypeCol);
2426
+ const updateTypeRaw = updateTypeCol >= 0 ? cellStr(row, updateTypeCol) : "";
2427
+ const desc = propDescCol >= 0 ? cellStr(row, propDescCol) : "";
2428
+ const propTag = propTagCol >= 0 ? cellStr(row, propTagCol) : "";
2429
+ if (seen.has(name)) continue;
2430
+ seen.add(name);
2431
+ const prop = {
2432
+ name,
2433
+ type: parsePropType(typeRaw, name, sheetName2),
2434
+ update_type: parseUpdateType(updateTypeRaw, name),
2435
+ source
2436
+ };
2437
+ if (displayName) prop.display_name = displayName;
2438
+ if (desc) prop.desc = desc;
2439
+ if (propTag) prop.prop_tag = propTag;
2440
+ props.push(prop);
2441
+ }
2442
+ return props;
2443
+ }
2444
+ async function readTemplateXlsx(filePath) {
2445
+ let wb;
2446
+ try {
2447
+ wb = XLSX.readFile(filePath);
2448
+ } catch (err) {
2449
+ throw new Error(t("error.xlsx_read_failed", { path: filePath, error: String(err) }));
2450
+ }
2451
+ const planName = path4.basename(filePath, path4.extname(filePath));
2452
+ const source = "template";
2453
+ let events = [];
2454
+ let event_properties = [];
2455
+ let common_event_properties = [];
2456
+ let user_properties = [];
2457
+ for (const sName of wb.SheetNames) {
2458
+ if (!sName.startsWith("#")) continue;
2459
+ if (allSheetNames("user_id").includes(sName)) continue;
2460
+ const ws = wb.Sheets[sName];
2461
+ const rows = XLSX.utils.sheet_to_json(ws, {
2462
+ header: 1,
2463
+ raw: false,
2464
+ defval: null
2465
+ });
2466
+ if (allSheetNames("event_data").includes(sName)) {
2467
+ const result = parseEventSheet(rows, source, sName);
2468
+ events = result.events;
2469
+ event_properties = result.event_properties;
2470
+ } else if (allSheetNames("common_props").includes(sName)) {
2471
+ common_event_properties = parseCommonEventSheet(rows, source, sName);
2472
+ } else if (allSheetNames("user_data").includes(sName)) {
2473
+ user_properties = parseUserDataSheet(rows, source, sName);
2474
+ }
2475
+ }
2476
+ return {
2477
+ meta: {
2478
+ app_type: "",
2479
+ sdk_integration_mode: "client_only",
2480
+ plan_name: planName
2481
+ },
2482
+ events,
2483
+ event_properties,
2484
+ common_event_properties,
2485
+ user_properties
2486
+ };
2487
+ }
2488
+
2489
+ // src/tracking/xlsx/md.ts
2490
+ import { readFile as readFile3 } from "fs/promises";
2491
+ var MD_SECTIONS = {
2492
+ event_data: allSheetNames("event_data").map((s) => s.replace(/^#/, "")),
2493
+ common_props: allSheetNames("common_props").map((s) => s.replace(/^#/, "")),
2494
+ user_data: allSheetNames("user_data").map((s) => s.replace(/^#/, ""))
2495
+ };
2496
+ var MD_COL_EVENT_NAME = ["\u4E8B\u4EF6\u540D", "Event Name", "\u30A4\u30D9\u30F3\u30C8\u540D", "\uC774\uBCA4\uD2B8 \uC774\uB984"];
2497
+ var MD_COL_DISPLAY_NAME = ["\u663E\u793A\u540D", "Display Name", "\u8868\u793A\u540D", "\uD45C\uC2DC \uC774\uB984", "\u30A4\u30D9\u30F3\u30C8\u8868\u793A\u540D", "\uC774\uBCA4\uD2B8 \uD45C\uC2DC \uC774\uB984"];
2498
+ var MD_COL_DESC = ["\u8BF4\u660E", "Description", "\u8AAC\u660E", "\uC124\uBA85", "\u30A4\u30D9\u30F3\u30C8\u8AAC\u660E", "\uC774\uBCA4\uD2B8 \uC124\uBA85"];
2499
+ var MD_COL_TAG = ["\u6807\u7B7E", "Tag", "\u30BF\u30B0", "\uD0DC\uADF8", "\u30AB\u30C6\u30B4\u30EA", "\u30A4\u30D9\u30F3\u30C8 \uD0DC\uADF8"];
2500
+ var MD_COL_PLATFORM = ["\u5E73\u53F0", "Platform", "\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0", "\uD50C\uB7AB\uD3FC"];
2501
+ var MD_COL_PROP_NAME = ["\u5C5E\u6027\u540D", "Property Name", "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D", "\uC18D\uC131 \uC774\uB984"];
2502
+ var MD_COL_PROP = ["\u5C5E\u6027", "Properties", "\u30D7\u30ED\u30D1\u30C6\u30A3", "\uC18D\uC131"];
2503
+ var MD_COL_TYPE = ["\u7C7B\u578B", "Type", "\u30BF\u30A4\u30D7", "\uC720\uD615", "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7", "\uC18D\uC131 \uC720\uD615"];
2504
+ var MD_COL_UPDATE = ["\u66F4\u65B0\u65B9\u5F0F", "Update Type", "\u66F4\u65B0\u65B9\u6CD5", "\uC5C5\uB370\uC774\uD2B8 \uBC29\uC2DD"];
2505
+ function matchSection(trimmed, candidates) {
2506
+ for (const c of candidates) {
2507
+ if (trimmed === `## ${c}`) return true;
2508
+ }
2509
+ return false;
2510
+ }
2511
+ function findCol(colIndex, candidates, fallback) {
2512
+ for (const c of candidates) {
2513
+ if (colIndex[c] !== void 0) return colIndex[c];
2514
+ }
2515
+ return fallback;
2516
+ }
2517
+ var VALID_UPDATE_TYPES3 = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
2518
+ function parseType(raw) {
2519
+ const canonical = displayToType(raw);
2520
+ if (canonical) return canonical;
2521
+ return "string";
2522
+ }
2523
+ function parseUpdateType2(raw) {
2524
+ if (VALID_UPDATE_TYPES3.has(raw)) return raw;
2525
+ return "user_set";
2526
+ }
2527
+ function trimCell(s) {
2528
+ if (!s) return "";
2529
+ return s.trim();
2530
+ }
2531
+ function parseEventSection(lines) {
2532
+ const dataLines = [];
2533
+ let inSection = false;
2534
+ let headerCols = 0;
2535
+ for (const line of lines) {
2536
+ const trimmed = line.trim();
2537
+ if (matchSection(trimmed, MD_SECTIONS.event_data)) {
2538
+ inSection = true;
2539
+ continue;
2540
+ }
2541
+ if (trimmed.startsWith("## ") && inSection) break;
2542
+ if (!inSection) continue;
2543
+ if (trimmed.startsWith("|") && !trimmed.match(/^\|\s*---/)) {
2544
+ const cells = trimmed.split("|").slice(1, -1).map((c) => c.trim());
2545
+ if (headerCols === 0) headerCols = cells.length;
2546
+ dataLines.push(cells);
2547
+ }
2548
+ }
2549
+ if (dataLines.length < 2) return { events: [], event_properties: [] };
2550
+ const header = dataLines[0];
2551
+ const colIndex = {};
2552
+ header.forEach((h, i) => {
2553
+ if (h) colIndex[h] = i;
2554
+ });
2555
+ const eventNameCol = findCol(colIndex, MD_COL_EVENT_NAME, 0);
2556
+ const displayCol = findCol(colIndex, MD_COL_DISPLAY_NAME, 1);
2557
+ const descCol = findCol(colIndex, MD_COL_DESC, 2);
2558
+ const tagCol = findCol(colIndex, MD_COL_TAG, 3);
2559
+ const platformCol = findCol(colIndex, MD_COL_PLATFORM, 4);
2560
+ const propsCol = findCol(colIndex, MD_COL_PROP, 5);
2561
+ const eventsMap = /* @__PURE__ */ new Map();
2562
+ const propsMap = /* @__PURE__ */ new Map();
2563
+ const source = "template";
2564
+ for (let i = 2; i < dataLines.length; i++) {
2565
+ const cells = dataLines[i];
2566
+ if (cells.length < headerCols) continue;
2567
+ const eventName = trimCell(cells[eventNameCol]);
2568
+ if (!eventName) continue;
2569
+ const isIdent = (s) => /^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(s);
2570
+ if (!isIdent(eventName)) continue;
2571
+ const displayName = trimCell(cells[displayCol]);
2572
+ const eventDesc = trimCell(cells[descCol]);
2573
+ const eventTag = trimCell(cells[tagCol]);
2574
+ const platformRaw = trimCell(cells[platformCol]);
2575
+ const propNamesRaw = trimCell(cells[propsCol]);
2576
+ const evt = {
2577
+ event_name: eventName,
2578
+ source,
2579
+ prop_names: []
2580
+ };
2581
+ if (displayName) evt.display_name = displayName;
2582
+ if (eventDesc) evt.event_desc = eventDesc;
2583
+ if (eventTag) evt.event_tag = eventTag;
2584
+ if (platformRaw) {
2585
+ const normalized = platformRaw.toLowerCase();
2586
+ if (normalized === "client" || normalized === "server" || normalized === "both") {
2587
+ evt.platform = normalized;
2588
+ } else if (normalized.includes("client") && normalized.includes("server")) {
2589
+ evt.platform = "both";
2590
+ }
2591
+ }
2592
+ const propNames = propNamesRaw ? propNamesRaw.split(",").map((p) => p.trim()).filter((p) => isIdent(p)) : [];
2593
+ evt.prop_names = propNames;
2594
+ eventsMap.set(eventName, evt);
2595
+ for (const propName of propNames) {
2596
+ if (!propsMap.has(propName)) {
2597
+ propsMap.set(propName, { name: propName, type: "string", source });
2598
+ }
2599
+ }
2600
+ }
2601
+ return {
2602
+ events: Array.from(eventsMap.values()),
2603
+ event_properties: Array.from(propsMap.values())
2604
+ };
2605
+ }
2606
+ function parseCommonSection(lines, source) {
2607
+ const dataLines = [];
2608
+ let inSection = false;
2609
+ for (const line of lines) {
2610
+ const trimmed = line.trim();
2611
+ if (matchSection(trimmed, MD_SECTIONS.common_props)) {
2612
+ inSection = true;
2613
+ continue;
2614
+ }
2615
+ if (trimmed.startsWith("## ") && inSection) break;
2616
+ if (!inSection) continue;
2617
+ if (trimmed.startsWith("|") && !trimmed.match(/^\|\s*---/)) {
2618
+ const cells = trimmed.split("|").slice(1, -1).map((c) => c.trim());
2619
+ dataLines.push(cells);
2620
+ }
2621
+ }
2622
+ if (dataLines.length < 2) return [];
2623
+ const header = dataLines[0];
2624
+ const colIndex = {};
2625
+ header.forEach((h, i) => {
2626
+ if (h) colIndex[h] = i;
2627
+ });
2628
+ const nameCol = findCol(colIndex, MD_COL_PROP_NAME, 0);
2629
+ const displayCol = findCol(colIndex, MD_COL_DISPLAY_NAME, 1);
2630
+ const typeCol = findCol(colIndex, MD_COL_TYPE, 2);
2631
+ const descCol = findCol(colIndex, MD_COL_DESC, 3);
2632
+ const props = [];
2633
+ for (let i = 2; i < dataLines.length; i++) {
2634
+ const cells = dataLines[i];
2635
+ const name = trimCell(cells[nameCol]);
2636
+ if (!name || !/^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(name)) continue;
2637
+ props.push({
2638
+ name,
2639
+ type: parseType(trimCell(cells[typeCol])),
2640
+ source,
2641
+ display_name: trimCell(cells[displayCol]) || void 0,
2642
+ desc: trimCell(cells[descCol]) || void 0
2643
+ });
2644
+ }
2645
+ return props;
2646
+ }
2647
+ function parseUserSection(lines, source) {
2648
+ const dataLines = [];
2649
+ let inSection = false;
2650
+ for (const line of lines) {
2651
+ const trimmed = line.trim();
2652
+ if (matchSection(trimmed, MD_SECTIONS.user_data)) {
2653
+ inSection = true;
2654
+ continue;
2655
+ }
2656
+ if (trimmed.startsWith("#") && inSection) break;
2657
+ if (!inSection) continue;
2658
+ if (trimmed.startsWith("|") && !trimmed.match(/^\|\s*---/)) {
2659
+ const cells = trimmed.split("|").slice(1, -1).map((c) => c.trim());
2660
+ dataLines.push(cells);
2661
+ }
2662
+ }
2663
+ if (dataLines.length < 2) return [];
2664
+ const header = dataLines[0];
2665
+ const colIndex = {};
2666
+ header.forEach((h, i) => {
2667
+ if (h) colIndex[h] = i;
2668
+ });
2669
+ const nameCol = findCol(colIndex, MD_COL_PROP_NAME, 0);
2670
+ const displayCol = findCol(colIndex, MD_COL_DISPLAY_NAME, 1);
2671
+ const typeCol = findCol(colIndex, MD_COL_TYPE, 2);
2672
+ const updateCol = findCol(colIndex, MD_COL_UPDATE, 3);
2673
+ const descCol = findCol(colIndex, MD_COL_DESC, 4);
2674
+ const tagCol = findCol(colIndex, MD_COL_TAG, 5);
2675
+ const props = [];
2676
+ for (let i = 2; i < dataLines.length; i++) {
2677
+ const cells = dataLines[i];
2678
+ const name = trimCell(cells[nameCol]);
2679
+ if (!name || !/^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(name)) continue;
2680
+ const prop = {
2681
+ name,
2682
+ type: parseType(trimCell(cells[typeCol])),
2683
+ update_type: parseUpdateType2(trimCell(cells[updateCol])),
2684
+ source
2685
+ };
2686
+ const displayName = trimCell(cells[displayCol]);
2687
+ if (displayName) prop.display_name = displayName;
2688
+ const desc = trimCell(cells[descCol]);
2689
+ if (desc) prop.desc = desc;
2690
+ const tag = trimCell(cells[tagCol]);
2691
+ if (tag) prop.prop_tag = tag;
2692
+ props.push(prop);
2693
+ }
2694
+ return props;
2695
+ }
2696
+ async function readTemplateMd(filePath) {
2697
+ const content = await readFile3(filePath, "utf8");
2698
+ const lines = content.split("\n");
2699
+ const source = "template";
2700
+ let planName = "";
2701
+ for (const line of lines) {
2702
+ const m = line.match(/^#\s+(.+)$/);
2703
+ if (m) {
2704
+ planName = m[1].trim();
2705
+ break;
2706
+ }
2707
+ }
2708
+ const { events, event_properties } = parseEventSection(lines);
2709
+ const common_event_properties = parseCommonSection(lines, source);
2710
+ const user_properties = parseUserSection(lines, source);
2711
+ return {
2712
+ meta: {
2713
+ plan_name: planName,
2714
+ app_type: "",
2715
+ sdk_integration_mode: "client_only"
2716
+ },
2717
+ events,
2718
+ event_properties,
2719
+ common_event_properties,
2720
+ user_properties
2721
+ };
2722
+ }
2723
+
2724
+ // src/commands/tracking/code.ts
2725
+ function inferSdkMode(events) {
2726
+ const hasPlatform = events.some((e) => e.platform !== void 0);
2727
+ if (!hasPlatform) return void 0;
2728
+ const platforms = new Set(events.map((e) => e.platform ?? "client"));
2729
+ if (platforms.has("both")) return "both";
2730
+ if (platforms.has("client") && platforms.has("server")) return "both";
2731
+ if (platforms.has("server")) return "server_only";
2732
+ return "client_only";
2733
+ }
2734
+ function registerCode(cmd) {
2735
+ cmd.description("tooling for ae-generate-tracking-code skill");
2736
+ const importTemplateCmd = cmd.command("import-template").description("Import a template file (md or xlsx) to draft.json, inferring sdk_integration_mode from events").requiredOption("--template <path>", "Path to template file (.md or .xlsx)").requiredOption("--out <path>", "Output path for draft.json").option("--sdk-type <type>", "Client SDK type (android/ios/openharmony/javascript/etc.)").option("--languages <langs>", "Client languages comma-separated (e.g., java,kotlin for android)").option("--server <lang>", "Server language (java/python/go/etc.)").action(async (opts) => {
2737
+ assertInputFilePath(opts.template, "--template");
2738
+ assertOutputFilePath(opts.out, "--out");
2739
+ const draft = opts.template.endsWith(".md") ? await readTemplateMd(opts.template) : await readTemplateXlsx(opts.template);
2740
+ const inferredMode = inferSdkMode(draft.events);
2741
+ if (inferredMode) {
2742
+ draft.meta.sdk_integration_mode = inferredMode;
2743
+ process.stdout.write(t("code.inferred_sdk_mode", { mode: draft.meta.sdk_integration_mode }) + "\n");
2744
+ } else {
2745
+ process.stdout.write(t("code.default_sdk_mode", { mode: draft.meta.sdk_integration_mode }) + "\n");
2746
+ }
2747
+ if (opts.sdkType) {
2748
+ draft.meta.client_sdk_type = opts.sdkType;
2749
+ draft.meta.client_platforms = [opts.sdkType];
2750
+ }
2751
+ if (opts.languages) {
2752
+ const langs = opts.languages.split(",");
2753
+ draft.meta.client_languages = langs;
2754
+ if (draft.meta.client_platforms?.[0]) {
2755
+ const platform = draft.meta.client_platforms[0];
2756
+ const langMap = {};
2757
+ langMap[platform] = langs;
2758
+ draft.meta.client_platform_languages = langMap;
2759
+ }
2760
+ }
2761
+ if (opts.server) {
2762
+ draft.meta.server_language = opts.server;
2763
+ }
2764
+ await mkdir(dirname2(opts.out), { recursive: true });
2765
+ await writeFile2(opts.out, JSON.stringify(draft, null, 2), "utf8");
2766
+ process.stdout.write(t("code.wrote_events", { count: draft.events.length, path: opts.out }) + "\n");
2767
+ });
2768
+ const dryrunCmd = cmd.command("dryrun").description("Preview SDK integration layout from draft.json (skill helper; hidden)").requiredOption("--plan <path>", "Draft JSON (from plan fetch)").option("--cwd <path>", "target project dir", process.cwd()).action(async (opts) => {
2769
+ assertInputFilePath(opts.plan, "--plan");
2770
+ const draft = JSON.parse(await readFile4(opts.plan, "utf8"));
2771
+ const detect = await detectProject(opts.cwd);
2772
+ const tagged = /* @__PURE__ */ new Map();
2773
+ for (const ev of draft.events) {
2774
+ const tag = ev.event_tag ?? "uncategorized";
2775
+ if (!tagged.has(tag)) tagged.set(tag, []);
2776
+ tagged.get(tag).push(ev.event_name);
2777
+ }
2778
+ const out = {
2779
+ detect,
2780
+ sdkInit: { candidateFiles: detect.entryFiles, placed: false },
2781
+ commonProperties: draft.common_event_properties.map((p) => p.name),
2782
+ userProperties: draft.user_properties.map((p) => ({ name: p.name, update_type: p.update_type })),
2783
+ eventGroups: [...tagged.entries()].map(([tag, events]) => ({ tag, events }))
2784
+ };
2785
+ process.stdout.write(JSON.stringify(out, null, 2) + "\n");
2786
+ });
2787
+ const detectCmd = cmd.command("detect").description("detect project type and recommended SDK integration modes").option("--cwd <path>", "project directory", process.cwd()).action(async (opts) => {
2788
+ const result = await detectProject(opts.cwd);
2789
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
2790
+ });
2791
+ importTemplateCmd._hidden = true;
2792
+ dryrunCmd._hidden = true;
2793
+ detectCmd._hidden = true;
2794
+ }
2795
+
2796
+ // src/tracking/wiki-query/query.ts
2797
+ import { readFileSync as readFileSync3, existsSync as existsSync5 } from "fs";
2798
+ import { join as join4 } from "path";
2799
+ var WIKI_ROOT = join4(getPackageRoot(), "wiki/te-docs");
2800
+ function searchIndex(keyword) {
2801
+ const indexPath = join4(WIKI_ROOT, "index.md");
2802
+ if (!existsSync5(indexPath)) return [];
2803
+ const lines = readFileSync3(indexPath, "utf8").split("\n");
2804
+ const kw = keyword.toLowerCase();
2805
+ const hits = [];
2806
+ for (const line of lines) {
2807
+ const m = /^\|\s*\[([^\]]+)\]\(([^)]+)\)\s*\|.*\|\s*\[docs\]\(([^)]+)\)\s*\|$/.exec(line);
2808
+ if (!m) continue;
2809
+ const [, name, rawPath, sourceUrl] = m;
2810
+ if (name.toLowerCase().includes(kw) || rawPath.toLowerCase().includes(kw)) {
2811
+ hits.push({ name, rawPath, sourceUrl });
2812
+ }
2813
+ }
2814
+ return hits;
2815
+ }
2816
+
2817
+ // src/commands/tracking/wiki.ts
2818
+ function registerWiki(cmd) {
2819
+ cmd.description("AE docs wiki (bundled)");
2820
+ cmd.command("query").description("Search bundled AE docs wiki index by keyword").requiredOption("--keyword <kw>", "substring to search in index").action((opts) => {
2821
+ const hits = searchIndex(opts.keyword);
2822
+ for (const h of hits) console.log(`${h.name} ${h.rawPath} ${h.sourceUrl}`);
2823
+ });
2824
+ cmd.command("sync").description("Refresh wiki from docs-v2 (developer only; disabled in published package)").action(async () => {
2825
+ console.error(t("wiki.sync_not_supported"));
2826
+ console.error(t("wiki.not_in_published_package"));
2827
+ process.exit(2);
2828
+ });
2829
+ }
2830
+
2831
+ // src/commands/tracking/lang.ts
2832
+ var SUPPORTED = ["zh", "en", "ja", "ko"];
2833
+ var SUPPORTED_LABELS = {
2834
+ zh: "\u4E2D\u6587 (Chinese)",
2835
+ en: "English",
2836
+ ja: "\u65E5\u672C\u8A9E (Japanese)",
2837
+ ko: "\uD55C\uAD6D\uC5B4 (Korean)"
2838
+ };
2839
+ function registerLang(cmd, rootProgram) {
2840
+ cmd.description("manage AE server language for tracking commands");
2841
+ cmd.command("set").description("set the AE server language").argument("<locale>", "language code: zh / en / ja / ko").option("--host <url>", HOST_OPTION_DESC).action(async (locale, opts) => {
2842
+ const normalized = locale.trim().toLowerCase();
2843
+ if (!SUPPORTED.includes(normalized)) {
2844
+ console.error(`Unsupported language: "${locale}"`);
2845
+ console.error("Supported languages:");
2846
+ for (const code of SUPPORTED) {
2847
+ console.error(` ${code} \u2014 ${SUPPORTED_LABELS[code]}`);
2848
+ }
2849
+ process.exit(1);
2850
+ }
2851
+ const host = resolveTrackingHost(rootProgram, opts);
2852
+ const client = await createTrackingClient(host);
2853
+ const aeCode = cliLocaleToAE(normalized);
2854
+ await client.saveUserAutoConfig(aeCode);
2855
+ process.stderr.write(`[ae-cli] Server language saved: ${aeCode}
2856
+ `);
2857
+ const config = await client.getUserAutoConfig();
2858
+ if (config) {
2859
+ const serverLang = config.lang ?? config.umi_locale ?? config.locale;
2860
+ console.log(`Server response: ${JSON.stringify({ lang: serverLang })}`);
2861
+ } else {
2862
+ console.log("Server response: (empty)");
2863
+ }
2864
+ });
2865
+ }
2866
+
2867
+ // src/commands/tracking/index.ts
2868
+ function registerTracking(program2) {
2869
+ const tracking = program2.command("tracking").description("AE tracking plan lifecycle (xlsx, debug, wiki)");
2870
+ registerPlan(tracking.command("plan"), program2);
2871
+ registerCode(tracking.command("code"));
2872
+ registerWiki(tracking.command("wiki"));
2873
+ registerLang(tracking.command("lang"), program2);
2874
+ }
2875
+
379
2876
  // src/index.ts
380
2877
  var require2 = createRequire(import.meta.url);
381
2878
  var pkg = require2("../package.json");
@@ -385,52 +2882,52 @@ program.name("ae-cli").version(version).description("CLI tool for ThinkingAI (AE
385
2882
  async function loadCommands() {
386
2883
  const commands = [];
387
2884
  try {
388
- const teAnalysis = await import("./te-analysis-CB3DA5I5.js");
2885
+ const teAnalysis = await import("./te-analysis-VAR4KUOK.js");
389
2886
  commands.push(...teAnalysis.default);
390
2887
  } catch {
391
2888
  }
392
2889
  try {
393
- const teAudience = await import("./te-audience-W7SCQFC7.js");
2890
+ const teAudience = await import("./te-audience-KMKYI2YJ.js");
394
2891
  commands.push(...teAudience.default);
395
2892
  } catch {
396
2893
  }
397
2894
  try {
398
- const teMeta = await import("./te-meta-PDKLMWXN.js");
2895
+ const teMeta = await import("./te-meta-EPZGQN56.js");
399
2896
  commands.push(...teMeta.default);
400
2897
  } catch {
401
2898
  }
402
2899
  try {
403
- const teCommon = await import("./te-common-FBXVWBSI.js");
2900
+ const teCommon = await import("./te-common-WNCZB7R7.js");
404
2901
  commands.push(...teCommon.default);
405
2902
  } catch {
406
2903
  }
407
2904
  try {
408
- const engage = await import("./te-engage-KARARMIR.js");
2905
+ const engage = await import("./te-engage-4XHCTS6I.js");
409
2906
  commands.push(...engage.default);
410
2907
  } catch {
411
2908
  }
412
2909
  try {
413
- const community = await import("./te-community-LNVDZSGW.js");
2910
+ const community = await import("./te-community-JEEFXPB3.js");
414
2911
  commands.push(...community.default);
415
2912
  } catch {
416
2913
  }
417
2914
  try {
418
- const dataops = await import("./te-dataops-IPCSSWYH.js");
2915
+ const dataops = await import("./te-dataops-GD3XBYCS.js");
419
2916
  commands.push(...dataops.default);
420
2917
  } catch {
421
2918
  }
422
2919
  try {
423
- const teKb = await import("./te-kb-2Z2CARN3.js");
2920
+ const teKb = await import("./te-kb-B62KFP2A.js");
424
2921
  commands.push(...teKb.default);
425
2922
  } catch {
426
2923
  }
427
2924
  try {
428
- const teTeam = await import("./te-team-SW5B7DHO.js");
2925
+ const teTeam = await import("./te-team-YY24VORI.js");
429
2926
  commands.push(...teTeam.default);
430
2927
  } catch {
431
2928
  }
432
2929
  try {
433
- const teAgent = await import("./te-agent-YV4DXEXK.js");
2930
+ const teAgent = await import("./te-agent-KZRIEN4N.js");
434
2931
  commands.push(...teAgent.default);
435
2932
  } catch {
436
2933
  }
@@ -438,35 +2935,35 @@ async function loadCommands() {
438
2935
  }
439
2936
  async function registerAuthCommands() {
440
2937
  try {
441
- const { registerAuth } = await import("./auth-H3GJD55A.js");
2938
+ const { registerAuth } = await import("./auth-GHBMJ5ZR.js");
442
2939
  registerAuth(program);
443
2940
  } catch {
444
2941
  }
445
2942
  }
446
2943
  async function registerConfigCommands() {
447
2944
  try {
448
- const { registerConfig } = await import("./config-64G36TJL.js");
2945
+ const { registerConfig } = await import("./config-NCUGK6NS.js");
449
2946
  registerConfig(program);
450
2947
  } catch {
451
2948
  }
452
2949
  }
453
2950
  async function registerApiCommand() {
454
2951
  try {
455
- const { registerApi } = await import("./raw-WJIWC6YP.js");
2952
+ const { registerApi } = await import("./raw-7NVWSVJP.js");
456
2953
  registerApi(program);
457
2954
  } catch {
458
2955
  }
459
2956
  }
460
2957
  async function registerSyncCommand() {
461
2958
  try {
462
- const { registerSync } = await import("./sync-NVASAISS.js");
2959
+ const { registerSync } = await import("./sync-GRVO4K3U.js");
463
2960
  registerSync(program);
464
2961
  } catch {
465
2962
  }
466
2963
  }
467
2964
  async function registerModelCommand() {
468
2965
  try {
469
- const { registerModel } = await import("./model-VZCYNIOG.js");
2966
+ const { registerModel } = await import("./model-SJSOZTRS.js");
470
2967
  registerModel(program);
471
2968
  } catch {
472
2969
  }
@@ -480,6 +2977,7 @@ async function main() {
480
2977
  await registerApiCommand();
481
2978
  await registerSyncCommand();
482
2979
  await registerModelCommand();
2980
+ registerTracking(program);
483
2981
  program.parse();
484
2982
  }
485
2983
  main();