DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-plugin-lcu

c

dsh-plugin-lcu

Manifest valid

DeepSeek Harness plugin: drive the desktop and Chrome through LCU (Codex computer use, decoupled from the app)

hasBundlePatch

dsh-plugin-lcu

English | 中文

Drive the desktop and Chrome from DeepSeek Harness by plugging in LCU — Codex computer use, decoupled from the app.

LCU exposes the computer-use runtime that ships inside the ChatGPT desktop app as an MCP server. This plugin makes that runtime a first-class DSH capability: an Agent in an enabled mode gets a js tool that can read and operate real application windows and real Chrome tabs. No Codex authentication is involved — the runtime comes from your local ChatGPT installation, and LCU never downloads, installs, authenticates, or rewrites it.

Table of Contents

What you get

Two model-facing tools, exactly as LCU defines them — this plugin does not invent a schema:

ToolWhat it does
jsRun one JavaScript program against the cua desktop/browser API. The first call returns the API documentation, and app or tab selection returns the initial UI state.
js_resetDiscard the persistent JavaScript session and start a fresh runtime.

Two host-only tools stay reachable by the plugin and are never shown to the model: turn_ended (per-turn cleanup) and js_add_node_module_dir.

The plugin adds exactly one tool of its own:

ToolWhat it does
computer_use_stopWith no argument, list the applications the runtime currently holds for this session. With app set to one of their bundle identifiers, release it. This is LCU's explicit per-app Stop — the same action its Pi adapter surfaces as /lcu stop — which clears the host application's "computer use is active" state for an app without ending the session.

Screenshots arrive as durable images through DSH's attachment store, so a model route that declares image input can actually look at the screen.

Requirements

OSmacOS on Apple Silicon. LCU supports Linux too, but this plugin is developed and verified on macOS.
ChatGPT desktop appInstalled and signed by OpenAI. It supplies the runtime and the instructions.
Python3.12 or newer, on PATH or in /opt/homebrew/bin, /usr/local/bin, /usr/bin.
LCUInstalled separately — see below.
DSHA profile you can install a bundle into.

The plugin targets macOS; the host-guard uses ps/plutil and the lifecycle uses LCU's macOS path. Linux would need those two pieces revisited.

Install

1. Install LCU

Download the release archive for your platform, verify its checksum, and run its installer. Do not register another harness: this plugin is your harness.

TAG=v0.9.6
TARGET=darwin-arm64
curl -fLO "https://github.com/amontlabs/lcu/releases/download/$TAG/lcu-${TAG#v}-$TARGET.tar.gz"
curl -fLO "https://github.com/amontlabs/lcu/releases/download/$TAG/lcu-${TAG#v}-$TARGET.tar.gz.sha256"
shasum -a 256 -c "lcu-${TAG#v}-$TARGET.tar.gz.sha256"   # must print OK
tar -xzf "lcu-${TAG#v}-$TARGET.tar.gz" && cd "lcu-${TAG#v}-$TARGET"
./scripts/install.sh --runtime-only --yes

Then confirm the runtime loads:

~/.local/share/lcu/current/bin/lcu doctor --non-interactive

You want Original Mac provider loaded; app listing and app-state methods are available. Privacy permissions are granted on first use, not here.

2. Install the plugin into a profile

Installing makes the plugin's one row — an LCU host — active in that profile. It opens nothing at load time.

dsh plugin --profile <profile> add dsh-plugin-lcu

For the desktop app's managed profile, the CLI refuses; install it through the app's plugin manager (Settings ▸ Plugins) instead, which runs the same pnpm operation.

3. Generate the presets

DSH agent presets have no inheritance: a preset's config.plugins is its complete plugin list, and a patch replaces a whole entry rather than merging into it. So a custom preset must restate its base. Rather than hand-copying that list, generate it from the preset that is actually installed:

node node_modules/dsh-plugin-lcu/scripts/gen-presets.mjs --profile ~/.dsh/profiles/<profile>

This writes a marked block into that profile's cordis.patch.yml containing two presets:

PresetBaseAdds
dailythe shipped ptc presetsubagent_codex enabled
heavythe same, with tool-presentation: botheverything above, and this plugin attaches

Re-run it after a DSH upgrade so the copies keep up. --with-heavy is implied; --dry-run prints without writing, and --out FILE writes somewhere else.

heavy sets the tool presentation to both on purpose. In pure ptc presentation the model only sees run_code, so js would have to be nested as a JavaScript string inside another JavaScript program. both keeps js directly callable.

