frame 0.1.5

A markdown task tracker with a terminal UI for humans and a CLI for agents
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
# TUI Reference

Launch the TUI by running `fr` with no arguments.

## Views

### Track View

The default view. Shows a single track's tasks as an indented tree with expand/collapse. Switch between tracks with `1`-`9` or `Tab`/`Shift+Tab`.

### Tracks View

Overview of all tracks grouped by state (active, shelved, archived) with task count statistics. Switch to it with `0` or `` ` ``.

### Board View

A kanban-style cross-track view showing tasks in three columns: Ready, In Progress, and Done. Switch to it with `K`.

**Columns:**
- **Ready**: Todo tasks that are not blocked and have all deps resolved
- **In Progress**: Active tasks
- **Done**: Tasks completed within the last N days (configured by `board_done_days`, default 7)

**CC/All mode:** By default the board shows only `#cc`-tagged tasks. Press `c` to toggle between CC mode and All mode. The mode is shown in the Ready column header and persists across sessions.

**Layout:** Three equal columns when width >= 80. Below 80 columns, the Done column is hidden. Below 50 columns, single-column mode shows only the focused column.

### Inbox View

Shows inbox items with numbered indices and tags. Switch to it with `i`.

### Recent View

Done tasks grouped by resolved date, with a tree structure for subtasks. Switch to it with `r`.

### Search View

Project-wide search results grouped by source (active tracks, inbox, archive). Open with `S` from any view. Supports cursor navigation, section jumping with `Alt+Up/Down`, and `Enter` to jump to a result in its original view. `Esc` returns to the search results; pressing `Esc` again restores the pre-search view.

### Detail View

Full view of a single task showing all fields as navigable regions: Title, Tags, Added, Deps, Spec, Refs, Note, Subtasks. Open with `Enter` on a task in Track view or Recent view. A breadcrumb trail always shows the origin (track prefix or "Recent") and any parent tasks when drilling into subtasks.

## Modes

| Mode | Description |
|------|-------------|
| Navigate | Normal browsing, keybindings dispatch actions |
| Search | Typing a search query (`/` to enter, `Enter` to execute, `Esc` to cancel) |
| Edit | Inline text editing (task titles, tags, fields) |
| Move | Reordering tasks/tracks with `j`/`k`, confirm with `Enter`, cancel with `Esc` |
| Triage | Moving inbox items to tracks (select track, then position) |
| Confirm | Yes/no prompt (e.g., delete inbox item, archive track) |
| Select | Multi-select mode for bulk operations on tasks |
| Command | Command palette fuzzy search (`>` to open) |

## Keybindings

### Global (All Views, Navigate Mode)

| Key | Action |
|-----|--------|
| `1`-`9` | Switch to track by number |
| `0`, `` ` `` | Switch to Tracks view |
| `K` | Switch to Board view |
| `i` | Switch to Inbox view |
| `r` | Switch to Recent view |
| `Tab` | Next view |
| `Shift+Tab` | Previous view |
| `QQ` | Quit (press `Q` twice) |
| `Ctrl+Q` | Quit immediately |
| `?` | Toggle help overlay |
| `/` | Enter search mode |
| `n` | Next search match |
| `N` | Previous search match |
| `>` | Open command palette |
| `T` | Open tag color editor |
| `P` | Open project picker |
| `J` | Jump to task by ID |
| `S` | Project-wide search (across all tracks, inbox, and archives) |
| `z`, `u`, `Ctrl+Z`, `Super+Z` | Undo |
| `Z`, `Ctrl+Y`, `Ctrl+Shift+Z`, `Super+Shift+Z` | Redo |

### Track View — Navigate Mode

**Cursor movement:**

| Key | Action |
|-----|--------|
| `j`, `Down` | Move cursor down |
| `k`, `Up` | Move cursor up |
| `g`, `Home` | Jump to top |
| `G`, `End` | Jump to bottom |
| `Alt+Up` | Jump to previous top-level task |
| `Alt+Down` | Jump to next top-level task |

**Expand/collapse:**

| Key | Action |
|-----|--------|
| `l`, `Right` | Expand task |
| `h`, `Left` | Collapse task / go to parent |

**State changes:**

| Key | Action |
|-----|--------|
| `Space` | Cycle state: todo -> active -> done -> todo |
| `o` | Set todo |
| `x` | Set done |
| `b` | Toggle blocked |
| `~` | Toggle parked |
| `c` | Toggle `#cc` tag |

