Add initial project structure with essential files

- Created .gitignore to exclude build artifacts and dependencies.
- Added index.html as the main entry point for the application.
- Included LICENSE file with Apache 2.0 terms.
- Initialized package.json and package-lock.json for project dependencies.
- Added pnpm-lock.yaml for package management.
- Created QUICKSTART.md for setup instructions.
- Added README.md and README.zh-CN.md for project documentation in English and Chinese.
This commit is contained in:
pftom
2026-04-28 12:25:59 +08:00
commit a98096a042
258 changed files with 67862 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useState,
type ReactNode,
} from 'react';
import { en } from './locales/en';
import { zhCN } from './locales/zh-CN';
import { LOCALES, type Dict, type Locale } from './types';
export { LOCALES, LOCALE_LABEL } from './types';
export type { Locale } from './types';
type DictKey = keyof Dict;
const DICTS: Record<Locale, Dict> = {
'en': en,
'zh-CN': zhCN,
};
const LS_KEY = 'open-claude-design:locale';
// First-run default is English. We honor an explicit user pick saved to
// localStorage but never auto-detect from `navigator.language`, so the
// initial experience is consistent and predictable.
function detectInitialLocale(): Locale {
if (typeof window === 'undefined') return 'en';
try {
const stored = window.localStorage.getItem(LS_KEY);
if (stored && (LOCALES as string[]).includes(stored)) {
return stored as Locale;
}
} catch {
/* ignore */
}
return 'en';
}
interface I18nContextValue {
locale: Locale;
setLocale: (next: Locale) => void;
t: (key: DictKey, vars?: Record<string, string | number>) => string;
}
const I18nContext = createContext<I18nContextValue | null>(null);
interface ProviderProps {
initial?: Locale;
children: ReactNode;
}
export function I18nProvider({ initial, children }: ProviderProps) {
const [locale, setLocaleState] = useState<Locale>(() => initial ?? detectInitialLocale());
// Keep <html lang="…"> in sync so screen readers and CSS hooks pick the
// right language token without each component having to set lang itself.
useEffect(() => {
if (typeof document !== 'undefined') {
document.documentElement.setAttribute('lang', locale);
}
}, [locale]);
const setLocale = useCallback((next: Locale) => {
setLocaleState(next);
try {
window.localStorage.setItem(LS_KEY, next);
} catch {
/* ignore */
}
}, []);
const t = useCallback(
(key: DictKey, vars?: Record<string, string | number>): string => {
const dict = DICTS[locale] ?? en;
const raw = dict[key] ?? en[key] ?? key;
if (!vars) return raw;
return raw.replace(/\{(\w+)\}/g, (_, name: string) => {
const v = vars[name];
return v == null ? `{${name}}` : String(v);
});
},
[locale],
);
const value = useMemo<I18nContextValue>(
() => ({ locale, setLocale, t }),
[locale, setLocale, t],
);
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;
}
export function useI18n(): I18nContextValue {
const ctx = useContext(I18nContext);
if (!ctx) {
// Fall back to a stand-alone English translator when no provider is
// mounted (e.g. an isolated test). This keeps the API safe to call
// without requiring every callsite to wrap in a provider.
return {
locale: 'en',
setLocale: () => {},
t: (key, vars) => {
const raw = en[key] ?? key;
if (!vars) return raw;
return raw.replace(/\{(\w+)\}/g, (_, n: string) => {
const v = vars[n];
return v == null ? `{${n}}` : String(v);
});
},
};
}
return ctx;
}
// Convenience for components that only need the translator function.
export function useT(): I18nContextValue['t'] {
return useI18n().t;
}
+494
View File
@@ -0,0 +1,494 @@
import type { Dict } from '../types';
export const en: Dict = {
'common.cancel': 'Cancel',
'common.save': 'Save',
'common.close': 'Close',
'common.delete': 'Delete',
'common.rename': 'Rename',
'common.preview': 'Preview',
'common.share': 'Share',
'common.search': 'Search',
'common.searchEllipsis': 'Search…',
'common.loading': 'Loading…',
'common.all': 'All',
'common.none': 'None',
'common.default': 'Default',
'common.installed': 'installed',
'common.notInstalled': 'not installed',
'common.active': 'active',
'common.offline': 'offline',
'common.selected': 'selected',
'common.create': 'Create',
'common.openPreview': 'Open preview',
'common.exitFullscreen': 'Exit fullscreen',
'common.fullscreen': 'Fullscreen',
'common.openInNewTab': 'Open in new tab',
'common.exportPdf': 'Export as PDF',
'common.exportZip': 'Download as .zip',
'common.exportHtml': 'Export as standalone HTML',
'common.justNow': 'just now',
'common.minutesAgo': '{n}m ago',
'common.hoursAgo': '{n}h ago',
'common.daysAgo': '{n}d ago',
'common.now': 'now',
'common.minutesShort': '{n}m',
'common.hoursShort': '{n}h',
'common.daysShort': '{n}d',
'common.untitled': 'Untitled',
'app.brand': 'Open Claude Design',
'app.brandPill': 'Research Preview',
'app.brandSubtitle': 'by Nexu Labs',
'app.welcomeLoading': 'Loading workspace…',
'settings.welcomeKicker': 'Welcome',
'settings.welcomeTitle': 'Set up Open Claude Design',
'settings.welcomeSubtitle':
"Pick how you'd like to run generations. You can change this any time from the Settings button in the top bar.",
'settings.kicker': 'Settings',
'settings.title': 'Execution & model',
'settings.subtitle':
'Choose between a local code-agent CLI and the Anthropic API (BYOK). Your API key is stored only in this browser.',
'settings.modeAria': 'Execution mode',
'settings.modeDaemon': 'Local CLI',
'settings.modeDaemonHelp': 'Run via a code-agent CLI on your machine',
'settings.modeDaemonOffline': 'Daemon is not running',
'settings.modeDaemonOfflineMeta': 'daemon offline',
'settings.modeDaemonInstalledMeta': '{count} installed',
'settings.modeApi': 'Anthropic API',
'settings.modeApiMeta': 'BYOK',
'settings.codeAgent': 'Code agent',
'settings.codeAgentHint':
'Detected by scanning your PATH. Pick the CLI you want generations to flow through.',
'settings.rescan': '↻ Rescan',
'settings.rescanTitle': 'Re-scan PATH',
'settings.noAgentsDetected':
'No agents detected yet. Install one of Claude Code, Codex, Gemini CLI, OpenCode, Cursor Agent, or Qwen, then click Rescan.',
'settings.apiSection': 'Anthropic API',
'settings.apiKey': 'API key',
'settings.showKey': 'Show key',
'settings.hideKey': 'Hide key',
'settings.show': 'Show',
'settings.hide': 'Hide',
'settings.model': 'Model',
'settings.baseUrl': 'Base URL',
'settings.apiHint':
'Calls go directly from this browser to the base URL you set. No proxy. The key never leaves localStorage.',
'settings.skipForNow': 'Skip for now',
'settings.getStarted': 'Get started',
'settings.envConfigure': 'Configure execution mode',
'settings.localCli': 'Local CLI',
'settings.anthropicApi': 'Anthropic API',
'settings.noAgentSelected': 'no agent selected',
'settings.language': 'Language',
'settings.languageHint': 'Switch the interface language. Saved to this browser.',
'entry.tabDesigns': 'Designs',
'entry.tabExamples': 'Examples',
'entry.tabDesignSystems': 'Design systems',
'entry.openSettingsTitle': 'Settings',
'entry.openSettingsAria': 'Open settings',
'entry.resizeAria': 'Resize sidebar',
'entry.loadingWorkspace': 'Loading workspace…',
'newproj.tabPrototype': 'Prototype',
'newproj.tabDeck': 'Slide deck',
'newproj.tabTemplate': 'From template',
'newproj.tabOther': 'Other',
'newproj.titlePrototype': 'New prototype',
'newproj.titleDeck': 'New slide deck',
'newproj.titleTemplate': 'Start from a template',
'newproj.titleOther': 'New project',
'newproj.namePlaceholder': 'Project name',
'newproj.fidelityLabel': 'Fidelity',
'newproj.fidelityWireframe': 'Wireframe',
'newproj.fidelityHigh': 'High fidelity',
'newproj.toggleSpeakerNotes': 'Use speaker notes',
'newproj.toggleSpeakerNotesHint': 'Less text on slides — keep talking points in notes.',
'newproj.toggleAnimations': 'Include animations',
'newproj.toggleAnimationsHint':
'Add motion (entrance, hover, transitions) on top of the template.',
'newproj.templateLabel': 'Template',
'newproj.noTemplatesTitle': 'No templates yet',
'newproj.noTemplatesBody':
'Open any project, then use the Share menu inside the file viewer to convert it into a template. Templates show up here.',
'newproj.savedTemplate': 'Saved template',
'newproj.fileSingular': 'file',
'newproj.filePlural': 'files',
'newproj.create': 'Create',
'newproj.createFromTemplate': 'Create from template',
'newproj.createDisabledTitle':
'Save a project as a template first (Share menu inside any project).',
'newproj.privacyFooter': 'Only you can see your project by default.',
'newproj.designSystem': 'Design system',
'newproj.dsNoneFreeform': 'None — freeform',
'newproj.dsNoneSubtitleEmpty': 'No system tokens, choose your own palette',
'newproj.dsNoneSubtitleSelected': 'Skip system tokens. The agent picks its own palette.',
'newproj.dsCategoryFallback': 'Design system',
'newproj.dsSearch': 'Search design systems…',
'newproj.dsModeAria': 'Selection mode',
'newproj.dsModeSingle': 'Single',
'newproj.dsModeMulti': 'Multi',
'newproj.dsNoneTitle': 'None — freeform',
'newproj.dsNoneSub': 'Skip system tokens. The agent picks its own palette.',
'newproj.dsEmpty': 'No design systems match “{query}”.',
'newproj.dsFootSingular': 'is inspiration only.',
'newproj.dsFootPlural': 'are inspiration only.',
'newproj.dsFootClear': 'Clear',
'newproj.dsBadgeDefault': 'DEFAULT',
'newproj.dsPrimaryFallback': 'Primary',
'designs.subRecent': 'Recent',
'designs.subYours': 'Your designs',
'designs.filterAria': 'Filter projects',
'designs.searchPlaceholder': 'Search…',
'designs.emptyNoProjects': 'No projects yet. Create one on the left.',
'designs.emptyNoMatch': 'No projects match your search.',
'designs.deleteTitle': 'Delete project',
'designs.deleteConfirm': 'Delete "{name}"?',
'designs.cardFreeform': 'freeform',
'examples.typeLabel': 'Type',
'examples.scenarioLabel': 'Scenario',
'examples.modeAll': 'All',
'examples.modePrototypeDesktop': 'Prototypes · Desktop',
'examples.modePrototypeMobile': 'Prototypes · Mobile',
'examples.modeDeck': 'Slides',
'examples.modeDocument': 'Docs & templates',
'examples.scenarioGeneral': 'General',
'examples.scenarioEngineering': 'Engineering',
'examples.scenarioProduct': 'Product',
'examples.scenarioDesign': 'Design',
'examples.scenarioMarketing': 'Marketing',
'examples.scenarioSales': 'Sales',
'examples.scenarioFinance': 'Finance',
'examples.scenarioHr': 'HR',
'examples.scenarioOperations': 'Operations',
'examples.scenarioSupport': 'Support',
'examples.scenarioLegal': 'Legal',
'examples.scenarioEducation': 'Education',
'examples.scenarioPersonal': 'Personal',
'examples.emptyNoSkills': 'No skills available. Is the daemon running?',
'examples.emptyNoMatch': 'No examples match these filters.',
'examples.openPreview': '⤢ Open preview',
'examples.loadingPreview': 'Loading preview…',
'examples.hoverPreview': 'Hover to preview',
'examples.usePrompt': 'Use this prompt',
'examples.previewModalTitle': 'Open full preview (modal)',
'examples.shareTitle': 'Share this example',
'examples.shareLoadFirst': 'Hover to load preview first',
'examples.shareMenu': 'Share ▾',
'examples.exportPdfAllSlides': 'Export as PDF (all slides)',
'examples.exportPptxLocked': 'Export as PPTX… (open template first)',
'examples.tagSlideDeck': 'Slide deck',
'examples.tagTemplate': 'Template',
'examples.tagDesignSystem': 'Design system',
'examples.tagMobilePrototype': 'Mobile prototype',
'examples.tagDesktopPrototype': 'Desktop prototype',
'examples.previewLabel': 'Preview',
'ds.searchPlaceholder': 'Search design systems…',
'ds.emptyNoMatch': 'No design systems match your search.',
'ds.badgeDefault': 'DEFAULT',
'ds.preview': 'Preview',
'ds.previewTitle': 'Preview design system',
'ds.categoryAll': 'All',
'ds.categoryUncategorized': 'Uncategorized',
'ds.showcase': 'Showcase',
'ds.tokens': 'Tokens',
'avatar.title': 'Account & settings',
'avatar.localCli': 'Local CLI',
'avatar.anthropicApi': 'Anthropic API',
'avatar.useLocal': 'Use Local CLI',
'avatar.useApi': 'Use Anthropic API',
'avatar.codeAgent': 'Code agent',
'avatar.rescan': 'Rescan PATH',
'avatar.settings': 'Settings',
'avatar.backToProjects': 'Back to projects',
'avatar.metaActive': 'active',
'avatar.metaOffline': 'offline',
'avatar.metaSelected': 'selected',
'avatar.noAgentSelected': 'no agent selected',
'project.backToProjects': 'Back to projects',
'project.metaFreeform': 'freeform',
'chat.tabChat': 'Chat',
'chat.tabComments': 'Comments',
'chat.commentsSoon': 'Comments — coming soon',
'chat.conversationsTitle': 'Conversations',
'chat.conversationsAria': 'Conversation history',
'chat.newConversation': 'New conversation',
'chat.newConversationsTitle': 'New conversation',
'chat.conversationsHeading': 'Conversations',
'chat.new': 'New',
'chat.emptyConversations': 'No conversations yet.',
'chat.deleteConversation': 'Delete conversation',
'chat.deleteConversationConfirm':
'Delete "{title}"? This removes its messages.',
'chat.untitledConversation': 'Untitled conversation',
'chat.startTitle': 'Start a conversation',
'chat.startHint':
'Drop or paste images for visual reference, or type @ to attach a file from this project. Or try one of these starters:',
'chat.fillInputTitle': 'Click to fill the input',
'chat.jumpToLatest': 'Jump to latest',
'chat.scrollToLatest': 'Scroll to latest',
'chat.you': 'You',
'chat.openFile': 'Open {name}',
'chat.composerPlaceholder':
'Describe the design you want — paste or drop images, or @ a file…',
'chat.composerHint':
'⌘/Ctrl + Enter to send · paste images · @ to reference files',
'chat.cliSettingsTitle': 'CLI & model settings',
'chat.cliSettingsAria': 'Open CLI and model settings',
'chat.attachTitle': 'Attach files (or paste / drop)',
'chat.attachAria': 'Attach files',
'chat.importTitle': 'Import sources (coming soon)',
'chat.importLabel': 'Import',
'chat.importComingSoon': 'Coming soon',
'chat.importSoon': 'Soon',
'chat.importFig': 'Upload .fig file',
'chat.importGitHub': 'Connect GitHub',
'chat.importWeb': 'Grab web element',
'chat.importFolder': 'Link code folder',
'chat.importSkills': 'Skills and design systems',
'chat.importProject': 'Reference another project',
'chat.send': 'Send',
'chat.stop': 'Stop',
'chat.removeAria': 'Remove {name}',
'chat.example1Title': 'Editorial pitch deck',
'chat.example1Tag': 'Magazine',
'chat.example1Prompt':
'A 10-slide editorial pitch deck for a design studio raising a seed round — Swiss-grid layout, oversized serif headlines with bold drop caps, monospace section numbers, generous negative space, and full-bleed photo slides interleaved with text-heavy ones. Cover, vision, market, product, traction, team, ask, contact.',
'chat.example2Title': 'SaaS analytics dashboard',
'chat.example2Tag': 'Data',
'chat.example2Prompt':
'A dense analytics dashboard for a developer-tools SaaS — KPI strip with week-over-week deltas, two stacked line charts (MRR and active workspaces), a world heatmap of usage, a cohort retention grid, a top-customers leaderboard, and a real-time event feed. Dark theme, tabular monospace numerals, sparkline accents.',
'chat.example3Title': 'Annual report long-scroll',
'chat.example3Tag': 'Editorial',
'chat.example3Prompt':
'An interactive annual report for a climate non-profit — long-scroll editorial layout mixing big pull-quote blocks, data visualizations (stacked bars, animated counters, a choropleth map of project sites), photography breakers, donor wall, and a final call-to-action. Modern serif body, sans-serif chart labels, earthy paper palette.',
'preview.shareMenu': 'Share ▾',
'preview.openInNewTab': 'Open in new tab',
'preview.exit': '⤓ Exit',
'preview.fullscreen': '⤢ Fullscreen',
'preview.closeTitle': 'Close (Esc)',
'preview.loading': 'Loading {label}…',
'misc.savedTemplate': 'Saved template',
'misc.primary': 'Primary',
'misc.designSystem': 'Design system',
'workspace.designFiles': 'Design Files',
'workspace.closeTab': 'Close tab',
'workspace.deleteFileConfirm': 'Delete "{name}" from the project folder?',
'workspace.openFromDesignFiles': 'Open a file from',
'workspace.designFilesLink': 'Design Files',
'workspace.loadingSketch': 'Loading sketch…',
'designFiles.title': 'Design Files',
'designFiles.upload': 'Upload image',
'designFiles.pasteText': 'Paste as text file',
'designFiles.newSketch': 'New sketch',
'designFiles.empty':
'Nothing here yet. Drop files below, or create a sketch / paste text.',
'designFiles.refresh': 'Refresh',
'designFiles.delete': 'Delete',
'designFiles.searchPlaceholder': 'Search files…',
'designFiles.up': 'Up',
'designFiles.back': 'Back',
'designFiles.crumbs': 'project',
'designFiles.rowMenu': 'Row menu',
'designFiles.openInTab': 'Open in tab',
'designFiles.download': 'Download',
'designFiles.dropTitle': '⤓ Drop files here',
'designFiles.dropDesc':
'Images, docs, references, Figma links, or folders — Claude will use them as context.',
'designFiles.upload.title': 'Upload an image',
'designFiles.paste.title': 'Paste text as a file',
'designFiles.upload.label': 'Upload',
'designFiles.paste.label': 'Paste',
'designFiles.previewOpen': 'Open',
'designFiles.previewClose': 'Close preview',
'designFiles.modified': 'Modified {time} · {size}',
'designFiles.weeksAgo': '{n}w ago',
'designFiles.sectionPages': 'Pages',
'designFiles.sectionScripts': 'Scripts',
'designFiles.sectionImages': 'Images',
'designFiles.sectionSketches': 'Sketches',
'designFiles.sectionOther': 'Other',
'designFiles.kindHtml': 'HTML page',
'designFiles.kindImage': 'Image',
'designFiles.kindSketch': 'Sketch',
'designFiles.kindText': 'Text',
'designFiles.kindCode': 'Script',
'designFiles.kindBinary': 'Binary',
'pasteDialog.title': 'Paste text',
'pasteDialog.hint': 'Saved into the project folder. Pick any name.',
'pasteDialog.fileNameLabel': 'File name',
'pasteDialog.namePlaceholder': 'notes.txt',
'pasteDialog.contentLabel': 'Content',
'pasteDialog.contentPlaceholder': 'Paste anything…',
'pasteDialog.save': 'Save',
'pasteDialog.cancel': 'Cancel',
'sketch.save': 'Save sketch',
'sketch.cancel': 'Cancel',
'sketch.saving': 'Saving…',
'sketch.tooltipDirty': 'Unsaved changes',
'sketch.tooltipClean': 'Saved',
'fileViewer.empty': 'Select a file to view.',
'fileViewer.loading': 'Loading…',
'fileViewer.exportPptx': 'Export as PPTX',
'fileViewer.openInNewTab': 'Open in new tab',
'fileViewer.copyPath': 'Copy path',
'fileViewer.copied': 'Copied!',
'fileViewer.share': 'Share',
'fileViewer.binaryMeta': 'Binary · {size}',
'fileViewer.binaryNote':
'Binary file ({size} bytes). Download or open from disk to inspect.',
'fileViewer.download': 'Download',
'fileViewer.open': 'Open',
'fileViewer.imageMeta': 'Image · {size}',
'fileViewer.sketchMeta': 'Sketch · {size}',
'fileViewer.reload': 'Reload',
'fileViewer.reloadDisk': 'Reload from disk',
'fileViewer.copy': 'Copy',
'fileViewer.copyTitle': 'Copy file contents',
'fileViewer.saveDisabled': 'Save (read-only viewer)',
'fileViewer.save': 'Save',
'fileViewer.preview': 'Preview',
'fileViewer.source': 'Source',
'fileViewer.tweaks': 'Tweaks',
'fileViewer.comment': 'Comment',
'fileViewer.edit': 'Edit',
'fileViewer.draw': 'Draw',
'fileViewer.zoomOut': 'Zoom out',
'fileViewer.zoomIn': 'Zoom in',
'fileViewer.resetZoom': 'Reset zoom',
'fileViewer.reloadAria': 'Reload',
'fileViewer.previousSlide': 'Previous slide',
'fileViewer.nextSlide': 'Next slide',
'fileViewer.slideNavAria': 'Slide navigation',
'fileViewer.present': 'Present',
'fileViewer.presentInTab': 'In this tab',
'fileViewer.presentFullscreen': 'Fullscreen',
'fileViewer.presentNewTab': 'New tab',
'fileViewer.exitPresentation': 'Exit presentation',
'fileViewer.shareLabel': 'Share',
'fileViewer.exportPdf': 'Export as PDF',
'fileViewer.exportPdfAllSlides': 'Export as PDF (all slides)',
'fileViewer.exportPptxBusy': 'Wait for the current turn to finish.',
'fileViewer.exportPptxHint':
'Send a request to the agent to convert this design to PPTX.',
'fileViewer.exportPptxNa': 'PPTX export is not available here.',
'fileViewer.exportZip': 'Download as .zip',
'fileViewer.exportHtml': 'Export as standalone HTML',
'fileViewer.saveAsTemplate': 'Save as template…',
'fileViewer.savingTemplate': 'Saving template…',
'fileViewer.savedTemplate': 'Saved as "{name}"',
'fileViewer.savedTemplateFail': 'Could not save template — try again.',
'fileViewer.templateNamePrompt': 'Template name',
'fileViewer.templateNameDefault': 'Untitled template',
'fileViewer.templateDescPrompt':
'Short description (optional — what makes this template useful?)',
'questionForm.submit': 'Submit',
'questionForm.skip': 'Skip',
'questionForm.locked': 'Answered',
'conv.switch': 'Switch conversation',
'conv.label': 'Conversation',
'conv.heading': 'Conversations',
'conv.new': '+ New',
'conv.empty': 'No conversations yet.',
'conv.untitled': 'Untitled conversation',
'conv.renameTooltip': 'Double-click to rename',
'conv.delete': 'Delete conversation',
'conv.deleteConfirm': 'Delete "{title}"? This removes its messages.',
'agentPicker.label': 'Agent',
'agentPicker.modeChoose': 'Choose execution mode',
'agentPicker.localCli': 'Local CLI',
'agentPicker.daemonOff': 'daemon off',
'agentPicker.byok': 'Anthropic API · BYOK',
'agentPicker.selectAgent': 'Select a detected code-agent CLI',
'agentPicker.noAgents': 'no agents on PATH',
'agentPicker.notInstalled': 'not installed',
'agentPicker.rescan': 'Re-scan local PATH for agents',
'tool.openInTab': 'Open {name} in a tab',
'tool.open': 'open',
'tool.todos': 'Todos',
'tool.write': 'Write',
'tool.edit': 'Edit',
'tool.read': 'Read',
'tool.bash': 'Bash',
'tool.glob': 'Glob',
'tool.grep': 'Grep',
'tool.fetch': 'Fetch',
'tool.search': 'Search',
'tool.lines': '{n} lines',
'tool.changeSingular': 'change',
'tool.changePlural': 'changes',
'tool.in': 'in {path}',
'tool.hide': 'hide',
'tool.output': 'output',
'tool.running': 'running…',
'tool.error': 'error',
'tool.done': 'done',
'assistant.role': 'Claude',
'assistant.workingLabel': 'Working',
'assistant.doneLabel': 'Done',
'assistant.outTokens': '{n} out',
'assistant.producedFiles': 'Files from this turn',
'assistant.openFile': 'Open',
'assistant.downloadFile': 'Download',
'assistant.thinking': 'Thinking',
'assistant.systemReminder': 'System reminder',
'assistant.waitingFirstOutput': 'Waiting for first output',
'assistant.statusBootingAgent': 'Booting agent',
'assistant.statusStarting': 'Starting',
'assistant.statusRequesting': 'Sending request',
'assistant.statusThinking': 'Thinking',
'assistant.statusStreaming': 'Streaming',
'assistant.slowHint':
'Taking longer than usual. The form usually shows in 510s — you can Stop and rephrase.',
'assistant.verbEditing': 'Editing',
'assistant.verbWriting': 'Writing',
'assistant.verbReading': 'Reading',
'assistant.verbSearching': 'Searching',
'assistant.verbRunning': 'Running',
'assistant.verbTodos': 'Todos',
'assistant.verbFetching': 'Fetching',
'assistant.verbCalling': 'Calling',
'qf.answered': 'answered',
'qf.choose': 'Choose…',
'qf.required': 'required',
'qf.lockedSubmitted':
'Answers sent — agent is using these for the rest of the session.',
'qf.lockedPrev': 'This form is from a previous turn.',
'qf.hint':
"Pick what fits. Skip optional fields you don't care about — the agent will use sensible defaults.",
'qf.submitDefault': 'Send answers',
'qf.submitDisabledTitle': 'Fill in the required fields first',
'qf.submitTitle': 'Send answers',
'qf.cardSelected': 'selected',
'qf.cardRefs': 'Refs:',
'qf.cardSampleText': 'The quick brown fox · 0123',
'sketch.toolSelect': 'Select (no-op)',
'sketch.toolPen': 'Pen',
'sketch.toolText': 'Text',
'sketch.toolRect': 'Rectangle',
'sketch.toolArrow': 'Arrow',
'sketch.toolEraser': 'Eraser',
'sketch.color': 'Color',
'sketch.strokeSize': 'Stroke size',
'sketch.undo': 'Undo',
'sketch.clear': 'Clear',
'sketch.close': 'Close',
'sketch.textPrompt': 'Text:',
};
+481
View File
@@ -0,0 +1,481 @@
import type { Dict } from '../types';
export const zhCN: Dict = {
'common.cancel': '取消',
'common.save': '保存',
'common.close': '关闭',
'common.delete': '删除',
'common.rename': '重命名',
'common.preview': '预览',
'common.share': '分享',
'common.search': '搜索',
'common.searchEllipsis': '搜索…',
'common.loading': '加载中…',
'common.all': '全部',
'common.none': '无',
'common.default': '默认',
'common.installed': '已安装',
'common.notInstalled': '未安装',
'common.active': '使用中',
'common.offline': '未运行',
'common.selected': '已选',
'common.create': '创建',
'common.openPreview': '打开预览',
'common.exitFullscreen': '退出全屏',
'common.fullscreen': '全屏',
'common.openInNewTab': '在新标签页中打开',
'common.exportPdf': '导出为 PDF',
'common.exportZip': '下载为 .zip',
'common.exportHtml': '导出为独立 HTML',
'common.justNow': '刚刚',
'common.minutesAgo': '{n} 分钟前',
'common.hoursAgo': '{n} 小时前',
'common.daysAgo': '{n} 天前',
'common.now': '刚刚',
'common.minutesShort': '{n}分',
'common.hoursShort': '{n}时',
'common.daysShort': '{n}天',
'common.untitled': '未命名',
'app.brand': 'Open Claude Design',
'app.brandPill': '研究预览版',
'app.brandSubtitle': '由 Nexu Labs 出品',
'app.welcomeLoading': '正在加载工作区…',
'settings.welcomeKicker': '欢迎',
'settings.welcomeTitle': '初始化 Open Claude Design',
'settings.welcomeSubtitle':
'选择你希望使用的执行方式。后续可以随时从顶部「设置」按钮中修改。',
'settings.kicker': '设置',
'settings.title': '执行模式与模型',
'settings.subtitle':
'在本机的代码代理 CLI 与 Anthropic API(自带 Key)之间切换。API Key 只保存在当前浏览器中。',
'settings.modeAria': '执行模式',
'settings.modeDaemon': '本机 CLI',
'settings.modeDaemonHelp': '通过本机的代码代理 CLI 执行',
'settings.modeDaemonOffline': '后台守护进程未运行',
'settings.modeDaemonOfflineMeta': '守护进程未运行',
'settings.modeDaemonInstalledMeta': '已安装 {count} 个',
'settings.modeApi': 'Anthropic API',
'settings.modeApiMeta': '自带 Key',
'settings.codeAgent': '代码代理',
'settings.codeAgentHint': '通过扫描 PATH 自动检测,选择你希望使用的 CLI。',
'settings.rescan': '↻ 重新扫描',
'settings.rescanTitle': '重新扫描 PATH',
'settings.noAgentsDetected':
'尚未检测到任何代理。请安装 Claude Code、Codex、Gemini CLI、OpenCode、Cursor Agent 或 Qwen 中的一个,然后点击「重新扫描」。',
'settings.apiSection': 'Anthropic API',
'settings.apiKey': 'API Key',
'settings.showKey': '显示 Key',
'settings.hideKey': '隐藏 Key',
'settings.show': '显示',
'settings.hide': '隐藏',
'settings.model': '模型',
'settings.baseUrl': 'Base URL',
'settings.apiHint':
'请求会从当前浏览器直连你设置的 Base URL,无中转代理。Key 只存放在 localStorage。',
'settings.skipForNow': '暂时跳过',
'settings.getStarted': '开始使用',
'settings.envConfigure': '配置执行模式',
'settings.localCli': '本机 CLI',
'settings.anthropicApi': 'Anthropic API',
'settings.noAgentSelected': '尚未选择代理',
'settings.language': '界面语言',
'settings.languageHint': '切换界面语言,设置仅保存在当前浏览器。',
'entry.tabDesigns': '我的设计',
'entry.tabExamples': '示例',
'entry.tabDesignSystems': '设计体系',
'entry.openSettingsTitle': '设置',
'entry.openSettingsAria': '打开设置',
'entry.resizeAria': '调整侧边栏宽度',
'entry.loadingWorkspace': '正在加载工作区…',
'newproj.tabPrototype': '原型',
'newproj.tabDeck': '幻灯片',
'newproj.tabTemplate': '从模板',
'newproj.tabOther': '其它',
'newproj.titlePrototype': '新建原型',
'newproj.titleDeck': '新建幻灯片',
'newproj.titleTemplate': '从模板开始',
'newproj.titleOther': '新建项目',
'newproj.namePlaceholder': '项目名称',
'newproj.fidelityLabel': '精度',
'newproj.fidelityWireframe': '线框图',
'newproj.fidelityHigh': '高保真',
'newproj.toggleSpeakerNotes': '使用演讲备注',
'newproj.toggleSpeakerNotesHint': '减少幻灯片上的文字,要点放到备注中。',
'newproj.toggleAnimations': '加入动效',
'newproj.toggleAnimationsHint': '在模板基础上叠加动效(入场、悬停、过渡)。',
'newproj.templateLabel': '模板',
'newproj.noTemplatesTitle': '还没有模板',
'newproj.noTemplatesBody':
'打开任意项目,在文件查看器内的「分享」菜单将其保存为模板,模板将出现在这里。',
'newproj.savedTemplate': '已保存的模板',
'newproj.fileSingular': '个文件',
'newproj.filePlural': '个文件',
'newproj.create': '创建',
'newproj.createFromTemplate': '基于模板创建',
'newproj.createDisabledTitle': '请先在任意项目内通过「分享」菜单将其保存为模板。',
'newproj.privacyFooter': '默认情况下只有你能看到自己的项目。',
'newproj.designSystem': '设计体系',
'newproj.dsNoneFreeform': '不指定 — 自由发挥',
'newproj.dsNoneSubtitleEmpty': '不使用体系 token,由你决定整体配色',
'newproj.dsNoneSubtitleSelected': '跳过体系 token,由代理自行选择配色。',
'newproj.dsCategoryFallback': '设计体系',
'newproj.dsSearch': '搜索设计体系…',
'newproj.dsModeAria': '选择模式',
'newproj.dsModeSingle': '单选',
'newproj.dsModeMulti': '多选',
'newproj.dsNoneTitle': '不指定 — 自由发挥',
'newproj.dsNoneSub': '跳过体系 token,由代理自行选择配色。',
'newproj.dsEmpty': '没有匹配「{query}」的设计体系。',
'newproj.dsFootSingular': '只作为灵感参考。',
'newproj.dsFootPlural': '只作为灵感参考。',
'newproj.dsFootClear': '清除',
'newproj.dsBadgeDefault': '默认',
'newproj.dsPrimaryFallback': '主体系',
'designs.subRecent': '最近',
'designs.subYours': '我的设计',
'designs.filterAria': '筛选项目',
'designs.searchPlaceholder': '搜索…',
'designs.emptyNoProjects': '还没有项目。请在左侧创建一个。',
'designs.emptyNoMatch': '没有匹配的项目。',
'designs.deleteTitle': '删除项目',
'designs.deleteConfirm': '确定删除「{name}」?',
'designs.cardFreeform': '自由设计',
'examples.typeLabel': '类型',
'examples.scenarioLabel': '场景',
'examples.modeAll': '全部',
'examples.modePrototypeDesktop': '原型 · 桌面端',
'examples.modePrototypeMobile': '原型 · 移动端',
'examples.modeDeck': '幻灯片',
'examples.modeDocument': '文档与模板',
'examples.scenarioGeneral': '通用',
'examples.scenarioEngineering': '工程',
'examples.scenarioProduct': '产品',
'examples.scenarioDesign': '设计',
'examples.scenarioMarketing': '市场',
'examples.scenarioSales': '销售',
'examples.scenarioFinance': '财务',
'examples.scenarioHr': '人力资源',
'examples.scenarioOperations': '运营',
'examples.scenarioSupport': '支持',
'examples.scenarioLegal': '法务',
'examples.scenarioEducation': '教育',
'examples.scenarioPersonal': '个人',
'examples.emptyNoSkills': '没有可用的技能,守护进程是否在运行?',
'examples.emptyNoMatch': '没有匹配当前筛选的示例。',
'examples.openPreview': '⤢ 打开预览',
'examples.loadingPreview': '正在加载预览…',
'examples.hoverPreview': '将鼠标悬停以查看预览',
'examples.usePrompt': '使用此 Prompt',
'examples.previewModalTitle': '在弹窗中查看完整预览',
'examples.shareTitle': '分享此示例',
'examples.shareLoadFirst': '请先悬停以加载预览',
'examples.shareMenu': '分享 ▾',
'examples.exportPdfAllSlides': '导出为 PDF(全部幻灯片)',
'examples.exportPptxLocked': '导出为 PPTX…(请先打开模板)',
'examples.tagSlideDeck': '幻灯片',
'examples.tagTemplate': '模板',
'examples.tagDesignSystem': '设计体系',
'examples.tagMobilePrototype': '移动端原型',
'examples.tagDesktopPrototype': '桌面端原型',
'examples.previewLabel': '预览',
'ds.searchPlaceholder': '搜索设计体系…',
'ds.emptyNoMatch': '没有匹配的设计体系。',
'ds.badgeDefault': '默认',
'ds.preview': '预览',
'ds.previewTitle': '预览设计体系',
'ds.categoryAll': '全部',
'ds.categoryUncategorized': '未分类',
'ds.showcase': '展示',
'ds.tokens': 'Token',
'avatar.title': '账户与设置',
'avatar.localCli': '本机 CLI',
'avatar.anthropicApi': 'Anthropic API',
'avatar.useLocal': '使用本机 CLI',
'avatar.useApi': '使用 Anthropic API',
'avatar.codeAgent': '代码代理',
'avatar.rescan': '重新扫描 PATH',
'avatar.settings': '设置',
'avatar.backToProjects': '返回项目列表',
'avatar.metaActive': '使用中',
'avatar.metaOffline': '未运行',
'avatar.metaSelected': '已选',
'avatar.noAgentSelected': '尚未选择代理',
'project.backToProjects': '返回项目列表',
'project.metaFreeform': '自由设计',
'chat.tabChat': '对话',
'chat.tabComments': '评论',
'chat.commentsSoon': '评论 — 即将上线',
'chat.conversationsTitle': '对话历史',
'chat.conversationsAria': '对话历史',
'chat.newConversation': '新建对话',
'chat.newConversationsTitle': '新建对话',
'chat.conversationsHeading': '对话',
'chat.new': '新建',
'chat.emptyConversations': '还没有对话。',
'chat.deleteConversation': '删除对话',
'chat.deleteConversationConfirm': '确定删除「{title}」?该操作会删除其消息。',
'chat.untitledConversation': '未命名对话',
'chat.startTitle': '开始一个对话',
'chat.startHint':
'可以拖拽或粘贴图片作为视觉参考,或键入 @ 引用本项目中的文件。也可以从下面的示例开始:',
'chat.fillInputTitle': '点击填充到输入框',
'chat.jumpToLatest': '回到最新',
'chat.scrollToLatest': '滚动到最新',
'chat.you': '你',
'chat.openFile': '打开 {name}',
'chat.composerPlaceholder': '描述你想要的设计 — 可粘贴/拖入图片,或用 @ 引用文件…',
'chat.composerHint': '⌘/Ctrl + Enter 发送 · 可粘贴图片 · @ 引用文件',
'chat.cliSettingsTitle': 'CLI 与模型设置',
'chat.cliSettingsAria': '打开 CLI 与模型设置',
'chat.attachTitle': '附加文件(也可以粘贴/拖入)',
'chat.attachAria': '附加文件',
'chat.importTitle': '导入素材(即将上线)',
'chat.importLabel': '导入',
'chat.importComingSoon': '即将上线',
'chat.importSoon': '即将',
'chat.importFig': '上传 .fig 文件',
'chat.importGitHub': '连接 GitHub',
'chat.importWeb': '抓取网页元素',
'chat.importFolder': '关联代码目录',
'chat.importSkills': '技能与设计体系',
'chat.importProject': '引用其它项目',
'chat.send': '发送',
'chat.stop': '停止',
'chat.removeAria': '移除 {name}',
'chat.example1Title': '编辑风路演 PPT',
'chat.example1Tag': '杂志',
'chat.example1Prompt':
'为一家正在融种子轮的设计工作室制作 10 张编辑风路演 PPT —— 瑞士网格布局,超大号衬线标题加粗体首字下沉,等宽字体的章节编号,留白充足,整页大图与文字密集页穿插出现。封面、愿景、市场、产品、增长、团队、融资诉求、联系方式。',
'chat.example2Title': 'SaaS 分析仪表盘',
'chat.example2Tag': '数据',
'chat.example2Prompt':
'为一款面向开发者的 SaaS 设计一份信息密度高的分析仪表盘 —— 顶部 KPI 条带(含周环比变化)、两张堆叠折线图(MRR 与活跃工作区)、全球使用热力图、留存矩阵、客户排行榜以及实时事件流。深色主题,等宽数字,迷你图作为点缀。',
'chat.example3Title': '长滚动年度报告',
'chat.example3Tag': '编辑',
'chat.example3Prompt':
'为一家关注气候议题的非营利机构制作互动式年度报告 —— 长滚动编辑式布局,混合大段引言区块、数据可视化(堆叠柱状图、动态计数器、项目地点分布的等值线地图)、摄影分隔页、捐赠者墙,以及最终行动号召。现代衬线正文、无衬线图表标签、大地纸张配色。',
'preview.shareMenu': '分享 ▾',
'preview.openInNewTab': '在新标签页中打开',
'preview.exit': '⤓ 退出',
'preview.fullscreen': '⤢ 全屏',
'preview.closeTitle': '关闭(Esc',
'preview.loading': '正在加载{label}…',
'misc.savedTemplate': '已保存的模板',
'misc.primary': '主体系',
'misc.designSystem': '设计体系',
'workspace.designFiles': '设计文件',
'workspace.closeTab': '关闭标签页',
'workspace.deleteFileConfirm': '从项目文件夹中删除「{name}」?',
'workspace.openFromDesignFiles': '请从',
'workspace.designFilesLink': '设计文件',
'workspace.loadingSketch': '正在加载草图…',
'designFiles.title': '设计文件',
'designFiles.upload': '上传图片',
'designFiles.pasteText': '粘贴为文本文件',
'designFiles.newSketch': '新建草图',
'designFiles.empty': '这里还没有文件。可以拖拽下方区域,或新建草图、粘贴文本。',
'designFiles.refresh': '刷新',
'designFiles.delete': '删除',
'designFiles.searchPlaceholder': '搜索文件…',
'designFiles.up': '上一级',
'designFiles.back': '返回',
'designFiles.crumbs': '项目',
'designFiles.rowMenu': '行菜单',
'designFiles.openInTab': '在标签页中打开',
'designFiles.download': '下载',
'designFiles.dropTitle': '⤓ 把文件拖到这里',
'designFiles.dropDesc': '图片、文档、参考资料、Figma 链接或文件夹 — Claude 都会用作上下文。',
'designFiles.upload.title': '上传一张图片',
'designFiles.paste.title': '将文本粘贴为文件',
'designFiles.upload.label': '上传',
'designFiles.paste.label': '粘贴',
'designFiles.previewOpen': '打开',
'designFiles.previewClose': '关闭预览',
'designFiles.modified': '修改于 {time} · {size}',
'designFiles.weeksAgo': '{n} 周前',
'designFiles.sectionPages': '页面',
'designFiles.sectionScripts': '脚本',
'designFiles.sectionImages': '图片',
'designFiles.sectionSketches': '草图',
'designFiles.sectionOther': '其它',
'designFiles.kindHtml': 'HTML 页面',
'designFiles.kindImage': '图片',
'designFiles.kindSketch': '草图',
'designFiles.kindText': '文本',
'designFiles.kindCode': '脚本',
'designFiles.kindBinary': '二进制',
'pasteDialog.title': '粘贴文本',
'pasteDialog.hint': '将保存到项目文件夹中,名称随你定。',
'pasteDialog.fileNameLabel': '文件名',
'pasteDialog.namePlaceholder': 'notes.txt',
'pasteDialog.contentLabel': '内容',
'pasteDialog.contentPlaceholder': '在此粘贴任何内容…',
'pasteDialog.save': '保存',
'pasteDialog.cancel': '取消',
'sketch.save': '保存草图',
'sketch.cancel': '取消',
'sketch.saving': '保存中…',
'sketch.tooltipDirty': '尚未保存',
'sketch.tooltipClean': '已保存',
'fileViewer.empty': '请选择一个文件查看。',
'fileViewer.loading': '加载中…',
'fileViewer.exportPptx': '导出为 PPTX',
'fileViewer.openInNewTab': '在新标签页中打开',
'fileViewer.copyPath': '复制路径',
'fileViewer.copied': '已复制!',
'fileViewer.share': '分享',
'fileViewer.binaryMeta': '二进制 · {size}',
'fileViewer.binaryNote': '二进制文件({size} 字节)。请下载或在本地打开查看。',
'fileViewer.download': '下载',
'fileViewer.open': '打开',
'fileViewer.imageMeta': '图片 · {size}',
'fileViewer.sketchMeta': '草图 · {size}',
'fileViewer.reload': '重新加载',
'fileViewer.reloadDisk': '从磁盘重新加载',
'fileViewer.copy': '复制',
'fileViewer.copyTitle': '复制文件内容',
'fileViewer.saveDisabled': '保存(只读预览)',
'fileViewer.save': '保存',
'fileViewer.preview': '预览',
'fileViewer.source': '源代码',
'fileViewer.tweaks': '调整',
'fileViewer.comment': '评论',
'fileViewer.edit': '编辑',
'fileViewer.draw': '绘制',
'fileViewer.zoomOut': '缩小',
'fileViewer.zoomIn': '放大',
'fileViewer.resetZoom': '重置缩放',
'fileViewer.reloadAria': '重新加载',
'fileViewer.previousSlide': '上一张',
'fileViewer.nextSlide': '下一张',
'fileViewer.slideNavAria': '幻灯片导航',
'fileViewer.present': '演示',
'fileViewer.presentInTab': '在当前标签页',
'fileViewer.presentFullscreen': '全屏',
'fileViewer.presentNewTab': '新标签页',
'fileViewer.exitPresentation': '退出演示',
'fileViewer.shareLabel': '分享',
'fileViewer.exportPdf': '导出为 PDF',
'fileViewer.exportPdfAllSlides': '导出为 PDF(全部幻灯片)',
'fileViewer.exportPptxBusy': '请等待当前任务完成。',
'fileViewer.exportPptxHint': '请求代理将此设计转换为 PPTX。',
'fileViewer.exportPptxNa': '此处暂不支持导出 PPTX。',
'fileViewer.exportZip': '下载为 .zip',
'fileViewer.exportHtml': '导出为独立 HTML',
'fileViewer.saveAsTemplate': '保存为模板…',
'fileViewer.savingTemplate': '正在保存模板…',
'fileViewer.savedTemplate': '已保存为「{name}」',
'fileViewer.savedTemplateFail': '保存模板失败,请重试。',
'fileViewer.templateNamePrompt': '模板名称',
'fileViewer.templateNameDefault': '未命名模板',
'fileViewer.templateDescPrompt': '简短描述(可选 — 这个模板用于什么场景?)',
'questionForm.submit': '提交',
'questionForm.skip': '跳过',
'questionForm.locked': '已回答',
'conv.switch': '切换对话',
'conv.label': '对话',
'conv.heading': '对话历史',
'conv.new': '+ 新建',
'conv.empty': '还没有对话。',
'conv.untitled': '未命名对话',
'conv.renameTooltip': '双击重命名',
'conv.delete': '删除对话',
'conv.deleteConfirm': '确定删除「{title}」?该操作会删除其消息。',
'agentPicker.label': '代理',
'agentPicker.modeChoose': '选择执行模式',
'agentPicker.localCli': '本机 CLI',
'agentPicker.daemonOff': '守护进程未运行',
'agentPicker.byok': 'Anthropic API · 自带 Key',
'agentPicker.selectAgent': '选择已检测到的代码代理 CLI',
'agentPicker.noAgents': 'PATH 中未发现代理',
'agentPicker.notInstalled': '未安装',
'agentPicker.rescan': '重新扫描 PATH 中的代理',
'tool.openInTab': '在标签页中打开 {name}',
'tool.open': '打开',
'tool.todos': '待办',
'tool.write': '写入',
'tool.edit': '编辑',
'tool.read': '读取',
'tool.bash': 'Bash',
'tool.glob': 'Glob',
'tool.grep': 'Grep',
'tool.fetch': '抓取',
'tool.search': '搜索',
'tool.lines': '{n} 行',
'tool.changeSingular': '处变更',
'tool.changePlural': '处变更',
'tool.in': '于 {path}',
'tool.hide': '隐藏',
'tool.output': '输出',
'tool.running': '运行中…',
'tool.error': '错误',
'tool.done': '完成',
'assistant.role': 'Claude',
'assistant.workingLabel': '执行中',
'assistant.doneLabel': '已完成',
'assistant.outTokens': '{n} 输出',
'assistant.producedFiles': '本轮产出的文件',
'assistant.openFile': '打开',
'assistant.downloadFile': '下载',
'assistant.thinking': '思考中',
'assistant.systemReminder': '系统提示',
'assistant.waitingFirstOutput': '等待首批输出中',
'assistant.statusBootingAgent': '正在启动代理',
'assistant.statusStarting': '启动中',
'assistant.statusRequesting': '正在发送请求',
'assistant.statusThinking': '思考中',
'assistant.statusStreaming': '流式输出中',
'assistant.slowHint':
'耗时比平时更久。一般 5–10 秒内会出现表单,可以「停止」后重新表述。',
'assistant.verbEditing': '编辑',
'assistant.verbWriting': '写入',
'assistant.verbReading': '读取',
'assistant.verbSearching': '搜索',
'assistant.verbRunning': '运行',
'assistant.verbTodos': '待办',
'assistant.verbFetching': '抓取',
'assistant.verbCalling': '调用',
'qf.answered': '已回答',
'qf.choose': '请选择…',
'qf.required': '必填',
'qf.lockedSubmitted': '答案已发送,代理将在本次会话后续使用。',
'qf.lockedPrev': '该表单来自此前的对话。',
'qf.hint': '挑选合适的选项;可选项可以跳过,代理会使用合理的默认值。',
'qf.submitDefault': '发送答案',
'qf.submitDisabledTitle': '请先填写必填项',
'qf.submitTitle': '发送答案',
'qf.cardSelected': '已选',
'qf.cardRefs': '参考:',
'qf.cardSampleText': '飞燕环宇 · 0123',
'sketch.toolSelect': '选择(占位)',
'sketch.toolPen': '钢笔',
'sketch.toolText': '文本',
'sketch.toolRect': '矩形',
'sketch.toolArrow': '箭头',
'sketch.toolEraser': '橡皮擦',
'sketch.color': '颜色',
'sketch.strokeSize': '描边粗细',
'sketch.undo': '撤销',
'sketch.clear': '清空',
'sketch.close': '关闭',
'sketch.textPrompt': '请输入文本:',
};
+503
View File
@@ -0,0 +1,503 @@
// Supported UI locales. Adding a new locale requires creating a new
// dictionary in `./locales/` and registering it in `./index.tsx`.
export type Locale = 'en' | 'zh-CN';
export const LOCALES: Locale[] = ['en', 'zh-CN'];
export const LOCALE_LABEL: Record<Locale, string> = {
'en': 'English',
'zh-CN': '简体中文',
};
// Translation dictionary shape — flat keys, dot-namespaced. We keep it
// flat (not deeply nested) so missing-key TS errors point straight at the
// offending string instead of a generic object mismatch.
export interface Dict {
// Common
'common.cancel': string;
'common.save': string;
'common.close': string;
'common.delete': string;
'common.rename': string;
'common.preview': string;
'common.share': string;
'common.search': string;
'common.searchEllipsis': string;
'common.loading': string;
'common.all': string;
'common.none': string;
'common.default': string;
'common.installed': string;
'common.notInstalled': string;
'common.active': string;
'common.offline': string;
'common.selected': string;
'common.create': string;
'common.openPreview': string;
'common.exitFullscreen': string;
'common.fullscreen': string;
'common.openInNewTab': string;
'common.exportPdf': string;
'common.exportZip': string;
'common.exportHtml': string;
'common.justNow': string;
'common.minutesAgo': string;
'common.hoursAgo': string;
'common.daysAgo': string;
'common.now': string;
'common.minutesShort': string;
'common.hoursShort': string;
'common.daysShort': string;
'common.untitled': string;
// App / brand
'app.brand': string;
'app.brandPill': string;
'app.brandSubtitle': string;
'app.welcomeLoading': string;
// Settings dialog
'settings.welcomeKicker': string;
'settings.welcomeTitle': string;
'settings.welcomeSubtitle': string;
'settings.kicker': string;
'settings.title': string;
'settings.subtitle': string;
'settings.modeAria': string;
'settings.modeDaemon': string;
'settings.modeDaemonHelp': string;
'settings.modeDaemonOffline': string;
'settings.modeDaemonOfflineMeta': string;
'settings.modeDaemonInstalledMeta': string;
'settings.modeApi': string;
'settings.modeApiMeta': string;
'settings.codeAgent': string;
'settings.codeAgentHint': string;
'settings.rescan': string;
'settings.rescanTitle': string;
'settings.noAgentsDetected': string;
'settings.apiSection': string;
'settings.apiKey': string;
'settings.showKey': string;
'settings.hideKey': string;
'settings.show': string;
'settings.hide': string;
'settings.model': string;
'settings.baseUrl': string;
'settings.apiHint': string;
'settings.skipForNow': string;
'settings.getStarted': string;
'settings.envConfigure': string;
'settings.localCli': string;
'settings.anthropicApi': string;
'settings.noAgentSelected': string;
'settings.language': string;
'settings.languageHint': string;
// Entry view / tabs
'entry.tabDesigns': string;
'entry.tabExamples': string;
'entry.tabDesignSystems': string;
'entry.openSettingsTitle': string;
'entry.openSettingsAria': string;
'entry.resizeAria': string;
'entry.loadingWorkspace': string;
// New project panel
'newproj.tabPrototype': string;
'newproj.tabDeck': string;
'newproj.tabTemplate': string;
'newproj.tabOther': string;
'newproj.titlePrototype': string;
'newproj.titleDeck': string;
'newproj.titleTemplate': string;
'newproj.titleOther': string;
'newproj.namePlaceholder': string;
'newproj.fidelityLabel': string;
'newproj.fidelityWireframe': string;
'newproj.fidelityHigh': string;
'newproj.toggleSpeakerNotes': string;
'newproj.toggleSpeakerNotesHint': string;
'newproj.toggleAnimations': string;
'newproj.toggleAnimationsHint': string;
'newproj.templateLabel': string;
'newproj.noTemplatesTitle': string;
'newproj.noTemplatesBody': string;
'newproj.savedTemplate': string;
'newproj.fileSingular': string;
'newproj.filePlural': string;
'newproj.create': string;
'newproj.createFromTemplate': string;
'newproj.createDisabledTitle': string;
'newproj.privacyFooter': string;
'newproj.designSystem': string;
'newproj.dsNoneFreeform': string;
'newproj.dsNoneSubtitleEmpty': string;
'newproj.dsNoneSubtitleSelected': string;
'newproj.dsCategoryFallback': string;
'newproj.dsSearch': string;
'newproj.dsModeAria': string;
'newproj.dsModeSingle': string;
'newproj.dsModeMulti': string;
'newproj.dsNoneTitle': string;
'newproj.dsNoneSub': string;
'newproj.dsEmpty': string;
'newproj.dsFootSingular': string;
'newproj.dsFootPlural': string;
'newproj.dsFootClear': string;
'newproj.dsBadgeDefault': string;
'newproj.dsPrimaryFallback': string;
// Designs tab
'designs.subRecent': string;
'designs.subYours': string;
'designs.filterAria': string;
'designs.searchPlaceholder': string;
'designs.emptyNoProjects': string;
'designs.emptyNoMatch': string;
'designs.deleteTitle': string;
'designs.deleteConfirm': string;
'designs.cardFreeform': string;
// Examples tab
'examples.typeLabel': string;
'examples.scenarioLabel': string;
'examples.modeAll': string;
'examples.modePrototypeDesktop': string;
'examples.modePrototypeMobile': string;
'examples.modeDeck': string;
'examples.modeDocument': string;
'examples.scenarioGeneral': string;
'examples.scenarioEngineering': string;
'examples.scenarioProduct': string;
'examples.scenarioDesign': string;
'examples.scenarioMarketing': string;
'examples.scenarioSales': string;
'examples.scenarioFinance': string;
'examples.scenarioHr': string;
'examples.scenarioOperations': string;
'examples.scenarioSupport': string;
'examples.scenarioLegal': string;
'examples.scenarioEducation': string;
'examples.scenarioPersonal': string;
'examples.emptyNoSkills': string;
'examples.emptyNoMatch': string;
'examples.openPreview': string;
'examples.loadingPreview': string;
'examples.hoverPreview': string;
'examples.usePrompt': string;
'examples.previewModalTitle': string;
'examples.shareTitle': string;
'examples.shareLoadFirst': string;
'examples.shareMenu': string;
'examples.exportPdfAllSlides': string;
'examples.exportPptxLocked': string;
'examples.tagSlideDeck': string;
'examples.tagTemplate': string;
'examples.tagDesignSystem': string;
'examples.tagMobilePrototype': string;
'examples.tagDesktopPrototype': string;
'examples.previewLabel': string;
// Design systems tab
'ds.searchPlaceholder': string;
'ds.emptyNoMatch': string;
'ds.badgeDefault': string;
'ds.preview': string;
'ds.previewTitle': string;
'ds.categoryAll': string;
'ds.categoryUncategorized': string;
'ds.showcase': string;
'ds.tokens': string;
// Avatar menu (project topbar)
'avatar.title': string;
'avatar.localCli': string;
'avatar.anthropicApi': string;
'avatar.useLocal': string;
'avatar.useApi': string;
'avatar.codeAgent': string;
'avatar.rescan': string;
'avatar.settings': string;
'avatar.backToProjects': string;
'avatar.metaActive': string;
'avatar.metaOffline': string;
'avatar.metaSelected': string;
'avatar.noAgentSelected': string;
// Project view / chat pane / composer
'project.backToProjects': string;
'project.metaFreeform': string;
'chat.tabChat': string;
'chat.tabComments': string;
'chat.commentsSoon': string;
'chat.conversationsTitle': string;
'chat.conversationsAria': string;
'chat.newConversation': string;
'chat.newConversationsTitle': string;
'chat.conversationsHeading': string;
'chat.new': string;
'chat.emptyConversations': string;
'chat.deleteConversation': string;
'chat.deleteConversationConfirm': string;
'chat.untitledConversation': string;
'chat.startTitle': string;
'chat.startHint': string;
'chat.fillInputTitle': string;
'chat.jumpToLatest': string;
'chat.scrollToLatest': string;
'chat.you': string;
'chat.openFile': string;
'chat.composerPlaceholder': string;
'chat.composerHint': string;
'chat.cliSettingsTitle': string;
'chat.cliSettingsAria': string;
'chat.attachTitle': string;
'chat.attachAria': string;
'chat.importTitle': string;
'chat.importLabel': string;
'chat.importComingSoon': string;
'chat.importSoon': string;
'chat.importFig': string;
'chat.importGitHub': string;
'chat.importWeb': string;
'chat.importFolder': string;
'chat.importSkills': string;
'chat.importProject': string;
'chat.send': string;
'chat.stop': string;
'chat.removeAria': string;
'chat.example1Title': string;
'chat.example1Tag': string;
'chat.example1Prompt': string;
'chat.example2Title': string;
'chat.example2Tag': string;
'chat.example2Prompt': string;
'chat.example3Title': string;
'chat.example3Tag': string;
'chat.example3Prompt': string;
// Preview modal
'preview.shareMenu': string;
'preview.openInNewTab': string;
'preview.exit': string;
'preview.fullscreen': string;
'preview.closeTitle': string;
'preview.loading': string;
// Misc fallback names
'misc.savedTemplate': string;
'misc.primary': string;
'misc.designSystem': string;
// Workspace / file viewer / design files panel
'workspace.designFiles': string;
'workspace.closeTab': string;
'workspace.deleteFileConfirm': string;
'workspace.openFromDesignFiles': string;
'workspace.designFilesLink': string;
'workspace.loadingSketch': string;
'designFiles.title': string;
'designFiles.upload': string;
'designFiles.pasteText': string;
'designFiles.newSketch': string;
'designFiles.empty': string;
'designFiles.refresh': string;
'designFiles.delete': string;
'designFiles.searchPlaceholder': string;
'designFiles.up': string;
'designFiles.back': string;
'designFiles.crumbs': string;
'designFiles.rowMenu': string;
'designFiles.openInTab': string;
'designFiles.download': string;
'designFiles.dropTitle': string;
'designFiles.dropDesc': string;
'designFiles.upload.title': string;
'designFiles.paste.title': string;
'designFiles.upload.label': string;
'designFiles.paste.label': string;
'designFiles.previewOpen': string;
'designFiles.previewClose': string;
'designFiles.modified': string;
'designFiles.weeksAgo': string;
'designFiles.sectionPages': string;
'designFiles.sectionScripts': string;
'designFiles.sectionImages': string;
'designFiles.sectionSketches': string;
'designFiles.sectionOther': string;
'designFiles.kindHtml': string;
'designFiles.kindImage': string;
'designFiles.kindSketch': string;
'designFiles.kindText': string;
'designFiles.kindCode': string;
'designFiles.kindBinary': string;
'pasteDialog.title': string;
'pasteDialog.hint': string;
'pasteDialog.fileNameLabel': string;
'pasteDialog.namePlaceholder': string;
'pasteDialog.contentLabel': string;
'pasteDialog.contentPlaceholder': string;
'pasteDialog.save': string;
'pasteDialog.cancel': string;
'sketch.save': string;
'sketch.cancel': string;
'sketch.saving': string;
'sketch.tooltipDirty': string;
'sketch.tooltipClean': string;
'fileViewer.empty': string;
'fileViewer.loading': string;
'fileViewer.exportPptx': string;
'fileViewer.openInNewTab': string;
'fileViewer.copyPath': string;
'fileViewer.copied': string;
'fileViewer.share': string;
'fileViewer.binaryMeta': string;
'fileViewer.binaryNote': string;
'fileViewer.download': string;
'fileViewer.open': string;
'fileViewer.imageMeta': string;
'fileViewer.sketchMeta': string;
'fileViewer.reload': string;
'fileViewer.reloadDisk': string;
'fileViewer.copy': string;
'fileViewer.copyTitle': string;
'fileViewer.saveDisabled': string;
'fileViewer.save': string;
'fileViewer.preview': string;
'fileViewer.source': string;
'fileViewer.tweaks': string;
'fileViewer.comment': string;
'fileViewer.edit': string;
'fileViewer.draw': string;
'fileViewer.zoomOut': string;
'fileViewer.zoomIn': string;
'fileViewer.resetZoom': string;
'fileViewer.reloadAria': string;
'fileViewer.previousSlide': string;
'fileViewer.nextSlide': string;
'fileViewer.slideNavAria': string;
'fileViewer.present': string;
'fileViewer.presentInTab': string;
'fileViewer.presentFullscreen': string;
'fileViewer.presentNewTab': string;
'fileViewer.exitPresentation': string;
'fileViewer.shareLabel': string;
'fileViewer.exportPdf': string;
'fileViewer.exportPdfAllSlides': string;
'fileViewer.exportPptxBusy': string;
'fileViewer.exportPptxHint': string;
'fileViewer.exportPptxNa': string;
'fileViewer.exportZip': string;
'fileViewer.exportHtml': string;
'fileViewer.saveAsTemplate': string;
'fileViewer.savingTemplate': string;
'fileViewer.savedTemplate': string;
'fileViewer.savedTemplateFail': string;
'fileViewer.templateNamePrompt': string;
'fileViewer.templateNameDefault': string;
'fileViewer.templateDescPrompt': string;
// Question form (assistant question UX)
'questionForm.submit': string;
'questionForm.skip': string;
'questionForm.locked': string;
// Conversations dropdown
'conv.switch': string;
'conv.label': string;
'conv.heading': string;
'conv.new': string;
'conv.empty': string;
'conv.untitled': string;
'conv.renameTooltip': string;
'conv.delete': string;
'conv.deleteConfirm': string;
// Agent picker (legacy / alt)
'agentPicker.label': string;
'agentPicker.modeChoose': string;
'agentPicker.localCli': string;
'agentPicker.daemonOff': string;
'agentPicker.byok': string;
'agentPicker.selectAgent': string;
'agentPicker.noAgents': string;
'agentPicker.notInstalled': string;
'agentPicker.rescan': string;
// Tool cards (assistant action cards)
'tool.openInTab': string;
'tool.open': string;
'tool.todos': string;
'tool.write': string;
'tool.edit': string;
'tool.read': string;
'tool.bash': string;
'tool.glob': string;
'tool.grep': string;
'tool.fetch': string;
'tool.search': string;
'tool.lines': string;
'tool.changeSingular': string;
'tool.changePlural': string;
'tool.in': string;
'tool.hide': string;
'tool.output': string;
'tool.running': string;
'tool.error': string;
'tool.done': string;
// Assistant message scaffolding
'assistant.role': string;
'assistant.workingLabel': string;
'assistant.doneLabel': string;
'assistant.outTokens': string;
'assistant.producedFiles': string;
'assistant.openFile': string;
'assistant.downloadFile': string;
'assistant.thinking': string;
'assistant.systemReminder': string;
'assistant.waitingFirstOutput': string;
'assistant.statusBootingAgent': string;
'assistant.statusStarting': string;
'assistant.statusRequesting': string;
'assistant.statusThinking': string;
'assistant.statusStreaming': string;
'assistant.slowHint': string;
'assistant.verbEditing': string;
'assistant.verbWriting': string;
'assistant.verbReading': string;
'assistant.verbSearching': string;
'assistant.verbRunning': string;
'assistant.verbTodos': string;
'assistant.verbFetching': string;
'assistant.verbCalling': string;
// Question form labels
'qf.answered': string;
'qf.choose': string;
'qf.required': string;
'qf.lockedSubmitted': string;
'qf.lockedPrev': string;
'qf.hint': string;
'qf.submitDefault': string;
'qf.submitDisabledTitle': string;
'qf.submitTitle': string;
'qf.cardSelected': string;
'qf.cardRefs': string;
'qf.cardSampleText': string;
// Sketch editor
'sketch.toolSelect': string;
'sketch.toolPen': string;
'sketch.toolText': string;
'sketch.toolRect': string;
'sketch.toolArrow': string;
'sketch.toolEraser': string;
'sketch.color': string;
'sketch.strokeSize': string;
'sketch.undo': string;
'sketch.clear': string;
'sketch.close': string;
'sketch.textPrompt': string;
}