MathieuPortmann/dsh-edit-panel

dsh-edit-panel

DSH plugin: live writing panel - the AI writes text/Markdown files section by section in a side editor you can type in; rewrites become proposals

待分类co-editingdeepseek-harnesseditor

dsh-edit-panel

Live writing of text files for DeepSeek Harness (DSH): the AI writes a text or Markdown file section by section into an editor in the right sidebar, and you can type in the same file at the same time.

Maintenance: best-effort. Issues may go unanswered; forks are welcome.

What it adds

  • Five tools for the model, in every conversation:
  • edit_begin(path, outline, title?) creates the file with its headings and opens the panel;
  • edit_write_section(section, content) writes one section, saved to disk at once;
  • edit_status() says what is written, what you changed, and what to do next;
  • edit_finish() ends the draft;
  • edit_open(path) shows an existing file in the panel without changing it.
  • The panel (a right-sidebar tab, *Live writing*): each section in a small word-processor editor

(bold, italic, headings, lists, quotes, links, undo; read and written as Markdown). What you type is saved after a short pause, and the AI cannot overwrite a section while you are typing in it.

  • Proposals instead of overwrites: when the AI rewrites a section that already has text, the

file does not change; the panel shows its proposal word by word (added in green, removed struck in red), and you keep or refuse each change, or all of them.

  • Existing files are safe: an existing file is drafted in .draft and replaces the original

only when you press Finish (the original is copied to the backup folder first); Cancel discards the draft. A file opened with edit_open is edited in place, after a backup copy.

  • Ask the AI about a passage: select text, then the *✦ Ask the AI* pill (or Ctrl+K) puts the

passage, with its section, in the message box, with quick actions (shorten, rephrase, fix, translate).

  • Documents of the conversation: a drawer above the message box lists the files opened in this

conversation; a click reopens one. A click on a text file link name in the conversation opens it in the panel.

  • Your instructions per section and your decisions are given back to the model as runtime context,

so they survive compaction.

Files: .md, .markdown, .txt, .text, .tex, .org, .rst, .qmd, .rmd, inside your home folder and not in a hidden folder. In Markdown files, sections are the ## headings.

The interface is in English, and in French when DSH's language is French (tables en and fr at the top of client.js).

Install

dsh plugin --profile web add github:MathieuPortmann/dsh-edit-panel

Restart the profile afterwards. Requires Node ^22.19.0 || >=24 and DSH >=0.2.0-rc.2 <0.3.0 (see Compatibility). Once the package is on npm, dsh plugin --profile web add dsh-edit-panel works too.

Configuration

Options of the edit-panel row:

Option · Default · Meaning dataDir · /edit-panel · state of the drafts (one JSON per conversation) and the document list backupDir · /backups/edit-panel · copies of files before they are replaced or opened announce · true · one line in every conversation telling the model that text files are written through the panel; set false to use the tools only when asked

How it works

  • lib/draft.js holds the drafts: it renders the file from its sections, reads it back to see

what you changed (a fingerprint per section), keeps proposals waiting, locks a section for 30 s while you type, and replaces or restores files with backups. lib/docs.js keeps the document list. Both are pure Node.js and covered by tests/.

  • index.js (host side) registers the tools, sends the draft state as runtime context, and serves

the panel through an RPC channel at /edit-api/, behind DSH's own connection check.

  • client.js (page side) draws the tab, the drawer and the editors. The editor itself

(web/editor.js) is a bundle of ProseMirror and markdown-it built from web-src/editor.js; the page receives it from the host and loads it once.

Compatibility

Component · Supported Node.js · ^22.19.0 \ · \ · >=24.0.0 (engines.node) DSH · >=0.2.0-rc.2 <0.3.0; declared as optional peerDependencies on @deepseek-ai/dsh-tools and @deepseek-ai/schemastery, the only DSH packages the host side imports Platform · Linux (tested); pure JavaScript, no native addon Page · DSH's web UI with the right sidebar; the drawer finds the message box by its editable area and may need an update when the page changes

Tested with DSH 0.2.0-rc.2 on Node 22.23 (see Verification).

Permissions and external services

Everything the plugin can touch, and what happens when it fails:

Capability · Where · Used for · If it fails Files · lib/draft.js, lib/docs.js · writes the text files the model drafts and the files you open in the panel, only inside your home folder, never in hidden folders, only the text extensions above; .draft working copies; backup copies in backupDir; state in dataDir · the tool or the panel shows the error; nothing is written Network · none · nothing leaves the computer · n/a Commands · none · no child process, no shell · n/a Tools for the model · index.js · edit_open, edit_begin, edit_write_section, edit_status, edit_finish (see above) · an error text is returned to the model HTTP route · index.js (ctx.webServer.register) · POST /edit-api/ for the panel, behind ctx.connection.admit() (DSH's Host/Origin fence and token); JSON bodies only, limited to 1 MiB · non-admitted requests get 401/403; other errors are returned in the RPC envelope Dynamic module loading · index.js (importFromDsh) · loads @deepseek-ai/dsh-tools and @deepseek-ai/schemastery from the DSH installation that runs the plugin. Nothing is downloaded · the plugin fails to load Code evaluation in the page · client.js (loadLib) · the editor bundle, read by the host from this package's web/editor.js, is turned into code with new Function once (or, under a strict content policy, loaded as a blob script). No other text is ever evaluated, and nothing comes from the network · the panel shows "Editor unavailable" and the sections as plain text Interface · client.js · a right-sidebar tab, a drawer above the message box, a click handler on text file links of the conversation, the font choice saved in the browser's localStorage; registers a French dictionary and language entry with DSH's locale service · no panel

Verification

Checked on a disposable profile (DSH_HOME pointing at a temporary folder, so the real profile is never touched):

npm pack
dsh plugin --profile t add file:$PWD/dsh-edit-panel-0.1.0.tgz   # install
dsh t --port 3095 --no-open                                      # start: plugin loads, no error
dsh plugin --profile t remove dsh-edit-panel                      # uninstall

npm test runs 9 standalone tests (drafts: new and existing files, the user's edits, locks, proposals kept, merged or refused, open in place, cancel, duplicate headings, path rules; the document list) with no DSH installation needed.

web/editor.js is reproducible: cd web-src && npm ci && npm run build rebuilds it byte for byte with the versions pinned in web-src/package-lock.json (esbuild 0.28.2). The bundled libraries and their licenses are listed in THIRD_PARTY_NOTICES.md.

Develop

npm test
cd web-src && npm ci && npm run build   # after changing web-src/editor.js

License

MIT for this plugin. The bundled libraries keep their own licenses (MIT, and BSD-2-Clause for entities), see THIRD_PARTY_NOTICES.md.