@thinkingai/ae-cli 1.0.15 → 1.0.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.
Files changed (43) hide show
  1. package/README.md +23 -24
  2. package/README.zh.md +21 -22
  3. package/dist/auth-A4NV2VHD.js +153 -0
  4. package/dist/{auth-4GAHTBVH.js → auth-T3ILGJKW.js} +6 -4
  5. package/dist/{chunk-TJIMDNAU.js → chunk-5CCFSPAF.js} +79 -3
  6. package/dist/{chunk-UK6HO5O5.js → chunk-OVMQFFC2.js} +13 -1
  7. package/dist/{chunk-EBFUVWIZ.js → chunk-TMMUBSKW.js} +52 -0
  8. package/dist/{chunk-OQ4XEG77.js → chunk-TOXRLDUP.js} +2 -2
  9. package/dist/{client-HU63573O.js → client-FPA76DGY.js} +3 -3
  10. package/dist/{config-OLF7RBPM.js → config-QZIEYXQZ.js} +20 -5
  11. package/dist/index.js +18 -13
  12. package/dist/{raw-GDO4IWNW.js → raw-MZIKHQH4.js} +3 -3
  13. package/dist/{te-analysis-ZDJXMWZY.js → te-analysis-CFQBXUCO.js} +93 -7
  14. package/dist/{te-audience-T5B52EEB.js → te-audience-WPBBWADL.js} +3 -3
  15. package/dist/{te-common-BPTXXTHQ.js → te-common-GL3KBZPD.js} +3 -3
  16. package/dist/{te-community-FPB5LH56.js → te-community-3XEJNSQL.js} +3 -3
  17. package/dist/{te-dataops-2NUJVG47.js → te-dataops-H4WSMCG5.js} +3 -3
  18. package/dist/{te-engage-K3EANZ5P.js → te-engage-2VFM37ZM.js} +3 -3
  19. package/dist/te-kb-U6SQUJVC.js +41 -0
  20. package/dist/{te-meta-JJMV75KB.js → te-meta-BO45GW32.js} +10 -8
  21. package/package.json +2 -1
  22. package/skills/ae-analysis/SKILL.md +119 -29
  23. package/skills/ae-analysis/references/build_event_analysis_qp.md +132 -0
  24. package/skills/ae-analysis/references/build_funnel_analysis_qp.md +143 -0
  25. package/skills/ae-analysis/references/build_prop_analysis_qp.md +122 -0
  26. package/skills/ae-analysis/references/build_retention_analysis_qp.md +141 -0
  27. package/skills/ae-analysis/references/generate_track_program.md +8 -8
  28. package/skills/ae-analysis/references/get_analysis_query_schema.md +22 -11
  29. package/skills/ae-analysis/references/get_metric.md +7 -1
  30. package/skills/ae-analysis/references/get_report_definition.md +4 -0
  31. package/skills/ae-analysis/references/list_alerts.md +4 -0
  32. package/skills/ae-analysis/references/list_clusters.md +4 -0
  33. package/skills/ae-analysis/references/list_dashboards.md +6 -0
  34. package/skills/ae-analysis/references/list_events.md +8 -1
  35. package/skills/ae-analysis/references/list_metrics.md +9 -0
  36. package/skills/ae-analysis/references/list_properties.md +6 -1
  37. package/skills/ae-analysis/references/list_reports.md +6 -0
  38. package/skills/ae-analysis/references/list_tags.md +4 -0
  39. package/skills/ae-analysis/references/query_adhoc.md +80 -30
  40. package/skills/ae-community/SKILL.md +14 -101
  41. package/skills/ae-dataops/SKILL.md +13 -58
  42. package/skills/ae-engage/SKILL.md +15 -98
  43. package/dist/auth-U2GHFMFY.js +0 -81
package/README.md CHANGED
@@ -86,14 +86,18 @@ ae-cli auth logout
86
86
 
87
87
  | Domain | Commands | Description |
88
88
  |--------|----------|-------------|
