// hosts/claude-code/runtime/plan-mode-gate.ts — SPEC-587
// Signals the Claude Code host to enter Plan mode at merger/planning gates
// when the spec is not yet approved.
/** Default timeout before abandoning plan-mode wait (ms). */
const PLAN_MODE_TIMEOUT_MS = 300_000; // 5 minutes
/**
 * Creates an awaiter that resolves after a timeout.
 * In production the host is expected to emit ExitPlanMode before this fires.
 * @internal exported for testing
 */
export function createExitPlanModeAwaiter(timeoutMs = PLAN_MODE_TIMEOUT_MS) {
    let resolved = false;
    let resolvePromise;
    const promise = new Promise((res) => {
        resolvePromise = res;
        // Auto-resolve after timeout so the flow never hangs forever
        setTimeout(() => {
            if (!resolved) {
                resolved = true;
                res();
            }
        }, timeoutMs);
    });
    return {
        promise,
        isResolved: () => resolved,
        resolve: () => {
            if (!resolved) {
                resolved = true;
                resolvePromise();
            }
        },
    };
}
/**
 * Enter Claude Code Plan mode when:
 *   1. The host declares it supports plan mode (context.hostSupportsPlanMode)
 *   2. The spec has not yet been approved (context.specApproved === false)
 *   3. The gate stage is 'merger' or 'planner'
 *
 * Returns a PlanModeGateResult with modeHint: "plan" to embed in the MCP
 * tool response. The caller must include this hint in the response JSON for
 * the Claude Code host to react.
 *
 * When any condition is not met, returns entered: false and a plain message
 * so the caller can proceed without blocking.
 */
export function enterPlanModeIfSupported(context) {
    const planStages = new Set(['merger', 'planner']);
    if (!context.hostSupportsPlanMode) {
        return {
            entered: false,
            message: `plan-mode gate: host does not support plan mode — proceeding with stage "${context.stage}"`,
        };
    }
    if (context.specApproved) {
        return {
            entered: false,
            message: `plan-mode gate: spec ${context.specId} already approved — skipping plan mode`,
        };
    }
    if (!planStages.has(context.stage)) {
        return {
            entered: false,
            message: `plan-mode gate: stage "${context.stage}" does not require plan mode`,
        };
    }
    return {
        entered: true,
        modeHint: 'plan',
        message: `plan-mode gate: entering plan mode for spec ${context.specId} at stage "${context.stage}" — awaiting ExitPlanMode`,
    };
}
//# sourceMappingURL=plan-mode-gate.js.map