gangtise-openapi-cli 0.6.0 → 0.7.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 CHANGED
@@ -44,6 +44,7 @@ export GANGTISE_TOKEN="Bearer xxx"
44
44
  - `gangtise quote ...`
45
45
  - `gangtise fundamental ...`
46
46
  - `gangtise ai ...`
47
+ - `gangtise vault ...`
47
48
  - `gangtise raw call ...`
48
49
 
49
50
  其中 `lookup` 下的研究方向、机构、行业枚举已内置在项目中,无需额外本地文档文件。
@@ -84,7 +85,7 @@ gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
84
85
  - `insight foreign-report list`
85
86
  - `insight announcement list`
86
87
  - `ai security-clue`
87
- - `ai cloud-disk-list`
88
+ - `vault drive-list`
88
89
 
89
90
  规则:
90
91
  - **有时间范围时**(传了 `--start-time/--end-time` 或 `--start-date/--end-date`):**省略 `--size`**,CLI 自动翻页查全
@@ -93,7 +94,7 @@ gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
93
94
 
94
95
  ## 智能文件命名
95
96
 
96
- 下载命令(`summary download`、`research download`、`foreign-report download`、`announcement download`、`cloud-disk-download`)省略 `--output` 时,自动使用真实标题作为文件名:
97
+ 下载命令(`summary download`、`research download`、`foreign-report download`、`announcement download`、`vault drive-download`)省略 `--output` 时,自动使用真实标题作为文件名:
97
98
 
98
99
  1. **缓存优先** — 如果之前执行过对应的 `list` 命令,标题已缓存在 `~/.config/gangtise/title-cache.json`,直接使用,无额外 API 调用
99
100
  2. **API 回查** — 缓存未命中时,自动查询最近 200 条记录匹配标题
@@ -146,6 +147,10 @@ gangtise insight roadshow list --institution C100000017
146
147
 
147
148
  ```bash
148
149
  gangtise quote day-kline --security 600519.SH --start-date 2026-03-01 --end-date 2026-03-31
150
+ # 不传 --security 默认返回全市场,不传 --start-date 默认往前一年,不传 --end-date 默认最新
151
+ gangtise quote day-kline --format json
152
+ # 港股日K线
153
+ gangtise quote day-kline-hk --security 00700.HK --start-date 2026-03-01 --end-date 2026-03-31
149
154
  ```
150
155
 
151
156
  ### Fundamental
@@ -179,14 +184,19 @@ gangtise ai peer-comparison --security-code 600519.SH
179
184
  gangtise ai earnings-review --security-code 600519.SH --period 2025q3
180
185
  gangtise ai theme-tracking --theme-id 121000131 --date 2026-03-01 --type morning
181
186
  gangtise ai research-outline --security-code 600519.SH
182
- gangtise ai cloud-disk-list --keyword 部门文档 --space-type 1 --file-type 1
187
+ ```
188
+
189
+ ### Vault
190
+
191
+ ```bash
192
+ gangtise vault drive-list --keyword 部门文档 --space-type 1 --file-type 1
183
193
 
184
194
  # 云盘下载:自动使用文件标题命名
185
- gangtise ai cloud-disk-download --file-id 62130
195
+ gangtise vault drive-download --file-id 62130
186
196
  # → 2028 全球智能危机 一份来自未来的金融史思想实验 .pdf
197
+ ```
187
198
 
188
199
  gangtise ai knowledge-resource-download --resource-type 60 --source-id 3052524 --output ./resource.txt
189
- # 若接口返回外链 URL,也会直接输出 URL 或按 --output 保存
190
200
  ```
191
201
 
192
202
  ### Raw
@@ -203,9 +213,10 @@ gangtise raw call insight.opinion.list --body '{"from":0,"size":120}'
203
213
  - auth: `login` / `status`
204
214
  - lookup: `research-area list` / `broker-org list` / `meeting-org list` / `industry list` / `industry-code list` / `region list` / `announcement-category list`
205
215
  - insight: `opinion list` / `summary list` / `summary download` / `roadshow list` / `site-visit list` / `strategy list` / `forum list` / `research list` / `research download` / `foreign-report list` / `foreign-report download` / `announcement list` / `announcement download`
206
- - quote: `day-kline`
216
+ - quote: `day-kline` / `day-kline-hk`
207
217
  - fundamental: `income-statement` / `main-business` / `valuation-analysis`
