Conversation
Launches Claude Code interactively in the new worktree after creation, using /dev/tty so it gets a real terminal despite the shell wrapper capturing stdout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughA new boolean flag Changes
Sequence DiagramsequenceDiagram
participant User
participant CreateCmd as Create Command
participant Worktree
participant PostCreate as Post-Create Steps
participant Claude as Claude Executable
participant Terminal
User->>CreateCmd: Run create with --claude flag
CreateCmd->>Worktree: Create new worktree
CreateCmd->>PostCreate: Execute post-create steps
PostCreate-->>CreateCmd: Complete
alt --claude flag enabled
CreateCmd->>Terminal: Open /dev/tty
Terminal-->>CreateCmd: Terminal I/O ready
CreateCmd->>Claude: Launch claude executable<br/>(working dir = worktree)
Claude->>Claude: Attach STDIN/STDOUT/STDERR
Claude-->>Terminal: Interactive session
Claude-->>CreateCmd: Exit (success or failure)
CreateCmd-->>User: Log result (non-fatal)
else --claude flag disabled
CreateCmd-->>User: Complete
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/create.go`:
- Around line 95-109: The code currently returns an error if
os.OpenFile("/dev/tty", ...) fails which aborts runCreate and prevents printing
worktreePath; change this to treat /dev/tty as optional: if os.OpenFile fails,
write a warning to os.Stderr (not return) and set claude.Stdin/Stdout/Stderr to
os.Stdin/os.Stdout/os.Stderr instead; only call tty.Close() via defer when tty
was successfully opened; keep exec.Command("claude") invocation and its Run()
error handling unchanged so the --claude step fails non-fatally.
| tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) | ||
| if err != nil { | ||
| return fmt.Errorf("cannot open terminal: %w", err) | ||
| } | ||
| defer tty.Close() | ||
|
|
||
| claude := exec.Command("claude") | ||
| claude.Dir = worktreePath | ||
| claude.Stdin = tty | ||
| claude.Stdout = tty | ||
| claude.Stderr = tty | ||
| if err := claude.Run(); err != nil { | ||
| fmt.Fprintf(os.Stderr, "claude exited: %v\n", err) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Explore the repository structure and find the file
git ls-files | grep -E '(create\.go|README|\.md)' | head -20Repository: songtov/wtt
Length of output: 88
🏁 Script executed:
#!/bin/bash
# Read the cmd/create.go file to understand the full context
# First, check the file size
wc -l cmd/create.go
# Then read around lines 95-109 with broader context
sed -n '80,125p' cmd/create.goRepository: songtov/wtt
Length of output: 966
🏁 Script executed:
#!/bin/bash
# Check for cross-platform/Windows support claims in documentation
fd -HI 'README*' . | xargs -r grep -i -E 'windows|cross-platform|supported.*platform' | head -20
# Also check for any platform-specific documentation
fd -HI '\.(md|txt)$' . | xargs -r grep -i -E 'windows|macos|linux' | head -20Repository: songtov/wtt
Length of output: 37
🏁 Script executed:
#!/bin/bash
# Find all /dev/tty usage points in the codebase
rg -n '"/dev/tty"|os\.OpenFile.*"/dev/tty"' --type goRepository: songtov/wtt
Length of output: 123
🏁 Script executed:
#!/bin/bash
# Check for the --claude flag definition and how it's used
rg -n -B3 -A3 'claude|--claude' cmd/create.go | head -40Repository: songtov/wtt
Length of output: 668
🏁 Script executed:
#!/bin/bash
# Check CLAUDE.md for context about the feature
cat CLAUDE.mdRepository: songtov/wtt
Length of output: 1203
🏁 Script executed:
#!/bin/bash
# Check if there are any existing cross-platform compatibility checks elsewhere
rg -n 'runtime\.GOOS|GOOS|windows|darwin|linux' cmd/ --type goRepository: songtov/wtt
Length of output: 37
🏁 Script executed:
#!/bin/bash
# Verify if stdout emission is critical by checking how this tool is meant to be used
head -50 README.mdRepository: songtov/wtt
Length of output: 954
🏁 Script executed:
#!/bin/bash
# Check for test files related to create functionality
fd -HI '.*test.*\.go' cmd/ | xargs -r grep -l 'create'
# Also check what CI/testing environments are configured
fd -HI '\.(yml|yaml|github|gitlab|circleci)$' | head -20Repository: songtov/wtt
Length of output: 109
🏁 Script executed:
#!/bin/bash
# Check if there's any documentation about platform support
grep -r -i 'platform\|windows\|linux\|macos\|supported' . --include='*.md' | grep -v '.git'Repository: songtov/wtt
Length of output: 37
🏁 Script executed:
#!/bin/bash
# Look for any environment detection or OS-specific handling elsewhere in the codebase
rg -n 'os\.' cmd/ --type go | head -30Repository: songtov/wtt
Length of output: 2319
🏁 Script executed:
#!/bin/bash
# Check the complete context around lines 95-111 to see the full flow
sed -n '88,115p' cmd/create.goRepository: songtov/wtt
Length of output: 715
🏁 Script executed:
#!/bin/bash
# Check the goreleaser and workflow configs to understand supported platforms
cat .goreleaser.yml | head -50
echo "---"
cat .github/workflows/release.yml | head -60Repository: songtov/wtt
Length of output: 1573
🏁 Script executed:
#!/bin/bash
# Check if there are any tests or examples showing non-interactive usage
fd -HI '.*test.*\.go' . | xargs -r grep -l 'claude\|create' 2>/dev/null
# Also check for Makefile or test targets
cat Makefile 2>/dev/null | head -40Repository: songtov/wtt
Length of output: 702
🏁 Script executed:
#!/bin/bash
# Verify the exact behavior: does the function return before printing worktreePath?
sed -n '40,115p' cmd/create.goRepository: songtov/wtt
Length of output: 2149
Avoid hard-failing on /dev/tty for an optional --claude step; fallback to stdio instead.
When opening /dev/tty fails (common in non-interactive environments like CI, cron, or SSH without a TTY), runCreate returns an error even though the worktree is already successfully created. This blocks the critical stdout emission at line 111 (fmt.Println(worktreePath)), breaking the documented shell wrapper pattern. Instead, gracefully fallback to stdin/stdout/stderr and log a warning, consistent with how post_create commands handle failures (line 89).
Proposed fallback
- tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
- if err != nil {
- return fmt.Errorf("cannot open terminal: %w", err)
- }
- defer tty.Close()
-
- claude := exec.Command("claude")
- claude.Dir = worktreePath
- claude.Stdin = tty
- claude.Stdout = tty
- claude.Stderr = tty
+ in := os.Stdin
+ out := os.Stdout
+ errOut := os.Stderr
+ if tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0); err == nil {
+ defer tty.Close()
+ in, out, errOut = tty, tty, tty
+ } else {
+ fmt.Fprintf(os.Stderr, "Warning: cannot open terminal, using current stdio: %v\n", err)
+ }
+
+ claude := exec.Command("claude")
+ claude.Dir = worktreePath
+ claude.Stdin = in
+ claude.Stdout = out
+ claude.Stderr = errOut
if err := claude.Run(); err != nil {
fmt.Fprintf(os.Stderr, "claude exited: %v\n", err)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) | |
| if err != nil { | |
| return fmt.Errorf("cannot open terminal: %w", err) | |
| } | |
| defer tty.Close() | |
| claude := exec.Command("claude") | |
| claude.Dir = worktreePath | |
| claude.Stdin = tty | |
| claude.Stdout = tty | |
| claude.Stderr = tty | |
| if err := claude.Run(); err != nil { | |
| fmt.Fprintf(os.Stderr, "claude exited: %v\n", err) | |
| } | |
| } | |
| in := os.Stdin | |
| out := os.Stdout | |
| errOut := os.Stderr | |
| if tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0); err == nil { | |
| defer tty.Close() | |
| in, out, errOut = tty, tty, tty | |
| } else { | |
| fmt.Fprintf(os.Stderr, "Warning: cannot open terminal, using current stdio: %v\n", err) | |
| } | |
| claude := exec.Command("claude") | |
| claude.Dir = worktreePath | |
| claude.Stdin = in | |
| claude.Stdout = out | |
| claude.Stderr = errOut | |
| if err := claude.Run(); err != nil { | |
| fmt.Fprintf(os.Stderr, "claude exited: %v\n", err) | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@cmd/create.go` around lines 95 - 109, The code currently returns an error if
os.OpenFile("/dev/tty", ...) fails which aborts runCreate and prevents printing
worktreePath; change this to treat /dev/tty as optional: if os.OpenFile fails,
write a warning to os.Stderr (not return) and set claude.Stdin/Stdout/Stderr to
os.Stdin/os.Stdout/os.Stderr instead; only call tty.Close() via defer when tty
was successfully opened; keep exec.Command("claude") invocation and its Run()
error handling unchanged so the --claude step fails non-fatally.
Summary by CodeRabbit
New Features