import type { MeshCoordinatorMcpConfigFormat, MeshCoordinatorSystemPromptInjection, ProviderModule } from '../providers/contracts.js';
export interface MeshCoordinatorMcpServerLaunch {
    command: string;
    args: string[];
}
export type MeshCoordinatorSetup = {
    kind: 'auto_import';
    serverName: string;
    configPath: string;
    configFormat?: MeshCoordinatorMcpConfigFormat;
    mcpServer: MeshCoordinatorMcpServerLaunch;
} | {
    kind: 'manual';
    serverName: string;
    configFormat?: MeshCoordinatorMcpConfigFormat;
    configPathCommand?: string;
    requiresRestart: boolean;
    instructions: string;
    template: string;
} | {
    /** Provider registers MCP via its own CLI command (e.g. `codex mcp add` / `gemini mcp add`). */
    kind: 'cli_command';
    serverName: string;
    /** The rendered shell command to execute before launching the coordinator session. */
    command: string;
    requiresRestart: boolean;
    instructions: string;
    mcpServer: MeshCoordinatorMcpServerLaunch;
} | {
    kind: 'unsupported';
    reason: string;
};
export interface ResolveMeshCoordinatorSetupOptions {
    provider?: ProviderModule | null;
    cliType?: string;
    meshId: string;
    workspace: string;
    adhdevMcpCommand?: string;
    adhdevMcpEntryPath?: string;
    nodeExecutable?: string;
    adhdevMcpTransport?: 'local' | 'ipc';
    adhdevMcpPort?: number;
}
export declare function createHermesManualMeshCoordinatorSetup(meshId: string, workspace: string): MeshCoordinatorSetup;
export declare function resolveMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetupOptions): MeshCoordinatorSetup;
/**
 * Apply a provider's declared system-prompt injection rule, mutating `cliArgs`
 * and `launchEnv` in place and writing any required workspace context file.
 *
 * Replaces the previous hard-coded `if (cliType === 'claude-cli') ... else if
 * (cliType === 'hermes-cli') ...` branches in router.ts. Adding a new CLI is
 * now provider.v1.json data, not a router edit.
 *
 * Failures are non-fatal: log and continue with whatever was applied so the
 * coordinator session still launches, just without the prompt for that
 * provider. A missing/unknown rule means "skip injection" — safe by default
 * (the previous fallback unconditionally pushed --append-system-prompt onto
 * every non-Claude CLI, which crashed agy on launch).
 */
export interface CoordinatorInjectionEffect {
    /** Absolute path the daemon wrote a wrapper-blocked file to. Only set for
     *  context_file injection. R48 schedules a strip after launch so workers
     *  don't see the wrapper on disk; R47's unregister cleanup uses it as a
     *  fallback if the timer never fires (process crash, etc). */
    contextFilePath?: string;
}
export declare function applyMeshCoordinatorSystemPromptInjection(systemPrompt: string, injection: MeshCoordinatorSystemPromptInjection | undefined, ctx: {
    cliArgs: string[];
    launchEnv: Record<string, string>;
    workspace: string;
    cliType: string;
}): CoordinatorInjectionEffect;
/**
 * Strip the daemon's wrapper block from a context_file we previously wrote.
 *
 * Used in two places:
 *   1. R48 inject-then-remove: ~5s after spawn, after agy/gemini have read
 *      the file into their in-memory system-prompt cache. Removing it from
 *      disk at that point doesn't affect the running coordinator but keeps
 *      worker sessions (or fresh non-coordinator launches) in the same
 *      workspace from picking up our wrapper.
 *   2. R47 unregister fallback: if the timer never fires (process crash,
 *      kill -9), coordinator-registry.unregisterMeshCoordinator runs the
 *      same logic when its entry is dropped.
 *
 * Idempotent: missing file is fine, missing sentinels are fine, returns
 * silently. Leaves user-authored content outside the sentinels intact.
 * Deletes the file outright if our wrapper was the only content.
 */
export declare function stripCoordinatorWrapperFile(filePath: string): void;
export interface PtyExecResult {
    exitCode: number | null;
    signal: number | null;
    output: string;
    timedOut: boolean;
}
export interface MeshCoordinatorRegistrationStep {
    command: string;
    args: string[];
    required: boolean;
    label: 'remove_existing' | 'register';
}
/**
 * Codex rejects `mcp add` when a server with the same name already exists.
 * Replace that entry before registering so transport/mesh changes do not leave
 * a fresh coordinator attached to stale MCP launch arguments.
 */
export declare function buildMeshCoordinatorRegistrationPlan(cliType: string, serverName: string, registrationCommand: string): MeshCoordinatorRegistrationStep[];
/**
 * Run a one-shot CLI command under a real PTY and collect its output.
 *
 * Some provider mcp-registration commands (`agy mcp add`, future bubbletea
 * TUIs) refuse to run without `/dev/tty`. Daemon-side `execFileSync` runs
 * pipe-only, so those commands fail with errors like
 *   `bubbletea: error opening TTY: open /dev/tty: device not configured`
 * and silently skip the registration, leaving the launched session
 * without the adhdev-mesh MCP tools — which is exactly what we saw with
 * agy coordinators.
 *
 * Wrapping the registration through node-pty gives the child a real PTY,
 * so the bubbletea check passes. We close stdin immediately and just
 * collect stdout until the process exits or the timeout fires.
 */
export declare function execUnderPty(command: string, args: string[], options?: {
    cwd?: string;
    env?: Record<string, string>;
    timeoutMs?: number;
}): Promise<PtyExecResult>;
