/**
 * Session creation pipeline — plan/execute architecture.
 *
 * Extracts duplicated session-creation logic from SessionManager into composable
 * pipeline steps.  Three creation paths (normal, worktree, delegate) share the
 * same step functions but differ in *when* the steps execute:
 *
 *   normal   — await full pipeline, return ready session
 *   worktree — return immediately with "preparing", pipeline runs async
 *   delegate — await pipeline + first prompt + streaming confirmation
 */
import type { WebSocket } from "ws";
import type { ServerMessage } from "../ws/protocol.js";
import type { SessionInfo } from "./session-manager.js";
import type { RpcBridgeOptions } from "./rpc-bridge.js";
import type { SessionStore } from "./session-store.js";
import type { GoalManager } from "./goal-manager.js";
import type { TaskManager } from "./task-manager.js";
import type { SearchService } from "../search/search-service.js";
import type { CostTracker } from "./cost-tracker.js";
import type { RoleManager } from "./role-manager.js";
import type { ToolManager } from "./tool-manager.js";
import type { ToolGroupPolicyStore } from "./tool-group-policy-store.js";
import type { McpManager } from "../mcp/mcp-manager.js";
import type { SandboxManager } from "./sandbox-manager.js";
import type { PromptParts } from "./system-prompt.js";
import type { PrStatusStore } from "./pr-status-store.js";
import type { ConfigCascade } from "./config-cascade.js";
import { type EffectiveTool } from "./tool-activation.js";
/** Delegate spawn timeout (30 seconds). */
export declare const DELEGATE_SPAWN_TIMEOUT_MS = 30000;
export interface SandboxWiringOptions {
    projectId?: string;
    goalId?: string;
    sandboxBranch?: string;
    sandboxBaseBranch?: string;
    /** Repo/worktree-relative cwd offset to preserve after remapping into /workspace* paths. */
    sandboxCwdOffset?: string;
}
/** Normalize a host-derived cwd offset so it can be safely appended to a container path. */
export declare function normalizeSandboxCwdOffset(relativeOffset?: string | null): string | undefined;
/** Apply a safe repo/worktree-relative offset to a container base cwd. */
export declare function applySandboxCwdOffset(containerBaseCwd: string, relativeOffset?: string | null): string;
/** Compute a safe relative cwd offset, returning undefined when cwd is outside root. */
export declare function relativeSandboxCwdOffset(rootPath?: string, cwd?: string): string | undefined;
export type SessionSetupMode = "normal" | "worktree" | "delegate";
export interface SessionSetupPlan {
    id: string;
    mode: SessionSetupMode;
    title: string;
    cwd: string;
    goalId?: string;
    assistantType?: string;
    delegateOf?: string;
    parentSessionId?: string;
    childKind?: string;
    readOnly?: boolean;
    walkthroughJobId?: string;
    walkthroughChangesetId?: string;
    walkthroughTargetKey?: string;
    /** Explicit session-scoped tool allowlist that must survive process restarts. */
    sessionScopedAllowedTools?: string[];
    taskId?: string;
    worktreePath?: string;
    repoPath?: string;
    branch?: string;
    sandboxed?: boolean;
    role?: string;
    staffId?: string;
    accessory?: string;
    nonInteractive?: boolean;
    bridgeOptions: RpcBridgeOptions;
    effectiveAllowedTools?: EffectiveTool[];
    promptPath?: string;
    agentArgs?: string[];
    env?: Record<string, string>;
    rolePrompt?: string;
    roleName?: string;
    workflowContext?: string;
    reattemptGoalId?: string;
    projectId?: string;
    skipAutoModel?: boolean;
    skipAutoThinking?: boolean;
    initialModel?: string;
    initialThinkingLevel?: string;
    sandboxBranch?: string;
    sandboxBaseBranch?: string;
    sandboxCwdOffset?: string;
    instructions?: string;
    context?: Record<string, string>;
    /**
     * Continue-Archived: a `.jsonl` path that has already been cloned from the
     * source archived session. When set, `spawnAgent` issues a `switch_session`
     * RPC against this path immediately after `rpcClient.start()` so the agent
     * CLI rehydrates from it (same mechanism `restoreSession` uses).
     */
    preExistingAgentSessionFile?: string;
}
/**
 * Dependencies from SessionManager that pipeline steps need.
 * Created via SessionManager.buildPipelineContext().
 */
