Skip to content

Enable Claude Code integration by default again - #247

Merged
lawrencecchen merged 1 commit into
mainfrom
feat-enable-claude-code-default
Feb 21, 2026
Merged

lawrencecchen merged 1 commit into
mainfrom
feat-enable-claude-code-default

Conversation

@lawrencecchen

Copy link
Copy Markdown
Contributor

Summary

  • set ClaudeCodeIntegrationSettings.defaultHooksEnabled back to true
  • update the corresponding unit test to assert default-on behavior when preference is unset

Validation

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination 'platform=macOS' build ✅
  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS' -only-testing:cmuxTests/GhosttyConfigTests test ❌ (blocked by existing compile errors in cmuxTests/CmuxWebViewKeyEquivalentTests.swift referencing UpdateChannelSettings)
  • ./scripts/reload.sh --tag claude-default-on ✅

@cmux-agent

cmux-agent Bot commented Feb 21, 2026 •

Copy link
Copy Markdown
Contributor

Preview Videos and Screenshots

Open Workspace (1 hr expiry) · Open Dev Browser (1 hr expiry) · Open Diff Heatmap

Failed to capture screenshots for commit 8f535f7.

Claude Code native binary not found at /root/.bun/bin/claude. Please ensure Claude Code is installed via native installer or specify a valid path with options.pathToClaudeCodeExecutable.


Generated by manaflow preview system

@vercel

vercel Bot commented Feb 21, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Feb 21, 2026 6:14am

