@blit386/kit
v1.8.0
Published
Canonical BLIT386 AI docs (AGENTS.md + local docs) and the blit project CLI.
Maintainers
Readme
@blit386/kit
The kit behind BLIT386 game projects: the canonical AI/human docs plus the
blit helper CLI. You normally do not install this yourself -
create-blit386 adds it to a new game for you.
What's inside
The
blitCLI - a small helper you run inside a BLIT386 game:blit run- start the dev server and open the game.blit play- play-test the game from the terminal: open it in the Chrome or Edge already installed, run steps (hold keys, wait, read the game'stestState()orwindow.__game.state(), save frames), and print one JSON line per step. Needsplaywright-corein the game (an optional peer dependency; the command prints the line that adds it).blit doctor- check Node, git,.gitattributes, the installedblit386version against the range this kit was written for, kit-managed files that drifted (the same check asblit agents sync --check), and whether every set-up assistant has its docs-server config (it names the missing file and the assistants that need it).blit upgrade- updateblit386to the latest version, with a friendly nudge if your work is not under git. After a version change it checks your game for old API names and offers to update them for you (seeblit migrate).blit migrate- update old BLIT386 names in your game to the current ones, and (on blit386 1.4.0+) enable hot reload invite.configwhen it is missing. It previews the changes by default and only writes them when you add--write. Safe, unambiguous renames are applied; names that are too common to change automatically (likeequals) are listed for you or your AI assistant to handle.blit agents sync- refresh the AI-assistant files from the installed kit. It keeps your edits: kit-owned files you have not touched are updated in place, shared files (AGENTS.md,CLAUDE.md) get only their managed region rewritten, and a file you changed is three-way merged (or saved next to yours as<file>.new). If a newer kit ships a file at a path where you already keep your own (say, a skill with the same name), sync leaves yours alone and saves the kit version as<file>.new---forcedoes not override this; rename or remove your file and sync again to take the kit version. Use--checkto report drift without writing (CI-safe;blit doctorruns it too), or--force [path...]to take the kit version back. Once sync has merged your edits into a kit file,--checktreats that file as settled - it will not keep reporting it as drifted.blit agents add <claude|cursor|antigravity|codex|copilot|gemini|opencode|zed>- set up the files for one AI assistant in a game that did not pick it at the start. It writes the new files and records them soblit agents synckeeps them fresh. It never overwrites a file you already have; if one is in the way it saves the kit version next to it as<file>.new.blit clean- replacesrc/game.ts(orsrc/game.js) with an empty skeleton: the sameinit/update/rendershape, no drawing, no input handling, ready for your own code. No other project file is touched other than.blit/manifest.json's tracked hash for it, kept in step so later drift checks do not flag the skeleton as modified. Warns before replacing a file that no longer matches what was scaffolded, and always asks first - add--yesto skip the prompt.blit help- list the commands.
content/- everything a scaffolded project ships so a person or an AI assistant can learn the engine from inside the project: the canonicalAGENTS.mdanddocs/, the engine APIrules/, the game-authorskills/(listed below), and the agenthooks/plushooks.manifest.json. Claude/Cursor/Antigravity/Codex/Copilot/Gemini CLI/OpenCode/Zed file generation lives insrc/adapters.tsand is exported as@blit386/kit/adaptersso the scaffolder andblit agents sync/blit agents addshare one implementation; the paths it emits and their sync ownership classes are defined once insrc/ownership.ts. The same manifest drives Cursor's.cursor/hooks.jsonand Claude Code's.claude/settings.json(format-on-edit, which formats only the file that was edited, + block-dangerous-shell). Claude Code also gets a hook that blocks hand edits to lock files and.envfiles (Cursor has no pre-edit event), and a SessionStart hook that installs dependencies and runsblit doctorwhen a fresh remote/web session starts, so a scaffolded game works without manual setup; Cursor has no SessionStart-equivalent event, so it does not get this hook. Each adapter also emits a documentation-MCP config -.mcp.jsonfor Claude Code and Copilot (one shared file the Copilot CLI and VS Code both read, written once when both agents are set up),.cursor/mcp.jsonfor Cursor,.agents/mcp_config.jsonfor Antigravity, anmcpentry inopencode.jsonfor OpenCode, anmcpServersentry in.gemini/settings.jsonfor Gemini CLI, a[mcp_servers.blit386-docs]table in.codex/config.tomlfor Codex - registering theblit386-docsserver athttps://blit386.dev/mcpso an assistant can search the live docs. The Claude adapter pre-approves it in.claude/settings.json(enabledMcpjsonServers), so Claude Code does not prompt for it once the project folder is trusted. It also writes.claude/launch.json, which tells the Claude desktop app's built-in browser pane how to start the game (Vite on port 5173, through your package manager), so a preview needs no setup. That file is yours: the desktop app and other tools write into it, soblit agents syncandblit agents addcreate it only when it is missing and never change, merge, or--forcean existing one.Antigravity gets
.agents/hooks.jsonplus.agents/hooks/(format-on-edit, block-dangerous-shell, the lock-file /.envguard, and a bootstrap that installs dependencies and runsblit doctoronce per conversation, since Antigravity has no session-start event), all as thin fail-closed scripts over the shared guard core, and the shared.agents/skills/folder. It readsAGENTS.mdnatively. Antigravity ignores project config until you trust the workspace..agents/hooks.jsonis kit-owned like.claude/settings.json: your edits to it are kept, andblit agents syncsaves the kit version beside it as.agents/hooks.json.new.Gemini CLI gets
.gemini/settings.json(theAGENTS.mdpointercontext.fileName, the docs server underhttpUrl- Gemini readsurlas SSE - and the same four hooks in Gemini's dialect, timeouts in milliseconds) plus.gemini/hooks/. Gemini CLI ignores that file until you trust the folder, andblit agents add geminimerges into a.gemini/settings.jsonyou already have.OpenCode gets
opencode.jsonand.opencode/plugins/kit-guard.ts. OpenCode readsAGENTS.mdand the shared.agents/skills/folder by itself, so it needs no copy of either.opencode.jsonturns on the formatters (Biome for code and JSON, Prettier for Markdown and YAML, as in theformatscript) (OpenCode's formatters are off until enabled), denies edits to lock files and.envfiles (.env.examplestays editable) and destructive git commands, asks before a force push, and registers the docs server. The plugin asks the same guard core Claude Code's hooks use, and starts the dependency install andblit doctorwhen a session begins. OpenCode has no folder trust prompt, so project plugins run on open - the plugin's header comment lists everything it does. You can extendopencode.json:blit agents add opencodemerges the kit's entries into yours, andblit agents syncthree-way merges your edits.Codex gets
.codex/hooks.json,.codex/config.toml, and.codex/hooks/, and readsAGENTS.mdand the shared.agents/skills/folder by itself. The hooks are the same four (the lock-file /.envguard and block-dangerous-shell as thin fail-closed scripts over the guard core, format-on-edit, and the session-start bootstrap). Codex sends an edit as rawapply_patchtext, so the guard core parses the file paths out of the patch, and each hook command finds the project from the session's directory, since Codex runs hooks there with no project variable. Codex has no ask answer, so the confirm-tier git commands are refused outright.config.tomlis one[mcp_servers.blit386-docs]table: you can add your own settings around it,blit agents add codexappends the table to aconfig.tomlyou already have, andblit agents syncthree-way merges your edits. Codex ignores.codex/until you trust the project, and then runs each project hook only after you approve it in/hooks(again whenever a kit update changes it). No.codex/rules/(experimental, and one bad rules file switches off every rule) and no.codex/environments/(undocumented schema).GitHub Copilot gets
.github/hooks/blit.jsonplus its scripts in.github/hooks/,.github/workflows/copilot-setup-steps.yml, and the root.mcp.json(shared with Claude Code; the Copilot CLI and VS Code both read it, so there is no.vscode/mcp.jsonto register the server a second time), and readsAGENTS.mdand the shared.agents/skills/folder by itself. The hooks file is the one every Copilot surface loads - the CLI, the cloud agent, and VS Code - with the same four hooks, all run by one Node script,copilot-hook.cjs, so they work under PowerShell on Windows too: the lock-file /.envguard and block-dangerous-shell (fail-closed, over the guard core), format-on-edit (only for the tools that edit files), and the session-start bootstrap. The script reads both thetoolName/toolArgspayload of the CLI and VS Code's Copilot harness and thetool_name/tool_inputpayload of VS Code's older Local harness. The setup-steps workflow installs Node and the game's dependencies in the cloud agent's sandbox. The cloud agent cannot read an MCP server from the project, so the docs server has to be added in the repository's Copilot settings there. Copilot ignores the hooks and the MCP configs until you trust the folder. No.github/prompts/(prompt files are deprecated, and VS Code's Copilot harness does not load them), and nochat.tools.*.autoApprovesettings (they only prompt, so they enforce nothing).
What each assistant gets
Every game gets AGENTS.md and docs/ from the scaffolder, whatever assistants it picks. On top of that, per assistant
(the registry is AGENT_SPECS in src/ownership.ts; the generators are AGENT_ADAPTERS in src/adapters.ts):
| Assistant | Persona and rules | Skills | Hooks and guards | Docs MCP config |
| --- | --- | --- | --- | --- |
| Claude Code | CLAUDE.md (managed region), .claude/rules/*.md | .claude/skills/ | .claude/settings.json + .claude/hooks/: format-on-edit, shell guard, lock-file / .env guard, session-start bootstrap; .claude/launch.json (yours, written once) | .mcp.json (shared with Copilot), pre-approved in settings.json |
| Cursor | .cursor/rules/*.mdc | .cursor/skills/ | .cursor/hooks.json + .cursor/hooks/: format-on-edit, shell guard (no pre-edit or session-start event) | .cursor/mcp.json |
| Antigravity | AGENTS.md | .agents/skills/ (shared) | .agents/hooks.json + .agents/hooks/: all four, the bootstrap once per conversation | .agents/mcp_config.json |
| Codex | AGENTS.md | .agents/skills/ (shared) | .codex/hooks.json + .codex/hooks/: all four; confirm-tier git commands are refused outright | .codex/config.toml |
| GitHub Copilot | AGENTS.md | .agents/skills/ (shared) | .github/hooks/blit.json + .github/hooks/: all four through copilot-hook.cjs; .github/workflows/copilot-setup-steps.yml | .mcp.json (shared with Claude Code) |
| Gemini CLI | AGENTS.md (context.fileName) | .agents/skills/ (shared) | .gemini/settings.json + .gemini/hooks/: all four; confirm-tier git commands are refused outright | .gemini/settings.json |
| OpenCode | AGENTS.md | .agents/skills/ (shared) | .opencode/plugins/kit-guard.ts + .opencode/hooks/: shell guard, file guard, session-start bootstrap; opencode.json restates the guards as permissions and turns the formatters on | opencode.json |
| Zed | AGENTS.md (hard rules as a paste-in snippet for your own settings) | .agents/skills/ (shared) | none - format on save in .zed/settings.json | .zed/settings.json |
"All four" is the manifest's set: format-on-edit, block-dangerous-shell, the lock-file / .env guard, and the
session-start bootstrap. Every guard is a thin entry over one shared guard-core.cjs, so the deny list (a hard reset,
checkout --, a restore onto the worktree, clean) and the ask list (force push, branch -D, stash drop/clear)
are the same in every assistant that can enforce them.
The game-author skills
Every scaffolded game gets these. Your AI assistant loads one on its own when the task calls for it - you do not have to
name them. In Claude Code they live in .claude/skills/<name>/SKILL.md. In Cursor they live in
.cursor/skills/<name>/SKILL.md, with the same name and description, so Cursor loads one on its own too, and you can
still invoke one by name (/add-sprite). A game set up for several assistants ships each one's copy. Cursor also reads
.claude/skills/, so the same skill can show up twice there; both copies are the same text. Antigravity, Codex, GitHub
Copilot, Gemini CLI, OpenCode, Zed (and most other assistants) read one shared folder, .agents/skills/<name>/SKILL.md,
which the kit writes once whenever such an assistant is set up.
Zed gets .zed/settings.json (format on save, Biome as the JavaScript, TypeScript, and JSON formatter, and the
blit386-docs MCP server), merged with any settings you already have. Zed's agent cannot take guardrails from project
files, so the hard rules live in AGENTS.md as instructions, with a snippet to paste into your own Zed settings for
real enforcement. Zed ignores .zed/ until you trust the project, and the Biome formatter needs the Biome extension.
| Skill | What it is for |
| --- | --- |
| structure-a-game | The shape of a game: configure, init, update, render - and what the engine does not do for you |
| run | Start the dev server and see the game |
| fix | The game crashes, shows a black screen, or behaves oddly |
| test-the-game | Play-test the game in a browser: fixed seeds, key presses, and reading the game state |
| ask-the-docs | Look something up that the local docs/ folder does not cover, using the live docs at blit386.dev |
| use-hot-reload | Keep playing while you edit code or assets (blit386/vite, onHotReload) |
| use-dev-mode | Gate debug HUDs, cheat keys, and verbose logging on BT.isDevMode |
| draw-shapes | Rectangles, lines, pixels, and clearing the screen |
| add-sprite | Load a PNG sprite sheet and draw it, whole or frame by frame |
| draw-a-panel | Panels, dialog boxes, buttons, and bars of any size from one small piece of art, with a nine-slice |
| show-a-loading-screen | Wait for sprites and audio with BT.loadingAssetsCount |
| add-text | Scores, labels, and titles with the built-in or a bitmap font |
| use-palette | Set up colors as numbered palette slots |
| animate-the-palette | Cycle, fade, flash, and swap colors for motion and mood |
| move-and-time | The frame clock, timers, cooldowns, easing curves, and interpolate |
| use-random | Dice, picks, shuffles, weighted drops, and seeds that replay the same game |
| use-noise | Terrain, caves, clouds, and procedural textures from noise and coordinate hashing |
| smooth-the-motion | Make movement look smooth instead of stepped, with BT.renderAlpha |
| scroll-with-camera | Scroll a world bigger than the screen, clamped to its bounds |
| read-keyboard | Keys, face buttons, typed text, and remapping |
| read-pointer | Mouse, touch, and pen, up to four at once |
| read-gamepad | Controllers: buttons, sticks, and triggers |
| play-a-sound | Sound effects, music, volume, and why a game starts silent |
| design-a-sound | Build a custom sound from scratch when the presets are not right |
| add-crt-effect | Fullscreen post-process effects: CRT, scanlines, bloom, glitch (WebGPU only) |
| show-debug-overlay | FPS, timings, your own values, the palette grid, audio volume meters, and renderer diagnostics |
| keep-it-fast | The game stutters, drops frames, or sprites start vanishing |
| save-a-screenshot | Capture the frame as a PNG |
| share-the-game | Build it and put it online for other people to play |
| migrate | Update the game's code after a BLIT386 upgrade (renames + enable hot reload) |
Usage
Inside a project created by create-blit386:
npx blit run
npx blit play --help
npx blit doctor
npx blit upgrade
npx blit migrate
npx blit migrate --write
npx blit agents sync
npx blit agents add cursor
npx blit agents add antigravity
npx blit agents add codex
npx blit agents add copilot
npx blit agents add gemini
npx blit agents add opencode
npx blit agents add zed
npx blit clean
npx blit clean --yes
npx blit helpRequirements
- Node.js 22.18.0 or newer.
Versions
@blit386/kit, create-blit386, and the blit386 engine share one version number and release together. The kit's
package.json carries two extra fields under blit386: engineRange is the engine range these guides and skills
describe (blit doctor compares it with the blit386 you have installed and tells you when to update the kit or the
engine), and docsReviewedAt is the engine version the docs/ pages were last reviewed against. A game pins the kit
and the engine it was scaffolded with; blit upgrade moves the engine, and a newer kit arrives like any other
dependency update, followed by npx blit agents sync to refresh the generated files.
Learn more
- Docs: blit386.dev
- Source: packages/kit
- Issues: github.com/blit386/blit386/issues
Community
License
ISC. Copyright (c) Václav Vančura. See LICENSE.