4. Configure which modes get the capability

The plugin is one root row with a presets allowlist. Edit the installed cordis.patch.yml (or the profile patch) to match the preset ids you generated:

- id: lcu
  name: 'dsh-plugin-lcu'
  config:
    presets:
      - heavy

5. Restart, then make one call

Restart the harness — plugin code and configuration changes are not hot-reloaded. Then start a task in the heavy mode (displayed as 重活) and ask it to do something harmless:

Use the js tool to run await cua.getState(); and tell me which apps are running.

The first time an app is touched, the runtime asks for approval. See below.

Optional: enable Chrome

config:
  chrome: true

Then:

~/.local/share/lcu/current/bin/lcu browser install

Enable the official ChatGPT extension in the Chrome profile you want to drive, and restart Chrome (or toggle the extension at chrome://extensions) so it reconnects through LCU's relay rather than Codex's. lcu browser status reports whether the connector points at this installation. Sites stay exact-origin approvals.

Optional: pre-approve sites

Every site the runtime wants to use asks once. To skip the prompt for origins you trust, list exact origins — the message must round-trip through new URL(...).origin unchanged:

config:
  allowedOrigins:
    - http://localhost:3000

The diagnostic log names every origin that was asked, which is the easiest way to discover them.

Use

Pick an enabled mode when you start a task. The tools are attached per Agent: a session in any other mode never sees them, and never spawns the runtime.

Typical asks:

Take a screenshot of the Finder window and tell me its resolution.
List my current Chrome tabs.
Open Safari, go to example.com and read the page title.

Configuration

FieldDefaultMeaning
command~/.local/share/lcu/current/bin/lcuLCU launcher. Set it for a custom --prefix.
chromefalsePass --chrome to enable the browser surface.
audiofalsePass --audio to enable the runtime's computer-audio API.
presets["heavy"]Agent preset ids whose sessions get the tools.
allowedOrigins[]Exact HTTP(S) origins answered without asking. Invalid entries are dropped, never widened.
sectionOrder0Prompt section order for the injected LCU instructions.

Approvals and the security model

The model cannot approve anything. Every decision is a person's:

  • Per-app approval. The runtime asks before it uses an app. The plugin renders its own choices — Allow once, Allow for this session and Always allow when the runtime offers them, and Decline — through DSH's question surface. An answer is mapped back to exactly what was offered; a scope the runtime did not offer cannot be granted.
  • Site approval. Browser access asks per exact origin. allowedOrigins only ever matches an exact origin; a trailing slash, a path, or different case is a different origin and is asked, not granted.
  • The agent's own host is never approvable. Computer use can click anything an approved app shows, including the approval prompt itself. The guard refuses the application hosting the agent — its process ancestry and a list of agent hosts and terminals — before any question is asked.
  • Fail closed. No question surface, a dismissed prompt, an unrecognized request shape, or an aborted call all end as cancel, which the runtime treats as a refusal.

LCU keeps no permission cache of its own; Always allow is remembered by the runtime, per app.

Understand the implementation

src/connection.ts   the MCP client: handshake, tool discovery, calls, elicitation, lifecycle
src/approval.ts     approval-shape recognition and label→value mapping
src/host-guard.ts   the anti-self-approval guard
src/tool.ts         tool definitions, text projection, durable screenshots
src/index.ts        the plugin: per-Agent attach, instructions, turn_ended, approvals
src/diag.ts         the attach/approval diagnostic log

No MCP SDK dependency. The harness's own MCP bridge declares capabilities: {} and therefore cannot answer elicitation — which is exactly how LCU asks for approval — and pulling a second SDK into a profile plugin would pin a version the host does not own. MCP over stdio is newline-delimited JSON-RPC, so the wire is owned here. Together with type-only imports of the DSH packages, the plugin has no runtime dependencies at all.

Tools are registered per Agent, not at mount. The server owns the tool schemas, so they can only be fetched after the handshake. An Agent's connection is opened when the Agent is created or when it commits a preset choice, and everything the plugin contributes is registered into that Agent's own context, so it unwinds on disposal.

Both preset timings are handled. A new task is created with the deployment default and the picker's choice is applied afterwards, so agent/created alone would see the wrong composition; the registry re-emits agent-preset/selected, and the plugin reacts to that too.

Lazy by construction. Nothing starts at load time. No enabled session, no lcu process.

Instructions are injected. The server's initialize.instructions becomes a prompt section on the Agent. It is short by design — the API manual lives in the js tool description and in the first tool result.

Troubleshooting

Everything the plugin decides about attaching and approving is appended to:

~/.dsh/lcu-diag.log

It rotates by starting over past 1 MB. LCU_DIAG=0 disables it. This is the first place to look: the harness has no plugin-log surface a running session can read, and a failing agent/created listener is otherwise swallowed silently.

SymptomCause and fix
Tools never appear in an enabled modeCheck the log for decide … composed=. If the composed preset is not in presets, fix the allowlist. If there is no agent-preset/selected line, the mode was never committed.
no userQuestions service -> cancel (fail closed)The approval surface is not mounted in this profile.
refusing to approve the app hosting this agentWorking as designed; ask for a different app.
Calls blocked after a turnThe runtime's turn cleanup had not settled; the plugin retries it before the next call and refuses until it does.
lcu doctor reports a socket-path errorThe signed helper binds under your home folder and refuses a path over 103 bytes. Use an account with a shorter home path.
Attach fails with a spawn errorRun ~/.local/share/lcu/current/bin/lcu doctor directly, then check command in the config.
The ChatGPT app still shows computer use on an appThe runtime is still holding it. Ask for computer_use_stop, or close the session — the connection owns the runtime process tree and releases it on the way out.
lcu status reports changed_since_installThe ChatGPT app updated underneath a running session. LCU warns that such a session can run "a mix of old and new files": stop those sessions and restart the harness so everything comes from one app version.

node scripts/probe-lcu.mjs talks to LCU with no harness involved and prints the protocol version, server identity, instructions length and the tool list — useful to separate a plugin problem from an LCU problem.

Companion tools

scripts/ also ships two tools for the sibling Codex subagent bundle, because the same profile usually wants both:

  • update-codex.mjs — keeps the profile's @openai/codex on the newest release that still passes three gates (handshake, protocol-schema assertions, and a real turn), rolling back automatically when one fails. The published @deepseek-ai/dsh-subagent-codex pins 0.153.4, which does not serve every current ChatGPT-account model; this bumps it through a profile-level, scoped pnpm override. See node scripts/update-codex.mjs --help for --check, --verify-only, --to and --rollback.
  • codex-baseline.json — the last version that passed all three gates.

Known limitations and deferred work

  • A delegated child cannot be asked for approval. DSH only accepts a human answer for a live runtime root, so a subagent's LCU approval fails closed. Subagents can perform read-only work that needs no approval; anything that needs one must be driven from the top-level session.
  • macOS turn cleanup can outlive the host's wait. The signed helper occasionally answers the turn-ended step slowly. The runtime keeps cleaning in the background and retries; the plugin blocks the next call until it settles rather than acting on a half-torn-down desktop.
  • One LCU connection per Agent. LCU's JavaScript session is per connection and its approvals are bound to a real session and turn, so sharing one connection across Agents would interleave both.
  • chrome needs the extension. Enabling the flag without the official ChatGPT extension, or without lcu browser install, yields no browser surface.
  • Not verified on Linux. See Requirements.

Development

npm install
npm run typecheck     # strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes
npm run build         # emits lib/
npm test              # node --test, no build step

The connection suite talks to the real installed lcu and skips itself when none is present, so npm test is meaningful locally and still passes on CI. The approval, projection and guard suites are pure and always run.

Plugin code and configuration are not hot-reloaded by the harness: a running process keeps the module it loaded. Rebuild and restart to see a change.

License

MIT. LCU is MIT (Amont Labs); the ChatGPT application and its instructions remain under their own terms and are used from your local installation.

Comments

Loading…

From the same category

awesome-dsh-plugin

by awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表

Development & Infrastructure

★ 18.3k

CC0-1.0

Python

Oct 10, 2026

Index only — not installable

by 0xsline

DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.

Development & Infrastructure

★ 1.2k

CC0-1.0

Python

Oct 10, 2026

Index only — not installable

by pax-beehive

Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub

Development & Infrastructure

★ 450

MIT

TypeScript

Oct 6, 2026

Index only — not installable

by xiajiajun516

DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.

Development & InfrastructureManifest valid

★ 176

MIT

TypeScript

Oct 8, 2026

dsh plugin --profile web add dsh-config-manager

by yjh051108

推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。

Development & InfrastructureManifest valid

★ 164

TypeScript

Sep 18, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by jigjoy-ai

A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.

Development & Infrastructure

★ 124

MIT

TypeScript

Oct 2, 2026

Index only — not installable