v0.2.0 759cc92

data-model.md RawHistoryFolder

Data Model: Browser Controls UI

Entities

1. ZoomLevel

Represents domain-specific zoom preferences for persistent user experience.

Fields:

  • Domain (string, primary key): Website domain (e.g., "github.com", "stackoverflow.com")
  • ZoomFactor (float64): Zoom multiplier (0.3 to 5.0 range, default 1.0)
  • UpdatedAt (time.Time): Timestamp of last zoom level change

Validation Rules:

  • Domain must be valid hostname format
  • ZoomFactor must be within Firefox range: 0.30 ≤ zoom ≤ 5.00
  • ZoomFactor must match standard Firefox zoom levels (30%, 50%, 67%, 80%, 90%, 100%, 110%, 120%, 133%, 150%, 170%, 200%, 240%, 300%, 400%, 500%)
  • UpdatedAt automatically set on creation/update

Relationships:

  • One-to-one with website domains
  • No foreign key relationships (standalone entity)

2. BrowserState (Extended)

Existing entity extended with zoom and navigation state management.

New Fields:

  • CurrentZoomLevel (float64): Active zoom level for current page
  • NavigationHistory ([]HistoryEntry): Back/forward navigation stack
  • HistoryIndex (int): Current position in navigation history

State Transitions:

  • Zoom In: CurrentZoomLevel → Next higher Firefox zoom level
  • Zoom Out: CurrentZoomLevel → Next lower Firefox zoom level
  • Navigate Back: HistoryIndex decrements (if > 0)
  • Navigate Forward: HistoryIndex increments (if < len(NavigationHistory)-1)
  • URL Change: Update CurrentZoomLevel from ZoomLevel persistence

Validation Rules:

  • CurrentZoomLevel follows same rules as ZoomLevel.ZoomFactor
  • HistoryIndex must be valid array index (0 ≤ index < len(NavigationHistory))
  • NavigationHistory maintained as bounded array (configurable max size)

3. KeyboardEvent (Transient)

Represents keyboard input events for processing.

Fields:

  • Key (string): Key identifier ("=", "-", "c")
  • Modifiers ([]string): Active modifier keys (["ctrl"], ["ctrl", "shift"])
  • Timestamp (time.Time): Event occurrence time

Validation Rules:

  • Key must be non-empty string
  • Modifiers must be valid modifier keys ("ctrl", "shift", "alt", "meta")
  • Timestamp must be recent (within reasonable event processing window)

State Transitions:

  • Ctrl+Plus → ZoomIn action
  • Ctrl+Minus → ZoomOut action
  • Ctrl+Shift+C → CopyURL action

4. MouseEvent (Transient)

Represents mouse button events for navigation.

Fields:

  • Button (int): Mouse button identifier (3=back, 4=forward)
  • EventType (string): Event type ("mousedown", "mouseup")
  • Timestamp (time.Time): Event occurrence time

Validation Rules:

  • Button must be 3 (back) or 4 (forward)
  • EventType must be valid mouse event type
  • Only "mousedown" events trigger navigation actions

State Transitions:

  • Button 3 mousedown → NavigateBack action
  • Button 4 mousedown → NavigateForward action

Database Schema Changes

New Table: zoom_levels

