<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Duc Vo</title>
    <description>The latest articles on DEV Community by Duc Vo (@vovanduc).</description>
    <link>https://dev.to/vovanduc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F102870%2F15bab91b-ed90-48c5-847d-8dd0d1d9cbc9.jpg</url>
      <title>DEV Community: Duc Vo</title>
      <link>https://dev.to/vovanduc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vovanduc"/>
    <language>en</language>
    <item>
      <title>Instant static staging without an account: tearing down Cloudflare Drop and building stage-drop</title>
      <dc:creator>Duc Vo</dc:creator>
      <pubDate>Tue, 06 Oct 2026 08:49:57 +0000</pubDate>
      <link>https://dev.to/vovanduc/instant-static-staging-without-an-account-tearing-down-cloudflare-drop-and-building-stage-drop-46ep</link>
      <guid>https://dev.to/vovanduc/instant-static-staging-without-an-account-tearing-down-cloudflare-drop-and-building-stage-drop-46ep</guid>
      <description>&lt;p&gt;&lt;em&gt;Inspired by &lt;a href="https://www.cloudflare.com/drop/" rel="noopener noreferrer"&gt;Cloudflare Drop&lt;/a&gt; (&lt;a href="https://www.cloudflare.com/drop/llms.txt" rel="noopener noreferrer"&gt;llms.txt&lt;/a&gt;). This post is an independent product teardown and open-source clone — not reverse-engineering of proprietary internals.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Drop a folder. Get a live URL. Claim it in sixty minutes or watch it vanish.&lt;/p&gt;

&lt;p&gt;That is the pitch of &lt;a href="https://www.cloudflare.com/drop/" rel="noopener noreferrer"&gt;Cloudflare Drop&lt;/a&gt;: instant static-site staging on the edge, no account required to start. For builders shipping previews, and for AI agents that need a deploy target with almost no ceremony, the product hits a nerve.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;Part 1&lt;/strong&gt; of a four-part series. Today: product teardown + a portable open-source clone you can run locally in about five minutes. Next posts take the same codebase to Cloudflare Workers, then AWS, then an agent-first surface (llms.txt + MCP).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clone:&lt;/strong&gt; &lt;a href="https://github.com/vovanduc/stage-drop" rel="noopener noreferrer"&gt;github.com/vovanduc/stage-drop&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The ten-second experience
&lt;/h2&gt;

&lt;p&gt;Public behavior (observed from the product page and &lt;a href="https://www.cloudflare.com/drop/llms.txt" rel="noopener noreferrer"&gt;llms.txt&lt;/a&gt;, not from private source):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You drop a folder or &lt;code&gt;.zip&lt;/code&gt; of a static site (HTML/CSS/JS, with an &lt;code&gt;index.html&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Cloudflare distributes it on the global network.&lt;/li&gt;
&lt;li&gt;You get a live &lt;code&gt;workers.dev&lt;/code&gt; URL.&lt;/li&gt;
&lt;li&gt;Within &lt;strong&gt;60 minutes&lt;/strong&gt;, you must open a &lt;strong&gt;claim URL&lt;/strong&gt; to keep the deployment. Miss the window and the temporary preview goes away.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is also a first-class CLI path: &lt;code&gt;wrangler deploy … --temporary&lt;/code&gt; (Wrangler ≥ 4.102.0) for local project workflows. Authenticated Wrangler uses a normal deploy — temporary mode is for the zero-account funnel.&lt;/p&gt;

&lt;p&gt;Two URLs come back every time: the &lt;strong&gt;live&lt;/strong&gt; URL (shareable preview) and the &lt;strong&gt;claim&lt;/strong&gt; URL (sensitive ownership grant). Treat the claim link like a password with a TTL.&lt;/p&gt;

&lt;p&gt;That loop is the whole product. Everything interesting — abuse resistance, metadata TTL, agent docs — hangs off it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Product lens: why ship a free tool with no login?
&lt;/h2&gt;

&lt;p&gt;From a product lead's perspective, Drop looks less like a side toy and more like a &lt;strong&gt;funnel + positioning&lt;/strong&gt; play:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero friction into Workers.&lt;/strong&gt; The first deploy does not ask for OAuth. The second action (claim) creates ownership. That is classic "try before you commit," tuned for static assets on Workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Experience (AX) as a first-class user.&lt;/strong&gt; Shipping an &lt;a href="https://www.cloudflare.com/drop/llms.txt" rel="noopener noreferrer"&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/a&gt; that tells agents how to upload, what to return, and how to prefer Wrangler over browser automation is a signal: AI agents are not an afterthought; they are a primary audience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Toolchain honesty.&lt;/strong&gt; Temporary deploy lives inside Wrangler, not only in a marketing UI. The web drop zone and the CLI share one mental model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hard product trade-off is obvious: &lt;strong&gt;zero-auth upload&lt;/strong&gt; versus &lt;strong&gt;abuse, phishing, and claim-token theft&lt;/strong&gt;. Production Drop must sit on Cloudflare's edge controls, rate limits, and account systems. A teaching clone should name that gap instead of pretending a weekend demo is a CDN.&lt;/p&gt;




&lt;h2&gt;
  
  
  Inferred architecture (behavior-only)
&lt;/h2&gt;

&lt;p&gt;This is &lt;strong&gt;inference from public behavior and docs&lt;/strong&gt;, not a claim about Cloudflare's internal implementation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;th&gt;What public behavior suggests&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compute&lt;/td&gt;
&lt;td&gt;Edge Workers (live URL on &lt;code&gt;workers.dev&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blobs&lt;/td&gt;
&lt;td&gt;Object storage for unzipped static files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadata&lt;/td&gt;
&lt;td&gt;TTL-aware record: site id, expiry, claim state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claim&lt;/td&gt;
&lt;td&gt;One-shot secret; grant ownership / clear temporary expiry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cleanup&lt;/td&gt;
&lt;td&gt;Something that reaps unclaimed expired deploys&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CLI temporary deploy and the browser UI both emit live + claim URLs, so the control plane is shared even if the upload path differs.&lt;/p&gt;

&lt;p&gt;What we deliberately do &lt;strong&gt;not&lt;/strong&gt; do: decompile Workers, scrape private APIs, or copy UI/branding. The clone is &lt;strong&gt;inspired-by&lt;/strong&gt;, with its own interfaces and security choices.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design of stage-drop: portable core + adapters
&lt;/h2&gt;

&lt;p&gt;The technical thesis of the series is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One TypeScript core. Swap storage adapters. Same upload / claim / serve / expire semantics on laptop, Cloudflare, and AWS.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Web UI / curl]
       |
       v
+-----------------+     +------------------------+
|  Core (Hono)    |----&amp;gt;| BlobStore (interface)  |  local FS | R2 (#2) | S3 (#3)
|  upload/claim   |     +------------------------+
|  serve/expire   |----&amp;gt;| MetaStore (interface)  |  memory   | KV (#2) | DynamoDB TTL (#3)
+-----------------+     +------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why Hono?&lt;/strong&gt; It runs on Node for local demos and on Workers / Lambda-style runtimes later without rewriting the HTTP surface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why interfaces?&lt;/strong&gt; Parts 2 and 3 should be adapter work, not a rewrite. That is how you get an honest Cloudflare-vs-AWS comparison on the same product semantics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three hard decisions (local demo)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Claim tokens&lt;/strong&gt; — Generate &amp;gt;=128-bit random tokens; store &lt;strong&gt;SHA-256 hashes only&lt;/strong&gt;; one-shot consume. The raw token lives in the claim URL, never in durable storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTL lifecycle&lt;/strong&gt; — Unclaimed sites expire (~60 minutes). Serve returns &lt;strong&gt;410 Gone&lt;/strong&gt; after expiry. A periodic sweep deletes blobs + meta for expired unclaimed sites. Claim clears expiry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abuse floor&lt;/strong&gt; — Zip &amp;lt;=10 MB, &amp;lt;=500 files; zip-slip blocked; content-type allowlist by extension; in-memory IP rate limit on upload. Explicitly &lt;strong&gt;not&lt;/strong&gt; included: malware scan, phishing heuristics, CAPTCHA. Those belong in a real edge product.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Architecture (lab + clone)
&lt;/h2&gt;

&lt;p&gt;The lab Worker at &lt;a href="https://lab.vovanduc.tech/stage-drop/" rel="noopener noreferrer"&gt;&lt;code&gt;lab.vovanduc.tech/stage-drop/&lt;/code&gt;&lt;/a&gt; uses the same core with &lt;strong&gt;R2&lt;/strong&gt; for unzipped files and &lt;strong&gt;KV&lt;/strong&gt; for metadata. Key layout:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Store&lt;/th&gt;
&lt;th&gt;Key pattern&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;R2 &lt;code&gt;stage-drop-blobs&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sites/{id}/...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Static files after unzip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV &lt;code&gt;META&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;meta:{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Site record (claimed?, expiresAt, ...)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claim:{sha256}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One-shot claim lookup (hash only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;exp:{expiresAt}:{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sweep index for unclaimed TTL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;TTL:&lt;/strong&gt; unclaimed sites expire after &lt;strong&gt;60 minutes&lt;/strong&gt;. &lt;strong&gt;Cron:&lt;/strong&gt; Worker trigger &lt;code&gt;*/5 * * * *&lt;/code&gt; runs &lt;code&gt;sweepExpired&lt;/code&gt; (delete R2 objects + KV keys for expired unclaimed sites). Health: &lt;a href="https://lab.vovanduc.tech/stage-drop/health" rel="noopener noreferrer"&gt;&lt;code&gt;/stage-drop/health&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Request flow
&lt;/h3&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
  U["Upload zip"] --&amp;gt; V["Unzip + validate"]
  V --&amp;gt; R2["R2 sites/{id}/"]
  V --&amp;gt; KV["KV meta:{id} · claim:{sha256} · exp:{expiresAt}:{id}"]
  KV --&amp;gt; URL["liveUrl + claimUrl"]
  S["GET /s/:id"] --&amp;gt; M["Lookup meta"]
  M --&amp;gt;|ok| SR["Serve from R2"]
  M --&amp;gt;|unclaimed expired| G["410 Gone"]
  C["Claim token"] --&amp;gt; H["SHA-256 → claim:{hash}"]
  H --&amp;gt; CL["claimed=true · expiresAt=null · delete exp: · rotate hash"]
  CR["Cron */5"] --&amp;gt; SW["sweepExpired → delete R2 + KV"]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Site state machine
&lt;/h3&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;stateDiagram-v2
  [*] --&amp;gt; LiveUnclaimed: upload
  LiveUnclaimed --&amp;gt; Claimed: claim one-shot
  LiveUnclaimed --&amp;gt; Expired: TTL 60 min
  Expired --&amp;gt; [*]: cron sweep
  Claimed --&amp;gt; [*]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Claim in plain language
&lt;/h3&gt;

&lt;p&gt;Upload returns two URLs. The &lt;strong&gt;live&lt;/strong&gt; URL is safe to share — anyone can view the preview while it is still alive. The &lt;strong&gt;claim&lt;/strong&gt; URL is the ownership grant: it carries a one-shot &amp;gt;=128-bit token. When you open it, the Worker hashes the token, looks up &lt;code&gt;claim:{sha256}&lt;/code&gt;, marks the site &lt;strong&gt;Claimed&lt;/strong&gt;, clears &lt;code&gt;expiresAt&lt;/code&gt;, deletes the &lt;code&gt;exp:&lt;/code&gt; index entry, and rotates the hash so the link cannot be replayed. Skip claim and, after 60 minutes, serve answers &lt;strong&gt;410 Gone&lt;/strong&gt;; within a few minutes the cron sweep removes blobs and meta.&lt;/p&gt;

&lt;p&gt;That is the whole lifecycle: &lt;strong&gt;LiveUnclaimed → Claimed&lt;/strong&gt; (keep forever on this demo) or &lt;strong&gt;LiveUnclaimed → Expired → swept&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Run the local demo (&amp;lt;=5 minutes)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/vovanduc/stage-drop.git
&lt;span class="nb"&gt;cd &lt;/span&gt;stage-drop
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm &lt;span class="nb"&gt;test&lt;/span&gt;          &lt;span class="c"&gt;# should be green&lt;/span&gt;
npm run dev       &lt;span class="c"&gt;# http://localhost:8787&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open the UI and drop a zip that contains &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;live URL&lt;/strong&gt; — files are served under &lt;code&gt;/s/:siteId/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;claim URL&lt;/strong&gt; within the TTL window. Token is one-shot; only a hash was stored.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or upload with curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zip &lt;span class="nt"&gt;-r&lt;/span&gt; site.zip index.html style.css
curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8787/api/upload &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/zip'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-binary&lt;/span&gt; @site.zip | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expect JSON with &lt;code&gt;liveUrl&lt;/code&gt; and &lt;code&gt;claimUrl&lt;/code&gt;. Hit live → HTML. Claim → site survives beyond the expiry sweep. Skip claim → eventually &lt;strong&gt;410&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vitest covers claim one-shot, TTL → 410, zip-slip rejection, size limits, and content-type serving. If &lt;code&gt;npm test&lt;/code&gt; is green, you have the same safety rails the README promises.&lt;/p&gt;

&lt;p&gt;Or skip local setup and open the &lt;strong&gt;live lab&lt;/strong&gt;: &lt;a href="https://lab.vovanduc.tech/stage-drop/" rel="noopener noreferrer"&gt;lab.vovanduc.tech/stage-drop/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Agent-friendly Cloudflare setup for anyone working on the repo (Claude, OpenCode, Orca, Cursor, ... — not host-locked):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/vovanduc/stage-drop/blob/master/docs/agent-setup.md" rel="noopener noreferrer"&gt;https://github.com/vovanduc/stage-drop/blob/master/docs/agent-setup.md&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What this clone teaches that a screenshot cannot
&lt;/h2&gt;

&lt;p&gt;Building the loop yourself forces the production questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where does expiry live — process sweep, cron, or datastore TTL?&lt;/li&gt;
&lt;li&gt;How do you serve path-prefixed sites (&lt;code&gt;/s/:id/...&lt;/code&gt;) without breaking relative assets?&lt;/li&gt;
&lt;li&gt;What is the minimum abuse bar before you are embarrassed in public?&lt;/li&gt;
&lt;li&gt;How do you document the product for humans &lt;strong&gt;and&lt;/strong&gt; agents without duplicating two truths?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those questions are the spine of the series. Local FS + in-memory meta answer them for a laptop. Cloud adapters must answer them again with real SLOs and bills.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next — Part 2
&lt;/h2&gt;

&lt;p&gt;Same core. Cloudflare adapters: &lt;strong&gt;Workers + R2 + KV&lt;/strong&gt;, Wrangler in-repo, and a live lab at:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://lab.vovanduc.tech/stage-drop/" rel="noopener noreferrer"&gt;https://lab.vovanduc.tech/stage-drop/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub Pages at &lt;a href="https://vovanduc.github.io/stage-drop/" rel="noopener noreferrer"&gt;vovanduc.github.io/stage-drop/&lt;/a&gt; is only a &lt;strong&gt;redirect to the repo&lt;/strong&gt; — not the upload API. The Worker owns upload/claim/serve.&lt;/p&gt;

&lt;p&gt;Part 3 mirrors the stack on AWS (S3 + CloudFront + Lambda + DynamoDB TTL) and compares cost / latency / DX. Part 4 makes the clone agent-first: llms.txt, HTTP API, MCP.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tip — try stage-drop
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Source / docs entry:&lt;/strong&gt; &lt;a href="https://vovanduc.github.io/stage-drop/" rel="noopener noreferrer"&gt;https://vovanduc.github.io/stage-drop/&lt;/a&gt; → redirects to the GitHub repo
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://lab.vovanduc.tech/stage-drop/" rel="noopener noreferrer"&gt;https://lab.vovanduc.tech/stage-drop/&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(Optional ops check: &lt;a href="https://lab.vovanduc.tech/stage-drop/health" rel="noopener noreferrer"&gt;https://lab.vovanduc.tech/stage-drop/health&lt;/a&gt;)&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare Drop&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.cloudflare.com/drop/" rel="noopener noreferrer"&gt;https://www.cloudflare.com/drop/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop llms.txt&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.cloudflare.com/drop/llms.txt" rel="noopener noreferrer"&gt;https://www.cloudflare.com/drop/llms.txt&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stage-drop repo&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/vovanduc/stage-drop" rel="noopener noreferrer"&gt;https://github.com/vovanduc/stage-drop&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages → repo&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vovanduc.github.io/stage-drop/" rel="noopener noreferrer"&gt;https://vovanduc.github.io/stage-drop/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Live lab&lt;/td&gt;
&lt;td&gt;&lt;a href="https://lab.vovanduc.tech/stage-drop/" rel="noopener noreferrer"&gt;https://lab.vovanduc.tech/stage-drop/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent setup (portable)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/vovanduc/stage-drop/blob/master/docs/agent-setup.md" rel="noopener noreferrer"&gt;https://github.com/vovanduc/stage-drop/blob/master/docs/agent-setup.md&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Official CF agent prompt&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developers.cloudflare.com/agent-setup/prompt.md" rel="noopener noreferrer"&gt;https://developers.cloudflare.com/agent-setup/prompt.md&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>cloudflare</category>
      <category>workers</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
