feishu-docs-cli 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +333 -0
  3. package/README.zh.md +332 -0
  4. package/bin/feishu-docs.js +8 -0
  5. package/dist/auth.d.ts +76 -0
  6. package/dist/auth.js +512 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/cli.d.ts +5 -0
  9. package/dist/cli.js +166 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/client.d.ts +42 -0
  12. package/dist/client.js +269 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/commands/cat.d.ts +6 -0
  15. package/dist/commands/cat.js +151 -0
  16. package/dist/commands/cat.js.map +1 -0
  17. package/dist/commands/create.d.ts +6 -0
  18. package/dist/commands/create.js +120 -0
  19. package/dist/commands/create.js.map +1 -0
  20. package/dist/commands/delete.d.ts +6 -0
  21. package/dist/commands/delete.js +89 -0
  22. package/dist/commands/delete.js.map +1 -0
  23. package/dist/commands/info.d.ts +6 -0
  24. package/dist/commands/info.js +69 -0
  25. package/dist/commands/info.js.map +1 -0
  26. package/dist/commands/login.d.ts +10 -0
  27. package/dist/commands/login.js +90 -0
  28. package/dist/commands/login.js.map +1 -0
  29. package/dist/commands/ls.d.ts +6 -0
  30. package/dist/commands/ls.js +76 -0
  31. package/dist/commands/ls.js.map +1 -0
  32. package/dist/commands/read.d.ts +6 -0
  33. package/dist/commands/read.js +404 -0
  34. package/dist/commands/read.js.map +1 -0
  35. package/dist/commands/search.d.ts +7 -0
  36. package/dist/commands/search.js +87 -0
  37. package/dist/commands/search.js.map +1 -0
  38. package/dist/commands/share.d.ts +13 -0
  39. package/dist/commands/share.js +210 -0
  40. package/dist/commands/share.js.map +1 -0
  41. package/dist/commands/spaces.d.ts +6 -0
  42. package/dist/commands/spaces.js +43 -0
  43. package/dist/commands/spaces.js.map +1 -0
  44. package/dist/commands/tree.d.ts +6 -0
  45. package/dist/commands/tree.js +101 -0
  46. package/dist/commands/tree.js.map +1 -0
  47. package/dist/commands/update.d.ts +9 -0
  48. package/dist/commands/update.js +211 -0
  49. package/dist/commands/update.js.map +1 -0
  50. package/dist/commands/wiki.d.ts +6 -0
  51. package/dist/commands/wiki.js +284 -0
  52. package/dist/commands/wiki.js.map +1 -0
  53. package/dist/parser/block-types.d.ts +141 -0
  54. package/dist/parser/block-types.js +167 -0
  55. package/dist/parser/block-types.js.map +1 -0
  56. package/dist/parser/blocks-to-md.d.ts +26 -0
  57. package/dist/parser/blocks-to-md.js +576 -0
  58. package/dist/parser/blocks-to-md.js.map +1 -0
  59. package/dist/parser/text-elements.d.ts +13 -0
  60. package/dist/parser/text-elements.js +91 -0
  61. package/dist/parser/text-elements.js.map +1 -0
  62. package/dist/services/block-writer.d.ts +30 -0
  63. package/dist/services/block-writer.js +131 -0
  64. package/dist/services/block-writer.js.map +1 -0
  65. package/dist/services/doc-blocks.d.ts +9 -0
  66. package/dist/services/doc-blocks.js +30 -0
  67. package/dist/services/doc-blocks.js.map +1 -0
  68. package/dist/services/markdown-convert.d.ts +51 -0
  69. package/dist/services/markdown-convert.js +109 -0
  70. package/dist/services/markdown-convert.js.map +1 -0
  71. package/dist/services/wiki-nodes.d.ts +21 -0
  72. package/dist/services/wiki-nodes.js +47 -0
  73. package/dist/services/wiki-nodes.js.map +1 -0
  74. package/dist/types/index.d.ts +234 -0
  75. package/dist/types/index.js +5 -0
  76. package/dist/types/index.js.map +1 -0
  77. package/dist/utils/document-resolver.d.ts +28 -0
  78. package/dist/utils/document-resolver.js +47 -0
  79. package/dist/utils/document-resolver.js.map +1 -0
  80. package/dist/utils/drive-types.d.ts +4 -0
  81. package/dist/utils/drive-types.js +16 -0
  82. package/dist/utils/drive-types.js.map +1 -0
  83. package/dist/utils/errors.d.ts +21 -0
  84. package/dist/utils/errors.js +110 -0
  85. package/dist/utils/errors.js.map +1 -0
  86. package/dist/utils/member.d.ts +11 -0
  87. package/dist/utils/member.js +30 -0
  88. package/dist/utils/member.js.map +1 -0
  89. package/dist/utils/url-parser.d.ts +5 -0
  90. package/dist/utils/url-parser.js +55 -0
  91. package/dist/utils/url-parser.js.map +1 -0
  92. package/dist/utils/validate.d.ts +8 -0
  93. package/dist/utils/validate.js +15 -0
  94. package/dist/utils/validate.js.map +1 -0
  95. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 cliff-byte
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,333 @@
1
+ # feishu-docs-cli
2
+
3
+ [中文文档](./README.zh.md)
4
+
5
+ CLI tool for AI Agents to read/write Feishu (Lark) docs via shell commands.
6
+
7
+ ## Features
8
+
9
+ - **Read** documents as Markdown, raw text, or original Block JSON
10
+ - **Create** documents in knowledge bases or cloud folders
11
+ - **Update** documents with overwrite or append mode
12
+ - **Delete** documents (move to recycle bin)
13
+ - **Info** — view document metadata (title, type, URL, revision)
14
+ - **Browse** knowledge base structure (spaces, tree, cat)
15
+ - **Search** documents by keyword
16
+ - **Share** — manage collaborators (list, add, set public mode)
17
+ - **List** files in cloud folders
18
+ - Written in TypeScript with strict mode
19
+ - Zero extra runtime dependencies — only `@larksuiteoapi/node-sdk`
20
+ - Agent-friendly output — pure text or JSON, no interactive UI
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ npm install -g github:cliff-byte/feishu-docs-cli
26
+ ```
27
+
28
+ Or use directly with npx:
29
+
30
+ ```bash
31
+ npx github:cliff-byte/feishu-docs-cli read <url>
32
+ ```
33
+
34
+ Requires Node.js >= 18.3.
35
+
36
+ ## Setup
37
+
38
+ ### 1. Create a Feishu App
39
+
40
+ 1. Go to [Feishu Open Platform](https://open.feishu.cn/app) (or [Lark Developer](https://open.larksuite.com/app) for international)
41
+ 2. Click **Create Custom App**, fill in the app name and description
42
+ 3. After creation, go to the app's **Credentials & Basic Info** page. Copy the **App ID** (`cli_xxx`) and **App Secret** — you'll need them for environment variables
43
+ 4. Go to **Permissions & Scopes**, search and add the following scopes:
44
+
45
+ | Scope | Description | Required |
46
+ |-------|-------------|----------|
47
+ | `wiki:wiki` | Knowledge base access | Yes |
48
+ | `docx:document` | Document read/write | Yes |
49
+ | `docx:document.block:convert` | Markdown to block conversion | Yes (for create/update) |
50
+ | `drive:drive` | File management & permission management | Yes |
51
+ | `contact:contact.base:readonly` | User name resolution (@mentions) | Recommended |
52
+ | `board:whiteboard:node:read` | Whiteboard content read | Optional |
53
+ | `bitable:app:readonly` | Bitable read access | Optional |
54
+
55
+ 5. Go to **Security Settings**, add the OAuth callback URL to the **Redirect URLs** allowlist:
56
+ - Default: `http://localhost:3456/callback`
57
+ - This must match exactly what you use during `feishu-docs login`
58
+
59
+ 6. **Publish the app version**: Go to **App Release** → **Create Version** → Submit for review → Approve (self-built apps in your org are usually auto-approved)
60
+
61
+ > **Note**: For tenant-level access (e.g., CI/CD), the app must be granted access to specific docs or knowledge bases. Add the app as a collaborator, or use the admin console to authorize document scope.
62
+
63
+ ### 2. Set Environment Variables
64
+
65
+ ```bash
66
+ export FEISHU_APP_ID="cli_xxx" # From step 3 above
67
+ export FEISHU_APP_SECRET="xxx" # From step 3 above
68
+ ```
69
+
70
+ ### 3. Login (for user-level access)
71
+
72
+ User-level access enables personal docs, search, and collaboration features.
73
+
74
+ ```bash
75
+ feishu-docs login
76
+ ```
77
+
78
+ This opens a browser for OAuth authorization and saves the encrypted token to `~/.feishu-docs/auth.json`.
79
+
80
+ If your app's registered redirect URL differs from the default (`http://localhost:3456/callback`), pass the exact same value:
81
+
82
+ ```bash
83
+ # Match the exact redirect URI registered in Feishu Open Platform
84
+ feishu-docs login --redirect-uri http://127.0.0.1:3456/callback
85
+
86
+ # Or change only the port and keep the default localhost path
87
+ feishu-docs login --port 4567
88
+ ```
89
+
90
+ ## Usage
91
+
92
+ ### Read
93
+
94
+ ```bash
95
+ # Read document as Markdown
96
+ feishu-docs read https://xxx.feishu.cn/wiki/wikcnXXX
97
+
98
+ # Read by token
99
+ feishu-docs read wikcnXXX
100
+
101
+ # Raw Block JSON (lossless)
102
+ feishu-docs read <url> --blocks
103
+
104
+ # Plain text only
105
+ feishu-docs read <url> --raw
106
+
107
+ # With metadata header
108
+ feishu-docs read <url> --with-meta
109
+ ```
110
+
111
+ ### Knowledge Base
112
+
113
+ ```bash
114
+ # List all knowledge bases
115
+ feishu-docs spaces
116
+
117
+ # Show node tree
118
+ feishu-docs tree <space_id>
119
+ feishu-docs tree <space_id> --depth 2
120
+
121
+ # Recursively read all documents
122
+ feishu-docs cat <space_id> --max-docs 20
123
+ feishu-docs cat <space_id> --node <token> --title-only
124
+ ```
125
+
126
+ ### Search
127
+
128
+ ```bash
129
+ feishu-docs search "API design" --type docx --limit 10
130
+ ```
131
+
132
+ Requires user access token. Use `feishu-docs login` first.
133
+
134
+ ### Create
135
+
136
+ ```bash
137
+ # In knowledge base
138
+ feishu-docs create "API Docs" --wiki <space_id> --body ./api.md
139
+
140
+ # In cloud folder
141
+ feishu-docs create "API Docs" --folder <folder_token> --body ./api.md
142
+
143
+ # Empty document
144
+ feishu-docs create "API Docs"
145
+
146
+ # From stdin
147
+ cat design.md | feishu-docs create "Design" --wiki <space_id> --body -
148
+ ```
149
+
150
+ ### Update
151
+
152
+ ```bash
153
+ # Overwrite (backs up first)
154
+ feishu-docs update <url> --body ./updated.md
155
+
156
+ # Append
157
+ feishu-docs update <url> --body ./extra.md --append
158
+
159
+ # From stdin
160
+ echo "## New Section" | feishu-docs update <url> --body - --append
161
+
162
+ # Restore from backup
163
+ feishu-docs update <url> --restore ~/.feishu-docs/backups/xxx.json
164
+ ```
165
+
166
+ ### Delete
167
+
168
+ ```bash
169
+ feishu-docs delete <url> --confirm
170
+ ```
171
+
172
+ Moves document to recycle bin (recoverable for 30 days).
173
+
174
+ ### Info
175
+
176
+ ```bash
177
+ feishu-docs info <url|token>
178
+ feishu-docs info <url> --json
179
+ ```
180
+
181
+ ### List Files
182
+
183
+ ```bash
184
+ # List root folder
185
+ feishu-docs ls
186
+
187
+ # List specific folder
188
+ feishu-docs ls <folder_token>
189
+
190
+ # Filter by type
191
+ feishu-docs ls --type docx --limit 20
192
+ ```
193
+
194
+ ### Share
195
+
196
+ ```bash
197
+ # List collaborators
198
+ feishu-docs share list <url>
199
+
200
+ # Add collaborator
201
+ feishu-docs share add <url> user@example.com --role view
202
+ feishu-docs share add <url> ou_xxx --role edit
203
+
204
+ # Set public sharing mode
205
+ feishu-docs share set <url> --public tenant # org-wide readable
206
+ feishu-docs share set <url> --public tenant:edit # org-wide editable
207
+ feishu-docs share set <url> --public open # anyone readable
208
+ feishu-docs share set <url> --public closed # disable link sharing
209
+ ```
210
+
211
+ Roles: `view`, `edit`, `manage`. Member types are auto-detected (email, openid, unionid, openchat, userid).
212
+
213
+ ### Auth
214
+
215
+ ```bash
216
+ feishu-docs login # OAuth login (default callback: http://localhost:3456/callback)
217
+ feishu-docs logout # Clear saved credentials
218
+ feishu-docs whoami # Show current auth status
219
+ ```
220
+
221
+ ## Global Options
222
+
223
+ | Option | Description |
224
+ |--------|-------------|
225
+ | `--auth <user\|tenant\|auto>` | Auth mode (default: auto) |
226
+ | `--json` | Output JSON format |
227
+ | `--lark` | Use Lark (international) domain |
228
+ | `--help` | Show help |
229
+
230
+ ## Auth Modes
231
+
232
+ | Mode | Token Type | Use Case |
233
+ |------|-----------|----------|
234
+ | `user` | user_access_token | Personal docs, collaboration, search |
235
+ | `tenant` | tenant_access_token | App-managed docs, CI/CD |
236
+ | `auto` | Best available | Default — tries user first, falls back to tenant |
237
+
238
+ ## AI Agent Integration
239
+
240
+ ### Claude Code (CLAUDE.md)
241
+
242
+ ```markdown
243
+ ## Feishu Docs
244
+
245
+ Read/write Feishu docs with feishu-docs-cli.
246
+
247
+ Read: feishu-docs read <url>
248
+ Search: feishu-docs search <keyword>
249
+ Tree: feishu-docs tree <space_id>
250
+ Batch: feishu-docs cat <space_id> --max-docs 10
251
+ Create: feishu-docs create <title> --wiki <space_id> --body <file>
252
+ Update: feishu-docs update <url> --body <file>
253
+
254
+ Env vars FEISHU_APP_ID and FEISHU_APP_SECRET are in .env.
255
+ Run `feishu-docs login` first.
256
+ ```
257
+
258
+ ### Programmatic Usage
259
+
260
+ All commands output to stdout (results) and stderr (errors/warnings). Exit codes:
261
+
262
+ | Code | Meaning |
263
+ |------|---------|
264
+ | 0 | Success |
265
+ | 1 | Invalid args |
266
+ | 2 | Auth failure |
267
+ | 3 | API error |
268
+
269
+ Use `--json` for structured output that agents can parse.
270
+
271
+ ## Write Safety
272
+
273
+ Overwrite operations (`update` without `--append`) automatically:
274
+
275
+ 1. **Back up** current document to `~/.feishu-docs/backups/`
276
+ 2. **Clear** then **rewrite** the document
277
+ 3. **Auto-recover** from backup if write fails
278
+ 4. **Rotate** backups (keeps last 10)
279
+
280
+ Feishu also maintains version history — you can always roll back in the Feishu client.
281
+
282
+ ## Development
283
+
284
+ ```bash
285
+ git clone https://github.com/cliff-byte/feishu-docs-cli.git
286
+ cd feishu-docs-cli
287
+ npm install
288
+
289
+ # Type check
290
+ npm run build:check
291
+
292
+ # Build (outputs to dist/)
293
+ npm run build
294
+
295
+ # Run tests
296
+ npm test
297
+
298
+ # Run CLI from source
299
+ npm run build && node bin/feishu-docs.js --help
300
+ ```
301
+
302
+ ### Project Structure
303
+
304
+ ```
305
+ src/
306
+ types/ # Shared TypeScript type definitions
307
+ commands/ # CLI command handlers
308
+ services/ # API service layer
309
+ parser/ # Block-to-Markdown parser
310
+ utils/ # Validation, error handling, URL parsing
311
+ test/ # Unit tests (node:test)
312
+ bin/ # CLI entry point (JS shim → dist/)
313
+ dist/ # Compiled output (git-ignored)
314
+ ```
315
+
316
+ ## Roadmap
317
+
318
+ - [x] Feishu cloud document operations (read, create, update, delete, info)
319
+ - [x] Knowledge base operations (spaces, tree, cat, wiki management, share, search)
320
+ - [ ] Feishu Bitable (multi-dimensional table) operations
321
+ - [ ] Feishu Sheets (spreadsheet) operations
322
+
323
+ ## Limitations
324
+
325
+ - **Supported**: docx (new documents)
326
+ - **Link only**: sheet, bitable, mindnote, board
327
+ - **Not supported**: doc (legacy format)
328
+ - Markdown conversion is lossy (colors, merged cells, layouts are dropped). Use `--blocks` for lossless JSON.
329
+ - Image write is not supported (read returns temporary URLs valid ~24h)
330
+
331
+ ## License
332
+
333
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,332 @@
1
+ # feishu-docs-cli
2
+
3
+ [English](./README.md)
4
+
5
+ 让 AI Agent(Claude Code、Codex、Trae 等)通过 shell 命令读写飞书云文档和知识库。
6
+
7
+ ## 功能
8
+
9
+ - **读取** 文档,输出 Markdown、纯文本或原始 Block JSON
10
+ - **创建** 文档到知识库或云空间文件夹
11
+ - **更新** 文档,支持覆盖写入或追加模式
12
+ - **删除** 文档(移至回收站)
13
+ - **详情** — 查看文档元信息(标题、类型、URL、版本号)
14
+ - **浏览** 知识库结构(空间列表、目录树、批量读取)
15
+ - **搜索** 按关键词搜索文档
16
+ - **分享** — 管理协作者(列表、添加、设置公开权限)
17
+ - **文件列表** — 浏览云空间文件夹
18
+ - 使用 TypeScript 编写,严格模式
19
+ - 零额外运行时依赖 — 仅依赖 `@larksuiteoapi/node-sdk`
20
+ - Agent 友好输出 — 纯文本或 JSON,无交互式 UI
21
+
22
+ ## 安装
23
+
24
+ ```bash
25
+ npm install -g github:cliff-byte/feishu-docs-cli
26
+ ```
27
+
28
+ 或通过 npx 直接运行:
29
+
30
+ ```bash
31
+ npx github:cliff-byte/feishu-docs-cli read <url>
32
+ ```
33
+
34
+ 需要 Node.js >= 18.3。
35
+
36
+ ## 配置
37
+
38
+ ### 1. 创建飞书应用
39
+
40
+ 1. 前往[飞书开放平台](https://open.feishu.cn/app),点击 **创建企业自建应用**,填写应用名称和描述
41
+ 2. 创建完成后,进入应用的 **凭证与基础信息** 页面,复制 **App ID**(`cli_xxx`)和 **App Secret** — 后续配置环境变量需要用到
42
+ 3. 进入 **权限管理**,搜索并添加以下权限:
43
+
44
+ | 权限 | 说明 | 是否必需 |
45
+ |------|------|----------|
46
+ | `wiki:wiki` | 知识库访问 | 是 |
47
+ | `docx:document` | 文档读写 | 是 |
48
+ | `docx:document.block:convert` | Markdown 转 Block | 是(创建/更新需要) |
49
+ | `drive:drive` | 文件管理和权限管理 | 是 |
50
+ | `contact:contact.base:readonly` | 用户名解析(@提及) | 推荐 |
51
+ | `board:whiteboard:node:read` | 白板内容读取 | 可选 |
52
+ | `bitable:app:readonly` | 多维表格只读 | 可选 |
53
+
54
+ 4. 进入 **安全设置**,在 **重定向 URL** 白名单中添加 OAuth 回调地址:
55
+ - 默认值:`http://localhost:3456/callback`
56
+ - 该地址必须与 `feishu-docs login` 使用的值完全一致
57
+
58
+ 5. **发布应用版本**:进入 **应用发布** → **创建版本** → 提交审核 → 审核通过(企业自建应用通常自动通过)
59
+
60
+ > **提示**:使用 tenant(应用)身份访问文档时(如 CI/CD 场景),需要将应用添加为文档或知识库的协作者,或通过管理后台授权文档范围。
61
+
62
+ ### 2. 设置环境变量
63
+
64
+ ```bash
65
+ export FEISHU_APP_ID="cli_xxx" # 上面第 2 步获取的 App ID
66
+ export FEISHU_APP_SECRET="xxx" # 上面第 2 步获取的 App Secret
67
+ ```
68
+
69
+ ### 3. 登录(获取用户级别访问权限)
70
+
71
+ 用户级别访问支持个人文档、搜索和协作等功能。
72
+
73
+ ```bash
74
+ feishu-docs login
75
+ ```
76
+
77
+ 执行后会打开浏览器进行 OAuth 授权,token 加密保存到 `~/.feishu-docs/auth.json`。
78
+
79
+ 如果应用注册的重定向 URL 与默认值(`http://localhost:3456/callback`)不同,需要传入完全一致的值:
80
+
81
+ ```bash
82
+ # 使用与飞书开放平台注册的完全一致的重定向 URI
83
+ feishu-docs login --redirect-uri http://127.0.0.1:3456/callback
84
+
85
+ # 或仅更改端口,保持默认的 localhost 路径
86
+ feishu-docs login --port 4567
87
+ ```
88
+
89
+ ## 使用
90
+
91
+ ### 读取
92
+
93
+ ```bash
94
+ # 读取文档,输出 Markdown
95
+ feishu-docs read https://xxx.feishu.cn/wiki/wikcnXXX
96
+
97
+ # 通过 token 读取
98
+ feishu-docs read wikcnXXX
99
+
100
+ # 原始 Block JSON(无损)
101
+ feishu-docs read <url> --blocks
102
+
103
+ # 纯文本
104
+ feishu-docs read <url> --raw
105
+
106
+ # 带元信息头
107
+ feishu-docs read <url> --with-meta
108
+ ```
109
+
110
+ ### 知识库
111
+
112
+ ```bash
113
+ # 列出所有知识库
114
+ feishu-docs spaces
115
+
116
+ # 查看目录树
117
+ feishu-docs tree <space_id>
118
+ feishu-docs tree <space_id> --depth 2
119
+
120
+ # 递归读取所有文档
121
+ feishu-docs cat <space_id> --max-docs 20
122
+ feishu-docs cat <space_id> --node <token> --title-only
123
+ ```
124
+
125
+ ### 搜索
126
+
127
+ ```bash
128
+ feishu-docs search "API 设计" --type docx --limit 10
129
+ ```
130
+
131
+ 需要用户级别 token,请先执行 `feishu-docs login`。
132
+
133
+ ### 创建
134
+
135
+ ```bash
136
+ # 在知识库中创建
137
+ feishu-docs create "API 文档" --wiki <space_id> --body ./api.md
138
+
139
+ # 在云空间文件夹中创建
140
+ feishu-docs create "API 文档" --folder <folder_token> --body ./api.md
141
+
142
+ # 创建空文档
143
+ feishu-docs create "API 文档"
144
+
145
+ # 从标准输入读取
146
+ cat design.md | feishu-docs create "设计文档" --wiki <space_id> --body -
147
+ ```
148
+
149
+ ### 更新
150
+
151
+ ```bash
152
+ # 覆盖写入(自动备份)
153
+ feishu-docs update <url> --body ./updated.md
154
+
155
+ # 追加内容
156
+ feishu-docs update <url> --body ./extra.md --append
157
+
158
+ # 从标准输入读取
159
+ echo "## 新章节" | feishu-docs update <url> --body - --append
160
+
161
+ # 从备份恢复
162
+ feishu-docs update <url> --restore ~/.feishu-docs/backups/xxx.json
163
+ ```
164
+
165
+ ### 删除
166
+
167
+ ```bash
168
+ feishu-docs delete <url> --confirm
169
+ ```
170
+
171
+ 将文档移至回收站(30 天内可恢复)。
172
+
173
+ ### 详情
174
+
175
+ ```bash
176
+ feishu-docs info <url|token>
177
+ feishu-docs info <url> --json
178
+ ```
179
+
180
+ ### 文件列表
181
+
182
+ ```bash
183
+ # 列出根目录
184
+ feishu-docs ls
185
+
186
+ # 列出指定文件夹
187
+ feishu-docs ls <folder_token>
188
+
189
+ # 按类型筛选
190
+ feishu-docs ls --type docx --limit 20
191
+ ```
192
+
193
+ ### 分享
194
+
195
+ ```bash
196
+ # 查看协作者
197
+ feishu-docs share list <url>
198
+
199
+ # 添加协作者
200
+ feishu-docs share add <url> user@example.com --role view
201
+ feishu-docs share add <url> ou_xxx --role edit
202
+
203
+ # 设置公开分享模式
204
+ feishu-docs share set <url> --public tenant # 组织内可读
205
+ feishu-docs share set <url> --public tenant:edit # 组织内可编辑
206
+ feishu-docs share set <url> --public open # 互联网可读
207
+ feishu-docs share set <url> --public closed # 关闭链接分享
208
+ ```
209
+
210
+ 角色:`view`(查看)、`edit`(编辑)、`manage`(管理)。成员类型自动识别(邮箱、openid、unionid、openchat、userid)。
211
+
212
+ ### 认证
213
+
214
+ ```bash
215
+ feishu-docs login # OAuth 登录(默认回调:http://localhost:3456/callback)
216
+ feishu-docs logout # 清除保存的凭证
217
+ feishu-docs whoami # 查看当前认证状态
218
+ ```
219
+
220
+ ## 全局选项
221
+
222
+ | 选项 | 说明 |
223
+ |------|------|
224
+ | `--auth <user\|tenant\|auto>` | 认证模式(默认:auto) |
225
+ | `--json` | JSON 格式输出 |
226
+ | `--lark` | 使用 Lark(国际版)域名 |
227
+ | `--help` | 显示帮助 |
228
+
229
+ ## 认证模式
230
+
231
+ | 模式 | Token 类型 | 适用场景 |
232
+ |------|-----------|----------|
233
+ | `user` | user_access_token | 个人文档、协作、搜索 |
234
+ | `tenant` | tenant_access_token | 应用管理的文档、CI/CD |
235
+ | `auto` | 自动选择最佳 | 默认 — 优先用户 token,回退到租户 token |
236
+
237
+ ## AI Agent 集成
238
+
239
+ ### Claude Code (CLAUDE.md)
240
+
241
+ ```markdown
242
+ ## 飞书文档
243
+
244
+ 通过 feishu-docs-cli 读写飞书文档。
245
+
246
+ 读取: feishu-docs read <url>
247
+ 搜索: feishu-docs search <关键词>
248
+ 目录树: feishu-docs tree <space_id>
249
+ 批量读取: feishu-docs cat <space_id> --max-docs 10
250
+ 创建: feishu-docs create <标题> --wiki <space_id> --body <文件>
251
+ 更新: feishu-docs update <url> --body <文件>
252
+
253
+ 环境变量 FEISHU_APP_ID 和 FEISHU_APP_SECRET 在 .env 中。
254
+ 先执行 `feishu-docs login` 登录。
255
+ ```
256
+
257
+ ### 程序化调用
258
+
259
+ 所有命令输出到 stdout(结果)和 stderr(错误/警告)。退出码:
260
+
261
+ | 退出码 | 含义 |
262
+ |--------|------|
263
+ | 0 | 成功 |
264
+ | 1 | 参数错误 |
265
+ | 2 | 认证失败 |
266
+ | 3 | API 错误 |
267
+
268
+ 使用 `--json` 获取结构化输出,便于 Agent 解析。
269
+
270
+ ## 写入安全
271
+
272
+ 覆盖写入(`update` 不带 `--append`)自动执行:
273
+
274
+ 1. **备份** 当前文档到 `~/.feishu-docs/backups/`
275
+ 2. **清空** 后 **重写** 文档
276
+ 3. 写入失败时 **自动恢复** 备份
277
+ 4. **轮转** 备份文件(保留最近 10 份)
278
+
279
+ 飞书本身也维护版本历史 — 你随时可以在飞书客户端中回滚。
280
+
281
+ ## 开发
282
+
283
+ ```bash
284
+ git clone https://github.com/cliff-byte/feishu-docs-cli.git
285
+ cd feishu-docs-cli
286
+ npm install
287
+
288
+ # 类型检查
289
+ npm run build:check
290
+
291
+ # 构建(输出到 dist/)
292
+ npm run build
293
+
294
+ # 运行测试
295
+ npm test
296
+
297
+ # 从源码运行
298
+ npm run build && node bin/feishu-docs.js --help
299
+ ```
300
+
301
+ ### 项目结构
302
+
303
+ ```
304
+ src/
305
+ types/ # 共享 TypeScript 类型定义
306
+ commands/ # CLI 命令处理器
307
+ services/ # API 服务层
308
+ parser/ # Block 转 Markdown 解析器
309
+ utils/ # 校验、错误处理、URL 解析
310
+ test/ # 单元测试(node:test)
311
+ bin/ # CLI 入口(JS shim → dist/)
312
+ dist/ # 编译输出(不提交到 git)
313
+ ```
314
+
315
+ ## 路线图
316
+
317
+ - [x] 飞书云文档操作(读取、创建、更新、删除、详情)
318
+ - [x] 知识库操作(空间列表、目录树、批量读取、Wiki 管理、分享、搜索)
319
+ - [ ] 飞书多维表格操作
320
+ - [ ] 飞书电子表格操作
321
+
322
+ ## 限制
323
+
324
+ - **支持**:docx(新版文档)
325
+ - **仅链接**:sheet、bitable、mindnote、board
326
+ - **不支持**:doc(旧版格式)
327
+ - Markdown 转换有损(颜色、合并单元格、布局会丢失)。使用 `--blocks` 获取无损 JSON。
328
+ - 不支持图片写入(读取返回约 24 小时有效的临时 URL)
329
+
330
+ ## 许可证
331
+
332
+ MIT
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { run } from "../dist/cli.js";
4
+
5
+ run(process.argv.slice(2)).catch((err) => {
6
+ process.stderr.write(`feishu-docs: fatal: ${err.message}\n`);
7
+ process.exit(err.exitCode ?? 1);
8
+ });