Skip to content
dsh.fish
Bundle

dsh-plugin-compact-button

Composer compact control for the DeepSeek Harness web UI: a button beside the model selector that runs the deployment's own /compact command.

Source
liutian11451-png
License
MIT
Updated
Updated 2 hours ago

Readme

# dsh-plugin-compact-button

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

> **AI-generated code.** This package was written by an AI agent (DeepSeek Harness, model `deepseek-flash`) in a human-directed session, and published by the human who ran it. Review it before you install it, and especially before you allow its `prepare` script to run on your machine. See [AI disclosure](#ai-disclosure) for exactly what has and has not been verified.

A compact control for the DeepSeek Harness web composer: one button, seated directly left of the model selector, that runs the deployment's own `/compact` command.

## What it does

Click it and the session compacts. The button submits the bare `/compact` line over the Session's command channel, which means the durable attempt record, the compaction lock, the summarization route, and the flow node the Chat view already renders all stay exactly the ones `/compact` owns. This plugin contributes the gesture and its localized refusals — never a second compaction path.

- **Blank session** — renders nothing; there is no history to compact.
- **Agent running** — greyed out and unclickable, keeping its ordinary label. Manual compaction needs an idle agent, but a turn this control did not submit must not claim to be compacting.
- **Compacting** — reads `Compacting…` from the gesture until the compaction turn ends, then returns to its ordinary label. The window is a three-step latch: the gesture arms it, the observed run confirms it, the run ending releases it. Watching the run alone is not enough — a compaction admitted while the agent was already running never shows the control a run *starting*, which is the case that once left the label stuck after the compaction had finished.
- **Refused** — one inline reason above the composer row. A transport failure shows the host's own message; a deployment with no `/compact` command is reported as the missing capability rather than appearing to succeed.

## Install

```sh
dsh plugin --profile web add dsh-plugin-compact-button
```

Substitute your profile name for `web` if you run a different one. The package declares `dsh.bundle`, so `dsh plugin` registers its patch layer in the profile automatically. Restart `dsh web` and reload the page; the build payload is composed at boot, so a reload alone is not enough the first time.

### From a GitHub checkout

```sh
dsh plugin --profile web add github:liutian11451-png/dsh-plugin-compact-button
```

A git install fetches sources, not built artifacts, so the package ships a `prepare` script that builds `lib/` from `src/` with plain tsdown — no sibling repository, no type checking. pnpm ≥10 refuses to run a git dependency's `prepare` until you allow it, so the first `add` fails with `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED` and prints the exact key to add. For a git install that key names the resolved tarball, not the bare package name:

```yaml
allowBuilds:
  dsh-plugin-compact-button@https://codeload.github.com/liutian11451-png/dsh-plugin-compact-button/tar.gz/<commit-sha>: true
```

Copy the line pnpm prints verbatim — it carries the commit the install resolved to — then re-run the `add`. Treat that allowance as permission to execute this package's code on your machine at install time, and pin a commit (`github:liutian11451-png/dsh-plugin-compact-button#<sha>`) so a later push cannot silently change what runs.

One caveat when moving an existing install: if the plugin was previously installed from a **local directory**, remove that first. A leftover link in the profile's `node_modules` collides with the incoming git install and pnpm fails with an `EPERM` symlink error during import.

To avoid asking users for the allowance altogether, publish to npm or ship a tarball from `pnpm pack` — neither needs build permission.

### Local directory

```sh
dsh plugin --profile web add /absolute/path/to/dsh-plugin-compact-button
```

### Requirements

The deployment must mount the compaction capability — `dsh-command-compact` plus a compaction backend. Both are part of the standard preset. Without the command the button still renders and answers a click with an explicit unavailable-capability reason; the client cannot know the host's command catalog up front.

## Layout

```
package.json                                # dsh.bundle + dsh.client manifests
cordis.patch.yml                            # inserts this package's loader row
src/index.ts                                # node half (inert)
src/client/index.ts                         # browser half: registers the seat
src/client/CompactButton.tsx                # the control
src/client/locales.ts                       # zh/en dictionaries
src/client/CompactButton.module.css         # chip chrome and the refusal strip
tsdown.config.ts                            # consumer-side build
smoke.mjs                                   # loader-contract smoke test
```

The node half is deliberately empty. The harness client module registry discovers `dsh.client` packages by walking the host Loader's rows, so the package needs one mounted row as its carrier; that is all the row is for.

## Development

```sh
pnpm install
pnpm build       # emits lib/index.js and lib/client.js
pnpm typecheck
node smoke.mjs   # evaluates the built browser half against a stub shell
```

`smoke.mjs` checks the two contracts that are easy to break and invisible until boot: the artifact must take the `window.__ModuleLoader__.load({ id, factory })` handoff and return `module.exports`, and `apply()` must register one `conversation.input.right` entry whose injected verb submits `/compact` and folds all three admissions into copy.

### The two build contracts

The browser bundle is not an ordinary ESM build. The shell fetches `lib/client.js` and evaluates it, so the file must be a CommonJS closure factory — hence the `banner`, `intro`, and `footer` in `tsdown.config.ts`. An ESM or unbannered artifact throws at boot.

Specifiers the shell's module table answers (`react`, `react/jsx-runtime`, `cordis`, the shared UI primitives and store) stay `require(...)` calls; everything else is inlined. A `require` the table cannot answer is a guaranteed runtime throw, which is why the external list in the build config is explicit rather than derived from the package's dependencies.

## Known limitations

- **The gesture is only as available as the command** — a deployment without `dsh-command-compact` renders the button and answers a click with the unavailable-capability reason.
- **Admission is not completion** — the command RPC resolves when the host admits the line, so the `Compacting…` label covers the window from the gesture to the end of the compaction turn. A compaction started by an automatic policy, or any other turn, leaves the label alone; the control is merely greyed out while that turn runs.
- **The busy label is bounded, not exact** — an admitted attempt that never produces an observable run releases after an 8-second grace period, because the client is not shown a compaction lifecycle it could wait on. A compaction that starts later than that reads as this control going idle early.
- **No region selection** — the control always submits the argument-free form, so it compacts the backend's own useful range and never a hand-picked span.
- **Idle agents only** — disabled while the agent runs, matching `compactNow`'s requirement; it is not a way to force compaction mid-turn.
- **Web profile only** — declared `platform: web`; there is no terminal-surface equivalent.

## AI disclosure

This package was **written by an AI agent**, not by a person typing the code. It was produced by DeepSeek Harness running the `deepseek-flash` model in a session directed by its human publisher ([@liutian11451-png](https://github.com/liutian11451-png)), on 2026-09-12. The human chose the feature, approved the approach, ran the app, and reported the behaviour; the agent wrote the source, tests, build configuration, and documentation in this repository. The same disclosure is recorded in machine-readable form under `aiDisclosure` in `package.json`.

Treat the code accordingly: read it before you install it, and treat the `allowBuilds` permission a git install asks for as permission to run unreviewed generated code on your machine.

### What has been verified

- `pnpm test` — 8 component tests, green, including a regression test for a busy-label latch bug that was found in real use
- `pnpm typecheck` — clean
- `node smoke.mjs` — 21 loader-contract assertions against the built artifact: the closure-factory handoff, the exported `apply`/`inject` face, the registered seat and order, and all three admission folds
- The GitHub Actions workflow in this repository runs those four steps on every push, and has passed
- The plugin was installed into a live web profile and used there; the behaviour above is what was observed
- A GitHub install (`dsh plugin add github:…`) was performed end to end, including the `prepare` build on the consumer side

### What has not been verified

- **No human line-by-line review.** The publisher verified the behaviour in the running app, not the source.
- **No security audit.** Nothing here was examined for hostile or careless behaviour beyond what the tests and the described behaviour cover.
- **One machine, one platform.** Development, testing, and live use all happened on Windows with Node 24 and pnpm 11. The CI workflow runs on Linux, so the build is exercised on two platforms, but the UI has only been seen on one.
- **No clean-machine install test.** The publishing machine already had a plugin install in its profile; an install onto a profile that has never held this plugin was not exercised.
- **No test of the button against a deployment that lacks `/compact`** beyond the stubbed `matched: false` path in the tests.

## License

MIT

Install

dsh plugin --profile web add github:liutian11451-png/dsh-plugin-compact-button

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