deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
English | 中文
A floating position P&L card for the DeepSeek Harness (DSH) web GUI. It automatically syncs your real portfolio data from the Tonghuashun investment-ledger (同花顺投资账本) — no manual stock picking. Displays 今日盈亏 (today's P&L), 上证指数 (Shanghai Composite Index), and an intraday mini chart, all in the A-share red-up/green-down convention.
Unlike watchlist tools, this plugin reads your actual positions and shows your real profit & loss — both as a percentage and as a yuan amount — updating every 20 seconds.

Plugin 0.2.1 targets the DSH 0.2 series and has been tested with Desktop 0.2.0-rc.2, without a compatibility exemption. For DSH 0.1, keep plugin 0.2.0; this migration does not support the older host.
dsh plugin --profile web add dsh-ths-holdings
Installation is pnpm add inside your web profile: the package's dsh.bundle.patch is applied to the profile layer automatically. Then restart dsh web — a floating card appears at the bottom-right corner.
To install manually (without dsh plugin), edit $DSH_HOME/profiles/web/package.json:
{
"dependencies": {
"dsh-ths-holdings": "^0.2.1"
},
"dsh": {
"profile": {
"bundles": [
// ...existing bundles,
"dsh-ths-holdings"
]
}
}
}
then cd $DSH_HOME/profiles/web && pnpm install and restart dsh web. The plugin row itself comes from the package's cordis.patch.yml — you don't write it by hand.
Recommended — auto-acquire:
Auto-acquire uses a temporary browser profile and reads cookies through browser-level commands. It does not attach a page debugger, inject scripts, or emulate viewport dimensions. Only cookies for
10jqka.com.cnand its subdomains are saved; the temporary profile is deleted after the browser exits. You do not need to open developer tools during sign-in.
If closing the window times out, profile cleanup continues when the browser actually exits. Cleanup failures remain visible in settings with a retry button. Cookie saves wait up to 30 seconds; a timeout or cancellation closes the login window, but an already submitted storage operation may still complete. The card shows that the result is unconfirmed and blocks additional saves until that operation settles, preventing an older request from overwriting a newer Cookie.
Manual saves are unavailable while automatic login is starting or running; cancel automatic login and wait for it to end before saving manually. Pending writes continue to block new writes to the same credential reference after the plugin reloads within the same DSH process, until the old operation settles.
Manual (backup):
… in Edge, ⋮ in Chrome). F12 may have no effect on this page; open the tools through the browser menu.tzzb.10jqka.com.cn. Under Headers → Request Headers, copy the complete Cookie value. Copy only the name=value; name2=value2 portion, without the Cookie: prefix; do not copy a response's Set-Cookie header.If the page reports that developer tools are unsupported, first check whether Network has already recorded a ledger request with a Cookie header. If no usable Cookie is available, use auto-acquire above. Keep developer tools open while inspecting cookies manually.
The session cookie expires eventually — when it does, the card shows a Token 已过期 banner; re-open ⚙ and click auto-acquire (or repeat manual steps 1–5) with a fresh cookie.
💡 After completing a new trade, re-upload your data from the investment-ledger app to the web version so your holdings stay consistent between the two.
fund_key is discovered from the portfolio list; multi-account selection via dropdown┌─────────────── Web browser ───────────────┐
│ lib/client.js (browser module) │
│ · shell.overlay slot → floating card │
│ · React + CSS Modules │
│ · config in localStorage │
│ │ fetch (same-origin) │
└──────────┼─────────────────────────────────┘
▼
┌─────────────── DSH Host (lib/index.js) ───┐
│ cordis plugin: webServer routes │
│ · GET /api/stock-pnl snapshot │
│ · GET /api/stock-pnl/portfolios accounts │
│ · GET /api/stock-pnl/verify cookie ok?│
│ · POST /api/stock-pnl/acquire* sign-in │
│ resolves Cookie via ctx.credentials │
│ auto-discovers user_id + fund_key │
│ POSTs Tonghuashun ledger APIs │
└───────────────────────────────────────────┘
The node half reads the login Cookie per request through the credential-reference seam (ctx.credentials). Manually pasted values are submitted to the host and never returned after saving; automatically acquired values stay on the host. Credential-bearing requests never follow a redirect.
Auto-acquire runs a host state machine (acquire.ts): open a system Edge / Chrome window, wait for a userid cookie, save ledger-domain cookies and close the window. login-browser.ts uses a dedicated pipe with browser-level commands, without opening a debugging port or enabling page Runtime / Debugger sessions. It does not read page contents; the user sees any site refusal directly. Cancellation, timeout, early closure and save failures are handled explicitly. Manual saves use the plugin's same-origin POST routes (/api/stock-pnl/cookie and /api/stock-pnl/fund-key), respect configured credential references, and no longer depend on DSH's legacy connection.api.credentials interface.
| Key | Default | Meaning |
|---|---|---|
cookieEnv |
STOCK_PNL_COOKIE |
Credential reference holding the ledger Cookie. |
fundKeyEnv |
STOCK_PNL_FUND_KEY |
Credential reference holding the ledger fund key (saved from the card's ⚙ form). |
user_id |
the Cookie's userid |
The ledger user id, included in every form payload; an empty value falls back to the Cookie's own userid. |
fund_key |
auto-discovered | The ledger fund key selecting the managed portfolio; overridden by the fundKeyEnv credential when set, auto-discovered from the account list when empty. |
pnlUrl |
Tonghuashun time_share endpoint |
P&L endpoint override (tests point at a scripted server). |
indexUrl |
Tonghuashun getQuotes endpoint |
Index endpoint override (tests point at a scripted server). |
pollMs |
20000 |
Poll interval (ms) the card uses; reported to the browser in each response's poll_ms. |
dsh-ths-holdings/
├── src/
│ ├── index.ts # node half: webServer routes + credential resolution
│ ├── fetch.ts # Tonghuashun ledger API calls + auto-discovery + cookie verify
│ ├── acquire.ts # cookie acquisition state machine
│ ├── login-browser.ts # system browser launch and cookie access
│ ├── settings.ts # write-only cookie / portfolio routes
│ └── client/
│ ├── index.ts # browser half: shell.overlay registration
│ └── StockPnlCard.tsx
├── lib/ # built artifacts (index.js + client.js)
├── cordis.patch.yml # dsh.bundle patch layer
├── package.json # dsh.bundle + dsh.client manifests
├── tests/ # ledger / verify / acquire unit tests
└── README.md
| Symptom | Cause & fix |
|---|---|
Card shows 请配置 Cookie |
STOCK_PNL_COOKIE is empty — click auto-acquire in the ⚙ panel, or paste manually. |
Card shows Token 已过期 |
Re-acquire the cookie or copy the Cookie request header using the manual steps above. |
Saving reports Cannot read properties of undefined (reading 'credentials') |
The old plugin used a changed DSH client interface. Install the fix, restart dsh web, and refresh the DSH page. |
| F12 has no effect | Click the browser's top-right menu → More tools → Developer tools, then follow the manual steps. |
| Login page says developer tools are unsupported | Auto-acquire does not require developer tools. For manual acquisition, check already recorded ledger requests in Network; if no usable Cookie is available, use auto-acquire. |
Popped window shows Nginx forbidden |
The Tonghuashun WAF intermittently refuses automation — F5 in the window or open the ledger URL manually, then click 「我已登录,继续 →」. |
| No portfolio in the dropdown | The account list needs a valid Cookie first; save the Cookie, then click ↻ to refresh. |
| Multiple portfolios | Select the one you want from the dropdown — the choice is saved as STOCK_PNL_FUND_KEY. |
| Cookie pasted with line breaks | The plugin strips whitespace on save, so wrapped lines are fine. |
None — the card is a browser-side overlay over a host data route and registers nothing model-facing.
None — the plugin contributes no prompt, schema, or result.
account_list) requires the Cookie to be saved first — the portfolio selector appears after you paste a valid Cookie.pollMs interval; there is no shared cache or push channel.npm test, npm run typecheck, and npm run build run the regression suite, check types, and build the plugin. npm run test:browser opens an isolated browser against a local fixture to verify Cookie access and cleanup.
npm run test:desktop-compat uses an installed Desktop's real runtime with an isolated profile. It checks plugin admission, credential writes and reads, Cookie validation, portfolio selection, and P&L routes. Ledger responses come from a local fixture; no real account or existing DSH configuration is used. The default paths target a standard Windows installation; override them with DSH_DESKTOP_EXECUTABLE and DSH_DESKTOP_RESOURCES for other locations. Run the test script directly with --serve to keep it available for UI checks. Test directories live under dist/desktop-compat-*. Real ledger sign-in and holdings still require account-level verification.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。