echopai 2.3.0 → 2.5.0

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 (54) hide show
  1. package/README.md +63 -348
  2. package/dist/bin.js +8388 -190
  3. package/package.json +11 -13
  4. package/dist/_generated/commands.js +0 -378
  5. package/dist/_generated/help.js +0 -295
  6. package/dist/_generated/operations.js +0 -2385
  7. package/dist/runtime/auth.js +0 -95
  8. package/dist/runtime/envelope.js +0 -52
  9. package/dist/runtime/errors.js +0 -186
  10. package/dist/runtime/filters.js +0 -153
  11. package/dist/runtime/format.js +0 -143
  12. package/dist/runtime/http.js +0 -65
  13. package/dist/runtime/idempotency.js +0 -18
  14. package/dist/runtime/invoker.js +0 -391
  15. package/dist/runtime/io.js +0 -16
  16. package/dist/runtime/paginator.js +0 -146
  17. package/dist/runtime/trace.js +0 -99
  18. package/dist/runtime/tty.js +0 -51
  19. package/dist/runtime/update_check.js +0 -120
  20. package/dist/runtime/update_worker.js +0 -63
  21. package/dist/runtime/verb_cmd.js +0 -72
  22. package/dist/runtime/verb_runner.js +0 -152
  23. package/dist/runtime/whoami_cache.js +0 -109
  24. package/dist/tools/api.js +0 -81
  25. package/dist/tools/completion.js +0 -116
  26. package/dist/tools/config.js +0 -123
  27. package/dist/tools/doctor.js +0 -183
  28. package/dist/tools/login.js +0 -99
  29. package/dist/tools/mcp.js +0 -141
  30. package/dist/tools/raw.js +0 -96
  31. package/dist/tools/schema.js +0 -58
  32. package/dist/tools/trace.js +0 -54
  33. package/dist/tools/upgrade.js +0 -103
  34. package/dist/tools/welcome.js +0 -225
  35. package/dist/tools/whoami.js +0 -132
  36. package/dist/verbs/_spec.js +0 -15
  37. package/dist/verbs/announcements.js +0 -195
  38. package/dist/verbs/bars_batch.js +0 -66
  39. package/dist/verbs/chart.js +0 -110
  40. package/dist/verbs/concepts.js +0 -393
  41. package/dist/verbs/digest.js +0 -351
  42. package/dist/verbs/financials.js +0 -212
  43. package/dist/verbs/hot.js +0 -29
  44. package/dist/verbs/index.js +0 -88
  45. package/dist/verbs/limit_up.js +0 -156
  46. package/dist/verbs/lookup.js +0 -72
  47. package/dist/verbs/market.js +0 -185
  48. package/dist/verbs/news.js +0 -81
  49. package/dist/verbs/quote.js +0 -53
  50. package/dist/verbs/scan.js +0 -42
  51. package/dist/verbs/search.js +0 -105
  52. package/dist/verbs/sentiment.js +0 -231
  53. package/dist/verbs/views.js +0 -85
  54. package/dist/version.js +0 -5
package/README.md CHANGED
@@ -1,398 +1,113 @@
1
1
  # echopai
2
2
 
