npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gangtise-openapi-cli

v0.33.0

Published

CLI for Gangtise OpenAPI

Readme

Gangtise OpenAPI CLI

一个可直接调用 Gangtise OpenAPI 获取全量金融信息的命令行工具,同时提供Agent Skill。

Changelog

README 仅列最近 5 个版本摘要:

  • v0.33.0 — 2026-08-09:四处行为变更,都是把「静默给出看着正常的错结果」改成显式失败——分页端点返回异形首包(含 data: null)改退出码 3;total 被服务端封顶时探测并标 totalCapped + 退出 3(三个 opinion 端点的 total 恒为 10000 而实际远不止,全量导出此前会被静默截断);空结果不再在 stdout 留空行、null 不再被渲染成一条记录。另补多处帮助文案与 EDE 占位值(个别指标填 0 而非 null)的说明。
  • v0.32.0 — 2026-08-08:新增帕米尔专家纪要列表与下载;跟进 2026-08-07 服务端修复——EDE 缺数据不再整列/整行消失(退出码 3 现在专指「代码没被识别」),条件选股重复指标的 unreliable 告警随之移除;--search-type/--rank-type/--file-type 等枚举改为本地拦截(此前传非法值不会报错,会拿到未过滤的全量)。
  • v0.31.0 — 2026-08-03:修复 v0.30.1 的矩阵维度校验误杀「单指标 × 板块 ID」时序查询的回归;EDE 结果不完整或不可信时改以退出码 3 标记(partial / unreliable)。
  • v0.30.1 — 2026-08-02:修复 sDate 吞掉查询日期导致的区间指标静默错数,让条件选股的文本筛选真正可用,并在服务端整行/整列丢数据时给出警告。
  • v0.30.0 — 2026-08-02:适配 EDE 接口重构(universe 取代 securityCodeList、截面矩阵转置、指标元数据结构化),新增 indicator screener 条件选股,并修正复权参数名。

历史里程碑

  • v0.29.0:新增财报日历与 PDF 解析工具,群消息补 quoteMsg,并加强大整数 ID 与高积分调用防护。
  • v0.26.0–v0.27.0:建立高积分端点 no-replay、原子下载与容错分页机制,并补齐 Skill 分发和发布质量门禁。
  • v0.22.0–v0.23.0:统一“省略 --size 即拉全量”的分页语义,引入机器可识别的部分结果、Token 自愈,并完成 API 域名迁移与资金流向、机构搜索支持。
  • v0.19.0–v0.20.0:上线 EDE 证券指标接口,扩展美股公告与财务报表,同时加强凭证脱敏、CSV 正确性和分页容错。
  • v0.16.0–v0.18.0:以服务端参考数据替代多数本地静态表,收紧端点参数,并加入产业公众号资讯。
  • v0.14.0–v0.15.0:新增跨市场实时行情、美股日 K 与题材数据,完善全市场 K 线分片和部分失败容错。
  • v0.12.0–v0.13.0:奠定并发翻页、连接复用、流式输出与 K 线分片架构,并扩展港股财报、EDB 和股票池。

完整更新明细及更早版本见 CHANGELOG.md

首次安装

npm install -g gangtise-openapi-cli

验证安装:

gangtise --help

更新到最新版(gangtise --version 会自动与线上版本比对):

npm update -g gangtise-openapi-cli

更新后若使用 Agent Skill:包内 skill 已随包更新,但复制到 ~/.claude/skills/ 等目录的副本是快照,需重新执行下方「安装」段的复制命令才能让 AI 助手拿到新版 skill。

本地开发:

git clone [email protected]:gangtiser/gangtise-openapi-cli.git
cd gangtise-openapi-cli
npm install
npm run dev -- --help

环境配置

优先读取以下环境变量:

export GANGTISE_ACCESS_KEY="your-ak"
export GANGTISE_SECRET_KEY="your-sk"
export GANGTISE_BASE_URL="https://openapi.gangtise.com"
export GANGTISE_TOKEN="Bearer xxx"

# 性能/调试可选项
export GANGTISE_PAGE_CONCURRENCY=5     # 翻页/分片并发数(默认 5,上限 32;非法值回退默认)
export GANGTISE_VERBOSE=1              # 打印每个请求的耗时与字节数
export GANGTISE_TIMEOUT_MS=30000       # 请求超时(默认 30s)
export GANGTISE_TOKEN_CACHE_PATH=...   # 覆盖 token 缓存路径(默认 ~/.config/gangtise/token.json)

如果没有 GANGTISE_TOKEN,CLI 会自动调用 token 接口并缓存到本地(~/.config/gangtise/token.json,权限 0600)。Token 失效(0000001008 / 999002)时会自动重新登录并重试一次;凭证本身错(999011)不重试,直接报错让你查环境变量。

AI Agent Skill

本项目包含 Skill 定义(gangtise-openapi/SKILL.md),可让 AI agent 自动调用 gangtise CLI 完成投研数据查询。支持以下 AI 编程助手:

Skill 目录结构:

gangtise-openapi/
├── SKILL.md                          # 主 skill 文件(必备规则、速查表、按需引用 references)
└── references/
    ├── commands/                     # 按命令组拆分的详细参数文档(agent 按需 Read)
    │   ├── ai.md                     #   AI 能力命令(one-pager / earnings-review / viewpoint-debate 等)
    │   ├── alternative.md            #   行业指标数据库(EDB search / EDB data)
    │   ├── fundamental.md            #   财务数据命令(A股/港股三大报表 / 估值 / 盈利预测 / 股东)
    │   ├── indicator.md              #   证券级数据指标 EDE(search / 截面 / 时序 / 条件选股)
    │   ├── insight.md                #   投研内容命令(研报 / 观点 / 纪要 / 公告 / 外资)
    │   ├── quote.md                  #   行情命令(A股/港股/指数 K 线)
    │   ├── reference-and-lookup.md   #   GTS Code 搜索与枚举速查
    │   └── vault.md                  #   云盘/录音/会议/群消息/股票池
    ├── examples.md                   # 典型场景的端到端示例
    ├── fields.md                     # K线/财务字段中英文对照速查表
    ├── lookup-ids.md                 # 常用 ID 速查表(行业/券商/机构/公告分类等)
    └── response-schema.md            # 各接口响应字段说明

安装(skill 目录随 npm 包分发,npm install -g 之后即可从全局安装位置复制):

SKILL_SRC="$(npm root -g)/gangtise-openapi-cli/gangtise-openapi"

# Claude Code
cp -r "$SKILL_SRC" ~/.claude/skills/gangtise-openapi

# Codex
cp -r "$SKILL_SRC" ~/.codex/skills/gangtise-openapi

# OpenClaw
cp -r "$SKILL_SRC" ~/.openclaw/skills/gangtise-openapi

# Hermes
cp -r "$SKILL_SRC" ~/.hermes/skills/gangtise-openapi

从仓库 clone 开发时,把 $SKILL_SRC 换成仓库内的 gangtise-openapi 目录即可。

版本更新:每次 CLI 发版时,gangtise-openapi/SKILL.mdversion 字段会自动同步。更新 CLI 后,请将项目中的 gangtise-openapi/ 目录重新复制到对应的 skills 目录覆盖更新:

# 示例:更新 Claude Code 的 skill
cp -r gangtise-openapi ~/.claude/skills/gangtise-openapi

可通过查看 SKILL.md 头部的 version 字段确认当前版本。

安装后,可以用自然语言触发,例如:

  • "帮我查今天所有的研报"
  • "用 gangtise 命令查一下贵州茅台的日K线"
  • "导出最近一周的首席观点到 jsonl"

数据接口覆盖

| 模块 | 子命令 | 说明 | |------|--------|------| | Auth | login / status | 认证登录、状态查询 | | Lookup | broker-org list / meeting-org list | 券商/会议机构本地全量枚举表(按名称找 ID 优先 reference institution-search;行业/区域/公告分类/题材/申万码已改用 Reference 接口) | | Insight | opinion list | 内资机构观点 | | | summary list / download | 纪要(含下载,支持 --file-type 选原始/HTML) | | | pamirs-summary list / download | 帕米尔专家纪要(需单独购买专家纪要库;筛选项比 summary 少,无 --source/--institution/--participant-role) | | | roadshow list | 路演 | | | site-visit list | 调研 | | | strategy list | 策略 | | | forum list | 论坛 | | | performance-calendar list / download | 财报日历(业绩预告/快报/公告,含原文 PDF 下载) | | | research list / download | 研报(含 Markdown 下载) | | | foreign-report list / download | 外资研报(含中文翻译下载) | | | announcement list / download | A股公告(含 Markdown 下载) | | | announcement-hk list / download | 港股公告(含 PDF/Markdown 下载) | | | announcement-us list / download | 美股公告(含 PDF/Markdown 下载) | | | foreign-opinion list | 外资机构观点 | | | independent-opinion list / download | 外资独立分析师观点(含原文/翻译HTML下载) | | | official-account list / download | 产业公众号资讯(含 txt/HTML 下载) | | | qa list | 投资者问答 QA(互动平台/电话会议/调研纪要,按证券) | | | report-image list / download | 研报图表搜索(按关键词,含原图 JPEG 下载) | | Reference | securities-search | GTS Code 搜索(按名称/代码/拼音匹配) | | | chiefs-search | 首席分析师 ID 搜索(按姓名/机构/团队匹配) | | | institution-search | 机构 ID 搜索(内资券商/外资/牵头/观点机构,按名称匹配) | | | official-account-search | 公众号 ID 搜索(按公众号名/机构/分类匹配,返回 accountId) | | | constant-category | 常量分类列表(含各分类适用的接口与参数) | | | constant-list | 按分类导出常量值全量列表(行业/城市/公告分类/区域等) | | | concept-search | 题材 ID 搜索(名称/拼音/分组名匹配) | | | sector-search | 板块 ID 搜索(返回层级路径) | | | sector-constituents | 板块成分股查询 | | Quote | day-kline / day-kline-hk / day-kline-us | A股/港股/美股历史日K线 | | | index-day-kline | 沪深京指数日K线 | | | minute-kline | A股分钟K线 | | | realtime | 个股实时行情快照(A股/港股/美股) | | | fund-flow | A股个股日资金流向(沪深京;小/中/大/特大单 + 主力净流入) | | Fundamental | income-statement / balance-sheet / cash-flow | A股三大财务报表(累计) | | | income-statement-quarterly / cash-flow-quarterly | A股利润表/现金流量表(单季度) | | | income-statement-hk / balance-sheet-hk / cash-flow-hk | 港股三大财务报表(中国会计准则) | | | income-statement-us / balance-sheet-us / cash-flow-us | 美股三大财务报表 | | | main-business | 主营构成(按地区/产品拆分) | | | valuation-analysis | 估值分析 | | | earning-forecast | 盈利预测(一致预期) | | | top-holders | 前十大股东/前十大流通股东 | | AI | knowledge-batch | 知识库批量检索 | | | knowledge-resource-download | 知识资源下载 | | | security-clue | 个股线索 | | | stock-summary | 个股看点(精炼投研总结,按代码或全市场;仅 A 股/港股) | | | one-pager | 一页通 | | | investment-logic | 投资逻辑 | | | peer-comparison | 同业对比 | | | earnings-review / earnings-review-check | 业绩回顾 | | | theme-tracking | 主题跟踪 | | | hot-topic | 热点话题 | | | research-outline | 研究提纲 | | | management-discuss-announcement | 管理层讨论-财报 | | | management-discuss-earnings-call | 管理层讨论-业绩会 | | | viewpoint-debate / viewpoint-debate-check | 观点PK(异步) | | Vault | drive-list / drive-download | 云盘文件列表与下载 | | | record-list / record-download | 录音速记列表与下载 | | | my-conference-list / my-conference-download | 我的会议列表与下载 | | | wechat-message-list / wechat-chatroom-list | 群消息列表与群ID查询 | | | stock-pool-list / stock-pool-stocks | 自选股股票池列表与证券明细 | | Indicator | search | 证券级数据指标搜索(按名称匹配,返回 indicatorCode 及可传参数 parameterList) | | | cross-section | 指标截面数据(多指标 × 多证券,单日快照;前置 search 拿 code) | | | time-series | 指标时间序列(多指标 × 单证券 或 单指标 × 多证券,按区间) | | | screener | 条件选股(按指标表达式从证券/板块范围筛股;前置 search 拿 code) | | Alternative | edb-search | 行业指标搜索(按关键词匹配,返回 indicatorId 等元信息) | | | edb-data | 行业指标时序数据(批量拉取,最多10个指标) | | | concept-info | 题材指数基本信息(投资逻辑/行业空间/竞争格局/催化事件) | | | concept-securities | 题材指数成分股(题材深度F8,按分组,标记重点个股) | | Tool | file-parse / file-parse-check | PDF 解析为 Markdown + 图片(异步,返回 ZIP) | | Raw | call | 原始接口调用(可访问任意 JSON / download endpoint;upload 型如 tool.file-parse.submit 需走 tool file-parse,raw 带不了文件) |

