Skills Plugins MCP Prompt Model 导航 博客 资讯 我的中心
开发与运行时 #dsh#dsh-plugin

fabric

类似 MC Fabric 的 hook 处理器。

omdsh-dev @omdsh-dev ⬇ 1 ★ 15 main

安装

dsh plugin --profile web add github:omdsh-dev/fabric
下载安装清单

需要可复现安装时,可在仓库后追加 #commit 固定提交。

类似 MC Fabric 的 hook 处理器。

该插件未提供要点说明,请参考仓库 README。

dshdsh-plugin
  1. 安装并启动 DeepSeek Harness:npx @deepseek-ai/dsh web
  2. 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
  3. 用 dsh plugins list 确认已安装,必要时重启 Harness 生效

插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。

代码仓库github.com/omdsh-dev/fabric
许可证未标注(见仓库)
主要语言main
下载量1
GitHub 星标15
最近推送2026-08-21
收录日期2026-09-19
分类开发与运行时

事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。

以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。

# RFC: dsh-external-stent — repository purpose, architecture, and decision record

English | [中文](README.zh.md)

- Status: **living document** (each section records the decision and its history)
- Scope: this standalone Stent extension workspace
- Upstream anchors: deepseek-harness snapshots `7b9644f2` (0812) / `9f9e2782a4` (0813),
  fork tip `65bcaf9902` (`feat-stent`)

This document explains *why* this repository is shaped the way it is. Every
non-obvious arrangement below was reached through a concrete failure recorded
in the commit history; the sections follow the repository's evolution rather
than its file layout.

---

## 1. Purpose: an external Stent extension, not a fork

deepseek-harness is a private monorepo. The Stent/Mixin extension layer lives
there as three implementation packages, but a consumer cannot install them from
the registry. This repository externalizes those three packages and publishes
the `@oh-my-dsh/stent-pack` carrier so consumers can install the complete bundle
through the official plugin channel:

```
dsh plugin --profile
 add @oh-my-dsh/stent-pack
```

**Boundary (hard rule):** the workspace contains exactly three complete
implementation packages — `stent` (pure transformation service),
`stent-api` (pure compat facade), and `stent-dsh` (DSH-facing
facades, invariant, profile bootstrap). The root `@oh-my-dsh/stent-pack` is a
separately publishable carrier, not a fourth implementation package. Anything
else — including the official `@deepseek-ai/dsh-tool-cordis` toolset — remains
an upstream dependency and is not republished here.

## 2. Host integration: launcher-provided wiring

The three packages install hooks and mount facades through the compiled launcher.
`src/stent-dsh.ts` compiles to `lib/stent-dsh.js`, while
`src/stent-dsh-preload.ts` compiles to `lib/stent-dsh-preload.js`; the launcher
injects that compiled preload before the official CLI loads. No host patch
checkout is required.

Everything the official channels already cover is deliberately excluded:
installing the trio (`dsh plugin add`), bundle roster rows and dependencies,
catalog generation, invariant/gate exemptions for trio-in-workspace, and all
documentation (`README*`, `docs/`, `.agents/`). What remains is what no channel
can provide: launcher bootstrap (`apps/cli/src/profile-boot.ts` calls
`installStentBootstrap` before any target import and
`checkStentRequiredPatches` after boot), the `clientBundle` source-transform
build seam (`packages/client/tsdown.client.ts`), catalog entries compiled into
the official `tool-cordis` package, their tests, and the pnpm-policy seams.

### 2.1 The disabled opt-in rows

The web-app bundle layer inserts `stent` / `stent-dsh` rows as
**disabled opt-ins**: the pure `stent` package is a library with no
plugin `apply`, so an enabled row fails every boot ("invalid plugin"). A
profile opts in by enabling the rows; the bundle layer applies on every boot,
so pre-existing profiles are covered without edits.

### 2.2 The TSX dead end (recorded and reverted)

The `dsh` source launch (`node --import tsx/esm apps/cli/src/bin.ts`) once
appeared to need `TSX_TSCONFIG_PATH` or a register preload: `FiberState` (a
const enum, only in `vendor/cordis/src`) failed to resolve. Both workarounds
shipped and were then **reverted** — the real cause was a stale
`TSX_TSCONFIG_PATH` in the shell pointing at an old staging checkout. With a
clean environment tsx auto-discovers the entry's tsconfig (extending the base)
and resolves the aliases to `src`. The official script runs unchanged; no
host-specific workaround is required.

