UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

57 lines (56 loc) • 3.52 kB
// cli-hooks-context.ts — HookContext: everything a hook handler needs as plain data + helpers. // Centralizes the "resolve state and check guards" pattern so hook handlers don't // reach into governance, init, project-config, hooks, init-setup, etc. directly. import { getPhrenPath, readRootManifest, appendAuditLog, } from "../shared.js"; import { updateRuntimeHealth, } from "../shared/governance.js"; import { detectProject } from "../shared/index.js"; import { getHooksEnabledPreference } from "../init/init.js"; import { isToolHookEnabled } from "../hooks.js"; import { isProjectHookEnabled } from "../project-config.js"; import { resolveRuntimeProfile } from "../runtime-profile.js"; /** Build a HookContext from the current process environment. */ export function buildHookContext() { const phrenPath = getPhrenPath(); const profile = resolveRuntimeProfile(phrenPath); const cwd = process.cwd(); const hookTool = process.env.PHREN_HOOK_TOOL || "claude"; const hooksEnabled = getHooksEnabledPreference(phrenPath); const toolHookEnabled = hooksEnabled && isToolHookEnabled(phrenPath, hookTool); const activeProject = detectProject(phrenPath, cwd, profile); const manifest = readRootManifest(phrenPath); return { phrenPath, profile, cwd, hookTool, activeProject, hooksEnabled, toolHookEnabled, manifest }; } /** Check common hook guards. Returns a reason string if the hook should NOT run, null if OK. */ export function checkHookGuard(ctx, event) { if (!ctx.hooksEnabled) return "disabled"; if (!ctx.toolHookEnabled) return `tool_disabled tool=${ctx.hookTool}`; if (!isProjectHookEnabled(ctx.phrenPath, ctx.activeProject, event)) { return `project_disabled project=${ctx.activeProject}`; } return null; } /** Log a guard skip and optionally update runtime health. */ export function handleGuardSkip(ctx, hookName, reason, healthUpdate) { if (healthUpdate) updateRuntimeHealth(ctx.phrenPath, healthUpdate); appendAuditLog(ctx.phrenPath, hookName, `status=${reason}`); } // Re-export frequently used functions so hook handlers can import from one place export { debugLog, appendAuditLog, getPhrenPath, readRootManifest, sessionMarker, runtimeFile, EXEC_TIMEOUT_MS, getProjectDirs, findProjectNameCaseInsensitive, projectSlugFromPath, homePath, } from "../shared.js"; export { updateRuntimeHealth, buildSyncStatus, getWorkflowPolicy, withFileLock, appendReviewQueue, recordFeedback, getQualityMultiplier, } from "../shared/governance.js"; export { detectProject } from "../shared/index.js"; export { isProjectHookEnabled, readProjectConfig, getProjectSourcePath } from "../project-config.js"; export { resolveRuntimeProfile } from "../runtime-profile.js"; export { detectProjectDir, ensureLocalGitRepo, isProjectTracked, repairPreexistingInstall, } from "../init/setup.js"; export { getProactivityLevelForTask, getProactivityLevelForFindings } from "../proactivity.js"; export { hasExplicitFindingSignal, shouldAutoCaptureFindingsForLevel } from "../proactivity.js"; export { FINDING_SENSITIVITY_CONFIG } from "./config.js"; export { isFeatureEnabled, errorMessage } from "../utils.js"; export { bootstrapPhrenDotEnv } from "../phren-dotenv.js"; export { finalizeTaskSession } from "../task/lifecycle.js"; export { appendFindingJournal } from "../finding/journal.js"; export { getHooksEnabledPreference } from "../init/init.js"; export { isToolHookEnabled } from "../hooks.js"; export { runDoctor } from "../link/link.js";