SuperAPI AI Directory

lov-media-publisher

Marketing & growth

View repository

Updated 10-16 00:02

About this skill

Publish a video to WeChat Channels / Bilibili

Only operate the visible web pages of the platform's own creator backend. Treat the page as a dynamic interface: re-read the current page at every step, locate controls semantically, and do not rely on historical CSS selectors, old handles, or coordinates.

Platform routing

By default, publish to WeChat Channels first, then to Bilibili, and the platform queue is [wechat-channels, bilibili]. When the user only says "publish" or "send it out" and does not specify a platform, directly use this default queue and do not ask generally about the publishing destination again.

  • When the current request explicitly specifies a platform, handle only the specified platform; when it explicitly specifies an order, execute in that order. For a request where the item link or BV number can already determine the platform, status only query that item, and do not expand to the default dual-platform queue.
  • When both platforms are selected but no order is otherwise specified, first complete this action for WeChat Channels and read back the list status, then enter the Bilibili process. If WeChat Channels is blocked, handle it first and report the specific blockage; do not skip it on your own or switch to Bilibili early.
  • When materials, accounts, or required fields are missing, first find out through this Skill's input and pre-check process; only ask about the specific missing items that truly cannot be resolved, and do not reinterpret missing items as a platform selection question. Verify platform restrictions, DOM writing methods, and status separately.
Platform --platform Entry Structure Page details Platform constraints
WeChat Channels wechat-channels https://channels.weixin.qq.com/platform/post/create wujie micro frontend + shadow DOM Creation page structure WeChat Channels constraints
Bilibili bilibili https://member.bilibili.com/platform/upload/video/frame Ordinary Vue application Submission page structure Bilibili constraints

Four platform differences that will bite you repeatedly; remember them before you start:

  • Different reversibility: after publishing to WeChat Channels, it cannot be withdrawn or modified; after a Bilibili submission is posted, you can ?type=edit&bvid= change the title, description, tags, cover, and collection, butafter changing them you must click "Submit Now" again. The final draft confirmation gate applies to both sides; only the reporting wording should change accordingly, and do not render a Bilibili mistaken submission as a disaster.
  • Hard limits differ by an order of magnitude: WeChat Channels 4 GiB / 2 hours, Bilibili 16 GB / 10 hours. Using one side's default value to constrain the other side will produce false conclusions, so scripts must always explicitly pass --platform。
  • Completely different value-writing methods: WeChat Channels' description is contenteditable, and topics must be generated by the platform button; Bilibili's input boxes require the native setter, and the description is a Quill instance. Do not apply one to the other.
  • Always copy control class names from page-anatomy; do not guess: both sides use self-developed component libraries (WeChat Channels wujie + shadow DOM, Bilibili data-v-* scoped CSS). Applying antd or generic guesses (.ant-select-*、 [role="combobox"]、.choose-btn、.category-item) will not match any of them, andif not found, it will not report an error, appearing as "clicked but no response", which is very easily misread as the timing not being right and leads to several rounds of empty waiting.Before filling in any field, first open that platform's page-anatomy and check the selector table against it——2026-08-18 EP.03 Just skipping this step, Bilibili's partition, collection, and cover fields cannot be filled in at all, and ultimately the user has to fill them in manually.

Platform final-cut mapping gate

The platform allowing a certain aspect ratio does not mean that version should be chosen for this episode. Before opening the publish page, first determine from the Creator delivery report, platform filename, Composition, or this episode's checklistthe approved final cut corresponding to this episode's target platform: for example, if this episode explicitly has Episode-Horizontal and Episode-Vertical, and the vertical filename is wechat-channels , Bilibili should first export the horizontal platform MP4, and you cannot take the vertical version and say "publish it first and figure it out later." The Composition in Studio and the review-ready preview are not uploadable files; when the target platform MP4 is missing, record the status as blocked-on-platform-variant and hand it back to lov-media-creator for rendering, decoding, and QA.

Preflight uses two layers of hard gates:

