diff --git a/.changeset/skill-path-single-resolver.md b/.changeset/skill-path-single-resolver.md new file mode 100644 index 000000000..871feef7f --- /dev/null +++ b/.changeset/skill-path-single-resolver.md @@ -0,0 +1,5 @@ +--- +"eve": patch +--- + +Resolve sandbox skill roots and seed-file paths through the same `$HOME` resolver the file tools use, so the skills location is spelled once instead of twice. diff --git a/packages/eve/src/execution/sandbox/bindings/local-backend-utils.ts b/packages/eve/src/execution/sandbox/bindings/local-backend-utils.ts index bf436bd3b..340ba0591 100644 --- a/packages/eve/src/execution/sandbox/bindings/local-backend-utils.ts +++ b/packages/eve/src/execution/sandbox/bindings/local-backend-utils.ts @@ -4,7 +4,7 @@ import { dirname, join } from "node:path"; import { bufferToStream, streamToBuffer } from "#execution/sandbox/stream-utils.js"; import { WORKSPACE_ROOT } from "#runtime/workspace/types.js"; -import { resolveSandboxSeedFilePath } from "#shared/skill-paths.js"; +import { resolveSandboxModelPath } from "#shared/skill-paths.js"; import type { SandboxSeedFile } from "#shared/sandbox-backend.js"; import type { InternalSandboxSession, @@ -116,7 +116,7 @@ export async function writeSandboxSeedFiles( seedFiles: ReadonlyArray, ): Promise { for (const file of seedFiles) { - const path = await resolveSandboxSeedFilePath({ + const path = await resolveSandboxModelPath({ path: file.path, sandbox: session, }); diff --git a/packages/eve/src/shared/skill-paths.test.ts b/packages/eve/src/shared/skill-paths.test.ts index c4a60ece6..3ba456cf7 100644 --- a/packages/eve/src/shared/skill-paths.test.ts +++ b/packages/eve/src/shared/skill-paths.test.ts @@ -7,7 +7,6 @@ import { formatFallbackSkillPath, formatSkillModelPath, resolveSandboxModelPath, - resolveSandboxSeedFilePath, resolveSandboxSkillReadPaths, resolveSandboxSkillRoot, } from "#shared/skill-paths.js"; @@ -126,7 +125,7 @@ describe("skill path helpers", () => { }); await expect( - resolveSandboxSeedFilePath({ + resolveSandboxModelPath({ path: `${MODEL_SKILL_ROOT}/research/references/catalog.md`, sandbox: sandbox.session, }), diff --git a/packages/eve/src/shared/skill-paths.ts b/packages/eve/src/shared/skill-paths.ts index 04faddd35..f4486e5b9 100644 --- a/packages/eve/src/shared/skill-paths.ts +++ b/packages/eve/src/shared/skill-paths.ts @@ -1,10 +1,10 @@ import type { SandboxSession } from "#shared/sandbox-session.js"; -export const MODEL_SKILL_ROOT = "$HOME/.agents/skills"; +const MODEL_HOME_ROOT = "$HOME"; + +export const MODEL_SKILL_ROOT = `${MODEL_HOME_ROOT}/.agents/skills`; export const FALLBACK_SKILL_ROOT = "/workspace/skills"; -const MODEL_HOME_ROOT = "$HOME"; -const HOME_SKILL_SUFFIX = ".agents/skills"; const HOME_PROBE_COMMAND = `printf '%s\\n' "$HOME"`; const sandboxHomeCache = new WeakMap>(); @@ -30,11 +30,14 @@ export function formatFallbackSkillPath(input: { }); } +/** + * Resolves where skills live in the sandbox: under the probed home when it has + * one, and under {@link FALLBACK_SKILL_ROOT} when it does not. + */ export async function resolveSandboxSkillRoot(input: { readonly sandbox: SandboxSession; }): Promise { - const home = await resolveSandboxHome(input.sandbox); - return home === null ? FALLBACK_SKILL_ROOT : joinHomeSkillRoot(home); + return await resolveSandboxModelPath({ path: MODEL_SKILL_ROOT, sandbox: input.sandbox }); } /** @@ -90,17 +93,6 @@ export async function resolveSandboxSkillWritePath(input: { }); } -export async function resolveSandboxSeedFilePath(input: { - readonly path: string; - readonly sandbox: SandboxSession; -}): Promise { - if (!isModelSkillPath(input.path)) { - return input.path; - } - - return await resolveSandboxModelPath(input); -} - function formatSkillPath(input: { readonly name: string; readonly relativePath: string; @@ -156,10 +148,6 @@ function isUsableSandboxHome(path: string): boolean { ); } -function joinHomeSkillRoot(home: string): string { - return `${home === "/" ? "" : home}/${HOME_SKILL_SUFFIX}`; -} - function normalizeSandboxHome(home: string): string { return home === "/" ? home : home.replace(/\/+$/, ""); }