whitelonng/dshcode/cordis-plugin-development
Claude Code and agent skill by whitelonng/dshcode
- community
Checking that the SKILL.md file is still in the repository.
Create, modify, debug, or extend dynamic Cordis Plugins, including Host Services and Events, Client Slot and theme UI, Package-private Client-to-Host calls, dynamic Tools, version updates, approval failures, and runtime diagnostics. Use this Skill to route a user request to the correct platform and Inspect Provider, then define, run, repair, or roll back the Plugin.
Install
npx vskill@latest install whitelonng/dshcode/cordis-plugin-developmentSKILL.md
The same SKILL.md was published earlier as blitzdotdev/blitzos/cordis-plugin-development.
Develop Dynamic Cordis Plugins
First determine whether a capability belongs on Host or Client, then query the real interface before writing code. Never infer a complete API from a Service name, Event payload, Slot props, theme token, or example.
Standard workflow
- Call
cordis_inspect_listto obtain the Providers, methods, and schemas currently registered on Host and Client. - Select the smallest set of
cordis_inspect_querycalls needed to read the exact Services, Events, Builtins, Slots, Theme tokens, or Tools that the implementation will use. - For a new Plugin, design its first Package. To modify an existing Plugin, first use
cordis_inspect_self(pluginId, packageId)to read the base source and diagnostics. - Write plain JavaScript in
code.host,code.client, or both, then callcordis_define. - Call
cordis_runwith the finalpluginIdandpackageIdreturned by define. - Handle approval, waiting, Client loading, and render failures from the Run card, steering messages, or
cordis_inspect_self. - Use
cordis_stopto disable the Plugin temporarily. Usecordis_undefineonly when it is no longer needed.
Do not wait in the same turn for user approval or asynchronous browser results. After cordis_run returns awaiting-approval or starting, end the current Tool flow and wait for the system to report the final outcome through state updates and steering.
Tool usage guidance
| Tool | Use it when | Do not | |
|---|---|---|---|
cordis_inspect_list | Discover current Host/Client Providers and method schemas in one call; refresh after the runtime capability directory changes | Hard-code Provider names and skip list; treat a manifest as business data | |
cordis_inspect_query | Confirm exact Service methods, Event modes, Builtins, Slots, tokens, or Tool schemas before writing code | Use it instead of calling a real Service from the Plugin; assume a Client query will finish without a responding page | |
cordis_inspect_self | List current Plugins, inspect version pointers, or read exact Package source and runtime diagnostics | Fetch all source just to build a list; use it to modify or start a Plugin | |
cordis_define | Create a Plugin's first version or append an immutable Package to an existing Plugin; let the user preview the code first | Expect define to execute apply, request approval, or update current | |
cordis_run | Activate an exact Package; use run for first activation, restart, or rollback, and update to switch versions | Use run to switch versions implicitly; treat pending or starting as success | |
cordis_stop | Pause current effects while preserving Packages, grants, and version pointers for later use | Use stop to mean permanent deletion | |
cordis_undefine | Permanently remove a Plugin and all of its Packages and clear historical business views | Call it while rollback, inspection, or restart is still needed |
Choose a platform
| Requirement | Preferred platform | Inspect first | |
|---|---|---|---|
| Files, commands, processes, or networking | Host | fs, bash, subprocess, pty, and web in Service.listService | |
| Agents, durable Session data, or Host lifecycle | Host | The relevant Service and Event.listEvents | |
| Register a dynamic Tool callable in the next model step | Host | harness in Builtin.listBuiltins, plus Tool.listTools | |
| Page theme, layout, or current page state | Client | Theme.listTokens and Client Service.listService | |
| Conversation Snapshot or session/workspace lists | Client | The target Slot's standard props and owner props | |
| Settings pages, sidebars, input areas, overlays, or Tool cards | Client | Slots.listSubTree | |
| Fetch on Host and display on Client | Both | Host Service + harness.handle; Client Slot + host.call |
Prefer the capability closest to the data owner. If Slot props already provide the Conversation Snapshot, do not fetch it again through Host. If only the Package's own styles need to change, do not override the global theme. If only a small entry point is needed, do not replace an entire product UI region.
Provider navigation
Select methods from the actual cordis_inspect_list result. Common initial methods include:
Service.listService: withoutservice, returns every callable Service with its purpose and exact method signatures. Query the selectedserviceagain for access rules, structured method descriptions/parameters/returns, and only its referenced types.Event.listEvents: withoutevent, returns every Event with its purpose, dispatch mode, and exact listener signature. Query the selectedeventagain for its structured listener contract and only its referenced types; a Waterfall listener must callnext().Builtin.listBuiltins: returns evaluator-provided symbols and signatures that cannot be obtained throughctx.get().Slots.listSubTree: withoutroot, returns compact live trees with each Slot's purpose, kind, scope, registration keys, replacement risk, and children. With an exactroot, it also returns that selected Slot's full contract, props, and current occupants while keeping descendants compact.Theme.listTokens: returns theme tokens that may currently be queried and overridden; it does not modify the theme.Tool.listTools: returns Tool schemas actually visible to the current Agent, including dynamically registered Tools.
Provider names, methods, and inputs must come from the current list result. The Service/Event Catalog describes which interfaces this version permits; it does not guarantee that a Service is currently mounted. At runtime, use real Services and Events rather than caching or displaying Catalog query results.
Execution environment
Both code.host and code.client are plain JavaScript function bodies that return a Cordis Plugin. They are not compiled by TypeScript, JSX, or a bundler.
Do not use:
import,require, TypeScript types,as, decorators, or JSX;- globals not confirmed by
Builtin.listBuiltins; - guessed access to
window,document,process,Buffer,fetch, or native timers.
Client React code must use React.createElement(...).
Correct:
Incorrect:
JSX is not the only problem in this example. apply() registers lifecycle contributions and cannot return a React Element as the Plugin result. UI must be registered in a queried Slot.
Access Services
Read optional capabilities with ctx.get(name) by default and handle their absence:
Declare inject only when a Service is a hard dependency and the Plugin must enter waiting until Cordis reactivates it after the Service appears:
Do not overuse inject merely to avoid an undefined check. Do not access ctx.requiredService without declaring the injection; the Guard rejects undeclared dependencies.
Manage side effects
Every contribution must be removed after the Plugin is stopped, updated, or removed. Prefer Cordis lifecycle APIs:
- Use
ctx.on()to register Event listeners. - Use
ctx.effect()to own an external subscription that returns a disposer. - Retain disposers returned by Cordis Service, Tool, Slot, timer, and theme APIs.
- Do not create process-wide or page-wide side effects at module scope or outside
apply().
Recommended:
If subscribe() does not return a disposer, first query whether the Service provides a supported cleanup mechanism. Do not assume unload automatically removes arbitrary third-party callbacks.
Host and Client timers
On both platforms, the timer is a Service named timer with the same interface; it is not a Builtin. Query { "service": "timer" } through the corresponding platform's Service.listService before using it. Declare inject: ['timer'] before using the timer mixin.
One-shot delay:
Periodic work in a React component:
Incorrect:
The first example does not declare the timer hard dependency. The second uses a global timer that does not exist.
Listen to Events
Query the Event Provider first to confirm the platform, parameter order, return value, and mode.
Ordinary emit Event:
The last parameter of a Waterfall Event is next. Unless the listener intentionally stops downstream processing, it must call and return it:
Register Client UI
Query Slots.listSubTree without root to choose a target from the compact purpose and topology tree, then query the exact Slot with root before writing its registration. The exact result determines:
- the Slot's purpose in the layout;
- whether its registration protocol is
single,list,keyed, orchain; - registration options;
- scope standard props and business owner props;
- current occupants, replacement risks, and descendant Slots.
Use ctx.get('slots') and handle its absence. Then use slots.inject to wait for the Slot declaration and call slots.register inside the callback:
ctx.get('slots') does not require an injection. Do not rewrite it as ctx.slots unless inject: ['slots'] is declared:
Do not guess an id, key, selector, or props before querying the Slot protocol. Do not default to root-level root, sidebar, conversation, or details Slots; replacing an entire occupant also removes the descendant Slots it declares.
Settings pages
A full settings UI should usually register its own section through settings.section to obtain a complete content area. settings.general.item is only appropriate for one compact, general-purpose preference. Query the actual subtree, options, and props for both, then select the narrowest entry point that is still sufficient.
Dynamic Plugins are temporary and process-local, so their settings UI does not need persistent storage. Do not add durable settings or another persistence mechanism for it. Register the UI in the appropriate settings Slot and keep any transient interaction state in memory for the lifetime of the Plugin.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingpackages/preset/agent-presets/presets/cordis/skills/cordis-plugin-development/SKILL.md
Popularity
- Repository stars
- 714
- Repository forks
- 30
- 7-day trend score
- 33
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/whitelonng/dshcode/cordis-plugin-development)