- plugin/ directory structure: hooks/, tools/, core/
- export default { id, name, register } entry format
- globalThis state management with lifecycle protection
- WeakSet dedup on before_prompt_build hook
- Tool uses inputSchema + execute (not parameters + handler)
- additionalProperties: false in config schema
- Core logic in plugin/core/ (no plugin-sdk dependency)
- Install/uninstall script (scripts/install.mjs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { getRouters } from "./router-loader.js";
|
|
import { getRule } from "./rule-store.js";
|
|
import type { RouterContext } from "./router-loader.js";
|
|
|
|
export interface InjectionResult {
|
|
appendSystemContext?: string;
|
|
}
|
|
|
|
export async function resolveInjection(
|
|
ctx: RouterContext,
|
|
log: { info(msg: string): void; warn(msg: string): void }
|
|
): Promise<InjectionResult> {
|
|
const routers = getRouters();
|
|
const segments: string[] = [];
|
|
|
|
for (const router of routers) {
|
|
try {
|
|
const key = await router.module.resolve(ctx);
|
|
if (!key) continue;
|
|
|
|
const promptFile = getRule(router.name, key);
|
|
if (!promptFile) continue;
|
|
|
|
try {
|
|
const content = readFileSync(promptFile, "utf8").trim();
|
|
if (content) {
|
|
segments.push(content);
|
|
log.info(`[prism-facet] injecting ${router.name}:${key} → ${promptFile}`);
|
|
}
|
|
} catch (err) {
|
|
log.warn(`[prism-facet] cannot read ${promptFile}: ${String(err)}`);
|
|
}
|
|
} catch (err) {
|
|
log.warn(`[prism-facet] router ${router.name} failed: ${String(err)}`);
|
|
}
|
|
}
|
|
|
|
if (segments.length === 0) return {};
|
|
return { appendSystemContext: segments.join("\n\n---\n\n") };
|
|
}
|