deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
An out-of-tree DSH bundle that brings the Awesome DSH Experts catalog (community experts and expert groups) into the DeepSeek Harness Web UI — without any changes to deepseek-harness itself.
DSH ("everything is a plugin") ships with no first-class "Expert / Expert Group" concept. This bundle fills that gap: a Settings → section tab (the same
settings.sectionslot the reference dshmarket client uses) to browse and copy experts, plus an optional compose-box entry to inject an installed expert group into the chat.
@expert <id> invocation block. Registered into the verified settings.section slot.0.1.0-rc.6 does not expose a composer input slot, so this entry is expected to silently degrade in that version; the Settings-tab clipboard flow is the working path. The slot is configurable (DSH_EXPERT_MARKETPLACE_COMPOSER_SLOT).POST /api/expert-marketplace with methods bootstrap, list, detail, groups, refresh, packs, packDetail.expert_list / expert_detail tools (best-effort, only when @deepseek-ai/dsh-tools is available).| Requirement | Value |
|---|---|
| DSH version | deepseek-harness@0.1.0-rc.6 (verified) |
| Profile | web (dsh.client.platform: "web") |
| Verified commit | see the repo's latest release tag / main HEAD |
| Node | >=18 (host side) |
| React | >=18 (peer, provided by the harness Web UI) |
The client bundle registers via the native __ModuleLoader__.load contract and only consumes the slots, locale, theme client services, so it degrades gracefully (never crashes the Web UI) on versions where those differ.
Install (from git):
dsh plugin --profile web add https://github.com/fuchao2pku/dsh-experts.git
Install (local dev, symlinked):
dsh plugin --profile web add /path/to/dsh-experts
Then (re)start the Web profile:
dsh --profile web web
Uninstall:
dsh plugin --profile web remove dsh-experts
dsh --profile web web # restart to apply
@expert <id> invocation block to your clipboard, then paste it into the chat input.Example: paste @software-team followed by a feature request to invoke the multi-role software team (product-manager → architect → engineer → QA).
All options default sensibly and can be overridden via cordis.patch.yml or environment variables:
| Option | Env override | Default |
|---|---|---|
catalogUrl |
DSH_EXPERT_MARKETPLACE_CATALOG_URL |
the published catalog.json (companion repo awesome-dsh-experts) |
maxAgeMs |
— | 172800000 (48h) |
timeoutMs |
— | 15000 |
maxBytes |
— | 5000000 |
composerSlot |
DSH_EXPERT_MARKETPLACE_COMPOSER_SLOT |
composer.toolbar (set to "" to disable) |
composerIntegration |
— | true |
agentTools |
— | true |
catalog.json from catalogUrl (default: the companion awesome-dsh-experts repo's raw catalog.json). The browser never contacts GitHub — it only calls the same-origin POST /api/expert-marketplace.<tmpdir>/dsh-experts/catalog.json), and a bundled catalog-seed.json is the offline fallback. No personal files are read or written.@expert <id> hint are surfaced in the UI.This bundle was written to the explicit contract: installing it must never crash the host or the Web UI. Mechanisms:
tsdown/TypeScript compile, so there is no build failure surface and every file is directly loadable + testable in plain Node.@deepseek-ai/* packages and react are optional peer dependencies, imported lazily inside try/catch. Missing them degrades a feature, never the plugin.try/catch in apply() — web server route, agent tools, system-prompt section, and UI tabs are each independently guarded; one failing feature never prevents the others (or the plugin mount).slots.inject and slots.register calls are wrapped, so a wrong slot name for a given DSH version silently degrades the composer entry while the Settings tab keeps working.403 instead of throwing.Short answer to "does dsh web load straight from the GitHub repo?" — No. The browser never touches GitHub. The host (Node) process fetches a pre-built catalog.json; the browser only calls the same-origin API /api/expert-marketplace. This mirrors how dshmarket sources its catalog.
experts/*.md (per-expert Markdown + YAML frontmatter) in the companion catalog repo awesome-dsh-experts.scripts/scan.mjs (in that repo) aggregates them into catalog.json (machine-readable, consumed by this plugin) and CATALOG.md (human-readable)..github/workflows/scan.yml regenerates the catalog on every push and on a daily cron (UTC 02:00). It runs scan.mjs --local --remote (local experts are always included, plus discovery of community repos tagged dsh-expert / dsh-expert-pack) and commits the refreshed catalog.json back.src/host.js CatalogSource seeds from the bundled catalog-seed.json, then refreshes from cfg.catalogUrl on startup / Settings-tab open / manual refresh. Fetches are conditional (ETag / Last-Modified + 304) so re-fetching is cheap, exactly like dshmarket's registry fetch.entries; best-effort on-disk cache in the system temp dir; bundled catalog-seed.json offline fallback.All fetch/cache failures are swallowed; the seed (or last good) wins and the UI shows a "catalog may be stale" hint.
| Symptom | Cause / Fix |
|---|---|
| Settings tab is empty | Catalog fetch failed and seed is empty. Check network to raw.githubusercontent.com; the tab shows a "stale" hint. Restart the Web profile to re-pull. |
| "Failed to load plugins" on startup | A client bundle didn't register via __ModuleLoader__.load. Ensure the plugin is the published version; this bundle always registers on load. |
| Composer button missing | Expected on 0.1.0-rc.6 (no composer slot). Use the Settings-tab Add to chat clipboard flow instead. |
| API returns 403 | Cross-origin call blocked. Only call /api/expert-marketplace from the same origin (the Web UI does this automatically). |
# run the test suite (node --test, no external deps)
npm test
npm run test:verbose
# link into a local DSH web profile for manual testing
dsh plugin --profile web add /path/to/dsh-experts
dsh --profile web web
The bundle is plain ESM (no build). src/client.js is the browser half (ModuleLoader contract); src/host.js is the Node half (HTTP API + catalog source); src/catalog.js is the shared, dependency-free catalog model.
@expert <id> hint reach the UI. No network egress beyond the single catalog.json fetch, no filesystem writes outside the temp-dir cache, no secrets.npm test # runs all suites (node --test, no external deps)
npm run test:verbose
27 tests cover: catalog model (parsing/validation/query/grouping), host route handler (every error path returns structured JSON, never throws), lifecycle (apply() survives a down network / missing services), client half (apply() never throws, degrades gracefully when slots/locale/composer are absent, never imports react in Node), and the client buildInvocationBlock.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。