/**
 * Shared foundation for feature-agent graph nodes.
 *
 * Provides consistent logging, spec file reading, executor invocation,
 * and error handling so every node follows the same patterns.
 */
import type { IAgentExecutor, AgentExecutionOptions, AgentExecutionResult } from '../../../../../application/ports/output/agents/agent-executor.interface.js';
import type { ApprovalGates } from '../../../../../domain/generated/output.js';
import type { FeatureAgentState } from '../state.js';
/**
 * Create a scoped logger that prefixes messages with the node name.
 * Output goes to stdout which the worker redirects to the log file.
 */
export declare function createNodeLogger(nodeName: string): {
    info(message: string): void;
    error(message: string): void;
};
export type NodeLogger = ReturnType<typeof createNodeLogger>;
/**
 * Safely read a file from the spec directory. Returns empty string if file doesn't exist.
 */
export declare function readSpecFile(specDir: string, filename: string): string;
/**
 * Build executor options with cwd. Each node gets a clean agent context.
 */
export declare function buildExecutorOptions(state: FeatureAgentState): AgentExecutionOptions;
/**
 * Parse YAML with automatic sanitization of common AI-generated issues.
 * First attempts normal parsing; on failure, sanitizes unquoted braces
 * in list items and retries.
 */
export declare function safeYamlLoad(content: string): unknown;
/**
 * Determine whether the current node should trigger an interrupt
 * for human approval given the configured approval gates.
 *
 * Gates control which phases auto-approve:
 * - allowPrd: when true, skip interrupt after requirements phase
 * - allowPlan: when true, skip interrupt after plan phase
 *
 * Nodes not covered by a gate (analyze, research) never interrupt.
 * The implement node always interrupts when gates are present
 * (unless both gates are true, meaning fully autonomous).
 */
export declare function shouldInterrupt(nodeName: string, gates: ApprovalGates | undefined): boolean;
export type ErrorCategory = 'retryable-api' | 'retryable-network' | 'non-retryable' | 'unknown';
/**
 * Classify an error message into a retry category.
 *
 * - **retryable-api**: Transient API errors (rate-limit, overload, bad request)
 * - **retryable-network**: Network-level failures (DNS, timeouts, connection refused)
 * - **non-retryable**: Logic / filesystem / syntax errors that won't resolve on retry
 * - **unknown**: Anything unrecognised (callers may choose to retry cautiously)
 */
export declare function classifyError(errorMessage: string): ErrorCategory;
export interface RetryOptions {
    /** Maximum number of execution attempts (default 3). */
    maxAttempts?: number;
    /** Base delay in ms before the first retry (default 2000). Doubles each retry. */
    baseDelayMs?: number;
    /** Optional logger for retry messages. */
    logger?: NodeLogger;
}
/**
 * Execute a prompt via the given executor with automatic retry and
 * exponential back-off for transient errors.
 *
 * Non-retryable errors are thrown immediately. Unknown errors are
 * retried (conservative stance: could be transient).
 */
export declare function retryExecute(executor: IAgentExecutor, prompt: string, options: AgentExecutionOptions, retryOpts?: RetryOptions): Promise<AgentExecutionResult>;
/**
 * Read completed phases from feature.yaml.
 */
export declare function getCompletedPhases(specDir: string): string[];
/**
 * Mark a phase as complete in feature.yaml by adding its ID to completedPhases.
 */
export declare function markPhaseComplete(specDir: string, phaseId: string, log?: NodeLogger): void;
/**
 * Execute a node with consistent logging and error handling.
 *
 * Wraps the node's core logic with:
 * - Entry/exit logging with timing
 * - Error catching that returns error state instead of throwing
 * - Consistent state shape for success and failure
 */
export declare function executeNode(nodeName: string, executor: IAgentExecutor, buildPrompt: (state: FeatureAgentState, log: NodeLogger) => string): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
//# sourceMappingURL=node-helpers.d.ts.map