merge: integrate remote and local main histories
# Conflicts: # .project-docs/20-architecture/module-map.md # .project-docs/30-worklog/current-state.md # .project-docs/50-evidence/evidence-index.md # src/pages/MyPlugins/index.tsx # tests/unit/pi-agent-server-process-real.test.ts # tests/unit/pi-managed-worker-opener.test.ts # tests/unit/plugin-marketplace-pages.test.tsx
This commit is contained in:
@@ -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';
|
||||
@@ -13,6 +14,36 @@ import type { PiRpcEvent } from '../../electron/coding-runtime/pi/rpc-client';
|
||||
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;
|
||||
@@ -283,6 +314,47 @@ describe('Pi Agent Server real process', () => {
|
||||
}
|
||||
}, 10_000);
|
||||
|
||||
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('restarts when start races with a graceful background stop', async () => {
|
||||
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-agent-server-restart-'));
|
||||
roots.push(root);
|
||||
const layout = await materializePackagedAgentServerLayout(root);
|
||||
const server = new PiAgentServerProcess({
|
||||
executablePath: electronExecutable,
|
||||
...layout,
|
||||
});
|
||||
|
||||
try {
|
||||
await server.start();
|
||||
const firstProcessId = server.processId;
|
||||
expect(firstProcessId).toBeTypeOf('number');
|
||||
|
||||
const stopping = server.stop();
|
||||
const restarting = server.start();
|
||||
await Promise.all([stopping, restarting]);
|
||||
expect(server.processId).toBeTypeOf('number');
|
||||
expect(server.processId).not.toBe(firstProcessId);
|
||||
} finally {
|
||||
await server.stop();
|
||||
}
|
||||
}, 20_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);
|
||||
|
||||
Reference in New Issue
Block a user