claudepluginhub 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/detect.js +21 -13
  2. package/package.json +1 -1
package/dist/detect.js CHANGED
@@ -1,9 +1,16 @@
1
1
  import { fetchDefaultBranch, fetchTree, downloadFile } from './github.js';
2
2
  import { printError } from './output.js';
3
+ import { sanitizeName } from './wrapper.js';
3
4
  const OWNER_REPO_RE = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/;
4
5
  const VALID_NAME_RE = /^[a-zA-Z0-9_.-]+$/;
5
6
  export function isOwnerRepo(identifier) {
6
- return OWNER_REPO_RE.test(identifier);
7
+ if (!OWNER_REPO_RE.test(identifier))
8
+ return false;
9
+ const [owner, repo] = identifier.split('/');
10
+ // Reject segments that are purely dots (e.g. "..", ".")
11
+ if (/^\.+$/.test(owner) || /^\.+$/.test(repo))
12
+ return false;
13
+ return true;
7
14
  }
8
15
  const COMPONENT_PATTERNS = [
9
16
  /^commands\/.*\.md$/,
@@ -59,6 +66,10 @@ export async function detectRepo(ownerRepo) {
59
66
  printError('marketplace.json is missing the required "name" field');
60
67
  process.exit(1);
61
68
  }
69
+ if (!VALID_NAME_RE.test(manifest.name)) {
70
+ printError(`marketplace.json has an invalid name: "${manifest.name}". Must match [a-zA-Z0-9_.-]+`);
71
+ process.exit(1);
72
+ }
62
73
  const rawPlugins = manifest.plugins;
63
74
  if (!Array.isArray(rawPlugins)) {
64
75
  printError('marketplace.json "plugins" must be an array');
@@ -80,14 +91,18 @@ export async function detectRepo(ownerRepo) {
80
91
  printError(`marketplace.json plugin has an invalid name: "${name}". Must match [a-zA-Z0-9_.-]+`);
81
92
  process.exit(1);
82
93
  }
94
+ const rawSource = plugin.source;
95
+ const source = rawSource &&
96
+ typeof rawSource === 'object' &&
97
+ typeof rawSource.source === 'string' &&
98
+ typeof rawSource.repo === 'string'
99
+ ? rawSource
100
+ : { source: 'github', repo: ownerRepo };
83
101
  validPlugins.push({
84
102
  name,
85
103
  description: typeof plugin.description === 'string' ? plugin.description : null,
86
- source: plugin.source ?? {
87
- source: 'github',
88
- repo: ownerRepo,
89
- },
90
- strict: plugin.strict ?? true,
104
+ source,
105
+ strict: plugin.strict === false ? false : true,
91
106
  });
92
107
  }
93
108
  return {
@@ -135,10 +150,3 @@ export async function detectRepo(ownerRepo) {
135
150
  }
136
151
  return { kind: 'unknown' };
137
152
  }
138
- function sanitizeName(raw) {
139
- return (raw
140
- .toLowerCase()
141
- .replace(/[^a-z0-9-]/g, '-')
142
- .replace(/-+/g, '-')
143
- .replace(/^-|-$/g, '') || 'plugin');
144
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudepluginhub",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Install Claude Code components from ClaudePluginHub",
5
5
  "bin": {
6
6
  "claudepluginhub": "dist/index.js"