3
- > **v2.0.0**: npm package renamed from `@echopai/cli` → `echopai` to match
4
- > the binary name. The scoped package has been unpublished — update your
5
- > installer to `npm install -g echopai`.
6
-
7
- Command-line interface for the EchoPai Open Platform. Programmatic access
8
- to stock-market data, news, analyst views, sentiment indicators, signals,
9
- and backtests over `https://api.echopai.com`.
10
-
11
- ## Features
12
-
13
- - **11 curated agent verbs** at the top level (`lookup`, `digest`, `quote`,
14
- `views`, `research`, `news`, `sentiment`, `hot`, `chart`, `bars-batch`,
15
- `scan`) with task-level defaults, agent-ready outputs, and product-priority
16
- encoding (`views` is the PRIMARY research source; `news` is supplementary).
17
- - **`digest`**: one HTTP call returns views + research-entity performance +
18
- quote + sentiment + news for a single security; server-side composite
19
- with `meta.partial_failures[]` tolerance; falls back to client-side
20
- fan-out if `/v1/digest/{code}` is rolling.
21
- - **Built-in MCP stdio server** (`echopai mcp serve`) exposing curated verbs
22
- to Claude Desktop / Cursor / Claude Code; `tools/list` filtered to the
23
- subset your token can actually call.
24
- - **37 OpenAPI operations as raw mirror** under `echopai raw <noun> <verb>`,
25
- auto-generated from `docs/api-contract/openapi.yaml`.
26
- - **Capability introspection** — `echopai whoami` (token kind / scopes /
27
- available verbs / rate limits) + `echopai doctor` (3-state diagnostics).
28
- - **Write safety** — non-TTY writes refuse without `--yes`
29
- (`confirmation_required`); `--dry-run` sends `X-Dry-Run: 1` for ops the
30
- server advertises support for; auto `Idempotency-Key` UUIDv4 on every
31
- `x-idempotency-required: true` endpoint.
32
- - **Local trace** — `~/.echopai/trace.ndjson` (50 MB ring buffer);
33
- `echopai trace tail` / `trace get <request_id>` for post-hoc inspection.
34
- - **JSON-first I/O** — JSON envelope on stdout, JSON error on stderr,
35
- three-state exit codes (0 / 1 / 2); six output formats
36
- (`json` / `ndjson` / `table` / `csv` / `tsv` / `yaml`).
37
- - **JMESPath filter** — global `--jq <expr>`, `--fields`, `--max-bytes`
38
- for shaping responses without piping to `jq`.
39
- - **Pagination** — `--all` for cursor/offset endpoints, bounded by
40
- `--max-pages` / `--max-items`.
41
- - **Multi-profile config** TOML at `~/.config/echopai/config.toml` (mode 0600).
42
- - **Shell completion** for bash / zsh / fish.
43
-
44
- ## Requirements
45
-
46
- Node.js 20 or later.
47
-
48
- ## Installation
3
+ Command-line interface for the [EchoPai Open Platform](https://echopai.com).
4
+ Programmatic access to A-share stock-market data, news, analyst views,
5
+ sentiment, financials, concepts, limit-up board, announcements, and digest
6
+ fan-out over `https://api.echopai.com`.
49
7
 
50
- ```bash
51
- npm install -g echopai
52
- echopai --version
53
- ```
54
-
55
- Or invoke without installation:
56
-
57
- ```bash
58
- npx -y echopai market status
59
- ```
60
-
61
- ## Authentication
8
+ AI-first: JSON envelope on stdout, JSON error envelope on stderr, three-state
9
+ exit codes suitable for scripts, CI pipelines, Claude Desktop / Cursor /
10
+ Claude Code MCP integration, and agent loops.
62
11
 
63
- Credentials take the form `eps_live_<lookup>_<secret>` and are issued via the
64
- EchoPai admin console.
12
+ ## Install
65
13
 
66
- Resolution order (highest precedence first):
14
+ Two ways pick whichever fits.
67
15
 
68
- 1. `ECHOPAI_KEY` environment variable
69
- 2. `--profile <name>` flag (on subcommands that accept it)
70
- 3. Default profile in `~/.config/echopai/config.toml`
71
-
72
- Persist a credential locally:
16
+ **A. npm (Node.js 20+)**
73
17
 
74
18
  ```bash
75
- echopai login --key eps_live_<lookup>_<secret>
76
- echopai status
19
+ npm install -g echopai
20
+ echopai --version
77
21
  ```
78
22
 
79
- Manage multiple profiles:
23
+ Or run without installing:
80
24
 
81
25
  ```bash
82
- echopai config profile add prod \
83
- --key eps_live_<lookup>_<secret> \
84
- --base-url https://api.echopai.com
85
- echopai config profile switch prod
86
- echopai config profile list
26
+ npx -y echopai market status
87
27
  ```
88
28
 
89
- ## AI agent integration (MCP)
29
+ **B. Standalone binary (no Node required) — 一键安装**
90
30
 
91
- The CLI doubles as a Model Context Protocol (MCP) stdio server, exposing
92
- curated agent verbs as MCP tools to Claude Desktop, Cursor, Claude Code, or
93
- any MCP-compatible host. The server filters its `tools/list` to the subset
94
- your token can actually call (intersection of curated-verb scopes with token
95
- scopes).
96
-
97
- Run as an MCP server:
31
+ 自带 Bun runtime,无需 Node。安装器自动判平台(AVX2→baseline / musl / Rosetta)并
32
+ 强制 sha256 校验:
98
33
 
99
34
  ```bash
100
- ECHOPAI_KEY=eps_live_... echopai mcp serve
101
- ```
102
-
103
- Claude Desktop / Cursor / Claude Code config (`~/.config/claude/...` or
104
- equivalent):
105
-
106
- ```json
107
- {
108
- "mcpServers": {
109
- "echopai": {
110
- "command": "echopai",
111
- "args": ["mcp", "serve"],
112
- "env": {
113
- "ECHOPAI_KEY": "eps_live_<lookup>_<secret>"
114
- }
115
- }
116
- }
117
- }
35
+ curl -fsSL https://downloads.echopai.com/echopai-cli-releases/install.sh | bash
36
+ # 指定版本:
37
+ curl -fsSL https://downloads.echopai.com/echopai-cli-releases/install.sh | bash -s -- 2.4.0
118
38
  ```
119
39
 
120
- Available MCP tools (subset shown to LLM depends on token scopes):
121
-
122
- | Tool | Purpose | Backing API |
123
- |---|---|---|
124
- | `lookup` | Resolve Chinese name / code / pinyin → canonical_code | `semantic.find` |
125
- | `digest` | One-shot research digest: 5 buckets in one call | `digest.get` + fan-out fallback |
126
- | `quote` | Real-time quote for 1-200 codes | `quote` |
127
- | `views` | **PRIMARY** research source (analyst views w/ entity attribution) | `views.recent` |
128
- | `news` | **SUPPLEMENTARY** news / market briefs | `news.search` / `news.feed` |
129
- | `sentiment` | Aggregate market sentiment | `sentiment.overview` |
130
- | `hot` | Today's hot-stock leaderboard | `stocks.hot` |
131
- | `chart` | Single-security K-line (daily / minute) | `bars.daily` / `bars.minute` |
132
- | `bars_batch` | Batch K-line (≤100 codes × 1yr daily; ≤20 × 7d minute) | `bars.daily-batch` / `bars.minute-batch` |
133
- | `scan` | Full-market quote snapshot (~5800 securities) | `quote.scan` |
134
- | `financials_quote_snapshot` | **Headline** valuation snapshot (PE / PB / PS / 换手率 / 股息率 / 量比 14 fields, TDX + Sina 自算) | `financials.quote-snapshot` |
135
- | `financials_pit` | Point-in-time financial indicators at a given trade_date (anti-future-fn for backtests) | `financials.pit` |
136
- | `financials_reports` | Last N report-period snapshots (~25 fields × period, filter by Q1/H1/Q3/annual) | `financials.reports` |
137
- | `financials_series` | Time series of a single financial metric across report periods | `financials.series` |
138
-
139
- The agent should prefer `views` over `news` when forming an investment
140
- opinion (views carries research-entity attribution; news is breadth-only).
141
-
142
- The MCP transport sends `X-Client-Channel: mcp` upstream so server-side
143
- audit / per-channel rate limiting can distinguish MCP traffic from CLI.
144
-
145
- ## Common usage
146
-
147
- ```bash
148
- # Market session state
149
- echopai market status
150
-
151
- # Real-time quotes (CSV codes)
152
- echopai quote --codes "SSE:600519,SZSE:000001"
153
-
154
- # News search with table output
155
- echopai news search --query "AI" --since-hours 24 --output table
156
-
157
- # Daily bars for a security over a date range
158
- echopai chart --code SSE:600519 --from 2026-01-01 --to 2026-05-01
159
-
160
- # Iterate all pages of analyst views (NDJSON one item per line)
161
- echopai raw views feed --since-days 7 --all | jq '.title'
40
+ 默认装到 `~/.local/bin/echopai`(可用 `ECHOPAI_INSTALL_DIR` 改)。Windows 用户手动下载
41
+ `echopai-windows-x64.exe`。平台矩阵、CDN 布局与发布流程见
42
+ [docs/CLI_RELEASE_AND_DISTRIBUTION.md](../docs/CLI_RELEASE_AND_DISTRIBUTION.md)。
162
43
 
163
- # One-shot research digest (server-side composite, 5 buckets, partial-failure tolerant)
164
- echopai digest --code SSE:600519
165
-
166
- # Headline valuation snapshot: 14 fields (PE / PB / PS / 换手率 / 股息率 / 量比 ...)
167
- echopai financials quote-snapshot --code SSE:600519
168
- echopai financials quote-snapshot --code SSE:600519 --date 2026-05-13 # historical
169
-
170
- # Deeper fundamentals
171
- echopai financials pit --code SSE:600519 --date 2024-11-01
172
- echopai financials reports --code SSE:600519 --kind annual --limit 5
173
- echopai financials series --code SSE:600519 --metric roe_simple
174
- ```
175
-
176
- ## Output formats
44
+ ## Auth
177
45
 
178
46
  ```bash
179
- echopai news search --query AI --output json # default; pretty in TTY
180
- echopai news search --query AI --output ndjson # one JSON object per line
181
- echopai news search --query AI --output table # ASCII table
182
- echopai news search --query AI --output csv # RFC-4180
183
- echopai news search --query AI --output tsv
184
- echopai news search --query AI --output yaml
185
- ```
186
-
187
- ## Pagination
188
-
189
- Endpoints that declare `x-cli-pagination: cursor|offset` accept `--all`:
47
+ # Save key to ~/.config/echopai/config.toml (mode 0600)
48
+ echopai login --key eps_live_<lookup>_<secret>
190
49
 
191
- ```bash
192
- echopai news feed --all --since-hours 168 | jq '.title'
193
- echopai news feed --all --max-pages 10 --max-items 500
50
+ # Or pass per-invocation via env (CI / agent)
51
+ ECHOPAI_KEY=eps_live_xxx echopai market status
194
52
  ```
195
53
 
196
- ## WebSocket streaming
197
-
198
- The CLI does **not** expose `/v1/ws/{news,views}` directly. Those upstream
199
- handlers gate on user-JWT JSON-auth, which is incompatible with the CLI's
200
- partner static-key bearer-subprotocol model. Partner SDKs that need WS
201
- should target the endpoints directly (the OpenAPI ops are still public);
202
- the CLI sticks to HTTP for now.
54
+ Get a key at the [EchoPai admin console](https://console.echopai.com).
203
55
 
204
- ## Write safety and dry-run
205
-
206
- Curated verbs are all read-only. The raw mirror surfaces a handful of
207
- writes (e.g. `agent.session-start`); these are gated:
56
+ ## Highlights
208
57
 
209
58
  ```bash
210
- # In a non-TTY (script / CI / agent), writes refuse without --yes:
211
- $ echo "" | echopai raw agent session-start --agent-id my-agent
212
- {"error":{"code":"confirmation_required","message":"Operation agent.session-start is a write (side-effect=write) and stdout is not a TTY. Pass --yes to confirm."}}
213
-
214
- # --dry-run sends X-Dry-Run:1 on ops the server advertises support for.
215
- # Useful for previewing what a write would do without persisting.
216
- echopai --yes --dry-run raw agent session-start --agent-id my-agent --budget-usd 1.0
217
-
218
- # --dry-run on a write op that doesn't advertise support → refused
219
- $ echopai --yes --dry-run raw agent session-end <session_id>
220
- {"error":{"code":"dry_run_unsupported","message":"..."}}
221
- ```
59
+ echopai lookup --text 贵州茅台 # 中文名 canonical_code
60
+ echopai digest --code SSE:600519 # 一键研究摘要(A 6 fan-out)
61
+ echopai digest --code HK:00700 # 港股/中概 digest(仅 views+news)
62
+ echopai quote --codes SSE:600519,SZSE:000001 # 1-200 只实时报价
63
+ echopai market movers --sort speed --top 20 # 3-min 涨速榜
64
+ echopai sentiment overview --date 2026-05-20 # 任意历史日的情绪聚合
65
+ echopai concepts alerts # 概念异动 (big_move / limit_up_cluster)
66
+ echopai limit-up summary # 涨停数 / 炸板数 / 连板梯队
67
+ echopai financials quote-snapshot --code SSE:600519 # PE/PB/PS/换手率/股息率 14 字段估值快照
222
68
 
223
- ## Channel enforcement
224
-
225
- Every outbound HTTP request carries `X-Client-Channel: cli` (or `mcp`
226
- when running under `echopai mcp serve`). Tokens may carry an
227
- `allowed_clients` JWT claim restricting which channels the token may use,
228
- plus `client_overrides` for per-channel `rate_limit_qps` tightening,
229
- `extra_scopes_deny`, or `read_only` on non-GET methods. Configure these
230
- on the credential when issuing through admin console.
231
-
232
- ## Idempotency
233
-
234
- For endpoints that declare `x-idempotency-required: true` (for example,
235
- `agent session-start`), the CLI generates a UUIDv4 `Idempotency-Key` and
236
- echoes it to stderr so it can be reused on retry:
237
-
238
- ```text
239
- $ echopai agent session-start
240
- [idempotency-key] agent.session-start: 7d8f2c00-3b9a-4f1d-8e2c-9c0a1b2d3e4f
241
- [idempotency-key] retry: pass --idempotency-key 7d8f2c00-... to dedupe.
242
- {"data":{"session_id":"sess_..."}}
243
- ```
244
-
245
- Provide an explicit key with `--idempotency-key <uuid>` to dedupe at the
246
- server.
247
-
248
- ## Exit codes
249
-
250
- | Code | Meaning |
251
- |------|---------|
252
- | 0 | Success |
253
- | 1 | User error (4xx, invalid arguments, authentication or scope failure) |
254
- | 2 | Service error (5xx, network failure, internal error) |
255
-
256
- Error envelope (single line on stderr):
257
-
258
- ```json
259
- {"error":{"code":"scope_insufficient","message":"...","recovery_hint":"...","request_id":"req_...","http_status":403}}
69
+ echopai mcp serve # 起 MCP stdio 服务给 Claude/Cursor
260
70
  ```
261
71
 
262
- In a TTY the same envelope is rendered as a coloured, multi-line message
263
- with the `recovery_hint` highlighted. Non-TTY environments (CI, pipelines)
264
- always receive single-line JSON.
72
+ `echopai welcome` 显示完整命令面板 + 鉴权状态。
265
73
 
266
- ## Global flags
74
+ ## Documentation
267
75
 
268
- | Flag | Description |
269
- |------|-------------|
270
- | `--debug` | Print HTTP wire trace to stderr; the bearer token is redacted |
271
- | `--raw` | Skip envelope unwrapping; emit the raw response body |
272
- | `--jq <expr>` | JMESPath transform applied to `data` (renamed from `--query` in v2.0 to avoid clashing with subcommand `--query` body params, e.g. `news.search`) |
273
- | `--fields <a,b,c>` | Keep only listed top-level fields per item |
274
- | `--max-bytes <n>` | Truncate serialised envelope; sets `meta.truncated=true` |
275
- | `--yes` | Confirm a write op in non-TTY mode (required for `sideEffect=write` ops) |
276
- | `--dry-run` | Send `X-Dry-Run: 1` on writes where the server advertises support |
277
- | `--output <format>` | Override per-command default output format |
76
+ 📖 **[docs/CLI.md](https://github.com/evanzhangx/EchoPulse/blob/main/docs/CLI.md)**
77
+ —— install / auth / persona / verb 总览 / MCP / I/O 约定 / pagination /
78
+ write safety / 设计原则 / 版本号约定 全在这里。
278
79
 
279
- Profile and credential overrides are exposed on the relevant subcommands
280
- (`echopai status --profile <name>`, `echopai login --key ...`); they are
281
- intentionally not declared as global options to avoid conflicting with
282
- subcommand parameters of the same name.
283
-
284
- ## Schema introspection
285
-
286
- ```bash
287
- echopai schema list # one line per command (cliKey, method, path, summary)
288
- echopai schema get news.search
289
- echopai schema export # full surface as NDJSON, including JSON Schemas
290
- ```
291
-
292
- ## Raw HTTP passthrough
293
-
294
- For arbitrary requests (debugging, unmirrored endpoints):
295
-
296
- ```bash
297
- echopai raw call GET /v1/some/path -q since_hours=24
298
- echopai raw call POST /v1/some/path -d '{"key":"value"}'
299
- ```
80
+ 📋 **[docs/partner-api/cli-reference.md](https://github.com/evanzhangx/EchoPulse/blob/main/docs/partner-api/cli-reference.md)**
81
+ —— 自动生成的完整 endpoint 参数表,每个 op inputSchema / scopes / 示例 /
82
+ 输出 schema。
300
83
 
301
- `echopai api call` is a deprecated alias of `raw call`; it will be removed
302
- in the next major.
84
+ 📝 **[CHANGELOG.md](./CHANGELOG.md)** —— 版本变更记录。
303
85
 
304
- ## Shell completion
86
+ ## Self-update
305
87
 
306
88
  ```bash
307
- echopai completion bash > ~/.local/share/bash-completion/completions/echopai
308
- echopai completion zsh > "${fpath[1]}/_echopai"
309
- echopai completion fish > ~/.config/fish/completions/echopai.fish
89
+ echopai upgrade # cache 命中即打印 npm i 命令(24h cache)
90
+ echopai upgrade --check # 强制刷 npm registry
91
+ echopai upgrade --exec # 真跑 npm i -g echopai@latest
310
92
  ```
311
93
 
312
- ## Architecture
313
-
314
- ```
315
- docs/api-contract/openapi.yaml (single source of truth)
316
-
317
- ▼ scripts/codegen/generate_cli_v2.py
318
- src/_generated/ (operations + command tree + help text)
319
-
320
-
321
- src/runtime/ (invoker, auth, http, envelope, errors, filters,
322
- trace, paginator, verb_runner, verb_cmd, whoami_cache)
323
-
324
-
325
- src/tools/ (login, status, config, raw, schema, completion,
326
- whoami, doctor, trace, mcp)
327
- src/verbs/ (lookup, digest, quote, views, research, news,
328
- sentiment, hot, chart, bars_batch, scan + _spec)
329
-
330
-
331
- src/bin.ts
332
- ```
333
-
334
- New raw mirror endpoints are added by setting `x-cli-key` (and optionally
335
- `x-cli-pagination`, `x-cli-output-default`) on the OpenAPI operation; the
336
- command tree is regenerated automatically. Curated verbs (`src/verbs/`)
337
- are hand-written task-level wrappers that can fan-out over multiple raw
338
- ops; each declares a `VerbSpec` shared by CLI and MCP entries.
94
+ CLI 启动时后台 detached 子进程检查 npm registry,下次启动若有新版本会在
95
+ stderr 打一行 dim banner。`ECHOPAI_DISABLE_UPDATE_CHECK=1` / `CI=1` 关掉。
339
96
 
340
97
  ## Development
341
98
 
342
- ```bash
343
- cd cli
344
- npm install
345
- npm run codegen # regenerate src/_generated/ from the OpenAPI spec
346
- npm test # vitest: codegen, runtime, paginator, idempotency, tools
347
- npx tsx src/bin.ts --help
348
-
349
- # Run against the staging environment
350
- ECHOPAI_BASE_URL=https://staging.echopai.com \
351
- ECHOPAI_KEY=eps_live_<lookup>_<secret> \
352
- npx tsx src/bin.ts news search --query AI --output table
353
-
354
- # HTTP wire trace (bearer redacted)
355
- npx tsx src/bin.ts market status --debug
356
- ```
357
-
358
- ## Releasing
359
-
360
- Two paths are supported. Both are documented in `docs/PLAN_CLI_V2_REWRITE.md`.
361
-
362
- ### Tag-triggered release (recommended)
363
-
364
- After a version bump is merged to `main`, push a tag named `cli-v<version>`:
99
+ 工具链是 [Bun](https://bun.sh)(install / test / build / compile 全用 bun;
100
+ codegen 仍是 Python)。npm 包产物 `dist/bin.js` 仍 node ≥20 兼容。
365
101
 
366
102
  ```bash
367
- git tag cli-v2.0.0
368
- git push origin cli-v2.0.0
103
+ bun install # 装依赖(bun.lock)
104
+ bun run dev -- --help # 直接跑 TS 源(含 codegen)
105
+ bun test # 跑测试(bun:test)
106
+ bun run typecheck # tsc --noEmit(仅 src)
107
+ bun run build # 产 node 兼容 dist/bin.js(bun build --target=node)
108
+ bun run compile # 产各平台 standalone 二进制到 dist/bin/
369
109
  ```
370
110
 
371
- `.github/workflows/release-cli.yml` builds, tests, runs `npm publish
372
- --access public --provenance`, and verifies the new version on the registry.
373
- The workflow requires a repository secret named `NPM_ACCESS_TOKEN` (an npm
374
- granular access token with the *Bypass 2FA* flag enabled).
375
-
376
- ### Local script
377
-
378
- For ad-hoc releases without GitHub Actions:
379
-
380
- ```bash
381
- bash scripts/publish-cli.sh # publish the current cli/package.json version
382
- bash scripts/publish-cli.sh --dry-run # inspect the tarball without publishing
383
- ```
384
-
385
- The script reads `NPM_ACCESS_TOKEN` from `server/.env`, writes it to a
386
- temporary `.npmrc` (mode 0600), invokes `npm publish`, then deletes the
387
- file via a shell `trap` (the token never appears on the command line).
388
-
389
- ## Links
390
-
391
- - Platform overview: `https://echopai.com`
392
- - Partner documentation: `docs/partner-api/`
393
- - Source: `https://github.com/evanzhangx/EchoPulse/tree/main/cli`
394
- - Issues: `https://github.com/evanzhangx/EchoPulse/issues`
395
-
396
111
  ## License
397
112
 
398
113
  MIT