0b7bbd93d5
* feat(mcp): accept repository_url and local_path on add_branch_to_task_kandev Mirror create_task_kandev's repo-locator surface so agents can attach a branch without first looking up the repository UUID. The MCP tool now takes repository_id OR repository_url OR local_path; the service resolves alternatives via the same workspace-scoped find-or-create path used by create_task. * fix(mcp): run executor guard before repo resolution on add_branch_to_task ResolveRepositoryRef may FindOrCreateRepository / CreateRepository inside the github_url / local_path paths. Running it before requireWorktreeExecutorForBranchAdd let a rejected add_branch call on a docker/sprites/SSH task leak an orphan Repository row into the workspace. Move the executor check ahead of resolution and add a regression test that asserts ListRepositories count is unchanged after a rejected call with a brand-new github_url. * test(mcp): assert task_id default in add_branch local_path test * fix(mcp): reject multiple repo locators on add_branch_to_task resolveRepoInput applies a silent precedence (repository_id > github_url > local_path), so an agent that accidentally supplies two of the three locators got a behaviour change with no signal. Reject at the WS handler with a clear error so the mistake is surfaced. Also refresh the AddBranchToTask docstring to document the new LocalPath / GitHubURL inputs and to correct the workspace-membership check ownership (now enforced by ResolveRepositoryRef → resolveRepoInput for the alternative paths). * fix(mcp): classify resolve_repository errors as validation, not internal Failures from ResolveRepositoryRef are user-fixable input mistakes (malformed URL, unknown local_path, cross-workspace repository_id). Without a matching case the wrapper "resolve repository: ..." message fell through to ErrorCodeInternalError, so an agent that supplied e.g. a bitbucket URL saw a server-fault code instead of a validation error it could correct. * fix(mcp): narrow add_branch error classification + use wire field name Two follow-ups to the round-3/4 review feedback: - Mutual-exclusion error mentioned the MCP tool alias `repository_url` but the WS handler sees the wire field `github_url`. A direct WS caller would see an error naming a field it never passed. - The broad `"resolve repository: "` prefix classified ALL wrapped errors as Validation, including DB / system failures from CreateRepository / ListRepositories inside ResolveRepositoryRef. Narrow to specific user-fixable patterns (GitHub URL parse failures, cross-workspace repository_id) so genuine internal errors no longer masquerade as validation rejections. * fix(mcp): mutual-exclusion check at MCP tier names agent-facing alias WS-tier rejection works for direct WS callers but its error mentions github_url, the wire field — confusing for MCP agents that supplied repository_url. Move the check up to addBranchToTaskHandler so the error reads "pass at most one of repository_id, repository_url, local_path" using the names the agent actually typed. WS handler still validates as defense-in-depth. --------- Co-authored-by: Kandev Agent <agent@kandev.dev>