---
title: Tasks (markdown outliner, in development) (part 7)
---
# Tasks (markdown outliner, in development) (part 7)

## What it is

This is part 7 of the [Tasks (markdown outliner, in development)](tasks-v2.md) 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)](tasks-v2.md) — 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 `tasksV2CollapsedProjectIds` setting); 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](#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-project` invariant (`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`-`k`** move 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 (`h` snooze · `d` deadline · `x`/`e` finish · `p` priority · `c`/`i` context · `:` command line · `g` agent · `b` break-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`/`e`** finish all · **`h`** snooze all · **`d`** set-deadline-all · **`p`** set-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](#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](#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+X` then `Ctrl/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 stays `Alt+Shift+↑/↓` or the filtered outliner). Or press **`V`** on 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](#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](drip.md)** — 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`](/.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)](tasks-v2.md).
