mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-20 22:40:58 +00:00
fix(ci): resolve Claude marketplace shortcuts from OS home
This commit is contained in:
@@ -4,6 +4,8 @@ import {
|
||||
expandHomePrefix,
|
||||
resolveEffectiveHomeDir,
|
||||
resolveHomeRelativePath,
|
||||
resolveOsHomeDir,
|
||||
resolveOsHomeRelativePath,
|
||||
resolveRequiredHomeDir,
|
||||
} from "./home-dir.js";
|
||||
|
||||
@@ -95,6 +97,21 @@ describe("resolveRequiredHomeDir", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveOsHomeDir", () => {
|
||||
it("ignores OPENCLAW_HOME and uses HOME", () => {
|
||||
expect(
|
||||
resolveOsHomeDir(
|
||||
{
|
||||
OPENCLAW_HOME: "/srv/openclaw-home",
|
||||
HOME: "/home/alice",
|
||||
USERPROFILE: "C:/Users/alice",
|
||||
} as NodeJS.ProcessEnv,
|
||||
() => "/fallback",
|
||||
),
|
||||
).toBe(path.resolve("/home/alice"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("expandHomePrefix", () => {
|
||||
it.each([
|
||||
{
|
||||
@@ -158,3 +175,16 @@ describe("resolveHomeRelativePath", () => {
|
||||
).toBe(path.resolve(process.cwd()));
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveOsHomeRelativePath", () => {
|
||||
it("expands tilde paths using the OS home instead of OPENCLAW_HOME", () => {
|
||||
expect(
|
||||
resolveOsHomeRelativePath("~/docs", {
|
||||
env: {
|
||||
OPENCLAW_HOME: "/srv/openclaw-home",
|
||||
HOME: "/home/alice",
|
||||
} as NodeJS.ProcessEnv,
|
||||
}),
|
||||
).toBe(path.resolve("/home/alice/docs"));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,12 +14,19 @@ export function resolveEffectiveHomeDir(
|
||||
return raw ? path.resolve(raw) : undefined;
|
||||
}
|
||||
|
||||
export function resolveOsHomeDir(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
homedir: () => string = os.homedir,
|
||||
): string | undefined {
|
||||
const raw = resolveRawOsHomeDir(env, homedir);
|
||||
return raw ? path.resolve(raw) : undefined;
|
||||
}
|
||||
|
||||
function resolveRawHomeDir(env: NodeJS.ProcessEnv, homedir: () => string): string | undefined {
|
||||
const explicitHome = normalize(env.OPENCLAW_HOME);
|
||||
if (explicitHome) {
|
||||
if (explicitHome === "~" || explicitHome.startsWith("~/") || explicitHome.startsWith("~\\")) {
|
||||
const fallbackHome =
|
||||
normalize(env.HOME) ?? normalize(env.USERPROFILE) ?? normalizeSafe(homedir);
|
||||
const fallbackHome = resolveRawOsHomeDir(env, homedir);
|
||||
if (fallbackHome) {
|
||||
return explicitHome.replace(/^~(?=$|[\\/])/, fallbackHome);
|
||||
}
|
||||
@@ -28,16 +35,18 @@ function resolveRawHomeDir(env: NodeJS.ProcessEnv, homedir: () => string): strin
|
||||
return explicitHome;
|
||||
}
|
||||
|
||||
return resolveRawOsHomeDir(env, homedir);
|
||||
}
|
||||
|
||||
function resolveRawOsHomeDir(env: NodeJS.ProcessEnv, homedir: () => string): string | undefined {
|
||||
const envHome = normalize(env.HOME);
|
||||
if (envHome) {
|
||||
return envHome;
|
||||
}
|
||||
|
||||
const userProfile = normalize(env.USERPROFILE);
|
||||
if (userProfile) {
|
||||
return userProfile;
|
||||
}
|
||||
|
||||
return normalizeSafe(homedir);
|
||||
}
|
||||
|
||||
@@ -56,6 +65,13 @@ export function resolveRequiredHomeDir(
|
||||
return resolveEffectiveHomeDir(env, homedir) ?? path.resolve(process.cwd());
|
||||
}
|
||||
|
||||
export function resolveRequiredOsHomeDir(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
homedir: () => string = os.homedir,
|
||||
): string {
|
||||
return resolveOsHomeDir(env, homedir) ?? path.resolve(process.cwd());
|
||||
}
|
||||
|
||||
export function expandHomePrefix(
|
||||
input: string,
|
||||
opts?: {
|
||||
@@ -97,3 +113,25 @@ export function resolveHomeRelativePath(
|
||||
}
|
||||
return path.resolve(trimmed);
|
||||
}
|
||||
|
||||
export function resolveOsHomeRelativePath(
|
||||
input: string,
|
||||
opts?: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
homedir?: () => string;
|
||||
},
|
||||
): string {
|
||||
const trimmed = input.trim();
|
||||
if (!trimmed) {
|
||||
return trimmed;
|
||||
}
|
||||
if (trimmed.startsWith("~")) {
|
||||
const expanded = expandHomePrefix(trimmed, {
|
||||
home: resolveRequiredOsHomeDir(opts?.env ?? process.env, opts?.homedir ?? os.homedir),
|
||||
env: opts?.env,
|
||||
homedir: opts?.homedir,
|
||||
});
|
||||
return path.resolve(expanded);
|
||||
}
|
||||
return path.resolve(trimmed);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,9 @@ describe("marketplace plugins", () => {
|
||||
|
||||
it("resolves Claude-style plugin@marketplace shortcuts from known_marketplaces.json", async () => {
|
||||
await withTempDir(async (homeDir) => {
|
||||
const openClawHome = path.join(homeDir, "openclaw-home");
|
||||
await fs.mkdir(path.join(homeDir, ".claude", "plugins"), { recursive: true });
|
||||
await fs.mkdir(openClawHome, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(homeDir, ".claude", "plugins", "known_marketplaces.json"),
|
||||
JSON.stringify({
|
||||
@@ -127,7 +129,7 @@ describe("marketplace plugins", () => {
|
||||
|
||||
const { resolveMarketplaceInstallShortcut } = await import("./marketplace.js");
|
||||
const shortcut = await withEnvAsync(
|
||||
{ HOME: homeDir },
|
||||
{ HOME: homeDir, OPENCLAW_HOME: openClawHome },
|
||||
async () => await resolveMarketplaceInstallShortcut("superpowers@claude-plugins-official"),
|
||||
);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { resolveArchiveKind } from "../infra/archive.js";
|
||||
import { resolveOsHomeRelativePath } from "../infra/home-dir.js";
|
||||
import { runCommandWithTimeout } from "../process/exec.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
import { installPluginFromPath, type InstallPluginResult } from "./install.js";
|
||||
@@ -299,7 +300,7 @@ async function pathExists(target: string): Promise<boolean> {
|
||||
}
|
||||
|
||||
async function readClaudeKnownMarketplaces(): Promise<Record<string, KnownMarketplaceRecord>> {
|
||||
const knownPath = resolveUserPath(CLAUDE_KNOWN_MARKETPLACES_PATH);
|
||||
const knownPath = resolveOsHomeRelativePath(CLAUDE_KNOWN_MARKETPLACES_PATH);
|
||||
if (!(await pathExists(knownPath))) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user