mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
feat(coding-agent): add local list and attach demo
This commit is contained in:
parent
7479148479
commit
e2888c4a93
12 changed files with 399 additions and 1 deletions
3
package-lock.json
generated
3
package-lock.json
generated
|
|
@ -5500,6 +5500,9 @@
|
|||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"@earendil-works/pi-ai": "^0.84.1",
|
||||
"@earendil-works/pi-client": "^0.84.1",
|
||||
"@earendil-works/pi-protocol": "^0.84.1",
|
||||
"@earendil-works/pi-server": "^0.84.1",
|
||||
"@earendil-works/pi-tui": "^0.84.1",
|
||||
"@silvia-odwyer/photon-node": "0.3.4",
|
||||
"chalk": "5.6.2",
|
||||
|
|
|
|||
38
packages/coding-agent/install-lock/package-lock.json
generated
38
packages/coding-agent/install-lock/package-lock.json
generated
|
|
@ -489,6 +489,17 @@
|
|||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-client": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-client/-/pi-client-0.84.1.tgz",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@earendil-works/pi-protocol": "^0.84.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-coding-agent": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.84.1.tgz",
|
||||
|
|
@ -496,6 +507,9 @@
|
|||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"@earendil-works/pi-ai": "^0.84.1",
|
||||
"@earendil-works/pi-client": "^0.84.1",
|
||||
"@earendil-works/pi-protocol": "^0.84.1",
|
||||
"@earendil-works/pi-server": "^0.84.1",
|
||||
"@earendil-works/pi-tui": "^0.84.1",
|
||||
"@silvia-odwyer/photon-node": "0.3.4",
|
||||
"chalk": "5.6.2",
|
||||
|
|
@ -524,6 +538,30 @@
|
|||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-protocol": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-protocol/-/pi-protocol-0.84.1.tgz",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"typebox": "1.3.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-server": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-server/-/pi-server-0.84.1.tgz",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"@earendil-works/pi-protocol": "^0.84.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-telemetry": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-telemetry/-/pi-telemetry-0.84.1.tgz",
|
||||
|
|
|
|||
38
packages/coding-agent/npm-shrinkwrap.json
generated
38
packages/coding-agent/npm-shrinkwrap.json
generated
|
|
@ -11,6 +11,9 @@
|
|||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"@earendil-works/pi-ai": "^0.84.1",
|
||||
"@earendil-works/pi-client": "^0.84.1",
|
||||
"@earendil-works/pi-protocol": "^0.84.1",
|
||||
"@earendil-works/pi-server": "^0.84.1",
|
||||
"@earendil-works/pi-tui": "^0.84.1",
|
||||
"@silvia-odwyer/photon-node": "0.3.4",
|
||||
"chalk": "5.6.2",
|
||||
|
|
@ -514,6 +517,41 @@
|
|||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-client": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-client/-/pi-client-0.84.1.tgz",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@earendil-works/pi-protocol": "^0.84.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-protocol": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-protocol/-/pi-protocol-0.84.1.tgz",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"typebox": "1.3.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-server": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-server/-/pi-server-0.84.1.tgz",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"@earendil-works/pi-protocol": "^0.84.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@earendil-works/pi-telemetry": {
|
||||
"version": "0.84.1",
|
||||
"resolved": "https://registry.npmjs.org/@earendil-works/pi-telemetry/-/pi-telemetry-0.84.1.tgz",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@
|
|||
"dependencies": {
|
||||
"@earendil-works/pi-agent-core": "^0.84.1",
|
||||
"@earendil-works/pi-ai": "^0.84.1",
|
||||
"@earendil-works/pi-client": "^0.84.1",
|
||||
"@earendil-works/pi-protocol": "^0.84.1",
|
||||
"@earendil-works/pi-server": "^0.84.1",
|
||||
"@earendil-works/pi-tui": "^0.84.1",
|
||||
"@silvia-odwyer/photon-node": "0.3.4",
|
||||
"chalk": "5.6.2",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { AuthInput } from "../auth.ts";
|
||||
import { Command } from "../command.ts";
|
||||
import { Command, stringOption } from "../command.ts";
|
||||
import {
|
||||
authTokenFileOption,
|
||||
authTokenOption,
|
||||
|
|
@ -14,6 +14,7 @@ export interface ClientCommand {
|
|||
readonly command: "client";
|
||||
readonly auth?: AuthInput;
|
||||
readonly connect?: TransportAddress;
|
||||
readonly sessionId?: string;
|
||||
}
|
||||
|
||||
export interface ClientCommandContext {
|
||||
|
|
@ -21,14 +22,17 @@ export interface ClientCommandContext {
|
|||
}
|
||||
|
||||
const connectOption = transportOption("--connect");
|
||||
const sessionIdOption = stringOption("--session-id");
|
||||
|
||||
export const clientCommand = new Command<ClientCommand, ClientCommandContext>("client")
|
||||
.option(connectOption)
|
||||
.option(sessionIdOption)
|
||||
.option(authTokenOption)
|
||||
.option(authTokenFileOption)
|
||||
.build((input) => {
|
||||
const { auth, errors: authErrors } = parseAuth(input);
|
||||
const connect = input.value(connectOption);
|
||||
const sessionId = input.value(sessionIdOption);
|
||||
const { errors: optionErrors } = parseLegacyOptions(input);
|
||||
const errors = [...authErrors, ...optionErrors, ...unsupportedLegacyOptions("client", input)];
|
||||
if (errors.length > 0) return { ok: false, errors };
|
||||
|
|
@ -38,6 +42,7 @@ export const clientCommand = new Command<ClientCommand, ClientCommandContext>("c
|
|||
command: "client",
|
||||
...(auth === undefined ? {} : { auth }),
|
||||
...(connect === undefined ? {} : { connect }),
|
||||
...(sessionId === undefined ? {} : { sessionId }),
|
||||
},
|
||||
};
|
||||
})
|
||||
|
|
|
|||
140
packages/coding-agent/src/cli/experimental/runtime.ts
Normal file
140
packages/coding-agent/src/cli/experimental/runtime.ts
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
import { basename } from "node:path";
|
||||
import { MemorySessionRepo, type Session } from "@earendil-works/pi-agent-core";
|
||||
import { PiClient } from "@earendil-works/pi-client";
|
||||
import {
|
||||
createUnixTransportFactory,
|
||||
discoverUnixServices,
|
||||
type UnixServiceRoute,
|
||||
} from "@earendil-works/pi-client/unix";
|
||||
import { isServiceId } from "@earendil-works/pi-protocol";
|
||||
import { generateServiceId, type PiServer, type PiServerService } from "@earendil-works/pi-server";
|
||||
import { createUnixServer, getUnixSocketPath } from "@earendil-works/pi-server/unix";
|
||||
import type { ClientCommand } from "./commands/client.ts";
|
||||
|
||||
const DEMO_SESSION_IDS = ["demo-1", "demo-2"] as const;
|
||||
|
||||
export interface ExperimentalMemoryServer {
|
||||
readonly serviceId: string;
|
||||
readonly socketPath: string;
|
||||
readonly server: PiServer;
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
export type ExperimentalClientResult =
|
||||
| {
|
||||
readonly kind: "list";
|
||||
readonly sessions: readonly { serviceId: string; sessionId: string }[];
|
||||
}
|
||||
| { readonly kind: "attached"; readonly serviceId: string; readonly sessionId: string };
|
||||
|
||||
export interface StartExperimentalMemoryServerOptions {
|
||||
/** Directory for service-addressed Unix sockets. Defaults to ~/.pi/server. */
|
||||
readonly directory?: string;
|
||||
readonly path?: string;
|
||||
}
|
||||
|
||||
export interface RunExperimentalClientOptions {
|
||||
/** Directory searched when --connect is omitted. Defaults to ~/.pi/server. */
|
||||
readonly directory?: string;
|
||||
}
|
||||
|
||||
/** Start the temporary in-memory list-and-attach server composition. */
|
||||
export async function startExperimentalMemoryServer(
|
||||
options: StartExperimentalMemoryServerOptions = {},
|
||||
): Promise<ExperimentalMemoryServer> {
|
||||
const serviceId = generateServiceId();
|
||||
const repo = new MemorySessionRepo();
|
||||
for (const id of DEMO_SESSION_IDS) {
|
||||
const session = await repo.create({ id });
|
||||
await session.close();
|
||||
}
|
||||
|
||||
// The list-and-attach protocol only needs ownership and close semantics. The
|
||||
// complete AgentHarness implementation will replace this session owner when
|
||||
// remote Harness methods are added.
|
||||
const service: PiServerService = {
|
||||
sessions: repo,
|
||||
createHarness: (session: Session) => Promise.resolve({ close: () => session.close() }),
|
||||
};
|
||||
const socketPath = options.path ?? getUnixSocketPath(serviceId, options.directory);
|
||||
const server = createUnixServer(service, { serviceId, path: socketPath });
|
||||
try {
|
||||
await server.start();
|
||||
} catch (error) {
|
||||
await repo.close();
|
||||
throw error;
|
||||
}
|
||||
|
||||
let closePromise: Promise<void> | undefined;
|
||||
return {
|
||||
serviceId,
|
||||
socketPath,
|
||||
server,
|
||||
close() {
|
||||
if (closePromise === undefined) closePromise = server.close().finally(() => repo.close());
|
||||
return closePromise;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** Discover local services, then list sessions or attach to one selected session. */
|
||||
export async function runExperimentalClient(
|
||||
command: ClientCommand,
|
||||
options: RunExperimentalClientOptions = {},
|
||||
): Promise<ExperimentalClientResult> {
|
||||
if (command.auth !== undefined) throw new Error("Authentication is not supported by the local demo server");
|
||||
const routes = command.connect ? [routeFromExplicitPath(command.connect.path)] : await discoverUnixServices(options);
|
||||
const discovered: { route: UnixServiceRoute; sessionIds: string[] }[] = [];
|
||||
|
||||
for (const route of routes) {
|
||||
const client = await PiClient.connect({
|
||||
serviceId: route.serviceId,
|
||||
transportFactory: createUnixTransportFactory({ path: route.path }),
|
||||
});
|
||||
try {
|
||||
const sessions = await client.listSessions();
|
||||
discovered.push({ route, sessionIds: sessions.map(({ id }) => id) });
|
||||
} finally {
|
||||
await client.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
const sessionId = command.sessionId;
|
||||
if (sessionId === undefined) {
|
||||
return {
|
||||
kind: "list",
|
||||
sessions: discovered
|
||||
.flatMap(({ route, sessionIds }) =>
|
||||
sessionIds.map((sessionId) => ({ serviceId: route.serviceId, sessionId })),
|
||||
)
|
||||
.sort(
|
||||
(left, right) =>
|
||||
left.serviceId.localeCompare(right.serviceId) || left.sessionId.localeCompare(right.sessionId),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const matches = discovered.filter((candidate) => candidate.sessionIds.includes(sessionId));
|
||||
if (matches.length === 0) throw new Error(`No discovered service contains session ${sessionId}`);
|
||||
if (matches.length > 1) throw new Error(`Session ${sessionId} is available from more than one service`);
|
||||
const route = matches[0]!.route;
|
||||
const client = await PiClient.connect({
|
||||
serviceId: route.serviceId,
|
||||
transportFactory: createUnixTransportFactory({ path: route.path }),
|
||||
});
|
||||
try {
|
||||
const attached = await client.attachSession(sessionId);
|
||||
return { kind: "attached", serviceId: route.serviceId, sessionId: attached.sessionId };
|
||||
} finally {
|
||||
await client.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
function routeFromExplicitPath(path: string): UnixServiceRoute {
|
||||
const name = basename(path);
|
||||
const serviceId = name.endsWith(".sock") ? name.slice(0, -".sock".length) : "";
|
||||
if (!isServiceId(serviceId)) {
|
||||
throw new Error("--connect path must end with <32-character-service-id>.sock");
|
||||
}
|
||||
return { serviceId, path };
|
||||
}
|
||||
|
|
@ -26,6 +26,10 @@ import {
|
|||
validateAuthCommandArgs,
|
||||
} from "./cli/auth-command.ts";
|
||||
import { resolveCredentialForPrint } from "./cli/credential-print.ts";
|
||||
import { experimentalCli } from "./cli/experimental/cli.ts";
|
||||
import type { ClientCommand } from "./cli/experimental/commands/client.ts";
|
||||
import type { ServerCommand } from "./cli/experimental/commands/server.ts";
|
||||
import { runExperimentalClient, startExperimentalMemoryServer } from "./cli/experimental/runtime.ts";
|
||||
import { processFileArguments } from "./cli/file-processor.ts";
|
||||
import { buildInitialMessage } from "./cli/initial-message.ts";
|
||||
import { listModels } from "./cli/list-models.ts";
|
||||
|
|
@ -41,6 +45,7 @@ import {
|
|||
} from "./core/agent-session-services.ts";
|
||||
import { formatNoModelsAvailableMessage } from "./core/auth-guidance.ts";
|
||||
import { AuthStorage, ReadOnlyAuthStorage } from "./core/auth-storage.ts";
|
||||
import { areExperimentalFeaturesEnabled } from "./core/experimental.ts";
|
||||
import { exportFromFile } from "./core/export-html/index.ts";
|
||||
import type { InlineExtension } from "./core/extensions/types.ts";
|
||||
import { applyHttpProxySettings, configureHttpDispatcher } from "./core/http-dispatcher.ts";
|
||||
|
|
@ -562,6 +567,61 @@ async function promptForMissingSessionCwd(
|
|||
]);
|
||||
}
|
||||
|
||||
async function waitForTermination(): Promise<void> {
|
||||
await new Promise<void>((resolve) => {
|
||||
const finish = (): void => {
|
||||
process.off("SIGINT", finish);
|
||||
process.off("SIGTERM", finish);
|
||||
resolve();
|
||||
};
|
||||
process.once("SIGINT", finish);
|
||||
process.once("SIGTERM", finish);
|
||||
});
|
||||
}
|
||||
|
||||
async function runExperimentalServerCommand(command: ServerCommand): Promise<void> {
|
||||
if (command.auth !== undefined) throw new Error("Authentication is not supported by the local demo server");
|
||||
if (command.listen !== undefined) throw new Error("The local demo server uses its service-addressed Unix socket");
|
||||
const runtime = await startExperimentalMemoryServer();
|
||||
console.log(`Service: ${runtime.serviceId}`);
|
||||
console.log(`Socket: ${runtime.socketPath}`);
|
||||
try {
|
||||
await waitForTermination();
|
||||
} finally {
|
||||
await runtime.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function runExperimentalClientCommand(command: ClientCommand): Promise<void> {
|
||||
const result = await runExperimentalClient(command);
|
||||
if (result.kind === "attached") {
|
||||
console.log(`${result.serviceId}\t${result.sessionId}\tattached`);
|
||||
return;
|
||||
}
|
||||
for (const session of result.sessions) console.log(`${session.serviceId}\t${session.sessionId}`);
|
||||
}
|
||||
|
||||
async function runExperimentalCommand(args: string[]): Promise<boolean> {
|
||||
if (!areExperimentalFeaturesEnabled()) return false;
|
||||
try {
|
||||
const result = await experimentalCli.execute(args, {
|
||||
runPi: () => {},
|
||||
runServer: runExperimentalServerCommand,
|
||||
runClient: runExperimentalClientCommand,
|
||||
});
|
||||
if (!result.ok) {
|
||||
for (const error of result.errors) console.error(chalk.red(`Error: ${error}`));
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
return result.command.command !== "pi";
|
||||
} catch (error) {
|
||||
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export interface MainOptions {
|
||||
extensionFactories?: InlineExtension[];
|
||||
}
|
||||
|
|
@ -579,6 +639,10 @@ export async function main(args: string[], options?: MainOptions) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (await runExperimentalCommand(args)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
cleanupWindowsSelfUpdateQuarantine(getPackageDir());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,16 @@ describe("experimental CLI commands", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test("parses a client session ID", () => {
|
||||
expect(experimentalCli.parse(["client", "--session-id", "demo-1"])).toEqual({
|
||||
ok: true,
|
||||
command: {
|
||||
command: "client",
|
||||
sessionId: "demo-1",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
[["--auth-token", "secret"], { type: "token", token: "secret" }],
|
||||
[["--auth-token-file", "/tmp/token"], { type: "file", path: "/tmp/token" }],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
import { mkdtemp, rm } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, describe, expect, test } from "vitest";
|
||||
import {
|
||||
type ExperimentalMemoryServer,
|
||||
runExperimentalClient,
|
||||
startExperimentalMemoryServer,
|
||||
} from "../src/cli/experimental/runtime.ts";
|
||||
|
||||
const servers = new Set<ExperimentalMemoryServer>();
|
||||
const directories = new Set<string>();
|
||||
|
||||
async function makeServer(): Promise<{ directory: string; runtime: ExperimentalMemoryServer }> {
|
||||
const directory = await mkdtemp(join(tmpdir(), "pes-"));
|
||||
directories.add(directory);
|
||||
const runtime = await startExperimentalMemoryServer({ directory });
|
||||
servers.add(runtime);
|
||||
return { directory, runtime };
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all([...servers].map((server) => server.close()));
|
||||
servers.clear();
|
||||
await Promise.all([...directories].map((directory) => rm(directory, { recursive: true, force: true })));
|
||||
directories.clear();
|
||||
});
|
||||
|
||||
describe("experimental memory server composition", () => {
|
||||
test("discovers and lists seeded sessions without hosting either session", async () => {
|
||||
const { directory, runtime } = await makeServer();
|
||||
|
||||
await expect(runExperimentalClient({ command: "client" }, { directory })).resolves.toEqual({
|
||||
kind: "list",
|
||||
sessions: [
|
||||
{ serviceId: runtime.serviceId, sessionId: "demo-1" },
|
||||
{ serviceId: runtime.serviceId, sessionId: "demo-2" },
|
||||
],
|
||||
});
|
||||
expect(runtime.server.hostedSessions).toEqual([]);
|
||||
});
|
||||
|
||||
test("attaches to a seeded session and reuses its hosted owner", async () => {
|
||||
const { directory, runtime } = await makeServer();
|
||||
|
||||
await expect(runExperimentalClient({ command: "client", sessionId: "demo-1" }, { directory })).resolves.toEqual({
|
||||
kind: "attached",
|
||||
serviceId: runtime.serviceId,
|
||||
sessionId: "demo-1",
|
||||
});
|
||||
expect(runtime.server.hostedSessions.map(({ sessionId }) => sessionId)).toEqual(["demo-1"]);
|
||||
|
||||
await runExperimentalClient({
|
||||
command: "client",
|
||||
sessionId: "demo-1",
|
||||
connect: { transport: "unix", path: runtime.socketPath },
|
||||
});
|
||||
expect(runtime.server.hostedSessions.map(({ sessionId }) => sessionId)).toEqual(["demo-1"]);
|
||||
});
|
||||
|
||||
test("reports missing and ambiguous session selections", async () => {
|
||||
const sharedDirectory = await mkdtemp(join(tmpdir(), "ped-"));
|
||||
directories.add(sharedDirectory);
|
||||
const firstShared = await startExperimentalMemoryServer({ directory: sharedDirectory });
|
||||
const secondShared = await startExperimentalMemoryServer({ directory: sharedDirectory });
|
||||
servers.add(firstShared);
|
||||
servers.add(secondShared);
|
||||
|
||||
await expect(
|
||||
runExperimentalClient({ command: "client", sessionId: "missing" }, { directory: sharedDirectory }),
|
||||
).rejects.toThrow("No discovered service contains session missing");
|
||||
await expect(
|
||||
runExperimentalClient({ command: "client", sessionId: "demo-1" }, { directory: sharedDirectory }),
|
||||
).rejects.toThrow("Session demo-1 is available from more than one service");
|
||||
});
|
||||
});
|
||||
|
|
@ -8,6 +8,11 @@
|
|||
"@earendil-works/pi-ai": ["../ai/dist/index.d.ts"],
|
||||
"@earendil-works/pi-ai/*": ["../ai/dist/*.d.ts", "../ai/dist/providers/*.d.ts"],
|
||||
"@earendil-works/pi-client": ["../client/dist/index.d.ts"],
|
||||
"@earendil-works/pi-client/unix": ["../client/dist/unix.d.ts"],
|
||||
"@earendil-works/pi-client/*": ["../client/dist/*.d.ts"],
|
||||
"@earendil-works/pi-server": ["../server/dist/index.d.ts"],
|
||||
"@earendil-works/pi-server/unix": ["../server/dist/transports/unix/index.d.ts"],
|
||||
"@earendil-works/pi-server/*": ["../server/dist/*.d.ts", "../server/dist/transports/*/index.d.ts"],
|
||||
"@earendil-works/pi-protocol": ["../protocol/dist/index.d.ts"],
|
||||
"@earendil-works/pi-tui": ["../tui/dist/index.d.ts"],
|
||||
"@earendil-works/pi-tui/*": ["../tui/dist/*.d.ts", "../tui/dist/components/*.d.ts"]
|
||||
|
|
|
|||
|
|
@ -22,6 +22,18 @@ export default mergeConfig(
|
|||
},
|
||||
resolve: {
|
||||
alias: [
|
||||
{
|
||||
find: /^@earendil-works\/pi-client\/unix$/,
|
||||
replacement: fileURLToPath(new URL("../client/src/unix.ts", import.meta.url)),
|
||||
},
|
||||
{
|
||||
find: /^@earendil-works\/pi-server\/unix$/,
|
||||
replacement: fileURLToPath(new URL("../server/src/transports/unix/index.ts", import.meta.url)),
|
||||
},
|
||||
{
|
||||
find: /^@earendil-works\/pi-server$/,
|
||||
replacement: fileURLToPath(new URL("../server/src/index.ts", import.meta.url)),
|
||||
},
|
||||
{
|
||||
find: /^@earendil-works\/pi-client$/,
|
||||
replacement: fileURLToPath(new URL("../client/src/index.ts", import.meta.url)),
|
||||
|
|
@ -30,6 +42,8 @@ export default mergeConfig(
|
|||
find: /^@earendil-works\/pi-protocol$/,
|
||||
replacement: fileURLToPath(new URL("../protocol/src/index.ts", import.meta.url)),
|
||||
},
|
||||
{ find: /^@earendil-works\/pi-ai$/, replacement: workspaceSourcePaths.aiIndex },
|
||||
{ find: /^@earendil-works\/pi-agent-core$/, replacement: workspaceSourcePaths.agentIndex },
|
||||
{ find: /^@mariozechner\/pi-ai$/, replacement: workspaceSourcePaths.aiIndex },
|
||||
{ find: /^@mariozechner\/pi-ai\/oauth$/, replacement: workspaceSourcePaths.aiOAuth },
|
||||
{ find: /^@mariozechner\/pi-agent-core$/, replacement: workspaceSourcePaths.agentIndex },
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@
|
|||
"@earendil-works/pi-protocol": ["./packages/protocol/src/index.ts"],
|
||||
"@earendil-works/pi-protocol/*": ["./packages/protocol/src/*"],
|
||||
"@earendil-works/pi-client": ["./packages/client/src/index.ts"],
|
||||
"@earendil-works/pi-client/unix": ["./packages/client/src/unix.ts"],
|
||||
"@earendil-works/pi-client/*": ["./packages/client/src/*"],
|
||||
"@earendil-works/pi-server": ["./packages/server/src/index.ts"],
|
||||
"@earendil-works/pi-server/unix": ["./packages/server/src/transports/unix/index.ts"],
|
||||
"@earendil-works/pi-server/*": ["./packages/server/src/*"],
|
||||
"typebox": ["./node_modules/typebox"],
|
||||
"@earendil-works/pi-tui": ["./packages/tui/src/index.ts"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue