feat: add packaging and validation coverage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot CLI
2026-03-21 09:30:37 +01:00
co-authored by Copilot
parent 9e509593d6
commit c8d23f91d1
11 changed files with 556 additions and 76 deletions
+8 -27
View File
@@ -1,6 +1,5 @@
import { app } from 'electron';
import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';
import { join } from 'node:path';
import type {
SidecarCapabilities,
@@ -11,6 +10,7 @@ import type {
RunTurnCommand,
} from '@shared/contracts/sidecar';
import type { ChatMessageRecord } from '@shared/domain/session';
import { resolveSidecarProcess } from '@main/sidecar/sidecarRuntime';
type PendingCommand =
| {
@@ -30,30 +30,6 @@ type PendingCommand =
onDelta: (event: TurnDeltaEvent) => void;
};
function getProjectRoot(): string {
return app.getAppPath();
}
function resolveSidecarProcess(): { command: string; args: string[] } {
if (app.isPackaged) {
return {
command: join(process.resourcesPath, 'sidecar', 'Kopaya.AgentHost.exe'),
args: ['--stdio'],
};
}
return {
command: 'dotnet',
args: [
'run',
'--project',
join(getProjectRoot(), 'sidecar', 'src', 'Kopaya.AgentHost', 'Kopaya.AgentHost.csproj'),
'--',
'--stdio',
],
};
}
export class SidecarClient {
private process?: ChildProcessWithoutNullStreams;
private stdoutBuffer = '';
@@ -94,9 +70,14 @@ export class SidecarClient {
return this.process;
}
const sidecar = resolveSidecarProcess();
const sidecar = resolveSidecarProcess({
isPackaged: app.isPackaged,
appPath: app.getAppPath(),
resourcesPath: process.resourcesPath,
platform: process.platform,
});
this.process = spawn(sidecar.command, sidecar.args, {
cwd: getProjectRoot(),
cwd: sidecar.cwd,
stdio: 'pipe',
windowsHide: true,
});
+48
View File
@@ -0,0 +1,48 @@
import { posix, win32 } from 'node:path';
export interface SidecarRuntimeContext {
readonly isPackaged: boolean;
readonly appPath: string;
readonly resourcesPath: string;
readonly platform: NodeJS.Platform;
}
export interface ResolvedSidecarProcess {
readonly command: string;
readonly args: string[];
readonly cwd: string;
}
function getPathModule(platform: NodeJS.Platform) {
return platform === 'win32' ? win32 : posix;
}
function getBundledSidecarExecutableName(platform: NodeJS.Platform): string {
return platform === 'win32' ? 'Kopaya.AgentHost.exe' : 'Kopaya.AgentHost';
}
export function resolveSidecarProcess(context: SidecarRuntimeContext): ResolvedSidecarProcess {
const pathModule = getPathModule(context.platform);
if (context.isPackaged) {
const sidecarDirectory = pathModule.join(context.resourcesPath, 'sidecar');
return {
command: pathModule.join(sidecarDirectory, getBundledSidecarExecutableName(context.platform)),
args: ['--stdio'],
cwd: sidecarDirectory,
};
}
return {
command: 'dotnet',
args: [
'run',
'--project',
pathModule.join(context.appPath, 'sidecar', 'src', 'Kopaya.AgentHost', 'Kopaya.AgentHost.csproj'),
'--',
'--stdio',
],
cwd: context.appPath,
};
}