208
- - ai: `knowledge-batch` / `knowledge-resource-download` / `security-clue` / `cloud-disk-list` / `cloud-disk-download` / `one-pager` / `investment-logic` / `peer-comparison` / `earnings-review` / `theme-tracking` / `research-outline`
218
+ - ai: `knowledge-batch` / `knowledge-resource-download` / `security-clue` / `one-pager` / `investment-logic` / `peer-comparison` / `earnings-review` / `theme-tracking` / `research-outline`
219
+ - vault: `drive-list` / `drive-download`
209
220
 
210
221
  注意:`knowledge-resource-download` 依赖正确的 `resourceType + sourceId` 组合;错误组合会返回 `433007 不支持该数据源`。
211
222
 
@@ -221,17 +232,22 @@ gangtise raw call insight.opinion.list --body '{"from":0,"size":120}'
221
232
 
222
233
  ## Claude Code Skill
223
234
 
224
- 本项目包含一个 [Claude Code](https://claude.ai/claude-code) skill 定义(`SKILL.md`),可让 AI agent 自动调用 `gangtise` CLI 完成投研数据查询。
235
+ 本项目包含一个 [Claude Code](https://claude.ai/claude-code) skill 定义(`gangtise-openapi/SKILL.md`),可让 AI agent 自动调用 `gangtise` CLI 完成投研数据查询。
236
+
237
+ Skill 目录结构:
238
+
239
+ ```
240
+ gangtise-openapi/
241
+ ├── SKILL.md # 主 skill 文件(命令参考、参数枚举、使用规则)
242
+ └── references/
243
+ └── lookup-ids.md # 常用 ID 速查表(行业/券商/机构/公告分类等)
244
+ ```
225
245
 
226
246
  安装到 Claude Code:
227
247
 
228
248
  ```bash
229
- # 方式一:从本地项目安装
230
- cp SKILL.md ~/.claude/skills/gangtise-openapi/SKILL.md
231
-
232
- # 方式二:手动创建目录并复制
233
- mkdir -p ~/.claude/skills/gangtise-openapi
234
- cp SKILL.md ~/.claude/skills/gangtise-openapi/
249
+ # 从项目根目录复制整个 skill 目录
250
+ cp -r gangtise-openapi ~/.claude/skills/gangtise-openapi
235
251
  ```
236
252
 
237
253
  安装后,在 Claude Code 中可以用自然语言触发,例如:
package/dist/src/cli.js CHANGED
@@ -348,10 +348,14 @@ insight.addCommand(foreignReport);
348
348
  insight.addCommand(announcement);
349
349
  program.addCommand(insight);
350
350
  const quote = new Command("quote").description("Quote APIs");
351
- quote.command("day-kline").option("--security <code>", "Security code", collectList, []).option("--start-date <date>").option("--end-date <date>").option("--limit <number>").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
351
+ quote.command("day-kline").option("--security <code>", "Security code (A-share only: .SH/.SZ/.BJ)", collectList, []).option("--start-date <date>", "Start date (default: 1 year before end-date)").option("--end-date <date>", "End date (default: latest)").option("--limit <number>", "Max rows per request (default: 5000, max: 10000)").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
352
352
  const client = await createClient();
353
353
  await printData(await client.call("quote.day-kline", { securityList: maybeArray(options.security), startDate: options.startDate, endDate: options.endDate, limit: options.limit ? Number(options.limit) : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
354
354
  });
355
+ quote.command("day-kline-hk").option("--security <code>", "Security code (HK stock only: .HK)", collectList, []).option("--start-date <date>", "Start date (default: 1 year before end-date)").option("--end-date <date>", "End date (default: latest)").option("--limit <number>", "Max rows per request (default: 5000, max: 10000)").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
356
+ const client = await createClient();
357
+ await printData(await client.call("quote.day-kline-hk", { securityList: maybeArray(options.security), startDate: options.startDate, endDate: options.endDate, limit: options.limit ? Number(options.limit) : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
358
+ });
355
359
  program.addCommand(quote);
356
360
  const fundamental = new Command("fundamental").description("Fundamental APIs");
357
361
  fundamental.command("income-statement").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", "Period", collectList, []).option("--report-type <type>", "Report type", collectList, []).option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
@@ -463,16 +467,18 @@ ai.command("research-outline").requiredOption("--security-code <code>").option("
463
467
  const client = await createClient();
464
468
  await printData(await client.call("ai.research-outline", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
465
469
  });
466
- ai.command("cloud-disk-list").option("--from <number>", "Starting offset", "0").option("--size <number>", "Total rows to return; omit to fetch all").option("--start-time <datetime>").option("--end-time <datetime>").option("--keyword <text>").option("--file-type <number>", "File type", collectNumberList, []).option("--space-type <number>", "Space type", collectNumberList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
470
+ const vault = new Command("vault").description("Vault APIs");
471
+ vault.command("drive-list").option("--from <number>", "Starting offset", "0").option("--size <number>", "Total rows to return; omit to fetch all").option("--start-time <datetime>").option("--end-time <datetime>").option("--keyword <text>").option("--file-type <number>", "File type", collectNumberList, []).option("--space-type <number>", "Space type", collectNumberList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
467
472
  const client = await createClient();
468
- await printData(await client.call("ai.cloud-disk.list", { from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword, fileTypeList: options.fileType.length ? options.fileType : undefined, spaceTypeList: options.spaceType.length ? options.spaceType : undefined }), parseFormat(options.format), options.output, { endpointKey: "ai.cloud-disk.list", idField: "fileId" });
473
+ await printData(await client.call("vault.drive.list", { from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword, fileTypeList: options.fileType.length ? options.fileType : undefined, spaceTypeList: options.spaceType.length ? options.spaceType : undefined }), parseFormat(options.format), options.output, { endpointKey: "vault.drive.list", idField: "fileId" });
469
474
  });
470
- ai.command("cloud-disk-download").requiredOption("--file-id <id>").option("--output <path>").action(async (options) => {
475
+ vault.command("drive-download").requiredOption("--file-id <id>").option("--output <path>").action(async (options) => {
471
476
  const client = await createClient();
472
- const result = await client.call("ai.cloud-disk.download", undefined, { fileId: options.fileId });
473
- const title = options.output ? undefined : await resolveTitle(client, result, "ai.cloud-disk.list", "fileId", options.fileId);
477
+ const result = await client.call("vault.drive.download", undefined, { fileId: options.fileId });
478
+ const title = options.output ? undefined : await resolveTitle(client, result, "vault.drive.list", "fileId", options.fileId);
474
479
  await saveDownloadResult(result, `file-${options.fileId}`, options.output ?? title);
475
480
  });
481
+ program.addCommand(vault);
476
482
  program.addCommand(ai);
477
483
  program.command("raw").description("Raw API calls").addCommand(new Command("call").argument("<endpointKey>").option("--body <json>").option("--query <key=value>", "Query string pair", collectKeyValue, {}).option("--format <format>", "Output format", "json").option("--output <path>").action(async (endpointKey, options) => {
478
484
  const client = await createClient();
@@ -167,7 +167,14 @@ export const ENDPOINTS = {
167
167
  method: "POST",
168
168
  path: "/application/open-quote/kline/daily",
169
169
  kind: "json",
170
- description: "Query daily kline",
170
+ description: "Query A-share daily kline (SH/SZ/BJ)",
171
+ },
172
+ quoteDayKlineHk: {
173
+ key: "quote.day-kline-hk",
174
+ method: "POST",
175
+ path: "/application/open-quote/kline-hk/daily",
176
+ kind: "json",
177
+ description: "Query HK stock daily kline (HK)",
171
178
  },
172
179
  fundamentalIncomeStatement: {
173
180
  key: "fundamental.income-statement",
@@ -275,20 +282,20 @@ export const ENDPOINTS = {
275
282
  kind: "json",
276
283
  description: "Get company research outline",
277
284
  },
278
- aiCloudDiskList: {
279
- key: "ai.cloud-disk.list",
285
+ vaultDriveList: {
286
+ key: "vault.drive.list",
280
287
  method: "POST",
281
- path: "/application/open-ai/drive/getList",
288
+ path: "/application/open-vault/drive/getList",
282
289
  kind: "json",
283
- description: "List AI cloud disk files",
290
+ description: "List vault drive files",
284
291
  pagination: { enabled: true, maxPageSize: 50 },
285
292
  },
286
- aiCloudDiskDownload: {
287
- key: "ai.cloud-disk.download",
293
+ vaultDriveDownload: {
294
+ key: "vault.drive.download",
288
295
  method: "GET",
289
- path: "/application/open-ai/drive/download/file",
296
+ path: "/application/open-vault/drive/download/file",
290
297
  kind: "download",
291
- description: "Download AI cloud disk file",
298
+ description: "Download vault drive file",
292
299
  },
293
300
  };
294
301
  export const ENDPOINT_REGISTRY = Object.values(ENDPOINTS).reduce((accumulator, endpoint) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gangtise-openapi-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "description": "CLI for Gangtise OpenAPI",
5
5
  "license": "MIT",
6
6
  "repository": {