Use explicit ts specifiers for declarations

Restore explicit .ts relative specifiers in source and enable rewriteRelativeImportExtensions so emitted JS uses .js while declarations keep explicit .ts specifiers. Add a NodeNext declaration-consumer gate to prevent extensionless declaration regressions.
This commit is contained in:
Tianyi Cui
2026-06-22 06:11:00 +08:00
parent 94e7355449
commit 07f4047ff0
56 changed files with 323 additions and 147 deletions

View File

@@ -79,5 +79,5 @@ Each package has its own `README.md` with purpose, service API, events, extensio
- **Declaration merging for events and ctx**: services declare their events in `declare module 'cordis' { interface Events { ... } }` and their ctx key in `interface Context`.
- **Waterfall semantics**: `ctx.waterfall` listeners receive `(...args, next)` and MUST call `next()` to delegate; returning without it short-circuits (the veto mechanism).
- **Extensible unions**: `ContentBlockMap`, `MessageSourceMap`, `FinishReasonMap`, `TurnTriggerMap`, `TurnEndReasonMap`, and `SessionEventMap` use the merge-extensible-map pattern so plugins can add variants via declaration merging.
- **ESM everywhere**; imports use package names across package boundaries and extensionless relative specifiers within a package.
- **ESM everywhere**; imports use package names across package boundaries and explicit `.ts` relative specifiers within a package.
- **Tests**: vitest, colocated under `packages/<group>/<pkg>/tests/*.spec.ts`. Every registry needs an HMR-safety test. Err on the side of more tests.

View File

@@ -17,11 +17,11 @@ import { Context } from 'cordis'
import z from 'schemastery'
import { BashExecutor, BashTaskId } from '@deepseek-ai/dsh-bash'
import type { BashExecRequest, BashExecSpec, BashRunResult, BashTask, BashTaskRead, OwnerToken } from '@deepseek-ai/dsh-bash'
import { runBash } from './run'
import type { RunInternals, RunningBash } from './run'
import { runBash } from './run.ts'
import type { RunInternals, RunningBash } from './run.ts'
export { DEFAULT_GRACE_MS, ENV_OVERRIDES, killGroup, OutputCollector, runBash } from './run'
export type { RunInternals, RunningBash, SpawnOutcome, SpawnSpec } from './run'
export { DEFAULT_GRACE_MS, ENV_OVERRIDES, killGroup, OutputCollector, runBash } from './run.ts'
export type { RunInternals, RunningBash, SpawnOutcome, SpawnSpec } from './run.ts'
/** Plugin config (all optional — `static Config` supplies the defaults). */
export interface Config {

View File

@@ -15,9 +15,9 @@
*/
import { Context, Service } from 'cordis'
import type { BashExecRequest, BashExecSpec, BashRunResult, BashTask, BashTaskId, BashTaskListener, BashTaskRead, OwnerToken } from './types'
import type { BashExecRequest, BashExecSpec, BashRunResult, BashTask, BashTaskId, BashTaskListener, BashTaskRead, OwnerToken } from './types.ts'
export { BashTaskId, OwnerToken } from './types'
export { BashTaskId, OwnerToken } from './types.ts'
export type {
BashExecRequest,
BashExecSpec,
@@ -27,7 +27,7 @@ export type {
BashTaskRead,
BashTaskStatus,
CollectedOutput,
} from './types'
} from './types.ts'
declare module 'cordis' {
interface Context {

View File

@@ -11,8 +11,8 @@ import type { AgentId, AgentOptions, AgentStatus, SendOptions } from '@deepseek-
import type { Agent } from '@deepseek-ai/dsh-agent'
import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm'
import type { Session } from '@deepseek-ai/dsh-session'
import { Inbox } from './inbox'
import { isTurnOpen, lastTurnNumber, runLoop } from './loop'
import { Inbox } from './inbox.ts'
import { isTurnOpen, lastTurnNumber, runLoop } from './loop.ts'
/**
* The concrete {@link Agent} implementation owned by the agent-loop plugin.

View File

@@ -17,11 +17,11 @@ import type { Session } from '@deepseek-ai/dsh-session'
import type {} from '@deepseek-ai/dsh-system-prompt'
import type {} from '@deepseek-ai/dsh-tools'
import type { SessionPersistence } from '@deepseek-ai/dsh-session-persistence'
import { ReactLoopAgent } from './agent'
import { ReactLoopAgent } from './agent.ts'
export { ReactLoopAgent } from './agent'
export { Inbox, type InboxMessage } from './inbox'
export { runLoop } from './loop'
export { ReactLoopAgent } from './agent.ts'
export { Inbox, type InboxMessage } from './inbox.ts'
export { runLoop } from './loop.ts'
declare module 'cordis' {
interface Context {

View File

@@ -13,7 +13,7 @@ import { BlockAssembler, HarnessError } from '@deepseek-ai/dsh-llm'
import type { Session, TurnEndReason, TurnTrigger } from '@deepseek-ai/dsh-session'
import { renderPrompt } from '@deepseek-ai/dsh-system-prompt'
import type {} from '@deepseek-ai/dsh-tools'
import type { ReactLoopAgent } from './agent'
import type { ReactLoopAgent } from './agent.ts'
/** An Error with an optional machine-readable code (e.g., from LlmError or a throwing plugin). */
type CodedError = Error & { code?: string }

View File

@@ -7,9 +7,9 @@
import { Context, Service } from 'cordis'
import type { SessionId } from '@deepseek-ai/dsh-session'
import type { Agent, AgentId, AgentOptions } from './types'
import type { Agent, AgentId, AgentOptions } from './types.ts'
export * from './types'
export * from './types.ts'
declare module 'cordis' {
interface Context {

View File

@@ -9,13 +9,13 @@
import { Context, Service } from 'cordis'
import { isAbsolute } from 'node:path'
import type { ContentBlock, Message, MessageSource } from '@deepseek-ai/dsh-llm'
import { SESSION_FORMAT_VERSION, SessionId } from './types'
import type { CreateSessionOptions, SessionEvent, SessionEventMap, SessionEventType, SessionHeader } from './types'
import { isJsonValue } from './json'
import { SESSION_FORMAT_VERSION, SessionId } from './types.ts'
import type { CreateSessionOptions, SessionEvent, SessionEventMap, SessionEventType, SessionHeader } from './types.ts'
import { isJsonValue } from './json.ts'
export * from './types'
export { isJsonValue } from './json'
export { interruptedTurnClosers } from './repair'
export * from './types.ts'
export { isJsonValue } from './json.ts'
export { interruptedTurnClosers } from './repair.ts'
declare module 'cordis' {
interface Context {

View File

@@ -36,7 +36,7 @@
*/
import type { CallId } from '@deepseek-ai/dsh-llm'
import type { SessionEvent } from './types'
import type { SessionEvent } from './types.ts'
/**
* Scan `events` for an open turn/step at the tail and return the synthetic

View File

@@ -24,7 +24,7 @@ export {
type InferArgs,
type DefineToolOptions,
type JsonSchemaObject,
} from './schema'
} from './schema.ts'
declare module 'cordis' {
interface Context {

View File

@@ -21,7 +21,7 @@
import type { ContentBlock } from '@deepseek-ai/dsh-llm'
import { assertNever, HarnessError } from '@deepseek-ai/dsh-llm'
import type { ToolCallPresentation, ToolDefinition, ToolExecution, ToolResult, ToolResultPresentation } from './index'
import type { ToolCallPresentation, ToolDefinition, ToolExecution, ToolResult, ToolResultPresentation } from './index.ts'
// ---------------------------------------------------------------------------
// SchemaSpec — the author-facing per-property type

View File

@@ -7,11 +7,11 @@
import { LlmAdapter, LlmError } from '@deepseek-ai/dsh-llm'
import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
import { serializeRequest } from './serialize'
import type { RequestDefaults } from './serialize'
import { parseSse } from './sse'
import { translate } from './translate'
import type { WireError } from './types'
import { serializeRequest } from './serialize.ts'
import type { RequestDefaults } from './serialize.ts'
import { parseSse } from './sse.ts'
import { translate } from './translate.ts'
import type { WireError } from './types.ts'
export interface DeepSeekAdapterOptions {
apiKey: string

View File

@@ -21,15 +21,15 @@
import type { Context } from 'cordis'
import z from 'schemastery'
import type {} from '@deepseek-ai/dsh-llm'
import { DeepSeekAdapter } from './adapter'
import { DeepSeekAdapter } from './adapter.ts'
export { DeepSeekAdapter, httpErrorCode } from './adapter'
export type { DeepSeekAdapterOptions } from './adapter'
export { serializeMessages, serializeRequest } from './serialize'
export type { RequestDefaults } from './serialize'
export { DONE, parseSse } from './sse'
export { mapFinishReason, mapUsage, translate } from './translate'
export type * from './types'
export { DeepSeekAdapter, httpErrorCode } from './adapter.ts'
export type { DeepSeekAdapterOptions } from './adapter.ts'
export { serializeMessages, serializeRequest } from './serialize.ts'
export type { RequestDefaults } from './serialize.ts'
export { DONE, parseSse } from './sse.ts'
export { mapFinishReason, mapUsage, translate } from './translate.ts'
export type * from './types.ts'
export const name = 'llm-deepseek'
export const inject = ['llm']

View File

@@ -18,7 +18,7 @@
import { LlmError } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, GenerateOptions, Message } from '@deepseek-ai/dsh-llm'
import type { WireMessage, WireRequest, WireTool } from './types'
import type { WireMessage, WireRequest, WireTool } from './types.ts'
/** Adapter-level request defaults (from plugin config). */
export interface RequestDefaults {

View File

@@ -16,8 +16,8 @@
import { CallId, LlmError } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, FinishReason, StreamChunk, TokenUsage } from '@deepseek-ai/dsh-llm'
import { DONE } from './sse'
import type { WireChunk, WireUsage } from './types'
import { DONE } from './sse.ts'
import type { WireChunk, WireUsage } from './types.ts'
/** One open block under assembly. */
interface OpenBlock {

View File

@@ -16,7 +16,7 @@ import type { Model } from '@earendil-works/pi-ai'
import { LlmAdapter, LlmError } from '@deepseek-ai/dsh-llm'
import { CallId } from '@deepseek-ai/dsh-llm'
import type { GenerateOptions, StreamChunk, ToolSchema } from '@deepseek-ai/dsh-llm'
import { toPiContext, toStreamChunks } from './convert'
import { toPiContext, toStreamChunks } from './convert.ts'
/** Reasoning levels surfaced by this adapter (DeepSeek wire: high|max). */
export type PiAiReasoning = 'off' | 'high' | 'xhigh'

View File

@@ -19,12 +19,12 @@
import type { Context } from 'cordis'
import z from 'schemastery'
import type {} from '@deepseek-ai/dsh-llm'
import { PiAiAdapter } from './adapter'
import type { PiAiReasoning } from './adapter'
import { PiAiAdapter } from './adapter.ts'
import type { PiAiReasoning } from './adapter.ts'
export { buildModel, PiAiAdapter } from './adapter'
export type { PiAiAdapterOptions, PiAiReasoning } from './adapter'
export { mapStopReason, mapUsage, toPiContext, toStreamChunks } from './convert'
export { buildModel, PiAiAdapter } from './adapter.ts'
export type { PiAiAdapterOptions, PiAiReasoning } from './adapter.ts'
export { mapStopReason, mapUsage, toPiContext, toStreamChunks } from './convert.ts'
export const name = 'llm-pi-ai'
export const inject = ['llm']

View File

@@ -6,9 +6,9 @@
* @module @deepseek-ai/dsh-llm/assembler
*/
import { CallId } from './brand'
import { assertNever } from './never'
import type { ContentBlock, FinishReason, Message, StreamChunk, TokenUsage } from './types'
import { CallId } from './brand.ts'
import { assertNever } from './never.ts'
import type { ContentBlock, FinishReason, Message, StreamChunk, TokenUsage } from './types.ts'
interface PartialBlock {
blockType: string

View File

@@ -7,14 +7,14 @@
*/
import { Context, Service } from 'cordis'
import type { GenerateOptions, StreamChunk } from './types'
import { HarnessError } from './error'
import type { GenerateOptions, StreamChunk } from './types.ts'
import { HarnessError } from './error.ts'
export * from './brand'
export * from './never'
export * from './error'
export * from './types'
export { BlockAssembler } from './assembler'
export * from './brand.ts'
export * from './never.ts'
export * from './error.ts'
export * from './types.ts'
export { BlockAssembler } from './assembler.ts'
declare module 'cordis' {
interface Context {

View File

@@ -19,7 +19,7 @@
* ```
*/
import type { CallId } from './brand'
import type { CallId } from './brand.ts'
/** Cache hint attached to a content block (provider-interpreted). */
export type CacheHint = 'ephemeral'

View File

@@ -29,7 +29,7 @@ import {
import type { Session, SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session'
import {
encodeSegment, eventLine, logPath, parseHeaderMeta, scanLog, sessionDir, toHeaderLine,
} from './format'
} from './format.ts'
export interface Config {
/**

View File

@@ -29,9 +29,9 @@ import {
import type { Session, SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session'
import {
openDatabase, rowToMeta, scanRows, type EventRow, type SessionRow,
} from './schema'
} from './schema.ts'
export { SCHEMA_VERSION } from './schema'
export { SCHEMA_VERSION } from './schema.ts'
/** Plugin configuration. */
export interface Config {

View File

@@ -27,7 +27,7 @@
import { Context } from 'cordis'
import { interruptedTurnClosers, SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session'
import type { Session, SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session'
import { assertSerializable, seedCoversPrefix } from './index'
import { assertSerializable, seedCoversPrefix } from './index.ts'
/**
* A stored session's durable prefix as read back from a backend: its

View File

@@ -29,8 +29,8 @@ import type { SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-se
export type { SessionHeader } from '@deepseek-ai/dsh-session'
// The backend-agnostic write-path orchestration first-party backends compose.
export { PersistenceCoordinator } from './coordinator'
export type { PersistenceBackend, StoredPrefix } from './coordinator'
export { PersistenceCoordinator } from './coordinator.ts'
export type { PersistenceBackend, StoredPrefix } from './coordinator.ts'
declare module 'cordis' {
interface Context {

View File

@@ -74,7 +74,7 @@ import {
harnessBlockToAcpContent,
promptHasUnsupportedContent,
turnEndToStopReason,
} from './codec'
} from './codec.ts'
export const name = 'acp'
// The bridge programs against the interface packages only (architecture rule: