Extension formats
dsh-cc consumes the Claude Code extension formats directly: a hooks.json, a SKILL.md, a plugin plugin.json manifest, and a .claude/agents/*.md subagent definition each mount onto a dsh-cc extension point without conversion. This page is an index: for each surface it gives the file location, a minimal skeleton, and a link to the guide that covers behavior in depth.
hooks — hooks.json
File location: a hooks.json, or a settings file's hooks key, passed to @dsh-cc/hooks-claude-code via its configPath config (the cc preset ships a tracked repo-root hooks.json). The path is process-level: a relative path resolves against the process's launch cwd at load time. A read/parse failure is contained — the bridge logs a warning and registers nothing.
Minimal skeleton (one event, one matcher, one command hook with an explicit timeout; the per-hook default is 600 000 ms):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "./scripts/gate.sh", "timeout": 5000 }
]
}
]
}
}Four executor kinds are accepted: command, http, and — off by default, enabled by the enablePromptHooks / enableAgentHooks config flags — prompt and agent (both fork a one-shot subagent). 18 hook events are supported; unsupported events in the config are ignored before group parsing.
Full story: /guide/hooks
skills — SKILL.md
File location: a skill is a directory bundle <name>/SKILL.md under one of these roots, in precedence order (lower rank wins name conflicts):
| Rank | Source | Path |
|---|---|---|
| 100 | managed | config.managedDir |
| 200 | project | <projectRoot>/.claude/skills |
| 300 | user | <dshHome>/skills |
| 400 | additional | each config.additionalDirs |
The project root is the nearest ancestor containing .git; without one, the current cwd is used. Legacy .claude/commands/*.md files are also loaded and marked deprecated. The harness-native filesystem provider adds the roots <projectRoot>/.dsh/skills, <projectRoot>/.agents/skills, and ~/.agents/skills (see the skills guide for the full merged root set).
Minimal skeleton:
---
name: my-skill
description: What the skill does and when to use it
---
Body with $ARGUMENTS substitution and optional inline-shell !`cmd` commands.Known frontmatter fields include allowed-tools, argument-hint, model (including inherit), user-invocable, disable-model-invocation, context (including fork), when_to_use, and paths. Names must be kebab-case to register. A skill declaring paths is conditional: it is not served until a Read/Write/Edit tool touches a matching file.
Full story: /guide/skills
plugins — plugin.json
File location: a plugin root holds .claude-plugin/plugin.json (preferred) or a top-level plugin.json (legacy). Plugin state is dual-home: default discovery intersects enabledPlugins (cascaded claude-user → dsh-user → project → local, later files overriding per key) with the merged plugins/installed_plugins.json of both homes — the Claude home $CLAUDE_CONFIG_DIR (else ~/.claude) stays read-visible while the dsh home $DSH_HOME (else ~/.dsh) is the write root, dsh entries winning per key. Explicit pluginDirs are flattened instead: the dir itself, or one-level children, that hold .claude-plugin/plugin.json or a top-level plugin.json.
Minimal skeleton:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "What the plugin provides"
}name is mandatory and kebab-case. Component fields are commands, agents, skills, hooks, mcpServers, and settings; when commands is omitted the loader scans commands/*.md. Unknown top-level fields are ignored. Each component mounts onto its host seam (commands, subagents, skills, hooks, mcp, settings); a component whose seam is absent is reported skipped, never failing the whole load. Agents mount namespaced under the plugin name, so the Task tool dispatches them by scoped id (plugin:agent).
Full story: /guide/plugins
subagents — .claude/agents/*.md
File location: .claude/agents directories discovered from the session's working directory — the project layer is the nearest .claude/agents found by walking up from the project root, and the user layer is ~/.claude/agents. Project shadows user (and the in-package bundled layer sits below both). A definition is keyed by its file basename, which becomes the subagent_type.
Minimal skeleton:
---
description: When to delegate to this agent
tools: Read, Grep, Glob
model: haiku
---
The agent's system prompt, written as the markdown body.description becomes the when-to-use guide; tools/disallowedTools compile to an effective allow/deny restriction; model (with inherit) resolves through the ccModelRoutes alias service; effort, permissionMode, maxTurns, initialPrompt, background, memory, skills, mcpServers, hooks, and isolation are carried through. Unknown fields are ignored; a bad known value fails loudly at load. The reserved types general-purpose (fresh spawn) and fork (conversation-inheriting fork) are sentinels — a workspace file named fork.md is unreachable.
Full story: /guide/subagents
Next
- /guide/hooks — hook events, decisions, and payloads.
- /guide/skills — invocation policy and conditional activation.
- /guide/plugins — component mounting and discovery.
- /reference/commands —
/pluginand/reload-plugins.