claudeup 1.8.0 → 3.3.0
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/bin/claudeup.js +20 -2
- package/package.json +10 -19
- package/src/data/cli-tools.js +123 -0
- package/src/data/cli-tools.ts +140 -0
- package/{dist → src}/data/marketplaces.js +23 -24
- package/src/data/marketplaces.ts +95 -0
- package/src/data/mcp-servers.js +509 -0
- package/src/data/mcp-servers.ts +526 -0
- package/src/data/statuslines.js +159 -0
- package/src/data/statuslines.ts +188 -0
- package/src/index.js +4 -0
- package/src/index.ts +5 -0
- package/{dist → src}/main.js +46 -47
- package/src/main.tsx +145 -0
- package/src/opentui.d.ts +191 -0
- package/{dist → src}/prerunner/index.js +31 -41
- package/src/prerunner/index.ts +124 -0
- package/{dist → src}/services/claude-runner.js +9 -10
- package/src/services/claude-runner.ts +31 -0
- package/{dist → src}/services/claude-settings.js +72 -33
- package/src/services/claude-settings.ts +934 -0
- package/src/services/local-marketplace.js +339 -0
- package/src/services/local-marketplace.ts +489 -0
- package/{dist → src}/services/mcp-registry.js +13 -14
- package/src/services/mcp-registry.ts +105 -0
- package/{dist → src}/services/plugin-manager.js +61 -13
- package/src/services/plugin-manager.ts +693 -0
- package/{dist → src}/services/plugin-mcp-config.js +19 -18
- package/src/services/plugin-mcp-config.ts +242 -0
- package/{dist → src}/services/update-cache.js +0 -1
- package/src/services/update-cache.ts +78 -0
- package/{dist → src}/services/version-check.js +15 -14
- package/src/services/version-check.ts +122 -0
- package/src/types/index.js +1 -0
- package/src/types/index.ts +141 -0
- package/src/ui/App.js +213 -0
- package/src/ui/App.tsx +359 -0
- package/src/ui/components/CategoryHeader.js +9 -0
- package/src/ui/components/CategoryHeader.tsx +41 -0
- package/{dist → src}/ui/components/ScrollableList.js +19 -6
- package/src/ui/components/ScrollableList.tsx +98 -0
- package/src/ui/components/SearchInput.js +19 -0
- package/src/ui/components/SearchInput.tsx +56 -0
- package/src/ui/components/StyledText.js +39 -0
- package/src/ui/components/StyledText.tsx +70 -0
- package/src/ui/components/TabBar.js +38 -0
- package/src/ui/components/TabBar.tsx +88 -0
- package/src/ui/components/layout/Panel.js +6 -0
- package/src/ui/components/layout/Panel.tsx +62 -0
- package/src/ui/components/layout/ProgressBar.js +14 -0
- package/src/ui/components/layout/ProgressBar.tsx +47 -0
- package/src/ui/components/layout/ScopeTabs.js +6 -0
- package/src/ui/components/layout/ScopeTabs.tsx +53 -0
- package/src/ui/components/layout/ScreenLayout.js +21 -0
- package/src/ui/components/layout/ScreenLayout.tsx +147 -0
- package/src/ui/components/layout/index.js +4 -0
- package/src/ui/components/layout/index.ts +4 -0
- package/src/ui/components/modals/ConfirmModal.js +14 -0
- package/src/ui/components/modals/ConfirmModal.tsx +59 -0
- package/src/ui/components/modals/InputModal.js +16 -0
- package/src/ui/components/modals/InputModal.tsx +68 -0
- package/src/ui/components/modals/LoadingModal.js +14 -0
- package/src/ui/components/modals/LoadingModal.tsx +40 -0
- package/src/ui/components/modals/MessageModal.js +16 -0
- package/src/ui/components/modals/MessageModal.tsx +64 -0
- package/src/ui/components/modals/ModalContainer.js +56 -0
- package/src/ui/components/modals/ModalContainer.tsx +104 -0
- package/src/ui/components/modals/SelectModal.js +26 -0
- package/src/ui/components/modals/SelectModal.tsx +82 -0
- package/src/ui/components/modals/index.js +6 -0
- package/src/ui/components/modals/index.ts +6 -0
- package/src/ui/hooks/index.js +3 -0
- package/src/ui/hooks/index.ts +3 -0
- package/{dist → src}/ui/hooks/useAsyncData.js +21 -22
- package/src/ui/hooks/useAsyncData.ts +127 -0
- package/src/ui/hooks/useKeyboard.js +13 -0
- package/src/ui/hooks/useKeyboard.ts +26 -0
- package/src/ui/hooks/useKeyboardHandler.js +39 -0
- package/src/ui/hooks/useKeyboardHandler.ts +63 -0
- package/{dist → src}/ui/screens/CliToolsScreen.js +60 -54
- package/src/ui/screens/CliToolsScreen.tsx +468 -0
- package/src/ui/screens/EnvVarsScreen.js +154 -0
- package/src/ui/screens/EnvVarsScreen.tsx +269 -0
- package/{dist → src}/ui/screens/McpRegistryScreen.js +56 -55
- package/src/ui/screens/McpRegistryScreen.tsx +331 -0
- package/{dist → src}/ui/screens/McpScreen.js +46 -47
- package/src/ui/screens/McpScreen.tsx +392 -0
- package/src/ui/screens/ModelSelectorScreen.js +292 -0
- package/src/ui/screens/ModelSelectorScreen.tsx +441 -0
- package/{dist → src}/ui/screens/PluginsScreen.js +305 -293
- package/src/ui/screens/PluginsScreen.tsx +1231 -0
- package/src/ui/screens/StatusLineScreen.js +200 -0
- package/src/ui/screens/StatusLineScreen.tsx +411 -0
- package/src/ui/screens/index.js +7 -0
- package/src/ui/screens/index.ts +7 -0
- package/src/ui/state/AnimationContext.js +34 -0
- package/src/ui/state/AnimationContext.tsx +76 -0
- package/{dist → src}/ui/state/AppContext.js +31 -32
- package/src/ui/state/AppContext.tsx +235 -0
- package/{dist → src}/ui/state/DimensionsContext.js +16 -17
- package/src/ui/state/DimensionsContext.tsx +144 -0
- package/{dist → src}/ui/state/reducer.js +89 -90
- package/src/ui/state/reducer.ts +467 -0
- package/src/ui/state/types.js +1 -0
- package/src/ui/state/types.ts +273 -0
- package/{dist → src}/utils/command-utils.js +3 -4
- package/src/utils/command-utils.ts +20 -0
- package/{dist → src}/utils/fuzzy-search.js +2 -3
- package/src/utils/fuzzy-search.ts +138 -0
- package/{dist → src}/utils/string-utils.js +6 -6
- package/src/utils/string-utils.ts +88 -0
- package/dist/data/cli-tools.d.ts +0 -13
- package/dist/data/cli-tools.d.ts.map +0 -1
- package/dist/data/cli-tools.js +0 -124
- package/dist/data/cli-tools.js.map +0 -1
- package/dist/data/marketplaces.d.ts +0 -6
- package/dist/data/marketplaces.d.ts.map +0 -1
- package/dist/data/marketplaces.js.map +0 -1
- package/dist/data/mcp-servers.d.ts +0 -8
- package/dist/data/mcp-servers.d.ts.map +0 -1
- package/dist/data/mcp-servers.js +0 -503
- package/dist/data/mcp-servers.js.map +0 -1
- package/dist/data/statuslines.d.ts +0 -10
- package/dist/data/statuslines.d.ts.map +0 -1
- package/dist/data/statuslines.js +0 -160
- package/dist/data/statuslines.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -90
- package/dist/index.js.map +0 -1
- package/dist/main.d.ts +0 -3
- package/dist/main.d.ts.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/prerunner/index.d.ts +0 -7
- package/dist/prerunner/index.d.ts.map +0 -1
- package/dist/prerunner/index.js.map +0 -1
- package/dist/services/claude-runner.d.ts +0 -7
- package/dist/services/claude-runner.d.ts.map +0 -1
- package/dist/services/claude-runner.js.map +0 -1
- package/dist/services/claude-settings.d.ts +0 -73
- package/dist/services/claude-settings.d.ts.map +0 -1
- package/dist/services/claude-settings.js.map +0 -1
- package/dist/services/local-marketplace.d.ts +0 -111
- package/dist/services/local-marketplace.d.ts.map +0 -1
- package/dist/services/local-marketplace.js +0 -599
- package/dist/services/local-marketplace.js.map +0 -1
- package/dist/services/mcp-registry.d.ts +0 -10
- package/dist/services/mcp-registry.d.ts.map +0 -1
- package/dist/services/mcp-registry.js.map +0 -1
- package/dist/services/plugin-manager.d.ts +0 -65
- package/dist/services/plugin-manager.d.ts.map +0 -1
- package/dist/services/plugin-manager.js.map +0 -1
- package/dist/services/plugin-mcp-config.d.ts +0 -52
- package/dist/services/plugin-mcp-config.d.ts.map +0 -1
- package/dist/services/plugin-mcp-config.js.map +0 -1
- package/dist/services/update-cache.d.ts +0 -21
- package/dist/services/update-cache.d.ts.map +0 -1
- package/dist/services/update-cache.js.map +0 -1
- package/dist/services/version-check.d.ts +0 -20
- package/dist/services/version-check.d.ts.map +0 -1
- package/dist/services/version-check.js.map +0 -1
- package/dist/types/index.d.ts +0 -105
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -2
- package/dist/types/index.js.map +0 -1
- package/dist/ui/InkApp.d.ts +0 -5
- package/dist/ui/InkApp.d.ts.map +0 -1
- package/dist/ui/InkApp.js +0 -188
- package/dist/ui/InkApp.js.map +0 -1
- package/dist/ui/components/CategoryHeader.d.ts +0 -16
- package/dist/ui/components/CategoryHeader.d.ts.map +0 -1
- package/dist/ui/components/CategoryHeader.js +0 -11
- package/dist/ui/components/CategoryHeader.js.map +0 -1
- package/dist/ui/components/ScrollableList.d.ts +0 -16
- package/dist/ui/components/ScrollableList.d.ts.map +0 -1
- package/dist/ui/components/ScrollableList.js.map +0 -1
- package/dist/ui/components/SearchInput.d.ts +0 -18
- package/dist/ui/components/SearchInput.d.ts.map +0 -1
- package/dist/ui/components/SearchInput.js +0 -30
- package/dist/ui/components/SearchInput.js.map +0 -1
- package/dist/ui/components/TabBar.d.ts +0 -8
- package/dist/ui/components/TabBar.d.ts.map +0 -1
- package/dist/ui/components/TabBar.js +0 -18
- package/dist/ui/components/TabBar.js.map +0 -1
- package/dist/ui/components/layout/Footer.d.ts +0 -14
- package/dist/ui/components/layout/Footer.d.ts.map +0 -1
- package/dist/ui/components/layout/Footer.js +0 -23
- package/dist/ui/components/layout/Footer.js.map +0 -1
- package/dist/ui/components/layout/Header.d.ts +0 -4
- package/dist/ui/components/layout/Header.d.ts.map +0 -1
- package/dist/ui/components/layout/Header.js +0 -25
- package/dist/ui/components/layout/Header.js.map +0 -1
- package/dist/ui/components/layout/Panel.d.ts +0 -22
- package/dist/ui/components/layout/Panel.d.ts.map +0 -1
- package/dist/ui/components/layout/Panel.js +0 -8
- package/dist/ui/components/layout/Panel.js.map +0 -1
- package/dist/ui/components/layout/ProgressBar.d.ts +0 -12
- package/dist/ui/components/layout/ProgressBar.d.ts.map +0 -1
- package/dist/ui/components/layout/ProgressBar.js +0 -16
- package/dist/ui/components/layout/ProgressBar.js.map +0 -1
- package/dist/ui/components/layout/ScopeTabs.d.ts +0 -12
- package/dist/ui/components/layout/ScopeTabs.d.ts.map +0 -1
- package/dist/ui/components/layout/ScopeTabs.js +0 -8
- package/dist/ui/components/layout/ScopeTabs.js.map +0 -1
- package/dist/ui/components/layout/ScreenLayout.d.ts +0 -30
- package/dist/ui/components/layout/ScreenLayout.d.ts.map +0 -1
- package/dist/ui/components/layout/ScreenLayout.js +0 -23
- package/dist/ui/components/layout/ScreenLayout.js.map +0 -1
- package/dist/ui/components/layout/index.d.ts +0 -7
- package/dist/ui/components/layout/index.d.ts.map +0 -1
- package/dist/ui/components/layout/index.js +0 -7
- package/dist/ui/components/layout/index.js.map +0 -1
- package/dist/ui/components/modals/ConfirmModal.d.ts +0 -14
- package/dist/ui/components/modals/ConfirmModal.d.ts.map +0 -1
- package/dist/ui/components/modals/ConfirmModal.js +0 -15
- package/dist/ui/components/modals/ConfirmModal.js.map +0 -1
- package/dist/ui/components/modals/InputModal.d.ts +0 -16
- package/dist/ui/components/modals/InputModal.d.ts.map +0 -1
- package/dist/ui/components/modals/InputModal.js +0 -23
- package/dist/ui/components/modals/InputModal.js.map +0 -1
- package/dist/ui/components/modals/LoadingModal.d.ts +0 -8
- package/dist/ui/components/modals/LoadingModal.d.ts.map +0 -1
- package/dist/ui/components/modals/LoadingModal.js +0 -8
- package/dist/ui/components/modals/LoadingModal.js.map +0 -1
- package/dist/ui/components/modals/MessageModal.d.ts +0 -14
- package/dist/ui/components/modals/MessageModal.d.ts.map +0 -1
- package/dist/ui/components/modals/MessageModal.js +0 -17
- package/dist/ui/components/modals/MessageModal.js.map +0 -1
- package/dist/ui/components/modals/ModalContainer.d.ts +0 -7
- package/dist/ui/components/modals/ModalContainer.d.ts.map +0 -1
- package/dist/ui/components/modals/ModalContainer.js +0 -38
- package/dist/ui/components/modals/ModalContainer.js.map +0 -1
- package/dist/ui/components/modals/SelectModal.d.ts +0 -17
- package/dist/ui/components/modals/SelectModal.d.ts.map +0 -1
- package/dist/ui/components/modals/SelectModal.js +0 -33
- package/dist/ui/components/modals/SelectModal.js.map +0 -1
- package/dist/ui/components/modals/index.d.ts +0 -7
- package/dist/ui/components/modals/index.d.ts.map +0 -1
- package/dist/ui/components/modals/index.js +0 -7
- package/dist/ui/components/modals/index.js.map +0 -1
- package/dist/ui/hooks/index.d.ts +0 -3
- package/dist/ui/hooks/index.d.ts.map +0 -1
- package/dist/ui/hooks/index.js +0 -3
- package/dist/ui/hooks/index.js.map +0 -1
- package/dist/ui/hooks/useAsyncData.d.ts +0 -40
- package/dist/ui/hooks/useAsyncData.d.ts.map +0 -1
- package/dist/ui/hooks/useAsyncData.js.map +0 -1
- package/dist/ui/hooks/useKeyboardNavigation.d.ts +0 -27
- package/dist/ui/hooks/useKeyboardNavigation.d.ts.map +0 -1
- package/dist/ui/hooks/useKeyboardNavigation.js +0 -82
- package/dist/ui/hooks/useKeyboardNavigation.js.map +0 -1
- package/dist/ui/screens/CliToolsScreen.d.ts +0 -4
- package/dist/ui/screens/CliToolsScreen.d.ts.map +0 -1
- package/dist/ui/screens/CliToolsScreen.js.map +0 -1
- package/dist/ui/screens/EnvVarsScreen.d.ts +0 -4
- package/dist/ui/screens/EnvVarsScreen.d.ts.map +0 -1
- package/dist/ui/screens/EnvVarsScreen.js +0 -145
- package/dist/ui/screens/EnvVarsScreen.js.map +0 -1
- package/dist/ui/screens/McpRegistryScreen.d.ts +0 -4
- package/dist/ui/screens/McpRegistryScreen.d.ts.map +0 -1
- package/dist/ui/screens/McpRegistryScreen.js.map +0 -1
- package/dist/ui/screens/McpScreen.d.ts +0 -4
- package/dist/ui/screens/McpScreen.d.ts.map +0 -1
- package/dist/ui/screens/McpScreen.js.map +0 -1
- package/dist/ui/screens/ModelSelectorScreen.d.ts +0 -4
- package/dist/ui/screens/ModelSelectorScreen.d.ts.map +0 -1
- package/dist/ui/screens/ModelSelectorScreen.js +0 -143
- package/dist/ui/screens/ModelSelectorScreen.js.map +0 -1
- package/dist/ui/screens/PluginsScreen.d.ts +0 -4
- package/dist/ui/screens/PluginsScreen.d.ts.map +0 -1
- package/dist/ui/screens/PluginsScreen.js.map +0 -1
- package/dist/ui/screens/StatusLineScreen.d.ts +0 -4
- package/dist/ui/screens/StatusLineScreen.d.ts.map +0 -1
- package/dist/ui/screens/StatusLineScreen.js +0 -197
- package/dist/ui/screens/StatusLineScreen.js.map +0 -1
- package/dist/ui/screens/index.d.ts +0 -8
- package/dist/ui/screens/index.d.ts.map +0 -1
- package/dist/ui/screens/index.js +0 -8
- package/dist/ui/screens/index.js.map +0 -1
- package/dist/ui/state/AppContext.d.ts +0 -40
- package/dist/ui/state/AppContext.d.ts.map +0 -1
- package/dist/ui/state/AppContext.js.map +0 -1
- package/dist/ui/state/DimensionsContext.d.ts +0 -27
- package/dist/ui/state/DimensionsContext.d.ts.map +0 -1
- package/dist/ui/state/DimensionsContext.js.map +0 -1
- package/dist/ui/state/reducer.d.ts +0 -4
- package/dist/ui/state/reducer.d.ts.map +0 -1
- package/dist/ui/state/reducer.js.map +0 -1
- package/dist/ui/state/types.d.ts +0 -266
- package/dist/ui/state/types.d.ts.map +0 -1
- package/dist/ui/state/types.js +0 -2
- package/dist/ui/state/types.js.map +0 -1
- package/dist/utils/command-utils.d.ts +0 -8
- package/dist/utils/command-utils.d.ts.map +0 -1
- package/dist/utils/command-utils.js.map +0 -1
- package/dist/utils/fuzzy-search.d.ts +0 -33
- package/dist/utils/fuzzy-search.d.ts.map +0 -1
- package/dist/utils/fuzzy-search.js.map +0 -1
- package/dist/utils/string-utils.d.ts +0 -24
- package/dist/utils/string-utils.d.ts.map +0 -1
- package/dist/utils/string-utils.js.map +0 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Marketplace,
|
|
3
|
+
McpServer,
|
|
4
|
+
StatusLineConfig,
|
|
5
|
+
} from "../../types/index.js";
|
|
6
|
+
import type { PluginInfo } from "../../services/plugin-manager.js";
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Route Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export type Screen =
|
|
13
|
+
| "plugins"
|
|
14
|
+
| "mcp"
|
|
15
|
+
| "mcp-registry"
|
|
16
|
+
| "statusline"
|
|
17
|
+
| "env-vars"
|
|
18
|
+
| "cli-tools"
|
|
19
|
+
| "model-selector";
|
|
20
|
+
|
|
21
|
+
export type Route =
|
|
22
|
+
| { screen: "plugins" }
|
|
23
|
+
| { screen: "mcp" }
|
|
24
|
+
| { screen: "mcp-registry"; query?: string }
|
|
25
|
+
| { screen: "statusline" }
|
|
26
|
+
| { screen: "env-vars" }
|
|
27
|
+
| { screen: "cli-tools" }
|
|
28
|
+
| { screen: "model-selector" };
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Async Data Types
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
export type AsyncData<T> =
|
|
35
|
+
| { status: "idle" }
|
|
36
|
+
| { status: "loading" }
|
|
37
|
+
| { status: "success"; data: T }
|
|
38
|
+
| { status: "error"; error: Error };
|
|
39
|
+
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Modal Types
|
|
42
|
+
// ============================================================================
|
|
43
|
+
|
|
44
|
+
export interface SelectOption {
|
|
45
|
+
label: string;
|
|
46
|
+
value: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type ModalState =
|
|
51
|
+
| {
|
|
52
|
+
type: "confirm";
|
|
53
|
+
title: string;
|
|
54
|
+
message: string;
|
|
55
|
+
onConfirm: () => void;
|
|
56
|
+
onCancel: () => void;
|
|
57
|
+
}
|
|
58
|
+
| {
|
|
59
|
+
type: "input";
|
|
60
|
+
title: string;
|
|
61
|
+
label: string;
|
|
62
|
+
defaultValue?: string;
|
|
63
|
+
onSubmit: (value: string) => void;
|
|
64
|
+
onCancel: () => void;
|
|
65
|
+
}
|
|
66
|
+
| {
|
|
67
|
+
type: "select";
|
|
68
|
+
title: string;
|
|
69
|
+
message: string;
|
|
70
|
+
options: SelectOption[];
|
|
71
|
+
onSelect: (value: string) => void;
|
|
72
|
+
onCancel: () => void;
|
|
73
|
+
}
|
|
74
|
+
| {
|
|
75
|
+
type: "message";
|
|
76
|
+
title: string;
|
|
77
|
+
message: string;
|
|
78
|
+
variant: "info" | "success" | "error";
|
|
79
|
+
onDismiss: () => void;
|
|
80
|
+
}
|
|
81
|
+
| {
|
|
82
|
+
type: "loading";
|
|
83
|
+
message: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Progress Types
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
export interface ProgressState {
|
|
91
|
+
message: string;
|
|
92
|
+
current?: number;
|
|
93
|
+
total?: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// Screen State Types
|
|
98
|
+
// ============================================================================
|
|
99
|
+
|
|
100
|
+
export interface PluginsScreenState {
|
|
101
|
+
scope: "project" | "global";
|
|
102
|
+
collapsedMarketplaces: Set<string>;
|
|
103
|
+
selectedIndex: number;
|
|
104
|
+
searchQuery: string;
|
|
105
|
+
marketplaces: AsyncData<Marketplace[]>;
|
|
106
|
+
plugins: AsyncData<PluginInfo[]>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface McpScreenState {
|
|
110
|
+
selectedIndex: number;
|
|
111
|
+
servers: AsyncData<McpServer[]>;
|
|
112
|
+
installedServers: Record<string, boolean>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface McpRegistryScreenState {
|
|
116
|
+
searchQuery: string;
|
|
117
|
+
selectedIndex: number;
|
|
118
|
+
servers: AsyncData<McpServer[]>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface StatusLineScreenState {
|
|
122
|
+
scope: "project" | "global";
|
|
123
|
+
selectedIndex: number;
|
|
124
|
+
presets: AsyncData<StatusLineConfig[]>;
|
|
125
|
+
currentPreset: string | null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface EnvVarsScreenState {
|
|
129
|
+
selectedIndex: number;
|
|
130
|
+
variables: AsyncData<Record<string, string>>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface CliTool {
|
|
134
|
+
name: string;
|
|
135
|
+
displayName: string;
|
|
136
|
+
description: string;
|
|
137
|
+
installCommand: string;
|
|
138
|
+
checkCommand: string;
|
|
139
|
+
homebrewFormula?: string;
|
|
140
|
+
npmPackage?: string;
|
|
141
|
+
installedVersion?: string;
|
|
142
|
+
latestVersion?: string;
|
|
143
|
+
hasUpdate?: boolean;
|
|
144
|
+
isInstalled: boolean;
|
|
145
|
+
isChecking: boolean;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface CliToolsScreenState {
|
|
149
|
+
selectedIndex: number;
|
|
150
|
+
tools: AsyncData<CliTool[]>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface ModelSelectorScreenState {
|
|
154
|
+
selectedIndex: number;
|
|
155
|
+
searchQuery: string;
|
|
156
|
+
taskSize: "large" | "small";
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// App State
|
|
161
|
+
// ============================================================================
|
|
162
|
+
|
|
163
|
+
export interface AppState {
|
|
164
|
+
// Navigation
|
|
165
|
+
currentRoute: Route;
|
|
166
|
+
|
|
167
|
+
// Project context
|
|
168
|
+
projectPath: string;
|
|
169
|
+
|
|
170
|
+
// Global UI state
|
|
171
|
+
modal: ModalState | null;
|
|
172
|
+
progress: ProgressState | null;
|
|
173
|
+
isSearching: boolean;
|
|
174
|
+
|
|
175
|
+
// Refresh counter - incremented when marketplace sync completes
|
|
176
|
+
// Screens can watch this to know when to refetch data
|
|
177
|
+
dataRefreshVersion: number;
|
|
178
|
+
|
|
179
|
+
// Screen-specific state
|
|
180
|
+
plugins: PluginsScreenState;
|
|
181
|
+
mcp: McpScreenState;
|
|
182
|
+
mcpRegistry: McpRegistryScreenState;
|
|
183
|
+
statusline: StatusLineScreenState;
|
|
184
|
+
envVars: EnvVarsScreenState;
|
|
185
|
+
cliTools: CliToolsScreenState;
|
|
186
|
+
modelSelector: ModelSelectorScreenState;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ============================================================================
|
|
190
|
+
// Action Types
|
|
191
|
+
// ============================================================================
|
|
192
|
+
|
|
193
|
+
export type AppAction =
|
|
194
|
+
// Navigation
|
|
195
|
+
| { type: "NAVIGATE"; route: Route }
|
|
196
|
+
|
|
197
|
+
// Plugins screen
|
|
198
|
+
| { type: "PLUGINS_SET_SCOPE"; scope: "project" | "global" }
|
|
199
|
+
| { type: "PLUGINS_TOGGLE_SCOPE" }
|
|
200
|
+
| { type: "PLUGINS_TOGGLE_MARKETPLACE"; name: string }
|
|
201
|
+
| { type: "PLUGINS_SELECT"; index: number }
|
|
202
|
+
| { type: "PLUGINS_SET_SEARCH"; query: string }
|
|
203
|
+
| { type: "PLUGINS_DATA_LOADING" }
|
|
204
|
+
| {
|
|
205
|
+
type: "PLUGINS_DATA_SUCCESS";
|
|
206
|
+
marketplaces: Marketplace[];
|
|
207
|
+
plugins: PluginInfo[];
|
|
208
|
+
}
|
|
209
|
+
| { type: "PLUGINS_DATA_ERROR"; error: Error }
|
|
210
|
+
|
|
211
|
+
// MCP screen
|
|
212
|
+
| { type: "MCP_SELECT"; index: number }
|
|
213
|
+
| { type: "MCP_DATA_LOADING" }
|
|
214
|
+
| {
|
|
215
|
+
type: "MCP_DATA_SUCCESS";
|
|
216
|
+
servers: McpServer[];
|
|
217
|
+
installedServers: Record<string, boolean>;
|
|
218
|
+
}
|
|
219
|
+
| { type: "MCP_DATA_ERROR"; error: Error }
|
|
220
|
+
|
|
221
|
+
// MCP Registry screen
|
|
222
|
+
| { type: "MCP_REGISTRY_SET_QUERY"; query: string }
|
|
223
|
+
| { type: "MCPREGISTRY_SEARCH"; query: string } // Alias for MCP_REGISTRY_SET_QUERY
|
|
224
|
+
| { type: "MCPREGISTRY_SELECT"; index: number } // Alias for MCP_REGISTRY_SELECT
|
|
225
|
+
| { type: "MCP_REGISTRY_SELECT"; index: number }
|
|
226
|
+
| { type: "MCP_REGISTRY_DATA_LOADING" }
|
|
227
|
+
| { type: "MCP_REGISTRY_DATA_SUCCESS"; servers: McpServer[] }
|
|
228
|
+
| { type: "MCP_REGISTRY_DATA_ERROR"; error: Error }
|
|
229
|
+
|
|
230
|
+
// Status line screen
|
|
231
|
+
| { type: "STATUSLINE_SET_SCOPE"; scope: "project" | "global" }
|
|
232
|
+
| { type: "STATUSLINE_TOGGLE_SCOPE" }
|
|
233
|
+
| { type: "STATUSLINE_SELECT"; index: number }
|
|
234
|
+
| { type: "STATUSLINE_DATA_LOADING" }
|
|
235
|
+
| {
|
|
236
|
+
type: "STATUSLINE_DATA_SUCCESS";
|
|
237
|
+
presets: StatusLineConfig[];
|
|
238
|
+
currentPreset: string | null;
|
|
239
|
+
}
|
|
240
|
+
| { type: "STATUSLINE_DATA_ERROR"; error: Error }
|
|
241
|
+
|
|
242
|
+
// Env vars screen
|
|
243
|
+
| { type: "ENVVARS_SELECT"; index: number }
|
|
244
|
+
| { type: "ENVVARS_DATA_LOADING" }
|
|
245
|
+
| { type: "ENVVARS_DATA_SUCCESS"; variables: Record<string, string> }
|
|
246
|
+
| { type: "ENVVARS_DATA_ERROR"; error: Error }
|
|
247
|
+
|
|
248
|
+
// CLI tools screen
|
|
249
|
+
| { type: "CLITOOLS_SELECT"; index: number }
|
|
250
|
+
| { type: "CLITOOLS_DATA_LOADING" }
|
|
251
|
+
| { type: "CLITOOLS_DATA_SUCCESS"; tools: CliTool[] }
|
|
252
|
+
| { type: "CLITOOLS_DATA_ERROR"; error: Error }
|
|
253
|
+
| { type: "CLITOOLS_UPDATE_TOOL"; name: string; updates: Partial<CliTool> }
|
|
254
|
+
|
|
255
|
+
// Model Selector Screen
|
|
256
|
+
| { type: "MODEL_SELECTOR_SELECT"; index: number }
|
|
257
|
+
| { type: "MODEL_SELECTOR_SET_SEARCH"; query: string }
|
|
258
|
+
| { type: "MODEL_SELECTOR_SET_TASK_SIZE"; size: "large" | "small" }
|
|
259
|
+
|
|
260
|
+
// Modals
|
|
261
|
+
| { type: "SHOW_MODAL"; modal: ModalState }
|
|
262
|
+
| { type: "HIDE_MODAL" }
|
|
263
|
+
|
|
264
|
+
// Progress
|
|
265
|
+
| { type: "SHOW_PROGRESS"; state: ProgressState }
|
|
266
|
+
| { type: "UPDATE_PROGRESS"; state: ProgressState }
|
|
267
|
+
| { type: "HIDE_PROGRESS" }
|
|
268
|
+
|
|
269
|
+
// Search state (blocks global key handlers)
|
|
270
|
+
| { type: "SET_SEARCHING"; isSearching: boolean }
|
|
271
|
+
|
|
272
|
+
// Data refresh - triggers screens to refetch
|
|
273
|
+
| { type: "DATA_REFRESH_COMPLETE" };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { execFile } from
|
|
2
|
-
import { promisify } from
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
3
|
const execFileAsync = promisify(execFile);
|
|
4
4
|
/**
|
|
5
5
|
* Check if a command exists in PATH
|
|
@@ -10,11 +10,10 @@ const execFileAsync = promisify(execFile);
|
|
|
10
10
|
export async function which(command) {
|
|
11
11
|
try {
|
|
12
12
|
// Use execFile with argument array to prevent command injection
|
|
13
|
-
const { stdout } = await execFileAsync(
|
|
13
|
+
const { stdout } = await execFileAsync("which", [command]);
|
|
14
14
|
return stdout.trim() || null;
|
|
15
15
|
}
|
|
16
16
|
catch {
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
//# sourceMappingURL=command-utils.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Check if a command exists in PATH
|
|
8
|
+
* Uses execFile (not exec) to avoid shell injection vulnerabilities
|
|
9
|
+
* @param command - Command name to check
|
|
10
|
+
* @returns Path to command if found, null otherwise
|
|
11
|
+
*/
|
|
12
|
+
export async function which(command: string): Promise<string | null> {
|
|
13
|
+
try {
|
|
14
|
+
// Use execFile with argument array to prevent command injection
|
|
15
|
+
const { stdout } = await execFileAsync("which", [command]);
|
|
16
|
+
return stdout.trim() || null;
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -52,7 +52,7 @@ export function fuzzyMatch(query, target) {
|
|
|
52
52
|
*/
|
|
53
53
|
export function fuzzyFilter(items, query, getText) {
|
|
54
54
|
if (!query.trim()) {
|
|
55
|
-
return items.map(item => ({ item, score: 1, matches: [] }));
|
|
55
|
+
return items.map((item) => ({ item, score: 1, matches: [] }));
|
|
56
56
|
}
|
|
57
57
|
const results = [];
|
|
58
58
|
for (const item of items) {
|
|
@@ -79,7 +79,7 @@ export function highlightMatches(text, matches) {
|
|
|
79
79
|
}
|
|
80
80
|
const matchSet = new Set(matches);
|
|
81
81
|
const segments = [];
|
|
82
|
-
let currentSegment =
|
|
82
|
+
let currentSegment = "";
|
|
83
83
|
let isHighlighted = matchSet.has(0);
|
|
84
84
|
for (let i = 0; i < text.length; i++) {
|
|
85
85
|
const shouldHighlight = matchSet.has(i);
|
|
@@ -99,4 +99,3 @@ export function highlightMatches(text, matches) {
|
|
|
99
99
|
}
|
|
100
100
|
return segments;
|
|
101
101
|
}
|
|
102
|
-
//# sourceMappingURL=fuzzy-search.js.map
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple fuzzy search utility for filtering lists
|
|
3
|
+
* Uses a scoring algorithm that rewards:
|
|
4
|
+
* - Consecutive character matches
|
|
5
|
+
* - Matches at word boundaries
|
|
6
|
+
* - Matches at start of string
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface FuzzyMatch<T> {
|
|
10
|
+
item: T;
|
|
11
|
+
score: number;
|
|
12
|
+
matches: number[]; // indices of matched characters
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Calculate fuzzy match score for a query against a target string
|
|
17
|
+
* Returns null if no match, otherwise returns score and match indices
|
|
18
|
+
*/
|
|
19
|
+
export function fuzzyMatch(
|
|
20
|
+
query: string,
|
|
21
|
+
target: string,
|
|
22
|
+
): { score: number; matches: number[] } | null {
|
|
23
|
+
if (!query) return { score: 1, matches: [] };
|
|
24
|
+
|
|
25
|
+
const queryLower = query.toLowerCase();
|
|
26
|
+
const targetLower = target.toLowerCase();
|
|
27
|
+
|
|
28
|
+
let queryIdx = 0;
|
|
29
|
+
let score = 0;
|
|
30
|
+
const matches: number[] = [];
|
|
31
|
+
let prevMatchIdx = -1;
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < targetLower.length && queryIdx < queryLower.length; i++) {
|
|
34
|
+
if (targetLower[i] === queryLower[queryIdx]) {
|
|
35
|
+
matches.push(i);
|
|
36
|
+
|
|
37
|
+
// Bonus for consecutive matches
|
|
38
|
+
if (prevMatchIdx === i - 1) {
|
|
39
|
+
score += 5;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Bonus for matching at word boundary
|
|
43
|
+
if (i === 0 || /[\s\-_.]/.test(target[i - 1])) {
|
|
44
|
+
score += 10;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Bonus for matching at start
|
|
48
|
+
if (i === 0) {
|
|
49
|
+
score += 15;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Base score for each match
|
|
53
|
+
score += 1;
|
|
54
|
+
|
|
55
|
+
prevMatchIdx = i;
|
|
56
|
+
queryIdx++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// All query characters must be found
|
|
61
|
+
if (queryIdx !== queryLower.length) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Penalty for longer strings (prefer shorter, more precise matches)
|
|
66
|
+
score -= Math.floor(target.length / 10);
|
|
67
|
+
|
|
68
|
+
return { score, matches };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Filter and sort items by fuzzy match score
|
|
73
|
+
*/
|
|
74
|
+
export function fuzzyFilter<T>(
|
|
75
|
+
items: T[],
|
|
76
|
+
query: string,
|
|
77
|
+
getText: (item: T) => string,
|
|
78
|
+
): FuzzyMatch<T>[] {
|
|
79
|
+
if (!query.trim()) {
|
|
80
|
+
return items.map((item) => ({ item, score: 1, matches: [] }));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const results: FuzzyMatch<T>[] = [];
|
|
84
|
+
|
|
85
|
+
for (const item of items) {
|
|
86
|
+
const text = getText(item);
|
|
87
|
+
const match = fuzzyMatch(query, text);
|
|
88
|
+
|
|
89
|
+
if (match) {
|
|
90
|
+
results.push({
|
|
91
|
+
item,
|
|
92
|
+
score: match.score,
|
|
93
|
+
matches: match.matches,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Sort by score descending
|
|
99
|
+
return results.sort((a, b) => b.score - a.score);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Highlight matched characters in a string
|
|
104
|
+
* Returns array of { text, highlighted } segments
|
|
105
|
+
*/
|
|
106
|
+
export function highlightMatches(
|
|
107
|
+
text: string,
|
|
108
|
+
matches: number[],
|
|
109
|
+
): Array<{ text: string; highlighted: boolean }> {
|
|
110
|
+
if (matches.length === 0) {
|
|
111
|
+
return [{ text, highlighted: false }];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const matchSet = new Set(matches);
|
|
115
|
+
const segments: Array<{ text: string; highlighted: boolean }> = [];
|
|
116
|
+
let currentSegment = "";
|
|
117
|
+
let isHighlighted = matchSet.has(0);
|
|
118
|
+
|
|
119
|
+
for (let i = 0; i < text.length; i++) {
|
|
120
|
+
const shouldHighlight = matchSet.has(i);
|
|
121
|
+
|
|
122
|
+
if (shouldHighlight !== isHighlighted) {
|
|
123
|
+
if (currentSegment) {
|
|
124
|
+
segments.push({ text: currentSegment, highlighted: isHighlighted });
|
|
125
|
+
}
|
|
126
|
+
currentSegment = text[i];
|
|
127
|
+
isHighlighted = shouldHighlight;
|
|
128
|
+
} else {
|
|
129
|
+
currentSegment += text[i];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (currentSegment) {
|
|
134
|
+
segments.push({ text: currentSegment, highlighted: isHighlighted });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return segments;
|
|
138
|
+
}
|
|
@@ -9,14 +9,14 @@ export function formatMarketplaceName(name) {
|
|
|
9
9
|
return name
|
|
10
10
|
.split(/[-_]/)
|
|
11
11
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
12
|
-
.join(
|
|
12
|
+
.join(" ");
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* Validate GitHub repository format (org/repo)
|
|
16
16
|
* Prevents SSRF via malicious repo strings
|
|
17
17
|
*/
|
|
18
18
|
export function isValidGitHubRepo(repo) {
|
|
19
|
-
if (!repo || typeof repo !==
|
|
19
|
+
if (!repo || typeof repo !== "string") {
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
// Must match GitHub username/repo format
|
|
@@ -25,7 +25,8 @@ export function isValidGitHubRepo(repo) {
|
|
|
25
25
|
const GITHUB_REPO_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]\/[a-zA-Z0-9_.-]+$/;
|
|
26
26
|
// Allow single-char usernames too
|
|
27
27
|
const GITHUB_REPO_PATTERN_SHORT = /^[a-zA-Z0-9]\/[a-zA-Z0-9_.-]+$/;
|
|
28
|
-
if (!GITHUB_REPO_PATTERN.test(repo) &&
|
|
28
|
+
if (!GITHUB_REPO_PATTERN.test(repo) &&
|
|
29
|
+
!GITHUB_REPO_PATTERN_SHORT.test(repo)) {
|
|
29
30
|
return false;
|
|
30
31
|
}
|
|
31
32
|
// Blocklist suspicious patterns
|
|
@@ -40,11 +41,11 @@ export function isValidGitHubRepo(repo) {
|
|
|
40
41
|
return !BLOCKLIST.some((pattern) => pattern.test(repo));
|
|
41
42
|
}
|
|
42
43
|
export function parsePluginId(pluginId) {
|
|
43
|
-
if (!pluginId || typeof pluginId !==
|
|
44
|
+
if (!pluginId || typeof pluginId !== "string") {
|
|
44
45
|
return null;
|
|
45
46
|
}
|
|
46
47
|
const trimmed = pluginId.trim();
|
|
47
|
-
const atIndex = trimmed.lastIndexOf(
|
|
48
|
+
const atIndex = trimmed.lastIndexOf("@");
|
|
48
49
|
if (atIndex <= 0) {
|
|
49
50
|
return null;
|
|
50
51
|
}
|
|
@@ -59,4 +60,3 @@ export function parsePluginId(pluginId) {
|
|
|
59
60
|
raw: trimmed,
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
|
-
//# sourceMappingURL=string-utils.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared string utilities for claudeup
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Format marketplace name for display
|
|
7
|
+
* e.g., "mag-claude-plugins" -> "Mag Claude Plugins"
|
|
8
|
+
*/
|
|
9
|
+
export function formatMarketplaceName(name: string): string {
|
|
10
|
+
return name
|
|
11
|
+
.split(/[-_]/)
|
|
12
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
13
|
+
.join(" ");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Validate GitHub repository format (org/repo)
|
|
18
|
+
* Prevents SSRF via malicious repo strings
|
|
19
|
+
*/
|
|
20
|
+
export function isValidGitHubRepo(repo: string): boolean {
|
|
21
|
+
if (!repo || typeof repo !== "string") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Must match GitHub username/repo format
|
|
26
|
+
// Username: alphanumeric, hyphens (no consecutive, not start/end)
|
|
27
|
+
// Repo: alphanumeric, hyphens, underscores, dots
|
|
28
|
+
const GITHUB_REPO_PATTERN =
|
|
29
|
+
/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]\/[a-zA-Z0-9_.-]+$/;
|
|
30
|
+
|
|
31
|
+
// Allow single-char usernames too
|
|
32
|
+
const GITHUB_REPO_PATTERN_SHORT = /^[a-zA-Z0-9]\/[a-zA-Z0-9_.-]+$/;
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
!GITHUB_REPO_PATTERN.test(repo) &&
|
|
36
|
+
!GITHUB_REPO_PATTERN_SHORT.test(repo)
|
|
37
|
+
) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Blocklist suspicious patterns
|
|
42
|
+
const BLOCKLIST = [
|
|
43
|
+
/\.\./, // Path traversal
|
|
44
|
+
/@/, // URL authority injection
|
|
45
|
+
/:/, // Port specification
|
|
46
|
+
/\s/, // Whitespace
|
|
47
|
+
/%/, // URL encoding
|
|
48
|
+
/\\/, // Backslash
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
return !BLOCKLIST.some((pattern) => pattern.test(repo));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Parse plugin ID into components
|
|
56
|
+
* Format: pluginName@marketplaceName
|
|
57
|
+
*/
|
|
58
|
+
export interface ParsedPluginId {
|
|
59
|
+
pluginName: string;
|
|
60
|
+
marketplace: string;
|
|
61
|
+
raw: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function parsePluginId(pluginId: string): ParsedPluginId | null {
|
|
65
|
+
if (!pluginId || typeof pluginId !== "string") {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const trimmed = pluginId.trim();
|
|
70
|
+
const atIndex = trimmed.lastIndexOf("@");
|
|
71
|
+
|
|
72
|
+
if (atIndex <= 0) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const pluginName = trimmed.slice(0, atIndex).trim();
|
|
77
|
+
const marketplace = trimmed.slice(atIndex + 1).trim();
|
|
78
|
+
|
|
79
|
+
if (!pluginName || !marketplace) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
pluginName,
|
|
85
|
+
marketplace,
|
|
86
|
+
raw: trimmed,
|
|
87
|
+
};
|
|
88
|
+
}
|
package/dist/data/cli-tools.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface CliTool {
|
|
2
|
-
name: string;
|
|
3
|
-
displayName: string;
|
|
4
|
-
description: string;
|
|
5
|
-
installCommand: string;
|
|
6
|
-
checkCommand: string;
|
|
7
|
-
website: string;
|
|
8
|
-
category: 'ai-coding' | 'utility';
|
|
9
|
-
packageManager: 'npm' | 'pip';
|
|
10
|
-
packageName: string;
|
|
11
|
-
}
|
|
12
|
-
export declare const cliTools: CliTool[];
|
|
13
|
-
//# sourceMappingURL=cli-tools.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-tools.d.ts","sourceRoot":"","sources":["../../src/data/cli-tools.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,cAAc,EAAE,KAAK,GAAG,KAAK,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,QAAQ,EAAE,OAAO,EA0H7B,CAAC"}
|