coldstart, command by command.
coldstart is one binary with two front doors — a CLI (the fast path for any shell-capable agent) and an MCP server (for no-shell clients), with byte-identical output. This page covers the stable core surface; for exhaustive flags, versioned changes, and internals, see the README and docs on GitHub — the source of truth.
find (which files?) and gs (what is this file, who uses it?) — and the kb family is the notebook: durable, agent-written notes kept honest by the index. That's the whole surface.Install & setup
Requires Node.js 18+. Install globally, then run init once per project.
init asks two things — the experience (cli, recommended, or mcp) and the client (claude / cursor / codex / other) — then writes the coldstart guidance into the client's own rules file — imported via coldstart.md for Claude Code, inlined directly into .cursor/rules/coldstart.mdc (Cursor) and AGENTS.md (Codex) — and wires the client. It also creates the notebook and, for Claude Code / Codex / Cursor, registers the navigation and notebook hooks. Pass --experience / --client to skip the prompts; the client is never auto-detected.
.raw logs so the team can share it. Private by default — see Sharing.Upgrading: npm install -g @cstart/coldstart@latest, then re-run coldstart init in each project. A version stamp in the keeper's lockfile shuts the old background process down on the next lookup; a fresh one spawns from the new binary.
Removing: coldstart unwire reverses init — it strips coldstart's per-repo wiring (hook entries, the coldstart.md import, the AGENTS.md block, the MCP entry, owned files) without touching your own content in shared files. The notebook is kept by default; --purge also deletes it. Run it per project, then npm uninstall -g @cstart/coldstart.
Codex hook trust: Codex gates hooks behind a trust review, so the notebook/navigation hooks init writes will not fire until you approve them (untrusted hooks are skipped silently) — init cannot pre-trust them (no supported non-interactive path; see openai/codex#21615). When Codex shows "Hooks need review", choose "Trust all and continue". If your Codex app doesn't surface that prompt, launch codex from a terminal in the repo — it appears at startup there; trust persists (keyed by each hook's hash) across surfaces. Re-approve after any coldstart update changes a hook. For automated codex exec runs, pass --dangerously-bypass-hook-trust instead. Project trust (trust_level = "trusted" in config.toml) is a separate gate and does not trust hooks.
The intended flow
find → gs → Read. Orient with two cheap calls before spending a token reading. Notebook summaries ride along on find, so the orientation step often answers itself.
- find a concept → ranked candidate files, each with the evidence for why it ranked.
- gs the best file → its symbols, importers, and per-symbol callers, in one call.
- Read only the method body you actually need — not the whole file.
Pass every salient identifier from your task — the symbol, the domain noun, the rare token you half-remember — not one distilled keyword. find ranks by coverage and shows where the terms cluster, so often that's enough to answer without opening anything. Its reference pass runs on ripgrep, so it competes with raw grep on speed.
! to exclude.a|b = OR, /regex/ = regex.symbols / imports / importers / callers. Default returns all.this.method(), api.method()) don't. Chase further hops by running gs on the caller file.The notebook, in depth
A repo-local knowledge base, written and read by agents, living in .coldstart/notebook/. It's the one place semantics belong: authored by the agent that just did the work, kept honest by the index, and recalled when a later task matches. No human writes or grooms it.
What a note is
What a file is for — a single summary, or per-symbol facets for hub files.
A cross-file story: ordered steps and the invariants that hold across them.
A trap, rule, bug-cause, rationale, or a confirmed absence.
Every note carries anchors — the concrete file paths and symbols its claims rest on. Anchors are what make a note checkable rather than a floating assertion.
Where notes reach the agent
- Summary lines on
findresults — a past agent's verified overview, right where the file ranks. fresh means the file is byte-identical to when the summary was verified, so the agent can rely on it without re-reading. - Recall at prompt time (optional hook) — notes whose titles, aliases, or anchors match the prompt surface as a compact, hard-capped block. Nothing matches → nothing injected.
kb search/kb lookup— a search engine over the notebook, and an exact-address lookup before editing a file.
Why it can be trusted
- Freshness is mechanical. Every anchor is stamped with a content hash at write time; the index re-checks it as the code changes. A drifted note renders evidence changed and the guidance says re-verify — stale knowledge degrades into a labeled hypothesis, not a confident lie.
- The log is the truth. Notes live in an append-only
.rawevent log; the Markdown notes are derived and regenerated mechanically. A note is a pure fold of its log. - Writes go through a gate. A new note's concept is searched against existing notes first — the agent must merge into a match or declare it new. Duplicates are caught at write time.
- Concurrent sessions are safe. Per-note append-only logs, exclusive creation of new ids, lossless union-merge of shared notes, atomic renders — concurrent writers never silently merge or lose a note.
- Corrections happen in-session. An agent that finds a note wrong while the evidence is in context is told to fix or retract it right then.
Language-agnostic. The freshness machinery is content-hash based, so the notebook works on any codebase — including languages the navigation index doesn't parse. Where the index does parse, notes additionally get symbol-level freshness.
- First call exits 3 with candidate matches. Resolve it with
--into <id>(merge into an existing note) or--new(declare it genuinely new). - Reads a spec file, or
-to stream the spec from stdin. - Freshly-coined ids are created exclusively — a same-moment duplicate becomes two visible notes, never a silent merge.
.raw logs and skeleton — never your feature code, and notes never ride along in a feature commit.kb commit is CLI/human-only and is not exposed as an MCP tool. Publishing notes to git is a human decision.index.html but don't launch the browser.kb search / lookup; this is the view for a person who wants to browse what the agents have been keeping. The generated file self-registers in the notebook's .gitignore..raw logs.coldstart init, which already does this.How the index stays fresh
coldstart is one keeper, thin readers. A single background keeper watches the repo and keeps an on-disk cache current; the readers (find, gs, the MCP server) are stateless and never build. There is no cache TTL — the index is never discarded for being old, it's kept correct.
Patched as you type
Edits debounce (400 ms), then patch incrementally (~2–5 ms/file) or trigger a background rebuild. Re-saved in atomic generations — a reader never loads a half-written mix.
Reconciled, not rebuilt
Stat-checks every file against its fingerprint plus a git diff, and patches exactly what changed. A branch switch that used to force a full rebuild is now typically a few seconds.
Linted & audited
Every patch is checked against index invariants (a violation auto-rebuilds), and a rotating fingerprint audit after each save catches watcher-missed drift.
Lifecycle commands
--root DIR targets another repo; --all kills every keeper.coldstart restart — a fresh keeper reconciles on start, so it comes back correct, not just alive. If something looks structurally wrong, TROUBLESHOOTING.md on GitHub has recovery steps.MCP tools
For no-shell clients (like Claude Desktop), the same engine is exposed as MCP tools with byte-identical output to the CLI.
kb_write.kb commit and kb view stay CLI/human-only — publishing to git and opening a browser are never agent actions.Bring your own semantics
coldstart has no embeddings, no generated summaries, no semantic layer computed at index time — on purpose. The semantic layer is the agent. Every consumer is already a frontier model; pre-computing meaning at index time only duplicates that, worse and stale. So the index keeps what's cheap to keep exact — paths, symbols, exports, the import/call graph — and returns why each file ranked. The notebook applies the same rule to memory: it stores and freshness-checks the meaning agents author, and computes none of its own.
Supported languages
Tree-sitter for the parsed set; the notebook's content-hash freshness works on all of them — notes on a Swift repo are as trustworthy as notes on a TypeScript one (they just lack symbol-level freshness).
Not indexed: Swift, Dart — no extension mapping; these files aren't walked or parsed. The notebook still works on them.