From 07f4047ff0d0d5e8f4eb24b0747e1a92b578b424 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Mon, 22 Jun 2026 06:11:00 +0800 Subject: [PATCH] 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. --- .github/workflows/ci.yml | 7 +- AGENTS.md | 6 +- docs/cookbook/adding-a-package.md | 2 + docs/cookbook/adding-a-vendored-package.md | 2 + docs/development.md | 5 +- .../process/2026-06-11-quality-gates.md | 2 +- .../process/2026-06-17-ts-build-config.md | 9 +- package.json | 3 +- packages/README.md | 2 +- packages/bash/bash-local/src/index.ts | 8 +- packages/bash/bash/src/index.ts | 6 +- packages/core/agent-loop/src/agent.ts | 4 +- packages/core/agent-loop/src/index.ts | 8 +- packages/core/agent-loop/src/loop.ts | 2 +- packages/core/agent/src/index.ts | 4 +- packages/core/session/src/index.ts | 12 +- packages/core/session/src/repair.ts | 2 +- packages/core/tools/src/index.ts | 2 +- packages/core/tools/src/schema.ts | 2 +- packages/llm/llm-deepseek/src/adapter.ts | 10 +- packages/llm/llm-deepseek/src/index.ts | 16 +- packages/llm/llm-deepseek/src/serialize.ts | 2 +- packages/llm/llm-deepseek/src/translate.ts | 4 +- packages/llm/llm-pi-ai/src/adapter.ts | 2 +- packages/llm/llm-pi-ai/src/index.ts | 10 +- packages/llm/llm/src/assembler.ts | 6 +- packages/llm/llm/src/index.ts | 14 +- packages/llm/llm/src/types.ts | 2 +- .../session-persistence-jsonl/src/index.ts | 2 +- .../session-persistence-sqlite/src/index.ts | 4 +- .../session-persistence/src/coordinator.ts | 2 +- .../session-persistence/src/index.ts | 4 +- packages/ui/acp/src/index.ts | 2 +- scripts/verify-node-next-types.ts | 160 ++++++++++++++++++ tsconfig.base.json | 2 + vendor/README.md | 2 +- vendor/cordis/src/context.ts | 12 +- vendor/cordis/src/events.ts | 8 +- vendor/cordis/src/fiber.ts | 10 +- vendor/cordis/src/index.ts | 14 +- vendor/cordis/src/logger.ts | 8 +- vendor/cordis/src/reflect.ts | 8 +- vendor/cordis/src/registry.ts | 8 +- vendor/cordis/src/service.ts | 4 +- vendor/cordis/src/utils.ts | 2 +- vendor/cosmokit/src/array.ts | 2 +- vendor/cosmokit/src/index.ts | 10 +- vendor/cosmokit/src/types.ts | 2 +- vendor/hmr/src/index.ts | 2 +- vendor/loader/src/config/entry.ts | 8 +- vendor/loader/src/config/group.ts | 4 +- vendor/loader/src/config/isolate.ts | 4 +- vendor/loader/src/config/tree.ts | 4 +- vendor/loader/src/index.ts | 20 +-- vendor/logger-console/src/browser.ts | 4 +- vendor/logger-console/src/index.ts | 4 +- 56 files changed, 323 insertions(+), 147 deletions(-) create mode 100644 scripts/verify-node-next-types.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47ca887219..f164e3c4c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,12 +69,13 @@ jobs: run: pnpm run test:snapshot # Before hygiene: publint validates the packed artifacts (lib/index.js), - # which only the tsdown bundling step emits. + # which only the tsdown bundling step emits, and verify-node-next-types + # validates the built declarations. - name: Build (tsc -b + tsdown bundles) run: pnpm run build - - name: Hygiene (knip + publint) - run: pnpm run knip && pnpm run publint + - name: Hygiene (knip + publint + constraints + NodeNext types) + run: pnpm run hygiene - name: Demo smoke test run: | diff --git a/AGENTS.md b/AGENTS.md index 2b38f32360..d7340c631d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -145,7 +145,7 @@ pnpm run lint:fix # eslint . --fix pnpm run build # tsc emits lib/types, then tsdown bundles runtime lib/index.* pnpm run knip # dead-code / unused-dependency check pnpm run publint # package.json publish-correctness check (every packages/*/* package) -pnpm run hygiene # knip + publint + workspace constraints +pnpm run hygiene # knip + publint + workspace constraints + NodeNext type-consumer check pnpm run doc-typecheck # typecheck every ```ts block in README.md, docs/**/*.md, # packages/*/*.md + packages/*/*/*.md (doc/code drift gate) pnpm run gen-cordis-catalog # regenerate docs/cordis-catalog/events-and-services.md @@ -160,6 +160,8 @@ pnpm run verify-package-paths # assert every packages/ cited in Markdown pnpm run verify-rfc-classification # assert every RFC lives in a valid # {lifecycle}/{class}/ folder and docs/rfc/README.md lists it # under the matching heading (closed class set + index completeness) +pnpm run verify-node-next-types # assert built declarations typecheck for a + # standard external NodeNext ESM TypeScript consumer pnpm run doc-sync # doc-typecheck + verify-cordis-catalog + verify-md-wrap + verify-md-links + verify-doc-refs + verify-package-paths + verify-rfc-classification + verify-type-equiv (CI runs this) pnpm run demo:echo # run examples/echo-agent (no API key; type "echo hi" to # see a tool call) — the mock skeleton @@ -188,7 +190,7 @@ Dev/test/demo run **unbuilt** via tsx + the source `paths` map in the root `tsco ## Conventions - **Package naming**: every npm package in this repo is `@deepseek-ai/dsh-` (vendored packages keep their upstream names and are `private: true`). -- **ESM everywhere** (`"type": "module"`); imports between workspace packages use package names, never relative paths across package boundaries. In-package relative imports are extensionless so generated `.d.ts` files stay extensionless; `lib/types/**/*.js` is a bundler-only intermediate, not a Node ESM entrypoint. +- **ESM everywhere** (`"type": "module"`); imports between workspace packages use package names, never relative paths across package boundaries. In-package relative imports use explicit `.ts` extensions; `rewriteRelativeImportExtensions` turns those into `.js` in emitted JS, while declarations keep explicit `.ts` specifiers that NodeNext/Node16 TypeScript consumers can resolve to sibling `.d.ts` files. `lib/types/**/*.js` is a bundler-only intermediate, not a Node ESM entrypoint. - **`cordis` is a peerDependency** (+ devDependency) of every harness package, mirroring upstream convention. - **Registrations are effects**: anything a plugin contributes (adapter, tool, section, agent, event listener) goes through `ctx.effect()` / `ctx.on()` so disposal and HMR work. If you write a registry, `register()` must return the disposer. - **Typed events via declaration merging**: services declare their events in `declare module 'cordis' { interface Events { … } }`, and their ctx key in `interface Context`. Extensible unions use the merge-extensible-map pattern (see `ContentBlockMap`, `MessageSourceMap`). diff --git a/docs/cookbook/adding-a-package.md b/docs/cookbook/adding-a-package.md index 991db3be60..593a0a93ba 100644 --- a/docs/cookbook/adding-a-package.md +++ b/docs/cookbook/adding-a-package.md @@ -17,6 +17,8 @@ packages// package.json invariants (enforced by `pnpm run constraints` / `scripts/check-workspace-constraints.ts`): `private: true`, `version: 0.0.1`, `type: module`, `main: "lib/index.js"`, `types: "lib/types/index.d.ts"`, `exports["."].types: "./lib/types/index.d.ts"`, `exports["."].default: "./lib/index.js"`, `cordis` in BOTH peerDependencies and devDependencies (same range). Mirror every dsh peer dependency in devDependencies. `schemastery` goes in `dependencies` (it is a runtime validator), matching agent-loop. The `files` list is precise: `lib/index.js`, `lib/types/**/*.d.ts`, `lib/types/**/*.d.ts.map`, and `src`; do not publish `lib/types` JS or JS-map intermediates or stale root declaration files. CLI app packages with a package `bin` include `lib/bin.js` immediately after `lib/index.js` in `files`. +In-package relative imports use explicit `.ts` specifiers in source (for example, `export * from './types.ts'`). The compiler rewrites those to `.js` in emitted JS and leaves explicit `.ts` specifiers in declarations, which standard NodeNext/Node16 TypeScript consumers resolve to the sibling `.d.ts` files. + ## 2. Register it in the root configs | File | Change | diff --git a/docs/cookbook/adding-a-vendored-package.md b/docs/cookbook/adding-a-vendored-package.md index 4f411c6f04..59df2f617b 100644 --- a/docs/cookbook/adding-a-vendored-package.md +++ b/docs/cookbook/adding-a-vendored-package.md @@ -29,6 +29,8 @@ vendor// `package.json` invariants: `"private": true` (vendored packages are never published), keep upstream's `name`/`version`/`exports`/`type`, point declaration metadata at `lib/types`, publish `.d.ts` and `.d.ts.map` declaration outputs, and list its cordis deps in `peerDependencies` (matching the upstream manifest). Transitive upstream deps must themselves be vendored or already present — vendoring one package often means vendoring its dependency tree (e.g. `@cordisjs/plugin-http` pulls `@cordisjs/fetch-file`). +Local relative imports/exports in vendored TypeScript source use explicit `.ts` specifiers after copying. This is a repo-local build-shape divergence from upstream: `rewriteRelativeImportExtensions` emits `.js` runtime imports while declarations keep explicit `.ts` specifiers that NodeNext/Node16 TypeScript consumers can resolve. + ## 2. Register it in the root configs | File | Change | diff --git a/docs/development.md b/docs/development.md index 5e4bf5d1e9..f2206d30c0 100644 --- a/docs/development.md +++ b/docs/development.md @@ -39,7 +39,7 @@ If you are preparing to push from a fresh clone or worktree, also build once: pnpm run build ``` -`pnpm run hygiene` includes `publint`, which validates package entrypoints against the built `lib/*.js` files. A fresh worktree has no bundled JS until `pnpm run build` runs. +`pnpm run hygiene` includes `publint`, which validates package entrypoints against the built `lib/*.js` files, and `verify-node-next-types`, which validates built declarations against a temporary NodeNext consumer. A fresh worktree has no bundled JS or declarations until `pnpm run build` runs. ## Environment variables @@ -101,7 +101,8 @@ pnpm run doc-sync # doc-typecheck, cordis-catalog freshness, markdown wrap pnpm run gen-module-graph # regenerate docs/module-graph.md from package peerDeps pnpm run verify-module-graph # fail if docs/module-graph.md is stale pnpm run build # emit lib/types intermediates, then bundle lib/index.* runtime files -pnpm run hygiene # knip, publint, and workspace constraints +pnpm run verify-node-next-types # fail if built declarations are not NodeNext-consumable +pnpm run hygiene # knip, publint, workspace constraints, and NodeNext declaration check ``` When changing package public behavior, update the relevant README or JSDoc in the same change. `pnpm run doc-sync` catches checked TypeScript snippets, cordis events/services catalog drift, and hard-wrapped markdown prose, but broader prose/API sync still needs review. diff --git a/docs/rfc/implemented/process/2026-06-11-quality-gates.md b/docs/rfc/implemented/process/2026-06-11-quality-gates.md index 3b41613b1a..277a56fa2b 100644 --- a/docs/rfc/implemented/process/2026-06-11-quality-gates.md +++ b/docs/rfc/implemented/process/2026-06-11-quality-gates.md @@ -15,7 +15,7 @@ Every AGENTS.md promise gets a command that exits non-zero, wired into git hooks - Max-strict TypeScript (`noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, …); examples, tests, and scripts typecheck in CI via the root no-emit `tsconfig.json` while package/vendor code stays behind its own project-reference boundary. - ESLint strict-type-checked + @stylistic (the house style, enforced); vendored code excluded. - Per-file 100% coverage on `packages/*/src` (v8); unreachable defensive guards carry `/* v8 ignore */ ` with stated reasons instead of deletion. -- knip (dead code/deps), publint (package correctness), workspace constraints (workspace rules: private, cordis peer+dev, uniform version, ESM). +- knip (dead code/deps), publint (package correctness), workspace constraints (workspace rules: private, cordis peer+dev, uniform version, ESM), and a NodeNext consumer typecheck for built package declarations. - lefthook pre-commit (lint staged, typecheck, vendor-manifest guard) and pre-push (tests, hygiene); CI runs the full matrix on node 24/26 plus a demo smoke test driving the echo-agent end to end. ## Consequences diff --git a/docs/rfc/implemented/process/2026-06-17-ts-build-config.md b/docs/rfc/implemented/process/2026-06-17-ts-build-config.md index f0a52d8d6a..fdcc85aa38 100644 --- a/docs/rfc/implemented/process/2026-06-17-ts-build-config.md +++ b/docs/rfc/implemented/process/2026-06-17-ts-build-config.md @@ -17,7 +17,7 @@ Validation found several concrete technical issues and possible routes: - `tsdown` uses `oxc` to transform TypeScript, which is not the same behavior as `tsc`. - Bundled `.d.ts` emitted by `tsdown` conflicts with Cordis' internal relative module augmentation shape. - - The tsc output is affected by `allowImportingTsExtensions`, so we need to ensure that generated `.js` files do not import `.ts` files and generated `.d.ts` files do not import `.js` files. Therefore, we need to adjust the import specifiers to extensionless in the TypeScript source. + - The tsc output is affected by `allowImportingTsExtensions`, so we need to ensure that generated `.js` files do not import `.ts` files and generated `.d.ts` files do not contain extensionless relative imports. Therefore, in-package relative imports use explicit `.ts` specifiers in TypeScript source and `rewriteRelativeImportExtensions` rewrites those specifiers to `.js` in emitted JS. - Bundled `.js` emitted by `tsdown` is not the same behavior as per-file `.js` emitted by `tsc -b`, such as decorator transform behavior. - `vendor/*/src`, examples, tests, and scripts cannot all be plain-included in one root strict program. - Directly typechecking `vendor/*/src` under the root strict config triggers many type errors outside this project's ownership. @@ -26,7 +26,7 @@ Validation found several concrete technical issues and possible routes: ## Decision -In-package relative imports are extensionless. +In-package relative imports use explicit `.ts` specifiers. `pnpm run build` is a two-stage build: @@ -47,6 +47,9 @@ pnpm run build: tsc -b tsconfig.build.json tsdown +pnpm run verify-node-next-types: +tsx scripts/verify-node-next-types.ts + pnpm run typecheck: tsc -b tsconfig.json ``` @@ -60,8 +63,10 @@ Build responsibilities are clearer: - Each module under `packages//` and `vendor/*` has one local tsconfig for build, typecheck, and tools that run source directly, such as `tsx` and `vitest`. - The `build` command uses `tsconfig.build.json`. `tsc -b` owns the publishable per-module `.js` and `.d.ts` output, and the bundler owns only `lib/index.*`. - `lib/types/*.d.ts` and `.d.ts.map` are the publish declaration output. + - `lib/types/*.d.ts` uses explicit `.ts` relative specifiers, which TypeScript's NodeNext/Node16 resolver maps to sibling `.d.ts` files. - `lib/types/*.js` is only a bundler input and must not be used as a runtime entry or public import target. - `lib/index.*` is the publish runtime output and is generated by the bundler, currently `tsdown`. +- `pnpm run verify-node-next-types` scans built declarations for extensionless relative specifiers, then typechecks a temporary external ESM consumer with `moduleResolution: "NodeNext"` against the built `types`/`exports` surface, so declaration specifier regressions fail before publish. - The `typecheck` command uses `tsconfig.json`. Examples, tests, and scripts are checked by the root no-emit project, while packages and vendor modules keep the same emit behavior as `build`. Package and vendor source stays behind project-reference boundaries. The Cordis vendor copy now has one more type-structure divergence from upstream. During upstream sync, that divergence must be reapplied or explicitly retired. diff --git a/package.json b/package.json index 1e6155ff94..2e83cdca61 100644 --- a/package.json +++ b/package.json @@ -31,13 +31,14 @@ "verify-package-paths": "tsx scripts/verify-package-paths.ts", "verify-rfc-classification": "tsx scripts/verify-rfc-classification.ts", "verify-type-equiv": "tsx scripts/verify-type-equiv.ts", + "verify-node-next-types": "tsx scripts/verify-node-next-types.ts", "gen-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts", "verify-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts --check", "gen-module-graph": "tsx scripts/gen-module-graph.ts", "verify-module-graph": "tsx scripts/gen-module-graph.ts --check", "constraints": "tsx scripts/check-workspace-constraints.ts", "doc-sync": "pnpm run doc-typecheck && pnpm run verify-cordis-catalog && pnpm run verify-md-wrap && pnpm run verify-md-links && pnpm run verify-doc-refs && pnpm run verify-package-paths && pnpm run verify-rfc-classification && pnpm run verify-type-equiv", - "hygiene": "pnpm run knip && pnpm run publint && pnpm run constraints", + "hygiene": "pnpm run knip && pnpm run publint && pnpm run constraints && pnpm run verify-node-next-types", "demo:echo": "node --expose-internals --import tsx packages/ui/stdio-agent/src/bin.ts examples/echo-agent/cordis.yml", "demo:coding": "node --expose-internals --import tsx packages/ui/stdio-agent/src/bin.ts examples/coding-agent/cordis.yml", "demo:acp": "node --import tsx packages/ui/acp-agent/src/bin.ts examples/acp-agent/cordis.yml", diff --git a/packages/README.md b/packages/README.md index 976c9f7ac7..1fcc0c44d0 100644 --- a/packages/README.md +++ b/packages/README.md @@ -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///tests/*.spec.ts`. Every registry needs an HMR-safety test. Err on the side of more tests. diff --git a/packages/bash/bash-local/src/index.ts b/packages/bash/bash-local/src/index.ts index b2d117324b..05f1ed75dd 100644 --- a/packages/bash/bash-local/src/index.ts +++ b/packages/bash/bash-local/src/index.ts @@ -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 { diff --git a/packages/bash/bash/src/index.ts b/packages/bash/bash/src/index.ts index b8d7c619e1..01c5c081c3 100644 --- a/packages/bash/bash/src/index.ts +++ b/packages/bash/bash/src/index.ts @@ -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 { diff --git a/packages/core/agent-loop/src/agent.ts b/packages/core/agent-loop/src/agent.ts index c6188c9a7e..402a9a8416 100644 --- a/packages/core/agent-loop/src/agent.ts +++ b/packages/core/agent-loop/src/agent.ts @@ -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. diff --git a/packages/core/agent-loop/src/index.ts b/packages/core/agent-loop/src/index.ts index 86fe091b85..90d641eeeb 100644 --- a/packages/core/agent-loop/src/index.ts +++ b/packages/core/agent-loop/src/index.ts @@ -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 { diff --git a/packages/core/agent-loop/src/loop.ts b/packages/core/agent-loop/src/loop.ts index 443f98d13a..8d19c464fd 100644 --- a/packages/core/agent-loop/src/loop.ts +++ b/packages/core/agent-loop/src/loop.ts @@ -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 } diff --git a/packages/core/agent/src/index.ts b/packages/core/agent/src/index.ts index b39d8343d7..158946178c 100644 --- a/packages/core/agent/src/index.ts +++ b/packages/core/agent/src/index.ts @@ -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 { diff --git a/packages/core/session/src/index.ts b/packages/core/session/src/index.ts index 56d8352c36..cef91c110c 100644 --- a/packages/core/session/src/index.ts +++ b/packages/core/session/src/index.ts @@ -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 { diff --git a/packages/core/session/src/repair.ts b/packages/core/session/src/repair.ts index 6215ebc2a8..5cc62b37c7 100644 --- a/packages/core/session/src/repair.ts +++ b/packages/core/session/src/repair.ts @@ -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 diff --git a/packages/core/tools/src/index.ts b/packages/core/tools/src/index.ts index 6a70cfdd01..5a17aa2b0c 100644 --- a/packages/core/tools/src/index.ts +++ b/packages/core/tools/src/index.ts @@ -24,7 +24,7 @@ export { type InferArgs, type DefineToolOptions, type JsonSchemaObject, -} from './schema' +} from './schema.ts' declare module 'cordis' { interface Context { diff --git a/packages/core/tools/src/schema.ts b/packages/core/tools/src/schema.ts index 16b46cd5d7..b717eabf9a 100644 --- a/packages/core/tools/src/schema.ts +++ b/packages/core/tools/src/schema.ts @@ -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 diff --git a/packages/llm/llm-deepseek/src/adapter.ts b/packages/llm/llm-deepseek/src/adapter.ts index f9250987f3..fda527359a 100644 --- a/packages/llm/llm-deepseek/src/adapter.ts +++ b/packages/llm/llm-deepseek/src/adapter.ts @@ -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 diff --git a/packages/llm/llm-deepseek/src/index.ts b/packages/llm/llm-deepseek/src/index.ts index f4f7e43635..79313f910f 100644 --- a/packages/llm/llm-deepseek/src/index.ts +++ b/packages/llm/llm-deepseek/src/index.ts @@ -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'] diff --git a/packages/llm/llm-deepseek/src/serialize.ts b/packages/llm/llm-deepseek/src/serialize.ts index 11b9028af0..4e967d6667 100644 --- a/packages/llm/llm-deepseek/src/serialize.ts +++ b/packages/llm/llm-deepseek/src/serialize.ts @@ -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 { diff --git a/packages/llm/llm-deepseek/src/translate.ts b/packages/llm/llm-deepseek/src/translate.ts index ea5e50d7c1..08cc019b61 100644 --- a/packages/llm/llm-deepseek/src/translate.ts +++ b/packages/llm/llm-deepseek/src/translate.ts @@ -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 { diff --git a/packages/llm/llm-pi-ai/src/adapter.ts b/packages/llm/llm-pi-ai/src/adapter.ts index 0f92da4bed..e15cce8252 100644 --- a/packages/llm/llm-pi-ai/src/adapter.ts +++ b/packages/llm/llm-pi-ai/src/adapter.ts @@ -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' diff --git a/packages/llm/llm-pi-ai/src/index.ts b/packages/llm/llm-pi-ai/src/index.ts index d146df5824..bef0d4b3f5 100644 --- a/packages/llm/llm-pi-ai/src/index.ts +++ b/packages/llm/llm-pi-ai/src/index.ts @@ -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'] diff --git a/packages/llm/llm/src/assembler.ts b/packages/llm/llm/src/assembler.ts index fd13c34ad1..328ef01c54 100644 --- a/packages/llm/llm/src/assembler.ts +++ b/packages/llm/llm/src/assembler.ts @@ -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 diff --git a/packages/llm/llm/src/index.ts b/packages/llm/llm/src/index.ts index 2f9e51e215..320838a8a6 100644 --- a/packages/llm/llm/src/index.ts +++ b/packages/llm/llm/src/index.ts @@ -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 { diff --git a/packages/llm/llm/src/types.ts b/packages/llm/llm/src/types.ts index 158492d99c..63fc0f5b0c 100644 --- a/packages/llm/llm/src/types.ts +++ b/packages/llm/llm/src/types.ts @@ -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' diff --git a/packages/session-persistence/session-persistence-jsonl/src/index.ts b/packages/session-persistence/session-persistence-jsonl/src/index.ts index 6992b4fa53..6de7eafeb3 100644 --- a/packages/session-persistence/session-persistence-jsonl/src/index.ts +++ b/packages/session-persistence/session-persistence-jsonl/src/index.ts @@ -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 { /** diff --git a/packages/session-persistence/session-persistence-sqlite/src/index.ts b/packages/session-persistence/session-persistence-sqlite/src/index.ts index 701ab6e0bc..cef61cb071 100644 --- a/packages/session-persistence/session-persistence-sqlite/src/index.ts +++ b/packages/session-persistence/session-persistence-sqlite/src/index.ts @@ -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 { diff --git a/packages/session-persistence/session-persistence/src/coordinator.ts b/packages/session-persistence/session-persistence/src/coordinator.ts index ace8125ce2..7c7b044ee1 100644 --- a/packages/session-persistence/session-persistence/src/coordinator.ts +++ b/packages/session-persistence/session-persistence/src/coordinator.ts @@ -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 diff --git a/packages/session-persistence/session-persistence/src/index.ts b/packages/session-persistence/session-persistence/src/index.ts index 239feb2825..a9ffd11792 100644 --- a/packages/session-persistence/session-persistence/src/index.ts +++ b/packages/session-persistence/session-persistence/src/index.ts @@ -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 { diff --git a/packages/ui/acp/src/index.ts b/packages/ui/acp/src/index.ts index 159fcb8044..ec79e97443 100644 --- a/packages/ui/acp/src/index.ts +++ b/packages/ui/acp/src/index.ts @@ -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: diff --git a/scripts/verify-node-next-types.ts b/scripts/verify-node-next-types.ts new file mode 100644 index 0000000000..0f2e392666 --- /dev/null +++ b/scripts/verify-node-next-types.ts @@ -0,0 +1,160 @@ +/** + * Verify that built package declarations are consumable by a standard external + * TypeScript ESM project using NodeNext resolution. + * + * Run after `pnpm run build` has emitted declaration files under package + * `lib/types` directories. + */ + +import { execFileSync } from 'node:child_process' +import { existsSync, globSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs' +import { dirname, resolve } from 'node:path' + +const root = resolve(import.meta.dirname, '..') + +interface ExportTarget { + types?: string +} + +interface PackageManifest { + name?: string + types?: string + exports?: Record +} + +interface WorkspacePackage { + dir: string + name: string + manifest: PackageManifest +} + +function readPackage(path: string): WorkspacePackage | null { + const manifest = JSON.parse(readFileSync(path, 'utf8')) as PackageManifest + if (!manifest.name) return null + return { dir: dirname(path), name: manifest.name, manifest } +} + +function workspacePackages(): WorkspacePackage[] { + return [ + ...globSync('vendor/*/package.json', { cwd: root }), + ...globSync('packages/*/*/package.json', { cwd: root }), + ] + .map(path => readPackage(resolve(root, path))) + .filter(pkg => pkg !== null) + .sort((a, b) => a.name.localeCompare(b.name)) +} + +const declarationSpecifierPattern = /(?:from\s*|import\s*\(\s*|import\s+|declare\s+module\s*)["'](\.{0,2}(?:\/[^"']*)?)["']/g +const hasExtension = /\.[^/.]+$/ + +function extensionlessRelativeSpecifiers(): string[] { + const errors: string[] = [] + const files = [ + ...globSync('vendor/*/lib/types/**/*.d.ts', { cwd: root }), + ...globSync('packages/*/*/lib/types/**/*.d.ts', { cwd: root }), + ].sort() + + for (const file of files) { + const text = readFileSync(resolve(root, file), 'utf8') + for (const match of text.matchAll(declarationSpecifierPattern)) { + const specifier = match[1] + if (!specifier) continue + const isRelative = specifier === '.' || specifier.startsWith('./') || specifier.startsWith('../') + if (isRelative && !hasExtension.test(specifier)) errors.push(`${file}: ${specifier}`) + } + } + + return errors +} + +function publicSpecifiers(pkg: WorkspacePackage): string[] { + const specifiers = new Set() + if (pkg.manifest.types) specifiers.add(pkg.name) + + for (const [key, target] of Object.entries(pkg.manifest.exports ?? {})) { + if (key.includes('*') || key === './package.json') continue + if (typeof target !== 'object' || target === null || !target.types) continue + specifiers.add(key === '.' ? pkg.name : `${pkg.name}/${key.slice(2)}`) + } + + return [...specifiers].sort() +} + +function linkPackage(pkg: WorkspacePackage, nodeModules: string): void { + const parts = pkg.name.split('/') + const link = resolve(nodeModules, ...parts) + mkdirSync(dirname(link), { recursive: true }) + symlinkSync(pkg.dir, link, 'dir') +} + +const packages = workspacePackages() +const badSpecifiers = extensionlessRelativeSpecifiers() +if (badSpecifiers.length > 0) { + console.error('verify-node-next-types: declaration files still contain extensionless relative specifiers.') + console.error(badSpecifiers.join('\n')) + process.exit(1) +} + +const missingOutputs = packages + .filter(pkg => pkg.manifest.types && !existsSync(resolve(pkg.dir, pkg.manifest.types))) + .map(pkg => `${pkg.name}: missing ${pkg.manifest.types}`) + +if (missingOutputs.length > 0) { + console.error('verify-node-next-types: build outputs are missing; run `pnpm run build` first.') + console.error(missingOutputs.join('\n')) + process.exit(1) +} + +const tmp = mkdtempSync(resolve(root, '.node-next-types-')) +let failed = false + +try { + const nodeModules = resolve(tmp, 'node_modules') + mkdirSync(nodeModules, { recursive: true }) + for (const pkg of packages) linkPackage(pkg, nodeModules) + + const rootTypes = resolve(root, 'node_modules/@types/node') + if (existsSync(rootTypes)) { + const typesDir = resolve(nodeModules, '@types') + mkdirSync(typesDir, { recursive: true }) + symlinkSync(rootTypes, resolve(typesDir, 'node'), 'dir') + } + + writeFileSync(resolve(tmp, 'package.json'), `${JSON.stringify({ type: 'module', private: true }, null, 2)}\n`) + writeFileSync(resolve(tmp, 'tsconfig.json'), `${JSON.stringify({ + compilerOptions: { + target: 'es2024', + module: 'NodeNext', + moduleResolution: 'NodeNext', + strict: true, + // Third-party SDK declarations can have their own lib-check noise under a + // symlinked temp install. The explicit scan above owns our regression: + // extensionless relative specifiers in built declarations. + skipLibCheck: true, + preserveSymlinks: true, + noEmit: true, + types: ['node'], + }, + include: ['index.ts'], + }, null, 2)}\n`) + + const imports = packages.flatMap(publicSpecifiers) + .map((specifier, index) => `import * as mod${index} from ${JSON.stringify(specifier)};\nvoid mod${index};`) + .join('\n') + writeFileSync(resolve(tmp, 'index.ts'), `${imports}\n`) + + execFileSync(resolve(root, 'node_modules/.bin/tsc'), ['-p', resolve(tmp, 'tsconfig.json'), '--pretty', 'false'], { + cwd: root, + stdio: 'pipe', + }) + console.log(`verify-node-next-types: ${packages.length} workspace package declaration surface(s) compile under NodeNext.`) +} catch (error: unknown) { + failed = true + const output = error as { stdout?: Buffer; stderr?: Buffer } + console.error('verify-node-next-types: NodeNext consumer typecheck failed.\n') + console.error(`${output.stdout?.toString() ?? ''}${output.stderr?.toString() ?? ''}`) +} finally { + rmSync(tmp, { recursive: true, force: true }) +} + +if (failed) process.exit(1) diff --git a/tsconfig.base.json b/tsconfig.base.json index f84c424b6d..3d6d1fc42a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -10,6 +10,8 @@ "incremental": true, "skipLibCheck": true, "esModuleInterop": true, + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, "verbatimModuleSyntax": false, "strict": true, "noUncheckedIndexedAccess": true, diff --git a/vendor/README.md b/vendor/README.md index dd55a9cd05..bf0f0b5a8c 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -33,7 +33,7 @@ Keep this log exhaustive — every divergence from upstream must be listed. 1. **`hmr/src/index.ts`**: removed the `./locales/en-US.yml` / `./locales/zh-CN.yml` imports, the `.i18n({...})` call on the `Config` schema, and the `src/locales/` directory. Rationale: those imports require a runtime YAML loader hook (`@cordisjs/unyaml`) that we do not vendor; the i18n texts only localize config descriptions. 2. **All `package.json` files**: regenerated — added `private: true`, added precise `files` entries for bundled runtime files and `lib/types/**/*.d.ts` / `.d.ts.map`, preserved `src` in `files` only for packages whose previous file list already shipped it, added a `./src/*` export where missing, pointed declaration metadata at `lib/types`, and removed upstream `devDependencies`/`scripts`/`repository` fields. Dependency and peer-dependency ranges preserved, except `hmr` declares `esbuild` as a direct dev dependency because its source imports the `BuildFailure` type and pnpm's strict workspace resolution requires the owner package to name that dependency. 3. **All `tsconfig.json` files**: regenerated to extend the repo-root `tsconfig.base.json`, emit TypeScript intermediates to `lib/types`, and declare project references. -4. **Vendored TypeScript source internal specifiers**: changed local relative imports/exports from explicit `.ts` / `.js` specifiers to extensionless specifiers so generated `.js` and `.d.ts` intermediates are extensionless and no declaration postprocess is needed. This includes `loader/src/config/isolate.ts` changing `declare module './entry.ts'` to `declare module './entry'`. +4. **Vendored TypeScript source internal specifiers**: changed local relative imports/exports from upstream's specifier shape to explicit `.ts` specifiers so TypeScript rewrites emitted JS to `.js` while declarations keep explicit, NodeNext-safe `.ts` specifiers. This includes `loader/src/config/isolate.ts` using `declare module './entry.ts'`. 5. **`schemastery/tsdown.config.ts` and `logger-console/tsdown.config.ts`**: ours, not upstream files — per-package build-shape overrides (dual ESM+CJS output; separate node/browser entries) for the repo-root tsdown build. They read the JS emitted under `lib/types` and then write the publish runtime entries under `lib/`. Like the regenerated tsconfigs, they are not part of the upstream sync surface. ## Sync procedure diff --git a/vendor/cordis/src/context.ts b/vendor/cordis/src/context.ts index 768ba52d6f..8b21c464b2 100644 --- a/vendor/cordis/src/context.ts +++ b/vendor/cordis/src/context.ts @@ -1,10 +1,10 @@ import { Dict } from 'cosmokit' -import { EventsService } from './events' -import { LoggerService } from './logger' -import { ReflectService } from './reflect' -import { InjectKey, RegistryService } from './registry' -import { getTraceable, symbols } from './utils' -import { Fiber } from './fiber' +import { EventsService } from './events.ts' +import { LoggerService } from './logger.ts' +import { ReflectService } from './reflect.ts' +import { InjectKey, RegistryService } from './registry.ts' +import { getTraceable, symbols } from './utils.ts' +import { Fiber } from './fiber.ts' /** * Public shape of a Cordis context. diff --git a/vendor/cordis/src/events.ts b/vendor/cordis/src/events.ts index f7dcf011f4..4461816537 100644 --- a/vendor/cordis/src/events.ts +++ b/vendor/cordis/src/events.ts @@ -1,7 +1,7 @@ import { defineProperty, Promisify } from 'cosmokit' -import { Context } from './context' -import { Fiber, FiberState } from './fiber' -import { DisposableList, symbols } from './utils' +import { Context } from './context.ts' +import { Fiber, FiberState } from './fiber.ts' +import { DisposableList, symbols } from './utils.ts' /** Return whether an event result should stop a bail-style dispatch. */ export function isBailed(value: any) { @@ -25,7 +25,7 @@ export type ThisType = F extends (this: infer T, ...args: any) => any ? T : n */ export type DispatchMode = 'emit' | 'parallel' | 'serial' | 'bail' | 'waterfall' -declare module './context' { +declare module './context.ts' { export interface Context { /* eslint-disable max-len */ parallel(name: K, ...args: Parameters): Promise diff --git a/vendor/cordis/src/fiber.ts b/vendor/cordis/src/fiber.ts index 840bc54352..fd472e7733 100644 --- a/vendor/cordis/src/fiber.ts +++ b/vendor/cordis/src/fiber.ts @@ -1,11 +1,11 @@ import { Awaitable, defineProperty, Dict, isNullable } from 'cosmokit' -import { Context } from './context' -import { Plugin } from './registry' -import { buildOuterStack, composeError, DisposableList, getTraceable, isConstructor, isObject, symbols } from './utils' -import { Impl } from './reflect' +import { Context } from './context.ts' +import { Plugin } from './registry.ts' +import { buildOuterStack, composeError, DisposableList, getTraceable, isConstructor, isObject, symbols } from './utils.ts' +import { Impl } from './reflect.ts' import { StandardSchemaV1 } from '@standard-schema/spec' -declare module './context' { +declare module './context.ts' { export interface Context extends Pick { fiber: Fiber } diff --git a/vendor/cordis/src/index.ts b/vendor/cordis/src/index.ts index 83d160395e..d0814213e0 100644 --- a/vendor/cordis/src/index.ts +++ b/vendor/cordis/src/index.ts @@ -1,14 +1,14 @@ /** Core context type and root context implementation. */ -export * from './context' +export * from './context.ts' /** Event bus, dispatch modes, and event augmentation types. */ -export * from './events' +export * from './events.ts' /** Plugin fiber lifecycle, effects, and config validation helpers. */ -export * from './fiber' +export * from './fiber.ts' /** Logger facade, logger service, message, exporter, and formatting types. */ -export * from './logger' +export * from './logger.ts' /** Plugin registry, dependency injection, and plugin entrypoint types. */ -export * from './registry' +export * from './registry.ts' /** Base service class and service lifecycle symbols. */ -export * from './service' +export * from './service.ts' /** Shared internal helpers used by context, services, and plugin fibers. */ -export * from './utils' +export * from './utils.ts' diff --git a/vendor/cordis/src/logger.ts b/vendor/cordis/src/logger.ts index f76ac2cdb7..a1e97c165a 100644 --- a/vendor/cordis/src/logger.ts +++ b/vendor/cordis/src/logger.ts @@ -1,9 +1,9 @@ import { defineProperty, hyphenate } from 'cosmokit' -import { Context } from './context' -import { Fiber } from './fiber' -import { createCallable, joinPrototype, symbols, Tracker } from './utils' +import { Context } from './context.ts' +import { Fiber } from './fiber.ts' +import { createCallable, joinPrototype, symbols, Tracker } from './utils.ts' -declare module './context' { +declare module './context.ts' { interface Intercept { logger: LoggerService.Intercept } diff --git a/vendor/cordis/src/reflect.ts b/vendor/cordis/src/reflect.ts index 4bc9fb44db..212ec4e779 100644 --- a/vendor/cordis/src/reflect.ts +++ b/vendor/cordis/src/reflect.ts @@ -1,9 +1,9 @@ import { defineProperty, Dict, isNullable } from 'cosmokit' -import { Context } from './context' -import { getTraceable, symbols, withProps } from './utils' -import { Fiber, FiberState } from './fiber' +import { Context } from './context.ts' +import { getTraceable, symbols, withProps } from './utils.ts' +import { Fiber, FiberState } from './fiber.ts' -declare module './context' { +declare module './context.ts' { interface Context { get(name: K, strict?: boolean): undefined | this[K] get(name: string, strict?: boolean): any diff --git a/vendor/cordis/src/registry.ts b/vendor/cordis/src/registry.ts index fae7712df9..9dfa10a06b 100644 --- a/vendor/cordis/src/registry.ts +++ b/vendor/cordis/src/registry.ts @@ -1,8 +1,8 @@ import { defineProperty, Dict } from 'cosmokit' import { StandardSchemaV1 } from '@standard-schema/spec' -import { Context } from './context' -import { Fiber } from './fiber' -import { buildOuterStack, DisposableList, symbols, withProps } from './utils' +import { Context } from './context.ts' +import { Fiber } from './fiber.ts' +import { buildOuterStack, DisposableList, symbols, withProps } from './utils.ts' function isApplicable(object: Plugin) { return object && typeof object === 'object' && typeof object.apply === 'function' @@ -140,7 +140,7 @@ type GetPluginConfig

