跳到主内容

fabric

15Star1Fork0Issue0Watching

为 DSH 安装 Stent/Mixin 扩展层,提供 stent-dsh 启动器和两个 profile 行,让受信插件在不修改源码的前提下改写其他模块的函数行为。

机审证据4/5方法论数据来源安装命令持续维护DSH 版本风险扫描
机审证据安装命令仓库已核验dsh-plugin Topic许可证READMEAI 百科
语言
TypeScript
分支
main
dshdsh-plugin

安装

命令web profile
$ dsh plugin --profile web add github:omdsh-dev/fabric

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

对话式安装

帮我安装 DeepSeek Harness 插件 omdsh-dev/fabric:先查看仓库 https://github.com/omdsh-dev/fabric 确认安全性,然后执行安装命令并验证插件加载成功。

把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。

一句话定位

这是 @oh-my-dsh/stent-pack 发行包在 DSH 插件市场的发布载体:把上游 deepseek-harness monorepo 里的 Stent/Mixin 扩展层(stent + stent-api + stent-dsh)打包成一行 dsh plugin 命令可装的 npm bundle,安装后为 DSH 增加一个独立的 stent-dsh 启动器和两个 profile 行(stent 与 stent-dsh),让受信插件能针对任何 npm 包的指定文件/函数注册 patch,无需 fork 也不必改上游源码。

核心能力

  • 提供 stent-dsh 启动器:替代普通 dsh 命令启动宿主 CLI,在官方 CLI 加载前注入 Stent 变换 hook 并写入进程级启动标记
  • 在 profile 中插入 stent 与 stent-dsh 两个可选行:默认 disabled,启用即接入 Stent/Mixin 扩展层
  • 提供四种 patch 操作:before(改参数)、after(改返回值)、around(决定是否执行原函数并可替换结果)、replace(完全接管调用)
  • 在目标模块首次加载前完成 AST 改写:基于 Orchestrion-JS(@apm-js-collab/code-transformer)改写 CommonJS 与 ESM 模块,并把每次改写记录为 binding
  • 支持声明 required: true:boot 后检查若 patch 未命中目标函数,loud 失败并指出 patch id 与目标模块
  • 同时支持 Node 宿主与浏览器 client:浏览器入口以 closure factory 形态发布,在 web Cordis 树上安装 ctx.stentClient

技术实现

  • 语言: TypeScript(ESM,monorepo 三个包 + 顶层 launcher)
  • 关键依赖: @apm-js-collab/code-transformer(AST 改写)、@deepseek-ai/cordis(插件 fiber 框架)、@oh-my-dsh/stent(核心运行时,跨三个内部包共享)、@deepseek-ai/dsh-*(作为 peer 与 devDep,类型声明而非打包发布)
  • 架构模式: 双层 launcher:编译后的 src/stent-dsh-preload.ts → lib/stent-dsh-preload.js 负责在 CLI 加载前安装 hook;src/stent-dsh/main.ts → lib/stent-dsh.js 作为 stent-dsh bin 启动官方 CLI,并合并多 patch layer(bundles、profile、$DSH_HOME、--patch 覆盖)输出 $STENT_CONFIG
  • 入口文件: 顶层 launcher src/stent-dsh.ts;preload src/stent-dsh-preload.ts;三个内部包主入口 packages/stent/src/index.ts、packages/stent-api/src/index.ts、packages/stent-dsh/src/index.ts

适用场景

希望让第三方插件在不修改 DSH 自身或任何 npm 包源码的前提下,"在外部"扩展、改写或观察某些函数行为——典型如记录某些关键调用、统一改写参数/返回值、或为已有闭源工具临时打补丁。安装此 bundle 后,下游需要 Stent 能力的插件(如声明 inject: ['stent'] 的 Mod)即可在你的 profile 里正常工作。

前置依赖与兼容性

