drivethrough-cli 0.1.2 → 0.1.3

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 +17 -12
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -24021,23 +24021,27 @@ function registerTools(server, ctx) {
24021
24021
  server.registerTool(
24022
24022
  "create_upload",
24023
24023
  {
24024
- title: "Create upload URL",
24025
- description: `Mint a short-lived signed URL the USER can upload one local file to \u2014 the route for large binary assets (photos, PDFs, audio, video) when you have no local filesystem and the file isn't hosted anywhere. The bytes never pass through the conversation: if the file is already in YOUR runtime (e.g. a chat attachment mounted in your sandbox) and you can make HTTP requests, PUT the bytes to the signed URL yourself; otherwise relay the returned upload command to the user and wait for them to run it. Either way, then reference the file in deploy_site as {path, upload_id} (mode "patch" adds it to a live site) \u2014 never base64-encode it instead. Choosing a route for a binary asset: already on the public web \u2192 deploy_site {path, source_url}; local file + this server runs on the user's machine \u2192 deploy the directory; local file + chat-only connection \u2192 this tool. Tiny pasted assets (\u22641 MB, e.g. a favicon) may still go inline as base64 content. Each link takes exactly one file, is capped at 25 MB, and expires in 15 minutes. Upload ids are single-use: the deploy that references one consumes it (the bundle keeps the bytes; the staged copy is removed and its quota refunded) \u2014 to rename or duplicate the file later, use deploy_site {path, from_path}. An upload no deploy references within 24 hours is deleted, so deploy soon after the user confirms. Pass size_bytes when the user told you the file size \u2014 quota errors then surface here instead of failing the user's upload.`,
24024
+ title: "Create upload link",
24025
+ description: "Mint a short-lived upload link the USER opens in their browser to add local files (photos, PDFs, audio, video) \u2014 the route for binary assets when you cannot reach the bytes and they aren't hosted anywhere. Two-step: (1) relay the returned upload_url as a clickable link \u2014 it opens a drag-and-drop page (no sign-in needed) that takes up to 20 files, 25 MB each, and expires in 30 minutes. (2) When the user says they're done, call this tool again with the returned `session` \u2014 it lists what they uploaded ({upload_id, filename, size_bytes}); ship each with deploy_site files: [{path, upload_id}] (mode \"patch\" adds them to a live site). Never base64-encode a file instead \u2014 but if the bytes are already in YOUR runtime (e.g. a chat attachment mounted in your sandbox) AND you can make HTTP requests, you may PUT them straight to the returned put_url (one file per request, its filename as the last path segment) without involving the user. Choosing a route for a binary asset: already on the public web \u2192 deploy_site {path, source_url}; this server runs on the user's machine \u2192 deploy the directory; file only in the chat or on the user's machine \u2192 this tool. Tiny pasted assets (\u22641 MB, e.g. a favicon) may still go inline as base64 content. Upload ids are single-use: the deploy that references one consumes it (the bundle keeps the bytes; the staged copy is removed and its quota refunded) \u2014 to rename or duplicate the file later, use deploy_site {path, from_path}. An upload no deploy references within 24 hours is deleted, so deploy soon after the user confirms. Pass size_bytes when the user told you a file's size \u2014 quota errors then surface here instead of failing their upload.",
24026
24026
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
24027
24027
  inputSchema: {
24028
- site: external_exports.string().describe("Site name or id the upload belongs to"),
24029
- filename: external_exports.string().optional().describe(`The file's name, e.g. "dog.jpg" \u2014 its extension names the stored object`),
24030
- size_bytes: external_exports.number().int().optional().describe("Expected file size in bytes, if known \u2014 checked against the 25 MB cap and storage quota now")
24028
+ site: external_exports.string().describe("Site name or id the uploads belong to"),
24029
+ session: external_exports.string().optional().describe(
24030
+ "A session id this tool returned earlier: list that session's uploaded files instead of minting a new link. Call this after the user says they're done uploading."
24031
+ ),
24032
+ size_bytes: external_exports.number().int().optional().describe(
24033
+ "Expected size in bytes of the largest file, if known \u2014 checked against the 25 MB cap and storage quota at mint time"
24034
+ )
24031
24035
  }
24032
24036
  },
24033
- async ({ site, filename, size_bytes }) => {
24037
+ async ({ site, session, size_bytes }) => {
24034
24038
  try {
24039
+ if (session !== void 0) {
24040
+ return ok(await ctx.api.request("GET", `${sitePath(site)}/uploads/${encodeURIComponent(session)}`));
24041
+ }
24035
24042
  return ok(
24036
24043
  await ctx.api.request("POST", `${sitePath(site)}/uploads`, {
24037
- body: {
24038
- ...filename !== void 0 ? { filename } : {},
24039
- ...size_bytes !== void 0 ? { size_bytes } : {}
24040
- }
24044
+ body: { ...size_bytes !== void 0 ? { size_bytes } : {} }
24041
24045
  })
24042
24046
  );
24043
24047
  } catch (error2) {
@@ -24644,7 +24648,7 @@ var init_tools = __esm({
24644
24648
  Work token-efficiently \u2014 generated output is your scarcest resource:
24645
24649
  - LOCATE, don't read: to find where text lives on a deployed site, call get_site with \`find\` \u2014 it returns byte-exact matching lines. Use \`manifest_only\` to see what files exist. Read full contents (\`paths\`) only when you genuinely need them; a bare get_site inlines every text file.
24646
24650
  - EDIT, don't resend: change existing files with edit_site (exact find/replace). Never re-emit a whole file to change a small part. Use deploy_site mode "patch" for new files or wholesale rewrites \u2014 unchanged files carry forward automatically.
24647
- - REFERENCE, don't inline: never base64-encode a file \u2014 not by hand, not in code, and never as a data: URI in HTML. To ship an image or other binary asset, pick the route by where the bytes live: already at a public URL \u2192 deploy_site {path, source_url}, fetched server-side; a local file (the user's, or a chat attachment already in your runtime) \u2192 create_upload mints a signed URL the bytes get PUT to, then deploy_site {path, upload_id}. (Agents with a local filesystem deploy the directory instead \u2014 binaries ride along.) To move or duplicate an ALREADY-DEPLOYED file, {path, from_path} copies it server-side \u2014 never re-upload unchanged bytes, and once an upload_id exists, reference it rather than inlining the same bytes again. Inline base64 content is capped at 1 MB and exists only for tiny pasted assets like a favicon.
24651
+ - REFERENCE, don't inline: never base64-encode a file \u2014 not by hand, not in code, and never as a data: URI in HTML. To ship an image or other binary asset, pick the route by where the bytes live: already at a public URL \u2192 deploy_site {path, source_url}, fetched server-side; a local file (the user's, or a chat attachment already in your runtime) \u2192 create_upload returns a link the user opens in their browser to drag files in; when they say done, call create_upload {session} for the upload_ids, then deploy_site {path, upload_id}. (Agents with a local filesystem deploy the directory instead \u2014 binaries ride along.) To move or duplicate an ALREADY-DEPLOYED file, {path, from_path} copies it server-side \u2014 never re-upload unchanged bytes, and once an upload_id exists, reference it rather than inlining the same bytes again. Inline base64 content is capped at 1 MB and exists only for tiny pasted assets like a favicon.
24648
24652
  - MERGE, don't replace: to change a few fields of a database row, write_db update with \`merge\` (null deletes a field). No need to fetch the row first.
24649
24653
  - UNDO by version, never by inverse edits: every deploy is a numbered version the platform keeps. When the user wants a change undone, call revert_site \u2014 it restores the exact bytes of any prior version in one call and proves it. Reconstructing old content from memory with edit_site is how sites end up in a state that is neither old nor new.
24650
24654
  - LOOK at what shipped: you have no browser, but preview_site returns a real rendered screenshot of any version \u2014 your only way to see visual results. Use it after layout/style/animation work, or to eyeball an old version before reverting.
@@ -27757,7 +27761,8 @@ continue in a later session:
27757
27761
  Already at a public URL \u2192 deploy_site \`{path, source_url}\` (fetched
27758
27762
  server-side). Local file and you have the filesystem \u2192 deploy the directory
27759
27763
  (binaries ride along). Local file but chat-only (remote MCP) \u2192
27760
- \`create_upload\` mints a signed URL the user uploads the file to, then
27764
+ \`create_upload\` returns a browser drag-and-drop link for the user; once
27765
+ they're done, \`create_upload {session}\` lists the upload_ids, then
27761
27766
  deploy_site \`{path, upload_id}\`. To rename or duplicate an already-deployed
27762
27767
  file, deploy_site \`{path, from_path}\` copies it server-side (with
27763
27768
  \`delete_paths\`, a move). Never hand-generate base64 \u2014 inline base64 is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drivethrough-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Agent-first hosting CLI. Say what you want. Stay in the car.",
5
5
  "type": "module",
6
6
  "license": "MIT",