89
- | `analysis` | 31 | Analysis workflows: alerts, reports, dashboards, ad-hoc/drilldown, clusters/tags, metadata/metrics, project tools, entity details, analysis schema |
90
- | `analysis_audience` | 14 | Audience operations: clusters, tags, and cluster/tag definition schema |
91
- | `analysis_meta` | 20 | Metadata governance: events/properties, metrics, virtual metadata, project config, tracking plan, mark times, resource links |
89
+ | `analysis` | 30+ | Analysis workflows: alerts, reports, dashboards, ad-hoc/drilldown, entity/event details, analysis schema |
90
+ | `analysis_audience` | 10+ | Audience operations: clusters, tags, and cluster/tag definition schema |
91
+ | `analysis_meta` | 20+ | Metadata governance: events/properties, metrics, virtual metadata, project config, tracking plan, mark times, entity catalog |
92
92
  | `engage` | 40+ | Hermes Engage MCP: channels, tasks, configs, flows, strategies |
93
- | `te_dataops` | 50+ | Data warehouse management: repos, datatables, flows, IDE queries, integration, operations |
94
- | `te_community` | 30+ | Community analysis: posts search, sentiment analysis, topic trends, livestream data |
93
+ | `dataops_repo` | 8 | Data warehouse repos: spaces, catalogs, schemas, members |
94
+ | `dataops_datatable` | 10+ | Data tables: table creation, views, batch operations, data dictionary |
95
+ | `dataops_flow` | 20+ | Task flows: flow creation, task nodes, scheduling, execution, monitoring |
96
+ | `dataops_ide` | 10+ | IDE queries: metadata browsing, SQL execution, query management |
97
+ | `dataops_integration` | 20+ | Data integration: datasource management, sync solutions, data synchronization |
98
+ | `community` | 10+ | Community analysis: posts search, sentiment analysis, topic trends, livestream data |
95
99
  | `analysis_common` | 2 | Cross-module common constraints: resource link completion, project ID gate |
96
- | `operation` | 11 | Tasks, flows, channels, space navigation |
100
+ | `auth` / `config` | 2 | Authentication and host configuration |
97
101
 
98
102
  ### Global Options
99
103
 
@@ -124,44 +128,39 @@ npx skills add ThinkingAIAgenticEngine/ae-cli -g -y
124
128
 
125
129
  ## Skill Details
126
130
 
127
- ### ae-analysis (67 tools)
131
+ ### ae-analysis
128
132
 
129
133
  Unified AE analysis capabilities:
130
- - **Alerts**: view, create, update alert definitions
131
- - **Reports & Dashboards**: create, query, update reports and dashboards
132
- - **Model Analysis**: event analysis, retention analysis, funnel analysis, SQL analysis, user property analysis, distribution analysis, interval analysis, path analysis, attribution analysis
134
+ - **Analysis**: alerts, reports, dashboards, ad-hoc/drilldown, entity/event details, analysis schema
133
135
  - **Audience**: cluster and tag lifecycle management, plus definition schema tools
134
- - **Metadata Governance**: events/properties, metrics, virtual metadata, project config, tracking plans, mark times, entity catalog
135
- - **Common Constraints**: mandatory project ID gate and post-write resource-link completion
136
- - **Entity/Event Details**: query details, generate analysis SQL
137
- - **Schema Helpers**: analysis query schema, filter schema, groupby schema
136
+ - **Metadata**: events/properties, metrics, virtual metadata, project config, tracking plans, mark times
137
+ - **Common**: mandatory project ID gate and post-write resource-link completion
138
138
 
139
- ### engage (40+ tools)
139
+ ### engage
140
140
 
141
141
  Hermes Engage MCP capabilities:
142
- - **Channels**: channel management, config channels, approval management
143
- - **Tasks**: task list, task details, task data/metrics overview, experiment reports
144
- - **Configs**: config items, strategies, strategy comparison, trigger/analysis reports
145
- - **Flows**: flow creation, node config, flow reports, flow validation
142
+ - **Channels**: channel management, config channels, approval, whitelist
143
+ - **Tasks**: task list, details, data/metrics overview, experiment reports
144
+ - **Configs**: config items, strategies, comparison, trigger/analysis reports
145
+ - **Flows**: flow creation, node config, reports, validation
146
146
 
147
- ### ae-dataops (50+ tools)
147
+ ### ae-dataops
148
148
 
149
149
  Data warehouse management:
150
150
  - **Repo Management**: spaces, catalogs, schemas, members
151
151
  - **Data Tables**: table creation, views, batch operations, data dictionary
152
152
  - **Task Flows**: flow creation, task nodes, scheduling, execution, monitoring
153
153
  - **IDE Queries**: metadata browsing, SQL execution, query management
154
- - **Integration**: datasource management, sync solutions, data synchronization
155
- - **Operations**: flow instances, task instances, backfill jobs
154
+ - **Data Integration**: datasource management, sync solutions, data synchronization
156
155
 
