Files
EJClaw/apps/dashboard/src/i18n.ts
2026-05-29 03:56:19 +09:00

2156 lines
64 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}