Function bodies 82 total
validatePath function · javascript · L90-L121 (32 LOC)server/workspaceScanner.js
async function validatePath(workspacePath) {
if (!workspacePath || typeof workspacePath !== 'string') {
return false;
}
// Skip validation for remote URLs
if (workspacePath.startsWith('http://') ||
workspacePath.startsWith('https://') ||
workspacePath.startsWith('vscode://') ||
workspacePath.startsWith('vscode-remote://')) {
return true; // Consider remote paths as valid
}
// Handle file:// prefix
let cleanPath = workspacePath;
if (cleanPath.startsWith('file://')) {
cleanPath = cleanPath.substring(7);
}
// Decode URL-encoded characters
try {
cleanPath = decodeURIComponent(cleanPath);
} catch (e) {
// If decoding fails, use original path
}
try {
return await pathExists(cleanPath);
} catch {
return false;
}
}validatePaths function · javascript · L128-L139 (12 LOC)server/workspaceScanner.js
async function validatePaths(workspaces) {
const results = {};
for (const workspace of workspaces) {
if (!workspace || !workspace.id || !workspace.path) {
continue;
}
results[workspace.id] = await validatePath(workspace.path);
}
return results;
}parseWorkspaceType function · javascript · L147-L160 (14 LOC)server/workspaceScanner.js
function parseWorkspaceType(uri) {
if (uri.startsWith('file://')) {
return 'local';
} else if (uri.includes('vscode-remote://dev-container')) {
return 'dev-container';
} else if (uri.includes('vscode-remote://attached-container')) {
return 'attached-container';
} else if (uri.includes('vscode-remote://ssh-remote')) {
return 'ssh-remote';
} else if (uri.startsWith('vscode-remote://')) {
return 'remote';
}
return 'unknown';
}extractWorkspaceName function · javascript · L165-L180 (16 LOC)server/workspaceScanner.js
function extractWorkspaceName(uri) {
try {
// Decode URI components
const decoded = decodeURIComponent(uri);
// Extract the last part of the path
const parts = decoded.split('/');
const lastPart = parts[parts.length - 1];
// Remove file extension if present
return lastPart.replace(/\.(code-workspace|json)$/, '');
} catch (error) {
console.error('Error extracting workspace name:', error);
return 'Unknown';
}
}parseWorkspaceData function · javascript · L185-L215 (31 LOC)server/workspaceScanner.js
function parseWorkspaceData(workspaceJson, workspaceDir, stats) {
try {
const data = JSON.parse(workspaceJson);
let uri = null;
let type = 'unknown';
let name = 'Unknown';
// Check for workspace or folder property
if (data.workspace) {
uri = data.workspace;
type = parseWorkspaceType(uri);
name = extractWorkspaceName(uri);
} else if (data.folder) {
uri = data.folder;
type = parseWorkspaceType(uri);
name = extractWorkspaceName(uri);
}
return {
id: path.basename(workspaceDir),
name,
path: uri || 'Unknown',
type,
lastAccessed: stats.mtime.toISOString(),
storageDir: workspaceDir
};
} catch (error) {
console.error(`Error parsing workspace data:`, error);
return null;
}
}scanWorkspaceDirectory function · javascript · L220-L241 (22 LOC)server/workspaceScanner.js
async function scanWorkspaceDirectory(workspaceDir) {
try {
const workspaceJsonPath = path.join(workspaceDir, 'workspace.json');
// Check if workspace.json exists
try {
await fs.access(workspaceJsonPath);
} catch {
// workspace.json doesn't exist, skip this directory
return null;
}
// Read workspace.json
const workspaceJson = await fs.readFile(workspaceJsonPath, 'utf8');
const stats = await fs.stat(workspaceDir);
return parseWorkspaceData(workspaceJson, workspaceDir, stats);
} catch (error) {
console.error(`Error scanning workspace directory ${workspaceDir}:`, error.message);
return null;
}
}scanWorkspaces function · javascript · L246-L283 (38 LOC)server/workspaceScanner.js
async function scanWorkspaces() {
try {
const WORKSPACE_STORAGE_PATH = getWorkspaceStoragePath();
// Check if workspace storage directory exists
try {
await fs.access(WORKSPACE_STORAGE_PATH);
} catch {
console.error(`Workspace storage directory not found: ${WORKSPACE_STORAGE_PATH}`);
return [];
}
// Read all subdirectories
const entries = await fs.readdir(WORKSPACE_STORAGE_PATH, { withFileTypes: true });
const workspaceDirs = entries
.filter(entry => entry.isDirectory())
.map(entry => path.join(WORKSPACE_STORAGE_PATH, entry.name));
// Scan each workspace directory
const workspacePromises = workspaceDirs.map(scanWorkspaceDirectory);
const workspaces = await Promise.all(workspacePromises);
// Filter out null results (failed scans)
const validWorkspaces = workspaces.filter(ws => ws !== null);
// Log if some workspaces failed to parse
const failedCount = workspaces.length - Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
refreshWorkspaces function · javascript · L288-L292 (5 LOC)server/workspaceScanner.js
async function refreshWorkspaces() {
console.log('Refreshing workspaces...');
workspacesCache = await scanWorkspaces();
console.log(`Found ${workspacesCache.length} workspaces`);
}initialize function · javascript · L297-L318 (22 LOC)server/workspaceScanner.js
async function initialize() {
console.log('Initializing workspace scanner...');
console.log(`Detected platform: ${process.platform}`);
const WORKSPACE_STORAGE_PATH = getWorkspaceStoragePath();
console.log(`Workspace storage path: ${WORKSPACE_STORAGE_PATH}`);
// Validate the workspace path exists
const pathExists = await validateWorkspacePath(WORKSPACE_STORAGE_PATH);
if (!pathExists) {
console.warn(`Workspace storage directory not found: ${WORKSPACE_STORAGE_PATH}`);
console.warn('This is normal if VS Code has not been used yet or workspaces have not been created.');
}
// Initial scan
await refreshWorkspaces();
// Set up periodic refresh
setInterval(refreshWorkspaces, REFRESH_INTERVAL);
console.log(`Workspace scanner initialized. Refresh interval: ${REFRESH_INTERVAL}ms`);
}getWorkspaces function · javascript · L323-L325 (3 LOC)server/workspaceScanner.js
function getWorkspaces() {
return workspacesCache;
}removeWorkspacesFromPath function · javascript · L332-L404 (73 LOC)server/workspaceScanner.js
async function removeWorkspacesFromPath(workspaceIds) {
console.log('[WorkspaceScanner] removeWorkspacesFromPath called with IDs:', workspaceIds);
if (!Array.isArray(workspaceIds) || workspaceIds.length === 0) {
console.log('[WorkspaceScanner] No workspace IDs provided');
return { success: false, removed: 0, errors: ['No workspace IDs provided'] };
}
const errors = [];
let removed = 0;
// Get current workspaces
const currentWorkspaces = getWorkspaces();
console.log('[WorkspaceScanner] Current workspaces count:', currentWorkspaces.length);
console.log('[WorkspaceScanner] Current workspace IDs:', currentWorkspaces.map(ws => ws.id));
// Validate that all workspaces exist in the current list
const validIds = workspaceIds.filter(id => {
const exists = currentWorkspaces.some(ws => ws.id === id);
if (!exists) {
console.log(`[WorkspaceScanner] Workspace ${id} not found in current list`);
errors.push(`Workspace ${id} not found`);
}
apiRequest function · javascript · L33-L105 (73 LOC)src/api/client.js
export async function apiRequest(endpoint, options = {}) {
const url = `${API_BASE_URL}${endpoint}`;
const retries = options.retries || MAX_RETRIES;
let lastError;
for (let attempt = 0; attempt < retries; attempt++) {
try {
let response;
if (isTauri()) {
// Use Tauri HTTP plugin in desktop mode
// Note: The Tauri HTTP plugin is loaded via the plugin system
response = await fetch(url, {
method: options.method || 'GET',
headers: {
'Content-Type': 'application/json',
...options.headers
},
body: options.body ? JSON.stringify(options.body) : undefined
});
} else {
// Use native fetch in browser/development mode
response = await fetch(url, {
method: options.method || 'GET',
headers: {
'Content-Type': 'application/json',
...options.headers
},
body: options.body ? JSON.stringifygetWorkspaces function · javascript · L111-L113 (3 LOC)src/api/client.js
export async function getWorkspaces() {
return apiRequest('/api/workspaces');
}validatePath function · javascript · L120-L125 (6 LOC)src/api/client.js
export async function validatePath(path) {
return apiRequest('/api/validate-path', {
method: 'POST',
body: { path }
});
}validatePaths function · javascript · L132-L137 (6 LOC)src/api/client.js
export async function validatePaths(workspaces) {
return apiRequest('/api/validate-paths', {
method: 'POST',
body: { workspaces }
});
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
deleteWorkspaces function · javascript · L144-L157 (14 LOC)src/api/client.js
export async function deleteWorkspaces(ids) {
console.log('[API Client] deleteWorkspaces called with IDs:', ids);
try {
const result = await apiRequest('/api/workspaces/delete', {
method: 'POST',
body: { ids }
});
console.log('[API Client] deleteWorkspaces result:', result);
return result;
} catch (error) {
console.error('[API Client] deleteWorkspaces error:', error);
throw error;
}
}checkHealth function · javascript · L163-L174 (12 LOC)src/api/client.js
export async function checkHealth() {
try {
const response = await fetch(`${API_BASE_URL}/health`, {
method: 'GET',
// Short timeout for health check
signal: AbortSignal.timeout(5000)
});
return response.ok;
} catch {
return false;
}
}waitForApi function · javascript · L182-L193 (12 LOC)src/api/client.js
export async function waitForApi(timeout = 30000, interval = 1000) {
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
if (await checkHealth()) {
return true;
}
await new Promise(resolve => setTimeout(resolve, interval));
}
return false;
}getEnvironment function · javascript · L199-L201 (3 LOC)src/api/client.js
export function getEnvironment() {
return isTauri() ? 'tauri' : 'browser';
}getDiagnostics function · javascript · L209-L232 (24 LOC)src/api/client.js
export async function getDiagnostics() {
const diag = {
environment: getEnvironment(),
api_url: API_BASE_URL,
api_port: validatedPort || 3010,
timestamp: new Date().toISOString(),
};
// Check API health
diag.health_check = await checkHealth();
// In Tauri mode, call the Rust get_diagnostics command
if (isTauri()) {
try {
const { invoke } = await import('@tauri-apps/api/core');
const tauriDiag = await invoke('get_diagnostics');
return { ...diag, ...tauriDiag };
} catch (e) {
diag.tauri_error = e.toString();
}
}
return diag;
}DiagnosticsPanel function · javascript · L6-L63 (58 LOC)src/App.js
function DiagnosticsPanel() {
const [diagnostics, setDiagnostics] = useState(null);
const [expanded, setExpanded] = useState(false);
const [loading, setLoading] = useState(false);
const runDiagnostics = async () => {
setLoading(true);
try {
const data = await getDiagnostics();
setDiagnostics(data);
setExpanded(true);
} catch (e) {
setDiagnostics({ error: e.toString() });
setExpanded(true);
} finally {
setLoading(false);
}
};
if (!expanded) {
return (
<button
className="diagnostics-toggle"
onClick={runDiagnostics}
disabled={loading}
>
{loading ? 'Running diagnostics...' : 'Show Diagnostics'}
</button>
);
}
return (
<div className="diagnostics-panel">
<div className="diagnostics-header">
<span>Diagnostics</span>
<button className="diagnostics-close" onClick={() => setExpanded(false)}>
Hide
</button>
</div>
App function · javascript · L65-L157 (93 LOC)src/App.js
function App() {
const [workspaces, setWorkspaces] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [isFetching, setIsFetching] = useState(false);
const [retryCount, setRetryCount] = useState(0);
// Fetch workspaces from API
const fetchWorkspaces = async () => {
if (isFetching) {
console.log('Already fetching workspaces, skipping...');
return;
}
console.log('Starting fetchWorkspaces...');
try {
setIsFetching(true);
const data = await getWorkspaces();
console.log('Workspaces fetched:', data.length);
setWorkspaces(data);
setError(null);
} catch (err) {
console.error('Error fetching workspaces:', err);
setError(`Failed to load workspaces: ${err.message || 'Unknown error'}. Please try again.`);
} finally {
setLoading(false);
setIsFetching(false);
console.log('fetchWorkspaces complete');
}
};
// Memoize fetchWorDashboard function · javascript · L21-L308 (288 LOC)src/components/Dashboard.js
function Dashboard({ workspaces, onRefresh }) {
const [searchTerm, setSearchTerm] = useState('');
const [typeFilter, setTypeFilter] = useState('all');
const [sortConfig, setSortConfig] = useState({ key: 'lastAccessed', direction: 'desc' });
const [validationStatus, setValidationStatus] = useState({}); // Map of workspace id to isValid
const [selectedWorkspaces, setSelectedWorkspaces] = useState(new Set());
const [isDeleting, setIsDeleting] = useState(false);
const [notification, setNotification] = useState(null);
// Filter and sort workspaces
const filteredAndSortedWorkspaces = useMemo(() => {
let filtered = workspaces;
// Apply search filter
if (searchTerm) {
const lowerSearch = searchTerm.toLowerCase();
filtered = filtered.filter(ws =>
ws.name.toLowerCase().includes(lowerSearch) ||
ws.path.toLowerCase().includes(lowerSearch)
);
}
// Apply type filter
if (typeFilter !== 'all') {
filtered = filtered.fiMethodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
SearchFilter function · javascript · L4-L44 (41 LOC)src/components/SearchFilter.js
function SearchFilter({ searchTerm, onSearchChange, typeFilter, onTypeFilterChange, workspaceTypes, onClear }) {
const hasActiveFilters = searchTerm || typeFilter !== 'all';
return (
<div className="search-filter">
<div className="filter-group">
<label htmlFor="search">Search:</label>
<input
id="search"
type="text"
placeholder="Search by name or path..."
value={searchTerm}
onChange={(e) => onSearchChange(e.target.value)}
className="search-input"
/>
</div>
<div className="filter-group">
<label htmlFor="type-filter">Type:</label>
<select
id="type-filter"
value={typeFilter}
onChange={(e) => onTypeFilterChange(e.target.value)}
className="type-filter"
>
{workspaceTypes.map(type => (
<option key={type} value={type}>
{type === 'all' ? 'All Types' : type.replace('-', ' ').replace(/\b\wmain function · rust · L1-L3 (3 LOC)src-tauri/build.rs
fn main() {
tauri_build::build()
}open_vscode function · rust · L14-L19 (6 LOC)src-tauri/src/lib.rs
async fn open_vscode(app: AppHandle, uri: String) -> Result<(), String> {
app.opener()
.open_url(&uri, None::<&str>)
.map_err(|e| format!("Failed to open VS Code: {}", e))?;
Ok(())
}get_diagnostics function · rust · L23-L69 (47 LOC)src-tauri/src/lib.rs
async fn get_diagnostics(app: AppHandle) -> Result<serde_json::Value, String> {
let state: State<SidecarState> = app.state();
let port = state.sidecar_port;
let sidecar_path = resolve_sidecar_path(&app).unwrap_or_default();
let sidecar_exists = sidecar_path.exists();
let health_ok = check_sidecar_health(port).await;
Ok(serde_json::json!({
"sidecar_path": sidecar_path.to_string_lossy(),
"sidecar_exists": sidecar_exists,
"sidecar_port": port,
"health_check": health_ok,
"api_url": format!("http://127.0.0.1:{}", port),
"platform": std::env::consts::OS,
"arch": std::env::consts::ARCH,
"dev_mode": cfg!(dev),
})
)
}
// Sidecar state management
pub struct SidecarState {
pub sidecar_port: u16,
pub restart_attempts: Arc<Mutex<u32>>,
pub last_restart: Arc<Mutex<std::time::Instant>>,
}
impl SidecarState {
pub fn new() -> Self {
Self {
sidecar_port: std::env::var("Dnew function · rust · L51-L60 (10 LOC)src-tauri/src/lib.rs
pub fn new() -> Self {
Self {
sidecar_port: std::env::var("DASHBOARD_PORT")
.ok()
.and_then(|p| p.parse().ok())
.unwrap_or(3010),
restart_attempts: Arc::new(Mutex::new(0)),
last_restart: Arc::new(Mutex::new(std::time::Instant::now())),
}
}resolve_sidecar_path function · rust · L72-L102 (31 LOC)src-tauri/src/lib.rs
fn resolve_sidecar_path(_app: &AppHandle) -> Result<std::path::PathBuf, String> {
if cfg!(dev) {
// In dev mode, look for the binary relative to the project root
// current_dir() is the workspace root, binaries are in src-tauri/binaries/
std::env::current_dir()
.map_err(|e| format!("Failed to get current dir: {}", e))
.map(|dir| {
dir.join("binaries").join(if cfg!(target_os = "macos") {
if cfg!(target_arch = "aarch64") {
"sidecar-vscode-dashboard-aarch64-apple-darwin"
} else {
"sidecar-vscode-dashboard-macos-x64"
}
} else if cfg!(target_os = "windows") {
"sidecar-vscode-dashboard-win-x64.exe"
} else {
"sidecar-vscode-dashboard-linux-x64"
})
})
} else {
// In production, Tauri places externalBin sidecarsspawn_sidecar function · rust · L105-L125 (21 LOC)src-tauri/src/lib.rs
fn spawn_sidecar(app: &AppHandle, port: u16) -> Result<std::process::Child, String> {
let sidecar_path = resolve_sidecar_path(app)?;
log::info!("Attempting to spawn sidecar from: {:?}", sidecar_path);
let mut command = std::process::Command::new(&sidecar_path);
command.env("DASHBOARD_PORT", port.to_string());
command.env("PORT", port.to_string()); // Backward compatibility
command.env("HOST", "127.0.0.1");
#[cfg(target_os = "windows")]
{
use std::os::windows::process::CommandExt;
const CREATE_NO_WINDOW: u32 = 0x08000000;
command.creation_flags(CREATE_NO_WINDOW);
}
command
.spawn()
.map_err(|e| format!("Failed to spawn sidecar: {}", e))
}start_health_monitor function · rust · L128-L175 (48 LOC)src-tauri/src/lib.rs
async fn start_health_monitor(app: AppHandle, port: u16) {
let mut interval = interval(Duration::from_secs(5));
let state: State<SidecarState> = app.state();
loop {
interval.tick().await;
if !check_sidecar_health(port).await {
log::warn!("Sidecar health check failed, attempting restart...");
let mut attempts = state.restart_attempts.lock().await;
let mut last_restart = state.last_restart.lock().await;
// Reset attempts if more than 60 seconds have passed
if last_restart.elapsed().as_secs() > 60 {
*attempts = 0;
}
if *attempts >= 3 {
log::error!("Sidecar restart limit exceeded");
let _ = app.emit(
"sidecar-error",
serde_json::json!({
"message": "Failed to start backend service after multiple attempts"
}),
);
brWant this analysis on your repo? https://repobility.com/scan/
run function · rust · L178-L285 (108 LOC)src-tauri/src/lib.rs
pub fn run() {
tauri::Builder::default()
.manage(SidecarState::new())
.manage(tray::TrayState::new())
.plugin(tauri_plugin_log::Builder::default().build())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_process::init())
.setup(|app| {
// Get sidecar port from state
let state: State<SidecarState> = app.state();
let port = state.sidecar_port;
// Spawn sidecar on startup
match spawn_sidecar(app.app_handle(), port) {
Ok(child) => {
log::info!("Sidecar spawned successfully on port {}", port);
// Store child process for cleanup
app.manage(Arc::new(Mutex::new(child)));
// Start health monitoring
main function · rust · L3-L6 (4 LOC)src-tauri/src/main.rs
fn main() {
app_lib::run();
}create_menu function · rust · L4-L146 (143 LOC)src-tauri/src/menu.rs
pub fn create_menu(app: &tauri::AppHandle) -> Menu<tauri::Wry> {
let app_name = "VS Code Launchpad";
// macOS specific menu
#[cfg(target_os = "macos")]
{
let app_menu = Submenu::with_items(
app,
app_name,
true,
&[
&MenuItem::with_id(app, "app_about", "About", true, None::<&str>).unwrap(),
&PredefinedMenuItem::separator(app).unwrap(),
&MenuItem::with_id(app, "app_preferences", "Preferences...", true, Some("Cmd+,")).unwrap(),
&PredefinedMenuItem::separator(app).unwrap(),
&MenuItem::with_id(app, "app_hide", "Hide", true, Some("Cmd+H")).unwrap(),
&MenuItem::with_id(app, "app_hide_others", "Hide Others", true, Some("Cmd+Option+H")).unwrap(),
&MenuItem::with_id(app, "app_show_all", "Show All", true, None::<&str>).unwrap(),
&PredefinedMenuItem::separator(app).unwrap(),
&MenuItemhandle_menu_event function · rust · L147-L184 (38 LOC)src-tauri/src/menu.rs
pub fn handle_menu_event(app: &tauri::AppHandle, event: tauri::menu::MenuEvent) {
match event.id().as_ref() {
"app_quit" => {
app.exit(0);
}
"app_hide" => {
if let Some(window) = app.get_webview_window("main") {
let _: Result<(), _> = window.minimize();
}
}
"window_minimize" => {
if let Some(window) = app.get_webview_window("main") {
let _: Result<(), _> = window.minimize();
}
}
"window_close" => {
if let Some(window) = app.get_webview_window("main") {
let _: Result<(), _> = window.close();
}
}
"view_reload" => {
if let Some(window) = app.get_webview_window("main") {
let _: Result<(), _> = window.eval("window.location.reload()");
}
}
"view_toggle_devtools" => {
if let Some(window) = app.get_webview_window("main") convert_to_vscode_uri function · rust · L25-L35 (11 LOC)src-tauri/src/tray.rs
pub fn convert_to_vscode_uri(path: &str, workspace_type: &str) -> String {
// Remote workspaces: transform vscode-remote:// to vscode://vscode-remote/
match workspace_type {
"remote" | "dev-container" | "attached-container" | "ssh-remote" => {
if path.starts_with("vscode-remote://") {
return path.replacen("vscode-remote://", "vscode://vscode-remote/", 1);
}
return path.to_string();
}
_ => {}
}new function · rust · L64-L68 (5 LOC)src-tauri/src/tray.rs
pub fn new() -> Self {
Self {
tray_icon: Arc::new(Mutex::new(None)),
}
}resolve_icon_path function · rust · L72-L90 (19 LOC)src-tauri/src/tray.rs
fn resolve_icon_path(app: &tauri::AppHandle) -> Option<std::path::PathBuf> {
if cfg!(dev) {
// In dev mode, icons are in src-tauri/icons/ relative to the working dir
let path = std::env::current_dir().ok()?.join("icons").join("32x32.png");
if path.exists() { Some(path) } else { None }
} else {
// In production, use the resource directory
let resource_dir = app.path().resource_dir().ok()?;
let path = resource_dir.join("icons").join("32x32.png");
if path.exists() {
Some(path)
} else {
// Fallback: icon may be bundled alongside the executable
let exe_dir = std::env::current_exe().ok()?.parent()?.to_path_buf();
let path = exe_dir.join("icons").join("32x32.png");
if path.exists() { Some(path) } else { None }
}
}
}create_tray function · rust · L93-L138 (46 LOC)src-tauri/src/tray.rs
pub fn create_tray(app: &tauri::AppHandle) -> tauri::Result<TrayIcon> {
let tray_menu = build_menu(app, &[], false, &HashMap::new());
let mut builder = TrayIconBuilder::with_id("main-tray")
.menu(&tray_menu)
.show_menu_on_left_click(cfg!(target_os = "macos"))
.on_menu_event(handle_tray_menu_event)
.on_tray_icon_event(|tray, event| {
// On Windows/Linux, left-click shows the main window
#[cfg(not(target_os = "macos"))]
{
use tauri::tray::{TrayIconEvent, MouseButton};
if let TrayIconEvent::Click { button, .. } = event {
if button == MouseButton::Left {
let app = tray.app_handle();
if let Some(window) = app.get_webview_window("main") {
let _: Result<(), _> = window.show();
let _: Result<(), _> = window.set_focus();
}
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
handle_tray_menu_event function · rust · L141-L168 (28 LOC)src-tauri/src/tray.rs
fn handle_tray_menu_event(app: &tauri::AppHandle, event: tauri::menu::MenuEvent) {
let id = event.id();
let id_str = id.as_ref();
if id_str.starts_with("ws_open:") {
// Workspace quick-open: extract the URI after the prefix
let uri = &id_str["ws_open:".len()..];
if let Err(e) = app.opener().open_url(uri, None::<&str>) {
log::error!("Failed to open workspace from tray: {}", e);
}
} else {
match id_str {
"show_dashboard" => {
if let Some(window) = app.get_webview_window("main") {
let _: Result<(), _> = window.show();
let _: Result<(), _> = window.set_focus();
}
}
"check_updates" => {
let _ = app.emit("check-for-updates", ());
}
"quit" => {
app.exit(0);
}
_ => {}
}
}
}type_emoji function · rust · L171-L180 (10 LOC)src-tauri/src/tray.rs
fn type_emoji(workspace_type: &str) -> &'static str {
match workspace_type {
"local" => "🔵",
"ssh-remote" => "🟣",
"dev-container" => "🟢",
"attached-container" => "🟡",
"remote" => "🩷",
_ => "⚪",
}
}is_remote_type function · rust · L183-L185 (3 LOC)src-tauri/src/tray.rs
fn is_remote_type(workspace_type: &str) -> bool {
matches!(workspace_type, "remote" | "dev-container" | "attached-container" | "ssh-remote")
}build_menu function · rust · L188-L242 (55 LOC)src-tauri/src/tray.rs
fn build_menu(app: &tauri::AppHandle, workspaces: &[TrayWorkspace], backend_healthy: bool, validity: &HashMap<String, bool>) -> Menu<tauri::Wry> {
let status_label = if backend_healthy { "Backend: Running" } else { "Backend: Offline" };
if workspaces.is_empty() {
let no_ws = MenuItem::with_id(app, "no_workspaces", "No workspaces found", false, None::<&str>).unwrap();
let sep1 = PredefinedMenuItem::separator(app).unwrap();
let show = MenuItem::with_id(app, "show_dashboard", "Show Dashboard", true, None::<&str>).unwrap();
let updates = MenuItem::with_id(app, "check_updates", "Check for Updates", true, None::<&str>).unwrap();
let sep2 = PredefinedMenuItem::separator(app).unwrap();
let quit = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>).unwrap();
let sep3 = PredefinedMenuItem::separator(app).unwrap();
let status = MenuItem::with_id(app, "backend_status", status_label, false, None::<&str>).unwrap();
update_tray_menu function · rust · L245-L259 (15 LOC)src-tauri/src/tray.rs
pub async fn update_tray_menu(app: &tauri::AppHandle, workspaces: &[TrayWorkspace], backend_healthy: bool, validity: &HashMap<String, bool>) {
let tray_state: tauri::State<'_, TrayState> = app.state();
let tray_icon = tray_state.tray_icon.lock().await;
if let Some(tray) = tray_icon.as_ref() {
let new_menu = build_menu(app, workspaces, backend_healthy, validity);
if let Err(e) = tray.set_menu(Some(new_menu)) {
log::error!("Failed to update tray menu: {}", e);
} else {
log::info!("Tray menu updated: {} workspaces, backend {}", workspaces.len(), if backend_healthy { "online" } else { "offline" });
}
} else {
log::warn!("Tray icon not stored in state, cannot update menu");
}
}fetch_workspaces function · rust · L262-L336 (75 LOC)src-tauri/src/tray.rs
pub async fn fetch_workspaces(port: u16) -> Vec<TrayWorkspace> {
let url = format!("http://127.0.0.1:{}/api/workspaces", port);
match reqwest::get(&url).await {
Ok(response) => {
if response.status().is_success() {
match response.json::<Vec<TrayWorkspace>>().await {
Ok(mut workspaces) => {
// Sort by last_accessed descending
workspaces.sort_by(|a, b| b.last_accessed.cmp(&a.last_accessed));
workspaces
}
Err(e) => {
log::warn!("Failed to parse workspace response: {}", e);
Vec::new()
}
}
} else {
Vec::new()
}
}
Err(e) => {
log::warn!("Failed to fetch workspaces for tray: {}", e);
Vec::new()
}
}
}
/// Validate workspace paths via the sidecar Avalidate_workspace_paths function · rust · L292-L586 (295 LOC)src-tauri/src/tray.rs
pub async fn validate_workspace_paths(port: u16, workspaces: &[TrayWorkspace]) -> HashMap<String, bool> {
let url = format!("http://127.0.0.1:{}/api/validate-paths", port);
// Build the request body: { workspaces: [{id, path}, ...] }
let payload: Vec<serde_json::Value> = workspaces.iter().map(|ws| {
serde_json::json!({ "id": ws.id, "path": ws.path })
}).collect();
let body = serde_json::json!({ "workspaces": payload });
let client = reqwest::Client::new();
match client.post(&url).json(&body).send().await {
Ok(response) => {
if response.status().is_success() {
// Response: { results: { "ws-id": true/false, ... } }
#[derive(Deserialize)]
struct ValidateResponse {
results: HashMap<String, bool>,
}
match response.json::<ValidateResponse>().await {
Ok(parsed) => {
// Convert id-keyed results refresh_tray function · rust · L339-L346 (8 LOC)src-tauri/src/tray.rs
pub async fn refresh_tray(app: &tauri::AppHandle, port: u16) {
log::debug!("Tray refresh: fetching workspaces from port {}", port);
let workspaces = fetch_workspaces(port).await;
let healthy = super::check_sidecar_health(port).await;
let validity = validate_workspace_paths(port, &workspaces).await;
log::debug!("Tray refresh: got {} workspaces, healthy={}, validated {} paths", workspaces.len(), healthy, validity.len());
update_tray_menu(app, &workspaces, healthy, &validity).await;
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
tray_state_starts_empty function · rust · L353-L358 (6 LOC)src-tauri/src/tray.rs
fn tray_state_starts_empty() {
let state = TrayState::new();
// TrayIcon should be None initially
let guard = state.tray_icon.blocking_lock();
assert!(guard.is_none(), "TrayState should start with no icon");
}blocking_lock_provides_immediate_access function · rust · L361-L379 (19 LOC)src-tauri/src/tray.rs
fn blocking_lock_provides_immediate_access() {
// This test verifies the fix: blocking_lock() in synchronous context
// makes the value immediately available, unlike the old async spawn pattern
// which could leave the value as None when accessed shortly after.
let state = TrayState::new();
// Simulate synchronous storage (the fix)
{
let guard = state.tray_icon.blocking_lock();
// We can't create a real TrayIcon in tests, but we verify the lock works
assert!(guard.is_none());
// In production: *guard = Some(tray_icon);
}
// Immediately accessible after the lock is released
let guard = state.tray_icon.blocking_lock();
// Lock is acquired without blocking — no race condition
assert!(guard.is_none()); // Still None since we didn't set a real icon
}async_spawn_storage_can_race_with_reader function · rust · L382-L403 (22 LOC)src-tauri/src/tray.rs
async fn async_spawn_storage_can_race_with_reader() {
// This test demonstrates the BUG: storing a value via async spawn
// means the value may not be available when a reader checks immediately.
let shared = Arc::new(Mutex::new(false));
// Simulate the old pattern: store value via async spawn
let writer = shared.clone();
tokio::spawn(async move {
// This task is queued but may not run immediately
let mut guard = writer.lock().await;
*guard = true;
});
// Read immediately WITHOUT awaiting the spawn — simulates the refresh
// task reading TrayState before the icon storage spawn executes.
// NOTE: This succeeds on a multi-threaded runtime but demonstrates
// the pattern issue — the value might still be false (unset).
let guard = shared.lock().await;
// On a busy runtime, the spawn may not have executed yet.
// The fix avoids this race enpage 1 / 2next ›