AI agents ship code faster than any programmer can keep up with, and the code decays faster than anyone can refactor it. nit is a vim-keyed TUI that watches every edit an agent makes and runs it through Conway's Game of Life as a fitness function for scoring. Code that scores well propagates and survives, but code that scores badly dies out. It is experimental because as of now, we do not quite know whether GoL is indeed a better quality measure for code written by everyone, not just agents.
macOS, Linux, WSL:
curl -fsSL https://download.nit.tools/install.sh | bashWindows (PowerShell):
irm https://download.nit.tools/install.ps1 | iexIf PowerShell's execution policy blocks it (rare on default Windows installs but common on managed/corporate machines), prefix with Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force; — the bypass is scoped to the current PowerShell process and never touches system-wide settings.
Homebrew (macOS / Linux):
brew install asheux/tap/nitFrom source:
git clone https://github.com/asheux/nit.git &&cd nitBinaries land at target/release/{nit, nit-mcp-server}
cargo build --releaseUpgrade (any platform, any install method):
nit updateDetects whether nit was installed via Homebrew or one of the install scripts and runs the right upgrade command (Homebrew users get brew upgrade asheux/tap/nit; others get install.sh; Windows prints the PowerShell snippet to run from a fresh PS session, since a running .exe can't replace itself in place). On launch, nit also prompts you with [i]nstall / [s]kip / [m]ute if a newer release is available — silenceable via NIT_NO_VERSION_CHECK=1.
Binaries are distributed via https://download.nit.tools/<tag>/, with a SHA256SUMS file per release for checksum verification.
| OS | Architecture | Distribution |
|---|---|---|
| macOS | arm64 + x86_64 (universal) | install.sh, Homebrew, direct tarball |
| Linux | x86_64 (glibc) | install.sh, Homebrew, direct tarball |
| Windows | x86_64 (MSVC) | install.ps1, direct zip |
The macOS asset is a single universal Mach-O binary — Apple Silicon and Intel Macs both run native code from the same file (no Rosetta needed).
nit requires external CLIs (codex, claude, git) on PATH to drive its agent runners.
macOS — "nit cannot be opened because the developer cannot be verified": The downloaded binary isn't signed/notarized yet. Clear the quarantine attribute:
xattr -d com.apple.quarantine ~/.nit/bin/nit ~/.nit/bin/nit-mcp-serverThis is only needed once per install and only triggers on machines where the binary went through a browser download (the curl | bash flow usually skips it).
nit not found after install:
The installer doesn't auto-modify your shell config; it prints a PATH hint at the end. Either start a new shell session after adding the export line, or run with the absolute path: ~/.nit/bin/nit --version.
nit path/to/filenit gamesnit multipanenit <file>opens the file in the editor.nit <dir>sets the workspace root (opens an untitled buffer).nitdefaults to the current directory and an untitled buffer.nit gol [path]explicitly launches GoL mode.nit games [path]launches Games mode (tournaments between programs).nit multipane [--backend <model>] [--panes N] [--cwd PATH]opens a grid of independent chat panes.
just fmtjust clippyjust testjust run -- path/to/fileFull CI gates (fmt-check + clippy + test + cargo deny):
just ciQuick repo-health preflight (add --deep to include clippy + tests):
scripts/healthcheck.sh
scripts/healthcheck.sh --deep- Rust 1.88.0 (pinned via
rust-toolchain.toml) - ratatui + crossterm for UI/input
- ropey, unicode-segmentation, unicode-width for text correctness
- tree-sitter 0.25 for syntax highlighting (29 active grammars; the workspace's language registry — extensions, filenames, shebangs, injection aliases,
is_codeflag — lives incrates/nit-core/src/languages.rs) and AST-based seed encoders
Cargo.lockis checked in; CI uses--locked.timeis patched to a vendored copy atvendor/time(seeCargo.toml).
Contributions are welcome — bug reports, feature ideas, new tree-sitter grammars, Game of Life rules, documentation, and code.
- Fork the repo and branch off
main. - Validate locally before opening a PR — all gates must pass (clippy runs with
-D warnings):
just ci- Keep changes focused, match the surrounding style, add tests for new behaviour, and run
just fmtbefore committing. - Open a pull request against
mainwith a clear description of the change and its motivation; CI must be green before review.
Good first contributions: new language grammars / highlight queries (crates/nit-syntax/), Game of Life rule presets (docs/RULES.md), and documentation fixes. For larger or architectural changes, open an issue first to discuss the approach — see docs/ARCHITECTURE.md and the subsystem guides under docs/.
nit/
├─ crates/
│ ├─ nit/ CLI binary entry point (args, agent discovery, lab dispatch)
│ │ └─ src/
│ │ ├─ agents/ Backend discovery (Claude, Codex, Gemini, discover)
│ │ ├─ cli/ clap subcommands + arg enums (lab, agents, codex, games)
│ │ ├─ games/ Headless games CLI (run, sweep, enumerate, inspect, graph)
│ │ ├─ graph/ Strategy graph export (DOT / JSON)
│ │ ├─ logging/ Tracing init + panic hook + log-path resolution
│ │ ├─ workspace/ Workspace target resolution + notes loading
│ │ ├─ bootstrap.rs Runner config assembly, lab dispatch
│ │ ├─ multipane_setup.rs Multipane launch wiring
│ │ └─ main.rs Entry point + dispatch
│ ├─ nit-core/ Pure state + protocol layer (no terminal deps)
│ │ └─ src/
│ │ ├─ agent_bus/ `AgentBusEvent` enum + state-mutation helpers
│ │ ├─ arbiters/ Substrate arbiters (escalate, intervene)
│ │ ├─ buffer/ Rope-backed text buffer + diff/edit
│ │ ├─ config/ Settings + TOML loaders (editor, highlight, gol, swarm, genome)
│ │ ├─ genome_report/ Code-as-genome tier scoring, parsimony, recommendations
│ │ ├─ genome_storage/ Disk-backed report cache (sharded, atomic writes)
│ │ ├─ mission_memory/ Cross-mission retrieval index
│ │ ├─ observers/ Substrate observers (pattern detectors)
│ │ ├─ rule_protocol/ Rule protocol types (GoL B/S, presets)
│ │ ├─ seed/ GoL seed encoders (token_spectrum, ast_structure,
│ │ │ complexity, structural, ascii, hilbert, lifehash)
│ │ ├─ state/ AppState, AgentsState, MultipaneState, GamesState,
│ │ │ VisualizerState, etc.
│ │ ├─ substrate/ Signals, claims, assumptions, mood
│ │ └─ tests/ Core unit tests
│ ├─ nit-tui/ TUI app loop, widgets, agent runners, swarm + multipane
│ │ └─ src/
│ │ ├─ app/ Main event loop, key/mouse dispatch, chat input,
│ │ │ runner, draw, terminal, scroll, popups
│ │ ├─ codex_runner/ Codex backend (MCP + exec runtime, JSON-RPC)
│ │ ├─ multipane/ Multipane grid (dispatch, dir search, persistence)
│ │ ├─ swarm/ Swarm orchestrator (DAG planning/execution, gates,
│ │ │ plan parser, dashboard, prompts, workers, scope)
│ │ ├─ widgets/ All TUI widgets (agent ops, gate monitor, artifacts,
│ │ │ file tree, top/bottom bar, popups, ...)
│ │ ├─ gol_render/ Game of Life rendering
│ │ ├─ seed_render/ Genome seed visualization
│ │ ├─ workspace_scan/ Background workspace scanner
│ │ ├─ claude_runner.rs Claude CLI subprocess runtime (`claude -p`)
│ │ ├─ claude_pool.rs Warm worker pool (`NIT_CLAUDE_POOL=1`)
│ │ ├─ intake.rs Hidden intent classifier (Claude-class only)
│ │ ├─ shadow.rs Shadow agents (propose-a/-b → judge → review)
│ │ ├─ seed_runtime.rs Seed compute worker + change detection
│ │ ├─ genome_worker.rs Off-thread genome evaluation
│ │ ├─ mcp_backchannel.rs Unix-domain socket for spawned `codex mcp-server`
│ │ ├─ vitals.rs / system_stats.rs / power.rs Process vitals + ECG
│ │ └─ ... (file_watcher, fuzzy_*_runner, syntax, layout, ...)
│ ├─ nit-mcp/ MCP stdio JSON-RPC server (`nit-mcp-server` binary)
│ │ — bridges spawned `codex` back into substrate tools
│ │ (`emit_signal`, `assert_claim`, `assert_assumption`)
│ ├─ nit-games/ Game theory tournament engine
│ │ └─ src/
│ │ ├─ analysis/ History-log analysis (per-match, per-strategy, trajectories)
│ │ ├─ config/ Config parsing, normalization, payoff matrices
│ │ ├─ fsm_enum/ FSM enumeration + canonicalization
│ │ ├─ strategy/ Strategy codecs (FSM, CA, one-sided TM)
│ │ ├─ tournament/ Match execution, accumulation, Metal batching, halting filter
│ │ ├─ fast_eval.rs Analytical evaluator (cycle detection on deterministic FSM)
│ │ ├─ introspection.rs Strategy introspection / export
│ │ └─ history.rs / history_log.rs / events.rs / output.rs / ndjson.rs
│ ├─ nit-gol/ Conway's Game of Life engine
│ │ └─ src/ Grid, step, rules, hashing, attractor detection,
│ │ snapshot manager, catalog
│ ├─ nit-metal/ Metal GPU acceleration (macOS)
│ │ └─ src/
│ │ ├─ macos/ Device, dispatch, shader, policy, cache
│ │ └─ stubs.rs No-op stubs for non-macOS platforms
│ ├─ nit-syntax/ Tree-sitter syntax highlighting (registry derives
│ │ │ from `nit-core::languages::LANGUAGES`; only the
│ │ │ per-grammar `tree_sitter_<lang>` arms in
│ │ │ `language/grammars.rs` live here)
│ │ ├─ src/ Engine, registry, captures, debounce
│ │ └─ queries/ Tree-sitter highlight queries per language
│ └─ nit-utils/ Shared filesystem, hashing, path utilities
├─ docs/ Architecture, swarm, substrate, multipane, intake,
│ shadows, seeds, games, keybindings, security, ...
├─ vendor/ Vendored dependencies (`time` crate)
├─ scripts/ Build and CI helpers (`healthcheck.sh`)
└─ assets/ Static assets
- No plugins.
- No network calls from
nititself. - No arbitrary command execution;
nitmay invokegit,codex,claude, and the platform URL launcher (open/xdg-open/cmd) directly (no shell). At startup,codex,claude, andgeminiare probed for model detection. #![forbid(unsafe_code)]across all crates exceptnit-metal(Metal GPU interop).- Atomic file writes.
- Terminal restored on exit and panic.
For details see docs/SECURITY.md.
nit includes an Agent Station UI (Agent Ops + Agent Chat) with multiple backends: Codex (MCP or exec runtime), Claude (subprocess per turn, optional warm worker pool), and a local mock lane. Gemini models are detected at startup but display-only (no runtime runner yet).
- Default: seeds all available lanes (Codex, Claude, and Gemini models when detected on
PATH). nit --agents local(alias:mock) — force local lane only.nit --agents codex— force Codex only (loads a model roster from~/.codex/models_cache.json).nit --agents claude— force Claude only (probesclaude models --jsonfor available models).nit --agents all— include all available lanes.- Codex runtime knobs:
--codex-runtime <mcp|exec>(default:mcp— runs a persistentcodex mcp-server;execspawnscodex execper turn).--codex-sandbox <read-only|workspace-write|danger-full-access>(default: Codex config).--codex-approval-policy <untrusted|on-failure|on-request|never>(default:never).--codex-max-parallel-turns <N>(alias--codex-parallel; default8, range1..=16). Shared cap across Codex and Claude.
@all <prompt>— fan-out to multiple agents (Codex and Claude).@swarm [all|N] [template=lab|parallel|bulk] [mission=general|research|computational-research] <prompt>— orchestrated multi-agent workflow (plan → DAG tasks → verify → synthesis).labis the default template. Seedocs/SWARM.md.@shadow <prompt>— single-agent dispatch with hidden propose-a / propose-b → judge → review pipeline; auto-enables for heavy prompts (>500 chars or keywords likerefactor,rewrite,implement). Seedocs/SHADOWS.md.@new <prompt>— spawn a fresh-context clone when the agent is busy.@queue/@q <prompt>— explicit queue (same as the implicit queueing below)./abort(or@abort) — cancel the active swarm mission./abort allcancels every running swarm;/abort <agent-id>is a surgical strike on one agent.- Prompts sent while an agent is busy are automatically queued and dispatched when the agent becomes idle.
In front of every Claude-class dispatch, a hidden intake agent classifies the operator's intent and appends a file checklist for write/mixed prompts.
As a prompt augmentation strategy. Disable with intake_enabled = false in config.toml or NIT_INTAKE_DISABLED=1 for a runtime kill switch. See docs/INTAKE.md.
Examples:
Load all available lanes (default)
nitForce Codex agent station
nit --agents codexForce Claude-only agent station with the warm worker pool
NIT_CLAUDE_POOL=1 nit --agents claudeForce Codex agent station, per-turn codex exec
nit --agents codex --codex-runtime execForce local-only agent station
nit --agents localMultipane: 8 panes, full roster picker per pane
nit multipaneMultipane: 4 panes pre-picked to a specific Claude lane
nit multipane --backend claude-haiku-4-5 --panes 4From source
cargo run -p nit -- --agents codexdocs/ARCHITECTURE.md— module layout, state model, agent system, swarm orchestration, runtime modes.docs/KEYBINDINGS.md— full keymap and:command reference (editor, agent ops, multipane).docs/SWARM.md— swarm orchestration operator guide (templates, roles, DAG, gates, custom gates, abort).docs/SHADOWS.md— shadow agents (propose-a/-b → judge → review behind a single agent).docs/INTAKE.md— intake preprocessor (hidden Claude-class intent classifier).docs/MULTIPANE.md— multipane grid mode (per-pane cwd, dir search, persistence).docs/TERMINAL.md— embedded OS shell (agent-chat tab, modal popup, per multipane pane) with selection/copy + scrollback.docs/SUBSTRATE.md— stigmergic substrate (signals, claims, assumptions, metabolism, mood).docs/SUBSTRATE_TESTING.md— substrate testing recipes + concrete verification steps.docs/LIVING_SYSTEM.md— coordination role roster (worker / observer / arbiter / resolver).docs/GAMES.md— games engine (strategies, config, headless CLI, analysis, Metal accelerator).docs/SEEDS.md— code-as-genome seed encoders, parsimony rule, retry guardrails.docs/RULES.md— Game of Life rule catalog and contribution guide.docs/SMOKE_TEST.md— feature tour + manual smoke checklist.docs/PERF.md— TUI render budget, games benchmarks, and flamegraphs.docs/ENVIRONMENT.md— runtime environment variables and tuning knobs.docs/SECURITY.md— security policy, protections, and hardening backlog.docs/REPO_HEALTH.md— snapshot of the last repo-health audit (fmt/clippy/tests/deny).
Open the command prompt with : in Normal mode (or press F1 / ? for the full help overlay). Commands are routed to the active lab; start nit with --lab gol|games to switch.
:q— quit (confirm if dirty):help/:commands— open the help overlay:run— run the active app (GoL Petri Dish or Games tournament):gol run|hide|show|stop|rule|rules|encoder|seed— GoL controls (aliases::petri,:life):games run|hide|show|stop|status|runs|replay|inspect|tm|ca|analyze|strategy— Games controls
Full command and keybinding reference: docs/KEYBINDINGS.md.
- Run Petri Dish:
Ctrl+Enter; show hidden:Ctrl+^ - Petri Dish popup:
Spacepause,Enterstep,+/-speed,Hhide,Ssnapshot,F2rule picker,Pprotocol picker,Grule search,Aapply best rule - Visualizer seed controls:
Ctrl+Eencoder,Ctrl+Ssymmetry,Ctrl+Vview,Ctrl+Rcycle seed view,Ctrl+Mplate render,Ctrl+Yseed source,Ctrl+Gsearch,Ctrl+Aapply,Ctrl+Nsnapshot - Seed encoders: 7 encoders (byte-level, hybrid, AST-driven) that turn the open buffer into a Game of Life genome. See
docs/SEEDS.md. - Rule selection: 28-rule built-in catalog (
crates/nit-gol/assets/rules.toml), custom B/S input, user overlay (~/.config/nit/rules.toml). Seedocs/RULES.md. - Snapshots land in
gol-snapshots/(async, bounded, deduped).
- Launch:
nit games [path](opensgames.tomlby default). - Run tournament:
Ctrl+Enteror:games run; hide/show:H/Ctrl+^. - Outputs land in
runs/games/under the workspace root. - Optional Metal GPU acceleration on macOS (
engine.accelerator = "auto" | "cpu" | "metal"ingames.toml). - Headless CLI:
nit games {run | sweep | enumerate fsm | inspect | graph}— seedocs/GAMES.md.
For strategy types (FSM, CA, one-sided TM), config format (payoff, history, scoring, engine), headless CLI, and analysis: see docs/GAMES.md.
nit multipane [--backend <model>] [--panes N] [--cwd PATH] opens a grid of N independent chat panes (default 8, range 1..=32), each anchored at its own working directory. --backend is optional: omit for a per-pane roster picker, name a family (claude / codex / gemini / local) to filter the per-pane roster, or name a specific lane id to pre-pick every pane. Per-pane sessions persist to <state_dir>/multipane/session-<workspace-hash>.json.
Per-pane keymap (focus cycling, dir-search, roster revert, focused-pane abort) lives in docs/KEYBINDINGS.md "Multipane mode"; docs/MULTIPANE.md has the full spec.
- Horizontal scrolling uses character columns; tabs before the viewport can shift alignment.
- Syntax highlighting covers 29 languages (the canonical list lives in
crates/nit-core/src/languages.rs) and falls back to plain text for the rest or for very large files. - Dockerfile detection is wired (it's an entry in the central
LANGUAGEStable) but the grammar crate is pinned to an older tree-sitter ABI; renders as plain text until upstream catches up. - Gemini models appear in the roster but are display-only (no runtime runner).
MIT © 2026 nit contributors

