尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Every morning, something fun and a little smart waits for your kid on paper.
Tearaway is the parent web app for a kitchen strip (58mm thermal today; US Letter / N80 next). Parents configure a kid profile (name, age band, paper size → slots, print time, weather, watchlist, calendar). Kids never log in — they are profiles, not accounts (COPPA).
This MVP is a local demo: no auth, no Stripe, no secrets, no real printer. Config lives in data/store.json (seeded from data/store.sample.json).
Open http://localhost:3000.檢視完整 README ↗Every morning, something fun and a little smart waits for your kid on paper.
Tearaway is the parent web app for a kitchen strip (58mm thermal today; US Letter / N80 next). Parents configure a kid profile (name, age band, paper size → slots, print time, weather, watchlist, calendar). Kids never log in — they are profiles, not accounts (COPPA).
This MVP is a local demo: no auth, no Stripe, no secrets, no real printer. Config lives in data/store.json (seeded from data/store.sample.json).
cd /workspace/tearaway-app
npm install
npm run dev
Open http://localhost:3000.
Production build:
npm run build
npm start
| Path | What |
|---|---|
/ | Marketing home |
/app | Dashboard — live strip/letter preview, Generate new strip, recent preview history, Print now |
/app/setup | Create a kid (name + age band + paper size + starter modules) |
/app/modules | Paper size → fixed slots; add modules into slots; in-order / random when a slot has 2+ |
/app/settings | Timezone / print time, weather, watchlist, calendar; tier stub (modulePoolLimit) |
Aliases that redirect: /dashboard → /app, /setup → /app/setup, /modules → /app/modules, /settings → /app/settings.
paperSize and slots live on each kid (not global kitchen settings). Kitchen settings.paperSize is only the default for newly created kids.
| Paper size | Slots | Preview |
|---|---|---|
strip58 | 4 | Classic ~384px thermal strip |
letter | 7 | Wider ~612px letter-ish page (2-column body) |
Flow on /app/modules:
Empty slots are skipped at generate time; save requires at least one filled slot.
single) → that modulein_order → moduleIds[cursor % length]; cursor advances after each successful Generate / Print now (persisted in store.json)random → seeded RNG from date + kid first name + nonce + slotId (reshuffle changes outcome)Legacy flat kid.modules: ModuleId[] is still written (unique pool across slots) and migrated into slots on read if slots is missing.
On /app, Generate new strip bumps the per-kid nonce, regenerates the preview (random slots reshuffle; in-order slots use the current cursor then advance), and keeps the last 3–5 previews for comparison. Print now saves a job using the current seed and slot picks, then advances in-order cursors. Refresh preview reloads without bumping the seed or cursors.
settings.modulePoolLimit: number | null — null unlocks all first-party modules (MVP). Later tiers can cap how many unique modules sit in a kid’s pool. No Stripe / payments in this build. Settings shows a short note.
The parent UI is not required for printing. Later firmware (ESP32 + Oreilet 58mm) can HTTP-fetch today’s strip.
| URL | What |
|---|---|
GET /api/render?kid=<id> | HTML of today’s strip (default format=html) |
GET /api/render?kid=<id>&format=png | PNG preview (strip width today) |
GET /api/render?kid=<id>&format=json | Structured PrintJob (sections + meta; no HTML) |
GET /strip/<id> | Same HTML strip in a page (iframe preview) |
GET /api/print-jobs/preview | Generate for the active kid (no persist; no cursor advance) |
POST /api/print-jobs/reshuffle | Bump nonce + preview + advance in-order cursors |
POST /api/print-jobs/print-now | Generate + save queued job + advance in-order cursors |
GET /api/print-jobs/latest | Last queued job for the active kid |
GET / PUT /api/store | Read / patch JSON store |
GET /api/weather | Open-Meteo snapshot (falls back to mock offline) |
Query params for /api/render
kid (required) — profile id, e.g. demo-samdate (optional) — YYYY-MM-DD. Default: today in the kid’s timezoneformat (optional) — html | png | jsonExample: /api/render?kid=demo-sam&date=2026-09-16&format=png
No ESC/POS yet. No talk to a real printer. HTML/PNG/JSON is the handoff.
Content is seeded by date + kid first name + nonce. Same inputs → same strip. Bumping the nonce (Generate new strip) reshuffles without changing the day. Multi-module slots add another layer of pick resolution (above).
| Module | Notes |
|---|---|
| Maze | Perfect maze; size by age band |
| Word Find | Tiny word-search (6×6–8×8) that fits 58mm |
| Connect the Dots | Funny numbered dots + silly caption (SVG) |
| Riddle | Question + answer on the strip (think first) |
| Number Puzzle | 4×4 / 6×6 / easy 9×9; parent key on-screen only |
| Module | Notes |
|---|---|
| Word of the Day | Age-banded definition + example |
| Poem of the Day | Short printable poem |
| Breakfast Joke | Age-banded groaners; kid-safe, no mean stuff |
| Spanish Word | Spanish + phonetic + English + try-it line |
| Module | Notes |
|---|---|
| This Day in History | Kid-appropriate local catalog |
| Fun Fact | Curated sample copy |
Wonder + discovery tone. No violence / politics anxiety. City news is generic “hometown” style (no geo API yet).
| Module | Notes |
|---|---|
| World News | Animals, space, discoveries |
| National News | Parks, science fairs, kindness |
| Hometown News | Library, playground, neighbors |
| Tech News | Robots, code, gadgets |
| Gamer News | Games, makers, fair play |
| Module | Notes |
|---|---|
| Weather | Open-Meteo + Zippopotam (no API key); mock if offline |
| Stock Watchlist | Mocked prices — not live market data |
| Calendar | Local events you edit in Settings |
| Module | Notes |
|---|---|
| Tiny Doodle | 30-second drawing prompt for the strip margin |
| Would You Rather | Two choices + a tiny debate nudge |
Demo kid (data/store.sample.json): strip58 with four slots — word · joke/riddle (in order) · doodle/wyr/poem (random) · maze/spanish (in order).
Space Week, Scorecard, Gratitude Note, Tongue Twister — shown in the modules UI as “coming soon.” First-party modules above are not duplicated here. No payments or pack install yet.
data/store.json (gitignored)data/store.sample.json (committed)kid.paperSize: "strip58" | "letter"
kid.slots: Array<{
id: string
moduleIds: ModuleId[]
mode: "single" | "in_order" | "random"
cursor?: number // in_order only
}>
settings.modulePoolLimit: number | null // null = all unlocked
Next.js (App Router) · TypeScript · Tailwind CSS · local JSON store
Private prototype — dad + kid project.
All animal line art is from OpenMoji, © OpenMoji contributors, licensed CC BY-SA 4.0. See src/lib/puzzles/animal-art.ts.