Skip to content

Conversation

@jamesrochabrun
Copy link
Owner

Summary

  • Fixed claudePath setting persistence across app restarts
  • Added real-time validation feedback to Claude Path field
  • Added resolved executable path to debug report
  • Implemented autonomous Doctor debugging command

Changes

1. claudePath Persistence (ClaudeCodeContainer.swift + GlobalSettingsView.swift)

  • Call updateClaudeCommand() on app launch to persist stored claudePath
  • Disable "Done" button when path is invalid
  • Added real-time validation with visual feedback (✅/❌)

2. Resolved Executable in Debug Report (ChatViewModel.swift + TerminalLauncher.swift)

  • Made findClaudeExecutable() public
  • Added "Resolved Executable:" line to debug report
  • Shows actual executable path used (including shell aliases)

3. Doctor Debugging Tool (TerminalLauncher.swift + GlobalSettingsView.swift)

  • New "Run Doctor" button in Settings > Debug section
  • Launches autonomous debugging session in Terminal
  • Analyzes debug report and investigates environment
  • Proposes prioritized fixes in plan mode
  • Executes fixes one-by-one with approval
  • Iterates until issue resolved

Test Plan

  1. Set Claude Path in Settings → restart app → verify path persists
  2. Enter invalid path → verify "Done" button is disabled
  3. Send message → check debug report shows "Resolved Executable"
  4. Click "Run Doctor" → verify Terminal session launches with debugging prompt

🤖 Generated with Claude Code

jamesrochabrun and others added 13 commits October 3, 2025 00:09
Launches an autonomous debugging session in Terminal that:
- Analyzes the full debug report
- Investigates the user's environment
- Proposes prioritized fixes in plan mode
- Executes fixes one-by-one with user approval
- Iterates until issue is resolved

Features:
- Uses same command/config as the app (respects preferences)
- Runs in plan permission mode for safety
- Provides systematic troubleshooting workflow
- Helps debug environment/PATH issues

Users can now click "Run Doctor" in Settings > Debug to get
automated help troubleshooting command execution failures.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The prompt was being broken by shell escaping. Now we:
- Write prompt to temp file
- Use input redirection (< file) instead of echo | pipe
- Clean up prompt file after execution

This avoids escaping issues with quotes, newlines, and special characters.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The issue was using '-p' flag which exits after processing.
Now using:
- Interactive session (no -p flag)
- --append-system-prompt with command substitution from file
- Session stays open for debugging workflow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Session now automatically sends:
"Analyze the debug report and help me troubleshoot this issue. Start by investigating the environment."

This kicks off the debugging workflow immediately instead of waiting for user input.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The issue: Piping stdin breaks Claude's interactive TUI.

Solution:
- Removed echo pipe
- Added instruction in system prompt to start immediately
- Claude now auto-starts investigation when session opens
- Keeps interactive mode working (no raw mode error)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Updated system prompt to:
- Start by running diagnostic commands immediately (no plan needed)
- Only create a plan AFTER understanding the problem
- This avoids the initial plan approval blocking auto-start

Workflow: investigate → analyze → create plan → get approval → execute fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
New workflow:
1. Run test command with -p to start session and get initial response
2. Extract session ID from output
3. Resume that session interactively in Terminal
4. Session already has context, so it auto-continues

Benefits:
- Tests command first before investigation
- Session auto-starts with initial message
- Reuses proven session resume approach
- Only investigates if there's actual output to analyze

Fallback: If session ID not captured, starts fresh interactive session.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The flow:
1. Get terminalReproductionCommand from debug report
2. Execute that exact command to start a session
3. Parse session_id from JSON output
4. Resume session in Terminal with doctor prompt
5. Claude has full context (command + output + debug report)

Benefits:
- Tests actual command execution
- Reuses session context
- Doctor sees real results, not assumptions
- Auto-starts with session resume

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Created launchDoctorByExecutingCommand():
- Writes reproduction command to temp file (avoids escaping issues)
- Executes command and captures JSON output
- Extracts session_id from first line
- Resumes session in Terminal with doctor prompt

