@tomorrowos/sdk 1.1.2 → 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 +21 -11
- package/VERCEL_SETUP.md +142 -57
- 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 +5 -0
- 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,17 +1,21 @@
|
|
|
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
|
-
> **Q1 and Q2 are choice questions
|
|
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.**
|
|
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.
|
|
8
10
|
> **HARD STOP on Q3:** show the form, then **wait** for the user's reply. Optional fields do **not** mean you may auto-skip.
|
|
9
11
|
> **Q4 is optional:** blank/skip is valid; they can set `CMS_PASSWORD` later.
|
|
10
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.
|
|
11
13
|
|
|
12
14
|
---
|
|
13
15
|
|
|
14
|
-
## Q1 - Database (paste
|
|
16
|
+
## Q1 - Database (clickable choice UI — paste option text exactly)
|
|
17
|
+
|
|
18
|
+
**UX:** Open a **clickable choice UI** (two option buttons / radio cards). Labels must match the bold titles below.
|
|
15
19
|
|
|
16
20
|
Which database should TomorrowOS use on Vercel?
|
|
17
21
|
|
|
@@ -19,7 +23,7 @@ Which database should TomorrowOS use on Vercel?
|
|
|
19
23
|
|
|
20
24
|
**2. Neon Postgres** - serverless Postgres native to Vercel; use Neon's **pooled** connection string from the Neon dashboard (not the direct un-pooled host for serverless).
|
|
21
25
|
|
|
22
|
-
Reply with **1** or **2** (or "Supabase" / "Neon").
|
|
26
|
+
**Fallback only** (no choice UI available): Reply with **1** or **2** (or "Supabase" / "Neon").
|
|
23
27
|
|
|
24
28
|
---
|
|
25
29
|
|
|
@@ -34,7 +38,9 @@ Never show blank Env fields for `TOMORROWOS_STORE` or `DATABASE_SSL`.
|
|
|
34
38
|
|
|
35
39
|
---
|
|
36
40
|
|
|
37
|
-
## Q2 - Media (
|
|
41
|
+
## Q2 - Media (clickable choice UI — same pattern as Q1)
|
|
42
|
+
|
|
43
|
+
**UX:** Open a **clickable choice UI** (two option buttons / radio cards). **Forbidden when UI exists:** chat-only “Reply with **1** or **2**”.
|
|
38
44
|
|
|
39
45
|
How should playlist media (images/videos) be stored?
|
|
40
46
|
|
|
@@ -42,7 +48,7 @@ How should playlist media (images/videos) be stored?
|
|
|
42
48
|
|
|
43
49
|
**2. Vercel Blob** - Vercel-native object storage; durable `https://*.public.blob.vercel-storage.com/...` URLs. Use when you want media on the same Vercel project without a Cloudinary account.
|
|
44
50
|
|
|
45
|
-
Reply with **1** or **2** (or "Cloudinary" / "Vercel Blob").
|
|
51
|
+
**Fallback only** (no choice UI available): Reply with **1** or **2** (or "Cloudinary" / "Vercel Blob").
|
|
46
52
|
|
|
47
53
|
**Forbidden replacements (never ask these):** Vercel Blob as recommended #1; Supabase Storage; S3 / R2 / B2 / `MEDIA_S3_*`; "no media storage" / disable uploads; local disk only.
|
|
48
54
|
|
|
@@ -88,18 +94,22 @@ Reply with **1** or **2** (or "Cloudinary" / "Vercel Blob").
|
|
|
88
94
|
- Auto-continuing to init/scaffold/deploy without a user Q3 reply or explicit "skip"
|
|
89
95
|
- Interpreting "do not re-ask" as "do not wait for the first reply"
|
|
90
96
|
|
|
91
|
-
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.
|
|
92
98
|
Blank fields -> keep existing `brand.json`. Logo blank -> `./assets/logo.svg`.
|
|
93
99
|
|
|
94
100
|
---
|
|
95
101
|
|
|
96
|
-
## Q4 - Optional CMS password (
|
|
102
|
+
## Q4 - Optional CMS password (Env input immediately after Q3)
|
|
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.
|
|
105
|
+
|
|
106
|
+
**UX (required):** One Env/Secret field labeled **`CMS_PASSWORD`** (password input). User may enter a password **or** leave blank / skip.
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
**Title / helper:**
|
|
99
109
|
|
|
100
|
-
|
|
110
|
+
Optional CMS password — Environment Variable **`CMS_PASSWORD`**.
|
|
101
111
|
|
|
102
|
-
|
|
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.
|
|
103
113
|
|
|
104
114
|
**Notes for the agent (do not invent extra UX):**
|
|
105
115
|
- This is **optional**. Blank/skip is a valid complete answer.
|
package/VERCEL_SETUP.md
CHANGED
|
@@ -5,12 +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
|
-
> **Q1/Q2 = choice
|
|
12
|
-
> **
|
|
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
|
+
> **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` (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.
|
|
13
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**.
|
|
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`.
|
|
14
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).
|
|
15
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.
|
|
16
19
|
|
|
@@ -20,6 +23,8 @@ The following rules are **mandatory acceptance criteria**, not suggestions. The
|
|
|
20
23
|
|
|
21
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.
|
|
22
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`.
|
|
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.
|
|
23
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.
|
|
24
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.
|
|
25
30
|
5. **After every Production deployment, verify all three gates before saying setup is complete:**
|
|
@@ -39,12 +44,14 @@ When a human pastes a prompt like this, **read this file and start Question 1 im
|
|
|
39
44
|
Follow @tomorrowos/sdk (an NPM package) VERCEL_SETUP.md and set up my TomorrowOS CMS from scratch.
|
|
40
45
|
|
|
41
46
|
Open VERCEL_QUESTIONS.md first.
|
|
42
|
-
For Q1
|
|
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.
|
|
48
|
+
For Q1, Q2, Q3: use exact option wording from VERCEL_QUESTIONS.md. Do not rephrase options.
|
|
43
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.
|
|
44
|
-
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.
|
|
45
51
|
After Q1 database choice, YOU set TOMORROWOS_STORE and DATABASE_SSL. Do not ask me to fill those.
|
|
46
52
|
After Q2 media storage choice, YOU set TOMORROWOS_MEDIA. Do not ask me to fill those.
|
|
47
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.
|
|
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.
|
|
48
55
|
Run: npx @tomorrowos/sdk@latest init . --hosting v0 --force
|
|
49
56
|
Keep cms-starter-v0 layout.
|
|
50
57
|
Apply the NON-NEGOTIABLE VERCEL RUNTIME CONTRACT exactly:
|
|
@@ -106,8 +113,8 @@ almost always means **Vercel still thinks this is a Next.js / static deploy**, n
|
|
|
106
113
|
If it still says **Next.js**, patch it via Vercel API / CLI / dashboard **before** redeploying.
|
|
107
114
|
`"framework": null` in `vercel.json` alone is **not enough** if the dashboard still says Next.js.
|
|
108
115
|
2. **Install Command** = `npm install` / `pnpm install` / `yarn` (normal install).
|
|
109
|
-
3. **Build Command** =
|
|
110
|
-
**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.
|
|
111
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`.
|
|
112
119
|
5. **Output Directory** = **empty / unset**. Do **not** set `outputDirectory: "."` as a fake static site.
|
|
113
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.
|
|
@@ -117,18 +124,47 @@ almost always means **Vercel still thinks this is a Next.js / static deploy**, n
|
|
|
117
124
|
|
|
118
125
|
**Setup is NOT complete** while Production `GET /` returns `404: NOT_FOUND` or WebSocket upgrade returns 200 HTML.
|
|
119
126
|
|
|
120
|
-
### Publish static trap
|
|
127
|
+
### Publish static trap — `public/` served without Node (read this)
|
|
121
128
|
|
|
122
|
-
A common
|
|
123
|
-
|
|
124
|
-
- `GET /` loads the Control Panel HTML (from static `public/index.html`)
|
|
129
|
+
**Symptom A — wrong runtime (common worse failure than `404: NOT_FOUND`):**
|
|
130
|
+
- `GET /` loads the Control Panel HTML (from static files)
|
|
125
131
|
- `GET /status`, `/devices`, etc. return **HTML** (Vercel 404 page)
|
|
126
132
|
- The panel shows **CMS unreachable** and console:
|
|
127
133
|
`Unexpected token 'T', "The page c"... is not valid JSON`
|
|
128
134
|
|
|
129
|
-
**Root cause:** Vercel deployed `public/` as a **static site** (Output Directory = `public` or Framework=Other default
|
|
135
|
+
**Root cause A:** Vercel deployed `public/` as a **static site** (Output Directory = `public` or Framework=Other default “public if it exists”). **No Function** is running TomorrowOS.
|
|
136
|
+
|
|
137
|
+
**Symptom B — build fails before deploy:**
|
|
138
|
+
```text
|
|
139
|
+
Error: The Output Directory "public" is empty.
|
|
140
|
+
```
|
|
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.
|
|
150
|
+
|
|
151
|
+
**Correct fix (mandatory for A and B):**
|
|
130
152
|
|
|
131
|
-
|
|
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**.
|
|
157
|
+
|
|
158
|
+
**Forbidden “fixes”:**
|
|
159
|
+
|
|
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.
|
|
162
|
+
- Setting Output Directory to `cms-panel`, `.`, or `public`.
|
|
163
|
+
- Claiming Publish succeeded because the build log turned green while Output is still `public` or Build Command still runs a static check.
|
|
164
|
+
|
|
165
|
+
**Optional:** If some tooling creates an empty `public/` folder, delete it or ignore it — **never** point Output Directory at it.
|
|
166
|
+
|
|
167
|
+
**Scheme A reminder:** use `cms-panel/` (not `public/`), Fluid Function `api/index.ts` + rewrites, Output Directory empty. Static UI is served **at runtime** via `staticRoot` in `listen()`.
|
|
132
168
|
|
|
133
169
|
**Publish gate (mandatory):** after deploy, `GET /status` must return **JSON** starting with `{`, not HTML starting with `<` or `The page`. **And** WebSocket upgrade on `/` or `/api` must return **101**.
|
|
134
170
|
|
|
@@ -168,10 +204,14 @@ Ask **only** these questions, in **this exact order**. **Copy the ?Ask exactly??
|
|
|
168
204
|
| 1 | **Question 1** ? Database (Supabase ? Neon) | Always |
|
|
169
205
|
| 2 | **Question 2** ? Media (**Cloudinary recommended** ? Vercel Blob) | Always (after Q1) |
|
|
170
206
|
| 3 | **Question 3** - Brand form (`brand.json` only; **not a choice** - open all 7 optional inputs at once) | Always (after Q2) |
|
|
171
|
-
| 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 |
|
|
172
208
|
|
|
173
209
|
**That is the complete list (Q1–Q4).** Do **not** ask how many screens / devices.
|
|
174
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
|
+
|
|
175
215
|
**Forbidden invented Question 2 options (never offer these in chat or UI):**
|
|
176
216
|
|
|
177
217
|
- ???Vercel Blob **(recommended)**??as option 1 ??Blob is option **2**, not recommended over Cloudinary
|
|
@@ -206,7 +246,9 @@ Then ask **Question 1**.
|
|
|
206
246
|
|
|
207
247
|
## Hard rules
|
|
208
248
|
|
|
209
|
-
1. **Open `VERCEL_QUESTIONS.md` first.**
|
|
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.
|
|
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.
|
|
210
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.
|
|
211
253
|
3. **Cloudinary:** open **one** Vercel Env popup with **all** Cloudinary fields together. Do **not** quiz one credential at a time.
|
|
212
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.
|
|
@@ -227,7 +269,7 @@ Then ask **Question 1**.
|
|
|
227
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**.
|
|
228
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.
|
|
229
271
|
|
|
230
|
-
**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.
|
|
231
273
|
|
|
232
274
|
---
|
|
233
275
|
|
|
@@ -390,7 +432,7 @@ SDK behaviour (0.9.32+):
|
|
|
390
432
|
"fluid": true,
|
|
391
433
|
"framework": null,
|
|
392
434
|
"installCommand": "npm install",
|
|
393
|
-
"buildCommand": "
|
|
435
|
+
"buildCommand": "",
|
|
394
436
|
"functions": {
|
|
395
437
|
"api/index.ts": {
|
|
396
438
|
"maxDuration": 300,
|
|
@@ -404,7 +446,7 @@ SDK behaviour (0.9.32+):
|
|
|
404
446
|
}
|
|
405
447
|
```
|
|
406
448
|
|
|
407
|
-
**`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*.
|
|
408
450
|
|
|
409
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.
|
|
410
452
|
|
|
@@ -414,19 +456,26 @@ SDK behaviour (0.9.32+):
|
|
|
414
456
|
|
|
415
457
|
- `"fluid": true` is required for WebSockets
|
|
416
458
|
- **Do not** set `outputDirectory` to `cms-panel` / `public`
|
|
417
|
-
- `"buildCommand"`
|
|
418
|
-
- 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 `""`)
|
|
419
461
|
|
|
420
|
-
### A4
|
|
462
|
+
### A4 — Vercel Project Settings (dashboard — mandatory)
|
|
421
463
|
|
|
422
464
|
| Setting | Required value |
|
|
423
465
|
|---------|----------------|
|
|
424
|
-
| Framework Preset | **Other** / null
|
|
466
|
+
| Framework Preset | **Other** / null — **not Next.js** |
|
|
425
467
|
| Install Command | `npm install` |
|
|
426
|
-
| Build Command | `npm run build`
|
|
427
|
-
| **Output Directory** | **empty** |
|
|
468
|
+
| **Build Command** | **empty / skip** — **not** `npm run build` |
|
|
469
|
+
| **Output Directory** | **empty / unset** — **never `public`** |
|
|
428
470
|
| Fluid compute | **On** |
|
|
429
|
-
| WebSockets | Account must allow Functions WebSockets (see docs
|
|
471
|
+
| WebSockets | Account must allow Functions WebSockets (see docs — Permissions Required) |
|
|
472
|
+
|
|
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.
|
|
477
|
+
|
|
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.
|
|
430
479
|
|
|
431
480
|
### A5 ??Publish acceptance (all must pass)
|
|
432
481
|
|
|
@@ -503,7 +552,7 @@ Adapt script names / process runners as needed. **Invariant:**
|
|
|
503
552
|
|
|
504
553
|
- **Local `npm start`** = TomorrowOS Node with `server.listen`.
|
|
505
554
|
- **Vercel Production** = Function `api/index.ts` (SDK `autoListen=false` when `VERCEL` is set).
|
|
506
|
-
- **`
|
|
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.
|
|
507
556
|
- **Preview / v0** = Next on public port + TomorrowOS on internal port + proxy.
|
|
508
557
|
|
|
509
558
|
### Minimal dependencies (Production)
|
|
@@ -620,23 +669,23 @@ Write `vercel.json` so Production cannot be mistaken for Next. Minimum:
|
|
|
620
669
|
"fluid": true,
|
|
621
670
|
"framework": null,
|
|
622
671
|
"installCommand": "npm install",
|
|
623
|
-
"buildCommand": "
|
|
672
|
+
"buildCommand": ""
|
|
624
673
|
}
|
|
625
674
|
```
|
|
626
675
|
|
|
627
|
-
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.
|
|
628
677
|
|
|
629
|
-
**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**.
|
|
630
679
|
|
|
631
|
-
**Also force Project Settings (dashboard or Vercel API)
|
|
680
|
+
**Also force Project Settings (dashboard or Vercel API) — this is mandatory (see Scheme A4):**
|
|
632
681
|
|
|
633
682
|
| Setting | Required value |
|
|
634
683
|
|---------|----------------|
|
|
635
|
-
| Framework Preset | **Other** / null
|
|
684
|
+
| Framework Preset | **Other** / null — **not Next.js** |
|
|
636
685
|
| Install Command | `npm install` (or pnpm/yarn) |
|
|
637
|
-
| Build Command | `npm run build`
|
|
638
|
-
| Output Directory | **empty / null**
|
|
639
|
-
| 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` |
|
|
640
689
|
| Fluid compute | **On** |
|
|
641
690
|
|
|
642
691
|
If `next` / `next.config.*` exist for Preview and the dashboard still auto-selects Next.js:
|
|
@@ -680,17 +729,26 @@ If Vercel?s UI and this file disagree on bundling, **prefer whatever keeps a sin
|
|
|
680
729
|
|
|
681
730
|
If you open an Env configuration UI for Q1, fields visible to the user may include **only** `SUPABASE_URL` or `DATABASE_URL`. **Do not** show blank `TOMORROWOS_STORE` / `DATABASE_SSL` inputs ? write those yourself in the same step.
|
|
682
731
|
|
|
683
|
-
### Step A
|
|
732
|
+
### Step A — Ask database choice (**clickable UI required**)
|
|
684
733
|
|
|
685
|
-
**
|
|
734
|
+
**UX:** Open a **choice UI** the user can **click** — two option buttons / radio cards / select list. Labels must match the verbatim options below. Same clickable pattern as Q2.
|
|
735
|
+
|
|
736
|
+
| # | Exact option label (UI) |
|
|
737
|
+
|---|-------------------------|
|
|
738
|
+
| 1 | **Supabase Postgres (recommended)** |
|
|
739
|
+
| 2 | **Neon Postgres** |
|
|
740
|
+
|
|
741
|
+
Supporting copy under each option may match `VERCEL_QUESTIONS.md`. **Do not** default to a chat message that only says “Reply with 1 or 2” when the platform can render choices.
|
|
742
|
+
|
|
743
|
+
**Ask exactly (wording / option text must match):**
|
|
686
744
|
|
|
687
745
|
> Which database should TomorrowOS use on Vercel?
|
|
688
746
|
>
|
|
689
|
-
> **1. Supabase Postgres (recommended)**
|
|
690
|
-
>
|
|
691
|
-
> **2. Neon Postgres** ? serverless Postgres native to Vercel; use Neon's **pooled** connection string from the Neon dashboard (not the direct un-pooled host for serverless).
|
|
747
|
+
> **1. Supabase Postgres (recommended)** — durable pairing/playlists; use the **Session pooler** URL (`*.pooler.supabase.com:6543`).
|
|
692
748
|
>
|
|
693
|
-
>
|
|
749
|
+
> **2. Neon Postgres** — serverless Postgres native to Vercel; use Neon's **pooled** connection string from the Neon dashboard (not the direct un-pooled host for serverless).
|
|
750
|
+
|
|
751
|
+
**Fallback only** (no choice UI available): allow chat reply **1** / **2** / "Supabase" / "Neon".
|
|
694
752
|
|
|
695
753
|
### Step B ??If **1 / Supabase**
|
|
696
754
|
|
|
@@ -746,19 +804,26 @@ If you open an Env configuration UI for Q1, fields visible to the user may inclu
|
|
|
746
804
|
> It is **not** about OpenAI, AI pairing, or LLM keys. If you are about to ask for an `sk-` key, **stop** ??you are off-protocol.
|
|
747
805
|
> **Copy the two options below verbatim.** Wrong examples that must **never** appear: "Vercel Blob (recommended)", "Supabase Storage", "No media storage / disable uploads", "local disk only".
|
|
748
806
|
|
|
749
|
-
### Step A
|
|
807
|
+
### Step A — Ask storage choice (**clickable UI required — same as Q1**)
|
|
808
|
+
|
|
809
|
+
**UX:** Open a **choice UI** the user can **click** — two option buttons / radio cards. **Forbidden when UI exists:** chat-only “Reply with **1** or **2**”.
|
|
750
810
|
|
|
751
|
-
|
|
811
|
+
| # | Exact option label (UI) |
|
|
812
|
+
|---|-------------------------|
|
|
813
|
+
| 1 | **Cloudinary (recommended)** |
|
|
814
|
+
| 2 | **Vercel Blob** |
|
|
815
|
+
|
|
816
|
+
**Ask exactly (wording must match — Cloudinary is recommended):**
|
|
752
817
|
|
|
753
818
|
> How should playlist media (images/videos) be stored?
|
|
754
819
|
>
|
|
755
|
-
> **1. Cloudinary (recommended)**
|
|
756
|
-
>
|
|
757
|
-
> **2. Vercel Blob** ? Vercel-native object storage; durable `https://*.public.blob.vercel-storage.com/...` URLs. Use when you want media on the same Vercel project without a Cloudinary account.
|
|
820
|
+
> **1. Cloudinary (recommended)** — durable public HTTPS URLs (`https://res.cloudinary.com/...`). Works out of the box with `@tomorrowos/sdk` auto-detection. **Prefer this on Vercel.**
|
|
758
821
|
>
|
|
759
|
-
>
|
|
822
|
+
> **2. Vercel Blob** — Vercel-native object storage; durable `https://*.public.blob.vercel-storage.com/...` URLs. Use when you want media on the same Vercel project without a Cloudinary account.
|
|
760
823
|
|
|
761
|
-
|
|
824
|
+
**Fallback only** (no choice UI): chat reply **1** / **2** / "Cloudinary" / "Vercel Blob".
|
|
825
|
+
|
|
826
|
+
If you catch yourself about to offer Blob-as-recommended, Supabase Storage, local disk, or "no media" — **stop and use the block above instead**.
|
|
762
827
|
|
|
763
828
|
### Step B ??If **1 / Cloudinary** (same Question 2 ??**one Env popup**)
|
|
764
829
|
|
|
@@ -922,9 +987,20 @@ Set `cmsEndpoint` only if they already know the public `https://?vercel.app` URL
|
|
|
922
987
|
|
|
923
988
|
> **Optional.** Protect the Control Panel with app-level auth. You may **skip** and set Env Var `CMS_PASSWORD` later (then Redeploy).
|
|
924
989
|
|
|
925
|
-
**
|
|
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.
|
|
991
|
+
|
|
992
|
+
**UX (required):** Open **one** Env/Secret input labeled **`CMS_PASSWORD`** (password field). User may enter a password **or** leave blank / skip.
|
|
926
993
|
|
|
927
|
-
|
|
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
|
|
928
1004
|
|
|
929
1005
|
**Why:**
|
|
930
1006
|
- Locks the **CMS Control Panel only** (not the whole deployment).
|
|
@@ -965,8 +1041,9 @@ Then (**Scheme A — mandatory for Publish**):
|
|
|
965
1041
|
|
|
966
1042
|
1. Keep **`server.ts`** at **project root** with top-level `listen()` + `export default server`.
|
|
967
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.
|
|
968
|
-
3. Write `vercel.json` per **Scheme A3** (`fluid`, `framework: null`,
|
|
969
|
-
4. **Force Project Settings** per **Scheme A4** (Framework = Other, Output Directory empty
|
|
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.
|
|
970
1047
|
5. Do **not** add root `api/` catch-all for raw `http.Server`.
|
|
971
1048
|
6. Do **not** add `.replit*`.
|
|
972
1049
|
7. If Q2 = Vercel Blob: set `BLOB_READ_WRITE_TOKEN` + `TOMORROWOS_MEDIA=vercel-blob` (SDK-native; no custom bridge).
|
|
@@ -1013,15 +1090,16 @@ vercel --prod
|
|
|
1013
1090
|
|
|
1014
1091
|
**Publish acceptance checklist (all must pass ??Scheme A5):**
|
|
1015
1092
|
|
|
1016
|
-
1. Framework Preset = **Other** / null (dashboard confirms
|
|
1093
|
+
1. Framework Preset = **Other** / null (dashboard confirms — not Next.js)
|
|
1017
1094
|
2. Output Directory = **empty** (not `public`)
|
|
1095
|
+
2a. Build Command = **empty** (`"buildCommand": ""` — not `npm run build`)
|
|
1018
1096
|
3. Start Command = Node `TomorrowOS.listen` (`npm run start` / `tsx server.ts`)
|
|
1019
1097
|
4. Fluid compute on
|
|
1020
1098
|
5. Env Vars present for Production
|
|
1021
|
-
6. Production `GET /status` returns **JSON**
|
|
1022
|
-
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`
|
|
1023
1101
|
|
|
1024
|
-
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`.
|
|
1025
1103
|
|
|
1026
1104
|
Tell the user:
|
|
1027
1105
|
|
|
@@ -1073,6 +1151,9 @@ More detail: https://docs.tomorrowos.org/docs/os/tizen and https://docs.tomorrow
|
|
|
1073
1151
|
|
|
1074
1152
|
| Symptom | Likely cause | Fix |
|
|
1075
1153
|
|---------|--------------|-----|
|
|
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` |
|
|
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) |
|
|
1076
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 |
|
|
1077
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 |
|
|
1078
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"` |
|
|
@@ -1086,7 +1167,7 @@ More detail: https://docs.tomorrowos.org/docs/os/tizen and https://docs.tomorrow
|
|
|
1086
1167
|
| `vercel.json` error: invalid `startCommand` | v0 schema rejects it | Remove from `vercel.json`; Function entry does not need startCommand |
|
|
1087
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`) |
|
|
1088
1169
|
| `vercel inspect` shows Output = `public if it exists` | Framework=Other static default | Force Output Directory **empty**; use `cms-panel/`; Path B redeploy |
|
|
1089
|
-
| 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": ""` |
|
|
1090
1171
|
| Preview blank but logs show TomorrowOS listening | v0 Next intercepts public port | Add Next reverse proxy ??internal TomorrowOS port |
|
|
1091
1172
|
| Preview works, Publish broken / Next-only | Production still on Next | Switch Production to Fluid Function `api/index.ts` |
|
|
1092
1173
|
| `ENETUNREACH` / IPv6 / `:5432` | Direct Postgres URL | Use **pooled** URL (Supabase `:6543` or Neon pooler) |
|
|
@@ -1154,7 +1235,11 @@ Protocol complete when:
|
|
|
1154
1235
|
|
|
1155
1236
|
## Protocol version
|
|
1156
1237
|
|
|
1157
|
-
`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.
|
|
1241
|
+
|
|
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.
|
|
1158
1243
|
|
|
1159
1244
|
**Changelog 1.17:** After Q&A, agents **must** run **IRON GATE — v0 Preview hygiene** before DB rabbit holes: clear root Next leftovers, restart supervised `dev`, prove `GET /status` is TomorrowOS JSON. Documents `.env` vs `.env.development.local` / supervised-env trap. Preview decision tree + cheat-sheet rows for Turbopack/`ENOENT`, missing `DATABASE_URL` in manual Bash, `EADDRINUSE`, stale `next-server`. Neon/Blob choices are not the usual Preview failure cause.
|
|
1160
1245
|
|
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,6 +10,11 @@ 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 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/`
|
|
17
|
+
|
|
13
18
|
## Scaffold
|
|
14
19
|
|
|
15
20
|
```bash
|
|
@@ -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
|
},
|