mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
fix(i18n): localize sidebar copy and correct Japanese mistranslations (#28921)
Route hardcoded sidebar strings (cache timer, delete-worktree dialog, imported-worktrees line, remote file browser, setup-script prompt, card agents/ports/status, add-repo busy labels, batch action menus) through i18n keys, and fix literal-sense Japanese translations in ja.json. Co-authored-by: Koji Miyazawa <24467062+kojikojikojikoji@users.noreply.github.com> Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
This commit is contained in:
co-authored by
Koji Miyazawa
Neil
parent
3816457631
commit
70d81598b0
@@ -9,6 +9,7 @@ import {
|
||||
getPromptCacheCountdownForPane,
|
||||
type PromptCacheCountdownSelection
|
||||
} from './prompt-cache-timer-selection'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
|
||||
/** Resolve the soonest-expiring Claude cache once for both row visibility and countdown rendering. */
|
||||
export function usePromptCacheCountdownStartedAt(worktreeId: string, active = true): number | null {
|
||||
@@ -70,8 +71,15 @@ export default function CacheTimer({
|
||||
const warning = !expired && remainingMs <= 60_000
|
||||
|
||||
const tooltipText = expired
|
||||
? 'The next message will re-send the full context as uncached tokens'
|
||||
: `Prompt cache expires in ${label}`
|
||||
? translate(
|
||||
'auto.components.sidebar.CacheTimer.expiredTooltip',
|
||||
'The next message will re-send the full context as uncached tokens'
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.CacheTimer.expiresIn',
|
||||
'Prompt cache expires in {{time}}',
|
||||
{ time: label }
|
||||
)
|
||||
|
||||
return (
|
||||
<Tooltip>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { useAppStore } from '@/store'
|
||||
import { WorktreeForceDeleteButton } from './WorktreeForceDeleteButton'
|
||||
import { deleteWorkspacesCountLabel } from './workspace-batch-action-labels'
|
||||
|
||||
export function DeleteWorktreeDialogFooter({
|
||||
isMainWorktree,
|
||||
@@ -34,15 +35,24 @@ export function DeleteWorktreeDialogFooter({
|
||||
}): JSX.Element {
|
||||
const label = isDeleting
|
||||
? canForceDelete
|
||||
? 'Force Deleting...'
|
||||
: 'Deleting...'
|
||||
? translate(
|
||||
'auto.components.sidebar.DeleteWorktreeDialogFooter.forceDeleting',
|
||||
'Force Deleting...'
|
||||
)
|
||||
: translate('auto.components.sidebar.DeleteWorktreeDialogFooter.deleting', 'Deleting...')
|
||||
: isBatchDelete
|
||||
? `Delete ${worktreeCount} Workspaces`
|
||||
? deleteWorkspacesCountLabel(worktreeCount)
|
||||
: canDeleteAllLineage
|
||||
? `Delete ${lineageDeleteTargetCount} Workspaces`
|
||||
? deleteWorkspacesCountLabel(lineageDeleteTargetCount)
|
||||
: canForceDelete
|
||||
? 'Force Delete'
|
||||
: 'Delete Workspace'
|
||||
? translate(
|
||||
'auto.components.sidebar.DeleteWorktreeDialogFooter.forceDelete',
|
||||
'Force Delete'
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.DeleteWorktreeDialogFooter.deleteWorkspace',
|
||||
'Delete Workspace'
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -42,8 +42,21 @@ export function DeleteWorktreeDirtyChangeHint({
|
||||
|
||||
const label =
|
||||
changeCount > 0
|
||||
? `${changeCount} uncommitted or untracked ${changeCount === 1 ? 'change' : 'changes'}`
|
||||
: 'Uncommitted or untracked changes'
|
||||
? changeCount === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.DeleteWorktreeDirtyChangeHint.changeCount_one',
|
||||
'1 uncommitted or untracked change',
|
||||
{ count: changeCount }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.DeleteWorktreeDirtyChangeHint.changeCount_other',
|
||||
'{{count}} uncommitted or untracked changes',
|
||||
{ count: changeCount }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.DeleteWorktreeDirtyChangeHint.changes',
|
||||
'Uncommitted or untracked changes'
|
||||
)
|
||||
|
||||
const warningLabel = (
|
||||
<>
|
||||
|
||||
@@ -34,7 +34,6 @@ type ImportedWorktreesVisibilityLineProps = {
|
||||
}
|
||||
|
||||
const PREVIEW_LIMIT = 3
|
||||
const KEEP_HIDDEN_LABEL = 'Keep hidden - recover from the project menu'
|
||||
const GROUP_LIMIT = 5
|
||||
|
||||
type ImportedWorktreePathGroup = {
|
||||
@@ -42,10 +41,6 @@ type ImportedWorktreePathGroup = {
|
||||
worktrees: ImportedWorktreeVisibilityPreview[]
|
||||
}
|
||||
|
||||
function pluralizeWorktree(count: number): string {
|
||||
return count === 1 ? 'worktree' : 'worktrees'
|
||||
}
|
||||
|
||||
function getWorktreeKey(
|
||||
worktree: ImportedWorktreeVisibilityPreview,
|
||||
index: number,
|
||||
@@ -92,15 +87,29 @@ export default function ImportedWorktreesVisibilityLine({
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const [expandedGroupPathKeys, setExpandedGroupPathKeys] = useState<Set<string>>(new Set())
|
||||
const hiddenCount = hiddenWorktrees.length
|
||||
const worktreeNoun = pluralizeWorktree(hiddenCount)
|
||||
const worktreeGroups = groupWorktreesByParentPath(hiddenWorktrees)
|
||||
const visibleWorktreeGroups = worktreeGroups.slice(0, GROUP_LIMIT)
|
||||
const remainingGroupCount = Math.max(0, worktreeGroups.length - visibleWorktreeGroups.length)
|
||||
// Host labels distinguish otherwise identical project notice rows.
|
||||
const repoScopeLabel = hostContextLabel
|
||||
? `${repoDisplayName} on ${hostContextLabel}`
|
||||
? translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.repoOnHost',
|
||||
'{{repo}} on {{host}}',
|
||||
{ repo: repoDisplayName, host: hostContextLabel }
|
||||
)
|
||||
: repoDisplayName
|
||||
const keepHiddenAriaLabel = `Keep ${hiddenCount} discovered ${worktreeNoun} hidden for ${repoScopeLabel}; recover from the project menu`
|
||||
const keepHiddenAriaLabel =
|
||||
hiddenCount === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.keepHiddenAriaLabel_one',
|
||||
'Keep 1 discovered worktree hidden for {{repo}}; recover from the project menu',
|
||||
{ count: hiddenCount, repo: repoScopeLabel }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.keepHiddenAriaLabel_other',
|
||||
'Keep {{count}} discovered worktrees hidden for {{repo}}; recover from the project menu',
|
||||
{ count: hiddenCount, repo: repoScopeLabel }
|
||||
)
|
||||
|
||||
if (hiddenCount === 0) {
|
||||
return null
|
||||
@@ -108,8 +117,28 @@ export default function ImportedWorktreesVisibilityLine({
|
||||
|
||||
const lineText =
|
||||
placement === 'pinned-fallback'
|
||||
? `Hiding ${hiddenCount} discovered ${worktreeNoun} in ${repoScopeLabel}`
|
||||
: `Hiding ${hiddenCount} discovered ${worktreeNoun}`
|
||||
? hiddenCount === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.hidingInRepo_one',
|
||||
'Hiding 1 discovered worktree in {{repo}}',
|
||||
{ count: hiddenCount, repo: repoScopeLabel }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.hidingInRepo_other',
|
||||
'Hiding {{count}} discovered worktrees in {{repo}}',
|
||||
{ count: hiddenCount, repo: repoScopeLabel }
|
||||
)
|
||||
: hiddenCount === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.hiding_one',
|
||||
'Hiding 1 discovered worktree',
|
||||
{ count: hiddenCount }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.hiding_other',
|
||||
'Hiding {{count}} discovered worktrees',
|
||||
{ count: hiddenCount }
|
||||
)
|
||||
|
||||
const toggleGroupExpanded = (path: string): void => {
|
||||
const key = normalizeRuntimePathForComparison(path)
|
||||
@@ -141,11 +170,19 @@ export default function ImportedWorktreesVisibilityLine({
|
||||
size="icon-xs"
|
||||
disabled={pending}
|
||||
aria-expanded={isExpanded}
|
||||
aria-label={translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.f54f2bec5d',
|
||||
'{{value0}} hidden worktrees for {{value1}}',
|
||||
{ value0: isExpanded ? 'Collapse' : 'Expand', value1: repoScopeLabel }
|
||||
)}
|
||||
aria-label={
|
||||
isExpanded
|
||||
? translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.collapseAriaLabel',
|
||||
'Collapse hidden worktrees for {{repo}}',
|
||||
{ repo: repoScopeLabel }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.expandAriaLabel',
|
||||
'Expand hidden worktrees for {{repo}}',
|
||||
{ repo: repoScopeLabel }
|
||||
)
|
||||
}
|
||||
onClick={() => setIsExpanded((value) => !value)}
|
||||
className="shrink-0 rounded-[4px] text-muted-foreground hover:bg-worktree-sidebar-accent hover:text-worktree-sidebar-accent-foreground"
|
||||
>
|
||||
@@ -185,7 +222,10 @@ export default function ImportedWorktreesVisibilityLine({
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top" sideOffset={4}>
|
||||
{KEEP_HIDDEN_LABEL}
|
||||
{translate(
|
||||
'auto.components.sidebar.ImportedWorktreesVisibilityLine.keepHiddenTooltip',
|
||||
'Keep hidden - recover from the project menu'
|
||||
)}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
|
||||
@@ -10,7 +10,10 @@ import { translate } from '@/i18n/i18n'
|
||||
|
||||
function statusLabel(entry: PendingWorktreeCreation): string {
|
||||
if (entry.status === 'error') {
|
||||
return entry.error ?? 'Creation failed'
|
||||
return (
|
||||
entry.error ??
|
||||
translate('auto.components.sidebar.PendingWorktreeRow.creationFailed', 'Creation failed')
|
||||
)
|
||||
}
|
||||
return getCreationProgressLabel(entry)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ type RemoteFileBrowserProps = (
|
||||
|
||||
const FILE_HINT_MS = 2000
|
||||
const NO_ENTRIES: readonly DirEntry[] = []
|
||||
const FILE_HINT_TEXT = "Files can't be opened as a project"
|
||||
|
||||
export function RemoteFileBrowser({
|
||||
targetId,
|
||||
@@ -345,7 +344,10 @@ export function RemoteFileBrowser({
|
||||
title={fileHint ? undefined : resolvedPath}
|
||||
>
|
||||
{fileHint
|
||||
? FILE_HINT_TEXT
|
||||
? translate(
|
||||
'auto.components.sidebar.RemoteFileBrowser.fileHint',
|
||||
"Files can't be opened as a project"
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.RemoteFileBrowser.971d85cc84',
|
||||
'Opens as a project on this host · {{value0}}',
|
||||
|
||||
@@ -50,9 +50,6 @@ export function RemoteFileBrowserEntryList({
|
||||
?.scrollIntoView?.({ block: 'nearest' })
|
||||
}, [activeIndex, displayEntries])
|
||||
|
||||
const displayEmptyDirCopy = isPreviewActive
|
||||
? `${preview!.resolvedPath} is empty`
|
||||
: 'Empty directory'
|
||||
const noMatchesFilter = isPreviewActive ? preview!.filter : filter
|
||||
const displayNoMatchesCopy = isRemoteFileBrowserPathResolveTextTooLarge(noMatchesFilter)
|
||||
? translate(
|
||||
@@ -90,7 +87,13 @@ export function RemoteFileBrowserEntryList({
|
||||
!preview!.error &&
|
||||
!preview!.loading ? (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<p className="text-xs text-muted-foreground">{displayEmptyDirCopy}</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{translate(
|
||||
'auto.components.sidebar.RemoteFileBrowserEntryList.pathEmpty',
|
||||
'{{path}} is empty',
|
||||
{ path: preview!.resolvedPath }
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
) : !isPreviewActive && entries.length === 0 ? (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
|
||||
@@ -267,8 +267,21 @@ function SetupScriptPromptCard(): React.JSX.Element | null {
|
||||
onOpenSettings: () => openLocalCommandSettings(importedRepoId, importedHostId),
|
||||
description:
|
||||
skippedCount > 0
|
||||
? `${skippedCount} unsupported field${skippedCount === 1 ? '' : 's'} skipped. Saved the setup command.`
|
||||
: 'Saved the setup command.'
|
||||
? skippedCount === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCard.savedWithSkippedFields_one',
|
||||
'1 unsupported field skipped. Saved the setup command.',
|
||||
{ count: skippedCount }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCard.savedWithSkippedFields_other',
|
||||
'{{count}} unsupported fields skipped. Saved the setup command.',
|
||||
{ count: skippedCount }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCard.savedSetupCommand',
|
||||
'Saved the setup command.'
|
||||
)
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -90,7 +90,11 @@ function WorkspaceKanbanStatusLane({
|
||||
undefined
|
||||
)
|
||||
}, [fullWorktreeIds, hasQuery, items])
|
||||
const createTooltip = `New workspace in ${status.label}`
|
||||
const createTooltip = translate(
|
||||
'auto.components.sidebar.WorkspaceKanbanStatusLane.newWorkspaceIn',
|
||||
'New workspace in {{status}}',
|
||||
{ status: status.label }
|
||||
)
|
||||
const createButton = (
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
@@ -244,7 +244,10 @@ const WorktreeCardAgentsBody = React.memo(function WorktreeCardAgentsBody({
|
||||
const sendTarget = isAgentSendTargetModeActive
|
||||
? (sendTargetsByPaneKey.get(agent.paneKey) ?? {
|
||||
status: 'disabled' as const,
|
||||
disabledReason: 'Agent is not available'
|
||||
disabledReason: translate(
|
||||
'auto.components.sidebar.WorktreeCardAgents.agentUnavailable',
|
||||
'Agent is not available'
|
||||
)
|
||||
})
|
||||
: undefined
|
||||
const descendantAncestorPaneKeys = new Set(ancestorPaneKeys)
|
||||
@@ -301,7 +304,10 @@ const WorktreeCardAgentsBody = React.memo(function WorktreeCardAgentsBody({
|
||||
const sendTarget = isAgentSendTargetModeActive
|
||||
? (sendTargetsByPaneKey.get(agent.paneKey) ?? {
|
||||
status: 'disabled' as const,
|
||||
disabledReason: 'Agent is not available'
|
||||
disabledReason: translate(
|
||||
'auto.components.sidebar.WorktreeCardAgents.agentUnavailable',
|
||||
'Agent is not available'
|
||||
)
|
||||
})
|
||||
: undefined
|
||||
const descendantAncestorPaneKeys = new Set(ancestorPaneKeys)
|
||||
|
||||
@@ -108,7 +108,11 @@ function WorktreePortRow({ port }: { port: WorkspacePort }): React.JSX.Element {
|
||||
const runtimeTarget = useWorktreeRuntimeTarget(
|
||||
port.kind === 'workspace' ? port.owner.worktreeId : null
|
||||
)
|
||||
const processLabel = port.processName ?? (port.pid ? `PID ${port.pid}` : 'Unknown process')
|
||||
const processLabel =
|
||||
port.processName ??
|
||||
(port.pid
|
||||
? `PID ${port.pid}`
|
||||
: translate('auto.components.sidebar.WorktreeCardPorts.unknownProcess', 'Unknown process'))
|
||||
const address = addressForPort(port)
|
||||
const canStop = canStopWorkspacePort(port)
|
||||
const openBrowserLabel = translate(
|
||||
|
||||
@@ -210,7 +210,9 @@ export function WorktreeCardStatusSlot({
|
||||
return overlayNewCardUnreadStatus(passiveStatus, showNewCardUnreadAlert)
|
||||
}
|
||||
|
||||
const actionLabel = isUnread ? 'Mark as read' : 'Mark as unread'
|
||||
const actionLabel = isUnread
|
||||
? translate('auto.components.sidebar.WorktreeCardStatusSlot.markAsRead', 'Mark as read')
|
||||
: translate('auto.components.sidebar.WorktreeCardStatusSlot.markAsUnread', 'Mark as unread')
|
||||
const tooltip =
|
||||
showStatus && !isUnread ? `${passiveStatusLabel} · ${unreadTooltip}` : unreadTooltip
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { translate } from '@/i18n/i18n'
|
||||
|
||||
export const addRepoBusyLabels = {
|
||||
scanningRepositories: (): string =>
|
||||
translate(
|
||||
'auto.components.sidebar.addRepoBusyLabels.scanningRepositories',
|
||||
'Scanning for repositories...'
|
||||
),
|
||||
openingProject: (): string =>
|
||||
translate('auto.components.sidebar.addRepoBusyLabels.openingProject', 'Opening project...'),
|
||||
openingFolder: (): string =>
|
||||
translate('auto.components.sidebar.addRepoBusyLabels.openingFolder', 'Opening folder...'),
|
||||
chooseFolder: (): string =>
|
||||
translate('auto.components.sidebar.addRepoBusyLabels.chooseFolder', 'Choose a folder...')
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import {
|
||||
IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR,
|
||||
IMPORTED_WORKTREES_SHOW_ERROR,
|
||||
getImportedWorktreesKeepHiddenError,
|
||||
getImportedWorktreesShowError,
|
||||
keepImportedWorktreesHiddenCard,
|
||||
showImportedWorktreesCard,
|
||||
type ImportedWorktreeCardActionState
|
||||
@@ -43,7 +43,7 @@ describe('imported worktrees card actions', () => {
|
||||
expect(updateRepo).toHaveBeenNthCalledWith(2, projectId, { externalWorktreeVisibility: 'hide' })
|
||||
expect(setCardState).toHaveBeenLastCalledWith(projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_SHOW_ERROR
|
||||
error: getImportedWorktreesShowError()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -66,7 +66,7 @@ describe('imported worktrees card actions', () => {
|
||||
})
|
||||
expect(setCardState).toHaveBeenLastCalledWith(projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_SHOW_ERROR,
|
||||
error: getImportedWorktreesShowError(),
|
||||
forceVisible: true
|
||||
})
|
||||
})
|
||||
@@ -81,7 +81,7 @@ describe('imported worktrees card actions', () => {
|
||||
expect(updateRepo).toHaveBeenNthCalledWith(2, projectId, { externalWorktreeVisibility: 'hide' })
|
||||
expect(setCardState).toHaveBeenLastCalledWith(projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_SHOW_ERROR,
|
||||
error: getImportedWorktreesShowError(),
|
||||
forceVisible: true
|
||||
})
|
||||
})
|
||||
@@ -109,7 +109,7 @@ describe('imported worktrees card actions', () => {
|
||||
|
||||
expect(setCardState).toHaveBeenLastCalledWith(projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR
|
||||
error: getImportedWorktreesKeepHiddenError()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Repo } from '../../../../shared/repo-types'
|
||||
import { mergeExternalWorktreeInboxPaths } from '../../../../shared/external-worktree-inbox'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
|
||||
export type ImportedWorktreeCardActionState = {
|
||||
pending: boolean
|
||||
@@ -30,9 +31,19 @@ type ImportedWorktreeCardActionDeps = {
|
||||
) => Promise<boolean>
|
||||
}
|
||||
|
||||
export const IMPORTED_WORKTREES_SHOW_ERROR = 'Could not show discovered worktrees. Try again.'
|
||||
export const IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR =
|
||||
'Could not keep discovered worktrees hidden. Try again.'
|
||||
export function getImportedWorktreesShowError(): string {
|
||||
return translate(
|
||||
'auto.components.sidebar.importedWorktreesCardActions.showError',
|
||||
'Could not show discovered worktrees. Try again.'
|
||||
)
|
||||
}
|
||||
|
||||
export function getImportedWorktreesKeepHiddenError(): string {
|
||||
return translate(
|
||||
'auto.components.sidebar.importedWorktreesCardActions.keepHiddenError',
|
||||
'Could not keep discovered worktrees hidden. Try again.'
|
||||
)
|
||||
}
|
||||
|
||||
export async function showImportedWorktreesCard(
|
||||
args: ImportedWorktreeCardActionDeps
|
||||
@@ -48,7 +59,7 @@ export async function showImportedWorktreesCard(
|
||||
if (!updated) {
|
||||
args.setCardState(args.projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_SHOW_ERROR,
|
||||
error: getImportedWorktreesShowError(),
|
||||
...(forceVisible ? { forceVisible: true } : {})
|
||||
})
|
||||
return
|
||||
@@ -58,7 +69,7 @@ export async function showImportedWorktreesCard(
|
||||
const rolledBack = await args.updateRepo(args.projectId, { externalWorktreeVisibility: 'hide' })
|
||||
args.setCardState(args.projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_SHOW_ERROR,
|
||||
error: getImportedWorktreesShowError(),
|
||||
...(rolledBack ? {} : { forceVisible: true })
|
||||
})
|
||||
return
|
||||
@@ -84,7 +95,7 @@ export async function keepImportedWorktreesHiddenCard(
|
||||
if (!updated) {
|
||||
args.setCardState(args.projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR
|
||||
error: getImportedWorktreesKeepHiddenError()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -42,7 +42,16 @@ export function useWorktreeCardLinkedDetails({
|
||||
? {
|
||||
number: worktree.linkedIssue,
|
||||
// Why: linked metadata persists immediately but GitHub details arrive async; show the link number so it doesn't look unlinked.
|
||||
title: issue === null ? 'Issue details unavailable' : 'Loading issue...'
|
||||
title:
|
||||
issue === null
|
||||
? translate(
|
||||
'auto.components.sidebar.useWorktreeCardLinkedDetails.issueUnavailable',
|
||||
'Issue details unavailable'
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.useWorktreeCardLinkedDetails.loadingIssue',
|
||||
'Loading issue...'
|
||||
)
|
||||
}
|
||||
: null)
|
||||
const linearIssue: LinearIssue | null | undefined = worktree.linkedLinearIssue
|
||||
@@ -70,8 +79,14 @@ export function useWorktreeCardLinkedDetails({
|
||||
identifier: worktree.linkedLinearIssue,
|
||||
title:
|
||||
linearIssueEntry || linearIssueFallbackEntry
|
||||
? 'Linear issue details unavailable'
|
||||
: 'Loading Linear issue...',
|
||||
? translate(
|
||||
'auto.components.sidebar.useWorktreeCardLinkedDetails.linearIssueUnavailable',
|
||||
'Linear issue details unavailable'
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.useWorktreeCardLinkedDetails.loadingLinearIssue',
|
||||
'Loading Linear issue...'
|
||||
),
|
||||
url: linearIssueUrlFallback
|
||||
}
|
||||
: null
|
||||
@@ -79,9 +94,10 @@ export function useWorktreeCardLinkedDetails({
|
||||
const cardTitleDisplay = getWorktreeCardTitleDisplay({
|
||||
storedDisplayName: worktree.displayName,
|
||||
branchName: branch,
|
||||
linearIssueTitle: linearIssueDisplay?.title,
|
||||
// Fetched titles only: display fallbacks hold localized loading/unavailable placeholders.
|
||||
linearIssueTitle: linearIssue?.title,
|
||||
jiraIssueTitle: jiraIssueDisplay?.title,
|
||||
issueTitle: issueDisplay?.title,
|
||||
issueTitle: issue?.title,
|
||||
reviewTitle: prDisplay?.title
|
||||
})
|
||||
const legacyCardTitleDisplay = coerceWorktreeCardVisibleTitle(worktree.displayName)
|
||||
|
||||
@@ -74,7 +74,9 @@ export function useWorktreeCardWorkspaceActions({
|
||||
},
|
||||
[setShowRenameErrorDialog]
|
||||
)
|
||||
const unreadTooltip = worktree.isUnread ? 'Mark read' : 'Mark unread'
|
||||
const unreadTooltip = worktree.isUnread
|
||||
? translate('auto.components.sidebar.useWorktreeCardWorkspaceActions.markRead', 'Mark read')
|
||||
: translate('auto.components.sidebar.useWorktreeCardWorkspaceActions.markUnread', 'Mark unread')
|
||||
const lineageChildAriaLabel =
|
||||
lineageChildCount === 1
|
||||
? lineageCollapsed
|
||||
|
||||
@@ -35,6 +35,7 @@ import { useWorktreeContextMenuCommands } from './use-worktree-context-menu-comm
|
||||
import { useWorktreeParentPickerTransition } from './use-worktree-parent-picker-transition'
|
||||
import { useWorktreeContextMenuSecondaryActions } from './use-worktree-context-menu-secondary-actions'
|
||||
import { CLOSE_ALL_CONTEXT_MENUS_EVENT } from '@/lib/close-all-context-menus'
|
||||
import { getWorktreeContextMenuBatchLabels } from './workspace-batch-action-labels'
|
||||
|
||||
export type WorktreeContextMenuProps = {
|
||||
worktree: Worktree
|
||||
@@ -195,14 +196,11 @@ export function useWorktreeContextMenuModel({
|
||||
[activeContextWorktrees, repoMap]
|
||||
)
|
||||
const removesProject = shouldRemoveProjectFromContextMenu(repo, worktree)
|
||||
const sleepLabel =
|
||||
isMultiContext && sleepableWorktrees.length > 0
|
||||
? `Sleep ${sleepableWorktrees.length} Workspace${sleepableWorktrees.length === 1 ? '' : 's'}`
|
||||
: 'Sleep'
|
||||
const deleteLabel =
|
||||
isMultiContext && batchDeleteWorktrees.length > 0
|
||||
? `Delete ${batchDeleteWorktrees.length} Workspace${batchDeleteWorktrees.length === 1 ? '' : 's'}`
|
||||
: 'Delete Selected'
|
||||
const { sleepLabel, deleteLabel } = getWorktreeContextMenuBatchLabels({
|
||||
isMultiContext,
|
||||
sleepableCount: sleepableWorktrees.length,
|
||||
deletableCount: batchDeleteWorktrees.length
|
||||
})
|
||||
const hasParentLink = hasWorktreeParentLink(
|
||||
worktree,
|
||||
worktreeLineageById,
|
||||
|
||||
@@ -16,6 +16,7 @@ import { createNestedRepoScanId } from './add-repo-dialog-types'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { worktreeRefreshOptions } from './add-repo-runtime-owner'
|
||||
import type { ExecutionHostId } from '../../../../shared/execution-host'
|
||||
import { addRepoBusyLabels } from './add-repo-busy-labels'
|
||||
|
||||
type ShowNestedRepoReview = (args: {
|
||||
scan: NestedRepoScanResult
|
||||
@@ -100,7 +101,7 @@ export function useAddRepoLocalFolderFlow({
|
||||
closeModal()
|
||||
return { status: 'paused' }
|
||||
}
|
||||
setAddProjectBusyLabel('Scanning for repositories...')
|
||||
setAddProjectBusyLabel(addRepoBusyLabels.scanningRepositories())
|
||||
try {
|
||||
const attemptId = createNestedRepoTelemetryAttemptId()
|
||||
const scanId = createNestedRepoScanId()
|
||||
@@ -160,7 +161,7 @@ export function useAddRepoLocalFolderFlow({
|
||||
})
|
||||
return { status: 'paused' }
|
||||
}
|
||||
setAddProjectBusyLabel('Opening project...')
|
||||
setAddProjectBusyLabel(addRepoBusyLabels.openingProject())
|
||||
const repo = await addRepoPath(path, undefined, {
|
||||
runtimeEnvironmentId: activeRuntimeEnvironmentId ?? null
|
||||
})
|
||||
@@ -293,7 +294,7 @@ export function useAddRepoLocalFolderFlow({
|
||||
const handleBrowse = useCallback(async (): Promise<void> => {
|
||||
const gen = ++localAddGenRef.current
|
||||
setIsAdding(true)
|
||||
setAddProjectBusyLabel('Choose a folder...')
|
||||
setAddProjectBusyLabel(addRepoBusyLabels.chooseFolder())
|
||||
try {
|
||||
const paths = await window.api.repos.pickFolders()
|
||||
if (paths.length === 0 || gen !== localAddGenRef.current) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import type { WorktreeFetchOptions } from '@/store/slices/worktree-helpers'
|
||||
import { createNestedRepoScanId } from './add-repo-dialog-types'
|
||||
import { worktreeRefreshOptions } from './add-repo-runtime-owner'
|
||||
import type { ExecutionHostId } from '../../../../shared/execution-host'
|
||||
import { addRepoBusyLabels } from './add-repo-busy-labels'
|
||||
|
||||
type ShowNestedRepoReview = (args: {
|
||||
scan: NestedRepoScanResult
|
||||
@@ -91,7 +92,11 @@ export function useAddRepoServerPathFlow({
|
||||
}
|
||||
const gen = ++serverAddGenRef.current
|
||||
setIsAddingServerPath(true)
|
||||
setAddProjectBusyLabel(kind === 'git' ? 'Scanning for repositories...' : 'Opening folder...')
|
||||
setAddProjectBusyLabel(
|
||||
kind === 'git'
|
||||
? addRepoBusyLabels.scanningRepositories()
|
||||
: addRepoBusyLabels.openingFolder()
|
||||
)
|
||||
try {
|
||||
if (kind === 'git') {
|
||||
const attemptId = createNestedRepoTelemetryAttemptId()
|
||||
@@ -157,7 +162,9 @@ export function useAddRepoServerPathFlow({
|
||||
return
|
||||
}
|
||||
}
|
||||
setAddProjectBusyLabel(kind === 'git' ? 'Opening project...' : 'Opening folder...')
|
||||
setAddProjectBusyLabel(
|
||||
kind === 'git' ? addRepoBusyLabels.openingProject() : addRepoBusyLabels.openingFolder()
|
||||
)
|
||||
const repo = await addRepoPath(path, kind, {
|
||||
runtimeEnvironmentId: activeRuntimeEnvironmentId
|
||||
})
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { translate } from '@/i18n/i18n'
|
||||
|
||||
export function deleteWorkspacesCountLabel(count: number): string {
|
||||
return count === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.workspaceBatchActionLabels.deleteCount_one',
|
||||
'Delete 1 Workspace',
|
||||
{ count }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.workspaceBatchActionLabels.deleteCount_other',
|
||||
'Delete {{count}} Workspaces',
|
||||
{ count }
|
||||
)
|
||||
}
|
||||
|
||||
function sleepWorkspacesCountLabel(count: number): string {
|
||||
return count === 1
|
||||
? translate(
|
||||
'auto.components.sidebar.workspaceBatchActionLabels.sleepCount_one',
|
||||
'Sleep 1 Workspace',
|
||||
{ count }
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.workspaceBatchActionLabels.sleepCount_other',
|
||||
'Sleep {{count}} Workspaces',
|
||||
{ count }
|
||||
)
|
||||
}
|
||||
|
||||
export function getWorktreeContextMenuBatchLabels(args: {
|
||||
isMultiContext: boolean
|
||||
sleepableCount: number
|
||||
deletableCount: number
|
||||
}): { sleepLabel: string; deleteLabel: string } {
|
||||
return {
|
||||
sleepLabel:
|
||||
args.isMultiContext && args.sleepableCount > 0
|
||||
? sleepWorkspacesCountLabel(args.sleepableCount)
|
||||
: translate('auto.components.sidebar.workspaceBatchActionLabels.sleep', 'Sleep'),
|
||||
deleteLabel:
|
||||
args.isMultiContext && args.deletableCount > 0
|
||||
? deleteWorkspacesCountLabel(args.deletableCount)
|
||||
: translate(
|
||||
'auto.components.sidebar.workspaceBatchActionLabels.deleteSelected',
|
||||
'Delete Selected'
|
||||
)
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,7 +3,7 @@ import { useAppStore } from '@/store'
|
||||
import type { AppState } from '@/store/types'
|
||||
import type { Repo } from '../../../../../../shared/repo-types'
|
||||
import {
|
||||
IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR,
|
||||
getImportedWorktreesKeepHiddenError,
|
||||
keepImportedWorktreesHiddenCard,
|
||||
showImportedWorktreesCard,
|
||||
type ImportedWorktreeCardActionState
|
||||
@@ -118,7 +118,7 @@ export function useSidebarExternalWorktreeCards(args: {
|
||||
if (!refreshed) {
|
||||
setImportedWorktreeCardState(projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR
|
||||
error: getImportedWorktreesKeepHiddenError()
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -127,7 +127,7 @@ export function useSidebarExternalWorktreeCards(args: {
|
||||
if (detected?.authoritative !== true) {
|
||||
setImportedWorktreeCardState(projectId, {
|
||||
pending: false,
|
||||
error: IMPORTED_WORKTREES_KEEP_HIDDEN_ERROR
|
||||
error: getImportedWorktreesKeepHiddenError()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
+9
-1
@@ -54,7 +54,15 @@ function getWorktreeVisibilityMenuLabel(
|
||||
isLegacyRepoForExternalWorktreeVisibility(repo),
|
||||
visibilityDefaults
|
||||
)
|
||||
return visibility === 'show' ? 'Hide non-Orca worktrees' : 'Show hidden worktrees'
|
||||
return visibility === 'show'
|
||||
? translate(
|
||||
'auto.components.sidebar.repoHeaderProjectActions.hideNonOrcaWorktrees',
|
||||
'Hide non-Orca worktrees'
|
||||
)
|
||||
: translate(
|
||||
'auto.components.sidebar.repoHeaderProjectActions.showHiddenWorktrees',
|
||||
'Show hidden worktrees'
|
||||
)
|
||||
}
|
||||
|
||||
export type RepoHeaderProjectActions = {
|
||||
|
||||
+20
-2
@@ -2115,7 +2115,9 @@
|
||||
"07729cc155": "expired"
|
||||
},
|
||||
"DeleteWorktreeDirtyChangeHint": {
|
||||
"8e2994ce28": "Deleting this workspace permanently removes these changes from disk."
|
||||
"8e2994ce28": "Deleting this workspace permanently removes these changes from disk.",
|
||||
"changeCount_one": "1 uncommitted or untracked change",
|
||||
"changeCount_other": "{{count}} uncommitted or untracked changes"
|
||||
},
|
||||
"FolderWorkspaceComposerDialog": {
|
||||
"chooseSourceProject": "Choose task source",
|
||||
@@ -2127,6 +2129,14 @@
|
||||
"HostSectionHeaderMenu": {
|
||||
"63f36455cc": "Reconnect"
|
||||
},
|
||||
"ImportedWorktreesVisibilityLine": {
|
||||
"hidingInRepo_one": "Hiding 1 discovered worktree in {{repo}}",
|
||||
"hidingInRepo_other": "Hiding {{count}} discovered worktrees in {{repo}}",
|
||||
"hiding_one": "Hiding 1 discovered worktree",
|
||||
"hiding_other": "Hiding {{count}} discovered worktrees",
|
||||
"keepHiddenAriaLabel_one": "Keep 1 discovered worktree hidden for {{repo}}; recover from the project menu",
|
||||
"keepHiddenAriaLabel_other": "Keep {{count}} discovered worktrees hidden for {{repo}}; recover from the project menu"
|
||||
},
|
||||
"LinearAgentSkillSetupPrompt": {
|
||||
"missingBoth": "Orca CLI and Linear agent skill are missing.",
|
||||
"panelDescription": "Install the host agent skill for linked Linear task handoffs.",
|
||||
@@ -2151,7 +2161,9 @@
|
||||
"e8c1f4a2b9": "in workspace options."
|
||||
},
|
||||
"SetupScriptPromptCard": {
|
||||
"dcaa645da5": "ok"
|
||||
"dcaa645da5": "ok",
|
||||
"savedWithSkippedFields_one": "1 unsupported field skipped. Saved the setup command.",
|
||||
"savedWithSkippedFields_other": "{{count}} unsupported fields skipped. Saved the setup command."
|
||||
},
|
||||
"SidebarHeader": {
|
||||
"49f62c5665": "Workspace board",
|
||||
@@ -2302,6 +2314,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"workspaceBatchActionLabels": {
|
||||
"deleteCount_one": "Delete 1 Workspace",
|
||||
"deleteCount_other": "Delete {{count}} Workspaces",
|
||||
"sleepCount_one": "Sleep 1 Workspace",
|
||||
"sleepCount_other": "Sleep {{count}} Workspaces"
|
||||
},
|
||||
"worktree": {
|
||||
"card": {
|
||||
"compact": {
|
||||
|
||||
@@ -5917,7 +5917,10 @@
|
||||
"loadedPathsNotice": "Loaded paths may be incomplete or out of date.",
|
||||
"loadedChangedPaths": "Loaded changed paths",
|
||||
"unresolvedConflict": "Unresolved conflict",
|
||||
"moreLoadedPaths": "and {{value0}} more loaded paths"
|
||||
"moreLoadedPaths": "and {{value0}} more loaded paths",
|
||||
"changeCount_one": "1 uncommitted or untracked change",
|
||||
"changeCount_other": "{{count}} uncommitted or untracked changes",
|
||||
"changes": "Uncommitted or untracked changes"
|
||||
},
|
||||
"DeleteWorktreeLineageNotice": {
|
||||
"ad407c2d55": "more",
|
||||
@@ -5940,9 +5943,18 @@
|
||||
"b2bc47c080": "more locations",
|
||||
"b47ba1a9d2": "{{value0}} preview",
|
||||
"2251d41ebb": "Hidden worktree groups",
|
||||
"f54f2bec5d": "{{value0}} hidden worktrees for {{value1}}",
|
||||
"5a9688802a": "Show {{value0}} more",
|
||||
"294de4aeb2": "Show fewer"
|
||||
"294de4aeb2": "Show fewer",
|
||||
"collapseAriaLabel": "Collapse hidden worktrees for {{repo}}",
|
||||
"expandAriaLabel": "Expand hidden worktrees for {{repo}}",
|
||||
"hiding_one": "Hiding 1 discovered worktree",
|
||||
"hiding_other": "Hiding {{count}} discovered worktrees",
|
||||
"hidingInRepo_one": "Hiding 1 discovered worktree in {{repo}}",
|
||||
"hidingInRepo_other": "Hiding {{count}} discovered worktrees in {{repo}}",
|
||||
"keepHiddenAriaLabel_one": "Keep 1 discovered worktree hidden for {{repo}}; recover from the project menu",
|
||||
"keepHiddenAriaLabel_other": "Keep {{count}} discovered worktrees hidden for {{repo}}; recover from the project menu",
|
||||
"keepHiddenTooltip": "Keep hidden - recover from the project menu",
|
||||
"repoOnHost": "{{repo}} on {{host}}"
|
||||
},
|
||||
"NonGitFolderDialog": {
|
||||
"e52454b7f6": "Open as Folder",
|
||||
@@ -5971,7 +5983,8 @@
|
||||
"PendingWorktreeRow": {
|
||||
"af21e953d1": "Cancel worktree creation",
|
||||
"188f6922a0": "Cancel",
|
||||
"creatingWorkspace": "Creating workspace…"
|
||||
"creatingWorkspace": "Creating workspace…",
|
||||
"creationFailed": "Creation failed"
|
||||
},
|
||||
"ProjectGroupDeleteDialog": {
|
||||
"ca65b78f78": "Cancel",
|
||||
@@ -6002,7 +6015,8 @@
|
||||
"00c4235c10": "No matches for '{{value0}}'",
|
||||
"largeInputNoMatches": "No matches for this long input",
|
||||
"entriesLabel": "Folder entries",
|
||||
"inputLabel": "Filter or path"
|
||||
"inputLabel": "Filter or path",
|
||||
"fileHint": "Files can't be opened as a project"
|
||||
},
|
||||
"SleepTwinWorkspaceDialog": {
|
||||
"title": "Sleep Workspace",
|
||||
@@ -6034,7 +6048,10 @@
|
||||
"a49196d538": "Runs when Orca creates a new worktree.",
|
||||
"d9f2db2738": "project's settings",
|
||||
"a5bb8c5135": "Saved in this",
|
||||
"dcaa645da5": "ok"
|
||||
"dcaa645da5": "ok",
|
||||
"savedSetupCommand": "Saved the setup command.",
|
||||
"savedWithSkippedFields_one": "1 unsupported field skipped. Saved the setup command.",
|
||||
"savedWithSkippedFields_other": "{{count}} unsupported fields skipped. Saved the setup command."
|
||||
},
|
||||
"SetupScriptPromptCardViews": {
|
||||
"96a7f4198c": "Save local setup",
|
||||
@@ -6274,7 +6291,8 @@
|
||||
"WorkspaceKanbanStatusLane": {
|
||||
"8ad104642b": "Empty",
|
||||
"3611d1ae7f": "Resize workspace board columns",
|
||||
"2df01a03ff": "No matches"
|
||||
"2df01a03ff": "No matches",
|
||||
"newWorkspaceIn": "New workspace in {{status}}"
|
||||
},
|
||||
"WorkspaceStatusAppearancePopover": {
|
||||
"514be2f569": "Set {{value0}} color to {{value1}}",
|
||||
@@ -6314,7 +6332,8 @@
|
||||
"ef18787206": "Queued for deletion"
|
||||
},
|
||||
"WorktreeCardAgents": {
|
||||
"1b0a156717": "Agents"
|
||||
"1b0a156717": "Agents",
|
||||
"agentUnavailable": "Agent is not available"
|
||||
},
|
||||
"WorktreeCardReviewDetailSection": {
|
||||
"copyLink": "Copy link",
|
||||
@@ -6381,7 +6400,8 @@
|
||||
"5d1a5d51bb": "Stopped process on {{value0}}",
|
||||
"c89f290e25": "Copied {{value0}}",
|
||||
"d1113f4660": "Failed to open browser",
|
||||
"fed49903c9": "{{value0}} live {{value1}}"
|
||||
"fed49903c9": "{{value0}} live {{value1}}",
|
||||
"unknownProcess": "Unknown process"
|
||||
},
|
||||
"WorktreeContextMenu": {
|
||||
"c39c37676a": "Create a group and move this project into it.",
|
||||
@@ -6746,11 +6766,17 @@
|
||||
}
|
||||
},
|
||||
"CacheTimer": {
|
||||
"07729cc155": "expired"
|
||||
"07729cc155": "expired",
|
||||
"expiredTooltip": "The next message will re-send the full context as uncached tokens",
|
||||
"expiresIn": "Prompt cache expires in {{time}}"
|
||||
},
|
||||
"DeleteWorktreeDialogFooter": {
|
||||
"c0e972d726": "Cancel",
|
||||
"cf95e3b5bb": "Close"
|
||||
"cf95e3b5bb": "Close",
|
||||
"deleteWorkspace": "Delete Workspace",
|
||||
"deleting": "Deleting...",
|
||||
"forceDelete": "Force Delete",
|
||||
"forceDeleting": "Force Deleting..."
|
||||
},
|
||||
"index": {
|
||||
"b826a98b6f": "busy"
|
||||
@@ -6865,7 +6891,9 @@
|
||||
},
|
||||
"WorktreeCardStatusSlot": {
|
||||
"branchIdentity": "Branch",
|
||||
"sleeping": "Sleeping"
|
||||
"sleeping": "Sleeping",
|
||||
"markAsRead": "Mark as read",
|
||||
"markAsUnread": "Mark as unread"
|
||||
},
|
||||
"NewExternalWorktreesInboxLine": {
|
||||
"9f2d4c8b17": "Hide external worktrees permanently for {{value0}}",
|
||||
@@ -7176,6 +7204,41 @@
|
||||
"outsideDistro": "Pick a folder inside {{value0}}.",
|
||||
"underDistro": "This host can only add folders under \\\\wsl.localhost\\{{value0}}.",
|
||||
"windowsDrive": "Folders on a Windows drive stay on this computer. Choose this computer as the host to add one."
|
||||
},
|
||||
"RemoteFileBrowserEntryList": {
|
||||
"pathEmpty": "{{path}} is empty"
|
||||
},
|
||||
"importedWorktreesCardActions": {
|
||||
"keepHiddenError": "Could not keep discovered worktrees hidden. Try again.",
|
||||
"showError": "Could not show discovered worktrees. Try again."
|
||||
},
|
||||
"repoHeaderProjectActions": {
|
||||
"hideNonOrcaWorktrees": "Hide non-Orca worktrees",
|
||||
"showHiddenWorktrees": "Show hidden worktrees"
|
||||
},
|
||||
"useWorktreeCardLinkedDetails": {
|
||||
"issueUnavailable": "Issue details unavailable",
|
||||
"linearIssueUnavailable": "Linear issue details unavailable",
|
||||
"loadingIssue": "Loading issue...",
|
||||
"loadingLinearIssue": "Loading Linear issue..."
|
||||
},
|
||||
"useWorktreeCardWorkspaceActions": {
|
||||
"markRead": "Mark read",
|
||||
"markUnread": "Mark unread"
|
||||
},
|
||||
"workspaceBatchActionLabels": {
|
||||
"deleteCount_one": "Delete 1 Workspace",
|
||||
"deleteCount_other": "Delete {{count}} Workspaces",
|
||||
"deleteSelected": "Delete Selected",
|
||||
"sleep": "Sleep",
|
||||
"sleepCount_one": "Sleep 1 Workspace",
|
||||
"sleepCount_other": "Sleep {{count}} Workspaces"
|
||||
},
|
||||
"addRepoBusyLabels": {
|
||||
"scanningRepositories": "Scanning for repositories...",
|
||||
"openingProject": "Opening project...",
|
||||
"openingFolder": "Opening folder...",
|
||||
"chooseFolder": "Choose a folder..."
|
||||
}
|
||||
},
|
||||
"shared": {
|
||||
|
||||
@@ -5557,9 +5557,10 @@
|
||||
"b2bc47c080": "más ubicaciones",
|
||||
"b47ba1a9d2": "Vista previa de {{value0}}",
|
||||
"2251d41ebb": "Grupos de worktrees ocultos",
|
||||
"f54f2bec5d": "{{value0}} worktrees ocultos para {{value1}}",
|
||||
"5a9688802a": "Mostrar {{value0}} más",
|
||||
"294de4aeb2": "Mostrar menos"
|
||||
"294de4aeb2": "Mostrar menos",
|
||||
"collapseAriaLabel": "Contraer worktrees ocultos de {{repo}}",
|
||||
"expandAriaLabel": "Expandir worktrees ocultos de {{repo}}"
|
||||
},
|
||||
"NonGitFolderDialog": {
|
||||
"e52454b7f6": "Abrir como carpeta",
|
||||
|
||||
@@ -5721,9 +5721,10 @@
|
||||
"b2bc47c080": "autres emplacements",
|
||||
"b47ba1a9d2": "Aperçu de {{value0}}",
|
||||
"2251d41ebb": "Groupes de worktrees masqués",
|
||||
"f54f2bec5d": "{{value0}} worktrees masqués pour {{value1}}",
|
||||
"5a9688802a": "Afficher {{value0}} de plus",
|
||||
"294de4aeb2": "Afficher moins"
|
||||
"294de4aeb2": "Afficher moins",
|
||||
"collapseAriaLabel": "Réduire les worktrees masqués de {{repo}}",
|
||||
"expandAriaLabel": "Développer les worktrees masqués de {{repo}}"
|
||||
},
|
||||
"NonGitFolderDialog": {
|
||||
"e52454b7f6": "Ouvrir comme dossier",
|
||||
|
||||
@@ -5500,12 +5500,15 @@
|
||||
"loadedPathsNotice": "読み込まれたパスは不完全な場合や古い場合があります。",
|
||||
"loadedChangedPaths": "読み込まれた変更済みパス",
|
||||
"unresolvedConflict": "未解決の競合",
|
||||
"moreLoadedPaths": "ほかに読み込まれたパスが{{value0}}件"
|
||||
"moreLoadedPaths": "ほかに読み込まれたパスが{{value0}}件",
|
||||
"changeCount_one": "未コミットまたは未追跡の変更: 1 件",
|
||||
"changeCount_other": "未コミットまたは未追跡の変更: {{count}} 件",
|
||||
"changes": "未コミットまたは未追跡の変更があります"
|
||||
},
|
||||
"DeleteWorktreeLineageNotice": {
|
||||
"ad407c2d55": "件以上",
|
||||
"a940f3c96e": "子ワークスペースは削除されます",
|
||||
"29b98bf9cd": "このワークスペースを削除すると、{{value0}} 子ワークスペースも削除されます。",
|
||||
"29b98bf9cd": "このワークスペースを削除すると、子ワークスペース {{value0}} 個も削除されます。",
|
||||
"66798cc6a2": "このワークスペースを削除すると、子ワークスペースも 1 つ削除されます。"
|
||||
},
|
||||
"DeleteWorktreeSkipConfirmOption": {
|
||||
@@ -5523,9 +5526,18 @@
|
||||
"b2bc47c080": "さらに多くの場所",
|
||||
"b47ba1a9d2": "{{value0}} プレビュー",
|
||||
"2251d41ebb": "非表示のワークツリーグループ",
|
||||
"f54f2bec5d": "{{value0}} {{value1}} の非表示ワークツリー",
|
||||
"5a9688802a": "{{value0}} をもっと見る",
|
||||
"294de4aeb2": "表示数を減らす"
|
||||
"294de4aeb2": "表示数を減らす",
|
||||
"collapseAriaLabel": "{{repo}} の非表示のワークツリー一覧を折りたたむ",
|
||||
"expandAriaLabel": "{{repo}} の非表示のワークツリー一覧を展開",
|
||||
"hiding_one": "1 件のワークツリーを非表示中",
|
||||
"hiding_other": "{{count}} 件のワークツリーを非表示中",
|
||||
"hidingInRepo_one": "{{repo}} の 1 件のワークツリーを非表示中",
|
||||
"hidingInRepo_other": "{{repo}} の {{count}} 件のワークツリーを非表示中",
|
||||
"keepHiddenAriaLabel_one": "{{repo}} で検出されたワークツリー 1 件を非表示のままにする(プロジェクトメニューから再表示できます)",
|
||||
"keepHiddenAriaLabel_other": "{{repo}} で検出されたワークツリー {{count}} 件を非表示のままにする(プロジェクトメニューから再表示できます)",
|
||||
"keepHiddenTooltip": "非表示のままにする(プロジェクトメニューから再表示できます)",
|
||||
"repoOnHost": "{{repo}}({{host}})"
|
||||
},
|
||||
"NonGitFolderDialog": {
|
||||
"e52454b7f6": "フォルダーとして開く",
|
||||
@@ -5554,7 +5566,8 @@
|
||||
"PendingWorktreeRow": {
|
||||
"af21e953d1": "ワークツリーの作成をキャンセルする",
|
||||
"188f6922a0": "キャンセル",
|
||||
"creatingWorkspace": "ワークスペースを作成中…"
|
||||
"creatingWorkspace": "ワークスペースを作成中…",
|
||||
"creationFailed": "作成に失敗しました"
|
||||
},
|
||||
"ProjectGroupDeleteDialog": {
|
||||
"ca65b78f78": "キャンセル",
|
||||
@@ -5585,7 +5598,8 @@
|
||||
"00c4235c10": "「{{value0}}」に一致するものはありません",
|
||||
"largeInputNoMatches": "この長い入力に一致するものはありません",
|
||||
"entriesLabel": "フォルダーの項目",
|
||||
"inputLabel": "フィルターまたはパス"
|
||||
"inputLabel": "フィルターまたはパス",
|
||||
"fileHint": "ファイルはプロジェクトとして開けません"
|
||||
},
|
||||
"SleepTwinWorkspaceDialog": {
|
||||
"title": "Sleep Workspace",
|
||||
@@ -5617,7 +5631,10 @@
|
||||
"a49196d538": "Orca が新規ワークツリーを作成するときに実行されます。",
|
||||
"d9f2db2738": "プロジェクトの設定",
|
||||
"a5bb8c5135": "これに保存されました",
|
||||
"dcaa645da5": "わかりました"
|
||||
"dcaa645da5": "わかりました",
|
||||
"savedSetupCommand": "セットアップコマンドを保存しました。",
|
||||
"savedWithSkippedFields_one": "未対応の項目を 1 件スキップしました。セットアップコマンドを保存しました。",
|
||||
"savedWithSkippedFields_other": "未対応の項目を {{count}} 件スキップしました。セットアップコマンドを保存しました。"
|
||||
},
|
||||
"SetupScriptPromptCardViews": {
|
||||
"96a7f4198c": "ローカル設定を保存する",
|
||||
@@ -5849,7 +5866,8 @@
|
||||
"WorkspaceKanbanStatusLane": {
|
||||
"8ad104642b": "空の",
|
||||
"3611d1ae7f": "ワークスペースボードの列のサイズを変更する",
|
||||
"2df01a03ff": "一致なし"
|
||||
"2df01a03ff": "一致なし",
|
||||
"newWorkspaceIn": "「{{status}}」に新しいワークスペースを作成"
|
||||
},
|
||||
"WorkspaceStatusAppearancePopover": {
|
||||
"514be2f569": "{{value0}} の色を {{value1}} に設定します",
|
||||
@@ -5889,7 +5907,8 @@
|
||||
"ef18787206": "削除待ち"
|
||||
},
|
||||
"WorktreeCardAgents": {
|
||||
"1b0a156717": "Agent"
|
||||
"1b0a156717": "Agent",
|
||||
"agentUnavailable": "Agent を利用できません"
|
||||
},
|
||||
"WorktreeCardReviewDetailSection": {
|
||||
"reviewHeader": "{{value0}} #{{value1}}",
|
||||
@@ -5956,7 +5975,8 @@
|
||||
"5d1a5d51bb": "{{value0}} でプロセスを停止しました",
|
||||
"c89f290e25": "{{value0}} をコピーしました",
|
||||
"d1113f4660": "ブラウザを開けませんでした",
|
||||
"fed49903c9": "{{value0}} ライブ {{value1}}"
|
||||
"fed49903c9": "{{value0}} ライブ {{value1}}",
|
||||
"unknownProcess": "不明なプロセス"
|
||||
},
|
||||
"WorktreeContextMenu": {
|
||||
"c39c37676a": "グループを作成し、このプロジェクトをそのグループに移動します。",
|
||||
@@ -5987,9 +6007,9 @@
|
||||
"workspaceSection": "ワークスペース",
|
||||
"primaryDeleteDisabled": "プライマリワークツリーは削除できません。代わりにプロジェクトを削除してください。",
|
||||
"deleteWorktree": "ワークツリーを削除",
|
||||
"sleepWithDescendants": "子孫と一緒に寝る ({{value0}})",
|
||||
"sleepWithDescendantsDescription": "このワークスペースとすべてのネストされた子孫のアクティブなパネルを閉じて、メモリと CPU を解放します。",
|
||||
"deleteWithDescendants": "子孫と一緒に削除…"
|
||||
"sleepWithDescendants": "配下のワークスペースも含めてスリープ ({{value0}})",
|
||||
"sleepWithDescendantsDescription": "このワークスペースと配下のすべてのワークスペースのアクティブなパネルを閉じて、メモリと CPU の使用量を減らします。",
|
||||
"deleteWithDescendants": "配下のワークスペースも含めて削除…"
|
||||
},
|
||||
"WorktreeList": {
|
||||
"d880ea0744": "グループを作成し、このプロジェクトをそのグループに移動します。",
|
||||
@@ -6347,11 +6367,17 @@
|
||||
}
|
||||
},
|
||||
"CacheTimer": {
|
||||
"07729cc155": "期限切れ"
|
||||
"07729cc155": "期限切れ",
|
||||
"expiredTooltip": "次のメッセージでは、コンテキスト全体がキャッシュされていないトークンとして再送信されます",
|
||||
"expiresIn": "プロンプトキャッシュはあと {{time}} で期限切れになります"
|
||||
},
|
||||
"DeleteWorktreeDialogFooter": {
|
||||
"c0e972d726": "キャンセル",
|
||||
"cf95e3b5bb": "閉じる"
|
||||
"cf95e3b5bb": "閉じる",
|
||||
"deleteWorkspace": "ワークスペースを削除",
|
||||
"deleting": "削除中…",
|
||||
"forceDelete": "強制削除",
|
||||
"forceDeleting": "強制削除中…"
|
||||
},
|
||||
"index": {
|
||||
"b826a98b6f": "忙しい"
|
||||
@@ -6512,7 +6538,9 @@
|
||||
},
|
||||
"WorktreeCardStatusSlot": {
|
||||
"branchIdentity": "ブランチ",
|
||||
"sleeping": "眠っている"
|
||||
"sleeping": "スリープ中",
|
||||
"markAsRead": "既読にする",
|
||||
"markAsUnread": "未読にする"
|
||||
},
|
||||
"NewExternalWorktreesInboxLine": {
|
||||
"9f2d4c8b17": "{{value0}} の外部ワークツリーを完全に非表示にする",
|
||||
@@ -6795,6 +6823,41 @@
|
||||
"outsideDistro": "{{value0}} 内のフォルダーを選択してください。",
|
||||
"underDistro": "このホストで追加できるのは \\\\wsl.localhost\\{{value0}} 以下のフォルダーのみです。",
|
||||
"windowsDrive": "Windows ドライブ上のフォルダーはこのコンピュータに残ります。追加するにはホストとしてこのコンピュータを選択してください。"
|
||||
},
|
||||
"RemoteFileBrowserEntryList": {
|
||||
"pathEmpty": "{{path}} は空です"
|
||||
},
|
||||
"importedWorktreesCardActions": {
|
||||
"keepHiddenError": "検出されたワークツリーを非表示のままにできませんでした。もう一度お試しください。",
|
||||
"showError": "検出されたワークツリーを表示できませんでした。もう一度お試しください。"
|
||||
},
|
||||
"repoHeaderProjectActions": {
|
||||
"hideNonOrcaWorktrees": "Orca 以外のワークツリーを非表示にする",
|
||||
"showHiddenWorktrees": "非表示のワークツリーを表示する"
|
||||
},
|
||||
"useWorktreeCardLinkedDetails": {
|
||||
"issueUnavailable": "Issue の詳細を表示できません",
|
||||
"linearIssueUnavailable": "Linear Issue の詳細を表示できません",
|
||||
"loadingIssue": "Issue を読み込み中…",
|
||||
"loadingLinearIssue": "Linear Issue を読み込み中…"
|
||||
},
|
||||
"useWorktreeCardWorkspaceActions": {
|
||||
"markRead": "既読にする",
|
||||
"markUnread": "未読にする"
|
||||
},
|
||||
"workspaceBatchActionLabels": {
|
||||
"deleteCount_one": "1 件のワークスペースを削除",
|
||||
"deleteCount_other": "{{count}} 件のワークスペースを削除",
|
||||
"deleteSelected": "選択した項目を削除",
|
||||
"sleep": "スリープ",
|
||||
"sleepCount_one": "1 件のワークスペースをスリープ",
|
||||
"sleepCount_other": "{{count}} 件のワークスペースをスリープ"
|
||||
},
|
||||
"addRepoBusyLabels": {
|
||||
"scanningRepositories": "リポジトリをスキャンしています…",
|
||||
"openingProject": "プロジェクトを開いています…",
|
||||
"openingFolder": "フォルダーを開いています…",
|
||||
"chooseFolder": "フォルダーを選択中…"
|
||||
}
|
||||
},
|
||||
"shared": {
|
||||
@@ -11068,7 +11131,7 @@
|
||||
"d2a366c7f9": "ダブルクリック",
|
||||
"4ed3e239a8": "境界",
|
||||
"d4aeafac10": "セパレーター",
|
||||
"7286cd2566": "言葉",
|
||||
"7286cd2566": "単語",
|
||||
"3ab64c47d8": "文字はダブルクリック選択の単語境界として扱われます。",
|
||||
"957a0203fc": "単語の区切り文字",
|
||||
"56fff3d113": "メモリ",
|
||||
@@ -11248,11 +11311,11 @@
|
||||
"7640ed9848": "声",
|
||||
"56defcd6c3": "ディクテーションに使用するローカルまたはクラウドの音声テキスト変換モデルを選択します。",
|
||||
"7e62cd7c41": "音声モデル",
|
||||
"931b1a9e53": "押して話をする",
|
||||
"064a9bd94a": "所有",
|
||||
"931b1a9e53": "プッシュトゥトーク",
|
||||
"064a9bd94a": "長押し",
|
||||
"6fa48bcd41": "トグル",
|
||||
"d86f5600da": "モード",
|
||||
"089d31a45b": "口述筆記",
|
||||
"089d31a45b": "音声入力",
|
||||
"748b33e531": "ディクテーション動作を切り替えたり、押し続けたりします。",
|
||||
"6a3abb4338": "ディクテーションモード",
|
||||
"e360027a65": "マイクロフォン",
|
||||
@@ -12403,7 +12466,7 @@
|
||||
"unavailable": "利用不可",
|
||||
"label": "マイクロフォン",
|
||||
"description": "音声ディクテーションに使用される入力デバイス。システムのデフォルトは OS のマイク設定に従います。",
|
||||
"accessHint": "リスト入力デバイスへのマイクのアクセスを許可します。",
|
||||
"accessHint": "入力デバイスの一覧を表示するには、マイクへのアクセスを許可してください。",
|
||||
"allowAccess": "アクセスを許可する",
|
||||
"noMicrophoneFound": "マイクが見つかりませんでした。 1 つ接続してから、再試行してください。",
|
||||
"openFailedDetail": "マイクを開けませんでした。 {{value0}}",
|
||||
@@ -17299,7 +17362,7 @@
|
||||
"a7c312430d": "最後の実行",
|
||||
"2df8970cd5": "Agent",
|
||||
"e353ab9516": "事前チェック",
|
||||
"620b22145e": "グレース",
|
||||
"620b22145e": "猶予時間",
|
||||
"15ea446b93": "セッション",
|
||||
"5405a09b1f": "実行場所",
|
||||
"2f8baf5360": "から作成",
|
||||
@@ -17355,9 +17418,9 @@
|
||||
"521f77cd58": "1時間",
|
||||
"e5ad263ae5": "30分",
|
||||
"529dc6c0b7": "猶予なし",
|
||||
"3d70c185c8": "Orca または実行ホストがスケジュールされた時刻に利用できなかった場合、Orca はこのウィンドウ内で利用可能になったときに、欠落したオカレンスを 1 つ実行します。失敗した古い実行はスキップされます。",
|
||||
"3d70c185c8": "予定の時刻に Orca または実行ホストが利用できなかった場合、この猶予時間内に利用できるようになれば、実行できなかった分のうち直近の 1 回を実行します。それより前の分はスキップされます。",
|
||||
"3df53d554a": "実行漏れの猶予時間のヘルプ",
|
||||
"fc089e5fde": "グレース"
|
||||
"fc089e5fde": "猶予時間"
|
||||
},
|
||||
"AutomationPrecheckFields": {
|
||||
"d2a2ac89ac": "10分",
|
||||
@@ -20262,16 +20325,16 @@
|
||||
},
|
||||
"popupBlocked": "ポップアップがブロックされました: {{origin}}",
|
||||
"hostPaneOfflineTitle": "そのデバイスはもう接続されていません",
|
||||
"hostPaneNamedTitle": "{{device}} で上映中",
|
||||
"hostPaneTitle": "別のデバイスで表示する",
|
||||
"hostPaneNamedTitle": "{{device}} で表示中",
|
||||
"hostPaneTitle": "別のデバイスで表示中",
|
||||
"hostPaneOfflineDescription": "このページは表示されたままになるため、ここから閉じることができます。デバイスが再接続すると元に戻ります。",
|
||||
"hostPaneDescription": "このページは、それを開いたペアリングされたデスクトップ上に表示されます。",
|
||||
"hostRowClose": "ホストされているページを閉じる",
|
||||
"hostRowCloseFailed": "このページを閉じることができませんでした。ホストしているデバイスがビジー状態である可能性があります。もう一度試してください。",
|
||||
"hostRowOfflineNamed": "オフライン — {{device}} にホストされました",
|
||||
"hostRowOfflineNamed": "オフライン — {{device}} で開かれていました",
|
||||
"hostRowOffline": "オフライン — ホストしているデバイスが終了しました",
|
||||
"hostRowNamed": "{{device}} で開催",
|
||||
"hostRow": "別のデバイスでホストされている"
|
||||
"hostRowNamed": "{{device}} で開いています",
|
||||
"hostRow": "別のデバイスで開いています"
|
||||
},
|
||||
"navigation": {
|
||||
"back": "戻る",
|
||||
|
||||
@@ -5523,9 +5523,10 @@
|
||||
"b2bc47c080": "더 많은 위치",
|
||||
"b47ba1a9d2": "{{value0}} 미리보기",
|
||||
"2251d41ebb": "숨겨진 워크트리 그룹",
|
||||
"f54f2bec5d": "{{value1}}의 숨겨진 워크트리 {{value0}}개",
|
||||
"5a9688802a": "{{value0}} 더 보기",
|
||||
"294de4aeb2": "간략히 표시"
|
||||
"294de4aeb2": "간략히 표시",
|
||||
"collapseAriaLabel": "{{repo}}의 숨겨진 워크트리 접기",
|
||||
"expandAriaLabel": "{{repo}}의 숨겨진 워크트리 펼치기"
|
||||
},
|
||||
"NonGitFolderDialog": {
|
||||
"e52454b7f6": "폴더로 열기",
|
||||
|
||||
@@ -11504,9 +11504,10 @@
|
||||
"b2bc47c080": "mais locais",
|
||||
"b47ba1a9d2": "Pré-visualização de {{value0}}",
|
||||
"2251d41ebb": "Grupos de worktrees ocultas",
|
||||
"f54f2bec5d": "{{value0}} worktrees ocultas para {{value1}}",
|
||||
"5a9688802a": "Mostrar mais {{value0}}",
|
||||
"294de4aeb2": "Mostrar menos"
|
||||
"294de4aeb2": "Mostrar menos",
|
||||
"collapseAriaLabel": "Recolher worktrees ocultas de {{repo}}",
|
||||
"expandAriaLabel": "Expandir worktrees ocultas de {{repo}}"
|
||||
},
|
||||
"WorkspaceKanbanSettingsMenu": {
|
||||
"79eb990aa4": "Adicionar status",
|
||||
|
||||
@@ -5523,9 +5523,10 @@
|
||||
"b2bc47c080": "更多位置",
|
||||
"b47ba1a9d2": "{{value0}} 预览",
|
||||
"2251d41ebb": "隐藏的工作树组",
|
||||
"f54f2bec5d": "{{value0}} 隐藏 {{value1}} 的工作树",
|
||||
"5a9688802a": "显示 {{value0}} 更多",
|
||||
"294de4aeb2": "显示较少"
|
||||
"294de4aeb2": "显示较少",
|
||||
"collapseAriaLabel": "折叠 {{repo}} 的隐藏工作树",
|
||||
"expandAriaLabel": "展开 {{repo}} 的隐藏工作树"
|
||||
},
|
||||
"NonGitFolderDialog": {
|
||||
"e52454b7f6": "作为文件夹打开",
|
||||
|
||||
Reference in New Issue
Block a user