DSH Plugin

dsh-claude-compat

็ฎ€ไฝ“ไธญๆ–‡ npm downloads/month npm total downloads Version License

> **Reuse your entire Claude Code setup in DSH โ€” zero migration.** > skills, commands, rules, agents, hooks, MCP โ€” install and they just work. Nothing to reconfigure. --- ## The 10-second pitch You've already built up a solid `.claude/` in Claude Code โ€” skills, slash commands, rules, agents, hooks, MCP servers. Moving to **DSH (DeepSeek Harness)** shouldn't mean rebuilding all of it. **dsh-claude-compat is that bridge.** It carries your `.claude/` directories **verbatim into DSH** โ€” everything works immediately. Install once, and both sides share one config: change it in one place, it updates in both. ```bash dsh plugin --profile web add dsh-claude-compat@latest dsh web ``` Done. Your skills show up in the `/` menu, rules inject into every new session, and you can invoke agents with `/agent-name` โ€” all inside DSH, exactly like Claude Code. **Or let DSH install it itself (recommended):** copy this line to DSH โ€” it reads the skill, installs, and verifies: > Read https://github.com/biedongbin/dsh-claude-compat/blob/main/.claude/skills/install-dsh-compat/SKILL.md and install the dsh-claude-compat plugin following its steps. > โญ Find this useful? [Give it a star](https://github.com/biedongbin/dsh-claude-compat) โ€” it keeps us improving and helps more people discover it. --- ## What it brings over โ€” at a glance | Your Claude Code asset | Becomes in DSH | How to use it | |---|---|---| | `skills/**/SKILL.md` | DSH skill (lazy-loaded) | `/skill-name`, the `skill` tool, and the model-visible catalog | | `commands/*.md` | DSH skill (user-invocable) | `/command-name` in the slash menu | | `rules/*.md` | message-stream injection (same channel Claude uses) | auto-applies to every new session | | `agents/*.md` | delegation-shim skill | invoke `/agent-name` with its persona | | `.claude/settings.json` hooks | Pre/PostToolUse + UserPromptSubmit bridged | commands, permissions, blocks behave as before | | `/.mcp.json` | `dsh-mcp-client` instances | stdio / streamable-http auto-translated | | `~/.claude/plugins` | DSH skill (managed via `/cc-plugin`) | installed plugin skills work too | Both the project `.claude/` and the user-level `~/.claude/` are read. Same-name entries dedupe by fixed priority: **project `.claude` > DSH native > `~/.claude`** โ€” a project skill always wins over other copies, and a user skill never overrides a DSH-native one. `CLAUDE.md` / `AGENTS.md` are handled by DSH's built-in `dsh-agent-instructions` โ€” **this plugin never touches them**. ## What it does (implementation detail) | `.claude/` path | Mechanism | Behavior | |---|---|---| | `skills/**/SKILL.md` | DSH skill provider | Name + description in the model-visible catalog; body loads on demand via the `skill` tool. New skills appear on the next catalog reconcile โ€” no restart. | | `commands/*.md` | DSH skill provider | Same, plus user-invocable: `/command-name` works in the slash menu. | | `rules/*.md` | Message-stream injection | Rules are concatenated, wrapped in a `` envelope, and prepended as a user-role message at the front of the message array once per session โ€” the same channel Claude Code uses (`prependUserContext`), which models follow reliably. | | `agents/*.md` | DSH skill provider (delegation shim) | DSH has no markdown subagent format, so each agent file becomes a **skill** whose body leads with an explicit "delegate with this persona" instruction. Model- and user-invocable, so `/agent-name` works. Same-name agents dedupe by rank like skills. | | `.claude/settings.json` โ†’ `hooks` | Tool/prompt hooks | Claude Code hooks subset bridged onto DSH's `tools/pre-execute` (PreToolUse), `tools/post-execute` (PostToolUse) and `agent/pre-step` (UserPromptSubmit) waterfalls. Commands run via `/bin/sh -c` with a Claude-style JSON payload on stdin; exit code 2 denies/blocks, `hookSpecificOutput` overrides are honored, timeouts allow through with a warning. | | `/.mcp.json` | MCP servers | Claude Code-format MCP server definitions are translated to `dsh-mcp-client` plugin instances at DSH startup from the launch workspace: `command` โ†’ stdio, `url` โ†’ streamable-http. Malformed entries or a missing `@deepseek-ai/dsh-mcp-client` degrade to a warning, never a crash. | | `~/.claude/plugins` (installed plugins) | DSH skill provider | Installed Claude Code plugin-marketplace plugins contribute their skills/commands/agents (via each install's `.claude-plugin/plugin.json` manifest, or a directory scan when manifest-less) at rank `750` โ€” the long tail: project `.claude`, DSH native, and `~/.claude` all win collisions. Plugin MCP servers (`mcpServers` in the manifest) mount only when `enablePluginMcp` is opted in โ€” mounting third-party MCP servers is a bigger trust step than listing skills. | The same directories are also read from the **user-level** `~/.claude/` (skills, commands, rules, agents, and `~/.claude/settings.json` hooks). Same-name skills/commands/rules/agents are deduped with a fixed priority: **project `.claude` > DSH native (`.dsh`) > `~/.claude`** - Project `.claude` entries carry rank `50`; DSH's own skills โ€” project `.dsh` roots, `.agents` roots, and bundled skills (ranks `100`โ€“`600`, `BUNDLED_SKILL_RANK`) โ€” sit in between; `~/.claude` entries rank `700`. So a project skill always overrides the DSH-native and user copies, and a user skill never overrides a DSH-native one. - Rule files with the same basename in `~/.claude/rules` are skipped when the project already provides one. `CLAUDE.md` / `AGENTS.md` are **not** touched โ€” DSH's built-in `dsh-agent-instructions` already handles those. ## Built-in commands Installing this plugin adds three management skills to the catalog: | Command | What it does | |---|---| | `/cc-plugin` | Full Claude Code plugin management: `list`, `install [@marketplace]`, `uninstall`, `enable`, `disable`, `update [name]`, `search `, `marketplace list\|add\|remove\|update`. One-shot syntax `/cc-plugin @` installs directly. Engine: the `claude` CLI when available, otherwise a built-in fallback (direct JSON + git, with timestamped backups of every file it touches). All state stays in Claude-native locations (`~/.claude/plugins`, `~/.claude/settings.json` `enabledPlugins`) so Claude Code and DSH read the same truth. | | `/reload-cc-plugins` | Hot-reload the skill catalog: drop cached provider lists and notify observers so newly installed/removed skills appear in the **current session** โ€” no restart, no new session. | | `/reload-skills` | Alias of `/reload-cc-plugins`. | | `/cc-export` | Export DSH-native skills (`.dsh/skills`) into Claude Code `.claude/skills//SKILL.md` with frontmatter preserved. `list` / `export [--overwrite] [--target]`. | | `/cc-resume` | List Claude Code conversation sessions for the current project (`~/.claude/projects/`) and import any of them into DSH with full user/assistant/tool history. Imported sessions appear in the DSH session list titled `cc: ` and resume like native ones. `list` / `import ` / `--limit-turns N` for huge sessions. | Typical loop: `/cc-plugin install ralph-loop@claude-plugins-official` โ†’ `/reload-cc-plugins` โ†’ new skills visible immediately. Plugin-shipped MCP servers still require a DSH restart (process-lifetime mount). ## Requirements - DSH with a profile (e.g. `web`) - A project using Claude Code conventions: `.claude/skills/`, `.claude/commands/`, `.claude/rules/`, `.claude/agents/`, `.claude/settings.json`, and a project-root `.mcp.json` (all optional; `~/.claude/` equivalents are also picked up) - `pnpm` on `PATH` โ€” `dsh plugin` is a thin pnpm forwarder ## Install / Update One command โ€” the package declares `dsh.bundle`, so DSH activates it automatically (no manual `cordis.patch.yml` editing). Install or update to the latest release: ```bash dsh plugin --profile web add dsh-claude-compat@latest ``` Or from GitHub: ```bash dsh plugin --profile web add github:biedongbin/dsh-claude-compat ``` Restart DSH (`dsh web`). Done โ€” skills show up in `/`, rules are injected into every new session. ## Configuration | Option | Default | Description | |---|---|---| | `enableSkills` | `true` | Register the `.claude/skills` + `.claude/commands` + `.claude/agents` provider (project and `~/.claude`) | | `enableRules` | `true` | Inject project + `~/.claude` `rules/*.md` into the message stream | | `enableMcp` | `true` | Translate `/.mcp.json` into mounted MCP server plugins | | `mcpFailOnStartupError` | `false` | Forward to `dsh-mcp-client`: fail plugin startup when an MCP server fails to connect | | `enableHooks` | `true` | Run `.claude/settings.json` hooks (Pre/PostToolUse, UserPromptSubmit) | | `hooksTimeoutMs` | `60000` | Per-hook run timeout (UserPromptSubmit capped at 10s regardless) | | `enableAgents` | `true` | Surface `.claude/agents/*.md` as delegation-shim skills | | `rulesMaxBytes` | `65536` | Hard cap on total injected project rules text | | `userRulesMaxBytes` | `65536` | Hard cap on total injected `~/.claude/rules` text | | `projectRootMarkers` | `[".git"]` | Ancestor markers for project-root discovery | | `skillRank` | `50` | Provider rank for project `.claude` skills (wins every DSH-native collision) | | `skillSource` | `project-claude` | Source tag for project catalog entries | | `userSkillRank` | `700` | Provider rank for `~/.claude` skills (loses to DSH-native `600`) | | `userSkillSource` | `user-claude` | Source tag for `~/.claude` catalog entries | | `userClaudeDir` | `~/.claude` | User-level `.claude` directory (`~` expands to the home dir) | | `enablePlugins` | `true` | Surface skills/commands/agents from installed Claude Code plugins (`~/.claude/plugins`) | | `pluginSkillRank` | `750` | Provider rank for plugin content (the long tail โ€” everything else wins) | | `pluginSkillSource` | `claude-plugin` | Source tag for plugin catalog entries | | `pluginsRoot` | `~/.claude/plugins` | Plugin-marketplace root (`installed_plugins.json` + `cache/`) | | `enablePluginMcp` | `false` | Mount plugin-declared MCP servers (opt-in; requires `enablePlugins` and `enableMcp`) | | `enablePluginManager` | `true` | Register the `/cc-plugin`, `/reload-cc-plugins`, `/reload-skills` management skills | | `pluginManagerRank` | `40` | Rank for the built-in management skills (top of the catalog) | ## Notes - **Skill naming**: DSH requires kebab-case skill names. Nested skill directories are flattened (`gitnexus/gitnexus-guide` โ†’ `gitnexus-gitnexus-guide`); invalid frontmatter names fall back to the directory name. - **MCP lifecycle**: `.mcp.json` is read once at DSH startup from the launch workspace โ€” not per session โ€” and each server mounts for the process lifetime. Restart DSH to pick up edits. - **Hooks scope**: a deliberately small subset of Claude Code hooks: PreToolUse / PostToolUse / UserPromptSubmit. Matchers support exact names, `*` wildcards, and `|` alternation; commands run with `stdin` carrying the Claude-style JSON payload. Exit code 2 = deny (Pre) / block (Post); other non-zero exits and timeouts allow through with a warning. - **Rules granularity**: rules are read per new session (cached per session cwd). Editing a rule mid-session takes effect in the next session. - **Rules content**: rules are injected verbatim as instructions to the model. Only commit rules you want the model to follow โ€” same trust level as `CLAUDE.md`. - **Catalog snapshot timing**: the skill catalog is snapshotted when a session is created. Skills installed or edited mid-session surface after `/reload-cc-plugins` (hot reload) or in the next session. ## Troubleshooting ### Known limitation: `/cc-resume` via the skill tool In some DSH runtime configurations the `skill` tool resolves in an agent-scoped layer where globally registered providers are not visible โ€” the invocation returns `skill "cc-resume" is unknown or no longer available` even though the catalog lists it. This is a DSH runtime layering behavior, not a plugin bug. The skill body only instructs the model to run the CLI, which is always available: ```bash node node_modules/dsh-claude-compat/scripts/cc-resume.mjs list node node_modules/dsh-claude-compat/scripts/cc-resume.mjs import ``` **DSH won't start back up after a restart / port 3080 stuck.** Old process still holding the port (symptom: `EADDRINUSE` in logs). Use the bundled restart script โ€” it waits for a clean stop, falls back to SIGKILL, and verifies the port before reporting success: ```bash npx dsh-claude-compat-restart # bin alias (installed with the package) bash node_modules/dsh-claude-compat/scripts/dsh-restart.sh # direct bash scripts/dsh-restart.sh --no-patch # skip the prompt patch, restart only ``` The script also re-applies the idempotent `dsh-terminal-bash` prompt patch, which npx/npm updates silently revert. `DSH_RESTART_PORT` overrides the port (default 3080). **Installed a plugin via `/cc-plugin` but its skills don't show.** Run `/reload-cc-plugins`. Still missing โ†’ restart DSH (plugin-shipped MCP servers always need a restart). **`/cc-resume` import fails on compression.** The importer needs the `zstd` binary (macOS: `brew install zstd`; most Linux images ship it). **`/cc-plugin` reports "claude CLI unavailable".** The fallback engine handles install/enable/disable; for marketplace add/update, install Claude Code (`npm install -g @anthropic-ai/claude-code`) or manage marketplaces from Claude Code directly. ## Release notes - **[Changelog](CHANGELOG.md) ([็ฎ€ไฝ“ไธญๆ–‡](CHANGELOG.zh-CN.md))** โ€” release history from 0.1.0 to the latest version. ## Acknowledgments - [Linux.do](https://linux.do) โ€” community - [Claude Code](https://claude.com/claude-code) โ€” the `.claude/` conventions this plugin bridges - [DeepSeek Harness](https://www.npmjs.com/package/@deepseek-ai/dsh) โ€” the runtime this plugin extends ## License [MIT](LICENSE) ## ๐Ÿ“ˆ NPM Downloads ![NPM Downloads](.github/assets/downloads.svg) [Data: api.npmjs.org](https://www.npmjs.com/package/dsh-claude-compat) ยท [npmtrends](https://npmtrends.com/dsh-claude-compat/) ## โญ Star History If this project helps you, please give it a โญ โ€” it motivates us to keep improving.

GitHub Stars GitHub Forks GitHub Watchers