@tcos/broker-parser 0.1.0 → 0.2.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.
@@ -14,46 +14,18 @@ description: 解析券商 PDF 结单文件,提取交易记录、持仓和资
14
14
 
15
15
  ## Setup
16
16
 
17
- 运行以下 setup 脚本确保环境就绪:
17
+ 先运行以下命令确保环境就绪:
18
18
 
19
19
  ```bash
20
- #!/usr/bin/env bash
21
- set -e
22
-
23
- # 1. 检查并安装 CLI
24
- if ! command -v tcos-parse &>/dev/null; then
25
- echo "Installing tcos-parse..."
26
- npm install -g @tcos/broker-parser
27
- fi
28
-
29
- # 2. 检查 Python 3
30
- if ! command -v python3 &>/dev/null; then
31
- if command -v brew &>/dev/null; then
32
- brew install python3
33
- elif command -v apt-get &>/dev/null; then
34
- sudo apt-get install -y python3 python3-pip
35
- else
36
- echo "ERROR: Cannot install Python automatically. Please install Python 3 manually."
37
- exit 1
38
- fi
39
- fi
40
-
41
- # 3. 检查并安装 pdfplumber
42
- if ! python3 -c "import pdfplumber" 2>/dev/null; then
43
- pip3 install pdfplumber
44
- fi
45
-
46
- # 4. 检查 poppler(pdfplumber 底层依赖)
47
- if ! command -v pdftotext &>/dev/null; then
48
- if command -v brew &>/dev/null; then
49
- brew install poppler
50
- elif command -v apt-get &>/dev/null; then
51
- sudo apt-get install -y poppler-utils
52
- fi
53
- fi
54
-
55
- echo "tcos-parse setup complete"
56
- tcos-parse --version
20
+ npx @tcos/broker-parser setup
21
+ npx @tcos/broker-parser install-skill
22
+ ```
23
+
24
+ 如果已经全局安装过 `@tcos/broker-parser`,也可以使用:
25
+
26
+ ```bash
27
+ tcos-parse setup
28
+ tcos-parse install-skill
57
29
  ```
58
30
 
59
31
  ## 使用方式
