OpenCockpitOpenCockpit

Changelog

Release notes pulled from GitHub Releases.

  1. v1.0.221

    Jun 12, 2026 · v1.0.221

    ✨ 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 + /cr

    The builtin slash commands (/qa /fx /ex /go /cg /cc) now write their resolved prompt to ~/.cockpit/skills/<cmd>/SKILL.md and 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_*, so vim/less showed CJK and emoji as mojibake while ASCII looked fine. Bubbles now default to a UTF-8 locale and pass real LANG/LC_ALL/LC_CTYPE through when the server has them.

    🐛 Fix: PTY mode handles AskUserQuestion cleanly

    In PTY mode, a model reaching for the AskUserQuestion dialog is now blocked at the source by a PreToolUse hook 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.

    View on GitHub
  2. v1.0.220

    Jun 11, 2026 · v1.0.220

    ✨ 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 AskUserQuestion selector 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.

    View on GitHub
  3. v1.0.219

    Jun 10, 2026 · v1.0.219

    ✨ 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 claude session 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 ESC to 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 /docs page 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 inline code / bold in a heading no longer breaks its anchor id.

    View on GitHub
  4. v1.0.218

    Jun 1, 2026 · v1.0.218

    ✨ New: AI-friendly browser CLI (selector / wait / assert / lifecycle)

    Reframes cockpit browser from 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 verbose evaluate(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 buttons
    

    What's behind the changes:

    • Selector-first interaction. click --text / --selector and fill --selector work 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-side health so 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-step act + sleep + evaluate.
    • Backend probing. fetch <url> shortcuts the most common evaluate(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 --reload for atomic test isolation; set --type cookie|local-storage|session-storage (there's now a write side, not just read); status for 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-ms to tune, --skip-verify to bypass for known no-op clicks.
    • Better timeouts and stale-ref errors. Every error now carries an actionable next step. Timeout after 15000ms becomes Timeout (action "X"). Bridge state: ws=open pending=2 lastSuccess=12s ago. Diagnose: cockpit browser <id> health …. Element ref "e5" not found becomes Element 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 (Write tool, 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. syncDirtyIndex only iterated existing keys, and refreshFocalFile early-returned for unknown paths.

    Now the first focal query on an unknown file dispatches to a new addFocalFile helper (five guards: project-fileset membership via git ls-files, registered grammar, MAX_FILES soft cap, parse-success, fileset add). The analytics cache is also invalidated so risk / related / context routes pick up the new node on the next query. When the fallback path runs, the response carries notIndexed: true so 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: 4rem keeps 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:

    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).

    View on GitHub
  5. v1.0.217

    May 26, 2026 · v1.0.217

    ✨ New: Bubble titles + cockpit connection list for /cc agentic flows

    A pain point with /cc slash mode: the LLM sees 4-char short ids like bmfb / mpcw as 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}.json file. The schema is upgraded from a plain string[] to { order, titles } with a transparent legacy-shape read — no migration script needed, and the POST endpoint accepts partial patches (touch only order or only titles, 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 enumeration

    cockpit 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 scripting
    

    Output 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:3000
    

    Exit codes are standardised — 0=hits, 1=no bubbles, 2=usage, 3=server unreachable — so you can pipe it through shell control flow.

    /cc prompt teaches the workflow

    The /cc slash-mode prompt now instructs the model to call cockpit connection list --cwd $PWD before 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 the command / URL column.

    Prod/dev signalling clarified

    /cc now defaults to cockpit (prod) explicitly. The model switches to cockpit-dev only when the user gives an explicit signal — either writes cockpit-dev ... in the task, or starts the task with /cc dev .... No more ambiguous swapping.

    📚 Docs

    • README / GUIDE / docs/manual (en + zh) all gain a cockpit connection list line alongside the existing terminal / browser CLI examples.
    • docs/manual adds a dedicated ## 6.5 Connection Enumeration (CLI) section with output schema, exit codes, and the design rationale.
    • Bulk cleanup across docs/manual (en + zh): retired cock terminal / cock browser (~33 occurrences each) in favour of the recommended cockpit terminal / cockpit browser, with an explicit "(cock is the prod-only short alias)" note per CLI section.
    • CLAUDE.md Commands 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 symlinks cockpit-dev to local source for repo contributors) now resolves the global bin dir from process.execPath instead of npm config get prefix. The previous approach could resolve to a different directory under sudo because /root/.npmrc and HOME differ from the user's — process.execPath is unaffected. Set COCKPIT_BIN_DIR=... to override for non-standard layouts.
    • cockpit codegraph search now accepts --include-literals to forward the v1.0.216 server-side flag (it was teaching agents about the capability via /cg but 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 from README / GUIDE / docs/manual / the website's /docs page — those were retired back in v1.0.214 and users hitting "Unknown subcommand" had no way to know.
    View on GitHub
  6. v1.0.216

    May 26, 2026 · v1.0.216

    ✨ New: Naming-style-tolerant search + opt-in string-literal indexing

    searchIndex now 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 same
    

    Strict 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-case or SCREAMING_CASE for a given concept.

    ?includeLiterals=true — surface names that only exist as string literals

    Symbol-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=true
    

    Identifier-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 --help and the /cg slash command prompt both mention the new flag with an inline example.

    View on GitHub
  7. v1.0.215

    May 26, 2026 · v1.0.215

    ✨ New: cockpit codegraph — unified entry for all 10 graph endpoints

    v1.0.214 shipped 10 CodeGraph HTTP endpoints but only exposed cock affected at 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     affected
    

    Each subcommand has full --help with Usage / Purpose / Flags / Output / Stderr / Exit codes / Examples, so an LLM agent can pre-construct grep / awk pipelines without trial-and-error. --as-jest was 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: /cc slash mode — drive the cockpit CLI from chat

    Sister to /cg. Teaches the agent what cockpit / cock / cockpit-dev can do, pointing at each subcommand's --help as 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 /cg and /skill-name.

    ✨ New: cockpit-dev binary + setup-dev selective symlink

    cock-dev is renamed to cockpit-dev everywhere — symmetry with the prod cockpit / cock pair (no short alias on purpose; production stability wants the prod/dev split to be loud). For CLI development, npm run setup-dev selectively symlinks only cockpit-dev to local source, leaving the npm-installed prod cockpit untouched. Unlike npm link (which clobbers both bins), this lets you edit bin/*.mjs live and still npm install -g @surething/cockpit@latest to upgrade prod without disturbing the dev symlink. No more npm unlink / install -g dance.

    🐛 Fix: cockpit browser type no longer silently no-ops on React SPAs

    cockpit browser <id> type <ref> "text" used to report success on contenteditable / React-controlled inputs (tiptap, ProseMirror, Lexical) even when CDP Input.dispatchKeyEvent was a no-op against the React state machine. Two fixes:

    1. Post-type verification. After the type call returns, the CLI evaluates document.activeElement and checks that the live .value / .textContent actually contains what was typed. Mismatch → exit 1 with a copy-pasteable evaluate template tailored to the input's shape (contenteditable insertText / React setter + input event dispatch / etc.).
    2. Cheat sheet upfront. cockpit browser <id> (no args) now opens with a "React / SPA gotchas" section + 3 evaluate templates ready to copy, and the type / click / fill lines 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> --help no longer rejected

    cockpit terminal <id> --help used to error with Unknown flag: --help because 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. Inside language-markdown blocks, every Prism token (table, code, list, title, …) was getting forced to display: 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 .table utility.

    📚 Docs

    README + README.zh.md were still advertising the v1.0.213-retired /review / /commit slash 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/*.md references 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.metaDescription field so the visible Hero copy stays untouched.
    • /docs page gained a real description + OpenGraph + Twitter card (was bare).
    • All per-locale routes now mirror og:locale via og: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 中文 / …).
    View on GitHub
  8. v1.0.214

    May 26, 2026 · v1.0.214

    ✨ New: Four CodeGraph analytics endpoints + cock affected CLI

    /cg mode 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. Combine query, cursor, and openFiles; get back the Top-K relevant coordinates ranked by PPR + TF-IDF + PageRank with explainable signals[] (query-match / ppr / pagerank / open). Useful when you don't know the symbol name yet, only the intent.
    • /api/projectGraph/related — broader than callers/callees. Each result carries a relations[] 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 /impact and overlays callFreq + coeditProb + hasTest + pagerank per node, with adaptive weights when coedit is unavailable. Returns highRisk (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 /risk is precision-oriented (highlight the few that matter most).

    Cursor tolerance got real: cursor accepts <file>::<qname>, <file>.<qname> (.::), bare qname (global lookup), case-insensitive fallback, and <file>:<line> with ±5 line fuzzing. Misses come back with a cursorResolution block listing suggestions, so the LLM can retry instead of silently dropping the strongest seed.

    Degraded responses always return 200 + degradedReason, never 5xx — coedit-unavailable for squash-style projects (coedit now auto-falls back to merge-granularity), analytics-warming while 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 + stats
    

    The CLI is a thin shim over /api/projectGraph/affected — it shares the live CodeIndex (no per-invocation parse), exits 1 when no tests are affected (so you can short-circuit in a Makefile), and 3 when Cockpit isn't running.

    ✨ New: cock terminal reshaped as a read-only log analyser

    The 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 dev log. 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 / timeout
    

    Server-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 you firstAvailable and truncated so you can detect the gap).

    AI-friendly defaults: ANSI stripped and \r collapsed by default (turborepo's \r\r\n no longer empties every line). Pass --keep-ansi / --keep-cr when 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: /cg slash command extended

    The /cg exploration mode prompt now teaches the four new endpoints in the same voice as the original six — including the relations / signals / tags vocabulary, the ambiguousIn disambiguation hint, the coedit echo on risk / related, and the difference between risk (analysis, precision) and affected (CI, recall). Both Chinese and English bodies updated.

    📦 Misc

    Two new runtime dependencies — graphology and graphology-communities-louvain — pull in Louvain community detection for the sibling-in-community relation. Both are pure JS, no native bindings, no model files; the analytics layer remains zero-training, zero-network.

    View on GitHub
  9. v1.0.213

    May 23, 2026 · v1.0.213

    ✨ New: /ex and /go slash commands

    Two new builtin discussion modes join the existing /qa, /fx, and /cg family:

    • /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/*.md or .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 measureElement ref produced a 0-height read. Row inline heights now floor to the row-type estimate, so a transient 0-height never gets re-cached.

    View on GitHub
  10. v1.0.212

    May 22, 2026 · v1.0.212

    🌐 Rebrand: OpenCockpit at opencockpit.dev

    Cockpit's public surface area is now OpenCockpit, served from https://opencockpit.dev. The old cocking.cc domain 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 vars
    

    The repo stays at Surething-io/cockpit. If you've scripted anything against the CLI or env, no changes are needed.

    View on GitHub
  11. v1.0.211

    May 22, 2026 · v1.0.211

    ✨ New: CodeGraph — give the AI a query graph, not a grep

    The 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 /cg slash mode. The agent stops driving grep and 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 grep could never give you. It catches the conventional couplings static analysis can't see — parallel registries, double-write tables, sibling .md configs 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 /cg in 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.cc gets 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 why grep is 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: CodegraphCodeGraph

    The user-facing brand name is now consistently CodeGraph (PascalCase, matching Code Map). Internal identifiers untouched: the /cg command name and the /api/projectGraph/* URL paths stay as technical IDs.

    🛠️ Dev-only: website builds on Next 16 again

    website/package.json's dev / build scripts pin webpack explicitly (env -u TURBOPACK … --webpack). Next 16 made Turbopack the default and the old TURBOPACK= empty-value opt-out stopped working; on this monorepo Turbopack panics on @import "tailwindcss". Webpack is the same bundler cockpit itself uses for prod, so the fix just brings website/ back in line.

    View on GitHub
  12. v1.0.210

    May 21, 2026 · v1.0.210

    ✨ 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 snapshots
    • lineSnapshot — 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 audit reports 0 vulnerabilities across root, website, and e2b manifests.

    View on GitHub
  13. v1.0.209

    May 21, 2026 · v1.0.209

    ✨ 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/cockpit now 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 screens

    The 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 || …) — which String()-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, errorToResponse now serializes errors as { error: <string>, tag: <_tag> }, extracting a real message from e.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:

    • useLineHighlight now derives the plain-text fallback synchronously from the current input via useMemo, removing the render frame where state could disagree with input.
    • The virtualizer gets getItemKey so 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 useEffect to useLayoutEffect, closing the timing window where ResizeObserver could write back into the just-cleared cache.

    The original bug-report reproduction no longer shows overlapping rows.

    View on GitHub
  14. v1.0.208

    May 11, 2026 · v1.0.208

    🐛 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 fills children for directories listed in the persisted expandedPaths file. Search-mode expansion is intentionally session-only and never persisted, so every refresh dropped children for 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.

    View on GitHub
  15. v1.0.207

    May 11, 2026 · v1.0.207

    🐛 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}px inline, and ref={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.

    View on GitHub
  16. v1.0.206

    May 11, 2026 · v1.0.206

    ⚙️ Internal: DDD modularization of the codebase

    Everything that was in src/components/ / src/hooks/ moved into 11 workspace packages under packages/{shared,feature}/. The intent: when AI works on chat, it loads feature-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 commands
    • feature-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 + LSP
    • feature-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 other feature-* (supporting-subdomain pattern, kept acyclic) and shared-*; shared-* is a leaf layer (cannot import @cockpit/*). See MODULES.md for the full architecture doc.

    HTTP route handlers are now Web standard Request / Response everywhere — NextRequest / NextResponse dropped from 108 files (~670 substitutions across .json(...), new ...(...), req.nextUrl.searchParams, type annotations, and next/server imports). Future Hono / Bun / Deno migration is a thin adapter layer instead of a rewrite.

    i18n: the full translation dictionary moved to @cockpit/shared-i18n as a singleton; dropped the IoC translator slot in shared-ui. Same translations, fewer levels of indirection.

    🐛 Fix: prod install + /api/version

    The DDD refactor accidentally listed 9 private workspace packages in dependencies, which made npm install @surething/cockpit fail with ERR 404 @cockpit/feature-agent@* — they don't exist on the registry. They're now devDependencies (needed for build, not for users); dist/wsServer.mjs and dist/scheduledTasks.mjs inline their contents at bundle time, mirroring what Next.js's transpilePackages already does for .next-prod/. No runtime resolution happens against the (missing) node_modules/@cockpit/* path.

    /api/version used to read package.json from process.cwd(). In Next.js's prod runtime that effective cwd is /, so the endpoint silently returned {"version":""}. Now reads from process.env.COCKPIT_ROOT, which server.mjs sets to the installed cockpit package root at boot.

    📦 Misc: drop unused tooling

    Storybook + Vitest + Playwright + 10 supporting devDependencies removed — they hadn't been part of the workflow for months. npm install is faster and lighter; one less dependency surface to keep patched.

    View on GitHub
  17. v1.0.205

    May 9, 2026 · v1.0.205

    🐛 Fix: fresh installs failed to start

    @vscode/ripgrep 1.18 split its platform binaries into per-arch packages (@vscode/ripgrep-darwin-arm64/bin/rg etc.) and stopped shipping bin/rg from the main package. Cockpit had hand-built a path off process.cwd() + node_modules/@vscode/ripgrep/bin/rg, which ENOENT'd on any fresh npm i -g that resolved 1.18+:

    Error: spawn .../node_modules/@vscode/ripgrep/bin/rg ENOENT
    

    Symptoms 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 rgPath export, which handles both 1.17 (binary in main) and 1.18+ (binary in platform sub-package) layouts. @vscode/ripgrep is also added to serverExternalPackages so its internal createRequire(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 +N controls.

    ··· 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 collisionstransition-all was sweeping up the virtualizer's transform: translateY(...) on every state change, briefly overlapping diff rows during reveal. Replaced with transition-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:

    • hono 4.12.15 → 4.12.18 — CSS injection in JSX SSR, cache cross-user leak via missing Vary handling, JSX tag HTML injection, bodyLimit bypass on chunked requests, JWT NumericDate validation
    • fast-uri 3.1.0 → 3.1.2 — host confusion, path traversal via percent-encoded segments
    • ip-address 10.1.0 → 10.2.0 — XSS in Address6 HTML-emitting methods (pulled in via express-rate-limit 8.4.1 → 8.5.1)

    All bumps stay within caret ranges already declared by MCP SDK; package.json itself unchanged.

    View on GitHub
  18. v1.0.204

    May 8, 2026 · v1.0.204

    ✨ 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 / Full toggle at the top of the diff brings back the whole-file view for the moments you want it

    Map mode (the chip view) was already compact-by-design and is unchanged. The compact treatment is opt-in via the compact prop on DiffView, 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 mtime is 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 with AI_NoOutputGenerated. Cockpit now coerces content: 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-flash pulse 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 — every data-tooltip or <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.

    View on GitHub
  19. v1.0.203

    May 7, 2026 · v1.0.203

    ✨ 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-level app.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.

    View on GitHub
  20. v1.0.202

    May 6, 2026 · v1.0.202

    ✨ 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, BlockDiffMinimap etc., because internally a Code Map is composed of per-function "blocks" / chips. Those names describe the primitive, not the user-facing feature.

    🐛 Fix: /try cooldown no longer dumps raw JSON

    The "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 with Accept: 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
    View on GitHub
  21. v1.0.201

    May 6, 2026 · v1.0.201

    🐛 Fix: chip view server-side createRequire is not a function

    v1.0.200's webpack DefinePlugin killed 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 function
    

    web-tree-sitter's ESM bundle does await 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 } yielded undefined.

    Fix: add web-tree-sitter to serverExternalPackages so it's loaded at runtime via Node's actual ESM resolver. import("module") then hits node:module directly and createRequire is 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@latest
    
    View on GitHub
  22. v1.0.200

    May 6, 2026 · v1.0.200

    🐛 Fix: chip view crashed in prod with createRequire is not a function

    After 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 function
    

    web-tree-sitter's ESM bundle has a runtime Node-detection branch that calls createRequire only 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 dynamic import("module") resolved to our empty stub — createRequire was undefined.

    This release adds a webpack DefinePlugin rule for the browser bundle that folds process.versions to ({}) and process.type to "renderer" at compile time. The if-condition then collapses to falsy && 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@latest
    
    View on GitHub
  23. v1.0.199

    May 6, 2026 · v1.0.199

    🐛 Fix: v1.0.198 install was broken

    v1.0.198's postinstall imported scripts/copy-tree-sitter-wasms.mjs from a path that wasn't in the published tarball, so every npm install of v1.0.198 failed with ERR_MODULE_NOT_FOUND and rolled back. The script is now included in the package's files manifest.

    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 install actually working.

    npm install -g @surething/cockpit@latest
    

    For the full list of new features in this release, see v1.0.198.

    View on GitHub
  24. v1.0.198

    May 6, 2026 · v1.0.198

    ✨ 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 under User. Rust &self / &mut self / self are preserved verbatim. Multi-name params (Go func(a, b int)) flatten correctly.

    Behind the scenes, codeMap is built on a pluggable LanguageHandler interface — 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 more 0;276;0c debris 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.ts twice 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 to globalThis (same pattern as the existing PgPoolManager); 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.

    View on GitHub
  25. v1.0.197

    Apr 29, 2026 · v1.0.197

    ⚙️ 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-changelog for 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.md for human review before gh release edit.

    Documentation only. Not shipped in the npm package (skills/ is not in package.json#files), so this release changes nothing for @surething/cockpit CLI users — it's for whoever cuts the next release.

    View on GitHub
  26. v1.0.196

    Apr 29, 2026 · v1.0.196

    ✨ New: cockpit command (full-name alias for cock)

    Both cockpit and cock now ship with the package and point at the same code path. Use whichever you prefer — the docs and help output have been switched to cockpit (easier to share in talks, Slack, and Show HN screenshots), but the short cock alias keeps working everywhere for muscle memory.

    npm i -g @surething/cockpit@latest
    cockpit                # new
    cockpit -h
    cockpit browser <id> snapshot
    cock                   # still works
    

    Subcommand help (cockpit browser --help, cockpit terminal --help) now consistently uses the cockpit prefix in usage examples.

    🌐 Marketing site SEO overhaul

    cocking.cc shipped a major SEO + content pass:

    📚 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.md all 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.
    View on GitHub
  27. v1.0.195

    Apr 29, 2026 · v1.0.195

    ✨ 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.

    View on GitHub
  28. v1.0.194

    Apr 29, 2026 · v1.0.194

    🌐 Website: Slash Modes, Skills, real screenshots

    cocking.cc got three upgrades:

    • Slash Modes section showcasing the built-in /qa, /fx workflows
    • Skills surfaced in the Extras section
    • Placeholder cards replaced with real product screenshots

    🐛 /fx now appears in autocomplete

    Typing / shows /fx alongside the other built-in commands (was missing before).

    View on GitHub
  29. v1.0.193

    Apr 29, 2026 · v1.0.193

    🌐 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.

    View on GitHub
  30. v1.0.192

    Apr 26, 2026 · v1.0.192

    ✨ 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.

    View on GitHub
  31. v1.0.191

    Apr 23, 2026 · v1.0.191

    🐛 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".

    View on GitHub
  32. v1.0.190

    Apr 23, 2026 · v1.0.190

    🐛 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.

    View on GitHub
  33. v1.0.189

    Apr 23, 2026 · v1.0.189

    ✨ 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.

    View on GitHub
  34. v1.0.188

    Apr 22, 2026 · v1.0.188

    ✨ 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.

    View on GitHub
  35. v1.0.187

    Apr 22, 2026 · v1.0.187

    ✨ 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).

    View on GitHub
  36. v1.0.186

    Apr 11, 2026 · v1.0.186

    ✨ 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
    View on GitHub
  37. v1.0.185

    Mar 31, 2026 · v1.0.185

    🐛 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.

    View on GitHub
  38. v1.0.184

    Mar 31, 2026 · v1.0.184

    ✨ 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.

    View on GitHub
  39. v1.0.183

    Mar 30, 2026 · v1.0.183

    🐛 More reliable end-of-turn detection

    The chat now decides "the assistant is done" based on whether a result message arrived, instead of guessing from stop_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.

    View on GitHub
  40. v1.0.182

    Mar 30, 2026 · v1.0.182

    ✨ 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.

    View on GitHub
  41. v1.0.181

    Mar 28, 2026 · v1.0.181

    Internal release — no user-facing changes.

    View on GitHub
  42. v1.0.180

    Mar 28, 2026 · v1.0.180

    Internal release — no user-facing changes.

    View on GitHub
  43. v1.0.179

    May 22, 2026 · v1.0.179

    ✨ 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`.

    View on GitHub
  44. v1.0.178

    Mar 26, 2026 · v1.0.178

    ✨ `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.

    View on GitHub
  45. v1.0.177

    Mar 25, 2026 · v1.0.177

    🐛 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.

    View on GitHub
  46. v1.0.176

    Mar 25, 2026 · v1.0.176

    🐛 Chrome extension auto-installs

    The cockpit chrome extension is now copied to ~/.cockpit/ during npm install, so the browser bubble works out of the box without manual setup.

    View on GitHub
  47. v1.0.175

    Mar 25, 2026 · v1.0.175

    First release tracked in the public changelog.

    View on GitHub