= ? S : GetPluginParameters

[0] -declare module './context' { +declare module './context.ts' { export interface Context { inject(deps: Inject, callback: Plugin.Function): Fiber & PromiseLike plugin

(plugin: P, ...args: Spread>): Fiber & PromiseLike diff --git a/vendor/cordis/src/service.ts b/vendor/cordis/src/service.ts index 4cc9f307f2..30895247c1 100644 --- a/vendor/cordis/src/service.ts +++ b/vendor/cordis/src/service.ts @@ -1,6 +1,6 @@ import { defineProperty } from 'cosmokit' -import { Context } from './context' -import { createCallable, joinPrototype, symbols, Tracker } from './utils' +import { Context } from './context.ts' +import { createCallable, joinPrototype, symbols, Tracker } from './utils.ts' /** * Base class for services that expose a named API on `ctx`. diff --git a/vendor/cordis/src/utils.ts b/vendor/cordis/src/utils.ts index 46dd962c6f..2fd499bd0c 100644 --- a/vendor/cordis/src/utils.ts +++ b/vendor/cordis/src/utils.ts @@ -1,5 +1,5 @@ import { defineProperty } from 'cosmokit' -import type { Context, Service } from '.' +import type { Context, Service } from './index.ts' /** Ordered collection of disposable values with O(1) deletion by value. */ export class DisposableList { diff --git a/vendor/cosmokit/src/array.ts b/vendor/cosmokit/src/array.ts index ccbc4b2752..18ed5e407f 100644 --- a/vendor/cosmokit/src/array.ts +++ b/vendor/cosmokit/src/array.ts @@ -1,4 +1,4 @@ -import { isNullable } from './misc' +import { isNullable } from './misc.ts' /** Return true when every item in `array2` is present in `array1`. */ export function contain(array1: readonly any[], array2: readonly any[]) { diff --git a/vendor/cosmokit/src/index.ts b/vendor/cosmokit/src/index.ts index 088e81c54f..9fe48de069 100644 --- a/vendor/cosmokit/src/index.ts +++ b/vendor/cosmokit/src/index.ts @@ -1,10 +1,10 @@ /** Array set and normalization helpers. */ -export * from './array' +export * from './array.ts' /** Runtime type, binary, clone, and equality helpers. */ -export * from './types' +export * from './types.ts' /** Shared utility types and object helpers. */ -export * from './misc' +export * from './misc.ts' /** String case, path, and property formatting helpers. */ -export * from './string' +export * from './string.ts' /** Time constants, parsing, and formatting helpers. */ -export * from './time' +export * from './time.ts' diff --git a/vendor/cosmokit/src/types.ts b/vendor/cosmokit/src/types.ts index b4d1e5bed8..499a46273a 100644 --- a/vendor/cosmokit/src/types.ts +++ b/vendor/cosmokit/src/types.ts @@ -1,4 +1,4 @@ -import { isNullable } from './misc' +import { isNullable } from './misc.ts' type GlobalConstructorNames = keyof { [K in keyof typeof globalThis as typeof globalThis[K] extends abstract new (...args: any) => any ? K : never]: K diff --git a/vendor/hmr/src/index.ts b/vendor/hmr/src/index.ts index 8948625db6..ada10cc934 100644 --- a/vendor/hmr/src/index.ts +++ b/vendor/hmr/src/index.ts @@ -4,7 +4,7 @@ import { ModuleJob, ModuleLoader, ResolveResult } from '@cordisjs/plugin-loader' import type { Include } from '@cordisjs/plugin-include' import { ChokidarOptions, FSWatcher, watch } from 'chokidar' import { relative, resolve } from 'node:path' -import { handleError } from './error' +import { handleError } from './error.ts' import type {} from '@cordisjs/plugin-timer' import { fileURLToPath, pathToFileURL } from 'node:url' import { createRequire } from 'node:module' diff --git a/vendor/loader/src/config/entry.ts b/vendor/loader/src/config/entry.ts index 8acba39548..c2959fe61e 100644 --- a/vendor/loader/src/config/entry.ts +++ b/vendor/loader/src/config/entry.ts @@ -1,9 +1,9 @@ import { Context, Fiber, Inject } from 'cordis' import { deepEqual, isNullable } from 'cosmokit' -import { Loader } from '../index' -import { EntryGroup } from './group' -import { EntryTree } from './tree' -import { evaluate, interpolate } from './utils' +import { Loader } from '../index.ts' +import { EntryGroup } from './group.ts' +import { EntryTree } from './tree.ts' +import { evaluate, interpolate } from './utils.ts' /** Serialized plugin entry options stored in loader config files. */ export interface EntryOptions { diff --git a/vendor/loader/src/config/group.ts b/vendor/loader/src/config/group.ts index 5966d87eb8..f6ce0fe306 100644 --- a/vendor/loader/src/config/group.ts +++ b/vendor/loader/src/config/group.ts @@ -1,6 +1,6 @@ import { Context, Service } from 'cordis' -import { Entry, EntryOptions } from './entry' -import { EntryTree } from './tree' +import { Entry, EntryOptions } from './entry.ts' +import { EntryTree } from './tree.ts' /** Runtime owner for a list of child loader entries. */ export class EntryGroup { diff --git a/vendor/loader/src/config/isolate.ts b/vendor/loader/src/config/isolate.ts index 4b2f1df894..a2e930c4fb 100644 --- a/vendor/loader/src/config/isolate.ts +++ b/vendor/loader/src/config/isolate.ts @@ -1,8 +1,8 @@ import { Context } from 'cordis' import { Dict } from 'cosmokit' -import { Entry } from './entry' +import { Entry } from './entry.ts' -declare module './entry' { +declare module './entry.ts' { interface EntryOptions { intercept?: Dict | null isolate?: Dict | null diff --git a/vendor/loader/src/config/tree.ts b/vendor/loader/src/config/tree.ts index 53f71220e1..6855884e11 100644 --- a/vendor/loader/src/config/tree.ts +++ b/vendor/loader/src/config/tree.ts @@ -1,7 +1,7 @@ import { composeError, Context } from 'cordis' import { Dict, isNonNullable } from 'cosmokit' -import { Entry, EntryOptions } from './entry' -import { EntryGroup } from './group' +import { Entry, EntryOptions } from './entry.ts' +import { EntryGroup } from './group.ts' /** Mutable tree of loader entries. Persistence is supplied by subclasses. */ export abstract class EntryTree { diff --git a/vendor/loader/src/index.ts b/vendor/loader/src/index.ts index 764f04f995..e18fc2ffa2 100644 --- a/vendor/loader/src/index.ts +++ b/vendor/loader/src/index.ts @@ -1,22 +1,22 @@ import { Context, Inject, Service } from 'cordis' import { defineProperty, Dict, isNullable } from 'cosmokit' -import { ModuleLoader } from './internal' -import { Entry, EntryOptions } from './config/entry' -import isolate from './config/isolate' -import { EntryTree } from './config/tree' +import { ModuleLoader } from './internal.ts' +import { Entry, EntryOptions } from './config/entry.ts' +import isolate from './config/isolate.ts' +import { EntryTree } from './config/tree.ts' /** Re-export entry node APIs. */ -export * from './config/entry' +export * from './config/entry.ts' /** Re-export nested entry group APIs. */ -export * from './config/group' +export * from './config/group.ts' /** Re-export service isolation helpers. */ -export * from './config/isolate' +export * from './config/isolate.ts' /** Re-export entry tree persistence APIs. */ -export * from './config/tree' +export * from './config/tree.ts' /** Re-export loader config expression helpers. */ -export * from './config/utils' +export * from './config/utils.ts' /** Re-export Node internal module loader compatibility types. */ -export * from './internal' +export * from './internal.ts' declare module 'cordis' { interface Events { diff --git a/vendor/logger-console/src/browser.ts b/vendor/logger-console/src/browser.ts index fb35366d14..b45a15e228 100644 --- a/vendor/logger-console/src/browser.ts +++ b/vendor/logger-console/src/browser.ts @@ -1,8 +1,8 @@ import { Message } from 'cordis' -import { ConsoleExporter as Base } from './shared' +import { ConsoleExporter as Base } from './shared.ts' /** Re-export shared console exporter config and base implementation. */ -export * from './shared' +export * from './shared.ts' /** Browser console exporter that dispatches to native console methods. */ export class ConsoleExporter extends Base { diff --git a/vendor/logger-console/src/index.ts b/vendor/logger-console/src/index.ts index 905287b1e8..d46ac6413f 100644 --- a/vendor/logger-console/src/index.ts +++ b/vendor/logger-console/src/index.ts @@ -1,10 +1,10 @@ import { Formatter } from 'cordis' import { inspect } from 'node:util' import supportsColor from 'supports-color' -import { ConsoleExporter as Base } from './shared' +import { ConsoleExporter as Base } from './shared.ts' /** Re-export shared console exporter config and base implementation. */ -export * from './shared' +export * from './shared.ts' const inspectFormatter: Formatter = (value, target) => { return inspect(value, { colors: !!target.colors, depth: Infinity, compact: true, breakLength: Infinity })