Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
143 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 tray icon and its menu, and showing and hiding the window. Closing
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r92//! the window hides it, unless settings say closing quits; g1t keeps
3//! running for notifications, and the tray's Open, or the icon, brings it
Merge branch 'main' into rm-agents4//! back. The runner's state is a row of its own, which opens the runner's
5//! menu under the title bar's dot, with Start or Stop under it
6//! (runner/mod.rs). Quit is here too. The menu's rows are handled with the
7//! app menu's (menu.rs).
preparing for cloud work8
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r99use std::sync::Mutex;
preparing for cloud work10
11use tauri::menu::{Menu, MenuItem, PredefinedMenuItem};
12use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent};
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r913use tauri::{AppHandle, Wry};
preparing for cloud work14
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r915use crate::{config, updates};
preparing for cloud work16
17pub const TRAY: &str = "g1t";
18
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r919/// The menu rows that restart into a downloaded update, the tray's and
20/// the Help menu's: off until one is.
21static RESTART: Mutex<Vec<MenuItem<Wry>>> = Mutex::new(Vec::new());
22
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.23/// The runner's rows: what it is doing, and Start or Stop.
24static RUNNER: Mutex<Option<(MenuItem<Wry>, MenuItem<Wry>)>> = Mutex::new(None);
25
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r926/// A row that restarts into the update, kept so `update_ready` can turn it on.
27pub fn restart_item(app: &AppHandle) -> tauri::Result<MenuItem<Wry>> {
28 let item = MenuItem::with_id(app, "restart", "Restart to finish updating", false, None::<&str>)?;
29 RESTART.lock().unwrap().push(item.clone());
30 Ok(item)
31}
preparing for cloud work32
33pub fn install(app: &AppHandle) -> tauri::Result<()> {
34 let open = MenuItem::with_id(app, "open", "Open g1t", true, None::<&str>)?;
35 let check = MenuItem::with_id(app, "check", "Check for updates…", true, None::<&str>)?;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r936 let restart = restart_item(app)?;
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.37 let runner_view = crate::runner::view(app);
38 let runner = MenuItem::with_id(app, "runner-status", crate::runner::headline(&runner_view), true, None::<&str>)?;
39 let runner_toggle = MenuItem::with_id(app, "runner-toggle", toggle_text(&runner_view), true, None::<&str>)?;
40 *RUNNER.lock().unwrap() = Some((runner.clone(), runner_toggle.clone()));
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r941 let settings = MenuItem::with_id(app, "settings", "Settings…", true, None::<&str>)?;
preparing for cloud work42 let server = MenuItem::with_id(app, "server", "Use another g1t…", true, None::<&str>)?;
43 let quit = MenuItem::with_id(app, "quit", "Quit g1t", true, None::<&str>)?;
44 let menu = Menu::with_items(
45 app,
46 &[
47 &open,
48 &PredefinedMenuItem::separator(app)?,
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.49 &runner,
50 &runner_toggle,
51 &PredefinedMenuItem::separator(app)?,
preparing for cloud work52 &check,
53 &restart,
54 &PredefinedMenuItem::separator(app)?,
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r955 &settings,
preparing for cloud work56 &server,
57 &PredefinedMenuItem::separator(app)?,
58 &quit,
59 ],
60 )?;
61 let mut tray = TrayIconBuilder::with_id(TRAY)
62 .menu(&menu)
63 .show_menu_on_left_click(false)
64 .tooltip("g1t")
65 .on_tray_icon_event(|tray, event| {
66 if let TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } = event {
67 show(tray.app_handle());
68 }
69 });
70 if let Some(icon) = app.default_window_icon() {
71 tray = tray.icon(icon.clone());
72 }
73 tray.build(app)?;
74 Ok(())
75}
76
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.77fn toggle_text(view: &crate::runner::View) -> &'static str {
78 if view.enabled && !view.paused { "Stop running jobs" } else { "Start running jobs" }
79}
80
81/// The runner changed: its rows, and the icon's tooltip, say what it is doing now.
82pub fn runner_changed(app: &AppHandle, view: &crate::runner::View) {
83 if let Some((status, toggle)) = RUNNER.lock().unwrap().as_ref() {
84 let _ = status.set_text(crate::runner::headline(view));
85 let _ = toggle.set_text(toggle_text(view));
86 }
87 if let Some(tray) = app.tray_by_id(TRAY) {
88 let _ = tray.set_tooltip(Some(format!("g1t · {}", crate::runner::headline(view))));
89 }
90}
91
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r992/// The update is downloaded: the menus say so, and offer the restart.
preparing for cloud work93pub fn update_ready(version: &str) {
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r994 for item in RESTART.lock().unwrap().iter() {
preparing for cloud work95 let _ = item.set_text(format!("Restart to update to {version}"));
96 let _ = item.set_enabled(true);
97 }
98}
99
100pub fn show(app: &AppHandle) {
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9101 if let Some(window) = crate::frame::window(app) {
preparing for cloud work102 let _ = window.show();
103 let _ = window.unminimize();
104 let _ = window.set_focus();
105 }
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9106 if let Some(site) = crate::frame::site(app) {
107 let _ = site.set_focus();
108 }
109}
110
111/// The window was closed: it waits in the tray, or g1t quits, as settings say.
112pub fn close(app: &AppHandle) {
113 if config::settings(app).close_to_tray {
114 hide(app);
115 } else {
116 updates::quit(app);
117 }
preparing for cloud work118}
119
120pub fn hide(app: &AppHandle) {
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9121 if let Some(window) = crate::frame::window(app) {
preparing for cloud work122 let _ = window.hide();
123 }
124}
125
126/// The address of the launcher page bundled with the app.
127pub fn launcher_url(query: &str) -> url::Url {
128 let base = if cfg!(windows) { "http://tauri.localhost/" } else { "tauri://localhost/" };
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9129 let mut url = config::dev_server().cloned().unwrap_or_else(|| url::Url::parse(base).expect("the launcher's address is a URL"));
preparing for cloud work130 url.set_path("/index.html");
131 if !query.is_empty() {
132 url.set_query(Some(query));
133 }
134 url
135}
136
137/// Takes the window to the launcher: `change` to choose another server.
138pub fn launcher(app: &AppHandle, query: &str) {
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9139 if let Some(site) = crate::frame::site(app) {
140 let _ = site.navigate(launcher_url(query));
preparing for cloud work141 show(app);
142 }
143}

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