**Task creation:**

| Key | Action |
|-----|--------|
| `a` | Add task at bottom of backlog |
| `=` | Append to end of group (top-level = bottom; subtask = end of siblings) |
| `-` | Insert after cursor (sibling at same level; type `-` again to outdent) |
| `p` | Add task at top of backlog |
| `A` | Add subtask under cursor |

**Insert behavior by cursor position:**

| Key | On top-level | On child | On sub-child |
|---|---|---|---|
| `a` | Append to end of backlog | ← same | ← same |
| `p` | Prepend to top of backlog | ← same | ← same |
| `-` | Insert top-level after current | Insert sibling after current | Insert sibling after current |
| `- -` | *(already top)* | Promote to top-level | Promote to child level |
| `- - -` | | *(already top)* | Promote to top-level |
| `=` | Same as `a` | Append to end of parent's children | Append to end of parent's children |
| `A` | Add child | Add sub-child | *(max depth)* |

**Editing & actions:**

| Key | Action |
|-----|--------|
| `e` | Edit task title |
| `t` | Edit task tags |
| `Enter` | Open detail view |
| `m` | Enter move mode |
| `M` | Cross-track move |
| `C` | Set/clear cc-focus |
| `D` | Open dependency popup |
| `.` | Repeat last action |

**Filtering (prefix key `f`):**

| Key | Action |
|-----|--------|
| `fa` | Filter: active tasks |
| `fo` | Filter: todo tasks |
| `fb` | Filter: blocked tasks |
| `fp` | Filter: parked tasks |
| `fr` | Filter: ready tasks (todo/active, all deps resolved) |
| `ft` | Filter by tag (opens tag autocomplete) |
| `f Space` | Clear state filter |
| `ff` | Clear all filters |

**Multi-select:**

| Key | Action |
|-----|--------|
| `v` | Toggle selection on current task |
| `V` | Range select (from anchor to cursor) |
| `Ctrl+A` | Select all visible tasks |

With selection active (Select mode):

| Key | Action |
|-----|--------|
| `Space` | Cycle state on all selected |
| `x` | Set selected to done |
| `o` | Set selected to todo |
| `b` | Toggle blocked on selected |
| `~` | Toggle parked on selected |
| `t` | Bulk edit tags (`+tag -tag` syntax) |
| `d` | Bulk edit deps (`+ID -ID` syntax) |
| `m` | Bulk move selected tasks |
| `M` | Bulk cross-track move |
| `N` | Clear selection |
| `Esc` | Clear selection, return to Navigate |

### Board View — Navigate Mode

| Key | Action |
|-----|--------|
| `h`, `Left` | Move to previous column |
| `l`, `Right` | Move to next column |
| `j`, `Down` | Move cursor down within column |
| `k`, `Up` | Move cursor up within column |
| `g`, `Home` | Jump to top of column |
| `G`, `End` | Jump to bottom of column |
| `Enter` | Open detail view for selected task |
| `Esc` | Back / close |
| `c` | Toggle CC/All mode |
| `Space` | Cycle task state |
| `o` | Set todo |
| `x` | Mark done |
| `b` | Toggle blocked |
| `~` | Toggle parked |
| `e` | Edit task title |
| `t` | Edit task tags |
| `M` | Cross-track move |
| `D` | Show dependency graph |
| `ft` | Filter by tag |
| `ff` | Clear all filters |
| `.` | Repeat last action |

### Tracks View — Navigate Mode

| Key | Action |
|-----|--------|
| `j`, `Down` | Move cursor down |
| `k`, `Up` | Move cursor up |
| `g`, `Home` | Jump to top |
| `G`, `End` | Jump to bottom |
| `Enter` | Open track in Track view |
| `a`, `=` | Add new track (bottom of active list) |
| `-` | Insert new track after cursor |
| `p` | Add new track (top of active list) |
| `e` | Edit track name |
| `s` | Toggle shelve/activate |
| `C` | Set cc-focus |
| `m` | Reorder track (enter move mode) |

### Inbox View — Navigate Mode