命令概览

  • gangtise auth ...
  • gangtise lookup ...
  • gangtise insight ...
  • gangtise quote ...
  • gangtise fundamental ...
  • gangtise ai ...
  • gangtise vault ...
  • gangtise indicator ...
  • gangtise alternative ...
  • gangtise reference ...
  • gangtise tool ...
  • gangtise raw call ... / gangtise raw list

推荐工作流

先查枚举/参数:

gangtise reference constant-category                              # 有哪些常量分类、各用于哪些参数
gangtise reference constant-list --category citicIndustry         # 中信行业(--industry / --research-area 的行业维度都用它)
gangtise reference constant-list --category gangtiseIndustry      # 研究方向 6 条(宏观/策略/固收/金工/海外/其他),不含行业
gangtise reference constant-list --category swIndustry            # 申万行业
gangtise reference constant-list --category regionCategory        # 外资研报区域
gangtise reference constant-list --category aShareAnnouncementCategory  # A股公告分类(树形)
gangtise reference sector-constituents --sector-id 2000000014   # 申万行业代码 821xxx.SWI 全量(security-clue --gts-code 用)
gangtise lookup broker-org list      # 券商机构(本地表)
gangtise lookup meeting-org list     # 会议机构(本地表)

再调用业务命令:

gangtise insight opinion list --industry 100800128
gangtise insight summary list --institution C100000017
gangtise quote day-kline --security 600519.SH --start-date 2025-03-01 --end-date 2025-03-12
gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念

性能特性

  • 并发翻页:自动翻页接口的首页拿到 total 后,剩余页用 Promise.all 并发拉取(默认并发数 5,可通过 GANGTISE_PAGE_CONCURRENCY 调整)。20 页查询从串行 ~10s 降到 ~2s。
  • HTTP keep-alive:所有请求复用同一个 undici.Agent(连接池 16),避免重复 TLS 握手。
  • 流式下载:指定 --output 时,二进制响应(PDF 等)直接 pipeline 到磁盘,不经过内存缓冲;50MB PDF 内存占用近乎为零。
  • 流式输出jsonl/csv 格式且 --output 指定时,超过 1000 行自动切换为逐行写盘,避免一次性构建百 MB 字符串。
  • 自动重试:5xx / 429 / ECONNREFUSED / ECONNRESET / ETIMEDOUT / ENOTFOUND / EAI_AGAIN / UND_ERR_*(undici 连接/超时类)/ 999999 系统错误自动指数退避重试 2 次。贵档端点例外(one-pager 等生成/提交类 + tool file-parse 提交 + 50/篇 的 summary / foreign-report / my-conference 下载 + 单价未公布但保守同档的 pamirs-summary 下载,共 18 个):5xx/超时不重放——按次计费不幂等,重放即重复扣分;仅连接失败、429 与 token 自愈重试。indicator(EDE)端点对 999999 不重试——重放一次已计费的查询没有意义(该码 2026-08-01 前还兼表「查询无数据」,现在无数据是保留行列的占位单元格(多数指标 null、个别如 is_dnrpnp0),空表另表示整轴 code 未识别)。终态码 999011(凭证无效)/ 140002(异步生成失败)在任何 HTTP 状态下都不重试——凭证错不会因重试而变,异步生成失败是终态。
  • Token 自愈:调用返回 0000001008 / 999002 时自动强制刷新 Token 并重试一次。
  • K线/资金流向自动分片quote day-kline --security allquote fund-flow --security aShares 等全市场查询自动按日期切分(A股 K线/资金流向 1 天/片、美股 1 天/片、HK 2 天/片、指数 30 天/片),并发执行后合并结果;按日分片自动跳过周六日。分片时如果用户未传 --limit,自动注入 limit: 10000(API 上限)避免默认 6000 截断。
  • Token 内存缓存:Token 在进程内存中缓存,避免每次请求读盘。
  • --verbose:打印每个请求的方法、路径、状态码、耗时和响应大小到 stderr,方便定位慢查询。

自动翻页

以下列表接口会自动翻页:

  • insight opinion list
  • insight summary list
  • insight pamirs-summary list
  • insight roadshow list
  • insight site-visit list
  • insight strategy list
  • insight forum list
  • insight performance-calendar list
  • insight research list
  • insight foreign-report list
  • insight announcement list
  • insight announcement-hk list
  • insight announcement-us list
  • insight foreign-opinion list
  • insight independent-opinion list
  • insight official-account list
  • insight qa list
  • ai security-clue
  • vault drive-list
  • vault record-list
  • vault my-conference-list
  • vault wechat-message-list
  • vault wechat-chatroom-list
  • ai hot-topic

