/** * The three panes. * * Chat on the left, the plan in the middle, decisions on the right. All three * are visible at once by design: the thing worth watching is the agent editing * prose while you are reading it, and a tab would hide exactly that. * * A pane that has nothing to show is not rendered, so the grid collapses to * whatever exists rather than reserving space for a placeholder. */ import { useCallback, useEffect, useRef, useState } from "react"; import type { ReactNode } from "react"; const MIN = 240; const MAX = 520; type Side = "left" | "right"; function clamp(value: number): number { return Math.min(MAX, Math.max(MIN, value)); } /** * A draggable edge. * * Pointer capture rather than window listeners: the pointer leaves the handle * immediately on any real drag, and capture is what keeps the events coming * without a document-level subscription to tear down. */ function Handle({ onResize, side }: { onResize: (delta: number) => void; side: Side }) { let origin = useRef(0); return (