/** * Hook type definitions * * Types for the module lifecycle hook system. * Hooks allow modules to execute custom logic at deployment milestones * (e.g., container_created triggers web automation for API key creation). */ import type { HookDefinition, HookResult as ModuleHookResult } from '@celilo/capabilities'; /** * `HookDefinition`, `HookLogger` and `HookContext` are re-exported from * `@celilo/capabilities`, which owns them. All three were declared a second * time here and the `HookLogger` copy said so in its own comment ("kept in * sync") — a duplicate that announces it needs syncing is one that will * eventually not be. * * A second declaration of a shared shape does not fail loudly when it drifts: * both sides keep compiling and the two meanings diverge silently. `HookName` * was the same duplication and HAD already drifted — it was missing * `reconcile_routes`, so caddy's reconcile hook was a hook the celilo side of * the codebase did not believe in (celilo#821). */ export type { HookDefinition, HookLogger, HookContext } from '@celilo/capabilities'; /** * Surfaced by `invokeHook` when a capability call inside the hook threw * a `MissingProviderInputError`. Callers (notably `module-deploy.ts`) * use this to drive the cross-module ensure interview and retry the * hook. See `apps/celilo/designs/CROSS_MODULE_CONFIG_INTERVIEW.md`. */ export interface MissingProviderInputDetails { providerModuleId: string; ensureId: string; value: string; humanContext?: string; } /** * Result returned from hook execution. * * The shape a module's hook produces is `@celilo/capabilities`' `HookResult`; * this adds the one field only the framework sets. A module never writes * `missingProviderInput` — the executor sets it when a capability call throws * `MissingProviderInputError` — so it belongs on the framework's view of the * result rather than in the module-facing contract. */ export interface HookResult extends ModuleHookResult { /** * Set when the hook failed because a capability call needs the * framework to extend another module's config. Mutually exclusive * with `success: true`. */ missingProviderInput?: MissingProviderInputDetails; } /** * Supported lifecycle hook names — re-exported from `@celilo/capabilities`, * which owns the one list (celilo#821). * * This was a second hand-maintained copy, and it had already drifted: it was * missing `reconcile_routes`, so caddy's public_web reconcile hook was a hook * the celilo side of the codebase did not believe in. */ export type { HookName } from '@celilo/capabilities'; export { HOOK_NAMES } from '@celilo/capabilities'; import type { HookName } from '@celilo/capabilities'; /** * Hook manifest section - maps hook names to definitions */ export type HookManifest = Partial>; /** * Render collected artifacts for an operator-facing error message. * * One definition, because three call sites rendered the single old * `screenshotPath` three separate times and would have drifted the moment * one of them learned about the others. */ export function describeArtifacts(artifactPaths: string[] | undefined): string { if (!artifactPaths || artifactPaths.length === 0) return ''; const label = artifactPaths.length === 1 ? 'Artifact saved' : 'Artifacts saved'; return `\n\n${label}:\n ${artifactPaths.join('\n ')}`; }