mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-03 18:38:35 +02:00
fix: resolve macos bun interop
Use Bun-safe Electron and child_process import patterns for macOS GitHub Actions tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { EventEmitter } from 'node:events';
|
||||
import { rm } from 'node:fs/promises';
|
||||
import { basename, dirname } from 'node:path';
|
||||
|
||||
import { dialog, shell } from 'electron';
|
||||
import electron from 'electron';
|
||||
|
||||
import type {
|
||||
AgentActivityEvent,
|
||||
@@ -107,6 +107,8 @@ import {
|
||||
validateSessionToolingSelectionIds,
|
||||
} from '@main/sessionToolingConfig';
|
||||
|
||||
const { dialog, shell } = electron;
|
||||
|
||||
type AppServiceEvents = {
|
||||
'workspace-updated': [WorkspaceState];
|
||||
'session-event': [SessionEventRecord];
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import * as childProcess from 'node:child_process';
|
||||
import childProcess, { type ExecFileException } from 'node:child_process';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
import type { ProjectGitChangeSummary, ProjectGitCommitSummary, ProjectGitContext } from '@shared/domain/project';
|
||||
import { nowIso } from '@shared/utils/ids';
|
||||
|
||||
type ExecFileException = childProcess.ExecFileException;
|
||||
|
||||
const execFileAsync = promisify(childProcess.execFile);
|
||||
const GIT_TIMEOUT_MS = 5_000;
|
||||
|
||||
|
||||
+5
-2
@@ -1,11 +1,14 @@
|
||||
import { app, BrowserWindow } from 'electron';
|
||||
import electron from 'electron';
|
||||
import type { BrowserWindow as BrowserWindowType } from 'electron';
|
||||
|
||||
import { registerIpcHandlers } from '@main/ipc/registerIpcHandlers';
|
||||
import { AryxAppService } from '@main/AryxAppService';
|
||||
import { createMainWindow } from '@main/windows/createMainWindow';
|
||||
import { applyTitleBarTheme } from '@main/windows/titleBarTheme';
|
||||
|
||||
let mainWindow: BrowserWindow | undefined;
|
||||
const { app, BrowserWindow } = electron;
|
||||
|
||||
let mainWindow: BrowserWindowType | undefined;
|
||||
let appService: AryxAppService | undefined;
|
||||
|
||||
async function bootstrap(): Promise<void> {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BrowserWindow, ipcMain } from 'electron';
|
||||
import electron from 'electron';
|
||||
import type { BrowserWindow } from 'electron';
|
||||
|
||||
import { ipcChannels } from '@shared/contracts/channels';
|
||||
import type {
|
||||
@@ -27,6 +28,8 @@ import type { AppearanceTheme } from '@shared/domain/tooling';
|
||||
import { AryxAppService } from '@main/AryxAppService';
|
||||
import { applyTitleBarTheme } from '@main/windows/titleBarTheme';
|
||||
|
||||
const { ipcMain } = electron;
|
||||
|
||||
export function registerIpcHandlers(window: BrowserWindow, service: AryxAppService): void {
|
||||
ipcMain.handle(ipcChannels.describeSidecarCapabilities, () => service.describeSidecarCapabilities());
|
||||
ipcMain.handle(ipcChannels.refreshSidecarCapabilities, () => service.refreshSidecarCapabilities());
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { app } from 'electron';
|
||||
import electron from 'electron';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const { app } = electron;
|
||||
|
||||
export function getWorkspaceFilePath(): string {
|
||||
return join(app.getPath('userData'), 'workspace.json');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app } from 'electron';
|
||||
import electron from 'electron';
|
||||
import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';
|
||||
|
||||
import type {
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
import { TurnCancelledError } from '@main/sidecar/turnCancelledError';
|
||||
import { resolveSidecarProcess } from '@main/sidecar/sidecarRuntime';
|
||||
|
||||
const { app } = electron;
|
||||
|
||||
type PendingCommand =
|
||||
| ({
|
||||
processId: number;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { app, BrowserWindow, Menu, shell } from 'electron';
|
||||
import electron from 'electron';
|
||||
import type { BrowserWindow as BrowserWindowType } from 'electron';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { resolveWindowIconPath } from '@main/windows/appIcon';
|
||||
|
||||
export function createMainWindow(): BrowserWindow {
|
||||
const { app, BrowserWindow, Menu, shell } = electron;
|
||||
|
||||
export function createMainWindow(): BrowserWindowType {
|
||||
Menu.setApplicationMenu(null);
|
||||
|
||||
const window = new BrowserWindow({
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { nativeTheme, type BrowserWindow } from 'electron';
|
||||
import electron from 'electron';
|
||||
import type { BrowserWindow } from 'electron';
|
||||
|
||||
import type { AppearanceTheme } from '@shared/domain/tooling';
|
||||
|
||||
const { nativeTheme } = electron;
|
||||
|
||||
interface TitleBarColors {
|
||||
backgroundColor: string;
|
||||
overlay: { color: string; symbolColor: string };
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
import electron from 'electron';
|
||||
|
||||
import { ipcChannels } from '@shared/contracts/channels';
|
||||
import type { ElectronApi } from '@shared/contracts/ipc';
|
||||
|
||||
const { contextBridge, ipcRenderer } = electron;
|
||||
|
||||
const api: ElectronApi = {
|
||||
describeSidecarCapabilities: () => ipcRenderer.invoke(ipcChannels.describeSidecarCapabilities),
|
||||
refreshSidecarCapabilities: () => ipcRenderer.invoke(ipcChannels.refreshSidecarCapabilities),
|
||||
|
||||
@@ -8,19 +8,26 @@ import { createWorkspaceSeed, type WorkspaceState } from '@shared/domain/workspa
|
||||
|
||||
const TIMESTAMP = '2026-03-25T00:00:00.000Z';
|
||||
|
||||
mock.module('electron', () => ({
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
}));
|
||||
mock.module('electron', () => {
|
||||
const electronMock = {
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...electronMock,
|
||||
default: electronMock,
|
||||
};
|
||||
});
|
||||
|
||||
mock.module('keytar', () => ({
|
||||
default: {
|
||||
|
||||
@@ -2,19 +2,26 @@ import { describe, expect, mock, test } from 'bun:test';
|
||||
|
||||
import type { SidecarCapabilities } from '@shared/contracts/sidecar';
|
||||
|
||||
mock.module('electron', () => ({
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
}));
|
||||
mock.module('electron', () => {
|
||||
const electronMock = {
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...electronMock,
|
||||
default: electronMock,
|
||||
};
|
||||
});
|
||||
|
||||
mock.module('keytar', () => ({
|
||||
default: {
|
||||
|
||||
@@ -9,19 +9,26 @@ import { createWorkspaceSeed, type WorkspaceState } from '@shared/domain/workspa
|
||||
const TIMESTAMP = '2026-03-25T00:00:00.000Z';
|
||||
const SCRATCHPAD_PATH = 'C:\\workspace\\personal\\repositories\\aryx\\scratchpad';
|
||||
|
||||
mock.module('electron', () => ({
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
}));
|
||||
mock.module('electron', () => {
|
||||
const electronMock = {
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...electronMock,
|
||||
default: electronMock,
|
||||
};
|
||||
});
|
||||
|
||||
mock.module('keytar', () => ({
|
||||
default: {
|
||||
|
||||
@@ -42,12 +42,19 @@ class FakeChildProcess extends EventEmitter {
|
||||
|
||||
const spawnedProcesses: FakeChildProcess[] = [];
|
||||
|
||||
mock.module('electron', () => ({
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
},
|
||||
}));
|
||||
mock.module('electron', () => {
|
||||
const electronMock = {
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\aryx',
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...electronMock,
|
||||
default: electronMock,
|
||||
};
|
||||
});
|
||||
|
||||
mock.module('node:child_process', () => ({
|
||||
spawn: () => {
|
||||
|
||||
Reference in New Issue
Block a user