fix: validate Claude binary installation before connection (#138)
CI / Build Linux (push) Has been cancelled
CI / Lint & Test (push) Has been cancelled
CI / Build Windows (cross-compile) (push) Has been cancelled
Security Scan and Upload / Security & DefectDojo Upload (push) Has been cancelled

## Summary

Add validation to check that the Claude CLI is installed before attempting to start a connection. If the `claude` binary is not found, users receive a helpful error message with installation instructions.

## Changes

-  Add Claude binary check using `which` command in `WslBridge::start()`
-  Return clear error message with installation command if not found
-  Add test coverage for the binary check logic (`test_claude_binary_check_command_structure`)
-  Update `CLAUDE.md` with Quality Assurance section documenting `check-all.sh`

## Error Message

If Claude Code is not installed, users will see:
```
Claude Code is not installed. Please install it using:

curl -fsSL https://claude.ai/install.sh | bash
```

## Testing

- All 427 backend tests pass 
- All 387 frontend tests pass 
- `check-all.sh` passes with no errors 
- New test validates the `which claude` command structure

## Documentation Updates

Added comprehensive Quality Assurance section to `CLAUDE.md` explaining:
- How to run `check-all.sh` before committing
- What checks are included and their order
- How to source necessary binaries (nvm for Node.js)
- Troubleshooting steps for failures

 This pull request was created by Hikari~ 🌸

Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Reviewed-on: #138
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #138.
This commit is contained in:
2026-02-08 13:47:43 -08:00
committed by Naomi Carrigan
parent fdb356a62c
commit 381bc8410a
3 changed files with 53 additions and 1 deletions
+31
View File
@@ -141,6 +141,37 @@ When developing new features, always add corresponding tests:
The goal is to maintain our near-100% coverage as the codebase grows, so future refactoring and changes can be made with confidence! The goal is to maintain our near-100% coverage as the codebase grows, so future refactoring and changes can be made with confidence!
## Quality Assurance
Before committing any changes, **always run the full test suite**:
```bash
./check-all.sh
```
This script runs all checks in the correct order:
1. Frontend linting (ESLint)
2. Frontend formatting (Prettier)
3. Frontend type checking (svelte-check)
4. Frontend tests with coverage (Vitest)
5. Backend linting (Clippy with strict rules)
6. Backend tests with coverage (cargo test + llvm-cov)
**Important**: The script requires Node.js and Rust toolchains to be available:
- **Node.js tools** (pnpm, npm): Source nvm first if needed: `source ~/.nvm/nvm.sh`
- **Rust tools** (cargo, clippy): Should be in PATH via `~/.cargo/bin/`
If `check-all.sh` reports any failures:
1. Read the error messages carefully - they usually explain what needs fixing
2. Fix the issues (linting errors, test failures, etc.)
3. Run `check-all.sh` again to verify the fixes
4. Only commit once all checks pass ✨
**Never commit code that doesn't pass `check-all.sh`** - this ensures code quality and prevents broken builds!
## Project Context ## Project Context
Hikari Desktop is a Tauri-based desktop application that wraps Claude Code with a visual anime character (Hikari) who appears on screen. This is a personal project where Hikari can sign her work and act as herself! Hikari Desktop is a Tauri-based desktop application that wraps Claude Code with a visual anime character (Hikari) who appears on screen. This is a personal project where Hikari can sign her work and act as herself!
+1 -1
View File
@@ -1636,7 +1636,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "hikari-desktop" name = "hikari-desktop"
version = "1.4.0" version = "1.5.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"dirs 5.0.1", "dirs 5.0.1",
+21
View File
@@ -129,6 +129,11 @@ impl WslBridge {
return Err("Process already running".to_string()); return Err("Process already running".to_string());
} }
// Check if Claude binary is installed before attempting to start
if Command::new("which").arg("claude").output().ok().is_none_or(|output| !output.status.success()) {
return Err("Claude Code is not installed. Please install it using:\n\ncurl -fsSL https://claude.ai/install.sh | bash".to_string());
}
// Load saved achievements and stats when starting a new session // Load saved achievements and stats when starting a new session
let app_clone = app.clone(); let app_clone = app.clone();
let stats = self.stats.clone(); let stats = self.stats.clone();
@@ -1868,6 +1873,22 @@ mod tests {
assert!(!bridge.is_running()); assert!(!bridge.is_running());
} }
#[test]
fn test_claude_binary_check_command_structure() {
// Test that we're using the correct command to check for Claude binary
let output = Command::new("which").arg("claude").output();
// The command should execute successfully (even if claude is not found)
// We're just verifying the command structure is valid
assert!(output.is_ok(), "which command should execute without error");
// Verify the check logic returns a boolean
// This is the same logic used in start() to check if claude is installed
let _result = output.ok().is_none_or(|o| !o.status.success());
// If claude is not installed, _result will be true (show error)
// If claude is installed, _result will be false (proceed with connection)
}
#[test] #[test]
fn test_create_shared_bridge_manager() { fn test_create_shared_bridge_manager() {
use crate::bridge_manager::create_shared_bridge_manager; use crate::bridge_manager::create_shared_bridge_manager;