@thinkingai/ae-cli 6.1.27 → 6.1.29

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 (177) hide show
  1. package/README.md +52 -6
  2. package/README.zh.md +52 -6
  3. package/bin/ae-cli.js +5 -0
  4. package/bin/runtime-capabilities.json +5 -0
  5. package/cli-installation-guide.md +24 -3
  6. package/dist/{auth-WA7YGGRT.js → auth-OBQ5KVQM.js} +175 -45
  7. package/dist/{automation-VAAQBM7Y.js → automation-NAR5DDGL.js} +94 -38
  8. package/dist/{capability-GAAYJ3IQ.js → capability-LFSVNI5B.js} +57 -28
  9. package/dist/chunk-2UW3Y463.js +2289 -0
  10. package/dist/{chunk-VZZNLV3I.js → chunk-3SDHJOCR.js} +68 -18
  11. package/dist/chunk-6HAUVWOQ.js +132 -0
  12. package/dist/{chunk-5XJYLEVC.js → chunk-72NJKS7O.js} +4 -4
  13. package/dist/{chunk-Q5US7JC5.js → chunk-7JAVT5TK.js} +3 -3
  14. package/dist/{chunk-7KU2WNQE.js → chunk-CVCTFLSO.js} +37 -15
  15. package/dist/{chunk-GHXZK54S.js → chunk-H3K5UGYC.js} +41 -13
  16. package/dist/{chunk-OP44TT4H.js → chunk-IN7KKL6K.js} +4 -2
  17. package/dist/{chunk-S6M42KND.js → chunk-JEUXDY3B.js} +1 -1
  18. package/dist/{chunk-ZL7SGNIA.js → chunk-JNVVJ273.js} +58 -46
  19. package/dist/chunk-N6XBLRB7.js +105 -0
  20. package/dist/{chunk-AP7YP2NX.js → chunk-OAWPT7VP.js} +2 -2
  21. package/dist/{chunk-AQJPNWZF.js → chunk-PWXDWMCW.js} +7 -7
  22. package/dist/{chunk-CT7QDJS6.js → chunk-QVRIDN42.js} +2 -2
  23. package/dist/chunk-QZLRHGVH.js +222 -0
  24. package/dist/{chunk-RPBOAQQQ.js → chunk-QZUVLFNR.js} +1 -1
  25. package/dist/{chunk-3YVEAZUN.js → chunk-RJHGDWSC.js} +32 -21
  26. package/dist/{chunk-MWIA43UJ.js → chunk-VCZE3IWO.js} +10 -8
  27. package/dist/chunk-YVG6QD3V.js +233 -0
  28. package/dist/{chunk-WNGFSIOB.js → chunk-Z3Q2AEIN.js} +237 -86
  29. package/dist/{community-report-client-PEERQCX2.js → community-report-client-TJVCLZ3K.js} +1 -1
  30. package/dist/compat-check-CII6B74E.js +32 -0
  31. package/dist/{config-JOD5DOPE.js → config-YZ6O2UQ2.js} +40 -7
  32. package/dist/{context-NGVFPCBK.js → context-F6FCGTF3.js} +4 -4
  33. package/dist/{data-integration-BCLQFTGU.js → data-integration-6UAZO4GG.js} +207 -24
  34. package/dist/evaluation-4LO2O4AF.js +3714 -0
  35. package/dist/index.js +352 -81
  36. package/dist/{local-data-upload-client-TWMHFLUA.js → local-data-upload-client-KCMG6J62.js} +1 -1
  37. package/dist/{memory-CQKH2JAV.js → memory-HHPX3NF2.js} +6 -6
  38. package/dist/{metadata-NR3PHR23.js → metadata-TIFY24LW.js} +17 -9
  39. package/dist/{model-VX5M2CJ6.js → model-7UHGWYVR.js} +4 -4
  40. package/dist/{personal-semantic-preference-2RAI36P3.js → personal-semantic-preference-WKJEGPTM.js} +7 -6
  41. package/dist/{project-semantic-3BUGP3ZM.js → project-semantic-EIQVZNHW.js} +11 -10
  42. package/dist/{sync-RZIAV37C.js → sync-RV3OPCTI.js} +8 -7
  43. package/dist/{te-agent-AORRE2FM.js → te-agent-5ENVZJUH.js} +757 -94
  44. package/dist/{te-analysis-GP7DSQ7Q.js → te-analysis-USIK6ZZG.js} +584 -100
  45. package/dist/{te-community-42M7ICDO.js → te-community-WE2UU4XV.js} +722 -228
  46. package/dist/{te-dataops-BNKNZ4F2.js → te-dataops-XNMO7MBF.js} +9 -6
  47. package/dist/{te-engage-2CO6LRCX.js → te-engage-6C3HCFQR.js} +13 -12
  48. package/dist/{te-experiment-652CLXMU.js → te-experiment-LVTRI3QK.js} +55 -21
  49. package/dist/{te-kb-ULATOTQ3.js → te-kb-TUPGMVBY.js} +409 -85
  50. package/dist/{te-system-UGHVKBVV.js → te-system-YM657FKO.js} +6 -6
  51. package/dist/{te-team-YA6SNOJ3.js → te-team-G4VEJJNL.js} +64 -41
  52. package/dist/{things-DTCOQIQB.js → things-22KQWC23.js} +7 -7
  53. package/dist/{update-ESNYKUVR.js → update-XX4ILU7X.js} +11 -7
  54. package/dist/{workspace-JEOHKFPX.js → workspace-LYDAP647.js} +6 -6
  55. package/package.json +26 -11
  56. package/skills/ae-agent/SKILL.md +22 -3
  57. package/skills/ae-agent/references/command_index.md +8 -0
  58. package/skills/ae-agent/references/resource-package.md +57 -0
  59. package/skills/ae-analysis/SKILL.md +23 -10
  60. package/skills/ae-analysis/references/adhoc_export.md +1 -1
  61. package/skills/ae-analysis/references/agent_review_preflight.md +55 -10
  62. package/skills/ae-analysis/references/agent_review_priorities_comparisons.md +5 -3
  63. package/skills/ae-analysis/references/agent_review_submit_to_page.md +60 -24
  64. package/skills/ae-analysis/references/ai_models/event.md +58 -2
  65. package/skills/ae-analysis/references/ai_models/rank_list.md +1 -0
  66. package/skills/ae-analysis/references/ai_models/retention.md +2 -0
  67. package/skills/ae-analysis/references/ai_models/revenue.md +2 -0
  68. package/skills/ae-analysis/references/analysis_data_export.md +11 -1
  69. package/skills/ae-analysis/references/asset_batch_info_export.md +2 -2
  70. package/skills/ae-analysis/references/asset_batch_sql_export.md +2 -2
  71. package/skills/ae-analysis/references/asset_export.md +1 -1
  72. package/skills/ae-analysis/references/bi_panel_page_data_export.md +1 -1
  73. package/skills/ae-analysis/references/check_export.md +1 -1
  74. package/skills/ae-analysis/references/command_index.md +39 -26
  75. package/skills/ae-analysis/references/dashboard_report_data_export.md +2 -0
  76. package/skills/ae-analysis/references/dashboard_report_get.md +6 -2
  77. package/skills/ae-analysis/references/dashboard_report_update.md +24 -5
  78. package/skills/ae-analysis/references/feedback_submit.md +1 -1
  79. package/skills/ae-analysis/references/governance_recommendation_export.md +40 -18
  80. package/skills/ae-analysis/references/governance_recommendation_run_update.md +13 -0
  81. package/skills/ae-analysis/references/live_data_export.md +1 -1
  82. package/skills/ae-analysis/references/metric_create.md +29 -0
  83. package/skills/ae-analysis/references/metric_get.md +2 -0
  84. package/skills/ae-analysis/references/metric_update.md +2 -0
  85. package/skills/ae-analysis/references/operation_record_export.md +1 -1
  86. package/skills/ae-analysis/references/plan_change_log_export.md +1 -1
  87. package/skills/ae-analysis/references/plan_export.md +1 -1
  88. package/skills/ae-analysis/references/project_info_get.md +4 -0
  89. package/skills/ae-analysis/references/project_member_group_add_members.md +35 -0
  90. package/skills/ae-analysis/references/project_member_group_create.md +25 -0
  91. package/skills/ae-analysis/references/project_member_group_delete.md +34 -0
  92. package/skills/ae-analysis/references/project_member_group_list.md +29 -0
  93. package/skills/ae-analysis/references/project_member_group_members.md +28 -0
  94. package/skills/ae-analysis/references/project_member_group_remove_members.md +35 -0
  95. package/skills/ae-analysis/references/project_member_group_rename.md +26 -0
  96. package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +9 -1
  97. package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +6 -1
  98. package/skills/ae-analysis/references/report_data_export.md +1 -1
  99. package/skills/ae-analysis/references/scenario_append.md +31 -0
  100. package/skills/ae-analysis/references/scenario_begin.md +11 -0
  101. package/skills/ae-analysis/references/scenario_collect.md +43 -0
  102. package/skills/ae-analysis/references/scenario_evaluation.md +18 -0
  103. package/skills/ae-analysis/references/scenario_get.md +15 -0
  104. package/skills/ae-analysis/references/scenario_list.md +64 -0
  105. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +73 -4
  106. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/company-kb.mjs +14 -1
  107. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-schema.md +5 -1
  108. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/execution-contract.mjs +173 -0
  109. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +109 -64
  110. package/skills/ae-automation/SKILL.md +2 -2
  111. package/skills/ae-automation/references/cli.md +18 -1
  112. package/skills/ae-capability/SKILL.md +7 -3
  113. package/skills/ae-community/SKILL.md +77 -27
  114. package/skills/ae-community/references/community-analyzing-theme-comment.md +10 -8
  115. package/skills/ae-community/references/community-data-quality.md +68 -0
  116. package/skills/ae-community/references/community-query-evidence.md +85 -0
  117. package/skills/ae-community/references/community-scenario-capabilities.md +137 -0
  118. package/skills/ae-community/references/community-weekly-report.md +6 -3
  119. package/skills/ae-community/references/get_channel_info.md +7 -4
  120. package/skills/ae-community/references/get_comment_tag_analysis.md +3 -3
  121. package/skills/ae-community/references/get_comments_summary.md +4 -4
  122. package/skills/ae-community/references/get_corpus_tags.md +3 -3
  123. package/skills/ae-community/references/get_daily_summary.md +3 -3
  124. package/skills/ae-community/references/get_hot_topics.md +3 -3
  125. package/skills/ae-community/references/get_livestream_analysis.md +3 -3
  126. package/skills/ae-community/references/get_livestream_detail.md +4 -4
  127. package/skills/ae-community/references/get_livestream_list.md +3 -3
  128. package/skills/ae-community/references/get_livestream_overview.md +3 -3
  129. package/skills/ae-community/references/get_livestream_room_metrics.md +3 -3
  130. package/skills/ae-community/references/get_livestream_rooms.md +3 -3
  131. package/skills/ae-community/references/get_overview_metrics.md +3 -3
  132. package/skills/ae-community/references/get_post_detail.md +4 -4
  133. package/skills/ae-community/references/get_risk_content.md +5 -5
  134. package/skills/ae-community/references/get_sentiment_overview.md +4 -4
  135. package/skills/ae-community/references/get_tag_trends.md +3 -3
  136. package/skills/ae-community/references/get_topic_detail.md +3 -3
  137. package/skills/ae-community/references/list_sources.md +28 -0
  138. package/skills/ae-community/references/list_spaces.md +39 -0
  139. package/skills/ae-community/references/search_posts.md +21 -7
  140. package/skills/ae-data-integration/SKILL.md +6 -4
  141. package/skills/ae-data-integration/references/error-handling.md +1 -0
  142. package/skills/ae-data-integration/references/handoff.md +1 -1
  143. package/skills/ae-data-integration/references/sink-upload.md +11 -0
  144. package/skills/ae-data-integration/references/source-inspect.md +2 -1
  145. package/skills/ae-data-integration/references/transform.md +1 -1
  146. package/skills/ae-data-integration/references/ue-mapping.md +1 -1
  147. package/skills/ae-evaluation/SKILL.md +83 -0
  148. package/skills/ae-evaluation/references/access-and-members.md +55 -0
  149. package/skills/ae-evaluation/references/connections.md +78 -0
  150. package/skills/ae-evaluation/references/datasets.md +57 -0
  151. package/skills/ae-evaluation/references/evaluators.md +81 -0
  152. package/skills/ae-evaluation/references/files.md +33 -0
  153. package/skills/ae-evaluation/references/integrations.md +39 -0
  154. package/skills/ae-evaluation/references/runs.md +160 -0
  155. package/skills/ae-evaluation/references/schedules.md +31 -0
  156. package/skills/ae-experiment/SKILL.md +7 -1
  157. package/skills/ae-experiment/references/manage_experiment.md +18 -1
  158. package/skills/ae-experiment/references/query_experiment_detail.md +7 -0
  159. package/skills/ae-experiment/references/save_experiment.md +76 -2
  160. package/skills/ae-experiment/references/save_submit_experiment.md +7 -0
  161. package/skills/ae-kb/SKILL.md +33 -7
  162. package/skills/ae-kb/references/publication.md +81 -0
  163. package/skills/ae-kb/references/query-workflow.md +14 -1
  164. package/skills/ae-metadata/SKILL.md +3 -2
  165. package/skills/ae-metadata/references/metadata_data_table_download.md +7 -1
  166. package/skills/ae-metadata/references/metadata_data_table_get.md +37 -0
  167. package/skills/ae-system/SKILL.md +1 -1
  168. package/skills/ae-team/SKILL.md +2 -2
  169. package/skills/ae-team/references/run-start.md +1 -0
  170. package/skills/ae-team/references/run-watch.md +7 -5
  171. package/skills/ae-things/SKILL.md +53 -51
  172. package/skills/ae-things/references/cli.md +56 -54
  173. package/skills/ae-things-progress/SKILL.md +20 -20
  174. package/skills/ae-things-review/SKILL.md +19 -19
  175. package/skills/ae-workspace/SKILL.md +1 -1
  176. package/dist/chunk-6VNIR4AP.js +0 -1422
  177. package/dist/chunk-CI24BDR2.js +0 -43
