claude-code-marketplace 0.5.11 → 0.5.13

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-marketplace",
3
- "version": "0.5.11",
3
+ "version": "0.5.13",
4
4
  "description": "Web UI for browsing and managing Claude Code marketplace plugins",
5
5
  "main": "server.js",
6
6
  "bin": {
package/public/style.css CHANGED
@@ -334,11 +334,11 @@ body {
334
334
  display: flex;
335
335
  align-items: center;
336
336
  gap: 6px;
337
- padding: 6px 12px;
338
- font-size: 12px;
337
+ padding: 7px 12px;
338
+ font-size: 13px;
339
339
  cursor: pointer;
340
340
  transition: background 0.1s ease;
341
- min-height: 34px;
341
+ min-height: 38px;
342
342
  flex-wrap: nowrap;
343
343
  border-left: 2px solid transparent;
344
344
  }
@@ -360,7 +360,7 @@ body {
360
360
  position: sticky;
361
361
  top: 0;
362
362
  z-index: 2;
363
- font-size: 11px;
363
+ font-size: 12px;
364
364
  text-transform: uppercase;
365
365
  letter-spacing: 0.04em;
366
366
  padding: 8px 12px;
@@ -395,8 +395,8 @@ body {
395
395
  opacity: 0.45;
396
396
  }
397
397
  .tree-icon svg {
398
- width: 14px;
399
- height: 14px;
398
+ width: 15px;
399
+ height: 15px;
400
400
  }
401
401
  .tree-label {
402
402
  flex-shrink: 0;
@@ -405,7 +405,7 @@ body {
405
405
  color: var(--text-secondary);
406
406
  }
407
407
  .version {
408
- font-size: 10px;
408
+ font-size: 11px;
409
409
  color: var(--accent);
410
410
  background: var(--accent-dim);
411
411
  padding: 1px 5px;
@@ -421,8 +421,8 @@ body {
421
421
  color: var(--text-primary);
422
422
  }
423
423
  .tree-meta {
424
- font-size: 10px;
425
- color: var(--text-muted);
424
+ font-size: 11px;
425
+ color: var(--text-tertiary);
426
426
  flex-shrink: 0;
427
427
  white-space: nowrap;
428
428
  }
@@ -456,37 +456,50 @@ body {
456
456
  border-color: rgba(196, 149, 106, 0.4);
457
457
  color: rgba(196, 149, 106, 0.5);
458
458
  }
459
- .scope-toggle.user.active,
460
- .scope-toggle.user.disabled {
459
+ .scope-toggle.user.active {
461
460
  background: var(--scope-user-dim);
462
461
  color: var(--scope-user);
463
462
  border-color: var(--scope-user);
464
463
  }
464
+ .scope-toggle.user.disabled {
465
+ background: transparent;
466
+ color: var(--scope-user);
467
+ border-color: var(--scope-user);
468
+ }
465
469
 
466
470
  .scope-toggle.project {
467
471
  border-color: rgba(122, 181, 160, 0.4);
468
472
  color: rgba(122, 181, 160, 0.5);
469
473
  }
470
- .scope-toggle.project.active,
471
- .scope-toggle.project.disabled {
474
+ .scope-toggle.project.active {
472
475
  background: var(--scope-project-dim);
473
476
  color: var(--scope-project);
474
477
  border-color: var(--scope-project);
475
478
  }
479
+ .scope-toggle.project.disabled {
480
+ background: transparent;
481
+ color: var(--scope-project);
482
+ border-color: var(--scope-project);
483
+ }
476
484
 
477
485
  .scope-toggle.local {
478
486
  border-color: rgba(138, 155, 181, 0.4);
479
487
  color: rgba(138, 155, 181, 0.5);
480
488
  }
481
- .scope-toggle.local.active,
482
- .scope-toggle.local.disabled {
489
+ .scope-toggle.local.active {
483
490
  background: var(--scope-local-dim);
484
491
  color: var(--scope-local);
485
492
  border-color: var(--scope-local);
486
493
  }
494
+ .scope-toggle.local.disabled {
495
+ background: transparent;
496
+ color: var(--scope-local);
497
+ border-color: var(--scope-local);
498
+ }
487
499
  .scope-toggle.disabled {
488
- border-style: dashed;
489
- opacity: 0.6;
500
+ text-decoration: line-through;
501
+ text-decoration-thickness: 1px;
502
+ opacity: 0.75;
490
503
  }
491
504
 
492
505
  /* Light theme: boost inactive scope contrast further */
@@ -633,9 +646,9 @@ body.light .scope-toggle.local {
633
646
  }
634
647
 
635
648
  .tree-desc-inline {
636
- font-size: 11px;
637
- color: var(--text-muted);
638
- opacity: 0.95;
649
+ font-size: 12px;
650
+ color: var(--text-tertiary);
651
+ opacity: 1;
639
652
  white-space: nowrap;
640
653
  overflow: hidden;
641
654
  text-overflow: ellipsis;
package/server.js CHANGED
@@ -256,6 +256,7 @@ function loadMarketplaces() {
256
256
 
257
257
  const fsComps = pluginDir ? countComponents(pluginDir) : null;
258
258
  const components = {};
259
+ const inlineConfig = {};
259
260
  for (const k of compKeys) {
260
261
  if (fsComps && Array.isArray(fsComps[k]) && fsComps[k].length > 0) {
261
262
  if (Array.isArray(pd[k]) && pd[k].length > 0) {
@@ -266,10 +267,19 @@ function loadMarketplaces() {
266
267
  }
267
268
  } else if (Array.isArray(pd[k]) && pd[k].length > 0) {
268
269
  components[k] = pd[k].map(p => typeof p === 'string' ? path.basename(p) : (p.name || String(p)));
270
+ } else if (pd[k] && typeof pd[k] === 'object') {
271
+ components[k] = Object.keys(pd[k]);
272
+ inlineConfig[k] = pd[k];
269
273
  } else if (pd[k]) {
270
- components[k] = Array.isArray(pd[k]) ? [] : [String(pd[k])];
274
+ components[k] = [String(pd[k])];
271
275
  }
272
276
  }
277
+ if (fsComps?._configFiles) components._configFiles = fsComps._configFiles;
278
+ if (fsComps?._readmePath) components._readmePath = fsComps._readmePath;
279
+ for (const k of Object.keys(inlineConfig)) {
280
+ if (!components._configFiles) components._configFiles = {};
281
+ if (!components._configFiles[k]) components._configFiles[k] = `${INLINE_PREFIX}${k}`;
282
+ }
273
283
 
274
284
  const installedVersion = [scopeDetails.user, scopeDetails.project, scopeDetails.local]
275
285
  .find(d => d?.version && d.version !== 'unknown')?.version || null;
@@ -301,6 +311,8 @@ function loadMarketplaces() {
301
311
  components,
302
312
  _pluginDir: toUnixPath(pluginDir),
303
313
  _originDir: toUnixPath(originDir),
314
+ _installLocation: toUnixPath(installLocation),
315
+ _inlineConfig: Object.keys(inlineConfig).length ? inlineConfig : null,
304
316
  _fsComps: fsComps,
305
317
  metadata: Object.fromEntries(
306
318
  Object.entries(pd).filter(([k]) => !['name', 'description', 'source', 'version', ...compKeys].includes(k))
@@ -429,6 +441,7 @@ function findFiles(dir, ext) {
429
441
  }
430
442
 
431
443
  const VIRTUAL_PREFIX = '_custom/';
444
+ const INLINE_PREFIX = '__inline__/';
432
445
  const SCOPE_LABELS = { user: 'User Customizations', project: 'Project Customizations' };
433
446
  const EMPTY_SCOPE = { installed: false, enabled: false, version: null, installPath: null };
434
447
 
@@ -623,14 +636,21 @@ app.get('/api/plugins/:pluginId/components', (req, res) => {
623
636
  if (!plugin?._pluginDir) return res.status(404).json({ error: 'Plugin directory not found', pluginId });
624
637
 
625
638
  const comps = plugin.components || plugin._fsComps || countComponents(plugin._pluginDir, plugin.metadata);
626
- const result = { ...comps, _pluginDir: plugin._pluginDir };
627
- res.json(result);
639
+ res.json({ ...comps, _pluginDir: plugin._pluginDir });
628
640
  });
629
641
 
630
642
  app.get('/api/plugins/:pluginId/preview/*', (req, res) => {
631
643
  const pluginId = decodeURIComponent(req.params.pluginId);
632
644
  const relPath = req.params[0];
633
645
  const marketplaces = getCachedMarketplaces();
646
+
647
+ if (relPath.startsWith(INLINE_PREFIX)) {
648
+ const type = relPath.slice(INLINE_PREFIX.length);
649
+ const inline = findPlugin(pluginId, marketplaces)?._inlineConfig?.[type];
650
+ if (inline === undefined) return res.status(404).json({ error: 'Inline config not found' });
651
+ return res.json({ type: 'file', content: JSON.stringify({ [type]: inline }, null, 2), name: `${type}.json` });
652
+ }
653
+
634
654
  const pluginDir = resolvePluginDir(pluginId, marketplaces);
635
655
  if (!pluginDir) return res.status(404).json({ error: 'Plugin not found' });
636
656
 
@@ -677,7 +697,13 @@ app.post('/api/open-in-editor', (req, res) => {
677
697
  const pluginJson = path.join(pluginDir, '.claude-plugin', 'plugin.json');
678
698
  if (fs.existsSync(pluginJson)) args.push(pluginJson);
679
699
 
680
- if (relativePath) {
700
+ if (relativePath && relativePath.startsWith(INLINE_PREFIX)) {
701
+ const installLocation = findPlugin(pluginId, marketplaces)?._installLocation;
702
+ if (installLocation) {
703
+ const mktJson = path.join(installLocation, '.claude-plugin', 'marketplace.json');
704
+ if (fs.existsSync(mktJson)) args.push(mktJson);
705
+ }
706
+ } else if (relativePath) {
681
707
  const fullPath = path.resolve(pluginDir, resolveVirtualRelPath(pluginId, relativePath));
682
708
  if (isPathAllowed(fullPath, pluginDir, pluginId)) args.push(fullPath);
683
709
  }