feat(init): detect plugin package managers

This commit is contained in:
Vincent Koc 2026-04-27 14:36:01 -07:00
parent 10d9c84865
commit 26543792f1
No known key found for this signature in database
6 changed files with 46 additions and 3 deletions

View File

@ -24,6 +24,9 @@ Add a local config and GitHub Actions workflow:
npx @openclaw/plugin-inspector init --ci
```
`init --ci` detects `packageManager` and common lockfiles. Pass
`--package-manager pnpm`, `npm`, `yarn`, or `bun` when you want to override it.
Or install it as a dev dependency:
```bash

View File

@ -138,6 +138,7 @@ export {
buildPluginInspectorConfig,
defaultInitConfigPath,
defaultInitWorkflowPath,
detectPackageManager,
renderGithubActionsWorkflow,
writePluginInspectorInit,
} from "./init.js";

View File

@ -95,7 +95,7 @@ async function runInit(commandArgs) {
const pluginRoot = readFlag(commandArgs, "--plugin-root") ?? readFlag(commandArgs, "--root");
const configPath = readFlag(commandArgs, "--config") ?? undefined;
const workflowPath = readFlag(commandArgs, "--workflow") ?? undefined;
const packageManager = readFlag(commandArgs, "--package-manager") ?? "npm";
const packageManager = readFlag(commandArgs, "--package-manager") ?? undefined;
const result = await writePluginInspectorInit({
pluginRoot,
configPath,

View File

@ -9,6 +9,7 @@ export const defaultInitWorkflowPath = ".github/workflows/plugin-inspector.yml";
export async function writePluginInspectorInit(options = {}) {
const pluginRoot = path.resolve(options.pluginRoot ?? options.cwd ?? process.cwd());
const configPath = path.resolve(pluginRoot, options.configPath ?? defaultInitConfigPath);
const packageManager = options.packageManager ?? (await detectPackageManager(pluginRoot));
const written = [];
if (existsSync(configPath) && options.force !== true) {
@ -26,11 +27,11 @@ export async function writePluginInspectorInit(options = {}) {
throw new Error(`${path.relative(pluginRoot, workflowPath)} already exists; pass --force to overwrite it`);
}
await mkdir(path.dirname(workflowPath), { recursive: true });
await writeFile(workflowPath, renderGithubActionsWorkflow({ packageManager: options.packageManager }), "utf8");
await writeFile(workflowPath, renderGithubActionsWorkflow({ packageManager }), "utf8");
written.push(workflowPath);
}
return { pluginRoot, configPath, written };
return { pluginRoot, configPath, packageManager, written };
}
export async function buildPluginInspectorConfig(options = {}) {
@ -88,6 +89,29 @@ ${setup.corepack ? " - run: corepack enable\n" : ""} - run: ${setup.in
`;
}
export async function detectPackageManager(pluginRoot) {
const root = path.resolve(pluginRoot ?? process.cwd());
const packageJson = await readJsonIfExists(path.join(root, "package.json"));
const packageManager = packageJson?.packageManager;
if (typeof packageManager === "string") {
const [name] = packageManager.split("@");
if (["npm", "pnpm", "yarn", "bun"].includes(name)) {
return name;
}
}
if (existsSync(path.join(root, "pnpm-lock.yaml"))) {
return "pnpm";
}
if (existsSync(path.join(root, "yarn.lock"))) {
return "yarn";
}
if (existsSync(path.join(root, "bun.lockb")) || existsSync(path.join(root, "bun.lock"))) {
return "bun";
}
return "npm";
}
function inferSourceRoot(packageJson) {
const entrypoints = [
packageJson?.openclaw?.entrypoint,

View File

@ -135,6 +135,7 @@ test("public API can initialize plugin inspector files", async () => {
const workflow = await readFile(path.join(pluginRoot, ".github", "workflows", "plugin-inspector.yml"), "utf8");
assert.equal(result.written.length, 2);
assert.equal(result.packageManager, "npm");
assert.equal(config.plugin.id, "weather");
assert.equal(config.capture.mockSdk, true);
assert.match(workflow, /npx @openclaw\/plugin-inspector ci --no-openclaw --runtime --mock-sdk/);

View File

@ -211,6 +211,20 @@ test("init command writes plugin config and CI workflow", async () => {
assert.match(workflow, /pnpm dlx @openclaw\/plugin-inspector ci --no-openclaw --runtime --mock-sdk/);
});
test("init command detects plugin package managers", async () => {
const rootDir = await createCliPluginRoot("plugin-inspector-cli-init-pm-");
const cliPath = path.resolve("src/cli.js");
await writeFile(path.join(rootDir, "pnpm-lock.yaml"), "lockfileVersion: '9.0'\n", "utf8");
await execFileAsync(process.execPath, [cliPath, "init", "--plugin-root", rootDir, "--ci", "--force"]);
const workflow = await readFile(path.join(rootDir, ".github", "workflows", "plugin-inspector.yml"), "utf8");
assert.match(workflow, /cache: pnpm/);
assert.match(workflow, /corepack enable/);
assert.match(workflow, /pnpm install --frozen-lockfile/);
assert.match(workflow, /pnpm dlx @openclaw\/plugin-inspector ci --no-openclaw --runtime --mock-sdk/);
});
async function createCliPluginRoot(prefix) {
const rootDir = await mkdtemp(path.join(os.tmpdir(), prefix));
await mkdir(path.join(rootDir, "src"), { recursive: true });