@mateusbmp/backup-manager 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/paths.ts","../src/core/schedule.ts","../src/core/config/schema.ts","../src/core/config/defaults.ts","../src/core/config/load.ts","../src/core/process.ts","../src/core/format.ts","../src/core/jobs/store.ts","../src/core/config/store.ts","../src/ui/theme.ts","../src/ui/router.ts","../src/ui/context.tsx","../src/ui/components/basics.tsx","../src/ui/components/Frame.tsx","../src/ui/components/Overlay.tsx","../src/ui/hooks/usePolling.ts","../src/ui/keys.ts","../src/ui/components/ScrollList.tsx","../src/ui/screens/Backups.tsx","../src/ui/hooks/useJobEvents.ts","../src/ui/screens/Dashboard.tsx","../src/ui/screens/Doctor.tsx","../src/ui/components/TextField.tsx","../src/ui/components/Form.tsx","../src/ui/screens/forms.ts","../src/ui/screens/DatabaseEdit.tsx","../src/ui/screens/ProjectEdit.tsx","../src/ui/screens/EnvironmentEdit.tsx","../src/ui/screens/Environments.tsx","../src/ui/screens/Jobs.tsx","../src/ui/screens/NewBackup.tsx","../src/ui/screens/Onboarding.tsx","../src/ui/screens/Prune.tsx","../src/ui/screens/Service.tsx","../src/ui/screens/Settings.tsx","../src/ui/screens/index.tsx","../src/ui/App.tsx","../src/ui/main.tsx","../src/cli.tsx","../src/cli/program.ts","../src/core/daemon/daemon.ts","../src/api/server.ts","../src/version.ts","../src/core/jobs/runner.ts","../src/core/backup/lock.ts","../src/core/backup/pipeline.ts","../src/core/backup/archive.ts","../src/core/backup/catalog.ts","../src/core/backup/manifest.ts","../src/core/backup/mariadb.ts","../src/core/dotenv.ts","../src/core/backup/prune.ts","../src/core/backup/retention.ts","../src/core/jobs/events.ts","../src/core/daemon/catchup.ts","../src/core/daemon/scheduler.ts","../src/core/services.ts","../src/core/doctor.ts","../src/core/service/manager.ts","../src/core/service/systemctl.ts","../src/core/service/unit.ts","../src/ui/print/print.tsx"],"sourcesContent":["import { homedir } from \"node:os\";\nimport path from \"node:path\";\n\nexport const APP_DIR = \"backup-manager\";\n\n/** Expand a leading `~` or `~/` to the current user's home directory. */\nexport function expandHome(p: string, home = homedir()): string {\n if (p === \"~\") return home;\n if (p.startsWith(\"~/\")) return path.join(home, p.slice(2));\n return p;\n}\n\n/** Expand `~` and make the path absolute (relative paths resolve against `base`). */\nexport function resolvePath(p: string, base = process.cwd()): string {\n return path.resolve(base, expandHome(p));\n}\n\nfunction xdg(name: string, fallback: string, env: NodeJS.ProcessEnv): string {\n const value = env[name];\n return value && path.isAbsolute(value) ? value : path.join(homedir(), fallback);\n}\n\nexport function xdgConfigHome(env = process.env): string {\n return xdg(\"XDG_CONFIG_HOME\", \".config\", env);\n}\n\nexport function xdgDataHome(env = process.env): string {\n return xdg(\"XDG_DATA_HOME\", \".local/share\", env);\n}\n\nexport function xdgStateHome(env = process.env): string {\n return xdg(\"XDG_STATE_HOME\", \".local/state\", env);\n}\n\nexport function defaultConfigPath(env = process.env): string {\n return path.join(xdgConfigHome(env), APP_DIR, \"config.json\");\n}\n\nexport function defaultBackupDir(env = process.env): string {\n return path.join(xdgDataHome(env), APP_DIR, \"backups\");\n}\n\nexport function defaultStateDir(env = process.env): string {\n return path.join(xdgStateHome(env), APP_DIR);\n}\n\n/** Config lookup order: explicit flag → `$BKM_CONFIG` → XDG default. */\nexport function resolveConfigPath(explicit?: string, env = process.env): string {\n if (explicit) return resolvePath(explicit);\n if (env.BKM_CONFIG) return resolvePath(env.BKM_CONFIG);\n return defaultConfigPath(env);\n}\n","import { Cron } from \"croner\";\n\n/** Returns an error message when `expr` is not a valid cron expression, otherwise `null`. */\nexport function scheduleError(expr: string, timezone?: string): string | null {\n try {\n new Cron(expr, { paused: true, ...(timezone ? { timezone } : {}) }).stop();\n return null;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n}\n\nexport function nextRuns(expr: string, count: number, timezone?: string, from?: Date): Date[] {\n try {\n const cron = new Cron(expr, { paused: true, ...(timezone ? { timezone } : {}) });\n const runs = cron.nextRuns(count, from);\n cron.stop();\n return runs;\n } catch {\n return [];\n }\n}\n\nexport function nextRun(expr: string | undefined, timezone?: string, from?: Date): Date | null {\n if (!expr) return null;\n return nextRuns(expr, 1, timezone, from)[0] ?? null;\n}\n\n/** Most recent scheduled fire time strictly before `reference`. */\nexport function previousRun(expr: string, reference: Date, timezone?: string): Date | null {\n try {\n const cron = new Cron(expr, { paused: true, ...(timezone ? { timezone } : {}) });\n const runs = cron.previousRuns(1, reference);\n cron.stop();\n return runs[0] ?? null;\n } catch {\n return null;\n }\n}\n\nexport function isValidTimezone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: tz });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function systemTimezone(): string {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n}\n\nconst DAYS = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nconst isNum = (v: string | undefined): v is string => v !== undefined && /^\\d+$/.test(v);\nconst hhmm = (h: string, m: string) => `${h.padStart(2, \"0\")}:${m.padStart(2, \"0\")}`;\n\n/** A short human description of common cron shapes; falls back to the expression itself. */\nexport function describeSchedule(expr: string): string {\n const parts = expr.trim().split(/\\s+/);\n const fields = parts.length === 6 ? parts.slice(1) : parts;\n const seconds = parts.length === 6 ? parts[0] : \"0\";\n if (fields.length !== 5) return expr;\n const [min, hour, dom, mon, dow] = fields as [string, string, string, string, string];\n if (parts.length === 6 && seconds !== \"0\") {\n if (/^\\*\\/\\d+$/.test(seconds ?? \"\") && [min, hour, dom, mon, dow].every((f) => f === \"*\")) {\n return `every ${seconds?.slice(2)} seconds`;\n }\n return `custom: ${expr}`;\n }\n const rest = [dom, mon, dow];\n if (min === \"*\" && hour === \"*\" && rest.every((f) => f === \"*\")) return \"every minute\";\n if (/^\\*\\/\\d+$/.test(min) && hour === \"*\" && rest.every((f) => f === \"*\")) {\n return `every ${min.slice(2)} minutes`;\n }\n if (isNum(min) && hour === \"*\" && rest.every((f) => f === \"*\")) {\n return `hourly at minute ${min}`;\n }\n if (isNum(min) && /^\\*\\/\\d+$/.test(hour) && rest.every((f) => f === \"*\")) {\n return `every ${hour.slice(2)} hours at minute ${min}`;\n }\n if (isNum(min) && isNum(hour)) {\n const at = hhmm(hour, min);\n if (rest.every((f) => f === \"*\")) return `daily at ${at}`;\n if (dom === \"*\" && mon === \"*\" && isNum(dow)) {\n return `weekly on ${DAYS[Number(dow) % 7]} at ${at}`;\n }\n if (dom === \"*\" && mon === \"*\" && dow === \"1-5\") return `weekdays at ${at}`;\n if (isNum(dom) && mon === \"*\" && dow === \"*\") return `monthly on day ${dom} at ${at}`;\n }\n return `custom: ${expr}`;\n}\n","import path from \"node:path\";\nimport { z } from \"zod\";\nimport { defaultBackupDir, resolvePath } from \"../paths.js\";\nimport { isValidTimezone, scheduleError } from \"../schedule.js\";\n\nexport const CONFIG_VERSION = 1;\nexport const NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\nexport const SCHEMA_URL =\n \"https://raw.githubusercontent.com/MateusBMP/backup-manager/main/config.schema.json\";\n\nexport const DEFAULT_INCLUDE = [\"storage/app\"];\nexport const DEFAULT_EXCLUDE = [\n \"storage/framework/{cache,sessions,views}/**\",\n \"storage/logs/**\",\n \"**/.gitignore\",\n];\nexport const DEFAULT_RETENTION = { keepLast: 7, keepDays: 30 } as const;\nexport const DEFAULT_API = { enabled: true, host: \"127.0.0.1\", port: 8080 } as const;\nexport const DEFAULT_SETTINGS = {\n compressLevel: 6,\n autoPrune: true,\n maxConcurrentJobs: 1,\n} as const;\n\nconst name = (what: string) =>\n z\n .string()\n .regex(\n NAME_PATTERN,\n \"use lowercase letters, digits, '-' or '_' (must start with a letter or digit)\",\n )\n .max(64)\n .describe(`${what} name: lowercase letters, digits, '-' and '_'.`);\n\nconst nonEmpty = z.string().trim().min(1);\n\nexport const SettingsSchema = z\n .object({\n backupDir: nonEmpty\n .optional()\n .describe(\"Root directory for backups. Default: $XDG_DATA_HOME/backup-manager/backups.\"),\n stateDir: nonEmpty\n .optional()\n .describe(\n \"Directory for jobs, logs, locks and schedule state. Default: $XDG_STATE_HOME/backup-manager.\",\n ),\n compressLevel: z\n .int()\n .min(1)\n .max(9)\n .default(DEFAULT_SETTINGS.compressLevel)\n .describe(\"gzip compression level for dumps and archives (1 fastest … 9 smallest).\"),\n autoPrune: z\n .boolean()\n .default(DEFAULT_SETTINGS.autoPrune)\n .describe(\"Apply the retention policy after every successful backup.\"),\n timezone: nonEmpty\n .optional()\n .describe(\n \"IANA timezone for schedules, e.g. 'America/Sao_Paulo'. Default: the system timezone.\",\n ),\n maxConcurrentJobs: z\n .int()\n .min(1)\n .max(16)\n .default(DEFAULT_SETTINGS.maxConcurrentJobs)\n .describe(\"Maximum scheduled jobs the daemon runs at the same time.\"),\n })\n .strict()\n .describe(\"Global settings.\");\n\nexport const RetentionSchema = z\n .object({\n keepLast: z\n .int()\n .min(0)\n .default(DEFAULT_RETENTION.keepLast)\n .describe(\"Keep the newest N complete backups (0 disables this rule).\"),\n keepDays: z\n .int()\n .min(0)\n .default(DEFAULT_RETENTION.keepDays)\n .describe(\"Keep complete backups younger than N days (0 disables this rule).\"),\n })\n .strict()\n .describe(\"Retention policy. A backup is kept when either rule keeps it.\");\n\nexport const RetentionOverrideSchema = z\n .object({\n keepLast: z.int().min(0).optional().describe(\"Overrides the global keepLast.\"),\n keepDays: z.int().min(0).optional().describe(\"Overrides the global keepDays.\"),\n })\n .strict()\n .describe(\"Per-environment retention override.\");\n\nexport const ApiSchema = z\n .object({\n enabled: z\n .boolean()\n .default(DEFAULT_API.enabled)\n .describe(\"Serve the read-only HTTP API from the daemon.\"),\n host: nonEmpty.default(DEFAULT_API.host).describe(\"Address to bind.\"),\n port: z.int().min(1).max(65_535).default(DEFAULT_API.port).describe(\"TCP port.\"),\n token: nonEmpty\n .optional()\n .describe(\"Bearer token required by every route except /health, /docs and /openapi.json.\"),\n tokenFile: nonEmpty\n .optional()\n .describe(\"File containing the bearer token (alternative to token).\"),\n })\n .strict()\n .describe(\"Read-only HTTP API served by `bkm daemon`.\");\n\nexport const ProjectSchema = z\n .object({\n name: name(\"Project\"),\n path: nonEmpty.describe(\n \"Absolute path to the Laravel project root (the directory with artisan).\",\n ),\n include: z\n .array(nonEmpty)\n .min(1)\n .default(DEFAULT_INCLUDE)\n .describe(\"Directories to archive, relative to the project root.\"),\n exclude: z\n .array(nonEmpty)\n .default(DEFAULT_EXCLUDE)\n .describe(\n \"Glob patterns (relative to the project root) to leave out. 'dir/**' keeps the empty directory.\",\n ),\n })\n .strict();\n\nconst credentials = {\n host: nonEmpty.optional().describe(\"Server host.\"),\n port: z.int().min(1).max(65_535).optional().describe(\"Server port.\"),\n socket: nonEmpty.optional().describe(\"Unix socket path (instead of host/port).\"),\n user: nonEmpty.optional().describe(\"User name.\"),\n password: z.string().optional().describe(\"Password. Prefer passwordFile.\"),\n passwordFile: nonEmpty.optional().describe(\"File containing the password (first line).\"),\n};\n\nexport const LaravelSourceSchema = z\n .object({\n type: z.literal(\"laravel\"),\n project: name(\"Project\").describe(\n \"Project (in the same environment) whose .env provides DB_* values.\",\n ),\n ...credentials,\n database: nonEmpty.optional().describe(\"Overrides DB_DATABASE.\"),\n })\n .strict()\n .describe(\"Read the connection from a Laravel project's .env; any field set here wins.\");\n\nexport const ConnectionSourceSchema = z\n .object({\n type: z.literal(\"connection\"),\n ...credentials,\n schemas: z.array(nonEmpty).min(1).describe(\"Schemas (databases) to dump into one file.\"),\n })\n .strict()\n .describe(\"An explicit MariaDB/MySQL connection.\");\n\nexport const DatabaseSchema = z\n .object({\n name: name(\"Database\"),\n source: z.discriminatedUnion(\"type\", [LaravelSourceSchema, ConnectionSourceSchema]),\n extraArgs: z\n .array(z.string())\n .default([])\n .describe(\"Extra arguments for mariadb-dump, e.g. ['--ignore-table=app.sessions'].\"),\n })\n .strict();\n\nexport const EnvironmentSchema = z\n .object({\n name: name(\"Environment\"),\n schedule: nonEmpty\n .optional()\n .describe(\"Cron expression (5 or 6 fields) for automatic backups. Omit for manual only.\"),\n backupDir: nonEmpty\n .optional()\n .describe(\"Backup directory used as-is. Default: <settings.backupDir>/<name>.\"),\n retention: RetentionOverrideSchema.optional(),\n projects: z\n .array(ProjectSchema)\n .default([])\n .describe(\"Laravel projects whose storage is archived.\"),\n databases: z.array(DatabaseSchema).default([]).describe(\"Databases dumped with mariadb-dump.\"),\n })\n .strict();\n\nexport const ConfigSchema = z\n .object({\n $schema: z.string().optional(),\n version: z.literal(CONFIG_VERSION).default(CONFIG_VERSION).describe(\"Config format version.\"),\n settings: SettingsSchema.default({\n compressLevel: DEFAULT_SETTINGS.compressLevel,\n autoPrune: DEFAULT_SETTINGS.autoPrune,\n maxConcurrentJobs: DEFAULT_SETTINGS.maxConcurrentJobs,\n }),\n retention: RetentionSchema.default({ ...DEFAULT_RETENTION }),\n api: ApiSchema.default({ ...DEFAULT_API }),\n environments: z\n .array(EnvironmentSchema)\n .default([])\n .describe(\"Environments, in display order.\"),\n })\n .strict()\n .superRefine((config, ctx) => {\n const tz = config.settings.timezone;\n if (tz && !isValidTimezone(tz)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"settings\", \"timezone\"],\n message: `unknown timezone '${tz}'`,\n });\n }\n if (config.api.token && config.api.tokenFile) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"api\", \"tokenFile\"],\n message: \"set token or tokenFile, not both\",\n });\n }\n checkRetention(config.retention, [\"retention\"], ctx);\n\n const envNames = new Set<string>();\n const dirs = new Map<string, string>();\n config.environments.forEach((env, i) => {\n const at = (...rest: (string | number)[]) => [\"environments\", i, ...rest];\n if (envNames.has(env.name)) {\n ctx.addIssue({\n code: \"custom\",\n path: at(\"name\"),\n message: `duplicate environment '${env.name}'`,\n });\n }\n envNames.add(env.name);\n if (env.schedule) {\n const error = scheduleError(env.schedule, tz && isValidTimezone(tz) ? tz : undefined);\n if (error)\n ctx.addIssue({\n code: \"custom\",\n path: at(\"schedule\"),\n message: `invalid cron expression: ${error}`,\n });\n }\n if (env.retention) {\n checkRetention(\n { ...config.retention, ...stripUndefined(env.retention) },\n at(\"retention\"),\n ctx,\n );\n }\n const dir = env.backupDir\n ? resolvePath(env.backupDir)\n : path.join(resolvePath(config.settings.backupDir ?? defaultBackupDir()), env.name);\n const other = dirs.get(dir);\n if (other) {\n ctx.addIssue({\n code: \"custom\",\n path: at(\"backupDir\"),\n message: `backup directory is already used by environment '${other}'`,\n });\n }\n dirs.set(dir, env.name);\n\n const projects = new Set<string>();\n env.projects.forEach((p, j) => {\n if (projects.has(p.name)) {\n ctx.addIssue({\n code: \"custom\",\n path: at(\"projects\", j, \"name\"),\n message: `duplicate project '${p.name}'`,\n });\n }\n projects.add(p.name);\n });\n const dbs = new Set<string>();\n env.databases.forEach((db, j) => {\n if (dbs.has(db.name)) {\n ctx.addIssue({\n code: \"custom\",\n path: at(\"databases\", j, \"name\"),\n message: `duplicate database '${db.name}'`,\n });\n }\n dbs.add(db.name);\n const source = db.source;\n if (source.password !== undefined && source.passwordFile) {\n ctx.addIssue({\n code: \"custom\",\n path: at(\"databases\", j, \"source\", \"passwordFile\"),\n message: \"set password or passwordFile, not both\",\n });\n }\n if (source.type === \"laravel\" && !projects.has(source.project)) {\n ctx.addIssue({\n code: \"custom\",\n path: at(\"databases\", j, \"source\", \"project\"),\n message: `unknown project '${source.project}' in environment '${env.name}'`,\n });\n }\n });\n });\n });\n\nfunction stripUndefined<T extends object>(value: T): Partial<T> {\n return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n\nfunction checkRetention(\n r: { keepLast: number; keepDays: number },\n at: (string | number)[],\n ctx: z.RefinementCtx,\n) {\n if (r.keepLast === 0 && r.keepDays === 0) {\n ctx.addIssue({ code: \"custom\", path: at, message: \"keepLast and keepDays cannot both be 0\" });\n }\n}\n\nexport type Config = z.output<typeof ConfigSchema>;\nexport type ConfigInput = z.input<typeof ConfigSchema>;\nexport type Settings = Config[\"settings\"];\nexport type Retention = Config[\"retention\"];\nexport type ApiSettings = Config[\"api\"];\nexport type Environment = Config[\"environments\"][number];\nexport type Project = Environment[\"projects\"][number];\nexport type Database = Environment[\"databases\"][number];\nexport type DatabaseSource = Database[\"source\"];\nexport type LaravelSource = z.output<typeof LaravelSourceSchema>;\nexport type ConnectionSource = z.output<typeof ConnectionSourceSchema>;\n\n/** JSON Schema for editors (`$schema` in config.json). */\nexport function configJsonSchema(): Record<string, unknown> {\n const schema = z.toJSONSchema(ConfigSchema, { io: \"input\", target: \"draft-2020-12\" }) as Record<\n string,\n unknown\n >;\n return {\n $schema: schema.$schema,\n $id: SCHEMA_URL,\n title: \"backup-manager configuration\",\n ...Object.fromEntries(Object.entries(schema).filter(([k]) => k !== \"$schema\")),\n };\n}\n","import path from \"node:path\";\nimport { defaultBackupDir, defaultStateDir, resolvePath } from \"../paths.js\";\nimport { systemTimezone } from \"../schedule.js\";\nimport {\n type Config,\n ConfigSchema,\n DEFAULT_API,\n DEFAULT_EXCLUDE,\n DEFAULT_INCLUDE,\n DEFAULT_RETENTION,\n DEFAULT_SETTINGS,\n type Environment,\n type Retention,\n SCHEMA_URL,\n} from \"./schema.js\";\n\n/** A valid config with no environments (what onboarding starts from). */\nexport function emptyConfig(): Config {\n return ConfigSchema.parse({ $schema: SCHEMA_URL });\n}\n\nexport function backupRoot(config: Config): string {\n return resolvePath(config.settings.backupDir ?? defaultBackupDir());\n}\n\nexport function stateDir(config: Config): string {\n return resolvePath(config.settings.stateDir ?? defaultStateDir());\n}\n\nexport function timezone(config: Config): string {\n return config.settings.timezone ?? systemTimezone();\n}\n\nexport function envBackupDir(config: Config, env: Environment): string {\n return env.backupDir ? resolvePath(env.backupDir) : path.join(backupRoot(config), env.name);\n}\n\nexport function effectiveRetention(config: Config, env: Environment): Retention {\n return {\n keepLast: env.retention?.keepLast ?? config.retention.keepLast,\n keepDays: env.retention?.keepDays ?? config.retention.keepDays,\n };\n}\n\nexport function findEnvironment(config: Config, name: string): Environment | undefined {\n return config.environments.find((e) => e.name === name);\n}\n\nconst sameArray = (a: readonly string[], b: readonly string[]) =>\n a.length === b.length && a.every((v, i) => v === b[i]);\n\nfunction dropDefaults<T extends Record<string, unknown>>(\n value: T,\n defaults: Record<string, unknown>,\n): Partial<T> {\n return Object.fromEntries(\n Object.entries(value).filter(([k, v]) => v !== undefined && defaults[k] !== v),\n ) as Partial<T>;\n}\n\nconst isEmpty = (o: object | undefined) => !o || Object.keys(o).length === 0;\n\n/**\n * The smallest JSON document that parses back to `config`: default values and empty\n * sections are removed, so the file only shows what the user chose.\n */\nexport function minimizeConfig(config: Config): Record<string, unknown> {\n const out: Record<string, unknown> = {\n $schema: config.$schema ?? SCHEMA_URL,\n version: config.version,\n };\n const settings = dropDefaults(config.settings, DEFAULT_SETTINGS);\n if (!isEmpty(settings)) out.settings = settings;\n const retention = dropDefaults(config.retention, DEFAULT_RETENTION);\n if (!isEmpty(retention)) out.retention = retention;\n const api = dropDefaults(config.api, DEFAULT_API);\n if (!isEmpty(api)) out.api = api;\n out.environments = config.environments.map((env) => {\n const e: Record<string, unknown> = { name: env.name };\n if (env.schedule) e.schedule = env.schedule;\n if (env.backupDir) e.backupDir = env.backupDir;\n const retention = env.retention ? dropDefaults(env.retention, {}) : undefined;\n if (!isEmpty(retention)) e.retention = retention;\n if (env.projects.length) {\n e.projects = env.projects.map((p) => {\n const project: Record<string, unknown> = { name: p.name, path: p.path };\n if (!sameArray(p.include, DEFAULT_INCLUDE)) project.include = p.include;\n if (!sameArray(p.exclude, DEFAULT_EXCLUDE)) project.exclude = p.exclude;\n return project;\n });\n }\n if (env.databases.length) {\n e.databases = env.databases.map((db) => {\n const d: Record<string, unknown> = {\n name: db.name,\n source: Object.fromEntries(Object.entries(db.source).filter(([, v]) => v !== undefined)),\n };\n if (db.extraArgs.length) d.extraArgs = db.extraArgs;\n return d;\n });\n }\n return e;\n });\n return out;\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport type { z } from \"zod\";\nimport { type Config, ConfigSchema } from \"./schema.js\";\n\nexport class ConfigError extends Error {\n constructor(\n message: string,\n readonly issues: string[] = [],\n ) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\nexport class ConfigMissingError extends ConfigError {\n constructor(readonly path: string) {\n super(`no config file at ${path}; run \\`bkm\\` to create one`);\n this.name = \"ConfigMissingError\";\n }\n}\n\nexport interface LoadedConfig {\n path: string;\n config: Config;\n /** File mtime when it was read; used to detect external edits before saving. */\n mtimeMs: number;\n}\n\n/** `environments[0].databases[1].source.host` style path. */\nexport function formatIssuePath(path: readonly PropertyKey[]): string {\n let out = \"\";\n for (const part of path) {\n if (typeof part === \"number\") out += `[${part}]`;\n else out += out ? `.${String(part)}` : String(part);\n }\n return out || \"(root)\";\n}\n\nexport function formatIssues(error: z.ZodError): string[] {\n return error.issues.map((issue) => `${formatIssuePath(issue.path)}: ${issue.message}`);\n}\n\nexport function parseConfig(data: unknown, source = \"config\"): Config {\n const result = ConfigSchema.safeParse(data);\n if (!result.success) {\n const issues = formatIssues(result.error);\n throw new ConfigError(`${source} is invalid:\\n ${issues.join(\"\\n \")}`, issues);\n }\n return result.data;\n}\n\nexport async function loadConfig(path: string): Promise<LoadedConfig> {\n let text: string;\n let mtimeMs: number;\n try {\n [text, { mtimeMs }] = await Promise.all([readFile(path, \"utf8\"), stat(path)]);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") throw new ConfigMissingError(path);\n throw new ConfigError(`cannot read ${path}: ${(error as Error).message}`);\n }\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch (error) {\n throw new ConfigError(`${path} is not valid JSON: ${(error as Error).message}`, [\n `(root): ${(error as Error).message}`,\n ]);\n }\n return { path, config: parseConfig(data, path), mtimeMs };\n}\n","import { constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/** True when a process with this pid exists (EPERM still means it exists). */\nexport function isAlive(pid: number | null | undefined): boolean {\n if (!pid || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === \"EPERM\";\n }\n}\n\n/** First executable found on PATH among `names`. */\nexport async function findExecutable(\n names: readonly string[],\n envPath = process.env.PATH ?? \"\",\n): Promise<string | null> {\n for (const name of names) {\n for (const dir of envPath.split(path.delimiter).filter(Boolean)) {\n const candidate = path.join(dir, name);\n try {\n await access(candidate, constants.X_OK);\n return candidate;\n } catch {\n // keep looking\n }\n }\n }\n return null;\n}\n","const UNITS = [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\"];\n\nexport function formatBytes(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return \"—\";\n let value = bytes;\n let unit = 0;\n while (value >= 1024 && unit < UNITS.length - 1) {\n value /= 1024;\n unit++;\n }\n return unit === 0 ? `${value} B` : `${value.toFixed(value < 10 ? 1 : 0)} ${UNITS[unit]}`;\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return \"—\";\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${String(s % 60).padStart(2, \"0\")}s`;\n const h = Math.floor(m / 60);\n return `${h}h ${String(m % 60).padStart(2, \"0\")}m`;\n}\n\n/** Compact relative age: `now`, `42s`, `5m`, `3h`, `2d`, `6w`. */\nexport function formatAge(from: Date | string | number, now: Date = new Date()): string {\n const diff = now.getTime() - new Date(from).getTime();\n if (!Number.isFinite(diff)) return \"—\";\n const s = Math.floor(Math.abs(diff) / 1000);\n let text: string;\n if (s < 5) return \"now\";\n if (s < 60) text = `${s}s`;\n else if (s < 3600) text = `${Math.floor(s / 60)}m`;\n else if (s < 86_400) text = `${Math.floor(s / 3600)}h`;\n else if (s < 86_400 * 14) text = `${Math.floor(s / 86_400)}d`;\n else text = `${Math.floor(s / (86_400 * 7))}w`;\n return diff >= 0 ? `${text} ago` : `in ${text}`;\n}\n\nconst pad = (n: number) => String(n).padStart(2, \"0\");\n\n/** `2026-11-09 03:15` in local time. */\nexport function formatDateTime(value: Date | string | number): string {\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return \"—\";\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n\n/** Backup/job id from a timestamp: `YYYYMMDD-HHMMSS` (local time). */\nexport function timestampId(d: Date = new Date()): string {\n return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;\n}\n\nexport function truncate(text: string, width: number): string {\n if (width <= 0) return \"\";\n return text.length <= width ? text : `${text.slice(0, Math.max(0, width - 1))}…`;\n}\n","import { randomBytes } from \"node:crypto\";\nimport { mkdir, readdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { BackupStatus } from \"../backup/manifest.js\";\nimport { timestampId } from \"../format.js\";\nimport { isAlive } from \"../process.js\";\n\nexport type JobState = \"queued\" | \"running\" | \"success\" | \"partial\" | \"failed\";\nexport type JobTrigger = \"ui\" | \"schedule\" | \"catch-up\";\n\nexport interface JobTarget {\n environment: string;\n databases?: string[];\n projects?: string[];\n}\n\nexport interface JobBackup {\n environment: string;\n backupId: string | null;\n status: BackupStatus | \"failed\";\n error?: string;\n}\n\nexport interface JobRecord {\n id: string;\n status: JobState;\n trigger: JobTrigger;\n targets: JobTarget[];\n configPath: string;\n /** Spawned in its own session (from the UI) rather than as a daemon child. */\n detached: boolean;\n pid: number | null;\n createdAt: string;\n startedAt?: string;\n finishedAt?: string;\n backups: JobBackup[];\n exitCode?: number | null;\n error?: string;\n}\n\nexport const ACTIVE: readonly JobState[] = [\"queued\", \"running\"];\nconst NEVER_STARTED_MS = 60_000;\nexport const KEEP_JOBS = 200;\n\nexport const jobsDir = (stateDir: string) => path.join(stateDir, \"jobs\");\nexport const logsDir = (stateDir: string) => path.join(stateDir, \"logs\");\nexport const jobFile = (stateDir: string, id: string) => path.join(jobsDir(stateDir), `${id}.json`);\nexport const eventsFile = (stateDir: string, id: string) =>\n path.join(logsDir(stateDir), `${id}.ndjson`);\nexport const outputFile = (stateDir: string, id: string) =>\n path.join(logsDir(stateDir), `${id}.out`);\n\nconst JOB_ID = /^\\d{8}-\\d{6}-[0-9a-f]{4}$/;\n\nexport function newJobId(now = new Date()): string {\n return `${timestampId(now)}-${randomBytes(2).toString(\"hex\")}`;\n}\n\nexport async function writeJob(stateDir: string, job: JobRecord): Promise<void> {\n const file = jobFile(stateDir, job.id);\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const tmp = `${file}.${process.pid}.tmp`;\n await writeFile(tmp, `${JSON.stringify(job, null, 2)}\\n`, { mode: 0o600 });\n await rename(tmp, file);\n}\n\nexport async function readJob(stateDir: string, id: string): Promise<JobRecord | null> {\n if (!JOB_ID.test(id)) return null;\n try {\n return JSON.parse(await readFile(jobFile(stateDir, id), \"utf8\")) as JobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function updateJob(\n stateDir: string,\n id: string,\n patch: Partial<JobRecord> | ((job: JobRecord) => Partial<JobRecord>),\n): Promise<JobRecord | null> {\n const job = await readJob(stateDir, id);\n if (!job) return null;\n const next = { ...job, ...(typeof patch === \"function\" ? patch(job) : patch) };\n await writeJob(stateDir, next);\n return next;\n}\n\n/** A queued/running job whose process is gone is marked failed. */\nexport async function reconcileJob(\n stateDir: string,\n job: JobRecord,\n now = Date.now(),\n): Promise<JobRecord> {\n if (!ACTIVE.includes(job.status)) return job;\n const lost = job.pid\n ? !isAlive(job.pid)\n : now - new Date(job.createdAt).getTime() > NEVER_STARTED_MS;\n if (!lost) return job;\n const error = job.pid ? \"job process exited unexpectedly\" : \"job process never started\";\n return (\n (await updateJob(stateDir, job.id, (current) =>\n ACTIVE.includes(current.status)\n ? { status: \"failed\", error, finishedAt: new Date(now).toISOString() }\n : {},\n )) ?? job\n );\n}\n\n/** Jobs newest first, reconciled. */\nexport async function listJobs(stateDir: string, limit = 50): Promise<JobRecord[]> {\n const names = await readdir(jobsDir(stateDir)).catch(() => [] as string[]);\n const ids = names\n .filter((n) => n.endsWith(\".json\"))\n .map((n) => n.slice(0, -5))\n .filter((id) => JOB_ID.test(id))\n .sort()\n .reverse()\n .slice(0, limit);\n const jobs = await Promise.all(ids.map((id) => readJob(stateDir, id)));\n return Promise.all(\n jobs.filter((j): j is JobRecord => j !== null).map((j) => reconcileJob(stateDir, j)),\n );\n}\n\n/** Delete records and logs beyond the newest `keep` finished jobs. */\nexport async function pruneJobs(stateDir: string, keep = KEEP_JOBS): Promise<number> {\n const names = await readdir(jobsDir(stateDir)).catch(() => [] as string[]);\n const ids = names\n .filter((n) => n.endsWith(\".json\") && JOB_ID.test(n.slice(0, -5)))\n .map((n) => n.slice(0, -5))\n .sort()\n .reverse();\n let removed = 0;\n for (const id of ids.slice(keep)) {\n const job = await readJob(stateDir, id);\n if (job && ACTIVE.includes(job.status)) continue;\n await Promise.all([\n rm(jobFile(stateDir, id), { force: true }),\n rm(eventsFile(stateDir, id), { force: true }),\n rm(outputFile(stateDir, id), { force: true }),\n ]);\n removed++;\n }\n return removed;\n}\n\nexport function jobState(backups: JobBackup[]): JobState {\n if (backups.length === 0) return \"failed\";\n if (backups.every((b) => b.status === \"complete\")) return \"success\";\n return backups.some((b) => b.status === \"complete\" || b.status === \"partial\")\n ? \"partial\"\n : \"failed\";\n}\n","import { copyFile, mkdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { minimizeConfig } from \"./defaults.js\";\nimport { ConfigError, parseConfig } from \"./load.js\";\nimport type { Config } from \"./schema.js\";\n\nexport class ConfigConflictError extends ConfigError {\n constructor(readonly path: string) {\n super(`${path} was changed by someone else since it was loaded; reload before saving`);\n this.name = \"ConfigConflictError\";\n }\n}\n\nexport interface SaveOptions {\n /** mtime from when the config was loaded; `null` means the file must not exist yet. */\n expectedMtimeMs?: number | null;\n}\n\nasync function currentMtime(file: string): Promise<number | null> {\n try {\n return (await stat(file)).mtimeMs;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n}\n\nexport function serializeConfig(config: Config): string {\n return `${JSON.stringify(minimizeConfig(config), null, 2)}\\n`;\n}\n\n/**\n * The only way config is written: validate, minimise, keep a `.bak`, then write a 0600\n * temp file and rename it over the target. Returns the new mtime.\n */\nexport async function saveConfig(\n file: string,\n config: Config,\n options: SaveOptions = {},\n): Promise<number> {\n const text = serializeConfig(config);\n parseConfig(JSON.parse(text)); // never write something we cannot read back\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const mtime = await currentMtime(file);\n if (options.expectedMtimeMs !== undefined && mtime !== options.expectedMtimeMs) {\n throw new ConfigConflictError(file);\n }\n if (mtime !== null) await copyFile(file, `${file}.bak`);\n const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;\n try {\n await writeFile(tmp, text, { mode: 0o600, flag: \"wx\" });\n await rename(tmp, file);\n } catch (error) {\n await rm(tmp, { force: true });\n throw error;\n }\n return (await stat(file)).mtimeMs;\n}\n","/** Design tokens shared by the full-screen UI and the printed CLI output. */\nconst noColor = (env: NodeJS.ProcessEnv = process.env) => \"NO_COLOR\" in env && env.NO_COLOR !== \"0\";\n\nexport interface Theme {\n color: boolean;\n accent: string | undefined;\n accentAlt: string | undefined;\n success: string | undefined;\n warning: string | undefined;\n error: string | undefined;\n info: string | undefined;\n muted: string | undefined;\n border: string | undefined;\n focus: string | undefined;\n selection: string | undefined;\n /** Colors for the title gradient (cyan → magenta). */\n gradient: string[];\n}\n\nexport function makeTheme(color = !noColor()): Theme {\n const c = (value: string) => (color ? value : undefined);\n return {\n color,\n accent: c(\"#22d3ee\"),\n accentAlt: c(\"#d946ef\"),\n success: c(\"#4ade80\"),\n warning: c(\"#facc15\"),\n error: c(\"#f87171\"),\n info: c(\"#60a5fa\"),\n muted: c(\"gray\"),\n border: c(\"#475569\"),\n focus: c(\"#22d3ee\"),\n selection: c(\"#1e293b\"),\n gradient: [\"#22d3ee\", \"#818cf8\", \"#d946ef\"],\n };\n}\n\nexport const theme = makeTheme();\n\nexport const ICONS = {\n ok: \"✔\",\n warn: \"!\",\n fail: \"✘\",\n running: \"●\",\n schedule: \"⏱\",\n bullet: \"•\",\n pointer: \"❯\",\n} as const;\n\nexport const SPINNER = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\nexport function statusColor(t: Theme, status: string): string | undefined {\n switch (status) {\n case \"ok\":\n case \"success\":\n case \"complete\":\n case \"active\":\n return t.success;\n case \"warn\":\n case \"partial\":\n case \"queued\":\n case \"activating\":\n case \"reloading\":\n return t.warning;\n case \"fail\":\n case \"failed\":\n case \"incomplete\":\n return t.error;\n case \"running\":\n return t.info;\n default:\n return t.muted;\n }\n}\n\nexport function statusIcon(status: string): string {\n switch (status) {\n case \"ok\":\n case \"success\":\n case \"complete\":\n return ICONS.ok;\n case \"warn\":\n case \"partial\":\n return \"⚠\";\n case \"fail\":\n case \"failed\":\n case \"incomplete\":\n return ICONS.fail;\n case \"running\":\n return ICONS.running;\n case \"queued\":\n return \"…\";\n default:\n return \"·\";\n }\n}\n","export type Route =\n | { name: \"onboarding\" }\n | { name: \"dashboard\" }\n | { name: \"environments\" }\n | { name: \"environment-edit\"; env?: string; onboarding?: boolean }\n | { name: \"backups\"; env?: string }\n | { name: \"backup-detail\"; env: string; id: string }\n | { name: \"jobs\" }\n | { name: \"job-live\"; id: string }\n | { name: \"new-backup\"; env?: string }\n | { name: \"prune\" }\n | { name: \"service\" }\n | { name: \"doctor\" }\n | { name: \"settings\" };\n\nexport type RouteName = Route[\"name\"];\n\nexport interface MenuItem {\n route: Route;\n label: string;\n /** Digit shortcut (1–9) and an optional letter alias. */\n key: string;\n alias?: string;\n}\n\nexport const MENU: MenuItem[] = [\n { route: { name: \"dashboard\" }, label: \"Dashboard\", key: \"1\" },\n { route: { name: \"environments\" }, label: \"Environments\", key: \"2\", alias: \"e\" },\n { route: { name: \"backups\" }, label: \"Backups\", key: \"3\" },\n { route: { name: \"jobs\" }, label: \"Jobs\", key: \"4\" },\n { route: { name: \"new-backup\" }, label: \"New backup\", key: \"5\", alias: \"n\" },\n { route: { name: \"prune\" }, label: \"Prune\", key: \"6\" },\n { route: { name: \"service\" }, label: \"Service\", key: \"7\", alias: \"s\" },\n { route: { name: \"doctor\" }, label: \"Doctor\", key: \"8\" },\n { route: { name: \"settings\" }, label: \"Settings\", key: \"9\" },\n];\n\n/** Which menu entry a route belongs to (detail screens highlight their parent). */\nexport function menuIndex(route: Route): number {\n const parent: Partial<Record<RouteName, RouteName>> = {\n \"environment-edit\": \"environments\",\n \"backup-detail\": \"backups\",\n \"job-live\": \"jobs\",\n onboarding: \"dashboard\",\n };\n const name = parent[route.name] ?? route.name;\n return Math.max(\n 0,\n MENU.findIndex((m) => m.route.name === name),\n );\n}\n","import {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { Config } from \"../core/config/schema.js\";\nimport type { Services } from \"../core/services.js\";\nimport type { Route } from \"./router.js\";\nimport type { Theme } from \"./theme.js\";\n\nexport type ToastKind = \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport interface Toast {\n id: number;\n text: string;\n kind: ToastKind;\n createdAt: number;\n}\n\nexport interface KeyHint {\n key: string;\n label: string;\n}\n\nexport interface ConfirmOptions {\n title: string;\n message: string;\n confirmLabel?: string;\n danger?: boolean;\n}\n\nexport interface AppContextValue {\n services: Services;\n theme: Theme;\n config: Config | null;\n configError: string | null;\n route: Route;\n navigate(route: Route, options?: { replace?: boolean }): void;\n back(): void;\n /** Re-read config.json from disk. */\n reload(): Promise<void>;\n /** Save through the store; returns false (with a toast) on error or external edits. */\n save(next: Config, message?: string): Promise<boolean>;\n toast(text: string, kind?: ToastKind): void;\n confirm(options: ConfirmOptions): Promise<boolean>;\n /** Content pane has keyboard focus (vs. the sidebar). */\n contentFocused: boolean;\n /** A modal (confirm/help) is open; screens should not react to keys. */\n modalOpen: boolean;\n /** Content area size in cells (inside the frame). */\n width: number;\n height: number;\n setCapture(owner: string, active: boolean): void;\n setHints(hints: KeyHint[]): void;\n /** A screen-level Esc handler; return true when it consumed the key. */\n setBackHandler(handler: (() => boolean) | null): void;\n /** Per-session memory so screens keep filters/selection when you come back. */\n memory: Map<string, unknown>;\n}\n\nexport const AppContext = createContext<AppContextValue | null>(null);\n\nexport function useApp(): AppContextValue {\n const ctx = useContext(AppContext);\n if (!ctx) throw new Error(\"useApp outside <AppContext>\");\n return ctx;\n}\n\n/** Keys reach the active screen only when the content pane is focused and no modal is open. */\nexport function useScreenActive(): boolean {\n const { contentFocused, modalOpen } = useApp();\n return contentFocused && !modalOpen;\n}\n\n/** While active, global shortcuts (q, e, n, …) are suspended so forms can take every key. */\nexport function useCaptureKeys(owner: string, active: boolean): void {\n const { setCapture } = useApp();\n useEffect(() => {\n setCapture(owner, active);\n return () => setCapture(owner, false);\n }, [owner, active, setCapture]);\n}\n\n/** useState that survives leaving and re-entering a screen (for this UI session). */\nexport function useSessionState<T>(\n key: string,\n initial: T,\n): [T, (value: T | ((prev: T) => T)) => void] {\n const { memory } = useApp();\n const [value, setValue] = useState<T>(() => (memory.has(key) ? (memory.get(key) as T) : initial));\n const set = useCallback(\n (next: T | ((prev: T) => T)) => {\n setValue((prev) => {\n const v = typeof next === \"function\" ? (next as (p: T) => T)(prev) : next;\n memory.set(key, v);\n return v;\n });\n },\n [key, memory],\n );\n return [value, set];\n}\n\n/** Let a screen handle Esc first (e.g. step back in a wizard) before the global \"back\". */\nexport function useBackHandler(handler: () => boolean): void {\n const { setBackHandler } = useApp();\n const ref = useRef(handler);\n ref.current = handler;\n useEffect(() => {\n setBackHandler(() => ref.current());\n return () => setBackHandler(null);\n }, [setBackHandler]);\n}\n\nexport function useHints(hints: KeyHint[], deps: unknown[] = []): void {\n const { setHints } = useApp();\n // biome-ignore lint/correctness/useExhaustiveDependencies: hints are recomputed from deps\n useEffect(() => {\n setHints(hints);\n }, [setHints, ...deps]);\n}\n\nexport function Provider({ value, children }: { value: AppContextValue; children: ReactNode }) {\n return <AppContext.Provider value={value}>{children}</AppContext.Provider>;\n}\n","import { Box, Text, useAnimation } from \"ink\";\nimport Gradient from \"ink-gradient\";\nimport type { ReactNode } from \"react\";\nimport { useApp } from \"../context.js\";\nimport { SPINNER, statusColor, statusIcon } from \"../theme.js\";\n\nexport function Spinner({ label, color }: { label?: string; color?: string }) {\n const { theme } = useApp();\n const { frame } = useAnimation({ interval: 80 });\n return (\n <Text>\n <Text color={color ?? theme.accent}>{SPINNER[frame % SPINNER.length]}</Text>\n {label ? ` ${label}` : \"\"}\n </Text>\n );\n}\n\n/** A dot that pulses while something runs. */\nexport function Pulse({ color }: { color?: string }) {\n const { theme } = useApp();\n const { frame } = useAnimation({ interval: 400 });\n return <Text color={color ?? theme.info}>{frame % 2 === 0 ? \"●\" : \"○\"}</Text>;\n}\n\nexport function GradientText({ children }: { children: string }) {\n const { theme } = useApp();\n if (!theme.color) return <Text bold>{children}</Text>;\n return (\n <Gradient colors={theme.gradient}>\n <Text bold>{children}</Text>\n </Gradient>\n );\n}\n\nexport function StatusText({ status, label }: { status: string; label?: string }) {\n const { theme } = useApp();\n return (\n <Text color={statusColor(theme, status)}>{`${statusIcon(status)} ${label ?? status}`}</Text>\n );\n}\n\nexport function Badge({ children, color }: { children: string; color?: string }) {\n const { theme } = useApp();\n if (!theme.color) return <Text>[{children}]</Text>;\n return (\n <Text backgroundColor={color ?? theme.accent} color=\"black\">\n {` ${children} `}\n </Text>\n );\n}\n\nexport function ProgressBar({\n value,\n width,\n color,\n}: {\n value: number;\n width: number;\n color?: string;\n}) {\n const { theme } = useApp();\n const ratio = Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0));\n const filled = Math.round(ratio * width);\n return (\n <Text>\n <Text color={color ?? theme.accent}>{\"█\".repeat(filled)}</Text>\n <Text color={theme.muted}>{\"░\".repeat(Math.max(0, width - filled))}</Text>\n </Text>\n );\n}\n\n/** Rounded panel with the title drawn into the top border. */\nexport function Panel({\n title,\n width,\n height,\n focused = false,\n right,\n children,\n flexGrow,\n}: {\n title: string;\n width: number;\n height?: number;\n focused?: boolean;\n right?: string;\n children: ReactNode;\n flexGrow?: number;\n}) {\n const { theme } = useApp();\n const color = focused ? theme.focus : theme.border;\n const label = ` ${title} `;\n const extra = right ? ` ${right} ` : \"\";\n const fill = Math.max(0, width - 3 - label.length - extra.length - 1);\n return (\n <Box flexDirection=\"column\" width={width} height={height} flexGrow={flexGrow} flexShrink={0}>\n <Text wrap=\"truncate-end\">\n <Text color={color}>╭─</Text>\n <Text bold color={focused ? theme.accent : undefined}>\n {label}\n </Text>\n <Text color={color}>{\"─\".repeat(fill)}</Text>\n <Text color={theme.muted}>{extra}</Text>\n <Text color={color}>─╮</Text>\n </Text>\n <Box\n borderStyle=\"round\"\n borderTop={false}\n borderColor={color}\n paddingX={1}\n flexDirection=\"column\"\n flexGrow={1}\n width={width}\n overflow=\"hidden\"\n >\n {children}\n </Box>\n </Box>\n );\n}\n\nexport function KeyHints({ hints }: { hints: { key: string; label: string }[] }) {\n const { theme } = useApp();\n return (\n <Text wrap=\"truncate-end\">\n {hints.map((h, i) => (\n <Text key={`${h.key}-${h.label}`}>\n {i > 0 ? \" \" : \" \"}\n <Text color={theme.accent} bold>\n {h.key}\n </Text>\n <Text color={theme.muted}>{` ${h.label}`}</Text>\n </Text>\n ))}\n </Text>\n );\n}\n\nexport function Muted({ children }: { children: ReactNode }) {\n const { theme } = useApp();\n return <Text color={theme.muted}>{children}</Text>;\n}\n\nexport function ErrorLine({ children }: { children: ReactNode }) {\n const { theme } = useApp();\n return <Text color={theme.error}>✘ {children}</Text>;\n}\n\n/** Fixed-width cell: pads or truncates so columns line up. */\nexport function cell(text: string, width: number, align: \"left\" | \"right\" = \"left\"): string {\n if (width <= 0) return \"\";\n const t = text.length > width ? `${text.slice(0, Math.max(0, width - 1))}…` : text;\n return align === \"right\" ? t.padStart(width) : t.padEnd(width);\n}\n","import { hostname } from \"node:os\";\nimport { Box, Text, useAnimation } from \"ink\";\nimport type { ReactNode } from \"react\";\nimport type { ServiceStatus } from \"../../core/service/manager.js\";\nimport type { KeyHint } from \"../context.js\";\nimport { MENU } from \"../router.js\";\nimport type { Theme } from \"../theme.js\";\nimport { GradientText, KeyHints } from \"./basics.js\";\n\nexport const SIDEBAR_WIDTH = 20;\nexport const WIDE = 90;\n\nfunction Clock({ theme }: { theme: Theme }) {\n useAnimation({ interval: 1000 });\n const d = new Date();\n return (\n <Text\n color={theme.muted}\n >{`${String(d.getHours()).padStart(2, \"0\")}:${String(d.getMinutes()).padStart(2, \"0\")}`}</Text>\n );\n}\n\nfunction serviceLabel(theme: Theme, status: ServiceStatus | null | undefined): ReactNode {\n if (!status) return <Text color={theme.muted}>service …</Text>;\n if (!status.available) return <Text color={theme.muted}>service n/a</Text>;\n if (!status.installed) return <Text color={theme.muted}>service ○ not installed</Text>;\n const active = status.activeState === \"active\";\n return (\n <Text>\n <Text color={theme.muted}>service </Text>\n <Text color={active ? theme.success : theme.warning}>{active ? \"●\" : \"○\"}</Text>\n <Text\n color={theme.muted}\n >{` ${status.activeState}${status.outdated ? \" (outdated)\" : \"\"}`}</Text>\n </Text>\n );\n}\n\nexport function Header({\n theme,\n columns,\n service,\n envCount,\n}: {\n theme: Theme;\n columns: number;\n service: ServiceStatus | null | undefined;\n envCount: number;\n}) {\n return (\n <Box width={columns} justifyContent=\"space-between\" paddingX={1}>\n <Box>\n <Text color={theme.accent}>▓▒░ </Text>\n <GradientText>backup-manager</GradientText>\n <Text color={theme.accentAlt}> ░▒▓</Text>\n </Box>\n <Box gap={1}>\n {columns >= 110 && <Text color={theme.muted}>{hostname().slice(0, 24)}</Text>}\n {columns >= 110 && <Text color={theme.border}>·</Text>}\n {serviceLabel(theme, service)}\n <Text color={theme.border}>·</Text>\n <Text color={theme.muted}>{`${envCount} env${envCount === 1 ? \"\" : \"s\"}`}</Text>\n <Text color={theme.border}>·</Text>\n <Clock theme={theme} />\n </Box>\n </Box>\n );\n}\n\nexport function Sidebar({\n theme,\n height,\n selected,\n current,\n focused,\n counters,\n}: {\n theme: Theme;\n height: number;\n selected: number;\n current: number;\n focused: boolean;\n counters: Record<string, number>;\n}) {\n return (\n <Box\n flexDirection=\"column\"\n width={SIDEBAR_WIDTH}\n height={height}\n borderStyle=\"round\"\n borderColor={focused ? theme.focus : theme.border}\n paddingX={1}\n flexShrink={0}\n >\n {MENU.map((item, i) => {\n const isCurrent = i === current;\n const isSelected = focused && i === selected;\n const count = counters[item.route.name];\n const badge = count ? ` ${count}` : \"\";\n const label = `${isCurrent ? \"●\" : \" \"} ${item.label}`.slice(\n 0,\n SIDEBAR_WIDTH - 4 - badge.length,\n );\n return (\n <Text key={item.label} wrap=\"truncate-end\">\n <Text\n color={isCurrent ? theme.accent : undefined}\n bold={isCurrent}\n inverse={isSelected}\n >\n {label.padEnd(SIDEBAR_WIDTH - 4 - badge.length)}\n </Text>\n {badge ? <Text color={theme.info}>{badge}</Text> : null}\n </Text>\n );\n })}\n </Box>\n );\n}\n\nexport function TabBar({\n theme,\n columns,\n current,\n}: {\n theme: Theme;\n columns: number;\n current: number;\n}) {\n return (\n <Box width={columns} paddingX={1}>\n <Text wrap=\"truncate-end\">\n {MENU.map((item, i) => (\n <Text\n key={item.label}\n color={i === current ? theme.accent : theme.muted}\n bold={i === current}\n inverse={i === current}\n >\n {` ${item.key} ${item.label} `}\n </Text>\n ))}\n </Text>\n </Box>\n );\n}\n\nexport function Footer({\n theme,\n columns,\n hints,\n global,\n}: {\n theme: Theme;\n columns: number;\n hints: KeyHint[];\n global: KeyHint[];\n}) {\n return (\n <Box width={columns}>\n <KeyHints hints={[...hints, ...global]} />\n <Text color={theme.muted}> </Text>\n </Box>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { ReactNode } from \"react\";\nimport type { ConfirmOptions, Toast } from \"../context.js\";\nimport type { Theme } from \"../theme.js\";\n\nexport function Modal({\n theme,\n width,\n columns,\n rows,\n title,\n children,\n danger,\n}: {\n theme: Theme;\n width: number;\n columns: number;\n rows: number;\n title: string;\n children: ReactNode;\n danger?: boolean;\n}) {\n const w = Math.min(width, columns - 4);\n return (\n <Box\n position=\"absolute\"\n top={Math.max(1, Math.floor(rows / 4))}\n left={Math.max(0, Math.floor((columns - w) / 2))}\n width={w}\n >\n <Box\n borderStyle=\"double\"\n borderColor={danger ? theme.error : theme.accent}\n flexDirection=\"column\"\n paddingX={2}\n paddingY={0}\n width={w}\n backgroundColor={theme.color ? \"#0f172a\" : undefined}\n >\n <Text bold color={danger ? theme.error : theme.accent}>\n {title}\n </Text>\n {children}\n </Box>\n </Box>\n );\n}\n\nexport function ConfirmBody({\n theme,\n options,\n choice,\n}: {\n theme: Theme;\n options: ConfirmOptions;\n choice: boolean;\n}) {\n return (\n <Box flexDirection=\"column\">\n <Box marginY={1}>\n <Text>{options.message}</Text>\n </Box>\n <Box gap={2}>\n <Text inverse={choice} color={options.danger ? theme.error : theme.accent}>\n {` ${options.confirmLabel ?? \"Yes\"} `}\n </Text>\n <Text inverse={!choice}> Cancel </Text>\n <Text color={theme.muted}>y/n · ←→ · ⏎</Text>\n </Box>\n </Box>\n );\n}\n\nconst HELP: [string, string][] = [\n [\"↑↓ / j k\", \"move in lists\"],\n [\"g G · Home End\", \"first / last\"],\n [\"PgUp PgDn\", \"page\"],\n [\"⏎\", \"open / select\"],\n [\"Esc\", \"back\"],\n [\"Tab\", \"switch sidebar / content (next field in forms)\"],\n [\"1–9\", \"jump to a menu entry\"],\n [\"n · e · s\", \"new backup · environments · service\"],\n [\"Ctrl-S\", \"save a form\"],\n [\"?\", \"this help\"],\n [\"q\", \"quit (jobs keep running)\"],\n];\n\nexport function HelpBody({ theme }: { theme: Theme }) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {HELP.map(([key, label]) => (\n <Box key={key}>\n <Box width={18}>\n <Text color={theme.accent} bold>\n {key}\n </Text>\n </Box>\n <Text>{label}</Text>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text color={theme.muted}>\n Backups started here run detached: closing the UI or SSH does not stop them.\n </Text>\n </Box>\n <Text color={theme.muted}>press any key to close</Text>\n </Box>\n );\n}\n\nexport function Toasts({ theme, toasts, now }: { theme: Theme; toasts: Toast[]; now: number }) {\n if (toasts.length === 0) return null;\n const color = {\n info: theme.info,\n success: theme.success,\n warning: theme.warning,\n error: theme.error,\n };\n const icon = { info: \"ℹ\", success: \"✔\", warning: \"⚠\", error: \"✘\" };\n return (\n <Box position=\"absolute\" bottom={1} right={1} flexDirection=\"column\" alignItems=\"flex-end\">\n {toasts.map((t) => (\n <Box key={t.id} borderStyle=\"round\" borderColor={color[t.kind]} paddingX={1}>\n <Text color={color[t.kind]} dimColor={now - t.createdAt > 2400}>\n {`${icon[t.kind]} ${t.text}`}\n </Text>\n </Box>\n ))}\n </Box>\n );\n}\n\nexport function TooSmall({\n theme,\n columns,\n rows,\n}: {\n theme: Theme;\n columns: number;\n rows: number;\n}) {\n return (\n <Box\n flexDirection=\"column\"\n width={columns}\n height={rows}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Text color={theme.warning}>Terminal too small</Text>\n <Text color={theme.muted}>{`${columns}×${rows} — needs at least 60×16`}</Text>\n <Text color={theme.muted}>resize, or press q to quit</Text>\n </Box>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface Polled<T> {\n data: T | undefined;\n error: string | null;\n loading: boolean;\n refresh(): void;\n}\n\n/** Calls `fn` now and every `intervalMs`; errors are captured, never thrown. */\nexport function usePolling<T>(\n fn: () => Promise<T>,\n intervalMs: number,\n deps: unknown[] = [],\n): Polled<T> {\n const [data, setData] = useState<T>();\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const fnRef = useRef(fn);\n fnRef.current = fn;\n const alive = useRef(true);\n const inflight = useRef(false);\n\n const run = useCallback(async () => {\n if (inflight.current) return;\n inflight.current = true;\n try {\n const value = await fnRef.current();\n if (alive.current) {\n setData(value);\n setError(null);\n }\n } catch (e) {\n if (alive.current) setError((e as Error).message);\n } finally {\n inflight.current = false;\n if (alive.current) setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n alive.current = true;\n setLoading(true);\n void run();\n const timer = intervalMs > 0 ? setInterval(() => void run(), intervalMs) : null;\n return () => {\n alive.current = false;\n if (timer) clearInterval(timer);\n };\n }, [run, intervalMs, ...deps]);\n\n return {\n data,\n error,\n loading,\n refresh: () => {\n setLoading(true);\n void run();\n },\n };\n}\n","import { type Key, useInput } from \"ink\";\nimport { useEffect, useState } from \"react\";\n\nexport const isUp = (input: string, key: Key) => key.upArrow || input === \"k\";\nexport const isDown = (input: string, key: Key) => key.downArrow || input === \"j\";\n\nexport interface ListNavOptions {\n isActive: boolean;\n /** Use an external index state (e.g. remembered across screens). */\n state?: [number, (v: number | ((p: number) => number)) => void];\n page?: number;\n initial?: number;\n onSelect?: (index: number) => void;\n}\n\n/** Vim-ish list navigation: ↑↓/jk, g/G, Home/End, PgUp/PgDn, ⏎. */\nexport function useListNav(count: number, options: ListNavOptions) {\n const own = useState(options.initial ?? 0);\n const [index, setIndex] = options.state ?? own;\n const page = Math.max(1, options.page ?? 10);\n useEffect(() => {\n if (index > count - 1) setIndex(Math.max(0, count - 1));\n }, [count, index, setIndex]);\n useInput(\n (input, key) => {\n if (count === 0) return;\n if (isUp(input, key)) setIndex((i) => Math.max(0, i - 1));\n else if (isDown(input, key)) setIndex((i) => Math.min(count - 1, i + 1));\n else if (key.pageUp) setIndex((i) => Math.max(0, i - page));\n else if (key.pageDown) setIndex((i) => Math.min(count - 1, i + page));\n else if (key.home || input === \"g\") setIndex(0);\n else if (key.end || input === \"G\") setIndex(count - 1);\n else if (key.return) options.onSelect?.(Math.min(index, count - 1));\n },\n { isActive: options.isActive },\n );\n return { index: Math.min(index, Math.max(0, count - 1)), setIndex };\n}\n\n/** Split a comma list, ignoring commas inside `{…}` glob braces. */\nexport function splitList(text: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let current = \"\";\n for (const ch of text) {\n if (ch === \"{\") depth++;\n if (ch === \"}\") depth = Math.max(0, depth - 1);\n if (ch === \",\" && depth === 0) {\n out.push(current);\n current = \"\";\n } else current += ch;\n }\n out.push(current);\n return out.map((s) => s.trim()).filter(Boolean);\n}\n\nexport const joinList = (items: readonly string[]) => items.join(\", \");\n","import { Box, Text } from \"ink\";\nimport { type ReactNode, useRef } from \"react\";\nimport { useApp } from \"../context.js\";\n\n/** Keeps `index` visible inside a window of `height` rows; returns the first visible row. */\nexport function useWindowOffset(index: number, height: number, total: number): number {\n const offset = useRef(0);\n const h = Math.max(1, height);\n if (index < offset.current) offset.current = index;\n if (index >= offset.current + h) offset.current = index - h + 1;\n offset.current = Math.max(0, Math.min(offset.current, Math.max(0, total - h)));\n return offset.current;\n}\n\nfunction Scrollbar({ height, offset, total }: { height: number; offset: number; total: number }) {\n const { theme } = useApp();\n if (total <= height) return null;\n const size = Math.max(1, Math.round((height / total) * height));\n const start = Math.min(\n height - size,\n Math.round((offset / Math.max(1, total - height)) * (height - size)),\n );\n return (\n <Box flexDirection=\"column\" width={1} marginLeft={1}>\n {Array.from({ length: height }, (_, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: fixed positional gutter\n <Text key={i} color={i >= start && i < start + size ? theme.accent : theme.border}>\n {i >= start && i < start + size ? \"┃\" : \"│\"}\n </Text>\n ))}\n </Box>\n );\n}\n\n/** Virtualized single-line rows with a selection and a scrollbar gutter. */\nexport function ScrollList<T>({\n items,\n index,\n height,\n render,\n empty,\n selectable = true,\n}: {\n items: readonly T[];\n index: number;\n height: number;\n render: (item: T, selected: boolean, i: number) => ReactNode;\n empty?: ReactNode;\n selectable?: boolean;\n}) {\n const { theme } = useApp();\n const h = Math.max(1, height);\n const offset = useWindowOffset(index, h, items.length);\n if (items.length === 0)\n return (\n <Box height={1}>\n {typeof empty === \"string\" ? <Text color={theme.muted}>{empty}</Text> : empty}\n </Box>\n );\n const visible = items.slice(offset, offset + h);\n return (\n <Box flexDirection=\"row\">\n <Box flexDirection=\"column\" flexGrow={1}>\n {visible.map((item, i) => {\n const at = offset + i;\n const selected = selectable && at === index;\n return (\n <Box key={at}>\n <Text color={theme.accent}>{selected ? \"❯ \" : \" \"}</Text>\n <Box flexGrow={1}>{render(item, selected, at)}</Box>\n </Box>\n );\n })}\n </Box>\n <Scrollbar height={Math.min(h, items.length)} offset={offset} total={items.length} />\n </Box>\n );\n}\n\n/**\n * Scrollable block of one-row lines using `overflow=\"hidden\"` + `contentOffsetY`;\n * the caller owns `offset` (e.g. to follow a live log).\n */\nexport function ScrollView({\n lines,\n height,\n offset,\n}: {\n lines: ReactNode[];\n height: number;\n offset: number;\n}) {\n const h = Math.max(1, height);\n const max = Math.max(0, lines.length - h);\n const y = Math.max(0, Math.min(offset, max));\n return (\n <Box flexDirection=\"row\" height={h}>\n <Box flexDirection=\"column\" flexGrow={1} height={h} overflow=\"hidden\" contentOffsetY={y}>\n {lines.map((line, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: lines are positional\n <Box key={i} height={1} flexShrink={0}>\n {line}\n </Box>\n ))}\n </Box>\n <Scrollbar height={h} offset={y} total={lines.length} />\n </Box>\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport { formatAge, formatBytes, formatDateTime, formatDuration } from \"../../core/format.js\";\nimport { cell, Muted, Panel, StatusText } from \"../components/basics.js\";\nimport { ScrollList, ScrollView } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive, useSessionState } from \"../context.js\";\nimport { usePolling } from \"../hooks/usePolling.js\";\nimport { isDown, isUp, useListNav } from \"../keys.js\";\n\nconst FILTERS = [\"all\", \"complete\", \"partial\", \"incomplete\"] as const;\n\nexport function Backups({ envName }: { envName?: string }) {\n const { services, config, width, height, navigate, theme } = useApp();\n const active = useScreenActive();\n const envs = config?.environments ?? [];\n const [envIndex, setEnvIndex] = useSessionState(\n `backups:env:${envName ?? \"\"}`,\n Math.max(\n 0,\n envs.findIndex((e) => e.name === envName),\n ),\n );\n const [filter, setFilter] = useSessionState(\"backups:filter\", 0);\n const selection = useSessionState(`backups:index:${envIndex}:${filter}`, 0);\n const env = envs[Math.min(envIndex, envs.length - 1)];\n const status = FILTERS[filter];\n const backups = usePolling(\n () =>\n config && env\n ? services.backups(config, env.name, status === \"all\" ? {} : { status })\n : Promise.resolve([]),\n 3000,\n [config, env?.name, status],\n );\n const list = backups.data ?? [];\n const nav = useListNav(list.length, {\n isActive: active,\n state: selection,\n onSelect: (i) => {\n const b = list[i];\n if (b && env) navigate({ name: \"backup-detail\", env: env.name, id: b.id });\n },\n });\n useHints(\n [\n { key: \"⏎\", label: \"details\" },\n { key: \"←→\", label: \"environment\" },\n { key: \"f\", label: `filter: ${status}` },\n ],\n [status],\n );\n useInput(\n (input, key) => {\n if (key.leftArrow) setEnvIndex((i) => (i - 1 + envs.length) % Math.max(1, envs.length));\n else if (key.rightArrow) setEnvIndex((i) => (i + 1) % Math.max(1, envs.length));\n else if (input === \"f\") setFilter((f) => (f + 1) % FILTERS.length);\n },\n { isActive: active },\n );\n const total = list.reduce((s, b) => s + b.size, 0);\n return (\n <Panel\n title=\"Backups\"\n width={width}\n height={height}\n focused={active}\n right={`${list.length} · ${formatBytes(total)}`}\n >\n <Box marginBottom={1}>\n <Text wrap=\"truncate-end\">\n {envs.map((e, i) => (\n <Text\n key={e.name}\n inverse={i === envIndex}\n color={i === envIndex ? theme.accent : theme.muted}\n >\n {` ${e.name} `}\n </Text>\n ))}\n <Text color={theme.muted}>{` filter: ${status}`}</Text>\n </Text>\n </Box>\n {envs.length === 0 ? (\n <Muted>No environments yet.</Muted>\n ) : (\n <ScrollList\n items={list}\n index={nav.index}\n height={height - 4}\n empty={backups.loading ? \"loading…\" : \"no backups\"}\n render={(b) => (\n <Text wrap=\"truncate-end\">\n <StatusText status={b.status} label={cell(b.status, 11)} />\n {` ${cell(b.id, 18)}`}\n {cell(formatBytes(b.size), 10, \"right\")}\n <Text color={theme.muted}>\n {cell(\n ` ${b.itemCount} items${b.failedCount ? `, ${b.failedCount} failed` : \"\"}`,\n 22,\n )}\n </Text>\n <Text color={theme.muted}>{formatAge(b.createdAt)}</Text>\n </Text>\n )}\n />\n )}\n </Panel>\n );\n}\n\nexport function BackupDetail({ envName, id }: { envName: string; id: string }) {\n const { services, config, width, height, theme } = useApp();\n const active = useScreenActive();\n const [offset, setOffset] = useState(0);\n const backup = usePolling(\n () => (config ? services.backup(config, envName, id) : Promise.resolve(null)),\n 0,\n [config, envName, id],\n );\n useHints([\n { key: \"↑↓\", label: \"scroll\" },\n { key: \"esc\", label: \"back\" },\n ]);\n const b = backup.data;\n const lines: React.ReactNode[] = [];\n if (b) {\n const m = b.manifest;\n lines.push(\n <Text>\n <Text color={theme.muted}>{cell(\"status\", 12)}</Text>\n <StatusText status={b.status} />\n </Text>,\n <Text>\n <Text color={theme.muted}>{cell(\"created\", 12)}</Text>\n {formatDateTime(b.createdAt)}\n <Text color={theme.muted}>{` (${formatAge(b.createdAt)})`}</Text>\n </Text>,\n <Text>\n <Text color={theme.muted}>{cell(\"size\", 12)}</Text>\n {formatBytes(b.size)}\n </Text>,\n <Text wrap=\"truncate-end\">\n <Text color={theme.muted}>{cell(\"path\", 12)}</Text>\n {b.dir}\n </Text>,\n );\n if (m?.trigger || m?.jobId) {\n lines.push(\n <Text>\n <Text color={theme.muted}>{cell(\"trigger\", 12)}</Text>\n {`${m.trigger ?? \"—\"}${m.jobId ? ` · job ${m.jobId}` : \"\"}`}\n </Text>,\n );\n }\n lines.push(\n <Text> </Text>,\n <Text bold color={theme.accent}>\n Items\n </Text>,\n );\n if (!m)\n lines.push(<Text color={theme.warning}>No manifest: this backup was interrupted.</Text>);\n for (const item of m?.items ?? []) {\n lines.push(\n <Text wrap=\"truncate-end\">\n <StatusText status={item.status} label={cell(`${item.kind} ${item.name}`, 26)} />\n {cell(formatBytes(item.size), 10, \"right\")}\n <Text\n color={theme.muted}\n >{` ${cell(formatDuration(item.durationMs), 8)} ${item.detail ?? \"\"}`}</Text>\n </Text>,\n );\n if (item.file)\n lines.push(\n <Text\n color={theme.muted}\n wrap=\"truncate-end\"\n >{` ${item.file} sha256 ${item.sha256?.slice(0, 16)}…`}</Text>,\n );\n if (item.error)\n lines.push(<Text color={theme.error} wrap=\"truncate-end\">{` ✘ ${item.error}`}</Text>);\n for (const w of item.warnings ?? [])\n lines.push(<Text color={theme.warning} wrap=\"truncate-end\">{` ! ${w}`}</Text>);\n }\n }\n const viewHeight = height - 2;\n useInput(\n (input, key) => {\n const max = Math.max(0, lines.length - viewHeight);\n if (isUp(input, key)) setOffset((o) => Math.max(0, o - 1));\n else if (isDown(input, key)) setOffset((o) => Math.min(max, o + 1));\n else if (key.pageUp) setOffset((o) => Math.max(0, o - viewHeight));\n else if (key.pageDown) setOffset((o) => Math.min(max, o + viewHeight));\n else if (input === \"g\" || key.home) setOffset(0);\n else if (input === \"G\" || key.end) setOffset(max);\n },\n { isActive: active },\n );\n return (\n <Panel title={`Backup · ${envName} · ${id}`} width={width} height={height} focused={active}>\n {backup.loading && !b ? (\n <Muted>loading…</Muted>\n ) : !b ? (\n <Text color={theme.error}>backup not found</Text>\n ) : (\n <ScrollView lines={lines} height={viewHeight} offset={offset} />\n )}\n </Panel>\n );\n}\n","import { watch } from \"node:fs\";\nimport path from \"node:path\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { stateDir } from \"../../core/config/defaults.js\";\nimport type { Config } from \"../../core/config/schema.js\";\nimport type { JobEvent } from \"../../core/jobs/events.js\";\nimport { eventsFile } from \"../../core/jobs/store.js\";\nimport type { Services } from \"../../core/services.js\";\n\nconst MAX_EVENTS = 5000;\n\n/** Tails a job's NDJSON log: fs.watch when possible, polling as a fallback. */\nexport function useJobEvents(\n services: Services,\n config: Config | null,\n id: string | null,\n pollMs = 1000,\n): JobEvent[] {\n const [events, setEvents] = useState<JobEvent[]>([]);\n const offset = useRef(0);\n useEffect(() => {\n setEvents([]);\n offset.current = 0;\n if (!config || !id) return;\n let alive = true;\n let busy = false;\n const read = async () => {\n if (busy) return;\n busy = true;\n try {\n const r = await services.jobEvents(config, id, offset.current);\n if (!alive) return;\n offset.current = r.offset;\n if (r.events.length) setEvents((prev) => [...prev, ...r.events].slice(-MAX_EVENTS));\n } finally {\n busy = false;\n }\n };\n void read();\n const file = eventsFile(stateDir(config), id);\n let watcher: ReturnType<typeof watch> | null = null;\n try {\n watcher = watch(path.dirname(file), (_e, name) => {\n if (!name || name.toString() === path.basename(file)) void read();\n });\n watcher.on(\"error\", () => {});\n } catch {\n watcher = null;\n }\n const timer = setInterval(() => void read(), pollMs);\n return () => {\n alive = false;\n watcher?.close();\n clearInterval(timer);\n };\n }, [services, config, id, pollMs]);\n return events;\n}\n\nexport interface ItemProgress {\n environment: string;\n kind: \"database\" | \"project\";\n name: string;\n status: \"pending\" | \"running\" | \"success\" | \"failed\";\n bytes: number;\n files?: number;\n size?: number;\n durationMs?: number;\n error?: string;\n index: number;\n total: number;\n startedAt?: number;\n}\n\n/** Fold events into per-item progress, in the order items started. */\nexport function itemProgress(events: JobEvent[]): ItemProgress[] {\n const items = new Map<string, ItemProgress>();\n const k = (e: { environment: string; kind: string; name: string }) =>\n `${e.environment}\\u0000${e.kind}\\u0000${e.name}`;\n for (const e of events) {\n if (e.type === \"item-start\") {\n items.set(k(e), {\n environment: e.environment,\n kind: e.kind,\n name: e.name,\n status: \"running\",\n bytes: 0,\n index: e.index,\n total: e.total,\n startedAt: Date.parse(e.ts),\n });\n } else if (e.type === \"item-progress\") {\n const item = items.get(k(e));\n if (item) {\n item.bytes = e.bytes;\n if (e.files !== undefined) item.files = e.files;\n }\n } else if (e.type === \"item-done\") {\n const item = items.get(k(e));\n if (item) {\n item.status = e.status;\n item.size = e.size;\n item.durationMs = e.durationMs;\n if (e.error) item.error = e.error;\n }\n }\n }\n return [...items.values()];\n}\n\n/** Overall fraction done for a running job (items done / items known). */\nexport function jobFraction(items: ItemProgress[]): { done: number; total: number } {\n const byEnv = new Map<string, number>();\n for (const i of items) byEnv.set(i.environment, i.total);\n const total = [...byEnv.values()].reduce((s, n) => s + n, 0);\n return {\n done: items.filter((i) => i.status === \"success\" || i.status === \"failed\").length,\n total,\n };\n}\n","import { Box, Text, useInput } from \"ink\";\nimport type { BackupInfo } from \"../../core/backup/catalog.js\";\nimport { formatAge, formatBytes, formatDuration } from \"../../core/format.js\";\nimport type { JobRecord } from \"../../core/jobs/store.js\";\nimport type { EnvironmentSummary } from \"../../core/services.js\";\nimport { cell, Muted, Panel, ProgressBar, Spinner, StatusText } from \"../components/basics.js\";\nimport { ScrollList } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { type ItemProgress, itemProgress, jobFraction } from \"../hooks/useJobEvents.js\";\nimport { usePolling } from \"../hooks/usePolling.js\";\nimport { useListNav } from \"../keys.js\";\n\nexport function nextLabel(date: Date | null, now = new Date()): string {\n if (!date) return \"—\";\n const hhmm = `${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}`;\n if (date.getTime() - now.getTime() < 86_400_000) return hhmm;\n return `${date.getMonth() + 1}/${date.getDate()} ${hhmm}`;\n}\n\nfunction EnvRow({ s, width }: { s: EnvironmentSummary; width: number }) {\n const { theme } = useApp();\n const counts = [s.databases ? `${s.databases} db` : \"\", s.projects ? `${s.projects} proj` : \"\"]\n .filter(Boolean)\n .join(\" · \");\n return (\n <Text wrap=\"truncate-end\">\n <Text bold>{cell(s.name, Math.min(16, Math.max(8, width - 60)))}</Text>\n <Text color={theme.muted}>{cell(counts || \"empty\", 16)}</Text>\n {cell(`${s.backups} bkp`, 8, \"right\")}\n {cell(formatBytes(s.totalSize), 10, \"right\")}\n {\" \"}\n {s.runningPid ? (\n <Text color={theme.info}>{cell(\"● running\", 10)}</Text>\n ) : s.last ? (\n <StatusText\n status={s.last.status}\n label={cell(formatAge(s.last.createdAt).replace(\" ago\", \"\"), 8)}\n />\n ) : (\n <Text color={theme.muted}>{cell(\"— never\", 10)}</Text>\n )}\n <Text color={theme.muted}>{` ⏱ ${nextLabel(s.nextRun)}`}</Text>\n </Text>\n );\n}\n\nfunction RunningRow({\n job,\n items,\n width,\n}: {\n job: JobRecord;\n items: ItemProgress[];\n width: number;\n}) {\n const { theme } = useApp();\n const current = items.filter((i) => i.status === \"running\").at(-1);\n const { done, total } = jobFraction(items);\n const started = job.startedAt ? Date.now() - Date.parse(job.startedAt) : 0;\n const label = current\n ? `${current.environment} · ${current.kind} ${current.name}`\n : job.targets.map((t) => t.environment).join(\", \");\n const barWidth = Math.max(6, Math.min(16, width - 60));\n return (\n <Text wrap=\"truncate-end\">\n <Spinner />\n {` ${cell(label, Math.max(12, width - barWidth - 30))} `}\n <ProgressBar value={total ? done / total : 0} width={barWidth} />\n {` ${cell(`${done}/${total || \"?\"}`, 5)} `}\n <Text color={theme.muted}>{`${cell(formatDuration(started), 7)} ${job.trigger}`}</Text>\n </Text>\n );\n}\n\nfunction RecentRow({ b }: { b: BackupInfo }) {\n const { theme } = useApp();\n return (\n <Text wrap=\"truncate-end\">\n <StatusText status={b.status} label={cell(b.environment, 14)} />\n {` ${cell(b.id, 19)} `}\n <Text color={theme.muted}>{cell(b.status, 10)}</Text>\n {cell(formatBytes(b.size), 10, \"right\")}\n <Text color={theme.muted}>{` ${formatAge(b.createdAt)}`}</Text>\n </Text>\n );\n}\n\nexport function Dashboard() {\n const { services, config, width, height, navigate, theme } = useApp();\n const active = useScreenActive();\n const summaries = usePolling(\n () => (config ? services.summaries(config) : Promise.resolve([])),\n 2000,\n [config],\n );\n const jobs = usePolling(() => (config ? services.jobs(config, 30) : Promise.resolve([])), 1000, [\n config,\n ]);\n const runningJobs = (jobs.data ?? []).filter(\n (j) => j.status === \"running\" || j.status === \"queued\",\n );\n const progress = usePolling(\n () =>\n config\n ? Promise.all(\n runningJobs.map(async (j) => ({\n id: j.id,\n items: itemProgress((await services.jobEvents(config, j.id)).events),\n })),\n )\n : Promise.resolve([]),\n 1000,\n [config, runningJobs.map((j) => j.id).join()],\n );\n const recent = usePolling(\n () => (config ? services.recentBackups(config, 20) : Promise.resolve([])),\n 3000,\n [config],\n );\n const envs = summaries.data ?? [];\n const nav = useListNav(envs.length, {\n isActive: active,\n onSelect: (i) => {\n const env = envs[i];\n if (env) navigate({ name: \"backups\", env: env.name });\n },\n });\n useHints(\n [\n { key: \"↑↓\", label: \"move\" },\n { key: \"⏎\", label: \"backups\" },\n { key: \"r\", label: \"run now\" },\n { key: \"n\", label: \"new backup\" },\n { key: \"e\", label: \"environments\" },\n ],\n [],\n );\n useRunNow(active, () => envs[nav.index]?.name);\n\n if (!config) return null;\n if (config.environments.length === 0) {\n return (\n <Panel title=\"Welcome\" width={width} height={height}>\n <Text>No environments yet.</Text>\n <Muted>Press e to open Environments, then a to add one.</Muted>\n </Panel>\n );\n }\n const envHeight = Math.min(envs.length || 1, Math.max(3, Math.floor((height - 9) / 2)));\n const runHeight = Math.max(1, Math.min(runningJobs.length || 1, 4));\n const recentHeight = Math.max(1, height - envHeight - runHeight - 6);\n const inner = width - 4;\n return (\n <Box flexDirection=\"column\">\n <Panel\n title=\"Environments\"\n width={width}\n focused={active}\n right={summaries.error ?? undefined}\n >\n <ScrollList\n items={envs}\n index={nav.index}\n height={envHeight}\n render={(s) => <EnvRow s={s} width={inner - 3} />}\n empty={summaries.loading ? \"loading…\" : \"no environments\"}\n selectable={active}\n />\n </Panel>\n <Panel\n title=\"Running\"\n width={width}\n right={runningJobs.length ? `${runningJobs.length}` : undefined}\n >\n {runningJobs.length === 0 ? (\n <Text color={theme.muted}>idle</Text>\n ) : (\n runningJobs\n .slice(0, runHeight)\n .map((j) => (\n <RunningRow\n key={j.id}\n job={j}\n items={progress.data?.find((p) => p.id === j.id)?.items ?? []}\n width={inner}\n />\n ))\n )}\n </Panel>\n <Panel title=\"Recent backups\" width={width}>\n {(recent.data ?? []).length === 0 ? (\n <Text color={theme.muted}>{recent.loading ? \"loading…\" : \"no backups yet\"}</Text>\n ) : (\n (recent.data ?? [])\n .slice(0, recentHeight)\n .map((b) => <RecentRow key={`${b.environment}/${b.id}`} b={b} />)\n )}\n </Panel>\n </Box>\n );\n}\n\n/** `r` starts a detached backup of the selected environment and opens its live view. */\nexport function useRunNow(active: boolean, envName: () => string | undefined) {\n const { services, config, navigate, toast, confirm } = useApp();\n useInput(\n (input) => {\n if (input !== \"r\" || !config) return;\n const name = envName();\n if (!name) return;\n void (async () => {\n if (\n !(await confirm({\n title: \"Run backup now\",\n message: `Back up every database and project of '${name}' now?`,\n confirmLabel: \"Run\",\n }))\n )\n return;\n try {\n const job = await services.startBackup(config, [{ environment: name }]);\n toast(`backup of ${name} started`, \"success\");\n navigate({ name: \"job-live\", id: job.id });\n } catch (error) {\n toast((error as Error).message, \"error\");\n }\n })();\n },\n { isActive: active },\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport { cell, Panel, Spinner } from \"../components/basics.js\";\nimport { ScrollView } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { usePolling } from \"../hooks/usePolling.js\";\nimport { isDown, isUp } from \"../keys.js\";\n\nexport function Doctor() {\n const { services, width, height, theme } = useApp();\n const active = useScreenActive();\n const report = usePolling(() => services.doctor({ db: true }), 0);\n const [offset, setOffset] = useState(0);\n useHints([\n { key: \"r\", label: \"re-run\" },\n { key: \"↑↓\", label: \"scroll\" },\n ]);\n const color = { ok: theme.success, warn: theme.warning, fail: theme.error };\n const icon = { ok: \"✔\", warn: \"!\", fail: \"✘\" };\n const lines: React.ReactNode[] = [];\n let group = \"\";\n for (const c of report.data?.checks ?? []) {\n if (c.group !== group) {\n if (group) lines.push(<Text> </Text>);\n group = c.group;\n lines.push(\n <Text bold color={theme.accent}>\n {group}\n </Text>,\n );\n }\n lines.push(\n <Text wrap=\"truncate-end\">\n <Text color={color[c.status]}>{` ${icon[c.status]} `}</Text>\n {cell(c.name, 22)}\n <Text color={c.status === \"ok\" ? theme.muted : color[c.status]}>{c.detail}</Text>\n </Text>,\n );\n }\n const viewHeight = height - 4;\n useInput(\n (input, key) => {\n if (input === \"r\") report.refresh();\n else if (isUp(input, key)) setOffset((o) => Math.max(0, o - 1));\n else if (isDown(input, key))\n setOffset((o) => Math.min(Math.max(0, lines.length - viewHeight), o + 1));\n },\n { isActive: active },\n );\n const fails = report.data?.checks.filter((c) => c.status === \"fail\").length ?? 0;\n const warns = report.data?.checks.filter((c) => c.status === \"warn\").length ?? 0;\n return (\n <Panel title=\"Doctor\" width={width} height={height} focused={active}>\n <Box marginBottom={1}>\n {report.loading ? (\n <Spinner label=\"checking config, tools, paths, databases and the service…\" />\n ) : (\n <Text color={fails ? theme.error : warns ? theme.warning : theme.success}>\n {fails\n ? `✘ ${fails} problem(s), ${warns} warning(s)`\n : warns\n ? `! all good, ${warns} warning(s)`\n : \"✔ all good\"}\n </Text>\n )}\n </Box>\n <ScrollView lines={lines} height={viewHeight} offset={offset} />\n </Panel>\n );\n}\n","import { Text, useInput, usePaste } from \"ink\";\nimport { useRef, useState } from \"react\";\nimport { useApp } from \"../context.js\";\n\nexport interface TextFieldProps {\n value: string;\n onChange(value: string): void;\n focus: boolean;\n mask?: boolean;\n placeholder?: string;\n width?: number;\n}\n\n/** Controlled single-line input: ←→, Home/End, Ctrl-A/E, Ctrl-U, Backspace/Delete, paste. */\nexport function TextField({ value, onChange, focus, mask, placeholder, width }: TextFieldProps) {\n const { theme } = useApp();\n // Keys can arrive faster than React re-renders, so edits apply to the live value in a ref\n // rather than to the (possibly stale) props of the last render.\n const live = useRef({ value, cursor: value.length, emitted: value });\n if (value !== live.current.emitted) {\n live.current = { value, cursor: Math.min(live.current.cursor, value.length), emitted: value };\n }\n const [, rerender] = useState(0);\n const commit = (next: string, cursor: number) => {\n const changed = next !== live.current.value;\n live.current = { value: next, cursor, emitted: changed ? next : live.current.emitted };\n if (changed) onChange(next);\n rerender((n) => n + 1);\n };\n const insert = (text: string) => {\n const clean = text.replace(/[\\r\\n]+/g, \" \");\n if (!clean) return;\n const { value: v, cursor } = live.current;\n const at = Math.min(cursor, v.length);\n commit(v.slice(0, at) + clean + v.slice(at), at + clean.length);\n };\n\n useInput(\n (input, key) => {\n const { value: v, cursor } = live.current;\n const at = Math.min(cursor, v.length);\n if (key.leftArrow) commit(v, Math.max(0, at - 1));\n else if (key.rightArrow) commit(v, Math.min(v.length, at + 1));\n else if (key.home || (key.ctrl && input === \"a\")) commit(v, 0);\n else if (key.end || (key.ctrl && input === \"e\")) commit(v, v.length);\n else if (key.ctrl && input === \"u\") commit(v.slice(at), 0);\n else if (key.backspace || key.delete) {\n if (at > 0) commit(v.slice(0, at - 1) + v.slice(at), at - 1);\n } else if (\n input &&\n !key.ctrl &&\n !key.meta &&\n !key.tab &&\n !key.return &&\n !key.escape &&\n !key.upArrow &&\n !key.downArrow\n ) {\n insert(input);\n }\n },\n { isActive: focus },\n );\n usePaste(insert, { isActive: focus });\n\n const cursor = live.current.cursor;\n value = live.current.value;\n const shown = mask ? \"•\".repeat(value.length) : value;\n const max = width && width > 1 ? width - 1 : Number.POSITIVE_INFINITY;\n const at = Math.min(cursor, shown.length);\n const start =\n shown.length > max ? Math.max(0, Math.min(at - Math.floor(max / 2), shown.length - max)) : 0;\n const visible = shown.slice(start, start + max);\n const rel = at - start;\n\n if (!focus) {\n if (!value) return <Text color={theme.muted}>{placeholder ?? \"\"}</Text>;\n return <Text wrap=\"truncate-end\">{visible}</Text>;\n }\n if (!value && placeholder) {\n return (\n <Text>\n <Text inverse>{placeholder[0] ?? \" \"}</Text>\n <Text color={theme.muted}>{placeholder.slice(1)}</Text>\n </Text>\n );\n }\n return (\n <Text>\n {visible.slice(0, rel)}\n <Text inverse>{visible[rel] ?? \" \"}</Text>\n {visible.slice(rel + 1)}\n </Text>\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { type ReactNode, useEffect, useRef, useState } from \"react\";\nimport { useApp, useCaptureKeys } from \"../context.js\";\nimport { cell } from \"./basics.js\";\nimport { TextField } from \"./TextField.js\";\n\nexport type FieldValue = string | boolean;\nexport type Values = Record<string, FieldValue>;\n\nexport type Field =\n | {\n kind: \"text\" | \"password\" | \"number\";\n key: string;\n label: string;\n placeholder?: string;\n hint?: ReactNode;\n error?: string;\n }\n | {\n kind: \"select\";\n key: string;\n label: string;\n options: { label: string; value: string }[];\n hint?: ReactNode;\n error?: string;\n }\n | { kind: \"toggle\"; key: string; label: string; hint?: ReactNode; error?: string }\n | {\n kind: \"action\";\n key: string;\n label: string;\n /** Text shown after the label (e.g. a path). */\n detail?: string;\n onPress(): void;\n onDelete?(): void;\n hint?: ReactNode;\n error?: string;\n }\n | { kind: \"heading\"; key: string; label: string };\n\nexport interface FormProps {\n id: string;\n fields: Field[];\n values: Values;\n onChange(values: Values): void;\n /** Called with the latest values (which may be newer than the last render). */\n onSubmit(values: Values): void;\n onCancel(): void;\n isActive: boolean;\n labelWidth?: number;\n width: number;\n /** Rows available; the form scrolls to keep the focused field visible. */\n height?: number;\n initialFocus?: string;\n}\n\nconst focusable = (f: Field) => f.kind !== \"heading\";\n\n/**\n * Keyboard form: Tab/↓ next, Shift-Tab/↑ previous, Space/←→ toggles and cycles selects,\n * ⏎ on an action presses it (on a text field it moves next), `d`/Delete on an action\n * deletes, Ctrl-S saves, Esc cancels.\n */\nexport function Form(props: FormProps) {\n const { theme } = useApp();\n const { fields, values, isActive } = props;\n // Several keys may arrive before the parent re-renders; merge into the latest values.\n const latest = useRef(values);\n latest.current = values;\n const onChange = (next: Values) => {\n latest.current = next;\n props.onChange(next);\n };\n const set = (key: string, value: FieldValue) => onChange({ ...latest.current, [key]: value });\n const focusables = fields.filter(focusable);\n const [focusKey, setFocusKey] = useState(props.initialFocus ?? focusables[0]?.key ?? \"\");\n useCaptureKeys(props.id, isActive);\n\n useEffect(() => {\n if (!focusables.some((f) => f.key === focusKey) && focusables[0])\n setFocusKey(focusables[0].key);\n }, [focusables, focusKey]);\n\n const at = Math.max(\n 0,\n focusables.findIndex((f) => f.key === focusKey),\n );\n const current = focusables[at];\n const move = (delta: number) => {\n const next = focusables[(at + delta + focusables.length) % focusables.length];\n if (next) setFocusKey(next.key);\n };\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === \"s\") return props.onSubmit(latest.current);\n if (key.escape) return props.onCancel();\n if (key.tab) return move(key.shift ? -1 : 1);\n if (key.downArrow) return move(1);\n if (key.upArrow) return move(-1);\n if (!current) return;\n if (\n current.kind === \"toggle\" &&\n (input === \" \" || key.leftArrow || key.rightArrow || key.return)\n ) {\n set(current.key, !latest.current[current.key]);\n } else if (current.kind === \"select\" && (input === \" \" || key.leftArrow || key.rightArrow)) {\n const options = current.options;\n const i = options.findIndex((o) => o.value === latest.current[current.key]);\n const next = options[(i + (key.leftArrow ? -1 : 1) + options.length) % options.length];\n if (next) set(current.key, next.value);\n } else if (current.kind === \"action\" && key.return) {\n current.onPress();\n } else if (current.kind === \"action\" && current.onDelete && (input === \"d\" || key.delete)) {\n current.onDelete();\n } else if (key.return) {\n move(1);\n }\n },\n { isActive },\n );\n\n const labelWidth =\n props.labelWidth ?? Math.min(22, Math.max(10, ...fields.map((f) => f.label.length + 1)));\n const inputWidth = Math.max(10, props.width - labelWidth - 4);\n const rows: { node: ReactNode; lines: number }[] = [];\n let focusRow = 0;\n for (const field of fields) {\n const focused = isActive && field.key === focusKey && focusable(field);\n if (focused) focusRow = rows.length;\n if (field.kind === \"heading\") {\n const gap = rows.length ? 1 : 0;\n rows.push({\n lines: 1 + gap,\n node: (\n <Box key={field.key} marginTop={gap} flexShrink={0}>\n <Text bold color={theme.accent}>\n {field.label}\n </Text>\n </Box>\n ),\n });\n continue;\n }\n const marker = <Text color={theme.accent}>{focused ? \"❯ \" : \" \"}</Text>;\n let control: ReactNode;\n if (field.kind === \"toggle\") {\n const on = Boolean(values[field.key]);\n control = (\n <Text color={on ? theme.success : theme.muted} inverse={focused}>\n {on ? \"● on\" : \"○ off\"}\n </Text>\n );\n } else if (field.kind === \"select\") {\n const option = field.options.find((o) => o.value === values[field.key]);\n control = focused ? (\n <Text>\n <Text inverse>{option?.label ?? \"—\"}</Text>\n <Text color={theme.muted}>{\" ◂ ▸\"}</Text>\n </Text>\n ) : (\n <Text>{option?.label ?? \"—\"}</Text>\n );\n } else if (field.kind === \"action\") {\n control = (\n <Text wrap=\"truncate-end\" color={focused ? theme.accent : undefined}>\n {field.detail ?? \"\"}\n </Text>\n );\n } else {\n control = (\n <TextField\n value={String(values[field.key] ?? \"\")}\n onChange={(v) => set(field.key, field.kind === \"number\" ? v.replace(/[^0-9]/g, \"\") : v)}\n focus={focused}\n mask={field.kind === \"password\"}\n placeholder={field.placeholder}\n width={inputWidth}\n />\n );\n }\n const extra = field.error ? (\n <Text color={theme.error} wrap=\"truncate-end\">\n ✘ {field.error}\n </Text>\n ) : field.hint && focused ? (\n typeof field.hint === \"string\" ? (\n <Text color={theme.muted} wrap=\"truncate-end\">\n {field.hint}\n </Text>\n ) : (\n field.hint\n )\n ) : null;\n rows.push({\n lines: extra ? 2 : 1,\n node: (\n <Box key={field.key} flexDirection=\"column\" flexShrink={0}>\n <Box height={1}>\n {marker}\n <Text bold={focused} color={field.kind === \"action\" ? theme.info : undefined}>\n {cell(field.label, labelWidth)}\n </Text>\n <Box flexGrow={1}>{control}</Box>\n </Box>\n {extra ? (\n <Box marginLeft={labelWidth + 2} height={1} overflow=\"hidden\">\n {extra}\n </Box>\n ) : null}\n </Box>\n ),\n });\n }\n const height = props.height;\n const total = rows.reduce((s, r) => s + r.lines, 0);\n if (!height || total <= height)\n return <Box flexDirection=\"column\">{rows.map((r) => r.node)}</Box>;\n\n // Window by lines: keep the focused row visible, leaving room for the ↑/↓ markers.\n const budget = Math.max(1, height - 2);\n let start = focusRow;\n let used = rows[focusRow]?.lines ?? 1;\n while (\n start > 0 &&\n used + (rows[start - 1]?.lines ?? 1) <= Math.ceil(budget / 3) + (rows[focusRow]?.lines ?? 1)\n ) {\n start--;\n used += rows[start]?.lines ?? 1;\n }\n let end = focusRow + 1;\n while (end < rows.length && used + (rows[end]?.lines ?? 1) <= budget) {\n used += rows[end]?.lines ?? 1;\n end++;\n }\n while (start > 0 && used + (rows[start - 1]?.lines ?? 1) <= budget) {\n start--;\n used += rows[start]?.lines ?? 1;\n }\n return (\n <Box flexDirection=\"column\">\n <Text color={theme.muted}>{start > 0 ? \" ↑ more\" : \" \"}</Text>\n {rows.slice(start, end).map((r) => r.node)}\n <Text color={theme.muted}>{end < rows.length ? \" ↓ more\" : \" \"}</Text>\n </Box>\n );\n}\n","import type { z } from \"zod\";\nimport { formatIssuePath } from \"../../core/config/load.js\";\n\n/** Map zod issues to form field keys via a path → key function; others go to `general`. */\nexport function issuesToErrors(\n error: z.ZodError,\n keyFor: (path: (string | number)[]) => string | null,\n): { fields: Record<string, string>; general: string[] } {\n const fields: Record<string, string> = {};\n const general: string[] = [];\n for (const issue of error.issues) {\n const path = issue.path.filter((p): p is string | number => typeof p !== \"symbol\");\n const key = keyFor(path);\n if (key && !fields[key]) fields[key] = issue.message;\n else if (!key) general.push(`${formatIssuePath(path)}: ${issue.message}`);\n }\n return { fields, general };\n}\n\nexport const opt = (v: unknown): string | undefined => {\n const s = typeof v === \"string\" ? v.trim() : \"\";\n return s ? s : undefined;\n};\n\nexport const optInt = (v: unknown): number | undefined => {\n const s = opt(v);\n return s === undefined ? undefined : Number.parseInt(s, 10);\n};\n","import { Box, Text } from \"ink\";\nimport { useState } from \"react\";\nimport { type Database, DatabaseSchema, type Environment } from \"../../core/config/schema.js\";\nimport { ErrorLine, Panel, Spinner } from \"../components/basics.js\";\nimport { type Field, Form, type Values } from \"../components/Form.js\";\nimport { useApp, useHints } from \"../context.js\";\nimport { joinList, splitList } from \"../keys.js\";\nimport { issuesToErrors, opt, optInt } from \"./forms.js\";\n\nfunction initialValues(db: Database | undefined, env: Environment): Values {\n const s = db?.source;\n return {\n name: db?.name ?? \"\",\n type: s?.type ?? (env.projects.length ? \"laravel\" : \"connection\"),\n project: s?.type === \"laravel\" ? s.project : (env.projects[0]?.name ?? \"\"),\n database: s?.type === \"laravel\" ? (s.database ?? \"\") : \"\",\n schemas: s?.type === \"connection\" ? joinList(s.schemas) : \"\",\n host: s?.host ?? \"\",\n port: s?.port ? String(s.port) : \"\",\n socket: s?.socket ?? \"\",\n user: s?.user ?? \"\",\n password: s?.password ?? \"\",\n passwordFile: s?.passwordFile ?? \"\",\n extraArgs: joinList(db?.extraArgs ?? []),\n };\n}\n\nexport function buildDatabase(values: Values): unknown {\n const common = {\n host: opt(values.host),\n port: optInt(values.port),\n socket: opt(values.socket),\n user: opt(values.user),\n password: values.password === \"\" ? undefined : String(values.password),\n passwordFile: opt(values.passwordFile),\n };\n const source =\n values.type === \"laravel\"\n ? {\n type: \"laravel\",\n project: String(values.project),\n database: opt(values.database),\n ...common,\n }\n : { type: \"connection\", schemas: splitList(String(values.schemas)), ...common };\n return {\n name: String(values.name).trim(),\n source: Object.fromEntries(Object.entries(source).filter(([, v]) => v !== undefined)),\n extraArgs: splitList(String(values.extraArgs)),\n };\n}\n\nexport function DatabaseEdit({\n env,\n index,\n onApply,\n onCancel,\n isActive,\n}: {\n env: Environment;\n index: number | null;\n onApply(env: Environment): void;\n onCancel(): void;\n isActive: boolean;\n}) {\n const { width, height, theme, services } = useApp();\n const original = index === null ? undefined : env.databases[index];\n const [values, setValues] = useState<Values>(() => initialValues(original, env));\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [general, setGeneral] = useState<string[]>([]);\n const [test, setTest] = useState<\n { state: \"running\" } | { state: \"done\"; ok: boolean; message: string } | null\n >(null);\n useHints([\n { key: \"tab\", label: \"next field\" },\n { key: \"←→\", label: \"change type\" },\n { key: \"ctrl-s\", label: \"apply\" },\n { key: \"esc\", label: \"cancel\" },\n ]);\n\n const validate = (values: Values): Database | null => {\n const parsed = DatabaseSchema.safeParse(buildDatabase(values));\n if (!parsed.success) {\n const e = issuesToErrors(parsed.error, (p) => {\n if (p[0] === \"source\" && typeof p[1] === \"string\" && p[1] !== \"type\") return p[1];\n if (p[0] === \"name\" || p[0] === \"extraArgs\") return p[0];\n return null;\n });\n setErrors(e.fields);\n setGeneral(e.general);\n return null;\n }\n const db = parsed.data;\n const errs: Record<string, string> = {};\n if (db.source.password !== undefined && db.source.passwordFile)\n errs.passwordFile = \"set password or passwordFile, not both\";\n if (env.databases.some((d, i) => i !== index && d.name === db.name))\n errs.name = `database '${db.name}' already exists`;\n if (\n db.source.type === \"laravel\" &&\n !env.projects.some((p) => p.name === (db.source as { project: string }).project)\n ) {\n errs.project = \"add a project to this environment first\";\n }\n setErrors(errs);\n setGeneral([]);\n return Object.keys(errs).length ? null : db;\n };\n\n const submit = (current: Values) => {\n const db = validate(current);\n if (!db) return;\n const databases = [...env.databases];\n if (index === null) databases.push(db);\n else databases[index] = db;\n onApply({ ...env, databases });\n };\n\n const runTest = () => {\n const db = validate(values);\n if (!db) return;\n setTest({ state: \"running\" });\n void services.testConnection(env, db).then((r) => setTest({ state: \"done\", ...r }));\n };\n\n const laravel = values.type === \"laravel\";\n const fields: Field[] = [\n { kind: \"text\", key: \"name\", label: \"Name\", placeholder: \"shop\", error: errors.name },\n {\n kind: \"select\",\n key: \"type\",\n label: \"Source\",\n options: [\n { label: \"Laravel .env\", value: \"laravel\" },\n { label: \"Connection\", value: \"connection\" },\n ],\n hint: laravel\n ? \"DB_* values from the project's .env; fields below override them\"\n : \"explicit host/socket and schemas\",\n },\n ...(laravel\n ? ([\n {\n kind: \"select\",\n key: \"project\",\n label: \"Project\",\n options: env.projects.map((p) => ({ label: p.name, value: p.name })),\n error: errors.project,\n },\n {\n kind: \"text\",\n key: \"database\",\n label: \"Database\",\n placeholder: \"from .env DB_DATABASE\",\n error: errors.database,\n },\n ] as Field[])\n : ([\n {\n kind: \"text\",\n key: \"schemas\",\n label: \"Schemas\",\n placeholder: \"app, reports\",\n error: errors.schemas,\n hint: \"comma separated; several go into one file\",\n },\n ] as Field[])),\n {\n kind: \"text\",\n key: \"host\",\n label: \"Host\",\n placeholder: laravel ? \"from .env DB_HOST\" : \"localhost\",\n error: errors.host,\n },\n {\n kind: \"number\",\n key: \"port\",\n label: \"Port\",\n placeholder: laravel ? \"from .env DB_PORT\" : \"3306\",\n error: errors.port,\n },\n {\n kind: \"text\",\n key: \"socket\",\n label: \"Socket\",\n placeholder: \"unix socket (instead of host)\",\n error: errors.socket,\n },\n {\n kind: \"text\",\n key: \"user\",\n label: \"User\",\n placeholder: laravel ? \"from .env DB_USERNAME\" : \"\",\n error: errors.user,\n },\n {\n kind: \"password\",\n key: \"password\",\n label: \"Password\",\n placeholder: laravel ? \"from .env DB_PASSWORD\" : \"\",\n error: errors.password,\n hint: \"stored in config.json (mode 0600); prefer a password file\",\n },\n {\n kind: \"text\",\n key: \"passwordFile\",\n label: \"Password file\",\n placeholder: \"~/.config/backup-manager/db.pw\",\n error: errors.passwordFile,\n },\n {\n kind: \"text\",\n key: \"extraArgs\",\n label: \"Extra args\",\n placeholder: \"--ignore-table=app.sessions\",\n error: errors.extraArgs,\n hint: \"extra mariadb-dump arguments, comma separated\",\n },\n {\n kind: \"action\",\n key: \"test\",\n label: \"Test connection\",\n detail: \"⏎ run SELECT 1\",\n onPress: runTest,\n },\n ];\n return (\n <Panel\n title={original ? `Database · ${original.name}` : \"New database\"}\n width={width}\n height={height}\n focused={isActive}\n right={`in ${env.name || \"new environment\"}`}\n >\n <Form\n id=\"database-edit\"\n fields={fields}\n values={values}\n onChange={setValues}\n onSubmit={submit}\n onCancel={onCancel}\n isActive={isActive}\n width={width - 4}\n height={height - 5}\n />\n <Box flexDirection=\"column\" marginTop={1}>\n {test?.state === \"running\" && <Spinner label=\"testing connection…\" />}\n {test?.state === \"done\" && (\n <Text\n color={test.ok ? theme.success : theme.error}\n >{`${test.ok ? \"✔\" : \"✘\"} ${test.message}`}</Text>\n )}\n {general.map((g) => (\n <ErrorLine key={g}>{g}</ErrorLine>\n ))}\n </Box>\n </Panel>\n );\n}\n","import { constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Box, Text } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport {\n DEFAULT_EXCLUDE,\n DEFAULT_INCLUDE,\n type Environment,\n type Project,\n ProjectSchema,\n} from \"../../core/config/schema.js\";\nimport { expandHome } from \"../../core/paths.js\";\nimport { ErrorLine, Panel } from \"../components/basics.js\";\nimport { type Field, Form, type Values } from \"../components/Form.js\";\nimport { useApp, useHints } from \"../context.js\";\nimport { joinList, splitList } from \"../keys.js\";\nimport { issuesToErrors } from \"./forms.js\";\n\nfunction useArtisanHint(projectPath: string): { ok: boolean; text: string } | null {\n const [hint, setHint] = useState<{ ok: boolean; text: string } | null>(null);\n useEffect(() => {\n const p = projectPath.trim();\n if (!p) return setHint(null);\n let alive = true;\n const timer = setTimeout(async () => {\n const dir = path.resolve(expandHome(p));\n const exists = await access(dir, constants.R_OK).then(\n () => true,\n () => false,\n );\n const artisan =\n exists &&\n (await access(path.join(dir, \"artisan\")).then(\n () => true,\n () => false,\n ));\n if (!alive) return;\n setHint(\n !exists\n ? { ok: false, text: \"directory not found or not readable\" }\n : artisan\n ? { ok: true, text: \"Laravel project (artisan found)\" }\n : { ok: false, text: \"no artisan file here; is this the project root?\" },\n );\n }, 200);\n return () => {\n alive = false;\n clearTimeout(timer);\n };\n }, [projectPath]);\n return hint;\n}\n\nexport function ProjectEdit({\n env,\n index,\n onApply,\n onCancel,\n isActive,\n}: {\n env: Environment;\n index: number | null;\n onApply(env: Environment): void;\n onCancel(): void;\n isActive: boolean;\n}) {\n const { width, height, theme } = useApp();\n const original = index === null ? undefined : env.projects[index];\n const [values, setValues] = useState<Values>({\n name: original?.name ?? \"\",\n path: original?.path ?? \"\",\n include: joinList(original?.include ?? DEFAULT_INCLUDE),\n exclude: joinList(original?.exclude ?? DEFAULT_EXCLUDE),\n });\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [general, setGeneral] = useState<string[]>([]);\n const hint = useArtisanHint(String(values.path));\n useHints([\n { key: \"tab\", label: \"next field\" },\n { key: \"ctrl-s\", label: \"apply\" },\n { key: \"esc\", label: \"cancel\" },\n ]);\n\n const submit = (values: Values) => {\n const candidate = {\n name: String(values.name).trim(),\n path: String(values.path).trim() ? path.resolve(expandHome(String(values.path).trim())) : \"\",\n include: splitList(String(values.include)),\n exclude: splitList(String(values.exclude)),\n };\n const parsed = ProjectSchema.safeParse(candidate);\n if (!parsed.success) {\n const e = issuesToErrors(parsed.error, (p) => (typeof p[0] === \"string\" ? p[0] : null));\n setErrors(e.fields);\n setGeneral(e.general);\n return;\n }\n const project: Project = parsed.data;\n if (env.projects.some((p, i) => i !== index && p.name === project.name)) {\n setErrors({ name: `project '${project.name}' already exists in this environment` });\n return;\n }\n const projects = [...env.projects];\n if (index === null) projects.push(project);\n else projects[index] = project;\n const renamed = original && original.name !== project.name;\n const databases = env.databases.map((db) =>\n renamed && db.source.type === \"laravel\" && db.source.project === original.name\n ? { ...db, source: { ...db.source, project: project.name } }\n : db,\n );\n onApply({ ...env, projects, databases });\n };\n\n const fields: Field[] = [\n {\n kind: \"text\",\n key: \"name\",\n label: \"Name\",\n placeholder: \"shop\",\n error: errors.name,\n hint: \"lowercase letters, digits, - and _\",\n },\n {\n kind: \"text\",\n key: \"path\",\n label: \"Path\",\n placeholder: \"/var/www/shop\",\n error: errors.path,\n hint: hint ? (\n <Text\n color={hint.ok ? theme.success : theme.warning}\n >{`${hint.ok ? \"✔\" : \"!\"} ${hint.text}`}</Text>\n ) : (\n \"absolute path to the Laravel project root\"\n ),\n },\n {\n kind: \"text\",\n key: \"include\",\n label: \"Include\",\n error: errors.include,\n hint: \"directories to archive, comma separated, relative to the project\",\n },\n {\n kind: \"text\",\n key: \"exclude\",\n label: \"Exclude\",\n error: errors.exclude,\n hint: \"glob patterns, comma separated; 'dir/**' keeps the empty dir\",\n },\n ];\n return (\n <Panel\n title={original ? `Project · ${original.name}` : \"New project\"}\n width={width}\n height={height}\n focused={isActive}\n right={`in ${env.name || \"new environment\"}`}\n >\n <Form\n id=\"project-edit\"\n fields={fields}\n values={values}\n onChange={setValues}\n onSubmit={submit}\n onCancel={onCancel}\n isActive={isActive}\n width={width - 4}\n height={height - 4}\n />\n <Box flexDirection=\"column\" marginTop={1}>\n {general.map((g) => (\n <ErrorLine key={g}>{g}</ErrorLine>\n ))}\n </Box>\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport { useState } from \"react\";\nimport {\n effectiveRetention,\n envBackupDir,\n findEnvironment,\n timezone,\n} from \"../../core/config/defaults.js\";\nimport { ConfigSchema, type Environment } from \"../../core/config/schema.js\";\nimport { formatDateTime } from \"../../core/format.js\";\nimport { describeSchedule, nextRuns, scheduleError } from \"../../core/schedule.js\";\nimport { ErrorLine, Panel } from \"../components/basics.js\";\nimport { type Field, Form, type Values } from \"../components/Form.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { DatabaseEdit } from \"./DatabaseEdit.js\";\nimport { issuesToErrors, opt, optInt } from \"./forms.js\";\nimport { ProjectEdit } from \"./ProjectEdit.js\";\n\ntype Mode =\n | { kind: \"env\" }\n | { kind: \"project\"; index: number | null }\n | { kind: \"database\"; index: number | null };\n\nfunction SchedulePreview({ schedule, tz }: { schedule: string; tz: string }) {\n const { theme } = useApp();\n if (!schedule.trim())\n return <Text color={theme.muted}>empty = manual only · e.g. \"30 3 * * *\" (03:30 daily)</Text>;\n const error = scheduleError(schedule.trim(), tz);\n if (error) return <Text color={theme.error}>✘ {error}</Text>;\n const runs = nextRuns(schedule.trim(), 3, tz);\n return (\n <Text>\n <Text color={theme.success}>{`✔ ${describeSchedule(schedule.trim())}`}</Text>\n <Text\n color={theme.muted}\n >{` · next ${runs.map((d) => formatDateTime(d)).join(\", \")} (${tz})`}</Text>\n </Text>\n );\n}\n\nexport function EnvironmentEdit({\n envName,\n onboarding,\n}: {\n envName?: string;\n onboarding?: boolean;\n}) {\n const { config, width, height, save, back, navigate, confirm, services, toast, theme } = useApp();\n const active = useScreenActive();\n const original = config && envName ? findEnvironment(config, envName) : undefined;\n const [draft, setDraft] = useState<Environment>(() =>\n structuredClone(original ?? { name: \"\", projects: [], databases: [] }),\n );\n const [values, setValues] = useState<Values>({\n name: original?.name ?? \"\",\n schedule: original?.schedule ?? \"\",\n backupDir: original?.backupDir ?? \"\",\n keepLast:\n original?.retention?.keepLast !== undefined ? String(original.retention.keepLast) : \"\",\n keepDays:\n original?.retention?.keepDays !== undefined ? String(original.retention.keepDays) : \"\",\n });\n const [mode, setMode] = useState<Mode>({ kind: \"env\" });\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [general, setGeneral] = useState<string[]>([]);\n useHints(\n mode.kind === \"env\"\n ? [\n { key: \"tab/↑↓\", label: \"field\" },\n { key: \"⏎\", label: \"open\" },\n { key: \"d\", label: \"remove item\" },\n { key: \"ctrl-s\", label: \"save\" },\n { key: \"esc\", label: \"cancel\" },\n ]\n : [],\n [mode.kind],\n );\n if (!config) return null;\n const tz = timezone(config);\n\n const build = (values: Values): Environment => {\n const keepLast = optInt(values.keepLast);\n const keepDays = optInt(values.keepDays);\n const retention =\n keepLast !== undefined || keepDays !== undefined\n ? {\n ...(keepLast !== undefined ? { keepLast } : {}),\n ...(keepDays !== undefined ? { keepDays } : {}),\n }\n : undefined;\n const env: Environment = {\n ...draft,\n name: String(values.name).trim(),\n projects: draft.projects,\n databases: draft.databases,\n };\n delete env.schedule;\n delete env.backupDir;\n delete env.retention;\n const schedule = opt(values.schedule);\n const backupDir = opt(values.backupDir);\n if (schedule) env.schedule = schedule;\n if (backupDir) env.backupDir = backupDir;\n if (retention) env.retention = retention;\n return env;\n };\n\n const submit = async (current: Values) => {\n const env = build(current);\n const index = original ? config.environments.indexOf(original) : config.environments.length;\n const environments = [...config.environments];\n environments[index] = env;\n const parsed = ConfigSchema.safeParse({ ...config, environments });\n if (!parsed.success) {\n const e = issuesToErrors(parsed.error, (p) => {\n if (p[0] !== \"environments\" || p[1] !== index) return null;\n if (p[2] === \"retention\") return typeof p[3] === \"string\" ? p[3] : \"keepLast\";\n return typeof p[2] === \"string\" && [\"name\", \"schedule\", \"backupDir\"].includes(p[2])\n ? p[2]\n : null;\n });\n setErrors(e.fields);\n setGeneral(e.general.map((g) => g.replace(`environments[${index}].`, \"\")));\n return;\n }\n setErrors({});\n setGeneral([]);\n if (!(await save(parsed.data, original ? `saved ${env.name}` : `added ${env.name}`))) return;\n if (onboarding) {\n const install = await confirm({\n title: \"Install the service?\",\n message: env.schedule\n ? \"Install the user-level systemd service now so the schedule runs automatically (no sudo)?\"\n : \"Install the user-level systemd service now (no sudo)? It runs schedules and serves the API.\",\n confirmLabel: \"Install\",\n });\n if (install) {\n try {\n const r = await services.service.install();\n toast(\n r.warnings[0] ?? \"service installed and started\",\n r.warnings.length ? \"warning\" : \"success\",\n );\n } catch (error) {\n toast((error as Error).message, \"error\");\n }\n }\n navigate({ name: \"dashboard\" }, { replace: true });\n return;\n }\n back();\n };\n\n const removeProject = async (i: number) => {\n const p = draft.projects[i];\n if (!p) return;\n const users = draft.databases.filter(\n (d) => d.source.type === \"laravel\" && d.source.project === p.name,\n );\n if (users.length) {\n toast(\n `'${p.name}' is used by database ${users.map((u) => `'${u.name}'`).join(\", \")}`,\n \"warning\",\n );\n return;\n }\n if (\n await confirm({\n title: \"Remove project\",\n message: `Remove project '${p.name}' from this environment?`,\n confirmLabel: \"Remove\",\n danger: true,\n })\n ) {\n setDraft({ ...draft, projects: draft.projects.filter((_, j) => j !== i) });\n }\n };\n const removeDatabase = async (i: number) => {\n const d = draft.databases[i];\n if (!d) return;\n if (\n await confirm({\n title: \"Remove database\",\n message: `Remove database '${d.name}' from this environment?`,\n confirmLabel: \"Remove\",\n danger: true,\n })\n ) {\n setDraft({ ...draft, databases: draft.databases.filter((_, j) => j !== i) });\n }\n };\n\n if (mode.kind === \"project\") {\n return (\n <ProjectEdit\n env={{ ...draft, name: String(values.name) }}\n index={mode.index}\n isActive={active}\n onCancel={() => setMode({ kind: \"env\" })}\n onApply={(env) => {\n setDraft({ ...draft, projects: env.projects, databases: env.databases });\n setMode({ kind: \"env\" });\n }}\n />\n );\n }\n if (mode.kind === \"database\") {\n return (\n <DatabaseEdit\n env={{ ...draft, name: String(values.name) }}\n index={mode.index}\n isActive={active}\n onCancel={() => setMode({ kind: \"env\" })}\n onApply={(env) => {\n setDraft({ ...draft, databases: env.databases });\n setMode({ kind: \"env\" });\n }}\n />\n );\n }\n\n const inherited = effectiveRetention(config, { name: \"\", projects: [], databases: [] });\n const defaultDir = String(values.name).trim()\n ? envBackupDir(config, { name: String(values.name).trim(), projects: [], databases: [] })\n : \"<backupDir>/<name>\";\n const fields: Field[] = [\n {\n kind: \"text\",\n key: \"name\",\n label: \"Name\",\n placeholder: \"production\",\n error: errors.name,\n hint: \"lowercase letters, digits, - and _\",\n },\n {\n kind: \"text\",\n key: \"schedule\",\n label: \"Schedule\",\n placeholder: \"30 3 * * *\",\n error: errors.schedule,\n hint: <SchedulePreview schedule={String(values.schedule)} tz={tz} />,\n },\n {\n kind: \"text\",\n key: \"backupDir\",\n label: \"Backup dir\",\n placeholder: defaultDir,\n error: errors.backupDir,\n hint: \"leave empty for the default\",\n },\n {\n kind: \"number\",\n key: \"keepLast\",\n label: \"Keep last\",\n placeholder: `inherit (${inherited.keepLast})`,\n error: errors.keepLast,\n hint: \"newest complete backups to keep; 0 disables\",\n },\n {\n kind: \"number\",\n key: \"keepDays\",\n label: \"Keep days\",\n placeholder: `inherit (${inherited.keepDays})`,\n error: errors.keepDays,\n hint: \"keep backups younger than N days; 0 disables\",\n },\n { kind: \"heading\", key: \"h-projects\", label: `Projects (${draft.projects.length})` },\n ...draft.projects.map(\n (p, i): Field => ({\n kind: \"action\",\n key: `project-${i}`,\n label: p.name,\n detail: `${p.path} · ${p.include.join(\", \")}`,\n onPress: () => setMode({ kind: \"project\", index: i }),\n onDelete: () => void removeProject(i),\n }),\n ),\n {\n kind: \"action\",\n key: \"add-project\",\n label: \"+ Add project\",\n detail: \"a Laravel project whose storage is archived\",\n onPress: () => setMode({ kind: \"project\", index: null }),\n },\n { kind: \"heading\", key: \"h-databases\", label: `Databases (${draft.databases.length})` },\n ...draft.databases.map(\n (d, i): Field => ({\n kind: \"action\",\n key: `database-${i}`,\n label: d.name,\n detail:\n d.source.type === \"laravel\"\n ? `from ${d.source.project}/.env`\n : `${d.source.schemas.join(\", \")} @ ${d.source.socket ?? d.source.host ?? \"localhost\"}`,\n onPress: () => setMode({ kind: \"database\", index: i }),\n onDelete: () => void removeDatabase(i),\n }),\n ),\n {\n kind: \"action\",\n key: \"add-database\",\n label: \"+ Add database\",\n detail: \"dumped with mariadb-dump\",\n onPress: () => setMode({ kind: \"database\", index: null }),\n },\n ];\n return (\n <Panel\n title={\n onboarding\n ? \"First environment\"\n : original\n ? `Environment · ${original.name}`\n : \"New environment\"\n }\n width={width}\n height={height}\n focused={active}\n right={onboarding ? \"step 2 of 2\" : undefined}\n >\n <Form\n id=\"environment-edit\"\n fields={fields}\n values={values}\n onChange={setValues}\n onSubmit={(v) => void submit(v)}\n onCancel={() => (onboarding ? undefined : back())}\n isActive={active}\n width={width - 4}\n height={height - 4 - general.length}\n />\n <Box flexDirection=\"column\">\n {general.map((g) => (\n <ErrorLine key={g}>{g}</ErrorLine>\n ))}\n {onboarding && (\n <Text color={theme.muted}>\n Ctrl-S saves; you can add projects and databases now or later.\n </Text>\n )}\n </Box>\n </Panel>\n );\n}\n","import { Text, useInput } from \"ink\";\nimport { describeSchedule } from \"../../core/schedule.js\";\nimport { cell, Panel } from \"../components/basics.js\";\nimport { ScrollList } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive, useSessionState } from \"../context.js\";\nimport { useListNav } from \"../keys.js\";\nimport { useRunNow } from \"./Dashboard.js\";\n\nexport function Environments() {\n const { config, width, height, navigate, theme, confirm, save } = useApp();\n const active = useScreenActive();\n const envs = config?.environments ?? [];\n const nav = useListNav(envs.length, {\n isActive: active,\n state: useSessionState(\"environments:index\", 0),\n onSelect: (i) => navigate({ name: \"environment-edit\", env: envs[i]?.name }),\n });\n useHints([\n { key: \"⏎\", label: \"edit\" },\n { key: \"a\", label: \"add\" },\n { key: \"d\", label: \"delete\" },\n { key: \"b\", label: \"backups\" },\n { key: \"r\", label: \"run now\" },\n ]);\n useRunNow(active, () => envs[nav.index]?.name);\n useInput(\n (input) => {\n const env = envs[nav.index];\n if (input === \"a\") navigate({ name: \"environment-edit\" });\n else if (input === \"b\" && env) navigate({ name: \"backups\", env: env.name });\n else if (input === \"d\" && env && config) {\n void (async () => {\n const ok = await confirm({\n title: \"Delete environment\",\n message: `Remove '${env.name}' from the config? Its backups on disk are kept.`,\n confirmLabel: \"Delete\",\n danger: true,\n });\n if (ok)\n await save(\n { ...config, environments: envs.filter((e) => e.name !== env.name) },\n `deleted ${env.name}`,\n );\n })();\n }\n },\n { isActive: active },\n );\n const inner = width - 7;\n return (\n <Panel\n title=\"Environments\"\n width={width}\n height={height}\n focused={active}\n right={`${envs.length}`}\n >\n <ScrollList\n items={envs}\n index={nav.index}\n height={height - 2}\n empty=\"No environments yet. Press a to add one.\"\n render={(e) => (\n <Text wrap=\"truncate-end\">\n <Text bold>{cell(e.name, 16)}</Text>\n <Text color={theme.muted}>\n {cell(`${e.databases.length} db · ${e.projects.length} proj`, 16)}\n </Text>\n <Text color={e.schedule ? undefined : theme.muted}>\n {cell(\n e.schedule ? `⏱ ${describeSchedule(e.schedule)}` : \"manual only\",\n Math.max(10, inner - 32),\n )}\n </Text>\n </Text>\n )}\n />\n </Panel>\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport { formatAge, formatBytes, formatDateTime, formatDuration } from \"../../core/format.js\";\nimport type { JobEvent } from \"../../core/jobs/events.js\";\nimport type { JobRecord } from \"../../core/jobs/store.js\";\nimport { cell, Muted, Panel, Pulse, Spinner, StatusText } from \"../components/basics.js\";\nimport { ScrollList, ScrollView } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive, useSessionState } from \"../context.js\";\nimport { itemProgress, useJobEvents } from \"../hooks/useJobEvents.js\";\nimport { usePolling } from \"../hooks/usePolling.js\";\nimport { isDown, isUp, useListNav } from \"../keys.js\";\n\nconst isActiveJob = (j: JobRecord) => j.status === \"running\" || j.status === \"queued\";\nconst elapsed = (j: JobRecord) =>\n j.startedAt\n ? (j.finishedAt ? Date.parse(j.finishedAt) : Date.now()) - Date.parse(j.startedAt)\n : 0;\n\nfunction useKill() {\n const { services, config, confirm, toast } = useApp();\n return (job: JobRecord | undefined) => {\n if (!job || !config || !isActiveJob(job)) return;\n void (async () => {\n const ok = await confirm({\n title: \"Stop job\",\n message: `Stop job ${job.id} (${job.targets.map((t) => t.environment).join(\", \")})? The unfinished backup is discarded.`,\n confirmLabel: \"Stop\",\n danger: true,\n });\n if (!ok) return;\n toast(\n (await services.killJob(config, job.id)) ? \"stop signal sent\" : \"job is not running\",\n \"info\",\n );\n })();\n };\n}\n\nexport function Jobs() {\n const { services, config, width, height, navigate, theme } = useApp();\n const active = useScreenActive();\n const jobs = usePolling(() => (config ? services.jobs(config, 100) : Promise.resolve([])), 1000, [\n config,\n ]);\n const list = jobs.data ?? [];\n const kill = useKill();\n const nav = useListNav(list.length, {\n isActive: active,\n state: useSessionState(\"jobs:index\", 0),\n onSelect: (i) => {\n const j = list[i];\n if (j) navigate({ name: \"job-live\", id: j.id });\n },\n });\n useHints([\n { key: \"⏎\", label: \"follow\" },\n { key: \"x\", label: \"stop\" },\n ]);\n useInput((input) => input === \"x\" && kill(list[nav.index]), { isActive: active });\n return (\n <Panel\n title=\"Jobs\"\n width={width}\n height={height}\n focused={active}\n right={`${list.filter(isActiveJob).length} running`}\n >\n <ScrollList\n items={list}\n index={nav.index}\n height={height - 2}\n empty={jobs.loading ? \"loading…\" : \"no jobs yet; press n to start a backup\"}\n render={(j) => (\n <Text wrap=\"truncate-end\">\n {j.status === \"running\" ? (\n <Spinner label={cell(\"running\", 9)} color={theme.info} />\n ) : (\n <StatusText status={j.status} label={cell(j.status, 9)} />\n )}\n {` ${cell(j.id, 21)}`}\n <Text color={theme.muted}>{cell(j.trigger, 9)}</Text>\n {cell(j.targets.map((t) => t.environment).join(\", \"), 18)}\n <Text\n color={theme.muted}\n >{`${cell(formatAge(j.createdAt), 9)} ${formatDuration(elapsed(j))}`}</Text>\n {j.error ? <Text color={theme.error}>{` ${j.error}`}</Text> : null}\n </Text>\n )}\n />\n </Panel>\n );\n}\n\nfunction eventLine(e: JobEvent, theme: ReturnType<typeof useApp>[\"theme\"]): React.ReactNode {\n const time = new Date(e.ts).toLocaleTimeString([], { hour12: false });\n const t = <Text color={theme.muted}>{`${time} `}</Text>;\n switch (e.type) {\n case \"log\": {\n const color =\n e.level === \"error\" ? theme.error : e.level === \"warn\" ? theme.warning : undefined;\n return (\n <Text wrap=\"truncate-end\">\n {t}\n <Text color={color}>{`${e.environment ? `[${e.environment}] ` : \"\"}${e.message}`}</Text>\n </Text>\n );\n }\n case \"item-start\":\n return (\n <Text wrap=\"truncate-end\">\n {t}\n {`[${e.environment}] ${e.kind} ${e.name} started (${e.index}/${e.total})`}\n </Text>\n );\n case \"item-done\":\n return (\n <Text wrap=\"truncate-end\">\n {t}\n <Text color={e.status === \"success\" ? theme.success : theme.error}>\n {`[${e.environment}] ${e.kind} ${e.name} ${e.status === \"success\" ? `done, ${formatBytes(e.size)} in ${formatDuration(e.durationMs)}` : `failed: ${e.error ?? \"\"}`}`}\n </Text>\n </Text>\n );\n case \"backup-done\":\n return (\n <Text wrap=\"truncate-end\">\n {t}\n <StatusText\n status={e.status}\n label={`[${e.environment}] backup ${e.backupId ?? \"\"} ${e.status}`}\n />\n </Text>\n );\n case \"job-done\":\n return (\n <Text wrap=\"truncate-end\">\n {t}\n <StatusText status={e.status} label={`job ${e.status}${e.error ? `: ${e.error}` : \"\"}`} />\n </Text>\n );\n default:\n return null;\n }\n}\n\nexport function JobLive({ id }: { id: string }) {\n const { services, config, width, height, theme } = useApp();\n const active = useScreenActive();\n const job = usePolling(() => (config ? services.job(config, id) : Promise.resolve(null)), 1000, [\n config,\n id,\n ]);\n const events = useJobEvents(services, config, id);\n const kill = useKill();\n const [offset, setOffset] = useState<number | null>(null); // null = follow the tail\n const j = job.data;\n const items = itemProgress(events);\n const logLines = events.filter((e) => e.type !== \"item-progress\").map((e) => eventLine(e, theme));\n const itemRows = Math.min(items.length, Math.max(2, Math.floor((height - 8) / 2)));\n const logHeight = Math.max(3, height - itemRows - 9);\n const max = Math.max(0, logLines.length - logHeight);\n useHints([\n { key: \"↑↓\", label: \"scroll log\" },\n { key: \"G\", label: \"follow\" },\n { key: \"x\", label: \"stop\" },\n ]);\n useInput(\n (input, key) => {\n const at = offset ?? max;\n if (input === \"x\") kill(j ?? undefined);\n else if (isUp(input, key)) setOffset(Math.max(0, at - 1));\n else if (isDown(input, key)) setOffset(at + 1 >= max ? null : at + 1);\n else if (key.pageUp) setOffset(Math.max(0, at - logHeight));\n else if (key.pageDown) setOffset(at + logHeight >= max ? null : at + logHeight);\n else if (input === \"g\" || key.home) setOffset(0);\n else if (input === \"G\" || key.end) setOffset(null);\n },\n { isActive: active },\n );\n if (!j)\n return (\n <Panel title={`Job ${id}`} width={width} height={height}>\n {job.loading ? <Muted>loading…</Muted> : <Text color={theme.error}>job not found</Text>}\n </Panel>\n );\n const running = isActiveJob(j);\n return (\n <Box flexDirection=\"column\">\n <Panel title={`Job · ${j.id}`} width={width} focused={active} right={j.trigger}>\n <Box gap={2}>\n {running ? <Pulse /> : null}\n <StatusText status={j.status} />\n <Text>{j.targets.map((t) => t.environment).join(\", \")}</Text>\n <Text\n color={theme.muted}\n >{`started ${j.startedAt ? formatDateTime(j.startedAt) : \"—\"} · ${formatDuration(elapsed(j))}`}</Text>\n {j.pid ? (\n <Text color={theme.muted}>{`pid ${j.pid}${j.detached ? \" (detached)\" : \"\"}`}</Text>\n ) : null}\n </Box>\n {j.error ? <Text color={theme.error}>{`✘ ${j.error}`}</Text> : null}\n {items.slice(-itemRows).map((i) => (\n <Text key={`${i.environment}/${i.kind}/${i.name}`} wrap=\"truncate-end\">\n {i.status === \"running\" ? <Spinner /> : <StatusText status={i.status} label=\"\" />}\n {` ${cell(`${i.environment} · ${i.kind} ${i.name}`, Math.max(20, width - 40))} `}\n <Text color={theme.muted}>\n {i.status === \"running\"\n ? `${formatBytes(i.bytes)}${i.files !== undefined ? ` · ${i.files} files` : \"\"}`\n : i.status === \"failed\"\n ? (i.error ?? \"failed\")\n : `${formatBytes(i.size ?? 0)} · ${formatDuration(i.durationMs ?? 0)}`}\n </Text>\n </Text>\n ))}\n </Panel>\n <Panel\n title=\"Log\"\n width={width}\n right={offset === null ? \"following\" : \"paused · G to follow\"}\n >\n {logLines.length === 0 ? (\n <Muted>waiting for output…</Muted>\n ) : (\n <ScrollView lines={logLines} height={logHeight} offset={offset ?? max} />\n )}\n </Panel>\n </Box>\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { useMemo, useState } from \"react\";\nimport type { JobTarget } from \"../../core/jobs/store.js\";\nimport { cell, Muted, Panel } from \"../components/basics.js\";\nimport { ScrollList } from \"../components/ScrollList.js\";\nimport { useApp, useBackHandler, useHints, useScreenActive } from \"../context.js\";\nimport { useListNav } from \"../keys.js\";\n\ntype Step = \"envs\" | \"items\" | \"confirm\";\ninterface Item {\n env: string;\n kind: \"database\" | \"project\";\n name: string;\n}\nconst keyOf = (i: Item) => `${i.env}\\u0000${i.kind}\\u0000${i.name}`;\n\n/** Build job targets; an environment with everything selected is sent without filters. */\nexport function buildTargets(\n envs: { name: string; databases: { name: string }[]; projects: { name: string }[] }[],\n picked: Set<string>,\n items: Item[],\n): JobTarget[] {\n const targets: JobTarget[] = [];\n for (const env of envs) {\n const mine = items.filter((i) => i.env === env.name);\n const chosen = mine.filter((i) => picked.has(keyOf(i)));\n if (chosen.length === 0) continue;\n if (chosen.length === mine.length) targets.push({ environment: env.name });\n else\n targets.push({\n environment: env.name,\n databases: chosen.filter((i) => i.kind === \"database\").map((i) => i.name),\n projects: chosen.filter((i) => i.kind === \"project\").map((i) => i.name),\n });\n }\n return targets;\n}\n\nexport function NewBackup({ envName }: { envName?: string }) {\n const { config, services, width, height, navigate, toast, theme } = useApp();\n const active = useScreenActive();\n const envs = (config?.environments ?? []).filter(\n (e) => e.databases.length + e.projects.length > 0,\n );\n const [step, setStep] = useState<Step>(\"envs\");\n const [selectedEnvs, setSelectedEnvs] = useState<Set<string>>(\n () => new Set(envName ? [envName] : envs.length === 1 ? [envs[0]!.name] : []),\n );\n const items = useMemo<Item[]>(\n () =>\n envs\n .filter((e) => selectedEnvs.has(e.name))\n .flatMap((e) => [\n ...e.databases.map((d) => ({ env: e.name, kind: \"database\" as const, name: d.name })),\n ...e.projects.map((p) => ({ env: e.name, kind: \"project\" as const, name: p.name })),\n ]),\n [envs, selectedEnvs],\n );\n const [excluded, setExcluded] = useState<Set<string>>(new Set());\n const picked = new Set(items.map(keyOf).filter((k) => !excluded.has(k)));\n const [starting, setStarting] = useState(false);\n\n const envNav = useListNav(envs.length, { isActive: active && step === \"envs\" });\n const itemNav = useListNav(items.length, { isActive: active && step === \"items\" });\n useHints(\n step === \"confirm\"\n ? [\n { key: \"⏎\", label: \"start\" },\n { key: \"esc\", label: \"back\" },\n ]\n : [\n { key: \"space\", label: \"toggle\" },\n { key: \"a\", label: \"all/none\" },\n { key: \"⏎\", label: \"next\" },\n { key: \"esc\", label: \"back\" },\n ],\n [step],\n );\n\n const start = async () => {\n if (!config || starting) return;\n setStarting(true);\n try {\n const job = await services.startBackup(config, buildTargets(envs, picked, items));\n toast(\"backup started; it keeps running if you quit\", \"success\");\n navigate({ name: \"job-live\", id: job.id }, { replace: true });\n } catch (error) {\n toast((error as Error).message, \"error\");\n setStarting(false);\n }\n };\n\n useBackHandler(() => {\n if (step === \"envs\") return false;\n setStep(step === \"confirm\" ? \"items\" : \"envs\");\n return true;\n });\n useInput(\n (input, key) => {\n if (step === \"envs\") {\n const env = envs[envNav.index];\n if (input === \" \" && env) {\n const next = new Set(selectedEnvs);\n next.has(env.name) ? next.delete(env.name) : next.add(env.name);\n setSelectedEnvs(next);\n } else if (input === \"a\") {\n setSelectedEnvs(\n selectedEnvs.size === envs.length ? new Set() : new Set(envs.map((e) => e.name)),\n );\n } else if (key.return) {\n if (selectedEnvs.size === 0 && env) setSelectedEnvs(new Set([env.name]));\n setStep(\"items\");\n }\n } else if (step === \"items\") {\n const item = items[itemNav.index];\n if (input === \" \" && item) {\n const next = new Set(excluded);\n next.has(keyOf(item)) ? next.delete(keyOf(item)) : next.add(keyOf(item));\n setExcluded(next);\n } else if (input === \"a\") {\n setExcluded(picked.size === items.length ? new Set(items.map(keyOf)) : new Set());\n } else if (key.return && picked.size > 0) setStep(\"confirm\");\n } else if (step === \"confirm\") {\n if (key.return) void start();\n }\n },\n { isActive: active },\n );\n\n if (!config) return null;\n if (envs.length === 0) {\n return (\n <Panel title=\"New backup\" width={width} height={height} focused={active}>\n <Muted>No environment has a database or project yet. Add them in Environments (e).</Muted>\n </Panel>\n );\n }\n const check = (on: boolean) => (\n <Text color={on ? theme.success : theme.muted}>{on ? \"◉ \" : \"○ \"}</Text>\n );\n const steps = [\"1 environments\", \"2 items\", \"3 confirm\"];\n const current = step === \"envs\" ? 0 : step === \"items\" ? 1 : 2;\n return (\n <Panel title=\"New backup\" width={width} height={height} focused={active}>\n <Box marginBottom={1}>\n {steps.map((s, i) => (\n <Text key={s} color={i === current ? theme.accent : theme.muted} bold={i === current}>\n {`${s}${i < steps.length - 1 ? \" › \" : \"\"}`}\n </Text>\n ))}\n </Box>\n {step === \"envs\" && (\n <ScrollList\n items={envs}\n index={envNav.index}\n height={height - 4}\n render={(e) => (\n <Text wrap=\"truncate-end\">\n {check(selectedEnvs.has(e.name))}\n <Text bold>{cell(e.name, 18)}</Text>\n <Text\n color={theme.muted}\n >{`${e.databases.length} db · ${e.projects.length} proj`}</Text>\n </Text>\n )}\n />\n )}\n {step === \"items\" && (\n <ScrollList\n items={items}\n index={itemNav.index}\n height={height - 4}\n render={(i) => (\n <Text wrap=\"truncate-end\">\n {check(picked.has(keyOf(i)))}\n <Text color={theme.muted}>{cell(i.env, 16)}</Text>\n {cell(i.kind, 10)}\n <Text bold>{i.name}</Text>\n </Text>\n )}\n />\n )}\n {step === \"confirm\" && (\n <Box flexDirection=\"column\">\n {buildTargets(envs, picked, items).map((t) => (\n <Text key={t.environment} wrap=\"truncate-end\">\n <Text bold>{cell(t.environment, 18)}</Text>\n {t.databases || t.projects\n ? [\n ...(t.databases ?? []).map((d) => `db ${d}`),\n ...(t.projects ?? []).map((p) => `project ${p}`),\n ].join(\", \")\n : \"everything\"}\n </Text>\n ))}\n <Box marginTop={1}>\n <Text color={theme.muted}>\n The job runs detached: you can quit the UI or lose SSH and it keeps going.\n </Text>\n </Box>\n <Text color={theme.accent}>{starting ? \"starting…\" : \"press ⏎ to start\"}</Text>\n </Box>\n )}\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport { useState } from \"react\";\nimport { emptyConfig } from \"../../core/config/defaults.js\";\nimport { ConfigSchema } from \"../../core/config/schema.js\";\nimport { defaultBackupDir } from \"../../core/paths.js\";\nimport { ErrorLine, GradientText, Panel } from \"../components/basics.js\";\nimport { type Field, Form, type Values } from \"../components/Form.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { issuesToErrors, opt, optInt } from \"./forms.js\";\n\nexport function Onboarding() {\n const { services, width, height, save, navigate, theme } = useApp();\n const active = useScreenActive();\n const [values, setValues] = useState<Values>({ backupDir: \"\", keepLast: \"7\", keepDays: \"30\" });\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [general, setGeneral] = useState<string[]>([]);\n useHints([\n { key: \"tab\", label: \"field\" },\n { key: \"ctrl-s\", label: \"continue\" },\n ]);\n\n const submit = async (values: Values) => {\n const base = emptyConfig();\n const parsed = ConfigSchema.safeParse({\n ...base,\n settings: { ...base.settings, backupDir: opt(values.backupDir) },\n retention: { keepLast: optInt(values.keepLast), keepDays: optInt(values.keepDays) },\n });\n if (!parsed.success) {\n const e = issuesToErrors(parsed.error, (p) =>\n p[0] === \"settings\"\n ? \"backupDir\"\n : p[0] === \"retention\"\n ? typeof p[1] === \"string\"\n ? p[1]\n : \"keepLast\"\n : null,\n );\n setErrors(e.fields);\n setGeneral(e.general);\n return;\n }\n if (await save(parsed.data, `created ${services.configPath}`)) {\n navigate({ name: \"environment-edit\", onboarding: true }, { replace: true });\n }\n };\n const fields: Field[] = [\n {\n kind: \"text\",\n key: \"backupDir\",\n label: \"Backup dir\",\n placeholder: defaultBackupDir(),\n error: errors.backupDir,\n hint: \"where backups are written; empty = the default shown\",\n },\n {\n kind: \"number\",\n key: \"keepLast\",\n label: \"Keep last\",\n error: errors.keepLast,\n hint: \"newest complete backups to keep per environment\",\n },\n {\n kind: \"number\",\n key: \"keepDays\",\n label: \"Keep days\",\n error: errors.keepDays,\n hint: \"also keep anything younger than this many days\",\n },\n {\n kind: \"action\",\n key: \"continue\",\n label: \"Continue ▸\",\n detail: \"save and add the first environment\",\n onPress: () => void submit(values),\n },\n ];\n return (\n <Panel title=\"Welcome\" width={width} height={height} focused={active} right=\"step 1 of 2\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <GradientText>Let's set up backup-manager</GradientText>\n <Text\n color={theme.muted}\n >{`No config yet at ${services.configPath}. Start with where backups go and how long to keep them.`}</Text>\n </Box>\n <Form\n id=\"onboarding\"\n fields={fields}\n values={values}\n onChange={setValues}\n onSubmit={(v) => void submit(v)}\n onCancel={() => {}}\n isActive={active}\n width={width - 4}\n />\n {general.map((g) => (\n <ErrorLine key={g}>{g}</ErrorLine>\n ))}\n </Panel>\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport type { PrunePlan } from \"../../core/backup/prune.js\";\nimport { effectiveRetention, findEnvironment } from \"../../core/config/defaults.js\";\nimport { formatAge, formatBytes } from \"../../core/format.js\";\nimport { cell, Muted, Panel, Spinner } from \"../components/basics.js\";\nimport { ScrollView } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { usePolling } from \"../hooks/usePolling.js\";\nimport { isDown, isUp } from \"../keys.js\";\n\nexport function Prune() {\n const { services, config, width, height, confirm, toast, theme } = useApp();\n const active = useScreenActive();\n const plans = usePolling<PrunePlan[]>(\n () => (config ? services.planPrune(config) : Promise.resolve([])),\n 0,\n [config],\n );\n const [offset, setOffset] = useState(0);\n const [busy, setBusy] = useState(false);\n useHints([\n { key: \"p\", label: \"apply\" },\n { key: \"r\", label: \"refresh\" },\n { key: \"↑↓\", label: \"scroll\" },\n ]);\n const list = plans.data ?? [];\n const toDelete = list.reduce((s, p) => s + p.delete.length + p.staleTemp.length, 0);\n const freed = list.reduce((s, p) => s + p.freedBytes, 0);\n\n const lines: React.ReactNode[] = [];\n for (const plan of list) {\n const env = config ? findEnvironment(config, plan.environment) : undefined;\n const r = config && env ? effectiveRetention(config, env) : null;\n lines.push(\n <Text>\n <Text bold color={theme.accent}>\n {cell(plan.environment, 18)}\n </Text>\n <Text color={theme.muted}>\n {r ? `keep last ${r.keepLast} or ${r.keepDays} days · ` : \"\"}\n </Text>\n {`keep ${plan.keep.length}, delete ${plan.delete.length}`}\n </Text>,\n );\n for (const b of plan.delete) {\n lines.push(\n <Text color={theme.error} wrap=\"truncate-end\">\n {` ✘ ${cell(b.id, 18)} ${cell(b.status, 11)}${cell(formatBytes(b.size), 10, \"right\")} ${formatAge(b.createdAt)}`}\n </Text>,\n );\n }\n for (const t of plan.staleTemp)\n lines.push(<Text color={theme.warning} wrap=\"truncate-end\">{` ✘ stale ${t}`}</Text>);\n if (plan.delete.length + plan.staleTemp.length === 0)\n lines.push(<Text color={theme.muted}> nothing to delete</Text>);\n }\n const viewHeight = height - 5;\n\n useInput(\n (input, key) => {\n if (isUp(input, key)) setOffset((o) => Math.max(0, o - 1));\n else if (isDown(input, key))\n setOffset((o) => Math.min(Math.max(0, lines.length - viewHeight), o + 1));\n else if (input === \"r\") plans.refresh();\n else if (input === \"p\" && toDelete > 0 && !busy) {\n void (async () => {\n const ok = await confirm({\n title: \"Apply retention\",\n message: `Delete ${toDelete} item(s) and free ${formatBytes(freed)}? This cannot be undone.`,\n confirmLabel: \"Delete\",\n danger: true,\n });\n if (!ok) return;\n setBusy(true);\n const r = await services.applyPrune(list);\n setBusy(false);\n toast(\n r.errors.length\n ? `deleted ${r.deleted}; ${r.errors[0]}`\n : `deleted ${r.deleted} item(s)`,\n r.errors.length ? \"warning\" : \"success\",\n );\n plans.refresh();\n })();\n }\n },\n { isActive: active },\n );\n return (\n <Panel title=\"Prune\" width={width} height={height} focused={active} right=\"dry run\">\n <Box marginBottom={1}>\n {plans.loading || busy ? (\n <Spinner label={busy ? \"deleting…\" : \"computing…\"} />\n ) : (\n <Text>\n {toDelete ? (\n <Text\n color={theme.warning}\n >{`${toDelete} item(s) to delete, ${formatBytes(freed)} to free`}</Text>\n ) : (\n <Text color={theme.success}>✔ everything is within the retention policy</Text>\n )}\n </Text>\n )}\n </Box>\n {list.length === 0 && !plans.loading ? (\n <Muted>No environments.</Muted>\n ) : (\n <ScrollView lines={lines} height={viewHeight} offset={offset} />\n )}\n </Panel>\n );\n}\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport { timezone } from \"../../core/config/defaults.js\";\nimport { formatDateTime } from \"../../core/format.js\";\nimport { nextRun } from \"../../core/schedule.js\";\nimport type { ServiceStatus } from \"../../core/service/manager.js\";\nimport { Badge, cell, Muted, Panel, Spinner } from \"../components/basics.js\";\nimport { ScrollView } from \"../components/ScrollList.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { usePolling } from \"../hooks/usePolling.js\";\nimport { useListNav } from \"../keys.js\";\n\ntype Action = \"install\" | \"uninstall\" | \"start\" | \"stop\" | \"restart\" | \"reload\";\nconst ACTIONS: { action: Action; label: string; describe: string }[] = [\n {\n action: \"install\",\n label: \"Install / update\",\n describe: \"write the unit, enable --now, enable linger\",\n },\n { action: \"start\", label: \"Start\", describe: \"systemctl --user start bkm\" },\n { action: \"stop\", label: \"Stop\", describe: \"systemctl --user stop bkm\" },\n { action: \"restart\", label: \"Restart\", describe: \"systemctl --user restart bkm\" },\n { action: \"reload\", label: \"Reload config\", describe: \"systemctl --user reload bkm (SIGHUP)\" },\n {\n action: \"uninstall\",\n label: \"Uninstall\",\n describe: \"disable --now and remove the unit (data kept)\",\n },\n];\n\nfunction StatusPanel({ s, width }: { s: ServiceStatus | undefined | null; width: number }) {\n const { theme } = useApp();\n const row = (label: string, value: React.ReactNode) => (\n <Text wrap=\"truncate-end\">\n <Text color={theme.muted}>{cell(label, 10)}</Text>\n {value}\n </Text>\n );\n if (!s) return <Spinner label=\"checking systemd…\" />;\n if (!s.available)\n return (\n <Text\n color={theme.warning}\n >{`systemctl --user is unavailable: ${s.error ?? \"unknown\"}`}</Text>\n );\n const active = s.activeState === \"active\";\n return (\n <Box flexDirection=\"column\" width={width}>\n <Box gap={1}>\n {s.installed ? (\n <Badge color={active ? theme.success : theme.warning}>\n {active ? \"ACTIVE\" : s.activeState.toUpperCase()}\n </Badge>\n ) : (\n <Badge color={theme.muted}>NOT INSTALLED</Badge>\n )}\n {s.outdated ? <Badge color={theme.warning}>OUTDATED</Badge> : null}\n {s.linger === false ? <Badge color={theme.warning}>NO LINGER</Badge> : null}\n </Box>\n {row(\"state\", `${s.activeState} (${s.subState})${s.mainPid ? ` · pid ${s.mainPid}` : \"\"}`)}\n {row(\"enabled\", s.enabled)}\n {row(\n \"linger\",\n s.linger === null\n ? \"unknown\"\n : s.linger\n ? \"yes: runs at boot and after logout\"\n : \"no: stops when you log out\",\n )}\n {row(\"unit\", s.unitPath)}\n {s.outdated ? (\n <Text color={theme.warning}>\n The unit points to an old node or bkm path: choose Install / update.\n </Text>\n ) : null}\n </Box>\n );\n}\n\nexport function Service() {\n const { services, config, width, height, confirm, toast, theme } = useApp();\n const active = useScreenActive();\n const status = usePolling(() => services.service.status(), 5000);\n const logs = usePolling(() => services.service.logs(200), 5000);\n const [busy, setBusy] = useState<string | null>(null);\n const run = async (action: Action) => {\n if (busy) return;\n if (action === \"uninstall\" || action === \"stop\") {\n const ok = await confirm({\n title: action === \"stop\" ? \"Stop the service\" : \"Uninstall the service\",\n message:\n action === \"stop\"\n ? \"Scheduled backups stop until you start it again.\"\n : \"Disable and remove the user unit? Config, backups and job history are kept.\",\n confirmLabel: action === \"stop\" ? \"Stop\" : \"Uninstall\",\n danger: true,\n });\n if (!ok) return;\n }\n setBusy(action);\n try {\n if (action === \"install\") {\n const r = await services.service.install({ force: status.data?.outdated });\n toast(\n r.warnings[0] ??\n (r.actions.length ? \"service installed and running\" : \"service already up to date\"),\n r.warnings.length ? \"warning\" : \"success\",\n );\n } else if (action === \"uninstall\") {\n await services.service.uninstall();\n toast(\"service removed\", \"success\");\n } else {\n await services.service.control(action);\n toast(`${action} done`, \"success\");\n }\n } catch (error) {\n toast((error as Error).message, \"error\");\n } finally {\n setBusy(null);\n status.refresh();\n logs.refresh();\n }\n };\n const nav = useListNav(ACTIONS.length, {\n isActive: active,\n onSelect: (i) => void run(ACTIONS[i]!.action),\n });\n useHints([\n { key: \"↑↓\", label: \"action\" },\n { key: \"⏎\", label: \"run\" },\n { key: \"r\", label: \"refresh\" },\n ]);\n useInput(\n (input) => {\n if (input === \"r\") {\n status.refresh();\n logs.refresh();\n }\n },\n { isActive: active },\n );\n\n const half = Math.floor(width / 2);\n const tz = config ? timezone(config) : undefined;\n const api = config?.api;\n const topHeight = 9;\n const lines = (logs.data ?? []).map((l, i) => (\n <Text\n // biome-ignore lint/suspicious/noArrayIndexKey: journal lines are positional and may repeat\n key={`${i}:${l}`}\n wrap=\"truncate-end\"\n color={/error|fail/i.test(l) ? theme.error : /warn/i.test(l) ? theme.warning : undefined}\n >\n {l}\n </Text>\n ));\n const logHeight = Math.max(3, height - topHeight - 4);\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Panel title=\"Service · bkm\" width={half} height={topHeight}>\n <StatusPanel s={status.data} width={half - 4} />\n </Panel>\n <Panel title=\"Actions\" width={width - half} height={topHeight} focused={active}>\n {ACTIONS.map((a, i) => (\n <Text key={a.action} wrap=\"truncate-end\">\n <Text color={theme.accent}>{i === nav.index && active ? \"❯ \" : \" \"}</Text>\n <Text bold={i === nav.index}>{cell(a.label, 17)}</Text>\n {busy === a.action ? <Spinner /> : <Text color={theme.muted}>{a.describe}</Text>}\n </Text>\n ))}\n </Panel>\n </Box>\n <Panel title=\"Schedules & API\" width={width}>\n <Text wrap=\"truncate-end\">\n {(config?.environments ?? [])\n .filter((e) => e.schedule)\n .map((e) => {\n const n = nextRun(e.schedule, tz);\n return `${e.name} ${n ? formatDateTime(n) : \"—\"}`;\n })\n .join(\" · \") || \"no schedules\"}\n <Text\n color={theme.muted}\n >{` api ${api?.enabled ? `http://${api.host}:${api.port}${api.token || api.tokenFile ? \" (token)\" : \"\"}` : \"disabled\"}`}</Text>\n </Text>\n </Panel>\n <Panel title=\"journalctl --user -u bkm\" width={width}>\n {lines.length ? (\n <ScrollView\n lines={lines}\n height={logHeight}\n offset={Math.max(0, lines.length - logHeight)}\n />\n ) : (\n <Muted>{logs.loading ? \"loading…\" : \"no log lines\"}</Muted>\n )}\n </Panel>\n </Box>\n );\n}\n","import { Box, Text } from \"ink\";\nimport { useState } from \"react\";\nimport { emptyConfig } from \"../../core/config/defaults.js\";\nimport { type Config, ConfigSchema } from \"../../core/config/schema.js\";\nimport { defaultBackupDir, defaultStateDir } from \"../../core/paths.js\";\nimport { systemTimezone } from \"../../core/schedule.js\";\nimport { ErrorLine, Panel } from \"../components/basics.js\";\nimport { type Field, Form, type Values } from \"../components/Form.js\";\nimport { useApp, useHints, useScreenActive } from \"../context.js\";\nimport { issuesToErrors, opt, optInt } from \"./forms.js\";\n\nexport function settingsValues(c: Config): Values {\n return {\n backupDir: c.settings.backupDir ?? \"\",\n stateDir: c.settings.stateDir ?? \"\",\n compressLevel: String(c.settings.compressLevel),\n autoPrune: c.settings.autoPrune,\n timezone: c.settings.timezone ?? \"\",\n maxConcurrentJobs: String(c.settings.maxConcurrentJobs),\n keepLast: String(c.retention.keepLast),\n keepDays: String(c.retention.keepDays),\n apiEnabled: c.api.enabled,\n apiHost: c.api.host,\n apiPort: String(c.api.port),\n apiToken: c.api.token ?? \"\",\n apiTokenFile: c.api.tokenFile ?? \"\",\n };\n}\n\nexport function applySettings(c: Config, v: Values): unknown {\n return {\n ...c,\n settings: {\n backupDir: opt(v.backupDir),\n stateDir: opt(v.stateDir),\n compressLevel: optInt(v.compressLevel),\n autoPrune: Boolean(v.autoPrune),\n timezone: opt(v.timezone),\n maxConcurrentJobs: optInt(v.maxConcurrentJobs),\n },\n retention: { keepLast: optInt(v.keepLast), keepDays: optInt(v.keepDays) },\n api: {\n enabled: Boolean(v.apiEnabled),\n host: opt(v.apiHost),\n port: optInt(v.apiPort),\n token: opt(v.apiToken),\n tokenFile: opt(v.apiTokenFile),\n },\n };\n}\n\nconst PATH_KEYS: Record<string, string> = {\n \"settings.backupDir\": \"backupDir\",\n \"settings.stateDir\": \"stateDir\",\n \"settings.compressLevel\": \"compressLevel\",\n \"settings.timezone\": \"timezone\",\n \"settings.maxConcurrentJobs\": \"maxConcurrentJobs\",\n \"retention.keepLast\": \"keepLast\",\n \"retention.keepDays\": \"keepDays\",\n retention: \"keepLast\",\n \"api.host\": \"apiHost\",\n \"api.port\": \"apiPort\",\n \"api.token\": \"apiToken\",\n \"api.tokenFile\": \"apiTokenFile\",\n};\n\nexport function Settings() {\n const { config, width, height, save, back, confirm } = useApp();\n const active = useScreenActive();\n const [values, setValues] = useState<Values>(() => settingsValues(config ?? emptyConfig()));\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [general, setGeneral] = useState<string[]>([]);\n useHints([\n { key: \"tab\", label: \"field\" },\n { key: \"space\", label: \"toggle\" },\n { key: \"ctrl-s\", label: \"save\" },\n { key: \"esc\", label: \"leave\" },\n ]);\n if (!config) return null;\n\n const submit = async (current: Values) => {\n const parsed = ConfigSchema.safeParse(applySettings(config, current));\n if (!parsed.success) {\n const e = issuesToErrors(\n parsed.error,\n (p) => PATH_KEYS[p.slice(0, 2).join(\".\")] ?? PATH_KEYS[String(p[0])] ?? null,\n );\n setErrors(e.fields);\n setGeneral(e.general);\n return;\n }\n setErrors({});\n setGeneral([]);\n await save(parsed.data, \"settings saved\");\n };\n const fields: Field[] = [\n { kind: \"heading\", key: \"h1\", label: \"Storage\" },\n {\n kind: \"text\",\n key: \"backupDir\",\n label: \"Backup dir\",\n placeholder: defaultBackupDir(),\n error: errors.backupDir,\n },\n {\n kind: \"text\",\n key: \"stateDir\",\n label: \"State dir\",\n placeholder: defaultStateDir(),\n error: errors.stateDir,\n hint: \"jobs, logs, locks and schedule state\",\n },\n {\n kind: \"number\",\n key: \"compressLevel\",\n label: \"Compression\",\n error: errors.compressLevel,\n hint: \"gzip level 1 (fast) … 9 (small)\",\n },\n { kind: \"heading\", key: \"h2\", label: \"Retention\" },\n {\n kind: \"number\",\n key: \"keepLast\",\n label: \"Keep last\",\n error: errors.keepLast,\n hint: \"newest complete backups kept per environment\",\n },\n {\n kind: \"number\",\n key: \"keepDays\",\n label: \"Keep days\",\n error: errors.keepDays,\n hint: \"complete backups younger than this are kept\",\n },\n {\n kind: \"toggle\",\n key: \"autoPrune\",\n label: \"Auto prune\",\n hint: \"apply retention after every complete backup\",\n },\n { kind: \"heading\", key: \"h3\", label: \"Scheduler\" },\n {\n kind: \"text\",\n key: \"timezone\",\n label: \"Timezone\",\n placeholder: systemTimezone(),\n error: errors.timezone,\n },\n {\n kind: \"number\",\n key: \"maxConcurrentJobs\",\n label: \"Max parallel jobs\",\n error: errors.maxConcurrentJobs,\n },\n { kind: \"heading\", key: \"h4\", label: \"HTTP API (served by the daemon)\" },\n { kind: \"toggle\", key: \"apiEnabled\", label: \"Enabled\" },\n {\n kind: \"text\",\n key: \"apiHost\",\n label: \"Host\",\n error: errors.apiHost,\n hint: \"127.0.0.1 keeps it local; other addresses should use a token\",\n },\n { kind: \"number\", key: \"apiPort\", label: \"Port\", error: errors.apiPort },\n {\n kind: \"password\",\n key: \"apiToken\",\n label: \"Token\",\n error: errors.apiToken,\n placeholder: \"none\",\n },\n {\n kind: \"text\",\n key: \"apiTokenFile\",\n label: \"Token file\",\n error: errors.apiTokenFile,\n placeholder: \"none\",\n },\n ];\n return (\n <Panel title=\"Settings\" width={width} height={height} focused={active}>\n <Form\n id=\"settings\"\n fields={fields}\n values={values}\n onChange={setValues}\n onSubmit={(v) => void submit(v)}\n onCancel={() =>\n void (async () => {\n const dirty = JSON.stringify(values) !== JSON.stringify(settingsValues(config));\n if (\n !dirty ||\n (await confirm({\n title: \"Discard changes\",\n message: \"Leave Settings without saving?\",\n confirmLabel: \"Discard\",\n danger: true,\n }))\n )\n back();\n })()\n }\n isActive={active}\n width={width - 4}\n height={height - 3 - general.length}\n />\n <Box flexDirection=\"column\">\n {general.map((g) => (\n <ErrorLine key={g}>{g}</ErrorLine>\n ))}\n </Box>\n <Text> </Text>\n </Panel>\n );\n}\n","import type { Route } from \"../router.js\";\nimport { BackupDetail, Backups } from \"./Backups.js\";\nimport { Dashboard } from \"./Dashboard.js\";\nimport { Doctor } from \"./Doctor.js\";\nimport { EnvironmentEdit } from \"./EnvironmentEdit.js\";\nimport { Environments } from \"./Environments.js\";\nimport { JobLive, Jobs } from \"./Jobs.js\";\nimport { NewBackup } from \"./NewBackup.js\";\nimport { Onboarding } from \"./Onboarding.js\";\nimport { Prune } from \"./Prune.js\";\nimport { Service } from \"./Service.js\";\nimport { Settings } from \"./Settings.js\";\n\nexport function Screen({ route }: { route: Route }) {\n switch (route.name) {\n case \"onboarding\":\n return <Onboarding />;\n case \"dashboard\":\n return <Dashboard />;\n case \"environments\":\n return <Environments />;\n case \"environment-edit\":\n return (\n <EnvironmentEdit\n key={route.env ?? \"new\"}\n envName={route.env}\n onboarding={route.onboarding}\n />\n );\n case \"backups\":\n return <Backups key={route.env ?? \"all\"} envName={route.env} />;\n case \"backup-detail\":\n return <BackupDetail envName={route.env} id={route.id} />;\n case \"jobs\":\n return <Jobs />;\n case \"job-live\":\n return <JobLive key={route.id} id={route.id} />;\n case \"new-backup\":\n return <NewBackup envName={route.env} />;\n case \"prune\":\n return <Prune />;\n case \"service\":\n return <Service />;\n case \"doctor\":\n return <Doctor />;\n case \"settings\":\n return <Settings />;\n }\n}\n","import { Box, Text, useApp as useInkApp, useInput, useWindowSize } from \"ink\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ConfigMissingError } from \"../core/config/load.js\";\nimport type { Config } from \"../core/config/schema.js\";\nimport { ConfigConflictError } from \"../core/config/store.js\";\nimport type { ServiceStatus } from \"../core/service/manager.js\";\nimport type { Services } from \"../core/services.js\";\nimport { Footer, Header, SIDEBAR_WIDTH, Sidebar, TabBar, WIDE } from \"./components/Frame.js\";\nimport { ConfirmBody, HelpBody, Modal, Toasts, TooSmall } from \"./components/Overlay.js\";\nimport {\n type AppContextValue,\n type ConfirmOptions,\n type KeyHint,\n Provider,\n type Toast,\n type ToastKind,\n useApp as useAppCtx,\n} from \"./context.js\";\nimport { usePolling } from \"./hooks/usePolling.js\";\nimport { isDown, isUp } from \"./keys.js\";\nimport { MENU, menuIndex, type Route } from \"./router.js\";\nimport { Screen } from \"./screens/index.js\";\nimport { makeTheme, type Theme } from \"./theme.js\";\n\nexport interface AppProps {\n services: Services;\n /** Fixed terminal size (tests); defaults to the live window size. */\n size?: { columns: number; rows: number };\n initialRoute?: Route;\n theme?: Theme;\n /** Poll intervals in ms (tests shorten them). */\n intervals?: { service?: number; jobs?: number };\n}\n\ntype ModalState =\n | { kind: \"confirm\"; options: ConfirmOptions; resolve: (ok: boolean) => void; choice: boolean }\n | { kind: \"help\" }\n | null;\n\nconst GLOBAL_HINTS: KeyHint[] = [\n { key: \"tab\", label: \"pane\" },\n { key: \"?\", label: \"help\" },\n { key: \"q\", label: \"quit\" },\n];\n\nexport function App(props: AppProps) {\n const { services } = props;\n const window = useWindowSize();\n const size = props.size ?? { columns: window.columns || 100, rows: window.rows || 30 };\n const theme = useMemo(() => props.theme ?? makeTheme(), [props.theme]);\n const ink = useInkApp();\n\n const [config, setConfig] = useState<Config | null>(null);\n const [configError, setConfigError] = useState<string | null>(null);\n const [ready, setReady] = useState(false);\n const mtime = useRef<number | null>(null);\n const [stack, setStack] = useState<Route[]>([props.initialRoute ?? { name: \"dashboard\" }]);\n const route = stack[stack.length - 1] as Route;\n const [focus, setFocus] = useState<\"sidebar\" | \"content\">(\"content\");\n const [sidebarIndex, setSidebarIndex] = useState(0);\n const [captures, setCaptures] = useState<string[]>([]);\n const [hints, setHints] = useState<KeyHint[]>([]);\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [modal, setModal] = useState<ModalState>(null);\n const toastId = useRef(0);\n const backHandler = useRef<(() => boolean) | null>(null);\n const memory = useRef(new Map<string, unknown>()).current;\n const setBackHandler = useCallback((handler: (() => boolean) | null) => {\n backHandler.current = handler;\n }, []);\n const [now, setNow] = useState(Date.now());\n\n const toast = useCallback((text: string, kind: ToastKind = \"info\") => {\n const id = ++toastId.current;\n setToasts((t) => [...t.slice(-3), { id, text, kind, createdAt: Date.now() }]);\n setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 3000).unref?.();\n }, []);\n\n useEffect(() => {\n if (toasts.length === 0) return;\n const timer = setInterval(() => setNow(Date.now()), 300);\n return () => clearInterval(timer);\n }, [toasts.length]);\n\n const reload = useCallback(async () => {\n try {\n const loaded = await services.load();\n setConfig(loaded.config);\n mtime.current = loaded.mtimeMs;\n setConfigError(null);\n } catch (error) {\n if (error instanceof ConfigMissingError) {\n setConfig(null);\n mtime.current = null;\n setConfigError(null);\n setStack([{ name: \"onboarding\" }]);\n } else {\n setConfigError((error as Error).message);\n }\n } finally {\n setReady(true);\n }\n }, [services]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n const save = useCallback(\n async (next: Config, message = \"saved\") => {\n try {\n const saved = await services.save(next, mtime.current);\n mtime.current = saved.mtimeMs;\n setConfig(next);\n setConfigError(null);\n toast(message, \"success\");\n return true;\n } catch (error) {\n if (error instanceof ConfigConflictError) {\n toast(\"config.json changed on disk; reloaded it, re-apply your change\", \"warning\");\n await reload();\n } else {\n toast((error as Error).message.split(\"\\n\").slice(0, 2).join(\" \"), \"error\");\n }\n return false;\n }\n },\n [services, toast, reload],\n );\n\n const navigate = useCallback((next: Route, options: { replace?: boolean } = {}) => {\n setStack((s) => (options.replace ? [...s.slice(0, -1), next] : [...s, next].slice(-20)));\n setFocus(\"content\");\n }, []);\n\n const back = useCallback(() => {\n setStack((s) =>\n s.length > 1\n ? s.slice(0, -1)\n : s[0]?.name === \"dashboard\" || s[0]?.name === \"onboarding\"\n ? s\n : [{ name: \"dashboard\" }],\n );\n }, []);\n\n const confirm = useCallback(\n (options: ConfirmOptions) =>\n new Promise<boolean>((resolve) =>\n setModal({ kind: \"confirm\", options, resolve, choice: !options.danger }),\n ),\n [],\n );\n\n const setCapture = useCallback((owner: string, active: boolean) => {\n setCaptures((c) =>\n active ? (c.includes(owner) ? c : [...c, owner]) : c.filter((o) => o !== owner),\n );\n }, []);\n\n const service = usePolling<ServiceStatus | null>(\n () => services.service.status().catch(() => null),\n props.intervals?.service ?? 5000,\n );\n const running = usePolling(\n async () =>\n config\n ? (await services.jobs(config, 20)).filter(\n (j) => j.status === \"running\" || j.status === \"queued\",\n ).length\n : 0,\n props.intervals?.jobs ?? 2000,\n [config],\n );\n\n const captured = captures.length > 0;\n const wide = size.columns >= WIDE;\n const current = menuIndex(route);\n\n const closeModal = (result?: boolean) => {\n if (modal?.kind === \"confirm\") modal.resolve(result ?? false);\n setModal(null);\n };\n\n useInput(\n (input, key) => {\n if (!modal) return;\n if (modal.kind === \"help\") return closeModal();\n if (input === \"y\") return closeModal(true);\n if (input === \"n\" || key.escape) return closeModal(false);\n if (key.leftArrow || key.rightArrow || key.tab)\n return setModal({ ...modal, choice: !modal.choice });\n if (key.return) return closeModal(modal.choice);\n },\n { isActive: modal !== null },\n );\n\n useInput(\n (input, key) => {\n if (input === \"q\") return ink.exit();\n if (input === \"?\") return setModal({ kind: \"help\" });\n if (!config) return;\n const item = MENU.find((m) => m.key === input || m.alias === input);\n if (item) {\n setStack([item.route]);\n setFocus(\"content\");\n return;\n }\n if (key.tab) {\n setSidebarIndex(current);\n return setFocus((f) => (f === \"content\" && wide ? \"sidebar\" : \"content\"));\n }\n if (key.escape) {\n if (focus === \"content\" && backHandler.current?.()) return;\n if (stack.length > 1) back();\n else if (wide) {\n setSidebarIndex(current);\n setFocus(\"sidebar\");\n }\n }\n },\n { isActive: !captured && modal === null },\n );\n\n useInput(\n (input, key) => {\n if (isUp(input, key)) setSidebarIndex((i) => (i - 1 + MENU.length) % MENU.length);\n else if (isDown(input, key)) setSidebarIndex((i) => (i + 1) % MENU.length);\n else if (key.return || key.rightArrow) {\n const item = MENU[sidebarIndex];\n if (item) {\n setStack([item.route]);\n setFocus(\"content\");\n }\n }\n },\n { isActive: focus === \"sidebar\" && !captured && modal === null && config !== null },\n );\n\n const bodyHeight = size.rows - 2 - (wide ? 0 : 1);\n const contentWidth = wide ? size.columns - SIDEBAR_WIDTH - 1 : size.columns;\n\n const ctx: AppContextValue = {\n services,\n theme,\n config,\n configError,\n route,\n navigate,\n back,\n reload,\n save,\n toast,\n confirm,\n contentFocused: focus === \"content\",\n modalOpen: modal !== null,\n width: contentWidth,\n height: bodyHeight,\n setCapture,\n setHints,\n setBackHandler,\n memory,\n };\n\n if (size.columns < 60 || size.rows < 16) {\n return (\n <Provider value={ctx}>\n <TooSmall theme={theme} columns={size.columns} rows={size.rows} />\n <QuitOnQ />\n </Provider>\n );\n }\n\n return (\n <Provider value={ctx}>\n <Box flexDirection=\"column\" width={size.columns} height={size.rows}>\n <Header\n theme={theme}\n columns={size.columns}\n service={service.data}\n envCount={config?.environments.length ?? 0}\n />\n {!wide && <TabBar theme={theme} columns={size.columns} current={current} />}\n <Box flexDirection=\"row\" height={bodyHeight} gap={1}>\n {wide && (\n <Sidebar\n theme={theme}\n height={bodyHeight}\n selected={sidebarIndex}\n current={current}\n focused={focus === \"sidebar\"}\n counters={{ jobs: running.data ?? 0 }}\n />\n )}\n <Box flexDirection=\"column\" width={contentWidth} height={bodyHeight}>\n {!ready ? (\n <Text color={theme.muted}>loading…</Text>\n ) : configError && !config ? (\n <ConfigErrorView message={configError} />\n ) : (\n <Screen route={route} />\n )}\n </Box>\n </Box>\n <Footer\n theme={theme}\n columns={size.columns}\n hints={hints}\n global={captured ? [] : GLOBAL_HINTS}\n />\n <Toasts theme={theme} toasts={toasts} now={now} />\n {modal?.kind === \"help\" && (\n <Modal theme={theme} width={64} columns={size.columns} rows={size.rows} title=\"Keys\">\n <HelpBody theme={theme} />\n </Modal>\n )}\n {modal?.kind === \"confirm\" && (\n <Modal\n theme={theme}\n width={60}\n columns={size.columns}\n rows={size.rows}\n title={modal.options.title}\n danger={modal.options.danger}\n >\n <ConfirmBody theme={theme} options={modal.options} choice={modal.choice} />\n </Modal>\n )}\n </Box>\n </Provider>\n );\n}\n\nfunction QuitOnQ() {\n const ink = useInkApp();\n useInput((input) => {\n if (input === \"q\") ink.exit();\n });\n return null;\n}\n\nfunction ConfigErrorView({ message }: { message: string }) {\n const { theme, reload, setHints } = useAppCtx();\n useEffect(() => setHints([{ key: \"r\", label: \"reload\" }]), [setHints]);\n useInput((input) => {\n if (input === \"r\") void reload();\n });\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n <Text color={theme.error} bold>\n The config file has errors\n </Text>\n <Box marginY={1} flexDirection=\"column\">\n {message.split(\"\\n\").map((line) => (\n <Text key={line} color={theme.error}>\n {line}\n </Text>\n ))}\n </Box>\n <Text color={theme.muted}>\n Fix the file (or restore config.json.bak) and press r to reload.\n </Text>\n </Box>\n );\n}\n","import { render } from \"ink\";\nimport type { Services } from \"../core/services.js\";\nimport { App } from \"./App.js\";\n\n/** Full-screen UI on the alternate screen; the terminal is restored on exit and Ctrl-C. */\nexport async function runUi(services: Services): Promise<number> {\n const app = render(<App services={services} />, {\n alternateScreen: true,\n maxFps: 30,\n exitOnCtrlC: true,\n });\n await app.waitUntilExit();\n return 0;\n}\n","import { fileURLToPath } from \"node:url\";\nimport { main } from \"./cli/program.js\";\nimport { setJobCommand } from \"./core/jobs/runner.js\";\n\n// Jobs and the systemd unit re-invoke this same entry point with the same node flags.\nsetJobCommand({\n command: process.execPath,\n args: [...process.execArgv, fileURLToPath(import.meta.url)],\n});\n\nconst code = await main(process.argv.slice(2));\nprocess.exitCode = code;\n","import { Command, CommanderError } from \"commander\";\nimport { stateDir } from \"../core/config/defaults.js\";\nimport { ConfigError, ConfigMissingError, loadConfig } from \"../core/config/load.js\";\nimport { consoleLogger, type DaemonLogger, runDaemon } from \"../core/daemon/daemon.js\";\nimport { EXIT_FAILURE, EXIT_OK, executeJob } from \"../core/jobs/runner.js\";\nimport { resolveConfigPath } from \"../core/paths.js\";\nimport type { CommandRunner } from \"../core/service/systemctl.js\";\nimport { Services } from \"../core/services.js\";\nimport { doctorText, type PrintOptions, printOptions } from \"../ui/print/print.js\";\nimport { VERSION } from \"../version.js\";\n\nexport const EXIT_USAGE = 2;\n\nexport interface CliIO {\n out(text: string): void;\n err(text: string): void;\n isTTY: boolean;\n print: PrintOptions;\n}\n\nexport interface CliDeps {\n io?: CliIO;\n runner?: CommandRunner;\n unitFile?: string;\n env?: NodeJS.ProcessEnv;\n /** Opens the full-screen UI; resolves with the exit code. */\n launchUi?: (services: Services) => Promise<number>;\n daemonLog?: DaemonLogger;\n /** Overrides runDaemon (tests). */\n daemon?: typeof runDaemon;\n}\n\nexport const processIO = (): CliIO => ({\n out: (t) => process.stdout.write(t.endsWith(\"\\n\") ? t : `${t}\\n`),\n err: (t) => process.stderr.write(t.endsWith(\"\\n\") ? t : `${t}\\n`),\n isTTY: Boolean(process.stdout.isTTY && process.stdin.isTTY),\n print: printOptions(process.stdout),\n});\n\nconst NO_CONFIG_HINT = \"run `bkm` in a terminal first to create one\";\n\n/** Parses argv (without node and script) and runs the command. Returns the exit code. */\nexport async function main(argv: string[], deps: CliDeps = {}): Promise<number> {\n const io = deps.io ?? processIO();\n const env = deps.env ?? process.env;\n let code = EXIT_OK;\n const services = (configPath: string) =>\n new Services({ configPath, runner: deps.runner, unitFile: deps.unitFile });\n\n const program = new Command(\"bkm\")\n .description(\"Back up MariaDB databases and Laravel storage per environment.\")\n .version(VERSION, \"-v, --version\")\n .option(\n \"-c, --config <path>\",\n \"config file (default: $BKM_CONFIG or ~/.config/backup-manager/config.json)\",\n )\n .showHelpAfterError(\"(run `bkm --help` for usage)\")\n .exitOverride()\n .configureOutput({ writeOut: (s) => io.out(s), writeErr: (s) => io.err(s) });\n\n const configPath = () => resolveConfigPath(program.opts<{ config?: string }>().config, env);\n\n async function requireConfig(path: string) {\n try {\n return await loadConfig(path);\n } catch (error) {\n if (error instanceof ConfigMissingError) {\n io.err(`bkm: no config at ${path}; ${NO_CONFIG_HINT}`);\n } else {\n io.err(`bkm: ${(error as Error).message}`);\n }\n code = EXIT_USAGE;\n return null;\n }\n }\n\n program.action(async () => {\n if (!io.isTTY) {\n io.err(program.helpInformation());\n io.err(\"bkm: the interactive UI needs a terminal (TTY)\");\n code = EXIT_USAGE;\n return;\n }\n const launch =\n deps.launchUi ?? (async (s: Services) => (await import(\"../ui/main.js\")).runUi(s));\n code = await launch(services(configPath()));\n });\n\n program\n .command(\"doctor\")\n .description(\"check config, tools, directories, project access, databases and the service\")\n .option(\"--no-db\", \"skip database connection checks\")\n .action(async (opts: { db: boolean }) => {\n const path = configPath();\n const report = await services(path).doctor({ db: opts.db });\n if (report.missingConfig) {\n io.err(`bkm: no config at ${path}; ${NO_CONFIG_HINT}`);\n code = EXIT_USAGE;\n return;\n }\n io.out(doctorText(report, io.print));\n code = report.ok ? EXIT_OK : EXIT_FAILURE;\n });\n\n program\n .command(\"daemon\")\n .description(\"run the scheduler and API in the foreground (what the systemd service starts)\")\n .action(async () => {\n const path = configPath();\n if (!(await requireConfig(path))) return;\n const run = deps.daemon ?? runDaemon;\n try {\n code = await run({ services: services(path), log: deps.daemonLog ?? consoleLogger });\n } catch (error) {\n io.err(`bkm daemon: ${(error as Error).message}`);\n code = error instanceof ConfigError ? EXIT_USAGE : EXIT_FAILURE;\n }\n });\n\n program\n .command(\"__job <id>\", { hidden: true })\n .description(\"run a queued backup job (internal)\")\n .action(async (id: string) => {\n const path = configPath();\n const loaded = await requireConfig(path);\n if (!loaded) return;\n code = await executeJob(stateDir(loaded.config), id, path);\n });\n\n try {\n await program.parseAsync(argv, { from: \"user\" });\n } catch (error) {\n if (error instanceof CommanderError) {\n if (\n error.code === \"commander.helpDisplayed\" ||\n error.code === \"commander.version\" ||\n error.code === \"commander.help\"\n ) {\n return EXIT_OK;\n }\n return EXIT_USAGE;\n }\n io.err(`bkm: ${(error as Error).message}`);\n return EXIT_FAILURE;\n }\n return code;\n}\n","import type { ChildProcess } from \"node:child_process\";\nimport { type FSWatcher, watch } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport type { Server } from \"node:http\";\nimport path from \"node:path\";\nimport { serve } from \"@hono/node-server\";\nimport { createApi } from \"../../api/server.js\";\nimport { stateDir, timezone } from \"../config/defaults.js\";\nimport type { ApiSettings, Config } from \"../config/schema.js\";\nimport { startJob } from \"../jobs/runner.js\";\nimport { type JobTrigger, updateJob } from \"../jobs/store.js\";\nimport { expandHome } from \"../paths.js\";\nimport type { Services } from \"../services.js\";\nimport { planCatchUp, readScheduleState, writeScheduleState } from \"./catchup.js\";\nimport { Scheduler } from \"./scheduler.js\";\n\nexport interface DaemonLogger {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n}\n\nexport const consoleLogger: DaemonLogger = {\n info: (m) => console.log(m),\n warn: (m) => console.warn(`warning: ${m}`),\n error: (m) => console.error(`error: ${m}`),\n};\n\nexport interface DaemonOptions {\n services: Services;\n log?: DaemonLogger;\n /** How long SIGTERM waits for running jobs before killing them. */\n graceMs?: number;\n debounceMs?: number;\n /** Watch the config file for changes (disable in tests that drive reload()). */\n watchConfig?: boolean;\n now?: () => Date;\n}\n\ninterface Running {\n environment: string;\n jobId: string;\n child: ChildProcess;\n exited: Promise<void>;\n}\n\nconst LOOPBACK = new Set([\"127.0.0.1\", \"::1\", \"localhost\"]);\n\n/** `bkm daemon`: per-environment schedules, catch-up, config reload and the HTTP API. */\nexport class Daemon {\n readonly services: Services;\n private readonly log: DaemonLogger;\n private config!: Config;\n private scheduler: Scheduler;\n private queue: { environment: string; trigger: JobTrigger; scheduledAt: Date }[] = [];\n private running = new Map<string, Running>();\n private server: Server | null = null;\n private apiKey = \"\";\n private watcher: FSWatcher | null = null;\n private debounce: NodeJS.Timeout | null = null;\n private stopping = false;\n private stateWrite: Promise<void> = Promise.resolve();\n readonly startedAt = new Date();\n /** Resolves after every job started so far has exited (for tests). */\n lastJob: Promise<void> = Promise.resolve();\n\n constructor(private readonly options: DaemonOptions) {\n this.services = options.services;\n this.log = options.log ?? consoleLogger;\n this.scheduler = new Scheduler((env, at) => this.onFire(env, at));\n }\n\n get currentConfig(): Config {\n return this.config;\n }\n\n get runningEnvironments(): string[] {\n return [...this.running.keys()];\n }\n\n get queued(): string[] {\n return this.queue.map((q) => q.environment);\n }\n\n get apiAddress(): string | null {\n const address = this.server?.address();\n if (!address || typeof address === \"string\") return null;\n const host = address.family === \"IPv6\" ? `[${address.address}]` : address.address;\n return `http://${host}:${address.port}`;\n }\n\n private now(): Date {\n return this.options.now?.() ?? new Date();\n }\n\n async start(): Promise<void> {\n const { config } = await this.services.load();\n this.config = config;\n this.log.info(`backup-manager daemon starting (config ${this.services.configPath})`);\n this.applySchedules();\n await this.catchUp();\n await this.applyApi();\n if (this.options.watchConfig !== false) this.watchConfig();\n this.log.info(`ready: ${this.describeSchedules()}`);\n }\n\n private describeSchedules(): string {\n const runs = this.scheduler.nextRuns();\n if (runs.length === 0) return \"no scheduled environments\";\n return runs\n .map((r) => `${r.environment} next ${r.nextRun?.toISOString() ?? \"never\"}`)\n .join(\", \");\n }\n\n nextRuns() {\n return this.scheduler.nextRuns();\n }\n\n private scheduled() {\n return this.config.environments\n .filter((e) => e.schedule)\n .map((e) => ({ environment: e.name, schedule: e.schedule as string }));\n }\n\n private applySchedules() {\n const tz = timezone(this.config);\n const { added, removed, changed } = this.scheduler.apply(this.scheduled(), tz);\n for (const n of added) this.log.info(`scheduled ${n}`);\n for (const n of changed) this.log.info(`rescheduled ${n}`);\n for (const n of removed) this.log.info(`unscheduled ${n}`);\n }\n\n private async catchUp() {\n const state = await readScheduleState(stateDir(this.config));\n const plan = planCatchUp(this.scheduled(), state, this.now(), timezone(this.config));\n await this.saveScheduleState(plan.state);\n for (const d of plan.decisions) {\n if (d.missed) {\n this.log.info(`${d.environment}: missed run at ${d.missed.toISOString()}, catching up`);\n this.enqueue(d.environment, \"catch-up\", d.missed);\n }\n }\n }\n\n private saveScheduleState(state: Awaited<ReturnType<typeof readScheduleState>>) {\n const dir = stateDir(this.config);\n this.stateWrite = this.stateWrite\n .then(() => writeScheduleState(dir, state))\n .catch((e) => {\n this.log.warn(`cannot write schedule state: ${(e as Error).message}`);\n });\n return this.stateWrite;\n }\n\n private recordFire(environment: string, at: Date) {\n const env = this.config.environments.find((e) => e.name === environment);\n if (!env?.schedule) return;\n const dir = stateDir(this.config);\n const schedule = env.schedule;\n this.stateWrite = this.stateWrite\n .then(async () => {\n const state = await readScheduleState(dir);\n state[environment] = { schedule, lastFire: at.toISOString() };\n await writeScheduleState(dir, state);\n })\n .catch((e) => this.log.warn(`cannot write schedule state: ${(e as Error).message}`));\n }\n\n private onFire(environment: string, scheduledAt: Date) {\n if (this.stopping) return;\n this.recordFire(environment, scheduledAt);\n this.enqueue(environment, \"schedule\", scheduledAt);\n }\n\n /** Queue a run unless the environment is already running or queued. */\n enqueue(environment: string, trigger: JobTrigger, scheduledAt = this.now()): boolean {\n if (this.running.has(environment) || this.queue.some((q) => q.environment === environment)) {\n this.log.warn(`${environment}: previous run still in progress, skipping ${trigger} run`);\n return false;\n }\n this.queue.push({ environment, trigger, scheduledAt });\n this.drain();\n return true;\n }\n\n private drain() {\n while (\n !this.stopping &&\n this.queue.length &&\n this.running.size < this.config.settings.maxConcurrentJobs\n ) {\n const next = this.queue.shift()!;\n void this.launch(next.environment, next.trigger);\n }\n }\n\n private async launch(environment: string, trigger: JobTrigger) {\n const placeholder = {\n environment,\n jobId: \"\",\n child: null as unknown as ChildProcess,\n exited: Promise.resolve(),\n };\n this.running.set(environment, placeholder);\n try {\n const { job, child } = await startJob(\n stateDir(this.config),\n this.services.configPath,\n [{ environment }],\n {\n trigger,\n detached: false,\n },\n );\n const exited = new Promise<void>((resolve) => {\n child.once(\"exit\", (code, signal) => {\n this.running.delete(environment);\n this.log.info(`${environment}: job ${job.id} finished (${signal ?? `exit ${code}`})`);\n resolve();\n this.drain();\n });\n });\n this.running.set(environment, { environment, jobId: job.id, child, exited });\n this.lastJob = Promise.all([this.lastJob, exited]).then(() => {});\n this.log.info(`${environment}: started ${trigger} job ${job.id} (pid ${child.pid ?? \"?\"})`);\n } catch (error) {\n this.running.delete(environment);\n this.log.error(`${environment}: cannot start job: ${(error as Error).message}`);\n this.drain();\n }\n }\n\n private async tokenFor(api: ApiSettings): Promise<string | null> {\n if (api.token) return api.token;\n if (api.tokenFile) {\n try {\n return (\n (await readFile(expandHome(api.tokenFile), \"utf8\")).split(/\\r?\\n/, 1)[0]?.trim() || null\n );\n } catch (error) {\n this.log.error(`cannot read api.tokenFile: ${(error as Error).message}`);\n return null;\n }\n }\n return null;\n }\n\n private async applyApi() {\n const api = this.config.api;\n const token = await this.tokenFor(api);\n const key = api.enabled ? JSON.stringify([api.host, api.port, token]) : \"\";\n if (key === this.apiKey && (this.server !== null) === api.enabled) return;\n await this.closeApi();\n this.apiKey = key;\n if (!api.enabled) {\n this.log.info(\"api disabled\");\n return;\n }\n if (!LOOPBACK.has(api.host) && !token) {\n this.log.warn(\n `api listens on ${api.host} without a token; anyone who can reach it can read backup metadata`,\n );\n }\n const app = createApi({\n services: this.services,\n getConfig: () => this.config,\n token,\n startedAt: this.startedAt,\n log: (m) => this.log.error(m),\n });\n await new Promise<void>((resolve) => {\n const server = serve({ fetch: app.fetch, hostname: api.host, port: api.port }, () =>\n resolve(),\n ) as Server;\n server.once(\"error\", (error) => {\n this.log.error(`api cannot listen on ${api.host}:${api.port}: ${error.message}`);\n this.server = null;\n this.apiKey = \"\";\n resolve();\n });\n this.server = server;\n });\n if (this.server) this.log.info(`api listening on ${this.apiAddress}`);\n }\n\n private async closeApi() {\n const server = this.server;\n this.server = null;\n if (!server) return;\n await new Promise<void>((resolve) => {\n server.close(() => resolve());\n server.closeAllConnections?.();\n });\n }\n\n private watchConfig() {\n const file = this.services.configPath;\n try {\n this.watcher = watch(path.dirname(file), (_event, name) => {\n if (name && name.toString() !== path.basename(file)) return;\n if (this.debounce) clearTimeout(this.debounce);\n this.debounce = setTimeout(\n () => void this.reload(\"config file changed\"),\n this.options.debounceMs ?? 500,\n );\n });\n } catch (error) {\n this.log.warn(\n `cannot watch ${file}: ${(error as Error).message}; use \\`systemctl --user reload bkm\\``,\n );\n }\n }\n\n /** Re-read the config; an invalid file keeps the current one. */\n async reload(reason = \"reload requested\"): Promise<boolean> {\n if (this.stopping) return false;\n try {\n const { config } = await this.services.load();\n if (JSON.stringify(config) === JSON.stringify(this.config)) {\n this.log.info(`${reason}: no changes`);\n return true;\n }\n this.config = config;\n this.log.info(`${reason}: configuration reloaded`);\n this.applySchedules();\n await this.applyApi();\n this.drain();\n return true;\n } catch (error) {\n this.log.error(`${reason}: keeping the previous configuration: ${(error as Error).message}`);\n return false;\n }\n }\n\n /** Stop scheduling and the API, wait for running jobs (up to the grace period), then kill them. */\n async stop(): Promise<void> {\n if (this.stopping) return;\n this.stopping = true;\n this.log.info(\"stopping\");\n this.scheduler.stop();\n this.queue = [];\n this.watcher?.close();\n if (this.debounce) clearTimeout(this.debounce);\n await this.closeApi();\n const running = [...this.running.values()].filter((r) => r.child);\n if (running.length) {\n this.log.info(`waiting for ${running.length} running job(s)`);\n const grace = this.options.graceMs ?? 5 * 60_000;\n const all = Promise.all(running.map((r) => r.exited));\n const timedOut = await Promise.race([all.then(() => false), sleep(grace).then(() => true)]);\n if (timedOut) {\n this.log.warn(\"grace period over, cancelling running jobs\");\n for (const r of running) r.child.kill(\"SIGTERM\");\n const killed = await Promise.race([all.then(() => false), sleep(10_000).then(() => true)]);\n if (killed) {\n for (const r of running) {\n r.child.kill(\"SIGKILL\");\n await updateJob(stateDir(this.config), r.jobId, {\n status: \"failed\",\n error: \"killed when the daemon stopped\",\n finishedAt: new Date().toISOString(),\n });\n }\n }\n }\n }\n await this.stateWrite;\n this.log.info(\"stopped\");\n }\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms).unref());\n\n/** Run until SIGTERM/SIGINT; SIGHUP reloads. Used by `bkm daemon`. */\nexport async function runDaemon(options: DaemonOptions): Promise<number> {\n const daemon = new Daemon(options);\n await daemon.start();\n return new Promise<number>((resolve) => {\n const onHup = () => void daemon.reload(\"SIGHUP\");\n const onStop = (signal: NodeJS.Signals) => {\n (options.log ?? consoleLogger).info(`received ${signal}`);\n process.off(\"SIGHUP\", onHup);\n process.off(\"SIGTERM\", onStop);\n process.off(\"SIGINT\", onStop);\n void daemon.stop().then(() => resolve(0));\n };\n process.on(\"SIGHUP\", onHup);\n process.on(\"SIGTERM\", onStop);\n process.on(\"SIGINT\", onStop);\n });\n}\n","import { timingSafeEqual } from \"node:crypto\";\nimport { swaggerUI } from \"@hono/swagger-ui\";\nimport { createRoute, OpenAPIHono, z } from \"@hono/zod-openapi\";\nimport type { BackupInfo } from \"../core/backup/catalog.js\";\nimport {\n effectiveRetention,\n envBackupDir,\n findEnvironment,\n timezone,\n} from \"../core/config/defaults.js\";\nimport type { Config, Database } from \"../core/config/schema.js\";\nimport type { JobRecord } from \"../core/jobs/store.js\";\nimport { nextRun } from \"../core/schedule.js\";\nimport type { Services } from \"../core/services.js\";\nimport { VERSION } from \"../version.js\";\n\nexport interface ApiOptions {\n services: Services;\n /** Current config (the daemon swaps it on reload). */\n getConfig: () => Config;\n token?: string | null;\n startedAt?: Date;\n log?: (message: string) => void;\n}\n\nconst ErrorBody = z.object({ error: z.string() }).openapi(\"Error\");\nconst Status = z.enum([\"complete\", \"partial\", \"incomplete\"]);\n\nconst BackupSummary = z\n .object({\n id: z.string(),\n environment: z.string(),\n status: Status,\n createdAt: z.string(),\n size: z.number(),\n items: z.number(),\n failed: z.number(),\n })\n .openapi(\"BackupSummary\");\n\nconst BackupItem = z\n .object({\n kind: z.enum([\"database\", \"project\"]),\n name: z.string(),\n file: z.string().nullable(),\n size: z.number(),\n sha256: z.string().nullable(),\n durationMs: z.number(),\n status: z.enum([\"success\", \"failed\"]),\n error: z.string().optional(),\n warnings: z.array(z.string()).optional(),\n detail: z.string().optional(),\n })\n .openapi(\"BackupItem\");\n\nconst BackupDetail = BackupSummary.extend({\n finishedAt: z.string().nullable(),\n trigger: z.string().nullable(),\n jobId: z.string().nullable(),\n contents: z.array(BackupItem),\n}).openapi(\"BackupDetail\");\n\nconst EnvironmentSummary = z\n .object({\n name: z.string(),\n schedule: z.string().nullable(),\n nextRun: z.string().nullable(),\n databases: z.number(),\n projects: z.number(),\n backups: z.number(),\n totalSize: z.number(),\n lastBackup: BackupSummary.nullable(),\n running: z.boolean(),\n })\n .openapi(\"EnvironmentSummary\");\n\nconst EnvironmentDetail = EnvironmentSummary.extend({\n backupDir: z.string(),\n retention: z.object({ keepLast: z.number(), keepDays: z.number() }),\n}).openapi(\"EnvironmentDetail\");\n\nconst Project = z\n .object({\n name: z.string(),\n path: z.string(),\n include: z.array(z.string()),\n exclude: z.array(z.string()),\n })\n .openapi(\"Project\");\n\nconst DatabaseOut = z\n .object({\n name: z.string(),\n type: z.enum([\"laravel\", \"connection\"]),\n project: z.string().nullable(),\n host: z.string().nullable(),\n port: z.number().nullable(),\n socket: z.string().nullable(),\n schemas: z.array(z.string()).nullable(),\n })\n .openapi(\"Database\");\n\nconst Job = z\n .object({\n id: z.string(),\n status: z.enum([\"queued\", \"running\", \"success\", \"partial\", \"failed\"]),\n trigger: z.enum([\"ui\", \"schedule\", \"catch-up\"]),\n environments: z.array(z.string()),\n createdAt: z.string(),\n startedAt: z.string().nullable(),\n finishedAt: z.string().nullable(),\n backups: z.array(\n z.object({\n environment: z.string(),\n backupId: z.string().nullable(),\n status: z.string(),\n error: z.string().optional(),\n }),\n ),\n error: z.string().nullable(),\n })\n .openapi(\"Job\");\n\nconst Health = z\n .object({\n status: z.literal(\"ok\"),\n version: z.string(),\n uptimeSeconds: z.number(),\n environments: z.number(),\n nextRuns: z.array(z.object({ environment: z.string(), nextRun: z.string() })),\n })\n .openapi(\"Health\");\n\nconst EnvParam = z.object({\n env: z.string().openapi({ param: { name: \"env\", in: \"path\" }, example: \"production\" }),\n});\nconst json = <T extends z.ZodType>(schema: T, description: string) => ({\n content: { \"application/json\": { schema } },\n description,\n});\nconst secured = [{ bearer: [] }];\nconst notFound = { 404: json(ErrorBody, \"Not found\") };\n\nfunction backupSummary(b: BackupInfo): z.infer<typeof BackupSummary> {\n return {\n id: b.id,\n environment: b.environment,\n status: b.status,\n createdAt: b.createdAt.toISOString(),\n size: b.size,\n items: b.itemCount,\n failed: b.failedCount,\n };\n}\n\n/** Only non-secret connection fields: never user, password or passwordFile, nor extraArgs. */\nfunction databaseOut(db: Database): z.infer<typeof DatabaseOut> {\n const s = db.source;\n return {\n name: db.name,\n type: s.type,\n project: s.type === \"laravel\" ? s.project : null,\n host: s.host ?? null,\n port: s.port ?? null,\n socket: s.socket ?? null,\n schemas: s.type === \"connection\" ? s.schemas : s.database ? [s.database] : null,\n };\n}\n\nfunction jobOut(j: JobRecord): z.infer<typeof Job> {\n return {\n id: j.id,\n status: j.status,\n trigger: j.trigger,\n environments: j.targets.map((t) => t.environment),\n createdAt: j.createdAt,\n startedAt: j.startedAt ?? null,\n finishedAt: j.finishedAt ?? null,\n backups: j.backups,\n error: j.error ?? null,\n };\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const x = Buffer.from(a);\n const y = Buffer.from(b);\n return x.length === y.length && timingSafeEqual(x, y);\n}\n\nconst OPEN_PATHS = new Set([\"/health\", \"/docs\", \"/openapi.json\"]);\n\nexport function createApi(options: ApiOptions) {\n const { services, getConfig } = options;\n const startedAt = options.startedAt ?? new Date();\n const app = new OpenAPIHono({\n defaultHook: (result, c) => {\n if (!result.success) return c.json({ error: \"invalid request\" }, 400);\n },\n });\n\n app.openAPIRegistry.registerComponent(\"securitySchemes\", \"bearer\", {\n type: \"http\",\n scheme: \"bearer\",\n });\n\n app.use(\"*\", async (c, next) => {\n if (options.token && !OPEN_PATHS.has(c.req.path)) {\n const header = c.req.header(\"authorization\") ?? \"\";\n const given = header.startsWith(\"Bearer \") ? header.slice(7) : \"\";\n if (!safeEqual(given, options.token)) return c.json({ error: \"unauthorized\" }, 401);\n }\n await next();\n });\n\n app.onError((error, c) => {\n options.log?.(`api error on ${c.req.path}: ${error.message}`);\n return c.json({ error: \"internal error\" }, 500);\n });\n app.notFound((c) => c.json({ error: \"not found\" }, 404));\n\n const envOr404 = (name: string) => findEnvironment(getConfig(), name);\n\n async function summary(name: string) {\n const config = getConfig();\n const env = findEnvironment(config, name)!;\n const s = await services.summary(config, env);\n return {\n name: s.name,\n schedule: s.schedule,\n nextRun: s.nextRun?.toISOString() ?? null,\n databases: s.databases,\n projects: s.projects,\n backups: s.backups,\n totalSize: s.totalSize,\n lastBackup: s.last ? backupSummary(s.last) : null,\n running: s.runningPid !== null,\n };\n }\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/health\",\n responses: { 200: json(Health, \"Daemon health\") },\n }),\n (c) => {\n const config = getConfig();\n const tz = timezone(config);\n return c.json(\n {\n status: \"ok\" as const,\n version: VERSION,\n uptimeSeconds: Math.round((Date.now() - startedAt.getTime()) / 1000),\n environments: config.environments.length,\n nextRuns: config.environments.flatMap((e) => {\n const next = nextRun(e.schedule, tz);\n return next ? [{ environment: e.name, nextRun: next.toISOString() }] : [];\n }),\n },\n 200,\n );\n },\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/environments\",\n security: secured,\n responses: { 200: json(z.array(EnvironmentSummary), \"Environments\") },\n }),\n async (c) =>\n c.json(await Promise.all(getConfig().environments.map((e) => summary(e.name))), 200),\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/environments/{env}\",\n security: secured,\n request: { params: EnvParam },\n responses: { 200: json(EnvironmentDetail, \"Environment\"), ...notFound },\n }),\n async (c) => {\n const env = envOr404(c.req.valid(\"param\").env);\n if (!env) return c.json({ error: \"unknown environment\" }, 404);\n const config = getConfig();\n return c.json(\n {\n ...(await summary(env.name)),\n backupDir: envBackupDir(config, env),\n retention: effectiveRetention(config, env),\n },\n 200,\n );\n },\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/environments/{env}/projects\",\n security: secured,\n request: { params: EnvParam },\n responses: { 200: json(z.array(Project), \"Projects\"), ...notFound },\n }),\n (c) => {\n const env = envOr404(c.req.valid(\"param\").env);\n if (!env) return c.json({ error: \"unknown environment\" }, 404);\n return c.json(\n env.projects.map(({ name, path, include, exclude }) => ({ name, path, include, exclude })),\n 200,\n );\n },\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/environments/{env}/databases\",\n security: secured,\n request: { params: EnvParam },\n responses: { 200: json(z.array(DatabaseOut), \"Databases (no credentials)\"), ...notFound },\n }),\n (c) => {\n const env = envOr404(c.req.valid(\"param\").env);\n if (!env) return c.json({ error: \"unknown environment\" }, 404);\n return c.json(env.databases.map(databaseOut), 200);\n },\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/environments/{env}/backups\",\n security: secured,\n request: {\n params: EnvParam,\n query: z.object({\n status: Status.optional(),\n limit: z.coerce.number().int().min(1).max(1000).optional(),\n }),\n },\n responses: { 200: json(z.array(BackupSummary), \"Backups, newest first\"), ...notFound },\n }),\n async (c) => {\n const env = envOr404(c.req.valid(\"param\").env);\n if (!env) return c.json({ error: \"unknown environment\" }, 404);\n const { status, limit } = c.req.valid(\"query\");\n const list = await services.backups(getConfig(), env.name, { status, limit });\n return c.json(list.map(backupSummary), 200);\n },\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/environments/{env}/backups/{id}\",\n security: secured,\n request: {\n params: EnvParam.extend({ id: z.string().openapi({ param: { name: \"id\", in: \"path\" } }) }),\n },\n responses: { 200: json(BackupDetail, \"Backup\"), ...notFound },\n }),\n async (c) => {\n const { env: name, id } = c.req.valid(\"param\");\n const env = envOr404(name);\n if (!env) return c.json({ error: \"unknown environment\" }, 404);\n const b = await services.backup(getConfig(), env.name, id);\n if (!b) return c.json({ error: \"unknown backup\" }, 404);\n return c.json(\n {\n ...backupSummary(b),\n finishedAt: b.manifest?.finishedAt ?? null,\n trigger: b.manifest?.trigger ?? null,\n jobId: b.manifest?.jobId ?? null,\n contents: b.manifest?.items ?? [],\n },\n 200,\n );\n },\n );\n\n app.openapi(\n createRoute({\n method: \"get\",\n path: \"/jobs\",\n security: secured,\n request: { query: z.object({ limit: z.coerce.number().int().min(1).max(200).optional() }) },\n responses: { 200: json(z.array(Job), \"Jobs, newest first\") },\n }),\n async (c) =>\n c.json((await services.jobs(getConfig(), c.req.valid(\"query\").limit ?? 50)).map(jobOut), 200),\n );\n\n app.doc31(\"/openapi.json\", {\n openapi: \"3.1.0\",\n info: {\n title: \"backup-manager API\",\n version: VERSION,\n description: \"Read-only view of environments, backups and jobs.\",\n },\n });\n app.get(\"/docs\", swaggerUI({ url: \"/openapi.json\" }));\n return app;\n}\n","import { createRequire } from \"node:module\";\n\n/** The npm package name; `package.json` is matched by it so a stray parent manifest is ignored. */\nexport const PACKAGE_NAME = \"@mateusbmp/backup-manager\";\n\nfunction readVersion(): string {\n try {\n const require = createRequire(import.meta.url);\n for (const candidate of [\"../package.json\", \"../../package.json\"]) {\n try {\n const pkg = require(candidate) as { name?: string; version?: string };\n if (pkg.name === PACKAGE_NAME && pkg.version) return pkg.version;\n } catch {\n // try the next location (src/ in dev, dist/ when built)\n }\n }\n } catch {\n // fall through\n }\n return \"0.0.0\";\n}\n\nexport const VERSION = readVersion();\n","import { type ChildProcess, spawn } from \"node:child_process\";\nimport { closeSync, mkdirSync, openSync } from \"node:fs\";\nimport { acquireLock, LockHeldError } from \"../backup/lock.js\";\nimport { runBackup } from \"../backup/pipeline.js\";\nimport { stateDir as configStateDir, findEnvironment } from \"../config/defaults.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport { isAlive } from \"../process.js\";\nimport { type Emit, eventWriter } from \"./events.js\";\nimport {\n eventsFile,\n type JobBackup,\n type JobRecord,\n type JobTarget,\n type JobTrigger,\n jobState,\n logsDir,\n newJobId,\n outputFile,\n pruneJobs,\n readJob,\n updateJob,\n writeJob,\n} from \"./store.js\";\n\nexport interface JobCommand {\n command: string;\n args: string[];\n}\n\nlet jobCommand: JobCommand = { command: process.execPath, args: [process.argv[1] ?? \"bkm\"] };\n\n/** Set by the CLI entry point: how to re-invoke `bkm` for `bkm __job <id>`. */\nexport function setJobCommand(cmd: JobCommand): void {\n jobCommand = cmd;\n}\n\nexport function getJobCommand(): JobCommand {\n return jobCommand;\n}\n\nexport interface StartOptions {\n trigger: JobTrigger;\n /** true from the UI: own session, survives the parent. false from the daemon. */\n detached: boolean;\n}\n\nexport interface StartedJob {\n job: JobRecord;\n child: ChildProcess;\n}\n\n/** Record a queued job and spawn `bkm __job <id>` to run it. */\nexport async function startJob(\n stateDir: string,\n configPath: string,\n targets: JobTarget[],\n options: StartOptions,\n): Promise<StartedJob> {\n const job: JobRecord = {\n id: newJobId(),\n status: \"queued\",\n trigger: options.trigger,\n targets,\n configPath,\n detached: options.detached,\n pid: null,\n createdAt: new Date().toISOString(),\n backups: [],\n };\n await writeJob(stateDir, job);\n mkdirSync(logsDir(stateDir), { recursive: true, mode: 0o700 });\n const out = openSync(outputFile(stateDir, job.id), \"a\", 0o600);\n let child: ChildProcess;\n try {\n child = spawn(\n jobCommand.command,\n [...jobCommand.args, \"__job\", job.id, \"--config\", configPath],\n {\n detached: options.detached,\n stdio: [\"ignore\", out, out],\n env: { ...process.env, BKM_JOB: job.id },\n },\n );\n } finally {\n closeSync(out);\n }\n child.once(\"error\", (error) => {\n void updateJob(stateDir, job.id, {\n status: \"failed\",\n error: `cannot start job: ${error.message}`,\n });\n });\n if (options.detached) child.unref();\n void pruneJobs(stateDir).catch(() => {});\n return { job, child };\n}\n\n/** Stop a running job: the whole process group for detached jobs, the process otherwise. */\nexport async function killJob(\n stateDir: string,\n id: string,\n signal: NodeJS.Signals = \"SIGTERM\",\n): Promise<boolean> {\n const job = await readJob(stateDir, id);\n if (!job?.pid || !isAlive(job.pid) || ![\"queued\", \"running\"].includes(job.status)) return false;\n try {\n process.kill(job.detached ? -job.pid : job.pid, signal);\n } catch {\n process.kill(job.pid, signal);\n }\n return true;\n}\n\nexport const EXIT_OK = 0;\nexport const EXIT_FAILURE = 1;\nexport const EXIT_LOCKED = 3;\n\n/** Body of `bkm __job <id>`: run every target in this process. Returns the exit code. */\nexport async function executeJob(\n stateDir: string,\n id: string,\n configPath?: string,\n): Promise<number> {\n const job = await readJob(stateDir, id);\n if (!job) {\n console.error(`job ${id} not found in ${stateDir}`);\n return EXIT_FAILURE;\n }\n const emit: Emit = eventWriter(eventsFile(stateDir, id));\n const controller = new AbortController();\n const onSignal = (signal: NodeJS.Signals) => {\n emit({ type: \"log\", level: \"warn\", message: `received ${signal}, cancelling` });\n controller.abort();\n };\n process.on(\"SIGTERM\", onSignal);\n process.on(\"SIGINT\", onSignal);\n process.on(\"SIGHUP\", onSignal);\n await updateJob(stateDir, id, {\n status: \"running\",\n pid: process.pid,\n startedAt: new Date().toISOString(),\n });\n\n const backups: JobBackup[] = [];\n let lockedOnly = true;\n let fatal: string | undefined;\n try {\n const { config } = await loadConfig(configPath ?? job.configPath);\n const state = configStateDir(config);\n for (const target of job.targets) {\n if (controller.signal.aborted) break;\n const env = findEnvironment(config, target.environment);\n if (!env) {\n lockedOnly = false;\n backups.push({\n environment: target.environment,\n backupId: null,\n status: \"failed\",\n error: \"unknown environment\",\n });\n emit({\n type: \"log\",\n level: \"error\",\n message: `unknown environment '${target.environment}'`,\n });\n continue;\n }\n let lock: Awaited<ReturnType<typeof acquireLock>>;\n try {\n lock = await acquireLock(state, env.name);\n } catch (error) {\n if (!(error instanceof LockHeldError)) lockedOnly = false;\n const message = (error as Error).message;\n backups.push({ environment: env.name, backupId: null, status: \"failed\", error: message });\n emit({ type: \"log\", level: \"error\", message, environment: env.name });\n continue;\n }\n lockedOnly = false;\n try {\n const result = await runBackup(\n config,\n env,\n { databases: target.databases, projects: target.projects },\n { emit, signal: controller.signal, jobId: id, trigger: job.trigger },\n );\n backups.push({ environment: env.name, backupId: result.backupId, status: result.status });\n } catch (error) {\n const message = (error as Error).message;\n backups.push({ environment: env.name, backupId: null, status: \"failed\", error: message });\n emit({ type: \"log\", level: \"error\", message, environment: env.name });\n } finally {\n await lock.release();\n }\n }\n } catch (error) {\n fatal = (error as Error).message;\n lockedOnly = false;\n emit({ type: \"log\", level: \"error\", message: fatal });\n } finally {\n process.off(\"SIGTERM\", onSignal);\n process.off(\"SIGINT\", onSignal);\n process.off(\"SIGHUP\", onSignal);\n }\n\n const status = controller.signal.aborted ? \"failed\" : jobState(backups);\n const error = controller.signal.aborted\n ? \"cancelled\"\n : (fatal ?? backups.find((b) => b.error)?.error);\n const exitCode =\n status === \"success\" ? EXIT_OK : lockedOnly && backups.length > 0 ? EXIT_LOCKED : EXIT_FAILURE;\n await updateJob(stateDir, id, {\n status,\n backups,\n exitCode,\n finishedAt: new Date().toISOString(),\n ...(error ? { error } : {}),\n });\n emit({ type: \"job-done\", status, ...(error ? { error } : {}) });\n return exitCode;\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { isAlive } from \"../process.js\";\n\nexport class LockHeldError extends Error {\n constructor(\n readonly environment: string,\n readonly pid: number,\n ) {\n super(`environment '${environment}' is already being backed up (pid ${pid})`);\n this.name = \"LockHeldError\";\n }\n}\n\nexport interface Lock {\n file: string;\n release(): Promise<void>;\n}\n\nexport function lockFile(stateDir: string, environment: string): string {\n return path.join(stateDir, \"locks\", `${environment}.lock`);\n}\n\nasync function holder(file: string): Promise<number | null> {\n try {\n const pid = Number.parseInt((await readFile(file, \"utf8\")).trim(), 10);\n return Number.isFinite(pid) ? pid : null;\n } catch {\n return null;\n }\n}\n\n/** Per-environment pid lock; a lock whose process is gone is taken over. */\nexport async function acquireLock(\n stateDir: string,\n environment: string,\n pid = process.pid,\n): Promise<Lock> {\n const file = lockFile(stateDir, environment);\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n await writeFile(file, `${pid}\\n`, { flag: \"wx\", mode: 0o600 });\n return {\n file,\n release: async () => {\n if ((await holder(file)) === pid) await rm(file, { force: true });\n },\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const current = await holder(file);\n if (current !== null && current !== pid && isAlive(current))\n throw new LockHeldError(environment, current);\n await rm(file, { force: true }); // stale (dead pid, our own pid or unreadable)\n }\n }\n throw new Error(`could not acquire lock ${file}`);\n}\n\n/** Pid holding the environment lock, or null when it is free (or stale). */\nexport async function lockHolder(stateDir: string, environment: string): Promise<number | null> {\n const pid = await holder(lockFile(stateDir, environment));\n return pid !== null && isAlive(pid) ? pid : null;\n}\n","import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { mkdir, rename, rm, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { envBackupDir } from \"../config/defaults.js\";\nimport type { Config, Environment } from \"../config/schema.js\";\nimport { timestampId } from \"../format.js\";\nimport type { Emit } from \"../jobs/events.js\";\nimport { archiveProject } from \"./archive.js\";\nimport { TMP_PREFIX } from \"./catalog.js\";\nimport {\n type BackupStatus,\n backupStatus,\n type Manifest,\n type ManifestItem,\n writeManifest,\n} from \"./manifest.js\";\nimport { describeConnection, dumpDatabase, resolveConnection } from \"./mariadb.js\";\nimport { applyPrune, planPrune } from \"./prune.js\";\n\nexport interface BackupSelection {\n /** Database names to dump; undefined = all. */\n databases?: string[];\n /** Project names to archive; undefined = all. */\n projects?: string[];\n}\n\nexport interface BackupOptions {\n emit?: Emit;\n signal?: AbortSignal;\n jobId?: string;\n trigger?: string;\n now?: () => Date;\n}\n\nexport interface BackupResult {\n backupId: string | null;\n dir: string | null;\n status: BackupStatus | \"failed\";\n manifest: Manifest | null;\n pruned: string[];\n}\n\nexport class NothingToBackUpError extends Error {\n override name = \"NothingToBackUpError\";\n}\n\nasync function sha256(file: string): Promise<string> {\n const hash = createHash(\"sha256\");\n for await (const chunk of createReadStream(file)) hash.update(chunk as Buffer);\n return hash.digest(\"hex\");\n}\n\nasync function freeId(dir: string, base: string): Promise<string> {\n for (let n = 0; ; n++) {\n const id = n === 0 ? base : `${base}-${n}`;\n const taken = await Promise.all([\n stat(path.join(dir, id)).then(\n () => true,\n () => false,\n ),\n stat(path.join(dir, `${TMP_PREFIX}${id}`)).then(\n () => true,\n () => false,\n ),\n ]);\n if (!taken.some(Boolean)) return id;\n }\n}\n\n/**\n * Back up one environment: each database and project is processed in turn inside\n * `.tmp-<id>/`; a failing item does not stop the others. The directory is renamed to\n * `<id>/` at the end, or removed when every item failed. The caller holds the env lock.\n */\nexport async function runBackup(\n config: Config,\n env: Environment,\n selection: BackupSelection = {},\n options: BackupOptions = {},\n): Promise<BackupResult> {\n const emit: Emit = options.emit ?? (() => {});\n const now = options.now ?? (() => new Date());\n const pick = <T extends { name: string }>(all: T[], names?: string[]) =>\n names ? all.filter((x) => names.includes(x.name)) : all;\n const databases = pick(env.databases, selection.databases);\n const projects = pick(env.projects, selection.projects);\n const total = databases.length + projects.length;\n if (total === 0)\n throw new NothingToBackUpError(`environment '${env.name}' has nothing selected to back up`);\n\n const root = envBackupDir(config, env);\n await mkdir(root, { recursive: true, mode: 0o700 });\n const createdAt = now();\n const id = await freeId(root, timestampId(createdAt));\n const work = path.join(root, `${TMP_PREFIX}${id}`);\n await mkdir(work, { mode: 0o700 });\n const level = config.settings.compressLevel;\n const log = (level: \"info\" | \"warn\" | \"error\", message: string) =>\n emit({ type: \"log\", level, message, environment: env.name });\n log(\n \"info\",\n `backup ${id} started (${databases.length} database(s), ${projects.length} project(s))`,\n );\n\n const items: ManifestItem[] = [];\n let index = 0;\n const run = async (\n kind: ManifestItem[\"kind\"],\n name: string,\n relative: string,\n task: (file: string, warnings: string[]) => Promise<string | undefined>,\n ) => {\n index++;\n emit({ type: \"item-start\", environment: env.name, kind, name, index, total });\n const file = path.join(work, relative);\n const started = Date.now();\n const warnings: string[] = [];\n let item: ManifestItem;\n try {\n if (options.signal?.aborted) throw new Error(\"aborted\");\n const detail = await task(file, warnings);\n const size = (await stat(file)).size;\n item = {\n kind,\n name,\n file: relative,\n size,\n sha256: await sha256(file),\n durationMs: Date.now() - started,\n status: \"success\",\n ...(detail ? { detail } : {}),\n };\n } catch (error) {\n await rm(file, { force: true });\n item = {\n kind,\n name,\n file: null,\n size: 0,\n sha256: null,\n durationMs: Date.now() - started,\n status: \"failed\",\n error: (error as Error).message,\n };\n log(\"error\", `${kind} ${name}: ${item.error}`);\n }\n if (warnings.length) item.warnings = warnings;\n for (const w of warnings) log(\"warn\", `${kind} ${name}: ${w}`);\n items.push(item);\n emit({\n type: \"item-done\",\n environment: env.name,\n kind,\n name,\n status: item.status,\n size: item.size,\n durationMs: item.durationMs,\n ...(item.error ? { error: item.error } : {}),\n });\n };\n\n for (const db of databases) {\n await run(\"database\", db.name, `databases/${db.name}.sql.gz`, async (file, warnings) => {\n const conn = await resolveConnection(db, env, (w) => warnings.push(w));\n await dumpDatabase(conn, file, {\n compressLevel: level,\n extraArgs: db.extraArgs,\n signal: options.signal,\n onProgress: (bytes) =>\n emit({\n type: \"item-progress\",\n environment: env.name,\n kind: \"database\",\n name: db.name,\n bytes,\n }),\n });\n return describeConnection(conn);\n });\n }\n for (const project of projects) {\n await run(\n \"project\",\n project.name,\n `projects/${project.name}.tar.gz`,\n async (file, warnings) => {\n const result = await archiveProject(project, file, {\n compressLevel: level,\n signal: options.signal,\n onProgress: ({ files, bytes }) =>\n emit({\n type: \"item-progress\",\n environment: env.name,\n kind: \"project\",\n name: project.name,\n bytes,\n files,\n }),\n });\n warnings.push(...result.warnings);\n return `${result.files} files`;\n },\n );\n }\n\n const status = backupStatus(items);\n if (status === \"incomplete\" || options.signal?.aborted) {\n await rm(work, { recursive: true, force: true });\n log(\n \"error\",\n options.signal?.aborted ? `backup ${id} cancelled` : `backup ${id} failed: every item failed`,\n );\n emit({ type: \"backup-done\", environment: env.name, backupId: null, status: \"failed\" });\n return { backupId: null, dir: null, status: \"failed\", manifest: null, pruned: [] };\n }\n const manifest: Manifest = {\n version: 1,\n id,\n environment: env.name,\n createdAt: createdAt.toISOString(),\n finishedAt: now().toISOString(),\n status,\n ...(options.jobId ? { jobId: options.jobId } : {}),\n ...(options.trigger ? { trigger: options.trigger } : {}),\n totalSize: items.reduce((s, i) => s + i.size, 0),\n items,\n };\n await writeManifest(work, manifest);\n const dir = path.join(root, id);\n await rename(work, dir);\n log(status === \"complete\" ? \"info\" : \"warn\", `backup ${id} ${status}`);\n emit({ type: \"backup-done\", environment: env.name, backupId: id, status });\n\n let pruned: string[] = [];\n if (status === \"complete\" && config.settings.autoPrune) {\n try {\n const plan = await planPrune(config, env, now());\n const result = await applyPrune(plan);\n pruned = result.deleted;\n if (pruned.length) log(\"info\", `pruned ${pruned.length} old backup(s)`);\n for (const e of result.errors) log(\"warn\", `prune: ${e}`);\n } catch (error) {\n log(\"warn\", `prune failed: ${(error as Error).message}`);\n }\n }\n return { backupId: id, dir, status, manifest, pruned };\n}\n","import { lstat, mkdir, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport picomatch from \"picomatch\";\nimport * as tar from \"tar\";\nimport type { Project } from \"../config/schema.js\";\n\nexport class ArchiveError extends Error {\n override name = \"ArchiveError\";\n}\n\nexport interface ArchiveResult {\n files: number;\n bytes: number;\n warnings: string[];\n}\n\nexport interface ArchiveOptions {\n compressLevel?: number;\n onProgress?: (progress: { files: number; bytes: number }) => void;\n signal?: AbortSignal;\n}\n\n/**\n * Builds the exclude test. A `dir/**` pattern excludes everything below `dir` but keeps the\n * (now empty) directory itself, so the structure survives a restore.\n */\nexport function excludeMatcher(\n patterns: readonly string[],\n): (relative: string, isDir: boolean) => boolean {\n const matchers = patterns.map((pattern) => {\n const full = picomatch(pattern, { dot: true });\n const base = pattern.endsWith(\"/**\") ? picomatch(pattern.slice(0, -3), { dot: true }) : null;\n return { full, base };\n });\n return (relative, isDir) =>\n matchers.some(({ full, base }) => full(relative) && !(isDir && base?.(relative)));\n}\n\n/** Archive `project.include` (relative to `project.path`) into a gzip tarball. */\nexport async function archiveProject(\n project: Project,\n destination: string,\n options: ArchiveOptions = {},\n): Promise<ArchiveResult> {\n const warnings: string[] = [];\n const present: string[] = [];\n for (const include of project.include) {\n const relative = path.posix.normalize(include.replace(/\\\\/g, \"/\")).replace(/^\\/+|\\/+$/g, \"\");\n const full = path.join(project.path, relative);\n if (relative.startsWith(\"..\") || path.relative(project.path, full).startsWith(\"..\")) {\n warnings.push(`include '${include}' points outside the project, skipped`);\n continue;\n }\n const info = await lstat(full).catch(() => null);\n if (!info || info.isSymbolicLink()) {\n warnings.push(`include '${include}' not found under ${project.path}, skipped`);\n continue;\n }\n present.push(relative);\n }\n if (present.length === 0) {\n throw new ArchiveError(\n `none of the include paths exist under ${project.path}: ${project.include.join(\", \")}`,\n );\n }\n\n await mkdir(path.dirname(destination), { recursive: true });\n const excluded = excludeMatcher(project.exclude);\n let files = 0;\n let bytes = 0;\n let lastReport = 0;\n try {\n await tar.c(\n {\n gzip: { level: options.compressLevel ?? 6 },\n file: destination,\n cwd: project.path,\n follow: false,\n portable: false,\n mode: 0o600,\n filter: (entryPath, stat) => {\n if (options.signal?.aborted) throw new ArchiveError(\"aborted\");\n const relative = entryPath.replace(/^\\.\\//, \"\");\n const isDir =\n \"isDirectory\" in stat && typeof stat.isDirectory === \"function\" && stat.isDirectory();\n if (excluded(relative, isDir)) return false;\n if (!isDir) {\n files++;\n bytes += \"size\" in stat ? Number(stat.size) || 0 : 0;\n const now = Date.now();\n if (options.onProgress && now - lastReport > 250) {\n lastReport = now;\n options.onProgress({ files, bytes });\n }\n }\n return true;\n },\n },\n present,\n );\n } catch (error) {\n await rm(destination, { force: true });\n throw error instanceof ArchiveError ? error : new ArchiveError((error as Error).message);\n }\n options.onProgress?.({ files, bytes });\n return { files, bytes, warnings };\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { type BackupStatus, type Manifest, readManifest } from \"./manifest.js\";\n\nexport const BACKUP_ID = /^(\\d{4})(\\d{2})(\\d{2})-(\\d{2})(\\d{2})(\\d{2})(?:-(\\d+))?$/;\nexport const TMP_PREFIX = \".tmp-\";\n\nexport interface BackupInfo {\n id: string;\n environment: string;\n dir: string;\n createdAt: Date;\n status: BackupStatus;\n size: number;\n itemCount: number;\n failedCount: number;\n manifest: Manifest | null;\n}\n\nexport function dateFromId(id: string): Date | null {\n const m = BACKUP_ID.exec(id);\n if (!m) return null;\n const [, y, mo, d, h, mi, s] = m.map(Number) as number[];\n return new Date(y!, mo! - 1, d!, h!, mi!, s!);\n}\n\nasync function dirSize(dir: string): Promise<number> {\n let total = 0;\n for (const entry of await readdir(dir, { withFileTypes: true }).catch(() => [])) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) total += await dirSize(full);\n else if (entry.isFile()) total += (await stat(full).catch(() => ({ size: 0 }))).size;\n }\n return total;\n}\n\nexport async function readBackup(\n envDir: string,\n environment: string,\n id: string,\n): Promise<BackupInfo | null> {\n const createdFromId = dateFromId(id);\n if (!createdFromId) return null;\n const dir = path.join(envDir, id);\n const info = await stat(dir).catch(() => null);\n if (!info?.isDirectory()) return null;\n const manifest = await readManifest(dir);\n if (!manifest) {\n return {\n id,\n environment,\n dir,\n createdAt: createdFromId,\n status: \"incomplete\",\n size: await dirSize(dir),\n itemCount: 0,\n failedCount: 0,\n manifest: null,\n };\n }\n const created = new Date(manifest.createdAt);\n return {\n id,\n environment,\n dir,\n createdAt: Number.isNaN(created.getTime()) ? createdFromId : created,\n status: manifest.status,\n size: manifest.totalSize ?? manifest.items.reduce((s, i) => s + (i.size || 0), 0),\n itemCount: manifest.items.length,\n failedCount: manifest.items.filter((i) => i.status === \"failed\").length,\n manifest,\n };\n}\n\n/** All backups of an environment, newest first. A missing directory means no backups. */\nexport async function listBackups(envDir: string, environment: string): Promise<BackupInfo[]> {\n const entries = await readdir(envDir, { withFileTypes: true }).catch(() => []);\n const backups = await Promise.all(\n entries\n .filter((e) => e.isDirectory() && BACKUP_ID.test(e.name))\n .map((e) => readBackup(envDir, environment, e.name)),\n );\n return backups\n .filter((b): b is BackupInfo => b !== null)\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime() || b.id.localeCompare(a.id));\n}\n\n/** `.tmp-<id>` working directories left behind by interrupted runs. */\nexport async function listTempDirs(envDir: string): Promise<{ dir: string; mtime: Date }[]> {\n const entries = await readdir(envDir, { withFileTypes: true }).catch(() => []);\n const out: { dir: string; mtime: Date }[] = [];\n for (const e of entries) {\n if (!e.isDirectory() || !e.name.startsWith(TMP_PREFIX)) continue;\n const dir = path.join(envDir, e.name);\n const s = await stat(dir).catch(() => null);\n if (s) out.push({ dir, mtime: s.mtime });\n }\n return out;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type ItemKind = \"database\" | \"project\";\nexport type ItemStatus = \"success\" | \"failed\";\nexport type BackupStatus = \"complete\" | \"partial\" | \"incomplete\";\n\nexport interface ManifestItem {\n kind: ItemKind;\n name: string;\n /** Path relative to the backup directory, or null when nothing was written. */\n file: string | null;\n size: number;\n sha256: string | null;\n durationMs: number;\n status: ItemStatus;\n error?: string;\n warnings?: string[];\n /** Short human description, e.g. `shop @ 127.0.0.1:3306` or `142 files`. */\n detail?: string;\n}\n\nexport interface Manifest {\n version: 1;\n id: string;\n environment: string;\n createdAt: string;\n finishedAt: string;\n status: BackupStatus;\n jobId?: string;\n trigger?: string;\n totalSize: number;\n items: ManifestItem[];\n}\n\nexport const MANIFEST_FILE = \"manifest.json\";\n\nexport async function writeManifest(dir: string, manifest: Manifest): Promise<void> {\n await writeFile(path.join(dir, MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}\\n`, {\n mode: 0o600,\n });\n}\n\nexport async function readManifest(dir: string): Promise<Manifest | null> {\n try {\n const data = JSON.parse(await readFile(path.join(dir, MANIFEST_FILE), \"utf8\")) as Manifest;\n return data && Array.isArray(data.items) ? data : null;\n } catch {\n return null;\n }\n}\n\nexport function backupStatus(items: ManifestItem[]): BackupStatus {\n const ok = items.filter((i) => i.status === \"success\").length;\n if (items.length > 0 && ok === items.length) return \"complete\";\n return ok > 0 ? \"partial\" : \"incomplete\";\n}\n","import { spawn } from \"node:child_process\";\nimport { createWriteStream } from \"node:fs\";\nimport { mkdir, mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { Transform } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { createGzip } from \"node:zlib\";\nimport type { Database, Environment } from \"../config/schema.js\";\nimport { dotenvGet, loadDotenv } from \"../dotenv.js\";\nimport { expandHome } from \"../paths.js\";\nimport { findExecutable } from \"../process.js\";\n\nexport const DUMP_BINARIES = [\"mariadb-dump\", \"mysqldump\"] as const;\nexport const CLIENT_BINARIES = [\"mariadb\", \"mysql\"] as const;\nexport const DUMP_OPTIONS = [\n \"--single-transaction\",\n \"--quick\",\n \"--routines\",\n \"--triggers\",\n \"--events\",\n \"--hex-blob\",\n] as const;\nconst SUPPORTED = new Set([\"mysql\", \"mariadb\"]);\n\nexport class DumpError extends Error {\n override name = \"DumpError\";\n}\n\nexport interface Connection {\n host?: string;\n port?: number;\n socket?: string;\n user?: string;\n password?: string;\n schemas: string[];\n}\n\nexport function describeConnection(c: Connection): string {\n const where = c.socket ?? `${c.host ?? \"localhost\"}:${c.port ?? 3306}`;\n return `${c.schemas.join(\", \")} @ ${where}`;\n}\n\nasync function readPasswordFile(file: string, dbName: string): Promise<string> {\n try {\n return (await readFile(expandHome(file), \"utf8\")).split(/\\r?\\n/, 1)[0] ?? \"\";\n } catch (error) {\n throw new DumpError(\n `database '${dbName}': cannot read passwordFile: ${(error as Error).message}`,\n );\n }\n}\n\n/** Merge explicit settings over the DB_* values of the linked Laravel project's `.env`. */\nexport async function resolveConnection(\n db: Database,\n env: Environment,\n warn: (message: string) => void = () => {},\n): Promise<Connection> {\n const s = db.source;\n let password = s.password;\n if (s.passwordFile) password = await readPasswordFile(s.passwordFile, db.name);\n const conn: Connection = {\n host: s.host,\n port: s.port,\n socket: s.socket,\n user: s.user,\n password,\n schemas: s.type === \"connection\" ? [...s.schemas] : [],\n };\n if (s.type === \"laravel\") {\n const project = env.projects.find((p) => p.name === s.project);\n if (!project) throw new DumpError(`database '${db.name}': unknown project '${s.project}'`);\n const file = path.join(project.path, \".env\");\n let dotenv: Awaited<ReturnType<typeof loadDotenv>>;\n try {\n dotenv = await loadDotenv(file);\n } catch (error) {\n throw new DumpError(\n `database '${db.name}': cannot read ${file}: ${(error as Error).message}`,\n );\n }\n for (const w of dotenv.warnings) warn(`${file}: ${w}`);\n const driver = (dotenvGet(dotenv, \"DB_CONNECTION\") ?? \"mysql\").toLowerCase();\n if (!SUPPORTED.has(driver)) {\n throw new DumpError(\n `database '${db.name}': ${file} has DB_CONNECTION=${driver}; only mysql/mariadb are supported`,\n );\n }\n conn.host ??= dotenvGet(dotenv, \"DB_HOST\");\n const envPort = dotenvGet(dotenv, \"DB_PORT\");\n if (conn.port === undefined && envPort) {\n const port = Number.parseInt(envPort, 10);\n if (!Number.isInteger(port))\n throw new DumpError(`${file}: DB_PORT is not a number: '${envPort}'`);\n conn.port = port;\n }\n conn.socket ??= dotenvGet(dotenv, \"DB_SOCKET\");\n conn.user ??= dotenvGet(dotenv, \"DB_USERNAME\");\n if (conn.password === undefined) conn.password = dotenv.values.DB_PASSWORD;\n const schema = s.database ?? dotenvGet(dotenv, \"DB_DATABASE\");\n if (schema) conn.schemas = [schema];\n }\n if (conn.schemas.length === 0)\n throw new DumpError(`database '${db.name}': no schema configured or found in .env`);\n return conn;\n}\n\nconst quote = (value: string) => `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n\nexport function renderOptionFile(c: Connection): string {\n const lines = [\"[client]\"];\n if (c.host) lines.push(`host=${quote(c.host)}`);\n if (c.port) lines.push(`port=${c.port}`);\n if (c.socket) lines.push(`socket=${quote(c.socket)}`);\n if (c.user) lines.push(`user=${quote(c.user)}`);\n if (c.password !== undefined) lines.push(`password=${quote(c.password)}`);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** Credentials live only in a private option file that is removed afterwards. */\nexport async function withOptionFile<T>(\n c: Connection,\n fn: (file: string) => Promise<T>,\n): Promise<T> {\n const dir = await mkdtemp(path.join(tmpdir(), \"bkm-\"));\n const file = path.join(dir, \"client.cnf\");\n try {\n await writeFile(file, renderOptionFile(c), { mode: 0o600, flag: \"wx\" });\n return await fn(file);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n}\n\nexport function buildDumpArgs(\n optionFile: string,\n c: Connection,\n extraArgs: readonly string[] = [],\n): string[] {\n const args = [`--defaults-extra-file=${optionFile}`, ...DUMP_OPTIONS, ...extraArgs];\n if (c.schemas.length > 1) args.push(\"--databases\", ...c.schemas);\n else args.push(c.schemas[0] as string);\n return args;\n}\n\nexport async function findDumpBinary(): Promise<string> {\n const found = await findExecutable(DUMP_BINARIES);\n if (!found) throw new DumpError(`none of ${DUMP_BINARIES.join(\", \")} found on PATH`);\n return found;\n}\n\nexport interface DumpOptions {\n compressLevel?: number;\n extraArgs?: readonly string[];\n binary?: string;\n signal?: AbortSignal;\n onProgress?: (bytes: number) => void;\n}\n\n/** Stream `mariadb-dump` stdout through gzip into `destination`. Returns uncompressed bytes. */\nexport async function dumpDatabase(\n c: Connection,\n destination: string,\n options: DumpOptions = {},\n): Promise<number> {\n const binary = options.binary ?? (await findDumpBinary());\n await mkdir(path.dirname(destination), { recursive: true });\n if (options.signal?.aborted) throw new DumpError(\"aborted\");\n return withOptionFile(c, async (optionFile) => {\n const child = spawn(binary, buildDumpArgs(optionFile, c, options.extraArgs), {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const onAbort = () => child.kill(\"SIGTERM\");\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n // the signal may have fired while the option file was being written\n if (options.signal?.aborted) onAbort();\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr = (stderr + chunk).slice(-8192);\n });\n const exited = new Promise<{\n code: number | null;\n signal: NodeJS.Signals | null;\n error?: Error;\n }>((resolve) => {\n child.once(\"error\", (error) => resolve({ code: null, signal: null, error }));\n child.once(\"close\", (code, signal) => resolve({ code, signal }));\n });\n let bytes = 0;\n let last = 0;\n const counter = new Transform({\n transform(chunk: Buffer, _enc, done) {\n bytes += chunk.length;\n const now = Date.now();\n if (options.onProgress && now - last > 250) {\n last = now;\n options.onProgress(bytes);\n }\n done(null, chunk);\n },\n });\n try {\n const [, result] = await Promise.all([\n pipeline(\n child.stdout,\n counter,\n createGzip({ level: options.compressLevel ?? 6 }),\n createWriteStream(destination, { mode: 0o600 }),\n ),\n exited,\n ]);\n if (result.error)\n throw new DumpError(`cannot run ${path.basename(binary)}: ${result.error.message}`);\n if (options.signal?.aborted) throw new DumpError(\"aborted\");\n if (result.code !== 0) {\n const tail = stderr.trim().split(\"\\n\").slice(-5).join(\" | \");\n const how = result.signal\n ? `was killed by ${result.signal}`\n : `exited with status ${result.code}`;\n throw new DumpError(`${path.basename(binary)} ${how}: ${tail || \"no error output\"}`);\n }\n } catch (error) {\n await rm(destination, { force: true });\n throw error instanceof DumpError ? error : new DumpError((error as Error).message);\n } finally {\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n options.onProgress?.(bytes);\n return bytes;\n });\n}\n\n/** Run `SELECT 1` against the first schema; throws `DumpError` with the server message. */\nexport async function checkConnection(\n c: Connection,\n binary?: string,\n timeoutMs = 15_000,\n): Promise<void> {\n const client = binary ?? (await findExecutable(CLIENT_BINARIES));\n if (!client) throw new DumpError(`none of ${CLIENT_BINARIES.join(\", \")} found on PATH`);\n await withOptionFile(c, async (optionFile) => {\n const result = await new Promise<{ code: number | null; stderr: string; error?: Error }>(\n (resolve) => {\n const child = spawn(\n client,\n [`--defaults-extra-file=${optionFile}`, \"-N\", \"-e\", \"SELECT 1\", c.schemas[0] as string],\n {\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n timeout: timeoutMs,\n },\n );\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (d: string) => {\n stderr += d;\n });\n child.once(\"error\", (error) => resolve({ code: null, stderr, error }));\n child.once(\"close\", (code) => resolve({ code, stderr }));\n },\n );\n if (result.error)\n throw new DumpError(`cannot run ${path.basename(client)}: ${result.error.message}`);\n if (result.code !== 0)\n throw new DumpError(result.stderr.trim() || `exit status ${result.code}`);\n });\n}\n","import { readFile } from \"node:fs/promises\";\n\n/**\n * Minimal parser for Laravel `.env` files: `KEY=value`, optional `export` prefix,\n * single/double quoted values, `#` comments and blank lines. `${VAR}` interpolation is\n * not performed; such values are kept verbatim and reported in `warnings`.\n */\nexport interface DotEnv {\n values: Record<string, string>;\n warnings: string[];\n}\n\nconst LINE = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_.]*)\\s*=\\s*(.*)$/;\nconst ESCAPES: Record<string, string> = { n: \"\\n\", r: \"\\r\", t: \"\\t\", '\"': '\"', \"\\\\\": \"\\\\\", $: \"$\" };\n\nfunction unescapeDouble(raw: string): string {\n let out = \"\";\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i];\n if (ch === \"\\\\\" && i + 1 < raw.length) {\n const next = raw[++i] as string;\n out += ESCAPES[next] ?? `\\\\${next}`;\n } else {\n out += ch;\n }\n }\n return out;\n}\n\nfunction parseValue(input: string): string {\n const raw = input.trim();\n if (!raw) return \"\";\n const quote = raw[0];\n if (quote === '\"' || quote === \"'\") {\n for (let i = 1; i < raw.length; i++) {\n if (raw[i] === \"\\\\\" && quote === '\"') {\n i++;\n continue;\n }\n if (raw[i] === quote) {\n const inner = raw.slice(1, i);\n return quote === '\"' ? unescapeDouble(inner) : inner;\n }\n }\n return raw.slice(1); // unterminated quote: be lenient\n }\n return (raw.split(/\\s+#/, 1)[0] ?? \"\").trim();\n}\n\nexport function parseDotenv(text: string): DotEnv {\n const env: DotEnv = { values: {}, warnings: [] };\n text.split(/\\r?\\n/).forEach((line, index) => {\n const stripped = line.trim();\n if (!stripped || stripped.startsWith(\"#\")) return;\n const match = LINE.exec(line);\n if (!match) {\n env.warnings.push(`line ${index + 1}: cannot parse ${JSON.stringify(stripped.slice(0, 40))}`);\n return;\n }\n const key = match[1] as string;\n const value = parseValue(match[2] as string);\n if (value.includes(\"${\")) {\n env.warnings.push(`line ${index + 1}: ${key} uses \\${...} interpolation, not expanded`);\n }\n env.values[key] = value;\n });\n return env;\n}\n\nexport async function loadDotenv(file: string): Promise<DotEnv> {\n return parseDotenv(await readFile(file, \"utf8\"));\n}\n\n/** Value of `key`, treating an empty string as absent. */\nexport function dotenvGet(env: DotEnv, key: string): string | undefined {\n const value = env.values[key];\n return value === undefined || value === \"\" ? undefined : value;\n}\n","import { rm } from \"node:fs/promises\";\nimport { effectiveRetention, envBackupDir } from \"../config/defaults.js\";\nimport type { Config, Environment } from \"../config/schema.js\";\nimport { type BackupInfo, listBackups, listTempDirs } from \"./catalog.js\";\nimport { selectForDeletion } from \"./retention.js\";\n\nexport const STALE_TMP_MS = 24 * 3600_000;\n\nexport interface PrunePlan {\n environment: string;\n keep: BackupInfo[];\n delete: BackupInfo[];\n staleTemp: string[];\n freedBytes: number;\n}\n\nexport async function planPrune(\n config: Config,\n env: Environment,\n now = new Date(),\n): Promise<PrunePlan> {\n const dir = envBackupDir(config, env);\n const backups = await listBackups(dir, env.name);\n const remove = selectForDeletion(backups, effectiveRetention(config, env), now);\n const temps = await listTempDirs(dir);\n return {\n environment: env.name,\n keep: backups.filter((b) => !remove.includes(b)),\n delete: remove,\n staleTemp: temps\n .filter((t) => now.getTime() - t.mtime.getTime() > STALE_TMP_MS)\n .map((t) => t.dir),\n freedBytes: remove.reduce((s, b) => s + b.size, 0),\n };\n}\n\nexport async function applyPrune(\n plan: PrunePlan,\n): Promise<{ deleted: string[]; errors: string[] }> {\n const deleted: string[] = [];\n const errors: string[] = [];\n for (const dir of [...plan.delete.map((b) => b.dir), ...plan.staleTemp]) {\n try {\n await rm(dir, { recursive: true, force: true });\n deleted.push(dir);\n } catch (error) {\n errors.push(`${dir}: ${(error as Error).message}`);\n }\n }\n return { deleted, errors };\n}\n","import type { Retention } from \"../config/schema.js\";\nimport type { BackupInfo } from \"./catalog.js\";\n\nconst DAY = 86_400_000;\n\n/**\n * Backups the policy no longer protects, newest first. Pure logic.\n *\n * - Complete backups are kept when among the newest `keepLast` complete ones **or** younger\n * than `keepDays` (0 disables a rule). The newest complete backup is always kept.\n * - Partial/incomplete backups are kept when younger than `keepDays` or newer than the newest\n * complete backup, so failures since the last good run stay inspectable.\n */\nexport function selectForDeletion<T extends Pick<BackupInfo, \"id\" | \"createdAt\" | \"status\">>(\n backups: readonly T[],\n retention: Retention,\n now: Date,\n): T[] {\n const ordered = [...backups].sort(\n (a, b) => b.createdAt.getTime() - a.createdAt.getTime() || b.id.localeCompare(a.id),\n );\n const young = (b: T) =>\n retention.keepDays > 0 && now.getTime() - b.createdAt.getTime() < retention.keepDays * DAY;\n const complete = ordered.filter((b) => b.status === \"complete\");\n const newest = complete[0];\n return ordered.filter((b) => {\n if (b.status === \"complete\") {\n const rank = complete.indexOf(b);\n return !(b === newest || rank < retention.keepLast || young(b));\n }\n const newerThanGood = !newest || b.createdAt.getTime() > newest.createdAt.getTime();\n return !(young(b) || newerThanGood);\n });\n}\n","import { appendFileSync, mkdirSync } from \"node:fs\";\nimport { open } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { BackupStatus, ItemKind, ItemStatus } from \"../backup/manifest.js\";\n\nexport type LogLevel = \"info\" | \"warn\" | \"error\";\n\nexport type JobEvent =\n | { type: \"log\"; ts: string; level: LogLevel; message: string; environment?: string }\n | {\n type: \"item-start\";\n ts: string;\n environment: string;\n kind: ItemKind;\n name: string;\n index: number;\n total: number;\n }\n | {\n type: \"item-progress\";\n ts: string;\n environment: string;\n kind: ItemKind;\n name: string;\n bytes: number;\n files?: number;\n }\n | {\n type: \"item-done\";\n ts: string;\n environment: string;\n kind: ItemKind;\n name: string;\n status: ItemStatus;\n size: number;\n durationMs: number;\n error?: string;\n }\n | {\n type: \"backup-done\";\n ts: string;\n environment: string;\n backupId: string | null;\n status: BackupStatus | \"failed\";\n }\n | { type: \"job-done\"; ts: string; status: string; error?: string };\n\n/** Distributive Omit so each variant keeps its own fields. */\nexport type JobEventInput = JobEvent extends infer E\n ? E extends JobEvent\n ? Omit<E, \"ts\">\n : never\n : never;\nexport type Emit = (event: JobEventInput) => void;\n\n/** Appends events synchronously so the order on disk matches the order emitted. */\nexport function eventWriter(file: string): Emit {\n mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });\n return (event) => {\n appendFileSync(file, `${JSON.stringify({ ts: new Date().toISOString(), ...event })}\\n`, {\n mode: 0o600,\n });\n };\n}\n\n/** Reads complete lines from `offset`; returns the events and the offset to continue from. */\nexport async function readEvents(\n file: string,\n offset = 0,\n): Promise<{ events: JobEvent[]; offset: number }> {\n let handle: Awaited<ReturnType<typeof open>>;\n try {\n handle = await open(file, \"r\");\n } catch {\n return { events: [], offset };\n }\n try {\n const { size } = await handle.stat();\n if (size <= offset) return { events: [], offset: size < offset ? 0 : offset };\n const buffer = Buffer.alloc(size - offset);\n await handle.read(buffer, 0, buffer.length, offset);\n const text = buffer.toString(\"utf8\");\n const end = text.lastIndexOf(\"\\n\");\n if (end < 0) return { events: [], offset };\n const events: JobEvent[] = [];\n for (const line of text.slice(0, end).split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as JobEvent);\n } catch {\n // ignore a corrupt line\n }\n }\n return { events, offset: offset + Buffer.byteLength(text.slice(0, end + 1)) };\n } finally {\n await handle.close();\n }\n}\n","import { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { previousRun } from \"../schedule.js\";\n\n/** `<stateDir>/schedule.json`: the last scheduled fire time per environment. */\nexport type ScheduleState = Record<string, { schedule: string; lastFire: string }>;\n\nexport const scheduleFile = (stateDir: string) => path.join(stateDir, \"schedule.json\");\n\nexport async function readScheduleState(stateDir: string): Promise<ScheduleState> {\n try {\n const data = JSON.parse(await readFile(scheduleFile(stateDir), \"utf8\"));\n return data && typeof data === \"object\" ? (data as ScheduleState) : {};\n } catch {\n return {};\n }\n}\n\nexport async function writeScheduleState(stateDir: string, state: ScheduleState): Promise<void> {\n const file = scheduleFile(stateDir);\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const tmp = `${file}.${process.pid}.tmp`;\n await writeFile(tmp, `${JSON.stringify(state, null, 2)}\\n`, { mode: 0o600 });\n await rename(tmp, file);\n}\n\nexport interface CatchUpDecision {\n environment: string;\n /** The missed fire time to run now. */\n missed: Date | null;\n}\n\n/**\n * Like systemd `Persistent=true`: when the most recent scheduled time is later than the\n * recorded last fire, that run was missed while the daemon was down and runs once now.\n * Without a record (first start) or after a schedule change, nothing is caught up; the\n * baseline is set to the most recent scheduled time instead.\n */\nexport function planCatchUp(\n schedules: { environment: string; schedule: string }[],\n state: ScheduleState,\n now: Date,\n timezone?: string,\n): { decisions: CatchUpDecision[]; state: ScheduleState } {\n const next: ScheduleState = {};\n const decisions: CatchUpDecision[] = [];\n for (const { environment, schedule } of schedules) {\n const previous = previousRun(schedule, now, timezone);\n const record = state[environment];\n let missed: Date | null = null;\n if (\n record &&\n record.schedule === schedule &&\n previous &&\n previous.getTime() > new Date(record.lastFire).getTime()\n ) {\n missed = previous;\n }\n decisions.push({ environment, missed });\n const baseline = previous ?? now;\n next[environment] = {\n schedule,\n lastFire:\n record && record.schedule === schedule && !missed\n ? record.lastFire\n : baseline.toISOString(),\n };\n }\n return { decisions, state: next };\n}\n","import { Cron } from \"croner\";\n\nexport interface ScheduledEnv {\n environment: string;\n schedule: string;\n}\n\n/** One croner job per scheduled environment, rebuilt on every `apply`. */\nexport class Scheduler {\n private jobs = new Map<string, { schedule: string; cron: Cron }>();\n private timezone: string | undefined;\n\n constructor(private readonly onFire: (environment: string, scheduledAt: Date) => void) {}\n\n apply(\n envs: ScheduledEnv[],\n timezone?: string,\n ): { added: string[]; removed: string[]; changed: string[] } {\n const tzChanged = timezone !== this.timezone;\n this.timezone = timezone;\n const wanted = new Map(envs.map((e) => [e.environment, e.schedule]));\n const added: string[] = [];\n const removed: string[] = [];\n const changed: string[] = [];\n for (const [name, job] of this.jobs) {\n const schedule = wanted.get(name);\n if (schedule === undefined) {\n job.cron.stop();\n this.jobs.delete(name);\n removed.push(name);\n } else if (schedule !== job.schedule || tzChanged) {\n job.cron.stop();\n this.jobs.delete(name);\n changed.push(name);\n }\n }\n for (const [name, schedule] of wanted) {\n if (this.jobs.has(name)) continue;\n if (!changed.includes(name)) added.push(name);\n const cron = new Cron(\n schedule,\n { ...(timezone ? { timezone } : {}), catch: true },\n (self: Cron) => {\n this.onFire(name, self.currentRun() ?? new Date());\n },\n );\n this.jobs.set(name, { schedule, cron });\n }\n return { added, removed, changed };\n }\n\n nextRuns(): { environment: string; nextRun: Date | null }[] {\n return [...this.jobs].map(([environment, job]) => ({\n environment,\n nextRun: job.cron.nextRun(),\n }));\n }\n\n stop(): void {\n for (const job of this.jobs.values()) job.cron.stop();\n this.jobs.clear();\n }\n}\n","import { type BackupInfo, listBackups, readBackup } from \"./backup/catalog.js\";\nimport { lockHolder } from \"./backup/lock.js\";\nimport { checkConnection, resolveConnection } from \"./backup/mariadb.js\";\nimport { applyPrune, type PrunePlan, planPrune } from \"./backup/prune.js\";\nimport { envBackupDir, findEnvironment, stateDir, timezone } from \"./config/defaults.js\";\nimport { type LoadedConfig, loadConfig } from \"./config/load.js\";\nimport type { Config, Database, Environment } from \"./config/schema.js\";\nimport { saveConfig } from \"./config/store.js\";\nimport { type DoctorReport, runDoctor } from \"./doctor.js\";\nimport { type JobEvent, readEvents } from \"./jobs/events.js\";\nimport { killJob, startJob } from \"./jobs/runner.js\";\nimport {\n eventsFile,\n type JobRecord,\n type JobTarget,\n type JobTrigger,\n listJobs,\n readJob,\n} from \"./jobs/store.js\";\nimport { nextRun, nextRuns } from \"./schedule.js\";\nimport { ServiceManager } from \"./service/manager.js\";\nimport type { CommandRunner } from \"./service/systemctl.js\";\n\nexport interface EnvironmentSummary {\n name: string;\n dir: string;\n databases: number;\n projects: number;\n backups: number;\n totalSize: number;\n last: BackupInfo | null;\n lastComplete: BackupInfo | null;\n schedule: string | null;\n nextRun: Date | null;\n /** pid holding the environment lock, if a backup is running. */\n runningPid: number | null;\n}\n\nexport interface ServicesOptions {\n configPath: string;\n runner?: CommandRunner;\n unitFile?: string;\n manager?: ServiceManager;\n}\n\n/** The single facade the CLI, the UI, the API and the daemon use to reach the engine. */\nexport class Services {\n readonly configPath: string;\n readonly service: ServiceManager;\n\n constructor(options: ServicesOptions) {\n this.configPath = options.configPath;\n this.service =\n options.manager ??\n new ServiceManager({\n configPath: options.configPath,\n runner: options.runner,\n unitFile: options.unitFile,\n });\n }\n\n load(): Promise<LoadedConfig> {\n return loadConfig(this.configPath);\n }\n\n /** Writes through the store (minimal, atomic, `.bak`, mtime-checked). */\n async save(config: Config, expectedMtimeMs: number | null): Promise<LoadedConfig> {\n const mtimeMs = await saveConfig(this.configPath, config, { expectedMtimeMs });\n return { path: this.configPath, config, mtimeMs };\n }\n\n async summary(config: Config, env: Environment): Promise<EnvironmentSummary> {\n const dir = envBackupDir(config, env);\n const backups = await listBackups(dir, env.name);\n return {\n name: env.name,\n dir,\n databases: env.databases.length,\n projects: env.projects.length,\n backups: backups.length,\n totalSize: backups.reduce((s, b) => s + b.size, 0),\n last: backups[0] ?? null,\n lastComplete: backups.find((b) => b.status === \"complete\") ?? null,\n schedule: env.schedule ?? null,\n nextRun: nextRun(env.schedule, timezone(config)),\n runningPid: await lockHolder(stateDir(config), env.name),\n };\n }\n\n summaries(config: Config): Promise<EnvironmentSummary[]> {\n return Promise.all(config.environments.map((env) => this.summary(config, env)));\n }\n\n nextRuns(config: Config, env: Environment, count = 3): Date[] {\n return env.schedule ? nextRuns(env.schedule, count, timezone(config)) : [];\n }\n\n async backups(\n config: Config,\n envName: string,\n filter: { status?: string; limit?: number } = {},\n ): Promise<BackupInfo[]> {\n const env = this.env(config, envName);\n let list = await listBackups(envBackupDir(config, env), env.name);\n if (filter.status) list = list.filter((b) => b.status === filter.status);\n return filter.limit ? list.slice(0, filter.limit) : list;\n }\n\n async recentBackups(config: Config, limit = 10): Promise<BackupInfo[]> {\n const all = await Promise.all(config.environments.map((e) => this.backups(config, e.name)));\n return all\n .flat()\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n .slice(0, limit);\n }\n\n backup(config: Config, envName: string, id: string): Promise<BackupInfo | null> {\n const env = this.env(config, envName);\n return readBackup(envBackupDir(config, env), env.name, id);\n }\n\n /** Start a backup job in its own session (survives the UI and SSH drops). */\n async startBackup(\n config: Config,\n targets: JobTarget[],\n trigger: JobTrigger = \"ui\",\n ): Promise<JobRecord> {\n for (const t of targets) this.env(config, t.environment);\n const { job } = await startJob(stateDir(config), this.configPath, targets, {\n trigger,\n detached: true,\n });\n return job;\n }\n\n jobs(config: Config, limit = 50): Promise<JobRecord[]> {\n return listJobs(stateDir(config), limit);\n }\n\n job(config: Config, id: string): Promise<JobRecord | null> {\n return readJob(stateDir(config), id);\n }\n\n jobEvents(\n config: Config,\n id: string,\n offset = 0,\n ): Promise<{ events: JobEvent[]; offset: number }> {\n return readEvents(eventsFile(stateDir(config), id), offset);\n }\n\n killJob(config: Config, id: string): Promise<boolean> {\n return killJob(stateDir(config), id);\n }\n\n async planPrune(config: Config, envNames?: string[]): Promise<PrunePlan[]> {\n const envs = envNames ? envNames.map((n) => this.env(config, n)) : config.environments;\n return Promise.all(envs.map((env) => planPrune(config, env)));\n }\n\n async applyPrune(plans: PrunePlan[]): Promise<{ deleted: number; errors: string[] }> {\n let deleted = 0;\n const errors: string[] = [];\n for (const plan of plans) {\n const r = await applyPrune(plan);\n deleted += r.deleted.length;\n errors.push(...r.errors);\n }\n return { deleted, errors };\n }\n\n async testConnection(env: Environment, db: Database): Promise<{ ok: boolean; message: string }> {\n try {\n const conn = await resolveConnection(db, env);\n await checkConnection(conn);\n return { ok: true, message: `connected to ${conn.schemas.join(\", \")}` };\n } catch (error) {\n return { ok: false, message: (error as Error).message };\n }\n }\n\n doctor(options: { db?: boolean } = {}): Promise<DoctorReport> {\n return runDoctor({ configPath: this.configPath, db: options.db, service: this.service });\n }\n\n private env(config: Config, name: string): Environment {\n const env = findEnvironment(config, name);\n if (!env) throw new Error(`unknown environment '${name}'`);\n return env;\n }\n}\n","import { constants } from \"node:fs\";\nimport { access, mkdir, readFile, rm, stat, statfs, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n CLIENT_BINARIES,\n checkConnection,\n DUMP_BINARIES,\n resolveConnection,\n} from \"./backup/mariadb.js\";\nimport { backupRoot, envBackupDir, stateDir, timezone } from \"./config/defaults.js\";\nimport { ConfigError, ConfigMissingError, type LoadedConfig, loadConfig } from \"./config/load.js\";\nimport type { Config } from \"./config/schema.js\";\nimport { formatBytes, formatDateTime } from \"./format.js\";\nimport { findExecutable } from \"./process.js\";\nimport { describeSchedule, nextRun } from \"./schedule.js\";\nimport type { ServiceManager } from \"./service/manager.js\";\n\nexport type CheckStatus = \"ok\" | \"warn\" | \"fail\";\n\nexport interface Check {\n group: string;\n name: string;\n status: CheckStatus;\n detail: string;\n}\n\nexport interface DoctorReport {\n configPath: string;\n checks: Check[];\n ok: boolean;\n /** true when no config file exists (the CLI exits 2). */\n missingConfig: boolean;\n}\n\nexport interface DoctorOptions {\n configPath: string;\n db?: boolean;\n service?: ServiceManager;\n minFreeBytes?: number;\n}\n\nasync function writable(dir: string): Promise<string | null> {\n try {\n await mkdir(dir, { recursive: true, mode: 0o700 });\n const probe = path.join(dir, `.bkm-doctor-${process.pid}`);\n await writeFile(probe, \"\");\n await rm(probe, { force: true });\n return null;\n } catch (error) {\n return (error as Error).message;\n }\n}\n\nasync function groupName(gid: number): Promise<string> {\n const text = await readFile(\"/etc/group\", \"utf8\").catch(() => \"\");\n for (const line of text.split(\"\\n\")) {\n const [name, , id] = line.split(\":\");\n if (name && Number(id) === gid) return name;\n }\n return String(gid);\n}\n\nasync function readable(target: string, dir: boolean): Promise<string | null> {\n try {\n await access(target, dir ? constants.R_OK | constants.X_OK : constants.R_OK);\n return null;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") return \"does not exist\";\n const info = await stat(target).catch(() => null);\n const hint = info\n ? ` (owned by group '${await groupName(info.gid)}'; add yourself with \\`sudo usermod -aG ${await groupName(info.gid)} $USER\\`)`\n : \"\";\n return `not readable${hint}`;\n }\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<DoctorReport> {\n const checks: Check[] = [];\n const add = (group: string, name: string, status: CheckStatus, detail: string) =>\n checks.push({ group, name, status, detail });\n let loaded: LoadedConfig | null = null;\n let missingConfig = false;\n try {\n loaded = await loadConfig(options.configPath);\n add(\"config\", \"config file\", \"ok\", `${options.configPath} is valid`);\n } catch (error) {\n missingConfig = error instanceof ConfigMissingError;\n if (error instanceof ConfigError && error.issues.length) {\n for (const issue of error.issues) add(\"config\", \"config file\", \"fail\", issue);\n } else {\n add(\"config\", \"config file\", \"fail\", (error as Error).message);\n }\n }\n\n const dump = await findExecutable(DUMP_BINARIES);\n add(\n \"tools\",\n \"dump client\",\n dump ? \"ok\" : \"fail\",\n dump ?? `none of ${DUMP_BINARIES.join(\", \")} on PATH (install mariadb-client)`,\n );\n const client = await findExecutable(CLIENT_BINARIES);\n add(\n \"tools\",\n \"sql client\",\n client ? \"ok\" : \"warn\",\n client ?? `none of ${CLIENT_BINARIES.join(\", \")} on PATH (needed for connection tests)`,\n );\n\n if (loaded) await checkConfig(loaded.config, options, add);\n\n if (options.service) {\n const s = await options.service.status();\n if (!s.available) {\n add(\"service\", \"systemd\", \"warn\", `systemctl --user unavailable: ${s.error ?? \"unknown\"}`);\n } else if (!s.installed) {\n add(\n \"service\",\n \"unit\",\n \"warn\",\n \"not installed; open `bkm` → Service → Install / update to run schedules\",\n );\n } else {\n add(\n \"service\",\n \"unit\",\n s.outdated ? \"warn\" : \"ok\",\n s.outdated\n ? `${s.unitPath} is outdated; open \\`bkm\\` → Service → Install / update`\n : s.unitPath,\n );\n add(\n \"service\",\n \"active\",\n s.activeState === \"active\" ? \"ok\" : \"warn\",\n `${s.activeState} (${s.subState})${s.mainPid ? `, pid ${s.mainPid}` : \"\"}`,\n );\n add(\"service\", \"enabled\", s.enabled === \"enabled\" ? \"ok\" : \"warn\", s.enabled);\n add(\n \"service\",\n \"linger\",\n s.linger ? \"ok\" : \"warn\",\n s.linger === null\n ? \"unknown\"\n : s.linger\n ? \"enabled (runs at boot and after logout)\"\n : \"disabled: the service stops when you log out (`loginctl enable-linger`)\",\n );\n }\n }\n\n return {\n configPath: options.configPath,\n checks,\n ok: !checks.some((c) => c.status === \"fail\"),\n missingConfig,\n };\n}\n\nasync function checkConfig(\n config: Config,\n options: DoctorOptions,\n add: (group: string, name: string, status: CheckStatus, detail: string) => void,\n) {\n const tz = timezone(config);\n if (config.environments.length === 0)\n add(\"config\", \"environments\", \"warn\", \"no environments yet; add one in `bkm`\");\n for (const env of config.environments) {\n if (env.schedule) {\n const next = nextRun(env.schedule, tz);\n add(\n \"schedule\",\n env.name,\n \"ok\",\n `${describeSchedule(env.schedule)} (${tz}); next ${next ? formatDateTime(next) : \"—\"}`,\n );\n } else {\n add(\"schedule\", env.name, \"ok\", \"manual only\");\n }\n }\n\n const dirs: [string, string][] = [\n [\"backup dir\", backupRoot(config)],\n [\"state dir\", stateDir(config)],\n ...config.environments\n .filter((e) => e.backupDir)\n .map((e): [string, string] => [`${e.name} backup dir`, envBackupDir(config, e)]),\n ];\n for (const [name, dir] of dirs) {\n const error = await writable(dir);\n add(\"storage\", name, error ? \"fail\" : \"ok\", error ? `${dir}: ${error}` : dir);\n }\n try {\n const fs = await statfs(backupRoot(config));\n const free = fs.bavail * fs.bsize;\n const ratio = fs.blocks ? fs.bavail / fs.blocks : 1;\n const low = free < (options.minFreeBytes ?? 1024 ** 3) || ratio < 0.05;\n add(\n \"storage\",\n \"free space\",\n low ? \"warn\" : \"ok\",\n `${formatBytes(free)} free (${Math.round(ratio * 100)}%)`,\n );\n } catch (error) {\n add(\"storage\", \"free space\", \"warn\", (error as Error).message);\n }\n\n for (const env of config.environments) {\n for (const project of env.projects) {\n const label = `${env.name}/${project.name}`;\n const problem = await readable(project.path, true);\n if (problem) {\n add(\"projects\", label, \"fail\", `${project.path} ${problem}`);\n continue;\n }\n const missing: string[] = [];\n for (const include of project.include) {\n const p = await readable(path.join(project.path, include), true);\n if (p) missing.push(`${include} ${p}`);\n }\n const usesEnv = env.databases.some(\n (d) => d.source.type === \"laravel\" && d.source.project === project.name,\n );\n if (usesEnv) {\n const p = await readable(path.join(project.path, \".env\"), false);\n if (p) missing.push(`.env ${p}`);\n }\n const allMissing = missing.length >= project.include.length + (usesEnv ? 1 : 0);\n add(\n \"projects\",\n label,\n missing.length ? (allMissing ? \"fail\" : \"warn\") : \"ok\",\n missing.length ? missing.join(\"; \") : project.path,\n );\n }\n if (options.db === false) continue;\n for (const db of env.databases) {\n const label = `${env.name}/${db.name}`;\n try {\n const conn = await resolveConnection(db, env);\n await checkConnection(conn);\n add(\"databases\", label, \"ok\", `connected (${conn.schemas.join(\", \")})`);\n } catch (error) {\n add(\"databases\", label, \"fail\", (error as Error).message.split(\"\\n\")[0] ?? \"error\");\n }\n }\n }\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { userInfo } from \"node:os\";\nimport path from \"node:path\";\nimport { getJobCommand } from \"../jobs/runner.js\";\nimport { type CommandRunner, execRunner, parseProperties, Systemd } from \"./systemctl.js\";\nimport { renderUnit, UNIT_FILE, UNIT_NAME, unitPath } from \"./unit.js\";\n\nexport interface ServiceStatus {\n /** systemctl --user is usable (a user manager is running). */\n available: boolean;\n installed: boolean;\n unitPath: string;\n /** The installed unit differs from what Install / update would write now. */\n outdated: boolean;\n activeState: string;\n subState: string;\n mainPid: number | null;\n /** UnitFileState: enabled, disabled, … */\n enabled: string;\n /** null when unknown */\n linger: boolean | null;\n error?: string;\n}\n\nexport interface InstallResult {\n unit: string;\n unitPath: string;\n actions: string[];\n warnings: string[];\n changed: boolean;\n}\n\nexport class ServiceError extends Error {\n override name = \"ServiceError\";\n}\n\nexport interface ManagerOptions {\n configPath: string;\n runner?: CommandRunner;\n unitFile?: string;\n user?: string;\n /** argv used to start the daemon; defaults to the current `bkm` invocation. */\n command?: string[];\n}\n\nexport class ServiceManager {\n readonly systemd: Systemd;\n readonly unitFile: string;\n private readonly user: string;\n\n constructor(private readonly options: ManagerOptions) {\n this.systemd = new Systemd(options.runner ?? execRunner);\n this.unitFile = options.unitFile ?? unitPath();\n this.user = options.user ?? userInfo().username;\n }\n\n expectedUnit(): string {\n const cmd =\n this.options.command ??\n (() => {\n const { command, args } = getJobCommand();\n return [command, ...args];\n })();\n return renderUnit({ command: cmd, configPath: this.options.configPath });\n }\n\n private async installedUnit(): Promise<string | null> {\n return readFile(this.unitFile, \"utf8\").catch(() => null);\n }\n\n async linger(): Promise<boolean | null> {\n const r = await this.systemd.loginctl(\"show-user\", this.user, \"-p\", \"Linger\");\n if (r.code !== 0) return null;\n return parseProperties(r.stdout).Linger === \"yes\";\n }\n\n async status(): Promise<ServiceStatus> {\n const installed = await this.installedUnit();\n const base: ServiceStatus = {\n available: false,\n installed: installed !== null,\n unitPath: this.unitFile,\n outdated: installed !== null && installed !== this.expectedUnit(),\n activeState: \"unknown\",\n subState: \"unknown\",\n mainPid: null,\n enabled: \"unknown\",\n linger: null,\n };\n const show = await this.systemd.systemctl(\n \"show\",\n UNIT_NAME,\n \"-p\",\n \"ActiveState,SubState,MainPID,UnitFileState,LoadState\",\n );\n if (show.code !== 0) {\n return {\n ...base,\n error: (show.stderr || show.stdout).trim() || `systemctl exited with ${show.code}`,\n };\n }\n const p = parseProperties(show.stdout);\n const pid = Number.parseInt(p.MainPID ?? \"0\", 10);\n return {\n ...base,\n available: true,\n activeState: p.ActiveState || \"unknown\",\n subState: p.SubState || \"unknown\",\n mainPid: pid > 0 ? pid : null,\n enabled: p.UnitFileState || (p.LoadState === \"not-found\" ? \"not-found\" : \"unknown\"),\n linger: await this.linger(),\n };\n }\n\n private async must(args: string[], what: string) {\n const r = await this.systemd.systemctl(...args);\n if (r.code !== 0)\n throw new ServiceError(\n `${what} failed: ${(r.stderr || r.stdout).trim() || `exit ${r.code}`}`,\n );\n }\n\n async install({ force = false } = {}): Promise<InstallResult> {\n const unit = this.expectedUnit();\n const current = await this.installedUnit();\n const result: InstallResult = {\n unit,\n unitPath: this.unitFile,\n actions: [],\n warnings: [],\n changed: false,\n };\n const writeUnit = current === null || (current !== unit && force);\n if (current !== null && current !== unit && !force) {\n throw new ServiceError(\n `${this.unitFile} differs from the expected unit; it was changed outside bkm`,\n );\n }\n const status = await this.status();\n if (!status.available) {\n throw new ServiceError(\n `systemd user manager is not available: ${status.error ?? \"unknown error\"}`,\n );\n }\n if (writeUnit) result.actions.push(`write ${this.unitFile}`, \"systemctl --user daemon-reload\");\n const needsStart = writeUnit || status.enabled !== \"enabled\" || status.activeState !== \"active\";\n if (needsStart) result.actions.push(`systemctl --user enable --now ${UNIT_NAME}`);\n if (writeUnit && current !== null) result.actions.push(`systemctl --user restart ${UNIT_NAME}`);\n const linger = await this.linger();\n if (linger !== true) result.actions.push(`loginctl enable-linger ${this.user}`);\n\n if (writeUnit) {\n await mkdir(path.dirname(this.unitFile), { recursive: true });\n await writeFile(this.unitFile, unit, { mode: 0o644 });\n result.changed = true;\n await this.must([\"daemon-reload\"], \"daemon-reload\");\n }\n if (needsStart) await this.must([\"enable\", \"--now\", UNIT_NAME], \"enable --now\");\n if (writeUnit && current !== null) await this.must([\"restart\", UNIT_NAME], \"restart\");\n if (linger !== true) {\n const r = await this.systemd.loginctl(\"enable-linger\", this.user);\n if (r.code !== 0) {\n result.warnings.push(\n `could not enable lingering (${(r.stderr || r.stdout).trim() || `exit ${r.code}`}); the service runs only while you are logged in`,\n );\n }\n }\n return result;\n }\n\n async uninstall(): Promise<string[]> {\n const actions: string[] = [];\n if ((await this.installedUnit()) === null) return actions;\n await this.systemd.systemctl(\"disable\", \"--now\", UNIT_NAME);\n actions.push(`systemctl --user disable --now ${UNIT_NAME}`);\n await rm(this.unitFile, { force: true });\n actions.push(`remove ${this.unitFile}`);\n await this.systemd.systemctl(\"daemon-reload\");\n actions.push(\"systemctl --user daemon-reload\");\n return actions;\n }\n\n async control(action: \"start\" | \"stop\" | \"restart\" | \"reload\"): Promise<void> {\n await this.must([action, UNIT_NAME], action);\n }\n\n async logs(lines = 200): Promise<string[]> {\n const r = await this.systemd.journal(UNIT_NAME, lines);\n if (r.code !== 0) return [`(journalctl failed: ${(r.stderr || r.stdout).trim()})`];\n return r.stdout.split(\"\\n\").filter((l) => l.trim() && !l.startsWith(\"-- \"));\n }\n}\n\nexport { UNIT_FILE, UNIT_NAME };\n","import { execFile } from \"node:child_process\";\n\nexport interface CommandResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\n/** Runs a program without a shell. Injected so tests never touch the real systemd. */\nexport type CommandRunner = (command: string, args: string[]) => Promise<CommandResult>;\n\nexport const execRunner: CommandRunner = (command, args) =>\n new Promise((resolve) => {\n execFile(\n command,\n args,\n { timeout: 30_000, maxBuffer: 4 * 1024 * 1024 },\n (error, stdout, stderr) => {\n const err = error as (NodeJS.ErrnoException & { code?: number | string }) | null;\n if (err && err.code === \"ENOENT\") {\n resolve({ code: 127, stdout: \"\", stderr: `${command}: command not found` });\n return;\n }\n resolve({\n code: err ? (typeof err.code === \"number\" ? err.code : 1) : 0,\n stdout: String(stdout),\n stderr: String(stderr),\n });\n },\n );\n });\n\n/** Every systemctl call is user-level; `sudo` is never used. */\nexport class Systemd {\n constructor(private readonly run: CommandRunner = execRunner) {}\n\n systemctl(...args: string[]): Promise<CommandResult> {\n return this.run(\"systemctl\", [\"--user\", ...args]);\n }\n\n journal(unit: string, lines: number): Promise<CommandResult> {\n return this.run(\"journalctl\", [\n \"--user\",\n \"-u\",\n unit,\n \"-n\",\n String(lines),\n \"--no-pager\",\n \"-o\",\n \"short-iso\",\n ]);\n }\n\n loginctl(...args: string[]): Promise<CommandResult> {\n return this.run(\"loginctl\", args);\n }\n}\n\nexport function parseProperties(text: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const line of text.split(\"\\n\")) {\n const i = line.indexOf(\"=\");\n if (i > 0) out[line.slice(0, i).trim()] = line.slice(i + 1).trim();\n }\n return out;\n}\n","import path from \"node:path\";\nimport { xdgConfigHome } from \"../paths.js\";\n\nexport const UNIT_NAME = \"bkm\";\nexport const UNIT_FILE = `${UNIT_NAME}.service`;\n\nexport function unitPath(env = process.env): string {\n return path.join(xdgConfigHome(env), \"systemd\", \"user\", UNIT_FILE);\n}\n\n/** Quote one ExecStart word for systemd (also escapes `%` specifiers and `$`). */\nexport function quoteArg(arg: string): string {\n const escaped = arg.replace(/%/g, \"%%\").replace(/\\$/g, \"$$$$\");\n if (/^[A-Za-z0-9_@%+=:,./-]+$/.test(escaped)) return escaped;\n return `\"${escaped.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nexport interface UnitOptions {\n /** argv of the daemon: node, its flags, the CLI script. */\n command: string[];\n configPath: string;\n}\n\nexport function renderUnit({ command, configPath }: UnitOptions): string {\n const exec = [...command, \"daemon\", \"--config\", configPath].map(quoteArg).join(\" \");\n return [\n \"# Managed by backup-manager (bkm → Service). Choose Install / update after moving node or bkm.\",\n \"[Unit]\",\n \"Description=backup-manager scheduler and API\",\n \"Documentation=https://github.com/MateusBMP/backup-manager\",\n \"\",\n \"[Service]\",\n \"Type=simple\",\n `ExecStart=${exec}`,\n \"ExecReload=/bin/kill -HUP $MAINPID\",\n \"Restart=on-failure\",\n \"RestartSec=10\",\n \"TimeoutStopSec=6min\",\n \"NoNewPrivileges=yes\",\n \"Environment=NODE_ENV=production\",\n \"\",\n \"[Install]\",\n \"WantedBy=default.target\",\n \"\",\n ].join(\"\\n\");\n}\n","import { Box, renderToString, Text } from \"ink\";\nimport Gradient from \"ink-gradient\";\nimport type { ReactElement } from \"react\";\nimport type { CheckStatus, DoctorReport } from \"../../core/doctor.js\";\nimport { ICONS, makeTheme, type Theme } from \"../theme.js\";\n\nexport interface PrintOptions {\n /** Plain text: no ANSI (no TTY or NO_COLOR). */\n plain: boolean;\n columns?: number;\n}\n\nexport function printOptions(stream: NodeJS.WriteStream = process.stdout): PrintOptions {\n const plain = !stream.isTTY || (\"NO_COLOR\" in process.env && process.env.NO_COLOR !== \"0\");\n return { plain, columns: stream.columns || 100 };\n}\n\nfunction render(element: ReactElement, options: PrintOptions): string {\n return renderToString(element, { columns: options.columns ?? 100 });\n}\n\nconst ICON: Record<CheckStatus, string> = { ok: ICONS.ok, warn: ICONS.warn, fail: ICONS.fail };\n\nfunction groupChecks(report: DoctorReport) {\n const groups = new Map<string, DoctorReport[\"checks\"]>();\n for (const check of report.checks) {\n const list = groups.get(check.group) ?? [];\n list.push(check);\n groups.set(check.group, list);\n }\n return groups;\n}\n\nfunction summary(report: DoctorReport): { text: string; status: CheckStatus } {\n const fails = report.checks.filter((c) => c.status === \"fail\").length;\n const warns = report.checks.filter((c) => c.status === \"warn\").length;\n if (fails) return { text: `${fails} problem(s), ${warns} warning(s)`, status: \"fail\" };\n if (warns) return { text: `all good, ${warns} warning(s)`, status: \"warn\" };\n return { text: \"all good\", status: \"ok\" };\n}\n\nfunction Title({ t, children }: { t: Theme; children: string }) {\n return t.color ? (\n <Gradient colors={t.gradient}>\n <Text bold>{children}</Text>\n </Gradient>\n ) : (\n <Text bold>{children}</Text>\n );\n}\n\nfunction DoctorView({ report, t }: { report: DoctorReport; t: Theme }) {\n const color = { ok: t.success, warn: t.warning, fail: t.error };\n const width = Math.max(...report.checks.map((c) => c.name.length), 8);\n const s = summary(report);\n return (\n <Box flexDirection=\"column\">\n <Title t={t}>backup-manager doctor</Title>\n <Text color={t.muted}>{report.configPath}</Text>\n {[...groupChecks(report)].map(([group, checks]) => (\n <Box key={group} flexDirection=\"column\" marginTop={1}>\n <Text bold color={t.accent}>\n {group}\n </Text>\n {checks.map((c) => (\n <Box key={`${c.name}\\u0000${c.detail}`}>\n <Box width={4} flexShrink={0}>\n <Text color={color[c.status]}>{` ${ICON[c.status]}`}</Text>\n </Box>\n <Box width={width + 2} flexShrink={0}>\n <Text>{c.name}</Text>\n </Box>\n <Text color={c.status === \"ok\" ? t.muted : undefined}>{c.detail}</Text>\n </Box>\n ))}\n </Box>\n ))}\n <Box marginTop={1}>\n <Text bold color={color[s.status]}>\n {`${ICON[s.status]} ${s.text}`}\n </Text>\n </Box>\n </Box>\n );\n}\n\nexport function doctorText(report: DoctorReport, options: PrintOptions): string {\n if (!options.plain) return render(<DoctorView report={report} t={makeTheme(true)} />, options);\n const lines = [\"backup-manager doctor\", report.configPath];\n const width = Math.max(...report.checks.map((c) => c.name.length), 8);\n for (const [group, checks] of groupChecks(report)) {\n lines.push(\"\", group);\n for (const c of checks) lines.push(` ${ICON[c.status]} ${c.name.padEnd(width)} ${c.detail}`);\n }\n const s = summary(report);\n lines.push(\"\", `${ICON[s.status]} ${s.text}`);\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["name","timezone","path","path","name","retention","path","path","name","mkdir","readdir","readFile","rename","rm","writeFile","path","stateDir","mkdir","rename","rm","stat","writeFile","path","init_store","c","name","jsx","Box","Text","Gradient","jsx","jsxs","theme","Box","Text","useAnimation","jsx","jsxs","theme","Box","Text","jsx","jsxs","theme","useCallback","useEffect","useRef","useState","useEffect","useState","Box","Text","useRef","jsx","jsxs","theme","render","Box","Text","useInput","useState","jsx","jsxs","theme","BackupDetail","watch","path","useEffect","useRef","useState","name","Box","Text","useInput","jsx","jsxs","hhmm","theme","name","Box","Text","useInput","useState","jsx","jsxs","theme","c","Text","useInput","useRef","useState","jsx","jsxs","theme","cursor","at","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","theme","path","Box","Text","useState","jsx","jsxs","theme","values","constants","access","path","Box","Text","useEffect","useState","jsx","jsxs","theme","values","Box","Text","useState","jsx","jsxs","theme","values","Text","useInput","jsx","jsxs","theme","Box","Text","useInput","useState","jsx","jsxs","theme","Box","Text","useInput","useState","jsx","jsxs","theme","Box","Text","useState","jsx","jsxs","theme","values","Box","Text","useInput","useState","jsx","jsxs","theme","Box","Text","useInput","useState","jsx","jsxs","theme","Box","Text","useState","jsx","jsxs","c","jsx","BackupDetail","Box","Text","useInput","useCallback","useEffect","useMemo","useRef","useState","jsx","jsxs","theme","c","init_store","render","jsx","readFile","path","z","require","z","c","name","summary","path","spawn","mkdirSync","readFile","path","stateDir","mkdir","rm","stat","path","mkdir","rm","path","stat","stat","path","readFile","writeFile","path","path","stat","mkdir","readFile","rm","writeFile","path","readFile","quote","c","readFile","path","writeFile","rm","mkdir","code","rm","rm","stat","path","mkdir","level","name","rm","path","stateDir","mkdirSync","spawn","error","mkdir","readFile","rename","writeFile","path","stateDir","timezone","Cron","timezone","name","code","readFile","path","name","init_store","constants","access","mkdir","readFile","rm","stat","writeFile","path","mkdir","path","writeFile","rm","readFile","name","access","constants","code","stat","c","mkdir","readFile","rm","writeFile","path","path","readFile","mkdir","path","writeFile","rm","name","c","code","configPath","path"]}