| Key | Action |
|-----|--------|
| `j`, `Down` | Move cursor down |
| `k`, `Up` | Move cursor up |
| `g`, `Home` | Jump to top |
| `G`, `End` | Jump to bottom |
| `a`, `=` | Add new inbox item (bottom) |
| `-` | Insert item after cursor |
| `p` | Add new inbox item (top) |
| `e` | Edit item title |
| `t` | Edit item tags |
| `n` | Edit item note, cursor at end (inline multi-line editor) |
| `N` | Edit item note, cursor at start (inline multi-line editor) |
| `x` | Delete item (with confirmation) |
| `m` | Reorder item (enter move mode) |
| `Enter` | Triage item to a track |

### Recent View — Navigate Mode

| Key | Action |
|-----|--------|
| `j`, `Down` | Move cursor down |
| `k`, `Up` | Move cursor up |
| `g`, `Home` | Jump to top |
| `G`, `End` | Jump to bottom |
| `Enter` | Open detail view |
| `l`, `Right` | Expand subtask tree |
| `h`, `Left` | Collapse subtask tree |
| `Space` | Reopen task (5s grace period, press again to cancel) |

### Search View — Navigate Mode

| Key | Action |
|-----|--------|
| `j`, `Down` | Move cursor down |
| `k`, `Up` | Move cursor up |
| `g` | Jump to top |
| `G` | Jump to bottom |
| `Alt+Up` | Jump to previous group |
| `Alt+Down` | Jump to next group |
| `n` | Next result |
| `N` | Previous result |
| `Enter` | Jump to task in its original view |
| `Esc` | Close search results and return to pre-search view |
| `S` | Start a new project search |

**Notes:**
- View search (`/`) is independent from project search (`S`). They do not interact.
- After jumping to a task with `Enter`, pressing `Esc` returns to the search results.
- View-switching keys (`1`-`9`, `Tab`, `i`, `r`, `0`) dismiss search results.
- Archive results are displayed dimmed; `Enter` on an archive result shows a status message.

### Detail View — Navigate Mode

**Region navigation:**

| Key | Action |
|-----|--------|
| `j`, `Down` | Next region / next subtask |
| `k`, `Up` | Previous region / previous subtask |
| `Tab` | Jump to next editable region |
| `Shift+Tab` | Jump to previous editable region |
| `g` | Jump to first region |
| `G` | Jump to last region |

**Editing:**

| Key | Action |
|-----|--------|
| `e`, `Enter` | Edit current region |
| `t` | Jump to Tags and edit |
| `@` | Jump to Refs and edit |
| `d` | Jump to Deps and edit |
| `n` | Jump to Note and edit, cursor at end |
| `N` | Jump to Note and edit, cursor at start |

**State changes (same as Track view):**

| Key | Action |
|-----|--------|
| `Space` | Cycle state |
| `o` | Set todo |
| `x` | Set done |
| `b` | Toggle blocked |
| `~` | Toggle parked |
| `c` | Toggle cc tag |
| `M` | Cross-track move |

**Other:**

| Key | Action |
|-----|--------|
| `w` | Toggle note wrap |
| `D` | Open dependency popup |
| `.` | Repeat last action |
| `Esc`, `Backspace` | Return to origin view (Track or Recent) |

### Edit Mode

| Key | Action |
|-----|--------|
| Characters | Insert text |
| `Left`, `Right` | Move cursor |
| `Alt+Left`, `Alt+Right` | Move by word |
| `Alt+b`, `Alt+f` | Move by word (readline) |
| `Home`, `Ctrl+A` | Jump to start of line |
| `Ctrl+E`, `End` | Jump to end of line |
| `Backspace` | Delete backward |
| `Alt+Backspace`, `Ctrl+Backspace` | Delete word backward |
| `Ctrl+U` | Kill to start of line |
| `Shift+Left/Right` | Extend selection |
| `Ctrl+C`, `Super+C` | Copy selection |
| `Ctrl+X`, `Super+X` | Cut selection |
| `Ctrl+V`, `Super+V` | Paste |
| `Ctrl+Z`, `Super+Z` | Inline undo |
| `Ctrl+Y`, `Ctrl+Shift+Z`, `Super+Shift+Z` | Inline redo |
| `Enter` | Confirm edit |
| `Esc` | Cancel edit |

**With autocomplete dropdown visible:**

| Key | Action |
|-----|--------|
| `Up`, `Down` | Navigate suggestions |
| `Tab` | Accept suggestion |
| `Enter` | Accept suggestion and confirm edit |
| `Esc` | Dismiss dropdown |

