fix: auto-start dev servers in tmux instead of blocking#344
fix: auto-start dev servers in tmux instead of blocking#344affaan-m merged 3 commits intoaffaan-m:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughReplaces inline dev-server blocking logic with an external Node.js PreToolUse hook that detects dev commands and auto-starts them in tmux (naming sessions from the current directory) or opens a new Windows cmd window; returns modified JSON tool_input.command or passes input through unchanged. Changes
Sequence Diagram(s)sequenceDiagram
participant Tool as Tool Runner
participant Hook as PreToolUse Hook (auto-tmux-dev.js)
participant Shell as Shell/OS
participant Tmux as tmux
Tool->>Hook: send tool_input JSON via stdin
Hook->>Hook: parse JSON, sanitize dir name, detect dev command
alt Non-Windows & dev command detected
Hook->>Shell: check tmux availability
alt tmux available
Hook->>Tmux: kill-session (if exists)
Hook->>Tmux: create detached session running dev command
Hook-->>Tool: return modified JSON with tmux-wrapped command and confirmation message
else tmux missing
Hook-->>Tool: return original JSON unchanged
end
else Windows & dev command detected
Hook->>Shell: open new cmd window with descriptive title running dev command
Hook-->>Tool: return modified JSON (Windows cmd invocation)
else no dev command detected
Hook-->>Tool: return original JSON unchanged
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
scripts/hooks/auto-tmux-dev.js (2)
2-5: Documentation claims cross-platform but Windows is explicitly unsupported.The header comment states "Cross-platform (Windows, macOS, Linux)" but Line 44 explicitly skips Windows (
process.platform !== 'win32'). This is misleading.Per coding guidelines for
scripts/**/*.js, cross-platform compatibility should be ensured. Consider either implementing Windows support (e.g., usingstart /bor Windows Terminal tabs) or updating the documentation to accurately reflect that Windows falls back to running the original command unchanged.📝 Update documentation to reflect actual behavior
/** * Auto-Tmux Dev Hook - Start dev servers in tmux automatically * - * Cross-platform (Windows, macOS, Linux) + * macOS/Linux: Runs dev servers in tmux sessions (non-blocking) + * Windows: Falls back to running the original command (blocking) *As per coding guidelines: "Ensure cross-platform compatibility for Windows, macOS, and Linux via Node.js scripts".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/hooks/auto-tmux-dev.js` around lines 2 - 5, The header comment in auto-tmux-dev.js incorrectly claims "Cross-platform (Windows, macOS, Linux)" while the script explicitly skips Windows via the process.platform !== 'win32' check; either implement Windows handling (e.g., add a Windows branch using a suitable launcher like start /b or Windows Terminal commands within the existing main routine that configures tmux/sessions) or update the top-of-file comment to accurately state that Windows is not supported and that the script will fall back to running the original command unchanged; locate the platform conditional using process.platform and adjust the file header string or add a Windows-specific code path in the same module to satisfy the guideline.
21-22: Unused import:execFileSyncis never used.The
execFileSyncimport fromchild_processis not used anywhere in this script.🧹 Remove unused import
const path = require('path'); -const { execFileSync } = require('child_process');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/hooks/auto-tmux-dev.js` around lines 21 - 22, Remove the unused import by deleting execFileSync from the child_process require in scripts/hooks/auto-tmux-dev.js; locate the top-level require that currently reads const { execFileSync } = require('child_process') (or a combined require with path) and remove the execFileSync symbol so only needed imports (e.g., path) remain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/hooks/auto-tmux-dev.js`:
- Around line 44-55: The current concatenation of sessionName and cmd into
transformedCmd creates a shell-injection risk; update the code so you do NOT
interpolate raw sessionName/cmd into a single shell string. Either (preferred)
stop building transformedCmd and invoke tmux via a non-shell API (e.g., use
child_process.spawn/execFile and call tmux with arguments: kill-session -t
sessionName, new-session -d -s sessionName and pass the dev command as a safe
argument) or (if you must produce a shell string) apply proper
shell-quoting/escaping to both sessionName and cmd before composing
transformedCmd (escape single quotes inside cmd and wrap it in single quotes,
and escape any characters in sessionName used in double quotes); then assign the
safe result back to input.tool_input.command. Ensure you change the code around
the sessionName, transformedCmd, and input.tool_input.command sites to use the
safe approach.
- Around line 57-62: The catch block around JSON.parse(data) swallows the error
and leaves input undefined so process.stdout.write(JSON.stringify(input)) emits
"undefined"; instead, in the catch for JSON.parse(data) (the block that
surrounds JSON.parse(data) and sets input), write the original data string to
stdout (use process.stdout.write(data)) and exit, preserving the raw input for
downstream hooks; update the catch associated with JSON.parse(data) and replace
the existing process.stdout.write(JSON.stringify(input)) path when parsing
failed so the original data is passed through.
---
Nitpick comments:
In `@scripts/hooks/auto-tmux-dev.js`:
- Around line 2-5: The header comment in auto-tmux-dev.js incorrectly claims
"Cross-platform (Windows, macOS, Linux)" while the script explicitly skips
Windows via the process.platform !== 'win32' check; either implement Windows
handling (e.g., add a Windows branch using a suitable launcher like start /b or
Windows Terminal commands within the existing main routine that configures
tmux/sessions) or update the top-of-file comment to accurately state that
Windows is not supported and that the script will fall back to running the
original command unchanged; locate the platform conditional using
process.platform and adjust the file header string or add a Windows-specific
code path in the same module to satisfy the guideline.
- Around line 21-22: Remove the unused import by deleting execFileSync from the
child_process require in scripts/hooks/auto-tmux-dev.js; locate the top-level
require that currently reads const { execFileSync } = require('child_process')
(or a combined require with path) and remove the execFileSync symbol so only
needed imports (e.g., path) remain.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 08d45b9a-0c14-4657-954f-b445782b2f93
📒 Files selected for processing (2)
hooks/hooks.jsonscripts/hooks/auto-tmux-dev.js
There was a problem hiding this comment.
2 issues found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/hooks/auto-tmux-dev.js">
<violation number="1" location="scripts/hooks/auto-tmux-dev.js:53">
P1: The tmux wrapper command is brittle: it has no tmux-availability fallback and does not escape single quotes in `cmd`, so valid dev commands can fail to start.</violation>
<violation number="2" location="scripts/hooks/auto-tmux-dev.js:61">
P1: `input` is out of scope when writing stdout, causing a runtime `ReferenceError` and breaking the hook.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Add one-off context when rerunning by tagging
@cubic-dev-aiwith guidance or docs links (includingllms.txt) - Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
Critical fixes: - Fix variable scope: declare 'input' before try block, not inside - Fix shell injection: sanitize sessionName and escape cmd for shell - Replace unused execFileSync import with spawnSync Improvements: - Add real Windows support using cmd /k window launcher - Add tmux availability check with graceful fallback - Update header comment to accurately describe platform support Test coverage: - Valid JSON input: transforms command for respective platform - Invalid JSON: passes through raw data unchanged - Unsupported tools: gracefully falls back to original command - Shell metacharacters: sanitized in sessionName, escaped in cmd
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/hooks/auto-tmux-dev.js">
<violation number="1" location="scripts/hooks/auto-tmux-dev.js:62">
P2: Wrong escape sequence for cmd.exe: `\"` is not a valid double-quote escape in cmd.exe. Use `^"` (cmd.exe's general escape character) or `""` (doubling) instead.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
affaan-m
left a comment
There was a problem hiding this comment.
Automated review: this PR has merge conflicts. Please rebase or resolve.
Replace blocking PreToolUse hook that used process.exit(2) with an auto-transform hook that: - Detects development server commands - Wraps them in tmux with directory-based session names - Runs server detached so Claude Code is not blocked - Provides confirmation message with log viewing instructions Benefits: - Development servers no longer block Claude Code execution - Each project gets its own tmux session (allows multiple projects) - Logs remain accessible via 'tmux capture-pane -t <session>' - Non-blocking: if tmux unavailable, command still runs (graceful fallback) Implementation: - Created scripts/hooks/auto-tmux-dev.js with transform logic - Updated hooks.json to reference the script instead of inline node command - Applied same fix to cached plugin version (1.4.1) for immediate effect
Critical fixes: - Fix variable scope: declare 'input' before try block, not inside - Fix shell injection: sanitize sessionName and escape cmd for shell - Replace unused execFileSync import with spawnSync Improvements: - Add real Windows support using cmd /k window launcher - Add tmux availability check with graceful fallback - Update header comment to accurately describe platform support Test coverage: - Valid JSON input: transforms command for respective platform - Invalid JSON: passes through raw data unchanged - Unsupported tools: gracefully falls back to original command - Shell metacharacters: sanitized in sessionName, escaped in cmd
Use double-quote doubling ('""') instead of backslash-escape ('\\\") for cmd.exe syntax.
Backslash escaping is Unix convention and not recognized by cmd.exe. This fixes quoted
arguments in dev server commands on Windows (e.g., 'npm run dev --filter="my-app"').
41d6c32 to
4170a29
Compare
PR #344 replaced the blocking dev-server hook with auto-tmux-dev.js which transforms commands into tmux sessions (exit 0) instead of blocking them (exit 2). Updated 2 tests to match the new behavior.
* fix: auto-start development servers in tmux instead of blocking Replace blocking PreToolUse hook that used process.exit(2) with an auto-transform hook that: - Detects development server commands - Wraps them in tmux with directory-based session names - Runs server detached so Claude Code is not blocked - Provides confirmation message with log viewing instructions Benefits: - Development servers no longer block Claude Code execution - Each project gets its own tmux session (allows multiple projects) - Logs remain accessible via 'tmux capture-pane -t <session>' - Non-blocking: if tmux unavailable, command still runs (graceful fallback) Implementation: - Created scripts/hooks/auto-tmux-dev.js with transform logic - Updated hooks.json to reference the script instead of inline node command - Applied same fix to cached plugin version (1.4.1) for immediate effect * fix: resolve PR affaan-m#344 code review issues in auto-tmux-dev.js Critical fixes: - Fix variable scope: declare 'input' before try block, not inside - Fix shell injection: sanitize sessionName and escape cmd for shell - Replace unused execFileSync import with spawnSync Improvements: - Add real Windows support using cmd /k window launcher - Add tmux availability check with graceful fallback - Update header comment to accurately describe platform support Test coverage: - Valid JSON input: transforms command for respective platform - Invalid JSON: passes through raw data unchanged - Unsupported tools: gracefully falls back to original command - Shell metacharacters: sanitized in sessionName, escaped in cmd * fix: correct cmd.exe escape sequence for double quotes on Windows Use double-quote doubling ('""') instead of backslash-escape ('\\\") for cmd.exe syntax. Backslash escaping is Unix convention and not recognized by cmd.exe. This fixes quoted arguments in dev server commands on Windows (e.g., 'npm run dev --filter="my-app"').
PR affaan-m#344 replaced the blocking dev-server hook with auto-tmux-dev.js which transforms commands into tmux sessions (exit 0) instead of blocking them (exit 2). Updated 2 tests to match the new behavior.
Summary
Replaces the blocking PreToolUse hook that used process.exit(2) with an auto-transform hook that wraps server startup commands in tmux sessions, allowing Claude Code to proceed without interruption.
What Changed
How It Works
When detecting startup commands (npm run dev, pnpm dev, yarn dev, bun run dev):
Benefits
Testing
Implementation Notes
Authored with Claude Code - hook implementation follows existing patterns from post-edit-format.js and other scripts in the hooks directory.
Summary by cubic
Replaces the blocking dev-server hook with a non-blocking transform that starts dev commands in a detached tmux session on macOS/Linux or a new cmd window on Windows. Keeps execution unblocked, names sessions after the project directory, and makes logs easy to view.
New Features
Bug Fixes
Written for commit 4170a29. Summary will update on new commits.
Summary by CodeRabbit
New Features
Refactoring