@tomorrowos/sdk 0.8.2 → 0.8.3

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/REPLIT_SETUP.md CHANGED
@@ -12,6 +12,7 @@ When a human pastes a prompt like this, **read this file and start Question 1 im
12
12
  ```text
13
13
  Follow @tomorrowos/sdk REPLIT_SETUP.md and set up my TomorrowOS CMS.
14
14
  Ask only the questions listed in REPLIT_SETUP.md, in order. Do not use LLM_PROMPT.md.
15
+ Artifact kind must be **web** (never **api**). Question 4 only updates **brand.json**.
15
16
  After all setup questions are answered (including Cloudinary Secrets if you chose Cloudinary), configure and start — minimal verification only (Web app type + Preview at /). **Never test Supabase connection** — save `SUPABASE_URL` and move on. No Supabase or WebSocket tests.
16
17
  Do not skip steps.
17
18
  ```
@@ -23,7 +24,31 @@ Alternate triggers that also activate this protocol:
23
24
 
24
25
  When any of these triggers fire, **ignore `LLM_PROMPT.md` entirely** for the Q&A phase.
25
26
 
26
- **Before Question 1:** ensure the Replit workspace is a **Web app** project (see **Deployability: Web app artifact**). If the project is API-only or not publishable, fix that first — do not continue the questionnaire on a broken project type.
27
+ **Before Question 1:** ensure the Replit workspace primary artifact **`kind` is `web`** (see **IRON RULE: `web` kind only**). If the project is `api` / API-only or not publishable, **fix artifact kind first** — do not continue the questionnaire on a broken project type.
28
+
29
+ ---
30
+
31
+ ## IRON RULE: `web` kind only (Publish will fail on `api`)
32
+
33
+ > **This is the #1 deployability rule. Non-negotiable.**
34
+
35
+ TomorrowOS CMS serves a **browser Control Panel at `/`** plus WebSocket for TVs. Replit’s publish detector treats **`kind = "api"`** artifacts as **not deployable** as a user-facing app — Publish may only see design mockups / libs and fail with *“api-server artifact isn't being recognized as deployable”*.
36
+
37
+ | Required | Forbidden |
38
+ |----------|-----------|
39
+ | Primary artifact **`kind = "web"`** | **`kind = "api"`** on the CMS artifact |
40
+ | Homepage / project type: **Web app** | **API server** as the only publishable artifact |
41
+ | `GET /` → Control Panel HTML (`public/index.html`) | `artifacts/api-server` with `kind = "api"` for this CMS |
42
+ | `.replit` + `npm run start` → live Node (`tsx server.ts`) | Splitting CMS into a non-publishable API artifact |
43
+
44
+ **Agent must enforce before and after Q&A:**
45
+
46
+ 1. If `.replit-artifact/artifact.toml` (or artifact metadata) shows **`kind = "api"`** → change to **`kind = "web"`** immediately (validated temp-file flow). **Never** leave the CMS on `api` kind.
47
+ 2. **Do not** scaffold TomorrowOS CMS under `artifacts/api-server` with `kind = "api"`. The CMS lives at the **project root** (or a **`web`** artifact at `/`).
48
+ 3. **Do not** create a separate `api` artifact “for the backend” — TomorrowOS is one **web** app (HTTP + WebSocket in `server.ts`).
49
+ 4. After setup, confirm publish detector sees a **web** artifact serving `/` — not api-only.
50
+
51
+ **If Publish says api-kind / api-server not deployable:** fix `kind` to **`web`** first, then `.replit` ports + `deploymentTarget = "autoscale"`. Creating a **new Web app** Repl is the fastest fix if Agent locked the project as API-only.
27
52
 
28
53
  ---
29
54
 
@@ -64,6 +89,7 @@ Then ask **Question 1** — do not switch to `LLM_PROMPT.md`.
64
89
  7. After Q&A, **configure and start** — do **not** run a long test suite (see **Post-Q&A: minimal verification only**).
65
90
  8. **Follow the Runtime & Replit publish rules below exactly.** A project that cannot Deploy / Publish on Replit is incomplete.
66
91
  9. **Supabase: configure only — never test.** Save `SUPABASE_URL` + `TOMORROWOS_STORE=supabase` and proceed. **Do not** ping Postgres, run `psql`, start the server solely to verify DB connectivity, or treat log errors like `ENOTFOUND` / `database connection failure` in **Replit dev / Preview** as a failed setup. Supabase often works only after **Publish** (production networking), not in the dev shell.
92
+ 10. **Artifact kind = `web` only.** **`kind = "api"` is forbidden** for the TomorrowOS CMS artifact. See **IRON RULE** above. Setup is incomplete if Publish would still see an `api` artifact.
67
93
 
68
94
  **Question order after Q1:**
69
95
 
@@ -76,7 +102,9 @@ Never insert extra questions between these steps. When the user chooses Cloudina
76
102
 
77
103
  ## Deployability: Web app artifact (mandatory — fixes “api-kind not deployable”)
78
104
 
79
- TomorrowOS CMS is a **user-facing Web app** (Control Panel at `/` + WebSocket for TVs). Replit must treat it as a **Web app** artifact, **not** an API-only / backend-library project.
105
+ > **Reminder:** Re-read **IRON RULE: `web` kind only** `api` kind is never acceptable for this CMS.
106
+
107
+ TomorrowOS CMS is a **user-facing Web app** (Control Panel at `/` + WebSocket for TVs). Replit must treat it as a **`web`** artifact, **not** `api` / API-only.
80
108
 
81
109
  ### Create the project correctly (do this first)
82
110
 
@@ -89,6 +117,7 @@ When scaffolding a **new** Repl:
89
117
 
90
118
  **Forbidden setups that cause publish failure:**
91
119
 
120
+ - ❌ **`kind = "api"`** on the CMS artifact (`api-server`, `artifacts/api-server`, etc.)
92
121
  - ❌ Project / primary artifact classified as **API** (`api-kind` artifact)
93
122
  - ❌ Backend-only Express/Fastify service with **no** `staticRoot` / Control Panel at `/`
94
123
  - ❌ Splitting CMS into a non-publishable API artifact + separate unpublished frontend
@@ -133,7 +162,8 @@ ignorePorts = false
133
162
  - Set `entrypoint = "server.ts"` (not `index.js` unless that file exists and starts TomorrowOS).
134
163
  - Set `deploymentTarget = "autoscale"` (WebSocket + long-lived connections; Static Deploy is wrong).
135
164
  - Keep exactly **one** primary `[[ports]]` entry with `externalPort = 80` for the CMS server.
136
- - If `.replit` contains `[[artifacts]]` with **only** `artifacts/api-server` and Publish fails, **convert to Web app layout** or create a **new Web app** Repl and migrate — do not tell the user publish succeeded.
165
+ - Ensure `.replit-artifact/artifact.toml` has **`kind = "web"`** (shipped in cms-starter). If `kind = "api"`, change to **`web`** before Publish.
166
+ - If `.replit` contains `[[artifacts]]` with **only** `artifacts/api-server` and Publish fails, set artifact **`kind = "web"`** or create a **new Web app** Repl and migrate — do not tell the user publish succeeded.
137
167
 
138
168
  If Replit assigns a different `localPort` via `PORT`, update `localPort` to match the port in `[TomorrowOS] listening on http://0.0.0.0:<PORT>` logs, but keep `externalPort = 80`.
139
169
 
@@ -154,14 +184,15 @@ After Publish, the public URL is:
154
184
 
155
185
  **Do not** keep retrying publish unchanged. Fix in this order:
156
186
 
157
- 1. Verify homepage artifact type is **Web app**; if the Repl was created as API-only, **create a new Web app Repl** and re-run this setup (fastest fix).
158
- 2. Replace `.replit` with the template above (`entrypoint`, `modules`, `[[ports]]`, `deploymentTarget = "autoscale"`).
159
- 3. Confirm `server.ts` calls `tomorrowos.listen({ staticRoot: join(__dirname, "public"), host: "0.0.0.0", port: Number(process.env.PORT) || 3000 })`.
160
- 4. Confirm `GET /` returns Control Panel HTML (not JSON-only API root).
161
- 5. In Publishing, switch to **Autoscale** if currently Static.
162
- 6. Restart workspace `npm run start` Publish again.
187
+ 1. Open `.replit-artifact/artifact.toml` (or artifact config) set **`kind = "web"`** (never `api`). This is the most common fix.
188
+ 2. Verify homepage artifact type is **Web app**; if the Repl was created as API-only, **create a new Web app Repl** and re-run this setup (fastest fix).
189
+ 3. Replace `.replit` with the template above (`entrypoint`, `modules`, `[[ports]]`, `deploymentTarget = "autoscale"`).
190
+ 4. Confirm `server.ts` calls `tomorrowos.listen({ staticRoot: join(__dirname, "public"), host: "0.0.0.0", port: Number(process.env.PORT) || 3000 })`.
191
+ 5. Confirm `GET /` returns Control Panel HTML (not JSON-only API root).
192
+ 6. In Publishing, switch to **Autoscale** if currently Static.
193
+ 7. Restart workspace → `npm run start` → Publish again.
163
194
 
