@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.
@@ -1,17 +1,21 @@
1
1
  # Vercel / v0 - Verbatim question bank
2
2
 
3
- > **Protocol:** `vercel-questions/1.6` (pairs with `VERCEL_SETUP.md` 1.17+ / `@tomorrowos/sdk` 0.9.70+)
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. Q3 is a form only - never a multiple-choice question. Q4 is optional CMS password (`CMS_PASSWORD`).**
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 this entire block)
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 (paste this entire block)
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 paste **Q4**. **Do not** re-ask Q3 a second time.
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 (paste this entire block)
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
- Optional: set a CMS password now?
108
+ **Title / helper:**
99
109
 
100
- If yes, reply with the password to store as Environment Variable **`CMS_PASSWORD`**.
110
+ Optional CMS password — Environment Variable **`CMS_PASSWORD`**.
101
111
 
102
- Leave blank / reply **skip** / **later** / **no** to keep the panel open for now — you can add `CMS_PASSWORD` later in Vercel → Settings → Environment Variables and redeploy.
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.17` - pairs with `@tomorrowos/sdk` **0.9.70+** (`templates/cms-starter-v0`, Fluid Functions WebSockets).
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 questions. 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**.
12
- > **Q4 = optional `CMS_PASSWORD`:** blank/skip is valid; can set later. Control Panel auth only — never Vercel Deployment Protection / whole-site password.
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, Q2, Q3: paste each question block VERBATIM. Do not rephrase options.
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, paste Q4 (optional CMS password). Blank/skip is valid.
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** = a **no-op that exits 0** (e.g. `node -e "process.exit(0)"` or `npm run build` where `build` is that no-op).
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 ??`public/` served without Node (read this)
127
+ ### Publish static trap — `public/` served without Node (read this)
121
128
 
122
- A common **worse** failure mode than `404: NOT_FOUND`:
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 *?public if it exists??). **No Function** is running TomorrowOS.
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
- **Fix (Scheme A):** use `cms-panel/` (not `public/`), Fluid Function `api/index.ts` + rewrites, Output Directory empty. Static UI is served **at runtime** via `staticRoot` in `listen()`.
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` (**optional**; blank = skip, can set later) | Always last |
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.** Paste Q1 → configure → paste Q2 → configure → paste Q3 → paste Q4. Never paraphrase question options. Never use `REPLIT_SETUP.md` as the questionnaire. **Never** ask for OpenAI or other LLM API keys.
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 optional `CMS_PASSWORD` -> **IRON GATE** -> execution checklist.
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": "npm run build",
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??00** 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??.
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"` = no-op ??**never** `next build` for Production
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 ??Vercel Project Settings (dashboard ??mandatory)
462
+ ### A4 — Vercel Project Settings (dashboard — mandatory)
421
463
 
422
464
  | Setting | Required value |
423
465
  |---------|----------------|
424
- | Framework Preset | **Other** / null ??**not Next.js** |
466
+ | Framework Preset | **Other** / null — **not Next.js** |
425
467
  | Install Command | `npm install` |
426
- | Build Command | `npm run build` (no-op) |
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 ?Permissions Required?? |
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
- - **`build`** = no-op exit 0 (never `next build` for Production).
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": "npm run build"
672
+ "buildCommand": ""
624
673
  }
625
674
  ```
626
675
 
627
- Use `pnpm` / `yarn` variants of install/build if that is the project?s package manager.
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) ??this is mandatory (see Scheme A4):**
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 ??**not Next.js** |
684
+ | Framework Preset | **Other** / null — **not Next.js** |
636
685
  | Install Command | `npm install` (or pnpm/yarn) |
637
- | Build Command | `npm run build` (no-op exit 0) |
638
- | Output Directory | **empty / null** ??**NOT `public`** |
639
- | Start Command | `npm run start` ??`tsx server.ts` (or `.mts`) ??set in **dashboard**, not `vercel.json` |
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 ? Ask storage choice
732
+ ### Step A — Ask database choice (**clickable UI required**)
684
733
 
685
- **Ask exactly:**
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)** ? durable pairing/playlists; use the **Session pooler** URL (`*.pooler.supabase.com:6543`).
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
- > Reply with **1** or **2** (or "Supabase" / "Neon").
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 ? Ask storage choice
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
- **Ask exactly (wording must match ? Cloudinary is recommended):**
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)** ? durable public HTTPS URLs (`https://res.cloudinary.com/...`). Works out of the box with `@tomorrowos/sdk` auto-detection. **Prefer this on Vercel.**
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
- > Reply with **1** or **2** (or "Cloudinary" / "Vercel Blob").
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
- If you catch yourself about to offer Blob-as-recommended, Supabase Storage, local disk, or "no media" ? **stop and paste the block above instead**.
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
- **Ask (Env input or one chat reply):**
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
- > Optional: set a CMS password now? If yes, enter the password to store as Environment Variable **`CMS_PASSWORD`**. Leave blank / skip to keep the panel open for now — you can add this later in Vercel → Settings → Environment Variables and redeploy.
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`, no-op `buildCommand` — **no** `startCommand`).
969
- 4. **Force Project Settings** per **Scheme A4** (Framework = Other, Output Directory empty, Start = `npm run start`, Fluid on). Patch dashboard via API if it still says Next.js.
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 ??not Next.js)
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** ??**not** HTML (`Unexpected token 'T'` means this failed)
1022
- 7. Production `GET /` returns Control Panel HTML ??**not** `404: NOT_FOUND`
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** ??Vercel is not running Node. Re-apply Scheme A3?A4; try **Path B** (Git / `vercel --prod`); do **not** invent `api/` + `rewrites`.
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; `build` = no-op |
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.17` - pairs with `@tomorrowos/sdk` 0.9.70+ and `VERCEL_QUESTIONS.md` 1.6.
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomorrowos/sdk",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Server SDK for building and self-hosting digital signage CMS products with TomorrowOS players.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "my-cms",
3
- "version": "1.1.0",
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.0",
9
+ "version": "1.1.4",
10
10
  "dependencies": {
11
- "@tomorrowos/sdk": "^1.1.0",
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.2",
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.2",
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.0",
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.0",
9
+ "version": "1.1.4",
10
10
  "dependencies": {
11
- "@tomorrowos/sdk": "^1.1.0",
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.2",
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.2",
19
+ "@tomorrowos/sdk": "^1.1.4",
20
20
  "dotenv": "^17.2.3",
21
21
  "tsx": "^4.19.0"
22
22
  },
@@ -3,7 +3,7 @@
3
3
  "fluid": true,
4
4
  "framework": null,
5
5
  "installCommand": "npm install",
6
- "buildCommand": "npm run build",
6
+ "buildCommand": "",
7
7
  "functions": {
8
8
  "api/index.ts": {
9
9
  "maxDuration": 300,