Workflow & Automation

dsh-plugin-photoshop

Better-Rain/dsh-plugin-photoshop · ★ 11

Better-Rain

DeepSeek Harness plugin: drive your local Adobe Photoshop from the agent — batch subject cutouts (Select Subject / Remove Background) to transparent PNGs, plus a raw ExtendScript escape hatch.

License
MIT
Added
2026-10-30
Maintenance
active
Install kind
github
Manifest details
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-10-30T09:38:58.442Z
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add 'github:Better-Rain/dsh-plugin-photoshop#6cb817c1f08632d05a8dc91442cd8cf207284198'

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. In thirty seconds
  2. The problem it solves
  3. Real output
  4. Requirements and compatibility
  5. Install
  6. Permissions and external services
  7. The seven tools
  8. photoshop_status
  9. photoshop_inspect
  10. photoshop_cutout — the workhorse
  11. photoshop_batch — production runs
  12. photoshop_apply — the general-purpose hand
  13. photoshop_reference
  14. photoshop_run_jsx
  15. A skill ships with it
  16. Safety
  17. How it works
  18. Troubleshooting
  19. Development
  20. License

Let an agent inside DeepSeek Harness drive your own Adobe Photoshop: batch subject cutouts, batch processing, and any scriptable Photoshop work — without clicking through hundreds of files by hand. Say one sentence and Photoshop does the work.

Topic Listed on dsh-plugin.org

简体中文 · English


In thirty seconds

What it is A resident DSH plugin that gives an agent seven tools for driving your own Adobe Photoshop
What changes once installed You can say "cut the people out of this batch" and the agent does it inside Photoshop — it does not hand you a script to run
Why not something else It uses Photoshop's own Select Subject, which is markedly better on people, products and illustration than any open-source matting model
What it costs you Windows and a local Photoshop. No network, no upload, no third-party dependencies

The problem it solves

Extracting frames from a video and cutting the people out of them is a normal asset-production task. Photoshop's Select Subject is markedly better at it than any open-source matting model — but an agent cannot reach the Photoshop on your desktop, so you end up doing the whole batch by hand.

With this plugin installed, you ask in plain language:

Cut the subjects out of every image in D:\frames and write them to D:\cutouts

and the agent drives your local Photoshop through the whole batch, producing transparent PNGs with a per-image report.

Real output

Everything below is from actual runs, not illustration.

Batch cutout — 40 frames in one call. Each line also reports edge quality: how many pixels along the outline are partly transparent, which is the width of the soft transition band.

Photoshop cutout — mode select-subject, 40 image(s) queued
succeeded 40, failed 0, skipped 0
output: D:\cutouts
[ok]   male_station_000.png -> male_station_000.png  670x874 -> 670x874 (alpha, soft edge (4869 partial pixels, 0.83%))
[ok]   male_station_001.png -> male_station_001.png  671x874 -> 671x874 (alpha, soft edge (4739 partial pixels, 0.81%))
[ok]   male_station_002.png -> male_station_002.png  672x874 -> 672x874 (alpha, soft edge (4797 partial pixels, 0.82%))

One plan is one undo step — 46 operations, reverted by a single Ctrl+Z

Applied 46 operations in a single undo step:
  1. select_all          12. levels            23. radial_blur
  2. contract            13. black_white       24. smart_blur
  3. feather             14. auto_levels       25. unsharp_mask
  4. fill                15. auto_contrast     26. sharpen
  ...

Dry-run a plan first and catch a wrong layer name — changing not one pixel, which the test proves by showing the document's history state count is identical before and after

Dry run — 3 operations, nothing applied
  1. select_all           ok    target = the active layer, "Green"
  2. gaussian_blur        ok    target "Canvas" -> "Canvas"
  3. gaussian_blur        FAIL  target "NoSuchLayer": no layer named "NoSuchLayer" — run photoshop_inspect to see the layer tree

1 operation(s) name something that does not exist. Fix those before running the plan for real.

The self-check says what this machine cannot do, instead of letting you find out by failing

Adobe Photoshop 27.0.0 (build 27.0 (20251015.r.25 d1c1320))
select subject available: yes
remove background available: yes

Not available on this installation, established by running them:
  - Neural Filters and Generative Fill — the commands are not available here
  - The Layer > Matting menu: Defringe, Remove White Matte, Remove Black Matte
  - Select and Mask / Refine Edge — a modal workspace, so use feather, contract and refine_mask instead

