@norman-else/dsh-claude
将本地 Claude Code 运行为原生对话提供者 适合希望在 DSH 界面中直接调用本地 Claude Code 代理循环的用户。
安裝
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:Norman-else/dsh-claude說明文件
閱讀完整 README ↗dsh-claude
1. Overview
dsh-claude runs the locally installed Claude Code CLI as a first-class conversation provider inside DeepSeek Harness (DSH). It uses Claude Code's official Agent SDK protocol instead of recreating the agent with a separate API client.
Claude Code remains responsible for its agent loop, tools, CLAUDE.md, Skills, Hooks, Plugins, MCP servers, settings, and authentication. DSH provides the conversation UI, approval and question surfaces, repository workflow, activity presentation, and managed process lifetime.
2. Installation and removal
Requirements
- DeepSeek Harness Desktop with compatible public plugin APIs. This package is currently developed against the DSH
0.1.7-rc.2package line (DSH Desktop 2.0.15) and requires it: 0.1.7 replaced directory-scanned presets with declared ones and renamed the shared icons. A Host still on0.1.5must pin@norman-else/dsh-claude@0.1.57; plugin 0.1.37 and later import symbols that do not exist on0.1.1-rc.2, so a Host on that line must pin@norman-else/dsh-claude@0.1.36. - A local Claude Code installation that is already authenticated.
- Node.js 20 or later when installing from a source checkout.
The plugin never asks for or stores Claude credentials. Authenticate through the local Claude Code CLI before using the plugin.
Install from npm
Add the published package to the profile used by your running DSH instance. The commands below use desktop; replace it with web only for an existing Web profile. Use the DSH CLI supplied by that installation:
dsh plugin --profile desktop add @norman-else/dsh-claude
Wait for the profile rebuild to finish, then quit DSH Desktop completely and reopen it. Create a new conversation and select Claude from the Agent Preset picker.
Install from source
git clone https://github.com/Norman-else/dsh-claude.git
cd dsh-claude
pnpm install
pnpm check
For a checkout already linked to a running Desktop, run builds only after its turns have finished: rebuilding can hot-reload the plugin. Use a separate source copy for validation during active work. See INSTALL.md.
Link the checkout to DSH from PowerShell:
dsh plugin --profile desktop add "link:$($PWD.Path.Replace('\', '/'))"
Or from macOS/Linux:
dsh plugin --profile desktop add "link:$(pwd)"
Remove the plugin
The Claude preset is declared by the package's bundle patch, so removing the package removes it:
dsh plugin --profile desktop remove @norman-else/dsh-claude
Plugin 0.1.57 and earlier also copied a compatibility preset to $DSH_HOME/.agent-presets/claude. Host 0.1.7 no longer reads that directory; remove the leftover copy with:
dsh plugin --profile desktop exec dsh-claude remove-preset
Cleanup removes only installer-written content and refuses to delete user-modified preset files.
3. Features
3.1 Conversation
- Native Claude Code conversations — Runs Claude Code as the main agent in a normal DSH conversation instead of wrapping it as a tool or secondary chat.
- Claude preset and model selection — Adds a
ClaudeAgent Preset and reads Claude Code's model catalog.default,opus[1m],fable,sonnet, andhaikuare fallback choices when the catalog is unavailable. - Thinking effort — Maps DSH's per-model reasoning effort onto Claude Code's thinking modes —
off,low,medium,high(Claude Code's own default),xhigh,max, andultracode— so the conversation's effort control drives extended thinking directly. Models that do not support a mode downgrade silently inside Claude Code;ultracodeadditionally turns on standing dynamic-workflow orchestration and needs anxhigh-capable model. - Local Claude environment compatibility — Preserves the user's existing Claude Code authentication, settings,
CLAUDE.md, Skills, Hooks, Plugins, tools, and MCP configuration. - Real-time streaming and conversation continuity — Streams Claude responses and tool activity into DSH while retaining multi-turn context and persisted Claude session resume.
- DSH permissions and questions — Routes Claude tool permission requests through DSH approvals and Claude clarification prompts through DSH's native question forms.
- Claude Code permission modes — Behind a Permission selector setting (Plugin, or DSH native to keep the Host's three-mode control and the plain sandbox mapping), replaces DSH's three-mode access selector, for Claude sessions only, with Claude Code's own modes in the same seat of the composer's tool row: Plan, Default, Accept edits, Don't ask, Auto, and Bypass permissions, each with its own glyph, bilingual name, and description; Auto is greyed out while the catalog says the session's model cannot run it, and an ask its classifier escalates reaches the DSH approval dialog with the classifier's reason under the title. The choice is the plugin's own per-session record and is what the next turn runs under; the DSH sandbox mode and approval policy are moved onto the preset that mode is carried on, so approvals and the sandbox follow without the Host learning any new modes. Bypass asks for an acknowledged confirmation first, the control locks while a turn is running, and a sandbox switched natively afterwards (the
/permissioncommand) wins over the recorded choice, so DSH's own knobs are never contradicted. The Host's selector is hidden with a scoped CSS rule rather than replaced, since it is not a slot; a Host that renames it simply shows both. A new Claude session starts in the Default permission mode from this plugin's Settings, Auto unless changed: the DSH access preset is moved onto the sandbox that mode needs as the session is created, so a Host whose own default preset is full access does not turn it into Bypass. - Plan review — Under read-only access Claude works in plan mode, and the plan it hands back is read in a plugin-owned panel in a right-sidebar tab, rendered as Markdown under the prose palette chosen in this plugin's settings. The approval itself stays with DSH: its dialog names the decision and points at the panel instead of pasting the plan into a plain-text modal, and it is asked even under Full access — that setting waives actions, not the decision the plan was written to put in front of the user. Full access silences approvals outright (
approval/policy: never, answered before any surface is shown), so the ask is un-silenced for as long as the plan is open and the session's own policy is put back afterwards. Approving and rejecting are the only answers the dialog has, and neither is "change this", so the panel adds the third: select a passage, write what should change, and send the plan back — the notes reach Claude as the reason it was refused, and the dialog closes itself. A session that proposes more than once keeps every plan: the panel heading becomes a picker listing each with its own decision, and a fresh proposal awaiting approval takes the panel back. The Session header carries a plan toggle, dotted while a plan is still waiting on its decision, and the turn's tool card carries the same plan. - Claude command bridge — Publishes Claude Code's own command catalog into the DSH command palette, retrying with backoff while a fresh CLI finishes loading Skills and Plugins.
- Prompt suggestions — After each turn Claude Code guesses the next prompt; the composer shows it as grey text after whatever has been typed, and Tab (or → at the end of the draft) accepts it. It disappears as soon as the draft stops matching, and when the next turn starts.
- Prompt snippets — Keeps the half-written messages a user retypes every day as ordinary Markdown files in
~/.claude/prompts, one per file, and offers them as a second/group beside the Claude command catalog. Picking one drops its text into the composer instead of sending it, so the draft stays editable — a snippet is a message the user finishes, not a command that runs. A control in the composer's own tool row, beside the attach and access controls, saves the current draft as a new snippet: it offers the draft's opening line as the file name and names the file it wrote. With an empty draft the same control lists the saved snippets instead, each deletable after a confirm. It costs the layout nothing — a docked row would move the composer on every keystroke — and an existing name is never overwritten. The derived name is only the starting point: a Claude Haiku call names the snippet properly and replaces it when it lands, unless the user has already started typing, and a failed or slow suggestion is a non-event because a working name was there from the first frame. That call runs with extended thinking off, which is what keeps it around three seconds rather than ten. - Rewrite a draft with AI — A second control in the same tool row hands the current draft to Claude Haiku and replaces it with a version an agent can act on without asking follow-up questions, keeping every concrete detail the original carried.
SessionInput.setDraftmerges into the editor's undo history rather than adding a step to it, so Ctrl/Cmd+Z would not bring the original back: the button holds it instead, and offers it back for as long as the rewrite is still on screen unedited. The rewrite is told to leave every reference to a person as written — asked to rewrite "assign it to me", the model otherwise reaches into Claude Code's ambient context and substitutes the operator's real email address. Editing, renaming, and deleting happen in the user's own editor, and a file added there shows up in the menu without a reload. - Message queue and steering — Accepts further messages while a turn is running, and lets a queued message be edited, removed, or steered into the turn already in flight. Steering reaches the turn the way Claude Code's own does: the message is pushed into the CLI's input stream and read at its next model step, so the turn keeps running with everything it already holds instead of waiting for the end and arriving as a follow-up. The transcript draws it where it arrived, between the work before it and the work after it — DSH's own surface takes one node per turn for this preset, so a message recorded there would sit above everything the turn did and read as the question the whole answer was for. A message with attachments travels the same path an ordinary send takes, and one that arrives with no turn left to steer stays queued for the next one. Plain Enter while a turn runs queues a follow-up unless the Host's busy-Enter setting is set to steer; the queue strip's own steer action always steers. Another plugin can reach the same entry point through the
claudeSteeringservice. - Rewind — Drops a message and everything after it: Claude resumes from the kept turn's transcript anchor and genuinely forgets the discarded turns, the discarded rows are hidden from the append-only DSH log, and the original text returns to the composer for editing and resending. Every turn is admitted against a captured working tree, so the same rewind optionally puts the checkout back to where the discarded turns found it — files created since are removed, changed files are restored, and files
.gitignorecovers are left alone. - Ask about a selection — Answers a question about any selected text through a read-only side query limited to
Read,Grep, andGlob, reusing the session's model and thinking mode, with the answer copyable or sendable into the main conversation. - Redacted activity timeline — Displays thinking summaries, tool calls and results, permission events, questions, status changes, usage, errors, and subagent activity without persisting credentials.
- Selectable AI output renderer — Draws Claude's output either with this plugin's own transcript (interleaved prose, grouped tool cards, activity rows) or with DSH's native conversation renderer, where prose arrives as ordinary assistant text blocks, thinking as reasoning blocks, and root Claude tools as native tool cards (terminal, diff, search, read). Chosen in Settings and applied from the next turn; the plugin transcript remains the default, and turns already recorded keep the renderer that drew them.
- Automatic session titles and branch names — Uses separate one-turn Haiku queries to summarize the first message or worktree intent. Both load
user,project, andlocalsettings like the main conversation, including settings-based authentication and behavior configuration. An error result keeps DSH's fallback title or the generated timestamped branch name. These queries do not borrow the main conversation process. - Background task tracking — Claude subagents and background commands appear in DSH's own session-header job list with live output, progress, and a stop button.
- Agent Team — Claude Code's implicit team (named agents, the shared task list, and mail between members) gets a session-header roster and a per-teammate conversation tab, mirroring DSH's own Agent Team UI.
- Context usage — Collects aggregate context-window usage from Claude Code and shows it on the session board. It does not register a separate context-meter slot beside the model selector.
- Turn accounting — Closes each turn the plugin transcript drew with the footer DSH gives only its own messages: tokens, cache hit rate, wall time, time to first token, and cumulative cost. The timings are measured as the turn runs, because activity records carry no clock of their own.
- Managed process lifecycle — Keeps one live Claude process per active session, serializes turns, evicts idle processes, queues user turns FIFO when every process slot is busy, converges safely after the limit is lowered, and handles Stop, cancellation, restart, and process-tree cleanup.
- Bilingual interface — Ships every user-facing string in both English and Chinese.
3.2 Repository, worktrees, and pull requests
- Repository and worktree preparation — Lets a user choose a branch before submitting, switch an eligible local branch, or create a dedicated Git worktree and DSH workspace while transferring the current draft and attachments, and reconciles plugin-managed worktrees after their workspace is deleted. That deletion can remove a dirty worktree with
--force; commit or preserve needed files before deleting the workspace. The separate merged-branch cleanup action requires a clean tree and checks for unpushed commits. New worktrees live under the repository's.claude/worktrees(kept out ofgit statusthrough the local.git/info/exclude), so with the sidebar set to Workspace tree each worktree session shows nested under its repository. - Branch picker — Lists the repository's local and remote-tracking branches, filters them as the user types, and refreshes from the remote on demand so a branch created elsewhere becomes selectable without leaving DSH.
- Jira-driven sessions — Connects to Jira Cloud and starts work from a ticket: the branch is named after the ticket key, the composer is seeded with the ticket brief, the ticket is assigned to the user once the worktree exists, and several tickets can be kicked off at once, each in its own worktree session.
- Repository and pull request status — Shows the current repository, branch, worktree state, changed-line counts, unpushed commits, GitHub pull request, checks, review state, merge state, and blocking Claude rate limits near the composer.
- Session board — Summarizes every Claude session in one place with its run state, branch, pull request, context usage, auto-fix state, and whether it is waiting on an approval or an answer.
- Session alerts — Raises a desktop notification when a session the user is not looking at starts waiting on an approval or an answer, or finishes its turn; clicking it brings that session up. The session on screen never raises one, a prompt is announ