fix(typecheck): add plugin command view types (#1565)

* fix(typecheck): add plugin command view types

* fix(typecheck): simplify plugin settings update
This commit is contained in:
Bogdan
2026-06-10 08:48:28 +08:00
committed by GitHub
parent 548bffc2a7
commit fc0a4b5cdf
5 changed files with 142 additions and 35 deletions
+18 -15
View File
@@ -236,7 +236,7 @@ function PluginComponentsDisplay({
const pluginEntry = marketplaceData.plugins.find(p => p.name === plugin.name);
if (pluginEntry) {
// Combine commands from both sources
const commandPathList = [];
const commandPathList: string[] = [];
if (plugin.commandsPath) {
commandPathList.push(plugin.commandsPath);
}
@@ -255,7 +255,7 @@ function PluginComponentsDisplay({
}
// Combine agents from both sources
const agentPathList = [];
const agentPathList: string[] = [];
if (plugin.agentsPath) {
agentPathList.push(plugin.agentsPath);
}
@@ -274,7 +274,7 @@ function PluginComponentsDisplay({
}
// Combine skills from both sources
const skillPathList = [];
const skillPathList: string[] = [];
if (plugin.skillsPath) {
skillPathList.push(plugin.skillsPath);
}
@@ -294,7 +294,7 @@ function PluginComponentsDisplay({
}
// Combine hooks from both sources
const hooksList = [];
const hooksList: unknown[] = [];
if (plugin.hooksConfig) {
hooksList.push(Object.keys(plugin.hooksConfig));
}
@@ -303,7 +303,7 @@ function PluginComponentsDisplay({
}
// Combine MCP servers from both sources
const mcpServersList = [];
const mcpServersList: unknown[] = [];
if (plugin.mcpServers) {
mcpServersList.push(Object.keys(plugin.mcpServers));
}
@@ -1468,12 +1468,14 @@ export function ManagePlugins({
for (const source of editableSources) {
const settings = getSettingsForSource(source);
if (settings?.enabledPlugins?.[pluginId_7] !== undefined) {
updateSettingsForSource(source, {
enabledPlugins: {
...settings.enabledPlugins,
[pluginId_7]: undefined
}
});
const enabledPlugins: Record<string, boolean | string[] | undefined> = {
...settings.enabledPlugins,
[pluginId_7]: undefined
};
const settingsUpdate: Record<string, unknown> = {
enabledPlugins
};
updateSettingsForSource(source, settingsUpdate);
success = true;
}
}
@@ -1509,13 +1511,14 @@ export function ManagePlugins({
// Write `false` directly — disablePluginOp's cross-scope guard would
// reject this (plugin isn't in localSettings yet; the override IS the
// point).
const enabledPlugins: Record<string, boolean | string[]> = {
...(getSettingsForSource('localSettings')?.enabledPlugins ?? {}),
[pluginId_8]: false
};
const {
error: error_2
} = updateSettingsForSource('localSettings', {
enabledPlugins: {
...getSettingsForSource('localSettings')?.enabledPlugins,
[pluginId_8]: false
}
enabledPlugins
});
if (error_2) {
setIsProcessing(false);
+30 -19
View File
@@ -28,7 +28,16 @@ import { type ParsedCommand, parsePluginArgs } from './parseArgs.js';
import type { PluginSettingsProps, ViewState } from './types.js';
import { ValidatePlugin } from './ValidatePlugin.js';
type TabId = 'discover' | 'installed' | 'marketplaces' | 'errors';
function MarketplaceList(t0) {
type MarketplaceLoadFailure = {
name: string;
error: string;
};
type ErrorsTabContentProps = {
setViewState: (state: ViewState) => void;
setActiveTab: (tab: TabId) => void;
markPluginsChanged: () => void | Promise<void>;
};
function MarketplaceList(t0: Pick<PluginSettingsProps, 'onComplete'>): React.ReactNode {
const $ = _c(4);
const {
onComplete
@@ -336,7 +345,7 @@ function removeExtraMarketplace(name: string, sources: Array<{
if (settings.enabledPlugins) {
const suffix = `@${name}`;
let removedPlugins = false;
const updatedPlugins = {
const updatedPlugins: Record<string, boolean | string[] | undefined> = {
...settings.enabledPlugins
};
for (const pluginId in updatedPlugins) {
@@ -354,7 +363,7 @@ function removeExtraMarketplace(name: string, sources: Array<{
}
}
}
function ErrorsTabContent(t0) {
function ErrorsTabContent(t0: ErrorsTabContentProps): React.ReactNode {
const $ = _c(26);
const {
setViewState,
@@ -365,15 +374,15 @@ function ErrorsTabContent(t0) {
const installationStatus = useAppState(_temp3);
const setAppState = useSetAppState();
const [selectedIndex, setSelectedIndex] = useState(0);
const [actionMessage, setActionMessage] = useState(null);
const [actionMessage, setActionMessage] = useState<string | null>(null);
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = [];
t1 = [] as MarketplaceLoadFailure[];
$[0] = t1;
} else {
t1 = $[0];
}
const [marketplaceLoadFailures, setMarketplaceLoadFailures] = useState(t1);
const [marketplaceLoadFailures, setMarketplaceLoadFailures] = useState<MarketplaceLoadFailure[]>(t1);
let t2;
let t3;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
@@ -725,7 +734,7 @@ function getInitialTab(viewState: ViewState): TabId {
if (viewState.type === 'manage-marketplaces') return 'marketplaces';
return 'discover';
}
export function PluginSettings(t0) {
export function PluginSettings(t0: PluginSettingsProps): React.ReactNode {
const $ = _c(75);
const {
onComplete,
@@ -744,8 +753,8 @@ export function PluginSettings(t0) {
parsedCommand = $[1];
t1 = $[2];
}
const initialViewState = t1;
const [viewState, setViewState] = useState(initialViewState);
const initialViewState = t1 as ViewState;
const [viewState, setViewState] = useState<ViewState>(initialViewState);
let t2;
if ($[3] !== initialViewState) {
t2 = getInitialTab(initialViewState);
@@ -754,11 +763,11 @@ export function PluginSettings(t0) {
} else {
t2 = $[4];
}
const [activeTab, setActiveTab] = useState(t2);
const [activeTab, setActiveTab] = useState<TabId>(t2 as TabId);
const [inputValue, setInputValue] = useState(viewState.type === "add-marketplace" ? viewState.initialValue || "" : "");
const [cursorOffset, setCursorOffset] = useState(0);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);
const [error, setError] = useState<string | null>(null);
const [result, setResult] = useState<string | null>(null);
const [childSearchActive, setChildSearchActive] = useState(false);
const setAppState = useSetAppState();
const pluginErrorCount = useAppState(_temp0);
@@ -977,14 +986,16 @@ export function PluginSettings(t0) {
} else {
t16 = $[43];
}
const browseMarketplaceTarget = viewState.type === "browse-marketplace" ? viewState.targetMarketplace : undefined;
const pluginTarget = viewState.type === "browse-marketplace" || viewState.type === "discover-plugins" ? viewState.targetPlugin : undefined;
let t17;
if ($[44] !== error || $[45] !== markPluginsChanged || $[46] !== result || $[47] !== viewState.targetMarketplace || $[48] !== viewState.targetPlugin || $[49] !== viewState.type) {
t17 = <Tab id="discover" title="Discover">{viewState.type === "browse-marketplace" ? <BrowseMarketplace error={error} setError={setError} result={result} setResult={setResult} setViewState={setViewState} onInstallComplete={markPluginsChanged} targetMarketplace={viewState.targetMarketplace} targetPlugin={viewState.targetPlugin} /> : <DiscoverPlugins error={error} setError={setError} result={result} setResult={setResult} setViewState={setViewState} onInstallComplete={markPluginsChanged} onSearchModeChange={setChildSearchActive} targetPlugin={viewState.type === "discover-plugins" ? viewState.targetPlugin : undefined} />}</Tab>;
$[44] = error;
$[45] = markPluginsChanged;
$[46] = result;
$[47] = viewState.targetMarketplace;
$[48] = viewState.targetPlugin;
if ($[44] !== browseMarketplaceTarget || $[45] !== error || $[46] !== markPluginsChanged || $[47] !== pluginTarget || $[48] !== result || $[49] !== viewState.type) {
t17 = <Tab id="discover" title="Discover">{viewState.type === "browse-marketplace" ? <BrowseMarketplace error={error} setError={setError} result={result} setResult={setResult} setViewState={setViewState} onInstallComplete={markPluginsChanged} targetMarketplace={browseMarketplaceTarget} targetPlugin={pluginTarget} /> : <DiscoverPlugins error={error} setError={setError} result={result} setResult={setResult} setViewState={setViewState} onInstallComplete={markPluginsChanged} onSearchModeChange={setChildSearchActive} targetPlugin={pluginTarget} />}</Tab>;
$[44] = browseMarketplaceTarget;
$[45] = error;
$[46] = markPluginsChanged;
$[47] = pluginTarget;
$[48] = result;
$[49] = viewState.type;
$[50] = t17;
} else {
+1 -1
View File
@@ -8,7 +8,7 @@ type Props = {
item: UnifiedInstalledItem;
isSelected: boolean;
};
export function UnifiedInstalledCell(t0) {
export function UnifiedInstalledCell(t0: Props): React.ReactNode {
const $ = _c(142);
const {
item,
+35
View File
@@ -0,0 +1,35 @@
import type { LocalJSXCommandOnDone } from '../../types/command.js'
export type PluginSettingsProps = {
onComplete: LocalJSXCommandOnDone
args?: string
showMcpRedirectMessage?: boolean
}
export type PluginManageAction = 'enable' | 'disable' | 'uninstall'
export type MarketplaceManageAction = 'update' | 'remove'
export type ViewState =
| { type: 'menu' }
| { type: 'help' }
| { type: 'validate'; path?: string }
| { type: 'discover-plugins'; targetPlugin?: string }
| {
type: 'browse-marketplace'
targetMarketplace?: string
targetPlugin?: string
}
| {
type: 'manage-plugins'
targetPlugin?: string
targetMarketplace?: string
action?: PluginManageAction
}
| { type: 'marketplace-list' }
| { type: 'marketplace-menu' }
| { type: 'add-marketplace'; initialValue?: string }
| {
type: 'manage-marketplaces'
targetMarketplace?: string
action?: MarketplaceManageAction
}
+58
View File
@@ -0,0 +1,58 @@
import type { MCPServerConnection, ConfigScope } from '../../services/mcp/types.js'
import type { LoadedPlugin, PluginError } from '../../types/plugin.js'
import type { PersistablePluginScope } from '../../utils/plugins/pluginIdentifier.js'
export type PluginInstalledScope = PersistablePluginScope | 'builtin'
export type UnifiedPluginScope = PluginInstalledScope | 'flagged' | ConfigScope
export type McpStatus =
| 'connected'
| 'disabled'
| 'pending'
| 'needs-auth'
| 'failed'
export type UnifiedInstalledItem =
| {
type: 'plugin'
id: string
name: string
description?: string
marketplace: string
scope: PluginInstalledScope
isEnabled: boolean
errorCount: number
errors: PluginError[]
plugin: LoadedPlugin
pendingEnable?: boolean
pendingUpdate?: boolean
pendingToggle?: 'will-enable' | 'will-disable'
}
| {
type: 'failed-plugin'
id: string
name: string
marketplace: string
scope: PersistablePluginScope
errorCount: number
errors: PluginError[]
}
| {
type: 'flagged-plugin'
id: string
name: string
marketplace: string
scope: 'flagged'
reason: string
text: string
flaggedAt: string
}
| {
type: 'mcp'
id: string
name: string
description?: string
scope: ConfigScope
status: McpStatus
client: MCPServerConnection
indented?: boolean
}