Skip to content

Commit a482a20

Browse files
author
Michael Feth
committed
refactor(desktop): split oversized files instead of raising the ratchet
The new file-size gate (#6187) pins each file to its base size when that is already over the 1000-line budget, so this branch's additions pushed six files past their ceiling. Every one is split rather than exempted: - shared/api/tauri.ts: the per-turn routing API moves to shared/api/routingPolicy.ts. Self-contained apart from invokeTauri, and deliberately not re-exported from tauri.ts -- that would re-add the lines it sheds and create an import cycle. - discovery.rs: the KNOWN_ACP_RUNTIMES table moves to discovery/known_runtimes.rs. Declared after windows_install so the macro_use macros its entries call are in scope. - discovery/tests.rs and config_bridge/reader_tests.rs: the OpenCode tests move to sibling modules, following the #[path] split reader_tests.rs already carried for this reason. - AgentInstanceEditDialog.tsx: drops a handleOpenChange wrapper that only forwarded to the onOpenChange prop. - lib.rs: collapses three huddle imports into one nested use and globs deep_link, matching the globs the file already uses. The tauri::Listener and shutdown imports are left alone -- both sit under cfg attributes that merging would silently widen. Signed-off-by: Michael Feth <michael@jira-flow.com>
1 parent 3b9563d commit a482a20

11 files changed

Lines changed: 457 additions & 437 deletions

File tree

desktop/src-tauri/src/lib.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,17 @@ use builderlab::*;
5050
#[doc(hidden)]
5151
pub use commands::print_agent_access_owner_only_probe_if_requested;
5252
use commands::*;
53-
use deep_link::{
54-
acknowledge_pending_community_deep_link, acknowledge_pending_entity_deep_link,
55-
acknowledge_pending_navigation_deep_link, clear_pending_navigation_deep_links,
56-
handle_deep_link_url, take_pending_community_deep_link, take_pending_entity_deep_link,
57-
take_pending_navigation_deep_link, PendingCommunityDeepLinks, PendingEntityDeepLinks,
58-
PendingNavigationDeepLinks,
59-
};
60-
use huddle::audio_output::{
61-
get_audio_output_device, list_audio_output_devices, set_audio_output_device,
62-
};
63-
use huddle::reconnect::reconnect_huddle_audio;
53+
use deep_link::*;
6454
use huddle::{
65-
add_agent_to_huddle, check_pipeline_hotstart, close_huddle_companion, confirm_huddle_active,
66-
download_voice_models, end_huddle, get_huddle_agent_pubkeys, get_huddle_state,
67-
get_model_status, get_voice_input_mode, interrupt_huddle_speech, join_huddle, leave_huddle,
68-
open_huddle_window, push_audio_pcm, remove_agent_from_huddle, set_huddle_manual_mic_unmuted,
69-
set_huddle_transcription_enabled, set_tts_enabled, set_voice_input_mode, speak_agent_message,
70-
start_huddle, start_stt_pipeline, HuddlePhase,
55+
add_agent_to_huddle,
56+
audio_output::{get_audio_output_device, list_audio_output_devices, set_audio_output_device},
57+
check_pipeline_hotstart, close_huddle_companion, confirm_huddle_active, download_voice_models,
58+
end_huddle, get_huddle_agent_pubkeys, get_huddle_state, get_model_status, get_voice_input_mode,
59+
interrupt_huddle_speech, join_huddle, leave_huddle, open_huddle_window, push_audio_pcm,
60+
reconnect::reconnect_huddle_audio,
61+
remove_agent_from_huddle, set_huddle_manual_mic_unmuted, set_huddle_transcription_enabled,
62+
set_tts_enabled, set_voice_input_mode, speak_agent_message, start_huddle, start_stt_pipeline,
63+
HuddlePhase,
7164
};
7265
use initial_window::*;
7366
use managed_agents::{

desktop/src-tauri/src/managed_agents/config_bridge/reader_tests.rs

Lines changed: 3 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -219,86 +219,6 @@ fn goose_mcp_config_path_follows_path_root_override() {
219219
);
220220
}
221221

222-
static OPENCODE_CONFIG_LOCK: Mutex<()> = Mutex::new(());
223-
224-
fn with_opencode_config<T>(path: &Path, body: impl FnOnce() -> T) -> T {
225-
let _guard = OPENCODE_CONFIG_LOCK
226-
.lock()
227-
.unwrap_or_else(|err| err.into_inner());
228-
let prior = std::env::var_os("OPENCODE_CONFIG");
229-
std::env::set_var("OPENCODE_CONFIG", path);
230-
let output = body();
231-
match prior {
232-
Some(value) => std::env::set_var("OPENCODE_CONFIG", value),
233-
None => std::env::remove_var("OPENCODE_CONFIG"),
234-
}
235-
output
236-
}
237-
238-
/// End-to-end wiring guard for the whole point of the OpenCode entry: the
239-
/// harness takes no `--model` flag and reads no model env var, so unless the
240-
/// bridge reaches its config file the model field is blank in the panel.
241-
#[test]
242-
fn opencode_surface_takes_its_model_from_the_config_file() {
243-
let dir = tempfile::tempdir().expect("tempdir");
244-
let config = dir.path().join("opencode.jsonc");
245-
std::fs::write(
246-
&config,
247-
r#"{
248-
// real OpenCode configs are JSONC with comments and trailing commas
249-
"$schema": "https://opencode.ai/config.json",
250-
"model": "anthropic/claude-sonnet-4-5",
251-
"mcp": { "filesystem": { "type": "local" } },
252-
}"#,
253-
)
254-
.expect("write config");
255-
256-
let record = test_record();
257-
let runtime = &KnownAcpRuntime {
258-
id: "opencode",
259-
label: "OpenCode",
260-
commands: &["opencode"],
261-
model_env_var: None,
262-
provider_env_var: None,
263-
supports_acp_native_config: false,
264-
thinking_env_var: None,
265-
max_tokens_env_var: None,
266-
context_limit_env_var: None,
267-
required_normalized_fields: &[],
268-
config_file_path: Some("~/.config/opencode/opencode.json"),
269-
config_file_format: Some("json"),
270-
..*test_runtime()
271-
};
272-
273-
let surface = with_opencode_config(&config, || {
274-
read_config_surface(&record, Some(runtime), None, None)
275-
});
276-
277-
let model = surface.normalized.model.expect("model field");
278-
assert_eq!(model.value.as_deref(), Some("claude-sonnet-4-5"));
279-
assert_eq!(model.origin, ConfigOrigin::ConfigFile);
280-
// Nothing can write it back — no env var, no ACP model switching.
281-
assert!(matches!(model.write_via, ConfigWriteMechanism::ReadOnly));
282-
283-
let provider = surface.normalized.provider.expect("provider field");
284-
assert_eq!(provider.value.as_deref(), Some("anthropic"));
285-
286-
assert_eq!(surface.sources.config_file, ConfigTierStatus::Available);
287-
assert_eq!(
288-
surface.sources.config_file_path.as_deref().map(Path::new),
289-
Some(config.as_path()),
290-
"the reported path must be the file actually read, not the static default"
291-
);
292-
assert_eq!(
293-
surface
294-
.extensions
295-
.iter()
296-
.map(|e| e.name.as_str())
297-
.collect::<Vec<_>>(),
298-
vec!["filesystem"]
299-
);
300-
}
301-
302222
#[test]
303223
fn claude_surface_uses_mcp_config_path_not_settings_path() {
304224
let record = test_record();
@@ -1032,3 +952,6 @@ fn numeric_max_tokens_inherits_from_global_env() {
1032952
// ── Extended tests (split file to respect line-count ratchet) ────────────────
1033953
#[path = "reader_tests_ext.rs"]
1034954
mod ext;
955+
956+
#[path = "reader_tests_opencode.rs"]
957+
mod opencode_tests;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//! OpenCode config-bridge tests — split out of `reader_tests.rs` to keep it
2+
//! under the 1000-line file-size ratchet.
3+
//!
4+
//! Included as `mod opencode_tests` inside `reader_tests.rs`, so `use super::*`
5+
//! gives access to all helpers and types from that module.
6+
7+
use super::*;
8+
9+
static OPENCODE_CONFIG_LOCK: Mutex<()> = Mutex::new(());
10+
11+
fn with_opencode_config<T>(path: &Path, body: impl FnOnce() -> T) -> T {
12+
let _guard = OPENCODE_CONFIG_LOCK
13+
.lock()
14+
.unwrap_or_else(|err| err.into_inner());
15+
let prior = std::env::var_os("OPENCODE_CONFIG");
16+
std::env::set_var("OPENCODE_CONFIG", path);
17+
let output = body();
18+
match prior {
19+
Some(value) => std::env::set_var("OPENCODE_CONFIG", value),
20+
None => std::env::remove_var("OPENCODE_CONFIG"),
21+
}
22+
output
23+
}
24+
25+
/// End-to-end wiring guard for the whole point of the OpenCode entry: the
26+
/// harness takes no `--model` flag and reads no model env var, so unless the
27+
/// bridge reaches its config file the model field is blank in the panel.
28+
#[test]
29+
fn opencode_surface_takes_its_model_from_the_config_file() {
30+
let dir = tempfile::tempdir().expect("tempdir");
31+
let config = dir.path().join("opencode.jsonc");
32+
std::fs::write(
33+
&config,
34+
r#"{
35+
// real OpenCode configs are JSONC with comments and trailing commas
36+
"$schema": "https://opencode.ai/config.json",
37+
"model": "anthropic/claude-sonnet-4-5",
38+
"mcp": { "filesystem": { "type": "local" } },
39+
}"#,
40+
)
41+
.expect("write config");
42+
43+
let record = test_record();
44+
let runtime = &KnownAcpRuntime {
45+
id: "opencode",
46+
label: "OpenCode",
47+
commands: &["opencode"],
48+
model_env_var: None,
49+
provider_env_var: None,
50+
supports_acp_native_config: false,
51+
thinking_env_var: None,
52+
max_tokens_env_var: None,
53+
context_limit_env_var: None,
54+
required_normalized_fields: &[],
55+
config_file_path: Some("~/.config/opencode/opencode.json"),
56+
config_file_format: Some("json"),
57+
..*test_runtime()
58+
};
59+
60+
let surface = with_opencode_config(&config, || {
61+
read_config_surface(&record, Some(runtime), None, &no_tiers())
62+
});
63+
64+
let model = surface.normalized.model.expect("model field");
65+
assert_eq!(model.value.as_deref(), Some("claude-sonnet-4-5"));
66+
assert_eq!(model.origin, ConfigOrigin::ConfigFile);
67+
// Nothing can write it back — no env var, no ACP model switching.
68+
assert!(matches!(model.write_via, ConfigWriteMechanism::ReadOnly));
69+
70+
let provider = surface.normalized.provider.expect("provider field");
71+
assert_eq!(provider.value.as_deref(), Some("anthropic"));
72+
73+
assert_eq!(surface.sources.config_file, ConfigTierStatus::Available);
74+
assert_eq!(
75+
surface.sources.config_file_path.as_deref().map(Path::new),
76+
Some(config.as_path()),
77+
"the reported path must be the file actually read, not the static default"
78+
);
79+
assert_eq!(
80+
surface
81+
.extensions
82+
.iter()
83+
.map(|e| e.name.as_str())
84+
.collect::<Vec<_>>(),
85+
vec!["filesystem"]
86+
);
87+
}

0 commit comments

Comments
 (0)