依赖最低版本说明
DSH0.1.0-rc.0+stent-dsh 的 peerDependencies 钉住 @deepseek-ai/dsh-agent / dsh-commands / dsh-invariants / dsh-session / dsh-system-prompt / dsh-tools / dsh-client-ui-commands / dsh-client-ui-slots 全部 ^0.1.0-rc.0
Node.js^22.19.0 或 >=24.0.0顶层 engines.node;若同时启用 loader-thread hook(如 tsx)建议 ≥ 22.22.3 / ≥ 24.11.1,否则 CommonJS 模块走同步 hook 路径会触发 Node load 校验崩溃
Cordis^4.0.1-0stent / stent-dsh 都以 @deepseek-ai/cordis 为 peer
平台跨平台未声明 os / cpu 限制
原生模块无未引入 node-pty / node:sqlite / FFI 等原生依赖;esbuild 是 pnpm 允许的构建依赖

安装方式

dsh plugin --profile web add github:omdsh-dev/fabric

配置项

本插件不需要用户直接编辑配置文件,安装后会通过 cordis.patch.yml 自动向 profile 注入两行并默认禁用。要启用 Stent 扩展能力,按下面的 YAML 模板在自己的 profile 配置或 patch 层里把对应行改为启用(并写好 patches 描述符):

配置类型说明默认值
id: stent(profile 行)行配置纯 stent 包的描述符载体,必须保持 disabled: true;其 config.stent.patches 字段列出所有静态 patch 描述符(id / target / operation)disabled: true
id: stent-dsh(profile 行)行配置DSH 集成包(Host facade + 浏览器 client + required-patch 校验),启用后才挂载 ctx.stentAgent / ctx.stentTools / ctx.stentPrompt / ctx.stentCommands 等服务disabled: true
config.stent.patches[*].id字符串patch 唯一 id,匹配 [A-Za-z0-9._:/+-]{1-120};同 id 仅属于一个属主无
config.stent.patches[*].target.module字符串被改写函数所属的 npm 包名无
config.stent.patches[*].target.versionRange字符串目标包必须满足的 semver 区间无
config.stent.patches[*].target.filePath / filePaths字符串 / RegExp / 字符串数组目标函数所在的包内文件路径,多形态并存时用 RegExp 或数组无
config.stent.patches[*].target.functionQuery / astQuery对象 / 字符串选中目标函数的查询(按函数名 / AST 选择器);二者至少给一个无
config.stent.patches[*].operation枚举before / after / around / replace 之一,决定 handler 介入方式无
config.stent.patches[*].required布尔true 时若 boot 后该 patch 没有任何 binding,启动直接报错而不是静默失效false
第三方 plugin 内的 inject字符串数组需要 Stent 注册能力的插件须声明 inject: ['stent'],否则在普通 dsh 下会保持 pending视插件而定

常见问题

Q: 这个插件装好后能做什么?

A: 在 profile 里同时启用 stent 和 stent-dsh 两行后,DSH 进程就具备 Stent 扩展能力:受信插件可针对 npm 包的指定文件与函数注册 patch(前置改参、结果拦截、整体替换等四种操作),无需 fork 上游包。

Q: 安装后为什么 profile 列表里看不到效果?

A: stent 与 stent-dsh 两行默认 disabled——纯 stent 包没有 apply,作为描述符载体存在;只有主动把这两行启用,且通过 stent-dsh 启动器(而非普通 dsh)启动,Stent hook 才会真正安装。

Q: 能不能用普通 dsh 命令启动?

A: 不行。普通 dsh 启动不会写入 stent-dsh 的进程级启动标记,Stent 依赖插件会保持 pending 而不挂载;任何声明了 config.stent.patches 的行若在普通 dsh 下被启用,boot 会直接抛出错误提示你改用 stent-dsh 启动。

Q: patch 注册后能撤销吗?

A: 单次注册的 disposer 由所属 Cordis fiber 持有,插件卸载时自动 disable + remove;同一 patch id 仅属于一个属主,其他插件再注册会被直接拒绝;同属主 HMR 重注册会把所有权转给新一代,旧一代清理动作自动 no-op。