164
- Tell the user plainly if step 1 requires a new Repl — API-only projects cannot publish a browser CMS without reclassification.
195
+ Tell the user plainly if step 2 requires a new Repl — API-only projects cannot publish a browser CMS without **`kind = "web"`**.
165
196
 
166
197
  ---
167
198
 
@@ -201,7 +232,7 @@ Allowed extras (optional): `"build-player": "tomorrowos build --platform tizen"`
201
232
  "node": ">=20"
202
233
  },
203
234
  "dependencies": {
204
- "@tomorrowos/sdk": "^0.8.2",
235
+ "@tomorrowos/sdk": "^0.8.3",
205
236
  "dotenv": "^17.2.3",
206
237
  "tsx": "^4.19.0"
207
238
  },
@@ -255,7 +286,7 @@ If the workspace already has a `.replit`, **merge** these keys — do not wipe u
255
286
 
256
287
  **Only these three checks matter after setup.** Do not add more unless Publish fails.
257
288
 
258
- 1. **Web app, not API** — project / primary artifact is **Web app** (not `api-kind` / API-only).
289
+ 1. **Web app, not API** — primary artifact **`kind = "web"`** (not `api` / API-only).
259
290
  2. **`.replit` is correct** — `entrypoint = "server.ts"`, `modules = ["nodejs-20"]`, `[[ports]]` with `externalPort = 80`, `deploymentTarget = "autoscale"`, Run/Deploy = `npm run start`.
260
291
  3. **Preview at `/`** — after `npm run start`, logs show `[TomorrowOS] listening on http://0.0.0.0:...` and Preview shows the Control Panel (HTML), not empty / API JSON.
261
292
 
@@ -486,7 +517,11 @@ The SDK auto-detects these env vars and uploads media to Cloudinary. New uploads
486
517
 
487
518
  ---
488
519
 
489
- ## Question 4 — Brand / TomorrowOS app look
520
+ ## Question 4 — Brand / TomorrowOS app look (`brand.json` only)
521
+
522
+ > **Scope:** Question 4 answers **only** update **`brand.json`** — colours, name, tagline, logo path, `cms.expectedScreens`, etc. They configure how the **TomorrowOS player app** looks and metadata flags.
523
+ >
524
+ > **Question 4 does NOT affect:** Replit Publish, artifact `kind`, `.replit`, `server.ts`, Secrets, Supabase, Cloudinary, ports, deployment target, or CMS server wiring. **Never** change deploy/runtime config based on branding answers.
490
525
 
491
526
  > **This is the only branding / platform / use-case question block.** Do not ask separate LLM_PROMPT “target platform”, “use case”, or “hosting” questions before this.
492
527
 
@@ -505,7 +540,7 @@ The SDK auto-detects these env vars and uploads media to Cloudinary. New uploads
505
540
 
506
541
  If the user only gives a name and primary colour, use defaults for the rest and say what you assumed.
507
542
 
508
- **Then write / update `brand.json`** at the project root (validate mentally against `brand.schema.json` in the SDK). Minimum example:
543
+ **Then write / update `brand.json` only** at the project root (validate mentally against `brand.schema.json` in the SDK). **Do not** modify `.replit`, `server.ts`, Secrets, or deployment settings from these answers. Minimum example:
509
544
 
510
545
  ```json
511
546
  {
@@ -541,9 +576,9 @@ Set `cms.expectedScreens` from Question 1 (do not ask screen count again). Alway
541
576
 
542
577
  Run these steps in order. Tick mentally; do not skip.
543
578
 
544
- ### A. Seed the project (Web app first)
579
+ ### A. Seed the project (Web app + `kind = "web"` first)
545
580
 
546
- **If creating a new Repl:** choose **Web app** on the Replit homepage before `init`.
581
+ **If creating a new Repl:** choose **Web app** on the Replit homepage before `init`. Confirm `.replit-artifact/artifact.toml` has **`kind = "web"`** after init.
547
582
 
548
583
  ```bash
549
584
  npx @tomorrowos/sdk@latest init .
@@ -657,6 +692,8 @@ Do **not**:
657
692
  - Use Canvas preview as the primary CMS verification surface