export interface PipelineContext {
    agentCliPath?: string;
    systemPromptPath?: string;
    roleManager: RoleManager | null;
    toolManager: ToolManager | null;
    mcpManager: McpManager | null;
    goalManager: GoalManager;
    taskManager: TaskManager;
    projectConfigStore: import("./project-config-store.js").ProjectConfigStore | null;
    sandboxManager: SandboxManager | null;
    sandboxTokenStore: import("../auth/sandbox-token.js").SandboxTokenStore | null;
    groupPolicyStore: ToolGroupPolicyStore | null;
    configCascade: ConfigCascade | null;
    costTracker: CostTracker;
    store: SessionStore;
    searchIndex: SearchService;
    sessions: Map<string, SessionInfo>;
    assemblePrompt: (id: string, parts: PromptParts) => string | undefined;
    applySandboxWiring: (opts: RpcBridgeOptions, id: string, sandboxOpts?: SandboxWiringOptions) => Promise<boolean>;
    handleAgentLifecycle: (session: SessionInfo, event: any) => void;
    trackCostFromEvent: (session: SessionInfo, event: any) => void;
    broadcast: (clients: Set<WebSocket>, msg: ServerMessage) => void;
    tryAutoSelectModel: (session: SessionInfo) => Promise<void>;
    tryApplyDefaultThinkingLevel: (session: SessionInfo) => Promise<void>;
    buildWorkflowList: (projectId?: string) => string;
    resolveInitialModel: (role: string | undefined, projectId: string | undefined) => string | undefined;
    resolveInitialThinkingLevel: (role: string | undefined, projectId: string | undefined) => string | undefined;
    /**
     * Persist agentSessionFile + other live-state-derived fields. Optional —
     * tests may construct a context without this; in that case a hard restart
     * during the gap will lose the session, which is fine for unit tests.
     */
    persistSessionMetadata?: (session: SessionInfo) => Promise<void>;
    /** PR status store — source of truth for goal PR URLs (re-attempt context). */
    prStatusStore: PrStatusStore;
}
/**
 * Pure exponential-backoff delay calculator.
 *
 * - `attempt` is 1-based. Raw delay = `baseMs * 2 ** (attempt - 1)`.
 * - Raw delay is capped at `maxMs` BEFORE jitter is applied.
 * - When `jitterRatio > 0`, a symmetric multiplier in
 *   `[1 - jitterRatio, 1 + jitterRatio]` is applied (using `random()`,
 *   default `Math.random`).
 * - Final delay is clamped to `[0, maxMs]` so jitter can never exceed the
 *   configured cap.
 *
 * Used by `SessionManager.maybeAutoRetryTransient()` for provider
 * overload/rate-limit backoff. Pure — no I/O, no timers — to keep the
 * scheduling logic in session-manager and the math here testable in
 * isolation.
 */
export declare function nextBackoffDelay(attempt: number, opts?: {
    baseMs?: number;
    maxMs?: number;
    jitterRatio?: number;
    random?: () => number;
}): number;
export declare function withRetry<T>(fn: () => Promise<T>, opts: {
    retries: number;
    delays: number[];
    label: string;
    sessionId: string;
}): Promise<T>;
/** Step 1: Construct RpcBridgeOptions base (cliPath, env, args). */
export declare function resolveBridgeOptions(plan: SessionSetupPlan, ctx: PipelineContext): void;
/** Step 2: Add goal/team extension paths to bridge args. */
export declare function resolveGoalExtensions(plan: SessionSetupPlan, ctx: PipelineContext): void;
/** Step 3: Compute effectiveAllowedTools, filter host-only tools for sandbox. */
export declare function resolveTools(plan: SessionSetupPlan, ctx: PipelineContext): void;
/** Step 4: Assemble system prompt (handles assistant, normal, delegate variants). */
export declare function resolvePrompt(plan: SessionSetupPlan, ctx: PipelineContext): void;
/**
 * Step 5: computeToolActivationArgs + writeMcpProxyExtensions + writeToolGuardExtension.
 *
 * Tool surface is selected by three intersecting paths, all funneled through
 * `effectiveRole` and the policy cascade in `tool-activation.ts`:
 *
 *   1. **Role-with-policy**: `plan.roleName` resolves to a registered role;
 *      its `toolPolicies` (allow/ask/never per group) override builtin
 *      defaults. MCP proxy + guard extensions are emitted as needed.
 *   2. **Team-lead / role-less**: `plan.roleName` is unset (regular sessions,
 *      goal team-lead, goal/project/tool assistants). `effectiveRole` is
 *      `undefined` and the cascade falls back to `groupPolicyStore` defaults
 *      (which themselves fall back to builtin defaults). The full tool
 *      surface allowed for the user is exposed.
 *   3. **MCP-only**: when `mcpManager` is present, MCP-proxy extensions are
 *      written regardless of role so MCP servers stay reachable; per-server
 *      policies still apply.
 *
 * The guard extension is emitted whenever any tool resolves to `ask` or
 * `never` so the agent can't bypass the policy by calling the tool directly.
 */
export declare function resolveToolActivation(plan: SessionSetupPlan, ctx: PipelineContext): void;
/** Shared event subscription, returns unsubscribe fn. */
export declare function subscribeToEvents(session: SessionInfo, ctx: PipelineContext): () => void;
/** Single store.put() with ALL structural fields. Called exactly once per session. */
export declare function persistOnce(session: SessionInfo, plan: SessionSetupPlan, store: SessionStore): void;
/**
 * Run the full pipeline synchronously: resolve steps → spawn agent → persist → post-spawn.
 * Used by normal and delegate session creation.
 */
export declare function executePlan(plan: SessionSetupPlan, ctx: PipelineContext): Promise<SessionInfo>;
/**
 * For worktree sessions: create worktree, then run remaining pipeline
 * on the existing "preparing" session. Updates session in place.
 */
export declare function executeWorktreeAsync(plan: SessionSetupPlan, session: SessionInfo, ctx: PipelineContext, preBuiltWorktreePath?: string): Promise<void>;
/**
 * Send the task prompt to a delegate session and wait for streaming to begin.
 * Enforces a timeout — rejects if the agent doesn't start streaming in time.
 */
export declare function sendDelegatePrompt(session: SessionInfo, _instructions: string, timeoutMs: number): Promise<void>;
/**
 * Clean up after a failed session setup. Order:
 * 1. Remove from in-memory map (fast — UI updates immediately)
 * 2. Archive in store (preserves evidence for debugging)
 * 3. Notify connected clients
 * 4. Background worktree cleanup (slow, non-blocking)
 * 5. Release sandbox pool slot if claimed
 * 6. Clean up sandbox token
 */
export declare function handleSetupFailure(session: SessionInfo, plan: SessionSetupPlan, error: Error, ctx: PipelineContext): void;
//# sourceMappingURL=session-setup.d.ts.map