Plugins
A plugin packages tools, hooks, and lifecycle scripts behind a single
plugin.json manifest. DSCC discovers plugins on startup,
merges their tools into the agent’s tool surface, and runs their hooks
alongside user hooks.
Manifest location
| Layout | Path |
|---|---|
| Flat | plugin.json at the plugin root |
| Packaged | ./.dscc-plugin/plugin.json |
Parsed at crates/plugins/src/lib.rs:107–122.
Manifest schema
| Field | Type | Purpose |
|---|---|---|
name |
string (required) | Plugin id |
version |
string (required) | Semver |
description |
string | One-line purpose |
permissions |
string[] | read, write, execute
declarations |
defaultEnabled |
bool | Enabled on install (default false) |
hooks.PreToolUse |
string[] | Paths to hook scripts |
hooks.PostToolUse |
string[] | Paths to hook scripts |
lifecycle.Init |
string[] | Scripts on enable |
lifecycle.Shutdown |
string[] | Scripts on disable |
tools[] |
object[] | Tools contributed to the agent |
commands[] |
object[] | Named shell commands |
Tool entry
{
"name": "my-tool",
"description": "...",
"inputSchema": {"type": "object", "properties": {}},
"command": "/absolute/path/to/executable",
"args": ["--flag"],
"requiredPermission": "read-only"
}
Valid requiredPermission: read-only,
workspace-write, danger-full-access.
Plugin kinds
From plugins/lib.rs:25–50.
| Kind | Source |
|---|---|
builtin |
Shipped inside DSCC |
bundled |
Packaged with the distribution; synced to install root |
external |
User-installed via /plugin install |
Discovery
Resolved at plugins/lib.rs:1097–1150:
- Scan
install_root(default under~/.dscc/plugins/) for valid manifests. - Load from the
installed.jsonregistry; mark stale entries. - Load from
plugins.externalDirectoriesin config. - Deduplicate by plugin id.
Lifecycle CLI
From commands/lib.rs:692–801.
| Command | Purpose |
|---|---|
/plugin list (aliases /plugins,
/marketplace) |
List installed plugins |
/plugin install <path> |
Install from a local path |
/plugin enable <name> |
Enable |
/plugin disable <name> |
Disable |
/plugin uninstall <id> |
Remove |
/plugin update <id> |
Update from source |
Hooks
Defined at plugins/hooks.rs:11–22. Same events, stdin
payload, and env vars as runtime hooks (see guides/hooks.md).
| Behaviour | Rule |
|---|---|
| Ordering | Multiple plugins’ hooks merged in order |
| Deny | First exit 2 denies the tool call |
| Other non-zero | Warn but allow |
Minimal working example
./my-plugin/plugin.json:
{
"name": "hello-plugin",
"version": "0.1.0",
"description": "Adds a greet tool and a PreToolUse audit hook",
"defaultEnabled": true,
"tools": [
{"name": "greet", "description": "Print hello", "command": "./bin/greet.sh", "requiredPermission": "read-only"}
],
"hooks": {"PreToolUse": ["./hooks/audit.sh"]}
}
Scripts referenced with relative paths resolve against the plugin root.
Testing your plugin
Plugin install runs as a REPL slash command — there is no
dscc plugin … CLI subcommand (see
crates/commands/src/lib.rs:692-801).
/plugin install ./my-plugin/ # [交互] run inside the REPL
Inside DSCC:
| Step | Check |
|---|---|
/plugin list |
hello-plugin appears as enabled |
Ask the model to call greet |
Tool runs; audit.sh fires on
PreToolUse |
/plugin disable hello-plugin |
Tool disappears from the surface |
See also
- guides/hooks.md — full hook contract (stdin, env, exit codes).
- guides/slash-commands.md —
/pluginand related commands.