658
693
  - Serve a different app or API-only response at `/` instead of the Control Panel
659
694
  - Create the Repl as **API-only** or publish with **Static Deployment** only
695
+ - Set or leave artifact **`kind = "api"`** for the TomorrowOS CMS
696
+ - Change `.replit`, `server.ts`, Secrets, or deployment config based on **Question 4** branding answers (those go in **`brand.json` only**)
660
697
  - Omit `[[ports]]` / `deploymentTarget` from `.replit` when setting up for Publish
661
698
  - Run **Supabase connection tests**, **WebSocket console tests**, or other post-setup smoke tests unless Preview fails or the user asks
662
699
  - **Debug or “fix” Supabase** because dev logs show `getaddrinfo ENOTFOUND` or `database connection failure` — save config and finish setup instead
@@ -685,7 +722,7 @@ TOMORROWOS_STORE=sqlite
685
722
 
686
723
  | Symptom | Likely cause | Fix |
687
724
  |---------|--------------|-----|
688
- | Publish: **api-kind artifact not deployable** | Repl created as API-only, or missing Web app + ports | New **Web app** Repl **or** fix `.replit` (`entrypoint`, `[[ports]]`, `deploymentTarget=autoscale`); serve Control Panel at `/` |
725
+ | Publish: **api-kind artifact not deployable** | CMS artifact `kind = "api"` or API-only Repl | Set **`kind = "web"`** in `.replit-artifact/artifact.toml`; new **Web app** Repl if needed; `.replit` ports + `deploymentTarget=autoscale` |
689
726
  | Preview empty / wrong app at `/` | Project type API, wrong staticRoot, or stale process | Set project to **Web app**; confirm `staticRoot: public`; stop old servers; restart workspace |
690
727
  | TV / browser: WebSocket handshake timeout | Node CMS not running or crash-loop | Fix Run → `npm run start`; check logs for `listening` |
691
728
  | Deploy/Publish fails / `tsx: not found` | `tsx` only in devDependencies | Move `tsx` to `dependencies`, reinstall, keep `start`: `tsx server.ts` |
@@ -701,11 +738,13 @@ TOMORROWOS_STORE=sqlite
701
738
 
702
739
  ## Protocol version
703
740
 
704
- `replit-setup/1.6` — aligned with TomorrowOS protocol `1.0` and `@tomorrowos/sdk` store drivers `sqlite` | `supabase` | `postgres` | `memory`.
741
+ `replit-setup/1.7` — aligned with TomorrowOS protocol `1.0` and `@tomorrowos/sdk` store drivers `sqlite` | `supabase` | `postgres` | `memory`.
742
+
743
+ **Changelog 1.7:** **IRON RULE** — artifact **`kind = "web"` only** (never `api`); Question 4 **only** writes `brand.json` (no deploy/server changes).
705
744
 
706
- **Changelog 1.6:** **Never test Supabase** in Replit dev — `ENOTFOUND` / connection errors in Preview logs are expected; setup completes when Control Panel loads.
745
+ **Changelog 1.6:** **Never test Supabase** in Replit dev — `ENOTFOUND` in Preview logs is expected.
707
746
 
708
- **Changelog 1.5:** Cloudinary Secrets collected **inside Question 3** — no separate “3b” step; show Secrets form immediately when user picks Cloudinary.
747
+ **Changelog 1.5:** Cloudinary Secrets inside Question 3 — no “3b” step.
709
748
 
710
749
  **Changelog 1.4:** mandatory Cloudinary credential collection before Question 4 (superseded by 1.5 flow).
711
750
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomorrowos/sdk",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "TomorrowOS CMS server SDK - WebSocket transport, pairing, device commands, optional static CMS UI. Includes CLI (tomorrowos init / build) and starter templates.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,5 @@
1
+ # TomorrowOS CMS — must be "web" for Replit Publish (never "api").
2
+ kind = "web"
3
+ previewPath = "/"
4
+ title = "TomorrowOS CMS"
5
+ version = "1.0.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-cms",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
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",
@@ -13,7 +13,7 @@
13
13
  "build-player": "tomorrowos build --platform tizen"
14
14
  },
15
15
  "dependencies": {
16
- "@tomorrowos/sdk": "^0.8.2",
16
+ "@tomorrowos/sdk": "^0.8.3",
17
17
  "dotenv": "^17.2.3",
18
18
  "tsx": "^4.19.0"
19
19
  },