DeepSeek Harness101 事件与通信 返回首页 官方教程 ↗

配置树、热替换与运行时状态

先确认装载了什么,再判断为何没运行。

配置转储解释组合结果,Fiber 注册表解释运行时,稳定 id 让热替换只触碰真正变化的条目。

cordis.yml
- id: logger
  name: '@deepseek-ai/cordis-plugin-logger-console'
- id: timer
  name: '@deepseek-ai/cordis-plugin-timer'
- id: hmr
  name: '@deepseek-ai/cordis-plugin-hmr'
  config:
    root: ['.']
- id: hello
  name: './hello.ts'

id 决定配置修改是更新,还是删除后重建

Loader 按稳定 id 比较配置项。没有显式 id 的条目在每次读取时获得新 id,因此无关编辑也可能导致它重新挂载。

显式 id- id: consumer只重新配置真正变化的条目
生成 id- name: './consumer.ts'配置文件变化后可能被视为先删除再添加
disabled: true

保留配置项但卸载插件。切回 false 后,插件以及所有等待其服务的 PENDING 消费方会重新加载。

group + isolate

组把子树作为一个单元装卸,isolate 让不同组持有同名服务的独立实例。

配置转储回答最终树从哪里来

DSH 按 bundle、profile、home 和命令行 overlay 的顺序组合。后层按行胜出,并整体替换目标行的 config。

bundles[]基础与已安装 bundle
profile/cordis.patch.yml当前 profile
$DSH_HOME/cordis.patch.yml机器共享偏好
--patch按参数顺序
shell
dsh --profile web --patch ./extra.yml --dump-config

# Bundle layers only:
dsh --profile web --dump-default-config
转储能证明每行来自哪个文件哪些 overlay 改写了它是否存在未匹配的 patch 目标
转储不会启动应用

它保留未求值的 !!js 表达式,不运行应用命令行提供方,也不显示 Fiber 状态。配置树正确不代表插件已经 ACTIVE。

HMR 是由三个支持能力组成的插件

HMR 监听文件,通过 logger 输出消息,并注入 timer 完成去抖。缺少 timer 时它会合法地停在 PENDING,且可能没有任何日志。

logger-console导出 HMR 日志
timer满足去抖依赖
cordis-plugin-hmr监视并替换插件
shell
node --import tsx ../../vendor/cordis/bin.js
hmr watching [ '.' ]hmr reload plugin at hello.tshello from my EDITED plugin
保存源文件卸载旧实例与 effect加载新代码重新运行 apply

插件无输出时,直接读取 Fiber 状态

PENDING 是合法等待,不会抛错。FAILED 表示 apply 或配置校验失败。ACTIVE 只说明加载完成,不说明业务输出一定发生。

diagnose.ts
import { FiberState, type Context } from '@deepseek-ai/cordis'

export function apply(ctx: Context) {
  setTimeout(() => {
    for (const runtime of ctx.registry.values()) {
      for (const fiber of runtime.fibers) {
        if (fiber.state === FiberState.PENDING) {
          console.log(`${fiber.name} is PENDING: required service missing`)
        }
      }
    }
  }, 500)
}
PENDING检查 inject 中谁没有提供方
FAILED检查 apply、schema 与错误日志
ACTIVE继续检查事件、调用路径和日志级别
看到 Loader 和 Include 是正常的

不加 PENDING 过滤时,注册表也会显示 loader 自身的 ACTIVE 插件,因为配置文件本身也是通过插件挂载。

从静态事实走向运行时事实

按这个顺序排查,可以避免把配置覆盖、模块解析和依赖等待混成同一个问题。

检查最终树--dump-config

确认条目存在、来源正确、覆盖符合预期。

正常启动dsh --profile web

解析、schema 或启动失败会非零退出。

枚举 Fiberctx.registry.values()

区分依赖等待、加载失败与正常活动。

补齐依赖inject: ['timer']

为 PENDING 插件添加缺失提供方,再观察自动加载。

下一步,把相同模式用于真实 Harness 服务