* fix(github): reliable PR-task association across all launch paths
Three bugs caused inconsistent PR detection for agent-opened PRs:
- StartCreatedSession never called ensureSessionPRWatch
- Push detection bailed out when a pr_number=0 watch existed
- PR watch branch was never updated after agent branch switches
* fix: extract searchPRForExistingWatch to reduce nesting depth
* fix: address review feedback and fix e2e test timeouts
- Fix UNIQUE constraint error when associatePRFromPush was called with
an existing watch (update pr_number instead of creating new watch)
- Add UpdatePRWatchPRNumber to GitHubService interface
- Fix e2e test timeouts: increase budget to 180s, remove unnecessary
clickTab("Changes"), replace 35s hard wait with polling assertion
* fix(e2e): accept both /t/ and /s/ URL patterns in PR detection tests
Task cards in the Done column navigate to /t/<task-id> (task view),
not /s/<session-id> (session view). The toHaveURL assertion must
accept both URL patterns.
* feat(vcs): add commit body/description field to commit dialog
Add an optional description textarea below the commit title in both
desktop and mobile commit dialogs, with a dedicated AI generate button
for the description. Add builtin-commit-description utility agent and
E2E test.
* style: fix prettier formatting in mobile git controls and E2E test
* fix(e2e): use specific testid selectors for commit dialog inputs
The commit dialog now has two textboxes (title + body), so
getByRole("textbox") is ambiguous. Use getByTestId selectors
and add exact match for the Commit button.
* fix(ui): add cursor-pointer to mobile commit button
* fix(ui): remove "(optional)" from description label and "Generate" text from button
* fix(ui): match PR dialog style for commit description generate button
* feat(vcs): add AI generate button for PR title
Add builtin-pr-title utility agent and wire up a generate button
inside the PR title input, matching the commit title pattern.
Extract shared dialog field components into vcs-dialog-fields.tsx
to stay within the 600-line file limit.
* refactor(ui): unify generate buttons as icon-only sparkles inside inputs
Move AI generate buttons inside both title inputs and description
textareas (top-right corner) for a consistent look. Remove the
"Generate" label variant — all buttons are now icon-only sparkles.
* style: fix prettier formatting in utility agent generator hook
* fix(a11y): add aria-labels to generate buttons and PR title input
* ci: retrigger E2E tests
* fix(e2e): improve commit dialog button click reliability
Add exact match and enabled check before clicking the dialog
Commit button, increase close timeout.
* ci: retrigger checks
* fix(e2e): improve pre-hooks test commit button reliability
Add exact match, enabled check, and longer dialog timeout to match
the commit-body test pattern.
* fix(ui): prevent dialog field overflow and improve commit description prompt
- Add min-w-0 to relative wrappers in commit and PR dialog fields to
prevent text inputs/textareas from overflowing the dialog bounds
- Rewrite commit description prompt to use system-role framing that
prevents weaker models from adding conversational preamble
* fix: include uncommitted changes in review dialog cumulative diff
The review dialog only showed uncommitted changes instead of the full
diff from the task's base commit. Two issues combined:
1. Backend used `git diff base..HEAD` (committed only); changed to
`git diff base` which compares against the working tree.
2. Frontend gave priority to git status over cumulative diff; reversed
the merge order so cumulative diff takes precedence.
Adds E2E test with a mock-agent scenario that commits changes then
leaves uncommitted modifications, verifying the review dialog shows
the complete base→working-tree diff.
* fix(e2e): remove incorrect BASE_CONTENT assertion in review cumulative diff test
The file is created after the base commit, so the entire file shows as
added in the cumulative diff. BASE_CONTENT was replaced and doesn't
appear. The key assertion is that COMMITTED_CHANGE is visible — proving
the diff includes committed changes (not just the uncommitted portion).
* fix: address CodeRabbit review feedback
- Update 3 docstrings to reflect working-tree diff (not HEAD)
- Generate scenario list dynamically in error message
- Use data-testid selector in E2E test for resilience
* style: format E2E test file
* fix(e2e): use toContainText and click file to ensure diff is scrollable
Pierre diff viewer content inside a scroll container may not be
considered "visible" by Playwright. Switch to toContainText which
checks text presence without element-level visibility. Also click
the file in the tree to ensure its diff section is scrolled into view.
* fix(workflow): store profile IDs in task metadata for deferred auto-start
When creating a task with "Create without starting agent", the
agent_profile_id and executor_profile_id were only parsed as top-level
request fields but never persisted into task.Metadata. When the task was
later moved to a step with auto_start_agent, handleTaskMovedNoSession
read empty strings from metadata, causing PrepareSession to fail with
ErrNoAgentProfileID.
Both task creation handlers (WS and HTTP) now inject profile IDs into
task metadata when the agent is not started immediately, so deferred
auto-start works correctly.
* refactor: extract metadata keys to constants
Address CodeRabbit review: extract repeated "agent_profile_id" and
"executor_profile_id" metadata key strings into constants in
task/models, used by both the creation handlers and the orchestrator.
fix: skip environment preparer for repo-less tasks like config chat
Config chat sessions created without repository associations would crash
with "no repository path provided" when the workspace default executor
had a registered preparer (e.g. worktree). The preparer was selected
based on executor type but had no repository to work with.
Skip any environment preparer when RepositoryPath is empty — the session
falls through to the quick-chat workspace path instead.