docs: verify Cordis signature type links

This commit is contained in:
Tianyi Cui
2026-07-19 14:57:52 +08:00
parent 7747aa450c
commit 350d1b2688
6 changed files with 294 additions and 60 deletions

View File

@@ -99,7 +99,7 @@ export interface Config {
}
```
Depends on: [`AgentOptions`](../packages/core/agent/src/index.ts) · [`SessionId`](../packages/core/session/src/index.ts)
Depends on: [`AgentOptions`](core-data-structures/core.md) · [`SessionId`](core-data-structures/core.md)
Source: [`packages/core/agent-loop/src/index.ts:369`](../packages/core/agent-loop/src/index.ts)
@@ -1108,7 +1108,7 @@ export interface Config {
}
```
Depends on: [`AgentOptions`](../packages/core/agent/src/index.ts)
Depends on: [`AgentOptions`](core-data-structures/core.md)
Source: [`packages/subagent/tool-subagent/src/index.ts:23`](../packages/subagent/tool-subagent/src/index.ts)

View File

@@ -31,7 +31,7 @@ A fully configured agent and live session were published. Setup is composition-o
'agent/created'(this: Scoped<Agent>, agent: Agent): void
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:141`](../../packages/core/agent/src/types.ts)
@@ -51,7 +51,7 @@ An agent left the registry; AgentLoop emits this after driver quiescence but bef
'agent/disposed'(this: Scoped<Agent>, agent: Agent): void
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:150`](../../packages/core/agent/src/types.ts)
@@ -73,7 +73,7 @@ A step or turn errored. The loop reports a failure here (plus the logger) even w
'agent/error'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, error: Error): void
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:285`](../../packages/core/agent/src/types.ts)
@@ -101,7 +101,7 @@ Awaited serial checkpoint for session-surface mutation after prompt assembly and
'agent/pre-step'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, fullSystemPrompt: string, sessionPrefix: readonly Message[], signal: AbortSignal): Promise<void> | void
```
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:204`](../../packages/core/agent/src/types.ts)
@@ -122,7 +122,7 @@ Allow, rewrite, or block one drained prompt before it becomes a user message. Ca
'agent/prompt-submit'(this: Scoped<Agent>, agent: Agent, content: ContentBlock[], source: MessageSource, next: () => Promise<PromptDecision>): Promise<PromptDecision>
```
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [MessageSource](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [MessageSource](../core-data-structures/core.md) · [PromptDecision](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:214`](../../packages/core/agent/src/types.ts)
@@ -143,7 +143,7 @@ Detached, frozen content entered the agent's inbox. Source defaults have already
'agent/queued'(this: Scoped<Agent>, agent: Agent, content: ContentBlock[], info: { source: MessageSource; steering: boolean }): void
```
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [MessageSource](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [MessageSource](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:169`](../../packages/core/agent/src/types.ts)
@@ -166,7 +166,7 @@ Replace the frozen call configuration. Model-visible content must use logged cha
'agent/request'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, config: LlmCallConfig, next: () => Promise<LlmCallConfig>): Promise<LlmCallConfig>
```
Types: [Agent](../core-data-structures/core.md) · [LlmCallConfig](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [LlmCallConfig](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:226`](../../packages/core/agent/src/types.ts)
@@ -192,7 +192,7 @@ Compose request-only messages placed before derived history. The frozen result i
'agent/session-prefix'(this: Scoped<Agent>, agent: Agent, prefix: Message[], signal: AbortSignal, next: () => Promise<Message[]>): Promise<Message[]>
```
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:241`](../../packages/core/agent/src/types.ts)
@@ -214,7 +214,7 @@ The session lifecycle began, once before the first turn. Use `agent.inject()` to
'agent/session-start'(this: Scoped<Agent>, agent: Agent, source: SessionStartSource): void
```
Types: [Agent](../core-data-structures/core.md) · [SessionStartSource](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md) · [SessionStartSource](../core-data-structures/core.md)
Source: [`packages/core/agent/src/types.ts:182`](../../packages/core/agent/src/types.ts)
@@ -234,7 +234,7 @@ Agent status changed (`idle` ⇄ `running`, or → `disposed`). `send()` does no
'agent/status'(this: Scoped<Agent>, agent: Agent, status: AgentStatus): void
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [AgentStatus](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:159`](../../packages/core/agent/src/types.ts)
@@ -256,7 +256,7 @@ Waterfall: post-process the assembled assistant Message before tool dispatch (va
'agent/step-result'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, message: Message, next: () => Promise<Message>): Promise<Message>
```
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:252`](../../packages/core/agent/src/types.ts)
@@ -277,7 +277,7 @@ Override whether the turn continues. The default continues after tool calls or s
'agent/turn-continuation'(this: Scoped<Agent>, agent: Agent, turn: number, defaultDecision: ContinuationDecision, next: () => Promise<ContinuationDecision>): Promise<ContinuationDecision>
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [ContinuationDecision](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:262`](../../packages/core/agent/src/types.ts)
@@ -298,7 +298,7 @@ Monotonic terminal-stop checkpoint after continuation and steering are folded; a
'agent/turn-stop'(this: Scoped<Agent>, agent: Agent, turn: number): ContinuationStop | undefined
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [ContinuationStop](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/core/agent/src/types.ts:272`](../../packages/core/agent/src/types.ts)
@@ -321,6 +321,8 @@ A declarative agent entry failed before it could publish a live agent. Consumers
'agent-loop/config-start-failed'(sessionId: SessionId, error: unknown): void
```
Types: [SessionId](../core-data-structures/core.md)
Source: [`packages/core/agent-loop/src/index.ts:362`](../../packages/core/agent-loop/src/index.ts)
## `approval/*`
@@ -340,7 +342,7 @@ Ask composed answerers for one decision. Return an outcome to claim the request
'approval/request'(this: Scoped<ApprovalService>, req: ApprovalRequest, next: () => Promise<ApprovalOutcome>): Promise<ApprovalOutcome>
```
Types: [ApprovalOutcome](../core-data-structures/approval.md) · [ApprovalRequest](../core-data-structures/approval.md)
Types: [ApprovalOutcome](../core-data-structures/approval.md) · [ApprovalRequest](../core-data-structures/approval.md) · [ApprovalService](../core-data-structures/approval.md) · [Scoped](../core-data-structures/scope.md)
Source: [`packages/ui/user-approval/src/index.ts:31`](../../packages/ui/user-approval/src/index.ts)
@@ -426,7 +428,7 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t
'llm/stream'(this: LlmService, options: GenerateOptions, next: () => AsyncIterable<StreamChunk>): AsyncIterable<StreamChunk>
```
Types: [GenerateOptions](../core-data-structures/core.md) · [StreamChunk](../core-data-structures/llm-streaming.md)
Types: [GenerateOptions](../core-data-structures/core.md) · [LlmService](../core-data-structures/llm-streaming.md) · [StreamChunk](../core-data-structures/llm-streaming.md)
Source: [`packages/llm/llm/src/index.ts:40`](../../packages/llm/llm/src/index.ts)
@@ -451,6 +453,8 @@ Creation announcement during session publication. A synchronous throw vetoes and
'session/created'(this: Scoped<Session>, session: Session): void
```
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md)
Source: [`packages/core/session/src/index.ts:47`](../../packages/core/session/src/index.ts)
### `session/disposed` — emit
@@ -470,6 +474,8 @@ Emitted once when an announced session leaves the store, including publication r
'session/disposed'(this: Scoped<Session>, session: Session): void
```
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md)
Source: [`packages/core/session/src/index.ts:57`](../../packages/core/session/src/index.ts)
### `session/event` — emit
@@ -491,7 +497,7 @@ Post-commit, fire-and-forget append feed. The listener snapshot resolves before
'session/event'(this: Scoped<Session>, session: Session, event: SessionEvent): void
```
Types: [SessionEvent](../core-data-structures/core.md)
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md) · [SessionEvent](../core-data-structures/core.md)
Source: [`packages/core/session/src/index.ts:69`](../../packages/core/session/src/index.ts)
@@ -512,6 +518,8 @@ Awaited parallel durability checkpoint: every listener runs and the caller await
'session/flush'(this: Scoped<Session>, session: Session): Promise<void> | void
```
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md)
Source: [`packages/core/session/src/index.ts:79`](../../packages/core/session/src/index.ts)
## `subagent/*`
@@ -532,6 +540,8 @@ A ready child settled. Scope-filtered dispatch uses the same delegating parent c
'subagent/end'(this: Scoped<SubagentService>, info: SubagentRunEndInfo): void
```
Types: [Scoped](../core-data-structures/scope.md) · [SubagentService](../core-data-structures/subagent.md)
Source: [`packages/subagent/subagent/src/index.ts:112`](../../packages/subagent/subagent/src/index.ts)
### `subagent/provider-added` — emit
@@ -547,6 +557,8 @@ A provider became resolvable in the registry.
'subagent/provider-added'(provider: SubagentProvider): void
```
Types: [SubagentProvider](../core-data-structures/subagent.md)
Source: [`packages/subagent/subagent/src/index.ts:86`](../../packages/subagent/subagent/src/index.ts)
### `subagent/provider-removed` — emit
@@ -582,6 +594,8 @@ A provider established a ready child. For in-process providers, `ctx.agents.get(
'subagent/start'(this: Scoped<SubagentService>, info: SubagentRunInfo): void
```
Types: [Scoped](../core-data-structures/scope.md) · [SubagentService](../core-data-structures/subagent.md)
Source: [`packages/subagent/subagent/src/index.ts:103`](../../packages/subagent/subagent/src/index.ts)
## `system-prompt/*`
@@ -602,6 +616,8 @@ Expert waterfall over the assembled sections, tools, and variables. Scope-filter
'system-prompt/assemble'(this: Scoped<SystemPrompt>, assembly: PromptAssembly, context: AssembleContext, next: () => Promise<PromptAssembly>): Promise<PromptAssembly>
```
Types: [AssembleContext](../core-data-structures/system-prompt.md) · [Scoped](../core-data-structures/scope.md) · [SystemPrompt](../core-data-structures/system-prompt.md)
Source: [`packages/core/system-prompt/src/index.ts:27`](../../packages/core/system-prompt/src/index.ts)
### `system-prompt/change` — emit
@@ -656,7 +672,7 @@ Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a nor
'tools/execute'(this: Scoped<ToolRegistry>, exec: ToolExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
```
Types: [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md)
Types: [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
Source: [`packages/core/tools/src/index.ts:89`](../../packages/core/tools/src/index.ts)
@@ -676,7 +692,7 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts
'tools/post-execute'(this: Scoped<ToolRegistry>, exec: ToolExecution, result: Readonly<ToolExecutionResult>, next: () => Promise<PostToolDecision>): Promise<PostToolDecision>
```
Types: [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md)
Types: [PostToolDecision](../core-data-structures/tools.md) · [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
Source: [`packages/core/tools/src/index.ts:98`](../../packages/core/tools/src/index.ts)
@@ -695,7 +711,7 @@ Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approv
'tools/pre-execute'(this: Scoped<ToolRegistry>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>
```
Types: [ToolExecution](../core-data-structures/tools.md)
Types: [PreToolDecision](../core-data-structures/tools.md) · [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
Source: [`packages/core/tools/src/index.ts:80`](../../packages/core/tools/src/index.ts)
@@ -714,7 +730,7 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained
'tools/result'(this: Scoped<ToolRegistry>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined
```
Types: [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md)
Types: [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
Source: [`packages/core/tools/src/index.ts:106`](../../packages/core/tools/src/index.ts)
@@ -738,6 +754,8 @@ One `agent()` call settled (clean result, child failure, or run cancellation). P
'workflow/agent-end'(info: WorkflowRunInfo, agent: WorkflowAgentEndInfo): void
```
Types: [WorkflowRunInfo](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:81`](../../packages/workflow/workflow/src/index.ts)
### `workflow/agent-start` — emit
@@ -757,6 +775,8 @@ One `agent()` call established a ready child run. Paired with Events['workflow/a
'workflow/agent-start'(info: WorkflowRunInfo, agent: WorkflowAgentInfo): void
```
Types: [WorkflowRunInfo](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:70`](../../packages/workflow/workflow/src/index.ts)
### `workflow/end` — emit
@@ -776,6 +796,8 @@ A workflow run settled (any stop reason). Fired when WorkflowRun.result resolves
'workflow/end'(info: WorkflowRunInfo, result: WorkflowResultInfo): void
```
Types: [WorkflowRunInfo](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:91`](../../packages/workflow/workflow/src/index.ts)
### `workflow/log` — emit
@@ -792,6 +814,8 @@ The script emitted a narration line (a `log(message)` call).
'workflow/log'(info: WorkflowRunInfo, message: string): void
```
Types: [WorkflowRunInfo](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:60`](../../packages/workflow/workflow/src/index.ts)
### `workflow/phase` — emit
@@ -809,6 +833,8 @@ The script entered a phase (a `phase(title)` call) — progress grouping for obs
'workflow/phase'(info: WorkflowRunInfo, title: string): void
```
Types: [WorkflowRunInfo](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:53`](../../packages/workflow/workflow/src/index.ts)
### `workflow/start` — emit
@@ -825,6 +851,8 @@ A workflow run started — the script's meta block validated, the body about to
'workflow/start'(info: WorkflowRunInfo): void
```
Types: [WorkflowRunInfo](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:45`](../../packages/workflow/workflow/src/index.ts)
## Inherited events (cordis core + loader/hmr/timer)

View File

@@ -42,7 +42,7 @@ async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<Agent
async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [AgentOptions](../core-data-structures/core.md) · [SessionHeader](../core-data-structures/persistence.md) · [SessionId](../core-data-structures/core.md)
Source: [`packages/core/agent-loop/src/index.ts:407`](../../packages/core/agent-loop/src/index.ts)
@@ -163,7 +163,7 @@ list(): Agent[]
roots(): Agent[]
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [SessionId](../core-data-structures/core.md)
Source: [`packages/core/agent/src/index.ts:201`](../../packages/core/agent/src/index.ts)
@@ -233,7 +233,7 @@ abstract run(spec: BashExecSpec): Promise<BashRunResult>
abstract start(spec: BashExecSpec): BashProcess
```
Types: [BashExecRequest](../core-data-structures/bash.md) · [BashExecSpec](../core-data-structures/bash.md) · [BashRunResult](../core-data-structures/bash.md)
Types: [BashExecRequest](../core-data-structures/bash.md) · [BashExecSpec](../core-data-structures/bash.md) · [BashProcess](../core-data-structures/bash.md) · [BashRunResult](../core-data-structures/bash.md)
Source: [`packages/bash/bash/src/index.ts:49`](../../packages/bash/bash/src/index.ts)
@@ -264,7 +264,7 @@ collect(execution: ToolExecution): DshEnvironment
list(): BashEnvVariableInfo[]
```
Types: [ToolExecution](../core-data-structures/tools.md)
Types: [DshEnvironment](../core-data-structures/bash.md) · [ToolExecution](../core-data-structures/tools.md)
Source: [`packages/bash/tool-bash/src/index.ts:102`](../../packages/bash/tool-bash/src/index.ts)
@@ -331,7 +331,7 @@ abstract compactIfNeeded( agent: CompactAgentContext, fullSystemPrompt: string,
abstract compactRegion( start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>
```
Types: [Message](../core-data-structures/core.md)
Types: [CompactionResult](../core-data-structures/compaction.md) · [Message](../core-data-structures/core.md)
Source: [`packages/compact/compact/src/index.ts:38`](../../packages/compact/compact/src/index.ts)
@@ -427,7 +427,7 @@ abstract writeText(target: FsTarget, content: string, expected?: FsWriteIntent,
abstract editText(target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal): Promise<FsEditOutcome>
```
Types: [FsEditOutcome](../core-data-structures/filesystem.md) · [FsEditRequest](../core-data-structures/filesystem.md) · [FsInfo](../core-data-structures/filesystem.md) · [FsTarget](../core-data-structures/filesystem.md) · [FsVersion](../core-data-structures/filesystem.md) · [FsWriteIntent](../core-data-structures/filesystem.md) · [FsWriteOutcome](../core-data-structures/filesystem.md)
Types: [FsDirEntry](../core-data-structures/filesystem.md) · [FsEditOutcome](../core-data-structures/filesystem.md) · [FsEditRequest](../core-data-structures/filesystem.md) · [FsInfo](../core-data-structures/filesystem.md) · [FsPathInfo](../core-data-structures/filesystem.md) · [FsTarget](../core-data-structures/filesystem.md) · [FsVersion](../core-data-structures/filesystem.md) · [FsWriteIntent](../core-data-structures/filesystem.md) · [FsWriteOutcome](../core-data-structures/filesystem.md)
Source: [`packages/fs/fs/src/index.ts:80`](../../packages/fs/fs/src/index.ts)
@@ -472,7 +472,7 @@ async listModels(provider: string): Promise<LlmModelInfo[]>
stream(options: GenerateOptions): AsyncIterable<StreamChunk>
```
Types: [GenerateOptions](../core-data-structures/core.md) · [StreamChunk](../core-data-structures/llm-streaming.md)
Types: [GenerateOptions](../core-data-structures/core.md) · [LlmAdapter](../core-data-structures/llm-streaming.md) · [LlmModelInfo](../core-data-structures/core.md) · [LlmProviderInfo](../core-data-structures/core.md) · [StreamChunk](../core-data-structures/llm-streaming.md)
Source: [`packages/llm/llm/src/index.ts:94`](../../packages/llm/llm/src/index.ts)
@@ -516,7 +516,7 @@ optionOf(name: string): PresetOption
set(session: Session, name: string): void
```
Types: [SessionEvent](../core-data-structures/core.md)
Types: [Session](../core-data-structures/session.md) · [SessionEvent](../core-data-structures/core.md)
Source: [`packages/ui/permission/src/index.ts:94`](../../packages/ui/permission/src/index.ts)
@@ -594,7 +594,7 @@ abstract load(id: SessionId): Promise<{ meta: SessionHeader; events: SessionEven
abstract list(): Promise<SessionHeader[]>
```
Types: [SessionEvent](../core-data-structures/core.md)
Types: [SessionEvent](../core-data-structures/core.md) · [SessionHeader](../core-data-structures/persistence.md) · [SessionId](../core-data-structures/core.md) · [SessionLocation](../core-data-structures/persistence.md)
Source: [`packages/session-persistence/session-persistence/src/index.ts:42`](../../packages/session-persistence/session-persistence/src/index.ts)
@@ -640,6 +640,8 @@ async traceEvent(request: SessionEventTraceRequest): Promise<SessionEventTrace>
async readEvent(request: SessionEventReadRequest): Promise<SessionEventWindow>
```
Types: [SessionEventReadRequest](../core-data-structures/session-query.md) · [SessionEventRecord](../core-data-structures/session-query.md) · [SessionEventTrace](../core-data-structures/session-query.md) · [SessionEventTraceRequest](../core-data-structures/session-query.md) · [SessionEventWindow](../core-data-structures/session-query.md) · [SessionId](../core-data-structures/core.md) · [SessionLineageTrace](../core-data-structures/session-query.md) · [SessionRecord](../core-data-structures/session-query.md)
Source: [`packages/session-query/session-query/src/index.ts:38`](../../packages/session-query/session-query/src/index.ts)
## `ctx.sessions` — `SessionStore`
@@ -765,6 +767,8 @@ list(): Session[]
fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId): Session
```
Types: [CreateSessionOptions](../core-data-structures/persistence.md) · [Session](../core-data-structures/session.md) · [SessionId](../core-data-structures/core.md)
Source: [`packages/core/session/src/index.ts:577`](../../packages/core/session/src/index.ts)
## `ctx.skills` — `SkillService`
@@ -811,6 +815,8 @@ async list(options: SkillLookupOptions = {}): Promise<SkillSummary[]>
async get(name: string, options: SkillLookupOptions = {}): Promise<SkillDefinition | undefined>
```
Types: [SkillDefinition](../core-data-structures/skills.md) · [SkillLookupOptions](../core-data-structures/skills.md) · [SkillProvider](../core-data-structures/skills.md) · [SkillRegistration](../core-data-structures/skills.md) · [SkillSummary](../core-data-structures/skills.md)
Source: [`packages/skill/skill/src/index.ts:141`](../../packages/skill/skill/src/index.ts)
## `ctx.spillStore` — `SpillStore` (abstract seam)
@@ -832,6 +838,8 @@ Semantics every implementation must honor:
abstract saveText(input: SaveTextSpill): Promise<SpillRef>
```
Types: [SaveTextSpill](../core-data-structures/spill.md) · [SpillRef](../core-data-structures/spill.md)
Source: [`packages/spill/spill/src/index.ts:45`](../../packages/spill/spill/src/index.ts)
## `ctx.subagents` — `SubagentService`
@@ -873,6 +881,8 @@ list(): string[]
async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
```
Types: [SubagentProvider](../core-data-structures/subagent.md) · [SubagentRun](../core-data-structures/subagent.md) · [SubagentStartRequest](../core-data-structures/subagent.md)
Source: [`packages/subagent/subagent/src/index.ts:153`](../../packages/subagent/subagent/src/index.ts)
## `ctx.systemPrompt` — `SystemPrompt`
@@ -919,6 +929,8 @@ variable(name: string, provider: (context: AssembleContext) => string | undefine
async assemble(context: AssembleContext = {}): Promise<PromptAssembly>
```
Types: [AssembleContext](../core-data-structures/system-prompt.md) · [PromptSection](../core-data-structures/system-prompt.md) · [ToolProviderResult](../core-data-structures/system-prompt.md)
Source: [`packages/core/system-prompt/src/index.ts:209`](../../packages/core/system-prompt/src/index.ts)
## `ctx.tasks` — `TaskService`
@@ -1006,7 +1018,7 @@ onTaskDone(listener: TaskDoneListener): () => void
attachSurface(name: string): () => void
```
Types: [Agent](../core-data-structures/core.md)
Types: [Agent](../core-data-structures/core.md) · [TaskDoneListener](../core-data-structures/tasks.md) · [TaskId](../core-data-structures/tasks.md) · [TaskRead](../core-data-structures/tasks.md) · [TaskSnapshot](../core-data-structures/tasks.md) · [TaskStart](../core-data-structures/tasks.md)
Source: [`packages/tasks/tasks/src/index.ts:76`](../../packages/tasks/tasks/src/index.ts)
@@ -1041,7 +1053,7 @@ measure(session: Session, requestHeader?: EpochHeader): TokenMeasurement
estimateMessage(message: Message): number
```
Types: [Message](../core-data-structures/core.md)
Types: [EpochHeader](../core-data-structures/session.md) · [Message](../core-data-structures/core.md) · [Session](../core-data-structures/session.md) · [TokenMeasurement](../core-data-structures/token-meter.md)
Source: [`packages/llm/token-meter/src/index.ts:106`](../../packages/llm/token-meter/src/index.ts)
@@ -1119,7 +1131,7 @@ executionMode(exec: ToolExecutionInput): ToolExecutionMode
async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
```
Types: [ToolDefinition](../core-data-structures/tools.md) · [ToolExecutionInput](../core-data-structures/tools.md) · [ToolExecutionMode](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md)
Types: [ScopeKey](../core-data-structures/scope.md) · [ToolDefinition](../core-data-structures/tools.md) · [ToolExecutionInput](../core-data-structures/tools.md) · [ToolExecutionMode](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolGuard](../core-data-structures/tools.md) · [ToolRestriction](../core-data-structures/tools.md) · [ToolSchema](../core-data-structures/tools.md)
Source: [`packages/core/tools/src/index.ts:438`](../../packages/core/tools/src/index.ts)
@@ -1145,6 +1157,8 @@ registerProvider(provider: UserInteractionProvider): () => void
async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
```
Types: [AskUserQuestionAnswer](../core-data-structures/user-interaction.md) · [AskUserQuestionRequest](../core-data-structures/user-interaction.md) · [UserInteractionProvider](../core-data-structures/user-interaction.md)
Source: [`packages/ui/user-interaction/src/index.ts:82`](../../packages/ui/user-interaction/src/index.ts)
## `ctx.web` — `WebService`
@@ -1201,6 +1215,8 @@ async search(request: WebSearchRequest, signal?: AbortSignal): Promise<WebSearch
async fetch(request: WebFetchRequest, signal?: AbortSignal): Promise<WebFetchResult>
```
Types: [WebFetchProvider](../core-data-structures/web.md) · [WebFetchRequest](../core-data-structures/web.md) · [WebFetchResult](../core-data-structures/web.md) · [WebSearchProvider](../core-data-structures/web.md) · [WebSearchRequest](../core-data-structures/web.md) · [WebSearchResult](../core-data-structures/web.md)
Source: [`packages/web/web/src/index.ts:74`](../../packages/web/web/src/index.ts)
## `ctx.workflows` — `WorkflowService` (abstract seam)
@@ -1217,6 +1233,8 @@ Workflow execution seam. Invalid requests throw before publication; a live run i
abstract start(request: WorkflowStartRequest): WorkflowRun
```
Types: [WorkflowRun](../core-data-structures/workflow.md) · [WorkflowStartRequest](../core-data-structures/workflow.md)
Source: [`packages/workflow/workflow/src/index.ts:159`](../../packages/workflow/workflow/src/index.ts)
## Inherited `ctx` members (cordis core + loader/hmr/timer)

View File

@@ -20,7 +20,7 @@ Specific choices:
- **`@mode` tag, cross-checked.** Each harness event's JSDoc carries an explicit `@mode emit|waterfall|parallel|serial` tag; the generator hard-errors on a missing tag. Where the signature shape is conclusive — a trailing `next: () => …` parameter is structurally a waterfall — it asserts the tag agrees and hard-errors on a contradiction. The emit/parallel/serial distinction is not structurally visible (`session/flush` returns `Promise<void> | void` with no `next`, as does the ordered `agent/pre-step` checkpoint), so it is trusted from the tag. The authoring rule lives in [AGENTS.md](../../../../AGENTS.md).
- **Tiered scope.** The harness tier (the 8 `@deepseek-ai/dsh-*` services + their events) is rendered in full from source. The inherited tier (cordis-core `ctx.on/emit/effect/provide/…` + the `internal/*` events + loader/hmr/timer) is pinned vendor source a plugin also sees; it is rendered tersely (name + one-line + source pointer) from a curated table in the generator, NOT walked from the vendor AST — the cordis-core `Context` mixes true ctx members with non-service fields (`root`, `baseUrl`, `logger`), and the vendor surface changes only on a deliberate vendor sync.
- **Cross-links to the data-structure catalog.** A type name in a signature (`GenerateOptions`, `StreamChunk`, `ToolDefinition`, …) links to the core-data-structures page that documents it. The map is a small hand-curated const in the generator — NOT `type-equiv.manifest.json`, which documents the `…Map` symbols while signatures reference the derived union names, and lists a few symbols on two pages.
- **Cross-links to the data-structure catalog.** Every repository-owned type name in a signature (`GenerateOptions`, `StreamChunk`, `ToolDefinition`, …) links to its primary core-data-structures page through a curated map. The AST walk is fail-closed: each parameter, generic constraint/default, and return-type reference must be mapped, be the signature's own type parameter, be a named TypeScript/Cordis foundation type, or carry a named exception with its non-catalog documentation owner. Violations aggregate with source pointers and name the appropriate owning lists. The map does NOT reuse `type-equiv.manifest.json`, which documents `…Map` symbols while signatures reference derived union names and lists some symbols on multiple pages.
- **A dedicated fence.** Signature blocks use a ` ```ts cordis-catalog ` info string and place the original event or public-method JSDoc immediately before its declaration. `doc-typecheck` recognizes and skips the bare fragments, excluding them from the opt-out ratio — the same treatment `type-equiv` blocks get.
This **supersedes the event-taxonomy half** of [doc-sync enforcement](2026-06-11-doc-sync-enforcement.md): `verify-event-taxonomy` and its `docs/architecture.md` table are retired (the architecture.md heading stays, its body now points at the catalog; the Service-map role table stays as curated prose). doc-typecheck, verify-md-wrap, verify-md-links, and verify-type-equiv are unchanged.
@@ -29,11 +29,11 @@ This **supersedes the event-taxonomy half** of [doc-sync enforcement](2026-06-11
- **Verify-don't-generate, as the retired taxonomy check did** — reversed *for this surface only*: the data here is mechanically complete, so generation is strictly stronger (full signatures, cannot drift, catches undocumented events) than a name-set check of a hand-maintained table.
- **Walking the vendor AST for the inherited tier** — rejected for the curated table: the cordis-core `Context` mixes true ctx members with non-service fields, and the pinned vendor surface changes only on a deliberate sync.
- **Reusing `type-equiv.manifest.json` as the signature cross-link map** — rejected for a small hand-curated const: the manifest documents the `…Map` symbols while signatures reference the derived union names, and it lists a few symbols on two pages.
- **Reusing `type-equiv.manifest.json` as the signature cross-link map** — rejected for a complete curated const plus fail-closed coverage: the manifest documents `…Map` symbols while signatures reference derived union names, and it lists some symbols on multiple pages. The explicit map makes each rendered destination and each non-catalog exception a reviewable decision.
## Consequences
- The catalog cannot drift: a source change that the committed file doesn't reflect fails `verify-cordis-catalog` in the pre-push hook and CI. A new event with no `@mode` tag, or a tag that contradicts its signature, fails the generator outright.
- The catalog cannot drift: a source change that the committed file doesn't reflect fails `verify-cordis-catalog` in the pre-push hook and CI. A new event with no `@mode` tag, a tag that contradicts its signature, or an unclassified signature type fails the generator outright.
- Event and service-method contracts have a single home — the JSDoc at the declaration. The catalog repeats that original JSDoc inside its generated signature block and uses its description portion as entry prose, so thin source documentation yields a thin catalog entry.
- The inherited tier is hand-summarized, so a vendor sync that adds/renames a cordis-core event or `ctx` member needs a matching edit to the curated table in `gen-cordis-catalog.ts`. This is the deliberate cost of not walking pinned vendor source; it changes rarely and is called out in the generator.
- `verify-event-taxonomy.ts` is deleted and the `docs/architecture.md` event table is gone; anyone who linked to a specific table row now lands on the generated catalog instead.

View File

@@ -1,5 +1,6 @@
/**
* Negative-path tests for the cordis catalog generator (`scripts/gen-cordis-catalog.ts`).
* Contract and negative-path tests for the cordis catalog generator
* (`scripts/gen-cordis-catalog.ts`).
*/
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
@@ -76,6 +77,33 @@ describe('gen-cordis-catalog collectEvents', () => {
expect(events[0]?.mode).toBe('parallel')
})
it('accepts linked, foundation, generic-parameter, and explicitly exempt signature types', () => {
const events = collectEvents(make(
' /**\n * Carry linked and foundation types.\n * @param value - the linked value.\n * @param preset - deployment metadata outside the core catalog.\n * @param signal - cancellation.\n * @mode parallel\n */\n \'fix/typed\'<T extends SessionEvent>(value: Readonly<T>, preset: PresetSpec, signal: AbortSignal): Promise<T>',
))
expect(events).toHaveLength(1)
expect(renderEvents(events)).toContain('Types: [SessionEvent](../core-data-structures/core.md)')
expect(renderEvents(events)).not.toContain('[PresetSpec]')
})
it('aggregates every unclassified signature type with its source and remediation', () => {
const expected = new RegExp([
'2 signature type-link coverage violation\\(s\\)',
'fix/one',
'packages/group/fix/src/index.ts',
'MissingOne',
'fix/two',
'packages/group/fix/src/index.ts',
'missingTwo',
'Add it to LINK_MAP',
'FOUNDATION_TYPE_NAMES',
'TYPE_LINK_EXEMPTIONS',
].join('[\\s\\S]*'))
expect(() => collectEvents(make(
' /**\n * First.\n * @param value - first value.\n * @mode emit\n */\n \'fix/one\'(value: MissingOne): void\n /**\n * Second.\n * @param value - second value.\n * @mode emit\n */\n \'fix/two\'(value: missingTwo): void',
))).toThrow(expected)
})
it('hard-errors when an event is missing its @mode tag', () => {
expect(() => collectEvents(make(
' /** No mode here. */\n \'fix/untagged\'(): void',
@@ -167,6 +195,12 @@ export class FixService {
expect(renderServices(services)).toContain('```ts cordis-catalog\n/**\n * Do the thing.\n * @param id - which thing to do.\n * @returns the outcome of doing it.\n */\nrun(id: string): string\n\n/** Fire and forget (void needs no @returns). */\npoke(): void')
})
it('hard-errors on an unclassified service-method signature type', () => {
expect(() => collectServices(makeService(
'/** Fixture service. */\nexport class FixService {\n /**\n * Use an unknown value.\n * @param value - the value.\n */\n run(value: MissingServiceType): void {}\n}',
))).toThrow(/service method ctx\.fix\.run .* references unclassified type 'MissingServiceType'/)
})
it('hard-errors on a public method with no JSDoc at all', () => {
expect(() => collectServices(makeService(
'/** Fixture service. */\nexport class FixService {\n run(id: string): string { return id }\n}',

View File

@@ -1,8 +1,8 @@
/**
* Generate the Cordis event and service catalogs from static declarations.
* The walk enforces event modes plus JSDoc parameter/return completeness;
* inherited Cordis services come from the curated table below. `--check`
* verifies both committed artifacts.
* The walk enforces event modes, JSDoc parameter/return completeness, and
* signature type-link coverage; inherited Cordis services come from the
* curated table below. `--check` verifies both committed artifacts.
*/
import { globSync, readFileSync, writeFileSync } from 'node:fs'
@@ -20,48 +20,196 @@ const OUT_SERVICES = 'docs/cordis-catalog/services.md'
const FENCE = 'ts cordis-catalog'
/**
* One primary core-data-structures page per signature type, shared by the
* Cordis and config catalogs; union names intentionally do not reuse the
* type-equivalence manifest's map-symbol entries.
* One primary core-data-structures page per project type used by a generated
* signature. This stays curated because union names intentionally do not
* reuse the type-equivalence manifest's map-symbol entries and some symbols
* appear on more than one page.
*/
// TODO(catalog-type-links): verify or generate link-map coverage.
export const LINK_MAP: Record<string, string> = {
Agent: 'core.md',
AgentOptions: 'core.md',
AgentStatus: 'core.md',
ContentBlock: 'core.md',
Message: 'core.md',
MessageSource: 'core.md',
ContinuationDecision: 'core.md',
ContinuationStop: 'core.md',
GenerateOptions: 'core.md',
LlmCallConfig: 'core.md',
LlmModelInfo: 'core.md',
LlmProviderInfo: 'core.md',
Message: 'core.md',
MessageSource: 'core.md',
PromptDecision: 'core.md',
SessionEvent: 'core.md',
SessionId: 'core.md',
SessionStartSource: 'core.md',
StreamChunk: 'llm-streaming.md',
TurnEndReason: 'session.md',
ToolDefinition: 'tools.md',
ToolExecution: 'tools.md',
ToolExecutionMode: 'tools.md',
ToolExecutionInput: 'tools.md',
ToolExecutionResult: 'tools.md',
ToolExecutionToken: 'tools.md',
ApprovalOutcome: 'approval.md',
ApprovalPolicy: 'approval.md',
ApprovalRequest: 'approval.md',
ApprovalService: 'approval.md',
BashExecRequest: 'bash.md',
BashExecSpec: 'bash.md',
BashProcess: 'bash.md',
BashRunResult: 'bash.md',
ConfinedArgv: 'sandbox.md',
SandboxMode: 'sandbox.md',
SandboxPolicy: 'sandbox.md',
DshEnvironment: 'bash.md',
CodeRunRequest: 'code-runtime.md',
CodeRunResult: 'code-runtime.md',
CompactionResult: 'compaction.md',
FileReadOutcome: 'filesystem.md',
FsDirEntry: 'filesystem.md',
FsEditOutcome: 'filesystem.md',
FsEditRequest: 'filesystem.md',
FsInfo: 'filesystem.md',
FsPathInfo: 'filesystem.md',
FsPolicyExec: 'filesystem.md',
FsTarget: 'filesystem.md',
FsVersion: 'filesystem.md',
FsWriteIntent: 'filesystem.md',
FsWriteOutcome: 'filesystem.md',
FsPolicyExec: 'filesystem.md',
FileReadOutcome: 'filesystem.md',
LlmAdapter: 'llm-streaming.md',
LlmService: 'llm-streaming.md',
StreamChunk: 'llm-streaming.md',
CreateSessionOptions: 'persistence.md',
SessionHeader: 'persistence.md',
SessionLocation: 'persistence.md',
ConfinedArgv: 'sandbox.md',
SandboxMode: 'sandbox.md',
SandboxPolicy: 'sandbox.md',
ScopeKey: 'scope.md',
Scoped: 'scope.md',
EpochHeader: 'session.md',
Session: 'session.md',
TurnEndReason: 'session.md',
SessionEventReadRequest: 'session-query.md',
SessionEventRecord: 'session-query.md',
SessionEventTrace: 'session-query.md',
SessionEventTraceRequest: 'session-query.md',
SessionEventWindow: 'session-query.md',
SessionLineageTrace: 'session-query.md',
SessionRecord: 'session-query.md',
SkillDefinition: 'skills.md',
SkillLookupOptions: 'skills.md',
SkillProvider: 'skills.md',
SkillRegistration: 'skills.md',
SkillSummary: 'skills.md',
SaveTextSpill: 'spill.md',
SpillRef: 'spill.md',
SubagentProvider: 'subagent.md',
SubagentRun: 'subagent.md',
SubagentService: 'subagent.md',
SubagentStartRequest: 'subagent.md',
AssembleContext: 'system-prompt.md',
PromptSection: 'system-prompt.md',
SystemPrompt: 'system-prompt.md',
ToolProviderResult: 'system-prompt.md',
TaskDoneListener: 'tasks.md',
TaskId: 'tasks.md',
TaskRead: 'tasks.md',
TaskSnapshot: 'tasks.md',
TaskStart: 'tasks.md',
TokenMeasurement: 'token-meter.md',
PostToolDecision: 'tools.md',
PreToolDecision: 'tools.md',
ToolDefinition: 'tools.md',
ToolExecution: 'tools.md',
ToolExecutionInput: 'tools.md',
ToolExecutionMode: 'tools.md',
ToolExecutionResult: 'tools.md',
ToolExecutionToken: 'tools.md',
ToolGuard: 'tools.md',
ToolRegistry: 'tools.md',
ToolRestriction: 'tools.md',
ToolSchema: 'tools.md',
AskUserQuestionAnswer: 'user-interaction.md',
AskUserQuestionRequest: 'user-interaction.md',
UserInteractionProvider: 'user-interaction.md',
WebFetchProvider: 'web.md',
WebFetchRequest: 'web.md',
WebFetchResult: 'web.md',
WebSearchProvider: 'web.md',
WebSearchRequest: 'web.md',
WebSearchResult: 'web.md',
WorkflowRun: 'workflow.md',
WorkflowRunInfo: 'workflow.md',
WorkflowStartRequest: 'workflow.md',
}
/** TypeScript lib and pinned framework types that have no repository-owned data page. */
const FOUNDATION_TYPE_NAMES = new Set([
'AbortSignal',
'AsyncIterable',
'Context',
'Error',
'Pick',
'Promise',
'Readonly',
])
/** Project types deliberately documented outside the core-data catalog. */
const TYPE_LINK_EXEMPTIONS: Readonly<Record<string, string>> = {
AgentFactory: 'agent creation seam is owned by packages/core/agent/README.md',
AgentHandle: 'agent ownership handle is owned by packages/core/agent/README.md',
BashEnvContributor: 'service-local extension type is owned by packages/bash/tool-bash/src/index.ts',
BashEnvVariableInfo: 'service-local metadata type is owned by packages/bash/tool-bash/src/index.ts',
CompactAgentContext: 'compaction service input is owned by packages/compact/compact/src/index.ts',
CreateAgentOptions: 'agent creation contract is owned by packages/core/agent/README.md',
PresetOption: 'deployment menu metadata is owned by packages/ui/permission/README.md',
PresetSpec: 'deployment preset composition is owned by packages/ui/permission/README.md',
PromptAssembly: 'assembly result is owned by packages/core/system-prompt/README.md',
ResumeAgentOptions: 'agent resume contract is owned by packages/core/agent/README.md',
SessionForkSource: 'service-local fork input is owned by packages/core/session/src/index.ts',
SubagentRunEndInfo: 'event-local snapshot is owned by packages/subagent/subagent/src/index.ts',
SubagentRunInfo: 'event-local snapshot is owned by packages/subagent/subagent/src/index.ts',
WorkflowAgentEndInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts',
WorkflowAgentInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts',
WorkflowResultInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts',
}
/** Collect named references from parameter, generic-constraint/default, and return types. */
function signatureTypeNames(member: ts.MethodSignature | ts.MethodDeclaration, sf: ts.SourceFile): string[] {
const declared = new Set(member.typeParameters?.map(parameter => parameter.name.text) ?? [])
const referenced = new Set<string>()
const visit = (node: ts.Node): void => {
if (ts.isTypeReferenceNode(node)) referenced.add(node.typeName.getText(sf))
if (ts.isTypeQueryNode(node)) referenced.add(node.exprName.getText(sf))
ts.forEachChild(node, visit)
}
for (const parameter of member.typeParameters ?? []) {
if (parameter.constraint) visit(parameter.constraint)
if (parameter.default) visit(parameter.default)
}
for (const parameter of member.parameters) {
if (parameter.type) visit(parameter.type)
}
if (member.type) visit(member.type)
return [...referenced].filter(name => !declared.has(name)).sort()
}
/** Append fail-closed signature type-link violations with actionable ownership choices. */
function checkTypeLinks(
where: string,
member: ts.MethodSignature | ts.MethodDeclaration,
sf: ts.SourceFile,
violations: string[],
): void {
for (const name of signatureTypeNames(member, sf)) {
if (Object.hasOwn(LINK_MAP, name)
|| FOUNDATION_TYPE_NAMES.has(name)
|| Object.hasOwn(TYPE_LINK_EXEMPTIONS, name)) continue
violations.push(
`${where} references unclassified type '${name}'. Add it to LINK_MAP with its core-data-structures page, `
+ 'to FOUNDATION_TYPE_NAMES if TypeScript or Cordis owns it, or to TYPE_LINK_EXEMPTIONS with '
+ 'the non-catalog documentation owner.',
)
}
}
/** Throw one aggregated diagnostic for every unclassified signature type. */
function reportTypeLinkViolations(gate: string, violations: string[]): void {
if (violations.length === 0) return
throw new Error(
`${gate}: ${violations.length} signature type-link coverage violation(s):\n`
+ violations.map(violation => ` ${violation}`).join('\n'),
)
}
/** One harness event, extracted from an `interface Events` block. */
@@ -148,6 +296,7 @@ function jsDocText(text: string, sf: ts.SourceFile, node: ts.Node): string {
export function collectEvents(scanRoot: string = root): EventEntry[] {
const entries: EventEntry[] = []
const violations: string[] = []
const typeLinkViolations: string[] = []
for (const rel of globSync('packages/*/*/src/*.ts', { cwd: scanRoot }).map(s => s.split(sep).join('/')).sort()) {
const abs = resolve(scanRoot, rel)
const text = readFileSync(abs, 'utf8')
@@ -161,6 +310,7 @@ export function collectEvents(scanRoot: string = root): EventEntry[] {
const { doc, mode } = parseJsDoc(raw)
const src = pointer(rel, sf, member)
const where = `event '${name}' (${src})`
checkTypeLinks(where, member, sf, typeLinkViolations)
if (!mode) {
violations.push(`${where} is missing an @mode tag. Add '@mode emit|waterfall|parallel|serial' to its JSDoc (see AGENTS.md).`)
}
@@ -185,6 +335,7 @@ export function collectEvents(scanRoot: string = root): EventEntry[] {
}
}
reportViolations('gen-cordis-catalog', violations)
reportTypeLinkViolations('gen-cordis-catalog', typeLinkViolations)
return entries
}
@@ -197,6 +348,7 @@ export function collectEvents(scanRoot: string = root): EventEntry[] {
export function collectServices(scanRoot: string = root): ServiceEntry[] {
const entries: ServiceEntry[] = []
const violations: string[] = []
const typeLinkViolations: string[] = []
for (const rel of globSync('packages/*/*/src/index.ts', { cwd: scanRoot }).map(s => s.split(sep).join('/')).sort()) {
const abs = resolve(scanRoot, rel)
const text = readFileSync(abs, 'utf8')
@@ -220,6 +372,7 @@ export function collectServices(scanRoot: string = root): ServiceEntry[] {
const memberName = member.name.getText(sf)
if (memberName.startsWith('[')) continue // computed/symbol members
const where = `service method ctx.${key}.${memberName} (${pointer(rel, sf, member)})`
checkTypeLinks(where, member, sf, typeLinkViolations)
const raw = rawJsDoc(text, member)
methods.push({ signature: memberSignature(member, sf), jsDoc: jsDocText(text, sf, member) })
if (!raw) { violations.push(`${where} has no JSDoc.`); continue }
@@ -243,6 +396,7 @@ export function collectServices(scanRoot: string = root): ServiceEntry[] {
}
}
reportViolations('gen-cordis-catalog', violations)
reportTypeLinkViolations('gen-cordis-catalog', typeLinkViolations)
return entries.sort((a, b) => a.key.localeCompare(b.key))
}