@aiwayds/dsh-tui-pi 2.18.2 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +12 -43
  2. package/README.zh-CN.md +11 -42
  3. package/lib/agents.js +67 -52
  4. package/lib/agents.js.map +1 -1
  5. package/lib/ask-user.d.ts +122 -3
  6. package/lib/ask-user.js +335 -41
  7. package/lib/ask-user.js.map +1 -1
  8. package/lib/attachments.js +8 -3
  9. package/lib/attachments.js.map +1 -1
  10. package/lib/btw.d.ts +4 -2
  11. package/lib/btw.js +22 -16
  12. package/lib/btw.js.map +1 -1
  13. package/lib/custom-provider.js +34 -28
  14. package/lib/custom-provider.js.map +1 -1
  15. package/lib/footer.d.ts +9 -8
  16. package/lib/footer.js +36 -18
  17. package/lib/footer.js.map +1 -1
  18. package/lib/hard-exit.d.ts +36 -0
  19. package/lib/hard-exit.js +64 -0
  20. package/lib/hard-exit.js.map +1 -0
  21. package/lib/history-fork.d.ts +2 -2
  22. package/lib/history-fork.js +12 -9
  23. package/lib/history-fork.js.map +1 -1
  24. package/lib/history-turns.d.ts +4 -2
  25. package/lib/history-turns.js +7 -3
  26. package/lib/history-turns.js.map +1 -1
  27. package/lib/history.js +57 -45
  28. package/lib/history.js.map +1 -1
  29. package/lib/hotkeys.js +44 -33
  30. package/lib/hotkeys.js.map +1 -1
  31. package/lib/i18n/index.d.ts +54 -0
  32. package/lib/i18n/index.js +98 -0
  33. package/lib/i18n/index.js.map +1 -0
  34. package/lib/i18n/registry.d.ts +65 -0
  35. package/lib/i18n/registry.js +129 -0
  36. package/lib/i18n/registry.js.map +1 -0
  37. package/lib/index.js +219 -109
  38. package/lib/index.js.map +1 -1
  39. package/lib/language-ask.d.ts +98 -0
  40. package/lib/language-ask.js +118 -0
  41. package/lib/language-ask.js.map +1 -0
  42. package/lib/live-widgets.js +9 -8
  43. package/lib/live-widgets.js.map +1 -1
  44. package/lib/login.js +5 -4
  45. package/lib/login.js.map +1 -1
  46. package/lib/messages.d.ts +0 -4
  47. package/lib/messages.js +14 -15
  48. package/lib/messages.js.map +1 -1
  49. package/lib/model-profiles.js +32 -20
  50. package/lib/model-profiles.js.map +1 -1
  51. package/lib/panels.js +18 -17
  52. package/lib/panels.js.map +1 -1
  53. package/lib/preflight-projcache.js +9 -3
  54. package/lib/preflight-projcache.js.map +1 -1
  55. package/lib/preset-dialog.d.ts +3 -3
  56. package/lib/preset-dialog.js +20 -17
  57. package/lib/preset-dialog.js.map +1 -1
  58. package/lib/provider-catalog.d.ts +23 -7
  59. package/lib/provider-catalog.js +90 -68
  60. package/lib/provider-catalog.js.map +1 -1
  61. package/lib/queue-panel.d.ts +2 -2
  62. package/lib/queue-panel.js +13 -9
  63. package/lib/queue-panel.js.map +1 -1
  64. package/lib/repair-dialog.d.ts +4 -4
  65. package/lib/repair-dialog.js +23 -16
  66. package/lib/repair-dialog.js.map +1 -1
  67. package/lib/route-dialog.d.ts +3 -3
  68. package/lib/route-dialog.js +20 -14
  69. package/lib/route-dialog.js.map +1 -1
  70. package/lib/selectors.d.ts +15 -1
  71. package/lib/selectors.js +57 -23
  72. package/lib/selectors.js.map +1 -1
  73. package/lib/sessions.d.ts +47 -14
  74. package/lib/sessions.js +162 -53
  75. package/lib/sessions.js.map +1 -1
  76. package/lib/settings.d.ts +68 -9
  77. package/lib/settings.js +327 -78
  78. package/lib/settings.js.map +1 -1
  79. package/lib/skills-manager.js +27 -21
  80. package/lib/skills-manager.js.map +1 -1
  81. package/lib/skills.js +5 -4
  82. package/lib/skills.js.map +1 -1
  83. package/lib/startup-info.js +9 -3
  84. package/lib/startup-info.js.map +1 -1
  85. package/lib/steer-flow.d.ts +14 -4
  86. package/lib/steer-flow.js +24 -9
  87. package/lib/steer-flow.js.map +1 -1
  88. package/lib/stop-dialog.d.ts +2 -2
  89. package/lib/stop-dialog.js +16 -12
  90. package/lib/stop-dialog.js.map +1 -1
  91. package/lib/subagent-viewer.d.ts +3 -8
  92. package/lib/subagent-viewer.js +38 -62
  93. package/lib/subagent-viewer.js.map +1 -1
  94. package/lib/theme-preview.js +12 -11
  95. package/lib/theme-preview.js.map +1 -1
  96. package/lib/theme-settings.d.ts +44 -2
  97. package/lib/theme-settings.js +97 -54
  98. package/lib/theme-settings.js.map +1 -1
  99. package/lib/tui.js +2 -1
  100. package/lib/tui.js.map +1 -1
  101. package/locales/en.json +646 -0
  102. package/locales/ja.json +646 -0
  103. package/locales/ko.json +646 -0
  104. package/locales/zh-CN.json +646 -0
  105. package/package.json +2 -1
  106. package/skills/dsh-tui-pi-config/SKILL.md +14 -4
