Add M4 orchestration: broadcast, idle notifications, palette
tree.ts
- LeafNode gains broadcast?: boolean
- walkLeaves(root) generator; toggleBroadcast helper
ops.ts (PaneOps)
- toggleBroadcast, broadcastFrom, setActivePane, registerPaneId,
notify; activeLeafId data field.
XtermPane.svelte
- onSpawn(paneId), onInput(b64), onDataReceived(),
and focusTrigger prop. All optional; backward-compatible.
LeafPane.svelte
- 📡 broadcast toggle; 5s idle detection -> ops.notify (once per
idle cycle); active + broadcasting border colors; click-to-focus
via setActivePane + focusTrigger bump.
New Notifications.svelte
- Top-right toast stack, slide-in, 5s auto-dismiss + click ×.
New Palette.svelte
- Modal overlay, backdrop, filtered leaf list with ↑/↓ + Enter,
Escape to close.
App.svelte
- paneIdByLeaf Map for routing; notifications array + auto-dismiss;
activeLeafId; Ctrl+K global listener; broadcastFrom routes via
walkLeaves + writeToPane to all other broadcast leaves; ⌘K button
in titlebar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
64b90ebddb
commit
3c2f6b8640
8 changed files with 578 additions and 28 deletions
|
|
@ -19,6 +19,12 @@ export interface LeafNode {
|
|||
cwd?: string;
|
||||
/** Optional user label shown in the pane toolbar. */
|
||||
label?: string;
|
||||
/**
|
||||
* If true, keystrokes typed in this pane are mirrored to every other
|
||||
* leaf with `broadcast === true`. Toggle via the 📡 button in the
|
||||
* pane toolbar.
|
||||
*/
|
||||
broadcast?: boolean;
|
||||
}
|
||||
|
||||
export interface SplitNode {
|
||||
|
|
@ -174,6 +180,24 @@ export function leafCount(root: TreeNode): number {
|
|||
return leafCount(root.a) + leafCount(root.b);
|
||||
}
|
||||
|
||||
/** Iterate all leaves in left-to-right order. */
|
||||
export function* walkLeaves(root: TreeNode): Generator<LeafNode> {
|
||||
if (root.kind === "leaf") {
|
||||
yield root;
|
||||
} else {
|
||||
yield* walkLeaves(root.a);
|
||||
yield* walkLeaves(root.b);
|
||||
}
|
||||
}
|
||||
|
||||
/** Toggle a leaf's broadcast flag. Metadata-only — does NOT swap the id, so the pane is not respawned. */
|
||||
export function toggleBroadcast(root: TreeNode, leafId: NodeId): TreeNode {
|
||||
return replaceById(root, leafId, (node) => {
|
||||
if (node.kind !== "leaf") return node;
|
||||
return { ...node, broadcast: !node.broadcast };
|
||||
});
|
||||
}
|
||||
|
||||
export function serialize(root: TreeNode): string {
|
||||
return JSON.stringify(root);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue