@thinkingai/ae-cli 6.0.20 → 6.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +1 -4
  2. package/README.zh.md +1 -4
  3. package/dist/{auth-GHBMJ5ZR.js → auth-A2XXG5K4.js} +34 -110
  4. package/dist/auth-IDPKDFSY.js +13 -0
  5. package/dist/chunk-2OW2RENH.js +193 -0
  6. package/dist/{chunk-I5CRVM2S.js → chunk-4FQ36OGO.js} +44 -17
  7. package/dist/{chunk-6W4QOZAL.js → chunk-65DKFJZB.js} +26 -16
  8. package/dist/chunk-AKORWVHJ.js +59 -0
  9. package/dist/{chunk-BJX3GXWC.js → chunk-F3ZDMC2W.js} +8 -8
  10. package/dist/chunk-FIT4CFIN.js +59 -0
  11. package/dist/{chunk-5OC7CYCG.js → chunk-IDXW6MEJ.js} +14 -14
  12. package/dist/{chunk-DMMEPCST.js → chunk-NGJDCOYA.js} +25 -115
  13. package/dist/chunk-NXJP4CES.js +209 -0
  14. package/dist/chunk-OCQPQYHZ.js +105 -0
  15. package/dist/{chunk-2DUEAXV3.js → chunk-ONOA6DYB.js} +1 -1
  16. package/dist/{chunk-RSHMZ3LG.js → chunk-PFJFZVCK.js} +13 -134
  17. package/dist/chunk-V5R5UIRM.js +195 -0
  18. package/dist/{chunk-PN3OS34E.js → chunk-WXBCP6SD.js} +1 -1
  19. package/dist/cli-token-OZXHC3U2.js +14 -0
  20. package/dist/{client-2UJ63MVQ.js → client-7L735LVY.js} +3 -3
  21. package/dist/{config-NCUGK6NS.js → config-SXD2JKSL.js} +3 -3
  22. package/dist/index.js +312 -197
  23. package/dist/metadata-QWUAX625.js +411 -0
  24. package/dist/metadata-XWTEGEN2.js +411 -0
  25. package/dist/{model-SJSOZTRS.js → model-3OVX42DA.js} +2 -2
  26. package/dist/{raw-7NVWSVJP.js → raw-IANB4AV5.js} +4 -4
  27. package/dist/{sync-GRVO4K3U.js → sync-4HQ3CXSK.js} +3 -3
  28. package/dist/{te-agent-CYZUC4US.js → te-agent-OYNNTJDU.js} +2 -2
  29. package/dist/{te-analysis-HJ22TUAA.js → te-analysis-CRPFK3LX.js} +1114 -358
  30. package/dist/te-analysis-JX3V76OI.js +2281 -0
  31. package/dist/{te-audience-MYDE5WEH.js → te-audience-77FGNG5E.js} +27 -18
  32. package/dist/te-audience-RO2IZOUC.js +599 -0
  33. package/dist/{te-common-WNCZB7R7.js → te-common-4TRJPRC5.js} +5 -4
  34. package/dist/te-common-PUXBUPOL.js +130 -0
  35. package/dist/{te-community-JEEFXPB3.js → te-community-NPDZQKMY.js} +5 -4
  36. package/dist/te-community-XKE526DS.js +687 -0
  37. package/dist/te-dataops-6KWLFNV4.js +1841 -0
  38. package/dist/{te-dataops-ZTS7XMXM.js → te-dataops-PW74WP76.js} +5 -5
  39. package/dist/{te-engage-4XHCTS6I.js → te-engage-HTLMUN7G.js} +5 -4
  40. package/dist/te-engage-YPQIVF5H.js +1510 -0
  41. package/dist/{te-kb-OWM3RQRH.js → te-kb-DOGDQIU4.js} +4 -5
  42. package/dist/{te-meta-JVO4QJBH.js → te-meta-5ESSQ5B3.js} +26 -19
  43. package/dist/te-meta-Z47X4VT3.js +595 -0
  44. package/dist/{te-team-YY24VORI.js → te-team-SOVKZIDD.js} +5 -6
  45. package/package.json +3 -2
  46. package/skills/ae-analysis/SKILL.md +60 -27
  47. package/skills/ae-analysis/references/analysis_gateway_assets.md +114 -0
  48. package/skills/ae-analysis/references/bi_panel_copy.md +15 -0
  49. package/skills/ae-analysis/references/bi_panel_create.md +15 -0
  50. package/skills/ae-analysis/references/bi_panel_delete.md +15 -0
  51. package/skills/ae-analysis/references/bi_panel_get.md +18 -0
  52. package/skills/ae-analysis/references/bi_panel_list.md +15 -0
  53. package/skills/ae-analysis/references/bi_panel_page_data_export.md +15 -0
  54. package/skills/ae-analysis/references/bi_panel_page_data_run.md +15 -0
  55. package/skills/ae-analysis/references/bi_panel_share.md +15 -0
  56. package/skills/ae-analysis/references/bi_panel_update.md +15 -0
  57. package/skills/ae-analysis/references/build_attribution_analysis_qp.md +2 -0
  58. package/skills/ae-analysis/references/build_cluster_definition.md +2 -0
  59. package/skills/ae-analysis/references/build_distribution_analysis_qp.md +2 -0
  60. package/skills/ae-analysis/references/build_event_analysis_qp.md +2 -0
  61. package/skills/ae-analysis/references/build_funnel_analysis_qp.md +2 -0
  62. package/skills/ae-analysis/references/build_heat_map_analysis_qp.md +2 -0
  63. package/skills/ae-analysis/references/build_interval_analysis_qp.md +2 -0
  64. package/skills/ae-analysis/references/build_path_analysis_qp.md +2 -0
  65. package/skills/ae-analysis/references/build_prop_analysis_qp.md +2 -0
  66. package/skills/ae-analysis/references/build_rank_list_analysis_qp.md +2 -0
  67. package/skills/ae-analysis/references/build_retention_analysis_qp.md +2 -0
  68. package/skills/ae-analysis/references/build_tag_definition.md +2 -0
  69. package/skills/ae-analysis/references/dashboard_abnormal_get.md +15 -0
  70. package/skills/ae-analysis/references/dashboard_copy.md +15 -0
  71. package/skills/ae-analysis/references/dashboard_create.md +15 -0
  72. package/skills/ae-analysis/references/dashboard_daily_report_send.md +15 -0
  73. package/skills/ae-analysis/references/dashboard_daily_report_update.md +15 -0
  74. package/skills/ae-analysis/references/dashboard_definition_export.md +15 -0
  75. package/skills/ae-analysis/references/dashboard_definition_import.md +15 -0
  76. package/skills/ae-analysis/references/dashboard_delete.md +15 -0
  77. package/skills/ae-analysis/references/dashboard_freeze.md +15 -0
  78. package/skills/ae-analysis/references/dashboard_get.md +15 -0
  79. package/skills/ae-analysis/references/dashboard_handover.md +15 -0
  80. package/skills/ae-analysis/references/dashboard_list.md +15 -0
  81. package/skills/ae-analysis/references/dashboard_report_data_export.md +15 -0
  82. package/skills/ae-analysis/references/dashboard_report_data_run.md +15 -0
  83. package/skills/ae-analysis/references/dashboard_share.md +15 -0
  84. package/skills/ae-analysis/references/dashboard_share_info.md +15 -0
  85. package/skills/ae-analysis/references/dashboard_task_status.md +15 -0
  86. package/skills/ae-analysis/references/dashboard_update.md +16 -0
  87. package/skills/ae-analysis/references/favorite_add.md +15 -0
  88. package/skills/ae-analysis/references/favorite_remove.md +15 -0
  89. package/skills/ae-analysis/references/folder_create.md +15 -0
  90. package/skills/ae-analysis/references/folder_delete.md +15 -0
  91. package/skills/ae-analysis/references/folder_members.md +15 -0
  92. package/skills/ae-analysis/references/folder_share.md +15 -0
  93. package/skills/ae-analysis/references/list_clusters.md +3 -1
  94. package/skills/ae-analysis/references/list_events.md +5 -2
  95. package/skills/ae-analysis/references/list_metrics.md +4 -2
  96. package/skills/ae-analysis/references/list_properties.md +4 -2
  97. package/skills/ae-analysis/references/list_tags.md +3 -1
  98. package/skills/ae-analysis/references/project_space_create.md +15 -0
  99. package/skills/ae-analysis/references/project_space_delete.md +15 -0
  100. package/skills/ae-analysis/references/project_space_get.md +18 -0
  101. package/skills/ae-analysis/references/project_space_list.md +15 -0
  102. package/skills/ae-analysis/references/project_space_members.md +15 -0
  103. package/skills/ae-analysis/references/project_space_share.md +15 -0
  104. package/skills/ae-analysis/references/public_link_create.md +15 -0
  105. package/skills/ae-analysis/references/public_link_delete.md +15 -0
  106. package/skills/ae-analysis/references/public_link_list.md +15 -0
  107. package/skills/ae-analysis/references/public_link_offline.md +15 -0
  108. package/skills/ae-analysis/references/public_link_update.md +15 -0
  109. package/skills/ae-analysis/references/query_cancel.md +15 -0
  110. package/skills/ae-generate-tracking-code/SKILL.md +68 -31
  111. package/skills/ae-generate-tracking-code/references/snippet-delivery.md +26 -1
  112. package/skills/ae-generate-tracking-code/references/te-api.md +47 -164
  113. package/skills/ae-generate-tracking-plan/SKILL.md +109 -32
  114. package/skills/ae-generate-tracking-plan/references/te-api.md +57 -27
  115. package/skills/ae-metadata/SKILL.md +90 -0
  116. package/skills/ae-metadata/references/metadata_data_table_csv_delete.md +15 -0
  117. package/skills/ae-metadata/references/metadata_data_table_csv_write.md +31 -0
  118. package/skills/ae-metadata/references/metadata_data_table_download.md +17 -0
  119. package/skills/ae-metadata/references/metadata_data_table_get.md +24 -0
  120. package/skills/ae-metadata/references/metadata_data_table_list.md +27 -0
  121. package/skills/ae-metadata/references/metadata_data_table_property_bindings_update.md +17 -0
  122. package/skills/ae-metadata/references/metadata_data_table_sql_delete.md +15 -0
  123. package/skills/ae-metadata/references/metadata_data_table_sql_write.md +32 -0
  124. package/skills/ae-metadata/references/metadata_event_get.md +52 -0
  125. package/skills/ae-metadata/references/metadata_input_file_upload.md +29 -0
  126. package/skills/ae-metadata/references/metadata_property_dimension_table_bind_existing.md +27 -0
  127. package/skills/ae-metadata/references/metadata_property_dimension_table_create_and_bind_csv.md +32 -0
  128. package/skills/ae-metadata/references/metadata_property_get.md +54 -0
  129. package/dist/auth-DYC2BGLM.js +0 -21
package/README.md CHANGED
@@ -67,12 +67,9 @@ ae-cli kb +read --source '{"scope":"company","name":"engineering-handbook"}' \
67
67
  Authentication is handled per-host. Each AE host URL maintains its own token.
68
68
 
69
69
  ```bash
70
- # Auto-login for active host (macOS, extracts token from Chrome)
70
+ # Device code login (cross-platform)
71
71
  ae-cli auth login
72
72
 
73
- # Manually set token
74
- ae-cli auth set-token <your-token>
75
-
76
73
  # Check status
77
74
  ae-cli auth status
78
75
 
package/README.zh.md CHANGED
@@ -67,12 +67,9 @@ ae-cli kb +read --source '{"scope":"company","name":"engineering-handbook"}' \
67
67
  每个 AE 主机 URL 维护独立的身份验证 token。
68
68
 
69
69
  ```bash
70
- # 自动登录当前主机(macOS,从 Chrome 提取 token)
70
+ # 设备码登录(跨平台)
71
71
  ae-cli auth login
72
72
 
73
- # 手动设置 token
74
- ae-cli auth set-token <your-token>
75
-
76
73
  # 检查状态
77
74
  ae-cli auth status
78
75
 
@@ -1,30 +1,24 @@
1
1
  import {
2
2
  printError,
3
3
  printOutput
4
- } from "./chunk-2DUEAXV3.js";
4
+ } from "./chunk-ONOA6DYB.js";
5
5
  import {
6
- clearMcpToken,
7
- setMcpTokenManual,
8
- validateMcpToken
9
- } from "./chunk-DMMEPCST.js";
10
- import "./chunk-PN3OS34E.js";
11
- import "./chunk-NOO24N7W.js";
6
+ clearCliToken,
7
+ mintCliToken
8
+ } from "./chunk-OCQPQYHZ.js";
12
9
  import {
13
10
  clear,
14
- clearToken,
15
- getAuthStatus,
16
11
  load,
17
12
  resolveHost,
18
- save,
19
- setTokenManual,
20
- validateToken
21
- } from "./chunk-RSHMZ3LG.js";
13
+ save
14
+ } from "./chunk-PFJFZVCK.js";
22
15
  import {
16
+ getFallbackCliToken,
23
17
  loadConfig,
24
18
  logger,
25
19
  removeHost,
26
20
  saveConfig
27
- } from "./chunk-6W4QOZAL.js";
21
+ } from "./chunk-65DKFJZB.js";
28
22
 
29
23
  // src/core/device-auth.ts
30
24
  import { execFileSync } from "child_process";
@@ -246,7 +240,7 @@ function activateHostAfterLogin(host, explicitHostOverride) {
246
240
  saveConfig(config);
247
241
  logger.info(`Active host set to ${host} after login`);
248
242
  }
249
- function persistDeviceTokens(host, tokens) {
243
+ async function persistDeviceTokens(host, tokens) {
250
244
  const DEFAULT_EXPIRES_IN = 72e3;
251
245
  const MAX_EXPIRES_IN = 86400 * 365;
252
246
  let expiresInSeconds = tokens.expires_in ?? DEFAULT_EXPIRES_IN;
@@ -258,16 +252,15 @@ function persistDeviceTokens(host, tokens) {
258
252
  save(host, {
259
253
  accessToken: tokens.access_token,
260
254
  refreshToken: tokens.refresh_token ?? "",
261
- accessExpiresAt: expiresAt,
262
- mcpToken: tokens.mcp_token ?? void 0
255
+ accessExpiresAt: expiresAt
263
256
  });
257
+ await mintCliToken(host);
264
258
  }
265
259
  function loginSummary(host, tokens) {
266
260
  return {
267
261
  authenticated: true,
268
262
  host,
269
- token: tokens.access_token.slice(0, 8) + "...",
270
- mcpToken: tokens.mcp_token ? tokens.mcp_token.slice(0, 8) + "..." : null
263
+ token: tokens.access_token.slice(0, 8) + "..."
271
264
  };
272
265
  }
273
266
  function resolveLoginTeClaudeBase(host) {
@@ -303,7 +296,7 @@ function registerAuth(program) {
303
296
  try {
304
297
  if (opts.deviceCode) {
305
298
  const tokens2 = await pollDeviceFlow(teClaudeBase, opts.deviceCode, {}, emit);
306
- persistDeviceTokens(host, tokens2);
299
+ await persistDeviceTokens(host, tokens2);
307
300
  activateHostAfterLogin(host, explicitHost);
308
301
  logger.info(`Device flow login successful for ${host} (resumed)`);
309
302
  emit("Login successful! Token saved securely.");
@@ -326,7 +319,7 @@ function registerAuth(program) {
326
319
  return;
327
320
  }
328
321
  const tokens = await runDeviceFlow(teClaudeBase, { noBrowser }, emit);
329
- persistDeviceTokens(host, tokens);
322
+ await persistDeviceTokens(host, tokens);
330
323
  activateHostAfterLogin(host, explicitHost);
331
324
  logger.info(`Device flow login successful for ${host}`);
332
325
  emit("Login successful! Token saved securely.");
@@ -336,7 +329,7 @@ function registerAuth(program) {
336
329
  printError(
337
330
  "auth",
338
331
  err.message,
339
- "Use `ae-cli auth set-token <token>` to authenticate, or upgrade the AE server to a version that supports device login."
332
+ "Upgrade the AE server to a version that supports device login."
340
333
  );
341
334
  process.exit(1);
342
335
  }
@@ -344,39 +337,6 @@ function registerAuth(program) {
344
337
  process.exit(1);
345
338
  }
346
339
  });
347
- auth.command("set-token <token>").description("Manually set authentication token for a host (--host or active host)").option("--host <url>", HOST_OPTION_DESC).action(async (token, opts) => {
348
- const host = resolveAuthHost(program, opts);
349
- if (!host) {
350
- printError("config", "No AE host configured.", "Run: ae-cli config set-host <url>");
351
- process.exit(1);
352
- }
353
- const config = loadConfig();
354
- if (!config.hosts[host]) {
355
- config.hosts[host] = { label: host };
356
- if (!config.activeHost) {
357
- config.activeHost = host;
358
- }
359
- saveConfig(config);
360
- process.stderr.write(`[ae-cli] Config saved for ${host}
361
- `);
362
- printOutput({ saved: true, config }, program.opts().format || "json");
363
- }
364
- process.stderr.write(`[ae-cli] Validating token...
365
- `);
366
- const isValid = await validateToken(token, host);
367
- if (!isValid) {
368
- logger.warn(`Token validation failed for ${host}`);
369
- process.stderr.write(`[ae-cli] Token validation failed
370
- `);
371
- printError("auth", "Invalid token", "Please check your token and try again");
372
- process.exit(1);
373
- }
374
- setTokenManual(token, host);
375
- logger.info(`Token manually set and validated for ${host}`);
376
- process.stderr.write(`[ae-cli] Token verified and saved for ${host}
377
- `);
378
- printOutput({ saved: true, host, verified: true }, program.opts().format || "json");
379
- });
380
340
  auth.command("status").description("Show authentication status for a host (--host or active host)").option("--host <url>", HOST_OPTION_DESC).action(async (opts) => {
381
341
  const host = resolveAuthHost(program, opts);
382
342
  if (!host) {
@@ -394,74 +354,38 @@ function registerAuth(program) {
394
354
  accessExpiresAt: secureEntry.accessExpiresAt,
395
355
  accessExpiresAtNote: "advisory: access token auto-slides on use server-side; re-login only if a command returns an auth error",
396
356
  pastStaticExpiry,
397
- hasMcpToken: !!secureEntry.mcpToken
357
+ hasCliToken: !!secureEntry.cliToken
358
+ },
359
+ program.opts().format || "json"
360
+ );
361
+ return;
362
+ }
363
+ const fallbackCliToken = getFallbackCliToken(host);
364
+ if (fallbackCliToken) {
365
+ printOutput(
366
+ {
367
+ authenticated: true,
368
+ host,
369
+ source: "sandbox-cli-token",
370
+ hasCliToken: true,
371
+ note: "sandbox-provisioned cli-token.json; no user access token in secure-store"
398
372
  },
399
373
  program.opts().format || "json"
400
374
  );
401
375
  return;
402
376
  }
403
- const tokenStatus = getAuthStatus(host);
404
- const authenticated = tokenStatus.authenticated;
405
- printOutput({ authenticated, host, source: tokenStatus.source ?? "none" }, program.opts().format || "json");
377
+ printOutput({ authenticated: false, host, source: "none" }, program.opts().format || "json");
406
378
  });
407
- auth.command("logout").description("Clear stored token for a host (--host or active host)").option("--host <url>", HOST_OPTION_DESC).action((opts) => {
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) => {
408
380
  const host = resolveAuthHost(program, opts);
409
381
  if (!host) {
410
382
  printError("config", "No AE host configured.", "Run: ae-cli config set-host <url>");
411
383
  process.exit(1);
412
384
  }
413
- clearToken(host);
385
+ clearCliToken(host);
414
386
  clear(host);
415
387
  removeHost(host);
416
- process.stderr.write(`[ae-cli] Token and config cleared for ${host}
417
- `);
418
- printOutput({ cleared: true, host }, program.opts().format || "json");
419
- });
420
- auth.command("set-mcp-token <token>").description("Manually set MCP token for a host (--host or active host)").option("--host <url>", HOST_OPTION_DESC).action(async (token, opts) => {
421
- const host = resolveAuthHost(program, opts);
422
- if (!host) {
423
- printError("config", "No AE host configured.", "Use --host <url> or run: ae-cli config set-host <url>");
424
- process.exit(1);
425
- }
426
- const config = loadConfig();
427
- if (!config.hosts[host]) {
428
- config.hosts[host] = { label: host };
429
- if (!config.activeHost) {
430
- config.activeHost = host;
431
- }
432
- saveConfig(config);
433
- process.stderr.write(`[ae-cli] Host config saved for ${host}
434
- `);
435
- }
436
- process.stderr.write(`[ae-cli] Validating MCP token...
437
- `);
438
- const isValid = await validateMcpToken(token, host);
439
- if (!isValid) {
440
- process.stderr.write(`[ae-cli] MCP token validation failed
441
- `);
442
- printError("auth", "Invalid MCP token", "Please check your MCP token and try again");
443
- process.exit(1);
444
- }
445
- setMcpTokenManual(token, host);
446
- process.stderr.write(`[ae-cli] MCP token verified and saved for ${host}
447
- `);
448
- printOutput({ saved: true, host, verified: true, type: "mcp-token" }, program.opts().format || "json");
449
- });
450
- auth.command("clear-mcp-token").description("Clear stored MCP token for a host (--host or active host; --all clears all)").option("--host <url>", HOST_OPTION_DESC).option("--all", "Clear MCP tokens for all hosts").action((opts) => {
451
- if (opts.all) {
452
- clearMcpToken();
453
- process.stderr.write(`[ae-cli] All MCP tokens cleared
454
- `);
455
- printOutput({ cleared: true, type: "all-mcp-tokens" }, program.opts().format || "json");
456
- return;
457
- }
458
- const host = resolveAuthHost(program, opts);
459
- if (!host) {
460
- printError("config", "No AE host configured.", "Use --host <url> or run: ae-cli config set-host <url>");
461
- process.exit(1);
462
- }
463
- clearMcpToken(host);
464
- process.stderr.write(`[ae-cli] MCP token cleared for ${host}
388
+ process.stderr.write(`[ae-cli] Credentials and config cleared for ${host}
465
389
  `);
466
390
  printOutput({ cleared: true, host }, program.opts().format || "json");
467
391
  });
@@ -0,0 +1,13 @@
1
+ import {
2
+ getToken,
3
+ invalidateAccessTokenForRetry,
4
+ resolveHost,
5
+ validateToken
6
+ } from "./chunk-PFJFZVCK.js";
7
+ import "./chunk-65DKFJZB.js";
8
+ export {
9
+ getToken,
10
+ invalidateAccessTokenForRetry,
11
+ resolveHost,
12
+ validateToken
13
+ };
@@ -0,0 +1,193 @@
1
+ import {
2
+ PermissionError
3
+ } from "./chunk-NOO24N7W.js";
4
+ import {
5
+ clearCliToken,
6
+ getCliToken
7
+ } from "./chunk-OCQPQYHZ.js";
8
+ import {
9
+ logger,
10
+ safeJsonParse
11
+ } from "./chunk-65DKFJZB.js";
12
+
13
+ // src/core/capability-api.ts
14
+ import { readFile } from "fs/promises";
15
+ import { basename } from "path";
16
+ var CapabilityGatewayError = class extends Error {
17
+ constructor(message, code, httpStatus, hint) {
18
+ super(message);
19
+ this.code = code;
20
+ this.httpStatus = httpStatus;
21
+ this.hint = hint;
22
+ this.name = "CapabilityGatewayError";
23
+ }
24
+ code;
25
+ httpStatus;
26
+ hint;
27
+ };
28
+ function buildCapabilityGatewayUrl(host, domain, pathAfterV1, queryParams = {}) {
29
+ const base = host.replace(/\/+$/, "");
30
+ const cleanDomain = domain.replace(/^\/+|\/+$/g, "");
31
+ const cleanPath = pathAfterV1.replace(/^\/+|\/+$/g, "");
32
+ const gatewayPrefix = cleanDomain === "" ? "/api/cli/v1" : `/api/cli/${cleanDomain}/v1`;
33
+ const url = new URL(`${base}${gatewayPrefix}/${cleanPath}`);
34
+ for (const [key, value] of Object.entries(queryParams)) {
35
+ if (value !== void 0 && value !== null) {
36
+ url.searchParams.set(key, String(value));
37
+ }
38
+ }
39
+ return url.toString();
40
+ }
41
+ async function permissionMessage(resp) {
42
+ const text = await resp.text().catch(() => "");
43
+ try {
44
+ const d = safeJsonParse(text);
45
+ const msg = d && (d.error?.message || (typeof d.error === "string" ? d.error : void 0) || d.message);
46
+ if (msg && typeof msg === "string") return msg;
47
+ } catch {
48
+ }
49
+ return "Permission denied for this resource (HTTP 403)";
50
+ }
51
+ function parseCapabilityResponse(text) {
52
+ if (!text) return void 0;
53
+ try {
54
+ return safeJsonParse(text);
55
+ } catch {
56
+ return text;
57
+ }
58
+ }
59
+ function unwrapCapabilityEnvelope(body) {
60
+ if (body == null) {
61
+ throw new CapabilityGatewayError("Empty capability gateway response");
62
+ }
63
+ if (typeof body.ok === "boolean") {
64
+ if (body.ok) {
65
+ return body.data;
66
+ }
67
+ const err = body.error ?? {};
68
+ const code = nonEmptyString(err.code);
69
+ const message = nonEmptyString(err.message) ?? code ?? "Capability gateway request failed";
70
+ const hint = nonEmptyString(err.hint);
71
+ throw new CapabilityGatewayError(message, code, err.http_status ?? err.httpStatus, hint);
72
+ }
73
+ return body;
74
+ }
75
+ function nonEmptyString(value) {
76
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
77
+ }
78
+ function buildCapabilityHttpError(resp, body) {
79
+ const fallback = `Capability gateway HTTP error: ${resp.status} ${resp.statusText}`.trim();
80
+ if (body && typeof body === "object") {
81
+ const err = body.error ?? body.data?.error ?? body;
82
+ const code = nonEmptyString(err.code) ?? nonEmptyString(err.errorCode) ?? nonEmptyString(body.code);
83
+ const message = nonEmptyString(err.message) ?? nonEmptyString(body.message);
84
+ const hint = nonEmptyString(err.hint) ?? nonEmptyString(body.hint);
85
+ const details = [code, message, hint ? `Hint: ${hint}` : void 0].filter(Boolean);
86
+ if (details.length > 0) {
87
+ return new CapabilityGatewayError(message ?? fallback, code, resp.status, hint);
88
+ }
89
+ }
90
+ if (typeof body === "string" && body.trim()) {
91
+ return new CapabilityGatewayError(`${fallback}: ${body.slice(0, 500)}`, void 0, resp.status);
92
+ }
93
+ return new CapabilityGatewayError(fallback, void 0, resp.status);
94
+ }
95
+ async function throwCapabilityHttpError(resp) {
96
+ const body = parseCapabilityResponse(await resp.text());
97
+ throw buildCapabilityHttpError(resp, body);
98
+ }
99
+ async function requestOnce(url, method, token, body) {
100
+ const headers = {
101
+ "cli-token": token,
102
+ "Accept": "application/json"
103
+ };
104
+ const init = { method, headers };
105
+ if (body !== void 0 && method !== "GET") {
106
+ headers["Content-Type"] = "application/json";
107
+ init.body = JSON.stringify(body);
108
+ }
109
+ return fetch(url, init);
110
+ }
111
+ async function requestMultipartOnce(url, token, form) {
112
+ return fetch(url, {
113
+ method: "POST",
114
+ headers: {
115
+ "cli-token": token,
116
+ "Accept": "application/json"
117
+ },
118
+ body: form
119
+ });
120
+ }
121
+ async function callGateway(host, domain, pathAfterV1, method, body) {
122
+ const url = buildCapabilityGatewayUrl(host, domain, pathAfterV1);
123
+ const token = await getCliToken(host);
124
+ let resp = await requestOnce(url, method, token, body);
125
+ if (resp.status === 403) {
126
+ throw new PermissionError(await permissionMessage(resp));
127
+ }
128
+ if (resp.status === 401) {
129
+ logger.warn(`Capability gateway request failed (HTTP 401) for ${host}, refreshing CLI token`);
130
+ clearCliToken(host);
131
+ const newToken = await getCliToken(host);
132
+ process.stderr.write(`[ae-cli] CLI token refreshed for ${host}
133
+ `);
134
+ resp = await requestOnce(url, method, newToken, body);
135
+ if (resp.status === 403) {
136
+ throw new PermissionError(await permissionMessage(resp));
137
+ }
138
+ if (!resp.ok) {
139
+ await throwCapabilityHttpError(resp);
140
+ }
141
+ } else if (!resp.ok) {
142
+ await throwCapabilityHttpError(resp);
143
+ }
144
+ return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
145
+ }
146
+ async function executeCapability(host, domain, capabilityId, input = {}) {
147
+ return callGateway(host, domain, `capabilities/${capabilityId}/execute`, "POST", { input });
148
+ }
149
+ async function uploadInputFile(host, domain, projectId, purpose, filePath) {
150
+ const fileBytes = await readFile(filePath);
151
+ return uploadInputFileBytes(host, domain, projectId, purpose, fileBytes, basename(filePath));
152
+ }
153
+ async function uploadInputFileBytes(host, domain, projectId, purpose, bytes, filename, contentType = "application/octet-stream") {
154
+ const url = buildCapabilityGatewayUrl(host, domain, "input-files");
155
+ const fileBuffer = bytes instanceof ArrayBuffer ? bytes : bytes.buffer.slice(
156
+ bytes.byteOffset,
157
+ bytes.byteOffset + bytes.byteLength
158
+ );
159
+ const form = new FormData();
160
+ form.append("project_id", String(projectId));
161
+ form.append("purpose", purpose);
162
+ form.append("file", new Blob([fileBuffer], { type: contentType }), filename);
163
+ const token = await getCliToken(host);
164
+ let resp = await requestMultipartOnce(url, token, form);
165
+ if (resp.status === 403) {
166
+ throw new PermissionError(await permissionMessage(resp));
167
+ }
168
+ if (resp.status === 401) {
169
+ logger.warn(`Capability gateway request failed (HTTP 401) for ${host}, refreshing CLI token`);
170
+ clearCliToken(host);
171
+ const newToken = await getCliToken(host);
172
+ process.stderr.write(`[ae-cli] CLI token refreshed for ${host}
173
+ `);
174
+ resp = await requestMultipartOnce(url, newToken, form);
175
+ if (resp.status === 403) {
176
+ throw new PermissionError(await permissionMessage(resp));
177
+ }
178
+ if (!resp.ok) {
179
+ await throwCapabilityHttpError(resp);
180
+ }
181
+ } else if (!resp.ok) {
182
+ await throwCapabilityHttpError(resp);
183
+ }
184
+ return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
185
+ }
186
+
187
+ export {
188
+ CapabilityGatewayError,
189
+ buildCapabilityGatewayUrl,
190
+ executeCapability,
191
+ uploadInputFile,
192
+ uploadInputFileBytes
193
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getActiveHost,
3
3
  getSandboxRuntimeRoot
4
- } from "./chunk-6W4QOZAL.js";
4
+ } from "./chunk-65DKFJZB.js";
5
5
 
6
6
  // src/core/te-agent-credentials.ts
7
7
  import { readFileSync } from "fs";
@@ -134,39 +134,66 @@ function teClaudeBaseFromActiveHost() {
134
134
  async function signRequest(method, path, rawBody) {
135
135
  const sandboxCred = tryLoadTeAgentSandboxCredentials();
136
136
  if (sandboxCred && sandboxCred.sandboxId && sandboxCred.sandboxSecretKey) {
137
- const headers2 = {
137
+ const headers = {
138
138
  "X-Sandbox-Id": sandboxCred.sandboxId,
139
139
  "X-Sandbox-Secret-Key": sandboxCred.sandboxSecretKey
140
140
  };
141
141
  if (method === "POST" || method === "PATCH") {
142
- headers2["Content-Type"] = "application/json";
142
+ headers["Content-Type"] = "application/json";
143
143
  }
144
144
  return {
145
145
  url: `${sandboxCred.url.replace(/\/$/, "")}${path}`,
146
- headers: headers2,
146
+ headers,
147
147
  rawBody
148
148
  };
149
149
  }
150
- const { getToken } = await import("./auth-DYC2BGLM.js");
150
+ const { getToken } = await import("./auth-IDPKDFSY.js");
151
+ const { getCliToken } = await import("./cli-token-OZXHC3U2.js");
151
152
  const baseUrl = sandboxCred?.url || teClaudeBaseFromActiveHost();
153
+ const hostForToken = getActiveHost() || baseUrl;
152
154
  if (!baseUrl) {
153
155
  throw new TeAgentCredentialsError(
154
156
  "Cannot determine the te-claude service URL",
155
157
  "Run ae-cli config set-host <url> to configure the service URL, or execute inside a te-agent sandbox"
156
158
  );
157
159
  }
158
- const accessToken = await getToken(getActiveHost() || baseUrl);
159
- const headers = {
160
- "Authorization": `bearer ${accessToken}`
161
- };
162
- if (method === "POST" || method === "PATCH") {
163
- headers["Content-Type"] = "application/json";
160
+ const contentTypeHeader = method === "POST" || method === "PATCH" ? { "Content-Type": "application/json" } : {};
161
+ let accessToken = null;
162
+ try {
163
+ accessToken = await getToken(hostForToken);
164
+ } catch {
165
+ accessToken = null;
164
166
  }
165
- return {
166
- url: `${baseUrl.replace(/\/$/, "")}${path}`,
167
- headers,
168
- rawBody
169
- };
167
+ if (accessToken) {
168
+ return {
169
+ url: `${baseUrl.replace(/\/$/, "")}${path}`,
170
+ headers: {
171
+ "Authorization": `bearer ${accessToken}`,
172
+ ...contentTypeHeader
173
+ },
174
+ rawBody
175
+ };
176
+ }
177
+ let cliToken = null;
178
+ try {
179
+ cliToken = await getCliToken(hostForToken);
180
+ } catch {
181
+ cliToken = null;
182
+ }
183
+ if (cliToken) {
184
+ return {
185
+ url: `${baseUrl.replace(/\/$/, "")}${path}`,
186
+ headers: {
187
+ "cli-token": cliToken,
188
+ ...contentTypeHeader
189
+ },
190
+ rawBody
191
+ };
192
+ }
193
+ throw new TeAgentCredentialsError(
194
+ "No te-claude credentials available",
195
+ "Run ae-cli auth login, or execute inside a te-agent sandbox"
196
+ );
170
197
  }
171
198
  async function parseResponse(response, defaultErrorPrefix) {
172
199
  const text = await response.text();
@@ -266,7 +293,7 @@ async function uploadToMainApp(path, formData) {
266
293
  "X-Sandbox-Secret-Key": sandboxCred.sandboxSecretKey
267
294
  };
268
295
  } else {
269
- const { getToken } = await import("./auth-DYC2BGLM.js");
296
+ const { getToken } = await import("./auth-IDPKDFSY.js");
270
297
  baseUrl = (sandboxCred?.url || teClaudeBaseFromActiveHost() || "").replace(/\/$/, "");
271
298
  if (!baseUrl) {
272
299
  throw new TeAgentCredentialsError(
@@ -108,8 +108,8 @@ function getSandboxRuntimeRoot() {
108
108
  function getSandboxAeConfigDir() {
109
109
  return join(getSandboxRuntimeRoot(), ".ae-config");
110
110
  }
111
- function getSandboxMcpTokenFilePath() {
112
- return join(getSandboxAeConfigDir(), "mcp-token.json");
111
+ function getSandboxCliTokenFilePath() {
112
+ return join(getSandboxAeConfigDir(), "cli-token.json");
113
113
  }
114
114
  function getSandboxClusterInfoFilePath() {
115
115
  return join(getSandboxAeConfigDir(), "cluster-info.json");
@@ -118,22 +118,22 @@ function getSandboxClusterInfoFilePath() {
118
118
  // src/core/config.ts
119
119
  var CONFIG_DIR = path2.join(process.env.HOME || "", ".ae-cli");
120
120
  var CONFIG_FILE = path2.join(CONFIG_DIR, "config.json");
121
- function sandboxMcpTokenCandidatePaths() {
122
- const paths = [getSandboxMcpTokenFilePath()];
123
- const homeFallback = path2.join(process.env.HOME || "", ".ae-config", "mcp-token.json");
121
+ function sandboxCliTokenCandidatePaths() {
122
+ const paths = [getSandboxCliTokenFilePath()];
123
+ const homeFallback = path2.join(process.env.HOME || "", ".ae-config", "cli-token.json");
124
124
  if (!paths.includes(homeFallback)) {
125
125
  paths.push(homeFallback);
126
126
  }
127
127
  return paths;
128
128
  }
129
- function readSandboxMcpTokenEntry() {
130
- for (const file of sandboxMcpTokenCandidatePaths()) {
129
+ function readSandboxCliTokenEntry() {
130
+ for (const file of sandboxCliTokenCandidatePaths()) {
131
131
  if (!fs3.existsSync(file)) continue;
132
132
  try {
133
133
  const data = safeReadJsonFile(file);
134
134
  if (data && typeof data === "object" && !Array.isArray(data)) {
135
135
  const url = data.url;
136
- const token = data["mcp-token"];
136
+ const token = data.token;
137
137
  if (url && token) {
138
138
  return { url, token };
139
139
  }
@@ -143,15 +143,12 @@ function readSandboxMcpTokenEntry() {
143
143
  }
144
144
  return null;
145
145
  }
146
- function ensureDir() {
147
- if (!fs3.existsSync(CONFIG_DIR)) fs3.mkdirSync(CONFIG_DIR, { recursive: true });
148
- }
149
146
  function forceMigrateFromFallback() {
150
- const entry = readSandboxMcpTokenEntry();
147
+ const entry = readSandboxCliTokenEntry();
151
148
  if (!entry) return null;
152
149
  return { [entry.url]: entry.token };
153
150
  }
154
- function getFallbackMcpToken(hostUrl) {
151
+ function getFallbackCliToken(hostUrl) {
155
152
  const store = forceMigrateFromFallback();
156
153
  if (!store) return null;
157
154
  if (hostUrl && store[hostUrl]) return store[hostUrl];
@@ -159,6 +156,9 @@ function getFallbackMcpToken(hostUrl) {
159
156
  if (entries.length === 1) return entries[0];
160
157
  return null;
161
158
  }
159
+ function ensureDir() {
160
+ if (!fs3.existsSync(CONFIG_DIR)) fs3.mkdirSync(CONFIG_DIR, { recursive: true });
161
+ }
162
162
  function loadConfig() {
163
163
  try {
164
164
  if (fs3.existsSync(CONFIG_FILE)) {
@@ -197,9 +197,10 @@ function saveConfig(config) {
197
197
  logger.info(`Config saved: activeHost=${config.activeHost}, hosts=${Object.keys(config.hosts).length}`);
198
198
  }
199
199
  function getActiveHost() {
200
+ const sandboxHost = readSandboxCliTokenEntry()?.url;
201
+ if (sandboxHost) return sandboxHost;
200
202
  const config = loadConfig();
201
- if (config.activeHost) return config.activeHost;
202
- return readSandboxMcpTokenEntry()?.url ?? "";
203
+ return config.activeHost || "";
203
204
  }
204
205
  function setActiveHost(url) {
205
206
  const config = loadConfig();
@@ -233,6 +234,14 @@ function removeHost(url) {
233
234
  }
234
235
  saveConfig(config);
235
236
  }
237
+ function listHosts() {
238
+ const config = loadConfig();
239
+ return Object.entries(config.hosts).map(([url, entry]) => ({
240
+ url,
241
+ label: entry.label,
242
+ active: url === config.activeHost
243
+ }));
244
+ }
236
245
  function getConfigDir() {
237
246
  return CONFIG_DIR;
238
247
  }
@@ -243,12 +252,13 @@ export {
243
252
  safeReadJsonFile,
244
253
  getSandboxRuntimeRoot,
245
254
  getSandboxClusterInfoFilePath,
246
- getFallbackMcpToken,
255
+ getFallbackCliToken,
247
256
  loadConfig,
248
257
  saveConfig,
249
258
  getActiveHost,
250
259
  setActiveHost,
251
260
  addHost,
252
261
  removeHost,
262
+ listHosts,
253
263
  getConfigDir
254
264
  };