Latest release
v 0.5.0
Added 11 Changed 6 Fixed 8 Tests 7
Added 11 entries
- Ink-based Interactive UI: Full terminal UI built with Ink + React
- Home screen with instance list, menu, and health warning banner
- Animated components: Header, StatusBar, StepIndicator, InstanceCard, IssueCard, WarningBanner
- Screens: AddInstance, RemoveInstance, ShowInstanceInfo, ToggleAutoSync, FixSymlinks, HealthScreen, ManagePlugins, ManageMcp, ListInstances
- Keyboard navigation: arrow keys, Enter, ESC,
!for health,qto quit useConfig,useNavigation,useHealthCheck,useAnimationshooks
- Per-Instance Plugin Management: Granular plugin control per instance
PluginInfointerface with id, name, category (internal/external), hasMcp, mcpServerNames, enabled, isSymlinkscanPluginsFromDir()discovers plugins from bothplugins/andexternal_plugins/subdirslistDefaultPlugins()/listInstancePlugins()for querying available and installed pluginscopySinglePlugin()/copySelectedPlugins()for individual or batch install with rollbackremoveSinglePlugin()with rename-to-backup safety patterndetectMcpCollisions()to check MCP server name conflicts before installvalidatePluginOperation()pre-flight checks (configDir, symlink, plugin existence, collisions)- Handles 12 internal LSP plugins without
plugin.json(falls back to dir name) - Supports both flat
{"serverName": config}and nested{"mcpServers": {"serverName": config}}.mcp.jsonformats - Coordinates with
installed_plugins.jsonv2 format (scope, installPath, version, timestamps) - Symlink detection: refuses per-plugin operations when auto-sync is active
- Migration System (
src/migration.ts): Safe v1 → v2 config upgraderunMigration()with 4-step procedure: backup → validate → transform → save- PID-based lock file prevents concurrent migrations
- Automatic backup of config.json + instance settings.json (keeps last 3)
- Failure flag: sets
migrationStatus: "failed"with error details, prevents auto-retry clearMigrationFailure()for explicit retryCLAUDE_MULTI_HOMEenv override for testability
- Health Check System (
src/health.ts): Detects and reports issues- Checks: migration failure, missing configDir, missing binary, corrupted settings.json, broken symlinks
- Persistent health status at
~/.claude-multi/health-status.json dismissIssue()/dismissAllIssues()for acknowledging warnings- Warning banner on home screen with
!key to review - HealthScreen with list/detail views, retry, dismiss actions
- ManagePlugins Screen: Full plugin management UI
- Install plugins from default (MultiSelect with MCP badge, [ext] tag)
- Remove installed plugins
- Enable/disable plugins
- List installed plugins with status indicators
- Symlink detection with warning
- ManageMcp Screen: Enhanced MCP server management
- List MCP servers with source attribution ([pluginName] or [custom])
- Add custom MCP server (name + JSON config input)
- Remove custom MCP server (select from custom servers)
- Verify MCP configuration
- Copy between instances
- CLI Plugin Commands: 5 new
pluginssub-commandsplugins install <instance> <ids...>— install plugins with collision detectionplugins remove <instance> <ids...>— remove plugins with symlink guardplugins list-defaults— list all 50 default plugins with category/MCP badgesplugins list-installed [instance]— list installed plugins per instanceplugins check-collisions <instance> <ids...>— detect MCP name conflicts
- Provider Templates: DeepSeek provider template added
- Instance State:
initializeInstanceState()creates.claude.jsonwithhasCompletedOnboarding: true - Provider Env:
mergeProviderEnv()integrates provider template env vars into instance settings - Screenshot Capture:
scripts/capture-screens.tsxfor automated UI screenshots
Changed 6 entries
-
copyAllFromDefault()restoredautoSyncparameter for symlink-based plugin sync -
syncPluginsAndSkills()creates actual symlinks instead of copying files - Broken symlink detection uses
lstatSync(works whenexistsSyncreturns false) -
~/.claudeis strictly read-only — never modified by any operation - Atomic file writes for both config.json and settings.json (temp-file-rename pattern)
- Lazy path resolution in migration.ts and health.ts for testability
Fixed 8 entries
-
syncPluginsAndSkillswas doing recursive copy instead of creating symlinks -
copyAllFromDefaultautoSyncparameter was removed, breaking symlink-based sync - Broken symlinks not cleaned before creating new ones (used
lstatSyncinstead ofexistsSync) -
isClaudeCodeRunning()blocked tests — skips inNODE_ENV=test -
writeFileSyncnot imported in config.ts -
McpSourceDetailsprop name mismatch in ManageMcp -
renameSyncdynamic import insaveConfigAtomicreplaced with top-level import - TypeScript:
updateInstanceAutoSyncobject possibly undefined after bounds check
Tests 7 entries
- 155 tests, 0 failures across 16 test files
-
test/plugin-management.test.ts(18 tests): scanning, copy, remove, MCP helpers, atomic writes -
test/e2e/plugin-flow.test.ts(6 tests): CLI plugin operations end-to-end -
test/migration.test.ts(15 tests): migration, backup, lock, failure recovery -
test/health.test.ts(15 tests): health checks, persistence, dismiss -
test/ink/(31 tests): component rendering, screen navigation, animation hooks -
test/config.test.ts(53 tests): sync/unsync, copyAllFromDefault, symlink cycles