import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; import { Database } from 'better-sqlite3'; interface AppLogsCommandOptions { follow?: boolean; lines?: string | number; since?: string; until?: string; grep?: string; priority?: string; stdout?: boolean; stderr?: boolean; cat?: boolean; json?: boolean; } declare function appLogsCommand(projectName?: string, options?: AppLogsCommandOptions): Promise; interface CleanCommandOptions { keep?: string | number; days?: string | number; vacuum?: boolean; } declare function cleanCommand(projectName?: string, options?: CleanCommandOptions): Promise; interface RollbackCommandOptions { to?: string; inline?: boolean; } declare function rollbackCommand(projectName?: string, options?: RollbackCommandOptions): Promise; declare function statsCommand(projectName?: string): void; interface StatusCommandOptions { watch?: boolean; interval?: string | number; } declare function statusCommand(projectName?: string, options?: StatusCommandOptions): Promise; declare function parseDurationMs(duration: string | number): number; declare function formatDurationMs(ms: number): string; type DeployStrategy = 'in-place' | 'isolated' | 'release' | 'zero-downtime'; type QueueMode = 'latest' | 'fifo' | 'reject'; type DirtyWorkspaceMode = 'reject' | 'reset' | 'stash'; type ServiceAction = 'start' | 'restart' | 'reload' | 'none'; type ReadinessMode = 'all' | 'any' | 'sequence'; type ReadyCheckType = 'http' | 'https' | 'tcp' | 'command' | 'process' | 'file'; interface HttpCheckConfig { type: 'http' | 'https'; url: string; expect?: { status?: number; headers?: Record; bodyIncludes?: string; }; } interface TcpCheckConfig { type: 'tcp'; host: string; port: number; } interface CommandCheckConfig { type: 'command'; command: string; expectedExitCode?: number; } interface ProcessCheckConfig { type: 'process'; name?: string; pidFile?: string; } interface FileCheckConfig { type: 'file'; path: string; } type IndividualCheckConfig = HttpCheckConfig | TcpCheckConfig | CommandCheckConfig | ProcessCheckConfig | FileCheckConfig; interface ReadyConfig { url?: string; timeout?: string | number; interval?: string | number; mode?: ReadinessMode; checks?: IndividualCheckConfig[]; } interface RetryConfig { attempts?: number; backoff?: string | number; } interface RollbackConfig { enabled?: boolean; on?: Array<'build-failure' | 'service-failure' | 'ready-failure'>; } interface DeployCommandsConfig { install?: string[]; build?: string[]; [stepName: string]: string[] | undefined; } interface DeployServiceConfig { name: string; action?: ServiceAction; stopBeforeBuild?: boolean; script?: string; command?: string; port?: number; zeroDowntime?: boolean; drainTimeout?: string | number; memoryMax?: string; memoryHigh?: string; cpuQuota?: string; restartSec?: string; } interface PreflightConfig { diskCheck?: boolean; minDiskFreeMb?: number; maxDiskUsagePercent?: number; portCheck?: boolean; } interface DeployConfig { strategy?: DeployStrategy; workspacePath?: string; concurrency?: number; queueMode?: QueueMode; dirtyWorkspace?: DirtyWorkspaceMode; releasesToKeep?: number; timeout?: string | number; retry?: RetryConfig; envFile?: string; env?: Record; preflight?: PreflightConfig; commands?: DeployCommandsConfig; service?: DeployServiceConfig; ready?: ReadyConfig; rollback?: RollbackConfig; port?: number; zeroDowntime?: boolean; drainTimeout?: string | number; canary?: boolean | { enabled?: boolean; weight?: number | string; }; canaryWeight?: number | string; } interface ProjectConfig { name: string; path: string; } interface SourceConfig { remote?: string; branch?: string; } interface WatchConfig { interval?: string | number; } interface WebhookConfig { enabled?: boolean; secret?: string; branch?: string; allowedIps?: string[]; trustProxy?: boolean; } type NotificationChannelType = 'slack' | 'discord' | 'telegram' | 'webhook'; type NotificationEvent = 'success' | 'failure' | 'rollback'; interface NotificationChannelConfig { type: NotificationChannelType; url?: string; token?: string; chatId?: string; events?: NotificationEvent[]; headers?: Record; } type NotificationsConfig = NotificationChannelConfig[] | { channels?: NotificationChannelConfig[]; slack?: { url: string; events?: NotificationEvent[]; }; discord?: { url: string; events?: NotificationEvent[]; }; telegram?: { token: string; chatId: string; events?: NotificationEvent[]; }; webhook?: { url: string; headers?: Record; events?: NotificationEvent[]; }; }; interface NormalizedNotificationChannel { type: NotificationChannelType; url?: string; token?: string; chatId?: string; events: NotificationEvent[]; headers?: Record; } interface DeployraConfig { project: ProjectConfig; source?: SourceConfig; watch?: WatchConfig; deploy?: DeployConfig; webhook?: WebhookConfig; notifications?: NotificationsConfig; environments?: Record; } interface NormalizedDeployraConfig { configHash?: string; configVersion?: number; environment?: string; project: { name: string; path: string; }; source: { remote: string; branch: string; }; watch: { intervalMs: number; }; webhook?: { enabled: boolean; secret?: string; branch?: string; allowedIps?: string[]; trustProxy: boolean; }; notifications: NormalizedNotificationChannel[]; deploy: { strategy: DeployStrategy; workspacePath: string; concurrency: number; queueMode: QueueMode; dirtyWorkspace: DirtyWorkspaceMode; releasesToKeep: number; timeoutMs: number; retry: { attempts: number; backoffMs: number; }; envFile?: string; env: Record; preflight: { diskCheck: boolean; minDiskFreeMb?: number; maxDiskUsagePercent: number; portCheck: boolean; }; commands: Record; port?: number; zeroDowntime: boolean; drainTimeoutMs: number; canary: { enabled: boolean; weight: number; }; service: { name: string; action: ServiceAction; stopBeforeBuild: boolean; script?: string; command?: string; port?: number; zeroDowntime?: boolean; drainTimeoutMs?: number; memoryMax?: string; memoryHigh?: string; cpuQuota?: string; restartSec?: string; }; ready: { timeoutMs: number; intervalMs: number; mode: ReadinessMode; checks: IndividualCheckConfig[]; }; rollback: { enabled: boolean; on: Array<'build-failure' | 'service-failure' | 'ready-failure'>; }; }; } declare function computeConfigHash(config: NormalizedDeployraConfig | object): string; declare function findConfigFile(targetPath?: string): string; declare function deepMerge>(target: T, source: Record): T; declare function parseEnvFile(filePath: string): Record; declare function loadConfig(configPath?: string, environmentName?: string): NormalizedDeployraConfig; declare function loadConfigFromDir(dirPath: string, environmentName?: string): NormalizedDeployraConfig | null; declare function normalizeAndValidateConfig(rawConfig: unknown): NormalizedDeployraConfig; interface DaemonOptions { concurrency?: number; webhookPort?: number; webhookHost?: string; enableWebhook?: boolean; watchdogIntervalMs?: number; } declare class DeployraDaemon { private workmaticEngine; private pipelineRunner; private watcher; private stateRepo; private projectRepo; private deploymentRepo; private unitupAdapter; private gitClient; private webhookServer?; private daemonOptions?; private selfRepairTimer?; private isShuttingDown; constructor(options?: DaemonOptions); getConcurrency(): number; getWebhookPort(): number | undefined; start(targetProjectName?: string, dryRun?: boolean): Promise; private repairStartupProjectsGitLocks; private startSelfRepairWatchdog; runSelfRepairCycle(dryRun?: boolean): Promise; private signalHandlers; shutdown(): Promise; private registerSignalHandlers; private unregisterSignalHandlers; } declare class RollbackManager { private gitClient; private unitupAdapter; private readyAdapter; rollback(data: { projectName: string; projectPath: string; previousSuccessfulSha?: string; deploymentId?: string; config: NormalizedDeployraConfig; }): Promise; private syncIsolatedWorkspace; } declare class DeployraError extends Error { constructor(message: string); } declare class RepositoryError extends DeployraError { constructor(message: string); } declare class CommandExecutionError extends DeployraError { exitCode: number; stderr: string; constructor(message: string, exitCode?: number, stderr?: string); } declare class RuntimeError extends DeployraError { constructor(message: string); } declare class ReadinessError extends DeployraError { constructor(message: string); } declare class RollbackError extends DeployraError { constructor(message: string); } declare class ConfigValidationError extends DeployraError { constructor(message: string); } declare class LockError extends DeployraError { constructor(message: string); } declare class PreflightError extends DeployraError { constructor(message: string); } declare class DeploymentPipelineRunner { private gitClient; private unitupAdapter; private readyAdapter; private rollbackManager; private notificationService; private projectRepo; private deploymentRepo; private stateRepo; private activeAbortControllers; abortDeployment(deploymentId: string, reason?: string): boolean; abortAllDeploymentsForProject(projectName: string, reason?: string): void; runDeployment(payload: DeploymentJobPayload): Promise; private validateAndPrepareRepository; private resolveDeploymentEnv; private executeBuildCommands; private performServiceAction; private handleDeploymentFailure; private cleanupOrphanRelease; private runStep; private executeCommandWithRetry; private reloadConfigFromWorkingDir; private syncIsolatedWorkspace; } interface DeploymentJobPayload { deploymentId: string; projectName: string; previousSha?: string; targetSha: string; triggerType: 'poll' | 'manual' | 'webhook'; dryRun?: boolean; canary?: boolean; canaryWeight?: number | string; triggeredAt: number; } interface WorkmaticEngineOptions { concurrency?: number; dbPath?: string; } declare class WorkmaticEngine { private client; private worker; private deploymentRepo; private runner; private db; private concurrency; private projectExecutionChains; constructor(options?: WorkmaticEngineOptions); private runningDeployments; getActiveRunningDeploymentIds(): Set; getConcurrency(): number; setPipelineRunner(runner: DeploymentPipelineRunner): void; startWorker(): Promise; private runForProject; enqueueDeployJob(payload: DeploymentJobPayload): Promise; cancelPendingJobsForProject(projectName: string): Promise; stopWorker(): Promise; } type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; type LogFormat = 'pretty' | 'json' | 'jsonl'; interface LogEntry { timestamp: string; level: LogLevel; project?: string; deploymentId?: string; step?: string; message: string; durationMs?: number; meta?: Record; } declare class Logger { private format; private level; constructor(format?: LogFormat, level?: LogLevel); setFormat(format: LogFormat): void; setLevel(level: LogLevel): void; getLevel(): LogLevel; log(entry: Omit): void; debug(message: string, meta?: Record): void; info(message: string, meta?: Record): void; warn(message: string, meta?: Record): void; error(message: string, meta?: Record): void; } declare const logger: Logger; declare function registerSecret(secret: string): void; declare function registerSecrets(secrets: string[] | Record): void; declare function clearRegisteredSecrets(): void; declare function maskSecrets(input: string): string; interface ReadyCheckResult { ready: boolean; attempts: number; duration: number; checks: Array<{ type: string; success: boolean; duration: number; error?: string; }>; } declare class ReadyCheckerAdapter { private executeCheck; wait(readyConfig: NormalizedDeployraConfig['deploy']['ready']): Promise; } interface RuntimeStatus { service: string; active: boolean; subState?: string; mainPid?: number; restartCount?: number; exitStatus?: number; generations?: GenerationRecordInfo[]; } interface GenerationRecordInfo { id: number; service: string; pid: number; internalPort: number; status: 'starting' | 'active' | 'previous' | 'draining' | 'stopped' | 'canary' | string; createdAt: string; activatedAt?: string; drainingAt?: string; stoppedAt?: string; canaryWeight?: number; } interface ZeroDowntimeOptions { cwd?: string; command?: string; script?: string; publicPort?: number; readyPath?: string; readinessTimeout?: number; drainTimeout?: number; canary?: boolean; canaryWeight?: number | string; onProgress?: (evt: any) => void; } interface ZeroDowntimeResult { service: string; previousGeneration: number | null; currentGeneration: number; downtimeMs: number; status: string; canaryWeight?: number; isCanary?: boolean; } interface ZeroDowntimeRollbackResult { service: string; rolledBackFrom: number | null; activeGeneration: number; status: string; } interface ZeroDowntimePromoteResult { service: string; promotedGeneration: number; previousGeneration: number | null; downtimeMs: number; status: string; } interface ServiceOptions { cwd?: string; script?: string; command?: string; port?: number; zeroDowntime?: boolean; drainTimeout?: number; memoryMax?: string; memoryHigh?: string; cpuQuota?: string; restartSec?: string; } interface AppLogOptions { follow?: boolean; lines?: number; cat?: boolean; output?: string; stdout?: boolean; stderr?: boolean; since?: string; until?: string; priority?: string; grep?: string; boot?: boolean; json?: boolean; } interface RuntimeManager { start(service: string, options?: ServiceOptions): Promise; stop(service: string): Promise; restart(service: string, options?: ServiceOptions): Promise; reload(service: string, options?: ServiceOptions): Promise; status(service: string): Promise; remove(service: string): Promise; logs?(service: string, options?: AppLogOptions): Promise; deployZeroDowntime?(service: string, options?: ZeroDowntimeOptions): Promise; rollbackZeroDowntime?(service: string, options?: ZeroDowntimeOptions): Promise; promoteZeroDowntime?(service: string, options?: ZeroDowntimeOptions): Promise; getGenerations?(service: string): Promise; } declare class UnitupAdapter implements RuntimeManager { private systemdAvailabilityCache?; private systemdCheckPromise?; private isSystemdAvailable; private upsertService; start(service: string, options?: ServiceOptions): Promise; stop(service: string): Promise; restart(service: string, options?: ServiceOptions): Promise; reload(service: string, options?: ServiceOptions): Promise; status(service: string): Promise; remove(service: string): Promise; deployZeroDowntime(service: string, options?: ZeroDowntimeOptions): Promise; rollbackZeroDowntime(service: string, options?: ZeroDowntimeOptions): Promise; promoteZeroDowntime(service: string, options?: ZeroDowntimeOptions): Promise; getGenerations(service: string): Promise; getServiceLogPaths(service: string, options?: Pick): string[]; logs(service: string, options?: AppLogOptions): Promise; } interface DiskSpaceResult { totalBytes: number; freeBytes: number; usedBytes: number; freeMb: number; usagePercent: number; ok: boolean; warning?: string; error?: string; } declare function checkDiskSpace(targetPath: string, options?: { minFreeMb?: number; maxUsagePercent?: number; }): DiskSpaceResult; declare function assertDiskSpace(targetPath: string, options?: { minFreeMb?: number; maxUsagePercent?: number; }): DiskSpaceResult; declare function normalizeIp(ip: string): string; declare function matchCidr(ip: string, cidr: string): boolean; declare function isIpAllowed(clientIp: string, allowedList?: string[]): boolean; declare function extractClientIp(remoteAddress: string | undefined, headers: Record, trustProxy?: boolean): string; declare function getDatabasePath(): string; declare function getDatabase(): Database; declare function closeDatabase(): void; declare function vacuumDatabase(): void; declare function getDatabaseSize(): number; type DeploymentStatus = 'queued' | 'running' | 'success' | 'failed' | 'cancelled' | 'rolling_back' | 'rolled_back' | 'rollback_failed'; interface DeploymentStep { id: string; deploymentId: string; stepName: string; status: 'pending' | 'running' | 'success' | 'failed' | 'skipped' | 'cancelled'; startedAt?: number; completedAt?: number; duration?: number; exitCode?: number; output?: string; error?: string; } interface DeploymentRecord { id: string; projectName: string; previousSha?: string; targetSha: string; status: DeploymentStatus; triggerType: 'poll' | 'manual' | 'webhook'; dryRun?: boolean; createdAt: number; startedAt?: number; completedAt?: number; steps: DeploymentStep[]; readyCheck?: any; error?: string; } declare class DeploymentRepository { createDeployment(data: { id?: string; projectName: string; previousSha?: string; targetSha: string; status?: DeploymentStatus; triggerType: 'poll' | 'manual' | 'webhook'; dryRun?: boolean; steps?: string[]; }): DeploymentRecord; updateStatus(id: string, status: DeploymentStatus, error?: string): void; updateStep(deploymentId: string, stepName: string, update: { status: 'pending' | 'running' | 'success' | 'failed' | 'skipped' | 'cancelled'; startedAt?: number; completedAt?: number; duration?: number; exitCode?: number; output?: string; error?: string; }): void; updateReadyCheckResult(id: string, result: any): void; getDeploymentStatus(id: string): DeploymentStatus | null; getDeploymentStartedAt(id: string): number | undefined; getDeployment(id: string): DeploymentRecord | null; private hydrateDeployments; getLatestDeployment(projectName: string): DeploymentRecord | null; getDeploymentsByProject(projectName: string, limit?: number): DeploymentRecord[]; countRecentFailures(projectName: string, targetSha: string, limit?: number): number; getActiveDeployments(projectName?: string): DeploymentRecord[]; hasActiveDeployments(projectName?: string): boolean; getActiveDeploymentSummaries(projectName?: string): Array<{ id: string; status: DeploymentStatus; targetSha: string; }>; cancelPendingDeployments(projectName: string, reason: string): Array<{ id: string; status: DeploymentStatus; }>; getStats(projectName?: string): { total: number; success: number; failed: number; rolledBack: number; cancelled: number; running: number; queued: number; avgDurationMs: number; }; cleanupUnfinishedJobsOnStartup(): number; cleanupStaleJobs(maxAgeMs?: number): number; pruneDeployments(options: { projectName?: string; keepCount?: number; maxAgeDays?: number; }): { deletedDeployments: number; deletedSteps: number; }; } interface StoredProject { name: string; path: string; remote: string; branch: string; lastSeenSha?: string; lastSuccessfulSha?: string; config: NormalizedDeployraConfig; configHash: string; configVersion: number; updatedAt: number; } declare class ProjectRepository { cleanupLegacyUrlProjects(): void; saveProject(config: NormalizedDeployraConfig): StoredProject; getProject(name: string): StoredProject | null; getAllProjects(): StoredProject[]; deleteProject(name: string): boolean; updateLastSeenSha(name: string, sha: string): void; updateLastSuccessfulSha(name: string, sha: string): void; } declare class StateRepository { acquireLock(rawProjectName: string, lockedBy: string, timeoutMs?: number): boolean; releaseLock(rawProjectName: string, lockedBy?: string): boolean; isLocked(rawProjectName: string): boolean; getLockInfo(rawProjectName: string): { lockedBy: string; lockedAt: number; } | null; pruneStaleLocks(activeDeploymentIds?: Set, maxAgeMs?: number): number; clearAllLocks(): void; } declare class SourceWatcher { private gitClient; private projectRepo; private deploymentRepo; private workmaticEngine; private timers; private errorCounts; private checkingProjects; private lastCheckTimestamps; private lastConcurrentCheckLogTimestamps; private configMtimes; private syncTimer?; private targetProjectName?; private isDryRun; private isStopped; constructor(workmaticEngine: WorkmaticEngine); start(targetProjectName?: string, dryRun?: boolean): Promise; stop(): Promise; syncProjects(): Promise; private countRecentFailedAttempts; checkProject(projectName: string, triggerType?: 'poll' | 'manual' | 'webhook', dryRun?: boolean, explicitTargetSha?: string, canaryOptions?: { canary?: boolean; canaryWeight?: number | string; }): Promise; private scheduleNextCheck; } export { type AppLogOptions, type AppLogsCommandOptions, type CommandCheckConfig, CommandExecutionError, ConfigValidationError, type DeployCommandsConfig, type DeployConfig, type DeployServiceConfig, type DeployStrategy, DeploymentPipelineRunner, DeploymentRepository, type DeployraConfig, DeployraDaemon, DeployraError, type DirtyWorkspaceMode, type FileCheckConfig, type HttpCheckConfig, type IndividualCheckConfig, LockError, Logger, type NormalizedDeployraConfig, type NormalizedNotificationChannel, type NotificationChannelConfig, type NotificationChannelType, type NotificationEvent, type NotificationsConfig, type PreflightConfig, PreflightError, type ProcessCheckConfig, type ProjectConfig, ProjectRepository, type QueueMode, ReadinessError, type ReadinessMode, type ReadyCheckType, ReadyCheckerAdapter, type ReadyConfig, RepositoryError, type RetryConfig, type RollbackConfig, RollbackError, RollbackManager, RuntimeError, type ServiceAction, type SourceConfig, SourceWatcher, StateRepository, type TcpCheckConfig, UnitupAdapter, type WatchConfig, type WebhookConfig, WorkmaticEngine, appLogsCommand, assertDiskSpace, checkDiskSpace, cleanCommand, clearRegisteredSecrets, closeDatabase, computeConfigHash, deepMerge, extractClientIp, findConfigFile, formatDurationMs, getDatabase, getDatabasePath, getDatabaseSize, isIpAllowed, loadConfig, loadConfigFromDir, logger, maskSecrets, matchCidr, normalizeAndValidateConfig, normalizeIp, parseDurationMs, parseEnvFile, registerSecret, registerSecrets, rollbackCommand, statsCommand, statusCommand, vacuumDatabase };