website: generate the API reference from source (cordis + all 15 harness services)

scripts/gen-website-api.ts renders website/zh-CN/api/{cordis,harness}/* and the
api-sidebar.json fragment the VitePress config imports, so pages and navigation
can never drift from the code: signatures, @param/@returns prose, dispatch
modes, and GitHub source links are extracted, never transcribed, and the
generator hard-errors on any rendered member missing docs. verify-website-api
(doc-sync + run-gates) is the freshness gate.

Replaces the hand-written zh api pages (7 pages covering 7 of 15 services,
with phantom APIs: Context.current/Context.events, agent/post-step, tool/call,
compact/*, llm/pre-request none of which exist) with generated English
references: 5 cordis pages, 15 per-service pages, and a 35-event catalog
grouped by scope. The hand-written hub api/index.md stays and now indexes the
full surface; zh for these pages arrives with the unified translation flow.
This commit is contained in:
lintianle
2026-07-16 18:13:34 +08:00
parent da26138592
commit efba9fab0a
31 changed files with 2983 additions and 931 deletions

View File

@@ -1,85 +1,192 @@
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# Context
上下文对象是 Cordis 的核心。所有服务、方法、属性都通过 `ctx` 访问。
The context is the core cordis object: every service, event, and lifecycle API is reached through `ctx`. Event methods (`ctx.on`, `ctx.emit`, …) are documented on [Events](./events.md); `ctx.effect` and `ctx.fiber` on [Fiber](./fiber.md); `ctx.plugin` and `ctx.inject` on [Registry](./registry.md).
## 服务与混入
Root and child dependency containers for Cordis plugins.
A context is a proxy: normal property reads go through the service resolver, while `extend()`, `isolate()`, and `intercept()` create scoped child contexts without mutating their parent.
Context 基于组合式 API 设计,大部分属性和方法挂载在服务上。以下是核心 API:
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L42)
- [`ctx.on`](./events#ctx-on) — 注册事件监听器
- [`ctx.emit`](./events#ctx-emit) — 触发事件
- [`ctx.bail`](./events#ctx-bail) — 短路事件
- [`ctx.serial`](./events#ctx-serial) — 顺序异步事件
- [`ctx.waterfall`](./events#ctx-waterfall) — 管道事件
- [`ctx.effect`](./fiber#fiber-effect) — 注册可逆效果
- [`ctx.plugin`](./registry#ctx-plugin) — 加载子插件
- [`ctx.inject`](./registry#ctx-inject) — 获取依赖的插件
- [`ctx.get`](#ctx-get) — 获取服务
- [`ctx.set`](#ctx-set) — 设置服务
- [`ctx.provide`](#ctx-provide) — 声明服务
### ctx.extend(meta?)
## 实例属性
```ts website-api
extend(meta = {}): this
```
### ctx.fiber
Create a child context with extra metadata on top of the current scope.
The child prototypally inherits every property of this context; own properties of `meta` shadow the inherited ones. The parent is not mutated.
- **类型:** [`Fiber`](./fiber)
- `meta` — own properties (including symbol keys) to define on the child.
当前上下文的作用域对象。
**Returns** a child context inheriting from this one.
## 实例方法
### ctx.extend(meta)
- **meta:** `object`
- **返回值:** `Context`
构造一个以当前上下文为原型的新上下文实例。
### ctx.intercept(name, config)
- **name:** `string` 服务名称
- **config:** `object` 配置拦截
- **返回值:** `Context`
为指定服务添加一层配置拦截,返回新的上下文实例。
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L99)
### ctx.isolate(name, label?)
- **name:** `string` 服务名称
- **label:** `symbol` 隔离域符号(可选)
- **返回值:** `Context`
```ts website-api
isolate(name: string, label?: symbol)
```
创建一个针对指定服务的隔离域,返回新的上下文实例。隔离域中的同名服务互不影响。
Create a child context with an independent service scope for `name`.
Below the returned context, reads and writes of the service `name` resolve against the new label instead of the parent's, so a different implementation can be provided without affecting the parent scope. Passing the same `label` to two `isolate()` calls joins their scopes.
### ctx.get(name)
- `name` — the service name to isolate.
- `label` — scope label to join; defaults to a fresh unique symbol.
- **name:** `string` 服务名称
- **返回值:** `Service | undefined`
**Returns** a child context whose `name` service resolves in the new scope.
获取指定名称的服务实例。
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L121)
### ctx.intercept(name, config)
```ts website-api
intercept<K extends InjectKey>(name: K, config: Context[K] extends { [symbols.config]: infer T } ? T : never): this
intercept(name: string, config: any): this
```
Add service-specific intercept config for plugins started below this context.
Plugins loaded under the returned context see `config` merged into the service's resolved config (ancestor entries first; see `Service[symbols.resolveConfig]`). The parent context is not affected.
- `name` — the service name whose config to intercept.
- `config` — the intercept config to merge for that service.
**Returns** a child context carrying the additional intercept entry.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L139)
## Static members
### Context.effect
```ts website-api
static readonly effect: unique symbol
```
Symbol key under which a disposer exposes its EffectMeta diagnostics tree.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L44)
### Context.filter
```ts website-api
static readonly filter: unique symbol
```
Symbol key for a context's listener filter, consulted on every event dispatch.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L46)
### Context.isolate
```ts website-api
static readonly isolate: unique symbol
```
Symbol key of the isolation map (see the `Context[symbols.isolate]` property).
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L48)
### Context.intercept
```ts website-api
static readonly intercept: unique symbol
```
Symbol key of the intercept map (see the `Context[symbols.intercept]` property).
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L50)
### Context.is(value)
```ts website-api
static is(value: any): value is Context
```
Returns true for Cordis context proxies and context prototypes.
Works across realms and across multiple copies of cordis, because the brand is keyed by a global symbol rather than by `instanceof`.
- `value` — the value to test.
**Returns** `true` if `value` is a Cordis context, narrowing its type.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/context.ts#L61)
### ctx.get(name, strict?)
```ts website-api
get<K extends string & keyof this>(name: K, strict?: boolean): undefined | this[K]
get(name: string, strict?: boolean): any
```
Read a service from the store without the inject requirement.
- `name` — the service name.
- `strict` — when `true` (default), only return implementations whose providing fiber is currently active.
**Returns** the service value, or `undefined` when not (yet) provided.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/reflect.ts#L16)
### ctx.set(name, value)
- **name:** `string` 服务名称
- **value:** `any` 服务值
```ts website-api
set<K extends string & keyof this>(name: K, value: undefined | this[K]): void
set(name: string, value: any): void
```
设置指定名称的服务。
Overwrite a provided service's value.
Only the fiber that provided the service may set it; setting an unprovided name throws.
### ctx.provide(name, value?, options?)
- `name` — the service name.
- `value` — the new service value.
- **name:** `string` 服务名称
- **value:** `any` 初始值(可选)
- **options:** `object`
- **返回值:** `void`
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/reflect.ts#L28)
声明一个服务。声明后其他插件可以通过 `inject` 依赖它。
### ctx.provide(name, value)
## 静态属性
```ts website-api
provide<K extends string & keyof this>(name: K, value: undefined | this[K]): () => void
provide(name: string, value?: any): () => void
```
### Context.events
Register a service implementation owned by the current fiber.
The service becomes visible to dependents in the same isolation scope once the fiber is active; it is unregistered (waking dependents) when the returned disposer runs or the fiber unloads. Throws if the name is already provided in this scope or declared as an accessor.
内置事件服务的 symbol key。
- `name` — the service name.
- `value` — the service value.
### Context.current
**Returns** a disposer that unregisters the service.
当前活跃的 Context 实例(在异步链中通过 AsyncLocalStorage 追踪)。
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/reflect.ts#L43)
### ctx.accessor(name, options)
```ts website-api
accessor(name: string, options: Omit<Property.Accessor, 'type'>): void
```
Define a computed context property backed by get/set hooks.
The accessor is removed when the current fiber unloads. Throws if the name is already declared.
- `name` — the context property name.
- `options` — the `get` hook and optional `set` hook.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/reflect.ts#L55)
### ctx.mixin(name, mixins)
```ts website-api
mixin<K extends string & keyof this>(name: K, mixins: (keyof this & keyof this[K])[] | Dict<string>): void
mixin<T extends {}>(source: T, mixins: (keyof this & keyof T)[] | Dict<string>): void
```
Expose selected members of a service directly on `ctx`.
Each mixed-in key becomes an accessor that forwards to the service (binding methods to it), so e.g. `ctx.on` forwards to `ctx.events.on`. Mixins are removed when the current fiber unloads.
- `name` — the context property holding the source service.
- `mixins` — keys to forward, or a source-key → ctx-key map.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/reflect.ts#L66)

View File

@@ -1,120 +1,142 @@
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# Events
`ctx.events` 是内置服务,提供事件系统相关的全部 API。
The event system mixed into every context. Harness-defined events are cataloged on [Harness events](../harness/events.md).
## 实例方法
### ctx.parallel(name, ...args)
### ctx.on(event, listener, options?) {#ctx-on}
- **event:** `string` 事件名称
- **listener:** `Function` 事件监听器
- **options:** `object`
- **prepend:** `boolean` 是否注册为前置(默认 `false`)
- **global:** `boolean` 是否注册为全局(默认 `false`)
- **返回值:** `() => void` 取消注册函数
注册一个事件监听器。返回的函数可用于手动取消注册,但通常不需要——插件卸载时会自动清理。
```typescript
ctx.on('agent/turn-end', (data) => {
console.log('turn ended:', data)
})
```ts website-api
parallel<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): Promise<void>
parallel<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): Promise<void>
```
### ctx.emit(thisArg?, event, ...args) {#ctx-emit}
Dispatch an event, running all listeners concurrently.
- **thisArg:** `any` 监听器的 `this` 参数(可选)
- **event:** `string` 事件名称
- **args:** `any[]` 事件参数
- **返回值:** `void`
- `name` — the event name.
- `args` — arguments passed to every listener.
同步触发所有匹配的监听器(并行,不等待异步完成)。
**Returns** a promise resolving once every listener has settled.
### ctx.parallel(thisArg?, event, ...args)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L43)
- 签名同 `emit`
- **返回值:** `Promise<void>`
### ctx.emit(name, ...args)
异步触发所有匹配的监听器(并行等待)。
### ctx.bail(thisArg?, event, ...args) {#ctx-bail}
- **返回值:** `any`
同步依次触发监听器。第一个返回非 `undefined`/`null`/`false` 值的监听器停止链并返回该值。
### ctx.serial(thisArg?, event, ...args) {#ctx-serial}
- **返回值:** `Promise<any>`
异步依次触发监听器。语义同 `bail` 的异步版本。
### ctx.waterfall(thisArg?, event, ...args) {#ctx-waterfall}
- **返回值:** `Promise<any>`
管道模式:每个监听器接收前一个的输出。监听器内部必须调用 `next()` 才会传递给下一个。
```typescript
// 注册
ctx.on('llm/pre-request', async (messages, next) => {
messages.push(extraMsg)
return next(messages) // 必须调用
})
// 触发
const result = await ctx.waterfall('llm/pre-request', initialMessages)
```ts website-api
emit<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): void
emit<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): void
```
::: warning
不调用 `next()` 即为否决 (veto)——管道终止。这是设计行为,用于拦截/网关。
:::
Dispatch an event synchronously, ignoring listener return values.
## Harness 内置事件
- `name` — the event name.
- `args` — arguments passed to every listener.
### agent/pre-step
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L52)
- **触发模式:** serial
- **参数:** `{ agentId, turnIndex }`
### ctx.serial(name, ...args)
Agent 执行一步之前触发。
```ts website-api
serial<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): Promisify<ReturnType<Events[K]>>
serial<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): Promisify<ReturnType<Events[K]>>
```
### agent/post-step
Dispatch an event, awaiting listeners in order until one bails.
- **触发模式:** emit
- **参数:** `{ agentId, turnIndex, blocks }`
- `name` — the event name.
- `args` — arguments passed to each listener.
Agent 执行一步之后触发。
**Returns** the first bail value (non-null, non-false, non-undefined), if any.
### tool/call
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L62)
- **触发模式:** emit
- **参数:** `{ name, args, callId }`
### ctx.bail(name, ...args)
Tool 被模型调用时触发。
```ts website-api
bail<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>
bail<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>
```
### tool/result
Dispatch an event, calling listeners in order until one bails.
- **触发模式:** emit
- **参数:** `{ name, result, callId }`
- `name` — the event name.
- `args` — arguments passed to each listener.
Tool 返回结果时触发。
**Returns** the first bail value (non-null, non-false, non-undefined), if any.
### session/event
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L72)
- **触发模式:** emit
- **参数:** `SessionEvent`
### ctx.waterfall(name, ...args)
会话事件被记录时触发。
```ts website-api
waterfall<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>
waterfall<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>
```
### compact/start
Dispatch an event whose last argument is a `next` continuation.
Each listener wraps the rest of the chain: calling `next()` invokes the next listener (finally the built-in behavior); not calling it vetoes.
- **触发模式:** emit
- `name` — the event name.
- `args` — listener arguments; the final one is the innermost `next`.
上下文压缩开始。
**Returns** the outermost listener's return value.
### compact/end
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L85)
- **触发模式:** emit
### ctx.on(name, listener, options?)
上下文压缩结束。
```ts website-api
on<K extends keyof Events>(name: K, listener: Events[K], options?: boolean | EventOptions): () => boolean
```
Register an event listener owned by the current fiber.
- `name` — the event name to listen for.
- `listener` — called with the dispatch arguments.
- `options` — listener options; a boolean is shorthand for `prepend`.
**Returns** a disposer removing the listener; `true` if it was still registered.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L96)
### ctx.once(name, listener, options?)
```ts website-api
once<K extends keyof Events>(name: K, listener: Events[K], options?: boolean | EventOptions): () => boolean
```
Same as `on()`, but the listener disposes itself after its first call.
- `name` — the event name to listen for.
- `listener` — called at most once with the dispatch arguments.
- `options` — listener options; a boolean is shorthand for `prepend`.
**Returns** a disposer removing the listener; `true` if it was still registered.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L105)
## EventOptions
Options accepted by `ctx.on()` and `ctx.once()`.
```ts website-api
interface EventOptions {
/** Add the listener before existing listeners for the same event. */
prepend?: boolean
/** Receive the event regardless of context filter checks. */
global?: boolean
}
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L111)
## DispatchMode
Event dispatch strategy used by the event service.
`emit` runs synchronous listeners without awaiting them, `parallel` awaits all listeners together, `serial` awaits them in order until one bails, `bail` stops on the first synchronous bail value, and `waterfall` composes listeners around a final `next` callback.
```ts website-api
type DispatchMode = 'emit' | 'parallel' | 'serial' | 'bail' | 'waterfall'
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/events.ts#L31)

View File

@@ -1,108 +1,263 @@
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# Fiber
Fiber(作用域)是插件实例的运行时容器,管理其生命周期和效果。
A fiber is one loaded plugin instance: its lifecycle state, validated config, and registered effects. `ctx.fiber` is the current fiber; `ctx.effect()` delegates to it.
## 状态机
### ctx.fiber
```
PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED
↘ FAILED
```ts website-api
fiber: Fiber
```
| 状态 | 数值 | 含义 |
|------|------|------|
| PENDING | 0 | 依赖未就绪,等待中 |
| LOADING | 1 | 正在执行 `apply` |
| ACTIVE | 2 | 运行中 |
| FAILED | 3 | `apply` 抛出异常 |
| UNLOADING | 4 | 正在撤销效果 |
| DISPOSED | 5 | 已完全卸载 |
The fiber (plugin runtime instance) that owns this context.
## 实例属性
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L11)
Runtime instance of one plugin application.
A fiber tracks dependency state, validated config, lifecycle effects, and cleanup for the plugin context returned by `ctx.plugin()`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L154)
### fiber.uid
- **类型:** `number`
```ts website-api
public uid: number | null
```
Fiber 的唯一标识符。
Unique id within the registry; 0 for the root fiber, `null` once disposed.
### fiber.status
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L156)
- **类型:** `number`
### fiber.ctx
当前状态(见状态机)。
```ts website-api
public readonly ctx: Context
```
The context this fiber's plugin runs in (extends the parent context).
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L158)
### fiber.config
- **类型:** `object`
传递给插件的配置对象。
### fiber.error
- **类型:** `Error | undefined`
如果状态是 FAILED,包含导致失败的异常。
## 实例方法
### fiber.effect(callback) {#fiber-effect}
- **callback:** `() => (() => void) | void`
- **返回值:** `() => void`
注册一个效果。`callback` 在 Fiber 激活时执行;如果返回函数,该函数在 Fiber dispose 时执行。
```typescript
ctx.effect(() => {
const timer = setInterval(tick, 1000)
return () => clearInterval(timer)
})
```ts website-api
public config: any
```
等价地可以通过 `ctx.effect()` 调用(ctx 代理到当前 fiber)。
The validated plugin config (updated by `update()`).
### fiber.dispose()
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L160)
- **返回值:** `Promise<void>`
### fiber.state
手动 dispose 该 Fiber。按注册逆序撤销所有效果,递归 dispose 所有子 Fiber。
```typescript
const child = ctx.plugin(somePlugin)
// 之后:
await child.dispose()
```ts website-api
public state
```
### fiber.update(config)
Current lifecycle state; transitions emit `internal/status`.
- **config:** `object` 新配置
- **返回值:** `void`
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L162)
热更新配置。如果新旧配置不同,触发 dispose + 重新 apply。
### fiber.dispose
```ts website-api
public readonly dispose: () => Promise<void>
```
Dispose this fiber: unload the plugin, then settle once cleanup finished.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L164)
### fiber.store
```ts website-api
public store: Dict<Impl> | undefined
```
Snapshot of required service implementations while loaded; `undefined` otherwise.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L166)
### fiber.inertia
```ts website-api
public inertia: Promise<void> | undefined
```
The in-flight load/unload transition, if one is currently running.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L168)
### fiber.name
```ts website-api
get name()
```
The plugin's display name, inherited from the nearest named ancestor, else `'root'`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L284)
### fiber.assertActive()
```ts website-api
assertActive()
```
Throw if the fiber has already been disposed.
**Returns** nothing when the fiber is still active.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L299)
### fiber.effect(execute, label?)
```ts website-api
effect(execute: () => SyncEffect, label?: string): Disposable<Promise<void>>
effect(execute: () => Effect, label?: string): AsyncDisposable<Promise<void>>
```
Register a cleanup-aware effect on this fiber.
`execute` runs immediately; the disposers it produces are collected and run (in reverse order) either when the returned disposer is called or when the fiber unloads, whichever comes first. Calling the disposer twice is a no-op. Throws `CordisError('INACTIVE_EFFECT')` if the fiber is already disposed, and `TypeError` if `execute` returns an invalid shape.
- `execute` — the effect body; see {@link Effect} for accepted shapes.
- `label` — effect label shown in `getEffects()` diagnostics.
**Returns** a disposer that tears the effect down and settles once done.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L363)
### fiber.getEffects()
```ts website-api
getEffects()
```
Return metadata for currently registered effects.
**Returns** one {@link EffectMeta} tree per labeled live effect.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L436)
### fiber.await()
```ts website-api
async await()
```
Wait for current lifecycle work and rethrow startup errors.
**Returns** this fiber, once it has settled into a stable state.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L560)
### fiber.restart()
- **返回值:** `void`
强制重启:dispose 后重新加载。
### fiber.then(resolve, reject?)
- **返回值:** `Promise<void>`
使 Fiber 可以被 `await`:等到状态进入 ACTIVE 或 FAILED。
```typescript
const fiber = ctx.plugin(myPlugin)
await fiber // 等待插件加载完成
```ts website-api
async restart()
```
## 访问当前 Fiber
Dispose and immediately reload this plugin with its current config.
```typescript
export function apply(ctx: Context) {
const fiber = ctx.fiber // 当前插件的 Fiber
console.log(fiber.status) // 1 (LOADING, 因为正在 apply 中)
**Returns** a promise resolving once the reload settled.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L574)
### fiber.update(config, noSave?)
```ts website-api
update(config: any, noSave = false)
```
Validate and apply new config, then restart the plugin.
Runs the `internal/update` waterfall first, so update hooks (and HMR) can veto or replace the restart.
- `config` — the new raw config; validated before anything restarts.
- `noSave` — hint for persistence hooks not to write the change back.
**Returns** nothing; the restart runs behind the `internal/update` waterfall.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L592)
## Effect
Effect body result accepted by `ctx.effect()` and plugin startup.
Either a single disposer, a promise of one, or a (possibly async) iterable yielding several — generator effects register each yielded disposer as it is produced.
```ts website-api
type Effect<T = any> =
| SyncEffect<T>
| AsyncEffect<T>
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L82)
## Disposable
Function returned by an effect to release resources during disposal.
Disposers run in reverse registration order when the owning fiber unloads; they may be async, in which case unloading awaits them.
```ts website-api
type Disposable<T = any> = () => T
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L73)
## EffectMeta
Tree node used to expose nested effect labels for diagnostics.
```ts website-api
interface EffectMeta {
/** Human-readable effect label, e.g. `ctx.on("event")` or `ctx.provide("name")`. */
label: string
/** Metadata of nested effects registered while this effect ran. */
children: EffectMeta[]
}
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L95)
## CordisError
Framework error with a stable machine-readable code.
```ts website-api
class CordisError extends Error {
/**
* @param code — the stable error code; also the default message.
* @param message — optional human-readable override.
*/
constructor(public code: CordisError.Code, message?: string)
}
namespace CordisError {
export type Code = keyof typeof Code
export const Code = {
INACTIVE_EFFECT: 'cannot create effect on inactive context',
} as const
}
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L127)
## ValidationError
Error raised when plugin configuration fails standard-schema validation.
```ts website-api
class ValidationError extends TypeError {
name = 'ValidationError'
/**
* Build the aggregated message from schema issues.
*
* @param issues — the standard-schema issues, one message line each.
*/
constructor(issues: readonly StandardSchemaV1.Issue[])
}
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/fiber.ts#L18)

View File

@@ -1,87 +1,121 @@
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# Registry
插件注册表,管理插件的加载和依赖解析。
Plugin loading and dependency injection.
## 实例方法
### ctx.inject(deps, callback)
### ctx.plugin(plugin, config?) {#ctx-plugin}
- **plugin:** `Plugin` 插件(函数、对象或类)
- **config:** `object` 传递给插件的配置(可选)
- **返回值:** `Fiber`
加载一个子插件,返回其 Fiber。子 Fiber 的生命周期绑定到父上下文。
```typescript
// 函数插件
ctx.plugin(myPlugin, { key: 'value' })
// 类插件
ctx.plugin(MyService)
// 返回的 Fiber 可以 await 或 dispose
const fiber = ctx.plugin(myPlugin)
await fiber
```ts website-api
inject(deps: Inject, callback: Plugin.Function<void>): Fiber & PromiseLike<Fiber>
```
### ctx.inject(names, callback) {#ctx-inject}
Run a callback once the requested services are available.
Shorthand for `ctx.plugin({ inject, apply: callback })`: the callback is unloaded and re-run whenever a required service changes.
- **names:** `string[]` 服务名列表
- **callback:** `(ctx: Context) => void`
- **返回值:** `() => void`
- `deps` — required services, as an array or a name → config map.
- `callback` — plugin body called with `(ctx, config)`.
等待指定服务全部就绪后执行 callback。如果服务消失,callback 的效果会自动撤销;服务恢复后重新执行。
**Returns** the fiber; awaiting it settles once loading finished.
```typescript
ctx.inject(['tools', 'llm'], (ctx) => {
// tools 和 llm 都就绪了
ctx.tools.register(/* ... */)
})
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/registry.ts#L175)
### ctx.plugin(plugin, ...args)
```ts website-api
plugin<P extends Plugin>(plugin: P, ...args: Spread<GetPluginConfig<P>>): Fiber & PromiseLike<Fiber>
```
这是 `export const inject = [...]` 声明的底层 API。大多数情况下直接使用声明式写法即可。
Load a plugin in the current context.
## 插件形态
- `plugin` — a function, class, or `{ apply }` object plugin.
- `args` — the plugin config, validated against its `Config` schema.
`ctx.plugin()` 接受三种插件形态:
**Returns** the fiber; awaiting it settles once loading finished (rejecting on config or startup errors).
### 函数插件
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/registry.ts#L184)
```typescript
function myPlugin(ctx: Context, config?: Config) {
// ...
}
myPlugin.name = 'my-plugin'
myPlugin.inject = ['tools']
```
## Plugin
### 对象插件
Supported plugin entrypoint shapes.
```typescript
const myPlugin = {
name: 'my-plugin',
inject: ['tools'],
apply(ctx: Context, config?: Config) {
// ...
},
}
```
```ts website-api
type Plugin<T = any> =
| Plugin.Function<T>
| Plugin.Constructor<T>
| Plugin.Object<T>
### 类插件(Service)
namespace Plugin {
/** Shared metadata understood by the plugin registry and related tooling. */
export interface Base<T = any> {
/** Display name used for fiber diagnostics and logger names. */
name?: string
/** Standard-schema validator applied to config before the plugin starts. */
Config?: StandardSchemaV1<any, T>
/** Services the plugin requires; it only loads while all are available. */
inject?: Inject
/** Service name(s) the plugin provides (read by `Service` and by loaders). */
provide?: string | string[]
/** Service names whose intercept config the plugin declares it consumes. */
intercept?: Dict<boolean>
}
```typescript
class MyService extends Service {
static inject = ['tools']
constructor(ctx: Context) {
super(ctx, 'myService')
export interface Transform<S, T> {
/** Marks the transform object as a schema/config transform. */
schema?: true
/** Convert user-facing config to runtime config. */
Config: (config: S) => T
}
/** Function plugin called with `(ctx, config)`. */
export interface Function<T = any> extends Base<T> {
(ctx: Context, config: T): any
}
/** Class plugin constructed with `(ctx, config)`. */
export interface Constructor<T = any> extends Base<T> {
new (ctx: Context, config: T): any
}
/** Object plugin with an `apply(ctx, config)` method. */
export interface Object<T = any> extends Base<T> {
apply(ctx: Context, config: T): any
}
/** Mutable registry record shared by all fibers of one plugin callback. */
export interface Runtime {
/** Display name copied from the first registered plugin shape. */
name?: string
/** Every live fiber of this plugin (one per `ctx.plugin()` call). */
fibers: DisposableList<Fiber>
/** The executable entrypoint all fibers share (registry identity key). */
callback: globalThis.Function
/** Standard-schema validator applied to each fiber's config. */
Config?: StandardSchemaV1
}
}
```
## 插件元信息
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/registry.ts#L91)
| 属性 | 类型 | 说明 |
|------|------|------|
| `name` | `string` | 插件名称(日志用) |
| `inject` | `string[] \| { required?: string[], optional?: string[] }` | 依赖声明 |
| `Config` | `Schema \| object` | 配置 schema 或默认值 |
## Inject
Service dependency declaration accepted by plugins and the `@Inject` decorator.
Array form requests services without intercept config. Object form maps each service name to optional intercept config for the plugin context.
```ts website-api
type Inject<M = Dict> = (keyof M)[] | { [K in keyof M]?: M[K] }
namespace Inject {
/**
* Convert array/object/class-inherited inject metadata into a plain map.
*
* @param inject — the declaration to normalize; `null`/`undefined` add nothing.
* @param result — the map to fill (service name → intercept config or `null`).
* @returns `result`.
*/
export function resolve(inject: Inject | null | undefined, result: Dict = Object.create(null))
}
```
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/registry.ts#L18)

View File

@@ -1,97 +1,92 @@
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# Service
Service 基类,用于创建对外暴露能力的插件。
Base class for context services: subclass it and load the subclass as a plugin to register `ctx.<name>`.
## 基本用法
Base class for services that expose a named API on `ctx`.
Subclasses call `super(ctx, name)` from their constructor. The service is registered immediately and is automatically removed with the owning fiber.
```typescript
import { Service, type Context } from 'cordis'
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L11)
declare module 'cordis' {
interface Context {
myService: MyService
}
}
### service.name
export default class MyService extends Service {
constructor(ctx: Context) {
super(ctx, 'myService')
}
// 公开方法
doSomething() {
// ...
}
}
```ts website-api
public name!: string
```
加载后,其他插件可通过 `ctx.myService` 访问。
The service name this instance is registered under.
## 构造函数
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L30)
### new Service(ctx, name)
## Static members
- **ctx:** `Context` 上下文
- **name:** `string` 服务名(注册到 `ctx[name]`)
### Service.init
## 实例属性
### service.ctx
- **类型:** `Context`
该服务绑定的上下文。
### service\[Service.tracker\]
- **类型:** `object`
服务追踪信息(名称、绑定状态等)。
## 生命周期
Service 子类可以覆写以下方法:
### start()
服务激活时调用。在这里初始化资源。
### stop()
服务停用时调用。在这里释放资源。
## 静态属性
### Service.inject
- **类型:** `string[] | { required?: string[], optional?: string[] }`
声明本服务依赖的其他服务。
## 与 inject 的关系
当一个 Service 被加载:
1. 框架为该服务名创建声明 (`ctx.provide`)
2. 实例赋值到 `ctx[name]`
3. 依赖该服务的所有 Fiber 从 PENDING 转为 LOADING
当 Service 被卸载:
1. `ctx[name]` 被置为 `undefined`
2. 依赖它的 Fiber 被 dispose
3. 当新的 provider 出现时,dependant Fiber 重新加载
## 示例:Harness 中的 Service
```typescript
// dsh-tools 的 ToolRegistry 就是一个 Service
export class ToolRegistry extends Service {
constructor(ctx: Context) {
super(ctx, 'tools')
}
register(tool: ToolDefinition): () => void {
// ...注册逻辑
return dispose
}
}
```ts website-api
static readonly init: unique symbol
```
Symbol key of an instance method run after construction (class plugins).
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L13)
### Service.check
```ts website-api
static readonly check: unique symbol
```
Symbol key of the availability predicate passed to `ctx.provide()`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L15)
### Service.config
```ts website-api
static readonly config: unique symbol
```
Symbol key of the phantom intercept-config type parameter.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L17)
### Service.invoke
```ts website-api
static readonly invoke: unique symbol
```
Symbol key of the call body making a service callable (e.g. `ctx.logger()`).
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L19)
### Service.extend
```ts website-api
static readonly extend: unique symbol
```
Symbol key of the helper deriving an extended service instance.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L21)
### Service.tracker
```ts website-api
static readonly tracker: unique symbol
```
Symbol key of the tracker metadata used for context tracing.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L23)
### Service.resolveConfig
```ts website-api
static readonly resolveConfig: unique symbol
```
Symbol key of the intercept-config resolution helper below.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/vendor/cordis/src/service.ts#L25)