Skip to content

Commit 790cd3b

Browse files
committed
fix(plugin-install): save installed plugins to config
The plugin-install command now saves installed plugins to the AIPM config file (.aipm/config.json), making them available for sync and uninstall operations. This fixes the broken workflow where: - Plugins installed with 'aipm plugin install' weren't tracked in config - 'aipm sync' couldn't find them (reads from config.plugins) - 'aipm uninstall' would fail (checks if plugin exists in config) Also made AIPM config required for plugin-install (not optional) and added a check to prevent re-installing already-installed plugins.
1 parent f6f1851 commit 790cd3b

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/commands/plugin-install.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { z } from 'zod';
44
import { loadClaudeCodeMarketplaces, loadPluginsConfig } from '../config/loader';
55
import { DIR_CURSOR } from '../constants';
66
import { getErrorMessage } from '../errors';
7+
import { loadTargetConfig, saveConfig } from '../helpers/aipm-config';
78
import { isClaudeCodeInstalled } from '../helpers/claude-code-config';
89
import { fileExists } from '../helpers/fs';
910
import { resolveMarketplacePath } from '../helpers/git';
@@ -26,18 +27,14 @@ export async function pluginInstall(options: unknown): Promise<void> {
2627
try {
2728
const { pluginName, marketplaceName } = parsePluginId(cmd.pluginId);
2829

29-
// Load marketplaces from both AIPM config (optional) and Claude Code (auto-discovered)
30-
let aipmMarketplaces: Record<string, any> = {};
31-
try {
32-
const config = await loadPluginsConfig(cwd);
33-
aipmMarketplaces = config.config.marketplaces || {};
34-
} catch (error: unknown) {
35-
// AIPM config is optional - proceed without it
36-
// Log at info level so users know about config issues but can continue
37-
if (!(error instanceof Error && error.message.includes('not found'))) {
38-
const message = getErrorMessage(error);
39-
defaultIO.logInfo(`ℹ️ Config loading: ${message}`);
40-
}
30+
// Load AIPM config - required for plugin-install to track installed plugins
31+
let { config } = await loadPluginsConfig(cwd);
32+
let aipmMarketplaces: Record<string, any> = config.marketplaces || {};
33+
34+
// Check if plugin is already installed
35+
if (config.plugins[cmd.pluginId]) {
36+
defaultIO.logInfo(`Plugin '${cmd.pluginId}' is already installed`);
37+
return;
4138
}
4239

4340
const claudeMarketplaces = await loadClaudeCodeMarketplaces();
@@ -150,9 +147,17 @@ export async function pluginInstall(options: unknown): Promise<void> {
150147
syncResult = await syncPluginToCursor(pluginPath, marketplaceName, pluginName, cursorDir);
151148
}
152149

150+
// Save plugin to AIPM config to make it available for sync and uninstall
151+
const targetConfig = await loadTargetConfig(cwd, false);
152+
const updatedConfig = merge({}, targetConfig, {
153+
plugins: { [cmd.pluginId]: { enabled: true } },
154+
});
155+
await saveConfig(cwd, updatedConfig, false);
156+
153157
const summary = formatSyncResult(syncResult);
154158

155159
defaultIO.logSuccess(`Installed ${cmd.pluginId}`);
160+
defaultIO.logSuccess(`Added plugin '${cmd.pluginId}' to .aipm/config.json`);
156161
console.log(`\n✨ Plugin '${cmd.pluginId}' installed successfully! (${summary})\n`);
157162
} catch (error: unknown) {
158163
const message = getErrorMessage(error);

0 commit comments

Comments
 (0)