Requirements and compatibility

OS Windows (the bridge uses COM automation; macOS and Linux are not supported)
Photoshop Verified end to end on Photoshop 2026 (27.0). Select Subject needs Photoshop 2020 or newer.
DSH profile web is verified. The plugin is host-plane and dependency-free, so any profile that registers the tools service works.
Node.js 20 or newer (already required by DSH itself)
Other No ffmpeg, no Python, no third-party dependencies
Licence MIT

Install

dsh plugin --profile web add github:better-rain/dsh-plugin-photoshop

One command, no build step — the repository already contains the loadable lib/.

Once it is published to npm, the package name is shorter:

dsh plugin --profile web add dsh-plugin-photoshop

The package-name form needs that version to exist on npm. Use the GitHub form above for now — it works today.

Restart dsh web afterwards. The plugin is resident: every later session has the tools.

Any profile works, not just web (web is the one verified here):

dsh plugin --profile tui add github:better-rain/dsh-plugin-photoshop

Remove it with:

dsh plugin --profile web remove dsh-plugin-photoshop

Permissions and external services

This plugin drives your real Photoshop, so the boundary is spelled out here.

What it needs

  • A locally installed Adobe Photoshop (Windows)
  • Read and write access to the files and directories you name
  • If Photoshop is not already running, the first call starts it (you will see the window appear; a cold start can take a minute)

What it never does

  • No network. No telemetry, no account, nothing uploaded — all the work happens inside your local Photoshop.
  • No writes to your input files. Every document is closed without saving; output goes only to the directory you name.
  • No closing of documents you opened. It closes only the ones it opened itself.
  • No changes to your Photoshop preferences. Modal dialogs are suppressed while a script runs — a modal would block automation forever — and the previous value is restored immediately afterwards.
  • No overwriting of existing output unless you pass overwrite: true.

Two ways to check before it acts

  • photoshop_apply with dry_run: true reports what a plan would touch, changing not one pixel.
  • With a document already open, a plan collapses into a single undo step — one Ctrl+Z reverts all of it.

Known limits, each established by running it rather than guessed: the whole Layer > Matting menu, Neural Filters, Generative Fill, Camera Raw as a filter, and playing a recorded Action (it can raise a dialog that no script can dismiss). photoshop_status lists them for you.

The seven tools

photoshop_status

Environment self-check, read-only — it opens nothing and modifies nothing. Reports the Photoshop version and build, whether it is already running, which documents are open, whether Select Subject and Remove Background exist in this version. Run it first when a Photoshop call fails for a non-obvious reason.

photoshop_inspect

Read what is actually on screen. Read-only.

Every open document, then for one of them: size, resolution, colour mode, bit depth, colour profile, disk path, unsaved state, active layer, selection bounds, history position, and channel / path / guide counts.

Then the complete layer tree, where each layer carries its index path, name path, kind, visibility, opacity, fill opacity, blend mode, clipping, mask presence, vector mask, layer effects, background flag, bounds — and for text layers their content, size, font and justification.

Layers are identified twice, so later operations can address them either way:

  • index path 0.1 — the second layer inside the first group
  • name path Header/Title — what the user actually says out loud

Why this came first: almost every real request is relative to something already open — "make the background layer blue", "export every layer in that group". Without this the agent guesses at layer names, and guessing is what makes an agent unreliable.

photoshop_cutout — the workhorse

Batch cutout. The whole batch runs inside a single Photoshop session rather than one round trip per image, which is an order of magnitude faster at a few hundred frames.

Parameter Meaning
paths Required. Image files and/or directories, freely mixed
output_dir Required. Created when missing
mode select-subject (default) or remove-background
recursive Walk subdirectories. Default false
trim Trim the transparent margin so each PNG hugs its subject. Default true
feather_px Soften the cut edge by N pixels. Default 0
contract_px Shrink the selection by N pixels before cutting, dropping the rim of background the subject sat on — the most effective way to kill a coloured halo, and the stand-in for Photoshop's Matting menu, which is not scriptable here. Default 0
mask_blur_px Blur the layer mask after the cutout, softening the outline further. Default 0. The stand-in for Select and Mask, which cannot run headless
max_side Cap the longest side, scaling proportionally. Default 0 (keep original)
suffix Text inserted before .png
overwrite Replace existing outputs. Default false (skip and say so)
limit Process at most N images — handy for trying a few frames first
timeout_ms Time budget for the whole batch; raise it for hundreds of images

