Cerbur/clutch-dsh

clutch-dsh-worktree

为 DSH Web UI 增加按 Git Worktree 组织 Session 的视角,同时继续由 DSH 管理原始 Project 和 Session 数据。

Git 与代码评审

English | 简体中文

@cerbur/clutch-dsh-worktree

@cerbur/clutch-dsh-worktree adds a Git Worktree view to the DSH Web UI. It groups Sessions as Workspace → Worktree → Session while keeping DSH as the source of truth for Workspace identity, Session metadata, native lists, messages, and conversation history.

Tool preferences are stored in separate Host-owned files, outside relationship indexes and native Session metadata. The plugin stores Worktree relationships, acquisition facts, shared Worktree instructions, and Workspace-root Main instructions in its own sidecar. Managed Worktrees expose a read-only baseline-relative Git & Changes dashboard, while Local/Main exposes its Workspace-root HEAD history with an optional comparison branch; the plugin does not copy transcripts or rewrite DSH Sessions.

Preview: Worktree Dashboard is an early, plugin-only MVP preview. Worktree navigation, lifecycle actions,
Session actions, Worktree/Main instructions, and the managed Worktree or Main Git & Changes view are connected.
Derived Worktrees and other unfinished actions remain marked
Coming soon.

Installation

After installing into a running DSH instance, restart DSH Desktop, or restart the DSH Web server and refresh the page, to load the plugin Host and permission configuration. Finish active tasks before restarting. If the Client loads while the Host is still unavailable, a native toast reminds you once per Client load. If a Worktree Session permission check reports that Worktree Full Access is unavailable and falls back to workspace-write, a separate once-per-load toast gives the same restart guidance for a recent install or update. The permission recovery message retains this guidance after the toast closes. Network failures, Workspace errors, unverified permissions, and explicit user restrictions do not trigger the missing-preset reminder. The reminder does not reload services or grant Full Access; if the preset remains unavailable after restarting, check the DSH plugin and permission configuration.

Install from npm

With an installed DSH CLI:

dsh plugin --profile web add @cerbur/clutch-dsh-worktree
dsh web

When using a DeepSeek Harness source checkout without a standalone dsh command, use the equivalent pnpm dsh form.

Install from a local checkout

Build this package, build the DSH source checkout, and add the package by absolute path:

cd /absolute/path/to/clutch-dsh
pnpm install
pnpm --filter @cerbur/clutch-dsh-worktree build

cd /absolute/path/to/deepseek-harness
pnpm install
pnpm run build
pnpm dsh plugin --profile web add /absolute/path/to/clutch-dsh/packages/clutch-dsh-worktree
pnpm dsh web

The DSH Web profile must be able to start before this plugin is added. Re-run the absolute-path install command after changing package.json or cordis.patch.yml.

For Desktop, fully quit DeepSeek Harness after active tasks finish, then use the installed DSH CLI:

dsh plugin --profile desktop add /absolute/path/to/clutch-dsh/packages/clutch-dsh-worktree

Reopen Desktop after installation. Keep the local checkout and its installed node_modules available while it is linked; copying only lib/ or removing the checkout's dependencies can cause the Host and permission-preset entries to fail to import. Client implementation dependencies are bundled during the build, so Desktop does not need separate Zustand or Immer modules.

Install from GitHub source (optional)

The package also supports the source dependency form used by the DSH plugin market:

dsh plugin --profile web add "github:Cerbur/clutch-dsh#path:/packages/clutch-dsh-worktree"

This form builds the package during installation. For pnpm build-script authorization and local development details, see docs/DEVELOPMENT.md.

Features

Feature · Preview · What it does Worktree navigation · · Adds a Worktree mode to the native DSH Sidebar. On macOS desktop, the panel shares DSH's native glass material without a second background layer or duplicate navigation showing through. Other platforms retain the theme fill; reduced transparency uses a stronger fill. Workspace expansion and new Session rows use native-style fades and movement. Browse each Workspace through Local/Main and Git Worktree rows, then open the Sessions bound to each row. Create and import Worktrees · · Create a Worktree from a local or fetched remote branch, or register an existing branch-attached Worktree in place. Import does not move, copy, or edit the existing directory. Worktree Dashboard · · The preview Dashboard shows Worktree identity, path, Sessions, Worktree/Main instructions, connected actions, the host-provided Open In action, and the read-only Git & Changes view for managed Worktrees or Main. Derived Worktrees and other unfinished cards remain Coming soon. Agent tool settings (Experimental) · · Choose capabilities for /cluworktree in General, and independently configure automatic injection in Local/Main and managed Worktree Dashboards. Delegated Sessions receive result reporting only by default.

