git-clone-resume 0.1.2 → 0.1.3

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.en.md ADDED
@@ -0,0 +1,69 @@
1
+ # Git Clone Resume for Windows
2
+
3
+ Resume-friendly partial cloning for GitHub and other unstable networks. The tool fetches commit/tree metadata first, then checks out files in batches. Run the same command again after an interruption to resume.
4
+
5
+ ## Requirements
6
+
7
+ - Git for Windows >= 2.19
8
+ - Windows PowerShell 5.1 or PowerShell 7+
9
+ - Optional: `git config --global core.longpaths true`
10
+
11
+ ## Install
12
+
13
+ Install from npm:
14
+
15
+ ```powershell
16
+ npm install -g git-clone-resume
17
+ gcr https://github.com/user/repo.git
18
+ ```
19
+
20
+ The package still requires Git for Windows and PowerShell. Release ZIP packages contain both `gcr` and `git-clone-resume` launchers.
21
+
22
+ ## Usage
23
+
24
+ Start the fullscreen wizard without a URL, or pass a URL directly:
25
+
26
+ ```bat
27
+ git-clone-resume.cmd
28
+ git-clone-resume.cmd https://github.com/user/repo.git
29
+ ```
30
+
31
+ PowerShell users can call the script directly:
32
+
33
+ ```powershell
34
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -Ref main -OutDir D:\src\repo
35
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -Include src/*,docs/* -Exclude *.bin
36
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -BatchSize 64 -MaxRetries 12
37
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -Verify
38
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -DryRun
39
+ ```
40
+
41
+ Use `-NoTui` in CI or when output is redirected. Use `-Tui` to force the fullscreen interface.
42
+
43
+ ## Language
44
+
45
+ On the first wizard screen, select `Language` and choose Chinese or English. Press `L` in the wizard or progress panel to switch at any time. The command-line equivalent is:
46
+
47
+ ```powershell
48
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -Language en-US
49
+ .\git-clone-resume.ps1 https://github.com/user/repo.git -Language zh-CN
50
+ ```
51
+
52
+ ## Resume State
53
+
54
+ Progress is stored outside the worktree in `.git/partial-resume/`. Do not delete the target repository's `.git` directory. Completed files are skipped on subsequent runs; failed files are retried.
55
+
56
+ The tool skips submodule gitlinks. Run it separately for submodules. After checking out Git LFS files, run `git lfs pull` if actual LFS content is needed.
57
+
58
+ ## TUI Keys
59
+
60
+ - `Q` / `Ctrl+C`: stop after the current Git command; press again to force stop
61
+ - `P` / `Esc`: pause after the current batch
62
+ - `Space`: resume from pause
63
+ - `F`: show failed files
64
+ - `L`: switch language
65
+ - `Up` / `Down` / `j` / `k`: scroll activity
66
+ - `?` / `H`: show help
67
+ - `Enter`: close the result screen
68
+
69
+ See the Chinese guide in [README.md](README.md) for the full implementation details and release channels.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Git 断点续传克隆(Windows)
2
2
 
3
+ English documentation: [README.en.md](README.en.md). 启动向导时可选择语言,也可使用 `-Language en-US`;向导和克隆面板中按 `L` 可随时切换。
4
+
3
5
  针对 GitHub 等网络不稳定场景:先用 **partial clone** 只拉 commit/tree 元数据,再 **按批 checkout 文件**。中断后用同一条命令再跑即可续传。
4
6
 
5
7
  对应 Linux 参考脚本:<https://github.com/chaihahaha/git-cheatsheet> 中的 `clone_1by1.sh`。
