Skip to content

Commit 713de37

Browse files
committed
refactor: modularize app source by splitting src/app.rs into separate UI, state, input, and capture modules.
1 parent b189e86 commit 713de37

19 files changed

Lines changed: 3366 additions & 3960 deletions

scratch/add_state_imports.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
with open('src/app/state.rs', 'r') as f:
2+
state_rs = f.read()
3+
4+
imports = """
5+
use crate::engine::{BrowserEngine, EngineEvent, EngineStatus, FocusState, RenderSurfaceMetadata, SecurityWarningKind};
6+
use crate::extraction::extract_entities;
7+
use std::time::Duration;
8+
use std::sync::{Arc, RwLock};
9+
"""
10+
11+
state_rs = imports + state_rs
12+
13+
with open('src/app/state.rs', 'w') as f:
14+
f.write(state_rs)

scratch/extract_capture.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import re
2+
3+
with open('src/app/mod.rs', 'r') as f:
4+
mod_rs = f.read()
5+
6+
funcs_to_extract = [
7+
"fn update_render_frame",
8+
"fn capture_frame_to_disk",
9+
"fn save_snapshot_to_disk",
10+
"fn resolve_capture_dir",
11+
"fn sample_pixel_rgba"
12+
]
13+
14+
extracted_funcs = []
15+
16+
for func in funcs_to_extract:
17+
start_idx = mod_rs.find(f" {func}")
18+
if start_idx != -1:
19+
brace_count = 0
20+
end_idx = -1
21+
for i in range(start_idx, len(mod_rs)):
22+
if mod_rs[i] == '{': brace_count += 1
23+
elif mod_rs[i] == '}':
24+
brace_count -= 1
25+
if brace_count == 0:
26+
end_idx = i + 1
27+
break
28+
29+
extracted = mod_rs[start_idx:end_idx]
30+
extracted = extracted.replace("fn ", "pub(super) fn ")
31+
extracted_funcs.append(extracted)
32+
mod_rs = mod_rs[:start_idx] + mod_rs[end_idx:]
33+
34+
with open('src/app/capture.rs', 'w') as f:
35+
f.write("use super::*;\nuse crate::engine::{RenderSurfaceMetadata};\nuse eframe::egui::ColorImage;\n\nimpl BrazenApp {\n" + "\n\n".join(extracted_funcs) + "\n}\n")
36+
37+
with open('src/app/mod.rs', 'w') as f:
38+
f.write(mod_rs)

scratch/extract_input.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import re
2+
3+
with open('src/app/mod.rs', 'r') as f:
4+
mod_rs = f.read()
5+
6+
# Find forward_input_events
7+
start_idx = mod_rs.find(" fn forward_input_events(&mut self, ctx: &eframe::egui::Context) {")
8+
if start_idx != -1:
9+
brace_count = 0
10+
end_idx = -1
11+
for i in range(start_idx, len(mod_rs)):
12+
if mod_rs[i] == '{': brace_count += 1
13+
elif mod_rs[i] == '}':
14+
brace_count -= 1
15+
if brace_count == 0:
16+
end_idx = i + 1
17+
break
18+
19+
input_fn = mod_rs[start_idx:end_idx]
20+
# change from `fn forward_input_events` to `pub(super) fn forward_input_events`
21+
input_fn = input_fn.replace("fn forward_input_events", "pub(super) fn forward_input_events")
22+
23+
# Write to input.rs
24+
with open('src/app/input.rs', 'w') as f:
25+
f.write("use super::*;\nuse crate::engine::{InputEvent, AlphaMode};\n\nimpl BrazenApp {\n" + input_fn + "\n}\n")
26+
27+
# Remove from mod.rs
28+
mod_rs = mod_rs[:start_idx] + mod_rs[end_idx:]
29+
30+
with open('src/app/mod.rs', 'w') as f:
31+
f.write(mod_rs)

scratch/extract_shell_state.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import re
2+
3+
with open('src/app/mod.rs', 'r') as f:
4+
mod_rs = f.read()
5+
6+
# Extract ShellState struct and impl
7+
struct_match = re.search(r'#\[derive\([^)]*\)\]\s*pub struct ShellState \{.*?\}', mod_rs, flags=re.DOTALL)
8+
impl_match = re.search(r'impl ShellState \{.*?^\}', mod_rs, flags=re.MULTILINE|re.DOTALL)
9+
10+
struct_str = struct_match.group(0) if struct_match else ""
11+
impl_str = impl_match.group(0) if impl_match else ""
12+
13+
if struct_str:
14+
mod_rs = mod_rs.replace(struct_str, "")
15+
if impl_str:
16+
mod_rs = mod_rs.replace(impl_str, "")
17+
18+
with open('src/app/mod.rs', 'w') as f:
19+
f.write(mod_rs)
20+
21+
with open('src/app/state.rs', 'r') as f:
22+
state_rs = f.read()
23+
24+
state_rs += "\n\n" + struct_str + "\n\n" + impl_str
25+
26+
with open('src/app/state.rs', 'w') as f:
27+
f.write(state_rs)

