From 1628f5028350d2903443d49d80a9c089b14ddb18 Mon Sep 17 00:00:00 2001 From: Turtle Date: Wed, 22 Jul 2026 17:07:15 +0800 Subject: [PATCH] docs(cordis-tutorial): clarify ctx.plugin function form; add dsh badge to every chapter --- docs/cordis-tutorial/01-first-plugin.md | 2 ++ docs/cordis-tutorial/02-lifecycle-and-effects.md | 4 +++- docs/cordis-tutorial/03-services.md | 2 ++ docs/cordis-tutorial/04-events.md | 2 ++ docs/cordis-tutorial/05-config.md | 2 ++ docs/cordis-tutorial/06-composition-and-hmr.md | 2 ++ 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/cordis-tutorial/01-first-plugin.md b/docs/cordis-tutorial/01-first-plugin.md index 468683a71d..cd4f060b03 100644 --- a/docs/cordis-tutorial/01-first-plugin.md +++ b/docs/cordis-tutorial/01-first-plugin.md @@ -89,3 +89,5 @@ Run again: the process dies with your error. A plugin that fails to load is a lo One caveat worth knowing early: a config entry whose module cannot be **resolved** — a typo'd path or package name — is reported through the Cordis logger service instead of crashing the process, and at boot that report can be lost before a console exporter is watching. If a freshly added entry seems to do nothing, check the spelling first. Next: [Lifecycle and effects](02-lifecycle-and-effects.md) — what happens when a plugin unloads. + +[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-harness/deepseek-harness) diff --git a/docs/cordis-tutorial/02-lifecycle-and-effects.md b/docs/cordis-tutorial/02-lifecycle-and-effects.md index 9763c0e2e6..4f3534a0eb 100644 --- a/docs/cordis-tutorial/02-lifecycle-and-effects.md +++ b/docs/cordis-tutorial/02-lifecycle-and-effects.md @@ -54,7 +54,7 @@ disposed Three things to notice: -- `ctx.plugin(heartbeat)` mounts a plugin **from code** — the same operation the YAML loader performs for each config entry. It returns a **fiber**, the runtime handle for one loaded plugin instance. +- `ctx.plugin(heartbeat)` mounts a function **from code** as a plugin — the same operation the YAML loader performs for each config entry. A function plugin needs no `apply` method: Cordis calls the function directly and uses its name only for diagnostics. An `apply` method is required only for the object form, `ctx.plugin({ apply(ctx) { /* ... */ } })`. The call returns a **fiber**, the runtime handle for one loaded plugin instance. - The effect body runs during load; the disposer it returns runs during unload. You never call the disposer yourself for a plugin-lifetime resource. - `fiber.dispose()` resolves after all of the plugin's cleanup — including async disposers — has finished, and recursively unloads any child plugins it mounted. @@ -87,3 +87,5 @@ For a resource Cordis does not manage, acquire it inside `ctx.effect()` and retu One ordering caveat: disposers start in reverse registration order, but multiple **async** disposers run concurrently. If teardown steps must run in sequence, keep them in one disposer and await them there. Next: [Services](03-services.md) — how plugins share capabilities. + +[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-harness/deepseek-harness) diff --git a/docs/cordis-tutorial/03-services.md b/docs/cordis-tutorial/03-services.md index a3538d1a9e..4915b59d48 100644 --- a/docs/cordis-tutorial/03-services.md +++ b/docs/cordis-tutorial/03-services.md @@ -92,3 +92,5 @@ export function apply(ctx: Context) { Service names live in one flat namespace per application. Prefix or namespace your own services distinctively (the harness claims plain names like `tools` and `llm`); the generated [services catalog](../cordis-catalog/services.md) lists every name the harness registers. Next: [Events](04-events.md) — communication without a shared service. + +[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-harness/deepseek-harness) diff --git a/docs/cordis-tutorial/04-events.md b/docs/cordis-tutorial/04-events.md index 5646d86a0c..fbc8eae441 100644 --- a/docs/cordis-tutorial/04-events.md +++ b/docs/cordis-tutorial/04-events.md @@ -138,3 +138,5 @@ The discipline that follows: **a waterfall listener that only observes or annota The harness uses waterfalls for decisions that cooperating plugins may wrap or answer: [`agent/request`](../cordis-catalog/events.md#agentrequest--waterfall) lets a plugin replace the model-call config, and [`approval/request`](../cordis-catalog/events.md#approvalrequest--waterfall) lets a policy answer instead of the user. Next: [Configuration](05-config.md) — plugin options from `cordis.yml`. + +[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-harness/deepseek-harness) diff --git a/docs/cordis-tutorial/05-config.md b/docs/cordis-tutorial/05-config.md index 60ee2f719d..3716c2d5e5 100644 --- a/docs/cordis-tutorial/05-config.md +++ b/docs/cordis-tutorial/05-config.md @@ -82,3 +82,5 @@ The loader used in this repo supports a `!!js` tag for config values that must b `!!js` works **only inside `config`**. Entry metadata (`name`, `id`, `disabled`, `inject`, ...) is static; `disabled: !!js ...` produces a truthy expression object that always disables the entry. See [loader configuration](../cordis-primer.md#loader-configuration). Next: [Composition and HMR](06-composition-and-hmr.md) — treating `cordis.yml` as the application. + +[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-harness/deepseek-harness) diff --git a/docs/cordis-tutorial/06-composition-and-hmr.md b/docs/cordis-tutorial/06-composition-and-hmr.md index 8e7be022c3..dd5020db0a 100644 --- a/docs/cordis-tutorial/06-composition-and-hmr.md +++ b/docs/cordis-tutorial/06-composition-and-hmr.md @@ -103,3 +103,5 @@ needs-timer is PENDING — a required service is missing `inject: ['timer']` has no provider. Add `- name: '@cordisjs/plugin-timer'` to the list and the plugin loads. When a plugin does nothing and reports nothing, inspect its fiber state. Iterating without the PENDING filter also shows the loader's own plugins (Loader, Include) as ACTIVE fibers because plugins mount the config file itself. Next: [Into the harness](07-into-the-harness.md) — the same patterns against real harness services. + +[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-harness/deepseek-harness)