From a3e0784d14becb94272903cf280591bd1e81eaea Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:03:13 -0700 Subject: [PATCH 01/11] fix: tolerate Windows short temp paths (fixes #838) --- scripts/install.ps1 | 3 ++- scripts/test_windows_launcher_install.ps1 | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/install.ps1 b/scripts/install.ps1 index ffdcbee309..4a40023a21 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -1091,7 +1091,8 @@ Copy-Item -Path $DestBin -Destination $StableBin -Force Set-Content -Path (Join-Path $BuildsDir "stable-version") -Value $VersionNum Install-JcodeLauncher -SourcePath $StableBin -LauncherPath $LauncherPath | Out-Null } finally { - Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue + Get-Item -LiteralPath $TempDir -ErrorAction SilentlyContinue | + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } # Gracefully reload any running background server onto the freshly installed diff --git a/scripts/test_windows_launcher_install.ps1 b/scripts/test_windows_launcher_install.ps1 index 8e757b221a..046fc8ecc6 100644 --- a/scripts/test_windows_launcher_install.ps1 +++ b/scripts/test_windows_launcher_install.ps1 @@ -106,11 +106,14 @@ try { $armManifest = "$digest nested/path/jcode-windows-aarch64.exe" Assert-Equal $digest (Get-JcodeSha256FromManifest -ManifestText $armManifest -AssetName 'jcode-windows-aarch64.exe') 'checksum parser should match the Windows ARM64 release asset' + Write-Host 'test_temp_cleanup_tolerates_windows_short_paths' + $installText = Get-Content -LiteralPath $installScript -Raw + Assert-True ($installText -match '(?m)^\s*Get-Item -LiteralPath \$TempDir -ErrorAction SilentlyContinue \|\r?\n\s*Remove-Item -Recurse -Force -ErrorAction SilentlyContinue\s*$') 'temporary cleanup should resolve the item before removal so Windows 8.3 TEMP paths are tolerated' + Write-Host 'test_optional_setup_and_source_build_are_opt_in' Assert-Equal $false ([bool]$ConfigureAlacritty) 'core install should not install an optional terminal by default' Assert-Equal $false ([bool]$ConfigureHotkey) 'core install should not add login persistence by default' Assert-Equal $false ([bool]$BuildFromSource) 'installer should not start a source build by default' - $installText = Get-Content -LiteralPath $installScript -Raw Assert-True ($installText.Contains('will not start a long source build automatically')) 'missing release assets should produce an explicit source-build opt-in message' Assert-True ($installText.Contains('"--locked", "-p", "jcode", "--bin", "jcode"')) 'source-build fallback should compile only the locked jcode binary target' From cb4a2e8f2f4b2b58571af275f1b4921ba2d7e535 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:04:02 -0700 Subject: [PATCH 02/11] fix: meter compatible remote providers (fixes #831) --- crates/jcode-tui/src/tui/app/misc_ui.rs | 37 +++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/crates/jcode-tui/src/tui/app/misc_ui.rs b/crates/jcode-tui/src/tui/app/misc_ui.rs index f909cc7fc6..b5127cc468 100644 --- a/crates/jcode-tui/src/tui/app/misc_ui.rs +++ b/crates/jcode-tui/src/tui/app/misc_ui.rs @@ -80,6 +80,17 @@ impl ResolvedTokenPricing { } } +fn remote_provider_is_inherently_billed(provider_name: &str) -> bool { + provider_name.contains("opencode") + || provider_name.contains("openrouter") + || provider_name.contains("bedrock") + || provider_name.contains("cerebras") + || provider_name.contains("compatible") + || crate::provider_catalog::openai_compatible_profile_id_for_display_name(provider_name) + .and_then(crate::provider_catalog::openai_compatible_profile_by_id) + .is_some_and(|profile| profile.requires_api_key) +} + /// Update cost calculation based on token usage (for API-key providers) impl App { pub(super) fn current_streaming_tps_elapsed(&self) -> Duration { @@ -358,11 +369,7 @@ impl App { api_key_billed } else { // Providers that are inherently cost-based when proxied remotely. - provider_name.contains("opencode") - || provider_name.contains("openrouter") - || provider_name.contains("bedrock") - || provider_name.contains("cerebras") - || provider_name.contains("compatible") + remote_provider_is_inherently_billed(&provider_name) }; if !billed { return None; @@ -555,3 +562,23 @@ impl App { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::remote_provider_is_inherently_billed; + + #[test] + fn remote_billing_recognizes_deepseek_display_name() { + assert!(remote_provider_is_inherently_billed("DeepSeek")); + } + + #[test] + fn remote_billing_does_not_meter_no_auth_compatible_profiles() { + for provider_name in ["LM Studio", "Ollama"] { + assert!( + !remote_provider_is_inherently_billed(provider_name), + "{provider_name} should not be billed per token" + ); + } + } +} From ef179ed2b678c642e0c3d4141a472f71be7891a1 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:04:12 -0700 Subject: [PATCH 03/11] fix: route slash models through compatible profiles (fixes #840) --- .../jcode-base/src/provider/catalog_routes.rs | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/crates/jcode-base/src/provider/catalog_routes.rs b/crates/jcode-base/src/provider/catalog_routes.rs index 83e6a3e819..d6877c8c9c 100644 --- a/crates/jcode-base/src/provider/catalog_routes.rs +++ b/crates/jcode-base/src/provider/catalog_routes.rs @@ -889,6 +889,13 @@ pub fn remote_model_routes_fallback( continue; } + if model.contains('/') + && let Some(route) = remote_openai_compatible_route_for_model(model) + { + routes.push(route); + continue; + } + if model.contains('/') { let cached = openrouter_cached; let auto_detail = cached @@ -1103,7 +1110,7 @@ pub fn remote_current_openai_compatible_route_for_model( remote_provider_name: Option<&str>, model: &str, ) -> Option { - if model.trim().is_empty() || model.contains('/') || provider_for_model(model).is_some() { + if model.trim().is_empty() || (!model.contains('/') && provider_for_model(model).is_some()) { return None; } @@ -1115,6 +1122,13 @@ pub fn remote_current_openai_compatible_route_for_model( return None; } let resolved = crate::provider_catalog::resolve_openai_compatible_profile(profile); + if model.contains('/') + && !remote_openai_compatible_profile_models(&resolved, profile) + .iter() + .any(|candidate| candidate.0 == model) + { + return None; + } Some(ModelRoute { model: model.to_string(), @@ -1522,6 +1536,35 @@ mod tests { assert!(!route.detail.contains("fallback")); } + #[test] + fn slash_model_fallback_prefers_matching_compatible_profile() { + let guard = EnvGuard::new(); + let model = "vendouple/gpt-5.6-sol"; + guard.save_opencode_cache("https://opencode.ai/zen/v1", &[model]); + + let routes = remote_model_routes_fallback(Some("OpenCode Zen"), &[model.to_string()]); + + assert_eq!(routes.len(), 1, "unexpected fallback routes: {routes:?}"); + assert_eq!(routes[0].provider, "OpenCode Zen"); + assert_eq!(routes[0].api_method, "openai-compatible:opencode"); + assert!(routes[0].available); + } + + #[test] + fn current_compatible_profile_accepts_only_cataloged_slash_models() { + let guard = EnvGuard::new(); + let model = "vendouple/gpt-5.6-sol"; + guard.save_opencode_cache("https://opencode.ai/zen/v1", &[model]); + + let route = remote_current_openai_compatible_route_for_model(Some("OpenCode Zen"), model) + .expect("cataloged slash model should use the current compatible profile"); + assert_eq!(route.api_method, "openai-compatible:opencode"); + assert!( + remote_current_openai_compatible_route_for_model(Some("OpenCode Zen"), "unknown/model") + .is_none() + ); + } + #[test] fn remote_compatible_route_marks_static_model_list_fallback() { let _guard = EnvGuard::new(); From f1361a7196770ebfb8d53542580fbb0872a9fdd2 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:04:55 -0700 Subject: [PATCH 04/11] fix: honor Ctrl-K in remote drafts (fixes #832) --- crates/jcode-tui/src/tui/app/remote.rs | 20 ++++++ .../src/tui/app/remote/key_handling.rs | 4 ++ crates/jcode-tui/src/tui/app/tests.rs | 1 + .../tui/app/tests/issue_832_remote_ctrl_k.rs | 66 +++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 crates/jcode-tui/src/tui/app/tests/issue_832_remote_ctrl_k.rs diff --git a/crates/jcode-tui/src/tui/app/remote.rs b/crates/jcode-tui/src/tui/app/remote.rs index ddf8c30595..48b9213da8 100644 --- a/crates/jcode-tui/src/tui/app/remote.rs +++ b/crates/jcode-tui/src/tui/app/remote.rs @@ -64,6 +64,22 @@ pub(super) use server_events::handle_server_event; const CONNECTION_MESSAGE_TITLE: &str = "Connection"; const RELOAD_MARKER_MAX_AGE: Duration = Duration::from_secs(30); + +fn handle_ctrl_kill_to_end(app: &mut App, code: KeyCode, modifiers: KeyModifiers) -> bool { + // Match the local draft semantics before remote navigation can claim Ctrl+K. + // Ctrl+Shift+K remains reserved for scrolling. + if modifiers.contains(KeyModifiers::CONTROL) + && !modifiers.contains(KeyModifiers::SHIFT) + && matches!(code, KeyCode::Char('k')) + && !app.input.is_empty() + { + input::delete_input_to_end(app); + return true; + } + + false +} + pub(super) enum RemoteEventOutcome { Continue, Reconnect, @@ -1823,6 +1839,10 @@ fn handle_disconnected_key_internal( let mut modifiers = modifiers; ctrl_bracket_fallback_to_esc(&mut code, &mut modifiers); + if handle_ctrl_kill_to_end(app, code, modifiers) { + return Ok(()); + } + if input::handle_navigation_shortcuts(app, code, modifiers) { return Ok(()); } diff --git a/crates/jcode-tui/src/tui/app/remote/key_handling.rs b/crates/jcode-tui/src/tui/app/remote/key_handling.rs index eace5e148b..17017e4832 100644 --- a/crates/jcode-tui/src/tui/app/remote/key_handling.rs +++ b/crates/jcode-tui/src/tui/app/remote/key_handling.rs @@ -546,6 +546,10 @@ async fn handle_remote_key_internal( return Ok(()); } + if handle_ctrl_kill_to_end(app, code, modifiers) { + return Ok(()); + } + if let Some(amount) = app.scroll_keys.scroll_amount(code, modifiers) { if amount < 0 { app.scroll_up((-amount) as usize); diff --git a/crates/jcode-tui/src/tui/app/tests.rs b/crates/jcode-tui/src/tui/app/tests.rs index a6e503e83a..e4110d6c88 100644 --- a/crates/jcode-tui/src/tui/app/tests.rs +++ b/crates/jcode-tui/src/tui/app/tests.rs @@ -49,6 +49,7 @@ include!("tests/keybinding_hot_reload.rs"); include!("tests/terminal_setup_command.rs"); include!("tests/issue_497_copy_ctrl_c.rs"); include!("tests/issue_699_ctrl_d_delete.rs"); +include!("tests/issue_832_remote_ctrl_k.rs"); include!("tests/spinner_slash_commands.rs"); include!("tests/command_suggestions_cache.rs"); include!("tests/skill_invocation_multi_word.rs"); diff --git a/crates/jcode-tui/src/tui/app/tests/issue_832_remote_ctrl_k.rs b/crates/jcode-tui/src/tui/app/tests/issue_832_remote_ctrl_k.rs new file mode 100644 index 0000000000..cf92a5c8f5 --- /dev/null +++ b/crates/jcode-tui/src/tui/app/tests/issue_832_remote_ctrl_k.rs @@ -0,0 +1,66 @@ +#[test] +fn issue_832_remote_ctrl_k_kills_draft_but_ctrl_shift_k_scrolls() { + let _render_lock = scroll_render_test_lock(); + let (mut app, mut terminal) = create_scroll_test_app(100, 30, 1, 20); + let rt = tokio::runtime::Runtime::new().unwrap(); + let _guard = rt.enter(); + let mut remote = crate::tui::backend::RemoteConnection::dummy(); + + render_and_snap(&app, &mut terminal); + app.set_input_for_test("hello world again"); + app.cursor_pos = "hello world ".len(); + + rt.block_on(app.handle_remote_key(KeyCode::Char('k'), KeyModifiers::CONTROL, &mut remote)) + .unwrap(); + + assert_eq!(app.input(), "hello world "); + assert_eq!(app.cursor_pos(), "hello world ".len()); + assert_eq!(app.scroll_offset, 0, "plain Ctrl+K must not jump prompts"); + + app.set_input_for_test("hello world again"); + app.cursor_pos = "hello world ".len(); + rt.block_on(app.handle_remote_key( + KeyCode::Char('k'), + KeyModifiers::CONTROL | KeyModifiers::SHIFT, + &mut remote, + )) + .unwrap(); + + assert_eq!(app.input(), "hello world again"); + assert_eq!(app.cursor_pos(), "hello world ".len()); + assert!(app.scroll_offset > 0, "Ctrl+Shift+K must still scroll up"); +} + +#[test] +fn issue_832_disconnected_ctrl_k_kills_draft_but_ctrl_shift_k_scrolls() { + let _render_lock = scroll_render_test_lock(); + let (mut app, mut terminal) = create_scroll_test_app(100, 30, 1, 20); + + render_and_snap(&app, &mut terminal); + app.set_input_for_test("hello world again"); + app.cursor_pos = "hello world ".len(); + + super::remote::handle_disconnected_key( + &mut app, + KeyCode::Char('k'), + KeyModifiers::CONTROL, + ) + .unwrap(); + + assert_eq!(app.input(), "hello world "); + assert_eq!(app.cursor_pos(), "hello world ".len()); + assert_eq!(app.scroll_offset, 0, "plain Ctrl+K must not jump prompts"); + + app.set_input_for_test("hello world again"); + app.cursor_pos = "hello world ".len(); + super::remote::handle_disconnected_key( + &mut app, + KeyCode::Char('k'), + KeyModifiers::CONTROL | KeyModifiers::SHIFT, + ) + .unwrap(); + + assert_eq!(app.input(), "hello world again"); + assert_eq!(app.cursor_pos(), "hello world ".len()); + assert!(app.scroll_offset > 0, "Ctrl+Shift+K must still scroll up"); +} From b04cb4d56d890b3644600509a1d1bce2a8df3dfd Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:05:06 -0700 Subject: [PATCH 05/11] fix: exclude multiline tool errors from memory focus (fixes #824) --- crates/jcode-base/src/memory_prompt.rs | 11 +++++--- crates/jcode-base/src/memory_tests.rs | 35 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/crates/jcode-base/src/memory_prompt.rs b/crates/jcode-base/src/memory_prompt.rs index 0bf20e09f8..64c7a815cc 100644 --- a/crates/jcode-base/src/memory_prompt.rs +++ b/crates/jcode-base/src/memory_prompt.rs @@ -26,10 +26,13 @@ fn format_content_block_for_relevance(block: &crate::message::ContentBlock) -> O content, is_error, .. } => { if is_error.unwrap_or(false) { - Some(format!( - "[Tool error: {}]", - truncate_chars(content.trim(), MEMORY_CONTEXT_MAX_BLOCK_CHARS / 4) - )) + // Keep the serialized block on one physical line. The focused-query + // filter drops tool blocks by their leading marker, so preserving + // payload newlines would let every line after the first escape as + // apparent conversation prose. + let content = truncate_chars(content.trim(), MEMORY_CONTEXT_MAX_BLOCK_CHARS / 4); + let content = content.split_whitespace().collect::>().join(" "); + Some(format!("[Tool error: {}]", content)) } else { None } diff --git a/crates/jcode-base/src/memory_tests.rs b/crates/jcode-base/src/memory_tests.rs index 2ac6837234..24f638526c 100644 --- a/crates/jcode-base/src/memory_tests.rs +++ b/crates/jcode-base/src/memory_tests.rs @@ -911,6 +911,41 @@ The bug is in the mouse delta calc."; ); } +#[test] +fn focused_query_excludes_multiline_tool_errors_but_keeps_later_user_prose() { + let messages = vec![Message { + role: Role::User, + content: vec![ + ContentBlock::ToolResult { + tool_use_id: "tool-1".to_string(), + content: "This command was not run.\nUNIQUE_MULTILINE_ERROR_PAYLOAD\nThe target cannot be confirmed.\nThe operation is irreversible." + .to_string(), + is_error: Some(true), + }, + ContentBlock::Text { + text: "Keep the token rotation behavior unchanged.".to_string(), + cache_control: None, + }, + ], + timestamp: None, + tool_duration_ms: None, + }]; + + let focused = format_focused_query_for_relevance(&messages); + + assert!(!focused.contains("This command was not run"), "{focused}"); + assert!( + !focused.contains("UNIQUE_MULTILINE_ERROR_PAYLOAD"), + "arbitrary error payload leaked: {focused}" + ); + assert!(!focused.contains("cannot be confirmed"), "{focused}"); + assert!(!focused.contains("irreversible"), "{focused}"); + assert!( + focused.contains("Keep the token rotation behavior unchanged."), + "subsequent user prose was lost: {focused}" + ); +} + #[test] fn focus_query_text_falls_back_when_all_stripped() { let raw = "\nonly boilerplate\n\n[Tool: read]"; From 17d6dceaad3092739682074633425f05b1bac8f0 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:05:52 -0700 Subject: [PATCH 06/11] fix: cancel pending rate-limit retries (fixes #826) --- crates/jcode-tui/src/tui/app/commands.rs | 8 ++++ .../tui/app/tests/issue_496_input_routing.rs | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/crates/jcode-tui/src/tui/app/commands.rs b/crates/jcode-tui/src/tui/app/commands.rs index 402be8bc3e..316eba96a0 100644 --- a/crates/jcode-tui/src/tui/app/commands.rs +++ b/crates/jcode-tui/src/tui/app/commands.rs @@ -836,6 +836,7 @@ pub(super) fn handle_cancel_command(app: &mut App, trimmed: &str) -> bool { return false; } + let pending_retry = app.rate_limit_reset.is_some() && app.rate_limit_pending_message.is_some(); if app.is_processing { app.cancel_requested = true; app.interleave_message = None; @@ -847,6 +848,13 @@ pub(super) fn handle_cancel_command(app: &mut App, trimmed: &str) -> bool { } else { app.set_status_notice("Interrupting..."); } + } else if pending_retry { + app.clear_pending_remote_retry(); + if matches!(app.status, ProcessingStatus::WaitingForNetwork { .. }) { + app.status = ProcessingStatus::Idle; + app.status_detail = None; + } + app.set_status_notice("Pending retry cancelled"); } else { app.push_display_message(DisplayMessage::system( "Nothing to cancel: no prompt or operation is in progress.".to_string(), diff --git a/crates/jcode-tui/src/tui/app/tests/issue_496_input_routing.rs b/crates/jcode-tui/src/tui/app/tests/issue_496_input_routing.rs index 2eb2fc8299..8495b0d6a8 100644 --- a/crates/jcode-tui/src/tui/app/tests/issue_496_input_routing.rs +++ b/crates/jcode-tui/src/tui/app/tests/issue_496_input_routing.rs @@ -61,6 +61,46 @@ fn test_stop_command_processing_requests_interrupt() { assert!(app.cancel_requested, "'/stop' must interrupt like /cancel"); } +#[test] +fn test_cancel_and_stop_clear_pending_rate_limit_retry() { + for command in ["/cancel", "/stop"] { + let mut app = create_test_app(); + let retry_at = Instant::now() + Duration::from_secs(30); + app.rate_limit_reset = Some(retry_at); + app.rate_limit_pending_message = Some(PendingRemoteMessage { + content: "retry me".to_string(), + images: vec![], + is_system: false, + system_reminder: None, + auto_retry: false, + retry_attempts: 0, + retry_at: Some(retry_at), + }); + + app.set_input_for_test(command); + app.submit_input(); + + assert!( + app.rate_limit_reset.is_none(), + "{command} must disarm the retry timer" + ); + assert!( + app.rate_limit_pending_message.is_none(), + "{command} must discard the pending retry payload" + ); + assert!( + !app.cancel_requested, + "{command} must not leak cancellation into the next turn" + ); + assert_eq!( + app.status_notice + .as_ref() + .map(|(message, _)| message.as_str()), + Some("Pending retry cancelled") + ); + } +} + fn pending_api_key_login() -> crate::tui::app::PendingLogin { crate::tui::app::PendingLogin::ApiKeyProfile { provider_id: "openrouter".to_string(), From 88a4ff26c0a6bfaed6914c699df9200458645912 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 17:30:12 -0700 Subject: [PATCH 07/11] fix(ci): satisfy current clippy --- crates/jcode-provider-core/src/openai_schema.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/jcode-provider-core/src/openai_schema.rs b/crates/jcode-provider-core/src/openai_schema.rs index 9dc7919a27..3d5db28fac 100644 --- a/crates/jcode-provider-core/src/openai_schema.rs +++ b/crates/jcode-provider-core/src/openai_schema.rs @@ -117,10 +117,10 @@ pub fn schema_supports_strict(schema: &Value) -> bool { // `description`) is valid JSON Schema, but strict normalization turns it // into an untyped `anyOf` branch that makes OpenAI reject the entire tool // catalog. Fall back to non-strict instead. See issue #713. - if let Some(Value::Object(props)) = map.get("properties") { - if props.values().any(|prop| !schema_has_type_info(prop)) { - return false; - } + if let Some(Value::Object(props)) = map.get("properties") + && props.values().any(|prop| !schema_has_type_info(prop)) + { + return false; } map.values().all(schema_supports_strict) From a6d44cee49d7fabc6c3f40c84a696b42bc53503c Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 17:49:51 -0700 Subject: [PATCH 08/11] fix(ci): satisfy full workspace clippy --- crates/jcode-app-core/src/notifications.rs | 2 +- .../jcode-app-core/src/server/client_lifecycle.rs | 1 + crates/jcode-base/src/auth/mod.rs | 13 ------------- crates/jcode-tui/src/tui/app/onboarding_graph.rs | 2 ++ crates/jcode-tui/src/tui/app/turn_notify.rs | 2 ++ crates/jcode-tui/src/tui/ui_onboarding.rs | 2 +- 6 files changed, 7 insertions(+), 15 deletions(-) diff --git a/crates/jcode-app-core/src/notifications.rs b/crates/jcode-app-core/src/notifications.rs index 99b1812ba4..eaecf74c95 100644 --- a/crates/jcode-app-core/src/notifications.rs +++ b/crates/jcode-app-core/src/notifications.rs @@ -452,7 +452,7 @@ pub fn send_macos_turn_notification( #[cfg(not(target_os = "macos"))] { let _ = (title, subtitle, body, sound); - return false; + false } #[cfg(target_os = "macos")] diff --git a/crates/jcode-app-core/src/server/client_lifecycle.rs b/crates/jcode-app-core/src/server/client_lifecycle.rs index 8278c938c1..e3b3401939 100644 --- a/crates/jcode-app-core/src/server/client_lifecycle.rs +++ b/crates/jcode-app-core/src/server/client_lifecycle.rs @@ -2834,6 +2834,7 @@ async fn append_context_message( let _ = client_event_tx.send(event); } +#[allow(clippy::too_many_arguments)] async fn start_processing_message( message: ProcessingMessage, client_session_id: &str, diff --git a/crates/jcode-base/src/auth/mod.rs b/crates/jcode-base/src/auth/mod.rs index 179b578208..bf1f917b2c 100644 --- a/crates/jcode-base/src/auth/mod.rs +++ b/crates/jcode-base/src/auth/mod.rs @@ -986,19 +986,6 @@ fn record_auth_probe_step( timings.push((name, step_start.elapsed().as_millis())); } -fn token_state(result: anyhow::Result) -> AuthState { - match result { - Ok(is_expired) => { - if is_expired { - AuthState::Expired - } else { - AuthState::Available - } - } - Err(_) => AuthState::NotConfigured, - } -} - /// Auth state for an OAuth credential that refreshes automatically. /// /// A short-lived access token is *not* a broken login. Antigravity/Gemini diff --git a/crates/jcode-tui/src/tui/app/onboarding_graph.rs b/crates/jcode-tui/src/tui/app/onboarding_graph.rs index 5a2cd04a6f..e0c462ff54 100644 --- a/crates/jcode-tui/src/tui/app/onboarding_graph.rs +++ b/crates/jcode-tui/src/tui/app/onboarding_graph.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! The onboarding state-space graph, as data. //! //! Onboarding is not one flow: it is a product of independent state spaces (UI diff --git a/crates/jcode-tui/src/tui/app/turn_notify.rs b/crates/jcode-tui/src/tui/app/turn_notify.rs index e5bc8b7c28..71bf839f37 100644 --- a/crates/jcode-tui/src/tui/app/turn_notify.rs +++ b/crates/jcode-tui/src/tui/app/turn_notify.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! Desktop notification for completed long agent turns. //! //! When a turn finishes after a configurable duration (lower threshold when diff --git a/crates/jcode-tui/src/tui/ui_onboarding.rs b/crates/jcode-tui/src/tui/ui_onboarding.rs index 459eb0e174..dde39085d5 100644 --- a/crates/jcode-tui/src/tui/ui_onboarding.rs +++ b/crates/jcode-tui/src/tui/ui_onboarding.rs @@ -684,7 +684,7 @@ pub(super) fn draw_onboarding_welcome(frame: &mut Frame, app: &dyn TuiState, are // The title/hint block is dropped first when the area is short so the // phase body (the actionable part) always fits. - let show_title_block = area.height >= telemetry_h + TITLE_H + HINT_H + body_h + GAP * 2 + 1; + let show_title_block = area.height > telemetry_h + TITLE_H + HINT_H + body_h + GAP * 2; let used = if show_title_block { telemetry_h + GAP + TITLE_H + HINT_H + GAP + body_h From 8982760013149d6f125c4cac59edd200a572fe55 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 18:02:30 -0700 Subject: [PATCH 09/11] chore(ci): sync code-size ratchet --- scripts/code_size_budget.json | 103 +++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/scripts/code_size_budget.json b/scripts/code_size_budget.json index c7cdf68c90..67acd48d66 100644 --- a/scripts/code_size_budget.json +++ b/scripts/code_size_budget.json @@ -1,105 +1,116 @@ { "threshold_loc": 1200, "tracked_files": { - "crates/jcode-app-core/src/agent/turn_streaming_mpsc.rs": 1710, + "crates/jcode-app-core/src/agent/turn_loops.rs": 1260, + "crates/jcode-app-core/src/agent/turn_streaming_mpsc.rs": 1730, "crates/jcode-app-core/src/overnight.rs": 1275, "crates/jcode-app-core/src/server.rs": 2376, - "crates/jcode-app-core/src/server/client_lifecycle.rs": 3180, - "crates/jcode-app-core/src/server/client_session.rs": 1710, + "crates/jcode-app-core/src/server/client_lifecycle.rs": 3282, + "crates/jcode-app-core/src/server/client_session.rs": 1716, "crates/jcode-app-core/src/server/comm_control.rs": 2625, - "crates/jcode-app-core/src/server/comm_session.rs": 1435, + "crates/jcode-app-core/src/server/comm_session.rs": 1434, "crates/jcode-app-core/src/server/debug_server_state.rs": 1257, "crates/jcode-app-core/src/server/jade_relay.rs": 1429, "crates/jcode-app-core/src/server/provider_control.rs": 1600, "crates/jcode-app-core/src/server/swarm.rs": 3170, "crates/jcode-app-core/src/tool/bash.rs": 1283, "crates/jcode-app-core/src/tool/communicate.rs": 3351, - "crates/jcode-app-core/src/tool/discover.rs": 2091, + "crates/jcode-app-core/src/tool/discover.rs": 2299, + "crates/jcode-app-core/src/tool/mod.rs": 1230, + "crates/jcode-app-core/src/tool/selfdev/build_queue.rs": 1264, "crates/jcode-app-core/src/tool/session_search.rs": 1892, - "crates/jcode-app-core/src/tool/todo.rs": 1804, + "crates/jcode-app-core/src/tool/todo.rs": 2408, "crates/jcode-app-core/src/update.rs": 1717, "crates/jcode-base/src/auth/lifecycle.rs": 2593, - "crates/jcode-base/src/auth/mod.rs": 1561, - "crates/jcode-base/src/auth/oauth.rs": 1531, + "crates/jcode-base/src/auth/mod.rs": 1615, + "crates/jcode-base/src/auth/oauth.rs": 1518, "crates/jcode-base/src/background.rs": 1465, "crates/jcode-base/src/compaction.rs": 1790, "crates/jcode-base/src/gmail.rs": 1213, "crates/jcode-base/src/import.rs": 1495, "crates/jcode-base/src/memory.rs": 2065, "crates/jcode-base/src/memory_agent.rs": 1901, - "crates/jcode-base/src/provider/catalog_routes.rs": 1610, - "crates/jcode-base/src/provider/mod.rs": 2798, + "crates/jcode-base/src/provider/catalog_routes.rs": 1653, + "crates/jcode-base/src/provider/mod.rs": 2805, "crates/jcode-base/src/session.rs": 1622, "crates/jcode-base/src/sidecar.rs": 1319, "crates/jcode-base/src/skill.rs": 1426, - "crates/jcode-base/src/todo.rs": 1277, - "crates/jcode-config-types/src/lib.rs": 1496, + "crates/jcode-base/src/todo.rs": 1917, + "crates/jcode-config-types/src/lib.rs": 1549, "crates/jcode-desktop2/src/editor.rs": 1373, - "crates/jcode-desktop2/src/main.rs": 1667, - "crates/jcode-desktop2/src/scene.rs": 1256, - "crates/jcode-desktop2/src/states.rs": 1243, - "crates/jcode-desktop2/src/transcript.rs": 3213, + "crates/jcode-desktop2/src/keymap.rs": 1323, + "crates/jcode-desktop2/src/layout.rs": 1453, + "crates/jcode-desktop2/src/main.rs": 2207, + "crates/jcode-desktop2/src/scene.rs": 1900, + "crates/jcode-desktop2/src/states.rs": 1593, + "crates/jcode-desktop2/src/transcript.rs": 3974, + "crates/jcode-harness-api-server/src/translate.rs": 1851, "crates/jcode-import-core/src/lib.rs": 1645, + "crates/jcode-math/src/layout.rs": 1512, "crates/jcode-plan/src/lib.rs": 1201, - "crates/jcode-protocol/src/wire.rs": 1450, - "crates/jcode-provider-anthropic-runtime/src/lib.rs": 2394, + "crates/jcode-protocol/src/wire.rs": 1460, + "crates/jcode-provider-anthropic-runtime/src/lib.rs": 2499, "crates/jcode-provider-bedrock/src/lib.rs": 1979, "crates/jcode-provider-core/src/lib.rs": 1642, "crates/jcode-provider-doctor/src/lifecycle_driver.rs": 1974, "crates/jcode-provider-doctor/src/live_provider_probes.rs": 2029, "crates/jcode-provider-doctor/src/provider_e2e.rs": 2713, "crates/jcode-provider-openai-runtime/src/lib.rs": 1384, - "crates/jcode-provider-openai-runtime/src/openai_provider_impl.rs": 1208, + "crates/jcode-provider-openai-runtime/src/openai_provider_impl.rs": 1229, "crates/jcode-provider-openai-runtime/src/openai_stream_runtime.rs": 1650, - "crates/jcode-provider-openrouter-runtime/src/lib.rs": 2821, + "crates/jcode-provider-openrouter-runtime/src/lib.rs": 2707, "crates/jcode-render-core/src/math.rs": 1234, + "crates/jcode-sdk/src/client.rs": 1379, "crates/jcode-setup-hints/src/lib.rs": 2635, - "crates/jcode-telemetry-core/src/lib.rs": 2165, - "crates/jcode-terminal-launch/src/lib.rs": 1219, - "crates/jcode-tui-mermaid/src/lib.rs": 1496, - "crates/jcode-tui-mermaid/src/mermaid_cache_render.rs": 1467, + "crates/jcode-telemetry-core/src/lib.rs": 2336, + "crates/jcode-terminal-launch/src/lib.rs": 1692, + "crates/jcode-tui-markdown/src/markdown_latex_image.rs": 1294, + "crates/jcode-tui-mermaid/src/lib.rs": 1497, + "crates/jcode-tui-mermaid/src/mermaid_cache_render.rs": 1475, "crates/jcode-tui-mermaid/src/mermaid_viewport.rs": 1953, "crates/jcode-tui-render/src/swarm_gallery.rs": 3099, - "crates/jcode-tui/src/tui/app.rs": 2528, - "crates/jcode-tui/src/tui/app/auth.rs": 3391, + "crates/jcode-tui/src/tui/app.rs": 2542, + "crates/jcode-tui/src/tui/app/auth.rs": 3433, + "crates/jcode-tui/src/tui/app/auth_account_commands.rs": 1202, "crates/jcode-tui/src/tui/app/auth_account_picker.rs": 1220, - "crates/jcode-tui/src/tui/app/commands.rs": 3492, + "crates/jcode-tui/src/tui/app/commands.rs": 3545, "crates/jcode-tui/src/tui/app/debug_bench.rs": 1284, - "crates/jcode-tui/src/tui/app/helpers.rs": 1506, - "crates/jcode-tui/src/tui/app/inline_interactive.rs": 4209, - "crates/jcode-tui/src/tui/app/input.rs": 3905, + "crates/jcode-tui/src/tui/app/helpers.rs": 1502, + "crates/jcode-tui/src/tui/app/inline_interactive.rs": 4334, + "crates/jcode-tui/src/tui/app/input.rs": 4022, "crates/jcode-tui/src/tui/app/model_context.rs": 1945, - "crates/jcode-tui/src/tui/app/navigation.rs": 1835, - "crates/jcode-tui/src/tui/app/onboarding_flow_control.rs": 1696, - "crates/jcode-tui/src/tui/app/remote.rs": 2073, - "crates/jcode-tui/src/tui/app/remote/key_handling.rs": 2615, + "crates/jcode-tui/src/tui/app/navigation.rs": 1843, + "crates/jcode-tui/src/tui/app/onboarding_flow_control.rs": 1743, + "crates/jcode-tui/src/tui/app/remote.rs": 2099, + "crates/jcode-tui/src/tui/app/remote/key_handling.rs": 2639, "crates/jcode-tui/src/tui/app/remote/server_events.rs": 2832, "crates/jcode-tui/src/tui/app/run_shell.rs": 1329, "crates/jcode-tui/src/tui/app/state_ui.rs": 2211, - "crates/jcode-tui/src/tui/app/state_ui_input_helpers.rs": 2081, - "crates/jcode-tui/src/tui/app/tui_lifecycle.rs": 1336, - "crates/jcode-tui/src/tui/app/tui_state.rs": 2413, + "crates/jcode-tui/src/tui/app/state_ui_input_helpers.rs": 2085, + "crates/jcode-tui/src/tui/app/tui_lifecycle.rs": 1349, + "crates/jcode-tui/src/tui/app/tui_state.rs": 2417, "crates/jcode-tui/src/tui/app/turn.rs": 1485, - "crates/jcode-tui/src/tui/backend.rs": 1820, + "crates/jcode-tui/src/tui/backend.rs": 1863, "crates/jcode-tui/src/tui/info_widget.rs": 2233, - "crates/jcode-tui/src/tui/mod.rs": 1869, + "crates/jcode-tui/src/tui/mod.rs": 1879, "crates/jcode-tui/src/tui/session_picker.rs": 2437, "crates/jcode-tui/src/tui/session_picker/loading.rs": 2983, - "crates/jcode-tui/src/tui/ui.rs": 3621, + "crates/jcode-tui/src/tui/ui.rs": 3683, "crates/jcode-tui/src/tui/ui_frame_metrics.rs": 1437, "crates/jcode-tui/src/tui/ui_header.rs": 1758, "crates/jcode-tui/src/tui/ui_inline_image.rs": 1726, "crates/jcode-tui/src/tui/ui_inline_interactive.rs": 1268, - "crates/jcode-tui/src/tui/ui_input.rs": 3108, - "crates/jcode-tui/src/tui/ui_messages.rs": 4213, + "crates/jcode-tui/src/tui/ui_input.rs": 3188, + "crates/jcode-tui/src/tui/ui_messages.rs": 4325, "crates/jcode-tui/src/tui/ui_pinned.rs": 2046, - "crates/jcode-tui/src/tui/ui_prepare.rs": 2645, + "crates/jcode-tui/src/tui/ui_prepare.rs": 2655, "crates/jcode-tui/src/tui/ui_tools.rs": 1656, - "crates/jcode-tui/src/tui/ui_viewport.rs": 1523, + "crates/jcode-tui/src/tui/ui_viewport.rs": 1524, "src/bin/memory_recall_bench.rs": 2667, "src/bin/tui_bench.rs": 1763, - "src/cli/commands.rs": 3378, - "src/cli/dispatch.rs": 1404, + "src/cli/acp.rs": 1641, + "src/cli/commands.rs": 3375, + "src/cli/dispatch.rs": 1435, "src/cli/login.rs": 1389, "src/cli/provider_init.rs": 1836 }, From 2d5b54edc8e5dc2eed762f2248829ad8d2ce0aa7 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Fri, 7 Aug 2026 18:03:02 -0700 Subject: [PATCH 10/11] chore(ci): sync remaining quality ratchets --- scripts/panic_budget.json | 10 +- scripts/swallowed_error_budget.json | 250 +++++++++++++++++++------- scripts/test_size_budget.json | 38 ++-- scripts/wildcard_reexport_budget.json | 3 +- 4 files changed, 221 insertions(+), 80 deletions(-) diff --git a/scripts/panic_budget.json b/scripts/panic_budget.json index 6a7fa966c9..8486fbc92b 100644 --- a/scripts/panic_budget.json +++ b/scripts/panic_budget.json @@ -1,5 +1,5 @@ { - "total": 63, + "total": 77, "tracked_files": { "crates/jcode-app-core/src/session_launch.rs": 1, "crates/jcode-app-core/src/tool/communicate.rs": 1, @@ -7,15 +7,21 @@ "crates/jcode-base/src/auth/oauth.rs": 3, "crates/jcode-base/src/hooks.rs": 1, "crates/jcode-desktop2/src/cli.rs": 1, + "crates/jcode-desktop2/src/icons.rs": 2, "crates/jcode-desktop2/src/main.rs": 2, "crates/jcode-desktop2/src/scroll_bench.rs": 1, - "crates/jcode-desktop2/src/states.rs": 1, + "crates/jcode-desktop2/src/states.rs": 2, "crates/jcode-desktop2/src/transcript.rs": 1, + "crates/jcode-harness-api-server/src/translate.rs": 2, "crates/jcode-harness-api/examples/harness_repl.rs": 15, + "crates/jcode-math/src/font.rs": 1, + "crates/jcode-math/src/parse.rs": 4, "crates/jcode-plan/src/dag/ops.rs": 1, + "crates/jcode-provider-anthropic/src/wedge_fixture_check.rs": 3, "crates/jcode-provider-doctor/src/lifecycle_driver.rs": 2, "crates/jcode-render-core/src/math.rs": 4, "crates/jcode-render-core/src/preprocess.rs": 2, + "crates/jcode-sdk/src/structured.rs": 1, "crates/jcode-telemetry-core/src/lib.rs": 2, "crates/jcode-terminal-launch/src/lib.rs": 1, "crates/jcode-tui-core/src/stream_buffer.rs": 3, diff --git a/scripts/swallowed_error_budget.json b/scripts/swallowed_error_budget.json index 3230445724..49a4094e83 100644 --- a/scripts/swallowed_error_budget.json +++ b/scripts/swallowed_error_budget.json @@ -1,9 +1,9 @@ { - "total": 3091, + "total": 3239, "totals_by_pattern": { - "dot_ok": 1157, - "let_underscore": 1168, - "unwrap_or_default": 766 + "dot_ok": 1213, + "let_underscore": 1201, + "unwrap_or_default": 825 }, "tracked_files": { "crates/jcode-app-core/src/agent.rs": { @@ -97,9 +97,9 @@ "unwrap_or_default": 0 }, "crates/jcode-app-core/src/notifications.rs": { - "dot_ok": 0, - "let_underscore": 5, - "unwrap_or_default": 1 + "dot_ok": 3, + "let_underscore": 9, + "unwrap_or_default": 4 }, "crates/jcode-app-core/src/overnight.rs": { "dot_ok": 12, @@ -153,7 +153,7 @@ }, "crates/jcode-app-core/src/server/client_lifecycle.rs": { "dot_ok": 0, - "let_underscore": 30, + "let_underscore": 33, "unwrap_or_default": 0 }, "crates/jcode-app-core/src/server/client_lifecycle_logging.rs": { @@ -436,6 +436,11 @@ "let_underscore": 1, "unwrap_or_default": 0 }, + "crates/jcode-app-core/src/tool/config_edit_notice.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, "crates/jcode-app-core/src/tool/conversation_search.rs": { "dot_ok": 1, "let_underscore": 0, @@ -446,6 +451,11 @@ "let_underscore": 0, "unwrap_or_default": 5 }, + "crates/jcode-app-core/src/tool/discover_secrets.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, "crates/jcode-app-core/src/tool/gmail.rs": { "dot_ok": 0, "let_underscore": 0, @@ -456,6 +466,11 @@ "let_underscore": 0, "unwrap_or_default": 4 }, + "crates/jcode-app-core/src/tool/inflight.rs": { + "dot_ok": 1, + "let_underscore": 0, + "unwrap_or_default": 0 + }, "crates/jcode-app-core/src/tool/ls.rs": { "dot_ok": 1, "let_underscore": 0, @@ -487,9 +502,9 @@ "unwrap_or_default": 1 }, "crates/jcode-app-core/src/tool/selfdev/build_queue.rs": { - "dot_ok": 1, - "let_underscore": 3, - "unwrap_or_default": 0 + "dot_ok": 2, + "let_underscore": 4, + "unwrap_or_default": 2 }, "crates/jcode-app-core/src/tool/selfdev/mod.rs": { "dot_ok": 8, @@ -524,7 +539,7 @@ "crates/jcode-app-core/src/tool/todo.rs": { "dot_ok": 0, "let_underscore": 0, - "unwrap_or_default": 8 + "unwrap_or_default": 10 }, "crates/jcode-app-core/src/tool/webfetch.rs": { "dot_ok": 3, @@ -542,7 +557,7 @@ "unwrap_or_default": 0 }, "crates/jcode-app-core/src/turn_cancel_registry.rs": { - "dot_ok": 1, + "dot_ok": 2, "let_underscore": 0, "unwrap_or_default": 1 }, @@ -573,7 +588,7 @@ }, "crates/jcode-base/src/auth/antigravity.rs": { "dot_ok": 8, - "let_underscore": 3, + "let_underscore": 1, "unwrap_or_default": 0 }, "crates/jcode-base/src/auth/claude.rs": { @@ -593,7 +608,12 @@ }, "crates/jcode-base/src/auth/cursor.rs": { "dot_ok": 10, - "let_underscore": 5, + "let_underscore": 3, + "unwrap_or_default": 0 + }, + "crates/jcode-base/src/auth/env_facts.rs": { + "dot_ok": 0, + "let_underscore": 1, "unwrap_or_default": 0 }, "crates/jcode-base/src/auth/external.rs": { @@ -603,12 +623,12 @@ }, "crates/jcode-base/src/auth/gemini.rs": { "dot_ok": 4, - "let_underscore": 3, + "let_underscore": 1, "unwrap_or_default": 0 }, "crates/jcode-base/src/auth/google.rs": { "dot_ok": 4, - "let_underscore": 2, + "let_underscore": 0, "unwrap_or_default": 0 }, "crates/jcode-base/src/auth/lifecycle.rs": { @@ -628,12 +648,12 @@ }, "crates/jcode-base/src/auth/oauth.rs": { "dot_ok": 4, - "let_underscore": 18, + "let_underscore": 13, "unwrap_or_default": 3 }, "crates/jcode-base/src/auth/refresh_state.rs": { "dot_ok": 0, - "let_underscore": 0, + "let_underscore": 3, "unwrap_or_default": 1 }, "crates/jcode-base/src/auth/test_sandbox.rs": { @@ -686,6 +706,11 @@ "let_underscore": 4, "unwrap_or_default": 2 }, + "crates/jcode-base/src/config/env_overrides.rs": { + "dot_ok": 1, + "let_underscore": 0, + "unwrap_or_default": 0 + }, "crates/jcode-base/src/copilot_usage.rs": { "dot_ok": 0, "let_underscore": 1, @@ -738,7 +763,7 @@ }, "crates/jcode-base/src/hooks.rs": { "dot_ok": 0, - "let_underscore": 1, + "let_underscore": 2, "unwrap_or_default": 0 }, "crates/jcode-base/src/import.rs": { @@ -756,8 +781,18 @@ "let_underscore": 4, "unwrap_or_default": 0 }, + "crates/jcode-base/src/mcp/manager.rs": { + "dot_ok": 1, + "let_underscore": 0, + "unwrap_or_default": 0 + }, + "crates/jcode-base/src/mcp/pool.rs": { + "dot_ok": 2, + "let_underscore": 0, + "unwrap_or_default": 0 + }, "crates/jcode-base/src/mcp/protocol.rs": { - "dot_ok": 0, + "dot_ok": 2, "let_underscore": 0, "unwrap_or_default": 2 }, @@ -832,7 +867,7 @@ "unwrap_or_default": 0 }, "crates/jcode-base/src/prompt.rs": { - "dot_ok": 10, + "dot_ok": 11, "let_underscore": 0, "unwrap_or_default": 0 }, @@ -1009,17 +1044,7 @@ "crates/jcode-base/src/todo.rs": { "dot_ok": 1, "let_underscore": 0, - "unwrap_or_default": 4 - }, - "crates/jcode-base/src/transport/unix.rs": { - "dot_ok": 0, - "let_underscore": 1, - "unwrap_or_default": 0 - }, - "crates/jcode-base/src/transport/windows.rs": { - "dot_ok": 0, - "let_underscore": 1, - "unwrap_or_default": 0 + "unwrap_or_default": 8 }, "crates/jcode-base/src/usage.rs": { "dot_ok": 0, @@ -1126,6 +1151,16 @@ "let_underscore": 1, "unwrap_or_default": 2 }, + "crates/jcode-desktop2/src/app_resume.rs": { + "dot_ok": 0, + "let_underscore": 2, + "unwrap_or_default": 1 + }, + "crates/jcode-desktop2/src/app_workspace.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, "crates/jcode-desktop2/src/capture.rs": { "dot_ok": 0, "let_underscore": 1, @@ -1141,25 +1176,30 @@ "let_underscore": 0, "unwrap_or_default": 0 }, + "crates/jcode-desktop2/src/clipboard_image.rs": { + "dot_ok": 2, + "let_underscore": 0, + "unwrap_or_default": 0 + }, "crates/jcode-desktop2/src/editor.rs": { "dot_ok": 0, "let_underscore": 0, "unwrap_or_default": 1 }, "crates/jcode-desktop2/src/edits.rs": { - "dot_ok": 0, + "dot_ok": 1, "let_underscore": 0, - "unwrap_or_default": 1 + "unwrap_or_default": 2 }, "crates/jcode-desktop2/src/harness.rs": { "dot_ok": 1, "let_underscore": 1, - "unwrap_or_default": 2 + "unwrap_or_default": 4 }, "crates/jcode-desktop2/src/main.rs": { "dot_ok": 0, "let_underscore": 2, - "unwrap_or_default": 0 + "unwrap_or_default": 1 }, "crates/jcode-desktop2/src/mem.rs": { "dot_ok": 4, @@ -1181,21 +1221,56 @@ "let_underscore": 0, "unwrap_or_default": 0 }, + "crates/jcode-desktop2/src/png.rs": { + "dot_ok": 2, + "let_underscore": 0, + "unwrap_or_default": 0 + }, "crates/jcode-desktop2/src/reasoning.rs": { "dot_ok": 3, "let_underscore": 0, "unwrap_or_default": 1 }, + "crates/jcode-desktop2/src/resume.rs": { + "dot_ok": 4, + "let_underscore": 0, + "unwrap_or_default": 2 + }, "crates/jcode-desktop2/src/scene.rs": { "dot_ok": 0, "let_underscore": 0, "unwrap_or_default": 1 }, + "crates/jcode-desktop2/src/scene_workspace.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, "crates/jcode-desktop2/src/scroll_bench.rs": { "dot_ok": 0, "let_underscore": 0, "unwrap_or_default": 1 }, + "crates/jcode-desktop2/src/selfdev_reload.rs": { + "dot_ok": 2, + "let_underscore": 1, + "unwrap_or_default": 0 + }, + "crates/jcode-desktop2/src/syntax.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, + "crates/jcode-desktop2/src/todos.rs": { + "dot_ok": 1, + "let_underscore": 0, + "unwrap_or_default": 0 + }, + "crates/jcode-desktop2/src/transcript.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, "crates/jcode-embedding/src/lib.rs": { "dot_ok": 2, "let_underscore": 0, @@ -1212,14 +1287,14 @@ "unwrap_or_default": 0 }, "crates/jcode-harness-api-server/src/lib.rs": { - "dot_ok": 1, - "let_underscore": 1, + "dot_ok": 2, + "let_underscore": 2, "unwrap_or_default": 0 }, "crates/jcode-harness-api-server/src/translate.rs": { - "dot_ok": 4, - "let_underscore": 0, - "unwrap_or_default": 5 + "dot_ok": 12, + "let_underscore": 2, + "unwrap_or_default": 23 }, "crates/jcode-harness-api/examples/harness_repl.rs": { "dot_ok": 0, @@ -1251,6 +1326,16 @@ "let_underscore": 1, "unwrap_or_default": 1 }, + "crates/jcode-math/src/font.rs": { + "dot_ok": 1, + "let_underscore": 0, + "unwrap_or_default": 0 + }, + "crates/jcode-math/src/parse.rs": { + "dot_ok": 0, + "let_underscore": 5, + "unwrap_or_default": 3 + }, "crates/jcode-memory-types/src/graph.rs": { "dot_ok": 0, "let_underscore": 0, @@ -1308,17 +1393,12 @@ }, "crates/jcode-provider-anthropic-runtime/src/lib.rs": { "dot_ok": 4, - "let_underscore": 14, - "unwrap_or_default": 1 - }, - "crates/jcode-provider-anthropic/src/lib.rs": { - "dot_ok": 0, - "let_underscore": 0, + "let_underscore": 15, "unwrap_or_default": 1 }, "crates/jcode-provider-antigravity-runtime/src/lib.rs": { "dot_ok": 2, - "let_underscore": 18, + "let_underscore": 19, "unwrap_or_default": 3 }, "crates/jcode-provider-antigravity/src/lib.rs": { @@ -1418,7 +1498,7 @@ }, "crates/jcode-provider-gemini-runtime/src/lib.rs": { "dot_ok": 4, - "let_underscore": 23, + "let_underscore": 24, "unwrap_or_default": 6 }, "crates/jcode-provider-gemini/src/lib.rs": { @@ -1467,10 +1547,15 @@ "unwrap_or_default": 6 }, "crates/jcode-provider-openrouter-runtime/src/lib.rs": { - "dot_ok": 23, + "dot_ok": 22, "let_underscore": 0, "unwrap_or_default": 9 }, + "crates/jcode-provider-openrouter-runtime/src/models_catalog_parse.rs": { + "dot_ok": 1, + "let_underscore": 0, + "unwrap_or_default": 0 + }, "crates/jcode-provider-openrouter-runtime/src/openrouter_provider_impl.rs": { "dot_ok": 2, "let_underscore": 3, @@ -1489,7 +1574,7 @@ "crates/jcode-provider-openrouter/src/request.rs": { "dot_ok": 0, "let_underscore": 0, - "unwrap_or_default": 2 + "unwrap_or_default": 1 }, "crates/jcode-render-core/src/math.rs": { "dot_ok": 0, @@ -1501,6 +1586,36 @@ "let_underscore": 0, "unwrap_or_default": 1 }, + "crates/jcode-schema-dialect/src/dialect.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 3 + }, + "crates/jcode-schema-dialect/src/lib.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 1 + }, + "crates/jcode-schema-dialect/src/quirks.rs": { + "dot_ok": 2, + "let_underscore": 2, + "unwrap_or_default": 2 + }, + "crates/jcode-sdk/src/client.rs": { + "dot_ok": 6, + "let_underscore": 4, + "unwrap_or_default": 0 + }, + "crates/jcode-sdk/src/launch.rs": { + "dot_ok": 5, + "let_underscore": 7, + "unwrap_or_default": 3 + }, + "crates/jcode-sdk/src/structured.rs": { + "dot_ok": 0, + "let_underscore": 0, + "unwrap_or_default": 2 + }, "crates/jcode-session-types/src/lib.rs": { "dot_ok": 0, "let_underscore": 0, @@ -1567,13 +1682,13 @@ "unwrap_or_default": 1 }, "crates/jcode-telemetry-core/src/lib.rs": { - "dot_ok": 7, + "dot_ok": 8, "let_underscore": 10, "unwrap_or_default": 3 }, "crates/jcode-telemetry-core/src/lifecycle.rs": { "dot_ok": 0, - "let_underscore": 2, + "let_underscore": 3, "unwrap_or_default": 0 }, "crates/jcode-telemetry-core/src/state_support.rs": { @@ -1591,6 +1706,16 @@ "let_underscore": 0, "unwrap_or_default": 0 }, + "crates/jcode-transport/src/unix.rs": { + "dot_ok": 0, + "let_underscore": 1, + "unwrap_or_default": 0 + }, + "crates/jcode-transport/src/windows.rs": { + "dot_ok": 0, + "let_underscore": 1, + "unwrap_or_default": 0 + }, "crates/jcode-tui-core/src/keybind.rs": { "dot_ok": 1, "let_underscore": 0, @@ -1608,7 +1733,7 @@ }, "crates/jcode-tui-markdown/src/markdown_latex_image.rs": { "dot_ok": 4, - "let_underscore": 5, + "let_underscore": 6, "unwrap_or_default": 0 }, "crates/jcode-tui-markdown/src/markdown_mermaid_fallback.rs": { @@ -1734,7 +1859,7 @@ "crates/jcode-tui/src/tui/app/auth.rs": { "dot_ok": 7, "let_underscore": 3, - "unwrap_or_default": 12 + "unwrap_or_default": 13 }, "crates/jcode-tui/src/tui/app/auth_account_commands.rs": { "dot_ok": 0, @@ -1852,9 +1977,9 @@ "unwrap_or_default": 1 }, "crates/jcode-tui/src/tui/app/input.rs": { - "dot_ok": 8, + "dot_ok": 9, "let_underscore": 3, - "unwrap_or_default": 3 + "unwrap_or_default": 4 }, "crates/jcode-tui/src/tui/app/local.rs": { "dot_ok": 0, @@ -2019,7 +2144,7 @@ "crates/jcode-tui/src/tui/app/turn_notify.rs": { "dot_ok": 0, "let_underscore": 0, - "unwrap_or_default": 2 + "unwrap_or_default": 4 }, "crates/jcode-tui/src/tui/app/ui_prefs.rs": { "dot_ok": 1, @@ -2234,7 +2359,7 @@ "src/cli/acp.rs": { "dot_ok": 1, "let_underscore": 5, - "unwrap_or_default": 2 + "unwrap_or_default": 3 }, "src/cli/commands.rs": { "dot_ok": 11, @@ -2281,6 +2406,11 @@ "let_underscore": 2, "unwrap_or_default": 0 }, + "src/cli/macos_notification_broker.rs": { + "dot_ok": 6, + "let_underscore": 4, + "unwrap_or_default": 0 + }, "src/cli/provider_init.rs": { "dot_ok": 2, "let_underscore": 14, diff --git a/scripts/test_size_budget.json b/scripts/test_size_budget.json index b81a891543..a80acd6442 100644 --- a/scripts/test_size_budget.json +++ b/scripts/test_size_budget.json @@ -1,25 +1,28 @@ { "threshold_loc": 1200, "tracked_files": { - "crates/jcode-app-core/src/agent_tests.rs": 1585, - "crates/jcode-app-core/src/server/client_lifecycle_tests.rs": 1232, + "crates/jcode-app-core/src/agent_tests.rs": 1760, + "crates/jcode-app-core/src/server/client_lifecycle_tests.rs": 1410, "crates/jcode-app-core/src/server/comm_control_tests/dag_e2e.rs": 1332, "crates/jcode-app-core/src/server/provider_control_tests.rs": 1393, "crates/jcode-app-core/src/server/swarm_persistence_tests.rs": 1232, - "crates/jcode-app-core/src/tool/communicate_tests.rs": 1795, + "crates/jcode-app-core/src/tool/communicate_tests.rs": 1796, "crates/jcode-app-core/src/tool/selfdev/tests.rs": 1440, - "crates/jcode-base/src/config_tests.rs": 1284, + "crates/jcode-app-core/src/tool/tests.rs": 1586, + "crates/jcode-base/src/config_tests.rs": 1335, "crates/jcode-base/src/live_tests.rs": 3087, "crates/jcode-base/src/provider/tests/model_resolution.rs": 2337, "crates/jcode-base/src/session_tests/cases.rs": 2448, - "crates/jcode-desktop2/src/tests/actions.rs": 1296, + "crates/jcode-desktop2/src/tests/actions.rs": 1518, + "crates/jcode-desktop2/src/tests/visual.rs": 1245, + "crates/jcode-harness-api-server/src/translate_tests.rs": 1390, "crates/jcode-plan/src/dag/tests.rs": 1392, - "crates/jcode-provider-anthropic-runtime/src/anthropic_tests.rs": 1937, - "crates/jcode-provider-openrouter-runtime/src/openrouter_tests.rs": 3014, - "crates/jcode-tui/src/tui/app/tests.rs": 1749, - "crates/jcode-tui/src/tui/app/tests/commands_accounts_01/part_01.rs": 1633, + "crates/jcode-provider-anthropic-runtime/src/anthropic_tests.rs": 2017, + "crates/jcode-provider-openrouter-runtime/src/openrouter_tests.rs": 3018, + "crates/jcode-tui/src/tui/app/tests.rs": 1751, + "crates/jcode-tui/src/tui/app/tests/commands_accounts_01/part_01.rs": 1673, "crates/jcode-tui/src/tui/app/tests/onboarding_eval.rs": 3302, - "crates/jcode-tui/src/tui/app/tests/onboarding_flow.rs": 1755, + "crates/jcode-tui/src/tui/app/tests/onboarding_flow.rs": 1784, "crates/jcode-tui/src/tui/app/tests/remote_events_reload_01/part_01.rs": 1930, "crates/jcode-tui/src/tui/app/tests/remote_events_reload_04.rs": 2415, "crates/jcode-tui/src/tui/app/tests/remote_startup_input_02/part_01.rs": 1998, @@ -27,17 +30,18 @@ "crates/jcode-tui/src/tui/app/tests/scroll_copy_02/part_01.rs": 1442, "crates/jcode-tui/src/tui/app/tests/scroll_copy_02/part_02.rs": 1272, "crates/jcode-tui/src/tui/app/tests/scroll_copy_03.rs": 1842, - "crates/jcode-tui/src/tui/app/tests/state_model_poke_01/part_01.rs": 1294, - "crates/jcode-tui/src/tui/app/tests/state_model_poke_02/part_01.rs": 1361, - "crates/jcode-tui/src/tui/app/tests/state_model_poke_03.rs": 2767, - "crates/jcode-tui/src/tui/app/tests/swarm_plan_graph_inline.rs": 1971, - "crates/jcode-tui/src/tui/info_widget_tests.rs": 1810, + "crates/jcode-tui/src/tui/app/tests/state_model_poke_01/part_01.rs": 1356, + "crates/jcode-tui/src/tui/app/tests/state_model_poke_02/part_01.rs": 1376, + "crates/jcode-tui/src/tui/app/tests/state_model_poke_03.rs": 2863, + "crates/jcode-tui/src/tui/app/tests/swarm_plan_graph_inline.rs": 1979, + "crates/jcode-tui/src/tui/info_widget_tests.rs": 1815, "crates/jcode-tui/src/tui/session_picker/loading_tests.rs": 1401, "crates/jcode-tui/src/tui/session_picker_tests.rs": 2453, - "crates/jcode-tui/src/tui/ui_messages/tests.rs": 2908, + "crates/jcode-tui/src/tui/ui_messages/tests.rs": 3095, "crates/jcode-tui/src/tui/ui_tests/prepare.rs": 1285, "crates/jcode-tui/src/tui/ui_tests/tools.rs": 1352, - "tests/e2e/test_support/mod.rs": 1424 + "src/cli/commands_tests.rs": 1274, + "tests/e2e/test_support/mod.rs": 1425 }, "version": 1 } diff --git a/scripts/wildcard_reexport_budget.json b/scripts/wildcard_reexport_budget.json index 77ee906070..eb52b3daf1 100644 --- a/scripts/wildcard_reexport_budget.json +++ b/scripts/wildcard_reexport_budget.json @@ -1,5 +1,5 @@ { - "total": 16, + "total": 17, "files": { "crates/jcode-app-core/src/lib.rs": 1, "crates/jcode-app-core/src/setup_hints.rs": 1, @@ -13,6 +13,7 @@ "crates/jcode-base/src/provider_catalog.rs": 1, "crates/jcode-base/src/stdin_detect.rs": 1, "crates/jcode-base/src/storage.rs": 1, + "crates/jcode-base/src/transport/mod.rs": 1, "crates/jcode-base/src/util.rs": 1, "crates/jcode-tui/src/lib.rs": 1, "crates/jcode-tui/src/tui/mod.rs": 1, From 47e8819ce8f2c24e59d52f6e1289c9813851ebc3 Mon Sep 17 00:00:00 2001 From: jeremy <94247773+1jehuang@users.noreply.github.com> Date: Thu, 6 Aug 2026 02:45:24 -0700 Subject: [PATCH 11/11] fix(ci): compile macOS notification broker --- src/cli/commands/menubar.rs | 16 +++++++--------- src/cli/macos_notification_broker.rs | 18 +++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/cli/commands/menubar.rs b/src/cli/commands/menubar.rs index fb90044c38..7812ca2c7a 100644 --- a/src/cli/commands/menubar.rs +++ b/src/cli/commands/menubar.rs @@ -485,16 +485,14 @@ mod macos { // in points from the right screen edge) before the item is realized // places it among the system icons; afterwards macOS keeps tracking // the user's chosen position under the same key. - unsafe { - let defaults = NSUserDefaults::standardUserDefaults(); - let pos_key = NSString::from_str(&format!( - "NSStatusItem Preferred Position {STATUS_ITEM_AUTOSAVE}" - )); - if defaults.objectForKey(&pos_key).is_none() { - defaults.setInteger_forKey(550, &pos_key); - } - status_item.setAutosaveName(Some(&NSString::from_str(STATUS_ITEM_AUTOSAVE))); + let defaults = NSUserDefaults::standardUserDefaults(); + let pos_key = NSString::from_str(&format!( + "NSStatusItem Preferred Position {STATUS_ITEM_AUTOSAVE}" + )); + if defaults.objectForKey(&pos_key).is_none() { + defaults.setInteger_forKey(550, &pos_key); } + status_item.setAutosaveName(Some(&NSString::from_str(STATUS_ITEM_AUTOSAVE))); // Style the button like a native menu bar extra: a template SF Symbol // (auto-adapts to light/dark menu bars and tinting) plus a compact diff --git a/src/cli/macos_notification_broker.rs b/src/cli/macos_notification_broker.rs index b7ec2f2ab4..5cd6764b9c 100644 --- a/src/cli/macos_notification_broker.rs +++ b/src/cli/macos_notification_broker.rs @@ -85,7 +85,7 @@ mod platform { }) .and_then(|value| serde_json::from_str(&value).ok()); if let Some(origin) = route { - jcode::notifications::activate_macos_notification_origin(&origin); + crate::notifications::activate_macos_notification_origin(&origin); } completion_handler.call(()); } @@ -171,7 +171,7 @@ mod platform { } fn recover_interrupted_submissions() { - let Some(inbox) = jcode::notifications::macos_notification_inbox_dir() else { + let Some(inbox) = crate::notifications::macos_notification_inbox_dir() else { return; }; let Ok(entries) = std::fs::read_dir(inbox) else { @@ -189,7 +189,7 @@ mod platform { } fn drain_inbox(center: &UNUserNotificationCenter) { - let Some(inbox) = jcode::notifications::macos_notification_inbox_dir() else { + let Some(inbox) = crate::notifications::macos_notification_inbox_dir() else { return; }; let Ok(entries) = std::fs::read_dir(inbox) else { @@ -208,7 +208,7 @@ mod platform { let result = std::fs::read(&path) .context("read queued notification") .and_then(|bytes| { - serde_json::from_slice::( + serde_json::from_slice::( &bytes, ) .context("decode queued notification") @@ -219,7 +219,7 @@ mod platform { // retry after this point. Ok(()) => {} Err(error) => { - jcode::logging::warn(&format!( + crate::logging::warn(&format!( "macOS notification broker skipped {}: {error:#}", path.display() )); @@ -240,17 +240,17 @@ mod platform { .and_then(|bytes| serde_json::from_slice::(&bytes).ok()) .and_then(|value| value.get("schema_version")?.as_u64()) .is_some_and(|version| { - version > jcode::notifications::MACOS_NOTIFICATION_SCHEMA_VERSION as u64 + version > crate::notifications::MACOS_NOTIFICATION_SCHEMA_VERSION as u64 }) } fn submit( center: &UNUserNotificationCenter, - envelope: &jcode::notifications::MacosNotificationEnvelope, + envelope: &crate::notifications::MacosNotificationEnvelope, queued_path: &std::path::Path, ) -> Result<()> { anyhow::ensure!( - envelope.schema_version == jcode::notifications::MACOS_NOTIFICATION_SCHEMA_VERSION, + envelope.schema_version == crate::notifications::MACOS_NOTIFICATION_SCHEMA_VERSION, "unsupported notification schema {}", envelope.schema_version ); @@ -296,7 +296,7 @@ mod platform { // Notification Center availability). Preserve the payload for // the next timer pass or helper launch. let _ = std::fs::rename(&submitting_path, &retry_path); - jcode::logging::warn("macOS Notification Center rejected a queued notification"); + crate::logging::warn("macOS Notification Center rejected a queued notification"); } }); center.addNotificationRequest_withCompletionHandler(&request, Some(&completion));