| name | medium-browser-publisher |
| description | Use this skill when the user has explicitly approved a drafted Medium article and it needs to be published through browser automation. Load the latest draft, verify the authenticated Medium editor state with browser snapshots, publish conservatively, and return the verified live URL over WhatsApp. |
| user-invocable | true |
| cron-invocable | false |
Medium Browser Publisher
Publish a previously drafted Medium article using browser automation with a persistent profile. This skill is the final publication step and must behave conservatively.
When to Use This Skill
Use this skill when:
- a current draft exists and the user clearly said
publish, approve, post, or similar
- the pipeline is in an approval-complete state and needs final Medium publication
- a live URL must be produced and confirmed
Do not use this skill to write drafts, choose topics, or infer approval from ambiguous messages.
Mission
Take an approved draft, open Medium's new-story flow, populate the article, publish it, and return the live URL to the user.
Your priorities are:
- accuracy
- safety
- idempotence
- explicit verification before publishing
Preconditions
Do not publish unless all of the following are true:
- a draft exists in shared memory or is provided directly
- the user has clearly approved publishing
- a persistent browser profile is available
- the Medium session appears authenticated
If any precondition is missing, stop and ask for the missing piece.
Shared Memory Contract
Read from:
- namespace:
tech-medium-pipeline
- key:
latest_draft
- namespace:
tech-medium-pipeline
- key:
conversation_state
If available, expect fields equivalent to:
{
"title": "Draft title",
"subtitle": "Draft subtitle",
"body_markdown": "# Title\n...",
"tags": ["AI", "Startups"],
"featured_image_path": "/path/to/image.png",
"markdown_path": "/Users/.../drafts/2026-04-04-topic.md"
}
featured_image_path may be null if image generation was skipped or failed during drafting. Treat null and a missing key identically: skip the image upload step and proceed to publish without a hero image. Do not block publication because an image is absent.
After a successful publish, write back to:
- namespace:
tech-medium-pipeline
- key:
latest_publication
- namespace:
tech-medium-pipeline
- key:
conversation_state
Use a structure equivalent to:
{
"published_at": "ISO-8601 timestamp",
"title": "Published title",
"url": "https://medium.com/...",
"tags": ["AI", "Startups"],
"source_markdown_path": "/Users/.../drafts/2026-04-04-topic.md"
}
Set conversation state to:
{
"phase": "published",
"last_action": "article_published",
"last_updated_at": "ISO-8601 timestamp"
}
Browser Requirements
Use the browser tool with a persistent profile. The browser session should preserve the user's Medium login.
Always use browser.snapshot before and after important state-changing actions, especially:
- after loading Medium
- before typing into any major field
- after inserting title and subtitle
- after pasting the article body
- after opening the publish flow
- after confirming tags
- after final publish
Do not blindly click through unknown UI states. Snapshots are mandatory evidence.
Defaults and Gotchas
- Default to stopping when login state, draft identity, or approval state is unclear.
- Medium's editor can change over time; rely on visible labels and fresh snapshots, not brittle assumptions.
- If Medium lacks a dedicated subtitle field, place the subtitle as a standfirst below the title instead of dropping it.
- A saved draft is not a published article; only a verified live story URL counts as success.
Publication Flow
Step 1: Load Medium
Open:
https://medium.com/new-story
Verify via snapshot that:
- the user is logged in
- the editor is visible
- the page is interactive
If Medium shows a login wall or onboarding interruption:
- do not continue as if published
- ask the user to restore the login session
Step 2: Resolve Article Components
Prepare the content before typing:
- title
- subtitle
- body markdown
- tags
- featured image path if provided
If the draft is missing a subtitle, derive one that matches the article.
If Medium does not expose a dedicated subtitle field, insert the subtitle as a short standfirst immediately below the title at the top of the story body.
If the tags list exceeds Medium's UI limits, keep the most relevant tags first.
Step 3: Insert Content Carefully
Populate the story in this order:
- title
- subtitle in Medium's subtitle field when available, otherwise as the first standfirst line below the title
- body markdown or editor content
- featured image if provided
- publish metadata such as tags
When pasting body content:
- preserve readable structure
- keep headings and paragraphs intact
- verify formatting in the editor after insertion
If Medium does not accept raw Markdown cleanly:
- paste in the cleanest editor-compatible form available
- preserve semantic structure rather than exact Markdown syntax
Step 4: Pre-Publish Safety Check
Before pressing the final publish button, verify from the browser state that:
- the title is correct
- the body is present and non-empty
- the draft is the intended article
- the user approval is explicit and recent
- the correct tags are entered
If anything looks wrong, stop and fix it before publishing.
Step 5: Publish
Complete the final publish action only after the safety check passes.
Then:
- wait for navigation or publish confirmation
- capture another snapshot
- extract the live article URL
- confirm the URL is a real Medium story URL, not a draft or editor URL
Featured Image Handling
If a valid image path is provided:
- upload it through the Medium editor UI
- verify the image appears in the story
If no image is provided:
- proceed without blocking publication
- do not invent an image file
WhatsApp Delivery
After success, send a concise WhatsApp message that includes:
- the published title
- the live Medium URL
- a short confirmation that the article is now live
If stats are visibly available at publish time, include them. Example categories:
- estimated read time
- tags used
- publication destination if visible
Do not invent analytics that are not shown.
Failure Handling
- If the Medium UI changes, rely on fresh snapshots and visible labels instead of brittle assumptions.
- If publishing fails mid-flow, preserve the draft and report the exact blocking point.
- If the URL cannot be extracted, search the current page state and recent navigation before reporting failure.
- If the editor appears to autosave but not publish, treat that as not published.
Guardrails
- Never publish without explicit approval.
- Never claim the post is live without a verified live URL.
- Never overwrite a different draft if the editor already contains unrelated content.
- Never continue through unclear dialogs or warnings without understanding them from the snapshot.
- Never fabricate stats.
Completion Checklist
Before ending:
- Confirm explicit approval exists.
- Confirm the Medium editor loaded in an authenticated session.
- Take required snapshots before and after major actions.
- Publish only after the pre-publish safety check passes.
- Extract and verify the live URL.
- Save publication metadata to shared memory.
- Send the result to the user on WhatsApp.