yuque-cookie-plugin 0.1.0 → 0.1.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.
- package/README.md +24 -19
- package/dist/auth.js +10 -2
- package/dist/cli.js +53 -8
- package/docs/npm-release.md +10 -0
- package/docs/usage-zh.md +16 -1
- package/package.json +2 -1
- package/skills/yuque-cookie-plugin/SKILL.md +2 -0
- package/skills/yuque-cookie-plugin/commands.yaml +14 -0
- package/skills/yuque-cookie-plugin/reference/agent-spec.md +6 -0
package/README.md
CHANGED
|
@@ -6,19 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
这不是一个 OpenAPI wrapper,而是一个本地 CLI 操作面:AI 可以用它读取、整理、下载、快照、对比、格式化并安全写入语雀文档,尽量接近语雀编辑器原生 Lake 结构。
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
- Cookie
|
|
12
|
-
- 读取语雀信息:`inspect`
|
|
13
|
-
- 文档快照和结构对比:`snapshot`、`diff
|
|
14
|
-
- Lake 和 Markdown 辅助转换:`lake
|
|
15
|
-
- 安全写入:`apply-lake`、`update-lake`
|
|
16
|
-
- 创建知识库和文档:`create
|
|
9
|
+
## 当前能力
|
|
10
|
+
|
|
11
|
+
- Cookie 登录、清理和登录态检测:`auth login`、`auth logout`、`auth status`
|
|
12
|
+
- 读取语雀信息:`book inspect`、`doc inspect`
|
|
13
|
+
- 文档快照和结构对比:`doc snapshot`、`lake diff`
|
|
14
|
+
- Lake 和 Markdown 辅助转换:`lake to-markdown`、`lake serialize`
|
|
15
|
+
- 安全写入:`doc apply-lake`、`doc update-lake`
|
|
16
|
+
- 创建知识库和文档:`book create`、`doc create`
|
|
17
17
|
- 标题原生编号:`--number-headings`
|
|
18
|
-
- 整库/单篇下载:`download
|
|
18
|
+
- 整库/单篇下载:`book download`、`doc download`
|
|
19
19
|
- 下载资源清单、warning、retry 报告
|
|
20
20
|
- 本地 VitePress 预览:`serve-book`
|
|
21
|
-
- 上传并插入图片、PDF 附件:`upload
|
|
21
|
+
- 上传并插入图片、PDF 附件:`doc upload`、`doc insert-image`、`doc insert-attachment`
|
|
22
22
|
|
|
23
23
|
## 安装
|
|
24
24
|
|
|
@@ -28,15 +28,16 @@
|
|
|
28
28
|
npm install -g yuque-cookie-plugin
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
当前 npm 最新版本:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
npm
|
|
34
|
+
npm view yuque-cookie-plugin version
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
安装后可直接运行:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
+
yuque-local --version
|
|
40
41
|
yuque-local --help
|
|
41
42
|
yuque-local auth login
|
|
42
43
|
yuque-local doctor --json
|
|
@@ -51,14 +52,12 @@ cd yuque-cookie-plugin
|
|
|
51
52
|
npm install
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
开发者也可以在源码目录中作为“项目内本地 CLI”使用:
|
|
55
56
|
|
|
56
57
|
```bash
|
|
57
58
|
npm run yuque-local -- --help
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
MVP 阶段不建议使用 `npm install -g`、`npm link` 或修改全局 npm 配置,避免影响电脑上的其他开发环境。
|
|
61
|
-
|
|
62
61
|
## 登录
|
|
63
62
|
|
|
64
63
|
```bash
|
|
@@ -99,6 +98,12 @@ npm run yuque-local -- auth status https://www.yuque.com/<your-login>/<your-book
|
|
|
99
98
|
yuque-local auth login --manual
|
|
100
99
|
```
|
|
101
100
|
|
|
101
|
+
清理本机保存的 Cookie:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
yuque-local auth logout
|
|
105
|
+
```
|
|
106
|
+
|
|
102
107
|
也可以一次性传入参数,适合本地受控脚本:
|
|
103
108
|
|
|
104
109
|
```bash
|
|
@@ -217,12 +222,11 @@ npm test
|
|
|
217
222
|
npm run yuque-local -- --help
|
|
218
223
|
```
|
|
219
224
|
|
|
220
|
-
|
|
225
|
+
发布检查:
|
|
221
226
|
|
|
222
227
|
```bash
|
|
223
|
-
npm
|
|
224
|
-
npm
|
|
225
|
-
yuque-local --help
|
|
228
|
+
npm run release:check
|
|
229
|
+
npm run release:smoke
|
|
226
230
|
```
|
|
227
231
|
|
|
228
232
|
真实语雀验收不会进入默认 `npm test`。需要手动运行:
|
|
@@ -248,6 +252,7 @@ npm run real:acceptance -- \
|
|
|
248
252
|
|
|
249
253
|
- 不要把真实 `_yuque_session` 或 `yuque_ctoken` 写入项目文件。
|
|
250
254
|
- 不要提交 `~/.config/yuque-cookie-plugin/config.json`。
|
|
255
|
+
- 需要清理本机凭据时运行 `yuque-local auth logout`。
|
|
251
256
|
- `reports/`、`backups/`、`node_modules/` 已被 `.gitignore` 忽略。
|
|
252
257
|
- 批量写入前先对单篇文档做真实实验。
|
|
253
258
|
- 不确定 Lake 语义时,先 snapshot,再 diff,再实现。
|
package/dist/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { chmod, mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { chmod, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { execFile } from 'node:child_process';
|
|
5
5
|
import { createInterface } from 'node:readline/promises';
|
|
6
6
|
import os from 'node:os';
|
|
@@ -11,6 +11,14 @@ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
|
11
11
|
export function getConfigFilePath() {
|
|
12
12
|
return CONFIG_FILE;
|
|
13
13
|
}
|
|
14
|
+
export async function clearSavedCredentials() {
|
|
15
|
+
const existed = existsSync(CONFIG_FILE);
|
|
16
|
+
await rm(CONFIG_FILE, { force: true });
|
|
17
|
+
return {
|
|
18
|
+
config_file: CONFIG_FILE,
|
|
19
|
+
removed: existed
|
|
20
|
+
};
|
|
21
|
+
}
|
|
14
22
|
export function getCredentials(flags = {}) {
|
|
15
23
|
const envSession = process.env[String(flags.sessionEnv || 'YUQUE_SESSION')];
|
|
16
24
|
const envCtoken = process.env[String(flags.ctokenEnv || 'YUQUE_CTOKEN')];
|
|
@@ -28,7 +36,7 @@ export function getCredentials(flags = {}) {
|
|
|
28
36
|
if (saved?.session && saved?.ctoken) {
|
|
29
37
|
return { ...saved, extraCookies: { ...(saved.extraCookies || {}), ...extraCookies }, source: CONFIG_FILE };
|
|
30
38
|
}
|
|
31
|
-
throw new Error('Missing Yuque credentials. Run "yuque-local login" to configure them in your browser.');
|
|
39
|
+
throw new Error('Missing Yuque credentials. Run "yuque-local auth login" to configure them in your browser.');
|
|
32
40
|
}
|
|
33
41
|
export function getCredentialStatus(flags = {}) {
|
|
34
42
|
const envSession = process.env[String(flags.sessionEnv || 'YUQUE_SESSION')];
|
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import process from 'node:process';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { cp, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
5
5
|
import { existsSync } from 'node:fs';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { YuqueCookieClient } from "./client-cookie.js";
|
|
8
8
|
import { diffLakeSnapshots } from "./lake-diff.js";
|
|
9
9
|
import { writeJson } from "./fs-utils.js";
|
|
10
|
-
import { getConfigFilePath, getCredentialStatus, getCredentials, loginWithBrowser, recordCredentialValidation } from "./auth.js";
|
|
10
|
+
import { clearSavedCredentials, getConfigFilePath, getCredentialStatus, getCredentials, loginWithBrowser, recordCredentialValidation } from "./auth.js";
|
|
11
11
|
import { serializeHtmlToLake } from "./editor-bridge.js";
|
|
12
12
|
import { snapshotToMarkdown } from "./lake-markdown.js";
|
|
13
13
|
import { downloadBook, downloadDocs } from "./downloader.js";
|
|
@@ -20,10 +20,12 @@ function help() {
|
|
|
20
20
|
console.log(`yuque-local
|
|
21
21
|
|
|
22
22
|
Usage:
|
|
23
|
+
yuque-local --version
|
|
23
24
|
yuque-local auth login [--manual]
|
|
25
|
+
yuque-local auth logout [--json]
|
|
24
26
|
yuque-local auth status [doc-or-book-url] [--json]
|
|
25
27
|
yuque-local doctor [--json]
|
|
26
|
-
yuque-local skill install|status [--json]
|
|
28
|
+
yuque-local skill install|status|uninstall [--json]
|
|
27
29
|
yuque-local book create --name <name> --slug <slug> [--description <text>] [--public]
|
|
28
30
|
yuque-local book download <book-url> [--dist-dir download] [--incremental]
|
|
29
31
|
yuque-local doc create <book-url> --title <title> --markdown-file <file> [--number-headings]
|
|
@@ -88,6 +90,7 @@ Options:
|
|
|
88
90
|
--force Recreate VitePress config
|
|
89
91
|
--config-only Generate serve-book VitePress config and exit
|
|
90
92
|
-h, --help Show help
|
|
93
|
+
-v, --version Show version
|
|
91
94
|
`);
|
|
92
95
|
}
|
|
93
96
|
function parseArgs(argv) {
|
|
@@ -129,6 +132,7 @@ function normalizeInvocation(argv) {
|
|
|
129
132
|
const grouped = {
|
|
130
133
|
auth: {
|
|
131
134
|
login: 'login',
|
|
135
|
+
logout: 'logout',
|
|
132
136
|
status: 'auth-status'
|
|
133
137
|
},
|
|
134
138
|
book: {
|
|
@@ -162,6 +166,14 @@ function normalizeInvocation(argv) {
|
|
|
162
166
|
function toCamel(value) {
|
|
163
167
|
return value.replace(/-([a-z])/g, (_match, char) => char.toUpperCase());
|
|
164
168
|
}
|
|
169
|
+
async function readPackageInfo() {
|
|
170
|
+
const packageJsonPath = path.join(PACKAGE_ROOT, 'package.json');
|
|
171
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'));
|
|
172
|
+
return {
|
|
173
|
+
name: packageJson.name || 'yuque-cookie-plugin',
|
|
174
|
+
version: packageJson.version || '0.0.0'
|
|
175
|
+
};
|
|
176
|
+
}
|
|
165
177
|
async function createClient(flags) {
|
|
166
178
|
let credentials;
|
|
167
179
|
try {
|
|
@@ -226,14 +238,13 @@ function printError(error) {
|
|
|
226
238
|
console.error(`yuque-local error: ${message}`);
|
|
227
239
|
}
|
|
228
240
|
async function commandDoctor(flags) {
|
|
229
|
-
const
|
|
230
|
-
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'));
|
|
241
|
+
const packageInfo = await readPackageInfo();
|
|
231
242
|
const status = getCredentialStatus(flags);
|
|
232
243
|
const skillSource = path.join(PACKAGE_ROOT, 'skills', 'yuque-cookie-plugin');
|
|
233
244
|
const data = {
|
|
234
245
|
package: {
|
|
235
|
-
name:
|
|
236
|
-
version:
|
|
246
|
+
name: packageInfo.name,
|
|
247
|
+
version: packageInfo.version,
|
|
237
248
|
root: PACKAGE_ROOT
|
|
238
249
|
},
|
|
239
250
|
runtime: {
|
|
@@ -277,9 +288,24 @@ async function commandSkill(action, flags) {
|
|
|
277
288
|
console.log(JSON.stringify(data, null, 2));
|
|
278
289
|
return;
|
|
279
290
|
}
|
|
291
|
+
const source = path.join(PACKAGE_ROOT, 'skills', 'yuque-cookie-plugin');
|
|
292
|
+
if (action === 'uninstall') {
|
|
293
|
+
const targets = skillTargets();
|
|
294
|
+
const removed = [];
|
|
295
|
+
for (const target of targets) {
|
|
296
|
+
const existed = existsSync(path.join(target, 'SKILL.md'));
|
|
297
|
+
await rm(target, { recursive: true, force: true });
|
|
298
|
+
removed.push({ path: target, removed: existed });
|
|
299
|
+
}
|
|
300
|
+
const data = { removed };
|
|
301
|
+
if (flags.json)
|
|
302
|
+
printJsonResult(jsonResult('success', 'skill uninstalled', data));
|
|
303
|
+
else
|
|
304
|
+
console.log(JSON.stringify(data, null, 2));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
280
307
|
if (action !== 'install')
|
|
281
308
|
throw new Error(`Unknown skill action: ${action}`);
|
|
282
|
-
const source = path.join(PACKAGE_ROOT, 'skills', 'yuque-cookie-plugin');
|
|
283
309
|
if (!existsSync(path.join(source, 'SKILL.md')))
|
|
284
310
|
throw new Error(`Skill source is missing: ${source}`);
|
|
285
311
|
const installed = [];
|
|
@@ -311,6 +337,14 @@ async function main() {
|
|
|
311
337
|
help();
|
|
312
338
|
return;
|
|
313
339
|
}
|
|
340
|
+
if (command === 'version' || command === '--version' || command === '-v') {
|
|
341
|
+
const packageInfo = await readPackageInfo();
|
|
342
|
+
if (flags.json)
|
|
343
|
+
printJsonResult(jsonResult('success', 'version loaded', packageInfo));
|
|
344
|
+
else
|
|
345
|
+
console.log(`${packageInfo.name}@${packageInfo.version}`);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
314
348
|
if (command === 'diff-lake') {
|
|
315
349
|
const [beforePath, afterPath] = positional;
|
|
316
350
|
if (!beforePath || !afterPath)
|
|
@@ -354,6 +388,17 @@ async function main() {
|
|
|
354
388
|
await loginWithBrowser(flags);
|
|
355
389
|
return;
|
|
356
390
|
}
|
|
391
|
+
if (command === 'logout') {
|
|
392
|
+
const result = await clearSavedCredentials();
|
|
393
|
+
printCommandResult({
|
|
394
|
+
ok: true,
|
|
395
|
+
...result,
|
|
396
|
+
note: process.env.YUQUE_SESSION || process.env.YUQUE_CTOKEN
|
|
397
|
+
? 'Environment credentials are still set in the current shell.'
|
|
398
|
+
: undefined
|
|
399
|
+
}, flags, 'auth credentials cleared');
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
357
402
|
if (command === 'doctor') {
|
|
358
403
|
await commandDoctor(flags);
|
|
359
404
|
return;
|
package/docs/npm-release.md
CHANGED
|
@@ -27,6 +27,16 @@ npm run release:check
|
|
|
27
27
|
|
|
28
28
|
这个命令会执行类型检查、测试、构建、敏感信息扫描、npm 包名检查、`npm pack` 和临时 prefix 安装验证。
|
|
29
29
|
|
|
30
|
+
## 发布后检查
|
|
31
|
+
|
|
32
|
+
发布完成后运行:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm run release:smoke
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
这个命令会从 npm registry 安装 `yuque-cookie-plugin@latest` 到临时 prefix,并验证 `yuque-local --help` 与 `yuque-local doctor --json`。
|
|
39
|
+
|
|
30
40
|
确认 tarball 至少包含:
|
|
31
41
|
|
|
32
42
|
- `bin/yuque-local.mjs`
|
package/docs/usage-zh.md
CHANGED
|
@@ -19,7 +19,15 @@
|
|
|
19
19
|
|
|
20
20
|
## 2. 安装和准备
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
普通用户推荐从 npm 安装:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g yuque-cookie-plugin
|
|
26
|
+
yuque-local --version
|
|
27
|
+
yuque-local --help
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
开发者进入项目目录:
|
|
23
31
|
|
|
24
32
|
```bash
|
|
25
33
|
cd /home/mi/文档/yuque-cookie-plugin
|
|
@@ -34,6 +42,7 @@ npm install
|
|
|
34
42
|
检查工具是否可运行:
|
|
35
43
|
|
|
36
44
|
```bash
|
|
45
|
+
npm run yuque-local -- --version
|
|
37
46
|
npm run yuque-local -- --help
|
|
38
47
|
```
|
|
39
48
|
|
|
@@ -88,6 +97,12 @@ Docker、SSH、远程服务器等无头环境中,推荐使用手动模式,
|
|
|
88
97
|
yuque-local auth login --manual
|
|
89
98
|
```
|
|
90
99
|
|
|
100
|
+
清理本机保存的 Cookie:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
yuque-local auth logout
|
|
104
|
+
```
|
|
105
|
+
|
|
91
106
|
正常执行 `inspect`、`snapshot`、`download-book`、`download-doc` 等真实语雀命令成功后,也会刷新 `last_validated_at`。如果检测到 401、403、页面无法解析等登录态问题,CLI 会提示重新登录。
|
|
92
107
|
|
|
93
108
|
### 额外 Cookie
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yuque-cookie-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cookie-based Yuque CLI for AI agents, without MCP or OpenAPI token limits.",
|
|
6
6
|
"homepage": "https://github.com/c-sunc6/yuque-cookie-plugin#readme",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"yuque-local": "tsx ./src/cli.ts",
|
|
49
49
|
"real:acceptance": "tsx ./scripts/real-acceptance.ts",
|
|
50
50
|
"release:check": "tsx ./scripts/prepublish-check.ts",
|
|
51
|
+
"release:smoke": "tsx ./scripts/registry-smoke.ts",
|
|
51
52
|
"typecheck": "tsc --noEmit",
|
|
52
53
|
"test": "npm run typecheck && vitest run && npm run yuque-local -- --help",
|
|
53
54
|
"test:unit": "vitest run",
|
|
@@ -33,6 +33,7 @@ Legacy flat commands such as `yuque-local snapshot` and `yuque-local download-bo
|
|
|
33
33
|
```bash
|
|
34
34
|
yuque-local auth login
|
|
35
35
|
yuque-local auth login --manual
|
|
36
|
+
yuque-local auth logout --json
|
|
36
37
|
yuque-local auth status <doc-or-book-url> --json
|
|
37
38
|
yuque-local doctor --json
|
|
38
39
|
yuque-local book download <book-url> --dist-dir download --incremental --quiet --json
|
|
@@ -42,6 +43,7 @@ yuque-local doc snapshot <doc-url> --out /tmp/doc.snapshot.json --json
|
|
|
42
43
|
yuque-local doc apply-lake <doc-url> --lake-file body_asl.html --dry-run --json
|
|
43
44
|
yuque-local doc insert-image <doc-url> --file image.png --after-text "位置" --json
|
|
44
45
|
yuque-local doc insert-attachment <doc-url> --file file.pdf --after-text "附件" --json
|
|
46
|
+
yuque-local skill uninstall --json
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
## Workflow
|
|
@@ -14,6 +14,13 @@ auth.status:
|
|
|
14
14
|
example: "yuque-local auth status https://www.yuque.com/user/book --json"
|
|
15
15
|
reference: "reference/agent-spec.md"
|
|
16
16
|
|
|
17
|
+
auth.logout:
|
|
18
|
+
cli: "yuque-local auth logout"
|
|
19
|
+
description: "Remove saved local Yuque cookies from the user config file"
|
|
20
|
+
optional: ["--json"]
|
|
21
|
+
example: "yuque-local auth logout --json"
|
|
22
|
+
reference: "reference/agent-spec.md"
|
|
23
|
+
|
|
17
24
|
doctor:
|
|
18
25
|
cli: "yuque-local doctor"
|
|
19
26
|
description: "Inspect CLI version, runtime, auth config path, and skill install status"
|
|
@@ -28,6 +35,13 @@ skill.install:
|
|
|
28
35
|
example: "yuque-local skill install --json"
|
|
29
36
|
reference: "reference/agent-spec.md"
|
|
30
37
|
|
|
38
|
+
skill.uninstall:
|
|
39
|
+
cli: "yuque-local skill uninstall"
|
|
40
|
+
description: "Remove the installed yuque-cookie-plugin AI skill from local supported agent skill directories"
|
|
41
|
+
optional: ["--json"]
|
|
42
|
+
example: "yuque-local skill uninstall --json"
|
|
43
|
+
reference: "reference/agent-spec.md"
|
|
44
|
+
|
|
31
45
|
book.download:
|
|
32
46
|
cli: "yuque-local book download"
|
|
33
47
|
description: "Download a Yuque knowledge base with resources and reports"
|
|
@@ -38,6 +38,12 @@ For Docker, SSH, or headless terminals:
|
|
|
38
38
|
yuque-local auth login --manual
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
To clear saved local cookies:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
yuque-local auth logout --json
|
|
45
|
+
```
|
|
46
|
+
|
|
41
47
|
Never request raw cookie values in the conversation.
|
|
42
48
|
|
|
43
49
|
## Safe Write Flow
|