fix(packages): load bundled Pi runtime for local installs
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { execFile } from 'node:child_process';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { cp, mkdir, readFile, rename, rm, stat } from 'node:fs/promises';
|
||||
import { createRequire } from 'node:module';
|
||||
import path from 'node:path';
|
||||
import { atomicWriteJson } from '../coding-projects/atomic-json';
|
||||
import {
|
||||
@@ -53,6 +54,17 @@ export interface DevicePackageInstallInput {
|
||||
|
||||
export type DevicePackageInstallRunner = (input: DevicePackageInstallInput) => Promise<void>;
|
||||
|
||||
interface PiPackageManagerModule {
|
||||
DefaultPackageManager: new (input: {
|
||||
cwd: string;
|
||||
agentDir: string;
|
||||
settingsManager: unknown;
|
||||
}) => { getInstalledPath(source: string, scope: 'user'): string | undefined };
|
||||
SettingsManager: {
|
||||
inMemory(user: Record<string, unknown>, project: { projectTrusted: boolean }): unknown;
|
||||
};
|
||||
}
|
||||
|
||||
export interface DevicePackageManagerOptions {
|
||||
rootDir: string;
|
||||
executablePath?: string;
|
||||
@@ -208,6 +220,23 @@ async function gitHead(directory: string): Promise<string> {
|
||||
});
|
||||
}
|
||||
|
||||
async function loadBundledPiPackageManager(cliPath: string): Promise<PiPackageManagerModule> {
|
||||
const entryPath = path.join(path.dirname(path.resolve(cliPath)), 'index.js');
|
||||
try {
|
||||
const loaded = createRequire(entryPath)(entryPath) as Partial<PiPackageManagerModule>;
|
||||
if (typeof loaded.DefaultPackageManager !== 'function'
|
||||
|| typeof loaded.SettingsManager?.inMemory !== 'function') {
|
||||
throw new Error('Pi package manager exports are unavailable');
|
||||
}
|
||||
return loaded as PiPackageManagerModule;
|
||||
} catch {
|
||||
throw new DevicePackageError(
|
||||
'local_package_dependency_failed',
|
||||
'Bundled Pi package manager is unavailable',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class DevicePackageManager {
|
||||
private readonly rootDir: string;
|
||||
private readonly packagesDir: string;
|
||||
@@ -270,18 +299,23 @@ export class DevicePackageManager {
|
||||
}
|
||||
const agentDir = path.join(planRoot, 'pi-agent');
|
||||
const cwd = path.join(planRoot, 'project');
|
||||
await this.runInstall({
|
||||
source: source.spec,
|
||||
executablePath,
|
||||
cliPath,
|
||||
...(this.options.npmCliPath ? { npmCliPath: this.options.npmCliPath } : {}),
|
||||
agentDir,
|
||||
cwd,
|
||||
env: installEnvironment(agentDir),
|
||||
});
|
||||
const { DefaultPackageManager, SettingsManager } = await import(
|
||||
'@earendil-works/pi-coding-agent'
|
||||
);
|
||||
try {
|
||||
await this.runInstall({
|
||||
source: source.spec,
|
||||
executablePath,
|
||||
cliPath,
|
||||
...(this.options.npmCliPath ? { npmCliPath: this.options.npmCliPath } : {}),
|
||||
agentDir,
|
||||
cwd,
|
||||
env: installEnvironment(agentDir),
|
||||
});
|
||||
} catch {
|
||||
throw new DevicePackageError(
|
||||
'local_package_dependency_failed',
|
||||
'Pi could not install this package source',
|
||||
);
|
||||
}
|
||||
const { DefaultPackageManager, SettingsManager } = await loadBundledPiPackageManager(cliPath);
|
||||
const manager = new DefaultPackageManager({
|
||||
cwd,
|
||||
agentDir,
|
||||
|
||||
Reference in New Issue
Block a user