@laststance/claude-plugin-dashboard 0.2.3 → 0.3.2

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 (58) hide show
  1. package/README.md +7 -1
  2. package/dist/app.d.ts +7 -1
  3. package/dist/app.js +544 -262
  4. package/dist/cli.js +60 -67
  5. package/dist/components/ComponentBadges.d.ts +0 -9
  6. package/dist/components/ComponentBadges.js +0 -33
  7. package/dist/components/ComponentDetail.d.ts +32 -0
  8. package/dist/components/ComponentDetail.js +106 -0
  9. package/dist/components/ComponentList.d.ts +87 -0
  10. package/dist/components/ComponentList.js +287 -0
  11. package/dist/components/HelpOverlay.js +1 -0
  12. package/dist/components/KeyHints.d.ts +1 -0
  13. package/dist/components/KeyHints.js +33 -29
  14. package/dist/components/MarketplaceActionMenu.d.ts +41 -0
  15. package/dist/components/MarketplaceActionMenu.js +68 -0
  16. package/dist/components/MarketplaceDetail.d.ts +10 -3
  17. package/dist/components/MarketplaceDetail.js +10 -4
  18. package/dist/components/PluginDetail.d.ts +19 -3
  19. package/dist/components/PluginDetail.js +56 -6
  20. package/dist/components/PluginList.js +19 -7
  21. package/dist/services/componentService.d.ts +10 -31
  22. package/dist/services/componentService.js +19 -174
  23. package/dist/services/components/hookService.d.ts +17 -0
  24. package/dist/services/components/hookService.js +45 -0
  25. package/dist/services/components/index.d.ts +41 -0
  26. package/dist/services/components/index.js +126 -0
  27. package/dist/services/components/markdownService.d.ts +39 -0
  28. package/dist/services/components/markdownService.js +147 -0
  29. package/dist/services/components/serverService.d.ts +28 -0
  30. package/dist/services/components/serverService.js +69 -0
  31. package/dist/services/components/skillService.d.ts +48 -0
  32. package/dist/services/components/skillService.js +164 -0
  33. package/dist/services/components/utils.d.ts +23 -0
  34. package/dist/services/components/utils.js +42 -0
  35. package/dist/services/marketplaceActionsService.d.ts +17 -0
  36. package/dist/services/marketplaceActionsService.js +18 -0
  37. package/dist/services/pluginActionsService.d.ts +31 -2
  38. package/dist/services/pluginActionsService.js +65 -6
  39. package/dist/services/pluginService.js +78 -2
  40. package/dist/store/index.d.ts +46 -0
  41. package/dist/store/index.js +47 -0
  42. package/dist/store/slices/marketplaceSlice.d.ts +344 -0
  43. package/dist/store/slices/marketplaceSlice.js +152 -0
  44. package/dist/store/slices/pluginSlice.d.ts +1544 -0
  45. package/dist/store/slices/pluginSlice.js +191 -0
  46. package/dist/store/slices/uiSlice.d.ts +147 -0
  47. package/dist/store/slices/uiSlice.js +126 -0
  48. package/dist/tabs/DiscoverTab.d.ts +8 -2
  49. package/dist/tabs/DiscoverTab.js +2 -2
  50. package/dist/tabs/EnabledTab.d.ts +8 -2
  51. package/dist/tabs/EnabledTab.js +3 -3
  52. package/dist/tabs/ErrorsTab.js +1 -1
  53. package/dist/tabs/InstalledTab.d.ts +8 -2
  54. package/dist/tabs/InstalledTab.js +3 -3
  55. package/dist/tabs/MarketplacesTab.d.ts +15 -2
  56. package/dist/tabs/MarketplacesTab.js +13 -4
  57. package/dist/types/index.d.ts +157 -5
  58. package/package.json +10 -3
@@ -13,18 +13,27 @@ import SearchInput from '../components/SearchInput.js';
13
13
  * @param selectedIndex - Currently selected item index
14
14
  * @param searchQuery - Current search query string
15
15
  * @param focusZone - Current focus zone for keyboard navigation
16
+ * @param showActionMenu - Whether to show the action menu
17
+ * @param actionMenuSelectedIndex - Selected index in action menu
16
18
  * @example
17
- * <MarketplacesTab marketplaces={marketplaces} selectedIndex={0} searchQuery="" focusZone="list" />
19
+ * <MarketplacesTab
20
+ * marketplaces={marketplaces}
21
+ * selectedIndex={0}
22
+ * searchQuery=""
23
+ * focusZone="list"
24
+ * showActionMenu={false}
25
+ * actionMenuSelectedIndex={0}
26
+ * />
18
27
  */
