fix: keep runtime skills scoped to ./skills
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { Command } from "commander";
|
||||
import type { Agent } from "@paperclipai/shared";
|
||||
import {
|
||||
removeMaintainerOnlySkillSymlinks,
|
||||
resolvePaperclipSkillsDir,
|
||||
} from "@paperclipai/adapter-utils/server-utils";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
@@ -34,17 +38,12 @@ interface SkillsInstallSummary {
|
||||
tool: "codex" | "claude";
|
||||
target: string;
|
||||
linked: string[];
|
||||
removed: string[];
|
||||
skipped: string[];
|
||||
failed: Array<{ name: string; error: string }>;
|
||||
}
|
||||
|
||||
const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const PAPERCLIP_SKILLS_CANDIDATES = [
|
||||
path.resolve(__moduleDir, "../../../../../.agents/skills"), // dev: cli/src/commands/client -> repo root/.agents/skills
|
||||
path.resolve(__moduleDir, "../../../../../skills"), // dev: cli/src/commands/client -> repo root/skills
|
||||
path.resolve(process.cwd(), ".agents/skills"),
|
||||
path.resolve(process.cwd(), "skills"),
|
||||
];
|
||||
|
||||
function codexSkillsHome(): string {
|
||||
const fromEnv = process.env.CODEX_HOME?.trim();
|
||||
@@ -58,14 +57,6 @@ function claudeSkillsHome(): string {
|
||||
return path.join(base, "skills");
|
||||
}
|
||||
|
||||
async function resolvePaperclipSkillsDir(): Promise<string | null> {
|
||||
for (const candidate of PAPERCLIP_SKILLS_CANDIDATES) {
|
||||
const isDir = await fs.stat(candidate).then((s) => s.isDirectory()).catch(() => false);
|
||||
if (isDir) return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function installSkillsForTarget(
|
||||
sourceSkillsDir: string,
|
||||
targetSkillsDir: string,
|
||||
@@ -75,12 +66,17 @@ async function installSkillsForTarget(
|
||||
tool,
|
||||
target: targetSkillsDir,
|
||||
linked: [],
|
||||
removed: [],
|
||||
skipped: [],
|
||||
failed: [],
|
||||
};
|
||||
|
||||
await fs.mkdir(targetSkillsDir, { recursive: true });
|
||||
const entries = await fs.readdir(sourceSkillsDir, { withFileTypes: true });
|
||||
summary.removed = await removeMaintainerOnlySkillSymlinks(
|
||||
targetSkillsDir,
|
||||
entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name),
|
||||
);
|
||||
for (const entry of entries) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
const source = path.join(sourceSkillsDir, entry.name);
|
||||
@@ -140,7 +136,6 @@ async function installSkillsForTarget(
|
||||
error: err instanceof Error ? err.message : String(err),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return summary;
|
||||
@@ -253,10 +248,10 @@ export function registerAgentCommands(program: Command): void {
|
||||
|
||||
const installSummaries: SkillsInstallSummary[] = [];
|
||||
if (opts.installSkills !== false) {
|
||||
const skillsDir = await resolvePaperclipSkillsDir();
|
||||
const skillsDir = await resolvePaperclipSkillsDir(__moduleDir, [path.resolve(process.cwd(), "skills")]);
|
||||
if (!skillsDir) {
|
||||
throw new Error(
|
||||
"Could not locate local Paperclip skills directory. Expected ./skills or ./.agents/skills in the repo checkout.",
|
||||
"Could not locate local Paperclip skills directory. Expected ./skills in the repo checkout.",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -301,7 +296,7 @@ export function registerAgentCommands(program: Command): void {
|
||||
if (installSummaries.length > 0) {
|
||||
for (const summary of installSummaries) {
|
||||
console.log(
|
||||
`${summary.tool}: linked=${summary.linked.length} skipped=${summary.skipped.length} failed=${summary.failed.length} target=${summary.target}`,
|
||||
`${summary.tool}: linked=${summary.linked.length} removed=${summary.removed.length} skipped=${summary.skipped.length} failed=${summary.failed.length} target=${summary.target}`,
|
||||
);
|
||||
for (const failed of summary.failed) {
|
||||
console.log(` failed ${failed.name}: ${failed.error}`);
|
||||
|
||||
Reference in New Issue
Block a user