scratch/extract_tests.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import re
2+
3+
with open('src/app/mod.rs', 'r') as f:
4+
mod_rs = f.read()
5+
6+
# Extract tests
7+
start_idx = mod_rs.find("#[cfg(test)]\nmod tests {")
8+
if start_idx != -1:
9+
brace_count = 0
10+
end_idx = -1
11+
for i in range(start_idx, len(mod_rs)):
12+
if mod_rs[i] == '{': brace_count += 1
13+
elif mod_rs[i] == '}':
14+
brace_count -= 1
15+
if brace_count == 0:
16+
end_idx = i + 1
17+
break
18+
19+
test_block = mod_rs[start_idx:end_idx]
20+
21+
# Strip `mod tests { ... }` wrappers to put in tests.rs
22+
test_content = re.sub(r'^#\[cfg\(test\)\]\s*mod tests\s*\{', '', test_block)
23+
test_content = test_content[:-1] # remove last brace
24+
25+
with open('src/app/tests.rs', 'w') as f:
26+
f.write("use super::*;\n" + test_content)
27+
28+
mod_rs = mod_rs[:start_idx] + "\n#[cfg(test)]\nmod tests;\n" + mod_rs[end_idx:]
29+
30+
with open('src/app/mod.rs', 'w') as f:
31+
f.write(mod_rs)

scratch/fix_errors.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import re
2+
3+
# Fix panels.rs
4+
with open('src/app/panels.rs', 'r') as f:
5+
panels_rs = f.read()
6+
7+
panels_rs = panels_rs.replace("crate::app::frame_average_ms", "crate::app::ui_main::frame_average_ms")
8+
9+
with open('src/app/panels.rs', 'w') as f:
10+
f.write(panels_rs)
11+
12+
13+
# Fix ui_components.rs
14+
with open('src/app/ui_components.rs', 'r') as f:
15+
ui_comp = f.read()
16+
17+
ui_comp = ui_comp.replace("use super::state::*;", "use super::state::*;\nuse crate::app::PaletteCommand;\nuse crate::engine::EngineStatus;")
18+
19+
with open('src/app/ui_components.rs', 'w') as f:
20+
f.write(ui_comp)
21+
22+
# Fix monitor_chatgpt_mcp in ui_main.rs
23+
# I'll just append it to impl BrazenApp in ui_main.rs
24+
monitor_code = """
25+
pub(super) fn monitor_chatgpt_mcp(&mut self) {
26+
if !self.shell_state.observe_dom || !self.shell_state.control_terminal {
27+
return;
28+
}
29+
30+
let Some(snapshot) = &self.shell_state.dom_snapshot else { return; };
31+
32+
// Use scraper to find <client mcp="terminal">...</client>
33+
let fragment = scraper::Html::parse_fragment(snapshot);
34+
let selector = scraper::Selector::parse("client[mcp=\\"terminal\\"]").unwrap();
35+
36+
for element in fragment.select(&selector) {
37+
let command = element.text().collect::<String>();
38+
let command = command.trim();
39+
if !command.is_empty() && !self.processed_mcp_commands.contains(command) {
40+
tracing::info!(target: "brazen::automation", command = %command, "Found new MCP terminal command in DOM");
41+
42+
// Run command
43+
if let Some(tx) = &self.terminal_tx {
44+
let _ = tx.send(command.to_string());
45+
}
46+
47+
// Mark as processed
48+
self.processed_mcp_commands.insert(command.to_string());
49+
}
50+
}
51+
}
52+
"""
53+
54+
with open('src/app/ui_main.rs', 'r') as f:
55+
ui_main_rs = f.read()
56+
57+
# insert before last } of impl BrazenApp
58+
last_brace = ui_main_rs.find("impl eframe::App")
59+
if last_brace != -1:
60+
# go back to find the } of impl BrazenApp
61+
idx = ui_main_rs.rfind("}", 0, last_brace)
62+
ui_main_rs = ui_main_rs[:idx] + monitor_code + ui_main_rs[idx:]
63+
64+
with open('src/app/ui_main.rs', 'w') as f:
65+
f.write(ui_main_rs)
66+
67+
print("Errors fixed")

