Add get-tree and append-layout commands#1958
Open
glassbe wants to merge 4 commits intonikitabobko:mainfrom
Open
Add get-tree and append-layout commands#1958glassbe wants to merge 4 commits intonikitabobko:mainfrom
glassbe wants to merge 4 commits intonikitabobko:mainfrom
Conversation
get-tree dumps the workspace container hierarchy as JSON, including tiling containers (with layout and orientation) and windows (with IDs and app bundle info). Floating windows are included in a separate array. append-layout reads a JSON layout specification from stdin and constructs the corresponding container tree on the target workspace. Windows are matched to spec slots by app-bundle-id. Unmatched windows remain as flat siblings in root. This enables preset layout tools to apply layouts in a single command instead of the fragile flatten/move/join-with/layout dance. Together these bring i3-style programmatic tree access to AeroSpace: - get-tree ≈ i3-msg -t get_tree - append-layout ≈ i3-msg append_layout Includes 7 tests covering JSON output structure, nested containers, floating windows, round-trip serialization, and unmatched window handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes for append-layout to work end-to-end: 1. CLI stdin forwarding: the aerospace CLI only forwarded stdin for workspace/move-node-to-workspace commands. Added AppendLayoutCmdArgs to the stdin-reading condition so piped JSON reaches the server. 2. Workspace spec support: append-layout now accepts both a bare container spec and the full get-tree workspace output (extracts the "tiling" field automatically). This enables the round-trip: aerospace get-tree > layout.json && cat layout.json | aerospace append-layout Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…iles The generate.sh script produces cmdHelpGenerated.swift and subcommandDescriptionsGenerated.swift from docs/aerospace-*.adoc files. Without the .adoc source files, running generate.sh would strip the help entries and CLI subcommand descriptions for the new commands. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…p structure Three improvements to the layout round-trip: 1. Weights: get-tree now outputs "weight" for each child node. append-layout reads it back, preserving custom window sizes (e.g., 70/30 splits) instead of resetting everything to equal. 2. Window-id matching: append-layout now tries to match windows by window-id first before falling back to app-bundle-id. This ensures specific windows (e.g., two Ghostty terminals) end up in the correct slots when restoring a layout immediately. 3. Structure preservation: Replaced normalizeContainers() with a targeted removeEmptyLeafContainers() that only prunes containers with zero children. Single-child containers from the layout spec are now preserved, so missing windows don't collapse the tree. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
This is exactly what I've been looking for. The imperative workarounds I'm using have not worked out well. Would it be possible to match by window-title regex as well, like we can do in the window detected event? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two new commands inspired by i3's
get_treeandappend_layout:get-tree— Serializes the workspace tree to JSON (containers with layout/orientation/weights, windows with IDs and bundle IDs)append-layout— Reads a JSON layout spec from stdin and reconstructs the workspace tree, matching windows bywindow-idthenapp-bundle-idTogether they enable programmatic layout save/restore — a round-trip workflow:
Motivation
AeroSpace currently has no way to programmatically save and restore window arrangements. Users who want preset layouts (e.g., coding layout with specific accordion/tiles nesting) must resort to fragile shell scripts using
flatten+move+join-with, which break due to unpredictable window ordering.These commands fill the gap, similar to i3's
i3-save-tree/append_layoutworkflow.Related discussion: #1957
Implementation Details
get-treerecursively walks the workspace tree and outputs JSON with container layout/orientation/weight and window metadataappend-layoutflattens the workspace, matches windows first bywindow-id(exact match) then byapp-bundle-id(fallback), and rebuilds the container hierarchy from the JSON specappend-layout(same pattern asworkspace --stdin)append-layoutaccepts both raw container specs and fullget-treeoutput (with"type": "workspace"wrapper)Files Changed
New files (8):
docs/aerospace-get-tree.adoc— command documentationdocs/aerospace-append-layout.adoc— command documentationSources/Common/cmdArgs/impl/GetTreeCmdArgs.swift— command argsSources/Common/cmdArgs/impl/AppendLayoutCmdArgs.swift— command argsSources/AppBundle/command/impl/GetTreeCommand.swift— tree serialization with weightsSources/AppBundle/command/impl/AppendLayoutCommand.swift— tree construction with window-id matchingSources/AppBundleTests/command/GetTreeCommandTest.swift— 3 testsSources/AppBundleTests/command/AppendLayoutCommandTest.swift— 7 testsModified files (5):
Sources/Common/cmdArgs/cmdArgsManifest.swift— register new commandsSources/Common/cmdHelpGenerated.swift— regenerated with new help stringsSources/Cli/subcommandDescriptionsGenerated.swift— regenerated with new subcommand entriesSources/AppBundle/command/cmdManifest.swift— command dispatchSources/AppBundle/model/Json.swift— add.doublecase for weight serializationSources/Cli/_main.swift— forward stdin for append-layoutTest Plan
get-treetests: simple, nested, floating windows (including weight output)append-layouttests: simple, nested, unmatched windows, window-id matching, weight preservation, missing window structure preservation, full round-tripgenerate.shregeneration produces consistent output (.adocsource files included)🤖 Generated with Claude Code