OpenCockpitOpenCockpit

更新日志

从 GitHub Releases 拉取的版本说明。

  1. v1.0.212

    2026年5月22日 · 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.

    在 GitHub 查看
  2. v1.0.211

    2026年5月22日 · 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.

    在 GitHub 查看
  3. v1.0.210

    2026年5月21日 · 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.

    在 GitHub 查看
  4. v1.0.209

    2026年5月21日 · 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.

    在 GitHub 查看
  5. v1.0.208

    2026年5月11日 · 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.

    在 GitHub 查看
  6. v1.0.207

    2026年5月11日 · 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.

    在 GitHub 查看
  7. v1.0.206

    2026年5月11日 · 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.

    在 GitHub 查看
  8. v1.0.205

    2026年5月9日 · 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/[email protected], 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.

    在 GitHub 查看
  9. v1.0.204

    2026年5月8日 · 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.

    在 GitHub 查看
  10. v1.0.203

    2026年5月7日 · 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.

    在 GitHub 查看
  11. v1.0.202

    2026年5月6日 · 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
    在 GitHub 查看
  12. v1.0.201

    2026年5月6日 · 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
    
    在 GitHub 查看
  13. v1.0.200

    2026年5月6日 · 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
    
    在 GitHub 查看
  14. v1.0.199

    2026年5月6日 · 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.

    在 GitHub 查看
  15. v1.0.198

    2026年5月6日 · 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.

    在 GitHub 查看
  16. v1.0.197

    2026年4月29日 · 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.

    在 GitHub 查看
  17. v1.0.196

    2026年4月29日 · 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.
    在 GitHub 查看
  18. v1.0.195

    2026年4月29日 · 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.

    在 GitHub 查看
  19. v1.0.194

    2026年4月29日 · v1.0.194

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

    在 GitHub 查看
  20. v1.0.193

    2026年4月29日 · 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.

    在 GitHub 查看
  21. v1.0.192

    2026年4月26日 · 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.

    在 GitHub 查看
  22. v1.0.191

    2026年4月23日 · 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".

    在 GitHub 查看
  23. v1.0.190

    2026年4月23日 · 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.

    在 GitHub 查看
  24. v1.0.189

    2026年4月23日 · 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.

    在 GitHub 查看
  25. v1.0.188

    2026年4月22日 · 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.

    在 GitHub 查看
  26. v1.0.187

    2026年4月22日 · 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).

    在 GitHub 查看
  27. v1.0.186

    2026年4月11日 · 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
    在 GitHub 查看
  28. v1.0.185

    2026年3月31日 · 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.

    在 GitHub 查看
  29. v1.0.184

    2026年3月31日 · 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.

    在 GitHub 查看
  30. v1.0.183

    2026年3月30日 · 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.

    在 GitHub 查看
  31. v1.0.182

    2026年3月30日 · 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.

    在 GitHub 查看
  32. v1.0.181

    2026年3月28日 · v1.0.181

    Internal release — no user-facing changes.

    在 GitHub 查看
  33. v1.0.180

    2026年3月28日 · v1.0.180

    Internal release — no user-facing changes.

    在 GitHub 查看
  34. v1.0.179

    2026年5月22日 · 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`.

    在 GitHub 查看
  35. v1.0.178

    2026年3月26日 · 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.

    在 GitHub 查看
  36. v1.0.177

    2026年3月25日 · 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.

    在 GitHub 查看
  37. v1.0.176

    2026年3月25日 · 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.

    在 GitHub 查看
  38. v1.0.175

    2026年3月25日 · v1.0.175

    First release tracked in the public changelog.

    在 GitHub 查看