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,195 +1,195 @@
1
- # DeepSeek Harness 插件开发资料全量下载脚本
2
- # 输出: dsh-plugin-guide/downloads/{web,github,community} + manifest.tsv
3
- # 参数: -DocRoot <路径> 官方 checkout 的 docs 目录(Phase D 站点路由来源),默认本机 checkout。
4
- param([string]$DocRoot = 'D:\deepseek-harness\docs')
5
- $ErrorActionPreference = 'Continue'
6
- $ProgressPreference = 'SilentlyContinue'
7
-
8
- $kit = Split-Path $PSScriptRoot -Parent
9
- $dl = Join-Path $kit 'downloads'
10
- New-Item -ItemType Directory -Force -Path $dl | Out-Null
11
- $manifest = New-Object System.Collections.Generic.List[string]
12
- $manifest.Add("status`thttpcode`tbytes`turl`tfile")
13
-
14
- function Log([string]$line) { $script:manifest.Add($line) }
15
-
16
- function Do-Curl([string]$url, [string]$outFile, [string]$extra) {
17
- $dir = Split-Path $outFile -Parent
18
- if ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }
19
- $args1 = @('-sS','-L','--max-time','90','-o',$outFile)
20
- if ($extra) { $args1 += $extra }
21
- $args1 += @('-w','%{http_code}', $url)
22
- $code = & curl.exe @args1 2>$null
23
- if (($code -match '^2') -and (Test-Path $outFile)) {
24
- $sz = (Get-Item $outFile).Length
25
- if ($sz -eq 0) { Remove-Item $outFile -Force; Log "FAIL`t$code`t0`t$url"; return $false }
26
- Log "OK`t$code`t$sz`t$url`t$outFile"
27
- return $true
28
- }
29
- if (Test-Path $outFile) { Remove-Item $outFile -Force -ErrorAction SilentlyContinue }
30
- Log "FAIL`t$code`t0`t$url"
31
- return $false
32
- }
33
-
34
- function Download([string[]]$urls, [string]$outFile, [string]$extra) {
35
- foreach ($u in $urls) { if (Do-Curl $u $outFile $extra) { return $true } }
36
- return $false
37
- }
38
-
39
- function Get-DefaultBranch([string]$metaFile, [string]$fallback) {
40
- if (!(Test-Path $metaFile)) { return $fallback }
41
- try {
42
- $m = Get-Content $metaFile -Raw | ConvertFrom-Json
43
- if ($m.default_branch) { return $m.default_branch }
44
- } catch { }
45
- return $fallback
46
- }
47
-
48
- $ua = @('-H','User-Agent: dsh-plugin-guide-research')
49
-
50
- # ---------- Phase A: 固定 URL ----------
51
- Download @('https://raw.githubusercontent.com/cordiverse/cordis/HEAD/README.md',
52
- 'https://raw.githubusercontent.com/cordiverse/cordis/master/README.md',
53
- 'https://raw.githubusercontent.com/cordiverse/cordis/main/README.md') `
54
- (Join-Path $dl 'github\cordis\README.md')
55
- Download @('https://raw.githubusercontent.com/cordiverse/cordis/HEAD/package.json') `
56
- (Join-Path $dl 'github\cordis\package.json')
57
- Download @('https://api.github.com/repos/cordiverse/cordis') `
58
- (Join-Path $dl 'github\cordis\repo.json') $ua
59
-
60
- Download @('https://raw.githubusercontent.com/cordiverse/paper/HEAD/README.md',
61
- 'https://raw.githubusercontent.com/cordiverse/paper/master/README.md',
62
- 'https://raw.githubusercontent.com/cordiverse/paper/main/README.md') `
63
- (Join-Path $dl 'github\paper\README.md')
64
- Download @('https://api.github.com/repos/cordiverse/paper') `
65
- (Join-Path $dl 'github\paper\repo.json') $ua
66
-
67
- Download @('https://raw.githubusercontent.com/deepseek-ai/deepseek-harness/HEAD/README.md',
68
- 'https://raw.githubusercontent.com/deepseek-ai/deepseek-harness/master/README.md',
69
- 'https://raw.githubusercontent.com/deepseek-ai/deepseek-harness/main/README.md') `
70
- (Join-Path $dl 'github\harness\README.md')
71
- Download @('https://api.github.com/repos/deepseek-ai/deepseek-harness') `
72
- (Join-Path $dl 'github\harness\repo.json') $ua
73
-
74
- # 官网与文档站入口页
75
- Download @('https://www.deepseek.com/harness/','https://www.deepseek.com/harness','https://deepseek.com/harness/') `
76
- (Join-Path $dl 'web\deepseek-com-harness.html')
77
- Download @('https://deepseek-harness.github.io/deepseek-harness/sitemap.xml') `
78
- (Join-Path $dl 'web\sitemap.xml')
79
- Download @('https://deepseek-harness.github.io/deepseek-harness/develop/basic/') `
80
- (Join-Path $dl 'web\develop-basic.html')
81
-
82
- # ---------- Phase B: cordis 仓库全量 md 文档 ----------
83
- $cordisBranch = Get-DefaultBranch (Join-Path $dl 'github\cordis\repo.json') 'master'
84
- $treeFile = Join-Path $dl 'github\cordis\tree.json'
85
- Download @("https://api.github.com/repos/cordiverse/cordis/git/trees/$cordisBranch`?recursive=1") $treeFile $ua
86
- if (Test-Path $treeFile) {
87
- try {
88
- $t = Get-Content $treeFile -Raw | ConvertFrom-Json
89
- $i = 0
90
- foreach ($item in $t.tree) {
91
- if ($item.type -ne 'blob') { continue }
92
- if ($item.path -notmatch '\.(md|mdx)$') { continue }
93
- $i++
94
- if ($i -gt 120) { break }
95
- $out = Join-Path $dl ("github\cordis\repo\" + ($item.path -replace '/','\'))
96
- Download @("https://raw.githubusercontent.com/cordiverse/cordis/$cordisBranch/$($item.path)") $out
97
- }
98
- } catch { Log "FAIL`tparse-tree`t0`tcordis tree.json 解析失败" }
99
- }
100
-
101
- # ---------- Phase C: paper 仓库 md/tex ----------
102
- $paperBranch = Get-DefaultBranch (Join-Path $dl 'github\paper\repo.json') 'master'
103
- $ptreeFile = Join-Path $dl 'github\paper\tree.json'
104
- Download @("https://api.github.com/repos/cordiverse/paper/git/trees/$paperBranch`?recursive=1") $ptreeFile $ua
105
- if (Test-Path $ptreeFile) {
106
- try {
107
- $t = Get-Content $ptreeFile -Raw | ConvertFrom-Json
108
- $i = 0
109
- foreach ($item in $t.tree) {
110
- if ($item.type -ne 'blob') { continue }
111
- if ($item.path -notmatch '\.(md|tex|bib|typ|pdf)$') { continue }
112
- $i++
113
- if ($i -gt 60) { break }
114
- $out = Join-Path $dl ("github\paper\repo\" + ($item.path -replace '/','\'))
115
- Download @("https://raw.githubusercontent.com/cordiverse/paper/$paperBranch/$($item.path)") $out
116
- }
117
- } catch { Log "FAIL`tparse-tree`t0`tpaper tree.json 解析失败" }
118
- }
119
-
120
- # ---------- Phase D: GitHub Pages 全站爬取 ----------
121
- $siteBase = 'https://deepseek-harness.github.io/deepseek-harness/'
122
- $docRoot = $DocRoot
123
- $routes = New-Object System.Collections.Generic.HashSet[string]
124
-
125
- function SitePath([string]$rel) {
126
- $p = $rel -replace '\.zh\.md$','' -replace '\.md$',''
127
- $p = $p -replace '\\','/'
128
- if ($p -match '/index$') { $p = $p -replace '/index$','' }
129
- return $p
130
- }
131
-
132
- Get-ChildItem (Join-Path $docRoot 'user') -Recurse -Filter *.md | ForEach-Object {
133
- $rel = $_.FullName.Substring((Join-Path $docRoot 'user').Length + 1)
134
- [void]$routes.Add((SitePath $rel))
135
- }
136
- Get-ChildItem (Join-Path $docRoot 'cordis-tutorial') -Filter *.md | ForEach-Object {
137
- [void]$routes.Add('develop/cordis-tutorial/' + (SitePath $_.Name))
138
- }
139
- Get-ChildItem (Join-Path $docRoot 'subsystems') -Filter *.md | ForEach-Object {
140
- $n = SitePath $_.Name
141
- [void]$routes.Add($(if ($_.BaseName -eq 'README') { 'reference/subsystems' } else { "reference/subsystems/$n" }))
142
- }
143
- @('architecture','cordis-primer','capability-seams','agent-lifecycle','tool-execution-pipeline','config-catalog','tool-catalog','persistence-catalog') | ForEach-Object {
144
- [void]$routes.Add("reference/$_")
145
- }
146
- Get-ChildItem (Join-Path $docRoot 'cordis-api') -Filter *.md | ForEach-Object {
147
- [void]$routes.Add('reference/cordis-api/' + (SitePath $_.Name))
148
- }
149
- @('adding-a-package','adding-a-tool','adding-an-llm-adapter','extension-cookbook') | ForEach-Object {
150
- [void]$routes.Add("reference/cookbook/$_")
151
- }
152
-
153
- $siteCount = 0
154
- foreach ($r in $routes) {
155
- foreach ($loc in @('','en/')) {
156
- $rel = $loc + $r
157
- $url = $siteBase + $rel
158
- $fname = $rel -replace '/','\'
159
- if ($fname -eq '') { $fname = 'index' }
160
- $out = Join-Path $dl ("web\site\$fname.html")
161
- Do-Curl $url $out | Out-Null
162
- $siteCount++
163
- }
164
- }
165
- Log "INFO`t-`t$siteCount`tpages attempted`tghpages crawl"
166
-
167
- # ---------- Phase E: 社区仓库 README ----------
168
- $community = @(
169
- @('AdamPlatin123','awesome-dsh-plugins'),
170
- @('omdsh-dev','dsh-plugin-dev'),
171
- @('omdsh-dev','plugin-template'),
172
- @('omdsh-dev','dsh-plugin-skills'),
173
- @('vlln','plugin-registry'),
174
- @('0xsline','awesome-deepseek-harness'),
175
- @('awesome-dsh-plugin','awesome-dsh-plugin'),
176
- @('Alex-Yanggg','awesome-DSH-plugin'),
177
- @('bruc3van','awesome-dsh-plugin'),
178
- @('Dominic789654','awesome-deepseek-harness'),
179
- @('hikariming','dshfind'),
180
- @('dsh-external','hub'),
181
- @('titanwings','colleague-skill')
182
- )
183
- foreach ($pair in $community) {
184
- $owner = $pair[0]; $repo = $pair[1]
185
- Download @("https://raw.githubusercontent.com/$owner/$repo/HEAD/README.md",
186
- "https://raw.githubusercontent.com/$owner/$repo/master/README.md",
187
- "https://raw.githubusercontent.com/$owner/$repo/main/README.md") `
188
- (Join-Path $dl "community\$repo.md")
189
- Download @("https://api.github.com/repos/$owner/$repo") `
190
- (Join-Path $dl "community\$repo.json") $ua
191
- }
192
-
193
- # ---------- Phase F: manifest ----------
194
- Set-Content -Path (Join-Path $dl 'manifest.tsv') -Value $manifest -Encoding UTF8
195
- Write-Output ("DONE: " + $manifest.Count + " 条记录 -> " + (Join-Path $dl 'manifest.tsv'))
1
+ # DeepSeek Harness 插件开发资料全量下载脚本
2
+ # 输出: dsh-plugin-guide/downloads/{web,github,community} + manifest.tsv
3
+ # 参数: -DocRoot <路径> 官方 checkout 的 docs 目录(Phase D 站点路由来源),默认本机 checkout。
4
+ param([string]$DocRoot = 'D:\deepseek-harness\docs')
5
+ $ErrorActionPreference = 'Continue'
6
+ $ProgressPreference = 'SilentlyContinue'
7
+
8
+ $kit = Split-Path $PSScriptRoot -Parent
9
+ $dl = Join-Path $kit 'downloads'
10
+ New-Item -ItemType Directory -Force -Path $dl | Out-Null
11
+ $manifest = New-Object System.Collections.Generic.List[string]
12
+ $manifest.Add("status`thttpcode`tbytes`turl`tfile")
13
+
14
+ function Log([string]$line) { $script:manifest.Add($line) }
15
+
16
+ function Do-Curl([string]$url, [string]$outFile, [string]$extra) {
17
+ $dir = Split-Path $outFile -Parent
18
+ if ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }
19
+ $args1 = @('-sS','-L','--max-time','90','-o',$outFile)
20
+ if ($extra) { $args1 += $extra }
21
+ $args1 += @('-w','%{http_code}', $url)
22
+ $code = & curl.exe @args1 2>$null
23
+ if (($code -match '^2') -and (Test-Path $outFile)) {
24
+ $sz = (Get-Item $outFile).Length
25
+ if ($sz -eq 0) { Remove-Item $outFile -Force; Log "FAIL`t$code`t0`t$url"; return $false }
26
+ Log "OK`t$code`t$sz`t$url`t$outFile"
27
+ return $true
28
+ }
29
+ if (Test-Path $outFile) { Remove-Item $outFile -Force -ErrorAction SilentlyContinue }
30
+ Log "FAIL`t$code`t0`t$url"
31
+ return $false
32
+ }
33
+
34
+ function Download([string[]]$urls, [string]$outFile, [string]$extra) {
35
+ foreach ($u in $urls) { if (Do-Curl $u $outFile $extra) { return $true } }
36
+ return $false
37
+ }
38
+
39
+ function Get-DefaultBranch([string]$metaFile, [string]$fallback) {
40
+ if (!(Test-Path $metaFile)) { return $fallback }
41
+ try {
42
+ $m = Get-Content $metaFile -Raw | ConvertFrom-Json
43
+ if ($m.default_branch) { return $m.default_branch }
44
+ } catch { }
45
+ return $fallback
46
+ }
47
+
48
+ $ua = @('-H','User-Agent: dsh-plugin-guide-research')
49
+
50
+ # ---------- Phase A: 固定 URL ----------
51
+ Download @('https://raw.githubusercontent.com/cordiverse/cordis/HEAD/README.md',
52
+ 'https://raw.githubusercontent.com/cordiverse/cordis/master/README.md',
53
+ 'https://raw.githubusercontent.com/cordiverse/cordis/main/README.md') `
54
+ (Join-Path $dl 'github\cordis\README.md')
55
+ Download @('https://raw.githubusercontent.com/cordiverse/cordis/HEAD/package.json') `
56
+ (Join-Path $dl 'github\cordis\package.json')
57
+ Download @('https://api.github.com/repos/cordiverse/cordis') `
58
+ (Join-Path $dl 'github\cordis\repo.json') $ua
59
+
60
+ Download @('https://raw.githubusercontent.com/cordiverse/paper/HEAD/README.md',
61
+ 'https://raw.githubusercontent.com/cordiverse/paper/master/README.md',
62
+ 'https://raw.githubusercontent.com/cordiverse/paper/main/README.md') `
63
+ (Join-Path $dl 'github\paper\README.md')
64
+ Download @('https://api.github.com/repos/cordiverse/paper') `
65
+ (Join-Path $dl 'github\paper\repo.json') $ua
66
+
67
+ Download @('https://raw.githubusercontent.com/deepseek-ai/deepseek-harness/HEAD/README.md',
68
+ 'https://raw.githubusercontent.com/deepseek-ai/deepseek-harness/master/README.md',
69
+ 'https://raw.githubusercontent.com/deepseek-ai/deepseek-harness/main/README.md') `
70
+ (Join-Path $dl 'github\harness\README.md')
71
+ Download @('https://api.github.com/repos/deepseek-ai/deepseek-harness') `
72
+ (Join-Path $dl 'github\harness\repo.json') $ua
73
+
74
+ # 官网与文档站入口页
75
+ Download @('https://www.deepseek.com/harness/','https://www.deepseek.com/harness','https://deepseek.com/harness/') `
76
+ (Join-Path $dl 'web\deepseek-com-harness.html')
77
+ Download @('https://deepseek-harness.github.io/deepseek-harness/sitemap.xml') `
78
+ (Join-Path $dl 'web\sitemap.xml')
79
+ Download @('https://deepseek-harness.github.io/deepseek-harness/develop/basic/') `
80
+ (Join-Path $dl 'web\develop-basic.html')
81
+
82
+ # ---------- Phase B: cordis 仓库全量 md 文档 ----------
83
+ $cordisBranch = Get-DefaultBranch (Join-Path $dl 'github\cordis\repo.json') 'master'
84
+ $treeFile = Join-Path $dl 'github\cordis\tree.json'
85
+ Download @("https://api.github.com/repos/cordiverse/cordis/git/trees/$cordisBranch`?recursive=1") $treeFile $ua
86
+ if (Test-Path $treeFile) {
87
+ try {
88
+ $t = Get-Content $treeFile -Raw | ConvertFrom-Json
89
+ $i = 0
90
+ foreach ($item in $t.tree) {
91
+ if ($item.type -ne 'blob') { continue }
92
+ if ($item.path -notmatch '\.(md|mdx)$') { continue }
93
+ $i++
94
+ if ($i -gt 120) { break }
95
+ $out = Join-Path $dl ("github\cordis\repo\" + ($item.path -replace '/','\'))
96
+ Download @("https://raw.githubusercontent.com/cordiverse/cordis/$cordisBranch/$($item.path)") $out
97
+ }
98
+ } catch { Log "FAIL`tparse-tree`t0`tcordis tree.json 解析失败" }
99
+ }
100
+
101
+ # ---------- Phase C: paper 仓库 md/tex ----------
102
+ $paperBranch = Get-DefaultBranch (Join-Path $dl 'github\paper\repo.json') 'master'
103
+ $ptreeFile = Join-Path $dl 'github\paper\tree.json'
104
+ Download @("https://api.github.com/repos/cordiverse/paper/git/trees/$paperBranch`?recursive=1") $ptreeFile $ua
105
+ if (Test-Path $ptreeFile) {
106
+ try {
107
+ $t = Get-Content $ptreeFile -Raw | ConvertFrom-Json
108
+ $i = 0
109
+ foreach ($item in $t.tree) {
110
+ if ($item.type -ne 'blob') { continue }
111
+ if ($item.path -notmatch '\.(md|tex|bib|typ|pdf)$') { continue }
112
+ $i++
113
+ if ($i -gt 60) { break }
114
+ $out = Join-Path $dl ("github\paper\repo\" + ($item.path -replace '/','\'))
115
+ Download @("https://raw.githubusercontent.com/cordiverse/paper/$paperBranch/$($item.path)") $out
116
+ }
117
+ } catch { Log "FAIL`tparse-tree`t0`tpaper tree.json 解析失败" }
118
+ }
119
+
120
+ # ---------- Phase D: GitHub Pages 全站爬取 ----------
121
+ $siteBase = 'https://deepseek-harness.github.io/deepseek-harness/'
122
+ $docRoot = $DocRoot
123
+ $routes = New-Object System.Collections.Generic.HashSet[string]
124
+
125
+ function SitePath([string]$rel) {
126
+ $p = $rel -replace '\.zh\.md$','' -replace '\.md$',''
127
+ $p = $p -replace '\\','/'
128
+ if ($p -match '/index$') { $p = $p -replace '/index$','' }
129
+ return $p
130
+ }
131
+
132
+ Get-ChildItem (Join-Path $docRoot 'user') -Recurse -Filter *.md | ForEach-Object {
133
+ $rel = $_.FullName.Substring((Join-Path $docRoot 'user').Length + 1)
134
+ [void]$routes.Add((SitePath $rel))
135
+ }
136
+ Get-ChildItem (Join-Path $docRoot 'cordis-tutorial') -Filter *.md | ForEach-Object {
137
+ [void]$routes.Add('develop/cordis-tutorial/' + (SitePath $_.Name))
138
+ }
139
+ Get-ChildItem (Join-Path $docRoot 'subsystems') -Filter *.md | ForEach-Object {
140
+ $n = SitePath $_.Name
141
+ [void]$routes.Add($(if ($_.BaseName -eq 'README') { 'reference/subsystems' } else { "reference/subsystems/$n" }))
142
+ }
143
+ @('architecture','cordis-primer','capability-seams','agent-lifecycle','tool-execution-pipeline','config-catalog','tool-catalog','persistence-catalog') | ForEach-Object {
144
+ [void]$routes.Add("reference/$_")
145
+ }
146
+ Get-ChildItem (Join-Path $docRoot 'cordis-api') -Filter *.md | ForEach-Object {
147
+ [void]$routes.Add('reference/cordis-api/' + (SitePath $_.Name))
148
+ }
149
+ @('adding-a-package','adding-a-tool','adding-an-llm-adapter','extension-cookbook') | ForEach-Object {
150
+ [void]$routes.Add("reference/cookbook/$_")
151
+ }
152
+
153
+ $siteCount = 0
154
+ foreach ($r in $routes) {
155
+ foreach ($loc in @('','en/')) {
156
+ $rel = $loc + $r
157
+ $url = $siteBase + $rel
158
+ $fname = $rel -replace '/','\'
159
+ if ($fname -eq '') { $fname = 'index' }
160
+ $out = Join-Path $dl ("web\site\$fname.html")
161
+ Do-Curl $url $out | Out-Null
162
+ $siteCount++
163
+ }
164
+ }
165
+ Log "INFO`t-`t$siteCount`tpages attempted`tghpages crawl"
166
+
167
+ # ---------- Phase E: 社区仓库 README ----------
168
+ $community = @(
169
+ @('AdamPlatin123','awesome-dsh-plugins'),
170
+ @('omdsh-dev','dsh-plugin-dev'),
171
+ @('omdsh-dev','plugin-template'),
172
+ @('omdsh-dev','dsh-plugin-skills'),
173
+ @('vlln','plugin-registry'),
174
+ @('0xsline','awesome-deepseek-harness'),
175
+ @('awesome-dsh-plugin','awesome-dsh-plugin'),
176
+ @('Alex-Yanggg','awesome-DSH-plugin'),
177
+ @('bruc3van','awesome-dsh-plugin'),
178
+ @('Dominic789654','awesome-deepseek-harness'),
179
+ @('hikariming','dshfind'),
180
+ @('dsh-external','hub'),
181
+ @('titanwings','colleague-skill')
182
+ )
183
+ foreach ($pair in $community) {
184
+ $owner = $pair[0]; $repo = $pair[1]
185
+ Download @("https://raw.githubusercontent.com/$owner/$repo/HEAD/README.md",
186
+ "https://raw.githubusercontent.com/$owner/$repo/master/README.md",
187
+ "https://raw.githubusercontent.com/$owner/$repo/main/README.md") `
188
+ (Join-Path $dl "community\$repo.md")
189
+ Download @("https://api.github.com/repos/$owner/$repo") `
190
+ (Join-Path $dl "community\$repo.json") $ua
191
+ }
192
+
193
+ # ---------- Phase F: manifest ----------
194
+ Set-Content -Path (Join-Path $dl 'manifest.tsv') -Value $manifest -Encoding UTF8
195
+ Write-Output ("DONE: " + $manifest.Count + " 条记录 -> " + (Join-Path $dl 'manifest.tsv'))
@@ -1,91 +1,91 @@
1
- # dsh-plugin-guide 话题快照生成脚本
2
- # 用途: 抓取 GitHub topic:dsh-plugin 全量仓库清单,产出与 sources.md §D.2 记录一致的快照目录
3
- # <OutDir>/raw-github-api-page-<n>.json + repos.tsv + README.md(全量表)
4
- # 用法: pwsh -File scripts/gen-topic-snapshot.ps1 -OutDir <路径> [-PerPage 100] [-MaxPages 10] [-DelaySeconds 6]
5
- # 说明: 走 GitHub Search API(未认证 10 次/分钟、分页上限 1000 条),分页抓取、按 full_name 去重、按 star 降序;
6
- # 提供 $env:GH_TOKEN / -Token 后限速提到 30 次/分钟且更稳定。
7
- # 传输用 Invoke-WebRequest(PS 5.1 下 curl 数组参数的引号拆分会把 -H 头打碎——已规避)。
8
- # 与 08-13/08-14 各期快照同构,便于续期对比(新增/消失仓库用 repos.tsv diff)。
9
- param(
10
- [Parameter(Mandatory=$true)][string]$OutDir,
11
- [int]$PerPage = 100,
12
- [int]$MaxPages = 10,
13
- [int]$DelaySeconds = 6,
14
- [string]$Token = $env:GH_TOKEN
15
- )
16
- $ErrorActionPreference = 'Stop'
17
- $ProgressPreference = 'SilentlyContinue'
18
- New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
19
-
20
- $headers = @{ 'User-Agent' = 'dsh-plugin-guide-research'; 'Accept' = 'application/vnd.github+json' }
21
- if ($Token) { $headers['Authorization'] = "Bearer $Token" }
22
-
23
- $all = @()
24
- $total = -1
25
- for ($p = 1; $p -le $MaxPages; $p++) {
26
- $r = $null
27
- for ($a = 0; $a -lt 3 -and $null -eq $r; $a++) {
28
- try {
29
- $resp = Invoke-WebRequest -Uri "https://api.github.com/search/repositories?q=topic:dsh-plugin&per_page=$PerPage&page=$p" -Headers $headers -TimeoutSec 45 -UseBasicParsing
30
- $r = $resp.Content | ConvertFrom-Json
31
- } catch { Start-Sleep -Seconds 3 }
32
- }
33
- if ($null -eq $r) { Write-Output "page ${p} FAILED (after retries)"; break }
34
- if ($r.PSObject.Properties.Name -contains 'message') { Write-Output "page ${p}: API message $($r.message)"; break }
35
- if (@($r.items).Count -eq 0) { Write-Output "page ${p}: no items (end)"; break }
36
- $total = $r.total_count
37
- $all += @($r.items)
38
- $raw = Join-Path $OutDir "raw-github-api-page-$p.json"
39
- $r | ConvertTo-Json -Depth 6 | Set-Content $raw -Encoding UTF8
40
- Write-Output "page ${p}: total=$($r.total_count) items=$(@($r.items).Count)"
41
- Start-Sleep -Seconds $DelaySeconds
42
- if ($all.Count -ge $total -or @($r.items).Count -lt $PerPage) { break }
43
- }
44
-
45
- $uniq = @{}
46
- foreach ($i in $all) { if (-not $uniq.ContainsKey($i.full_name)) { $uniq[$i.full_name] = $i } }
47
- $rows = @($uniq.Values | Sort-Object -Property stargazers_count -Descending)
48
-
49
- $tsv = @("full_name`tstars`tlanguage`tlicense`tarchived`tpushed_at`tdescription")
50
- foreach ($i in $rows) {
51
- $desc = ($i.description -replace "[\r\n\t]", ' ')
52
- $tsv += "{0}`t{1}`t{2}`t{3}`t{4}`t{5}`t{6}" -f $i.full_name, $i.stargazers_count, $i.language, $i.license.spdx_id, $i.archived, $i.pushed_at, $desc
53
- }
54
- Set-Content -Path (Join-Path $OutDir 'repos.tsv') -Value ($tsv -join "`r`n") -Encoding UTF8
55
-
56
- $utc = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mmZ')
57
- $L = @()
58
- $L += '# DeepSeek Harness `dsh-plugin` 话题全量清单'
59
- $L += ''
60
- $L += '> 数据来源:GitHub Search API `q=topic:dsh-plugin`(公开话题页 <https://github.com/topics/dsh-plugin>)。'
61
- $L += "> 抓取时间:$utc(UTC)。API total_count $total;本清单去重收录 $($rows.Count) 个。"
62
- $L += '> 注意:Search API 分页上限 1000 条,去重数与 total_count 都要记录(见 sources.md §D.2 惯例)。'
63
- $L += ''
64
- $L += '## 元信息'
65
- $L += ''
66
- $L += '| 项目 | 值 |'
67
- $L += '|---|---|'
68
- $L += '| 话题 | [dsh-plugin](https://github.com/topics/dsh-plugin) |'
69
- $L += "| 仓库总数 | $($rows.Count)(API total_count $total) |"
70
- $L += "| 抓取时间 (UTC) | $utc |"
71
- $L += '| 排序 | star 数降序 |'
72
- $L += ''
73
- $L += '## 全量清单(按 star 排序)'
74
- $L += ''
75
- $L += '| # | 仓库 | ⭐ | 语言 | 许可 | 归档 | 功能 / 效果(官方描述) | 最近推送 (UTC) | 话题标签 |'
76
- $L += '|---|------|----|------|------|------|----------------|----------------|----------|'
77
- $n = 0
78
- foreach ($i in $rows) {
79
- $n++
80
- $name = $i.full_name
81
- $stars = $i.stargazers_count
82
- $lang = $i.language
83
- $lic = if ($i.license) { $i.license.spdx_id } else { '-' }
84
- $arch = if ($i.archived) { '是' } else { '否' }
85
- $desc = ($i.description -replace '\|','\|' -replace "[\r\n]", ' ')
86
- $push = $i.pushed_at
87
- $topics = if ($i.topics) { ($i.topics -join ', ') } else { '' }
88
- $L += "| $n | [$name](https://github.com/$name) | $stars | $lang | $lic | $arch | $desc | $push | $topics |"
89
- }
90
- Set-Content -Path (Join-Path $OutDir 'README.md') -Value ($L -join "`r`n") -Encoding UTF8
91
- Write-Output "DONE: $($rows.Count) unique repos -> $OutDir (README/repos.tsv/raw pages)"
1
+ # dsh-plugin-guide 话题快照生成脚本
2
+ # 用途: 抓取 GitHub topic:dsh-plugin 全量仓库清单,产出与 sources.md §D.2 记录一致的快照目录
3
+ # <OutDir>/raw-github-api-page-<n>.json + repos.tsv + README.md(全量表)
4
+ # 用法: pwsh -File scripts/gen-topic-snapshot.ps1 -OutDir <路径> [-PerPage 100] [-MaxPages 10] [-DelaySeconds 6]
5
+ # 说明: 走 GitHub Search API(未认证 10 次/分钟、分页上限 1000 条),分页抓取、按 full_name 去重、按 star 降序;
6
+ # 提供 $env:GH_TOKEN / -Token 后限速提到 30 次/分钟且更稳定。
7
+ # 传输用 Invoke-WebRequest(PS 5.1 下 curl 数组参数的引号拆分会把 -H 头打碎——已规避)。
8
+ # 与 08-13/08-14 各期快照同构,便于续期对比(新增/消失仓库用 repos.tsv diff)。
9
+ param(
10
+ [Parameter(Mandatory=$true)][string]$OutDir,
11
+ [int]$PerPage = 100,
12
+ [int]$MaxPages = 10,
13
+ [int]$DelaySeconds = 6,
14
+ [string]$Token = $env:GH_TOKEN
15
+ )
16
+ $ErrorActionPreference = 'Stop'
17
+ $ProgressPreference = 'SilentlyContinue'
18
+ New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
19
+
20
+ $headers = @{ 'User-Agent' = 'dsh-plugin-guide-research'; 'Accept' = 'application/vnd.github+json' }
21
+ if ($Token) { $headers['Authorization'] = "Bearer $Token" }
22
+
23
+ $all = @()
24
+ $total = -1
25
+ for ($p = 1; $p -le $MaxPages; $p++) {
26
+ $r = $null
27
+ for ($a = 0; $a -lt 3 -and $null -eq $r; $a++) {
28
+ try {
29
+ $resp = Invoke-WebRequest -Uri "https://api.github.com/search/repositories?q=topic:dsh-plugin&per_page=$PerPage&page=$p" -Headers $headers -TimeoutSec 45 -UseBasicParsing
30
+ $r = $resp.Content | ConvertFrom-Json
31
+ } catch { Start-Sleep -Seconds 3 }
32
+ }
33
+ if ($null -eq $r) { Write-Output "page ${p} FAILED (after retries)"; break }
34
+ if ($r.PSObject.Properties.Name -contains 'message') { Write-Output "page ${p}: API message $($r.message)"; break }
35
+ if (@($r.items).Count -eq 0) { Write-Output "page ${p}: no items (end)"; break }
36
+ $total = $r.total_count
37
+ $all += @($r.items)
38
+ $raw = Join-Path $OutDir "raw-github-api-page-$p.json"
39
+ $r | ConvertTo-Json -Depth 6 | Set-Content $raw -Encoding UTF8
40
+ Write-Output "page ${p}: total=$($r.total_count) items=$(@($r.items).Count)"
41
+ Start-Sleep -Seconds $DelaySeconds
42
+ if ($all.Count -ge $total -or @($r.items).Count -lt $PerPage) { break }
43
+ }
44
+
45
+ $uniq = @{}
46
+ foreach ($i in $all) { if (-not $uniq.ContainsKey($i.full_name)) { $uniq[$i.full_name] = $i } }
47
+ $rows = @($uniq.Values | Sort-Object -Property stargazers_count -Descending)
48
+
49
+ $tsv = @("full_name`tstars`tlanguage`tlicense`tarchived`tpushed_at`tdescription")
50
+ foreach ($i in $rows) {
51
+ $desc = ($i.description -replace "[\r\n\t]", ' ')
52
+ $tsv += "{0}`t{1}`t{2}`t{3}`t{4}`t{5}`t{6}" -f $i.full_name, $i.stargazers_count, $i.language, $i.license.spdx_id, $i.archived, $i.pushed_at, $desc
53
+ }
54
+ Set-Content -Path (Join-Path $OutDir 'repos.tsv') -Value ($tsv -join "`r`n") -Encoding UTF8
55
+
56
+ $utc = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mmZ')
57
+ $L = @()
58
+ $L += '# DeepSeek Harness `dsh-plugin` 话题全量清单'
59
+ $L += ''
60
+ $L += '> 数据来源:GitHub Search API `q=topic:dsh-plugin`(公开话题页 <https://github.com/topics/dsh-plugin>)。'
61
+ $L += "> 抓取时间:$utc(UTC)。API total_count $total;本清单去重收录 $($rows.Count) 个。"
62
+ $L += '> 注意:Search API 分页上限 1000 条,去重数与 total_count 都要记录(见 sources.md §D.2 惯例)。'
63
+ $L += ''
64
+ $L += '## 元信息'
65
+ $L += ''
66
+ $L += '| 项目 | 值 |'
67
+ $L += '|---|---|'
68
+ $L += '| 话题 | [dsh-plugin](https://github.com/topics/dsh-plugin) |'
69
+ $L += "| 仓库总数 | $($rows.Count)(API total_count $total) |"
70
+ $L += "| 抓取时间 (UTC) | $utc |"
71
+ $L += '| 排序 | star 数降序 |'
72
+ $L += ''
73
+ $L += '## 全量清单(按 star 排序)'
74
+ $L += ''
75
+ $L += '| # | 仓库 | ⭐ | 语言 | 许可 | 归档 | 功能 / 效果(官方描述) | 最近推送 (UTC) | 话题标签 |'
76
+ $L += '|---|------|----|------|------|------|----------------|----------------|----------|'
77
+ $n = 0
78
+ foreach ($i in $rows) {
79
+ $n++
80
+ $name = $i.full_name
81
+ $stars = $i.stargazers_count
82
+ $lang = $i.language
83
+ $lic = if ($i.license) { $i.license.spdx_id } else { '-' }
84
+ $arch = if ($i.archived) { '是' } else { '否' }
85
+ $desc = ($i.description -replace '\|','\|' -replace "[\r\n]", ' ')
86
+ $push = $i.pushed_at
87
+ $topics = if ($i.topics) { ($i.topics -join ', ') } else { '' }
88
+ $L += "| $n | [$name](https://github.com/$name) | $stars | $lang | $lic | $arch | $desc | $push | $topics |"
89
+ }
90
+ Set-Content -Path (Join-Path $OutDir 'README.md') -Value ($L -join "`r`n") -Encoding UTF8
91
+ Write-Output "DONE: $($rows.Count) unique repos -> $OutDir (README/repos.tsv/raw pages)"