dsh-plugin-guide 0.3.29 → 0.3.31

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.
@@ -1,232 +1,232 @@
1
- # 社区插件开发相关仓库全量下载(tarball)脚本
2
- # 输出: dsh-plugin-guide/downloads/community-repos/<repo>/
3
- # 刷新策略: codeload HEAD 请求的 ETag 对比(内容变更即重新下载);记录在 downloads/community-repos/_heads.tsv。
4
- # 传输: 纯 curl + codeload(main -> master -> HEAD 分支回退),不消耗 GitHub API 配额,也不依赖 git 进程。
5
- # 参数: -Force 忽略 ETag 对比,强制全部重下; -Slice <n> -Slices <m> 只处理第 n/m 段(1-based),
6
- # 此时日志与 heads 写入 _download.s<n>.log / _heads.s<n>.tsv,由调用方自行合并。
7
- param([switch]$Force, [int]$Slice = 0, [int]$Slices = 1, [switch]$OnlyMissing)
8
- $ErrorActionPreference = 'Continue'
9
- $ProgressPreference = 'SilentlyContinue'
10
-
11
- $kb = Split-Path $PSScriptRoot -Parent
12
- $dl = Join-Path $kb 'downloads\community-repos'
13
- New-Item -ItemType Directory -Force -Path $dl | Out-Null
14
-
15
- # 后台/受限环境 PATH 可能缺失 curl/tar:逐一下落
16
- $curl = Get-Command curl.exe -ErrorAction SilentlyContinue
17
- if (-not $curl) { if (Test-Path "$env:SystemRoot\System32\curl.exe") { $curl = "$env:SystemRoot\System32\curl.exe" } else { $curl = 'curl.exe' } }
18
- $tar = Get-Command tar.exe -ErrorAction SilentlyContinue
19
- if (-not $tar) { if (Test-Path "$env:SystemRoot\System32\tar.exe") { $tar = "$env:SystemRoot\System32\tar.exe" } else { $tar = 'tar.exe' } }
20
-
21
- $repos = @(
22
- # 第一批:08-13/14 首批深读的 15 个插件开发仓库
23
- 'omdsh-dev/plugin-template',
24
- 'omdsh-dev/dsh-plugin-skills',
25
- 'omdsh-dev/dsh-plugin-dev',
26
- 'vlln/plugin-registry',
27
- 'omdsh-dev/fabric',
28
- 'whyihaveyou/dsh-suite',
29
- 'omdsh-dev/dsh-plugin-check',
30
- 'Opr4Mp3r/deepseek-harness-plugin-from-scratch',
31
- 'randerous/dsh-turn-meta',
32
- 'bobleer/deepseek-harness-plugin-mcp',
33
- 'Nagi-ovo/dsh-find-plugins',
34
- 'omdsh-dev/dsh-hub-workshop',
35
- 'AdamPlatin123/awesome-dsh-plugins',
36
- 'bruc3van/awesome-dsh-plugin',
37
- 'Alex-Yanggg/awesome-DSH-plugin',
38
- # 第二批:08-14 上午清单(awesome/市场/候选,此前未归档)
39
- 'walkinglabs/awesome-deepseek-harness-plugins',
40
- 'vvlife/awesome-deepseek-harness-plugins',
41
- 'cccakeee/awesome-dsh-plugins',
42
- 'bradeGithub/DSH-Plugins-Marketplace',
43
- 'Toukaiteio/dsh-plugin-installer',
44
- 'Scorp1o117/dsh-plugin-marketplace',
45
- 'NanmiCoder/dsh-agent-teams',
46
- 'vibeinging/dsh-tool-search',
47
- 'zhu1090093659/dsh-web-ui',
48
- 'ccch1mneyyy/dsh-cc-tui',
49
- 'dataelement/dsh-desktop',
50
- 'hust-open-atom-club/oh-dsh-desktop',
51
- 'lhh010/dsh-bash-encoding',
52
- 'Nagi-ovo/dsh-visualize',
53
- # 第三批:08-14 晚间 GitHub 生态扫描(高优先级 26 个文档型仓库)
54
- 'flaqai/deepeseek-harness-guide',
55
- 'Electricitysheep/dsh-handbook',
56
- 'JingHao-Leon/deepseek-harness-guide',
57
- 'flysheep-ai/learn_deepseek_harness',
58
- 'pingfanfan/hello-dsh',
59
- 'LaplaceYoung/dsh-book-deepseek-harness',
60
- 'yanhua1010/dsh-harness-tutorial',
61
- 'hoco-scy/deepseek-harness-deep-dive',
62
- 'libukai/awesome-deepseek-harness',
63
- 'sandbaseai/deepseek-harness-handbook',
64
- 'openma-ai/deepseek-harness-typescript-sdk',
65
- 'h565656445/dsh-llm-agent-harness-guide',
66
- 'h565656445/dsh-agent-os-worker-protocol',
67
- 'cyanseek/dsh-native-playbook',
68
- 'whyihaveyou/dsh-plugin-tutorial',
69
- 'DumplingHuman/dsh-plugin-tutorial',
70
- 'anweat/dsh-plugin-dev-guide',
71
- 'Hubert-hwk/dsh-for-humans',
72
- 'yangl326-Dylan/learning-dsh',
73
- 'curtiseng/cordis-course',
74
- 'THU-MAIC/dsh-openmaic',
75
- 'qomob/DSHwiki',
76
- 'calderbuild/awesome-deepseek-harness',
77
- 'njdldkl666699/dsh-learning',
78
- 'Loner1024/deepseek-harness-sdk-rs',
79
- 'dshworks/howto-dsh',
80
- # 第四批:skill 集合/契约规范/含实质开发知识(中优先级 19 个)
81
- 'dhicoc/dsh-reverse-skill',
82
- 'phoenixlucky/zerotoken-skill',
83
- 'unknowbug/anchorlaw',
84
- 'w2112515/dsh-plugin-development',
85
- 'OneZero-Y/dsh-plugin-kit',
86
- 'akira399/dsh-plugin-publisher',
87
- 'LeslieWylie/dsh-plugin-release',
88
- 'LeslieWylie/dsh-benchmark-evidence',
89
- 'LeslieWylie/dsh-agent-orchestration',
90
- 'dongsheng123132/task-passport',
91
- 'Tostoevsky/TsienHsueShen',
92
- 'Whning0513/awesome-deepseek-skills',
93
- 'Jesse-njx/dsh-skillport',
94
- 'green-dalii/dsh-plugin-dev-skill',
95
- 'RayYeung1989/dsh-plugin-development',
96
- 'SmileTao/dsh-plugin-dev-skill',
97
- 'Leeaoyin/dr-agent-skills',
98
- 'KhalilYamber/hana-dsh-bridge',
99
- 'ieookm/agent-to-dsh-migration',
100
- # 第五批:目录/市场/awesome 索引(低优先级 20 个,README 即文档)
101
- 'kejixiaoliang/awesome-dsh-plugins',
102
- 'like-study1/Oh-My-DSH',
103
- 'zp-home/dsh-recommend',
104
- 'white0dew/awesome-dsh-plugins',
105
- 'wangshunnn/oh-my-dsh',
106
- 'billLiao/awesome-dsh-plugin',
107
- 'YYTbit/awesome-dsh-bridges',
108
- 'HackSing/dsh-plugins',
109
- 'xiaohai-78/Top',
110
- '2BingLing/dsh-market',
111
- 'lwmxiaobei/dsh-plugins',
112
- 'dshworks/awesome-dsh-themes',
113
- 'dshworks/awesome-dsh-plugins',
114
- 'dsh-pub/dsh-pub',
115
- 'cooljser/dsh-plugin-portal',
116
- 'WatchaAI/awesome-deepseek-harness-plugins',
117
- 'imsai-sh/awesome-deepseek-harness-plugins',
118
- 'xianyu110/awesome-deepseek-harness',
119
- 'openguardrails/openguardrails',
120
- 'Bandersnatch0x/amber-protocol',
121
- # 第六批:中英文社区扫描补充(教程仓库/Tauri 壳)
122
- 'onychen/learn-dsh',
123
- 'alchaincyf/deepseek-harness-orange-book',
124
- 'bobleer/deepseek-harness-gui',
125
- # 第七批:08-15 上午增量扫描(web_search 新线索:桌面端/QAT 桥接/安全 PoC/awesome/Python 移植/Termux)
126
- 'anywhere-labs/deepseek-harness-desktop',
127
- 'cc1252/deepseek-harness-desktop',
128
- 'LisiChen0/DeepSeek-Harness-Desktop',
129
- 'Skyearn/deepseek-harness-app',
130
- 'salathleizhang/deepseek-harness-desktop',
131
- 'ChisaAlter/Deepseek-Harness-Desktop',
132
- 'hairyf/deepseek-harness-desktop',
133
- 'banana770/dsh-qq-bridge',
134
- 'mishibeikejie/zat-dsh-engine',
135
- 'beancookie/awesome-dsh-plugin',
136
- 'Vengisk/deepseek-harness-termux',
137
- 'zzszmyf/dsh-security-pocs',
138
- 'HenryZ838978/deepseek-harness',
139
- 'Lyowisee/deepseek-harness',
140
- # 第八批:08-15 午间补充(主题注册表/WhaleHub 市场/dsh-market 组织)
141
- 'orxz/deepseek-harness-themes',
142
- 'vvlife/whalehub-dsh',
143
- 'dsh-market/dsh-market'
144
- )
145
-
146
- $headsFile = Join-Path $dl '_heads.tsv'
147
- $logFile = Join-Path $dl '_download.log'
148
-
149
- # 同名仓库消歧: 清单中多个 owner 有同名仓库(如 4 个 awesome-dsh-plugins、7 个 deepseek-harness-desktop),
150
- # 且 Windows 文件系统大小写不敏感——裸 repo 名互相覆盖会丢数据。规则: 首个出现者保留裸名
151
- # (兼容既有文档引用), 后续同名者用 "<owner>-<repo>" 目录名。
152
- # 必须在切片之前对全量清单计算: 切片后每片只见子集, 跨片的同名会误判(08-15 真实踩坑)。
153
- $seenNames = @{}
154
- $dirNames = @{}
155
- foreach ($r in $repos) {
156
- $owner, $repoName = $r -split '/'
157
- $repoKey = $repoName.ToLowerInvariant()
158
- if ($seenNames.ContainsKey($repoKey)) { $dirNames[$r] = "$owner-$repoName" } else { $seenNames[$repoKey] = $true; $dirNames[$r] = $repoName }
159
- }
160
-
161
- if ($Slice -gt 0 -and $Slices -gt 1) {
162
- $headsFile = Join-Path $dl ("_heads.s{0}.tsv" -f $Slice)
163
- $logFile = Join-Path $dl ("_download.s{0}.log" -f $Slice)
164
- # 注意: 切片数学必须先算进变量再传给 Select-Object——PS 5.1 会把裸的 [Math]::Ceiling(...)
165
- # 当成字符串参数导致绑定失败(切片失效, 多进程重跑全量互相踩踏, 08-15 真实踩坑)。
166
- $sliceSize = [Math]::Ceiling($repos.Count / $Slices)
167
- $sliceStart = ($Slice - 1) * $sliceSize
168
- $repos = @($repos | Select-Object -Skip $sliceStart -First $sliceSize)
169
- }
170
- $heads = @{}
171
- if ((Test-Path $headsFile) -and -not $Force) {
172
- Get-Content $headsFile -Encoding UTF8 | ForEach-Object {
173
- if ($_ -match '^(.+)\t(.+)$') { $heads[$matches[1]] = $matches[2] }
174
- }
175
- }
176
-
177
- $log = New-Object System.Collections.Generic.List[string]
178
- foreach ($r in $repos) {
179
- $owner, $repo = $r -split '/'
180
- $repoDir = Join-Path $dl $dirNames[$r]
181
- # -OnlyMissing: 只补清单中本地缺失的仓库(已有目录跳过下载;仍会探测 ETag 写入 heads,便于后续增量刷新)。
182
- $exists = (Test-Path $repoDir) -and (Get-ChildItem $repoDir -File -ErrorAction SilentlyContinue)
183
- if ($OnlyMissing -and $exists -and -not $Force) {
184
- $hdr2 = & $curl -sI --connect-timeout 10 --max-time 30 "https://codeload.github.com/$r/tar.gz/HEAD" 2>&1 | Out-String
185
- if ($hdr2 -match '(?i)etag:\s*"?((?:W/)?[0-9a-fA-F]+)"?') { $heads[$r] = $matches[1]; $log.Add("KEEP`t$r`tlocal-exists") }
186
- else { $log.Add("KEEP`t$r`tlocal-exists(etag-probe-miss)") }
187
- continue
188
- }
189
- # 全部走 curl + codeload(后台沙箱对 git 进程的对外连接不稳定,curl 带 connect/max 超时最可靠)。
190
- # 刷新标记用 codeload 的 ETag(内容变更即变化):分支探测 main -> master -> HEAD 三级回退。
191
- $branch = ''
192
- $etag = ''
193
- foreach ($cand in @('refs/heads/main','refs/heads/master','HEAD')) {
194
- $hdr = & $curl -sI --connect-timeout 10 --max-time 40 "https://codeload.github.com/$r/tar.gz/$cand" 2>&1 | Out-String
195
- if ($hdr -match 'HTTP/\S+\s+200') {
196
- $branch = $cand
197
- # ETag 形如 ETag: "abc..."(弱 ETag 为 W/"abc..."):正则可选跳过 W/ 前缀,完整捕获引号内十六进制值。
198
- # 修复历史: 旧正则带 ^ 锚点(-match 非多行,永远匹配不到中间行的 etag)且 W/ 前缀为必选,导致 etag 恒为空、Substring(0,12) 越界、heads 记录损坏——08-15 修复。
199
- if ($hdr -match '(?i)etag:\s*"?((?:W/)?[0-9a-fA-F]+)"?') { $etag = $matches[1] }
200
- break
201
- }
202
- }
203
- if (-not $branch) { $log.Add("FAIL`t$r`thead-request-failed(404?)"); continue }
204
- $etagShort = $etag
205
- if ($etagShort.Length -gt 12) { $etagShort = $etagShort.Substring(0, 12) }
206
- $downloaded = (Test-Path $repoDir) -and (Get-ChildItem $repoDir -File -ErrorAction SilentlyContinue)
207
- if (-not $Force -and $downloaded -and $heads.ContainsKey($r) -and $etag -and $heads[$r] -eq $etag) {
208
- $log.Add("SKIP`t$r`tup-to-date@$etagShort"); continue
209
- }
210
- $tgz = Join-Path $dl ($dirNames[$r] + '.tar.gz')
211
- $code = & $curl -sS -L --retry 1 --retry-delay 2 --connect-timeout 10 --max-time 120 -o $tgz -w '%{http_code}' "https://codeload.github.com/$r/tar.gz/$branch" 2>&1
212
- if ($code -match '^2' -and (Test-Path $tgz) -and (Get-Item $tgz).Length -gt 1024) {
213
- $tmp = Join-Path $dl ("_" + $dirNames[$r])
214
- if (Test-Path $tmp) { Remove-Item $tmp -Recurse -Force }
215
- New-Item -ItemType Directory -Force -Path $tmp | Out-Null
216
- & $tar -xzf $tgz -C $tmp 2>&1 | Out-Null
217
- $extracted = Get-ChildItem $tmp -Directory | Select-Object -First 1
218
- if ($extracted) {
219
- if (Test-Path $repoDir) { Remove-Item $repoDir -Recurse -Force }
220
- Move-Item $extracted.FullName $repoDir
221
- Remove-Item $tmp -Recurse -Force -ErrorAction SilentlyContinue
222
- $n = (Get-ChildItem $repoDir -Recurse -File | Measure-Object).Count
223
- $heads[$r] = $etag
224
- $log.Add("OK`t$r`tbranch=$branch`tfiles=$n`tetag=$etagShort")
225
- } else { $log.Add("FAIL`t$r`textract-empty") }
226
- } else { $log.Add("FAIL`t$r`thttp=$code") }
227
- if (Test-Path $tgz) { Remove-Item $tgz -Force }
228
- }
229
- $heads.GetEnumerator() | Sort-Object Key | ForEach-Object { "{0}`t{1}" -f $_.Key, $_.Value } | Set-Content $headsFile -Encoding UTF8
230
- $log | Set-Content $logFile -Encoding UTF8
231
- Write-Output ('DONE: ' + $log.Count + ' repos -> ' + $logFile)
232
- $log | Write-Output
1
+ # 社区插件开发相关仓库全量下载(tarball)脚本
2
+ # 输出: dsh-plugin-guide/downloads/community-repos/<repo>/
3
+ # 刷新策略: codeload HEAD 请求的 ETag 对比(内容变更即重新下载);记录在 downloads/community-repos/_heads.tsv。
4
+ # 传输: 纯 curl + codeload(main -> master -> HEAD 分支回退),不消耗 GitHub API 配额,也不依赖 git 进程。
5
+ # 参数: -Force 忽略 ETag 对比,强制全部重下; -Slice <n> -Slices <m> 只处理第 n/m 段(1-based),
6
+ # 此时日志与 heads 写入 _download.s<n>.log / _heads.s<n>.tsv,由调用方自行合并。
7
+ param([switch]$Force, [int]$Slice = 0, [int]$Slices = 1, [switch]$OnlyMissing)
8
+ $ErrorActionPreference = 'Continue'
9
+ $ProgressPreference = 'SilentlyContinue'
10
+
11
+ $kb = Split-Path $PSScriptRoot -Parent
12
+ $dl = Join-Path $kb 'downloads\community-repos'
13
+ New-Item -ItemType Directory -Force -Path $dl | Out-Null
14
+
15
+ # 后台/受限环境 PATH 可能缺失 curl/tar:逐一下落
16
+ $curl = Get-Command curl.exe -ErrorAction SilentlyContinue
17
+ if (-not $curl) { if (Test-Path "$env:SystemRoot\System32\curl.exe") { $curl = "$env:SystemRoot\System32\curl.exe" } else { $curl = 'curl.exe' } }
18
+ $tar = Get-Command tar.exe -ErrorAction SilentlyContinue
19
+ if (-not $tar) { if (Test-Path "$env:SystemRoot\System32\tar.exe") { $tar = "$env:SystemRoot\System32\tar.exe" } else { $tar = 'tar.exe' } }
20
+
21
+ $repos = @(
22
+ # 第一批:08-13/14 首批深读的 15 个插件开发仓库
23
+ 'omdsh-dev/plugin-template',
24
+ 'omdsh-dev/dsh-plugin-skills',
25
+ 'omdsh-dev/dsh-plugin-dev',
26
+ 'vlln/plugin-registry',
27
+ 'omdsh-dev/fabric',
28
+ 'whyihaveyou/dsh-suite',
29
+ 'omdsh-dev/dsh-plugin-check',
30
+ 'Opr4Mp3r/deepseek-harness-plugin-from-scratch',
31
+ 'randerous/dsh-turn-meta',
32
+ 'bobleer/deepseek-harness-plugin-mcp',
33
+ 'Nagi-ovo/dsh-find-plugins',
34
+ 'omdsh-dev/dsh-hub-workshop',
35
+ 'AdamPlatin123/awesome-dsh-plugins',
36
+ 'bruc3van/awesome-dsh-plugin',
37
+ 'Alex-Yanggg/awesome-DSH-plugin',
38
+ # 第二批:08-14 上午清单(awesome/市场/候选,此前未归档)
39
+ 'walkinglabs/awesome-deepseek-harness-plugins',
40
+ 'vvlife/awesome-deepseek-harness-plugins',
41
+ 'cccakeee/awesome-dsh-plugins',
42
+ 'bradeGithub/DSH-Plugins-Marketplace',
43
+ 'Toukaiteio/dsh-plugin-installer',
44
+ 'Scorp1o117/dsh-plugin-marketplace',
45
+ 'NanmiCoder/dsh-agent-teams',
46
+ 'vibeinging/dsh-tool-search',
47
+ 'zhu1090093659/dsh-web-ui',
48
+ 'ccch1mneyyy/dsh-cc-tui',
49
+ 'dataelement/dsh-desktop',
50
+ 'hust-open-atom-club/oh-dsh-desktop',
51
+ 'lhh010/dsh-bash-encoding',
52
+ 'Nagi-ovo/dsh-visualize',
53
+ # 第三批:08-14 晚间 GitHub 生态扫描(高优先级 26 个文档型仓库)
54
+ 'flaqai/deepeseek-harness-guide',
55
+ 'Electricitysheep/dsh-handbook',
56
+ 'JingHao-Leon/deepseek-harness-guide',
57
+ 'flysheep-ai/learn_deepseek_harness',
58
+ 'pingfanfan/hello-dsh',
59
+ 'LaplaceYoung/dsh-book-deepseek-harness',
60
+ 'yanhua1010/dsh-harness-tutorial',
61
+ 'hoco-scy/deepseek-harness-deep-dive',
62
+ 'libukai/awesome-deepseek-harness',
63
+ 'sandbaseai/deepseek-harness-handbook',
64
+ 'openma-ai/deepseek-harness-typescript-sdk',
65
+ 'h565656445/dsh-llm-agent-harness-guide',
66
+ 'h565656445/dsh-agent-os-worker-protocol',
67
+ 'cyanseek/dsh-native-playbook',
68
+ 'whyihaveyou/dsh-plugin-tutorial',
69
+ 'DumplingHuman/dsh-plugin-tutorial',
70
+ 'anweat/dsh-plugin-dev-guide',
71
+ 'Hubert-hwk/dsh-for-humans',
72
+ 'yangl326-Dylan/learning-dsh',
73
+ 'curtiseng/cordis-course',
74
+ 'THU-MAIC/dsh-openmaic',
75
+ 'qomob/DSHwiki',
76
+ 'calderbuild/awesome-deepseek-harness',
77
+ 'njdldkl666699/dsh-learning',
78
+ 'Loner1024/deepseek-harness-sdk-rs',
79
+ 'dshworks/howto-dsh',
80
+ # 第四批:skill 集合/契约规范/含实质开发知识(中优先级 19 个)
81
+ 'dhicoc/dsh-reverse-skill',
82
+ 'phoenixlucky/zerotoken-skill',
83
+ 'unknowbug/anchorlaw',
84
+ 'w2112515/dsh-plugin-development',
85
+ 'OneZero-Y/dsh-plugin-kit',
86
+ 'akira399/dsh-plugin-publisher',
87
+ 'LeslieWylie/dsh-plugin-release',
88
+ 'LeslieWylie/dsh-benchmark-evidence',
89
+ 'LeslieWylie/dsh-agent-orchestration',
90
+ 'dongsheng123132/task-passport',
91
+ 'Tostoevsky/TsienHsueShen',
92
+ 'Whning0513/awesome-deepseek-skills',
93
+ 'Jesse-njx/dsh-skillport',
94
+ 'green-dalii/dsh-plugin-dev-skill',
95
+ 'RayYeung1989/dsh-plugin-development',
96
+ 'SmileTao/dsh-plugin-dev-skill',
97
+ 'Leeaoyin/dr-agent-skills',
98
+ 'KhalilYamber/hana-dsh-bridge',
99
+ 'ieookm/agent-to-dsh-migration',
100
+ # 第五批:目录/市场/awesome 索引(低优先级 20 个,README 即文档)
101
+ 'kejixiaoliang/awesome-dsh-plugins',
102
+ 'like-study1/Oh-My-DSH',
103
+ 'zp-home/dsh-recommend',
104
+ 'white0dew/awesome-dsh-plugins',
105
+ 'wangshunnn/oh-my-dsh',
106
+ 'billLiao/awesome-dsh-plugin',
107
+ 'YYTbit/awesome-dsh-bridges',
108
+ 'HackSing/dsh-plugins',
109
+ 'xiaohai-78/Top',
110
+ '2BingLing/dsh-market',
111
+ 'lwmxiaobei/dsh-plugins',
112
+ 'dshworks/awesome-dsh-themes',
113
+ 'dshworks/awesome-dsh-plugins',
114
+ 'dsh-pub/dsh-pub',
115
+ 'cooljser/dsh-plugin-portal',
116
+ 'WatchaAI/awesome-deepseek-harness-plugins',
117
+ 'imsai-sh/awesome-deepseek-harness-plugins',
118
+ 'xianyu110/awesome-deepseek-harness',
119
+ 'openguardrails/openguardrails',
120
+ 'Bandersnatch0x/amber-protocol',
121
+ # 第六批:中英文社区扫描补充(教程仓库/Tauri 壳)
122
+ 'onychen/learn-dsh',
123
+ 'alchaincyf/deepseek-harness-orange-book',
124
+ 'bobleer/deepseek-harness-gui',
125
+ # 第七批:08-15 上午增量扫描(web_search 新线索:桌面端/QAT 桥接/安全 PoC/awesome/Python 移植/Termux)
126
+ 'anywhere-labs/deepseek-harness-desktop',
127
+ 'cc1252/deepseek-harness-desktop',
128
+ 'LisiChen0/DeepSeek-Harness-Desktop',
129
+ 'Skyearn/deepseek-harness-app',
130
+ 'salathleizhang/deepseek-harness-desktop',
131
+ 'ChisaAlter/Deepseek-Harness-Desktop',
132
+ 'hairyf/deepseek-harness-desktop',
133
+ 'banana770/dsh-qq-bridge',
134
+ 'mishibeikejie/zat-dsh-engine',
135
+ 'beancookie/awesome-dsh-plugin',
136
+ 'Vengisk/deepseek-harness-termux',
137
+ 'zzszmyf/dsh-security-pocs',
138
+ 'HenryZ838978/deepseek-harness',
139
+ 'Lyowisee/deepseek-harness',
140
+ # 第八批:08-15 午间补充(主题注册表/WhaleHub 市场/dsh-market 组织)
141
+ 'orxz/deepseek-harness-themes',
142
+ 'vvlife/whalehub-dsh',
143
+ 'dsh-market/dsh-market'
144
+ )
145
+
146
+ $headsFile = Join-Path $dl '_heads.tsv'
147
+ $logFile = Join-Path $dl '_download.log'
148
+
149
+ # 同名仓库消歧: 清单中多个 owner 有同名仓库(如 4 个 awesome-dsh-plugins、7 个 deepseek-harness-desktop),
150
+ # 且 Windows 文件系统大小写不敏感——裸 repo 名互相覆盖会丢数据。规则: 首个出现者保留裸名
151
+ # (兼容既有文档引用), 后续同名者用 "<owner>-<repo>" 目录名。
152
+ # 必须在切片之前对全量清单计算: 切片后每片只见子集, 跨片的同名会误判(08-15 真实踩坑)。
153
+ $seenNames = @{}
154
+ $dirNames = @{}
155
+ foreach ($r in $repos) {
156
+ $owner, $repoName = $r -split '/'
157
+ $repoKey = $repoName.ToLowerInvariant()
158
+ if ($seenNames.ContainsKey($repoKey)) { $dirNames[$r] = "$owner-$repoName" } else { $seenNames[$repoKey] = $true; $dirNames[$r] = $repoName }
159
+ }
160
+
161
+ if ($Slice -gt 0 -and $Slices -gt 1) {
162
+ $headsFile = Join-Path $dl ("_heads.s{0}.tsv" -f $Slice)
163
+ $logFile = Join-Path $dl ("_download.s{0}.log" -f $Slice)
164
+ # 注意: 切片数学必须先算进变量再传给 Select-Object——PS 5.1 会把裸的 [Math]::Ceiling(...)
165
+ # 当成字符串参数导致绑定失败(切片失效, 多进程重跑全量互相踩踏, 08-15 真实踩坑)。
166
+ $sliceSize = [Math]::Ceiling($repos.Count / $Slices)
167
+ $sliceStart = ($Slice - 1) * $sliceSize
168
+ $repos = @($repos | Select-Object -Skip $sliceStart -First $sliceSize)
169
+ }
170
+ $heads = @{}
171
+ if ((Test-Path $headsFile) -and -not $Force) {
172
+ Get-Content $headsFile -Encoding UTF8 | ForEach-Object {
173
+ if ($_ -match '^(.+)\t(.+)$') { $heads[$matches[1]] = $matches[2] }
174
+ }
175
+ }
176
+
177
+ $log = New-Object System.Collections.Generic.List[string]
178
+ foreach ($r in $repos) {
179
+ $owner, $repo = $r -split '/'
180
+ $repoDir = Join-Path $dl $dirNames[$r]
181
+ # -OnlyMissing: 只补清单中本地缺失的仓库(已有目录跳过下载;仍会探测 ETag 写入 heads,便于后续增量刷新)。
182
+ $exists = (Test-Path $repoDir) -and (Get-ChildItem $repoDir -File -ErrorAction SilentlyContinue)
183
+ if ($OnlyMissing -and $exists -and -not $Force) {
184
+ $hdr2 = & $curl -sI --connect-timeout 10 --max-time 30 "https://codeload.github.com/$r/tar.gz/HEAD" 2>&1 | Out-String
185
+ if ($hdr2 -match '(?i)etag:\s*"?((?:W/)?[0-9a-fA-F]+)"?') { $heads[$r] = $matches[1]; $log.Add("KEEP`t$r`tlocal-exists") }
186
+ else { $log.Add("KEEP`t$r`tlocal-exists(etag-probe-miss)") }
187
+ continue
188
+ }
189
+ # 全部走 curl + codeload(后台沙箱对 git 进程的对外连接不稳定,curl 带 connect/max 超时最可靠)。
190
+ # 刷新标记用 codeload 的 ETag(内容变更即变化):分支探测 main -> master -> HEAD 三级回退。
191
+ $branch = ''
192
+ $etag = ''
193
+ foreach ($cand in @('refs/heads/main','refs/heads/master','HEAD')) {
194
+ $hdr = & $curl -sI --connect-timeout 10 --max-time 40 "https://codeload.github.com/$r/tar.gz/$cand" 2>&1 | Out-String
195
+ if ($hdr -match 'HTTP/\S+\s+200') {
196
+ $branch = $cand
197
+ # ETag 形如 ETag: "abc..."(弱 ETag 为 W/"abc..."):正则可选跳过 W/ 前缀,完整捕获引号内十六进制值。
198
+ # 修复历史: 旧正则带 ^ 锚点(-match 非多行,永远匹配不到中间行的 etag)且 W/ 前缀为必选,导致 etag 恒为空、Substring(0,12) 越界、heads 记录损坏——08-15 修复。
199
+ if ($hdr -match '(?i)etag:\s*"?((?:W/)?[0-9a-fA-F]+)"?') { $etag = $matches[1] }
200
+ break
201
+ }
202
+ }
203
+ if (-not $branch) { $log.Add("FAIL`t$r`thead-request-failed(404?)"); continue }
204
+ $etagShort = $etag
205
+ if ($etagShort.Length -gt 12) { $etagShort = $etagShort.Substring(0, 12) }
206
+ $downloaded = (Test-Path $repoDir) -and (Get-ChildItem $repoDir -File -ErrorAction SilentlyContinue)
207
+ if (-not $Force -and $downloaded -and $heads.ContainsKey($r) -and $etag -and $heads[$r] -eq $etag) {
208
+ $log.Add("SKIP`t$r`tup-to-date@$etagShort"); continue
209
+ }
210
+ $tgz = Join-Path $dl ($dirNames[$r] + '.tar.gz')
211
+ $code = & $curl -sS -L --retry 1 --retry-delay 2 --connect-timeout 10 --max-time 120 -o $tgz -w '%{http_code}' "https://codeload.github.com/$r/tar.gz/$branch" 2>&1
212
+ if ($code -match '^2' -and (Test-Path $tgz) -and (Get-Item $tgz).Length -gt 1024) {
213
+ $tmp = Join-Path $dl ("_" + $dirNames[$r])
214
+ if (Test-Path $tmp) { Remove-Item $tmp -Recurse -Force }
215
+ New-Item -ItemType Directory -Force -Path $tmp | Out-Null
216
+ & $tar -xzf $tgz -C $tmp 2>&1 | Out-Null
217
+ $extracted = Get-ChildItem $tmp -Directory | Select-Object -First 1
218
+ if ($extracted) {
219
+ if (Test-Path $repoDir) { Remove-Item $repoDir -Recurse -Force }
220
+ Move-Item $extracted.FullName $repoDir
221
+ Remove-Item $tmp -Recurse -Force -ErrorAction SilentlyContinue
222
+ $n = (Get-ChildItem $repoDir -Recurse -File | Measure-Object).Count
223
+ $heads[$r] = $etag
224
+ $log.Add("OK`t$r`tbranch=$branch`tfiles=$n`tetag=$etagShort")
225
+ } else { $log.Add("FAIL`t$r`textract-empty") }
226
+ } else { $log.Add("FAIL`t$r`thttp=$code") }
227
+ if (Test-Path $tgz) { Remove-Item $tgz -Force }
228
+ }
229
+ $heads.GetEnumerator() | Sort-Object Key | ForEach-Object { "{0}`t{1}" -f $_.Key, $_.Value } | Set-Content $headsFile -Encoding UTF8
230
+ $log | Set-Content $logFile -Encoding UTF8
231
+ Write-Output ('DONE: ' + $log.Count + ' repos -> ' + $logFile)
232
+ $log | Write-Output