<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Tap</title>
  <link>https://taprun.dev/</link>
  <description>Browser automation that runs in your browser, not someone else's cloud. Compile once, run forever, diff the drift.</description>
  <language>en-us</language>
  <atom:link href="https://taprun.dev/feed.xml" rel="self" type="application/rss+xml" />
  <lastBuildDate>Mon, 01 Jun 2026 07:06:41 +0000</lastBuildDate>
  
  
  <item>
    <title>Why your Playwright scraper keeps getting logged out</title>
    <link>https://taprun.dev/blog/playwright-keeps-getting-logged-out.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/playwright-keeps-getting-logged-out.html</guid>
    <description>The three things a &apos;logged-in&apos; web session actually depends on, what Playwright&apos;s storageState captures and what it silently drops, and why the bug class disappears once you stop simulating the session and drive a real Chrome instead.</description>
    <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>What 44 capture traces taught us about SPA shells</title>
    <link>https://taprun.dev/blog/capture-trace-spa-shells.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/capture-trace-spa-shells.html</guid>
    <description>An audit of Tap&apos;s recent capture traces found that 34% were retry loops against single-page-app shells — same URL, three to five attempts, identical 200-OK empty bodies. Two ADRs and five commits later, the first-time success rate stopped depending on luck.</description>
    <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>Scraping behind login walls: stop fighting OTP, CAPTCHA, and Cloudflare Turnstile</title>
    <link>https://taprun.dev/blog/scrape-behind-login-walls.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/scrape-behind-login-walls.html</guid>
    <description>r/webscraping keeps asking the same architectural question — how to scrape past OTP, CAPTCHA, Cloudflare Turnstile, Incapsula. The cheapest answer is to stop fighting detection and use your real authenticated browser instead.</description>
    <pubDate>Sat, 16 May 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>Notes from playwright-mcp #1530: named browser sessions need typed manifests</title>
    <link>https://taprun.dev/blog/playwright-mcp-named-sessions-engineering-notes.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/playwright-mcp-named-sessions-engineering-notes.html</guid>
    <description>A feature request to add named, persistent BrowserContexts to playwright-mcp surfaces a deeper problem: once sessions are first-class objects, the manifest describing them needs a stable schema before it grows a long tail of consumers.</description>
    <pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>How We Turned Tap&apos;s Engine Into a 0.8 ms Library (and Measured a 294× Speedup)</title>
    <link>https://taprun.dev/blog/taprun-executor-0-8-ms-library.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/taprun-executor-0-8-ms-library.html</guid>
    <description>Tap spent three months as a compiled binary that every embedding product had to shell out to. We extracted the composition engine into @taprun/executor — a Deno-first, zero-dep, 65KB package that runs pipes in-process. Measured against the old subprocess path on the same pipeline: 0.8 ms vs 233.7 ms. 294× faster, zero semantic change, full backwards compatibility. Here&apos;s why the extraction matters for every product that wraps an LLM.</description>
    <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>Four Rounds, Two Trace-Driven Fixes, One Working Pipe</title>
    <link>https://taprun.dev/blog/tap-trace-found-the-bug-in-our-reference-pipe.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/tap-trace-found-the-bug-in-our-reference-pipe.html</guid>
    <description>We shipped tap.explain, forge.pipe, and tap.trace in one session. The first real demo composed a pipe in Claude Code, saved it, ran it against live Reddit, failed, and iterated through four rounds to a working version — every fix driven by a specific piece of trace data, every round still zero external AI cost. Along the way we found the same silent bug sitting in our hand-written reference pipe.</description>
    <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>How Reddit Demand Kit Turned a $0.15 LLM Call Into a $0 Compiled Pipe</title>
    <link>https://taprun.dev/blog/rdk-compiled-pipes-from-llm-prompts.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/rdk-compiled-pipes-from-llm-prompts.html</guid>
    <description>Reddit Demand Kit&apos;s market_scan tool burns 26,000 LLM tokens every time a user runs it — $0.15 per call, $135/month for a heavy user. We compiled the prompt into a deterministic JavaScript pipeline that produces the same structured output with zero LLM tokens per run. Break-even: 0.46 of a single invocation. Here&apos;s how we did it with Tap&apos;s new composition DSL, and why every LLM-wrapping product should steal this pattern.</description>
    <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>Composable Taps Are Just JavaScript: Why Tap&apos;s Pipeline DSL Doesn&apos;t Need YAML</title>
    <link>https://taprun.dev/blog/composable-taps-are-just-javascript.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/composable-taps-are-just-javascript.html</guid>
    <description>GitHub Actions pipelines are YAML. Kubernetes is YAML. CircleCI, Airflow, n8n — all YAML. When we designed Tap&apos;s composition DSL, the convention was obvious. We picked JavaScript instead, and it&apos;s strictly better for every argument YAML is usually chosen for: diff-friendly, AI-generatable, type-checked, debuggable. Here&apos;s the full breakdown with real before/after code from migrating Tap&apos;s bounty/match composite tap.</description>
    <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
  <item>
    <title>40 Commits to Ship a Chrome MV3 Extension: A Git Log Retrospective</title>
    <link>https://taprun.dev/blog/building-mv3-extension-git-log-retrospective.html</link>
    <guid isPermaLink="true">https://taprun.dev/blog/building-mv3-extension-git-log-retrospective.html</guid>
    <description>Building Tap&apos;s Chrome extension meant fighting Chrome MV3 for three months — service worker termination, chrome.alarms&apos; silent 1-minute floor, the 25-second timeout cap, chrome.storage.session as the only durable state, the CDP debugger-attached bar, the unsafe-eval ban, and tab stealing across sessions. A category-by-category tour of forty-ish real commits that got Tap to ship.</description>
    <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
    <author>noreply@taprun.dev (Leon Ting)</author>
  </item>
  
</channel>
</rss>