@@ -1,4 +1,8 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ import {
3
+ invalidateBusinessSkillSynchronization,
4
+ refreshEnvironmentAfterLogin
5
+ } from "./chunk-6HAUVWOQ.js";
2
6
  import {
3
7
  MultiselectCancelled,
4
8
  promptSingleSelect
@@ -9,13 +13,15 @@ import {
9
13
  } from "./chunk-6ZIQV5GW.js";
10
14
  import {
11
15
  resolveHost
12
- } from "./chunk-OP44TT4H.js";
16
+ } from "./chunk-IN7KKL6K.js";
13
17
  import {
14
- getLocalCliPackageInfo,
15
18
  printError,
16
- printOutput,
19
+ printOutput
20
+ } from "./chunk-QZLRHGVH.js";
21
+ import {
22
+ getLocalCliPackageInfo,
17
23
  runHostCompatCheck
18
- } from "./chunk-6VNIR4AP.js";
24
+ } from "./chunk-2UW3Y463.js";
19
25
  import {
20
26
  CliTokenValidationUnavailableError,
21
27
  CredentialStoreUnreadableError,
@@ -31,25 +37,54 @@ import {
31
37
  saveCredential,
32
38
  updateCredentialMetadata,
33
39
  validateCliTokenOnServer
34
- } from "./chunk-GHXZK54S.js";
40
+ } from "./chunk-H3K5UGYC.js";
35
41
  import {
36
42
  getFallbackCliToken,
37
43
  loadConfig,
38
- normalizeUrl,
39
44
  saveConfig
40
- } from "./chunk-ZL7SGNIA.js";
45
+ } from "./chunk-JNVVJ273.js";
41
46
  import {
47
+ ExternalCliTokenError,
42
48
  PermissionError,
43
- logger
44
- } from "./chunk-WNGFSIOB.js";
49
+ logger,
50
+ normalizeUrl,
51
+ readExternalCliToken
52
+ } from "./chunk-Z3Q2AEIN.js";
45
53
 
46
54
  // src/core/device-auth.ts
47
55
  import { execFileSync } from "child_process";
56
+ function deviceApiPath(protocol, action) {
57
+ return protocol === "uba" ? `/v1/ta/cli/auth/device/${action}` : `/api/auth/device/${action}`;
58
+ }
59
+ function ubaAuthorizationDenial(code) {
60
+ if (code === "CLI_ACCESS_DISABLED") return {
61
+ code,
62
+ message: "CLI access is disabled for this account.",
63
+ hint: "Contact your administrator."
64
+ };
65
+ if (code === "ACCOUNT_UNAVAILABLE") return {
66
+ code,
67
+ message: "This account is unavailable.",
68
+ hint: "Contact your administrator or sign in with an active account."
69
+ };
70
+ if (code === "ORIGIN_DENIED") return {
71
+ code,
72
+ message: "Authorization must be approved from the trusted platform page.",
73
+ hint: "Open the verification URL on the configured AE host and sign in there."
74
+ };
75
+ return {
76
+ code: "AUTHORIZATION_DENIED",
77
+ message: "Device authorization was denied.",
78
+ hint: "Check your account status with your administrator before requesting authorization again."
79
+ };
80
+ }
48
81
  var DeviceFlowUnsupportedError = class extends Error {
49
- constructor() {
82
+ constructor(httpStatus) {
50
83
  super("This AE server does not support device code login (it may be an older server version).");
84
+ this.httpStatus = httpStatus;
51
85
  this.name = "DeviceFlowUnsupportedError";
52
86
  }
87
+ httpStatus;
53
88
  };
54
89
  function looksLikeMissingEndpoint(status, contentType, body) {
55
90
  if (status === 404) return true;
@@ -83,29 +118,46 @@ function openBrowser(url, _execFile) {
83
118
  exec("xdg-open", [url], { timeout: 5e3 });
84
119
  return true;
85
120
  } catch (e) {
86
- logger.warn(`openBrowser: failed to open ${safeLogUrl}: ${e.message}`);
121
+ logger.warn(`openBrowser: failed to open ${safeLogUrl}`);
87
122
  return false;
88
123
  }
89
124
  }
90
- async function authorizeDevice(host) {
125
+ async function authorizeDevice(host, protocol = "legacy") {
91
126
  const base = host.replace(/\/+$/, "");
92
- const url = `${base}/api/auth/device/authorize`;
127
+ const url = `${base}${deviceApiPath(protocol, "authorize")}`;
93
128
  let resp;
94
129
  try {
95
130
  resp = await fetch(url, {
96
131
  method: "POST",
97
- headers: { "Content-Type": "application/json" }
132
+ headers: {
133
+ "Content-Type": "application/json",
134
+ ...protocol === "uba" ? { "X-CLI-Verification-Origin": new URL(host).origin } : {}
135
+ },
136
+ redirect: "error",
137
+ signal: AbortSignal.timeout(1e4)
98
138
  });
99
139
  } catch (e) {
100
- throw new Error(`Device authorize request failed: ${e.message}`);
140
+ throw new Error("Device authorize request failed. Check the AE host and network, then retry.");
101
141
  }
102
142
  const contentType = resp.headers.get("content-type");
103
143
  const text = await resp.text().catch(() => "");
104
144
  if (looksLikeMissingEndpoint(resp.status, contentType, text)) {
105
- throw new DeviceFlowUnsupportedError();
145
+ throw new DeviceFlowUnsupportedError(resp.status);
106
146
  }
107
147
  if (!resp.ok) {
108
- throw new Error(`Device authorize returned HTTP ${resp.status}: ${text}`);
148
+ if (resp.status === 403) {
149
+ if (protocol === "uba") {
150
+ let code;
151
+ try {
152
+ code = JSON.parse(text)?.code;
153
+ } catch {
154
+ }
155
+ const denial = ubaAuthorizationDenial(code);
156
+ throw new PermissionError(denial.message, denial.code, denial.hint);
157
+ }
158
+ throw new PermissionError("CLI authorization is not allowed.", "CLI_ACCESS_DISABLED", "Contact your administrator.");
159
+ }
160
+ throw new Error(`Device authorize returned HTTP ${resp.status}`);
109
161
  }
110
162
  let body;
111
163
  try {
@@ -113,23 +165,28 @@ async function authorizeDevice(host) {
113
165
  } catch {
114
166
  throw new Error("Device authorize returned invalid JSON");
115
167
  }
116
- if (!body.device_code || !body.user_code) {
168
+ if (typeof body.device_code !== "string" || !body.device_code || typeof body.user_code !== "string" || !body.user_code) {
117
169
  throw new Error("Device authorize response missing required fields");
118
170
  }
171
+ if (protocol === "uba" && (!Number.isInteger(body.expires_in) || body.expires_in < 1 || body.expires_in > 300 || !Number.isInteger(body.interval) || body.interval < 1 || body.interval > body.expires_in)) {
172
+ throw new Error("UBA authorization returned invalid polling limits. Check the server deployment.");
173
+ }
119
174
  return body;
120
175
  }
121
- async function pollDeviceToken(host, deviceCode) {
176
+ async function pollDeviceToken(host, deviceCode, protocol = "legacy") {
122
177
  const base = host.replace(/\/+$/, "");
123
- const url = `${base}/api/auth/device/token`;
178
+ const url = `${base}${deviceApiPath(protocol, "token")}`;
124
179
  let resp;
125
180
  try {
126
181
  resp = await fetch(url, {
127
182
  method: "POST",
128
183
  headers: { "Content-Type": "application/json" },
129
- body: JSON.stringify({ device_code: deviceCode })
184
+ body: JSON.stringify({ device_code: deviceCode }),
185
+ redirect: "error",
186
+ signal: AbortSignal.timeout(1e4)
130
187
  });
131
188
  } catch (e) {
132
- return { status: "error", message: `Network error: ${e.message}` };
189
+ return { status: "error", message: "Network error while polling authorization." };
133
190
  }
134
191
  if (resp.status === 200) {
135
192
  let body;
@@ -138,7 +195,7 @@ async function pollDeviceToken(host, deviceCode) {
138
195
  } catch {
139
196
  return { status: "error", message: "Token response is not valid JSON" };
140
197
  }
141
- if (!body.access_token) {
198
+ if (typeof body.access_token !== "string" || !body.access_token) {
142
199
  return { status: "error", message: "Token response missing access_token" };
143
200
  }
144
201
  return { status: "approved", tokens: body };
@@ -154,7 +211,13 @@ async function pollDeviceToken(host, deviceCode) {
154
211
  if (err === "authorization_pending") return { status: "pending" };
155
212
  if (err === "slow_down") return { status: "slow_down" };
156
213
  if (err === "expired_token") return { status: "expired" };
157
- return { status: "error", message: `Unknown error: ${err ?? "unknown"}` };
214
+ if (err === "access_denied") return {
215
+ status: "denied",
216
+ code: "AUTHORIZATION_DENIED",
217
+ message: "Device authorization was denied.",
218
+ hint: "Run ae-cli auth login again only when you want to request authorization."
219
+ };
220
+ return { status: "error", message: "Token endpoint returned an unrecognized authorization error." };
158
221
  }
159
222
  if (resp.status === 403) {
160
223
  let errorBody = {};
@@ -162,6 +225,7 @@ async function pollDeviceToken(host, deviceCode) {
162
225
  errorBody = await resp.json();
163
226
  } catch {
164
227
  }
228
+ if (protocol === "uba") return { status: "denied", ...ubaAuthorizationDenial(errorBody.code) };
165
229
  return {
166
230
  status: "denied",
167
231
  code: errorBody.code ?? "CLI_ACCESS_DISABLED",
@@ -176,7 +240,10 @@ async function pollDeviceToken(host, deviceCode) {
176
240
  }
177
241
  return { status: "error", message: `Unexpected HTTP ${resp.status} from token endpoint` };
178
242
  }
179
- function buildVerificationUrl(host, userCode) {
243
+ function buildVerificationUrl(host, userCode, protocol = "legacy") {
244
+ if (protocol === "uba") {
245
+ return `${host.replace(/\/+$/, "")}/#/cli/device-activate?user_code=${encodeURIComponent(userCode)}`;
246
+ }
180
247
  return `${host.replace(/\/+$/, "")}/device-activate?user_code=${encodeURIComponent(userCode)}`;
181
248
  }
182
249
  async function pollDeviceFlow(host, deviceCode, options = {}, onStatus) {
@@ -190,7 +257,7 @@ async function pollDeviceFlow(host, deviceCode, options = {}, onStatus) {
190
257
  while (Date.now() < deadline) {
191
258
  await sleep(intervalMs);
192
259
  pollCount++;
193
- const result = await pollDeviceToken(host, deviceCode);
260
+ const result = await pollDeviceToken(host, deviceCode, options.protocol);
194
261
  if (result.status === "approved") {
195
262
  emit(`Authorization successful! (polled ${pollCount} time(s))`);
196
263
  return result.tokens;
@@ -237,9 +304,9 @@ async function runDeviceFlow(host, options = {}, onStatus) {
237
304
  if (onStatus) onStatus(msg);
238
305
  };
239
306
  emit("Requesting authorization code from server...");
240
- const auth = await authorizeDevice(host);
307
+ const auth = options.authorization ?? await authorizeDevice(host, options.protocol);
241
308
  const userCode = auth.user_code;
242
- const verifyUrl = buildVerificationUrl(host, userCode);
309
+ const verifyUrl = buildVerificationUrl(host, userCode, options.protocol);
243
310
  const expiresIn = auth.expires_in ?? 300;
244
311
  emit("");
245
312
  emit(`Verification code: ${userCode}`);
@@ -255,21 +322,47 @@ async function runDeviceFlow(host, options = {}, onStatus) {
255
322
  }
256
323
  emit("");
257
324
  }
258
- return pollDeviceFlow(host, auth.device_code, { intervalMs: (auth.interval ?? 5) * 1e3, expiresIn }, onStatus);
325
+ return pollDeviceFlow(host, auth.device_code, { intervalMs: (auth.interval ?? 5) * 1e3, expiresIn, protocol: options.protocol }, onStatus);
259
326
  }
260
327
  function sleep(ms) {
261
328
  return new Promise((resolve) => setTimeout(resolve, ms));
262
329
  }
263
330
 
331
+ // src/core/login-device-flow.ts
332
+ function resolveLegacyLoginBase(host) {
333
+ const base = host.replace(/\/+$/, "");
334
+ const basePath = process.env.TE_CLAUDE_BASE_PATH || "/agent";
335
+ return base.endsWith(basePath) ? base : base + basePath;
336
+ }
337
+ function resolveDeviceSessionRoute(host, deviceCode) {
338
+ return deviceCode.startsWith("uba_") ? { baseUrl: host, protocol: "uba" } : { baseUrl: resolveLegacyLoginBase(host), protocol: "legacy" };
339
+ }
340
+ async function authorizeLoginDevice(host) {
341
+ try {
342
+ const authorization = await authorizeDevice(host, "uba");
343
+ if (!/^uba_[A-Za-z0-9_-]+$/.test(authorization.device_code)) {
344
+ throw new Error("UBA authorization returned an unsupported device-code format. Check the server deployment.");
345
+ }
346
+ return { baseUrl: host, protocol: "uba", authorization };
347
+ } catch (error) {
348
+ if (!(error instanceof DeviceFlowUnsupportedError) || error.httpStatus !== 404) throw error;
349
+ const baseUrl = resolveLegacyLoginBase(host);
350
+ return { baseUrl, protocol: "legacy", authorization: await authorizeDevice(baseUrl) };
351
+ }
352
+ }
353
+
264
354
  // src/commands/auth.ts
265
355
  var HOST_OPTION_DESC = "Override active AE host URL (e.g., https://ta.thinkingdata.cn)";
356
+ function shellArgument(value) {
357
+ return `'${value.replace(/'/g, `'\\''`)}'`;
358
+ }
266
359
  function getExplicitAuthHostOverride(program, opts) {
267
360
  return opts.host || program.opts().host;
268
361
  }
269
362
  function resolveAuthHost(program, opts) {
270
363
  return resolveHost(getExplicitAuthHostOverride(program, opts));
271
364
  }
272
- async function validateExistingCliToken(host, cliToken) {
365
+ async function validateExistingCliToken(host, cliToken, external = false) {
273
366
  try {
274
367
  return { valid: true, trusted: false, details: await validateCliTokenOnServer(host, cliToken) };
275
368
  } catch (error) {
@@ -286,7 +379,7 @@ async function validateExistingCliToken(host, cliToken) {
286
379
  printError(
287
380
  "auth",
288
381
  error.message,
289
- `Run: ae-cli auth logout --host ${host}, then ae-cli auth login --host ${host}`
382
+ external ? "Replace the external CLI token with a valid token for this host." : `Run: ae-cli auth logout --host ${host}, then ae-cli auth login --host ${host}`
290
383
  );
291
384
  process.exitCode = 1;
292
385
  return { valid: false, trusted: false, details: {} };
@@ -349,6 +442,7 @@ function promptHiddenCliToken() {
349
442
  });
350
443
  }
351
444
  function activateHostAfterLogin(host, explicitHostOverride) {
445
+ invalidateBusinessSkillSynchronization();
352
446
  if (!explicitHostOverride) return;
353
447
  const normalized = normalizeUrl(host);
354
448
  const config = loadConfig();
@@ -426,12 +520,15 @@ async function switchActiveAccount(program, opts) {
426
520
  }
427
521
  }
428
522
  try {
523
+ invalidateBusinessSkillSynchronization();
429
524
  const selected = activateCredential(host, account);
430
525
  clearCliTokenCache(host);
526
+ const environment = await refreshEnvironmentAfterLogin(host);
431
527
  await printOutput({
432
528
  host,
433
529
  active: true,
434
- account: accountOutput(selected.account)
530
+ account: accountOutput(selected.account),
531
+ ...environment ? { environment } : {}
435
532
  }, program.opts().format || "json");
436
533
  } catch (error) {
437
534
  if (error instanceof CredentialStoreUnreadableError) throw error;
@@ -455,6 +552,7 @@ async function persistDeviceTokens(host, tokens, options = {}) {
455
552
  }
456
553
  let saved;
457
554
  try {
555
+ invalidateBusinessSkillSynchronization();
458
556
  saved = saveCredential(host, {
459
557
  cliToken,
460
558
  ...validation.account ? { account: validation.account } : {},
@@ -473,6 +571,7 @@ async function persistManualCliToken(host, cliToken, options = {}) {
473
571
  const validation = await validateCliTokenOnServer(host, cliToken);
474
572
  let saved;
475
573
  try {
574
+ invalidateBusinessSkillSynchronization();
476
575
  saved = saveCredential(host, {
477
576
  cliToken,
478
577
  ...validation.account ? { account: validation.account } : {},
@@ -506,12 +605,16 @@ function manualTokenSummary(host, credential) {
506
605
  };
507
606
  }
508
607
  function resolveLoginTeClaudeBase(host) {
509
- const base = host.replace(/\/+$/, "");
510
- const basePath = process.env.TE_CLAUDE_BASE_PATH || "/agent";
511
- return base.endsWith(basePath) ? base : base + basePath;
608
+ return resolveLegacyLoginBase(host);
512
609
  }
513
610
  function registerAuth(program) {
514
611
  const auth = program.command("auth").description("Manage authentication or switch the active account interactively").hook("preAction", (_command, actionCommand) => {
612
+ if (["auth", "login", "set-token", "use", "logout"].includes(actionCommand.name()) && readExternalCliToken()) {
613
+ throw new ExternalCliTokenError(
614
+ "Stored-account changes are unavailable while an external CLI token is selected.",
615
+ "EXTERNAL_CLI_TOKEN_ACTIVE"
616
+ );
617
+ }
515
618
  if (["login", "set-token"].includes(actionCommand.name())) {
516
619
  const host = resolveAuthHost(program, actionCommand.opts());
517
620
  if (host) assertCredentialsReadable(host);
@@ -536,36 +639,43 @@ function registerAuth(program) {
536
639
  }
537
640
  const noBrowser = !opts.browser;
538
641
  const format = program.opts().format || "json";
539
- const teClaudeBase = resolveLoginTeClaudeBase(host);
540
642
  const emit = (message) => process.stderr.write(`[ae-cli] ${message}
541
643
  `);
542
644
  try {
543
645
  if (opts.deviceCode) {
544
- const tokens2 = await pollDeviceFlow(teClaudeBase, opts.deviceCode, {}, emit);
646
+ const route = resolveDeviceSessionRoute(host, opts.deviceCode);
647
+ const tokens2 = await pollDeviceFlow(route.baseUrl, opts.deviceCode, { protocol: route.protocol }, emit);
545
648
  const saved2 = await persistDeviceTokens(host, tokens2, { add: opts.add });
546
649
  activateHostAfterLogin(host, explicitHost);
650
+ const environment2 = await refreshEnvironmentAfterLogin(host);
547
651
  emit("Login successful! CLI token saved securely.");
548
- await printOutput(loginSummary(host, saved2), format);
652
+ await printOutput({ ...loginSummary(host, saved2), ...environment2 ? { environment: environment2 } : {} }, format);
549
653
  return;
550
654
  }
655
+ const session = await authorizeLoginDevice(host);
656
+ const authResp = session.authorization;
551
657
  if (opts.wait === false) {
552
- const authResp = await authorizeDevice(teClaudeBase);
553
658
  const addFlag = opts.add ? " --add" : "";
554
659
  await printOutput({
555
660
  device_code: authResp.device_code,
556
661
  user_code: authResp.user_code,
557
- verification_url: buildVerificationUrl(teClaudeBase, authResp.user_code),
662
+ verification_url: buildVerificationUrl(session.baseUrl, authResp.user_code, session.protocol),
558
663
  interval: authResp.interval,
559
664
  expires_in: authResp.expires_in,
560
- next: `Open verification_url in a browser to authorize, then run: ae-cli auth login${addFlag} --device-code ${authResp.device_code}`
665
+ next: `Open verification_url in a browser to authorize, then run: ae-cli auth login${addFlag} --host ${shellArgument(host)} --device-code ${shellArgument(authResp.device_code)}`
561
666
  }, format);
562
667
  return;
563
668
  }
564
- const tokens = await runDeviceFlow(teClaudeBase, { noBrowser }, emit);
669
+ const tokens = await runDeviceFlow(session.baseUrl, {
670
+ noBrowser,
671
+ protocol: session.protocol,
672
+ authorization: authResp
673
+ }, emit);
565
674
  const saved = await persistDeviceTokens(host, tokens, { add: opts.add });
566
675
  activateHostAfterLogin(host, explicitHost);
676
+ const environment = await refreshEnvironmentAfterLogin(host);
567
677
  emit("Login successful! CLI token saved securely.");
568
- await printOutput(loginSummary(host, saved), format);
678
+ await printOutput({ ...loginSummary(host, saved), ...environment ? { environment } : {} }, format);
569
679
  } catch (error) {
570
680
  if (error instanceof CredentialStoreUnreadableError) throw error;
571
681
  if (error instanceof DeviceFlowUnsupportedError) {
@@ -608,9 +718,10 @@ function registerAuth(program) {
608
718
  try {
609
719
  const saved = await persistManualCliToken(host, cliToken, { add: opts.add });
610
720
  activateHostAfterLogin(host, explicitHost);
721
+ const environment = await refreshEnvironmentAfterLogin(host);
611
722
  process.stderr.write(`[ae-cli] CLI token verified and saved securely for ${host}
612
723
  `);
613
- await printOutput(manualTokenSummary(host, saved), program.opts().format || "json");
724
+ await printOutput({ ...manualTokenSummary(host, saved), ...environment ? { environment } : {} }, program.opts().format || "json");
614
725
  } catch (error) {
615
726
  if (error instanceof CredentialStoreUnreadableError) throw error;
616
727
  if (error instanceof PermissionError) {
@@ -644,6 +755,22 @@ function registerAuth(program) {
644
755
  }, program.opts().format || "json");
645
756
  return;
646
757
  }
758
+ const external = readExternalCliToken(host);
759
+ if (external) {
760
+ const state = await validateExistingCliToken(host, external.token, true);
761
+ if (!state.valid) return;
762
+ await printOutput({
763
+ authenticated: true,
764
+ host,
765
+ source: external.source,
766
+ cli_token: {
767
+ status: state.trusted ? "trusted" : "valid",
768
+ ...state.details.cliTokenExpiresAt ? { expires_at: state.details.cliTokenExpiresAt } : {}
769
+ },
770
+ ...state.details.account ? { account: accountOutput(state.details.account) } : {}
771
+ }, program.opts().format || "json");
772
+ return;
773
+ }
647
774
  const active = getActiveCredential(host);
648
775
  if (active) {
649
776
  const state = await validateExistingCliToken(host, active.cliToken);
@@ -706,18 +833,21 @@ function registerAuth(program) {
706
833
  process.exit(1);
707
834
  }
708
835
  clearCliTokenCache(host);
836
+ invalidateBusinessSkillSynchronization();
709
837
  if (opts.all) {
710
838
  clearAllCredentials(host);
711
839
  await printOutput({ cleared: true, all: true, host }, program.opts().format || "json");
712
840
  return;
713
841
  }
714
842
  const result = removeActiveCredential(host);
843
+ const environment = result.active ? await refreshEnvironmentAfterLogin(host) : void 0;
715
844
  await printOutput({
716
845
  cleared: !!result.removed,
717
846
  all: false,
718
847
  host,
719
848
  remaining_accounts: listCredentials(host).length,
720
- ...result.active?.account ? { active_account: accountOutput(result.active.account) } : {}
849
+ ...result.active?.account ? { active_account: accountOutput(result.active.account) } : {},
850
+ ...environment ? { environment } : {}
721
851
  }, program.opts().format || "json");
722
852
  });
723
853
  }