Skip to content

Commit a963801

Browse files
committed
Merge remote-tracking branch 'origin/main' into pr/divaltor/47
* origin/main: feat(tui): Two-column layout with detail preview (hmans#42) feat: add ETag support for optimistic concurrency control (hmans#59) feat(plugin): improve OpenCode plugin robustness with availability checks (hmans#58) feat(cli): Add --prefix flag to create command (hmans#56) chore: clean up README.md docs: only push prime if it exists (hmans#52) fix: normalise short IDs when storing relationship links (hmans#50)
2 parents 97930e3 + e1c178c commit a963801

40 files changed

Lines changed: 3174 additions & 122 deletions
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# beans-3f64
3+
title: 'Phase 1: Compact list format'
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2025-12-28T17:38:41Z
8+
updated_at: 2025-12-28T18:44:44Z
9+
parent: beans-t0tv
10+
---
11+
12+
Add single-character type and status codes to make the list more compact. Prerequisite for two-column layout.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# beans-41ly
3+
title: 'Phase 3: Two-column layout composition'
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2025-12-28T17:38:52Z
8+
updated_at: 2025-12-28T18:56:24Z
9+
parent: beans-t0tv
10+
---
11+
12+
Wire up the two-column layout in the main App with responsive width detection.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# beans-433o
3+
title: 'Phase 2: Detail preview component'
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2025-12-28T17:38:51Z
8+
updated_at: 2025-12-28T18:49:10Z
9+
parent: beans-t0tv
10+
---
11+
12+
Create a lightweight, read-only detail preview that can be rendered in the right pane.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# beans-6x50
3+
title: 'Phase 5: Integration and polish'
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2025-12-28T17:38:53Z
8+
updated_at: 2025-12-28T19:04:41Z
9+
parent: beans-t0tv
10+
---
11+
12+
Final integration, help overlay updates, edge case handling, and testing.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# beans-ld8p
3+
title: 'Two-column layout: right pane extends beyond screen width'
4+
status: scrapped
5+
type: bug
6+
priority: normal
7+
created_at: 2025-12-28T19:20:10Z
8+
updated_at: 2025-12-28T19:22:00Z
9+
parent: t0tv
10+
---
11+
12+
Same root cause as beans-m3mq - the footer in list.View() is not width-constrained, causing lipgloss.JoinHorizontal to miscalculate widths. See beans-m3mq for details.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
# beans-m3mq
3+
title: 'Two-column layout: left pane too narrow with whitespace gap'
4+
status: completed
5+
type: bug
6+
priority: normal
7+
created_at: 2025-12-28T19:20:10Z
8+
updated_at: 2025-12-28T19:49:19Z
9+
parent: beans-t0tv
10+
---
11+
12+
The left pane only takes up ~40 chars instead of the intended 55 chars. There's significant whitespace between the left and right panes.
13+
14+
## Screenshot
15+
16+
```
17+
╭─────────────────────────────────────────────────────╮ ╭─────────────────────────────
18+
│ Beans │ │ beans-18db
19+
│ │ │ beans milestones command
20+
│ beans-f11p M I Milestone 0.4.0 │ │
21+
│ ├─ beans-hz87 F T Add blocked-by relatio... │ │ Status: todo Type: task
22+
```
23+
24+
## Root Cause (investigation notes)
25+
26+
The issue is in `list.View()` (list.go:500-567):
27+
- The border box is constrained to `m.width - 2`
28+
- BUT the footer is appended as `content + "\n" + footer` without width constraint
29+
- The footer line extends to full terminal width
30+
- `lipgloss.JoinHorizontal` sees the left pane width as the footer width (unbounded), not the box width
31+
32+
## Fix
33+
34+
The footer needs to be constrained to the same width as the border box, or the entire View() output needs width clamping.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# beans-pri5
3+
title: 'Phase 4: Cursor sync'
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2025-12-28T17:38:53Z
8+
updated_at: 2025-12-28T18:59:15Z
9+
parent: beans-t0tv
10+
---
11+
12+
Detect cursor changes in the list and update the preview pane accordingly.

.beans/beans-t0tv--refactor-tui-to-two-column-layout-with-hierarchica.md

Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
# beans-t0tv
33
title: Refactor TUI to two-column layout with hierarchical navigation
4-
status: todo
4+
status: in-progress
55
type: feature
6+
priority: normal
67
created_at: 2025-12-14T15:37:22Z
7-
updated_at: 2025-12-14T15:37:22Z
8+
updated_at: 2025-12-28T19:20:20Z
89
parent: beans-f11p
910
---
1011

@@ -45,18 +46,109 @@ The current single-list view doesn't provide enough context about individual bea
4546
- Batch selection and editing
4647
- Opening bean in editor
4748

48-
## Checklist
49-
50-
- [ ] Design the two-column layout structure with Bubbletea
51-
- [ ] Implement left pane (bean list) component
52-
- [ ] Implement right pane (bean detail) component
53-
- [ ] Add responsive width handling between panes
54-
- [ ] Implement Enter to drill into bean hierarchy
55-
- [ ] Implement back navigation (Escape/Backspace)
56-
- [ ] Add breadcrumb/path indicator showing current root
57-
- [ ] Preserve filtering functionality
58-
- [ ] Preserve status change shortcuts
59-
- [ ] Preserve batch selection and editing
60-
- [ ] Preserve editor integration
61-
- [ ] Handle edge cases (no children, deep nesting, narrow terminals)
62-
- [ ] Update help overlay with new keybindings
49+
## Subtasks
50+
51+
- beans-3f64: Phase 1 - Compact list format (single-char type/status)
52+
- beans-433o: Phase 2 - Detail preview component
53+
- beans-41ly: Phase 3 - Two-column layout composition
54+
- beans-pri5: Phase 4 - Cursor sync
55+
- beans-6x50: Phase 5 - Integration and polish
56+
57+
## Implementation Plan
58+
59+
See `_spec/plans/2025-12-28-tui-two-column-layout.md` for detailed implementation steps.
60+
61+
## Research
62+
63+
- [[2025-12-28-beans-t0tv-tui-two-column-layout]] - Codebase research documenting the current TUI implementation and architecture considerations for two-column layout
64+
65+
## Design
66+
67+
### Key Decisions
68+
69+
1. **No hierarchy drilling** - list stays flat with tree structure, filtering handles focus
70+
2. **Cursor updates preview** - moving through list immediately shows bean details
71+
3. **Read-only right pane** - no focus, no shortcuts, just visual preview
72+
4. **Enter for full detail** - opens existing full-screen detail view with all features
73+
5. **Responsive collapse** - below 120 columns, single-column list (current behavior)
74+
6. **Compact list format** - single-character type/status codes everywhere
75+
76+
### Layout
77+
78+
**Two-column mode (≥120 columns):**
79+
```
80+
┌─────────────────────────────────┬──────────────────────────────────────────┐
81+
│ Beans │ beans-t0tv │
82+
│ │ Refactor TUI to two-column layout │
83+
│ ▌ beans-t0tv F T Refactor TUI │──────────────────────────────────────────│
84+
│ beans-f11p E T TUI Improve.. │ Status: todo Type: feature │
85+
│ beans-govy F T Add Y shortc. │ Parent: beans-f11p │
86+
│ │──────────────────────────────────────────│
87+
│ │ ## Summary │
88+
│ │ Refactor the TUI to a two-column format │
89+
│ │ ... │
90+
├─────────────────────────────────┴──────────────────────────────────────────┤
91+
│ enter view · e edit · space select · ? help │
92+
└────────────────────────────────────────────────────────────────────────────┘
93+
```
94+
95+
**Single-column mode (<120 columns):** Current list behavior, unchanged.
96+
97+
**Dimensions:**
98+
- Left pane: fixed 55 characters
99+
- Right pane: remaining width minus borders
100+
- Threshold: 120 columns for two-column mode
101+
102+
### Compact List Format
103+
104+
Single-character codes for type and status columns:
105+
106+
**Types:** M(ilestone), E(pic), B(ug), F(eature), T(ask)
107+
108+
**Statuses:** D(raft), T(odo), I(n-progress), C(ompleted), S(crapped)
109+
110+
Applied everywhere (not just two-column mode) for consistency.
111+
112+
### Navigation
113+
114+
**In two-column mode:**
115+
- `j/k`, arrows - move cursor, preview updates automatically
116+
- `enter` - open full-screen detail view
117+
- `space` - toggle multi-select
118+
- `p/s/t/P/b/e/y/c` - existing shortcuts work on highlighted bean
119+
- `g t` - tag filter, `/` - text filter, `?` - help overlay
120+
- `esc` - clear selection, then clear filter
121+
122+
**In full-screen detail (unchanged):**
123+
- `tab` - switch focus between links and body
124+
- `j/k` - scroll body
125+
- `enter` - navigate to linked bean
126+
- `esc` - back to two-column view
127+
128+
### Implementation
129+
130+
**Cursor sync:** Detect cursor change in list Update(), emit `cursorChangedMsg`. App handles it to update detail preview.
131+
132+
**View rendering:** In `View()`, if width ≥120, compose left (list) + right (preview) with `lipgloss.JoinHorizontal`.
133+
134+
**Files to modify:**
135+
- `internal/tui/tui.go` - View() composition, cursor change handling
136+
- `internal/tui/list.go` - ViewCompact(), compact type/status, cursor change detection
137+
- `internal/tui/detail.go` - extract preview rendering
138+
- `internal/ui/styles.go` - single-char type/status formatting helpers
139+
140+
### Edge Cases
141+
142+
- **Empty list:** right pane shows "No bean selected"
143+
- **Terminal resize:** automatic switch between one/two column
144+
- **Long body:** truncated in preview, scroll in full-screen detail
145+
- **Bean deleted:** list reloads, cursor adjusts, preview updates
146+
- **Multi-select:** preview shows cursor's bean (not summary)
147+
- **Links in preview:** shown but non-interactive
148+
149+
### Out of Scope (YAGNI)
150+
151+
- Hierarchy drilling (Enter to show only children)
152+
- Configurable pane widths
153+
- Keyboard focus on right pane
154+
- Breadcrumb navigation
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
# beans-tbtr
3+
title: 'Two-column layout polish: footer, pane widths, preview height'
4+
status: completed
5+
type: task
6+
created_at: 2025-12-28T19:44:32Z
7+
updated_at: 2025-12-28T19:44:32Z
8+
parent: t0tv
9+
---
10+
11+
Several polish fixes for the two-column TUI layout:
12+
13+
- Footer is now app-global, spanning full terminal width (not constrained to left pane)
14+
- Right pane capped at 80 chars max width (text files follow 80-char convention), left pane gets remaining space
15+
- Preview height properly constrained to prevent overflow when bean body is long
16+
- Detail view linked beans show full type/status names instead of single-char abbreviations
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
# beans-vn93
3+
title: Responsive type/status column expansion in TUI
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2025-12-29T18:30:52Z
8+
updated_at: 2025-12-29T18:39:15Z
9+
parent: beans-t0tv
10+
---
11+
12+
Show full type/status names (e.g., 'feature', 'in-progress') when terminal is wide enough (≥120 cols), single-letter abbreviations (F, I) when space is tight.
13+
14+
**Scope:** TUI only (not CLI output).
15+
16+
## Plan
17+
18+
1. Add `UseFullTypeStatus bool` to `ResponsiveColumns` struct
19+
2. Update `CalculateResponsiveColumns()` to set flag when width ≥ 120
20+
3. Update list delegate to pass `UseFullNames: d.cols.UseFullTypeStatus` to `RenderBeanRow`
21+
22+
## Files
23+
- `internal/ui/styles.go` - ResponsiveColumns, CalculateResponsiveColumns
24+
- `internal/tui/list.go` - itemDelegate.Render

0 commit comments

Comments
 (0)