Skip to content
dsh.fish
Bundle

dsh-file-changes

Per-turn file-change panel: lists created/modified files at the end of every answer, shows their diffs, and reveals them in the OS file manager

Source
mixin-ai
License
MIT
Updated
Updated 2 hours ago

Readme

# dsh-file-changes

A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web plugin that
shows a **file-change panel at the end of every answer**. When a turn creates or
modifies files, the panel lists each one under the closing message with three actions:

- **Open** — click the file name to open it with the OS default application;
- **View diff** — a modal renders the turn's actual applied changes (whole-file
  content for new files) using the harness DiffBlock primitive;
- **Reveal** — locate and select the file in the OS file manager
  (macOS `open -R`, Windows `explorer /select,`, desktop Linux opens the
  containing directory). The action appears only on loopback access with a
  native opener available.

The panel complements the built-in "Produced" row: it adds created/modified
badges, per-file diffs, and per-file filesystem reveal.

## Install

```sh
# from GitHub
dsh plugin --profile web add git+https://github.com/mixin-ai/dsh-file-changes

# from a local checkout
dsh plugin --profile web add link:/path/to/dsh-file-changes
```

Restart `dsh web`, then refresh the browser page.

## How it works

- **Native mode** — the client half registers a conversation definition (like
  `@deepseek-ai/dsh-client-ui-deliverables`) that accumulates successful mutation
  tool calls from their presentation views (`card: 'diff'` hunks, or generic
  `kind: 'edit'` locations) into turn-scoped data published under the
  `fileChanges` key, and renders it through the chat view's
  `conversation.chat.turnTail` slot chain.
- **Code Mode (`run_code`)** — nested dispatches carry no presentation views
  on the wire, so the host half listens to `tools/execute` / `tools/result`
  for executions with a `parent` (Code Mode sub-calls), rebuilds change
  records from the `write` / `edit` / `str_replace_editor` arguments, and
  serves them over `/api/file-changes/changes`. The panel merges both
  sources, deduplicated by path.
- **Reveal** — `POST /api/file-changes/reveal` validates a JSON payload,
  loopback origin, and an absolute existing path before handing it to the
  platform opener.

## Structure

| File | Role |
| --- | --- |
| `lib/index.js` | Host half: nested-dispatch tap + the two HTTP routes |
| `lib/client.js` | Browser bundle: turn accumulator + panel/diff/reveal UI |
| `cordis.patch.yml` | Bundle patch mounting the dual-half row |
| `smoke.test.mjs` / `client.test.mjs` | Host and client logic tests |

Run the tests with:

```sh
node smoke.test.mjs && node client.test.mjs
```

## Limitations

- Files created indirectly by terminal commands (e.g. `bash`) are not
  detected — the same vocabulary limit as the official produced-files row.
- Host-side Code Mode records live in memory (2-hour / 2000-per-session ring);
  a server restart clears them.
- The reveal endpoint trusts loopback same-origin JSON requests only.

## License

MIT

Install

dsh plugin --profile web add github:mixin-ai/dsh-file-changes

Profile: web

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