python3 $SKILL_DIR/scripts/check_video.py PLATFORM_MP4 \
  --platform bilibili --expected-orientation horizontal --json
  • When the filename explicitly contains another platform's identifier (for example, a Bilibili task selects wechat-channels), it fails by default; only when the user explicitly requests cross-platform reuse may you add --allow-cross-platform-name。
  • --expected-orientation from this episode's delivery contract, and do not arbitrarily infer it from stereotyped platform rules like "Bilibili must be horizontal"; Bilibili itself supports vertical, but when the project has approved horizontal, passing in vertical must fail.
  • The user may switch the platform file before submission or explicitly override the aspect ratio; any override must rerun preflight and be written into the final draft field table.

The parts shared by the two platforms are only:browser workflow(helper signatures, control ownership, task space lifecycle),publish gate checklist、 heavy compression plan、video description structure。

Triggers

Activate when

  • The user requests publishing a local video to WeChat Channels or Bilibili, or saving it as a draft.
  • The user requests scheduling a timed publish, verifying publish status, or publish a video to Bilibili / video channels.
  • The user requests republishing the same local video based on the previous version of content in this session.

Do not activate when

  • The user only requests publishing a WeChat official account article or calling the official account API.
  • The user only requests local media preflight or transcoding, and does not involve publishing to platform pages.
  • The user requests editing, rendering, or generating the video asset itself (that is the responsibility of lov-media-creator ).

Read input

Obtain the following inputs before starting:

  • Required: thetarget platform queueparsed according to the previous section (when unspecified, it is WeChat Channels → Bilibili), the target action draft / schedule / publish / status, and the expected account name for each platform.
  • draft / schedule / publish Required: local video path;schedule also requires a publish time with time zone.
  • status Required: item link, item ID / BV number, or a copy prefix, filename, and submission time window sufficient to uniquely locate it.
  • Optional: copy, topics/tags, cover, location, collection, originality statement, partition, type, and other settings supported by the current page.

publish also implies onenon-omittable input: the user's explicit consent to the final draft before submission. The "go ahead and publish" at the beginning of the session only authorizes starting the process; see the next section.

Treat the topic, title, description, hashtags, cover, and originality requirements that the user has confirmed in the current session as the input for this task; when the user says "based on the previous version," "send it again," or points out that a field was left blank, continue using the last confirmed version in this session, and keep applying the corrected requirements to subsequent steps. Do not add facts or promotional language unrelated to the topic.

Resolve the description source according to the following priority order; once a higher priority is matched, it must not be overridden by a lower priority:

  1. the actual text after the user manually edits it on the current platform page;
  2. the description the user gives verbatim in the current session;
  3. the most recently explicitly approved publish copy in the same project;
  4. only when none of the above exist and the edit area is empty, generate a draft according to references/description-template.md .

If the user says "your description is no good," has already taken over editing the page, or the page text differs from the value the agent last wrote, all are treated as description_source=user-edited. At this point, immediately freeze the full text: subsequent cover, collection, originality, location, and hashtag operations must not rebuild the description edit area, nor polish the user's version to "match the template." The template is a constraint for generating drafts, not a license to override the user's final version.

When the user further provides theactual publish textand states "already modified and published," this text immediately becomes the highest-priority gold reference for this issue, and is also the source of expression strategy for subsequent platforms: preserve its hook, tone, capitalization, and keywords, and only make the minimal adaptations required by platform mechanics (for example, migrating the WeChat Channels #话题 to the Bilibili tag field, appending the approved chapters after the Bilibili hook), and do not restore the agent's old draft, series introduction, or lengthy summary. Record the user report and platform verification separately; before reading back from the content list, do not write "user says it is published" as verified published。

For knowledge-and-tips short videos (usually about 10 minutes or less) with no user final version, by default use "real pain-point question → capability promise question → 5–10 precise keywords," rather than forcing "series episode N + content description + polite closing." Only long interviews, long tutorials, or resource-intensive content enable the full chapter and link skeleton. For specific criteria, see references/description-template.md。

By default, use thefull namefor the series name. When hitting the character limit, do not directly downgrade to a short name—first read the maxLengthof the creation form and the edit form separately; they are not necessarily the same (the Bilibili creation dialog is 20 characters but the edit form is 50 characters, so you can create with a short name first and then rename it). Only use the short name when neither form can fit it, and explain this in the report.

Before submission, the user must confirm the final version (publish hard gate, applies to both platforms)

publish is not "publish once the fields are complete." After all required items pass , the status first enters awaiting_confirmation, show the final version to the user for review, and only click the main submit button after obtaining explicit consent. If the user has said "go ahead and publish" or "okay," that isstartup authorization, and does not replacefinal versionconfirmation—between the two, uploading, platform rewriting, and field readback occurred, and the user had not yet seen the final result at that time.

The confirmation action has three steps; missing any one does not count as notified:

  1. Read the entire field table in one js() (for the method, see the corresponding platform's page-anatomy), and read the real value / checked / tag nodes, without inferring from appearance.

  2. Send a system notification + voice announcement—the user may not be at the terminal:

    python3 $SKILL_DIR/scripts/notify_user.py \
      --title "视频号发布 · 终稿待确认" \
      --message "标题/描述/话题/封面已就位,确认后我再提交" \
      --speech "终稿已准备好,请确认后我再发布"
    
  3. Include the field table together withPlaces rewritten by the platformpresent them together, then stop and wait for the user to reply. This differs from "waiting for control": control is polling and waiting, whereas final-draft confirmation must wait until the user actually replies, with no timeout, no default consent, and no self-approval.

Fields rewritten by the platform must be marked separately; this is the part users most need to see. Observed examples: WeChat Channels short titles rewritten due to the 16-character limit or prohibited symbols, the number of cover slots not matching expectations, and the location being automatically filled in by the platform; Bilibili tags being rejected with "the current tag is topic-specific and custom additions are not allowed" and then replaced with synonyms, and the platform automatically inserting tags based on the account name such as 手工/生活记录 . The user only approved the original copy, not these rewrites.

draft / schedule / status does not require final-draft confirmation: drafts can be edited, scheduled posts can be withdrawn before the time arrives,status is read-only.

Publishing completeness gate

For publish, by default require a title, a non-empty description, at least one topic/tag, andevery cover slot actually present on the current pageto have usable content. When the user has not provided this text verbatim, a restrained version may be assembled from the current session, the same project's explicit copy, and the video's visible theme; when evidence is insufficient, stop before submission and point out the missing items, and do not publish blank or half-finished content.draft may retain unfinished fields that the user has explicitly allowed.

If Bilibili has verified chapters, a clickable timeline must be added to the description. Time codes may only be taken from the final cut's timeline, in the format of one per line MM:SS 章节名(use HH:MM:SSfor over one hour), and must not be copied from source recordings, old edit versions, or human memory. If the project already has approved chapters but the description lacks a timeline, the completeness gate is fail. For already frozen description_source=user-edited, do not silently overwrite the full text: make a minimal append as explicitly requested by the user, or stop and show the missing items; after modification, re-freeze the full text and rerun copy precheck, field readback, and final-draft confirmation.

Bilibili tags must be publicly read back after publishing. The tag node in the submission form can only prove the pre-submission state; after publishing, additionally call /x/tag/archive/tags?bvid=BV... to read data[].tag_name, and verify on the public page .video-tag-container a.tag-link。/x/web-interface/view itself does not return tags, and the description not containing #标签 does not mean the tags are lost. The platform will reorder tags, so compare by exact name set, not by order; when both the API and the public page hit the expected set, do not re-edit or resubmit just to display a misjudgment.

The number of cover slots is measured from the page, not hardcoded. WeChat Channels, as measured on 2026-08-17, has only one slot on the creation page (labeled "Personal homepage and share card (3:4)"), and the two previews are cropped from the same 3:4 image; Bilibili has twomutually independentslots (4:3 homepage recommendation / 16:9 personal space), and the list, space, and feed all use the 16:9 one—uploading only 4:3 is equivalent to not uploading. Upload as many images as there are slots read, and state in the report which spare assets were unused.

A cover existing does not mean it is qualified. For each slot actually present on the page, open the editor one by one and confirm through screenshots or effect previews that the title subject is within that slot's crop safe area. The 16:9 slot on Bilibili especially must not be judged from the preview inside the popup; the only trustworthy verification is to pull the public API once after submission and read pic(for the method, see Bilibili submission page structure"Covers are two independent slots"). See details in Publishing gate checklist。

Cover assets have an established source; on-the-spot generation is not allowed. Each issue's cover is in output/covers/<ep>/ (lov-channels-cover produced cover_3x4.png / cover_4x3.png) and output/deliverables/…-封面-<宽x高>-v*.png , if you can't find it, ask; don't make one yourself. That set only produces 3:4 and 4:3,Bilibili's 16:9 slot is a known gap: if it's missing, say so plainly and have the user supply one, never use ffmpeg -vframes 1 to grab the first frame as a substitute—the first frame is the title card still or the first frame of the main video, and using it as a cover is the same as having no cover. 2026-08-18 EP.03 I grabbed the first frame as the asset for two slots, and the user manually replaced them with the official cover (the online 16:9 is actually a 1440×810 portrait + title version).

Original (WeChat Channels):Checked by default for creator accounts, unless the user explicitly says in the same task "don't check original", "not original" or other negative terms. Lesson source (2026-08-21 EP.01): the user required checking original for several issues in a row, and the agent kept stopping at the passive logic of "if the user didn't explicitly say it, don't check it", requiring the user to remind it every issue. Original is a standing right of creator accounts, not an option that needs the user to reaffirm it to enable. When checking original,you must complete the notice/terms checkboxes in the original rights popup, and after the popup closes, read the main checkbox's real checked=true; you cannot judge only by visual style or click action. In the final draft confirmation, include "Original: checked" in the field table, so the user sees it rather than it being hidden by default.

Collection: first read the page's actual selected value and existing candidates; creating a new collection still requires the user's explicit consent, because a WeChat Channels collection cannot be renamed after creation. When the user has already selected a collection during handover, or explicitly says "the collection is checked and published", do not ask again, do not clear it, and do not recreate it; if it can be read back, record the actual collection name; if the page has navigated away and the name is not visible, record only user-selected, and do not guess the name from local candidates. Lesson source (2026-08-21 EP.01): the agent treated the collection as an optional item that could be skipped "if not raised"; and on 2026-08-26 EP.01, after the user had already checked it themselves, it still could not continue using the old unselected field table.

Copy such as description/title:the user's hand-edited final version prevails. After the user modifies the description, title, or topics, do not overwrite it with the agent's own compiled version, and do not show the old version in the final draft confirmation. Lesson source (2026-08-21 EP.01): the agent showed the old description, and the user had already fixed it themselves.

In implementation, you cannot rely only on remembering this sentence: after taking over or restoring the publish page, thefirst read-only actionis to read the full description text, and record description_source, the exact text, and the length. After each page write operation unrelated to the description, read it again; if it differs from the frozen snapshot, stop immediately and have the user confirm before restoring. The final draft field table's expected takes the frozen user text, and cannot still reference the local publish-copy.md or the agent's old draft. After the user edits, do not call the description area's clear,fill、 execCommand or Quill setText()。

Generated-content labeling must be based on the asset source, not on the video topic. Explaining AI products, demoing AI cases, and using AI-assisted editing, subtitles, or color grading cannot by themselves prove the finished video contains generated/synthesized assets. First verify the user's explicit statement about the asset source and verifiable production evidence; do not speculate about the source of screen-demo clips; record the basis and read back the field according to Asset Source and Generated-Content Labeling.

Advertising, visibility scope, location, partition, type, and comments are options that change publishing semantics: execute them when the user explicitly requests them, and keep the platform defaults when they do not. If the location is automatically populated by the platform, it must also be read back before submission and included in the field table.

If the user only says "my account," and the page displays only one clear logged-in account name, record that name and report it back before submission; if an account selector, multiple accounts, or an ambiguous avatar appears, confirm first. If the title, description, topic, or originality declaration requested by the user is missing in the page read-back, stop before submission, point out the specific missing fields, and do not click publish.

Publishing collaboration cadence (hard constraints)

  • Freeze the asset list before opening the page: first resolve the platform final video and all covers into existing, readable absolute paths, and record the version, dimensions, and platform slot. Do not merely hide the paths in a file input or tool log.
  • Wait only on dependencies: once the video input starts uploading, the title, description, tags, collection, originality, and other already-mounted independent fields immediately enter the write/read-back channel. Only the cover editor, video parsing results, and submission action, which are true dependencies, continue to wait; do not serialize the entire table just to poll upload progress.
  • Manual handoff must be executable: hand off only when login, platform blocking, or real occlusion cannot be automated. At the same time as the handoff:
    1. provide clickable absolute paths to the final video and cover in the conversation;
    2. the system notification should clearly state the platform, the current blocker, and the only action the user needs to complete;
    3. prefer using Volcano TTS to announce the same instruction, and explicitly state the boundary of "do not click publish" or "you may click publish";
    4. after handing over control, only wait for it to be returned, and do not read the page, click, or take over on your own.
  • Degrade immediately on failure: after automatic upload or cover writing encounters a definite blocker, do not repeat the same ineffective action. First preserve the already-filled fields, then deliver the exact file paths and a single manual step; after the user acts, only read back the changed area.

Execution flow

  1. For draft / schedule / publish, first read that platform's platform-constraints, then run the read-only video precheck (must include --platform, the hard limits of the two platforms differ by an order of magnitude):

    python3 $SKILL_DIR/scripts/check_video.py <视频路径> --platform wechat-channels --json
    python3 $SKILL_DIR/scripts/check_video.py <视频路径> --platform bilibili \
      --expected-orientation "$EXPECTED_ORIENTATION" --json
    

    EXPECTED_ORIENTATION must first be read from this issue's delivery contract and set to horizontal / vertical / square; when there is no project evidence, do not guess the value based only on the platform name.

    When a hard error occurs, stop at the precheck stage and report it; warnings do not block, but must be clearly listed before upload. If the page clearly shows that the account has been relaxed (Video Account 20 GiB / 8 hours), record the page text and rerun with --max-gb / --max-hours overriding it. When the real-time page limit is lower, obey the lower limit.status is a read-only query; skip the video precheck and upload.

    Exception for long videos (about 30 minutes or more) or large files: in this case treat warnings as the actual threshold, first follow the heavy compression plan to eliminate deviation items before uploading, especially video_bitrate_high. The platform's transcoding rejection is returned only after the entire package has finished transferring and the server has parsed it; for a long video, one failure costs several hours.

  2. Precheck the copy at the same time, do not wait for the page to reject it. These are all pure string checks; one collision adds another page round trip of "fill in → blur → read validation → rewrite":

    # 视频号:短标题 16 字上限 + 禁用逗号 + 合集 10 字且创建后不可改
    python3 $SKILL_DIR/scripts/check_copy.py --platform wechat-channels \
      --short-title "第一时间读 Harness 架构" --description "$(cat 描述.txt)" \
      --topic DeepSeek --collection "学 Harness" --json
    
    # B 站:标题 80 / 简介 2000 / 标签 ≤10 且部分名字是话题专用
    python3 $SKILL_DIR/scripts/check_copy.py --platform bilibili \
      --title "如何快速上手一个新项目" --description "$(cat 简介.txt)" \
      --topic 架构设计 --topic 开源 \
      --collection "手工川与你一起学 DeepSeek Harness" --collection-stage edit --json
    

    status: fail Change the copy first, then open the browser. It only covers the parts that can be determined offline,passing does not mean the platform will definitely accept it, you still need to read the validation prompt and toast once after filling it in. Two things to note clearly: WeChat Channels collections are limited to 10 characters and cannot be modified after creation, so when it is too long, stop and rename it instead of truncating it and creating it as is; Bilibili's dedicated topic tag list only covers names that have been actually tested and rejected, and new names will still be rejected on the page.

  3. Read browser workflow, and follow the ego-browser task space flow to open that platform entry:

    ego-browser nodejs <<'EOF'
    const task = await useOrCreateTaskSpace('media publish')
    await openOrReuseTab(ENTRY_URL, { wait: true })
    await snapshotText()
    cliLog('task space: ' + task.id)
    EOF
    

    helpers alwayspass id, not a task object(handOffTaskSpace(task) will throw task space not found: [object Object]); the complete signature pitfalls table is in the same document.

  4. First snapshotText() then locate the account, account status, and visible controls on the page; read back the snapshot after each key operation.

  5. If a login QR code or account selection appears,handOffTaskSpace(task.id) hand it to the user, and continue only after the user returns, do not fill in credentials on their behalf, and do not bypass login. When WeChat is already logged in on this machine for Channels, prioritize clicking "Quick Login"; do not make an extra handoff just to scan the code. After handing over control, you may only wait for it to be returned via waitForAgentControl(task.id) ,under no circumstances may you by yourself takeOverTaskSpace()—including when you only want to read a snapshot once, or when the page looks ready. When handing over, first show the material checklist, then send a system notification and voice announcement ($SKILL_DIR/scripts/notify_user.py --tts-provider auto), then poll the control ownership status in the background; do not stop to ask the user to reply. Take over only after the user explicitly says "logged in" or "done".

  6. Read the account name displayed on the page and verify it character by character against the expectation. When there is only one clear account and the user says "my account", record that name; when the account does not match, there are multiple candidates, or there is only a blurry avatar, stop and confirm.

  7. Summarize the fields confirmed in this session into a pre-submission field table, recording for each item required / source / expected / actual / result. After taking over the page, first read the description; if the page already has a non-empty description and it differs from the value last written by the agent,source=user-edited, freeze on the spot, and do not enter the description-writing branch. Common items: account, title, description, topics/tags, cover (one row per slot according to the actual number of slots on the page), collection, schedule. WeChat Channels adds: short title, location, original, video annotation, comments, visibility scope. Bilibili adds: partition, type, clickable timeline of verified chapters, 16:9 cover pic readback result. For the full field table see publish gate checklist. Once the account, target action, and required inputs are all clear, record the status as prepared。

  8. status directly open the content management list and jump to step 12. Other actions go through themain upload areaassociated file input to submit the original video—both platforms have multiple accept identical file inputs, so you must anchor according to the criteria in the platform document, and must not take the first one. After observing upload progress, record it as uploading; after progress reaches 100%, still wait for transcoding, thumbnail, or material parsing, and record it as processing. After the upload starts, as long as the field area is already mounted and two consecutive read-backs are stable, fill in in parallel the title, description, topics, collection, original and annotations that do not depend on asset parsing; do not serialize these fields just to wait for the upload to complete. Each write must still obey the description freeze rule. After asset parsing completes, do a unified re-read once, and only do minimal supplementary writes when platform re-rendering has cleared them.

  9. After asset parsing completes and the page does not show a video error, fill in the fields that depend on the asset, such as the cover, and complete a full-table read-back. Before writing, first judge each field according to source priority;description_source=user-edited , skip the description write and only do a read-only read-back. Operate according to each platform's page-anatomy value-writing method, and read back the actual value item by item:

    • WeChat Channels: read the short title from the input box value, and when the platform reports special characters, make the minimal correction as prompted and confirm the warning disappears; read the description from the actual text in the editing area; for topics, you must read the independent tag nodes already recognized by the platform, not just check the raw #文本; the cover's image file input only exists after the editor is opened; for original to take effect, you must first check the notice and then read the main checkbox attribute. The collection defaults to asking the user which collection it belongs to (especially when creators publish content by series); original is checked by default and the notice popup confirmation is completed (see the "Original" section above); do not wait for the user to restate it.
    • Bilibili: write values into the input box with the native setter,inputType cannot be omitted; after writing, the countermust be read in the next round js() again(what is read in the same round is the old value before nextTick , and0/20 is a false failure); for the description, use Quill; after using .ql-container.__quill.setText(text, 'user') , blur(), and in the next round read back character by character from .ql-editor or getText() ; before filling in tags, first clear the ones the platform guessed automatically;svg.close and .hot-tag-item only accept real CDP mouse input. When the project has verified chapters, generate the complete MM:SS 章节名 list from the final cut's timeline and write it into the description; in the next round read back all timecodes and titles item by item, and you cannot submit if even one is missing. The "Home Recommendation / Personal Space" buttons on the right side of the cover only switch the effect preview; the real upload slot is the canvas wrapper that wraps #editor_4_3 / #editor_16_9 , and you must read back activeslot by slot, upload and take a screenshot, and disable dual-ratio sync. After every write operation unrelated to the description, assert that the frozen description has not changed character by character. If any required field is not persisted, the user's description has been altered, or validation still has warnings, stop before submission.
  10. publish stop here and wait for the user to confirm the final draft: once js() read the entire field table, run notify_user.py to send notifications and announcements, let the user review the final draft (especially fields that have been rewritten by the platform), and record the status as awaiting_confirmation. Only continue after obtaining explicit consent.draft / schedule / status skip this step. If the user takes over the page and then returns and says "I have already fixed it and published it", do not treat this sentence as confirmation for the agent to click again: immediately freeze the actual text given by the user, stop all form writes, and directly enter the content list for read-only read-back; before the read-back, keep the previous proven state, and separately record user_reported_published=true。

  11. Enter the corresponding branch according to the target action:

    • draft: select the semantic action "Save Draft", and after confirming completion, enter the draft list and reload.
    • schedule: Enable scheduled publishing, verify the page time zone, date, and time, and after confirming the submission, enter the content list and reload.
    • publish: All required fields pass and after the user has confirmed the final draft, click the primary submit action (WeChat Channels "Publish" / Bilibili "Submit Now"),submit only once, then enter the content list and reload. If confirmation has not been obtained, do not click, and do not switch to draft to bypass due to waiting. The primary submit button often falls outside the viewport (WeChat Channels observed y=726 / viewport height 727, Bilibili observed y=1380 / viewport height 731), and coordinate clicks are silently lost; first scrollIntoView thenoperate according to the new rect , and after clicking, read back the page state to confirm it actually took effect. For Bilibili, first do a semantic/direct click once; only when real occlusion is confirmed and there is no submit state at all, hand it over to the user, and do not hide the occluding layer or blindly click a second time.
    • status: Do not modify the entry; open the content list matching the target identifier and reload, and read the platform status text.
  12. Use the account and the currently available entry ID / BV number, link, video filename, copy prefix, submission time, cover, and other combined fingerprints to find the unique entry. Record the list status, entry link or ID, readback time, and page URL. Bilibili's management page rejects direct links (upload-manager/all and /season will jump back to the homepage); enter from the sidebar. For Bilibili, also read back view.data.title、view.data.desc、view.data.pic and x/tag/archive/tags.data[].tag_nameseparately; verify the first three items word-for-word/visually against the frozen final draft, accept public tags as a set, and do not infer from whether # appears in the description. When public fields are missing, edit only the same BV and resubmit once; do not create a duplicate submission.

State contract

Use only the following values for states; when an error occurs, keep the last confirmed state and list the error separately:

State Evidence of establishment
prepared The platform and account have been verified, the inputs required for the action are complete; the write action has also passed a read-only precheck
uploading The page shows actual upload progress for this file
processing Upload is complete, and the platform is still transcoding, parsing, or generating the cover
awaiting_confirmation Only publish: all items in the field table pass, the user has been notified and the final draft has been handed to him for review, waiting for explicit consent
draft_saved After the draft list is reloaded, a unique matching entry is found
scheduled After the content list is reloaded, a matching entry and the correct scheduled time/status are found
platform_pending After the content list is reloaded, a unique entry is found, and the status is clearly transcoding, under review, or publishing in progress
published After the content list is reloaded, a matching entry is found, and the list clearly shows a published/posted status
publish_failed After the content list is reloaded, a unique entry is found, and the list clearly shows a failed, rejected, or terminated status

A success prompt, the button disappearing, a request returning, or a page redirect do not by themselves prove published. When there is no list reload readback, stay at the last proven state. For Bilibili, the public view of title / desc / pic must also be used to prove that the final draft and the 16:9 cover have really been persisted; do not substitute an in-form preview or success page.

Closing errors

  • When there is a timeout or the status is unclear after submission, do not click publish again; first go to the content list to reload and read back, to prevent duplicate content.
  • Once the main submit button enters the loading state, the page navigates, or a success prompt appears, it is considered that a submission has been attempted; afterward, only read back the list.
  • When upload or processing fails, record the page's original text, file name, pre-check summary, account, current URL, last status, and time of occurrence; keep the source video unchanged.
  • When the page shows a transcoding failure (e.g., "Video transcoding failed. Adjust the video export parameters and try again"), this is a server-side rejection, not a network problem: re-uploading the same file will only fail once more. First verify that the file size and duration are indeed within the limits shown on the page, then follow re-compression plan to eliminate pre-check deviations, re-compress, and re-verify.
  • When the same material is re-submitted, both the old entry and the new entry will exist in the list at the same time, and the file name, duration, and first frame will be completely identical. In this case, it is forbidden to use these fields as a fingerprint; instead use the submission time, title, topic combination, new cover, or entry ID / BV number; if they cannot be distinguished, keep the last confirmed status and report all candidates. Whether to delete the old entry is decided by the user.
  • When the page structure changes, re-acquire the snapshot and locate by role, visible name, tag, and nearby text; when there are multiple candidates, stop clicking and report the candidates.
  • A control not being found does not mean the control does not exist: the video account's form is inside the <wujie-app> shadow root, document.querySelector always returns empty without error, and it is easy to read this as "not rendered yet" and waste several rounds waiting; the file input cannot even be found in the shadow root, and only DOM.getDocument({ pierce: true }) can see it. Bilibili does not have this problem, but instead has "Vue does not accept synthetic events." The respective locator tables and reusable probes are in the two page-anatomy documents.
  • The video account's popups are pre-rendered; filter by visibility rather than existence: about 35 popups are all in the DOM, hidden only by size. Reading .weui-desktop-dialog 's innerText will get text unrelated to the current state (observed instance: after uploading a cover, it read "Keep this edit?", but there was no such popup on the screen), and clicking a button based on that is clicking nothing. Use getBoundingClientRect().width > 100 to filter.
  • No response after clicking and no error: do not retry the same click method; first determine whether it fell outside the viewport (scroll it into view and then click according to the new rect), or whether the control only accepts a real mouse (use cdp('Input.dispatchMouseEvent', ...)). Observed instance: Bilibili reported deleting 12 tags, but in fact not a single one was removed.
  • If the list shows processing text such as "Originality under review", "Under review", or "Transcoding", use platform_pendingfor the status, even if a success prompt has appeared or it has already navigated to the list, do not write it as published。
  • When the user has not replied to the final draft confirmation,awaiting_confirmation is the final status of this task; report it truthfully—this is not a failure, and do not switch to draft or approve it yourself just to wrap up. At this point, keep the task space and the page.
  • When the user reports that they have modified and published it themselves, it is forbidden to click the main submit button again, and it is also forbidden to overwrite the page with the old field table; afterward, only read back the content list. If the list has not yet been read back, state "the user reports it has been published, but the platform status has not been verified"; do not falsely report published。
  • When the user explicitly requests at any stage of the task "do not close after publishing" or "keep the page for review", that request remains in effect until explicitly revoked. To wrap up, you must use completeTaskSpace(task.id, { keep: true }) and check the returned done。
  • Finally report the platform, target action, account, final status, original platform status text, list read-back evidence, warnings, and unfinished items. Use it only when the status contract is satisfied draft_saved / scheduled / platform_pending / published / publish_failed. The Bilibili report must additionally state that the submission is still editable; do not say this for WeChat Channels.

For the division of labor with adjacent Skills and what not to do, see Combination decisions。