@gobing-ai/knowledge-kit 0.1.11 → 0.1.13
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/dist/index.js +2372 -1722
- package/package.json +1 -1
- package/plugins/generations/image-gen/README.md +108 -0
- package/plugins/generations/image-gen/assets/sample/cover__clean-webapp-ui.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__cute.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__daily-news.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__editorial.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__fresh.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__minimalist.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__photorealistic.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__sketch.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__technical-diagram.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__vibrant.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__warm.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/cover__xhs-knowledge.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__clean-webapp-ui.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__cute.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__daily-news.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__editorial.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__fresh.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__minimalist.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__photorealistic.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__sketch.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__technical-diagram.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__vibrant.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__warm.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/daily-news-cover__xhs-knowledge.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__clean-webapp-ui.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__cute.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__daily-news.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__editorial.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__fresh.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__minimalist.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__photorealistic.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__sketch.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__technical-diagram.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__vibrant.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__warm.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/free__xhs-knowledge.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__clean-webapp-ui.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__cute.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__daily-news.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__editorial.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__fresh.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__minimalist.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__photorealistic.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__sketch.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__technical-diagram.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__vibrant.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__warm.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/illustration__xhs-knowledge.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__clean-webapp-ui.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__cute.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__daily-news.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__editorial.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__fresh.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__minimalist.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__photorealistic.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__sketch.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__technical-diagram.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__vibrant.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__warm.jpg +0 -0
- package/plugins/generations/image-gen/assets/sample/xhs-card__xhs-knowledge.jpg +0 -0
- package/plugins/generations/image-gen/dist/index.js +102 -58
- package/plugins/generations/image-gen/scripts/compose-e2e-artifact.ts +5 -21
- package/plugins/generations/image-gen/scripts/gen-samples.ts +208 -0
- package/plugins/generations/image-gen/src/compose/chromium.ts +2 -3
- package/plugins/generations/image-gen/src/presets.ts +6 -3
- package/plugins/generations/image-gen/src/providers/errors.ts +16 -1
- package/plugins/generations/image-gen/src/providers/minimax.ts +46 -17
- package/plugins/ingestions/web-search/src/index.ts +1 -1
- package/plugins/kk/README.md +18 -0
- package/plugins/kk/commands/image-extract.md +1 -0
- package/plugins/kk/commands/image-generate.md +1 -0
- package/plugins/kk/commands/tell-me.md +1 -0
- package/plugins/kk/commands/workflow-run.md +7 -1
- package/plugins/kk/decisions/extract/it-topics.yaml +24 -0
- package/plugins/kk/decisions/kk-itc.yaml +6 -4
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/publish-presets/daily-ai-voice-migration.json +146 -0
- package/plugins/kk/publish-presets/daily-ai-voice.json +15 -7
- package/plugins/kk/schedules/kk-collect.grok-bot.md.tmpl +69 -0
- package/plugins/kk/schedules/kk-daily-ai-voice3.cron.tmpl +18 -0
- package/plugins/kk/schedules/kk-daily-publish3-cn-peak.cron.tmpl +15 -5
- package/plugins/kk/schedules/kk-daily-publish3-overseas.cron.tmpl +9 -4
- package/plugins/kk/scripts/daily-scheduled-run.ts +91 -41
- package/plugins/kk/scripts/daily-stages.ts +394 -53
- package/plugins/kk/scripts/kk-workflow-stages.ts +190 -0
- package/plugins/kk/scripts/safety-artifact-check.ts +70 -28
- package/plugins/kk/scripts/voice3-publish-window.ts +202 -0
- package/plugins/kk/skills/article-adapt/SKILL.md +1 -0
- package/plugins/kk/skills/audio-authoring/SKILL.md +1 -0
- package/plugins/kk/skills/content-judge/SKILL.md +1 -0
- package/plugins/kk/skills/content-safety/SKILL.md +1 -0
- package/plugins/kk/skills/content-safety/references/platforms/podcast-salty.md +41 -0
- package/plugins/kk/skills/content-safety/references/platforms/surfdash.md +36 -0
- package/plugins/kk/skills/content-safety/references/platforms/xhs.md +39 -0
- package/plugins/kk/skills/explain-things/SKILL.md +1 -0
- package/plugins/kk/skills/image-authoring/SKILL.md +1 -0
- package/plugins/kk/skills/itc-generating/SKILL.md +1 -0
- package/plugins/kk/skills/publish/SKILL.md +1 -0
- package/plugins/kk/skills/smart-seo/SKILL.md +1 -0
- package/plugins/kk/skills/storm-research/SKILL.md +1 -0
- package/plugins/kk/skills/taste-unslop/SKILL.md +1 -0
- package/plugins/kk/skills/topic/SKILL.md +1 -0
- package/plugins/kk/skills/web-automation/SKILL.md +1 -0
- package/plugins/kk/skills/xhs-images/SKILL.md +1 -0
- package/plugins/kk/workflows/kk-collect.yaml +3 -3
- package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +21 -19
- package/plugins/kk/workflows/kk-daily-ai-voice3.yaml +163 -63
- package/plugins/kk/workflows/kk-daily-publish3.yaml +82 -26
- package/plugins/kk/workflows/kk-daily-safety.yaml +39 -31
- package/plugins/kk/workflows/kk-itc-author.yaml +75 -0
- package/plugins/kk/workflows/kk-itc-publish-tail.yaml +25 -3
- package/plugins/kk/workflows/kk-itc.yaml +36 -4
- package/plugins/publishings/linkedin-pub/dist/index.js +21333 -0
- package/plugins/publishings/linkedin-pub/dist/profile-check.js +21005 -0
- package/plugins/publishings/linkedin-pub/package.json +19 -0
- package/plugins/publishings/linkedin-pub/plugin.json +12 -0
- package/plugins/publishings/linkedin-pub/src/index.ts +705 -0
- package/plugins/publishings/linkedin-pub/src/profile-check.ts +17 -0
- package/plugins/publishings/linkedin-pub/tsconfig.json +4 -0
- package/plugins/publishings/surfdash-pub/dist/index.js +53 -24
- package/plugins/publishings/surfdash-pub/src/index.ts +72 -25
- package/plugins/publishings/threads-pub/dist/index.js +7 -0
- package/plugins/publishings/threads-pub/src/index.ts +12 -0
- package/plugins/publishings/wechatmp-pub/dist/index.js +176 -32
- package/plugins/publishings/wechatmp-pub/src/flow.ts +298 -52
- package/plugins/publishings/weibo-pub/dist/index.js +100 -7
- package/plugins/publishings/weibo-pub/src/index.ts +111 -11
- package/plugins/publishings/x-pub/dist/index.js +7 -0
- package/plugins/publishings/x-pub/src/index.ts +11 -0
- package/plugins/publishings/xhs-pub/dist/index.js +164 -12
- package/plugins/publishings/xhs-pub/dist/profile-check.js +11 -1
- package/plugins/publishings/xhs-pub/src/flow.ts +194 -23
- package/plugins/publishings/xhs-pub/src/page.ts +26 -0
|
@@ -22533,6 +22533,11 @@ var TITLE_BLOCK = [
|
|
|
22533
22533
|
'div.ProseMirror[data-placeholder*="\u6807\u9898"]'
|
|
22534
22534
|
];
|
|
22535
22535
|
var TITLE_MIRROR = ["textarea#title", "textarea.js_title"];
|
|
22536
|
+
var PODCAST_TITLE = ["textarea.js_title"];
|
|
22537
|
+
var PODCAST_BODY = [
|
|
22538
|
+
"div.ProseMirror.ProseMirror-focused:not([data-placeholder])",
|
|
22539
|
+
"div.ProseMirror:not([data-placeholder])"
|
|
22540
|
+
];
|
|
22536
22541
|
var BODY_BLOCK = [
|
|
22537
22542
|
"div.ProseMirror.ProseMirror-focused:not([data-placeholder])",
|
|
22538
22543
|
"div.ProseMirror:not([data-placeholder])",
|
|
@@ -22626,17 +22631,19 @@ var VIDEO_FILE_INPUT = [
|
|
|
22626
22631
|
];
|
|
22627
22632
|
var VIDEO_CONFIRM = ['div.weui-desktop-dialog button:has-text("\u786E\u5B9A")', 'button:has-text("\u786E\u5B9A")'];
|
|
22628
22633
|
var PODCAST_UPLOAD = ["text=\u4E0A\u4F20\u97F3\u9891", 'button:has-text("\u4E0A\u4F20\u97F3\u9891")'];
|
|
22634
|
+
var PODCAST_ROW = (title) => `li.audio_item_wrp:has-text("${JSON.stringify(title).slice(1, -1)}"), div.audio_item_wrp:has-text("${JSON.stringify(title).slice(1, -1)}")`;
|
|
22629
22635
|
var PODCAST_AUDIO_INPUT = [
|
|
22636
|
+
"div.weui-desktop-dialog input.weui-desktop-upload-input",
|
|
22637
|
+
'div.weui-desktop-dialog input[name="audio_id"]',
|
|
22630
22638
|
'div.weui-desktop-dialog input[type="file"][accept*="audio"]',
|
|
22631
|
-
'div.weui-desktop-dialog input[type="file"][accept*=".mp3"]'
|
|
22632
|
-
'input[type="file"][accept*="audio"]',
|
|
22633
|
-
'input[type="file"][accept*=".mp3"]'
|
|
22639
|
+
'div.weui-desktop-dialog input[type="file"][accept*=".mp3"]'
|
|
22634
22640
|
];
|
|
22635
22641
|
var PODCAST_COVER_INPUT = [
|
|
22636
|
-
'
|
|
22637
|
-
'div.weui-desktop-dialog input[type="file"][accept*="
|
|
22638
|
-
'div.weui-desktop-dialog input[type="file"][accept*=".jpg"]'
|
|
22642
|
+
'input[type="file"][accept*="image/bmp"]',
|
|
22643
|
+
'div.weui-desktop-dialog input[type="file"][accept*="image/"]'
|
|
22639
22644
|
];
|
|
22645
|
+
var PODCAST_TITLE_INPUT = ".weui-desktop-dialog .title_form_wrp input.weui-desktop-form__input";
|
|
22646
|
+
var PODCAST_COVER_CHOOSER = '.weui-desktop-dialog:visible:has(h3:has-text("\u9009\u62E9\u56FE\u7247"))';
|
|
22640
22647
|
var PODCAST_INSERT = ['div.weui-desktop-dialog button:has-text("\u63D2\u5165")', 'button:has-text("\u63D2\u5165")'];
|
|
22641
22648
|
var AUDIO_MENU = "li.js_insertaudio";
|
|
22642
22649
|
var AUDIO_TOOLBAR_TRIGGER = "#audio_music_plugin_btn";
|
|
@@ -22854,10 +22861,7 @@ async function typeTitle(page, deps) {
|
|
|
22854
22861
|
return mirror.observed ? "mirror-agreed" : "mirror-unread";
|
|
22855
22862
|
}
|
|
22856
22863
|
async function readTitleMirror(page) {
|
|
22857
|
-
const found = await trySelectors(page, TITLE_MIRROR, { visible: false })
|
|
22858
|
-
found: false,
|
|
22859
|
-
selector: null
|
|
22860
|
-
}));
|
|
22864
|
+
const found = await trySelectors(page, TITLE_MIRROR, { visible: false });
|
|
22861
22865
|
if (!found.found || !found.selector)
|
|
22862
22866
|
return { observed: false, value: "" };
|
|
22863
22867
|
const locator = page.locator(found.selector).first();
|
|
@@ -22869,13 +22873,24 @@ async function readTitleMirror(page) {
|
|
|
22869
22873
|
return { observed: false, value: "" };
|
|
22870
22874
|
}
|
|
22871
22875
|
}
|
|
22872
|
-
async function insertBody(page, deps) {
|
|
22876
|
+
async function insertBody(page, deps, selectors = BODY_BLOCK) {
|
|
22873
22877
|
const body = bodyOf(deps.content);
|
|
22874
22878
|
if (body.trim().length === 0)
|
|
22875
22879
|
return;
|
|
22876
|
-
const selector = await findSelector(page,
|
|
22880
|
+
const selector = await findSelector(page, selectors, "article body", deps.stepTimeoutMs);
|
|
22877
22881
|
await pasteHtml(asPlaywrightPage(page), selector, markdownToWechatHtml(body), { timeoutMs: deps.stepTimeoutMs });
|
|
22878
22882
|
}
|
|
22883
|
+
async function typePodcastTitle(page, deps) {
|
|
22884
|
+
const title = titleOf(deps.content);
|
|
22885
|
+
if (title.length === 0)
|
|
22886
|
+
return;
|
|
22887
|
+
const sel = await findSelector(page, PODCAST_TITLE, "podcast title", deps.stepTimeoutMs);
|
|
22888
|
+
await fillSelector(page, sel, title);
|
|
22889
|
+
const locator = page.locator(sel).first();
|
|
22890
|
+
const mirror = typeof locator.inputValue === "function" ? await locator.inputValue() : "";
|
|
22891
|
+
if (mirror !== title)
|
|
22892
|
+
throw new Error(`podcast title: textarea.js_title reads '${mirror}' but the flow typed '${title}'`);
|
|
22893
|
+
}
|
|
22879
22894
|
function nativeLayoutTargetScript() {
|
|
22880
22895
|
return `/* ${LAYOUT_TARGET_MARKER} */ (() => {
|
|
22881
22896
|
const popups = [...document.querySelectorAll('.edui-popup')].filter((popup) => {
|
|
@@ -23286,24 +23301,154 @@ async function composeVideo(input, deps, entry) {
|
|
|
23286
23301
|
const confirm = await findSelector(page, VIDEO_CONFIRM, "video media confirm", deps.stepTimeoutMs);
|
|
23287
23302
|
await clickSelector(page, confirm, deps.stepTimeoutMs);
|
|
23288
23303
|
await awaitSaveBar(page, deps);
|
|
23289
|
-
|
|
23290
|
-
await insertBody(page, deps);
|
|
23291
|
-
return { warnings: [], titlePath, enrichWarnings: [] };
|
|
23304
|
+
await typePodcastTitle(page, deps);
|
|
23305
|
+
await insertBody(page, deps, PODCAST_BODY);
|
|
23306
|
+
return { warnings: [], titlePath: "mirror-agreed", enrichWarnings: [] };
|
|
23292
23307
|
}
|
|
23293
23308
|
async function composePodcast(input, deps, entry) {
|
|
23294
23309
|
const page = entry.editor;
|
|
23310
|
+
const materialTitle = titleOf(deps.content);
|
|
23311
|
+
const reuseProbe = `(() => {
|
|
23312
|
+
const rows = [...document.querySelectorAll('.weui-desktop-dialog li.audio_item_wrp, .weui-desktop-dialog div.audio_item_wrp')].filter((r) => r.offsetWidth > 0);
|
|
23313
|
+
if (rows.length === 0) return 'LOADING';
|
|
23314
|
+
const row = rows.find((r) => ((r.textContent ?? '').replace(/[s\xA0]/g, '')).includes(${JSON.stringify(materialTitle).replace(/[\s\u00a0]/g, "")}));
|
|
23315
|
+
return row ? (row.textContent ?? '') : 'NONE';
|
|
23316
|
+
})()`;
|
|
23317
|
+
let reuseRowText = "";
|
|
23318
|
+
const reuseHistory = [];
|
|
23319
|
+
{
|
|
23320
|
+
const probe = async () => String(await page.evaluate(reuseProbe) ?? "");
|
|
23321
|
+
for (let i = 0;i < 10; i++) {
|
|
23322
|
+
const text = await probe();
|
|
23323
|
+
reuseHistory.push(text === "LOADING" || text === "ERR" ? text : text.slice(0, 25));
|
|
23324
|
+
if (text === "LOADING" || text === "ERR") {
|
|
23325
|
+
await page.waitForTimeout?.(2500);
|
|
23326
|
+
continue;
|
|
23327
|
+
}
|
|
23328
|
+
if (text === "NONE")
|
|
23329
|
+
break;
|
|
23330
|
+
if (!/\u8F6C\u7801\u4E2D|\u5BA1\u6838\u4E2D|\u5904\u7406\u4E2D/.test(text)) {
|
|
23331
|
+
reuseRowText = text;
|
|
23332
|
+
break;
|
|
23333
|
+
}
|
|
23334
|
+
}
|
|
23335
|
+
}
|
|
23336
|
+
if (reuseRowText) {
|
|
23337
|
+
const reuseReady = await waitUntil(async () => {
|
|
23338
|
+
const text = String(await page.evaluate(reuseProbe) ?? "");
|
|
23339
|
+
return text !== "ERR" && text !== "LOADING" && text !== "NONE" && !/\u8F6C\u7801\u4E2D|\u5BA1\u6838\u4E2D|\u5904\u7406\u4E2D/.test(text);
|
|
23340
|
+
}, 40 * 60000);
|
|
23341
|
+
if (!reuseReady)
|
|
23342
|
+
throw new Error(`\u64AD\u5BA2: \u590D\u7528\u7D20\u6750\u5217\u8868\u5728 40min \u5185\u672A\u89C1\u300C${materialTitle}\u300D\u5B8C\u6210\u8F6C\u7801/\u5BA1\u6838`);
|
|
23343
|
+
await clickSelector(page, await findSelector(page, [`${PODCAST_ROW(materialTitle)} label.audio_item`, PODCAST_ROW(materialTitle)], "\u64AD\u5BA2\u7D20\u6750 row", deps.stepTimeoutMs), deps.stepTimeoutMs);
|
|
23344
|
+
await clickSelector(page, await findSelector(page, PODCAST_INSERT, "\u63D2\u5165 control", deps.stepTimeoutMs), deps.stepTimeoutMs);
|
|
23345
|
+
await awaitSaveBar(page, deps);
|
|
23346
|
+
await typePodcastTitle(page, deps);
|
|
23347
|
+
await insertBody(page, deps, PODCAST_BODY);
|
|
23348
|
+
return { warnings: [], titlePath: "mirror-agreed", enrichWarnings: [] };
|
|
23349
|
+
}
|
|
23295
23350
|
const upload = await findSelector(page, PODCAST_UPLOAD, "\u4E0A\u4F20\u97F3\u9891 control", deps.stepTimeoutMs);
|
|
23296
23351
|
await clickSelector(page, upload, deps.stepTimeoutMs);
|
|
23297
23352
|
const audioInput = await findAttachedSelector(page, PODCAST_AUDIO_INPUT, "audio file input", deps.stepTimeoutMs);
|
|
23298
|
-
await uploadFile(asPlaywrightPage(page), audioInput, input.audio, { timeoutMs:
|
|
23299
|
-
const
|
|
23353
|
+
await uploadFile(asPlaywrightPage(page), audioInput, input.audio, { timeoutMs: 120000 });
|
|
23354
|
+
const uploadDialog = '.weui-desktop-dialog:visible:has(h3.weui-desktop-dialog__title:text-is("\u4E0A\u4F20\u97F3\u9891"))';
|
|
23355
|
+
await waitUntil(async () => await page.locator(`${uploadDialog} button:has-text("\u91CD\u65B0\u4E0A\u4F20")`).count() > 0 && /100%/.test(await page.evaluate(`(() => {
|
|
23356
|
+
const d = [...document.querySelectorAll(".weui-desktop-dialog")].find((el) => el.offsetWidth > 0 && el.querySelector("input[name=audio_id]"));
|
|
23357
|
+
return d ? (d.textContent ?? "") : "";
|
|
23358
|
+
})()`)), 120000);
|
|
23359
|
+
const coverTrigger = await findSelector(page, [`${uploadDialog} .select_audio_cover .upload_cover_text`, ".select_audio_cover .upload_cover_text"], "\u4E0A\u4F20\u5C01\u9762 control (audio upload form)", deps.stepTimeoutMs);
|
|
23360
|
+
await clickSelector(page, coverTrigger, deps.stepTimeoutMs);
|
|
23361
|
+
const coverInput = await findAttachedSelector(page, PODCAST_COVER_INPUT, "cover file input (\u9009\u62E9\u56FE\u7247 chooser)", deps.stepTimeoutMs);
|
|
23300
23362
|
await uploadFile(asPlaywrightPage(page), coverInput, input.cover, { timeoutMs: deps.stepTimeoutMs });
|
|
23301
|
-
const
|
|
23302
|
-
await
|
|
23363
|
+
const chooser = PODCAST_COVER_CHOOSER;
|
|
23364
|
+
const next = await findSelector(page, [`${chooser} button:has-text("\u4E0B\u4E00\u6B65"):not(.weui-desktop-btn_disabled):not([disabled])`], "\u64AD\u5BA2\u5C01\u9762 chooser \u4E0B\u4E00\u6B65", 30000);
|
|
23365
|
+
await clickSelector(page, next, deps.stepTimeoutMs);
|
|
23366
|
+
const cropSettled = await waitUntil(async () => await page.locator(`${chooser} button:has-text("\u4E0A\u4E00\u6B65")`).count() > 0, 15000);
|
|
23367
|
+
if (!cropSettled)
|
|
23368
|
+
throw new Error("\u64AD\u5BA2: \u5C01\u9762\u88C1\u526A\u9875\u672A\u51FA\u73B0\uFF08\u4E0B\u4E00\u6B65\u540E\u65E0\u4E0A\u4E00\u6B65\u6309\u94AE\uFF09");
|
|
23369
|
+
await page.waitForTimeout?.(4000);
|
|
23370
|
+
const finish = await findSelector(page, [`${chooser} button:has-text("\u5B8C\u6210"):not(.weui-desktop-btn_disabled):not([disabled])`], "\u64AD\u5BA2\u5C01\u9762 chooser \u5B8C\u6210", 30000);
|
|
23371
|
+
await clickSelector(page, finish, deps.stepTimeoutMs);
|
|
23372
|
+
let chooserClosed = await waitUntil(async () => await page.locator(chooser).count() === 0, 25000);
|
|
23373
|
+
if (!chooserClosed) {
|
|
23374
|
+
const confirm = await tryFindSelector(page, [`${chooser} button:has-text("\u786E\u5B9A")`], 5000);
|
|
23375
|
+
if (confirm) {
|
|
23376
|
+
await clickSelector(page, confirm, deps.stepTimeoutMs);
|
|
23377
|
+
chooserClosed = await waitUntil(async () => await page.locator(chooser).count() === 0, 1e4);
|
|
23378
|
+
}
|
|
23379
|
+
}
|
|
23380
|
+
if (!chooserClosed) {
|
|
23381
|
+
const residue = String(await page.evaluate(`(() => JSON.stringify([...document.querySelectorAll(".weui-desktop-dialog")]
|
|
23382
|
+
.filter((d) => d.offsetWidth > 0).map((d) => (d.querySelector("h3")?.textContent ?? "") + ":" + (d.textContent ?? "").replace(/\\s+/g, " ").slice(0, 120)) + " toast:" + (document.querySelector(".weui-desktop-toast")?.textContent ?? "")))()`).catch(() => null)).slice(0, 900);
|
|
23383
|
+
throw new Error(`\u64AD\u5BA2: \u5C01\u9762\u9009\u62E9\u5668\u5B8C\u6210\u540E\u672A\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58\u97F3\u9891\u7D20\u6750 \u2014 \u73B0\u573A\u6B8B\u7559 ${residue ?? "(probe \u5931\u8D25)"}`);
|
|
23384
|
+
}
|
|
23385
|
+
await fillSelector(page, await findSelector(page, [PODCAST_TITLE_INPUT], "\u7D20\u6750\u6807\u9898 input", deps.stepTimeoutMs), materialTitle);
|
|
23386
|
+
const agreed = String(await page.evaluate(`(() => {
|
|
23387
|
+
const dialog = [...document.querySelectorAll('.weui-desktop-dialog')].find((d) => d.querySelector('.title_form_wrp'));
|
|
23388
|
+
if (!dialog) return 'no-dialog';
|
|
23389
|
+
const cb = dialog.querySelector('.audio-upload-dialog_agreement input[type=checkbox]');
|
|
23390
|
+
if (!cb) return 'no-box';
|
|
23391
|
+
if (!cb.checked) cb.click();
|
|
23392
|
+
return cb.checked ? 'checked' : 'unchecked';
|
|
23393
|
+
})()`));
|
|
23394
|
+
if (agreed !== "checked")
|
|
23395
|
+
throw new Error(`\u64AD\u5BA2: \u670D\u52A1\u89C4\u5219\u52FE\u9009\u5931\u8D25 (${agreed})`);
|
|
23396
|
+
const save = await findSelector(page, [
|
|
23397
|
+
`${uploadDialog} button.weui-desktop-btn_primary:text-is("\u4FDD\u5B58"):not(.weui-desktop-btn_disabled):not([disabled])`
|
|
23398
|
+
], "\u97F3\u9891\u7D20\u6750\u4FDD\u5B58 (enabled after cover + title + agreement)", 90000);
|
|
23399
|
+
await page.evaluate(`(() => {
|
|
23400
|
+
window.__kkToasts = [];
|
|
23401
|
+
new MutationObserver(() => {
|
|
23402
|
+
const t = document.querySelector(".weui-desktop-toast");
|
|
23403
|
+
if (t && t.textContent) window.__kkToasts.push(t.textContent.trim().slice(0, 200));
|
|
23404
|
+
}).observe(document.body, { subtree: true, childList: true, characterData: true });
|
|
23405
|
+
})()`);
|
|
23406
|
+
const saveDiagnostics = `(() => {
|
|
23407
|
+
const form = [...document.querySelectorAll(".weui-desktop-dialog")].find((d) => d.querySelector(".title_form_wrp"));
|
|
23408
|
+
if (!form) return { form: "gone" };
|
|
23409
|
+
const btn = [...form.querySelectorAll("button")].find((b) => (b.textContent ?? "").trim() === "\u4FDD\u5B58");
|
|
23410
|
+
return {
|
|
23411
|
+
btn: btn ? { html: btn.outerHTML.slice(0, 120), disabled: btn.disabled, offW: btn.offsetWidth } : null,
|
|
23412
|
+
fields: [...form.querySelectorAll("input, textarea")].map((f) => ({ cls: String(f.className ?? "").slice(0, 40), v: String(f.value ?? "").slice(0, 30), offW: f.offsetWidth, cb: f.type === "checkbox" ? f.checked : undefined })),
|
|
23413
|
+
toasts: (window.__kkToasts ?? []).slice(-3),
|
|
23414
|
+
};
|
|
23415
|
+
})()`;
|
|
23416
|
+
const saveBefore = String(await page.evaluate(saveDiagnostics).catch(() => null)).slice(0, 450);
|
|
23417
|
+
await clickSelector(page, save, deps.stepTimeoutMs);
|
|
23418
|
+
const formClosed = await waitUntil(async () => await page.locator(uploadDialog).count() === 0, 30000);
|
|
23419
|
+
if (!formClosed) {
|
|
23420
|
+
const dispatched = String(await page.evaluate(`(() => {
|
|
23421
|
+
const form = [...document.querySelectorAll(".weui-desktop-dialog")].find((d) => d.querySelector(".title_form_wrp"));
|
|
23422
|
+
const btn = form && [...form.querySelectorAll("button")].find((b) => (b.textContent ?? "").trim() === "\u4FDD\u5B58");
|
|
23423
|
+
if (!btn) return "no-btn";
|
|
23424
|
+
btn.click();
|
|
23425
|
+
return btn.disabled ? "was-disabled" : "clicked";
|
|
23426
|
+
})()`).catch(() => null));
|
|
23427
|
+
const dispatchClosed = await waitUntil(async () => await page.locator(uploadDialog).count() === 0, 1e4);
|
|
23428
|
+
if (!dispatchClosed) {
|
|
23429
|
+
const after = String(await page.evaluate(saveDiagnostics).catch(() => null)).slice(0, 600);
|
|
23430
|
+
throw new Error(`\u64AD\u5BA2: \u4FDD\u5B58\u5931\u8D25 \u2014 dispatch=${dispatched} before=${saveBefore} after=${after}`);
|
|
23431
|
+
}
|
|
23432
|
+
}
|
|
23433
|
+
const rowSelector = PODCAST_ROW(materialTitle);
|
|
23434
|
+
const rowProbe = `(() => {
|
|
23435
|
+
const row = [...document.querySelectorAll('.weui-desktop-dialog li.audio_item_wrp, .weui-desktop-dialog div.audio_item_wrp')].find((r) => (r.textContent ?? '').includes(${JSON.stringify(materialTitle)}));
|
|
23436
|
+
return row ? (row.textContent ?? '') : null;
|
|
23437
|
+
})()`;
|
|
23438
|
+
const materialReady = await waitUntil(async () => {
|
|
23439
|
+
const rowText = await page.evaluate(rowProbe);
|
|
23440
|
+
return rowText !== null && !/\u8F6C\u7801\u4E2D|\u5BA1\u6838\u4E2D|\u5904\u7406\u4E2D/.test(rowText);
|
|
23441
|
+
}, 15 * 60000);
|
|
23442
|
+
if (!materialReady) {
|
|
23443
|
+
const probeNow = String(await page.evaluate(reuseProbe) ?? "ERR");
|
|
23444
|
+
throw new Error(`\u64AD\u5BA2: \u97F3\u9891\u7D20\u6750 '${materialTitle}' \u672A\u5728 15min \u5185\u5B8C\u6210\u8F6C\u7801/\u5BA1\u6838\uFF0C\u63D2\u5165\u672A\u6267\u884C\uFF08\u53EF\u91CD\u8DD1\uFF09` + ` \u2014 reuse \u7A97\u53E3 [${reuseHistory.join(",")}] \u6700\u8FD1\u8BFB=${probeNow.slice(0, 30)}`);
|
|
23445
|
+
}
|
|
23446
|
+
await clickSelector(page, await findSelector(page, [`${rowSelector} label.audio_item`, rowSelector], "\u64AD\u5BA2\u7D20\u6750 row", deps.stepTimeoutMs), deps.stepTimeoutMs);
|
|
23447
|
+
await clickSelector(page, await findSelector(page, PODCAST_INSERT, "\u63D2\u5165 control", deps.stepTimeoutMs), deps.stepTimeoutMs);
|
|
23303
23448
|
await awaitSaveBar(page, deps);
|
|
23304
|
-
|
|
23305
|
-
await insertBody(page, deps);
|
|
23306
|
-
return { warnings: [], titlePath, enrichWarnings: [] };
|
|
23449
|
+
await typePodcastTitle(page, deps);
|
|
23450
|
+
await insertBody(page, deps, PODCAST_BODY);
|
|
23451
|
+
return { warnings: [], titlePath: "mirror-agreed", enrichWarnings: [] };
|
|
23307
23452
|
}
|
|
23308
23453
|
async function awaitSaveBar(page, deps) {
|
|
23309
23454
|
await findSelector(page, SAVE_DRAFT, "\u4FDD\u5B58\u4E3A\u8349\u7A3F control (it appears only after the media is attached)", deps.stepTimeoutMs);
|
|
@@ -23355,7 +23500,7 @@ async function saveDraft(input, deps, entry, composed) {
|
|
|
23355
23500
|
await sleep(deps.submitSettleMs);
|
|
23356
23501
|
if (await closeOpenDialogs(entry.editor) !== "closed") {
|
|
23357
23502
|
residuals += 1;
|
|
23358
|
-
residualDialogs.push(await openDialogInventory(entry.editor)
|
|
23503
|
+
residualDialogs.push(await openDialogInventory(entry.editor));
|
|
23359
23504
|
if (attempts < deps.submitAttempts)
|
|
23360
23505
|
continue;
|
|
23361
23506
|
break;
|
|
@@ -23378,7 +23523,7 @@ async function saveDraft(input, deps, entry, composed) {
|
|
|
23378
23523
|
}
|
|
23379
23524
|
if (signal === null || control === null) {
|
|
23380
23525
|
if (control === null)
|
|
23381
|
-
return fail(`draft confirmation: a residual modal refused cleanup after ${attempts} attempt(s), ${residuals} refused cleanup(s) (${residualDialogs.join(" | ") || "no inventory"}) \u2014 '\u4FDD\u5B58\u4E3A\u8349\u7A3F' was not clicked through an unresolved overlay (inventory: ${await openDialogInventory(entry.editor)
|
|
23526
|
+
return fail(`draft confirmation: a residual modal refused cleanup after ${attempts} attempt(s), ${residuals} refused cleanup(s) (${residualDialogs.join(" | ") || "no inventory"}) \u2014 '\u4FDD\u5B58\u4E3A\u8349\u7A3F' was not clicked through an unresolved overlay (inventory: ${await openDialogInventory(entry.editor)})`);
|
|
23382
23527
|
return fail(`draft confirmation: '${SAVE_DRAFT[0]}' was clicked ${attempts}\xD7 but no fresh \u8349\u7A3F\u7BB1 row for '${title}' (its ${DRAFT_STAMP} stamp) was observed within ${deps.draftTimeoutMs}ms (before=${deps.draftBaseline.stamp ?? "none"}, after=${stampAfter ?? "none"}, page=${deps.entry.url()}, frames=${await describeFrames(deps.entry, 5)})`);
|
|
23383
23528
|
}
|
|
23384
23529
|
return ResultSchema.parse({
|
|
@@ -23504,6 +23649,8 @@ function publicSnapshotIsIncomplete(expected, actual) {
|
|
|
23504
23649
|
return true;
|
|
23505
23650
|
if (!snapshotValueIsEmpty(expected.body) && snapshotValueIsEmpty(actual.body))
|
|
23506
23651
|
return true;
|
|
23652
|
+
if (actual.body.length < expected.body.length && expected.body.startsWith(actual.body))
|
|
23653
|
+
return true;
|
|
23507
23654
|
if (expected.media.length > actual.media.length)
|
|
23508
23655
|
return true;
|
|
23509
23656
|
if (!snapshotValueIsEmpty(expected.cover) && snapshotValueIsEmpty(actual.cover))
|
|
@@ -23517,12 +23664,8 @@ function appmsgIdFromCanonical(value) {
|
|
|
23517
23664
|
const canonical = canonicalSavedEditorUrl(value);
|
|
23518
23665
|
if (canonical === null)
|
|
23519
23666
|
return null;
|
|
23520
|
-
|
|
23521
|
-
|
|
23522
|
-
return appmsgId && appmsgId.length > 0 ? appmsgId : null;
|
|
23523
|
-
} catch {
|
|
23524
|
-
return null;
|
|
23525
|
-
}
|
|
23667
|
+
const appmsgId = new URL(canonical).searchParams.get("appmsgid")?.trim();
|
|
23668
|
+
return appmsgId && appmsgId.length > 0 ? appmsgId : null;
|
|
23526
23669
|
}
|
|
23527
23670
|
async function waitForPublicEditorReadiness(page, deps) {
|
|
23528
23671
|
let consecutiveSaved = 0;
|
|
@@ -23659,8 +23802,9 @@ async function recoverStaleVersion(deps, entry, saved) {
|
|
|
23659
23802
|
}, deps.draftTimeoutMs, deps.pollMs);
|
|
23660
23803
|
if (!snapshotSettled || latestSnapshot === null)
|
|
23661
23804
|
return fail("public stale-version recovery: latest editor snapshot was unreadable; no second \u53D1\u8868 click attempted");
|
|
23805
|
+
const latestBody = latestSnapshot.body;
|
|
23662
23806
|
if (differences.length > 0)
|
|
23663
|
-
return fail(`public stale-version recovery: latest editor content mismatch (${differences.join(", ")}); no second \u53D1\u8868 click attempted`);
|
|
23807
|
+
return fail(`public stale-version recovery: latest editor content mismatch (${differences.join(", ")}; body ${latestBody.length}/${saved.snapshot.body.length} chars); no second \u53D1\u8868 click attempted`);
|
|
23664
23808
|
if (!await waitForPublicEditorReadiness(latestEditor, deps))
|
|
23665
23809
|
return fail("public stale-version recovery: latest editor did not provide two consecutive recognized readiness probes; no second \u53D1\u8868 click attempted");
|
|
23666
23810
|
return {
|
|
@@ -23716,7 +23860,7 @@ function shouldNotifySubscribers(content) {
|
|
|
23716
23860
|
return wechatmp.notifySubscribers !== false;
|
|
23717
23861
|
}
|
|
23718
23862
|
async function confirmPublicPublish(page, notifySubscribers, stepTimeoutMs, pollMs) {
|
|
23719
|
-
const confirmationTimeoutMs =
|
|
23863
|
+
const confirmationTimeoutMs = stepTimeoutMs;
|
|
23720
23864
|
const dialog = await findUniqueVisibleSelector(page, PUBLISH_DIALOG, confirmationTimeoutMs, pollMs);
|
|
23721
23865
|
if (dialog.selector === undefined) {
|
|
23722
23866
|
if (dialog.reason === "missing") {
|