feat(app): M2 layout TS types + bridge commands

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-09 21:28:54 +07:00
parent 62a65b691d
commit ee2f7097ce
2 changed files with 102 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
export type Orient = "h" | "v";
export type LayoutNode =
| { leaf: { surface_id: string } }
| { split: { orient: Orient; ratios: number[]; children: LayoutNode[] } };
export interface SurfaceView {
spec: {
command: string;
args: string[];
cwd: string;
agent_label: string | null;
cols: number;
rows: number;
autostart: boolean;
};
running: boolean;
}
export interface Group {
id: string;
name: string;
color: string;
order: number;
}
export interface WorkspaceView {
id: string;
path: string;
name: string;
group_id: string | null;
order: number;
unread: boolean;
layout: LayoutNode | null;
surfaces: Record<string, SurfaceView>;
}
export function leafIds(node: LayoutNode | null): string[] {
if (!node) return [];
if ("leaf" in node) return [node.leaf.surface_id];
return node.split.children.flatMap(leafIds);
}
+60
View File
@@ -1,5 +1,6 @@
import { invoke, Channel } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import type { Group, WorkspaceView } from "./layoutTypes";
export interface WorkspaceStatus {
workspace_id: string;
@@ -73,3 +74,62 @@ export function onDaemonEvent(handler: (evt: DaemonEvt) => void): Promise<() =>
export function onDaemonRawEvent(name: string, handler: () => void): Promise<() => void> {
return listen(name, () => handler());
}
// ---- M2 additions ----
export interface StatusResult {
groups: Group[];
workspaces: WorkspaceView[];
}
export async function getStatusFull(): Promise<StatusResult> {
return await invoke<StatusResult>("status");
}
export async function splitSurface(surfaceId: string, dir: "right" | "down", command?: string, args: string[] = []): Promise<string> {
const data = await invoke<{ surface_id: string }>("split_surface", { surfaceId, dir, command: command ?? null, args });
return data.surface_id;
}
export async function setRatios(workspaceId: string, nodePath: number[], ratios: number[]): Promise<void> {
await invoke("set_ratios", { workspaceId, nodePath, ratios });
}
export async function moveSurface(surfaceId: string, targetSurfaceId: string, edge: "left" | "right" | "top" | "bottom"): Promise<void> {
await invoke("move_surface", { surfaceId, targetSurfaceId, edge });
}
export async function applyPreset(workspaceId: string, presetId: string, slots: { command?: string; args?: string[] }[]): Promise<string[]> {
const data = await invoke<{ surface_ids: string[] }>("apply_preset", {
workspaceId, presetId,
slots: slots.map((s) => ({ command: s.command ?? null, args: s.args ?? [] })),
});
return data.surface_ids;
}
export async function restartSurface(surfaceId: string): Promise<void> {
await invoke("restart_surface", { surfaceId });
}
export async function closeWorkspaceCmd(workspaceId: string): Promise<void> {
await invoke("close_workspace", { workspaceId });
}
export async function setWorkspaceMeta(workspaceId: string, meta: { name?: string; groupId?: string | null; unread?: boolean; order?: number }): Promise<void> {
await invoke("set_workspace_meta", {
workspaceId,
name: meta.name ?? null,
groupId: meta.groupId === undefined ? null : meta.groupId,
unread: meta.unread ?? null,
order: meta.order ?? null,
});
}
export async function createGroup(name: string, color: string): Promise<string> {
const data = await invoke<{ group_id: string }>("create_group", { name, color });
return data.group_id;
}
export async function closeSurfaceCmd(surfaceId: string): Promise<void> {
await invoke("close_surface", { surfaceId });
}