@thinkingai/ae-cli 6.1.16 → 6.1.18

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 (103) hide show
  1. package/README.md +5 -2
  2. package/README.zh.md +5 -2
  3. package/dist/{auth-2WTQOP77.js → auth-GBMV6TEJ.js} +3 -3
  4. package/dist/{auth-77BUFLGC.js → auth-ROB2EDYV.js} +12 -13
  5. package/dist/{capability-72DTW5M2.js → capability-DKMYUTLC.js} +50 -13
  6. package/dist/{capability-PJHNI4GJ.js → capability-HYVVPG25.js} +49 -12
  7. package/dist/chunk-3FY3RJ26.js +293 -0
  8. package/dist/{chunk-PTE56QPL.js → chunk-3KWQYGYI.js} +4 -0
  9. package/dist/{chunk-UOUS37JQ.js → chunk-4XXOWOTA.js} +3 -3
  10. package/dist/{chunk-GT46FPXN.js → chunk-BYYS3ANB.js} +17 -8
  11. package/dist/{chunk-YA6SMTXG.js → chunk-EFH4XWYC.js} +3 -3
  12. package/dist/{chunk-4SGZG4XY.js → chunk-J2DEBMRF.js} +9 -7
  13. package/dist/{chunk-LYVNONC4.js → chunk-JHENBQ5B.js} +35 -0
  14. package/dist/{chunk-VR3LCBHW.js → chunk-JRJY5DMJ.js} +5 -5
  15. package/dist/{chunk-ILIU36SU.js → chunk-OMPRXM3V.js} +3 -3
  16. package/dist/{chunk-VPKZ7I72.js → chunk-QNOLN2LJ.js} +2 -2
  17. package/dist/{chunk-SAU3QFIQ.js → chunk-QZ3AS4KK.js} +3 -3
  18. package/dist/chunk-RJDU7NYP.js +1198 -0
  19. package/dist/{chunk-4KVPKXFX.js → chunk-RNAALWJK.js} +2 -2
  20. package/dist/{chunk-C4MGVGJW.js → chunk-SERWF6G5.js} +1 -1
  21. package/dist/{chunk-RGKJGKT7.js → chunk-Y3LOALAV.js} +5 -5
  22. package/dist/{chunk-P3FGXJTU.js → chunk-ZQ47LWTI.js} +4 -4
  23. package/dist/chunk-ZQKDZXDO.js +317 -0
  24. package/dist/{client-TKG4WBHN.js → client-L2YDMHQ6.js} +5 -4
  25. package/dist/{community-report-client-FI4LNVYS.js → community-report-client-C7WDGET3.js} +1 -2
  26. package/dist/{config-RE6CMGPK.js → config-BMYZX2UE.js} +7 -6
  27. package/dist/{data-integration-2MYMANJI.js → data-integration-QEKDWQDY.js} +1741 -212
  28. package/dist/index.js +131 -1241
  29. package/dist/{local-data-upload-client-BWHSUQQK.js → local-data-upload-client-4YYHSYD6.js} +1 -2
  30. package/dist/{memory-CHRU2F7W.js → memory-3ORCR7JH.js} +6 -6
  31. package/dist/{memory-YK33G4T7.js → memory-I2WXDTV2.js} +5 -5
  32. package/dist/{metadata-XXR34N5P.js → metadata-I4C2EWUN.js} +10 -10
  33. package/dist/{metadata-UILXHBWF.js → metadata-VUOQJE26.js} +9 -9
  34. package/dist/{model-NR3JHFSJ.js → model-HLHIEFMU.js} +5 -5
  35. package/dist/{model-K3KLWIW6.js → model-UGRDX4MW.js} +6 -6
  36. package/dist/personal-semantic-preference-LIPACBDX.js +239 -0
  37. package/dist/personal-semantic-preference-OEISBRHM.js +239 -0
  38. package/dist/project-semantic-FFPWFPIW.js +1114 -0
  39. package/dist/project-semantic-RT3R2VQD.js +1114 -0
  40. package/dist/{sync-FCKOVWWS.js → sync-HKIOZXQE.js} +6 -6
  41. package/dist/{sync-DAVKYVMW.js → sync-TFHU2UTG.js} +7 -7
  42. package/dist/{te-agent-HLW4VTQK.js → te-agent-BR6VDBNX.js} +9 -8
  43. package/dist/{te-agent-4BKBODMF.js → te-agent-VLYOV7S4.js} +8 -7
  44. package/dist/{te-analysis-ZMNGOVNW.js → te-analysis-4YGQL5RC.js} +437 -38
  45. package/dist/{te-analysis-O6DCO6BS.js → te-analysis-7VUNUYWZ.js} +436 -37
  46. package/dist/{te-community-HLC43QKH.js → te-community-5DMNKJWY.js} +5 -5
  47. package/dist/{te-community-6HPBWJUZ.js → te-community-ISDQWJU7.js} +6 -6
  48. package/dist/{te-dataops-HDRUXY4K.js → te-dataops-6P5IKWNJ.js} +8 -7
  49. package/dist/{te-dataops-EJP56W3K.js → te-dataops-CVULXNVB.js} +7 -6
  50. package/dist/{te-engage-RAK5PESW.js → te-engage-KZPR5R22.js} +9 -9
  51. package/dist/{te-engage-FGBGQ4IY.js → te-engage-N5WI32H6.js} +8 -8
  52. package/dist/{te-experiment-SO5MPDMJ.js → te-experiment-6BITX4RD.js} +226 -8
  53. package/dist/{te-experiment-VZF7BT6G.js → te-experiment-UVR4HLND.js} +227 -9
  54. package/dist/{te-kb-APXBWBDY.js → te-kb-RCLSSH2Q.js} +251 -127
  55. package/dist/{te-system-Z77IKZFN.js → te-system-FXITO2JG.js} +5 -5
  56. package/dist/{te-system-YARIK4S5.js → te-system-K2GYMCTB.js} +6 -6
  57. package/dist/{te-team-EFKWYKMK.js → te-team-ADOC2ROP.js} +6 -6
  58. package/dist/{update-OGPSZM5A.js → update-YCYCKJOO.js} +7 -6
  59. package/package.json +2 -1
  60. package/skills/ae-agent/SKILL.md +3 -4
  61. package/skills/ae-agent/references/edit-skill.md +3 -0
  62. package/skills/ae-agent/references/get-skill-content.md +1 -1
  63. package/skills/ae-agent/references/rescan-skills.md +15 -13
  64. package/skills/ae-agent/references/upload-skill.md +7 -4
  65. package/skills/ae-analysis/SKILL.md +45 -4
  66. package/skills/ae-analysis/metadata_resolution.md +38 -4
  67. package/skills/ae-analysis/references/analysis_data_retrieval.md +29 -0
  68. package/skills/ae-analysis/references/asset_authentication_export.md +22 -0
  69. package/skills/ae-analysis/references/asset_authentication_list.md +18 -14
  70. package/skills/ae-analysis/references/asset_authentication_update.md +29 -14
  71. package/skills/ae-analysis/references/command_index.md +17 -9
  72. package/skills/ae-analysis/references/dashboard_get.md +18 -1
  73. package/skills/ae-analysis/references/dashboard_update.md +3 -0
  74. package/skills/ae-analysis/references/personal_semantic_preference_add.md +23 -0
  75. package/skills/ae-analysis/references/personal_semantic_preference_delete.md +17 -0
  76. package/skills/ae-analysis/references/personal_semantic_preference_get.md +19 -0
  77. package/skills/ae-analysis/references/personal_semantic_preference_list.md +21 -0
  78. package/skills/ae-analysis/references/personal_semantic_preference_update.md +19 -0
  79. package/skills/ae-data-integration/SKILL.md +23 -4
  80. package/skills/ae-data-integration/references/custom-layer.md +93 -0
  81. package/skills/ae-data-integration/references/error-handling.md +92 -0
  82. package/skills/ae-data-integration/references/handoff.md +77 -18
  83. package/skills/ae-data-integration/references/local-analysis.md +1 -1
  84. package/skills/ae-data-integration/references/reuse.md +9 -5
  85. package/skills/ae-data-integration/references/sink-upload.md +1 -1
  86. package/skills/ae-data-integration/references/source-inspect.md +32 -13
  87. package/skills/ae-data-integration/references/tracking-plan.md +7 -5
  88. package/skills/ae-data-integration/references/transform.md +10 -10
  89. package/skills/ae-data-integration/references/ue-mapping.md +33 -11
  90. package/skills/ae-engage/references/build-task-save-guide.md +9 -0
  91. package/skills/ae-engage/references/save-task.md +82 -0
  92. package/skills/ae-experiment/SKILL.md +8 -2
  93. package/skills/ae-experiment/references/manage_feature_whitelist.md +66 -0
  94. package/skills/ae-experiment/references/manage_guardrail_metrics.md +26 -0
  95. package/skills/ae-experiment/references/save_experiment.md +1 -1
  96. package/skills/ae-kb/SKILL.md +56 -51
  97. package/skills/ae-kb/references/query-workflow.md +112 -0
  98. package/skills/ae-kb-discovery/SKILL.md +105 -0
  99. package/skills/ae-project-semantic/SKILL.md +193 -0
  100. package/skills/ae-project-semantic/references/query-routing-v5.md +165 -0
  101. package/skills/ae-project-semantic/references/recommendation-quality.md +68 -0
  102. package/dist/chunk-QGM4M3NI.js +0 -37
  103. package/dist/chunk-ZZUOD757.js +0 -598
package/dist/index.js CHANGED
@@ -1,3 +1,16 @@
1
+ import {
2
+ allHeaderNames,
3
+ allSheetNames,
4
+ detectCliLocale,
5
+ displayToType,
6
+ extractErrors,
7
+ fixDraft,
8
+ getPackageRoot,
9
+ t,
10
+ validateAndFix,
11
+ validateDraft,
12
+ writeDraftXlsx
13
+ } from "./chunk-RJDU7NYP.js";
1
14
  import {
2
15
  getLocalCliPackageInfo
3
16
  } from "./chunk-VTWMIC5L.js";
@@ -7,30 +20,32 @@ import {
7
20
  import {
8
21
  TeAgentApiError,
9
22
  TeAgentCredentialsError
10
- } from "./chunk-VPKZ7I72.js";
23
+ } from "./chunk-QNOLN2LJ.js";
11
24
  import {
12
25
  formatCapabilityMissCompatHint,
13
26
  printError,
14
27
  printOutput,
15
28
  runHostCompatCheck
16
- } from "./chunk-GT46FPXN.js";
29
+ } from "./chunk-BYYS3ANB.js";
17
30
  import {
18
31
  CapabilityGatewayError,
19
32
  executeCapability,
20
33
  uploadInputFileBytes
21
- } from "./chunk-ILIU36SU.js";
34
+ } from "./chunk-OMPRXM3V.js";
22
35
  import "./chunk-6EIJSNBD.js";
23
36
  import {
24
37
  clearCliToken,
25
38
  getCliToken
26
- } from "./chunk-4SGZG4XY.js";
39
+ } from "./chunk-J2DEBMRF.js";
27
40
  import {
28
41
  SecureStoreAuthError,
42
+ resolveHost
43
+ } from "./chunk-ZQKDZXDO.js";
44
+ import {
29
45
  getActiveHost,
30
46
  getConfigDir,
31
- resolveHost,
32
47
  safeJsonParse
33
- } from "./chunk-ZZUOD757.js";
48
+ } from "./chunk-3FY3RJ26.js";
34
49
  import {
35
50
  CliValidationError,
36
51
  CommunityReportError,
@@ -39,8 +54,7 @@ import {
39
54
  } from "./chunk-UW5UN47B.js";
40
55
  import {
41
56
  logger
42
- } from "./chunk-LYVNONC4.js";
43
- import "./chunk-QGM4M3NI.js";
57
+ } from "./chunk-JHENBQ5B.js";
44
58
 
