Skip to content

Commit 94de6f0

Browse files
committed
Fix npx install for Claude Code v2.1.112
Four bugs prevented `npx beastmode install` from producing a working plugin on a clean Claude Code installation: 1. `.claude-plugin/` missing from `files` in package.json — npm strips it from the tarball even when fetching from GitHub, causing plugin-copier to fail with ENOENT. 2. index.mjs exits with code 1 on install failure but never prints the error message — users see only the version banner. 3. config-merger.mjs writes `source.name` in known_marketplaces.json but Claude Code's Zod schema requires `source.package`. 4. config-merger.mjs uses `source: "npm"` which Claude Code v2.1.112 hasn't implemented. Additionally, plugin-copier writes marketplace.json to the wrong location (Claude Code expects it in a `.claude-plugin/` subdirectory) and the `./plugin` relative source path doesn't resolve. Fixes: include `.claude-plugin/` in package files, print install errors, use `source: "directory"` instead of `source: "npm"`, write marketplace.json into `.claude-plugin/` subdir, and symlink the plugin cache so the relative source path resolves. All bugs introduced in v0.101.0 (2d84d3c). Tested from clean state on Claude Code v2.1.112 / macOS.
1 parent c155da5 commit 94de6f0

4 files changed

Lines changed: 14 additions & 7 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"files": [
1010
"src/npx-cli/",
1111
"plugin/",
12-
"cli/"
12+
"cli/",
13+
".claude-plugin/"
1314
],
1415
"scripts": {
1516
"test:npx": "node --test src/npx-cli/__tests__/*.test.mjs",

src/npx-cli/config-merger.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ async function mergeKnownMarketplaces(homeDir) {
3737

3838
data['beastmode-marketplace'] = {
3939
source: {
40-
source: 'npm',
41-
name: 'beastmode',
40+
source: 'directory',
41+
path: join(homeDir, '.claude', 'plugins', 'marketplaces', 'bugroger'),
4242
},
4343
installLocation: join(homeDir, '.claude', 'plugins', 'marketplaces', 'bugroger'),
4444
lastUpdated: new Date().toISOString(),

src/npx-cli/index.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ switch (command) {
1818
homeDir: homedir(),
1919
packageDir,
2020
});
21+
if (!result.success) {
22+
console.error(`Install failed at step "${result.step}": ${result.error}`);
23+
}
2124
process.exit(result.success ? 0 : 1);
2225
break;
2326
}

src/npx-cli/plugin-copier.mjs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// src/npx-cli/plugin-copier.mjs
2-
import { cp, rm, mkdir } from 'node:fs/promises';
2+
import { cp, rm, mkdir, symlink } from 'node:fs/promises';
33
import { join } from 'node:path';
44

55
/**
@@ -19,12 +19,12 @@ export async function copyPlugin({ homeDir, packageDir, version }) {
1919

2020
// Clean-replace marketplace directory
2121
await rm(marketplaceDir, { recursive: true, force: true });
22-
await mkdir(marketplaceDir, { recursive: true });
22+
await mkdir(join(marketplaceDir, '.claude-plugin'), { recursive: true });
2323

24-
// Copy marketplace.json to marketplace dir
24+
// Copy marketplace.json into .claude-plugin/ subdir (where Claude Code expects it)
2525
await cp(
2626
join(pluginMetaDir, 'marketplace.json'),
27-
join(marketplaceDir, 'marketplace.json')
27+
join(marketplaceDir, '.claude-plugin', 'marketplace.json')
2828
);
2929

3030
// Clean-replace cache directory
@@ -34,6 +34,9 @@ export async function copyPlugin({ homeDir, packageDir, version }) {
3434
// Copy plugin tree to cache dir (includes plugin.json, skills/, agents/, hooks/)
3535
await cp(pluginSourceDir, cacheDir, { recursive: true });
3636

37+
// Symlink plugin content into marketplace dir so "source": "./plugin" resolves
38+
await symlink(cacheDir, join(marketplaceDir, 'plugin'));
39+
3740
console.log(`Plugin files copied to ${marketplaceDir}`);
3841
console.log(`Plugin cache written to ${cacheDir}`);
3942
}

0 commit comments

Comments
 (0)