2156 lines
64 KiB
TypeScript
2156 lines
64 KiB
TypeScript
import { roomMessages, type RoomMessages } from './i18n/rooms';
|
||
|
||
export const LOCALES = ['ko', 'en', 'zh', 'ja'] as const;
|
||
|
||
export type Locale = (typeof LOCALES)[number];
|
||
|
||
export interface Messages {
|
||
app: {
|
||
loading: string;
|
||
};
|
||
actions: {
|
||
close: string;
|
||
refresh: string;
|
||
refreshing: string;
|
||
retry: string;
|
||
};
|
||
nav: {
|
||
aria: string;
|
||
drawerAria: string;
|
||
drawerNavAria: string;
|
||
menuOpen: string;
|
||
menuClose: string;
|
||
operations: string;
|
||
updated: string;
|
||
health: string;
|
||
inbox: string;
|
||
usage: string;
|
||
rooms: string;
|
||
scheduled: string;
|
||
settings: string;
|
||
};
|
||
language: {
|
||
label: string;
|
||
};
|
||
settings: {
|
||
title: string;
|
||
nicknameLabel: string;
|
||
nicknamePlaceholder: string;
|
||
nicknameHelp: string;
|
||
languageLabel: string;
|
||
navAria: string;
|
||
contentAria: string;
|
||
sidebarAria: string;
|
||
nav: {
|
||
general: { title: string; detail: string };
|
||
models: { title: string; detail: string };
|
||
runtime: { title: string; detail: string };
|
||
moa: { title: string; detail: string };
|
||
codex: { title: string; detail: string };
|
||
accounts: { title: string; detail: string };
|
||
};
|
||
apply: {
|
||
aria: string;
|
||
kicker: string;
|
||
title: string;
|
||
hint: string;
|
||
restart: string;
|
||
};
|
||
sections: {
|
||
general: { kicker: string; title: string; description: string };
|
||
models: { kicker: string; title: string; description: string };
|
||
runtime: { kicker: string; title: string; description: string };
|
||
moa: { kicker: string; title: string; description: string };
|
||
codex: { kicker: string; title: string; description: string };
|
||
accounts: { kicker: string; title: string; description: string };
|
||
};
|
||
common: {
|
||
loading: string;
|
||
none: string;
|
||
saving: string;
|
||
saved: string;
|
||
savedRestartHint: string;
|
||
save: string;
|
||
delete: string;
|
||
refresh: string;
|
||
refreshing: string;
|
||
refreshAll: string;
|
||
switch: string;
|
||
switching: string;
|
||
default: string;
|
||
inUse: string;
|
||
add: string;
|
||
};
|
||
models: {
|
||
roleOwner: string;
|
||
roleReviewer: string;
|
||
roleArbiter: string;
|
||
roleOwnerHint: string;
|
||
roleReviewerHint: string;
|
||
roleArbiterHint: string;
|
||
modelLabel: string;
|
||
effortLabel: string;
|
||
modelDefault: string;
|
||
modelCustom: string;
|
||
modelCustomLabel: string;
|
||
modelPlaceholder: string;
|
||
groupCodex: string;
|
||
groupClaude: string;
|
||
groupCustom: string;
|
||
effortDefault: string;
|
||
effortOptions: {
|
||
low: string;
|
||
medium: string;
|
||
high: string;
|
||
xhigh: string;
|
||
max: string;
|
||
};
|
||
agentTypeLabel: string;
|
||
agentTypeCodex: string;
|
||
agentTypeClaude: string;
|
||
effortInvalid: string;
|
||
effortSaveBlocked: string;
|
||
save: string;
|
||
empty: string;
|
||
};
|
||
codex: {
|
||
fastMode: string;
|
||
features: string;
|
||
codexFast: string;
|
||
codexFastHint: string;
|
||
claudeFast: string;
|
||
claudeFastHint: string;
|
||
fastModeApplyHint: string;
|
||
goal: string;
|
||
goalHint: string;
|
||
goalApplyHint: string;
|
||
};
|
||
accounts: {
|
||
claude: string;
|
||
codex: string;
|
||
noAccounts: string;
|
||
autoRefresh: string;
|
||
codexRefreshHint: string;
|
||
tokenPlaceholder: string;
|
||
deleteConfirm: string;
|
||
refreshFailed: string;
|
||
paymentExpired: string;
|
||
paymentUntil: string;
|
||
paymentUntilDays: string;
|
||
primaryAccount: string;
|
||
activeAccount: string;
|
||
addTokenLabel: string;
|
||
refreshTitle: string;
|
||
switchTitle: string;
|
||
};
|
||
moa: {
|
||
master: string;
|
||
masterHint: string;
|
||
save: string;
|
||
empty: string;
|
||
test: string;
|
||
testing: string;
|
||
testAfterSave: string;
|
||
notTested: string;
|
||
statusOk: string;
|
||
statusFail: string;
|
||
apiKeyPlaceholder: string;
|
||
apiKeySet: string;
|
||
modelLabel: string;
|
||
baseUrlLabel: string;
|
||
formatLabel: string;
|
||
};
|
||
runtime: {
|
||
defaultHint: string;
|
||
selectRoomLabel: string;
|
||
selectAgentLabel: string;
|
||
scopeCodexUser: string;
|
||
scopeClaudeUser: string;
|
||
scopeRunner: string;
|
||
emptyRooms: string;
|
||
emptySkills: string;
|
||
agentCodex: string;
|
||
agentClaude: string;
|
||
};
|
||
};
|
||
error: {
|
||
api: string;
|
||
network: string;
|
||
timeout: string;
|
||
server: string;
|
||
notFound: string;
|
||
auth: string;
|
||
unknown: string;
|
||
};
|
||
control: {
|
||
aria: string;
|
||
queue: string;
|
||
activeRooms: string;
|
||
pendingRooms: string;
|
||
};
|
||
pwa: {
|
||
app: string;
|
||
install: string;
|
||
installed: string;
|
||
ready: string;
|
||
cached: string;
|
||
online: string;
|
||
offline: string;
|
||
fresh: string;
|
||
stale: string;
|
||
secureRequired: string;
|
||
updated: string;
|
||
};
|
||
metrics: {
|
||
agents: string;
|
||
rooms: string;
|
||
ciWatchers: string;
|
||
};
|
||
panels: {
|
||
health: string;
|
||
heartbeat: string;
|
||
healthSignals: string;
|
||
inbox: string;
|
||
inboxQueue: string;
|
||
usage: string;
|
||
usageWindow: string;
|
||
rooms: string;
|
||
queue: string;
|
||
scheduled: string;
|
||
};
|
||
service: {
|
||
empty: string;
|
||
heartbeat: string;
|
||
service: string;
|
||
rooms: string;
|
||
updated: string;
|
||
};
|
||
health: {
|
||
system: string;
|
||
signals: string;
|
||
services: string;
|
||
fresh: string;
|
||
stale: string;
|
||
queue: string;
|
||
ciFailures: string;
|
||
affectedServices: string;
|
||
restart: string;
|
||
restartStack: string;
|
||
restarting: string;
|
||
restartHint: string;
|
||
confirmRestart: string;
|
||
restartLog: string;
|
||
restartTarget: string;
|
||
restartStatus: string;
|
||
restartRequested: string;
|
||
restartServices: string;
|
||
levels: {
|
||
ok: string;
|
||
stale: string;
|
||
down: string;
|
||
};
|
||
};
|
||
inbox: {
|
||
empty: string;
|
||
cardsAria: string;
|
||
summary: string;
|
||
total: string;
|
||
filters: string;
|
||
all: string;
|
||
noSummary: string;
|
||
occurred: string;
|
||
source: string;
|
||
target: string;
|
||
openTask: string;
|
||
openRoom: string;
|
||
kinds: {
|
||
'pending-room': string;
|
||
'reviewer-request': string;
|
||
approval: string;
|
||
'arbiter-request': string;
|
||
'ci-failure': string;
|
||
mention: string;
|
||
};
|
||
severity: {
|
||
info: string;
|
||
warn: string;
|
||
error: string;
|
||
};
|
||
actions: {
|
||
run: string;
|
||
busy: string;
|
||
runReview: string;
|
||
finalize: string;
|
||
runArbiter: string;
|
||
decline: string;
|
||
dismiss: string;
|
||
confirmDecline: string;
|
||
};
|
||
};
|
||
rooms: RoomMessages;
|
||
usage: {
|
||
empty: string;
|
||
current: string;
|
||
tightest: string;
|
||
watch: string;
|
||
remaining: string;
|
||
speed: string;
|
||
inUse: string;
|
||
reset: string;
|
||
noReset: string;
|
||
limitBasis: {
|
||
h5: string;
|
||
d7: string;
|
||
};
|
||
quota: {
|
||
h5: string;
|
||
d7: string;
|
||
};
|
||
usage: string;
|
||
groupPrimary: string;
|
||
groupCodex: string;
|
||
risk: {
|
||
ok: string;
|
||
warn: string;
|
||
critical: string;
|
||
};
|
||
speedLabel: {
|
||
ok: string;
|
||
warn: string;
|
||
critical: string;
|
||
};
|
||
};
|
||
tasks: {
|
||
empty: string;
|
||
cardsAria: string;
|
||
groups: {
|
||
watchers: string;
|
||
scheduled: string;
|
||
paused: string;
|
||
completed: string;
|
||
};
|
||
count: string;
|
||
groupEmpty: string;
|
||
task: string;
|
||
status: string;
|
||
schedule: string;
|
||
next: string;
|
||
last: string;
|
||
context: string;
|
||
ciWatch: string;
|
||
emptyPrompt: string;
|
||
prompt: string;
|
||
until: string;
|
||
suspendedUntil: string;
|
||
lastResult: string;
|
||
result: string;
|
||
resultOk: string;
|
||
resultFail: string;
|
||
noResult: string;
|
||
noTime: string;
|
||
now: string;
|
||
createTitle: string;
|
||
createSubtitle: string;
|
||
filterAll: string;
|
||
details: string;
|
||
room: string;
|
||
selectRoom: string;
|
||
scheduleType: string;
|
||
scheduleValue: string;
|
||
scheduleValueHint: string;
|
||
promptPlaceholder: string;
|
||
editPromptPlaceholder: string;
|
||
scheduleTypes: {
|
||
once: string;
|
||
interval: string;
|
||
cron: string;
|
||
};
|
||
contextModes: {
|
||
isolated: string;
|
||
group: string;
|
||
};
|
||
actions: {
|
||
create: string;
|
||
edit: string;
|
||
save: string;
|
||
pause: string;
|
||
resume: string;
|
||
cancel: string;
|
||
busy: string;
|
||
confirmCancel: string;
|
||
};
|
||
};
|
||
status: {
|
||
processing: string;
|
||
waiting: string;
|
||
inactive: string;
|
||
active: string;
|
||
paused: string;
|
||
completed: string;
|
||
};
|
||
units: {
|
||
second: string;
|
||
minute: string;
|
||
hour: string;
|
||
task: string;
|
||
messageShort: string;
|
||
chars: string;
|
||
};
|
||
}
|
||
|
||
export const languageNames: Record<Locale, string> = {
|
||
ko: '한국어',
|
||
en: 'English',
|
||
zh: '简体中文',
|
||
ja: '日本語',
|
||
};
|
||
|
||
export const localeTags: Record<Locale, string> = {
|
||
ko: 'ko-KR',
|
||
en: 'en-US',
|
||
zh: 'zh-CN',
|
||
ja: 'ja-JP',
|
||
};
|
||
|
||
export const messages = {
|
||
ko: {
|
||
app: {
|
||
loading: '대시보드 로딩 중',
|
||
},
|
||
actions: {
|
||
close: '닫기',
|
||
refresh: '새로고침',
|
||
refreshing: '새로고침 중',
|
||
retry: '다시 시도',
|
||
},
|
||
nav: {
|
||
aria: '대시보드 섹션',
|
||
drawerAria: '대시보드 메뉴',
|
||
drawerNavAria: '대시보드 메뉴 섹션',
|
||
menuOpen: '메뉴 열기',
|
||
menuClose: '메뉴 닫기',
|
||
operations: '운영',
|
||
updated: '갱신',
|
||
health: '상태',
|
||
inbox: 'Inbox',
|
||
usage: '사용량',
|
||
rooms: '룸',
|
||
scheduled: '예약',
|
||
settings: '설정',
|
||
},
|
||
language: {
|
||
label: '언어',
|
||
},
|
||
settings: {
|
||
title: '설정',
|
||
nicknameLabel: '닉네임',
|
||
nicknamePlaceholder: 'Web Dashboard',
|
||
nicknameHelp: '룸에서 메시지 보낼 때 표시될 이름',
|
||
languageLabel: '언어',
|
||
navAria: '설정 섹션',
|
||
contentAria: '설정 항목',
|
||
sidebarAria: '설정 탐색과 적용',
|
||
nav: {
|
||
general: { title: '일반', detail: '표시 · 언어' },
|
||
models: { title: '모델', detail: 'owner · reviewer · arbiter' },
|
||
runtime: { title: '스킬', detail: '방별 ON · OFF' },
|
||
moa: { title: 'MoA', detail: '참조 모델 · 연결 테스트' },
|
||
codex: { title: 'Codex', detail: 'fast mode · /goal' },
|
||
accounts: { title: '계정', detail: 'Claude · Codex' },
|
||
},
|
||
apply: {
|
||
aria: '변경 적용',
|
||
kicker: 'Apply',
|
||
title: '저장 후 재시작',
|
||
hint: '모델, MoA, Codex, 계정 변경은 스택 재시작 후 반영됩니다.',
|
||
restart: '스택 재시작',
|
||
},
|
||
sections: {
|
||
general: {
|
||
kicker: 'Dashboard identity',
|
||
title: '일반',
|
||
description: '브라우저에서 보이는 이름과 언어만 즉시 바뀝니다.',
|
||
},
|
||
models: {
|
||
kicker: 'Agent routing',
|
||
title: '모델',
|
||
description:
|
||
'역할별 모델과 추론 강도를 선택합니다. 저장 후 스택 재시작이 필요합니다.',
|
||
},
|
||
runtime: {
|
||
kicker: 'Agent skills',
|
||
title: '스킬',
|
||
description:
|
||
'방마다 에이전트가 쓸 스킬을 켜거나 끕니다. 전역 일괄 설정은 없고, 기본값은 모두 켜짐입니다.',
|
||
},
|
||
moa: {
|
||
kicker: 'Arbiter references',
|
||
title: 'MoA 참조 모델',
|
||
description:
|
||
'Kimi, GLM 같은 외부 참조 모델을 켜고 연결 상태를 바로 확인합니다.',
|
||
},
|
||
codex: {
|
||
kicker: 'Codex runtime',
|
||
title: 'Codex 옵션',
|
||
description:
|
||
'빠른 응답과 실험 기능을 관리합니다. /goal은 여기에서 찾을 수 있습니다.',
|
||
},
|
||
accounts: {
|
||
kicker: 'Credentials',
|
||
title: '계정',
|
||
description: 'Claude OAuth와 Codex 계정 상태를 확인하고 전환합니다.',
|
||
},
|
||
},
|
||
common: {
|
||
loading: '불러오는 중…',
|
||
none: '없음',
|
||
saving: '저장 중…',
|
||
saved: '저장됨',
|
||
savedRestartHint:
|
||
'저장됨. 적용하려면 사이드바의 스택 재시작을 눌러 주세요.',
|
||
save: '저장',
|
||
delete: '삭제',
|
||
refresh: '갱신',
|
||
refreshing: '갱신중…',
|
||
refreshAll: '전체 갱신',
|
||
switch: '전환',
|
||
switching: '전환중…',
|
||
default: '기본',
|
||
inUse: '사용중',
|
||
add: '추가',
|
||
},
|
||
models: {
|
||
roleOwner: 'Owner',
|
||
roleReviewer: 'Reviewer',
|
||
roleArbiter: 'Arbiter',
|
||
roleOwnerHint: '작업을 직접 수행하는 에이전트',
|
||
roleReviewerHint: '변경 사항을 검토하는 에이전트',
|
||
roleArbiterHint: '최종 판단을 내리는 에이전트',
|
||
modelLabel: '모델',
|
||
effortLabel: '추론 강도',
|
||
modelDefault: '기본값 (.env 상속)',
|
||
modelCustom: '직접 입력…',
|
||
modelCustomLabel: '모델 ID',
|
||
modelPlaceholder: '예: gpt-5.5, claude-opus-4-8',
|
||
groupCodex: 'Codex',
|
||
groupClaude: 'Claude',
|
||
groupCustom: '사용자 지정',
|
||
effortDefault: '기본값 (.env 상속)',
|
||
effortOptions: {
|
||
low: '낮음',
|
||
medium: '보통',
|
||
high: '높음',
|
||
xhigh: '매우 높음',
|
||
max: '최대',
|
||
},
|
||
agentTypeLabel: '에이전트',
|
||
agentTypeCodex: 'Codex',
|
||
agentTypeClaude: 'Claude Code',
|
||
effortInvalid:
|
||
'"{value}"는 {agent}에서 지원하지 않는 추론 강도입니다. 다른 값을 선택해 주세요.',
|
||
effortSaveBlocked:
|
||
'지원하지 않는 추론 강도가 있습니다. 저장하기 전에 수정해 주세요.',
|
||
save: '모델 저장',
|
||
empty: '모델 정보 없음',
|
||
},
|
||
codex: {
|
||
fastMode: '패스트 모드',
|
||
features: 'Codex 기능',
|
||
codexFast: 'Codex (GPT)',
|
||
codexFastHint:
|
||
'~/.codex/config.toml [features].fast_mode — GPT 5.5 등에서 응답 속도를 높입니다. 사용량이 더 듭니다.',
|
||
claudeFast: 'Claude',
|
||
claudeFastHint:
|
||
'~/.claude/settings.json fastMode — Opus 4.8에서 세션 settings.json으로 동기화됩니다.',
|
||
fastModeApplyHint:
|
||
'스택 재시작 없이 다음 Codex/Claude 작업부터 적용됩니다.',
|
||
goal: 'Goals (/goal)',
|
||
goalHint:
|
||
'~/.codex/config.toml [features].goals — Codex 0.133 기준 opt-in 기능입니다. 기본값은 꺼짐(OFF)이며, 켜면 /goal 장기 목표 추적을 쓸 수 있습니다.',
|
||
goalApplyHint: '스택 재시작 없이 다음 Codex 작업부터 적용됩니다.',
|
||
},
|
||
accounts: {
|
||
claude: 'Claude',
|
||
codex: 'Codex',
|
||
noAccounts: '계정 없음',
|
||
autoRefresh: '토큰 자동갱신',
|
||
codexRefreshHint:
|
||
'OAuth 토큰은 6시간마다 자동 갱신됩니다. plan 변경/해지가 즉시 반영되게 하려면 수동으로 “전체 갱신”을 누르세요.',
|
||
tokenPlaceholder:
|
||
'Claude OAuth 토큰 (claude CLI 로그인 후 ~/.claude/.credentials.json 에서 accessToken 값을 페이스트)',
|
||
deleteConfirm:
|
||
'{provider} 계정 #{index} 디렉터리를 삭제합니다. 되돌릴 수 없습니다. 계속할까요?',
|
||
refreshFailed: '일부 갱신 실패: {indexes}',
|
||
paymentExpired: '결제 만료 {date} ({days}일 전)',
|
||
paymentUntil: '결제 {date}까지 ({days}일)',
|
||
paymentUntilDays: '결제 {date}까지 ({days}일)',
|
||
primaryAccount: '기본 계정',
|
||
activeAccount: '사용 중',
|
||
addTokenLabel: 'OAuth 토큰 추가',
|
||
refreshTitle: '구독 상태를 다시 조회합니다',
|
||
switchTitle: '다음 Codex 호출부터 이 계정을 사용합니다',
|
||
},
|
||
moa: {
|
||
master: 'MoA 사용',
|
||
masterHint:
|
||
'Arbiter 호출 전에 외부 참조 모델 의견을 수집합니다. 저장 후 스택 재시작이 필요합니다.',
|
||
save: 'MoA 저장',
|
||
empty: 'MoA 설정 없음',
|
||
test: '연결 테스트',
|
||
testing: '테스트중…',
|
||
testAfterSave: '저장 후 테스트',
|
||
notTested: '연결 테스트 전',
|
||
statusOk: '정상',
|
||
statusFail: '실패',
|
||
apiKeyPlaceholder: 'new API key',
|
||
apiKeySet: 'API key set',
|
||
modelLabel: '모델 ID',
|
||
baseUrlLabel: 'Base URL',
|
||
formatLabel: 'API 형식',
|
||
},
|
||
runtime: {
|
||
defaultHint:
|
||
'기본값은 모든 스킬이 켜져 있습니다. 여기서 끈 스킬만 해당 방·에이전트에 저장됩니다. 전체(모든 방) 일괄 설정은 아직 없습니다.',
|
||
selectRoomLabel: '방 선택',
|
||
selectAgentLabel: '에이전트',
|
||
scopeCodexUser: 'Codex 스킬',
|
||
scopeClaudeUser: 'Claude 스킬',
|
||
scopeRunner: '공통 러너 스킬',
|
||
emptyRooms: '등록된 Discord 방이 없습니다.',
|
||
emptySkills: '이 방·에이전트에 연결된 스킬이 없습니다.',
|
||
agentCodex: 'Codex',
|
||
agentClaude: 'Claude Code',
|
||
},
|
||
},
|
||
error: {
|
||
api: '문제 발생',
|
||
network: '네트워크 연결 확인 후 다시 시도해주세요.',
|
||
timeout: '응답 시간이 초과됐어요. 잠시 후 다시 시도해주세요.',
|
||
server: '서버에 일시적인 문제가 있어요. 잠시 후 다시 시도해주세요.',
|
||
notFound: '요청한 정보를 찾을 수 없어요.',
|
||
auth: '권한이 없어요. 다시 로그인해주세요.',
|
||
unknown: '알 수 없는 오류가 발생했어요.',
|
||
},
|
||
control: {
|
||
aria: '컨트롤 플레인 요약',
|
||
queue: '작업 큐',
|
||
activeRooms: '처리 + 대기 룸',
|
||
pendingRooms: '메시지 대기 룸',
|
||
},
|
||
pwa: {
|
||
app: 'PWA',
|
||
install: '설치',
|
||
installed: '설치됨',
|
||
ready: '오프라인 준비',
|
||
cached: '캐시됨',
|
||
online: '온라인',
|
||
offline: '오프라인',
|
||
fresh: '최신',
|
||
stale: '지연',
|
||
secureRequired: 'HTTPS 필요',
|
||
updated: '갱신',
|
||
},
|
||
metrics: {
|
||
agents: '에이전트',
|
||
rooms: '룸',
|
||
ciWatchers: 'CI 감시',
|
||
},
|
||
panels: {
|
||
health: '상태',
|
||
heartbeat: '하트비트',
|
||
healthSignals: '운영 신호',
|
||
inbox: 'Inbox',
|
||
inboxQueue: '처리할 액션',
|
||
usage: '사용량',
|
||
usageWindow: '남음 / 속도',
|
||
rooms: '룸',
|
||
queue: '큐',
|
||
scheduled: '예약',
|
||
},
|
||
service: {
|
||
empty: '하트비트 없음. 서비스 로그 확인.',
|
||
heartbeat: '하트비트',
|
||
service: '서비스',
|
||
rooms: '룸',
|
||
updated: '갱신',
|
||
},
|
||
health: {
|
||
system: '시스템',
|
||
signals: '헬스 신호',
|
||
services: '서비스',
|
||
fresh: '정상',
|
||
stale: '지연',
|
||
queue: '큐',
|
||
ciFailures: 'CI 실패',
|
||
affectedServices: '이상 서비스',
|
||
restart: '재시작',
|
||
restartStack: '스택 재시작',
|
||
restarting: '재시작 중...',
|
||
restartHint: '서비스 전체 재시작',
|
||
confirmRestart: 'Restart stack now?',
|
||
restartLog: 'Restart log',
|
||
restartTarget: 'Target',
|
||
restartStatus: 'Status',
|
||
restartRequested: 'Requested',
|
||
restartServices: 'Services',
|
||
levels: {
|
||
ok: '정상',
|
||
stale: '주의',
|
||
down: '중단',
|
||
},
|
||
},
|
||
inbox: {
|
||
empty: '처리할 Inbox 액션 없음.',
|
||
cardsAria: 'Inbox 항목',
|
||
summary: 'Inbox 요약',
|
||
total: '전체',
|
||
filters: 'Inbox 필터',
|
||
all: '전체',
|
||
noSummary: '요약 없음',
|
||
occurred: '발생',
|
||
source: '소스',
|
||
target: '대상',
|
||
openTask: '예약 보기',
|
||
openRoom: '룸 보기',
|
||
kinds: {
|
||
'pending-room': '대기 룸',
|
||
'reviewer-request': '리뷰 요청',
|
||
approval: '승인',
|
||
'arbiter-request': '중재 요청',
|
||
'ci-failure': 'CI 실패',
|
||
mention: '멘션',
|
||
},
|
||
severity: {
|
||
info: '정보',
|
||
warn: '주의',
|
||
error: '위험',
|
||
},
|
||
actions: {
|
||
run: 'Run',
|
||
busy: 'Running...',
|
||
runReview: 'Run review',
|
||
finalize: 'Finalize',
|
||
runArbiter: 'Run arbiter',
|
||
decline: 'Decline',
|
||
dismiss: 'Dismiss',
|
||
confirmDecline: 'Decline this item?',
|
||
},
|
||
},
|
||
rooms: roomMessages.ko,
|
||
usage: {
|
||
empty: '사용량 스냅샷 없음. 수집기 확인.',
|
||
current: '사용중',
|
||
tightest: '가장 적음',
|
||
watch: '주의',
|
||
remaining: '남음',
|
||
speed: '속도',
|
||
inUse: '사용중',
|
||
reset: '리셋',
|
||
noReset: '리셋 없음',
|
||
limitBasis: {
|
||
h5: '5시간 기준',
|
||
d7: '7일 기준',
|
||
},
|
||
quota: {
|
||
h5: '5시간',
|
||
d7: '7일',
|
||
},
|
||
usage: '사용량',
|
||
groupPrimary: 'Claude / Kimi',
|
||
groupCodex: 'Codex',
|
||
risk: {
|
||
ok: '여유',
|
||
warn: '주의',
|
||
critical: '위험',
|
||
},
|
||
speedLabel: {
|
||
ok: '보통',
|
||
warn: '빠름',
|
||
critical: '너무 빠름',
|
||
},
|
||
},
|
||
tasks: {
|
||
empty: '예약 작업 없음.',
|
||
cardsAria: '예약 작업 카드',
|
||
groups: {
|
||
watchers: 'CI 감시',
|
||
scheduled: '예약',
|
||
paused: '일시정지',
|
||
completed: '완료',
|
||
},
|
||
count: '개',
|
||
groupEmpty: '해당 없음',
|
||
task: '작업',
|
||
status: '상태',
|
||
schedule: '스케줄',
|
||
next: '다음',
|
||
last: '최근',
|
||
context: '컨텍스트',
|
||
ciWatch: 'CI 감시',
|
||
emptyPrompt: '(빈 미리보기)',
|
||
prompt: '프롬프트',
|
||
until: '까지',
|
||
suspendedUntil: '정지 해제',
|
||
lastResult: '최근 결과',
|
||
result: '결과 없음',
|
||
resultOk: '정상',
|
||
resultFail: '실패',
|
||
noResult: '결과 없음',
|
||
noTime: '-',
|
||
now: '지금',
|
||
createTitle: '작업 예약',
|
||
createSubtitle: '룸에 반복 작업 걸기',
|
||
filterAll: '전체',
|
||
details: '상세',
|
||
room: '방',
|
||
selectRoom: '방 선택',
|
||
scheduleType: '방식',
|
||
scheduleValue: '시간값',
|
||
scheduleValueHint: 'ISO 시간, 10m 같은 간격, 또는 cron',
|
||
promptPlaceholder: '에이전트가 실행할 작업을 적어주세요.',
|
||
editPromptPlaceholder: '비우면 기존 프롬프트 유지',
|
||
scheduleTypes: {
|
||
once: '한 번',
|
||
interval: '간격',
|
||
cron: '크론',
|
||
},
|
||
contextModes: {
|
||
isolated: '격리',
|
||
group: '방 맥락',
|
||
},
|
||
actions: {
|
||
create: '생성',
|
||
edit: '수정',
|
||
save: '저장',
|
||
pause: '일시정지',
|
||
resume: '재개',
|
||
cancel: '취소',
|
||
busy: '처리 중',
|
||
confirmCancel: '이 예약 작업을 취소할까요?',
|
||
},
|
||
},
|
||
status: {
|
||
processing: '처리중',
|
||
waiting: '대기',
|
||
inactive: '휴면',
|
||
active: '활성',
|
||
paused: '일시정지',
|
||
completed: '완료',
|
||
},
|
||
units: {
|
||
second: '초',
|
||
minute: '분',
|
||
hour: '시간',
|
||
task: '작업',
|
||
messageShort: '메시지',
|
||
chars: '자',
|
||
},
|
||
},
|
||
en: {
|
||
app: {
|
||
loading: 'Loading dashboard',
|
||
},
|
||
actions: {
|
||
close: 'Close',
|
||
refresh: 'Refresh',
|
||
refreshing: 'Refreshing',
|
||
retry: 'Retry',
|
||
},
|
||
nav: {
|
||
aria: 'Dashboard sections',
|
||
drawerAria: 'Dashboard menu',
|
||
drawerNavAria: 'Dashboard menu sections',
|
||
menuOpen: 'Open menu',
|
||
menuClose: 'Close menu',
|
||
operations: 'Ops',
|
||
updated: 'Updated',
|
||
health: 'Health',
|
||
inbox: 'Inbox',
|
||
usage: 'Usage',
|
||
rooms: 'Rooms',
|
||
scheduled: 'Scheduled',
|
||
settings: 'Settings',
|
||
},
|
||
language: {
|
||
label: 'Language',
|
||
},
|
||
settings: {
|
||
title: 'Settings',
|
||
nicknameLabel: 'Nickname',
|
||
nicknamePlaceholder: 'Web Dashboard',
|
||
nicknameHelp: 'Name shown when sending messages from this dashboard',
|
||
languageLabel: 'Language',
|
||
navAria: 'Settings sections',
|
||
contentAria: 'Settings items',
|
||
sidebarAria: 'Settings navigation and apply',
|
||
nav: {
|
||
general: { title: 'General', detail: 'Display · language' },
|
||
models: { title: 'Models', detail: 'owner · reviewer · arbiter' },
|
||
runtime: { title: 'Skills', detail: 'per-room on/off' },
|
||
moa: { title: 'MoA', detail: 'reference models · test' },
|
||
codex: { title: 'Codex', detail: 'fast mode · /goal' },
|
||
accounts: { title: 'Accounts', detail: 'Claude · Codex' },
|
||
},
|
||
apply: {
|
||
aria: 'Apply changes',
|
||
kicker: 'Apply',
|
||
title: 'Restart after save',
|
||
hint: 'Model, MoA, Codex, and account changes apply after a stack restart.',
|
||
restart: 'Restart stack',
|
||
},
|
||
sections: {
|
||
general: {
|
||
kicker: 'Dashboard identity',
|
||
title: 'General',
|
||
description:
|
||
'Only the display name and language change immediately in the browser.',
|
||
},
|
||
models: {
|
||
kicker: 'Agent routing',
|
||
title: 'Models',
|
||
description:
|
||
'Pick a model and inference depth for each role. Restart the stack after saving.',
|
||
},
|
||
runtime: {
|
||
kicker: 'Agent skills',
|
||
title: 'Skills',
|
||
description:
|
||
'Turn skills on or off per room and agent. Default is all on; there is no global bulk setting yet.',
|
||
},
|
||
moa: {
|
||
kicker: 'Arbiter references',
|
||
title: 'MoA reference models',
|
||
description:
|
||
'Enable external reference models like Kimi or GLM and verify connectivity.',
|
||
},
|
||
codex: {
|
||
kicker: 'Codex runtime',
|
||
title: 'Codex options',
|
||
description:
|
||
'Manage fast responses and experimental features. /goal lives here.',
|
||
},
|
||
accounts: {
|
||
kicker: 'Credentials',
|
||
title: 'Accounts',
|
||
description: 'Review and switch Claude OAuth and Codex accounts.',
|
||
},
|
||
},
|
||
common: {
|
||
loading: 'Loading…',
|
||
none: 'None',
|
||
saving: 'Saving…',
|
||
saved: 'Saved',
|
||
savedRestartHint: 'Saved. Use Restart stack in the sidebar to apply.',
|
||
save: 'Save',
|
||
delete: 'Delete',
|
||
refresh: 'Refresh',
|
||
refreshing: 'Refreshing…',
|
||
refreshAll: 'Refresh all',
|
||
switch: 'Switch',
|
||
switching: 'Switching…',
|
||
default: 'Default',
|
||
inUse: 'In use',
|
||
add: 'Add',
|
||
},
|
||
models: {
|
||
roleOwner: 'Owner',
|
||
roleReviewer: 'Reviewer',
|
||
roleArbiter: 'Arbiter',
|
||
roleOwnerHint: 'Runs the main work',
|
||
roleReviewerHint: 'Reviews proposed changes',
|
||
roleArbiterHint: 'Makes the final call',
|
||
modelLabel: 'Model',
|
||
effortLabel: 'Inference depth',
|
||
modelDefault: 'Default (.env)',
|
||
modelCustom: 'Custom…',
|
||
modelCustomLabel: 'Model ID',
|
||
modelPlaceholder: 'e.g. gpt-5.5, claude-opus-4-8',
|
||
groupCodex: 'Codex',
|
||
groupClaude: 'Claude',
|
||
groupCustom: 'Custom',
|
||
effortDefault: 'Default (.env)',
|
||
effortOptions: {
|
||
low: 'Low',
|
||
medium: 'Medium',
|
||
high: 'High',
|
||
xhigh: 'Very high',
|
||
max: 'Max',
|
||
},
|
||
agentTypeLabel: 'Agent',
|
||
agentTypeCodex: 'Codex',
|
||
agentTypeClaude: 'Claude Code',
|
||
effortInvalid:
|
||
'"{value}" is not supported for {agent}. Choose another effort level.',
|
||
effortSaveBlocked:
|
||
'Unsupported effort levels are set. Fix them before saving.',
|
||
save: 'Save models',
|
||
empty: 'No model config',
|
||
},
|
||
codex: {
|
||
fastMode: 'Fast mode',
|
||
features: 'Codex features',
|
||
codexFast: 'Codex (GPT)',
|
||
codexFastHint:
|
||
'~/.codex/config.toml [features].fast_mode — faster responses on GPT 5.5 and newer; higher usage.',
|
||
claudeFast: 'Claude',
|
||
claudeFastHint:
|
||
'~/.claude/settings.json fastMode — synced into session settings.json for Opus 4.8.',
|
||
fastModeApplyHint:
|
||
'Applies on the next Codex/Claude run. No stack restart required.',
|
||
goal: 'Goals (/goal)',
|
||
goalHint:
|
||
'~/.codex/config.toml [features].goals — opt-in on Codex 0.133. Off by default; enables /goal long-running objectives when on.',
|
||
goalApplyHint:
|
||
'Applies on the next Codex run. No stack restart required.',
|
||
},
|
||
accounts: {
|
||
claude: 'Claude',
|
||
codex: 'Codex',
|
||
noAccounts: 'No accounts',
|
||
autoRefresh: 'Auto token refresh',
|
||
codexRefreshHint:
|
||
'OAuth tokens refresh every 6 hours. Use Refresh all for immediate plan changes.',
|
||
tokenPlaceholder:
|
||
'Claude OAuth token (paste accessToken from ~/.claude/.credentials.json after claude CLI login)',
|
||
deleteConfirm:
|
||
'Delete {provider} account #{index} directory. This cannot be undone. Continue?',
|
||
refreshFailed: 'Some refreshes failed: {indexes}',
|
||
paymentExpired: 'Expired {date} ({days}d ago)',
|
||
paymentUntil: 'Paid until {date} ({days}d)',
|
||
paymentUntilDays: 'Paid until {date} ({days}d)',
|
||
primaryAccount: 'Primary',
|
||
activeAccount: 'Active',
|
||
addTokenLabel: 'Add OAuth token',
|
||
refreshTitle: 'Refresh subscription status',
|
||
switchTitle: 'Use this account for the next Codex call',
|
||
},
|
||
moa: {
|
||
master: 'Enable MoA',
|
||
masterHint:
|
||
'Collect external reference opinions before arbiter calls. Stack restart required after save.',
|
||
save: 'Save MoA',
|
||
empty: 'No MoA settings',
|
||
test: 'Test connection',
|
||
testing: 'Testing…',
|
||
testAfterSave: 'Save to test',
|
||
notTested: 'Not tested yet',
|
||
statusOk: 'OK',
|
||
statusFail: 'Failed',
|
||
apiKeyPlaceholder: 'new API key',
|
||
apiKeySet: 'API key set',
|
||
modelLabel: 'Model ID',
|
||
baseUrlLabel: 'Base URL',
|
||
formatLabel: 'API format',
|
||
},
|
||
runtime: {
|
||
defaultHint:
|
||
'All skills start enabled. Only per-room, per-agent disables are saved. Global bulk settings are not available yet.',
|
||
selectRoomLabel: 'Room',
|
||
selectAgentLabel: 'Agent',
|
||
scopeCodexUser: 'Codex skill',
|
||
scopeClaudeUser: 'Claude skill',
|
||
scopeRunner: 'Shared runner skill',
|
||
emptyRooms: 'No registered Discord rooms.',
|
||
emptySkills: 'No skills for this room and agent.',
|
||
agentCodex: 'Codex',
|
||
agentClaude: 'Claude Code',
|
||
},
|
||
},
|
||
error: {
|
||
api: 'Something went wrong',
|
||
network: 'Check your network connection and try again.',
|
||
timeout: 'The request timed out. Try again in a moment.',
|
||
server: 'Server hiccup. Try again in a bit.',
|
||
notFound: "We couldn't find what you asked for.",
|
||
auth: 'Sign in again to continue.',
|
||
unknown: 'An unexpected error occurred.',
|
||
},
|
||
control: {
|
||
aria: 'Control plane summary',
|
||
queue: 'Work queue',
|
||
activeRooms: 'processing + waiting rooms',
|
||
pendingRooms: 'rooms with pending messages',
|
||
},
|
||
pwa: {
|
||
app: 'PWA',
|
||
install: 'Install',
|
||
installed: 'Installed',
|
||
ready: 'Offline ready',
|
||
cached: 'Cached',
|
||
online: 'Online',
|
||
offline: 'Offline',
|
||
fresh: 'Fresh',
|
||
stale: 'Stale',
|
||
secureRequired: 'HTTPS required',
|
||
updated: 'Updated',
|
||
},
|
||
metrics: {
|
||
agents: 'agents',
|
||
rooms: 'rooms',
|
||
ciWatchers: 'CI watchers',
|
||
},
|
||
panels: {
|
||
health: 'Health',
|
||
heartbeat: 'Heartbeat',
|
||
healthSignals: 'Signals',
|
||
inbox: 'Inbox',
|
||
inboxQueue: 'Action queue',
|
||
usage: 'Usage',
|
||
usageWindow: 'Remaining / speed',
|
||
rooms: 'Rooms',
|
||
queue: 'Queue',
|
||
scheduled: 'Scheduled',
|
||
},
|
||
service: {
|
||
empty: 'No heartbeat yet. Check service logs.',
|
||
heartbeat: 'heartbeat',
|
||
service: 'service',
|
||
rooms: 'rooms',
|
||
updated: 'updated',
|
||
},
|
||
health: {
|
||
system: 'System',
|
||
signals: 'Health signals',
|
||
services: 'Services',
|
||
fresh: 'Fresh',
|
||
stale: 'stale',
|
||
queue: 'Queue',
|
||
ciFailures: 'CI failures',
|
||
affectedServices: 'Affected services',
|
||
restart: 'Restart',
|
||
restartStack: 'Restart stack',
|
||
restarting: 'Restarting...',
|
||
restartHint: 'Restart all services',
|
||
confirmRestart: 'Restart stack now?',
|
||
restartLog: 'Restart log',
|
||
restartTarget: 'Target',
|
||
restartStatus: 'Status',
|
||
restartRequested: 'Requested',
|
||
restartServices: 'Services',
|
||
levels: {
|
||
ok: 'OK',
|
||
stale: 'Watch',
|
||
down: 'Down',
|
||
},
|
||
},
|
||
inbox: {
|
||
empty: 'No Inbox actions.',
|
||
cardsAria: 'Inbox items',
|
||
summary: 'Inbox summary',
|
||
total: 'Total',
|
||
filters: 'Inbox filters',
|
||
all: 'All',
|
||
noSummary: 'No summary',
|
||
occurred: 'Occurred',
|
||
source: 'Source',
|
||
target: 'Target',
|
||
openTask: 'Open scheduled',
|
||
openRoom: 'Open room',
|
||
kinds: {
|
||
'pending-room': 'Pending room',
|
||
'reviewer-request': 'Review request',
|
||
approval: 'Approval',
|
||
'arbiter-request': 'Arbiter request',
|
||
'ci-failure': 'CI failure',
|
||
mention: 'Mention',
|
||
},
|
||
severity: {
|
||
info: 'Info',
|
||
warn: 'Warn',
|
||
error: 'Risk',
|
||
},
|
||
actions: {
|
||
run: 'Run',
|
||
busy: 'Running...',
|
||
runReview: 'Run review',
|
||
finalize: 'Finalize',
|
||
runArbiter: 'Run arbiter',
|
||
decline: 'Decline',
|
||
dismiss: 'Dismiss',
|
||
confirmDecline: 'Decline this item?',
|
||
},
|
||
},
|
||
rooms: roomMessages.en,
|
||
usage: {
|
||
empty: 'No usage snapshot. Check collector.',
|
||
current: 'Active',
|
||
tightest: 'Tightest',
|
||
watch: 'Watch',
|
||
remaining: 'Left',
|
||
speed: 'Rate',
|
||
inUse: 'active',
|
||
reset: 'reset',
|
||
noReset: 'no reset',
|
||
limitBasis: {
|
||
h5: '5h basis',
|
||
d7: '7d basis',
|
||
},
|
||
quota: {
|
||
h5: '5h',
|
||
d7: '7d',
|
||
},
|
||
usage: 'usage',
|
||
groupPrimary: 'Claude / Kimi',
|
||
groupCodex: 'Codex',
|
||
risk: {
|
||
ok: 'OK',
|
||
warn: 'Watch',
|
||
critical: 'Risk',
|
||
},
|
||
speedLabel: {
|
||
ok: 'OK',
|
||
warn: 'Fast',
|
||
critical: 'Too fast',
|
||
},
|
||
},
|
||
tasks: {
|
||
empty: 'No scheduled work.',
|
||
cardsAria: 'Scheduled task cards',
|
||
groups: {
|
||
watchers: 'CI watch',
|
||
scheduled: 'Scheduled',
|
||
paused: 'Paused',
|
||
completed: 'Completed',
|
||
},
|
||
count: 'items',
|
||
groupEmpty: 'None',
|
||
task: 'task',
|
||
status: 'status',
|
||
schedule: 'schedule',
|
||
next: 'next',
|
||
last: 'last',
|
||
context: 'context',
|
||
ciWatch: 'CI Watch',
|
||
emptyPrompt: '(empty preview)',
|
||
prompt: 'prompt',
|
||
until: 'until',
|
||
suspendedUntil: 'resume',
|
||
lastResult: 'last result',
|
||
result: 'no result',
|
||
resultOk: 'ok',
|
||
resultFail: 'failed',
|
||
noResult: 'no result',
|
||
noTime: '-',
|
||
now: 'now',
|
||
createTitle: 'Create task',
|
||
createSubtitle: 'Schedule work from web',
|
||
filterAll: 'All',
|
||
details: 'Details',
|
||
room: 'Room',
|
||
selectRoom: 'Select room',
|
||
scheduleType: 'Type',
|
||
scheduleValue: 'Value',
|
||
scheduleValueHint: 'ISO time, ms, or cron',
|
||
promptPlaceholder: 'What should the agent do?',
|
||
editPromptPlaceholder: 'Leave blank to keep prompt',
|
||
scheduleTypes: {
|
||
once: 'Once',
|
||
interval: 'Interval',
|
||
cron: 'Cron',
|
||
},
|
||
contextModes: {
|
||
isolated: 'Isolated',
|
||
group: 'Group',
|
||
},
|
||
actions: {
|
||
create: 'Create',
|
||
edit: 'Edit',
|
||
save: 'Save',
|
||
pause: 'Pause',
|
||
resume: 'Resume',
|
||
cancel: 'Cancel',
|
||
busy: 'Working',
|
||
confirmCancel: 'Cancel this scheduled work?',
|
||
},
|
||
},
|
||
status: {
|
||
processing: 'processing',
|
||
waiting: 'waiting',
|
||
inactive: 'inactive',
|
||
active: 'active',
|
||
paused: 'paused',
|
||
completed: 'completed',
|
||
},
|
||
units: {
|
||
second: 's',
|
||
minute: 'm',
|
||
hour: 'h',
|
||
task: 'task',
|
||
messageShort: 'msg',
|
||
chars: 'chars',
|
||
},
|
||
},
|
||
zh: {
|
||
app: {
|
||
loading: '正在加载仪表盘',
|
||
},
|
||
actions: {
|
||
close: '关闭',
|
||
refresh: '刷新',
|
||
refreshing: '刷新中',
|
||
retry: '重试',
|
||
},
|
||
nav: {
|
||
aria: '仪表盘分区',
|
||
drawerAria: '仪表盘菜单',
|
||
drawerNavAria: '仪表盘菜单分区',
|
||
menuOpen: '打开菜单',
|
||
menuClose: '关闭菜单',
|
||
operations: '运营',
|
||
updated: '更新',
|
||
health: '健康',
|
||
inbox: '收件',
|
||
usage: '用量',
|
||
rooms: '房间',
|
||
scheduled: '计划',
|
||
settings: '设置',
|
||
},
|
||
language: {
|
||
label: '语言',
|
||
},
|
||
settings: {
|
||
title: '设置',
|
||
nicknameLabel: '昵称',
|
||
nicknamePlaceholder: 'Web Dashboard',
|
||
nicknameHelp: '从此面板发送消息时显示的名称',
|
||
languageLabel: '语言',
|
||
navAria: '设置分区',
|
||
contentAria: '设置项',
|
||
sidebarAria: '设置导航与应用',
|
||
nav: {
|
||
general: { title: '常规', detail: '显示 · 语言' },
|
||
models: { title: '模型', detail: 'owner · reviewer · arbiter' },
|
||
runtime: { title: '技能', detail: '按房间开关' },
|
||
moa: { title: 'MoA', detail: '参考模型 · 连接测试' },
|
||
codex: { title: 'Codex', detail: 'fast mode · /goal' },
|
||
accounts: { title: '账户', detail: 'Claude · Codex' },
|
||
},
|
||
apply: {
|
||
aria: '应用更改',
|
||
kicker: 'Apply',
|
||
title: '保存后重启',
|
||
hint: '模型、MoA、Codex、账户更改需在栈重启后生效。',
|
||
restart: '重启栈',
|
||
},
|
||
sections: {
|
||
general: {
|
||
kicker: 'Dashboard identity',
|
||
title: '常规',
|
||
description: '仅浏览器中的显示名称和语言会立即更改。',
|
||
},
|
||
models: {
|
||
kicker: 'Agent routing',
|
||
title: '模型',
|
||
description: '为各角色选择模型和推理强度。保存后需重启栈。',
|
||
},
|
||
runtime: {
|
||
kicker: 'Agent skills',
|
||
title: '技能',
|
||
description: '按房间和代理开关技能。默认全部开启,尚无全局批量设置。',
|
||
},
|
||
moa: {
|
||
kicker: 'Arbiter references',
|
||
title: 'MoA 参考模型',
|
||
description: '启用 Kimi、GLM 等外部参考模型并验证连接。',
|
||
},
|
||
codex: {
|
||
kicker: 'Codex runtime',
|
||
title: 'Codex 选项',
|
||
description: '管理快速响应和实验功能。/goal 在此设置。',
|
||
},
|
||
accounts: {
|
||
kicker: 'Credentials',
|
||
title: '账户',
|
||
description: '查看并切换 Claude OAuth 和 Codex 账户。',
|
||
},
|
||
},
|
||
common: {
|
||
loading: '加载中…',
|
||
none: '无',
|
||
saving: '保存中…',
|
||
saved: '已保存',
|
||
savedRestartHint: '已保存。请在侧边栏点击重启栈以应用。',
|
||
save: '保存',
|
||
delete: '删除',
|
||
refresh: '刷新',
|
||
refreshing: '刷新中…',
|
||
refreshAll: '全部刷新',
|
||
switch: '切换',
|
||
switching: '切换中…',
|
||
default: '默认',
|
||
inUse: '使用中',
|
||
add: '添加',
|
||
},
|
||
models: {
|
||
roleOwner: 'Owner',
|
||
roleReviewer: 'Reviewer',
|
||
roleArbiter: 'Arbiter',
|
||
roleOwnerHint: '执行主要工作的代理',
|
||
roleReviewerHint: '审查变更的代理',
|
||
roleArbiterHint: '做最终裁决的代理',
|
||
modelLabel: '模型',
|
||
effortLabel: '推理强度',
|
||
modelDefault: '默认 (.env)',
|
||
modelCustom: '自定义…',
|
||
modelCustomLabel: '模型 ID',
|
||
modelPlaceholder: '例如 gpt-5.5, claude-opus-4-8',
|
||
groupCodex: 'Codex',
|
||
groupClaude: 'Claude',
|
||
groupCustom: '自定义',
|
||
effortDefault: '默认 (.env)',
|
||
effortOptions: {
|
||
low: '低',
|
||
medium: '中',
|
||
high: '高',
|
||
xhigh: '很高',
|
||
max: '最大',
|
||
},
|
||
agentTypeLabel: '代理',
|
||
agentTypeCodex: 'Codex',
|
||
agentTypeClaude: 'Claude Code',
|
||
effortInvalid: '“{value}” 不适用于 {agent},请选择其他推理强度。',
|
||
effortSaveBlocked: '存在不支持的推理强度,请先修正再保存。',
|
||
save: '保存模型',
|
||
empty: '无模型配置',
|
||
},
|
||
codex: {
|
||
fastMode: '快速模式',
|
||
features: 'Codex 功能',
|
||
codexFast: 'Codex (GPT)',
|
||
codexFastHint:
|
||
'~/.codex/config.toml [features].fast_mode — GPT 5.5 等更快响应,用量更高。',
|
||
claudeFast: 'Claude',
|
||
claudeFastHint:
|
||
'~/.claude/settings.json fastMode — 同步到会话 settings.json,适用于 Opus 4.8。',
|
||
fastModeApplyHint: '无需重启栈,下次 Codex/Claude 任务起生效。',
|
||
goal: 'Goals (/goal)',
|
||
goalHint:
|
||
'~/.codex/config.toml [features].goals — Codex 0.133 可选功能,默认关闭;开启后可使用 /goal。',
|
||
goalApplyHint: '无需重启栈,下次 Codex 任务起生效。',
|
||
},
|
||
accounts: {
|
||
claude: 'Claude',
|
||
codex: 'Codex',
|
||
noAccounts: '无账户',
|
||
autoRefresh: '自动刷新令牌',
|
||
codexRefreshHint:
|
||
'OAuth 令牌每 6 小时自动刷新。计划变更请手动全部刷新。',
|
||
tokenPlaceholder:
|
||
'Claude OAuth 令牌(claude CLI 登录后从 ~/.claude/.credentials.json 粘贴 accessToken)',
|
||
deleteConfirm: '将删除 {provider} 账户 #{index} 目录,无法撤销。继续?',
|
||
refreshFailed: '部分刷新失败: {indexes}',
|
||
paymentExpired: '已过期 {date}({days} 天前)',
|
||
paymentUntil: '付费至 {date}({days} 天)',
|
||
paymentUntilDays: '付费至 {date}({days} 天)',
|
||
primaryAccount: '主账户',
|
||
activeAccount: '使用中',
|
||
addTokenLabel: '添加 OAuth 令牌',
|
||
refreshTitle: '重新查询订阅状态',
|
||
switchTitle: '下次 Codex 调用起使用此账户',
|
||
},
|
||
moa: {
|
||
master: '启用 MoA',
|
||
masterHint: 'Arbiter 调用前收集外部参考意见。保存后需重启栈。',
|
||
save: '保存 MoA',
|
||
empty: '无 MoA 设置',
|
||
test: '连接测试',
|
||
testing: '测试中…',
|
||
testAfterSave: '保存后测试',
|
||
notTested: '尚未测试',
|
||
statusOk: '正常',
|
||
statusFail: '失败',
|
||
apiKeyPlaceholder: 'new API key',
|
||
apiKeySet: 'API key set',
|
||
modelLabel: '模型 ID',
|
||
baseUrlLabel: 'Base URL',
|
||
formatLabel: 'API 格式',
|
||
},
|
||
runtime: {
|
||
defaultHint:
|
||
'默认所有技能开启。仅保存按房间、按代理的关闭项。尚无全局批量设置。',
|
||
selectRoomLabel: '选择房间',
|
||
selectAgentLabel: '代理',
|
||
scopeCodexUser: 'Codex 技能',
|
||
scopeClaudeUser: 'Claude 技能',
|
||
scopeRunner: '共享 runner 技能',
|
||
emptyRooms: '没有已注册的 Discord 房间。',
|
||
emptySkills: '此房间和代理没有可用技能。',
|
||
agentCodex: 'Codex',
|
||
agentClaude: 'Claude Code',
|
||
},
|
||
},
|
||
error: {
|
||
api: '发生问题',
|
||
network: '请检查网络连接后重试。',
|
||
timeout: '请求超时,请稍后重试。',
|
||
server: '服务器暂时出现问题,请稍后重试。',
|
||
notFound: '找不到所请求的信息。',
|
||
auth: '没有权限,请重新登录。',
|
||
unknown: '发生未知错误。',
|
||
},
|
||
control: {
|
||
aria: '控制平面摘要',
|
||
queue: '任务队列',
|
||
activeRooms: '处理中 + 等待房间',
|
||
pendingRooms: '有待处理消息的房间',
|
||
},
|
||
pwa: {
|
||
app: 'PWA',
|
||
install: '安装',
|
||
installed: '已安装',
|
||
ready: '离线可用',
|
||
cached: '已缓存',
|
||
online: '在线',
|
||
offline: '离线',
|
||
fresh: '最新',
|
||
stale: '延迟',
|
||
secureRequired: '需要 HTTPS',
|
||
updated: '更新',
|
||
},
|
||
metrics: {
|
||
agents: '代理',
|
||
rooms: '房间',
|
||
ciWatchers: 'CI 监控',
|
||
},
|
||
panels: {
|
||
health: '健康',
|
||
heartbeat: '心跳',
|
||
healthSignals: '运行信号',
|
||
inbox: '收件',
|
||
inboxQueue: '待处理操作',
|
||
usage: '用量',
|
||
usageWindow: '剩余 / 速度',
|
||
rooms: '房间',
|
||
queue: '队列',
|
||
scheduled: '计划',
|
||
},
|
||
service: {
|
||
empty: '暂无心跳。检查服务日志。',
|
||
heartbeat: '心跳',
|
||
service: '服务',
|
||
rooms: '房间',
|
||
updated: '更新',
|
||
},
|
||
health: {
|
||
system: '系统',
|
||
signals: '健康信号',
|
||
services: '服务',
|
||
fresh: '正常',
|
||
stale: '延迟',
|
||
queue: '队列',
|
||
ciFailures: 'CI 失败',
|
||
affectedServices: '异常服务',
|
||
restart: '重启',
|
||
restartStack: '重启 stack',
|
||
restarting: '重启中...',
|
||
restartHint: '重启全部服务',
|
||
confirmRestart: '现在重启 stack?',
|
||
restartLog: '重启记录',
|
||
restartTarget: '目标',
|
||
restartStatus: '状态',
|
||
restartRequested: '请求',
|
||
restartServices: '服务',
|
||
levels: {
|
||
ok: '正常',
|
||
stale: '关注',
|
||
down: '中断',
|
||
},
|
||
},
|
||
inbox: {
|
||
empty: '暂无待处理收件操作。',
|
||
cardsAria: '收件项',
|
||
summary: '收件摘要',
|
||
total: '全部',
|
||
filters: '收件筛选',
|
||
all: '全部',
|
||
noSummary: '无摘要',
|
||
occurred: '发生',
|
||
source: '来源',
|
||
target: '目标',
|
||
openTask: '查看计划',
|
||
openRoom: '查看房间',
|
||
kinds: {
|
||
'pending-room': '待处理房间',
|
||
'reviewer-request': '评审请求',
|
||
approval: '审批',
|
||
'arbiter-request': '仲裁请求',
|
||
'ci-failure': 'CI 失败',
|
||
mention: '提及',
|
||
},
|
||
severity: {
|
||
info: '信息',
|
||
warn: '关注',
|
||
error: '风险',
|
||
},
|
||
actions: {
|
||
run: '运行',
|
||
busy: '运行中...',
|
||
runReview: '运行评审',
|
||
finalize: '完成',
|
||
runArbiter: '运行仲裁',
|
||
decline: '拒绝',
|
||
dismiss: '忽略',
|
||
confirmDecline: '确认拒绝此项?',
|
||
},
|
||
},
|
||
rooms: roomMessages.zh,
|
||
usage: {
|
||
empty: '暂无用量快照。检查采集器。',
|
||
current: '使用中',
|
||
tightest: '剩余最少',
|
||
watch: '关注',
|
||
remaining: '剩余',
|
||
speed: '速度',
|
||
inUse: '使用中',
|
||
reset: '重置',
|
||
noReset: '无重置',
|
||
limitBasis: {
|
||
h5: '按5小时',
|
||
d7: '按7天',
|
||
},
|
||
quota: {
|
||
h5: '5小时',
|
||
d7: '7天',
|
||
},
|
||
usage: '用量',
|
||
groupPrimary: 'Claude / Kimi',
|
||
groupCodex: 'Codex',
|
||
risk: {
|
||
ok: '充足',
|
||
warn: '关注',
|
||
critical: '接近上限',
|
||
},
|
||
speedLabel: {
|
||
ok: '正常',
|
||
warn: '较快',
|
||
critical: '过快',
|
||
},
|
||
},
|
||
tasks: {
|
||
empty: '暂无计划任务。',
|
||
cardsAria: '计划任务卡片',
|
||
groups: {
|
||
watchers: 'CI 监控',
|
||
scheduled: '计划',
|
||
paused: '暂停',
|
||
completed: '完成',
|
||
},
|
||
count: '项',
|
||
groupEmpty: '无',
|
||
task: '任务',
|
||
status: '状态',
|
||
schedule: '计划',
|
||
next: '下次',
|
||
last: '最近',
|
||
context: '上下文',
|
||
ciWatch: 'CI 监控',
|
||
emptyPrompt: '(空预览)',
|
||
prompt: '提示',
|
||
until: '直到',
|
||
suspendedUntil: '恢复',
|
||
lastResult: '最近结果',
|
||
result: '无结果',
|
||
resultOk: '正常',
|
||
resultFail: '失败',
|
||
noResult: '无结果',
|
||
noTime: '-',
|
||
now: '现在',
|
||
createTitle: 'Create task',
|
||
createSubtitle: 'Schedule work from web',
|
||
filterAll: 'All',
|
||
details: 'Details',
|
||
room: 'Room',
|
||
selectRoom: 'Select room',
|
||
scheduleType: 'Type',
|
||
scheduleValue: 'Value',
|
||
scheduleValueHint: 'ISO time, ms, or cron',
|
||
promptPlaceholder: 'What should the agent do?',
|
||
editPromptPlaceholder: 'Leave blank to keep prompt',
|
||
scheduleTypes: {
|
||
once: 'Once',
|
||
interval: 'Interval',
|
||
cron: 'Cron',
|
||
},
|
||
contextModes: {
|
||
isolated: 'Isolated',
|
||
group: 'Group',
|
||
},
|
||
actions: {
|
||
create: 'Create',
|
||
edit: 'Edit',
|
||
save: 'Save',
|
||
pause: 'Pause',
|
||
resume: 'Resume',
|
||
cancel: 'Cancel',
|
||
busy: 'Working',
|
||
confirmCancel: 'Cancel this scheduled work?',
|
||
},
|
||
},
|
||
status: {
|
||
processing: '处理中',
|
||
waiting: '等待',
|
||
inactive: '空闲',
|
||
active: '活跃',
|
||
paused: '暂停',
|
||
completed: '完成',
|
||
},
|
||
units: {
|
||
second: '秒',
|
||
minute: '分',
|
||
hour: '小时',
|
||
task: '任务',
|
||
messageShort: '消息',
|
||
chars: '字',
|
||
},
|
||
},
|
||
ja: {
|
||
app: {
|
||
loading: 'ダッシュボードを読み込み中',
|
||
},
|
||
actions: {
|
||
close: '閉じる',
|
||
refresh: '更新',
|
||
refreshing: '更新中',
|
||
retry: '再試行',
|
||
},
|
||
nav: {
|
||
aria: 'ダッシュボードセクション',
|
||
drawerAria: 'ダッシュボードメニュー',
|
||
drawerNavAria: 'ダッシュボードメニューセクション',
|
||
menuOpen: 'メニューを開く',
|
||
menuClose: 'メニューを閉じる',
|
||
operations: '運用',
|
||
updated: '更新',
|
||
health: '状態',
|
||
inbox: '受信',
|
||
usage: '使用量',
|
||
rooms: 'ルーム',
|
||
scheduled: '予定',
|
||
settings: '設定',
|
||
},
|
||
language: {
|
||
label: '言語',
|
||
},
|
||
settings: {
|
||
title: '設定',
|
||
nicknameLabel: 'ニックネーム',
|
||
nicknamePlaceholder: 'Web Dashboard',
|
||
nicknameHelp: 'このダッシュボードからメッセージを送る時に表示される名前',
|
||
languageLabel: '言語',
|
||
navAria: '設定セクション',
|
||
contentAria: '設定項目',
|
||
sidebarAria: '設定ナビと適用',
|
||
nav: {
|
||
general: { title: '一般', detail: '表示 · 言語' },
|
||
models: { title: 'モデル', detail: 'owner · reviewer · arbiter' },
|
||
runtime: { title: 'スキル', detail: 'ルーム別 ON/OFF' },
|
||
moa: { title: 'MoA', detail: '参照モデル · 接続テスト' },
|
||
codex: { title: 'Codex', detail: 'fast mode · /goal' },
|
||
accounts: { title: 'アカウント', detail: 'Claude · Codex' },
|
||
},
|
||
apply: {
|
||
aria: '変更を適用',
|
||
kicker: 'Apply',
|
||
title: '保存後に再起動',
|
||
hint: 'モデル、MoA、Codex、アカウントの変更はスタック再起動後に反映されます。',
|
||
restart: 'スタック再起動',
|
||
},
|
||
sections: {
|
||
general: {
|
||
kicker: 'Dashboard identity',
|
||
title: '一般',
|
||
description: 'ブラウザ上の表示名と言語だけがすぐに変わります。',
|
||
},
|
||
models: {
|
||
kicker: 'Agent routing',
|
||
title: 'モデル',
|
||
description:
|
||
'役割ごとにモデルと推論強度を選びます。保存後にスタック再起動が必要です。',
|
||
},
|
||
runtime: {
|
||
kicker: 'Agent skills',
|
||
title: 'スキル',
|
||
description:
|
||
'ルームとエージェントごとにスキルを ON/OFF します。デフォルトはすべて ON で、全体一括設定はまだありません。',
|
||
},
|
||
moa: {
|
||
kicker: 'Arbiter references',
|
||
title: 'MoA 参照モデル',
|
||
description:
|
||
'Kimi や GLM などの外部参照モデルを有効化し接続を確認します。',
|
||
},
|
||
codex: {
|
||
kicker: 'Codex runtime',
|
||
title: 'Codex オプション',
|
||
description:
|
||
'高速応答と実験機能を管理します。/goal はここにあります。',
|
||
},
|
||
accounts: {
|
||
kicker: 'Credentials',
|
||
title: 'アカウント',
|
||
description: 'Claude OAuth と Codex アカウントの状態確認と切り替え。',
|
||
},
|
||
},
|
||
common: {
|
||
loading: '読み込み中…',
|
||
none: 'なし',
|
||
saving: '保存中…',
|
||
saved: '保存済み',
|
||
savedRestartHint:
|
||
'保存済み。サイドバーのスタック再起動で適用してください。',
|
||
save: '保存',
|
||
delete: '削除',
|
||
refresh: '更新',
|
||
refreshing: '更新中…',
|
||
refreshAll: '一括更新',
|
||
switch: '切替',
|
||
switching: '切替中…',
|
||
default: 'デフォルト',
|
||
inUse: '使用中',
|
||
add: '追加',
|
||
},
|
||
models: {
|
||
roleOwner: 'Owner',
|
||
roleReviewer: 'Reviewer',
|
||
roleArbiter: 'Arbiter',
|
||
roleOwnerHint: '作業を実行するエージェント',
|
||
roleReviewerHint: '変更をレビューするエージェント',
|
||
roleArbiterHint: '最終判断を下すエージェント',
|
||
modelLabel: 'モデル',
|
||
effortLabel: '推論強度',
|
||
modelDefault: 'デフォルト (.env)',
|
||
modelCustom: 'カスタム…',
|
||
modelCustomLabel: 'モデル ID',
|
||
modelPlaceholder: '例: gpt-5.5, claude-opus-4-8',
|
||
groupCodex: 'Codex',
|
||
groupClaude: 'Claude',
|
||
groupCustom: 'カスタム',
|
||
effortDefault: 'デフォルト (.env)',
|
||
effortOptions: {
|
||
low: '低',
|
||
medium: '中',
|
||
high: '高',
|
||
xhigh: '最高',
|
||
max: '最大',
|
||
},
|
||
agentTypeLabel: 'エージェント',
|
||
agentTypeCodex: 'Codex',
|
||
agentTypeClaude: 'Claude Code',
|
||
effortInvalid:
|
||
'「{value}」は {agent} では使えない推論強度です。別の値を選んでください。',
|
||
effortSaveBlocked:
|
||
'サポート外の推論強度があります。保存前に修正してください。',
|
||
save: 'モデル保存',
|
||
empty: 'モデル情報なし',
|
||
},
|
||
codex: {
|
||
fastMode: 'ファストモード',
|
||
features: 'Codex 機能',
|
||
codexFast: 'Codex (GPT)',
|
||
codexFastHint:
|
||
'~/.codex/config.toml [features].fast_mode — GPT 5.5 などで応答を高速化。使用量は増えます。',
|
||
claudeFast: 'Claude',
|
||
claudeFastHint:
|
||
'~/.claude/settings.json fastMode — セッション settings.json に同期。Opus 4.8 向け。',
|
||
fastModeApplyHint:
|
||
'スタック再起動不要。次の Codex/Claude 実行から反映されます。',
|
||
goal: 'Goals (/goal)',
|
||
goalHint:
|
||
'~/.codex/config.toml [features].goals — Codex 0.133 の opt-in 機能。デフォルト OFF。ON で /goal を利用。',
|
||
goalApplyHint: 'スタック再起動不要。次の Codex 実行から反映されます。',
|
||
},
|
||
accounts: {
|
||
claude: 'Claude',
|
||
codex: 'Codex',
|
||
noAccounts: 'アカウントなし',
|
||
autoRefresh: 'トークン自動更新',
|
||
codexRefreshHint:
|
||
'OAuth トークンは 6 時間ごとに自動更新されます。プラン変更は「一括更新」を押してください。',
|
||
tokenPlaceholder:
|
||
'Claude OAuth トークン(claude CLI ログイン後 ~/.claude/.credentials.json の accessToken を貼り付け)',
|
||
deleteConfirm:
|
||
'{provider} アカウント #{index} ディレクトリを削除します。元に戻せません。続行しますか?',
|
||
refreshFailed: '一部の更新に失敗: {indexes}',
|
||
paymentExpired: '期限切れ {date}({days} 日前)',
|
||
paymentUntil: '支払い {date} まで({days} 日)',
|
||
paymentUntilDays: '支払い {date} まで({days} 日)',
|
||
primaryAccount: 'プライマリ',
|
||
activeAccount: '使用中',
|
||
addTokenLabel: 'OAuth トークン追加',
|
||
refreshTitle: 'サブスクリプション状態を再取得',
|
||
switchTitle: '次回 Codex 呼び出しからこのアカウントを使用',
|
||
},
|
||
moa: {
|
||
master: 'MoA を使用',
|
||
masterHint:
|
||
'Arbiter 呼び出し前に外部参照モデルの意見を集めます。保存後にスタック再起動が必要です。',
|
||
save: 'MoA 保存',
|
||
empty: 'MoA 設定なし',
|
||
test: '接続テスト',
|
||
testing: 'テスト中…',
|
||
testAfterSave: '保存後にテスト',
|
||
notTested: '未テスト',
|
||
statusOk: '正常',
|
||
statusFail: '失敗',
|
||
apiKeyPlaceholder: 'new API key',
|
||
apiKeySet: 'API key set',
|
||
modelLabel: 'モデル ID',
|
||
baseUrlLabel: 'Base URL',
|
||
formatLabel: 'API 形式',
|
||
},
|
||
runtime: {
|
||
defaultHint:
|
||
'デフォルトですべてのスキルは ON です。ルーム・エージェント単位の OFF のみ保存されます。全体一括設定はまだありません。',
|
||
selectRoomLabel: 'ルーム',
|
||
selectAgentLabel: 'エージェント',
|
||
scopeCodexUser: 'Codex スキル',
|
||
scopeClaudeUser: 'Claude スキル',
|
||
scopeRunner: '共通 runner スキル',
|
||
emptyRooms: '登録済み Discord ルームがありません。',
|
||
emptySkills: 'このルームとエージェントに利用可能なスキルがありません。',
|
||
agentCodex: 'Codex',
|
||
agentClaude: 'Claude Code',
|
||
},
|
||
},
|
||
error: {
|
||
api: '問題が発生しました',
|
||
network: 'ネットワーク接続を確認してから再試行してください。',
|
||
timeout:
|
||
'リクエストがタイムアウトしました。少し経ってから再試行してください。',
|
||
server:
|
||
'サーバーに一時的な問題があります。少し経ってから再試行してください。',
|
||
notFound: 'お探しの情報が見つかりませんでした。',
|
||
auth: '権限がありません。再ログインしてください。',
|
||
unknown: '不明なエラーが発生しました。',
|
||
},
|
||
control: {
|
||
aria: 'コントロールプレーン概要',
|
||
queue: '作業キュー',
|
||
activeRooms: '処理中 + 待機ルーム',
|
||
pendingRooms: 'メッセージ待ちルーム',
|
||
},
|
||
pwa: {
|
||
app: 'PWA',
|
||
install: 'インストール',
|
||
installed: 'インストール済み',
|
||
ready: 'オフライン可',
|
||
cached: 'キャッシュ済み',
|
||
online: 'オンライン',
|
||
offline: 'オフライン',
|
||
fresh: '最新',
|
||
stale: '遅延',
|
||
secureRequired: 'HTTPS 必須',
|
||
updated: '更新',
|
||
},
|
||
metrics: {
|
||
agents: 'エージェント',
|
||
rooms: 'ルーム',
|
||
ciWatchers: 'CI監視',
|
||
},
|
||
panels: {
|
||
health: '状態',
|
||
heartbeat: 'ハートビート',
|
||
healthSignals: '運用シグナル',
|
||
inbox: '受信',
|
||
inboxQueue: '対応アクション',
|
||
usage: '使用量',
|
||
usageWindow: '残量 / 速度',
|
||
rooms: 'ルーム',
|
||
queue: 'キュー',
|
||
scheduled: '予定',
|
||
},
|
||
service: {
|
||
empty: 'ハートビートなし。サービスログを確認。',
|
||
heartbeat: 'ハートビート',
|
||
service: 'サービス',
|
||
rooms: 'ルーム',
|
||
updated: '更新',
|
||
},
|
||
health: {
|
||
system: 'システム',
|
||
signals: '状態シグナル',
|
||
services: 'サービス',
|
||
fresh: '正常',
|
||
stale: '遅延',
|
||
queue: 'キュー',
|
||
ciFailures: 'CI失敗',
|
||
affectedServices: '異常サービス',
|
||
restart: '再起動',
|
||
restartStack: 'Stack再起動',
|
||
restarting: '再起動中...',
|
||
restartHint: '全サービス再起動',
|
||
confirmRestart: 'Stackを再起動しますか?',
|
||
restartLog: '再起動ログ',
|
||
restartTarget: '対象',
|
||
restartStatus: '状態',
|
||
restartRequested: '要求',
|
||
restartServices: 'サービス',
|
||
levels: {
|
||
ok: '正常',
|
||
stale: '注意',
|
||
down: '停止',
|
||
},
|
||
},
|
||
inbox: {
|
||
empty: '対応する受信アクションはありません。',
|
||
cardsAria: '受信項目',
|
||
summary: '受信サマリー',
|
||
total: '全体',
|
||
filters: '受信フィルター',
|
||
all: '全体',
|
||
noSummary: '概要なし',
|
||
occurred: '発生',
|
||
source: 'ソース',
|
||
target: '対象',
|
||
openTask: '予定を見る',
|
||
openRoom: 'ルームを見る',
|
||
kinds: {
|
||
'pending-room': '待機ルーム',
|
||
'reviewer-request': 'レビュー依頼',
|
||
approval: '承認',
|
||
'arbiter-request': '仲裁依頼',
|
||
'ci-failure': 'CI失敗',
|
||
mention: 'メンション',
|
||
},
|
||
severity: {
|
||
info: '情報',
|
||
warn: '注意',
|
||
error: '危険',
|
||
},
|
||
actions: {
|
||
run: '実行',
|
||
busy: '実行中...',
|
||
runReview: 'レビュー実行',
|
||
finalize: 'Finalize',
|
||
runArbiter: '仲裁実行',
|
||
decline: '拒否',
|
||
dismiss: '非表示',
|
||
confirmDecline: 'この項目を拒否しますか?',
|
||
},
|
||
},
|
||
rooms: roomMessages.ja,
|
||
usage: {
|
||
empty: '使用量スナップショットなし。収集器を確認。',
|
||
current: '使用中',
|
||
tightest: '残量最少',
|
||
watch: '注意',
|
||
remaining: '残量',
|
||
speed: '速度',
|
||
inUse: '使用中',
|
||
reset: 'リセット',
|
||
noReset: 'リセットなし',
|
||
limitBasis: {
|
||
h5: '5時間基準',
|
||
d7: '7日基準',
|
||
},
|
||
quota: {
|
||
h5: '5時間',
|
||
d7: '7日',
|
||
},
|
||
usage: '使用量',
|
||
groupPrimary: 'Claude / Kimi',
|
||
groupCodex: 'Codex',
|
||
risk: {
|
||
ok: '余裕',
|
||
warn: '注意',
|
||
critical: '上限注意',
|
||
},
|
||
speedLabel: {
|
||
ok: '通常',
|
||
warn: '速い',
|
||
critical: '速すぎ',
|
||
},
|
||
},
|
||
tasks: {
|
||
empty: '予定作業なし。',
|
||
cardsAria: '予定作業カード',
|
||
groups: {
|
||
watchers: 'CI監視',
|
||
scheduled: '予定',
|
||
paused: '一時停止',
|
||
completed: '完了',
|
||
},
|
||
count: '件',
|
||
groupEmpty: 'なし',
|
||
task: '作業',
|
||
status: '状態',
|
||
schedule: '予定',
|
||
next: '次回',
|
||
last: '直近',
|
||
context: 'コンテキスト',
|
||
ciWatch: 'CI監視',
|
||
emptyPrompt: '(空のプレビュー)',
|
||
prompt: 'プロンプト',
|
||
until: 'まで',
|
||
suspendedUntil: '再開',
|
||
lastResult: '直近結果',
|
||
result: '結果なし',
|
||
resultOk: '正常',
|
||
resultFail: '失敗',
|
||
noResult: '結果なし',
|
||
noTime: '-',
|
||
now: '今',
|
||
createTitle: 'Create task',
|
||
createSubtitle: 'Schedule work from web',
|
||
filterAll: 'All',
|
||
details: 'Details',
|
||
room: 'Room',
|
||
selectRoom: 'Select room',
|
||
scheduleType: 'Type',
|
||
scheduleValue: 'Value',
|
||
scheduleValueHint: 'ISO time, ms, or cron',
|
||
promptPlaceholder: 'What should the agent do?',
|
||
editPromptPlaceholder: 'Leave blank to keep prompt',
|
||
scheduleTypes: {
|
||
once: 'Once',
|
||
interval: 'Interval',
|
||
cron: 'Cron',
|
||
},
|
||
contextModes: {
|
||
isolated: 'Isolated',
|
||
group: 'Group',
|
||
},
|
||
actions: {
|
||
create: 'Create',
|
||
edit: 'Edit',
|
||
save: 'Save',
|
||
pause: 'Pause',
|
||
resume: 'Resume',
|
||
cancel: 'Cancel',
|
||
busy: 'Working',
|
||
confirmCancel: 'Cancel this scheduled work?',
|
||
},
|
||
},
|
||
status: {
|
||
processing: '処理中',
|
||
waiting: '待機',
|
||
inactive: '休止',
|
||
active: '有効',
|
||
paused: '一時停止',
|
||
completed: '完了',
|
||
},
|
||
units: {
|
||
second: '秒',
|
||
minute: '分',
|
||
hour: '時間',
|
||
task: '作業',
|
||
messageShort: 'メッセージ',
|
||
chars: '字',
|
||
},
|
||
},
|
||
} satisfies Record<Locale, Messages>;
|
||
|
||
export function isLocale(value: string | null | undefined): value is Locale {
|
||
return LOCALES.includes(value as Locale);
|
||
}
|
||
|
||
export function matchLocale(value: string | null | undefined): Locale | null {
|
||
if (!value) return null;
|
||
const normalized = value.toLowerCase();
|
||
if (normalized.startsWith('ko')) return 'ko';
|
||
if (normalized.startsWith('en')) return 'en';
|
||
if (normalized.startsWith('zh')) return 'zh';
|
||
if (normalized.startsWith('ja')) return 'ja';
|
||
return null;
|
||
}
|