/**
 * ApprovalManager — in-memory Claude Code PermissionRequest approval flow.
 *
 * Hook script (bin/ccweb-approval-hook.js) holds an HTTP POST open until the
 * user decides in the web UI; this manager bridges that POST to a WS event
 * and back to a Promise resolution.
 *
 * Security:
 *  - Shared HMAC secret at ~/.ccweb/approval-secret (mode 0600) verifies hook ↔ backend calls.
 *  - Hook HTTP is 127.0.0.1-only (enforced at route level) so LAN clients can't forge requests.
 *  - Frontend decide() goes through JWT-auth'd route.
 *
 * Claude-only on purpose (not a missed adapter abstraction):
 *   - Codex DOES have an approval system (`approval_policy = on-request`),
 *     but it is purely internal to the TUI — Codex does NOT emit external
 *     webhooks for pre-tool decisions, so ccweb cannot intercept. The only
 *     adapter surfaces are (a) MCP server wrapping or (b) the undocumented
 *     `--remote ws://...` TUI protocol, both of which are an order of
 *     magnitude more engineering than this module. Keeping this Claude-only
 *     is a cost decision, not "Codex lacks approval".
 *   - Gemini / OpenCode / Qwen likewise have no compatible webhook surface.
 */
export interface ApprovalRequest {
    projectId: string;
    toolUseId: string;
    toolName: string;
    toolInput: unknown;
    sessionId: string;
    createdAt: number;
}
export interface ApprovalDecision {
    behavior: 'allow' | 'deny';
    message?: string;
}
declare class ApprovalManager {
    private pending;
    private secret;
    private listeners;
    constructor();
    getSecretFile(): string;
    sign(data: string): string;
    verify(data: string, signature: string): boolean;
    private keyOf;
    /** Register a new pending approval. Resolves with the decision (or timeout deny). */
    register(req: ApprovalRequest, timeoutMs: number): Promise<ApprovalDecision>;
    /** Resolve a pending request with a decision. Returns true if it existed. */
    decide(projectId: string, toolUseId: string, decision: ApprovalDecision): boolean;
    /** Cancel a pending request (e.g. hook client disconnected). Resolves with a deny internally; no WS resolved event. */
    cancel(projectId: string, toolUseId: string, reason: string): boolean;
    /** List all pending approvals for a project (for UI reconnect). */
    listPending(projectId: string): ApprovalRequest[];
    subscribe(fn: (evt: ApprovalEvent) => void): () => void;
    private emit;
}
export type ApprovalEvent = ({
    type: 'approval_request';
} & ApprovalRequest) | {
    type: 'approval_resolved';
    projectId: string;
    toolUseId: string;
    behavior: 'allow' | 'deny';
    reason?: string;
};
export declare const approvalManager: ApprovalManager;
export {};
//# sourceMappingURL=approval-manager.d.ts.map