Cordis makes plugin registrations reversible
A Cordis context is a registry of services addressed by stable keys such as tools, model access, or sessions. Plugins ask for those services through declared injections rather than importing an implementation directly. If a required service is missing, activation waits. That turns boot order into a dependency relationship and lets a host add or remove a capability while the process stays alive.
The second idea is cleanup. Listeners, prompt fragments, provider adapters, timers, and other registrations can be installed as effects with matching disposers. When a plugin reloads or its context disappears, Cordis unwinds those registrations. The codebase is compact at about 8,440 lines in 111 files, yet it addresses a lifecycle problem that is easy to get wrong in a long-running agent or plugin host.
Four event modes make dispatch behavior explicit
Cordis documents four event modes. emit observes without waiting, parallel awaits listeners concurrently, and serial awaits them in registration order. waterfall behaves as around-middleware: a listener receives next, can delegate a changed value, or can stop the chain and own the result. The selected mode is part of an event's public contract.
That is more precise than one generic event emitter, but plugin authors have to choose correctly. A policy listener may intentionally short-circuit a waterfall; an observer that forgets next() can block everything downstream. Recent pull request #83 guarded waterfall continuation against double invocation, while pull request #81 addressed ordering for concurrent timer reads. The 49 open issues and pull requests on August 25 include real lifecycle edge cases, not only feature requests.
Services avoid concrete imports at the cost of indirection
A plugin claims a service key on its context, and consumers declare that key as an injected dependency. This makes implementations replaceable and allows a service to become available after startup. The linked primer recommends events for interception or policy and direct service methods for capability calls. That rule keeps cross-plugin behavior visible if a team follows it consistently.
Debugging can still become abstract. A missing capability may mean that no plugin registered it, its injection never activated, its fiber failed, or teardown removed it. Issue #95 reports a failed fiber re-entering reload during dependency refresh while retaining its error state. Cordis was pushed on August 21, 2026, and that issue was active on August 25, so maintenance is current even though the repository itself had no later push.
Loader and HMR target changing plugin graphs
The workspace includes core, loader, HMR, include, timer, logger, group, utility, and project-creation packages. Loader configuration can enable entries conditionally and interpolate configuration after declared injections activate. HMR then has to preserve the same dependency and disposal rules while code changes under a live process. This is where Cordis differs most from ordinary startup-only dependency injection.
The package READMEs barely explain those modules. packages/hmr/README.md and packages/loader/README.md contain little beyond their names. The useful explanation lives in the DeepSeek Harness primer and its English reference pages. That separation is a documentation cost for general adopters: the framework repository has 0 GitHub releases, and the best conceptual guide is framed around a downstream agent host.
What happened when we ran it
Our sandbox used npm to install 432 packages in 120 seconds at commit 8cc9e33. Dependencies occupied 145 MB, compared with a 0.3 MB checkout. npm audit found 0 known vulnerabilities across critical, high, moderate, and low severities. Installation completed, so the registry packages resolved in the fresh Node 22 container.
The build failed after 9 seconds. The root build script called yarn yakumo esbuild and yarn yakumo tsc, then Yarn 4.14.1 said @root/cordis@workspace:. did not appear in the lockfile. Its own message advised running yarn install to update that lockfile. No esbuild or TypeScript diagnostic appears because execution stopped during workspace resolution.
Tests failed after 10 seconds with the same lockfile message. The test script never produced a test count, assertion, or coverage result. On our box, mixing the npm install step with the project's Yarn command path created a state that Yarn rejected. The finding is narrower than a broken test suite, but it makes the correct package-manager workflow part of setup rather than an incidental preference.
The unstable API is a real adoption boundary
The main README has only 424 characters and explicitly warns that the API can change without notice. There is no latest GitHub release to anchor an upgrade policy. Recent work on unload registration, service callers, loader persistence, HMR, and event handling shows active development, while the lack of a release history makes compatibility harder to judge from tags.
Cordis deserves a prototype when a plugin host must react to services appearing and disappearing during its lifetime. Test failed activation, dependency refresh, repeated reload, partial teardown, and disposal order before trusting it. A fixed application graph does not need this machinery. NestJS is easier for conventional TypeScript services, and Fastify is more direct when the plugin surface is an HTTP server.

