mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 18:05:11 +00:00
fix(coding-agent): normalize local package removal paths (fixes #1243)
This commit is contained in:
parent
150aeebf7d
commit
b1c2c95f23
2 changed files with 65 additions and 3 deletions
|
|
@ -94,7 +94,7 @@ function expandTildePath(input: string): string {
|
||||||
|
|
||||||
function resolveLocalSourceFromInput(source: string, cwd: string): string {
|
function resolveLocalSourceFromInput(source: string, cwd: string): string {
|
||||||
const expanded = expandTildePath(source);
|
const expanded = expandTildePath(source);
|
||||||
return isAbsolute(expanded) ? expanded : resolve(cwd, expanded);
|
return isAbsolute(expanded) ? resolve(expanded) : resolve(cwd, expanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveLocalSourceFromSettings(source: string, baseDir: string): string {
|
function resolveLocalSourceFromSettings(source: string, baseDir: string): string {
|
||||||
|
|
@ -172,18 +172,21 @@ function updatePackageSources(
|
||||||
cwd: string,
|
cwd: string,
|
||||||
agentDir: string,
|
agentDir: string,
|
||||||
action: "add" | "remove",
|
action: "add" | "remove",
|
||||||
): void {
|
): boolean {
|
||||||
const currentSettings = local ? settingsManager.getProjectSettings() : settingsManager.getGlobalSettings();
|
const currentSettings = local ? settingsManager.getProjectSettings() : settingsManager.getGlobalSettings();
|
||||||
const currentPackages = currentSettings.packages ?? [];
|
const currentPackages = currentSettings.packages ?? [];
|
||||||
const baseDir = local ? join(cwd, CONFIG_DIR_NAME) : agentDir;
|
const baseDir = local ? join(cwd, CONFIG_DIR_NAME) : agentDir;
|
||||||
const normalizedSource = normalizePackageSourceForSettings(source, baseDir, cwd);
|
const normalizedSource = normalizePackageSourceForSettings(source, baseDir, cwd);
|
||||||
|
|
||||||
let nextPackages: PackageSource[];
|
let nextPackages: PackageSource[];
|
||||||
|
let changed = false;
|
||||||
if (action === "add") {
|
if (action === "add") {
|
||||||
const exists = currentPackages.some((existing) => packageSourcesMatch(existing, source, baseDir, cwd));
|
const exists = currentPackages.some((existing) => packageSourcesMatch(existing, source, baseDir, cwd));
|
||||||
nextPackages = exists ? currentPackages : [...currentPackages, normalizedSource];
|
nextPackages = exists ? currentPackages : [...currentPackages, normalizedSource];
|
||||||
|
changed = !exists;
|
||||||
} else {
|
} else {
|
||||||
nextPackages = currentPackages.filter((existing) => !packageSourcesMatch(existing, source, baseDir, cwd));
|
nextPackages = currentPackages.filter((existing) => !packageSourcesMatch(existing, source, baseDir, cwd));
|
||||||
|
changed = nextPackages.length !== currentPackages.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
|
|
@ -191,6 +194,8 @@ function updatePackageSources(
|
||||||
} else {
|
} else {
|
||||||
settingsManager.setPackages(nextPackages);
|
settingsManager.setPackages(nextPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handlePackageCommand(args: string[]): Promise<boolean> {
|
async function handlePackageCommand(args: string[]): Promise<boolean> {
|
||||||
|
|
@ -230,7 +235,11 @@ async function handlePackageCommand(args: string[]): Promise<boolean> {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
await packageManager.remove(options.source, { local: options.local });
|
await packageManager.remove(options.source, { local: options.local });
|
||||||
updatePackageSources(settingsManager, options.source, options.local, cwd, agentDir, "remove");
|
const removed = updatePackageSources(settingsManager, options.source, options.local, cwd, agentDir, "remove");
|
||||||
|
if (!removed) {
|
||||||
|
console.error(chalk.red(`No matching package found for ${options.source}`));
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
console.log(chalk.green(`Removed ${options.source}`));
|
console.log(chalk.green(`Removed ${options.source}`));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
packages/coding-agent/test/package-command-paths.test.ts
Normal file
53
packages/coding-agent/test/package-command-paths.test.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { mkdirSync, readFileSync, rmSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import { ENV_AGENT_DIR } from "../src/config.js";
|
||||||
|
import { main } from "../src/main.js";
|
||||||
|
|
||||||
|
describe("package commands", () => {
|
||||||
|
let tempDir: string;
|
||||||
|
let agentDir: string;
|
||||||
|
let projectDir: string;
|
||||||
|
let packageDir: string;
|
||||||
|
let originalCwd: string;
|
||||||
|
let originalAgentDir: string | undefined;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tempDir = join(tmpdir(), `pi-package-commands-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
||||||
|
agentDir = join(tempDir, "agent");
|
||||||
|
projectDir = join(tempDir, "project");
|
||||||
|
packageDir = join(tempDir, "local-package");
|
||||||
|
mkdirSync(agentDir, { recursive: true });
|
||||||
|
mkdirSync(projectDir, { recursive: true });
|
||||||
|
mkdirSync(packageDir, { recursive: true });
|
||||||
|
|
||||||
|
originalCwd = process.cwd();
|
||||||
|
originalAgentDir = process.env[ENV_AGENT_DIR];
|
||||||
|
process.env[ENV_AGENT_DIR] = agentDir;
|
||||||
|
process.chdir(projectDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
process.chdir(originalCwd);
|
||||||
|
if (originalAgentDir === undefined) {
|
||||||
|
delete process.env[ENV_AGENT_DIR];
|
||||||
|
} else {
|
||||||
|
process.env[ENV_AGENT_DIR] = originalAgentDir;
|
||||||
|
}
|
||||||
|
rmSync(tempDir, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should remove local packages using a path with a trailing slash", async () => {
|
||||||
|
await main(["install", `${packageDir}/`]);
|
||||||
|
|
||||||
|
const settingsPath = join(agentDir, "settings.json");
|
||||||
|
const installedSettings = JSON.parse(readFileSync(settingsPath, "utf-8")) as { packages?: string[] };
|
||||||
|
expect(installedSettings.packages?.length).toBe(1);
|
||||||
|
|
||||||
|
await main(["remove", `${packageDir}/`]);
|
||||||
|
|
||||||
|
const removedSettings = JSON.parse(readFileSync(settingsPath, "utf-8")) as { packages?: string[] };
|
||||||
|
expect(removedSettings.packages ?? []).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue