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
|
* Entry point. Registers `/pygienium-help`, auto-registers one
|
||||||
* `/pygienium-<check>` command per registered `CheckDefinition`, plus the
|
* `/pygienium-<check>` command per registered `CheckDefinition`, plus the
|
||||||
* `all`/`resume`/`status`/`export` commands. Adding a check requires ONLY a new
|
* `all`/`resume`/`status`/`export` commands. Adding a check requires a new
|
||||||
* file in `src/checks/` plus one `registerCheck(def)` call — no changes here.
|
* 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
|
* Check modules self-register on import (top-level `registerCheck`); the
|
||||||
* registry barrel), so they self-register at load time before commands bind.
|
* 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).
|
* 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
|
* The default export runs once per session; the factory is async so check
|
||||||
@@ -16,10 +20,9 @@
|
|||||||
* @module pygienium/index
|
* @module pygienium/index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { readdir, readFile } from "node:fs/promises";
|
import { readFile } from "node:fs/promises";
|
||||||
import { dirname, join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
import type {
|
import type {
|
||||||
ExtensionAPI,
|
ExtensionAPI,
|
||||||
ExtensionCommandContext,
|
ExtensionCommandContext,
|
||||||
@@ -28,6 +31,7 @@ import type {
|
|||||||
SessionStartEvent,
|
SessionStartEvent,
|
||||||
} from "@earendil-works/pi-coding-agent";
|
} from "@earendil-works/pi-coding-agent";
|
||||||
import { Box, Text } from "@earendil-works/pi-tui";
|
import { Box, Text } from "@earendil-works/pi-tui";
|
||||||
|
import "./checks/all.js";
|
||||||
import { registerPygieniumCommands, type PygieniumCtx } from "./commands.js";
|
import { registerPygieniumCommands, type PygieniumCtx } from "./commands.js";
|
||||||
import {
|
import {
|
||||||
type SendChatMessage,
|
type SendChatMessage,
|
||||||
@@ -243,27 +247,6 @@ function makeStreamForwarder(pi: ExtensionAPI): StreamForwarder {
|
|||||||
return { onAgentEvent, sendPhaseLine };
|
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.
|
* 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(
|
export default async function pygieniumExtension(
|
||||||
pi: ExtensionAPI,
|
pi: ExtensionAPI,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Self-register every shipped check before wiring commands.
|
// Checks self-register on import (see ./checks/all.js), which runs before
|
||||||
await loadCheckModules();
|
// this factory — commands below bind against a fully populated registry.
|
||||||
|
|
||||||
const sendChatMessage = makeSendChatMessage(pi);
|
const sendChatMessage = makeSendChatMessage(pi);
|
||||||
|
|
||||||
// Register custom message renderer for pygienium progress messages.
|
// Register custom message renderer for pygienium progress messages.
|
||||||
|
|||||||
Reference in New Issue
Block a user