dsh-agent-plugins-market

Workspace behaviour

English | 简体中文 | README

Guide: Install · Sources · Resources · Services · Translation · Settings · Workspace

The settings page is the canonical layout, and the preset manager renders the same pieces. All surfaces share one tab row of equal columns that never scrolls sideways, and a label that does not fit ellipsizes. They also share one card and detail anatomy, hooks included, and one text-view switch at the toolbar’s trailing edge: the manager’s switch flips its cards and the detail behind them together. The workspace tabs share a saved grid/list preference; search and filters remain resource-specific. Add and refresh are header actions. Every card carries its enable switch, MCP and LSP services included, so a service can be stopped without opening its detail. The market filters by install state; the other five surfaces filter by owner — user, plugin — and by switched-off entries, whose count is the number of rows that filter shows. MCP Add validates a JSON server declaration and persists it under ~/.agents/mcp.json, then mounts it through the plugin bridge; LSP Add does the same into ~/.agents/lsp.json. Invalid declarations and duplicate names are rejected. Existing host-owned MCP services remain observation-only.

Resource detail editing

Details and editors share one dialog in three widths — 460px for a confirmation, 640px for a short form, 880px for a detail or an editor — constrained to the viewport. An editor opens at 80% of the window’s height, so switching between its form and JSON views never resizes the window and a long document scrolls inside it; a detail dialog stays as tall as its content. A resource’s card carries its identity line (name and owning tag) with its state as a colour rail on the leading edge, a two-line description or endpoint, and a source row naming the owning suite, with its actions on the identity row and revealed on hover or keyboard focus; opening it shows the overview, the description, and its contents grouped by surface, each row expanding in place. Markdown preview shows the frontmatter as authored above the rendered body; raw editing preserves unknown keys and comments, and the editor offers the source with line numbers and syntax highlighting, with a switch to the rendered draft beside its title. What saving does is stated beside the buttons, and a command’s argument-hint has its own field beside the name. MCP forms choose the transport from a segmented control that states what each option configures, keep command, arguments, environment, URL and headers in the main body, and open from the card’s edit action into a dialog of their own: the detail dialog reports the state, the capabilities and the credentials, and the editor changes the configuration. The editor shows one document — the portable definition under mcpServers plus this client’s policy under com.deepseek.harness — so the form can cover the common fields while every other setting stays writable as JSON. A service you declared yourself keeps keys this client does not know exactly as written; a suite’s packaged mcp.json stays closed to them. Creating and editing a service use the same dialog and form. Creation exposes an editable name, while editing retains the existing identity, so a service reads the same before and after it exists, and anything the form has no field for stays writable in the JSON view, which shows the whole document; an Advanced settings disclosure — form view only, since the JSON view already holds everything it sets — carries the optional connection inputs — the working directory for a stdio server, and the tool-call and startup timeouts in milliseconds, with the value in force as the field’s placeholder. Leaving a timeout empty inherits it again, and only the fields you changed are written back. The host compatibility backend cannot enforce a startup timeout, so it fixes that field and offers a clear control when a value was stored earlier. A rejected save places each reason beside the field the API named. Environment variables and headers accept a pasted block of KEY=VALUE or Key: Value lines. LSP forms cover command, arguments, environment, extension mapping, initialization options and configuration, and follow the same split: its detail dialog reports, and its card carries the edit action. Invalid JSON, incomplete map rows and an out-of-range timeout remain editable but cannot be saved. Uninstalling a suite asks you to acknowledge what leaves the profile before the action is available.

The MCP service detail lists every tool with a checkbox. A checked tool is allowed; unchecking it stores a denial, which keeps the tool listed after the live registry drops it, so you can check it again. A tool the suite’s own declaration limits is unchecked and fixed, and names the suite as the reason. A tool that advertises an input schema opens its parameter list from its name. The list shows the first eight rows with a count of the rest, offers a name filter once a server publishes more than eight, and expands on demand. It is read-only for a host-observed server and for one another MCP client mounts. A service detail opens on one status band that carries the whole state: the state dot and tags with the one recovery action the state offers (retry, re-authorize), the last operation’s result, one sentence for the failure shape the plugin recognized (missing credential, refused connection, command not found, a taken seam, and so on), the recorded diagnostic with the messages under it behind a Diagnostic details disclosure, and the endpoint or command. The band’s leading edge takes the same state colour as the card, and the title is the readable service name — a plugin service’s key, a direct service’s name — with the mount name shown beside the service key in the overview only when the runtime registers a different one. A reason the plugin cannot place is shown as recorded; the retry result says only whether the operation reconnected, and a failed service that registered no tools says the list needs a live connection.

GET /api/agent-plugins/server-config?kind=mcp|lsp&id=... returns the full editable configuration plus, for MCP, the policy view and the mount backend; POST /api/agent-plugins/server-config/save replaces that service config and takes an optional policy: { toolCallTimeoutMs, startupTimeoutMs } where a number sets a timeout and null clears it back to inheritance. POST /api/agent-plugins/set-mcp-server-tool takes { suiteId, serverKey, tool, enabled } and stores the tool denial in the override record. Plugin MCP replacements persist in its existing override file; plugin LSP replacements persist in data/lsp-overrides.json. Checkouts stay untouched. Unchanged [redacted] fields preserve original secrets. Modified config remounts through the plugin runtime. Host-observed MCP remains read-only. GET /api/agent-plugins/server-config?kind=mcp|lsp&create=true returns an unsaved template, including current MCP backend and timeout defaults. POST /api/agent-plugins/mcp-servers/add accepts { name, config, policy? }; it validates both parts, saves the policy before publishing the declaration, and restores the previous policy if declaration publication fails. The two files are not a cross-file transaction: interruption can leave an unused policy, but not a service missing its requested policy. POST /api/agent-plugins/lsp-servers/add creates one named direct service without replacing others.

Operation overlay

Visual feedback waits 200 ms and disappears when the last operation finishes, without a minimum visible duration. Reads stay interactive and use a nonblocking status card for longer waits. Mutations block repeated input immediately; only visible mutation feedback moves focus and sets inert state.

Workspace requests and credential/settings writes share withBusyOperation (packages/market-ui/src/ui/busy-operation.ts). Wrap a complete workflow when it also refreshes data afterward; nested leases keep the mask until every operation settles. A single body-level BusyOverlay tracks the active dialog rectangle, marks it inert, blocks backdrop/keyboard interaction and restores focus afterward. Tips rotate every 3.2 seconds; reduced-motion preferences disable the scrolling transition. Source-progress, model-catalog background loading and automatic LSP polling remain silent. The mask never occupies a row in the resource list and does not fabricate percentage progress.

Waiting never ends in silence: a mask that outlives 20 seconds says a local service may not be answering, reads stop waiting after 15 seconds, and mutations after a 10-minute backstop — a request that ran out of time is reported as such instead of holding the page.