@laststance/claude-plugin-dashboard 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -244,6 +244,17 @@ MIT © [Laststance.io](https://github.com/laststance)
244
244
 
245
245
  ## Changelog
246
246
 
247
+ ### v0.2.2
248
+
249
+ - Claude Code v2.1.3 compatibility (unified Skills/Commands model)
250
+
251
+ ### v0.2.1
252
+
253
+ - **Marketplace Management**: Add/remove/refresh marketplaces directly from dashboard
254
+ - **Plugin Component Types**: Display skills, agents, hooks, MCP servers in detail view
255
+ - **Bug Fix**: Search filter now works correctly in Enabled and Installed tabs
256
+ - **CI/CD**: GitHub Actions workflow, CI and Codecov badges
257
+
247
258
  ### v0.2.0
248
259
 
249
260
  - **Enabled tab**: New default view showing active plugins (installed AND enabled)
package/dist/app.js CHANGED
@@ -513,7 +513,7 @@ export default function App() {
513
513
  }
514
514
  // Handle plugin uninstall confirmation dialog
515
515
  if (state.confirmUninstall && state.operationPluginId) {
516
- if (input === 'y' || input === 'Y') {
516
+ if (input === 'y' || input === 'Y' || key.return) {
517
517
  dispatch({ type: 'HIDE_CONFIRM_UNINSTALL' });
518
518
  handleUninstall(state.operationPluginId);
519
519
  return;
@@ -527,7 +527,7 @@ export default function App() {
527
527
  }
528
528
  // Handle marketplace remove confirmation dialog
529
529
  if (state.confirmRemoveMarketplace && state.operationMarketplaceId) {
530
- if (input === 'y' || input === 'Y') {
530
+ if (input === 'y' || input === 'Y' || key.return) {
531
531
  dispatch({ type: 'HIDE_CONFIRM_REMOVE_MARKETPLACE' });
532
532
  handleRemoveMarketplace(state.operationMarketplaceId);
533
533
  return;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * ComponentBadges component
3
- * Displays plugin component type badges with icons and counts
4
- * Icons: Skills(S), Commands(/), Agents(@), Hooks(H), MCP(M), LSP(L)
3
+ * Displays plugin component type badges with readable text labels and counts
4
+ * Labels: Skills, Slash, Agents, Hooks, MCP, LSP
5
5
  */
6
6
  import type { PluginComponents } from '../types/index.js';
7
7
  /**
@@ -18,7 +18,7 @@ export interface ComponentBadgesProps {
18
18
  * @returns Badges component or null if no components
19
19
  * @example
20
20
  * <ComponentBadges components={{ skills: 5, commands: 2 }} />
21
- * // Renders: [S:5] [/:2]
21
+ * // Renders: Skills:5 Slash:2
22
22
  */
23
23
  export default function ComponentBadges({ components, }: ComponentBadgesProps): React.ReactNode;
24
24
  /**
@@ -1,20 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * ComponentBadges component
4
- * Displays plugin component type badges with icons and counts
5
- * Icons: Skills(S), Commands(/), Agents(@), Hooks(H), MCP(M), LSP(L)
4
+ * Displays plugin component type badges with readable text labels and counts
5
+ * Labels: Skills, Slash, Agents, Hooks, MCP, LSP
6
6
  */
7
7
  import { Box, Text } from 'ink';
8
8
  /**
9
- * Badge configurations with intuitive abbreviations and colors
9
+ * Badge configurations with readable text labels and colors
10
10
  */
11
11
  const BADGE_CONFIGS = [
12
- { label: 'S', color: 'magenta', key: 'skills' },
13
- { label: '/', color: 'cyan', key: 'commands' },
14
- { label: '@', color: 'blue', key: 'agents' },
15
- { label: 'H', color: 'yellow', key: 'hooks', isBoolean: true },
16
- { label: 'M', color: 'green', key: 'mcpServers' },
17
- { label: 'L', color: 'blueBright', key: 'lspServers' },
12
+ { label: 'Skills', color: 'magenta', key: 'skills' },
13
+ { label: 'Slash', color: 'cyan', key: 'commands' },
14
+ { label: 'Agents', color: 'blue', key: 'agents' },
15
+ { label: 'Hooks', color: 'yellow', key: 'hooks', isBoolean: true },
16
+ { label: 'MCP', color: 'green', key: 'mcpServers' },
17
+ { label: 'LSP', color: 'blueBright', key: 'lspServers' },
18
18
  ];
19
19
  /**
20
20
  * Displays component type badges for a plugin
@@ -23,7 +23,7 @@ const BADGE_CONFIGS = [
23
23
  * @returns Badges component or null if no components
24
24
  * @example
25
25
  * <ComponentBadges components={{ skills: 5, commands: 2 }} />
26
- * // Renders: [S:5] [/:2]
26
+ * // Renders: Skills:5 Slash:2
27
27
  */
28
28
  export default function ComponentBadges({ components, }) {
29
29
  if (!components) {
@@ -43,9 +43,10 @@ export default function ComponentBadges({ components, }) {
43
43
  }
44
44
  /**
45
45
  * Single badge component
46
+ * Renders as "Label:count" without brackets for better readability
46
47
  */
47
48
  function Badge({ label, count, color, }) {
48
- return (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "[" }), _jsx(Text, { color: color, bold: true, children: label }), count !== undefined && _jsxs(Text, { dimColor: true, children: [":", count] }), _jsx(Text, { dimColor: true, children: "]" })] }));
49
+ return (_jsxs(Text, { children: [_jsx(Text, { color: color, bold: true, children: label }), count !== undefined && _jsxs(Text, { dimColor: true, children: [":", count] })] }));
49
50
  }
50
51
  /**
51
52
  * Get a human-readable description of component types
@@ -13,7 +13,7 @@ export default function MarketplaceDetail({ marketplace, }) {
13
13
  if (!marketplace) {
14
14
  return (_jsx(Box, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "gray", children: _jsx(Text, { dimColor: true, children: "Select a marketplace to view details" }) }));
15
15
  }
16
- return (_jsxs(Box, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: marketplace.name || marketplace.id }) }), _jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsx(DetailRow, { label: "ID", value: marketplace.id }), _jsx(DetailRow, { label: "Plugins", value: `${marketplace.pluginCount || 0}` }), _jsx(DetailRow, { label: "Source", value: marketplace.source.source }), marketplace.source.url && (_jsx(DetailRow, { label: "URL", value: marketplace.source.url })), marketplace.source.repo && (_jsx(DetailRow, { label: "Repo", value: marketplace.source.repo })), _jsx(DetailRow, { label: "Last Updated", value: formatDate(marketplace.lastUpdated) })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Install Location:" }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: marketplace.installLocation })] })] }));
16
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: marketplace.name || marketplace.id }) }), _jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsx(DetailRow, { label: "ID", value: marketplace.id }), _jsx(DetailRow, { label: "Plugins", value: `${marketplace.pluginCount || 0}` }), _jsx(DetailRow, { label: "Source", value: marketplace.source.source }), marketplace.source.url && (_jsx(DetailRow, { label: "URL", value: marketplace.source.url })), marketplace.source.repo && (_jsx(DetailRow, { label: "Repo", value: marketplace.source.repo })), _jsx(DetailRow, { label: "Last Updated", value: formatDate(marketplace.lastUpdated) })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Install Location:" }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: marketplace.installLocation })] }), _jsx(Box, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsxs(Text, { dimColor: true, children: [_jsx(Text, { bold: true, color: "white", children: "a" }), ' ', "add |", ' ', _jsx(Text, { bold: true, color: "white", children: "d" }), ' ', "remove |", ' ', _jsx(Text, { bold: true, color: "white", children: "u" }), ' ', "update"] }) })] }));
17
17
  }
18
18
  /**
19
19
  * Single detail row with label and value
@@ -26,7 +26,7 @@ export function detectPluginComponents(installPath) {
26
26
  if (skillsCount > 0) {
27
27
  components.skills = skillsCount;
28
28
  }
29
- // Detect commands (count .md files in commands/ folder)
29
+ // Detect commands (legacy location, now unified with skills in Claude Code v2.1.3+)
30
30
  const commandsCount = countMarkdownFiles(installPath, 'commands');
31
31
  if (commandsCount > 0) {
32
32
  components.commands = commandsCount;
@@ -11,7 +11,7 @@
11
11
  export interface PluginComponents {
12
12
  /** Count of skill directories in skills/ */
13
13
  skills?: number;
14
- /** Count of slash command .md files in commands/ */
14
+ /** Count of command .md files in commands/ (legacy location, now unified with skills in Claude Code v2.1.3+) */
15
15
  commands?: number;
16
16
  /** Count of subagent .md files in agents/ */
17
17
  agents?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laststance/claude-plugin-dashboard",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Interactive CLI dashboard to manage Claude Code plugins",
5
5
  "license": "MIT",
6
6
  "author": "Ryota Murakami <ryota.murakami@laststance.io> (https://github.com/ryota-murakami)",