@thinkingai/ae-cli 6.0.22 → 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/dist/{auth-RDN6D5HU.js → auth-A2XXG5K4.js} +7 -11
- package/dist/auth-IDPKDFSY.js +13 -0
- package/dist/{chunk-4EUZRJPO.js → chunk-2OW2RENH.js} +40 -10
- package/dist/{chunk-H52CSLJW.js → chunk-4FQ36OGO.js} +4 -4
- package/dist/chunk-AKORWVHJ.js +59 -0
- package/dist/{chunk-E34XH4GW.js → chunk-F3ZDMC2W.js} +8 -8
- package/dist/chunk-FIT4CFIN.js +59 -0
- package/dist/{chunk-2W7HULUD.js → chunk-IDXW6MEJ.js} +2 -2
- package/dist/{chunk-5FBLRSMU.js → chunk-NGJDCOYA.js} +3 -3
- package/dist/chunk-NXJP4CES.js +209 -0
- package/dist/{chunk-FPE5LGVU.js → chunk-OCQPQYHZ.js} +2 -2
- package/dist/{chunk-YACCPUNQ.js → chunk-ONOA6DYB.js} +1 -1
- package/dist/{chunk-U6QPKCN3.js → chunk-PFJFZVCK.js} +8 -115
- package/dist/chunk-V5R5UIRM.js +195 -0
- package/dist/{chunk-XE2PI5DS.js → chunk-WXBCP6SD.js} +1 -1
- package/dist/{cli-token-6AGEDJF4.js → cli-token-OZXHC3U2.js} +3 -3
- package/dist/{client-VTJMUZ4O.js → client-7L735LVY.js} +3 -3
- package/dist/{config-2SDTLGOC.js → config-SXD2JKSL.js} +3 -3
- package/dist/index.js +27 -24
- package/dist/{metadata-JZ2OTWBK.js → metadata-QWUAX625.js} +56 -65
- package/dist/metadata-XWTEGEN2.js +411 -0
- package/dist/{model-ZYMRN4VS.js → model-3OVX42DA.js} +2 -2
- package/dist/{raw-NGYHAL3F.js → raw-IANB4AV5.js} +4 -4
- package/dist/{sync-JVLX6TGW.js → sync-4HQ3CXSK.js} +3 -3
- package/dist/{te-agent-QPZTLHPH.js → te-agent-OYNNTJDU.js} +2 -2
- package/dist/{te-analysis-WWX3Z6RP.js → te-analysis-CRPFK3LX.js} +1074 -340
- package/dist/te-analysis-JX3V76OI.js +2281 -0
- package/dist/{te-audience-UXGHUVBB.js → te-audience-77FGNG5E.js} +5 -5
- package/dist/te-audience-RO2IZOUC.js +599 -0
- package/dist/{te-common-7XXH73MF.js → te-common-4TRJPRC5.js} +5 -5
- package/dist/te-common-PUXBUPOL.js +130 -0
- package/dist/{te-community-QKE67HR2.js → te-community-NPDZQKMY.js} +5 -5
- package/dist/te-community-XKE526DS.js +687 -0
- package/dist/{te-dataops-6W7NNYST.js → te-dataops-6KWLFNV4.js} +5 -5
- package/dist/te-dataops-PW74WP76.js +1842 -0
- package/dist/{te-engage-NCFAQFX3.js → te-engage-HTLMUN7G.js} +5 -5
- package/dist/te-engage-YPQIVF5H.js +1510 -0
- package/dist/{te-kb-K5BQYUCM.js → te-kb-DOGDQIU4.js} +4 -4
- package/dist/{te-meta-LJZBOSMO.js → te-meta-5ESSQ5B3.js} +5 -5
- package/dist/te-meta-Z47X4VT3.js +595 -0
- package/dist/{te-team-DHK5R7MV.js → te-team-SOVKZIDD.js} +5 -5
- package/package.json +1 -1
- package/skills/ae-analysis/SKILL.md +51 -25
- 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/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/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-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-WPXHCP4A.js → chunk-65DKFJZB.js} +3 -3
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
printError,
|
|
3
3
|
printOutput
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ONOA6DYB.js";
|
|
5
5
|
import {
|
|
6
6
|
clearCliToken,
|
|
7
7
|
mintCliToken
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
9
9
|
import {
|
|
10
10
|
clear,
|
|
11
|
-
clearToken,
|
|
12
|
-
getAuthStatus,
|
|
13
11
|
load,
|
|
14
12
|
resolveHost,
|
|
15
13
|
save
|
|
16
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-PFJFZVCK.js";
|
|
17
15
|
import {
|
|
18
16
|
getFallbackCliToken,
|
|
19
17
|
loadConfig,
|
|
20
18
|
logger,
|
|
21
19
|
removeHost,
|
|
22
20
|
saveConfig
|
|
23
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-65DKFJZB.js";
|
|
24
22
|
|
|
25
23
|
// src/core/device-auth.ts
|
|
26
24
|
import { execFileSync } from "child_process";
|
|
@@ -369,15 +367,14 @@ function registerAuth(program) {
|
|
|
369
367
|
authenticated: true,
|
|
370
368
|
host,
|
|
371
369
|
source: "sandbox-cli-token",
|
|
372
|
-
hasCliToken: true
|
|
370
|
+
hasCliToken: true,
|
|
371
|
+
note: "sandbox-provisioned cli-token.json; no user access token in secure-store"
|
|
373
372
|
},
|
|
374
373
|
program.opts().format || "json"
|
|
375
374
|
);
|
|
376
375
|
return;
|
|
377
376
|
}
|
|
378
|
-
|
|
379
|
-
const authenticated = tokenStatus.authenticated;
|
|
380
|
-
printOutput({ authenticated, host, source: tokenStatus.source ?? "none" }, program.opts().format || "json");
|
|
377
|
+
printOutput({ authenticated: false, host, source: "none" }, program.opts().format || "json");
|
|
381
378
|
});
|
|
382
379
|
auth.command("logout").description("Clear stored credentials (access token, CLI token, and host config) for a host (--host or active host)").option("--host <url>", HOST_OPTION_DESC).action((opts) => {
|
|
383
380
|
const host = resolveAuthHost(program, opts);
|
|
@@ -386,7 +383,6 @@ function registerAuth(program) {
|
|
|
386
383
|
process.exit(1);
|
|
387
384
|
}
|
|
388
385
|
clearCliToken(host);
|
|
389
|
-
clearToken(host);
|
|
390
386
|
clear(host);
|
|
391
387
|
removeHost(host);
|
|
392
388
|
process.stderr.write(`[ae-cli] Credentials and config cleared for ${host}
|
|
@@ -4,30 +4,33 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
clearCliToken,
|
|
6
6
|
getCliToken
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
8
8
|
import {
|
|
9
9
|
logger,
|
|
10
10
|
safeJsonParse
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-65DKFJZB.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));
|
|
@@ -62,11 +65,37 @@ function unwrapCapabilityEnvelope(body) {
|
|
|
62
65
|
return body.data;
|
|
63
66
|
}
|
|
64
67
|
const err = body.error ?? {};
|
|
65
|
-
const
|
|
66
|
-
|
|
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);
|
|
67
72
|
}
|
|
68
73
|
return body;
|
|
69
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
|
+
}
|
|
70
99
|
async function requestOnce(url, method, token, body) {
|
|
71
100
|
const headers = {
|
|
72
101
|
"cli-token": token,
|
|
@@ -107,10 +136,10 @@ async function callGateway(host, domain, pathAfterV1, method, body) {
|
|
|
107
136
|
throw new PermissionError(await permissionMessage(resp));
|
|
108
137
|
}
|
|
109
138
|
if (!resp.ok) {
|
|
110
|
-
|
|
139
|
+
await throwCapabilityHttpError(resp);
|
|
111
140
|
}
|
|
112
141
|
} else if (!resp.ok) {
|
|
113
|
-
|
|
142
|
+
await throwCapabilityHttpError(resp);
|
|
114
143
|
}
|
|
115
144
|
return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
|
|
116
145
|
}
|
|
@@ -147,15 +176,16 @@ async function uploadInputFileBytes(host, domain, projectId, purpose, bytes, fil
|
|
|
147
176
|
throw new PermissionError(await permissionMessage(resp));
|
|
148
177
|
}
|
|
149
178
|
if (!resp.ok) {
|
|
150
|
-
|
|
179
|
+
await throwCapabilityHttpError(resp);
|
|
151
180
|
}
|
|
152
181
|
} else if (!resp.ok) {
|
|
153
|
-
|
|
182
|
+
await throwCapabilityHttpError(resp);
|
|
154
183
|
}
|
|
155
184
|
return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
|
|
156
185
|
}
|
|
157
186
|
|
|
158
187
|
export {
|
|
188
|
+
CapabilityGatewayError,
|
|
159
189
|
buildCapabilityGatewayUrl,
|
|
160
190
|
executeCapability,
|
|
161
191
|
uploadInputFile,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getActiveHost,
|
|
3
3
|
getSandboxRuntimeRoot
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-65DKFJZB.js";
|
|
5
5
|
|
|
6
6
|
// src/core/te-agent-credentials.ts
|
|
7
7
|
import { readFileSync } from "fs";
|
|
@@ -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-IDPKDFSY.js");
|
|
151
|
+
const { getCliToken } = await import("./cli-token-OZXHC3U2.js");
|
|
152
152
|
const baseUrl = sandboxCred?.url || teClaudeBaseFromActiveHost();
|
|
153
153
|
const hostForToken = getActiveHost() || baseUrl;
|
|
154
154
|
if (!baseUrl) {
|
|
@@ -293,7 +293,7 @@ async function uploadToMainApp(path, formData) {
|
|
|
293
293
|
"X-Sandbox-Secret-Key": sandboxCred.sandboxSecretKey
|
|
294
294
|
};
|
|
295
295
|
} else {
|
|
296
|
-
const { getToken } = await import("./auth-
|
|
296
|
+
const { getToken } = await import("./auth-IDPKDFSY.js");
|
|
297
297
|
baseUrl = (sandboxCred?.url || teClaudeBaseFromActiveHost() || "").replace(/\/$/, "");
|
|
298
298
|
if (!baseUrl) {
|
|
299
299
|
throw new TeAgentCredentialsError(
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildCapabilityGatewayUrl,
|
|
3
|
+
executeCapability
|
|
4
|
+
} from "./chunk-V5R5UIRM.js";
|
|
5
|
+
|
|
6
|
+
// src/core/capability-routing.ts
|
|
7
|
+
var cliServiceRoutes = /* @__PURE__ */ new Map();
|
|
8
|
+
function registerCapabilityGatewayRoute(cliService, route) {
|
|
9
|
+
cliServiceRoutes.set(cliService, route);
|
|
10
|
+
}
|
|
11
|
+
function resolveGatewayDomain(cliService, override) {
|
|
12
|
+
if (override !== void 0) {
|
|
13
|
+
return override;
|
|
14
|
+
}
|
|
15
|
+
const route = cliServiceRoutes.get(cliService);
|
|
16
|
+
if (!route) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return route.gatewayDomain;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/core/capability-command.ts
|
|
25
|
+
function createCapabilityCommand(config) {
|
|
26
|
+
return {
|
|
27
|
+
service: config.cliService,
|
|
28
|
+
resource: config.resource,
|
|
29
|
+
command: config.command,
|
|
30
|
+
description: config.description,
|
|
31
|
+
flags: config.flags,
|
|
32
|
+
risk: config.risk,
|
|
33
|
+
validate: config.validate,
|
|
34
|
+
dryRun: (ctx) => {
|
|
35
|
+
const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
|
|
36
|
+
const input = config.buildInput(ctx);
|
|
37
|
+
return {
|
|
38
|
+
method: "POST",
|
|
39
|
+
url: buildCapabilityGatewayUrl(
|
|
40
|
+
ctx.host(),
|
|
41
|
+
gatewayDomain,
|
|
42
|
+
`capabilities/${config.capabilityId}/dry-run`
|
|
43
|
+
),
|
|
44
|
+
body: { input }
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
execute: async (ctx) => {
|
|
48
|
+
const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
|
|
49
|
+
const input = config.buildInput(ctx);
|
|
50
|
+
return executeCapability(ctx.host(), gatewayDomain, config.capabilityId, input);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
registerCapabilityGatewayRoute,
|
|
57
|
+
resolveGatewayDomain,
|
|
58
|
+
createCapabilityCommand
|
|
59
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SecureStoreAuthError,
|
|
3
|
-
clearToken,
|
|
4
3
|
getToken,
|
|
4
|
+
invalidateAccessTokenForRetry,
|
|
5
5
|
resolveHost
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PFJFZVCK.js";
|
|
7
7
|
import {
|
|
8
8
|
logger,
|
|
9
9
|
safeJsonParse
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-65DKFJZB.js";
|
|
11
11
|
|
|
12
12
|
// src/core/client.ts
|
|
13
13
|
import WebSocket from "ws";
|
|
@@ -46,7 +46,7 @@ async function request(method, modulePath, params = {}, body = null, retry = tru
|
|
|
46
46
|
logger.api(method, url, resp.status, body, data);
|
|
47
47
|
if (resp.status === 401) {
|
|
48
48
|
if (retry) {
|
|
49
|
-
|
|
49
|
+
invalidateAccessTokenForRetry(resolvedHost);
|
|
50
50
|
return request(method, modulePath, params, body, false, resolvedHost);
|
|
51
51
|
}
|
|
52
52
|
throw new SecureStoreAuthError(`Session expired or unauthorized for ${resolvedHost}. Please run: ae-cli auth login`);
|
|
@@ -56,7 +56,7 @@ async function request(method, modulePath, params = {}, body = null, retry = tru
|
|
|
56
56
|
throw new Error(m);
|
|
57
57
|
}
|
|
58
58
|
if (data.return_code === -1001 && retry) {
|
|
59
|
-
|
|
59
|
+
invalidateAccessTokenForRetry(resolvedHost);
|
|
60
60
|
return request(method, modulePath, params, body, false, resolvedHost);
|
|
61
61
|
}
|
|
62
62
|
if (data.return_code !== 0 && data.return_code !== void 0) {
|
|
@@ -89,7 +89,7 @@ async function uploadRequest(modulePath, form, params = {}, retry = true, hostUr
|
|
|
89
89
|
logger.api("POST", url, resp.status, { upload: true }, data);
|
|
90
90
|
if (resp.status === 401) {
|
|
91
91
|
if (retry) {
|
|
92
|
-
|
|
92
|
+
invalidateAccessTokenForRetry(resolvedHost);
|
|
93
93
|
return uploadRequest(modulePath, form, params, false, resolvedHost);
|
|
94
94
|
}
|
|
95
95
|
throw new SecureStoreAuthError(`Session expired or unauthorized for ${resolvedHost}. Please run: ae-cli auth login`);
|
|
@@ -99,7 +99,7 @@ async function uploadRequest(modulePath, form, params = {}, retry = true, hostUr
|
|
|
99
99
|
throw new Error(m);
|
|
100
100
|
}
|
|
101
101
|
if (data.return_code === -1001 && retry) {
|
|
102
|
-
|
|
102
|
+
invalidateAccessTokenForRetry(resolvedHost);
|
|
103
103
|
return uploadRequest(modulePath, form, params, false, resolvedHost);
|
|
104
104
|
}
|
|
105
105
|
if (data.return_code !== 0 && data.return_code !== void 0) {
|
|
@@ -162,7 +162,7 @@ async function wsQuery(projectId, requestId, qp, eventModel, options = {}, hostU
|
|
|
162
162
|
} catch (err) {
|
|
163
163
|
const msg = err.message || "";
|
|
164
164
|
if (msg.includes("401") || msg.includes("403") || msg.includes("auth")) {
|
|
165
|
-
|
|
165
|
+
invalidateAccessTokenForRetry(resolvedHost);
|
|
166
166
|
const newToken = await getToken(resolvedHost);
|
|
167
167
|
return wsQueryOnce(projectId, requestId, qp, eventModel, options, newToken, resolvedHost);
|
|
168
168
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildCapabilityGatewayUrl,
|
|
3
|
+
executeCapability
|
|
4
|
+
} from "./chunk-2OW2RENH.js";
|
|
5
|
+
|
|
6
|
+
// src/core/capability-routing.ts
|
|
7
|
+
var cliServiceRoutes = /* @__PURE__ */ new Map();
|
|
8
|
+
function registerCapabilityGatewayRoute(cliService, route) {
|
|
9
|
+
cliServiceRoutes.set(cliService, route);
|
|
10
|
+
}
|
|
11
|
+
function resolveGatewayDomain(cliService, override) {
|
|
12
|
+
if (override !== void 0) {
|
|
13
|
+
return override;
|
|
14
|
+
}
|
|
15
|
+
const route = cliServiceRoutes.get(cliService);
|
|
16
|
+
if (!route) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return route.gatewayDomain;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/core/capability-command.ts
|
|
25
|
+
function createCapabilityCommand(config) {
|
|
26
|
+
return {
|
|
27
|
+
service: config.cliService,
|
|
28
|
+
resource: config.resource,
|
|
29
|
+
command: config.command,
|
|
30
|
+
description: config.description,
|
|
31
|
+
flags: config.flags,
|
|
32
|
+
risk: config.risk,
|
|
33
|
+
validate: config.validate,
|
|
34
|
+
dryRun: (ctx) => {
|
|
35
|
+
const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
|
|
36
|
+
const input = config.buildInput(ctx);
|
|
37
|
+
return {
|
|
38
|
+
method: "POST",
|
|
39
|
+
url: buildCapabilityGatewayUrl(
|
|
40
|
+
ctx.host(),
|
|
41
|
+
gatewayDomain,
|
|
42
|
+
`capabilities/${config.capabilityId}/dry-run`
|
|
43
|
+
),
|
|
44
|
+
body: { input }
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
execute: async (ctx) => {
|
|
48
|
+
const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
|
|
49
|
+
const input = config.buildInput(ctx);
|
|
50
|
+
return executeCapability(ctx.host(), gatewayDomain, config.capabilityId, input);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
registerCapabilityGatewayRoute,
|
|
57
|
+
resolveGatewayDomain,
|
|
58
|
+
createCapabilityCommand
|
|
59
|
+
};
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-NOO24N7W.js";
|
|
4
4
|
import {
|
|
5
5
|
getCliToken
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
7
7
|
import {
|
|
8
8
|
safeJsonParse
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-65DKFJZB.js";
|
|
10
10
|
|
|
11
11
|
// src/core/mcp-access.ts
|
|
12
12
|
function buildUrl(host, path, params = {}) {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getAnalysisMappingPathForClusterMode
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WXBCP6SD.js";
|
|
4
4
|
import {
|
|
5
5
|
PermissionError
|
|
6
6
|
} from "./chunk-NOO24N7W.js";
|
|
7
7
|
import {
|
|
8
8
|
clearCliToken,
|
|
9
9
|
getCliToken
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
11
11
|
import {
|
|
12
12
|
getActiveHost,
|
|
13
13
|
logger,
|
|
14
14
|
safeJsonParse
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-65DKFJZB.js";
|
|
16
16
|
|
|
17
17
|
// src/core/mcp.ts
|
|
18
18
|
async function permissionMessage(resp) {
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAnalysisMappingPathForClusterMode
|
|
3
|
+
} from "./chunk-WXBCP6SD.js";
|
|
4
|
+
import {
|
|
5
|
+
PermissionError
|
|
6
|
+
} from "./chunk-NOO24N7W.js";
|
|
7
|
+
import {
|
|
8
|
+
clearCliToken,
|
|
9
|
+
getCliToken
|
|
10
|
+
} from "./chunk-OCQPQYHZ.js";
|
|
11
|
+
import {
|
|
12
|
+
getActiveHost,
|
|
13
|
+
logger,
|
|
14
|
+
safeJsonParse
|
|
15
|
+
} from "./chunk-65DKFJZB.js";
|
|
16
|
+
|
|
17
|
+
// src/core/mcp.ts
|
|
18
|
+
async function permissionMessage(resp) {
|
|
19
|
+
const text = await resp.text().catch(() => "");
|
|
20
|
+
try {
|
|
21
|
+
const d = safeJsonParse(text);
|
|
22
|
+
const msg = d && (d.error?.message || (typeof d.error === "string" ? d.error : void 0) || d.message);
|
|
23
|
+
if (msg && typeof msg === "string") return msg;
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
return "Permission denied for this resource (HTTP 403)";
|
|
27
|
+
}
|
|
28
|
+
function isInvalidCliTokenMessage(message) {
|
|
29
|
+
return /\b(cli[-_\s]?token|token)\b.*\binvalid\b/i.test(message) || /\binvalid\b.*\b(cli[-_\s]?token|token)\b/i.test(message);
|
|
30
|
+
}
|
|
31
|
+
var MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
32
|
+
var JSONRPC_VERSION = "2.0";
|
|
33
|
+
var serviceMappingMap = /* @__PURE__ */ new Map();
|
|
34
|
+
registerMcpMapping("analysis", {
|
|
35
|
+
componentName: "analysis",
|
|
36
|
+
mappingPath: "analysis"
|
|
37
|
+
});
|
|
38
|
+
registerMcpMapping("te_analysis_extend", {
|
|
39
|
+
componentName: "analysis",
|
|
40
|
+
mappingPath: "analysis-extend"
|
|
41
|
+
});
|
|
42
|
+
function registerMcpMapping(serviceName, mapping) {
|
|
43
|
+
serviceMappingMap.set(serviceName, mapping);
|
|
44
|
+
}
|
|
45
|
+
function registerMcpMappings(mappings) {
|
|
46
|
+
for (const [serviceName, mapping] of Object.entries(mappings)) {
|
|
47
|
+
serviceMappingMap.set(serviceName, mapping);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function getMcpMapping(serviceName) {
|
|
51
|
+
const mapping = serviceMappingMap.get(serviceName);
|
|
52
|
+
if (!mapping) {
|
|
53
|
+
throw new Error(`MCP mapping not found for service: '${serviceName}'. Please register it using registerMcpMapping() first.`);
|
|
54
|
+
}
|
|
55
|
+
if (serviceName === "analysis") {
|
|
56
|
+
return { ...mapping, mappingPath: getAnalysisMappingPathForClusterMode() };
|
|
57
|
+
}
|
|
58
|
+
return mapping;
|
|
59
|
+
}
|
|
60
|
+
function buildMcpUrl(host, serviceName) {
|
|
61
|
+
const mapping = getMcpMapping(serviceName);
|
|
62
|
+
const base = host.replace(/\/+$/, "");
|
|
63
|
+
return `${base}/mcp/${mapping.componentName}/http/${mapping.mappingPath}`;
|
|
64
|
+
}
|
|
65
|
+
function resolveMcpUrl(mcpUrlOverride, host, serviceName) {
|
|
66
|
+
if (mcpUrlOverride) {
|
|
67
|
+
return mcpUrlOverride;
|
|
68
|
+
}
|
|
69
|
+
return buildMcpUrl(host, serviceName);
|
|
70
|
+
}
|
|
71
|
+
var requestIdCounter = 1;
|
|
72
|
+
function genRequestId() {
|
|
73
|
+
return requestIdCounter++;
|
|
74
|
+
}
|
|
75
|
+
function buildAuthHeaders(cliToken) {
|
|
76
|
+
return {
|
|
77
|
+
"cli-token": cliToken
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async function mcpRequest(url, method, params = {}, hostOverride) {
|
|
81
|
+
const hostUrl = hostOverride || getActiveHost();
|
|
82
|
+
const token = await getCliToken(hostUrl);
|
|
83
|
+
const requestId = genRequestId();
|
|
84
|
+
const paramsWithMeta = {
|
|
85
|
+
...params,
|
|
86
|
+
_meta: { progressToken: requestId }
|
|
87
|
+
};
|
|
88
|
+
const body = {
|
|
89
|
+
jsonrpc: JSONRPC_VERSION,
|
|
90
|
+
id: requestId,
|
|
91
|
+
method,
|
|
92
|
+
params: paramsWithMeta
|
|
93
|
+
};
|
|
94
|
+
const headers = {
|
|
95
|
+
"Content-Type": "application/json",
|
|
96
|
+
"Accept": "application/json, text/event-stream",
|
|
97
|
+
"mcp-protocol-version": MCP_PROTOCOL_VERSION,
|
|
98
|
+
"X-Source": "ae-cli",
|
|
99
|
+
...buildAuthHeaders(token)
|
|
100
|
+
};
|
|
101
|
+
const resp = await fetch(url, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers,
|
|
104
|
+
body: JSON.stringify(body)
|
|
105
|
+
});
|
|
106
|
+
if (!resp.ok) {
|
|
107
|
+
let permissionMsg;
|
|
108
|
+
if (resp.status === 403) {
|
|
109
|
+
permissionMsg = await permissionMessage(resp);
|
|
110
|
+
if (!isInvalidCliTokenMessage(permissionMsg)) {
|
|
111
|
+
throw new PermissionError(permissionMsg);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (resp.status === 401 || resp.status === 403 && permissionMsg) {
|
|
115
|
+
logger.warn(`MCP request failed (${resp.status === 403 ? permissionMsg : "HTTP 401"}) for ${hostUrl}, refreshing CLI token`);
|
|
116
|
+
clearCliToken(hostUrl);
|
|
117
|
+
const newToken = await getCliToken(hostUrl);
|
|
118
|
+
logger.info(`CLI token refreshed for ${hostUrl}`);
|
|
119
|
+
process.stderr.write(`[ae-cli] CLI token refreshed for ${hostUrl}
|
|
120
|
+
`);
|
|
121
|
+
Object.assign(headers, buildAuthHeaders(newToken));
|
|
122
|
+
const retryResp = await fetch(url, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers,
|
|
125
|
+
body: JSON.stringify(body)
|
|
126
|
+
});
|
|
127
|
+
if (retryResp.status === 403) {
|
|
128
|
+
throw new PermissionError(await permissionMessage(retryResp));
|
|
129
|
+
}
|
|
130
|
+
if (!retryResp.ok) {
|
|
131
|
+
throw new Error(`MCP HTTP error: ${retryResp.status} ${retryResp.statusText}`);
|
|
132
|
+
}
|
|
133
|
+
const retryData = safeJsonParse(await retryResp.text());
|
|
134
|
+
if (retryData.error) {
|
|
135
|
+
throw new Error(`MCP error: ${retryData.error.message || JSON.stringify(retryData.error)}`);
|
|
136
|
+
}
|
|
137
|
+
return retryData.result;
|
|
138
|
+
}
|
|
139
|
+
throw new Error(`MCP HTTP error: ${resp.status} ${resp.statusText}`);
|
|
140
|
+
}
|
|
141
|
+
const data = safeJsonParse(await resp.text());
|
|
142
|
+
if (data.error) {
|
|
143
|
+
throw new Error(`MCP error: ${data.error.message || JSON.stringify(data.error)}`);
|
|
144
|
+
}
|
|
145
|
+
return data.result;
|
|
146
|
+
}
|
|
147
|
+
async function callMcpTool(url, toolName, args = {}, hostOverride) {
|
|
148
|
+
const params = {
|
|
149
|
+
name: toolName,
|
|
150
|
+
arguments: args
|
|
151
|
+
};
|
|
152
|
+
logger.info(`MCP tool call: ${toolName}`);
|
|
153
|
+
const result = await mcpRequest(url, "tools/call", params, hostOverride);
|
|
154
|
+
if (result.isError) {
|
|
155
|
+
logger.warn(`MCP tool call failed: ${toolName}`);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
content: result.content.map((item) => {
|
|
159
|
+
if (item.type === "text") {
|
|
160
|
+
return { type: "text", text: item.text };
|
|
161
|
+
} else if (item.type === "image") {
|
|
162
|
+
return { type: "image", data: item.data, mimeType: item.mimeType };
|
|
163
|
+
} else {
|
|
164
|
+
return { type: "resource", ...item };
|
|
165
|
+
}
|
|
166
|
+
}),
|
|
167
|
+
isError: result.isError
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function parseMcpResult(result) {
|
|
171
|
+
if (result.content.length > 0 && result.content[0].type === "text") {
|
|
172
|
+
const text = result.content[0].text || "";
|
|
173
|
+
let parsed;
|
|
174
|
+
try {
|
|
175
|
+
parsed = safeJsonParse(text);
|
|
176
|
+
} catch {
|
|
177
|
+
return text;
|
|
178
|
+
}
|
|
179
|
+
const errMsg = mcpResultErrorMessage(parsed);
|
|
180
|
+
if (errMsg !== null) {
|
|
181
|
+
if (/no_auth|auth_error|permission|forbidden|unauthor|\u65e0\u6743/i.test(errMsg)) {
|
|
182
|
+
throw new PermissionError(errMsg);
|
|
183
|
+
}
|
|
184
|
+
throw new Error(errMsg);
|
|
185
|
+
}
|
|
186
|
+
return parsed;
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
function mcpResultErrorMessage(parsed) {
|
|
191
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
192
|
+
if (parsed.success === true || parsed.ok === true) return null;
|
|
193
|
+
const e = parsed.error;
|
|
194
|
+
if (typeof e === "string" && e.trim()) return e;
|
|
195
|
+
if (e && typeof e === "object") {
|
|
196
|
+
const msg = typeof e.message === "string" && e.message || void 0;
|
|
197
|
+
const code = typeof e.code === "string" && e.code || void 0;
|
|
198
|
+
if (msg && code) return `${code}: ${msg}`;
|
|
199
|
+
if (msg || code) return msg || code;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export {
|
|
205
|
+
registerMcpMappings,
|
|
206
|
+
resolveMcpUrl,
|
|
207
|
+
callMcpTool,
|
|
208
|
+
parseMcpResult
|
|
209
|
+
};
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
load,
|
|
4
4
|
loadCliToken,
|
|
5
5
|
save
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PFJFZVCK.js";
|
|
7
7
|
import {
|
|
8
8
|
getActiveHost,
|
|
9
9
|
getFallbackCliToken,
|
|
10
10
|
listHosts,
|
|
11
11
|
logger,
|
|
12
12
|
safeJsonParse
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-65DKFJZB.js";
|
|
14
14
|
|
|
15
15
|
// src/core/cli-token.ts
|
|
16
16
|
var CLI_TOKEN_GENERATE_PATH = "/v1/ta/cli/token/generate";
|