Tasks (markdown outliner, in development) (part 7)
Press / (or Ctrl/Cmd+F), or click the header's Find button (π), and a slim find bar opens under the header. Type, and the list filters live β in the giant All-Projects view and in a single project alike. Matches (and their parent tasks, so you can see where they live) stay visible; everything else drops away; the matched letters are highlighted in each row.
What it is
This is part 7 of the Tasks (markdown outliner, in development) page. It carries the next stretch of the material on that page, moved here because a single page is capped at 40,000 characters.
Where to find it
Reach this part through Tasks (markdown outliner, in development) β it lists every part and explains where the feature lives in the product. Everything below is reached from the same place.
How it behaves
Everything below is the behaviour, detail and edge cases that belong to this stretch of the Tasks (markdown outliner, in development) page.
Find tasks β / or Ctrl+F
Press / (or Ctrl/Cmd+F), or click the header's Find button (π), and a slim find bar opens under the header. Type, and the list filters live β in the giant All-Projects view and in a single project alike. Matches (and their parent tasks, so you can see where they live) stay visible; everything else drops away; the matched letters are highlighted in each row. It searches task text and #tags, ignores case and accents ("cafe" finds "CafΓ©"), and shows a live "N found" count. Snoozed tasks are findable too β a snoozed match surfaces in its Snoozed section instead of staying invisible until it wakes. Collapsed projects and folded sub-items open up for a match while the search is active (your folds come back when it closes).
Press Enter to jump the keyboard onto the results (arrow through them like any list), Esc to close. Closing always clears the query β a hidden search can never keep quietly filtering your list. It's a view overlay: searching never changes your saved order (drag-reorder pauses while it's active). The keys are rebindable (Settings β Keyboard Shortcuts β Tasks β "Find tasks").
Select many & act once β Ctrl+A + the bulk bar
Build a selection any way you like. Ctrl/Cmd+A selects every visible task (in the giant view: across all open projects). Or use the mouse: Ctrl/Cmd+click a task to add or remove just that one, and Shift+click to grab everything between the last-clicked task and this one β exactly like a file manager. (The keyboard Shift+β/β still extends a selection row by row.) A plain click goes back to a single highlighted task and drops the group. The moment 2 or more tasks are selected, a bulk action bar appears under the header with a live "N selected" pill and one-tap actions.
Ctrl/Cmd+click and Shift+click work on the checkbox too, not just the row text β the checkbox used to be the one control on the row that couldn't select, which is why multi-select was easy to miss.
Prefer email-style checkboxes? Turn on Checkbox selects (Customize, or Settings) and a plain box click selects the task instead of finishing it, so a single stray click can never clear something. The action bar then appears at one checked task rather than two, Done and Dropped move to the bar and the row's hover buttons, and clicking another task's text no longer wipes what you've checked (clear with Esc or the bar's β). It's off by default; nothing changes until you turn it on.
Tired of the "are you sure?" step? Turn on Finish without asking (Customize, or Settings β "Finish tasks without asking") and the bulk Finish / Drop archive on the spot instead of opening a confirm. It covers all three places that ask β the bulk bar, the right-click-a-selection menu, and a project header's Finish all β at any selection size, one task or forty (deliberately no count threshold: a size-gated prompt reintroduces exactly the surprise the setting exists to remove). The safety net is unchanged: every bulk archive still fires its Undo toast and its Ctrl/Cmd+Z entry, and the tasks land in Archived rather than being deleted. Delete is never covered β a bulk delete has no archive-ledger undo, so Delete all and the selection menu's Delete confirm no matter how this is set. It's off by default (tasksV2SkipFinishConfirm). Note that a single-task finish never confirmed in the first place; this only bites once a selection exists, which is why it shows up most with Checkbox selects on β there one checked row already counts as a selection and routes a single finish through the bulk confirm. Invariant skip-finish-confirm in the contract.
| Action | What it does |
|---|---|
| Snooze | one time picker β every selected task snoozes to it |
| Due | one date β set on every selected task |
| Priority | one level β set on every selected task |
| Move | pick a project β every selected task moves there (sub-items travel with their parents) |
| Finish | done + archived, the whole selection at once |
| Drop | archived without being marked done β "I'm not doing these" (the honest exit) |
| β | clear the selection (Esc does too) |
Selections are smart about nesting: if you selected a task and its sub-item, moving or finishing acts on the parent once β the sub-item rides along; it's never moved or finished twice. Every bulk action is one Ctrl/Cmd+Z to undo. (While you're typing in a row, Ctrl+A stays the normal select-all-text.)
The move keys (Shift+W/Shift+S, Alt+Shift+β/β) and the β― Move up / Move down rows also act on a multi-selection: they move the whole selected block up / down as one unit that stays together (order preserved), so you can nudge several tasks at once. When the block sits at one level it just shifts within that level; when your selection spans a grouped item (a sub-item plus the row below its group), it still moves together β a sub-item pulled above its group becomes a top-level task so nothing is left behind, and the block never crosses into another project. A block already at the top / bottom stays put, and one move is one Ctrl/Cmd+Z.
Every keyboard row action acts on the whole selection β not just move. With 2+ tasks selected, Tab/Shift+Tab (or Alt+Shift+β/β, Shift+A/Shift+D) indent/outdent the whole selected block together, finishing (x / e / Delete) finishes every selected task in one undoable batch, and Ctrl/Cmd+D duplicates each selected task β so the keyboard matches the bulk bar and the right-click menu. This holds in all three surfaces (the giant "All Projects" view, a single project, and Today). A single highlighted row (nothing multi-selected) still acts on just that one row.
Right-click the group for everything else. The bar covers the common actions; for the full set, right-click any task in your selection and you get the same menu you'd get on a single task β but every action runs across the whole group: Finish Β· Delete (asks first) Β· Snooze Β· Due Β· Priority Β· Move to project Β· Star / Bold / Highlight Β· Copy Β· Cut. (Right-clicking a task that isn't in the selection drops the group and acts on just that one, so you can't fire a bulk action at the wrong rows by accident.) Cut the group and Paste it below any task β or onto a project heading β to move the whole set at once, across projects included; Copy the group and paste to duplicate it instead (the originals stay). And Launch agent on a group opens a small launch popup β the task count, a repo picker (default the hidden Tasks workspace, or one of your real repos), and an explicit Launch button (the cost gate a batch launch previously lacked; Ctrl/Cmd+Enter also launches) β then starts one session seeded with all the selected tasks as context (never one session per task), capped at 25 so a giant selection can't run up a huge first prompt.
Repeating tasks β "every monday"
A task can repeat: daily, every weekday, weekly on chosen days, monthly, yearly, or every N days. Set it two ways:
- Type it β quick capture and the
:command line understand "water plants every monday", "standup daily", "sync every 2 weeks", "pay rent monthly". - Pick it β the task's details pane has a Repeat picker.
A repeating task shows a π marker on its row (hover it for the schedule, e.g. "Weekly on Mon"). Finishing the task creates the next occurrence in place β same text, project, priority and tags, with the due date advanced to the next time on the schedule. The finish toast tells you when the next one is due, and its Undo removes the new copy and restores the finished one, in one step.
The date math is built for real life: finishing late never creates a backlog (a "daily" you finish after a long weekend spawns one task due tomorrow β not three overdue ones), monthly repeats clamp to month-end without losing your day (Jan 31 β Feb 28 β Mar 31), and daylight-saving transitions keep the task's local time. Sub-items don't copy to the next occurrence (the repeat is the task itself). Agents can set a schedule too, through the task's metadata over the CLI, and the tasks-v2.md mirror shows it as repeat=β¦ so a reading agent sees the schedule.
The giant default view β all your tasks in one list
The view you land on is one giant list that folds every project's tasks into a single screen, grouped under each project's heading (projects in their rail order; each heading shows the project's icon β or its color dot when no icon is set and a color is chosen (no color β nothing) β and its open count rendered as part of the title (parenthesised and the same size as the project name β e.g. Business (6) / Inbox (1,234) β not a smaller, greyer number tacked on the end; under an active importance/tag filter that hides rows it reads an honest "n of m", e.g. 0 of 6, so it never claims more than the group shows), plus a "+" to add a task to that project and a β― to customize it (rename / color / icon / delete), the same menu the rail uses). You scan everything you're tracking in one place instead of clicking project by project. It is the default β the old one-list-at-a-time screen is now reached by filtering to a single project (via the header Show βΎ control or the rail).
- Projects are collapsible. Each project heading is a chevron toggle β fold a project down to just its header (its tasks tuck away) and unfold it again. What's folded is remembered (a
tasksV2CollapsedProjectIdssetting); it's purely a view preference and never changes your tasks. - Fully editable in place β rows behave exactly like the per-project view. A single click/tap HIGHLIGHTS a row (it selects it; it does not pop the details editor); the details pane opens from the focused row's Task-details button (double-click renames). The focused row carries the full action cluster β Task details, Launch agent, and the β― menu (Add subtask, Copy, Context, Break it down, Move to project, Move up / Move down scoped to that project; the keyboard reorder Alt+Shift+β/β does the same but additionally hops the task into the neighboring project at a project's top/bottom edge β a keyboard-only reach the menu deliberately doesn't have). Check off, rename, edit details (due, snooze, importance, tags), and add a task (each project heading has its own "+") β all without leaving the giant view. Every edit lands on the task's real project automatically.
- Make a new project without leaving this view. A "+ New project" box is pinned at the bottom of the All Projects view β click it, type a name, press Enter, and the project is created right here (Escape or a blank name cancels). Unlike the project rail's "New project" (which switches you INTO the new project β see Projects & master context), this one keeps you on the All Projects view and drops your cursor straight into a first task in the new project, so you start typing immediately β and because that first task exists, a brand-new project shows up right away even from the empty first-run screen. Locked by the contract's
master-new-projectinvariant (TaskV2MasterView.test.tsx). - Fully keyboard-driven, exactly like the single-project view. The giant view shares the same command-mode keyboard as the per-project outliner β one implementation (
useTaskV2CommandKeys), so the two can never drift. Arrows /w-s/j-kmove the highlight from row to row across project groups (skipping any that are collapsed); Alt+Shift+β/β moves the focused task up/down β and at a project's top/bottom edge carries it into the neighboring project; Space edits and Enter adds a new task below, Esc stops; and every command key acts on the focused row (hsnooze Β·ddeadline Β·x/efinish Β·ppriority Β·c/icontext Β·:command line Β·gagent Β·bbreak-it-down Β·?cheat-sheet Β· Ctrl/Cmd+D duplicate Β· Ctrl/Cmd+Delete archive). Tab/Shift+Tab indent/outdent the focused row within its own project β so you can build a full outline while entering tasks right here in the default view, without first filtering to one project. Indent nests a row under the task above it in the same project (it can never reparent a task into a different project), and it works while you're still typing the row. Only Backspace-merge and drill-in/out remain no-ops in the merged view β a cross-project text merge has no well-defined target, and there's no breadcrumb to drill into; for those, filter to one project. (Before this landed the giant view had no keyboard at all: the hotkeys only worked once you filtered down to a single project β see the contract's invariant 54.) - Select the project NAME itself, and act on the whole project. Up/down nav also stops on each project header (even a collapsed one) β so you can act on a whole project, not just a task. With a project selected, the same keys fan out to every task in it:
x/efinish all Β·hsnooze all Β·dset-deadline-all Β·pset-priority-all Β· Ctrl/Cmd+Delete delete all (asks first). Space folds/unfolds it; Enter (or right-click / the β― button) opens the project actions menu. The project header also carries inline quick-action icons β Launch agent, Snooze all, and Set priority β beside its "+" and β― (hover-revealed on desktop, always shown on mobile), mirroring the per-task row icons so the most-reached project actions are one click without opening a menu; each reuses the project action the menu already offers, they're hidden on the synthetic (Unfiled) bucket, and Snooze/Priority disable on an empty project (MasterViewRows.tsx). Each bulk action is a single Ctrl/Cmd+Z. See Select a project & act on the whole thing. - A task can't be left blank. Clear a task's text and click away and it's removed (a task with no sub-items); a parent that still has sub-items is kept so its subtree is never lost. And if a blank row is ever left behind another way β a new row abandoned before that click-away cleanup ran, or a blank parent whose last sub-item was later removed β it's now swept up automatically once the list settles, so nothing empty is ever left sitting in your tasks (the one row you're actively typing into is never swept). In the brief moment before the sweep, a blank row shows a muted "Empty task" placeholder rather than an invisible, un-clickable ghost β so you can always click it to highlight it and remove it by hand too (Ctrl/Cmd+Delete / β― β Finish).
- Filter down to one project β pick it in the rail or the header Show βΎ control β to get that project's per-project outliner. "All Projects" returns you to the giant view.
- Drag a task anywhere β including into another project. Long-press (hold) a row to grab it, then drop it above/below any task (same project = a precise reorder; another project = the task moves there, sub-items riding along) or onto a project's heading to file it at the top of that project β an empty project's heading works too. One drop = one move = one Ctrl/Cmd+Z. (Dragging pauses while a search/sort/filter overlay is active β what you see then isn't the saved order.)
- Empty projects show their (collapsible) heading too β a project with no tasks is no longer hidden in the giant view, so you can see it and move a task INTO it: cut a task, then either land the cursor on its heading and press Ctrl/Cmd+V, or simply click its heading (the mouse / phone way β see Cut & paste a task); you can also drag a task onto it. A task with no known project appears under Inbox (or an
(Unfiled)heading) so nothing is hidden. (When every project is empty β a brand-new install β you get the friendly "Add your first taskβ¦" box instead, filing into Inbox.) - Move a task between projects with the keyboard. Cut/paste (
Ctrl/Cmd+XthenCtrl/Cmd+V) works right here: cut a task, move the cursor onto another project β even an empty one's heading β and paste to move it there (a cross-project move; within-project reordering staysAlt+Shift+β/βor the filtered outliner). Or pressVon a task to open a "move to project" picker and choose the destination. Both are rebindable (Settings β Keyboard Shortcuts β Tasks) and on the β― / right-click menu for mouse + mobile.
This reuses the data the app already loads, so it adds no new database tables, server routes, or storage β only view-state settings (the collapse lists). The giant view now renders virtualized β only the rows on screen are drawn β so it stays smooth even with thousands of tasks (the soft/hard scale warnings remain as an honest heads-up for extreme lists, since some bookkeeping still grows with the tree). Sort & filter work here too (the header funnel applies within each project group), and cross-project drag is built (see the drag bullet above). Two-way file sync β hand-edit a JSON file and sync it back β stays the deferred someday-luxury.
Select a project & act on the whole thing
In the giant view the up/down keyboard nav doesn't only step between tasks β it also stops on each project NAME (header), even one that's collapsed. A selected project gets the same accent highlight a focused task does (and scrolls into view), so "the project itself is selected" reads at a glance. This is the giant view only; in a single-project view the name lives in the top bar, and the left project rail already opens its menu via right-click / long-press / Shift+F10.
With a project selected, the command keys fan out to the WHOLE project. They reuse the exact keys (and your custom rebindings) you use on a task β only the target is now every task in the project:
| Key | What it does to the whole project |
|---|---|
x / e |
Finish all β done + archived (a one-click "Undo" toast; reversible) |
h |
Snooze all β pick one time, every task is snoozed to it |
d |
Set deadline on all β pick one date |
p |
Set priority on all β pick one level |
Ctrl/Cmd+Delete |
Delete all the project's tasks β asks for confirmation first |
Space |
Fold / unfold the project |
Enter (also right-click / Shift+F10 / the β― button) |
open the project actions menu |
w/s Β· j/k Β· arrows |
keep moving the cursor (now across headers + tasks) |
Task-only keys (launch agent g, break-it-down b, context c/i, reorder, indent, duplicate, the : command line) do nothing on a project header.
Every bulk action is a single Undo. Finish/snooze/deadline/priority/delete/move/emphasis (star/bold/highlight all) on a whole project is one Ctrl/Cmd+Z (not one press per task), and a bulk action that can't fully apply rolls back cleanly with a plain-English error. Destructive ones are guarded: Delete all confirms first β always β and Finish all confirms too unless you have turned on Finish without asking (tasksV2SkipFinishConfirm), which skips that one prompt and leans on the one-click Undo instead; Delete all is never skippable. Finish, delete, and move empty the project, so the cursor jumps to the next project rather than getting stranded. The whole-project keys (and the bulk apply) read the project's tasks from the data, so they cover a collapsed project's hidden tasks too.
The project actions menu (opened by Enter / right-click / Shift+F10, or the header β― button) gathers it all in one place β and now offers the same organizing actions a single task's menu does, applied to the whole project. It carries: Add task; Launch agentβ¦ (starts one agent for the whole project with all its tasks folded in as context, via the same session-type picker a task launch gives β see Per-task agent chat); fold/unfold; Star all / Bold all / Highlight all (+ clear) and Copy all (the project's tasks as an indented markdown list); the lifecycle bulk actions (Finish all Β· Snooze all Β· Set deadlineβ¦ Β· Set priorityβ¦ Β· Move all to projectβ¦ Β· Delete all); Move project up / down (reorder it among your projects); and two project-level rows β Rename, color & iconβ¦ (opens the existing rename/color/icon menu β nothing reinvented) and a direct Delete projectβ¦ (removes the WHOLE project and its tasks through the same confirm dialog β a one-click alternative to reaching delete two menus deep via "Rename, color & iconβ¦"; disabled when it's your last project, and β unlike the task-bulk rows β available even on an empty project). The Star / Bold labels read the project's current state (all-set β "Unstar all" / "Unbold all"). Delete projectβ¦ is distinct from Delete all, which empties a project but keeps it (Ctrl/Cmd+Z-undoable); deleting the project soft-deletes it and cascades its tasks β also Ctrl/Cmd+Z-undoable (restores the project and the tasks that cascade deleted with it). The master view refetches so they disappear, rather than re-bucketing into "(Unfiled)". The emphasis + copy + reorder rows are menu-only β there's no keyboard shortcut for them on a header (the g/b keys stay task-only); Launch agent, Snooze all, and Set priority now also appear as inline icons on the project header (Snooze/Priority reuse the header's h/p fan-out keys so their tooltip shows the key-cap; Launch has no whole-project key by design). The synthetic (Unfiled) group hides the rows that need a real project (Add task, Launch agent, Move project up/down, Rename, Delete project); "Move all to projectβ¦" hides when there's only one project, and Move project up/down disable at the ends. Implementation + invariants live in the contract (giant-view-project-parity + giant-view-project-focus in .claude/memory/contracts/tasks-v2-contract.md); the menu is TaskV2ProjectActionsMenu.tsx, the batch store actions (archiveMany / deleteMany / updateMany / moveManyToList / setEmphasisMany) are in tasks-v2-store.ts, the whole-project launch reuses TaskV2LaunchPromptModal in list mode via launchListAgent (buildListInterviewPrompt; see the session-types contract), and the keyboard fan-out is the focus-target-aware useTaskV2CommandKeys.
Send top tasks to the inbox
The header's β― More β Send to inbox drops your few highest-value open tasks into the Omniscio inbox as dismissible reminder rows β so important work resurfaces where you triage everything else, without opening Tasks. It's on demand (a manual click β there's no background service, schedule, or setting), free (the same local ranking that powers "Right now" β no AI, no tokens), and re-sending coalesces by task (one row per task, never a duplicate pile-up); completing or snoozing a task drops it from the next send. It's handled by tasks-v2:drip-now (gated, IPC-only) reusing the shared inbox-alert primitive, so it adds no new storage β the rows land in the Alerts bucket alongside other agent alerts.
Trickle tasks into the inbox (on a schedule)
Where "Send top tasks to the inbox" is a one-shot nudge, "Trickle to inboxβ¦" is the recurring version: instead of dropping the whole pile at once, it feeds a project's tasks (or a hand-picked set) into your inbox a few at a time, on a cadence you choose. Pick Trickle to inboxβ¦ from a project's actions menu (the whole project's open tasks) or from a multi-selected set of tasks (just those), and a small box asks for a name, a cadence (the same plain-English picker as Drip β "every weekday at 9am"), how many to send each time, an optional repeat forever, and "Archive each task once it's sent to my inbox." Confirm and a few tasks start arriving on that schedule.
Under the hood this is Drip β the action creates a real drip pre-loaded with your chosen tasks, so pause/resume, snooze, repeat-forever, and the Drip management view all work on it, and you can tweak it in Drip later. It's free (the same local ranking, no AI). A task you finish (or delete) before its turn never shows up β it quietly drains, so the inbox never nags you about done work. With archive-on-release on, a task is archived (reversible, via the Archived tab) the moment it's sent β that option is off by default and is hidden for a repeat-forever trickle (archiving would end the reminder). Big projects are capped (the top ~100 tasks) and you're told if anything was left out. It snapshots the tasks as they are when you set it up; add more later and you re-trickle (or use repeat-forever). Handled by tasks-v2:trickle-create (gated, desktop/IPC-only for now); full invariants + the tests that lock them live in .claude/memory/contracts/tasks-v2-trickle-contract.md.
Export every task as a JSON file
The header's β― More β Export JSON writes an inspectable folder β one pretty-printed JSON file per task, plus an _index.json manifest β into the app's data folder (tasks-v2-export/), then opens it for you. Each file carries the task's fields (text, done, due/snooze, importance/urgency, tags) plus the name of the list it lives in, with a human-readable filename taken from the task's first line. It's on demand (a manual click), read-only (it reads the database and writes the folder β it never reads the folder back, so editing a file changes nothing), and the folder is rewritten from scratch each time so it always matches your current tasks. Handled by tasks-v2:export-json (gated, IPC-only); it adds no database tables or server routes. Two-way file sync β edit a JSON file by hand and have the change flow back into the app β is the deferred someday-luxury, not this.
Related
The overview, the other parts, and everything else worth reading next all sit on Tasks (markdown outliner, in development).
Last verified 2026-09-23