@cloud411716/fancy-webnovel 0.1.81 → 0.1.83
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/package.json
CHANGED
|
@@ -90,47 +90,112 @@ export async function apply(ctx) {
|
|
|
90
90
|
length = 'long';
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
{ timeout: 120000, stop: stopActivity }
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
if (!scriptResult.ok) {
|
|
104
|
-
const err = (typeof scriptResult.error === 'object' && scriptResult.error !== null)
|
|
105
|
-
? (scriptResult.error.message || JSON.stringify(scriptResult.error))
|
|
106
|
-
: String(scriptResult.error || '未知错误');
|
|
107
|
-
notify(session, scan.notify({ type: 'failed', err }));
|
|
93
|
+
// 执行采集,包含 Chromium 缺失处理
|
|
94
|
+
const scanResult = await runScanWithChromiumFix(ctx, session, invocation, {
|
|
95
|
+
platform, length, projectRoot,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (scanResult === 'retry') {
|
|
99
|
+
// Chromium 安装后重试已完成,runScanWithChromiumFix 已处理所有输出
|
|
108
100
|
return { kind: 'success', text: '' };
|
|
109
101
|
}
|
|
110
|
-
|
|
111
|
-
// 解析 receipt
|
|
112
|
-
let receipt;
|
|
113
|
-
try { receipt = JSON.parse(scriptResult.output); } catch (_) {
|
|
114
|
-
notify(session, scan.notify({ type: 'parse_error' }));
|
|
102
|
+
if (!scanResult) {
|
|
115
103
|
return { kind: 'success', text: '' };
|
|
116
104
|
}
|
|
117
105
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
notify(session, scan.notify({ type: 'handover', platform, length, files, topicFile, projectRoot }));
|
|
106
|
+
return { kind: 'success', text: '' };
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
123
110
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
111
|
+
/**
|
|
112
|
+
* 执行采集,检测 Chromium 缺失并弹框处理。
|
|
113
|
+
* 返回 undefined 表示已处理完毕(取消/失败),返回 'retry' 表示安装后重试完成。
|
|
114
|
+
*/
|
|
115
|
+
async function runScanWithChromiumFix(ctx, session, invocation, { platform, length, projectRoot }) {
|
|
116
|
+
const { spawn } = await import('child_process');
|
|
117
|
+
|
|
118
|
+
const runOnce = async (isRetry = false) => {
|
|
119
|
+
const stop = startActivity(session);
|
|
120
|
+
if (isRetry) notify(session, '⏳ 重新采集...\n');
|
|
121
|
+
const r = await spawnScript(
|
|
122
|
+
'node',
|
|
123
|
+
[join(SCAN_SCRIPTS_DIR, 'run-scan.js'),
|
|
124
|
+
'--project-root', projectRoot, '--platform', platform, '--length', length],
|
|
125
|
+
{ timeout: 120000, stop }
|
|
126
|
+
);
|
|
127
|
+
return r;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const handleSuccess = (stdout) => {
|
|
131
|
+
let receipt;
|
|
132
|
+
try { receipt = JSON.parse(stdout); } catch (_) {
|
|
133
|
+
notify(session, scan.notify({ type: 'parse_error' }));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const files = receipt.scan_files || [];
|
|
137
|
+
const topicFile = receipt.topic_decision || '';
|
|
138
|
+
notify(session, scan.notify({ type: 'handover', platform, length, files, topicFile, projectRoot }));
|
|
139
|
+
const prompt = scan.llmAnalysisPrompt({ platform, length, date: receipt.date || '', files, topicFile, projectRoot });
|
|
140
|
+
llmFollowup(invocation, prompt);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const scriptResult = await runOnce();
|
|
144
|
+
|
|
145
|
+
if (!scriptResult.ok) {
|
|
146
|
+
const rawErr = (typeof scriptResult.error === 'object' && scriptResult.error !== null)
|
|
147
|
+
? (scriptResult.error.message || JSON.stringify(scriptResult.error))
|
|
148
|
+
: String(scriptResult.error || '未知错误');
|
|
149
|
+
|
|
150
|
+
// Chromium 未找到 → 弹框让用户选择
|
|
151
|
+
if (rawErr.includes("Executable doesn't exist") || rawErr.includes('Executable doesn')) {
|
|
152
|
+
const choice = await ctx.userQuestions.ask({
|
|
153
|
+
questions: [scan.askChromiumInstall()],
|
|
130
154
|
});
|
|
131
|
-
|
|
155
|
+
const answer = choice.answers[0]?.selected?.[0] ?? choice.answers[0]?.custom;
|
|
156
|
+
if (!answer || answer === '我自己安装') {
|
|
157
|
+
notify(session, '⚠️ 已取消。请手动安装 Chromium 后再次运行 /fancy-scan。\n安装命令:npx playwright install chromium');
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
132
160
|
|
|
133
|
-
|
|
161
|
+
// 用户选择自动安装
|
|
162
|
+
notify(session, '⏳ 正在下载 Chromium 浏览器(首次约 2-3 分钟),请耐心等待...\n');
|
|
163
|
+
const installStop = startActivity(session);
|
|
164
|
+
|
|
165
|
+
const installProc = spawn('npx', ['playwright', 'install', 'chromium', '--registry', 'https://registry.npmmirror.com'], {
|
|
166
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
167
|
+
});
|
|
168
|
+
const installOut = [];
|
|
169
|
+
installProc.stdout.on('data', d => { installOut.push(d.toString()); });
|
|
170
|
+
installProc.stderr.on('data', d => { installOut.push(d.toString()); });
|
|
171
|
+
|
|
172
|
+
return new Promise((resolve) => {
|
|
173
|
+
installProc.on('close', async (code) => {
|
|
174
|
+
installStop();
|
|
175
|
+
if (code === 0) {
|
|
176
|
+
notify(session, '✅ Chromium 安装完成,正在重新采集...\n');
|
|
177
|
+
const retryResult = await runOnce(true);
|
|
178
|
+
if (!retryResult.ok) {
|
|
179
|
+
const err2 = String(retryResult.error || '未知错误');
|
|
180
|
+
notify(session, scan.notify({ type: 'failed', err: err2 }));
|
|
181
|
+
resolve(undefined);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
handleSuccess(retryResult.output);
|
|
185
|
+
resolve('retry');
|
|
186
|
+
} else {
|
|
187
|
+
const out = installOut.join('').slice(-300);
|
|
188
|
+
notify(session, `❌ Chromium 安装失败(exit ${code})。\n请手动运行以下命令后重试:\n npx playwright install chromium\n\n安装日志末尾:\n${out}`);
|
|
189
|
+
resolve(undefined);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
134
193
|
}
|
|
135
|
-
|
|
194
|
+
|
|
195
|
+
notify(session, scan.notify({ type: 'failed', err: rawErr }));
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
handleSuccess(scriptResult.output);
|
|
200
|
+
return 'retry';
|
|
136
201
|
}
|
|
@@ -49,6 +49,17 @@ export const scan = {
|
|
|
49
49
|
};
|
|
50
50
|
},
|
|
51
51
|
|
|
52
|
+
askChromiumInstall() {
|
|
53
|
+
return {
|
|
54
|
+
question: '⚠️ 未检测到 Chromium 浏览器,请选择处理方式:',
|
|
55
|
+
hideCustomInput: true,
|
|
56
|
+
options: [
|
|
57
|
+
{ label: '自动安装', description: '下载 Chromium 到 ~/.cache/ms-playwright/(需要网络,首次约 2-3 分钟)' },
|
|
58
|
+
{ label: '我自己安装', description: '手动安装后再次运行 /fancy-scan' },
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
|
|
52
63
|
notify({ type, platform, length, files, receipt, topicFile, projectRoot, err }) {
|
|
53
64
|
const lenStr = length === 'long' ? '长篇' : '短篇';
|
|
54
65
|
const pLabel = platformLabel(platform);
|