scratch/fix_state_imports.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
with open('src/app/state.rs', 'r') as f:
2+
state_rs = f.read()
3+
4+
imports = """
5+
use chrono::Utc;
6+
use crate::session::{NavigationEntry, SessionSnapshot, load_session};
7+
use crate::engine::EngineLoadStatus;
8+
use crate::profile_db::ProfileDb;
9+
use std::time::Instant;
10+
"""
11+
12+
state_rs = imports + state_rs
13+
14+
with open('src/app/state.rs', 'w') as f:
15+
f.write(state_rs)

scratch/fix_structs.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import re
2+
3+
with open('src/app/mod.rs', 'r') as f:
4+
mod_rs = f.read()
5+
6+
# Delete duplicate structs/enums from mod.rs
7+
structs_to_delete = [
8+
"WorkspaceLayout",
9+
"UiTheme",
10+
"UiDensity",
11+
"LayoutPreset",
12+
"SettingsTab",
13+
"LeftPanelTab",
14+
"WorkspacePanels",
15+
"ReadingQueueItem",
16+
"ExtractedEntity"
17+
]
18+
19+
for s in structs_to_delete:
20+
# regex to delete `enum X { ... }` or `struct X { ... }`
21+
mod_rs = re.sub(r'#\[derive\([^)]*\)\]\s*(pub )?(enum|struct)\s+' + s + r'\s*\{[^}]*\}', '', mod_rs, flags=re.MULTILINE)
22+
# also remove `impl Default for WorkspacePanels`
23+
if s == "WorkspacePanels":
24+
mod_rs = re.sub(r'impl Default for WorkspacePanels\s*\{.*?(?=\n\n|\Z)', '', mod_rs, flags=re.MULTILINE|re.DOTALL)
25+
26+
# Find DiagnosticTab and move it
27+
diag_tab_match = re.search(r'#\[derive\([^)]*\)\]\s*(pub )?enum DiagnosticTab\s*\{[^}]*\}', mod_rs)
28+
diag_tab_str = ""
29+
if diag_tab_match:
30+
diag_tab_str = diag_tab_match.group(0)
31+
# make it pub
32+
diag_tab_str = diag_tab_str.replace("enum DiagnosticTab", "pub enum DiagnosticTab")
33+
mod_rs = mod_rs[:diag_tab_match.start()] + mod_rs[diag_tab_match.end():]
34+
35+
# Make PaletteCommand pub
36+
mod_rs = mod_rs.replace("enum PaletteCommand", "pub enum PaletteCommand")
37+
38+
with open('src/app/mod.rs', 'w') as f:
39+
f.write(mod_rs)
40+
41+
with open('src/app/state.rs', 'r') as f:
42+
state_rs = f.read()
43+
44+
# Remove `use super::DiagnosticTab;` from state.rs
45+
state_rs = state_rs.replace("use super::DiagnosticTab;", "")
46+
47+
# add DiagnosticTab
48+
if diag_tab_str:
49+
state_rs += "\n" + diag_tab_str + "\n"
50+
51+
with open('src/app/state.rs', 'w') as f:
52+
f.write(state_rs)
53+
54+
print("Fixed structs in mod.rs and state.rs")

scratch/fix_ui_main.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
with open('src/app/ui_main.rs', 'r') as f:
2+
ui_main = f.read()
3+
4+
# Fix frame_average_ms
5+
ui_main = ui_main.replace("""fn frame_average_ms(times: &VecDeque<f32>) -> Option<f32> {
6+
if times.is_empty() {
7+
return None;
8+
}
9+
let sum: f32 = times.iter().copied().sum();
10+
Some(sum / times.len() as f32)
11+
12+
pub(super) fn monitor_chatgpt_mcp(&mut self) {""", """pub(super) fn frame_average_ms(times: &VecDeque<f32>) -> Option<f32> {
13+
if times.is_empty() {
14+
return None;
15+
}
16+
let sum: f32 = times.iter().copied().sum();
17+
Some(sum / times.len() as f32)
18+
}
19+
20+
impl super::BrazenApp {
21+
pub(super) fn monitor_chatgpt_mcp(&mut self) {""")
22+
23+
with open('src/app/ui_main.rs', 'w') as f:
24+
f.write(ui_main)
25+

0 commit comments

Comments
 (0)