@tomorrowos/sdk 0.7.8 → 0.7.9
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 +130 -40
- package/package.json +1 -1
- package/templates/cms-starter/.replit +13 -0
- package/templates/cms-starter/package.json +2 -2
- package/LLM_PROMPT.md +0 -173
package/REPLIT_SETUP.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **This file is a contract for Replit Agent / Replit AI.**
|
|
4
4
|
> Follow it literally. Ask questions in order. Do not invent answers. Do not write or rewrite application logic until the Q&A is complete. Prefer configuring Secrets, `.env`, `brand.json`, and `server.ts` store wiring over inventing a custom CMS.
|
|
5
5
|
>
|
|
6
|
-
> **On Replit, this file is the ONLY questionnaire.**
|
|
6
|
+
> **On Replit, this file is the ONLY questionnaire.**
|
|
7
7
|
|
|
8
8
|
## User trigger (copy-paste)
|
|
9
9
|
|
|
@@ -22,6 +22,8 @@ Alternate triggers that also activate this protocol:
|
|
|
22
22
|
|
|
23
23
|
When any of these triggers fire, **ignore `LLM_PROMPT.md` entirely** for the Q&A phase.
|
|
24
24
|
|
|
25
|
+
**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.
|
|
26
|
+
|
|
25
27
|
---
|
|
26
28
|
|
|
27
29
|
## Questionnaire scope (STRICT — read before asking anything)
|
|
@@ -37,18 +39,6 @@ Replit Agent must ask **only** the questions defined in **this file**, in **this
|
|
|
37
39
|
|
|
38
40
|
**That is the complete list.** There are no other setup questions.
|
|
39
41
|
|
|
40
|
-
### Forbidden questions (never ask on Replit setup)
|
|
41
|
-
|
|
42
|
-
Do **not** ask questions from `LLM_PROMPT.md` or improvise similar ones, including but not limited to:
|
|
43
|
-
|
|
44
|
-
- ❌ “Which screen platform will you manage? … Tizen … BrightSign …” as a **standalone first question**
|
|
45
|
-
- ❌ “What's the primary use case?” as a **standalone** question (use case is collected **inside Question 4** only)
|
|
46
|
-
- ❌ “Where will the CMS server run? … here / vercel / railway …” — on Replit, hosting is always **`here`**; set `cms.hostingTarget: "here"` without asking
|
|
47
|
-
- ❌ Separate “brand identity” interview before Question 4 (colours, logo, name belong in **Question 4** only)
|
|
48
|
-
- ❌ “How many screens?” asked **again** after Question 1 (you already have `cms.expectedScreens`)
|
|
49
|
-
- ❌ Any technical implementation question (WebSocket library, pairing format, etc.)
|
|
50
|
-
|
|
51
|
-
**Target platform (`tizen` / `brightsign`):** collect only as **item 8 inside Question 4**, not as its own step.
|
|
52
42
|
|
|
53
43
|
If the user volunteers extra info early (e.g. brand name before Q4), **record it** and still ask the current question’s required fields you do not yet have. Do not skip ahead to execution until Q1–Q4 (or Q1, Q3, Q4 if ≤5 screens) are complete.
|
|
54
44
|
|
|
@@ -83,6 +73,97 @@ Never insert extra questions between these steps.
|
|
|
83
73
|
|
|
84
74
|
---
|
|
85
75
|
|
|
76
|
+
## Deployability: Web app artifact (mandatory — fixes “api-kind not deployable”)
|
|
77
|
+
|
|
78
|
+
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.
|
|
79
|
+
|
|
80
|
+
### Create the project correctly (do this first)
|
|
81
|
+
|
|
82
|
+
When scaffolding a **new** Repl:
|
|
83
|
+
|
|
84
|
+
1. On the Replit homepage, open the artifact-type dropdown and choose **Web app** (not API, not “Backend only”, not Agent & Automation-only).
|
|
85
|
+
2. **Do not** create an “API server” artifact as the only publishable output.
|
|
86
|
+
3. Describe the project as: *“TomorrowOS digital signage CMS — web Control Panel at `/` with WebSocket device pairing.”*
|
|
87
|
+
4. Run `npx @tomorrowos/sdk init` at the project root (or merge the cms-starter template).
|
|
88
|
+
|
|
89
|
+
**Forbidden setups that cause publish failure:**
|
|
90
|
+
|
|
91
|
+
- ❌ Project / primary artifact classified as **API** (`api-kind` artifact)
|
|
92
|
+
- ❌ Backend-only Express/Fastify service with **no** `staticRoot` / Control Panel at `/`
|
|
93
|
+
- ❌ Splitting CMS into a non-publishable API artifact + separate unpublished frontend
|
|
94
|
+
- ❌ **Static Deployment** as the publish type (TomorrowOS needs a **live Node server** for WebSocket)
|
|
95
|
+
- ❌ `deploymentTarget` or publish mode that only serves static files without `tsx server.ts`
|
|
96
|
+
|
|
97
|
+
### What “deployable” means for TomorrowOS
|
|
98
|
+
|
|
99
|
+
Replit Publish must see:
|
|
100
|
+
|
|
101
|
+
- A **Web app** that serves HTML at `GET /` (`public/index.html`)
|
|
102
|
+
- A Node process started by `npm run start` → `tsx server.ts`
|
|
103
|
+
- `host: "0.0.0.0"` and `port: Number(process.env.PORT) || 3000`
|
|
104
|
+
- An exposed port with `externalPort = 80` in `.replit` (see template below)
|
|
105
|
+
- **Autoscale** (or Reserved VM) deployment — **not** Static-only
|
|
106
|
+
|
|
107
|
+
### `.replit` (create or replace — required for publish)
|
|
108
|
+
|
|
109
|
+
Use this **minimum** configuration (merge with existing Nix/modules if needed; **do not** remove `[[ports]]` or `deploymentTarget`):
|
|
110
|
+
|
|
111
|
+
```toml
|
|
112
|
+
entrypoint = "server.ts"
|
|
113
|
+
modules = ["nodejs-20"]
|
|
114
|
+
hidden = [".config", "package-lock.json"]
|
|
115
|
+
run = "npm run start"
|
|
116
|
+
|
|
117
|
+
[nix]
|
|
118
|
+
channel = "stable-24_11"
|
|
119
|
+
|
|
120
|
+
[[ports]]
|
|
121
|
+
localPort = 3000
|
|
122
|
+
externalPort = 80
|
|
123
|
+
|
|
124
|
+
[deployment]
|
|
125
|
+
run = ["sh", "-c", "npm run start"]
|
|
126
|
+
deploymentTarget = "autoscale"
|
|
127
|
+
ignorePorts = false
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Agent rules for `.replit`:**
|
|
131
|
+
|
|
132
|
+
- Set `entrypoint = "server.ts"` (not `index.js` unless that file exists and starts TomorrowOS).
|
|
133
|
+
- Set `deploymentTarget = "autoscale"` (WebSocket + long-lived connections; Static Deploy is wrong).
|
|
134
|
+
- Keep exactly **one** primary `[[ports]]` entry with `externalPort = 80` for the CMS server.
|
|
135
|
+
- 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.
|
|
136
|
+
|
|
137
|
+
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`.
|
|
138
|
+
|
|
139
|
+
### Publishing pane (human + Agent)
|
|
140
|
+
|
|
141
|
+
Before Publish:
|
|
142
|
+
|
|
143
|
+
1. Confirm project filter / type shows **Web** (not API-only).
|
|
144
|
+
2. In Publishing, choose **Autoscale** (recommended) or **Reserved VM** — **not Static**.
|
|
145
|
+
3. Stop stale processes; clear port conflicts; restart workspace if needed.
|
|
146
|
+
4. `npm run start` → Preview at `/` shows Control Panel.
|
|
147
|
+
|
|
148
|
+
After Publish, the public URL is:
|
|
149
|
+
|
|
150
|
+
`https://YOUR-REPLIT-DOMAIN`
|
|
151
|
+
|
|
152
|
+
### If Publish says “api-kind artifact … not deployable”
|
|
153
|
+
|
|
154
|
+
**Do not** keep retrying publish unchanged. Fix in this order:
|
|
155
|
+
|
|
156
|
+
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).
|
|
157
|
+
2. Replace `.replit` with the template above (`entrypoint`, `modules`, `[[ports]]`, `deploymentTarget = "autoscale"`).
|
|
158
|
+
3. Confirm `server.ts` calls `tomorrowos.listen({ staticRoot: join(__dirname, "public"), host: "0.0.0.0", port: Number(process.env.PORT) || 3000 })`.
|
|
159
|
+
4. Confirm `GET /` returns Control Panel HTML (not JSON-only API root).
|
|
160
|
+
5. In Publishing, switch to **Autoscale** if currently Static.
|
|
161
|
+
6. Restart workspace → `npm run start` → Publish again.
|
|
162
|
+
|
|
163
|
+
Tell the user plainly if step 1 requires a new Repl — API-only projects cannot publish a browser CMS without reclassification.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
86
167
|
## Runtime & Replit publish rules (mandatory)
|
|
87
168
|
|
|
88
169
|
These rules exist so the CMS can be **Run** and **Published/Deployed** on Replit without custom build steps.
|
|
@@ -119,7 +200,7 @@ Allowed extras (optional): `"build-player": "tomorrowos build --platform tizen"`
|
|
|
119
200
|
"node": ">=20"
|
|
120
201
|
},
|
|
121
202
|
"dependencies": {
|
|
122
|
-
"@tomorrowos/sdk": "^0.7.
|
|
203
|
+
"@tomorrowos/sdk": "^0.7.9",
|
|
123
204
|
"dotenv": "^17.2.3",
|
|
124
205
|
"tsx": "^4.19.0"
|
|
125
206
|
},
|
|
@@ -150,28 +231,40 @@ npm run start
|
|
|
150
231
|
|
|
151
232
|
### `.replit` (create or edit)
|
|
152
233
|
|
|
234
|
+
Use the full template in **Deployability: Web app artifact** (not run/deployment lines only). Minimum:
|
|
235
|
+
|
|
153
236
|
```toml
|
|
237
|
+
entrypoint = "server.ts"
|
|
238
|
+
modules = ["nodejs-20"]
|
|
154
239
|
run = "npm run start"
|
|
155
240
|
|
|
241
|
+
[[ports]]
|
|
242
|
+
localPort = 3000
|
|
243
|
+
externalPort = 80
|
|
244
|
+
|
|
156
245
|
[deployment]
|
|
157
246
|
run = ["sh", "-c", "npm run start"]
|
|
247
|
+
deploymentTarget = "autoscale"
|
|
248
|
+
ignorePorts = false
|
|
158
249
|
```
|
|
159
250
|
|
|
160
|
-
If the workspace already has a `.replit`, **merge** these keys — do not wipe unrelated Nix/modules config. Ensure
|
|
251
|
+
If the workspace already has a `.replit`, **merge** these keys — do not wipe unrelated Nix/modules config. Ensure Run, Deployment, **ports**, and **deploymentTarget** are correct.
|
|
161
252
|
|
|
162
253
|
### Publish readiness checklist (before telling the user “done”)
|
|
163
254
|
|
|
164
|
-
1. Replit project
|
|
165
|
-
2. `
|
|
166
|
-
3.
|
|
167
|
-
4.
|
|
168
|
-
5.
|
|
169
|
-
6.
|
|
170
|
-
7.
|
|
171
|
-
8.
|
|
172
|
-
9.
|
|
173
|
-
10.
|
|
174
|
-
11.
|
|
255
|
+
1. Replit project / primary artifact is **Web app** (not API-only / `api-kind`)
|
|
256
|
+
2. `.replit` has `entrypoint = "server.ts"`, `modules = ["nodejs-20"]`, `[[ports]]` with `externalPort = 80`, `deploymentTarget = "autoscale"`
|
|
257
|
+
3. Publishing type is **Autoscale** or **Reserved VM** (not Static-only)
|
|
258
|
+
4. `package.json` has `scripts.start` = `tsx server.ts`
|
|
259
|
+
5. `tsx` is listed under `dependencies` (runtime-safe for Deploy)
|
|
260
|
+
6. Dependency is `@tomorrowos/sdk` (not a fork or vendored rewrite)
|
|
261
|
+
7. `.replit` Run + `[deployment].run` use `npm run start`
|
|
262
|
+
8. Node is **20+**
|
|
263
|
+
9. Preview at `/` shows the TomorrowOS Control Panel (not Canvas, not another app, not API JSON)
|
|
264
|
+
10. Stale processes / port conflicts cleared before publish
|
|
265
|
+
11. `npm run start` prints `[TomorrowOS] listening on http://0.0.0.0:...`
|
|
266
|
+
12. Browser WebSocket test to `wss://<host>/` succeeds
|
|
267
|
+
13. Secrets required by the Q&A answers are set (`SUPABASE_URL`, Cloudinary, etc.)
|
|
175
268
|
|
|
176
269
|
If any item fails, fix it before finishing.
|
|
177
270
|
|
|
@@ -352,8 +445,7 @@ Tell the user:
|
|
|
352
445
|
> 5. **Text colour** (hex, optional — default `#0A0908`)
|
|
353
446
|
> 6. **Secondary / accent colour** (hex, optional)
|
|
354
447
|
> 7. **Logo** — upload an SVG/PNG into the project, or give a URL I can fetch into `./assets/`
|
|
355
|
-
|
|
356
|
-
> 9. **Use case** — one of: `restaurant`, `retail`, `corporate`, `wayfinding`, `transit`, `other`
|
|
448
|
+
|
|
357
449
|
|
|
358
450
|
If the user only gives a name and primary colour, use defaults for the rest and say what you assumed.
|
|
359
451
|
|
|
@@ -393,7 +485,9 @@ Set `cms.expectedScreens` from Question 1 (do not ask screen count again). Alway
|
|
|
393
485
|
|
|
394
486
|
Run these steps in order. Tick mentally; do not skip.
|
|
395
487
|
|
|
396
|
-
### A. Seed the project
|
|
488
|
+
### A. Seed the project (Web app first)
|
|
489
|
+
|
|
490
|
+
**If creating a new Repl:** choose **Web app** on the Replit homepage before `init`.
|
|
397
491
|
|
|
398
492
|
```bash
|
|
399
493
|
npx @tomorrowos/sdk@latest init .
|
|
@@ -448,14 +542,7 @@ CLOUDINARY_API_SECRET=...
|
|
|
448
542
|
|
|
449
543
|
2. Move / keep `tsx` in **`dependencies`** so Deploy works.
|
|
450
544
|
3. Set `engines.node` to `>=20`.
|
|
451
|
-
4. Create or update `.replit
|
|
452
|
-
|
|
453
|
-
```toml
|
|
454
|
-
run = "npm run start"
|
|
455
|
-
|
|
456
|
-
[deployment]
|
|
457
|
-
run = ["sh", "-c", "npm run start"]
|
|
458
|
-
```
|
|
545
|
+
4. Create or update `.replit` using the **Deployability** template (`entrypoint`, `modules`, `[[ports]]`, `deploymentTarget = "autoscale"`).
|
|
459
546
|
|
|
460
547
|
### E. Install and run
|
|
461
548
|
|
|
@@ -528,6 +615,8 @@ Do **not**:
|
|
|
528
615
|
- Leave `tsx` only in `devDependencies` if the Deploy pipeline installs production deps only
|
|
529
616
|
- Use Canvas preview as the primary CMS verification surface
|
|
530
617
|
- Serve a different app or API-only response at `/` instead of the Control Panel
|
|
618
|
+
- Create the Repl as **API-only** or publish with **Static Deployment** only
|
|
619
|
+
- Omit `[[ports]]` / `deploymentTarget` from `.replit` when setting up for Publish
|
|
531
620
|
|
|
532
621
|
---
|
|
533
622
|
|
|
@@ -553,7 +642,8 @@ TOMORROWOS_STORE=sqlite
|
|
|
553
642
|
|
|
554
643
|
| Symptom | Likely cause | Fix |
|
|
555
644
|
|---------|--------------|-----|
|
|
556
|
-
|
|
|
645
|
+
| 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 `/` |
|
|
646
|
+
| 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 |
|
|
557
647
|
| TV / browser: WebSocket handshake timeout | Node CMS not running or crash-loop | Fix Run → `npm run start`; check logs for `listening` |
|
|
558
648
|
| Deploy/Publish fails / `tsx: not found` | `tsx` only in devDependencies | Move `tsx` to `dependencies`, reinstall, keep `start`: `tsx server.ts` |
|
|
559
649
|
| Deploy runs wrong process | `.replit` / Deployment not `npm run start` | Set `run = "npm run start"` and `[deployment] run = ["sh", "-c", "npm run start"]` |
|
|
@@ -567,6 +657,6 @@ TOMORROWOS_STORE=sqlite
|
|
|
567
657
|
|
|
568
658
|
## Protocol version
|
|
569
659
|
|
|
570
|
-
`replit-setup/1.
|
|
660
|
+
`replit-setup/1.2` — aligned with TomorrowOS protocol `1.0` and `@tomorrowos/sdk` store drivers `sqlite` | `supabase` | `postgres` | `memory`.
|
|
571
661
|
|
|
572
|
-
**Changelog 1.
|
|
662
|
+
**Changelog 1.2:** Web app deployability rules — avoid `api-kind` publish failure; full `.replit` with `[[ports]]`, `deploymentTarget = "autoscale"`, `entrypoint = "server.ts"`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomorrowos/sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.9",
|
|
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",
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
entrypoint = "server.ts"
|
|
2
|
+
modules = ["nodejs-20"]
|
|
3
|
+
hidden = [".config", "package-lock.json"]
|
|
1
4
|
run = "npm run start"
|
|
2
5
|
|
|
6
|
+
[nix]
|
|
7
|
+
channel = "stable-24_11"
|
|
8
|
+
|
|
9
|
+
# Expose the CMS HTTP + WebSocket server (TomorrowOS Control Panel at /).
|
|
10
|
+
[[ports]]
|
|
11
|
+
localPort = 3000
|
|
12
|
+
externalPort = 80
|
|
13
|
+
|
|
3
14
|
[deployment]
|
|
4
15
|
run = ["sh", "-c", "npm run start"]
|
|
16
|
+
deploymentTarget = "autoscale"
|
|
17
|
+
ignorePorts = false
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.9",
|
|
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.7.
|
|
16
|
+
"@tomorrowos/sdk": "^0.7.9",
|
|
17
17
|
"dotenv": "^17.2.3",
|
|
18
18
|
"tsx": "^4.19.0"
|
|
19
19
|
},
|
package/LLM_PROMPT.md
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
# Elicitation Protocol for TomorrowOS CMS Projects
|
|
2
|
-
|
|
3
|
-
> **This file is the contract between TomorrowOS and any LLM generating code using this package. You must follow it literally. Do not skip questions, do not infer answers, do not start writing code until the protocol is complete.**
|
|
4
|
-
|
|
5
|
-
> **Replit Agent:** if the user is setting up a CMS on Replit (or pastes a prompt that mentions `REPLIT_SETUP.md`), follow **`REPLIT_SETUP.md` only** — not this file. Do **not** ask `LLM_PROMPT.md` questions (e.g. standalone “Which screen platform will you manage?”). Replit uses four questions: screen count → optional Supabase → media storage → brand (including platform and use case inside Question 4).
|
|
6
|
-
|
|
7
|
-
You are generating a digital signage CMS using `@tomorrowos/sdk`. The user has asked you to build something like "a CMS for my restaurant" or "a signage dashboard for my retail network". Before you write any code, you must gather five pieces of information from the user.
|
|
8
|
-
|
|
9
|
-
Ask each question in order. If the user answers multiple at once, record those and skip ahead. If the user hasn't given you an answer to a specific field, do not invent one — ask the question explicitly.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Question 1 — Target platform
|
|
14
|
-
|
|
15
|
-
**Ask exactly:**
|
|
16
|
-
|
|
17
|
-
> "Which screen platform will you manage? TomorrowOS V1 fully supports Samsung Tizen (commercial signage displays) and BrightSign (media players). Which would you like to target?"
|
|
18
|
-
|
|
19
|
-
**Valid answers:** `tizen`, `brightsign`, or `both`
|
|
20
|
-
|
|
21
|
-
**If the user names a platform not in V1** (webOS, Android, ChromeOS, Windows), respond:
|
|
22
|
-
|
|
23
|
-
> "That platform is planned for a later release. For V1, the supported options are Tizen and BrightSign. Which would you like to use for now?"
|
|
24
|
-
|
|
25
|
-
**Store answer as:** `targetPlatforms` array in `brand.json`
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Question 2 — Brand identity
|
|
30
|
-
|
|
31
|
-
**Ask exactly:**
|
|
32
|
-
|
|
33
|
-
> "What's the name of the product or company this CMS is for? I'll also need:
|
|
34
|
-
>
|
|
35
|
-
> - A logo file (SVG preferred, PNG acceptable — or a URL I can fetch)
|
|
36
|
-
> - A primary brand colour (hex format, e.g. `#FF8A3D`)
|
|
37
|
-
> - Optional: a secondary/accent colour"
|
|
38
|
-
|
|
39
|
-
**Required fields:**
|
|
40
|
-
|
|
41
|
-
- `brand.name` — string
|
|
42
|
-
- `brand.primaryColor` — hex string matching `^#[0-9A-Fa-f]{6}$`
|
|
43
|
-
- `brand.logoPath` — relative path to logo file the user will save to the project
|
|
44
|
-
|
|
45
|
-
**If the user does not provide a logo**, proceed with a placeholder comment in the generated code noting that the logo must be added before production use. Do not fabricate a logo.
|
|
46
|
-
|
|
47
|
-
**If the user provides a brand name but no colour**, ask:
|
|
48
|
-
|
|
49
|
-
> "What's the primary colour for your brand? I need it as a hex code like `#FF8A3D`."
|
|
50
|
-
|
|
51
|
-
Store answers in `brand.json`.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Question 3 — Use case
|
|
56
|
-
|
|
57
|
-
**Ask exactly:**
|
|
58
|
-
|
|
59
|
-
> "What's the primary use case for this CMS? For example: restaurant menu boards, retail promotions, corporate lobby displays, hospital wayfinding, transit information."
|
|
60
|
-
|
|
61
|
-
**Use the answer to:**
|
|
62
|
-
|
|
63
|
-
- Tailor the example content shown in the starter template (e.g. menu items vs retail promo templates)
|
|
64
|
-
- Set the dashboard's default greeting and page titles
|
|
65
|
-
- Suggest sensible default playlist names
|
|
66
|
-
|
|
67
|
-
**Do NOT use the answer to:**
|
|
68
|
-
|
|
69
|
-
- Change the SDK method signatures
|
|
70
|
-
- Add or remove required components from `BUILD_GUARDRAILS.md`
|
|
71
|
-
- Skip any mandatory pages
|
|
72
|
-
|
|
73
|
-
The SDK contract is identical regardless of use case. Use case only affects content and copy.
|
|
74
|
-
|
|
75
|
-
**Store answer as:** `cms.useCase` in `brand.json` (one of: `restaurant`, `retail`, `corporate`, `wayfinding`, `transit`, `other`)
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Question 4 — Hosting target
|
|
80
|
-
|
|
81
|
-
**Ask exactly:**
|
|
82
|
-
|
|
83
|
-
> "Where will the CMS server run? Options:
|
|
84
|
-
>
|
|
85
|
-
> - `here` — you're in Replit, Claude Code, or another hosted AI workspace (I'll configure it automatically)
|
|
86
|
-
> - `vercel` — deploy to Vercel
|
|
87
|
-
> - `railway` — deploy to Railway
|
|
88
|
-
> - `self-hosted` — you'll run it on your own infrastructure"
|
|
89
|
-
|
|
90
|
-
**If the user says `here`:**
|
|
91
|
-
|
|
92
|
-
- Use environment variable `process.env.PORT` for the server port
|
|
93
|
-
- Configure the WebSocket handler to bind to `0.0.0.0`
|
|
94
|
-
- Include a comment in `server.ts` noting that Replit/Claude Code handles the hosting and HTTPS termination
|
|
95
|
-
- Do NOT commit any secrets or keys to the generated code
|
|
96
|
-
|
|
97
|
-
**If the user says `vercel`:**
|
|
98
|
-
|
|
99
|
-
- Note that Vercel free tier has WebSocket limitations; recommend Railway for production
|
|
100
|
-
- Generate `vercel.json` with appropriate WebSocket routing
|
|
101
|
-
|
|
102
|
-
**If the user says `railway`:**
|
|
103
|
-
|
|
104
|
-
- Generate `railway.toml` with port configuration
|
|
105
|
-
- Include Dockerfile if appropriate
|
|
106
|
-
|
|
107
|
-
**Store answer as:** `cms.hostingTarget` in `brand.json`
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
## Question 5 — Expected number of screens
|
|
112
|
-
|
|
113
|
-
**Ask exactly:**
|
|
114
|
-
|
|
115
|
-
> "How many screens will you manage initially? (1-10 is fine for testing. For larger deployments I'll add pagination and grouping features.)"
|
|
116
|
-
|
|
117
|
-
**If answer is 1-10:** generate simple list views without pagination.
|
|
118
|
-
|
|
119
|
-
**If answer is 11-100:** include pagination on the screens list page (page size 20).
|
|
120
|
-
|
|
121
|
-
**If answer is 100+:** include pagination, grouping, and tag filtering on the screens list. Note to user that fleet-level features (bulk commands, group broadcast) are recommended.
|
|
122
|
-
|
|
123
|
-
**Store answer as:** `cms.expectedScreens` in `brand.json`
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## After all five answers collected
|
|
128
|
-
|
|
129
|
-
Follow this sequence strictly:
|
|
130
|
-
|
|
131
|
-
1. **Write `brand.json`** at the project root using the answers. Validate against `brand.schema.json`.
|
|
132
|
-
2. **Run `npx tomorrowos init [dir]`** or copy `templates/cms-starter/` from the SDK package into the user's project as the seed.
|
|
133
|
-
3. **Customise the starter:**
|
|
134
|
-
- Replace placeholder brand name, colour, logo references
|
|
135
|
-
- Rename example content to match the use case
|
|
136
|
-
- Remove any platform-specific notes for platforms the user didn't select
|
|
137
|
-
4. **Read `BUILD_GUARDRAILS.md`** and verify every mandatory component is present in the generated code. Do not skip any.
|
|
138
|
-
5. **Run `npm install`** and confirm dependencies resolve.
|
|
139
|
-
6. **Start the dev server** (`npm run dev`) and confirm it runs without errors.
|
|
140
|
-
7. **Show the user `PLAYER_INSTALL.md`** and explain what to do next to get a screen paired and controllable.
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## What not to ask
|
|
145
|
-
|
|
146
|
-
Do not ask the user:
|
|
147
|
-
|
|
148
|
-
- How WebSocket connections should be handled (the SDK handles this)
|
|
149
|
-
- How to implement pairing (the SDK handles this)
|
|
150
|
-
- How to format command messages (the SDK handles this)
|
|
151
|
-
- Which WebSocket library to use (the SDK bundles this)
|
|
152
|
-
- What TCP port to use (use `process.env.PORT` or `3000`)
|
|
153
|
-
- Whether to use TypeScript or JavaScript (default to TypeScript; offer JS only if user explicitly asks)
|
|
154
|
-
|
|
155
|
-
These are implementation details the SDK controls. The user cares about their brand, their platform, their use case. Everything else is the SDK's job.
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## When to re-prompt
|
|
160
|
-
|
|
161
|
-
If the user's initial prompt already contains answers to some questions (e.g. "build me a CMS for my Acme Burger restaurant menu boards on Samsung Tizen"), record those answers and only ask the remaining questions. Do not re-ask what the user has already told you.
|
|
162
|
-
|
|
163
|
-
If the user says "just build it, don't ask me questions," respond:
|
|
164
|
-
|
|
165
|
-
> "I'd love to, but I need five quick answers to make sure the CMS you get actually works with your screens and looks like your brand. It'll take about sixty seconds. Ready?"
|
|
166
|
-
|
|
167
|
-
Do not proceed without the answers. The SDK will not function without at minimum: `targetPlatforms`, `brand.name`, `brand.primaryColor`, and `cms.hostingTarget`.
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Protocol version
|
|
172
|
-
|
|
173
|
-
This elicitation protocol is version `1.0`, aligned with TomorrowOS wire protocol `1.0`. Future SDK versions may add questions; they will not remove existing ones without a major-version bump.
|