Testing & Publishing
Testing locally
Section titled “Testing locally”Manual testing
Section titled “Manual testing”The fastest way to test a plugin during development:
-
Place the plugin in the local directory
Terminal window # Your plugin should be at:~/.recursive/plugins/local/my-plugin/ -
Enable it
plugin_toggle({ id: "my-plugin", enabled: true }) -
Test tools via chat
Open the Recursive dashboard, start a workspace chat, and call your tools directly.
-
Check the tool catalog
tool_catalog()Verify your tools appear with the correct names, descriptions, and audience.
-
Test with an agent session
Create a session and verify agents can discover and use your tools correctly.
Automated testing
Section titled “Automated testing”For reliable plugin development, write tests using Vitest:
import { describe, it, expect, beforeAll } from 'vitest';
describe('widget_create tool', () => { it('creates a widget with required fields', async () => { const result = await callTool('widget_create', { title: 'Test Widget', });
expect(result.error).toBeUndefined(); expect(result.id).toBeDefined(); expect(result.title).toBe('Test Widget'); });
it('returns INVALID_INPUT for missing title', async () => { const result = await callTool('widget_create', {});
expect(result.error).toBe(true); expect(result.code).toBe('INVALID_INPUT'); expect(result.retryable).toBe(true); });});Testing checklist
Section titled “Testing checklist”Before publishing, verify:
- All tools appear in
tool_catalog()with correct metadata - Required parameters are validated and return
INVALID_INPUTwhen missing - Not-found cases return
NOT_FOUNDwith a helpfulfixmessage - Success responses include a human-readable
summaryfield - SSE events fire correctly and the dashboard updates in real time
- Skills load correctly and include accurate file paths
- Rules are injected into agent contexts when the plugin is enabled
- Workflows execute end-to-end without stalling
- UI components render correctly in both dark and light themes
- Plugin disabling cleanly removes all tools, routes, and UI elements
Publishing
Section titled “Publishing”Registry publishing
Section titled “Registry publishing”GitHub distribution
Section titled “GitHub distribution”The recommended way to share plugins:
-
Create a GitHub repository for your plugin
Terminal window cd ~/.recursive/plugins/local/my-plugingit initgit add .git commit -m "Initial plugin release"gh repo create my-plugin --public --push -
Others install via the plugin manager
plugin_install({ repo: "your-username/my-plugin" })This clones the repo to
~/.recursive/plugins/installed/my-plugin/. -
Updating
plugin_update({ id: "my-plugin" })Pulls the latest changes from the repository.
Versioning
Section titled “Versioning”Use semantic versioning in your plugin.json:
{ "version": "1.2.3"}- Patch (1.2.x): Bug fixes, no API changes
- Minor (1.x.0): New features, backward compatible
- Major (x.0.0): Breaking changes to tool schemas or behavior
Plugin quality guidelines
Section titled “Plugin quality guidelines”High-quality plugins follow these patterns:
- Every tool has validation — never trust input, always use
ctx.V - Structured errors — use error codes, not generic messages
- Human-readable summaries — every success response includes a
summary - Scoped naming — prefix tool names with your plugin ID to avoid collisions
- Minimal dependencies — plugins should be self-contained
- Documentation — include a README with usage examples
- Auto-detection — use
detectso the plugin enables itself for matching projects