Skip to content

feat: UX/a11y polish + right-click quit + open-source onboarding#9

Merged
cskwork merged 3 commits into
mainfrom
feat/ux-quit-and-docs
May 4, 2026
Merged

feat: UX/a11y polish + right-click quit + open-source onboarding#9
cskwork merged 3 commits into
mainfrom
feat/ux-quit-and-docs

Conversation

@cskwork
Copy link
Copy Markdown
Owner

@cskwork cskwork commented May 4, 2026

Summary

Three focused commits that prepare the repo for public release:

  1. feat(ux): mood glyphs, a11y polish, sleep wake-up — closes BACKLOG #16/#17/#19/#20.
  2. feat: right-click quit menu + robust save persistence — adds the missing close affordance for the frameless overlay window, and fixes the repeating "(couldn't save state)" bubble.
  3. docs: README polish, contributor + AI agent guides, CI workflow — LICENSE, CONTRIBUTING.md, AGENTS.md, .github/ templates + CI, docs/ARCHITECTURE.md, README rewrite.

What changed

UX & a11y (commit 1)

  • New mood-distinguishing glyphs: 🍡 hungry, … bored, ♡ lonely (colors alone made these too similar).
  • Patting a sleeping pet now plays yawn → blush → celebrate instead of snapping to celebrate.
  • Sprite <img> no longer announces "Mochi pet" on top of the button's "Mochi" aria-label.
  • Settings loading state announces via role="status" aria-live="polite".

Desktop functional (commit 2)

  • Right-click → Close Mochi context menu. New quit_app Tauri command on the Rust side.
  • roundStats() helper at the persistence boundary. Backend models stats as i32; the simulator accumulated fractional decay each tick so saves were silently failing every cycle with serde "invalid type: floating point".
  • Heart bond badge now Math.round'd at display (was rendering ♥0.999754).
  • Save-failure bubble now shows the real error reason (truncated), and only on the first failure of a streak — repeated failures log only.

Open-source onboarding (commit 3)

  • LICENSE (MIT) — README was claiming MIT but the file was missing.
  • CONTRIBUTING.md — required checks, what kinds of PRs are welcome, what needs an issue first.
  • AGENTS.md — project brief for AI coding agents (Claude Code, Codex, Cursor…) so AI-assisted PRs match the simulation-first invariants.
  • .github/PULL_REQUEST_TEMPLATE.md + bug/feature issue templates.
  • .github/workflows/ci.yml — vitest + svelte-check + cargo test --lib + cargo build on every push/PR (Linux runner with full webkit2gtk deps).
  • docs/ARCHITECTURE.md — deeper-than-README walkthrough of the 4-layer stack, why values are floats internally and ints at the boundaries, salience gate, sandbox model.
  • README.md rewrite: tighter hero, sprite gallery (12 poses), badges, install above architecture.

Why

  • Closes pending BACKLOG items.
  • Eliminates the visible save-failure spam loop and its root cause.
  • Makes the overlay actually closeable without Task Manager.
  • Prepares for public release: contributor onboarding paths for both humans and AI agents.

Test plan

  • npm test99/99 passing (3 new: roundStats boundary tests + sleep-wake-up sequence)
  • npm run check0 errors / 0 warnings
  • cd src-tauri && cargo test --lib41/41 passing
  • cd src-tauri && cargo check — clean
  • npm run tauri:dev — manually verified app launches, vite ready in ~1s, cargo dev profile finished, pet-mochi.exe runs without panic
  • Reviewer: smoke-test right-click → Close Mochi closes the app
  • Reviewer: leave Mochi idle for 30+ minutes, confirm no (couldn't save state) bubble and bond shows an integer
  • Reviewer: trigger hungry/bored/lonely mood and confirm the new glyph appears (and is suppressed during the conflicting action animation)

Reviews

Both typescript-reviewer and code-reviewer subagents reviewed commit 1 in parallel:

  • 1 HIGH (bored glyph collided with action animations) — fixed
  • 4 MEDIUM (yawn-during-bored, redundant test assertion, alt="" container assumption, etc.) — fixed where actionable, documented otherwise

Notes

This branch was created because direct push to main was blocked by the contributor's tooling. The CONTRIBUTING.md file in this PR codifies the PR-first workflow it accidentally enforced. 🙂

cskwork added 3 commits May 4, 2026 21:37
Closes BACKLOG #16, #17, #19, #20 from the 2026-05-03 review:

- #19: hungry/bored/lonely now have distinguishing glyphs (🍡/…/♡) so
  desaturated mood tints stop reading identically. Each is suppressed
  during the conflicting action animation (eat/blush/yawn/celebrate).
- #20: applyAction("pet") prepends a yawn beat when the pet was sleeping,
  replacing the old sleep→celebrate snap. Test added.
- #16: <img alt=""> on the sprite — the parent button already names the
  control via aria-label="Mochi", so the image is decorative.
- #17: Settings loading state now uses role="status" aria-live="polite".

#15 (per-event-kind cooldowns) and #18 (ChatInput) intentionally skipped
— see DECISIONS.md for the rationale.
The desktop overlay window is frameless, so users had no way to close
the app short of Task Manager. Adds a small right-click context menu
with a "Close Mochi" item that invokes a new `quit_app` command on the
Rust side (`app.exit(0)`).

While here, fix two related save-path symptoms:

- "(couldn't save state)" bubble repeated every ~4 s. The simulator
  accumulates fractional decay each tick (e.g. relationshipLevel drifts
  by 0.0023/s after 30 min idle), but the backend models every stat as
  i32 — so save_pet_state was failing with serde "invalid type:
  floating point" on every cycle. New `roundStats()` helper in
  sim/state.ts canonicalizes the conversion at the persistence
  boundary; Pet.svelte:scheduleSave wraps with it.
- Heart bond badge displaying "♥0.999754". PetStatus.svelte was the one
  remaining gauge that didn't apply Math.round at render. Fixed.

The save-failure UX itself is also less noisy now: only the FIRST
failure in a streak shows a bubble (with the actual error reason
truncated to 60 chars), subsequent failures log only.
Reorients the project for public release:

- README.md: tighter hero, sprite gallery (12 poses), clearer install
  flow, badges, install/usage above architecture.
- LICENSE: MIT (the README was already claiming it; now it's real).
- CONTRIBUTING.md: human contributor guide — quick start, the four
  required checks before opening a PR, simulation-first principles,
  what kinds of PRs are welcome and what needs an issue first.
- AGENTS.md: brief for AI coding agents (Claude Code, Codex, Cursor,
  Aider…). Encodes the architectural invariants — pure simulation in
  src/lib/sim, integer-at-boundaries stat handling, salience-gated LLM
  calls, sandbox path-jail — so an AI agent can produce a PR a human
  reviewer will accept.
- .github/PULL_REQUEST_TEMPLATE.md + ISSUE_TEMPLATE/{bug,feature}.md.
- .github/workflows/ci.yml: vitest + svelte-check + cargo test --lib +
  cargo build on every push/PR. Linux runner with full Tauri webkit2gtk
  build deps.
- docs/ARCHITECTURE.md: deeper-than-README design walkthrough — 4-layer
  stack, 3-second tick anatomy, why values are floats internally and
  ints at boundaries, salience gate, memory ranking, sandbox model,
  event flow on a typical interaction, testing strategy.
@cskwork cskwork merged commit d684583 into main May 4, 2026
2 checks passed
@cskwork cskwork deleted the feat/ux-quit-and-docs branch May 4, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant