huenjie/dsh-paste-collapse

dsh-paste-collapse

dsh-plugin

Uncategorizeddsh-plugins

中文 | English

dsh-paste-collapse — DSH static plugin: auto-collapse large pasted text

A true static Cordis plugin package (dual-half: Host + browser Client). After being added to a dsh web profile, it loads automatically on the next dsh web restart — no dynamic rebuild, no re-authorization.

Compatible with dsh v0.1.2-rc.1.

Features

1. Auto-collapse large pasted text

When you paste text into the AI input box:

Pasted contentBehavior
Real line break (still multi-line after trimming)Collapsed immediately, regardless of length
Single line, ≥ 100 charsCollapsed
Everything elsePasted as-is

"Pseudo" newlines don't count: leading/trailing whitespace and blank lines (e.g. the trailing \r\n that comes with copied commands) are trimmed before the check, and a lone \r (char 13) — invisible in the web UI — doesn't count either. A real line break means the text is a paragraph → collapse; line counts are computed from the trimmed content, while storage and ↺ restore keep the original characters.

  • After collapsing, only a [Paste #N +M lines] marker remains in the input box (N is a small sequential integer, no verbose timestamps; after naming it becomes [Paste #N | name +M lines]), and the text on both sides of the insertion point is preserved.
  • The full text is persisted in browser localStorage (up to 32 entries, 50,000 chars each); the Host side keeps the last 8 entries in process memory as a fallback and never writes to disk on the Host.
  • In the input box's image-insert area (where pasted images appear), a label chip is rendered (buttons and number only), left to right:
    • 👁 Preview: click to open a scrollable card with the full content; close it by clicking anywhere outside the card, the ✕ in the top-right corner, or clicking the same 👁 again (no auto popup/hide on hover)
    • ✎ Name it: give this block a name (e.g. Version A), which updates the input label to [Paste #N | Version A +M lines] and also shows in the send block; submitting empty clears the name. The number cannot be changed (the number is the unique id assigned by the plugin)
    • ↺ Restore original: writes the corresponding label back as plain original text (no block decoration) for further editing in the input box
    • No delete button: just delete the label text in the input box and the chip disappears
  • After a page refresh, [Paste #N +M lines] labels are restored from the browser cache first, so they never become dead plain strings when the client memory is cleared; the sequence number is also persisted so old numbers are not reused.
  • On send, labels in the message are automatically expanded to the full original text at the moment of sending (local cache first, Host fallback) — the model receives the original text directly, no tool call needed; the input box keeps the label style.
  • Expanded text is wrapped with a pair of pure marker lines (zero commentary, original content unchanged) whose numbers exactly match the input labels, carrying only: number, optional custom name, line count, e.g.:
    [Paste #12 | Version A | 342 lines]
    <original text>
    [End #12]
    
    [Paste #13 | Version B | 210 lines]
    <original text>
    [End #13]
    
    So multiple consecutively pasted blocks (e.g. two code snippets to compare) stay clearly delimited on the model side, with numbers matching the input box, without any explanatory text added by the plugin.
  • All three places share one consistent concise wording: input box [Paste #N +M lines] (with | name after naming), chip name #N, send block [Paste #N ...] / [End #N] (same number — no mismatch such as #12 in the input box but #1 sent to the AI); ↺ restores plain text without block decoration.
  • Old-version [Pasted text #N +M lines] labels are still recognized, expanded and editable (backward compatible).
  • Slash commands with parameters (e.g. /agent-teams [long text]) expand parameters before command submission, but without block decoration (pure replacement) so command parsing is not broken.
  • Only when the original text cannot be retrieved (e.g. browser cache cleared and the Host process restarted) is the label sent as-is; the agent can then call the myds_read_captured tool to read the full text by number.

Directory structure

dsh-paste-collapse\
├── package.json        # package manifest: dsh.bundle.patch + dsh.client (zero dependency)
├── cordis.patch.yml    # mount declaration: inserts dsh-paste-collapse into the profile plugin tree
├── lib\
│   ├── index.js        # Host half: /myds/captured route + myds_read_captured tool
│   └── client.js       # browser half: paste interception + label editing + text persistence + auto expansion on send
├── test\
│   └── expander.test.cjs  # smoke test
├── README.md           # this document (中文)
├── README.en.md        # this document (English)
└── LICENSE             # MIT license

Usage

Install:

dsh plugin --profile web add dsh-paste-collapse

Remove:

dsh plugin --profile web remove dsh-paste-collapse

Restart dsh web after installing/removing.


Development

# Install from a local directory (after changing code, run remove + add again; adding the same version does not update — bump the version number)
dsh plugin --profile web add /path/to/this-repo