dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
OnlyOffice document viewer/editor plugin for DeepSeek Harness — open docx/xlsx/pptx from the sidebar, edit and save back (client-side static SDK, no Document Server).
English | 中文
A DeepSeek Harness plugin that opens .docx / .xlsx / .pptx files from the Harness sidebar file managers and edits them in an embedded OnlyOffice editor — client-side static SDK, no Document Server, no backend conversion service. Documents never leave the machine; the only network traffic is fetching the OpenOffice-format engine assets once (cached on disk).
| Package | @dake6767/dsh-onlyoffice (npm) — linked directory install in the desktop profile |
| Host half | lib/index.js — /dsh-onlyoffice/* routes (SDK proxy + cache, read/write, diagnostics) |
| Client half | lib/client.js — one module-loader bundle, three consumers of the vendored engine |
| Engine | onlyoffice-web-comp vendored under vendor/onlyoffice-web-comp (patched: vendor/PATCHES.md) |
ctx.documentPreviews plus the
keyed sidebar.right.tab.document slot (loading: 'renderer').ctx.betterSidebar.registerFileViewer. The service is awaited across load
order (get → optional inject → bounded poll), so the two plugins compose in
either boot order.⌘S / Ctrl+S inside the editor (the vendor's save-shortcut blocker is
re-pointed at this plugin) and the editor's own save affordance
(onSave → ONSAVE) both write the document back.POST /dsh-onlyoffice/diagnostic (appended to <cacheDir>/.requests.log).documentPreviews + slots (the shipped
@deepseek-ai/dsh-client-ui-sidebar-documentpreview) and, for the optional
path, dsh-better-sidebar.Deployments behind a reverse proxy are supported: the plugin resolves its routes against the page directory, so a GUI served at
https://host/app/<id>/works the same ashttp://127.0.0.1:53803/or the desktop shelldsh-app://app/.
The bundle is a linked directory; plugin_manager install_bundle with
target: /Users/wuliqi/projects/dsh-onlyoffice adds the dependency and the
profile bundle row. A page refresh (Cmd+R) loads client changes; host-half
changes need a full DSH restart (HMR is not reliable for the linked host
module).
node build/build-client.mjs # vendor + src/client -> lib/client.js (582 KB)
node build/build-host.mjs # host/*.js -> lib/*.js
node --test "test/**/*.test.mjs"
The SDK tree is ~19.6k files / 1.1 GB and is distributed separately. The Host reads a prepared shared copy when configured, then falls back to its writable member cache and upstream mirrors.
GET /dsh-onlyoffice/sdk/onlyoffice/<version>/<rest>
shared hit -> <DSH_ONLYOFFICE_SHARED_CACHE_DIR>/<version>/<rest>
member hit -> <cacheDir>/<version>/<rest>
cache miss -> <mirror>/onlyoffice/<version>/<rest> (first working mirror)
Default ordered mirrors (failover on network error / timeout / 404 / 5xx):
https://onlyoffice-web-comp.vercel.app/packageshttps://cdn.jsdelivr.net/gh/electroluxcode/onlyoffice-web-comp@main/public/packageshttps://raw.githubusercontent.com/electroluxcode/onlyoffice-web-comp/main/public/packagesDefinitive 404s (e.g. dictionaries/en_US/*, absent from every mirror) are
remembered for 10 minutes so they do not re-walk the mirror chain on every
render.
cordis.patch.yml row onlyoffice)- id: onlyoffice
name: '@dake6767/dsh-onlyoffice'
config:
version: '9.4.0-develop' # SDK directory segment (client reads it from /status)
upstreamBase: 'https://onlyoffice-web-comp.vercel.app/packages'
upstreamFallbacks: [] # [] = single source; omit for the defaults above
cacheDir: '~/.dsh/onlyoffice-sdk'
fetchTimeoutMs: 300000 # upstream budget per asset
saveEnabled: true # false disables the write route
autoSave: false # true enables the debounced background writer
# (manual Cmd/Ctrl+S and the editor save button always work)
maxSaveBytes: 268435456 # 256 MiB write cap
Offline / intranet: pre-populate cacheDir with the same directory layout, or
point upstreamBase at a self-hosted static copy.
Set DSH_ONLYOFFICE_SHARED_CACHE_DIR (0.1.9+) to a prepared SDK root visible to
each Host process:
export DSH_ONLYOFFICE_SHARED_CACHE_DIR=/opt/onlyoffice-sdk
# Expected asset: /opt/onlyoffice-sdk/9.4.0-develop/web-apps/apps/api/documents/api.js
Mount this directory read-only for members. Shared hits contact no upstream and write nothing into the shared tree. Missing, inaccessible or non-file entries fall back to the member cache; symlinks resolving outside the shared root are ignored. A newly available shared file takes priority over both a member copy and a remembered upstream 404.
Downloads and request logs stay in the writable cache. Its existing precedence
is unchanged: explicit plugin cacheDir, then DSH_ONLYOFFICE_CACHE_DIR, then
$DSH_HOME/onlyoffice-sdk. The older DSH_ONLYOFFICE_CACHE_DIR setting still
selects a writable cache; use the separate shared setting for a read-only mount.
/status file and byte counts describe only the writable cache.
/sidebar/*)| Route | Purpose |
|---|---|
GET /status | {version, sdkBaseUrl, upstreams, cacheDir, files, bytes, lastError} |
GET /sdk/onlyoffice/<ver>/<rest> | SDK proxy + disk cache (immutable headers) |
GET /read?sessionId&path[&cwd] | document bytes + x-dsh-file-version (renderer mode) |
POST /save?sessionId&path[&cwd][&mtimeMs] | atomic write-back of raw document bytes |
POST /diagnostic | bounded browser diagnostic line → .requests.log |
Write safety (the only writer in the plugin): target must already exist and
be a regular file inside the session workspace (fs.contains, realpath fallback);
extension must be docx/xlsx/pptx (the engine's native output — writing docx
bytes over .odt/.doc/.csv would corrupt them, those stay export-only); optional
mtimeMs is an optimistic lock (409 instead of clobbering a changed file);
same-directory temp file + rename, original mode preserved.
DSH spaces can serve the workspace at /app/<spaceId>/. On such a page the
plugin routes are reachable only under that prefix; the same routes at the
origin root are rejected by the connection fence with 403 Forbidden. The
client therefore probes the candidates at startup (page directory → origin →
root-relative) and reuses whichever answers GET …/status with JSON.
Run this in the page console to see exactly what each base returns:
await window.__dshooProbe()
It reports HTTP status, content-type, timing and a body prefix for both
/status and the SDK api.js, so 403 / text/plain (fence) is easy to tell
apart from 200 / text/html (SPA fallback) or a timeout.
| What | Formats |
|---|---|
| Opened in OnlyOffice (built-in preview & better-sidebar) | docx doc odt rtf · xlsx xls ods csv · pptx ppt odp |
| Written back to the original file | only docx xlsx pptx (the engine's native output; writing docx bytes over .odt/.doc/.csv would corrupt them) |
| Other formats (still previewed/edited by DSH's own viewers) | text, markdown, code, images, pdf, html… |
| Parsed by the engine but not usable in this SDK export | pdf/pdfa/djvu/xps (needs the pdfeditor app), Visio vsdx/vssx/vstx/... (needs visioeditor) — the shipped static SDK contains only documenteditor/spreadsheeteditor/presentationeditor, and api.js maps documentType: 'pdf' to pdfeditor, so those 404 |
| Engine input formats not registered here | txt html mht epub fb2 mobi docm dotx dotm fodt ott oform docxf xlsm xltx xltm xlsb fods ots ppsx pptm ppsm potx potm fodp otp — add the extension to NATIVE_EXTENSIONS / VIEWER_EXTS and a MIME entry to enable, but keep them read-only/export-only |
The extension must match the actual content (x2t picks its parser by extension).
PDF deliberately stays on DSH's native viewer: it renders the embedded glyphs
directly, while routing it through OnlyOffice would require a separate
pdfeditor application and a conversion round-trip.
refreshFile path is unreliable in this SDK build
and is only a documented vendor patch, not the default.dsh-resource://file/absolute/... addresses carry no session, so save-back is
unavailable for them (viewing works).| Symptom | Check |
|---|---|
First open very slow / loading engine | expected cold download; watch <cacheDir> grow |
编辑器渲染超时 | viewer error detail shows console errors + iframe state |
404 for dictionaries/en_US/* | harmless (spellcheck dictionaries absent upstream), negative-cached |
Save fails with conflict | file changed on disk since load — reload first |
Save fails with method not allowed | the running Host predates the save route — restart DSH |
| Blank sidebar after a plugin update | client bundle crash — the viewer reports [console-*] lines; check .requests.log |
<cacheDir>/.requests.log records every SDK/read/save/diagnostic request with
status and duration (2 MiB rotation) — the fastest way to see what the browser
actually did.
This package is distributed under the GNU Affero General Public License v3.0
(see LICENSE); first-party sources carry
SPDX-License-Identifier: AGPL-3.0-only headers.
vendor/onlyoffice-web-comp is upstream
electroluxcode/onlyoffice-web-comp,
also AGPL-3.0, modified per vendor/PATCHES.md; its
license text is kept at vendor/onlyoffice-web-comp/LICENSE.x2t WASM
build) are recorded in THIRD_PARTY_NOTICES.md;
read that before publishing, self-hosting a mirror, or shipping commercially.OnlyOffice is a trademark of Ascensio System SIA; this plugin is an independent integration.