@thinkingai/ae-cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +229 -0
- package/bin/ae-cli.js +2 -0
- package/dist/auth-JXELJNDS.js +19 -0
- package/dist/auth-L3G3A74I.js +67 -0
- package/dist/chunk-3GM5LJZR.js +145 -0
- package/dist/chunk-JD5DXMKL.js +172 -0
- package/dist/chunk-KM57HI5B.js +107 -0
- package/dist/chunk-OVQOK35G.js +108 -0
- package/dist/chunk-RJNLN3KQ.js +217 -0
- package/dist/client-5QSQBBDB.js +16 -0
- package/dist/community-GMALVSRF.js +684 -0
- package/dist/config-Q7J3Z7Z2.js +242 -0
- package/dist/index.js +277 -0
- package/dist/raw-ZNVURYMR.js +59 -0
- package/dist/te-analysis-7NN3SY3I.js +871 -0
- package/dist/te-audience-P43BWMHM.js +350 -0
- package/dist/te-common-H3IPTI2I.js +144 -0
- package/dist/te-dataops-WCGDBJLF.js +1853 -0
- package/dist/te-engage-UTRVNTGU.js +1470 -0
- package/dist/te-meta-HGYNXVGF.js +479 -0
- package/package.json +53 -0
- package/skills/te-analysis/SKILL.md +107 -0
- package/skills/te-analysis/references/build-entity-details-sql.md +58 -0
- package/skills/te-analysis/references/build-event-details-sql.md +61 -0
- package/skills/te-analysis/references/create-alert.md +47 -0
- package/skills/te-analysis/references/create-dashboard.md +49 -0
- package/skills/te-analysis/references/create-or-update-dashboard-note.md +39 -0
- package/skills/te-analysis/references/create-public-access-link.md +43 -0
- package/skills/te-analysis/references/create-report.md +60 -0
- package/skills/te-analysis/references/create-result-cluster.md +73 -0
- package/skills/te-analysis/references/drilldown-user-events.md +72 -0
- package/skills/te-analysis/references/drilldown-users.md +75 -0
- package/skills/te-analysis/references/get-alert-definition-schema.md +32 -0
- package/skills/te-analysis/references/get-alert.md +31 -0
- package/skills/te-analysis/references/get-analysis-query-schema.md +36 -0
- package/skills/te-analysis/references/get-filter-schema.md +33 -0
- package/skills/te-analysis/references/get-groupby-schema.md +33 -0
- package/skills/te-analysis/references/get-report-definition.md +33 -0
- package/skills/te-analysis/references/get-table-columns.md +38 -0
- package/skills/te-analysis/references/list-alerts.md +33 -0
- package/skills/te-analysis/references/list-dashboards.md +33 -0
- package/skills/te-analysis/references/list-public-access-links.md +31 -0
- package/skills/te-analysis/references/list-reports.md +33 -0
- package/skills/te-analysis/references/load-filters.md +44 -0
- package/skills/te-analysis/references/query-adhoc.md +71 -0
- package/skills/te-analysis/references/query-dashboard-detail.md +35 -0
- package/skills/te-analysis/references/query-dashboard-report-data.md +60 -0
- package/skills/te-analysis/references/query-entity-details.md +60 -0
- package/skills/te-analysis/references/query-event-details.md +63 -0
- package/skills/te-analysis/references/query-report-data.md +65 -0
- package/skills/te-analysis/references/update-alert.md +49 -0
- package/skills/te-analysis/references/update-dashboard.md +45 -0
- package/skills/te-analysis/references/update-public-access-link.md +41 -0
- package/skills/te-audience/SKILL.md +63 -0
- package/skills/te-audience/references/create-cluster.md +65 -0
- package/skills/te-audience/references/create-tag.md +60 -0
- package/skills/te-audience/references/get-cluster-definition-schema.md +37 -0
- package/skills/te-audience/references/get-clusters-by-name.md +32 -0
- package/skills/te-audience/references/get-tag-definition-schema.md +32 -0
- package/skills/te-audience/references/get-tags-by-name.md +32 -0
- package/skills/te-audience/references/list-cluster-members.md +35 -0
- package/skills/te-audience/references/list-clusters.md +32 -0
- package/skills/te-audience/references/list-tag-members.md +36 -0
- package/skills/te-audience/references/list-tags.md +32 -0
- package/skills/te-audience/references/refresh-cluster.md +31 -0
- package/skills/te-audience/references/refresh-tag.md +31 -0
- package/skills/te-audience/references/update-cluster.md +59 -0
- package/skills/te-audience/references/update-tag.md +60 -0
- package/skills/te-common/SKILL.md +135 -0
- package/skills/te-common/references/get-resource-url.md +32 -0
- package/skills/te-common/references/list-projects.md +37 -0
- package/skills/te-community/SKILL.md +133 -0
- package/skills/te-community/references/community-activity-analysis.md +68 -0
- package/skills/te-community/references/community-analyzing-official-content.md +72 -0
- package/skills/te-community/references/community-analyzing-theme-comment.md +124 -0
- package/skills/te-community/references/community-character-analysis.md +71 -0
- package/skills/te-community/references/community-daily-report.md +82 -0
- package/skills/te-community/references/community-hottopic-insight.md +120 -0
- package/skills/te-community/references/community-release-analysis.md +79 -0
- package/skills/te-community/references/community-weekly-report.md +84 -0
- package/skills/te-community/references/get_channel_info.md +21 -0
- package/skills/te-community/references/get_comment_tag_analysis.md +30 -0
- package/skills/te-community/references/get_comments_summary.md +33 -0
- package/skills/te-community/references/get_corpus_tags.md +21 -0
- package/skills/te-community/references/get_daily_summary.md +23 -0
- package/skills/te-community/references/get_hot_topics.md +26 -0
- package/skills/te-community/references/get_livestream_analysis.md +23 -0
- package/skills/te-community/references/get_livestream_detail.md +34 -0
- package/skills/te-community/references/get_livestream_list.md +26 -0
- package/skills/te-community/references/get_livestream_overview.md +25 -0
- package/skills/te-community/references/get_livestream_room_metrics.md +26 -0
- package/skills/te-community/references/get_livestream_rooms.md +26 -0
- package/skills/te-community/references/get_overview_metrics.md +26 -0
- package/skills/te-community/references/get_post_detail.md +38 -0
- package/skills/te-community/references/get_risk_content.md +43 -0
- package/skills/te-community/references/get_sentiment_overview.md +34 -0
- package/skills/te-community/references/get_tag_trends.md +28 -0
- package/skills/te-community/references/get_topic_detail.md +27 -0
- package/skills/te-community/references/search_posts.md +48 -0
- package/skills/te-dataops/SKILL.md +645 -0
- package/skills/te-dataops/references/dataops-flow-create.md +163 -0
- package/skills/te-dataops/references/dataops-flow-monitor.md +118 -0
- package/skills/te-dataops/references/dataops-integration.md +246 -0
- package/skills/te-dataops/references/dataops-operations.md +107 -0
- package/skills/te-dataops/references/dataops-query.md +111 -0
- package/skills/te-dataops/references/dataops-table.md +122 -0
- package/skills/te-engage/SKILL.md +211 -0
- package/skills/te-engage/references/add-approver.md +24 -0
- package/skills/te-engage/references/add-channel.md +74 -0
- package/skills/te-engage/references/approver-list.md +19 -0
- package/skills/te-engage/references/cancel-query-by-request-id.md +23 -0
- package/skills/te-engage/references/channel-detail.md +52 -0
- package/skills/te-engage/references/channel-list.md +41 -0
- package/skills/te-engage/references/config-channel-detail.md +32 -0
- package/skills/te-engage/references/config-channel-list.md +27 -0
- package/skills/te-engage/references/config-item-analysis-report.md +34 -0
- package/skills/te-engage/references/config-item-detail.md +30 -0
- package/skills/te-engage/references/config-item-list.md +19 -0
- package/skills/te-engage/references/config-item-strategy-comparison.md +25 -0
- package/skills/te-engage/references/config-item-trigger-report.md +42 -0
- package/skills/te-engage/references/copy-config-template.md +29 -0
- package/skills/te-engage/references/delete-channel.md +24 -0
- package/skills/te-engage/references/delete-config-channel.md +24 -0
- package/skills/te-engage/references/delete-config-item.md +25 -0
- package/skills/te-engage/references/delete-flow.md +24 -0
- package/skills/te-engage/references/flow-ab-split-node-report.md +54 -0
- package/skills/te-engage/references/flow-detail.md +79 -0
- package/skills/te-engage/references/flow-list.md +19 -0
- package/skills/te-engage/references/flow-node-config-schema.md +44 -0
- package/skills/te-engage/references/flow-node-detail-report.md +55 -0
- package/skills/te-engage/references/flow-node-overview-report.md +52 -0
- package/skills/te-engage/references/flow-process-report.md +59 -0
- package/skills/te-engage/references/manage-flow.md +94 -0
- package/skills/te-engage/references/manage-strategy.md +74 -0
- package/skills/te-engage/references/manage-task.md +37 -0
- package/skills/te-engage/references/modify-flow-base-info.md +27 -0
- package/skills/te-engage/references/save-flow.md +870 -0
- package/skills/te-engage/references/strategy-detail.md +73 -0
- package/skills/te-engage/references/strategy-list.md +21 -0
- package/skills/te-engage/references/task-data-detail.md +81 -0
- package/skills/te-engage/references/task-data-overview.md +48 -0
- package/skills/te-engage/references/task-detail.md +61 -0
- package/skills/te-engage/references/task-experiment-report.md +51 -0
- package/skills/te-engage/references/task-list.md +91 -0
- package/skills/te-engage/references/task-metric-detail.md +56 -0
- package/skills/te-engage/references/task-stats.md +89 -0
- package/skills/te-engage/references/update-channel-status.md +32 -0
- package/skills/te-engage/references/update-config-channel-status.md +32 -0
- package/skills/te-engage/references/validate-flow-node-config.md +52 -0
- package/skills/te-engage/references/whitelist-list.md +19 -0
- package/skills/te-meta/SKILL.md +71 -0
- package/skills/te-meta/references/batch-create-metadata.md +37 -0
- package/skills/te-meta/references/batch-edit-metadata.md +36 -0
- package/skills/te-meta/references/create-metric.md +62 -0
- package/skills/te-meta/references/create-project-mark-time.md +38 -0
- package/skills/te-meta/references/create-virtual-event.md +64 -0
- package/skills/te-meta/references/create-virtual-property.md +69 -0
- package/skills/te-meta/references/delete-project-mark-times.md +34 -0
- package/skills/te-meta/references/delete-track-items.md +35 -0
- package/skills/te-meta/references/get-metric.md +32 -0
- package/skills/te-meta/references/get-project-config.md +32 -0
- package/skills/te-meta/references/get-track-program.md +31 -0
- package/skills/te-meta/references/list-entities.md +34 -0
- package/skills/te-meta/references/list-events.md +33 -0
- package/skills/te-meta/references/list-metrics.md +33 -0
- package/skills/te-meta/references/list-project-mark-times.md +33 -0
- package/skills/te-meta/references/list-project-users.md +32 -0
- package/skills/te-meta/references/list-properties.md +35 -0
- package/skills/te-meta/references/save-track-items.md +34 -0
- package/skills/te-meta/references/update-metric.md +61 -0
- package/skills/te-meta/references/update-project-mark-time.md +39 -0
- package/skills/te-shared/SKILL.md +115 -0
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# ae-cli
|
|
2
|
+
|
|
3
|
+
CLI tool for ThinkingAI AgenticEngine (AE) platform. Designed for both AI Agent and human use.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
**Step 1: Install ae-cli**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @thinkingai/ae-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Step 2: Install AI Agent Skills**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx skills add ThinkingAIAgenticEngine/ae-cli -g -y
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This installs 8 skill packages into your AI coding agent (Claude Code, Trae, Cursor, etc.), enabling the agent to understand and call ae-cli commands.
|
|
20
|
+
|
|
21
|
+
To update:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm cache clean --force && npm install -g @thinkingai/ae-cli
|
|
25
|
+
npx skills add ThinkingAIAgenticEngine/ae-cli -g -y
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# First run — interactive host setup + auto-login
|
|
32
|
+
ae-cli config
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The `config` command opens an interactive terminal UI:
|
|
36
|
+
- First run: prompts you to add a TE host URL and label, then auto-authenticates
|
|
37
|
+
- Subsequent runs: shows all configured hosts, lets you switch, edit, delete, or add new ones
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
TE Host Manager (↑↓ select · Enter switch · e edit label · d delete · a add · q quit)
|
|
41
|
+
|
|
42
|
+
❯ ● Production https://ta.thinkingdata.cn ✓
|
|
43
|
+
○ Staging https://ta-staging.example.com:8080 ✗
|
|
44
|
+
+ Add new host...
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
After selecting a host, ae-cli automatically checks if the token is valid. If not, it triggers `auth login` for you.
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# TE meta domain (metadata and governance)
|
|
53
|
+
ae-cli te_meta +list_events --project_id 1
|
|
54
|
+
|
|
55
|
+
# Table output
|
|
56
|
+
ae-cli te_meta +list_events --project_id 1 --format table
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Authentication
|
|
60
|
+
|
|
61
|
+
Authentication is handled per-host. Each TE host URL maintains its own token.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Auto-login for active host (macOS, extracts token from Chrome)
|
|
65
|
+
ae-cli auth login
|
|
66
|
+
|
|
67
|
+
# Manually set token
|
|
68
|
+
ae-cli auth set-token <your-token>
|
|
69
|
+
|
|
70
|
+
# Check status
|
|
71
|
+
ae-cli auth status
|
|
72
|
+
|
|
73
|
+
# Logout
|
|
74
|
+
ae-cli auth logout
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Commands
|
|
78
|
+
|
|
79
|
+
### Domains
|
|
80
|
+
|
|
81
|
+
| Domain | Commands | Description |
|
|
82
|
+
|--------|----------|-------------|
|
|
83
|
+
| `te_analysis` | 31 | Analysis workflows: alerts, reports, dashboards, ad-hoc/drilldown, clusters/tags, metadata/metrics, project tools, entity details, analysis schema |
|
|
84
|
+
| `te_audience` | 14 | Audience operations: clusters, tags, and cluster/tag definition schema |
|
|
85
|
+
| `te_meta` | 20 | Metadata governance: events/properties, metrics, virtual metadata, project config, tracking plan, mark times, resource links |
|
|
86
|
+
| `te_engage` | 40+ | Hermes Engage MCP: channels, tasks, configs, flows, strategies |
|
|
87
|
+
| `te_dataops` | 50+ | Data warehouse management: repos, datatables, flows, IDE queries, integration, operations |
|
|
88
|
+
| `te_community` | 30+ | Community analysis: posts search, sentiment analysis, topic trends, livestream data |
|
|
89
|
+
| `te_common` | 2 | Cross-module common constraints: resource link completion, project ID gate |
|
|
90
|
+
| `operation` | 11 | Tasks, flows, channels, space navigation |
|
|
91
|
+
|
|
92
|
+
### Global Options
|
|
93
|
+
|
|
94
|
+
| Option | Description | Default |
|
|
95
|
+
|--------|-------------|---------|
|
|
96
|
+
| `--host <url>` | Override active TE host URL | from config |
|
|
97
|
+
| `--format <json\|table>` | Output format | json |
|
|
98
|
+
| `--jq <expr>` | Filter expression | - |
|
|
99
|
+
| `--dry-run` | Preview request | false |
|
|
100
|
+
| `--yes` | Skip confirmation | false |
|
|
101
|
+
|
|
102
|
+
## Skills
|
|
103
|
+
|
|
104
|
+
8 AI Agent skill packages are included in the `skills/` directory:
|
|
105
|
+
|
|
106
|
+
| Skill | Description |
|
|
107
|
+
|-------|-------------|
|
|
108
|
+
| `te-shared` | Authentication, configuration, global options |
|
|
109
|
+
| `te-analysis` | Alerts, reports, dashboards, ad-hoc/drilldown, entity details, analysis schema |
|
|
110
|
+
| `te-audience` | Cluster and tag lifecycle management |
|
|
111
|
+
| `te-meta` | Metadata governance, project config, tracking plan, and resource link operations |
|
|
112
|
+
| `te-engage` | Hermes Engage MCP: channels, tasks, configs, flows, strategies |
|
|
113
|
+
| `te-dataops` | Data warehouse management, task flows, IDE queries, integration, operations |
|
|
114
|
+
| `te-community` | Community analysis: posts, comments, topics, livestreams |
|
|
115
|
+
| `te-common` | Cross-module constraints: project ID gate, resource link completion |
|
|
116
|
+
|
|
117
|
+
Install them with:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx skills add ThinkingAIAgenticEngine/ae-cli -g -y
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Skill Details
|
|
124
|
+
|
|
125
|
+
### te-analysis (31 tools)
|
|
126
|
+
|
|
127
|
+
Analysis query and visualization capabilities:
|
|
128
|
+
- **Alerts**: view, create, update alert definitions
|
|
129
|
+
- **Reports & Dashboards**: create, query, update reports and dashboards
|
|
130
|
+
- **Model Analysis**: event analysis, retention analysis, funnel analysis, SQL analysis, user property analysis, distribution analysis, interval analysis, path analysis, attribution analysis
|
|
131
|
+
- **Entity/Event Details**: query details, generate analysis SQL
|
|
132
|
+
- **Schema Helpers**: analysis query schema, filter schema, groupby schema
|
|
133
|
+
|
|
134
|
+
### te-audience (14 tools)
|
|
135
|
+
|
|
136
|
+
Audience operations and targeting:
|
|
137
|
+
- **Clusters**: create, update, query, member inspection, recomputation
|
|
138
|
+
- **Tags**: create, update, query, member inspection, recomputation
|
|
139
|
+
- **Schema Definitions**: cluster/tag definition schemas
|
|
140
|
+
|
|
141
|
+
### te-meta (20 tools)
|
|
142
|
+
|
|
143
|
+
Metadata and tracking-plan governance:
|
|
144
|
+
- **Metadata Governance**: events/properties, metrics, virtual metadata
|
|
145
|
+
- **Project Configuration**: project config, project users
|
|
146
|
+
- **Tracking Plans**: track program management
|
|
147
|
+
- **Mark Times**: date markers management
|
|
148
|
+
- **Entity Catalog**: entity listing
|
|
149
|
+
|
|
150
|
+
### te-engage (40+ tools)
|
|
151
|
+
|
|
152
|
+
Hermes Engage MCP capabilities:
|
|
153
|
+
- **Channels**: channel management, config channels, approval management
|
|
154
|
+
- **Tasks**: task list, task details, task data/metrics overview, experiment reports
|
|
155
|
+
- **Configs**: config items, strategies, strategy comparison, trigger/analysis reports
|
|
156
|
+
- **Flows**: flow creation, node config, flow reports, flow validation
|
|
157
|
+
|
|
158
|
+
### te-dataops (50+ tools)
|
|
159
|
+
|
|
160
|
+
Data warehouse management:
|
|
161
|
+
- **Repo Management**: spaces, catalogs, schemas, members
|
|
162
|
+
- **Data Tables**: table creation, views, batch operations, data dictionary
|
|
163
|
+
- **Task Flows**: flow creation, task nodes, scheduling, execution, monitoring
|
|
164
|
+
- **IDE Queries**: metadata browsing, SQL execution, query management
|
|
165
|
+
- **Integration**: datasource management, sync solutions, data synchronization
|
|
166
|
+
- **Operations**: flow instances, task instances, backfill jobs
|
|
167
|
+
|
|
168
|
+
### te-community (30+ tools)
|
|
169
|
+
|
|
170
|
+
Community social media analysis:
|
|
171
|
+
- **Posts**: search, detail, corpus tags
|
|
172
|
+
- **Comments**: sentiment analysis, tag analysis, summary
|
|
173
|
+
- **Topics**: hot topics, trends, daily summaries
|
|
174
|
+
- **Livestreams**: rooms, sessions, analysis, metrics
|
|
175
|
+
- **Advanced Analysis**: activity analysis, character analysis, weekly reports, release analysis
|
|
176
|
+
|
|
177
|
+
### te-common (2 tools)
|
|
178
|
+
|
|
179
|
+
Cross-module common constraints:
|
|
180
|
+
- **Project ID Gate**: mandatory project verification before execution
|
|
181
|
+
- **Resource Link Completion**: post-write link generation for dashboards, reports, metrics, alerts, clusters, tags
|
|
182
|
+
|
|
183
|
+
## Development
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
git clone https://github.com/ThinkingAIAgenticEngine/ae-cli.git
|
|
187
|
+
cd ae-cli
|
|
188
|
+
npm install
|
|
189
|
+
npx tsx src/index.ts --help
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Architecture
|
|
193
|
+
|
|
194
|
+
ae-cli is built with:
|
|
195
|
+
- **TypeScript** (~8000 lines of code)
|
|
196
|
+
- **Commander.js** for CLI framework
|
|
197
|
+
- **WebSocket** for MCP server integration
|
|
198
|
+
- **Node.js** runtime (v18+)
|
|
199
|
+
|
|
200
|
+
The project structure:
|
|
201
|
+
```
|
|
202
|
+
src/
|
|
203
|
+
├── core/ # Core modules: auth, config, client, mcp
|
|
204
|
+
├── framework/ # Framework: types, register, runner, output
|
|
205
|
+
├── api/ # Raw API access
|
|
206
|
+
└── commands/ # Domain-specific commands
|
|
207
|
+
├── auth.ts
|
|
208
|
+
├── config.ts
|
|
209
|
+
├── te-analysis/
|
|
210
|
+
├── te-audience/
|
|
211
|
+
├── te-meta/
|
|
212
|
+
├── te-engage/
|
|
213
|
+
├── te-dataops/
|
|
214
|
+
├── community/
|
|
215
|
+
└── te-common/
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Verification Scripts
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
npm run verify:te-analysis-tools
|
|
222
|
+
npm run verify:te-audience-tools
|
|
223
|
+
npm run verify:te-meta-tools
|
|
224
|
+
npm run verify:te-common-tools
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|
package/bin/ae-cli.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearToken,
|
|
3
|
+
getAuthStatus,
|
|
4
|
+
getToken,
|
|
5
|
+
loadToken,
|
|
6
|
+
resolveHost,
|
|
7
|
+
saveToken,
|
|
8
|
+
setTokenManual
|
|
9
|
+
} from "./chunk-RJNLN3KQ.js";
|
|
10
|
+
import "./chunk-OVQOK35G.js";
|
|
11
|
+
export {
|
|
12
|
+
clearToken,
|
|
13
|
+
getAuthStatus,
|
|
14
|
+
getToken,
|
|
15
|
+
loadToken,
|
|
16
|
+
resolveHost,
|
|
17
|
+
saveToken,
|
|
18
|
+
setTokenManual
|
|
19
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
printError,
|
|
3
|
+
printOutput
|
|
4
|
+
} from "./chunk-KM57HI5B.js";
|
|
5
|
+
import {
|
|
6
|
+
clearToken,
|
|
7
|
+
getAuthStatus,
|
|
8
|
+
getToken,
|
|
9
|
+
resolveHost,
|
|
10
|
+
setTokenManual
|
|
11
|
+
} from "./chunk-RJNLN3KQ.js";
|
|
12
|
+
import "./chunk-OVQOK35G.js";
|
|
13
|
+
|
|
14
|
+
// src/commands/auth.ts
|
|
15
|
+
function registerAuth(program) {
|
|
16
|
+
const auth = program.command("auth").description("Authentication management");
|
|
17
|
+
auth.command("login").description("Login to TE (auto-extract token from Chrome on macOS)").action(async () => {
|
|
18
|
+
const host = resolveHost(program.opts().host);
|
|
19
|
+
if (!host) {
|
|
20
|
+
printError("config", "No TE host configured.", "Run: ae-cli config set-host");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const token = await getToken(host);
|
|
25
|
+
process.stderr.write(`[ae-cli] Authenticated to ${host}
|
|
26
|
+
`);
|
|
27
|
+
printOutput({ authenticated: true, host, token: token.slice(0, 8) + "..." }, program.opts().format || "json");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
printError("auth", err.message);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
auth.command("set-token <token>").description("Manually set authentication token for active host").action((token) => {
|
|
34
|
+
const host = resolveHost(program.opts().host);
|
|
35
|
+
if (!host) {
|
|
36
|
+
printError("config", "No TE host configured.", "Run: ae-cli config set-host");
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
setTokenManual(token, host);
|
|
40
|
+
process.stderr.write(`[ae-cli] Token saved for ${host}
|
|
41
|
+
`);
|
|
42
|
+
printOutput({ saved: true, host }, program.opts().format || "json");
|
|
43
|
+
});
|
|
44
|
+
auth.command("status").description("Show current authentication status").action(() => {
|
|
45
|
+
const host = resolveHost(program.opts().host);
|
|
46
|
+
if (!host) {
|
|
47
|
+
printOutput({ authenticated: false, host: "(none)", hint: "Run: ae-cli config set-host" }, program.opts().format || "json");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const status = getAuthStatus(host);
|
|
51
|
+
printOutput(status, program.opts().format || "json");
|
|
52
|
+
});
|
|
53
|
+
auth.command("logout").description("Clear stored token for active host").action(() => {
|
|
54
|
+
const host = resolveHost(program.opts().host);
|
|
55
|
+
if (!host) {
|
|
56
|
+
printError("config", "No TE host configured.", "Run: ae-cli config set-host");
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
clearToken(host);
|
|
60
|
+
process.stderr.write(`[ae-cli] Token cleared for ${host}
|
|
61
|
+
`);
|
|
62
|
+
printOutput({ cleared: true, host }, program.opts().format || "json");
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
registerAuth
|
|
67
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearToken,
|
|
3
|
+
getToken,
|
|
4
|
+
resolveHost
|
|
5
|
+
} from "./chunk-RJNLN3KQ.js";
|
|
6
|
+
|
|
7
|
+
// src/core/client.ts
|
|
8
|
+
import WebSocket from "ws";
|
|
9
|
+
import { randomBytes } from "crypto";
|
|
10
|
+
function genRequestId(prefix) {
|
|
11
|
+
const rand = randomBytes(4).toString("base64url").slice(0, 8);
|
|
12
|
+
return `${prefix}@@${rand}`;
|
|
13
|
+
}
|
|
14
|
+
function buildUrl(baseUrl, modulePath, params = {}) {
|
|
15
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
16
|
+
const p = modulePath.startsWith("/") ? modulePath : `/${modulePath}`;
|
|
17
|
+
const url = new URL(`${base}${p}`);
|
|
18
|
+
for (const [k, v] of Object.entries(params)) {
|
|
19
|
+
if (v !== void 0 && v !== null) url.searchParams.set(k, String(v));
|
|
20
|
+
}
|
|
21
|
+
return url.toString();
|
|
22
|
+
}
|
|
23
|
+
function buildWsUrl(baseUrl, token) {
|
|
24
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
25
|
+
const wsBase = base.replace(/^https:\/\//, "wss://").replace(/^http:\/\//, "ws://");
|
|
26
|
+
return `${wsBase}/v1/ta-websocket/query/${token}`;
|
|
27
|
+
}
|
|
28
|
+
async function request(method, modulePath, params = {}, body = null, retry = true, hostUrl) {
|
|
29
|
+
const resolvedHost = resolveHost(hostUrl);
|
|
30
|
+
const token = await getToken(resolvedHost);
|
|
31
|
+
const url = buildUrl(resolvedHost, modulePath, params);
|
|
32
|
+
const headers = {
|
|
33
|
+
"Authorization": `bearer ${token}`,
|
|
34
|
+
"Content-Type": "application/json"
|
|
35
|
+
};
|
|
36
|
+
const options = { method, headers };
|
|
37
|
+
if (body && method !== "GET") options.body = JSON.stringify(body);
|
|
38
|
+
const resp = await fetch(url, options);
|
|
39
|
+
if ((resp.status === 401 || resp.status === 403) && retry) {
|
|
40
|
+
clearToken(resolvedHost);
|
|
41
|
+
return request(method, modulePath, params, body, false, resolvedHost);
|
|
42
|
+
}
|
|
43
|
+
const data = await resp.json();
|
|
44
|
+
if (data.return_code === -1001 && retry) {
|
|
45
|
+
clearToken(resolvedHost);
|
|
46
|
+
return request(method, modulePath, params, body, false, resolvedHost);
|
|
47
|
+
}
|
|
48
|
+
if (data.return_code !== 0 && data.return_code !== void 0) {
|
|
49
|
+
throw new Error(`TE API error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
50
|
+
}
|
|
51
|
+
return data.data !== void 0 ? data.data : data;
|
|
52
|
+
}
|
|
53
|
+
async function httpGet(modulePath, params = {}, hostUrl) {
|
|
54
|
+
return request("GET", modulePath, params, null, true, hostUrl);
|
|
55
|
+
}
|
|
56
|
+
async function httpPost(modulePath, params = {}, body, hostUrl) {
|
|
57
|
+
return request("POST", modulePath, params, body ?? {}, true, hostUrl);
|
|
58
|
+
}
|
|
59
|
+
async function wsQueryOnce(projectId, requestId, qp, eventModel, options = {}, token, hostUrl, timeoutMs = 3e4) {
|
|
60
|
+
const wsUrl = buildWsUrl(hostUrl, token);
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
const ws = new WebSocket(wsUrl);
|
|
63
|
+
const timer = setTimeout(() => {
|
|
64
|
+
ws.close();
|
|
65
|
+
reject(new Error(`WebSocket query timed out after ${timeoutMs}ms`));
|
|
66
|
+
}, timeoutMs);
|
|
67
|
+
ws.on("open", () => {
|
|
68
|
+
const payload = {
|
|
69
|
+
requestId,
|
|
70
|
+
projectId,
|
|
71
|
+
eventModel,
|
|
72
|
+
qp: typeof qp === "string" ? qp : JSON.stringify(qp),
|
|
73
|
+
searchSource: options.searchSource || "reportQuery",
|
|
74
|
+
querySource: options.querySource || "single_report",
|
|
75
|
+
contentTranslate: options.contentTranslate !== false,
|
|
76
|
+
...options.extra || {}
|
|
77
|
+
};
|
|
78
|
+
ws.send(JSON.stringify(["data", payload, { channel: "ta" }]));
|
|
79
|
+
});
|
|
80
|
+
ws.on("message", (raw) => {
|
|
81
|
+
try {
|
|
82
|
+
const msg = JSON.parse(raw.toString());
|
|
83
|
+
if (Array.isArray(msg) && msg.length >= 2) {
|
|
84
|
+
const data = msg[1];
|
|
85
|
+
if (data.requestId === requestId && data.progress === 100) {
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
ws.close();
|
|
88
|
+
resolve(data);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
ws.on("error", (err) => {
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
reject(err);
|
|
97
|
+
});
|
|
98
|
+
ws.on("close", () => {
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async function wsQuery(projectId, requestId, qp, eventModel, options = {}, hostUrl) {
|
|
104
|
+
const resolvedHost = resolveHost(hostUrl);
|
|
105
|
+
const token = await getToken(resolvedHost);
|
|
106
|
+
try {
|
|
107
|
+
return await wsQueryOnce(projectId, requestId, qp, eventModel, options, token, resolvedHost);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
const msg = err.message || "";
|
|
110
|
+
if (msg.includes("401") || msg.includes("403") || msg.includes("auth")) {
|
|
111
|
+
clearToken(resolvedHost);
|
|
112
|
+
const newToken = await getToken(resolvedHost);
|
|
113
|
+
return wsQueryOnce(projectId, requestId, qp, eventModel, options, newToken, resolvedHost);
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function querySql(projectId, sql, hostUrl) {
|
|
119
|
+
const requestId = genRequestId("sqlIde");
|
|
120
|
+
const qp = {
|
|
121
|
+
events: { sql },
|
|
122
|
+
eventView: { sqlViewParams: [] }
|
|
123
|
+
};
|
|
124
|
+
return wsQuery(projectId, requestId, qp, 10, {
|
|
125
|
+
searchSource: "sqlIde",
|
|
126
|
+
querySource: "sqlIde"
|
|
127
|
+
}, hostUrl);
|
|
128
|
+
}
|
|
129
|
+
async function queryReportData(projectId, reportId, qp, eventModel, options = {}, hostUrl) {
|
|
130
|
+
const dashboardId = options.dashboardId || 0;
|
|
131
|
+
const requestId = genRequestId(`${projectId}_${dashboardId}_${reportId}`);
|
|
132
|
+
return wsQuery(projectId, requestId, qp, eventModel, {
|
|
133
|
+
searchSource: options.searchSource || "model_search",
|
|
134
|
+
querySource: options.querySource || "module",
|
|
135
|
+
...options
|
|
136
|
+
}, hostUrl);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export {
|
|
140
|
+
httpGet,
|
|
141
|
+
httpPost,
|
|
142
|
+
wsQuery,
|
|
143
|
+
querySql,
|
|
144
|
+
queryReportData
|
|
145
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getToken
|
|
3
|
+
} from "./chunk-RJNLN3KQ.js";
|
|
4
|
+
import {
|
|
5
|
+
getActiveHost,
|
|
6
|
+
getConfigDir
|
|
7
|
+
} from "./chunk-OVQOK35G.js";
|
|
8
|
+
|
|
9
|
+
// src/core/mcp.ts
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
var MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
13
|
+
var JSONRPC_VERSION = "2.0";
|
|
14
|
+
var serviceMappingMap = /* @__PURE__ */ new Map();
|
|
15
|
+
registerMcpMapping("te_analysis", {
|
|
16
|
+
componentName: "analysis",
|
|
17
|
+
mappingPath: "analysis"
|
|
18
|
+
});
|
|
19
|
+
registerMcpMapping("te_analysis_extend", {
|
|
20
|
+
componentName: "analysis",
|
|
21
|
+
mappingPath: "analysis-extend"
|
|
22
|
+
});
|
|
23
|
+
function registerMcpMapping(serviceName, mapping) {
|
|
24
|
+
serviceMappingMap.set(serviceName, mapping);
|
|
25
|
+
}
|
|
26
|
+
function registerMcpMappings(mappings) {
|
|
27
|
+
for (const [serviceName, mapping] of Object.entries(mappings)) {
|
|
28
|
+
serviceMappingMap.set(serviceName, mapping);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getMcpMapping(serviceName) {
|
|
32
|
+
const mapping = serviceMappingMap.get(serviceName);
|
|
33
|
+
if (!mapping) {
|
|
34
|
+
throw new Error(`MCP mapping not found for service: '${serviceName}'. Please register it using registerMcpMapping() first.`);
|
|
35
|
+
}
|
|
36
|
+
return mapping;
|
|
37
|
+
}
|
|
38
|
+
function buildMcpUrl(host, serviceName) {
|
|
39
|
+
const mapping = getMcpMapping(serviceName);
|
|
40
|
+
const base = host.replace(/\/+$/, "");
|
|
41
|
+
return `${base}/mcp/${mapping.componentName}/http/${mapping.mappingPath}`;
|
|
42
|
+
}
|
|
43
|
+
function resolveMcpUrl(mcpUrlOverride, host, serviceName) {
|
|
44
|
+
if (mcpUrlOverride) {
|
|
45
|
+
return mcpUrlOverride;
|
|
46
|
+
}
|
|
47
|
+
return buildMcpUrl(host, serviceName);
|
|
48
|
+
}
|
|
49
|
+
var requestIdCounter = 1;
|
|
50
|
+
function genRequestId() {
|
|
51
|
+
return requestIdCounter++;
|
|
52
|
+
}
|
|
53
|
+
var MCP_TOKEN_FILE = path.join(getConfigDir(), "mcp-tokens.json");
|
|
54
|
+
var MCP_TOKEN_GENERATE_PATH = "/v1/ta/mcp/token/generate";
|
|
55
|
+
function loadMcpTokenStore() {
|
|
56
|
+
try {
|
|
57
|
+
if (fs.existsSync(MCP_TOKEN_FILE)) {
|
|
58
|
+
return JSON.parse(fs.readFileSync(MCP_TOKEN_FILE, "utf-8"));
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
function saveMcpTokenStore(store) {
|
|
65
|
+
const dir = getConfigDir();
|
|
66
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
67
|
+
fs.writeFileSync(MCP_TOKEN_FILE, JSON.stringify(store, null, 2));
|
|
68
|
+
}
|
|
69
|
+
async function generateMcpToken(hostUrl) {
|
|
70
|
+
const teToken = await getToken(hostUrl);
|
|
71
|
+
const base = hostUrl.replace(/\/+$/, "");
|
|
72
|
+
const url = `${base}${MCP_TOKEN_GENERATE_PATH}`;
|
|
73
|
+
const resp = await fetch(url, {
|
|
74
|
+
method: "GET",
|
|
75
|
+
headers: {
|
|
76
|
+
"Authorization": `bearer ${teToken}`
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
if (!resp.ok) {
|
|
80
|
+
throw new Error(`MCP token generate HTTP error: ${resp.status} ${resp.statusText}`);
|
|
81
|
+
}
|
|
82
|
+
const data = await resp.json();
|
|
83
|
+
if (data.return_code !== 0) {
|
|
84
|
+
throw new Error(`MCP token generate error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
85
|
+
}
|
|
86
|
+
const mcpToken = data.data?.userSecret;
|
|
87
|
+
if (!mcpToken) {
|
|
88
|
+
throw new Error("MCP token generate error: empty userSecret in response");
|
|
89
|
+
}
|
|
90
|
+
return mcpToken;
|
|
91
|
+
}
|
|
92
|
+
async function getMcpToken(hostOverride) {
|
|
93
|
+
const hostUrl = hostOverride || getActiveHost();
|
|
94
|
+
const store = loadMcpTokenStore();
|
|
95
|
+
if (store[hostUrl]) {
|
|
96
|
+
return store[hostUrl];
|
|
97
|
+
}
|
|
98
|
+
const mcpToken = await generateMcpToken(hostUrl);
|
|
99
|
+
const updatedStore = { ...store, [hostUrl]: mcpToken };
|
|
100
|
+
saveMcpTokenStore(updatedStore);
|
|
101
|
+
return mcpToken;
|
|
102
|
+
}
|
|
103
|
+
async function mcpRequest(url, method, params = {}, hostOverride) {
|
|
104
|
+
const token = await getMcpToken(hostOverride);
|
|
105
|
+
const requestId = genRequestId();
|
|
106
|
+
const paramsWithMeta = {
|
|
107
|
+
...params,
|
|
108
|
+
_meta: { progressToken: requestId }
|
|
109
|
+
};
|
|
110
|
+
const body = {
|
|
111
|
+
jsonrpc: JSONRPC_VERSION,
|
|
112
|
+
id: requestId,
|
|
113
|
+
method,
|
|
114
|
+
params: paramsWithMeta
|
|
115
|
+
};
|
|
116
|
+
const headers = {
|
|
117
|
+
"Content-Type": "application/json",
|
|
118
|
+
"Accept": "application/json, text/event-stream",
|
|
119
|
+
"mcp-protocol-version": MCP_PROTOCOL_VERSION,
|
|
120
|
+
"mcp-token": token
|
|
121
|
+
};
|
|
122
|
+
const resp = await fetch(url, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers,
|
|
125
|
+
body: JSON.stringify(body)
|
|
126
|
+
});
|
|
127
|
+
if (!resp.ok) {
|
|
128
|
+
throw new Error(`MCP HTTP error: ${resp.status} ${resp.statusText}`);
|
|
129
|
+
}
|
|
130
|
+
const data = await resp.json();
|
|
131
|
+
if (data.error) {
|
|
132
|
+
throw new Error(`MCP error: ${data.error.message || JSON.stringify(data.error)}`);
|
|
133
|
+
}
|
|
134
|
+
return data.result;
|
|
135
|
+
}
|
|
136
|
+
async function callMcpTool(url, toolName, args = {}, hostOverride) {
|
|
137
|
+
const params = {
|
|
138
|
+
name: toolName,
|
|
139
|
+
arguments: args
|
|
140
|
+
};
|
|
141
|
+
const result = await mcpRequest(url, "tools/call", params, hostOverride);
|
|
142
|
+
return {
|
|
143
|
+
content: result.content.map((item) => {
|
|
144
|
+
if (item.type === "text") {
|
|
145
|
+
return { type: "text", text: item.text };
|
|
146
|
+
} else if (item.type === "image") {
|
|
147
|
+
return { type: "image", data: item.data, mimeType: item.mimeType };
|
|
148
|
+
} else {
|
|
149
|
+
return { type: "resource", ...item };
|
|
150
|
+
}
|
|
151
|
+
}),
|
|
152
|
+
isError: result.isError
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function parseMcpResult(result) {
|
|
156
|
+
if (result.content.length > 0 && result.content[0].type === "text") {
|
|
157
|
+
const text = result.content[0].text || "";
|
|
158
|
+
try {
|
|
159
|
+
return JSON.parse(text);
|
|
160
|
+
} catch {
|
|
161
|
+
return text;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export {
|
|
168
|
+
registerMcpMappings,
|
|
169
|
+
resolveMcpUrl,
|
|
170
|
+
callMcpTool,
|
|
171
|
+
parseMcpResult
|
|
172
|
+
};
|