

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# Fizzy23Cross-platform, open-source general editor written in Zig, UI via [DVUI](https://github.com/david-vanderson/dvui). Targets native (macOS/Linux/Windows) and web (wasm32). Layout/UX is IDE-shaped (VSCode-like): sidebar rail + explorer, menubar, center tabs/splits, bottom panel, infobar.45**Read this file first, then go deeper via the links below — don't re-derive the architecture from scratch.**67## The core idea: fizzy + plugins89Fizzy the app is itself a near-empty host (window, frame loop, menu/sidebar/panel layout, document model) that owns **no editing features**. Everything the user sees — pixel-art editing, the file explorer/tabs/splits, text editing — is contributed by **plugins** that register against a stable SDK. Plugins never import each other; they meet only at the SDK.1011```12Fizzy (Editor) ←── Host registries + EditorAPI ──→ Plugin (register(host) + vtable)13```1415- **`src/sdk/`** — the entire contract. `Host` (registries + service locator), `Plugin` (identity + vtable of hooks Fizzy calls), `DocHandle` (opaque `{ptr, id, owner}` — Fizzy routes every doc op to `owner`, never inspects `ptr`), `EditorAPI` (Fizzy's own read/util surface plugins reach back through), `regions.zig` (sidebar/bottom/center/menu/settings/command contribution structs), `dylib.zig`/`dvui_context.zig` (runtime-library C-ABI + dvui injection).16- **`src/editor/`** — Fizzy itself: `Editor.zig` (frame loop, plugin registration/loading), `PluginLoader.zig` (dlopen), `Menu.zig`, `Sidebar.zig`, `Settings.zig`, etc.17- **`src/core/`** — shared infra (Atlas/Sprite, math, gfx, fs, paths, platform detection) used by Fizzy *and* plugins. Not plugin-owned; don't move it. `core.fuzzy` is the one matcher behind every filter box in the app (settings tree, file tree, plugin store, LSP completions) — wrap zf through it rather than matching by hand, and remember **lower scores are better**.18- **`src/plugins/`** — bundled built-in plugins. Each is file-for-file the **same shape a third-party plugin would use**: root `plugin.zig` + identity-only `plugin.zig.zon` + `build.zig` + `build.zig.zon` (optional `src/**`), plus fizzy-internal glue in `static/`. No author `root.zig` or `<name>.zig` hub — the build helper generates the dylib entry; files use named imports (`fizzy_sdk`/`dvui`/…). Builds standalone with `cd src/plugins/<name> && zig build`.1920**Two link modes, one source:** built-in plugins compile **static** (linked directly, all targets incl. web) or **dynamic** (`.dylib`/`.so`/`.dll`, desktop-only, `dlopen`'d — this is how third-party plugins ship too). `FIZZY_STATIC_<NAME>=1` env var forces static for a given built-in (useful when debugging dylib loading).2122## Currently bundled plugins (check `ls src/plugins/` — this list moves)2324- **`workbench`** — file tree, tabs/splits, center provider; owns no documents. Exposes a `workbench-api` service other plugins use to open/close/manage files without importing workbench.25- **`text`** — generic text/code editor; fallback owner for any file extension nothing else claims. (Recently renamed from `code`.)26- **`image`** — read-only PNG/JPG/JPEG viewer with zoom/pan (fallback when pixi is not installed).27- **`markdown`** — `.md` preview utility plugin.28- `shared` — build helpers used across plugins' `static/integration.zig` (not a plugin itself).2930**Pixi (pixel-art editor) has been extracted out of this repo** into an external, third-party-style plugin ([`fizzyedit/pixi`](https://github.com/fizzyedit/pixi), `~/dev/fizzyedit/pixi`) — it ships and updates purely through the plugin store (`docs/PLUGINS.md` §6), with no special treatment in Fizzy itself. Older docs/handoffs (`HANDOFF.md`) still describe pixi as in-tree — that's historical, not current. **Trust `ls src/plugins/` and `git log` over any doc's plugin list.**3132## Writing a plugin33341. Copy `src/plugins/text/` as your template (or `src/plugins/image/` for a document-owning viewer).352. Add identity-only `plugin.zig.zon` (`id`/`name`/`version`/`min_sdk_version`). Implement root `plugin.zig`: `Plugin` + `register(host)` + vtable; call `host.register{SidebarView,BottomView,CenterProvider,Menu,Command,Service,…}` as needed.363. Plugin prefs: `sdk.settings.Schema(struct { … })` then `.register(host, &plugin, …)` — Fizzy draws them only while the plugin is loaded (no SettingsSection). User config on disk is ZON (`settings.zon` / `recents.zon`).374. Editor plugins implement the document vtable cluster; workbench-style plugins register a center provider + sidebar views instead.385. User-invoked actions are **`Command`s** — `"<active_owner_id>.<action>"`.396. `zig build install` drops `{id}/{id}.dylib` (its own directory) into the fizzy plugins dir (no sidecar `.zon`).407. Memory: `host.allocator` vs `host.arena()`; never touch `dvui.currentWindow().gpa` directly.418. ABI: structural fingerprint at `dlopen` (`fizzy_plugin_abi_fingerprint`); bumps are rare/deliberate.4243Full contract: **[`docs/PLUGINS.md`](docs/PLUGINS.md)**. Living reshape plan: **[`docs/PLUGIN_MANIFEST_PLAN.md`](docs/PLUGIN_MANIFEST_PLAN.md)**.4445## Plugin store: built, not forward-looking4647The plugin registry/install flow (author repo → release CI → `fizzyedit/plugins` registry →48in-app store) is fully built and is the canonical publishing path for every third-party49plugin, `pixi` included. It's documented end-to-end in `docs/PLUGINS.md` §6; the registry50repo itself is [`fizzyedit/plugins`](https://github.com/fizzyedit/plugins) and the reusable51release CI is [`fizzyedit/plugin-build-action`](https://github.com/fizzyedit/plugin-build-action).52Don't trust older narrative docs that call this forward-looking/not-yet-built.5354## Historical docs (not current — don't re-derive architecture from these)5556- **`HANDOFF.md`** — historical Phase 4 handoff (compile-time modular separation, predates the57 pixi extraction and the `code`→`text` rename). Superseded by `docs/PLUGINS.md` for anything58 plugin-related; useful only for the older "how did we get here" narrative.5960## Build6162```sh63zig build # native exe64zig build check-web # wasm65zig build test # unit/integration tests66zig build test-sdk-version # CI lock: ABI fingerprint bump must bump sdk_version too67```6869Run all of these after touching the SDK boundary (`src/sdk/**`) or a plugin's vtable usage.7071### Keep the plugin build free of app-only dependencies7273Plugins depend on the **`sdk/` package** (its own `build.zig` + `build.zig.zon`), not the repo root. The root zon owns the editor build and may list app-only deps (Velopack, nightwatch, …). A root-zon `.lazy = true` URL dep is **not** enough by itself: Zig eagerly unpacks lazy URL deps that already sit in the global cache into every consumer's `zig-pkg`, so after any app build a plugin depending on the root package would grow a Velopack tree even though `lazyDependency` never runs on the plugin path.7475Pattern:7677- **Plugins** (built-in + third-party): `.fizzy = .{ .path = ".../sdk" }` locally, or the `fizzy-sdk-v*` **release asset** URL from the matching `sdk-v*` tag (not the git archive — that is the monorepo root zon with Velopack). Call `fizzy.plugin.create` / `.install` as before; `b.dependency("fizzy", .{ .plugin_sdk = true })` still works (the option is accepted and ignored — `sdk/` always exports modules). Packing: `scripts/pack-sdk.sh` / `.github/workflows/sdk-tag.yml`.78- **App**: repo-root `zig build` as usual. Velopack stays `.lazy = true` in the root zon; never `@import("velopack_zig")` — the helper surface is vendored in `build/velopack.zig` and resolved only in `build/app.zig` via `lazyDependency`.79- Shared `core` import wiring lives in `sdk/core_module.zig` and is called from the app build *and* `sdk/plugin_sdk.zig`'s `exportModules` so the import set can't drift. Note the `with_tui = false` on the zf dependency: without it, zf's standalone terminal binary drags `libvaxis` into every plugin build.8081Acceptance test after any build-graph change:8283```sh84cd src/plugins/image && rm -rf .zig-cache zig-out zig-pkg && zig build -Doptimize=ReleaseFast85ls zig-pkg | grep -i velo # must be empty86```8788CI builds plugins for all 6 host targets by cross-compiling with `-Dtarget=` (see `fizzyedit/plugin-build-action`); pure-Zig + vendored-C plugins don't need per-arch runners.8990## When you need more than this file9192- Full plugin contract + lifecycle/hook tables → `docs/PLUGINS.md`93- Living reshape plan (identity `plugin.zig.zon`, comptime `settings.Schema`, ZON user config, no sidecars) → [`docs/PLUGIN_MANIFEST_PLAN.md`](docs/PLUGIN_MANIFEST_PLAN.md)94
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| fizzyedit/fizzy.cursor/rules/lang-plugins.mdc · 1.4k | Cursor rules | build | 65/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| stacklok/toolhiveCLAUDE.md · 2.0k | CLAUDE.md | buildteststylearch+4 | 100/100 | 14 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 46 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 14 days ago | |
| microsoft/playwrightCLAUDE.md · 95k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 7 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.5k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 14 days ago | |
| tphakala/birdnet-goCLAUDE.md · 1.6k | CLAUDE.md | buildtestlint-formatstyle+8 | 100/100 | today | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 14 days ago | |
| tyrchen/geektime-bootcamp-aiw7/genslides/backend/CLAUDE.md · 230 | CLAUDE.md | testlint-formatstylearch+6 | 100/100 | 9 days ago | |
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 7 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/fizzyedit-fizzy-claude)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.