[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-77820":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":14,"stars30d":14,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":15,"rankGlobal":9,"rankLanguage":9,"license":16,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":19,"hasPages":17,"topics":20,"createdAt":9,"pushedAt":9,"updatedAt":21,"readmeContent":22,"aiSummary":23,"trendingCount":14,"starSnapshotCount":14,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},77820,"mochi","jieyefriic\u002Fmochi","jieyefriic","Desktop pixel pet that eats from your macOS Trash and evolves. Privacy-first, local-only.",null,"Swift",112,1,3,0,40.9,"MIT License",false,"main",true,[],"2026-06-12 04:01:22","# Mochi\n\nA desktop pixel pet that quietly watches your macOS Trash and grows from what you throw away.\n\nIt starts as an egg floating on your desktop. Every time you delete a file, Mochi takes note — `.py` is a magma snack, `.psd` is solar food, `node_modules` is toxin. Over the next few weeks Mochi locks an **element coat** (from your dominant diet), hatches into one of **five species** (decided by the *rhythm* of how you delete), and starts speaking lines in a voice tuned to who you turned out to be.\n\n> **Status:** v0.2 — evolution + sprites + personality engine all live. The pet is a real pet now.\n\n\u003Cp align=\"center\">\n  \u003Cem>5 species × 5 colors × 4 stages = 100 unique sprites · 999 feed-reaction frames · 125 bubble pools.\u003C\u002Fem>\n\u003C\u002Fp>\n\n## Why\n\n`lsof`, Activity Monitor, Finder — none of them tell you anything interesting about your *digital habits*. Mochi is a tiny opinionated mirror: a soft-pixel reminder of what you just chose to throw away today, this week, this month. And it's a desktop pet. That's it.\n\n## Privacy\n\nThis is the first thing to know. Mochi:\n\n- Reads **extension + size + timestamp** only — never the file contents, never the filename, never a hash.\n- Has **no network code**. No telemetry. No crash reporters. No analytics.\n- Stores everything locally in `~\u002FLibrary\u002FApplication Support\u002FMochi\u002F` — `state.json` (the pet) plus an append-only `meals.jsonl` (`{ts, ext, size, category, hour, weekday}`).\n- Source is short enough you can audit it in 30 minutes — start at `TrashWatcher.swift`.\n\n## Install (from source)\n\nRequires macOS 13+, Apple Silicon. No dependencies.\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fjieyefriic\u002Fmochi.git\ncd mochi\n.\u002Fbuild.sh\nopen ~\u002FApplications\u002FMochi.app\n```\n\n`build.sh` runs `swiftc`, flattens ~2,200 sprite PNGs into `Resources\u002F`, ad-hoc codesigns the bundle, and installs it to `~\u002FApplications\u002FMochi.app`.\n\n## First launch\n\nYou'll see a small egg in the bottom-right of your screen with a speech bubble saying `hungry... tap me`.\n\nTap it. A setup window walks you through the one thing that needs doing:\n\n1. **Open System Settings** — deep-links straight to *Privacy & Security → Full Disk Access*.\n2. **Reveal Mochi.app in Finder** — opens Finder with Mochi.app pre-selected, ready to drag into the access list.\n3. Drop Mochi into the list and flip its switch.\n\nThe setup window auto-detects the moment access is granted and dismisses itself. Mochi starts eating.\n\n> Why Full Disk Access? `~\u002F.Trash` is gated behind the strictest TCC tier on modern macOS — there is no purpose-string-driven prompt for it. This is the only path. Mochi will never read anything outside `~\u002F.Trash`.\n\n## The three axes\n\nEvery Mochi specimen is fully described by three orthogonal axes, each driven by a different pattern in your deletion behavior. See `DESIGN.md` for the source of truth.\n\n### Color · what you eat\n\nLocked at **S1 (10 GP)** by your dominant diet across the first 10 meals.\n\n| Dominant diet                     | Element  | Color  |\n|-----------------------------------|----------|--------|\n| `code` (.py .js .ts .swift …)     | Magma    | red    |\n| `image` (.png .psd .jpg …)        | Solar    | gold   |\n| `doc` (.pdf .md .docx .txt …)     | Frost    | blue   |\n| `archive` (.zip .dmg .iso .rar)   | Arcane   | purple |\n| `junk` (.DS_Store .cache .log …)  | Toxin    | green  |\n\nColor is **immutable** after stage 1.\n\n### Species · how you eat\n\nLocked at **S3 hatching (110 GP)** by a 5-D centroid in your meal-rhythm space:\n\n```\nv_freq       mean meals per active day\nv_size       log-mean file size\nv_variance   stddev of meals per hour-of-day  (bursty vs steady)\nv_diversity  unique extensions seen\nv_workhours  fraction of meals in 9-18\n```\n\n| Species   | Body         | Strongest signals                                   |\n|-----------|--------------|-----------------------------------------------------|\n| **DRAKKIN** | dragon-line | high `workhours`, low `variance`, mid `diversity` |\n| **MOCHIMA** | slime-line  | high `freq`, low `size`, high `diversity`          |\n| **FELIQ**   | cat-line    | low `freq`, **very high** `size`, low `diversity` |\n| **AVIORN**  | bird-line   | high `variance`, screenshot-heavy                  |\n| **TIDLE**   | mollusk-line| low `freq`, doc\u002Farchive-heavy, low `variance`     |\n\nSpecies is **immutable** after S3.\n\n### Traits · when & how often you eat\n\nRe-evaluated on a rolling 30-day window. Up to two active at a time.\n\n| Trait        | Activation predicate                            |\n|--------------|-------------------------------------------------|\n| Nocturnal    | ≥ 40% meals in `[22:00, 06:00)`                |\n| Indecisive   | ≥ 20 trash-restore events in 30 days            |\n| Voracious    | mean ≥ 30 meals\u002Fday                             |\n| Hibernator   | mean ≤ 2 meals\u002Fday                              |\n| Polyglot     | ≥ 10 distinct extensions seen                   |\n| Cipherheart  | ≥ 10% archive\u002Fencrypted meals                   |\n| Companion    | force-active starting 1 year after first meal   |\n\nTraits **don't change visuals** — they pick which voice Mochi speaks in. A `Magma DRAKKIN · Nocturnal · Polyglot` says different things from a `Solar TIDLE · Hibernator`.\n\n## Progression\n\n```\n+1 GP per meal · daily soft cap 30 · no decay\n\nS0 Common Egg     0 GP        (default)\nS1 Elemental Egg  10 GP       — color locks, first ceremony\nS2 Cracking       100 GP      — visual transition\nS3 Hatchling      110 GP      — species locks\nS4 Juvenile       300 GP\nS5 Adult          700 GP\nS6 Ultimate       1500 GP     — terminal (Mochi never dies)\n```\n\nFor a steady ~15 meal\u002Fday user: S1 day 1 · S3 ~day 8 · S6 ~5 months.\n\n## Special events\n\n| Trigger                                       | Reaction                              |\n|-----------------------------------------------|---------------------------------------|\n| Trashing a `.git\u002F` folder                     | Bubble: *\"…you sure?\"* (tag SPECIAL_GIT) |\n| Empty Trash with ≥ 100 items at once          | One-off \"feast\" — `+50 GP` bonus      |\n| Idle (no meal for a while)                    | 20–40 min random ambient bubble       |\n\n## Controls\n\n- **Left-click** the egg — opens onboarding if FDA isn't set up; otherwise pulls a contextual idle bubble.\n- **Drag** anywhere on the egg — moves Mochi (position is remembered across launches; `.canJoinAllSpaces` so it follows you between desktops and into full-screen apps).\n- **Right-click** — menu with `Wake Up Mochi (Setup)`, `Reset Position`, `Quit`. Build with `-D MOCHI_DEBUG_MENU` to expose stage \u002F color \u002F species jumps + `+50 GP` for development.\n\n## Inspector — `codex.html`\n\nA standalone HTML inspector lives at the repo root. Open it directly in any browser — no server needed:\n\n```bash\nopen codex.html\n```\n\nPick `(stage · color · species)` from the segmented controls and watch the idle and feed animations cycle inline. Useful for sprite QA and for showing the full 100-variant evolution tree without running the app.\n\n## How it works\n\n```\n~\u002F.Trash  ──FSEvents──►  TrashWatcher  ──TrashMeal──►  PetState\n                                                            │\n                                                            ▼\n                                  EvolutionEngine.processMeal()\n                                  → +GP → maybe color lock \u002F stage jump \u002F species hatch\n                                  → TraitEvaluator (rolling 30d) → active trait set\n                                                            │\n                                                            ▼\n                                  BubbleEngine.pick(tag, color, species, stage)\n                                                            │\n                                                            ▼\n                                          NSPanel + EggSprite (idle + feed-reaction overlay)\n```\n\n| File                   | What it does |\n|------------------------|--------------|\n| `Mochi.swift`          | `@main`, `NSPanel`, drag handling, app delegate, idle bubble timer |\n| `TrashWatcher.swift`   | FSEvents on `~\u002F.Trash` + iCloud Trash, diff-based meal detection |\n| `Persistence.swift`    | `state.json` + `meals.jsonl` + `restores.jsonl` |\n| `Evolution.swift`      | GP ladder, color election, stage transitions, sprite resolution |\n| `Species.swift`        | 5-D centroid election at S3 hatching |\n| `Traits.swift`         | Rolling 30-day predicate evaluator |\n| `Bubbles.swift`        | Loads `bubbles.json` (125 pools), tag-with-fallback picker |\n| `Onboarding.swift`     | FDA setup window + system-settings deeplink |\n\n## Sprite pipeline\n\nAll 111 sprites + ~2,200 animation frames were generated with [PixelLab.ai](https:\u002F\u002Fwww.pixellab.ai\u002F) using the scripts under `scripts\u002F`:\n\n- **`match_objects_full.py`** — Recovers cloud `object_id`s by sha256 byte-matching local PNGs against every cloud preview. (Necessary because `vary_object`-derived color variants inherit the parent's prompt, so prompt-keyword classification mis-buckets them — byte-match is the only reliable way.)\n- **`feed_batch.py`** — Sequential animator: fires `animate-object` per (species × color × stage), polls until done, downloads 9 frames using the URL template, retries on SSL\u002Fnetwork\u002FCUDA OOM. Sequential because PixelLab's per-account concurrency cap is very low (parallel fires get `429: maximum number of concurrent jobs`).\n- **`objects_map_full.json`** — Persistent `object_id` registry. Commit this so the IDs survive even if a future PixelLab UI cleanup wipes their tags.\n\n## Roadmap\n\n- [x] Floating transparent panel + drag + position persistence\n- [x] FSEvents Trash watcher (local + iCloud staging)\n- [x] Onboarding flow for Full Disk Access\n- [x] 100-variant species sprite tree (5 species × 5 colors × 4 stages) + idle anims\n- [x] Feed-reaction animation (one-shot overlay per meal)\n- [x] Local meal\u002Frestore JSONL log (extension + size + category, no filenames)\n- [x] Evolution state machine — color election + 5-D species centroid + GP ladder\n- [x] Trait evaluator — 6 traits + COMPANION 1y anniversary, 30d rolling window\n- [x] Bubble corpus — 125 pools across (color × species × stage) with per-tag voices\n- [x] Special events — `.git` warning, ≥100-item feast bonus\n- [ ] S3 \u002F S6 hatch ceremony — full-screen dim + reveal card\n- [ ] 7-day cooldown on `Reset Mochi`\n- [ ] Bubble localization (zh)\n- [ ] AFK detection so Mochi doesn't talk to an empty desk\n- [ ] External volume Trashes (`\u002FVolumes\u002F*\u002F.Trashes\u002F$UID`)\n- [ ] Alpha-aware hit testing (transparent regions of the sprite click through)\n\n## Contributing\n\nIssues and PRs welcome. Things that are particularly useful right now: macOS 14\u002F15 testing, additional bubble lines (especially zh), tuning the species centroids against real meal logs, and ideas for non-gimmicky special events.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","Mochi 是一款专为 macOS 设计的桌面像素宠物，它会从你的废纸篓中“进食”并根据你删除文件的习惯进化。其核心功能包括通过分析用户删除的文件类型（如.py、.psd等）来决定宠物的成长方向和最终形态，支持五种不同物种、五种颜色以及四个成长阶段共100种独特的外观变化。Mochi强调隐私保护，仅读取文件扩展名、大小及时间戳而不涉及具体内容或名称，并且完全离线运行，所有数据均存储于本地。该项目适合希望在日常使用电脑时增添一点趣味性同时又注重个人隐私安全的macOS用户。",2,"2026-06-11 03:56:07","CREATED_QUERY"]