**Multi-line note editing (Detail view, Inbox view):**

| Key | Action |
|-----|--------|
| `Enter` | Insert newline |
| `Tab` | Insert 4 spaces |
| `Up`, `Down` | Move between lines |
| `Alt+Up`, `Alt+Down` | Jump between paragraphs |
| `Alt+w` | Toggle note wrap |
| `Cmd+J`, `Ctrl+J` | Join current line with next (vim-style) |
| `Esc` | Save and exit edit |

### Move Mode

| Key | Action |
|-----|--------|
| `j`, `Down` | Move item down (same depth, crosses parent boundaries) |
| `k`, `Up` | Move item up (same depth, crosses parent boundaries) |
| `h`, `Left` | Outdent: promote to parent's level |
| `l`, `Right` | Indent: make child of sibling above |
| `g`, `Home` | Move to top |
| `G`, `End` | Move to bottom |
| `Enter` | Confirm position (re-keys IDs if depth/parent changed) |
| `Esc` | Cancel and restore |

### Search Mode

| Key | Action |
|-----|--------|
| Characters | Type search query (regex) |
| `Enter` | Execute search |
| `Esc` | Cancel search |
| `Up` | Previous search history |
| `Down` | Next search history |

After confirming a search with `Enter`, clear the active search with `Esc` in most views. In Detail view, use `Backspace` instead (since `Esc` navigates back).

### Triage Mode

**Step 1 — Select track:**

| Key | Action |
|-----|--------|
| Characters | Filter track list |
| `Up`, `Down` | Navigate tracks |
| `Enter` | Select track |
| `Esc` | Cancel triage |

**Step 2 — Select position:**

| Key | Action |
|-----|--------|
| `t` | Insert at top |
| `b`, `Enter` | Insert at bottom |
| `Up`, `Down` | Navigate options |
| `Esc` | Cancel |

### Confirm Mode

| Key | Action |
|-----|--------|
| `y` | Confirm action |
| `n`, `Esc` | Cancel |

### Command Palette

| Key | Action |
|-----|--------|
| Characters | Filter actions |
| `Up`, `Down` | Navigate actions |
| `Enter` | Execute selected action |
| `Backspace` | Delete filter char (or close if empty) |
| `Esc` | Close palette |

Actions are context-sensitive — the available set depends on the current view (Track, Detail, Tracks, Inbox, Recent). Uses fuzzy matching: type any part of an action name to filter. Each action shows its keyboard shortcut, making the palette useful for discovering keybindings.

Some actions are **palette-only** (no direct key binding):

| Action | View | Description |
|--------|------|-------------|
| Mark done (#wontdo) | Track | Add `#wontdo` tag and mark task done |
| Mark done (#duplicate) | Track | Add `#duplicate` tag and mark task done |
| Collapse all | Track | Collapse all expanded tasks |
| Expand all | Track | Expand all tasks with children |
| Delete task | Track, Detail, Recent | Permanently delete a task (supports bulk with multi-select) |
| Import tasks | Track | Import tasks from a markdown file into the current track |
| Archive track | Tracks | Archive a non-empty track |
| Delete track | Tracks | Delete an empty track |
| Unarchive track | Tracks | Restore an archived track to active |
| Rename track prefix | Tracks | Rename a track's ID prefix |
| Check project | Global | Run project integrity check and display results |
| Preview clean | Global | Preview what `fr clean` would do |
| Prune recovery | Global | Remove old entries from the recovery log |
| View recovery log | Global | Open recovery log overlay showing recent entries |

## Overlays

### Help Overlay (`?`)

Context-sensitive keybinding reference. Scrollable with `j`/`k`, `g`/`G` to jump. Close with `?` or `Esc`.

### Recovery Log Overlay

Shows the most recent recovery log entries. Open from the command palette ("View recovery log").

- `j`/`k` or `Up`/`Down` — scroll
- `Alt+Up`/`Alt+Down` — jump to previous/next log entry
- `g`/`G` — jump to top/bottom
- `PageUp`/`PageDown` — scroll by page
- `Esc` or `q` — close

### Results Overlay

Displays structured results from "Check project" and "Preview clean" palette actions. Open from the command palette.

- `j`/`k` or `Up`/`Down` — scroll
- `g`/`G` — jump to top/bottom
- `PageUp`/`PageDown` — scroll by page
- `Esc` — close

### Tag Color Editor (`T`)

Popup for assigning colors to tags from a 10-swatch palette.

- `j`/`k` — navigate tags
- `Enter` — open color picker
- `Backspace` — clear tag color
- `Esc` — close

In the color picker:
- `h`/`l` — navigate swatches
- `Enter` — assign color
- `Backspace` — clear color
- `Esc` — close picker

### Dependency Popup (`D`)

Shows upstream (blocked by) and downstream (blocking) dependencies in an expandable tree.

- `j`/`k` — navigate entries
- `h`/`l` — collapse/expand
- `g`/`G` — jump to first/last
- `Enter` — jump to task (cross-track)
- `Esc` — close

The popup has two sections: **Blocked by** (tasks this task depends on) and **Blocking** (tasks that depend on this task). When a section has 1-2 entries, they are auto-expanded one level. With 3+ entries, they start collapsed. Empty sections show "(nothing)".

Circular dependencies marked with `↻`. Missing deps shown as `[?]`.

### Project Picker (`P`)

Switch between registered frame projects without leaving the TUI. If `fr` is launched outside any project, the picker opens automatically.

- `j`/`k` — navigate project list
- `Enter` — switch to selected project
- `s` — toggle sort (recent vs. alphabetical)
- `X` — remove project from registry (press twice to confirm)
- `Esc` — close

Projects are listed with their name and abbreviated path. The current project is highlighted. Missing projects (directory no longer exists) are shown dimmed with "(not found)".

### Prefix Rename (via Command Palette)

3-step flow for renaming a track's ID prefix (e.g., `EFF` to `FX`):

1. **Edit**: Inline editor opens pre-filled with the current prefix, text selected. Type the new prefix (auto-uppercased). Live validation shows errors for empty, non-alphanumeric, or duplicate prefixes. `Enter` to proceed, `Esc` to cancel.
2. **Confirm**: Popup shows old/new prefix, blast radius (task ID count, dep references across tracks), and a warning that the operation cannot be undone. `Enter` to confirm, `Esc` to go back to editing.
3. **Execute**: Renames all task IDs and subtask IDs in the track, updates dep references across all other tracks, renames IDs in the archive file, and updates `project.toml`. Inserts an undo sync marker (no undo — use git to revert).

### Conflict Popup

Appears when an external file change conflicts with an in-progress edit. Shows the orphaned text. `Esc` to dismiss.

## Features

### Autocomplete

Activates automatically during editing:

- **Tag editing** — suggests tags from config `tag_colors`, `ui.default_tags`, and all existing tags
- **Dep editing** — suggests task IDs from all tracks
- **Spec/Ref editing** — suggests file paths from the project (up to 3 levels deep, filtered by `ref_extensions` and `ref_paths` config)

The dropdown appears immediately when entering edit mode on an eligible field — no keypress is needed to trigger it. It also activates during inline tag editing (`t` in Track view), filter tag selection (`ft`), and jump-to-task (`J`).

Filtering is case-insensitive substring matching. Word extraction depends on the field: tag autocomplete matches the word after the last space; dep autocomplete matches after the last comma or space; file path autocomplete matches after the last space.

`Tab` accepts the selected suggestion and stays in edit mode. `Enter` accepts and confirms the edit. `Esc` dismisses the dropdown but stays in edit mode.

### Undo/Redo

Full undo/redo stack for all TUI mutations: state changes, title edits, task creation, moves, field edits, inbox operations, track management, and section moves.

- `z`, `u`, or `Ctrl+Z` — undo
- `Z`, `Ctrl+Y`, or `Ctrl+Shift+Z` — redo

Undo navigates to the affected item — switching views and tracks if needed — and briefly highlights it.

External file changes insert a sync marker that blocks undo across the boundary. The undo stack starts empty on each launch, so there is nothing to undo from a previous session. When a sync marker is inserted, the redo stack is cleared permanently.

Inline edit undo (`Ctrl+Z`/`Ctrl+Y` in Edit mode) operates within the current editing session separately from the main undo stack.

### File Watching

The TUI watches `frame/` for `.md` and `.toml` changes. Self-writes are detected and ignored. External changes trigger a reload; if an edit is in progress, the reload is queued until the edit completes.

Reload is deferred during both Edit and Move modes, applied when the mode exits. After reload, if `auto_clean` is enabled (default: true), frame automatically assigns missing IDs/dates and archives excess done tasks. This can cause visible changes to the file that weren't made by the user. Each reload inserts an undo sync marker, which clears the redo stack.

### Filtering

Track view filtering via the `f` prefix key:

- `fa` active, `fo` todo, `fb` blocked, `fp` parked, `fr` ready
- `ft` filter by tag (with autocomplete)
- `f Space` clear state filter, `ff` clear all

State and tag filters are independent — you can have both active simultaneously. Both must match (AND logic). `f Space` clears only the state filter (tag stays). `ff` clears both.

The filter applies globally across all tracks, not per-track. Switching tracks keeps the same filter active. Filters are session-only — not persisted to `.state.json`, cleared on restart.

"Ready" means: state is todo or active, AND all dependency tasks are done.

When a filter removes the task under the cursor, the cursor moves to the nearest matching task. Ancestor context rows appear when a nested task matches but its parent doesn't — the parent is shown dimmed to preserve tree context. Context rows are skipped during cursor navigation. When no tasks match, the track shows "no matching tasks".

The active filter indicator appears right-aligned in the tab separator (e.g., "filter: ready #bug"). Filters have no undo — they are view-only, not mutations.

Project search (`S`) ignores view filters — it always searches all tasks regardless of any active state or tag filter.

### Multi-Select

`v` toggles individual task selection, `V` range-selects, `Ctrl+A` selects all. With tasks selected, bulk operations apply to all selected: state changes, tag/dep edits, move, cross-track move.

First `v` press enters Select mode and toggles the current task. Subsequent `v` presses toggle without mode change. `V` sets an anchor at the current position; moving the cursor and pressing `V` again selects all tasks in the range. Context rows (from filtering) and section separators are excluded from selection.

Selection persists when opening Detail view (`Enter`) and returning (`Esc`). Selection is cleared when switching to a different view (Inbox, Recent, Tracks). Multi-select is only available in Track view. If the last selected task is deselected via `v`, the mode returns to Navigate automatically.

### Jump to Task (`J`)

Opens an ID search prompt with autocomplete showing all task IDs and titles. Enter jumps to the matching task, switching tracks if needed.

### Repeat Action (`.`)

Repeats the last repeatable action (state change, tag toggle, etc.) on the current task.

### Grace Period Moves

When a task is marked done or parked in the TUI, it stays in Backlog for 5 seconds before moving to its target section (Done or Parked). During this period, undo cancels the move. Un-parking a task in the Parked section and reopening a task in the Recent view (`Space`) have a similar grace period in reverse (task moves back to Backlog).

The 5-second timer only counts down in Navigate mode. Entering Search, Edit, or Move mode pauses it. Switching views (e.g., Track to Inbox) or quitting immediately flushes all pending moves — tasks move to their target section without waiting.

The entire subtask tree moves as a unit. Subtasks cannot be moved between sections independently — only top-level tasks trigger section moves.

### Clipboard

In Edit mode: `Ctrl+C`/`Super+C` copies, `Ctrl+X`/`Super+X` cuts, `Ctrl+V`/`Super+V` pastes. Text selection via `Shift+arrows`.

## Keyboard Protocol

Frame uses the Kitty keyboard protocol by default for unambiguous key event reporting. This matters most for modified keys like `Ctrl+Shift+Z` (redo) and distinguishing `Tab` from `Ctrl+I`. If your terminal doesn't support it, frame falls back gracefully — most keybindings still work, but a few modified-key combos may not register. Set `kitty_keyboard = false` in `project.toml` if you see input issues.

## Configuration

UI-relevant settings in `project.toml`:

```toml
[ui]
kitty_keyboard = true      # enhanced keyboard protocol (disable if terminal has issues)
note_wrap = true           # soft word wrap for note editing (toggle with w / Alt+w)
board_done_days = 7        # days of done tasks to show on board (0 = hide done column)
ref_extensions = ["md"]    # file types for ref/spec autocomplete
ref_paths = ["doc"]        # directories for ref/spec autocomplete

[ui.tag_colors]
bug = "#FF4444"
design = "#44DDFF"

[ui.colors]
# state/UI color overrides
```

The TUI persists cursor positions, scroll offsets, expanded task state, and note wrap preference in `frame/.state.json` (auto-saved, not meant for manual editing).