@@ -105,6 +105,9 @@ param(
105
105
 
106
106
  [switch]$NoTui,
107
107
 
108
+ [ValidateSet("zh-CN", "en-US")]
109
+ [string]$Language = "zh-CN",
110
+
108
111
  [switch]$ResumeLast,
109
112
 
110
113
  [switch]$Help
@@ -133,6 +136,57 @@ $script:StateDirName = "partial-resume"
133
136
  $script:GcrTuiWanted = $false
134
137
  $script:GcrExitCode = 0
135
138
  $script:GcrUserStop = $false
139
+ $script:GcrLanguage = $Language
140
+
141
+ function Convert-GcrText {
142
+ param([AllowNull()][string]$Text)
143
+ if ($null -eq $Text -or $script:GcrLanguage -ne "en-US") { return $Text }
144
+ $pairs = @(
145
+ @("未找到 git。请先安装 Git for Windows", "Git was not found. Install Git for Windows"),
146
+ @("错误:", "Error:"), @("必须提供仓库 URL。", "A repository URL is required."),
147
+ @("无法读取历史记录。", "Could not read history."),
148
+ @("没有可恢复的历史记录。请先启动过一次克隆。", "No resumable history was found. Start a clone first."),
149
+ @("向导失败:", "Wizard failed:"), @("无法开始克隆", "Could not start clone"),
150
+ @("当前终端无法进入全屏 TUI,改用日志模式。Windows Terminal 下再试,或去掉 -Tui。", "This terminal cannot enter fullscreen TUI; using log mode. Try Windows Terminal or remove -Tui."),
151
+ @("已由用户停止。", "Stopped by user."), @("再次运行同一命令即可续传。", "Run the same command again to resume."),
152
+ @("使用 ", "Using "), @("仓库:", "Repository:"), @("目录:", "Directory:"), @("引用:", "Ref:"),
153
+ @("语言", "Language"), @("中文", "Chinese"), @("英文", "English"), @("开", "On"), @("关", "Off"),
154
+ @("目标 commit:", "Target commit:"), @("fetch 元数据:", "Fetching metadata:"), @("枚举文件树", "Enumerating file tree"),
155
+ @("树中条目:", "Tree entries:"), @("待处理文件:", "Pending files:"), @("工作区:", "Workspace:"),
156
+ @("全部文件已就绪。", "All files are ready."), @("完成", "Complete"), @("克隆完成", "Clone complete"),
157
+ @("部分文件失败", "Some files failed"), @("失败列表:", "Failure list:"), @("仍失败:", "Still failed:"),
158
+ @("批次", "Batch"), @("失败", "failed"), @("单文件失败:", "Single-file failure:"), @("出错", "Error"),
159
+ @("已停止", "Stopped"), @("中断后续传: ", "Resume after interruption: "), @("仓库目录:", "Repository directory:"),
160
+ @("文件数:", "Files:"), @("清单文件:", "List file:"), @("DryRun 完成", "DryRun complete"),
161
+ @("未下载 blob。去掉 -DryRun 后开始/继续克隆。", "No blobs were downloaded. Remove -DryRun to start or resume."),
162
+ @("检查工作区已有文件", "Checking existing workspace files"), @("进度: 已记录", "Progress: recorded"),
163
+ @("分 ", "Downloading in "), @(" 批下载,每批最多 ", " batches, up to "), @(" 个文件", " files each"),
164
+ @("跳过", "Skipped"), @("个子模块(gitlink)。需要的话请在对应目录单独再跑本脚本。", " submodules (gitlinks). Run this script separately if needed.")
165
+ ,@("断点续传克隆", "Resumable clone"), @("按批 checkout", "batch checkout"), @("刚刚", "just now"),
166
+ @("分钟前", " minutes ago"), @("小时前", " hours ago"), @("天前", " days ago"),
167
+ @("就绪", "Ready"), @("设置", "Setup"), @("初始化仓库", "Initialize repository"), @("拉取元数据", "Fetch metadata"),
168
+ @("枚举文件树", "List file tree"), @("扫描已有文件", "Scan existing files"), @("下载文件", "Download files"),
169
+ @("修复 git index", "Repair git index"), @("快捷键说明。任意键关闭此帮助。", "Keyboard help. Press any key to close."),
170
+ @("失败文件列表。F 返回活动日志,再次运行同一命令会重试。", "Failed files. Press F to return; run the same command to retry."),
171
+ @("本次运行已结束。Enter 关闭界面,进度保留在 .git/partial-resume/。", "This run has ended. Press Enter to close; progress remains in .git/partial-resume/."),
172
+ @("已暂停:当前批次结束后停住。Space 继续,Q 停止。", "Paused after the current batch. Space resumes; Q stops."),
173
+ @("全部完成。工作区已可用。", "Everything is complete. The workspace is ready."),
174
+ @("出错或未完成。重新运行同一命令即可从断点继续。", "Failed or incomplete. Run the same command to resume."),
175
+ @("远程仓库地址,支持 https、ssh、git@ 以及本地路径。Ctrl+V 从剪贴板粘贴。", "Remote repository URL. Supports https, ssh, git@, and local paths. Ctrl+V pastes from the clipboard."),
176
+ @("工作区目录。留空则用仓库名。已有 .git/partial-resume 时自动续传。", "Workspace directory. Leave empty to use the repository name. Existing .git/partial-resume state resumes automatically."),
177
+ @("选择界面语言。可随时按 L 在中文和英文之间切换。", "Interface language. Press L at any time to switch between Chinese and English."),
178
+ @("最近任务", "Recent tasks"), @("切换", "switch"), @("填入", "fill in"), @("无。完成一次克隆后会出现在这里", "None. Completed clones appear here"),
179
+ @("Enter 编辑/开始", "Enter edit/start"), @("Space 开关", "Space toggle"), @("改批次", "change batch"), @("粘贴", "paste"), @("退出", "quit"),
180
+ @("按上面的设置开始或继续克隆。Enter 启动。中断后重跑即可续传。", "Start or resume with the settings above. Press Enter to begin; rerun after interruption."),
181
+ @("请填写仓库 URL(Ctrl+V 可从剪贴板粘贴)", "Enter a repository URL (Ctrl+V pastes from the clipboard)"),
182
+ @("语言", "Language"), @("中文", "Chinese"), @("英文", "English")
183
+ ,@(" 仓库 ", " Repository "), @(" 目录 ", " Directory "), @(" 引用 ", " Ref "), @(" 阶段 ", " Phase "), @(" 当前 ", " Current "),
184
+ @("键盘", "Keyboard"), @("暂无失败文件。", "No failed files."), @("停止", "stop"), @("暂停", "pause"), @("帮助", "help"), @("日志", "log")
185
+ )
186
+ $result = $Text
187
+ foreach ($pair in $pairs) { $result = $result.Replace([string]$pair[0], [string]$pair[1]) }
188
+ return $result
189
+ }
136
190
 
137
191
  $script:GcrTuiFile = Join-Path $PSScriptRoot "git-clone-resume.tui.ps1"
138
192
  if (-not $PSScriptRoot) {
@@ -173,6 +227,7 @@ function Write-Log {
173
227
  elseif ($Message -is [System.Array]) { $text = (@($Message | ForEach-Object { "$_" }) -join " ") }
174
228
  else { $text = [string]$Message }
175
229
  } catch { $text = "$Message" }
230
+ $text = Convert-GcrText $text
176
231
  $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
177
232
  $color = switch ($Level) {
178
233
  "INFO" { "Gray" }
@@ -218,6 +273,7 @@ function Show-Usage {
218
273
  Write-Host " -DryRun List files, do not checkout blobs"
219
274
  Write-Host " -Tui Force fullscreen TUI"
220
275
  Write-Host " -NoTui Disable TUI (script/CI mode)"
276
+ Write-Host " -Language zh-CN|en-US User interface language"
221
277
  Write-Host " -ResumeLast Resume the latest history entry"
222
278
  Write-Host " -Help Show this help"
223
279
  Write-Host ""
@@ -966,12 +1022,12 @@ if ($NoTui) {
966
1022
 
967
1023
  if ($ResumeLast) {
968
1024
  if (-not (Get-Command Get-GcrHistoryLast -ErrorAction SilentlyContinue)) {
969
- Write-Host "错误: 无法读取历史记录。" -ForegroundColor Red
1025
+ Write-Host (Convert-GcrText "错误: 无法读取历史记录。") -ForegroundColor Red
970
1026
  exit 2
971
1027
  }
972
1028
  $last = Get-GcrHistoryLast
973
1029
  if ($null -eq $last) {
974
- Write-Host "错误: 没有可恢复的历史记录。请先启动过一次克隆。" -ForegroundColor Red
1030
+ Write-Host (Convert-GcrText "错误: 没有可恢复的历史记录。请先启动过一次克隆。") -ForegroundColor Red
975
1031
  exit 2
976
1032
  }
977
1033
  if ([string]::IsNullOrWhiteSpace($RepoUrl) -and $last.url) { $RepoUrl = [string]$last.url }
@@ -982,7 +1038,7 @@ if ($ResumeLast) {
982
1038
  if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
983
1039
  if ($NoTui -or -not $script:GcrInteractive) {
984
1040
  Show-Usage
985
- Write-Host "错误: 必须提供仓库 URL。" -ForegroundColor Red
1041
+ Write-Host (Convert-GcrText "错误: 必须提供仓库 URL。") -ForegroundColor Red
986
1042
  exit 2
987
1043
  }
988
1044
  $defaults = @{
@@ -1000,7 +1056,7 @@ if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
1000
1056
  if ($PSBoundParameters.ContainsKey("Depth")) { $defaults["Depth"] = $Depth }
1001
1057
  if (-not (Get-Command Show-GcrInteractiveSetup -ErrorAction SilentlyContinue)) {
1002
1058
  Show-Usage
1003
- Write-Host "错误: 必须提供仓库 URL。" -ForegroundColor Red
1059
+ Write-Host (Convert-GcrText "错误: 必须提供仓库 URL。") -ForegroundColor Red
1004
1060
  exit 2
1005
1061
  }
1006
1062
  $wiz = $null
@@ -1021,6 +1077,9 @@ if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
1021
1077
  }
1022
1078
  try {
1023
1079
  $RepoUrl = [string]$wiz.RepoUrl
1080
+ if ($wiz.Language -eq "en-US" -or $wiz.Language -eq "zh-CN") {
1081
+ $script:GcrLanguage = [string]$wiz.Language
1082
+ }
1024
1083
  if ($wiz.OutDir) { $OutDir = [string]$wiz.OutDir }
1025
1084
  if ($wiz.Ref) { $Ref = [string]$wiz.Ref }
1026
1085
  if ($wiz.BatchSize) { $BatchSize = [int]$wiz.BatchSize }
@@ -1048,14 +1107,14 @@ if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
1048
1107
  if ([string]::IsNullOrWhiteSpace($RepoUrl)) {
1049
1108
  if (Get-Command Close-GcrTui -ErrorAction SilentlyContinue) { Close-GcrTui }
1050
1109
  Show-Usage
1051
- Write-Host "错误: 必须提供仓库 URL。" -ForegroundColor Red
1110
+ Write-Host (Convert-GcrText "错误: 必须提供仓库 URL。") -ForegroundColor Red
1052
1111
  exit 2
1053
1112
  }
1054
1113
 
1055
1114
  if ($script:GcrTuiWanted -and (Get-Command Initialize-GcrTui -ErrorAction SilentlyContinue)) {
1056
1115
  if (-not (Test-GcrTuiActive)) { [void](Initialize-GcrTui) }
1057
1116
  if ($Tui -and -not (Test-GcrTuiActive)) {
1058
- Write-Host "当前终端无法进入全屏 TUI,改用日志模式。Windows Terminal 下再试,或去掉 -Tui。" -ForegroundColor Yellow
1117
+ Write-Host (Convert-GcrText "当前终端无法进入全屏 TUI,改用日志模式。Windows Terminal 下再试,或去掉 -Tui。") -ForegroundColor Yellow
1059
1118
  }
1060
1119
  }
1061
1120
 
@@ -752,6 +752,10 @@ function Invoke-GcrTuiKey {
752
752
  $script:GcrTui.Dirty = $true
753
753
  }
754
754
  "H" { $script:GcrTui.Help = $true; $script:GcrTui.Dirty = $true }
755
+ "L" {
756
+ $script:GcrLanguage = $(if ($script:GcrLanguage -eq "en-US") { "zh-CN" } else { "en-US" })
757
+ $script:GcrTui.Dirty = $true
758
+ }
755
759
  "F" { $script:GcrTui.FailView = -not $script:GcrTui.FailView; $script:GcrTui.Dirty = $true }
756
760
  "UpArrow" {
757
761
  $script:GcrTui.LogOffset = [Math]::Min($script:GcrTui.Logs.Count, $script:GcrTui.LogOffset + 1)
@@ -902,6 +906,8 @@ function Render-GcrTui {
902
906
  function Push-GcrRow {
903
907
  param([string]$Left, [string]$Right = "", [string]$Color = "")
904
908
  if (-not $Color) { $Color = $c.W }
909
+ $Left = Convert-GcrText $Left
910
+ $Right = Convert-GcrText $Right
905
911
  $leftW = Get-GcrDisplayWidth $Left
906
912
  $rightW = Get-GcrDisplayWidth $Right
907
913
  $gap = $inner - $leftW - $rightW
@@ -1210,6 +1216,7 @@ function Convert-GcrWizardResult {
1210
1216
  Add-Member -InputObject $obj -NotePropertyName Verify -NotePropertyValue ([bool]$St.Verify)
1211
1217
  Add-Member -InputObject $obj -NotePropertyName ForceRefetch -NotePropertyValue ([bool]$St.ForceRefetch)
1212
1218
  Add-Member -InputObject $obj -NotePropertyName DryRun -NotePropertyValue ([bool]$St.DryRun)
1219
+ Add-Member -InputObject $obj -NotePropertyName Language -NotePropertyValue ([string]$St.Language)
1213
1220
  return ,$obj
1214
1221
  }
1215
1222
 
@@ -1256,6 +1263,7 @@ function Render-GcrTuiWizard {
1256
1263
  }
1257
1264
  function WRow([string]$Text, [string]$Color, [switch]$Sel) {
1258
1265
  if (-not $Color) { $Color = $c.W }
1266
+ $Text = Convert-GcrText $Text
1259
1267
  $body = Format-GcrCell -Text $Text -Width $inner
1260
1268
  if ($Sel) { $Color = (Get-GcrColor "rev") + $Color }
1261
1269
  $row = $c.D + $box.V + $c.R + $Color + $body + $c.R + $c.D + $box.V + $c.R
@@ -1268,7 +1276,7 @@ function Render-GcrTuiWizard {
1268
1276
  WRow " 断点续传克隆 · partial clone + 按批 checkout" $c.D
1269
1277
  WBorder "mid"
1270
1278
 
1271
- $formEnd = 11
1279
+ $formEnd = 12
1272
1280
  $recent = @($St.Recent)
1273
1281
  $maxFormVisible = [Math]::Max(6, $h - 10)
1274
1282
  if ($maxFormVisible -gt ($formEnd + 1)) { $maxFormVisible = $formEnd + 1 }
@@ -1363,6 +1371,7 @@ function Get-GcrWizardItems {
1363
1371
  @{ Id = "verify"; Kind = "bool"; Label = "哈希校验"; Value = ""; Flag = [bool]$St.Verify; Guide = "续传时对已有文件做 hash-object 校验,哈希不一致则重新下载。Space 开关。" }
1364
1372
  @{ Id = "force"; Kind = "bool"; Label = "强制 refetch"; Value = ""; Flag = [bool]$St.ForceRefetch; Guide = "强制重新 fetch 目标 ref。换分支或更新到最新 commit 时打开。Space 开关。" }
1365
1373
  @{ Id = "dry"; Kind = "bool"; Label = "DryRun"; Value = ""; Flag = [bool]$St.DryRun; Guide = "只列出将要处理的文件,不下载 blob。适合先看清单。Space 开关。" }
1374
+ @{ Id = "language"; Kind = "enum"; Label = "语言"; Value = $(if ($St.Language -eq "en-US") { "英文" } else { "中文" }); Flag = $false; Guide = "选择界面语言。可随时按 L 在中文和英文之间切换。" }
1366
1375
  @{ Id = "start"; Kind = "start"; Label = "开始克隆"; Value = ""; Flag = $false; Guide = "按上面的设置开始或继续克隆。Enter 启动。中断后重跑即可续传。" }
1367
1376
  )
1368
1377
  }
@@ -1374,7 +1383,7 @@ function Apply-GcrRecentToWizard {
1374
1383
  if ($Item.outDir) { $St.OutDir = [string]$Item.outDir; $St.OutDirAuto = $false }
1375
1384
  if ($Item.ref) { $St.Ref = [string]$Item.ref }
1376
1385
  $St.Focus = "form"
1377
- $St.Sel = 11
1386
+ $St.Sel = 12
1378
1387
  }
1379
1388
 
1380
1389
  function Show-GcrTuiWizard {
@@ -1407,6 +1416,7 @@ function Show-GcrTuiWizard {
1407
1416
  OutDir = $dir
1408
1417
  OutDirAuto = $dirAuto
1409
1418
  Ref = $ref
1419
+ Language = $(if ($script:GcrLanguage) { $script:GcrLanguage } else { "zh-CN" })
1410
1420
  BatchSize = $batch
1411
1421
  MaxRetries = $retries
1412
1422
  Include = ""
@@ -1537,7 +1547,7 @@ function Show-GcrTuiWizard {
1537
1547
  "UpArrow" {
1538
1548
  if ($st.Focus -eq "recent") {
1539
1549
  if ($st.RecentSel -gt 0) { $st.RecentSel-- }
1540
- else { $st.Focus = "form"; $st.Sel = 11 }
1550
+ else { $st.Focus = "form"; $st.Sel = 12 }
1541
1551
  } else {
1542
1552
  if ($st.Sel -gt 0) { $st.Sel-- }
1543
1553
  }
@@ -1546,7 +1556,7 @@ function Show-GcrTuiWizard {
1546
1556
  if ($st.Focus -eq "recent") {
1547
1557
  if ($st.RecentSel -lt ($st.Recent.Count - 1)) { $st.RecentSel++ }
1548
1558
  } else {
1549
- if ($st.Sel -lt 11) { $st.Sel++ }
1559
+ if ($st.Sel -lt 12) { $st.Sel++ }
1550
1560
  elseif ($st.Recent.Count -gt 0) { $st.Focus = "recent"; $st.RecentSel = 0 }
1551
1561
  }
1552
1562
  }
@@ -1557,10 +1567,13 @@ function Show-GcrTuiWizard {
1557
1567
  }
1558
1568
  "J" {
1559
1569
  if ($k.KeyChar -eq "j") {
1560
- if ($st.Focus -eq "form" -and $st.Sel -lt 11) { $st.Sel++ }
1570
+ if ($st.Focus -eq "form" -and $st.Sel -lt 12) { $st.Sel++ }
1561
1571
  }
1562
1572
  }
1563
1573
  "LeftArrow" {
1574
+ if ($st.Focus -eq "form" -and $st.Sel -eq 11) {
1575
+ $st.Language = "zh-CN"
1576
+ }
1564
1577
  if ($st.Focus -eq "form" -and $st.Sel -eq 3) {
1565
1578
  $idx = [array]::IndexOf($batches, [int]$st.BatchSize)
1566
1579
  if ($idx -lt 0) { $idx = 2 }
@@ -1573,6 +1586,9 @@ function Show-GcrTuiWizard {
1573
1586
  }
1574
1587
  }
1575
1588
  "RightArrow" {
1589
+ if ($st.Focus -eq "form" -and $st.Sel -eq 11) {
1590
+ $st.Language = "en-US"
1591
+ }
1576
1592
  if ($st.Focus -eq "form" -and $st.Sel -eq 3) {
1577
1593
  $idx = [array]::IndexOf($batches, [int]$st.BatchSize)
1578
1594
  if ($idx -lt 0) { $idx = 2 }
@@ -1589,6 +1605,7 @@ function Show-GcrTuiWizard {
1589
1605
  if ($st.Sel -eq 8) { $st.Verify = -not $st.Verify }
1590
1606
  elseif ($st.Sel -eq 9) { $st.ForceRefetch = -not $st.ForceRefetch }
1591
1607
  elseif ($st.Sel -eq 10) { $st.DryRun = -not $st.DryRun }
1608
+ elseif ($st.Sel -eq 11) { $st.Language = $(if ($st.Language -eq "en-US") { "zh-CN" } else { "en-US" }); $script:GcrLanguage = $st.Language }
1592
1609
  }
1593
1610
  }
1594
1611
  "Enter" {
@@ -1617,6 +1634,7 @@ function Show-GcrTuiWizard {
1617
1634
  } elseif ($id -eq "verify") { $st.Verify = -not $st.Verify }
1618
1635
  elseif ($id -eq "force") { $st.ForceRefetch = -not $st.ForceRefetch }
1619
1636
  elseif ($id -eq "dry") { $st.DryRun = -not $st.DryRun }
1637
+ elseif ($id -eq "language") { $st.Language = $(if ($st.Language -eq "en-US") { "zh-CN" } else { "en-US" }); $script:GcrLanguage = $st.Language }
1620
1638
  elseif ($id -eq "batch" -or $id -eq "retry") { }
1621
1639
  else {
1622
1640
  $st.Edit = $true
@@ -1647,6 +1665,10 @@ function Show-GcrTuiWizard {
1647
1665
  }
1648
1666
  }
1649
1667
  default {
1668
+ if ($k.KeyChar -eq "l" -or $k.KeyChar -eq "L") {
1669
+ $st.Language = $(if ($st.Language -eq "en-US") { "zh-CN" } else { "en-US" })
1670
+ $script:GcrLanguage = $st.Language
1671
+ }
1650
1672
  if ($k.KeyChar -eq "?") { $st.Error = "Enter 编辑 · Space 开关 · Tab 最近任务 · S 开始 · Q 退出" }
1651
1673
  }
1652
1674
  }
@@ -1669,20 +1691,20 @@ function Show-GcrCliWizard {
1669
1691
  }
1670
1692
  $prompt = "仓库 URL"
1671
1693
  if ($pre) { $prompt = "仓库 URL [$pre]" }
1672
- $url = Read-Host $prompt
1694
+ $url = Read-Host (Convert-GcrText $prompt)
1673
1695
  if ([string]::IsNullOrWhiteSpace($url)) { $url = $pre }
1674
1696
  if ([string]::IsNullOrWhiteSpace($url)) { return $null }
1675
1697
  $defDir = Get-GcrFolderNameSafe -Url $url
1676
1698
  if ($Defaults -and $Defaults.ContainsKey("OutDir") -and $Defaults.OutDir) { $defDir = [string]$Defaults.OutDir }
1677
- $dir = Read-Host "本地目录 [$defDir]"
1699
+ $dir = Read-Host (Convert-GcrText "本地目录 [$defDir]")
1678
1700
  if ([string]::IsNullOrWhiteSpace($dir)) { $dir = $defDir }
1679
1701
  $defRef = "HEAD"
1680
1702
  if ($Defaults -and $Defaults.ContainsKey("Ref") -and $Defaults.Ref) { $defRef = [string]$Defaults.Ref }
1681
- $ref = Read-Host "分支/标签/commit [$defRef]"
1703
+ $ref = Read-Host (Convert-GcrText "分支/标签/commit [$defRef]")
1682
1704
  if ([string]::IsNullOrWhiteSpace($ref)) { $ref = $defRef }
1683
1705
  $batch = 32
1684
1706
  if ($Defaults -and $Defaults.ContainsKey("BatchSize") -and $Defaults.BatchSize) { $batch = [int]$Defaults.BatchSize }
1685
- $batchText = Read-Host "每批文件数 [$batch]"
1707
+ $batchText = Read-Host (Convert-GcrText "每批文件数 [$batch]")
1686
1708
  if ($batchText -match "^\d+$") { $batch = [int]$batchText }
1687
1709
  return @{
1688
1710
  RepoUrl = $url.Trim()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-clone-resume",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Resume-friendly partial clone tool for Windows",
5
5
  "bin": {
6
6
  "gcr": "gcr.cmd",
@@ -11,7 +11,8 @@
11
11
  "git-clone-resume.cmd",
12
12
  "git-clone-resume.ps1",
13
13
  "git-clone-resume.tui.ps1",
14
- "README.md"
14
+ "README.md",
15
+ "README.en.md"
15
16
  ],
16
17
  "engines": {
17
18
  "node": ">=16"