mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
fix(ui): restore missing spaces in i18n JSX fragment copy (#9513)
This commit is contained in:
@@ -4935,13 +4935,12 @@ function ChecksTab({
|
||||
</span>
|
||||
{startedAt && (
|
||||
<span>
|
||||
{translate('auto.components.GitHubItemDialog.4812814bc8', 'Started')}
|
||||
{startedAt}
|
||||
{translate('auto.components.GitHubItemDialog.4812814bc8', 'Started')} {startedAt}
|
||||
</span>
|
||||
)}
|
||||
{completedAt && (
|
||||
<span>
|
||||
{translate('auto.components.GitHubItemDialog.0f478f5efa', 'Completed')}
|
||||
{translate('auto.components.GitHubItemDialog.0f478f5efa', 'Completed')}{' '}
|
||||
{completedAt}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -1034,7 +1034,7 @@ export default function GitLabItemDialog({
|
||||
<StateBadge state={item.state} />
|
||||
{item.author ? (
|
||||
<span>
|
||||
{translate('auto.components.GitLabItemDialog.9bfb4a24d7', 'by')}
|
||||
{translate('auto.components.GitLabItemDialog.9bfb4a24d7', 'by')}{' '}
|
||||
{item.author}
|
||||
</span>
|
||||
) : null}
|
||||
@@ -1521,7 +1521,7 @@ export default function GitLabItemDialog({
|
||||
{translate(
|
||||
'auto.components.GitLabItemDialog.a7eb4f4916',
|
||||
'from'
|
||||
)}
|
||||
)}{' '}
|
||||
{file.oldPath}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -5030,13 +5030,12 @@ function ChecksTab({
|
||||
</span>
|
||||
{startedAt && (
|
||||
<span>
|
||||
{translate('auto.components.PullRequestPage.76551b1161', 'Started')}
|
||||
{startedAt}
|
||||
{translate('auto.components.PullRequestPage.76551b1161', 'Started')} {startedAt}
|
||||
</span>
|
||||
)}
|
||||
{completedAt && (
|
||||
<span>
|
||||
{translate('auto.components.PullRequestPage.000f90afcf', 'Completed')}
|
||||
{translate('auto.components.PullRequestPage.000f90afcf', 'Completed')}{' '}
|
||||
{completedAt}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -9323,7 +9323,7 @@ export default function TaskPage(): React.JSX.Element {
|
||||
// Why: per-repo partial-failure signal — distinct from a hard
|
||||
// IPC reject (tasksError). The two are mutually exclusive.
|
||||
<div className="border-b border-border/50 bg-amber-500/10 px-4 py-3 text-sm text-amber-700 dark:text-amber-200">
|
||||
{failedCount} {translate('auto.components.TaskPage.7762f4b03a', 'of')}
|
||||
{failedCount} {translate('auto.components.TaskPage.7762f4b03a', 'of')}{' '}
|
||||
{selectedRepos.length}{' '}
|
||||
{translate('auto.components.TaskPage.d1766fd62d', 'projects failed to load')}
|
||||
</div>
|
||||
|
||||
@@ -887,8 +887,7 @@ function DownloadingContent({
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
{release ? (
|
||||
<h3 className="text-sm font-semibold">
|
||||
{translate('auto.components.UpdateCard.f58b5c57a6', 'New:')}
|
||||
{release.title}
|
||||
{translate('auto.components.UpdateCard.f58b5c57a6', 'New:')} {release.title}
|
||||
</h3>
|
||||
) : (
|
||||
<h3 className="text-sm font-semibold">
|
||||
|
||||
@@ -2877,7 +2877,7 @@ export default function AutomationsPage(): React.JSX.Element {
|
||||
)}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="runs" disabled={!selected}>
|
||||
{translate('auto.components.automations.AutomationsPage.0e110a3469', 'Runs')}
|
||||
{translate('auto.components.automations.AutomationsPage.0e110a3469', 'Runs')}{' '}
|
||||
<span className="text-xs text-muted-foreground">{selectedRuns.length}</span>
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
@@ -288,7 +288,7 @@ export function ExternalAutomationRunTable({
|
||||
<FileText className="size-3.5" />
|
||||
<span>
|
||||
{pageStart}-{pageEnd}{' '}
|
||||
{translate('auto.components.automations.ExternalAutomationRunTable.7475c0ce96', 'of')}
|
||||
{translate('auto.components.automations.ExternalAutomationRunTable.7475c0ce96', 'of')}{' '}
|
||||
{totalCount}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -46,7 +46,7 @@ export function ContextualTourProgressDots({
|
||||
</span>
|
||||
<span className="whitespace-nowrap text-[11px] font-medium leading-none text-muted-foreground">
|
||||
{current}{' '}
|
||||
{translate('auto.components.contextual.tours.ContextualTourProgressDots.7734cb8ad3', 'of')}
|
||||
{translate('auto.components.contextual.tours.ContextualTourProgressDots.7734cb8ad3', 'of')}{' '}
|
||||
{total}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -2022,7 +2022,7 @@ export default function CombinedDiffViewer({
|
||||
{translate('auto.components.editor.CombinedDiffViewer.948a5fd6c8', 'Clear Notes')}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-xs">
|
||||
{translate('auto.components.editor.CombinedDiffViewer.84898c548d', 'Clear')}
|
||||
{translate('auto.components.editor.CombinedDiffViewer.84898c548d', 'Clear')}{' '}
|
||||
{diffCommentCount}{' '}
|
||||
{diffCommentCount === 1
|
||||
? translate('auto.components.editor.CombinedDiffViewer.8ab3248fd8', 'note')
|
||||
|
||||
@@ -101,7 +101,7 @@ export function ConflictBanner({
|
||||
)}
|
||||
<span className="min-w-0 truncate font-medium text-foreground">
|
||||
{label}{' '}
|
||||
{translate('auto.components.editor.ConflictComponents.55d61a0ccd', 'conflict ·')}
|
||||
{translate('auto.components.editor.ConflictComponents.55d61a0ccd', 'conflict ·')}{' '}
|
||||
{CONFLICT_KIND_LABELS[conflict.conflictKind]}
|
||||
</span>
|
||||
{conflictNavigation && conflictNavigation.total > 0 && (
|
||||
@@ -171,7 +171,7 @@ export function ConflictBanner({
|
||||
)}
|
||||
{entry?.oldPath && (
|
||||
<div className="mt-1 text-muted-foreground">
|
||||
{translate('auto.components.editor.ConflictComponents.d5edd81755', 'Renamed from')}
|
||||
{translate('auto.components.editor.ConflictComponents.d5edd81755', 'Renamed from')}{' '}
|
||||
{entry.oldPath}
|
||||
</div>
|
||||
)}
|
||||
@@ -334,7 +334,7 @@ export function ConflictReviewPanel({
|
||||
{translate(
|
||||
'auto.components.editor.ConflictComponents.a1ce36f77d',
|
||||
'Snapshot captured at'
|
||||
)}
|
||||
)}{' '}
|
||||
{snapshotTime}.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -899,7 +899,7 @@ export default function IpynbViewer({
|
||||
{translate('auto.components.editor.IpynbViewer.329764e9fc', 'BETA')}
|
||||
</span>
|
||||
<span className="font-mono">
|
||||
{translate('auto.components.editor.IpynbViewer.8c3b21369a', 'nbformat')}
|
||||
{translate('auto.components.editor.IpynbViewer.8c3b21369a', 'nbformat')}{' '}
|
||||
{notebook.nbformat}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -103,8 +103,7 @@ export default function MermaidBlock({
|
||||
return (
|
||||
<div className="mermaid-block">
|
||||
<div className="mermaid-error">
|
||||
{translate('auto.components.editor.MermaidBlock.dcc132e691', 'Diagram error:')}
|
||||
{error}
|
||||
{translate('auto.components.editor.MermaidBlock.dcc132e691', 'Diagram error:')} {error}
|
||||
</div>
|
||||
<pre>
|
||||
<code>{content}</code>
|
||||
|
||||
@@ -68,9 +68,9 @@ export function RichMarkdownDocLinkMenu({
|
||||
)}
|
||||
{overflow ? (
|
||||
<div className="rich-markdown-doc-link-footer">
|
||||
{translate('auto.components.editor.RichMarkdownDocLinkMenu.2aaf7d9678', 'Showing')}
|
||||
{translate('auto.components.editor.RichMarkdownDocLinkMenu.2aaf7d9678', 'Showing')}{' '}
|
||||
{rows.length}{' '}
|
||||
{translate('auto.components.editor.RichMarkdownDocLinkMenu.90c5f0e1e4', 'of')}
|
||||
{translate('auto.components.editor.RichMarkdownDocLinkMenu.90c5f0e1e4', 'of')}{' '}
|
||||
{totalMatches}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -381,7 +381,7 @@ export function ReviewNotesAnimatedVisual(props: { reducedMotion: boolean }): JS
|
||||
</button>
|
||||
<div className="ravs-popover" data-note-popover>
|
||||
<div className="ravs-pop-label">
|
||||
{translate('auto.components.feature.wall.ReviewNotesAnimatedVisual.a7a89d8f94', 'Line')}
|
||||
{translate('auto.components.feature.wall.ReviewNotesAnimatedVisual.a7a89d8f94', 'Line')}{' '}
|
||||
<span data-pop-line>?</span>
|
||||
</div>
|
||||
<div className="ravs-pop-input" data-pop-input />
|
||||
|
||||
@@ -272,7 +272,7 @@ export function ReviewPRViewAnimatedVisual(props: { reducedMotion: boolean }): J
|
||||
{translate(
|
||||
'auto.components.feature.wall.ReviewPRViewAnimatedVisual.6f4c2d7cb7',
|
||||
'Add a coverage case for'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>
|
||||
{translate(
|
||||
'auto.components.feature.wall.ReviewPRViewAnimatedVisual.c2062da7ec',
|
||||
|
||||
@@ -303,7 +303,7 @@ export function ReviewShipAnimatedVisual(props: { reducedMotion: boolean }): JSX
|
||||
{translate(
|
||||
'auto.components.feature.wall.ReviewShipAnimatedVisual.e725000cd7',
|
||||
'Changes'
|
||||
)}
|
||||
)}{' '}
|
||||
<span className="ravs-sc-changes-count">{SHIP_FILES.length}</span>
|
||||
</span>
|
||||
<span className="ravs-sc-view-all">
|
||||
|
||||
@@ -85,7 +85,7 @@ export function ReviewDiffRows(): JSX.Element {
|
||||
{translate(
|
||||
'auto.components.feature.wall.review.notes.diff.rows.f621c734f8',
|
||||
'Note · line'
|
||||
)}
|
||||
)}{' '}
|
||||
<span data-slot-line>?</span>
|
||||
</div>
|
||||
<div className="ravs-note-body" data-slot-body />
|
||||
|
||||
@@ -208,8 +208,7 @@ export function SectionMenu({
|
||||
return (
|
||||
<div className="py-1 text-xs">
|
||||
<div className="px-3 py-1.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
|
||||
{translate('auto.components.github.PRFilterSections.8177eda37e', 'Filter')}
|
||||
{subject}
|
||||
{translate('auto.components.github.PRFilterSections.8177eda37e', 'Filter')} {subject}
|
||||
</div>
|
||||
{rows.map((row) => (
|
||||
<button
|
||||
|
||||
@@ -154,12 +154,12 @@ function GitHubRateLimitRows({
|
||||
)}
|
||||
>
|
||||
{v.remaining}{' '}
|
||||
{translate('auto.components.github.github.rate.limit.display.f42790d150', 'of')}
|
||||
{translate('auto.components.github.github.rate.limit.display.f42790d150', 'of')}{' '}
|
||||
{v.limit}{' '}
|
||||
{translate(
|
||||
'auto.components.github.github.rate.limit.display.6da1858354',
|
||||
'left · resets in'
|
||||
)}
|
||||
)}{' '}
|
||||
{formatGitHubRateLimitReset(v.resetAt)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -133,7 +133,7 @@ function GitLabRateLimitRows({
|
||||
)}
|
||||
>
|
||||
{rest.remaining}{' '}
|
||||
{translate('auto.components.gitlab.gitlab.rate.limit.display.ea8ad0bae8', 'of')}
|
||||
{translate('auto.components.gitlab.gitlab.rate.limit.display.ea8ad0bae8', 'of')}{' '}
|
||||
{rest.limit}{' '}
|
||||
{translate(
|
||||
'auto.components.gitlab.gitlab.rate.limit.display.3e2c982cfa',
|
||||
|
||||
@@ -54,8 +54,7 @@ export function LinearPriorityIcon({
|
||||
>
|
||||
<span aria-hidden="true">!</span>
|
||||
<span className="sr-only">
|
||||
{translate('auto.components.linear.priority.icon.c43d3e065b', 'Priority:')}
|
||||
{label}
|
||||
{translate('auto.components.linear.priority.icon.c43d3e065b', 'Priority:')} {label}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
@@ -72,8 +71,7 @@ export function LinearPriorityIcon({
|
||||
className="size-3 rounded-full border border-muted-foreground/55"
|
||||
/>
|
||||
<span className="sr-only">
|
||||
{translate('auto.components.linear.priority.icon.c43d3e065b', 'Priority:')}
|
||||
{label}
|
||||
{translate('auto.components.linear.priority.icon.c43d3e065b', 'Priority:')} {label}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
@@ -110,8 +108,7 @@ export function LinearPriorityIcon({
|
||||
})}
|
||||
</svg>
|
||||
<span className="sr-only">
|
||||
{translate('auto.components.linear.priority.icon.c43d3e065b', 'Priority:')}
|
||||
{label}
|
||||
{translate('auto.components.linear.priority.icon.c43d3e065b', 'Priority:')} {label}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ export function FileExplorerTreeStatus({
|
||||
{translate(
|
||||
'auto.components.right.sidebar.FileExplorerTreeStatus.c76693e456',
|
||||
'Could not load files for this workspace:'
|
||||
)}
|
||||
)}{' '}
|
||||
{error}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -378,7 +378,7 @@ export function SourceControlAgentActionDialogForm({
|
||||
{translate(
|
||||
'auto.components.right.sidebar.SourceControlAgentActionDialogForm.1bc0bdbb5e',
|
||||
'Launch:'
|
||||
)}
|
||||
)}{' '}
|
||||
{deliveryPlan.commandLabel}
|
||||
</div>
|
||||
<div className="text-[11px]">{deliveryPlan.caveat}</div>
|
||||
|
||||
@@ -735,7 +735,7 @@ function CheckRunDetails({
|
||||
{translate(
|
||||
'auto.components.right.sidebar.checks.panel.content.fd46a70f1a',
|
||||
'Started'
|
||||
)}
|
||||
)}{' '}
|
||||
{startedAt}
|
||||
</span>
|
||||
)}
|
||||
@@ -744,7 +744,7 @@ function CheckRunDetails({
|
||||
{translate(
|
||||
'auto.components.right.sidebar.checks.panel.content.00e1c1658a',
|
||||
'Completed'
|
||||
)}
|
||||
)}{' '}
|
||||
{completedAt}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -1501,14 +1501,14 @@ export function AccountsPane({
|
||||
{translate(
|
||||
'auto.components.settings.AccountsPane.0023cc336e',
|
||||
'Paste either the raw token value (e.g.'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="text-xs">
|
||||
{translate('auto.components.settings.AccountsPane.922b51e02d', 'Fe26.2**…')}
|
||||
</code>
|
||||
{translate(
|
||||
'auto.components.settings.AccountsPane.338820326a',
|
||||
') or the full cookie header (e.g.'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="text-xs">
|
||||
{translate('auto.components.settings.AccountsPane.8951c5309f', 'auth=Fe26.2**…')}
|
||||
</code>
|
||||
|
||||
@@ -159,7 +159,7 @@ export function AutoRenameBranchFromWorkSetting({
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.12ea4a408d',
|
||||
'When an agent starts working in a new workspace, Orca renames its auto-generated branch (e.g.'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.1626524572',
|
||||
@@ -223,7 +223,7 @@ export function AutoRenameBranchFromWorkSetting({
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.9241b59bf5',
|
||||
'Use'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="font-mono">
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.c71770c455',
|
||||
@@ -261,7 +261,7 @@ export function AutoRenameBranchFromWorkSetting({
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.56580dcf60',
|
||||
'. You can also reference'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="font-mono">
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.2ee2779c05',
|
||||
@@ -281,7 +281,7 @@ export function AutoRenameBranchFromWorkSetting({
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.5d569f5199',
|
||||
'. Orca generates only the final segment, like'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="font-mono">
|
||||
{translate(
|
||||
'auto.components.settings.AutoRenameBranchFromWorkSetting.800edb1e54',
|
||||
|
||||
@@ -195,14 +195,14 @@ export function BaseRefPicker({
|
||||
{translate(
|
||||
'auto.components.settings.BaseRefPicker.a5c16712c1',
|
||||
'Multiple remotes detected. Type a remote name (e.g.'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>
|
||||
{translate('auto.components.settings.BaseRefPicker.915ad97875', 'upstream')}
|
||||
</code>
|
||||
{translate(
|
||||
'auto.components.settings.BaseRefPicker.80f7c82303',
|
||||
') or a full ref (e.g.'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>
|
||||
{translate('auto.components.settings.BaseRefPicker.b468f46726', 'upstream/main')}
|
||||
</code>
|
||||
|
||||
@@ -72,7 +72,7 @@ export function BrowserSessionCookiesSection({
|
||||
{translate(
|
||||
'auto.components.settings.BrowserPane.cd47bc9622',
|
||||
'Select a default profile for new browser tabs. Import cookies and switch profiles per-tab via the'
|
||||
)}
|
||||
)}{' '}
|
||||
<strong>···</strong>{' '}
|
||||
{translate('auto.components.settings.BrowserPane.e4aaf8051b', 'toolbar menu.')}
|
||||
</p>
|
||||
|
||||
@@ -317,7 +317,7 @@ export function CliSection({
|
||||
{translate(
|
||||
'auto.components.settings.CliSection.b0c310ab46',
|
||||
'Existing launcher target:'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>{status.currentTarget}</code>
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -273,7 +273,7 @@ export function CommitMessageAiPane({
|
||||
{translate(
|
||||
'auto.components.settings.CommitMessageAiPane.4f722a5f53',
|
||||
'Used by commit-message, pull-request, and branch-name recipes that select Custom command. Use'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="font-mono">
|
||||
{translate('auto.components.settings.CommitMessageAiPane.b8b6fd55b4', '{prompt}')}
|
||||
</code>{' '}
|
||||
|
||||
@@ -170,7 +170,7 @@ export function GeneralEditorSettingsSection({
|
||||
{translate(
|
||||
'auto.components.settings.GeneralEditorSettingsSection.8112cd6dcf',
|
||||
'How long Orca waits after your last edit before saving automatically. First launch defaults to'
|
||||
)}
|
||||
)}{' '}
|
||||
{DEFAULT_EDITOR_AUTO_SAVE_DELAY_MS}{' '}
|
||||
{translate('auto.components.settings.GeneralEditorSettingsSection.fc5c5306ff', 'ms.')}
|
||||
</p>
|
||||
|
||||
@@ -161,7 +161,7 @@ export function GeneralUpdateSettingsSection(): React.JSX.Element {
|
||||
{translate(
|
||||
'auto.components.settings.GeneralUpdateSettingsSection.a6b37929dc',
|
||||
'Version'
|
||||
)}
|
||||
)}{' '}
|
||||
{updateStatus.version}{' '}
|
||||
{translate(
|
||||
'auto.components.settings.GeneralUpdateSettingsSection.8311da27ba',
|
||||
@@ -199,7 +199,7 @@ export function GeneralUpdateSettingsSection(): React.JSX.Element {
|
||||
{translate(
|
||||
'auto.components.settings.GeneralUpdateSettingsSection.a6b37929dc',
|
||||
'Version'
|
||||
)}
|
||||
)}{' '}
|
||||
{updateStatus.version}{' '}
|
||||
{translate(
|
||||
'auto.components.settings.GeneralUpdateSettingsSection.d89806cc89',
|
||||
|
||||
@@ -236,11 +236,14 @@ export function GitPane({
|
||||
{translate(
|
||||
'auto.components.settings.GitPane.976afc6b3e',
|
||||
'When you create a workspace, Orca refreshes the remote base and safely fast-forwards your matching local branch, such as'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>{translate('auto.components.settings.GitPane.ffba483bae', 'main')}</code>{' '}
|
||||
{translate('auto.components.settings.GitPane.5bf885be48', 'or')}
|
||||
{translate('auto.components.settings.GitPane.5bf885be48', 'or')}{' '}
|
||||
<code>{translate('auto.components.settings.GitPane.3ae3de8898', 'master')}</code>
|
||||
{translate('auto.components.settings.GitPane.db3a127eb1', '. This keeps commands like')}
|
||||
{translate(
|
||||
'auto.components.settings.GitPane.db3a127eb1',
|
||||
'. This keeps commands like'
|
||||
)}{' '}
|
||||
<code>
|
||||
{translate('auto.components.settings.GitPane.d072a12995', 'git diff main...HEAD')}
|
||||
</code>{' '}
|
||||
|
||||
@@ -66,7 +66,7 @@ export function ManageSessionKillDialog({
|
||||
{translate(
|
||||
'auto.components.settings.ManageSessionKillDialog.8401328fed',
|
||||
'Force-quits'
|
||||
)}
|
||||
)}{' '}
|
||||
<span className="font-medium text-foreground">{session.sessionId}</span>
|
||||
{translate(
|
||||
'auto.components.settings.ManageSessionKillDialog.ad9832aa26',
|
||||
|
||||
@@ -159,7 +159,7 @@ export function NotificationSoundSection({
|
||||
className="truncate font-mono text-[11px] text-muted-foreground"
|
||||
title={notificationSettings.customSoundPath}
|
||||
>
|
||||
{translate('auto.components.settings.NotificationsPane.4aa5085cd7', 'Custom:')}
|
||||
{translate('auto.components.settings.NotificationsPane.4aa5085cd7', 'Custom:')}{' '}
|
||||
{notificationSettings.customSoundPath}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -441,7 +441,7 @@ function ExampleTemplateCard({
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<p className="text-[10px] tracking-[0.18em] text-muted-foreground">
|
||||
{translate('auto.components.settings.RepositoryHooksSection.175daba180', 'Example')}
|
||||
{translate('auto.components.settings.RepositoryHooksSection.175daba180', 'Example')}{' '}
|
||||
<code className="rounded bg-muted px-1 py-0.5">
|
||||
{translate('auto.components.settings.RepositoryHooksSection.39da2ae12f', 'orca.yaml')}
|
||||
</code>{' '}
|
||||
@@ -665,7 +665,7 @@ function ScriptEditor({
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-[11px] text-muted-foreground">
|
||||
{translate('auto.components.settings.RepositoryHooksSection.b113344b6a', 'Edit')}
|
||||
{translate('auto.components.settings.RepositoryHooksSection.b113344b6a', 'Edit')}{' '}
|
||||
<code className="rounded bg-muted px-1 py-0.5">
|
||||
{translate(
|
||||
'auto.components.settings.RepositoryHooksSection.39da2ae12f',
|
||||
@@ -1308,7 +1308,7 @@ export function RepositoryHooksSection({
|
||||
{translate(
|
||||
'auto.components.settings.RepositoryHooksSection.ac9038d2cc',
|
||||
'When both'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="rounded bg-muted px-1 py-0.5">
|
||||
{translate(
|
||||
'auto.components.settings.RepositoryHooksSection.39da2ae12f',
|
||||
|
||||
@@ -226,7 +226,7 @@ export function RepositoryPane({
|
||||
)}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{translate('auto.components.settings.RepositoryPane.323debba71', 'Type:')}
|
||||
{translate('auto.components.settings.RepositoryPane.323debba71', 'Type:')}{' '}
|
||||
<span className="text-foreground">{getRepoKindLabel(repo)}</span>
|
||||
</p>
|
||||
{isFolder ? (
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ export function RepositorySourceControlAiHostedReviewDefaults({
|
||||
{translate(
|
||||
'auto.components.settings.RepositorySourceControlAiHostedReviewDefaults.a68849a859',
|
||||
'Global default is'
|
||||
)}
|
||||
)}{' '}
|
||||
{inherited}.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -813,7 +813,7 @@ export function RuntimeEnvironmentsPane({
|
||||
className="h-8 min-w-0 font-mono text-xs"
|
||||
/>
|
||||
<p id="runtime-server-pairing-code-help" className="text-xs text-muted-foreground">
|
||||
{translate('auto.components.settings.RuntimeEnvironmentsPane.163671f7b5', 'Run')}
|
||||
{translate('auto.components.settings.RuntimeEnvironmentsPane.163671f7b5', 'Run')}{' '}
|
||||
<span className="font-mono">
|
||||
{translate(
|
||||
'auto.components.settings.RuntimeEnvironmentsPane.960e901ae4',
|
||||
|
||||
@@ -133,7 +133,7 @@ export function SshPassphraseDialog(): React.JSX.Element | null {
|
||||
{translate(
|
||||
'auto.components.settings.SshPassphraseDialog.dbf9b6f2d0',
|
||||
'Enter the password for'
|
||||
)}
|
||||
)}{' '}
|
||||
<span className="font-medium">{label}</span>
|
||||
</>
|
||||
) : (
|
||||
@@ -141,7 +141,7 @@ export function SshPassphraseDialog(): React.JSX.Element | null {
|
||||
{translate(
|
||||
'auto.components.settings.SshPassphraseDialog.ce4fdf7914',
|
||||
'Enter the passphrase for'
|
||||
)}
|
||||
)}{' '}
|
||||
<span className="font-medium">{label}</span>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -217,7 +217,7 @@ export function WslCliRegistration({
|
||||
{translate(
|
||||
'auto.components.settings.WslCliRegistration.1dbb0377d9',
|
||||
'Existing launcher target:'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>{status.currentTarget}</code>
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -21,7 +21,7 @@ export function DeleteWorktreeWarningPanels({
|
||||
{translate(
|
||||
'auto.components.sidebar.DeleteWorktreeWarningPanels.e3be9eba15',
|
||||
'This is the'
|
||||
)}
|
||||
)}{' '}
|
||||
<span className="font-semibold text-foreground">
|
||||
{translate(
|
||||
'auto.components.sidebar.DeleteWorktreeWarningPanels.c4f96a6e18',
|
||||
@@ -32,7 +32,7 @@ export function DeleteWorktreeWarningPanels({
|
||||
'auto.components.sidebar.DeleteWorktreeWarningPanels.026738155a',
|
||||
'(the original clone directory).'
|
||||
)}
|
||||
{mainWorktreeBlocker}
|
||||
{mainWorktreeBlocker ? <> {mainWorktreeBlocker}</> : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -71,7 +71,7 @@ export function DetectedSetupPreview({
|
||||
{translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCardViews.d02e6a42b1',
|
||||
'Detected from'
|
||||
)}
|
||||
)}{' '}
|
||||
<code className="rounded bg-muted px-1 py-0.5">{provenance}</code>
|
||||
</p>
|
||||
) : null}
|
||||
@@ -157,7 +157,7 @@ export function SetupScriptPromptBody({
|
||||
{translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCardViews.bb879db364',
|
||||
'This repo ignores shared'
|
||||
)}
|
||||
)}{' '}
|
||||
<code>
|
||||
{translate('auto.components.sidebar.SetupScriptPromptCardViews.8f6be51aa1', 'orca.yaml')}
|
||||
</code>{' '}
|
||||
@@ -184,7 +184,7 @@ export function SetupScriptPromptBody({
|
||||
{translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCardViews.b56d1322f7',
|
||||
'Found a setup command in'
|
||||
)}
|
||||
)}{' '}
|
||||
<span className="break-words">{candidateSource}</span>
|
||||
{translate(
|
||||
'auto.components.sidebar.SetupScriptPromptCardViews.8349e3fa4c',
|
||||
|
||||
@@ -233,7 +233,7 @@ function ChartHeader(props: {
|
||||
<div style={{ display: 'table-cell', verticalAlign: 'bottom', textAlign: 'right' }}>
|
||||
<span style={{ fontSize: 10, color: '#444' }}>
|
||||
{props.sessions}{' '}
|
||||
{translate('auto.components.stats.ShareUsageCard.4a4c6c79a3', 'sessions ·')}
|
||||
{translate('auto.components.stats.ShareUsageCard.4a4c6c79a3', 'sessions ·')}{' '}
|
||||
{props.turnsOrEvents.count} {props.turnsOrEvents.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -253,7 +253,7 @@ export function UsageOverviewPane(): React.JSX.Element {
|
||||
</h4>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{overview.enabledProviderCount}{' '}
|
||||
{translate('auto.components.stats.UsageOverviewPane.ecb0cd8a4c', 'enabled -')}
|
||||
{translate('auto.components.stats.UsageOverviewPane.ecb0cd8a4c', 'enabled -')}{' '}
|
||||
{overview.dataProviderCount}{' '}
|
||||
{translate('auto.components.stats.UsageOverviewPane.444585cb41', 'with data')}
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
/**
|
||||
* Guard against the i18n fragment glue-word class of bugs:
|
||||
* `translate('…', 'word')}` immediately followed by `<code>` / `{value}` without
|
||||
* an explicit `{' '}` space. Newline indentation alone is not reliable.
|
||||
*/
|
||||
const ROOT = path.resolve(__dirname, '..')
|
||||
|
||||
type GuardCase = {
|
||||
file: string
|
||||
/** English fallback that must be followed by `{' '}` before the next token. */
|
||||
afterFallback: string
|
||||
/** Human-readable description for assertion messages. */
|
||||
label: string
|
||||
}
|
||||
|
||||
const CASES: GuardCase[] = [
|
||||
{
|
||||
file: 'components/sidebar/SetupScriptPromptCardViews.tsx',
|
||||
afterFallback: 'This repo ignores shared',
|
||||
label: 'shared orca.yaml'
|
||||
},
|
||||
{
|
||||
file: 'components/sidebar/SetupScriptPromptCardViews.tsx',
|
||||
afterFallback: 'Detected from',
|
||||
label: 'Detected from provenance'
|
||||
},
|
||||
{
|
||||
file: 'components/sidebar/SetupScriptPromptCardViews.tsx',
|
||||
afterFallback: 'Found a setup command in',
|
||||
label: 'Found a setup command in source'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/RepositoryHooksSection.tsx',
|
||||
afterFallback: 'Example',
|
||||
label: 'Example orca.yaml template'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/RepositoryHooksSection.tsx',
|
||||
afterFallback: 'Edit',
|
||||
label: 'Edit orca.yaml'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/RepositoryHooksSection.tsx',
|
||||
afterFallback: 'When both',
|
||||
label: 'When both orca.yaml'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/GitPane.tsx',
|
||||
afterFallback: 'or',
|
||||
label: 'main or master'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/GitPane.tsx',
|
||||
afterFallback: 'such as',
|
||||
label: 'such as main'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/RuntimeEnvironmentsPane.tsx',
|
||||
afterFallback: 'Run',
|
||||
label: 'Run orca serve'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/AutoRenameBranchFromWorkSetting.tsx',
|
||||
afterFallback: 'Use',
|
||||
label: 'Use {basePrompt}'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/CommitMessageAiPane.tsx',
|
||||
afterFallback: 'Use',
|
||||
label: 'Use {prompt}'
|
||||
},
|
||||
{
|
||||
file: 'components/editor/RichMarkdownDocLinkMenu.tsx',
|
||||
afterFallback: 'Showing',
|
||||
label: 'Showing N of M'
|
||||
},
|
||||
{
|
||||
file: 'components/editor/RichMarkdownDocLinkMenu.tsx',
|
||||
afterFallback: 'of',
|
||||
label: 'of totalMatches'
|
||||
},
|
||||
{
|
||||
file: 'components/contextual-tours/ContextualTourProgressDots.tsx',
|
||||
afterFallback: 'of',
|
||||
label: 'tour of total'
|
||||
},
|
||||
{
|
||||
file: 'components/github/PRFilterSections.tsx',
|
||||
afterFallback: 'Filter',
|
||||
label: 'Filter pull requests'
|
||||
},
|
||||
{
|
||||
file: 'components/editor/ConflictComponents.tsx',
|
||||
afterFallback: 'Renamed from',
|
||||
label: 'Renamed from path'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/SshPassphraseDialog.tsx',
|
||||
afterFallback: 'Enter the password for',
|
||||
label: 'password for host'
|
||||
},
|
||||
{
|
||||
file: 'components/settings/ManageSessionKillDialog.tsx',
|
||||
afterFallback: 'Force-quits',
|
||||
label: 'Force-quits session id'
|
||||
},
|
||||
{
|
||||
file: 'components/sidebar/DeleteWorktreeWarningPanels.tsx',
|
||||
afterFallback: 'This is the',
|
||||
label: 'This is the main worktree'
|
||||
}
|
||||
]
|
||||
|
||||
function hasExplicitSpaceAfterFallback(source: string, fallback: string): boolean {
|
||||
// Match translate fallbacks that end with (or equal) the given phrase, then
|
||||
// require an explicit {' '} after the closing )} so JSX whitespace is not
|
||||
// left to indentation alone.
|
||||
const escaped = fallback.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
const pattern = new RegExp(
|
||||
String.raw`translate\(\s*'[^']+',\s*(?:'[^']*${escaped}'|"[^"]*${escaped}")\s*(?:,\s*\{[^}]*\})?\s*\)\s*\}\s*\{\s*['"]\s['"]\s*\}`,
|
||||
'm'
|
||||
)
|
||||
return pattern.test(source)
|
||||
}
|
||||
|
||||
describe('i18n JSX fragment spacing guard', () => {
|
||||
for (const testCase of CASES) {
|
||||
it(`keeps an explicit space after "${testCase.label}" in ${testCase.file}`, () => {
|
||||
const source = readFileSync(path.join(ROOT, testCase.file), 'utf8')
|
||||
expect(
|
||||
hasExplicitSpaceAfterFallback(source, testCase.afterFallback),
|
||||
`Expected {' '} immediately after translate fallback "${testCase.afterFallback}" in ${testCase.file}`
|
||||
).toBe(true)
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user