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:
YeonGyu-Kim
2025-12-28 02:33:14 +09:00
parent 262f0c3f1f
commit 1c12925c9e
2 changed files with 31 additions and 7 deletions

View File

@@ -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)) {