package/README.en.md ADDED
@@ -0,0 +1,66 @@
1
+ # @tcos/broker-parser
2
+
3
+ > English reference page. The primary documentation is maintained in Chinese.
4
+
5
+ [![CI](https://github.com/biggersun/broker-parser/actions/workflows/ci.yml/badge.svg)](https://github.com/biggersun/broker-parser/actions)
6
+ [![npm](https://img.shields.io/npm/v/@tcos/broker-parser)](https://www.npmjs.com/package/@tcos/broker-parser)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
8
+
9
+ Primary documentation: [README.md](./README.md)
10
+
11
+ ## What this package does
12
+
13
+ `@tcos/broker-parser` parses brokerage PDF statements into structured JSON.
14
+
15
+ Current support:
16
+
17
+ - Phillip Securities
18
+
19
+ Usage modes:
20
+
21
+ - CLI
22
+ - npm package
23
+ - AI skill for Claude Code, Codex, and OpenClaw
24
+
25
+ ## Recommended setup
26
+
27
+ For full details, troubleshooting, environment compatibility, and upgrade notes, see the Chinese README:
28
+
29
+ - [安装与环境说明](./README.md#运行环境要求)
30
+ - [Skill 安装详解](./README.md#skill-安装详解)
31
+ - [常见问题](./README.md#常见问题)
32
+ - [方案评审结论](./README.md#方案评审结论)
33
+
34
+ Typical commands:
35
+
36
+ ```bash
37
+ npx @tcos/broker-parser setup
38
+ npx @tcos/broker-parser install-skill
39
+ ```
40
+
41
+ CLI example:
42
+
43
+ ```bash
44
+ npm install -g @tcos/broker-parser
45
+ tcos-parse statement.pdf
46
+ ```
47
+
48
+ SDK example:
49
+
50
+ ```typescript
51
+ import { ParsePipeline, PhillipPlugin, PluginRegistry } from '@tcos/broker-parser';
52
+
53
+ const registry = new PluginRegistry();
54
+ registry.register(new PhillipPlugin());
55
+
56
+ const pipeline = new ParsePipeline(registry);
57
+ const result = await pipeline.parse('./statement.pdf');
58
+
59
+ console.log(result.data);
60
+ ```
61
+
62
+ ## Notes
63
+
64
+ - The Chinese README is the source of truth.
65
+ - The English file is intentionally brief to avoid documentation drift.
66
+ - If any detail differs, follow [README.md](./README.md).
package/README.md CHANGED
@@ -1,74 +1,359 @@
1
1
  # @tcos/broker-parser
2
2
 
3
- > Parse brokerage PDF statements into structured JSON
3
+ > 将券商 PDF 结单解析为结构化 JSON
4
4
 
5
5
  [![CI](https://github.com/biggersun/broker-parser/actions/workflows/ci.yml/badge.svg)](https://github.com/biggersun/broker-parser/actions)
6
6
  [![npm](https://img.shields.io/npm/v/@tcos/broker-parser)](https://www.npmjs.com/package/@tcos/broker-parser)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
8
8
 
9
- ## Supported Brokers
9
+ English reference: [README.en.md](./README.en.md)
10
10
 
11
- | Broker | Status |
12
- | ----------------------------- | --------- |
13
- | Phillip Securities (辉立证券) | Supported |
11
+ `@tcos/broker-parser` 目前支持 3 种使用方式:
14
12
 
15
- ## Quick Start
13
+ - `CLI`:直接在命令行解析 PDF
14
+ - `npm package`:在你自己的 Node.js / TypeScript 项目中集成解析能力
15
+ - `AI Skill`:为 Claude Code、Codex、OpenClaw 安装 `/parse-statement`
16
16
 
17
- ### Option 1: CLI
17
+ ## 支持的券商
18
+
19
+ | 券商 | 状态 |
20
+ | ------------------------------ | ------ |
21
+ | 辉立证券(Phillip Securities) | 已支持 |
22
+
23
+ ## 运行环境要求
24
+
25
+ 当前版本主要面向类 Unix 环境:
26
+
27
+ - macOS + Homebrew
28
+ - Ubuntu / Debian + `apt-get`
29
+ - 其他 Linux 发行版:如果系统里已经有 `python3`、`pip`、`pdftotext`,也可以使用
30
+
31
+ 运行时依赖:
32
+
33
+ - Node.js 18+
34
+ - Python 3.8+
35
+ - Python 包:`pdfplumber`
36
+ - `poppler` 提供的 `pdftotext`
37
+
38
+ 内置的 `setup` 命令会在 macOS 和 Ubuntu/Debian 上自动安装或校验这些依赖。其他系统不会强行猜测包管理器,而是提示你手动补齐。
39
+
40
+ ## 快速开始
41
+
42
+ ### 1. 命令行直接解析
18
43
 
19
44
  ```bash
20
- # Install
21
45
  npm install -g @tcos/broker-parser
22
-
23
- # Parse a PDF statement
24
46
  tcos-parse statement.pdf
47
+ ```
25
48
 
26
- # Output to file
49
+ 输出到文件:
50
+
51
+ ```bash
27
52
  tcos-parse statement.pdf -o result.json
28
53
  ```
29
54
 
30
- ### Option 2: As an npm Package
55
+ ### 2. 作为 AI Skill 安装
56
+
57
+ 如果你希望在 Agent 里直接使用 `/parse-statement`,推荐按下面顺序执行:
58
+
59
+ ```bash
60
+ npx @tcos/broker-parser setup
61
+ npx @tcos/broker-parser install-skill
62
+ ```
63
+
64
+ 这两步的职责不同:
65
+
66
+ 1. `setup`
67
+ - 安装或检查 `tcos-parse`
68
+ - 安装或检查 `python3`
69
+ - 安装或检查 `pip`
70
+ - 安装或检查 `pdfplumber`
71
+ - 安装或检查 `pdftotext` / `poppler`
72
+ 2. `install-skill`
73
+ - 将 `parse-statement` skill 安装到 Agent 可发现的目录
74
+ - Claude Code:`~/.claude/skills/parse-statement`
75
+ - Codex / OpenClaw:`~/.agents/skills/parse-statement`
76
+
77
+ 安装完成后,重新打开一个新的 Agent 会话,然后可以直接说:
78
+
79
+ - `帮我解析这个券商 PDF 结单`
80
+ - `读取这个辉立证券结单并返回 JSON`
81
+ - `从这个 PDF 提取交易记录、持仓和账户汇总`
82
+
83
+ ### 3. 作为 npm 包使用
31
84
 
32
85
  ```typescript
33
- import { ParsePipeline, PluginRegistry, PhillipPlugin } from '@tcos/broker-parser';
86
+ import { ParsePipeline, PhillipPlugin, PluginRegistry } from '@tcos/broker-parser';
34
87
 
35
88
  const registry = new PluginRegistry();
36
89
  registry.register(new PhillipPlugin());
37
- const pipeline = new ParsePipeline(registry);
38
90
 
91
+ const pipeline = new ParsePipeline(registry);
39
92
  const result = await pipeline.parse('./statement.pdf');
93
+
40
94
  console.log(result.data);
41
95
  ```
42
96
 
43
- ### Option 3: Claude Code Skill (Recommended for Non-Technical Users)
97
+ ## Skill 安装详解
44
98
 
45
- After installing, tell Claude: "Help me parse this PDF statement"
99
+ ### 第一步:`setup`
46
100
 
47
- ## Prerequisites
101
+ ```bash
102
+ npx @tcos/broker-parser setup
103
+ ```
48
104
 
49
- - Node.js 18+
50
- - Python 3.8+ with `pdfplumber` (`pip install pdfplumber`)
51
- - poppler
52
- - macOS: `brew install poppler`
53
- - Ubuntu: `apt-get install poppler-utils`
105
+ 这个命令会做什么:
106
+
107
+ 1. 检查 `PATH` 里是否已经有 `tcos-parse`
108
+ 2. 如果没有,执行 `npm install -g @tcos/broker-parser`
109
+ 3. 检查是否存在 `python3`
110
+ 4. 如果没有:
111
+ - macOS:执行 `brew install python3`
112
+ - Ubuntu / Debian:执行 `sudo apt-get install -y python3 python3-pip`
113
+ 5. 检查 `python3 -m pip` 是否可用
114
+ 6. 如果不可用,执行 `python3 -m ensurepip --upgrade`
115
+ 7. 检查是否能导入 `pdfplumber`
116
+ 8. 如果没有,执行 `python3 -m pip install --user pdfplumber`
117
+ 9. 检查是否存在 `pdftotext`
118
+ 10. 如果没有:
119
+ - macOS:执行 `brew install poppler`
120
+ - Ubuntu / Debian:执行 `sudo apt-get install -y poppler-utils`
121
+
122
+ 适合的环境:
123
+
124
+ - 个人 macOS 开发机器
125
+ - Ubuntu / Debian 开发机或云主机
126
+ - 允许使用 `brew` / `apt-get` / `sudo` 的 shell 环境
127
+
128
+ 不太适合的环境:
129
+
130
+ - 企业受限机器
131
+ - 没有系统包管理器的极简容器
132
+ - Windows 原生环境
133
+
134
+ 可能的副作用:
135
+
136
+ - 会全局安装 `@tcos/broker-parser`
137
+ - 在 Linux 上可能触发 `sudo` 提示
138
+ - 会把 `pdfplumber` 安装到当前用户的 Python 用户目录
139
+ - 可能升级你的系统 Python / poppler 包版本
140
+
141
+ 可选参数:
142
+
143
+ - `--dry-run`:只展示即将执行的动作,不真正执行
144
+
145
+ 示例:
146
+
147
+ ```bash
148
+ npx @tcos/broker-parser setup --dry-run
149
+ tcos-parse setup
150
+ ```
151
+
152
+ 建议先用 `--dry-run` 的情况:
153
+
154
+ - 共享机器
155
+ - CI / Docker 环境
156
+ - 你想先确认它到底会执行哪些安装命令
157
+
158
+ ### 第二步:`install-skill`
159
+
160
+ ```bash
161
+ npx @tcos/broker-parser install-skill
162
+ ```
163
+
164
+ 这个命令会做什么:
165
+
166
+ 1. 找到 `@tcos/broker-parser` 包内自带的 `parse-statement` skill
167
+ 2. 自动探测宿主目录:
168
+ - Claude Code -> `~/.claude/skills`
169
+ - Codex / OpenClaw -> `~/.agents/skills`
170
+ 3. 将 skill 复制到对应目录
171
+ 4. 写入一个小的 manifest 文件,用于后续识别该目录是否由 broker-parser 安装
172
+ 5. 如果检测到相同版本已经安装,会直接跳过
173
+
174
+ 适合的环境:
175
+
176
+ - 本地开发机器
177
+ - 你拥有 `~/.claude` 或 `~/.agents` 写权限的环境
178
+ - 可以方便重启 Agent 会话的环境
179
+
180
+ 可能的副作用:
181
+
182
+ - 会创建或更新 `~/.claude/skills/parse-statement`
183
+ - 会创建或更新 `~/.agents/skills/parse-statement`
184
+ - 不会自动重启你的 Agent 会话
185
+ - 加上 `--force` 时,会先删除旧目录再覆盖安装
186
+
187
+ 可选参数:
188
+
189
+ - `--host auto`:自动探测宿主,默认值
190
+ - `--host claude`:只安装 Claude Code 版本
191
+ - `--host agents`:只安装 Codex / OpenClaw 版本
192
+ - `--dry-run`:只展示安装计划,不真正写文件
193
+ - `--force`:覆盖已有冲突目录
194
+
195
+ 示例:
196
+
197
+ ```bash
198
+ npx @tcos/broker-parser install-skill --host claude
199
+ npx @tcos/broker-parser install-skill --host agents
200
+ npx @tcos/broker-parser install-skill --dry-run
201
+ ```
54
202
 
55
- ## CLI Reference
203
+ 一行完成首次安装:
56
204
 
57
- | Command | Description |
58
- | ------------------------------ | ------------------------------------ |
59
- | `tcos-parse <pdf>` | Parse PDF, output JSON to stdout |
60
- | `tcos-parse <pdf> -o out.json` | Output to file |
61
- | `tcos-parse <pdf> --raw` | Output Stage1 raw data only |
62
- | `tcos-parse <pdf> --no-clean` | Skip Stage3 cleaning step |
63
- | `tcos-parse <pdf> -b phillip` | Specify broker (skip auto-detect) |
64
- | `tcos-parse --detect <pdf>` | Detect which broker a PDF belongs to |
65
- | `tcos-parse --list-parsers` | List available broker parsers |
66
- | `tcos-parse <pdf> -v` | Show stage timing to stderr |
67
- | `tcos-parse <pdf> -q` | Quiet mode, output JSON only |
205
+ ```bash
206
+ npx @tcos/broker-parser setup && npx @tcos/broker-parser install-skill
207
+ ```
208
+
209
+ 适合直接用这一行的情况:
210
+
211
+ - 新机器首次安装
212
+ - 你只想要最短可复制命令
213
+
214
+ 不建议直接一行跑的情况:
215
+
216
+ - 你想先审查 setup 会执行哪些命令
217
+ - 当前机器是共享环境或受限环境
218
+ - 你只想刷新 skill,不想动系统运行时
219
+
220
+ ### 升级与重装
221
+
222
+ 推荐升级流程:
223
+
224
+ ```bash
225
+ npm install -g @tcos/broker-parser@latest
226
+ tcos-parse setup
227
+ tcos-parse install-skill --force
228
+ ```
229
+
230
+ 为什么升级后建议再跑一次 `install-skill --force`:
231
+
232
+ - 当前 skill 安装方式是“复制目录”,不是软链
233
+ - 这样可以避免 `npx` 临时缓存路径失效
234
+ - 但这也意味着升级 npm 包后,旧的 skill 目录不会自动覆盖
235
+
236
+ 如果你只升级了 CLI,不在意 skill 文案或 prompt 版本,也可以跳过 `install-skill --force`
237
+
238
+ ### 手动 fallback
239
+
240
+ 如果你明确想要用软链,而不是复制目录,可以手动这样做:
241
+
242
+ ```bash
243
+ npm install -g @tcos/broker-parser
244
+ mkdir -p ~/.claude/skills ~/.agents/skills
245
+ ln -sfn "$(npm root -g)/@tcos/broker-parser/.claude/skills/parse-statement" ~/.claude/skills/parse-statement
246
+ ln -sfn "$(npm root -g)/@tcos/broker-parser/.claude/skills/parse-statement" ~/.agents/skills/parse-statement
247
+ ```
248
+
249
+ 只有在这些情况下才推荐手动软链:
250
+
251
+ - 你明确想保持 skill 与全局 npm 包目录同步
252
+ - 你正在本地调试 skill 文件
253
+ - 你确认全局 npm 安装路径是稳定的
254
+
255
+ 如果你主要依赖 `npx @tcos/broker-parser ...`,不建议手动软链,因为 `npx` 可能来自临时缓存目录。
256
+
257
+ ## 环境适配建议
258
+
259
+ | 环境 | `setup` | `install-skill` | 建议 |
260
+ | --------------------------- | ---------- | --------------- | ------------------------- |
261
+ | macOS + Homebrew | 完整支持 | 完整支持 | 最佳体验 |
262
+ | Ubuntu / Debian + `apt-get` | 完整支持 | 完整支持 | 最佳体验 |
263
+ | 其他 Linux 发行版 | 部分支持 | 完整支持 | 先手动补 Python / poppler |
264
+ | sudo 受限的远程主机 | 部分支持 | 通常可用 | 先跑 `setup --dry-run` |
265
+ | CI / Docker 镜像 | 部分支持 | 通常没必要 | 更建议把依赖烘焙进镜像 |
266
+ | Windows 原生环境 | 未正式支持 | 不确定 | 如有需要建议使用 WSL |
267
+
268
+ ## 常见问题
269
+
270
+ ### `setup` 过程中要求输入 `sudo`
271
+
272
+ 这是预期行为。Ubuntu / Debian 上如果缺少 `python3` 或 `poppler-utils`,会通过 `sudo apt-get` 安装。
273
+
274
+ 如果当前机器没有 sudo 权限:
275
+
276
+ - 先手动安装这些系统依赖
277
+ - 再重新执行 `tcos-parse setup`
68
278
 
69
- ## Pipeline Architecture
279
+ ### `setup` 提示需要手动安装依赖
70
280
 
281
+ 说明当前系统既没有 `brew`,也没有 `apt-get`。此时需要你手动补齐:
282
+
283
+ - `python3`
284
+ - `python3 -m pip`
285
+ - `python3 -m pip install --user pdfplumber`
286
+ - `pdftotext` / `poppler`
287
+
288
+ 补齐后再跑一次 `tcos-parse setup`。
289
+
290
+ ### `install-skill` 提示没有检测到支持的宿主
291
+
292
+ 常见原因:
293
+
294
+ - Claude / Codex / OpenClaw 还没安装
295
+ - 宿主命令不在 `PATH`
296
+ - `~/.claude` 或 `~/.agents` 目录还没创建
297
+
298
+ 这时可以显式指定:
299
+
300
+ ```bash
301
+ tcos-parse install-skill --host claude
302
+ tcos-parse install-skill --host agents
71
303
  ```
304
+
305
+ ### `install-skill` 提示目标目录已存在
306
+
307
+ 这表示 broker-parser 默认不会覆盖已有目录,以免误删你自己的 skill 内容。
308
+
309
+ 确认可以覆盖后,执行:
310
+
311
+ ```bash
312
+ tcos-parse install-skill --force
313
+ ```
314
+
315
+ ### 安装后 skill 没有立即生效
316
+
317
+ 这通常不是安装失败,而是 Agent 进程还没重新扫描 skill 目录。
318
+
319
+ 做法:
320
+
321
+ - 关闭当前会话
322
+ - 新开一个 Claude / Codex / OpenClaw 会话
323
+ - 再尝试调用 `/parse-statement`
324
+
325
+ ## 方案评审结论
326
+
327
+ 当前方案整体可用,没有明显阻塞问题,但边界需要明确:
328
+
329
+ - `setup` 只对 `brew` 和 `apt-get` 做了自动化支持,其他 Linux 发行版依然以手动安装为主
330
+ - `install-skill` 的宿主探测是保守策略;探测失败时需要用户手动指定 `--host`
331
+ - skill 目录使用复制而不是软链,优点是不会因 `npx` 临时路径失效;代价是升级后需要显式 `--force` 刷新
332
+ - 当前流程默认用户拥有自己 home 目录的写权限,不适合受严格权限控制的多用户共享系统
333
+
334
+ ## CLI 命令参考
335
+
336
+ | 命令 | 说明 |
337
+ | ------------------------------------- | ----------------------------- |
338
+ | `tcos-parse <pdf>` | 解析 PDF,输出 JSON 到 stdout |
339
+ | `tcos-parse <pdf> -o out.json` | 输出到文件 |
340
+ | `tcos-parse <pdf> --raw` | 只输出 Stage1 原始数据 |
341
+ | `tcos-parse <pdf> --no-clean` | 跳过 Stage3 清理 |
342
+ | `tcos-parse <pdf> -b phillip` | 指定券商,跳过自动检测 |
343
+ | `tcos-parse --detect <pdf>` | 检测 PDF 属于哪个券商 |
344
+ | `tcos-parse --list-parsers` | 列出支持的券商解析器 |
345
+ | `tcos-parse <pdf> -v` | 在 stderr 输出阶段耗时 |
346
+ | `tcos-parse <pdf> -q` | 静默模式,只输出 JSON |
347
+ | `tcos-parse setup` | 安装 / 检查运行时依赖 |
348
+ | `tcos-parse setup --dry-run` | 预览 setup 将执行的动作 |
349
+ | `tcos-parse install-skill` | 安装 `/parse-statement` skill |
350
+ | `tcos-parse install-skill --dry-run` | 预览 skill 安装目标 |
351
+ | `tcos-parse install-skill --force` | 覆盖已有冲突目录 |
352
+ | `tcos-parse install-skill --host ...` | 只安装到指定宿主 |
353
+
354
+ ## 解析流程
355
+
356
+ ```text
72
357
  PDF File
73
358
  |
74
359
  Stage1: Extract (pdfplumber)
@@ -83,7 +368,7 @@ PDF File
83
368
  JSON Output
84
369
  ```
85
370
 
86
- ## Output Format
371
+ ## 输出格式
87
372
 
88
373
  ```json
89
374
  {
@@ -98,7 +383,7 @@ PDF File
98
383
  "transactionType": "BUY",
99
384
  "quantity": 1000,
100
385
  "price": 12.34,
101
- "amount": -12340.0,
386
+ "amount": -12340,
102
387
  "currency": "HKD"
103
388
  }
104
389
  ],
@@ -107,44 +392,33 @@ PDF File
107
392
  {
108
393
  "symbol": "HKD",
109
394
  "assetCategory": "Cash",
110
- "quantity": 50000.0,
395
+ "quantity": 50000,
111
396
  "currency": "HKD"
112
397
  }
113
398
  ]
114
399
  }
115
400
  ```
116
401
 
117
- Key type definitions:
402
+ 关键类型:
118
403
 
119
- - **`StatementData`** — Full parsed statement (account info, transactions, IPO records, holdings snapshots)
120
- - **`TradeData`** — Individual trade record (BUY, SELL, DIVIDEND, FEE, etc.)
121
- - **`IPOData`** IPO subscription/allotment record
122
- - **`SnapshotData`** — Holdings snapshot (cash balances, stock positions)
404
+ - `StatementData`:完整结单结果
405
+ - `TradeData`:单条交易记录
406
+ - `IPOData`:IPO 申购 / 分配记录
407
+ - `SnapshotData`:持仓快照
123
408
 
124
- ## Adding a New Broker
409
+ ## 新增券商解析器
125
410
 
126
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for the guide on implementing a new broker plugin.
411
+ 新增券商插件的实现方式见 [CONTRIBUTING.md](./CONTRIBUTING.md)
127
412
 
128
- ## Development
413
+ ## 开发
129
414
 
130
415
  ```bash
131
- # Install dependencies
132
416
  npm install
133
-
134
- # Run CI tests (Stage2 + CLI, no PDF dependency)
135
417
  npm test
136
-
137
- # Run all tests including Stage1 (requires local PDFs)
138
418
  npm run test:local
139
-
140
- # Lint & format
141
419
  npm run lint
142
420
  npm run format:check
143
-
144
- # Type check
145
421
  npm run typecheck
146
-
147
- # Build
148
422
  npm run build
149
423
  ```
150
424
 
@@ -12,6 +12,8 @@
12
12
  * tcos-parse --list-parsers # 列出支持的券商
13
13
  * tcos-parse -v <pdf> # 显示各阶段耗时
14
14
  * tcos-parse -q <pdf> # 静默模式,只输出 JSON
15
+ * tcos-parse setup # 安装运行时依赖
16
+ * tcos-parse install-skill # 安装 parse-statement Skill
15
17
  */
16
18
  export {};
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG"}
package/dist/cli/index.js CHANGED
@@ -13,6 +13,8 @@
13
13
  * tcos-parse --list-parsers # 列出支持的券商
14
14
  * tcos-parse -v <pdf> # 显示各阶段耗时
15
15
  * tcos-parse -q <pdf> # 静默模式,只输出 JSON
16
+ * tcos-parse setup # 安装运行时依赖
17
+ * tcos-parse install-skill # 安装 parse-statement Skill
16
18
  */
17
19
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
20
  if (k2 === undefined) k2 = k;
@@ -54,6 +56,8 @@ const commander_1 = require("commander");
54
56
  const pipeline_1 = require("../core/pipeline");
55
57
  const registry_1 = require("../core/registry");
56
58
  const phillip_1 = require("../parsers/phillip");
59
+ const install_skill_1 = require("./install-skill");
60
+ const setup_1 = require("./setup");
57
61
  // 初始化插件注册表
58
62
  const registry = new registry_1.PluginRegistry();
59
63
  registry.register(new phillip_1.PhillipPlugin());
@@ -63,6 +67,62 @@ program
63
67
  .name('tcos-parse')
64
68
  .description('Parse brokerage PDF statements into structured JSON')
65
69
  .version('0.1.0');
70
+ program
71
+ .command('install-skill')
72
+ .description('install parse-statement skill for Claude, Codex, or OpenClaw')
73
+ .option('--host <host>', 'install target: auto | claude | agents', 'auto')
74
+ .option('--force', 'replace existing target if it already exists')
75
+ .option('--dry-run', 'show planned install actions without writing files')
76
+ .action((opts) => {
77
+ try {
78
+ const result = (0, install_skill_1.installSkill)({
79
+ host: (0, install_skill_1.normalizeInstallHost)(opts.host),
80
+ force: opts.force,
81
+ dryRun: opts.dryRun,
82
+ });
83
+ console.log(`Skill source: ${result.sourcePath}`);
84
+ for (const action of result.actions) {
85
+ const hostLabel = action.host === 'claude' ? 'Claude Code' : 'Agent Skills';
86
+ console.log(`[${hostLabel}] ${action.message}: ${action.targetPath}`);
87
+ }
88
+ if (!opts.dryRun) {
89
+ console.log('Open a new agent session to use /parse-statement.');
90
+ }
91
+ }
92
+ catch (err) {
93
+ const message = err instanceof Error ? err.message : String(err);
94
+ process.stderr.write(`Error: ${message}\n`);
95
+ process.exit(1);
96
+ }
97
+ });
98
+ program
99
+ .command('setup')
100
+ .description('install runtime dependencies required by broker-parser')
101
+ .option('--dry-run', 'show planned setup actions without running commands')
102
+ .action((opts) => {
103
+ try {
104
+ const result = (0, setup_1.setupEnvironment)({
105
+ dryRun: opts.dryRun,
106
+ });
107
+ for (const action of result.actions) {
108
+ const prefix = `[${action.status}]`;
109
+ if (action.command) {
110
+ console.log(`${prefix} ${action.message}: ${action.command} ${action.args?.join(' ') ?? ''}`);
111
+ }
112
+ else {
113
+ console.log(`${prefix} ${action.message}`);
114
+ }
115
+ }
116
+ if (!opts.dryRun) {
117
+ console.log('Setup finished. You can now run tcos-parse or install the skill.');
118
+ }
119
+ }
120
+ catch (err) {
121
+ const message = err instanceof Error ? err.message : String(err);
122
+ process.stderr.write(`Error: ${message}\n`);
123
+ process.exit(1);
124
+ }
125
+ });
66
126
  // 主命令:解析 PDF
67
127
  program
68
128
  .argument('[pdf]', 'PDF statement file to parse')
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAE7B,yCAAoC;AAEpC,+CAAiD;AACjD,+CAAkD;AAClD,gDAAmD;AAEnD,WAAW;AACX,MAAM,QAAQ,GAAG,IAAI,yBAAc,EAAE,CAAC;AACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,uBAAa,EAAE,CAAC,CAAC;AACvC,MAAM,QAAQ,GAAG,IAAI,wBAAa,CAAC,QAAQ,CAAC,CAAC;AAE7C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,qDAAqD,CAAC;KAClE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,aAAa;AACb,OAAO;KACJ,QAAQ,CAAC,OAAO,EAAE,6BAA6B,CAAC;KAChD,MAAM,CAAC,qBAAqB,EAAE,kCAAkC,CAAC;KACjE,MAAM,CAAC,qBAAqB,EAAE,uCAAuC,CAAC;KACtE,MAAM,CAAC,OAAO,EAAE,6BAA6B,CAAC;KAC9C,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC;KAC1C,MAAM,CAAC,eAAe,EAAE,+BAA+B,CAAC;KACxD,MAAM,CAAC,aAAa,EAAE,+BAA+B,CAAC;KACtD,MAAM,CAAC,UAAU,EAAE,kCAAkC,CAAC;KACtD,MAAM,CAAC,gBAAgB,EAAE,+BAA+B,CAAC;KACzD,MAAM,CACL,KAAK,EACH,MAA0B,EAC1B,IASC,EACD,EAAE;IACF,yBAAyB;IACzB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,OAAO;IACT,CAAC;IAED,iBAAiB;IACjB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAErC,WAAW;IACX,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kBAAkB;IAClB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,QAAQ,GAAG,SAAS,CAAC;QACzB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;gBACtB,SAAS,GAAG,KAAK,CAAC;gBAClB,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,iBAAiB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACpF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QACD,OAAO;IACT,CAAC;IAED,OAAO;IACP,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE;YAC3C,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,oDAAoD;YAC1E,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QAEH,0CAA0C;QAC1C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC,MAAM,KAAK;gBACnD,UAAU,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,KAAK,MAAM,CACjE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAElD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3D,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CACF,CAAC;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export type SkillInstallHost = 'auto' | 'claude' | 'agents';
2
+ export type SkillTarget = 'claude' | 'agents';
3
+ export interface DetectHostsOptions {
4
+ homeDir?: string;
5
+ hasCommand?: (command: string) => boolean;
6
+ }
7
+ export interface InstallSkillOptions extends DetectHostsOptions {
8
+ host?: SkillInstallHost;
9
+ dryRun?: boolean;
10
+ force?: boolean;
11
+ packageRoot?: string;
12
+ }
13
+ export interface InstallSkillAction {
14
+ host: SkillTarget;
15
+ sourcePath: string;
16
+ targetPath: string;
17
+ status: 'installed' | 'skipped';
18
+ message: string;
19
+ }
20
+ export interface InstallSkillResult {
21
+ sourcePath: string;
22
+ actions: InstallSkillAction[];
23
+ }
24
+ /** 返回包内 Skill 的发布路径。 */
25
+ export declare function resolveSkillSourcePath(packageRoot?: string): string;
26
+ /** 从 src/cli 或 dist/cli 目录反推出包根目录。 */
27
+ export declare function resolvePackageRoot(currentDir?: string): string;
28
+ /** 根据本机环境探测需要安装到哪些宿主目录。 */
29
+ export declare function detectInstallTargets(options?: DetectHostsOptions): SkillTarget[];
30
+ /** 校验并规范化 host 参数。 */
31
+ export declare function normalizeInstallHost(host: string): SkillInstallHost;
32
+ /** 返回指定宿主的 Skill 安装目标路径。 */
33
+ export declare function resolveSkillTargetPath(host: SkillTarget, homeDir?: string): string;
34
+ /** 以统一规则安装 parse-statement Skill。 */
35
+ export declare function installSkill(options?: InstallSkillOptions): InstallSkillResult;
36
+ //# sourceMappingURL=install-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/cli/install-skill.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC5D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AA4CD,wBAAwB;AACxB,wBAAgB,sBAAsB,CAAC,WAAW,SAAuB,GAAG,MAAM,CAEjF;AAED,sCAAsC;AACtC,wBAAgB,kBAAkB,CAAC,UAAU,SAAY,GAAG,MAAM,CAEjE;AAED,2BAA2B;AAC3B,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,EAAE,CAiBpF;AAED,sBAAsB;AACtB,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAMnE;AAED,4BAA4B;AAC5B,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,SAAe,GAAG,MAAM,CAMxF;AA8BD,qCAAqC;AACrC,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CAiGlF"}
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveSkillSourcePath = resolveSkillSourcePath;
37
+ exports.resolvePackageRoot = resolvePackageRoot;
38
+ exports.detectInstallTargets = detectInstallTargets;
39
+ exports.normalizeInstallHost = normalizeInstallHost;
40
+ exports.resolveSkillTargetPath = resolveSkillTargetPath;
41
+ exports.installSkill = installSkill;
42
+ const fs = __importStar(require("fs"));
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const SKILL_NAME = 'parse-statement';
46
+ const MANIFEST_FILE = '.broker-parser-install.json';
47
+ /** 检查命令是否存在于当前 PATH。 */
48
+ function commandExists(command) {
49
+ const pathValue = process.env.PATH;
50
+ if (!pathValue)
51
+ return false;
52
+ for (const dir of pathValue.split(path.delimiter)) {
53
+ if (!dir)
54
+ continue;
55
+ const candidate = path.join(dir, command);
56
+ if (fs.existsSync(candidate)) {
57
+ return true;
58
+ }
59
+ }
60
+ return false;
61
+ }
62
+ /** 读取当前包的基础信息。 */
63
+ function readPackageInfo(packageRoot) {
64
+ const packageJsonPath = path.join(packageRoot, 'package.json');
65
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
66
+ return {
67
+ name: packageJson.name ?? '@tcos/broker-parser',
68
+ version: packageJson.version ?? '0.0.0',
69
+ };
70
+ }
71
+ /** 返回包内 Skill 的发布路径。 */
72
+ function resolveSkillSourcePath(packageRoot = resolvePackageRoot()) {
73
+ return path.join(packageRoot, '.claude', 'skills', SKILL_NAME);
74
+ }
75
+ /** 从 src/cli 或 dist/cli 目录反推出包根目录。 */
76
+ function resolvePackageRoot(currentDir = __dirname) {
77
+ return path.resolve(currentDir, '..', '..');
78
+ }
79
+ /** 根据本机环境探测需要安装到哪些宿主目录。 */
80
+ function detectInstallTargets(options = {}) {
81
+ const homeDir = options.homeDir ?? os.homedir();
82
+ const hasCommand = options.hasCommand ?? commandExists;
83
+ const supportsClaude = hasCommand('claude') || fs.existsSync(path.join(homeDir, '.claude'));
84
+ const supportsAgentSkills = hasCommand('codex') || hasCommand('openclaw') || fs.existsSync(path.join(homeDir, '.agents'));
85
+ const targets = [];
86
+ if (supportsClaude) {
87
+ targets.push('claude');
88
+ }
89
+ if (supportsAgentSkills) {
90
+ targets.push('agents');
91
+ }
92
+ return targets;
93
+ }
94
+ /** 校验并规范化 host 参数。 */
95
+ function normalizeInstallHost(host) {
96
+ if (host === 'auto' || host === 'claude' || host === 'agents') {
97
+ return host;
98
+ }
99
+ throw new Error(`Invalid host: ${host}. Expected auto, claude, or agents.`);
100
+ }
101
+ /** 返回指定宿主的 Skill 安装目标路径。 */
102
+ function resolveSkillTargetPath(host, homeDir = os.homedir()) {
103
+ if (host === 'claude') {
104
+ return path.join(homeDir, '.claude', 'skills', SKILL_NAME);
105
+ }
106
+ return path.join(homeDir, '.agents', 'skills', SKILL_NAME);
107
+ }
108
+ /** 读取安装清单,用于识别是否为 broker-parser 管理的目录。 */
109
+ function readInstallManifest(targetPath) {
110
+ const manifestPath = path.join(targetPath, MANIFEST_FILE);
111
+ if (!fs.existsSync(manifestPath)) {
112
+ return null;
113
+ }
114
+ try {
115
+ return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
116
+ }
117
+ catch {
118
+ return null;
119
+ }
120
+ }
121
+ /** 复制 Skill 目录并写入安装清单,避免 npx 临时目录软链失效。 */
122
+ function copySkillDirectory(sourcePath, targetPath, manifest) {
123
+ fs.cpSync(sourcePath, targetPath, { recursive: true });
124
+ fs.writeFileSync(path.join(targetPath, MANIFEST_FILE), JSON.stringify(manifest, null, 2), 'utf-8');
125
+ }
126
+ /** 以统一规则安装 parse-statement Skill。 */
127
+ function installSkill(options = {}) {
128
+ const packageRoot = options.packageRoot ?? resolvePackageRoot();
129
+ const packageInfo = readPackageInfo(packageRoot);
130
+ const manifest = {
131
+ ...packageInfo,
132
+ skillName: SKILL_NAME,
133
+ };
134
+ const sourcePath = resolveSkillSourcePath(packageRoot);
135
+ const homeDir = options.homeDir ?? os.homedir();
136
+ const host = normalizeInstallHost(options.host ?? 'auto');
137
+ const dryRun = options.dryRun ?? false;
138
+ const force = options.force ?? false;
139
+ if (!fs.existsSync(sourcePath)) {
140
+ throw new Error(`Skill source not found: ${sourcePath}`);
141
+ }
142
+ const targets = host === 'auto' ? detectInstallTargets(options) : [host];
143
+ if (targets.length === 0) {
144
+ throw new Error('No supported host detected. Use --host claude or --host agents to install manually.');
145
+ }
146
+ const actions = [];
147
+ for (const targetHost of targets) {
148
+ const targetPath = resolveSkillTargetPath(targetHost, homeDir);
149
+ const targetDir = path.dirname(targetPath);
150
+ if (!dryRun) {
151
+ fs.mkdirSync(targetDir, { recursive: true });
152
+ }
153
+ if (fs.existsSync(targetPath)) {
154
+ const stat = fs.lstatSync(targetPath);
155
+ if (stat.isSymbolicLink()) {
156
+ const currentLink = fs.readlinkSync(targetPath);
157
+ const resolvedLink = path.resolve(path.dirname(targetPath), currentLink);
158
+ if (resolvedLink === sourcePath) {
159
+ actions.push({
160
+ host: targetHost,
161
+ sourcePath,
162
+ targetPath,
163
+ status: 'skipped',
164
+ message: 'already installed',
165
+ });
166
+ continue;
167
+ }
168
+ }
169
+ if (stat.isDirectory()) {
170
+ const existingManifest = readInstallManifest(targetPath);
171
+ if (existingManifest &&
172
+ existingManifest.name === manifest.name &&
173
+ existingManifest.version === manifest.version &&
174
+ existingManifest.skillName === manifest.skillName) {
175
+ actions.push({
176
+ host: targetHost,
177
+ sourcePath,
178
+ targetPath,
179
+ status: 'skipped',
180
+ message: 'already installed',
181
+ });
182
+ continue;
183
+ }
184
+ }
185
+ if (!force) {
186
+ throw new Error(`Skill target already exists: ${targetPath}. Re-run with --force to replace it.`);
187
+ }
188
+ if (!dryRun) {
189
+ fs.rmSync(targetPath, { recursive: true, force: true });
190
+ }
191
+ }
192
+ if (!dryRun) {
193
+ copySkillDirectory(sourcePath, targetPath, manifest);
194
+ }
195
+ actions.push({
196
+ host: targetHost,
197
+ sourcePath,
198
+ targetPath,
199
+ status: 'installed',
200
+ message: dryRun ? 'planned' : 'installed',
201
+ });
202
+ }
203
+ return { sourcePath, actions };
204
+ }
205
+ //# sourceMappingURL=install-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../src/cli/install-skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface SetupEnvironmentOptions {
2
+ dryRun?: boolean;
3
+ hasCommand?: (command: string) => boolean;
4
+ pythonHasModule?: (pythonBin: string, moduleName: string) => boolean;
5
+ pythonHasPip?: (pythonBin: string) => boolean;
6
+ runCommand?: (command: string, args: string[]) => void;
7
+ packageName?: string;
8
+ }
9
+ export interface SetupAction {
10
+ status: 'installed' | 'skipped' | 'planned' | 'manual';
11
+ message: string;
12
+ command?: string;
13
+ args?: string[];
14
+ }
15
+ export interface SetupEnvironmentResult {
16
+ actions: SetupAction[];
17
+ }
18
+ /** 安装或检查运行时依赖。 */
19
+ export declare function setupEnvironment(options?: SetupEnvironmentOptions): SetupEnvironmentResult;
20
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IACrE,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAwED,kBAAkB;AAClB,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,sBAAsB,CAgH9F"}
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.setupEnvironment = setupEnvironment;
37
+ const child_process_1 = require("child_process");
38
+ const path = __importStar(require("path"));
39
+ /** 检查命令是否存在于当前 PATH。 */
40
+ function commandExists(command) {
41
+ const pathValue = process.env.PATH;
42
+ if (!pathValue)
43
+ return false;
44
+ for (const dir of pathValue.split(path.delimiter)) {
45
+ if (!dir)
46
+ continue;
47
+ const candidate = path.join(dir, command);
48
+ const probe = (0, child_process_1.spawnSync)(candidate, ['--version'], { stdio: 'ignore' });
49
+ if (!probe.error) {
50
+ return true;
51
+ }
52
+ }
53
+ return false;
54
+ }
55
+ /** 检查 python 模块是否可导入。 */
56
+ function defaultPythonHasModule(pythonBin, moduleName) {
57
+ const probe = (0, child_process_1.spawnSync)(pythonBin, ['-c', `import ${moduleName}`], { stdio: 'ignore' });
58
+ return probe.status === 0;
59
+ }
60
+ /** 检查 python3 是否已具备 pip。 */
61
+ function defaultPythonHasPip(pythonBin) {
62
+ const probe = (0, child_process_1.spawnSync)(pythonBin, ['-m', 'pip', '--version'], { stdio: 'ignore' });
63
+ return probe.status === 0;
64
+ }
65
+ /** 执行外部命令,并在失败时抛出异常。 */
66
+ function defaultRunCommand(command, args) {
67
+ const result = (0, child_process_1.spawnSync)(command, args, { stdio: 'inherit' });
68
+ if (result.error) {
69
+ throw result.error;
70
+ }
71
+ if (result.status !== 0) {
72
+ throw new Error(`Command failed: ${command} ${args.join(' ')}`);
73
+ }
74
+ }
75
+ /** 执行或计划一条 setup 动作。 */
76
+ function executeOrPlan(actions, dryRun, runCommand, message, command, args) {
77
+ if (dryRun) {
78
+ actions.push({
79
+ status: 'planned',
80
+ message,
81
+ command,
82
+ args,
83
+ });
84
+ return;
85
+ }
86
+ runCommand(command, args);
87
+ actions.push({
88
+ status: 'installed',
89
+ message,
90
+ command,
91
+ args,
92
+ });
93
+ }
94
+ /** 安装或检查运行时依赖。 */
95
+ function setupEnvironment(options = {}) {
96
+ const dryRun = options.dryRun ?? false;
97
+ const hasCommand = options.hasCommand ?? commandExists;
98
+ const pythonHasModule = options.pythonHasModule ?? defaultPythonHasModule;
99
+ const pythonHasPip = options.pythonHasPip ?? defaultPythonHasPip;
100
+ const runCommand = options.runCommand ?? defaultRunCommand;
101
+ const packageName = options.packageName ?? '@tcos/broker-parser';
102
+ const actions = [];
103
+ const hasBrew = hasCommand('brew');
104
+ const hasApt = hasCommand('apt-get');
105
+ if (!hasCommand('tcos-parse')) {
106
+ executeOrPlan(actions, dryRun, runCommand, 'install global tcos-parse CLI', 'npm', [
107
+ 'install',
108
+ '-g',
109
+ packageName,
110
+ ]);
111
+ }
112
+ else {
113
+ actions.push({
114
+ status: 'skipped',
115
+ message: 'tcos-parse already available',
116
+ });
117
+ }
118
+ let pythonReady = hasCommand('python3');
119
+ if (!pythonReady) {
120
+ if (hasBrew) {
121
+ executeOrPlan(actions, dryRun, runCommand, 'install python3 via Homebrew', 'brew', [
122
+ 'install',
123
+ 'python3',
124
+ ]);
125
+ pythonReady = true;
126
+ }
127
+ else if (hasApt) {
128
+ executeOrPlan(actions, dryRun, runCommand, 'install python3 and pip via apt-get', 'sudo', [
129
+ 'apt-get',
130
+ 'install',
131
+ '-y',
132
+ 'python3',
133
+ 'python3-pip',
134
+ ]);
135
+ pythonReady = true;
136
+ }
137
+ else {
138
+ actions.push({
139
+ status: 'manual',
140
+ message: 'python3 not found; install Python 3 manually',
141
+ });
142
+ }
143
+ }
144
+ else {
145
+ actions.push({
146
+ status: 'skipped',
147
+ message: 'python3 already available',
148
+ });
149
+ }
150
+ if (pythonReady) {
151
+ if (!pythonHasPip('python3')) {
152
+ executeOrPlan(actions, dryRun, runCommand, 'install pip for python3', 'python3', [
153
+ '-m',
154
+ 'ensurepip',
155
+ '--upgrade',
156
+ ]);
157
+ }
158
+ else {
159
+ actions.push({
160
+ status: 'skipped',
161
+ message: 'python3 pip already available',
162
+ });
163
+ }
164
+ if (!pythonHasModule('python3', 'pdfplumber')) {
165
+ executeOrPlan(actions, dryRun, runCommand, 'install pdfplumber for current user', 'python3', [
166
+ '-m',
167
+ 'pip',
168
+ 'install',
169
+ '--user',
170
+ 'pdfplumber',
171
+ ]);
172
+ }
173
+ else {
174
+ actions.push({
175
+ status: 'skipped',
176
+ message: 'pdfplumber already available',
177
+ });
178
+ }
179
+ }
180
+ if (!hasCommand('pdftotext')) {
181
+ if (hasBrew) {
182
+ executeOrPlan(actions, dryRun, runCommand, 'install poppler via Homebrew', 'brew', [
183
+ 'install',
184
+ 'poppler',
185
+ ]);
186
+ }
187
+ else if (hasApt) {
188
+ executeOrPlan(actions, dryRun, runCommand, 'install poppler via apt-get', 'sudo', [
189
+ 'apt-get',
190
+ 'install',
191
+ '-y',
192
+ 'poppler-utils',
193
+ ]);
194
+ }
195
+ else {
196
+ actions.push({
197
+ status: 'manual',
198
+ message: 'pdftotext not found; install poppler manually if your system requires it',
199
+ });
200
+ }
201
+ }
202
+ else {
203
+ actions.push({
204
+ status: 'skipped',
205
+ message: 'pdftotext already available',
206
+ });
207
+ }
208
+ return { actions };
209
+ }
210
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tcos/broker-parser",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Parse brokerage PDF statements into structured JSON",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",