autohand-cli 0.7.5 → 0.7.7
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.
- package/README.md +2 -0
- package/dist/{AutomodeManager-TJSW2SQY.cjs → AutomodeManager-HV6M7EAX.cjs} +61 -22
- package/dist/{AutomodeManager-WIMHLG4W.js → AutomodeManager-YVCJXOMQ.js} +61 -22
- package/dist/CommunitySkillsCache-2BITCEAA.cjs +7 -0
- package/dist/{CommunitySkillsCache-XPDVYU3K.js → CommunitySkillsCache-Q22FUAR5.js} +2 -2
- package/dist/HookManager-X47HCM5G.cjs +6 -0
- package/dist/{HookManager-VIX56KFU.js → HookManager-ZXKHCD7U.js} +1 -1
- package/dist/MemoryManager-2ATHG7BH.js +7 -0
- package/dist/MemoryManager-AENCGCEW.cjs +7 -0
- package/dist/PermissionManager-6HZGTK2N.cjs +10 -0
- package/dist/{PermissionManager-YFZI4ZZ6.js → PermissionManager-HATZKTRC.js} +3 -3
- package/dist/SessionManager-AG4WT3DP.cjs +9 -0
- package/dist/{SessionManager-IMW2HGR3.js → SessionManager-S5R6O3NU.js} +2 -2
- package/dist/{SkillsRegistry-7NICF6FY.js → SkillsRegistry-R5WDM6T3.js} +2 -2
- package/dist/SkillsRegistry-ZXU6YDRP.cjs +8 -0
- package/dist/SyncApiClient-FAOMIZAP.js +10 -0
- package/dist/SyncApiClient-UOA4VLLD.cjs +10 -0
- package/dist/add-dir-OMK3Y4DM.cjs +8 -0
- package/dist/add-dir-PNU7AGKO.js +8 -0
- package/dist/{agents-B33IAATH.js → agents-ICAC3KD3.js} +2 -2
- package/dist/agents-YONWPKFS.cjs +9 -0
- package/dist/agents-new-NV557UVG.cjs +10 -0
- package/dist/{agents-new-KTXJFC5E.js → agents-new-QHM3CO4B.js} +2 -2
- package/dist/{chunk-MFLRXVKU.js → chunk-23JQSCTO.js} +1 -1
- package/dist/chunk-2JPUEN44.cjs +299 -0
- package/dist/{chunk-5PD2L6WI.js → chunk-3YEDXG6S.js} +1 -1
- package/dist/{chunk-3ZUWWML7.cjs → chunk-4M2GX7RH.cjs} +2 -2
- package/dist/chunk-4RWTUT2Z.js +151 -0
- package/dist/{chunk-CHQMK2ZG.js → chunk-52MLYK5P.js} +1 -1
- package/dist/{chunk-CVYEUA3D.cjs → chunk-53BR4MUW.cjs} +3 -3
- package/dist/{chunk-5WKR4HIB.js → chunk-5DN5KNXU.js} +1 -1
- package/dist/{chunk-3CO5R6M2.cjs → chunk-7TOHYAUF.cjs} +2 -2
- package/dist/{chunk-UPR5PKX4.cjs → chunk-7VW3A7DO.cjs} +7 -3
- package/dist/chunk-A552JHUJ.cjs +151 -0
- package/dist/{chunk-NGSLABLS.js → chunk-A6QBABQ7.js} +1 -1
- package/dist/chunk-ARVFUZOB.js +736 -0
- package/dist/{chunk-2FLBGPE3.js → chunk-AVL4DKQO.js} +6 -2
- package/dist/{chunk-CT2VTDPQ.cjs → chunk-B4ZPNXZE.cjs} +1 -1
- package/dist/{chunk-OKMYLMCR.cjs → chunk-B7EUETGY.cjs} +4 -4
- package/dist/chunk-C26EN22G.cjs +328 -0
- package/dist/chunk-DOTAX65F.js +328 -0
- package/dist/{chunk-SKT2CRNY.cjs → chunk-DSKVMFRM.cjs} +56 -8
- package/dist/{chunk-FUEL6BK7.js → chunk-EKY5PKQI.js} +15 -0
- package/dist/{chunk-YMP7AGNT.js → chunk-G77ZY4QG.js} +1 -1
- package/dist/{chunk-KN5C4TR4.cjs → chunk-GDTZQSJ6.cjs} +2 -2
- package/dist/{chunk-536VWSZK.cjs → chunk-GFJ6AETU.cjs} +4 -4
- package/dist/chunk-GR7VWN63.js +613 -0
- package/dist/{chunk-PVM5I5WI.js → chunk-GWIAMKKF.js} +1 -1
- package/dist/{chunk-XAM7SFVB.cjs → chunk-GWXXFQ3F.cjs} +2 -2
- package/dist/{chunk-REPKBECD.cjs → chunk-JHFH3N4U.cjs} +2 -2
- package/dist/{chunk-4L5WYXHN.js → chunk-KH7BCZJN.js} +1 -1
- package/dist/{chunk-JXOXZTMA.js → chunk-L5ZFPWHY.js} +54 -6
- package/dist/chunk-MDWULS57.js +288 -0
- package/dist/{chunk-6LP2GO5C.js → chunk-MJFBVQHB.js} +2 -2
- package/dist/{chunk-MWLAHCU7.js → chunk-NI3BQXKU.js} +1 -1
- package/dist/{chunk-63XGCFCC.cjs → chunk-NYQVQYIF.cjs} +6 -103
- package/dist/{chunk-SKU4M27Z.js → chunk-OBV3UUIL.js} +1 -1
- package/dist/{chunk-27ISZOFA.js → chunk-P2Z6GDEN.js} +1 -1
- package/dist/{chunk-XTHHDIBG.cjs → chunk-PMMSDR44.cjs} +16 -1
- package/dist/chunk-PR53E47T.cjs +613 -0
- package/dist/{chunk-URY4AS4L.cjs → chunk-PU534KPO.cjs} +4 -4
- package/dist/chunk-Q3WCMY3Z.js +104 -0
- package/dist/{chunk-EYBIKL2I.js → chunk-QXAPHGEW.js} +4 -101
- package/dist/chunk-SFGJQPGC.cjs +288 -0
- package/dist/{chunk-53YDUYNS.cjs → chunk-SLISYSP4.cjs} +2 -2
- package/dist/{chunk-2E2COWKB.cjs → chunk-SYJLMBLP.cjs} +66 -10
- package/dist/chunk-U5WIP4HS.js +674 -0
- package/dist/{chunk-7HB7GSQF.js → chunk-UL7YPRCU.js} +1 -1
- package/dist/chunk-VDZJ3W4M.cjs +104 -0
- package/dist/{chunk-LUKMRIKJ.cjs → chunk-VEDIYPWY.cjs} +2 -2
- package/dist/{chunk-C2NFLFHH.js → chunk-VPAN5H7Q.js} +1 -1
- package/dist/chunk-WH3D42BQ.js +299 -0
- package/dist/{chunk-2FSQPRPJ.js → chunk-WIUGUR5T.js} +59 -3
- package/dist/{chunk-QMVTT55Y.cjs → chunk-WQSWU2QA.cjs} +4 -4
- package/dist/chunk-XFPITUFJ.cjs +674 -0
- package/dist/chunk-XFQS2VGT.cjs +736 -0
- package/dist/{chunk-HYTYXN2G.cjs → chunk-YAGD43KA.cjs} +10 -10
- package/dist/constants-G2PLP5HH.cjs +20 -0
- package/dist/{constants-QYBEF3DB.js → constants-ZLG6M5SI.js} +3 -1
- package/dist/{defaultHooks-3G3DVF6I.js → defaultHooks-R56VYG7I.js} +315 -1
- package/dist/{defaultHooks-Z4KA6U5C.cjs → defaultHooks-WLMRQUXG.cjs} +315 -1
- package/dist/{feedback-PZ2PINDU.js → feedback-HZBCTSFG.js} +2 -2
- package/dist/feedback-JBQ3UPGZ.cjs +10 -0
- package/dist/index.cjs +2669 -978
- package/dist/index.js +2657 -966
- package/dist/language-KODBDE5R.js +12 -0
- package/dist/language-SJT475NW.cjs +12 -0
- package/dist/localProjectPermissions-AYQYGTOE.cjs +17 -0
- package/dist/{localProjectPermissions-DURCNDZG.js → localProjectPermissions-YFFAKLUZ.js} +2 -2
- package/dist/login-TC2KROQI.js +14 -0
- package/dist/login-TYMR2ZD3.cjs +14 -0
- package/dist/logout-2ECV365P.js +12 -0
- package/dist/logout-CO3CPYZJ.cjs +12 -0
- package/dist/resume-EPOEF3WV.cjs +9 -0
- package/dist/{resume-2NERFSTD.js → resume-LOYD5MMP.js} +2 -1
- package/dist/share-544SIZOY.js +10 -0
- package/dist/share-OETK2GUF.cjs +10 -0
- package/dist/{skills-CRFOVWEQ.js → skills-3YEEODHK.js} +1 -1
- package/dist/skills-CRM55MKM.cjs +12 -0
- package/dist/{skills-install-Z27KPEGF.cjs → skills-install-FTGOHOZ4.cjs} +5 -5
- package/dist/{skills-install-RMPXN6RK.js → skills-install-KAXAQSN6.js} +2 -2
- package/dist/skills-new-JF4FKNUT.cjs +11 -0
- package/dist/{skills-new-S2YPO635.js → skills-new-JYX2GBKM.js} +2 -2
- package/dist/{status-VRYDAEBT.js → status-7LCXYYY4.js} +2 -1
- package/dist/status-E7MZEQ26.cjs +9 -0
- package/dist/sync-3B7SNBYC.js +14 -0
- package/dist/sync-4RARBQIH.cjs +39 -0
- package/dist/sync-H4UHHLKU.js +39 -0
- package/dist/sync-YZ6YZ42H.cjs +14 -0
- package/dist/theme-3XV5BWUB.js +12 -0
- package/dist/theme-Z2WS5XWZ.cjs +12 -0
- package/package.json +5 -2
- package/dist/CommunitySkillsCache-X3X237QQ.cjs +0 -7
- package/dist/HookManager-EOMUXKJ4.cjs +0 -6
- package/dist/MemoryManager-UVHILGV5.js +0 -7
- package/dist/MemoryManager-WO3KUZVA.cjs +0 -7
- package/dist/PermissionManager-PMTQN263.cjs +0 -10
- package/dist/SessionManager-VZNWGX4O.cjs +0 -9
- package/dist/SkillsRegistry-OINIPILA.cjs +0 -8
- package/dist/agents-GRAFXZY3.cjs +0 -9
- package/dist/agents-new-67NJJSDA.cjs +0 -10
- package/dist/chunk-55DQY6B5.js +0 -49
- package/dist/chunk-RYY5I7QN.cjs +0 -49
- package/dist/constants-PE5DLI7Q.cjs +0 -18
- package/dist/feedback-R66B3B3C.cjs +0 -10
- package/dist/localProjectPermissions-75X3ZGKH.cjs +0 -17
- package/dist/login-NYWZRZO5.js +0 -12
- package/dist/login-QNJ5C42G.cjs +0 -12
- package/dist/logout-MBS7L3ZW.js +0 -12
- package/dist/logout-MVUP7GPU.cjs +0 -12
- package/dist/resume-OYZMJRNO.cjs +0 -8
- package/dist/skills-6PIGHOWS.cjs +0 -12
- package/dist/skills-new-3QJUST7P.cjs +0 -11
- package/dist/status-CYVPCW7G.cjs +0 -8
- package/dist/theme-CVY6MVEK.cjs +0 -12
- package/dist/theme-CY7WF4M6.js +0 -12
|
@@ -0,0 +1,736 @@
|
|
|
1
|
+
import {
|
|
2
|
+
saveConfig
|
|
3
|
+
} from "./chunk-GWIAMKKF.js";
|
|
4
|
+
|
|
5
|
+
// src/commands/language.ts
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import enquirer from "enquirer";
|
|
8
|
+
|
|
9
|
+
// src/i18n/index.ts
|
|
10
|
+
import i18next from "i18next";
|
|
11
|
+
|
|
12
|
+
// src/i18n/locales/en.json
|
|
13
|
+
var en_default = {
|
|
14
|
+
common: {
|
|
15
|
+
error: "Error",
|
|
16
|
+
warning: "Warning",
|
|
17
|
+
success: "Success",
|
|
18
|
+
failed: "Failed",
|
|
19
|
+
cancelled: "Cancelled",
|
|
20
|
+
continue: "Continue",
|
|
21
|
+
yes: "Yes",
|
|
22
|
+
no: "No",
|
|
23
|
+
done: "Done",
|
|
24
|
+
loading: "Loading...",
|
|
25
|
+
pressEnter: "Press Enter to continue...",
|
|
26
|
+
pressEscToCancel: "Press Esc to cancel",
|
|
27
|
+
or: "or",
|
|
28
|
+
and: "and",
|
|
29
|
+
unknown: "Unknown",
|
|
30
|
+
none: "None",
|
|
31
|
+
default: "Default",
|
|
32
|
+
current: "current",
|
|
33
|
+
required: "required",
|
|
34
|
+
optional: "optional",
|
|
35
|
+
enabled: "Enabled",
|
|
36
|
+
disabled: "Disabled",
|
|
37
|
+
on: "On",
|
|
38
|
+
off: "Off"
|
|
39
|
+
},
|
|
40
|
+
cli: {
|
|
41
|
+
description: "Autonomous LLM-powered coding agent CLI",
|
|
42
|
+
options: {
|
|
43
|
+
prompt: "Run a single instruction in command mode",
|
|
44
|
+
path: "Workspace path to operate in",
|
|
45
|
+
yes: "Auto-confirm risky actions",
|
|
46
|
+
dryRun: "Preview actions without applying mutations",
|
|
47
|
+
debug: "Enable debug output (verbose logging)",
|
|
48
|
+
model: "Override the configured LLM model",
|
|
49
|
+
config: "Path to config file (default ~/.autohand/config.json)",
|
|
50
|
+
temperature: "Sampling temperature",
|
|
51
|
+
displayLanguage: "Set display language (e.g., en, zh-cn, fr, de)",
|
|
52
|
+
autoCommit: "Auto-commit with LLM-generated message",
|
|
53
|
+
unrestricted: "Run without any approval prompts",
|
|
54
|
+
restricted: "Deny all dangerous operations automatically",
|
|
55
|
+
autoSkill: "Auto-generate skills based on project analysis",
|
|
56
|
+
skillInstall: "Install a community skill",
|
|
57
|
+
project: "Install skill to project level",
|
|
58
|
+
permissions: "Display current permission settings and exit",
|
|
59
|
+
login: "Sign in to your Autohand account",
|
|
60
|
+
logout: "Sign out of your Autohand account",
|
|
61
|
+
syncSettings: "Enable/disable settings sync",
|
|
62
|
+
patch: "Generate git patch without applying changes",
|
|
63
|
+
output: "Output file for patch (default: stdout)",
|
|
64
|
+
autoMode: "Start autonomous development loop",
|
|
65
|
+
maxIterations: "Max auto-mode iterations (default: 50)",
|
|
66
|
+
completionPromise: "Completion marker text (default: DONE)",
|
|
67
|
+
noWorktree: "Disable git worktree isolation in auto-mode",
|
|
68
|
+
checkpointInterval: "Git commit every N iterations (default: 5)",
|
|
69
|
+
maxRuntime: "Max runtime in minutes (default: 120)",
|
|
70
|
+
maxCost: "Max API cost in dollars (default: 10)",
|
|
71
|
+
setup: "Run the setup wizard",
|
|
72
|
+
addDir: "Add additional directories to workspace scope"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
welcome: {
|
|
76
|
+
banner: "Welcome to Autohand!",
|
|
77
|
+
subtitle: "Your super fast AI coding agent",
|
|
78
|
+
version: "v{{version}}",
|
|
79
|
+
updateAvailable: "Update available: {{current}} -> {{latest}}. Run 'npm i -g autohand' to update.",
|
|
80
|
+
loggedInAs: "Logged in as {{email}}",
|
|
81
|
+
notLoggedIn: "Not logged in",
|
|
82
|
+
modelLine: "model: {{model}}",
|
|
83
|
+
directoryLine: "directory: {{directory}}",
|
|
84
|
+
tips: {
|
|
85
|
+
title: "To get started, describe a task or try one of these commands:",
|
|
86
|
+
init: "/init - create an AGENTS.md file with instructions for Autohand",
|
|
87
|
+
help: "/help - show all available commands",
|
|
88
|
+
model: "/model - change the AI model",
|
|
89
|
+
language: "/language - change display language"
|
|
90
|
+
},
|
|
91
|
+
shortcuts: {
|
|
92
|
+
title: "Keyboard shortcuts:",
|
|
93
|
+
mention: "@ - mention files for context",
|
|
94
|
+
arrows: "Arrow keys - navigate suggestions",
|
|
95
|
+
tab: "Tab - autocomplete",
|
|
96
|
+
escape: "Esc - cancel current operation",
|
|
97
|
+
ctrlC: "Ctrl+C - exit"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
commands: {
|
|
101
|
+
help: {
|
|
102
|
+
title: "Available Commands:",
|
|
103
|
+
command: "Command",
|
|
104
|
+
description: "Description",
|
|
105
|
+
tips: {
|
|
106
|
+
title: "Tips:",
|
|
107
|
+
mention: "Type @ to mention files for the AI",
|
|
108
|
+
arrows: "Use arrow keys to navigate file suggestions",
|
|
109
|
+
tab: "Press Tab to autocomplete file paths",
|
|
110
|
+
escape: "Press Esc to cancel current operation"
|
|
111
|
+
},
|
|
112
|
+
docsLink: "For more information, visit {{link}}"
|
|
113
|
+
},
|
|
114
|
+
model: {
|
|
115
|
+
description: "choose what model and reasoning effort to use",
|
|
116
|
+
title: "Model Selection",
|
|
117
|
+
currentModel: "Current model: {{model}}",
|
|
118
|
+
selectPrompt: "Select a model:",
|
|
119
|
+
changed: "Model changed to {{model}}",
|
|
120
|
+
noChange: "No change made."
|
|
121
|
+
},
|
|
122
|
+
theme: {
|
|
123
|
+
description: "change terminal color theme",
|
|
124
|
+
title: "Theme Selection",
|
|
125
|
+
currentTheme: "Current theme: {{theme}}",
|
|
126
|
+
selectPrompt: "Select a theme:",
|
|
127
|
+
changed: "Theme changed to '{{theme}}'",
|
|
128
|
+
noChange: "No change made."
|
|
129
|
+
},
|
|
130
|
+
language: {
|
|
131
|
+
description: "change display language",
|
|
132
|
+
title: "Language Selection",
|
|
133
|
+
currentLanguage: "Current language: {{language}}",
|
|
134
|
+
selectPrompt: "Select a language:",
|
|
135
|
+
changed: "Language changed to {{language}}",
|
|
136
|
+
noChange: "No change made.",
|
|
137
|
+
restartHint: "Some changes may require restarting the CLI to take full effect."
|
|
138
|
+
},
|
|
139
|
+
quit: {
|
|
140
|
+
description: "exit Autohand",
|
|
141
|
+
goodbye: "Goodbye!"
|
|
142
|
+
},
|
|
143
|
+
init: {
|
|
144
|
+
description: "create AGENTS.md file",
|
|
145
|
+
created: "Created AGENTS.md in {{path}}",
|
|
146
|
+
alreadyExists: "AGENTS.md already exists in {{path}}",
|
|
147
|
+
overwritePrompt: "Overwrite existing AGENTS.md?"
|
|
148
|
+
},
|
|
149
|
+
undo: {
|
|
150
|
+
description: "revert the last file mutation",
|
|
151
|
+
success: "Reverted changes to {{file}}",
|
|
152
|
+
noChanges: "No changes to undo.",
|
|
153
|
+
failed: "Failed to undo: {{error}}"
|
|
154
|
+
},
|
|
155
|
+
new: {
|
|
156
|
+
description: "start a new conversation",
|
|
157
|
+
cleared: "Conversation cleared. Starting fresh."
|
|
158
|
+
},
|
|
159
|
+
status: {
|
|
160
|
+
description: "show current status",
|
|
161
|
+
title: "Autohand Status",
|
|
162
|
+
version: "Version",
|
|
163
|
+
sessionId: "Session ID",
|
|
164
|
+
cwd: "Current directory",
|
|
165
|
+
provider: "Provider",
|
|
166
|
+
model: "Model",
|
|
167
|
+
locale: "Language",
|
|
168
|
+
apiStatus: "API Status",
|
|
169
|
+
connected: "Connected",
|
|
170
|
+
disconnected: "Disconnected",
|
|
171
|
+
sessions: "Sessions",
|
|
172
|
+
total: "{{count}} total"
|
|
173
|
+
},
|
|
174
|
+
sessions: {
|
|
175
|
+
description: "list saved sessions",
|
|
176
|
+
title: "Saved Sessions",
|
|
177
|
+
noSessions: "No saved sessions found.",
|
|
178
|
+
selectPrompt: "Select a session to resume:",
|
|
179
|
+
sessionInfo: "{{name}} - {{date}}"
|
|
180
|
+
},
|
|
181
|
+
resume: {
|
|
182
|
+
description: "resume a previous session",
|
|
183
|
+
resuming: "Resuming session {{id}}...",
|
|
184
|
+
notFound: "Session not found: {{id}}",
|
|
185
|
+
failed: "Failed to resume session: {{error}}"
|
|
186
|
+
},
|
|
187
|
+
memory: {
|
|
188
|
+
description: "manage project and user memory",
|
|
189
|
+
title: "Memory Management",
|
|
190
|
+
projectMemory: "Project Memory",
|
|
191
|
+
userMemory: "User Memory",
|
|
192
|
+
noMemory: "No memories stored.",
|
|
193
|
+
addPrompt: "Add a new memory:",
|
|
194
|
+
added: "Memory added.",
|
|
195
|
+
cleared: "Memory cleared."
|
|
196
|
+
},
|
|
197
|
+
permissions: {
|
|
198
|
+
description: "display current permission settings",
|
|
199
|
+
title: "Permission Settings",
|
|
200
|
+
mode: "Mode: {{mode}}",
|
|
201
|
+
allowed: "Allowed actions:",
|
|
202
|
+
denied: "Denied actions:",
|
|
203
|
+
pending: "Pending approval:"
|
|
204
|
+
},
|
|
205
|
+
login: {
|
|
206
|
+
description: "sign in to your Autohand account",
|
|
207
|
+
prompt: "Enter your login code:",
|
|
208
|
+
success: "Successfully logged in as {{email}}",
|
|
209
|
+
failed: "Login failed: {{error}}",
|
|
210
|
+
cancelled: "Login cancelled."
|
|
211
|
+
},
|
|
212
|
+
logout: {
|
|
213
|
+
description: "sign out of your Autohand account",
|
|
214
|
+
confirm: "Log out from {{email}}?",
|
|
215
|
+
success: "Successfully logged out.",
|
|
216
|
+
cancelled: "Logout cancelled."
|
|
217
|
+
},
|
|
218
|
+
sync: {
|
|
219
|
+
description: "manage settings sync",
|
|
220
|
+
enabled: "Settings sync enabled.",
|
|
221
|
+
disabled: "Settings sync disabled.",
|
|
222
|
+
status: "Sync status: {{status}}",
|
|
223
|
+
lastSync: "Last synced: {{date}}"
|
|
224
|
+
},
|
|
225
|
+
feedback: {
|
|
226
|
+
description: "submit feedback about the CLI",
|
|
227
|
+
prompt: "Enter your feedback:",
|
|
228
|
+
success: "Thank you for your feedback!",
|
|
229
|
+
failed: "Failed to submit feedback: {{error}}"
|
|
230
|
+
},
|
|
231
|
+
hooks: {
|
|
232
|
+
description: "manage git hooks",
|
|
233
|
+
title: "Git Hooks",
|
|
234
|
+
installed: "Installed hooks:",
|
|
235
|
+
available: "Available hooks:",
|
|
236
|
+
noHooks: "No hooks configured."
|
|
237
|
+
},
|
|
238
|
+
skills: {
|
|
239
|
+
description: "list and manage skills",
|
|
240
|
+
title: "Skills",
|
|
241
|
+
installed: "Installed skills:",
|
|
242
|
+
available: "Available skills:",
|
|
243
|
+
noSkills: "No skills installed."
|
|
244
|
+
},
|
|
245
|
+
export: {
|
|
246
|
+
description: "export session data",
|
|
247
|
+
success: "Exported to {{path}}",
|
|
248
|
+
failed: "Export failed: {{error}}"
|
|
249
|
+
},
|
|
250
|
+
agents: {
|
|
251
|
+
description: "manage sub-agents",
|
|
252
|
+
title: "Sub-Agents",
|
|
253
|
+
noAgents: "No sub-agents configured."
|
|
254
|
+
},
|
|
255
|
+
automode: {
|
|
256
|
+
description: "manage autonomous mode",
|
|
257
|
+
starting: "Starting auto-mode...",
|
|
258
|
+
stopping: "Stopping auto-mode...",
|
|
259
|
+
iteration: "Iteration {{current}} of {{max}}",
|
|
260
|
+
completed: "Auto-mode completed.",
|
|
261
|
+
aborted: "Auto-mode aborted."
|
|
262
|
+
},
|
|
263
|
+
share: {
|
|
264
|
+
description: "share session",
|
|
265
|
+
generating: "Generating share link...",
|
|
266
|
+
success: "Share link: {{url}}",
|
|
267
|
+
failed: "Failed to generate share link: {{error}}"
|
|
268
|
+
},
|
|
269
|
+
addDir: {
|
|
270
|
+
description: "add directories to workspace scope",
|
|
271
|
+
added: "Added directory: {{path}}",
|
|
272
|
+
alreadyAdded: "Directory already added: {{path}}",
|
|
273
|
+
notFound: "Directory not found: {{path}}"
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
setup: {
|
|
277
|
+
welcome: "Welcome to Autohand!",
|
|
278
|
+
subtitle: "Your super fast AI coding agent",
|
|
279
|
+
letsStart: "Let's get you set up in just a few steps.",
|
|
280
|
+
providerSelect: "Which LLM provider would you like to use?",
|
|
281
|
+
apiKeyPrompt: "Enter your {{provider}} API key:",
|
|
282
|
+
apiKeyHelp: "Get your API key at: {{url}}",
|
|
283
|
+
apiKeyHint: "Your API key will be stored locally in ~/.autohand/config.json",
|
|
284
|
+
modelPrompt: "Enter model ID (or press Enter for default):",
|
|
285
|
+
modelDefault: "Default: {{model}}",
|
|
286
|
+
testingConnection: "Testing connection...",
|
|
287
|
+
connectionSuccess: "Connection successful!",
|
|
288
|
+
connectionFailed: "Connection failed: {{error}}",
|
|
289
|
+
telemetry: {
|
|
290
|
+
title: "Help us improve Autohand",
|
|
291
|
+
description: "We collect anonymous usage data to understand how Autohand is used.",
|
|
292
|
+
whatWeCollect: "What we collect:",
|
|
293
|
+
collectItem1: "Command usage (which features are popular)",
|
|
294
|
+
collectItem2: "Error rates (to fix bugs faster)",
|
|
295
|
+
collectItem3: "Performance metrics (to speed things up)",
|
|
296
|
+
whatWeNeverCollect: "What we never collect:",
|
|
297
|
+
neverItem1: "Your code or file contents",
|
|
298
|
+
neverItem2: "API keys or credentials",
|
|
299
|
+
neverItem3: "Personal information",
|
|
300
|
+
prompt: "Share anonymous usage data to help improve Autohand?",
|
|
301
|
+
thanks: "Thanks for helping us improve Autohand!",
|
|
302
|
+
declined: "No problem! You can change this anytime in config."
|
|
303
|
+
},
|
|
304
|
+
complete: "Setup complete!",
|
|
305
|
+
created: "What was created:",
|
|
306
|
+
configFile: "~/.autohand/config.json (your settings)",
|
|
307
|
+
agentsFile: "AGENTS.md (project instructions for Autohand)",
|
|
308
|
+
nextSteps: "Next steps:",
|
|
309
|
+
tryCommand: "Try: autohand"
|
|
310
|
+
},
|
|
311
|
+
errors: {
|
|
312
|
+
generic: "An error occurred: {{message}}",
|
|
313
|
+
invalidLocale: "Invalid locale: {{locale}}. Supported: {{supported}}",
|
|
314
|
+
configParseFailed: "Failed to parse config at {{path}}: {{error}}",
|
|
315
|
+
configSaveFailed: "Failed to save config: {{error}}",
|
|
316
|
+
apiKeyRequired: "API key is required",
|
|
317
|
+
apiKeyTooShort: "API key seems too short",
|
|
318
|
+
apiKeyInvalid: "Invalid API key format",
|
|
319
|
+
directoryNotExist: "Directory does not exist: {{path}}",
|
|
320
|
+
unsafeDirectory: "Unsafe directory: {{path}}. Cannot operate in system directories.",
|
|
321
|
+
fileNotFound: "File not found: {{path}}",
|
|
322
|
+
permissionDenied: "Permission denied: {{path}}",
|
|
323
|
+
patchRequiresPrompt: "--patch requires --prompt to specify the instruction",
|
|
324
|
+
autoModeRequiresPrompt: "--auto-mode requires a task prompt",
|
|
325
|
+
noProviderConfigured: "No provider is configured yet. Run setup with: autohand --setup",
|
|
326
|
+
modelNotFound: "Model not found: {{model}}",
|
|
327
|
+
rateLimited: "Rate limited. Please wait a moment and try again.",
|
|
328
|
+
networkError: "Network error: {{message}}",
|
|
329
|
+
timeout: "Request timed out. Please try again.",
|
|
330
|
+
contextTooLong: "Context too long. Try /new to start fresh or /undo to remove recent turns.",
|
|
331
|
+
authFailed: "Authentication failed. Check your API key.",
|
|
332
|
+
paymentRequired: "Payment required. Check your account balance.",
|
|
333
|
+
serverError: "Server error. Please try again later.",
|
|
334
|
+
cancelled: "Operation cancelled by user."
|
|
335
|
+
},
|
|
336
|
+
agent: {
|
|
337
|
+
thinking: "Thinking...",
|
|
338
|
+
executing: "Executing {{tool}}...",
|
|
339
|
+
reading: "Reading {{file}}...",
|
|
340
|
+
writing: "Writing {{file}}...",
|
|
341
|
+
searching: "Searching...",
|
|
342
|
+
toolSuccess: "{{tool}} completed successfully",
|
|
343
|
+
toolFailed: "{{tool}} failed: {{error}}",
|
|
344
|
+
taskComplete: "Task complete",
|
|
345
|
+
noChanges: "No changes were made.",
|
|
346
|
+
changesApplied: "Changes applied successfully.",
|
|
347
|
+
awaitingApproval: "Awaiting approval...",
|
|
348
|
+
approved: "Approved",
|
|
349
|
+
denied: "Denied",
|
|
350
|
+
skipped: "Skipped",
|
|
351
|
+
exploring: "Exploring...",
|
|
352
|
+
exploredFiles: "Explored {{count}} files"
|
|
353
|
+
},
|
|
354
|
+
providers: {
|
|
355
|
+
openrouter: "OpenRouter",
|
|
356
|
+
openai: "OpenAI",
|
|
357
|
+
ollama: "Ollama",
|
|
358
|
+
llamacpp: "llama.cpp",
|
|
359
|
+
mlx: "MLX (Apple Silicon)",
|
|
360
|
+
hints: {
|
|
361
|
+
openrouter: "Cloud - Access to 100+ models (Claude, GPT-4, etc.)",
|
|
362
|
+
openai: "Cloud - Official OpenAI models (GPT-4o, o1, etc.)",
|
|
363
|
+
ollama: "Local - Run models on your machine (free)",
|
|
364
|
+
llamacpp: "Local - Fast inference with GGUF models",
|
|
365
|
+
mlx: "Local - Optimized for Apple Silicon Macs"
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
startup: {
|
|
369
|
+
checkingTools: "Checking required tools...",
|
|
370
|
+
toolFound: "{{tool}} found",
|
|
371
|
+
toolMissing: "{{tool}} not found",
|
|
372
|
+
installHint: "Install with: {{command}}",
|
|
373
|
+
allToolsReady: "All tools ready!",
|
|
374
|
+
someToolsMissing: "Some tools are missing. Some features may not work."
|
|
375
|
+
},
|
|
376
|
+
confirmation: {
|
|
377
|
+
proceed: "Proceed?",
|
|
378
|
+
areYouSure: "Are you sure?",
|
|
379
|
+
thisWillDelete: "This will delete {{item}}. This action cannot be undone.",
|
|
380
|
+
confirm: "Confirm",
|
|
381
|
+
cancel: "Cancel",
|
|
382
|
+
yesDelete: "Yes, delete",
|
|
383
|
+
noDontDelete: "No, keep it"
|
|
384
|
+
},
|
|
385
|
+
diff: {
|
|
386
|
+
title: "Changes to {{file}}",
|
|
387
|
+
additions: "{{count}} additions",
|
|
388
|
+
deletions: "{{count}} deletions",
|
|
389
|
+
noChanges: "No changes",
|
|
390
|
+
apply: "Apply changes?",
|
|
391
|
+
applied: "Changes applied.",
|
|
392
|
+
discarded: "Changes discarded."
|
|
393
|
+
},
|
|
394
|
+
languages: {
|
|
395
|
+
en: "English",
|
|
396
|
+
"zh-cn": "\u7B80\u4F53\u4E2D\u6587 (Simplified Chinese)",
|
|
397
|
+
"zh-tw": "\u7E41\u9AD4\u4E2D\u6587 (Traditional Chinese)",
|
|
398
|
+
fr: "Fran\xE7ais (French)",
|
|
399
|
+
de: "Deutsch (German)",
|
|
400
|
+
it: "Italiano (Italian)",
|
|
401
|
+
es: "Espa\xF1ol (Spanish)",
|
|
402
|
+
ja: "\u65E5\u672C\u8A9E (Japanese)",
|
|
403
|
+
ko: "\uD55C\uAD6D\uC5B4 (Korean)",
|
|
404
|
+
ru: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)",
|
|
405
|
+
"pt-br": "Portugu\xEAs (Brazilian Portuguese)",
|
|
406
|
+
tr: "T\xFCrk\xE7e (Turkish)",
|
|
407
|
+
pl: "Polski (Polish)",
|
|
408
|
+
cs: "\u010Ce\u0161tina (Czech)",
|
|
409
|
+
hu: "Magyar (Hungarian)",
|
|
410
|
+
hi: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)"
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// src/i18n/localeDetector.ts
|
|
415
|
+
import { execSync } from "child_process";
|
|
416
|
+
var SUPPORTED_LOCALES = [
|
|
417
|
+
"en",
|
|
418
|
+
"zh-cn",
|
|
419
|
+
"zh-tw",
|
|
420
|
+
"fr",
|
|
421
|
+
"de",
|
|
422
|
+
"it",
|
|
423
|
+
"es",
|
|
424
|
+
"ja",
|
|
425
|
+
"ko",
|
|
426
|
+
"ru",
|
|
427
|
+
"pt-br",
|
|
428
|
+
"tr",
|
|
429
|
+
"pl",
|
|
430
|
+
"cs",
|
|
431
|
+
"hu",
|
|
432
|
+
"hi"
|
|
433
|
+
];
|
|
434
|
+
var LANGUAGE_DISPLAY_NAMES = {
|
|
435
|
+
en: "English",
|
|
436
|
+
"zh-cn": "\u7B80\u4F53\u4E2D\u6587 (Simplified Chinese)",
|
|
437
|
+
"zh-tw": "\u7E41\u9AD4\u4E2D\u6587 (Traditional Chinese)",
|
|
438
|
+
fr: "Fran\xE7ais (French)",
|
|
439
|
+
de: "Deutsch (German)",
|
|
440
|
+
it: "Italiano (Italian)",
|
|
441
|
+
es: "Espa\xF1ol (Spanish)",
|
|
442
|
+
ja: "\u65E5\u672C\u8A9E (Japanese)",
|
|
443
|
+
ko: "\uD55C\uAD6D\uC5B4 (Korean)",
|
|
444
|
+
ru: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)",
|
|
445
|
+
"pt-br": "Portugu\xEAs (Brazilian Portuguese)",
|
|
446
|
+
tr: "T\xFCrk\xE7e (Turkish)",
|
|
447
|
+
pl: "Polski (Polish)",
|
|
448
|
+
cs: "\u010Ce\u0161tina (Czech)",
|
|
449
|
+
hu: "Magyar (Hungarian)",
|
|
450
|
+
hi: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)"
|
|
451
|
+
};
|
|
452
|
+
function detectOSLocale() {
|
|
453
|
+
const platform = process.platform;
|
|
454
|
+
const envLocale = process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG || process.env.LANGUAGE;
|
|
455
|
+
if (envLocale) {
|
|
456
|
+
return envLocale;
|
|
457
|
+
}
|
|
458
|
+
try {
|
|
459
|
+
if (platform === "darwin") {
|
|
460
|
+
const result = execSync("defaults read -g AppleLocale", {
|
|
461
|
+
encoding: "utf8",
|
|
462
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
463
|
+
}).trim();
|
|
464
|
+
return result;
|
|
465
|
+
}
|
|
466
|
+
if (platform === "win32") {
|
|
467
|
+
const result = execSync('powershell -NoProfile -Command "(Get-Culture).Name"', {
|
|
468
|
+
encoding: "utf8",
|
|
469
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
470
|
+
}).trim();
|
|
471
|
+
return result;
|
|
472
|
+
}
|
|
473
|
+
if (platform === "linux") {
|
|
474
|
+
try {
|
|
475
|
+
const result = execSync("localectl status", {
|
|
476
|
+
encoding: "utf8",
|
|
477
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
478
|
+
});
|
|
479
|
+
const match = result.match(/LANG=([^\n]+)/);
|
|
480
|
+
if (match) return match[1];
|
|
481
|
+
} catch {
|
|
482
|
+
try {
|
|
483
|
+
const result = execSync("locale", {
|
|
484
|
+
encoding: "utf8",
|
|
485
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
486
|
+
});
|
|
487
|
+
const match = result.match(/LANG="?([^"\n]+)"?/);
|
|
488
|
+
if (match) return match[1];
|
|
489
|
+
} catch {
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
} catch {
|
|
494
|
+
}
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
function normalizeLocale(rawLocale) {
|
|
498
|
+
let locale = rawLocale.split(".")[0].toLowerCase();
|
|
499
|
+
locale = locale.replace("_", "-");
|
|
500
|
+
const mappings = {
|
|
501
|
+
"zh-hans": "zh-cn",
|
|
502
|
+
"zh-hant": "zh-tw",
|
|
503
|
+
zh: "zh-cn",
|
|
504
|
+
pt: "pt-br",
|
|
505
|
+
nb: "en",
|
|
506
|
+
// Norwegian Bokmal -> fallback
|
|
507
|
+
nn: "en"
|
|
508
|
+
// Norwegian Nynorsk -> fallback
|
|
509
|
+
};
|
|
510
|
+
if (SUPPORTED_LOCALES.includes(locale)) {
|
|
511
|
+
return locale;
|
|
512
|
+
}
|
|
513
|
+
if (mappings[locale]) {
|
|
514
|
+
return mappings[locale];
|
|
515
|
+
}
|
|
516
|
+
const baseLang = locale.split("-")[0];
|
|
517
|
+
if (SUPPORTED_LOCALES.includes(baseLang)) {
|
|
518
|
+
return baseLang;
|
|
519
|
+
}
|
|
520
|
+
if (baseLang === "zh") {
|
|
521
|
+
return "zh-cn";
|
|
522
|
+
}
|
|
523
|
+
return "en";
|
|
524
|
+
}
|
|
525
|
+
function detectLocale(options) {
|
|
526
|
+
if (options?.cliOverride) {
|
|
527
|
+
const normalized = normalizeLocale(options.cliOverride);
|
|
528
|
+
return { locale: normalized, source: "cli", rawLocale: options.cliOverride };
|
|
529
|
+
}
|
|
530
|
+
if (options?.configLocale) {
|
|
531
|
+
const normalized = normalizeLocale(options.configLocale);
|
|
532
|
+
return { locale: normalized, source: "config", rawLocale: options.configLocale };
|
|
533
|
+
}
|
|
534
|
+
const envLocale = process.env.AUTOHAND_LOCALE || process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG;
|
|
535
|
+
if (envLocale) {
|
|
536
|
+
const normalized = normalizeLocale(envLocale);
|
|
537
|
+
return { locale: normalized, source: "env", rawLocale: envLocale };
|
|
538
|
+
}
|
|
539
|
+
const osLocale = detectOSLocale();
|
|
540
|
+
if (osLocale) {
|
|
541
|
+
const normalized = normalizeLocale(osLocale);
|
|
542
|
+
return { locale: normalized, source: "os", rawLocale: osLocale };
|
|
543
|
+
}
|
|
544
|
+
return { locale: "en", source: "fallback" };
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// src/i18n/llmLocale.ts
|
|
548
|
+
var LANGUAGE_NAMES_FOR_LLM = {
|
|
549
|
+
en: "English",
|
|
550
|
+
"zh-cn": "Simplified Chinese (\u7B80\u4F53\u4E2D\u6587)",
|
|
551
|
+
"zh-tw": "Traditional Chinese (\u7E41\u9AD4\u4E2D\u6587)",
|
|
552
|
+
fr: "French (Fran\xE7ais)",
|
|
553
|
+
de: "German (Deutsch)",
|
|
554
|
+
it: "Italian (Italiano)",
|
|
555
|
+
es: "Spanish (Espa\xF1ol)",
|
|
556
|
+
ja: "Japanese (\u65E5\u672C\u8A9E)",
|
|
557
|
+
ko: "Korean (\uD55C\uAD6D\uC5B4)",
|
|
558
|
+
ru: "Russian (\u0420\u0443\u0441\u0441\u043A\u0438\u0439)",
|
|
559
|
+
"pt-br": "Brazilian Portuguese (Portugu\xEAs)",
|
|
560
|
+
tr: "Turkish (T\xFCrk\xE7e)",
|
|
561
|
+
pl: "Polish (Polski)",
|
|
562
|
+
cs: "Czech (\u010Ce\u0161tina)",
|
|
563
|
+
hu: "Hungarian (Magyar)",
|
|
564
|
+
hi: "Hindi (\u0939\u093F\u0928\u094D\u0926\u0940)"
|
|
565
|
+
};
|
|
566
|
+
function buildLocaleInstruction(locale) {
|
|
567
|
+
if (locale === "en") {
|
|
568
|
+
return "";
|
|
569
|
+
}
|
|
570
|
+
const languageName = LANGUAGE_NAMES_FOR_LLM[locale];
|
|
571
|
+
return `
|
|
572
|
+
## Response Language Preference
|
|
573
|
+
|
|
574
|
+
The user has configured their preferred language as **${languageName}**.
|
|
575
|
+
|
|
576
|
+
Please respond in ${languageName} when providing:
|
|
577
|
+
- Explanations and descriptions
|
|
578
|
+
- Summaries and overviews
|
|
579
|
+
- Conversational responses
|
|
580
|
+
- Error explanations
|
|
581
|
+
- Suggestions and recommendations
|
|
582
|
+
|
|
583
|
+
**Keep the following in their original form (usually English):**
|
|
584
|
+
- Code snippets and examples
|
|
585
|
+
- File paths and directory names
|
|
586
|
+
- Command names and CLI flags
|
|
587
|
+
- Technical identifiers (function names, variables, etc.)
|
|
588
|
+
- JSON output format and tool call parameters
|
|
589
|
+
- Error messages from tools (but you may add translated explanations)
|
|
590
|
+
|
|
591
|
+
**Code comments:** If the project already uses ${languageName} comments, continue in ${languageName}. Otherwise, use English for consistency with the codebase.
|
|
592
|
+
`;
|
|
593
|
+
}
|
|
594
|
+
function injectLocaleIntoPrompt(systemPrompt, locale) {
|
|
595
|
+
const localeInstruction = buildLocaleInstruction(locale);
|
|
596
|
+
if (!localeInstruction) {
|
|
597
|
+
return systemPrompt;
|
|
598
|
+
}
|
|
599
|
+
return systemPrompt + "\n" + localeInstruction;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// src/i18n/index.ts
|
|
603
|
+
var resources = {
|
|
604
|
+
en: { translation: en_default },
|
|
605
|
+
// These will use en.json as fallback until translations are generated
|
|
606
|
+
"zh-cn": { translation: en_default },
|
|
607
|
+
"zh-tw": { translation: en_default },
|
|
608
|
+
fr: { translation: en_default },
|
|
609
|
+
de: { translation: en_default },
|
|
610
|
+
it: { translation: en_default },
|
|
611
|
+
es: { translation: en_default },
|
|
612
|
+
ja: { translation: en_default },
|
|
613
|
+
ko: { translation: en_default },
|
|
614
|
+
ru: { translation: en_default },
|
|
615
|
+
"pt-br": { translation: en_default },
|
|
616
|
+
tr: { translation: en_default },
|
|
617
|
+
pl: { translation: en_default },
|
|
618
|
+
cs: { translation: en_default },
|
|
619
|
+
hu: { translation: en_default },
|
|
620
|
+
hi: { translation: en_default }
|
|
621
|
+
};
|
|
622
|
+
var currentLocale = "en";
|
|
623
|
+
var initialized = false;
|
|
624
|
+
async function initI18n(locale) {
|
|
625
|
+
currentLocale = locale;
|
|
626
|
+
await i18next.init({
|
|
627
|
+
lng: locale,
|
|
628
|
+
fallbackLng: "en",
|
|
629
|
+
resources,
|
|
630
|
+
interpolation: {
|
|
631
|
+
escapeValue: false
|
|
632
|
+
// Not needed for CLI (no XSS risk)
|
|
633
|
+
},
|
|
634
|
+
// Support nested keys like 'commands.help.title'
|
|
635
|
+
keySeparator: ".",
|
|
636
|
+
nsSeparator: ":",
|
|
637
|
+
// Return key if translation missing (for debugging)
|
|
638
|
+
returnNull: false,
|
|
639
|
+
returnEmptyString: false
|
|
640
|
+
});
|
|
641
|
+
initialized = true;
|
|
642
|
+
}
|
|
643
|
+
async function changeLanguage(locale) {
|
|
644
|
+
currentLocale = locale;
|
|
645
|
+
await i18next.changeLanguage(locale);
|
|
646
|
+
}
|
|
647
|
+
function getCurrentLocale() {
|
|
648
|
+
return currentLocale;
|
|
649
|
+
}
|
|
650
|
+
function t(key, options) {
|
|
651
|
+
if (!initialized) {
|
|
652
|
+
console.warn(`[i18n] Not initialized, returning key: ${key}`);
|
|
653
|
+
return key;
|
|
654
|
+
}
|
|
655
|
+
return i18next.t(key, options);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/commands/language.ts
|
|
659
|
+
async function language(ctx) {
|
|
660
|
+
const { Select } = enquirer;
|
|
661
|
+
const currentLocale2 = getCurrentLocale();
|
|
662
|
+
const currentDisplayName = LANGUAGE_DISPLAY_NAMES[currentLocale2];
|
|
663
|
+
console.log(chalk.cyan(`
|
|
664
|
+
\u{1F310} ${t("commands.language.title")}
|
|
665
|
+
`));
|
|
666
|
+
console.log(chalk.gray(`${t("commands.language.currentLanguage", { language: currentDisplayName })}`));
|
|
667
|
+
console.log();
|
|
668
|
+
const choices = SUPPORTED_LOCALES.map((locale) => ({
|
|
669
|
+
name: locale,
|
|
670
|
+
message: locale === currentLocale2 ? `${LANGUAGE_DISPLAY_NAMES[locale]} (${t("common.current")})` : LANGUAGE_DISPLAY_NAMES[locale]
|
|
671
|
+
}));
|
|
672
|
+
try {
|
|
673
|
+
const prompt = new Select({
|
|
674
|
+
name: "locale",
|
|
675
|
+
message: t("commands.language.selectPrompt"),
|
|
676
|
+
choices,
|
|
677
|
+
initial: SUPPORTED_LOCALES.indexOf(currentLocale2)
|
|
678
|
+
});
|
|
679
|
+
const selected = await prompt.run();
|
|
680
|
+
if (selected === currentLocale2) {
|
|
681
|
+
console.log(chalk.gray(`
|
|
682
|
+
${t("commands.language.noChange")}`));
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
await changeLanguage(selected);
|
|
686
|
+
ctx.config.ui = { ...ctx.config.ui, locale: selected };
|
|
687
|
+
await saveConfig(ctx.config);
|
|
688
|
+
const newDisplayName = LANGUAGE_DISPLAY_NAMES[selected];
|
|
689
|
+
console.log(chalk.green(`
|
|
690
|
+
\u2713 ${t("commands.language.changed", { language: newDisplayName })}`));
|
|
691
|
+
console.log(chalk.gray(`
|
|
692
|
+
${t("commands.language.restartHint")}`));
|
|
693
|
+
console.log();
|
|
694
|
+
return null;
|
|
695
|
+
} catch {
|
|
696
|
+
console.log(chalk.gray("\nLanguage selection cancelled."));
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
async function languageInfo() {
|
|
701
|
+
const currentLocale2 = getCurrentLocale();
|
|
702
|
+
const currentDisplayName = LANGUAGE_DISPLAY_NAMES[currentLocale2];
|
|
703
|
+
console.log(chalk.cyan(`
|
|
704
|
+
\u{1F310} ${t("commands.language.title")}
|
|
705
|
+
`));
|
|
706
|
+
console.log(chalk.gray(`${t("commands.language.currentLanguage", { language: currentDisplayName })}`));
|
|
707
|
+
console.log(chalk.gray(`Locale code: ${chalk.white(currentLocale2)}`));
|
|
708
|
+
console.log();
|
|
709
|
+
console.log(chalk.gray("Supported languages:"));
|
|
710
|
+
for (const locale of SUPPORTED_LOCALES) {
|
|
711
|
+
const marker = locale === currentLocale2 ? chalk.green("\u25CF") : chalk.gray("\u25CB");
|
|
712
|
+
console.log(` ${marker} ${LANGUAGE_DISPLAY_NAMES[locale]}`);
|
|
713
|
+
}
|
|
714
|
+
console.log();
|
|
715
|
+
return null;
|
|
716
|
+
}
|
|
717
|
+
var metadata = {
|
|
718
|
+
command: "/language",
|
|
719
|
+
description: "change display language",
|
|
720
|
+
implemented: true
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
export {
|
|
724
|
+
detectLocale,
|
|
725
|
+
injectLocaleIntoPrompt,
|
|
726
|
+
initI18n,
|
|
727
|
+
getCurrentLocale,
|
|
728
|
+
language,
|
|
729
|
+
languageInfo,
|
|
730
|
+
metadata
|
|
731
|
+
};
|
|
732
|
+
/**
|
|
733
|
+
* @license
|
|
734
|
+
* Copyright 2025 Autohand AI LLC
|
|
735
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
736
|
+
*/
|