@@ -0,0 +1,646 @@
1
+ {
2
+ "name": "한국어",
3
+ "command.language.description": "UI 언어를 전환합니다 (/language 는 선택을 묻고, /language <코드> 는 직접 전환)",
4
+ "command.language.unknown": "알 수 없는 언어 \"{id}\"입니다. 설치된 언어: {list}",
5
+ "command.language.switched": "이제 {name} ({id}) 언어를 사용합니다. 다음 화면 갱신부터 적용되며, 대화 기록 백로그는 다시 구성될 때까지 이전 언어를 유지합니다.",
6
+ "command.language.persistFailed": "이 세션에서는 전환되었지만 환경설정 저장에 실패했습니다: {error}",
7
+ "command.language.unchanged": "언어가 변경되지 않았습니다.",
8
+ "command.language.unavailable": "언어를 선택할 ask-user 응답자가 없습니다. 설치됨: {list} — /language <코드> 를 사용하세요.",
9
+ "command.language.askFailed": "언어 선택을 요청할 수 없습니다: {error}",
10
+ "settings.language.description": "UI 언어: 내장 locales/ 디렉터리 또는 ~/.dsh/locales의 로캘 id (예: 'en', 'zh-CN'); 알 수 없는 id는 'en'으로 폴백합니다. 다음 화면 갱신 시 적용 — /language 명령은 즉시 전환합니다",
11
+ "settings.theme.description": "터미널 색 구성표 ('auto'는 터미널 따름, 'light'/'dark'는 GitHub 팔레트, 그 외 값은 등록된 커스텀 테마 이름)",
12
+ "settings.panelHeight.description": "생각/도구 패널 높이 ('1' = 한 행: 식별자 + 경과 시간 + 마지막 줄, 오른쪽 잘림; '5'/'7'/'10' = 박스형 헤더 + 내용 행, 테두리가 2행 더 차지; 'all' = 전체 내용 — 스트리밍 추론은 실시간 200행 꼬리 표시, 도구 결과는 2000행 제한)",
13
+ "settings.maxAgents.description": "동시 실행 가능한 서브에이전트 최대 수 (0 = 무제한)",
14
+ "settings.maxRounds.description": "TUI가 마무리 요청을 보내기 전까지 서브에이전트당 허용되는 어시스턴트 메시지 최대 라운드 수 (0 = 무제한)",
15
+ "settings.maxRoundsGrace.description": "마무리 요청 후에도 서브에이전트가 계속 실행될 수 있는 라운드 수, 초과하면 TUI가 강제 중지시킵니다 (0 = 경고만, 강제 중지 안 함)",
16
+ "settings.disableSubagent.description": "네이티브 subagent 도구를 비활성화합니다 (위임은 use_agent를 통해 등록된 에이전트 ~/.dsh/agents/*.md로 진행); subagent_fork/workflow/ralph는 계속 사용 가능",
17
+ "settings.registeredOnly.description": "use_agent를 제외한 모든 spawn 도구를 차단합니다: 위임은 등록된 에이전트 정의(~/.dsh/agents/*.md)가 뒷받침하는 서브에이전트만 생성할 수 있으며, 즉석 경로(subagent, subagent_fork, workflow, ralph)는 가드에서 거부됩니다",
18
+ "settings.footerHints.description": "표시할 푸터 단축키 힌트 (각 항목 on/off)",
19
+ "settings.footerHints.send.description": "푸터 힌트 바에 \"Enter: 전송\" 표시",
20
+ "settings.footerHints.stop.description": "푸터 힌트 바에 \"Esc ×2: 중지\" 표시",
21
+ "settings.footerHints.quit.description": "푸터 힌트 바에 \"Ctrl+C ×2: 종료\" 표시",
22
+ "settings.footerHints.quitEmpty.description": "푸터 힌트 바에 \"Ctrl+D: 종료 (빈 입력)\" 표시",
23
+ "settings.footerHints.subagents.description": "푸터 힌트 바에 \"Ctrl+G: 서브에이전트\" 표시",
24
+ "settings.footerHints.search.description": "푸터 힌트 바에 \"Ctrl+Shift+F: 검색\" 표시",
25
+ "settings.footerHints.history.description": "푸터 힌트 바에 \"↑↓: 기록\" 표시",
26
+ "settings.cacheHitMode.description": "푸터 CH 세그먼트의 범위: 'lastMessage' = 최근 어시스턴트 메시지의 히트율 (pi-tui 푸터와 동일); 'session' = 세션 전체 입력 트래픽의 누적 히트율. 다음 푸터 갱신 때 적용됩니다",
27
+ "settings.iconSet.description": "위험한 글리프의 아이콘 세트 ('auto' = 시작 시 Nerd Font가 감지되면 nerdfont, 아니면 plain; 'nerdfont' = powerline PUA 글리프 (U+E0B0 구분자, 정지, 굵은 원); plain = 안전한 Unicode 대체 (▸ ■ ●) — auto가 권장 기본값)",
28
+ "settings.rememberPreset.description": "워크스페이스별로 마지막 /preset 선택을 기억하여, 다음에 같은 디렉터리에서 시작할 때 그 프리셋으로 시작합니다 (서버 기본값 대신). false이면 항상 서버 측 기본 프리셋으로 시작합니다",
29
+ "settings.favoriteModels.description": "즐겨찾기 모델 (provider/id 키) — /model 선택기 상단에 고정됩니다",
30
+ "settings.hiddenModels.description": "숨긴 모델 (provider/id 키) — /model 선택기의 숨김 섹션으로 이동됩니다",
31
+ "settings.retention.description": "시작 시 ~/.dsh/sessions 세션 로그를 정리합니다 (여기에 명시한 값이 DSH_TUI_RETENTION_* 환경 변수보다 우선)",
32
+ "settings.retention.maxCount.description": "세션 로그 보존: 최대 이 수만큼 세션을 유지합니다 (<= 0이면 정리기를 끕니다); DSH_TUI_RETENTION_MAX_COUNT보다 우선; 다음 시작 시 적용",
33
+ "settings.retention.maxAgeDays.description": "세션 로그 보존: 이 일수보다 오래 손대지 않은 로그를 삭제합니다 (> 0); DSH_TUI_RETENTION_MAX_AGE_DAYS보다 우선; 다음 시작 시 적용",
34
+ "settings.retention.minIdleHours.description": "세션 로그 보존: 개수 규칙 전용 유휴 보호, 시간 단위 (>= 0); DSH_TUI_RETENTION_MIN_IDLE_HOURS보다 우선; 다음 시작 시 적용",
35
+ "settings.resume.description": "재개 선택기의 표시 필터 (여기에 명시한 값이 DSH_TUI_RESUME_* 환경 변수보다 우선)",
36
+ "settings.resume.maxAgeDays.description": "재개 선택기: 로그 활동이 이 기간 안에 있는 세션만 한 줄로 표시됩니다 (> 0); DSH_TUI_RESUME_MAX_AGE_DAYS보다 우선",
37
+ "settings.resume.minBytes.description": "재개 선택기: 한 줄이 되기 위한 최소 압축 로그 크기 (>= 0); DSH_TUI_RESUME_MIN_BYTES보다 우선",
38
+ "settings.askUser.description": "Ask User 질문 패널의 타임아웃 (여기에 명시한 값이 DSH_TUI_ASK_USER_* 환경 변수보다 우선)",
39
+ "settings.askUser.idleMinutes.description": "Ask User 패널: 포커스된 질문에 이 분 동안 아무 키도 누르지 않으면 자동으로 답변합니다 — 답변 없는 질문은 추천 옵션(목록의 첫 항목)을 선택하며, 플랜은 절대 자동 승인되지 않습니다; <= 0이면 무입력 규칙을 비활성화합니다; DSH_TUI_ASK_USER_IDLE_MINUTES보다 우선",
40
+ "settings.askUser.absoluteMinutes.description": "Ask User 패널: 질문별 하드 한도 — 이 분이 지나면 사용자가 계속 조작 중이어도 자동으로 답변됩니다 (패널이 실행을 붙잡아 두어서는 안 됨); <= 0이면 한도를 비활성화합니다; DSH_TUI_ASK_USER_ABSOLUTE_MINUTES보다 우선",
41
+ "ask.language.header": "언어",
42
+ "ask.language.question": "TUI 가 사용할 UI 언어는 무엇입니까?",
43
+ "ask.language.detail": "현재 {current} 입니다. 선택하면 즉시 적용되고(다음 화면 갱신부터 새 언어, 기존 대화 기록은 재구성될 때까지 이전 언어 유지) dsh-tui.language 에 저장됩니다.",
44
+ "ask.language.current": "현재",
45
+ "ask.sentinel": "텍스트를 입력하세요.",
46
+ "ask.questionFallback": "질문 {n}",
47
+ "ask.confirmRow": "⏎ 답변 확정",
48
+ "ask.col.selection": "선택",
49
+ "ask.title.single": "● 질문",
50
+ "ask.title.multi": "● 질문 ({index}/{total})",
51
+ "ask.empty": "(질문 없음)",
52
+ "ask.escHint": "Esc를 한 번 더 누르면 거절합니다",
53
+ "ask.footer.editing": "자유 텍스트 입력 · Enter 유지 · ↑↓ 이동 · Ctrl+T 접기 · Esc 포기",
54
+ "ask.footer.tabs": "←→ 탭 전환 · ",
55
+ "ask.footer.navSelect": "↑↓ 이동 · Enter 선택 · 1-9 바로 선택 · Ctrl+T 접기 · Esc 거절",
56
+ "ask.footer.navToggle": "↑↓ 이동 · Enter 전환 · 1-9 바로 선택 · Ctrl+T 접기 · Esc 거절",
57
+ "ask.review.title": "● 답변 검토",
58
+ "ask.review.colQuestion": "질문",
59
+ "ask.review.colAnswer": "내 답변",
60
+ "ask.review.submit": "답변 제출",
61
+ "ask.review.ready": "✓ 준비됨",
62
+ "ask.review.incomplete": "— 미완료",
63
+ "ask.review.footer": "↑↓ 선택 · Enter 편집으로 돌아가기 / 제출 · Ctrl+T 접기",
64
+ "ask.review.noAnswer": "(답변 없음)",
65
+ "ask.collapsed.esc": "Esc를 한 번 더 누르면 거절 · Ctrl+T 펼치기",
66
+ "ask.collapsed.review": "● 답변 검토 대기 중 · Ctrl+T 펼치기",
67
+ "ask.collapsed.question": "● 질문 대기 중",
68
+ "ask.collapsed.questions": "● 질문 ({index}/{total} · {answered}개 답변됨)",
69
+ "ask.collapsed.expand": "Ctrl+T 펼치기",
70
+ "ask.autoIn": "{time} 후 자동 답변",
71
+ "ask.incomplete": "먼저 모든 질문에 답변하세요",
72
+ "ask.copied": "복사됨",
73
+ "ask.notice.timeoutReview": "ask_user_question: 시간 초과 — 이미 제공된 답변을 제출했습니다",
74
+ "ask.notice.timeoutAuto": "ask_user_question: 시간 초과 — 답변 없는 질문은 추천 옵션을 선택했습니다 (답변에 표기됨)",
75
+ "ask.settings.invalid": "설정 dsh-tui.askUser.{key}: 잘못된 값 {value} — 환경 변수/기본값으로 폴백합니다",
76
+ "viewer.footer.running": "↑↓ 스크롤 · Esc 닫기 · x ×2 중지 · Enter 스티어",
77
+ "viewer.footer.settled": "↑↓ 스크롤 · Esc 닫기 · x ×2 닫기 · Enter 스티어",
78
+ "viewer.steer.footer": "Enter 전송 · Shift+Enter 줄바꿈 · Esc 취소",
79
+ "viewer.steer.sent": "스티어 메시지를 전송했습니다",
80
+ "viewer.steer.ended": "이 서브에이전트는 종료되었습니다 — 스티어를 사용할 수 없습니다",
81
+ "viewer.steer.title": "스티어: {label}",
82
+ "viewer.steer.hint": "플러그인 출처의 사용자 메시지로 전달됩니다.",
83
+ "viewer.title": "● 서브에이전트",
84
+ "viewer.col.subagent": "서브에이전트",
85
+ "viewer.col.stats": "통계",
86
+ "viewer.pickerFooter": "↑↓ 이동 · Enter 열기 · s 정렬 · K 전체 중지 · Esc 닫기",
87
+ "viewer.truncated": "…기록이 잘렸습니다 ({cap}개 이벤트 제한)",
88
+ "viewer.hardStopped": "⏻ maxRounds 정책에 의해 강제 중지되었습니다 (라운드 {round} + 유예 소진, 상한 {cap})",
89
+ "viewer.noEvents": " — 아직 이벤트 없음 —",
90
+ "viewer.canceling": "⏹ 이 서브에이전트를 취소하는 중…",
91
+ "viewer.stopAllOne": "⏹ 전체 중지: 서브에이전트 1개를 취소했습니다",
92
+ "viewer.stopAllMany": "⏹ 전체 중지: 서브에이전트 {n}개를 취소했습니다",
93
+ "viewer.header.child": "ⓘ 서브에이전트 {id}",
94
+ "viewer.status.running": "실행 중",
95
+ "viewer.status.completed": "완료됨",
96
+ "viewer.status.failed": "실패",
97
+ "viewer.status.cancelled": "취소됨",
98
+ "viewer.route.think": "생각 {effort}",
99
+ "viewer.rounds": "라운드 {count}{cap}",
100
+ "viewer.hardStoppedAt": "⏻ @{round} 강제 중지",
101
+ "viewer.injected": "⚡ 주입됨",
102
+ "viewer.stopped": "⏻ 중지됨",
103
+ "viewer.event.turnStart": "– 턴 {n} 시작",
104
+ "viewer.event.turnEnd": "– 턴 {n} 종료 · {detail}",
105
+ "viewer.event.error": "오류",
106
+ "viewer.event.errorDetail": "오류: {message}",
107
+ "viewer.event.subagent": "서브에이전트",
108
+ "viewer.event.todos": "☑ 할 일 {done}/{total}: {summary}",
109
+ "agentsmg.error.integer": "음수가 아닌 정수를 기대했지만 \"{text}\"을(를) 받았습니다",
110
+ "agentsmg.inherit": "(상속)",
111
+ "agentsmg.inheritWord": "상속",
112
+ "agentsmg.model.title": "● 모델",
113
+ "agentsmg.picker.colModel": "모델",
114
+ "agentsmg.picker.colProvider": "프로바이더",
115
+ "agentsmg.openFailed": "✘ 에이전트 뷰를 열지 못했습니다: {message}",
116
+ "agentsmg.title": "● 에이전트",
117
+ "agentsmg.col.name": "이름",
118
+ "agentsmg.col.model": "모델",
119
+ "agentsmg.col.deep": "깊이",
120
+ "agentsmg.col.description": "설명",
121
+ "agentsmg.tableFooter": "↑↓ 이동 · Enter 열기 · Esc 뒤로 · l 제한",
122
+ "agentsmg.seededNote": " ({dir}에서 {n}개 가져옴)",
123
+ "agentsmg.updated": "에이전트 업데이트됨: {list}{note}",
124
+ "agentsmg.seededOnly": "{dir}에서 에이전트 {n}개를 가져왔습니다 — 변경 사항이 없습니다.",
125
+ "agentsmg.noDescription": "(설명 없음)",
126
+ "agentsmg.target.profile": "model/think 수정은 프로필 \"{name}\"에 적용됩니다 (워크스페이스 범위 — frontmatter 기준선은 그대로 유지됨)",
127
+ "agentsmg.target.frontmatter": "워크스페이스 프로필 고정 없음 — 수정 사항은 frontmatter 기준선(전역)에 기록됩니다",
128
+ "agentsmg.inheritDefault": "(상속 — 기본 모델)",
129
+ "agentsmg.fieldsFooter": "↑↓ 필드 · Enter 편집 (m 모델 · t 생각 · d 깊이) · v 전체 프롬프트 · Esc 뒤로",
130
+ "agentsmg.savedModel": "{name} 저장됨 → {model}{think}{scope}",
131
+ "agentsmg.thinkSuffix": " · 생각 {effort}",
132
+ "agentsmg.scopeNote": " (프로필 \"{name}\")",
133
+ "agentsmg.error.noModel": "✘ 모델이 설정되지 않았습니다 — 먼저 모델을 선택하세요 (m)",
134
+ "agentsmg.error.noLlm": "✘ llm 서비스를 사용할 수 없습니다",
135
+ "agentsmg.error.noThinkLevels": "✘ {model}의 생각 레벨을 해석할 수 없습니다",
136
+ "agentsmg.error.modelNoThink": "✘ {model}에 생각 레벨이 없습니다",
137
+ "agentsmg.savedThink": "{name} 저장됨 → 생각 {effort}{scope}",
138
+ "agentsmg.deep.title": "최대 파생 깊이 — {name}",
139
+ "agentsmg.deep.subtitle": "0 = 이 에이전트는 서브에이전트를 파생하지 않음 · 무제한 옵션 없음",
140
+ "agentsmg.deep.saved": "최대 깊이 {n} 저장됨 — 이 에이전트가 파생될 때 적용됩니다",
141
+ "agentsmg.deep.status": "{name} 저장됨 → 최대 깊이 {n}",
142
+ "agentsmg.body.title": "ⓘ {name} · 시스템 프롬프트",
143
+ "agentsmg.body.footer": " Esc로 닫기",
144
+ "agentsmg.limits.maxAgents": "{n} · 동시 실행 중인 자식 서브에이전트 수 (0 = 무제한)",
145
+ "agentsmg.limits.maxRounds": "{n} · 마무리 전 어시스턴트 메시지 수 (0 = 무제한)",
146
+ "agentsmg.limits.maxRoundsGrace": "{n} · 강제 중지 전 마무리 라운드 수 (0 = 경고만)",
147
+ "agentsmg.limits.disableSubagent": "{value} · 네이티브 subagent 도구",
148
+ "agentsmg.limits.registeredOnly": "{value} · use_agent만 파생 가능 (subagent/fork/workflow/ralph 차단됨)",
149
+ "agentsmg.on": "on",
150
+ "agentsmg.off": "off",
151
+ "agentsmg.limits.title": "⚙ 서브에이전트",
152
+ "agentsmg.limits.footer": "↑↓ 필드 · Enter 편집 (0 = 무제한) · d subagent 전환 · r 등록 전용 · Esc 뒤로",
153
+ "agentsmg.limits.intro": "서브에이전트 위임 조절 항목 — 매 파생/턴 결정 때 실시간으로 읽습니다",
154
+ "agentsmg.limits.runtime": "런타임: 실행 중 {live} · 허용 {allowed} · 거부 {denied} · 정리됨 {pruned} · 진행 중 {inFlight} (TUI 시작 이후)",
155
+ "agentsmg.limits.noAgents": "{dir}에 아직 에이전트가 없습니다 — markdown 파일을 하나 넣으면 정의할 수 있습니다",
156
+ "agentsmg.limits.broken": "손상된 파일 {n}개를 무시했습니다",
157
+ "agentsmg.limit.title": "{key} — 서브에이전트 위임 한도 (현재 {current})",
158
+ "agentsmg.limit.subtitle": "음수가 아닌 정수 · 0 = 무제한 · 비워 두면 현재 값 유지",
159
+ "agentsmg.limit.saved": "{key} → {n} 저장됨 — 이후 서브에이전트 파생에 적용됩니다",
160
+ "agentsmg.subagent.disabled": "subagent 도구가 비활성화되었습니다 — 이후 서브에이전트 파생에 적용됩니다",
161
+ "agentsmg.subagent.enabled": "subagent 도구가 활성화되었습니다 — 이후 서브에이전트 파생에 적용됩니다",
162
+ "agentsmg.fence.on": "등록 전용 펜스 ON — use_agent만 파생할 수 있습니다",
163
+ "agentsmg.fence.off": "등록 전용 펜스 off — 즉석 파생 도구를 사용할 수 있습니다",
164
+ "queue.footer": "↑↓ 선택 · d 제거 · s 지금 스티어 · Esc 닫기",
165
+ "queue.refreshFailed": "대기열 상태 새로 고침에 실패했습니다 — 아래 목록은 오래되었을 수 있습니다.",
166
+ "queue.target.steer": "↪ 스티어",
167
+ "queue.target.queued": "⏳ 대기 중",
168
+ "queue.title": "대기 중인 메시지",
169
+ "queue.empty": "— 대기 중인 메시지 없음 —",
170
+ "skillsmgr.reason.notSymlink": "심볼릭 링크 아님",
171
+ "skillsmgr.reason.differentSource": "소스가 다름",
172
+ "skillsmgr.reason.sourceMissing": "소스 없음",
173
+ "skillsmgr.reason.destMissing": "대상 없음",
174
+ "skillsmgr.reason.failed": "실패",
175
+ "skillsmgr.summary.more": " +{n}개 더",
176
+ "skillsmgr.summary.ok": "성공: {list}",
177
+ "skillsmgr.summary.applied": "{ok}/{total} 적용됨 — {okPart}실패: {failed}",
178
+ "skillsmgr.title": "⚙ 스킬 관리자",
179
+ "skillsmgr.unsaved": " ({n}개 저장 안 됨)",
180
+ "skillsmgr.noMatches": "'{query}'에 대한 일치 항목이 없습니다",
181
+ "skillsmgr.col.on": "활성",
182
+ "skillsmgr.col.skill": "스킬",
183
+ "skillsmgr.footer.confirm": "저장하지 않은 변경 사항을 버릴까요? Y/N",
184
+ "skillsmgr.footer.filter": "필터: {query} · Backspace 지우기 · Esc 필터 지우기",
185
+ "skillsmgr.footer.dirty": "↑↓ 이동 · Space 전환 · Enter 적용 · Esc 버림",
186
+ "skillsmgr.footer.idle": "↑↓ 이동 · PgUp/PgDn 페이지 · Home/End 점프 · Space 전환 · Enter 적용 · Esc 뒤로",
187
+ "skillsmgr.scanning": "공개 스킬을 스캔하는 중…",
188
+ "skillsmgr.empty": "~/.agents/skills/에서 공개 스킬을 찾을 수 없습니다.",
189
+ "skillsmgr.readError": "~/.agents/skills/를 읽을 수 없습니다.",
190
+ "skills.error.cannotRead": "스킬 파일을 읽을 수 없습니다: {path}",
191
+ "skills.error.missingFrontmatter": "frontmatter가 없습니다 (파일은 `---`로 시작해야 함)",
192
+ "skills.error.missingCloseFence": "frontmatter 닫는 펜스가 없습니다",
193
+ "skills.error.cannotWrite": "스킬 파일을 쓸 수 없습니다: {message}",
194
+ "btw.error.noQuestion": "/btw --model 뒤에 질문이 없습니다.",
195
+ "btw.error.invalidModel": "잘못된 --model \"{model}\" — provider/model 형식이어야 합니다.",
196
+ "btw.queueFull": "btw 대기열이 가득 찼습니다 ({cap})",
197
+ "btw.error.unknownStream": "알 수 없는 모델 스트림 오류입니다.",
198
+ "btw.error.maxTokens": "답변이 출력 토큰 상한에 도달했습니다.",
199
+ "btw.error.toolCalls": "사이드 모델이 예기치 않게 도구를 요청했습니다.",
200
+ "btw.error.unsupportedFinish": "지원되지 않는 스트림 종료 유형: {kind}",
201
+ "btw.error.noFinish": "모델 스트림이 finish 청크 없이 끝났습니다.",
202
+ "btw.error.noModel": "모델이 선택되지 않았습니다 — btw를 실행할 수 없습니다.",
203
+ "btw.error.modelUnavailable": "btw 모델 \"{model}\"을(를) 사용할 수 없습니다.",
204
+ "btw.background": "btw가 백그라운드에서 실행 중입니다 — /btw로 답변을 확인하세요.",
205
+ "btw.failed": "btw 실패: {message}",
206
+ "btw.notice.idle": "/btw는 메인 작업이 실행 중일 때 곁가지 질문을 하는 명령입니다 — 메인 라인이 유휴 상태이니 바로 질문하세요.",
207
+ "btw.notice.usage": "사용법: /btw <질문> — 메인 작업이 실행되는 동안 곁가지 질문을 합니다. 답변은 임시 오버레이에 스트리밍되며 세션에는 저장되지 않습니다.",
208
+ "misc.attachment.loading": "🖼 {name} — 로딩 중 ({width}×{height})",
209
+ "misc.attachment.more": "🖼 +{n}개 이미지 미표시",
210
+ "misc.attachment.unavailable": "🖼 {name} — 사용 불가{code}",
211
+ "misc.todos.title": "● 할 일 ",
212
+ "misc.todos.showing": " · {ranges} 표시 중",
213
+ "misc.todos.task": "작업",
214
+ "misc.agent.rounds": "라운드 {n}{cap}",
215
+ "misc.agent.fallbackName": "서브에이전트",
216
+ "misc.pending.queued": "⏳ 대기 중",
217
+ "misc.pending.steer": "↪ 스티어",
218
+ "misc.pending.canceled": "✕ 취소됨",
219
+ "misc.pending.notDelivered": "✘ 전달되지 않음",
220
+ "misc.turnFailed": "턴 실패",
221
+ "misc.interrupted": "중단됨",
222
+ "misc.tokenLimit": "⚠ 출력 토큰 한도에 도달했습니다",
223
+ "stop.confirm.title": "● 모든 LLM 작업을 중지할까요?",
224
+ "stop.confirm.mainRunning": "메인 턴이 생성 중",
225
+ "stop.confirm.childrenOne": "서브에이전트 {count}개가 실행 중",
226
+ "stop.confirm.childrenMany": "서브에이전트 {count}개가 실행 중",
227
+ "stop.confirm.joiner": "이며 ",
228
+ "stop.confirm.situation": "현재 {parts}입니다.",
229
+ "stop.confirm.idle": "지금 실행 중인 작업이 없습니다.",
230
+ "stop.confirm.reassure": "확인하면 메인 턴과 실행 중인 모든 서브에이전트를 취소합니다. 대기 중인 메시지는 유지되며 세션은 재개할 수 있습니다.",
231
+ "stop.option.stop": "전체 중지 — 메인 턴과 모든 서브에이전트를 취소합니다",
232
+ "stop.option.cancel": "취소 — 전부 계속 실행합니다",
233
+ "stop.footer": "↑↓ 선택 · 1/2 선택 · Enter 확인 · Esc 계속 실행",
234
+ "repair.confirm.title": "● 손상된 재개 로그",
235
+ "repair.confirm.body": "재개 로그가 손상되었습니다 (과거의 이중 기록기 때문일 가능성이 높습니다). 그 자리에서 복구할까요? 원본은 .corrupt-bak로 보존됩니다.",
236
+ "repair.option.repair": "복구 후 재개",
237
+ "repair.option.repairHint": "로그를 그 자리에서 다시 작성한 뒤 세션에 들어갑니다",
238
+ "repair.option.cancel": "취소",
239
+ "repair.option.cancelHint": "로그를 그대로 둡니다",
240
+ "repair.footer": "↑↓ 선택 · 1/2 선택 · Enter 확인 · Esc 취소",
241
+ "presetdlg.title.switch": "● {name} 프리셋으로 전환할까요?",
242
+ "presetdlg.title.restart": "● {name}에서 세션을 재시작할까요?",
243
+ "presetdlg.fork.switch": "포크 후 전환 — {name}에서 새 세션을 열고 이 대화를 가져갑니다",
244
+ "presetdlg.fork.restart": "포크 후 재시작 — {name}에서 새 세션을 열고 이 대화를 가져갑니다",
245
+ "presetdlg.fresh.switch": "새로 시작 — {name}에서 빈 새 세션을 엽니다",
246
+ "presetdlg.fresh.restart": "지금 재시작 — {name}에서 빈 새 세션을 엽니다",
247
+ "presetdlg.point.switch": "전환하면 {name}에서 새 세션을 시작합니다.",
248
+ "presetdlg.point.restart": "재시작하면 {name}에서 새 세션을 시작합니다.",
249
+ "presetdlg.option.cancel": "취소 — 현재 세션에 머무릅니다",
250
+ "presetdlg.carry": "포크는 이 대화를 새 세션으로 가져갑니다 (압축된 컨텍스트 포함) — 새로 시작하면 빈 세션이 됩니다.",
251
+ "presetdlg.footer": "↑↓ 선택 · 1/2/3 선택 · Enter 확인 · Esc 취소",
252
+ "presetdlg.echo.unchanged": "프리셋 변경 없음 — 현재 세션에 그대로 있습니다.",
253
+ "presetdlg.echo.forked": "프리셋 → {name} — 이 대화에서 포크한 새 세션입니다.",
254
+ "presetdlg.echo.fresh": "프리셋 → {name} — 빈 새 세션이 열렸습니다.",
255
+ "presetdlg.echo.direct": "프리셋 → {name} — 새 세션이 열렸습니다.",
256
+ "route.title": "에이전트가 실행 중입니다 — 이 메시지의 경로를 선택하세요",
257
+ "route.preview.empty": "(빈 메시지)",
258
+ "route.option.followup": "후속 질문으로 대기열에 추가",
259
+ "route.option.followupHint": "현재 턴이 끝나면 전달됩니다",
260
+ "route.option.steer": "지금 스티어",
261
+ "route.option.steerHint": "다음 단계 경계에서 주입됩니다",
262
+ "route.footer": "↑↓ 선택 · 1/2 선택 · Enter 확인 · Esc 취소",
263
+ "fork.title": "● 턴 {turn}에서 포크할까요?",
264
+ "fork.body.carry": "새 세션은 {total}개 턴 중 {turn}번째 턴까지 가져가며, 그 이후 턴은 현재 세션에 남습니다.",
265
+ "fork.body.resume": "현재 세션은 /resume으로 재개할 수 있습니다.",
266
+ "fork.body.detach": "실행 중인 세션 {id}는 분리됩니다 — /resume으로 재개할 수 있습니다.",
267
+ "fork.option.fork": "지금 포크 — 턴 {turn}까지의 새 세션을 만듭니다",
268
+ "fork.option.cancel": "취소",
269
+ "fork.footer": "↑↓ 선택 · 1/2 선택 · Enter 확인 · Esc 취소",
270
+ "steer.notice.unavailable": "스티어를 사용할 수 없었습니다 — 메시지는 후속 질문으로 대기열에 남아 있습니다.",
271
+ "steer.notice.turnEnded": "스티어가 전달되기 전에 턴이 끝났습니다 — 대신 후속 질문으로 대기열에 추가했습니다.",
272
+ "steer.notice.removed": "대기열에서 제거했습니다.",
273
+ "steer.notice.promoted": "즉시 전송으로 전환했습니다 — 지금 현재 턴을 스티어합니다.",
274
+ "steer.notice.notFound": "이미 처리되었거나 제거된 상태입니다 — 목록을 새로 고쳤습니다.",
275
+ "steer.notice.error": "✘ {error}",
276
+ "steer.notice.orphaned": "{error} — 메시지가 대기열에서 빠졌지만 전달되지는 않았습니다. 다시 제출하세요.",
277
+ "history.footer": "↑↓ 이동 · Enter/c 복사 · f 포크 · → 상세 · s 세션 · / 필터 · Esc 닫기",
278
+ "history.noText": "(텍스트 없음)",
279
+ "history.listTitle": "● 기록 · {id}",
280
+ "history.liveTag": "(실시간)",
281
+ "history.moreLines": "… +{count}줄 더",
282
+ "history.turnFailed": "턴 실패",
283
+ "history.interrupted": "중단됨",
284
+ "history.maxTokens": "출력 토큰 한도 도달",
285
+ "history.truncated": "… {count}줄이 더 잘렸습니다 — {pointer}전체 턴 보기",
286
+ "history.emptyTurn": "(이 턴에는 표시된 프롬프트나 답변 텍스트가 없습니다)",
287
+ "history.title": "기록",
288
+ "history.turnTitle": "턴 {turn}",
289
+ "history.liveSnapshot": "실시간 스냅샷",
290
+ "history.selectTurn": "왼쪽에서 턴을 선택하세요.",
291
+ "history.lineOne": "{count}줄",
292
+ "history.lineMany": "{count}줄",
293
+ "history.linesRange": "{start}–{end}/{total}줄",
294
+ "history.detailFooterFocused": "← 목록 · ↑↓ 스크롤 · [ / ] 페이지 넘기기 · {window}",
295
+ "history.detailFooterIdle": "[ / ] 페이지 넘기기 · {window}",
296
+ "history.corruptLog": "⚠ {id}: 세션 로그가 손상되었습니다 — /resume {id} 명령으로 복구할 수 있습니다.",
297
+ "history.cannotRead": "{id} 세션을 읽을 수 없습니다: {message}",
298
+ "history.noPersistence": "이 프로필에는 세션 지속성이 구성되어 있지 않습니다.",
299
+ "history.noCwd": "디렉터리 없음",
300
+ "history.col.turn": "턴",
301
+ "history.col.prompt": "프롬프트",
302
+ "history.col.updated": "업데이트",
303
+ "history.col.dir": "디렉터리",
304
+ "history.col.session": "세션",
305
+ "history.empty": "완료된 턴이 없습니다",
306
+ "history.closed": "기록 뷰어를 닫았습니다.",
307
+ "history.nothingToCopy": "복사할 내용이 없습니다 — 이 턴에는 사용자 프롬프트가 없습니다.",
308
+ "history.copied": "프롬프트를 편집기에 복사했습니다.",
309
+ "history.pickerTitle": "● 세션 탐색",
310
+ "history.pickerFooter": "↑↓ 이동 · Enter 탐색 · / 필터 · Esc 뒤로",
311
+ "history.noMatching": "일치하는 세션이 없습니다",
312
+ "history.forked": "턴 {turn}에서 포크했습니다 — 새 세션이 열렸습니다.",
313
+ "history.forkFailed": "포크 실패: {message}",
314
+ "history.forkAtTurnFailed": "턴 {turn} 포크 실패: {message}",
315
+ "history.noStored": "탐색할 저장된 세션이 없습니다.",
316
+ "history.noActive": "활성 세션이 없습니다 — 저장된 세션은 /history <sessionId> 명령으로 탐색하세요.",
317
+ "history.openFailed": "기록 뷰어를 열지 못했습니다.",
318
+ "turns.toolCallOne": "회 도구 호출",
319
+ "turns.toolCallMany": "회 도구 호출",
320
+ "resume.title": "● 세션 재개",
321
+ "resume.headingTitle": "ⓘ {title} · 토큰: 현재 라우트",
322
+ "resume.headingPlain": "ⓘ 세션 · 토큰: 현재 라우트",
323
+ "resume.empty": "활성 세션이 없습니다 — 프롬프트를 보내거나 /resume으로 재개하세요",
324
+ "resume.field.session": "세션",
325
+ "resume.field.cwd": "작업 디렉터리",
326
+ "resume.field.created": "생성됨",
327
+ "resume.field.model": "모델",
328
+ "resume.field.think": "생각",
329
+ "resume.field.status": "상태",
330
+ "resume.field.messages": "메시지",
331
+ "resume.field.toolcalls": "도구 호출",
332
+ "resume.field.tokensin": "입력 토큰",
333
+ "resume.field.tokensout": "출력 토큰",
334
+ "resume.field.cacheread": "캐시 읽기",
335
+ "resume.field.cachewrite": "캐시 쓰기",
336
+ "resume.field.events": "이벤트",
337
+ "resume.field.parent": "부모",
338
+ "resume.col.field": "필드",
339
+ "resume.col.value": "값",
340
+ "resume.col.updated": "업데이트",
341
+ "resume.col.dir": "디렉터리",
342
+ "resume.col.session": "세션",
343
+ "resume.hintEdit": "Enter 저장 · Esc 취소",
344
+ "resume.renameEmpty": "이름 변경 ▸ {cursor} (제목 입력)",
345
+ "resume.renameEdit": "이름 변경 ▸ {buffer}{cursor}",
346
+ "resume.hintRename": "r 이름 변경 · Esc 닫기",
347
+ "resume.hintClose": "Esc 닫기",
348
+ "resume.titleEmpty": "제목이 비어 있습니다",
349
+ "resume.noBackend": "세션 지속성이 open()이나 inspect()를 제공하지 않습니다.",
350
+ "resume.noPersistence": "이 프로필에는 세션 지속성이 구성되어 있지 않습니다.",
351
+ "resume.settingInvalid": "설정 dsh-tui.resume.{key}: 잘못된 값 {value} — 환경 변수/기본값으로 폴백합니다",
352
+ "resume.listFailed": "저장된 세션 목록을 가져오지 못했습니다: {message}",
353
+ "resume.noCwd": "디렉터리 없음",
354
+ "tui.esc.armStop": "모든 LLM 작업을 중지하려면 Esc를 한 번 더 누르세요",
355
+ "tui.esc.quitArmed": "{icon} Ctrl+C ×2 — 종료하는 중…",
356
+ "tui.esc.quitAborted": "종료가 취소되었습니다 — Ctrl+C는 길게 누른 것이었고 두 번 누른 것이 아닙니다",
357
+ "tui.stop.stopping": "{icon} 모든 LLM 작업을 중지하는 중…",
358
+ "tui.stop.nothingRunning": "취소할 실행 중인 작업이 없습니다.",
359
+ "tui.keys.warningPrefix": "키 바인딩: {warning}",
360
+ "tui.status.working": "작업 중…",
361
+ "tui.takeover.writeLock": "쓰기 잠금을 획득했습니다 — 후속 질문을 보냈습니다.",
362
+ "tui.session.none": "활성 세션이 없습니다.",
363
+ "tui.session.infoShown": "세션 정보를 표시했습니다.",
364
+ "tui.session.renamed": "이름 변경됨: \"{title}\"",
365
+ "tui.session.titleEmpty": "제목이 정규화되면 비어 있습니다",
366
+ "tui.session.effortDefault": "프로바이더 기본값",
367
+ "tui.btw.noLlm": "LLM 서비스를 사용할 수 없습니다.",
368
+ "tui.btw.backOnScreen": "btw — 실행 중이던 답변이 다시 화면에 표시됩니다.",
369
+ "tui.btw.lastShown": "마지막 btw 대화를 표시했습니다.",
370
+ "tui.btw.started": "btw — 메인 작업과 함께 답변하는 중입니다.",
371
+ "tui.btw.queued": "btw가 대기열에 추가되었습니다 (위치 {position}).",
372
+ "tui.btw.rejected": "btw가 거부되었습니다 — {reason}.",
373
+ "tui.model.unchanged": "모델이 변경되지 않았습니다.",
374
+ "tui.agents.unchanged": "에이전트가 변경되지 않았습니다.",
375
+ "tui.subagents.viewerClosed": "서브에이전트 뷰어를 닫았습니다.",
376
+ "tui.model.selected": "모델: {id}",
377
+ "tui.model.selectedThink": "모델: {id} · think {effort}",
378
+ "tui.persist.failed": "{text} · ⚠ 저장되지 않음: {error}",
379
+ "tui.think.noModel": "선택된 모델이 없습니다 — 먼저 /model로 선택하세요.",
380
+ "tui.think.unsupported": "{id}에 선택 가능한 think 레벨이 없습니다.",
381
+ "tui.think.unchanged": "think 레벨이 변경되지 않았습니다.",
382
+ "tui.think.providerDefault": "think: 프로바이더 기본값 ({id}).",
383
+ "tui.think.set": "think: {effort} ({id}).",
384
+ "tui.preset.memorySaveFailed": "프리셋 메모리를 저장하지 못했습니다: {error}",
385
+ "tui.preset.none": "사용 가능한 에이전트 프리셋이 없습니다.",
386
+ "tui.preset.unknown": "알 수 없는 프리셋: {name}",
387
+ "tui.preset.unchanged": "프리셋이 변경되지 않았습니다.",
388
+ "tui.resume.noneOther": "재개할 수 있는 다른 저장 세션이 없습니다.",
389
+ "tui.resume.windowEmpty": "재개 기간 내에 세션이 없습니다 ({days}일, ≥{floor}) — 더 보려면 dsh-tui.resume.*를 조정하세요.",
390
+ "tui.resume.cancelled": "재개가 취소되었습니다.",
391
+ "tui.resume.watching": "{id} 세션을 읽기 전용으로 지켜보고 있습니다 (다른 프로세스가 구동 중). /resume 또는 /new로 전환하세요.",
392
+ "tui.resume.watchFailed": "{id} 세션을 읽기 전용으로 볼 수 없습니다: {error}",
393
+ "tui.resume.failed": "재개 실패: {error} — 이전 세션이 닫혔습니다; 다음 프롬프트가 새 세션을 시작합니다.",
394
+ "tui.resume.done": "{id} 세션을 재개했습니다 · {count}개 이벤트.",
395
+ "tui.resume.cannot": "{id} 세션을 재개할 수 없습니다: {error}",
396
+ "tui.repair.logMissing": "복구 실패: 디스크에서 {id}의 로그를 찾을 수 없습니다 — 로그는 변경되지 않았습니다",
397
+ "tui.repair.failed": "복구 실패: {error} — 로그는 변경되지 않았습니다",
398
+ "tui.boot.resumeFailed": "--resume {id}: {error} — 새로 시작합니다.",
399
+ "tui.export.noSession": "내보낼 활성 세션이 없습니다.",
400
+ "tui.export.done": "이벤트 {count}개를 내보냈습니다 → {path}",
401
+ "tui.new.done": "새 세션을 시작했습니다.",
402
+ "tui.settings.unavailable": "설정 서비스를 사용할 수 없습니다.",
403
+ "tui.settings.noNamespaces": "등록된 설정 네임스페이스가 없습니다.",
404
+ "tui.settings.noChanges": "설정: 변경 사항이 없습니다.",
405
+ "tui.settings.appliedOne": "설정: 변경 사항 {count}개를 적용했습니다.",
406
+ "tui.settings.appliedMany": "설정: 변경 사항 {count}개를 적용했습니다.",
407
+ "tui.skills.opened": "스킬 관리자를 열었습니다.",
408
+ "tui.theme.unchanged": "테마가 변경되지 않았습니다.",
409
+ "tui.theme.pinned": "테마 환경설정이 저장되었습니다 — 표시는 DSH_TUI_THEME={value}에 의해 고정됩니다",
410
+ "tui.theme.applied": "테마: {name} — 적용되었습니다.",
411
+ "tui.hotkeys.unchanged": "키 바인딩이 변경되지 않았습니다.",
412
+ "tui.login.unknownProvider": "알 수 없는 프로바이더 '{name}' — /login을 실행해 디렉터리에서 선택하세요.",
413
+ "tui.login.cancelled": "로그인이 취소되었습니다.",
414
+ "tui.login.configured": "프로바이더 {name} 구성 완료.",
415
+ "tui.logout.none": "제거할 저장된 자격 증명이 없습니다.",
416
+ "tui.logout.cancelled": "로그아웃이 취소되었습니다.",
417
+ "tui.logout.failed": "{name}의 저장된 API 키를 제거하지 못했습니다{cause}.",
418
+ "tui.logout.incomplete": "{name}의 API 키를 제거했지만 프로바이더 구성은 남아 있습니다: {error} — 로그아웃을 마치려면 /settings에서 프로바이더를 제거하세요.",
419
+ "tui.logout.keyOnly": "{name}의 API 키를 제거했습니다. 수동 선언 라우트 — 구성은 유지되며, 모델까지 제거하려면 /settings에서 프로바이더를 제거하세요.",
420
+ "tui.logout.done": "{name}에서 로그아웃했습니다 — API 키와 프로바이더 구성이 제거되었습니다.",
421
+ "tui.permission.unchanged": "권한이 변경되지 않았습니다.",
422
+ "tui.steer.queuedFollowup": "후속 질문으로 대기열에 추가했습니다 — 쓰기 잠금이 해제되면 자동으로 전송됩니다.",
423
+ "tui.steer.noSession": "활성 세션이 없습니다 — 메시지가 전달되지 않았습니다.",
424
+ "tui.exit.resumeHint": "이 세션을 재개하려면: {command}",
425
+ "tui.cmd.btw.description": "메인 작업이 실행되는 동안 곁가지 질문을 합니다 (임시 오버레이, 저장 안 됨)",
426
+ "tui.cmd.model.description": "이 대화의 모델(및 think 레벨)을 선택합니다",
427
+ "tui.cmd.agents.description": "markdown 파일에서 에이전트 정의(모델, think 레벨, 파생 깊이)를 관리합니다",
428
+ "tui.cmd.subagents.description": "서브에이전트를 탐색하고 실시간 대화 기록을 확인합니다",
429
+ "tui.cmd.think.description": "현재 모델의 think(추론) 레벨을 전환합니다",
430
+ "tui.cmd.preset.description": "에이전트 프리셋을 전환합니다 (그 프리셋으로 새 세션을 시작; /preset next는 순환)",
431
+ "tui.cmd.session.description": "현재 세션 정보(id, 제목, 통계)를 표시하고 이름을 변경합니다 (r)",
432
+ "tui.cmd.resume.description": "저장된 세션을 재개합니다",
433
+ "tui.cmd.history.description": "세션의 과거 턴을 탐색합니다 (읽기 전용; 저장된 세션은 /history <id>)",
434
+ "tui.cmd.export.description": "이 세션 로그를 JSONL로 내보냅니다",
435
+ "tui.cmd.new.description": "새 세션을 시작합니다",
436
+ "tui.cmd.settings.description": "구성을 탐색하고 편집합니다 (네임스페이스, 값, 재설정)",
437
+ "tui.cmd.skills.description": "사용자 스킬을 관리합니다 (설치됨 및 사용 가능)",
438
+ "tui.cmd.theme.description": "터미널 색 구성표를 설정합니다 (즉시 적용)",
439
+ "tui.cmd.reload.description": "현재 소스에서 TUI를 다시 로드합니다 (dsh를 재시작하지 않고 코드 변경을 적용)",
440
+ "tui.cmd.hotkeys.description": "현재 키 바인딩을 표시합니다 (사용자 지정 파일: ~/.dsh/keybindings.json)",
441
+ "tui.cmd.login.description": "프로바이더 디렉터리를 통해 프로바이더 자격 증명(API 키)을 등록합니다",
442
+ "tui.cmd.logout.description": "프로바이더에서 로그아웃합니다 (API 키와 프로바이더 구성을 제거)",
443
+ "settingsui.group.subagent": "서브에이전트",
444
+ "settingsui.title": "⚙ 설정",
445
+ "settingsui.category.dsh-tui": "TUI",
446
+ "settingsui.category.general": "일반",
447
+ "settingsui.category.models": "모델",
448
+ "settingsui.category.plugins": "플러그인",
449
+ "settingsui.category.agent": "에이전트 프리셋",
450
+ "settingsui.category.other": "기타",
451
+ "settingsui.summary.namespaces": "{count}개 네임스페이스",
452
+ "settingsui.fields.count": "{count}개 필드",
453
+ "settingsui.ns.applies": "적용 시점: {applies}",
454
+ "settingsui.value.unset": "(설정 안 됨)",
455
+ "settingsui.value.items": "[{count}개 항목]",
456
+ "settingsui.value.keys": "키 {count}개",
457
+ "settingsui.dict.one": "사전 · {count}개 항목",
458
+ "settingsui.dict.many": "사전 · {count}개 항목",
459
+ "settingsui.meta.required": "필수",
460
+ "settingsui.meta.default": "기본값: {value}",
461
+ "settingsui.meta.min": "최소: {value}",
462
+ "settingsui.meta.max": "최대: {value}",
463
+ "settingsui.meta.step": "단계: {value}",
464
+ "settingsui.meta.pattern": "패턴: {value}",
465
+ "settingsui.meta.secret": "비밀 값",
466
+ "settingsui.meta.disabled": "비활성화됨",
467
+ "settingsui.meta.userSet": "사용자 설정",
468
+ "settingsui.edit.footer": "Enter 저장 · Esc 뒤로",
469
+ "settingsui.edit.secret": "비밀 값 — 현재 값을 유지하려면 비워 두세요",
470
+ "settingsui.edit.current": "현재 값: {value}",
471
+ "settingsui.parse.number": "숫자를 기대했지만 \"{text}\"을(를) 받았습니다",
472
+ "settingsui.parse.json": "JSON 값을 기대했습니다 (숫자, 불리언, 문자열 등)",
473
+ "settingsui.parse.type": "{type} 값은 편집할 수 없습니다",
474
+ "settingsui.reset.working": "재설정 중…",
475
+ "settingsui.reset.hints": "Enter: 기본값으로 재설정 · Esc: 취소",
476
+ "settingsui.reset.namespace": "이 네임스페이스를 기본값으로 재설정",
477
+ "settingsui.reset.path": "기본값으로 재설정: {path}",
478
+ "settingsui.reset.ns": "기본값으로 재설정: \"{ns}\"",
479
+ "settingsui.addKey.label": "+ 키 추가…",
480
+ "settingsui.addKey.title": "{path}에 키 추가",
481
+ "settingsui.addKey.subtitle": "기본값: {default} · Enter로 추가 · Esc 취소",
482
+ "settingsui.addKey.empty": "키는 비워 둘 수 없습니다",
483
+ "settingsui.addKey.exists": "\"{key}\" 키가 이미 존재합니다",
484
+ "settingsui.addProvider.title": "⚙ 프로바이더 추가",
485
+ "settingsui.addProvider.empty": "모든 내장 프로바이더가 이미 구성되어 있습니다.",
486
+ "settingsui.escClose": "Esc를 눌러 닫기",
487
+ "settingsui.addProvider.keyTitle": "{name}의 API 키",
488
+ "settingsui.addProvider.keySubtitle": "{ref}로 저장됨 — settings.yaml에는 절대 기록되지 않습니다",
489
+ "settingsui.addProvider.keyRequired": "API 키는 비워 둘 수 없습니다",
490
+ "settingsui.commit.noCredentials": "프로바이더가 추가되었습니다 — 이 프로세스에는 자격 증명 서비스가 없습니다: 사용하려면 {ref}를 export 하세요",
491
+ "settingsui.commit.keyFailed": "API 키를 저장하지 못했습니다: {cause} — 프로바이더는 추가되었습니다; 사용하려면 {ref}=<키>를 export 하세요",
492
+ "settingsui.models.title": "⚙ 모델",
493
+ "settingsui.models.readonly": "TUI에서는 읽기 전용 — 변경하려면 설정 문서를 편집하세요",
494
+ "settingsui.models.deepseek": "DeepSeek (공식)",
495
+ "settingsui.models.defaultModel": "기본 모델",
496
+ "settingsui.models.add": "+ 프로바이더 추가…",
497
+ "settingsui.models.addDesc": "내장 프로바이더를 API 키와 함께 구성합니다",
498
+ "settingsui.route.think": "{provider}/{model} · 생각 {effort}",
499
+ "themepv.title": "● 테마",
500
+ "themepv.col.theme": "테마",
501
+ "themepv.footer": "↑↓ 이동 · Enter 선택 · Esc 뒤로",
502
+ "themepv.desc.auto": "터미널 밝기/어두움 신호를 따릅니다",
503
+ "themepv.desc.githubLight": "GitHub 라이트 팔레트",
504
+ "themepv.desc.githubDark": "GitHub 다크 팔레트",
505
+ "themepv.origin.user": "사용자 테마",
506
+ "themepv.origin.builtin": "내장",
507
+ "themepv.auto.follows": "테마가 터미널을 따릅니다.",
508
+ "themepv.auto.pick": "light/dark 또는 이름으로 된 테마를 선택하면 미리 볼 수 있습니다.",
509
+ "themepv.input.placeholder": "메시지 입력…",
510
+ "sel.effort.default": "(프로바이더 기본값)",
511
+ "sel.effort.defaultDesc": "어댑터 기본 동작 — 생각 강도 재정의를 해제합니다",
512
+ "sel.col.description": "설명",
513
+ "sel.col.effort": "강도",
514
+ "sel.col.language": "언어",
515
+ "sel.col.model": "모델",
516
+ "sel.col.provider": "프로바이더",
517
+ "sel.col.preset": "프리셋",
518
+ "sel.title.effort": "● 추론 강도",
519
+ "sel.title.language": "● 언어",
520
+ "sel.title.model": "● 모델",
521
+ "sel.title.permission": "● 권한 프리셋",
522
+ "sel.title.preset": "● 에이전트 프리셋",
523
+ "sel.hidden.header": "─ 숨김 ({count}) ─",
524
+ "sel.footer.model": "↑↓ 이동 · Enter 선택 · f 즐겨찾기 · h 숨김 · / 필터 · Esc 뒤로",
525
+ "sel.status.saveFailed": "✘ 저장 실패: {message}",
526
+ "sel.preset.shipped": "기본 제공 프리셋",
527
+ "sel.preset.user": "사용자 프리셋",
528
+ "modelprof.error.nameEmpty": "프로필 이름은 비워 둘 수 없습니다",
529
+ "modelprof.error.exists": "이름이 \"{name}\"인 프로필이 이미 존재합니다",
530
+ "modelprof.error.notFound": "이름이 \"{name}\"인 프로필이 없습니다",
531
+ "modelprof.error.lastProfile": "마지막 프로필은 삭제할 수 없습니다",
532
+ "modelprof.error.pinEmpty": "파일에 프로필 이름이 없습니다",
533
+ "modelprof.error.pinOverwrite": "덮어쓰기 거부: {file} — 직접 편집된 파일입니다 (전환은 이번에만 즉시 적용)",
534
+ "modelprof.error.pinRemove": "제거 거부: {file} — 직접 편집된 파일입니다 (직접 제거하세요)",
535
+ "modelprof.route.notSet": "(설정 안 됨)",
536
+ "modelprof.route.plain": "{provider}/{model}",
537
+ "modelprof.route.think": "{provider}/{model} · 생각 {effort}",
538
+ "modelprof.review.profile": "프로필: {name}",
539
+ "modelprof.review.current": "현재",
540
+ "modelprof.review.defaultModel": "기본 모델: {route}",
541
+ "modelprof.review.none": "에이전트: 기록 없음 — /profile-cfg에서 모델을 선택하거나 s를 눌러 현재 구성을 저장하세요",
542
+ "modelprof.review.agents": "에이전트 ({count}개):",
543
+ "modelprof.review.notSaved": "(저장 안 됨 — 적용해도 변경되지 않음)",
544
+ "modelprof.review.inherit": "(상속)",
545
+ "modelprof.review.inheritWord": "상속",
546
+ "modelprof.review.think": "생각 {effort}",
547
+ "modelprof.review.fileMissing": "파일 없음",
548
+ "custprov.entry.name": "커스텀 프로바이더…",
549
+ "custprov.entry.hint": "base URL + API 키 + 모델 — 모든 OpenAI/Anthropic 호환 게이트웨이",
550
+ "custprov.hint.declared": "수동 선언 라우트",
551
+ "custprov.step.title": "커스텀 프로바이더 {current}/{total} · {label}",
552
+ "custprov.step.id": "프로바이더 ID",
553
+ "custprov.step.idHint": "settings.yaml의 라우트 키 — 자격 증명 참조도 여기서 파생됩니다 (예: acme-gateway → ACME_GATEWAY_API_KEY)",
554
+ "custprov.step.displayName": "표시 이름 (선택)",
555
+ "custprov.step.displayNameHint": "/model 및 모델 카테고리에 표시됩니다 — 비워 두면 라우트 id를 사용합니다",
556
+ "custprov.step.protocol": "API 프로토콜",
557
+ "custprov.step.protocolHint": "{list} 중 하나 — 비워 두면 {default}가 기본값",
558
+ "custprov.step.baseUrl": "Base URL",
559
+ "custprov.step.baseUrlHint": "게이트웨이 엔드포인트, 예: https://gateway.internal.example/v1",
560
+ "custprov.step.models": "모델",
561
+ "custprov.step.modelsHint": "쉼표로 구분된 와이어 모델 id, 예: acme-large, acme-think",
562
+ "custprov.step.apiKey": "API 키",
563
+ "custprov.step.apiKeyHint": "파생된 참조로 저장됩니다 — settings.yaml에는 절대 기록되지 않습니다",
564
+ "custprov.error.idEmpty": "프로바이더 ID는 비워 둘 수 없습니다",
565
+ "custprov.error.idLength": "프로바이더 ID는 2–40자여야 합니다",
566
+ "custprov.error.idChars": "소문자, 숫자, 대시만 사용하세요 (점과 공백은 사용 불가)",
567
+ "custprov.error.idTaken": "\"{id}\" id가 이미 존재합니다 — 다른 라우트 id를 선택하세요",
568
+ "custprov.error.nameLength": "표시 이름은 최대 40자여야 합니다",
569
+ "custprov.error.protocol": "프로토콜은 다음 중 하나여야 합니다: {list}",
570
+ "custprov.error.baseUrlEmpty": "Base URL은 비워 둘 수 없습니다",
571
+ "custprov.error.baseUrlFormat": "Base URL은 http:// 또는 https://로 시작해야 하며 공백을 포함할 수 없습니다",
572
+ "custprov.error.modelsEmpty": "모델 id를 최소 하나 이상 나열하세요 (쉼표로 구분)",
573
+ "custprov.error.modelLength": "각 모델 id는 최대 80자여야 합니다",
574
+ "custprov.error.modelsMax": "초기 목록은 최대 50개 모델입니다",
575
+ "custprov.error.keyEmpty": "API 키는 비워 둘 수 없습니다",
576
+ "provcatalog.hint.apiKey": "API 키",
577
+ "provcatalog.hint.aws": "AWS 자격 증명 또는 bearer 토큰",
578
+ "provcatalog.hint.copilot": "GitHub Copilot 토큰",
579
+ "provcatalog.hint.googleCloud": "Google Cloud 자격 증명",
580
+ "provcatalog.hint.huggingface": "Hugging Face 토큰",
581
+ "provcatalog.hint.apiKey.gateway": "API 키 · OpenAI 호환 게이트웨이",
582
+ "provcatalog.status.set": "API 키 설정됨",
583
+ "provcatalog.status.missing": "API 키 없음",
584
+ "provcatalog.status.notConfigured": "API 키 미구성",
585
+ "login.title.logout": "● 로그아웃",
586
+ "login.col.provider": "프로바이더",
587
+ "login.col.keyRef": "키 참조",
588
+ "login.error.removeFailed": "{name}의 저장된 키를 제거하지 못했습니다{cause}",
589
+ "login.error.removeIncomplete": "{name}의 저장된 키를 제거했지만 프로바이더 구성은 제거되지 않았습니다: {error}",
590
+ "footer.hint.default": "⌨ Enter: 전송 · Esc ×2: 중지 · Ctrl+C ×2: 종료 · Ctrl+D: 종료 (빈 입력) · Ctrl+G: 서브에이전트 · Ctrl+Shift+F: 검색 · /preset: 전환 · ↑↓: 기록",
591
+ "footer.hint.send": "Enter: 전송",
592
+ "footer.hint.stop": "Esc ×2: 중지",
593
+ "footer.hint.quit": "Ctrl+C ×2: 종료",
594
+ "footer.hint.quitEmpty": "Ctrl+D: 종료 (빈 입력)",
595
+ "footer.hint.subagents": "Ctrl+G: 서브에이전트",
596
+ "footer.hint.search": "Ctrl+Shift+F: 검색",
597
+ "footer.hint.preset": "/preset: 전환",
598
+ "footer.hint.history": "↑↓: 기록",
599
+ "footer.seg.msgs": "💬 메시지 {count}개",
600
+ "footer.seg.tools": "🔧 도구 {count}개",
601
+ "panel.empty.models": "일치하는 모델이 없습니다",
602
+ "panel.empty.settings": "일치하는 설정이 없습니다",
603
+ "panel.filter.input": "필터: {query}_",
604
+ "panel.filter.active": "필터: {query}",
605
+ "panel.filter.hint": "필터: {query} · Backspace 지우기 · Esc 필터 지우기",
606
+ "panel.footer.filtering": "Enter 적용 · Esc 필터 지우기",
607
+ "panel.footer.navigate": "↑↓ 이동 · Enter 선택 · Esc 뒤로",
608
+ "panel.footer.search": "↑↓ 이동 · Enter 선택 · 입력하여 검색 · Esc 뒤로",
609
+ "panel.footer.field": "↑↓ 필드 · Enter 편집 · Esc 뒤로",
610
+ "panel.col.field": "필드",
611
+ "panel.col.value": "값",
612
+ "panel.col.setting": "설정",
613
+ "panel.viewer.more": "… {count}줄 더",
614
+ "panel.viewer.close": "Esc로 닫기",
615
+ "startup.plugin.disabled": "{label} (비활성화됨)",
616
+ "startup.tree.base": "└─ dsh-base ({count})",
617
+ "startup.summary": "mcp {mcp} · 스킬 {installed}/{total} · 플러그인 {plugins}",
618
+ "hotkeys.title": "⚙ 단축키",
619
+ "hotkeys.updated": "단축키가 업데이트되었습니다.",
620
+ "hotkeys.openFailed": "✘ 단축키 뷰를 열지 못했습니다: {message}",
621
+ "hotkeys.footer": "↑↓ 키 · Enter 변경 · Esc 닫기",
622
+ "hotkeys.action.escape": "현재 작업을 중지합니다 — 두 번 눌러야 합니다 (첫 번째 누름은 대기, 500ms 안의 두 번째 누름이 발동)",
623
+ "hotkeys.action.ctrlC": "실행 중: 턴 취소 · 유휴: 편집기 지우기 · 한 번 더 누르면 종료",
624
+ "hotkeys.action.ctrlD": "종료 — 편집기가 비어 있을 때만",
625
+ "hotkeys.action.modelPicker": "모델/생각 선택기를 엽니다",
626
+ "hotkeys.action.subagentViewer": "서브에이전트 선택기/뷰어를 엽니다",
627
+ "hotkeys.action.queuePanel": "대기 중인 메시지 대기열을 엽니다 (d 제거 · s 지금 스티어)",
628
+ "hotkeys.custom.many": "사용자 지정: {path} ({count}개 재정의)",
629
+ "hotkeys.custom.one": "사용자 지정: {path} (재정의 1개)",
630
+ "hotkeys.custom.missing": "사용자 지정: {path} (없음 — 기본값 사용)",
631
+ "hotkeys.formatHint": "형식: ctrl/shift/alt/super+키 · Enter로 편집 · 비워 두면 기본값으로 초기화",
632
+ "hotkeys.editorHint": "편집기: pi-tui 기본값 — 방향키 · Ctrl+B/F · Alt+←→ 단어 단위 이동 · Home/End · Ctrl+W/U/K 삭제 · Ctrl+- 실행 취소",
633
+ "hotkeys.warn.invalidJson": "{label}: 잘못된 JSON — {error}",
634
+ "hotkeys.warn.notObject": "{label}: 앱 키 → 키 id 형태의 JSON 객체가 필요합니다",
635
+ "hotkeys.warn.invalidKey": "{label}: \"{field}\" = {value}은(는) 유효한 키 id가 아닙니다 — 기본값을 유지합니다",
636
+ "hotkeys.warn.unknownField": "{label}: 알 수 없는 필드 \"{field}\" — 무시합니다",
637
+ "hotkeys.file.notObject": "{label}: JSON 객체가 필요합니다 — 파일을 고치거나 삭제한 후 다시 시도하세요",
638
+ "hotkeys.file.parseError": "{label}: {error} — 파일을 고치거나 삭제한 후 다시 시도하세요",
639
+ "hotkeys.file.writeError": "{label}: 쓸 수 없습니다 — {error}",
640
+ "hotkeys.parse.notKeyId": "키 id가 아닙니다 — ctrl/shift/alt/super + 키 (예: ctrl+x, f5, escape)",
641
+ "hotkeys.edit.title": "{field} 키 — 기본값 {defaultValue}",
642
+ "hotkeys.edit.titleCustom": "{field} 키 — 기본값 {defaultValue} · 사용자 지정 {custom}",
643
+ "hotkeys.edit.subtitle": "ctrl/shift/alt/super + 키 · 비워 두면 기본값으로 초기화",
644
+ "hotkeys.status.reset": "{field} → 기본값 ({defaultValue}) — 적용됨",
645
+ "hotkeys.status.set": "{field} → {id} — 적용됨"
646
+ }