skillgo 1.0.0 → 1.0.1
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 -1
- package/bin/skillgo.js +68 -13
- package/package.json +8 -2
package/README.md
CHANGED
package/bin/skillgo.js
CHANGED
|
@@ -1,20 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const isDebug = () => process.env.SKILLGO_DEBUG === '1' || process.env.SKILLGO_DEBUG === 'true'
|
|
5
|
+
const API_BASE = process.env.SKILLGO_API || 'http://skillgo.cn'
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
if (!res.ok) throw new Error(`请求失败: ${res.status}`)
|
|
9
|
-
return res.json()
|
|
7
|
+
const debug = (...args) => {
|
|
8
|
+
if (isDebug()) console.error('[skillgo]', ...args)
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
const wrapFetch = (fn) => async (...args) => {
|
|
12
|
+
try {
|
|
13
|
+
return await fn(...args)
|
|
14
|
+
} catch (e) {
|
|
15
|
+
if (isDebug()) {
|
|
16
|
+
console.error('[skillgo] 请求失败:', e.message)
|
|
17
|
+
if (e.cause) console.error('[skillgo] cause:', e.cause)
|
|
18
|
+
if (e.stack) console.error('[skillgo] stack:', e.stack)
|
|
19
|
+
}
|
|
20
|
+
const msg = e.message || ''
|
|
21
|
+
const isNetworkErr = msg.includes('fetch failed') || e.cause?.code === 'ECONNREFUSED' || e.cause?.code === 'ENOTFOUND'
|
|
22
|
+
if (isNetworkErr) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`无法连接 SkillGo API (${API_BASE})。请检查网络或设置 SKILLGO_API`
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
throw e
|
|
28
|
+
}
|
|
16
29
|
}
|
|
17
30
|
|
|
31
|
+
const fetchJson = wrapFetch(async (path) => {
|
|
32
|
+
const url = `${API_BASE}${path}`
|
|
33
|
+
debug('GET', url)
|
|
34
|
+
const start = Date.now()
|
|
35
|
+
const res = await fetch(url)
|
|
36
|
+
debug('响应', res.status, `${Date.now() - start}ms`)
|
|
37
|
+
if (!res.ok) throw new Error(`请求失败: ${res.status} ${res.statusText}`)
|
|
38
|
+
return res.json()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const fetchText = wrapFetch(async (path) => {
|
|
42
|
+
const url = `${API_BASE}${path}`
|
|
43
|
+
debug('GET', url)
|
|
44
|
+
const start = Date.now()
|
|
45
|
+
const res = await fetch(url)
|
|
46
|
+
debug('响应', res.status, `${Date.now() - start}ms`)
|
|
47
|
+
if (!res.ok) throw new Error(`请求失败: ${res.status} ${res.statusText}`)
|
|
48
|
+
return res.text()
|
|
49
|
+
})
|
|
50
|
+
|
|
18
51
|
const search = async (keyword) => {
|
|
19
52
|
const data = await fetchJson(`/api/skills?status=published&q=${encodeURIComponent(keyword)}&pageSize=20`)
|
|
20
53
|
const items = data.items || []
|
|
@@ -30,12 +63,15 @@ const search = async (keyword) => {
|
|
|
30
63
|
}
|
|
31
64
|
|
|
32
65
|
const install = async (slug, version, cwd) => {
|
|
66
|
+
debug('install', { slug, version, cwd })
|
|
33
67
|
let data
|
|
34
68
|
if (version) {
|
|
35
69
|
data = await fetchJson(`/api/skills?status=published&slug=${encodeURIComponent(slug)}&version=${encodeURIComponent(version)}`)
|
|
36
70
|
} else {
|
|
71
|
+
debug('从 MCP 获取技能列表')
|
|
37
72
|
const all = await fetchJson('/mcp/skills?latest=true')
|
|
38
73
|
const skills = all.skills || []
|
|
74
|
+
debug('MCP 返回', skills.length, '个技能')
|
|
39
75
|
const skill = skills.find((s) => s.slug === slug)
|
|
40
76
|
if (!skill) {
|
|
41
77
|
console.error(`未找到技能: ${slug}`)
|
|
@@ -51,9 +87,11 @@ const install = async (slug, version, cwd) => {
|
|
|
51
87
|
return
|
|
52
88
|
}
|
|
53
89
|
const items = data.items || []
|
|
90
|
+
debug('查询结果:', items.length, '条')
|
|
54
91
|
const skill = items[0]
|
|
55
92
|
if (!skill) {
|
|
56
|
-
|
|
93
|
+
debug('未找到匹配技能,slug=', slug, 'version=', version)
|
|
94
|
+
console.error(`未找到技能: ${slug}${version ? '@' + version : ''}`)
|
|
57
95
|
process.exit(1)
|
|
58
96
|
}
|
|
59
97
|
if (skill.review_tier === 'none' || !skill.review_tier) {
|
|
@@ -119,7 +157,15 @@ const update = async (cwd) => {
|
|
|
119
157
|
}
|
|
120
158
|
|
|
121
159
|
const main = async () => {
|
|
122
|
-
|
|
160
|
+
let args = process.argv.slice(2)
|
|
161
|
+
if (args.includes('--debug') || args.includes('-d')) {
|
|
162
|
+
args = args.filter((a) => a !== '--debug' && a !== '-d')
|
|
163
|
+
process.env.SKILLGO_DEBUG = '1'
|
|
164
|
+
}
|
|
165
|
+
if (isDebug()) {
|
|
166
|
+
debug('API_BASE:', process.env.SKILLGO_API || '(默认)', '->', API_BASE)
|
|
167
|
+
debug('命令:', args[0], '参数:', args.slice(1))
|
|
168
|
+
}
|
|
123
169
|
const cmd = args[0]
|
|
124
170
|
const cwd = process.cwd()
|
|
125
171
|
|
|
@@ -166,12 +212,21 @@ SkillGo CLI - 技能管理工具 (https://skillgo.cn)
|
|
|
166
212
|
skillgo list 列出已安装技能
|
|
167
213
|
skillgo update --all 更新所有已安装技能
|
|
168
214
|
|
|
215
|
+
选项:
|
|
216
|
+
--debug, -d 调试模式,输出请求详情和错误堆栈
|
|
217
|
+
|
|
169
218
|
环境变量:
|
|
170
|
-
SKILLGO_API
|
|
219
|
+
SKILLGO_API API 地址,默认 http://skillgo.cn
|
|
220
|
+
SKILLGO_DEBUG 设为 1 启用调试模式
|
|
171
221
|
`)
|
|
172
222
|
}
|
|
173
223
|
|
|
174
224
|
main().catch((e) => {
|
|
175
|
-
|
|
225
|
+
if (isDebug()) {
|
|
226
|
+
console.error('[skillgo] 错误:', e.message)
|
|
227
|
+
if (e.stack) console.error(e.stack)
|
|
228
|
+
} else {
|
|
229
|
+
console.error(e.message)
|
|
230
|
+
}
|
|
176
231
|
process.exit(1)
|
|
177
232
|
})
|
package/package.json
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillgo",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "SkillGo 命令行工具 - 搜索、安装、管理 Agent 技能 (https://skillgo.cn)",
|
|
5
5
|
"bin": {
|
|
6
6
|
"skillgo": "bin/skillgo.js"
|
|
7
7
|
},
|
|
8
|
-
"keywords": [
|
|
8
|
+
"keywords": [
|
|
9
|
+
"skillgo",
|
|
10
|
+
"cli",
|
|
11
|
+
"skill",
|
|
12
|
+
"agent",
|
|
13
|
+
"skillgo.cn"
|
|
14
|
+
],
|
|
9
15
|
"author": "",
|
|
10
16
|
"license": "Apache-2.0",
|
|
11
17
|
"repository": {
|