@thinkingai/ae-cli 6.1.19 → 6.1.20
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 +95 -38
- package/README.zh.md +95 -38
- package/dist/{auth-QPEVVBKT.js → auth-FUM37MHF.js} +236 -127
- package/dist/{capability-ASI62I4A.js → capability-AXFQW5WM.js} +45 -32
- package/dist/{chunk-FR2EDAQM.js → chunk-4P355ZWB.js} +69 -1
- package/dist/chunk-6ZIQV5GW.js +26 -0
- package/dist/chunk-ATSM5XAW.js +623 -0
- package/dist/{chunk-6QK7SYYY.js → chunk-BBEFP4SB.js} +29 -37
- package/dist/{chunk-KEWVSO64.js → chunk-CZU3V3DQ.js} +4 -15
- package/dist/chunk-ECBLHAZO.js +15 -0
- package/dist/{chunk-B5HMQAOM.js → chunk-I4WQAEYB.js} +1 -1
- package/dist/{chunk-QL6R6TSK.js → chunk-LNZBEQXW.js} +6 -5
- package/dist/{chunk-GJXRF7Y6.js → chunk-QJQZH5GQ.js} +47 -78
- package/dist/{chunk-S5PONFBM.js → chunk-RSG4ONOI.js} +7 -7
- package/dist/{chunk-DKEXH6Q5.js → chunk-TAL6CZH6.js} +6 -6
- package/dist/{chunk-JYMGHGCE.js → chunk-VXNMYUXU.js} +24 -13
- package/dist/{chunk-KZ6ZHF5J.js → chunk-WZ6YVQSF.js} +14 -14
- package/dist/{community-report-client-6OL6GBQW.js → community-report-client-XXWGSBSD.js} +2 -4
- package/dist/{config-XNMACCKX.js → config-EXUGQN5T.js} +8 -9
- package/dist/{data-integration-4NZGZ45E.js → data-integration-4NZ53OMT.js} +17 -15
- package/dist/index.js +52 -79
- package/dist/{local-data-upload-client-EFHDLXFG.js → local-data-upload-client-KYOKVYZV.js} +2 -4
- package/dist/{memory-HBJQ2GC5.js → memory-ATNKZNW5.js} +4 -6
- package/dist/{metadata-62EWBEIG.js → metadata-VZVC7YMH.js} +7 -9
- package/dist/{model-BHLJ2QMT.js → model-E4JMQ4V2.js} +4 -6
- package/dist/{personal-semantic-preference-JBVMAI7L.js → personal-semantic-preference-7S2SQ3UV.js} +6 -8
- package/dist/{project-semantic-BQ4MPUS5.js → project-semantic-2SZP2OPO.js} +11 -13
- package/dist/{sync-MUWPRM5I.js → sync-YV3E66IF.js} +6 -8
- package/dist/{te-agent-WQZTMEK4.js → te-agent-JB5T3PO7.js} +393 -90
- package/dist/{te-analysis-MNCG65LU.js → te-analysis-3YJAAT2D.js} +99 -33
- package/dist/{te-community-BNE6KREL.js → te-community-UDBI672N.js} +9 -32
- package/dist/{te-dataops-TXLKM2W6.js → te-dataops-ZLYOCXZ4.js} +19 -20
- package/dist/{te-engage-TPKLRVTL.js → te-engage-4XG6OJML.js} +12 -14
- package/dist/{te-experiment-6BYKTCY7.js → te-experiment-VXUWPINJ.js} +6 -8
- package/dist/{te-kb-BUD6N3NI.js → te-kb-WYQWHFSC.js} +595 -85
- package/dist/{te-system-44LZJDTQ.js → te-system-7G6F2LJA.js} +6 -8
- package/dist/{te-team-XMP47YXE.js → te-team-E7FBBXMQ.js} +6 -8
- package/dist/{update-UODFOZ4P.js → update-D47BUG25.js} +7 -8
- package/package.json +12 -9
- package/skills/ae-agent/SKILL.md +30 -13
- package/skills/ae-agent/references/agent-distribution.md +94 -0
- package/skills/ae-agent/references/approval-request.md +4 -0
- package/skills/ae-agent/references/command_index.md +9 -2
- package/skills/ae-agent/references/create-automation.md +20 -2
- package/skills/ae-agent/references/get-agent-context.md +70 -0
- package/skills/ae-agent/references/list-automations.md +18 -3
- package/skills/ae-agent/references/list-mcp-credentials.md +1 -1
- package/skills/ae-agent/references/mcp-token.md +3 -3
- package/skills/ae-agent/references/set-mcp-credential.md +0 -1
- package/skills/ae-agent/references/update-automation.md +18 -0
- package/skills/ae-analysis/SKILL.md +11 -2
- package/skills/ae-analysis/references/adhoc_run.md +2 -0
- package/skills/ae-analysis/references/ai_models.md +23 -3
- package/skills/ae-analysis/references/analysis_gateway_assets.md +2 -2
- package/skills/ae-analysis/references/command_index.md +7 -7
- package/skills/ae-analysis/references/cross_source_config.md +84 -0
- package/skills/ae-analysis/references/dashboard_update.md +1 -1
- package/skills/ae-analysis/references/user_tag_create.md +23 -1
- package/skills/ae-analysis/references/user_tag_models.md +9 -1
- package/skills/ae-analysis/references/user_tag_update.md +14 -2
- package/skills/ae-data-integration/SKILL.md +2 -1
- package/skills/ae-data-integration/references/dimension-routing.md +36 -0
- package/skills/ae-data-integration/references/local-analysis.md +2 -0
- package/skills/ae-data-integration/references/source-inspect.md +1 -1
- package/skills/ae-data-integration/references/tracking-plan.md +1 -1
- package/skills/ae-data-integration/references/transform.md +1 -1
- package/skills/ae-data-integration/references/ue-mapping.md +5 -2
- package/skills/ae-data-integration/references/ue-routing.md +17 -1
- package/skills/ae-generate-tracking-plan/SKILL.md +25 -13
- package/skills/ae-generate-tracking-plan/references/business-dimension-mapping.md +1 -1
- package/skills/ae-kb/SKILL.md +107 -36
- package/skills/ae-kb/references/query-workflow.md +59 -29
- package/skills/ae-kb/references/versions.md +46 -0
- package/skills/ae-system/SKILL.md +1 -1
- package/skills/ae-use-agent/SKILL.md +42 -0
- package/skills/ae-use-agent/references/local-agent.md +114 -0
- package/dist/auth-UMJAA72O.js +0 -15
- package/dist/chunk-533JK3YX.js +0 -72
- package/dist/chunk-O6K2ODUE.js +0 -318
- package/dist/chunk-RWXIXOZG.js +0 -326
- package/dist/client-N7NGZUNI.js +0 -204
- package/skills/ae-agent/references/auto-provision-mcp-credentials.md +0 -57
package/dist/chunk-RWXIXOZG.js
DELETED
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
SecureStoreAuthError,
|
|
4
|
-
getToken,
|
|
5
|
-
load,
|
|
6
|
-
loadCliToken,
|
|
7
|
-
save
|
|
8
|
-
} from "./chunk-O6K2ODUE.js";
|
|
9
|
-
import {
|
|
10
|
-
getActiveHost,
|
|
11
|
-
getConfigDir,
|
|
12
|
-
getFallbackCliToken,
|
|
13
|
-
listHosts,
|
|
14
|
-
normalizeUrl,
|
|
15
|
-
safeJsonParse,
|
|
16
|
-
safeReadJsonFile
|
|
17
|
-
} from "./chunk-KZ6ZHF5J.js";
|
|
18
|
-
import {
|
|
19
|
-
PermissionError
|
|
20
|
-
} from "./chunk-533JK3YX.js";
|
|
21
|
-
import {
|
|
22
|
-
logger
|
|
23
|
-
} from "./chunk-FR2EDAQM.js";
|
|
24
|
-
|
|
25
|
-
// src/core/cli-token.ts
|
|
26
|
-
import fs from "fs";
|
|
27
|
-
import path from "path";
|
|
28
|
-
var CLI_TOKEN_GENERATE_PATH = "/v1/ta/cli/token/generate";
|
|
29
|
-
var CLI_TOKEN_RENEW_PATH = "/v1/ta/cli/token/renew";
|
|
30
|
-
var CLI_TOKEN_VALIDATE_PATH = "/v1/ta/cli/token/validate";
|
|
31
|
-
var CliTokenValidationUnavailableError = class extends Error {
|
|
32
|
-
constructor(message) {
|
|
33
|
-
super(message);
|
|
34
|
-
this.name = "CliTokenValidationUnavailableError";
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
function isExplicitCliTokenRejection(data, responseText) {
|
|
38
|
-
const code = String(data?.code ?? data?.error?.code ?? "");
|
|
39
|
-
const message = String(data?.return_message ?? data?.message ?? data?.error?.message ?? responseText);
|
|
40
|
-
return /cli[_-]?token[_-]?(invalid|expired)/i.test(code) || /cli[-_\s]?token.*\b(invalid|expired)\b/i.test(message) || /\b(invalid|expired)\b.*cli[-_\s]?token/i.test(message);
|
|
41
|
-
}
|
|
42
|
-
var _cliTokenCache = /* @__PURE__ */ new Map();
|
|
43
|
-
var _renewedLocalDateByHost = /* @__PURE__ */ new Map();
|
|
44
|
-
var _renewInFlightByHost = /* @__PURE__ */ new Map();
|
|
45
|
-
function renewHostKey(hostUrl) {
|
|
46
|
-
return normalizeUrl(hostUrl);
|
|
47
|
-
}
|
|
48
|
-
function renewStateFilePath() {
|
|
49
|
-
return path.join(getConfigDir(), "cli-token-renew.json");
|
|
50
|
-
}
|
|
51
|
-
function localRenewDate(now = /* @__PURE__ */ new Date()) {
|
|
52
|
-
const y = now.getFullYear();
|
|
53
|
-
const m = String(now.getMonth() + 1).padStart(2, "0");
|
|
54
|
-
const d = String(now.getDate()).padStart(2, "0");
|
|
55
|
-
return `${y}-${m}-${d}`;
|
|
56
|
-
}
|
|
57
|
-
function loadRenewStore() {
|
|
58
|
-
try {
|
|
59
|
-
const file = renewStateFilePath();
|
|
60
|
-
if (!fs.existsSync(file)) return {};
|
|
61
|
-
const data = safeReadJsonFile(file);
|
|
62
|
-
if (!data || typeof data !== "object" || Array.isArray(data)) return {};
|
|
63
|
-
return data;
|
|
64
|
-
} catch {
|
|
65
|
-
return {};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function saveRenewStore(store) {
|
|
69
|
-
const dir = getConfigDir();
|
|
70
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
71
|
-
const file = renewStateFilePath();
|
|
72
|
-
if (Object.keys(store).length === 0) {
|
|
73
|
-
try {
|
|
74
|
-
fs.unlinkSync(file);
|
|
75
|
-
} catch {
|
|
76
|
-
}
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
fs.writeFileSync(file, JSON.stringify(store, null, 2), { encoding: "utf8" });
|
|
80
|
-
try {
|
|
81
|
-
fs.chmodSync(file, 384);
|
|
82
|
-
} catch {
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function getPersistedRenewDate(hostUrl) {
|
|
86
|
-
const key = renewHostKey(hostUrl);
|
|
87
|
-
const store = loadRenewStore();
|
|
88
|
-
return store[key]?.date ?? (key !== hostUrl ? store[hostUrl]?.date : void 0) ?? null;
|
|
89
|
-
}
|
|
90
|
-
function markRenewSucceeded(hostUrl, date) {
|
|
91
|
-
const key = renewHostKey(hostUrl);
|
|
92
|
-
_renewedLocalDateByHost.set(key, date);
|
|
93
|
-
const store = loadRenewStore();
|
|
94
|
-
if (key !== hostUrl && store[hostUrl]) {
|
|
95
|
-
delete store[hostUrl];
|
|
96
|
-
}
|
|
97
|
-
store[key] = { date };
|
|
98
|
-
saveRenewStore(store);
|
|
99
|
-
}
|
|
100
|
-
function clearRenewState(hostUrl) {
|
|
101
|
-
if (hostUrl) {
|
|
102
|
-
const key = renewHostKey(hostUrl);
|
|
103
|
-
_renewedLocalDateByHost.delete(key);
|
|
104
|
-
_renewInFlightByHost.delete(key);
|
|
105
|
-
if (key !== hostUrl) {
|
|
106
|
-
_renewedLocalDateByHost.delete(hostUrl);
|
|
107
|
-
_renewInFlightByHost.delete(hostUrl);
|
|
108
|
-
}
|
|
109
|
-
const store = loadRenewStore();
|
|
110
|
-
let changed = false;
|
|
111
|
-
for (const k of /* @__PURE__ */ new Set([key, hostUrl])) {
|
|
112
|
-
if (store[k]) {
|
|
113
|
-
delete store[k];
|
|
114
|
-
changed = true;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (changed) {
|
|
118
|
-
saveRenewStore(store);
|
|
119
|
-
}
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
_renewedLocalDateByHost.clear();
|
|
123
|
-
_renewInFlightByHost.clear();
|
|
124
|
-
saveRenewStore({});
|
|
125
|
-
}
|
|
126
|
-
async function generateCliToken(hostUrl, accessTokenOverride) {
|
|
127
|
-
const accessToken = accessTokenOverride ?? await getToken(hostUrl);
|
|
128
|
-
const base = hostUrl.replace(/\/+$/, "");
|
|
129
|
-
const url = `${base}${CLI_TOKEN_GENERATE_PATH}`;
|
|
130
|
-
const resp = await fetch(url, {
|
|
131
|
-
method: "GET",
|
|
132
|
-
headers: {
|
|
133
|
-
"Authorization": `bearer ${accessToken}`
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
if (!resp.ok) {
|
|
137
|
-
if (resp.status === 403) {
|
|
138
|
-
const text = await resp.text();
|
|
139
|
-
let body = {};
|
|
140
|
-
try {
|
|
141
|
-
body = text ? safeJsonParse(text) : {};
|
|
142
|
-
} catch {
|
|
143
|
-
}
|
|
144
|
-
const message = body.message ?? body.return_message ?? "CLI access is disabled for this account.";
|
|
145
|
-
const code = body.code ?? (String(message).includes("CLI_ACCESS_DISABLED") ? "CLI_ACCESS_DISABLED" : void 0);
|
|
146
|
-
throw new PermissionError(message, code, body.hint);
|
|
147
|
-
}
|
|
148
|
-
throw new Error(`CLI token generate HTTP error: ${resp.status} ${resp.statusText}`);
|
|
149
|
-
}
|
|
150
|
-
const data = safeJsonParse(await resp.text());
|
|
151
|
-
if (data.return_code !== 0) {
|
|
152
|
-
const message = data.return_message || data.message || "unknown";
|
|
153
|
-
if (data.code === "CLI_ACCESS_DISABLED" || String(message).includes("CLI_ACCESS_DISABLED")) {
|
|
154
|
-
throw new PermissionError(message, "CLI_ACCESS_DISABLED", data.hint);
|
|
155
|
-
}
|
|
156
|
-
throw new Error(`CLI token generate error: ${message} (code: ${data.return_code})`);
|
|
157
|
-
}
|
|
158
|
-
const cliToken = data.data?.userSecret;
|
|
159
|
-
if (!cliToken) {
|
|
160
|
-
throw new Error("CLI token generate error: empty userSecret in response");
|
|
161
|
-
}
|
|
162
|
-
return cliToken;
|
|
163
|
-
}
|
|
164
|
-
async function validateCliTokenOnServer(hostUrl, cliToken) {
|
|
165
|
-
const base = hostUrl.replace(/\/+$/, "");
|
|
166
|
-
const url = `${base}${CLI_TOKEN_VALIDATE_PATH}`;
|
|
167
|
-
let resp;
|
|
168
|
-
try {
|
|
169
|
-
resp = await fetch(url, {
|
|
170
|
-
method: "GET",
|
|
171
|
-
headers: {
|
|
172
|
-
Accept: "application/json",
|
|
173
|
-
"cli-token": cliToken
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
} catch (e) {
|
|
177
|
-
throw new CliTokenValidationUnavailableError(`Unable to validate CLI token for ${hostUrl}: ${e.message}`);
|
|
178
|
-
}
|
|
179
|
-
const responseText = await resp.text();
|
|
180
|
-
let data;
|
|
181
|
-
try {
|
|
182
|
-
data = safeJsonParse(responseText);
|
|
183
|
-
} catch {
|
|
184
|
-
data = void 0;
|
|
185
|
-
}
|
|
186
|
-
if (isExplicitCliTokenRejection(data, responseText)) {
|
|
187
|
-
throw new SecureStoreAuthError(
|
|
188
|
-
`CLI token is invalid or expired for ${hostUrl}. Run: ae-cli auth logout --host ${hostUrl}, then ae-cli auth login --host ${hostUrl}`
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
if (!resp.ok) {
|
|
192
|
-
throw new CliTokenValidationUnavailableError(
|
|
193
|
-
`CLI token validation is unavailable for ${hostUrl} (HTTP ${resp.status} ${resp.statusText})`
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
if (data?.return_code !== 0) {
|
|
197
|
-
throw new CliTokenValidationUnavailableError(`CLI token validation returned an unsupported response for ${hostUrl}`);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
async function renewCliTokenOnServer(hostUrl, cliToken) {
|
|
201
|
-
const base = hostUrl.replace(/\/+$/, "");
|
|
202
|
-
const url = new URL(`${base}${CLI_TOKEN_RENEW_PATH}`);
|
|
203
|
-
url.searchParams.set("cli-token", cliToken);
|
|
204
|
-
const headers = {
|
|
205
|
-
Accept: "application/json"
|
|
206
|
-
};
|
|
207
|
-
try {
|
|
208
|
-
const accessToken = await getToken(hostUrl);
|
|
209
|
-
if (accessToken) {
|
|
210
|
-
headers.Authorization = `bearer ${accessToken}`;
|
|
211
|
-
}
|
|
212
|
-
} catch {
|
|
213
|
-
}
|
|
214
|
-
const resp = await fetch(url.toString(), { method: "GET", headers });
|
|
215
|
-
const text = await resp.text();
|
|
216
|
-
const data = safeJsonParse(text);
|
|
217
|
-
if (!resp.ok) {
|
|
218
|
-
throw new Error(`CLI token renew HTTP error: ${resp.status} ${resp.statusText}`);
|
|
219
|
-
}
|
|
220
|
-
if (data?.return_code !== void 0 && data.return_code !== 0) {
|
|
221
|
-
throw new Error(`CLI token renew error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
async function maybeRenewCliTokenDaily(hostUrl, cliToken) {
|
|
225
|
-
const hostKey = renewHostKey(hostUrl);
|
|
226
|
-
const today = localRenewDate();
|
|
227
|
-
if (_renewedLocalDateByHost.get(hostKey) === today) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
if (getPersistedRenewDate(hostUrl) === today) {
|
|
231
|
-
_renewedLocalDateByHost.set(hostKey, today);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const existing = _renewInFlightByHost.get(hostKey);
|
|
235
|
-
if (existing) {
|
|
236
|
-
await existing;
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
const attempt = (async () => {
|
|
240
|
-
try {
|
|
241
|
-
await renewCliTokenOnServer(hostUrl, cliToken);
|
|
242
|
-
markRenewSucceeded(hostUrl, today);
|
|
243
|
-
logger.info(`cli-token: renewed for ${hostKey} (local day ${today})`);
|
|
244
|
-
} catch (e) {
|
|
245
|
-
logger.warn(`cli-token: renew failed for ${hostKey}: ${e?.message || e}; business call proceeds with cached token`);
|
|
246
|
-
} finally {
|
|
247
|
-
_renewInFlightByHost.delete(hostKey);
|
|
248
|
-
}
|
|
249
|
-
})();
|
|
250
|
-
_renewInFlightByHost.set(hostKey, attempt);
|
|
251
|
-
await attempt;
|
|
252
|
-
}
|
|
253
|
-
function persistCliTokenIfPossible(hostUrl, cliToken) {
|
|
254
|
-
const existing = load(hostUrl);
|
|
255
|
-
if (!existing) {
|
|
256
|
-
logger.info(`cli-token: no secure-store session for ${hostUrl}, keeping token in-process only`);
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
save(hostUrl, { ...existing, cliToken });
|
|
260
|
-
}
|
|
261
|
-
function clearPersistedCliToken(hostUrl) {
|
|
262
|
-
const existing = load(hostUrl);
|
|
263
|
-
if (existing?.cliToken) {
|
|
264
|
-
save(hostUrl, { ...existing, cliToken: void 0 });
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
function peekCliToken(hostOverride) {
|
|
268
|
-
const hostUrl = hostOverride || getActiveHost();
|
|
269
|
-
if (!hostUrl) return void 0;
|
|
270
|
-
return _cliTokenCache.get(hostUrl) || loadCliToken(hostUrl) || getFallbackCliToken(hostUrl) || void 0;
|
|
271
|
-
}
|
|
272
|
-
async function getCliToken(hostOverride) {
|
|
273
|
-
const hostUrl = hostOverride || getActiveHost();
|
|
274
|
-
let token = _cliTokenCache.get(hostUrl);
|
|
275
|
-
if (!token) {
|
|
276
|
-
const storedToken = loadCliToken(hostUrl);
|
|
277
|
-
if (storedToken) {
|
|
278
|
-
_cliTokenCache.set(hostUrl, storedToken);
|
|
279
|
-
logger.info(`Using persisted CLI token (secure-store) for ${hostUrl}`);
|
|
280
|
-
token = storedToken;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (!token) {
|
|
284
|
-
const fallbackToken = getFallbackCliToken(hostUrl);
|
|
285
|
-
if (fallbackToken) {
|
|
286
|
-
_cliTokenCache.set(hostUrl, fallbackToken);
|
|
287
|
-
logger.info(`Using sandbox-provisioned CLI token (fallback file) for ${hostUrl}`);
|
|
288
|
-
token = fallbackToken;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
if (!token) {
|
|
292
|
-
token = await mintCliToken(hostUrl);
|
|
293
|
-
}
|
|
294
|
-
await maybeRenewCliTokenDaily(hostUrl, token);
|
|
295
|
-
return token;
|
|
296
|
-
}
|
|
297
|
-
async function mintCliToken(hostUrl, accessTokenOverride, persist = true) {
|
|
298
|
-
logger.info(`Generating CLI token for ${hostUrl}`);
|
|
299
|
-
const cliToken = await generateCliToken(hostUrl, accessTokenOverride);
|
|
300
|
-
_cliTokenCache.set(hostUrl, cliToken);
|
|
301
|
-
if (persist) persistCliTokenIfPossible(hostUrl, cliToken);
|
|
302
|
-
logger.info(`CLI token generated and cached${persist ? " and persisted" : ""} for ${hostUrl}`);
|
|
303
|
-
return cliToken;
|
|
304
|
-
}
|
|
305
|
-
function clearCliToken(hostUrl) {
|
|
306
|
-
if (hostUrl) {
|
|
307
|
-
_cliTokenCache.delete(hostUrl);
|
|
308
|
-
clearPersistedCliToken(hostUrl);
|
|
309
|
-
clearRenewState(hostUrl);
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
_cliTokenCache.clear();
|
|
313
|
-
clearRenewState();
|
|
314
|
-
for (const { url } of listHosts()) {
|
|
315
|
-
clearPersistedCliToken(url);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
export {
|
|
320
|
-
CliTokenValidationUnavailableError,
|
|
321
|
-
validateCliTokenOnServer,
|
|
322
|
-
peekCliToken,
|
|
323
|
-
getCliToken,
|
|
324
|
-
mintCliToken,
|
|
325
|
-
clearCliToken
|
|
326
|
-
};
|
package/dist/client-N7NGZUNI.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
SecureStoreAuthError,
|
|
4
|
-
getToken,
|
|
5
|
-
invalidateAccessTokenForRetry,
|
|
6
|
-
resolveHost
|
|
7
|
-
} from "./chunk-O6K2ODUE.js";
|
|
8
|
-
import {
|
|
9
|
-
safeJsonParse
|
|
10
|
-
} from "./chunk-KZ6ZHF5J.js";
|
|
11
|
-
import {
|
|
12
|
-
logger
|
|
13
|
-
} from "./chunk-FR2EDAQM.js";
|
|
14
|
-
|
|
15
|
-
// src/core/client.ts
|
|
16
|
-
import WebSocket from "ws";
|
|
17
|
-
import { randomBytes } from "crypto";
|
|
18
|
-
function genRequestId(prefix) {
|
|
19
|
-
const rand = randomBytes(4).toString("base64url").slice(0, 8);
|
|
20
|
-
return `${prefix}@@${rand}`;
|
|
21
|
-
}
|
|
22
|
-
function buildUrl(baseUrl, modulePath, params = {}) {
|
|
23
|
-
const base = baseUrl.replace(/\/$/, "");
|
|
24
|
-
const p = modulePath.startsWith("/") ? modulePath : `/${modulePath}`;
|
|
25
|
-
const url = new URL(`${base}${p}`);
|
|
26
|
-
for (const [k, v] of Object.entries(params)) {
|
|
27
|
-
if (v !== void 0 && v !== null) url.searchParams.set(k, String(v));
|
|
28
|
-
}
|
|
29
|
-
return url.toString();
|
|
30
|
-
}
|
|
31
|
-
function buildWsUrl(baseUrl, token) {
|
|
32
|
-
const base = baseUrl.replace(/\/$/, "");
|
|
33
|
-
const wsBase = base.replace(/^https:\/\//, "wss://").replace(/^http:\/\//, "ws://");
|
|
34
|
-
return `${wsBase}/v1/ta-websocket/query/${token}`;
|
|
35
|
-
}
|
|
36
|
-
async function request(method, modulePath, params = {}, body = null, retry = true, hostUrl) {
|
|
37
|
-
const resolvedHost = resolveHost(hostUrl);
|
|
38
|
-
const token = await getToken(resolvedHost);
|
|
39
|
-
const url = buildUrl(resolvedHost, modulePath, params);
|
|
40
|
-
const headers = {
|
|
41
|
-
"Authorization": `bearer ${token}`,
|
|
42
|
-
"Content-Type": "application/json"
|
|
43
|
-
};
|
|
44
|
-
const options = { method, headers };
|
|
45
|
-
if (body && method !== "GET") options.body = JSON.stringify(body);
|
|
46
|
-
const resp = await fetch(url, options);
|
|
47
|
-
const text = await resp.text();
|
|
48
|
-
const data = safeJsonParse(text);
|
|
49
|
-
logger.api(method, url, resp.status, body, data);
|
|
50
|
-
if (resp.status === 401) {
|
|
51
|
-
if (retry) {
|
|
52
|
-
invalidateAccessTokenForRetry(resolvedHost);
|
|
53
|
-
return request(method, modulePath, params, body, false, resolvedHost);
|
|
54
|
-
}
|
|
55
|
-
throw new SecureStoreAuthError(`Session expired or unauthorized for ${resolvedHost}. Please run: ae-cli auth login`);
|
|
56
|
-
}
|
|
57
|
-
if (resp.status === 403) {
|
|
58
|
-
const m = data && typeof data === "object" && typeof data.error === "string" ? data.error : "Permission denied";
|
|
59
|
-
throw new Error(m);
|
|
60
|
-
}
|
|
61
|
-
if (data.return_code === -1001 && retry) {
|
|
62
|
-
invalidateAccessTokenForRetry(resolvedHost);
|
|
63
|
-
return request(method, modulePath, params, body, false, resolvedHost);
|
|
64
|
-
}
|
|
65
|
-
if (data.return_code !== 0 && data.return_code !== void 0) {
|
|
66
|
-
throw new Error(`AE API error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
67
|
-
}
|
|
68
|
-
return data.data !== void 0 ? data.data : data;
|
|
69
|
-
}
|
|
70
|
-
async function httpGet(modulePath, params = {}, hostUrl) {
|
|
71
|
-
return request("GET", modulePath, params, null, true, hostUrl);
|
|
72
|
-
}
|
|
73
|
-
async function httpPost(modulePath, params = {}, body, hostUrl) {
|
|
74
|
-
return request("POST", modulePath, params, body ?? {}, true, hostUrl);
|
|
75
|
-
}
|
|
76
|
-
async function httpRequest(method, modulePath, params = {}, body, hostUrl) {
|
|
77
|
-
return request(method.toUpperCase(), modulePath, params, body ?? {}, true, hostUrl);
|
|
78
|
-
}
|
|
79
|
-
async function httpDelete(modulePath, params = {}, body, hostUrl) {
|
|
80
|
-
return request("DELETE", modulePath, params, body ?? null, true, hostUrl);
|
|
81
|
-
}
|
|
82
|
-
async function uploadRequest(modulePath, form, params = {}, retry = true, hostUrl) {
|
|
83
|
-
const resolvedHost = resolveHost(hostUrl);
|
|
84
|
-
const token = await getToken(resolvedHost);
|
|
85
|
-
const url = buildUrl(resolvedHost, modulePath, params);
|
|
86
|
-
const headers = {
|
|
87
|
-
"Authorization": `bearer ${token}`
|
|
88
|
-
};
|
|
89
|
-
const resp = await fetch(url, { method: "POST", headers, body: form });
|
|
90
|
-
const text = await resp.text();
|
|
91
|
-
const data = safeJsonParse(text);
|
|
92
|
-
logger.api("POST", url, resp.status, { upload: true }, data);
|
|
93
|
-
if (resp.status === 401) {
|
|
94
|
-
if (retry) {
|
|
95
|
-
invalidateAccessTokenForRetry(resolvedHost);
|
|
96
|
-
return uploadRequest(modulePath, form, params, false, resolvedHost);
|
|
97
|
-
}
|
|
98
|
-
throw new SecureStoreAuthError(`Session expired or unauthorized for ${resolvedHost}. Please run: ae-cli auth login`);
|
|
99
|
-
}
|
|
100
|
-
if (resp.status === 403) {
|
|
101
|
-
const m = data && typeof data === "object" && typeof data.error === "string" ? data.error : "Permission denied";
|
|
102
|
-
throw new Error(m);
|
|
103
|
-
}
|
|
104
|
-
if (data.return_code === -1001 && retry) {
|
|
105
|
-
invalidateAccessTokenForRetry(resolvedHost);
|
|
106
|
-
return uploadRequest(modulePath, form, params, false, resolvedHost);
|
|
107
|
-
}
|
|
108
|
-
if (data.return_code !== 0 && data.return_code !== void 0) {
|
|
109
|
-
throw new Error(`AE API error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
110
|
-
}
|
|
111
|
-
return data.data !== void 0 ? data.data : data;
|
|
112
|
-
}
|
|
113
|
-
async function httpUpload(modulePath, form, params = {}, hostUrl) {
|
|
114
|
-
return uploadRequest(modulePath, form, params, true, hostUrl);
|
|
115
|
-
}
|
|
116
|
-
async function wsQueryOnce(projectId, requestId, qp, eventModel, options = {}, token, hostUrl, timeoutMs = 3e4) {
|
|
117
|
-
const wsUrl = buildWsUrl(hostUrl, token);
|
|
118
|
-
return new Promise((resolve, reject) => {
|
|
119
|
-
const ws = new WebSocket(wsUrl);
|
|
120
|
-
const timer = setTimeout(() => {
|
|
121
|
-
ws.close();
|
|
122
|
-
reject(new Error(`WebSocket query timed out after ${timeoutMs}ms`));
|
|
123
|
-
}, timeoutMs);
|
|
124
|
-
ws.on("open", () => {
|
|
125
|
-
const payload = {
|
|
126
|
-
requestId,
|
|
127
|
-
projectId,
|
|
128
|
-
eventModel,
|
|
129
|
-
qp: typeof qp === "string" ? qp : JSON.stringify(qp),
|
|
130
|
-
searchSource: options.searchSource || "reportQuery",
|
|
131
|
-
querySource: options.querySource || "single_report",
|
|
132
|
-
contentTranslate: options.contentTranslate !== false,
|
|
133
|
-
...options.extra || {}
|
|
134
|
-
};
|
|
135
|
-
ws.send(JSON.stringify(["data", payload, { channel: "ta" }]));
|
|
136
|
-
});
|
|
137
|
-
ws.on("message", (raw) => {
|
|
138
|
-
try {
|
|
139
|
-
const msg = safeJsonParse(raw.toString());
|
|
140
|
-
if (Array.isArray(msg) && msg.length >= 2) {
|
|
141
|
-
const data = msg[1];
|
|
142
|
-
if (data.requestId === requestId && data.progress === 100) {
|
|
143
|
-
clearTimeout(timer);
|
|
144
|
-
ws.close();
|
|
145
|
-
resolve(data);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
} catch {
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
ws.on("error", (err) => {
|
|
152
|
-
clearTimeout(timer);
|
|
153
|
-
reject(err);
|
|
154
|
-
});
|
|
155
|
-
ws.on("close", () => {
|
|
156
|
-
clearTimeout(timer);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
async function wsQuery(projectId, requestId, qp, eventModel, options = {}, hostUrl) {
|
|
161
|
-
const resolvedHost = resolveHost(hostUrl);
|
|
162
|
-
const token = await getToken(resolvedHost);
|
|
163
|
-
try {
|
|
164
|
-
return await wsQueryOnce(projectId, requestId, qp, eventModel, options, token, resolvedHost);
|
|
165
|
-
} catch (err) {
|
|
166
|
-
const msg = err.message || "";
|
|
167
|
-
if (msg.includes("401") || msg.includes("403") || msg.includes("auth")) {
|
|
168
|
-
invalidateAccessTokenForRetry(resolvedHost);
|
|
169
|
-
const newToken = await getToken(resolvedHost);
|
|
170
|
-
return wsQueryOnce(projectId, requestId, qp, eventModel, options, newToken, resolvedHost);
|
|
171
|
-
}
|
|
172
|
-
throw err;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
async function querySql(projectId, sql, hostUrl) {
|
|
176
|
-
const requestId = genRequestId("sqlIde");
|
|
177
|
-
const qp = {
|
|
178
|
-
events: { sql },
|
|
179
|
-
eventView: { sqlViewParams: [] }
|
|
180
|
-
};
|
|
181
|
-
return wsQuery(projectId, requestId, qp, 10, {
|
|
182
|
-
searchSource: "sqlIde",
|
|
183
|
-
querySource: "sqlIde"
|
|
184
|
-
}, hostUrl);
|
|
185
|
-
}
|
|
186
|
-
async function queryReportData(projectId, reportId, qp, eventModel, options = {}, hostUrl) {
|
|
187
|
-
const dashboardId = options.dashboardId || 0;
|
|
188
|
-
const requestId = genRequestId(`${projectId}_${dashboardId}_${reportId}`);
|
|
189
|
-
return wsQuery(projectId, requestId, qp, eventModel, {
|
|
190
|
-
searchSource: options.searchSource || "model_search",
|
|
191
|
-
querySource: options.querySource || "module",
|
|
192
|
-
...options
|
|
193
|
-
}, hostUrl);
|
|
194
|
-
}
|
|
195
|
-
export {
|
|
196
|
-
httpDelete,
|
|
197
|
-
httpGet,
|
|
198
|
-
httpPost,
|
|
199
|
-
httpRequest,
|
|
200
|
-
httpUpload,
|
|
201
|
-
queryReportData,
|
|
202
|
-
querySql,
|
|
203
|
-
wsQuery
|
|
204
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# agent +auto-provision-mcp-credentials (Auto-Provision MCP Credentials)
|
|
2
|
-
|
|
3
|
-
> **Prerequisite:** Follow the Global AE CLI Rules in [`../SKILL.md`](../SKILL.md).
|
|
4
|
-
|
|
5
|
-
Domain: **MCP Credentials / write**
|
|
6
|
-
|
|
7
|
-
## Use Cases
|
|
8
|
-
- Auto-provision per-user credentials for all system-scope MCP servers in one call.
|
|
9
|
-
- Endpoint: `POST /api/sandbox/agent/mcp-credentials/auto-provision`.
|
|
10
|
-
- Uses the current user's access token to mint MCP tokens via the central token-generation endpoint.
|
|
11
|
-
- For `useMcpToken=true` system servers, a shared MCP token is generated and stored; for OAuth system servers, the access token is stored as the credential.
|
|
12
|
-
|
|
13
|
-
## Mandatory Rules (MUST)
|
|
14
|
-
- `--access-token` is optional; when omitted, the current session token is used automatically (via `ctx.token()`).
|
|
15
|
-
- The access token must be valid — an invalid/expired token causes the MCP token generation to fail (reported via `mcpTokenFailed: true` in the response).
|
|
16
|
-
- This is an ordinary `write` operation and does not require CLI confirmation.
|
|
17
|
-
- This is a bulk operation — it upserts credentials for ALL system MCP servers visible to the current user.
|
|
18
|
-
|
|
19
|
-
## Command
|
|
20
|
-
```bash
|
|
21
|
-
# Auto-provision using the current session token (recommended)
|
|
22
|
-
ae-cli agent +auto-provision-mcp-credentials
|
|
23
|
-
|
|
24
|
-
# Explicitly pass an access token
|
|
25
|
-
ae-cli agent +auto-provision-mcp-credentials --access-token "eyJhbGci..."
|
|
26
|
-
|
|
27
|
-
# Dry-run to inspect the request
|
|
28
|
-
ae-cli agent +auto-provision-mcp-credentials --dry-run
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Parameters
|
|
32
|
-
| Parameter | Required | Description |
|
|
33
|
-
|---|---|---|
|
|
34
|
-
| `--access-token` | No | Access token (defaults to the current session token) |
|
|
35
|
-
|
|
36
|
-
## Decision Rules
|
|
37
|
-
- If the user wants to set up all system MCP credentials in one step, use this command.
|
|
38
|
-
- Prefer running without `--access-token` — the CLI automatically sources the current session token.
|
|
39
|
-
- The response reports `count` (total system servers processed), `mcpTokenCount` (servers that got a shared MCP token), and `mcpTokenFailed` (whether the MCP token generation failed).
|
|
40
|
-
- If `mcpTokenFailed` is `true`, the MCP token endpoint may be down or the access token invalid — check the access token and retry.
|
|
41
|
-
- For individual credential control, use `+set-mcp-credential` instead.
|
|
42
|
-
|
|
43
|
-
## Response Shape
|
|
44
|
-
```json
|
|
45
|
-
{
|
|
46
|
-
"count": 3,
|
|
47
|
-
"mcpTokenCount": 1,
|
|
48
|
-
"mcpTokenFailed": false
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Next Steps on Failure
|
|
53
|
-
- `401` / auth expired: run `ae-cli auth login`, then retry.
|
|
54
|
-
- `mcpTokenFailed: true`: the MCP token generation failed — verify the access token is valid and the MCP token endpoint is configured.
|
|
55
|
-
|
|
56
|
-
## Recommended Chaining
|
|
57
|
-
- `ae-cli auth login` → `+auto-provision-mcp-credentials` → `+list-mcp-credentials` (verify) → `+mcp-token` (get shared token)
|