@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
|
@@ -1,39 +1,47 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
MultiselectCancelled,
|
|
4
|
+
promptSingleSelect
|
|
5
|
+
} from "./chunk-7K24F7T2.js";
|
|
6
|
+
import {
|
|
7
|
+
missingAeHostGuidance,
|
|
8
|
+
missingAeHostHint
|
|
9
|
+
} from "./chunk-6ZIQV5GW.js";
|
|
2
10
|
import {
|
|
3
11
|
getLocalCliPackageInfo
|
|
4
12
|
} from "./chunk-E2JKXMVO.js";
|
|
13
|
+
import {
|
|
14
|
+
resolveHost
|
|
15
|
+
} from "./chunk-ECBLHAZO.js";
|
|
5
16
|
import {
|
|
6
17
|
printError,
|
|
7
18
|
printOutput,
|
|
8
19
|
runHostCompatCheck
|
|
9
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-CZU3V3DQ.js";
|
|
10
21
|
import {
|
|
11
22
|
CliTokenValidationUnavailableError,
|
|
12
|
-
|
|
23
|
+
SecureStoreAuthError,
|
|
24
|
+
activateCredential,
|
|
25
|
+
clearAllCredentials,
|
|
26
|
+
clearCliTokenCache,
|
|
27
|
+
getActiveCredential,
|
|
28
|
+
listCredentials,
|
|
13
29
|
mintCliToken,
|
|
30
|
+
removeActiveCredential,
|
|
31
|
+
saveCredential,
|
|
32
|
+
updateCredentialMetadata,
|
|
14
33
|
validateCliTokenOnServer
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import {
|
|
17
|
-
SecureStoreAuthError,
|
|
18
|
-
clear,
|
|
19
|
-
load,
|
|
20
|
-
missingAeHostGuidance,
|
|
21
|
-
missingAeHostHint,
|
|
22
|
-
resolveHost,
|
|
23
|
-
save
|
|
24
|
-
} from "./chunk-O6K2ODUE.js";
|
|
34
|
+
} from "./chunk-ATSM5XAW.js";
|
|
25
35
|
import {
|
|
26
36
|
getFallbackCliToken,
|
|
27
37
|
loadConfig,
|
|
28
38
|
normalizeUrl,
|
|
29
39
|
saveConfig
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import {
|
|
32
|
-
PermissionError
|
|
33
|
-
} from "./chunk-533JK3YX.js";
|
|
40
|
+
} from "./chunk-WZ6YVQSF.js";
|
|
34
41
|
import {
|
|
42
|
+
PermissionError,
|
|
35
43
|
logger
|
|
36
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-4P355ZWB.js";
|
|
37
45
|
|
|
38
46
|
// src/core/device-auth.ts
|
|
39
47
|
import { execFileSync } from "child_process";
|
|
@@ -263,55 +271,141 @@ function resolveAuthHost(program, opts) {
|
|
|
263
271
|
}
|
|
264
272
|
async function validateExistingCliToken(host, cliToken) {
|
|
265
273
|
try {
|
|
266
|
-
await validateCliTokenOnServer(host, cliToken);
|
|
267
|
-
return true;
|
|
274
|
+
return { valid: true, trusted: false, details: await validateCliTokenOnServer(host, cliToken) };
|
|
268
275
|
} catch (error) {
|
|
269
276
|
if (error instanceof CliTokenValidationUnavailableError) {
|
|
270
277
|
logger.warn(`auth status: ${error.message}; trusting the stored CLI token for compatibility`);
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
if (!(error instanceof SecureStoreAuthError)) {
|
|
274
|
-
throw error;
|
|
278
|
+
return { valid: true, trusted: true, details: {} };
|
|
275
279
|
}
|
|
280
|
+
if (!(error instanceof SecureStoreAuthError)) throw error;
|
|
276
281
|
printError("auth", error.message);
|
|
277
282
|
process.exitCode = 1;
|
|
278
|
-
return false;
|
|
283
|
+
return { valid: false, trusted: false, details: {} };
|
|
279
284
|
}
|
|
280
285
|
}
|
|
281
286
|
function activateHostAfterLogin(host, explicitHostOverride) {
|
|
282
287
|
if (!explicitHostOverride) return;
|
|
283
288
|
const normalized = normalizeUrl(host);
|
|
284
289
|
const config = loadConfig();
|
|
285
|
-
if (!config.hosts[normalized]) {
|
|
286
|
-
config.hosts[normalized] = { label: normalized };
|
|
287
|
-
}
|
|
290
|
+
if (!config.hosts[normalized]) config.hosts[normalized] = { label: normalized };
|
|
288
291
|
config.activeHost = normalized;
|
|
289
292
|
saveConfig(config);
|
|
290
293
|
logger.info(`Active host set to ${normalized} after login`);
|
|
291
294
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
295
|
+
function accountOutput(account) {
|
|
296
|
+
return {
|
|
297
|
+
open_id: account.openId,
|
|
298
|
+
login_name: account.loginName,
|
|
299
|
+
user_name: account.userName
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function credentialOutput(credential, active) {
|
|
303
|
+
return {
|
|
304
|
+
credential_id: credential.id,
|
|
305
|
+
active,
|
|
306
|
+
...credential.account ? { account: accountOutput(credential.account) } : {},
|
|
307
|
+
cli_token: {
|
|
308
|
+
...credential.cliTokenExpiresAt ? { expires_at: credential.cliTokenExpiresAt } : {},
|
|
309
|
+
...credential.lastRenewedOn ? { last_renewed_on: credential.lastRenewedOn } : {}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function buildAccountSelectionItems(credentials, activeCredentialId) {
|
|
314
|
+
return credentials.filter((credential) => Boolean(credential.account)).sort((left, right) => Number(right.id === activeCredentialId) - Number(left.id === activeCredentialId)).map((credential) => {
|
|
315
|
+
const account = credential.account;
|
|
316
|
+
const displayName = account.userName && account.userName !== account.loginName ? `${account.loginName} (${account.userName})` : account.loginName;
|
|
317
|
+
const active = credential.id === activeCredentialId ? " [active]" : "";
|
|
318
|
+
return {
|
|
319
|
+
value: account.openId,
|
|
320
|
+
label: `${displayName} \xB7 ${account.openId}${active}`
|
|
321
|
+
};
|
|
307
322
|
});
|
|
323
|
+
}
|
|
324
|
+
async function switchActiveAccount(program, opts) {
|
|
325
|
+
const host = resolveAuthHost(program, opts);
|
|
326
|
+
if (!host) {
|
|
327
|
+
printError("config", "No AE host configured.", missingAeHostHint());
|
|
328
|
+
process.exitCode = 1;
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
let account = opts.account;
|
|
332
|
+
if (!account) {
|
|
333
|
+
if (!process.stdin.isTTY || !process.stderr.isTTY) {
|
|
334
|
+
printError(
|
|
335
|
+
"validation",
|
|
336
|
+
"Interactive account selection requires a TTY.",
|
|
337
|
+
`Run: ae-cli auth list --host ${host}, then ae-cli auth use --host ${host} --account <login-name-or-open-id>`
|
|
338
|
+
);
|
|
339
|
+
process.exitCode = 1;
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const active = getActiveCredential(host);
|
|
343
|
+
const items = buildAccountSelectionItems(listCredentials(host), active?.id);
|
|
344
|
+
if (items.length === 0) {
|
|
345
|
+
printError(
|
|
346
|
+
"auth",
|
|
347
|
+
`No stored accounts with identity metadata for ${host}.`,
|
|
348
|
+
`Upgrade the AE server if needed, then run: ae-cli auth login --host ${host}`
|
|
349
|
+
);
|
|
350
|
+
process.exitCode = 1;
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
account = await promptSingleSelect({
|
|
355
|
+
title: `Select an account for ${host} (up/down: move, enter: select, q: cancel)`,
|
|
356
|
+
items
|
|
357
|
+
});
|
|
358
|
+
} catch (error) {
|
|
359
|
+
if (error instanceof MultiselectCancelled) return;
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
const selected = activateCredential(host, account);
|
|
365
|
+
clearCliTokenCache(host);
|
|
366
|
+
await printOutput({
|
|
367
|
+
host,
|
|
368
|
+
active: true,
|
|
369
|
+
account: accountOutput(selected.account)
|
|
370
|
+
}, program.opts().format || "json");
|
|
371
|
+
} catch (error) {
|
|
372
|
+
printError("auth", error.message);
|
|
373
|
+
process.exitCode = 1;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
async function persistDeviceTokens(host, tokens, options = {}) {
|
|
377
|
+
const cliToken = await mintCliToken(host, tokens.access_token);
|
|
378
|
+
let validation = {};
|
|
379
|
+
try {
|
|
380
|
+
validation = await validateCliTokenOnServer(host, cliToken);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
if (error instanceof CliTokenValidationUnavailableError) {
|
|
383
|
+
logger.warn(`auth login: ${error.message}; saving CLI token without account metadata for compatibility`);
|
|
384
|
+
} else {
|
|
385
|
+
clearCliTokenCache(host);
|
|
386
|
+
throw error;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
let saved;
|
|
390
|
+
try {
|
|
391
|
+
saved = saveCredential(host, {
|
|
392
|
+
cliToken,
|
|
393
|
+
...validation.account ? { account: validation.account } : {},
|
|
394
|
+
...validation.cliTokenExpiresAt ? { cliTokenExpiresAt: validation.cliTokenExpiresAt } : {}
|
|
395
|
+
}, options);
|
|
396
|
+
} catch (error) {
|
|
397
|
+
clearCliTokenCache(host);
|
|
398
|
+
throw error;
|
|
399
|
+
}
|
|
400
|
+
clearCliTokenCache(host);
|
|
308
401
|
await runHostCompatCheck(getLocalCliPackageInfo(), host);
|
|
402
|
+
return saved;
|
|
309
403
|
}
|
|
310
|
-
function loginSummary(host,
|
|
404
|
+
function loginSummary(host, credential) {
|
|
311
405
|
return {
|
|
312
406
|
authenticated: true,
|
|
313
407
|
host,
|
|
314
|
-
|
|
408
|
+
...credential.account ? { account: accountOutput(credential.account) } : {}
|
|
315
409
|
};
|
|
316
410
|
}
|
|
317
411
|
function resolveLoginTeClaudeBase(host) {
|
|
@@ -320,8 +414,10 @@ function resolveLoginTeClaudeBase(host) {
|
|
|
320
414
|
return base.endsWith(basePath) ? base : base + basePath;
|
|
321
415
|
}
|
|
322
416
|
function registerAuth(program) {
|
|
323
|
-
const auth = program.command("auth").description("
|
|
324
|
-
|
|
417
|
+
const auth = program.command("auth").description("Manage authentication or switch the active account interactively").action(async () => {
|
|
418
|
+
await switchActiveAccount(program, {});
|
|
419
|
+
});
|
|
420
|
+
auth.command("login").description("Log in to AE; by default replaces this host credentials, --add keeps existing accounts").option("--host <url>", HOST_OPTION_DESC).option("--add", "Add another account for the host and keep existing accounts").option("--no-browser", "Do not auto-open the browser; only print the authorization URL").option("--no-wait", "Print device authorization data and exit; resume with --device-code").option("--device-code <code>", "Resume a split-flow login with the given device code").action(async (opts) => {
|
|
325
421
|
const explicitHost = getExplicitAuthHostOverride(program, opts);
|
|
326
422
|
const host = resolveAuthHost(program, opts);
|
|
327
423
|
if (!host) {
|
|
@@ -331,135 +427,148 @@ function registerAuth(program) {
|
|
|
331
427
|
const config = loadConfig();
|
|
332
428
|
if (!config.hosts[host]) {
|
|
333
429
|
config.hosts[host] = { label: host };
|
|
334
|
-
if (!config.activeHost)
|
|
335
|
-
config.activeHost = host;
|
|
336
|
-
}
|
|
430
|
+
if (!config.activeHost) config.activeHost = host;
|
|
337
431
|
saveConfig(config);
|
|
338
|
-
logger.info(`Host config auto-saved for ${host}`);
|
|
339
432
|
process.stderr.write(`[ae-cli] Config saved for ${host}
|
|
340
433
|
`);
|
|
341
434
|
}
|
|
342
435
|
const noBrowser = !opts.browser;
|
|
343
|
-
const
|
|
436
|
+
const format = program.opts().format || "json";
|
|
344
437
|
const teClaudeBase = resolveLoginTeClaudeBase(host);
|
|
345
|
-
const emit = (
|
|
438
|
+
const emit = (message) => process.stderr.write(`[ae-cli] ${message}
|
|
346
439
|
`);
|
|
347
440
|
try {
|
|
348
441
|
if (opts.deviceCode) {
|
|
349
442
|
const tokens2 = await pollDeviceFlow(teClaudeBase, opts.deviceCode, {}, emit);
|
|
350
|
-
await persistDeviceTokens(host, tokens2);
|
|
443
|
+
const saved2 = await persistDeviceTokens(host, tokens2, { add: opts.add });
|
|
351
444
|
activateHostAfterLogin(host, explicitHost);
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
await printOutput(loginSummary(host, tokens2), fmt);
|
|
445
|
+
emit("Login successful! CLI token saved securely.");
|
|
446
|
+
await printOutput(loginSummary(host, saved2), format);
|
|
355
447
|
return;
|
|
356
448
|
}
|
|
357
449
|
if (opts.wait === false) {
|
|
358
450
|
const authResp = await authorizeDevice(teClaudeBase);
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
fmt
|
|
369
|
-
);
|
|
451
|
+
const addFlag = opts.add ? " --add" : "";
|
|
452
|
+
await printOutput({
|
|
453
|
+
device_code: authResp.device_code,
|
|
454
|
+
user_code: authResp.user_code,
|
|
455
|
+
verification_url: buildVerificationUrl(teClaudeBase, authResp.user_code),
|
|
456
|
+
interval: authResp.interval,
|
|
457
|
+
expires_in: authResp.expires_in,
|
|
458
|
+
next: `Open verification_url in a browser to authorize, then run: ae-cli auth login${addFlag} --device-code ${authResp.device_code}`
|
|
459
|
+
}, format);
|
|
370
460
|
return;
|
|
371
461
|
}
|
|
372
462
|
const tokens = await runDeviceFlow(teClaudeBase, { noBrowser }, emit);
|
|
373
|
-
await persistDeviceTokens(host, tokens);
|
|
463
|
+
const saved = await persistDeviceTokens(host, tokens, { add: opts.add });
|
|
374
464
|
activateHostAfterLogin(host, explicitHost);
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
printError(
|
|
381
|
-
"auth",
|
|
382
|
-
err.message,
|
|
383
|
-
"Upgrade the AE server to a version that supports device login."
|
|
384
|
-
);
|
|
465
|
+
emit("Login successful! CLI token saved securely.");
|
|
466
|
+
await printOutput(loginSummary(host, saved), format);
|
|
467
|
+
} catch (error) {
|
|
468
|
+
if (error instanceof DeviceFlowUnsupportedError) {
|
|
469
|
+
printError("auth", error.message, "Upgrade the AE server to a version that supports device login.");
|
|
385
470
|
process.exit(1);
|
|
386
471
|
}
|
|
387
|
-
if (
|
|
388
|
-
printError("permission",
|
|
472
|
+
if (error instanceof PermissionError) {
|
|
473
|
+
printError("permission", error.message, error.hint, error.code);
|
|
389
474
|
process.exit(1);
|
|
390
475
|
}
|
|
391
|
-
printError("auth",
|
|
476
|
+
printError("auth", error.message);
|
|
392
477
|
process.exit(1);
|
|
393
478
|
}
|
|
394
479
|
});
|
|
395
|
-
auth.command("status").description("Show authentication status for a host
|
|
480
|
+
auth.command("status").description("Show the active CLI-token authentication status for a host").option("--host <url>", HOST_OPTION_DESC).action(async (opts) => {
|
|
396
481
|
const host = resolveAuthHost(program, opts);
|
|
397
482
|
if (!host) {
|
|
398
|
-
await printOutput(
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
},
|
|
405
|
-
program.opts().format || "json"
|
|
406
|
-
);
|
|
483
|
+
await printOutput({
|
|
484
|
+
authenticated: false,
|
|
485
|
+
host: "(none)",
|
|
486
|
+
hint: missingAeHostHint(),
|
|
487
|
+
next_steps: missingAeHostGuidance()
|
|
488
|
+
}, program.opts().format || "json");
|
|
407
489
|
return;
|
|
408
490
|
}
|
|
409
|
-
const
|
|
410
|
-
if (
|
|
411
|
-
|
|
412
|
-
|
|
491
|
+
const active = getActiveCredential(host);
|
|
492
|
+
if (active) {
|
|
493
|
+
const state = await validateExistingCliToken(host, active.cliToken);
|
|
494
|
+
if (!state.valid) return;
|
|
495
|
+
if (state.details.account || state.details.cliTokenExpiresAt) {
|
|
496
|
+
updateCredentialMetadata(host, active.cliToken, state.details);
|
|
413
497
|
}
|
|
414
|
-
const
|
|
415
|
-
await printOutput(
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
hasCliToken: !!secureEntry.cliToken
|
|
498
|
+
const current = getActiveCredential(host) ?? active;
|
|
499
|
+
await printOutput({
|
|
500
|
+
authenticated: true,
|
|
501
|
+
host,
|
|
502
|
+
source: "secure-store",
|
|
503
|
+
cli_token: {
|
|
504
|
+
status: state.trusted ? "trusted" : "valid",
|
|
505
|
+
...current.cliTokenExpiresAt ? { expires_at: current.cliTokenExpiresAt } : {},
|
|
506
|
+
...current.lastRenewedOn ? { last_renewed_on: current.lastRenewedOn } : {}
|
|
424
507
|
},
|
|
425
|
-
|
|
426
|
-
);
|
|
508
|
+
...current.account ? { account: accountOutput(current.account) } : {}
|
|
509
|
+
}, program.opts().format || "json");
|
|
427
510
|
return;
|
|
428
511
|
}
|
|
429
|
-
const
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
note: "sandbox-provisioned cli-token.json; no user access token in secure-store"
|
|
512
|
+
const fallback = getFallbackCliToken(host);
|
|
513
|
+
if (fallback) {
|
|
514
|
+
const state = await validateExistingCliToken(host, fallback);
|
|
515
|
+
if (!state.valid) return;
|
|
516
|
+
await printOutput({
|
|
517
|
+
authenticated: true,
|
|
518
|
+
host,
|
|
519
|
+
source: "sandbox-cli-token",
|
|
520
|
+
cli_token: {
|
|
521
|
+
status: state.trusted ? "trusted" : "valid",
|
|
522
|
+
...state.details.cliTokenExpiresAt ? { expires_at: state.details.cliTokenExpiresAt } : {}
|
|
441
523
|
},
|
|
442
|
-
|
|
443
|
-
);
|
|
524
|
+
...state.details.account ? { account: accountOutput(state.details.account) } : {}
|
|
525
|
+
}, program.opts().format || "json");
|
|
444
526
|
return;
|
|
445
527
|
}
|
|
446
528
|
await printOutput({ authenticated: false, host, source: "none" }, program.opts().format || "json");
|
|
447
529
|
});
|
|
448
|
-
auth.command("
|
|
530
|
+
auth.command("list").description("List stored accounts for one host (does not call the server)").option("--host <url>", HOST_OPTION_DESC).action(async (opts) => {
|
|
449
531
|
const host = resolveAuthHost(program, opts);
|
|
450
532
|
if (!host) {
|
|
451
533
|
printError("config", "No AE host configured.", missingAeHostHint());
|
|
452
534
|
process.exit(1);
|
|
453
535
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
536
|
+
const active = getActiveCredential(host);
|
|
537
|
+
const credentials = listCredentials(host);
|
|
538
|
+
await printOutput({
|
|
539
|
+
host,
|
|
540
|
+
accounts: credentials.map((credential) => credentialOutput(credential, credential.id === active?.id))
|
|
541
|
+
}, program.opts().format || "json");
|
|
542
|
+
});
|
|
543
|
+
auth.command("use").description("Switch the active account for a host; omit --account to choose interactively").option("--account <login-name-or-open-id>", "Login name or open_id returned by auth list").option("--host <url>", HOST_OPTION_DESC).action(async (opts) => {
|
|
544
|
+
await switchActiveAccount(program, opts);
|
|
545
|
+
});
|
|
546
|
+
auth.command("logout").description("Remove the active account, or all accounts with --all").option("--host <url>", HOST_OPTION_DESC).option("--all", "Remove all accounts stored for this host").action(async (opts) => {
|
|
547
|
+
const host = resolveAuthHost(program, opts);
|
|
548
|
+
if (!host) {
|
|
549
|
+
printError("config", "No AE host configured.", missingAeHostHint());
|
|
550
|
+
process.exit(1);
|
|
551
|
+
}
|
|
552
|
+
clearCliTokenCache(host);
|
|
553
|
+
if (opts.all) {
|
|
554
|
+
clearAllCredentials(host);
|
|
555
|
+
await printOutput({ cleared: true, all: true, host }, program.opts().format || "json");
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
const result = removeActiveCredential(host);
|
|
559
|
+
await printOutput({
|
|
560
|
+
cleared: !!result.removed,
|
|
561
|
+
all: false,
|
|
562
|
+
host,
|
|
563
|
+
remaining_accounts: listCredentials(host).length,
|
|
564
|
+
...result.active?.account ? { active_account: accountOutput(result.active.account) } : {}
|
|
565
|
+
}, program.opts().format || "json");
|
|
459
566
|
});
|
|
460
567
|
}
|
|
461
568
|
export {
|
|
462
569
|
activateHostAfterLogin,
|
|
570
|
+
buildAccountSelectionItems,
|
|
571
|
+
persistDeviceTokens,
|
|
463
572
|
registerAuth,
|
|
464
573
|
resolveLoginTeClaudeBase
|
|
465
574
|
};
|
|
@@ -3,36 +3,38 @@ import {
|
|
|
3
3
|
normalizeRiskLevel,
|
|
4
4
|
requiresConfirmation
|
|
5
5
|
} from "./chunk-AMBFK2K3.js";
|
|
6
|
+
import {
|
|
7
|
+
CapabilityGatewayError,
|
|
8
|
+
dryRunCapabilityWithEnvelope,
|
|
9
|
+
executeCapabilityWithEnvelope,
|
|
10
|
+
inspectCapability,
|
|
11
|
+
inspectCapabilityWithEnvelope,
|
|
12
|
+
listCapabilitiesWithEnvelope,
|
|
13
|
+
validateCapabilityWithEnvelope
|
|
14
|
+
} from "./chunk-QJQZH5GQ.js";
|
|
6
15
|
import {
|
|
7
16
|
findGatewayDomain,
|
|
8
17
|
listRegisteredCapabilityDomains,
|
|
9
18
|
resolveGatewayDomain
|
|
10
19
|
} from "./chunk-TKHSULJT.js";
|
|
11
20
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from "./chunk-KEWVSO64.js";
|
|
21
|
+
resolveHost
|
|
22
|
+
} from "./chunk-ECBLHAZO.js";
|
|
15
23
|
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
listCapabilities,
|
|
21
|
-
validateCapability
|
|
22
|
-
} from "./chunk-GJXRF7Y6.js";
|
|
24
|
+
printError,
|
|
25
|
+
printOutput,
|
|
26
|
+
withOutputMetadata
|
|
27
|
+
} from "./chunk-CZU3V3DQ.js";
|
|
23
28
|
import "./chunk-Y74WTIKJ.js";
|
|
24
|
-
import "./chunk-RWXIXOZG.js";
|
|
25
29
|
import {
|
|
26
|
-
SecureStoreAuthError
|
|
27
|
-
|
|
28
|
-
} from "./chunk-O6K2ODUE.js";
|
|
30
|
+
SecureStoreAuthError
|
|
31
|
+
} from "./chunk-ATSM5XAW.js";
|
|
29
32
|
import {
|
|
30
33
|
safeJsonParse
|
|
31
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-WZ6YVQSF.js";
|
|
32
35
|
import {
|
|
33
36
|
PermissionError
|
|
34
|
-
} from "./chunk-
|
|
35
|
-
import "./chunk-FR2EDAQM.js";
|
|
37
|
+
} from "./chunk-4P355ZWB.js";
|
|
36
38
|
|
|
37
39
|
// src/commands/capability/index.ts
|
|
38
40
|
import * as readline from "readline";
|
|
@@ -178,15 +180,16 @@ function registerCapability(program) {
|
|
|
178
180
|
await executeAndPrint(program, async (host) => {
|
|
179
181
|
const gatewayDomain = resolveCapabilityListDomain(opts.domain);
|
|
180
182
|
const projectId = parseOptionalProjectId(opts.projectId);
|
|
181
|
-
const
|
|
183
|
+
const envelope = await listCapabilitiesWithEnvelope(host, gatewayDomain, projectId);
|
|
184
|
+
const catalog = normalizeCapabilityList(envelope.data);
|
|
182
185
|
const capabilities = filterCapabilities(catalog, opts.domain);
|
|
183
186
|
const warning = emptyCapabilityCatalogWarning(catalog);
|
|
184
|
-
return {
|
|
187
|
+
return withOutputMetadata({
|
|
185
188
|
domain: opts.domain,
|
|
186
189
|
count: capabilities.length,
|
|
187
190
|
capabilities,
|
|
188
191
|
...warning ? { warning } : {}
|
|
189
|
-
};
|
|
192
|
+
}, envelope.meta);
|
|
190
193
|
});
|
|
191
194
|
}).addHelpText(
|
|
192
195
|
"after",
|
|
@@ -199,16 +202,17 @@ function registerCapability(program) {
|
|
|
199
202
|
await executeAndPrint(program, async (host) => {
|
|
200
203
|
const gatewayDomain = resolveCapabilityListDomain(opts.domain);
|
|
201
204
|
const projectId = parseOptionalProjectId(opts.projectId);
|
|
202
|
-
const
|
|
205
|
+
const envelope = await listCapabilitiesWithEnvelope(host, gatewayDomain, projectId);
|
|
206
|
+
const catalog = normalizeCapabilityList(envelope.data);
|
|
203
207
|
const capabilities = filterCapabilities(catalog, opts.domain, query);
|
|
204
208
|
const warning = emptyCapabilityCatalogWarning(catalog);
|
|
205
|
-
return {
|
|
209
|
+
return withOutputMetadata({
|
|
206
210
|
domain: opts.domain,
|
|
207
211
|
query,
|
|
208
212
|
count: capabilities.length,
|
|
209
213
|
capabilities,
|
|
210
214
|
...warning ? { warning } : {}
|
|
211
|
-
};
|
|
215
|
+
}, envelope.meta);
|
|
212
216
|
});
|
|
213
217
|
}).addHelpText(
|
|
214
218
|
"after",
|
|
@@ -217,7 +221,7 @@ function registerCapability(program) {
|
|
|
217
221
|
capability.command("inspect").description("Inspect one capability schema, risk, auth, and output metadata").argument("<capability-id>", "Capability ID, such as analysis.report.list").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--project-id <project-id>", "Check availability in a project before returning metadata").action(async (capabilityId, opts) => {
|
|
218
222
|
await executeAndPrint(program, async (host) => {
|
|
219
223
|
const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
|
|
220
|
-
return
|
|
224
|
+
return gatewayOutput(await inspectCapabilityWithEnvelope(host, gatewayDomain, capabilityId, parseOptionalProjectId(opts.projectId)), host);
|
|
221
225
|
});
|
|
222
226
|
}).addHelpText(
|
|
223
227
|
"after",
|
|
@@ -228,7 +232,7 @@ function registerCapability(program) {
|
|
|
228
232
|
).argument("<capability-id>", "Capability ID, such as metadata.data_table.sql_write").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--input <json-or-path>", "Input JSON object, file path, @<path>, or - for stdin").action(async (capabilityId, opts) => {
|
|
229
233
|
await executeAndPrint(program, async (host) => {
|
|
230
234
|
const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
|
|
231
|
-
return
|
|
235
|
+
return gatewayOutput(await validateCapabilityWithEnvelope(host, gatewayDomain, capabilityId, parseCapabilityInput(opts.input)), host);
|
|
232
236
|
});
|
|
233
237
|
}).addHelpText(
|
|
234
238
|
"after",
|
|
@@ -250,7 +254,7 @@ Examples:
|
|
|
250
254
|
).argument("<capability-id>", "Capability ID, such as analysis.query.export").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--input <json-or-path>", "Input JSON object, file path, @<path>, or - for stdin").action(async (capabilityId, opts) => {
|
|
251
255
|
await executeAndPrint(program, async (host) => {
|
|
252
256
|
const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
|
|
253
|
-
return
|
|
257
|
+
return gatewayOutput(await dryRunCapabilityWithEnvelope(host, gatewayDomain, capabilityId, parseCapabilityInput(opts.input)), host);
|
|
254
258
|
});
|
|
255
259
|
}).addHelpText(
|
|
256
260
|
"after",
|
|
@@ -270,10 +274,10 @@ Examples:
|
|
|
270
274
|
);
|
|
271
275
|
}
|
|
272
276
|
if (globalOpts.validate) {
|
|
273
|
-
return
|
|
277
|
+
return gatewayOutput(await validateCapabilityWithEnvelope(host, gatewayDomain, capabilityId, input), host);
|
|
274
278
|
}
|
|
275
279
|
if (globalOpts.dryRun) {
|
|
276
|
-
return
|
|
280
|
+
return gatewayOutput(await dryRunCapabilityWithEnvelope(host, gatewayDomain, capabilityId, input), host);
|
|
277
281
|
}
|
|
278
282
|
if (!globalOpts.yes) {
|
|
279
283
|
const metadata = await inspectCapability(host, gatewayDomain, capabilityId);
|
|
@@ -286,7 +290,7 @@ Examples:
|
|
|
286
290
|
}
|
|
287
291
|
}
|
|
288
292
|
}
|
|
289
|
-
return
|
|
293
|
+
return gatewayOutput(await executeCapabilityWithEnvelope(host, gatewayDomain, capabilityId, input), host);
|
|
290
294
|
});
|
|
291
295
|
}).addHelpText(
|
|
292
296
|
"after",
|
|
@@ -296,6 +300,15 @@ Examples:
|
|
|
296
300
|
ae-cli capability run analysis.dashboard.list --input input.json`
|
|
297
301
|
);
|
|
298
302
|
}
|
|
303
|
+
function gatewayOutput(envelope, host) {
|
|
304
|
+
return withOutputMetadata(withPageUrl(envelope.data, host), envelope.meta);
|
|
305
|
+
}
|
|
306
|
+
function withPageUrl(value, host) {
|
|
307
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
308
|
+
const record = value;
|
|
309
|
+
if (typeof record.page_path !== "string" || !/^\/(?![\\/])/.test(record.page_path) || record.page_url !== void 0) return value;
|
|
310
|
+
return { ...record, page_url: new URL(record.page_path, host).toString() };
|
|
311
|
+
}
|
|
299
312
|
async function executeAndPrint(program, action) {
|
|
300
313
|
const globalOpts = program.opts();
|
|
301
314
|
const host = resolveHost(globalOpts.host);
|
|
@@ -315,11 +328,11 @@ async function executeAndPrint(program, action) {
|
|
|
315
328
|
process.exitCode = 1;
|
|
316
329
|
return;
|
|
317
330
|
}
|
|
318
|
-
printCapabilityError(error);
|
|
331
|
+
printCapabilityError(error, host);
|
|
319
332
|
process.exitCode = 1;
|
|
320
333
|
}
|
|
321
334
|
}
|
|
322
|
-
function printCapabilityError(error) {
|
|
335
|
+
function printCapabilityError(error, host) {
|
|
323
336
|
if (error instanceof CapabilityCommandValidationError) {
|
|
324
337
|
printError("validation", error.message, error.hint, error.code);
|
|
325
338
|
return;
|
|
@@ -333,7 +346,7 @@ function printCapabilityError(error) {
|
|
|
333
346
|
return;
|
|
334
347
|
}
|
|
335
348
|
if (error instanceof CapabilityGatewayError) {
|
|
336
|
-
printError("api", error.message, error.hint, error.code);
|
|
349
|
+
printError("api", error.message, error.hint, error.code, withPageUrl(error.meta, host));
|
|
337
350
|
return;
|
|
338
351
|
}
|
|
339
352
|
const message = error instanceof Error ? error.message : String(error);
|