deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
An embedded Overleaf workbench plugin for DeepSeek Harness (DSH) Web. It adds a fourth tab next to Chat / Trajectory / Context on the session page: the tab loads your Overleaf site (public cloud or self-hosted such as https://tex.nju.edu.cn) through a same-origin reverse proxy, so the page renders and stays fully operable — editing, compiling, PDF preview — while the native DSH composer stays below it, with selection quoting, caret insertion, and LaTeX assist panels wired between the two.
+--------------------------------------------------------------+
| Session tabs: Chat | Trajectory | Context | [Overleaf] |
+--------------------------------------------------------------+
| toolbar: reload / open window / login / cookie / panel |
| +----------------------------------------------------------+ |
| | https://.../overleaf-proxy/... (same-origin iframe) | |
| | full Overleaf editor, compiler, and PDF preview | |
| +----------------------------------------------------------+ |
| floating quote CTA - selection bridge |
| status strip / assist panel (AI write, selection AI, outline)|
+--------------------------------------------------------------+
| DSH composer (native, untouched) |
+--------------------------------------------------------------+
0.1.1-rc.2, web profile (http://127.0.0.1:3080)dsh-plugin.json per the dsh-std interoperability spec; classic dual-face bundle loading remains the primary activation path.The Overleaf editor running inside a DSH conversation tab — full editor with project file tree, and the DSH composer stays below:

Split view: LaTeX source and PDF preview side by side, with Recompile — compile, preview, and iterate without leaving the conversation:

Assist panel — three tools side by side: AI write & auto-captured insert, selection AI with reviewed replace, and compile fix (log errors/warnings with one-click agent fixes):

[ ai-insert ] — describe the change, the DSH agent writes it, and the panel automatically captures the agent's output into the custom-content box — review it, then insert at the editor caret.[ selection-ai ] — select text in the editor, ask the agent to explain or rewrite it, review the replacement, then replace the original selection. Source/selection drift checks are on by default and can be unchecked to force replacement at the saved anchor (file switches are still refused).[ compile-fix ] — read the compile log's errors and warnings after a Recompile, then let the agent propose fixes for the currently open document..bib sync — both ai-insert and selection-ai offer “Update Overleaf .bib”: recursively auto-detect workspace bibliographies or accept an absolute/relative path inside the current DSH workspace, then update the same-named Overleaf document and wait for autosave confirmation..tex sync — the assist panel's Status page defaults to saving the current Overleaf source into the workspace: it recursively detects local .tex files and creates a same-named root file when none exist. The reverse “Local → Overleaf” direction can use a selected local file or manually pasted complete LaTeX, but requires an explicit whole-document warning confirmation plus document-ID, revision, snapshot, write-verification, and save-event checks.Overleaf sends X-Frame-Options / CSP frame-ancestors on every response, so a plain <iframe src="https://tex.nju.edu.cn"> is refused by browsers. This plugin ships an HTTP/1.1 reverse proxy inside the DSH host process: all browser traffic goes to /overleaf-proxy/<original-path> which forwards to your configured upstream origin — one fixed origin, locked by configuration, no open SSRF surface. Because the iframe and the GUI then share one origin, browser-level bridges become possible: text selections flow out of the embedded editor into the composer as structured quotes, and generated content can be written back at the editor caret.
| Requirement | Status |
|---|---|
| R1 · fourth session-page tab | conversation.view entry id:"overleaf", order:30; visible whenever the tab bar shows (tabs >= 2) |
| R2 · configurable site address | Settings page (Settings > Plugins > Plugin configuration > dsh-overleaf) edits baseUrl; saving hot-swaps the proxy target without a restart |
| R3 · original site features usable | Streaming reverse proxy preserves paths and query strings; responses pass through minus framing headers; small HTML bodies get link/asset rebasing plus the bridge script |
| R4 · native composer below | The view replaces only the message area; composer, workspace recording, deliverables untouched |
| R5 · selection quoting | selectionchange in the iframe surfaces a floating quote button; clicking inserts a structured quote chip through the official reference pipeline (inputTriggers.registerSource({name:'quote-ref'}) codec), falling back to plain-text block quotes when absent |
| R6 · generate at caret | Template inserts and free-form/agent-generated LaTeX write to the live cursor through CodeMirror APIs (CM5 primary, CM6 probe, editable fallback); agent output is captured into a review box before insertion |
| R7 · assist features | Assist panel: AI writing; selection questions and reviewed replacement (safe checks by default, explicit force mode available); safe local .bib synchronization; bidirectional current Overleaf/workspace .tex synchronization (Overleaf-to-local by default, explicit confirmation and revision checks for reverse whole-document replacement); reviewed compile-log fixes; document outline navigation; login/logout/cookie management; status reporting |
The npm package name dsh-overleaf is occupied by another project, so this plugin is not published to npm — install it from GitHub instead. The repository commits the prebuilt lib/ bundle, so git installs need no build step and no allowBuilds authorization:
# From GitHub, tracking the main branch (recommended for latest features):
dsh plugin --profile web add github:gychen-NJU/dsh-overleaf
# Or pin an exact released version:
dsh plugin --profile web add github:gychen-NJU/dsh-overleaf#v0.3.9
From a release tarball (download the .tgz attached to the latest release):
dsh plugin --profile web add ./dsh-overleaf-0.3.9.tgz
Then restart the web service once (client bundles join the boot graph at startup):
dsh --profile web web # or however you normally start it
Verify composition survived:
dsh --profile web --dump-config # expect a "# == dsh-overleaf" block
The default upstream is https://www.overleaf.com. To point the workbench at any other instance (self-hosted Overleaf, tex.nju.edu.cn, ...), open Settings > Plugins > Plugin configuration > dsh-overleaf, change baseUrl, and save — the proxy target hot-swaps without a restart.
Uninstall cleanly at any time:
dsh plugin --profile web remove dsh-overleaf
Deliberate isolation from existing plugins/configs:
| Surface | dsh-overleaf claim | Other known claims |
|---|---|---|
| Cordis row id | overleaf-workbench |
overleaf (better-overleaf) |
| Client module id | dsh-overleaf (must equal the package name) |
dsh-better-overleaf |
| HTTP routes | /overleaf-proxy/*, /overleaf/workbench/* |
/overleaf/* (better-overleaf), /api/dsh-browser/* |
| WS upgrades | /overleaf-proxy/socket.io[/] exact |
none known |
| Credential ref | OVERLEAF_WORKBENCH_COOKIE |
OVERLEAF_COOKIE / OVERLEAF_GIT_TOKEN |
| Data dir | ~/.dsh/plugin-data/dsh-overleaf-workbench/browser-profile |
~/.dsh/plugin-data/dsh-overleaf/... |
| Conversation view id | overleaf order 30 |
chat 0 / trajectory 10 / context 20 |
Both halves fail soft: a missing credentials service disables stored cookies (manual-paste mode degrades per request), missing settings skips the settings card, and any client-half exception logs instead of throwing so GUI boot never breaks.
src/
index.ts host re-exports + default Service class (cordis loader target)
service.ts routes, status/login/projects ops, settings namespace wiring
config.ts schemastery schema + defaults + origin normalization
proxy.ts ReverseProxy: streaming HTTP proxy + raw upgrade tunnel
inject-script.ts source of the browser bridge script (bridge.js)
login-cdp.ts direct-CDP login (ported from Hoemr/dsh-better-overleaf, MIT)
credentials.ts OVERLEAF_WORKBENCH_COOKIE credentialRef
types.ts wire shapes
client/
index.ts client half apply(): dictionaries, quote-ref source, view slot,
settings card slot (soft settingsScope wait)
view.tsx OverleafView component (toolbar/iframe/CTA/panel/dialog)
workbench.ts root ctx capture, quote registry, composer insertion helpers
settings-card.tsx staged settings form keyed by namespace 'dsh-overleaf'
locales.ts zh/en flat dictionaries (zh canonical)
scripts/
smoke-offline.mjs fake-context harness: route census, JSON flows, HTML rewrite
assertions, cookie/logout lifecycle, client factory
materialization + apply() against stub services
smoke-live.mjs boots the REAL @deepseek-ai/dsh-host-webserver on an
OS-assigned port, aims the proxy at a local fixture upstream,
and verifies rebase/injection, Set-Cookie scoping, binary
streaming, JSON routes, a genuine RFC6455 tunnel round trip,
and the bridge.js asset route
Request path summary:
/overleaf-proxy/<path>?<query> from the DSH server.Origin, cookies merged with the stored credential when present, identity encoding kept for textual bodies).X-Frame-Options dropped, frame-ancestors removed from CSP, absolute redirects rebased under the prefix, Set-Cookie domain attributes stripped so cookies land host-only.text/html bodies up to 4 MB are buffered once: root-relative href/src/action/poster/data-src and srcset references get the prefix, and <base href="/overleaf-proxy/"> plus the bridge script are injected right after <head>. Larger HTML and every other content type stream untouched.Inside the proxied document the bridge script installs defensive wrappers (fetch, XMLHttpRequest.open, EventSource, WebSocket) so late-created root-relative URLs also land under the prefix, reports CodeMirror-native selections with safe anchor tokens, watches fresh/cached compile responses and Overleaf's own output-log requests to capture output.log/.blg for the auto-fix panel, exposes caret insertion/selection replacement with default conflict checks and explicit force mode/outline/reveal commands, and keeps a localStorage snapshot before each mutation for rollback.
Two paths, both feeding the same credential store:
auto finds default + installed Chromium builds; explicit channel/path available) with a reserved loopback debug port and its own profile under ~/.dsh/plugin-data/dsh-overleaf-workbench/browser-profile. Sign in once and keep that window open; the plugin polls Storage.getCookies/Network.getAllCookies until (1) at least one non-preference cookie exists for the configured host, (2) a tab sits on the origin outside its login/SSO pages, and (3) the assembled header passes a tolerant server-side check. This works for standard Overleaf AND TeXPage-based deployments (such as tex.nju.edu.cn) whose session cookie names differ. Closing the login window early aborts capture immediately — paste the cookie instead. The login route returns immediately and the view polls progress, so the toolbar never wedges.When logging into www.overleaf.com from a CN network, the proxied embedded page may be blocked by Google reCAPTCHA (see the CAPTCHA notes below), so pasting a copied cookie is the recommended path:
F12 (or Ctrl+Shift+J) to open the Web DevTools console → the Application tab;overleaf_session2 entry and copy the full value from its Cookie Value field;overleaf_session2=<Cookie Value> and paste it into the toolbar dialog.
Overleaf's login is protected by Google reCAPTCHA hosted on google.com/gstatic.com. Two consequences:
loginProxyServer (Settings > Plugins > dsh-overleaf, or the composed row) to your proxy client's HTTP endpoint — http://127.0.0.1:7890 for a typical Clash setup, a bare port works too — and the login browser is launched with --proxy-server. Leave it empty to use the system default. Without reachability you will see "captcha not available".No cookie value ever passes through plugin config, route payloads (beyond your paste), logs, or client storage.
127.0.0.1/::1); non-loopback callers get 403 before handlers read bodies.baseUrl like any tool allowed to hold your LaTeX account session: configure private/internal Overleaf instances only if your workstation is the trust boundary.Secure cookies are accepted over http://127.0.0.1:3080 on modern Chrome/Firefox/Edge because loopback is trustworthy, but old browsers may drop them; host-side injection still works regardless./overleaf-proxy/socket.io[/] — the bridge wrapper rewrites the standard paths; exotic transports bypassing it fall back to polling.<base>; anything opening sockets outside these paths needs manual routing rules.DSH_OVERLEAF_DEBUG=1 on the host to log stripped CSP frames.pnpm install
pnpm build # tsc -b (types + runnable ESM/CJS emitters) then tsdown
pnpm test # smoke-offline.mjs + smoke-live.mjs (no DSH instance needed)
pnpm typecheck
Build produces lib/index.js (node half, ESM) and lib/client.js (browser half, lazy-CJS closure registered via window.__ModuleLoader__.load({ id:'dsh-overleaf', factory }) — the module id MUST equal the npm package name, which is what dsh-client-modules matches each served /plugins/<pkg>/client.js bundle against). Only React (+jsx-runtime) may be required from platform seeds in the client bundle; everything else inlines — the purity gate mirrors the community convention.
To try local changes in a real profile, pack and add the tarball, restart the web service, and watch both DevTools consoles (shell + iframe) prefixed [dsh-overleaf].
0.1.1-rc.2 web profile; peer ranges accept >=0.1.0-rc.5 for host services and cordis ^4.0.1.^22.19 || >=24.dsh-better-sidebar/dsh-better-overleaf/dsh-context/paperlab et al.; see the coexistence table.dsh-plugin.json follows dsh-std Community v0.15; hosts implementing @dsh-std/adapter-dsh discover the manifest statically, while ordinary profiles simply ignore it.login-cdp.ts with domain-parameterized filtering and a dedicated profile directory.CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。