The insrc CLI

The insrc command is a full-screen interactive TUI — an ink (React) terminal app with six panes: Daemon, Repos, Workflows, Setup, Tiers, and Debug. It replaced the old commander subcommands entirely; there are no insrc <verb> subcommands, only the interactive app and its built-in command bar.

A full-screen terminal app

Launch it from anywhere — the launch directory becomes the default selected repo. The insrc bin resolves to out/cli/index.js (built) with source at src/cli/index.tsx.

bash
$ npx insrc              # or the built entry: node out/cli/index.js

The app renders a header with the four pane tabs, the active pane body, a toast line, and a persistent key-hint footer. Every pane talks to the running daemon; if the daemon is down, the Daemon pane starts it.

global keys

These work from any pane (a pane suspends them while it has an open prompt / modal):

: open the command bar · 16 jump to a pane · Tab / Shift+Tab cycle panes · r refresh · ? help · q quit

The six panes

Panes are ordered Daemon (1), Repos (2), Workflows (3), Setup (4), Tiers (5), and Debug (6). Each pane owns a small set of single-key actions shown in its footer hint bar.

Daemon — health & lifecycle

A live health readout (uptime, queue depth, embeddings pending, model-pull status, LMDB size on disk, registered repo count) plus the full maintenance lifecycle. Long-running operations — restart, update, backup — stream their progress into a live log below the readout.

insrc — Daemon
┌─ Daemon ──────────────────────────────────────────┐
 ● running  uptime 4h 12m                         
 queue     0 job(s) · embeddings pending 0       
 model     ready                                  
 lmdb      218 MiB on disk                        
 repos     2 registered                          
└───────────────────────────────────────────────────┘
 s start  x stop  R restart  u update  b backup  c compact

Keys: s start · x stop · R restart · u update · b backup (prompts for a directory) · c compact the LMDB store.

Prefer u update / R restart here over a manual git-pull-and-kill — they run the daemon's own maintenance service functions and stream each step.

Repos — registered repositories

The list of registered repositories with a colored status dot — ready (green), indexing (yellow), pending (gray), error (red) — the status label, path, and when it was last indexed. The highlighted row is the selected repo that the Workflows pane targets. Adding a repo goes through the repo.add IPC (the registry contract); the daemon then parses, builds the graph, and generates embeddings.

insrc — Repos
┌─ Repos ───────────────────────────────────────────┐
   ready    ~/work/insrc      (indexed 2m ago)  
    indexing ~/work/my-service  (indexed never)   
└───────────────────────────────────────────────────┘
 ↑/↓ select   a add   d remove   i reindex

Keys: / select · a add (prompts for a path) · d remove (confirms, drops its graph data) · i reindex the highlighted repo.

The repo registry is the contract. An entity whose repo path isn't registered fails the upsert with UnregisteredRepoError — the storage layer never auto-allocates rows. Add the repo with a first, and add its dependency repos too if you want cross-repo answers (searches span the transitive DEPENDS_ON closure).

Workflows — the Epic chain

The Epic chain for the selected repo. The list view shows every Epic (a DEF-*.json under .insrc/artifacts/); opens a detail view with the chain state — Define / HLD marks, per-story LLD status (with STALE flags), the next action, amendment counts — and a cursor over the actionable items (the next pending artifact and any pending amendments) that you approve or reject in place.

insrc — Workflows
┌─ Workflows · plan-workflow ───────────────────────┐
 define  ✓ approved   hld  ✓ approved            
 stories                                          
   s1 tracker resolve        ✓ approved          
   s2 id resolution          • pending           
 next: approve-lld   amendments: 0 pending      
 actionable                                       
  approve LLD s2 (…/artifacts/LLD-s2.json)         
└───────────────────────────────────────────────────┘
 ↑/↓ select   a approve   x reject   b/Esc back

Keys (list): / select · open. Keys (detail): / select · a approve · x reject (prompts for a reason) · b / Esc back.

The panes approve and reject artifacts; they don't generate them. Run a workflow stage to produce the next artifact via the insrc_workflow_step MCP tool or the daemon's workflow.run IPC — then approve it here. See the workflow guide.

Setup — provider & model config

Hardware detection (CPU, RAM, GPU/VRAM, Ollama availability) and a model recommendation for a tier — the coder model, the embedding model + dims, and the context shape/token budget. a writes the recommended config; p pulls any missing models, streaming Ollama's progress into a log (never stdio:inherit, which would fight ink).

insrc — Setup
┌─ Setup ───────────────────────────────────────────┐
 System                                            
   CPU   Apple M3 Max (14 cores)                    
   RAM   64GB total · 22GB free                     
   GPU   Apple M3 Max · 48GB VRAM                    
   Ollama v0.5.4 (6 models)                         
 Recommendation (high)                            
   local     qwen3.6:27b (27B)                      
   embedding qwen3-embedding (1024 dims)            
   context   wide (65536 tokens)                    
└───────────────────────────────────────────────────┘
 a apply config   p pull models

Keys: a apply the recommended config · p pull the missing models.

Tiers — per-role model tiering

Accuracy is the primary principle, and the Tiers pane is where it is enforced concretely. It shows the effective model tier for each role — computed by overlaying your config onto the built-in defaults and the role taxonomy (computeEffectiveTiers) — and lets you edit a tier's runner/model, the coreFloor, or a single role's override. The coreFloor guarantees the critical roles (design, review, build, validate) are never served below the high tier; peripheral roles (classification, narrow probes, tracker rendering, summaries) may trade capability for cost on cheaper local models. Reads and writes go through the daemon like every other pane (models.analyze.tiers / coreFloor / roleTiers).

insrc — Tiers
┌─ Tiers · effective per-role ──────────────────────┐
 core   (coreFloor: high)                          
   design    high   cli-claude                     
   review    high   cli-claude                     
   build     high   cli-claude                     
 peripheral                                        
   classify  low    ollama:qwen3.6:35b-a3b         
   summarise low    ollama:qwen3.6:35b-a3b         
└───────────────────────────────────────────────────┘
 edit tier   f coreFloor   o role override

Debug — daemon internals

A diagnostics pane hosting three inner sections, one shown full-height at a time; navigate them with / (the outer switcher keeps 16/Tab). The section registry is injected as a services facade, so the views stay thin:

SectionShows
DaemonLive daemon status — pid, uptime, socket — plus an orphan-process scan and a kill action for stale daemons left behind by a crash.
MCPThe registered MCP clients (Claude Code / Codex) and a debug-status probe over the daemon's IPC, so you can see what's actually connected.
LogsA live tail of the daemon's rotating log file, in-pane.
insrc — Debug
┌─ Debug · Daemon ──────────────────────────────────┐
   pid     48213   uptime 2h14m                     
   socket  ~/.insrc/daemon.sock  ● up              
   orphans none                                    
└───────────────────────────────────────────────────┘
 ←/→ section   Daemon · MCP · Logs

Talking to the daemon

The CLI never opens LMDB or LanceDB directly. Every pane action goes through the daemon over JSON-RPC on its Unix socket at ~/.insrc/daemon.sock, via the service functions in src/cli/services/daemon, repo, workflow, config, setup, maintenance, lifecycle, and debug. The panes are thin views over that services facade; the daemon owns all DB access.

The command bar

Press : for a vim-style command line — the same operations the panes expose via keys, but typed, plus a few that have no key. It runs against the same services facade and prints its output inline.

insrc — command
: tracker setup --project
 config      — wrote .github tracker config
 labels      — created 6 workflow labels
 issue-types — already present
 project     — linked GitHub Project
 tracker ready — no manual steps remaining
CommandSubcommands
repoadd <path> · remove <path> · reindex <path> · list
daemonstart · stop · restart · update · backup <dir> · compact · status
workflowlist · chain <hash> · approve <path> · reject <path> <reason> · ack-stale <path> <reason> · sync <hash> · deferred <epicSlug|hash>
trackersetup [--project] — bootstrap the GitHub tracker (config, labels, issue types, project)
configlist [search] · get <key> · set <key> <value> · unset <key> · reload (dot-path keys)
setupshow · apply · pull
panedaemon|repos|workflows|setup|tiers|debug · plus help and quit
The command bar is the same interpreter for every workflow verb — including tracker setup, which has no pane key. It's pure logic over the services facade, so it unit-tests directly with a fake Services.

Shared config layout

The CLI and the daemon share one on-disk home, ~/.insrc/ (defined in src/shared/paths.ts). The socket the CLI dials, the config it edits, the graph + vector stores the daemon owns, and the workflow artifacts all live under it.

PathWhat it is
~/.insrc/daemon.sockUnix socket — the JSON-RPC endpoint every pane and service function dials.
~/.insrc/daemon.pidPID file the lifecycle service uses to start / stop / restart.
~/.insrc/config.jsonon-disk config the Setup pane and config command read and write.
~/.insrc/graph.lmdbLMDB store — the graph, repo registry, plans, conversations, config.
~/.insrc/lanceLanceDB store — entity / session / turn / config vectors.
<repo>/.insrc/artifacts/per-repo workflow artifacts (DEF-*.json and the rest of the Epic chain) the Workflows pane lists.

Because the daemon owns every one of these, the CLI stays a pure client — no LMDB / Lance handles in the TUI process, only IPC. That's the same contract the MCP servers and the IDE workbench follow.

Where next