{"id":50188734,"url":"https://github.com/khawkins98/classic-vibe-mac","last_synced_at":"2026-05-25T11:34:08.996Z","repository":{"id":356412709,"uuid":"1232416730","full_name":"khawkins98/classic-vibe-mac","owner":"khawkins98","description":"Vibe-code your own classic Mac app. C source in, 68k Mac binary out, served running in System 7.5.5 in a browser via WebAssembly Basilisk II. A 1993 Macintosh that lives at a URL.","archived":false,"fork":false,"pushed_at":"2026-05-15T09:49:55.000Z","size":8259,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-15T10:38:06.771Z","etag":null,"topics":["68k","basilisk-ii","classic-mac","github-template","mac-os","retro68","system-7","webassembly"],"latest_commit_sha":null,"homepage":"https://khawkins98.github.io/classic-vibe-mac/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/khawkins98.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-07T23:06:05.000Z","updated_at":"2026-05-15T09:49:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/khawkins98/classic-vibe-mac","commit_stats":null,"previous_names":["khawkins98/classic-vibe-mac"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/khawkins98/classic-vibe-mac","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khawkins98%2Fclassic-vibe-mac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khawkins98%2Fclassic-vibe-mac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khawkins98%2Fclassic-vibe-mac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khawkins98%2Fclassic-vibe-mac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/khawkins98","download_url":"https://codeload.github.com/khawkins98/classic-vibe-mac/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khawkins98%2Fclassic-vibe-mac/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33473704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-25T06:32:55.349Z","status":"ssl_error","status_checked_at":"2026-05-25T06:32:35.322Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["68k","basilisk-ii","classic-mac","github-template","mac-os","retro68","system-7","webassembly"],"created_at":"2026-05-25T11:34:08.827Z","updated_at":"2026-05-25T11:34:08.974Z","avatar_url":"https://github.com/khawkins98.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# classic-vibe-mac\n\n**Vibe-code classic Macintosh apps in your browser.** Edit C in the\npage, hit Build \u0026 Run, your code is running on an emulated Mac OS 7\nin seconds. Pair it with your favorite AI coding assistant and you\ncan write period-correct Macintosh software the way nobody could in\n1995 — with autocomplete, a chat that knows the Toolbox APIs, and no\ninstall needed.\n\nUnder the covers: a System 7-style IDE that compiles classic Mac C\nstraight to a `.bin` and boots it. **Open the page, pick a sample,\nclick Build \u0026 Run; the Mac wakes up with your freshly-compiled app\non the desktop.** `cc1` + `as` + `ld` + `Elf2Mac` are all wasm-bundled\n— no install, no toolchain on your machine, no backend. Edit the\nsource in the page; hit Build \u0026 Run again; the Mac reboots in ~1s\nwith your changes. The full read / edit / compile / hot-load loop is\nlive in production today.\n\n\u003e **Two-repo project.** This repo ships the playground, demo apps,\n\u003e and the in-browser editor + emulator integration. The wasm\n\u003e toolchain it compiles your code with lives in a sibling repo,\n\u003e **[`wasm-retro-cc`](https://github.com/khawkins98/wasm-retro-cc)** —\n\u003e Retro68's C compiler + binutils + Elf2Mac, Emscripten-compiled.\n\u003e That toolchain is also reusable on its own; nothing in\n\u003e `wasm-retro-cc` is cv-mac-specific.\n\n## Live at\n\n**https://khawkins98.github.io/classic-vibe-mac/** — the full\nplayground: 26 in-browser-buildable samples (a small\nToolbox-coverage ladder from one-line \"Hello, World!\" up to the\n1992 game *Glypha III* — playable, with sprite art and sound),\nedit-and-rebuild loop running, the Mac wakes up the moment you\nclick Build \u0026 Run.\n\nToolchain-only proof of life: **https://khawkins98.github.io/wasm-retro-cc/**\n— compile a Toolbox `hello.c` straight through the four wasm tools\nwithout booting an emulator. Useful when evaluating\n[`wasm-retro-cc`](https://github.com/khawkins98/wasm-retro-cc) for\nyour own non-cv-mac use.\n\n## Reading paths\n\nThis README serves three different visitors:\n\n- **[I'm curious — what is this?](#what-it-does)** Two-minute read.\n  Screenshots, the live link, what's running where.\n- **[\"I'm using the playground\" → the handbook](./docs/HANDBOOK.md)**\n  End-user manual. What every button does, the keyboard shortcuts\n  (⌘P for Open Quickly, the Routines popup, Build \u0026 Run, the Debug\n  Console), where files live, how to fork a sample as a new project\n  of your own. Start here if you opened the page and want to do\n  something.\n- **[I want to try it / build something with it](#try-it)** Step-by-step\n  walkthrough from \"open the URL\" through \"compile my own C code in\n  the tab\" through \"fork it for my own app.\"\n- **[I want to understand how it works or build on the platform itself](#build-on-it)**\n  Pointers into the deeper docs: architecture, build pipeline, design\n  rationale, dev process, gotchas.\n\n## What it looks like\n\n![Live deployed page: a Mac OS 8 Platinum-styled IDE with a top menubar (Apple / File / Edit / View / Special / Windows / Help, with a \"cv-mac \u003chash\u003e\" build stamp and clock on the right), and four draggable WinBox panes tiled across the viewport. Top-left: Project picker listing the wasm-* sample shelf. Centre-left: Playground with syntax-highlighted C source. Top-right: Macintosh pane — on first paint shows a \"Welcome to Macintosh — Pick a project and Build \u0026 Run\" placeholder; after Build \u0026 Run, the Mac boots into System 7.5.5 with the user's freshly-built app on a secondary disk on the desktop. Bottom-right: Output panel with Build log + Console tabs.](public/screenshot-deployed.png)\n\nThe deployed page is the IDE first; the Mac is a build target the\nIDE delivers into. Four docked panes:\n\n- **The Project picker** (top-left) — 26 sample apps in a small\n  Toolbox-coverage ladder, from one-line \"Hello, World!\" up through\n  GWorld double-buffering, dialog managers, file I/O, custom icon\n  resources, a Markdown editor with live preview, and (at the top\n  of the ladder) the 1992 game *Glypha III*. Pick one; it opens in\n  the editor.\n- **The Playground** (centre-left) — CodeMirror 6 with C syntax\n  highlighting, a project tab bar, and per-project file persistence\n  in IndexedDB. ⌘-click any Toolbox identifier to pin its\n  Inside-Macintosh-style reference card. Edit and your changes\n  survive reloads.\n- **The Macintosh** (top-right) — empty until you click Build \u0026 Run.\n  Shows a \"Welcome to Macintosh — Pick a project and Build \u0026 Run\"\n  placeholder on first paint. When you build, the page compiles your\n  source through wasm-cc1 → wasm-as → wasm-ld → wasm-Elf2Mac in your\n  tab, packages the result as a MacBinary, hot-loads it onto a\n  fresh secondary disk, and boots System 7.5.5 with your app's disk\n  on the desktop. First boot ~15s cold; subsequent Build \u0026 Runs ~1s.\n- **The Output panel** (bottom-right) — Build log mirrors `[cvm]`,\n  `[build-c]`, `[asm]`, `[cvm-fetch]`, `[cvm-stats]` lines from the\n  compile pipeline. Console tab surfaces `cvm_log()` output from\n  your running Mac app (see [`cvm_log.h`](./src/app/wasm-debug-console/cvm_log.h)).\n\n## What it does\n\nTwo things, sequenced in that order:\n\n- **Playground** — visit the live URL, pick a sample from the\n  project picker, read the C and Rez source in the editor, edit it,\n  click Build \u0026 Run. The page compiles your edits through the wasm\n  toolchain (`cc1.wasm` + `as.wasm` + `ld.wasm` + `Elf2Mac.wasm`,\n  built from Retro68 via\n  [`wasm-retro-cc`](https://github.com/khawkins98/wasm-retro-cc)),\n  packages the result as a MacBinary, mounts it on a fresh secondary\n  disk, and boots System 7.5.5 with your app's disk on the desktop.\n  Subsequent Build \u0026 Runs reuse the cached toolchain and the warm\n  boot disk and finish in ~1 second. Edits persist in IndexedDB.\n  Architecture rationale and the phase plan live in\n  [`docs/PLAYGROUND.md`](./docs/PLAYGROUND.md).\n- **Template** — the same repo is structured so you can fork it,\n  add your own sample under `src/app/wasm-\u003cyour-name\u003e/`, register\n  it in `src/web/src/playground/types.ts`, push, and your sample\n  shows up in the picker on your fork's GitHub Pages URL. The\n  playground rides along with the deploy. See\n  [Fork it for your own app](#fork-it-for-your-own-app) below.\n\nThe hard project constraint, which is worth stating up front because\nit shapes every design choice: **everything runs as JavaScript in\nthe visitor's browser. No backend, no relay, no auth, no compile\nservice.** Two Epics that violated that constraint were closed after\nreview (#12 and #19); the playground (#21) is what survived as the\narchitecturally honest version. See\n[`docs/ARCHITECTURE.md` § What we deliberately avoid](./docs/ARCHITECTURE.md#what-we-deliberately-avoid)\nfor the long version.\n\n### The sample shelf\n\n26 small-to-medium classic Mac apps under `src/app/wasm-*/`. The\nplayground picker surfaces all of them with a complexity rating\n(★☆☆☆☆☆ → ★★★★★★) so visitors can pick an on-ramp matched to their\ncomfort level. Highlights:\n\n- **Wasm Hello** — `DrawString` only. The \"this is what a Mac app\n  looks like at absolute minimum\" rung. Default selection.\n- **Wasm Clock** — analog face + digital readout with `GetDateTime`,\n  `FrameOval`, hand-drawn trig table. Pure QuickDraw.\n- **Wasm Files** — `StandardGetFile` / `StandardPutFile`,\n  `FSpCreate`, `FSWrite`. The \"talk to disk\" rung.\n- **Wasm Bounce** — offscreen `BitMap` + `CopyBits` double-buffer.\n  No flicker, exactly the way it was done in 1989. Also instruments\n  itself with `cvm_log()` so the Console tab in the IDE shows live\n  ball-position trace as it plays.\n- **Wasm GWorld** — the modern System 7+ way to do the same thing\n  (`NewGWorld`, `LockPixels`, `UpdateGWorld`).\n- **Wasm Icon Gallery** ★★★★★★ — uses an external `.rsrc.bin`\n  asset spliced into the disk image (the `binaryAssets` infra).\n- **Debug Console demo** — the smallest possible exercise of\n  `cvm_log()` / `cvm_log_p()` / `cvm_log_reset()`, the Mac-side\n  API the IDE's Console tab picks up via a polled `:Unix:` file.\n- **Glypha III** ★★★★★★ — John Calhoun's 1992 game, vendored\n  whole. 6,600 LOC, nine .c files. Plays in the browser tab with\n  sprite art, 17 sound effects, and a working menu bar — the \"real\n  period app at scale\" milestone for the in-browser pipeline. The\n  underlying wasm-rez stack-overflow that briefly blocked it was\n  fixed in #287; full closeout story is `docs/DEBUGGING-VENDORED-APPS.md`.\n- **Wasm Markdown** ★★★★☆☆ — split-pane Markdown editor with live\n  preview. The \"modern format, classic chrome\" sample — Markdown\n  post-dates System 7 by a decade, but here it is in Geneva and\n  Chicago against grey bevel windows.\n\nFull inventory + coverage matrix in\n[`src/app/README.md`](./src/app/README.md). Adding a sample is a\nnew `src/app/wasm-\u003cname\u003e/` directory + a `SAMPLE_PROJECTS` entry\nin `src/web/src/playground/types.ts` + a SEED_FILES entry in\n`src/web/vite.config.ts` — no CMake, no CI step, no toolchain\ninstall. The audit at `npm run audit:wasm-e2e` compiles every\nsample headlessly on every PR so regressions surface at review\ntime, not at \"user clicks Build.\"\n\n## Try it\n\n### As a visitor (no install)\n\nOpen \u003chttps://khawkins98.github.io/classic-vibe-mac/\u003e. The IDE loads\nin ~2 seconds: project picker on the left, editor in the middle,\nMacintosh pane top-right showing a \"Welcome to Macintosh — Pick a\nproject and Build \u0026 Run\" placeholder, Output panel bottom-right.\nThe Mac doesn't actually boot until you ask it to — first build\nfetches the boot disk + warms the wasm toolchain (~15s cold), so\nthe page stays fast for visitors who just want to read source.\n\nPick a sample from the project dropdown (default is *Wasm Hello* —\na one-window \"Hello, World!\"). Read the C source in the editor.\nHit **Build \u0026 Run**. The progress window shows you what's happening\n(Preparing → Compiling → Packaging → Mounting → Booting); once boot\nfinishes, your app appears as a disk on the Mac's desktop —\ndouble-click to launch.\n\nType into the editor. Reload the page — your edits are still there\n(IndexedDB, per-project). Build \u0026 Run again, and the warm-cache\nloop finishes in ~1 second. The Console tab in the Output panel\ncatches anything your app emits via\n[`cvm_log()`](./src/app/wasm-debug-console/cvm_log.h) (the Mac-side\ndebug-log API) — useful for verifying your changes actually ran.\n\nSomething not working? See\n[`docs/TROUBLESHOOTING.md`](./docs/TROUBLESHOOTING.md)\nfor the symptom → cause → fix table.\n\n### Locally\n\n```sh\n# One-time setup\nbrew install hfsutils                    # for HFS disk packing (macOS)\ngit clone https://github.com/khawkins98/classic-vibe-mac.git\ncd classic-vibe-mac\nnpm install\nnpm run fetch:emulator                   # BasiliskII.wasm + Quadra-650.rom\n```\n\nTwo paths from here, depending on whether you want the full boot\ndisk available or just the page chrome.\n\n**Page-only** — fast (~5 seconds to first paint), no Docker needed,\nno CI fetch. The Mac canvas shows the welcome placeholder forever\n(no boot disk → no boot), but the IDE, the picker, the editor, the\nOutput panel, and the audit all work normally:\n\n```sh\nnpm run dev               # → http://localhost:5173/\nnpm run audit:wasm-e2e    # compile every sample's .c + .r locally, no browser\nnpm run audit:wasm-e2e -- wasm-mdpad   # or just one\n```\n\n**Full deploy** — also includes the boot disk so Build \u0026 Run actually\nlaunches the Mac. Pulls the boot disk from CI rather than rebuilding\nit from scratch (the boot disk build needs `hfsutils` + the\nupstream System 7.5.5 image; CI handles both):\n\n```sh\ngh run download \\\n  \"$(gh run list --branch main --workflow Build --limit 1 \\\n       --json databaseId -q '.[0].databaseId')\" \\\n  -D /tmp/cvm-artifact\n\nART=\"$(echo /tmp/cvm-artifact/classic-vibe-mac-*)\"\ncp \"$ART/system755-vibe.dsk\" src/web/public/\ncp \"$ART/system755-vibe.dsk.json\" src/web/public/\ncp -R \"$ART/system755-vibe-chunks\" src/web/public/\n\nnpm run dev      # → http://localhost:5173/\n```\n\nOpen \u003chttp://localhost:5173/\u003e. The Vite dev server already sets the\nCOOP/COEP headers BasiliskII needs for `SharedArrayBuffer`, so you\nskip the service-worker reload dance the production GitHub Pages\ndeploy does.\n\nFor day-to-day iteration loops (fast unit-test cycle, in-browser\nedit cycle, CI ship cycle), see\n[`docs/DEVELOPMENT.md`](./docs/DEVELOPMENT.md).\n\n## How it works\n\nA static GitHub Pages site ships HTML + JS + WASM + a chunked HFS\ndisk image. The page registers a service-worker shim for cross-origin\nisolation, mounts a CodeMirror-based editor seeded with the sample\nshelf, and parks the Mac canvas at a welcome placeholder. When the\nuser clicks Build \u0026 Run, the page hands the active project's source\nto wasm-cc1, runs the four-stage pipeline (cc1 → as → ld → Elf2Mac),\nsplices a SIZE resource onto the output, patches a fresh HFS template\nwith the resulting MacBinary, spawns a Web Worker, and instantiates\nBasiliskII against the boot disk + the just-built secondary disk.\nMac comes up; your app's disk is on the desktop.\n\nThe data flow is bidirectional but disciplined: **JS owns the\nnetwork**, Mac owns rendering and the event loop. The runtime\nback-channel is a mounted extfs volume (the Mac sees it as\n`:Unix:`); the Mac can read host-seeded files there and write back\n(e.g. `cvm_log()` lands in `:Unix:__cvm_console.log` which the host\npolls into the Output panel's Console tab). There is no\ngeneral-purpose socket inside the Mac. The opt-in AppleTalk/Ethernet\npath is `?zone=\u003cname\u003e`: `src/web/src/ethernet-provider.ts` bridges\nthe emulator worker to a Cloudflare Durable Object relay in `worker/`.\n\nFor the byte-by-byte version — boot pipeline, SharedArrayBuffer\nlayout, the four-state input lock, the chunked disk reader, the\ntwo-way `:Shared:` data flow, the multi-app model — see\n[`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md). For why the\nplayground is shaped this way (Rez-in-WASM, no backend, no auth,\nno GCC port), see\n[`docs/PLAYGROUND.md`](./docs/PLAYGROUND.md).\n\n## Iterating on it\n\nThree loops, fastest first. Pick the fastest one that exercises your\nchange.\n\n1. **In-browser (sub-second warm, no install).** Open the live page,\n   edit a sample's source in the playground, click Build \u0026 Run. The\n   page compiles your edits in-browser and hot-loads the result into\n   the Mac in ~1s.\n2. **Audit + host tests (couple seconds).** `npm run audit:wasm-shelf`\n   compiles every sample headlessly via the same wasm-cc1 the browser\n   uses. `npm run test:unit` runs the JS preprocessor + HFS-patcher\n   suites. Catches compile + structural regressions before push.\n3. **CI deploy (~5-10 min).** Push, let CI build, deploy lands on\n   Pages.\n\nThere's no cross-compile loop any more — every app the playground\nships compiles in the browser. The CMake aggregator under `src/app/`\nis empty scaffolding for any future host-native build; today it\nconfigures + builds nothing.\n\nThe full walkthrough — first-time setup, all four loop variants,\ncommon-task recipes, common failure modes mapped to fixes — is in\n[`docs/DEVELOPMENT.md`](./docs/DEVELOPMENT.md). The architectural\npattern the apps follow (and the rationale for the split) is in\n[`src/app/README.md`](./src/app/README.md).\n\nThe dev process this project has converged on (the five-reviewer\nred-flag pass that killed Epics #12 and #19 and produced #21) is\ndocumented in [`docs/AGENT-PROCESS.md`](./docs/AGENT-PROCESS.md).\n\n## Status\n\nThe playground is **feature-complete on the main editor + build +\nrun loop**. Highlights of what's shipped on `main` today:\n\n- **End-to-end in-browser C compilation** (cc1 + as + ld + Elf2Mac\n  all wasm-bundled, produced from Retro68 via\n  [`wasm-retro-cc`](https://github.com/khawkins98/wasm-retro-cc)).\n  Build \u0026 Run on any sample boots the result cleanly in BasiliskII.\n  First time anyone has compiled classic Mac C in a tab and watched\n  it launch.\n- **26-sample shelf** under `src/app/wasm-*/`, climbing from a\n  one-line \"Hello, World!\" up through GWorld double-buffering,\n  modal dialogs, file I/O, custom resource fork assets, a Markdown\n  editor with live preview, and (at the top) the 6,600-LOC 1992\n  game *Glypha III* — playable, with sprite art and 17 sound effects.\n- **Deferred-boot UX** — the Mac canvas shows a welcome placeholder\n  on first paint; boots into System 7.5.5 with your freshly-built\n  app's disk on the desktop when you click Build \u0026 Run. Page load\n  is fast (no boot disk fetch); the IDE is the product, the Mac is\n  a build target.\n- **Mac OS 8-style build progress window** while compile/boot\n  happens, with per-phase timing, a slow-compile reassurance hint\n  (\u003e15s in Compiling reveals \"why so slow\"), and per-stage\n  diagnostics.\n- **Debug Console** — the Output panel's Console tab surfaces\n  Mac-side `cvm_log()` output in near-real-time via a polled\n  extfs back-channel. `cvm_log.h` is mounted as a system header so\n  any sample can `#include \u003ccvm_log.h\u003e` without bundling.\n- **Opt-in AppleTalk/Ethernet zone networking** via `?zone=`.\n\nThe canonical shipped-state checklist — what's live, what's\nclosed-Epic, what's next — lives in\n[`docs/PLAYGROUND.md`](./docs/PLAYGROUND.md#status). The current\nforward-looking work is open in the\n[issue tracker](https://github.com/khawkins98/classic-vibe-mac/issues)\n— Aaron UI window-manager prototype (#246), boot-disk Finder window\nsuppression (#245), and the rainbow Apple menu + runtime color-depth\nswitching (#224) are the live tickets at the time of writing.\n\n## Recently shipped\n\n- **IDE affordances — make a Mac app without leaving the tab**\n  (2026-05-18, #319 / #320 / #321 / #322). Four new playground\n  affordances ship a real \"vibe-code a Mac app\" loop end-to-end:\n  the **`+`** in the tab bar adds a new `.c` / `.h` / `.r` file to\n  the current project (#319); **File → Duplicate as new project…**\n  forks any sample into an IDB-only project you can edit + Build\n  independently (#320); a **{ } Routines** popup above the editor\n  jumps you to any function in the current file (CodeWarrior-style)\n  (#321); and **⌘P** opens a fuzzy file-jump palette (#322).\n  Together they make starting from a sample → forking → editing\n  multiple files → building a single uninterrupted loop. New\n  end-user manual at\n  [`docs/HANDBOOK.md`](./docs/HANDBOOK.md).\n- **Welcome modal + sample gallery** (2026-05-18, #307). First-run\n  greeter with a curated 4-card sample gallery (Wasm Hello / Wasm\n  Markdown / Wasm Bounce / Wasm Glypha III) so first-time visitors\n  see the ladder. Re-openable from Apple → \"Welcome to\n  classic-vibe-mac…\".\n- **Deferred-boot IDE** (2026-05-17, #279). Mac doesn't auto-boot\n  on page load; canvas shows a welcome placeholder until first\n  Build \u0026 Run. Page load went from \"25 MB boot disk + 15s of cold\n  boot before the visitor can do anything\" to \"IDE in 2 seconds,\n  Mac only when asked for.\"\n- **Precompiled-path retirement** (2026-05-17, #276 → #277 / #278).\n  The legacy auto-launching demo apps (Reader, MacWeather, Hello\n  Mac, Pixel Pad, Markdown Viewer) were retired wholesale; the\n  in-browser pipeline is now the only path. ~9,000 LOC of\n  scaffolding gone.\n- **Glypha III playable** (2026-05-17 → 2026-05-18, #287–#292,\n  closing #256). First third-party period app on the shelf — 6,600\n  LOC, John Calhoun's 1992 game, vendored whole. Now boots into the\n  real game with sprite art, 17 sound effects, and a working menu\n  bar. The closeout pulled in two reusable pieces: the wasm-rez\n  STACK_SIZE bump that unblocked any large `.r` (#287), and the\n  vendored-app debugging toolkit captured in\n  [`docs/DEBUGGING-VENDORED-APPS.md`](./docs/DEBUGGING-VENDORED-APPS.md) +\n  [`docs/VENDORING-A-MAC-APP.md`](./docs/VENDORING-A-MAC-APP.md).\n- **Wasm Markdown (live preview)** (2026-05-18, #296). New\n  split-pane sample: source TextEdit on the left, custom-drawn\n  rendered preview on the right, re-renders on each keystroke. The\n  \"modern format in classic chrome\" exhibit.\n- **`audit:wasm-e2e` + diagnostic toolkit** (2026-05-17 → 2026-05-18,\n  #294, #297, #299). `npm run audit:wasm-e2e` runs both halves of\n  the build (`.c` via wasm-cc1 + `.r` via wasm-rez) and prints a\n  combined pass/fail line per sample — the local pre-push check\n  for any playground change. Companion `scripts/splice-bin.mjs`\n  reproduces the browser's resource-fork splice in plain Node for\n  offline inspection.\n- **Debug Console tab** (2026-05-16, #261). `cvm_log()` API +\n  watcher pipeline. Originally the \"Coming soon\" placeholder under\n  Output → Console; now live with unread indicators and a system\n  header so any sample can use it.\n- **Output panel improvements** (2026-05-16, #258 / #259 / #274).\n  Copy button, fetch-time breakdown in stats, Mac OS 8-style build\n  progress window with slow-compile hint.\n- **Compile pipeline refactor chain** (2026-05-17, #267 → #270 /\n  #273). One canonical pipeline runner shared between the in-browser\n  Build path and the Node-side CI audit; no more \"compile flag bump\n  in one place, drift in the other.\"\n- **GPL-3.0 relicense** (2026-05-17, #281). Aligned with upstream\n  inheritance (BasiliskII GPL-2.0+, Retro68 GCC/binutils GPL-2.0+ /\n  GPL-3.0+). The MIT declaration we shipped was inaccurate the\n  moment the in-browser compiler started redistributing wasm-\n  compiled GCC/binutils binaries.\n\nFor the current status table, see\n[`docs/PLAYGROUND.md`](./docs/PLAYGROUND.md#status).\n\n## Fork it for your own app\n\nThe repo is still a GitHub template. The playground rides along\nwith the deploy.\n\n1. **Fork** this repository (or click \"Use this template\" on\n   GitHub).\n2. **Add `src/app/wasm-\u003cyour-app\u003e/`** with your own C source. At\n   minimum: one `.c` file with a `main()` and one `.r` file (SIZE,\n   WIND if you want a window, signature data). Pick a 4-letter\n   creator code. See\n   [`src/app/README.md` § How to add a new app](./src/app/README.md#how-to-add-a-new-app).\n3. **Register the sample.** Two short entries:\n   - `src/web/src/playground/types.ts` → push a `SampleProject`\n     entry (id, label, files, rezFile, outputName, appType,\n     appCreator, complexity).\n   - `src/web/vite.config.ts` → push the same files into the\n     `SEED_FILES` map so they get copied into the playground bundle.\n4. **Verify locally.** `npm run audit:wasm-e2e -- wasm-\u003cyour-name\u003e`\n   runs both halves of the build (`.c` + `.r`) for your sample.\n   If it goes green, the\n   browser-side Build will too.\n5. **Push to `main`.** GitHub Actions builds the bundle (no\n   cross-compile step — the wasm toolchain ships in the bundle)\n   and publishes to GitHub Pages.\n6. **Open your repo's Pages URL.** Your sample shows up in the\n   playground picker. Visitors pick it, edit it, and Build \u0026 Run\n   produces a working Mac binary running in their tab.\n\nThe web layer in `src/web/` doesn't usually need touching — it's\nthe container the OS boots in. Edit it if you want a different\npage chrome around the emulator.\n\n## Build on it\n\nPointers for the third reader path — *I want to understand how it\nworks, modify the platform, or extend it.* Suggested reading order:\n\n1. **[`docs/HOW-IT-WORKS.md`](./docs/HOW-IT-WORKS.md)** — Guided\n   tour. From \"you typed the URL\" through \"the Mac is running and\n   the editor is seeded\" to \"you clicked Build and the new binary\n   booted.\" One layer of abstraction below this README.\n2. **[`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md)** — Engineer\n   deep-dive. The boot pipeline, the SharedArrayBuffer layout, the\n   four-state input lock, the chunked disk reader, the two-way\n   `:Shared:` data flow, the multi-app model. Read this if you're\n   going to modify the host TypeScript or worker.\n3. **[`docs/PLAYGROUND.md`](./docs/PLAYGROUND.md)** — The\n   playground's design rationale (Epic #21), the five-reviewer pass\n   that produced it, the open child issues, and the closed-Epic\n   graveyard. Read before proposing anything that smells like \"what\n   if we just added a backend.\"\n4. **[`docs/DEVELOPMENT.md`](./docs/DEVELOPMENT.md)** — Local\n   iteration. The four loops (in-browser, host-test, cross-compile,\n   deploy), first-time setup, common-task recipes, common failure\n   modes → fixes. Start here if you're cloning the repo.\n5. **[`src/app/README.md`](./src/app/README.md)** — Per-app\n   anatomy. How `add_application()` wires creator codes through\n   Rez, the Toolbox-shell + pure-C-engine split, how to add a new\n   app to the boot disk.\n6. **[`docs/AGENT-PROCESS.md`](./docs/AGENT-PROCESS.md)** — The\n   five-reviewer red-flag pass that catches \"what if we just added\n   a backend\"-class proposals before they sink weeks. Useful if\n   you're scoping new work.\n7. **[`LEARNINGS.md`](./LEARNINGS.md)** — Running gotcha log + Key\n   Stories. Skim this before you debug anything weird. Six Key\n   Stories at the top are required reading for toolchain work.\n8. **[`docs/TROUBLESHOOTING.md`](./docs/TROUBLESHOOTING.md)** —\n   Symptom → cause → fix table for the common things that break.\n9. **[`docs/HANDBOOK.md`](./docs/HANDBOOK.md)** — End-user manual for\n   the playground itself: every button, every shortcut, where files\n   live, how to fork a sample as your own project. Use this when you\n   want to know what something *does*, not how it's built.\n10. **[`docs/NETWORKING.md`](./docs/NETWORKING.md)** — Specialised:\n    the opt-in AppleTalk zone relay.\n11. **[`docs/VENDORING-A-MAC-APP.md`](./docs/VENDORING-A-MAC-APP.md)** —\n    Recipe for adding a third-party period Mac app to the sample\n    shelf so it builds end-to-end in the playground. Distilled from\n    the Glypha III closeout (#287–#292).\n12. **[`docs/DEBUGGING-VENDORED-APPS.md`](./docs/DEBUGGING-VENDORED-APPS.md)** —\n    Companion to the vendoring recipe: instrumentation patterns +\n    offline splice repro for when a vendored app fails silently.\n\nFor cross-repo context (the wasm toolchain itself), see\n[`wasm-retro-cc`](https://github.com/khawkins98/wasm-retro-cc).\n\n## Requirements\n\n- A current desktop browser (Chrome, Firefox, Safari).\n- For local development: Node 20+, npm, and `hfsutils` (`brew\n  install hfsutils` on macOS, `apt-get install hfsutils` on\n  Debian/Ubuntu).\n- For local Mac binary builds: Docker (to run the Retro68 image)\n  — or just pull the latest CI artifact, which is faster.\n- The OS disk is downloaded once from archive.org during the\n  boot-disk build; ROM and BasiliskII core come from Infinite\n  Mac. None are bundled in this repository.\n\n## Credits\n\nBuilt on the work of others who did the heavy lifting:\n\n- **[Retro68](https://github.com/autc04/Retro68)** by Wolfgang\n  Thaller and contributors — the cross-compiler that makes 68k\n  Mac binaries from modern source. Mixed licensing reflecting its\n  GCC / binutils heritage (GPL-2.0+ and GPL-3.0+); the\n  cc1 / as / ld / Elf2Mac binaries cv-mac vendors via\n  [wasm-retro-cc](https://github.com/khawkins98/wasm-retro-cc)\n  redistribute GPL-licensed code. See NOTICE for the chain.\n- **[Infinite Mac](https://github.com/mihaip/infinite-mac)** by\n  Mihai Parparita — Basilisk II and SheepShaver compiled to\n  WebAssembly, plus the chunked disk-fetch infrastructure we lean\n  on. Apache-2.0 (with the underlying BasiliskII core itself\n  GPL-2.0; see NOTICE).\n- **Basilisk II** by Christian Bauer and the open-source\n  community — the 68k Mac emulator that all of this rides on.\n  GPL-2.0.\n- **System 7.5.5** by Apple Computer, freely redistributed since\n  Apple's 2001 release.\n- **CodeMirror 6** for the editor surface. MIT.\n- **JSZip** for in-browser zip generation. MIT/GPL dual-licensed.\n- **Susan Kare**, in spirit, for the icons that taught the world\n  what computers were allowed to look like.\n\n## License\n\n**GPL-3.0-or-later** for our code. See [LICENSE](./LICENSE) and\n[NOTICE](./NOTICE) for the full attribution stack, including:\nBasiliskII (GPL-2.0+), Infinite Mac (Apache-2.0), Retro68\n(GPL-2.0+ / GPL-3.0+ for its GCC / binutils-derived parts),\nSystem 7.5.5 (Apple's 1998 free-redistribution release). When\nthe emulator core ships next to a deploy, its own LICENSE and\nNOTICE files travel with it.\n\n\u003e **A note on what GPLv3 does and doesn't cover.** This project —\n\u003e the emulator wrapper, the IDE, the build infrastructure — is\n\u003e GPL-3.0-or-later. If you fork or modify *this project*, your\n\u003e fork is GPLv3-bound. **However**, classic Mac apps you write\n\u003e *using* the playground and compile with the bundled toolchain\n\u003e are entirely your own work. The compiler's license governs the\n\u003e compiler, not its output — the same way a code editor's license\n\u003e doesn't apply to what you type into it. License your own apps\n\u003e however you want.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhawkins98%2Fclassic-vibe-mac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhawkins98%2Fclassic-vibe-mac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhawkins98%2Fclassic-vibe-mac/lists"}