Skip to content

linux(socket): add system.tree composing window/workspace/pane/surface (Sprint A #5) - #223

Merged
Jesssullivan merged 1 commit into
mainfrom
sid/socket-system-tree
Apr 18, 2026
Merged

Jesssullivan merged 1 commit into
mainfrom
sid/socket-system-tree

Conversation

@Jesssullivan

Copy link
Copy Markdown
Owner

Summary

  • Adds system.tree to the Linux v2 socket dispatch, mirroring the macOS response shape.
  • Composes window.list + workspace.list + pane.list + surface.list into a single envelope so CLIs / status-bar clients don't need N+1 round-trips.
  • Exploits Linux's current 1:1 panel:pane mapping: every pane has exactly one surface, and `pane.id == surface.id` for that pair. The shape leaves room for future pane grouping without breaking clients.
  • Adds a socket round-trip test exercising structure, refs, focus pointer, and the 1:1 invariant. Test creates an extra workspace, restores baseline selection, and tears down in a `finally` block.

Tree shape

```
active: { workspace_id, surface_id, window_id } // matches system.identify
windows[]: {
id, ref, index, workspace_count, selected_workspace_id,
workspaces[]: {
id, ref, index, title, selected, pinned,
panes[]: {
id, ref, index, focused, surface_count, selected_surface_id, selected_surface_ref,
surfaces[]: {
id, ref, index, index_in_pane, type, focused, selected, selected_in_pane,
pane_id, pane_ref, title
}
}
}
}
```

Optional macOS params (`workspace_id`, `all_windows`, `caller`) are not yet implemented; tree always covers every known window. Filed as a follow-up note in the docstring.

Sprint context

Test plan

  • Local: `git diff --stat` confirms surgical change (one new function + one test).
  • CI: Socket Tests workflow on `sid/socket-system-tree` runs `tests_v2/test_system_tree.py`.
  • CI: Verify no regression in the existing 14 passing tests.

Future work

  • Implement `workspace_id`, `all_windows`, `caller` filters once a use case appears.
  • Update tree shape if/when Linux adds pane grouping (`pane.join` / `pane.break`).

Related

@greptile-apps

greptile-apps Bot commented Apr 18, 2026 •

Copy link
Copy Markdown

Greptile Summary

Adds handleSystemTree to the Linux v2 socket dispatch, composing window.list / workspace.list / pane.list / surface.list into a single system.tree RPC that mirrors the macOS envelope shape. The workspace-level output counter (ws_out_idx) and JSON structure are correct; a previously raised concern about the pane-loop comma guard remains the primary open issue on the implementation side. The new test covers envelope structure, 1:1 pane/surface invariant, and the active-workspace pointer, with minor gaps in validating the active.window_id, active.surface_id, and the pane focused boolean.

Confidence Score: 4/5

Safe to merge once the pane comma-guard issue (flagged in a prior review thread) is addressed; new findings are P2 only.

A previously raised P1 concern — the pane loop using raw p_idx rather than a local output counter for the comma guard, which can produce invalid JSON when ordered_panels contains stale entries — remains unresolved in the current code (line 682–684 of socket.zig). All findings introduced by this review pass are P2 (missing assertions in the test). Score stays at 4 until the comma guard is fixed.

cmux-linux/src/socket.zig lines 682–684 (pane comma guard) — see the existing open comment thread on this PR.

Important Files Changed

Filename Overview
cmux-linux/src/socket.zig Adds handleSystemTree (lines 587–729): composes window/workspace/pane/surface into one JSON envelope. The workspace output loop correctly tracks ws_out_idx, but the inner pane loop (line 682–684) guards commas with the raw ordered_panels index p_idx instead of a local output counter, which can emit a leading comma and produce invalid JSON when a panel_id is stale.
tests_v2/test_system_tree.py New round-trip test; validates tree structure, 1:1 invariant, and active workspace pointer. Cleanup via finally block is correct. active.window_id and active.surface_id go unverified, and _assert_pane_node skips the focused bool type-check.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Client([CLI / Status-bar client]) -->|system.tree| Handler[handleSystemTree]
    Handler --> Active["Build active{}\n workspace_id, surface_id, window_id"]
    Handler --> WinLoop["for each window in window_store"]
    WinLoop --> WsCount["Count workspaces in window\n(ws_in_window, sel_ws_in_window)"]
    WsCount --> WsLoop["for each workspace in tm.workspaces\n(filtered by hasWorkspace)"]
    WsLoop --> WsNode["Emit workspace node\n{id, ref, index, title, selected, pinned}"]
    WsNode --> PaneLoop["for each panel_id in ws.ordered_panels\n(p_idx, raw index used for comma guard)"]
    PaneLoop --> PanelLookup{ws.panels.get panel_id}
    PanelLookup -->|missing: continue| PaneLoop
    PanelLookup -->|found| PaneNode["Emit pane node\n{id, ref, index, focused, surface_count=1,\nselected_surface_id, selected_surface_ref}"]
    PaneNode --> SurfNode["Emit single surface node\n{id, ref, index_in_pane=0, type, focused,\nselected=true, pane_id, pane_ref, title}"]
    Active --> Response[JSON response]
    SurfNode --> Response
Loading

Reviews (2): Last reviewed commit: "linux(socket): add system.tree composing..." | Re-trigger Greptile

Comment thread cmux-linux/src/socket.zig
Comment thread tests_v2/test_system_tree.py
The macOS build ships a system.tree RPC that flattens the entire UI hierarchy
into a single response so clients (CLIs, shell prompts, status bars) can avoid
N+1 round-trips. Linux currently exposes the leaf RPCs (window.list,
workspace.list, surface.list, pane.list) but not the composed view.

Add handleSystemTree mirroring the macOS shape:
  active: { workspace_id, surface_id, window_id }   // matches identify
  windows[]: { id, ref, index, workspace_count, selected_workspace_id,
               workspaces[]: { id, ref, index, title, selected, pinned,
                               panes[]: { id, ref, index, focused, surface_count,
                                          selected_surface_id, surfaces[]: {
                                            id, ref, index, index_in_pane, type,
                                            focused, selected, selected_in_pane,
                                            pane_id, pane_ref, title } } } }

Linux uses 1:1 panel:pane today, so each pane has exactly one surface and
pane.id == surface.id. The shape leaves room for future pane grouping
(multiple surfaces per pane) without breaking clients.

The handler is alloc-free in the steady-state error path: every writer.* call
that fails returns the same canonical empty envelope so partial responses
never leak. Workspace and panel titles flow through writeJsonString to keep
user-supplied strings safe.

The new socket round-trip test creates an extra workspace, asserts the
envelope, restores the baseline workspace selection, and closes the
scratch workspace in a finally block so it never leaves stale state.

Sprint A item #5 from #220 (TIN-183 follow-up after #218 / #221 / #222).
@Jesssullivan
Jesssullivan force-pushed the sid/socket-system-tree branch from 1fd049a to cadd33b Compare April 18, 2026 04:46
@Jesssullivan
Jesssullivan merged commit 6cec6c2 into main Apr 18, 2026
22 of 27 checks passed
@Jesssullivan
Jesssullivan deleted the sid/socket-system-tree branch April 18, 2026 04:47

This branch was successfully deployed

No deployments
gpu-tests — cadd33bb Deployed Apr 18, 2026 by Jesssullivan via SSH proxy e2e (honey) #49
distro-tests — cadd33bb Deployed Apr 18, 2026 by Jesssullivan via Distro package tests (self-hosted KVM) #71
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant