@tomorrowos/sdk 1.1.3 → 1.1.4
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.
- package/VERCEL_QUESTIONS.md +12 -7
- package/VERCEL_SETUP.md +78 -43
- package/VERCEL_UPGRADE.md +2 -1
- package/package.json +1 -1
- package/templates/cms-starter/package-lock.json +3 -3
- package/templates/cms-starter/package.json +2 -2
- package/templates/cms-starter-v0/README.md +4 -1
- package/templates/cms-starter-v0/package-lock.json +3 -3
- package/templates/cms-starter-v0/package.json +2 -2
- package/templates/cms-starter-v0/vercel.json +1 -1
package/VERCEL_QUESTIONS.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# Vercel / v0 - Verbatim question bank
|
|
2
2
|
|
|
3
|
-
> **Protocol:** `vercel-questions/1.
|
|
3
|
+
> **Protocol:** `vercel-questions/1.8` (pairs with `VERCEL_SETUP.md` 1.19+ / `@tomorrowos/sdk` 0.9.70+)
|
|
4
4
|
> **For Agents:** When asking the user a setup question, **copy-paste the block below for that step EXACTLY**.
|
|
5
5
|
> Do **not** paraphrase, reorder, rename options, or invent alternatives (no S3, no Supabase Storage, no "Blob recommended", no "disable media").
|
|
6
6
|
> After each answer, configure per `VERCEL_SETUP.md`, then paste the **next** block.
|
|
7
7
|
> **Q1 and Q2 are choice questions — present them as a clickable choice UI** (buttons / radio / option cards) using the exact option labels below. Do **not** ask the user to type `1` or `2` in chat when a choice UI is available (chat typing is fallback only).
|
|
8
|
-
> **Q3 is a form only - never a multiple-choice question
|
|
8
|
+
> **Q3 is a form only - never a multiple-choice question.**
|
|
9
|
+
> **Q4 is optional CMS password (`CMS_PASSWORD`) — immediately after Q3, no yes/no prelude.** Open the password Env/Secret input; blank/skip is valid.
|
|
9
10
|
> **HARD STOP on Q3:** show the form, then **wait** for the user's reply. Optional fields do **not** mean you may auto-skip.
|
|
10
11
|
> **Q4 is optional:** blank/skip is valid; they can set `CMS_PASSWORD` later.
|
|
11
12
|
> **After Q4 (or after Q3 if you deferred Q4):** run `VERCEL_SETUP.md` **IRON GATE — v0 Preview hygiene** before debugging Neon/Postgres or Blob.
|
|
@@ -93,18 +94,22 @@ How should playlist media (images/videos) be stored?
|
|
|
93
94
|
- Auto-continuing to init/scaffold/deploy without a user Q3 reply or explicit "skip"
|
|
94
95
|
- Interpreting "do not re-ask" as "do not wait for the first reply"
|
|
95
96
|
|
|
96
|
-
After the user submits (including all-blank) or says "skip": apply `brand.json`, then
|
|
97
|
+
After the user submits (including all-blank) or says "skip": apply `brand.json`, then open **Q4 immediately** (CMS_PASSWORD Env input — **no** yes/no prelude). **Do not** re-ask Q3 a second time.
|
|
97
98
|
Blank fields -> keep existing `brand.json`. Logo blank -> `./assets/logo.svg`.
|
|
98
99
|
|
|
99
100
|
---
|
|
100
101
|
|
|
101
|
-
## Q4 - Optional CMS password (
|
|
102
|
+
## Q4 - Optional CMS password (Env input immediately after Q3)
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
**IRON RULE — no prelude:** Right after Q3, open the **CMS_PASSWORD** Env/Secret input. **Forbidden first:** "Do you want a password?", "Enable auth?", "Protect the CMS?", Option A/B yes/no.
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
**UX (required):** One Env/Secret field labeled **`CMS_PASSWORD`** (password input). User may enter a password **or** leave blank / skip.
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
**Title / helper:**
|
|
109
|
+
|
|
110
|
+
Optional CMS password — Environment Variable **`CMS_PASSWORD`**.
|
|
111
|
+
|
|
112
|
+
Enter a password to lock the Control Panel, or leave blank / skip to keep the panel open. You can add `CMS_PASSWORD` later in Vercel → Settings → Environment Variables and redeploy.
|
|
108
113
|
|
|
109
114
|
**Notes for the agent (do not invent extra UX):**
|
|
110
115
|
- This is **optional**. Blank/skip is a valid complete answer.
|
package/VERCEL_SETUP.md
CHANGED
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
>
|
|
6
6
|
> **On Vercel, this file is the setup questionnaire** (not `REPLIT_SETUP.md`).
|
|
7
7
|
>
|
|
8
|
-
> Protocol id: `vercel-setup/1.
|
|
8
|
+
> Protocol id: `vercel-setup/1.19` - pairs with `@tomorrowos/sdk` **0.9.70+** (`templates/cms-starter-v0`, Fluid Functions WebSockets).
|
|
9
9
|
>
|
|
10
10
|
> **Questions source of truth:** `VERCEL_QUESTIONS.md` - Agents must **open that file and paste each Q block verbatim**. Do not paraphrase.
|
|
11
11
|
> **Q1/Q2 = clickable choice UI (same pattern):** open a **button / radio / option-card UI** with the two fixed choices. Do **not** ask the user to type `1` or `2` in chat when a choice UI is available. Chat “reply 1 or 2” is fallback only.
|
|
12
12
|
> **Q3 = form only:** open **all seven optional inputs at once**, then **HARD STOP and WAIT** for submit or "skip". Never auto-skip because fields are optional. Never ask a branding choice first. Never show only Name + Primary colour. Logo = **Upload** above **Logo URL**.
|
|
13
|
-
> **Q4 = optional `CMS_PASSWORD
|
|
13
|
+
> **Q4 = optional `CMS_PASSWORD` (immediately after Q3, no prelude):** open the **CMS password Env/Secret input** right away. Blank/skip is valid. **Forbidden:** yes/no “Do you want a password / enable auth?” before the field. Control Panel auth only — never Vercel Deployment Protection / whole-site password.
|
|
14
14
|
> **After Q&A (before debugging DB):** run **IRON GATE — v0 Preview hygiene** (clear root Next leftovers, restart supervised `dev`, prove `GET /status` is TomorrowOS JSON). Do **not** spend turns “fixing Neon/Blob” while port 3000 is still a stale Next/Turbopack process.
|
|
15
|
-
> **Publish Output Directory:** must stay **empty / unset**.
|
|
15
|
+
> **Publish Output Directory:** must stay **empty / unset**.
|
|
16
|
+
> **Publish Build Command:** must be **empty / skip build** (`"buildCommand": ""` in `vercel.json` + dashboard). A defined build command (even a no-op `npm run build`) forces Vercel **static-build** mode and requires `public/` — that causes `Output Directory "public" is empty` / not found. Do **not** “fix” by stuffing `public/robots.txt`.
|
|
16
17
|
> **Copy questions verbatim from `VERCEL_QUESTIONS.md`.** Do not invent alternate Q2 options (no "Supabase Storage", no S3, no "disable media", no making Blob the recommended option).
|
|
17
18
|
> **`TOMORROWOS_STORE` and `DATABASE_SSL` are agent-only** - set them automatically after Q1; never put them in a user-facing Env form for the customer to type.
|
|
18
19
|
|
|
@@ -22,7 +23,8 @@ The following rules are **mandatory acceptance criteria**, not suggestions. The
|
|
|
22
23
|
|
|
23
24
|
1. **One TomorrowOS instance only.** Use the shared instance exported through `api/index.ts`. **Never create a second `TomorrowOS` instance in `api/ws.ts`** or any other route.
|
|
24
25
|
2. **Never use `public/` as the Vercel Output Directory.** The dashboard Output Directory must be **empty / unset**. Serve the Control Panel at runtime from `cms-panel/` through TomorrowOS `staticRoot`.
|
|
25
|
-
2a. **Build
|
|
26
|
+
2a. **Build Command must be empty / skip build** (`"buildCommand": ""` in `vercel.json`, dashboard Build Command empty). Do **not** use a no-op `npm run build` / `node -e "process.exit(0)"` as the Production build command — any defined build command with Framework=Other puts Vercel in **static-build** mode and requires a `public/` output directory.
|
|
27
|
+
2b. **Build errors `The Output Directory "public" is empty` or `public` not found:** First clear Output Directory if it is set to `public`. If Output is already null and the error remains, the cause is a **defined Build Command** — set Build Command / `buildCommand` to **empty string** and redeploy. Filling `public/` only papers over wrong static-output mode.
|
|
26
28
|
3. **Preview may use Next only as an isolated reverse-proxy shell under `preview/`.** Preview must not replace TomorrowOS or determine the Production runtime.
|
|
27
29
|
4. **Publish must use the Fluid Function.** Production must run `api/index.ts` ??the shared exported `http.Server`, with Fluid compute enabled. It must not use `next start`, a static export, or a bare `(req, res)` handler.
|
|
28
30
|
5. **After every Production deployment, verify all three gates before saying setup is complete:**
|
|
@@ -45,11 +47,11 @@ Open VERCEL_QUESTIONS.md first.
|
|
|
45
47
|
For Q1 and Q2: open a **clickable choice UI** (buttons / radio / option cards) using the verbatim options from VERCEL_QUESTIONS.md. Do not ask me to type 1 or 2 in chat when UI is available.
|
|
46
48
|
For Q1, Q2, Q3: use exact option wording from VERCEL_QUESTIONS.md. Do not rephrase options.
|
|
47
49
|
For Q3: DO NOT ask a branding choice. Open one form with ALL SEVEN optional inputs at once, then HARD STOP and WAIT for my submit or "skip". Never auto-continue with defaults without my reply. Never only Name + Primary colour. Logo = Upload above Logo URL.
|
|
48
|
-
After Q3,
|
|
50
|
+
After Q3, open Q4 immediately: one Env/Secret input for CMS_PASSWORD (blank/skip OK). Do NOT ask yes/no "want a password?" first.
|
|
49
51
|
After Q1 database choice, YOU set TOMORROWOS_STORE and DATABASE_SSL. Do not ask me to fill those.
|
|
50
52
|
After Q2 media storage choice, YOU set TOMORROWOS_MEDIA. Do not ask me to fill those.
|
|
51
53
|
After answers: run IRON GATE v0 Preview hygiene BEFORE debugging Postgres/media — clear root Next leftovers, restart supervised dev, prove GET /status is TomorrowOS JSON.
|
|
52
|
-
Before Publish: Output Directory
|
|
54
|
+
Before Publish: Output Directory empty/unset (NOT public). Build Command EMPTY (buildCommand: "") — never a no-op npm run build (forces static public/ check). Do not stuff public/robots.txt.
|
|
53
55
|
Run: npx @tomorrowos/sdk@latest init . --hosting v0 --force
|
|
54
56
|
Keep cms-starter-v0 layout.
|
|
55
57
|
Apply the NON-NEGOTIABLE VERCEL RUNTIME CONTRACT exactly:
|
|
@@ -111,8 +113,8 @@ almost always means **Vercel still thinks this is a Next.js / static deploy**, n
|
|
|
111
113
|
If it still says **Next.js**, patch it via Vercel API / CLI / dashboard **before** redeploying.
|
|
112
114
|
`"framework": null` in `vercel.json` alone is **not enough** if the dashboard still says Next.js.
|
|
113
115
|
2. **Install Command** = `npm install` / `pnpm install` / `yarn` (normal install).
|
|
114
|
-
3. **Build Command** =
|
|
115
|
-
**Never** run `next build` for Production.
|
|
116
|
+
3. **Build Command** = **empty / skip build** (`""` in `vercel.json` and dashboard).
|
|
117
|
+
**Never** run `next build` for Production. **Never** use a no-op `npm run build` / `node -e "process.exit(0)"` as the Production build command — that forces static-build mode and the `public/` output check.
|
|
116
118
|
4. **Production entry** = Fluid **Vercel Function** `api/index.ts` that **`export default server`** from shared `cms-app.ts` (see [WebSockets docs](https://vercel.com/docs/functions/websockets)). Local `npm start` may still use root `server.ts`.
|
|
117
119
|
5. **Output Directory** = **empty / unset**. Do **not** set `outputDirectory: "."` as a fake static site.
|
|
118
120
|
6. **Do** use a single `api/index.ts` that exports the TomorrowOS `http.Server`. **Do not** create a second TomorrowOS in `api/ws.ts`, and **do not** use bare `(req, res)` handlers that drop upgrades.
|
|
@@ -136,19 +138,29 @@ almost always means **Vercel still thinks this is a Next.js / static deploy**, n
|
|
|
136
138
|
```text
|
|
137
139
|
Error: The Output Directory "public" is empty.
|
|
138
140
|
```
|
|
139
|
-
|
|
141
|
+
or (after deleting `public/`):
|
|
142
|
+
```text
|
|
143
|
+
No Output Directory named "public"
|
|
144
|
+
```
|
|
145
|
+
(wording may vary; both mean Vercel is in **static-build** mode looking for `public/`)
|
|
146
|
+
|
|
147
|
+
**Root cause B (check in order):**
|
|
148
|
+
1. Project Settings **Output Directory = `public`** (explicit override) — clear it.
|
|
149
|
+
2. Output Directory is already **null**, but a **Build Command is defined** (`npm run build` or any no-op). With Framework=Other, a defined build command forces static-build mode and defaults the output check to `public/` — even when dashboard Output is unset.
|
|
140
150
|
|
|
141
151
|
**Correct fix (mandatory for A and B):**
|
|
142
152
|
|
|
143
|
-
1. Set **Output Directory** = **empty / unset
|
|
144
|
-
2.
|
|
145
|
-
3.
|
|
153
|
+
1. Set **Output Directory** = **empty / unset**.
|
|
154
|
+
2. Set **Build Command** = **empty** (`"buildCommand": ""` in `vercel.json` + dashboard). This is a **functions-only** deploy; skip the static build step entirely.
|
|
155
|
+
3. Framework Preset = **Other** / null; Fluid on; `api/index.ts` + rewrites per Scheme A.
|
|
156
|
+
4. Redeploy. Verify `GET /status` is **JSON** and WebSocket is **101**.
|
|
146
157
|
|
|
147
158
|
**Forbidden “fixes”:**
|
|
148
159
|
|
|
149
160
|
- Adding `public/robots.txt` / `.gitkeep` **so a static Output Directory = `public` build passes** — that leaves Production on the static trap path.
|
|
161
|
+
- Keeping a no-op `buildCommand: "npm run build"` while hoping Output=null is enough — the defined build command still triggers the `public/` check.
|
|
150
162
|
- Setting Output Directory to `cms-panel`, `.`, or `public`.
|
|
151
|
-
- Claiming Publish succeeded because the build log turned green while Output is still `public
|
|
163
|
+
- Claiming Publish succeeded because the build log turned green while Output is still `public` or Build Command still runs a static check.
|
|
152
164
|
|
|
153
165
|
**Optional:** If some tooling creates an empty `public/` folder, delete it or ignore it — **never** point Output Directory at it.
|
|
154
166
|
|
|
@@ -192,10 +204,14 @@ Ask **only** these questions, in **this exact order**. **Copy the ?Ask exactly??
|
|
|
192
204
|
| 1 | **Question 1** ? Database (Supabase ? Neon) | Always |
|
|
193
205
|
| 2 | **Question 2** ? Media (**Cloudinary recommended** ? Vercel Blob) | Always (after Q1) |
|
|
194
206
|
| 3 | **Question 3** - Brand form (`brand.json` only; **not a choice** - open all 7 optional inputs at once) | Always (after Q2) |
|
|
195
|
-
| 4 | **Question 4** - Optional CMS password Env `CMS_PASSWORD` (**
|
|
207
|
+
| 4 | **Question 4** - Optional CMS password Env `CMS_PASSWORD` (**immediately after Q3**; blank = skip; **no** yes/no prelude) | Always last |
|
|
196
208
|
|
|
197
209
|
**That is the complete list (Q1–Q4).** Do **not** ask how many screens / devices.
|
|
198
210
|
|
|
211
|
+
| Step UX | Rule |
|
|
212
|
+
|---------|------|
|
|
213
|
+
| Q4 CMS password | **Immediately after Q3** — one Env/Secret input for `CMS_PASSWORD` (blank/skip allowed). **Never** ask a yes/no "do you want a password?" first. |
|
|
214
|
+
|
|
199
215
|
**Forbidden invented Question 2 options (never offer these in chat or UI):**
|
|
200
216
|
|
|
201
217
|
- ???Vercel Blob **(recommended)**??as option 1 ??Blob is option **2**, not recommended over Cloudinary
|
|
@@ -232,6 +248,7 @@ Then ask **Question 1**.
|
|
|
232
248
|
|
|
233
249
|
1. **Open `VERCEL_QUESTIONS.md` first.** Ask Q1 → configure → Q2 → configure → Q3 → Q4. Never paraphrase question options. Never use `REPLIT_SETUP.md` as the questionnaire. **Never** ask for OpenAI or other LLM API keys.
|
|
234
250
|
1a. **Q1 and Q2 UX:** Prefer a **clickable choice UI** (same pattern for both): two option buttons/cards matching the verbatim labels. **Forbidden when UI exists:** chat-only “Reply with 1 or 2”. Chat typing is fallback only if the platform cannot render choices.
|
|
251
|
+
1b. **Q4 UX:** Immediately after Q3, open the **`CMS_PASSWORD` Env/Secret input**. **Forbidden:** yes/no “Do you want a password / enable auth?” prelude. Blank/skip is a complete answer.
|
|
235
252
|
2. **Question 2 options are fixed:** (1) Cloudinary **(recommended)**, (2) Vercel Blob. Do not reorder; do not invent Supabase Storage, local disk, or disable-uploads.
|
|
236
253
|
3. **Cloudinary:** open **one** Vercel Env popup with **all** Cloudinary fields together. Do **not** quiz one credential at a time.
|
|
237
254
|
4. **`TOMORROWOS_STORE` + `DATABASE_SSL` = agent-owned.** After Q1 choice (and URL if needed), set them yourself in Vercel Env Vars. **Never** include them as blank fields for the customer. Mapping: Supabase ? `TOMORROWOS_STORE=supabase` + `DATABASE_SSL=true`; Neon ? `TOMORROWOS_STORE=postgres` + `DATABASE_SSL=true`. **Do not offer SQLite as a questionnaire choice** ? it is ephemeral on Vercel and unsuitable for production.
|
|
@@ -252,7 +269,7 @@ Then ask **Question 1**.
|
|
|
252
269
|
19. **Q3 is a form, not a question — and you must WAIT.** After Q2, open one dialog with **all seven** optional inputs visible together, then **stop and wait** for submit or explicit **"skip"**. **Never** auto-continue because fields are optional. **Never** ask a preliminary branding choice. **Never** show only Product Name + Primary colour. **Never** use multiple-choice / Option A-B for branding. Logo = **Upload** above **Logo URL**.
|
|
253
270
|
20. **IRON GATE after Q&A:** Before blaming Neon / Blob / migrations, complete **IRON GATE — v0 Preview hygiene** below. Preview 500s are usually leftover root Next or a stale supervised `next-server`, not a bad Q1/Q2 choice.
|
|
254
271
|
|
|
255
|
-
**Question order:** Q1 -> (auto-set store env) -> Q2 -> Q3 form (**wait for user**) -> Q4
|
|
272
|
+
**Question order:** Q1 -> (auto-set store env) -> Q2 -> Q3 form (**wait for user**) -> Q4 `CMS_PASSWORD` Env input (**no yes/no prelude**; blank/skip OK) -> **IRON GATE** -> execution checklist.
|
|
256
273
|
|
|
257
274
|
---
|
|
258
275
|
|
|
@@ -415,7 +432,7 @@ SDK behaviour (0.9.32+):
|
|
|
415
432
|
"fluid": true,
|
|
416
433
|
"framework": null,
|
|
417
434
|
"installCommand": "npm install",
|
|
418
|
-
"buildCommand": "
|
|
435
|
+
"buildCommand": "",
|
|
419
436
|
"functions": {
|
|
420
437
|
"api/index.ts": {
|
|
421
438
|
"maxDuration": 300,
|
|
@@ -429,7 +446,7 @@ SDK behaviour (0.9.32+):
|
|
|
429
446
|
}
|
|
430
447
|
```
|
|
431
448
|
|
|
432
|
-
**`maxDuration` plan limits:** Hobby / many default plans allow **1
|
|
449
|
+
**`maxDuration` plan limits:** Hobby / many default plans allow **1–300** seconds. **800** requires a higher Vercel plan. Prefer **`300`** unless the account already allows more — otherwise Publish fails with *maxDuration must be between 1 and 300 / upgrade your plan*.
|
|
433
450
|
|
|
434
451
|
**Why rewrites:** Public URLs stay `https://app.vercel.app/` and `/status` while the Function mount is `/api`. Device `wss://app.vercel.app/` is rewritten to the same Function so one isolate handles HTTP + WS.
|
|
435
452
|
|
|
@@ -439,8 +456,8 @@ SDK behaviour (0.9.32+):
|
|
|
439
456
|
|
|
440
457
|
- `"fluid": true` is required for WebSockets
|
|
441
458
|
- **Do not** set `outputDirectory` to `cms-panel` / `public`
|
|
442
|
-
- `"buildCommand"`
|
|
443
|
-
- Dashboard Output Directory must stay **empty**
|
|
459
|
+
- `"buildCommand": ""` — **skip build entirely** (functions-only). **Never** `next build`. **Never** a no-op `npm run build` as Production build (forces static `public/` check)
|
|
460
|
+
- Dashboard Output Directory must stay **empty**; dashboard Build Command must stay **empty** (or match `""`)
|
|
444
461
|
|
|
445
462
|
### A4 — Vercel Project Settings (dashboard — mandatory)
|
|
446
463
|
|
|
@@ -448,14 +465,17 @@ SDK behaviour (0.9.32+):
|
|
|
448
465
|
|---------|----------------|
|
|
449
466
|
| Framework Preset | **Other** / null — **not Next.js** |
|
|
450
467
|
| Install Command | `npm install` |
|
|
451
|
-
| Build Command | `npm run build`
|
|
468
|
+
| **Build Command** | **empty / skip** — **not** `npm run build` |
|
|
452
469
|
| **Output Directory** | **empty / unset** — **never `public`** |
|
|
453
470
|
| Fluid compute | **On** |
|
|
454
471
|
| WebSockets | Account must allow Functions WebSockets (see docs — Permissions Required) |
|
|
455
472
|
|
|
456
|
-
**If Publish build fails with `The Output Directory "public" is empty
|
|
473
|
+
**If Publish build fails with `The Output Directory "public" is empty` or `public` not found:**
|
|
474
|
+
1. Clear Output Directory if set to `public`.
|
|
475
|
+
2. If Output is already null: set **Build Command** / `vercel.json` `"buildCommand"` to **`""`** and redeploy. A defined build command (even no-op) forces static-build mode.
|
|
476
|
+
3. Do **not** add `public/robots.txt` as the primary fix.
|
|
457
477
|
|
|
458
|
-
**`vercel.json` must not set `outputDirectory`.** Leaving it out is correct
|
|
478
|
+
**`vercel.json` must not set `outputDirectory`.** Leaving it out is correct. **`buildCommand` must be `""`** (empty string), not omitted if the dashboard still has a leftover `npm run build` — set both file and dashboard.
|
|
459
479
|
|
|
460
480
|
### A5 ??Publish acceptance (all must pass)
|
|
461
481
|
|
|
@@ -532,7 +552,7 @@ Adapt script names / process runners as needed. **Invariant:**
|
|
|
532
552
|
|
|
533
553
|
- **Local `npm start`** = TomorrowOS Node with `server.listen`.
|
|
534
554
|
- **Vercel Production** = Function `api/index.ts` (SDK `autoListen=false` when `VERCEL` is set).
|
|
535
|
-
- **`
|
|
555
|
+
- **`vercel.json` `"buildCommand"`** = `""` (skip build). Optional `package.json` `"build"` no-op is unused by Vercel Publish — **never** wire it as the Production Build Command.
|
|
536
556
|
- **Preview / v0** = Next on public port + TomorrowOS on internal port + proxy.
|
|
537
557
|
|
|
538
558
|
### Minimal dependencies (Production)
|
|
@@ -649,23 +669,23 @@ Write `vercel.json` so Production cannot be mistaken for Next. Minimum:
|
|
|
649
669
|
"fluid": true,
|
|
650
670
|
"framework": null,
|
|
651
671
|
"installCommand": "npm install",
|
|
652
|
-
"buildCommand": "
|
|
672
|
+
"buildCommand": ""
|
|
653
673
|
}
|
|
654
674
|
```
|
|
655
675
|
|
|
656
|
-
Use `pnpm` / `yarn` variants of install
|
|
676
|
+
Use `pnpm` / `yarn` variants of install if that is the project's package manager. **`buildCommand` must be `""`** (skip build) — do **not** set `npm run build` even as a no-op.
|
|
657
677
|
|
|
658
|
-
**Do not** add `startCommand`, `processes`, or `outputDirectory` to `vercel.json` when v0 schema rejects them. Start = `package.json` `"start": "tsx server.ts"`. Output Directory = **empty in dashboard**.
|
|
678
|
+
**Do not** add `startCommand`, `processes`, or `outputDirectory` to `vercel.json` when v0 schema rejects them. Start = `package.json` `"start": "tsx server.ts"`. Output Directory = **empty in dashboard**. Build Command = **empty in dashboard**.
|
|
659
679
|
|
|
660
|
-
**Also force Project Settings (dashboard or Vercel API)
|
|
680
|
+
**Also force Project Settings (dashboard or Vercel API) — this is mandatory (see Scheme A4):**
|
|
661
681
|
|
|
662
682
|
| Setting | Required value |
|
|
663
683
|
|---------|----------------|
|
|
664
|
-
| Framework Preset | **Other** / null
|
|
684
|
+
| Framework Preset | **Other** / null — **not Next.js** |
|
|
665
685
|
| Install Command | `npm install` (or pnpm/yarn) |
|
|
666
|
-
| Build Command | `npm run build`
|
|
667
|
-
| Output Directory | **empty / null**
|
|
668
|
-
| Start Command | `npm run start`
|
|
686
|
+
| **Build Command** | **empty / skip** — **not** `npm run build` |
|
|
687
|
+
| Output Directory | **empty / null** — **NOT `public`** |
|
|
688
|
+
| Start Command | `npm run start` — `tsx server.ts` (or `.mts`) — set in **dashboard**, not `vercel.json` |
|
|
669
689
|
| Fluid compute | **On** |
|
|
670
690
|
|
|
671
691
|
If `next` / `next.config.*` exist for Preview and the dashboard still auto-selects Next.js:
|
|
@@ -967,9 +987,20 @@ Set `cmsEndpoint` only if they already know the public `https://?vercel.app` URL
|
|
|
967
987
|
|
|
968
988
|
> **Optional.** Protect the Control Panel with app-level auth. You may **skip** and set Env Var `CMS_PASSWORD` later (then Redeploy).
|
|
969
989
|
|
|
970
|
-
**
|
|
990
|
+
> **IRON RULE — no prelude:** As soon as Q3 is submitted/skipped, open **this** step next. Do **not** first ask whether they want a password / auth / lock. Open the password Env/Secret field (or one chat prompt) immediately; blank/skip is a complete Q4 answer.
|
|
971
991
|
|
|
972
|
-
|
|
992
|
+
**UX (required):** Open **one** Env/Secret input labeled **`CMS_PASSWORD`** (password field). User may enter a password **or** leave blank / skip.
|
|
993
|
+
|
|
994
|
+
**Ask (Env input — preferred — or one chat reply):**
|
|
995
|
+
|
|
996
|
+
> Optional CMS password — Environment Variable **`CMS_PASSWORD`**.
|
|
997
|
+
>
|
|
998
|
+
> Enter a password to lock the Control Panel, or leave blank / skip to keep the panel open. You can add `CMS_PASSWORD` later in Vercel → Settings → Environment Variables and redeploy.
|
|
999
|
+
|
|
1000
|
+
**Forbidden before / instead of this input:**
|
|
1001
|
+
- "Do you want to protect the CMS?"
|
|
1002
|
+
- "Add a password?" / "Enable auth?"
|
|
1003
|
+
- Option A/B or yes/no for password first
|
|
973
1004
|
|
|
974
1005
|
**Why:**
|
|
975
1006
|
- Locks the **CMS Control Panel only** (not the whole deployment).
|
|
@@ -1010,9 +1041,9 @@ Then (**Scheme A — mandatory for Publish**):
|
|
|
1010
1041
|
|
|
1011
1042
|
1. Keep **`server.ts`** at **project root** with top-level `listen()` + `export default server`.
|
|
1012
1043
|
2. **Immediately** move leftover v0 Next from root into **`preview/`** or delete root Next files (`next.config.*`, `app/`, Next `tsconfig` / `postcss` / `next-env.d.ts`, starter `components/`). Production must not see root Next.
|
|
1013
|
-
3. Write `vercel.json` per **Scheme A3** (`fluid`, `framework: null`,
|
|
1014
|
-
4. **Force Project Settings** per **Scheme A4** (Framework = Other, Output Directory **empty/unset**, Start = `npm run start`, Fluid on). Patch dashboard via API if it still says Next.js **or**
|
|
1015
|
-
4a. **Pre-Publish
|
|
1044
|
+
3. Write `vercel.json` per **Scheme A3** (`fluid`, `framework: null`, `"buildCommand": ""` — **no** `startCommand`, **no** no-op `npm run build`).
|
|
1045
|
+
4. **Force Project Settings** per **Scheme A4** (Framework = Other, Output Directory **empty/unset**, Build Command **empty**, Start = `npm run start`, Fluid on). Patch dashboard via API if it still says Next.js, Output = `public`, **or** Build = `npm run build`.
|
|
1046
|
+
4a. **Pre-Publish build/output check:** If build fails with `Output Directory "public" is empty` / not found: clear Output Directory **and** set Build Command / `buildCommand` to **`""`**. Do **not** add `public/robots.txt`. Do **not** keep a no-op build command.
|
|
1016
1047
|
5. Do **not** add root `api/` catch-all for raw `http.Server`.
|
|
1017
1048
|
6. Do **not** add `.replit*`.
|
|
1018
1049
|
7. If Q2 = Vercel Blob: set `BLOB_READ_WRITE_TOKEN` + `TOMORROWOS_MEDIA=vercel-blob` (SDK-native; no custom bridge).
|
|
@@ -1059,15 +1090,16 @@ vercel --prod
|
|
|
1059
1090
|
|
|
1060
1091
|
**Publish acceptance checklist (all must pass ??Scheme A5):**
|
|
1061
1092
|
|
|
1062
|
-
1. Framework Preset = **Other** / null (dashboard confirms
|
|
1093
|
+
1. Framework Preset = **Other** / null (dashboard confirms — not Next.js)
|
|
1063
1094
|
2. Output Directory = **empty** (not `public`)
|
|
1095
|
+
2a. Build Command = **empty** (`"buildCommand": ""` — not `npm run build`)
|
|
1064
1096
|
3. Start Command = Node `TomorrowOS.listen` (`npm run start` / `tsx server.ts`)
|
|
1065
1097
|
4. Fluid compute on
|
|
1066
1098
|
5. Env Vars present for Production
|
|
1067
|
-
6. Production `GET /status` returns **JSON**
|
|
1068
|
-
7. Production `GET /` returns Control Panel HTML
|
|
1099
|
+
6. Production `GET /status` returns **JSON** — **not** HTML (`Unexpected token 'T'` means this failed)
|
|
1100
|
+
7. Production `GET /` returns Control Panel HTML — **not** `404: NOT_FOUND`
|
|
1069
1101
|
|
|
1070
|
-
If step 6 fails but step 7 passes: **static `public/` trap**
|
|
1102
|
+
If step 6 fails but step 7 passes: **static `public/` trap** — Vercel is not running Node. Re-apply Scheme A3–A4; try **Path B** (Git / `vercel --prod`); do **not** invent `api/` + `rewrites`.
|
|
1071
1103
|
|
|
1072
1104
|
Tell the user:
|
|
1073
1105
|
|
|
@@ -1119,8 +1151,9 @@ More detail: https://docs.tomorrowos.org/docs/os/tizen and https://docs.tomorrow
|
|
|
1119
1151
|
|
|
1120
1152
|
| Symptom | Likely cause | Fix |
|
|
1121
1153
|
|---------|--------------|-----|
|
|
1122
|
-
| Build: `Output Directory "public" is empty` |
|
|
1154
|
+
| Build: `Output Directory "public" is empty` / public not found | (1) Output Directory = `public`, **or** (2) Output null but **Build Command defined** → static-build mode | Clear Output; set `"buildCommand": ""` + dashboard Build empty; Fluid `api/index.ts`. Do **not** primary-fix with `public/robots.txt` or keep no-op `npm run build` |
|
|
1123
1155
|
| Agent asked Q2 as chat “type 1 or 2” while choice UI available | Off-protocol Q2 UX | Re-ask Q2 with **clickable** Cloudinary / Vercel Blob options (same pattern as Q1) |
|
|
1156
|
+
| Agent asked yes/no “want a CMS password?” before Q4 | Off-protocol Q4 UX | After Q3, open **CMS_PASSWORD** Env input immediately (blank/skip OK) |
|
|
1124
1157
|
| Preview 500 / Turbopack / `ENOENT .../app` after Q1–Q3 | Leftover **root** Next from v0 starter; not Neon/Blob | **IRON GATE:** delete/move root `app/` + `next.config.*`; keep `preview/`; restart supervised `dev`; prove `/status` JSON |
|
|
1125
1158
|
| `Internal Server Error` + logs blame missing `DATABASE_URL` in a **manual** Bash server | `dotenv` loaded `.env` only; secret is in `.env.development.local` / supervised env | Restart **supervised** Preview process; or load both env files — do **not** immediately change Neon URL |
|
|
1126
1159
|
| `EADDRINUSE :3000` while debugging | Second `pnpm dev` / stale `next-server` after script rewrite | Kill stale Next/tsx; one process; let supervisor re-exec new `"dev"` |
|
|
@@ -1134,7 +1167,7 @@ More detail: https://docs.tomorrowos.org/docs/os/tizen and https://docs.tomorrow
|
|
|
1134
1167
|
| `vercel.json` error: invalid `startCommand` | v0 schema rejects it | Remove from `vercel.json`; Function entry does not need startCommand |
|
|
1135
1168
|
| Separate `api/ws.ts` with a second `new TomorrowOS` | Two isolates ??pairing memory split | **One** Function only (`api/index.ts` ??shared `cms-app.ts`) |
|
|
1136
1169
|
| `vercel inspect` shows Output = `public if it exists` | Framework=Other static default | Force Output Directory **empty**; use `cms-panel/`; Path B redeploy |
|
|
1137
|
-
| Build runs `next build` / missing routes-manifest | Next auto-detected from root `next.config` / `app/` | Move Next to `preview/`; Framework null/Other; `
|
|
1170
|
+
| Build runs `next build` / missing routes-manifest | Next auto-detected from root `next.config` / `app/` | Move Next to `preview/`; Framework null/Other; `"buildCommand": ""` |
|
|
1138
1171
|
| Preview blank but logs show TomorrowOS listening | v0 Next intercepts public port | Add Next reverse proxy ??internal TomorrowOS port |
|
|
1139
1172
|
| Preview works, Publish broken / Next-only | Production still on Next | Switch Production to Fluid Function `api/index.ts` |
|
|
1140
1173
|
| `ENETUNREACH` / IPv6 / `:5432` | Direct Postgres URL | Use **pooled** URL (Supabase `:6543` or Neon pooler) |
|
|
@@ -1202,7 +1235,9 @@ Protocol complete when:
|
|
|
1202
1235
|
|
|
1203
1236
|
## Protocol version
|
|
1204
1237
|
|
|
1205
|
-
`vercel-setup/1.
|
|
1238
|
+
`vercel-setup/1.19` - pairs with `@tomorrowos/sdk` 0.9.70+ and `VERCEL_QUESTIONS.md` 1.8.
|
|
1239
|
+
|
|
1240
|
+
**Changelog 1.19:** Publish Build Command must be **empty** (`"buildCommand": ""`) — a defined no-op `npm run build` forces Vercel static-build mode and the `public/` output check (empty → “not found” after deleting `public/`). Q4 opens **immediately after Q3** as the `CMS_PASSWORD` Env input with **no** yes/no password prelude.
|
|
1206
1241
|
|
|
1207
1242
|
**Changelog 1.18:** Q1/Q2 must use **clickable choice UI** (not chat “type 1 or 2” when UI exists). Publish build error `Output Directory "public" is empty` → **clear Output Directory** (forbidden primary fix: stuff `public/robots.txt` while Output stays `public`). Strengthens static-output trap docs.
|
|
1208
1243
|
|
package/VERCEL_UPGRADE.md
CHANGED
|
@@ -40,6 +40,7 @@ When any of these triggers fire:
|
|
|
40
40
|
4. **Do NOT** blindly overwrite `cms-panel/methods.js`, `cms-panel/index.html`, `cms-panel/panel.css`, `server.ts`, `cms-app.ts`, or `api/index.ts` with template copies. Always **diff → report → merge only with user consent** (or apply surgical patches that preserve custom code).
|
|
41
41
|
5. **Do NOT** create a second `new TomorrowOS(...)` in `api/ws.ts` or elsewhere. **One** shared instance only.
|
|
42
42
|
6. **Do NOT** set Vercel Output Directory to `public/` or switch Production to Next/`next start` / static-only.
|
|
43
|
+
6a. **Do NOT** keep a Production Build Command of `npm run build` (even no-op) — use `"buildCommand": ""` so Vercel does not enter static-build / `public/` output checks.
|
|
43
44
|
7. Prefer **`npm install @tomorrowos/sdk@latest`** over pinning an older version unless the user named a specific version.
|
|
44
45
|
8. Keep `tsx` available at runtime (`dependencies`, not only `devDependencies`) if local `npm run start` / Preview still relies on `tsx server.ts`.
|
|
45
46
|
9. After upgrade, re-check Production gates: `GET /status` → JSON, `GET /` → Control Panel, WebSocket `/` or `/api` → **101**.
|
|
@@ -54,7 +55,7 @@ Capture and remember:
|
|
|
54
55
|
|------|-----|
|
|
55
56
|
| **Old SDK version** | `package.json` → `dependencies["@tomorrowos/sdk"]`, and/or `npm ls @tomorrowos/sdk --depth=0` |
|
|
56
57
|
| **Layout** | Confirm `cms-starter-v0` shape: `cms-app.ts` / `api/index.ts` / `cms-panel/` (or equivalent shared TomorrowOS export) |
|
|
57
|
-
| **Runtime** | Confirm Fluid Function + `vercel.json` rewrites; Output Directory empty |
|
|
58
|
+
| **Runtime** | Confirm Fluid Function + `vercel.json` rewrites; Output Directory empty; **Build Command empty** (`"buildCommand": ""`) |
|
|
58
59
|
|
|
59
60
|
If `@tomorrowos/sdk` is not a dependency, stop and tell the user this project does not look like a TomorrowOS CMS — offer `VERCEL_SETUP.md` instead. Do **not** run `init` unless they explicitly switch to setup.
|
|
60
61
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "my-cms",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.4",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@tomorrowos/sdk": "^1.1.
|
|
11
|
+
"@tomorrowos/sdk": "^1.1.4",
|
|
12
12
|
"dotenv": "^17.2.3",
|
|
13
13
|
"tsx": "^4.19.0"
|
|
14
14
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "CMS server on @tomorrowos/sdk. Add your UI (React, static files, etc.) alongside this server.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"type": "module",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"start": "tsx server.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@tomorrowos/sdk": "^1.1.
|
|
15
|
+
"@tomorrowos/sdk": "^1.1.4",
|
|
16
16
|
"dotenv": "^17.2.3",
|
|
17
17
|
"tsx": "^4.19.0"
|
|
18
18
|
},
|
|
@@ -10,7 +10,10 @@ This starter is for **Vercel Publish** and **v0**. It follows
|
|
|
10
10
|
- **`preview/`** — Next.js shell for v0 Preview only
|
|
11
11
|
- **`vercel.json`** — `fluid`, rewrites → `/api`, `maxDuration`
|
|
12
12
|
|
|
13
|
-
**Publish
|
|
13
|
+
**Publish settings (critical):**
|
|
14
|
+
- **Output Directory** = empty / unset (never `public/`)
|
|
15
|
+
- **Build Command** = empty / skip (`"buildCommand": ""` in `vercel.json`) — a defined no-op `npm run build` forces Vercel static-build mode and requires `public/`
|
|
16
|
+
- If the build fails with `The Output Directory "public" is empty` (or public not found): clear Output Directory **and** set Build Command to empty — do **not** add filler files under `public/`
|
|
14
17
|
|
|
15
18
|
## Scaffold
|
|
16
19
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "my-cms",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.4",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@tomorrowos/sdk": "^1.1.
|
|
11
|
+
"@tomorrowos/sdk": "^1.1.4",
|
|
12
12
|
"dotenv": "^17.2.3",
|
|
13
13
|
"tsx": "^4.19.0"
|
|
14
14
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "TomorrowOS CMS for Vercel / v0 Publish (Fluid Function + WebSockets + optional Next Preview).",
|
|
5
5
|
"private": true,
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"build": "node -e \"process.exit(0)\""
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@tomorrowos/sdk": "^1.1.
|
|
19
|
+
"@tomorrowos/sdk": "^1.1.4",
|
|
20
20
|
"dotenv": "^17.2.3",
|
|
21
21
|
"tsx": "^4.19.0"
|
|
22
22
|
},
|