navid-kianfar/dsh-add-assets0

@achasoft/dsh-add-assets

Composer add-assets plate for the DeepSeek Harness Web Client: an options menu on the composer's + button (files, folders, slash commands) and a Claude Code-style draft attachment preview

包名
@achasoft/dsh-add-assets
版本
0.1.0
许可证
MIT
最近更新
2026年8月26日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:navid-kianfar/dsh-add-assets

@achasoft/dsh-add-assets

An options plate on the composer's + for the DeepSeek Harness Web Client, and a Claude Code-style preview of what you have attached.

The harness's own + does exactly one thing: it opens the slash-command menu. This plugin makes that one entry among several — add files, add folders, upload from this device, slash command — each with a keyboard shortcut, and each reaching the same machinery the composer already uses.

What makes the picker worth opening rather than typing @: it keeps your selection across directories and searches, so three files from three folders go in with one gesture. Folders are a first-class target rather than a step on the way to a file. And the attachment row above the draft finally says what you attached — thumbnail, name, format, dimensions, size — with a full-size preview you can page through and remove from.

Requirements

  • A dsh installation with the Web Client (@deepseek-ai/dsh-web-app).
  • For the two workspace rows: a Host file-reference provider (@deepseek-ai/dsh-file-reference-local in the stock profiles). Without one, both rows say so and the rest of the plate still works.
  • For the slash-command row: the trigger pipeline (@deepseek-ai/dsh-client-ui-input-trigger), which is what the resident + uses too. Without it, that row says so.

Install

dsh plugin forwards to pnpm, so any pnpm source works:

dsh plugin --profile default add @achasoft/dsh-add-assets

Other install sources

dsh plugin --profile default add ./achasoft-dsh-add-assets-0.1.0.tgz   # from `pnpm pack`
dsh plugin --profile default add ./dsh-add-assets                       # a local checkout
dsh plugin --profile default add github:navid-kianfar/dsh-add-assets#   # from git

A git install fetches sources, not build output. This package ships a prepare script that builds them, but pnpm ≥10 will not run it until you allow it — add the key pnpm names to your profile's pnpm-workspace.yaml:

allowBuilds:
  '@achasoft/dsh-add-assets': true

That is permission to execute this package's code at install time. Prefer the npm or tarball forms, which need no such allowance.

The bundle appends itself to your profile automatically. Verify with dsh --profile default --dump-config, which should show a # == @achasoft/dsh-add-assets layer.

What the plate does

RowWhat it addsDefault shortcut
Add filesBrowses the session's working directory and inserts the chosen paths as @path mentions in the draft — the same text the composer's @ completion writes, so tools resolve them the same way.⌘U / Ctrl+U
Add foldersThe same picker, listing directories only and selecting them rather than descending. Inserts @path/.⇧⌘U / Ctrl+Shift+U
Upload from this deviceThe browser's file chooser. Images become draft attachments, exactly as paste and drop produce.
Slash commandOpens the composer's own slash-command menu over the caret. This is what the resident + did.⌘/ / Ctrl+/

Inside the picker: type to search the whole workspace, or type a path to browse a level. / move, Enter selects or descends, opens a folder, goes up, ⌘Enter adds everything selected, Esc closes.

The attachment preview

Each pending image is a card: a cropped square thumbnail, the file name, and a details line (PNG · 1024×768 · 240KB). Hover reveals a remove control; a click opens the full image over a dimmed page, where / page through the rest of the draft's attachments and the trash control removes the one you are looking at.

Dragging files anywhere over the page still shows the drop invitation and still attaches on drop — this plugin takes over that seat from the shipped attachment rail, so it owns the drop target too.

Prefer something quieter? Set previewDensity: compact for small round thumbnails with names only.

Settings

Everything below is editable at Settings → Plugins → Add assets, and can be fixed by the deployment from your profile's own cordis.patch.yml ($DSH_HOME/profiles//cordis.patch.yml). A patch replaces a row's entire config, so restate every key.

- patch:
    - id: add-assets
      config:
        replaceCommandButton: true
        deviceUpload: true
        filesShortcut: mod+u
        foldersShortcut: mod+shift+u
        commandShortcut: mod+/
        pickerResultLimit: 20
        previewDensity: card
        previewDetails: true
FieldMeaning
replaceCommandButtonHide the composer's own + so this plugin's plate is the only one. See the note below.
deviceUploadOffer the device file chooser under the files entry. Paste and drop work either way.
filesShortcut, foldersShortcut, commandShortcutChords like mod+u, mod+shift+u, mod+/. mod is Command on macOS and Ctrl elsewhere. Blank disables one. A chord the browser could not match is refused at load, naming the field.
pickerResultLimitRows the picker renders per query, 1–200. The Host applies its own, lower cap (20 by default), so raising this alone does not widen results — raise the file-reference provider's maxResults with it.
previewDensitycard (thumbnail, name, details) or compact (small round thumbnail and name).
previewDetailsWhether the details line shows format, dimensions, and size.

Shortcuts are deliberately modifier chords: the composer's textarea owns every bare key, and a plain-key shortcut would eat your typing.

About replaceCommandButton

The harness draws its + inside its own InputBar and declares no slot for it, so no plugin can replace it in place. Leaving one + in the tool row therefore means hiding the resident one, which this plugin does by marking that single element — found by searching the composer card its own seat sits in, for the accessible signature (aria-haspopup="listbox") unique to that button across the client. Nothing document-wide, no class names, and the mark is removed when the plugin unloads.

Set it to false if you would rather no plugin reached the harness's own chrome. Both buttons then show: the resident one still opens the slash-command menu, and this plugin's plate sits beside it.

Model Experience

Indirectly, and only through text a person can see and edit. Picked paths become ordinary @path prompt text in the draft — the model's view of them is whatever @deepseek-ai/dsh-file-reference-local already provides for a typed mention — and uploaded images become the same draft attachments paste and drop produce. This plugin adds no prompt, no tool, and no session event of its own.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

  • The resident + is hidden, not replaced. Until the harness declares a slot for that seat, the takeover depends on an accessible signature rather than a contract. It fails visibly (two buttons), never silently.
  • The picker's caret is the composer's, but its span is collapsed. A slash command picked from the plate inserts at the caret and replaces nothing, even if text is selected.
  • Images only in the preview. The composer accepts image attachments alone, so a card is always an image card; non-image file cards wait until the composer accepts non-image attachments.
  • No zoom or download in the full-size preview. It renders the original at fit-to-viewport size, pages, and removes.
  • The preview does not trap focus. It sets aria-modal and restores focus on close, but Tab can reach the page behind it — the same limitation the shipped lightbox has.

Development

pnpm install
pnpm run typecheck
pnpm run test
pnpm run build      # tsc emit → tsdown's two halves (lib/host.js, lib/client.js)

The link: devDependencies point at a sibling deepseek-harness checkout, which supplies the types and the built lib/ this package compiles against. The build reproduces the two artifact formats the harness's own (unpublished) client preset emits; tsdown.config.ts documents why each one is shaped the way it is.

License

MIT