CREATE TABLE zoom_levels (
    domain TEXT PRIMARY KEY,
    zoom_factor REAL NOT NULL DEFAULT 1.0 CHECK(zoom_factor >= 0.3 AND zoom_factor <= 5.0),
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_zoom_levels_updated_at ON zoom_levels(updated_at);

SQLC Queries

-- name: GetZoomLevel :one
SELECT zoom_factor FROM zoom_levels WHERE domain = ?;

-- name: SetZoomLevel :exec
INSERT OR REPLACE INTO zoom_levels (domain, zoom_factor, updated_at)
VALUES (?, ?, CURRENT_TIMESTAMP);

-- name: CleanupOldZoomLevels :exec
DELETE FROM zoom_levels WHERE updated_at < date('now', '-30 days');

Data Flow

Zoom Operations

  1. User triggers zoom event → JavaScript captures keyboard event
  2. Frontend calls backend ZoomIn() or ZoomOut() method
  3. Backend calculates next valid Firefox zoom level
  4. Backend updates BrowserState.CurrentZoomLevel
  5. Backend persists to database via SetZoomLevel
  6. Frontend applies CSS zoom styling
  7. Optional: Visual feedback notification

Navigation Operations

  1. User triggers mouse back/forward → JavaScript captures mouse event
  2. Frontend calls backend NavigateBack() or NavigateForward() method
  3. Backend validates navigation history bounds
  4. Backend updates BrowserState.HistoryIndex
  5. Backend returns target URL from history
  6. Frontend navigates WebView to target URL

URL Copy Operation

  1. User triggers Ctrl+Shift+C → JavaScript captures keyboard event
  2. Frontend calls backend CopyCurrentURL() method
  3. Backend retrieves current URL from BrowserState
  4. Backend executes clipboard tool chain (wlcopy → xclip → xsel)
  5. Backend returns success/failure status
  6. Optional: Visual feedback notification

Validation Strategy

Input Validation

  • All user inputs validated at service layer entry points
  • Zoom levels constrained to Firefox standard values
  • Navigation bounds checking prevents array index errors
  • URL validation for copy operations

Data Integrity

  • SQLite constraints enforce zoom level ranges
  • Database transactions for atomic state updates
  • Error handling for clipboard tool failures
  • Graceful degradation when tools unavailable

Performance Considerations

  • Zoom level persistence debounced to prevent excessive DB writes
  • Navigation history bounded to prevent memory growth
  • Database cleanup for old zoom preferences
  • Prepared statements for repeated queries

Error Handling

Domain Errors

  • Invalid zoom level → clamp to nearest valid value
  • Empty navigation history → silent no-op
  • Invalid clipboard tool → try next in fallback chain
  • Malformed URL → log error, return failure status

System Errors

  • Database unavailable → continue with in-memory state only
  • Clipboard tools unavailable → user notification, graceful degradation
  • WebView navigation failure → restore previous state
  • Event processing errors → log and continue

All data models maintain constitutional principles of simplicity and performance while providing robust user experience for browser control operations.

source
1# Data Model: Browser Controls UI
2
3## Entities
4
5### 1. ZoomLevel
6Represents domain-specific zoom preferences for persistent user experience.
7
8**Fields**:
9- `Domain` (string, primary key): Website domain (e.g., "github.com", "stackoverflow.com")
10- `ZoomFactor` (float64): Zoom multiplier (0.3 to 5.0 range, default 1.0)
11- `UpdatedAt` (time.Time): Timestamp of last zoom level change
12
13**Validation Rules**:
14- Domain must be valid hostname format
15- ZoomFactor must be within Firefox range: 0.30 ≤ zoom ≤ 5.00
16- ZoomFactor must match standard Firefox zoom levels (30%, 50%, 67%, 80%, 90%, 100%, 110%, 120%, 133%, 150%, 170%, 200%, 240%, 300%, 400%, 500%)
17- UpdatedAt automatically set on creation/update
18
19**Relationships**:
20- One-to-one with website domains
21- No foreign key relationships (standalone entity)
22
23### 2. BrowserState (Extended)
24Existing entity extended with zoom and navigation state management.
25
26**New Fields**:
27- `CurrentZoomLevel` (float64): Active zoom level for current page
28- `NavigationHistory` ([]HistoryEntry): Back/forward navigation stack
29- `HistoryIndex` (int): Current position in navigation history
30
31**State Transitions**:
32- Zoom In: CurrentZoomLevel → Next higher Firefox zoom level
33- Zoom Out: CurrentZoomLevel → Next lower Firefox zoom level  
34- Navigate Back: HistoryIndex decrements (if > 0)
35- Navigate Forward: HistoryIndex increments (if < len(NavigationHistory)-1)
36- URL Change: Update CurrentZoomLevel from ZoomLevel persistence
37
38**Validation Rules**:
39- CurrentZoomLevel follows same rules as ZoomLevel.ZoomFactor
40- HistoryIndex must be valid array index (0 ≤ index < len(NavigationHistory))
41- NavigationHistory maintained as bounded array (configurable max size)
42
43### 3. KeyboardEvent (Transient)
44Represents keyboard input events for processing.
45
46**Fields**:
47- `Key` (string): Key identifier ("=", "-", "c")
48- `Modifiers` ([]string): Active modifier keys (["ctrl"], ["ctrl", "shift"])
49- `Timestamp` (time.Time): Event occurrence time
50
51**Validation Rules**:
52- Key must be non-empty string
53- Modifiers must be valid modifier keys ("ctrl", "shift", "alt", "meta")
54- Timestamp must be recent (within reasonable event processing window)
55
56**State Transitions**:
57- Ctrl+Plus → ZoomIn action
58- Ctrl+Minus → ZoomOut action  
59- Ctrl+Shift+C → CopyURL action
60
61### 4. MouseEvent (Transient)
62Represents mouse button events for navigation.
63
64**Fields**:
65- `Button` (int): Mouse button identifier (3=back, 4=forward)
66- `EventType` (string): Event type ("mousedown", "mouseup")
67- `Timestamp` (time.Time): Event occurrence time
68
69**Validation Rules**:
70- Button must be 3 (back) or 4 (forward)
71- EventType must be valid mouse event type
72- Only "mousedown" events trigger navigation actions
73
74**State Transitions**:
75- Button 3 mousedown → NavigateBack action
76- Button 4 mousedown → NavigateForward action
77
78## Database Schema Changes
79
80### New Table: zoom_levels
81```sql
82CREATE TABLE zoom_levels (
83    domain TEXT PRIMARY KEY,
84    zoom_factor REAL NOT NULL DEFAULT 1.0 CHECK(zoom_factor >= 0.3 AND zoom_factor <= 5.0),
85    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
86);
87
88CREATE INDEX idx_zoom_levels_updated_at ON zoom_levels(updated_at);
89```
90
91### SQLC Queries
92```sql
93-- name: GetZoomLevel :one
94SELECT zoom_factor FROM zoom_levels WHERE domain = ?;
95
96-- name: SetZoomLevel :exec
97INSERT OR REPLACE INTO zoom_levels (domain, zoom_factor, updated_at)
98VALUES (?, ?, CURRENT_TIMESTAMP);
99
100-- name: CleanupOldZoomLevels :exec
101DELETE FROM zoom_levels WHERE updated_at < date('now', '-30 days');
102```
103
104## Data Flow
105
106### Zoom Operations
1071. User triggers zoom event → JavaScript captures keyboard event
1082. Frontend calls backend `ZoomIn()` or `ZoomOut()` method
1093. Backend calculates next valid Firefox zoom level
1104. Backend updates BrowserState.CurrentZoomLevel
1115. Backend persists to database via `SetZoomLevel`
1126. Frontend applies CSS zoom styling
1137. Optional: Visual feedback notification
114
115### Navigation Operations  
1161. User triggers mouse back/forward → JavaScript captures mouse event
1172. Frontend calls backend `NavigateBack()` or `NavigateForward()` method
1183. Backend validates navigation history bounds
1194. Backend updates BrowserState.HistoryIndex
1205. Backend returns target URL from history
1216. Frontend navigates WebView to target URL
122
123### URL Copy Operation
1241. User triggers Ctrl+Shift+C → JavaScript captures keyboard event
1252. Frontend calls backend `CopyCurrentURL()` method  
1263. Backend retrieves current URL from BrowserState
1274. Backend executes clipboard tool chain (wlcopy → xclip → xsel)
1285. Backend returns success/failure status
1296. Optional: Visual feedback notification
130
131## Validation Strategy
132
133### Input Validation
134- All user inputs validated at service layer entry points
135- Zoom levels constrained to Firefox standard values
136- Navigation bounds checking prevents array index errors
137- URL validation for copy operations
138
139### Data Integrity
140- SQLite constraints enforce zoom level ranges
141- Database transactions for atomic state updates
142- Error handling for clipboard tool failures
143- Graceful degradation when tools unavailable
144
145### Performance Considerations
146- Zoom level persistence debounced to prevent excessive DB writes
147- Navigation history bounded to prevent memory growth
148- Database cleanup for old zoom preferences
149- Prepared statements for repeated queries
150
151## Error Handling
152
153### Domain Errors
154- Invalid zoom level → clamp to nearest valid value
155- Empty navigation history → silent no-op
156- Invalid clipboard tool → try next in fallback chain
157- Malformed URL → log error, return failure status
158
159### System Errors
160- Database unavailable → continue with in-memory state only
161- Clipboard tools unavailable → user notification, graceful degradation
162- WebView navigation failure → restore previous state
163- Event processing errors → log and continue
164
165All data models maintain constitutional principles of simplicity and performance while providing robust user experience for browser control operations.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close