Usage

Open Worktree mode

The Sidebar scrollbar floats over the edge without shifting row spacing. Workspace folders and rotating disclosure triangles match native DSH. An expanded Workspace containing the current Session uses the native blue folder; other Workspace folders use the native gray. Hover over a long Session title or Worktree name to reveal its tail at native speed; leaving restores the start. Reduced motion reveals the tail immediately.

  1. Start DSH Web and select Worktree from the DSH Sidebar footer.
  2. Search or expand a Workspace in the Worktree tree.
  3. Select Local/Main or a Worktree to browse its Sessions. The view is additive; DSH's native

Workspace and Session navigation remains available. Each group initially shows five rows; use Expand more and Collapse for additional rows.

  1. Use Collapse All in the header to collapse other unrelated Workspaces and Worktrees;

the Workspace and Worktree containing the current Session remain expanded.

Collapsing the native Sidebar also hides the Worktree panel on Web and desktop. macOS desktop keeps no collapsed rail; use the native titlebar control to reopen it. Row animation respects reduced motion and settles immediately during search, drag, and initial loading. On Web, Worktree navigation starts below the native DSH brand row, leaving its Sidebar toggle visible and clickable even when the New Session action displays keyboard shortcuts. If the native Sidebar layout cannot be safely recognized, the plugin leaves native navigation visible rather than covering its controls. It retries when the layout changes. Worktree navigation and Dashboard support AppFrame layouts with extra titlebar or shell controls before, between, or after the native columns, while keeping those controls accessible.

Create a Worktree

You can also enable Agent tools with /cluworktree; see the next section.

New Worktree actions use the same branch icon as Worktree rows. The Workspace row button appears on hover, keyboard focus, or while its options menu is open, matching the menu button.

  1. Open the options menu for Local/Main or an active Worktree and choose Create Worktree.
  2. Choose a local or fetched remote base branch and a new local branch name. The dialog suggests an available name.
  3. Confirm the dialog. The plugin creates the Git Worktree, records its acquisition facts, and

continues through the normal Session and binding flow when you open a Session from that Worktree.

The Create and Import tabs share aligned, full-width controls and consistent spacing between fields.

Creation, saved baselines, and Git comparison use the same searchable selector, grouped into Local branches and Remote branches, with current/checked-out markers and filters for all, local, or remote branches. Dropdowns use DSH’s native menu material in light and dark themes. Dropdown lists are compact and prefer opening below the field, shrinking to available space with internal scrolling; they open above only when there is too little useful space below. Search ignores case; use Arrow Up/Down to move, Enter to choose, and Escape to close. Clicking within the dropdown keeps it open, including headings, empty space, search, filters, and fetch controls; selecting an option or clicking outside closes it. Branch and import selectors open immediately while candidates load, show a loading indicator inside, and update in place when data arrives. Search and filters stay intact; refreshes keep existing rows visible. Closing and reopening the baseline editor discards pending results from the previous dialog. Only the latest branch read or Fetch can update its candidates and loading state. Even with cached candidates, the dropdown paints its compact loading shell before preparing the list. The initial shell and loading state keep the same height; ready results size to their content within the scrolling limit. Large lists render only rows near the viewport; search, filters, and keyboard selection still cover every candidate. Switching between Create and Import replaces the form content in the same dialog without replaying its opening animation. Opening any branch selector rereads local Git refs, including changes made in a terminal. Returning to the browser does not reload candidates. Fetch reads the updated list once and supplies it directly to the selector. Opening the New Worktree dialog does not preload branches; its default comes from the current branch or HEAD. The full branch list is loaded only when a picker opens or Fetch completes. Workspace navigation reads Git readiness and the current root-checkout branch separately; entering Git & Changes loads history without preloading branches. The current local branch is preferred by default. Remote refs are read from the local repository. Use the download-arrow button beside Remote branches to fetch all configured remotes, including when the remote list is empty. Fetch updates remote branch refs and refreshes this Workspace; it preserves your current selection, local branches, tags and working files, and does not prune deleted refs. The button shows a loading icon during fetch, then displays Remote branches updated in place for two seconds before restoring the download icon. Failures retain the list and show a retry on the same button; the button details retain the error code, message, and diagnostics, also available in Errors & Repair. no extra status row is added beneath the list. Listing branches never contacts a remote automatically. Remote baselines require a new local branch when creating a Worktree; its short name may match the remote baseline when that local branch does not exist. Symbolic remote HEAD entries are excluded.