157
- ### ae-community (30+ tools)
156
+ ### ae-community
158
157
 
159
158
  Community social media analysis:
160
159
  - **Posts**: search, detail, corpus tags
161
160
  - **Comments**: sentiment analysis, tag analysis, summary
162
161
  - **Topics**: hot topics, trends, daily summaries
163
162
  - **Livestreams**: rooms, sessions, analysis, metrics
164
- - **Advanced Analysis**: activity analysis, character analysis, weekly reports, release analysis
163
+ - **Channel Info**: channel overview metrics
165
164
 
166
165
  ## Architecture
167
166
 
package/README.zh.md CHANGED
@@ -86,14 +86,18 @@ ae-cli auth logout
86
86
 
87
87
  | 域 | 命令数 | 描述 |
88
88
  |---|---|---|
89
- | `analysis` | 31 | 分析工作流:告警、报表、仪表板、即时分析/下钻、分群/标签、元数据/指标、项目工具、实体详情、分析模型 |
90
- | `analysis_audience` | 14 | 受众运营:分群、标签及其定义模型 |
91
- | `analysis_meta` | 20 | 元数据治理:事件/属性、指标、虚拟元数据、项目配置、埋点方案、标记时间、资源链接 |
89
+ | `analysis` | 30+ | 分析工作流:告警、报表、仪表板、即时分析/下钻、实体/事件详情、分析模型 |
90
+ | `analysis_audience` | 10+ | 受众运营:分群、标签及其定义模型 |
91
+ | `analysis_meta` | 20+ | 元数据治理:事件/属性、指标、虚拟元数据、项目配置、埋点方案、标记时间、实体目录 |
92
92
  | `engage` | 40+ | Hermes Engage MCP:渠道、任务、配置、流程、策略 |
93
- | `te_dataops` | 50+ | 数仓管理:仓库、数据表、任务流、IDE 查询、数据集成、运维管理 |
94
- | `te_community` | 30+ | 社区分析:帖子搜索、情感分析、话题趋势、直播数据 |
93
+ | `dataops_repo` | 8 | 数仓仓库:空间、目录、模式、成员 |
94
+ | `dataops_datatable` | 10+ | 数据表:表创建、视图、批量操作、数据字典 |
95
+ | `dataops_flow` | 20+ | 任务流:流程创建、任务节点、调度、执行、监控 |
96
+ | `dataops_ide` | 10+ | IDE 查询:元数据浏览、SQL 执行、查询管理 |
97
+ | `dataops_integration` | 20+ | 数据集成:数据源管理、同步方案、数据同步 |
98
+ | `community` | 10+ | 社区分析:帖子搜索、情感分析、话题趋势、直播数据 |
95
99
  | `analysis_common` | 2 | 跨模块通用约束:资源链接补全、项目 ID 门控 |
96
- | `operation` | 11 | 任务、流程、渠道、空间导航 |
100
+ | `auth` / `config` | 2 | 身份验证和主机配置 |
97
101
 
98
102
  ### 全局选项
99
103
 
@@ -124,27 +128,23 @@ npx skills add ThinkingAIAgenticEngine/ae-cli -g -y
124
128
 
125
129
  ## Skill 详情
126
130
 
127
- ### ae-analysis(67 个工具)
131
+ ### ae-analysis
128
132
 
129
133
  统一的 AE 分析能力:
130
- - **告警**:查看、创建、更新告警定义
131
- - **报表和仪表板**:创建、查询、更新报表和仪表板
132
- - **模型分析**:事件分析、留存分析、漏斗分析、SQL 分析、用户属性分析、分布分析、间隔分析、路径分析、归因分析
134
+ - **分析**:告警、报表、仪表板、即时分析/下钻、实体/事件详情、分析模型
133
135
  - **受众**:分群和标签生命周期管理,以及定义模型工具
134
- - **元数据治理**:事件/属性、指标、虚拟元数据、项目配置、埋点方案、标记时间、实体目录
136
+ - **元数据**:事件/属性、指标、虚拟元数据、项目配置、埋点方案、标记时间
135
137
  - **通用约束**:强制的项目 ID 门控和写入后资源链接补全
136
- - **实体/事件详情**:查询详情、生成分析 SQL
137
- - **模型辅助**:分析查询模型、过滤模型、分组模型
138
138
 
139
- ### engage(40+ 个工具)
139
+ ### engage
140
140
 
