Skip to content
dsh.fish
Bundle

dsh-plugin-wepre

DeepSeek Harness plugin: publish single-screen content cards to WePre Next straight from a dsh agent session

Source
shujiTech
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-plugin-wepre

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

A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`) plugin that lets your agent publish single-screen content cards to [WePre Next](https://wepre.cn/next-test/) — a platform that pushes offline, single-viewport cards to users while they wait on AI generations.

With this plugin installed, a dsh session goes from "write me a card" to "it's live" in one conversation:

```
you:   Build a pomodoro-timer card and publish it to WePre
agent: <writes index.html, calls wepre_publish>
agent: QA gate rejected it — OVERFLOW_Y at 390x600. Fixing… <edits, republishes>
agent: Published. contentId=cnt_xxx, version v1 (QA: passed)
```

## Install

```sh
dsh plugin --profile web add dsh-plugin-wepre
```

Verify the layer composed, then boot:

```sh
dsh --profile web --dump-config   # shows a "# == dsh-plugin-wepre" layer
dsh --profile web
```

No build step and no `prepare` script — installing from a git host works too:

```sh
dsh plugin --profile web add github:shujiTech/dsh-plugin-wepre
```

## What the agent gets

Five model-facing tools on `ctx.tools`:

| Tool | What it does |
|---|---|
| `wepre_request_code` | Send a one-time login code (SMS / email) |
| `wepre_login` | Redeem the code; the session cookie is persisted locally |
| `wepre_whoami` | Show current login state |
| `wepre_publish` | Upload an `index.html` / `.zip` card through the server-side QA gate |
| `wepre_qa_report` | Fetch the full QA report (per-viewport issues) for a content |

The tools' descriptions teach the model WePre's content rules (single-screen layout, no network calls, no external resources, the `wepre-next:execute` postMessage contract) and the QA fix loop: when the gate answers `QA_GATE_FAILED`, the agent reads the structured per-viewport issues, fixes the card, and republishes with the same `contentId` — no human in the loop.

## Authentication

`wepre_publish` / `wepre_qa_report` resolve credentials in this order:

1. **`token` config field** — a short-lived publish token from the WePre publish page
2. **`WEPRE_PUBLISH_TOKEN`** environment variable
3. **The stored login session** — created by `wepre_login`, persisted to `sessionFile` (default `~/.dsh/wepre-session.json`, mode `0600`)

For interactive use, just ask the agent to log in: *"log in to WePre with 13800138000"* — it will send the code, ask you for it, and store the session. For CI / headless (`dsh --profile headless "…"`), set a token.

## Configuration

Override the plugin row in your profile's `cordis.patch.yml` (a patch replaces the row's **whole** config — restate keys you keep):

```yaml
- id: wepre-publish
  name: dsh-plugin-wepre
  config:
    endpoint: 'https://wepre.cn/next-test'
    token: !!js process.env.WEPRE_PUBLISH_TOKEN
    sessionFile: '/home/me/.dsh/wepre-session.json'
```

| Key | Default | Meaning |
|---|---|---|
| `endpoint` | `https://wepre.cn/next-test` | WePre Next site root |
| `token` | — | Short-lived publish token (Bearer) |
| `sessionFile` | `~/.dsh/wepre-session.json` | Persisted login session |

## What a publish call looks like

`wepre_publish` maps to `POST /next-test/api/next-contents` (multipart). Parameters: `title`, `path` (absolute, `.html` or `.zip`), `description`, `contentId` (for in-place version updates), `changeNote`, `versionLabel`, `downloadEnabled` (default `false`), and manifest fields `viewports` (`all`/`desktop`/`mobile`), `interaction` (`execute`/`passive`), `capabilities`.

On success it returns `contentId`, `versionId`, `versionNumber` and the QA status. On `QA_GATE_FAILED` (HTTP 422) it returns the structured `issues` and `reportId` as a canonical value — not an exception — so the agent can iterate. Before uploading, the tool runs a local pre-flight scan for WePre's banned tokens (`fetch`, `localStorage`, `Worker`, `overflow:auto`, …) and external links, and reports them as non-blocking warnings.

## Content rules in one paragraph

WePre Next cards are single-screen, offline, sandboxed pages: one `index.html` (or a zip with it at the root), root container at `100dvh` with `overflow:hidden`, no `overflow:auto/scroll`, no network calls / `localStorage` / `Worker` (the words are banned even in comments), no external or root-absolute URLs, and `execute`-mode cards must run their main action on the `wepre-next:execute` postMessage. The full contract: [WePre Next 内容发布规范](https://wepre.cn/next-test/) (see the publish guide on the site).

## Development

Plain ESM JavaScript, no build step. Behavioral tests drive the tools against a mock WePre server:

```sh
npm install
npm test
```

## License

[MIT](LICENSE)

Install

dsh plugin --profile web add github:shujiTech/dsh-plugin-wepre

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source