fix(plugin-loader): support installed_plugins.json v1 format for backward compatibility (#288)
The installed_plugins.json file has two versions: - v1: plugins stored as direct objects - v2: plugins stored as arrays Use discriminated union types (InstalledPluginsDatabaseV1/V2) for proper type narrowing based on version field. 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
@@ -14,6 +14,7 @@ import type { AgentFrontmatter } from "../claude-code-agent-loader/types"
|
||||
import type { ClaudeCodeMcpConfig, McpServerConfig } from "../claude-code-mcp-loader/types"
|
||||
import type {
|
||||
InstalledPluginsDatabase,
|
||||
PluginInstallation,
|
||||
PluginManifest,
|
||||
LoadedPlugin,
|
||||
PluginLoadResult,
|
||||
@@ -134,6 +135,15 @@ function isPluginEnabled(
|
||||
return true
|
||||
}
|
||||
|
||||
function extractPluginEntries(
|
||||
db: InstalledPluginsDatabase
|
||||
): Array<[string, PluginInstallation | undefined]> {
|
||||
if (db.version === 1) {
|
||||
return Object.entries(db.plugins).map(([key, installation]) => [key, installation])
|
||||
}
|
||||
return Object.entries(db.plugins).map(([key, installations]) => [key, installations[0]])
|
||||
}
|
||||
|
||||
export function discoverInstalledPlugins(options?: PluginLoaderOptions): PluginLoadResult {
|
||||
const db = loadInstalledPlugins()
|
||||
const settings = loadClaudeSettings()
|
||||
@@ -147,15 +157,14 @@ export function discoverInstalledPlugins(options?: PluginLoaderOptions): PluginL
|
||||
const settingsEnabledPlugins = settings?.enabledPlugins
|
||||
const overrideEnabledPlugins = options?.enabledPluginsOverride
|
||||
|
||||
for (const [pluginKey, installations] of Object.entries(db.plugins)) {
|
||||
if (!installations || installations.length === 0) continue
|
||||
for (const [pluginKey, installation] of extractPluginEntries(db)) {
|
||||
if (!installation) continue
|
||||
|
||||
if (!isPluginEnabled(pluginKey, settingsEnabledPlugins, overrideEnabledPlugins)) {
|
||||
log(`Plugin disabled: ${pluginKey}`)
|
||||
continue
|
||||
}
|
||||
|
||||
const installation = installations[0]
|
||||
const { installPath, scope, version } = installation
|
||||
|
||||
if (!existsSync(installPath)) {
|
||||
|
||||
@@ -20,14 +20,29 @@ export interface PluginInstallation {
|
||||
isLocal?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Installed plugins database v1 (legacy)
|
||||
* plugins stored as direct objects
|
||||
*/
|
||||
export interface InstalledPluginsDatabaseV1 {
|
||||
version: 1
|
||||
plugins: Record<string, PluginInstallation>
|
||||
}
|
||||
|
||||
/**
|
||||
* Installed plugins database v2 (current)
|
||||
* plugins stored as arrays
|
||||
*/
|
||||
export interface InstalledPluginsDatabaseV2 {
|
||||
version: 2
|
||||
plugins: Record<string, PluginInstallation[]>
|
||||
}
|
||||
|
||||
/**
|
||||
* Installed plugins database structure
|
||||
* Located at ~/.claude/plugins/installed_plugins.json
|
||||
*/
|
||||
export interface InstalledPluginsDatabase {
|
||||
version: number
|
||||
plugins: Record<string, PluginInstallation[]>
|
||||
}
|
||||
export type InstalledPluginsDatabase = InstalledPluginsDatabaseV1 | InstalledPluginsDatabaseV2
|
||||
|
||||
/**
|
||||
* Plugin author information
|
||||
|
||||
Reference in New Issue
Block a user