@tomorrowos/sdk 0.7.6 → 0.7.8
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/LLM_PROMPT.md +1 -1
- package/REPLIT_SETUP.md +140 -29
- package/package.json +1 -1
- package/templates/cms-starter/package.json +2 -2
package/LLM_PROMPT.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
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
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
|
|
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
6
|
|
|
7
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
8
|
|
package/REPLIT_SETUP.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
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
|
+
>
|
|
6
|
+
> **On Replit, this file is the ONLY questionnaire.** Do **not** use `LLM_PROMPT.md` questions.
|
|
5
7
|
|
|
6
8
|
## User trigger (copy-paste)
|
|
7
9
|
|
|
@@ -9,7 +11,8 @@ When a human pastes a prompt like this, **read this file and start Question 1 im
|
|
|
9
11
|
|
|
10
12
|
```text
|
|
11
13
|
Follow @tomorrowos/sdk REPLIT_SETUP.md and set up my TomorrowOS CMS.
|
|
12
|
-
Ask
|
|
14
|
+
Ask only the questions listed in REPLIT_SETUP.md, in order. Do not use LLM_PROMPT.md.
|
|
15
|
+
Do not skip steps.
|
|
13
16
|
```
|
|
14
17
|
|
|
15
18
|
Alternate triggers that also activate this protocol:
|
|
@@ -17,20 +20,66 @@ Alternate triggers that also activate this protocol:
|
|
|
17
20
|
- “Set up TomorrowOS on Replit using REPLIT_SETUP.md”
|
|
18
21
|
- “Configure my TomorrowOS CMS (Replit wizard)”
|
|
19
22
|
|
|
23
|
+
When any of these triggers fire, **ignore `LLM_PROMPT.md` entirely** for the Q&A phase.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Questionnaire scope (STRICT — read before asking anything)
|
|
28
|
+
|
|
29
|
+
Replit Agent must ask **only** the questions defined in **this file**, in **this exact order**:
|
|
30
|
+
|
|
31
|
+
| Step | Section | When |
|
|
32
|
+
|------|---------|------|
|
|
33
|
+
| 1 | **Question 1** — How many screens / devices? | Always |
|
|
34
|
+
| 2 | **Question 2** — Supabase connection | Only if answer to Q1 is **> 5** |
|
|
35
|
+
| 3 | **Question 3** — Media storage (Cloudinary vs Object Storage) | Always (after Q1 or Q2) |
|
|
36
|
+
| 4 | **Question 4** — Brand / TomorrowOS app look | Always last, before execution |
|
|
37
|
+
|
|
38
|
+
**That is the complete list.** There are no other setup questions.
|
|
39
|
+
|
|
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
|
+
|
|
53
|
+
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
|
+
|
|
55
|
+
If the user says “just set it up, don’t ask questions,” respond:
|
|
56
|
+
|
|
57
|
+
> I need four quick answers from REPLIT_SETUP.md (screen count, media storage, and branding). It takes about a minute and ensures the CMS deploys correctly on Replit.
|
|
58
|
+
|
|
59
|
+
Then ask **Question 1** — do not switch to `LLM_PROMPT.md`.
|
|
60
|
+
|
|
20
61
|
---
|
|
21
62
|
|
|
22
63
|
## Hard rules
|
|
23
64
|
|
|
24
|
-
1. **
|
|
25
|
-
2. **
|
|
26
|
-
3. **Do not
|
|
27
|
-
4. **
|
|
28
|
-
5. **
|
|
29
|
-
6.
|
|
65
|
+
1. **Ask only REPLIT_SETUP.md questions 1–4** (see **Questionnaire scope**). Never use `LLM_PROMPT.md` on Replit.
|
|
66
|
+
2. **One question at a time.** Wait for the user’s answer before asking the next question (unless they already answered several in one message).
|
|
67
|
+
3. **Do not invent** screen counts, Cloudinary credentials, Supabase URLs, or brand colours.
|
|
68
|
+
4. **Do not use Replit’s reserved `DATABASE_URL` Secret for Supabase.** On Replit, `DATABASE_URL` is often pre-claimed. Always use **`SUPABASE_URL`** for TomorrowOS ↔ Supabase.
|
|
69
|
+
5. **Prefer `npx @tomorrowos/sdk init`** (or the package’s `templates/cms-starter`) as the project seed. Do not rebuild pairing, WebSocket, or playlist APIs from scratch.
|
|
70
|
+
6. **Never commit secrets** into git. Put credentials only in Replit **Secrets** (and optionally mirror non-secret flags in `.env` that reference env vars).
|
|
71
|
+
7. After Q&A, apply configuration, install deps, start the server, and verify:
|
|
30
72
|
- HTTP Control Panel loads
|
|
31
73
|
- `GET /brand.json` returns 200
|
|
32
74
|
- WebSocket upgrade on `wss://<repl-host>/` succeeds (critical for TV pairing)
|
|
33
|
-
|
|
75
|
+
8. **Follow the Runtime & Replit publish rules below exactly.** A project that cannot Deploy / Publish on Replit is incomplete.
|
|
76
|
+
|
|
77
|
+
**Question order after Q1:**
|
|
78
|
+
|
|
79
|
+
- If **≤ 5 screens:** Q1 → Q3 → Q4 → execution checklist
|
|
80
|
+
- If **> 5 screens:** Q1 → Q2 → Q3 → Q4 → execution checklist
|
|
81
|
+
|
|
82
|
+
Never insert extra questions between these steps.
|
|
34
83
|
|
|
35
84
|
---
|
|
36
85
|
|
|
@@ -70,7 +119,7 @@ Allowed extras (optional): `"build-player": "tomorrowos build --platform tizen"`
|
|
|
70
119
|
"node": ">=20"
|
|
71
120
|
},
|
|
72
121
|
"dependencies": {
|
|
73
|
-
"@tomorrowos/sdk": "^0.7.
|
|
122
|
+
"@tomorrowos/sdk": "^0.7.8",
|
|
74
123
|
"dotenv": "^17.2.3",
|
|
75
124
|
"tsx": "^4.19.0"
|
|
76
125
|
},
|
|
@@ -112,22 +161,65 @@ If the workspace already has a `.replit`, **merge** these keys — do not wipe u
|
|
|
112
161
|
|
|
113
162
|
### Publish readiness checklist (before telling the user “done”)
|
|
114
163
|
|
|
115
|
-
1.
|
|
116
|
-
2. `
|
|
117
|
-
3.
|
|
118
|
-
4.
|
|
119
|
-
5.
|
|
120
|
-
6.
|
|
121
|
-
7.
|
|
122
|
-
8.
|
|
164
|
+
1. Replit project type is **Web** (not API)
|
|
165
|
+
2. `package.json` has `scripts.start` = `tsx server.ts`
|
|
166
|
+
3. `tsx` is listed under `dependencies` (runtime-safe for Deploy)
|
|
167
|
+
4. Dependency is `@tomorrowos/sdk` (not a fork or vendored rewrite)
|
|
168
|
+
5. `.replit` Run + `[deployment].run` use `npm run start`
|
|
169
|
+
6. Node is **20+**
|
|
170
|
+
7. Preview at `/` shows the TomorrowOS Control Panel (not Canvas, not another app)
|
|
171
|
+
8. Stale processes / port conflicts cleared before publish
|
|
172
|
+
9. `npm run start` prints `[TomorrowOS] listening on http://0.0.0.0:...`
|
|
173
|
+
10. Browser WebSocket test to `wss://<host>/` succeeds
|
|
174
|
+
11. Secrets required by the Q&A answers are set (`SUPABASE_URL`, Cloudinary, etc.)
|
|
123
175
|
|
|
124
176
|
If any item fails, fix it before finishing.
|
|
125
177
|
|
|
178
|
+
### Preview requirements (Replit workspace)
|
|
179
|
+
|
|
180
|
+
The Replit **Preview** must show the **TomorrowOS Control Panel** at `/` (root URL).
|
|
181
|
+
|
|
182
|
+
- `GET /` must serve the CMS Control Panel (`public/index.html` via `staticRoot: public`).
|
|
183
|
+
- **Do not** serve another app, API-only landing page, or placeholder at `/`.
|
|
184
|
+
- **Do not** use or rely on the **Canvas** preview for this CMS — use the normal **Web** preview in the browser.
|
|
185
|
+
- If the preview is **empty** or shows the wrong thing:
|
|
186
|
+
1. Confirm the Replit project type is **Web**, not **API**.
|
|
187
|
+
2. Confirm `npm run start` is running and logs show `[TomorrowOS] listening on http://0.0.0.0:...`
|
|
188
|
+
3. Confirm `server.ts` calls `tomorrowos.listen({ staticRoot: join(__dirname, "public"), ... })`
|
|
189
|
+
4. Open the preview URL directly (not Canvas) and hard-refresh.
|
|
190
|
+
|
|
191
|
+
### Before publishing / deploying
|
|
192
|
+
|
|
193
|
+
Do this **before** clicking Publish / Deploy:
|
|
194
|
+
|
|
195
|
+
1. **Stop** stale running processes (old `tsx` / `node` servers from prior attempts).
|
|
196
|
+
2. **Clear** old background tasks from previous failed projects (Replit Shell / Processes panel).
|
|
197
|
+
3. **Ensure no old process is holding the port** (`EADDRINUSE` in logs = something still bound to `PORT`).
|
|
198
|
+
4. **Restart the Replit workspace** if the port is stuck or preview still shows a ghost app.
|
|
199
|
+
5. Run `npm run start` once cleanly and confirm Control Panel loads at `/` in preview.
|
|
200
|
+
|
|
201
|
+
### After publishing / deploying
|
|
202
|
+
|
|
203
|
+
Tell the user their live CMS URLs:
|
|
204
|
+
|
|
205
|
+
- **Control Panel (browser):** `https://YOUR-REPLIT-DOMAIN`
|
|
206
|
+
- **TV / player CMS endpoint:** same HTTPS origin, e.g. `https://YOUR-REPLIT-DOMAIN/` (player converts `https://` → `wss://` for WebSocket)
|
|
207
|
+
|
|
208
|
+
Replace `YOUR-REPLIT-DOMAIN` with the actual published hostname (e.g. `my-cms.replit.app`).
|
|
209
|
+
|
|
210
|
+
Verify after publish:
|
|
211
|
+
|
|
212
|
+
1. `https://YOUR-REPLIT-DOMAIN/` shows the Control Panel (not empty, not API docs).
|
|
213
|
+
2. `https://YOUR-REPLIT-DOMAIN/brand.json` returns 200.
|
|
214
|
+
3. WebSocket to `wss://YOUR-REPLIT-DOMAIN/` succeeds.
|
|
215
|
+
|
|
126
216
|
---
|
|
127
217
|
|
|
128
218
|
## Question 1 — How many screens / devices?
|
|
129
219
|
|
|
130
|
-
**
|
|
220
|
+
> **This is the first and only “screen count” question.** Do not re-ask later.
|
|
221
|
+
|
|
222
|
+
**Ask exactly (copy wording; do not substitute LLM_PROMPT questions):**
|
|
131
223
|
|
|
132
224
|
> How many TomorrowOS screens (devices) do you expect to manage with this CMS?
|
|
133
225
|
>
|
|
@@ -247,7 +339,9 @@ Tell the user:
|
|
|
247
339
|
|
|
248
340
|
## Question 4 — Brand / TomorrowOS app look
|
|
249
341
|
|
|
250
|
-
**
|
|
342
|
+
> **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.
|
|
343
|
+
|
|
344
|
+
**Ask exactly (one message; user may answer in one reply):**
|
|
251
345
|
|
|
252
346
|
> Let’s brand your TomorrowOS experience. Please provide:
|
|
253
347
|
>
|
|
@@ -291,7 +385,7 @@ If the user only gives a name and primary colour, use defaults for the rest and
|
|
|
291
385
|
}
|
|
292
386
|
```
|
|
293
387
|
|
|
294
|
-
Set `cms.expectedScreens` from Question 1. Set `cmsEndpoint` only if the user already knows their public `wss://…replit.app` URL; otherwise leave it out and tell them to pair TVs using the published HTTPS URL (player converts `https://` → `wss://`).
|
|
388
|
+
Set `cms.expectedScreens` from Question 1 (do not ask screen count again). Always set `cms.hostingTarget` to `"here"` on Replit without asking. Set `cmsEndpoint` only if the user already knows their public `wss://…replit.app` URL; otherwise leave it out and tell them to pair TVs using the published HTTPS URL (player converts `https://` → `wss://`).
|
|
295
389
|
|
|
296
390
|
---
|
|
297
391
|
|
|
@@ -365,6 +459,8 @@ run = ["sh", "-c", "npm run start"]
|
|
|
365
459
|
|
|
366
460
|
### E. Install and run
|
|
367
461
|
|
|
462
|
+
**Before starting:** stop stale processes, clear old background tasks, free the port if needed, restart workspace if stuck.
|
|
463
|
+
|
|
368
464
|
```bash
|
|
369
465
|
npm install
|
|
370
466
|
npm run start
|
|
@@ -378,11 +474,14 @@ Confirm logs contain something like:
|
|
|
378
474
|
[TomorrowOS] listening on http://0.0.0.0:<PORT>
|
|
379
475
|
```
|
|
380
476
|
|
|
477
|
+
Confirm the **Web preview** (not Canvas) shows the Control Panel at `/`.
|
|
478
|
+
|
|
381
479
|
### F. Verify before telling the user “done”
|
|
382
480
|
|
|
383
|
-
1.
|
|
384
|
-
2.
|
|
385
|
-
3.
|
|
481
|
+
1. Replit project type is **Web**; preview at `/` shows Control Panel (not empty, not Canvas-only).
|
|
482
|
+
2. Open the Control Panel URL.
|
|
483
|
+
3. `GET /brand.json` → 200 and correct `name` / colours.
|
|
484
|
+
4. In browser console on the Control Panel origin:
|
|
386
485
|
|
|
387
486
|
```javascript
|
|
388
487
|
const ws = new WebSocket(location.origin.replace(/^http/, "ws") + "/");
|
|
@@ -390,22 +489,28 @@ ws.onopen = () => console.log("WS OK");
|
|
|
390
489
|
ws.onerror = (e) => console.log("WS ERR", e);
|
|
391
490
|
```
|
|
392
491
|
|
|
393
|
-
|
|
492
|
+
5. Confirm the **Publish readiness checklist** in **Runtime & Replit publish rules**.
|
|
394
493
|
|
|
395
494
|
If WebSocket fails, fix Run command / process crash / sleep **before** asking the user to pair a TV.
|
|
396
495
|
|
|
397
496
|
### G. Tell the user next steps (no code)
|
|
398
497
|
|
|
399
498
|
1. Keep this Repl **running** (Always On if available).
|
|
400
|
-
2.
|
|
401
|
-
3.
|
|
402
|
-
4.
|
|
403
|
-
5.
|
|
499
|
+
2. **Published Control Panel URL:** `https://YOUR-REPLIT-DOMAIN`
|
|
500
|
+
3. On the TomorrowOS player, enter the CMS URL: `https://YOUR-REPLIT-DOMAIN/`
|
|
501
|
+
4. Enter the 6-character pairing code from the screen into the Control Panel.
|
|
502
|
+
5. Create a playlist, upload media, Publish to the device.
|
|
503
|
+
6. Point them at `PLAYER_INSTALL.md` in the SDK for player install details.
|
|
404
504
|
|
|
405
505
|
---
|
|
406
506
|
|
|
407
507
|
## What not to ask / change
|
|
408
508
|
|
|
509
|
+
### Forbidden questionnaire sources
|
|
510
|
+
|
|
511
|
+
- **`LLM_PROMPT.md`** — not used on Replit setup; its five questions are **replaced** by REPLIT_SETUP Questions 1–4
|
|
512
|
+
- Standalone “target platform” / “hosting target” / “use case” prompts outside Question 4
|
|
513
|
+
|
|
409
514
|
Do **not** ask the user how to implement:
|
|
410
515
|
|
|
411
516
|
- WebSocket framing
|
|
@@ -421,6 +526,8 @@ Do **not**:
|
|
|
421
526
|
- Skip Cloudinary recommendation without stating the persistence tradeoff
|
|
422
527
|
- Claim uploads are “permanent” on Replit local disk without Object Storage or Cloudinary
|
|
423
528
|
- Leave `tsx` only in `devDependencies` if the Deploy pipeline installs production deps only
|
|
529
|
+
- Use Canvas preview as the primary CMS verification surface
|
|
530
|
+
- Serve a different app or API-only response at `/` instead of the Control Panel
|
|
424
531
|
|
|
425
532
|
---
|
|
426
533
|
|
|
@@ -446,9 +553,11 @@ TOMORROWOS_STORE=sqlite
|
|
|
446
553
|
|
|
447
554
|
| Symptom | Likely cause | Fix |
|
|
448
555
|
|---------|--------------|-----|
|
|
556
|
+
| Preview empty / wrong app at `/` | Project type API, wrong staticRoot, or stale process | Set project to **Web**; confirm `staticRoot: public`; stop old servers; restart workspace |
|
|
449
557
|
| TV / browser: WebSocket handshake timeout | Node CMS not running or crash-loop | Fix Run → `npm run start`; check logs for `listening` |
|
|
450
558
|
| Deploy/Publish fails / `tsx: not found` | `tsx` only in devDependencies | Move `tsx` to `dependencies`, reinstall, keep `start`: `tsx server.ts` |
|
|
451
559
|
| Deploy runs wrong process | `.replit` / Deployment not `npm run start` | Set `run = "npm run start"` and `[deployment] run = ["sh", "-c", "npm run start"]` |
|
|
560
|
+
| `EADDRINUSE` on start | Old process holding port | Stop stale processes, clear background tasks, restart Repl |
|
|
452
561
|
| Upload: `storage.objects.create` denied | Replit Object Storage IAM | Fix Object Storage permissions **or** switch to Cloudinary |
|
|
453
562
|
| Upload OK then thumbnails vanish later | Non-persistent `public/uploads` | Object Storage or Cloudinary |
|
|
454
563
|
| Supabase connection errors | Wrong URL or using reserved `DATABASE_URL` | Use `SUPABASE_URL` + `TOMORROWOS_STORE=supabase` |
|
|
@@ -458,4 +567,6 @@ TOMORROWOS_STORE=sqlite
|
|
|
458
567
|
|
|
459
568
|
## Protocol version
|
|
460
569
|
|
|
461
|
-
`replit-setup/1.
|
|
570
|
+
`replit-setup/1.1` — aligned with TomorrowOS protocol `1.0` and `@tomorrowos/sdk` store drivers `sqlite` | `supabase` | `postgres` | `memory`.
|
|
571
|
+
|
|
572
|
+
**Changelog 1.1:** strict questionnaire scope; Replit must not use `LLM_PROMPT.md` questions (e.g. standalone target-platform prompt).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomorrowos/sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
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.8",
|
|
17
17
|
"dotenv": "^17.2.3",
|
|
18
18
|
"tsx": "^4.19.0"
|
|
19
19
|
},
|