规则:

  • 省略 --size 一律拉全量(无论是否传时间范围),CLI 自动翻页查完
  • 数据量未知时,可先 --size 1 从 stderr 的 Total: N 探明量级,再决定是否全量
  • 如果显式传了 --size,则按指定值翻页,直到达到 size 或数据取完
  • --from 必须是非负整数,--size 必须是正整数;非法数字会在本地直接报 ValidationError,不会继续请求 API
  • 安全上限:自动翻页最多 1000 页,防止异常循环
  • 部分页失败、或服务端实际返回行数与 total 矛盾(提前短页)时,不丢弃已取到的数据:结果带 partial: true(页失败时另有 failedPages;K线分片为 failedShards--format json 可见),stderr 输出警告,进程退出码为 3(完整成功为 0)
  • indicator 命令的退出码 3(脚本按 != 0 判失败的需留意):服务端整指标/整证券没返回时标 partial + omittedIndicators / omittedSecurities 并退出 3。v0.32.0 起这个信号的含义变窄了——2026-08-07 服务端改为给缺数据补占位单元格(行列都保留),所以整列/整行消失现在只发生在服务端解析不了那个 code 时(指标码拼错,或证券后缀错,如美股写成 AAPL.US 而非 AAPL.O)。真实的无数据/无覆盖是占位单元格 + 退出码 0。🔴 占位值不统一:多数指标是 null,个别(如 is_dnrpnp)是 0,而 0 会穿过比较与聚合——别把它当真值,详见 skill 的 references/commands/indicator.md。⚠️ 这个检测需要同批里有一个能解析的对照物:拼错的 code 与正确的 code 混在一批才会标 partial;整个轴都写错时(如只查一个拼错的指标)响应是空表、退出码 0,只有 stderr 提示——空表拿到手必须先核对代码拼写与后缀。同版本移除了条件选股重复指标的 unreliable / duplicatedIndicators 标记(服务端已修复,继续告警会是误报)。条件选股的缺列另有更严的一档:把缺列的变量当作无法求值,若表达式(按 &&/|| 的布尔结构)再无任何可成立的分支,则退出码 1 且不输出——那些行以「通过了该条件」的名义呈现,而条件根本无法证明被执行过。⚠️ 这一档以「服务端返回了命中行」为前提;零命中时一律退出码 0(没有行需要被质疑),所以空集要先核对指标码拼写,不能直接当成「无标的符合条件」。语义约定:0 完整成功(含合法空结果)/3 有数据但不完整/1 硬失败
  • 分页端点返回 null 也退出 3:分页端点本该返回 {total, list},真实的空结果是 {total: 0, list: []}。若响应体是 null(已知一例:insight foreign-opinion / independent-opinion--industry),CLI 在 stderr 告警并退出码 3——只给告警的话,脚本无法区分「这个筛选确实没命中」和「这个筛选没生效」。机器格式(jsonl/csv)此时 stdout 不输出任何字节(不是空行),--format json 仍忠实打印 null。⚠️ 带 --output 时文件仍会被创建:csv 会写入 3 字节 UTF-8 BOM(Excel 兼容用),jsonl 为 0 字节——按文件大小判空的脚本要留意 csv 的这 3 个字节
  • 🔴 total 被服务端封顶时会标 totalCapped 并退出 3insight opinion / foreign-opinion / independent-opinion 三个端点的 total 恒为 10000,而实际记录远不止(把 from 加到远超该值仍能取到真实记录)。省略 --size 的全量拉取本来会正好取满 10000 条就停、且不报任何异常——导出的文件是截断的却看不出来。现在全量拉取结束后会多探一行from = total):探到数据就标 partial + totalCapped 并退出 3。判据不写死 10000,服务端改配置仍然有效;total 诚实时探针返回空、不产生计费。传了 --size 的有界请求不做此探测。
  • 分页结果中 total 字段会被保留(json 格式输出 {total, list});其他格式下 stderr 输出 Total: N, showing: M(json 格式不输出该行)

智能文件命名

下载命令(summary downloadpamirs-summary downloadresearch downloadforeign-report downloadannouncement downloadannouncement-hk downloadannouncement-us downloadofficial-account downloadperformance-calendar downloadvault drive-downloadvault record-downloadvault my-conference-download)省略 --output 时,自动使用真实标题作为文件名:

  1. 缓存优先 — 如果之前执行过对应的 list 命令,标题已缓存在 ~/.config/gangtise/title-cache.json,直接使用,无额外 API 调用
  2. API 回查 — 缓存未命中时,自动查询最近 200 条记录匹配标题
  3. 兜底 — 都找不到时使用服务器返回的原始文件名或 {type}-{id}.{ext}

推荐工作流:先 listdownload,文件名自动正确。

常用示例

认证

gangtise auth login
gangtise auth status

Insight

# 省略 --size → 自动翻页查全
gangtise insight research list --start-time "2026-04-01 00:00:00" --end-time "2026-04-09 23:59:59"

# 无时间范围也是拉全量;只要前 200 条就显式传 --size
gangtise insight research list --industry 100800126 --category company --llm-tag inDepth --rating buy --size 200

# 多值 List 模式:一次查多家券商 + 多个行业 + 多个评级
gangtise insight research list --broker C100000027 --broker C100000014 --industry 100800119 --industry 100800118 --rating buy --rating overweight --format json

gangtise insight opinion list --keyword AI
gangtise insight summary list --keyword 算力

# 帕米尔专家纪要(需单独购买专家纪要库;全文搜索 + 时间倒序)
# --rank-type 2 = 严格时间倒序;换成 1(综合排序)在「全文搜索 + 有关键词」下是真正的相关度重排
gangtise insight pamirs-summary list --keyword PCB --search-type 2 --rank-type 2 --size 20
gangtise insight pamirs-summary download --summary-id 5863771 --file-type 2
# → PCB钻针:高端钻针扩产有壁垒,供需紧缺会持续到28年.html

# 下载:先 list 再 download,自动使用真实标题作为文件名
gangtise insight summary download --summary-id 4902586
# → 超颖电子:2026年4月7日投资者关系活动记录表.txt

# 下载 Markdown 版本
gangtise insight research download --report-id 432092410345574400 --file-type 2
# 下载外资研报中文翻译版
gangtise insight foreign-report download --report-id RPT20260401001 --file-type 4
# 下载公告 Markdown 版本
gangtise insight announcement download --announcement-id 123456 --file-type 2

# 也可手动指定文件名
gangtise insight research download --report-id 12345 --output ./report.pdf

gangtise insight roadshow list --institution C100000017

# 港股公告
gangtise insight announcement-hk list --security 01913.HK --rank-type 2 --size 20 --format json
gangtise insight announcement-hk download --announcement-id ANN2026040200012345
gangtise insight announcement-hk download --announcement-id ANN2026040200012345 --file-type 2   # Markdown

# 美股公告(--security 用美股代码;分类用 reference constant-list --category usShareAnnouncementCategory)
gangtise insight announcement-us list --security TSLA.O --rank-type 2 --size 20 --format json
gangtise insight announcement-us download --announcement-id 49629029 --file-type 2   # Markdown

