Skip to content
dsh.fish
Bundle

dsh-rich-artifacts

DeepSeek Harness Artifact/Deliverable plugin: publish workspace files as chat artifacts with inline image previews and download cards.

Source
Inkotake
stars
1 stars
License
MIT
Updated
Updated 13 days ago

Readme

# dsh-rich-artifacts

[中文](README.zh.md) | English

A DeepSeek Harness (dsh) dual-face plugin that turns workspace files into **chat artifacts**: raster images render inline in the conversation, other files become download cards.

No more `file:///...` links or “the file is in `output/`” — when the model creates a user-facing file, it calls `publish_artifact` and the file is durably delivered through the chat UI.

## Features

- `publish_artifact` tool
  - `path` (required): workspace file to publish
  - `title` (optional): display title
  - `display`: `auto` (default) · `inline` · `download`
- ArtifactStore
  - SHA-256 content-addressed blob storage
  - metadata stored separately under `~/.dsh/artifacts/v1/`
- Durable session event `artifact/published`
  - only artifact metadata enters the session log
  - historical sessions keep showing artifacts after reload / fork
- HTTP endpoints
  - `GET /api/artifacts/:id/content` — inline-safe preview
  - `GET /api/artifacts/:id/download` — attachment download
- Web UI turn-tail gallery
  - PNG / JPEG / WebP / GIF render inline
  - everything else gets a file card with a download button
- Security
  - workspace containment via `fs.resolve` + `fs.contains`
  - final-component symlink rejection
  - magic-byte MIME sniffing (a `.png` that is actually HTML will not inline)
  - SVG / HTML are download-only in V0.1
  - file size, image size and image-pixel limits

## Install

```sh
dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts
```

For a locked, reproducible source install:

```sh
dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts#<commit>
```

Then restart `dsh web` (or the profile you installed into).

## Usage

The plugin registers a system-prompt section, so the model should call the tool on its own when it creates a deliverable. You can also ask for it directly:

```text
Create a training-loss chart, export it to CSV, and publish both files as artifacts.
```

The agent then runs:

```text
publish_artifact({ "path": "output/loss.png", "display": "auto" })
publish_artifact({ "path": "output/loss.csv" })
```

and the turn tail shows the image inline plus a CSV download card.

## Configuration

In the profile `cordis.patch.yml`:

```yaml
- id: dsh-rich-artifacts
  name: dsh-rich-artifacts
  config:
    root: ~/.dsh/artifacts
    maxFileBytes: 104857600
    maxTurnBytes: 524288000
    maxImageBytes: 20971520
    maxImagePixels: 40000000
    inline:
      png: true
      jpeg: true
      webp: true
      gif: true
      svg: false
```

| Field | Default | Meaning |
| --- | --- | --- |
| `root` | `~/.dsh/artifacts` | Artifact storage root |
| `maxFileBytes` | `104857600` | Per-file size cap |
| `maxTurnBytes` | `524288000` | Reserved per-turn cap (not yet enforced in V0.1) |
| `maxImageBytes` | `20971520` | Max inline image size |
| `maxImagePixels` | `40000000` | Max inline image pixels (best-effort parse) |
| `inline.*` | `png/jpeg/webp/gif: true`, `svg: false` | Which image types may render inline |

## Build

```sh
pnpm install
pnpm run build
```

`lib/index.js` is the ESM host plugin, `lib/client.js` is the browser bundle
(`window.__ModuleLoader__.load(...)`). Both are committed so source installs
work without a build step.

## Test

```sh
node tests/artifact-store.test.mjs
```

## Architecture

```text
DeepSeek Agent
     │  creates file
     ▼
Workspace File
     │  publish_artifact
     ▼
ArtifactStore ──────────────► artifact/published session event
     │                                  │
     │ (blob + metadata)                │ (artifact_id + metadata)
     ▼                                  ▼
HTTP /api/artifacts/:id/*        Session log (replayable)
     │                                  │
     └──────────────┬───────────────────┘
                    ▼
              Web UI turn-tail
              ┌─────────┴──────────┐
              ▼                    ▼
        ImageArtifact         FileArtifact
```

## Notes

- `artifact/published` is a log-only event. Because the current harness has no
  registration surface for out-of-repo session event types, the host adds it to
  `KNOWN_SESSION_EVENT_TYPES` at startup so persisted sessions remain loadable
  while the plugin is installed.
- MIME type is decided by magic bytes first; extensions are only a secondary hint.
- SVG and HTML are intentionally not inlined in V0.1.

## License

MIT

Install

dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source