141
141
  Hermes Engage MCP 能力:
142
- - **渠道**:渠道管理、配置渠道、审批管理
143
- - **任务**:任务列表、任务详情、任务数据/指标概览、实验报告
144
- - **配置**:配置项、策略、策略对比、触发/分析报告
145
- - **流程**:流程创建、节点配置、流程报告、流程验证
142
+ - **渠道**:渠道管理、配置渠道、审批、白名单
143
+ - **任务**:任务列表、详情、数据/指标概览、实验报告
144
+ - **配置**:配置项、策略、对比、触发/分析报告
145
+ - **流程**:流程创建、节点配置、报告、验证
146
146
 
147
- ### ae-dataops(50+ 个工具)
147
+ ### ae-dataops
148
148
 
149
149
  数仓管理:
150
150
  - **仓库管理**:空间、目录、模式、成员
@@ -152,16 +152,15 @@ Hermes Engage MCP 能力:
152
152
  - **任务流**:流程创建、任务节点、调度、执行、监控
153
153
  - **IDE 查询**:元数据浏览、SQL 执行、查询管理
154
154
  - **数据集成**:数据源管理、同步方案、数据同步
155
- - **运维管理**:流程实例、任务实例、补数据任务
156
155
 
157
- ### ae-community(30+ 个工具)
156
+ ### ae-community
158
157
 
159
158
  社区社媒分析:
160
159
  - **帖子**:搜索、详情、语料标签
161
160
  - **评论**:情感分析、标签分析、摘要
162
161
  - **话题**:热门话题、趋势、每日摘要
163
162
  - **直播**:直播间、场次、分析、指标
164
- - **高级分析**:活动分析、角色分析、周报、发布分析
163
+ - **渠道信息**:渠道概览指标
165
164
 
166
165
  ## 架构
167
166
 
