更新日志
从 GitHub Releases 拉取的版本说明。
v1.0.212
2026年5月22日 · v1.0.212在 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
2026年5月22日 · v1.0.211在 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
2026年5月21日 · v1.0.210在 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
2026年5月21日 · v1.0.209在 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
2026年5月11日 · v1.0.208在 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
2026年5月11日 · v1.0.207在 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
2026年5月11日 · v1.0.206在 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
2026年5月9日 · v1.0.205在 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/[email protected], 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
2026年5月8日 · v1.0.204在 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
2026年5月7日 · v1.0.203在 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
2026年5月6日 · v1.0.202在 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
2026年5月6日 · v1.0.201在 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
2026年5月6日 · v1.0.200在 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
2026年5月6日 · v1.0.199在 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
2026年5月6日 · v1.0.198在 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
2026年4月29日 · v1.0.197在 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
2026年4月29日 · v1.0.196在 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 4 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
2026年4月29日 · v1.0.195在 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
2026年4月29日 · v1.0.194在 GitHub 查看 ↗🌐 Website: Slash Modes, Skills, real screenshots
cocking.cc got three upgrades:
- Slash Modes section showcasing the built-in `/qa`, `/fx`, `/review`, `/commit` 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).
v1.0.193
2026年4月29日 · v1.0.193在 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
2026年4月26日 · v1.0.192在 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
2026年4月23日 · v1.0.191在 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
2026年4月23日 · v1.0.190在 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
2026年4月23日 · v1.0.189在 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
2026年4月22日 · v1.0.188在 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
2026年4月22日 · v1.0.187在 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
2026年4月11日 · v1.0.186在 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
2026年3月31日 · v1.0.185在 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
2026年3月31日 · v1.0.184在 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
2026年3月30日 · v1.0.183在 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
2026年3月30日 · v1.0.182在 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
2026年3月28日 · v1.0.181在 GitHub 查看 ↗Internal release — no user-facing changes.
v1.0.180
2026年3月28日 · v1.0.180在 GitHub 查看 ↗Internal release — no user-facing changes.
v1.0.179
2026年5月22日 · v1.0.179在 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
2026年3月26日 · v1.0.178在 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
2026年3月25日 · v1.0.177在 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
2026年3月25日 · v1.0.176在 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
2026年3月25日 · v1.0.175在 GitHub 查看 ↗First release tracked in the public changelog.