Skip to content

fix(plugins): implement dynamic plugin loading and unloading#6

Merged
vobu merged 4 commits intomainfrom
fix/plugin-lifecycle-loading
Jan 28, 2026
Merged

fix(plugins): implement dynamic plugin loading and unloading#6
vobu merged 4 commits intomainfrom
fix/plugin-lifecycle-loading

Conversation

@vobu
Copy link
Collaborator

@vobu vobu commented Jan 28, 2026

Problem

After loading and unloading a plugin, the command was still available even though the plugin was unloaded. This was because there was no actual runtime plugin loading mechanism - the CLI only wrapped npm install and npm uninstall but never actually loaded or executed plugin commands.

Solution

  • Created plugin-loader.ts module for dynamic command loading
  • Load installed plugins on CLI startup by scanning node_modules
  • Execute plugin commands when matched in command routing
  • Clear plugin cache when unloading to prevent stale commands
  • Made loadPlugin and unloadPlugin async

Changes

  • src/plugin-loader.ts - New module for managing plugin lifecycle
  • src/index.ts - Load plugins at startup, route plugin commands
  • src/commands/plugins.ts - Made async, clear cache on unload
  • tests/unit/plugin-loader.test.ts - Unit tests for plugin loader
  • tests/integration/plugin-lifecycle.test.ts - Integration test (skipped by default)

Testing

  • All existing tests pass ✅
  • New unit tests for plugin loader ✅
  • Integration test added (skipped by default) ✅

Fixes the issue where plugin commands remained available after unloading.

vobu added 4 commits January 28, 2026 23:11
- Add plugin-loader.ts module for dynamic command loading
- Load installed plugins on CLI startup
- Execute plugin commands when matched
- Clear plugin cache when unloading to prevent stale commands
- Add tests for plugin loader functionality
- Add integration test for plugin lifecycle (load/unload)

Fixes issue where plugin commands remained available after unloading.
Plugin commands are now properly loaded from node_modules at runtime
and removed from memory when unloaded.
- Remove test.skip from plugin lifecycle integration test
- Make test idempotent with proper before/after cleanup
- Fix plugin command routing - check plugins BEFORE verb-only check
- Add file:// protocol and cache-busting for dynamic imports
- Improve test to capture both stdout and stderr

The key bug was that plugin commands were checked after the verb-only
check, so single-word plugin commands would trigger showVerbResources
instead of executing. Now plugin commands are checked first.

Test now runs successfully in both local and CI/CD environments.
- Add debug() method to Logger class with timestamp and JSON support
- Enable debug mode via DEBUG=1 or C8CTL_DEBUG=1 env vars
- Refactor getter/setter methods to modern TS property syntax
  - mode property (was getMode/setMode methods)
  - debugEnabled property for toggling debug output
- Update plugin-loader to use logger.debug() instead of console.log
- Add comprehensive debug mode tests
- Document debug mode in README

Debug output goes to stderr to avoid interfering with command output.
Modern TS syntax reduces boilerplate and improves readability.
@vobu vobu merged commit 32c0a16 into main Jan 28, 2026
7 of 8 checks passed
@vobu vobu deleted the fix/plugin-lifecycle-loading branch January 28, 2026 22:51
@github-actions
Copy link

This has been released in 1.0.0.

@vobu
Copy link
Collaborator Author

vobu commented Feb 17, 2026

@github-actions
Copy link

This has been released in 2.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant