shiply-cli 0.23.0 → 0.25.0

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.
@@ -0,0 +1,103 @@
1
+ ---
2
+ type: reference
3
+ title: Publishing & site management
4
+ description: Static framework build matrix, detect, SPA mode, .shiplyignore, list/delete/rollback, verify, stable previews, promote, machine-readable output, form-data subcommands.
5
+ timestamp: 2026-07-04
6
+ ---
7
+
8
+ # Publishing & site management
9
+
10
+ Part of the shiply skill (see SKILL.md for publish basics, auth, and updates).
11
+ Everything here works over CLI, MCP, and REST with a `Authorization: Bearer
12
+ shp_…` key unless marked anonymous-ok.
13
+
14
+ ## Any static site works — frameworks + SSGs auto-detected
15
+
16
+ shiply hosts any static site (and full SSR apps too — see
17
+ [ssr-frameworks.md](ssr-frameworks.md)). For a static build, publish the BUILD
18
+ OUTPUT, never the source: run the build, then publish the output dir with SPA
19
+ mode for client-routed apps. The CLI auto-detects 16+ frameworks and tells you
20
+ the right command. Run `shiply detect` to preview what it found without
21
+ uploading.
22
+
23
+ - Vite (React/Vue/Svelte/Solid/Qwik): `npm run build` then `shiply publish dist --spa`
24
+ - Create React App: `npm run build` then `shiply publish build --spa`
25
+ - Next.js (static): set `output: "export"` in next.config, `npm run build`, then
26
+ `shiply publish out` (no --spa; export emits real HTML per route). For full
27
+ Next.js SSR (via OpenNext) see [ssr-frameworks.md](ssr-frameworks.md) —
28
+ plain SSR is live (ISR/revalidate not yet; Next 16 needs
29
+ `next build --webpack`).
30
+ - Astro: `npm run build` then `shiply publish dist`
31
+ - SvelteKit (adapter-static): `npm run build` then `shiply publish build --spa`
32
+ - Nuxt: `npx nuxt generate` then `shiply publish .output/public`
33
+ - Remix (client build): `npm run build` then `shiply publish build/client --spa`
34
+ - Docusaurus: `npm run build` then `shiply publish build`
35
+ - Hugo: `hugo` then `shiply publish public`
36
+ - Jekyll: `bundle exec jekyll build` then `shiply publish _site`
37
+ - Eleventy: `npx @11ty/eleventy` then `shiply publish _site`
38
+ - MkDocs: `mkdocs build` then `shiply publish site`
39
+ - Hexo: `npx hexo generate` then `shiply publish public`
40
+ - SolidStart (static): `npm run build` then `shiply publish dist/public`
41
+ - Qwik City (static adapter): `npm run build` then `shiply publish dist`
42
+ - Anything else with a built `dist/`/`build/`/`out/`/`_site/`/`public/`/
43
+ `.output/public/` folder: generic fallback picks it up.
44
+ - Plain HTML: `shiply publish .` — no build step.
45
+
46
+ Override auto-detection with `--framework=<name>`. Use the CLI (not inline
47
+ MCP files) for builds — hashed bundles often exceed the 50-file inline cap,
48
+ and the CLI hash-skips unchanged chunks on updates.
49
+
50
+ **SPA mode**: pass `--spa` (CLI) or `"spaMode": true` (REST/MCP) so deep links
51
+ serve index.html.
52
+
53
+ ## Manage & verify sites (CLI)
54
+
55
+ List, delete, roll back, verify, and promote owned sites — all over the same
56
+ Bearer API key. Great for agents that ship iteratively and need to keep their
57
+ subdomains tidy.
58
+
59
+ ```bash
60
+ shiply ls # list your sites: slug, status, URL
61
+ shiply rm <slug> --yes # PERMANENTLY delete a site + its files (--yes required)
62
+ shiply rollback <slug> # list finalized versions (current one marked)
63
+ shiply rollback <slug> <versionId> # re-point the site to that version — live instantly
64
+ shiply verify <slug> # edge SSL + HTTP + thumbnail readiness check
65
+ shiply publish <dir> --as <name> # STABLE preview: same URL every iteration (local alias)
66
+ shiply promote <preview-slug> --to <dest-slug> # copy the preview's exact live bytes onto a prod site
67
+ shiply publish <dir> --json # one machine-readable JSON line, no confetti/banners
68
+ ```
69
+
70
+ - **`shiply verify <slug>`** prints a human report PLUS a stable machine marker
71
+ line `VERIFY status=LIVE http=200 ssl=valid thumb=…` (or `status=PENDING`).
72
+ Headless agents should parse that `VERIFY status=…` line — it's the
73
+ contract, like `SITE_READY` in `status`.
74
+ - **`shiply publish <dir> --as <name>`** gives a stable preview URL that the
75
+ next publish with the same `--as <name>` reuses — no more changing URLs or
76
+ orphaned scratch sites across iterations, independent of the source dir.
77
+ - **`shiply promote <preview-slug> --to <dest-slug>`** copies the *exact bytes*
78
+ you previewed onto an existing owned destination site (keeps its slug,
79
+ domains, access) — atomic preview→production, no rebuild.
80
+ - **`--json`** on `publish`/`update` emits a single JSON line
81
+ `{slug,siteUrl,siteId,uploaded,skipped,anonymous,expiresAt,updated}` and
82
+ suppresses all human output + confetti — use it in scripts/agents.
83
+ - **`.shiplyignore`** in the publish root excludes files from upload
84
+ (documented gitignore subset: `# comments`, `secret.txt`, `internal/`,
85
+ `*.log`, `/anchored`, `**` globs, `!negation`). Keep `.env`, notes, and
86
+ internal files out of the published bytes.
87
+
88
+ ## Rollback + version history (REST/MCP)
89
+
90
+ - Deploy history: `GET /api/v1/sites/<slug>/versions` (Bearer) →
91
+ `{versions:[{id,createdAt,isLive,fileCount,bytes}]}` (newest-first, ≤20).
92
+ MCP tool: `list_versions`.
93
+ - Rollback: `POST /api/v1/publish/<slug>/rollback {"versionId"}` flips any
94
+ finalized version live instantly. MCP tool: `rollback_site`.
95
+
96
+ ## Reading captured form data from the CLI
97
+
98
+ To verify captured signups/form data without the dashboard (see
99
+ [site-features.md](site-features.md) for how sites capture data):
100
+ `shiply data list <slug>` (collections + counts),
101
+ `shiply data query <slug> <coll> [--limit N] [--where '<json>']`, and
102
+ `shiply data export <slug> <coll> [--out file.ndjson]`. Confetti is
103
+ suppressed automatically on non-TTY stdout; `--no-confetti` forces it off.
@@ -0,0 +1,110 @@
1
+ ---
2
+ type: reference
3
+ title: Site features (proxy routes, Site Data, access control, variables, drives, auth)
4
+ description: Dynamic capabilities on any owned site — server-side secret proxying for AI/API calls, zero-backend form storage, password/invite-only access, encrypted variables, private drives, path-mounting, public profile, and the bring-your-own-auth pattern.
5
+ timestamp: 2026-07-04
6
+ ---
7
+
8
+ # Site features — the dynamic layer on owned sites
9
+
10
+ Part of the shiply skill (see SKILL.md for publish basics). Everything here
11
+ requires an OWNED site (claim it first) and applies per-site.
12
+
13
+ ## Proxy routes — AI/API calls WITHOUT exposing keys
14
+
15
+ NEVER embed API keys in published HTML/JS. Instead: store the key as a
16
+ Variable (PUT /api/v1/variables), then include `.shiply/proxy.json` in the
17
+ published files declaring routes, e.g. {"proxies":{"/api/chat":{"upstream":
18
+ "https://openrouter.ai/api/v1/chat/completions","method":"POST","headers":
19
+ {"Authorization":"Bearer ${OPENROUTER_API_KEY}"}}}}. The page then calls the
20
+ relative path (fetch('/api/chat')) and shiply injects the secret server-side.
21
+ `${VAR}` resolves from the owner's encrypted Variables at request time — keys
22
+ NEVER reach the browser. Prefix routes "/api/db/*" forward subpaths (great
23
+ for Supabase REST). Owned sites only; https public upstreams only;
24
+ 100 req/h/ip; 10 MB bodies; SSE streams supported. Docs: /docs/proxy-routes
25
+
26
+ ## Site Data — forms/waitlists/guestbooks with ZERO backend
27
+
28
+ When the user wants to collect anything from visitors (waitlist, contact
29
+ form, RSVP, guestbook): include `.shiply/data.json` in the published files,
30
+ e.g. {"collections":{"signups":{"fields":{"email":{"type":"email",
31
+ "required":true}},"access":{"read":"owner","insert":"public"},
32
+ "rateLimit":"10/hour/ip"}}}, then have the page POST JSON to the relative
33
+ path /.shiply/data/signups (201 + id; 400 with the exact field error).
34
+ Records are validated server-side; the owner reads them in the dashboard
35
+ (Data section, CSV export) or GET /api/v1/publishes/<slug>/data/<collection>
36
+ with a Bearer key. Field types: string/number/integer/boolean/email/url/
37
+ datetime. Limits: 10 collections, 16 KB records, 25k/collection. Owned sites
38
+ only. CLI readers: `shiply data list/query/insert/export/wipe-collection`
39
+ (see [publishing.md](publishing.md)) and `shiply data init` scaffolds the
40
+ manifest. Docs: /docs/site-data
41
+
42
+ To also email/confirm/broadcast to captured signups, add an `email` block —
43
+ see [email.md](email.md).
44
+
45
+ ## Access control — password or invite-only sites (paid)
46
+
47
+ To password-protect or restrict a site: PATCH /api/v1/publishes/<slug>/access
48
+ with {"mode":"password","password":"..."} or {"mode":"restricted",
49
+ "allowedEmails":[...],"allowedDomains":[...]}, or set mode "public" to open it.
50
+ GET returns the policy (never the hash). MCP tool: `set_site_access`. Enforced
51
+ at the edge before any content/proxy/data is served; visitors get a 7-day
52
+ signed cookie; changing any setting signs current visitors out.
53
+ Docs: /docs/access-control
54
+
55
+ ## Variables — encrypted per-user KV
56
+
57
+ For API keys the user's sites need: GET/PUT /api/v1/variables
58
+ {"name","value"}, DELETE /api/v1/variables/{NAME}; GET ?reveal=1 returns
59
+ plaintext values. MCP: `set_variable`. Referenced by proxy routes (`${VAR}`)
60
+ and injected into Workers as `env.<NAME>`. Supabase can be connected from the
61
+ dashboard and lands here as SUPABASE_URL + SUPABASE_ANON_KEY.
62
+
63
+ ## Drives — private cloud storage (agent memory + assets)
64
+
65
+ Private storage for files/notes/context you don't want on a public site.
66
+ MCP tools: `list_drives`, `create_drive`, `drive_put_file` (driveId
67
+ "default", utf8/base64, ≤2 MB), `drive_list_files`, `drive_delete_file`,
68
+ `publish_from_drive` (snapshot a drive into a live site).
69
+
70
+ ## Path-mounting + public profile
71
+
72
+ - `set_link` (MCP) — mount another owned **public** site at a path on a host
73
+ (host/docs → target).
74
+ - `set_profile` / `feature_site` (MCP) — stand up the user's public portfolio
75
+ at <handle>.shiply.now and feature a public site on shiply.now/explore.
76
+ - `export_account` (MCP) — JSON bundle of the user's data (no secrets).
77
+ - Site metadata: `PATCH /api/v1/publish/<slug>/metadata`
78
+ {"title?","spaMode?","addedToProfile?"}.
79
+
80
+ ## Bring your own auth (Clerk / Auth.js / Lucia / Supabase Auth)
81
+
82
+ shiply does **not** host customer auth. If the user's app needs sign-in, you
83
+ (the agent) set up their auth provider yourself — Clerk is the fastest path.
84
+
85
+ **One-time human step:** ask the user to create a Clerk app at
86
+ `dashboard.clerk.com` (~2 min). They paste you the publishable key (`pk_…`)
87
+ and secret key (`sk_…`).
88
+
89
+ **Wire it:**
90
+ ```bash
91
+ shiply secret set <slug> CLERK_SECRET_KEY sk_live_xxxxxxxxxx
92
+ # The publishable key can be embedded in the JS build — it's safe in the browser.
93
+ ```
94
+
95
+ **In `worker.ts`:** verify the session JWT against `env.CLERK_SECRET_KEY` on
96
+ every API request (e.g. `@clerk/backend` verifyToken), scope D1 rows by
97
+ `payload.sub` (the Clerk user id).
98
+
99
+ **In the SPA:** add `@clerk/clerk-react` to the build, wrap with
100
+ `<ClerkProvider>`, attach `Authorization: Bearer <token>` to every
101
+ authenticated fetch.
102
+
103
+ Why not auto-integrate? shiply's own Clerk instance signs in **agents** to the
104
+ shiply dashboard — it's not multi-tenant for someone else's app's users.
105
+ Customers owning their own Clerk is the only correct shape.
106
+
107
+ Same pattern works for Auth.js, Lucia, Supabase Auth, Firebase Auth — store
108
+ the provider secret via `shiply secret set`, verify the JWT in the worker.
109
+
110
+ Docs: https://shiply.now/docs/auth
@@ -0,0 +1,47 @@
1
+ ---
2
+ type: reference
3
+ title: SSR frameworks
4
+ description: Deploy full server-side-rendered apps — SvelteKit, Astro, Qwik, the Nitro family (Nuxt, SolidStart, Analog, TanStack Start), React Router v7, Next.js via OpenNext, and Hono/raw Workers.
5
+ timestamp: 2026-07-04
6
+ ---
7
+
8
+ # SSR / server frameworks (live: every major JS framework)
9
+
10
+ Part of the shiply skill (see SKILL.md for publish basics). Requires sign-in +
11
+ Developer plan.
12
+
13
+ `shiply publish` auto-detects an SSR build and deploys the worker bundle with
14
+ `nodejs_compat`, serving static assets from the edge. Live and verified on prod:
15
+ SvelteKit (`@sveltejs/adapter-cloudflare`), Astro (`@astrojs/cloudflare`), Qwik
16
+ City, the Nitro family (Nuxt, SolidStart, Analog, TanStack Start), React Router
17
+ v7, and Next.js (via OpenNext) — plus wrangler workers (`wrangler.toml` with
18
+ `main` — Hono, itty-router, raw `fetch`). **Build first** (`npm run build`),
19
+ then `shiply publish .`. Force the static path with `--framework=<name>`, or
20
+ skip SSR detection entirely with `--no-ssr`.
21
+
22
+ Per-framework build setup:
23
+
24
+ - **SvelteKit** — `@sveltejs/adapter-cloudflare`, then `npm run build`,
25
+ `shiply publish .`
26
+ - **Astro** — `@astrojs/cloudflare` adapter, `npm run build`, `shiply publish .`
27
+ - **Qwik City** — `@builder.io/qwik-city` cloudflare-pages adapter,
28
+ `npm run build`, `shiply publish .`
29
+ - **Nitro family (Nuxt, SolidStart, Analog, TanStack Start)** — build with the
30
+ `cloudflare`(-module) Nitro preset, then `shiply publish .`
31
+ - **React Router v7** — framework mode (`@react-router/dev`), `react-router
32
+ build`, then `shiply publish .`
33
+ - **Next.js** — build via `@opennextjs/cloudflare` (OpenNext), then
34
+ `shiply publish .`. Plain SSR works today; **ISR / on-demand revalidate is
35
+ not live yet**, and Next 16 must build with `next build --webpack` (not
36
+ Turbopack).
37
+ - **Wrangler workers** — any repo with `wrangler.toml` declaring `main`
38
+ (Hono, itty-router, raw `fetch` handler) deploys as-is.
39
+
40
+ How serving works: the deployed worker receives every request; static assets
41
+ are tried first (the worker calls `env.ASSETS`, 200 = asset served from the
42
+ edge / 404 = your SSR handler runs). The worker gets the same bindings,
43
+ secrets, and crons as Functions — see [functions.md](functions.md). Bundle
44
+ cap 8 MB.
45
+
46
+ Plan gate: Free/Hobby get `402 payment_required` — upgrade at
47
+ https://shiply.now/dashboard/plan.