This is a separate function so we don't touch the working
launchTerminalWithSession() logic.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Delete launchDoctorWithCommand (had escapedCommand error)
- Delete launchDoctorSessionWithTest (not used)
- Delete launchDoctorSession (not used)
- Keep only launchDoctorByExecutingCommand (the working implementation)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Load ~/.zshrc, ~/.bash_profile, or ~/.bashrc to get proper PATH
- Use 'source' instead of 'bash' to execute command file in same shell context
- This ensures claude command is found when executing reproduction command

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…erminal (plan mode). Fixes PATH/alias isolation and session parsing. (#84)
- Add buildDoctorContextMessage() helper to format execution details
- Update resumeSessionInTerminal() to accept capturedOutput and originalCommand
- Pipe context message as first user input: cat context.txt | claude -r ...
- Claude now receives full execution context (command, output, working dir)
- Allows doctor to compare headless execution vs debug report

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
jamesrochabrun and others added 9 commits October 3, 2025 14:00
- Save leadingPrefix when parsing 'echo "..." | claude' commands
- Restore prefix when rebuilding command: leadingPrefix + replacedPortion
- Fixes --print flag error (requires stdin input)

Example:
Before: echo "test" | claude --print -> "/path/claude" --print (missing stdin)
After:  echo "test" | claude --print -> echo "test" | "/path/claude" --print

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add runProcess() helper that combines stdout+stderr
- Check for "Raw mode is not supported" BEFORE checking exit status
- Auto-retry with PTY via script command when Ink error detected
- Fixes headless execution of Claude Code CLI which requires TTY

Flow:
1. Try normal execution via Process
2. Check output for Ink error (may occur even with status 0)
3. If detected, retry: script -q /dev/stdout /bin/zsh -lc "command"
4. Return PTY result

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Set CI=true, TERM=dumb, NO_COLOR=1 to disable TUI
- Fallback to unbuffer (from expect) if Ink error persists
- Replace script approach with unbuffer (designed for this use case)
- Better error message with brew install suggestion

This properly handles Claude CLI's Ink TUI requirements in headless mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
PROBLEM: Claude Code CLI uses Ink TUI which requires real TTY.
Cannot run headlessly via Swift Process() - Ink errors every time.

SOLUTION: Run everything in Terminal (has TTY), no headless execution.

How it works:
1. Launch Terminal with single script that:
   - Executes reproduction command (OUTPUT=$(command 2>&1))
   - Extracts session_id from output
   - Pipes captured output as context into resumed session
2. All in one Terminal window - simple and works with TTY constraints

Removed:
- executeHeadless() - no longer needed
- runProcess() - no longer needed
- extractSessionId() - done in bash now
- buildDoctorContextMessage() - done in bash now
- resumeSessionInTerminal() - done in bash now

Benefits:
- Much simpler approach (1 Terminal script vs complex headless retry logic)
- Actually works (Terminal provides TTY that Ink requires)
- Easier to debug (user can see execution happen in Terminal)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Issues fixed:
1. originalCommand was embedded in bash causing "command not found" errors
2. Hardcoded 'claude' in resume - not in PATH

Solutions:
1. Write originalCommand to temp file, read with cat
2. Extract claude executable path from prepared command via regex
3. Use heredoc for context message to handle multiline properly
4. Use resolved claude path in resume command

Now bash won't try to execute lines from the command string.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Issue: Heredoc content lines caused Swift compiler error due to
insufficient indentation in multiline string literal.

Solution: Avoid heredoc entirely - use echo with string interpolation
and bash brace grouping to build context file.

Before (broke): cat > file <<'EOF' [content] EOF
After (works): { echo "header"; cat file; echo "footer"; } > file

Cleaner and no indentation issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Piping context into resumed session caused Ink TTY error:
cat context.txt | claude -r session --append-system-prompt ...

Solution: Resume without piping - session already has execution context:
claude -r session --append-system-prompt ... --permission-mode plan

Why this works:
- Resumed session contains original execution history
- Debug report is in system prompt (--append-system-prompt)
- No stdin piping = no Ink "raw mode not supported" error
- Claude can analyze the session with doctor prompt in plan mode

Removed:
- Context file building (not needed)
- Stdin piping (caused error)
- contextHeader/contextFooter variables (unused)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Resumed session started fresh with "hello" - no context.

Solution: Use -p flag to send context message when resuming:
- Build CONTEXT_MSG with debug report + command output
- Resume with: claude -r session -p "$CONTEXT_MSG" --append-system-prompt ...
- Claude now sees both debug report AND execution output immediately

Changes:
1. Add debugReport parameter to launchDoctorByExecutingCommand
2. Write debug report to temp file
3. Build context message in bash with debug report + OUTPUT
4. Use -p flag when resuming instead of relying on session history
5. Update system prompt to be instructions-only (no embedded data)

Now Claude receives the full context as the first message in the resumed session.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Heredoc content caused "Insufficient indentation" compiler error
because lines inside heredoc don't align with Swift multiline string rules.

Solution: Use bash string concatenation instead of heredoc:
CONTEXT_MSG="Debug Report:"$'\n'"$(cat file)"$'\n\nCommand Output:\n'"$OUTPUT"

This is simpler and avoids all Swift indentation requirements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
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.

2 participants