# 外资机构观点
gangtise insight foreign-opinion list --keyword "自动驾驶" --region us --rank-type 2 --format json
gangtise insight foreign-opinion list --security APP.O --rating buy --format json

# 外资独立观点
gangtise insight independent-opinion list --keyword "肿瘤" --industry 100800118 --format json
gangtise insight independent-opinion download --independent-opinion-id 207051900018372 --file-type 2

# 产业公众号资讯
gangtise insight official-account list --keyword 泡泡玛特 --rank-type 2 --size 20 --format json
gangtise insight official-account download --article-id 7286248 --file-type 2

# 投资者问答 QA(按证券;--source/--question-category/--answer-important 精筛,自动翻页)
gangtise insight qa list --security-code 601012.SH --source interactive --answer-important 1 --size 20 --format json
# 研报图表:按关键词搜图拿 chunkId,再下原图(JPEG)
gangtise insight report-image list --keyword AI --top 5 --format json
gangtise insight report-image download --chunk-id image_10_384655917758685184_8 --output ./ai-chart.jpg

# 纪要下载(会议平台来源可选 HTML 格式)
gangtise insight summary download --summary-id 4906813 --file-type 2

# 财报日历:注意用 --start-date/--end-date(按 publishDate 过滤),不是 --start-time
gangtise insight performance-calendar list --start-date 2026-07-01 --end-date 2026-07-25 \
  --market aShares --category performanceForecast --size 20 --format json
# 下载业绩报告原文(仅 hasAttachment: true 的记录;A股 10 积分 / 港美股 20 积分)
gangtise insight performance-calendar download --performance-report-id 33753017 --output ./业绩预告.pdf

Reference

# GTS Code 搜索:按公司名/代码/拼音查证券代码
gangtise reference securities-search --keyword "贵州茅台" --category stock
gangtise reference securities-search --keyword "600519" --category stock
gangtise reference securities-search --keyword gzmt --top 5
gangtise reference securities-search --keyword "银行" --category stock --category index

# 首席分析师 ID 搜索(按姓名/机构/团队;拿 chiefId 供 insight opinion list --chief 使用)
gangtise reference chiefs-search --keyword 东吴证券 --top 3 --format json
gangtise reference chiefs-search --keyword 芦哲 --format json
# 机构 ID 搜索(--category: domesticBroker/foreignInstitution/leadInstitution/opinionInstitution/foreignOpinionInstitution)
gangtise reference institution-search --keyword 招商证券 --category domesticBroker --top 3 --format json
# 公众号 ID 搜索(按名称/机构/分类;拿 accountId 供 insight official-account list --account-id)
gangtise reference official-account-search --keyword 中信证券 --top 3 --format json

# 常量查询:先看分类,再按分类导出全量常量值
gangtise reference constant-category --format json
gangtise reference constant-list --category citicIndustry --format json
gangtise reference constant-list --category aShareAnnouncementCategory --format json   # 树形,含 children
gangtise reference constant-list --category usShareAnnouncementCategory --format json  # 美股公告分类(103980xxx 段)

# 题材 ID 搜索(供 concept-info / concept-securities / theme-tracking 使用)
gangtise reference concept-search --keyword 机器人 --top 3 --format json
gangtise reference concept-search --keyword jqr   # 拼音首字母

# 板块:先搜板块 ID,再查成分股(sectorId 必须来自 sector-search)
gangtise reference sector-search --keyword 半导体设备 --format json
gangtise reference sector-constituents --sector-id 1000001005 --format json

Quote

gangtise quote day-kline --security 600519.SH --start-date 2026-03-01 --end-date 2026-03-31
# 查最近/最新 K 线建议显式传 --start-date/--end-date;只传 --limit 会截取查询窗口开头,不等于最近N条
gangtise quote day-kline --format json
# 全市场查询(--security all)
gangtise quote day-kline --security all --start-date 2026-04-01 --end-date 2026-04-01 --limit 100 --format json
# 港股日K线
gangtise quote day-kline-hk --security 00700.HK --start-date 2026-03-01 --end-date 2026-03-31
# 港股全市场
gangtise quote day-kline-hk --security all --start-date 2026-04-01 --end-date 2026-04-01 --limit 100 --format json
# 美股日K线(NASDAQ/NYSE/AMEX,历史)
gangtise quote day-kline-us --security AAPL.O --security MSFT.O --start-date 2026-04-22 --end-date 2026-05-22 --field tradeDate --field open --field close --field volume
# 美股全市场(自动分片)
gangtise quote day-kline-us --security all --start-date 2026-04-01 --end-date 2026-04-02 --field securityCode --field close --format json
# 沪深京指数日K线
gangtise quote index-day-kline --security 000001.SH --security 399001.SZ --start-date 2024-05-01 --end-date 2024-05-20 --field securityCode --field tradeDate --field close --field volume
# A股分钟K线
gangtise quote minute-kline --security 600519.SH --start-time "2026-04-15 09:30:00" --end-time "2026-04-15 15:00:00" --field open --field close --field volume
# 实时行情:三大市场混合查询
gangtise quote realtime --security 600519.SH --security 00700.HK --security AAPL.O --field securityCode --field tradeTime --field latestPrice --field pctChange --field volume --format json
# 实时行情:全市场批量(建议配合 --field 精简字段)
gangtise quote realtime --security aShares --field securityCode --field latestPrice --field pctChange --field volume --format json
# A股个股日资金流向(沪深京;--security aShares 全市场;--limit 上限 10000,超限缩短日期区间分批)
gangtise quote fund-flow --security 600519.SH --security 000001.SZ --start-date 2026-06-01 --end-date 2026-06-05 --field mainNetInflow --field largeInflow --field xlargeInflow --format json

历史 vs 实时day-kline* 仅返回历史数据(当日数据入库时间:A 股 ~15:30 / 港股 ~16:30 / 美股 ~07:00 北京时间)。盘中需要最新成交价、振幅等实时字段必须走 quote realtime

Fundamental

gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2025 --period q3 --field netProfit
# 多年度:同时查2023-2025年报净利润
gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2023 --fiscal-year 2024 --fiscal-year 2025 --period annual --field netProfit
# 最新一期完整利润表
gangtise fundamental income-statement --security-code 600519.SH --format json
gangtise fundamental balance-sheet --security-code 600519.SH --fiscal-year 2025 --period q3 --field totalCurrAssets --field totalCurrLiab
# 最新一期完整资产负债表
gangtise fundamental balance-sheet --security-code 600519.SH --format json
gangtise fundamental cash-flow --security-code 600519.SH --fiscal-year 2025 --period q3 --field netOpCashFlows --field netInvCashFlows --field netFinCashFlows
# 最新一期完整现金流量表
gangtise fundamental cash-flow --security-code 600519.SH --format json
gangtise fundamental main-business --security-code 600519.SH --breakdown region
# 多报告期:--period 可传多个值
gangtise fundamental main-business --security-code 600519.SH --breakdown product --period annual --period interim
gangtise fundamental valuation-analysis --security-code 600519.SH --indicator peTtm
# 盈利预测(一致预期)
gangtise fundamental earning-forecast --security-code 600519.SH --consensus netIncome --consensus eps --consensus pe
# 利润表(单季度)
gangtise fundamental income-statement-quarterly --security-code 600519.SH --fiscal-year 2025 --period q2 --field netProfit
# 现金流量表(单季度)
gangtise fundamental cash-flow-quarterly --security-code 600519.SH --fiscal-year 2025 --period q2 --field netOpCashFlows
# 前十大股东
gangtise fundamental top-holders --security-code 600519.SH --holder-type top10 --fiscal-year 2025 --format json
# 前十大流通股东(按日期范围)
gangtise fundamental top-holders --security-code 600519.SH --holder-type top10Float --start-date 2025-01-01 --end-date 2025-12-31 --period q3 --format json

# 港股三大报表(中国会计准则,--security-code 用港股代码)
gangtise fundamental income-statement-hk --security-code 09992.HK --fiscal-year 2025 --period annual --field netProfit --field basicEPS
gangtise fundamental income-statement-hk --security-code 09992.HK --fiscal-year 2023 --fiscal-year 2024 --fiscal-year 2025 --period annual --field netProfit
gangtise fundamental balance-sheet-hk --security-code 09992.HK --fiscal-year 2025 --period h1 --field totalCurrAssets --field totalNonCurrAssets --field totalCurrLiab --field totalNonCurrLiab
gangtise fundamental cash-flow-hk --security-code 09992.HK --fiscal-year 2025 --period annual --field netOpCashFlows --field netInvCashFlows --field netFinCashFlows
# 最新一期完整港股利润表
gangtise fundamental income-statement-hk --security-code 09992.HK --format json

# 美股三大报表(--security-code 用美股代码;period 同港股但无 h2)
gangtise fundamental income-statement-us --security-code TSLA.O --period latest --format json
gangtise fundamental balance-sheet-us --security-code TSLA.O --fiscal-year 2025 --period annual --field totalAssets --field totalLiab --field totalEquity
gangtise fundamental cash-flow-us --security-code TSLA.O --fiscal-year 2024 --fiscal-year 2025 --period annual --field netOpCashFlows

AI

gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
# 多 resource-type:同时搜索券商研报和外资研报
gangtise ai knowledge-batch --query 新能源汽车 --resource-type 10 --resource-type 11 --top 10
gangtise ai security-clue --start-time "2026-04-01 00:00:00" --end-time "2026-04-09 23:59:59" --query-mode byIndustry --gts-code 821035.SWI --source researchReport --source announcement
gangtise ai one-pager --security-code 600519.SH
# 个股看点(精炼投研总结,仅 A 股/港股):传具体代码,或 aShares/hkStocks 拉全市场
gangtise ai stock-summary --security 600519.SH --security 00700.HK --format json
gangtise ai stock-summary --security hkStocks --format json
gangtise ai investment-logic --security-code 600519.SH
gangtise ai peer-comparison --security-code 600519.SH
gangtise ai earnings-review --security-code 600519.SH --period 2025q3
gangtise ai theme-tracking --theme-id 121000131 --date 2026-03-01 --type morning
gangtise ai hot-topic --start-date 2026-03-22 --end-date 2026-03-27 --category morningBriefing --category noonBriefing --with-related-securities --with-close-reading
# 不传 --category 默认查全部类型(早报+午报+盘中快报+晚报),--with-related-securities 和 --with-close-reading 默认开启,可用 --no-with-related-securities / --no-with-close-reading 关闭
gangtise ai hot-topic --start-date 2026-04-15 --end-date 2026-04-17
gangtise ai research-outline --security-code 600519.SH
# 管理层讨论-财报(三个细分维度)
gangtise ai management-discuss-announcement --report-date 2025-06-30 --security-code 000001.SZ --dimension businessOperation
gangtise ai management-discuss-announcement --report-date 2025-12-31 --security-code 000001.SZ --dimension financialPerformance
# 传入 all 返回完整管理层讨论内容(内容较长,谨慎使用)
gangtise ai management-discuss-announcement --report-date 2025-12-31 --security-code 000001.SZ --dimension all
# 管理层讨论-业绩会
gangtise ai management-discuss-earnings-call --report-date 2025-06-30 --security-code 000001.SZ --dimension financialPerformance
# 观点PK(异步,返回 dataId)
gangtise ai viewpoint-debate --viewpoint "飞天茅台的批价低点是1500元"
# 等待生成完成后查询结果
gangtise ai viewpoint-debate-check --data-id 202603310528
# 也可以 --wait 同步等待结果(最长约 5 分钟:14 次指数退避轮询,累计 ≈316s)
gangtise ai viewpoint-debate --viewpoint "比亚迪股价将突破500元" --wait
gangtise ai knowledge-resource-download --resource-type 60 --source-id 3052524 --output ./resource.txt

Vault

gangtise vault drive-list --keyword 部门文档 --space-type 1 --file-type 1

# 云盘下载:自动使用文件标题命名
gangtise vault drive-download --file-id 62130
# → 2028 全球智能危机  一份来自未来的金融史思想实验  .pdf

# 录音速记列表
gangtise vault record-list --keyword 晨会 --category upload --category mobile
# 录音速记下载(--content-type: original/asr/summary)
gangtise vault record-download --record-id 49412 --content-type summary

# 我的会议列表(--source 录制来源:1=企微会议助理 2=会议服务微信群,可重复;不传返回全部)
gangtise vault my-conference-list --keyword AI --category earningsCall --institution C100000027
gangtise vault my-conference-list --source 2 --category earningsCall --size 20
# 我的会议下载(--content-type: asr/summary)
gangtise vault my-conference-download --conference-id 43319 --content-type asr

# 群消息:先按群名称查群ID,再按群ID查消息
gangtise vault wechat-chatroom-list --room-name "AI学习群,投研分享群" --size 50
gangtise vault wechat-message-list --keyword AI应用 --wechat-group-id ueKEGyhdjFGkjyebh --category text --category url --tag roadShow --tag meetingSummary --size 50
# 按证券代码过滤群消息
gangtise vault wechat-message-list --security 000001.SZ --security 300750.SZ --size 50

# 自选股股票池
gangtise vault stock-pool-list
# 查询指定股票池中的证券
gangtise vault stock-pool-stocks --pool-id 808477293
# 查询所有股票池中的全量证券(默认行为)
gangtise vault stock-pool-stocks

Indicator(证券级数据指标 EDE)

# Step 1:按名称搜索,拿 indicatorCode(绝不猜编码);--format json 看可传参数 parameterList 及 required
gangtise indicator search --keyword 收盘价 --format table             # → qte_close
gangtise indicator search --keyword 平均ROE --limit 5 --format json    # 看 parameterList

# 截面:多指标 × 多证券,单日快照(行情类用交易日;财务类用报告期末,如 2026-03-31)
# --security 也接受板块 ID(reference sector-search 的 10 位 sectorId),与代码混传取并集
gangtise indicator cross-section \
  --indicator qte_close --indicator qte_vol --indicator qte_mkt_cptl \
  --security 600519.SH --security 09992.HK \
  --date 2026-07-31 --format table
# 输出列:security / name / <各指标名>…(v0.30.0 起无 date 列——日期挂在每个指标的参数上)

# 时间序列:多指标 × 单证券 或 单指标 × 多证券(不能多 × 多,否则报 100003)
gangtise indicator time-series --indicator qte_close \
  --security 600519.SH --security 09992.HK \
  --start-date 2026-07-29 --end-date 2026-07-31 --format table

# 条件选股:F1/F2… 绑定指标,用表达式组合筛选(--indicator-param 按变量索引,不是按 code)
# --date 必填:绝大多数指标吃 tradeDate,漏传就是空表 + 退出码 0
gangtise indicator screener \
  --indicator F1:qte_mkt_cptl --indicator F2:finc_pe_ttm \
  --indicator-param "F1:scale=8" \
  --security 1000000287 \
  --expression "F1 >= 500 && F2 <= 30" \
  --date 2026-07-31 --format table

# 文本筛选:经营范围含「酒」(contains/notcontains 只对 string 类型指标有效)
gangtise indicator screener --indicator F1:pty_op_scope \
  --security 1000000287 --expression "F1 contains '酒'" \
  --date 2026-07-31 --format table

# 复权 / 指标专属参数用 --indicator-param "code:key=value"
# ⚠️ 参数名必须以 search 的 parameterList 为准:写错名不会报错,会按默认值取数,结果看着正常但口径不对
gangtise indicator cross-section --indicator qte_close --security 600519.SH \
  --date 2024-01-02 --indicator-param "qte_close:adjustType=3"   # 1不复权/2前复权/3后复权/4定点
# 不复权 1685.01 → 前复权 1531.225 → 后复权 13609.6168(前复权在最新交易日等于不复权,验证要用历史日)

# 必填参数:部分指标缺必填参数会报 140002,按 parameterList 的 required 补齐再取:
#   N 期统计补 periodNum、区间类补 sDate(起始日,tradeDate 仍是终点)、年度/分红类补 fiscalYear
gangtise indicator cross-section --indicator finc_roe_avg_avg --security 600519.SH \
  --date 2026-03-31 --indicator-param "finc_roe_avg_avg:periodNum=4"

# 区间指标:sDate 是起点、--date 下发的 tradeDate 是终点,两者共存
gangtise indicator cross-section --indicator qte_vol_intvl --security 600519.SH \
  --date 2024-01-31 --indicator-param "qte_vol_intvl:sDate=2024-01-02"

Alternative(行业指标数据库 EDB)

# Step 1:按关键词搜索指标,获取 indicatorId
gangtise alternative edb-search --keyword 空调 --limit 50 --format table
gangtise alternative edb-search --keyword "海尔销量"

# Step 2:按 indicatorId 拉取时间序列数据(最多10个指标)
gangtise alternative edb-data \
  --indicator-id S14001618 \
  --indicator-id S14001620 \
  --start-date 2024-01-01 \
  --end-date 2024-12-31 \
  --format table

# 导出为 CSV
gangtise alternative edb-data \
  --indicator-id S14001618 \
  --start-date 2023-01-01 \
  --end-date 2024-12-31 \
  --format csv \
  --output ./indicator.csv

# 题材指数:先查 conceptId(与 theme-id 共用 ID 体系),再拉画像 / 成分股
gangtise reference concept-search --keyword 机器人 --format json   # → 121000130
gangtise alternative concept-info --concept-id 121000130 --format json
# 题材成分股(题材深度 F8,按分组返回,标记重点个股)
gangtise alternative concept-securities --concept-id 121000130 --format json

Tool(PDF 解析)

# 一步到位:上传 → 阻塞等待 → 结果 ZIP 落盘(含 file.md + images/)
gangtise tool file-parse --file ./研报.pdf --wait --output ./研报.zip

# 分两步:先提交拿 taskId(此时按页扣费 0.8/页),约 3 分钟后取结果(免费)
gangtise tool file-parse --file ./研报.pdf
gangtise tool file-parse-check --task-id 829081108954501120 --output ./研报.zip

限制:单文件 ≤100MB、≤500 页,同一用户最多 10 个并发任务;未就绪时 file-parse-check 输出 {"status":"pending"}(退出码 0),重试即可,不会重复扣费。

Raw

# 先列出所有 endpoint key(配合 raw call,不必翻文档记 key)
gangtise raw list
gangtise raw list --format json   # key / method / path / description

gangtise raw call insight.opinion.list --body '{"from":0,"size":120}'

说明:对已标记为自动翻页的 endpoint,raw call 也会复用同一套 client 翻页逻辑;这里的 size 仍表示最终希望返回的记录数。

输出格式

支持:

  • table
  • json(分页结果保留 {total, list} 结构)
  • jsonl(每行一条记录)
  • csv
  • markdown

所有格式均支持 --output <path> 输出到文件(自动创建父目录)。

参数校验

CLI 会在本地校验常见数值参数,避免把明显非法的请求发到 API:

  • --from:非负整数
  • --size / --limit / --top:正整数
  • --file-type / --resource-type 以及数值型列表参数:有限数字
  • 所有 date 参数(--start-date/--end-date/--date/--report-date,含 Quote/Fundamental/AI/Alternative/Indicator):YYYY-MM-DD(严格——年在后等歧义格式在发请求前拒绝)
  • 所有 --start-time / --end-time(Insight/Vault/AI 透传、quote minute-kline,以及 A 股公告 / knowledge-batch 两个转换端点):YYYY-MM-DD[ HH:mm[:ss]](时间部分秒可省、空格或 T 分隔)或 10/13 位 Unix 时间戳(严格校验——年在后等歧义格式在发请求前拒绝)

校验失败会输出 ValidationError: Invalid ... 并以非 0 状态退出。

常见错误

| 错误/错误码 | 说明 | |-----------|------| | ValidationError | 本地参数校验失败,检查 --size / --limit / --from / --file-type 等数值参数 | | API error (HTTP 4xx/5xx) | HTTP 层失败;CLI 会把 4xx/5xx 响应视为错误,即使响应体不是标准 {code,msg,data} 信封 | | 999011 | 开发账号凭证无效(AK/SK 不匹配)——取代旧 8000014/8000015,不再区分是 AK 错还是 SK 错 | | 999002 / 0000001008 | Token 无效或已过期(有 AK/SK 时 CLI 自动重登重试一次) | | 999001 / 0000001007 | 请求未携带 token | | 999003 | 未开通接口权限(定制接口需联系客户经理) | | 999005 | 积分不足 | | 999006 | 调用超出上限(HTTP 429,CLI 按 Retry-After 退避重试) | | 999010 | 接口地址不存在(raw call 的 key 可能已下线,用 raw list 核对) | | 999012 / 999013 / 999014 | 账号禁用 / 已过期 / 租户失效 | | 999016 | 调用方 IP 不在允许范围 | | 999999 | Gangtise 系统错误,请稍后重试(indicator 端点的「无数据」已不再用此码——有效 code 无数据返回占位单元格(多数 null、个别指标 0),此码基本只剩真故障) | | 140002 | 终态失败:AI 异步生成失败,或 indicator 的参数/表达式错误(枚举越界、语法错)——改参数重提,不重试 | | 100003 | 参数值非法——最宽的兜底码;msg 通常已指明字段(如「limit 最小为 1,最大为 10000」),先读 msg | | 100001 | 缺必填参数(msg 带字段名,如「缺少必填参数: reportId」) | | 100006 | 查询/下载数量超限——取代旧 430007 | | 110001 / 110002 | 日期格式错误 / 日期区间非法(起晚于止) | | 120001 | 证券代码无效(用 reference securities-search 确认代码与后缀) | | 130001 | 数据未找到或无指标权限——取代旧 410004 | | 130002 | 资源不存在——下载类的兜底码--report-id 不存在 / 非数字 / --file-type 非法都归这里(取代旧 430004) | | 410110 / 410111 | 异步任务生成中(继续轮询)/ 生成失败(终态)——实测服务端仍发这两个旧码;新码 140001/140002,CLI 两代都认 | | 240001 | 财报期未披露或超出查询期(earnings-review 提交阶段即报,不扣积分) | | 250001 | 不支持该数据源(knowledge-resource-download 需正确的 resourceType + sourceId 组合)——取代旧 433007 | | 900002 | 请求方法不正确(服务端 msg 为「请求类型有误」,HTTP 405) |

关于这次错误码重排:服务端 2026-07-17 重排了 41 个公开码(三层:999xxx 服务统一层 / 1xxxxx 业务通用层 / 2xxxxx 接口专有层),信封新增 errorTypetraceId。2026-07-20 逐码实测发现迁移是按「错误处理层」而非按业务模块进行的:同一个接口内,参数校验层与路由层已发新码,方法路由层、token 过滤器、以及异步生成状态仍发旧码。新码信封 code 是 JSON 数字且带 errorType,旧码是字符串且没有——但这判断的是单条错误路径,不是整个接口;CLI 对两代都能识别。报错行会带 [trace <id>]报障时请带上它

其余码(999003999006999012999016100002100004100005130003130005210001220001230001240002240003)在实测中未触发到,多被上面的兜底码接管,CLI 仍内置了对应提示。⚠️ 110003(超出时间范围限制)此前也列在这里,2026-08-08 实测已确认可触发——凡超出账号数据权限范围的查询都返回它(如 fundamental income-statement --fiscal-year 2015)。两个实测坑:枚举值拼错和分页越界服务端不报错(静默忽略该筛选条件,v0.32.0 起 CLI 对 --search-type/--rank-type/--file-type 等已知枚举本地拦截);viewpoint-debate 的敏感内容不会被提前拦截,会扣满 50 积分再以 410111 失败。


发布(维护者)

面向仓库维护者的发版流程,普通用户可跳过。

npm 发版通过 GitHub Actions Trusted Publishing 完成,不需要 NPM_TOKEN。npm 包设置里的 Trusted Publisher 需要匹配本仓库和 workflow 文件名 publish.yml

npm version patch --no-git-tag-version
npm run prepare
VERSION=$(node -p "require('./package.json').version")
git commit -am "chore: release v$VERSION"
git tag -a "v$VERSION" -m "v$VERSION"   # 必须 annotated:--follow-tags 不推 lightweight tag
git push --follow-tags

推送 v* tag 后,.github/workflows/publish.yml 会在 GitHub-hosted runner 上使用 OIDC 发布到 https://registry.npmjs.org/。也可以从 GitHub Actions 页面手动运行该 workflow。