45
59
  // src/index.ts
46
60
  import { Command as CommanderCommand } from "commander";
@@ -55,6 +69,31 @@ function missingRequiredFlagsError(cmdName, missing) {
55
69
  const hint = hintParts.length > 0 ? hintParts.join(" ") : `Usage: ae-cli ${cmdName} ${names.map((name) => `${name} <value>`).join(" ")}`;
56
70
  return { message, hint };
57
71
  }
72
+ function readSkillCurrentVersion(body) {
73
+ if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
74
+ const currentVersion = body.currentVersion;
75
+ if (typeof currentVersion !== "string") return void 0;
76
+ return /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(currentVersion) ? currentVersion : void 0;
77
+ }
78
+ function teAgentApiErrorPresentation(err) {
79
+ if (err.code === "SKILL_VERSION_CONFLICT") {
80
+ const currentVersion = readSkillCurrentVersion(err.body);
81
+ return {
82
+ message: "The Skill content changed, and the new version must be greater than the current version.",
83
+ code: err.code,
84
+ hint: currentVersion ? `Retry with --version set to a major.minor version greater than ${currentVersion}.` : "Retry with --version set to a major.minor version greater than the current Skill version.",
85
+ ...currentVersion ? { meta: { currentVersion } } : {}
86
+ };
87
+ }
88
+ if (err.code === "SKILL_HISTORY_CONFLICT") {
89
+ return {
90
+ message: "The Skill cannot be safely updated right now.",
91
+ code: err.code,
92
+ hint: "The Skill cannot be safely updated right now. Please contact your administrator."
93
+ };
94
+ }
95
+ return {};
96
+ }
58
97
  async function runCommand(cmd, opts, globalOpts) {
59
98
  try {
60
99
  const ctx = createRuntimeContext(cmd, opts, globalOpts);
@@ -203,7 +242,14 @@ async function runCommand(cmd, opts, globalOpts) {
203
242
  } else if (err.status === 401) {
204
243
  printError("auth", message, "Run: ae-cli auth login");
205
244
  } else {
206
- printError("api", message);
245
+ const presentation = teAgentApiErrorPresentation(err);
246
+ printError(
247
+ "api",
248
+ presentation.message ?? message,
249
+ presentation.hint,
250
+ presentation.code,
251
+ presentation.meta
252
+ );
207
253
  }
208
254
  } else if (looksLikeAuthFailure(message)) {
209
255
  printError("auth", message, "Run: ae-cli auth login");
@@ -237,7 +283,7 @@ function capabilityGatewayHint(err) {
237
283
  ${compatExtra}` : base;
238
284
  }
239
285
  if (err.httpStatus === 404 && !err.code) {
240
- const base = "The current host returned 404 for this capability route. Do not keep retrying the same command; verify the backend route/capability deployment.";
286
+ const base = "The current host returned 404 for this capability route. Do not keep retrying the same command; verify the backend route/capability deployment. If --host points directly to a local Common service instead of the deployed gateway, scope AE_CLI_CAPABILITY_GATEWAY_DOMAIN= to this command so it uses /api/cli/v1.";
241
287
  return compatExtra ? `${base}
242
288
  ${compatExtra}` : base;
243
289
  }
@@ -252,21 +298,21 @@ function createRuntimeContext(cmd, opts, globalOpts) {
252
298
  let _clientModule = null;
253
299
  async function getClient() {
254
300
  if (!_clientModule) {
255
- _clientModule = await import("./client-TKG4WBHN.js");
301
+ _clientModule = await import("./client-L2YDMHQ6.js");
256
302
  }
257
303
  return _clientModule;
258
304
  }
259
305
  let _communityReportModule = null;
260
306
  async function getCommunityReportClient() {
261
307
  if (!_communityReportModule) {
262
- _communityReportModule = await import("./community-report-client-FI4LNVYS.js");
308
+ _communityReportModule = await import("./community-report-client-C7WDGET3.js");
263
309
  }
264
310
  return _communityReportModule;
265
311
  }
266
312
  let _localDataUploadModule = null;
267
313
  async function getLocalDataUploadClient() {
268
314
  if (!_localDataUploadModule) {
269
- _localDataUploadModule = await import("./local-data-upload-client-BWHSUQQK.js");
315
+ _localDataUploadModule = await import("./local-data-upload-client-4YYHSYD6.js");
270
316
  }
271
317
  return _localDataUploadModule;
272
318
  }
@@ -328,7 +374,7 @@ function createRuntimeContext(cmd, opts, globalOpts) {
328
374
  return client.localDataUpload(endpoint, rawBody, options);
329
375
  },
330
376
  async token() {
331
- const { getToken } = await import("./auth-2WTQOP77.js");
377
+ const { getToken } = await import("./auth-GBMV6TEJ.js");
332
378
  return getToken(ctx.host());
333
379
  },
334
380
  host() {
@@ -386,7 +432,7 @@ function registerCommands(program2, commands) {
386
432
  parent = resourceCmd;
387
433
  }
388
434
  }
389
- const sub = parent.command(cmd.command).description(cmd.description);
435
+ const sub = parent.command(cmd.command, { hidden: cmd.hidden === true }).description(cmd.description);
390
436
  for (const flag of cmd.flags) {
391
437
  const flagStr = buildFlagString(flag);
392
438
  if (flag.variadic) {
@@ -460,886 +506,6 @@ function extractGlobalOptions(program2) {
460
506
  import { readFile, writeFile, cp } from "fs/promises";
461
507
  import path2, { resolve as resolve2 } from "path";
462
508
 
463
- // src/tracking/xlsx/write.ts
464
- import ExcelJS from "exceljs";
465
-
466
- // src/tracking/i18n/locale.ts
467
- var VALID_LOCALES = /* @__PURE__ */ new Set(["zh", "en", "ja", "ko"]);
468
- function normalize(raw) {
469
- const lower = raw.trim().toLowerCase();
470
- if (lower.startsWith("zh") || lower.startsWith("cn")) return "zh";
471
- if (lower.startsWith("ja") || lower.startsWith("jp")) return "ja";
472
- if (lower.startsWith("ko") || lower.startsWith("kr")) return "ko";
473
- if (lower.startsWith("en")) return "en";
474
- if (VALID_LOCALES.has(lower)) return lower;
475
- return "en";
476
- }
477
- var _cliLocale;
478
- function detectCliLocale() {
479
- if (_cliLocale) return _cliLocale;
480
- if (process.env.AE_LANG) {
481
- _cliLocale = normalize(process.env.AE_LANG);
482
- return _cliLocale;
483
- }
484
- const sys = (process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || "").toLowerCase();
485
- if (sys) {
486
- _cliLocale = normalize(sys);
487
- return _cliLocale;
488
- }
489
- _cliLocale = "en";
490
- return _cliLocale;
491
- }
492
-
493
- // src/tracking/i18n/resources/xlsx/sheets.ts
494
- var SHEET_NAMES = {
495
- event_data: {
496
- zh: "#\u4E8B\u4EF6\u6570\u636E",
497
- en: "#event data",
498
- ja: "#\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF",
499
- ko: "#\uC774\uBCA4\uD2B8 \uB370\uC774\uD130"
500
- },
501
- common_props: {
502
- zh: "#\u516C\u5171\u4E8B\u4EF6\u5C5E\u6027",
503
- en: "#super property",
504
- ja: "#\u30D1\u30D6\u30EA\u30C3\u30AF\u30A4\u30D9\u30F3\u30C8\u30D7\u30ED\u30D1\u30C6\u30A3",
505
- ko: "#\uACF5\uD1B5 \uC774\uBCA4\uD2B8 \uC18D\uC131"
506
- },
507
- user_data: {
508
- zh: "#\u7528\u6237\u6570\u636E",
509
- en: "#user data",
510
- ja: "#\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF",
511
- ko: "#\uC720\uC800 \uB370\uC774\uD130"
512
- },
513
- user_id: {
514
- zh: "#\u7528\u6237ID\u4F53\u7CFB",
515
- en: "#ID mapping rule",
516
- ja: "#\u30E6\u30FC\u30B6\u30FCID\u30B7\u30B9\u30C6\u30E0",
517
- ko: "#\uC720\uC800 ID \uCCB4\uACC4"
518
- }
519
- };
520
- function sheetName(key, locale) {
521
- return SHEET_NAMES[key][locale];
522
- }
523
- function allSheetNames(key) {
524
- return Object.values(SHEET_NAMES[key]);
525
- }
526
-
527
- // src/tracking/i18n/resources/xlsx/headers.ts
528
- var HEADERS = {
529
- // === #事件数据 (9 列) ===
530
- event_name: {
531
- zh: "\u4E8B\u4EF6\u540D\uFF08\u5FC5\u586B\uFF09",
532
- en: "Event Name",
533
- ja: "\u30A4\u30D9\u30F3\u30C8\u540D\uFF08\u5FC5\u9808\uFF09",
534
- ko: "\uC774\uBCA4\uD2B8 \uC774\uB984 (\uD544\uC218)"
535
- },
536
- event_display_name: {
537
- zh: "\u4E8B\u4EF6\u663E\u793A\u540D",
538
- en: "Event Display Name",
539
- ja: "\u30A4\u30D9\u30F3\u30C8\u8868\u793A\u540D",
540
- ko: "\uC774\uBCA4\uD2B8 \uD45C\uC2DC \uC774\uB984"
541
- },
542
- event_desc: {
543
- zh: "\u4E8B\u4EF6\u8BF4\u660E",
544
- en: "Event Description",
545
- ja: "\u30A4\u30D9\u30F3\u30C8\u8AAC\u660E",
546
- ko: "\uC774\uBCA4\uD2B8 \uC124\uBA85"
547
- },
548
- event_tag: {
549
- zh: "\u4E8B\u4EF6\u6807\u7B7E",
550
- en: "Event Tag",
551
- ja: "\u30AB\u30C6\u30B4\u30EA",
552
- ko: "\uC774\uBCA4\uD2B8 \uD0DC\uADF8"
553
- },
554
- platform: {
555
- zh: "\u91C7\u96C6\u7AEF",
556
- en: "Platform",
557
- ja: "\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0",
558
- ko: "\uD50C\uB7AB\uD3FC"
559
- },
560
- prop_name: {
561
- zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
562
- en: "Property Name",
563
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
564
- ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
565
- },
566
- prop_display_name: {
567
- zh: "\u5C5E\u6027\u663E\u793A\u540D",
568
- en: "Property Display Name",
569
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
570
- ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
571
- },
572
- prop_type: {
573
- zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
574
- en: "Data Type",
575
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
576
- ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
577
- },
578
- prop_desc: {
579
- zh: "\u5C5E\u6027\u8BF4\u660E",
580
- en: "Property Description",
581
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
582
- ko: "\uC18D\uC131 \uC124\uBA85"
583
- },
584
- // === #公共事件属性 (4 列) ===
585
- common_prop_name: {
586
- zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
587
- en: "Property Name",
588
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
589
- ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
590
- },
591
- common_prop_display_name: {
592
- zh: "\u5C5E\u6027\u663E\u793A\u540D",
593
- en: "Property Display Name",
594
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
595
- ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
596
- },
597
- common_prop_type: {
598
- zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
599
- en: "Data Type",
600
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
601
- ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
602
- },
603
- common_prop_desc: {
604
- zh: "\u5C5E\u6027\u8BF4\u660E",
605
- en: "Property Description",
606
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
607
- ko: "\uC18D\uC131 \uC124\uBA85"
608
- },
609
- // === #用户数据 (6 列) ===
610
- user_prop_name: {
611
- zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
612
- en: "Property Name",
613
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
614
- ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
615
- },
616
- user_prop_display_name: {
617
- zh: "\u5C5E\u6027\u663E\u793A\u540D",
618
- en: "Property Display Name",
619
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
620
- ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
621
- },
622
- user_prop_type: {
623
- zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
624
- en: "Data Type",
625
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
626
- ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
627
- },
628
- update_type: {
629
- zh: "\u66F4\u65B0\u65B9\u5F0F",
630
- en: "Update Type",
631
- ja: "\u66F4\u65B0\u65B9\u6CD5",
632
- ko: "\uC5C5\uB370\uC774\uD2B8 \uBC29\uC2DD"
633
- },
634
- user_prop_desc: {
635
- zh: "\u5C5E\u6027\u8BF4\u660E",
636
- en: "Property Description",
637
- ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
638
- ko: "\uC18D\uC131 \uC124\uBA85"
639
- },
640
- prop_tag: {
641
- zh: "\u5C5E\u6027\u6807\u7B7E",
642
- en: "Property Tag",
643
- ja: "\u30AB\u30C6\u30B4\u30EA",
644
- ko: "\uC18D\uC131 \uD0DC\uADF8"
645
- },
646
- // === #用户ID体系 (4 列,不含"游戏类型"前置列) ===
647
- user_id_prop_name: {
648
- zh: "\u5C5E\u6027\u540D",
649
- en: "Property",
650
- ja: "\u5C5E\u6027\u540D",
651
- ko: "\uC18D\uC131 \uC774\uB984"
652
- },
653
- user_id_display_name: {
654
- zh: "\u5C5E\u6027\u663E\u793A\u540D",
655
- en: "Display Name",
656
- ja: "\u5C5E\u6027\u8868\u793A\u540D",
657
- ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
658
- },
659
- user_id_desc: {
660
- zh: "\u5C5E\u6027\u8BF4\u660E",
661
- en: "Description",
662
- ja: "\u5C5E\u6027\u8AAC\u660E",
663
- ko: "\uC18D\uC131 \uC124\uBA85"
664
- },
665
- user_id_value_desc: {
666
- zh: "\u8D4B\u503C\u8BF4\u660E",
667
- en: "Value Description",
668
- ja: "\u4EE3\u5165\u8AAC\u660E",
669
- ko: "\uAC12 \uC124\uBA85"
670
- }
671
- };
672
- function headerName(key, locale) {
673
- return HEADERS[key][locale];
674
- }
675
- function allHeaderNames(key) {
676
- return Object.values(HEADERS[key]);
677
- }
678
-
679
- // src/tracking/i18n/resources/xlsx/types.ts
680
- var PROP_TYPE_DISPLAY = {
681
- string: { zh: "\u6587\u672C", en: "String", ja: "\u30B9\u30C8\u30EA\u30F3\u30B0", ko: "String" },
682
- number: { zh: "\u6570\u503C", en: "Number", ja: "\u6570\u5024", ko: "Number" },
683
- bool: { zh: "\u5E03\u5C14", en: "Boolean", ja: "\u30D6\u30FC\u30EB\u5024", ko: "Boolean" },
684
- datetime: { zh: "\u65F6\u95F4", en: "Date", ja: "\u6642\u9593", ko: "Date" },
685
- object: { zh: "\u5BF9\u8C61", en: "Row", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8", ko: "Row" },
686
- array_row: { zh: "\u5BF9\u8C61\u7EC4", en: "Array Row", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30B0\u30EB\u30FC\u30D7", ko: "Array Row" },
687
- array_string: { zh: "\u5217\u8868", en: "List", ja: "\u30EA\u30B9\u30C8", ko: "List" }
688
- };
689
- function typeToDisplay(type, locale) {
690
- return PROP_TYPE_DISPLAY[type][locale];
691
- }
692
- var ALL_DISPLAY_TO_TYPE = {};
693
- for (const [canonical, locales] of Object.entries(PROP_TYPE_DISPLAY)) {
694
- for (const val of Object.values(locales)) {
695
- ALL_DISPLAY_TO_TYPE[val] = canonical;
696
- }
697
- }
698
- var ALIASES = {
699
- // zh alias(行业模板)
700
- "\u5B57\u7B26\u4E32": "string",
701
- // en alias(旧值兼容 — 2026-07-15 前生成的老 xlsx)
702
- "string": "string",
703
- "number": "number",
704
- "boolean": "bool",
705
- "datetime": "datetime",
706
- "object": "object",
707
- "object[]": "array_row",
708
- "string[]": "array_string",
709
- // en 额外 alias
710
- "Bool": "bool",
711
- "DateTime": "datetime",
712
- "Time": "datetime",
713
- "Object": "object",
714
- "Object Array": "array_row",
715
- "String Array": "array_string",
716
- // ja alias
717
- "\u6587\u5B57\u5217": "string",
718
- "\u30C6\u30AD\u30B9\u30C8": "string",
719
- "\u30D6\u30FC\u30EB": "bool",
720
- "\u65E5\u6642": "datetime",
721
- // ja 旧值兼容
722
- "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u914D\u5217": "array_row",
723
- "\u914D\u5217": "array_string",
724
- // ko alias
725
- "\uD14D\uC2A4\uD2B8": "string",
726
- "\uBB38\uC790\uC5F4": "string",
727
- "\uC22B\uC790": "number",
728
- "\uBD80\uC6B8": "bool",
729
- "\uB0A0\uC9DC\uC2DC\uAC04": "datetime",
730
- "\uAC1D\uCCB4 \uBC30\uC5F4": "array_row",
731
- "\uB9AC\uC2A4\uD2B8": "array_string",
732
- // ko 旧值兼容
733
- "time": "datetime",
734
- "object_array": "array_row",
735
- "string_array": "array_string"
736
- };
737
- Object.assign(ALL_DISPLAY_TO_TYPE, ALIASES);
738
- function displayToType(raw) {
739
- const trimmed = raw.trim();
740
- return ALL_DISPLAY_TO_TYPE[trimmed] ?? null;
741
- }
742
-
743
- // src/tracking/i18n/translate.ts
744
- import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
745
- import { join as join2 } from "path";
746
-
747
- // src/tracking/paths.ts
748
- import { existsSync, readFileSync } from "fs";
749
- import { dirname, join } from "path";
750
- import { fileURLToPath } from "url";
751
- var AE_CLI_PACKAGE_NAMES = /* @__PURE__ */ new Set(["@tant/ae-cli", "@thinkingai/ae-cli"]);
752
- function isAeCliPackageName(name) {
753
- return typeof name === "string" && (AE_CLI_PACKAGE_NAMES.has(name) || name.endsWith("/ae-cli"));
754
- }
755
- function getPackageRoot() {
756
- let cur = dirname(fileURLToPath(import.meta.url));
757
- while (cur !== dirname(cur)) {
758
- const pj = join(cur, "package.json");
759
- if (existsSync(pj)) {
760
- try {
761
- const pkg2 = JSON.parse(readFileSync(pj, "utf8"));
762
- if (isAeCliPackageName(pkg2.name)) return cur;
763
- } catch {
764
- }
765
- }
766
- cur = dirname(cur);
767
- }
768
- throw new Error("Could not locate ae-cli package root");
769
- }
770
-
771
- // src/tracking/i18n/translate.ts
772
- var loaded = /* @__PURE__ */ new Map();
773
- function i18nFile(locale) {
774
- const root = getPackageRoot();
775
- const candidates = [
776
- join2(root, "dist", "tracking", "i18n", "resources", "cli", `${locale}.json`),
777
- join2(root, "src", "tracking", "i18n", "resources", "cli", `${locale}.json`)
778
- ];
779
- for (const p of candidates) {
780
- if (existsSync2(p)) return p;
781
- }
782
- return candidates[candidates.length - 1];
783
- }
784
- function loadSync(locale) {
785
- if (loaded.has(locale)) return loaded.get(locale);
786
- try {
787
- const raw = readFileSync2(i18nFile(locale), "utf8");
788
- const tree = JSON.parse(raw);
789
- loaded.set(locale, tree);
790
- return tree;
791
- } catch {
792
- if (locale !== "en") {
793
- return loadSync("en");
794
- }
795
- loaded.set("en", {});
796
- return {};
797
- }
798
- }
799
- function t(key, params, locale) {
800
- const loc = locale ?? detectCliLocale();
801
- const tree = loadSync(loc);
802
- const parts = key.split(".");
803
- let node = tree;
804
- for (const part of parts) {
805
- if (typeof node !== "object" || node === null) return key;
806
- node = node[part];
807
- }
808
- if (typeof node !== "string") return key;
809
- if (params) {
810
- return node.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? `{${name}}`));
811
- }
812
- return node;
813
- }
814
-
815
- // src/tracking/xlsx/tag-priority.ts
816
- var TAG_PRIORITY = {
817
- // Account lifecycle
818
- "Basic": 1,
819
- // Core gameplay
820
- "Battle": 10,
821
- "Stage": 11,
822
- "Dungeon": 12,
823
- "Gacha": 13,
824
- // Progression & economy
825
- "Growth": 20,
826
- "Resource": 21,
827
- // Monetization
828
- "Ads": 30,
829
- "Payment": 31,
830
- "Subscription": 32,
831
- // Supporting systems
832
- "Shop": 40,
833
- "Quest": 41,
834
- "Achievement": 42,
835
- "Check-in": 43,
836
- "Leaderboard": 44,
837
- "Guild": 45,
838
- "Social": 46,
839
- // Genre-specific (game)
840
- "Building": 50,
841
- "Alliance": 51,
842
- "Equipment": 52,
843
- "Trade": 53,
844
- "Revive": 54,
845
- "Slots": 55,
846
- "Lottery": 56,
847
- "Reward": 57,
848
- // Non-game
849
- "Discovery": 60,
850
- "Product": 61,
851
- "Order": 62,
852
- "After-sales": 63,
853
- "Content": 64,
854
- "Interaction": 65,
855
- "Relationship": 66,
856
- "Live": 67,
857
- "Onboarding": 68,
858
- "Course": 69,
859
- "Enrollment": 70,
860
- "Quiz": 71,
861
- "Creation": 72,
862
- "Material": 73,
863
- "Export": 74,
864
- "Playback": 75,
865
- "Withdraw": 76
866
- };
867
- var DEFAULT_TAG_PRIORITY = 80;
868
- var CANONICAL_TAG = {
869
- // zh
870
- "\u57FA\u7840\u4E8B\u4EF6": "Basic",
871
- "\u6218\u6597": "Battle",
872
- "\u5173\u5361": "Stage",
873
- "\u526F\u672C": "Dungeon",
874
- "\u62BD\u5361": "Gacha",
875
- "\u517B\u6210": "Growth",
876
- "\u6210\u957F": "Growth",
877
- "\u8D44\u6E90": "Resource",
878
- "\u5E7F\u544A": "Ads",
879
- "\u652F\u4ED8": "Payment",
880
- "\u8BA2\u9605": "Subscription",
881
- "\u5546\u57CE": "Shop",
882
- "\u4EFB\u52A1": "Quest",
883
- "\u6210\u5C31": "Achievement",
884
- "\u7B7E\u5230": "Check-in",
885
- "\u6392\u884C\u699C": "Leaderboard",
886
- "\u516C\u4F1A": "Guild",
887
- "\u793E\u4EA4": "Social",
888
- "\u5EFA\u7B51": "Building",
889
- "\u8054\u76DF": "Alliance",
890
- "\u88C5\u5907": "Equipment",
891
- "\u4EA4\u6613": "Trade",
892
- "\u590D\u6D3B": "Revive",
893
- "\u62BD\u5956": "Lottery",
894
- "\u5956\u52B1": "Reward",
895
- "\u63D0\u73B0": "Withdraw",
896
- "\u53D1\u73B0": "Discovery",
897
- "\u5546\u54C1": "Product",
898
- "\u8BA2\u5355": "Order",
899
- "\u552E\u540E": "After-sales",
900
- "\u5185\u5BB9": "Content",
901
- "\u4E92\u52A8": "Interaction",
902
- "\u5173\u7CFB": "Relationship",
903
- "\u76F4\u64AD": "Live",
904
- "\u5F15\u5BFC": "Onboarding",
905
- "\u8BFE\u7A0B": "Course",
906
- "\u62A5\u540D": "Enrollment",
907
- "\u6D4B\u9A8C": "Quiz",
908
- "\u521B\u4F5C": "Creation",
909
- "\u7D20\u6750": "Material",
910
- "\u5BFC\u51FA": "Export",
911
- "\u5185\u5BB9\u64AD\u653E": "Playback",
912
- // ja
913
- "\u57FA\u672C\u30A4\u30D9\u30F3\u30C8": "Basic",
914
- "\u6226\u95D8": "Battle",
915
- "\u30B9\u30C6\u30FC\u30B8": "Stage",
916
- "\u30C0\u30F3\u30B8\u30E7\u30F3": "Dungeon",
917
- "\u30AC\u30C1\u30E3": "Gacha",
918
- "\u80B2\u6210": "Growth",
919
- "\u30EA\u30BD\u30FC\u30B9": "Resource",
920
- "\u5E83\u544A": "Ads",
921
- "\u652F\u6255\u3044": "Payment",
922
- "\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3": "Subscription",
923
- "\u30B7\u30E7\u30C3\u30D7": "Shop",
924
- "\u30AF\u30A8\u30B9\u30C8": "Quest",
925
- "\u5B9F\u7E3E": "Achievement",
926
- "\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3": "Check-in",
927
- "\u30E9\u30F3\u30AD\u30F3\u30B0": "Leaderboard",
928
- "\u30AE\u30EB\u30C9": "Guild",
929
- "\u30BD\u30FC\u30B7\u30E3\u30EB": "Social",
930
- "\u5EFA\u7BC9": "Building",
931
- "\u540C\u76DF": "Alliance",
932
- "\u88C5\u5099": "Equipment",
933
- "\u30C8\u30EC\u30FC\u30C9": "Trade",
934
- "\u5FA9\u6D3B": "Revive",
935
- "\u30B9\u30ED\u30C3\u30C8": "Slots",
936
- "\u62BD\u9078": "Lottery",
937
- "\u5831\u916C": "Reward",
938
- "\u5F15\u304D\u51FA\u3057": "Withdraw",
939
- "\u767A\u898B": "Discovery",
940
- "\u6CE8\u6587": "Order",
941
- "\u30A2\u30D5\u30BF\u30FC\u30B5\u30FC\u30D3\u30B9": "After-sales",
942
- "\u30B3\u30F3\u30C6\u30F3\u30C4": "Content",
943
- "\u30A4\u30F3\u30BF\u30E9\u30AF\u30B7\u30E7\u30F3": "Interaction",
944
- "\u95A2\u4FC2": "Relationship",
945
- "\u30E9\u30A4\u30D6": "Live",
946
- "\u30AA\u30F3\u30DC\u30FC\u30C7\u30A3\u30F3\u30B0": "Onboarding",
947
- "\u30B3\u30FC\u30B9": "Course",
948
- "\u7533\u3057\u8FBC\u307F": "Enrollment",
949
- "\u30AF\u30A4\u30BA": "Quiz",
950
- "\u5275\u4F5C": "Creation",
951
- "\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8": "Export",
952
- "\u518D\u751F": "Playback",
953
- // ko
954
- "\uAE30\uBCF8 \uC774\uBCA4\uD2B8": "Basic",
955
- "\uC804\uD22C": "Battle",
956
- "\uC2A4\uD14C\uC774\uC9C0": "Stage",
957
- "\uB358\uC804": "Dungeon",
958
- "\uAC00\uCC60": "Gacha",
959
- "\uC721\uC131": "Growth",
960
- "\uB9AC\uC18C\uC2A4": "Resource",
961
- "\uAD11\uACE0": "Ads",
962
- "\uACB0\uC81C": "Payment",
963
- "\uAD6C\uB3C5": "Subscription",
964
- "\uC0C1\uC810": "Shop",
965
- "\uD018\uC2A4\uD2B8": "Quest",
966
- "\uC5C5\uC801": "Achievement",
967
- "\uCD9C\uC11D\uCCB4\uD06C": "Check-in",
968
- "\uB9AC\uB354\uBCF4\uB4DC": "Leaderboard",
969
- "\uAE38\uB4DC": "Guild",
970
- "\uC18C\uC15C": "Social",
971
- "\uAC74\uC124": "Building",
972
- "\uC5F0\uB9F9": "Alliance",
973
- "\uC7A5\uBE44": "Equipment",
974
- "\uAC70\uB798": "Trade",
975
- "\uBD80\uD65C": "Revive",
976
- "\uC2AC\uB86F": "Slots",
977
- "\uCD94\uCCA8": "Lottery",
978
- "\uBCF4\uC0C1": "Reward",
979
- "\uCD9C\uAE08": "Withdraw",
980
- "\uBC1C\uACAC": "Discovery",
981
- "\uC0C1\uD488": "Product",
982
- "\uC8FC\uBB38": "Order",
983
- "A/S": "After-sales",
984
- "\uCF58\uD150\uCE20": "Content",
985
- "\uC778\uD130\uB799\uC158": "Interaction",
986
- "\uAD00\uACC4": "Relationship",
987
- "\uB77C\uC774\uBE0C": "Live",
988
- "\uC628\uBCF4\uB529": "Onboarding",
989
- "\uCF54\uC2A4": "Course",
990
- "\uC2E0\uCCAD": "Enrollment",
991
- "\uD034\uC988": "Quiz",
992
- "\uCC3D\uC791": "Creation",
993
- "\uC18C\uC7AC": "Material",
994
- "\uB0B4\uBCF4\uB0B4\uAE30": "Export",
995
- "\uC7AC\uC0DD": "Playback"
996
- };
997
- function getTagPriority(tag) {
998
- const canonical = CANONICAL_TAG[tag] ?? tag;
999
- return TAG_PRIORITY[canonical] ?? DEFAULT_TAG_PRIORITY;
1000
- }
1001
-
1002
- // src/tracking/xlsx/write.ts
1003
- var PLATFORM_TO_XLSX = {
1004
- "client": "client",
1005
- "server": "server",
1006
- "both": "client,server"
1007
- };
1008
- var VALID_PROP_TYPES = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
1009
- var VALID_UPDATE_TYPES = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
1010
- var SNAKE_CASE_RE = /^[a-z][a-z0-9_]*$/;
1011
- var PROP_NAME_RE = /^[a-zA-Z#][a-zA-Z0-9_.]*$/;
1012
- var MIN_COL_WIDTH = 10;
1013
- var PADDING = 3;
1014
- function isWideChar(code) {
1015
- return code >= 19968 && code <= 40959 || // CJK Unified Ideographs
1016
- code >= 13312 && code <= 19903 || // CJK Ext-A
1017
- code >= 12352 && code <= 12447 || // Hiragana
1018
- code >= 12448 && code <= 12543 || // Katakana
1019
- code >= 44032 && code <= 55215 || // Hangul
1020
- code >= 65280 && code <= 65519;
1021
- }
1022
- function displayWidth(s) {
1023
- let w = 0;
1024
- for (const ch of s) {
1025
- w += isWideChar(ch.charCodeAt(0)) ? 2 : 1;
1026
- }
1027
- return w;
1028
- }
1029
- function autoFitSheet(ws, maxWidth = 55) {
1030
- const colCount = ws.columnCount;
1031
- if (colCount === 0) return;
1032
- for (let i = 1; i <= colCount; i++) {
1033
- const col = ws.getColumn(i);
1034
- let maxDisplay = 0;
1035
- let needsWrap = false;
1036
- col.eachCell({ includeEmpty: false }, (cell) => {
1037
- const text = String(cell.value ?? "");
1038
- if (!text) return;
1039
- const dw = displayWidth(text);
1040
- if (dw > maxDisplay) maxDisplay = dw;
1041
- });
1042
- if (maxDisplay === 0) {
1043
- col.width = MIN_COL_WIDTH;
1044
- continue;
1045
- }
1046
- const capped = maxDisplay + PADDING > maxWidth;
1047
- col.width = Math.max(MIN_COL_WIDTH, Math.min(maxWidth, maxDisplay + PADDING));
1048
- if (capped) {
1049
- col.eachCell({ includeEmpty: false }, (cell) => {
1050
- cell.alignment = { ...cell.alignment, wrapText: true };
1051
- });
1052
- }
1053
- }
1054
- }
1055
- function validateDraft(d) {
1056
- const errors = [];
1057
- const eventNames = /* @__PURE__ */ new Set();
1058
- for (const evt of d.events) {
1059
- if (!SNAKE_CASE_RE.test(evt.event_name)) {
1060
- errors.push(`Event name "${evt.event_name}" does not match snake_case pattern`);
1061
- }
1062
- if (eventNames.has(evt.event_name)) {
1063
- errors.push(`Duplicate event_name: "${evt.event_name}"`);
1064
- }
1065
- eventNames.add(evt.event_name);
1066
- }
1067
- const eventProps = d.event_properties ?? d.common_properties ?? [];
1068
- const eventPropNames = /* @__PURE__ */ new Set();
1069
- const compositeProps = new Set(
1070
- eventProps.filter((p) => p.type === "array_row" || p.type === "object").map((p) => p.name)
1071
- );
1072
- for (const prop of eventProps) {
1073
- if (!PROP_NAME_RE.test(prop.name)) {
1074
- errors.push(`Event property name "${prop.name}" has invalid characters`);
1075
- }
1076
- if (prop.name.includes(".")) {
1077
- const parent = prop.name.split(".")[0];
1078
- if (!compositeProps.has(parent)) {
1079
- errors.push(`Nested property "${prop.name}" references non-composite parent "${parent}"`);
1080
- }
1081
- }
1082
- if (!VALID_PROP_TYPES.has(prop.type)) {
1083
- errors.push(`Event property "${prop.name}" has invalid type: "${prop.type}"`);
1084
- }
1085
- if (eventPropNames.has(prop.name)) {
1086
- errors.push(`Duplicate event property name: "${prop.name}"`);
1087
- }
1088
- eventPropNames.add(prop.name);
1089
- }
1090
- const commonProps = d.common_event_properties ?? d.common_properties ?? [];
1091
- const commonPropNames = /* @__PURE__ */ new Set();
1092
- for (const prop of commonProps) {
1093
- if (!VALID_PROP_TYPES.has(prop.type)) {
1094
- errors.push(`Common event property "${prop.name}" has invalid type: "${prop.type}"`);
1095
- }
1096
- if (commonPropNames.has(prop.name)) {
1097
- errors.push(`Duplicate common event property name: "${prop.name}"`);
1098
- }
1099
- commonPropNames.add(prop.name);
1100
- }
1101
- const userPropNames = /* @__PURE__ */ new Set();
1102
- for (const prop of d.user_properties) {
1103
- if (!VALID_PROP_TYPES.has(prop.type)) {
1104
- errors.push(`User property "${prop.name}" has invalid type: "${prop.type}"`);
1105
- }
1106
- if (prop.update_type && !VALID_UPDATE_TYPES.has(prop.update_type)) {
1107
- errors.push(`User property "${prop.name}" has invalid update_type: "${prop.update_type}"`);
1108
- }
1109
- if (userPropNames.has(prop.name)) {
1110
- errors.push(`Duplicate user property name: "${prop.name}"`);
1111
- }
1112
- userPropNames.add(prop.name);
1113
- }
1114
- for (const evt of d.events) {
1115
- if (!evt.prop_names) continue;
1116
- for (const propName of evt.prop_names) {
1117
- if (propName.startsWith("#")) continue;
1118
- if (!eventPropNames.has(propName)) {
1119
- errors.push(`Event "${evt.event_name}" references unknown event property "${propName}"`);
1120
- }
1121
- }
1122
- }
1123
- const eventDisplayNames = /* @__PURE__ */ new Map();
1124
- for (const prop of eventProps) {
1125
- if (prop.display_name) {
1126
- const names = eventDisplayNames.get(prop.display_name) || [];
1127
- names.push(prop.name);
1128
- eventDisplayNames.set(prop.display_name, names);
1129
- }
1130
- }
1131
- for (const [displayName, names] of eventDisplayNames) {
1132
- if (names.length > 1) {
1133
- errors.push(`Display name "${displayName}" is used by multiple event properties: ${names.join(", ")}`);
1134
- }
1135
- }
1136
- const commonDisplayNames = /* @__PURE__ */ new Map();
1137
- for (const prop of commonProps) {
1138
- if (prop.display_name) {
1139
- const names = commonDisplayNames.get(prop.display_name) || [];
1140
- names.push(prop.name);
1141
- commonDisplayNames.set(prop.display_name, names);
1142
- }
1143
- }
1144
- for (const [displayName, names] of commonDisplayNames) {
1145
- if (names.length > 1) {
1146
- errors.push(`Display name "${displayName}" is used by multiple common properties: ${names.join(", ")}`);
1147
- }
1148
- }
1149
- const userDisplayNames = /* @__PURE__ */ new Map();
1150
- for (const prop of d.user_properties) {
1151
- if (prop.display_name) {
1152
- const names = userDisplayNames.get(prop.display_name) || [];
1153
- names.push(prop.name);
1154
- userDisplayNames.set(prop.display_name, names);
1155
- }
1156
- }
1157
- for (const [displayName, names] of userDisplayNames) {
1158
- if (names.length > 1) {
1159
- errors.push(`Display name "${displayName}" is used by multiple user properties: ${names.join(", ")}`);
1160
- }
1161
- }
1162
- const compositeChildren = /* @__PURE__ */ new Map();
1163
- for (const prop of eventProps) {
1164
- if (prop.type === "array_row" || prop.type === "object") {
1165
- compositeChildren.set(prop.name, /* @__PURE__ */ new Set());
1166
- }
1167
- }
1168
- for (const prop of eventProps) {
1169
- if (prop.name.includes(".")) {
1170
- const parent = prop.name.split(".")[0];
1171
- const children = compositeChildren.get(parent);
1172
- if (children) {
1173
- children.add(prop.name);
1174
- }
1175
- }
1176
- }
1177
- for (const evt of d.events) {
1178
- if (!evt.prop_names) continue;
1179
- for (const parentName of compositeProps) {
1180
- if (evt.prop_names.includes(parentName)) {
1181
- const eventChildren = evt.prop_names.filter((p) => p.startsWith(parentName + "."));
1182
- const expectedChildren = compositeChildren.get(parentName);
1183
- if (expectedChildren && eventChildren.length > 0) {
1184
- for (const child of expectedChildren) {
1185
- if (!eventChildren.includes(child)) {
1186
- errors.push(`Event "${evt.event_name}" uses "${parentName}" but missing child "${child}"`);
1187
- }
1188
- }
1189
- }
1190
- }
1191
- }
1192
- }
1193
- const childPropTypes = /* @__PURE__ */ new Map();
1194
- for (const prop of eventProps) {
1195
- if (prop.name.includes(".")) {
1196
- const childName = prop.name;
1197
- const existing = childPropTypes.get(childName);
1198
- if (existing) {
1199
- if (existing.type !== prop.type) {
1200
- errors.push(`Child property "${childName}" has inconsistent types: "${existing.type}" vs "${prop.type}" (used in events: ${existing.events.join(", ")})`);
1201
- }
1202
- } else {
1203
- childPropTypes.set(childName, { type: prop.type, events: [] });
1204
- }
1205
- }
1206
- }
1207
- if (errors.length > 0) {
1208
- throw new Error(`Draft validation failed:
1209
- ${errors.map((e) => " - " + e).join("\n")}`);
1210
- }
1211
- }
1212
- async function writeDraftXlsx(d, outPath, locale = "zh") {
1213
- validateDraft(d);
1214
- const workbook = new ExcelJS.Workbook();
1215
- const eventSheet = workbook.addWorksheet(sheetName("event_data", locale));
1216
- eventSheet.addRow([
1217
- headerName("event_name", locale),
1218
- headerName("event_display_name", locale),
1219
- headerName("event_desc", locale),
1220
- headerName("event_tag", locale),
1221
- headerName("platform", locale),
1222
- headerName("prop_name", locale),
1223
- headerName("prop_display_name", locale),
1224
- headerName("prop_type", locale),
1225
- headerName("prop_desc", locale)
1226
- ]);
1227
- const propByName = new Map(d.event_properties.map((p) => [p.name, p]));
1228
- const autotrackEvents = d.events.filter((e) => e.source === "autotrack");
1229
- const businessEvents = d.events.filter((e) => e.source !== "autotrack");
1230
- const tagGroups = /* @__PURE__ */ new Map();
1231
- const tagOrder = [];
1232
- for (const evt of businessEvents) {
1233
- const tag = evt.event_tag || "";
1234
- if (!tagGroups.has(tag)) {
1235
- tagGroups.set(tag, []);
1236
- tagOrder.push(tag);
1237
- }
1238
- tagGroups.get(tag).push(evt);
1239
- }
1240
- tagOrder.sort((a, b) => getTagPriority(a) - getTagPriority(b));
1241
- const sorted = [...autotrackEvents];
1242
- for (const tag of tagOrder) {
1243
- for (const evt of tagGroups.get(tag)) {
1244
- sorted.push(evt);
1245
- }
1246
- }
1247
- for (const evt of sorted) {
1248
- const startRow = eventSheet.rowCount + 1;
1249
- const platformStr = evt.platform ? PLATFORM_TO_XLSX[evt.platform] : "";
1250
- if (evt.prop_names.length === 0) {
1251
- eventSheet.addRow([
1252
- evt.event_name,
1253
- evt.display_name ?? "",
1254
- evt.event_desc ?? "",
1255
- evt.event_tag ?? "",
1256
- platformStr,
1257
- "",
1258
- "",
1259
- "",
1260
- ""
1261
- ]);
1262
- } else {
1263
- for (const propName of evt.prop_names) {
1264
- const prop = propByName.get(propName);
1265
- eventSheet.addRow([
1266
- evt.event_name,
1267
- evt.display_name ?? "",
1268
- evt.event_desc ?? "",
1269
- evt.event_tag ?? "",
1270
- platformStr,
1271
- prop?.name ?? propName,
1272
- prop?.display_name ?? "",
1273
- prop ? typeToDisplay(prop.type, locale) : "",
1274
- prop?.desc ?? ""
1275
- ]);
1276
- }
1277
- const endRow = eventSheet.rowCount;
1278
- if (endRow > startRow) {
1279
- for (const col of ["A", "B", "C", "D", "E"]) {
1280
- eventSheet.mergeCells(`${col}${startRow}:${col}${endRow}`);
1281
- }
1282
- for (let r = startRow; r <= endRow; r++) {
1283
- const row = eventSheet.getRow(r);
1284
- for (const col of ["A", "B", "C", "D", "E"]) {
1285
- const cell = row.getCell(col);
1286
- cell.alignment = { ...cell.alignment, vertical: "middle" };
1287
- }
1288
- }
1289
- }
1290
- }
1291
- }
1292
- autoFitSheet(eventSheet, 50);
1293
- const commonSheet = workbook.addWorksheet(sheetName("common_props", locale));
1294
- commonSheet.addRow([
1295
- headerName("common_prop_name", locale),
1296
- headerName("common_prop_display_name", locale),
1297
- headerName("common_prop_type", locale),
1298
- headerName("common_prop_desc", locale)
1299
- ]);
1300
- for (const prop of d.common_event_properties) {
1301
- commonSheet.addRow([
1302
- prop.name,
1303
- prop.display_name ?? "",
1304
- typeToDisplay(prop.type, locale),
1305
- prop.desc ?? ""
1306
- ]);
1307
- }
1308
- autoFitSheet(commonSheet, 50);
1309
- const userSheet = workbook.addWorksheet(sheetName("user_data", locale));
1310
- userSheet.addRow([
1311
- headerName("user_prop_name", locale),
1312
- headerName("user_prop_display_name", locale),
1313
- headerName("user_prop_type", locale),
1314
- headerName("update_type", locale),
1315
- headerName("user_prop_desc", locale),
1316
- headerName("prop_tag", locale)
1317
- ]);
1318
- for (const prop of d.user_properties) {
1319
- userSheet.addRow([
1320
- prop.name,
1321
- prop.display_name ?? "",
1322
- typeToDisplay(prop.type, locale),
1323
- prop.update_type ?? "user_set",
1324
- // 默认 user_set
1325
- prop.desc ?? "",
1326
- prop.prop_tag ?? ""
1327
- ]);
1328
- }
1329
- autoFitSheet(userSheet, 50);
1330
- const userIdSheet = workbook.addWorksheet(sheetName("user_id", locale));
1331
- userIdSheet.addRow([
1332
- headerName("user_id_prop_name", locale),
1333
- headerName("user_id_display_name", locale),
1334
- headerName("user_id_desc", locale),
1335
- headerName("user_id_value_desc", locale)
1336
- ]);
1337
- 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)]);
1338
- userIdSheet.addRow(["#distinct_id", t("user_id.distinct_id_display", {}, locale), t("user_id.system_property", {}, locale), t("user_id.auto_generated", {}, locale)]);
1339
- autoFitSheet(userIdSheet, 50);
1340
- await workbook.xlsx.writeFile(outPath);
1341
- }
1342
-
1343
509
  // src/core/tracking-client.ts
1344
510
  var DEBUG_BASE = "/v1/ta/bury/manage/debug";
1345
511
  var TRACK_LOCAL_HOST = "http://localhost:8992";
@@ -1572,9 +738,9 @@ async function fetchPlan({ projectId, host }) {
1572
738
  if (!data) {
1573
739
  throw new Error(t("error.fetch_no_data", { host }));
1574
740
  }
1575
- return normalize2(data);
741
+ return normalize(data);
1576
742
  }
1577
- function normalize2(data) {
743
+ function normalize(data) {
1578
744
  return {
1579
745
  meta: { app_type: "unknown", sdk_integration_mode: "client_only", plan_name: "from-te" },
1580
746
  events: (data.events ?? []).map((e) => ({
@@ -1821,292 +987,6 @@ function injectAutotrackEvents(draft, locale = "zh") {
1821
987
  return draft;
1822
988
  }
1823
989
 
1824
- // src/tracking/plan/fix.ts
1825
- function extractErrors(response) {
1826
- const errors = [];
1827
- if (response.data?.eventErrorMap) {
1828
- for (const [errorType, items] of Object.entries(response.data.eventErrorMap)) {
1829
- for (const item of items) {
1830
- errors.push({ ...item, errorType });
1831
- }
1832
- }
1833
- }
1834
- if (response.data?.userErrorMap) {
1835
- for (const [errorType, items] of Object.entries(response.data.userErrorMap)) {
1836
- for (const item of items) {
1837
- errors.push({ ...item, errorType });
1838
- }
1839
- }
1840
- }
1841
- return errors;
1842
- }
1843
- function fixDisplayDuplicate(draft, errors) {
1844
- const duplicateDisplayNames = /* @__PURE__ */ new Map();
1845
- for (const error of errors) {
1846
- if (error.errorType === "event_prop_display_duplicate") {
1847
- const names = duplicateDisplayNames.get(error.value) || [];
1848
- names.push(error.value);
1849
- duplicateDisplayNames.set(error.value, names);
1850
- }
1851
- }
1852
- for (const prop of draft.event_properties) {
1853
- if (duplicateDisplayNames.has(prop.display_name || "")) {
1854
- const eventsUsingProp = draft.events.filter((e) => e.prop_names.includes(prop.name));
1855
- if (prop.name.includes(".")) {
1856
- prop.display_name = `\u660E\u7EC6${prop.display_name}`;
1857
- } else if (eventsUsingProp.length > 0) {
1858
- prop.display_name = `${prop.display_name}${t("fix.detail_suffix")}`;
1859
- }
1860
- }
1861
- }
1862
- }
1863
- function fixArrayRowConsistency(draft, errors) {
1864
- const compositeChildren = /* @__PURE__ */ new Map();
1865
- const evProps = draft.event_properties ?? draft.common_properties ?? [];
1866
- for (const prop of evProps) {
1867
- if (prop.type === "array_row" || prop.type === "object") {
1868
- compositeChildren.set(prop.name, []);
1869
- }
1870
- }
1871
- for (const prop of evProps) {
1872
- if (prop.name.includes(".")) {
1873
- const parent = prop.name.split(".")[0];
1874
- const children = compositeChildren.get(parent);
1875
- if (children) {
1876
- children.push(prop.name);
1877
- }
1878
- }
1879
- }
1880
- for (const event of draft.events) {
1881
- if (!event.prop_names) continue;
1882
- const propNamesSet = new Set(event.prop_names);
1883
- for (const [parentName, children] of compositeChildren) {
1884
- if (propNamesSet.has(parentName)) {
1885
- for (const child of children) {
1886
- if (!propNamesSet.has(child)) {
1887
- event.prop_names.push(child);
1888
- }
1889
- }
1890
- const parentProps = event.prop_names.filter(
1891
- (p) => p === parentName || p.startsWith(parentName + ".")
1892
- );
1893
- const sorted = [parentName, ...children.filter((c) => event.prop_names.includes(c))];
1894
- event.prop_names = event.prop_names.filter(
1895
- (p) => !p.startsWith(parentName) || p === parentName
1896
- );
1897
- const idx = event.prop_names.indexOf(parentName);
1898
- if (idx >= 0) {
1899
- event.prop_names.splice(idx, 1, ...sorted);
1900
- }
1901
- }
1902
- }
1903
- }
1904
- }
1905
- function fixUnknownPropRefs(draft) {
1906
- const fixed = [];
1907
- const props = draft.event_properties ?? draft.common_properties ?? [];
1908
- const eventPropNames = new Set(props.map((p) => p.name));
1909
- for (const event of draft.events) {
1910
- if (!event.prop_names) continue;
1911
- const removed = [];
1912
- event.prop_names = event.prop_names.filter((pn) => {
1913
- if (pn.startsWith("#")) return true;
1914
- if (eventPropNames.has(pn)) return true;
1915
- removed.push(pn);
1916
- return false;
1917
- });
1918
- if (removed.length > 0) {
1919
- fixed.push(...removed.map((r) => `Removed unknown prop "${r}" from event "${event.event_name}"`));
1920
- }
1921
- }
1922
- return fixed;
1923
- }
1924
- function fixDisplayNameDuplicates(draft) {
1925
- const fixed = [];
1926
- const pools = [
1927
- { name: "event_properties", items: draft.event_properties ?? draft.common_properties ?? [] },
1928
- { name: "common_event_properties", items: draft.common_event_properties ?? draft.common_properties ?? [] },
1929
- { name: "user_properties", items: draft.user_properties ?? [] }
1930
- ];
1931
- for (const pool of pools) {
1932
- const displayMap = /* @__PURE__ */ new Map();
1933
- for (let i = 0; i < pool.items.length; i++) {
1934
- const dn = pool.items[i].display_name;
1935
- if (!dn) continue;
1936
- const list = displayMap.get(dn) || [];
1937
- list.push(i);
1938
- displayMap.set(dn, list);
1939
- }
1940
- for (const [displayName, indices] of displayMap) {
1941
- if (indices.length <= 1) continue;
1942
- for (let j = 1; j < indices.length; j++) {
1943
- const prop = pool.items[indices[j]];
1944
- const newDisplayName = `${displayName} (${prop.name})`;
1945
- prop.display_name = newDisplayName;
1946
- fixed.push(`Disambiguated display name "${displayName}" \u2192 "${newDisplayName}" in ${pool.name}`);
1947
- }
1948
- }
1949
- }
1950
- return fixed;
1951
- }
1952
- function fixCrossPoolDisplayNameInconsistency(draft) {
1953
- const fixed = [];
1954
- const commonProps = draft.common_event_properties ?? [];
1955
- const eventProps = draft.event_properties ?? [];
1956
- for (const cp2 of commonProps) {
1957
- if (!cp2.display_name) continue;
1958
- const ep = eventProps.find((p) => p.name === cp2.name);
1959
- if (!ep) continue;
1960
- if (ep.display_name && ep.display_name !== cp2.display_name) {
1961
- const oldName = ep.display_name;
1962
- ep.display_name = cp2.display_name;
1963
- fixed.push(
1964
- `Aligned display_name for "${cp2.name}" in event_properties: "${oldName}" \u2192 "${cp2.display_name}" (from common_event_properties)`
1965
- );
1966
- }
1967
- }
1968
- return fixed;
1969
- }
1970
- function fixEventPlatforms(draft) {
1971
- const fixed = [];
1972
- const mode = draft.meta.sdk_integration_mode;
1973
- if (mode !== "client_only" && mode !== "server_only") return fixed;
1974
- const targetPlatform = mode === "client_only" ? "client" : "server";
1975
- let count = 0;
1976
- for (const event of draft.events) {
1977
- if (!event.platform) {
1978
- event.platform = targetPlatform;
1979
- count++;
1980
- }
1981
- }
1982
- if (count > 0) {
1983
- fixed.push(
1984
- `Auto-filled platform="${targetPlatform}" for ${count} event(s) based on sdk_integration_mode="${mode}"`
1985
- );
1986
- }
1987
- return fixed;
1988
- }
1989
- function fixEventPropNameInvalid(draft, errors) {
1990
- const invalidNames = /* @__PURE__ */ new Set();
1991
- for (const error of errors) {
1992
- if (error.errorType === "event_prop_name_invalid") {
1993
- invalidNames.add(error.value);
1994
- }
1995
- }
1996
- for (const prop of draft.event_properties) {
1997
- if (invalidNames.has(prop.name)) {
1998
- 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();
1999
- const oldName = prop.name;
2000
- prop.name = fixedName;
2001
- for (const event of draft.events) {
2002
- const idx = event.prop_names.indexOf(oldName);
2003
- if (idx >= 0) {
2004
- event.prop_names[idx] = fixedName;
2005
- }
2006
- }
2007
- if (prop.display_name && !prop.display_name.includes("(")) {
2008
- prop.display_name = `${prop.display_name}${t("fix.auto_fix_suffix")}`;
2009
- }
2010
- }
2011
- }
2012
- }
2013
- function fixEventNameDuplicate(draft, errors) {
2014
- const duplicateEvents = /* @__PURE__ */ new Set();
2015
- for (const error of errors) {
2016
- if (error.errorType === "event_name_duplicate") {
2017
- duplicateEvents.add(error.value);
2018
- }
2019
- }
2020
- const seen = /* @__PURE__ */ new Set();
2021
- draft.events = draft.events.filter((event) => {
2022
- if (duplicateEvents.has(event.event_name)) {
2023
- if (seen.has(event.event_name)) {
2024
- return false;
2025
- }
2026
- seen.add(event.event_name);
2027
- }
2028
- return true;
2029
- });
2030
- }
2031
- function fixDraft(draft, response) {
2032
- const errors = extractErrors(response);
2033
- const fixed = [];
2034
- if (errors.length === 0) {
2035
- return fixed;
2036
- }
2037
- const errorTypes = new Set(errors.map((e) => e.errorType));
2038
- if (errorTypes.has("event_prop_display_duplicate")) {
2039
- fixDisplayDuplicate(draft, errors);
2040
- fixed.push(t("fix.display_name_dedup"));
2041
- }
2042
- if (errorTypes.has("complex_event_property_should_has_same_child_property")) {
2043
- fixArrayRowConsistency(draft, errors);
2044
- fixed.push(t("fix.array_row_consistency"));
2045
- }
2046
- if (errorTypes.has("event_prop_name_invalid")) {
2047
- fixEventPropNameInvalid(draft, errors);
2048
- fixed.push(t("fix.event_prop_name_invalid"));
2049
- }
2050
- if (errorTypes.has("event_name_duplicate")) {
2051
- fixEventNameDuplicate(draft, errors);
2052
- fixed.push(t("fix.event_name_duplicate"));
2053
- }
2054
- return fixed;
2055
- }
2056
- function validateAndFix(draft) {
2057
- const fixed = [];
2058
- const unknownFixes = fixUnknownPropRefs(draft);
2059
- if (unknownFixes.length > 0) {
2060
- fixed.push(t("fix.unknown_prop_ref"));
2061
- }
2062
- const displayFixes = fixDisplayNameDuplicates(draft);
2063
- if (displayFixes.length > 0) {
2064
- fixed.push(t("fix.display_name_dedup"));
2065
- }
2066
- const crossPoolFixes = fixCrossPoolDisplayNameInconsistency(draft);
2067
- if (crossPoolFixes.length > 0) {
2068
- fixed.push(`Cross-pool display_name consistency: ${crossPoolFixes.length} property(s) aligned`);
2069
- }
2070
- const platformFixes = fixEventPlatforms(draft);
2071
- if (platformFixes.length > 0) {
2072
- fixed.push(...platformFixes);
2073
- }
2074
- const compositeChildren = /* @__PURE__ */ new Map();
2075
- const evProps = draft.event_properties ?? draft.common_properties ?? [];
2076
- for (const prop of evProps) {
2077
- if (prop.type === "array_row" || prop.type === "object") {
2078
- compositeChildren.set(prop.name, []);
2079
- }
2080
- }
2081
- for (const prop of evProps) {
2082
- if (prop.name.includes(".")) {
2083
- const parent = prop.name.split(".")[0];
2084
- const children = compositeChildren.get(parent);
2085
- if (children) {
2086
- children.push(prop.name);
2087
- }
2088
- }
2089
- }
2090
- let needFix = false;
2091
- for (const event of draft.events) {
2092
- if (!event.prop_names) continue;
2093
- for (const [parentName, children] of compositeChildren) {
2094
- if (event.prop_names.includes(parentName)) {
2095
- for (const child of children) {
2096
- if (!event.prop_names.includes(child)) {
2097
- needFix = true;
2098
- }
2099
- }
2100
- }
2101
- }
2102
- }
2103
- if (needFix) {
2104
- fixArrayRowConsistency(draft, []);
2105
- fixed.push(t("fix.array_row_consistency"));
2106
- }
2107
- return fixed;
2108
- }
2109
-
2110
990
  // src/tracking/plan/conflict.ts
2111
991
  function detectConflicts(newDraft, existingDraft) {
2112
992
  const conflicts = [];
@@ -2203,11 +1083,11 @@ function formatConflictReport(result, existingSummary) {
2203
1083
  }
2204
1084
 
2205
1085
  // src/commands/tracking/plan.ts
2206
- import { existsSync as existsSync5 } from "fs";
1086
+ import { existsSync as existsSync3 } from "fs";
2207
1087
 
2208
1088
  // src/tracking/templates.ts
2209
1089
  import { readdir } from "fs/promises";
2210
- import { existsSync as existsSync3 } from "fs";
1090
+ import { existsSync } from "fs";
2211
1091
  import { resolve } from "path";
2212
1092
  function getTemplateDirs() {
2213
1093
  return [
@@ -2218,7 +1098,7 @@ function getTemplateDirs() {
2218
1098
  async function listTrackingTemplates() {
2219
1099
  const found = [];
2220
1100
  for (const dir of getTemplateDirs()) {
2221
- if (!existsSync3(dir)) continue;
1101
+ if (!existsSync(dir)) continue;
2222
1102
  let entries = [];
2223
1103
  try {
2224
1104
  entries = await readdir(dir);
@@ -2230,7 +1110,7 @@ async function listTrackingTemplates() {
2230
1110
  const base = f.replace(/\.xlsx$/i, "");
2231
1111
  const xlsxPath = resolve(dir, f);
2232
1112
  const mdPath = resolve(dir, base + ".md");
2233
- const hasMd = existsSync3(mdPath);
1113
+ const hasMd = existsSync(mdPath);
2234
1114
  found.push({
2235
1115
  path: hasMd ? mdPath : xlsxPath,
2236
1116
  xlsxPath,
@@ -2256,7 +1136,7 @@ async function resolveTrackingTemplateByName(name) {
2256
1136
  }
2257
1137
 
2258
1138
  // src/commands/tracking/shared.ts
2259
- import { existsSync as existsSync4, statSync } from "fs";
1139
+ import { existsSync as existsSync2, statSync } from "fs";
2260
1140
  var HOST_OPTION_DESC = "Override active AE host URL";
2261
1141
  function resolveTrackingHost(program2, opts) {
2262
1142
  const root = program2.root ?? program2;
@@ -2269,7 +1149,7 @@ function resolveTrackingHost(program2, opts) {
2269
1149
  return host;
2270
1150
  }
2271
1151
  function isExistingDirectory(path4) {
2272
- if (!existsSync4(path4)) return false;
1152
+ if (!existsSync2(path4)) return false;
2273
1153
  try {
2274
1154
  return statSync(path4).isDirectory();
2275
1155
  } catch {
@@ -2285,7 +1165,7 @@ function assertOutputFilePath(path4, optionName = "--out") {
2285
1165
  }
2286
1166
  function assertInputFilePath(path4, optionName = "--in") {
2287
1167
  const trimmed = path4.trim();
2288
- if (!existsSync4(trimmed)) {
1168
+ if (!existsSync2(trimmed)) {
2289
1169
  console.error(t("error.input_path_not_found", { path: trimmed, option: optionName }));
2290
1170
  process.exit(1);
2291
1171
  }
@@ -2490,7 +1370,7 @@ function registerPlan(cmd, rootProgram) {
2490
1370
  assertInputFilePath(opts.xlsx, "--xlsx");
2491
1371
  const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2492
1372
  const dest = resolve2(opts.plansDir, `${stamp}-${opts.name}.xlsx`);
2493
- if (existsSync5(dest)) {
1373
+ if (existsSync3(dest)) {
2494
1374
  console.error(t("plan.archive_exists", { path: dest }));
2495
1375
  console.error(t("plan.remove_or_rename"));
2496
1376
  return;
@@ -2539,11 +1419,11 @@ function registerPlan(cmd, rootProgram) {
2539
1419
 
2540
1420
  // src/commands/tracking/code.ts
2541
1421
  import { readFile as readFile4, writeFile as writeFile2, mkdir } from "fs/promises";
2542
- import { dirname as dirname2 } from "path";
1422
+ import { dirname } from "path";
2543
1423
 
2544
1424
  // src/tracking/project-detect/detect.ts
2545
1425
  import { readFile as readFile2, readdir as readdir2, stat } from "fs/promises";
2546
- import { join as join3 } from "path";
1426
+ import { join } from "path";
2547
1427
  async function exists(p) {
2548
1428
  try {
2549
1429
  await stat(p);
@@ -2560,14 +1440,14 @@ async function readJson(p) {
2560
1440
  }
2561
1441
  }
2562
1442
  async function classifyDir(cwd) {
2563
- if (await exists(join3(cwd, "project.config.json"))) {
2564
- const cfg = await readJson(join3(cwd, "project.config.json"));
1443
+ if (await exists(join(cwd, "project.config.json"))) {
1444
+ const cfg = await readJson(join(cwd, "project.config.json"));
2565
1445
  if (cfg && "miniprogramRoot" in cfg) return "mini-program";
2566
1446
  }
2567
- if (await exists(join3(cwd, "ProjectSettings/ProjectVersion.txt"))) return "unity";
2568
- if (await exists(join3(cwd, "Podfile"))) return "ios";
2569
- if (await exists(join3(cwd, "build.gradle")) || await exists(join3(cwd, "settings.gradle"))) return "android";
2570
- const pkg2 = await readJson(join3(cwd, "package.json"));
1447
+ if (await exists(join(cwd, "ProjectSettings/ProjectVersion.txt"))) return "unity";
1448
+ if (await exists(join(cwd, "Podfile"))) return "ios";
1449
+ if (await exists(join(cwd, "build.gradle")) || await exists(join(cwd, "settings.gradle"))) return "android";
1450
+ const pkg2 = await readJson(join(cwd, "package.json"));
2571
1451
  if (pkg2) {
2572
1452
  const deps = { ...pkg2.dependencies ?? {}, ...pkg2.devDependencies ?? {} };
2573
1453
  if (deps.astro) return "web-astro";
@@ -2577,9 +1457,9 @@ async function classifyDir(cwd) {
2577
1457
  if (deps.express || deps.fastify || deps.koa) return "node-server";
2578
1458
  return "web-vanilla";
2579
1459
  }
2580
- if (await exists(join3(cwd, "go.mod"))) return "go-server";
2581
- if (await exists(join3(cwd, "pom.xml"))) return "java-server";
2582
- if (await exists(join3(cwd, "pyproject.toml")) || await exists(join3(cwd, "requirements.txt"))) return "python-server";
1460
+ if (await exists(join(cwd, "go.mod"))) return "go-server";
1461
+ if (await exists(join(cwd, "pom.xml"))) return "java-server";
1462
+ if (await exists(join(cwd, "pyproject.toml")) || await exists(join(cwd, "requirements.txt"))) return "python-server";
2583
1463
  return "unknown";
2584
1464
  }
2585
1465
  async function classify(cwd) {
@@ -2594,7 +1474,7 @@ async function classify(cwd) {
2594
1474
  const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules").slice(0, 20);
2595
1475
  let vanillaMatch;
2596
1476
  for (const d of dirs) {
2597
- const sub = await classifyDir(join3(cwd, d.name));
1477
+ const sub = await classifyDir(join(cwd, d.name));
2598
1478
  if (sub !== "unknown" && sub !== "web-vanilla") {
2599
1479
  return { appType: sub, subPath: d.name };
2600
1480
  }
@@ -2642,8 +1522,8 @@ async function detectProject(cwd) {
2642
1522
  import XLSXMod from "xlsx";
2643
1523
  import path3 from "path";
2644
1524
  var XLSX = XLSXMod.default ?? XLSXMod;
2645
- var VALID_PROP_TYPES2 = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
2646
- var VALID_UPDATE_TYPES2 = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
1525
+ var VALID_PROP_TYPES = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
1526
+ var VALID_UPDATE_TYPES = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
2647
1527
  function normalizeHeader(h) {
2648
1528
  return h.trim().replace(/[((]\s*(?:必填|必須|필수|required|Required)\s*[))]/g, "").trim().replace(/名称$/g, "\u540D");
2649
1529
  }
@@ -2674,7 +1554,7 @@ function cellStr(row, idx) {
2674
1554
  function parsePropType(raw, propName, sheetCtx) {
2675
1555
  const canonical = displayToType(raw);
2676
1556
  if (canonical) return canonical;
2677
- if (VALID_PROP_TYPES2.has(raw)) return raw;
1557
+ if (VALID_PROP_TYPES.has(raw)) return raw;
2678
1558
  process.stderr.write(
2679
1559
  `[read] unknown type "${raw}" on ${sheetCtx}:${propName}, defaulting to string
2680
1560
  `
@@ -2682,7 +1562,7 @@ function parsePropType(raw, propName, sheetCtx) {
2682
1562
  return "string";
2683
1563
  }
2684
1564
  function parseUpdateType(raw, propName) {
2685
- if (VALID_UPDATE_TYPES2.has(raw)) return raw;
1565
+ if (VALID_UPDATE_TYPES.has(raw)) return raw;
2686
1566
  process.stderr.write(
2687
1567
  `[xlsx/read] Warning: unknown update_type "${raw}" for user property "${propName}", falling back to "user_set"
2688
1568
  `
@@ -2695,7 +1575,7 @@ function shouldSkipRow(row, firstColIdx) {
2695
1575
  if (!/^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(first)) return true;
2696
1576
  return false;
2697
1577
  }
2698
- function parseEventSheet(rows, source, sheetName2) {
1578
+ function parseEventSheet(rows, source, sheetName) {
2699
1579
  const eventsMap = /* @__PURE__ */ new Map();
2700
1580
  const propsMap = /* @__PURE__ */ new Map();
2701
1581
  const eventsOrder = [];
@@ -2797,7 +1677,7 @@ function parseEventSheet(rows, source, sheetName2) {
2797
1677
  evt.prop_names.push(propName);
2798
1678
  }
2799
1679
  if (!propsMap.has(propName)) {
2800
- const propType = parsePropType(propTypeRaw, propName, sheetName2);
1680
+ const propType = parsePropType(propTypeRaw, propName, sheetName);
2801
1681
  const prop = {
2802
1682
  name: propName,
2803
1683
  type: propType,
@@ -2808,7 +1688,7 @@ function parseEventSheet(rows, source, sheetName2) {
2808
1688
  propsMap.set(propName, prop);
2809
1689
  } else {
2810
1690
  const existing = propsMap.get(propName);
2811
- const newType = parsePropType(propTypeRaw, propName, sheetName2);
1691
+ const newType = parsePropType(propTypeRaw, propName, sheetName);
2812
1692
  if (propTypeRaw && existing.type !== newType) {
2813
1693
  process.stderr.write(
2814
1694
  `[xlsx/read] Warning: property "${propName}" has conflicting types: "${existing.type}" vs "${newType}". Keeping first.
@@ -2822,7 +1702,7 @@ function parseEventSheet(rows, source, sheetName2) {
2822
1702
  const event_properties = Array.from(propsMap.values());
2823
1703
  return { events, event_properties };
2824
1704
  }
2825
- function parseCommonEventSheet(rows, source, sheetName2) {
1705
+ function parseCommonEventSheet(rows, source, sheetName) {
2826
1706
  const props = [];
2827
1707
  const seen = /* @__PURE__ */ new Set();
2828
1708
  if (rows.length < 2) return props;
@@ -2866,7 +1746,7 @@ function parseCommonEventSheet(rows, source, sheetName2) {
2866
1746
  seen.add(name);
2867
1747
  const prop = {
2868
1748
  name,
2869
- type: parsePropType(typeRaw, name, sheetName2),
1749
+ type: parsePropType(typeRaw, name, sheetName),
2870
1750
  source
2871
1751
  };
2872
1752
  if (displayName) prop.display_name = displayName;
@@ -2875,7 +1755,7 @@ function parseCommonEventSheet(rows, source, sheetName2) {
2875
1755
  }
2876
1756
  return props;
2877
1757
  }
2878
- function parseUserDataSheet(rows, source, sheetName2) {
1758
+ function parseUserDataSheet(rows, source, sheetName) {
2879
1759
  const props = [];
2880
1760
  const seen = /* @__PURE__ */ new Set();
2881
1761
  if (rows.length < 2) return props;
@@ -2916,7 +1796,7 @@ function parseUserDataSheet(rows, source, sheetName2) {
2916
1796
  seen.add(name);
2917
1797
  const prop = {
2918
1798
  name,
2919
- type: parsePropType(typeRaw, name, sheetName2),
1799
+ type: parsePropType(typeRaw, name, sheetName),
2920
1800
  update_type: parseUpdateType(updateTypeRaw, name),
2921
1801
  source
2922
1802
  };
@@ -3020,14 +1900,14 @@ function findCol(colIndex, candidates, fallback) {
3020
1900
  }
3021
1901
  return fallback;
3022
1902
  }
3023
- var VALID_UPDATE_TYPES3 = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
1903
+ var VALID_UPDATE_TYPES2 = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
3024
1904
  function parseType(raw) {
3025
1905
  const canonical = displayToType(raw);
3026
1906
  if (canonical) return canonical;
3027
1907
  return "string";
3028
1908
  }
3029
1909
  function parseUpdateType2(raw) {
3030
- if (VALID_UPDATE_TYPES3.has(raw)) return raw;
1910
+ if (VALID_UPDATE_TYPES2.has(raw)) return raw;
3031
1911
  return "user_set";
3032
1912
  }
3033
1913
  function trimCell(s) {
@@ -3277,7 +2157,7 @@ function registerCode(cmd) {
3277
2157
  if (opts.server) {
3278
2158
  draft.meta.server_language = opts.server;
3279
2159
  }
3280
- await mkdir(dirname2(opts.out), { recursive: true });
2160
+ await mkdir(dirname(opts.out), { recursive: true });
3281
2161
  await writeFile2(opts.out, JSON.stringify(draft, null, 2), "utf8");
3282
2162
  process.stdout.write(t("code.wrote_events", { count: draft.events.length, path: opts.out }) + "\n");
3283
2163
  });
@@ -3310,13 +2190,13 @@ function registerCode(cmd) {
3310
2190
  }
3311
2191
 
3312
2192
  // src/tracking/wiki-query/query.ts
3313
- import { readFileSync as readFileSync3, existsSync as existsSync6 } from "fs";
3314
- import { join as join4 } from "path";
3315
- var WIKI_ROOT = join4(getPackageRoot(), "wiki/te-docs");
2193
+ import { readFileSync, existsSync as existsSync4 } from "fs";
2194
+ import { join as join2 } from "path";
2195
+ var WIKI_ROOT = join2(getPackageRoot(), "wiki/te-docs");
3316
2196
  function searchIndex(keyword) {
3317
- const indexPath = join4(WIKI_ROOT, "index.md");
3318
- if (!existsSync6(indexPath)) return [];
3319
- const lines = readFileSync3(indexPath, "utf8").split("\n");
2197
+ const indexPath = join2(WIKI_ROOT, "index.md");
2198
+ if (!existsSync4(indexPath)) return [];
2199
+ const lines = readFileSync(indexPath, "utf8").split("\n");
3320
2200
  const kw = keyword.toLowerCase();
3321
2201
  const hits = [];
3322
2202
  for (const line of lines) {
@@ -3471,62 +2351,72 @@ program.name("ae-cli").version(version).description("CLI tool for ThinkingAI (AE
3471
2351
  async function loadCommands() {
3472
2352
  const commands = [];
3473
2353
  try {
3474
- const teAnalysis = await import("./te-analysis-O6DCO6BS.js");
2354
+ const teAnalysis = await import("./te-analysis-7VUNUYWZ.js");
3475
2355
  commands.push(...teAnalysis.default);
3476
2356
  } catch {
3477
2357
  }
3478
2358
  try {
3479
- const engage = await import("./te-engage-FGBGQ4IY.js");
2359
+ const engage = await import("./te-engage-N5WI32H6.js");
3480
2360
  commands.push(...engage.default);
3481
2361
  } catch {
3482
2362
  }
3483
2363
  try {
3484
- const experiment = await import("./te-experiment-SO5MPDMJ.js");
2364
+ const experiment = await import("./te-experiment-6BITX4RD.js");
3485
2365
  commands.push(...experiment.default);
3486
2366
  } catch {
3487
2367
  }
3488
2368
  try {
3489
- const community = await import("./te-community-HLC43QKH.js");
2369
+ const community = await import("./te-community-5DMNKJWY.js");
3490
2370
  commands.push(...community.default);
3491
2371
  } catch {
3492
2372
  }
3493
2373
  try {
3494
- const dataops = await import("./te-dataops-EJP56W3K.js");
2374
+ const dataops = await import("./te-dataops-CVULXNVB.js");
3495
2375
  commands.push(...dataops.default);
3496
2376
  } catch {
3497
2377
  }
3498
2378
  try {
3499
- const teKb = await import("./te-kb-APXBWBDY.js");
2379
+ const teKb = await import("./te-kb-RCLSSH2Q.js");
3500
2380
  commands.push(...teKb.default);
3501
2381
  } catch {
3502
2382
  }
3503
2383
  try {
3504
- const teTeam = await import("./te-team-EFKWYKMK.js");
2384
+ const teTeam = await import("./te-team-ADOC2ROP.js");
3505
2385
  commands.push(...teTeam.default);
3506
2386
  } catch {
3507
2387
  }
3508
2388
  try {
3509
- const teAgent = await import("./te-agent-4BKBODMF.js");
2389
+ const teAgent = await import("./te-agent-VLYOV7S4.js");
3510
2390
  commands.push(...teAgent.default);
3511
2391
  } catch {
3512
2392
  }
3513
2393
  try {
3514
- const memory = await import("./memory-YK33G4T7.js");
2394
+ const memory = await import("./memory-I2WXDTV2.js");
3515
2395
  commands.push(...memory.default);
3516
2396
  } catch {
3517
2397
  }
3518
2398
  try {
3519
- const teSystem = await import("./te-system-Z77IKZFN.js");
2399
+ const teSystem = await import("./te-system-FXITO2JG.js");
3520
2400
  commands.push(...teSystem.default);
3521
2401
  } catch {
3522
2402
  }
3523
2403
  try {
3524
- const metadata = await import("./metadata-UILXHBWF.js");
2404
+ const metadata = await import("./metadata-VUOQJE26.js");
3525
2405
  commands.push(...metadata.default);
3526
2406
  } catch {
3527
2407
  }
3528
2408
  try {
3529
- const dataIntegration = await import("./data-integration-2MYMANJI.js");
2409
+ const projectSemantic = await import("./project-semantic-RT3R2VQD.js");
2410
+ commands.push(...projectSemantic.default);
2411
+ } catch {
2412
+ }
2413
+ try {
2414
+ const personalSemanticPreference = await import("./personal-semantic-preference-LIPACBDX.js");
2415
+ commands.push(...personalSemanticPreference.default);
2416
+ } catch {
2417
+ }
2418
+ try {
2419
+ const dataIntegration = await import("./data-integration-QEKDWQDY.js");
3530
2420
  commands.push(...dataIntegration.default);
3531
2421
  } catch {
3532
2422
  }
@@ -3534,42 +2424,42 @@ async function loadCommands() {
3534
2424
  }
3535
2425
  async function registerAuthCommands() {
3536
2426
  try {
3537
- const { registerAuth } = await import("./auth-77BUFLGC.js");
2427
+ const { registerAuth } = await import("./auth-ROB2EDYV.js");
3538
2428
  registerAuth(program);
3539
2429
  } catch {
3540
2430
  }
3541
2431
  }
3542
2432
  async function registerConfigCommands() {
3543
2433
  try {
3544
- const { registerConfig } = await import("./config-RE6CMGPK.js");
2434
+ const { registerConfig } = await import("./config-BMYZX2UE.js");
3545
2435
  registerConfig(program);
3546
2436
  } catch {
3547
2437
  }
3548
2438
  }
3549
2439
  async function registerCapabilityCommands() {
3550
2440
  try {
3551
- const { registerCapability } = await import("./capability-PJHNI4GJ.js");
2441
+ const { registerCapability } = await import("./capability-HYVVPG25.js");
3552
2442
  registerCapability(program);
3553
2443
  } catch {
3554
2444
  }
3555
2445
  }
3556
2446
  async function registerSyncCommand() {
3557
2447
  try {
3558
- const { registerSync } = await import("./sync-FCKOVWWS.js");
2448
+ const { registerSync } = await import("./sync-HKIOZXQE.js");
3559
2449
  registerSync(program);
3560
2450
  } catch {
3561
2451
  }
3562
2452
  }
3563
2453
  async function registerModelCommand() {
3564
2454
  try {
3565
- const { registerModel } = await import("./model-NR3JHFSJ.js");
2455
+ const { registerModel } = await import("./model-HLHIEFMU.js");
3566
2456
  registerModel(program);
3567
2457
  } catch {
3568
2458
  }
3569
2459
  }
3570
2460
  async function registerUpdateCommand() {
3571
2461
  try {
3572
- const { registerUpdate } = await import("./update-OGPSZM5A.js");
2462
+ const { registerUpdate } = await import("./update-YCYCKJOO.js");
3573
2463
  registerUpdate(program);
3574
2464
  } catch {
3575
2465
  }