Skip to content

grosa787/localcode

Repository files navigation

🌙 LocalCode

A local-first, Claude-Code-class AI coding assistant for your terminal — and your browser.

Website · English · Русский

Bun ≥ 1.1 TypeScript strict License MIT Tests 3196 passing Local-first


What is LocalCode?

LocalCode is a terminal + web AI pair-programming assistant. It speaks to any LLM (local or cloud), gives the model a curated toolbox (read/write files, run commands, browse the web, view images, manage Jupyter notebooks, etc.), keeps everything you do in a local SQLite session store, and ships extensive controls so the assistant is fast, safe, and inspectable.

Built on Bun + ink (TUI) + Vite/React (Web). Single statically-compiled binary, no Electron, no cloud calls unless you opt in.

localcode                            # terminal UI (default)
localcode --web                      # browser UI (opens automatically)

Table of contents


Highlights

  • Bring your own LLM — Ollama, LM Studio, OpenAI, Anthropic, OpenRouter, Google Gemini, and any OpenAI-compatible URL (Groq, Together, Fireworks, Mistral, vLLM, llama.cpp…). One UI, seven backends.
  • Two surfaces, same brain — gorgeous ink TUI and a polished web UI (tabs, dock, voice in/out, drag-drop, PDF, whiteboard).
  • Real tool calling with approval gates — diff previews, command previews, per-tool auto-approve, five permission profiles (default, acceptEdits, plan, dontAsk, bypassPermissions).
  • Sub-agents on-demand — spawn specialist workers (architect, debugger, security-reviewer, language reviewers, etc.) from a curated catalog. Switch between them, send extra context, see live progress.
  • Memory — persistent file-based per-project memory (user / feedback / project / reference) injected into every system prompt.
  • Hooks — shell scripts at PreToolUse / PostToolUse / UserPromptSubmit / SessionStart / Stop / PreCompact / SessionEnd.
  • MCP support — Model Context Protocol over stdio or http; tools auto-namespaced as mcp__<server>__<tool>.
  • Cost tracking — per-message cost chip using real OpenRouter / static pricing. /usage dashboard, /cost per-session, token visualizer with sparklines.
  • Smart inputs — paste an image path → auto-attached as multimodal. Drag-drop files in the web. Voice in/out via Web Speech API. PDF parsing.
  • Diagnostics + recovery — process introspection (/watch <cmd> + /diagnose), conversation branching, /undo, full diff viewer, health watchdog, error banner with retry.
  • Codebase ontology — TypeScript LSP-powered knowledge graph; new tools find_call_sites, impacts_of, type_hierarchy.
  • Architecture rules — declare layering rules in .localcode/arch.toml; PreToolUse validator blocks forbidden imports.
  • Built-in security — secret scanner pre-commit hook (AWS / GitHub / OpenAI / Anthropic / Stripe / private-key patterns + entropy heuristic), sensitive-files gating, redaction.
  • LAN sharing — mDNS discovery + HMAC pairing + AES-GCM session sync; share a session with a colleague on the same network without any cloud round-trip.
  • Multi-user web — two browser tabs on the same session see each other's messages live, with typing presence and colored peer dots.
  • Sandboxed run_command — every shell command runs through sandbox-exec (macOS), firejail (Linux), or Docker — fully configurable per-platform.
  • Plan mode — visible 🔒 banner + Ctrl+P hotkey; write & run tools blocked so the model can plan before touching anything.
  • Batch approval — when the model emits 3+ mutating tool calls, a single 2-pane dialog reviews them all at once.
  • Crash journal + resume — synchronous JSONL per chunk; on next start, offer to resume any session interrupted by SIGKILL / power loss.
  • Cost forecast~$0.02 next turn chip before sending; cumulative session + today totals in the footer.
  • Smarter context compression — semantic dedup of repeated read_file results, write/run preserved verbatim, middle summarised via a cheap model.
  • Image paste TUI — Ctrl+V pastes the clipboard image straight into the conversation (mac / linux / win).
  • Skill auto-suggest — when your message matches a skill's triggers regex, a toast offers Tab-to-activate.
  • Marketplace browse/skills browse (anthropics/skills) and /mcp browse (modelcontextprotocol/servers) install with one keypress.
  • Migration from Claude Code/import claude-code imports your ~/.claude/projects/*/ history into the local SQLite.
  • /metrics dashboard — opt-in tool success rate, cache hit %, cost per model, top expensive sessions — all local.
  • i18n — full UI in English and Russian, switchable live; all 6 main overlays fully translated.

Supported providers

Provider Type Setup
Ollama Local Install Ollama, run ollama serve
LM Studio Local Install LM Studio, enable the local server
OpenAI Cloud API key via OPENAI_API_KEY or /provider
Anthropic Cloud API key via ANTHROPIC_API_KEY or /provider
OpenRouter Cloud API key via OPENROUTER_API_KEY or /provider
Google Gemini Cloud API key via GEMINI_API_KEY or /provider
Custom Cloud Any OpenAI-compatible base URL (Groq, Together, Fireworks, Mistral, …)

Explicit apiKey in ~/.localcode/config.toml wins; environment variables are the fallback. See docs/PROVIDERS.md for per-provider examples.


Requirements

  • Bun ≥ 1.1 — runtime, package manager, and bundler.
  • macOS or Linux. Windows is supported via WSL.
  • At least one reachable LLM backend (local server or cloud API key).

Install

Pick whichever channel fits your platform — all paths land at the same binary.

Debian / Ubuntu (.deb)

VER=0.20.0
curl -fsSL -o localcode.deb \
  https://github.com/grosa787/localcode/releases/download/v${VER}/localcode_${VER}_amd64.deb
sudo dpkg -i localcode.deb
# arm64: replace amd64 with arm64 in the URL above.

Fedora / RHEL (.rpm)

VER=0.20.0
sudo dnf install \
  https://github.com/grosa787/localcode/releases/download/v${VER}/localcode-${VER}-1.x86_64.rpm
# arm64: replace x86_64 with aarch64.

Homebrew (macOS & Linux)

brew install grosa787/tap/localcode

Auto-resolves the right prebuilt binary for darwin-arm64, darwin-x64, linux-arm64, or linux-x64. Upgrade later with brew upgrade localcode. See docs/HOMEBREW.md for tap-bootstrap and maintainer setup details.

Scoop (Windows)

scoop bucket add localcode https://github.com/grosa787/scoop-bucket
scoop install localcode

See docs/SCOOP.md for bucket-bootstrap and maintainer setup.

One-command install script

# Claude-Code-style installer (clones + builds with Bun)
curl -fsSL https://raw.githubusercontent.com/grosa787/localcode/main/install.sh | bash

# Or pin a version / branch / tag
curl -fsSL https://raw.githubusercontent.com/grosa787/localcode/main/install.sh | LOCALCODE_REF=v0.19.0 bash

The installer detects your OS/arch, installs Bun if missing (via the official bun.sh/install), clones LocalCode into ~/.local/share/localcode, runs bun install && bun run build, and symlinks dist/cli.js. It prefers ~/.local/bin (no sudo); only if that directory isn't writable does it fall back to /usr/local/bin with sudo. Re-running the same command updates an existing install.

Flags & env overrides:

curl -fsSL .../install.sh | bash -s -- --update      # git pull + rebuild
curl -fsSL .../install.sh | bash -s -- --uninstall   # remove symlink + install dir
curl -fsSL .../install.sh | bash -s -- --verbose     # debug output
LOCALCODE_HOME=/opt/localcode bash install.sh        # custom install dir
LOCALCODE_BIN_DIR=$HOME/bin bash install.sh          # custom PATH dir

Manual install (existing clone):

git clone https://github.com/grosa787/localcode.git
cd localcode
./install.sh

To run without installing:

bun install
bun run dev          # alias for: bun run src/cli.tsx

Docker

LocalCode ships as a multi-arch image (linux/amd64 + linux/arm64) to GitHub Container Registry: ghcr.io/grosa787/localcode. Tags: latest, vX.Y.Z, and X.Y.Z per release.

# TUI (needs an interactive TTY)
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -v "$HOME/.localcode:/root/.localcode" \
  -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
  ghcr.io/grosa787/localcode:latest

# Web UI (port-mapped, no TTY)
docker run --rm -p 7777:7777 \
  -v "$(pwd):/workspace" \
  -v "$HOME/.localcode:/root/.localcode" \
  -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
  ghcr.io/grosa787/localcode:latest \
  --web --web-host 0.0.0.0 --no-open

For local backends (Ollama / LM Studio) running on the host, use host.docker.internal (Docker Desktop) or add --add-host=host.docker.internal:host-gateway on Linux. Full usage, auth, persistence, and compose recipes: docs/DOCKER.md.


Quick start

localcode                            # open the current directory
localcode ~/path/to/project          # open a specific project
localcode --resume ab12cd34          # resume a session by id prefix
localcode --model claude-3-5-sonnet  # override the model
localcode --profile plan             # start in Plan Mode (no mutations)
localcode --web                      # browser UI
localcode --help                     # full flag list
localcode --version

First launch triggers onboarding: pick a backend, confirm the URL, choose a model, and you're in the chat.


CLI flags

localcode [projectRoot] [flags]
Flag What it does
[projectRoot] Positional. Path to the project. Defaults to process.cwd().
--profile <name> Permission profile: default · acceptEdits · plan · dontAsk · bypassPermissions. Overrides persisted config.
--dangerously-allow-all DEPRECATED. Equivalent to --profile dontAsk. Skips approvals.
--resume <sessionId> Resume a session. Accepts full UUID or sufficiently-unique prefix.
--model <name> Override the active model for this run only (does NOT modify persisted config).
--reconfigure Re-run onboarding, overwriting config.
--no-refresh-models Skip startup model-list refresh.
--web Launch the browser-based UI instead of the terminal.
--web-host <host> Bind host for --web. Default 127.0.0.1. Pass 0.0.0.0 to expose on the LAN.
--web-port <port> First port to try for --web. Default 7777. Probes subsequent ports if busy.
--no-open Do not auto-open the browser when --web starts. URL still printed to stdout.
--lan Enable LAN P2P session sharing via mDNS (off by default).
--help, -h Show usage and exit.
--version, -v Print version and exit.

Subcommands

Subcommand Description
localcode plugin <action> Manage plugins: install <path> · uninstall <id> · list · enable <id> · disable <id>
localcode daemon Run the persistent cron daemon (background scheduled wakeups).
localcode doctor [--json] Diagnose installation health: config, backend, models, disk, hooks, MCP, git.
localcode completion <sh> Print a shell-completion script (bash, zsh, fish) to stdout.
localcode demo Replay a short bundled tour that demonstrates what LocalCode can do.
localcode update <action> Auto-update from GitHub Releases (supports delta patches — typical update is ~200 KB).

Web mode

localcode --web boots a local server on 127.0.0.1:7777 (configurable), prints the URL with a one-shot CSRF token in the fragment, and auto-opens your default browser.

The web UI features:

  • Tabbed sessions (Cmd/Ctrl + 1…9 to switch, Cmd/Ctrl + T new, Cmd/Ctrl + W close).
  • Resizable / dockable panels.
  • Top-bar icon panels: Tasks · Agents · Browser · Memory · Files · Usage · Notifications · Settings.
  • Voice input (push-to-talk) + voice output (TTS) via the Web Speech API.
  • Drag-drop files from OS (images become multimodal attachments, text becomes @path).
  • PDF parsing with page-by-page preview.
  • High-quality whiteboard via tldraw — sketch a diagram → send to chat as multimodal image.
  • Mermaid diagrams rendered as SVG, full-screen zoom/pan.
  • Light & dark themes.
  • Live cost meter, queued-message indicator, error banner with Retry last.

Slash commands

Every slash command runs locally — none are sent to the LLM.

Show all commands
Command What it does
/help List every registered command.
/init Scan project & write .localcode/LOCALCODE.md.
/model [name] Open picker or switch directly.
/provider [...] Switch backend (Ollama / LM Studio / OpenAI / Anthropic / OpenRouter / Google / custom).
/profile [name] Switch permission profile: default · acceptEdits · plan · dontAsk · bypassPermissions.
/style [name] Output style: concise · explanatory · verbose.
/statusline Configure the status line template.
/resume [id] Pick or load a session.
/clear Persist a summary, start a fresh chat.
/context Show token usage, active skills, LOCALCODE.md status.
/ctxsize [n] Tune num_ctx and keep-alive.
/compress Compact context into one summary message.
/settings Edit generation params (temperature, top_p, repeat_penalty, max_tokens).
/permissions Toggle per-tool auto-approval.
/diff [ref] Open the full-screen diff viewer.
/undo [N|list] Roll back the last N file mutations from the in-memory snapshot stack.
/review One-shot LLM code review.
/plan Two-phase plan generation.
/skills Manage skills.
/new-skill Paste or supply a path for a new skill.
/memory Open memory entries list.
/memory-save <id> Save a staged feedback proposal.
/todos Open the Tasks panel.
/usage Cumulative usage dashboard with cost per model.
/cost Current-session cost breakdown per turn.
/perf /tokens Token visualizer with sparkline charts.
/agent Run the agentic loop on a task.
/spawn [id task] Spawn a specialist worker from the catalog.
/agents diff <id> Show worktree diff for a sub-agent.
/branch [...] Branching sessions: list · <name> · switch <name> · delete <name>.
/conv diff A B Compare two branches.
/record Record / replay session: start · stop · save · list.
/replay <file> Replay a recording at chosen speed.
/cron Persistent cron schedules.
/wakeups In-session deferred-continuation list.
/watch <cmd> Watch a long-running process (dev server, test runner) for diagnostic signals.
/diagnose [id] Surface compile / test errors from watched processes.
/arch Architecture rules: check · rules · init · ignore <pattern>.
/ontology Codebase knowledge graph: status · refresh · graph <symbol>.
/secrets Secret scanner: scan · scan-all · allow <pattern>.
/sensitive Sensitive-files gating: list · add <pattern> · check <path>.
/worktrees Worktree management for sub-agents.
/plugin Plugin management.
/share LAN P2P session sharing: start · stop · peers · accept.
/whiteboard Open the web whiteboard.
/filter Hide/show thinking / tool calls / system notes in chat.
/suggest Toggle proactive suggestions panel.
/exit Quit and persist the session summary.

Tools for the model

The model gets a typed toolbox. Read-only tools auto-run; mutating tools go through approval (unless pre-approved or under dontAsk).

Read-only / inspect
Tool Purpose
read_file Read file under projectRoot; auto-paginate >1 MB.
list_dir Tree listing with .gitignore honoured.
glob_search fast-glob lookup, gitignore-aware, symlink-safe.
find_symbol Symbol search via tsserver.
find_call_sites Ontology query: all callers of a function/method.
impacts_of Ontology query: transitive impact graph.
type_hierarchy Ontology query: ancestors/descendants/siblings.
lint_file Native syntax check (tsc / ruff / go vet / rustc).
fetch_image Download HTTPS or data:image/* URL; attach as multimodal.
web_fetch URL → markdown.
web_search DuckDuckGo top results.
notebook_read Read a .ipynb.
pdf_read Parse PDF pages to text.
monitor Status of a background bash task.
process_status Status of watched processes.
git_status/diff/log/branch Read-only Git ops.
Mutating (approval required by default)
Tool Purpose
write_file Replace file (two-phase preview + commit).
edit_file Unique-string search/replace.
multi_edit Atomic batch edits on one file.
notebook_edit Replace / insert / delete a notebook cell.
run_command sh -c … (optionally runInBackground: true).
git_commit Make a commit (also runs secret-scanner hook).
todo_write Update in-session task list.
schedule_wakeup Defer continuation 60–3600 s.
spawn_agent Spawn a sub-agent worker.
team_send / team_read Inter-agent communication via TeamBus.

Permission profiles

Profile read-only write_file / edit_file run_command / git_commit / browser_evaluate
default run approval approval
acceptEdits run auto approval
plan run blocked blocked
dontAsk run auto auto
bypassPermissions run auto + ⚠ banner auto + ⚠ banner

Switch at any time with /profile <name> or Ctrl+P (TUI). Sensitive-files gating overrides every profile.


Memory & skills

Memory lives at <projectRoot>/.localcode/memory/*.md. Four types: user / feedback / project / reference. Each entry is a markdown file with YAML frontmatter. The full memory section is injected into the system prompt byte-stably so prompt-prefix caching stays hot. Indexed in MEMORY.md at the root.

Skills are markdown files in .localcode/skills/ (project-local) + ~/.localcode/skills/ (global). Project wins on id collision. Hot-reloaded via chokidar. Manage via /skills and /new-skill.


Hooks & sensitive files

Hooks are shell scripts wired through [[hooks]] blocks in ~/.localcode/config.toml. Triggers:

  • PreToolUse — can BLOCK a tool call (non-zero exit → tool fails).
  • PostToolUse — synthetic system note only.
  • UserPromptSubmit — fires before context commit; blocking aborts the turn.
  • SessionStart / SessionEnd / Stop / PreCompact — lifecycle.

Built-in secret-scanner hook auto-registers on PreToolUse:git_commit — refuses to commit AWS keys, GitHub PATs, OpenAI/Anthropic/Stripe/Google keys, private keys, or high-entropy assignments.

Sensitive files at ~/.localcode/sensitive-files.toml (or .localcode/sensitive-files.toml) declare path globs (e.g. .env*, **/secrets/**, *.pem, **/.ssh/**) that always require approval, even under dontAsk.


Sub-agents

Spawn specialist workers from the curated catalog (10 templates):

architect · debugger · security-reviewer · typescript-reviewer ·
python-reviewer · rust-reviewer · go-reviewer · test-engineer ·
performance-optimizer · doc-writer
/spawn debugger "find why the migration timed out"

Workers run in isolated git worktrees, communicate via TeamBus. In TUI press Tab to enter agent-focus mode, ↑/↓ to select, Enter to attach and chat with a worker; Esc to return to the lead. In the web UI click a worker in the Agents panel to enter reply mode.

Completed workers automatically move to history; toggle visibility per panel.


MCP servers

LocalCode is a Model Context Protocol client. Configure via TOML:

[[mcpServers.my-server]]
type = "stdio"
command = "uvx"
args = ["mcp-server-time"]

[[mcpServers.docs]]
type = "http"
url = "https://example.com/mcp"
headers = { Authorization = "Bearer …" }

Tools are auto-namespaced as mcp__<server>__<tool>. Status panel at GET /api/mcp.


Configuration

All config lives at ~/.localcode/config.toml (global) + per-project overrides at <projectRoot>/.localcode/settings.json. The first run scaffolds defaults; subsequent edits are atomic (temp + rename) and Zod-validated.

Sample:

[backend]
type = "openrouter"
baseUrl = "https://openrouter.ai/api/v1"

[model]
current = "anthropic/claude-3.5-sonnet"

[permissions]
profile = "acceptEdits"
autoApprove = ["read_file", "list_dir"]

[context]
maxTokens = 32768
keepAliveSeconds = 1800
autoCompressPercent = 0.80
maxRecentMessages = 20

[sound]
enabled = false

outputStyle = "concise"

[statusline]
enabled = true
template = "{provider} · {model} · {tokens}/{maxTokens} ({pct}%) · {profile}"

Full schema: docs/CONFIG.md.


Architecture

src/
├── cli.tsx                    argv + ink mount
├── app.tsx                    composition root
├── llm/                       adapter (OpenAI-compat + Anthropic), context, executor, pricing
├── tools/                     30+ tool implementations
├── sessions/                  bun:sqlite, FTS5 search, branching
├── commands/                  slash-command factories
├── config/                    Zod-validated TOML
├── skills/                    chokidar-watched markdown skills
├── memory/                    persistent memory entries
├── hooks/                     shell-hook engine (7 triggers)
├── mcp/                       Model Context Protocol client
├── agents/                    orchestrator, TeamBus, worker pool, worktree GC, catalog
├── ontology/                  TS LSP knowledge graph
├── architecture/              arch.toml validator
├── security/                  secret scanner, sensitive files
├── process-monitor/           watched-process diagnoser
├── networking/                LAN P2P (mDNS + HMAC + AES-GCM)
├── recordings/                session record/replay
├── scheduling/                wakeups + persistent crons
├── web/                       REST + WS server, runtime pool, approval bridge
└── ui/                        ink TUI (screens, components, overlays)

web-frontend/                  Vite + React SPA (Zustand, CSS Modules, tldraw)

Single-process Bun, no daemons (except optional localcode daemon for crons). Web SPA is embedded as base64 in the CLI binary by scripts/embed-web.ts.


Testing

bun test                            # full suite (3196 passing)
bun test tests/llm/adapter.test.ts  # single file
bunx tsc --noEmit                   # type-check
bun run build                       # bundle to dist/cli.js
cd web-frontend && bunx vitest run  # web tests (435 passing)

CI: bunx tsc --noEmit, bun test, bun build, and a lint job that fails the build on any : any / <any> / as any / @ts-ignore in src/.


License

MIT — the LocalCode binary you install is free to use, modify, and redistribute.

Source code

LocalCode's distribution lives here: installer, docs, packaging, landing page, and the issue tracker. Active development happens in a separate, private repository.

  • Binaries are MIT. Anything you download from Releases is yours to use, fork, and redistribute under those terms.
  • Bug reports + feature requestsopen an issue. This is where we triage everything.
  • Want to contribute code? Open an issue describing the change. We accept code contributions via a short CLA + invite to the private source repo. See CONTRIBUTING.md and BUILD_FROM_SOURCE.md.

We picked this layout to keep the public surface focused on real users (downloads, issues, docs) while shipping fast. If you've used LocalCode under MIT, you keep MIT — closing future development doesn't retroactively close past releases.


Made with ☕, late nights, and a lot of /undos.

About

Local-first, Claude-Code-class AI coding assistant for your terminal and your browser. Bring any LLM (local or cloud), real tool calling with approval gates, sub-agents, memory, hooks, MCP, branching sessions, voice, PDF, whiteboard, LAN sharing. Bun + ink + Vite/React.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages