/**
 * App-framework drivers.
 *
 * ts-cloud runs a site's background work — the scheduler, queue workers, and
 * daemons — as systemd units / cron on the box. HOW those are invoked differs
 * per app framework: Stacks (Bun, `buddy …`) vs Laravel (PHP, `artisan …`), and
 * the runtime environment a systemd/cron process needs differs too (bun on PATH
 * vs pantry's php env). This module isolates those differences behind one small
 * driver so the reconciler (`app-services.ts`) stays framework-agnostic.
 *
 * Stacks-first: `getAppFrameworkDriver()` defaults to the Stacks driver.
 */
import type { QueueWorkerConfig, SiteConfig } from '@ts-cloud/core';
export type FrameworkId = 'stacks' | 'laravel';
/**
 * Resolve which framework driver a site uses. An explicit `framework` wins; a
 * PHP-oriented `type` (laravel/php/statamic/wordpress) implies Laravel for
 * backward compatibility; everything else uses the Stacks-first default.
 */
export declare function resolveSiteFramework(site: Pick<SiteConfig, 'framework' | 'type'>): FrameworkId;
export interface FrameworkExecContext {
    /** The active-release directory (`/var/www/<site>/current`). */
    current: string;
}
export interface AppFrameworkDriver {
    readonly id: FrameworkId;
    /**
     * Wrap a command for a systemd unit / cron entry. Prefer a BARE command +
     * {@link AppFrameworkDriver.execEnv} (like the app's own service) so starting
     * a long-lived unit over SSH doesn't hold the deploy channel open; only wrap
     * in a shell when the env must be computed at runtime (e.g. Laravel/pantry).
     */
    wrapExec: (command: string) => string;
    /** Static `Environment=` vars for a unit (systemd inherits no shell env). */
    readonly execEnv?: Record<string, string>;
    /**
     * How the app scheduler runs:
     *  - `'cron'`   → `schedule:run` is one-shot; run it every minute via cron (Laravel).
     *  - `'daemon'` → `schedule:run` is long-lived (holds in-process timers); run it
     *                 as a single always-on systemd unit (Stacks).
     */
    readonly schedulerMode: 'cron' | 'daemon';
    /**
     * The scheduler command WITHOUT output redirection. For `'cron'` it is run
     * from cron and sets up its own cwd/env; for `'daemon'` it becomes a unit's
     * ExecStart (systemd supplies WorkingDirectory), so no `cd` is needed.
     */
    schedulerCommand: (ctx: FrameworkExecContext) => string;
    /** `ExecStart` for a single queue-worker process. */
    queueWorkerCommand: (worker: QueueWorkerConfig, ctx: FrameworkExecContext) => string;
}
/**
 * Stacks (Bun) — the default. bun lives at an absolute path installed by the box
 * bootstrap, so units use a BARE ExecStart (no shell wrapper) + `Environment=`
 * for PATH/BUN_INSTALL — matching the app's own service. This matters: wrapping
 * a long-lived unit in `/bin/sh -lc` makes `systemctl restart` over SSH hold the
 * deploy channel open and hang the deploy.
 */
export declare const stacksDriver: AppFrameworkDriver;
/** Laravel (PHP / Artisan) — the original Forge-style behavior, now a driver. */
export declare const laravelDriver: AppFrameworkDriver;
/** Resolve the app-framework driver for a site. Stacks-first default. */
export declare function getAppFrameworkDriver(framework?: FrameworkId): AppFrameworkDriver;
