387 Commits

Author SHA1 Message Date
93fdc7d0f9 chore: gitignore .wave/state.db (Wave runtime sqlite)
Some checks failed
CI / ci (push) Successful in 1m5s
Deploy / deploy (push) Failing after 40s
2026-04-30 12:21:20 +02:00
ab6dabd542 fix(ci): correct image digest separator
Some checks failed
CI / ci (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
2026-04-30 12:20:26 +02:00
ba4d3fc89d ci: digest-pin runner-image v0.1.0
Some checks failed
CI / ci (push) Failing after 0s
Deploy / deploy (push) Failing after 0s
2026-04-30 12:17:45 +02:00
bf20e9d39e ci: update runner-image + repo path to public/ namespace
Some checks failed
CI / ci (push) Failing after 1s
Deploy / deploy (push) Failing after 1s
Repos moved to public/ on Gitea: public/runner-image (CI image)
and public/code-crispies (this repo). Updates workflow image refs,
spec hyperlinks, README, and compose tags.
2026-04-30 11:54:06 +02:00
967069a65c ci: kick first Gitea Actions run after enabling actions
All checks were successful
Deploy / deploy (push) Successful in 1m28s
CI / ci (push) Successful in 1m59s
2026-04-29 17:41:54 +02:00
4762952822 ci(deploy): Gitea-driven build/push/deploy for netcup (#14)
Replaces the GitHub Pages workflow with a Gitea Actions pipeline that publishes the cc image to `git.librete.ch/libretech/code-crispies` and ssh-deploys it to `/srv/cc` on netcup.

## Changes
- `.gitea/workflows/ci.yml` — npm test + sanity build (with placeholder VITE_*) on every push / PR.
- `.gitea/workflows/deploy.yml` — single-job build → push → ssh-deploy → /healthz check, gated on `vars.DEPLOY_ENABLED`. Tag push → `:vX.Y.Z` + `:latest`; main push → `:main` + `:sha-<7>`.
- `compose.yaml` — adds `image: ${CC_IMAGE:-cc:local}` so production pulls the published tag while dev still builds locally.
- Both workflows pin `git.librete.ch/libretech/runner-image:v1` (no third-party Docker Hub images, no `--user root`).

## Operator follow-up (before merging into hot deploy)
- Set repo secrets at `https://git.librete.ch/libretech/code-crispies/settings/actions/secrets`:
  - `REGISTRY=git.librete.ch`
  - `REGISTRY_USER=libretech` (user-namespace packages — bot can't push)
  - `REGISTRY_PASS=<libretech package PAT>` (same PAT used for `libretech/runner-image`)
  - `DEPLOY_HOST=root@cloud.librete.ch`
  - `DEPLOY_KEY=<bot deploy private key>` (same key as librenotes deploy)
  - `DEPLOY_PATH=/srv/cc`
  - `HEALTH_URL=https://cc.cloud.librete.ch/`
  - `VITE_SUPABASE_URL=https://yretixuyfuiresnrjkbs.supabase.co`
  - `VITE_SUPABASE_ANON_KEY=<the anon key>` (public-by-design supabase key)
- Set repo variable `DEPLOY_ENABLED=true` once the secrets are in.
- Add `CC_IMAGE=git.librete.ch/libretech/code-crispies:main` to `/srv/cc/.env` on netcup (no rebuild on host).

## Verification
- `yq -e .` parses both workflow YAMLs.
- `docker compose config` resolves cleanly in both build mode (no `CC_IMAGE`) and image-pull mode (`CC_IMAGE=test:1`).
- `npm test` is the same script the previous github-pages workflow ran.

Reviewed-on: libretech/code-crispies#14
Co-authored-by: Michael Czechowski <mail@dailysh.it>
Co-committed-by: Michael Czechowski <mail@dailysh.it>
2026-04-29 17:28:18 +02:00
1e4b4430ee feat(wave): add pedagogy-auditor persona 2026-04-28 22:00:28 +02:00
f216db8953 chore(deps): refresh package-lock 2026-04-28 22:00:27 +02:00
be99f9e4f7 feat: add umami tracking via umami.cloud.librete.ch 2026-04-28 20:31:27 +02:00
d0dbd3c257 feat(deploy): docker compose + nginx static for netcup VPS 2026-04-28 18:58:32 +02:00
45fc2a43f0 Merge pull request 'fix: rewrite CSS Filters tasks to describe visual outcomes' (#13) from 012-filters-tasks into main 2026-03-29 23:33:11 +02:00
8c96d6aa64 fix: implement #12 — rewrite CSS Filters tasks to describe visual outcomes 2026-03-29 23:27:43 +02:00
b25e6a4e20 docs: add spec, plan, and tasks for filters task wording fix (#12) 2026-03-29 23:24:32 +02:00
c5641a8364 fix: revert primary and section colors back to original lilac/purple
The impl-feature pipeline changed the default color scheme from
lilac/purple (#5e4b8b, #9163b8) to pink (#c9507a, #d95a8a).
This was unintentional — lilac was the chosen brand color.

Reverted: primary, section defaults, bg tints, success colors,
gradients, nav highlights, and all hardcoded rgba values back to
the original purple palette.
2026-03-29 22:22:23 +02:00
00e9bd18e5 Merge pull request 'fix: rewrite colors and box-model tasks to describe outcomes instead of answers' (#10) from 009-colors-boxmodel-tasks into main 2026-03-29 00:01:08 +01:00
1baff9075c feat: implement #9 — rewrite colors and box-model task descriptions
Rewrite task text in Colors (4 lessons) and Box Model (8 lessons x 6
locales) to describe visual outcomes instead of giving copy-paste CSS
answers. Colors validations changed from property_value to regex
accepting multiple valid named colors per lesson.
2026-03-28 23:56:55 +01:00
3d6ff645fe docs: add spec, plan, and tasks for colors and box-model task wording fix (#9) 2026-03-28 23:51:13 +01:00
dc048eba4e Merge pull request 'feat: add JavaScript learning section with starter lessons and sidebar section headers' (#8) from feat/impl-feature-20260328-200101-ecae into main 2026-03-28 21:32:38 +01:00
05a683388b Merge pull request 'fix: rewrite validation messages to guide learning instead of revealing answers' (#7) from 004-validation-messages into main 2026-03-28 21:32:31 +01:00
ae8f9fef45 feat: add JavaScript learning section with starter lessons and sidebar section headers
Implementation following plan:
- S01: Foundation: schema, section config, and router
- S02: Install CodeMirror JavaScript language support
- S03: Create JavaScript lesson JSON files (variables, DOM, events)
- S04: Register JavaScript lessons in module stores
- S05: Add JavaScript validation logic
- S06: Add JavaScript mode to LessonEngine preview rendering
- S07: Add JavaScript mode to CodeEditor
- S08: Update app.js for JavaScript mode support
- S09: Update navigation HTML and CSS theming for JavaScript section
- S10: Add section grouping headers in sidebar navigation
- S11: Update and write tests
2026-03-28 20:22:50 +01:00
8d567390e5 fix: rewrite validation messages to guide learning instead of revealing answers (#4) 2026-03-28 20:10:04 +01:00
372320b807 Merge pull request 'fix: rewrite flexbox tasks to describe outcomes instead of answers' (#5) from 003-flexbox-task-wording into main 2026-03-28 19:59:24 +01:00
61acd692f4 fix: rewrite flexbox task descriptions to describe outcomes instead of answers (#3)
Replace copy-pasteable CSS declarations in all 6 flexbox lesson tasks with
outcome-oriented descriptions. Update validation error messages to hint at
properties without revealing exact declarations. Add regex validation for
flexbox-6 to accept both flex: 1 and flex-grow: 1.
2026-03-28 19:25:32 +01:00
672a2d28cb docs: add spec, plan, and tasks for flexbox task wording fix (#3) 2026-03-28 19:17:48 +01:00
433379155b fix(security): add Content-Security-Policy meta tag
Restricts script sources to self and known CDNs, connect sources to
self and Supabase, blocks unauthorized resource loading. Allows
unsafe-inline for styles (CodeMirror requirement) and blob: for
sandboxed preview iframes.

Addresses SEC-5 (HIGH) from security audit.
2026-03-28 17:01:32 +01:00
756841f8c2 fix(security): sandbox preview iframes to prevent XSS
Add sandbox='allow-scripts' to all preview iframes. This isolates
user-executed code from the parent page's localStorage (auth tokens),
cookies, and DOM. Switch from document.write() to srcdoc attribute
since sandboxed iframes can't use document.write().

Addresses SEC-1 (critical) from security audit.
2026-03-28 16:38:56 +01:00
c97fce1f29 fix: replace github personas with gitea, add ontology telos 2026-03-28 16:19:15 +01:00
8b6a88ad59 test: add 182 new tests for router, sections, renderer, and validator
Generated by wave test-gen pipeline. Coverage:
- router.js: 0% → ~85% (33 tests, all 7 exports)
- sections.js: 0% → ~90% (29 tests, all 5 exports)
- renderer.js: partial → extended (36 tests, difficulty, feedback, sidebar)
- validator.js: partial → extended (84 tests, all types + edge cases)

Total: 43 → 225 tests
2026-03-28 16:14:52 +01:00
4476d26140 chore: update wave.yaml to latest wave version with corrected project config 2026-03-28 15:58:46 +01:00
f28531fb4c ignore auto claude files 2026-01-27 16:53:47 +01:00
7ab095718b chore(nix): add flake with claude-code in devShell 2026-01-25 21:28:16 +01:00
5a243f332a chore: temporarily disable Tailwind CSS section
- Comment out Tailwind nav links in header and sidebar
- Comment out Tailwind card on landing page
- Remove tailwind from router SECTIONS array
- Remove tailwind from landing page progress tracking

Tailwind content and styles remain in codebase for easy re-enabling.
2026-01-25 15:40:53 +01:00
739470e045 feat: add Markdown learning module with 8 beginner lessons
- Add markdown-basics module with lessons for headings, text formatting,
  lists, links, and inline code
- Integrate markdown section with blue color theme (#5b8dd9)
- Add markdown mode support in CodeEditor and LessonEngine
- Add markdown preview rendering using marked library
- Add section overview page with educational content
- Add markdown reference page with syntax guide
- Add i18n translations for 6 languages (EN, DE, PL, ES, AR, UK)
- Update router to recognize #markdown as section route
- Add all section-specific CSS styles for markdown theme
2026-01-25 11:27:07 +01:00
07aafa0d89 feat(app): pass codePrefix/codeSuffix to editor on lesson load
- Update loadCurrentLesson() to pass prefix/suffix to editor
- Use getEditableValue() in runCode() to get only user code
2026-01-25 02:00:07 +01:00
eb82eed826 style: add styling for read-only editor zones
Dimmed appearance with subtle background for codePrefix/codeSuffix regions.
2026-01-25 01:59:59 +01:00
82f6e46d3c feat(editor): add read-only zones support for codePrefix/codeSuffix
- Add initWithContext() method for prefix/suffix initialization
- Implement changeFilter to prevent edits in read-only zones
- Add transactionFilter to constrain cursor to editable area
- Add visual decorations with cm-readonly-zone class
- Update getValue/setValue to handle editable portions correctly
2026-01-25 00:39:09 +01:00
847b261f16 fix: restore gradient scaling and distribute milestone colors evenly 2026-01-16 23:45:19 +01:00
2ce88f9cb7 fix: milestone colors now correctly reflect position in 0-100 gradient 2026-01-16 23:40:38 +01:00
a8ef3d3c5c fix: progress bar now shows milestone progress instead of overall progress 2026-01-16 23:21:41 +01:00
0f5ac81fe8 fix: shorten German reset progress label to 'Fortschritt' 2026-01-16 22:01:15 +01:00
cf0d2cba51 feat: add lesson difficulty indicators and improve mobile sidebar
- Add computeLessonDifficulty function to determine lesson difficulty
  based on selector complexity (easy/medium/hard)
- Display difficulty badge with bar indicator in lesson title row
- Add mobile navigation links (CSS, HTML, Tailwind) to sidebar
- Add mobile auth trigger button in sidebar
- Redesign settings section with card layout and native toggles
- Add difficulty translations for all 6 languages
- Fix module pill overflow on narrow screens
2026-01-16 21:47:47 +01:00
d5bd23615f fix: update German CTA to 'Jetzt gleich anfangen' 2026-01-16 16:53:38 +01:00
fcc6748aae fix: update German landing hero text to 'Lerne Web Entwicklung mit CODE CRISPIES' 2026-01-16 16:41:17 +01:00
5c16a8a767 feat: redesign sidebar progress to show milestone progress and total lessons 2026-01-16 16:37:23 +01:00
17b3d5380d fix: show Next button disabled in playground instead of hiding it 2026-01-16 15:32:21 +01:00
f9311d83f7 fix: remove centered class toggle - grid layout handles positioning 2026-01-16 15:31:17 +01:00
f4ce61ba64 fix: add gap between game controls grid items 2026-01-16 15:29:44 +01:00
813d669302 fix: use CSS grid for game controls to keep pill centered when next is hidden 2026-01-16 15:28:45 +01:00
9328399dcb fix: change 'Crispy Code' to 'Code Crispy' in landing page title 2026-01-16 15:27:14 +01:00
857ae9c3ef fix: move device notice under section cards on landing page 2026-01-16 15:26:10 +01:00