Git must have a usable repository and initial commit. Choose a local branch, or choose HEAD to create a new branch from Main's current checkout, including an exact Tag or detached Commit. The localized HEAD option includes the current reference name, for example HEAD (v1.0.0). Creation uses the commit shown when selected. If HEAD changes before submission, creation is rejected with WORKTREE_STATE_CONFLICT; refresh the dialog and select the source again. Main displays the current branch, exact Tag, or short Commit and retains its creation action when detached. If setup is incomplete, DSH shows the relevant readiness message and copyable setup guidance.

When the Workspace is a repository subdirectory, its Worktrees preserve that relative directory. For example, a Workspace at /repo/packages/app uses /packages/app for new Sessions, the Dashboard path, Copy Path, and Open In. Git operations still use the entire checkout. If that directory is missing or resolves outside the checkout, the Worktree needs repair; it does not fall back to the Git root or create the missing directory.

Already-bound Sessions with a legacy Git-root cwd remain usable after a subdirectory upgrade, including automatic tool injection, Session discovery, follow-ups, result reports and default Worktree creation from their own checkout's HEAD. Their original cwd and history remain unchanged; new Session bindings still require the Workspace directory inside the checkout. Git file previews use relative addresses inside the target Session cwd. Files outside that cwd show a prompt to use an IDE or a Session at the repository root; already-bound Git-root Sessions keep their original preview scope.

Enable Agent Worktree tools

Open Settings → Worktree → General and turn on Worktree tools, then select the capabilities you want. Both tool switches start off. Run /cluworktree in a Session belonging to a Workspace or an active managed Worktree to enable your selected capabilities. Turning the general switch off removes the command; deselecting every capability turns the switch off automatically.

For automatic injection, open Dashboard → Settings for Local/Main or a managed Worktree and select capabilities under Automatically inject Worktree tools. Local/Main settings apply only to unbound Sessions in that Workspace root; Worktree settings apply only to Sessions bound to that Worktree. Each configuration is stored separately. Selected tools are assembled before the first model request, including after an Agent restart; ordinary prompt presets also include delegation guidance and, in PTC mode, their SDK. These selections are independent of General: if General selects capabilities 1, 2, 3 and automatic injection selects 2, 3, 4, running /cluworktree adds only capability 1. Already enabled tools remain until that Agent ends; changing preferences affects future injection.

The Worktree entry in Settings uses the same branch icon as the sidebar. Both settings use a card with the main switch at the top. Turning it on reveals tool selections and their descriptions below a divider; turning it off collapses them and retains your selection. Injection and reporting notes sit directly under the tool-selection explanation. The command and automatic-injection settings carry DSH's native Experimental badge. The settings explain each capability in plain language. Command results use DSH's native command presentation and report how many capabilities were added or already available. In a new Session, running /cluworktree immediately opens the conversation page and shows the command outcome, without first sending a message to the model.

With delegation enabled, a request to create a feature Worktree and implement or fix something defaults to creating the Worktree and assigning the work to its own Session. That Session handles code edits, dependency setup and verification; creating the directory alone does not start the task. Guidance prefers the enabled plugin tools over other Worktree/Session tools, while respecting explicit requests to only create a Worktree, work in the current Session or use a different tool.

The six selectable capabilities correspond to these tools:

Tool · Parameters · Behavior clutch_new_worktree · name, optional baseBranch, instructions · Creates a new branch from the calling Session's healthy Worktree branch; Local/Main uses the root checkout's current branch. An explicit local or fetched remote baseBranch overrides this. Returns the acquisition baseBranch and baseCommit. clutch_list_worktrees · optional workspaceId · Lists managed Worktree ids, branches, paths, lifecycle and health, plus available local and fetched remote base branches. Defaults to the calling Workspace. clutch_span_worktree · worktreeId or legacy name, prompt, optional model, title · Creates a fresh native Session, binds it, configures its initial model and submits the prompt. Returns its sessionId and admission status. clutch_list_models · optional provider · Lists native provider/model routes, reasoning efforts and provider failures, alongside the current Session model and deployment default. clutch_list_sessions · optional workspaceId, worktreeId · Finds existing Sessions, binding state, status and title. Unavailable relations return a diagnostic without reading their history. clutch_send_message · sessionId, prompt, optional mode, requestId · Continues an existing Session. queue is the default; steer corrects at a native step boundary. Returns admission, not a reply.

For example, ask the Agent to call clutch_new_worktree({ name: "feature/demo", instructions: "Run tests before finishing." }), then clutch_span_worktree({ worktreeId: created.worktreeId, prompt: "Implement the feature and report the result." }) using the returned Worktree id. The tool name is intentionally clutch_span_worktree. Worktree names are exact Git branch names within the calling Workspace; prefer stable worktreeId for dispatch. Creating a Worktree alone does not create a Session. Only committed state is inherited; staged, unstaged and untracked files are not copied. An unhealthy binding never silently falls back to Main. The default captures the calling checkout's committed HEAD, including a detached root HEAD. Detached sources return baseCommit without inventing a baseBranch; an explicit local or fetched remote baseBranch remains available as an override.

Newly delegated Sessions automatically receive only clutch_report_result({ status, summary, evidence?, requestId? }). The Host fixes the destination to the delegating Session. status is completed, blocked, or failed; summary and evidence are each limited to 2,000 characters. The other six capabilities require /cluworktree or the Worktree's explicit automatic-injection selection. Reports arrive as ordinary queued native messages; verify their claims and evidence before accepting completion. Reports are model-driven: a crash, stopped Agent or unanswered human approval may prevent reporting. idle is not success.

Reporting is limited to the active delegated task. One successfully admitted completed, blocked, or failed report consumes and clears its in-memory token. The reporting tool, SDK and guidance stay stable; calls without a token are rejected. Later user input clears any remaining token; it does not report to the former parent. An explicit new clutch_send_message dispatch from that parent opens reporting again after its prompt is consumed. Uncertain report admission permits only an identical retry with the returned requestId. Tokens are never persisted and are lost on Agent/plugin restart. Dispatch retry identities are retained in a bounded in-memory cache; expired retries fail explicitly instead of reopening reporting. The plugin rejects self/ancestor messages and blocks further message/task dispatch from turns triggered solely by reports or ordinary plugin messages. New human input permits dispatch again; these guards apply to this plugin's tools in both native and PTC modes.

clutch_read_session and clutch_wait_sessions are removed from the model catalog. Do not poll lists or read raw Session logs for progress. After successful dispatch or follow-up admission, acknowledge dispatch and end the turn, waiting for the executing Session's pushed report. Continue only separate independent work already requested by the user. Do not check the delegated task through agent lists, terminal commands, Git, files or tests, and do not edit or commit it yourself. An explicit user progress/investigation request or a concrete admission failure permits a targeted action. Evaluate a report's supplied evidence rather than automatically rerunning checks; investigate only when requested or when the evidence has a concrete gap or inconsistency. Complete prompt presets such as minimal omit extra prompt sections; critical handoff and model-selection rules also appear in native tool descriptions, preserving that preset's complete prompt. Activation adds Agent-scoped guidance for choosing delegation from ordinary task descriptions, so users need not specify tool names. Schemas describe exact ids, defaults and target alternatives without $schema; errors explain the cause, correction and a valid invocation. A bad Session history returns one unavailable diagnostic while keeping healthy list entries available.

In PTC mode, t