@lawrencecchen
lawrencecchen merged commit ff11ba0 into main Feb 21, 2026
4 of 5 checks passed
BillionClaw added a commit to BillionClaw/cmux that referenced this pull request Mar 24, 2026
The pre-0.60 "Claude Code hooks" section is no longer relevant
after PR manaflow-ai#247. Fixes manaflow-ai#2009
BillionClaw added a commit to BillionClaw/cmux that referenced this pull request Mar 24, 2026
The Claude Code hooks section documented manual JSON configuration for
notification hooks. Since PR manaflow-ai#247 (released in 0.60.0), Claude Code
integration is enabled by default — cmux automatically injects notification
hooks when the claude command is invoked. This manual configuration is no
longer needed and is misleading for users on 0.60+.
BillionClaw added a commit to BillionClaw/cmux that referenced this pull request Mar 24, 2026
Claude Code integration is now enabled by default (PR manaflow-ai#247, 0.60.0), so
the manual hooks configuration in settings.json is no longer needed.
Kept OpenAI Codex and OpenCode integration examples which are still
relevant. Fixes manaflow-ai#2009.
bn-l pushed a commit to bn-l/cmux that referenced this pull request Apr 3, 2026
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request May 22, 2026
Drag-storm log analysis (bd23f95 build, captured via os_log) shows
the freeze symptom is per-RPC SSH subprocess cost, not main-thread
saturation:

  - 27 outbound pane.resize during a ~10s cmux divider drag
  - each oneshot.ok durMs=600-1000ms over the SSH master
  - ~19s of cumulative SSH-master time spent on pane.resize alone
  - applyDividers.end durMs=0 across 294 calls (main is fast)
  - pump.stats kept reporting (PTY consumer not starved)

Each pane.resize today opens a fresh ssh subprocess + remote
api-bridge + bincode handshake — that's the ~700ms baseline.
Multiplied by 27 fires per drag, the SSH master gets jammed and
the raw-pty-attach channel multiplexed on the same master can't
land output bytes — user sees "panel input invisible" and
right-click menu hangs while the master is in flight.

The 80ms debounce was too short for bursty mouse motion: a single
panel observed 7-10 fires per drag because brief mouse pauses (>=
80ms) re-fired the timer instead of coalescing. With 4 panels in
the workspace and ~10 fires each, you get the 35-40 outbound
pane.resize calls the log shows.

Bumping to 400ms keeps drag bursts coalesced into one fire per
panel at drag end. Real fix is the persistent api-bridge
(task manaflow-ai#247): collapses the per-RPC ~700ms baseline to <50ms and
makes the debounce length immaterial.
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request May 22, 2026
Routes every non-streaming RPC through a per-host long-lived
HerdrApiClient connection cached by HerdrPersistentClientRegistry.
With herdr daemon >= 0.6.0-cmux9 the API socket loops on the
same connection (see daemon commit f91ffdf...cmux9 ssh side
"feat(api): persistent socket connections"); cmux now reuses one
ssh subprocess + one remote api-bridge for all RPCs instead of
paying ~700ms ssh+bincode handshake per call.

Why this matters in practice: drag-storm os_log capture from
build c25cf0d (debounce 80→400ms) showed 31 outbound pane.resize
in a 10-second cmux divider drag, each oneshot.ok durMs in the
644-2130ms range, totalling ~21s of cumulative SSH-master time.
The raw-pty-attach output channel multiplexed on the same SSH
master got starved for the duration — user observed "panel input
invisible / right-click menu hangs" while bytes still flowed
TUI-side. The 400ms debounce mitigated nothing because the
per-RPC cost dominates; reducing the per-RPC cost is what unblocks
the drag freeze.

Architecture:

- HerdrPersistentApiClient (actor) per host. Holds optional
  HerdrApiClient + reconnect lock. ensureConnected() coalesces
  concurrent connect attempts so a burst of RPCs after a
  disconnect doesn't spawn 30 parallel ssh subprocesses.
- request(method, params) does up to one transparent reconnect
  on a transport-level error. Application errors (HerdrApiError
  with daemon codes like pane_not_found) propagate as-is — we
  don't retry refusals.
- HerdrPersistentClientRegistry caches by HerdrHost.id and
  exposes forget/forgetAll. EventPump.tearDownHost calls forget
  so a removed host doesn't leak its ssh subprocess.

HerdrOneShotRPC.send/request now thin facades that route through
the registry. All existing call sites (Workspace, Sidebar,
DividerSync, FocusSync, ZoomSync, CloseHandler, KillCommands,
WorkspaceSync, EventPump's pane.set_split_ratio path) pick up
the new transport without any change.

Backward compat: legacy daemons (pre-cmux9) close the socket
after one response. The persistent client sees that as a transport
disconnect and lazy-reconnects on the next call — visibly
identical to the old per-call connection model. No client side
change is needed for the user to keep working against an old
remote daemon; they just don't see the latency win until the
daemon gets upgraded.

Tests:

- HerdrPersistentApiClientTests.testThreeSequentialRequestsReuseOneConnection
  spins up an in-test UDS daemon mock, drives three echo RPCs
  through HerdrPersistentApiClient, and asserts the daemon saw
  EXACTLY ONE inbound connection. Without manaflow-ai#247 this would be 3.
- HerdrPersistentApiClientTests.testRegistryReusesClientForSameHost
  locks the registry's identity-by-host-id contract and the
  forget()-then-fresh contract.

Daemon side already shipped as v0.6.0-cmux9 with
multiple_requests_share_one_socket_connection integration test
in herdr/tests/api_ping.rs.
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request May 22, 2026
CRIT-1 — test compile break.
testMalformedPayloadSurfacesAsApiError used `[String: Any?]` which
the JSONSerialization API never returns and which can't be
subscripted via the `??` flatten — the cmuxTests target failed to
build. Switch the helper return type to `[String: Any]` and
extract the error body via a clean `as? [String: Any]` cast.

MED-4 — close()-during-connect leaked a fresh HerdrApiClient.
The previous design: A is awaiting `api.start()` at the top of
the connect path. close() runs (stopped = true; awaiters drained;
client is still nil so close exits without doing anything). A's
start() then succeeds and writes `client = api` against an
already-stopped instance, leaking the api forever (no caller will
release it). Now: after start() succeeds, check `stopped` and if
flipped, close the just-spawned api and throw `disconnected`
instead of publishing it. close() therefore guarantees no surviving
HerdrApiClient on a stopped instance.

HIGH-2 — direct end-to-end test for daemon error surfacing.
Replaced the raw-socket "exercise the mock fixture" approach with
testDaemonErrorEnvelopeSurfacesAsHerdrApiError, which drives a
request through HerdrPersistentApiClient against a mock daemon
configured to emit a HerdrApiError envelope (`force_error_*`
method prefix). Asserts:
  - persistent.request throws HerdrApiError(code: "invalid_request")
  - the connection stays alive afterwards (a follow-up ping on
    the same socket succeeds)
  - daemon.connectionCount stays at 1 (error envelope did not
    cause a reconnect)
This locks the contract that manaflow-ai#247 requires: per-request errors
are surfaced as application errors, not as transport drops that
would void the persistent connection.

Mock daemon's `makeResponse` now emits the error envelope for any
method starting with `force_error_` so future tests can drive
arbitrary daemon error flows without changing the mock plumbing.
lawrencecchen added a commit that referenced this pull request Oct 2, 2026
Bump the ghostty submodule from b1a49b601 to 257a40956, the merge of
manaflow-ai/ghostty#252. That PR adds the offscreen embedded platform
(GHOSTTY_PLATFORM_OFFSCREEN = 6, CPU frame and Linux dmabuf callbacks,
app-thread draw) behind -Dembedded-offscreen, so the cross-platform GPUI
and cmux-browser clients can render daemon terminals offscreen on Linux
and Windows from the same fork. The default macOS GhosttyKit build does
not change, and cmux-next does not use the new platform.

feat-cmux-next now tracks fork main (coordinator decision), so the bump
also brings the fork-main merges between the old pin and the #252 base
dcb1d6965: #242 (PTY tee after the parser, under the renderer mutex),
#243, #245, #247, #250 (prompt line and replay fixes), #246, #248, #249
(VT replay blank cells keep the default style) and #251 (config API
window padding, whose fix commit was the old pin).

scripts/ghosttykit-checksums.txt pins the published 257a409 GhosttyKit
archive (build-ghosttykit.yml run 36989929300), which every cmux-next CI
job downloads. docs/ghostty-fork.md documents the offscreen platform, #242 and a map of
every merge in the range, with conflict notes. The cmux main pin's
local-only binding flag (324c02738) is not on fork main; cmux-next does
not use it.

This branch was successfully deployed

1 active deployment
Preview — 8f535f70 Deployed Feb 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant