import { filterBootstrapFilesForSession, loadExtraBootstrapFilesWithDiagnostics, } from "../../../agents/workspace.js"; import { createSubsystemLogger } from "../../../logging/subsystem.js"; import { resolveHookConfig } from "../../config.js"; import { isAgentBootstrapEvent, type HookHandler } from "../../hooks.js"; const HOOK_KEY = "bootstrap-extra-files"; const log = createSubsystemLogger("bootstrap-extra-files"); function normalizeStringArray(value: unknown): string[] { if (!Array.isArray(value)) { return []; } return value.map((v) => (typeof v === "string" ? v.trim() : "")).filter(Boolean); } function resolveExtraBootstrapPatterns(hookConfig: Record): string[] { const fromPaths = normalizeStringArray(hookConfig.paths); if (fromPaths.length > 0) { return fromPaths; } const fromPatterns = normalizeStringArray(hookConfig.patterns); if (fromPatterns.length > 0) { return fromPatterns; } return normalizeStringArray(hookConfig.files); } const bootstrapExtraFilesHook: HookHandler = async (event) => { if (!isAgentBootstrapEvent(event)) { return; } const context = event.context; const hookConfig = resolveHookConfig(context.cfg, HOOK_KEY); if (!hookConfig || hookConfig.enabled === false) { return; } const patterns = resolveExtraBootstrapPatterns(hookConfig as Record); if (patterns.length === 0) { return; } try { const { files: extras, diagnostics } = await loadExtraBootstrapFilesWithDiagnostics( context.workspaceDir, patterns, ); if (diagnostics.length > 0) { log.debug("skipped extra bootstrap candidates", { skipped: diagnostics.length, reasons: diagnostics.reduce>((counts, item) => { counts[item.reason] = (counts[item.reason] ?? 0) + 1; return counts; }, {}), }); } if (extras.length === 0) { return; } context.bootstrapFiles = filterBootstrapFilesForSession( [...context.bootstrapFiles, ...extras], context.sessionKey, ); } catch (err) { log.warn(`failed: ${String(err)}`); } }; export default bootstrapExtraFilesHook;