Bundle
dsh-table-attach
Paste or drag non-image files (xlsx/csv/pdf/zip…) into the DSH web composer: files are saved into the session workspace and an @reference is inserted.
- Source
- yybukn
- stars
- 1 stars
- License
- MIT
- Updated
- Updated yesterday
Readme
# dsh-table-attach
Paste or drag **tables & documents** (`.xlsx`, `.csv`, `.pdf`, `.zip`, …) into the
DSH web composer. The file is saved into the current session's workspace and an
`@reference` is inserted at the caret, so the agent reads the real file.
> The official DSH composer only accepts images (PNG/JPG/WebP/GIF) on paste/drop.
> This plugin adds non-image file attachments.
## Features
- **Paste & drop**: works for file pastes (`⌘C` a file, then paste) and drag-and-drop.
- **Any non-image file**: spreadsheets, CSVs, documents, PDFs, archives, JSON, …
- **Saves into the session workspace**: files land in `<workspace>/attachments/`
(auto-renamed with a `-1`/`-2`… suffix on name clashes).
- **Inserts an `@reference`**: e.g. `@attachments/report.xlsx` (quoted as
`@"attachments/my report.xlsx"` when the name contains spaces) — matching the
host's @-mention grammar so the agent can read the file.
- **Safe by default**: 50 MiB size cap, executable extensions blocked
(`.exe`, `.dll`, `.sh`, `.js`, …), and path-traversal-proof file names.
- **Images untouched**: PNG/JPG/WebP/GIF pastes/drops still go through the
built-in image path.
- **i18n**: zh / en toasts and drop-hint overlay.
## Install
Currently distributed from GitHub (npm publishing pending):
```bash
dsh plugin add github:yybukn/dsh-table-attach
```
For local development:
```bash
dsh plugin --profile web add /path/to/dsh-table-attach
```
## Usage
1. Open any session (it provides the workspace).
2. **Drag** a `.xlsx` / `.csv` / `.pdf` / `.zip` … into the composer, or copy a
file and **paste** it into the composer.
3. A toast reports progress; on success the composer contains
`@attachments/<file>`.
4. Send the message — the agent can read the referenced file.
> Pasting **table cell text** (copied out of Excel) is treated as ordinary text
> and passes through untouched; it is not converted into a file.
## How it works
- **Host side** (`lib/index.js`) registers a Typert Remote service
`tableAttach.saveFile(agent, payload)`. It validates the payload, keeps the
path inside the session workspace, de-duplicates file names and writes with
`0o644`. It runs as a cordis plugin (no build step — plain ESM + zod).
- **Client side** (`lib/client.js`) is a web bundle. It intercepts
`paste`/`dragenter`/`dragover`/`drop` at the document level *before* the
conversation plugin's handlers, base64-encodes the file, calls the host
remote, and inserts the `@mention` into the composer (which is a
[Lexical](https://lexical.dev/) contenteditable — insertion goes through
`execCommand("insertText")`, the same `beforeinput` path the editor itself
uses).
## Security
- Files larger than **50 MiB** are rejected before bytes cross the wire.
- Executable extensions (`.exe`, `.dll`, `.app`, `.sh`, `.js`, `.jar`, …) are
blocked.
- File names are sanitized (no directories, control characters, dotfiles or
traversal), and the target path is verified to stay inside the workspace.
- The agent only ever sees the workspace-relative reference, never an arbitrary
absolute path.
## Development
```
dsh-table-attach/
├── lib/
│ ├── index.js # host: cordis plugin + Typert Remote service
│ └── client.js # browser: interception, upload, composer insertion
├── cordis.patch.yml # loader entry for the host bundle
├── dsh.plugin.json # plugin manifest
└── package.json # exports ./client for the web platform
```
The host runs in the DSH harness (Node); the client runs in the web GUI. When
installed from npm the host's peer deps (`@deepseek-ai/cordis`,
`@deepseek-ai/dsh-typert-protocol`, `zod`) resolve from the profile's shared
dependency closure. A local `link:` install outside the profile needs those
deps made resolvable (e.g. `node_modules` symlinks into the app bundle) — these
are **not** part of the package and are git-ignored.
## License
[MIT](./LICENSE)
Install
dsh plugin --profile web add github:yybukn/dsh-table-attach
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-table-attach from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.