Skip to content
173 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

preparing for cloud work1//! The g1t desktop app: g1t.sh, or a g1t of your own, in a window of its
2//! own. The window loads the live site, so every change to g1t reaches it
3//! the moment it is deployed and nothing here needs a new build for it;
4//! only what is native lives in this program: notifications from the
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r95//! system, a badge on the icon, a tray, a menu, `g1t://` links, the server
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.6//! to use, the app's own settings, updates that install themselves, and a
7//! self-hosted runner for the signed-in person (runner/mod.rs)
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r98//! (docs.g1t.sh/guides/desktop/).
preparing for cloud work9//!
10//! The site finds the app at `window.g1tDesktop` (bridge.js), the one
11//! contract between the two; what the page asks of it is answered by the
12//! commands in bridge.rs, each of which checks that the page asking is the
13//! configured server's.
14#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
15
16mod badge;
17mod bridge;
18mod config;
Merge branch 'worktree-agent-a6b141eb3a7e9cf01'19mod devtools;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r920mod frame;
preparing for cloud work21mod links;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r922mod menu;
preparing for cloud work23mod navigation;
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.24mod runner;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r925mod settings;
preparing for cloud work26mod tray;
27mod updates;
28
Merge branch 'main' into rm-agents29use tauri::webview::{PageLoadEvent, WebviewBuilder};
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r930use tauri::{RunEvent, WebviewUrl, WindowEvent};
preparing for cloud work31use tauri_plugin_window_state::{StateFlags, WindowExt};
32
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r933/// What the window keeps between launches: its size, place, and whether it
34/// was maximized or full screen; not its frame.
35const KEPT: StateFlags = StateFlags::all().difference(StateFlags::DECORATIONS);
36
preparing for cloud work37/// The one window's label.
38pub const WINDOW: &str = "main";
39
40fn main() {
41 tauri::Builder::default()
42 // A second launch (a g1t:// link, or the icon clicked again) goes to
43 // the app already running: the link reaches links.rs through the
44 // deep-link plugin, and the window comes forward.
45 .plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| tray::show(app)))
46 .plugin(tauri_plugin_deep_link::init())
47 .plugin(tauri_plugin_notification::init())
48 .plugin(tauri_plugin_opener::init())
49 .plugin(tauri_plugin_updater::Builder::new().build())
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r950 // The window's size and place come back in setup, without the plugin
51 // also showing it: at sign-in g1t may start in the tray. Whether it
52 // has the system's frame is the title bar setting's (frame.rs), never
53 // what an earlier run left: kept, it would put the frame back round
54 // g1t's own title bar.
55 .plugin(
56 tauri_plugin_window_state::Builder::new()
57 .with_state_flags(KEPT)
58 .skip_initial_state(WINDOW)
59 .with_denylist(&[settings::SETTINGS])
60 .build(),
61 )
62 // Opening at sign-in, which settings turn on; the argument tells that start from someone's.
63 .plugin(tauri_plugin_autostart::init(tauri_plugin_autostart::MacosLauncher::LaunchAgent, Some(vec![settings::AT_LOGIN])))
preparing for cloud work64 .manage(config::State::default())
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r965 .manage(frame::State::default())
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.66 .manage(runner::Shared::default())
preparing for cloud work67 .invoke_handler(tauri::generate_handler![
68 bridge::desktop_info,
69 bridge::notify,
70 bridge::set_badge,
71 bridge::open_url,
72 bridge::reachable,
73 bridge::set_server,
74 bridge::check_for_updates,
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r975 bridge::open_settings,
76 bridge::get_settings,
77 bridge::save_settings,
78 bridge::set_open_at_login,
79 bridge::change_server,
80 bridge::restart_to_update,
81 bridge::restart,
82 bridge::window_control,
83 bridge::window_menu,
84 bridge::title_bar_page,
85 bridge::title_bar_current,
86 bridge::title_bar_act,
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.87 bridge::runner_status,
88 bridge::runner_offer,
89 bridge::runner_register,
90 bridge::runner_control,
Merge branch 'main' into rm-agents91 bridge::site_ready,
Merge branch 'worktree-agent-a6b141eb3a7e9cf01'92 bridge::open_devtools,
preparing for cloud work93 ])
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r994 .on_menu_event(|app, event| menu::handle(app, event.id().as_ref()))
preparing for cloud work95 .setup(|app| {
96 let handle = app.handle().clone();
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r997 config::note_dev_server(&handle);
preparing for cloud work98 config::load(&handle);
99 config::allow_site(&handle)?;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9100 let hidden = settings::starts_hidden(&handle);
101 let prefs = config::settings(&handle);
102 let custom = frame::started(&handle);
103 // The site's web view: the launcher first, which goes on to the server.
104 let site = WebviewBuilder::new(frame::SITE, WebviewUrl::App("index.html".into()))
105 .initialization_script(bridge::script(custom))
Merge branch 'worktree-agent-a6b141eb3a7e9cf01'106 // The web inspector, as the Developer tools setting has it now (devtools.rs).
107 .devtools(devtools::started(&handle))
preparing for cloud work108 .on_navigation({
109 let handle = handle.clone();
110 move |url| navigation::allowed(&handle, url)
111 })
112 .on_page_load({
113 let handle = handle.clone();
Merge branch 'main' into rm-agents114 move |_webview, payload| config::at(&handle, payload.url().clone(), matches!(payload.event(), PageLoadEvent::Started))
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9115 });
116 let builder = frame::main_window(app, custom)?;
117 // macOS has one menu bar, the app's; elsewhere the menu is the window's own.
118 #[cfg(target_os = "macos")]
119 app.set_menu(menu::build(&handle)?)?;
120 #[cfg(not(target_os = "macos"))]
121 let builder = builder.menu(menu::build(&handle)?);
122 let window = builder.build()?;
123 // Opened at sign-in, g1t waits in the tray; otherwise the window comes up where it was.
124 let _ = window.restore_state(KEPT - StateFlags::VISIBLE);
125 frame::fill(&window, custom, site)?;
126 frame::layout(&window);
127 #[cfg(not(target_os = "macos"))]
128 frame::menu_bar(&window, custom);
129 if !hidden {
130 let _ = window.show();
131 if let Some(site) = frame::site(&handle) {
132 let _ = site.set_focus();
133 }
134 }
135 if let Some(site) = frame::site(&handle).filter(|_| prefs.zoom != 1.0) {
136 let _ = site.set_zoom(prefs.zoom);
137 }
138 // Closing the window keeps g1t running, for notifications, unless
139 // settings say it quits. A new size gives the bar and the site theirs.
preparing for cloud work140 window.on_window_event({
141 let handle = handle.clone();
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9142 let window = window.clone();
143 move |event| match event {
144 WindowEvent::CloseRequested { api, .. } => {
preparing for cloud work145 api.prevent_close();
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9146 tray::close(&handle);
preparing for cloud work147 }
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9148 WindowEvent::Resized(_) | WindowEvent::ScaleFactorChanged { .. } => frame::layout(&window),
149 _ => {}
preparing for cloud work150 }
151 });
152 tray::install(&handle)?;
153 links::install(&handle);
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.154 updates::schedule(handle.clone());
155 // The runner starts on a thread of its own, a few seconds after the window.
156 runner::install(&handle);
preparing for cloud work157 Ok(())
158 })
159 .build(tauri::generate_context!())
160 .expect("g1t could not start")
161 .run(|app, event| match event {
162 // The dock icon, clicked while the window is hidden.
163 #[cfg(target_os = "macos")]
164 RunEvent::Reopen { .. } => tray::show(app),
165 // No window open is not a reason to quit: the tray is still there.
166 RunEvent::ExitRequested { api, code: None, .. } => api.prevent_exit(),
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.167 // However g1t ends, the runner it started ends with it.
168 RunEvent::Exit => runner::shutdown(app),
preparing for cloud work169 _ => {
170 let _ = app;
171 }
172 });
173}

This file's history is long; its oldest lines are credited to the oldest commit read.