xparse-cli 0.0.0 → 2.2.1-beta.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
@@ -1,9 +1,381 @@
1
- # xparse-cli
1
+ # xParser CLI
2
2
 
3
- The stable npm channel is reserved but not released yet.
3
+ Textin xParser 文档解析命令行工具,基于 [TextIn xParse API](https://docs.textin.com/api-reference/endpoint/xparse/v1/parse-sync) 实现。
4
4
 
5
- To opt in to the beta, install it explicitly:
5
+ 支持将 PDF、图片、Office 文档等 20+ 格式转换为 Markdown 及结构化数据。
6
+
7
+ ## 安装
8
+
9
+ ### npm Beta
10
+
11
+ 需要 Node.js 18 或更高版本。Beta 版本必须显式安装,不会被普通安装或升级自动选中:
12
+
13
+ ```bash
14
+ npm install -g xparse-cli@2.2.1-beta.1
15
+ ```
16
+
17
+ 安装后可运行 `xparse-cli version` 检查版本。
18
+
19
+ ### 一键安装
20
+
21
+ **Linux / macOS**
22
+
23
+ ```bash
24
+ source <(curl -fsSL https://dllf.intsig.net/download/2026/Solution/xparse-cli/install.sh)
25
+ ```
26
+
27
+ **Windows (PowerShell)**
28
+
29
+ ```powershell
30
+ irm https://dllf.intsig.net/download/2026/Solution/xparse-cli/install.ps1 | iex
31
+ ```
32
+
33
+ ### 从源码构建
34
+
35
+ > 要求 Go 1.23+
36
+
37
+ **单平台构建(当前系统):**
38
+
39
+ ```bash
40
+ go build -o xparse-cli .
41
+ ```
42
+
43
+ **带版本信息构建:**
44
+
45
+ ```bash
46
+ VERSION=v0.0.1
47
+ COMMIT=$(git rev-parse --short HEAD)
48
+ DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
49
+ PKG=github.com/intsig-textin/xparse-skills/cli/cmd/parse
50
+
51
+ go build -ldflags "-s -w \
52
+ -X ${PKG}.version=${VERSION} \
53
+ -X ${PKG}.commit=${COMMIT} \
54
+ -X ${PKG}.date=${DATE}" \
55
+ -o xparse-cli .
56
+ ```
57
+
58
+ **交叉编译全平台:**
59
+
60
+ ```bash
61
+ VERSION=v0.0.1
62
+ COMMIT=$(git rev-parse --short HEAD)
63
+ DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
64
+ PKG=github.com/intsig-textin/xparse-skills/cli/cmd/parse
65
+ LDFLAGS="-s -w -X ${PKG}.version=${VERSION} -X ${PKG}.commit=${COMMIT} -X ${PKG}.date=${DATE}"
66
+
67
+ GOOS=linux GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/xparse-cli-linux-amd64 .
68
+ GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -o dist/xparse-cli-linux-arm64 .
69
+ GOOS=darwin GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/xparse-cli-darwin-amd64 .
70
+ GOOS=darwin GOARCH=arm64 go build -ldflags "$LDFLAGS" -o dist/xparse-cli-darwin-arm64 .
71
+ GOOS=windows GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/xparse-cli-windows-amd64.exe .
72
+ GOOS=windows GOARCH=arm64 go build -ldflags "$LDFLAGS" -o dist/xparse-cli-windows-arm64.exe .
73
+ ```
74
+
75
+ 产物位于 `dist/` 目录,共 6 个二进制文件:
76
+
77
+ | 平台 | 文件 |
78
+ |------|------|
79
+ | Linux x86_64 | `xparse-cli-linux-amd64` |
80
+ | Linux ARM64 | `xparse-cli-linux-arm64` |
81
+ | macOS Intel | `xparse-cli-darwin-amd64` |
82
+ | macOS Apple Silicon | `xparse-cli-darwin-arm64` |
83
+ | Windows x86_64 | `xparse-cli-windows-amd64.exe` |
84
+ | Windows ARM64 | `xparse-cli-windows-arm64.exe` |
85
+
86
+ ## 快速开始
87
+
88
+ ### 1. 零配置解析(自动使用免费额度)
89
+
90
+ ```bash
91
+ # 输出 Markdown 到终端
92
+ xparse-cli parse report.pdf
93
+
94
+ # JSON 视图
95
+ xparse-cli parse report.pdf --view json
96
+
97
+ # 保存到目录
98
+ xparse-cli parse report.pdf --output ./output/
99
+
100
+ # 指定页码范围
101
+ xparse-cli parse report.pdf --page-range "1-5"
102
+
103
+ # 加密 PDF
104
+ xparse-cli parse secret.pdf --password mypassword
105
+ ```
106
+
107
+ ### 2. 付费 API(可选)
108
+
109
+ 前往 [Textin 控制台](https://www.textin.com/user/login?redirect=%252Fconsole%252Fdashboard%252Fsetting&from=xparse-parse-skill) 获取凭证(`x-ti-app-id` 和 `x-ti-secret-code`),然后运行:
110
+
111
+ ```bash
112
+ xparse-cli auth
113
+ ```
114
+
115
+ 按提示输入 App ID 和 Secret Code,凭证将保存至 `~/.xparse-cli/config.yaml`。
116
+
117
+ 也可通过环境变量配置(适合 CI/CD):
118
+
119
+ ```bash
120
+ export XPARSE_APP_ID=your_app_id
121
+ export XPARSE_SECRET_CODE=your_secret_code
122
+ ```
6
123
 
7
124
  ```bash
8
- npm install -g xparse-cli@beta
125
+ # 显式使用付费 API
126
+ xparse-cli parse report.pdf --api paid
9
127
  ```
128
+
129
+ 也可以使用 OAuth。正式二进制默认使用无 Secret 的 public client
130
+ `cli_textin_xparse`;私有部署可以通过 flag、环境变量或配置文件覆盖:
131
+
132
+ ```bash
133
+ # 终端中进入 AppKey / OAuth / 状态 / 登出选单
134
+ xparse-cli auth
135
+
136
+ export XPARSE_OAUTH_CLIENT_ID=cli_your_registered_client
137
+
138
+ # Device Flow(SSH、服务器、Agent 推荐)
139
+ xparse-cli auth device --open-browser=never
140
+
141
+ # 本地桌面 Authorization Code + PKCE;默认使用系统分配的可用回调端口
142
+ xparse-cli auth browser
143
+
144
+ # 强制重新展示授权确认页
145
+ xparse-cli auth browser --prompt=consent
146
+
147
+ # 显式使用 OAuth 调用 paid API
148
+ xparse-cli parse report.pdf --api paid --auth-method oauth
149
+ ```
150
+
151
+ 认证选单使用方向键或 `j`/`k` 移动,`Enter` 确认,`Esc` 或 `Ctrl+C` 取消。
152
+ 菜单会显示当前环境、OAuth/AppKey 配置状态和当前生效的认证方式。需要屏幕阅读器兼容的
153
+ 线性提示时,可设置 `XPARSE_TUI_ACCESSIBLE=1`。
154
+
155
+ WorkBuddy Connector 使用显式 Profile,避免依赖任务进程是否继承 Connector 环境变量:
156
+
157
+ ```bash
158
+ xparse-cli --profile workbuddy auth device --open-browser=always
159
+ xparse-cli --profile workbuddy parse report.pdf --api paid --auth-method oauth
160
+ ```
161
+
162
+ 该 Profile 的凭证保存在 `~/.xparse-cli/profiles/workbuddy/`,其登录和登出不会影响
163
+ 终端中默认的 `~/.xparse-cli` 凭证;请求会自动携带 `X-From: workbuddy`。
164
+
165
+ ## 命令一览
166
+
167
+ | 命令 | 说明 |
168
+ |------|------|
169
+ | `xparse-cli parse` | 解析文档,输出 Markdown / JSON |
170
+ | `xparse-cli auth` | TTY 中进入认证选单;非 TTY 保持旧版 AppKey 输入流程 |
171
+ | `xparse-cli auth app-key` | 配置 AppKey 凭证 |
172
+ | `xparse-cli auth device` | OAuth Device Flow 登录 |
173
+ | `xparse-cli auth browser` | OAuth Authorization Code + PKCE 登录 |
174
+ | `xparse-cli auth status` | 只读查看登录状态 |
175
+ | `xparse-cli auth logout` | 删除指定认证方式的本地凭证 |
176
+ | `xparse-cli config` | 管理配置(show / set / reset / path) |
177
+ | `xparse-cli quota` | 查看免费 API 额度 |
178
+ | `xparse-cli download` | 下载解析结果中 elements 的图片 |
179
+ | `xparse-cli update` | 自更新 CLI 到最新版本 |
180
+ | `xparse-cli version` | 显示版本信息 |
181
+
182
+ 全局参数 `--profile workbuddy` 可放在子命令前后,用于选择 WorkBuddy 的隔离凭证。
183
+
184
+ ## parse 命令参数
185
+
186
+ | 参数 | 默认值 | 说明 |
187
+ |------|--------|------|
188
+ | `--view` | `markdown` | 输出视图:`markdown`、`json` |
189
+ | `--api` | `auto` | API 模式:`auto`、`free`、`paid`;`auto` 根据服务端额度快照路由 |
190
+ | `--auth-method` | _(自动)_ | 请求认证:`app-key`、`oauth` |
191
+ | `--page-range` | | 页码范围:`"1-5"` 或 `"1-2,5-10"` |
192
+ | `--password` | | 加密文档密码 |
193
+ | `--include-hierarchy` | `true` | 元素层级关系与父子关联,默认开启。为 `false` 时关闭 |
194
+ | `--include-inline-objects` | `true` | 内嵌对象:公式、手写、复选框、嵌入图片,默认开启。为 `false` 时关闭 |
195
+ | `--include-image-data` | `true` | 图片 URL 及 Base64 数据,默认开启。为 `false` 时关闭 |
196
+ | `--include-table-structure` | `true` | 表格单元格结构与坐标,默认开启。为 `false` 时关闭 |
197
+ | `--include-pages` | `true` | 分页元数据与预览图 |
198
+ | `--include-title-tree` | `true` | 文档标题层级目录树 |
199
+ | `--include-char-details` | `false` | 返回字符级坐标和置信度 |
200
+ | `--table-view` | `html` | 表格视图:`html`、`markdown` |
201
+ | `--list` | | 从文件读取输入列表(需配合 `--output`) |
202
+ | `--output` | _(stdout)_ | 输出文件路径或目录(目录须已存在) |
203
+
204
+ **全局参数(所有命令均支持):**
205
+
206
+ | 参数 | 说明 |
207
+ |------|------|
208
+ | `--app-id` | Textin App ID(覆盖环境变量和配置文件) |
209
+ | `--secret-code` | Textin Secret Code(覆盖环境变量和配置文件) |
210
+ | `--base-url` | API 地址(私有化部署时使用) |
211
+ | `--verbose` | 调试模式,打印 HTTP 请求详情 |
212
+
213
+ ### API capabilities 默认值
214
+
215
+ CLI 默认开启以下能力,Agent 无需额外配置:
216
+
217
+ | 能力 | 默认 |
218
+ |------|------|
219
+ | 标题层级 | 开启 |
220
+ | 内嵌对象(图片) | 开启 |
221
+ | 图片数据 | 开启 |
222
+ | 表格视图 | `html` |
223
+ | 表格结构 | 开启 |
224
+ | 分页结果 | 开启 |
225
+ | 目录树 | 开启 |
226
+ | 字符级详情 | **关闭**(`--include-char-details` 开启) |
227
+
228
+ ## 使用示例
229
+
230
+ ### 管道组合
231
+
232
+ ```bash
233
+ # 解析并搜索
234
+ xparse-cli parse report.pdf | grep "revenue"
235
+
236
+ # 解析并喂给 LLM
237
+ xparse-cli parse paper.pdf | llm "summarize this paper"
238
+ ```
239
+
240
+ ### 批量处理
241
+
242
+ ```bash
243
+ # 从文件列表读取
244
+ xparse-cli parse --list files.txt --output ./results/
245
+ ```
246
+
247
+ ### 下载图片
248
+
249
+ ```bash
250
+ # 从解析结果 JSON 中提取 elements 图片并下载
251
+ xparse-cli download --from result.json --output ./images/
252
+
253
+ # 直接下载图片 URL
254
+ xparse-cli download https://web-api.textin.com/ocr_image/external/abc123.jpg --output ./images/
255
+ ```
256
+
257
+ ### 配置管理
258
+
259
+ ```bash
260
+ xparse-cli config show
261
+ xparse-cli config set base_url https://your-server.com
262
+ xparse-cli config reset
263
+ xparse-cli config path
264
+ ```
265
+
266
+ ### 自更新
267
+
268
+ ```bash
269
+ xparse-cli update
270
+ ```
271
+
272
+ ### 调试模式
273
+
274
+ ```bash
275
+ xparse-cli parse report.pdf --verbose
276
+ ```
277
+
278
+ ## 凭证管理
279
+
280
+ | 优先级 | 方式 | 说明 |
281
+ |--------|------|------|
282
+ | 1 | 命令行参数 | `--app-id` 和 `--secret-code` |
283
+ | 2 | 环境变量 | `XPARSE_APP_ID` 和 `XPARSE_SECRET_CODE` |
284
+ | 3 | 配置文件 | `~/.xparse-cli/config.yaml` |
285
+
286
+ AppKey 与 OAuth Token 分开保存:
287
+
288
+ ```text
289
+ ~/.xparse-cli/config.yaml # AppKey 和非敏感 OAuth 偏好
290
+ ~/.xparse-cli/oauth-token.json # OAuth Access/Refresh Token
291
+ ```
292
+
293
+ 目录权限固定为 `0700`,凭证文件固定为 `0600`,更新通过 fsync + rename 原子替换。
294
+ `xparse-cli config reset` 只重置 YAML,不会删除 OAuth Token;请使用
295
+ `xparse-cli auth logout --method oauth|app-key|all` 精确登出。
296
+ OAuth 登出会先尝试通过 `/oauth21/revoke` 撤销 Refresh Token(没有时撤销 Access
297
+ Token),随后始终删除本地 Token。远端暂时不可用只会产生警告,不会阻止本地登出;
298
+ 登出不会删除服务端记住的 consent。
299
+
300
+ OAuth 参数优先级:
301
+
302
+ | 参数 | 优先级 |
303
+ |------|--------|
304
+ | Client ID | `--client-id` > `XPARSE_OAUTH_CLIENT_ID` > `oauth.client_id` > public default `cli_textin_xparse` |
305
+ | Scope | `--scope` > `XPARSE_OAUTH_SCOPE` > `oauth.scope` > `ocr:*` |
306
+ | Browser redirect | `--redirect-uri` > `XPARSE_OAUTH_REDIRECT_URI` > `oauth.redirect_uri` > `http://127.0.0.1:0/callback` |
307
+ | Base URL | `--base-url` > `XPARSE_BASE_URL` > `base_url` > `https://api.textin.com` |
308
+
309
+ 不传 `--api` 时使用 `auto`:CLI 先读取现有 quota 接口,在匿名每日免费额度与登录
310
+ 用户的免费套餐额度之间制定执行计划。显式 `--api free` 固定调用免费 Agent 接口,
311
+ 显式 `--api paid` 固定调用现有付费接口,不参与自动额度路由。
312
+
313
+ 认证选择顺序为:显式 `--auth-method` / 环境或配置选择 > OAuth > 完整 AppKey >
314
+ 匿名(仅可选认证接口)。自动选择 OAuth 时若刷新失败,会先回退完整 AppKey;两者都
315
+ 不可用时,quota、免费解析与 telemetry 才匿名继续。显式选择 OAuth 失败不会切换身份。
316
+
317
+ 本地 PDF 会使用服务端返回的 `max_pages_per_request` 和 `max_file_size_mb` 预检。
318
+ 仅页数超限且原文件体积合规时使用页范围分段;文件体积超限时生成真实临时 PDF
319
+ 片段,按可重试错误最多重试一次,并按原始页码顺序合并结果。临时片段执行后删除。
320
+
321
+ ## 退出码与错误处理
322
+
323
+ | 码 | 含义 | stderr 格式 |
324
+ |----|------|-------------|
325
+ | 0 | 成功 | — |
326
+ | 1 | 一般错误 / 网络异常 | 纯文本 + `> [tag] suggestion` |
327
+ | 2 | 参数错误 | 纯文本 + `> [tag] suggestion` |
328
+ | 3 | API 返回错误 | `api_code:message` + `> [tag] suggestion` |
329
+
330
+ 每条错误输出到 stderr,格式:
331
+
332
+ ```
333
+ <错误信息>
334
+ > <建议操作>
335
+ (request_id: xxx, contact Textin support if unresolved) ← 部分 API 错误额外输出
336
+ ```
337
+
338
+ 第二行以 `>` 开头,包含 `[tag]` 标签指示处理方式:
339
+
340
+ | 标签 | 含义 |
341
+ |------|------|
342
+ | `[fix]` | 修正参数后重新执行 |
343
+ | `[retry]` | 自动重试(带退避) |
344
+ | `[fallback]` | 尝试替代方案 |
345
+ | `[ask human]` | 需要人工介入 |
346
+
347
+ 示例:
348
+
349
+ ```
350
+ invalid --view value, must be 'markdown' or 'json'
351
+ > [fix] use --view markdown or --view json
352
+ ```
353
+
354
+ ```
355
+ 40306:服务暂时不可用
356
+ > [retry] wait 3s then retry, max 2 retries
357
+ (request_id: 644e2efdb..., contact Textin support if unresolved)
358
+ ```
359
+
360
+ > stdout 仅输出文档内容,stderr 仅输出错误信息,exit code 严格为 0/1/2/3。
361
+ > 完整的错误和建议枚举见 [suggestion.txt](suggestion.txt)。
362
+
363
+ ## 支持的文件格式
364
+
365
+ | 类型 | 格式 |
366
+ |------|------|
367
+ | 文档 | PDF, DOC, DOCX, TXT, RTF, OFD |
368
+ | 图片 | PNG, JPG, JPEG, BMP, TIFF, WebP |
369
+ | 表格 | XLS, XLSX, CSV |
370
+ | 演示 | PPT, PPTX |
371
+ | 网页 | HTML, MHTML |
372
+
373
+ 限制:
374
+
375
+ | 限制项 | 免费 API | 付费 API |
376
+ |--------|----------|----------|
377
+ | 文件大小 | 由 quota 的 `max_file_size_mb` 下发,PDF 可自动分片 | 500MB |
378
+ | PDF 页数 | 由 quota 的 `max_pages_per_request` 下发,支持自动分段 | 1000 页 |
379
+ | XLS/XLSX/CSV | — | 每 sheet ≤ 2000 行 × 100 列 |
380
+ | TXT | — | ≤ 100KB |
381
+ | 图片尺寸 | 20~20000 像素 | 20~20000 像素 |
package/bin/xparse-cli.js CHANGED
@@ -1,8 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
 
4
- console.error(
5
- "xparse-cli does not have a stable npm release yet. " +
6
- "Install the beta explicitly with: npm install -g xparse-cli@beta",
7
- );
8
- process.exit(1);
4
+ const { spawnSync } = require("node:child_process");
5
+ const { resolveBinaryPath } = require("../lib/platform.js");
6
+
7
+ let binaryPath;
8
+ try {
9
+ binaryPath = resolveBinaryPath();
10
+ } catch (error) {
11
+ console.error(`xparse-cli: ${error.message}`);
12
+ process.exit(1);
13
+ }
14
+
15
+ const result = spawnSync(binaryPath, process.argv.slice(2), {
16
+ stdio: "inherit",
17
+ windowsHide: false,
18
+ });
19
+
20
+ if (result.error) {
21
+ console.error(`xparse-cli: unable to start ${binaryPath}: ${result.error.message}`);
22
+ process.exit(1);
23
+ }
24
+
25
+ if (result.signal) {
26
+ console.error(`xparse-cli: process terminated by ${result.signal}`);
27
+ process.exit(1);
28
+ }
29
+
30
+ process.exit(result.status ?? 1);
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ const path = require("node:path");
4
+
5
+ const PLATFORM_PACKAGES = Object.freeze({
6
+ "darwin-x64": {
7
+ packageName: "xparse-cli-darwin-amd64",
8
+ binary: "xparse-cli-darwin-amd64",
9
+ },
10
+ "darwin-arm64": {
11
+ packageName: "xparse-cli-darwin-arm64",
12
+ binary: "xparse-cli-darwin-arm64",
13
+ },
14
+ "linux-x64": {
15
+ packageName: "xparse-cli-linux-amd64",
16
+ binary: "xparse-cli-linux-amd64",
17
+ },
18
+ "linux-arm64": {
19
+ packageName: "xparse-cli-linux-arm64",
20
+ binary: "xparse-cli-linux-arm64",
21
+ },
22
+ "win32-x64": {
23
+ packageName: "xparse-cli-windows-amd64",
24
+ binary: "xparse-cli-windows-amd64.exe",
25
+ },
26
+ "win32-arm64": {
27
+ packageName: "xparse-cli-windows-arm64",
28
+ binary: "xparse-cli-windows-arm64.exe",
29
+ },
30
+ });
31
+
32
+ function getPlatformSpec(platform = process.platform, arch = process.arch) {
33
+ const spec = PLATFORM_PACKAGES[`${platform}-${arch}`];
34
+ if (!spec) {
35
+ throw new Error(
36
+ `Unsupported platform: ${platform}/${arch}. ` +
37
+ "Supported platforms are macOS, Linux, and Windows on x64 or arm64.",
38
+ );
39
+ }
40
+ return spec;
41
+ }
42
+
43
+ function resolveBinaryPath(options = {}) {
44
+ const platform = options.platform ?? process.platform;
45
+ const arch = options.arch ?? process.arch;
46
+ const resolve = options.resolve ?? require.resolve;
47
+ const spec = getPlatformSpec(platform, arch);
48
+
49
+ let manifestPath;
50
+ try {
51
+ manifestPath = resolve(`${spec.packageName}/package.json`);
52
+ } catch (error) {
53
+ const wrapped = new Error(
54
+ `The optional package ${spec.packageName} is missing. ` +
55
+ "Reinstall xparse-cli without omitting optional dependencies.",
56
+ );
57
+ wrapped.cause = error;
58
+ throw wrapped;
59
+ }
60
+
61
+ return path.join(path.dirname(manifestPath), "bin", spec.binary);
62
+ }
63
+
64
+ module.exports = {
65
+ PLATFORM_PACKAGES,
66
+ getPlatformSpec,
67
+ resolveBinaryPath,
68
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "xparse-cli",
3
- "version": "0.0.0",
4
- "description": "Stable-channel placeholder for xparse-cli",
3
+ "version": "2.2.1-beta.1",
4
+ "description": "TextIn xParse command-line client for document parsing",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -12,13 +12,22 @@
12
12
  "xparse-cli": "bin/xparse-cli.js"
13
13
  },
14
14
  "files": [
15
- "bin/"
15
+ "bin/",
16
+ "lib/"
16
17
  ],
17
18
  "engines": {
18
19
  "node": ">=18"
19
20
  },
21
+ "optionalDependencies": {
22
+ "xparse-cli-darwin-amd64": "2.2.1-beta.1",
23
+ "xparse-cli-darwin-arm64": "2.2.1-beta.1",
24
+ "xparse-cli-linux-amd64": "2.2.1-beta.1",
25
+ "xparse-cli-linux-arm64": "2.2.1-beta.1",
26
+ "xparse-cli-windows-amd64": "2.2.1-beta.1",
27
+ "xparse-cli-windows-arm64": "2.2.1-beta.1"
28
+ },
20
29
  "publishConfig": {
21
30
  "access": "public",
22
- "tag": "latest"
31
+ "tag": "beta"
23
32
  }
24
33
  }