Output is PNG-24 with alpha, named after each input.

Every output is verified against its PNG header for an alpha channel. A file that silently came back opaque is reported as NO ALPHA with advice to switch mode, so a fake success cannot slip through.

And its edge quality is measured. The plugin decodes the PNG, inflates the image data and counts the alpha samples: fully transparent, fully opaque, and partly transparent. The partial count is the width of the soft transition band along the outline, which turns "the edges look better" into a number. On the same input, adding feather_px: 2, contract_px: 1, mask_blur_px: 1 gives:

Cutout Partial-alpha pixels Soft band
plain 1,271 0.75%
refined 12,637 7.36%

A tenfold wider transition band — produced by the test, not asserted.

photoshop_batch — production runs

Apply the same list of operations to a set of files, all inside one Photoshop session.

Parameter Meaning
paths Required. Image files and/or directories
ops Required. The operations applied to every file — the same vocabulary as photoshop_apply
output_dir Required. Where results are written
output_format png (default, the only one that keeps transparency), jpeg, psd, tiff
suffix Text inserted before the extension
overwrite Replace existing outputs. Default false
recursive Walk subdirectories
limit Process at most this many files

Each file is opened → run through the plan → saved to the output directory → closed without saving, so an input is never modified. A failure on one file is recorded and the batch carries on — stopping at the first bad frame is useless for production work.

The plan may not contain open, new_document, close or save_as: the batch handles those itself. Including one is refused with the reason, and save_as especially so — it would make every input write to the same path.

photoshop_apply — the general-purpose hand

Run an ordered list of named operations against the open documents. Document setup and resizing, layer creation / naming / ordering / grouping, masks, opacity, blend modes, layer styles, tonal and colour adjustments, filters, text, fills, selections, history and metadata.

93 operations in nine groups:

Group Count Covers
document 16 open, new, close, save as, resize, canvas, crop, rotate, flip, trim, flatten, merge, duplicate, mode, profile, export layers
layer 23 create, delete, duplicate, rename, move, group, ungroup, opacity, fill opacity, blend mode, visibility, lock, unlock background, rasterize, smart object, merge down, masks (add / delete / apply / invert / refine), clipping mask, layer styles
adjust 12 levels, brightness/contrast, hue/saturation, vibrance, black & white, desaturate, invert, threshold, posterize, equalize, auto levels, auto contrast
filter 20 gaussian / motion / radial / smart blur, unsharp mask, sharpen ×3, add noise, dust & scratches, median, despeckle, high pass, maximum, minimum, offset, custom filter, pinch, spherize, twirl
select 14 all, none, invert, clear, subject, sky, remove background, expand, contract, feather, smooth, border, save/load channel
paint 4 add text, edit text, fill, add colour layer
action 1 list the Actions panel (playing is deliberately not offered — see the roadmap)
history 2 step backward, step forward
metadata 1 set document metadata

Two properties make it dependable:

  • The whole plan is one undo step. With a document already open the sequence runs inside suspendHistory, so a single Ctrl+Z reverts everything the agent did. A plan that works with history itself can opt out.
  • The plan is validated before Photoshop is involved. A misspelled operation costs a sentence, not a round trip: Unknown operation "gausian_blur". Did you mean gaussian_blur, ….
  • Plans can be dry-run. With dry_run: true it resolves every layer reference and reports what it would touch, changing not one pixel — the test proves that by showing the document's history state count is identical before and after. When a plan mentions layer names, this is the one call that turns a guess into a fact.

Failure reporting is designed to be actionable: which operation failed, by name and position, why, what had already been applied, and whether one undo reverts all of it.

photoshop_reference

Return the operation vocabulary on demand, optionally one group at a time. Needs no running Photoshop and no document, which is what lets the standing prompt stay small while the model can still learn every operation.

photoshop_run_jsx

The escape hatch: run arbitrary ExtendScript inside Photoshop and return its result. Batch resizing, applying recorded actions (.atn), compositing, inspecting documents — anything Photoshop can script, without waiting for a dedicated tool.

