fix(coding): resolve packaged Pi Agent Server dependencies

This commit is contained in:
2026-09-01 11:11:00 +08:00
parent 7f0e9310a7
commit 7df245af5a
3 changed files with 123 additions and 2 deletions

View File

@@ -1,7 +1,8 @@
// @vitest-environment node
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
import { copyFile, mkdtemp, mkdir, realpath, rm, symlink, writeFile } from 'node:fs/promises';
import { createServer, type ServerResponse } from 'node:http';
import { createRequire } from 'node:module';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { afterEach, describe, expect, it } from 'vitest';
@@ -11,6 +12,36 @@ import { MAKELORE_DEFAULT_LANGUAGE_PROMPT } from '../../electron/coding-runtime/
import type { PiWorkerProcessOptions } from '../../electron/coding-runtime/pi/worker-process';
const roots: string[] = [];
const electronExecutable = createRequire(path.resolve('package.json'))('electron') as string;
async function materializePackagedAgentServerLayout(root: string): Promise<{
configDir: string;
runtimeRoot: string;
serverPath: string;
}> {
const resourcesPath = path.join(root, 'artifact', 'resources');
const serverPath = path.join(resourcesPath, 'resources', 'pi-agent-server.mjs');
const runtimeRoot = path.join(resourcesPath, 'pi-runtime');
const configDir = path.join(root, 'config');
const piAiRoot = path.join(runtimeRoot, 'node_modules', '@earendil-works', 'pi-ai');
const [sourceRuntimeRoot, sourcePiAiRoot] = await Promise.all([
realpath(path.resolve('node_modules/@earendil-works/pi-coding-agent')),
realpath(path.resolve('node_modules/@earendil-works/pi-ai')),
]);
await Promise.all([
mkdir(path.dirname(serverPath), { recursive: true }),
mkdir(path.dirname(piAiRoot), { recursive: true }),
mkdir(configDir, { recursive: true }),
]);
const directoryLinkType = process.platform === 'win32' ? 'junction' : 'dir';
await Promise.all([
copyFile(path.resolve('resources/pi-agent-server.mjs'), serverPath),
copyFile(path.join(sourceRuntimeRoot, 'package.json'), path.join(runtimeRoot, 'package.json')),
symlink(path.join(sourceRuntimeRoot, 'dist'), path.join(runtimeRoot, 'dist'), directoryLinkType),
symlink(sourcePiAiRoot, piAiRoot, directoryLinkType),
]);
return { configDir, runtimeRoot, serverPath };
}
async function startHeldProvider(): Promise<{
baseUrl: string;
@@ -85,6 +116,23 @@ afterEach(async () => {
});
describe('Pi Agent Server real process', () => {
it('boots from the packaged sibling resource layout', async () => {
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-agent-server-layout-'));
roots.push(root);
const layout = await materializePackagedAgentServerLayout(root);
const server = new PiAgentServerProcess({
executablePath: electronExecutable,
...layout,
});
try {
await expect(server.start()).resolves.toBeUndefined();
expect(server.processId).toBeTypeOf('number');
} finally {
await server.stop();
}
}, 10_000);
it('hosts isolated Conversation threads in one long-lived process', async () => {
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-agent-server-'));
roots.push(root);