Tasks (markdown outliner, in development) (part 3)
Snoozing tucks the task into a "Snoozed" section. Once a task is snoozed into the future, it leaves the list and collects under a single collapsible ⏰ Snoozed (N) row pinned at the bottom — so the list stays focused on what's actually actionable, while the count tells you at a glance what's parked.
What it is
This is part 3 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.
Keyboard: two modes (writing vs command) (continued 3)
Snoozing tucks the task into a "Snoozed" section. Once a task is snoozed into the future, it leaves the list and collects under a single collapsible ⏰ Snoozed (N) row pinned at the bottom — so the list stays focused on what's actually actionable, while the count tells you at a glance what's parked. Open the section to see each snoozed task rendered just like a regular task row — it's numbered (1./2./3., the same as the list above), shows its full text, its wake date on the usual alarm-clock chip, and a "+N sub-tasks" count if it has any. Its 🕐 clock header lines up in the same column as those task numbers and the add-row's "+", so the section reads as part of the list instead of sitting off to the side. To bring one back early, open the row's ⋯ menu and choose Wake now — the old always-on button is gone, so the rows stay calm and read like any other task. When the snooze time passes the task returns to its place in the list on its own — and Omniscio also drops a reminder in your Inbox so you don't miss it (see Deadline & snooze reminders). If every task in a list is snoozed, the section still shows (with an "all snoozed" note), so nothing is ever out of reach. The consolidated "All Projects" view now behaves the same way — each project group carries its own collapsible ⏰ Snoozed (N) section at its bottom (same numbering + the ⋯ Wake now). These snoozed tasks used to stay inline in that view as a slim ⏰ stub; they're now tucked into the section like everywhere else.
A task that came back is marked so you can see it was snoozed. When a snooze time
passes and the task returns to the list, it carries a small alarm-clock icon (the same
one the rest of Omniscio uses for snooze) instead of the old "⏰ Yesterday"-style stale date. If
it's been snoozed more than once, a ×2 / ×3 badge rides beside the icon, and
hovering lists every snooze — each as "Snoozed Jul 1 → until Jul 5" (both the moment you
snoozed it and the wake time you picked). A still-waiting task is unchanged — it keeps
its "Snoozed until Friday" wording so you know when it's back; only the emoji was swapped for
that same alarm-clock icon. This history is recorded per task on every genuine snooze (editing
an already-set snooze's time or clearing it doesn't inflate the count) and is capped at the 25
most recent; tasks already snoozed when this shipped are backfilled with one entry so they read
right immediately. Undoing a snooze restores the count too, so it can never drift. Stored in
the tasks_v2.snooze_history_json column; the invariant + tests live in the contract
(snooze-history in .claude/memory/contracts/tasks-v2-contract.md).
Fold a task that has sub-items. Any task with sub-items shows a small chevron (▸/▾)
just to the left of its number (so the arrow hugs the item) — click it (or press F, or use the right-click Collapse sub-items
row) to fold its subtree out of sight; a quiet count shows how many items are tucked away, and
folding again unfolds them. The fold is remembered across restarts (it's saved like the
collapsed-project state), works in both the giant "All Projects" view and a single-project
list, and keyboard navigation skips folded rows. It only changes what's on screen — it never
moves, edits, deletes, or exports a task — and a folded parent is still fully covered by
whole-project actions (its hidden children still count). Drilling into or adding a sub-item under
a folded task automatically unfolds it so you always see what you just touched, and while a filter
is active folding is paused so a filtered-in match is never hidden.
The command line reuses the same plain-English reader that parses a typed capture
line ("call vendor due friday #work !high") when you create a task, plus a small
phrase layer for "high priority" / "move to <list>" / "done" — so dates
("tomorrow", "next week", "in 3 days"), priority, and tags all just work,
and a line it can't read is shown back to you (nothing is written on a misread).
Removing isn't a typed command — a bare Delete (or Ctrl/Cmd+Delete) archives the task (reversible, like checking it off),
so a typed line can never destroy a task. New keys only fire when a task is highlighted
and you're not mid-typing, so they never eat your keystrokes; v1 Tasks is untouched.
This keyboard drives both views the same way — the default giant "All Projects"
view and a single-project filtered view — because both mount one shared
implementation (useTaskV2CommandKeys). In the giant view the focus nav steps across
project groups, Alt+Shift+↑/↓ reorders the task up/down — and at its sibling-group edge a nested
(child) row nests into the visually-adjacent SAME-PROJECT item (move-down → first child of the item
below, move-up → last child of the item above; depth preserved), while a top-level row at a
project's top / bottom edge instead carries into the neighboring project (move-down → top of the
next project, move-up → bottom of the previous), and a multi-selected block at that edge crosses together as a set (appended to the target, one undo) — and Tab/Shift+Tab — or the OneNote
aliases Alt+Shift+→/← — indent/outdent the focused row (or, with multiple rows selected, the WHOLE selected block together as one undo) within its own project (scoped so neither indent nor a child's nest ever crosses projects); only
Backspace-merge and drill-in differ (no-ops in the merged view — see
The giant default view). In the giant
view the up/down nav also stops on each project name (header), so you can act on a whole
project — see Select a project & act on the whole thing.
While your cursor is in the Tasks list, the list owns its keys: Omniscio's app-wide shortcuts stand down for these bare keys (and for Ctrl/Cmd+Z / Ctrl/Cmd+Y, which run the list's own universal undo / redo — see Archive & universal undo), so a command-mode key never also fires an app-wide action behind the list — exactly how the Mind Map and Notes panels work. App-wide combos that aren't list keys (Ctrl+1-9 jump to a project, Ctrl+T new session) still work from the list. Ctrl/Cmd+K is now a list key — it inserts a link (see the keyboard table) rather than opening global search from Tasks, the same way the Notes editor claims Ctrl+K for its own insert-link.
Keyboard: two modes (writing vs command) — Caught — AI suggestions in their own view
When one of your agent sessions ends, a quick AI pass reads its transcript for follow-up tasks you still owe and stages them as suggestions — nothing files itself. They live in their own Caught entry in the project rail (with a count of how many are waiting); the entry appears only while there are suggestions to review, and opens a plain numbered list, just like a normal task list (this replaced the old strip that used to sit above the list).
Each row shows the suggestion, a quiet link back to the session it came from, a small category chip (the project it will file into, editable), and — on the row you're pointing at or have focused — Approve ✓ and Dismiss ✕. Approve turns it into a real task in the chip's project; Dismiss asks to confirm and stays undoable. At rest a row reads as a clean numbered item, so the list never feels like a form.
It's keyboard-first, so you can clear it without a mouse: ↑ / ↓ (or j / k) move
between suggestions, Home / End jump to the first / last, Enter approves the focused
row (into its chip's project), and Delete opens the Dismiss confirm. The keys act only while
the row itself is focused, so typing in the category chip is never hijacked; the active row
shows a focus ring, and after you approve or dismiss, focus moves to the neighbouring suggestion
rather than being lost. Clear the last one and a friendly "you're all caught up" note takes its
place (TaskV2CaughtView.tsx).
Control what gets caught. Under Settings → Tasks · Caught (find it via Settings search) you can turn catching off entirely, or give it guidance — tell the AI, in your own words, what counts as a follow-up worth catching ("only things I still owe someone", "skip anything about code"). The guidance steers which suggestions are kept but can't break the feature (the format it returns stays fixed). Catching can also be limited to sessions from chosen projects (empty = every session, so it never silently stops); that project picker is a small follow-up for now.
Catching is selective by design. A session is scanned only when you actually typed in it — purely agent-driven sessions (background lanes, cron and recipe runs, peer-messaged workers) are skipped entirely, so the agents' own to-do chatter never lands in Caught (and no AI call is spent on them). A scanned session stages at most 8 suggestions across three detection layers — up to 3 explicit (Layer 1), 3 implicit action items (Layer 2), and 2 pattern-based (Layer 3) — and most stage none. The bar is a real next step you own, never the agent's own workflow steps (running tests, merging a branch, re-running a session…). A suggestion you've already seen in the last two weeks — kept, dismissed, or still pending from another session — won't be staged again, so five sessions on the same piece of work can't each re-suggest "send Sam the deck".
Suggestions re-check themselves, so the list doesn't go stale. The most common reason a good suggestion gets dismissed is simply that you already did it — the work closes long before you next open the lane. So when a later session is scanned, the AI also looks at the suggestions still waiting here and flags any the transcript shows you've since finished. A flagged row is not removed: it sinks to the bottom of the list, renders faded under a "Looks already done since this was caught" line, and shows the quote it based that on — so the top of the lane is only what's still genuinely live, and a wrong guess is visible instead of silently trusted. You still click, and Approve on a flagged row clears the flag (keeping it means you disagreed). This costs no extra AI call — it rides the scan that was already running — and it never touches anything if there's nothing waiting.
Older suggestions fade out, but nothing is lost. Suggestions older than 30 days are automatically hidden from the active Caught list so the lane stays focused on recent, actionable items. They are not deleted — they remain in the database and are still findable. When any suggestions have aged out, a subtle banner at the bottom of the list shows how many were hidden and links to Ask Omniscio, where the user can search past sessions for the task they're looking for and re-add it.
Cut & paste a task
Move a task with Ctrl/Cmd+X (cut) then Ctrl/Cmd+V (paste) — the same cut/paste you know from files. Cut is a move; Copy (Ctrl/Cmd+C or the ⋯ / right-click Copy row) now pastes too, as a duplicate — the original stays put and a copy lands where you paste, into the same project or any other (a brand-new one included). Cut and copy share one clipboard (arming one clears the other), and both paste the same way (below the highlighted row, or into a project heading):
- Ctrl/Cmd+X marks the highlighted task (or a multi-selection) to move. With multiple rows selected, only the topmost selected tasks are cut — a parent+child selection keeps the child's nesting under the parent (same rule as Finish / Move). The row dims and gets a dashed outline and a small ✂ cut tag (hover it for the paste/cancel hint). The task does not move or vanish — if you never paste, nothing changes (cut only marks).
- Ctrl/Cmd+V moves the cut task(s) to right below the highlighted task — in every view. A single-project list, the All Projects giant view, and moving a task between projects all land it directly under the highlighted row now (carried into that row's project when they differ). Nesting under a cut parent is preserved. The cut mark then clears.
- Copy → paste is a DUPLICATE. Copy a task (Ctrl/Cmd+C or the Copy row), then paste it (Ctrl/Cmd+V / Paste here / onto a project heading) to drop a copy in that spot — the original is untouched, so you can paste the same task into several projects, or into a brand-new one. Unlike a cut, a copy stays on the clipboard after pasting (paste it again) and survives even if you later archive the original. Copy carries the task's own line (not its sub-items), matching Duplicate (Ctrl/Cmd+D).
- Paste into a fresh blank row. After you copy or cut task(s), you can press Enter to add a new task and then Ctrl/Cmd+V — Omniscio drops the copied/cut tasks into that spot and clears away the empty new-task line, so the paste lands exactly where you started the new task. (Typing anything into the row first, or having nothing on the clipboard, keeps Ctrl/Cmd+V a normal text paste.)
- Onto a project HEADING instead (All Projects) — drop the cut task straight INTO a project, even an empty one (appended, since a heading has no task to sit below). Two ways: with the keyboard, land the cursor on another project's heading and press Ctrl/Cmd+V; with the mouse or on a phone, just CLICK that project's heading while a task is cut — the click drops it in instead of folding the project (and a collapsed target opens so you see it land). That click is how you fill an empty project without a keyboard. Clicking a project you can't move into — the synthetic (Unfiled) heading, or the task's own project — just folds it as usual (and pasting a task onto itself is a no-op). With nothing cut, clicking a heading folds it exactly as before.
- Prefer a picker? Press
Von a task to choose the destination project from a small menu — the same as the ⋯ / right-click Move to project. Handy in a single-project view, where there's no other project on screen to paste onto. - Esc cancels a pending cut; cutting another task moves the mark; archiving or deleting the cut task clears it. A failed or not-allowed paste keeps the mark so you can retry.
- It also lives in the ⋯ menu and the right-click menu as Cut and Paste here, so it
works with a mouse and on a phone (no Ctrl key there). The keys (cut / paste / move-to-project)
are rebindable (Settings → Keyboard Shortcuts → Tasks) and show in the
?cheat-sheet. - Precise within-project paste needs the manual sort with no filter (the same rule as drag / Move up-down — under another sort the on-screen order is just a view); if you're sorted or filtered, Omniscio tells you instead of dropping the task somewhere misleading. While you're typing in a row, Ctrl/Cmd+X/V stay the normal text cut/paste.
Paste a link onto selected words → a hyperlink
Select some words in a task and paste a link (any http(s) URL) — the selected words
turn into a clickable hyperlink to that address, instead of the raw URL landing as plain
text beside them. It's the same gesture every notes app and chat box uses: highlight
the spec, paste https://…, and the row now shows the spec as a link. Works in both the
"+" quick-add row and when editing an existing task; undo with Ctrl/Cmd+Z.
- On an existing task the row drops straight back to its rendered view after the paste, so
you see the finished clickable link immediately instead of the raw
[words](url)markdown source. (In the "+" quick-add row the text stays as you type and becomes the link on Enter.) - It only kicks in when you have text selected and the clipboard is just a URL. Paste a URL with nothing selected and it drops in as an ordinary (still clickable) link; paste plain text and nothing special happens — your paste is never hijacked.
- Want to type the label yourself, or add a link without selecting first? Ctrl/Cmd+K opens the Insert-link popover (see the shortcuts table). The paste gesture is just the fast path for the common case.
- Non-web schemes (
mailto:,ftp:,javascript:) are never turned into a link.
Edit a link you already added
Got a link in a task and need to fix where it points or change its wording? Right-click the link and pick Edit link. A small box opens pre-filled with the link's current address and text — change either, hit Save, and just that one link is rewritten in place (the rest of the row is untouched). Like every other link edit, it's Ctrl/Cmd+Z-undoable.
- Edit link sits right next to Copy link in the menu that pops up when you right-click a link — so a link's own right-click menu is where you copy it OR edit it.
- It finds the exact link you clicked even when a row has several, and even when a pasted-URL link's on-screen text was shortened to keep the row tidy (the full address is still there to edit).
- This is a Tasks thing — links in chat and the inbox keep their usual right-click menu.
A bare link → its title
Add a task whose text is just a link — a YouTube/Vimeo video or any other web page — and,
a beat later, it becomes a clickable link labeled with the page's real title:
https://youtu.be/dQw4w9WgXcQ turns into Rick Astley - Never Gonna Give You Up, and a bare
article / GitHub / docs link turns into that page's headline. Under the hood it's stored as a markdown
link ([title](link)) and the row renders task text as markdown, so you get the readable title and
keep the click-through — never dead, un-clickable text. The raw link is always kept inside the
titled link, so nothing is ever lost, and Ctrl/Cmd+Z snaps a just-pasted link back to raw.
It fires no matter how the link got there — including links already in your list. Paste a video link into the "+" row or a task title and you get an instant spinner + Ctrl+Z; type any link, or hit Enter before the title loads, and it still gets titled a beat later (titling is keyed off the saved task, not the typing box). Links you already had — added before this feature, dropped in by an agent, or created any other way — now get titled automatically when the list loads (a one-time, per-session background pass). And for any bare-link row you can right-click (or open its ⋯ menu) and pick Get link title on demand.
- It only fires when the task text IS the whole link. A link dropped into the middle of other
words is left alone, and non-web schemes (
mailto:,data:, …) aren't touched. Twitter/X isn't auto-titled from a paste (a tweet has no "title" that reads as a task). - While a title loads a small spinner shows in the row's trailing edge; if the fetch fails or times out (offline, a private/blocked page, a page with no title), it quietly keeps the raw link — no error popup, and the link is still a perfectly good task.
- It's free and safe — a video title comes from YouTube/Vimeo's public oEmbed (with an
og:titlepage fallback for Vimeo's firewall); any other page's title comes from the same security-hardened fetcher the chat link-preview uses (it blocks private/internal addresses, follows redirects safely, caps size + time, and is rate-limited). Both run in the main process (the renderer can't make outbound calls) and cache results, so a re-load never re-hits the site. - The backfill never disturbs you. It tries each link once per session, never re-touches a link it already titled, keeps the raw link on any failure, and — importantly — doesn't touch your Undo history, so Ctrl+Z always undoes your last edit, not a background titling.
- Never clobbers what you wrote. The title lands only while the row still holds exactly that link;
edit it in the meantime and the title is quietly dropped so your text wins. Key files:
store/tasks-crud-slice.ts(resolveLinkTitleForTask+ the create-time net +backfillLinkTitles),video-title-paste.ts(detectVideoUrl+detectBareUrl),useVideoTitlePaste.ts(the paste hook),ipc/tasks-v2/video-title.ts+ the sharedlink-previewfetcher (main). Invariants:tasks-v2-video-title-paste-contract.md(create-net-keyed-off-persisted-task,manual-get-link-title-action,backfill-is-session-once-and-undo-free: the create-net, the "Get link title" action, and the load-time backfill).
Paste an internal link → attach it to the task
Copied a link to a session — or to a specific comment/message inside one (the "Copy link"
on a session's menu, or "Copy link to this message")? Or a link to a project, a chat
message, a KMS note, a super prompt, a mind map, a setting, a shared
conversation? Paste it into a task and that entity is attached to the task — the same
kind of link the "Attach" picker makes — instead of the raw omniscio://… address landing as
text. It appears under the task's 📎
Context attachments (click the chip to open it), and a toast with Undo
takes it right back.
- On a task you're editing, it attaches the instant you paste and the raw link is dropped. In the "+" add-a-task row, pasting a link fills the row with a label (session name / project name / a friendly noun like "Chat message") as a starter title and attaches it when you press Enter to create the task (type your own title over it if you'd rather). On a focused task in command mode, paste it straight onto the task the same way.
- A link to a comment attaches its parent session (there's no separate "attach a comment");
session and project links attach as rich session/project context items, and any other internal
link attaches as a clickable link item that opens the entity when clicked. Older
agentmc://…links work too. - It only fires when the clipboard is the whole link — a link pasted into the middle of other words is left alone, and a normal web/video link still does its own thing (see A bare link → its title). Already attached? It won't add a duplicate.
- No new setting — Undo is the off-switch (same as the bare-link titling above). Key files:
internal-link-paste.ts(parsePastedInternalLink),attach-pasted-internal-link.ts(resolve the label → attach),view-mode-paste.ts(command-mode Ctrl+V onto a focused task),TaskV2Row.tsx/TaskV2NewTaskRow.tsx(the two edit surfaces), reusing the sharedattachSessionToTask/attachContextItemToTask; url-kind items open in-process viaopenAppLink→DEEP_LINK_OPEN. Invariants:tasks-v2-internal-link-paste-contract.md.
Archive & universal undo
Finishing a task marks it done and files it into Archived in one step — completing and clearing it off your list together (think email Archive vs. Trash; Delete still exists separately).
Two outcomes, so Archived reads as a real ledger. Finish says you did it. Drop files the task away without marking it done, for the things that stopped mattering rather than got completed. Both clear the task and its sub-tasks off your list; only the record differs. Drop is on the row's ⊘ button, the ⋯ and right-click menus, the bulk bar, and Shift+X (X finishes, Shift+X drops). Undo restores the exact outcome — a dropped task that you undo and redo comes back dropped, never quietly finished. A recurring task that you drop creates no next occurrence: dropping ends the series, where finishing rolls it forward.
The Archived area badges every item Done or Dropped, with a filter to see just one. Anything archived before this shipped is badged a neutral Archived: back then archiving always wrote "done", so that flag can't tell whether you finished the task or abandoned it, and the ledger won't claim an outcome it cannot know.
You finish a task four ways, all equivalent (they finish the task and its sub-tasks):
- Check the box — the primary gesture. The row smoothly collapses + fades (~0.2s), is marked done, and tucks into Archived. (Under reduced-motion or low-power mode the collapse is skipped and the row finishes instantly.)
- Middle-click (the mouse's middle button) anywhere on a row — the fast power shortcut (Omniscio suppresses the browser's middle-click scroll "compass" so the gesture is clean); right-click opens the row's full action menu, where Finish is one of the options.
- The Finish row in a focused task's ⋯ menu (works on touch + keyboard).
- The
xorekey on the highlighted task (command mode).
The first time you finish a task, a small "Item complete! Use Ctrl+Z to undo." toast
teaches you the shortcut; after that, finishes are silent (no repeated toast noise).
Finished tasks leave your lists, counts, and the tasks-v2.md mirror and
collect in a browsable Archived area — open it from the "Archived" entry pinned at
the bottom of the project rail (it shows a count of what's inside) or the header ⋯
More → Archived. It opens as a dedicated tab that takes over the main area — your
active task list and the "Add a task" box are hidden while it's open, so finished items
never linger beneath it; click Done (or pick a project in the rail) to return. Inside,
items are grouped by project, with a project filter dropdown to show just one
project's archive, and each row shows when it was archived (the exact time on hover).
Each row's Restore button sits on the left and appears on hover (always visible
on touch); Restore brings the task back active and unchecked (if a task's original
parent is gone, Restore returns it to the top of its project so it never dangles).
A bare Delete — or Ctrl/Cmd+Delete — archives here too. Ctrl/Cmd+Delete used to be a
separate soft-delete that stranded the task (no toast, not browsable), and a bare Delete did
nothing; both now land in Archived like every other remove gesture. The bare Delete works only
in command mode (never while editing a row's text) and never on a project heading, so it can't
wipe a whole project — and it's Delete only, not Backspace.
Universal undo — Ctrl/Cmd+Z. Every change you make in Tasks — add, rename,
check-off, archive, delete, reorder, indent, move-to-project — can be undone with
Ctrl/Cmd+Z, and you can keep pressing it to walk back through your recent changes
(no step limit). It is a real undo: it puts the data back in the database (so it
sticks), not a screen repaint. A continuous run of typing on a row counts as one undo
step — so undoing a rename reverts the whole edit at once, never one letter per press. One honest limit: undo history is per session — it
resets when you quit and reopen Omniscio (surviving a restart is a separate, later feature).
While you're typing in a row, Ctrl/Cmd+Z is the normal text undo; the task-level undo
runs in command mode (a highlighted, non-editing row) — and a mouse-only archive
(middle-click, the checkbox, or the ⋯ menu) keeps keyboard focus on the list so Ctrl/Cmd+Z
lands right after it, including from the "No tasks yet" screen when you archive your last
task. (Under the hood every action records its exact inverse and replays it as a real
operation — v2 only; the older Tasks list and Tasks are untouched.)
Redo — Ctrl/Cmd+Y. Anything you undo, you can redo with Ctrl/Cmd+Y (or
Ctrl/Cmd+Shift+Z) — it re-applies the change you just took back. Like undo it has no step
limit, so you can walk all the way forward again, and it's a real redo that persists to
the database. Starting a new change clears the redo trail (the standard "once you do
something new, there's nothing left to redo" rule). Redoing a typed word re-applies the whole
word at once, and redoing an added task or a finished recurring task brings back the
same row / the same next occurrence — never a duplicate. While you're typing in a
row, Ctrl/Cmd+Y is the normal text redo; the task-level redo runs in command mode, exactly
like undo.
Related
The overview, the other parts, and everything else worth reading next all sit on Tasks (markdown outliner, in development).
Last verified 2026-09-28