Q: 怎么知道 patch 真的命中了目标函数?

A: ctx.stent.list() 返回每个 patch 的有序快照,ctx.stent.bindings(id) 返回实际改写的文件清单;如果声明了 required: true 而启动后绑定为空,launcher 会在 boot 后 loud 失败并点名 patch id 与目标。

Q: 哪些 DSH 客户端面也支持 Stent?

A: stent-dsh 同时发布 ./client 浏览器入口(closure factory 形态),DSH 客户端加载 client.js 时会在浏览器 Cordis 树上安装 ctx.stent,并把 ctx.stentClient 暴露给 Mod 使用 commands 与命名 UI slot。

Q: 卸载这个插件会不会留下残余状态?

A: 卸载时把 stent 与 stent-dsh 两行从 cordis.patch.yml / dsh.profile.bundles 里删除,重启即可;运行时的 hook 安装由注册 fiber 的 effect 跟踪,插件卸载会自动释放。

Q: 移动端或国产 CPU 能用吗?

A: 本插件未声明 os / cpu 限制,跨平台可用;但运行时需要 Node ≥ 22.19.0,且当 loader-thread hook 共存时建议 ≥ 22.22.3 / ≥ 24.11.1,否则 CommonJS 模块可能触发 Node load 校验崩溃。

上手难度

进阶 — 需要理解 Cordis fiber / 启动能力门控、Orchestrion 风格的 AST 改写语义、profile 多 patch layer 合并顺序,并能在 YAML 中描述目标函数(包名 / 版本区间 / 文件路径 / 函数查询),普通用户建议直接复用社区已写好的 patch 描述符。

已知问题与限制

  • 必须用 stent-dsh 启动器而非普通 dsh 命令,否则 Stent hook 不安装、Stent 依赖插件保持 pending(packages/stent/src/service.ts:44-47)
  • hooks 必须早于目标模块首次求值安装;之后注册的 patch 只能对尚未加载的模块生效,已加载模块保持原行为(packages/stent/README.md:64)
  • Node 在 22.19.0–22.22.3 / 24.0.0–24.11.1 区间与 loader-thread hook 共存时,同步 registerHooks 链对 CommonJS 模块可能让 Node load 校验崩溃;此区间会走异步 module.register fallback(packages/stent/README.zh.md:101)
  • 同一目标函数上的两个 replace patch 在注册时会被拒绝;selector 默认改写全部匹配,传 index 才能只改某一个(packages/stent/README.zh.md:97、141)
  • 同一 patch id 仅属于一个属主,跨属主再注册直接抛错;同属主 HMR 重注册会移交所有权,旧一代清理 no-op(packages/stent/README.zh.md:89、140-141)
  • 格式正确但匹配不到任何东西的目标(如目标包版本不一致、文件布局变化)会让模块保持未变换——安装不会失败,但 patch 静默失效(packages/stent/README.zh.md:96)
  • 目标必须是编译后的 JavaScript:Node loader 不会接受原始 .ts,传给 .ts 路径会失败;浏览器路径会在改写前剥离 TS 注解(packages/stent/README.zh.md:143)
  • constructor 目标在改写期被显式拒绝(移动的 constructor 体无法携带 super() / new.target),需改为 patch 方法或工厂函数(packages/stent/README.zh.md:97)
  • 安装 tsdown --watch 时,编辑 patches JSON 才会触发 bundle 重建;浏览器侧通过 client-hmr 链送达,路径上偶尔出现 patch 与 bundle 不同步(packages/stent/README.zh.md:117)
  • DSH 自身 registry 上某些 rc 版本(0.1.0-rc.5)实际未发布,本 bundle 通过 ^0.1.0-rc.0 范围规避,仍可能遇到上下游 rc 节奏不匹配的小幅延迟(README.md:128-139)

查看使用指南 →

该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。

收录徽章

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/omdsh-dev/fabric)

把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。

返回插件目录