@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
@@ -0,0 +1,59 @@
1
+ import {
2
+ buildCapabilityGatewayUrl,
3
+ executeCapability
4
+ } from "./chunk-V5R5UIRM.js";
5
+
6
+ // src/core/capability-routing.ts
7
+ var cliServiceRoutes = /* @__PURE__ */ new Map();
8
+ function registerCapabilityGatewayRoute(cliService, route) {
9
+ cliServiceRoutes.set(cliService, route);
10
+ }
11
+ function resolveGatewayDomain(cliService, override) {
12
+ if (override !== void 0) {
13
+ return override;
14
+ }
15
+ const route = cliServiceRoutes.get(cliService);
16
+ if (!route) {
17
+ throw new Error(
18
+ `Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
19
+ );
20
+ }
21
+ return route.gatewayDomain;
22
+ }
23
+
24
+ // src/core/capability-command.ts
25
+ function createCapabilityCommand(config) {
26
+ return {
27
+ service: config.cliService,
28
+ resource: config.resource,
29
+ command: config.command,
30
+ description: config.description,
31
+ flags: config.flags,
32
+ risk: config.risk,
33
+ validate: config.validate,
34
+ dryRun: (ctx) => {
35
+ const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
36
+ const input = config.buildInput(ctx);
37
+ return {
38
+ method: "POST",
39
+ url: buildCapabilityGatewayUrl(
40
+ ctx.host(),
41
+ gatewayDomain,
42
+ `capabilities/${config.capabilityId}/dry-run`
43
+ ),
44
+ body: { input }
45
+ };
46
+ },
47
+ execute: async (ctx) => {
48
+ const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
49
+ const input = config.buildInput(ctx);
50
+ return executeCapability(ctx.host(), gatewayDomain, config.capabilityId, input);
51
+ }
52
+ };
53
+ }
54
+
55
+ export {
56
+ registerCapabilityGatewayRoute,
57
+ resolveGatewayDomain,
58
+ createCapabilityCommand
59
+ };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  SecureStoreAuthError,
3
- clearToken,
4
3
  getToken,
4
+ invalidateAccessTokenForRetry,
5
5
  resolveHost
6
- } from "./chunk-RSHMZ3LG.js";
6
+ } from "./chunk-PFJFZVCK.js";
7
7
  import {
8
8
  logger,
9
9
  safeJsonParse
10
- } from "./chunk-6W4QOZAL.js";
10
+ } from "./chunk-65DKFJZB.js";
11
11
 
12
12
  // src/core/client.ts
13
13
  import WebSocket from "ws";
@@ -46,7 +46,7 @@ async function request(method, modulePath, params = {}, body = null, retry = tru
46
46
  logger.api(method, url, resp.status, body, data);
47
47
  if (resp.status === 401) {
48
48
  if (retry) {
49
- clearToken(resolvedHost);
49
+ invalidateAccessTokenForRetry(resolvedHost);
50
50
  return request(method, modulePath, params, body, false, resolvedHost);
51
51
  }
52
52
  throw new SecureStoreAuthError(`Session expired or unauthorized for ${resolvedHost}. Please run: ae-cli auth login`);
@@ -56,7 +56,7 @@ async function request(method, modulePath, params = {}, body = null, retry = tru
56
56
  throw new Error(m);
57
57
  }
58
58
  if (data.return_code === -1001 && retry) {
59
- clearToken(resolvedHost);
59
+ invalidateAccessTokenForRetry(resolvedHost);
60
60
  return request(method, modulePath, params, body, false, resolvedHost);
61
61
  }
62
62
  if (data.return_code !== 0 && data.return_code !== void 0) {
@@ -89,7 +89,7 @@ async function uploadRequest(modulePath, form, params = {}, retry = true, hostUr
89
89
  logger.api("POST", url, resp.status, { upload: true }, data);
90
90
  if (resp.status === 401) {
91
91
  if (retry) {
92
- clearToken(resolvedHost);
92
+ invalidateAccessTokenForRetry(resolvedHost);
93
93
  return uploadRequest(modulePath, form, params, false, resolvedHost);
94
94
  }
95
95
  throw new SecureStoreAuthError(`Session expired or unauthorized for ${resolvedHost}. Please run: ae-cli auth login`);
@@ -99,7 +99,7 @@ async function uploadRequest(modulePath, form, params = {}, retry = true, hostUr
99
99
  throw new Error(m);
100
100
  }
101
101
  if (data.return_code === -1001 && retry) {
102
- clearToken(resolvedHost);
102
+ invalidateAccessTokenForRetry(resolvedHost);
103
103
  return uploadRequest(modulePath, form, params, false, resolvedHost);
104
104
  }
105
105
  if (data.return_code !== 0 && data.return_code !== void 0) {
@@ -162,7 +162,7 @@ async function wsQuery(projectId, requestId, qp, eventModel, options = {}, hostU
162
162
  } catch (err) {
163
163
  const msg = err.message || "";
164
164
  if (msg.includes("401") || msg.includes("403") || msg.includes("auth")) {
165
- clearToken(resolvedHost);
165
+ invalidateAccessTokenForRetry(resolvedHost);
166
166
  const newToken = await getToken(resolvedHost);
167
167
  return wsQueryOnce(projectId, requestId, qp, eventModel, options, newToken, resolvedHost);
168
168
  }
@@ -0,0 +1,59 @@
1
+ import {
2
+ buildCapabilityGatewayUrl,
3
+ executeCapability
4
+ } from "./chunk-2OW2RENH.js";
5
+
6
+ // src/core/capability-routing.ts
7
+ var cliServiceRoutes = /* @__PURE__ */ new Map();
8
+ function registerCapabilityGatewayRoute(cliService, route) {
9
+ cliServiceRoutes.set(cliService, route);
10
+ }
11
+ function resolveGatewayDomain(cliService, override) {
12
+ if (override !== void 0) {
13
+ return override;
14
+ }
15
+ const route = cliServiceRoutes.get(cliService);
16
+ if (!route) {
17
+ throw new Error(
18
+ `Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
19
+ );
20
+ }
21
+ return route.gatewayDomain;
22
+ }
23
+
24
+ // src/core/capability-command.ts
25
+ function createCapabilityCommand(config) {
26
+ return {
27
+ service: config.cliService,
28
+ resource: config.resource,
29
+ command: config.command,
30
+ description: config.description,
31
+ flags: config.flags,
32
+ risk: config.risk,
33
+ validate: config.validate,
34
+ dryRun: (ctx) => {
35
+ const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
36
+ const input = config.buildInput(ctx);
37
+ return {
38
+ method: "POST",
39
+ url: buildCapabilityGatewayUrl(
40
+ ctx.host(),
41
+ gatewayDomain,
42
+ `capabilities/${config.capabilityId}/dry-run`
43
+ ),
44
+ body: { input }
45
+ };
46
+ },
47
+ execute: async (ctx) => {
48
+ const gatewayDomain = resolveGatewayDomain(config.cliService, config.gatewayDomain);
49
+ const input = config.buildInput(ctx);
50
+ return executeCapability(ctx.host(), gatewayDomain, config.capabilityId, input);
51
+ }
52
+ };
53
+ }
54
+
55
+ export {
56
+ registerCapabilityGatewayRoute,
57
+ resolveGatewayDomain,
58
+ createCapabilityCommand
59
+ };
@@ -1,12 +1,12 @@
1
- import {
2
- getMcpToken
3
- } from "./chunk-DMMEPCST.js";
4
1
  import {
5
2
  PermissionError
6
3
  } from "./chunk-NOO24N7W.js";
