Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, `verify-translation-pairing --write` for the touched bilingual pairs, `gen-doc-graphs`, and one typert snapshot whose ids embed character offsets. `pnpm run rescope-vendor --check` verifies the result. Renames nine vendored packages (cordis, cosmokit, schemastery and the six @cordisjs plugins) and every reference that resolves them: manifest names and dependency keys, module specifiers including declare-module merges, cordis.yml plugin names, tsconfig paths, every Markdown fence, and `docs/` prose. Directory names, upstream versions, and dependency ranges are unchanged, so vendor/README.md still reads as an upstream snapshot; its manifest table gains an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed at each fork's origin. The tutorial tier follows the rename end to end: its yaml fences named plugins the Loader can no longer resolve, its `ts ignore-check` fences disagreed with the compiled fences beside them, and its prose quoted both. The contracts that told readers to keep upstream names — the root convention and the vendoring cookbook's tree comment and manifest invariant — now say to rescope instead. Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle purity gate now names the vendored libraries a browser bundle inlines, and the files where a bare `cordis` is an agent-preset id keep that product data.
59 lines
4.0 KiB
Markdown
59 lines
4.0 KiB
Markdown
# Cordis tutorial
|
|
|
|
English | [中文](index.zh.md)
|
|
|
|
Cordis is the plugin framework underneath the DeepSeek Harness SDK: a small runtime where every capability — tools, LLM adapters, file access, the agent loop itself — is a plugin mounted into a shared context. This tutorial teaches Cordis hands-on: each chapter is a runnable example you build in a scratch directory inside this repository, ending with a plugin wired into real harness services.
|
|
|
|
The audience is agent developers. You do not need deep TypeScript experience; the [TypeScript notes](#typescript-notes) below explain the syntax that may be unfamiliar, and every chapter shows the exact commands and expected output.
|
|
|
|
If you want the condensed concept reference instead of a walkthrough, read the [Cordis primer](../cordis-primer.md). The exhaustive API reference lives in the generated `cordis-surface` regions on the [subsystem pages](../subsystems/core.md) and the [Cordis core API](../cordis-api/context.md) pages.
|
|
|
|
## Setup
|
|
|
|
You need a clone of this repository with dependencies installed — the [quick start](../user/guide/quickstart.md) covers prerequisites. No API key is needed for this tutorial; every example runs keylessly.
|
|
|
|
```sh
|
|
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
|
|
cd deepseek-harness
|
|
pnpm install
|
|
```
|
|
|
|
Create the scratch directory the chapters work in. `tmp/` is gitignored, so nothing you write there touches version control:
|
|
|
|
```sh
|
|
mkdir -p tmp/cordis-tutorial
|
|
cd tmp/cordis-tutorial
|
|
```
|
|
|
|
Every chapter runs the same command from this directory:
|
|
|
|
```sh
|
|
node --import tsx ../../vendor/cordis/bin.js
|
|
```
|
|
|
|
That one-file launcher (see [vendor/cordis/bin.js](../../vendor/cordis/bin.js)) creates a root `Context`, mounts the Loader plugin, and tells it to load `./cordis.yml` from the current directory. Everything else — which plugins exist, how they are configured — comes from that YAML file, which you will write in a moment. The `--import tsx` flag lets Node run the TypeScript files the config points at without a build step.
|
|
|
|
## Chapters
|
|
|
|
1. [Your first plugin](01-first-plugin.md) — a plugin is a function; the loader mounts it.
|
|
2. [Lifecycle and effects](02-lifecycle-and-effects.md) — Cordis-managed registrations are undone when their plugin unloads.
|
|
3. [Services](03-services.md) — expose a capability on `ctx` and depend on it with `inject`.
|
|
4. [Events](04-events.md) — typed events, broadcast dispatch, and the waterfall short-circuit.
|
|
5. [Configuration](05-config.md) — validated config from `cordis.yml`, failing loud on bad input.
|
|
6. [Composition and HMR](06-composition-and-hmr.md) — the config file as a plugin tree, hot reload, and diagnosing a plugin that never loads.
|
|
7. [Into the harness](07-into-the-harness.md) — register a model-callable tool against real harness services.
|
|
|
|
<a id="typescript-notes"></a>
|
|
|
|
## TypeScript notes
|
|
|
|
The examples use three TypeScript features beyond ordinary modern JavaScript:
|
|
|
|
- **Type annotations** describe values without changing runtime behavior: `ctx: Context` says that `ctx` has the Cordis context API, `who: string` accepts text, and `string[]` means an array of strings.
|
|
- **`import type { Context } from '@deepseek-ai/cordis'`** imports only type information. It vanishes at runtime, so a plugin file that needs `Context` solely for annotations adds no runtime dependency.
|
|
- **Declaration merging** (`declare module '@deepseek-ai/cordis' { ... }`) adds your entries to interfaces that Cordis already declares — for example the type of a new `ctx.greeter` property or event name. It generates no runtime wiring; the plugin separately provides the service or emits the event. Chapter 3 shows the pattern in full.
|
|
|
|
Chapter 5 also uses an `interface` to describe a configuration object's fields and a generic type such as `Schema<Config>` to say which object fields a schema validates. You can copy those declarations as shown; the surrounding text explains what each one connects.
|
|
|
|
[](https://github.com/deepseek-ai/deepseek-harness-sdk)
|