Workbench Development Standard
Version: 2026-10-27 · The website is authoritative; DSH Desktop bundles a copy for offline use.
Official page: https://dshdesktop.com/workbench/docs/development-en/
Markdown source for agents: https://dshdesktop.com/workbench/docs/development-en.md
Six-step quickstart: https://dshdesktop.com/workbench/docs/quickstart-en/ (Markdown). 中文版.
This standard is intended for direct execution by an AI developing a workbench. For local development and personal use, this document is sufficient: build the package under Section 3, install it in the local DSH Desktop, and pass the Section 8 self-test. There is no requirement to publish code or upload anything.
If the author later wants to list the workbench in the Workbench Market, also read the Workbench Market Acceptance Standard. Its separate rules cover a public repository, releases, descriptions, screenshots, and listing PRs.
A workbench is a DSH plugin. It must first be a valid DSH plugin package that dsh plugin add can install and Harness can load. It then registers a business panel with Desktop and follows the rules for workbenches, sessions, and workspaces.
Rule levels are required (failure prevents installation or loading), recommended (strongly advised for usability and future listing), and optional.
1. Execution principles
Standard retrieval order: Before development, actually fetch and read the complete online Markdown above and record its URL and document version; prior knowledge or bundled documents do not count. Use a bundled offline copy only if online retrieval fails, and report the failure reason, offline source, and version. Offline copies are packaged snapshots, may be outdated, and must never silently replace the online standard. If the latest standard conflicts with the running version, explain capability differences and blocked steps; do not override it with an older standard.
Communication with users: Use business language for requirements discovery, layout suggestions, confirmation choices, and installation or completion status, such as “Show the business content on a full page and open AI conversation when needed” or “Talk while viewing supporting information.” Do not ask ordinary users to confirm code fields such as customFrame, register(), repository, dshHomePath, or reconcileLocalProviders, internal identities, or placeholder repository URLs; do not present lengthy implementation details as choices. The Agent handles technical fields during development under this standard. Missing publication identity must not block confirmed local development, and a real repository must never be fabricated. Ask only for practical information affecting the business or installation, such as “Which folder should hold the data?” Explain technical details briefly when the user asks. Lead completion reports with what works, actual operations tested, and items still pending verification; put changed files and technical checks in a short appendix, then end with the usage handoff required below.
After every workbench development handoff, the final response must end with a prominent three-point “What to do next” block, after all change descriptions, self-test results, file links, and technical appendices. Do not leave the reminder only at the beginning, and do not append any content after these three points:
- Development result: Use the actual workbench name and state the development and installation status. Say “Developed and installed locally” only when both actually succeeded; if development is incomplete or installation failed, explain the blocker honestly. Do not claim it loaded or all acceptance checks passed.
- How to restart: When installation succeeded and a restart is needed, ask the user to wait until the current task finishes, then click “Restart now” in the top banner or choose Harness → Restart Harness; normally only Harness needs restarting, without quitting DSH Desktop. Suggest fully quitting and reopening DSH Desktop only if Harness restart does not load the workbench and troubleshooting confirms this is needed. Do not close or restart the app the user is working in yourself. If no restart is needed or installation is incomplete, say so; do not present restarting as a fix for failed installation.
- Where to open it: After restarting, expand the sidebar and use the current name / switch area beside “Workbenches” at the upper left to select the newly created workbench (give its actual name). If missing, go to Workbench Market → Installed, find the entry marked “Local,” and check its running state; switch after it loads or is enabled. The user can try it directly, or optionally return to the original conversation and say “Restart complete” for continued verification; returning to the conversation is not required to use it. If installation is incomplete, state that this entry remains unconfirmed until installation and loading succeed.
Requirements conversation (before code): Discover the workbench through progressive conversation, asking only one necessary question at a time that affects the next step. Reuse the current request and confirmed context; do not repeat information the user already provided. If the name is unknown, first ask “What would you like to call this workbench?” A provisional name is fine and naming must not block implementation. Then fill gaps about the intended users, main functions, or business scenario as needed, without a fixed questionnaire or several questions bundled together. If the user cannot describe the core workflow, suggest a minimal flow based on their answers and ask them to confirm or adjust it; do not require a complete requirements form. Start once the business goal and smallest implementation scope are sufficiently clear and confirmed, without filling every formal field. Generic development instructions, directory names, existing code, or dependencies do not establish intent by themselves. While business intent or implementation scope remains unclear, wait for the current answer. Read-only checks of directories, versions, scripts, and host capabilities are allowed; creating or editing business code, UI, or package files, building, packing, installing, or submitting are not.
Once requirements are clear, read project name, author, version, description, and test commands from the project; ask only for necessary information that cannot be found and affects implementation. A development request does not authorize publication of code, business data, or credentials.
Before development, check:
- Project root, existing code, uncommitted changes, package manager, scripts, and target Desktop version. Do not overwrite others' changes.
- Target platform and architecture; distinguish JS/TS packages, external programs, and native dependencies. If the host or toolchain is missing, say so; a successful build alone does not prove the workbench runs.
One-page execution flow
- Confirm requirements: Reuse confirmed information and ask only one necessary follow-up at a time. Names may be provisional; suggest and confirm the flow. Start when the business goal and minimal scope are clear, without requiring every field. Generic instructions or a directory alone are not confirmation.
- Inspect project: Identify root; run
pwdand, for a Git repository,git status --short; inspect code, package manager, uncommitted work, and target Desktop version. Preserve unrelated changes. - Define the smallest business flow and layout: Write down entry point, main action, completion state, and failure recovery. Under Section 4, choose a standard split or
customFrameand define the first-use path without a session before choosing host capabilities. - Implement: Create the plugin package and registration under Section 3; follow Sections 4–7 for applicable responsibilities and capabilities.
- Verify package: Run
pnpm pack; inspectpackage.json, declared entries,cordis.patch.yml, size, and sensitive files inside the tarball. - Install and test locally: Check installation capabilities under Section 3.6, install that tarball, complete the required restart, and record real UI and loading evidence under Section 8. If the agent runs inside the target DSH Desktop, ask the user to restart it manually under the boundary below.
After building and verifying the archive, the model calls install_local_workbench({ path: "<absolute local .tgz path>", replace: false }) directly. This uses Plugin Manager installBundle; users do not enter paths or operate an installation page. Pass replace: true only for an authorized update of the same workbench. Inspect application: verify the UI for applied; only restart-required calls for restarting Harness. Failed, cancelled and overridden do not mean applied.
Restart boundary inside the target app: Do not close or restart DSH Desktop or Harness yourself or use process probes such as ps or pgrep to manage the restart; ask the user to restart manually. After the user restarts Harness, offer two optional paths: (1) Try it directly: expand the sidebar, click the current workbench name / switch area to the right of “Workbenches” at the upper left, and select the new workbench. If it is missing, check its entry and running state in Workbench Market → Installed, then switch after it loads or is enabled. New local workbenches are added to the switch menu automatically when loaded; there is no separate “Add” button. (2) Continue Agent verification: return to the original development conversation and tell the Agent “Restart complete”; the Agent then follows Section 8 to check loading, the installed list, the switch entry, and the real business UI. Users may try it independently without returning to the conversation. Checks the Agent has not actually performed remain pending verification; installation success does not mean all acceptance checks passed. An Agent outside the target app may follow the normal restart process.
Empty-directory exercise: If the directory is empty and the user only pasted generic development instructions or said “make a workbench,” reuse any context already provided. If the name is unknown, ask only “What would you like to call this workbench?” and allow a provisional name. On the next turn, ask the one business question that most affects implementation, such as “What should it mainly help you do?” If the purpose is already clear, skip that question and suggest a minimal flow for confirmation. Read-only directory and Desktop capability checks are allowed. Until the business goal and scope are sufficiently clear, do not create package files, business code, or pages, or build, install, or submit. A name alone is not a business brief.
2. What a workbench is
A workbench package is simultaneously:
- An npm package with
nameandversion, installable from a local directory or.tgz, and after listing potentially from npm or GitHub. - A DSH plugin (bundle) whose
package.jsondeclaresdsh.bundle.patch;cordis.patch.ymlinserts the server entry into the Harness plugin tree. - A Desktop workbench whose client calls
desktopWorkbenches.register()to register a business panel. When a local package omitsrepository, Desktop derives a stable local identity from the actual calling client npm package name; valid existing repository identities are retained.
The following identifiers have distinct purposes and must not be conflated:
| Identifier | Location | Purpose |
|---|---|---|
| npm package name | package.json name | Installation, dependency resolution, cordis.patch.yml name: |
| Plugin entry ID | id of an insert row in cordis.patch.yml | Locate that row in the Harness plugin tree |
| Local workbench identity | Derived by the host from the actual client npm package name | local:<npm package name>, such as local:my-workbench-package or local:@scope/name; shared by sidebar entry and session ownership |
| Repository workbench identity | Valid GitHub repository URL, market entry id, and existing attribution records | Lowercase owner/repository; existing identities stay compatible, shared by market card, sidebar entry, and session ownership |
| Legacy ID for compatibility | Old register({ id }) and catalog workbenchId | Migration of old data only; omit from new packages and submissions |
Local development, installation, and use require no GitHub account, repository URL, repository creation, or code upload. Never fill a fabricated or placeholder repository. The host uses actual client package provenance; authors must not supply a local ID manually. Version upgrades and project-directory moves preserve local identity; renaming the npm package creates a new identity. Later market publication does not automatically migrate local sessions or silently replace local identity. Migration must be explicitly designed and confirmed; this standard provides no automatic local-to-market migration.
Desktop lowercases GitHub owner and repository, so https://github.com/Owner/Repo corresponds to owner/repo. A rename or transfer changes workbench identity; migrate existing sessions under the migration rules rather than changing only the URL. The legacy wb-owner-repo is only a compatibility mapping, not a registration ID for new packages.
3. Package format
3.1 Layout
Put one workbench in one package. Typical structure:
package.json # npm and DSH plugin declaration
cordis.patch.yml # insert the server entry in the plugin tree
dsh/index.js # server entry (exports["."])
lib/client.js # built client entry (exports["./client"])
README.md LICENSE
3.2 package.json
| Field | Level | Requirement |
|---|---|---|
name, version | Required | Normal npm fields; version is full SemVer such as 1.2.0 |
"type": "module" | Recommended | All official examples use ES modules |
main and exports["."] | Required | Point to the server entry imported by cordis.patch.yml |
dsh.bundle.patch | Required | For example "dsh": { "bundle": { "patch": "./cordis.patch.yml" } }, relative to package root. Without it, the package is an ordinary dependency and no plugin layer activates |
dsh.client.platform | Required | Must be "web", or the client module will not load |
dsh.client.inject | Required | String array that must contain dsh-desktop-workbenches so its service loads before the client; list other client packages used. This controls load order, not Cordis service injection |
exports["./client"] | Required | A declared dsh.client must export the built client file, or startup fails |
dsh.client.external | Optional | List modules (including subpaths) required by the client beyond the shared baseline; do not list itself |
exports["./package.json"], exports["./cordis.patch.yml"] | Recommended | Match official packages |
files | Recommended | Include cordis.patch.yml, server entry, and built output |
peerDependencies | Recommended | Put official @deepseek-ai/* packages such as @deepseek-ai/cordis and @deepseek-ai/dsh-client-connection here, not in dependencies, to avoid a second copy of host code. Explicitly include prereleases, for example ">=0.1.5-rc.2 <0.2.0-0", or prerelease Harness versions are excluded and installation fails with ERESOLVE |
@deepseek-ai/schemastery | Recommended | Used to define server Config; it is a runtime dependency |
license, author, description | Recommended | Provide truthful values |
Do not rely on undocumented dsh fields such as dsh.client.inline; they are silently ignored.
3.3 cordis.patch.yml
This file is a YAML array. A workbench normally needs one insert:
- insert:
- id: my-workbench # plugin entry ID
name: my-workbench-package # npm package name, so Node can resolve installed code
config:
root: !!js dshHomePath('my-workbench') # optional business data directory
- Required:
nameis the package name, never a relative or absolute path. - An empty or comment-only file fails startup; write
[]if no rows are needed. !!jsexpressions evaluate at startup.dshHomePath()yields a path under the DSH data directory.- When overriding an existing row, the patch replaces the whole
config, rather than merging it. Include all keys that must remain. A workbench should not override Desktop or another plugin's rows.
3.4 Server entry
import Schema from '@deepseek-ai/schemastery'
export const name = 'my-workbench'
export const inject = ['connection']
export const Config = Schema.object({ root: Schema.string().required() })
export function apply(ctx, config) {
// Register local endpoints under this workbench, e.g. /api/my-workbench/...
}
Configmust be a Schemastery schema, not a plain exported object.- Put local endpoints under the workbench's own prefix, such as
/api/<workbench-id>/, never under Desktop's or another plugin's paths. - To determine session ownership, inject the internal read-only
desktopWorkbenchOwnershipservice and callawait read(); do not infer it from the visible panel, an old preset, or private settings. - Write business data in the configured data directory or the location explained in author documentation. Uninstall must not delete user data.
3.5 Client entry
The client file must be a built single-file module registered through the module loader:
window.__ModuleLoader__.load({
id: 'my-workbench-package',
factory: (require) => {
const React = require('react')
function BusinessPanel({ service, entry }) { /* business panel */ }
function apply(ctx) {
ctx.effect(() => ctx.desktopWorkbenches.register({
title: 'My Workbench',
description: 'Describe the problem it solves'
}, BusinessPanel))
}
return { apply, inject: ['desktopWorkbenches'] }
}
})
requirecan access only the shared baseline (React, Cordis, etc.), loaded plugins, and modules listed indsh.client.external. Bundle other dependencies into the client file at build time.register()must provide atitleand business component. For local development, omitrepositoryby default; the host deriveslocal:<npm package name>from the actual calling client package. New packages must not specifyregister({ id }). Valid existing repository attribution keepsowner/repo; source conflicts must not fall back to another identity. Legacyidis only for compatibility migration.- Only when preparing a market submission with a real repository, separately add
repository: 'https://github.com/your-org/your-workbench'. It is not a prerequisite for local installation. Do not skipregister()becauserepositoryis absent. - On registration failure, Workbench management shows the package name, failure stage, and reason, and the console emits a warning. A successful reload after fixing the issue clears the corresponding diagnostic. If the client has not executed or dependencies are missing, investigate that loading stage; a missing entry alone does not establish identity failure.
workbench.jsonand submission YAMLworkbenchIdare not required for new workbenches. The runtime package name must correspond towindow.__ModuleLoader__.load({ id }).- Optional registration fields:
description,panelTitle,icon,audience,requirements,layout(businessSideisleftorright;businessWidthis 0.25–0.7),customFrame(boolean; Section 4),headerLayout(Section 4), andinitialization. - Give the unregister function returned by registration to
ctx.effect.
3.6 Build and local installation
- The client file must already be built as a single file. Desktop does not build it for you.
- Detect capabilities first: record Desktop version, platform and architecture, and check whether this session exposes
install_local_workbench. Publication dates do not prove installed-version support. - After building and verifying the archive, the model calls
install_local_workbench({ path: "<absolute local .tgz path>", replace: false })directly. This uses Plugin ManagerinstallBundle; users do not enter paths or operate an installation page. Passreplace: trueonly for an authorized update of the same workbench. Inspectapplication: verify the UI forapplied; onlyrestart-requiredcalls for restarting Harness. Failed, cancelled and overridden do not mean applied. - The tool follows host plugin-management permissions: it executes directly with full access, otherwise uses the existing approval flow. Never bypass a refusal via CLI. Pass
approvedBuildsnames frompendingBuildsonly after explicit build-script approval. Only when an older version lacks this tool, inspect actualdsh plugin --helpand use its supporteddsh plugin addflow, verifying installation, any required restart and loading separately. Do not call a nonexistent HTTP install API. - If neither tool nor CLI is available, or installation fails, deliver the verified archive and record the failure and untested steps; do not claim successful loading.
- If installation or build scripts need to run (pnpm 10 blocks them by default), understand each script and obtain separate authorization.
4. UI boundary
A workbench is a plugin for a specific business scenario. This standard governs its relationship and switching behavior with sessions and workspaces; it does not prescribe a uniform business panel design.
Authors or users may define business panel layout, content, toolbar, and operations. When integrating an existing workbench, reuse its existing UI and business binding flow where possible. A universal top toolbar, session dropdown, business-area collapse control, or “generic chat” button is not required.
4.1 Choose the layout for the primary task
When advising the user, say: “I suggest showing the business content on a full page and opening AI conversation when needed. If talking with AI is your main task, you can talk while viewing supporting information.” Confirm the experience tradeoff only; the Agent implements the APIs and layout parameters below rather than presenting them as confirmation choices.
Do not treat a persistent conversation pane as the default product design for every workbench. Confirm the user's primary task first; when requirements are unclear, suggest a business-first full page or a conversation split and explain the tradeoffs. Omitting customFrame still selects the standard split technically, but authors should choose deliberately rather than inherit that default.
- Business-first full page with conversation on demand (
customFrame: true): For content review, renovation management, reports, dashboards, or wide tables, recommend a usable business home first. Decide whether and where a conversation entry belongs based on the task; a permanent entry or reserved chat pane is not required for every workbench. Create or restore a workbench session and show the conversation only when the user explicitly requests AI help; closing it returns to the business view. Place the host-providedconversationnode when needed; do not duplicate the chat UI. This mode does not show the host's generic no-session guidance. Design the first-entry and no-session business states yourself. Do not automatically create a session on first entry to fill the interface. - Standard split: Use when conversation is the primary task and the business content is a compact companion tool, status panel, or reference. By default, the host native conversation is on the left and the business panel occupies 36% of the main content area on the right. In
register(),layoutmay setbusinessSide: 'left' | 'right'andbusinessWidth: 0.25–0.7; this proportion does not guarantee enough space for every column inside the business panel. When no session is bound to the current workbench, the host shows optional AI-help guidance in the conversation area. The business panel must remain usable, and independent business actions must not require creating a session first. Do not simply enlargebusinessWidthto squeeze a report into the split at the expense of the guidance or conversation.
In either layout, make the business UI respond to the actual width of its own container. Window-wide media queries alone do not reflect the space left by the sidebar, split, or embedding. Use container queries or measure the business root; rearrange columns, collapse secondary information, or provide bounded scrolling when space is tight. Long Chinese headings, English identifiers, numbers, and action buttons must stay readable and usable, without single-character vertical wrapping, clipped controls, or page-wide horizontal overflow.
DSH reserves shared entrances for the market, workbench switcher, and settings; the business panel must not cover them. A customFrame (Section 3.5) must stay within the host-assigned main content area. Its root should fill that area using normal flex layout. Internal absolute positioning, maximization, or drag-based repositioning must remain inside the host container's positioning and clipping boundaries, never cover Desktop's left session sidebar. Put the host-provided conversation node into the business layout for native sessions; do not build a second chat UI. Native conversation capabilities and mode switching continue to follow Desktop rules.
Header layout: default and compact
register() accepts headerLayout: 'default' | 'compact'; omission means default and other values fail registration. With the sidebar expanded, the host preserves the existing layout and adds no blank row. It makes only unoccupied pieces of the existing top band (--dsh-frame-top-clearance, normally 48px) draggable, subtracting actual rectangles for controls, menus, iframes and custom data-dsh-no-drag areas. Default mode reserves a separate system-controls row only on macOS outside fullscreen with the sidebar collapsed; business content starts below it regardless of nested header markup. Windows keeps its separate title bar; fullscreen adds no row. Existing providers default to this mode. The host does not infer the first <header> as a toolbar or clear provider-owned heading padding.
Any customFrame: true provider, or a standard split with layout.businessSide: 'left' (embedded is not required), can opt into compact mode:
ctx.desktopWorkbenches.register({
title: 'Business tool',
customFrame: true, headerLayout: 'compact'
}, BusinessPanel)
// Exactly one same-document toolbar rendered by BusinessPanel:
React.createElement('header', { 'data-dsh-workbench-toolbar': '' },
React.createElement('span', null, 'Business tool'),
React.createElement('button', { onClick: refresh }, 'Refresh'))
Ordinary left splits retain their side and bottom content gutters. Only valid compact mode removes the top gutter and makes the toolbar sticky while content scrolls. Toolbar ancestors must span the content height, without extra top margin/padding or an independent scroll container.
The marked toolbar must be the top row and span the host content width; nested wrappers are supported. For ordinary left splits, the host uses existing blank space above the right conversation without adding a row. For custom frames the toolbar must span the entire custom frame, including the conversation area, rather than only a business subpanel. The host sets minimum row height and leading clearance, makes blank space draggable, and excludes buttons, links, form controls and standard interactive roles. Add data-dsh-no-drag to custom interactions, expanded menus and popovers. data-dsh-compact-toolbar and data-dsh-compact-valid are host-owned internal markers. Do not duplicate system-controls padding or override the entire drag/no-drag policy.
Missing or multiple markers, right-side splits safely fall back to the default row. Iframe documents are outside this protocol: an iframe-based provider may place its unique toolbar in a same-document outer wrapper; marking the whole iframe does not make its contents a draggable toolbar. Reflow by business container width; truncate long titles, move descriptions below the toolbar, and keep actions usable.
Verify both modes with expanded/collapsed sidebar, narrow containers, realistic Chinese/English headings, entering/leaving fullscreen, and no duplicated space or covered controls. Click buttons, edit inputs, open menus and check keyboard focus. Verify actual native window movement from blank space; DOM/CSS checks do not replace native drag acceptance.
Existing-provider migration and compatibility limits
This is an explicit opt-in contract. The host cannot both prevent system controls from overlapping arbitrary legacy DOM and automatically preserve every legacy compact arrangement. Unmigrated providers remain loadable with the safe default layout. Only the collapsed sidebar on macOS outside fullscreen adds the default controls row; expanded layouts retain their original geometry.
| Existing provider | Migration | Before migration |
|---|---|---|
| Default business heading and description | May omit the declaration; review and remove provider-owned system-controls clearance while keeping normal business padding | Original expanded layout; separate row when collapsed |
| Custom frame or left split that should share the top row | Declare headerLayout: 'compact', mark exactly one same-document data-dsh-workbench-toolbar, and remove duplicate system-controls clearance | Original expanded layout; separate collapsed row, no toolbar inference |
| Toolbar inside an iframe, right split, or multiple markers | Move a single toolbar to a supported same-document position or retain default mode | Safe fallback to default mode |
Migration uses only the public registration field and toolbar marker, with no provider-name allowlist or semantic-header inference. External maintainers must publish their own migration releases; host updates do not modify installed external packages. Only valid compact declarations remove the host's 18px top gutter in ordinary left splits. Default mode and provider-owned header padding retain their existing values.
5. Workbenches, sessions, and workspaces
- One workbench may have many sessions; each session belongs to at most one workbench.
- A workspace is a DSH Desktop project-file environment. A session bound to a workspace has at most one workspace. Different sessions in the same workspace may belong to different workbenches.
- One workbench can use multiple workspaces, and different workbenches can use the same workspace.
- Internal business records or projects are not DSH workspaces and need no duplicate binding. For example, metaphysics records and location-selection projects retain their own create/select flows. A DSH workspace directory is a user-chosen file location; opening or creating a business project does not automatically assign it to a workbench.
6. Using a workbench without a bound session
Open the business panel immediately, even without a session or workspace. Browsing, creating, and choosing business records or projects must not require a pre-existing native session or workspace.
Check whether the current session belongs to this workbench only when an action depends on a session, such as sending an agent request or writing a draft. If unbound, guide the user to create or open a session at that action; do not block unrelated business features.
Provide a clear action such as “New workbench session in this workspace” or “Choose a file location and start a workbench session.” A business record may be created first if it needs no filesystem. Once file storage or DSH workspace creation is required, call the host directory picker first; the user must choose an existing directory or explicitly create one in the system picker. Never silently create a folder in a default location, home directory, current repository, or guessed path. After confirming location, create workspace and session, register ownership, save business association, and populate an opening draft. On cancellation, leave no directory, empty project, workspace, session, or binding. Restore existing business records only from a location the user previously confirmed; if missing, ask for a new selection rather than recreating a same-named directory. On failure, retain retryable state and never silently choose an unrelated workspace.
If the user selects a business record or project before creating the first session, preserve that selection. When opening an existing session, restore its own business mapping first; do not let another session's latest selection overwrite it.
When integrating an existing workbench, retain its project-creation guidance and independent business flow. The user need not manually create a session first; the workbench requests creation or restoration through Desktop, which validates and records ownership. Keep user-written opening drafts for the user to send; preserve them for retry if creation fails or is delayed. Automatically run business flows only in a correctly owned session, never mix them with the opening draft or let a hidden workbench send accidentally.
7. Mode entry and switching
The host supplies one mode switcher at the top of the sidebar. Its button displays only the current mode; the expanded menu switches among “Native sessions” and added workbenches, with “Workbench management” always at the far right. A workbench must not duplicate, cover, or replace these shared entrances. Switching mode changes foreground display and session filtering only; it neither reinstalls a package nor stops background tasks.
“Native sessions” and each workbench are peer modes. Current mode determines visible sessions and new-session ownership:
- Workbench mode: Show only sessions of the current workbench. “New session” and workspace switching may open only sessions of that owner. If a target workspace has none, create a new owner session, persisting ownership and the recent-session record before display. Never reuse, absorb, or rebind ordinary sessions or sessions of another workbench.
- Native session mode: Show only unbound sessions. “New session” and workspace switching may open only unbound sessions; create one if the target workspace has none. Do not infer or switch workbench from another session in the same workspace.
Explicitly opening an unbound session switches to Native sessions; explicitly opening a bound session with an available owner switches to that workbench. If its owner is removed, uninstalled, or unavailable, treat it as an ordinary session without automatically activating or reinstalling the owner. If the user navigates, switches modes, or removes an owner during asynchronous creation, do not pull the UI back to an old mode, overwrite the later selection, or bind to an invalid owner.
Mode switching must not collapse or expand the left session sidebar automatically; the user controls its state across modes. A workbench session title has a small icon of its owner; an ordinary session does not. The icon indicates ownership and needs an accessible name or tooltip. Buttons, menus, selected states, and focus rings must not clip, overlap, or overflow in collapsed or expanded states.
First entry may show a home page, empty-session state, or initialize a session under workbench conventions, but the business panel must not depend on session initialization. Later entries restore that workbench's most recent session. Navigation and switching must not delete sessions, business records, project files, favorites, or notes.
8. Local self-test checklist
Verify a local package without repository (including a scoped npm package name): after installation and loading, its entry is marked “Local,” appears in the switcher, and opens the business panel. Reloads and version updates preserve identity and session ownership. Verify that registration failures show the package, stage, and reason in Workbench management and clear after a successful reload. Module HTTP 200, successful imports, and passing tests do not replace real UI acceptance.
Check each applicable responsibility after development. “Host responsibility” means observe current Desktop behavior and report issues; plugin authors must not copy host UI. For “only when using this capability,” mark “not applicable” with a reason if unused. Claim local self-test passed only with evidence for all applicable items.
Package and loading
- Plugin: All required items in Section 3 pass. Run
pnpm pack; usetar -tzf <artifact.tgz>to confirmpackage.json, server and client entries, andcordis.patch.yml. Install that artifact rather than running only from source. - Plugin: Install under 3.6 and complete the required restart. If the agent runs inside the target DSH Desktop, the user must click “Restart now” in the top banner or choose Harness → Restart Harness; perform Agent checks once the user chooses continued verification and confirms the restart; independent trial does not require returning to the conversation. Find the plugin layer in
dsh --profile web --dump-config, the entry in Desktop “Workbench management / Installed workbenches,” and the real business panel opened from the sidebar. Record configuration, list, and UI evidence separately; keep post-restart loading and UI checks pending until restart is confirmed.
Section 4: UI boundary
- Plugin: Open the panel, resize the window, switch between native session and workbench modes, and verify the panel does not cover sidebar, market, or management controls; business actions are keyboard reachable.
- Plugin: Check the business entry point and session-related actions both on first entry without a workbench session and with an owned session open. In a standard split, check the host generic guidance beside the business panel. With
customFrame, check the workbench's own first-use and no-session actions. - Plugin: With the sidebar expanded and collapsed and the window narrowed, check realistic Chinese and English headings, identifiers, numbers, and buttons. Avoid single-character vertical wrapping, clipped primary controls, and page-wide horizontal overflow. Verify that columns respond to the business container width, not only the window width.
- Only if used; plugin: With
customFrame, narrow the window and operate layouts, overlays, and drag actions. Everything stays in host main content; nativeconversationworks.
Sections 5–6: workspaces and sessions
- Only if used; plugin: When the business flow creates files or a workspace, trigger the host directory picker. After cancellation, verify no new directory, empty project, or binding. After confirmation, verify files are only at the chosen location. Test reselection and failure recovery if the original directory disappears.
- Only if used; plugin: If a business action sends to an agent or writes a session draft, open the panel without a session first and verify non-session functions. At the session-dependent action, create or restore this workbench's session; the user sends the draft. Opening an existing session restores its business selection.
- Host; plugin assists verification: In one workspace create a native session and sessions for two workbenches; open each from the sidebar. Each belongs to one owner, and project files remain in place across mode switching.
Section 7: mode switching and preservation
- Host: Use the sidebar switcher between Native sessions and each workbench. Verify only corresponding sessions appear; workbench icon, management entrance, focus, and collapse state are correct. Recheck ownership after workspace switching and new sessions. Report Desktop version and reproduction steps for defects; the plugin must not privately rewrite host state.
- Host; plugin assists verification: After closing/reopening and uninstalling, confirm existing sessions, project files, drafts, notes, and favorites remain in their original places. Record install/uninstall separately from data preservation.
- Plugin: Record Desktop version, OS, architecture, package version, UI path taken, and unverified items. If installation is unavailable, deliver under Section 9 without checking post-install items.
9. Delivery when something fails
Final delivery must list actual results and evidence: changed files, package version, local installation and self-test outcomes, and unverified items. Identify anything missing; never invent success. If the toolchain is missing, installation fails, or host APIs are unavailable, keep completed code, explain why, and state the next step.
References
- DSH plugin packaging and publication:
docs/user/develop/basic/publish.mdandconfig.mdin deepseek-harness; package manifest types in@deepseek-ai/dsh-package-manifest; client module loading in@deepseek-ai/dsh-client-modules. - Market listing: Workbench Market Acceptance Standard.