drivethrough-cli 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.mjs +29 -3
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -23869,7 +23869,7 @@ function registerTools(server, ctx) {
23869
23869
  "deploy_site",
23870
23870
  {
23871
23871
  title: "Deploy site",
23872
- description: "Deploy a site to Drivethrough. Idempotent: creates the site if needed, else ships a new version. Sites are private by default. Pass `files` with generated content (the platform assembles the bundle server-side \u2014 no local filesystem or build toolchain needed), or `directory` when this tool runs on the user's machine. Images and other binary assets \u2014 pick the route by where the bytes live: already at a public URL \u2192 {path, source_url} (fetched server-side); a local file \u2014 the user's, or an attachment already in your runtime \u2014 and no directory deploy here \u2192 create_upload first, then {path, upload_id}; a local project directory with filesystem access \u2192 `directory` carries binaries by itself; already deployed on this site \u2192 {path, from_path} copies it server-side (with delete_paths, a move). Never base64-encode a file, by hand or in code \u2014 inline base64 is capped at 1 MB and is only for tiny pasted assets; a file shipped via upload_id is referenced, never additionally inlined. To rework an already-deployed site, read it back with get_site first, then deploy with mode \"patch\" \u2014 only the files that change. For small text changes to existing files, use edit_site instead: it sends find/replace pairs, never whole files. Every deploy's version number is a restore point: prior versions stay listed (get_site history), diffable, viewable (preview_site), and returnable (revert_site).",
23872
+ description: "Deploy a site to Drivethrough. Idempotent: creates the site if needed, else ships a new version. Sites are private by default. Pass `files` with generated content (the platform assembles the bundle server-side \u2014 no local filesystem or build toolchain needed), or `directory` when this tool runs on the user's machine. Images and other binary assets \u2014 pick the route by where the bytes live: already at a public URL \u2192 {path, source_url} (fetched server-side); a local file \u2014 the user's, or an attachment already in your runtime \u2014 and no directory deploy here \u2192 create_upload first, then {path, upload_id}; a local project directory with filesystem access \u2192 `directory` carries binaries by itself; already deployed on this site \u2192 {path, from_path} copies it server-side (with delete_paths, a move). Never base64-encode a file, by hand or in code \u2014 inline base64 is capped at 1 MB and is only for tiny pasted assets; a file shipped via upload_id is referenced, never additionally inlined. To rework an already-deployed site, read it back with get_site first, then deploy with mode \"patch\" \u2014 only the files that change. For small text changes to existing files, use edit_site instead: it sends find/replace pairs, never whole files. Every deploy's version number is a restore point: prior versions stay listed (get_site history), diffable, viewable (preview_site), and returnable (revert_site). A successful deploy may still return `warnings` (e.g. a form type anonymous visitors can write with no page loading the Turnstile widget) \u2014 resolve them before telling the user it works.",
23873
23873
  // Destructive: the default "replace" mode drops every deployed file the
23874
23874
  // call doesn't re-send, and delete_paths removes files outright. Prior
23875
23875
  // versions stay revertible, but the live site does lose content.
@@ -24657,6 +24657,19 @@ Work token-efficiently \u2014 generated output is your scarcest resource:
24657
24657
 
24658
24658
  Typical small-change flow, two calls total: get_site {find: "old phrase"} \u2192 edit_site {edits: [{path, find, replace}]}. If you already know the exact deployed text, edit_site alone is enough \u2014 a miss fails safely with recovery instructions. For visual changes, add preview_site to see the result; to undo anything, get_site {history: true} \u2192 revert_site.
24659
24659
 
24660
+ RECIPE \u2014 add an uploaded image to a live site (the complete flow, 4 calls):
24661
+ 1. create_upload {site} \u2192 relay the returned upload_url to the user as a clickable link (drag-and-drop page, no sign-in).
24662
+ 2. When they say done: create_upload {site, session} \u2192 lists {upload_id, filename} per file.
24663
+ 3. deploy_site {site, mode: "patch", files: [{path: "/images/photo.jpg", upload_id}]} \u2014 the image is now deployed but NOT yet on any page.
24664
+ 4. edit_site to place it: insert/replace an <img src="/images/photo.jpg" alt="\u2026"> where it belongs. Then preview_site to see it.
24665
+
24666
+ RECIPE \u2014 public form that saves to the site's database (RSVPs, leads, guestbooks):
24667
+ 1. Declare the type in drivethrough.json and deploy it (mode "patch" on a live site): {"types": {"lead": {"write": "public", "fields": {"name": "string", "email": "string", "note": "string?"}, "notify": "owner-email"}}}. Deploying it provisions the database; submissions are owner-only readable by default. Optional: "unique_per": "session" makes a visitor's row update instead of duplicate (RSVPs); "rate_limit" like "5/hour" throttles.
24668
+ 2. Wire the page, same origin, no SDK: on submit, POST /api/data with JSON body {type: "lead", json: {name, email, note}, turnstile_token}. GET /api/data?type=lead \u2192 {items} lists rows the caller may read.
24669
+ 3. Turnstile (required for anonymous writes, usually invisible to visitors): GET /api/config \u2192 {turnstile_site_key}; load https://challenges.cloudflare.com/turnstile/v0/api.js; put <div class="cf-turnstile" data-sitekey="\u2026"></div> inside the form; send its "cf-turnstile-response" input value as turnstile_token.
24670
+ 4. Anonymous visitors only reach a public site (set_privacy) or a shared one \u2014 on a private site the form works for invited viewers.
24671
+ 5. Verify: the deploy response includes a warning when an anonymously-writable type is declared but no page loads the Turnstile widget \u2014 fix it before telling the user it works. End-to-end test: have the user submit once, then query_db {action: "list", type: "lead"} to show the row landed. (Local dev accepts any turnstile_token \u2014 the test secret always passes \u2014 so there a scripted POST to /api/data proves the whole path.)
24672
+
24660
24673
  Custom domains (paid plans): manage_domain attaches a domain the user already owns. After attaching, check_domain {action: "connect"} looks up one-click setup at their registrar (relay the URL when offered, else the exact DNS records from attach), and check_domain {action: "status"} polls until "active" \u2014 DNS seen, then TLS issued.`;
24661
24674
  }
24662
24675
  });
@@ -27734,13 +27747,24 @@ Declare data types the site collects. The platform owns the write path.
27734
27747
  Deploying a drivethrough.json with types auto-provisions the site's database.
27735
27748
 
27736
27749
  ## Client-side data access
27737
- Static pages call the Data API. A typed helper keeps it legible:
27750
+ Static pages call the same-origin Data API \u2014 no SDK required:
27751
+ - \`POST /api/data\` with JSON \`{type, json: {\u2026fields}, turnstile_token?}\`
27752
+ inserts (turnstile_token only for anonymous writes \u2014 wiring above).
27753
+ - \`GET /api/data?type=X\` \u2192 \`{items}\` lists the rows the caller may read.
27754
+ A typed helper ships in the starter template and keeps it legible:
27738
27755
  \`\`\`ts
27739
27756
  import { data } from "./lib/data"; // ships in the starter template
27740
27757
  await data.ofType("rsvp").create({ name, attending: true });
27741
27758
  const rows = await data.ofType("rsvp").list();
27742
27759
  \`\`\`
27743
27760
 
27761
+ **Verify a form before calling it done.** The deploy response warns when a
27762
+ type anonymous visitors can write is declared but no page loads the Turnstile
27763
+ widget \u2014 fix that before handing over. End-to-end: submit once, then
27764
+ \`drivethrough data list <site> <type>\` shows the row. In local dev any
27765
+ turnstile_token passes (Cloudflare's test secret), so a scripted POST to
27766
+ \`/api/data\` proves the whole path; in production, have the user submit.
27767
+
27744
27768
  ## Resuming work on a deployed site
27745
27769
  Every deployed site can be read back \u2014 files and database \u2014 so work can
27746
27770
  continue in a later session:
@@ -27772,7 +27796,9 @@ continue in a later session:
27772
27796
  deploy_site \`{path, upload_id}\`. To rename or duplicate an already-deployed
27773
27797
  file, deploy_site \`{path, from_path}\` copies it server-side (with
27774
27798
  \`delete_paths\`, a move). Never hand-generate base64 \u2014 inline base64 is
27775
- capped at 1 MB, for tiny pasted assets only.
27799
+ capped at 1 MB, for tiny pasted assets only. Deploying an image does NOT
27800
+ put it on a page: follow up with an edit that references it
27801
+ (\`<img src="/images/photo.jpg">\`), then preview to confirm.
27776
27802
  - Versions are restore points: every deploy is kept. MCP \`get_site\` lists
27777
27803
  history (\`history: true\`), diffs versions (\`compare\`), and reads old ones
27778
27804
  (\`version\`); \`revert_site\` returns to any version byte-exactly \u2014 the safe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drivethrough-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Agent-first hosting CLI. Say what you want. Stay in the car.",
5
5
  "type": "module",
6
6
  "license": "MIT",