diff --git a/README.md b/README.md index 8eb14b09..17e3be6e 100644 --- a/README.md +++ b/README.md @@ -1,106 +1,429 @@ # ClaudeDo -A desktop task management app that executes tasks autonomously via [Claude CLI](https://docs.anthropic.com/en/docs/claude-code) in isolated git worktrees. +A Windows desktop app that turns your to-do list into a work queue for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). -Queue up coding tasks, and ClaudeDo picks them up one by one — each running in its own worktree so your main branch stays clean. +Write down what you want done. ClaudeDo picks the task up, runs Claude in an isolated git +worktree, and hands you back a diff to review. Your main branch is never touched until you +approve. -## Architecture +It looks and feels like a normal task app — lists, My Day, stars, due dates — except every +task can also be *executed*. -Two-process system communicating over SignalR: +--- -| Project | Role | -|---|---| -| **ClaudeDo.App** | Avalonia desktop entry point, DI container setup | -| **ClaudeDo.Ui** | Views, ViewModels, SignalR client (MVVM) | -| **ClaudeDo.Data** | SQLite data layer, repositories, models, GitService | -| **ClaudeDo.Worker** | ASP.NET Core hosted service, task queue, Claude CLI runner | +## Contents -``` -┌────────────────┐ SignalR ┌────────────────┐ -│ ClaudeDo.App │◄───────────►│ ClaudeDo.Worker │ -│ (Avalonia) │ 127.0.0.1 │ (ASP.NET Core) │ -│ │ :47821 │ │ -│ ┌────────────┐│ │ ┌────────────┐ │ -│ │ Ui ││ │ │ TaskQueue │ │ -│ │(ViewModels)││ │ │ Claude CLI │ │ -│ └────────────┘│ │ └────────────┘ │ -└───────┬────────┘ └───────┬────────┘ - │ │ - └──────────────┬───────────────┘ - │ - ┌───────┴───────┐ - │ ClaudeDo.Data │ - │ (SQLite) │ - └───────────────┘ -``` +- [Is this for you?](#is-this-for-you) +- [Requirements](#requirements) +- [Install](#install) +- [The window](#the-window) +- [The core loop](#the-core-loop) +- [Lists and repositories](#lists-and-repositories) +- [Writing a task](#writing-a-task) +- [Ways to run a task](#ways-to-run-a-task) +- [Watching work happen](#watching-work-happen) +- [Reviewing and merging](#reviewing-and-merging) +- [Resolving conflicts](#resolving-conflicts) +- [Worktrees](#worktrees) +- [Staying inside your usage limits](#staying-inside-your-usage-limits) +- [Your daily rhythm](#your-daily-rhythm) +- [Settings](#settings) +- [Letting Claude drive ClaudeDo](#letting-claude-drive-claudedo) +- [Updates](#updates) +- [Where your data lives](#where-your-data-lives) +- [Keyboard shortcuts](#keyboard-shortcuts) +- [Troubleshooting](#troubleshooting) +- [For developers](#for-developers) -## Tech Stack +--- -- .NET 8.0 -- Avalonia 12.0.0 (Fluent theme) -- SQLite (WAL mode) via Entity Framework Core (EF Core + Migrations) -- SignalR for real-time IPC between UI and Worker -- CommunityToolkit.Mvvm for source-generated MVVM -- Git worktrees for task isolation +## Is this for you? -## Prerequisites +ClaudeDo is built for one person running many small-to-medium coding jobs across several +repositories, mostly unattended. -- [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) -- [Claude CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated +It fits when you: + +- have a backlog of contained changes ("rename this", "add that endpoint", "fix this bug") +- want them worked on while you do something else +- still want to read every diff before it lands on `main` + +It is *not* a CI system, not a team tool, and not a chat window. There are no pull +requests, no reviewers but you, and no cloud component (unless you deliberately turn on the +optional online inbox). + +## Requirements + +- Windows 10/11 +- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code), installed and signed in + (ClaudeDo runs `claude` as *you* — it never handles your credentials) - Git +- [.NET 8 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/8.0) — the installer + itself needs it, so install it first if the installer refuses to start -## Getting Started +## Install + +Run `ClaudeDo.Installer.exe`. It downloads the current release, writes its config, and +starts the background worker. + +The wizard asks for: + +| Page | What it decides | +|---|---| +| **Welcome** | Install folder, and whether Claude may manage your tasks via MCP (see [below](#letting-claude-drive-claudedo)) | +| **Data paths** | Where the database, logs, sandboxes and worktrees live | +| **Worker** | Port, path to the `claude` binary, and whether the worker starts at logon | + +Re-running the installer later gives you **Update**, **Repair** and **Uninstall** instead +of the full wizard. Uninstall asks separately before deleting your tasks and settings. + +ClaudeDo has two parts: the window you see, and a background **worker** that does the +actual running. The worker starts at logon and keeps going even when the window is closed — +so a long task finishes whether you are watching or not. + +## The window + +Three panes ("islands"), plus a footer: + +``` +┌──────────────┬────────────────────────────┬───────────────────────────┐ +│ LISTS │ TASKS │ DETAILS │ +│ │ │ │ +│ My Day │ ▸ Add a task… ENTER │ Fix login redirect │ +│ Important │ │ ───────────────────── │ +│ Planned │ OVERDUE │ Steps ▢ ▢ ▣ │ +│ │ ● Fix login redirect │ Details (markdown) │ +│ Queue 3 │ │ Files (drop here) │ +│ Running 1 │ TASKS │ │ +│ Review 2 │ ● Add CSV export RUNNING │ Worktree · Diff · Merge │ +│ │ ● Bump deps QUEUED │ │ +│ MY LISTS │ ● Write changelog │ Output │ Git │ Session │ +│ LagerApp 7 │ ● Call the tax guy MANUAL │ ┌─────────────────────┐ │ +│ LogX 2 │ │ │ live Claude output │ │ +│ ClaudeDo 12 │ │ └─────────────────────┘ │ +├──────────────┴────────────────────────────┴───────────────────────────┤ +│ ● Online 5h 41% · 7d 22% worker log line… logs │ +└───────────────────────────────────────────────────────────────────────┘ +``` + +- **Lists** (left) — smart lists, virtual work lists, and your own lists (one per repo) +- **Tasks** (middle) — the selected list, grouped into Overdue / Tasks / Completed +- **Details** (right) — everything about the selected task, including its live output +- **Footer** — worker connection, usage pill, and the latest worker log line (clickable) + +On a narrow window the side panes fold away automatically. + +The grid icon in the title bar opens **Mission Control**, a separate window for watching +several running sessions at once. + +## The core loop + +``` + write it down → queue it → Claude runs it → you review → merge + (Idle) (Queued) (Running) (Waiting for (Done) + Review) +``` + +1. **Capture.** Type into the add box. That is it — a task starts out as a plain reminder. +2. **Queue.** Right-click → *Send to queue*. The worker claims queued tasks in order, as + many at a time as *Max parallel executions* allows. +3. **Run.** ClaudeDo creates a git worktree off your repo (branch `claudedo/`), runs + Claude there with your task as the prompt, and streams the output into the detail pane. +4. **Review.** On success the task lands in **Waiting for Review** with a committed + worktree and a diff. Nothing has touched your working copy. +5. **Merge.** *Approve & merge* merges the branch into the target you pick, then marks the + task Done. Or reject it with feedback, park it, or cancel it. + +A task that fails is marked **Failed** and keeps its worktree and its log, so you can look +at what happened and either continue the same session or reset and retry from scratch. + +## Lists and repositories + +A list becomes *runnable* by giving it a **working directory** — a git repo. Tasks in that +list get worktrees off that repo; tasks in a list without a working directory can still be +run, but in a scratch sandbox with no git. + +- **Add repos as lists** (`Repositories` menu, or the folder icon) scans folders you point + it at and creates one list per git repo it finds. This is the fastest way to get started. +- **List settings** (right-click a list) sets the name, working directory, default commit + type, the agent defaults for that list, and an optional verify command. +- **Manual list** — mark a list as reminders-only. New tasks in it start out manual, so + automation never touches them. Good for a "Errands" or "Phone calls" list. +- Drag a task onto another list to move it. ClaudeDo refuses to move a running task and + warns you when the two lists point at different repos. + +**Smart lists** are always there: + +| List | Contains | +|---|---| +| **My Day** | What you (or the daily prep) picked for today, plus a pinned Notes row | +| **Important** | Starred tasks | +| **Planned** | Everything with a date | +| **Queue / Running / Review** | Live work — waiting, in flight, and awaiting your review | + +## Writing a task + +The detail pane is where a one-line reminder becomes a brief Claude can act on: + +- **Title + Details** — markdown, with an edit/preview toggle. This is the prompt. +- **Steps** — a checklist. Handy for you, and included when you copy the task out. +- **Files** — drag files onto the pane (or use *Add file…*) to attach reference material. + Attachments are handed to Claude as read-only paths, not pasted into the prompt. +- **Star / Schedule / Add to My Day** — the usual task-app affordances. +- **Agent settings** — per-task overrides for model, turn budget, extra system prompt, + agent file and skills. Anything you do not override shows an *inherited* badge pointing at + the list or global default. +- **Refine** — hand the task to Claude to sharpen it: it rewrites the title and details into + a proper brief. Useful when you captured something in three words. +- **Mark as manual** — a MANUAL badge; the queue, the daily prep and every automation skip + it. Use it for things only you can do. + +## Ways to run a task + +| Way | What it does | Use it when | +|---|---|---| +| **Send to queue** | Worker picks it up in order | The normal path | +| **Run now** | Skips the queue, starts immediately | You want this one first | +| **Continue** | Resumes the last session with a follow-up | "Almost right, now also…" | +| **Reset & retry** | Throws the worktree away, re-queues from scratch | The run went sideways | +| **Open ConPTY session** | Opens the *real* Claude terminal for this task in Mission Control | You want to drive it yourself, with the task as the starting brief | +| **Open planning session** | An interactive session whose job is to break the task into subtasks | The work is too big for one run | +| **Let Claude handle it** | Hands a whole list over in one go | You have a pile of small tasks | + +### Planning sessions + +A planning session is a conversation whose output is *structure*, not code. Claude creates +child tasks under the parent. You then: + +1. **Finalize plan** — children are chained (each waits for the previous one) but stay Idle. +2. **Queue plan** — when you are happy with the list, this queues them all. +3. The parent waits in **Waiting for Subtasks** until every child is terminal, then surfaces + for review once — you review and merge the *whole unit*, not each child. + +A parked planning session is remembered; the next launch offers to resume, finalize or +discard it. + +### "Let Claude handle it" + +Right-click a list → *Let Claude handle it*. You get a checkbox list of that list's open +tasks. Confirm, and one Claude session works the selection end to end: it reads them, +de-duplicates overlaps, enhances thin descriptions, queues the work, and merges the results. +It shows up as its own MANUAL task so you can see what a given run covered, and you review +the combined diff when it is finished. + +## Watching work happen + +- **Detail pane, three tabs** — *Output* (live Claude stream), *Git* (worktree, diff, + merge), *Session* (result, token/turn counts, subtask outcomes). +- **Mission Control** — one tile per running or interactive session, in Focus or Overview + mode. ConPTY tiles are the real Claude TUI, embedded: keyboard, colors, `/` commands, all + of it. *New session* opens an ad-hoc one that belongs to no task. +- **Roadblocks** — when a run gets stuck it reports a roadblock instead of silently failing. + The Session tab shows it as its own card with a reply box: answer the question and the + same session picks up where it stopped. +- **Claude is asking** — an interactive session can put a question in front of you mid-run; + answer it inline in Mission Control and the run continues. +- **Footer log strip** — the worker's latest event. Failures of your own actions flash here + too, instead of vanishing. Click it for the last 30 minutes of worker logs, with a + warnings-and-errors filter. + +## Reviewing and merging + +When a task reaches **Waiting for Review** you get four actions: + +| Action | Result | +|---|---| +| **Approve & merge** | Merges the work into the target branch, then Done | +| **Reject** | Asks for feedback and re-runs the same session with it | +| **Park** | Back to Idle so you can rewrite the task yourself | +| **Cancel** | Done with it; the worktree stays until you clean it up | + +**You have to look before you approve.** When there is a diff to inspect, *Approve & merge* +stays disabled until you have opened the diff viewer once. It re-locks after any new run. +(The quick-approve on the task row itself is a deliberate bypass for when you already know.) + +The diff viewer shows a file tree on the left and the diff on the right, and can show a +dirty worktree, a branch against its base, or a commit range. For a parent with children, +*Review combined diff* shows per-subtask diffs plus a combined preview of the whole unit. + +**Verify command** (optional, per list) — a command that must exit 0 after a merge lands +before the task is allowed to reach Done. Typically a build or a test run. If it fails, the +merge stays (nothing is rewritten behind your back) but the task is held out of Done and the +failure output is reported. + +## Resolving conflicts + +If a merge conflicts, ClaudeDo opens a three-pane merge editor in-app: + +``` +┌──────────────────┬──────────────────┬──────────────────┐ +│ MAIN │ RESULT │ INCOMING │ +│ merge target │ (editable) │ task branch │ +│ │ ▐ │ │ +│ › │ ← you build │ ‹ │ +│ │ the result │ │ +└──────────────────┴──────────────────┴──────────────────┘ +``` + +- Whole files, syntax-highlighted, scrolling in sync +- Each conflict starts *empty*. The gutter arrows toggle each side in or out — take main, + incoming, both (in the order you click), or neither +- Only conflict regions are editable in the middle pane; type your own resolution if + neither side is right +- `F8` / `Shift+F8` jump between conflicts; the ruler beside the result pane maps every + conflict in the file +- A counter tells you how many files still need attention. *Resolve & continue* is disabled + until they are all done, and *Abort merge* always leaves the target branch as it was + +Binary conflicts cannot be resolved here — ClaudeDo says so and lists the paths. + +## Worktrees + +Every run gets its own worktree, so parallel tasks never fight over your checkout. + +The **Worktrees** overview (per list or global) lists them with state, diff size, age and +outcome. From there you can show a diff, jump to the task, merge, batch-merge a selection +into one target, mark one *Kept* or *Discarded*, or force-remove a leftover. Worktrees whose +directory is gone from disk are flagged as *phantom*. + +Finished worktrees are auto-cleaned after a number of days you choose in Settings. + +## Staying inside your usage limits + +The footer pill shows your Claude usage: `5h 41% · 7d 22%`. Click it for the **Usage +Monitor**: + +- Gauges for the 5-hour session window and the 7-day windows, each with a reset countdown +- **Models** — token usage per model over a range you pick, split into ClaudeDo's own + consumption and everything else +- **Tasks** — your biggest consumers, with run counts and totals + +And the part that matters when you are asleep: the **usage limit stop**. Set a percentage +per window in Settings, and once usage reaches it the queue simply stops picking up new +tasks. Running tasks finish normally, and the queue resumes by itself as the window rolls +over. `0` turns a stop off. Manual actions — *Run now*, *Continue*, interactive and planning +sessions — are never blocked. + +## Your daily rhythm + +- **My Day** — the day's shortlist. *Clear day* empties it. +- **Prime Claude** (Settings → Prime Claude) — schedules for the days and times you pick. + At that time ClaudeDo runs a short prep session: Claude looks at your idle tasks, picks an + effort-aware subset up to your daily cap, and fills My Day. It also warms your usage + window for the day. Only runs while ClaudeDo is open; if you start the app within 30 + minutes of a scheduled time it fires right away. *Plan day* runs it on demand. +- **Notes** — a pinned row in My Day: dated bullet notes with a day navigator, for the + thoughts that are not tasks. +- **Weekly report** (`Help` menu) — pick a range (defaults to "since your standup weekday") + and Claude writes up what actually happened, from your task and session history. Paths you + do not want in reports can be excluded in Settings. + +## Settings + +Most settings exist at three levels — **global → list → task** — and the more specific one +wins. Overridden fields carry an *override* badge with a one-click reset; inherited ones say +where they come from. + +**General** +- Default instructions applied to every task +- Default model, and a **per-model table** of reasoning effort and turn budget — so `haiku` + can be cheap and short while `opus` gets room to think +- Permission mode for autonomous runs +- Max parallel executions +- Usage limit stops (see above) +- Session skills applied to every task +- Report exclusions, standup weekday +- Accent color (Moss / Peat / Sea) and language (English / German) + +**Worktrees** — sibling or central placement, auto-cleanup age, and the manual cleanup and +force-remove-all buttons. + +**Files** — open the prompt templates (system, planning, retry, daily prep, weekly report) +in your editor, and restore the bundled default agent files. + +**Skills** — install a skill from a git URL, update it, remove it. Skills selected globally, +per list and per task combine. + +**Prime Claude** — the schedules and the daily task cap. + +**Online Inbox** (optional, off by default) — mirrors your idle backlog to a server so you +can capture tasks from your phone. Disabled means zero network traffic. Enabling it needs a +URL plus a sign-in; the refresh token is stored encrypted on your machine, never in a config +file. + +## Letting Claude drive ClaudeDo + +If you allowed it during install, ClaudeDo registers itself as an MCP server with the Claude +CLI. Any Claude session on your machine can then read and manage your tasks: list and create +tasks, add subtasks, queue and cancel runs, read logs and diffs, merge, review, manage lists +and per-list config. + +Concretely, you can sit in a normal Claude Code session and say "put these five things in +the ClaudeDo backlog for the LagerApp list", or "check whether the CSV export task is done". + +The MCP surface is deliberately narrow on the dangerous end: it can start and observe work, +but it cannot rewrite your app settings, and a task with an active worktree cannot be forced +to Done behind your back. + +## Updates + +ClaudeDo checks for new releases and shows a banner when one is out. *Update now* relaunches +the installer, which stops the worker, swaps the binaries and starts it again. Your database, +worktrees and settings are preserved. You can also check manually via `Help → Check for +updates`. + +## Where your data lives + +Everything is under `%USERPROFILE%\.todo-app`: + +| Path | What | +|---|---| +| `todo.db` | Your tasks, lists, runs and worktree records (SQLite) | +| `ui.config.json` | Window and UI settings | +| `worker.config.json` | Worker settings — paths, port, worktree strategy | +| `logs/` | Worker and task logs | +| `agents/` | Your agent definition files | +| `attachments/` | Files you attached to tasks | + +`Help → About` links straight to these folders. Nothing leaves your machine unless you turn +on the online inbox. + +## Keyboard shortcuts + +| Key | Action | +|---|---| +| `Ctrl+K` | Focus search | +| `Ctrl+N` | Focus the add-task box | +| `Enter` | Add the task | +| `Esc` | Leave the current text field / close a dialog | +| `F8` / `Shift+F8` | Next / previous conflict (merge editor) | + +## Troubleshooting + +**"Worker not reachable"** — the background worker is not running. The dialog offers to +start it; `Worker → Restart worker` does the same later. If it keeps happening, re-run the +installer and choose *Repair*. + +**A task failed immediately** — usually the `claude` CLI is not signed in, or the list's +working directory is not a git repo. Check the Output tab and the footer log. + +**A task is stuck in Running after a crash** — the worker sweeps orphaned runs to Failed on +startup. Restart the worker. + +**Nothing is being picked up** — check the usage pill: if a usage stop is active the queue is +paused on purpose. Also check whether the tasks are MANUAL, blocked by a predecessor, or +scheduled for later. + +## For developers + +Architecture, build commands and per-project docs live in `CLAUDE.md` (root and one per +project under `src/`). Short version: .NET 8, Avalonia UI, SQLite via EF Core, and a +SignalR-connected worker process on `127.0.0.1:47821`. ```bash -# Build -dotnet build src/ClaudeDo.App -dotnet build src/ClaudeDo.Worker - -# Run tests -dotnet test tests/ClaudeDo.Worker.Tests - -# Run the app -dotnet run --project src/ClaudeDo.App -``` - -## How It Works - -1. Create a task in the UI and tag it with **"agent"** to mark it for automated execution. -2. The Worker picks up queued tasks and runs each one via Claude CLI in an isolated git worktree. -3. When done, the worktree can be merged, kept for review, or discarded. - -**Task status flow:** `Manual | Queued → Running → Done | Failed` - -**Worktree state flow:** `Active → Merged | Discarded | Kept` - -## Configuration - -All data and config lives under `~/.todo-app/`: - -| File | Purpose | -|---|---| -| `todo.db` | SQLite database | -| `ui.config.json` | UI settings | -| `worker.config.json` | Worker settings (worktree strategy, etc.) | -| `logs/` | Application logs | - -## Project Structure - -``` -ClaudeDo.slnx -├── src/ -│ ├── ClaudeDo.App/ # Desktop entry point -│ ├── ClaudeDo.Ui/ # Views & ViewModels -│ ├── ClaudeDo.Data/ # Data access layer -│ └── ClaudeDo.Worker/ # Background task runner -├── tests/ -│ └── ClaudeDo.Worker.Tests/ -├── schema/ -│ └── schema.sql # Database schema -└── docs/ - ├── plan.md # Architecture & design spec - ├── open.md # Verification checklist & backlog - └── improvement-plan.md # Prioritized improvements +dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj -c Release +dotnet build src/ClaudeDo.Worker/ClaudeDo.Worker.csproj -c Release +dotnet test tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj -c Release ``` ## License