Skip to content
dsh.fish
Bundle

dsh-annotation-plugin

Quote selected assistant text into your next request: a Host-side annotation service (session events + Typert Remote) plus a Web client plugin (quote button + pending-quote dock).

Source
boboozeng
stars
2 stars
License
MIT
Updated
Updated 10 days ago

Readme

# dsh-annotation-plugin

Quote selected assistant text into your next request — a standalone plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).

This plugin ships both halves of the feature in one npm package:

- **Host half** (`dsh.bundle` + `cordis.patch.yml`): an `annotation` plugin that records quotes as log-only session events (`annotation/added` / `annotation/removed`), exposes a Typert Remote (`record` / `list` / `discard`), and materializes pending quotes into the model-facing message batch at `agent/pre-step`.
- **Browser half** (`dsh.client`): a quote button on each assistant message and a floating, collapsible pending-quote card above the composer.

## Install

Requires a DeepSeek Harness profile that composes `@deepseek-ai/dsh-base` (the official base layer provides `session`, `agent`, `web` and the client runtime).

### From npm (recommended)

```bash
dsh plugin --profile <name> add dsh-annotation-plugin
```

The published package ships prebuilt artifacts, so nothing builds at install time.

### From GitHub

A git install fetches **sources, not built artifacts** — the package's `prepare` script (`tsdown`) builds `lib/` after checkout, and pnpm refuses to run a git dependency's `prepare` until you explicitly allow it. The first `add` fails and `dsh` prints the exact package key to allow:

```bash
dsh plugin --profile <name> add github:you/dsh-annotation-plugin
# → pnpm refuses to run the prepare script; copy the package key it prints
#   into the profile's pnpm-workspace.yaml, then re-run the add:
```

```yaml
# <profile dir>/pnpm-workspace.yaml
allowBuilds:
  dsh-annotation-plugin: true
```

```bash
dsh plugin --profile <name> add github:you/dsh-annotation-plugin   # re-run
```

That allowance is **permission to execute the package's code on your machine at install time**, outside any sandbox the agent runs under. Only allow packages whose source you trust, and pin a commit so a later push cannot silently change what runs:

```bash
dsh plugin --profile <name> add github:you/dsh-annotation-plugin#<sha>
```

If you would rather not ask users for the allowance, install the npm build instead (or distribute a tarball from `pnpm pack` — neither needs any build permission).

The bundle layer inserts the `annotation` plugin row; the client-modules table picks up the `dsh.client` declaration and loads the browser bundle in the Web GUI.

## Usage

1. Select text in an assistant message.
2. Click the quote button (✎) in the message action strip — the selection is recorded and a floating card appears above the composer: **Quotes · N ▴**.
3. Click the card to expand the quoted-text list; use **✕** on a row to cancel that quote.
4. Send your message — the pending quotes are materialized as quoted context for the model and the card disappears.

## Requirements

| Package | Version |
|---|---|
| `@deepseek-ai/dsh-base` | `^0.1.0-rc.5` |
| `react` (host web bundle) | `^18.2.0` |

Peer dependencies (`@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-client-ui-conversation`, …) are satisfied by the profile's dependency tree.

## Development

```bash
pnpm install
pnpm build        # tsdown: lib/index.mjs (node half) + lib/client.js (browser bundle)
pnpm test         # vitest (jsdom client specs)
pnpm typecheck
```

### Regenerating the Remote contribution

`src/remote.ts` is a committed copy of the Typert-generated descriptors. After changing any `@Remote` method signature in `src/index.ts`, regenerate it (e.g. from the official checkout: `pnpm run build:lib:host`, then copy `packages/session/annotation/lib/typert.remote-client.js` into `src/remote.ts` and adapt the package ids). An out-of-date descriptor silently strips fields on the client — the classic "schema missing a field" failure.

## Notes

- The Host half uses the namespace plugin form (`name` / `inject` / `apply` named exports). Do **not** add an `export default` — the Loader's `unwrapExports` would discard the namespace.
- The browser half mounts its own Typert Remote contribution (`ctx.remote.$mount`) because the published `@deepseek-ai/dsh-api-remotes` does not carry the annotation namespace.
- The `discard` Remote export maps to the `remove` method (`method: "discard"`, `implementation: "remove"`); keep the generated descriptor in sync.

## License

MIT

Install

dsh plugin --profile web add github:boboozeng/dsh-annotation-plugin

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