Compare commits

..

2 Commits

Author SHA1 Message Date
minori 3b15384e1b deps: update @codemirror/view to 6.39.13
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m24s
CI / Lint & Test (pull_request) Successful in 17m9s
CI / Build Linux (pull_request) Successful in 20m13s
CI / Build Windows (cross-compile) (pull_request) Successful in 30m7s
2026-02-18 07:11:05 -08:00
minori 9ee89c94e2 deps: update @codemirror/view to 6.39.12
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m15s
CI / Lint & Test (pull_request) Successful in 20m30s
CI / Build Linux (pull_request) Successful in 26m55s
CI / Build Windows (cross-compile) (pull_request) Successful in 39m15s
2026-02-10 07:06:42 -08:00
6 changed files with 35 additions and 114 deletions
+1 -1
View File
@@ -51,7 +51,7 @@
"@codemirror/legacy-modes": "^6.5.2",
"@codemirror/state": "^6.5.4",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.39.11",
"@codemirror/view": "6.39.13",
"@lezer/highlight": "^1.2.3",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
+16 -16
View File
@@ -81,8 +81,8 @@ importers:
specifier: ^6.1.3
version: 6.1.3
'@codemirror/view':
specifier: ^6.39.11
version: 6.39.11
specifier: 6.39.13
version: 6.39.13
'@lezer/highlight':
specifier: ^1.2.3
version: 1.2.3
@@ -323,8 +323,8 @@ packages:
'@codemirror/theme-one-dark@6.1.3':
resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==}
'@codemirror/view@6.39.11':
resolution: {integrity: sha512-bWdeR8gWM87l4DB/kYSF9A+dVackzDb/V56Tq7QVrQ7rn86W0rgZFtlL3g3pem6AeGcb9NQNoy3ao4WpW4h5tQ==}
'@codemirror/view@6.39.13':
resolution: {integrity: sha512-QBO8ZsgJLCbI28KdY0/oDy5NQLqOQVZCozBknxc2/7L98V+TVYFHnfaCsnGh1U+alpd2LOkStVwYY7nW2R1xbw==}
'@csstools/color-helpers@5.1.0':
resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
@@ -2192,14 +2192,14 @@ snapshots:
dependencies:
'@codemirror/language': 6.12.1
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@codemirror/commands@6.8.1':
dependencies:
'@codemirror/language': 6.12.1
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@codemirror/lang-angular@0.1.4':
@@ -2239,7 +2239,7 @@ snapshots:
'@codemirror/lang-javascript': 6.2.4
'@codemirror/language': 6.12.1
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@lezer/css': 1.3.0
'@lezer/html': 1.3.13
@@ -2255,7 +2255,7 @@ snapshots:
'@codemirror/language': 6.12.1
'@codemirror/lint': 6.9.3
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@lezer/javascript': 1.5.4
@@ -2278,7 +2278,7 @@ snapshots:
'@codemirror/lang-html': 6.4.11
'@codemirror/language': 6.12.1
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@lezer/markdown': 1.6.3
@@ -2341,7 +2341,7 @@ snapshots:
'@codemirror/autocomplete': 6.20.0
'@codemirror/language': 6.12.1
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@lezer/xml': 1.0.6
@@ -2358,7 +2358,7 @@ snapshots:
'@codemirror/language@6.12.1':
dependencies:
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/common': 1.5.0
'@lezer/highlight': 1.2.3
'@lezer/lr': 1.4.8
@@ -2371,13 +2371,13 @@ snapshots:
'@codemirror/lint@6.9.3':
dependencies:
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
crelt: 1.0.6
'@codemirror/search@6.6.0':
dependencies:
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
crelt: 1.0.6
'@codemirror/state@6.5.4':
@@ -2388,10 +2388,10 @@ snapshots:
dependencies:
'@codemirror/language': 6.12.1
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
'@lezer/highlight': 1.2.3
'@codemirror/view@6.39.11':
'@codemirror/view@6.39.13':
dependencies:
'@codemirror/state': 6.5.4
crelt: 1.0.6
@@ -3230,7 +3230,7 @@ snapshots:
'@codemirror/lint': 6.9.3
'@codemirror/search': 6.6.0
'@codemirror/state': 6.5.4
'@codemirror/view': 6.39.11
'@codemirror/view': 6.39.13
color-convert@2.0.1:
dependencies:
+1 -3
View File
@@ -86,9 +86,8 @@ impl ContextWarning {
/// Get the context window limit (in tokens) for a given model
fn get_context_window_limit(model: &str) -> u64 {
match model {
// Claude 4.6 family
// Claude 4.6 family - 200K standard (1M beta available via header)
"claude-opus-4-6" => 200_000,
"claude-sonnet-4-6" => 1_000_000, // 1M token context window
// Claude 4.5 family - 200K standard context
"claude-opus-4-5-20251101"
| "claude-sonnet-4-5-20250929"
@@ -503,7 +502,6 @@ pub fn calculate_cost(
let (input_price_per_million, output_price_per_million) = match model {
// Current generation (Claude 4.6)
"claude-opus-4-6" => (5.0, 25.0),
"claude-sonnet-4-6" => (3.0, 15.0),
// Previous generation (Claude 4.5)
"claude-opus-4-5-20251101" => (5.0, 25.0),
+16 -91
View File
@@ -125,19 +125,15 @@ impl WslBridge {
}
pub fn start(&mut self, app: AppHandle, options: ClaudeStartOptions) -> Result<(), String> {
// If a process handle exists but the process has already exited (e.g. due to a
// failed working directory), clean up the stale handle so we can restart cleanly.
if let Some(ref mut process) = self.process {
if process.try_wait().map(|s| s.is_some()).unwrap_or(false) {
self.process = None;
self.stdin = None;
}
}
if self.process.is_some() {
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
let app_clone = app.clone();
let stats = self.stats.clone();
@@ -266,30 +262,6 @@ impl WslBridge {
} else {
// Running on Windows - use wsl with bash login shell to ensure PATH is loaded
tracing::debug!("Windows path - using wsl");
// Check if Claude binary is installed inside WSL
let binary_check = Command::new("wsl")
.args(["-e", "bash", "-lc", "which claude"])
.output();
if let Ok(output) = binary_check {
if !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());
}
}
// Validate the working directory exists inside WSL before spawning
let dir_check = Command::new("wsl")
.args(["-e", "test", "-d", working_dir])
.output();
if let Ok(output) = dir_check {
if !output.status.success() {
return Err(format!(
"Working directory does not exist: {}",
working_dir
));
}
}
let mut cmd = Command::new("wsl");
// Build the claude command with all arguments
@@ -1902,66 +1874,19 @@ mod tests {
}
#[test]
fn test_stale_process_detection_with_try_wait() {
// Spawn a real process that exits immediately so we can verify try_wait detects it
let mut child = Command::new("true").spawn().expect("Failed to spawn 'true'");
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();
// Wait for it to exit
let _ = child.wait();
// 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");
// try_wait on an already-exited process should return Some(_)
let status = child.try_wait();
assert!(
status.is_ok(),
"try_wait should not error on an exited process"
);
// The process has already been waited on, so try_wait might return None or Some
// depending on the OS - what matters is that the call succeeds
}
#[test]
fn test_stale_process_is_some_after_exit() {
// Verify the logic used in start(): a process that has exited is detected
// and the handle is cleaned up so start() can proceed
let mut child = Command::new("true").spawn().expect("Failed to spawn 'true'");
// Let it exit
let _ = child.wait();
// This mirrors the check in start()
let has_exited = child
.try_wait()
.map(|s| s.is_some())
.unwrap_or(false);
// After wait(), try_wait() returns None (already reaped), which means
// unwrap_or(false) → false. The important thing is the call doesn't panic
// and the control flow logic compiles and runs correctly.
let _ = has_exited; // suppress unused warning
}
/// Build the WSL binary check command structure without executing it (for testing)
#[cfg(test)]
fn build_wsl_binary_check_args() -> Vec<&'static str> {
vec!["-e", "bash", "-lc", "which claude"]
}
#[test]
fn test_wsl_binary_check_command_structure() {
// Windows path: verify Claude is detected inside WSL via `wsl -e bash -lc "which claude"`
let args = build_wsl_binary_check_args();
assert_eq!(args[0], "-e");
assert_eq!(args[1], "bash");
assert_eq!(args[2], "-lc");
assert_eq!(args[3], "which claude");
}
#[test]
fn test_linux_binary_check_does_not_panic() {
// Linux/WSL path: find_claude_binary() searches Linux filesystem paths.
// We just verify it runs without panicking; whether it returns Some depends
// on whether Claude is actually installed in this environment.
let _result = find_claude_binary();
// 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]
+1 -2
View File
@@ -83,9 +83,8 @@
{ value: "", label: "Default (from ~/.claude)" },
// Current generation (Claude 4.6)
{ value: "claude-opus-4-6", label: "Claude Opus 4.6 (Most Capable)" },
{ value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6 (Recommended)" },
// Previous generation (Claude 4.5)
{ value: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
{ value: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5 (Recommended)" },
{ value: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5 (Fast & Cheap)" },
{ value: "claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
// Previous generation (Claude 4.x)
-1
View File
@@ -12,7 +12,6 @@ export type BudgetType = "token" | "cost";
export const MODEL_PRICING: Record<string, { input: number; output: number }> = {
// Current generation (Claude 4.6)
"claude-opus-4-6": { input: 5.0, output: 25.0 },
"claude-sonnet-4-6": { input: 3.0, output: 15.0 },
// Previous generation (Claude 4.5)
"claude-opus-4-5-20251101": { input: 5.0, output: 25.0 },
"claude-sonnet-4-5-20250929": { input: 3.0, output: 15.0 },