Summary
cmux ships a wrapper script at Resources/bin/claude that intercepts claude invocations inside cmux terminals. This wrapper automatically injects 6 hooks via --settings and a generated --session-id before passing through to the real Claude binary. This behavior is currently undocumented.
I understand this is a pragmatic design choice to deliver a zero-config experience — and it works. The seamless out-of-the-box integration is genuinely one of cmux's strengths. The implementation itself is well-designed (environment checks, socket validation, passthrough fallback, opt-out via CMUX_CLAUDE_HOOKS_DISABLED=1). This issue is not about removing the feature, but about disclosing it.
What the wrapper does
When a user runs claude inside a cmux terminal (CMUX_SURFACE_ID is set):
- cmux's
bin/ directory takes PATH precedence over the real claude binary
- The wrapper injects
--settings with hooks for: SessionStart, Stop, SessionEnd, Notification, UserPromptSubmit, PreToolUse
- A UUID is generated and passed as
--session-id
- The real
claude binary is then exec'd with these additional flags
Outside cmux, the wrapper passes through to the real binary unchanged.
Current documentation gap
- README: No mention of the wrapper, PATH shim, or automatic hook injection
- docs/notifications.md: Only documents the manual approach (user configures hooks in
settings.json themselves)
- CONTRIBUTING.md: No mention
- CHANGELOG: A single bugfix entry references "claude shim" in passing — not a disclosure
The only way to discover this behavior is to read the source code.
Why this matters
Claude Code is an AI agent with broad system permissions (file I/O, code execution, network access). The UserPromptSubmit and PreToolUse hooks observe every prompt and tool invocation within a session. While the current hooks only perform notification/status updates, the interception surface itself warrants explicit disclosure — users should know that a third-party layer sits between their input and the official binary.
PATH shims are an established pattern (nvm, pyenv, rbenv, direnv), but those tools clearly document their shim behavior. Transparency is especially important when the intercepted tool operates with elevated trust.
Suggestions
- Add a section to the README explaining the Claude wrapper, what it injects, and why
- Show a first-launch notice or log line when the wrapper activates (e.g.,
[cmux] Using Claude wrapper with session hooks — disable with CMUX_CLAUDE_HOOKS_DISABLED=1)
- Have the wrapper append a line like
(cmux wrapped) to claude --version or claude --help output, so users can easily tell when they're running through the shim
- Consider an opt-in prompt on first use
Thanks for building cmux — the UX is genuinely great. Just hoping to see the trust layer match the engineering quality.
Summary
cmux ships a wrapper script at
Resources/bin/claudethat interceptsclaudeinvocations inside cmux terminals. This wrapper automatically injects 6 hooks via--settingsand a generated--session-idbefore passing through to the real Claude binary. This behavior is currently undocumented.I understand this is a pragmatic design choice to deliver a zero-config experience — and it works. The seamless out-of-the-box integration is genuinely one of cmux's strengths. The implementation itself is well-designed (environment checks, socket validation, passthrough fallback, opt-out via
CMUX_CLAUDE_HOOKS_DISABLED=1). This issue is not about removing the feature, but about disclosing it.What the wrapper does
When a user runs
claudeinside a cmux terminal (CMUX_SURFACE_IDis set):bin/directory takes PATH precedence over the realclaudebinary--settingswith hooks for:SessionStart,Stop,SessionEnd,Notification,UserPromptSubmit,PreToolUse--session-idclaudebinary is thenexec'd with these additional flagsOutside cmux, the wrapper passes through to the real binary unchanged.
Current documentation gap
settings.jsonthemselves)The only way to discover this behavior is to read the source code.
Why this matters
Claude Code is an AI agent with broad system permissions (file I/O, code execution, network access). The
UserPromptSubmitandPreToolUsehooks observe every prompt and tool invocation within a session. While the current hooks only perform notification/status updates, the interception surface itself warrants explicit disclosure — users should know that a third-party layer sits between their input and the official binary.PATH shims are an established pattern (nvm, pyenv, rbenv, direnv), but those tools clearly document their shim behavior. Transparency is especially important when the intercepted tool operates with elevated trust.
Suggestions
[cmux] Using Claude wrapper with session hooks — disable with CMUX_CLAUDE_HOOKS_DISABLED=1)(cmux wrapped)toclaude --versionorclaude --helpoutput, so users can easily tell when they're running through the shimThanks for building cmux — the UX is genuinely great. Just hoping to see the trust layer match the engineering quality.