Skip to content

Commit 0c5dc4f

Browse files
jongioCopilot
andcommitted
docs: add issue detail for add-favorites-for-sessions-and-folders
Co-authored-by: Copilot <[email protected]>
1 parent d54af9f commit 0c5dc4f

1 file changed

Lines changed: 197 additions & 0 deletions

File tree

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Add Favorites for Sessions and Folders
2+
3+
## Summary
4+
5+
Add a favorites system that lets users star individual sessions and folder paths so they can quickly access frequently-used items. Favorited items display a ★ indicator and can be filtered with `F`. All group-header favorites resolve to folder paths as the canonical storage type.
6+
7+
## Description
8+
9+
Power users accumulate hundreds of Copilot sessions across many repositories and branches. Currently there's no way to pin or bookmark the items you care about most — you have to search, scroll, or remember pivot/filter combos every time.
10+
11+
A favorites feature would let users mark sessions and folders as favorites with a single keypress (`*`). Favorites persist across restarts and surface visually with a star indicator (★). Users can toggle favorites on and off, and filter to show only favorites.
12+
13+
This mirrors the existing **hidden sessions** pattern (`h`/`H` keys, `HiddenSessions` config field, `hiddenSet` map) but inverts the intent — instead of hiding items, it highlights them.
14+
15+
### Why It Matters
16+
17+
- **Speed**: Jump to your most important sessions without searching
18+
- **Context switching**: When working across multiple repos/branches, favorites act as a personal "pinned" workspace
19+
- **Discoverability**: With hundreds of sessions, visual markers reduce cognitive load
20+
21+
## Technical Details
22+
23+
### Architecture: Follow the Hidden Sessions Pattern
24+
25+
The hidden sessions feature is the closest analog and should serve as the implementation blueprint:
26+
27+
| Aspect | Hidden Sessions (existing) | Favorites (proposed) |
28+
|--------|---------------------------|---------------------|
29+
| Config field | `HiddenSessions []string` | `FavoriteSessions []string`, `FavoriteFolders []string` |
30+
| Runtime set | `hiddenSet map[string]struct{}` | `favoriteSessions map[string]struct{}`, `favoriteFolders map[string]struct{}` |
31+
| Toggle key | `h` (hide) | `*` (star/favorite) |
32+
| Show/filter key | `H` (toggle hidden visibility) | `F` (filter to favorites only) |
33+
| Visual indicator | Dimmed styling | `` prefix on item label |
34+
| Persistence | Config JSON | Config JSON |
35+
36+
### Keyboard Bindings
37+
38+
**Currently used keys** (must NOT collide):
39+
40+
| Key | Action |
41+
|-----|--------|
42+
| ``/`k`, ``/`j` | Navigate |
43+
| ``, `` | Collapse/expand folder |
44+
| `Enter` | Launch/toggle |
45+
| `Space` | Multi-select |
46+
| `q`, `Ctrl+C` | Quit |
47+
| `/` | Search |
48+
| `Esc` | Clear/back |
49+
| `f` | Filter panel |
50+
| `s` / `S` | Sort field / sort direction |
51+
| `Tab` / `Shift+Tab` | Pivot / reverse pivot |
52+
| `p` | Preview |
53+
| `r` | Reindex |
54+
| `?` | Help |
55+
| `,` | Config/settings |
56+
| `1`-`4` | Time range filters |
57+
| `h` / `H` | Hide / toggle hidden |
58+
| `w`, `t`, `e` | Launch window/tab/pane |
59+
| `PgUp` / `PgDn` | Preview scroll |
60+
| `n` | Jump next attention |
61+
| `!` | Filter attention |
62+
| `O` | Open all selected |
63+
| `a` / `d` | Select all / deselect all |
64+
| `o` | Conversation sort |
65+
66+
**Proposed new bindings:**
67+
68+
| Key | Action | Rationale |
69+
|-----|--------|-----------|
70+
| `*` | Toggle favorite on selected item | Universal "star" metaphor; unused; doesn't conflict with any existing binding |
71+
| `F` (Shift+F) | Toggle "favorites only" filter | Parallels `H` for hidden; uppercase `F` is free (`f` is filter panel) |
72+
73+
**Why `*`:** The asterisk is universally associated with starring/favoriting (Gmail, GitHub, file managers). It's a single keypress (Shift+8 on US layout), mnemonic, and not used by any existing binding. Alternative candidates (`+`, `#`) are less intuitive.
74+
75+
### Data Model Changes
76+
77+
#### `internal/config/config.go`
78+
79+
Add two new fields to the `Config` struct:
80+
81+
```go
82+
type Config struct {
83+
// ... existing fields ...
84+
FavoriteSessions []string `json:"favorite_sessions,omitempty"`
85+
FavoriteFolders []string `json:"favorite_folders,omitempty"`
86+
}
87+
```
88+
89+
- **FavoriteSessions**: Session IDs (same format as `HiddenSessions`)
90+
- **FavoriteFolders**: Folder/cwd paths — the canonical storage type for all group-level favorites
91+
92+
These are stored in the same `config.json` file and follow the same sanitization rules.
93+
94+
#### `internal/tui/components/sessionlist.go`
95+
96+
Add favorite tracking sets parallel to `hiddenSet`:
97+
98+
```go
99+
type SessionList struct {
100+
// ... existing fields ...
101+
favoriteSessions map[string]struct{}
102+
favoriteFolders map[string]struct{}
103+
favoritesOnly bool // filter mode: show only favorites
104+
}
105+
```
106+
107+
### Key Behaviors
108+
109+
#### Toggle Favorite (`*` key)
110+
111+
When pressed on a **session item** (any pivot mode):
112+
1. If session ID is in `favoriteSessions` → remove it (unfavorite)
113+
2. If session ID is NOT in `favoriteSessions` → add it (favorite)
114+
3. Save config immediately (same pattern as `handleHideSession()`)
115+
4. Rebuild visible items to update visual indicator
116+
117+
When pressed on a **folder group header** (folder pivot):
118+
1. Use the folder path directly as the key
119+
2. Toggle in `favoriteFolders` set
120+
3. Save and rebuild
121+
122+
When pressed on a **repo group header** (repo pivot):
123+
1. Collect all unique folder paths (cwds) from sessions within that repo group
124+
2. If **one folder** → toggle that folder path directly in `favoriteFolders`
125+
3. If **multiple folders** → show a sub-selection picker listing the folder paths; user picks which to favorite/unfavorite
126+
4. Save and rebuild
127+
128+
When pressed on a **branch group header** (branch pivot):
129+
1. Same resolution as repo: collect unique folder paths from sessions in that branch group
130+
2. If **one folder** → toggle directly
131+
3. If **multiple folders** → show sub-selection picker
132+
4. Save and rebuild
133+
134+
When pressed on a **date group header** (date pivot):
135+
→ No-op. Favoriting a date is not supported.
136+
137+
#### Filter Favorites (`F` key)
138+
139+
Toggle `favoritesOnly` mode:
140+
- **ON**: Only show items where the session is individually favorited OR the session's cwd matches a favorited folder
141+
- **OFF**: Show all items (default), favorites still visually marked
142+
- Visual indicator in the status bar when favorites filter is active (e.g., "★ Favorites")
143+
144+
#### Visual Rendering
145+
146+
- Favorited sessions: Prepend `` to the session title in the list
147+
- Favorited folder headers: Prepend `` to the folder label
148+
- Sessions whose cwd matches a favorited folder: Show `` even if not individually favorited (inherited from folder)
149+
- Use a distinct color for the star (e.g., yellow/gold from the theme's accent palette)
150+
- In repo/branch pivot modes: group headers show `` if ALL sessions in the group belong to favorited folders
151+
152+
#### Sort Integration
153+
154+
- When sorting, favorited items should optionally sort to the top (a boolean "favorites first" toggle, or simply respected when `F` filter is active)
155+
- Consider adding `favorites` as a sort field option (cycle with `s` key)
156+
157+
### Files to Modify
158+
159+
1. **`internal/config/config.go`** — Add `FavoriteSessions`, `FavoriteFolders` fields
160+
2. **`internal/tui/keys.go`** — Add `ToggleFavorite` (`*`) and `FilterFavorites` (`F`) key bindings
161+
3. **`internal/tui/components/sessionlist.go`** — Add favorite sets, filter logic, visual rendering, sub-selection picker for multi-folder resolution
162+
4. **`internal/tui/model.go`** — Add `handleToggleFavorite()` and `handleFilterFavorites()` in key handler, load favorites from config on init
163+
5. **`internal/tui/styles.go`** — Add star style (color for `` indicator)
164+
6. **`docs/KEYBOARD_BINDINGS.md`** — Document new keybindings (if this file exists)
165+
166+
### Edge Cases
167+
168+
- **Favoriting a session that gets deleted**: On next load, stale IDs in config are harmless (session just won't appear). Optionally prune stale favorites on reindex.
169+
- **Favoriting a folder path that changes**: Folder favorites are by exact path string. If a repo moves, the old favorite becomes inert. Acceptable tradeoff.
170+
- **Favoriting + hiding**: A session can be both favorited and hidden. Hidden takes precedence for visibility (unless `H` is toggled to show hidden). The star still renders on hidden-but-visible items.
171+
- **Multi-folder sub-selection picker**: When `*` is pressed on a repo/branch group header with multiple cwds, a small overlay lists the folders. User selects with arrow keys + Enter/Space. Pressing Esc cancels without changes.
172+
- **Empty favorites filter**: If `F` is toggled but no favorites exist, show an empty state message: "No favorites yet. Press * to favorite an item."
173+
- **Config migration**: Old configs without favorite fields deserialize cleanly due to `omitempty` — slices default to nil/empty.
174+
- **Date pivot**: `*` is a no-op on date group headers — no visual affordance or error, just ignored.
175+
176+
## Acceptance Criteria
177+
178+
- [ ] `*` key toggles favorite on the currently selected session (any pivot mode)
179+
- [ ] `*` key on a folder group header toggles favorite on that folder path
180+
- [ ] `*` key on a repo/branch group header resolves to folder path(s); if multiple, shows a sub-selection picker
181+
- [ ] `*` key on a date group header is a no-op
182+
- [ ] `F` key toggles a "favorites only" filter showing individually-favorited sessions and sessions whose cwd matches a favorited folder
183+
- [ ] Favorited items display a `` visual indicator in the list
184+
- [ ] Sessions inherit `` from favorited parent folder (without being individually favorited)
185+
- [ ] Favorites persist across application restarts via `config.json`
186+
- [ ] New key bindings (`*`, `F`) do not collide with any existing bindings
187+
- [ ] Favoriting + hiding coexist without conflict (hidden takes visibility precedence)
188+
- [ ] Help overlay (`?`) documents the new `*` and `F` keybindings
189+
- [ ] Status bar indicates when favorites filter is active
190+
- [ ] Empty favorites filter shows a helpful message
191+
192+
## Related
193+
194+
- **Existing pattern**: Hidden sessions (`h`/`H` keys, `HiddenSessions` config, `hiddenSet` map) — direct blueprint
195+
- **Files**: `internal/config/config.go`, `internal/tui/keys.go`, `internal/tui/model.go`, `internal/tui/components/sessionlist.go`
196+
- **Config location**: `%APPDATA%\dispatch\config.json` (Windows), `~/.config/dispatch/config.json` (Unix)
197+
- **Storage types**: Only two — `FavoriteSessions` (session IDs) and `FavoriteFolders` (cwd paths). All group-header favorites resolve to folder paths.

0 commit comments

Comments
 (0)