AI Attempts (agentic runs)
Last updated: 2025-12-30What an Attempt is
- An Attempt is a single agent run tied to a specific card on a project’s board.
- Attempts encapsulate:
- Status (
queued,running,stopping,succeeded,failed,stopped). - Associated project/board/card identifiers.
- Git worktree path and branch information.
- Logs and conversation history (stored as structured JSONL).
- Status (
- Attempt data is stored in SQLite via Drizzle ORM (server layer). Core modules access data through abstract repository interfaces (
core/src/repos/interfaces.ts).
Lifecycle and events
- Attempts are created and controlled via the Attempts service and routes:
POST /projects/:projectId/cards/:cardId/attempts– start a new Attempt.GET /projects/:projectId/cards/:cardId/attempt– fetch the latest Attempt for a card.GET /attempts/:id– detailed Attempt info.PATCH /attempts/:idwith{ status: "stopped" }– request graceful stop.POST /attempts/:id/messages– send follow-up prompts into an existing Attempt.GET /attempts/:id/logs– stream Attempt logs.DELETE /attempts/:id/resetwith{ deleteWorktree: boolean }– reset an Attempt by clearing conversation history, logs, and todos. Returns{ attempt, worktreeDeleted }. Cannot reset running or stopping Attempts.POST /projects/:projectId/cards/:cardId/ai-review– trigger AI review for a completed Attempt.
- The underlying runner emits a stream of events:
attempt.queuedattempt.startedattempt.status.changedattempt.log.appendedattempt.conversation.appendedattempt.session.recordedattempt.todos.updatedattempt.completedattempt.autocommit.requestedattempt.stoppedattempt.resetattempt.aiReview.requestedattempt.aiReview.completed
- WebSocket listeners subscribe to these events and forward them to connected clients so the board, Attempts panel,
messages, and logs stay in sync. When an Attempt status changes to
failed, the board displays a “Failed” badge with destructive styling on the associated card to make issues immediately visible.
Worktrees and isolation
- Every Attempt runs inside a dedicated Git worktree:
- Located under
$HOME/.cache/kanban-ai/worktrees/<project>/<attempt>/....
- Located under
- When starting or resuming an Attempt, the service:
- Ensures the base project repository is present.
- Creates a new worktree and branch if needed.
- Emits
worktree.createdwith metadata (project, attempt, paths).
- Cleanup:
- When a card is moved to Done and its Attempt is finished, a listener calls
cleanupCardWorkspace, which removes the worktree and deletes its branch. - After successful cleanup, the Attempt row remains in the database but its
worktreePathfield is set toNULLso completed Attempts no longer claim a live worktree on disk. - When a project is deleted, Filesystem listeners purge all worktrees for that repository.
- When a card is moved to Done and its Attempt is finished, a listener calls
Conversations, processes, and logs
- The client surfaces Attempt activity through three main views:
- Messages – live conversation with the agent; uses
attempt.conversation.appendedevents. - Processes – summaries of dev/automation processes (e.g. project dev scripts), including controls to re-run or stop them.
- Logs – structured log output, including script output and internal diagnostics via
attempt.log.appended. - Todos panel – a read-only list of the latest AI-generated todos for the Attempt, shown next to Open editor
as
<completed>/<total> Todos; it is powered byattempt.todos.updatedevents and is kept separate from assistant messages so todo text is never reused as commit message content.
- Messages – live conversation with the agent; uses
- Follow-up prompts:
- Sent via
POST /attempts/:id/messages. - Reuse the same Attempt session so the agent can use prior context.
- Sent via
- Stopping Attempts:
PATCH /attempts/:idwithstatus: "stopped"triggersattempt.stopped.- The runner and listeners update status so the UI shows the Attempt as stopped.
- Retrying failed Attempts:
- Failed Attempts can be retried directly from the Card Inspector’s Attempts tab.
- The Retry button re-queues the Attempt using the same agent and profile configuration.
- This allows users to quickly retry failed work without recreating the ticket or manually starting a new Attempt.
AI Review workflow
- After an Attempt completes successfully, users can request an AI review of the code changes:
- Click the “AI Review” button in the Card Inspector or card menu.
- The card moves to the AI Review column.
- An AI agent analyzes the git diff between the base branch and the Attempt branch.
- The agent provides either:
- Approval → card moves to Human Review with “AI Approved” badge, iteration counter resets to 0.
- Changes requested → card moves back to In Progress, iteration counter increments, and the Attempt resumes with AI feedback injected as a follow-up prompt.
- The review summary and findings appear in the conversation view as a special
reviewconversation item.
- Configuration:
- AI Review prompt – customize the review prompt in project settings (defaults to code quality, bugs, consistency checks).
- Max iterations – configure maximum review cycles before auto-advancing to Human Review (default: 3).
- Agent profile mapping – assign a specific agent profile for AI review tasks via the inline agent profile mapping in project settings.
- The AI review loop prevents infinite iterations; after reaching the max iteration limit, cards advance to Human Review even if issues remain, ensuring human oversight.
Git & PR integration for Attempts
- Attempt worktrees expose Git operations through dedicated endpoints:
GET /attempts/:id/git/statusGET /attempts/:id/git/filePOST /attempts/:id/git/commitPOST /attempts/:id/git/pushPOST /attempts/:id/git/merge
- The UI uses these to power the Changes dialog, Commit flow, and merge helpers for Attempt branches.
- Pull Requests:
POST /projects/:projectId/pull-requestscan be called withbranch,attemptId, andcardIdso PRs are tied back to the originating Attempt and card.- Older attempt-specific PR routes have been removed; everything flows through project-scoped PR endpoints.