19
- export default function MarketplacesTab({ marketplaces, selectedIndex, searchQuery = '', focusZone = 'list', }) {
28
+ export default function MarketplacesTab({ marketplaces, selectedIndex, searchQuery = '', focusZone = 'list', showActionMenu = false, actionMenuSelectedIndex = 0, }) {
20
29
  const selectedMarketplace = marketplaces[selectedIndex] ?? null;
21
30
  // Count total plugins across all marketplaces
22
31
  const totalPlugins = marketplaces.reduce((sum, m) => sum + (m.pluginCount || 0), 0);
23
32
  return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { marginBottom: 1, gap: 2, children: [_jsxs(Text, { bold: true, children: ["Marketplaces (", marketplaces.length > 0
24
33
  ? `${selectedIndex + 1}/${marketplaces.length}`
25
- : '0', ")"] }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: "gray", children: [totalPlugins, " total plugins"] })] }), _jsx(Box, { marginBottom: 1, children: _jsx(SearchInput, { query: searchQuery, isActive: focusZone === 'search', placeholder: "Type to search marketplaces..." }) }), _jsxs(Box, { flexGrow: 1, children: [_jsx(Box, { width: "50%", flexDirection: "column", children: marketplaces.length === 0 ? (_jsxs(Box, { padding: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: searchQuery
34
+ : '0', ")"] }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: "gray", children: [totalPlugins, " total plugins"] })] }), _jsx(Box, { marginBottom: 1, children: _jsx(SearchInput, { query: searchQuery, isActive: focusZone === 'search', placeholder: "Type to search marketplaces..." }) }), _jsxs(Box, { flexGrow: 1, overflow: "hidden", children: [_jsx(Box, { width: "50%", flexDirection: "column", overflow: "hidden", children: marketplaces.length === 0 ? (_jsxs(Box, { padding: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: searchQuery
26
35
  ? 'No matching marketplaces'
27
36
  : 'No marketplaces found' }), _jsx(Text, { dimColor: true, children: searchQuery
28
37
  ? 'Try a different search term'
29
- : 'Add marketplaces with /plugin add-marketplace' })] })) : (_jsx(MarketplaceList, { marketplaces: marketplaces, selectedIndex: selectedIndex, isFocused: focusZone === 'list' })) }), _jsx(Box, { width: "50%", flexDirection: "column", children: _jsx(MarketplaceDetail, { marketplace: selectedMarketplace }) })] })] }));
38
+ : 'Add marketplaces with /plugin add-marketplace' })] })) : (_jsx(MarketplaceList, { marketplaces: marketplaces, selectedIndex: selectedIndex, isFocused: focusZone === 'list' })) }), _jsx(Box, { width: "50%", flexDirection: "column", overflow: "hidden", children: _jsx(MarketplaceDetail, { marketplace: selectedMarketplace, showActionMenu: showActionMenu, actionMenuSelectedIndex: actionMenuSelectedIndex }) })] })] }));
30
39
  }
@@ -3,7 +3,114 @@
3
3
  * These types aggregate data from multiple Claude Code configuration files
4
4
  */
5
5
  /**
6
- * Component types provided by a plugin
6
+ * Component type identifier
7
+ */
8
+ export type ComponentType = 'skill' | 'command' | 'agent' | 'hook' | 'mcp' | 'lsp';
9
+ /**
10
+ * Individual component information with name and optional description
11
+ *
12
+ * Data Source Architecture:
13
+ * ```
14
+ * ┌─────────────────────────────────────────────────────────────┐
15
+ * │ Plugin Installed? │
16
+ * │ │ │
17
+ * │ ┌──── YES ─────┴───── NO ────┐ │
18
+ * │ │ │ │
19
+ * │ ▼ ▼ │
20
+ * │ ┌─────────────────────┐ ┌─────────────────────┐ │
21
+ * │ │ File System Scan │ │ Marketplace JSON │ │
22
+ * │ │ ───────────────── │ │ ───────────────── │ │
23
+ * │ │ skills/{name}/ │ │ skills: [ │ │
24
+ * │ │ commands/{name}.md │ │ "./skills/xlsx" │ │
25
+ * │ │ agents/{name}.md │ │ ] │ │
26
+ * │ │ plugin.json keys │ │ │ │
27
+ * │ └─────────────────────┘ └─────────────────────┘ │
28
+ * │ │ │ │
29
+ * │ ▼ ▼ │
30
+ * │ Names + Descriptions Names only (if available) │
31
+ * │ │
32
+ * │ └────────────────────────────┘ │
33
+ * │ │ │
34
+ * │ ▼ │
35
+ * │ PluginComponentsDetailed │
36
+ * │ ───────────────────────── │
37
+ * │ { │
38
+ * │ skills: [ │
39
+ * │ { name: "xlsx", description: "..." }, │
40
+ * │ { name: "docx" } │
41
+ * │ ], │
42
+ * │ mcpServers: ["supabase", "context7"] │
43
+ * │ } │
44
+ * └─────────────────────────────────────────────────────────────┘
45
+ * ```
46
+ *
47
+ * @example
48
+ * // Skill with description (from SKILL.md frontmatter)
49
+ * { name: "xlsx", description: "Spreadsheet editing", type: "skill" }
50
+ *
51
+ * @example
52
+ * // Command without description
53
+ * { name: "code-review", type: "command" }
54
+ */
55
+ export interface ComponentInfo {
56
+ /** Component name (e.g., "xlsx", "code-review") */
57
+ name: string;
58
+ /** Optional description from SKILL.md frontmatter or first line of .md file */
59
+ description?: string;
60
+ /** Component type for display categorization */
61
+ type: ComponentType;
62
+ }
63
+ /**
64
+ * Extended component information with full SKILL.md parsing
65
+ * Used for Component detail view in PluginDetail panel
66
+ *
67
+ * @example
68
+ * {
69
+ * name: "sentry-code-review",
70
+ * description: "Analyze and resolve Sentry comments...",
71
+ * type: "skill",
72
+ * allowedTools: ["Read", "Edit", "Write", "Bash", "Grep"],
73
+ * fullDescription: "Full markdown body content...",
74
+ * filePath: "/Users/.../skills/sentry-code-review/SKILL.md"
75
+ * }
76
+ */
77
+ export interface ComponentDetailedInfo extends ComponentInfo {
78
+ /** Allowed tools from SKILL.md frontmatter (allowed-tools field) */
79
+ allowedTools?: string[];
80
+ /** Full markdown body content (after frontmatter) */
81
+ fullDescription?: string;
82
+ /** Absolute file path for reference */
83
+ filePath?: string;
84
+ }
85
+ /**
86
+ * Detailed component information for a plugin
87
+ * Extends PluginComponents (counts) with actual component names and descriptions
88
+ *
89
+ * @example
90
+ * {
91
+ * skills: [
92
+ * { name: "xlsx", description: "Spreadsheet editing", type: "skill" },
93
+ * { name: "docx", type: "skill" }
94
+ * ],
95
+ * mcpServers: ["supabase", "context7"]
96
+ * }
97
+ */
98
+ export interface PluginComponentsDetailed {
99
+ /** Skill details (name + optional description) */
100
+ skills?: ComponentInfo[];
101
+ /** Command details */
102
+ commands?: ComponentInfo[];
103
+ /** Agent details */
104
+ agents?: ComponentInfo[];
105
+ /** Hook event names */
106
+ hooks?: string[];
107
+ /** MCP server names from plugin.json mcpServers keys */
108
+ mcpServers?: string[];
109
+ /** LSP server language IDs from .lsp.json keys */
110
+ lspServers?: string[];
111
+ }
112
+ /**
113
+ * Component types provided by a plugin (counts only)
7
114
  * Detected by scanning plugin directory structure and plugin.json
8
115
  * @example
9
116
  * { skills: 5, commands: 2, mcpServers: 1 } // Plugin with skills, commands, and MCP
@@ -64,6 +171,8 @@ export interface Plugin {
64
171
  gitCommitSha?: string;
65
172
  /** Component types provided by this plugin (skills, commands, MCP, etc.) */
66
173
  components?: PluginComponents;
174
+ /** Detailed component info with names and descriptions */
175
+ componentsDetailed?: PluginComponentsDetailed;
67
176
  }
68
177
  /**
69
178
  * Raw installed plugin data from installed_plugins.json
@@ -98,6 +207,7 @@ export interface Marketplace {
98
207
  installLocation: string;
99
208
  lastUpdated: string;
100
209
  pluginCount?: number;
210
+ autoUpdate?: boolean;
101
211
  }
102
212
  /**
103
213
  * Structure of known_marketplaces.json file
@@ -111,6 +221,7 @@ export interface KnownMarketplacesFile {
111
221
  };
112
222
  installLocation: string;
113
223
  lastUpdated: string;
224
+ autoUpdate?: boolean;
114
225
  };
115
226
  }
116
227
  /**
@@ -128,6 +239,12 @@ export interface MarketplacePluginEntry {
128
239
  homepage?: string;
129
240
  tags?: string[];
130
241
  keywords?: string[];
242
+ /** Skill paths from marketplace.json (e.g., ["./skills/xlsx"]) */
243
+ skills?: string[];
244
+ /** Agent paths from marketplace.json */
245
+ agents?: string[];
246
+ /** Command paths from marketplace.json */
247
+ commands?: string[];
131
248
  }
132
249
  /**
133
250
  * Structure of marketplace.json file
@@ -178,7 +295,7 @@ export interface Settings {
178
295
  * Focus zones for keyboard navigation
179
296
  * Defines which UI area currently has keyboard focus
180
297
  */