## 3. Install model: npm bundle

The publishable root bundle `@oh-my-dsh/stent-pack` declares the three published
npm implementation packages:

```
@oh-my-dsh/stent@^0.1.1
@oh-my-dsh/stent-api@^0.1.1
@oh-my-dsh/stent-dsh@^0.1.1
```

The same tag workflow publishes the root carrier after those three packages,
so its semver dependencies already exist on npm.

This keeps installation to one npm package:

```sh
dsh plugin --profile web add @oh-my-dsh/stent-pack
```

At installation, pnpm resolves those npm semver dependencies. At launch, `stent-dsh` asks DSH's module-fallback healer to map the bundle's dependency closure into `$DSH_HOME/profiles/node_modules`, so the Profile and the preload resolve the same trio copies.

- Host source installs declare the bundle in `apps/cli/package.json`; run the
  harness workspace's `pnpm install` and `pnpm run build`, then install the
  published npm bundle through the plugin channel (joining `@oh-my-dsh/stent-pack` to
  `dsh.profile.bundles`) and enable the `stent-dsh` row. Launches go
  through the compiled `lib/stent-dsh.js`.
- Consumer-side builds use the explicit root `build` script. The trio and the
  launcher are built with tsdown before packing; no install-time prepare build
  is required.

### 3.1 pnpm 11 supply-chain seams

The npm bundle does not require `blockExoticSubdeps: false`, a Git
prepare allowlist, or `dangerouslyAllowAllBuilds` in the Profile. The workspace
still allows the native `esbuild` build and excludes the fast-moving DSH rc
train from minimum-release-age checks:

- `allowBuilds: esbuild` in this workspace;
- `minimumReleaseAgeExclude: ['@deepseek-ai/dsh-*']` — the dsh-* rc train ships
  inside the 24h window and a name-only entry exempts all versions.

## 4. Registry dependency policy

The dsh-* host packages publish fast rc trains; this repository tracks them
through registry ranges, and each lesson below came from a real breakage.

### 4.1 The dsh-compact trap

`@deepseek-ai/dsh-client-runtime@0.0.1-rc.1` depended on
`@deepseek-ai/dsh-compact`, which was **never published** (upstream deleted the
package after publishing that runtime). The `0.1.0-rc.x` series dropped the
dependency; verified installable end-to-end.

### 4.2 The missing rc.5

Upstream code is versioned `0.1.0-rc.5`, but the registry jumps
`rc.3 → rc.6` — rc.5 was never published. Ranges therefore read `^0.1.0-rc.0`
(resolving the newest published rc, and `rc.0` keeps stable releases in range
too). Peers use the same range, which the host workspace's rc.5 satisfies —
host installs reuse workspace packages instead of registry copies.

### 4.3 Real host types, not a local contract

The trio once declared a `host-contracts.ts` facade plus a global
`@deepseek-ai/cordis` Events injection. That broke type-checking across host
packages and was deleted in favor of importing the real `@deepseek-ai/dsh-*`
types (declared as peers + devDeps) — exactly the upstream shape. `ctx.slots`
typing comes from `dsh-client-runtime`'s declaration, as upstream.

### 4.4 Runtime peers of the published libs

With `autoInstallPeers: false`, the published `dsh-*` libs' load-time imports
(`dsh-scope`, `dsh-llm`, `dsh-timeout`, `dsh-typert-protocol`) must be listed
as devDependencies explicitly — each was added after a "Cannot find package"
at test load.

## 5. Browser client format: the closure factory

The web shell loads `/plugins//client.js` as a classic script and resolves
value imports through the loader module table (a synchronous `require` inside
the factory). Plain ESM bundles cannot load there at all. Consequently both
trio browser halves ship as closure factories:

```js
window.__ModuleLoader__.load({ id: "@oh-my-dsh/stent", factory: (require) => { ...; return module.exports; } })
```

with `@deepseek-ai/cordis` external (a platform seed) and everything else
inlined. `stent` was converted first; `stent-dsh` followed
(the same gap, fixed after the ex-setting install exposed the first one).
Upstream never notices this — its monorepo builds both through the shared
`clientBundle()` preset.

### 5.1 ex-setting's three lessons (same contract, external repo)

The sibling `omdsh-dev/ex-setting` bundle hit the same contract three times:

1. Its `dsh.client` manifest must be **nested** (`"dsh": { "client": ... }`),
   not a top-level `dshClient` field — client-modules scans the nested form;
2. its consumer-side build must use the **prepare config**, not just the local
   one, or git installs serve the old artifact;
3. cross-bundle value imports must not rely on a disabled row's factory —
   ex-setting inlines/avoids what the module table cannot answer, and installs
   static styles directly instead of routing them through a Stent publish the
   transform could not produce (browser-transform cannot match inside the
   closure artifact).

## 6. Test strategy

The upstream suite resolves `src` through tsconfig paths; this repository only
has registry `lib` artifacts, which drove the evolution below.

- **serve.spec** uses a test-local `node:http` adapter for the host `webServer`
  service, so exact/prefix routing and real HTTP responses stay covered without
  a DSH host-webserver test dependency.
- **hmr-e2e-runner** drives config HMR by toggling the row's `disabled` flag
  in `cordis.yml`: the vendored fork's `hmr.registerConfig` and include
  `internal/update` are fork-private and exist in **no** registry version
  (verified against latest 1.0.16/1.0.6).
- **client specs** originally faked `CommandUiRuntime`/`SlotRegistry` because
  the runtime rc.1 tree was uninstallable and the bundles are closure
  factories. After rc.6 became installable the real reason remained the
  factory format, so the specs now mount the **real services** through a test
  module loader (`packages/stent-dsh/tests/browser/module-loader.ts`): happy-dom provides `window`; the
  `__ModuleLoader__` sink installs at helper module load; platform seeds
  (`cordis`, `ui-slots`, `react`) preload as ESM namespaces (the factory
  `require` is synchronous and node cannot `require` ESM);
  `ui-primitives` — a render-only heavy package — is stubbed; `materialize()`
  executes a factory with the module-table require (recursing into other
  registered bundles, memoized, `stripClientSuffix` normalizing `pkg/client`).
  Loader `baseUrl` and fixture URLs are pinned to file paths because
  happy-dom's `location` is `http://localhost:3000`.

## 7. Linting

Oxlint runs from the standalone root with the pinned DSH toolchain (`oxlint` plus `oxlint-tsgolint`), enables the selected type-aware TypeScript rules, and treats warnings as failures. Generated `lib/` output, JavaScript fixture launchers, and build configs stay outside this TypeScript lint face.

The carrier root's `pnpm run lint` is scoped to its own `src/` launcher and runs Oxlint-tsgolint's experimental `--type-check` diagnostics. Each implementation package exposes one source-scoped `lint` command for its own source; tests remain covered by `pnpm test`, and there is no separate `typecheck` or `lint:fix` command.

## 8. Timeline (abridged)

| Commit | Decision |
|---|---|
| `1e04b1a`..`2a42254` | externalization: standalone Stent bundle, self-contained template |
| `4018661`, `8ffaac4` | port the upstream three-package split + full host patch; HMR e2e |
| `d9228c4`, `40600d4` | official plugin channel install; source-host install script |
| `1ba7077`, `3331b80` | web-app bundle composes the rows; rows become disabled opt-ins |
| `7b8e913`, `3fd3106` | patch rebases: 0812 baseline → 0813 baseline |
| `9158f5d` | delete `host-contracts.ts`; real `@deepseek-ai/dsh-*` types |
| `30ed5ff`, `b58c643` | registry dependency policy (rc.5 peer, installable suites) |
| `58fbe75`, `33955ef` | both browser halves become closure factories |
| `aa58a52` | publish publicly (upstream parity) |
| `62ced22` | revert the TSX workarounds (environment misdiagnosis) |
| `3fd1a56` | happy-dom + ModuleLoader materializer; real browser services in tests |

## 9. Future work

- If the registry ever publishes node-importable builds (plain ESM or the
  `src` halves), the test module loader disappears and the specs import
  packages directly.
- Upstream promoting `createSnapshotStore` out of `dsh-client-runtime` shrinks
  the seed table.
- Upstream publishing `hmr.registerConfig` / `internal/update` would let the
  HMR runner mirror the in-tree config flow again.

数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。