@@ -0,0 +1,153 @@
1
+ import {
2
+ printError,
3
+ printOutput
4
+ } from "./chunk-KM57HI5B.js";
5
+ import {
6
+ clearMcpToken,
7
+ loadMcpTokenStore,
8
+ setMcpTokenManual,
9
+ validateMcpToken
10
+ } from "./chunk-5CCFSPAF.js";
11
+ import {
12
+ clearToken,
13
+ getAuthStatus,
14
+ getToken,
15
+ resolveHost,
16
+ setTokenManual,
17
+ validateToken
18
+ } from "./chunk-OVMQFFC2.js";
19
+ import {
20
+ loadConfig,
21
+ saveConfig
22
+ } from "./chunk-TMMUBSKW.js";
23
+
24
+ // src/commands/auth.ts
25
+ function registerAuth(program) {
26
+ const auth = program.command("auth").description("Authentication management");
27
+ auth.command("login").description("Login to AE (auto-extract token from Chrome on macOS)").action(async () => {
28
+ const host = resolveHost(program.opts().host);
29
+ if (!host) {
30
+ printError("config", "No AE host configured.", "Run: ae-cli config set-host");
31
+ process.exit(1);
32
+ }
33
+ try {
34
+ const token = await getToken(host);
35
+ process.stderr.write(`[ae-cli] Authenticated to ${host}
36
+ `);
37
+ printOutput({ authenticated: true, host, token: token.slice(0, 8) + "..." }, program.opts().format || "json");
38
+ } catch (err) {
39
+ printError("auth", err.message);
40
+ process.exit(1);
41
+ }
42
+ });
43
+ auth.command("set-token <token>").description("Manually set authentication token for active host").action(async (token) => {
44
+ const host = resolveHost(program.opts().host);
45
+ if (!host) {
46
+ printError("config", "No AE host configured.", "Run: ae-cli config set-host");
47
+ process.exit(1);
48
+ }
49
+ const config = loadConfig();
50
+ if (!config.hosts[host]) {
51
+ config.hosts[host] = { label: host };
52
+ if (!config.activeHost) {
53
+ config.activeHost = host;
54
+ }
55
+ saveConfig(config);
56
+ process.stderr.write(`[ae-cli] Config saved for ${host}
57
+ `);
58
+ printOutput({ saved: true, config }, program.opts().format || "json");
59
+ }
60
+ process.stderr.write(`[ae-cli] Validating token...
61
+ `);
62
+ const isValid = await validateToken(token, host);
63
+ if (!isValid) {
64
+ process.stderr.write(`[ae-cli] Token validation failed
65
+ `);
66
+ printError("auth", "Invalid token", "Please check your token and try again");
67
+ process.exit(1);
68
+ }
69
+ setTokenManual(token, host);
70
+ process.stderr.write(`[ae-cli] Token verified and saved for ${host}
71
+ `);
72
+ printOutput({ saved: true, host, verified: true }, program.opts().format || "json");
73
+ });
74
+ auth.command("status").description("Show current authentication status").action(async () => {
75
+ const host = resolveHost(program.opts().host);
76
+ if (!host) {
77
+ printOutput({ authenticated: false, host: "(none)", hint: "Run: ae-cli config set-host" }, program.opts().format || "json");
78
+ return;
79
+ }
80
+ const tokenStatus = getAuthStatus(host);
81
+ const hasValidToken = tokenStatus.authenticated;
82
+ const mcpStore = loadMcpTokenStore();
83
+ const cachedMcpToken = mcpStore[host];
84
+ let hasValidMcpToken = false;
85
+ if (cachedMcpToken) {
86
+ hasValidMcpToken = await validateMcpToken(cachedMcpToken, host);
87
+ }
88
+ const authenticated = hasValidToken || hasValidMcpToken;
89
+ printOutput({ authenticated, host }, program.opts().format || "json");
90
+ });
91
+ auth.command("logout").description("Clear stored token for active host").action(() => {
92
+ const host = resolveHost(program.opts().host);
93
+ if (!host) {
94
+ printError("config", "No AE host configured.", "Run: ae-cli config set-host");
95
+ process.exit(1);
96
+ }
97
+ clearToken(host);
98
+ process.stderr.write(`[ae-cli] Token cleared for ${host}
99
+ `);
100
+ printOutput({ cleared: true, host }, program.opts().format || "json");
101
+ });
102
+ auth.command("set-mcp-token <token>").description("Manually set MCP token for a host").option("--host <host>", "Target host URL (defaults to active host)").action(async (token, opts) => {
103
+ const host = opts.host || resolveHost(program.opts().host);
104
+ if (!host) {
105
+ printError("config", "No AE host configured.", "Use --host <url> or run: ae-cli config set-host");
106
+ process.exit(1);
107
+ }
108
+ const config = loadConfig();
109
+ if (!config.hosts[host]) {
110
+ config.hosts[host] = { label: host };
111
+ if (!config.activeHost) {
112
+ config.activeHost = host;
113
+ }
114
+ saveConfig(config);
115
+ process.stderr.write(`[ae-cli] Host config saved for ${host}
116
+ `);
117
+ }
118
+ process.stderr.write(`[ae-cli] Validating MCP token...
119
+ `);
120
+ const isValid = await validateMcpToken(token, host);
121
+ if (!isValid) {
122
+ process.stderr.write(`[ae-cli] MCP token validation failed
123
+ `);
124
+ printError("auth", "Invalid MCP token", "Please check your MCP token and try again");
125
+ process.exit(1);
126
+ }
127
+ setMcpTokenManual(token, host);
128
+ process.stderr.write(`[ae-cli] MCP token verified and saved for ${host}
129
+ `);
130
+ printOutput({ saved: true, host, verified: true, type: "mcp-token" }, program.opts().format || "json");
131
+ });
132
+ auth.command("clear-mcp-token").description("Clear stored MCP token for a host").option("--host <host>", "Target host URL (defaults to active host)").option("--all", "Clear MCP tokens for all hosts").action((opts) => {
133
+ if (opts.all) {
134
+ clearMcpToken();
135
+ process.stderr.write(`[ae-cli] All MCP tokens cleared
136
+ `);
137
+ printOutput({ cleared: true, type: "all-mcp-tokens" }, program.opts().format || "json");
138
+ return;
139
+ }
140
+ const host = opts.host || resolveHost(program.opts().host);
141
+ if (!host) {
142
+ printError("config", "No AE host configured.", "Use --host <url> or run: ae-cli config set-host");
143
+ process.exit(1);
144
+ }
145
+ clearMcpToken(host);
146
+ process.stderr.write(`[ae-cli] MCP token cleared for ${host}
147
+ `);
148
+ printOutput({ cleared: true, host }, program.opts().format || "json");
149
+ });
150
+ }
151
+ export {
152
+ registerAuth
153
+ };
@@ -5,9 +5,10 @@ import {
5
5
  loadToken,
6
6
  resolveHost,
7
7
  saveToken,
8
- setTokenManual
9
- } from "./chunk-UK6HO5O5.js";
10
- import "./chunk-EBFUVWIZ.js";
8
+ setTokenManual,
9
+ validateToken
10
+ } from "./chunk-OVMQFFC2.js";
11
+ import "./chunk-TMMUBSKW.js";
11
12
  export {
12
13
  clearToken,
13
14
  getAuthStatus,
@@ -15,5 +16,6 @@ export {
15
16
  loadToken,
16
17
  resolveHost,
17
18
  saveToken,
18
- setTokenManual
19
+ setTokenManual,
20
+ validateToken
19
21
  };
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  getToken
3
- } from "./chunk-UK6HO5O5.js";
3
+ } from "./chunk-OVMQFFC2.js";
4
4
  import {
5
+ forceMigrateFromFallback,
5
6
  getActiveHost,
6
7
  getConfigDir,
7
8
  safeJsonParse,
8
9
  safeReadJsonFile
9
- } from "./chunk-EBFUVWIZ.js";
10
+ } from "./chunk-TMMUBSKW.js";
10
11
 
11
12
  // src/core/mcp.ts
12
13
  import fs from "fs";
@@ -102,8 +103,60 @@ async function getMcpToken(hostOverride) {
102
103
  saveMcpTokenStore(updatedStore);
103
104
  return mcpToken;
104
105
  }
106
+ function clearMcpToken(hostUrl) {
107
+ const store = loadMcpTokenStore();
108
+ if (hostUrl) {
109
+ delete store[hostUrl];
110
+ } else {
111
+ for (const key of Object.keys(store)) {
112
+ delete store[key];
113
+ }
114
+ }
115
+ saveMcpTokenStore(store);
116
+ }
117
+ function setMcpTokenManual(token, hostUrl) {
118
+ const store = loadMcpTokenStore();
119
+ store[hostUrl] = token;
120
+ saveMcpTokenStore(store);
121
+ }
122
+ async function validateMcpToken(token, hostUrl) {
123
+ const mapping = getMcpMapping("analysis");
124
+ const base = hostUrl.replace(/\/+$/, "");
125
+ const url = `${base}/mcp/${mapping.componentName}/http/${mapping.mappingPath}`;
126
+ const requestId = 1;
127
+ const body = {
128
+ jsonrpc: JSONRPC_VERSION,
129
+ id: requestId,
130
+ method: "tools/list",
131
+ params: { _meta: { progressToken: requestId } }
132
+ };
133
+ const headers = {
134
+ "Content-Type": "application/json",
135
+ "Accept": "application/json, text/event-stream",
136
+ "mcp-protocol-version": MCP_PROTOCOL_VERSION,
137
+ "mcp-token": token
138
+ };
139
+ try {
140
+ const resp = await fetch(url, {
141
+ method: "POST",
142
+ headers,
143
+ body: JSON.stringify(body)
144
+ });
145
+ if (!resp.ok) {
146
+ return false;
147
+ }
148
+ const data = safeJsonParse(await resp.text());
149
+ if (data.error) {
150
+ return false;
151
+ }
152
+ return data.result?.tools !== void 0;
153
+ } catch {
154
+ return false;
155
+ }
156
+ }
105
157
  async function mcpRequest(url, method, params = {}, hostOverride) {
106
- const token = await getMcpToken(hostOverride);
158
+ const hostUrl = hostOverride || getActiveHost();
159
+ const token = await getMcpToken(hostUrl);
107
160
  const requestId = genRequestId();
108
161
  const paramsWithMeta = {
109
162
  ...params,
@@ -127,6 +180,25 @@ async function mcpRequest(url, method, params = {}, hostOverride) {
127
180
  body: JSON.stringify(body)
128
181
  });
129
182
  if (!resp.ok) {
183
+ const migrated = forceMigrateFromFallback();
184
+ if (migrated && migrated[hostUrl]) {
185
+ process.stderr.write(`[ae-cli] MCP token refreshed from fallback for ${hostUrl}
186
+ `);
187
+ headers["mcp-token"] = migrated[hostUrl];
188
+ const retryResp = await fetch(url, {
189
+ method: "POST",
190
+ headers,
191
+ body: JSON.stringify(body)
192
+ });
193
+ if (!retryResp.ok) {
194
+ throw new Error(`MCP HTTP error: ${retryResp.status} ${retryResp.statusText}`);
195
+ }
196
+ const retryData = safeJsonParse(await retryResp.text());
197
+ if (retryData.error) {
198
+ throw new Error(`MCP error: ${retryData.error.message || JSON.stringify(retryData.error)}`);
199
+ }
200
+ return retryData.result;
201
+ }
130
202
  throw new Error(`MCP HTTP error: ${resp.status} ${resp.statusText}`);
131
203
  }
132
204
  const data = safeJsonParse(await resp.text());
@@ -169,6 +241,10 @@ function parseMcpResult(result) {
169
241
  export {
170
242
  registerMcpMappings,
171
243
  resolveMcpUrl,
244
+ loadMcpTokenStore,
245
+ clearMcpToken,
246
+ setMcpTokenManual,
247
+ validateMcpToken,
172
248
  callMcpTool,
173
249
  parseMcpResult
174
250
  };
@@ -2,8 +2,9 @@ import {
2
2
  extractHostname,
3
3
  getActiveHost,
4
4
  getConfigDir,
5
+ safeJsonParse,
5
6
  safeReadJsonFile
6
- } from "./chunk-EBFUVWIZ.js";
7
+ } from "./chunk-TMMUBSKW.js";
7
8
 
8
9
  // src/core/auth.ts
9
10
  import fs from "fs";
@@ -22,6 +23,16 @@ function resolveHost(hostOverride) {
22
23
  if (hostOverride) return hostOverride;
23
24
  return getActiveHost();
24
25
  }
26
+ async function validateToken(token, hostUrl) {
27
+ const url = `${hostUrl}/v1/oauth/checkToken?accessToken=${token}`;
28
+ try {
29
+ const resp = await fetch(url, { method: "POST" });
30
+ const respJson = safeJsonParse(await resp.text());
31
+ return respJson?.return_code === 0;
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
25
36
  function loadAllTokens() {
26
37
  try {
27
38
  const legacyTokens = path.join(LEGACY_DIR, "tokens.json");
@@ -209,6 +220,7 @@ Options:
209
220
 
210
221
  export {
211
222
  resolveHost,
223
+ validateToken,
212
224
  loadToken,
213
225
  saveToken,
214
226
  clearToken,
@@ -17,11 +17,46 @@ import fs2 from "fs";
17
17
  import path from "path";
18
18
  var CONFIG_DIR = path.join(process.env.HOME || "", ".ae-cli");
19
19
  var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
20
+ var MCP_TOKENS_FILE = path.join(CONFIG_DIR, "mcp-tokens.json");
21
+ var FALLBACK_MCP_TOKEN_FILE = "/data/app/te_agent_ta/.ae-config/mcp-token.json";
20
22
  function ensureDir() {
21
23
  if (!fs2.existsSync(CONFIG_DIR)) fs2.mkdirSync(CONFIG_DIR, { recursive: true });
22
24
  }
25
+ function migrateFromFallback() {
26
+ if (!fs2.existsSync(FALLBACK_MCP_TOKEN_FILE) || fs2.existsSync(MCP_TOKENS_FILE)) {
27
+ return null;
28
+ }
29
+ return doMigrateFromFallback();
30
+ }
31
+ function forceMigrateFromFallback() {
32
+ if (!fs2.existsSync(FALLBACK_MCP_TOKEN_FILE)) {
33
+ return null;
34
+ }
35
+ return doMigrateFromFallback();
36
+ }
37
+ function doMigrateFromFallback() {
38
+ try {
39
+ const fallbackData = safeReadJsonFile(FALLBACK_MCP_TOKEN_FILE);
40
+ const tokenStore = {};
41
+ if (fallbackData && typeof fallbackData === "object" && !Array.isArray(fallbackData)) {
42
+ const url = fallbackData.url;
43
+ const token = fallbackData["mcp-token"];
44
+ if (url && token) {
45
+ tokenStore[url] = token;
46
+ }
47
+ }
48
+ if (Object.keys(tokenStore).length > 0) {
49
+ ensureDir();
50
+ fs2.writeFileSync(MCP_TOKENS_FILE, JSON.stringify(tokenStore, null, 2));
51
+ return tokenStore;
52
+ }
53
+ } catch {
54
+ }
55
+ return null;
56
+ }
23
57
  function loadConfig() {
24
58
  try {
59
+ const migratedTokens = migrateFromFallback();
25
60
  if (fs2.existsSync(CONFIG_FILE)) {
26
61
  const raw = safeReadJsonFile(CONFIG_FILE);
27
62
  if (raw.defaultHost && !raw.activeHost) {
@@ -31,6 +66,22 @@ function loadConfig() {
31
66
  }
32
67
  return raw;
33
68
  }
69
+ if (migratedTokens && Object.keys(migratedTokens).length > 0) {
70
+ const hosts = {};
71
+ for (const url of Object.keys(migratedTokens)) {
72
+ hosts[url] = { label: url };
73
+ process.stderr.write(`[ae-cli] Added host: ${url}
74
+ `);
75
+ }
76
+ const activeHost = Object.keys(migratedTokens)[0];
77
+ process.stderr.write(`[ae-cli] Active host set to: ${activeHost}
78
+ `);
79
+ process.stderr.write(`[ae-cli] MCP tokens migrated from ${FALLBACK_MCP_TOKEN_FILE}
80
+ `);
81
+ const config = { activeHost, hosts };
82
+ saveConfig(config);
83
+ return config;
84
+ }
34
85
  } catch (err) {
35
86
  console.error(`Error loading config: ${err.message}`);
36
87
  }
@@ -114,6 +165,7 @@ function extractHostname(fullUrl) {
114
165
  export {
115
166
  safeJsonParse,
116
167
  safeReadJsonFile,
168
+ forceMigrateFromFallback,
117
169
  loadConfig,
118
170
  saveConfig,
119
171
  getActiveHost,
@@ -2,10 +2,10 @@ import {
2
2
  clearToken,
3
3
  getToken,
4
4
  resolveHost
5
- } from "./chunk-UK6HO5O5.js";
5
+ } from "./chunk-OVMQFFC2.js";
6
6
  import {
7
7
  safeJsonParse
8
- } from "./chunk-EBFUVWIZ.js";
8
+ } from "./chunk-TMMUBSKW.js";
9
9
 
10
10
  // src/core/client.ts
11
11
  import WebSocket from "ws";
@@ -4,9 +4,9 @@ import {
4
4
  queryReportData,
5
5
  querySql,
6
6
  wsQuery
7
- } from "./chunk-OQ4XEG77.js";
8
- import "./chunk-UK6HO5O5.js";
9
- import "./chunk-EBFUVWIZ.js";
7
+ } from "./chunk-TOXRLDUP.js";
8
+ import "./chunk-OVMQFFC2.js";
9
+ import "./chunk-TMMUBSKW.js";
10
10
  export {
11
11
  httpGet,
12
12
  httpPost,
@@ -1,14 +1,17 @@
1
1
  import {
2
+ clearToken,
2
3
  getAuthStatus,
3
- getToken
4
- } from "./chunk-UK6HO5O5.js";
4
+ getToken,
5
+ loadToken,
6
+ validateToken
7
+ } from "./chunk-OVMQFFC2.js";
5
8
  import {
6
9
  addHost,
7
10
  listHosts,
8
11
  removeHost,
9
12
  setActiveHost,
10
13
  updateHostLabel
11
- } from "./chunk-EBFUVWIZ.js";
14
+ } from "./chunk-TMMUBSKW.js";
12
15
 
13
16
  // src/commands/config.ts
14
17
  import * as readline from "readline";
@@ -136,9 +139,21 @@ Delete \x1B[1m${label}\x1B[0m (${url})? [y/N]: `, (a) => {
136
139
  async function ensureAuth(hostUrl) {
137
140
  const status = getAuthStatus(hostUrl);
138
141
  if (status.authenticated) {
139
- process.stderr.write(`\x1B[32m\u2713\x1B[0m Token valid for ${hostUrl}
142
+ const cached = loadToken(hostUrl);
143
+ if (cached && cached.token) {
144
+ process.stderr.write(`\x1B[2m[ae-cli] Validating token...\x1B[0m
140
145
  `);
141
- return;
146
+ const isValid = await validateToken(cached.token, hostUrl);
147
+ if (isValid) {
148
+ process.stderr.write(`\x1B[32m\u2713\x1B[0m Token valid for ${hostUrl}
149
+ `);
150
+ return;
151
+ } else {
152
+ clearToken(hostUrl);
153
+ process.stderr.write(`\x1B[33m!\x1B[0m Token expired or invalid. Re-authenticating...
154
+ `);
155
+ }
156
+ }
142
157
  }
143
158
  process.stderr.write(`
144
159
  \x1B[33m!\x1B[0m No valid token for ${hostUrl}. Starting login...