181
- export type FocusZone = 'tabbar' | 'search' | 'list';
298
+ export type FocusZone = 'tabbar' | 'search' | 'list' | 'components';
182
299
  /**
183
300
  * Marketplace operation types
184
301
  */
@@ -211,12 +328,20 @@ export interface AppState {
211
328
  error: string | null;
212
329
  /** Status message */
213
330
  message: string | null;
214
- /** Current async operation (install/uninstall) */
215
- operation: 'idle' | 'installing' | 'uninstalling';
331
+ /** Current async operation (install/uninstall/update) */
332
+ operation: 'idle' | 'installing' | 'uninstalling' | 'updating';
216
333
  /** Plugin ID being operated on */
217
334
  operationPluginId: string | null;
218
335
  /** Whether confirmation dialog is showing */
219
336
  confirmUninstall: boolean;
337
+ /** Whether update all confirmation dialog is showing */
338
+ confirmUpdateAll: boolean;
339
+ /** Progress of bulk update operation */
340
+ updateProgress: {
341
+ current: number;
342
+ total: number;
343
+ pluginId: string;
344
+ } | null;
220
345
  /** Whether help overlay is showing */
221
346
  showHelp: boolean;
222
347
  /** Current marketplace operation */
@@ -229,6 +354,12 @@ export interface AppState {
229
354
  showAddMarketplaceDialog: boolean;
230
355
  /** Error message for add marketplace dialog */
231
356
  addMarketplaceError: string | null;
357
+ /** Whether marketplace action menu is showing */
358
+ showMarketplaceActionMenu: boolean;
359
+ /** Selected index in marketplace action menu */
360
+ actionMenuSelectedIndex: number;
361
+ /** Selected component index within the current plugin */
362
+ selectedComponentIndex: number;
232
363
  }
233
364
  /**
234
365
  * Action types for useReducer
@@ -282,7 +413,7 @@ export type Action = {
282
413
  } | {
283
414
  type: 'START_OPERATION';
284
415
  payload: {
285
- operation: 'installing' | 'uninstalling';
416
+ operation: 'installing' | 'uninstalling' | 'updating';
286
417
  pluginId: string;
287
418
  };
288
419
  } | {
@@ -317,4 +448,25 @@ export type Action = {
317
448
  } | {
318
449
  type: 'SET_ADD_MARKETPLACE_ERROR';
319
450
  payload: string | null;
451
+ } | {
452
+ type: 'SHOW_MARKETPLACE_ACTION_MENU';
453
+ } | {
454
+ type: 'HIDE_MARKETPLACE_ACTION_MENU';
455
+ } | {
456
+ type: 'SET_ACTION_MENU_INDEX';
457
+ payload: number;
458
+ } | {
459
+ type: 'MOVE_ACTION_MENU_SELECTION';
460
+ payload: 'up' | 'down';
461
+ } | {
462
+ type: 'SET_COMPONENT_INDEX';
463
+ payload: number;
464
+ } | {
465
+ type: 'MOVE_COMPONENT_SELECTION';
466
+ payload: 'up' | 'down';
467
+ maxIndex: number;
468
+ } | {
469
+ type: 'ENTER_COMPONENT_MODE';
470
+ } | {
471
+ type: 'EXIT_COMPONENT_MODE';
320
472
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laststance/claude-plugin-dashboard",
3
- "version": "0.2.3",
3
+ "version": "0.3.2",
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)",
@@ -47,13 +47,19 @@
47
47
  "prettier": "prettier --ignore-unknown --write .",
48
48
  "test": "vitest",
49
49
  "test:run": "vitest run",
50
- "test:coverage": "vitest run --coverage"
50
+ "test:coverage": "vitest run --coverage",
51
+ "push-release-commit": "push-release-commit"
51
52
  },
52
53
  "dependencies": {
54
+ "@reduxjs/toolkit": "^2.11.2",
55
+ "fullscreen-ink": "^0.1.0",
53
56
  "ink": "^5.1.0",
54
- "react": "^18.3.1"
57
+ "react": "^18.3.1",
58
+ "react-redux": "^9.2.0",
59
+ "ts-pattern": "^5.9.0"
55
60
  },
56
61
  "devDependencies": {
62
+ "@laststance/npm-publish-tool": "^2.1.0",
57
63
  "@sindresorhus/tsconfig": "^6.0.0",
58
64
  "@types/node": "^22.10.2",
59
65
  "@types/react": "^18.3.18",
@@ -62,6 +68,7 @@
62
68
  "ink-testing-library": "^4.0.0",
63
69
  "lint-staged": "^16.2.7",
64
70
  "prettier": "^3.7.4",
71
+ "release-it": "^19.2.4",
65
72
  "typescript": "^5.7.2",
66
73
  "vitest": "^4.0.16"
67
74
  }