@thinkingai/ae-cli 6.0.22 → 6.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{auth-RDN6D5HU.js → auth-7TQRGLBC.js} +13 -15
- package/dist/auth-MEJ642P4.js +13 -0
- package/dist/chunk-2NDGFQHW.js +190 -0
- package/dist/{chunk-5FBLRSMU.js → chunk-7QQ4233A.js} +3 -3
- package/dist/{chunk-U6QPKCN3.js → chunk-AJTH7LT3.js} +10 -116
- package/dist/chunk-BXMXMUD7.js +254 -0
- package/dist/chunk-C4DH76LX.js +59 -0
- package/dist/chunk-GWZ5MYWE.js +209 -0
- package/dist/{chunk-E34XH4GW.js → chunk-KCA6BA5D.js} +8 -8
- package/dist/{chunk-XE2PI5DS.js → chunk-KGJQCYVC.js} +1 -1
- package/dist/chunk-LG5YT7P7.js +59 -0
- package/dist/{chunk-2W7HULUD.js → chunk-MDJGDI6K.js} +2 -2
- package/dist/{chunk-H52CSLJW.js → chunk-R77JT7XD.js} +53 -6
- package/dist/{chunk-WPXHCP4A.js → chunk-YCLVYFK7.js} +52 -9
- package/dist/{chunk-4EUZRJPO.js → chunk-YNQFYBDB.js} +102 -14
- package/dist/{chunk-YACCPUNQ.js → chunk-ZAOL36CG.js} +1 -1
- package/dist/cli-token-TVQRSE46.js +18 -0
- package/dist/{client-VTJMUZ4O.js → client-2643Z5AG.js} +3 -3
- package/dist/{config-2SDTLGOC.js → config-ZVPARN4R.js} +4 -9
- package/dist/index.js +27 -24
- package/dist/{metadata-JZ2OTWBK.js → metadata-IPSPQBX3.js} +56 -65
- package/dist/metadata-N5REJ7R7.js +411 -0
- package/dist/{model-ZYMRN4VS.js → model-T3KZJWLW.js} +2 -2
- package/dist/{raw-NGYHAL3F.js → raw-OHSUK42D.js} +4 -4
- package/dist/{sync-JVLX6TGW.js → sync-ULT5SECP.js} +3 -3
- package/dist/{te-agent-QPZTLHPH.js → te-agent-QLIVKRUN.js} +1146 -61
- package/dist/{te-analysis-WWX3Z6RP.js → te-analysis-2U5EPXQC.js} +1213 -341
- package/dist/te-analysis-QMZ2UH7F.js +2419 -0
- package/dist/{te-audience-UXGHUVBB.js → te-audience-PVMKQAFH.js} +5 -5
- package/dist/te-audience-XMRMVD2V.js +599 -0
- package/dist/{te-common-7XXH73MF.js → te-common-CFGQXTFV.js} +5 -5
- package/dist/te-common-SDB3O2QG.js +130 -0
- package/dist/{te-community-QKE67HR2.js → te-community-6A7LKYUH.js} +5 -5
- package/dist/te-community-GMWFGILT.js +687 -0
- package/dist/te-dataops-6LIPYNGH.js +1864 -0
- package/dist/{te-dataops-6W7NNYST.js → te-dataops-Z53CTG2U.js} +90 -68
- package/dist/{te-engage-NCFAQFX3.js → te-engage-AGREUOW7.js} +30 -15
- package/dist/te-engage-MIIUKY6M.js +1525 -0
- package/dist/{te-kb-K5BQYUCM.js → te-kb-KQJ53M3A.js} +4 -4
- package/dist/{te-meta-LJZBOSMO.js → te-meta-QLANJ4B4.js} +5 -5
- package/dist/te-meta-TOA6FWDE.js +595 -0
- package/dist/{te-team-DHK5R7MV.js → te-team-TQGMNHQQ.js} +5 -5
- package/package.json +3 -1
- package/skills/ae-agent/SKILL.md +158 -189
- package/skills/ae-agent/references/accept-skill-share.md +39 -0
- package/skills/ae-agent/references/add-attachment.md +57 -0
- package/skills/ae-agent/references/add-mcp.md +75 -0
- package/skills/ae-agent/references/add-model.md +70 -0
- package/skills/ae-agent/references/add-skill.md +71 -0
- package/skills/ae-agent/references/approve-skill.md +41 -0
- package/skills/ae-agent/references/attachment-stats.md +50 -0
- package/skills/ae-agent/references/auto-provision-mcp-credentials.md +57 -0
- package/skills/ae-agent/references/cancel-skill-submission.md +39 -0
- package/skills/ae-agent/references/copy-skill.md +53 -0
- package/skills/ae-agent/references/create-agent.md +71 -0
- package/skills/ae-agent/references/create-automation.md +99 -0
- package/skills/ae-agent/references/del-agent.md +38 -0
- package/skills/ae-agent/references/del-attachment.md +35 -0
- package/skills/ae-agent/references/del-mcp.md +35 -0
- package/skills/ae-agent/references/del-model.md +37 -0
- package/skills/ae-agent/references/del-skill-asset.md +41 -0
- package/skills/ae-agent/references/del-skill-reference.md +41 -0
- package/skills/ae-agent/references/del-skill-script.md +41 -0
- package/skills/ae-agent/references/del-skill.md +36 -0
- package/skills/ae-agent/references/edit-skill.md +64 -0
- package/skills/ae-agent/references/get-agent.md +37 -0
- package/skills/ae-agent/references/get-skill-content.md +36 -0
- package/skills/ae-agent/references/list-agents.md +40 -0
- package/skills/ae-agent/references/list-attachments.md +42 -0
- package/skills/ae-agent/references/list-automations.md +41 -0
- package/skills/ae-agent/references/list-mcp-credentials.md +65 -0
- package/skills/ae-agent/references/list-mcp-market.md +58 -0
- package/skills/ae-agent/references/list-mcps.md +37 -0
- package/skills/ae-agent/references/list-models.md +38 -0
- package/skills/ae-agent/references/list-skill-assets.md +35 -0
- package/skills/ae-agent/references/list-skill-market.md +59 -0
- package/skills/ae-agent/references/list-skill-references.md +36 -0
- package/skills/ae-agent/references/list-skill-scripts.md +35 -0
- package/skills/ae-agent/references/list-skill-shares.md +49 -0
- package/skills/ae-agent/references/list-skill-submissions.md +45 -0
- package/skills/ae-agent/references/list-skills.md +37 -0
- package/skills/ae-agent/references/mcp-auth-disconnect.md +50 -0
- package/skills/ae-agent/references/mcp-auth-start.md +61 -0
- package/skills/ae-agent/references/mcp-auth-status.md +56 -0
- package/skills/ae-agent/references/mcp-stats.md +68 -0
- package/skills/ae-agent/references/mcp-token.md +63 -0
- package/skills/ae-agent/references/mcp-tools.md +55 -0
- package/skills/ae-agent/references/read-skill-asset.md +51 -0
- package/skills/ae-agent/references/read-skill-reference.md +50 -0
- package/skills/ae-agent/references/read-skill-script.md +51 -0
- package/skills/ae-agent/references/reject-skill-share.md +37 -0
- package/skills/ae-agent/references/reject-skill.md +42 -0
- package/skills/ae-agent/references/rescan-skills.md +44 -0
- package/skills/ae-agent/references/set-mcp-credential.md +67 -0
- package/skills/ae-agent/references/set-mcp-meta.md +52 -0
- package/skills/ae-agent/references/set-skill-meta.md +51 -0
- package/skills/ae-agent/references/share-skill.md +50 -0
- package/skills/ae-agent/references/submit-skill.md +51 -0
- package/skills/ae-agent/references/test-model.md +61 -0
- package/skills/ae-agent/references/toggle-mcp.md +39 -0
- package/skills/ae-agent/references/toggle-model.md +37 -0
- package/skills/ae-agent/references/toggle-skill.md +37 -0
- package/skills/ae-agent/references/update-agent.md +71 -0
- package/skills/ae-agent/references/update-automation.md +83 -0
- package/skills/ae-agent/references/update-mcp.md +79 -0
- package/skills/ae-agent/references/update-model.md +77 -0
- package/skills/ae-agent/references/upload-skill-asset.md +49 -0
- package/skills/ae-agent/references/upload-skill-reference.md +51 -0
- package/skills/ae-agent/references/upload-skill-script.md +49 -0
- package/skills/ae-agent/references/upload-skill.md +89 -0
- package/skills/ae-analysis/SKILL.md +53 -25
- package/skills/ae-analysis/references/analysis_gateway_assets.md +129 -0
- package/skills/ae-analysis/references/artifact_download.md +17 -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 +25 -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/dashboard_abnormal_get.md +15 -0
- package/skills/ae-analysis/references/dashboard_copy.md +17 -0
- package/skills/ae-analysis/references/dashboard_create.md +15 -0
- package/skills/ae-analysis/references/dashboard_daily_report_send.md +17 -0
- package/skills/ae-analysis/references/dashboard_daily_report_update.md +17 -0
- package/skills/ae-analysis/references/dashboard_definition_export.md +33 -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 +25 -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/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-analysis/references/run_inspect.md +22 -0
- package/skills/ae-dataops/references/dataops-flow-create.md +2 -2
- package/skills/ae-dataops/references/dataops-flow-monitor.md +3 -3
- package/skills/ae-dataops/references/dataops-integration.md +1 -0
- package/skills/ae-engage/references/flow-node-config-schema.md +32 -8
- package/skills/ae-engage/references/save-flow.md +65 -29
- package/skills/ae-engage/references/validate-flow-node-config.md +28 -10
- package/skills/ae-generate-tracking-plan/SKILL.md +9 -7
- package/skills/ae-metadata/references/metadata_data_table_csv_write.md +5 -3
- package/skills/ae-metadata/references/metadata_data_table_sql_write.md +5 -4
- package/skills/ae-metadata/references/metadata_property_dimension_table_create_and_bind_csv.md +5 -3
- package/dist/auth-I2G7OAU2.js +0 -19
- package/dist/chunk-FPE5LGVU.js +0 -105
- package/dist/cli-token-6AGEDJF4.js +0 -14
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getActiveHost,
|
|
3
3
|
getSandboxRuntimeRoot
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YCLVYFK7.js";
|
|
5
5
|
|
|
6
6
|
// src/core/te-agent-credentials.ts
|
|
7
7
|
import { readFileSync } from "fs";
|
|
@@ -138,7 +138,7 @@ async function signRequest(method, path, rawBody) {
|
|
|
138
138
|
"X-Sandbox-Id": sandboxCred.sandboxId,
|
|
139
139
|
"X-Sandbox-Secret-Key": sandboxCred.sandboxSecretKey
|
|
140
140
|
};
|
|
141
|
-
if (method === "POST" || method === "PATCH") {
|
|
141
|
+
if (method === "POST" || method === "PATCH" || method === "PUT") {
|
|
142
142
|
headers["Content-Type"] = "application/json";
|
|
143
143
|
}
|
|
144
144
|
return {
|
|
@@ -147,8 +147,8 @@ async function signRequest(method, path, rawBody) {
|
|
|
147
147
|
rawBody
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
|
-
const { getToken } = await import("./auth-
|
|
151
|
-
const { getCliToken } = await import("./cli-token-
|
|
150
|
+
const { getToken } = await import("./auth-MEJ642P4.js");
|
|
151
|
+
const { getCliToken } = await import("./cli-token-TVQRSE46.js");
|
|
152
152
|
const baseUrl = sandboxCred?.url || teClaudeBaseFromActiveHost();
|
|
153
153
|
const hostForToken = getActiveHost() || baseUrl;
|
|
154
154
|
if (!baseUrl) {
|
|
@@ -157,7 +157,7 @@ async function signRequest(method, path, rawBody) {
|
|
|
157
157
|
"Run ae-cli config set-host <url> to configure the service URL, or execute inside a te-agent sandbox"
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
-
const contentTypeHeader = method === "POST" || method === "PATCH" ? { "Content-Type": "application/json" } : {};
|
|
160
|
+
const contentTypeHeader = method === "POST" || method === "PATCH" || method === "PUT" ? { "Content-Type": "application/json" } : {};
|
|
161
161
|
let accessToken = null;
|
|
162
162
|
try {
|
|
163
163
|
accessToken = await getToken(hostForToken);
|
|
@@ -282,6 +282,51 @@ async function patchToMainApp(path, body) {
|
|
|
282
282
|
});
|
|
283
283
|
return parseResponse(response, "Main app returned");
|
|
284
284
|
}
|
|
285
|
+
async function putToMainApp(path, body) {
|
|
286
|
+
const rawBody = JSON.stringify(body);
|
|
287
|
+
const signed = await signRequest("PUT", path, rawBody);
|
|
288
|
+
const response = await fetchWithTimeout(signed.url, {
|
|
289
|
+
method: "PUT",
|
|
290
|
+
headers: signed.headers,
|
|
291
|
+
body: signed.rawBody
|
|
292
|
+
});
|
|
293
|
+
return parseResponse(response, "Main app returned");
|
|
294
|
+
}
|
|
295
|
+
async function getBufferFromMainApp(path) {
|
|
296
|
+
const signed = await signRequest("GET", path, "");
|
|
297
|
+
const response = await fetchWithTimeout(signed.url, {
|
|
298
|
+
method: "GET",
|
|
299
|
+
headers: signed.headers
|
|
300
|
+
});
|
|
301
|
+
if (!response.ok) {
|
|
302
|
+
const text = await response.text();
|
|
303
|
+
let parsed = void 0;
|
|
304
|
+
if (text) {
|
|
305
|
+
try {
|
|
306
|
+
parsed = JSON.parse(text);
|
|
307
|
+
} catch {
|
|
308
|
+
parsed = text;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (response.status === 401) {
|
|
312
|
+
throw new TeAgentApiError(
|
|
313
|
+
"Session expired or unauthorized. Please run: ae-cli auth login",
|
|
314
|
+
response.status,
|
|
315
|
+
"auth_expired",
|
|
316
|
+
parsed
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const message = typeof parsed === "object" && parsed && typeof parsed.error === "string" ? parsed.error : `Main app returned ${response.status}`;
|
|
320
|
+
const code = typeof parsed === "object" && parsed && typeof parsed.code === "string" ? parsed.code : void 0;
|
|
321
|
+
throw new TeAgentApiError(message, response.status, code, parsed);
|
|
322
|
+
}
|
|
323
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
324
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
325
|
+
const cd = response.headers.get("Content-Disposition") || "";
|
|
326
|
+
const match = cd.match(/filename\*=UTF-8''([^;]+)/);
|
|
327
|
+
const fileName = match ? decodeURIComponent(match[1]) : null;
|
|
328
|
+
return { buffer, fileName };
|
|
329
|
+
}
|
|
285
330
|
async function uploadToMainApp(path, formData) {
|
|
286
331
|
const sandboxCred = tryLoadTeAgentSandboxCredentials();
|
|
287
332
|
let baseUrl;
|
|
@@ -293,7 +338,7 @@ async function uploadToMainApp(path, formData) {
|
|
|
293
338
|
"X-Sandbox-Secret-Key": sandboxCred.sandboxSecretKey
|
|
294
339
|
};
|
|
295
340
|
} else {
|
|
296
|
-
const { getToken } = await import("./auth-
|
|
341
|
+
const { getToken } = await import("./auth-MEJ642P4.js");
|
|
297
342
|
baseUrl = (sandboxCred?.url || teClaudeBaseFromActiveHost() || "").replace(/\/$/, "");
|
|
298
343
|
if (!baseUrl) {
|
|
299
344
|
throw new TeAgentCredentialsError(
|
|
@@ -328,5 +373,7 @@ export {
|
|
|
328
373
|
postSandboxSyncPull,
|
|
329
374
|
deleteFromMainApp,
|
|
330
375
|
patchToMainApp,
|
|
376
|
+
putToMainApp,
|
|
377
|
+
getBufferFromMainApp,
|
|
331
378
|
uploadToMainApp
|
|
332
379
|
};
|
|
@@ -66,9 +66,14 @@ var Logger = class {
|
|
|
66
66
|
}
|
|
67
67
|
this.info(parts.join(" | "));
|
|
68
68
|
}
|
|
69
|
-
/** Log command execution */
|
|
69
|
+
/** Log command execution (sensitive flags redacted to ***) */
|
|
70
70
|
command(name, args) {
|
|
71
|
-
const
|
|
71
|
+
const SENSITIVE = ["token", "apikey", "secret", "accesstoken", "headers"];
|
|
72
|
+
const isSensitive = (k) => {
|
|
73
|
+
const lk = k.toLowerCase();
|
|
74
|
+
return SENSITIVE.some((s) => lk.includes(s));
|
|
75
|
+
};
|
|
76
|
+
const filtered = Object.entries(args).filter(([, v]) => v !== void 0 && v !== null && v !== "").map(([k, v]) => `--${k}=${isSensitive(k) ? "***" : JSON.stringify(v)}`).join(" ");
|
|
72
77
|
this.info(`CMD ${name}${filtered ? " " + filtered : ""}`);
|
|
73
78
|
}
|
|
74
79
|
};
|
|
@@ -88,6 +93,15 @@ function safeReadJsonFile(filePath) {
|
|
|
88
93
|
return safeJsonParse(content);
|
|
89
94
|
}
|
|
90
95
|
|
|
96
|
+
// src/core/url-utils.ts
|
|
97
|
+
function normalizeUrl(url) {
|
|
98
|
+
if (!url) return url;
|
|
99
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
100
|
+
url = `https://${url}`;
|
|
101
|
+
}
|
|
102
|
+
return url.replace(/\/$/, "");
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
// src/core/config.ts
|
|
92
106
|
import fs3 from "fs";
|
|
93
107
|
import path2 from "path";
|
|
@@ -143,9 +157,6 @@ function readSandboxCliTokenEntry() {
|
|
|
143
157
|
}
|
|
144
158
|
return null;
|
|
145
159
|
}
|
|
146
|
-
function ensureDir() {
|
|
147
|
-
if (!fs3.existsSync(CONFIG_DIR)) fs3.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
148
|
-
}
|
|
149
160
|
function forceMigrateFromFallback() {
|
|
150
161
|
const entry = readSandboxCliTokenEntry();
|
|
151
162
|
if (!entry) return null;
|
|
@@ -159,16 +170,44 @@ function getFallbackCliToken(hostUrl) {
|
|
|
159
170
|
if (entries.length === 1) return entries[0];
|
|
160
171
|
return null;
|
|
161
172
|
}
|
|
173
|
+
function ensureDir() {
|
|
174
|
+
if (!fs3.existsSync(CONFIG_DIR)) fs3.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
175
|
+
}
|
|
176
|
+
function dedupeNormalizedHosts(config) {
|
|
177
|
+
const hosts = {};
|
|
178
|
+
for (const [url, entry] of Object.entries(config.hosts)) {
|
|
179
|
+
const key = normalizeUrl(url);
|
|
180
|
+
if (!hosts[key]) {
|
|
181
|
+
hosts[key] = entry;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
activeHost: config.activeHost ? normalizeUrl(config.activeHost) : "",
|
|
186
|
+
hosts
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function configNeedsNormalization(config) {
|
|
190
|
+
if (config.activeHost && normalizeUrl(config.activeHost) !== config.activeHost) return true;
|
|
191
|
+
const keys = Object.keys(config.hosts);
|
|
192
|
+
if (keys.some((url) => normalizeUrl(url) !== url)) return true;
|
|
193
|
+
return new Set(keys.map(normalizeUrl)).size !== keys.length;
|
|
194
|
+
}
|
|
162
195
|
function loadConfig() {
|
|
163
196
|
try {
|
|
164
197
|
if (fs3.existsSync(CONFIG_FILE)) {
|
|
165
198
|
const raw = safeReadJsonFile(CONFIG_FILE);
|
|
166
199
|
if (raw.defaultHost && !raw.activeHost) {
|
|
167
|
-
const migrated = migrateConfig(raw);
|
|
200
|
+
const migrated = dedupeNormalizedHosts(migrateConfig(raw));
|
|
168
201
|
saveConfig(migrated);
|
|
169
202
|
return migrated;
|
|
170
203
|
}
|
|
171
|
-
|
|
204
|
+
const rawConfig = raw;
|
|
205
|
+
if (configNeedsNormalization(rawConfig)) {
|
|
206
|
+
const config = dedupeNormalizedHosts(rawConfig);
|
|
207
|
+
saveConfig(config);
|
|
208
|
+
return config;
|
|
209
|
+
}
|
|
210
|
+
return rawConfig;
|
|
172
211
|
}
|
|
173
212
|
} catch (err) {
|
|
174
213
|
logger.error(`Error loading config: ${err.message}`);
|
|
@@ -181,11 +220,11 @@ function migrateConfig(old) {
|
|
|
181
220
|
const oldHost = old.defaultHost;
|
|
182
221
|
if (old.hosts) {
|
|
183
222
|
for (const [key, val] of Object.entries(old.hosts)) {
|
|
184
|
-
const url = key.startsWith("http") ? key : `https://${key}
|
|
223
|
+
const url = normalizeUrl(key.startsWith("http") ? key : `https://${key}`);
|
|
185
224
|
hosts[url] = val;
|
|
186
225
|
}
|
|
187
226
|
}
|
|
188
|
-
const activeHost = oldHost.startsWith("http") ? oldHost : `https://${oldHost}
|
|
227
|
+
const activeHost = normalizeUrl(oldHost.startsWith("http") ? oldHost : `https://${oldHost}`);
|
|
189
228
|
if (!hosts[activeHost]) {
|
|
190
229
|
hosts[activeHost] = { label: "default" };
|
|
191
230
|
}
|
|
@@ -203,6 +242,7 @@ function getActiveHost() {
|
|
|
203
242
|
return config.activeHost || "";
|
|
204
243
|
}
|
|
205
244
|
function setActiveHost(url) {
|
|
245
|
+
url = normalizeUrl(url);
|
|
206
246
|
const config = loadConfig();
|
|
207
247
|
if (!config.hosts[url]) {
|
|
208
248
|
throw new Error(`Host ${url} is not in the configured hosts list. Add it first.`);
|
|
@@ -211,6 +251,7 @@ function setActiveHost(url) {
|
|
|
211
251
|
saveConfig(config);
|
|
212
252
|
}
|
|
213
253
|
function addHost(url, label) {
|
|
254
|
+
url = normalizeUrl(url);
|
|
214
255
|
const config = loadConfig();
|
|
215
256
|
assertUniqueHostLabel(config, label, url);
|
|
216
257
|
config.hosts[url] = { label };
|
|
@@ -226,6 +267,7 @@ function assertUniqueHostLabel(config, label, excludeUrl) {
|
|
|
226
267
|
}
|
|
227
268
|
}
|
|
228
269
|
function removeHost(url) {
|
|
270
|
+
url = normalizeUrl(url);
|
|
229
271
|
const config = loadConfig();
|
|
230
272
|
delete config.hosts[url];
|
|
231
273
|
if (config.activeHost === url) {
|
|
@@ -250,6 +292,7 @@ export {
|
|
|
250
292
|
logger,
|
|
251
293
|
safeJsonParse,
|
|
252
294
|
safeReadJsonFile,
|
|
295
|
+
normalizeUrl,
|
|
253
296
|
getSandboxRuntimeRoot,
|
|
254
297
|
getSandboxClusterInfoFilePath,
|
|
255
298
|
getFallbackCliToken,
|
|
@@ -4,30 +4,33 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
clearCliToken,
|
|
6
6
|
getCliToken
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2NDGFQHW.js";
|
|
8
8
|
import {
|
|
9
9
|
logger,
|
|
10
10
|
safeJsonParse
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YCLVYFK7.js";
|
|
12
12
|
|
|
13
13
|
// src/core/capability-api.ts
|
|
14
14
|
import { readFile } from "fs/promises";
|
|
15
15
|
import { basename } from "path";
|
|
16
16
|
var CapabilityGatewayError = class extends Error {
|
|
17
|
-
constructor(message, code, httpStatus) {
|
|
17
|
+
constructor(message, code, httpStatus, hint) {
|
|
18
18
|
super(message);
|
|
19
19
|
this.code = code;
|
|
20
20
|
this.httpStatus = httpStatus;
|
|
21
|
+
this.hint = hint;
|
|
21
22
|
this.name = "CapabilityGatewayError";
|
|
22
23
|
}
|
|
23
24
|
code;
|
|
24
25
|
httpStatus;
|
|
26
|
+
hint;
|
|
25
27
|
};
|
|
26
28
|
function buildCapabilityGatewayUrl(host, domain, pathAfterV1, queryParams = {}) {
|
|
27
29
|
const base = host.replace(/\/+$/, "");
|
|
28
30
|
const cleanDomain = domain.replace(/^\/+|\/+$/g, "");
|
|
29
31
|
const cleanPath = pathAfterV1.replace(/^\/+|\/+$/g, "");
|
|
30
|
-
const
|
|
32
|
+
const gatewayPrefix = cleanDomain === "" ? "/api/cli/v1" : `/api/cli/${cleanDomain}/v1`;
|
|
33
|
+
const url = new URL(`${base}${gatewayPrefix}/${cleanPath}`);
|
|
31
34
|
for (const [key, value] of Object.entries(queryParams)) {
|
|
32
35
|
if (value !== void 0 && value !== null) {
|
|
33
36
|
url.searchParams.set(key, String(value));
|
|
@@ -45,6 +48,9 @@ async function permissionMessage(resp) {
|
|
|
45
48
|
}
|
|
46
49
|
return "Permission denied for this resource (HTTP 403)";
|
|
47
50
|
}
|
|
51
|
+
function isInvalidCliTokenMessage(message) {
|
|
52
|
+
return /\byour token is invalid\b/i.test(message) || /\bcli[-_\s]?token\b.*\binvalid\b/i.test(message) || /\binvalid\b.*\bcli[-_\s]?token\b/i.test(message);
|
|
53
|
+
}
|
|
48
54
|
function parseCapabilityResponse(text) {
|
|
49
55
|
if (!text) return void 0;
|
|
50
56
|
try {
|
|
@@ -62,11 +68,37 @@ function unwrapCapabilityEnvelope(body) {
|
|
|
62
68
|
return body.data;
|
|
63
69
|
}
|
|
64
70
|
const err = body.error ?? {};
|
|
65
|
-
const
|
|
66
|
-
|
|
71
|
+
const code = nonEmptyString(err.code);
|
|
72
|
+
const message = nonEmptyString(err.message) ?? code ?? "Capability gateway request failed";
|
|
73
|
+
const hint = nonEmptyString(err.hint);
|
|
74
|
+
throw new CapabilityGatewayError(message, code, err.http_status ?? err.httpStatus, hint);
|
|
67
75
|
}
|
|
68
76
|
return body;
|
|
69
77
|
}
|
|
78
|
+
function nonEmptyString(value) {
|
|
79
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
80
|
+
}
|
|
81
|
+
function buildCapabilityHttpError(resp, body) {
|
|
82
|
+
const fallback = `Capability gateway HTTP error: ${resp.status} ${resp.statusText}`.trim();
|
|
83
|
+
if (body && typeof body === "object") {
|
|
84
|
+
const err = body.error ?? body.data?.error ?? body;
|
|
85
|
+
const code = nonEmptyString(err.code) ?? nonEmptyString(err.errorCode) ?? nonEmptyString(body.code);
|
|
86
|
+
const message = nonEmptyString(err.message) ?? nonEmptyString(body.message);
|
|
87
|
+
const hint = nonEmptyString(err.hint) ?? nonEmptyString(body.hint);
|
|
88
|
+
const details = [code, message, hint ? `Hint: ${hint}` : void 0].filter(Boolean);
|
|
89
|
+
if (details.length > 0) {
|
|
90
|
+
return new CapabilityGatewayError(message ?? fallback, code, resp.status, hint);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (typeof body === "string" && body.trim()) {
|
|
94
|
+
return new CapabilityGatewayError(`${fallback}: ${body.slice(0, 500)}`, void 0, resp.status);
|
|
95
|
+
}
|
|
96
|
+
return new CapabilityGatewayError(fallback, void 0, resp.status);
|
|
97
|
+
}
|
|
98
|
+
async function throwCapabilityHttpError(resp) {
|
|
99
|
+
const body = parseCapabilityResponse(await resp.text());
|
|
100
|
+
throw buildCapabilityHttpError(resp, body);
|
|
101
|
+
}
|
|
70
102
|
async function requestOnce(url, method, token, body) {
|
|
71
103
|
const headers = {
|
|
72
104
|
"cli-token": token,
|
|
@@ -89,15 +121,28 @@ async function requestMultipartOnce(url, token, form) {
|
|
|
89
121
|
body: form
|
|
90
122
|
});
|
|
91
123
|
}
|
|
124
|
+
async function requestDownloadOnce(url, token) {
|
|
125
|
+
return fetch(url, {
|
|
126
|
+
method: "GET",
|
|
127
|
+
headers: {
|
|
128
|
+
"cli-token": token,
|
|
129
|
+
"Accept": "*/*"
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
92
133
|
async function callGateway(host, domain, pathAfterV1, method, body) {
|
|
93
134
|
const url = buildCapabilityGatewayUrl(host, domain, pathAfterV1);
|
|
94
135
|
const token = await getCliToken(host);
|
|
95
136
|
let resp = await requestOnce(url, method, token, body);
|
|
137
|
+
let permissionMsg;
|
|
96
138
|
if (resp.status === 403) {
|
|
97
|
-
|
|
139
|
+
permissionMsg = await permissionMessage(resp);
|
|
140
|
+
if (!isInvalidCliTokenMessage(permissionMsg)) {
|
|
141
|
+
throw new PermissionError(permissionMsg);
|
|
142
|
+
}
|
|
98
143
|
}
|
|
99
|
-
if (resp.status === 401) {
|
|
100
|
-
logger.warn(`Capability gateway request failed (HTTP 401) for ${host}, refreshing CLI token`);
|
|
144
|
+
if (resp.status === 401 || resp.status === 403 && permissionMsg) {
|
|
145
|
+
logger.warn(`Capability gateway request failed (${resp.status === 403 ? permissionMsg : "HTTP 401"}) for ${host}, refreshing CLI token`);
|
|
101
146
|
clearCliToken(host);
|
|
102
147
|
const newToken = await getCliToken(host);
|
|
103
148
|
process.stderr.write(`[ae-cli] CLI token refreshed for ${host}
|
|
@@ -107,10 +152,10 @@ async function callGateway(host, domain, pathAfterV1, method, body) {
|
|
|
107
152
|
throw new PermissionError(await permissionMessage(resp));
|
|
108
153
|
}
|
|
109
154
|
if (!resp.ok) {
|
|
110
|
-
|
|
155
|
+
await throwCapabilityHttpError(resp);
|
|
111
156
|
}
|
|
112
157
|
} else if (!resp.ok) {
|
|
113
|
-
|
|
158
|
+
await throwCapabilityHttpError(resp);
|
|
114
159
|
}
|
|
115
160
|
return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
|
|
116
161
|
}
|
|
@@ -147,17 +192,60 @@ async function uploadInputFileBytes(host, domain, projectId, purpose, bytes, fil
|
|
|
147
192
|
throw new PermissionError(await permissionMessage(resp));
|
|
148
193
|
}
|
|
149
194
|
if (!resp.ok) {
|
|
150
|
-
|
|
195
|
+
await throwCapabilityHttpError(resp);
|
|
151
196
|
}
|
|
152
197
|
} else if (!resp.ok) {
|
|
153
|
-
|
|
198
|
+
await throwCapabilityHttpError(resp);
|
|
154
199
|
}
|
|
155
200
|
return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
|
|
156
201
|
}
|
|
202
|
+
async function downloadCapabilityArtifact(host, domain, runId, artifactId) {
|
|
203
|
+
const url = buildCapabilityGatewayUrl(
|
|
204
|
+
host,
|
|
205
|
+
domain,
|
|
206
|
+
`runs/${encodeURIComponent(runId)}/artifacts/${encodeURIComponent(artifactId)}/download`
|
|
207
|
+
);
|
|
208
|
+
const token = await getCliToken(host);
|
|
209
|
+
let resp = await requestDownloadOnce(url, token);
|
|
210
|
+
if (resp.status === 403) {
|
|
211
|
+
throw new PermissionError(await permissionMessage(resp));
|
|
212
|
+
}
|
|
213
|
+
if (resp.status === 401) {
|
|
214
|
+
logger.warn(`Capability gateway artifact download failed (HTTP 401) for ${host}, refreshing CLI token`);
|
|
215
|
+
clearCliToken(host);
|
|
216
|
+
const newToken = await getCliToken(host);
|
|
217
|
+
process.stderr.write(`[ae-cli] CLI token refreshed for ${host}
|
|
218
|
+
`);
|
|
219
|
+
resp = await requestDownloadOnce(url, newToken);
|
|
220
|
+
if (resp.status === 403) {
|
|
221
|
+
throw new PermissionError(await permissionMessage(resp));
|
|
222
|
+
}
|
|
223
|
+
if (!resp.ok) {
|
|
224
|
+
await throwCapabilityHttpError(resp);
|
|
225
|
+
}
|
|
226
|
+
} else if (!resp.ok) {
|
|
227
|
+
await throwCapabilityHttpError(resp);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
bytes: Buffer.from(await resp.arrayBuffer()),
|
|
231
|
+
contentType: resp.headers.get("content-type") ?? void 0,
|
|
232
|
+
contentDisposition: resp.headers.get("content-disposition") ?? void 0
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
async function callCapabilityApi(host, domain, action, method = "POST", params = {}) {
|
|
236
|
+
const isGet = method === "GET";
|
|
237
|
+
if (isGet) {
|
|
238
|
+
return callGateway(host, domain, action.replace(/^\/+|\/+$/g, ""), "GET");
|
|
239
|
+
}
|
|
240
|
+
return callGateway(host, domain, action.replace(/^\/+|\/+$/g, ""), method, params);
|
|
241
|
+
}
|
|
157
242
|
|
|
158
243
|
export {
|
|
244
|
+
CapabilityGatewayError,
|
|
159
245
|
buildCapabilityGatewayUrl,
|
|
160
246
|
executeCapability,
|
|
161
247
|
uploadInputFile,
|
|
162
|
-
uploadInputFileBytes
|
|
248
|
+
uploadInputFileBytes,
|
|
249
|
+
downloadCapabilityArtifact,
|
|
250
|
+
callCapabilityApi
|
|
163
251
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
_resetRenewMemoryForTest,
|
|
3
|
+
clearCliToken,
|
|
4
|
+
getCliToken,
|
|
5
|
+
localRenewDate,
|
|
6
|
+
mintCliToken,
|
|
7
|
+
setCliTokenManual
|
|
8
|
+
} from "./chunk-2NDGFQHW.js";
|
|
9
|
+
import "./chunk-AJTH7LT3.js";
|
|
10
|
+
import "./chunk-YCLVYFK7.js";
|
|
11
|
+
export {
|
|
12
|
+
_resetRenewMemoryForTest,
|
|
13
|
+
clearCliToken,
|
|
14
|
+
getCliToken,
|
|
15
|
+
localRenewDate,
|
|
16
|
+
mintCliToken,
|
|
17
|
+
setCliTokenManual
|
|
18
|
+
};
|
|
@@ -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-KCA6BA5D.js";
|
|
11
|
+
import "./chunk-AJTH7LT3.js";
|
|
12
|
+
import "./chunk-YCLVYFK7.js";
|
|
13
13
|
export {
|
|
14
14
|
httpDelete,
|
|
15
15
|
httpGet,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
printError,
|
|
3
3
|
printOutput
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZAOL36CG.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-KGJQCYVC.js";
|
|
12
12
|
import {
|
|
13
13
|
addHost,
|
|
14
14
|
loadConfig,
|
|
15
|
+
normalizeUrl,
|
|
15
16
|
setActiveHost
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-YCLVYFK7.js";
|
|
17
18
|
|
|
18
19
|
// src/commands/config.ts
|
|
19
20
|
function registerConfig(program) {
|
|
@@ -119,12 +120,6 @@ function failConfig(message, hint) {
|
|
|
119
120
|
printError("config", message, hint);
|
|
120
121
|
process.exitCode = 1;
|
|
121
122
|
}
|
|
122
|
-
function normalizeUrl(url) {
|
|
123
|
-
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
124
|
-
url = `https://${url}`;
|
|
125
|
-
}
|
|
126
|
-
return url.replace(/\/$/, "");
|
|
127
|
-
}
|
|
128
123
|
export {
|
|
129
124
|
registerConfig
|
|
130
125
|
};
|