yuque-cookie-plugin 0.1.2 → 0.1.3
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 +17 -1
- package/dist/auth.js +26 -18
- package/dist/cli.js +8 -0
- package/dist/client-cookie.js +45 -0
- package/docs/usage-zh.md +67 -14
- package/package.json +1 -1
- package/skills/yuque-cookie-plugin/SKILL.md +6 -4
- package/skills/yuque-cookie-plugin/commands.yaml +7 -0
- package/skills/yuque-cookie-plugin/reference/agent-spec.md +10 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
## 当前能力
|
|
10
10
|
|
|
11
11
|
- Cookie 登录、清理和登录态检测:`auth login`、`auth logout`、`auth status`
|
|
12
|
-
- 读取语雀信息:`book inspect`、`doc inspect`
|
|
12
|
+
- 读取语雀信息:`book list`、`book inspect`、`doc inspect`
|
|
13
13
|
- 文档快照和结构对比:`doc snapshot`、`lake diff`
|
|
14
14
|
- Lake 和 Markdown 辅助转换:`lake to-markdown`、`lake serialize`
|
|
15
15
|
- 安全写入:`doc apply-lake`、`doc update-lake`
|
|
@@ -78,6 +78,15 @@ npm run yuque-local -- auth login
|
|
|
78
78
|
|
|
79
79
|
项目目录不会保存真实 Cookie。配置文件会记录保存时间、更新时间、最近成功验证时间和最近失败时间。
|
|
80
80
|
|
|
81
|
+
如果你在同一台电脑上同时做全局 npm 版真实测试和本地源码开发,可以用独立配置目录隔离 Cookie:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
YUQUE_COOKIE_PLUGIN_CONFIG_DIR=/tmp/yuque-plugin-real-test yuque-local auth login
|
|
85
|
+
YUQUE_COOKIE_PLUGIN_CONFIG_DIR=/tmp/yuque-plugin-real-test yuque-local auth status --json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
这会把配置保存到 `/tmp/yuque-plugin-real-test/config.json`,不会影响默认的 `~/.config/yuque-cookie-plugin/config.json`。
|
|
89
|
+
|
|
81
90
|
也可以用环境变量覆盖本地配置:
|
|
82
91
|
|
|
83
92
|
```bash
|
|
@@ -121,6 +130,12 @@ yuque-local auth login --manual \
|
|
|
121
130
|
npm run yuque-local -- book inspect https://www.yuque.com/<your-login>/<your-book>
|
|
122
131
|
```
|
|
123
132
|
|
|
133
|
+
列出当前账号可访问的知识库:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
yuque-local book list --json
|
|
137
|
+
```
|
|
138
|
+
|
|
124
139
|
下载整个知识库:
|
|
125
140
|
|
|
126
141
|
```bash
|
|
@@ -240,6 +255,7 @@ npm run real:acceptance -- \
|
|
|
240
255
|
## 文档
|
|
241
256
|
|
|
242
257
|
- `docs/usage-zh.md`:中文完整使用指南
|
|
258
|
+
- `docs/ai-dialogue-test-cases.md`:用户和 AI 对话测试用例
|
|
243
259
|
- `docs/real-acceptance.md`:真实语雀验收流程
|
|
244
260
|
- `docs/native-lake-capability.md`:原生 Lake 能力矩阵
|
|
245
261
|
- `docs/development-plan.md`:开发计划和迭代日志
|
package/dist/auth.js
CHANGED
|
@@ -6,16 +6,20 @@ import { createInterface } from 'node:readline/promises';
|
|
|
6
6
|
import os from 'node:os';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import process from 'node:process';
|
|
9
|
-
const
|
|
10
|
-
|
|
9
|
+
export const CONFIG_DIR_ENV = 'YUQUE_COOKIE_PLUGIN_CONFIG_DIR';
|
|
10
|
+
export function getConfigDirPath() {
|
|
11
|
+
const override = process.env[CONFIG_DIR_ENV]?.trim();
|
|
12
|
+
return override ? path.resolve(override) : path.join(os.homedir(), '.config', 'yuque-cookie-plugin');
|
|
13
|
+
}
|
|
11
14
|
export function getConfigFilePath() {
|
|
12
|
-
return
|
|
15
|
+
return path.join(getConfigDirPath(), 'config.json');
|
|
13
16
|
}
|
|
14
17
|
export async function clearSavedCredentials() {
|
|
15
|
-
const
|
|
16
|
-
|
|
18
|
+
const configFile = getConfigFilePath();
|
|
19
|
+
const existed = existsSync(configFile);
|
|
20
|
+
await rm(configFile, { force: true });
|
|
17
21
|
return {
|
|
18
|
-
config_file:
|
|
22
|
+
config_file: configFile,
|
|
19
23
|
removed: existed
|
|
20
24
|
};
|
|
21
25
|
}
|
|
@@ -34,7 +38,7 @@ export function getCredentials(flags = {}) {
|
|
|
34
38
|
}
|
|
35
39
|
const saved = readSavedCredentials();
|
|
36
40
|
if (saved?.session && saved?.ctoken) {
|
|
37
|
-
return { ...saved, extraCookies: { ...(saved.extraCookies || {}), ...extraCookies }, source:
|
|
41
|
+
return { ...saved, extraCookies: { ...(saved.extraCookies || {}), ...extraCookies }, source: getConfigFilePath() };
|
|
38
42
|
}
|
|
39
43
|
throw new Error('Missing Yuque credentials. Run "yuque-local auth login" to configure them in your browser.');
|
|
40
44
|
}
|
|
@@ -56,12 +60,12 @@ export function getCredentialStatus(flags = {}) {
|
|
|
56
60
|
if (!saved?.session || !saved?.ctoken) {
|
|
57
61
|
return {
|
|
58
62
|
configured: false,
|
|
59
|
-
source:
|
|
63
|
+
source: getConfigFilePath()
|
|
60
64
|
};
|
|
61
65
|
}
|
|
62
66
|
return {
|
|
63
67
|
configured: true,
|
|
64
|
-
source:
|
|
68
|
+
source: getConfigFilePath(),
|
|
65
69
|
home_url: saved.homeUrl || null,
|
|
66
70
|
saved_at: saved.saved_at || null,
|
|
67
71
|
updated_at: saved.updated_at || null,
|
|
@@ -111,7 +115,7 @@ export async function loginWithBrowser(flags = {}) {
|
|
|
111
115
|
await openBrowser(result.url);
|
|
112
116
|
const credentials = await result.done;
|
|
113
117
|
await saveCredentials(credentials);
|
|
114
|
-
console.log(`Saved Yuque credentials to ${
|
|
118
|
+
console.log(`Saved Yuque credentials to ${getConfigFilePath()}`);
|
|
115
119
|
}
|
|
116
120
|
export async function loginManually(flags = {}) {
|
|
117
121
|
const sessionFromFlag = typeof flags.session === 'string' ? flags.session.trim() : '';
|
|
@@ -124,7 +128,7 @@ export async function loginManually(flags = {}) {
|
|
|
124
128
|
homeUrl: normalizeYuqueHomeUrl(homeUrlFromFlag),
|
|
125
129
|
saved_at: new Date().toISOString()
|
|
126
130
|
});
|
|
127
|
-
console.log(`Saved Yuque credentials to ${
|
|
131
|
+
console.log(`Saved Yuque credentials to ${getConfigFilePath()}`);
|
|
128
132
|
return;
|
|
129
133
|
}
|
|
130
134
|
if (!process.stdin.isTTY) {
|
|
@@ -145,17 +149,18 @@ export async function loginManually(flags = {}) {
|
|
|
145
149
|
homeUrl: normalizeYuqueHomeUrl(homeUrlInput.trim()),
|
|
146
150
|
saved_at: new Date().toISOString()
|
|
147
151
|
});
|
|
148
|
-
console.log(`Saved Yuque credentials to ${
|
|
152
|
+
console.log(`Saved Yuque credentials to ${getConfigFilePath()}`);
|
|
149
153
|
}
|
|
150
154
|
finally {
|
|
151
155
|
rl.close();
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
158
|
function readSavedCredentials() {
|
|
155
|
-
|
|
159
|
+
const configFile = getConfigFilePath();
|
|
160
|
+
if (!existsSync(configFile))
|
|
156
161
|
return null;
|
|
157
162
|
try {
|
|
158
|
-
return JSON.parse(readFileSync(
|
|
163
|
+
return JSON.parse(readFileSync(configFile, 'utf8'));
|
|
159
164
|
}
|
|
160
165
|
catch {
|
|
161
166
|
return null;
|
|
@@ -163,14 +168,16 @@ function readSavedCredentials() {
|
|
|
163
168
|
}
|
|
164
169
|
async function saveCredentials(credentials) {
|
|
165
170
|
const now = new Date().toISOString();
|
|
171
|
+
const configDir = getConfigDirPath();
|
|
172
|
+
const configFile = getConfigFilePath();
|
|
166
173
|
const data = {
|
|
167
174
|
...credentials,
|
|
168
175
|
saved_at: credentials.saved_at || now,
|
|
169
176
|
updated_at: now
|
|
170
177
|
};
|
|
171
|
-
await mkdir(
|
|
172
|
-
await writeFile(
|
|
173
|
-
await chmod(
|
|
178
|
+
await mkdir(configDir, { recursive: true, mode: 0o700 });
|
|
179
|
+
await writeFile(configFile, `${JSON.stringify(data, null, 2)}\n`, { mode: 0o600 });
|
|
180
|
+
await chmod(configFile, 0o600);
|
|
174
181
|
}
|
|
175
182
|
function ageHours(value) {
|
|
176
183
|
if (!value)
|
|
@@ -326,6 +333,7 @@ function sendHtml(res, html, status = 200) {
|
|
|
326
333
|
res.end(html);
|
|
327
334
|
}
|
|
328
335
|
function loginPage(error = '') {
|
|
336
|
+
const configFile = getConfigFilePath();
|
|
329
337
|
return `<!doctype html>
|
|
330
338
|
<html lang="zh-CN">
|
|
331
339
|
<head>
|
|
@@ -370,7 +378,7 @@ function loginPage(error = '') {
|
|
|
370
378
|
<p>本地保存语雀网页 Session,让 CLI 使用浏览器同款 Cookie 访问语雀。</p>
|
|
371
379
|
</div>
|
|
372
380
|
<div class="facts">
|
|
373
|
-
<div class="fact"><strong>保存位置</strong><span
|
|
381
|
+
<div class="fact"><strong>保存位置</strong><span>${escapeHtml(configFile)}</span></div>
|
|
374
382
|
<div class="fact"><strong>安全边界</strong><span>只写入本机配置,不写入项目仓库。</span></div>
|
|
375
383
|
<div class="fact"><strong>失效处理</strong><span>后续可用 auth-status 检测并提示重新登录。</span></div>
|
|
376
384
|
</div>
|
package/dist/cli.js
CHANGED
|
@@ -26,6 +26,7 @@ Usage:
|
|
|
26
26
|
yuque-local auth status [doc-or-book-url] [--json]
|
|
27
27
|
yuque-local doctor [--json]
|
|
28
28
|
yuque-local skill install|status|uninstall [--json]
|
|
29
|
+
yuque-local book list [--json]
|
|
29
30
|
yuque-local book create --name <name> --slug <slug> [--description <text>] [--public]
|
|
30
31
|
yuque-local book download <book-url> [--dist-dir download] [--incremental]
|
|
31
32
|
yuque-local doc create <book-url> --title <title> --markdown-file <file> [--number-headings]
|
|
@@ -136,6 +137,7 @@ function normalizeInvocation(argv) {
|
|
|
136
137
|
status: 'auth-status'
|
|
137
138
|
},
|
|
138
139
|
book: {
|
|
140
|
+
list: 'list-books',
|
|
139
141
|
create: 'create-book',
|
|
140
142
|
download: 'download-book',
|
|
141
143
|
inspect: 'inspect'
|
|
@@ -463,6 +465,12 @@ async function main() {
|
|
|
463
465
|
printCommandResult(info, flags, 'inspect completed');
|
|
464
466
|
return;
|
|
465
467
|
}
|
|
468
|
+
if (command === 'list-books') {
|
|
469
|
+
const result = await client.listBooks();
|
|
470
|
+
await recordCredentialValidation(true);
|
|
471
|
+
printCommandResult(result, flags, 'book list completed');
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
466
474
|
if (command === 'snapshot') {
|
|
467
475
|
const [url] = positional;
|
|
468
476
|
if (!url)
|
package/dist/client-cookie.js
CHANGED
|
@@ -54,6 +54,17 @@ export class YuqueCookieClient {
|
|
|
54
54
|
const appData = await this.fetchAppData(url);
|
|
55
55
|
return summarizeAppData(appData);
|
|
56
56
|
}
|
|
57
|
+
async listBooks() {
|
|
58
|
+
const result = await this.requestJson('GET', '/api/mine/books?offset=0&limit=100', undefined, `${this.host}/dashboard`);
|
|
59
|
+
const books = normalizeBookListResponse(result)
|
|
60
|
+
.map((book) => normalizeBookSummary(book, this.host))
|
|
61
|
+
.filter((book) => Boolean(book));
|
|
62
|
+
return {
|
|
63
|
+
ok: true,
|
|
64
|
+
count: books.length,
|
|
65
|
+
books
|
|
66
|
+
};
|
|
67
|
+
}
|
|
57
68
|
async getBookInfo(url) {
|
|
58
69
|
const appData = await this.fetchAppData(url);
|
|
59
70
|
if (!appData.book?.id)
|
|
@@ -490,6 +501,40 @@ function buildDocUrl(host, appData, book, doc) {
|
|
|
490
501
|
return `${host}/${bookSlug}/${docSlug}`;
|
|
491
502
|
return `${host}/api/docs/${doc.id || ''}`;
|
|
492
503
|
}
|
|
504
|
+
function normalizeBookListResponse(result) {
|
|
505
|
+
const data = result.data;
|
|
506
|
+
if (Array.isArray(data))
|
|
507
|
+
return data;
|
|
508
|
+
if (Array.isArray(data?.books))
|
|
509
|
+
return data.books;
|
|
510
|
+
if (Array.isArray(data?.repos))
|
|
511
|
+
return data.repos;
|
|
512
|
+
if (Array.isArray(result.books))
|
|
513
|
+
return result.books;
|
|
514
|
+
if (Array.isArray(result.repos))
|
|
515
|
+
return result.repos;
|
|
516
|
+
return [];
|
|
517
|
+
}
|
|
518
|
+
function normalizeBookSummary(book, host) {
|
|
519
|
+
const slug = typeof book.slug === 'string' ? book.slug : '';
|
|
520
|
+
const login = typeof book.login === 'string'
|
|
521
|
+
? book.login
|
|
522
|
+
: typeof book.user?.login === 'string'
|
|
523
|
+
? book.user.login
|
|
524
|
+
: undefined;
|
|
525
|
+
if (!slug)
|
|
526
|
+
return null;
|
|
527
|
+
return {
|
|
528
|
+
id: typeof book.id === 'number' ? book.id : undefined,
|
|
529
|
+
name: typeof book.name === 'string' ? book.name : slug,
|
|
530
|
+
slug,
|
|
531
|
+
login,
|
|
532
|
+
public: typeof book.public === 'number' || typeof book.public === 'boolean' ? book.public : undefined,
|
|
533
|
+
items_count: typeof book.items_count === 'number' ? book.items_count : undefined,
|
|
534
|
+
updated_at: typeof book.updated_at === 'string' ? book.updated_at : undefined,
|
|
535
|
+
url: login ? `${host}/${login}/${slug}` : `${host}/${slug}`
|
|
536
|
+
};
|
|
537
|
+
}
|
|
493
538
|
function guessContentType(fileName) {
|
|
494
539
|
const ext = extname(fileName).toLowerCase();
|
|
495
540
|
const types = {
|
package/docs/usage-zh.md
CHANGED
|
@@ -17,6 +17,21 @@
|
|
|
17
17
|
|
|
18
18
|
项目目录不会保存真实 Cookie。
|
|
19
19
|
|
|
20
|
+
如果需要把全局 npm 版、源码开发版、Docker 或 AI 真实测试环境隔离开,可以通过 `YUQUE_COOKIE_PLUGIN_CONFIG_DIR` 指定独立配置目录:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
YUQUE_COOKIE_PLUGIN_CONFIG_DIR=/tmp/yuque-plugin-real-test yuque-local auth login
|
|
24
|
+
YUQUE_COOKIE_PLUGIN_CONFIG_DIR=/tmp/yuque-plugin-real-test yuque-local auth status --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
指定后,Cookie 会保存到:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
/tmp/yuque-plugin-real-test/config.json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
不会影响默认的 `~/.config/yuque-cookie-plugin/config.json`。
|
|
34
|
+
|
|
20
35
|
## 2. 安装和准备
|
|
21
36
|
|
|
22
37
|
普通用户推荐从 npm 安装:
|
|
@@ -103,6 +118,12 @@ yuque-local auth login --manual
|
|
|
103
118
|
yuque-local auth logout
|
|
104
119
|
```
|
|
105
120
|
|
|
121
|
+
如果你使用了隔离配置目录,清理时也要带上同一个环境变量:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
YUQUE_COOKIE_PLUGIN_CONFIG_DIR=/tmp/yuque-plugin-real-test yuque-local auth logout
|
|
125
|
+
```
|
|
126
|
+
|
|
106
127
|
正常执行 `inspect`、`snapshot`、`download-book`、`download-doc` 等真实语雀命令成功后,也会刷新 `last_validated_at`。如果检测到 401、403、页面无法解析等登录态问题,CLI 会提示重新登录。
|
|
107
128
|
|
|
108
129
|
### 额外 Cookie
|
|
@@ -129,7 +150,38 @@ export YUQUE_EXTRA_COOKIE_VALUE='<cookie-value>'
|
|
|
129
150
|
|
|
130
151
|
额外 Cookie 不会改变本项目的主链路,只用于兼容特殊访问场景。
|
|
131
152
|
|
|
132
|
-
## 4.
|
|
153
|
+
## 4. 列出知识库
|
|
154
|
+
|
|
155
|
+
查看当前账号可访问的语雀知识库:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
yuque-local book list --json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
这个命令会通过网页 Session 调用语雀列表接口,只输出知识库摘要,不会打印本机配置文件或 Cookie。
|
|
162
|
+
|
|
163
|
+
输出示例:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"status": "success",
|
|
168
|
+
"message": "book list completed",
|
|
169
|
+
"data": {
|
|
170
|
+
"ok": true,
|
|
171
|
+
"count": 2,
|
|
172
|
+
"books": [
|
|
173
|
+
{
|
|
174
|
+
"name": "工控",
|
|
175
|
+
"slug": "ydv5i5",
|
|
176
|
+
"login": "your-login",
|
|
177
|
+
"url": "https://www.yuque.com/your-login/ydv5i5"
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 5. 下载整个知识库
|
|
133
185
|
|
|
134
186
|
推荐先下载到临时目录验证:
|
|
135
187
|
|
|
@@ -234,7 +286,7 @@ AI 或脚本可以用 `retry.args` 只重试失败文档。
|
|
|
234
286
|
|
|
235
287
|
`resources.files` 只记录本地相对路径和大小,不保存 Cookie。
|
|
236
288
|
|
|
237
|
-
##
|
|
289
|
+
## 6. 创建知识库和文档
|
|
238
290
|
|
|
239
291
|
创建私密测试知识库:
|
|
240
292
|
|
|
@@ -261,7 +313,7 @@ npm run yuque-local -- create-doc https://www.yuque.com/<your-login>/<your-book>
|
|
|
261
313
|
- 不默认修改标题文本。
|
|
262
314
|
- 返回 JSON 中 `format` 表示语雀创建接口的初始格式;如果默认 Lake 写回成功,会额外返回 `final_format: "lake"`。
|
|
263
315
|
|
|
264
|
-
##
|
|
316
|
+
## 7. 上传和插入附件
|
|
265
317
|
|
|
266
318
|
只上传文件,不写入正文:
|
|
267
319
|
|
|
@@ -333,7 +385,7 @@ npm run yuque-local -- create-doc https://www.yuque.com/<your-login>/<your-book>
|
|
|
333
385
|
- 语雀会把 Markdown 创建结果自动转换成 Lake 文档,工具随后会默认写回 Lake,后续修改应按 Lake 链路处理。
|
|
334
386
|
- 当前原生写入能力矩阵见 `docs/native-lake-capability.md`。图片、附件、思维导图、画板属于下一阶段真实探索项,不能在未验证前手写 card。
|
|
335
387
|
|
|
336
|
-
##
|
|
388
|
+
## 8. 上传图片或附件探索
|
|
337
389
|
|
|
338
390
|
只上传本地文件,不写入正文:
|
|
339
391
|
|
|
@@ -392,7 +444,7 @@ npm run yuque-local -- insert-attachment https://www.yuque.com/user/book/doc \
|
|
|
392
444
|
|
|
393
445
|
和图片一样,`insert-attachment --dry-run` 会真实上传附件以获得语雀附件 URL,但不会修改文档正文。
|
|
394
446
|
|
|
395
|
-
##
|
|
447
|
+
## 9. 下载单篇或多篇文档
|
|
396
448
|
|
|
397
449
|
下载单篇:
|
|
398
450
|
|
|
@@ -409,7 +461,7 @@ npm run yuque-local -- download-doc \
|
|
|
409
461
|
--dist-dir /tmp/yuque-doc-test
|
|
410
462
|
```
|
|
411
463
|
|
|
412
|
-
##
|
|
464
|
+
## 10. 本地预览下载结果
|
|
413
465
|
|
|
414
466
|
只生成或检查 VitePress 配置,不启动长驻服务:
|
|
415
467
|
|
|
@@ -441,7 +493,7 @@ http://localhost:5173/
|
|
|
441
493
|
npm run yuque-local -- serve-book /tmp/yuque-download-test/工控 --port 5173 --force
|
|
442
494
|
```
|
|
443
495
|
|
|
444
|
-
##
|
|
496
|
+
## 11. 快照和差异比较
|
|
445
497
|
|
|
446
498
|
抓取语雀文档快照:
|
|
447
499
|
|
|
@@ -461,7 +513,7 @@ npm run yuque-local -- diff-lake /tmp/before.json /tmp/after.json
|
|
|
461
513
|
npm run yuque-local -- lake-to-markdown /tmp/doc.snapshot.json --out /tmp/doc.md
|
|
462
514
|
```
|
|
463
515
|
|
|
464
|
-
##
|
|
516
|
+
## 12. HTML 转语雀 Lake
|
|
465
517
|
|
|
466
518
|
把本地 HTML 交给语雀 Lake editor runtime 序列化:
|
|
467
519
|
|
|
@@ -477,7 +529,7 @@ npm run yuque-local -- editor-serialize --html-file article.html --out article.l
|
|
|
477
529
|
|
|
478
530
|
说明使用的是 vendored Lake editor,而不是 fallback。
|
|
479
531
|
|
|
480
|
-
##
|
|
532
|
+
## 13. 安全写入语雀文档
|
|
481
533
|
|
|
482
534
|
强烈建议先 dry-run:
|
|
483
535
|
|
|
@@ -503,7 +555,7 @@ backups/
|
|
|
503
555
|
reports/
|
|
504
556
|
```
|
|
505
557
|
|
|
506
|
-
##
|
|
558
|
+
## 14. 文章格式化流程
|
|
507
559
|
|
|
508
560
|
本地 HTML 到语雀文档的完整流程:
|
|
509
561
|
|
|
@@ -517,7 +569,7 @@ npm run yuque-local -- format-article https://www.yuque.com/user/book/doc --html
|
|
|
517
569
|
npm run yuque-local -- format-article https://www.yuque.com/user/book/doc --html-file article.html
|
|
518
570
|
```
|
|
519
571
|
|
|
520
|
-
##
|
|
572
|
+
## 15. 常用选项
|
|
521
573
|
|
|
522
574
|
忽略图片下载:
|
|
523
575
|
|
|
@@ -565,15 +617,16 @@ npm run yuque-local -- format-article https://www.yuque.com/user/book/doc --html
|
|
|
565
617
|
|
|
566
618
|
如果需要严格的 JSON 输出,建议加 `--quiet`。
|
|
567
619
|
|
|
568
|
-
##
|
|
620
|
+
## 16. 安全规则
|
|
569
621
|
|
|
570
622
|
- 不要把真实 `_yuque_session` 或 `yuque_ctoken` 写入项目文件。
|
|
571
623
|
- 不要提交 `~/.config/yuque-cookie-plugin/config.json`。
|
|
624
|
+
- 真实测试多个版本时,用 `YUQUE_COOKIE_PLUGIN_CONFIG_DIR` 隔离配置目录。
|
|
572
625
|
- 线上写入必须先 dry-run。
|
|
573
626
|
- 批量写入前先对单篇文档做实验。
|
|
574
627
|
- 章节编号不要直接改标题文本硬塞编号,必须先做 snapshot before/after diff。
|
|
575
628
|
|
|
576
|
-
##
|
|
629
|
+
## 17. 当前已验证场景
|
|
577
630
|
|
|
578
631
|
已真实验证:
|
|
579
632
|
|
|
@@ -584,7 +637,7 @@ npm run yuque-local -- format-article https://www.yuque.com/user/book/doc --html
|
|
|
584
637
|
- 第二次增量下载全部跳过。
|
|
585
638
|
- 导出文件名保留正常空格。
|
|
586
639
|
|
|
587
|
-
##
|
|
640
|
+
## 18. 当前未完全覆盖场景
|
|
588
641
|
|
|
589
642
|
仍需继续补齐:
|
|
590
643
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: yuque-cookie-plugin
|
|
3
3
|
description: Use when an AI agent needs to operate Yuque through the local yuque-local CLI with _yuque_session and yuque_ctoken, including login, auth status, inspect, snapshot, download, create, native Lake update, image/PDF insertion, and safe document formatting. This skill is for CLI orchestration, not MCP or Yuque OpenAPI token usage.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "0.1.
|
|
5
|
+
version: "0.1.3"
|
|
6
6
|
author: "c-sunc6"
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -36,6 +36,7 @@ yuque-local auth login --manual
|
|
|
36
36
|
yuque-local auth logout --json
|
|
37
37
|
yuque-local auth status <doc-or-book-url> --json
|
|
38
38
|
yuque-local doctor --json
|
|
39
|
+
yuque-local book list --json
|
|
39
40
|
yuque-local book download <book-url> --dist-dir download --incremental --quiet --json
|
|
40
41
|
yuque-local doc download <doc-url> --dist-dir download --quiet --json
|
|
41
42
|
yuque-local doc create <book-url> --title "Title" --markdown-file article.md --number-headings --json
|
|
@@ -50,9 +51,10 @@ yuque-local skill uninstall --json
|
|
|
50
51
|
|
|
51
52
|
1. Run `yuque-local doctor --json` to inspect local installation and credential state.
|
|
52
53
|
2. If credentials are missing or stale, ask the user to run `yuque-local auth login` or `yuque-local auth login --manual`.
|
|
53
|
-
3. For
|
|
54
|
-
4. For
|
|
55
|
-
5.
|
|
54
|
+
3. For book discovery, use `yuque-local book list --json`; do not read or print the local config file.
|
|
55
|
+
4. For reads and downloads, call the relevant `book` or `doc` command with `--json`.
|
|
56
|
+
5. For writes, snapshot first, prepare the change, run a dry run when available, then apply after user approval.
|
|
57
|
+
6. Save local reports and paths from the CLI result for later audit.
|
|
56
58
|
|
|
57
59
|
## References
|
|
58
60
|
|
|
@@ -42,6 +42,13 @@ skill.uninstall:
|
|
|
42
42
|
example: "yuque-local skill uninstall --json"
|
|
43
43
|
reference: "reference/agent-spec.md"
|
|
44
44
|
|
|
45
|
+
book.list:
|
|
46
|
+
cli: "yuque-local book list"
|
|
47
|
+
description: "List Yuque books available to the current cookie-authenticated account without printing local credential files"
|
|
48
|
+
optional: ["--json"]
|
|
49
|
+
example: "yuque-local book list --json"
|
|
50
|
+
reference: "reference/agent-spec.md"
|
|
51
|
+
|
|
45
52
|
book.download:
|
|
46
53
|
cli: "yuque-local book download"
|
|
47
54
|
description: "Download a Yuque knowledge base with resources and reports"
|
|
@@ -46,6 +46,16 @@ yuque-local auth logout --json
|
|
|
46
46
|
|
|
47
47
|
Never request raw cookie values in the conversation.
|
|
48
48
|
|
|
49
|
+
## Book Discovery
|
|
50
|
+
|
|
51
|
+
Use the dedicated command:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
yuque-local book list --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Do not inspect, print, or copy the local `config.json` file to discover books. The CLI reads credentials internally and returns only book summaries.
|
|
58
|
+
|
|
49
59
|
## Safe Write Flow
|
|
50
60
|
|
|
51
61
|
1. Snapshot the online document.
|