Tasks (markdown outliner, in development) (part 8)
Any task can host its own Claude agent chat. On a focused outliner row, the "Launch agent" button or the g key runs open-or-launch: If the task already has a chat, it reveals in the Sessions tab and selects it — free, no spawn, no pop-out. If it doesn't, an editable launch-prompt popup opens, showing the visible task message the agent starts from (the task text + its open subtasks) — editable — plus a session-type picker
What it is
This is part 8 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.
Start a session — the one-click launchers
Above the session list, the Sessions tab carries a row of six one-click launcher buttons — Today's Session, Weekly Review, Brain Dump, Deep Work, Quick Wins, and Catch Up. Click one and a guided session opens instantly and greets you with its own first questions — no picker, no prompt to type. It's the fast way in when you don't have a specific task in hand: you just pick the kind of session you want and start talking.
It costs nothing until you reply. Each button uses the same deferred pattern as AI Coaching: a pre-authored opening message shows the moment you click — no model is spawned and no tokens are spent yet — and the model only cold-spawns when you send your first reply. So opening one, reading its opener, and closing it is free. Under the hood each launcher is seeded with a hidden super prompt that steers the whole conversation; you see the opener and your own messages, never the steering. Like every task agent, these run in the hidden Tasks workspace (__tasks_workspace__) and land in the Sessions list in the background.
The six presets are built-in super prompts you can edit — they live in the bundled Super Prompt library as the macro-* prompts (macro-todays-session, macro-weekly-review, macro-brain-dump, macro-deep-work, macro-quick-wins, macro-catch-up), each carrying the hidden steering body plus its pre-authored opener. Still behind the Tasks Labs flag.
Plan — chat your way to a plan (removed from the UI; backend dormant)
The Plan tab has been removed from the tab strip. The Tasks / Sessions strip no longer shows a third Plan tab. The plan-chat backend described below is left in place (dormant) but is not reachable from the UI right now.
The panel's tab strip (TasksV2PanelTabs.tsx) used to carry a third tab — Plan — between Tasks and Sessions; the strip is now Tasks / Sessions only. It was an internal, plan-only conversational planner: instead of driving the outliner key-by-key, you chat — "what should I focus on today?", "add a task to call the vendor before Friday", "break the launch task into steps". Plan chat reads your board (today's plate, caught suggestions, the project master context, and what it has learned about you) and answers in plain language — and when your message implies a board change, it doesn't just make it. It proposes the change and waits for you.
Propose → preview → approve. One message is one bounded AI turn that returns a reply plus zero or more proposed actions. Any board-changing action renders in a "Proposed changes" card (TaskV2ProposedChangesCard.tsx) — each row spelled out in plain language ("Add task: 'call vendor' (due Friday)", "Mark 'finish report' done") — with Approve and Reject. Nothing touches your tasks until you approve: a plain question just answers, a proposal sits transient in the card, and only Approve writes it — through the same task writers a normal edit uses (add-task → the ordinary create, complete-task → the same cascade-complete, plus move-to-list, break-down, reorder, field edits, and "pull" a caught suggestion into a real task). So Plan chat can never do anything to your board you couldn't do by hand.
A closed action vocabulary. The model's reply is JSON, and Plan chat trusts none of it blindly. A defensive parser (tasks-v2-plan-chat-prompt.ts) accepts only eight action kinds — add-task, edit-task, complete-task, set-today, reorder, move-to-list, break-down, pull-caught — and silently drops anything else: an unknown kind, a malformed action, or an action pointing at a task id (or caught id) that wasn't in the board it was shown. It never throws, it clamps out-of-range values, and it caps how many actions one turn can propose — so a hallucinated or hostile reply can only ever surface a subset of safe, real actions for you to approve.
One resettable thread. Your Plan chat is a single rolling conversation stored in the tasks_v2_plan_chat table (queries-tasks-v2-plan-chat.ts); it survives closing and reopening the panel, and a Clear wipes it back to empty so you can start fresh. The turns persist; the proposed actions do not — they live only until you approve or reject them.
Cost & gating. A turn is a cheap Haiku pass billed to the tasks-v2:plan-chat label, which pools into the one shared tasksV2AiDailyCapUsd daily budget alongside the rest of Tasks's AI (Right now, the daily check-in, the breakdown interview, session-end catches, the distill pass) — there is no separate Plan-chat spend cap, and when the shared cap is spent for the day a turn falls back to a free local summary instead of calling the model. Like the rest of Tasks, Plan chat is gated dark behind the tasks-v2 Labs flag: the Plan tab, its IPC handlers (TASKS_V2_PLANCHAT_{GET,SEND,APPLY,CLEAR}, each requireTasksV2Enabled()-first), and its store slice are all inert until the flag is on. The paid SEND and mutating APPLY/CLEAR channels are IPC-only (no CLI route, by design — they only mean anything bound to the live chat panel) and are blocked from the mobile/web bridge. Merging Plan chat changes nothing for users until the flag flips.
Key files: TaskV2PlanChat.tsx (chat pane) + TaskV2ProposedChangesCard.tsx (the approve/reject card) · service src/main/services/tasks/tasks-v2-plan-chat-service.ts (send a turn / apply approved actions) + tasks-v2-plan-chat-prompt.ts (prompt builder + defensive parser) + tasks-v2-plan-chat-context.ts (bounded board context) · makePlanChatAi in tasks-v2-ai-runtime.ts (the pooled-cap AI factory) · thread table src/main/db/queries-tasks-v2-plan-chat.ts · store slice src/renderer/src/features/tasks-v2/store/tasks-plan-chat-slice.ts · shared vocabulary + message types src/shared/tasks-v2-plan-chat.ts.
Break it down — the AI interview (M4)
When a task feels big or vague, Break it down turns it into a short list of next-actions without leaving your list. From a focused row, the "Break it down" action (in the row's ⋯ overflow menu) or the b key opens a right pane beside the list (full-screen on a narrow screen). This is Break it down's own pane — the per-task agent chat now lives in the Sessions tab (no right pane) — but the two remain mutually exclusive at the store level: opening Break it down clears an open chat's detailSessionId, and revealing a chat clears interviewTaskId.
How it works, and why it's cheap and safe:
- It's an interview, not a spawn. Unlike the per-task agent chat (a full Claude session that uses real tokens per turn), Break it down uses the same cheap, bounded AI as the "Right now" / daily-check-in prioritizer (Haiku via the embedded key, short bounded prompts, defensive parsing). The model never sees full task bodies — only a bounded brief (the task text, its list's master context, a few attached-context labels, and the existing sub-steps so it won't re-propose them).
- Starting it spends one bounded call. Clicking Break it down runs the interview directly (no confirm pop-up); reopening an existing breakdown is free (the thread is saved). Every turn — and the daily check-in and "Right now" — draw on ONE shared daily budget (
tasksV2AiDailyCapUsd, default $0.50). Over the cap, it degrades to a friendly "budget used up" message, never a broken pane. - It proposes; you decide. The AI asks at most one short question at a time, then proposes 3–7 concrete next-actions. They land in an editable list — reword, remove, or add your own. Nothing is written until you click "Add N subtasks", which creates them all at once under the task (via the normal task-create path, inheriting the task's list). The AI can never add tasks on its own, and the write step is in-app only (no CLI route) so a background agent or a test can't trigger spend or create tasks.
- It's aware of the time-estimate field — but only fills it on request. The AI knows the estimated-time field exists and sees the task's current estimate (if any), so it can reason about how long the work takes. Only when you ask about time — "roughly how long will each step take?", "give me estimates", "how long is this in total?" — does it propose a per-step estimate and offer a running total; unprompted it stays silent on time (a task app shouldn't guess durations you didn't ask for). When it does estimate, each step shows a small ⏱ chip and the panel adds an honest total line ("≈ 1h 15m total · 2 of 3 steps estimated" — truthful about partial coverage). On Add, each step's estimate is written onto its subtask, and if the parent task had no estimate yet, the steps' total rolls up onto it — so a big task finally shows a realistic total — but it never overwrites an estimate you set by hand. This is the "help me feel less overwhelmed" path: ask for a breakdown, then ask for the time, and you get both the steps and a grounded total.
- Proactive nudge (opt-in, free, default OFF). Turn on "Suggest breakdowns" (a toggle in the header's ⋯ More menu) and a subtle hint appears on rows that look big or vague — decided by a free local heuristic (long text / many words, or no sub-steps and no priority dials set), so no AI is called and nothing is spent until you actually click the hint.
Still behind the Tasks Labs flag. State for a task's breakdown lives in tasks_v2_interviews (the conversation + the current proposal + an "accepted" stamp); reopening never re-spends.
Tame the overwhelm
A coaching session type in the launch picker, Tame the overwhelm, runs The Overwhelm Coach — a warm, steady guide for when the pile feels bigger than the day. It works in two gears. First it gets you calm and clear: normalizes the feeling, offers a 60-second reset (never opening with the to-do list), then empties your head, cuts the list ruthlessly (delete / defer / delegate / renegotiate), and ranks the vital few (ICE, head-to-head). Then it gets tactical: it shapes an "Overwhelm Battle Plan" with a concrete Today's 1–3 and a trickle plan for the rest — and when a priority is itself a big project, it runs the Eat-the-Elephant engine, breaking it into a phased, bite-sized roadmap with an easy first win to start on today.
Unlike Clarify & enrich (project-launch only), it's offered on both a single task and a whole project — pick Tame the overwhelm from the Launch agent popup (the button / g on a task, or a project's "Launch agent…" menu). Like Interview for context and Clarify & enrich, it's a full background Claude session in the hidden Tasks workspace (real tokens per turn, cost-gated by the Launch button) — not the cheap bounded Break it down interview. After you approve the plan, it files its concrete next-actions as real tasks via the Omniscio CLI — subtasks under the task on a single-task launch, or tasks in the project on a whole-project launch. When the plan includes an Eat the Elephant roadmap, its phases become subtasks with their steps nested beneath and the easy first win is flagged first. It never creates or changes anything before you approve.
Under the hood it reuses the exact machinery the other coaches use: your Overwhelm Coach superprompt is stored verbatim, main-process only (OVERWHELM_PREAMBLE, never shipped to the renderer), with a small CLI-agent ending appended — the same pattern as the Break it down coach's verbatim Momentum prompt. It rides the existing launch path and the shared list builder (a non-interview/clarify type gets the "file tasks into this list" footer), so there's no new IPC channel, Zod schema, DB table, or Labs toggle. Still behind the Tasks Labs flag; invariants (overwhelm-verbatim) live in .claude/memory/contracts/tasks-v2-session-types-contract.md.
Eliminate, automate, delegate
A coaching session type in the launch picker, Eliminate, automate, delegate, runs the EAD Analyzer — an operations-efficiency coach for getting work off your plate. It works the Eliminate → Automate → Delegate hierarchy in that strict order (the best task is one that doesn't need to happen at all): it interviews you to surface hidden work, then runs each item through the three lenses — Eliminate (zombie processes, the Two-Week Test, the "New CEO" test), Automate (only once a process is "perfectly defined"), and Delegate (who-not-how, delegation vs. dumping) — gently challenging every "but it has to be me". The deliverable is a categorized, prioritized, confidence-scored analysis of what to cut, automate, or hand off.
Like Tame the overwhelm, it's offered on both a single task and a whole project — pick Eliminate, automate, delegate from the Launch agent popup (the button / g on a task, or a project's "Launch agent…" menu). It's a full background Claude session in the hidden Tasks workspace (real tokens per turn, cost-gated by the Launch button) — not the cheap bounded Break it down interview. After you approve the analysis, it files each recommendation's concrete next step as real tasks via the Omniscio CLI — subtasks under the task on a single-task launch, or tasks in the project on a whole-project launch — and, for a task it recommends eliminating, it checks that task off only with your sign-off. It can also save the whole analysis as a context note. It never creates, changes, or completes anything before you approve.
Under the hood it reuses the exact machinery the other coaches use: your EAD Analyzer superprompt is stored verbatim, main-process only (EAD_PREAMBLE, never shipped to the renderer), with a small CLI-agent ending appended — the same pattern as the Tame the overwhelm and Break it down coaches' verbatim prompts. It rides the existing launch path and the shared list builder (a non-interview/clarify type gets the "file tasks into this list" footer), so there's no new IPC channel, Zod schema, DB table, or Labs toggle. Still behind the Tasks Labs flag; invariants (ead-verbatim) live in .claude/memory/contracts/tasks-v2-session-types-contract.md.
Interview for context
A sixth agent session type in the launch picker, Interview for context, adapts the "Context Handoff Generator": it interviews you about a task (or a whole project), writes one clean, paste-ready context document, and — only after you approve it — saves it as attached context that every future agent inherits. Two entry points, differing only in where the result is saved:
- On a task — the launch-agent picker's sixth option (the Launch agent button /
g, then pick Interview for context). On your approval it saves the document as a context note on that task (POST /tasks-v2/context/create), so every future agent launched on that task receives it automatically (via the same cascading-context brief the per-task chat gets). - On a project — the "Interview" button on a project's master-context card (beside its Edit button). It interviews about the whole project and, on your approval, writes the project's master context (
POST /tasks-v2-lists/update), inherited by every future agent launched on any task in that project. A confirm dialog gates the spend first.
Unlike Break it down (a cheap, bounded, in-app AI that only proposes subtasks and can never write on its own), Interview for context is a full background Claude session in the hidden Tasks workspace — it uses real tokens per turn and persists its output through the Omniscio CLI. It never hard-codes an id: the launch-time hidden footer hands the agent the concrete route + id + auto-trusted token for whatever it was launched on, and it saves only after you approve the draft. Both surfaces share one main-only preamble (INTERVIEW_PREAMBLE) and the hidden/visible split; the project surface adds buildListInterviewPrompt and the tasks-v2:launch-list-agent / tasks-v2:build-list-agent-prompt channels. Still behind the Tasks Labs flag; invariants live in .claude/memory/contracts/tasks-v2-session-types-contract.md.
Clarify & enrich
A seventh agent session type, Clarify & enrich, is the whole-list groomer — it turns a messy, opaque task list into one an AI (or a stranger) could actually act on. Unlike the other types it is project-launch only: it never appears on a single-task launch (the picker filters it via LIST_ONLY_SESSION_TYPES), because its whole job is to walk the list, not one task.
Launch it from a project's "Launch agent…" menu (the generalized launch popup in list mode) and pick Clarify & enrich. The spawned agent walks the project's open tasks one at a time and, for each, shows its clean read and offers a three-way choice: A. Skip (already clear — leave it), B. Clarify, or C. Spawn. On Clarify it asks a few simple questions about a vague task, shows a before → after rewrite that preserves your wording and intent, and — only after you approve that task — rewrites the task's own text in place (POST /tasks-v2/update); where it helps it also offers to add a subtask (POST /tasks-v2/create) or attach a context note (POST /tasks-v2/context/create), but the description is the point. On Spawn it writes a ready-to-run prompt for the task (objective, context, definition of done, a do-it instruction) as a copyable block for you to launch a fresh session with — it never runs the task or launches a session itself (the same Spawn option Define & enrich offers). It handles an empty / already-clear list ("nothing to groom") and a long, truncated list (grooms what it can see, offers to continue) gracefully.
Like Interview for context, it's a full background Claude session in the hidden Tasks workspace (real tokens per turn, cost-gated by the Launch button) — not the cheap bounded Break it down interview. It shares the same main-only preamble mechanism (CLARIFY_PREAMBLE, never shipped to the renderer) and the hidden/visible split, and reuses the existing buildListInterviewPrompt + tasks-v2:launch-list-agent machinery — no new IPC channel, Zod schema, DB table, or Labs toggle (it rides the existing Tasks flag). So it can edit the right rows, the project prompt's hidden background task list carries each task's id (only for this type). Still behind the Tasks Labs flag; invariants (clarify-groomer, clarify-list-only) live in .claude/memory/contracts/tasks-v2-session-types-contract.md.
For agents
Per-task agent chat
Any task can host its own Claude agent chat. On a focused outliner row, the "Launch agent" button or the g key runs open-or-launch:
- If the task already has a chat, it reveals in the Sessions tab and selects it — free, no spawn, no pop-out.
- If it doesn't, an editable launch-prompt popup opens, showing the visible task message the agent starts from (the task text + its open subtasks) — editable — plus a session-type picker (Custom / Break it down / Work through resistance / Tame the overwhelm / Eliminate, automate, delegate / Interview for context — see Tame the overwhelm, Eliminate, automate, delegate and Interview for context). A repo picker (shown only when you have real repos) lets you choose where the task runs — default: the hidden Tasks workspace, or pick one of your real repos to run the task inside that codebase instead. The agent ALSO receives a hidden brief (coaching guidance for the chosen type + your project / attached / inherited context); a collapsed "Show what the agent will also receive" line lets you expand and read exactly that appended context before launching (lazily fetched, updates with the picked type, and never exposes a token). You review/edit and hit Launch; only then does Omniscio spawn the agent — in the background, landing in the Sessions tab. The popup is the token-cost gate: nothing is sent and no tokens are spent until you press Launch. Closing it — whether you Launch or Cancel — hands the keyboard back to the task list, so the arrow keys keep moving the highlight right away (it traps focus while open, like every Tasks popup; returning focus to the list on close is the focus-recovery contract's I8 invariant — and returning to the app window while Tasks is open reclaims the keyboard for the list too, its I9 invariant).
The agent boots already briefed: it's handed the list's master context, any context inherited from ancestor tasks (the M3 subtree tier), the task's text, its open subtasks, its own attachments, the full roster of your projects (each with its id + open-task count, its own project marked [current]), and a cheat-sheet of the task API routes (list projects, create / update / complete / move a task between projects, attach a context note) — all with an auto-trusted token — so it can confidently read and update your tasks across the whole board, not just its own list. By default it runs in a hidden, managed "Tasks workspace" folder (__tasks_workspace__ → <userData>/tasks-workspace) — isolated from your real project repos, so a task agent can't touch code you didn't point it at. That workspace project is permanently hidden from the sidebar (it's plumbing, not a place you visit). If you deliberately pick a repo in the launch popup's destination picker, the task instead runs inside that chosen repo — the main process validates the pick is a real, session-eligible project (the same rule the "Move session to project" menu uses), so the renderer can never spawn a task into an arbitrary or virtual path. The choice is per-launch (it resets to the workspace each time — no persistence).
The chat lives in the Sessions tab (not as a separate active session), so launching one keeps you in Tasks and runs in the background rather than throwing a panel over your list (the old desktop right-pane pop-out was removed). The prompt is composed by the shared buildTaskAgentPrompt (project context + inherited context + task + open subtasks + attached context + project roster + CLI route cheat-sheet) — the same builder the popup previews, so what you edit is byte-identical to an un-edited launch, and your edited text is used verbatim. Launching reuses an existing session rather than spawning a duplicate. The spawned session is also auto-attached to the task as session-kind context — the same link the manual "Attach a session" makes — so it shows up in the task's 📎 count chip with no extra step. The link is idempotent (a re-launch never double-links) and best-effort (it can never block or fail the paid spawn); a multi-select batch launch attaches its one session to every selected task. This is distinct from the sessions.task_id "launched-from-this-task" binding (which powers the Sessions-tab reveal): that was always set, but it never populated the attachment list the 📎 chip reads — so before, a launched session showed no attachment until you attached it by hand. The whole feature stays behind the Tasks Labs flag like the rest of the surface.
gonly fires in "command mode" (a focused row you're not editing) — while you're typing in a row, "g" is just the letter g. This is Milestone 4 of the agent-chat design (= roadmap M0); the full hotkey layer, a persistent activity log, and the visual polish are later milestones, not yet built. The context-attachment stack below is Milestone 3. The roadmap M4 (a different thing) is Break it down, just below.
The Sessions tab — every task agent in one place
The panel's left column carries a "Tasks | Sessions" tab strip (TasksV2PanelTabs.tsx, the shared SegmentedControl variant="tabs"). Tasks is the outliner you already know (unchanged); Sessions turns the left column into a full AI-sessions sidebar for your task agents — the same list experience as the KMS and Mind Map "Sessions" tabs, not a bespoke one.
A live count rides on the "Sessions" tab. When task agents are running (green), waiting on you (amber), or errored / stuck (red), a small colored count appears right on the Sessions tab label (or, on a phone where the tab strip is folded away, on the header's Sessions icon) — the same colored-number style your project rows use — so you can tell at a glance that agents need you without leaving the Tasks list. It shows only non-zero counts (nothing when everything is idle) and hides while Focus Mode is armed. This is a universal touch: the same badge appears on every "Sessions" tab across Omniscio (KMS, Mind Map, Flowchart, Whiteboard, SMS), because they all share one session-host — it reads the one canonical session count the sidebar and inbox use, so the number never disagrees with them (SessionsTabCountBadge.tsx; see .claude/memory/contracts/session-host-contract.md invariant 13).
Every Claude agent you launch on a task (the Launch agent button / g — see Per-task agent chat) runs in the hidden Tasks workspace project (__tasks_workspace__) and lands here in the background — the Sessions tab is its home. (The one exception: a task you deliberately launch into a real repo via the destination picker surfaces under that repo's sessions instead of this workspace-scoped tab — but the task row's own "open agent" button still reopens it, since the link is by session id, not project.):
- A sectioned, sorted list of every task agent — Needs You / live / paused / snoozed / archived — with the same right-click management menu (pause · archive · rename · pin · snooze) as the main sidebar. Clicking a session opens its chat in the Sessions-tab pane (desktop) or a full-screen chat (mobile) — it sets the view-local
detailSessionId(TaskspanelOwnsLayout, so it owns its own layout and never switches you into the hidden workspace project). While that chat is on screen it is also mirrored into the global active-session slice — viasetHostedActiveSession, a project-switch-free set that keeps you in the panel — so the standard session hotkeys act on the open chat: E / Ctrl+W archive it (the archived chat stays shown, grayed, with an Undo toast), P pauses, H snoozes. When you close the chat or switch back to the Tasks tab the mirror is released (so on the Tasks tab,e/xstill means "finish the highlighted task", not "archive a session"). See.claude/memory/contracts/session-host-contract.mdinvariant 15. This is the agent chat's only home: a fresh launch lands it here in the background, and reopening a task's chat reveals it here, never as a pop-out beside the list. - A "+ New session" button launches a fresh task agent into the Tasks workspace (source
tasks-v2-session-host), for agent work not tied to a single row.
This reuses Omniscio's shared session-host seam (useProjectSessionHost + SessionHostSidebar) end to end — the new tasks-v2-session-host.ts hook just points that machinery at the Tasks-workspace project; there is no hand-rolled session row or menu (the session-host contract forbids it). It adds no new database table, IPC channel, or Labs toggle — it surfaces sessions that already exist. On a phone there is no tab strip (it wasted a whole row): Sessions is reached from a Sessions icon in the header — carrying the same live count badge — and the full-width Sessions list is fronted by a "← Tasks" back header that returns you to your tasks. Like the rest of Tasks it stays behind the Tasks Labs flag.
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