wxpub-cli 0.1.2 → 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.
- package/README.md +26 -4
- package/dist/client.d.ts +32 -0
- package/dist/client.js +50 -0
- package/dist/client.js.map +1 -1
- package/dist/commands/illustrate.d.ts +9 -0
- package/dist/commands/illustrate.js +34 -0
- package/dist/commands/illustrate.js.map +1 -0
- package/dist/commands/login.d.ts +12 -4
- package/dist/commands/login.js +66 -3
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/tone.d.ts +6 -0
- package/dist/commands/tone.js +35 -0
- package/dist/commands/tone.js.map +1 -0
- package/dist/device-auth.d.ts +66 -0
- package/dist/device-auth.js +128 -0
- package/dist/device-auth.js.map +1 -0
- package/dist/index.js +25 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,8 +21,10 @@ npm install -g wxpub-cli@0.1.1
|
|
|
21
21
|
## 快速开始
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
# 1.
|
|
25
|
-
wxpub login
|
|
24
|
+
# 1. 登录(推荐:设备流交互登录——给个 URL 浏览器确认即得短时效委托票,无需手动贴 Key)
|
|
25
|
+
wxpub login
|
|
26
|
+
# → 打开 https://auth.ai-as.cc/admin/#/device?user_code=XXXX-XXXX 批准即可
|
|
27
|
+
# 委托票有时效(约 15 分钟),过期重跑 wxpub login
|
|
26
28
|
|
|
27
29
|
# 2. 发文(markdown 直传,渲染与主题判定在服务端完成)
|
|
28
30
|
wxpub publish --account danxin --file article.md
|
|
@@ -31,6 +33,10 @@ wxpub publish --account danxin --file article.md
|
|
|
31
33
|
wxpub me
|
|
32
34
|
```
|
|
33
35
|
|
|
36
|
+
设备流走 auth(AuthKeystone)标准协议:RFC 8414 发现 → RFC 8628 设备授权 → 批准后签 RFC 8693 委托票(`aud=client_wechat`,服务端按委托票验票)。全程零密钥经手、端点零硬编码。
|
|
37
|
+
|
|
38
|
+
旧通道仍可用:`wxpub login --base-url https://yyps.net --api-key sk_live_xxx`(API Key 由服务端签发,长期有效)。
|
|
39
|
+
|
|
34
40
|
API Key 由服务端签发(管理后台或 `scripts/generate_api_key.py`)。
|
|
35
41
|
|
|
36
42
|
也可以不落配置,用环境变量:`WXPUB_BASE_URL` / `WXPUB_API_KEY`。
|
|
@@ -63,6 +69,22 @@ wxpub publish -a <account> -f article.md [options]
|
|
|
63
69
|
- 同内容重复投递会被服务端幂等去重(返回 `duplicate: true`),不会新建草稿
|
|
64
70
|
- 只落草稿箱,**不群发**;群发请在公众号后台人工确认
|
|
65
71
|
|
|
72
|
+
### `tone` — 拉账号写作调性(写文前注入)
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
wxpub tone -a danxin
|
|
76
|
+
# 输出主笔人设(persona)+ 结构规则(style_rules)+ 建议字数区间
|
|
77
|
+
# AI/agent 写文前先跑这个,把调性注入上下文,保证成稿跟号调性一致
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `illustrate` — AI 生成正文配图
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
wxpub illustrate -a danxin -f article.md [-t 标题] [--preset <模板id>]
|
|
84
|
+
# LLM 读全文提炼画面 prompt → 出图 → 上传永久素材
|
|
85
|
+
# 输出可直接粘贴进 markdown 的  片段;约 10-60 秒
|
|
86
|
+
```
|
|
87
|
+
|
|
66
88
|
### `theme` — 查询账号默认主题
|
|
67
89
|
|
|
68
90
|
```bash
|
|
@@ -94,7 +116,7 @@ wxpub --json theme -a danxin
|
|
|
94
116
|
# {"account":"danxin","theme_key":"green","theme_name":"品牌绿"}
|
|
95
117
|
```
|
|
96
118
|
|
|
97
|
-
agent 典型工作流:`
|
|
119
|
+
agent 典型工作流:`tone` 拉调性 → 按调性写 markdown → `illustrate` 生成插图 → `publish` 投递 → 从 JSON 里取 `media_id` 复命。
|
|
98
120
|
|
|
99
121
|
## 开发
|
|
100
122
|
|
|
@@ -109,4 +131,4 @@ node dist/index.js --help
|
|
|
109
131
|
|
|
110
132
|
## 路线图
|
|
111
133
|
|
|
112
|
-
- v0.2
|
|
134
|
+
- ✅ v0.2:`wxpub tone` 拉账号调性(写文前注入 agent 上下文);`wxpub illustrate` AI 生成文中插图(依赖服务端 `/api/mp/account-tone` 与 `/api/mp/ai-image`)
|
package/dist/client.d.ts
CHANGED
|
@@ -71,6 +71,31 @@ export interface UploadResult {
|
|
|
71
71
|
/** 微信 CDN URL(mmbiz…),可直接内嵌正文 */
|
|
72
72
|
url?: string;
|
|
73
73
|
}
|
|
74
|
+
/** 账号绑定的写作调性(persona 人设 + style_rules 结构规则 + 建议字数区间)。 */
|
|
75
|
+
export interface TonePreset {
|
|
76
|
+
name: string;
|
|
77
|
+
persona: string;
|
|
78
|
+
styleRules: string;
|
|
79
|
+
lengthMin?: number;
|
|
80
|
+
lengthMax?: number;
|
|
81
|
+
}
|
|
82
|
+
export interface AccountToneResult {
|
|
83
|
+
ok: boolean;
|
|
84
|
+
account: string;
|
|
85
|
+
/** null = 账号未绑定调性(或已删/停用),回落无调性写作 */
|
|
86
|
+
tone: TonePreset | null;
|
|
87
|
+
}
|
|
88
|
+
export interface IllustrationResult {
|
|
89
|
+
ok: boolean;
|
|
90
|
+
message: string;
|
|
91
|
+
mediaId?: string;
|
|
92
|
+
/** mmbiz URL,可直接内嵌 markdown 正文 */
|
|
93
|
+
url?: string;
|
|
94
|
+
/** 现成的插图片段  */
|
|
95
|
+
markdown?: string;
|
|
96
|
+
/** 服务端 LLM 提炼的画面 prompt(透明度/复用价值) */
|
|
97
|
+
prompt?: string;
|
|
98
|
+
}
|
|
74
99
|
/** 服务端错误(4xx/5xx 或业务失败),携带状态码与响应体。 */
|
|
75
100
|
export declare class WxpubApiError extends Error {
|
|
76
101
|
readonly status: number;
|
|
@@ -105,6 +130,13 @@ export declare class WxpubClient {
|
|
|
105
130
|
offset?: number;
|
|
106
131
|
count?: number;
|
|
107
132
|
}): Promise<MaterialsResult>;
|
|
133
|
+
/** 查询账号绑定的写作调性(写文前注入上下文;未绑定返回 tone=null)。 */
|
|
134
|
+
accountTone(account: string): Promise<AccountToneResult>;
|
|
135
|
+
/** AI 生成正文配图(LLM 提炼 prompt → 出图 → 上传素材)。耗时 10-60s,注意超时。 */
|
|
136
|
+
generateIllustration(account: string, text: string, options?: {
|
|
137
|
+
title?: string;
|
|
138
|
+
presetId?: number;
|
|
139
|
+
}): Promise<IllustrationResult>;
|
|
108
140
|
/** 上传本地图片为永久素材,返回 media_id + mmbiz URL(正文插图用)。 */
|
|
109
141
|
uploadImage(account: string, fileName: string, fileBytes: Uint8Array): Promise<UploadResult>;
|
|
110
142
|
}
|
package/dist/client.js
CHANGED
|
@@ -171,6 +171,56 @@ export class WxpubClient {
|
|
|
171
171
|
items,
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
|
+
/** 查询账号绑定的写作调性(写文前注入上下文;未绑定返回 tone=null)。 */
|
|
175
|
+
async accountTone(account) {
|
|
176
|
+
const body = (await this.request(`/api/mp/account-tone?account=${encodeURIComponent(account)}`, { method: "GET", headers: this.authHeaders() }));
|
|
177
|
+
if (body.success !== true) {
|
|
178
|
+
throw new WxpubApiError(body.message || "查询账号调性失败", 0, body);
|
|
179
|
+
}
|
|
180
|
+
const tone = body.tone;
|
|
181
|
+
return {
|
|
182
|
+
ok: true,
|
|
183
|
+
account: body.account ?? account,
|
|
184
|
+
tone: tone
|
|
185
|
+
? {
|
|
186
|
+
name: tone.name || "",
|
|
187
|
+
persona: tone.persona || "",
|
|
188
|
+
styleRules: tone.style_rules || "",
|
|
189
|
+
lengthMin: typeof tone.length_min === "number" ? tone.length_min : undefined,
|
|
190
|
+
lengthMax: typeof tone.length_max === "number" ? tone.length_max : undefined,
|
|
191
|
+
}
|
|
192
|
+
: null,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/** AI 生成正文配图(LLM 提炼 prompt → 出图 → 上传素材)。耗时 10-60s,注意超时。 */
|
|
196
|
+
async generateIllustration(account, text, options = {}) {
|
|
197
|
+
const payload = {
|
|
198
|
+
account,
|
|
199
|
+
text,
|
|
200
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
201
|
+
};
|
|
202
|
+
if (options.title !== undefined)
|
|
203
|
+
payload.title = options.title;
|
|
204
|
+
if (options.presetId !== undefined)
|
|
205
|
+
payload.preset_id = options.presetId;
|
|
206
|
+
const body = (await this.request("/api/mp/ai-image", {
|
|
207
|
+
method: "POST",
|
|
208
|
+
headers: { ...this.authHeaders(), "Content-Type": "application/json" },
|
|
209
|
+
body: JSON.stringify(payload),
|
|
210
|
+
}));
|
|
211
|
+
// mp 通道业务失败也是 HTTP 200 + success:false + message(生图失败不阻断语义)
|
|
212
|
+
if (body.success !== true) {
|
|
213
|
+
throw new WxpubApiError(body.message || "生成配图失败", 0, body);
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
ok: true,
|
|
217
|
+
mediaId: body.media_id || undefined,
|
|
218
|
+
url: body.url || undefined,
|
|
219
|
+
markdown: body.markdown || undefined,
|
|
220
|
+
prompt: body.prompt || undefined,
|
|
221
|
+
message: body.message || "",
|
|
222
|
+
};
|
|
223
|
+
}
|
|
174
224
|
/** 上传本地图片为永久素材,返回 media_id + mmbiz URL(正文插图用)。 */
|
|
175
225
|
async uploadImage(account, fileName, fileBytes) {
|
|
176
226
|
const form = new FormData();
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsCzC,iDAAiD;AACjD,MAAM,UAAU,mBAAmB,CACjC,KAAmB,EACnB,MAAoB,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EACvD,QAAsB,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC;IAE5D,MAAM,OAAO,GAAmB;QAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,UAAU;QAC1B,SAAS,EAAE,GAAG,EAAE;QAChB,KAAK,EAAE,KAAK,EAAE;KACf,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9D,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3D,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS;QAAE,OAAO,CAAC,kBAAkB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC9F,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,CAAC,cAAc,GAAG,KAAK,CAAC,YAAY,CAAC;IAClF,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IACrD,OAAO,OAAO,CAAC;AACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface IllustrateOptions {
|
|
2
|
+
account: string;
|
|
3
|
+
file: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
presetId?: number;
|
|
6
|
+
json: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** wxpub illustrate:AI 生成正文配图,输出可直接粘贴进 markdown 的插图片段。 */
|
|
9
|
+
export declare function runIllustrate(options: IllustrateOptions): Promise<void>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { WxpubClient } from "../client.js";
|
|
3
|
+
import { resolveConfig } from "../config.js";
|
|
4
|
+
/** AI 生图含出图+上传全链路,10-60s 常态,给足超时余量 */
|
|
5
|
+
const ILLUSTRATE_TIMEOUT_MS = 180_000;
|
|
6
|
+
/** wxpub illustrate:AI 生成正文配图,输出可直接粘贴进 markdown 的插图片段。 */
|
|
7
|
+
export async function runIllustrate(options) {
|
|
8
|
+
const config = resolveConfig();
|
|
9
|
+
const text = await readFile(options.file, "utf8");
|
|
10
|
+
const client = new WxpubClient({ ...config, timeoutMs: ILLUSTRATE_TIMEOUT_MS });
|
|
11
|
+
const result = await client.generateIllustration(options.account, text, {
|
|
12
|
+
title: options.title,
|
|
13
|
+
presetId: options.presetId,
|
|
14
|
+
});
|
|
15
|
+
if (options.json) {
|
|
16
|
+
console.log(JSON.stringify({
|
|
17
|
+
media_id: result.mediaId ?? null,
|
|
18
|
+
url: result.url ?? null,
|
|
19
|
+
markdown: result.markdown ?? null,
|
|
20
|
+
}));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
console.log(`✓ 配图已生成并上传永久素材`);
|
|
24
|
+
if (result.prompt) {
|
|
25
|
+
console.log(` 画面 prompt:${result.prompt.slice(0, 80)}${result.prompt.length > 80 ? "…" : ""}`);
|
|
26
|
+
}
|
|
27
|
+
if (result.mediaId) {
|
|
28
|
+
console.log(` media_id:${result.mediaId}`);
|
|
29
|
+
}
|
|
30
|
+
if (result.markdown) {
|
|
31
|
+
console.log(`\n 插入正文:${result.markdown}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=illustrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"illustrate.js","sourceRoot":"","sources":["../../src/commands/illustrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAU7C,sCAAsC;AACtC,MAAM,qBAAqB,GAAG,OAAO,CAAC;AAEtC,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA0B;IAC5D,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE;QACtE,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;YAChC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;SAClC,CAAC,CACH,CAAC;QACF,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CACT,eAAe,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
export interface LoginOptions {
|
|
2
|
-
|
|
3
|
-
apiKey
|
|
2
|
+
/** 旧通道:手动贴 API Key / JWT(仍可用) */
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
/** 发文服务地址;设备流登录时缺省 https://yyps.net */
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
/** auth 服务 issuer;设备流登录时缺省 https://auth.ai-as.cc */
|
|
7
|
+
authIssuer?: string;
|
|
4
8
|
}
|
|
5
|
-
/**
|
|
6
|
-
|
|
9
|
+
/**
|
|
10
|
+
* wxpub login:
|
|
11
|
+
* - 无 --api-key:设备流交互登录(给个 URL 浏览器确认 → 轮询拿 JWT 存配置)
|
|
12
|
+
* - 带 --api-key:旧通道原样保存
|
|
13
|
+
*/
|
|
14
|
+
export declare function runLogin(options: LoginOptions): Promise<void>;
|
package/dist/commands/login.js
CHANGED
|
@@ -1,10 +1,73 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
1
2
|
import { configPath, normalizeBaseUrl, saveConfig } from "../config.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { DEFAULT_AUTH_ISSUER, DEVICE_CLIENT_ID, DeviceFlowError, discoverDeviceEndpoints, pollDeviceToken, requestDeviceAuthorization, } from "../device-auth.js";
|
|
4
|
+
/** 尽力打开浏览器(平台差异吞错;失败时用户手点打印出的 URL)。 */
|
|
5
|
+
function openBrowser(url) {
|
|
6
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
7
|
+
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
8
|
+
try {
|
|
9
|
+
spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// 打印的 URL 就是完整兜底
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* wxpub login:
|
|
17
|
+
* - 无 --api-key:设备流交互登录(给个 URL 浏览器确认 → 轮询拿 JWT 存配置)
|
|
18
|
+
* - 带 --api-key:旧通道原样保存
|
|
19
|
+
*/
|
|
20
|
+
export async function runLogin(options) {
|
|
21
|
+
if (!options.apiKey) {
|
|
22
|
+
await runDeviceLogin(options);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl ?? "https://yyps.net");
|
|
5
26
|
saveConfig({ baseUrl, apiKey: options.apiKey.trim() });
|
|
6
27
|
console.log(`已保存到 ${configPath()}`);
|
|
7
28
|
console.log(`服务地址:${baseUrl}`);
|
|
8
29
|
console.log("现在可以发文了:wxpub publish --account <账号> --file article.md");
|
|
9
30
|
}
|
|
31
|
+
/** 设备流交互登录:discovery → 授权 URL → 轮询 → 存 JWT。 */
|
|
32
|
+
async function runDeviceLogin(options) {
|
|
33
|
+
const issuer = normalizeBaseUrl(options.authIssuer ?? DEFAULT_AUTH_ISSUER);
|
|
34
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl ?? "https://yyps.net");
|
|
35
|
+
console.log(`连接授权服务器:${issuer}`);
|
|
36
|
+
const endpoints = await discoverDeviceEndpoints(issuer);
|
|
37
|
+
const auth = await requestDeviceAuthorization(endpoints.deviceAuthorizationEndpoint);
|
|
38
|
+
console.log();
|
|
39
|
+
console.log("请在浏览器完成登录并批准:");
|
|
40
|
+
console.log(` ${auth.verificationUriComplete}`);
|
|
41
|
+
console.log(` 用户码:${auth.userCode}(${auth.expiresIn} 秒内有效)`);
|
|
42
|
+
openBrowser(auth.verificationUriComplete);
|
|
43
|
+
console.log();
|
|
44
|
+
console.log("等待授权…(批准后自动继续;拒绝或超时会退出)");
|
|
45
|
+
try {
|
|
46
|
+
const { accessToken } = await pollDeviceToken({
|
|
47
|
+
tokenEndpoint: endpoints.tokenEndpoint,
|
|
48
|
+
clientId: DEVICE_CLIENT_ID,
|
|
49
|
+
deviceCode: auth.deviceCode,
|
|
50
|
+
intervalSecs: auth.interval,
|
|
51
|
+
});
|
|
52
|
+
// JWT 走现有 Bearer 通道(client.ts 三段点分判定),publish 等接口零改动
|
|
53
|
+
saveConfig({ baseUrl, apiKey: accessToken });
|
|
54
|
+
console.log("✓ 授权成功,登录态已保存");
|
|
55
|
+
console.log(`已保存到 ${configPath()}`);
|
|
56
|
+
console.log(`服务地址:${baseUrl}`);
|
|
57
|
+
console.log("现在可以发文了:wxpub publish --account <账号> --file article.md");
|
|
58
|
+
console.log("提示:token 有时效,过期后重跑 wxpub login 即可。");
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
if (err instanceof DeviceFlowError && err.code === "access_denied") {
|
|
62
|
+
console.error("✗ 你在浏览器里拒绝了本次授权");
|
|
63
|
+
}
|
|
64
|
+
else if (err instanceof DeviceFlowError && err.code === "expired_token") {
|
|
65
|
+
console.error("✗ 设备码已过期,请重跑 wxpub login");
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
10
73
|
//# sourceMappingURL=login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { WxpubClient } from "../client.js";
|
|
2
|
+
import { resolveConfig } from "../config.js";
|
|
3
|
+
/** wxpub tone:拉账号绑定的写作调性——AI 写文前注入上下文,保证成稿跟号调性一致。 */
|
|
4
|
+
export async function runTone(options) {
|
|
5
|
+
const config = resolveConfig();
|
|
6
|
+
const client = new WxpubClient(config);
|
|
7
|
+
const result = await client.accountTone(options.account);
|
|
8
|
+
if (options.json) {
|
|
9
|
+
console.log(JSON.stringify({
|
|
10
|
+
account: result.account,
|
|
11
|
+
tone: result.tone
|
|
12
|
+
? {
|
|
13
|
+
name: result.tone.name,
|
|
14
|
+
persona: result.tone.persona,
|
|
15
|
+
style_rules: result.tone.styleRules,
|
|
16
|
+
length_min: result.tone.lengthMin ?? null,
|
|
17
|
+
length_max: result.tone.lengthMax ?? null,
|
|
18
|
+
}
|
|
19
|
+
: null,
|
|
20
|
+
}, null, 0));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!result.tone) {
|
|
24
|
+
console.log(`账号 ${result.account} 未绑定写作调性(服务端「账号管理 → 绑定调性」可配置)`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const tone = result.tone;
|
|
28
|
+
const length = (tone.lengthMin ?? tone.lengthMax)
|
|
29
|
+
? `(建议 ${tone.lengthMin ?? "?"}-${tone.lengthMax ?? "?"} 字)`
|
|
30
|
+
: "";
|
|
31
|
+
console.log(`账号 ${result.account} 的写作调性:${tone.name}${length}`);
|
|
32
|
+
console.log(`\n【主笔人设】\n${tone.persona}`);
|
|
33
|
+
console.log(`\n【结构规则】\n${tone.styleRules}`);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=tone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tone.js","sourceRoot":"","sources":["../../src/commands/tone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAO7C,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;YACE,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACf,CAAC,CAAC;oBACE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;oBACtB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO;oBAC5B,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU;oBACnC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI;oBACzC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI;iBAC1C;gBACH,CAAC,CAAC,IAAI;SACT,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;QACF,OAAO;IACT,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,+BAA+B,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,MAAM,GACV,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QAChC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,GAAG,KAAK;QAC5D,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 设备授权流(RFC 8628)登录:对接 auth 服务(AuthKeystone)。
|
|
3
|
+
*
|
|
4
|
+
* 链路:discovery(RFC 8414)发现端点 → POST 设备授权端点拿 device_code/user_code →
|
|
5
|
+
* 打印确认 URL(用户浏览器登录并批准)→ 轮询 token 端点直到 approved → JWT 存入配置。
|
|
6
|
+
* 全程零硬编码 URL(端点都来自 discovery),零密钥经手(浏览器侧完成登录)。
|
|
7
|
+
*/
|
|
8
|
+
/** auth 服务默认地址(issuer)。 */
|
|
9
|
+
export declare const DEFAULT_AUTH_ISSUER = "https://auth.ai-as.cc";
|
|
10
|
+
/** 设备流 grant 的 URN 形态(与 token 端点 dispatch 匹配)。 */
|
|
11
|
+
export declare const DEVICE_GRANT_URN = "urn:ietf:params:oauth:grant-type:device_code";
|
|
12
|
+
/** 设备流专用公开 client(auth 侧注册:public + device_code grant)。 */
|
|
13
|
+
export declare const DEVICE_CLIENT_ID = "wxpub-cli";
|
|
14
|
+
/** 请求的 scope:auth:permissions 让 token 带权限标识(服务端 introspect 实时回填)。 */
|
|
15
|
+
export declare const DEVICE_SCOPE = "openid profile auth:permissions";
|
|
16
|
+
/**
|
|
17
|
+
* RFC 8693 audience:wechat-publish 只收 aud=自己 client_id 的 delegation 委托票,
|
|
18
|
+
* 设备流带 audience 发起 → 批准后直接签出委托票(无需机密 client 的 token exchange)。
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEVICE_AUDIENCE = "client_wechat";
|
|
21
|
+
export interface DeviceEndpoints {
|
|
22
|
+
deviceAuthorizationEndpoint: string;
|
|
23
|
+
tokenEndpoint: string;
|
|
24
|
+
}
|
|
25
|
+
export interface DeviceAuthorization {
|
|
26
|
+
deviceCode: string;
|
|
27
|
+
userCode: string;
|
|
28
|
+
verificationUri: string;
|
|
29
|
+
verificationUriComplete: string;
|
|
30
|
+
/** 秒 */
|
|
31
|
+
expiresIn: number;
|
|
32
|
+
/** 轮询间隔(秒) */
|
|
33
|
+
interval: number;
|
|
34
|
+
}
|
|
35
|
+
/** 设备流失败(RFC 8628 §3.5 错误码),terminal 错误抛出终止轮询。 */
|
|
36
|
+
export declare class DeviceFlowError extends Error {
|
|
37
|
+
readonly code: string;
|
|
38
|
+
constructor(code: string, message: string);
|
|
39
|
+
}
|
|
40
|
+
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
41
|
+
type SleepLike = (ms: number) => Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* RFC 8414 发现:拉 AS metadata,校验支持设备流,返回两端点。
|
|
44
|
+
* 不支持时给出可行动的错误(而不是让后续请求莫名 400)。
|
|
45
|
+
*/
|
|
46
|
+
export declare function discoverDeviceEndpoints(issuer: string, fetchImpl?: FetchLike): Promise<DeviceEndpoints>;
|
|
47
|
+
/** 发起设备授权:拿 device_code + user_code + 确认 URL。audience 非空时批准后签委托票。 */
|
|
48
|
+
export declare function requestDeviceAuthorization(endpoint: string, clientId?: string, fetchImpl?: FetchLike, audience?: string): Promise<DeviceAuthorization>;
|
|
49
|
+
/**
|
|
50
|
+
* 轮询 token 端点直到批准/失败/过期。
|
|
51
|
+
* authorization_pending → 继续等;slow_down → 间隔 +5s;其余错误(access_denied /
|
|
52
|
+
* expired_token / invalid_grant…)终止抛出;成功返回 token 响应。
|
|
53
|
+
*/
|
|
54
|
+
export declare function pollDeviceToken(options: {
|
|
55
|
+
tokenEndpoint: string;
|
|
56
|
+
clientId: string;
|
|
57
|
+
deviceCode: string;
|
|
58
|
+
intervalSecs: number;
|
|
59
|
+
fetchImpl?: FetchLike;
|
|
60
|
+
/** 测试注入:无则真 sleep */
|
|
61
|
+
sleepImpl?: SleepLike;
|
|
62
|
+
}): Promise<{
|
|
63
|
+
accessToken: string;
|
|
64
|
+
refreshToken?: string;
|
|
65
|
+
}>;
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 设备授权流(RFC 8628)登录:对接 auth 服务(AuthKeystone)。
|
|
3
|
+
*
|
|
4
|
+
* 链路:discovery(RFC 8414)发现端点 → POST 设备授权端点拿 device_code/user_code →
|
|
5
|
+
* 打印确认 URL(用户浏览器登录并批准)→ 轮询 token 端点直到 approved → JWT 存入配置。
|
|
6
|
+
* 全程零硬编码 URL(端点都来自 discovery),零密钥经手(浏览器侧完成登录)。
|
|
7
|
+
*/
|
|
8
|
+
/** auth 服务默认地址(issuer)。 */
|
|
9
|
+
export const DEFAULT_AUTH_ISSUER = "https://auth.ai-as.cc";
|
|
10
|
+
/** 设备流 grant 的 URN 形态(与 token 端点 dispatch 匹配)。 */
|
|
11
|
+
export const DEVICE_GRANT_URN = "urn:ietf:params:oauth:grant-type:device_code";
|
|
12
|
+
/** 设备流专用公开 client(auth 侧注册:public + device_code grant)。 */
|
|
13
|
+
export const DEVICE_CLIENT_ID = "wxpub-cli";
|
|
14
|
+
/** 请求的 scope:auth:permissions 让 token 带权限标识(服务端 introspect 实时回填)。 */
|
|
15
|
+
export const DEVICE_SCOPE = "openid profile auth:permissions";
|
|
16
|
+
/**
|
|
17
|
+
* RFC 8693 audience:wechat-publish 只收 aud=自己 client_id 的 delegation 委托票,
|
|
18
|
+
* 设备流带 audience 发起 → 批准后直接签出委托票(无需机密 client 的 token exchange)。
|
|
19
|
+
*/
|
|
20
|
+
export const DEVICE_AUDIENCE = "client_wechat";
|
|
21
|
+
/** 设备流失败(RFC 8628 §3.5 错误码),terminal 错误抛出终止轮询。 */
|
|
22
|
+
export class DeviceFlowError extends Error {
|
|
23
|
+
code;
|
|
24
|
+
constructor(code, message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "DeviceFlowError";
|
|
27
|
+
this.code = code;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
31
|
+
/**
|
|
32
|
+
* RFC 8414 发现:拉 AS metadata,校验支持设备流,返回两端点。
|
|
33
|
+
* 不支持时给出可行动的错误(而不是让后续请求莫名 400)。
|
|
34
|
+
*/
|
|
35
|
+
export async function discoverDeviceEndpoints(issuer, fetchImpl = fetch) {
|
|
36
|
+
const base = issuer.replace(/\/+$/, "");
|
|
37
|
+
const resp = await fetchImpl(`${base}/.well-known/oauth-authorization-server`);
|
|
38
|
+
if (!resp.ok) {
|
|
39
|
+
throw new DeviceFlowError("discovery_failed", `发现文档请求失败:HTTP ${resp.status}`);
|
|
40
|
+
}
|
|
41
|
+
const meta = (await resp.json());
|
|
42
|
+
if (!meta.device_authorization_endpoint || !meta.token_endpoint) {
|
|
43
|
+
throw new DeviceFlowError("discovery_incomplete", "发现文档缺少 device_authorization_endpoint / token_endpoint");
|
|
44
|
+
}
|
|
45
|
+
if (!(meta.grant_types_supported ?? []).includes(DEVICE_GRANT_URN)) {
|
|
46
|
+
throw new DeviceFlowError("unsupported_grant_type", `该授权服务器不支持设备流(${DEVICE_GRANT_URN})`);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
deviceAuthorizationEndpoint: meta.device_authorization_endpoint,
|
|
50
|
+
tokenEndpoint: meta.token_endpoint,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** 发起设备授权:拿 device_code + user_code + 确认 URL。audience 非空时批准后签委托票。 */
|
|
54
|
+
export async function requestDeviceAuthorization(endpoint, clientId = DEVICE_CLIENT_ID, fetchImpl = fetch, audience = DEVICE_AUDIENCE) {
|
|
55
|
+
const body = new URLSearchParams({
|
|
56
|
+
client_id: clientId,
|
|
57
|
+
scope: DEVICE_SCOPE,
|
|
58
|
+
audience,
|
|
59
|
+
});
|
|
60
|
+
const resp = await fetchImpl(endpoint, {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
63
|
+
body,
|
|
64
|
+
});
|
|
65
|
+
const data = (await resp.json().catch(() => ({})));
|
|
66
|
+
if (!resp.ok || typeof data.device_code !== "string" || typeof data.user_code !== "string") {
|
|
67
|
+
const desc = typeof data.error_description === "string" ? data.error_description : `HTTP ${resp.status}`;
|
|
68
|
+
throw new DeviceFlowError(typeof data.error === "string" ? data.error : "device_authorize_failed", `设备授权发起失败:${desc}`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
deviceCode: data.device_code,
|
|
72
|
+
userCode: data.user_code,
|
|
73
|
+
verificationUri: typeof data.verification_uri === "string" ? data.verification_uri : "",
|
|
74
|
+
verificationUriComplete: typeof data.verification_uri_complete === "string"
|
|
75
|
+
? data.verification_uri_complete
|
|
76
|
+
: typeof data.verification_uri === "string"
|
|
77
|
+
? data.verification_uri
|
|
78
|
+
: "",
|
|
79
|
+
expiresIn: typeof data.expires_in === "number" ? data.expires_in : 600,
|
|
80
|
+
interval: typeof data.interval === "number" ? data.interval : 5,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 轮询 token 端点直到批准/失败/过期。
|
|
85
|
+
* authorization_pending → 继续等;slow_down → 间隔 +5s;其余错误(access_denied /
|
|
86
|
+
* expired_token / invalid_grant…)终止抛出;成功返回 token 响应。
|
|
87
|
+
*/
|
|
88
|
+
export async function pollDeviceToken(options) {
|
|
89
|
+
const doSleep = options.sleepImpl ?? sleep;
|
|
90
|
+
let interval = options.intervalSecs;
|
|
91
|
+
// 上限 15 分钟(服务端 600s 过期会先返回 expired_token,这是兜底防呆循环)
|
|
92
|
+
const deadline = Date.now() + 15 * 60 * 1000;
|
|
93
|
+
for (;;) {
|
|
94
|
+
const body = new URLSearchParams({
|
|
95
|
+
grant_type: DEVICE_GRANT_URN,
|
|
96
|
+
device_code: options.deviceCode,
|
|
97
|
+
client_id: options.clientId,
|
|
98
|
+
});
|
|
99
|
+
const resp = await (options.fetchImpl ?? fetch)(options.tokenEndpoint, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
102
|
+
body,
|
|
103
|
+
});
|
|
104
|
+
const data = (await resp.json().catch(() => ({})));
|
|
105
|
+
if (resp.ok && typeof data.access_token === "string") {
|
|
106
|
+
return {
|
|
107
|
+
accessToken: data.access_token,
|
|
108
|
+
refreshToken: typeof data.refresh_token === "string" ? data.refresh_token : undefined,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const code = typeof data.error === "string" ? data.error : `http_${resp.status}`;
|
|
112
|
+
if (code === "authorization_pending") {
|
|
113
|
+
if (Date.now() > deadline) {
|
|
114
|
+
throw new DeviceFlowError("expired_token", "等待超时,设备码已过期");
|
|
115
|
+
}
|
|
116
|
+
await doSleep(interval * 1000);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (code === "slow_down") {
|
|
120
|
+
interval += 5;
|
|
121
|
+
await doSleep(interval * 1000);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const desc = typeof data.error_description === "string" ? data.error_description : "设备授权失败";
|
|
125
|
+
throw new DeviceFlowError(code, desc);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=device-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-auth.js","sourceRoot":"","sources":["../src/device-auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,13 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { WxpubApiError } from "./client.js";
|
|
5
5
|
import { runImage } from "./commands/image.js";
|
|
6
|
+
import { runIllustrate } from "./commands/illustrate.js";
|
|
6
7
|
import { runLogin } from "./commands/login.js";
|
|
7
8
|
import { runMaterials } from "./commands/materials.js";
|
|
8
9
|
import { runMe } from "./commands/me.js";
|
|
9
10
|
import { runPublish } from "./commands/publish.js";
|
|
10
11
|
import { runTheme } from "./commands/theme.js";
|
|
12
|
+
import { runTone } from "./commands/tone.js";
|
|
11
13
|
// 版本号单一真源 = package.json(发版只改那里,--version 永远同步)
|
|
12
14
|
const { version } = createRequire(import.meta.url)("../package.json");
|
|
13
15
|
const program = new Command();
|
|
@@ -18,11 +20,12 @@ program
|
|
|
18
20
|
.option("--json", "输出 JSON(供 coding agent / 程序消费)", false);
|
|
19
21
|
program
|
|
20
22
|
.command("login")
|
|
21
|
-
.description("
|
|
22
|
-
.
|
|
23
|
-
.
|
|
24
|
-
.
|
|
25
|
-
|
|
23
|
+
.description("登录(默认设备流:给个 URL 浏览器确认即得 JWT;也可 --api-key 贴密钥)")
|
|
24
|
+
.option("--base-url <url>", "发文服务地址(默认 https://yyps.net)")
|
|
25
|
+
.option("--api-key <key>", "手动通道:API Key(sk_…)或已有 JWT;不填则走设备流交互登录")
|
|
26
|
+
.option("--auth <issuer>", "auth 服务地址(默认 https://auth.ai-as.cc)")
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
await runLogin(options);
|
|
26
29
|
});
|
|
27
30
|
program
|
|
28
31
|
.command("me")
|
|
@@ -45,6 +48,23 @@ program
|
|
|
45
48
|
.action(async (options) => {
|
|
46
49
|
await runPublish({ ...options, json: program.opts().json });
|
|
47
50
|
});
|
|
51
|
+
program
|
|
52
|
+
.command("tone")
|
|
53
|
+
.description("拉账号绑定的写作调性(AI 写文前注入上下文,保证成稿跟号调性一致)")
|
|
54
|
+
.requiredOption("-a, --account <key>", "公众号账号 key")
|
|
55
|
+
.action(async (options) => {
|
|
56
|
+
await runTone({ ...options, json: program.opts().json });
|
|
57
|
+
});
|
|
58
|
+
program
|
|
59
|
+
.command("illustrate")
|
|
60
|
+
.description("AI 生成正文配图,输出可直接粘贴进 markdown 的插图片段(约 10-60 秒)")
|
|
61
|
+
.requiredOption("-a, --account <key>", "公众号账号 key")
|
|
62
|
+
.requiredOption("-f, --file <path>", "markdown 文件(取其全文作为配图依据)")
|
|
63
|
+
.option("-t, --title <title>", "文章标题(辅助 LLM 提炼画面)")
|
|
64
|
+
.option("--preset <id>", "配图模板 id(服务端 image_presets)", (value) => Number.parseInt(value, 10))
|
|
65
|
+
.action(async (options) => {
|
|
66
|
+
await runIllustrate({ ...options, json: program.opts().json });
|
|
67
|
+
});
|
|
48
68
|
program
|
|
49
69
|
.command("theme")
|
|
50
70
|
.description("查询账号默认主题")
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|