Changelog
Release notes pulled from GitHub Releases.
v1.0.221
Jun 12, 2026 · v1.0.221View on GitHub ↗✨ New: Inspect subagent transcripts
When a turn spawns a subagent via the Agent/Task tool, its full transcript is now one click away. The tool call card gets a Subagent action that opens a modal rendering the subagent's messages with the same bubbles as the main session. While the parent tool call is still running, the modal polls every 5s and auto-scrolls so you can watch the subagent work in real time; closing it stops the polling.
The Agent/Task tool header also now shows the task description (the same slot Bash uses for its command — truncated, full text on hover) instead of a bare tool name, so you can tell subagents apart at a glance.
✨ New: Builtin slash commands are real skills +
/crThe builtin slash commands (
/qa/fx/ex/go/cg/cc) now write their resolved prompt to~/.cockpit/skills/<cmd>/SKILL.mdand hand the model a "read this skill file" pointer — the same flow user-defined skills use — instead of inlining the whole template. They're now inspectable and editable on disk like any other skill.New this release:
/cr— a full code review (static triangulation + dynamic modelling), available alongside the others.🐛 Fix: Terminal bubbles render UTF-8 correctly
Terminal bubbles ran in the C/POSIX locale because the pty env whitelist dropped
LANG/LC_*, sovim/lessshowed CJK and emoji as mojibake while ASCII looked fine. Bubbles now default to a UTF-8 locale and pass realLANG/LC_ALL/LC_CTYPEthrough when the server has them.🐛 Fix: PTY mode handles
AskUserQuestioncleanlyIn PTY mode, a model reaching for the
AskUserQuestiondialog is now blocked at the source by aPreToolUsehook that steers it to ask in plain text and end the turn normally — so the turn completes instead of getting stuck behind an interactive card. A circuit breaker ends the turn after 3 attempts as a backstop, and the injected hook settings now self-heal across mixed-version cockpit instances.🐛 Fix: Update popover closes on outside clicks
The "update available" popover stayed open when you clicked into the project area, because that area is a per-project iframe whose clicks never reached the handler. It now listens in the capture phase and closes on window blur, so clicking anywhere — including inside the project iframe — dismisses it.
v1.0.220
Jun 11, 2026 · v1.0.220View on GitHub ↗✨ New: Claude Code CLI mode is now the default
New chat tabs (and restored tabs that never made an explicit choice) now run in Claude Code CLI (PTY) mode out of the box. The toggle in the chat header still lets you switch back — an explicit SDK choice is remembered per tab, and the button order now puts the default first.
CLI mode also got smarter about interactive prompts: when claude-code pops its
AskUserQuestionselector mid-turn, nobody is there to press Enter — previously the turn just hung until timeout. Cockpit now detects the selector, dismisses it, and ends the turn cleanly. The question itself still appears in the chat, so you answer it as your next message; a short notice explains why the turn ended early.✨ New: Send Q&A straight to chat
The AskQuestion viewer modal has a new send-to-AI button — pick selected (or all) Q&A pairs and send them directly into the active chat instead of copy-pasting by hand. The modal closes after sending.
🐛 Fix: Scheduled tasks run with the right engine
A scheduled task created from an Ollama / Codex / Kimi / DeepSeek tab used to fail at fire time with "No conversation found with session ID" — tasks always resumed through the Claude Agent SDK, even when the session lived elsewhere. Tasks now record the engine (and model) of their originating chat and execute with it, with a clear error if the session has since disappeared.
v1.0.219
Jun 10, 2026 · v1.0.219View on GitHub ↗✨ New: Claude Code CLI execution mode
Each Claude / Claude2 chat tab now has a second way to run: a Claude Code CLI mode alongside the existing Claude Agent SDK mode. Flip the toggle above the message list.
In CLI mode every message drives a real interactive
claudesession in a pseudo-terminal — it types your prompt into the live REPL, watches the session transcript to know when the turn is done, then exits. Both modes read and write the same session file, so you can switch per tab, mid-conversation, and the next turn just continues. One history, no split.A small floating terminal in the corner shows the live, character-by-character output of the real session. It auto-expands while a turn runs, and if a turn ever gets stuck you can type directly into it to nudge things through by hand. Press
ESCto interrupt — the session is reaped cleanly, no orphan processes.Different invocation paths can be metered differently over time; pick whichever fits. More background on the blog: https://opencockpit.dev/en/blog/claude-code-cli-execution-mode/
✨ New: Search results scope toggle
The Explorer search panel gets a selected / all toggle next to the results title — show only matches in the file selected in the tree, or every match across the search. Defaults to "selected" and resets on each new search.
🌐 Site: "On this page" docs TOC
Every
/docspage now renders an "On this page" table of contents in the right column (shown at xl+). Heading anchors and TOC links derive from one shared module, so links can't drift — and inlinecode/ bold in a heading no longer breaks its anchor id.v1.0.218
Jun 1, 2026 · v1.0.218View on GitHub ↗✨ New: AI-friendly browser CLI (selector / wait / assert / lifecycle)
Reframes
cockpit browserfrom a snapshot+ref toolkit into a selector-first E2E surface designed for an AI to drive end-to-end. Three things that used to bite: refs going stale on every re-render, silent failures when CDP key/click events get ignored by React's synthetic event flow, and verboseevaluate(fetch(...))wrappers just to read the backend.# Find and interact (no snapshot needed; refs go stale on re-render) cock browser <id> click --text "Sign in" cock browser <id> click --selector 'button[type="submit"]' cock browser <id> fill --selector 'input[name="email"]' --value "user@example.com" cock browser <id> submit --form-selector 'form#login' # act → wait → assert (atomic E2E) cock browser <id> wait --network-idle --quiet-ms 500 cock browser <id> assert --selector '[role="status"]' --text "Saved" cock browser <id> assert --fetch /api/items --jsonpath '$.count' --equals 5 # Probe the backend (page auth inherited) cock browser <id> fetch /api/users/me --json '$.email' # Test isolation cock browser <id> reset --cookies --storage --reload cock browser <id> set --type cookie --name token --value abc123 --path / # Bridge state without entering the page (answers even while the page is busy) cock browser <id> health cock browser <id> status # url + title + last console error + top buttonsWhat's behind the changes:
- Selector-first interaction.
click --text / --selectorandfill --selectorwork after any re-render. Refs still work but now carry a snapshot epoch (e5#v3); using a stale one returns a clear error pointing at the selector form. - Wait / assert atomics.
wait --network-idle,--selector --state visible|hidden|attached|detached,--dom-stable, and the CLI-side--extension-ready(polls the cheap server-sidehealthso it survives a busy page).assert --selector,--network --method --url --status, and--fetch --jsonpath {--equals|--contains|--not-contains}compose with selector-based acts to give one-step act + assert instead of three-stepact + sleep + evaluate. - Backend probing.
fetch <url>shortcuts the most commonevaluate(fetch(...).then(r=>r.json()))pattern. Inherits the page's auth session; supports--method,--body, and a--json <jsonpath>extractor (subset of JSONPath:$,.key,[N],[*]). - Lifecycle helpers.
reset --cookies --storage --cache --reloadfor atomic test isolation;set --type cookie|local-storage|session-storage(there's now a write side, not just read);statusfor a one-line "where am I" — URL + title + last console error + last failed request + top visible buttons. - Silent-failure detection for
click/key/submit. After CDP returns "success", the CLI quietly diffs page state. If the URL didn't change, the DOM didn't mutate, and no network fired within the verify window, it writes a warning to stderr with concrete recovery commands. Window is 1 s by default;--verify-msto tune,--skip-verifyto bypass for known no-op clicks. - Better timeouts and stale-ref errors. Every error now carries an actionable next step.
Timeout after 15000msbecomesTimeout (action "X"). Bridge state: ws=open pending=2 lastSuccess=12s ago. Diagnose: cockpit browser <id> health ….Element ref "e5" not foundbecomesElement ref "e5" is stale (current snapshot v=3). Re-run snapshot, or use click --text / --selector.
Full action surface: https://opencockpit.dev/en/docs/reference/cli/#cockpit-browser (Chinese version under
/zh/).✨ New: version-update pill in Settings
When a newer cockpit is published to npm, the Settings row in the project sidebar shows a small pill — click it for a popover with Copy
cockpit update(paste-ready upgrade command) and View changelog. The check is a client-side npm-registry probe (3 s timeout, silent on failure), so it doesn't block startup or leak telemetry.When the sidebar is collapsed, the gear icon picks up a red dot — the only update signal that fits in icon-only mode.
Help also moves into the same row as a secondary
?action that takes you to the docs in your current locale.🐛 Fix: Code Map indexes newly created files
Creating a file (
Writetool,git pull, branch switch, new file in editor) used to leave the Code Map panel stuck at "0 blocks · No functions detected." until you rebuilt the index manually.syncDirtyIndexonly iterated existing keys, andrefreshFocalFileearly-returned for unknown paths.Now the first focal query on an unknown file dispatches to a new
addFocalFilehelper (five guards: project-fileset membership viagit ls-files, registered grammar,MAX_FILESsoft cap, parse-success, fileset add). The analytics cache is also invalidated sorisk/related/contextroutes pick up the new node on the next query. When the fallback path runs, the response carriesnotIndexed: trueso the UI can render a "not in project graph" hint with a rebuild button instead of the generic empty state.🌐 Site: docs IA rewrite at opencockpit.dev
The docs site got a structural rewrite into five sections — Get Started / Agent / Explorer / Console / Reference. Tech Plan Reviews moved under Explorer; Chrome extension moved under Console. All ~30 doc pages were fact-checked against the actual product code, MDX was converted to MD, and the sidebar now persists scroll position across navigation by being hoisted into the docs layout.
scroll-padding-top: 4remkeeps anchor-linked titles from tucking under the sticky nav.📚 Docs: long-form local docs retired in favour of opencockpit.dev
The long-form docs that used to live in the repo are gone — they were drifting behind the website:
docs/manual.md/docs/manual.zh.mdremovedGUIDE.md/GUIDE.zh.mdremovedREADME"Contributing" link now points to https://opencockpit.dev/en/docs/
The website's CLI reference is the new single source of truth for the browser CLI — rewritten end-to-end to match this release's surface, including a new "When NOT to use this CLI" section that mirrors the in-CLI help (LLM-agent E2E, long-streaming pages, multi-tab OAuth flows).
- Selector-first interaction.
v1.0.217
May 26, 2026 · v1.0.217View on GitHub ↗✨ New: Bubble titles +
cockpit connection listfor /cc agentic flowsA pain point with
/ccslash mode: the LLM sees 4-char short ids likebmfb/mpcwas opaque tokens — there's no way to know which terminal is the alloydb proxy and which browser is the staging admin. This release closes that gap.Give each bubble a name
Every terminal / browser bubble's short-id badge now has a ✎ next to it. Click it (or the
(set title)placeholder for unnamed bubbles) and a small dialog opens to label the bubble —"alloydb proxy","staging admin", etc. Titles persist to disk per project + tab, so they survive reloads and server restarts.Implementation note: titles ride along the existing
terminal-bubble-order-${tabId}.jsonfile. The schema is upgraded from a plainstring[]to{ order, titles }with a transparent legacy-shape read — no migration script needed, and the POST endpoint accepts partial patches (touch onlyorderor onlytitles, never both unnecessarily).The dialog guards against CJK / Hangul / etc. IME composition: pressing Enter to commit a candidate no longer fires "save" prematurely.
cockpit connection list— cross-type bubble enumerationcockpit connection list --cwd $PWD # all alive bubbles in this project cockpit connection list --cwd $PWD --all # include exited terminals / disconnected browsers cockpit connection list --cwd $PWD --json # machine-readable for scriptingOutput is TAB-separated, one row per bubble:
term aqou alloydb proxy /Users/.../ai-assistant ~/alloydb-auth-proxy ... brow mpcw staging admin /Users/.../my-project https://staging.example.com brow vxvk (none) /Users/.../my-project http://localhost:3000Exit codes are standardised — 0=hits, 1=no bubbles, 2=usage, 3=server unreachable — so you can pipe it through shell control flow.
/ccprompt teaches the workflowThe
/ccslash-mode prompt now instructs the model to callcockpit connection list --cwd $PWDbefore picking an id, when the user refers to a bubble semantically ("the alloydb proxy terminal") rather than by short id. Title (none) entries fall back to matching thecommand/URLcolumn.Prod/dev signalling clarified
/ccnow defaults tocockpit(prod) explicitly. The model switches tocockpit-devonly when the user gives an explicit signal — either writescockpit-dev ...in the task, or starts the task with/cc dev .... No more ambiguous swapping.📚 Docs
README/GUIDE/docs/manual(en + zh) all gain acockpit connection listline alongside the existing terminal / browser CLI examples.docs/manualadds a dedicated## 6.5 Connection Enumeration (CLI)section with output schema, exit codes, and the design rationale.- Bulk cleanup across
docs/manual(en + zh): retiredcock terminal/cock browser(~33 occurrences each) in favour of the recommendedcockpit terminal/cockpit browser, with an explicit "(cock is the prod-only short alias)" note per CLI section. CLAUDE.mdCommands block expanded to show all three entries explicitly:cockpit(primary) /cock(prod alias) /cockpit-dev(dev only).
📦 Misc
bin/setup-dev.mjs(the script that selectively symlinkscockpit-devto local source for repo contributors) now resolves the global bin dir fromprocess.execPathinstead ofnpm config get prefix. The previous approach could resolve to a different directory undersudobecause/root/.npmrcandHOMEdiffer from the user's —process.execPathis unaffected. SetCOCKPIT_BIN_DIR=...to override for non-standard layouts.cockpit codegraph searchnow accepts--include-literalsto forward the v1.0.216 server-side flag (it was teaching agents about the capability via/cgbut couldn't actually pass it through). Help also documents the case + word-separator folding that v1.0.216 added.- Stale terminal write-side examples (
cock terminal <id> exec / stdin / follow) are gone fromREADME/GUIDE/docs/manual/ the website's/docspage — those were retired back in v1.0.214 and users hitting "Unknown subcommand" had no way to know.
v1.0.216
May 26, 2026 · v1.0.216View on GitHub ↗✨ New: Naming-style-tolerant search + opt-in string-literal indexing
searchIndexnow folds case and word separators on both the query and the indexed names, so naming-style variants of the same concept all collide on one query:cockpit codegraph search build_code_index # finds buildCodeIndex cockpit codegraph search BUILD-CODE-INDEX # same result cockpit codegraph search build_code_index # also sameStrict matches still rank first; the change only adds more — fully backward compatible. Useful when you don't remember if the codebase uses
snake_case,camelCase,kebab-caseorSCREAMING_CASEfor a given concept.?includeLiterals=true— surface names that only exist as string literalsSymbol-only search used to be blind to names that never appear as identifiers — tool registrations, event names, config keys, route paths. With the new opt-in flag:
cockpit codegraph search 'agent.fork' --include-literals # finds it in registry literals GET /api/projectGraph/search?q=agent.fork&includeLiterals=trueIdentifier-shaped literals (length 3-64, shape-filtered to skip SQL / JSX / prose) are harvested at index time and stored alongside symbols. The flag is off by default so Cmd+K palette responses stay lean; flip it on when you're hunting a name you can't grep because it's hiding in source as a string.
Per-file cap is 500 literals, scan cost is O(log n) per hit (offset table + binary search for line numbers), language-agnostic regex — no parser plugins needed.
📚 Docs
cockpit codegraph search --helpand the/cgslash command prompt both mention the new flag with an inline example.v1.0.215
May 26, 2026 · v1.0.215View on GitHub ↗✨ New:
cockpit codegraph— unified entry for all 10 graph endpointsv1.0.214 shipped 10 CodeGraph HTTP endpoints but only exposed
cock affectedat the CLI surface. That asymmetry is gone — every endpoint now has a CLI subcommand under a single dispatcher:cockpit codegraph search callers callees impact file coedit context related risk affectedEach subcommand has full
--helpwith Usage / Purpose / Flags / Output / Stderr / Exit codes / Examples, so an LLM agent can pre-constructgrep/awkpipelines without trial-and-error.--as-jestwas renamed to the generic--as-cmd <runner>(jest /"vitest run"/"pytest -v"/ …) so the binary doesn't lie about being Jest-specific in mixed-language projects.✨ New:
/ccslash mode — drive the cockpit CLI from chatSister to
/cg. Teaches the agent whatcockpit/cock/cockpit-devcan do, pointing at each subcommand's--helpas the canonical reference (no prompt drift). Trailing user text gets labeled任务:/Task:to prime the action-execution mindset. Typical usage:/cc cockpit terminal bmfb 看错误日志 /cc cockpit browser vxvk 给我截屏并描述页面Type
/in the chat to see it in the autocomplete dropdown, between/cgand/skill-name.✨ New:
cockpit-devbinary +setup-devselective symlinkcock-devis renamed tocockpit-deveverywhere — symmetry with the prodcockpit/cockpair (no short alias on purpose; production stability wants the prod/dev split to be loud). For CLI development,npm run setup-devselectively symlinks onlycockpit-devto local source, leaving the npm-installed prodcockpituntouched. Unlikenpm link(which clobbers both bins), this lets you editbin/*.mjslive and stillnpm install -g @surething/cockpit@latestto upgrade prod without disturbing the dev symlink. No morenpm unlink/install -gdance.🐛 Fix:
cockpit browser typeno longer silently no-ops on React SPAscockpit browser <id> type <ref> "text"used to report success on contenteditable / React-controlled inputs (tiptap, ProseMirror, Lexical) even when CDPInput.dispatchKeyEventwas a no-op against the React state machine. Two fixes:- Post-type verification. After the type call returns, the CLI evaluates
document.activeElementand checks that the live.value/.textContentactually contains what was typed. Mismatch → exit1with a copy-pasteableevaluatetemplate tailored to the input's shape (contenteditableinsertText/ React setter +inputevent dispatch / etc.). - Cheat sheet upfront.
cockpit browser <id>(no args) now opens with a "React / SPA gotchas" section + 3 evaluate templates ready to copy, and thetype/click/filllines carry inline ⚠ markers. The same task that took 15 bash calls to debug across two earlier sessions now lands in 5.
🐛 Fix:
cockpit terminal <id> --helpno longer rejectedcockpit terminal <id> --helpused to error withUnknown flag: --helpbecause the meta-page handler whitelisted only--json. The meta page is the help for that bubble, so<id>and<id> --help(and-h) now behave identically.🐛 Fix: markdown — fenced blocks preserved + Prism token classes isolated
Two related fixes for chat-rendered markdown that mishandled mixed content:
- The GFM table-pipe escape pass used to run across the entire input, including ```markdown / ~~~ fenced examples. A snippet showing literal
| col1 | \a|b` |would get its inner|` silently rewritten — corrupting the verbatim source the user clearly meant to display. Fenced blocks are now masked before substitution and restored after. react-syntax-highlighter's Prism markdown grammar emits class names literally —<span class="token table table-header-row">— and Tailwind ships a.table { display: table }utility class with the same name. Insidelanguage-markdownblocks, every Prism token (table,code,list,title, …) was getting forced todisplay: table, breaking each cell onto its own line. A scoped reset (code[class*="language-"] .token { display: inline }) keeps Prism tokens inline without affecting other places that use Tailwind's.tableutility.
📚 Docs
README + README.zh.md were still advertising the v1.0.213-retired
/review//commitslash commands and 6 CodeGraph endpoints (v1.0.214 shipped 10). Pulled both into sync: slash-mode list is/qa /fx /ex /go /cg /cc, the CodeGraph section names the 4 new analytics endpoints (context/related/risk/affected, powered by PageRank · PPR · TF-IDF · Louvain, zero training), and~/.claude/commands/*.mdreferences are replaced with the current "drop a SKILL.md via the Skills sidebar" convention.🌐 Site
opencockpit.dev got an SEO pass:
- Homepage meta description trimmed from 339 → 157 chars so it fits Google SERP without truncation; introduced a separate
hero.metaDescriptionfield so the visible Hero copy stays untouched. /docspage gained a real description + OpenGraph + Twitter card (was bare).- All per-locale routes now mirror
og:localeviaog:locale:alternate(en_US ↔ zh_CN). hreflang="x-default"added on blog list / blog post / changelog / docs.- Keywords expanded 26 → 72: CodeGraph / Code Map / per-engine GUI long-tails (Codex / DeepSeek / Kimi / Ollama) /
Cline alternative/Windsurf alternative/GitHub Copilot alternative+ the corresponding ZH variants (代码图谱/智能气泡/AI 编辑器/Codex 中文/ …).
- Post-type verification. After the type call returns, the CLI evaluates
v1.0.214
May 26, 2026 · v1.0.214View on GitHub ↗✨ New: Four CodeGraph analytics endpoints +
cock affectedCLI/cgmode gains a second tier of endpoints — alongside the original six (search/callers/callees/impact/file/coedit), the project graph now exposes ranked, signal-annotated outputs designed for both LLM analysis and CI pipelines:/api/projectGraph/context— multi-source semantic retrieval. Combinequery,cursor, andopenFiles; get back the Top-K relevant coordinates ranked by PPR + TF-IDF + PageRank with explainablesignals[](query-match / ppr / pagerank / open). Useful when you don't know the symbol name yet, only the intent./api/projectGraph/related— broader thancallers/callees. Each result carries arelations[]tag explaining why it surfaced: direct caller / callee, PPR neighbour, frequent-coedit partner, or sibling-in-community (Louvain). One call replaces the three you used to make./api/projectGraph/risk— risk-scored impact. Wraps/impactand overlayscallFreq + coeditProb + hasTest + pagerankper node, with adaptive weights when coedit is unavailable. ReturnshighRisk(sorted, capped) +suggestedTests+ an echo of the target's coedit history so callers don't re-fetch./api/projectGraph/affected— file-level reverse-import closure. Sister to/risk: pass a SET of changed files (git diff --name-only), get back the test files transitively affected. Recall-oriented (catch every relevant test) where/riskis precision-oriented (highlight the few that matter most).
Cursor tolerance got real:
cursoraccepts<file>::<qname>,<file>.<qname>(.↔::), bare qname (global lookup), case-insensitive fallback, and<file>:<line>with ±5 line fuzzing. Misses come back with acursorResolutionblock listing suggestions, so the LLM can retry instead of silently dropping the strongest seed.Degraded responses always return 200 +
degradedReason, never 5xx —coedit-unavailablefor squash-style projects (coedit now auto-falls back to merge-granularity),analytics-warmingwhile the index precomputes in the background.cock affected— for selective test runs# Inside your project: git diff --name-only main | cock affected --stdin # newline-separated test paths git diff --name-only | cock affected --stdin --as-jest # → `jest "a.test.ts" "b.test.ts" …` cock affected src/auth.ts --filter "**/*.e2e.ts" # restrict to e2e cock affected --stdin --json # full byInput + statsThe CLI is a thin shim over
/api/projectGraph/affected— it shares the live CodeIndex (no per-invocation parse), exits1when no tests are affected (so you can short-circuit in a Makefile), and3when Cockpit isn't running.✨ New:
cock terminalreshaped as a read-only log analyserThe terminal CLI used to dump the whole ring buffer on every read — fine for humans, a flood for AI agents trying to analyse a
npm run devlog. It's now four self-describing subcommands:cock terminal list # discover terminals cock terminal <id> # status + full cheat sheet (entry point) cock terminal <id> output [flags] # read + filter + cursor cock terminal <id> wait <mode> [flags] # block until pattern / idle / exit / timeoutServer-side filtering —
--grep,--since,--around,--tail,--head,--max-bytes— runs against the buffer; you only ship the bytes you actually want. A monotonic global line counter stays stable across ring-buffer churn and server restarts, so--since <lineno>keeps working even after the oldest lines have been evicted (the response tells youfirstAvailableandtruncatedso you can detect the gap).AI-friendly defaults: ANSI stripped and
\rcollapsed by default (turborepo's\r\r\nno longer empties every line). Pass--keep-ansi/--keep-crwhen you want raw bytes.The write-side intentionally goes away: no more
stdin/kill/signal/follow. If you need to spawn a process, that's the Bash tool's job. If you need to drive an interactive REPL, use the web UI. The CLI is purely for observing running processes.End-to-end example used during development:
cock terminal list # find the make admin id cock terminal <id> output --grep '"level":"error"' # 3 lines, global line numbers cock terminal <id> output --around 4127 --context 10 # context around the first DrizzleQueryError cock terminal <id> wait idle --timeout 30s # block until quiet📚 Docs:
/cgslash command extendedThe
/cgexploration mode prompt now teaches the four new endpoints in the same voice as the original six — including therelations/signals/tagsvocabulary, theambiguousIndisambiguation hint, thecoeditecho onrisk/related, and the difference between risk (analysis, precision) and affected (CI, recall). Both Chinese and English bodies updated.📦 Misc
Two new runtime dependencies —
graphologyandgraphology-communities-louvain— pull in Louvain community detection for thesibling-in-communityrelation. Both are pure JS, no native bindings, no model files; the analytics layer remains zero-training, zero-network.v1.0.213
May 23, 2026 · v1.0.213View on GitHub ↗✨ New: /ex and /go slash commands
Two new builtin discussion modes join the existing
/qa,/fx, and/cgfamily:-
/ex— structured analysis. A heavier sibling of/qa: complexity check first, then a 6-step skeleton (problem study → diverge → converge → diverge again → iterate-verify → summarize) with What/Why/How threading through. Designed for problems that span multiple modules or have several candidate solutions to weigh. Does not ask back mid-flow — emits⚠️ Pending:markers when information is missing. -
/go— landing mode. The implementation counterpart to/ex: take a converged plan, slice it into minimum-deliverable-verifiable stages, write code + self-verify per stage, no per-stage sign-off, end-to-end recap at the very end.
Type
/in the chat to see them in the autocomplete dropdown.📦 Misc: slash command housekeeping
A few cleanups that surface in small ways:
- The autocomplete dropdown no longer lists
/commit//review//test//fix//explain//refactor— those were nominal entries with no server-side expansion (they silently passed through to the model verbatim). If you typed them, they still work as plain text; the dropdown just won't suggest them. - Cockpit no longer reads slash commands from
~/.claude/commands/*.mdor.claude/commands/*.md— Claude Code's commands convention is retired. If you want a custom shortcut, drop a SKILL.md and add it via the Skills sidebar instead. - Builtin command descriptions in the dropdown now follow the UI language (zh / en) — previously always English.
- Chat input placeholder hints "ESC 取消" / "ESC to cancel" while a response is generating.
🐛 Fix: DiffView row collapse
The diff view in the file explorer occasionally rendered the bottom of long diffs with rows stacked on top of each other ("已隐藏 N 行" labels overlapping). The cause was a virtualizer measurement-cache feedback loop that closed when a panel visibility flip or a shared
measureElementref produced a 0-height read. Row inline heights now floor to the row-type estimate, so a transient 0-height never gets re-cached.-
v1.0.212
May 22, 2026 · v1.0.212View on GitHub ↗🌐 Rebrand: OpenCockpit at opencockpit.dev
Cockpit's public surface area is now OpenCockpit, served from https://opencockpit.dev. The old
cocking.ccdomain is retired across README, the marketing site, sitemap, and Chrome extension links — update any bookmarks.README leads with a sharper headline:
The open Claude Code GUI for any agent — One seat. One AI. Everything under control.
(中文站同步:开源 Claude Code GUI,兼容任意 Agent)
The "Comparison" section in the README has been dropped; the page focuses on what cockpit is, not what it isn't.
📦 Misc: nothing changes under the hood
The rebrand is external only. None of the things you depend on day-to-day moved:
npm install -g @surething/cockpit # same package cock # same CLI ls ~/.cockpit/ # same config dir echo $COCKPIT_PORT # same env varsThe repo stays at
Surething-io/cockpit. If you've scripted anything against the CLI or env, no changes are needed.v1.0.211
May 22, 2026 · v1.0.211View on GitHub ↗✨ New: CodeGraph — give the AI a query graph, not a
grepThe same tree-sitter call-graph that powers Code Map (the chip view in Explorer) is now queryable as a set of HTTP endpoints, and reachable from any chat via the new
/cgslash mode. The agent stops drivinggrepand starts asking the project a graph six different ways:search— where is a symbol defined?callers/callees— who calls it, and what does it call?impact— what does changing it ripple out to (BFS, depth-capped)?file— what symbols does a file contain (no full read)?coedit— what files get edited together with this one (git history + working tree)?
That last one is the one
grepcould never give you. It catches the conventional couplings static analysis can't see — parallel registries, double-write tables, sibling.mdconfigs that humans always remember to update together until the day they don't. The agent now flags them by default when you ask about impact.Endpoints return coordinates only (file / line range / qname / kind / params), never source — the agent fetches source with a precision
Read offset=startLine limit=…after locating, so context budget stays bounded.Type
/cgin any Cockpit chat. No install, no config. Read the long version in What is a Code Graph (and why your AI needs one).✨ New: Slash command hint in the chat input
The placeholder no longer just says "
/for commands". It now shows the actual command shape:/qa /fx /cg /skill-name … for commands— three builtins by name, the skill-name pattern as a template, and an ellipsis hinting at more. Three layers of information in one line; new users learn the surface without opening a menu.📝 Website: new section + blog post
cocking.ccgets a dedicated CodeGraph section (sibling to Code Map) and a new blog: "What is a Code Graph (and why your AI needs one)" / "Code Graph:给 AI 一张项目图谱" — both languages. The story version of whygrepis the agent's ceiling on the questions that actually matter, with the BUILTIN_COMMANDS-style "I shipped without updating the second registry" anecdote made small enough for non-technical readers.🧹 Branding cleanup:
Codegraph→CodeGraphThe user-facing brand name is now consistently CodeGraph (PascalCase, matching
Code Map). Internal identifiers untouched: the/cgcommand name and the/api/projectGraph/*URL paths stay as technical IDs.🛠️ Dev-only: website builds on Next 16 again
website/package.json'sdev/buildscripts pin webpack explicitly (env -u TURBOPACK … --webpack). Next 16 made Turbopack the default and the oldTURBOPACK=empty-value opt-out stopped working; on this monorepo Turbopack panics on@import "tailwindcss". Webpack is the same bundlercockpititself uses for prod, so the fix just bringswebsite/back in line.v1.0.210
May 21, 2026 · v1.0.210View on GitHub ↗✨ New: New chats land at the end of the tab strip
Opening a fresh chat from the + menu (Claude Code / Claude 2 / Codex / DeepSeek / Kimi / Ollama) or from the sidebar's session list now appends the tab to the end, instead of inserting it next to whatever you had active. Switching engines mid-thread no longer breaks your tab layout in two.
Fork keeps the old behavior — a forked chat still lands right next to its parent, because that adjacency is the point of forking.
✨ New: Rerun an exited terminal where your eyes already are
Exited PTY bubbles in the Console panel show a center-mounted Rerun hint on hover now. The action used to live in the top-right corner of the black xterm chrome where nobody could see it.
🐛 Fix: DiffView search no longer expands to the whole line
When you selected text inside a DiffView and hit search, the query used to silently expand to the entire enclosing line. We've split the selection-toolbar payload in two:
selectedText— the literal selection, used for Search and DB snapshotslineSnapshot— line-expanded text, used only for preview cards and AI context
The same root cause also dropped the literal selection from comments created via CodeViewer / DiffView / Interactive Markdown — those now correctly persist the exact text you highlighted.
📦 Misc: 15 CVE patches via Next / ws / brace-expansion
Patch-level dependency bumps that clear 15 CVEs without any API surface change:
- next
16.2.4 → 16.2.6— 13 CVEs across middleware bypass, SSRF over WebSocket upgrades, cache-component DoS, CSP-nonce XSS, cache poisoning, and image-opt DoS. The website (cocking.cc) is the public-internet exposure surface for these. - ws
8.19.0 → 8.20.1— uninitialized memory disclosure - brace-expansion
5.0.5 → 5.0.6— large-numeric-range DoS bypass
npm auditreports 0 vulnerabilities across root, website, and e2b manifests.v1.0.209
May 21, 2026 · v1.0.209View on GitHub ↗✨ New: Save-or-stay on file switch
Switching files mid-edit no longer silently drops unsaved changes. With a dirty editor, Cockpit prompts Save and switch vs Cancel — pick Cancel and you stay on the current file with the edit intact. Clean editors switch instantly as before.
Bonus: vi-mode mutations (
yyp,dd,x, …) in normal mode now auto-promote the viewer into edit mode and mark the file dirty, so Save, Cmd+S, and the new switch prompt all treat them as real unsaved edits. The caret lands near the vi cursor on entry.✨ New: Chat tool list keeps its header reachable
Single-tool calls in chat used to render inline and hide the tool-list header — the bar that holds AskUserQuestion, FileDiff, and the other interactive entry points. The list now always collapses, and the single-tool case is expanded by default, so you keep the content visible and the header always sits where you expect it.
🌐 Site: positioned for any agent, not just Claude
cocking.cc and the README have been rewritten around "Claude by default — bring any agent you want." A new Engines section on the landing page covers Claude, OpenAI Codex, DeepSeek, Kimi, and Ollama side by side; the hero badge reads
Claude · Codex · DeepSeek · Kimi · Ollama; the README pain table, comparison table, and use-cases pick up the same framing (cheap second opinion, Ollama air-gapped, …). The npm package description and keywords broaden too, so@surething/cockpitnow turns up in npm search for more than just "Claude."UI labels normalize DeepSeek (a few places still spelled it "Deepseek"); code identifiers are intentionally left as-is to keep diffs small.
🐛 Fix: no more
[object Object]on error screensThe recent Effect-runtime overhaul changed every API route's error shape to a structured object, but every client error path was still doing
new Error(data.error || …)— whichString()-ifies an object into the literal[object Object]. That's what users were seeing on the Postgres bubble's "connection failed" screen, on SQL execution failures, and on roughly every other route's error display.Server-side,
errorToResponsenow serializes errors as{ error: <string>, tag: <_tag> }, extracting a real message frome.message,cause.message, or the error's typed fields in that order. Client-side, a defensive helper handles the old object shape too, so a future regression can never reintroduce[object Object]in the UI. Real database / filesystem / agent error messages everywhere again.🐛 Fix: DiffView no longer garbles rows after panel switch
Diff rows could collapse into each other vertically after the sequence open a diff → swipe to Chat → have the agent edit the file a few times → swipe back — the row-overlap / "garbled diff" symptom. Root cause was the virtualizer keying its measurement cache by array index, so a freshly rebuilt diff could reuse a sibling row's stale ~0 height; the misaligned render frame between plain-text and tokenized highlight then pinned the bad measurement.
Three layered fixes land together:
useLineHighlightnow derives the plain-text fallback synchronously from the current input viauseMemo, removing the render frame where state could disagree with input.- The virtualizer gets
getItemKeyso rows are keyed by identity (gap id, or L/R line number) instead of array position — cross-build cache reuse can't pick up a sibling's measurement. - The cache reset on file change moves from
useEffecttouseLayoutEffect, closing the timing window where ResizeObserver could write back into the just-cleared cache.
The original bug-report reproduction no longer shows overlapping rows.
v1.0.208
May 11, 2026 · v1.0.208View on GitHub ↗🐛 Fix: File-tree no longer flickers while files keep changing
If you opened the Explorer's search tab, typed a query, and then let an agent edit files in the background, the matching directories would visibly collapse and refill every ~3 seconds. Rows disappeared for a frame, spinners blossomed across many directories, and the tree re-populated in waves — the entire cycle repeating while file changes kept arriving.
The directory tree gets refreshed on every batch of file-watch events. That refresh re-fetches the whole tree from
/api/files/init, which only fillschildrenfor directories listed in the persistedexpandedPathsfile. Search-mode expansion is intentionally session-only and never persisted, so every refresh droppedchildrenfor everything you'd expanded via the search filter — the tree visibly collapsed, the safety-net effect then fan-out-fetched each missing directory, and you watched the tree re-grow row by row.The refresh now merges the new tree with the in-memory one instead of replacing it: directories the server didn't repopulate keep their existing children. No visible collapse, no spinner storm, no fan-out refetch.
🐛 Fix: Filename search no longer 500s in cwds with dangling symlinks
Searching for a query with no matches in a project that happened to contain a broken symlink (e.g. a stale
.claude/skills/<name>link pointing at a moved skill) blew up with a "Search failed" toast. Queries that did match worked fine — the asymmetry was the giveaway.ripgrep exits with code 2 whenever any walk-level error occurred during the scan (broken symlink with
--follow, unreadable subdir, …), independent of whether matches were returned from everywhere else. The previous guard only recovered the "exit 2 + non-empty stdout" branch and dropped "exit 2 + empty stdout" into the failure path. Both are now treated as no-match.🐛 Fix: Staged / unstaged trees fold independently
In the Changes pane, the staged and unstaged file trees shared a single collapsed-paths set — folding
src/on one side also folded it on the other. They each get their own fold state now.📚 Docs: New blog post
"Vibe coding needs a bit of taste" — a short essay on how the
packages/feature/*+packages/shared/*layout constrains the agent's blast radius and writing style. EN + ZH. Read it on cocking.cc/blog.v1.0.207
May 11, 2026 · v1.0.207View on GitHub ↗🐛 Fix: Diff view rows no longer collapse on file switch
In the git changes pane, switching between files could leave a stretch of rows visually stacked on top of each other — line numbers blurred together at one Y position, characters overlapping — until you toggled compact / full density or did anything else that re-ran syntax highlighting. The symptom showed up in both density modes and was easy to mistake for garbled rendering.
The diff viewer's virtualizer was reusing per-index row-height measurements across files. If any of those measurements got captured at zero height during a layout-jitter frame between the highlighter's plain-text and tokenized-HTML render passes, the bad value would pin itself there: the row outer div carries
height: ${size}pxinline, andref={measureElement}reciprocally confirms whatever the inline value already is — neither side ever disagrees, so nothing nudges the cache back. Re-running the highlighter happened to trigger a content-size change that woke ResizeObserver and overwrote the stale measurement, which is why users found that "switching density fixes it."Measurements now reset whenever the underlying diff content changes, alongside the existing gap-state reset.
v1.0.206
May 11, 2026 · v1.0.206View on GitHub ↗⚙️ Internal: DDD modularization of the codebase
Everything that was in
src/components//src/hooks/moved into 11 workspace packages underpackages/{shared,feature}/. The intent: when AI works on chat, it loadsfeature-agent; on file browser,feature-explorer; etc. — not the whole monolith.src/is now just Next.js routing + the WebSocket server bootstrap.Six feature packages — each is self-contained client + server code:
feature-agent— chat domain (Claude / Ollama / Codex / Kimi / Deepseek), scheduled tasks, slash commandsfeature-comments— code annotation API + hooks (new)feature-console— terminal + browser bubbles + DB bubbles (Postgres / MySQL / Redis / Neo4j / Bash / Jupyter)feature-explorer— file browser + code rendering (DiffView, CodeViewer, MarkdownPreview, PreviewModal) + git + LSPfeature-review— review pages with anchored highlights and threaded comments (new)feature-skills— SKILL.md parser + slash autocomplete + cross-frame bus (new)feature-workspace— application integrator (Workspace, TabManager, Providers, cross-feature modals)
Plus three shared packages:
shared-i18n(i18next + the full translation dictionary),shared-ui(UI primitives + generic React hooks),shared-utils(paths / platform / shortId).Dependency rule, ESLint enforced:
feature-*may import otherfeature-*(supporting-subdomain pattern, kept acyclic) andshared-*;shared-*is a leaf layer (cannot import@cockpit/*). SeeMODULES.mdfor the full architecture doc.HTTP route handlers are now Web standard
Request/Responseeverywhere —NextRequest/NextResponsedropped from 108 files (~670 substitutions across.json(...),new ...(...),req.nextUrl.searchParams, type annotations, andnext/serverimports). Future Hono / Bun / Deno migration is a thin adapter layer instead of a rewrite.i18n: the full translation dictionary moved to
@cockpit/shared-i18nas a singleton; dropped the IoC translator slot inshared-ui. Same translations, fewer levels of indirection.🐛 Fix: prod install +
/api/versionThe DDD refactor accidentally listed 9 private workspace packages in
dependencies, which madenpm install @surething/cockpitfail withERR 404 @cockpit/feature-agent@*— they don't exist on the registry. They're nowdevDependencies(needed for build, not for users);dist/wsServer.mjsanddist/scheduledTasks.mjsinline their contents at bundle time, mirroring what Next.js'stranspilePackagesalready does for.next-prod/. No runtime resolution happens against the (missing)node_modules/@cockpit/*path./api/versionused to readpackage.jsonfromprocess.cwd(). In Next.js's prod runtime that effective cwd is/, so the endpoint silently returned{"version":""}. Now reads fromprocess.env.COCKPIT_ROOT, whichserver.mjssets to the installed cockpit package root at boot.📦 Misc: drop unused tooling
Storybook + Vitest + Playwright + 10 supporting
devDependenciesremoved — they hadn't been part of the workflow for months.npm installis faster and lighter; one less dependency surface to keep patched.v1.0.205
May 9, 2026 · v1.0.205View on GitHub ↗🐛 Fix: fresh installs failed to start
@vscode/ripgrep1.18 split its platform binaries into per-arch packages (@vscode/ripgrep-darwin-arm64/bin/rgetc.) and stopped shippingbin/rgfrom the main package. Cockpit had hand-built a path offprocess.cwd() + node_modules/@vscode/ripgrep/bin/rg, which ENOENT'd on any freshnpm i -gthat resolved 1.18+:Error: spawn .../node_modules/@vscode/ripgrep/bin/rg ENOENTSymptoms in 1.0.204 were "search returns nothing" and "file index never builds" right after install — without obvious crashes. We now resolve via the package's own
rgPathexport, which handles both 1.17 (binary in main) and 1.18+ (binary in platform sub-package) layouts.@vscode/ripgrepis also added toserverExternalPackagesso its internalcreateRequire(import.meta.url)resolution stays correct under webpack.If you hit this in 1.0.204, upgrading fixes it — no manual reinstall needed.
✨ New: smarter compact-diff gaps
The
··· lines hidden ···bar in compact diff mode got a UX rework after user feedback on v1.0.204's bidirectional+Ncontrols.··· more +20 ··· ← click to reveal 47 lines hidden · loginHandler(req, res, next) ← gap label ··· more +20 ··· ← click to reveal- Function context — gap label now shows the enclosing function signature, mirroring the chip-view header. Driven by
useFileFunctions; read-only, doesn't change expansion behaviour. - Three explicit rows — top/bottom expand rows are real
<button>s, position implies direction. No more chevron icons that didn't read as clickable. - Honest reveal counts —
··· more +20 ···clamps to actual remaining lines per side, so the label never overshoots what you'll see. - Drift fixed — virtualized rows now self-measure on entry (
measureElement+data-index), so cumulative scroll error toward file bottom no longer compounds as you click. - No more animation collisions —
transition-allwas sweeping up the virtualizer'stransform: translateY(...)on every state change, briefly overlapping diff rows during reveal. Replaced withtransition-colors; transform changes are instant. - Focus rings stay inside the button — was painting 2-3 px outside the box, visibly spilling onto the line above.
📦 Misc: security dep refresh
Lockfile refreshed to pull patched transitive deps under
@modelcontextprotocol/sdk@1.29.0, closing 8 dependabot alerts:hono4.12.15 → 4.12.18 — CSS injection in JSX SSR, cache cross-user leak via missingVaryhandling, JSX tag HTML injection,bodyLimitbypass on chunked requests, JWT NumericDate validationfast-uri3.1.0 → 3.1.2 — host confusion, path traversal via percent-encoded segmentsip-address10.1.0 → 10.2.0 — XSS in Address6 HTML-emitting methods (pulled in viaexpress-rate-limit8.4.1 → 8.5.1)
All bumps stay within caret ranges already declared by MCP SDK;
package.jsonitself unchanged.- Function context — gap label now shows the enclosing function signature, mirroring the chip-view header. Driven by
v1.0.204
May 8, 2026 · v1.0.204View on GitHub ↗✨ New: Compact diff in git-changes file mode
Opening a changed file in git-changes view now collapses unchanged stretches GitHub-style. Only the changed lines and 3-line context render; everything in between becomes a clickable bar.
↑/↓arrow buttons on each bar reveal +20 lines per click, clamped to remaining- Scroll position stays anchored — your viewport content doesn't jump as the bar grows; new lines slide above/below the bar in place
- The bar's hunk-header label tells you the function the next change lands in:
47 lines hidden · loginHandler(req, res, next) - A
Compact/Fulltoggle at the top of the diff brings back the whole-file view for the moments you want it
Mapmode (the chip view) was already compact-by-design and is unchanged. The compact treatment is opt-in via thecompactprop onDiffView, so other diff surfaces (the AI-edits modal, commit-history detail) keep their full-file behaviour.🐛 Fix: Code Map chips stay current after file edits
The project-wide AST index that powers Code Map was built once per project and never refreshed automatically. After editing a file (yourself or via the agent) and reopening it in Code Map, you'd see chip headers naming functions whose bodies no longer matched what was rendered, missing newly-added functions, or stale entries for ones you'd deleted.
Per-request the file's on-disk
mtimeis now checked and the focal file alone is re-parsed when stale (~10–50 ms). The full project rebuild — which takes seconds on monorepos — is reserved for the manual "Rebuild project graph" button, so editing a file no longer puts the chip view behind a long loading spinner.🐛 Fix: Ollama tool-only turns no longer error out
Ollama's OpenAI-compatible endpoint rejects assistant messages with
content: null— the canonical shape for "I called a tool, no text". Sessions with many tool-only turns died on the next continuation withAI_NoOutputGenerated. Cockpit now coercescontent: null → ""right before the request leaves; existing transcripts and other providers (Claude / DeepSeek / Kimi) are unaffected.🐛 Fix: Code Map navigation no longer animates
Click-to-jump in Code Map (TOC row, caller/callee pin, history drawer entry, Cmd+K result, minimap tick) used to smooth-scroll over ~250 ms. With dozens of jumps per minute that adds up to several seconds of "watch the page slide". Switched to instant — VSCode / JetBrains / Cursor / Zed all do the same. The
.line-flashpulse on arrival still fires, so the "you're here" feedback is unchanged.📦 Misc: Unified tooltip system
The codebase had three concurrent tooltip implementations (native
title=, a Portal-based component, manual delegation). Hovering a function name in one panel looked different from hovering one in another. Consolidated into a single global provider — everydata-tooltipor<Tooltip>now produces the same brand-bordered monospace popover. Function names in the Code Map sidebars, file paths in the diff toolbar, and comment markers all share the same styling.v1.0.203
May 7, 2026 · v1.0.203View on GitHub ↗✨ New: file TOC sidebar in Code Map
Open any file in Explorer → Code Map and you'll now see a narrow sidebar on the left listing every function / class / method in the file, in source order. Click any entry to flash and scroll-into-view its chip; the function whose lines currently straddle the viewport center renders highlighted as you scroll, doubling as a passive "you are here" indicator.
Drives the moment you'd previously reach for Cmd+K just to scan what's in a file: typing a name is great when you know it, but onboarding into an unfamiliar repo wants a visible index. The sidebar is paired with the existing right-side navigation history (where pin clicks accumulate) — left = "what's in this file", right = "where I've been across files".
The TOC filters to call-graph nodes only (
function/class/method), so compile-time-only types and the synthetic chunks the chip canvas uses to keep every line visible (interface,type,__imports__,__code_*__, etc.) are kept off the index.🐛 Fix: Cmd+K palette now scrolls to the matched symbol
Picking a symbol from the Cmd+K palette used to drop you at line 1 of the target file — the hit's line number was being ignored. Now the chip view scrolls to the symbol's line and pulses it on arrival, including across-file jumps (the focal change kicks off the file load, then the flash fires once the new file's blocks have rendered).
🐛 Fix: chip-diff renders top-level code changes
Commits that ONLY touched top-level expressions — middleware setup,
dotenv.config(), module-levelapp.listen(...)— used to render an empty chip-diff panel. The projection's stale-qname filter was dropping the synthetic blocks those edits land in (__code_*__), so the diff had nothing to surface. The projection now also runs a line-overlap pass: any synthetic block whose line range contains a changed line gets surfaced in chip-diff, the same way real function changes do.🐛 Fix: chip-diff minimap thumb aligns with the change runs
After filtering to changed-only chips, the right-side minimap's thumb (where you are) and its green change stripes (what changed) used to disagree visually — they were positioned in file-line space, but the chip canvas only renders a sparse subset of file lines, so the thumb at canvas-top would sit at ~5% of the minimap while changes lived at 50%, 80%, etc.
The minimap now positions everything in rendered-line space: minimap-top = canvas-top, minimap-bottom = canvas-bottom, and the thumb visibly sits on the change run currently in view. Click-to-jump still resolves to the precise line.
v1.0.202
May 6, 2026 · v1.0.202View on GitHub ↗✨ New: the chip view has a name — Code Map
The chip view shipped in v1.0.198: every function rendered as a card with caller pins on the left, callees on the right, click to walk the call graph. Until now it was awkwardly labelled
Block/代码块in the toolbar — a holdover from how the components are named internally. This release renames it to Code Map / 代码地图 everywhere a user can see it.- File Browser toolbar: the third reading-mode button (Edit / Blame / Code Map) opens the chip view
- Git Changes diff toggle: File / Map instead of File / Block
- Empty state, loading, and unsupported-file messages all unified
- Internal state is now
'code' | 'map'end-to-end, matching the rest of the file browser
No behavior changes — same view, consistent name. Component / hook / file names stay
BlockViewer,BlockDiffViewer,BlockDiffMinimapetc., because internally a Code Map is composed of per-function "blocks" / chips. Those names describe the primitive, not the user-facing feature.🐛 Fix:
/trycooldown no longer dumps raw JSONThe "Start Demo" button on cocking.cc/try was a plain
<a href>— a full-page navigation. When the function hit its 5-minute cooldown and returned{"error":"Please wait 280s..."}, the browser navigated to that JSON response and rendered it as raw text. Worse, if the user clicked while a slow sandbox-create was already in flight, the working sandbox URL would arrive after the user had left the page and get lost.The button now
fetch-es withAccept: application/json. On success it navigates to the sandbox; on cooldown or error it shows a toast and re-enables the button so you can retry. No-JS fallback via<noscript>still works.🌐 Site: Code Map on cocking.cc + new blog post
Code Map is now advertised on the homepage and gets its own user-perspective walkthrough in the blog:
- New homepage section between Bubbles and Modes — chip view + caller/callee pins explained from a usage angle
- New post "Read code as a map, not a tree" (中文) — five real moments where Code Map saves time: day-one in a new repo, following a call you don't trust, reviewing AI-generated PRs, tracing a bug, reading code with no LSP
- README updated (EN + ZH): Code Map added to the Explorer features list, the pain table, and the use cases
v1.0.201
May 6, 2026 · v1.0.201View on GitHub ↗🐛 Fix: chip view server-side
createRequire is not a functionv1.0.200's webpack
DefinePluginkilled the spurious createRequire call in the browser bundle, but the same error then surfaced server-side when opening 代码块 / Code Map:[projectGraph/file-functions] failed: TypeError: createRequire is not a functionweb-tree-sitter's ESM bundle doesawait import("module")inside its Node-detection branch. With the package bundled into Next.js's server chunks,import("module")was getting rewritten as__webpack_require__.t.bind(...)— webpack's namespace wrapper for a Node-builtin shim doesn't preserve enumerable static properties cleanly across mode-19 dynamic imports, so destructuring{ createRequire }yieldedundefined.Fix: add
web-tree-sittertoserverExternalPackagesso it's loaded at runtime via Node's actual ESM resolver.import("module")then hitsnode:moduledirectly andcreateRequireis the real Node function. The browser-side dead-code fix from v1.0.200 stays in place; both sides now correct independently.npm install -g @surething/cockpit@latestv1.0.200
May 6, 2026 · v1.0.200View on GitHub ↗🐛 Fix: chip view crashed in prod with
createRequire is not a functionAfter the v1.0.198 / v1.0.199 install path was fixed, opening the 代码块 / Code Map chip view in a prod build threw:
Uncaught (in promise) TypeError: createRequire is not a functionweb-tree-sitter's ESM bundle has a runtime Node-detection branch that callscreateRequireonly when it thinks it's running in Node:var ENVIRONMENT_IS_NODE = typeof process == "object" && process.versions?.node && process.type != "renderer"; if (ENVIRONMENT_IS_NODE) { const { createRequire } = await import("module"); var require = createRequire(import.meta.url); }Next.js's webpack browser polyfill exposes
process.versions.node, so the gate evaluated truthy in the browser and the dynamicimport("module")resolved to our empty stub —createRequirewas undefined.This release adds a webpack
DefinePluginrule for the browser bundle that foldsprocess.versionsto({})andprocess.typeto"renderer"at compile time. The if-condition then collapses tofalsy && void 0 && false≡ undefined, so the Node branch never runs in the browser. Server bundle is untouched.Same v1.0.198 / v1.0.199 changes ship in this release; just the build now actually loads in production.
npm install -g @surething/cockpit@latestv1.0.199
May 6, 2026 · v1.0.199View on GitHub ↗🐛 Fix: v1.0.198 install was broken
v1.0.198's
postinstallimportedscripts/copy-tree-sitter-wasms.mjsfrom a path that wasn't in the published tarball, so everynpm installof v1.0.198 failed withERR_MODULE_NOT_FOUNDand rolled back. The script is now included in the package'sfilesmanifest.If you tried to install v1.0.198 and saw that error, install v1.0.199 — it ships the exact same v1.0.198 changes (Code Map / multi-language chip view / ollama language fix / scheduler double-dispatch fix / terminal phantom-character fix / git-changes fold-state fix), with
npm installactually working.npm install -g @surething/cockpit@latestFor the full list of new features in this release, see v1.0.198.
v1.0.198
May 6, 2026 · v1.0.198View on GitHub ↗✨ New: Code Map
A new architectural view sits inside the file/diff browser. Every function in the focal file renders as a chip with caller/callee pins on the sides; clicking a pin jumps to the other end across files. In diff mode the same component overlays line-level changes and adds a navigable mini-map on the right.
Six languages out of the box: TypeScript, TSX, JavaScript, Python, Go, Rust.
The chip header now shows the function signature inline:
loginHandler(req, res, next)Go method receivers (
func (u *User) Bar()) re-parent underUser. Rust&self/&mut self/selfare preserved verbatim. Multi-name params (Gofunc(a, b int)) flatten correctly.Behind the scenes, codeMap is built on a pluggable
LanguageHandlerinterface — adding a new language is "write a handler + add one barrel import"; the orchestration layer stays language-agnostic.🐛 Fix: ollama replies in your language
Local ollama models (qwen3.5 and friends) were biased into English replies regardless of the user's input language. The system prompt now explicitly instructs the model to mirror the user's most recent message, with carve-outs for tool "thought" templates, code, paths, and tool-output quotes so the existing PREVIOUS / THIS / EXPECT protocol stays intact.
🐛 Fix: terminal phantom characters (continued)
v1.0.195 stopped primary Device Attributes replies (
0;276;0c) from leaking into shell prompts. Idle-prompt re-probing turned out to use secondary (\x1b[>c) and tertiary (\x1b[=c) DA, which slipped through the first fix. Cockpit now blocks all three variants plus DEC private DSR for symmetry — no more0;276;0cdebris on the prompt after the shell has been idle.🐛 Fix: scheduler double-dispatch → no more rate-limit trips
Next.js custom-server was loading
scheduledTasks.tstwice in one process — once via Node ESM, once via webpack — so every cron tick ran two timers per task and tripped Anthropic's burst rate limit on each fire. Singleton state is now pinned toglobalThis(same pattern as the existingPgPoolManager); dual-realm dispatch is no longer possible. Same fix applied to file watcher, WS server, and the browser-bubble bridge.🐛 Fix: tree fold state in git changes
Refetching git status (file watcher, visibility change, manual refresh) was unioning every directory path back into the expanded set, so any folder you just collapsed re-expanded within the next debounce window. Fold state now persists across refetches: only paths you actually click stay collapsed.
📚 Docs: DeepSeek in Cockpit
New blog post on https://cocking.cc/blog/ walking through pasting an API key, picking a model, and which Claude workflows transfer to DeepSeek wholesale. Bilingual EN / ZH per repo convention.
v1.0.197
Apr 29, 2026 · v1.0.197View on GitHub ↗⚙️ Internal: release pipeline as Skills
Captured the v1.0.196 release flow as two project-internal Cockpit Skills under
skills/:/cockpit-release [patch|minor|major]— runs the full pipeline: pre-flight checks →npm version→ push tag → watch the publish workflow → verify npm → invoke/cockpit-changelogfor release notes → manually trigger a website redeploy (the publish workflow does not rebuild the site) → verify the changelog page./cockpit-changelog [from-tag] [to-tag]— drafts release notes in the project's voice from a commit range, written to/tmp/release-notes.mdfor human review beforegh release edit.
Documentation only. Not shipped in the npm package (
skills/is not inpackage.json#files), so this release changes nothing for@surething/cockpitCLI users — it's for whoever cuts the next release.v1.0.196
Apr 29, 2026 · v1.0.196View on GitHub ↗✨ New:
cockpitcommand (full-name alias forcock)Both
cockpitandcocknow ship with the package and point at the same code path. Use whichever you prefer — the docs and help output have been switched tocockpit(easier to share in talks, Slack, and Show HN screenshots), but the shortcockalias keeps working everywhere for muscle memory.npm i -g @surething/cockpit@latest cockpit # new cockpit -h cockpit browser <id> snapshot cock # still worksSubcommand help (
cockpit browser --help,cockpit terminal --help) now consistently uses thecockpitprefix in usage examples.🌐 Marketing site SEO overhaul
cocking.cc shipped a major SEO + content pass:
- New
/blogroute with long-form posts (en + zh): - 1200×630 OG image, robots.txt, sitemap.xml (16 URLs with hreflang), JSON-LD (
SoftwareApplication,WebSite,BlogPosting). - Plausible analytics support (opt-in via env var).
📚 README + GUIDE rewrites
Top-level docs got badges, a "Why Cockpit?" pain-vs-solution table, a comparison vs raw CLI / IDE plugins / Aider, five concrete use cases, and links into the blog. Bilingual:
README.md/README.zh.md/GUIDE.md/GUIDE.zh.mdall in sync.📦 Package metadata
- Description rewritten to lead with the actual category ("Claude Code GUI for parallel AI coding").
- Keywords expanded from 4 to 25 (claude-code, claude-agent-sdk, ai-coding, multi-project-ai, etc.) — surfaces on npm search.
- Homepage now points at https://cocking.cc.
- New
v1.0.195
Apr 29, 2026 · v1.0.195View on GitHub ↗✨ New: Deepseek engine
Talk to DeepSeek models directly from cockpit, alongside Claude / Codex / Kimi / Ollama.
- Pick Deepseek from the new-tab dropdown
- Click the picker in the chat header to paste your API key (saved locally in `~/.cockpit/settings.json`) and switch between models:
- `deepseek-v4-pro` (default)
- `deepseek-v4-flash`
- Sessions are kept in `~/.cockpit/deepseek/` so they don't mix with your existing Claude history or credentials
- All the normal goodies (file edits, bash, web search, slash commands, sub-agents, …) work as on Claude
Get a key from https://platform.deepseek.com/api_keys, paste it into the picker, send a message — done.
🔄 Retry visibility
When the upstream API hiccups and the SDK silently retries (transient 401, rate limit, 5xx), you now see it: an amber line under "thinking…" shows attempt N/M, delay, and error reason in real time. No more wondering why a response feels slow.
🐛 Terminal: no more phantom commands
Fixed a long-standing bug where running certain CLI tools left the shell spitting out things like:
``` zsh: command not found: 11 zsh: no such file or directory: rgb:0000/0000/0000 ```
Cockpit's terminal now swallows OSC color / DSR cursor-position / Device Attributes queries so a misbehaving child can't poison the parent shell's input.
v1.0.194
Apr 29, 2026 · v1.0.194View on GitHub ↗🌐 Website: Slash Modes, Skills, real screenshots
cocking.cc got three upgrades:
- Slash Modes section showcasing the built-in
/qa,/fxworkflows - Skills surfaced in the Extras section
- Placeholder cards replaced with real product screenshots
🐛
/fxnow appears in autocompleteTyping
/shows/fxalongside the other built-in commands (was missing before).- Slash Modes section showcasing the built-in
v1.0.193
Apr 29, 2026 · v1.0.193View on GitHub ↗🌐 cocking.cc is live
First cut of the public marketing site at https://cocking.cc — landing page introducing cockpit's three-panel layout, browser automation, and slash workflows.
🐛 Panels: overlays follow swipes
Modals and popovers inside the three-panel UI (Agent / Explorer / Console) now correctly stick to the panel you're on when you swipe. No more orphan menus drifting into the wrong panel.
v1.0.192
Apr 26, 2026 · v1.0.192View on GitHub ↗✨ Terminal sessions survive page refresh
Reload the page and the Console terminal replays its last screen — running commands keep running, scrollback comes back, no more starting from a blank prompt.
🐛 Git Changes: fresh image previews
Image diffs in the Git Changes tab no longer show stale thumbnails after the file is updated.
v1.0.191
Apr 23, 2026 · v1.0.191View on GitHub ↗🐛 Better error message in `cock browser evaluate`
When your JS expression returns nothing (e.g. you forgot to add `return`), you now get a clear hint — instead of a confusing generic "no result".
v1.0.190
Apr 23, 2026 · v1.0.190View on GitHub ↗🐛 Cleaner CLI exit
`cock` and its subcommands no longer cut off the last line of output before exiting — error messages and logs now always print in full.
v1.0.189
Apr 23, 2026 · v1.0.189View on GitHub ↗✨ Skills sidebar
A new Skills entry in the sidebar lets you browse all your installed Skills and inject any of them as a slash command directly into the chat input.
✨ Chat tabs shrink-to-fit
Many tabs no longer overflow horizontally — they shrink to fit the available width while keeping the close button reachable.
🐛 Ollama: tools are non-blocking + truncation-aware
When Ollama uses Bash or Grep, the calls are now non-blocking and gracefully truncate huge outputs — no more long pauses or chat freezes on commands that emit megabytes.
v1.0.188
Apr 22, 2026 · v1.0.188View on GitHub ↗✨ Branch compare: HEAD vs. base, with one-click pins
The Git branch-compare UI now splits the source and target into two separate selectors. Common targets (
main,master, current branch's upstream) are pinned at the top so you don't have to scroll.v1.0.187
Apr 22, 2026 · v1.0.187View on GitHub ↗✨ Claude 2 engine — run two accounts in parallel
A second Claude engine that uses an independent config directory (
~/.claude2) so you can stay signed in to two Anthropic accounts at the same time (e.g. personal + work) and chat with each from a different tab.✨ Rate limit visibility
The Anthropic SDK's rate-limit info is now shown in the token usage bar — utilization %, reset time, and overage status. You can see at a glance how close you are to your quota.
Markdown math toggle
Math rendering in markdown is now opt-in per renderer (kept off in chat to avoid surprises with
\$...\$text).v1.0.186
Apr 11, 2026 · v1.0.186View on GitHub ↗✨ Built-in slash commands `/qa` and `/fx`
Two universal workflows built right into the chat:
- `/qa` — requirements clarification mode (asks before coding)
- `/fx` — bug evidence-chain analysis mode
Auto-localized: the prompt picks Chinese or English based on your UI language.
✨ Ollama: smarter agent loop for small models
The Ollama chat route was rewritten with a tool-design and UI tuned for weaker local models, so you get more reliable tool calls and reasoning even on 7B–14B class models.
✨ Unified session format across engines
All engines (Claude, Codex, Kimi, Ollama) now use a Claude-style transcript format under the hood, so chat history loads consistently no matter which model produced it.
🐛 Streaming + terminal fixes
- Fixed duplicated text appearing during streaming
- Fixed PTY garbled output in the Console terminal
- Jupyter bridge is now bundled correctly in production installs
v1.0.185
Mar 31, 2026 · v1.0.185View on GitHub ↗🐛 New Tab menu position fix
When you swiped to the Explorer or Console panel, opening the New Tab dropdown could land in the wrong place. The popover now anchors correctly regardless of which panel you're on.
v1.0.184
Mar 31, 2026 · v1.0.184View on GitHub ↗✨ Multi-provider chat: Codex, Kimi, Ollama
Cockpit no longer only talks to Claude. From the new-tab dropdown you can now pick:
- OpenAI Codex (uses your OpenAI account /
~/.codex) - Kimi (Moonshot)
- Ollama (local models, with a model picker in the chat header)
Each engine keeps its own session history and badge in the tab.
✨ Tool calls visible in Kimi
Tool invocations made by Kimi are now rendered in the chat just like Claude's — you can see what was called and what came back.
- OpenAI Codex (uses your OpenAI account /
v1.0.183
Mar 30, 2026 · v1.0.183View on GitHub ↗🐛 More reliable end-of-turn detection
The chat now decides "the assistant is done" based on whether a
resultmessage arrived, instead of guessing fromstop_reason. Fixes occasional cases where the spinner never stopped.🐛 ESC cancel: no more auto-continue
Pressing ESC to cancel a streaming response no longer triggers a stale "continue" retry afterwards.
v1.0.182
Mar 30, 2026 · v1.0.182View on GitHub ↗✨ Neo4j browser bubble
Open a Neo4j database directly in the Console panel — interactive graph visualization plus a schema browser for nodes, relationships, and constraints.
🐛 Cmd+V paste, scheduled task unread, compaction
- Cmd+V paste in chat now works reliably
- Scheduled tasks correctly mark sessions as unread on completion
- Long conversations no longer hang during the SDK's auto-compaction
🐛 No more duplicate user messages
Adjacent identical user messages are deduplicated when loading transcripts — your chat history now reads cleanly.
v1.0.181
Mar 28, 2026 · v1.0.181View on GitHub ↗Internal release — no user-facing changes.
v1.0.180
Mar 28, 2026 · v1.0.180View on GitHub ↗Internal release — no user-facing changes.
v1.0.179
May 22, 2026 · v1.0.179View on GitHub ↗✨ Try cockpit online — no install
A hosted demo via E2B sandbox lets you spin up cockpit in your browser to try it out, no local setup needed.
✨ Bind to a custom host
New `COCKPIT_HOST` env var lets you serve cockpit on a non-localhost address (e.g. for remote dev boxes).
🚀 Faster file search
File index and project-wide search are now both powered by ripgrep under the hood — noticeably faster on large repos.
📺 Promo video in README
Added a walkthrough video at the top of `README.md` / `README.zh.md`.
v1.0.178
Mar 26, 2026 · v1.0.178View on GitHub ↗✨ `cock <path>` to open a project
One-shot command to open any directory as a project:
```bash cock ~/Work/my-app ```
README also got a Prerequisites section.
v1.0.177
Mar 25, 2026 · v1.0.177View on GitHub ↗🐛 Sudo install: extension files owned by you
When installing globally with
sudo npm install -g, the chrome extension files are now chown'd back to your user — so you can load them in Chrome without "permission denied" errors.v1.0.176
Mar 25, 2026 · v1.0.176View on GitHub ↗🐛 Chrome extension auto-installs
The cockpit chrome extension is now copied to
~/.cockpit/duringnpm install, so the browser bubble works out of the box without manual setup.v1.0.175
Mar 25, 2026 · v1.0.175View on GitHub ↗First release tracked in the public changelog.