@thinkingai/ae-cli 6.0.20 → 6.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -4
- package/README.zh.md +1 -4
- package/dist/{auth-GHBMJ5ZR.js → auth-A2XXG5K4.js} +34 -110
- package/dist/auth-IDPKDFSY.js +13 -0
- package/dist/chunk-2OW2RENH.js +193 -0
- package/dist/{chunk-I5CRVM2S.js → chunk-4FQ36OGO.js} +44 -17
- package/dist/{chunk-6W4QOZAL.js → chunk-65DKFJZB.js} +26 -16
- package/dist/chunk-AKORWVHJ.js +59 -0
- package/dist/{chunk-BJX3GXWC.js → chunk-F3ZDMC2W.js} +8 -8
- package/dist/chunk-FIT4CFIN.js +59 -0
- package/dist/{chunk-5OC7CYCG.js → chunk-IDXW6MEJ.js} +14 -14
- package/dist/{chunk-DMMEPCST.js → chunk-NGJDCOYA.js} +25 -115
- package/dist/chunk-NXJP4CES.js +209 -0
- package/dist/chunk-OCQPQYHZ.js +105 -0
- package/dist/{chunk-2DUEAXV3.js → chunk-ONOA6DYB.js} +1 -1
- package/dist/{chunk-RSHMZ3LG.js → chunk-PFJFZVCK.js} +13 -134
- package/dist/chunk-V5R5UIRM.js +195 -0
- package/dist/{chunk-PN3OS34E.js → chunk-WXBCP6SD.js} +1 -1
- package/dist/cli-token-OZXHC3U2.js +14 -0
- package/dist/{client-2UJ63MVQ.js → client-7L735LVY.js} +3 -3
- package/dist/{config-NCUGK6NS.js → config-SXD2JKSL.js} +3 -3
- package/dist/index.js +312 -197
- package/dist/metadata-QWUAX625.js +411 -0
- package/dist/metadata-XWTEGEN2.js +411 -0
- package/dist/{model-SJSOZTRS.js → model-3OVX42DA.js} +2 -2
- package/dist/{raw-7NVWSVJP.js → raw-IANB4AV5.js} +4 -4
- package/dist/{sync-GRVO4K3U.js → sync-4HQ3CXSK.js} +3 -3
- package/dist/{te-agent-CYZUC4US.js → te-agent-OYNNTJDU.js} +2 -2
- package/dist/{te-analysis-HJ22TUAA.js → te-analysis-CRPFK3LX.js} +1114 -358
- package/dist/te-analysis-JX3V76OI.js +2281 -0
- package/dist/{te-audience-MYDE5WEH.js → te-audience-77FGNG5E.js} +27 -18
- package/dist/te-audience-RO2IZOUC.js +599 -0
- package/dist/{te-common-WNCZB7R7.js → te-common-4TRJPRC5.js} +5 -4
- package/dist/te-common-PUXBUPOL.js +130 -0
- package/dist/{te-community-JEEFXPB3.js → te-community-NPDZQKMY.js} +5 -4
- package/dist/te-community-XKE526DS.js +687 -0
- package/dist/te-dataops-6KWLFNV4.js +1841 -0
- package/dist/{te-dataops-ZTS7XMXM.js → te-dataops-PW74WP76.js} +5 -5
- package/dist/{te-engage-4XHCTS6I.js → te-engage-HTLMUN7G.js} +5 -4
- package/dist/te-engage-YPQIVF5H.js +1510 -0
- package/dist/{te-kb-OWM3RQRH.js → te-kb-DOGDQIU4.js} +4 -5
- package/dist/{te-meta-JVO4QJBH.js → te-meta-5ESSQ5B3.js} +26 -19
- package/dist/te-meta-Z47X4VT3.js +595 -0
- package/dist/{te-team-YY24VORI.js → te-team-SOVKZIDD.js} +5 -6
- package/package.json +3 -2
- package/skills/ae-analysis/SKILL.md +60 -27
- package/skills/ae-analysis/references/analysis_gateway_assets.md +114 -0
- package/skills/ae-analysis/references/bi_panel_copy.md +15 -0
- package/skills/ae-analysis/references/bi_panel_create.md +15 -0
- package/skills/ae-analysis/references/bi_panel_delete.md +15 -0
- package/skills/ae-analysis/references/bi_panel_get.md +18 -0
- package/skills/ae-analysis/references/bi_panel_list.md +15 -0
- package/skills/ae-analysis/references/bi_panel_page_data_export.md +15 -0
- package/skills/ae-analysis/references/bi_panel_page_data_run.md +15 -0
- package/skills/ae-analysis/references/bi_panel_share.md +15 -0
- package/skills/ae-analysis/references/bi_panel_update.md +15 -0
- package/skills/ae-analysis/references/build_attribution_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_cluster_definition.md +2 -0
- package/skills/ae-analysis/references/build_distribution_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_event_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_funnel_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_heat_map_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_interval_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_path_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_prop_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_rank_list_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_retention_analysis_qp.md +2 -0
- package/skills/ae-analysis/references/build_tag_definition.md +2 -0
- package/skills/ae-analysis/references/dashboard_abnormal_get.md +15 -0
- package/skills/ae-analysis/references/dashboard_copy.md +15 -0
- package/skills/ae-analysis/references/dashboard_create.md +15 -0
- package/skills/ae-analysis/references/dashboard_daily_report_send.md +15 -0
- package/skills/ae-analysis/references/dashboard_daily_report_update.md +15 -0
- package/skills/ae-analysis/references/dashboard_definition_export.md +15 -0
- package/skills/ae-analysis/references/dashboard_definition_import.md +15 -0
- package/skills/ae-analysis/references/dashboard_delete.md +15 -0
- package/skills/ae-analysis/references/dashboard_freeze.md +15 -0
- package/skills/ae-analysis/references/dashboard_get.md +15 -0
- package/skills/ae-analysis/references/dashboard_handover.md +15 -0
- package/skills/ae-analysis/references/dashboard_list.md +15 -0
- package/skills/ae-analysis/references/dashboard_report_data_export.md +15 -0
- package/skills/ae-analysis/references/dashboard_report_data_run.md +15 -0
- package/skills/ae-analysis/references/dashboard_share.md +15 -0
- package/skills/ae-analysis/references/dashboard_share_info.md +15 -0
- package/skills/ae-analysis/references/dashboard_task_status.md +15 -0
- package/skills/ae-analysis/references/dashboard_update.md +16 -0
- package/skills/ae-analysis/references/favorite_add.md +15 -0
- package/skills/ae-analysis/references/favorite_remove.md +15 -0
- package/skills/ae-analysis/references/folder_create.md +15 -0
- package/skills/ae-analysis/references/folder_delete.md +15 -0
- package/skills/ae-analysis/references/folder_members.md +15 -0
- package/skills/ae-analysis/references/folder_share.md +15 -0
- package/skills/ae-analysis/references/list_clusters.md +3 -1
- package/skills/ae-analysis/references/list_events.md +5 -2
- package/skills/ae-analysis/references/list_metrics.md +4 -2
- package/skills/ae-analysis/references/list_properties.md +4 -2
- package/skills/ae-analysis/references/list_tags.md +3 -1
- package/skills/ae-analysis/references/project_space_create.md +15 -0
- package/skills/ae-analysis/references/project_space_delete.md +15 -0
- package/skills/ae-analysis/references/project_space_get.md +18 -0
- package/skills/ae-analysis/references/project_space_list.md +15 -0
- package/skills/ae-analysis/references/project_space_members.md +15 -0
- package/skills/ae-analysis/references/project_space_share.md +15 -0
- package/skills/ae-analysis/references/public_link_create.md +15 -0
- package/skills/ae-analysis/references/public_link_delete.md +15 -0
- package/skills/ae-analysis/references/public_link_list.md +15 -0
- package/skills/ae-analysis/references/public_link_offline.md +15 -0
- package/skills/ae-analysis/references/public_link_update.md +15 -0
- package/skills/ae-analysis/references/query_cancel.md +15 -0
- package/skills/ae-generate-tracking-code/SKILL.md +68 -31
- package/skills/ae-generate-tracking-code/references/snippet-delivery.md +26 -1
- package/skills/ae-generate-tracking-code/references/te-api.md +47 -164
- package/skills/ae-generate-tracking-plan/SKILL.md +109 -32
- package/skills/ae-generate-tracking-plan/references/te-api.md +57 -27
- package/skills/ae-metadata/SKILL.md +90 -0
- package/skills/ae-metadata/references/metadata_data_table_csv_delete.md +15 -0
- package/skills/ae-metadata/references/metadata_data_table_csv_write.md +31 -0
- package/skills/ae-metadata/references/metadata_data_table_download.md +17 -0
- package/skills/ae-metadata/references/metadata_data_table_get.md +24 -0
- package/skills/ae-metadata/references/metadata_data_table_list.md +27 -0
- package/skills/ae-metadata/references/metadata_data_table_property_bindings_update.md +17 -0
- package/skills/ae-metadata/references/metadata_data_table_sql_delete.md +15 -0
- package/skills/ae-metadata/references/metadata_data_table_sql_write.md +32 -0
- package/skills/ae-metadata/references/metadata_event_get.md +52 -0
- package/skills/ae-metadata/references/metadata_input_file_upload.md +29 -0
- package/skills/ae-metadata/references/metadata_property_dimension_table_bind_existing.md +27 -0
- package/skills/ae-metadata/references/metadata_property_dimension_table_create_and_bind_csv.md +32 -0
- package/skills/ae-metadata/references/metadata_property_get.md +54 -0
- package/dist/auth-DYC2BGLM.js +0 -21
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getToken,
|
|
3
|
+
load,
|
|
4
|
+
loadCliToken,
|
|
5
|
+
save
|
|
6
|
+
} from "./chunk-PFJFZVCK.js";
|
|
7
|
+
import {
|
|
8
|
+
getActiveHost,
|
|
9
|
+
getFallbackCliToken,
|
|
10
|
+
listHosts,
|
|
11
|
+
logger,
|
|
12
|
+
safeJsonParse
|
|
13
|
+
} from "./chunk-65DKFJZB.js";
|
|
14
|
+
|
|
15
|
+
// src/core/cli-token.ts
|
|
16
|
+
var CLI_TOKEN_GENERATE_PATH = "/v1/ta/cli/token/generate";
|
|
17
|
+
var _cliTokenCache = /* @__PURE__ */ new Map();
|
|
18
|
+
async function generateCliToken(hostUrl) {
|
|
19
|
+
const accessToken = await getToken(hostUrl);
|
|
20
|
+
const base = hostUrl.replace(/\/+$/, "");
|
|
21
|
+
const url = `${base}${CLI_TOKEN_GENERATE_PATH}`;
|
|
22
|
+
const resp = await fetch(url, {
|
|
23
|
+
method: "GET",
|
|
24
|
+
headers: {
|
|
25
|
+
"Authorization": `bearer ${accessToken}`
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (!resp.ok) {
|
|
29
|
+
throw new Error(`CLI token generate HTTP error: ${resp.status} ${resp.statusText}`);
|
|
30
|
+
}
|
|
31
|
+
const data = safeJsonParse(await resp.text());
|
|
32
|
+
if (data.return_code !== 0) {
|
|
33
|
+
throw new Error(`CLI token generate error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
34
|
+
}
|
|
35
|
+
const cliToken = data.data?.userSecret;
|
|
36
|
+
if (!cliToken) {
|
|
37
|
+
throw new Error("CLI token generate error: empty userSecret in response");
|
|
38
|
+
}
|
|
39
|
+
return cliToken;
|
|
40
|
+
}
|
|
41
|
+
function persistCliTokenIfPossible(hostUrl, cliToken) {
|
|
42
|
+
const existing = load(hostUrl);
|
|
43
|
+
if (!existing) {
|
|
44
|
+
logger.info(`cli-token: no secure-store session for ${hostUrl}, keeping token in-process only`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
save(hostUrl, { ...existing, cliToken });
|
|
48
|
+
}
|
|
49
|
+
function clearPersistedCliToken(hostUrl) {
|
|
50
|
+
const existing = load(hostUrl);
|
|
51
|
+
if (existing?.cliToken) {
|
|
52
|
+
save(hostUrl, { ...existing, cliToken: void 0 });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function getCliToken(hostOverride) {
|
|
56
|
+
const hostUrl = hostOverride || getActiveHost();
|
|
57
|
+
const cached = _cliTokenCache.get(hostUrl);
|
|
58
|
+
if (cached) {
|
|
59
|
+
return cached;
|
|
60
|
+
}
|
|
61
|
+
const storedToken = loadCliToken(hostUrl);
|
|
62
|
+
if (storedToken) {
|
|
63
|
+
_cliTokenCache.set(hostUrl, storedToken);
|
|
64
|
+
logger.info(`Using persisted CLI token (secure-store) for ${hostUrl}`);
|
|
65
|
+
return storedToken;
|
|
66
|
+
}
|
|
67
|
+
const fallbackToken = getFallbackCliToken(hostUrl);
|
|
68
|
+
if (fallbackToken) {
|
|
69
|
+
_cliTokenCache.set(hostUrl, fallbackToken);
|
|
70
|
+
logger.info(`Using sandbox-provisioned CLI token (fallback file) for ${hostUrl}`);
|
|
71
|
+
return fallbackToken;
|
|
72
|
+
}
|
|
73
|
+
return mintCliToken(hostUrl);
|
|
74
|
+
}
|
|
75
|
+
async function mintCliToken(hostUrl) {
|
|
76
|
+
logger.info(`Generating CLI token for ${hostUrl}`);
|
|
77
|
+
const cliToken = await generateCliToken(hostUrl);
|
|
78
|
+
_cliTokenCache.set(hostUrl, cliToken);
|
|
79
|
+
persistCliTokenIfPossible(hostUrl, cliToken);
|
|
80
|
+
logger.info(`CLI token generated, cached, and persisted for ${hostUrl}`);
|
|
81
|
+
return cliToken;
|
|
82
|
+
}
|
|
83
|
+
function clearCliToken(hostUrl) {
|
|
84
|
+
if (hostUrl) {
|
|
85
|
+
_cliTokenCache.delete(hostUrl);
|
|
86
|
+
clearPersistedCliToken(hostUrl);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
_cliTokenCache.clear();
|
|
90
|
+
for (const { url } of listHosts()) {
|
|
91
|
+
clearPersistedCliToken(url);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function setCliTokenManual(token, hostUrl) {
|
|
95
|
+
_cliTokenCache.set(hostUrl, token);
|
|
96
|
+
persistCliTokenIfPossible(hostUrl, token);
|
|
97
|
+
logger.info(`CLI token set for ${hostUrl}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export {
|
|
101
|
+
getCliToken,
|
|
102
|
+
mintCliToken,
|
|
103
|
+
clearCliToken,
|
|
104
|
+
setCliTokenManual
|
|
105
|
+
};
|
|
@@ -2,13 +2,8 @@ import {
|
|
|
2
2
|
getActiveHost,
|
|
3
3
|
getConfigDir,
|
|
4
4
|
logger,
|
|
5
|
-
safeJsonParse
|
|
6
|
-
|
|
7
|
-
} from "./chunk-6W4QOZAL.js";
|
|
8
|
-
|
|
9
|
-
// src/core/auth.ts
|
|
10
|
-
import fs2 from "fs";
|
|
11
|
-
import path2 from "path";
|
|
5
|
+
safeJsonParse
|
|
6
|
+
} from "./chunk-65DKFJZB.js";
|
|
12
7
|
|
|
13
8
|
// src/core/secure-store.ts
|
|
14
9
|
import crypto from "crypto";
|
|
@@ -170,15 +165,15 @@ async function getValidAccessToken(host) {
|
|
|
170
165
|
if (payload.refreshToken) {
|
|
171
166
|
logger.info(`secure-store: access token past local expiry for ${host}, refreshing\u2026`);
|
|
172
167
|
const refreshed = await doRefresh(host, payload.refreshToken);
|
|
173
|
-
save(host, { ...refreshed,
|
|
168
|
+
save(host, { ...refreshed, cliToken: payload.cliToken });
|
|
174
169
|
logger.info(`secure-store: token refreshed for ${host}`);
|
|
175
170
|
return refreshed.accessToken;
|
|
176
171
|
}
|
|
177
172
|
logger.info(`secure-store: ${host} past static local expiry, no refresh token \u2014 returning stored token, server validates (lazy)`);
|
|
178
173
|
return payload.accessToken;
|
|
179
174
|
}
|
|
180
|
-
function
|
|
181
|
-
return load(host)?.
|
|
175
|
+
function loadCliToken(host) {
|
|
176
|
+
return load(host)?.cliToken ?? null;
|
|
182
177
|
}
|
|
183
178
|
async function doRefresh(host, refreshToken) {
|
|
184
179
|
const base = host.replace(/\/+$/, "");
|
|
@@ -236,22 +231,6 @@ var SecureStoreAuthError = class extends Error {
|
|
|
236
231
|
};
|
|
237
232
|
|
|
238
233
|
// src/core/auth.ts
|
|
239
|
-
var TOKENS_FILE = path2.join(getConfigDir(), "tokens.json");
|
|
240
|
-
var LEGACY_MCP_TOKENS_FILE = path2.join(getConfigDir(), "mcp-tokens.json");
|
|
241
|
-
var LEGACY_DIR = path2.join(process.env.HOME || "", ".te-mcp");
|
|
242
|
-
(function removeLegacyMcpTokens() {
|
|
243
|
-
try {
|
|
244
|
-
if (fs2.existsSync(LEGACY_MCP_TOKENS_FILE)) {
|
|
245
|
-
fs2.rmSync(LEGACY_MCP_TOKENS_FILE);
|
|
246
|
-
logger.info("auth: removed legacy mcp-tokens.json (plaintext MCP token file)");
|
|
247
|
-
}
|
|
248
|
-
} catch {
|
|
249
|
-
}
|
|
250
|
-
})();
|
|
251
|
-
function ensureDir() {
|
|
252
|
-
const dir = getConfigDir();
|
|
253
|
-
if (!fs2.existsSync(dir)) fs2.mkdirSync(dir, { recursive: true });
|
|
254
|
-
}
|
|
255
234
|
function resolveHost(hostOverride) {
|
|
256
235
|
if (hostOverride) return hostOverride;
|
|
257
236
|
return getActiveHost();
|
|
@@ -270,95 +249,11 @@ async function validateToken(token, hostUrl) {
|
|
|
270
249
|
return false;
|
|
271
250
|
}
|
|
272
251
|
}
|
|
273
|
-
function
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const migrated = {};
|
|
279
|
-
for (const [key, val] of Object.entries(data)) {
|
|
280
|
-
const url = key.startsWith("http") ? key : `https://${key}`;
|
|
281
|
-
migrated[url] = val;
|
|
282
|
-
}
|
|
283
|
-
ensureDir();
|
|
284
|
-
fs2.writeFileSync(TOKENS_FILE, JSON.stringify(migrated, null, 2));
|
|
285
|
-
return migrated;
|
|
286
|
-
}
|
|
287
|
-
if (fs2.existsSync(TOKENS_FILE)) {
|
|
288
|
-
const data = safeReadJsonFile(TOKENS_FILE);
|
|
289
|
-
if (data && typeof data === "object" && !Array.isArray(data) && Object.keys(data).length === 0) {
|
|
290
|
-
try {
|
|
291
|
-
fs2.unlinkSync(TOKENS_FILE);
|
|
292
|
-
} catch {
|
|
293
|
-
}
|
|
294
|
-
return {};
|
|
295
|
-
}
|
|
296
|
-
let needsMigration = false;
|
|
297
|
-
const migrated = {};
|
|
298
|
-
for (const [key, val] of Object.entries(data)) {
|
|
299
|
-
if (!key.startsWith("http")) {
|
|
300
|
-
migrated[`https://${key}`] = val;
|
|
301
|
-
needsMigration = true;
|
|
302
|
-
} else {
|
|
303
|
-
migrated[key] = val;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
if (needsMigration) {
|
|
307
|
-
fs2.writeFileSync(TOKENS_FILE, JSON.stringify(migrated, null, 2));
|
|
308
|
-
return migrated;
|
|
309
|
-
}
|
|
310
|
-
return data;
|
|
311
|
-
}
|
|
312
|
-
} catch {
|
|
313
|
-
}
|
|
314
|
-
return {};
|
|
315
|
-
}
|
|
316
|
-
function saveAllTokens(tokens) {
|
|
317
|
-
ensureDir();
|
|
318
|
-
if (Object.keys(tokens).length === 0) {
|
|
319
|
-
try {
|
|
320
|
-
fs2.unlinkSync(TOKENS_FILE);
|
|
321
|
-
} catch {
|
|
322
|
-
}
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
fs2.writeFileSync(TOKENS_FILE, JSON.stringify(tokens, null, 2));
|
|
326
|
-
try {
|
|
327
|
-
fs2.chmodSync(TOKENS_FILE, 384);
|
|
328
|
-
} catch {
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
function loadToken(hostUrl) {
|
|
332
|
-
const tokens = loadAllTokens();
|
|
333
|
-
const entry = tokens[hostUrl];
|
|
334
|
-
if (!entry || !entry.token) return null;
|
|
335
|
-
return { host: hostUrl, token: entry.token, updatedAt: entry.updatedAt };
|
|
336
|
-
}
|
|
337
|
-
function saveToken(token, hostUrl) {
|
|
338
|
-
const tokens = loadAllTokens();
|
|
339
|
-
tokens[hostUrl] = { token, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
340
|
-
saveAllTokens(tokens);
|
|
341
|
-
logger.info(`Token saved for ${hostUrl}`);
|
|
342
|
-
}
|
|
343
|
-
function clearToken(hostUrl) {
|
|
344
|
-
const tokens = loadAllTokens();
|
|
345
|
-
delete tokens[hostUrl];
|
|
346
|
-
saveAllTokens(tokens);
|
|
347
|
-
}
|
|
348
|
-
function setTokenManual(token, hostUrl) {
|
|
349
|
-
saveToken(token, hostUrl);
|
|
350
|
-
}
|
|
351
|
-
function getAuthStatus(hostUrl) {
|
|
352
|
-
if (process.env.TE_TOKEN) {
|
|
353
|
-
return { authenticated: true, host: hostUrl, source: "env:TE_TOKEN" };
|
|
354
|
-
}
|
|
355
|
-
const cached = loadToken(hostUrl);
|
|
356
|
-
if (cached) {
|
|
357
|
-
const ageMs = Date.now() - new Date(cached.updatedAt).getTime();
|
|
358
|
-
const hours = Math.round(ageMs / 36e5);
|
|
359
|
-
return { authenticated: true, host: hostUrl, tokenAge: `${hours}h ago`, source: "cache" };
|
|
360
|
-
}
|
|
361
|
-
return { authenticated: false, host: hostUrl };
|
|
252
|
+
function invalidateAccessTokenForRetry(hostUrl) {
|
|
253
|
+
const payload = load(hostUrl);
|
|
254
|
+
if (!payload) return;
|
|
255
|
+
save(hostUrl, { ...payload, accessExpiresAt: (/* @__PURE__ */ new Date(0)).toISOString() });
|
|
256
|
+
logger.info(`auth: marked access token stale for retry on ${hostUrl}`);
|
|
362
257
|
}
|
|
363
258
|
async function getToken(hostUrl) {
|
|
364
259
|
if (!hostUrl) {
|
|
@@ -367,15 +262,6 @@ async function getToken(hostUrl) {
|
|
|
367
262
|
Run: ae-cli config set-host <url>`
|
|
368
263
|
);
|
|
369
264
|
}
|
|
370
|
-
if (process.env.TE_TOKEN) {
|
|
371
|
-
logger.info("Using token from env:TE_TOKEN");
|
|
372
|
-
return process.env.TE_TOKEN;
|
|
373
|
-
}
|
|
374
|
-
const cached = loadToken(hostUrl);
|
|
375
|
-
if (cached && cached.token) {
|
|
376
|
-
logger.info(`Using cached token for ${hostUrl}`);
|
|
377
|
-
return cached.token;
|
|
378
|
-
}
|
|
379
265
|
try {
|
|
380
266
|
const secureToken = await getValidAccessToken(hostUrl);
|
|
381
267
|
logger.info(`Using secure-store token for ${hostUrl}`);
|
|
@@ -389,10 +275,7 @@ Run: ae-cli config set-host <url>`
|
|
|
389
275
|
}
|
|
390
276
|
throw new Error(
|
|
391
277
|
`Cannot obtain token for ${hostUrl}.
|
|
392
|
-
|
|
393
|
-
1. ae-cli auth login (device code flow, cross-platform)
|
|
394
|
-
2. ae-cli auth set-token <token>
|
|
395
|
-
3. export TE_TOKEN=<token> (CI/headless)`
|
|
278
|
+
Run: ae-cli auth login (device code flow, cross-platform)`
|
|
396
279
|
);
|
|
397
280
|
}
|
|
398
281
|
|
|
@@ -400,14 +283,10 @@ export {
|
|
|
400
283
|
save,
|
|
401
284
|
load,
|
|
402
285
|
clear,
|
|
403
|
-
|
|
286
|
+
loadCliToken,
|
|
404
287
|
SecureStoreAuthError,
|
|
405
288
|
resolveHost,
|
|
406
289
|
validateToken,
|
|
407
|
-
|
|
408
|
-
saveToken,
|
|
409
|
-
clearToken,
|
|
410
|
-
setTokenManual,
|
|
411
|
-
getAuthStatus,
|
|
290
|
+
invalidateAccessTokenForRetry,
|
|
412
291
|
getToken
|
|
413
292
|
};
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PermissionError
|
|
3
|
+
} from "./chunk-NOO24N7W.js";
|
|
4
|
+
import {
|
|
5
|
+
clearCliToken,
|
|
6
|
+
getCliToken
|
|
7
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
8
|
+
import {
|
|
9
|
+
logger,
|
|
10
|
+
safeJsonParse
|
|
11
|
+
} from "./chunk-65DKFJZB.js";
|
|
12
|
+
|
|
13
|
+
// src/core/capability-api.ts
|
|
14
|
+
import { readFile } from "fs/promises";
|
|
15
|
+
import { basename } from "path";
|
|
16
|
+
var CapabilityGatewayError = class extends Error {
|
|
17
|
+
constructor(message, code, httpStatus, hint) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.httpStatus = httpStatus;
|
|
21
|
+
this.hint = hint;
|
|
22
|
+
this.name = "CapabilityGatewayError";
|
|
23
|
+
}
|
|
24
|
+
code;
|
|
25
|
+
httpStatus;
|
|
26
|
+
hint;
|
|
27
|
+
};
|
|
28
|
+
function buildCapabilityGatewayUrl(host, domain, pathAfterV1, queryParams = {}) {
|
|
29
|
+
const base = host.replace(/\/+$/, "");
|
|
30
|
+
const cleanDomain = domain.replace(/^\/+|\/+$/g, "");
|
|
31
|
+
const cleanPath = pathAfterV1.replace(/^\/+|\/+$/g, "");
|
|
32
|
+
const gatewayPrefix = cleanDomain === "" ? "/api/cli/v1" : `/api/cli/${cleanDomain}/v1`;
|
|
33
|
+
const url = new URL(`${base}${gatewayPrefix}/${cleanPath}`);
|
|
34
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
35
|
+
if (value !== void 0 && value !== null) {
|
|
36
|
+
url.searchParams.set(key, String(value));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return url.toString();
|
|
40
|
+
}
|
|
41
|
+
async function permissionMessage(resp) {
|
|
42
|
+
const text = await resp.text().catch(() => "");
|
|
43
|
+
try {
|
|
44
|
+
const d = safeJsonParse(text);
|
|
45
|
+
const msg = d && (d.error?.message || (typeof d.error === "string" ? d.error : void 0) || d.message);
|
|
46
|
+
if (msg && typeof msg === "string") return msg;
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
return "Permission denied for this resource (HTTP 403)";
|
|
50
|
+
}
|
|
51
|
+
function parseCapabilityResponse(text) {
|
|
52
|
+
if (!text) return void 0;
|
|
53
|
+
try {
|
|
54
|
+
return safeJsonParse(text);
|
|
55
|
+
} catch {
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function unwrapCapabilityEnvelope(body) {
|
|
60
|
+
if (body == null) {
|
|
61
|
+
throw new CapabilityGatewayError("Empty capability gateway response");
|
|
62
|
+
}
|
|
63
|
+
if (typeof body.ok === "boolean") {
|
|
64
|
+
if (body.ok) {
|
|
65
|
+
return body.data;
|
|
66
|
+
}
|
|
67
|
+
const err = body.error ?? {};
|
|
68
|
+
const code = nonEmptyString(err.code);
|
|
69
|
+
const message = nonEmptyString(err.message) ?? code ?? "Capability gateway request failed";
|
|
70
|
+
const hint = nonEmptyString(err.hint);
|
|
71
|
+
throw new CapabilityGatewayError(message, code, err.http_status ?? err.httpStatus, hint);
|
|
72
|
+
}
|
|
73
|
+
return body;
|
|
74
|
+
}
|
|
75
|
+
function nonEmptyString(value) {
|
|
76
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
77
|
+
}
|
|
78
|
+
function buildCapabilityHttpError(resp, body) {
|
|
79
|
+
const fallback = `Capability gateway HTTP error: ${resp.status} ${resp.statusText}`.trim();
|
|
80
|
+
if (body && typeof body === "object") {
|
|
81
|
+
const err = body.error ?? body.data?.error ?? body;
|
|
82
|
+
const code = nonEmptyString(err.code) ?? nonEmptyString(err.errorCode) ?? nonEmptyString(body.code);
|
|
83
|
+
const message = nonEmptyString(err.message) ?? nonEmptyString(body.message);
|
|
84
|
+
const hint = nonEmptyString(err.hint) ?? nonEmptyString(body.hint);
|
|
85
|
+
const details = [code, message, hint ? `Hint: ${hint}` : void 0].filter(Boolean);
|
|
86
|
+
if (details.length > 0) {
|
|
87
|
+
return new CapabilityGatewayError(message ?? fallback, code, resp.status, hint);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (typeof body === "string" && body.trim()) {
|
|
91
|
+
return new CapabilityGatewayError(`${fallback}: ${body.slice(0, 500)}`, void 0, resp.status);
|
|
92
|
+
}
|
|
93
|
+
return new CapabilityGatewayError(fallback, void 0, resp.status);
|
|
94
|
+
}
|
|
95
|
+
async function throwCapabilityHttpError(resp) {
|
|
96
|
+
const body = parseCapabilityResponse(await resp.text());
|
|
97
|
+
throw buildCapabilityHttpError(resp, body);
|
|
98
|
+
}
|
|
99
|
+
async function requestOnce(url, method, token, body) {
|
|
100
|
+
const headers = {
|
|
101
|
+
"cli-token": token,
|
|
102
|
+
"Accept": "application/json",
|
|
103
|
+
"X-Source": "ae-cli"
|
|
104
|
+
};
|
|
105
|
+
const init = { method, headers };
|
|
106
|
+
if (body !== void 0 && method !== "GET") {
|
|
107
|
+
headers["Content-Type"] = "application/json";
|
|
108
|
+
init.body = JSON.stringify(body);
|
|
109
|
+
}
|
|
110
|
+
return fetch(url, init);
|
|
111
|
+
}
|
|
112
|
+
async function requestMultipartOnce(url, token, form) {
|
|
113
|
+
return fetch(url, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: {
|
|
116
|
+
"cli-token": token,
|
|
117
|
+
"Accept": "application/json",
|
|
118
|
+
"X-Source": "ae-cli"
|
|
119
|
+
},
|
|
120
|
+
body: form
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async function callGateway(host, domain, pathAfterV1, method, body) {
|
|
124
|
+
const url = buildCapabilityGatewayUrl(host, domain, pathAfterV1);
|
|
125
|
+
const token = await getCliToken(host);
|
|
126
|
+
let resp = await requestOnce(url, method, token, body);
|
|
127
|
+
if (resp.status === 403) {
|
|
128
|
+
throw new PermissionError(await permissionMessage(resp));
|
|
129
|
+
}
|
|
130
|
+
if (resp.status === 401) {
|
|
131
|
+
logger.warn(`Capability gateway request failed (HTTP 401) for ${host}, refreshing CLI token`);
|
|
132
|
+
clearCliToken(host);
|
|
133
|
+
const newToken = await getCliToken(host);
|
|
134
|
+
process.stderr.write(`[ae-cli] CLI token refreshed for ${host}
|
|
135
|
+
`);
|
|
136
|
+
resp = await requestOnce(url, method, newToken, body);
|
|
137
|
+
if (resp.status === 403) {
|
|
138
|
+
throw new PermissionError(await permissionMessage(resp));
|
|
139
|
+
}
|
|
140
|
+
if (!resp.ok) {
|
|
141
|
+
await throwCapabilityHttpError(resp);
|
|
142
|
+
}
|
|
143
|
+
} else if (!resp.ok) {
|
|
144
|
+
await throwCapabilityHttpError(resp);
|
|
145
|
+
}
|
|
146
|
+
return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
|
|
147
|
+
}
|
|
148
|
+
async function executeCapability(host, domain, capabilityId, input = {}) {
|
|
149
|
+
return callGateway(host, domain, `capabilities/${capabilityId}/execute`, "POST", { input });
|
|
150
|
+
}
|
|
151
|
+
async function uploadInputFile(host, domain, projectId, purpose, filePath) {
|
|
152
|
+
const fileBytes = await readFile(filePath);
|
|
153
|
+
return uploadInputFileBytes(host, domain, projectId, purpose, fileBytes, basename(filePath));
|
|
154
|
+
}
|
|
155
|
+
async function uploadInputFileBytes(host, domain, projectId, purpose, bytes, filename, contentType = "application/octet-stream") {
|
|
156
|
+
const url = buildCapabilityGatewayUrl(host, domain, "input-files");
|
|
157
|
+
const fileBuffer = bytes instanceof ArrayBuffer ? bytes : bytes.buffer.slice(
|
|
158
|
+
bytes.byteOffset,
|
|
159
|
+
bytes.byteOffset + bytes.byteLength
|
|
160
|
+
);
|
|
161
|
+
const form = new FormData();
|
|
162
|
+
form.append("project_id", String(projectId));
|
|
163
|
+
form.append("purpose", purpose);
|
|
164
|
+
form.append("file", new Blob([fileBuffer], { type: contentType }), filename);
|
|
165
|
+
const token = await getCliToken(host);
|
|
166
|
+
let resp = await requestMultipartOnce(url, token, form);
|
|
167
|
+
if (resp.status === 403) {
|
|
168
|
+
throw new PermissionError(await permissionMessage(resp));
|
|
169
|
+
}
|
|
170
|
+
if (resp.status === 401) {
|
|
171
|
+
logger.warn(`Capability gateway request failed (HTTP 401) for ${host}, refreshing CLI token`);
|
|
172
|
+
clearCliToken(host);
|
|
173
|
+
const newToken = await getCliToken(host);
|
|
174
|
+
process.stderr.write(`[ae-cli] CLI token refreshed for ${host}
|
|
175
|
+
`);
|
|
176
|
+
resp = await requestMultipartOnce(url, newToken, form);
|
|
177
|
+
if (resp.status === 403) {
|
|
178
|
+
throw new PermissionError(await permissionMessage(resp));
|
|
179
|
+
}
|
|
180
|
+
if (!resp.ok) {
|
|
181
|
+
await throwCapabilityHttpError(resp);
|
|
182
|
+
}
|
|
183
|
+
} else if (!resp.ok) {
|
|
184
|
+
await throwCapabilityHttpError(resp);
|
|
185
|
+
}
|
|
186
|
+
return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export {
|
|
190
|
+
CapabilityGatewayError,
|
|
191
|
+
buildCapabilityGatewayUrl,
|
|
192
|
+
executeCapability,
|
|
193
|
+
uploadInputFile,
|
|
194
|
+
uploadInputFileBytes
|
|
195
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearCliToken,
|
|
3
|
+
getCliToken,
|
|
4
|
+
mintCliToken,
|
|
5
|
+
setCliTokenManual
|
|
6
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
7
|
+
import "./chunk-PFJFZVCK.js";
|
|
8
|
+
import "./chunk-65DKFJZB.js";
|
|
9
|
+
export {
|
|
10
|
+
clearCliToken,
|
|
11
|
+
getCliToken,
|
|
12
|
+
mintCliToken,
|
|
13
|
+
setCliTokenManual
|
|
14
|
+
};
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
queryReportData,
|
|
8
8
|
querySql,
|
|
9
9
|
wsQuery
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-F3ZDMC2W.js";
|
|
11
|
+
import "./chunk-PFJFZVCK.js";
|
|
12
|
+
import "./chunk-65DKFJZB.js";
|
|
13
13
|
export {
|
|
14
14
|
httpDelete,
|
|
15
15
|
httpGet,
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
printError,
|
|
3
3
|
printOutput
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ONOA6DYB.js";
|
|
5
5
|
import {
|
|
6
6
|
GLOBAL_QUERY_CONFIG_KEY,
|
|
7
7
|
getAnalysisMappingPathForClusterMode,
|
|
8
8
|
getClusterInfoFilePath,
|
|
9
9
|
isGlobalQueryModeEnabled,
|
|
10
10
|
setGlobalQueryModeEnabled
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WXBCP6SD.js";
|
|
12
12
|
import {
|
|
13
13
|
addHost,
|
|
14
14
|
loadConfig,
|
|
15
15
|
setActiveHost
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-65DKFJZB.js";
|
|
17
17
|
|
|
18
18
|
// src/commands/config.ts
|
|
19
19
|
function registerConfig(program) {
|