Skip to content

中文版

Generated reference snapshot

Original Cubic page · captured 2026-09-23 · source commit. This AI-generated page has not been verified against the current code. Use the Zhin documentation for current behavior and see known corrections.

Known correction

Code capabilities use named directories with fixed index.ts entries: commands/**/index.ts and one-level handlers/<name>/index.ts. The file-style examples in the snapshot are not discovered. See Convention Directories.

Relevant source files

The following files were used as context for generating this wiki page:

Plugin Runtime & Conventions

The Zhin.js Plugin Runtime is the execution environment and structural standard for extending the framework. It enforces a "convention over configuration" approach where capabilities are discovered via specific directory structures rather than imperative registration. The sole entry path for the application is zhin runtime start, which assembles the IM core, agents, and console hosts based on these conventions.

Sources: CLAUDE.md:77-80, AGENTS.md:61-66

Core Architecture

The runtime operates on a Generation-based system for Hot Module Replacement (HMR). A "Generation" represents a stable snapshot of the plugin tree; when code changes occur, the runtime prepares a new generation off-path and publishes it atomically. If a candidate generation fails validation, the active generation continues to serve traffic.

The HMR process atomically replaces artifacts like Pages and Layouts without restarting the entire system unless required. Sources: README.md:126-130, packages/im/runtime/tests/console-feature-hmr.test.ts:31-60

Plugin Manifest and Entry

Every plugin must be a valid NPM package containing a zhin manifest in its package.json. The plugin.ts file serves as the assembly point and must default-export a definePlugin() definition.

Manifest Configuration (package.json)

FieldDescriptionRequirement
zhin.protocolVersion of the plugin protocol (currently 1)Required
zhin.typeThe type of package (plugin or feature)Required
zhin.entryPath to the entry file (usually ./plugin.ts)Required
zhin.featuresList of Feature dependencies required by the pluginOptional
zhin.pluginsList of child plugin or adapter instancesOptional

Sources: basic/cli/src/commands/new.ts:246-254, packages/toolkit/create-zhin/src/workspace.ts:109-122

Entry Point Definition (plugin.ts)

The definePlugin function initializes the plugin scope. It provides access to the context, which includes configuration, resources (Dependency Injection), and the lifecycle manager.

typescript
import { definePlugin } from 'zhin.js';

export default definePlugin({
  name: 'my-plugin',
  metadata: { displayName: 'My Plugin' },
  setup(context) {
    // Provide resources
    context.resources.provide(myToken, value);
    // Register cleanup
    context.lifecycle.add(() => cleanup());
  },
});

Sources: CLAUDE.md:82-93, basic/cli/src/commands/new.ts:333-352

Convention Directories

Capabilities are automatically discovered if placed in the correct directories within the plugin package. Each file in these directories should define exactly one capability and use a default export.

DirectoryAuthoring APIDescription
commands/defineCommand()Chat commands. Paths define the route (e.g., commands/greet.ts -> /greet).
middlewares/defineMiddleware()Request/Message processing pipeline components.
tools/defineAgentTool()AI capabilities used by Agents.
components/defineComponent()UI or message rendering components (e.g., Satori cards).
pages/definePage()Remote Console pages and layouts (nav/index.tsx, footer/index.tsx).
handlers/defineHandler()Event handlers (e.g., handlers/message/receive.ts).
skills/Markdown (SKILL.md)AI agent workflow and trigger descriptions.

Sources: CLAUDE.md:95-108, packages/toolkit/create-zhin/template/skills/plugin-develop/SKILL.md:16-25

Command Routing Patterns

Command directories support Next.js-style dynamic segments for parameter parsing:

  • commands/[name]/index.ts: Defines a required parameter name.
  • commands/[[name]]/index.ts: Defines an optional parameter name.
  • commands/[...name]/index.ts: Catch-all parameter (returns an array).

Sources: packages/toolkit/create-zhin/template/skills/plugin-develop/SKILL.md:33-36, basic/cli/src/commands/new.ts:400-415

Dependency and Send Chain Governance

The runtime enforces strict boundaries to ensure stability and security.

Dependency Layers

Lower layers must never import from higher layers. The hierarchy is: basickernelaicoreagentzhin. The basic/cli package is the only exception as the composition root. Sources: CLAUDE.md:46-56, AGENTS.md:78-83

Outbound Send Chain

Plugins must not bypass the standard send chain. All messages must flow through Message.$reply or Adapter.sendMessage. Direct calls to platform bots or bot.$sendMessage are prohibited and flagged by harness checks.

Sources: CLAUDE.md:67-70, AGENTS.md:143-145

Development Standards

  1. ESM Only: The runtime requires "type": "module" and target Node.js ≥20.19.0.
  2. Import Extensions: All local TypeScript imports must include the .js extension (e.g., import { foo } from './bar.js').
  3. Legacy API Prohibition: APIs such as usePlugin(), getPlugin(), and bootstrapNode have been removed. Using them will cause the PluginScopeAssembler to throw errors.
  4. Resource Handling: Shared resources (databases, connections) must be managed via context.resources.provide and context.resources.use rather than module-level singletons.

Sources: CLAUDE.md:27-29, CLAUDE.md:110-113, packages/toolkit/create-zhin/template/skills/plugin-quality/SKILL.md:52-54