Local setup, verification, and common change workflows.
- Node.js 22+ (matches CI)
- npm (comes with Node)
git clone https://github.com/namefailed/namefailed.github.io.git
cd namefailed.github.io
npm install
npm run dev| URL | Entry |
|---|---|
| http://localhost:5173/ | Desktop shell |
| http://localhost:5173/static/ | Brochure |
| http://localhost:5173/phoeme/ | Phoneme product page |
Production build:
npm run build # tsc + vite → dist/
npm run preview # serve dist/ locallyRun before opening a PR:
npm run lint # ESLint
npm test # Vitest — 615 unit tests
npm run build # TypeScript + Vite
npm run test:e2e # Playwright (requires preview build)CI (.github/workflows/deploy-pages.yml) runs the same sequence on every push to main.
Coverage report (optional):
npm run test:coverage # output in coverage/ (gitignored)Watch mode during development:
npm run test:watch| Topic | Rule |
|---|---|
| Tests | Co-located: foo.ts → foo.test.ts |
| Test env | Node (no real DOM) — stub document / localStorage when needed |
| Tiles | Filename ends in -window.ts |
| OS layer | Prefix os- |
| WM helpers | Prefix desktop-wm- or desktop- |
| Storage | Always use storage.ts wrapper, never raw localStorage in new code |
| CSS tokens | Use --th-* / --ui-* vars — see THEMING.md |
Full coding standards: STYLE_GUIDE.md.
- Add handler in
src/commands/system-commands.tsorvfs-commands.ts. - Export spreads into
src/commands/index.tsautomatically via submodule import. - Add tests in matching
*.test.ts. - Update help groups in
help-output.tsif the command should appear in a section.
- Create
src/my-app-window.tsimplementing close/minimize/maximize/focus callbacks. - Add lazy import branch in
src/desktop-open-window.ts→dispatchOpenWindow. - Register command in
src/commands/app-commands.ts(returns[]— desktop intercepts). - Add to
TILED_WINDOW_COMMANDSinlauncher-catalog.tsif it should appear in launcher. - Add
prefetchLazyWindowModulecase for hover warmup. - Add tests for any pure logic; WM integration may use
desktop.test.tspatterns.
See API.md for WindowSpec and createWindowChrome.
- Define pack in
src/theme-packs.ts(spreadmochaCss, override deltas). - Append to
THEME_PACKSarray — picker andthemecommand auto-detect.
Details: THEMING.md.
- Change
STORAGE_KEYversion insrc/os-fs.ts(e.g.v8→v9). - Update default seed tree if needed.
- Update docs: ARCHITECTURE.md persistence table.
Returning visitors get a fresh tree; old data is orphaned under the previous key.
Desktop styles live in src/styles/*.css (semantic names like 01-foundation.css, 21-p5.css), imported via src/style.css.
Regenerate split files from monolith backup (if used):
node scripts/split-style-css.mjsBrochure CSS is separate: src/static/static.css (--plain-* tokens). The Phoneme product page has its own stylesheet too: src/phoeme/phoeme.css.
| Issue | Check |
|---|---|
| Tile doesn't open | Browser console; dispatchOpenWindow switch; command in app-commands.ts |
| Terminal command no-op | App commands return [] — desktop must handle via openWindow |
| Theme not applying | theme-control.ts; --th-* keys all present in pack |
| Test fails in Node | Missing DOM stub — see bsp-layout.test.ts or desktop.test.ts FakeEl patterns |
| iframe reloads on layout | BSP never moves iframe elements after mount — see bsp-layout.ts comment |
GitHub Pages serves dist/, not the repo root.
- Repo → Settings → Pages → Source → GitHub Actions
- Push to
maintriggers build + deploy
Custom domain: configured in repo settings (currently mrgrey.site).
| Doc | When |
|---|---|
| ARCHITECTURE.md | Module map and data flow |
| AGENTS.md | Machine-oriented repo guide |
| API.md | Type reference |
| USER_GUIDE.md | End-user features |