-
- {#if editingLabel}
-
- {:else}
-
- {/if}
-
-
-
- {#if distroOpen}
-
- {/if}
-
-
-
-
- {status}
-
-
-
-
-
-
-
-
- {
- status = msg;
- statusOk = ok;
- }}
- onSpawn={onPaneSpawned}
- onInput={onTerminalInput}
- onFocus={() => orch.setActive(leaf.id)}
- {onDataReceived}
- {focusTrigger}
- />
-
-
-
-
diff --git a/src/lib/layout/LeafPane.tsx b/src/lib/layout/LeafPane.tsx
new file mode 100644
index 0000000..73d8f49
--- /dev/null
+++ b/src/lib/layout/LeafPane.tsx
@@ -0,0 +1,263 @@
+import {
+ useState,
+ useEffect,
+ useRef,
+ useCallback,
+ type KeyboardEvent,
+ type MouseEvent,
+} from "react";
+import type { LeafNode } from "./tree";
+import { useOrchestration } from "./orchestration";
+import XtermPane from "../../components/XtermPane";
+import "./LeafPane.css";
+
+const IDLE_THRESHOLD_MS = 5000;
+
+export default function LeafPane({ leaf }: { leaf: LeafNode }) {
+ const orch = useOrchestration();
+ const isActive = orch.activeLeafId === leaf.id;
+ const isBroadcasting = !!leaf.broadcast;
+
+ // ---- status (from XtermPane) -------------------------------------------
+ const [status, setStatus] = useState("starting…");
+ const [statusOk, setStatusOk] = useState(true);
+
+ // ---- label editing -----------------------------------------------------
+ const [editingLabel, setEditingLabel] = useState(false);
+ const [labelDraft, setLabelDraft] = useState("");
+ const labelInputRef = useRef