Files
vibe-kanban/frontend/src/i18n/locales/en/tasks.json
Alex Netsch 67711e77f4 Show error when remote branch status is unavailable (Vibe Kanban) (#1825)
* I've completed the implementation. Here's a summary of the changes:

## Summary

### Changes Made

1. **`frontend/src/hooks/useBranchStatus.ts`**
   - Modified to return `{ data, error, isError, isLoading, refetch }` instead of just the query result
   - This exposes the error state to consuming components

2. **`frontend/src/components/tasks/Toolbar/GitOperations.tsx`**
   - Added `branchStatusError` prop to interface
   - Removed `hasConflictsCalculated` from the "Change target branch" button's disabled condition - now it stays enabled even during errors, allowing users to recover
   - Changed the actions section from hiding completely when `selectedRepoStatus` is null to showing an error message when there's a `branchStatusError`

3. **`frontend/src/components/dialogs/tasks/GitActionsDialog.tsx`**
   - Extracted `error` from `useBranchStatus` and passes it to `GitOperations` as `branchStatusError`

4. **`frontend/src/pages/ProjectTasks.tsx`**
   - Updated `DiffsPanelContainer` to accept and pass `branchStatusError`
   - Extracted `branchStatusError` from `useBranchStatus` hook
   - Passes the error through to `DiffsPanelContainer`

5. **i18n translation files** (all 6 locales: en, es, ja, ko, zh-Hans, zh-Hant)
   - Added `git.errors.branchStatusUnavailable` translation string

### Behavior Changes

- **Before**: When branch status API failed, git operations (Merge, PR/Push, Rebase buttons) were completely hidden
- **After**:
  - An error message is shown: "Unable to fetch branch status. You can still change the target branch."
  - The "Change target branch" button remains enabled, allowing users to recover from deadlock situations
  - Users can see something went wrong instead of the UI silently failing

* Cleanup script changes for workspace cdcbb9c6-fc9f-45bf-9c30-0e432d06cccf

* Simplify useBranchStatus hook return

Return useQuery result directly instead of manually constructing an object.
The useQuery hook already returns all needed properties (data, error, isError, isLoading, refetch).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Restore hasConflictsCalculated check for change target branch button

The conflict check wasn't needed for the branch status error fix.
Keeping it prevents changing target branch during active git conflicts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 13:42:15 +00:00

522 lines
19 KiB
JSON

{
"loading": "Loading tasks...",
"empty": {
"noTasks": "No tasks found for this project.",
"createFirst": "Create First Task",
"noSearchResults": "No tasks match your search."
},
"actions": {
"addTask": "Add task"
},
"filters": {
"sharedToggleAria": "Toggle shared tasks",
"sharedToggleTooltip": "Show/hide shared content"
},
"rebase": {
"common": {
"action": "Rebase",
"inProgress": "Rebasing...",
"withTarget": "Rebase onto {{branch}}"
},
"dialog": {
"title": "Rebase Task Attempt",
"description": "Choose a new base branch to rebase this task attempt onto.",
"upstreamLabel": "Upstream Branch",
"upstreamPlaceholder": "Select an upstream branch",
"targetLabel": "Target Branch",
"targetPlaceholder": "Select a target branch",
"advanced": "Advanced"
},
"status": {
"inProgress": "Rebase in progress{{counts}}",
"needed": "Rebase needed{{dirty}}{{counts}}",
"dirtyMarker": " (dirty)"
}
},
"branches": {
"changeTarget": {
"dialog": {
"title": "Change target branch",
"description": "Choose a new target branch for the task attempt.",
"placeholder": "Select a target branch",
"action": "Change Branch",
"inProgress": "Changing..."
}
}
},
"repos": {
"changeRepo": {
"dialog": {
"title": "Change Repository",
"description": "Choose a repository for git operations.",
"label": "Repository",
"placeholder": "Select a repository",
"action": "Change Repository"
}
},
"selector": {
"placeholder": "Select repository",
"empty": "No repositories available"
}
},
"preview": {
"title": "Preview",
"selectAttempt": "Select an attempt to see preview",
"troubleAlert": {
"title": "We're having trouble previewing your application:",
"item1": "Did the dev server start successfully? There may be a bug you need to resolve, or perhaps dependencies need to be installed.",
"item2": "Did your dev server print the URL and port to the terminal in the format",
"item2Suffix": "? (this is how we know it's running)",
"item3": "Have you installed the Web Companion (required for click-to-edit)? If not, please",
"item3Link": "follow the installation instructions here"
},
"noServer": {
"title": "No dev server running",
"startPrompt": "Please start a dev server to see the preview",
"setupPrompt": "To use the live preview and click-to-edit, please add a dev server script to this project.",
"companionPrompt": "For click-to-edit functionality, add the browser companion to your project.",
"companionLink": "View installation guide",
"startButton": "Start Dev Server",
"editButton": "Edit Dev Script",
"stopAndEditButton": "Stop Dev Server & Resolve Issues"
},
"devScript": {
"saveAndStart": "Save & Start",
"saveOnly": "Save Only",
"saveChanges": "Save Changes",
"cancel": "Cancel",
"errors": {
"notLoaded": "Project not loaded",
"empty": "Dev script cannot be empty"
}
},
"logs": {
"title": "Dev Server Logs",
"hide": "Hide",
"show": "Show"
},
"iframe": {
"title": "Dev server preview"
},
"toolbar": {
"refresh": "Refresh preview",
"copyUrl": "Copy URL",
"openInTab": "Open in new tab",
"stopDevServer": "Stop dev server",
"clickToEdit": "Click to edit URL",
"resetUrl": "Reset to detected URL"
}
},
"diff": {
"viewModes": {
"inline": "Inline view",
"split": "Split view"
},
"ignoreWhitespace": "Ignore whitespace changes",
"errorLoadingDiff": "Failed to load diff: {{error}}",
"expandAll": "Expand all diffs",
"collapseAll": "Collapse all diffs",
"filesChanged_one": "{{count}} file changed",
"filesChanged_other": "{{count}} files changed",
"noChanges": "No changes have been made yet"
},
"taskPanel": {
"noTaskSelected": "No task selected",
"loadingAttempts": "Loading attempts...",
"errorLoadingAttempts": "Failed to load attempts",
"attemptsCount": "Attempts ({{count}})",
"noAttempts": "No attempts yet"
},
"processes": {
"selectAttempt": "Select an attempt to view execution processes.",
"errorLoadingUpdates": "Failed to load live updates for processes.",
"reconnecting": "Reconnecting...",
"loading": "Loading execution processes...",
"noProcesses": "No execution processes found for this attempt.",
"processId": "Process ID: {{id}}",
"deleted": "Deleted",
"deletedTooltip": "Deleted by restore: timeline was restored to a checkpoint and later executions were removed",
"agent": "Agent:",
"exit": "Exit: {{code}}",
"started": "Started: {{date}}",
"completed": "Completed: {{date}}",
"detailsTitle": "Process Details",
"backToList": "Back to list",
"loadingDetails": "Loading process details...",
"errorLoadingDetails": "Failed to load process details. Please try again.",
"copyLogs": "Copy logs",
"logsCopied": "Copied!"
},
"taskHeader": {
"editTask": "Edit task",
"deleteTask": "Delete task",
"closePanel": "Close panel"
},
"navigateToParent": "Navigate to parent task attempt",
"toolbar": {
"actions": "Actions",
"noAttempts": "No attempts yet",
"startFirstAttempt": "Start your first attempt to begin working on this task",
"startAttempt": "Start Attempt"
},
"followUp": {
"stop": "Stop",
"clearReviewComments": "Clear Review Comments",
"resolveConflicts": "Resolve conflicts",
"send": "Send",
"unqueuing": "Unqueuing…",
"edit": "Edit",
"queuing": "Queuing…",
"queueForNextTurn": "Queue for next turn",
"queue": "Queue",
"cancelQueue": "Cancel Queue",
"queuedMessage": "Message queued - will execute when current run finishes",
"runSetupScript": "Run setup script",
"runCleanupScript": "Run cleanup script",
"noSetupScript": "No setup script configured for this project",
"noCleanupScript": "No cleanup script configured for this project",
"scriptsDisabledWhileRunning": "Cannot run scripts while a process is running"
},
"todos": {
"title_one": "Todos ({{count}})",
"title_other": "Todos ({{count}})"
},
"attempt": {
"actions": {
"openInIde": "Open in IDE",
"openMenu": "Open menu",
"startDevServer": "Start dev server",
"stopDevServer": "Stop dev server"
},
"labels": {
"attempt": "Attempt",
"agent": "Agent",
"branch": "Branch",
"diffs": "Diffs",
"summaryAndActions": "Summary & Actions"
},
"agent": "Agent",
"path": "Path",
"openInEditor": "See changes in {{editor}}",
"copied": "Copied!",
"clickToCopy": "Copy worktree path",
"stopDev": "Stop Dev",
"pauseDev": "Pause Dev",
"startDev": "Start Dev",
"viewDevLogs": "View dev server logs",
"stopping": "Stopping...",
"stopAttempt": "Stop Attempt",
"newAttempt": "New Attempt",
"viewHistory": "View attempt history",
"createSubtask": "Create Subtask",
"preview": "Preview",
"diffs": "Diffs",
"gitActions": "Git Actions",
"tryAgain": "Try Again",
"runSetup": "Run Setup",
"setupHelpText": "{{agent}} isn't setup correctly. Click 'Run Setup' to install it and login.",
"devScriptMissingTooltip": "To start the dev server, add a dev script to this project"
},
"git": {
"labels": {
"taskBranch": "Task Branch"
},
"branch": {
"current": "current"
},
"forcePushDialog": {
"title": "Force Push Required",
"description": "The remote branch{{branchLabel}} has diverged from your local branch. A regular push was rejected.",
"warning": "Force pushing will overwrite the remote changes with your local changes. This action cannot be undone.",
"note": "Only proceed if you're certain you want to replace the remote branch history.",
"error": "Failed to force push"
},
"status": {
"commits_one": "commit",
"commits_other": "commits",
"conflicts": "Conflicts",
"upToDate": "Up to date",
"ahead": "ahead",
"behind": "behind"
},
"states": {
"merged": "Merged!",
"merging": "Merging...",
"merge": "Merge",
"rebasing": "Rebasing...",
"rebase": "Rebase",
"pushed": "Pushed!",
"pushing": "Pushing...",
"push": "Push",
"forcePush": "Force Push",
"forcePushing": "Force Pushing...",
"creating": "Creating...",
"createPr": "Create PR"
},
"errors": {
"changeTargetBranch": "Failed to change target branch",
"pushChanges": "Failed to push changes",
"mergeChanges": "Failed to merge changes",
"rebaseBranch": "Failed to rebase branch",
"branchStatusUnavailable": "Unable to fetch branch status. You can still change the target branch."
},
"pr": {
"open": "Open PR #{{number}}",
"number": "PR #{{number}}"
},
"actions": {
"title": "Git Actions",
"prMerged": "PR #{{number}} is already merged",
"loginRequired": {
"title": "Sign in to manage git actions",
"description": "Sign in to Vibe Kanban so you can push branches, merge changes, or open pull requests for this task.",
"action": "Sign in"
}
}
},
"createAttemptDialog": {
"title": "Create Attempt",
"description": "Start a new attempt with a coding agent. A git worktree and task branch will be created.",
"baseBranch": "Base branch",
"loadingBranches": "Loading branches...",
"selectBranch": "Select branch",
"error": "Failed to create attempt. Please try again.",
"creating": "Creating...",
"start": "Start"
},
"repoBranchSelector": {
"label": "Base branch"
},
"attemptRepoSelector": {
"label": "Repositories",
"addButton": "Add",
"empty": "No repositories selected. Add at least one repository.",
"selectBranch": "Select branch",
"addRepo": {
"title": "Select Git Repository",
"description": "Choose a git repository to add to this attempt"
}
},
"viewProcessesDialog": {
"title": "Execution processes"
},
"viewRelatedTasksDialog": {
"title": "Related tasks",
"empty": "No related tasks for this attempt",
"error": "Failed to load related tasks",
"tasksCount": "Tasks ({{count}})",
"columns": {
"title": "Title",
"description": "Description",
"status": "Status"
}
},
"attemptHeaderActions": {
"preview": "Preview",
"diffs": "Diffs",
"relatedTasks": "Related tasks"
},
"actionsMenu": {
"attempt": "Attempt",
"openInIde": "Open attempt in IDE",
"viewProcesses": "View processes",
"viewRelatedTasks": "View related tasks",
"createNewAttempt": "Create new attempt",
"createSubtask": "Create subtask",
"gitActions": "Git actions",
"editBranchName": "Edit branch name",
"task": "Task",
"share": "Share",
"reassign": "Reassign",
"stopShare": "Stop share",
"duplicate": "Duplicate"
},
"editBranchName": {
"dialog": {
"title": "Edit Branch Name",
"description": "Enter a new name for the branch. Cannot rename if an open PR exists.",
"branchNameLabel": "Branch Name",
"placeholder": "e.g., feature/my-branch",
"renaming": "Renaming...",
"action": "Rename Branch"
}
},
"stopShareDialog": {
"title": "Stop Sharing Task",
"description": "Stop sharing \"{{title}}\" with your organization?",
"warning": "Stops sharing the task with your organization, but keeps your local task.",
"confirm": "Stop share task",
"inProgress": "Stop sharing...",
"genericError": "Failed to stop sharing task. Please try again."
},
"shareDialog": {
"title": "Share Task",
"description": "Share \"{{title}}\" with your organization?",
"success": "Task shared successfully.",
"genericError": "Failed to share task. Please try again.",
"loadingSystem": "Loading account status...",
"loginRequired": {
"title": "Sign in to continue",
"description": "You need to sign in before you can share tasks. We will redirect you to the sign-in page.",
"action": "Go to sign in"
},
"githubRequired": {
"title": "Connect GitHub",
"description": "Connect your GitHub account to share tasks. This project must have a remote repository on GitHub.",
"action": "Connect GitHub"
},
"linkProjectRequired": {
"description": "Link this project to an organization before sharing tasks.",
"action": "Link Project"
},
"confirmationTitle": "Confirm sharing",
"confirmationBody": "Sharing will publish this task to your shared workspace.",
"cancel": "Cancel",
"confirm": "Share task",
"inProgress": "Sharing...",
"closeButton": "Close"
},
"createPrDialog": {
"title": "Create GitHub Pull Request",
"description": "Create a pull request for this task attempt on GitHub.",
"titleLabel": "Title",
"titlePlaceholder": "Enter PR title",
"descriptionLabel": "Description (optional)",
"descriptionPlaceholder": "Enter PR description",
"baseBranchLabel": "Base Branch",
"loadingBranches": "Loading branches...",
"selectBaseBranch": "Select base branch",
"draftLabel": "Create as draft",
"autoGenerateLabel": "Auto-generate PR description with AI",
"creating": "Creating...",
"createButton": "Create PR",
"errors": {
"insufficientPermissions": "Insufficient permissions. Please ensure the GitHub CLI has the necessary permissions.",
"repoNotFoundOrNoAccess": "Repository not found or no access. Please check your repository access and ensure you are authenticated.",
"failedToCreate": "Failed to create GitHub PR",
"gitCliNotLoggedIn": "Git is not authenticated. Run \"gh auth login\" (or configure Git credentials) and try again.",
"gitCliNotInstalled": "Git CLI is not installed. Install Git to create a PR.",
"targetBranchNotFound": "Target branch '{{branch}}' does not exist on remote. Please ensure the branch exists before creating a pull request."
},
"loginRequired": {
"title": "Sign in to create a pull request",
"description": "You need to sign in before you can open a pull request for this task. We'll take you to the sign-in page.",
"action": "Sign in"
}
},
"showcases": {
"taskPanel": {
"companion": {
"title": "Vibe Kanban Companion Point-and-Click",
"description": "Click any UI component in the preview window to select it precisely. The coding agent receives exact DOM selectors and component hierarchy, eliminating ambiguous feedback."
},
"installation": {
"title": "Dev Server & Companion Installation",
"description": "Set a dev server command for previews, with a setup script configurable in settings. Use a coding agent to automatically install the Vibe Kanban web companion."
},
"codeReview": {
"title": "Built-in Code Review",
"description": "Add line-specific comments directly in the diffs view with the plus icon. All feedback is collected and sent as a complete review to the coding agent."
},
"pullRequest": {
"title": "Create PR from Task",
"description": "Merge your changes or create pull requests directly from task attempts. The PR dialog pre-fills title and description from your task details for streamlined workflows."
},
"tags": {
"title": "Custom Prompt Tags",
"description": "Save custom prompts as tags and embed them within new tasks or follow-up messages. Reuse common instructions to maintain consistency across your workflow."
}
},
"buttons": {
"previous": "Previous",
"next": "Next",
"finish": "Finish"
}
},
"githubComments": {
"dialog": {
"title": "Select GitHub Comments",
"noComments": "No comments found on this PR",
"selectAll": "Select All",
"deselectAll": "Deselect All",
"add": "Add",
"selectedCount": "{{selected}} of {{total}} selected"
},
"card": {
"review": "Review",
"tooltip": "Click to view on GitHub, double-click to edit"
}
},
"taskFormDialog": {
"createTitle": "Create New Task",
"editTitle": "Edit Task",
"titlePlaceholder": "Task title...",
"descriptionPlaceholder": "Add more details (optional). Type @ to search files.",
"statusLabel": "Status",
"statusOptions": {
"todo": "To Do",
"inprogress": "In Progress",
"inreview": "In Review",
"done": "Done",
"cancelled": "Cancelled"
},
"startLabel": "Start",
"attachImage": "Attach image",
"dropImagesHere": "Drop images here",
"updating": "Updating...",
"updateTask": "Update Task",
"starting": "Starting...",
"creating": "Creating...",
"create": "Create",
"discardDialog": {
"title": "Discard unsaved changes?",
"description": "You have unsaved changes. Are you sure you want to discard them?",
"continueEditing": "Continue Editing",
"discardChanges": "Discard Changes"
}
},
"restoreLogsDialog": {
"title": "Confirm Retry",
"historyChange": {
"title": "History change",
"willDelete": "Will delete this process",
"andLaterProcesses_one": "and {{count}} later process",
"andLaterProcesses_other": "and {{count}} later processes",
"fromHistory": "from history.",
"codingAgentRuns_one": "{{count}} coding agent run",
"codingAgentRuns_other": "{{count}} coding agent runs",
"scriptProcesses_one": "{{count}} script process",
"scriptProcesses_other": "{{count}} script processes",
"setupCleanupBreakdown": "({{setup}} setup, {{cleanup}} cleanup)",
"permanentWarning": "This permanently alters history and cannot be undone."
},
"uncommittedChanges": {
"title": "Uncommitted changes detected",
"description_one": "You have {{count}} uncommitted change",
"description_other": "You have {{count}} uncommitted changes",
"andUntracked_one": " and {{count}} untracked file",
"andUntracked_other": " and {{count}} untracked files",
"acknowledgeLabel": "I understand these changes may be affected"
},
"resetWorktree": {
"title": "Reset worktree",
"enabled": "Enabled",
"disabled": "Disabled",
"disabledUncommitted": "Disabled (uncommitted changes detected)",
"restoreDescription": "Your worktree will be restored to this commit.",
"rollbackCommits_one": "Roll back {{count}} commit from current HEAD.",
"rollbackCommits_other": "Roll back {{count}} commits from current HEAD.",
"discardChanges_one": "Discard {{count}} uncommitted change.",
"discardChanges_other": "Discard {{count}} uncommitted changes.",
"untrackedPresent_one": "{{count}} untracked file present (not affected by reset).",
"untrackedPresent_other": "{{count}} untracked files present (not affected by reset).",
"forceReset": "Force reset (discard uncommitted changes)",
"uncommittedWillDiscard": "Uncommitted changes will be discarded.",
"uncommittedPresentHint": "Uncommitted changes present. Turn on Force reset or commit/stash to proceed."
},
"buttons": {
"retry": "Retry"
}
}
}