# dsh-super-injector

> Module Injector for DSH ecosystem: Load any local plugin into a running web without restart, featuring hot reload, self-reload, one-click uninstall, route self-healing, and plugin management UI for side panels and settings pages.

## Metadata

- Author: [@yjh051108](https://github.com/yjh051108)
- Repo: <https://github.com/yjh051108/dsh-super-injector.git>
- GitHub: [yjh051108/dsh-super-injector](https://github.com/yjh051108/dsh-super-injector)
- Stars: 127
- Language: TypeScript
- Topics: `dsh`, `dsh-plugin`
- Forks: 17
- Open Issues: 20
- Last push: 2026-08-15T13:21:42.000Z
- Added: 2026-08-16T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:yjh051108/dsh-super-injector
```

## Wiki

## One-Line Pitch
DSH (DeepSeek Harness) runtime "module injector": once installed, you can tell the agent to load any local plugin package into the running web without restart, and deliver the entire development loop—hot reload, self-reload, one-click uninstall, route self-healing, sidebar test area—all at once, eliminating repeated restarts and config changes.

## Core Capabilities
- **Runtime injection of any local plugin package**: Link the plugin directory to the profile's node_modules, then assemble it with loader.create—no need to modify patch/package.json, takes effect immediately without restart (includes host tools + client UI)
- **Full-package hot reload**: Modify code → build → automatically detects file fingerprint changes within 1.5 seconds to trigger reload, or explicitly call `dev_reload_package`; failures auto-rollback to preserve the old version
- **One-click uninstall + route self-healing**: Remove loader entry, clear injection list, delete junction, clean webserver route residuals—all without restart
- **Dual-path installation + auto-restore on startup**: Can be runtime-injected (dev mode) or go through profile bundles (officially managed after restart); injection list persists, auto-restores after restart
- **Plugin production line scaffolding**: Built-in four skeleton forms (toolkit / daemon loop / UI panel / hybrid), including build scripts, peerDependencies range declarations, ctx.effect resource registration specs
- **Settings page plugin management UI**: Client adds a "Plugins" settings page to visually browse injected plugins, one-click uninstall, drag folders into "internalization" (create new agent session for AI to turn content into plugin)

## Technical Implementation
- **Language**: TypeScript (ESM, NodeNext)
- **Key dependencies**: `@deepseek-ai/dsh-tools` (peer, tool registration), `cordis` (peer, DI/fiber), `schemastery` (peer, Config Schema); runtime also uses `node:fs / node:path / node:os / node:child_process`
- **Architecture pattern**: Comes with a cordis bootstrapper entry (injected via `insert` in `cordis.patch.yml`), registering 16 `dev_*` tools (host layer) + one `settings.section` client UI; host and client each have independent builds (tsc + tsdown)
- **Entry file**: `src/index.ts:570` (`apply(ctx, config)`), client entry `src/client/index.ts:54`

## Use Cases
- Want to quickly try out or iterate your own plugin packages on DSH, but don't want to restart the web every time (especially painful during frequent debug restarts)
- Need an AI agent to autonomously decide "install/uninstall/replace" plugin runtime management surface—the official assembly mechanism only covers "what to install", leaving "how to modify after installation" blank
- In multi-person/multi-environment DSH deployments, need to inject third-party plugins without touching official profile configuration

## Prerequisites & Compatibility
| Dependency | Min Version | Notes |
|---|---|---|
| DSH (@deepseek-ai/dsh-tools) | >=0.0.1-rc <2 | peerDependencies range declaration, DSH 0.1.0-rc.6 tested, no plugin changes needed on upgrade |
| cordis | >=4.0.0-rc <5 | peerDependencies range declaration |
| schemastery | ^3.18.0 | peerDependencies |
| Node | Not declared | devDependencies use `@types/node ^24.13.3`; runtime depends on DSH host Node version |
| Platform | macOS / Windows / Linux | Windows uses NTFS junction, other systems use symlinks; Windows needs Git Bash or WSL to run bash build scripts |
| Native modules | None | Only uses node:fs / node:path / node:os / node:child_process / node:url |
| External tools | bash + node + npm | Only needed when using `dev_scaffold_plugin` / `dev_build_plugin` scaffold toolchain; pure injection/uninstall doesn't need bash |

## Installation
```bash
dsh plugin --profile web add github:yjh051108/dsh-super-injector
```

## Configuration Options
| Config | Type | Description | Default |
|---|---|---|---|
| `registryFile` | string | Injection list persistence file path; records injected plugin package directories and timestamps, auto-restores after restart | `~/.dsh/super-injector/registry.json` (`DSH_HOME` takes precedence over `homedir()`) |
| `profileNodeModules` | string | Profile's node_modules path; junction link target, DSH loader resolves packages based on this | `~/.dsh/profiles/web/node_modules` |
| `autoRestore` | boolean | Whether to auto-restore injection list on startup (re-link and assemble all injected packages) | `true` |
| `intervalMs` | number | Watch polling interval in ms for detecting build artifact fingerprints; build artifacts are written in batches, interval naturally merges jitter | `1500` |
| `watches` | array | Custom watch directories and match substrings, each format `{dir, match}`; loadCache key is realpath URL, matched by directory name substring | `[]` |

## FAQ

**Q: Can't see dev_* tools after installation. What should I do?**

A: First confirm the injector has taken effect through official assembly path (`dsh plugin --profile web add` or `cordis.patch.yml`), then restart the corresponding web profile. Ask the agent for `dev_plugin_status`—if `dsh-super-injector` is not in the list, it's likely installed to a non-running profile.

**Q: Injecting a UI-type plugin reports "client ✗". How to debug?**

A: If the plugin doesn't declare `dsh.client.platform`, it shows "skipped", which is expected. If it shows "registration failed", it means `lib/client.js` is missing or the client bundle isn't a tsdown output; you need to `npm run build:client` to build the client bundle separately. The injector will automatically block injection in this case.

**Q: dev_reload_package reports "reload target hits injector itself" and gets rejected?**

A: The injector refuses self-destruction via normal paths—you must use `dev_reload_package` with a match string containing `dsh-super-injector` (goes to self-reload branch), and the interval between two self-reloads must be ≥10 seconds, otherwise it gets throttled.

**Q: Web reports "duplicate loader entry id" crash. How to fix?**

A: Run `node scripts/fix-patch.mjs` in the extraction directory (or use `dev_fix_patch` in a running environment), which deduplicates by ID and auto-backs up the original file; dsh loader strictly requires only one entry per ID.

**Q: Build reports "can't find bash" on Windows or WSL errors?**

A: The injector actively rejects WSL's `System32\bash.exe` (which fails when System32 takes priority in PATH). You need to install Git for Windows or PortableGit and add `Git\bin` to PATH; Windows uses NTFS junction instead of symlinks.

**Q: Are injected plugins still there after restart?**

A: Yes. The injection list persists to `~/.dsh/super-injector/registry.json`. On next assembly, `autoRestore` is enabled by default, automatically re-injects each package from the list; sidebar-to-main tools are also persisted in `staging.json`.

**Q: How to completely uninstall the injector?**

A: `dsh plugin --profile web remove @yjh051108/dsh-super-injector`, then clean up related entries in `cordis.patch.yml` (keep single top-level array), delete profile node_modules links, optionally delete `~/.dsh/super-injector/` directory; after restart, `dev_*` tools disappearing means uninstall is complete.

**Q: Can scaffold-generated skeletons be injected directly?**

A: Yes, but you need to first `dev_build_plugin` under `DSH_CHECKOUT` environment to build `lib/`; skeletons already enforce `ctx.effect` registration specs and peerDependencies range declarations. Client-type skeletons also validate `slots.register` against legitimate slot names.

## Learning Curve
Advanced—it's not just installing a plugin, but bringing in a complete set of runtime management surfaces outside the official assembly mechanism; you need to understand junctions, loader.create, cordis fiber, and schema injection to read the source code; regular users only need to follow README/INSTALL to complete installation and self-check.

## Known Issues & Limitations
- Self-reload must explicitly call `dev_reload_package` with match string containing `dsh-super-injector`; watch auto-reload won't trigger self-reload (prevents injector permanent absence during unattended operation)
- Self-reload minimum interval is 10 seconds (prevents chain suicide), throttle timestamp persisted to `~/.dsh/super-injector/self-reload.json` for cross-instance persistence
- Client-type plugins must declare `inject = ['slots']` and `slots.register` name must fall within known whitelist (`conversation.view` / `settings.section` / `settings.plugin.item` etc. 11 slots), otherwise injection is blocked
- Pre-injection validates build artifact freshness: declares `dsh.client.platform` but missing `lib/client.js` or artifact isn't tsdown output (missing `__ModuleLoader__` marker) → block; `src/` newer than `lib/` → warning without block
- PowerShell-edited `cordis.patch.yml` on Windows may contain UTF-8 BOM, injector actively checks for BOM and rejects
- When `DSH_HOME` environment variable differs from web process's `homedir()` (e.g., service account), path derivation will be completely off—`DSH_HOME` is authoritative
- When WSL is installed but no distribution configured, `System32\bash.exe` takes priority in PATH, injector actively detects and rejects; need Git for Windows / PortableGit
- Test plugin (`dev_self_test`) temp directory is fixed at `super-injector/selftest-runner` under `DSH_HOME`; directory name/path changes will trigger old tsx cache hits causing reload failure
- peerDependencies range declarations are scaffold's enforced constraint (no hardcoded versions), downstream plugin authors using precise versions like `0.1.0` may fail to install when DSH upgrades

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-super-injector](https://deepseek-plugin.org/plugins/yjh051108/dsh-super-injector)
Wiki generated by AI (model: `MiniMax-M2.5`)
