Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,21 @@ const result = grid_row * GRID_COLS + grid_col; // usize, works correctly
- When hoisting shared locals (e.g., `cursor`) to wider scopes inside long functions, avoid re-declaring them later with the same name. Zig treats this as shadowing and fails compilation. Prefer a single binding per logical value or choose distinct names for nested scopes to prevent “local constant shadows” errors.

### Zig 0.15 collection API differences
- `std.ArrayList(T)` now prefers `initCapacity(allocator, 0)`; `append` and similar methods require the allocator argument (`list.append(allocator, item)`).
- `std.ArrayList(T)`: Zig 0.15 only provides `initCapacity(allocator, n)`, not `init()`. When initializing, use a reasonable capacity estimate (e.g., 8 or 16) rather than 0—`initCapacity(allocator, 0)` still allocates and is wasteful. For truly lazy allocation, use `.empty` and pass the allocator on each operation. Methods like `append` require the allocator argument (`list.append(allocator, item)`).
- `std.fmt.allocPrintZ` is unavailable; create a null-terminated buffer manually: allocate `len+1`, copy bytes, set the last byte to 0, and slice as `buf[0..len :0]`.
- For writers, `toml.serialize` expects `*std.Io.Writer`. Use `std.Io.Writer.Allocating.init(allocator)` (or `initCapacity`) and pass `&writer.writer`; read bytes with `writer.written()`.

### Loop boundary conditions
When iterating over slices with index arithmetic, use `< len` not `<= len`:
```zig
// WRONG: iterates one past the end, causing unnecessary work or out-of-bounds
while (pos <= slice.len) { ... }

// CORRECT: stops at the last valid position
while (pos < slice.len) { ... }
```
The `<= len` pattern is only correct when `pos` represents a position *after* processing (e.g., `slice[0..pos]` as a "processed so far" marker).

## Build and Test (required after every task)
- Run `zig build` and `zig build test` (or `just ci` when appropriate) once the task is complete.
- Report the results in your summary; if you must skip tests, state the reason explicitly.
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ Architect solves this with a grid view that keeps all your agents visible, with

### Agent-Focused
- **Status highlights** — agents glow when awaiting approval or done, so you never miss a prompt
- **Grid view** — keep 4+ agents visible simultaneously, expand any one to full screen
- **Dynamic grid** — starts with a single terminal in full view; press ⌘N to add a terminal after the current one, and closing terminals compacts the grid forward
- **Grid view** — keep all agents visible simultaneously, expand any one to full screen
- **Worktree picker** (⌘T) — quickly `cd` into git worktrees for parallel agent work on separate branches

### Terminal Essentials
- Smooth expand/collapse animations between grid and focused views
- Keyboard navigation: ⌘+Return to expand, ⌘1–⌘0 to switch, ⌘W to close, ⌘/ for shortcuts
- Smooth animated transitions for grid expansion, contraction, and reflow (cells and borders move/resize together)
- Keyboard navigation: ⌘+Return to expand, ⌘1–⌘0 to switch grid slots, ⌘N to add, ⌘W to close (restarts if it's the only terminal), ⌘/ for shortcuts
- Scrollback with trackpad/wheel support and grid indicator when scrolled
- OSC 8 hyperlink support (Cmd+Click to open)
- Kitty keyboard protocol for enhanced key handling
Expand Down Expand Up @@ -107,9 +108,9 @@ just build
Architect stores configuration in `~/.config/architect/`:

* `config.toml`: read-only user preferences (edit via `⌘,`).
* `persistence.toml`: runtime state (window position/size, font size), managed automatically.
* `persistence.toml`: runtime state (window position/size, font size, terminal cwds), managed automatically.

Common settings include font family, theme colors, and grid rows/cols. Remove the files to reset to the default values.
Common settings include font family, theme colors, and grid font scale. The grid size is dynamic and adapts to the number of terminals. Remove the files to reset to the default values.

## Troubleshooting

Expand Down
7 changes: 5 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Architecture Overview

Architect is a terminal multiplexer displaying interactive sessions in a grid with smooth expand/collapse animations. It is organized around five layers: platform abstraction, input handling, session management, scene rendering, and a UI overlay system.
Architect is a terminal multiplexer displaying interactive sessions in a grid with smooth expand/collapse and resize/reflow animations. It is organized around five layers: platform abstraction, input handling, session management, scene rendering, and a UI overlay system.

```
┌─────────────────────────────────────────────────────────────┐
Expand Down Expand Up @@ -62,6 +62,8 @@ Architect is a terminal multiplexer displaying interactive sessions in a grid wi
- Reports `needsFrame()` when any component requires animation
- Owns per-session `SessionViewState` via `SessionInteractionComponent` (selection, hover, scrollback state)

Grid slots are ordered independently of session IDs: slot indices drive UI focus and shortcuts, while each `SessionState` receives a monotonic `id` used for external notifications. Slots may be compacted without changing session IDs. Grid resize animations are canceled when the last terminal is relaunched so the renderer does not keep animating stale cell geometry, and runtime logs (including short frame traces) capture the close/relaunch path for debugging.

**UiAssets** provides shared rendering resources:
- `FontCache` stores configured fonts keyed by pixel size, so terminal rendering and UI components reuse a single loaded font set instead of opening per-component instances.

Expand Down Expand Up @@ -163,14 +165,15 @@ src/

### View Modes (`app_state.ViewMode`)
```
Grid → 3×3 overview, all sessions visible
Grid → Dynamic grid overview, all sessions visible
Expanding → Animating from grid cell to fullscreen
Full → Single session fullscreen
Collapsing → Animating from fullscreen to grid cell
PanningLeft → Horizontal pan animation (moving left)
PanningRight → Horizontal pan animation (moving right)
PanningUp → Vertical pan animation (moving up)
PanningDown → Vertical pan animation (moving down)
GridResizing → Grid is expanding or shrinking (adding/removing cells)
```

### Session Status (`app_state.SessionStatus`)
Expand Down
33 changes: 15 additions & 18 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ The font family must be installed on your system. Common choices:

```toml
[grid]
rows = 3 # Number of rows (1-12, default: 3)
cols = 3 # Number of columns (1-12, default: 3)
font_scale = 1.0 # Font scale in grid view (0.5-3.0, default: 1.0)
```

The grid defines how many terminal sessions are displayed. Values outside the valid range are clamped automatically.
The grid size is dynamic and adjusts automatically based on the number of terminals:
- Press `Cmd+N` to add a new terminal after the currently focused one — the grid expands to accommodate it
- Press `Cmd+W` to close a terminal — remaining terminals compact forward to fill gaps and the grid shrinks when possible; if it's the only terminal, it restarts in place
- When only one terminal is spawned, the view stays in full-screen mode
- Grid layout maintains `columns >= rows` (e.g., 1x1 → 2x1 → 2x2 → 3x2 → 3x3 → ...)
- Maximum grid size is 12×12 (144 terminals)

### Window Configuration

Expand Down Expand Up @@ -145,8 +148,6 @@ family = "JetBrains Mono"
size = 13

[grid]
rows = 2
cols = 3
font_scale = 0.9

[theme]
Expand Down Expand Up @@ -199,10 +200,11 @@ height = 900
x = 100
y = 50

[terminals]
terminal_1_1 = "/Users/me/projects/app"
terminal_1_2 = "/Users/me/projects/lib"
terminal_2_1 = "/Users/me"
terminals = [
"/Users/me/projects/app",
"/Users/me/projects/lib",
"/Users/me",
]
```

### Fields
Expand All @@ -211,18 +213,14 @@ terminal_2_1 = "/Users/me"
|-------|-------------|
| `font_size` | Current font size (adjusted with `Cmd++`/`Cmd+-`) |
| `[window]` | Last window position and dimensions |
| `[terminals]` | Working directories for each terminal cell |
| `terminals` | Working directories for each terminal (ordered by session index) |

### Terminal Keys

Terminal keys use 1-based `row_col` format:
- `terminal_1_1` = top-left cell (row 1, column 1)
- `terminal_2_3` = second row, third column

On launch, Architect restores terminals to their saved working directories. Entries outside the current grid dimensions are pruned automatically.
On launch, Architect restores terminals to their saved working directories. The grid automatically resizes to fit the number of restored terminals.

Note: Terminal cwd persistence is currently macOS-only.

Older `persistence.toml` files that used the `[terminals]` table are migrated automatically.

## Resetting Configuration

Delete the configuration files to reset to defaults:
Expand All @@ -237,4 +235,3 @@ Or remove the entire directory:
```bash
rm -rf ~/.config/architect
```

1 change: 1 addition & 0 deletions src/app/app_state.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub const ViewMode = enum {
PanningRight,
PanningUp,
PanningDown,
GridResizing, // Grid is reflowing or changing dimensions (adding/removing cells)
};

pub const Rect = geom.Rect;
Expand Down
Loading