/**
 * Crewly Agent External Runtime Service
 *
 * Runs the Crewly Agent as a dedicated executable process and communicates
 * with it over a newline-delimited JSON protocol on stdin/stdout.
 *
 * This keeps OSS integration points intact while moving the agent runtime
 * behind an external process boundary so it can be versioned separately.
 *
 * @module services/agent/crewly-agent/crewly-agent-external-runtime.service
 */
import { RuntimeAgentService } from '../runtime-agent.service.abstract.js';
import type { AgentRunResult, CrewlyAgentConfig } from './types.js';
import { SessionCommandHelper } from '../../session/index.js';
import { type RuntimeType } from '../../../constants.js';
export declare class CrewlyAgentExternalRuntimeService extends RuntimeAgentService {
    private initialized;
    private ready;
    private currentSessionName;
    private currentMemberId;
    private currentRoleName;
    private currentModelString;
    private child;
    private logBuffer;
    private heartbeatTimer;
    private stdoutBuffer;
    private pendingRunResolve;
    private pendingRunReject;
    private pendingInitResolve;
    private pendingInitReject;
    private storedConfig;
    /**
     * Bound signal forwarder so we can register it on parent SIGINT/
     * SIGTERM/SIGHUP and detach the same identity on shutdown. Null
     * when no child is currently attached.
     */
    private signalForwarder;
    constructor(sessionHelper: SessionCommandHelper, projectRoot: string);
    protected getRuntimeType(): RuntimeType;
    protected detectRuntimeSpecific(_sessionName: string): Promise<boolean>;
    protected getRuntimeReadyPatterns(): string[];
    protected getRuntimeErrorPatterns(): string[];
    protected getRuntimeExitPatterns(): RegExp[];
    initializeInProcess(sessionName: string, config?: Partial<CrewlyAgentConfig> & {
        memberId?: string;
    }, roleName?: string): Promise<void>;
    handleMessage(message: string, metadata?: Record<string, string>): Promise<AgentRunResult>;
    isReady(): boolean;
    shutdown(): void;
    private spawnAgentProcess;
    /**
     * Resolve the runtime command. Returns the bare binary name (no shell)
     * by default, or, if the user has configured a custom shell command in
     * settings, returns it with `useShell=true` after validating it against
     * a strict allow-list.
     *
     * Allow-list rationale: a shell-ready command is anything matching the
     * shape `<word>[ <flag-or-arg>]*` — no shell metacharacters like
     * `;` `|` `&` `$` backticks. Anything richer is suspicious and is
     * silently dropped (we fall back to the default binary). Settings are
     * user-controlled in principle but flow through HTTP APIs, so we
     * treat the value as semi-trusted input.
     */
    private resolveRuntimeCommand;
    /**
     * Allow-list for custom runtime commands. Matches an executable path or
     * name followed by space-separated flags/args, where each token is a
     * combination of letters, digits, and the path-safe punctuation
     * (`. _ / - = :`). Rejects anything containing shell control characters
     * (`; | & $ \` < > ( ) { } [ ]`), newlines, or quotes.
     */
    private static readonly SAFE_SHELL_COMMAND_RE;
    /**
     * Find an executable on the engine's PATH. Returns the absolute path
     * when found, or null when not. Async so we never block the event
     * loop on slow disks. Exported behavior is "is `name` runnable?";
     * we don't care which exact entry won the search.
     */
    private lookupOnPath;
    /**
     * Forward parent SIGINT/SIGTERM/SIGHUP to the spawned child so it gets
     * a chance to flush + exit instead of being orphaned. Idempotent —
     * calling more than once just replaces the previous listeners.
     *
     * Removes its own listeners on `handleExit` so old callbacks don't
     * fire against a recycled `this.child` reference after a restart.
     */
    private attachSignalForwarders;
    private detachSignalForwarders;
    private sendMessage;
    private handleStdout;
    private handleWorkerMessage;
    private handleStderr;
    private handleExit;
    private handleProcessError;
    private recordTokenUsageIfEnabled;
    private startHeartbeat;
    private stopHeartbeat;
    private loadSystemPrompt;
    buildEnhancedSystemPrompt(roleName?: string): Promise<string>;
    private loadSkillsCatalogSummary;
    private loadInstalledAddons;
}
//# sourceMappingURL=crewly-agent-external-runtime.service.d.ts.map