# Example Chi module

This is the smallest useful module shape. The module is a separate Pi
extension and does not create another Chi Base runtime.

~~~ts
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import type { ChiBase } from "@henkaku-center/chi-base/contract";
import { z } from "zod";

const config = z.object({
	mode: z.enum(["safe", "fast"]).default("safe"),
});

export default function exampleModule(pi: ExtensionAPI) {
	pi.events.on("chi:discover", (data) => {
		const chi = data as ChiBase;
		chi.register({
			id: "chi-example",
			version: "1.0.0",
			config: {
				schemaVersion: 1,
				schema: config,
			},
			api: {
				ping: () => "pong",
			},
			async initialize(chi, parsedConfig) {
				const optionalModule = chi.get<{ run(): Promise<void> }>("chi-optional");
				if (optionalModule) await optionalModule.run();
				if (parsedConfig.mode === "fast") {
					// Start fast-mode resources here.
				}
			},
		});
	});
}
~~~

The module package should pin the exact compatible @henkaku-center/chi-base version in
peerDependencies and, when TypeScript compilation needs it, devDependencies.
Zod is a runtime dependency of the module because its schema is constructed at
runtime.
