DeepSeek Harness Plugin

bill9109/dsh-101

Stars ★ 2 Category UI Enhancements Added 2026-08-13

Document reading mode for DSH.

Install

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:bill9109/dsh-101

GitHub-sourced plugins run build scripts on your machine at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).

README

Release v0.1.7 License: BSD-3-Clause Node.js DSH profiles

Install: bash <(curl -fsSL https://raw.githubusercontent.com/bill9109/dsh-101/main/scripts/install.sh) github:bill9109/dsh-101#v0.1.7

DSH 101 is a document-first reading interface built on top of dsh-base + dsh-web-app: it organizes DSH's own documentation into an ordered, searchable, translatable reader.

English | 中文

Why this exists

DSH ships a large body of built-in documentation, but in its raw form it is a file dump: scattered across the source tree, with no order, no search, and no comfortable way to read it. dsh-101 makes that documentation a first-class part of the DSH experience — a curated, ordered, searchable, translatable reader instead of raw files, with the conversation panel alongside so you can ask questions while you read.

Features

  • DSH's built-in documentation, curated and ordered by topic
  • Built-in document translation
  • A sliding hidden table of contents
  • Conversation panel on the right

Usage

Boot the profile (default port 3081, coexists with the web GUI on 3080):

dsh --profile dsh-101

Open http://127.0.0.1:3081 (or the port you chose): the reader shows the curated corpus with the sliding table of contents, search filters the documents, translation switches the reading language, and the right-hand panel is the DSH conversation you already know.

Install

This repository ships both a bundle (@bill9109/dsh-101, installable via dsh plugin add) and a profile/ directory (a ready-to-use dsh-101 profile composing dsh-base + dsh-web-app + this bundle). DSH's official distribution model is "distribute bundles, compose profiles" — there is no official command to distribute a profile, but a profile is just a directory under $DSH_HOME/profiles/<name>/, so the repository's profile/ is directly usable.

Recommended: one-liner script (places profile/ into ~/.dsh/profiles/dsh-101/ and installs the bundle):

# Install from GitHub (pin to a tag/commit when possible):
bash <(curl -fsSL https://raw.githubusercontent.com/bill9109/dsh-101/main/scripts/install.sh) github:bill9109/dsh-101#v0.1.7

# Or install from a local checkout, specifying the port (default 3081):
./scripts/install.sh --port 3081 .

# Boot:
dsh --profile dsh-101

What the script does: places the three profile/ files into $DSH_HOME/profiles/dsh-101/ (only fills in missing dsh-base/dsh-web-app layers if the profile already exists), primes the DSH module fallback (so in-box peers resolve at runtime), then runs dsh plugin --profile dsh-101 add to install this bundle.

Manual install:

mkdir -p ~/.dsh/profiles/dsh-101
cp profile/package.json profile/pnpm-workspace.yaml ~/.dsh/profiles/dsh-101/
# Optional: port patch
cp profile/cordis.patch.yml ~/.dsh/profiles/dsh-101/
# Install the bundle (appends to the bundles list)
dsh plugin --profile dsh-101 add github:bill9109/dsh-101#v0.1.7
dsh --profile dsh-101

Verify the bundles list has the three layers:

python3 -c "import json; print(json.load(open('$HOME/.dsh/profiles/dsh-101/package.json'))['dsh']['profile']['bundles'])"
# expected: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app', '@bill9109/dsh-101']

Do NOT install into the web profile. dsh-101's bundle disables ui-layout (the default browser shell); installed into any web-app profile it takes down the whole web (sidebar / conversation / app-shell all wait for the layout service and stay pending). Always use dsh-101 as its own profile (dsh --profile dsh-101, default port 3081, coexists with the web GUI on 3080). install.sh now rejects --profile web outright.

Port

Defaults to 3081 (coexists with the web GUI on 3080). Two ways to change it:

At launch (recommended, no config change, dsh 0.1.0-rc.6+):

dsh --profile dsh-101 --port 8080

Persist a different default in the profile config:

# ~/.dsh/profiles/dsh-101/cordis.patch.yml
- id: webserver
  inject: [webStartup]
  config:
    host: !!js ctx.webStartup.host ?? '127.0.0.1'
    port: !!js ctx.webStartup.port ?? 8080

(Launch flags win; the patch value is only the fallback.)

Git installs ship build artifacts. lib/ is committed to this repository, so a git install gets the built host + client bundles directly — no build, no credentials needed. If you install from a pristine clone before building, run node scripts/build.mjs first (needs a DSH source checkout, see below).

Upgrade

Re-run the one-liner with the new pinned tag:

bash <(curl -fsSL https://raw.githubusercontent.com/bill9109/dsh-101/main/scripts/install.sh) github:bill9109/dsh-101#v<new-version>

For a local-checkout installation, re-run ./scripts/install.sh . against the updated checkout (it only fills in missing layers, so your profile state is preserved). When DSH itself publishes a new snapshot, sync the bundle sources from the upgraded checkout with node scripts/upgrade.mjs (see "Upgrading from a newer DSH snapshot").

Uninstall

dsh plugin --profile dsh-101 remove @bill9109/dsh-101
# and, if you no longer want the standalone profile:
rm -rf ~/.dsh/profiles/dsh-101

The first command runs pnpm remove in the profile directory and removes the bundle from dsh.profile.bundles; the second deletes the standalone profile itself.

Troubleshooting

Symptom Resolution
Web GUI (3080) is down / sidebar stays pending after installing dsh-101 dsh-101 was installed into the web profile and disabled ui-layout — remove @bill9109/dsh-101 from the web profile and reinstall dsh-101 as its own profile with the one-liner
dsh --profile dsh-101 fails to start Confirm $DSH_HOME/profiles/dsh-101/ exists and its bundles list contains the three layers (dsh-base, dsh-web-app, @bill9109/dsh-101); re-run install.sh if a layer is missing
Port 3081 already in use Pass --port <port> at launch, or persist a different default in the profile's cordis.patch.yml
GitHub install fails or installs stale code Pin the install to a tag (github:bill9109/dsh-101#v0.1.7) or install from a local checkout (./scripts/install.sh .)
Documents missing or outdated Regenerate the corpus from a DSH source checkout: DSH_CHECKOUT=/path/to/dsh node scripts/build.mjs --corpus
Broken after DSH published a new snapshot Sync sources and rebuild with node scripts/upgrade.mjs --checkout /path/to/upgraded-dsh

Directory layout

src/
  app/        host plugin: corpus service + /api/dsh101 routes (from dsh-101-app)
  app/invariant.ts
  core/       corpus model: loading, merging, search (from dsh-101-core)
  tutor/      host plugin: model tools, curator skill (from dsh-101-tutor)
  client/     browser side: reader shell (from dsh-101-app/src/client)
  invariant.ts
assets/dsh-101/   generated corpus (corpus.json + documents/ + images/)
cordis.patch.yml  bundle patch: mounts app (package root) + tutor (./tutor subpath)
profile/          ready-to-use dsh-101 profile (package.json + pnpm-workspace.yaml + cordis.patch.yml)
scripts/
  install.sh            one-liner profile installer (install.sh --port <port> <src>)
  build.mjs             builds host + client bundles against a DSH checkout
  gen-dsh-101-corpus.ts regenerates the corpus from a DSH source tree
  upgrade.mjs           syncs sources from an upgraded DSH checkout and rebuilds
  verify-i18n.mjs       bilingual README consistency check (node scripts/verify-i18n.mjs)

Build

The bundle's peer dependencies resolve from a DSH install — either a source checkout (DSH_CHECKOUT) or the module fallback of a running DSH ($DSH_HOME/profiles/node_modules). Toolchain binaries (tsc, tsdown) prefer the DSH source checkout.

DSH_CHECKOUT=/path/to/dsh node scripts/build.mjs
# Rebuild after regenerating the corpus:
DSH_CHECKOUT=/path/to/dsh node scripts/build.mjs --corpus

build.mjs symlinks DSH's peers into node_modules, runs tsc (types into types/) then tsdown (host bundle + client bundle into lib/), and removes the symlinks afterwards.

Usually no build needed. lib/ is committed; dsh plugin add (GitHub / tarball / local checkout) installs the built bundle. Build only when developing this repo or after an upgrade sync.

Regenerating the corpus

The corpus is a snapshot of the DSH repository's docs. Regenerate it from any DSH source checkout (uses that checkout's tsx):

DSH_CHECKOUT=/path/to/dsh node scripts/build.mjs --corpus
# or explicitly:
/path/to/dsh/node_modules/.bin/tsx scripts/gen-dsh-101-corpus.ts /path/to/dsh

Upgrading from a newer DSH snapshot

After DSH publishes a new snapshot, sync this bundle from the upgraded checkout:

node scripts/upgrade.mjs --checkout /path/to/upgraded-dsh

The script copies the 101 packages' sources into src/, rewrites internal imports to relative paths, regenerates the corpus, and rebuilds. Then review the diff, commit, bump the version and tag:

git add -A && git commit -m "sync with DSH <snapshot>"
git tag v0.2.0 && git push origin main --tags

Development and verification

pnpm install
pnpm run build       # tsc + tsdown -> lib/ (committed)
pnpm run gen-corpus  # regenerate corpus from a DSH source tree (needs DSH_CHECKOUT)
node scripts/verify-i18n.mjs   # bilingual README consistency

pnpm run build emits the host + client bundles into lib/, which is committed so consumers install without building. Keep the bilingual README in sync: edit both README.md and README.zh.md, then node scripts/verify-i18n.mjs --write to re-record the blob hashes.

Community and About

License

BSD-3-Clause

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →