Merge branch 'agents/vital-hyena'

# Conflicts:
#	src/renderer/App.tsx
This commit is contained in:
David Kaya
2026-04-13 08:57:29 +02:00
6 changed files with 246 additions and 176 deletions
+25 -9
View File
@@ -473,27 +473,43 @@ export class AryxAppService extends EventEmitter<AppServiceEvents> {
const selectedProject = selectedProjectId
? this.workspace.projects.find((project) => project.id === selectedProjectId)
: undefined;
const didSyncUserTooling = await this.syncUserDiscoveredTooling(this.workspace);
const didSyncProjectTooling = selectedProject
? await this.syncProjectDiscoveredTooling(this.workspace, selectedProject)
: false;
const didSyncProjectCustomization = selectedProject
? await this.syncProjectCustomization(selectedProject)
: false;
// Run independent sync operations in parallel
const [didSyncUserTooling, didSyncProjectTooling, didSyncProjectCustomization] = await Promise.all([
this.syncUserDiscoveredTooling(this.workspace),
selectedProject
? this.syncProjectDiscoveredTooling(this.workspace, selectedProject)
: false,
selectedProject
? this.syncProjectCustomization(selectedProject)
: false,
]);
const didPruneSelections = this.pruneUnavailableSessionToolingSelections(this.workspace);
const didPruneApprovalTools = await this.pruneUnavailableApprovalTools(this.workspace);
if (
didSyncUserTooling
|| didSyncProjectTooling
|| didSyncProjectCustomization
|| didPruneSelections
|| didPruneApprovalTools
|| this.cleanupInterruptedSessions(this.workspace)
) {
await this.workspaceRepository.save(this.workspace);
}
await this.syncProjectCustomizationWatchers(this.workspace);
// Defer sidecar-dependent approval pruning so it doesn't block startup.
// This runs in the background and emits workspace-updated when done.
void this.pruneUnavailableApprovalTools(this.workspace)
.then(async (didPrune) => {
if (didPrune && this.workspace) {
await this.workspaceRepository.save(this.workspace);
this.emit('workspace-updated', this.workspace);
}
})
.catch((error) => {
console.error('[aryx startup] deferred approval tool pruning failed', error);
});
}
if (!this.didScheduleInitialProjectGitRefresh) {
+27 -19
View File
@@ -23,21 +23,34 @@ async function bootstrap(): Promise<void> {
mainWindow = createMainWindow();
registerIpcHandlers(mainWindow, appService, autoUpdateService);
// Apply persisted theme to the title bar overlay
const workspace = await appService.loadWorkspace();
applyTitleBarTheme(mainWindow, workspace.settings.theme);
// Start workspace loading in parallel — don't block window from showing.
// The renderer fetches the workspace via its own IPC call after mount.
const workspaceReady = appService.loadWorkspace();
// Set up system tray
systemTray = new SystemTray({
onShowWindow: showAndFocusWindow,
onCreateScratchpad: () => {
showAndFocusWindow();
mainWindow?.webContents.send('tray:create-scratchpad');
},
onQuit: () => app.quit(),
});
systemTray.create();
systemTray.updateRunningCount(workspace);
// Apply theme and set up tray once workspace is available
workspaceReady
.then((workspace) => {
if (!mainWindow) return;
applyTitleBarTheme(mainWindow, workspace.settings.theme);
systemTray = new SystemTray({
onShowWindow: showAndFocusWindow,
onCreateScratchpad: () => {
showAndFocusWindow();
mainWindow?.webContents.send('tray:create-scratchpad');
},
onQuit: () => app.quit(),
});
systemTray.create();
systemTray.updateRunningCount(workspace);
appService!.on('workspace-updated', (updatedWorkspace) => {
systemTray?.updateRunningCount(updatedWorkspace);
});
})
.catch((error) => {
console.error('[aryx bootstrap] workspace load failed', error);
});
// Intercept close to hide to tray when the setting is enabled
setupCloseToTray(mainWindow, () => {
@@ -45,11 +58,6 @@ async function bootstrap(): Promise<void> {
return currentWorkspace?.settings.minimizeToTray === true;
});
// Keep tray status in sync when workspace changes
appService.on('workspace-updated', (updatedWorkspace) => {
systemTray?.updateRunningCount(updatedWorkspace);
});
if (!app.isPackaged) {
mainWindow.webContents.openDevTools({ mode: 'detach' });
}
+5
View File
@@ -14,6 +14,7 @@ export function createMainWindow(): BrowserWindowType {
height: 960,
minWidth: 1120,
minHeight: 720,
show: false,
title: 'aryx',
icon: resolveWindowIconPath({
appPath: app.getAppPath(),
@@ -36,6 +37,10 @@ export function createMainWindow(): BrowserWindowType {
},
});
window.once('ready-to-show', () => {
window.show();
});
const rendererUrl = process.env.ELECTRON_RENDERER_URL;
if (rendererUrl) {