Files
deepseek-harness/docs/rescope.md
T
imccyu 194828e8b8 build(vendor): add the @deepseek-ai rescope codemod, its mapping doc, and its Agent Note
Every harness package declares cordis as a peer dependency, so publishing the
harness publishes the vendored framework layer too; under the upstream names
that publication would squat them on the registry.

scripts/rescope-vendor.ts owns the rename: the nine-package mapping, a
delimited-token rule that leaves cordis.yml, the Loader's cordis: builtins and
vendor directory names alone, per-file exemptions where a name is a directory
or an upstream runtime identifier, and the exact edits for sites a token rule
cannot express — dot-notation lookups, unquoted manifest keys, a regex literal
whose failure would make every Context-merge scan silently find nothing, the
vendored-manifest table, and the contracts that told readers vendored packages
keep their upstream names.

Markdown follows the rename inside every fence, because a fence is code a
reader copies or configuration they mount, and in `docs/` prose as well, where
a sentence quoting a name teaches something this repository no longer resolves.
Prose elsewhere records what was true when it was written, and the same
spelling can mean something else: the Python SDK's `cordis` option, or the
unvendored `@cordisjs/plugin-http`. `docs/rescope.md` states both names on
purpose and is exempt.

exactEditState() classifies every exact edit as pending, applied, or invalid.
An insertion keeps its anchor and a deletion keeps its remainder, so each side
counts the form that survives: a duplicated insertion, a half-applied
replacement, and a deletion whose remainder moved are all invalid. The run
classifies every edit before writing anything and aborts on the first invalid
one, so a disagreement between the mapping and the tree cannot leave a
half-rescoped checkout; each write re-reads its file, because two edits can
target one. rescope-vendor.spec.ts pins those rejections, and --check asserts
the whole post-state from the hygiene gate, so CI owns the invariant.

--reverse restores the upstream names, verified as a round trip: reverse, then
apply, reproduces this tree byte for byte.

docs/rescope.md is the consumer-facing reference: the old-name/new-name table
with each package's role, what the rename deliberately leaves alone, the sites
callers must change, and the commands to apply, verify, and revert. The Agent
Note carries the decision and its consequences.

The rename itself lands in the next commit, produced by running the script.
2026-08-10 22:04:10 +08:00

4.5 KiB

Vendored package rescope

English | 中文

The Cordis framework and its foundation libraries are vendored under vendor/ and published under the @deepseek-ai scope, because every harness package declares the framework as a peer dependency: publishing the harness publishes this layer with it, and under the upstream names that publication would squat them on the registry. This page is the name mapping; the decision and its consequences live in the rescope Agent Note, and the upstream commits in vendor/README.md.

Name mapping

Directory Upstream name Published name Version Role
vendor/cordis/ cordis @deepseek-ai/cordis 4.0.0-rc.7 Framework core: Context, Service, Fiber, events
vendor/cosmokit/ cosmokit @deepseek-ai/cosmokit 1.8.1 Shared utilities the framework and Schemastery build on
vendor/schemastery/ schemastery @deepseek-ai/schemastery 3.18.0 Config schemas (Schema) behind every plugin's Config
vendor/loader/ @cordisjs/plugin-loader @deepseek-ai/cordis-plugin-loader 1.0.0-rc.5 cordis.yml loading, plugin resolution, repository cache
vendor/include/ @cordisjs/plugin-include @deepseek-ai/cordis-plugin-include 1.0.4 Config includes and patch overlays
vendor/group/ @cordisjs/plugin-group @deepseek-ai/cordis-plugin-group 1.0.0 Nested plugin groups
vendor/timer/ @cordisjs/plugin-timer @deepseek-ai/cordis-plugin-timer 1.1.2 Disposal-aware timers on ctx
vendor/hmr/ @cordisjs/plugin-hmr @deepseek-ai/cordis-plugin-hmr 1.0.15 Hot module replacement for plugins and config
vendor/logger-console/ @cordisjs/plugin-logger-console @deepseek-ai/cordis-plugin-logger-console 1.0.0 Console logger exporter

Subpath exports keep their path: @cordisjs/plugin-loader/repository becomes @deepseek-ai/cordis-plugin-loader/repository.

What the rename does not touch

  • Directory names and versions. vendor/hmr/ stays vendor/hmr/, and every package keeps the upstream version its manifest table row records, so the vendored tree still reads as an upstream snapshot.
  • Dependency ranges. A dependency entry changes its key, never its range: "cordis": "^4.0.0-rc.7" becomes "@deepseek-ai/cordis": "^4.0.0-rc.7". linkWorkspacePackages resolves those preserved ranges to the pinned workspaces.
  • The Loader's cordis: builtin prefix. cordis:include and cordis:group are a protocol prefix, not a package name.
  • The cordis.yml configuration family, including *.cordis.yml, *.cordis.snapshot.yml, and cordis.patch.yml.
  • Harness packages whose own names contain the word, such as @deepseek-ai/dsh-tool-cordis.
  • Upstream runtime identifiers, such as Schemastery's Symbol.for('schemastery') and its vendor: metadata field.
  • Prose outside docs/. vendor/*/README.md, package READMEs, and Agent Notes keep the names they were written with; a bare cordis there can also be the Python SDK's option name or an agent-preset id. Inside docs/, prose and every Markdown fence follow the rename.

What your code has to change

Site Before After
Module import import { Context } from 'cordis' import { Context } from '@deepseek-ai/cordis'
Typed-event merge declare module 'cordis' declare module '@deepseek-ai/cordis'
package.json dependency key "@cordisjs/plugin-hmr": "^1.0.15" "@deepseek-ai/cordis-plugin-hmr": "^1.0.15"
cordis.yml plugin entry name: '@cordisjs/plugin-include' name: '@deepseek-ai/cordis-plugin-include'

Applying, verifying, and reverting

scripts/rescope-vendor.ts owns the mapping above and performs the rename, so no reference is renamed by hand:

pnpm run rescope-vendor            # report what would change
pnpm run rescope-vendor --apply    # rewrite every reference
pnpm run rescope-vendor:check      # assert the post-state; runs in the hygiene gate
pnpm run rescope-vendor --apply --reverse   # return to the upstream names

Re-apply it after an upstream sync (procedure), and follow it with the regeneration it prints: pnpm install for the lockfile, pnpm run gen-third-party-notices, and pnpm run verify-translation-pairing --write for the bilingual pairs it touched.