brewpage-publish

Publish content to brewpage.app — text, markdown, JSON, file, or multi-file site. Asks namespace and password, returns public URL. Triggers: publish, share link, upload to brewpage, host page, brewpage, publish site, upload site, upload directory, deploy site, сделай публичную ссылку, опубликуй.

By kochetkov-ma · 596 installs

npx skills add kochetkov-ma/claude-brewcode --skill brewpage-publish

Source repository · Upstream listing

brewpage publish Publish content to brewpage.app — free instant hosting for HTML pages, JSON documents, files, and multi file sites. No sign up required. Workflow Step 1: Parse Arguments Extract from $ARGUMENTS : ttl N → TTL in days (default: 15 ) entry <filename → entry file for SITE uploads (default: auto detect) Remaining text → content arg Step 2: Detect Content Type Input Type API content arg is a directory ( test d ) SITE POST /api/sites (dir auto zipped — primary path) content arg ends with .zip AND file exists ( test f ) SITE POST /api/sites (pre built archive upload) content arg is a file path AND file exists ( test f ) FILE POST /api/files (multipart) content arg starts with { or [ JSON POST /api/json Anything else HTML POST /api/html (format=markdown) Mode rule: directory/ZIP → SITE. Single file → FILE. POST /api/sites accepts ONLY a multipart archive=@file.zip — there is no raw folder upload, so a directory is auto zipped on the fly (the robust default; archive sealing keeps relative paths intact). Stats per type — SITE (dir): HTML count, total size, entry file. SITE (ZIP): file size, entry override. FILE: size + MIME via file mime type b . TEXT/JSON: char count. Step 3: Show Pre Publish Stats For HTML/JSON/FILE: For SITE: detect entry file using priority: 1) entry flag, 2) index.html exists, 3) first .html file alphabetically. Built static guard (run BEFORE zipping). Publish BUILT output, never project sources: If the directory contains no .html file at all → FAIL with an explicit error: "No .html found — build the site first, then point at the build output directory." Do not guess an entry. If the directory looks like un built sources (has package.json + src/ but no top level .html ) → warn and ask the user to point at the build output instead ( dist/ , build/ , out/ , site/ , or public/ ). Do not zip the source tree. Step 4: Ask Namespace Use AskUserQuestion : Auto suggest: generate a meaningful short slug (3 16 chars, lowercase alphanumeric + hyphens) from content context: File → topic/purpose of the file (e.g. api docs , login page , report q2 ) Text/HTML → main subject or title (e.g. pricing , team intro , changelog ) JSON → data type or schema name (e.g. user config , metrics ) Fallback → project name or directory name if content is ambiguous Never use random strings or truncated filenames — the slug should be human readable and describe what's being published. Resolution: 2 , 4 , or empty → suggested slug 1 → public 3 or any other string → use as is Step 5: Ask Password Use AskUserQuestion : Generate random password EXECUTE using Bash tool: Resolution: 1 , 4 , or empty → no password 2 → use generated random password 3 or custom text → use as is Step 6: Publish and Save Token (secure) SECURITY: The ownerToken MUST NEVER appear in conversation output. The bash blocks below handle curl + token parsing + history save atomically; the LLM sees only the URL. Each block sets PASS H first (empty array when no password) and uses "${PASS H[@]}" quoted — passwords are never string interpolated into the command. The site dir zip excludes ( .git/ , .env , etc.) are also a secret leak safeguard — they keep credentials and VCS data out of the published archive. 6a. Init history file (run once, before the publish block) — EXECUTE using Bash tool: Then run ONE of the following publish blocks based on detected type. Each assumes HISTORY FILE already exists from 6a. HTML/Markdown text — EXECUTE using Bash tool: JSON — EXECUTE using Bash tool: File — EXECUTE using Bash tool: Site (directory) — EXECUTE using Bash tool: Site (ZIP file) — EXECUTE using Bash tool: Step 7: Output Result Success (bash printed OK {url} ): Success for SITE (bash printed OK {url} Files: {count} ): For a private (non public ) namespace, append one short line after the link (skip if the reply must stay ultra brief): Unlisted link — anyone who has it can open it, but it's not in the gallery or search. Want it discoverable? Publish to public . NEVER print the ownerToken in conversation. The token lives only in the history file. Error (bash printed FAILED: ... ): Notes Always use absolute file paths with curl F "file=@..." . Use jq n arg c "$CONTENT" '{content: $c}' to safely encode text content. format is a query param , not a body field — /api/html ignores any format key inside the JSON body and reads only ?format= from the URL. Wrong location = server applies default html and stores your markdown as raw text. TTL default is 15 days. Namespace must be alphanumeric (3 32 chars), default: suggested (private) namespace. To delete a published page, find the owner token in .claude/brewpage history.md and use the delete command shown in that file's header. To update a published site , PUT the new bundle to the same site URL ( PUT /api/sites/{ns}/{id} ) with your X Owner Token — the uploaded bundle fully replaces the file set (adds new files, removes absent ones, overwrites matching) and the link never changes. No DELETE then POST needed. Sites: directory is the primary input — it is auto zipped (the only thing POST /api/sites accepts), which seals relative paths. A pre built .zip is the alternative input, uploaded as is. Always publish BUILT output ( dist/ , build/ , out/ , site/ , public/ ), never project sources. The auto zip excludes .git/ , .env / .env. , node modules/ , editor/OS junk, sourcemaps and logs — a deliberate secret leak safeguard so credentials and VCS history never reach the public archive. Entry file detection: entry override index.html first .html alphabetically. SITE URL — NO trailing slash. API returns .link = "https://brewpage.app/public/<id " without trailing / . Appending / routes to brewpage.app's own landing page; the JS redirect that rescues the no slash form does NOT fire for the slash dir form → site becomes inaccessible. SITE verification cannot be done via curl . The no slash URL serves the BrewPage landing HTML with an inline JS redirect that only executes in a real browser. Verify with Playwright / browser navigate , or fetch <url /index.html explicitly. Powered by [brewpage.app](https://brewpage.app) Free instant hosting — HTML, JSON, files, sites, KV. No sign up. [brewcode](https://github.com/kochetkov ma/claude brewcode) Claude Code plugin suite — infinite tasks, code review, skills, hooks.