feat(ui): show GitLab merge request status in walkthrough, git view and work status
This commit is contained in:
@@ -4,6 +4,8 @@ import { useGitStore } from '@/stores/useGitStore';
|
||||
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
|
||||
import { runBackgroundNetworkTask } from '@/lib/background-network';
|
||||
import { getGitHubPrStatusKey, usePrVisualSummary } from '@/stores/useGitHubPrStatusStore';
|
||||
import { useGitLabMrForBranch } from '@/lib/gitlabMrStatus';
|
||||
import { useGitProvider } from '@/lib/gitProvider';
|
||||
import { useSession, useSessionMessages } from '@/sync/sync-context';
|
||||
import { useConfigStore } from '@/stores/useConfigStore';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
@@ -113,6 +115,12 @@ export const WorkStatusPrimaryGroup: React.FC<Props> = ({ sessionId, directory,
|
||||
);
|
||||
const prSummary = usePrVisualSummary(prKey);
|
||||
|
||||
// GitLab merge requests ride the same shared TTL cache as the git view and
|
||||
// the walkthrough, so every surface that reports the branch's request stays
|
||||
// consistent without extra requests.
|
||||
const gitProvider = useGitProvider(directory);
|
||||
const { mr: gitLabMr } = useGitLabMrForBranch(directory, branch);
|
||||
|
||||
// `getCurrentModel` is an imperative getter: its reference never changes, so
|
||||
// calling it in render subscribes to nothing. Subscribe to the selected model
|
||||
// ids and recompute the limits from those.
|
||||
@@ -201,7 +209,17 @@ export const WorkStatusPrimaryGroup: React.FC<Props> = ({ sessionId, directory,
|
||||
|
||||
const cost = typeof session?.cost === 'number' && session.cost > 0 ? session.cost : null;
|
||||
const hasSession = showSession && (usagePercent !== null || cost !== null || Boolean(goalRow));
|
||||
const hasRepository = showRepository && Boolean(branch || changed || prSummary || attentionLabel);
|
||||
const hasGitLabMr = gitProvider === 'gitlab' && gitLabMr !== null;
|
||||
const gitLabMrVisualState = gitLabMr
|
||||
? gitLabMr.state === 'merged'
|
||||
? 'merged'
|
||||
: gitLabMr.state === 'closed'
|
||||
? 'closed'
|
||||
: gitLabMr.draft
|
||||
? 'draft'
|
||||
: 'open'
|
||||
: null;
|
||||
const hasRepository = showRepository && Boolean(branch || changed || prSummary || attentionLabel || hasGitLabMr);
|
||||
|
||||
useReportWorkStatusPresence('session-repository', hasSession || hasRepository);
|
||||
|
||||
@@ -284,6 +302,24 @@ export const WorkStatusPrimaryGroup: React.FC<Props> = ({ sessionId, directory,
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{hasGitLabMr && gitLabMr ? (
|
||||
<WorkStatusRow
|
||||
icon="git-merge"
|
||||
onClick={directory ? () => openSurface('pr') : undefined}
|
||||
ariaLabel={t('chat.workStatus.action.openMr')}
|
||||
iconColor={`var(--pr-${gitLabMrVisualState})`}
|
||||
label={gitLabMr.title || t('chat.workStatus.mr.untitled')}
|
||||
value={(
|
||||
<WorkStatusPill
|
||||
color={`var(--pr-${gitLabMrVisualState})`}
|
||||
background={`color-mix(in srgb, var(--pr-${gitLabMrVisualState}) 18%, transparent)`}
|
||||
>
|
||||
{gitLabMr.draft ? t('chat.workStatus.pr.draft') : `!${gitLabMr.number}`}
|
||||
</WorkStatusPill>
|
||||
)}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{prSummary ? (
|
||||
<>
|
||||
<WorkStatusRow
|
||||
|
||||
@@ -59,6 +59,7 @@ import { InProgressOperationBanner } from './git/InProgressOperationBanner';
|
||||
import { BranchIntegrationSection, type OperationLogEntry } from './git/BranchIntegrationSection';
|
||||
import { deriveBaseBranch } from './git/baseBranch';
|
||||
import { getFreshestPrStatusForBranch, useGitHubPrStatusStore } from '@/stores/useGitHubPrStatusStore';
|
||||
import { useGitLabMrForBranch } from '@/lib/gitlabMrStatus';
|
||||
import { createGitIndexMutationQueue, type GitIndexMutationDirection, type GitIndexMutationQueue } from './git/gitIndexMutationQueue';
|
||||
import type { GitRemote } from '@/lib/gitApi';
|
||||
import { getRootBranch } from '@/lib/worktrees/worktreeStatus';
|
||||
@@ -304,6 +305,7 @@ export const GitView: React.FC<GitViewProps> = ({ isActive }) => {
|
||||
const openContextSurface = useUIStore((state) => state.openContextSurface);
|
||||
|
||||
const prStatusBranch = status?.current ?? null;
|
||||
const { mr: gitLabMr } = useGitLabMrForBranch(currentDirectory, prStatusBranch);
|
||||
const prChipStatus = useGitHubPrStatusStore((state) => {
|
||||
if (!currentDirectory || !prStatusBranch) {
|
||||
return null;
|
||||
@@ -2361,6 +2363,10 @@ export const GitView: React.FC<GitViewProps> = ({ isActive }) => {
|
||||
onOpenPullRequest={
|
||||
currentDirectory ? () => openContextSurface(currentDirectory, 'pr') : undefined
|
||||
}
|
||||
gitLabMr={gitLabMr}
|
||||
onOpenGitLabMr={
|
||||
currentDirectory ? () => openContextSurface(currentDirectory, 'pr') : undefined
|
||||
}
|
||||
/>
|
||||
|
||||
{/* In-progress operation banner */}
|
||||
|
||||
@@ -19,6 +19,7 @@ import type {
|
||||
GitRemoteComparison,
|
||||
GitHubPullRequest,
|
||||
GitHubChecksSummary,
|
||||
GitLabMergeRequestSummary,
|
||||
} from '@/lib/api/types';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
|
||||
@@ -51,6 +52,8 @@ interface GitHeaderProps {
|
||||
pullRequest?: GitHubPullRequest | null;
|
||||
prChecks?: GitHubChecksSummary | null;
|
||||
onOpenPullRequest?: () => void;
|
||||
gitLabMr?: GitLabMergeRequestSummary | null;
|
||||
onOpenGitLabMr?: () => void;
|
||||
}
|
||||
|
||||
const IDENTITY_ICON_MAP: Record<string, IconName> = {
|
||||
@@ -258,6 +261,8 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
pullRequest,
|
||||
prChecks,
|
||||
onOpenPullRequest,
|
||||
gitLabMr,
|
||||
onOpenGitLabMr,
|
||||
}) => {
|
||||
const { t } = useI18n();
|
||||
if (!status) {
|
||||
@@ -371,6 +376,40 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
</Tooltip>
|
||||
) : null;
|
||||
|
||||
// GitLab merge request chip, mirroring the GitHub PR chip above. GitLab
|
||||
// states are surfaced with the same PR state palette so merged/closed/open
|
||||
// read identically across providers.
|
||||
const gitLabMrVisualState = gitLabMr
|
||||
? gitLabMr.state === 'merged'
|
||||
? 'merged'
|
||||
: gitLabMr.state === 'closed'
|
||||
? 'closed'
|
||||
: gitLabMr.draft
|
||||
? 'draft'
|
||||
: 'open'
|
||||
: null;
|
||||
|
||||
const gitLabMrChip = gitLabMr && onOpenGitLabMr ? (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onOpenGitLabMr}
|
||||
className="h-8 gap-1.5 px-2 typography-micro"
|
||||
>
|
||||
<Icon
|
||||
name="git-merge"
|
||||
className="size-3.5"
|
||||
style={{ color: `var(--pr-${gitLabMrVisualState})` }}
|
||||
/>
|
||||
<span className="tabular-nums text-foreground/80">!{gitLabMr.number}</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent sideOffset={8}>{t('gitView.header.openMergeRequest')}</TooltipContent>
|
||||
</Tooltip>
|
||||
) : null;
|
||||
|
||||
const syncButtons = (
|
||||
<SyncActions
|
||||
syncAction={syncAction}
|
||||
@@ -435,6 +474,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
|
||||
<div className="mt-3 flex h-8 min-w-0 items-center gap-2">
|
||||
{prChip ? <div className="shrink-0">{prChip}</div> : null}
|
||||
{gitLabMrChip ? <div className="shrink-0">{gitLabMrChip}</div> : null}
|
||||
<div className="min-w-0 flex-1" />
|
||||
{upstreamStatusPill ? (
|
||||
<div className="min-w-0 shrink">{upstreamStatusPill}</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
|
||||
import { useI18n, type Locale } from '@/lib/i18n';
|
||||
import { openExternalUrl } from '@/lib/url';
|
||||
import { useGitProvider } from '@/lib/gitProvider';
|
||||
import { useGitLabMrForBranch } from '@/lib/gitlabMrStatus';
|
||||
import { buildWalkthroughView } from '@/lib/walkthrough/model';
|
||||
import type { WalkthroughSource, WalkthroughWorkingTreeScope } from '@/lib/walkthrough/types';
|
||||
import { ModelSelector } from '@/components/sections/agents/ModelSelector';
|
||||
@@ -210,6 +211,7 @@ export const WalkthroughView = ({ directory }: WalkthroughViewProps) => {
|
||||
const setPrStatusParams = useGitHubPrStatusStore((state) => state.setParams);
|
||||
const refreshPrStatusTargets = useGitHubPrStatusStore((state) => state.refreshTargets);
|
||||
const gitProvider = useGitProvider(directory);
|
||||
const gitLabMr = useGitLabMrForBranch(directory, currentBranch);
|
||||
|
||||
useEffect(() => {
|
||||
if (!directory || !currentBranch || !githubAuthChecked || !githubConnected || gitProvider !== 'github') return;
|
||||
@@ -250,12 +252,18 @@ export const WalkthroughView = ({ directory }: WalkthroughViewProps) => {
|
||||
[requestedSource, scope]
|
||||
);
|
||||
|
||||
// Offer whichever pull request we know about: the one already selected, or
|
||||
// the one this branch has.
|
||||
// Offer whichever pull request or merge request we know about: the one
|
||||
// already selected, or the one this branch has. GitLab repos get their MR
|
||||
// number from the branch lookup; everything else falls back to the GitHub PR
|
||||
// status store, which the polling effect above only fills for GitHub repos.
|
||||
const prSource = useMemo<Extract<WalkthroughSource, { kind: 'pr' }> | null>(() => {
|
||||
if (source.kind === 'pr') return source;
|
||||
if (gitProvider === 'gitlab') {
|
||||
const number = gitLabMr.mr?.number;
|
||||
return number ? { kind: 'pr', number } : null;
|
||||
}
|
||||
return branchPrNumber ? { kind: 'pr', number: branchPrNumber } : null;
|
||||
}, [branchPrNumber, source]);
|
||||
}, [branchPrNumber, gitLabMr.mr, gitProvider, source]);
|
||||
|
||||
const selectWorkingTree = useCallback(
|
||||
(value: WalkthroughWorkingTreeScope) => {
|
||||
@@ -341,7 +349,9 @@ export const WalkthroughView = ({ directory }: WalkthroughViewProps) => {
|
||||
const sourceLabel = source.kind === 'branch'
|
||||
? t('walkthrough.scope.branch')
|
||||
: source.kind === 'pr'
|
||||
? t('walkthrough.scope.pullRequest', { number: source.number })
|
||||
? gitProvider === 'gitlab'
|
||||
? t('walkthrough.scope.mergeRequest', { number: source.number })
|
||||
: t('walkthrough.scope.pullRequest', { number: source.number })
|
||||
: scope === 'all'
|
||||
? t('walkthrough.scope.all')
|
||||
: scope === 'staged'
|
||||
@@ -547,7 +557,9 @@ export const WalkthroughView = ({ directory }: WalkthroughViewProps) => {
|
||||
)}
|
||||
{prSource && (
|
||||
<DropdownMenuRadioItem value="pr">
|
||||
{t('walkthrough.scope.pullRequest', { number: prSource.number })}
|
||||
{gitProvider === 'gitlab'
|
||||
? t('walkthrough.scope.mergeRequest', { number: prSource.number })
|
||||
: t('walkthrough.scope.pullRequest', { number: prSource.number })}
|
||||
</DropdownMenuRadioItem>
|
||||
)}
|
||||
</DropdownMenuRadioGroup>
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test';
|
||||
import type { GitLabMergeRequestSummary } from '@/lib/api/types';
|
||||
|
||||
const mrsListCalls: Array<{ directory: string; options?: { sourceBranch?: string } }> = [];
|
||||
let mrsListResult: GitLabMergeRequestSummary[] = [];
|
||||
let mrsListFailure: Error | null = null;
|
||||
let registryHasGitlab = true;
|
||||
|
||||
mock.module('@/contexts/runtimeAPIRegistry', () => ({
|
||||
getRegisteredRuntimeAPIs: () => {
|
||||
if (!registryHasGitlab) return null;
|
||||
return {
|
||||
gitlab: {
|
||||
mrsList: (directory: string, options?: { sourceBranch?: string }) => {
|
||||
mrsListCalls.push({ directory, options });
|
||||
if (mrsListFailure) {
|
||||
return Promise.reject(mrsListFailure);
|
||||
}
|
||||
const all = mrsListResult;
|
||||
const filtered = options?.sourceBranch
|
||||
? all.filter((item) => item.sourceBranch === options.sourceBranch)
|
||||
: all;
|
||||
return Promise.resolve({ mrs: filtered });
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}));
|
||||
|
||||
const { resolveGitLabMrForBranch } = await import('./gitlabMrStatus');
|
||||
|
||||
const mr = (number: number, state: string, sourceBranch: string): GitLabMergeRequestSummary => ({
|
||||
number,
|
||||
title: `MR ${number}`,
|
||||
url: `https://gitlab.example/${number}`,
|
||||
state,
|
||||
draft: false,
|
||||
author: { id: 1, username: 'user', name: 'User' },
|
||||
sourceBranch,
|
||||
targetBranch: 'main',
|
||||
});
|
||||
|
||||
describe('resolveGitLabMrForBranch', () => {
|
||||
beforeEach(() => {
|
||||
mrsListCalls.length = 0;
|
||||
mrsListResult = [];
|
||||
mrsListFailure = null;
|
||||
registryHasGitlab = true;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mrsListCalls.length = 0;
|
||||
mrsListResult = [];
|
||||
mrsListFailure = null;
|
||||
registryHasGitlab = true;
|
||||
});
|
||||
|
||||
test('prefers the opened MR over a merged one for the branch', async () => {
|
||||
mrsListResult = [mr(3, 'merged', 'feat/a'), mr(7, 'opened', 'feat/a')];
|
||||
|
||||
const result = await resolveGitLabMrForBranch('/repo', 'feat/a');
|
||||
|
||||
expect(result?.number).toBe(7);
|
||||
expect(mrsListCalls).toEqual([
|
||||
{ directory: '/repo', options: { sourceBranch: 'feat/a' } },
|
||||
]);
|
||||
});
|
||||
|
||||
test('falls back to a merged MR when no opened one exists', async () => {
|
||||
mrsListResult = [mr(5, 'merged', 'feat/b'), mr(9, 'closed', 'feat/b')];
|
||||
|
||||
const result = await resolveGitLabMrForBranch('/repo', 'feat/b');
|
||||
|
||||
expect(result?.number).toBe(5);
|
||||
});
|
||||
|
||||
test('returns null when no MR matches the branch', async () => {
|
||||
mrsListResult = [mr(5, 'merged', 'feat/a')];
|
||||
|
||||
const result = await resolveGitLabMrForBranch('/repo', 'feat/c');
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(mrsListCalls).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('returns null without calling the API when the runtime has no GitLab client', async () => {
|
||||
registryHasGitlab = false;
|
||||
|
||||
const result = await resolveGitLabMrForBranch('/repo', 'feat/a');
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(mrsListCalls).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('returns null and caches when the request fails', async () => {
|
||||
mrsListFailure = new Error('boom');
|
||||
|
||||
const first = await resolveGitLabMrForBranch('/repo', 'fail-branch');
|
||||
expect(first).toBeNull();
|
||||
|
||||
mrsListFailure = null;
|
||||
mrsListResult = [mr(1, 'opened', 'fail-branch')];
|
||||
// Same directory+branch within TTL must not re-request.
|
||||
const second = await resolveGitLabMrForBranch('/repo', 'fail-branch');
|
||||
expect(second).toBeNull();
|
||||
expect(mrsListCalls).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('serves the second call from cache within the TTL window', async () => {
|
||||
mrsListResult = [mr(7, 'opened', 'cache-branch')];
|
||||
|
||||
const first = await resolveGitLabMrForBranch('/repo', 'cache-branch');
|
||||
const second = await resolveGitLabMrForBranch('/repo', 'cache-branch');
|
||||
|
||||
expect(first?.number).toBe(7);
|
||||
expect(second?.number).toBe(7);
|
||||
expect(mrsListCalls).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
|
||||
import type { GitLabMergeRequestSummary } from '@/lib/api/types';
|
||||
|
||||
// Branch MR lookups are cheap to re-request but visible to the user on every
|
||||
// mount of the surfaces that display them (walkthrough header, git view, work
|
||||
// status). A shared TTL cache keeps those surfaces consistent with each other
|
||||
// and stops repeated GitLab calls while a branch is in view.
|
||||
const CACHE_TTL_MS = 90_000;
|
||||
const mrCache = new Map<string, { at: number; mr: GitLabMergeRequestSummary | null }>();
|
||||
|
||||
const cacheKeyFor = (directory: string, branch: string): string => `${directory}\n${branch}`;
|
||||
|
||||
const readCachedMr = (directory: string, branch: string): GitLabMergeRequestSummary | null | undefined => {
|
||||
const entry = mrCache.get(cacheKeyFor(directory, branch));
|
||||
return entry?.mr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve the merge request targeting `branch` in `directory`, preferring the
|
||||
* opened request and falling back to a merged one so a just-merged branch still
|
||||
* surfaces its request instead of nothing.
|
||||
*
|
||||
* Returns null when the runtime has no GitLab API, the request fails, or no MR
|
||||
* matches — callers only use the result to show or hide an additive chip, so a
|
||||
* null answer simply means "nothing to show". Results are cached per
|
||||
* directory+branch for CACHE_TTL_MS, including the null case.
|
||||
*/
|
||||
export const resolveGitLabMrForBranch = async (
|
||||
directory: string,
|
||||
branch: string,
|
||||
): Promise<GitLabMergeRequestSummary | null> => {
|
||||
const gitlab = getRegisteredRuntimeAPIs()?.gitlab;
|
||||
if (!gitlab?.mrsList || !directory || !branch) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = cacheKeyFor(directory, branch);
|
||||
const cached = mrCache.get(key);
|
||||
if (cached && Date.now() - cached.at < CACHE_TTL_MS) {
|
||||
return cached.mr;
|
||||
}
|
||||
|
||||
let mr: GitLabMergeRequestSummary | null = null;
|
||||
try {
|
||||
const result = await gitlab.mrsList(directory, { sourceBranch: branch });
|
||||
const candidates = result.mrs ?? [];
|
||||
mr = candidates.find((item) => item.state === 'opened')
|
||||
?? candidates.find((item) => item.state === 'merged')
|
||||
?? null;
|
||||
} catch {
|
||||
mr = null;
|
||||
}
|
||||
|
||||
mrCache.set(key, { at: Date.now(), mr });
|
||||
return mr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribe to the branch's merge request. Reads the TTL cache synchronously
|
||||
* for the initial render so an already-resolved MR never flashes away while a
|
||||
* refresh runs; a cache miss shows a loading state instead of a stale result
|
||||
* from another branch.
|
||||
*/
|
||||
export const useGitLabMrForBranch = (
|
||||
directory: string | null | undefined,
|
||||
branch: string | null | undefined,
|
||||
): { mr: GitLabMergeRequestSummary | null; isLoading: boolean } => {
|
||||
const [mr, setMr] = useState<GitLabMergeRequestSummary | null>(() =>
|
||||
directory && branch ? (readCachedMr(directory, branch) ?? null) : null
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!directory || !branch) {
|
||||
setMr(null);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let mounted = true;
|
||||
const cached = readCachedMr(directory, branch);
|
||||
const cacheEntry = mrCache.get(cacheKeyFor(directory, branch));
|
||||
const fresh = cacheEntry !== undefined && Date.now() - cacheEntry.at < CACHE_TTL_MS;
|
||||
|
||||
if (fresh) {
|
||||
setMr(cached ?? null);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// A stale entry stays on screen while it refreshes; a missing one shows
|
||||
// the loading state rather than a result from a previous branch.
|
||||
setMr(cached ?? null);
|
||||
setIsLoading(true);
|
||||
|
||||
void resolveGitLabMrForBranch(directory, branch).then((resolved) => {
|
||||
if (mounted) {
|
||||
setMr(resolved);
|
||||
setIsLoading(false);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
mounted = false;
|
||||
};
|
||||
}, [directory, branch]);
|
||||
|
||||
return { mr, isLoading };
|
||||
};
|
||||
@@ -2968,6 +2968,7 @@ export const dict = {
|
||||
'sessions.sidebar.session.status.movingToWorktree': 'Sitzung wird in einen neuen Worktree verschoben',
|
||||
'gitView.header.updateBranch': 'Branch aktualisieren',
|
||||
'gitView.header.openPullRequest': 'Pull Request öffnen',
|
||||
'gitView.header.openMergeRequest': 'Merge Request öffnen',
|
||||
'gitView.history.refresh': 'Verlauf aktualisieren',
|
||||
'gitView.operation.inProgressTitleManyConflicts': 'Operation {operation} läuft: {count} Konflikte',
|
||||
'gitView.operation.inProgressTitleOneConflict': 'Operation {operation} läuft: {count} Konflikt',
|
||||
@@ -3022,6 +3023,7 @@ export const dict = {
|
||||
'walkthrough.missing.languageAndModel': 'Noch kein Walkthrough auf dieser Sprache von diesem Modell vorhanden — zeige den zuletzt hier erstellten.',
|
||||
'walkthrough.language.selectorAria': 'Sprache auswählen',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': 'Generieren',
|
||||
'walkthrough.action.regenerate': 'Erneut generieren',
|
||||
'walkthrough.action.cancel': 'Abbrechen',
|
||||
@@ -3109,6 +3111,7 @@ export const dict = {
|
||||
'chat.workStatus.git.changedFileSingle': '{count} Datei geändert',
|
||||
'chat.workStatus.git.changedFilePlural': '{count} Dateien geändert',
|
||||
'chat.workStatus.pr.untitled': 'Pull Request ohne Titel',
|
||||
'chat.workStatus.mr.untitled': 'Merge Request ohne Titel',
|
||||
'chat.workStatus.pr.draft': 'Entwurf',
|
||||
'chat.workStatus.pr.checks': 'Prüfungen',
|
||||
'chat.workStatus.pr.checksFailed': '{count} fehlgeschlagen',
|
||||
@@ -3140,6 +3143,7 @@ export const dict = {
|
||||
'chat.workStatus.action.openChanges': 'Änderungen öffnen',
|
||||
'chat.workStatus.action.openGit': 'Git-Panel öffnen',
|
||||
'chat.workStatus.action.openPr': 'Pull Request öffnen',
|
||||
'chat.workStatus.action.openMr': 'Merge Request öffnen',
|
||||
'chat.workStatus.action.openSubagent': '{name} öffnen',
|
||||
'chat.workStatus.section.usage': 'Nutzung',
|
||||
'chat.workStatus.goal.open': 'Ziel verwalten',
|
||||
|
||||
@@ -770,6 +770,7 @@ export const dict = {
|
||||
'gitView.header.repositoryViews': 'Repository views',
|
||||
'gitView.header.updateBranch': 'Update branch',
|
||||
'gitView.header.openPullRequest': 'Open pull request',
|
||||
'gitView.header.openMergeRequest': 'Open merge request',
|
||||
'gitView.header.removeRemoteAria': 'Remove remote {name}',
|
||||
'gitView.header.removeRemoteTitle': 'Remove remote {name}',
|
||||
'gitView.header.upstreamSynced': 'synced',
|
||||
@@ -1160,6 +1161,7 @@ export const dict = {
|
||||
'walkthrough.missing.languageAndModel': 'No walkthrough in this language from this model yet — showing the last one generated here.',
|
||||
'walkthrough.language.selectorAria': 'Select the walkthrough language',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': 'Generate walkthrough',
|
||||
'walkthrough.action.regenerate': 'Regenerate',
|
||||
'walkthrough.action.cancel': 'Cancel',
|
||||
@@ -3111,6 +3113,7 @@ export const dict = {
|
||||
'chat.workStatus.git.changedFileSingle': '{count} file changed',
|
||||
'chat.workStatus.git.changedFilePlural': '{count} files changed',
|
||||
'chat.workStatus.pr.untitled': 'Untitled pull request',
|
||||
'chat.workStatus.mr.untitled': 'Untitled merge request',
|
||||
'chat.workStatus.pr.draft': 'Draft',
|
||||
'chat.workStatus.pr.checks': 'Checks',
|
||||
'chat.workStatus.pr.checksFailed': '{count} failed',
|
||||
@@ -3142,6 +3145,7 @@ export const dict = {
|
||||
'chat.workStatus.action.openChanges': 'Open changes',
|
||||
'chat.workStatus.action.openGit': 'Open Git panel',
|
||||
'chat.workStatus.action.openPr': 'Open pull request',
|
||||
'chat.workStatus.action.openMr': 'Open merge request',
|
||||
'chat.workStatus.action.openSubagent': 'Open {name}',
|
||||
'chat.workStatus.section.usage': 'Usage',
|
||||
'chat.workStatus.goal.open': 'Manage goal',
|
||||
|
||||
@@ -771,6 +771,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"gitView.header.repositoryViews": "Vistas del repositorio",
|
||||
"gitView.header.updateBranch": "Actualizar rama",
|
||||
"gitView.header.openPullRequest": "Abrir pull request",
|
||||
"gitView.header.openMergeRequest": "Abrir solicitud de fusión",
|
||||
"gitView.header.removeRemoteAria": "Eliminar remoto",
|
||||
"gitView.header.removeRemoteTitle": "Eliminar remoto",
|
||||
"gitView.header.upstreamSynced": "sincronizado",
|
||||
@@ -1161,6 +1162,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"walkthrough.missing.languageAndModel": "Aún no hay un recorrido en este idioma con este modelo: se muestra el último generado aquí.",
|
||||
"walkthrough.language.selectorAria": "Elegir el idioma del recorrido",
|
||||
"walkthrough.scope.pullRequest": "PR n.º {number}",
|
||||
"walkthrough.scope.mergeRequest": "MR !{number}",
|
||||
"walkthrough.action.generate": "Generar recorrido",
|
||||
"walkthrough.action.regenerate": "Regenerar",
|
||||
"walkthrough.action.cancel": "Cancelar",
|
||||
@@ -3112,6 +3114,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': '{count} archivo modificado',
|
||||
'chat.workStatus.git.changedFilePlural': '{count} archivos modificados',
|
||||
'chat.workStatus.pr.untitled': 'Pull request sin título',
|
||||
'chat.workStatus.mr.untitled': 'Solicitud de fusión sin título',
|
||||
'chat.workStatus.pr.draft': 'Borrador',
|
||||
'chat.workStatus.pr.checks': 'Comprobaciones',
|
||||
'chat.workStatus.pr.checksFailed': '{count} fallaron',
|
||||
@@ -3143,6 +3146,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': 'Abrir cambios',
|
||||
'chat.workStatus.action.openGit': 'Abrir panel de Git',
|
||||
'chat.workStatus.action.openPr': 'Abrir pull request',
|
||||
'chat.workStatus.action.openMr': 'Abrir solicitud de fusión',
|
||||
'chat.workStatus.action.openSubagent': 'Abrir {name}',
|
||||
'chat.workStatus.section.usage': 'Uso',
|
||||
'chat.workStatus.goal.open': 'Gestionar objetivo',
|
||||
|
||||
@@ -594,6 +594,7 @@ export const dict = {
|
||||
'gitView.header.repositoryViews': 'Vues du dépôt',
|
||||
'gitView.header.updateBranch': 'Mettre à jour la branche',
|
||||
'gitView.header.openPullRequest': 'Ouvrir la pull request',
|
||||
'gitView.header.openMergeRequest': 'Ouvrir la demande de fusion',
|
||||
'gitView.header.removeRemoteAria': 'Supprimer le remote',
|
||||
'gitView.header.removeRemoteTitle': 'Supprimer le remote',
|
||||
'gitView.header.upstreamSynced': 'synchronisé',
|
||||
@@ -980,6 +981,7 @@ export const dict = {
|
||||
'walkthrough.missing.languageAndModel': 'Pas encore de parcours dans cette langue avec ce modèle — voici le dernier généré ici.',
|
||||
'walkthrough.language.selectorAria': 'Choisir la langue du parcours',
|
||||
'walkthrough.scope.pullRequest': 'PR n° {number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': 'Générer le parcours',
|
||||
'walkthrough.action.regenerate': 'Régénérer',
|
||||
'walkthrough.action.cancel': 'Annuler',
|
||||
@@ -3109,6 +3111,7 @@ export const dict = {
|
||||
'chat.workStatus.git.changedFileSingle': '{count} fichier modifié',
|
||||
'chat.workStatus.git.changedFilePlural': '{count} fichiers modifiés',
|
||||
'chat.workStatus.pr.untitled': 'Pull request sans titre',
|
||||
'chat.workStatus.mr.untitled': 'Demande de fusion sans titre',
|
||||
'chat.workStatus.pr.draft': 'Brouillon',
|
||||
'chat.workStatus.pr.checks': 'Vérifications',
|
||||
'chat.workStatus.pr.checksFailed': '{count} en échec',
|
||||
@@ -3140,6 +3143,7 @@ export const dict = {
|
||||
'chat.workStatus.action.openChanges': 'Ouvrir les modifications',
|
||||
'chat.workStatus.action.openGit': 'Ouvrir le panneau Git',
|
||||
'chat.workStatus.action.openPr': 'Ouvrir la pull request',
|
||||
'chat.workStatus.action.openMr': 'Ouvrir la demande de fusion',
|
||||
'chat.workStatus.action.openSubagent': 'Ouvrir {name}',
|
||||
'chat.workStatus.section.usage': 'Utilisation',
|
||||
'chat.workStatus.goal.open': 'Gérer l’objectif',
|
||||
|
||||
@@ -768,6 +768,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.header.repositoryViews': 'リポジトリビュー',
|
||||
'gitView.header.updateBranch': 'ブランチを更新',
|
||||
'gitView.header.openPullRequest': 'プルリクエストを開く',
|
||||
'gitView.header.openMergeRequest': 'マージリクエストを開く',
|
||||
'gitView.header.removeRemoteAria': 'リモート{name}を削除',
|
||||
'gitView.header.removeRemoteTitle': 'リモート{name}を削除',
|
||||
'gitView.header.upstreamSynced': '同期済み',
|
||||
@@ -1157,6 +1158,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'walkthrough.missing.languageAndModel': 'この言語・このモデルのウォークスルーはまだありません。ここで最後に生成されたものを表示しています。',
|
||||
'walkthrough.language.selectorAria': 'ウォークスルーの言語を選択',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': 'ウォークスルーを生成',
|
||||
'walkthrough.action.regenerate': '再生成',
|
||||
'walkthrough.action.cancel': 'キャンセル',
|
||||
@@ -3111,6 +3113,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': '{count} 件のファイルを変更',
|
||||
'chat.workStatus.git.changedFilePlural': '{count} 件のファイルを変更',
|
||||
'chat.workStatus.pr.untitled': 'タイトルなしのプルリクエスト',
|
||||
'chat.workStatus.mr.untitled': 'タイトルなしのマージリクエスト',
|
||||
'chat.workStatus.pr.draft': 'ドラフト',
|
||||
'chat.workStatus.pr.checks': 'チェック',
|
||||
'chat.workStatus.pr.checksFailed': '{count} 件失敗',
|
||||
@@ -3142,6 +3145,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': '変更を開く',
|
||||
'chat.workStatus.action.openGit': 'Git パネルを開く',
|
||||
'chat.workStatus.action.openPr': 'プルリクエストを開く',
|
||||
'chat.workStatus.action.openMr': 'マージリクエストを開く',
|
||||
'chat.workStatus.action.openSubagent': '{name} を開く',
|
||||
'chat.workStatus.section.usage': '使用量',
|
||||
'chat.workStatus.goal.open': '目標を管理',
|
||||
|
||||
@@ -771,6 +771,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.header.repositoryViews': '저장소 보기',
|
||||
'gitView.header.updateBranch': '브랜치 업데이트',
|
||||
'gitView.header.openPullRequest': '풀 리퀘스트 열기',
|
||||
'gitView.header.openMergeRequest': '머지 리퀘스트 열기',
|
||||
'gitView.header.removeRemoteAria': '리모트 제거',
|
||||
'gitView.header.removeRemoteTitle': '리모트 제거',
|
||||
'gitView.header.upstreamSynced': '동기화됨',
|
||||
@@ -1161,6 +1162,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'walkthrough.missing.languageAndModel': '이 언어와 이 모델로 생성한 워크스루가 아직 없어 마지막으로 생성된 것을 표시합니다.',
|
||||
'walkthrough.language.selectorAria': '워크스루 언어 선택',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': '워크스루 생성',
|
||||
'walkthrough.action.regenerate': '다시 생성',
|
||||
'walkthrough.action.cancel': '취소',
|
||||
@@ -3111,6 +3113,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': '파일 {count}개 변경됨',
|
||||
'chat.workStatus.git.changedFilePlural': '파일 {count}개 변경됨',
|
||||
'chat.workStatus.pr.untitled': '제목 없는 풀 리퀘스트',
|
||||
'chat.workStatus.mr.untitled': '제목 없는 머지 리퀘스트',
|
||||
'chat.workStatus.pr.draft': '초안',
|
||||
'chat.workStatus.pr.checks': '검사',
|
||||
'chat.workStatus.pr.checksFailed': '{count}개 실패',
|
||||
@@ -3142,6 +3145,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': '변경 사항 열기',
|
||||
'chat.workStatus.action.openGit': 'Git 패널 열기',
|
||||
'chat.workStatus.action.openPr': '풀 리퀘스트 열기',
|
||||
'chat.workStatus.action.openMr': '머지 리퀘스트 열기',
|
||||
'chat.workStatus.action.openSubagent': '{name} 열기',
|
||||
'chat.workStatus.section.usage': '사용량',
|
||||
'chat.workStatus.goal.open': '목표 관리',
|
||||
|
||||
@@ -1498,6 +1498,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'walkthrough.missing.languageAndModel': 'Nie ma jeszcze przewodnika w tym języku od tego modelu — pokazujemy ostatni wygenerowany tutaj.',
|
||||
'walkthrough.language.selectorAria': 'Wybierz język przewodnika',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': 'Wygeneruj przewodnik',
|
||||
'walkthrough.action.regenerate': 'Wygeneruj ponownie',
|
||||
'walkthrough.action.cancel': 'Anuluj',
|
||||
@@ -2074,6 +2075,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.header.repositoryViews': 'Widoki repozytorium',
|
||||
'gitView.header.updateBranch': 'Zaktualizuj gałąź',
|
||||
'gitView.header.openPullRequest': 'Otwórz pull request',
|
||||
'gitView.header.openMergeRequest': 'Otwórz żądanie scalenia',
|
||||
'gitView.header.removeRemoteAria': 'Usuń remote {name}',
|
||||
'gitView.header.removeRemoteTitle': 'Usuń remote {name}',
|
||||
'gitView.header.upstreamSynced': 'zsynchronizowano',
|
||||
@@ -3128,6 +3130,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': 'Zmieniono {count} plik',
|
||||
'chat.workStatus.git.changedFilePlural': 'Zmieniono {count} plików',
|
||||
'chat.workStatus.pr.untitled': 'Pull request bez tytułu',
|
||||
'chat.workStatus.mr.untitled': 'Żądanie scalenia bez tytułu',
|
||||
'chat.workStatus.pr.draft': 'Szkic',
|
||||
'chat.workStatus.pr.checks': 'Sprawdzenia',
|
||||
'chat.workStatus.pr.checksFailed': '{count} nieudanych',
|
||||
@@ -3159,6 +3162,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': 'Otwórz zmiany',
|
||||
'chat.workStatus.action.openGit': 'Otwórz panel Git',
|
||||
'chat.workStatus.action.openPr': 'Otwórz pull request',
|
||||
'chat.workStatus.action.openMr': 'Otwórz żądanie scalenia',
|
||||
'chat.workStatus.action.openSubagent': 'Otwórz {name}',
|
||||
'chat.workStatus.section.usage': 'Zużycie',
|
||||
'chat.workStatus.goal.open': 'Zarządzaj celem',
|
||||
|
||||
@@ -771,6 +771,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"gitView.header.repositoryViews": "Visualizações do repositório",
|
||||
"gitView.header.updateBranch": "Atualizar branch",
|
||||
"gitView.header.openPullRequest": "Abrir pull request",
|
||||
"gitView.header.openMergeRequest": "Abrir solicitação de merge",
|
||||
"gitView.header.removeRemoteAria": "Excluir remoto",
|
||||
"gitView.header.removeRemoteTitle": "Excluir remoto",
|
||||
"gitView.header.upstreamSynced": "sincronizado",
|
||||
@@ -1161,6 +1162,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"walkthrough.missing.languageAndModel": "Ainda não há um percurso neste idioma com este modelo — exibindo o último gerado aqui.",
|
||||
"walkthrough.language.selectorAria": "Escolher o idioma do percurso",
|
||||
"walkthrough.scope.pullRequest": "PR nº {number}",
|
||||
"walkthrough.scope.mergeRequest": "MR !{number}",
|
||||
"walkthrough.action.generate": "Gerar percurso",
|
||||
"walkthrough.action.regenerate": "Gerar novamente",
|
||||
"walkthrough.action.cancel": "Cancelar",
|
||||
@@ -3112,6 +3114,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': '{count} arquivo alterado',
|
||||
'chat.workStatus.git.changedFilePlural': '{count} arquivos alterados',
|
||||
'chat.workStatus.pr.untitled': 'Pull request sem título',
|
||||
'chat.workStatus.mr.untitled': 'Solicitação de merge sem título',
|
||||
'chat.workStatus.pr.draft': 'Rascunho',
|
||||
'chat.workStatus.pr.checks': 'Verificações',
|
||||
'chat.workStatus.pr.checksFailed': '{count} falharam',
|
||||
@@ -3143,6 +3146,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': 'Abrir alterações',
|
||||
'chat.workStatus.action.openGit': 'Abrir painel do Git',
|
||||
'chat.workStatus.action.openPr': 'Abrir pull request',
|
||||
'chat.workStatus.action.openMr': 'Abrir solicitação de merge',
|
||||
'chat.workStatus.action.openSubagent': 'Abrir {name}',
|
||||
'chat.workStatus.section.usage': 'Uso',
|
||||
'chat.workStatus.goal.open': 'Gerenciar objetivo',
|
||||
|
||||
@@ -771,6 +771,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"gitView.header.repositoryViews": "Перегляди репозиторію",
|
||||
"gitView.header.updateBranch": "Оновити гілку",
|
||||
"gitView.header.openPullRequest": "Відкрити pull request",
|
||||
"gitView.header.openMergeRequest": "Відкрити запит на злиття",
|
||||
"gitView.header.removeRemoteAria": "Видалити remote",
|
||||
"gitView.header.removeRemoteTitle": "Видалити remote",
|
||||
"gitView.header.upstreamSynced": "синхронізовано",
|
||||
@@ -1161,6 +1162,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"walkthrough.missing.languageAndModel": "Розбору цією мовою від цієї моделі ще немає — показано останній згенерований тут.",
|
||||
"walkthrough.language.selectorAria": "Обрати мову розбору",
|
||||
"walkthrough.scope.pullRequest": "PR #{number}",
|
||||
"walkthrough.scope.mergeRequest": "MR !{number}",
|
||||
"walkthrough.action.generate": "Створити розбір",
|
||||
"walkthrough.action.regenerate": "Створити заново",
|
||||
"walkthrough.action.cancel": "Скасувати",
|
||||
@@ -3112,6 +3114,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': 'Змінено {count} файл',
|
||||
'chat.workStatus.git.changedFilePlural': 'Змінено {count} файлів',
|
||||
'chat.workStatus.pr.untitled': 'Pull request без назви',
|
||||
'chat.workStatus.mr.untitled': 'Запит на злиття без назви',
|
||||
'chat.workStatus.pr.draft': 'Чернетка',
|
||||
'chat.workStatus.pr.checks': 'Перевірки',
|
||||
'chat.workStatus.pr.checksFailed': '{count} впало',
|
||||
@@ -3143,6 +3146,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': 'Відкрити зміни',
|
||||
'chat.workStatus.action.openGit': 'Відкрити панель Git',
|
||||
'chat.workStatus.action.openPr': 'Відкрити pull request',
|
||||
'chat.workStatus.action.openMr': 'Відкрити запит на злиття',
|
||||
'chat.workStatus.action.openSubagent': 'Відкрити {name}',
|
||||
'chat.workStatus.section.usage': 'Використання',
|
||||
'chat.workStatus.goal.open': 'Керувати ціллю',
|
||||
|
||||
@@ -771,6 +771,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.header.repositoryViews': '仓库视图',
|
||||
'gitView.header.updateBranch': '更新分支',
|
||||
'gitView.header.openPullRequest': '打开拉取请求',
|
||||
'gitView.header.openMergeRequest': '打开合并请求',
|
||||
'gitView.header.removeRemoteAria': '移除远程 {name}',
|
||||
'gitView.header.removeRemoteTitle': '移除 {name}',
|
||||
'gitView.header.upstreamSynced': '已同步',
|
||||
@@ -1161,6 +1162,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'walkthrough.missing.languageAndModel': '尚无使用该语言和该模型生成的导读,当前显示最近一次生成的版本。',
|
||||
'walkthrough.language.selectorAria': '选择导读语言',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': '生成导读',
|
||||
'walkthrough.action.regenerate': '重新生成',
|
||||
'walkthrough.action.cancel': '取消',
|
||||
@@ -3112,6 +3114,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': '已更改 {count} 个文件',
|
||||
'chat.workStatus.git.changedFilePlural': '已更改 {count} 个文件',
|
||||
'chat.workStatus.pr.untitled': '未命名的拉取请求',
|
||||
'chat.workStatus.mr.untitled': '未命名的合并请求',
|
||||
'chat.workStatus.pr.draft': '草稿',
|
||||
'chat.workStatus.pr.checks': '检查',
|
||||
'chat.workStatus.pr.checksFailed': '{count} 项失败',
|
||||
@@ -3143,6 +3146,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': '打开更改',
|
||||
'chat.workStatus.action.openGit': '打开 Git 面板',
|
||||
'chat.workStatus.action.openPr': '打开拉取请求',
|
||||
'chat.workStatus.action.openMr': '打开合并请求',
|
||||
'chat.workStatus.action.openSubagent': '打开 {name}',
|
||||
'chat.workStatus.section.usage': '用量',
|
||||
'chat.workStatus.goal.open': '管理目标',
|
||||
|
||||
@@ -784,6 +784,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.header.repositoryViews': '儲存庫檢視',
|
||||
'gitView.header.updateBranch': '更新分支',
|
||||
'gitView.header.openPullRequest': '開啟提取請求',
|
||||
'gitView.header.openMergeRequest': '開啟合併請求',
|
||||
'gitView.header.removeRemoteAria': '移除遠端 {name}',
|
||||
'gitView.header.removeRemoteTitle': '移除 {name}',
|
||||
'gitView.header.upstreamSynced': '已同步',
|
||||
@@ -1173,6 +1174,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'walkthrough.missing.languageAndModel': '尚無使用該語言與該模型產生的導讀,目前顯示最近一次產生的版本。',
|
||||
'walkthrough.language.selectorAria': '選擇導讀語言',
|
||||
'walkthrough.scope.pullRequest': 'PR #{number}',
|
||||
'walkthrough.scope.mergeRequest': 'MR !{number}',
|
||||
'walkthrough.action.generate': '產生導讀',
|
||||
'walkthrough.action.regenerate': '重新產生',
|
||||
'walkthrough.action.cancel': '取消',
|
||||
@@ -3111,6 +3113,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.git.changedFileSingle': '已變更 {count} 個檔案',
|
||||
'chat.workStatus.git.changedFilePlural': '已變更 {count} 個檔案',
|
||||
'chat.workStatus.pr.untitled': '未命名的提取請求',
|
||||
'chat.workStatus.mr.untitled': '未命名的合併請求',
|
||||
'chat.workStatus.pr.draft': '草稿',
|
||||
'chat.workStatus.pr.checks': '檢查',
|
||||
'chat.workStatus.pr.checksFailed': '{count} 項失敗',
|
||||
@@ -3142,6 +3145,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.action.openChanges': '開啟變更',
|
||||
'chat.workStatus.action.openGit': '開啟 Git 面板',
|
||||
'chat.workStatus.action.openPr': '開啟提取請求',
|
||||
'chat.workStatus.action.openMr': '開啟合併請求',
|
||||
'chat.workStatus.action.openSubagent': '開啟 {name}',
|
||||
'chat.workStatus.section.usage': '用量',
|
||||
'chat.workStatus.goal.open': '管理目標',
|
||||
|
||||
Reference in New Issue
Block a user