A skill ships with it

The plugin also registers a skill named photoshop carrying the working knowledge: the order to call things in, how layers are addressed, the rules that keep the user's files safe, and this installation's counter-intuitive corners (a new layer is fully transparent, a background layer must be unlocked first, groups cannot be filled, Select and Mask cannot run headless, and so on).

It is loaded on demand, so the standing prompt only says "load it before non-trivial Photoshop work" and the model reads the rest when it needs to.

Safety

This plugin drives your real Photoshop, so it is deliberately conservative:

  • It only touches documents it opened itself. Files you opened by hand are never closed.
  • It never saves over an input. Every document closes without saving; output goes only to the directory you name.
  • It does not change your Photoshop preferences. Modal dialogs are suppressed for the duration of a script — a modal would block automation forever — and the previous value is restored immediately afterwards.
  • Overwriting needs explicit consent. An existing output is skipped by default unless overwrite: true.
  • It is interruptible. The batch polls a cancel marker between images, and a cancellation still reports everything that finished.

How it works

Photoshop registers a version-independent COM automation server, Photoshop.Application, which exposes DoJavaScript() — run ExtendScript inside the running Photoshop and hand the result back. So the chain is:

Node (the plugin)
  └─ powershell.exe -File runner.ps1
       └─ New-Object -ComObject Photoshop.Application
            └─ DoJavaScript(generated ExtendScript)
                 └─ the real Photoshop

Design choices worth knowing:

  • Parameters are embedded as a JSON object literal. JSON is a subset of JavaScript literals, so no escaping layer or base64 hop is needed.
  • Results travel by file, never by console. Windows PowerShell encodes its console in the code page, which mangles non-ASCII paths and messages, so ExtendScript writes its own UTF-8 result file.
  • One script per batch. One COM round trip covers the whole list, not one per image.
  • Zero dependencies. The plugin imports nothing outside Node's standard library — not even a framework package — so it cannot fail to load because a package manager hoisted something differently in someone else's profile.

The cutout recipe itself was established empirically: Select Subject is the autoCutout action (selectSubject reports "command not currently available" on this version), and cutting out requires unlocking the background layer (isBackgroundLayer = false) before clearing the inverted selection — otherwise the delete fails.

Troubleshooting

PHOTOSHOP_UNAVAILABLE — no Photoshop found on this machine, or its COM server is not registered. Confirm Photoshop launches normally.

Photoshop did not answer within the time budget — the batch is too large, or Photoshop was not running and this call had to cold-start it (which can take over a minute). Raise timeout_ms.

Select Subject found no subject in this image — Photoshop's AI found nothing to select. Try mode: "remove-background", or check that the frame really contains a subject.

An output reported NO ALPHA — the cutout did not take effect and the image is still opaque. Re-run those images with remove-background.

Development

git clone https://github.com/Better-Rain/dsh-plugin-photoshop.git
cd dsh-plugin-photoshop
node test/e2e.mjs                 # runs the full verification against your Photoshop
node test/probe-capabilities.mjs  # reflects the real API surface of this installation
node test/probe-operations.mjs    # attempts every operation for real, producing a matrix

test/e2e.mjs builds the tool definitions, registers them on a stand-in registry, and then calls their execute exactly as the tool runtime would — covering the whole path except Cordis itself. It verifies each cutout output's alpha through its PNG header, and verifies every fact photoshop_inspect reports against a fixture document carrying a group, a nested text layer and a masked pixel layer. Inputs come from ~/Pictures/1.jpg (pass your own image as an argument); artifacts land in _research/e2e/ for inspection. The run clears its output directory first, so it is repeatable.

The two probes are what the capability inventory rests on: reflection gives the API surface this installation actually has, and the execution matrix establishes what really runs. A feature is documented as available only once it shows up there as ok.

To develop against a live profile instead:

dsh plugin --profile web add "C:\path\to\dsh-plugin-photoshop"

License

MIT


This is an independent community project. It is not affiliated with, endorsed by, or connected to DeepSeek AI or the DeepSeek Harness team. The package name dsh-plugin-photoshop carries no official scope; it follows DSH's public plugin specification (exporting apply(ctx) plus a cordis.patch.yml).

Licence and documents: MIT · CHANGELOG · roadmap, and the evidence behind the capability list