All notable changes to this project are documented here.
The format follows Keep a Changelog, and the project adheres to Semantic Versioning.
- Quality-gate subagents in the bundled skill. SKILL.md now instructs the host agent to spawn two narrow subagents during clip recording: a per-slide caption verifier (Step 3.5) that runs after every
slideshow_add_slideand forces correction viaslideshow_update_slidewhen the caption drifts from the screenshot, and a whole-script reviewer (Step 4.5) that runs once beforeslideshow_set_summaryand catches voice / banned-phrase / opener-shape drift across the whole clip. Both prompts are hardcoded in SKILL.md as copy-pasteable blocks following the MJ1 grounded-verification chain (enumerate visible elements before scoring) for the verifier and a SKILL.md-rubric-driven check for the reviewer. - Visual-vet rule at the top of Step 3 — even before the subagent fires, the captioning agent must Read the screenshot file before writing the caption. Free intermediate that helps on hosts that can't spawn subagents.
- Anti-patterns section gains four new entries directly tied to the quality gates: don't put captioning itself in a subagent (loses visual grounding), don't run verifiers in parallel, don't feed the verifier a text description instead of the image bytes, don't loop on verifier rejections (single-pass max).
- Tool reference table footer clarifies that quality-gate subagents are not shipped as MCP tools by design — they run in the host's existing model context, no model-API dependency for agentclip-python.
Three of five captions on the v0.app hero clip (UisOCaH5UbO-yKcn, recorded 2026-05-09) drifted from what was actually pixel-visible — the caption claimed "no template picker" while one was on screen, claimed four components when only two were in the rail, claimed "version one is done" while the right panel still rendered "Creating dashboard page". The clip shipped to a public URL before the user caught the drift in manual audit. Discipline rules don't fix that; structural gates do. Rationale and architecture decisions are in docs/brainstorms/2026-05-09-quality-gates-and-subagents-requirements.md and docs/plans/2026-05-09-001-feat-quality-gates-and-subagents-plan.md.
pip install --upgrade agentclip
agentclip install-skill --force # refreshes ~/.claude/skills/agentclip/SKILL.md
# restart Claude Code so the new skill loads
No Python code changed. No MCP tool surface changed. No API changes. Pure skill update bundled with the package.
browser_*MCP tools crashed under the live FastMCP server withIt looks like you are using Playwright Sync API inside the asyncio loop. Tools were sync, FastMCP runs handlers under asyncio, Playwright sync refuses to coexist. Everybrowser_opencall against the running server failed on its first line. The pytest suite missed it because tests called the tool functions directly, bypassing FastMCP's async wrapper.- Each
browser_*tool is now an async @mcp.tool wrapper that delegates the actual Playwright work to a sync_*_implhelper, run inside a dedicated single-threadThreadPoolExecutor. The thread has no event loop, so sync_playwright works there; reusing the same thread across calls is required because Playwright sync objects are thread-bound. - New
test_browser_tools_are_async(structural — every browser_* must beiscoroutinefunction) andtest_async_open_screenshot_close_under_event_loop(drives the wrapper throughasyncio.run) pin the regression. The existing tests now call_*_implhelpers directly so both layers stay covered.
- First-run setup now auto-registers the MCP server in
~/.claude/mcp.json. Closes the last manual step in onboarding —pip install agentclipfollowed by a Claude Code restart is now the entire setup. The install is idempotent and preserves any other MCP servers you have registered. agentclip install-mcpCLI command — re-runs the registration on demand (after a config reset, a different config path via--config, etc.). HonorsAGENTCLIP_MCP_CONFIGfor non-default Claude Code installs and tests.agentclip uninstall-mcpCLI command — removes the agentclip entry. No-op when the file or entry isn't present. Other servers untouched.
- Eager Chromium install removed from first-run setup — it became dead code in 0.5.0 when Chromium install moved to lazy-on-first-
browser_open. Setup is now skill install + MCP registration + marker write.
__version__now reads from package metadata viaimportlib.metadatainstead of a hardcoded constant, soagentclip versionalways reflects what's actually installed. Hardcoded value had drifted four releases behind.
pip install agentclipnow bundles Playwright by default. The[browser]extra was scaffolding from when the MCP server was slideshow-only; now that browser primitives are the canonical capture path, hiding them behind an extra was friction every dogfooder hit on first run. Single install command, the canonical path works out of the box.- Chromium binaries (~200MB) install lazily on first
browser_opencall, not atpip installtime. First browser-tool use takes ~1 minute to download Chromium; every subsequent call is near-instant. CI / non-browser users who never callbrowser_opennever pay the Chromium cost. [browser]extra is preserved as an empty alias sopip install 'agentclip[browser]'(in old docs, install scripts, dotfiles) still resolves cleanly.SKILL.mdandCLAUDE.mdscrubbed of[browser]install instructions — they're docs noise now that the deps are core.
If you previously installed with pip install 'agentclip[browser]', that command still works exactly the same. If you previously installed with pip install agentclip and then needed to add the extra later, that step is gone — bare install is enough.
- Browser primitives in the MCP server. Ten new tools —
browser_open,browser_navigate,browser_type,browser_click,browser_press_key,browser_wait_for_text,browser_screenshot,browser_get_text,browser_close,browser_list_sessions— drive a Playwright Chromium instance from any MCP-speaking agent.browser_screenshotwrites a viewport-only PNG to disk and returns the path; you pass that path straight intoslideshow_add_slide. Sessions are scoped to the MCP server lifetime and torn down at exit. Closes the dogfood gap where agents had no canonical way to capture screenshots and would fall back to OS-level screencapture (which leaks IDE / terminal / chat windows to the public clip URL — a privacy bug). run_typeparameter on theslideshow_createMCP tool. The SDK already accepted it; the MCP tool didn't expose it, which forced agents to usewalkthrough(the server-side default) regardless of trigger phrasing.
SKILL.md"Browser tooling" section now names the agentclip-mcpbrowser_*tools as Method 1 (the canonical path), with a worked example. Other browser MCPs and scripted Playwright remain as fallbacks.CLAUDE.mddocuments how to register the agentclip-mcp server in~/.claude/mcp.json(and the local-checkout variant for development).
0.3.2 - 2026-05-07
Fix: pip install agentclip was broken out of the box. The default backend URL pointed at the marketing host, which 308-redirects /api/* and Cloudflare strips the body — so every slideshow create failed with expected 201. Default now points at the API host directly.
DEFAULT_BASE_URLnow resolves tohttps://api.agentclip.dev(washttps://agentclip.dev). The marketing host doesn't forward/api/*to the Django service; the trailing-slash redirect plus Cloudflare's body-strip on 308 made every CLI/SDK write fail. Existing users who exportedAGENTCLIP_BASE_URLare unaffected.
- No API or schema changes. Drop-in replacement for 0.3.1.
0.3.1 - 2026-05-07
Skill rewrite: caption + intro + outro guidance is now run-type-aware. Same content, different run_type, totally different voice.
SKILL.mdStep 4 (captions) replaced the universal "action + expectation + result" rule with five explicit voice profiles — one per run_type — each with concrete good examples. Bug repros stay terse and stack-trace-adjacent. Demos read like a presenter narrating in present tense, with no setup or recap. Onboarding evals are observational. Competitive teardowns are analytical with named comparisons.SKILL.mdStep 2 (description = spoken intro) gets per-run-type opener examples. Demo intros explicitly ban "Welcome to...", "Today we'll be looking at...", "I'm excited to show you..." — the MP4 starts where the action is.SKILL.mdStep 6 (summary = spoken outro) gets per-run-type wrap examples. Demos land the value in one sentence, not a recap.- New anti-patterns called out by name: corporate-presenter cringe, court-reporter past tense in demos, buzzword filler (seamless, robust, leverage), as-we-can-see-isms.
- Added a second worked example contrasting the same flow recorded as
smoke_test(QA log) vsdemo(presenter). Makes the run-type → voice mapping concrete.
- No code changes. Backend pipeline is unchanged. This release is entirely about the prompt the bundled skill plants in the agent — better prompt, better captions, better narration.
- Run
agentclip install-skill --forceto refresh the cached skill on a previously-installed system.
0.3.0 - 2026-05-07
The walkthrough release. Backend now produces a clip that opens with a brand title card + spoken intro and closes with an end card + spoken outro, with the narration voice picked automatically from the clip's run_type. The CLI/SDK exposes the new knobs and adds an explicit narrate command for force-regeneration use cases.
agentclip slideshow create --type/-T <run_type>— sets the clip's run type at create time. Drives the narration voice + pacing for the whole rendered MP4 (intro + every slide + outro share one voice). Values:bug_repro(onyx),smoke_test(nova),demo(shimmer, slightly slower),onboarding_eval(nova),competitive_teardown(echo),generic(default, nova).agentclip slideshow narrate <id_or_token>— explicit CLI for narration. Accepts a slideshow_id (UUID) or a share_token. Flags:--voice,--force,--dry-run. In normal use you don't need this — hitting any clip's.mp4URL auto-narrates and renders. Use it for force-regeneration (e.g. trying a different voice on an already-narrated clip).AgentClipClient.narrate_slideshow()— SDK equivalent.run_typefield onSlideshowCreatedso the CLI/SDK can echo it back at create time.
- Bundled
SKILL.mdrewrite. Adds a Step 0 pre-flight that picks the spine + run_type from the trigger phrasing — agent only asks the user when the prompt is too ambiguous to map. Vocabulary shifts from "slideshow" to "clip" / "walkthrough" in user-facing prose; tool names + CLI command verbs unchanged. Caption guidance gets a "narration-friendly" addendum (em-dashes for natural pacing, complete sentences, jargon-free for a listener). Old "Filed by" framing dropped throughout. - CLI summary block at create time prints
created clip <id>instead ofcreated slideshow <id>. The CLI command structure (agentclip slideshow ...) is unchanged for backwards compatibility. agentclip whoami --set ...output drops the "Filed by" phrasing in favor of "X will be credited on every clip."
- Backwards-compatible. Older API versions that don't surface the new
run_typefield parse cleanly; the CLI flag just sends an extra payload key the older API ignores. - The narrate CLI command requires the local state store to have the clip's
write_tokencached. That's how clips are mutated in general — the credential is yours, not the platform's.
0.2.0 - 2026-05-07
The render-pipeline release. Backend now produces a server-rendered MP4, a branded PDF walkthrough, an OG-tagged poster image, and a chrome-less iframe embed page for every clip — all materialized lazily on first external fetch and pre-warmed on slideshow_set_summary. This package surfaces the artifact URLs at the CLI/SDK boundary so agents can hand them straight off.
clip_mp4_url,clip_pdf_url,embed_url(andedit_url) on theslideshow_createresponse model. Surfaced in the CLI's create-summary output asmp4:,pdf:, andembed:lines so the agent can echo them into PR descriptions, Slack messages, or wherever the user is going to paste them.slideshow_set_summarysummary block echoes the share +.mp4+.pdfURLs at the agent's "I'm done" moment, since that's the moment the renders pre-warm server-side and the URLs become useful.StateStore.get_share_urlso callers can resolve the cached share URL byslideshow_idwithout a server round-trip.
- Bundled
SKILL.mdupdated to walk through the four artifact surfaces (share, MP4 for GitHub, PDF for downloads, embed for iframes) and to clarify that narration is now automatic — agents do not callnarrateas a separate step.
- Backwards-compatible. Older API versions that don't surface the new fields parse cleanly; the artifact lines simply don't print.
0.1.0 - 2026-05-06
First public release. Backend is live at https://agentclip.dev; this package is the canonical client.
- Python SDK (
AgentClipClient) withcreate_slideshow,add_slide,update_slide,set_summary,delete_slideshow. - Typer CLI mirroring the SDK:
agentclip slideshow create | add | update | summary | delete | list, plusagentclip whoami,agentclip install-skill,agentclip setup,agentclip version. - MCP server (
agentclip-mcp) registering four tools:slideshow_create,slideshow_add_slide,slideshow_update_slide,slideshow_set_summary. - Bundled Claude skill at
src/agentclip/skill/SKILL.mdcovering when to screenshot, caption style, narrative arc, summary format, and anti-patterns. - Local state store at
~/.agentclip/state.jsonfor write_token persistence with atomic writes and 0600 permissions. Tracks slideshows, an optionalwhoamicreator credit (auto-applied to every new clip), and one-time CLI nudge flags. - Lazy first-run setup that wires the bundled Claude skill, downloads browser drivers if
[browser]is installed, and writes a marker so subsequent invocations are instant. Bypassed forversion,setup, andinstall-skillto keep them fast and non-recursive. - Optional
[browser]extra pulling Playwright for standalone CLI users; agent runtimes that bring their own browser substrate skip it by default. - 65-test suite covering SDK wire shapes (httpx MockTransport), state persistence, CLI flow, and lazy setup.
justfilewithtest,lint,format, and a guardedreleaserecipe that enforces version match + changelog block + clean tree before tagging.
- Default backend URL:
https://agentclip.dev. Override withAGENTCLIP_BASE_URLfor self-hosted deploys. - v0.1 has no account flow; the
write_tokenreturned at create time is the only credential. Cache it via the state store or pass it explicitly.