Repository navigation
Releases
Releases · johnpc/spork
Spork Android android-20261109001314
fix(study): keep a finished session's streak when the app closes or r…
Spork Android android-20261108181234
ci: deploy, seed and tear down an ephemeral sandbox per CI run (#39) CI read one hand-made dev sandbox (amplify-spork-xss-sandbox-08f8a387ed), so it broke when that sandbox was deleted. Each run now deploys its own ci-<run id> sandbox, creates the e2e editor in the fresh pool, seeds, runs quality + acceptance against it, and deletes it in an if: always() teardown job. A 6-hourly sweep deletes leaked ci<digits> sandboxes older than 6h. The study streak scenario navigated with page.goto right after finishing, aborting the in-flight UserStat write; it only passed on the old sandbox because a UserStat row from earlier runs already existed. It now waits for that write to land first.
Spork Android android-20261107224811
ci: sign iOS archives from the Mac mini CI keychain (#36) * ci: sign iOS archives from the Mac mini CI keychain Automatic signing can't work in the self-hosted runner's system launchd context. Sign manually with the CI keychain's Apple Distribution identity (shared ~/ci-signing tool), drop the certificate-revoke step and the /Users/runner key path, and add per-job timeouts. * fix(deps): resync package-lock.json so npm ci passes npm ci has failed on every CI and deploy run since 2026-11-03 with 'lock file's semver@7.8.5 does not satisfy semver@7.8.6': the lockfile was missing entries, so npm re-resolved them and picked up the newly published semver 7.8.6. Regenerated with npm install --package-lock-only (minimal change).
Spork Android android-20260728204111
perf(routes): lazy-load every game screen to halve first-load JS (#32) Only ChessAttack was code-split; every other game's list + play screen was eagerly imported into the main bundle, so a visitor landing on Home downloaded all eight game engines (the Quizzes/map renderer, Wordle's word list, etc.) before seeing anything. Now each game route is lazy-loaded behind the shared LazyRoute Suspense boundary — a visitor pulls only the chunk for the game they open. - Main `index` chunk: 795 kB → 408 kB raw (249 kB → 120 kB gzip), a 52% cut to first-load JS. The heavy renderers (Quizzes Play 243 kB, Wordle 107 kB) now load on demand. - Preserves the IonRouterOutlet contract: gameRoutes() still returns an ARRAY of direct <Route> elements (the GameRoutes regression guard still passes), with a small gameRoute() helper wrapping each lazy component in LazyRoute. - Harden three flaky game e2e steps (steps/quizzle/acrostic): accumulated daily puzzles can share a topic with the static seed but have different content, so target the static seed (UUID href), not a `daily-*` one, disambiguating the strict-mode match the topic filter otherwise hit.
Spork Android android-20260728203112
fix(admin): show a retry when deck, run, or draft reads fail (#31) Manage Decks and Quiz Studio rendered a failed list read as a false empty — "no decks yet" or silently-empty runs/drafts sections — with no way to recover. Amplify's `.list()` resolves (never rejects) on GraphQL errors, so a transient failure looked identical to genuinely empty. Same root cause as the play/ discover/flashcards fixes; last of the swallowed reads in the app. - unwrap the reads in `fetchAllDecks`, `fetchGenerationRuns`, `fetchQuizRuns`, and `fetchDraftQuizzes` so a failure throws (→ react-query error). - Route the deck list (ManageDecks) and the runs/drafts sections (QuizAdmin) through the shared `LoadState` (isError → retry). The generate/create forms above stay usable — only the list sections gate. - Cover it: unit tests (each fetch throws on errors; each screen surfaces a retry that fires refetch, form still present) + Gherkin scenarios failing the specific read (listDecks; listGenerationRuns/listQuizzes).
Spork Android android-20260728201252
fix(flashcards): show a retry when deck, study, or library reads fail…
Spork Android android-20260728200352
fix(flashcards): show a retry when deck, study, or library reads fail…
Spork Android android-20260728194715
feat(shell): app toast for transient feedback (failed action surfaces…
Spork Android android-20260728193653
fix(games): keep daily puzzles out of the evergreen game lists (#34) The scheduled daily ingest writes one PUBLISHED `daily-<game>-<date>` puzzle per game every day, and each game's home list rendered ALL published puzzles — so the evergreen lists (/steps, /quizzle, /acrostic, /wordle, /spellingbee, /connections, /quizzes) grew by ~1 row/day forever into an unbounded wall of links, even though daily puzzles already have their own /daily/:game browse surface. - Add a shared pure `isDailyPuzzle(id)` helper (matches the `daily-` id prefix). - Filter daily-generated puzzles out of every evergreen list composer/API, so the home lists stay a curated set. Seed puzzles use auto-generated ids (never `daily-`), so only the accumulating dailies are removed — the lists don't empty. - Cover it: a unit test per game asserting dailies are excluded while evergreen puzzles remain, plus the isDailyPuzzle helper's own tests. Verified live: all game lists still render + play their evergreen puzzles.
Spork Android android-20260707190534
feat(daily): browse past days, permalink them, and badge each day's r…