A task is a running agent session. A backlog item is something someone wants done. Warpforge keeps them separate on purpose, and links them when work actually starts — so your backlog stays a list of intent, not a graveyard of stale agent runs.
The backlog
Every project has one, and it can be fed straight from where your team already tracks work.
Connect a tracker
Create a personal access token (classic with repo + read:project, or fine-grained) at github.com/settings/tokens and paste it in Settings → Trackers → GitHub. Stored in OS keychain.
Deprecated:
ghCLI session (gh auth login) still works as a fallback if no token is set, but it spawns a process per request, is flaky for bulk sync, and will be removed in a future version. Prefer a token.
A project’s open issues import when you open it, and refresh on Sync.
Connect with a personal API key, which is stored in your OS keychain — not in a config file, not in the database.
A Linear key is account-wide, so each project picks the Linear team it reads from. Until you pick one, that project imports nothing from Linear.
The backlog works standalone. Some work never belongs in a tracker — “try this later,” “look at why that’s slow” — and local items are first-class here.
Whichever you use, new items are created the same way: the destination is a chip on the form. Local, GitHub, or Linear — one form, one list, one shape.
Working the list
The backlog loads more as you scroll, and each row reads across a single line: title, status, priority, tracker, assignee, and when it last changed.
- Search titles and bodies; filter by status, priority, tracker, or assignee — your own account is offered first, since most of the time you’re looking for your own work.
- Clicking a row opens details beside the list, not somewhere else. The full description renders with any screenshots from the issue shown inline, plus assignee, timestamps, and a link straight to the issue.
- Priority is editable there. So is status — for items you wrote yourself. Issues that came from a tracker show the tracker’s status, because that’s where it’s decided.
- Escape, or a click outside, puts you back exactly where you were in the list.
From item to task
Start task turns a backlog item into an agent task and links the two. The row offers Open task from then on, so the connection survives — you can always get from the intent to the work and back.
Start in Factory starts a Factory task instead: agents make the change, test and review it, and — with Open a draft PR when done on — you get a draft pull request back; merging it marks the item done. The button is on each row and in the item’s details, and opens New Task in Factory mode with the item’s text as the prompt.
- Several items: select the rows and press Start 3 in Factory (the button counts what you picked) — one configuration, one Factory task per item.
- Everything that matches a filter: Run in Factory… in the toolbar picks items by status, source, search, or your selection, shows how many match, and starts a Factory task for each. It is a one-time batch; items added later are not picked up.
Items that already have a Factory task are skipped, and show In Factory with where they are — In Factory · Queued, In Factory · PR #41.
Agents can add to the queue too: the create_task tool files work an agent discovered but wasn’t asked to do. It lands Queued for you to triage rather than auto-running, because discovered work is exactly the work a human should look at first.
The task lifecycle
| Status | What it means |
|---|---|
| Queued | Created; the agent hasn’t started. A queued Factory task says why it is waiting. |
| Running | The agent is actively working. |
| Waiting | The agent yielded — the ball is in your court. |
| Blocked | Genuinely stuck; needs a decision or a permission grant. |
| Interrupted | Cut short by a stop; the work is incomplete. |
| Done | Finished or archived. |
The distinction that matters: Waiting is an agent choosing to hand back, Blocked is an agent that can’t proceed, and Interrupted is a run that was cut off. Three very different things that most tools show as one ambiguous “stopped.”
Mission Control
Active work across every project lives in four tabs:
| Tab | For |
|---|---|
| Live | What’s running right now, with the conversation streaming in full-width rows |
| Needs you | Everything waiting on a human — approvals, questions, review-ready work |
| Failed | What broke, so it doesn’t hide among the healthy runs |
| Pinned | The handful you’re personally tracking |
Queue actions are inline on the row, and the tab you were last on is remembered. It’s a triage screen: the point is answering what needs me right now without opening anything.
Notifications carry the answer. When something needs approval while Warpforge is in the background, the macOS notification has working Approve, Reject, and Review buttons — you don’t have to switch back to the app to unblock an agent. They stay quiet while Warpforge is focused. Answering in one place settles it everywhere: the first answer wins, so a second tap (in-app or from the banner) is refused rather than flipping the outcome, and the banner is withdrawn once the request is answered.
Tasks and git
Isolated worktrees
A task can run in its own git worktree while staying attached to the same project. Two agents on two tasks then edit two checkouts — no stashing, no branch juggling, no collisions. Worktrees live in .warpforge/worktrees/ inside the project, alongside its committed config, and a .gitignore in that folder keeps them out of git status and git add . — your own .gitignore and .git are never touched. (Tasks created by older versions keep their checkouts where they were; Warpforge still uses and hides those.)
The task’s Terminal tab opens in its worktree. The project’s services keep running from the project checkout, though, so restarting one does not pick up the task’s edits — the agent is told this when it starts, and list_runtime names the checkout each service runs from.
Choose where it starts. With Worktree on in New Task, the Worktree base chip beside it sets the base — it reads From main, From origin, On my-branch, or PR #42. It has three tabs, with a search box for long lists:
| Tab | Starts from | Notes |
|---|---|---|
| New branch | Your current branch, Latest from origin, or any other local branch | A fresh task branch is forked from it. Latest from origin fetches origin’s default branch just before the task starts. |
| Existing branch | A local branch, or a remote branch that has no local copy yet | The worktree checks out that branch itself, so a push updates it. Checking out a remote branch creates a local one that tracks it. |
| Pull request | An open pull request’s branch, forks included | A push updates the pull request. Needs the GitHub CLI signed in to list them. |
The base also decides what Merge into <base> merges into:
| Base | Merges into |
|---|---|
| Current branch, or another local branch | That branch |
| Latest from origin | Origin’s default branch, by its local name (main, not origin/main) |
| Existing branch | The branch your project checkout was on when the task started |
| Pull request | The pull request’s base branch |
Warpforge refuses a base that cannot work, in the dialog, before the task exists: a branch that is already checked out — in your project checkout or in another worktree, and the message says where — a merged pull request, or a branch that does not exist. Removing the worktree of a task on an existing branch or pull request deletes only the checkout. Your branch stays; only the task branches Warpforge creates itself are ever deleted.
Set new worktrees up automatically. A worktree: section in the project config copies files such as .env into each new worktree and runs a setup command there. The project’s Worktrees tab lists every worktree; see Worktrees tab.
If the worktree cannot be created — a full disk, say — the task does not quietly fall back to your checkout. It waits in Needs you with git’s error; send a message to run it in the project checkout instead, or delete it. Deleting a task removes its worktree, including after Warpforge restarts or updates.
When the work is good, Merge into <base> in the task’s branch menu brings it back. Warpforge fast-forwards the base when it has not moved, or writes a merge commit otherwise, and it never changes your own checkout unless the base branch is the one checked out there — and then only if that checkout is clean. A conflict leaves every branch untouched and tells you to update the task branch from the base first. By default the worktree and its branch are removed after a successful merge and the task is marked Done, because the merged work is finished; clear Remove the worktree after merging to keep both and leave the task as it is. Prefer a pull request? Push the branch and open one as usual. A task without a worktree just works in the project checkout, which is often what you want for a quick change.
Review, then commit
Nothing an agent does reaches a commit without passing your review:
- Read the diff — unified or split, hunk by hunk.
- Revert individual hunks in split view, or edit the file inline. The editor is a real editor, not a diff viewer.
- Commit or amend. The message is drafted from the actual diff in Conventional Commits form — you edit or accept it.
- Push with
--force-with-lease, and open a pull request with a title and body drafted from the branch’s outgoing commits.
Your conversations are kept
Task history and conversations persist locally. Quit the app, come back tomorrow — every conversation is still there. Running agents, services, and port-forwards stop when you quit, after Warpforge lists what is running and asks you to confirm.
See also
- Working in a task — the day-to-day craft once a task is running
- Choosing your mode — how to start the task once you know what it is
- The Factory — run items through a reviewed workflow, with a draft pull request at the end
- Projects and their runtime — the services and ports a task inherits
- Agent tools (MCP) — what an agent can do while the task runs