4
+ import {
5
+ getCliToken
6
+ } from "./chunk-OCQPQYHZ.js";
7
7
  import {
8
8
  safeJsonParse
9
- } from "./chunk-6W4QOZAL.js";
9
+ } from "./chunk-65DKFJZB.js";
10
10
 
11
11
  // src/core/mcp-access.ts
12
12
  function buildUrl(host, path, params = {}) {
@@ -52,21 +52,21 @@ function parseKbResponse(resp, text) {
52
52
  }
53
53
  return data.data !== void 0 ? data.data : data;
54
54
  }
55
- async function fetchWithMcpToken(input, init, mcpToken) {
55
+ async function fetchWithCliToken(input, init, cliToken) {
56
56
  const headers = new Headers(init.headers);
57
- headers.set("mcp-token", mcpToken);
57
+ headers.set("cli-token", cliToken);
58
58
  const resp = await fetch(input, { ...init, headers });
59
59
  return parseKbResponse(resp, await resp.text());
60
60
  }
61
61
  async function getAuthHeaders(ctx) {
62
- const mcpToken = await getMcpToken(ctx.host());
63
- return { "mcp-token": mcpToken };
62
+ const cliToken = await getCliToken(ctx.host());
63
+ return { "cli-token": cliToken };
64
64
  }
65
65
  async function kbApi(ctx, method, path, params = {}, body) {
66
66
  const host = ctx.host();
67
- const mcpToken = await getMcpToken(host);
67
+ const cliToken = await getCliToken(host);
68
68
  const upperMethod = method.toUpperCase();
69
- return fetchWithMcpToken(
69
+ return fetchWithCliToken(
70
70
  buildUrl(host, path, params),
71
71
  {
72
72
  method: upperMethod,
@@ -75,19 +75,19 @@ async function kbApi(ctx, method, path, params = {}, body) {
75
75
  },
76
76
  body: upperMethod === "GET" ? void 0 : JSON.stringify(body ?? {})
77
77
  },
78
- mcpToken
78
+ cliToken
79
79
  );
80
80
  }
81
81
  async function kbUpload(ctx, path, form, params = {}) {
82
82
  const host = ctx.host();
83
- const mcpToken = await getMcpToken(host);
84
- return fetchWithMcpToken(
83
+ const cliToken = await getCliToken(host);
84
+ return fetchWithCliToken(
85
85
  buildUrl(host, path, params),
86
86
  {
87
87
  method: "POST",
88
88
  body: form
89
89
  },
90
- mcpToken
90
+ cliToken
91
91
  );
92
92
  }
93
93
 
@@ -1,19 +1,18 @@
1
1
  import {
2
2
  getAnalysisMappingPathForClusterMode
3
- } from "./chunk-PN3OS34E.js";
3
+ } from "./chunk-WXBCP6SD.js";
4
4
  import {
5
5
  PermissionError
6
6
  } from "./chunk-NOO24N7W.js";
7
7
  import {
8
- getToken,
9
- loadMcpToken
10
- } from "./chunk-RSHMZ3LG.js";
8
+ clearCliToken,
9
+ getCliToken
10
+ } from "./chunk-OCQPQYHZ.js";
11
11
  import {
12
12
  getActiveHost,
13
- getFallbackMcpToken,
14
13
  logger,
15
14
  safeJsonParse
16
- } from "./chunk-6W4QOZAL.js";
15
+ } from "./chunk-65DKFJZB.js";
17
16
 
