register checks via static barrel instead of readdir + dynamic import
Checks keep self-registering on import; src/checks/all.ts imports every shipped check from the entry's static graph. Keeps the check graph fully statically resolvable (bundler/loader friendly) and removes the only dynamic-import discovery in the codebase.
This commit is contained in:
15
src/checks/all.ts
Normal file
15
src/checks/all.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Static barrel for shipped checks.
|
||||
*
|
||||
* Every check module self-registers on import (top-level `registerCheck`), so
|
||||
* importing all of them here — once, statically, from the entry graph —
|
||||
* registers every check before commands bind. Adding a check means dropping
|
||||
* the file in and adding one import line here.
|
||||
*/
|
||||
import "./comments.js";
|
||||
import "./complexity.js";
|
||||
import "./dead-code.js";
|
||||
import "./deep-modules.js";
|
||||
import "./defensive-guards.js";
|
||||
import "./scope.js";
|
||||
import "./todos.js";
|
||||
44
src/index.ts
44
src/index.ts
@@ -3,11 +3,15 @@
|
||||
*
|
||||
* Entry point. Registers `/pygienium-help`, auto-registers one
|
||||
* `/pygienium-<check>` command per registered `CheckDefinition`, plus the
|
||||
* `all`/`resume`/`status`/`export` commands. Adding a check requires ONLY a new
|
||||
* file in `src/checks/` plus one `registerCheck(def)` call — no changes here.
|
||||
* `all`/`resume`/`status`/`export` commands. Adding a check requires a new
|
||||
* file in `src/checks/` plus one import line in `src/checks/all.ts` — no
|
||||
* changes here.
|
||||
*
|
||||
* Check files in `src/checks/` are auto-discovered (every `.ts` except the
|
||||
* registry barrel), so they self-register at load time before commands bind.
|
||||
* Check modules self-register on import (top-level `registerCheck`); the
|
||||
* static barrel `src/checks/all.ts` imports every shipped check so they all
|
||||
* register before commands bind. A static import list (rather than readdir +
|
||||
* dynamic import) keeps the whole check graph resolvable up front, which
|
||||
* matters for bundlers and module-loaders that tag extension graphs.
|
||||
*
|
||||
* Pi loads this file via jiti at runtime (see `pi.extensions` in package.json).
|
||||
* The default export runs once per session; the factory is async so check
|
||||
@@ -16,10 +20,9 @@
|
||||
* @module pygienium/index
|
||||
*/
|
||||
|
||||
import { readdir, readFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { homedir } from "node:os";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import type {
|
||||
ExtensionAPI,
|
||||
ExtensionCommandContext,
|
||||
@@ -28,6 +31,7 @@ import type {
|
||||
SessionStartEvent,
|
||||
} from "@earendil-works/pi-coding-agent";
|
||||
import { Box, Text } from "@earendil-works/pi-tui";
|
||||
import "./checks/all.js";
|
||||
import { registerPygieniumCommands, type PygieniumCtx } from "./commands.js";
|
||||
import {
|
||||
type SendChatMessage,
|
||||
@@ -243,27 +247,6 @@ function makeStreamForwarder(pi: ExtensionAPI): StreamForwarder {
|
||||
return { onAgentEvent, sendPhaseLine };
|
||||
}
|
||||
|
||||
/**
|
||||
* Import every `checks/*.ts` module (except the registry barrel) so each check
|
||||
* file's top-level `registerCheck(def)` call runs before command binding. This
|
||||
* is what makes adding a check require zero index.ts changes — drop a file,
|
||||
* it self-registers.
|
||||
*/
|
||||
async function loadCheckModules(): Promise<void> {
|
||||
const dir = join(dirname(fileURLToPath(import.meta.url)), "checks");
|
||||
let entries: string[];
|
||||
try {
|
||||
entries = await readdir(dir);
|
||||
} catch {
|
||||
return; // no checks dir (e.g. minimal install)
|
||||
}
|
||||
for (const entry of entries) {
|
||||
if (!entry.endsWith(".ts")) continue;
|
||||
if (entry === "registry.ts" || entry === "load.ts") continue;
|
||||
await import(`./checks/${entry}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a callback to send completion messages to the main chat window.
|
||||
*/
|
||||
@@ -283,9 +266,8 @@ function makeSendChatMessage(pi: ExtensionAPI): SendChatMessage {
|
||||
export default async function pygieniumExtension(
|
||||
pi: ExtensionAPI,
|
||||
): Promise<void> {
|
||||
// Self-register every shipped check before wiring commands.
|
||||
await loadCheckModules();
|
||||
|
||||
// Checks self-register on import (see ./checks/all.js), which runs before
|
||||
// this factory — commands below bind against a fully populated registry.
|
||||
const sendChatMessage = makeSendChatMessage(pi);
|
||||
|
||||
// Register custom message renderer for pygienium progress messages.
|
||||
|
||||
Reference in New Issue
Block a user