@gobing-ai/knowledge-kit 0.0.26 → 0.0.28
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/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/plugins/generations/dailynews-gen/dist/index.js +15 -12
- package/plugins/generations/dailynews-gen/src/script-builder.ts +18 -9
- package/plugins/generations/episode-plan-gen/dist/index.js +7 -0
- package/plugins/generations/episode-plan-gen/src/index.ts +12 -0
- package/plugins/generations/image-gen/dist/index.js +6 -1
- package/plugins/generations/image-gen/src/providers/google.ts +9 -1
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/kk-workflow-stages.ts +77 -3
- package/plugins/kk/workflows/kk-daily-ai-voice.yaml +19 -7
- package/plugins/publishings/wechatmp-pub/dist/index.js +272 -115
- package/plugins/publishings/wechatmp-pub/package.json +2 -1
- package/plugins/publishings/wechatmp-pub/src/index.ts +336 -40
- package/plugins/publishings/wechatmp-pub/src/profile-check.ts +21 -9
- package/plugins/publishings/xhs-pub/dist/index.js +28 -22
- package/plugins/publishings/xhs-pub/package.json +2 -1
- package/plugins/publishings/xhs-pub/src/index.ts +30 -22
|
@@ -29933,20 +29933,6 @@ class PlaywrightUnavailableError extends BrowserAutomationError {
|
|
|
29933
29933
|
this.name = "PlaywrightUnavailableError";
|
|
29934
29934
|
}
|
|
29935
29935
|
}
|
|
29936
|
-
|
|
29937
|
-
class LoginTimeoutError extends BrowserAutomationError {
|
|
29938
|
-
constructor(message) {
|
|
29939
|
-
super(message);
|
|
29940
|
-
this.name = "LoginTimeoutError";
|
|
29941
|
-
}
|
|
29942
|
-
}
|
|
29943
|
-
|
|
29944
|
-
class OperationAbortedError extends BrowserAutomationError {
|
|
29945
|
-
constructor(message = "Browser automation operation was cancelled via AbortSignal.") {
|
|
29946
|
-
super(message);
|
|
29947
|
-
this.name = "OperationAbortedError";
|
|
29948
|
-
}
|
|
29949
|
-
}
|
|
29950
29936
|
// ../../node_modules/.bun/@gobing-ai+ts-browser-automation@0.5.11+e28deaf1f2c5a2b1/node_modules/@gobing-ai/ts-browser-automation/dist/launcher.js
|
|
29951
29937
|
import { mkdir } from "fs/promises";
|
|
29952
29938
|
|
|
@@ -30014,83 +30000,17 @@ function createPersistentLauncher(options = {}) {
|
|
|
30014
30000
|
}
|
|
30015
30001
|
|
|
30016
30002
|
// ../../node_modules/.bun/@gobing-ai+ts-browser-automation@0.5.11+e28deaf1f2c5a2b1/node_modules/@gobing-ai/ts-browser-automation/dist/operations.js
|
|
30017
|
-
var DEFAULT_TIMEOUT_MS = 30000;
|
|
30018
|
-
var POLL_INTERVAL_MS = 250;
|
|
30019
30003
|
var defaultLauncher;
|
|
30020
30004
|
function getDefaultLauncher() {
|
|
30021
30005
|
if (defaultLauncher === undefined)
|
|
30022
30006
|
defaultLauncher = createPersistentLauncher();
|
|
30023
30007
|
return defaultLauncher;
|
|
30024
30008
|
}
|
|
30025
|
-
async function
|
|
30026
|
-
|
|
30027
|
-
if (options.isAuthenticated !== undefined)
|
|
30028
|
-
assertFiniteTimeoutMs(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
30029
|
-
const context2 = await (options.launcher ?? getDefaultLauncher()).launch({
|
|
30009
|
+
async function openPersistentBrowser(options) {
|
|
30010
|
+
return (options.launcher ?? getDefaultLauncher()).launch({
|
|
30030
30011
|
profileDir: resolveProfileDir(options.profileDir),
|
|
30031
|
-
headless: options.headless
|
|
30012
|
+
headless: options.headless
|
|
30032
30013
|
});
|
|
30033
|
-
try {
|
|
30034
|
-
const page = await openPage(context2);
|
|
30035
|
-
if (options.url !== undefined)
|
|
30036
|
-
await page.goto(options.url);
|
|
30037
|
-
if (options.isAuthenticated !== undefined) {
|
|
30038
|
-
await pollPredicate(page, options.isAuthenticated, options.timeoutMs ?? DEFAULT_TIMEOUT_MS, options.signal);
|
|
30039
|
-
}
|
|
30040
|
-
return await callback({ context: context2, page });
|
|
30041
|
-
} finally {
|
|
30042
|
-
await context2.close();
|
|
30043
|
-
}
|
|
30044
|
-
}
|
|
30045
|
-
function assertNotAborted(signal) {
|
|
30046
|
-
if (signal?.aborted)
|
|
30047
|
-
throw new OperationAbortedError;
|
|
30048
|
-
}
|
|
30049
|
-
async function openPage(context2) {
|
|
30050
|
-
const existing = context2.pages()[0];
|
|
30051
|
-
return existing ?? await context2.newPage();
|
|
30052
|
-
}
|
|
30053
|
-
function assertFiniteTimeoutMs(timeoutMs) {
|
|
30054
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
30055
|
-
throw new TypeError(`timeoutMs must be a finite non-negative number of milliseconds; received ${timeoutMs}`);
|
|
30056
|
-
}
|
|
30057
|
-
}
|
|
30058
|
-
async function pollPredicate(page, predicate, timeoutMs, signal) {
|
|
30059
|
-
const timeoutError = new LoginTimeoutError(`Authentication was not confirmed within ${timeoutMs}ms. The profile's site session has likely ` + "expired or the sign-in was not completed: re-run loginWithProfile() with the same profileDir to sign in again.");
|
|
30060
|
-
let timer;
|
|
30061
|
-
let onAbort;
|
|
30062
|
-
let stopped = false;
|
|
30063
|
-
const deadline = new Promise((_, reject) => {
|
|
30064
|
-
timer = setTimeout(() => reject(timeoutError), timeoutMs);
|
|
30065
|
-
if (signal) {
|
|
30066
|
-
onAbort = () => reject(new OperationAbortedError);
|
|
30067
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
30068
|
-
if (signal.aborted)
|
|
30069
|
-
onAbort();
|
|
30070
|
-
}
|
|
30071
|
-
});
|
|
30072
|
-
const poll = async () => {
|
|
30073
|
-
for (;; ) {
|
|
30074
|
-
if (stopped)
|
|
30075
|
-
return;
|
|
30076
|
-
assertNotAborted(signal);
|
|
30077
|
-
if (await predicate(page))
|
|
30078
|
-
return;
|
|
30079
|
-
await sleep(POLL_INTERVAL_MS);
|
|
30080
|
-
}
|
|
30081
|
-
};
|
|
30082
|
-
try {
|
|
30083
|
-
await Promise.race([poll(), deadline]);
|
|
30084
|
-
} finally {
|
|
30085
|
-
stopped = true;
|
|
30086
|
-
if (timer)
|
|
30087
|
-
clearTimeout(timer);
|
|
30088
|
-
if (signal && onAbort)
|
|
30089
|
-
signal.removeEventListener("abort", onAbort);
|
|
30090
|
-
}
|
|
30091
|
-
}
|
|
30092
|
-
function sleep(ms) {
|
|
30093
|
-
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
30094
30014
|
}
|
|
30095
30015
|
// ../../plugins/publishings/wechatmp-pub/src/index.ts
|
|
30096
30016
|
init_dist();
|
|
@@ -30099,11 +30019,16 @@ var CONSOLE_URL = "https://mp.weixin.qq.com/";
|
|
|
30099
30019
|
var SEL = {
|
|
30100
30020
|
loggedInFragment: "/cgi-bin/home",
|
|
30101
30021
|
menuItem: ".new-creation__menu .new-creation__menu-item",
|
|
30102
|
-
titleInput: "
|
|
30022
|
+
titleInput: '.ProseMirror[data-placeholder*="\u6807\u9898"]',
|
|
30103
30023
|
authorInput: "#author",
|
|
30104
|
-
editor: ".ProseMirror",
|
|
30024
|
+
editor: ".ProseMirror:not([data-placeholder])",
|
|
30105
30025
|
summaryInput: "#js_description",
|
|
30106
|
-
saveDraftBtn: '
|
|
30026
|
+
saveDraftBtn: 'button:has-text("\u4FDD\u5B58\u4E3A\u8349\u7A3F")',
|
|
30027
|
+
originalSwitch: ".setting-group__switch.js_edit_ori",
|
|
30028
|
+
tagRow: ".allow_click_opr.js_article_tags_label",
|
|
30029
|
+
tagInput: 'input[placeholder*="\u5408\u96C6"]',
|
|
30030
|
+
claimSourceCheckbox: "#js_claim_source_area .frm_checkbox_label",
|
|
30031
|
+
coverBtn: ".js_cover_btn_area",
|
|
30107
30032
|
publishBtn: '.js_publish, button:has-text("\u53D1\u8868"), button:has-text("\u53D1\u5E03")',
|
|
30108
30033
|
confirmBtn: '.weui-desktop-dialog .weui-desktop-btn_primary, button:has-text("\u786E\u5B9A")',
|
|
30109
30034
|
toast: ".weui-desktop-toast"
|
|
@@ -30202,23 +30127,34 @@ function resolveDigest(content) {
|
|
|
30202
30127
|
function isWechatLoggedIn(page) {
|
|
30203
30128
|
return page.url().includes(SEL.loggedInFragment);
|
|
30204
30129
|
}
|
|
30130
|
+
function storageStatePath(profileDir) {
|
|
30131
|
+
return `${profileDir}/storage-state.json`;
|
|
30132
|
+
}
|
|
30205
30133
|
async function checkWechatSession(profileDir) {
|
|
30206
|
-
await
|
|
30207
|
-
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30134
|
+
const { page, context: context2 } = await openWithState(profileDir, true);
|
|
30135
|
+
try {
|
|
30136
|
+
await pollLogin(page);
|
|
30137
|
+
} finally {
|
|
30138
|
+
await context2.close();
|
|
30139
|
+
}
|
|
30140
|
+
}
|
|
30141
|
+
async function pollLogin(page) {
|
|
30142
|
+
const deadline = Date.now() + CONSOLE_READY_TIMEOUT_MS;
|
|
30143
|
+
while (!isWechatLoggedIn(page)) {
|
|
30144
|
+
if (Date.now() > deadline) {
|
|
30145
|
+
throw new Error(`Authentication was not confirmed within ${CONSOLE_READY_TIMEOUT_MS}ms \u2014 the saved session state has ` + "likely expired: re-run `bun src/profile-check.ts login` to sign in again.");
|
|
30146
|
+
}
|
|
30147
|
+
await new Promise((resolve2) => setTimeout(resolve2, 1000));
|
|
30148
|
+
}
|
|
30149
|
+
}
|
|
30150
|
+
function wrapPlaywrightPage(page, context2) {
|
|
30215
30151
|
return {
|
|
30216
30152
|
goto: (url2) => page.goto(url2, { waitUntil: "domcontentloaded" }).then(() => {
|
|
30217
30153
|
return;
|
|
30218
30154
|
}),
|
|
30219
30155
|
url: () => page.url(),
|
|
30220
30156
|
fill: (selector, value) => page.locator(selector).first().fill(value),
|
|
30221
|
-
click: (selector) => page.locator(selector).first().click(),
|
|
30157
|
+
click: (selector, timeoutMs) => page.locator(selector).first().click(timeoutMs ? { timeout: timeoutMs } : undefined),
|
|
30222
30158
|
setInnerHtml: (selector, html) => page.locator(selector).first().evaluate((node, value) => {
|
|
30223
30159
|
node.innerHTML = value;
|
|
30224
30160
|
node.dispatchEvent(new Event("input", { bubbles: true }));
|
|
@@ -30237,11 +30173,54 @@ function wrapPlaywrightPage(page) {
|
|
|
30237
30173
|
}
|
|
30238
30174
|
}
|
|
30239
30175
|
return "";
|
|
30176
|
+
},
|
|
30177
|
+
waitForUrlFragment: (fragment, timeoutMs) => page.waitForURL(new RegExp(fragment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")), { timeout: timeoutMs }).then(() => {
|
|
30178
|
+
return;
|
|
30179
|
+
}),
|
|
30180
|
+
setInputFiles: (selector, files) => page.locator(selector).first().setInputFiles(files),
|
|
30181
|
+
waitForTimeout: (ms) => page.waitForTimeout(ms),
|
|
30182
|
+
evalJs: (expression) => page.evaluate(expression),
|
|
30183
|
+
press: (key) => page.keyboard.press(key),
|
|
30184
|
+
clickAndAwaitNewPage: context2 ? async (selector) => {
|
|
30185
|
+
const popup = context2.waitForEvent("page", { timeout: 15000 }).catch(() => {
|
|
30186
|
+
return;
|
|
30187
|
+
});
|
|
30188
|
+
await page.locator(selector).first().click();
|
|
30189
|
+
const opened = await popup;
|
|
30190
|
+
if (!opened)
|
|
30191
|
+
return wrapPlaywrightPage(page, context2);
|
|
30192
|
+
await opened.waitForLoadState("domcontentloaded").catch(() => {});
|
|
30193
|
+
return wrapPlaywrightPage(opened, context2);
|
|
30194
|
+
} : undefined,
|
|
30195
|
+
close: context2 ? () => context2.close() : undefined
|
|
30196
|
+
};
|
|
30197
|
+
}
|
|
30198
|
+
async function openWithState(profileDir, headless) {
|
|
30199
|
+
const context2 = await openPersistentBrowser({ profileDir, headless });
|
|
30200
|
+
try {
|
|
30201
|
+
const stateFile = storageStatePath(profileDir);
|
|
30202
|
+
let state;
|
|
30203
|
+
try {
|
|
30204
|
+
state = JSON.parse(await createNodeFileSystem().readFile(stateFile));
|
|
30205
|
+
} catch {
|
|
30206
|
+
state = undefined;
|
|
30240
30207
|
}
|
|
30241
|
-
|
|
30208
|
+
const cookies = state?.cookies;
|
|
30209
|
+
if (!cookies || cookies.length === 0) {
|
|
30210
|
+
throw new BrowserProfileMissingError(`no saved console session state (${stateFile}) \u2014 run \`bun src/profile-check.ts login\` once`);
|
|
30211
|
+
}
|
|
30212
|
+
await context2.addCookies(cookies);
|
|
30213
|
+
const page = context2.pages()[0] ?? await context2.newPage();
|
|
30214
|
+
await page.goto(CONSOLE_URL);
|
|
30215
|
+
return { page, context: context2 };
|
|
30216
|
+
} catch (error51) {
|
|
30217
|
+
await context2.close();
|
|
30218
|
+
throw error51;
|
|
30219
|
+
}
|
|
30242
30220
|
}
|
|
30243
30221
|
async function defaultOpenPage(profileDir) {
|
|
30244
|
-
|
|
30222
|
+
const { page, context: context2 } = await openWithState(profileDir, true);
|
|
30223
|
+
return wrapPlaywrightPage(page, context2);
|
|
30245
30224
|
}
|
|
30246
30225
|
|
|
30247
30226
|
class WechatmpBrowserTransport {
|
|
@@ -30270,38 +30249,215 @@ class WechatmpBrowserTransport {
|
|
|
30270
30249
|
return this.failed(`wechatmp-pub: ${why}`);
|
|
30271
30250
|
}
|
|
30272
30251
|
const page = await this.openPage(profileDir);
|
|
30252
|
+
let enrichWarnings = [];
|
|
30273
30253
|
try {
|
|
30274
30254
|
await page.waitFor(SEL.menuItem, CONSOLE_READY_TIMEOUT_MS);
|
|
30275
|
-
await page.
|
|
30276
|
-
|
|
30277
|
-
|
|
30278
|
-
|
|
30279
|
-
await
|
|
30280
|
-
await
|
|
30255
|
+
const editor = page.clickAndAwaitNewPage ? await page.clickAndAwaitNewPage(`${SEL.menuItem}:has-text("\u56FE\u6587"), ${SEL.menuItem}`) : page;
|
|
30256
|
+
if (editor === page) {
|
|
30257
|
+
await page.click(`${SEL.menuItem}:has-text("\u56FE\u6587"), ${SEL.menuItem}`);
|
|
30258
|
+
}
|
|
30259
|
+
await editor.waitFor(SEL.titleInput, CONSOLE_READY_TIMEOUT_MS);
|
|
30260
|
+
await editor.fill(SEL.titleInput, title);
|
|
30261
|
+
await this.tryFill(editor, SEL.authorInput, String(content.metadata?.author ?? ""));
|
|
30262
|
+
await editor.waitFor(SEL.editor, CONSOLE_READY_TIMEOUT_MS);
|
|
30263
|
+
await editor.setInnerHtml(SEL.editor, markdownToWechatHtml(content.body));
|
|
30281
30264
|
const digest = resolveDigest(content);
|
|
30282
30265
|
if (digest)
|
|
30283
|
-
await this.tryFill(
|
|
30266
|
+
await this.tryFill(editor, SEL.summaryInput, digest);
|
|
30267
|
+
const enrichMeta = content.metadata?.wechatmp;
|
|
30268
|
+
if (enrichMeta && typeof enrichMeta === "object" && !Array.isArray(enrichMeta)) {
|
|
30269
|
+
enrichWarnings = await this.enrichDraft(editor, enrichMeta);
|
|
30270
|
+
const audioTitle = enrichMeta.audioTitle;
|
|
30271
|
+
if (typeof audioTitle === "string" && audioTitle.trim() !== "") {
|
|
30272
|
+
const audioWarn = await this.insertAudio(editor, audioTitle.trim());
|
|
30273
|
+
if (audioWarn !== "")
|
|
30274
|
+
enrichWarnings.push(audioWarn);
|
|
30275
|
+
}
|
|
30276
|
+
}
|
|
30284
30277
|
if (want === "draft") {
|
|
30285
|
-
await
|
|
30278
|
+
await editor.click(SEL.saveDraftBtn);
|
|
30286
30279
|
} else {
|
|
30287
|
-
await
|
|
30288
|
-
await this.tryClick(
|
|
30280
|
+
await editor.click(SEL.publishBtn);
|
|
30281
|
+
await this.tryClick(editor, SEL.confirmBtn);
|
|
30289
30282
|
}
|
|
30290
|
-
|
|
30291
|
-
|
|
30292
|
-
|
|
30283
|
+
if (editor.waitForUrlFragment) {
|
|
30284
|
+
await editor.waitForUrlFragment("appmsg_edit&action=edit", CONSOLE_READY_TIMEOUT_MS);
|
|
30285
|
+
} else {
|
|
30286
|
+
const seen = await editor.waitForAny([SEL.toast], TOAST_TIMEOUT_MS);
|
|
30287
|
+
if (seen === "") {
|
|
30288
|
+
return this.failed(`save was clicked but no confirmation toast appeared within ${TOAST_TIMEOUT_MS}ms \u2014 verify the console manually`);
|
|
30289
|
+
}
|
|
30293
30290
|
}
|
|
30291
|
+
const appmsgid = /appmsgid=(\d+)/.exec(editor.url())?.[1] ?? "";
|
|
30294
30292
|
return {
|
|
30295
30293
|
ok: true,
|
|
30296
30294
|
target: TARGET,
|
|
30297
30295
|
metadata: {
|
|
30298
30296
|
publishStatus: want,
|
|
30299
|
-
note: want === "draft" ?
|
|
30297
|
+
note: want === "draft" ? `saved to the WeChat MP draft box (\u8349\u7A3F\u7BB1)${appmsgid ? ` as appmsgid ${appmsgid}` : ""}` : "published via the console \u53D1\u8868 flow",
|
|
30298
|
+
...enrichWarnings.length > 0 ? { enrichWarnings } : {}
|
|
30300
30299
|
}
|
|
30301
30300
|
};
|
|
30302
30301
|
} catch (error51) {
|
|
30303
30302
|
const why = error51 instanceof Error ? error51.message : String(error51);
|
|
30304
|
-
|
|
30303
|
+
const enrich = enrichWarnings.length > 0 ? ` (enrich warnings: ${enrichWarnings.join(" | ")})` : "";
|
|
30304
|
+
return this.failed(`console flow failed: ${why}${enrich}`);
|
|
30305
|
+
} finally {
|
|
30306
|
+
await page.close?.();
|
|
30307
|
+
}
|
|
30308
|
+
}
|
|
30309
|
+
async enrichDraft(editor, meta3) {
|
|
30310
|
+
const DIALOG = ".weui-desktop-dialog:visible";
|
|
30311
|
+
const CONFIRM = `${DIALOG} button:has-text("\u786E\u8BA4"), ${DIALOG} button:has-text("\u786E\u5B9A")`;
|
|
30312
|
+
const warnings = [];
|
|
30313
|
+
const str = (key) => typeof meta3[key] === "string" ? meta3[key] : "";
|
|
30314
|
+
const on6 = (key) => meta3[key] === true;
|
|
30315
|
+
const sweep = async () => {
|
|
30316
|
+
await this.tryClick(editor, 'button:has-text("\u53D6\u6D88")', 2000);
|
|
30317
|
+
await editor.press?.("Escape");
|
|
30318
|
+
await editor.waitForTimeout?.(400);
|
|
30319
|
+
};
|
|
30320
|
+
const step = async (name, fn) => {
|
|
30321
|
+
try {
|
|
30322
|
+
await fn();
|
|
30323
|
+
return;
|
|
30324
|
+
} catch {}
|
|
30325
|
+
await sweep();
|
|
30326
|
+
await editor.waitForTimeout?.(1000);
|
|
30327
|
+
try {
|
|
30328
|
+
await fn();
|
|
30329
|
+
} catch (error51) {
|
|
30330
|
+
warnings.push(`${name}: ${(error51 instanceof Error ? error51.message : String(error51)).slice(0, 120)}`);
|
|
30331
|
+
await sweep();
|
|
30332
|
+
}
|
|
30333
|
+
};
|
|
30334
|
+
if (on6("original")) {
|
|
30335
|
+
await step("\u539F\u521B\u58F0\u660E", async () => {
|
|
30336
|
+
await editor.click(SEL.originalSwitch, 1e4);
|
|
30337
|
+
await editor.click(`${DIALOG} :text("\u6587\u5B57\u539F\u521B")`, 8000);
|
|
30338
|
+
const author = str("author");
|
|
30339
|
+
if (author)
|
|
30340
|
+
await this.tryFill(editor, `${DIALOG} input[placeholder*="\u4F5C\u8005"]`, author);
|
|
30341
|
+
await editor.click(CONFIRM, 8000);
|
|
30342
|
+
});
|
|
30343
|
+
const committed = await editor.evalJs?.(`[...document.querySelectorAll('.weui-desktop-dialog')].every((d) => !d.offsetWidth)`);
|
|
30344
|
+
if (committed === false) {
|
|
30345
|
+
warnings.push("\u539F\u521B\u58F0\u660E: \u672A\u751F\u6548 - \u4F5C\u8005\u987B\u4E3A\u8D5E\u8D4F\u8D26\u6237(\u641C\u7D22\u9009\u62E9)\uFF0C\u8BF7\u624B\u52A8\u8BBE\u7F6E");
|
|
30346
|
+
await sweep();
|
|
30347
|
+
}
|
|
30348
|
+
}
|
|
30349
|
+
const collection = str("collection");
|
|
30350
|
+
if (collection) {
|
|
30351
|
+
await step("\u5408\u96C6", async () => {
|
|
30352
|
+
await editor.click(SEL.tagRow, 8000);
|
|
30353
|
+
await editor.waitFor(SEL.tagInput, 8000);
|
|
30354
|
+
await editor.fill(SEL.tagInput, collection);
|
|
30355
|
+
await editor.waitForTimeout?.(1200);
|
|
30356
|
+
await editor.click(`${DIALOG} :text("${collection}")`, 8000);
|
|
30357
|
+
await editor.click(CONFIRM, 8000);
|
|
30358
|
+
});
|
|
30359
|
+
}
|
|
30360
|
+
if (on6("aiGenerated")) {
|
|
30361
|
+
await step("\u521B\u4F5C\u6765\u6E90", async () => {
|
|
30362
|
+
await editor.click(SEL.claimSourceCheckbox, 8000);
|
|
30363
|
+
const dialog = await editor.waitForAny([DIALOG], 3000);
|
|
30364
|
+
if (dialog) {
|
|
30365
|
+
await editor.click(`${DIALOG} :text("\u5185\u5BB9\u7531AI\u751F\u6210")`, 8000);
|
|
30366
|
+
await editor.click(CONFIRM, 8000);
|
|
30367
|
+
}
|
|
30368
|
+
});
|
|
30369
|
+
const checked = await editor.evalJs?.(`!!document.querySelector('#js_claim_source_area input:checked')`);
|
|
30370
|
+
if (checked === false)
|
|
30371
|
+
warnings.push("\u521B\u4F5C\u6765\u6E90: \u52FE\u9009\u672A\u751F\u6548\uFF0C\u8BF7\u624B\u52A8\u8BBE\u7F6E");
|
|
30372
|
+
}
|
|
30373
|
+
const coverPath = str("coverPath");
|
|
30374
|
+
const putFile = editor.setInputFiles?.bind(editor);
|
|
30375
|
+
if (coverPath && putFile) {
|
|
30376
|
+
await step("\u5C01\u9762", async () => {
|
|
30377
|
+
try {
|
|
30378
|
+
await putFile('input[type="file"]', coverPath);
|
|
30379
|
+
} catch {
|
|
30380
|
+
await editor.click(SEL.coverBtn, 8000);
|
|
30381
|
+
await editor.waitForTimeout?.(1500);
|
|
30382
|
+
await putFile('input[type="file"]', coverPath);
|
|
30383
|
+
}
|
|
30384
|
+
const cropBtn = await editor.waitForAny([`${DIALOG} button:has-text("\u5B8C\u6210")`, `${DIALOG} button:has-text("\u786E\u5B9A")`], 5000);
|
|
30385
|
+
if (cropBtn)
|
|
30386
|
+
await editor.click(cropBtn, 8000);
|
|
30387
|
+
});
|
|
30388
|
+
}
|
|
30389
|
+
await sweep();
|
|
30390
|
+
return warnings;
|
|
30391
|
+
}
|
|
30392
|
+
async insertAudio(editor, title) {
|
|
30393
|
+
const evalJs = editor.evalJs;
|
|
30394
|
+
if (typeof evalJs !== "function")
|
|
30395
|
+
return "";
|
|
30396
|
+
const CARET = `(() => {
|
|
30397
|
+
const pm = [...document.querySelectorAll('.ProseMirror')].find((e) => !(e.getAttribute('data-placeholder') ?? '').includes('\u6807\u9898'));
|
|
30398
|
+
if (!pm || !pm.firstChild) return;
|
|
30399
|
+
const r = document.createRange();
|
|
30400
|
+
r.setStart(pm.firstChild, 0);
|
|
30401
|
+
r.collapse(true);
|
|
30402
|
+
const sel = window.getSelection();
|
|
30403
|
+
sel?.removeAllRanges();
|
|
30404
|
+
sel?.addRange(r);
|
|
30405
|
+
})()`;
|
|
30406
|
+
const DEDUPE = `(() => {
|
|
30407
|
+
const want = ${JSON.stringify(title)}.replace(/\\s+/g, '');
|
|
30408
|
+
const hit = [...document.querySelectorAll('label.frm_checkbox_label.audio_item')]
|
|
30409
|
+
.find((l) => (l.textContent ?? '').replace(/\\s+/g, '').includes(want));
|
|
30410
|
+
if (!hit) return 'missing';
|
|
30411
|
+
const cb = (hit.closest('li') ?? hit.parentElement)?.querySelector('input[type=checkbox]');
|
|
30412
|
+
if (!cb) return 'nobox';
|
|
30413
|
+
cb.click();
|
|
30414
|
+
return 'checked';
|
|
30415
|
+
})()`;
|
|
30416
|
+
const INSERT = `(() => {
|
|
30417
|
+
const btn = [...document.querySelectorAll('button')].find((b) => (b.textContent ?? '').trim() === '\u63D2\u5165' && b.offsetWidth > 0);
|
|
30418
|
+
if (!btn) return false;
|
|
30419
|
+
btn.click();
|
|
30420
|
+
return true;
|
|
30421
|
+
})()`;
|
|
30422
|
+
const CANCEL = `(() => {
|
|
30423
|
+
const btn = [...document.querySelectorAll('button')].find((b) => (b.textContent ?? '').trim() === '\u53D6\u6D88' && b.offsetWidth > 0);
|
|
30424
|
+
btn?.click();
|
|
30425
|
+
})()`;
|
|
30426
|
+
const VERIFY = `(() => {
|
|
30427
|
+
const pm = [...document.querySelectorAll('.ProseMirror')].find((e) => !(e.getAttribute('data-placeholder') ?? '').includes('\u6807\u9898'));
|
|
30428
|
+
if (!pm) return 'noeditor';
|
|
30429
|
+
const node = pm.querySelector('mpvoice, [class*="audio"]');
|
|
30430
|
+
if (!node) return 'absent';
|
|
30431
|
+
const first = pm.firstElementChild;
|
|
30432
|
+
return first && (first === node || first.contains(node)) ? 'top' : 'notop';
|
|
30433
|
+
})()`;
|
|
30434
|
+
try {
|
|
30435
|
+
const run = (expression) => evalJs.call(editor, expression);
|
|
30436
|
+
await run(CARET);
|
|
30437
|
+
await run("document.querySelector('li.js_insertaudio')?.click()");
|
|
30438
|
+
await editor.waitFor(".audio_dialog", TOAST_TIMEOUT_MS);
|
|
30439
|
+
let dedupe = String(await run(DEDUPE));
|
|
30440
|
+
for (let i2 = 0;dedupe === "missing" && i2 < 2; i2++) {
|
|
30441
|
+
await editor.waitForTimeout?.(1200);
|
|
30442
|
+
dedupe = String(await run(DEDUPE));
|
|
30443
|
+
}
|
|
30444
|
+
if (dedupe !== "checked") {
|
|
30445
|
+
await run(CANCEL);
|
|
30446
|
+
return dedupe === "missing" ? "\u97F3\u9891: \u7D20\u6750\u5E93\u65E0\u540C\u540D\u97F3\u9891\uFF0C\u8BF7\u624B\u52A8\u4E0A\u4F20\u540E\u63D2\u5165" : "\u97F3\u9891: \u540C\u540D\u7D20\u6750\u884C\u672A\u627E\u5230\u52FE\u9009\u6846\uFF0C\u8BF7\u624B\u52A8\u63D2\u5165";
|
|
30447
|
+
}
|
|
30448
|
+
if (await run(INSERT) !== true) {
|
|
30449
|
+
await run(CANCEL);
|
|
30450
|
+
return "\u97F3\u9891: \u63D2\u5165\u6309\u94AE\u672A\u627E\u5230\uFF0C\u8BF7\u624B\u52A8\u63D2\u5165";
|
|
30451
|
+
}
|
|
30452
|
+
await editor.waitForTimeout?.(2000);
|
|
30453
|
+
const state = String(await run(VERIFY));
|
|
30454
|
+
if (state === "absent" || state === "noeditor")
|
|
30455
|
+
return "\u97F3\u9891: \u63D2\u5165\u672A\u751F\u6548\uFF0C\u8BF7\u624B\u52A8\u68C0\u67E5";
|
|
30456
|
+
if (state === "notop")
|
|
30457
|
+
return "\u97F3\u9891: \u5DF2\u63D2\u5165\u4F46\u672A\u5728\u6587\u9996\uFF0C\u8BF7\u624B\u52A8\u8C03\u6574\u4F4D\u7F6E";
|
|
30458
|
+
return "";
|
|
30459
|
+
} catch {
|
|
30460
|
+
return "\u97F3\u9891: \u81EA\u52A8\u63D2\u5165\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u63D2\u5165";
|
|
30305
30461
|
}
|
|
30306
30462
|
}
|
|
30307
30463
|
async tryFill(page, selector, value) {
|
|
@@ -30311,9 +30467,9 @@ class WechatmpBrowserTransport {
|
|
|
30311
30467
|
await page.fill(selector, value);
|
|
30312
30468
|
} catch {}
|
|
30313
30469
|
}
|
|
30314
|
-
async tryClick(page, selector) {
|
|
30470
|
+
async tryClick(page, selector, timeoutMs) {
|
|
30315
30471
|
try {
|
|
30316
|
-
await page.click(selector);
|
|
30472
|
+
await page.click(selector, timeoutMs);
|
|
30317
30473
|
} catch {}
|
|
30318
30474
|
}
|
|
30319
30475
|
failed(error51) {
|
|
@@ -30357,6 +30513,7 @@ if (import.meta.main) {
|
|
|
30357
30513
|
}
|
|
30358
30514
|
export {
|
|
30359
30515
|
wrapPlaywrightPage,
|
|
30516
|
+
storageStatePath,
|
|
30360
30517
|
processPublishIO,
|
|
30361
30518
|
markdownToWechatHtml,
|
|
30362
30519
|
main2 as main,
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"@gobing-ai/publish-harness": "workspace:*",
|
|
11
11
|
"@gobing-ai/ts-browser-automation": "catalog:",
|
|
12
12
|
"@gobing-ai/ts-runtime": "catalog:",
|
|
13
|
-
"@gobing-ai/ts-utils": "catalog:"
|
|
13
|
+
"@gobing-ai/ts-utils": "catalog:",
|
|
14
|
+
"playwright": "catalog:"
|
|
14
15
|
},
|
|
15
16
|
"devDependencies": {
|
|
16
17
|
"@types/bun": "1.3.14"
|