简体中文 | English

# dsh-openwiki > A DSH plugin that brings [openwiki](https://github.com/langchain-ai/openwiki)'s codebase knowledge-base capability into DeepSeek Harness — generate / read / update repository Wiki and Grounded Claims (traceable knowledge cards) in one click, **reusing the model already configured in DSH**, no need to enter an API key again. `dsh-openwiki` is a **Web-profile package plugin** for DeepSeek Harness (a Cordis all-plugin architecture): the Host half hosts the openwiki CLI runtime and drives generation jobs, while the Client half provides the knowledge-base entry, floating window, directory tree and document reading UI in the DSH main interface. The core idea is to **treat openwiki as an incremental generation engine** (CLI + disk-artifact contract); the DSH side owns UI, job orchestration, model bridging and triggers. *** ## 📑 Table of Contents * [🚀 Installation](#-installation) * [🛠️ Development & Maintenance](#-development--maintenance) * [✨ Feature Overview](#-feature-overview) * [🧱 Architecture](#-architecture) * [🖼️ Feature Tour](#-feature-tour) * [🧠 Key Logic](#-key-logic) * [📡 RPC API](#-rpc-api) * [⚠️ Known Limitations](#-known-limitations) * [🧪 Verification Scripts](#-verification-scripts) *** ## 🚀 Installation Prerequisites: Node ≥ 20, openwiki CLI (the plugin can install it automatically), DSH model + credentials configured. ### Option 1: npm package (recommended) ```powershell dsh plugin --profile web add dsh-openwiki ``` ### Option 2: Local source ```powershell # 1. Get the source into any local directory (referred to as below) git clone # 2. Build the artifacts (lib/ and client/) cd npm run build # 3. Install into the DSH web profile as a local directory dsh plugin --profile web add ``` ### Post-install configuration (same for both options) ```powershell # Edit \profiles\web\cordis.patch.yml, append: # - id: dsh-openwiki # name: 'dsh-openwiki' # Restart dsh web ``` > Notes: > > * When installing from a local directory, `dsh plugin add` links the profile's `node_modules` entry to `` (pnpm's default behavior for directory installs); edit source + `npm run build`, then restart dsh web to load the new bundle > > * `dsh.profile.bundles` must include `dsh-openwiki` (dsh.client manifest: platform web, peerDependency schemastery) *** ## 🛠️ Development & Maintenance ### Directory Layout ``` / ├── src/host/index.js # Host authoritative source (shared by dynamic & package forms) ├── src/client/index.js # Client authoritative source ├── scripts/build-host.mjs # → lib/index.js (ESM entry) ├── scripts/build-client.mjs # → client/client.js (ModuleLoader bundle) ├── lib/ client/ # build artifacts ├── tests/ # Playwright / offline verification scripts + screenshots/ └── package.json # dsh.client manifest (platform web) ```
### AI-Facing Notes * **Build script rewrites**: build-host rewrites `harness.handle` → `rpc.handle` and injects `webServer`/`settings`; build-client rewrites `host.call` → `rpc.call`. Use `harness.handle(...)` for new Host handlers and `host.call(...)` for new Client interactions; the build adapts automatically. * **readBytes limit**: `fs.readBytes` throws when the file exceeds maxBytes (it does not truncate) — read file heads with `readText` + slice. * **Missing manifest is the norm**: all wiki reads must go through the disk-scan fallback (`readWikiTree`/`readWikiOverview`/`readWikiClaims`). * **Shim EPERM**: on Windows do not spawn `.cmd`; parse the script path inside the shim and spawn node directly. * **not found stays silent**: optional state files (`.page-manifest.json`/`.run.json`/`.last-update.json`) missing must not `console.error`, or polling will spam. * **settings namespace**: `settings.register('openwiki', schema)` depends on `@deepseek-ai/schemastery`, whose dynamic import from the profile may fail (`settings namespace skipped`) — do not rely on it; use in-memory state + localStorage. * **Client service registry is rebuilt on every refresh**: the better-sidebar registration must auto-re-register (autoRegisterSidebar), never depend on a user click. * **openwiki has no git trigger**: auto-update relies on the plugin polling `git rev-parse HEAD`. * **Non-git repos cannot be generated**: `startJob` pre-checks and returns a clear error. * **Markdown rendering**: the fence detection must be `startsWith('```')` (see the hang lesson under «🧠 Key Logic»). * **Performance**: idle polling only refreshes jobs + overview (lightweight); full `refreshWorkspace` only while a job is running — avoid a full disk scan every 3s. *** ## ✨ Feature Overview * **📚 Knowledge-base entry**: the "openwiki知识库" entry above the "Settings" button in the DSH bottom-left (can be hidden, persisted in `localStorage`), opening a draggable/resizable **floating window**; plus a `conversation.view` session-view tab and a better-sidebar side page as two more embedded forms. **The workspace list is re-fetched whenever the knowledge base opens or the "Refresh" button is clicked** (a workspace added afterwards shows up without a page reload). ![Knowledge-base floating window](screenshots/readme-1-window.png) * **🗂️ Three-mode views**: three persistent tabs — `Open Wiki` (repo Wiki document tree), `知识卡片` (Grounded Claims traceable points) and `知识库` (personal-mode knowledge base) — with selected highlight; plus "忽略文件" (ignore file) and "Refresh" buttons; the left column width is draggable. ![Left column, three-mode tabs and button row](screenshots/readme-4-left.png) * **🧠 Knowledge base (personal mode)**: the third tab `知识库` — upload local files (text formats, with a file-type hint; add/remove file behavior is described under the "生成知识库" button) to build a personal knowledge base at `/openwiki-kb/wiki` (via `OPENWIKI_CONFIG_DIR` injection); the tree reader reuses the document view. **Model credentials stay single-sourced**: they are injected from `~/.openwiki/.env` into the child process — nothing is duplicated in the project, and one `.gitignore` line for `openwiki-kb/` excludes every personal artifact. ![Knowledge base (personal mode) view](screenshots/readme-6-kb.png) * **📄 Document reading**: preview / code dual views + **TOC split pane** (click "目录" to split a left TOC panel beneath the toolbar, with its own vertical scrollbar, sticky and not scrolling with the body; clicking an entry smooth-scrolls to the heading). ![Document reading (preview / code / TOC split)](screenshots/readme-2-doc.png) ![TOC split pane](screenshots/readme-3-toc.png) * **🗂️ Knowledge cards**: Grounded Claims traceable points (statement + evidence), viewed from the "知识卡片" tab. ![Knowledge cards view](screenshots/readme-5-cards.png) * **🔗 In-app link navigation**: internal md links (including `/openwiki/...` absolute paths) navigate within the app on click, never taking the browser to a `file://`; folder links (trailing `/`) enter folder browse. * **⚡ Generation jobs**: generate / regenerate (incremental update) / cancel with live progress (`已完成 X/Y (Z%),处理中: N,失败: M`), resumable via openwiki's `.run.json`; non-git repos get a clear error. * **📊 Generation status card**: the right panel shows file count / success / failure / last update / document location (`openwiki/`) plus a "Regenerate" button. * **🔌 Model reuse**: reads the DSH default model (`agentDefaultModel`) and credentials, maps them to openwiki provider config written to `~/.openwiki/.env` (openai-compatible / anthropic / gemini / openrouter). * **🖥️ Runtime hosting**: auto-detects the openwiki CLI (parses the npm shim), version check (registry), install / upgrade / self-check (`--help`). * **🔔 Auto-update**: polls each workspace's git HEAD; on a new commit it runs an incremental update (openwiki has no native git trigger, the plugin supplies it); **defaults to ON for every workspace** — the switch sits next to the "Refresh" button in the knowledge-base left column (**shown only on the Open Wiki tab**; cards and knowledge base are unaffected), **per-workspace independent**, a manual disable is never overridden. * **🧩 better-sidebar integration**: when the `dsh-better-sidebar` service is detected it **auto-registers** a side page (re-registered after refresh, effectively persistent); when not installed the settings page shows install guidance. * **🛡️ Ignore file**: `.openwikiignore` (gitignore syntax) graphical editing and save. * **⚙️ Settings page**: runtime / model / better-sidebar registration / entry visibility (the auto-update switch moved to the knowledge-base panel, per workspace). ![openwiki settings page](screenshots/readme-7-settings.png) > 🔌 **Core idea**: openwiki is the CLI engine, DSH is the host. All state (`.page-manifest.json` / `.run.json` / `.last-update.json` / `.claims/` under the `openwiki/` directory) is a disk contract; the plugin only **reads + displays + triggers**, never touching the generation algorithm itself. *** ## 🧱 Architecture ### Dual Half Structure (Host / Client) A Cordis plugin splits into two halves, each with **authoritative source code**, and build scripts produce the package artifacts: | Half | Authoritative source | Build artifact | Responsibility | | ------ | --------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | Host | `src/host/index.js` | `lib/index.js` (ESM entry) | openwiki runtime hosting, model bridging, generation jobs, wiki/claims disk reads, ignore file, auto-update, RPC server | | Client | `src/client/index.js` | `client/client.js` (Web ModuleLoader bundle) | all UI: entry, floating window, directory tree, document rendering, settings page, better-sidebar registration | The build scripts (`scripts/build-host.mjs` / `build-client.mjs`) rewrite the free identifiers in the source into package form: * Host: `harness.handle(` → `rpc.handle(`; `lib/index.js` injects hard deps `webServer`/`settings` and registers the same-origin JSON-RPC route `/dsh-openwiki/rpc` * Client: `host.call(` → `rpc.call(` (`fetch('/dsh-openwiki/rpc', { headers: {'x-dsh-openwiki':'1'} })`); `styles.insert` → local `