18
17
  // src/core/mcp.ts
19
18
  async function permissionMessage(resp) {
@@ -26,6 +25,9 @@ async function permissionMessage(resp) {
26
25
  }
27
26
  return "Permission denied for this resource (HTTP 403)";
28
27
  }
28
+ function isInvalidCliTokenMessage(message) {
29
+ return /\b(cli[-_\s]?token|token)\b.*\binvalid\b/i.test(message) || /\binvalid\b.*\b(cli[-_\s]?token|token)\b/i.test(message);
30
+ }
29
31
  var MCP_PROTOCOL_VERSION = "2025-11-25";
30
32
  var JSONRPC_VERSION = "2.0";
31
33
  var serviceMappingMap = /* @__PURE__ */ new Map();
@@ -70,104 +72,14 @@ var requestIdCounter = 1;
70
72
  function genRequestId() {
71
73
  return requestIdCounter++;
72
74
  }
73
- var MCP_TOKEN_GENERATE_PATH = "/v1/ta/mcp/token/generate";
74
- var _mcpTokenCache = /* @__PURE__ */ new Map();
75
- async function generateMcpToken(hostUrl) {
76
- const teToken = await getToken(hostUrl);
77
- const base = hostUrl.replace(/\/+$/, "");
78
- const url = `${base}${MCP_TOKEN_GENERATE_PATH}`;
79
- const resp = await fetch(url, {
80
- method: "GET",
81
- headers: {
82
- "Authorization": `bearer ${teToken}`
83
- }
84
- });
85
- if (!resp.ok) {
86
- throw new Error(`MCP token generate HTTP error: ${resp.status} ${resp.statusText}`);
87
- }
88
- const data = safeJsonParse(await resp.text());
89
- if (data.return_code !== 0) {
90
- throw new Error(`MCP token generate error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
91
- }
92
- const mcpToken = data.data?.userSecret;
93
- if (!mcpToken) {
94
- throw new Error("MCP token generate error: empty userSecret in response");
95
- }
96
- return mcpToken;
97
- }
98
- async function getMcpToken(hostOverride) {
99
- const hostUrl = hostOverride || getActiveHost();
100
- const cached = _mcpTokenCache.get(hostUrl);
101
- if (cached) {
102
- return cached;
103
- }
104
- const storedToken = loadMcpToken(hostUrl);
105
- if (storedToken) {
106
- _mcpTokenCache.set(hostUrl, storedToken);
107
- logger.info(`Using persisted MCP token (secure-store) for ${hostUrl}`);
108
- return storedToken;
109
- }
110
- const fallbackToken = getFallbackMcpToken(hostUrl);
111
- if (fallbackToken) {
112
- _mcpTokenCache.set(hostUrl, fallbackToken);
113
- logger.info(`Using sandbox-provisioned MCP token (fallback file) for ${hostUrl}`);
114
- return fallbackToken;
115
- }
116
- logger.info(`Generating MCP token for ${hostUrl}`);
117
- const mcpToken = await generateMcpToken(hostUrl);
118
- _mcpTokenCache.set(hostUrl, mcpToken);
119
- logger.info(`MCP token generated and in-process cached for ${hostUrl}`);
120
- return mcpToken;
121
- }
122
- function clearMcpToken(hostUrl) {
123
- if (hostUrl) {
124
- _mcpTokenCache.delete(hostUrl);
125
- } else {
126
- _mcpTokenCache.clear();
127
- }
128
- }
129
- function setMcpTokenManual(token, hostUrl) {
130
- _mcpTokenCache.set(hostUrl, token);
131
- logger.info(`MCP token manually set (in-process) for ${hostUrl}`);
132
- }
133
- async function validateMcpToken(token, hostUrl) {
134
- const mapping = getMcpMapping("analysis");
135
- const base = hostUrl.replace(/\/+$/, "");
136
- const url = `${base}/mcp/${mapping.componentName}/http/${mapping.mappingPath}`;
137
- const requestId = 1;
138
- const body = {
139
- jsonrpc: JSONRPC_VERSION,
140
- id: requestId,
141
- method: "tools/list",
142
- params: { _meta: { progressToken: requestId } }
143
- };
144
- const headers = {
145
- "Content-Type": "application/json",
146
- "Accept": "application/json, text/event-stream",
147
- "mcp-protocol-version": MCP_PROTOCOL_VERSION,
148
- "mcp-token": token
75
+ function buildAuthHeaders(cliToken) {
76
+ return {
77
+ "cli-token": cliToken
149
78
  };
150
- try {
151
- const resp = await fetch(url, {
152
- method: "POST",
153
- headers,
154
- body: JSON.stringify(body)
155
- });
156
- if (!resp.ok) {
157
- return false;
158
- }
159
- const data = safeJsonParse(await resp.text());
160
- if (data.error) {
161
- return false;
162
- }
163
- return data.result?.tools !== void 0;
164
- } catch {
165
- return false;
166
- }
167
79
  }
168
80
  async function mcpRequest(url, method, params = {}, hostOverride) {
169
81
  const hostUrl = hostOverride || getActiveHost();
170
- const token = await getMcpToken(hostUrl);
82
+ const token = await getCliToken(hostUrl);
171
83
  const requestId = genRequestId();
172
84
  const paramsWithMeta = {
173
85
  ...params,
@@ -183,7 +95,7 @@ async function mcpRequest(url, method, params = {}, hostOverride) {
183
95
  "Content-Type": "application/json",
184
96
  "Accept": "application/json, text/event-stream",
185
97
  "mcp-protocol-version": MCP_PROTOCOL_VERSION,
186
- "mcp-token": token
98
+ ...buildAuthHeaders(token)
187
99
  };
188
100
  const resp = await fetch(url, {
189
101
  method: "POST",
@@ -191,19 +103,21 @@ async function mcpRequest(url, method, params = {}, hostOverride) {
191
103
  body: JSON.stringify(body)
192
104
  });
193
105
  if (!resp.ok) {
106
+ let permissionMsg;
194
107
  if (resp.status === 403) {
195
- throw new PermissionError(await permissionMessage(resp));
108
+ permissionMsg = await permissionMessage(resp);
109
+ if (!isInvalidCliTokenMessage(permissionMsg)) {
110
+ throw new PermissionError(permissionMsg);
111
+ }
196
112
  }
197
- if (resp.status === 401) {
198
- logger.warn(`MCP request failed (HTTP 401) for ${hostUrl}, re-minting token`);
199
- _mcpTokenCache.delete(hostUrl);
200
- const fallbackToken = getFallbackMcpToken(hostUrl);
201
- const newToken = fallbackToken ?? await generateMcpToken(hostUrl);
202
- _mcpTokenCache.set(hostUrl, newToken);
203
- logger.info(`MCP token re-minted for ${hostUrl}`);
204
- process.stderr.write(`[ae-cli] MCP token re-minted for ${hostUrl}
113
+ if (resp.status === 401 || resp.status === 403 && permissionMsg) {
114
+ logger.warn(`MCP request failed (${resp.status === 403 ? permissionMsg : "HTTP 401"}) for ${hostUrl}, refreshing CLI token`);
115
+ clearCliToken(hostUrl);
116
+ const newToken = await getCliToken(hostUrl);
117
+ logger.info(`CLI token refreshed for ${hostUrl}`);
118
+ process.stderr.write(`[ae-cli] CLI token refreshed for ${hostUrl}
205
119
  `);
206
- headers["mcp-token"] = newToken;
120
+ Object.assign(headers, buildAuthHeaders(newToken));
207
121
  const retryResp = await fetch(url, {
208
122
  method: "POST",
209
123
  headers,
@@ -289,10 +203,6 @@ function mcpResultErrorMessage(parsed) {
289
203
  export {
290
204
  registerMcpMappings,
291
205
  resolveMcpUrl,
292
- getMcpToken,
293
- clearMcpToken,
294
- setMcpTokenManual,
295
- validateMcpToken,
296
206
  callMcpTool,
297
207
  parseMcpResult
298
208
  };
@@ -0,0 +1,209 @@
1
+ import {
2
+ getAnalysisMappingPathForClusterMode
3
+ } from "./chunk-WXBCP6SD.js";
4
+ import {
5
+ PermissionError
6
+ } from "./chunk-NOO24N7W.js";
7
+ import {
8
+ clearCliToken,
9
+ getCliToken
10
+ } from "./chunk-OCQPQYHZ.js";
11
+ import {
12
+ getActiveHost,
13
+ logger,
14
+ safeJsonParse
15
+ } from "./chunk-65DKFJZB.js";
16
+
17
+ // src/core/mcp.ts
18
+ async function permissionMessage(resp) {
19
+ const text = await resp.text().catch(() => "");
20
+ try {
21
+ const d = safeJsonParse(text);
22
+ const msg = d && (d.error?.message || (typeof d.error === "string" ? d.error : void 0) || d.message);
23
+ if (msg && typeof msg === "string") return msg;
24
+ } catch {
25
+ }
26
+ return "Permission denied for this resource (HTTP 403)";
27
+ }
28
+ function isInvalidCliTokenMessage(message) {
29
+ return /\b(cli[-_\s]?token|token)\b.*\binvalid\b/i.test(message) || /\binvalid\b.*\b(cli[-_\s]?token|token)\b/i.test(message);
30
+ }
31
+ var MCP_PROTOCOL_VERSION = "2025-11-25";
32
+ var JSONRPC_VERSION = "2.0";
33
+ var serviceMappingMap = /* @__PURE__ */ new Map();
34
+ registerMcpMapping("analysis", {
35
+ componentName: "analysis",
36
+ mappingPath: "analysis"
37
+ });
38
+ registerMcpMapping("te_analysis_extend", {
39
+ componentName: "analysis",
40
+ mappingPath: "analysis-extend"
41
+ });
42
+ function registerMcpMapping(serviceName, mapping) {
43
+ serviceMappingMap.set(serviceName, mapping);
44
+ }
45
+ function registerMcpMappings(mappings) {
46
+ for (const [serviceName, mapping] of Object.entries(mappings)) {
47
+ serviceMappingMap.set(serviceName, mapping);
48
+ }
49
+ }
50
+ function getMcpMapping(serviceName) {
51
+ const mapping = serviceMappingMap.get(serviceName);
52
+ if (!mapping) {
53
+ throw new Error(`MCP mapping not found for service: '${serviceName}'. Please register it using registerMcpMapping() first.`);
54
+ }
55
+ if (serviceName === "analysis") {
56
+ return { ...mapping, mappingPath: getAnalysisMappingPathForClusterMode() };
57
+ }
58
+ return mapping;
59
+ }
60
+ function buildMcpUrl(host, serviceName) {
61
+ const mapping = getMcpMapping(serviceName);
62
+ const base = host.replace(/\/+$/, "");
63
+ return `${base}/mcp/${mapping.componentName}/http/${mapping.mappingPath}`;
64
+ }
65
+ function resolveMcpUrl(mcpUrlOverride, host, serviceName) {
66
+ if (mcpUrlOverride) {
67
+ return mcpUrlOverride;
68
+ }
69
+ return buildMcpUrl(host, serviceName);
70
+ }
71
+ var requestIdCounter = 1;
72
+ function genRequestId() {
73
+ return requestIdCounter++;
74
+ }
75
+ function buildAuthHeaders(cliToken) {
76
+ return {
77
+ "cli-token": cliToken
78
+ };
79
+ }
80
+ async function mcpRequest(url, method, params = {}, hostOverride) {
81
+ const hostUrl = hostOverride || getActiveHost();
82
+ const token = await getCliToken(hostUrl);
83
+ const requestId = genRequestId();
84
+ const paramsWithMeta = {
85
+ ...params,
86
+ _meta: { progressToken: requestId }
87
+ };
88
+ const body = {
89
+ jsonrpc: JSONRPC_VERSION,
90
+ id: requestId,
91
+ method,
92
+ params: paramsWithMeta
93
+ };
94
+ const headers = {
95
+ "Content-Type": "application/json",
96
+ "Accept": "application/json, text/event-stream",
97
+ "mcp-protocol-version": MCP_PROTOCOL_VERSION,
98
+ "X-Source": "ae-cli",
99
+ ...buildAuthHeaders(token)
100
+ };
101
+ const resp = await fetch(url, {
102
+ method: "POST",
103
+ headers,
104
+ body: JSON.stringify(body)
105
+ });
106
+ if (!resp.ok) {
107
+ let permissionMsg;
108
+ if (resp.status === 403) {
109
+ permissionMsg = await permissionMessage(resp);
110
+ if (!isInvalidCliTokenMessage(permissionMsg)) {
111
+ throw new PermissionError(permissionMsg);
112
+ }
113
+ }
114
+ if (resp.status === 401 || resp.status === 403 && permissionMsg) {
115
+ logger.warn(`MCP request failed (${resp.status === 403 ? permissionMsg : "HTTP 401"}) for ${hostUrl}, refreshing CLI token`);
116
+ clearCliToken(hostUrl);
117
+ const newToken = await getCliToken(hostUrl);
118
+ logger.info(`CLI token refreshed for ${hostUrl}`);
119
+ process.stderr.write(`[ae-cli] CLI token refreshed for ${hostUrl}
120
+ `);
121
+ Object.assign(headers, buildAuthHeaders(newToken));
122
+ const retryResp = await fetch(url, {
123
+ method: "POST",
124
+ headers,
125
+ body: JSON.stringify(body)
126
+ });
127
+ if (retryResp.status === 403) {
128
+ throw new PermissionError(await permissionMessage(retryResp));
129
+ }
130
+ if (!retryResp.ok) {
131
+ throw new Error(`MCP HTTP error: ${retryResp.status} ${retryResp.statusText}`);
132
+ }
133
+ const retryData = safeJsonParse(await retryResp.text());
134
+ if (retryData.error) {
135
+ throw new Error(`MCP error: ${retryData.error.message || JSON.stringify(retryData.error)}`);
136
+ }
137
+ return retryData.result;
138
+ }
139
+ throw new Error(`MCP HTTP error: ${resp.status} ${resp.statusText}`);
140
+ }
141
+ const data = safeJsonParse(await resp.text());
142
+ if (data.error) {
143
+ throw new Error(`MCP error: ${data.error.message || JSON.stringify(data.error)}`);
144
+ }
145
+ return data.result;
146
+ }
147
+ async function callMcpTool(url, toolName, args = {}, hostOverride) {
148
+ const params = {
149
+ name: toolName,
150
+ arguments: args
151
+ };
152
+ logger.info(`MCP tool call: ${toolName}`);
153
+ const result = await mcpRequest(url, "tools/call", params, hostOverride);
154
+ if (result.isError) {
155
+ logger.warn(`MCP tool call failed: ${toolName}`);
156
+ }
157
+ return {
158
+ content: result.content.map((item) => {
159
+ if (item.type === "text") {
160
+ return { type: "text", text: item.text };
161
+ } else if (item.type === "image") {
162
+ return { type: "image", data: item.data, mimeType: item.mimeType };
163
+ } else {
164
+ return { type: "resource", ...item };
165
+ }
166
+ }),
167
+ isError: result.isError
168
+ };
169
+ }
170
+ function parseMcpResult(result) {
171
+ if (result.content.length > 0 && result.content[0].type === "text") {
172
+ const text = result.content[0].text || "";
173
+ let parsed;
174
+ try {
175
+ parsed = safeJsonParse(text);
176
+ } catch {
177
+ return text;
178
+ }
179
+ const errMsg = mcpResultErrorMessage(parsed);
180
+ if (errMsg !== null) {
181
+ if (/no_auth|auth_error|permission|forbidden|unauthor|\u65e0\u6743/i.test(errMsg)) {
182
+ throw new PermissionError(errMsg);
183
+ }
184
+ throw new Error(errMsg);
185
+ }
186
+ return parsed;
187
+ }
188
+ return result;
189
+ }
190
+ function mcpResultErrorMessage(parsed) {
191
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
192
+ if (parsed.success === true || parsed.ok === true) return null;
193
+ const e = parsed.error;
194
+ if (typeof e === "string" && e.trim()) return e;
195
+ if (e && typeof e === "object") {
196
+ const msg = typeof e.message === "string" && e.message || void 0;
197
+ const code = typeof e.code === "string" && e.code || void 0;
198
+ if (msg && code) return `${code}: ${msg}`;
199
+ if (msg || code) return msg || code;
200
+ }
201
+ return null;
202
+ }
203
+
204
+ export {
205
+ registerMcpMappings,
206
+ resolveMcpUrl,
207
+ callMcpTool,
208
+ parseMcpResult
209
+ };