mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-18 08:29:48 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d1336d8bd | |||
| 42931d6294 |
@@ -6,7 +6,7 @@
|
|||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"description": "Skills shared by Baoyu for improving daily work efficiency",
|
"description": "Skills shared by Baoyu for improving daily work efficiency",
|
||||||
"version": "1.44.0"
|
"version": "1.45.0"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
English | [中文](./CHANGELOG.zh.md)
|
English | [中文](./CHANGELOG.zh.md)
|
||||||
|
|
||||||
|
## 1.45.0 - 2026-03-05
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- `baoyu-post-to-x`: add post-composition verification for X Articles — automatically checks remaining placeholders and image count after all images are inserted
|
||||||
|
- `baoyu-post-to-x`: increase CDP timeout to 60s and add 3s DOM stabilization delay between image insertions for long articles
|
||||||
|
|
||||||
## 1.44.0 - 2026-03-05
|
## 1.44.0 - 2026-03-05
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
[English](./CHANGELOG.md) | 中文
|
[English](./CHANGELOG.md) | 中文
|
||||||
|
|
||||||
|
## 1.45.0 - 2026-03-05
|
||||||
|
|
||||||
|
### 新功能
|
||||||
|
- `baoyu-post-to-x`:X 文章发布后自动验证——检查残留占位符和图片数量是否正确
|
||||||
|
- `baoyu-post-to-x`:增加 CDP 超时至 60 秒,图片插入间隔增加 3 秒 DOM 稳定等待,改善长文章发布稳定性
|
||||||
|
|
||||||
## 1.44.0 - 2026-03-05
|
## 1.44.0 - 2026-03-05
|
||||||
|
|
||||||
### 新功能
|
### 新功能
|
||||||
|
|||||||
@@ -172,6 +172,12 @@ npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg
|
|||||||
|
|
||||||
**Note**: Script opens browser with article filled in. User reviews and publishes manually.
|
**Note**: Script opens browser with article filled in. User reviews and publishes manually.
|
||||||
|
|
||||||
|
**Post-Composition Check**: The script automatically verifies after all images are inserted:
|
||||||
|
- Remaining `XIMGPH_` placeholders in editor content
|
||||||
|
- Expected vs actual image count
|
||||||
|
|
||||||
|
If the check fails (warnings in output), alert the user with the specific issues before they publish.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|||||||
@@ -132,8 +132,12 @@ JSON output:
|
|||||||
- Select the placeholder
|
- Select the placeholder
|
||||||
- Copy image to clipboard
|
- Copy image to clipboard
|
||||||
- Paste to replace selection
|
- Paste to replace selection
|
||||||
9. **Review**: Browser stays open for 60s preview
|
9. **Post-Composition Check** (automatic):
|
||||||
10. **Publish**: Only with `--submit` flag
|
- Scan editor for remaining `XIMGPH_` placeholders
|
||||||
|
- Compare expected vs actual image count
|
||||||
|
- Warn if issues found
|
||||||
|
10. **Review**: Browser stays open for 60s preview
|
||||||
|
11. **Publish**: Only with `--submit` flag
|
||||||
|
|
||||||
## Example Session
|
## Example Session
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const wsUrl = await waitForChromeDebugPort(port, 30_000, { includeLastError: true });
|
const wsUrl = await waitForChromeDebugPort(port, 30_000, { includeLastError: true });
|
||||||
cdp = await CdpConnection.connect(wsUrl, 30_000, { defaultTimeoutMs: 30_000 });
|
cdp = await CdpConnection.connect(wsUrl, 30_000, { defaultTimeoutMs: 60_000 });
|
||||||
|
|
||||||
// Get page target
|
// Get page target
|
||||||
const targets = await cdp.send<{ targetInfos: Array<{ targetId: string; url: string; type: string }> }>('Target.getTargets');
|
const targets = await cdp.send<{ targetInfos: Array<{ targetId: string; url: string; type: string }> }>('Target.getTargets');
|
||||||
@@ -148,7 +148,7 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
|||||||
await cdp.send('DOM.enable', {}, { sessionId });
|
await cdp.send('DOM.enable', {}, { sessionId });
|
||||||
|
|
||||||
console.log('[x-article] Waiting for articles page...');
|
console.log('[x-article] Waiting for articles page...');
|
||||||
await sleep(3000);
|
await sleep(1000);
|
||||||
|
|
||||||
// Wait for and click "create" button
|
// Wait for and click "create" button
|
||||||
const waitForElement = async (selector: string, timeoutMs = 60_000): Promise<boolean> => {
|
const waitForElement = async (selector: string, timeoutMs = 60_000): Promise<boolean> => {
|
||||||
@@ -644,6 +644,8 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
|||||||
|
|
||||||
if (imgUploadOk) {
|
if (imgUploadOk) {
|
||||||
console.log(`[x-article] Image upload verified (${expectedImgCount} image block(s))`);
|
console.log(`[x-article] Image upload verified (${expectedImgCount} image block(s))`);
|
||||||
|
// Wait for DraftEditor DOM to stabilize after image insertion
|
||||||
|
await sleep(3000);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[x-article] Image upload not detected after 15s`);
|
console.warn(`[x-article] Image upload not detected after 15s`);
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
@@ -653,6 +655,42 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log('[x-article] All images processed.');
|
console.log('[x-article] All images processed.');
|
||||||
|
|
||||||
|
// Final verification: check placeholder residue and image count
|
||||||
|
console.log('[x-article] Running post-composition verification...');
|
||||||
|
const finalEditorContent = await cdp.send<{ result: { value: string } }>('Runtime.evaluate', {
|
||||||
|
expression: `document.querySelector('.DraftEditor-editorContainer [data-contents="true"]')?.innerText || ''`,
|
||||||
|
returnByValue: true,
|
||||||
|
}, { sessionId });
|
||||||
|
|
||||||
|
const remainingPlaceholders: string[] = [];
|
||||||
|
for (const img of parsed.contentImages) {
|
||||||
|
const regex = new RegExp(img.placeholder + '(?!\\d)');
|
||||||
|
if (regex.test(finalEditorContent.result.value)) {
|
||||||
|
remainingPlaceholders.push(img.placeholder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalImgCount = await cdp.send<{ result: { value: number } }>('Runtime.evaluate', {
|
||||||
|
expression: `document.querySelectorAll('section[data-block="true"][contenteditable="false"] img[src^="blob:"]').length`,
|
||||||
|
returnByValue: true,
|
||||||
|
}, { sessionId });
|
||||||
|
|
||||||
|
const expectedCount = parsed.contentImages.length;
|
||||||
|
const actualCount = finalImgCount.result.value;
|
||||||
|
|
||||||
|
if (remainingPlaceholders.length > 0 || actualCount < expectedCount) {
|
||||||
|
console.warn('[x-article] ⚠ POST-COMPOSITION CHECK FAILED:');
|
||||||
|
if (remainingPlaceholders.length > 0) {
|
||||||
|
console.warn(`[x-article] Remaining placeholders: ${remainingPlaceholders.join(', ')}`);
|
||||||
|
}
|
||||||
|
if (actualCount < expectedCount) {
|
||||||
|
console.warn(`[x-article] Image count: expected ${expectedCount}, found ${actualCount}`);
|
||||||
|
}
|
||||||
|
console.warn('[x-article] Please check the article before publishing.');
|
||||||
|
} else {
|
||||||
|
console.log(`[x-article] ✓ Verification passed: ${actualCount} image(s), no remaining placeholders.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before preview: blur editor to trigger save
|
// Before preview: blur editor to trigger save
|
||||||
|
|||||||
Reference in New Issue
Block a user