skillfree 0.1.20 → 0.1.21
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/install.sh +94 -112
- package/package.json +1 -1
- package/scripts/commands/auth.js +42 -27
package/install.sh
CHANGED
|
@@ -1,136 +1,118 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# curl -fsSL https://
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
# SkillFree 一键安装脚本
|
|
3
|
+
# curl -fsSL https://cdn.jsdelivr.net/gh/ChongC1990/install@main/install.sh | bash
|
|
4
|
+
|
|
5
|
+
# ── 颜色定义 ─────────────────────────────────────────────────────────────────
|
|
6
|
+
CYAN='\033[0;36m'
|
|
7
|
+
BOLD_CYAN='\033[1;36m'
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
BOLD_GREEN='\033[1;32m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
BOLD='\033[1m'
|
|
13
|
+
DIM='\033[2m'
|
|
14
|
+
NC='\033[0m'
|
|
15
|
+
|
|
16
|
+
info() { echo -e "${CYAN} →${NC} $*"; }
|
|
17
|
+
success() { echo -e "${BOLD_GREEN} ✓${NC} $*"; }
|
|
18
|
+
warn() { echo -e "${YELLOW} ⚠${NC} $*"; }
|
|
19
|
+
err() { echo -e "${RED} ✗${NC} $*"; exit 1; }
|
|
20
|
+
step() { echo -e "\n${BOLD}$*${NC}"; }
|
|
21
|
+
|
|
22
|
+
# ── ASCII Banner ──────────────────────────────────────────────────────────────
|
|
23
|
+
clear
|
|
13
24
|
echo ""
|
|
14
|
-
echo -e "${
|
|
15
|
-
|
|
25
|
+
echo -e "${BOLD_CYAN}"
|
|
26
|
+
cat << 'EOF'
|
|
27
|
+
███████╗██╗ ██╗██╗██╗ ██╗ ███████╗██████╗ ███████╗███████╗
|
|
28
|
+
██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝██╔══██╗██╔════╝██╔════╝
|
|
29
|
+
███████╗█████╔╝ ██║██║ ██║ █████╗ ██████╔╝█████╗ █████╗
|
|
30
|
+
╚════██║██╔═██╗ ██║██║ ██║ ██╔══╝ ██╔══██╗██╔══╝ ██╔══╝
|
|
31
|
+
███████║██║ ██╗██║███████╗███████╗██║ ██║ ██║███████╗███████╗
|
|
32
|
+
╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝
|
|
33
|
+
EOF
|
|
34
|
+
echo -e "${NC}"
|
|
35
|
+
echo -e " ${DIM}🦞 一个 Key,调用 53+ 顶级 AI 模型${NC}"
|
|
36
|
+
echo -e " ${DIM} Chat · Image · Video · TTS · Music · OCR · Search${NC}"
|
|
16
37
|
echo ""
|
|
38
|
+
echo -e " ${DIM}────────────────────────────────────────────────────${NC}"
|
|
39
|
+
echo ""
|
|
40
|
+
|
|
41
|
+
# ── Step 1: 检查环境 ──────────────────────────────────────────────────────────
|
|
42
|
+
step "[ 1 / 3 ] 检查环境"
|
|
17
43
|
|
|
18
|
-
# ── 1. 检查 Node.js ──────────────────────────────────────────────────────────
|
|
19
44
|
if ! command -v node &>/dev/null; then
|
|
20
|
-
err "
|
|
45
|
+
err "未检测到 Node.js,请先安装:https://nodejs.org(需要 18+)"
|
|
21
46
|
fi
|
|
22
47
|
NODE_VER=$(node -e "process.stdout.write(process.versions.node.split('.')[0])")
|
|
23
|
-
[ "$NODE_VER" -lt 18 ]
|
|
48
|
+
if [ "$NODE_VER" -lt 18 ]; then
|
|
49
|
+
err "Node.js 版本过低(当前 v$(node -v)),需要 18+"
|
|
50
|
+
fi
|
|
51
|
+
success "Node.js $(node -v)"
|
|
24
52
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|| warn "全局安装需要权限,尝试 sudo npm install -g skillfree"
|
|
30
|
-
success "CLI 安装完成"
|
|
53
|
+
if ! command -v npm &>/dev/null; then
|
|
54
|
+
err "未检测到 npm,请检查 Node.js 安装"
|
|
55
|
+
fi
|
|
56
|
+
success "npm $(npm -v)"
|
|
31
57
|
|
|
32
|
-
# ──
|
|
58
|
+
# ── Step 2: 安装 CLI ──────────────────────────────────────────────────────────
|
|
59
|
+
step "[ 2 / 3 ] 安装 SkillFree CLI"
|
|
60
|
+
echo ""
|
|
61
|
+
echo -e " ${DIM}正在从 npm 安装 skillfree...${NC}"
|
|
33
62
|
echo ""
|
|
34
|
-
echo -e " 请前往 ${CYAN}https://skillfree.tech/app${NC} 获取 API Key"
|
|
35
|
-
read -rp " 输入你的 API Key (sk-sf-...): " API_KEY
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
|
|
64
|
+
INSTALL_OK=false
|
|
65
|
+
if npm install -g skillfree 2>&1 | sed 's/^/ /'; then
|
|
66
|
+
INSTALL_OK=true
|
|
39
67
|
else
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if
|
|
44
|
-
|
|
45
|
-
echo "# SkillFree" >> "$SHELL_RC"
|
|
46
|
-
echo "export SKILLFREE_API_KEY=\"$API_KEY\"" >> "$SHELL_RC"
|
|
47
|
-
else
|
|
48
|
-
sed -i.bak "s/export SKILLFREE_API_KEY=.*/export SKILLFREE_API_KEY=\"$API_KEY\"/" "$SHELL_RC"
|
|
49
|
-
fi
|
|
50
|
-
export SKILLFREE_API_KEY="$API_KEY"
|
|
51
|
-
success "API Key 已写入 $SHELL_RC"
|
|
52
|
-
|
|
53
|
-
# ── 5. 自动配置各 AI 工具 ────────────────────────────────────────────────────
|
|
54
|
-
SKILL_SRC_DIR="$HOME/.skillfree/skill"
|
|
55
|
-
mkdir -p "$SKILL_SRC_DIR"
|
|
56
|
-
|
|
57
|
-
# 获取已安装包里的 SKILL.md(优先用本地,否则下载)
|
|
58
|
-
NPM_SKILL_MD="$(npm root -g 2>/dev/null)/skillfree/SKILL.md"
|
|
59
|
-
if [ -f "$NPM_SKILL_MD" ]; then
|
|
60
|
-
cp "$NPM_SKILL_MD" "$SKILL_SRC_DIR/SKILL.md"
|
|
61
|
-
else
|
|
62
|
-
curl -fsSL "https://skillfree.tech/skill/SKILL.md" -o "$SKILL_SRC_DIR/SKILL.md" 2>/dev/null \
|
|
63
|
-
|| echo "# SkillFree\nUse skillfree CLI for AI tasks." > "$SKILL_SRC_DIR/SKILL.md"
|
|
68
|
+
echo ""
|
|
69
|
+
warn "权限不足,尝试 sudo..."
|
|
70
|
+
echo ""
|
|
71
|
+
if sudo npm install -g skillfree 2>&1 | sed 's/^/ /'; then
|
|
72
|
+
INSTALL_OK=true
|
|
64
73
|
fi
|
|
74
|
+
fi
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
mkdir -p "$OPENCLAW_SKILLS_DIR"
|
|
70
|
-
cp "$SKILL_SRC_DIR/SKILL.md" "$OPENCLAW_SKILLS_DIR/SKILL.md"
|
|
71
|
-
success "OpenClaw skill 已安装 → $OPENCLAW_SKILLS_DIR/"
|
|
76
|
+
if [ "$INSTALL_OK" = false ]; then
|
|
77
|
+
err "安装失败,请手动运行:sudo npm install -g skillfree"
|
|
78
|
+
fi
|
|
72
79
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
node - <<NODEJS
|
|
76
|
-
const fs = require('fs'), path = require('path')
|
|
77
|
-
const cfgPath = '$OPENCLAW_CFG'
|
|
78
|
-
let cfg = {}
|
|
79
|
-
try { cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8')) } catch {}
|
|
80
|
-
cfg.skills = cfg.skills || {}
|
|
81
|
-
cfg.skills.entries = cfg.skills.entries || {}
|
|
82
|
-
cfg.skills.entries['skillfree'] = {
|
|
83
|
-
enabled: true,
|
|
84
|
-
apiKey: '$API_KEY'
|
|
85
|
-
}
|
|
86
|
-
// 确保 ~/.openclaw/skills 在扫描路径里(通常已内置,但加上无妨)
|
|
87
|
-
cfg.skills.load = cfg.skills.load || {}
|
|
88
|
-
fs.mkdirSync(path.dirname(cfgPath), { recursive: true })
|
|
89
|
-
fs.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2))
|
|
90
|
-
console.log('openclaw.json 已更新')
|
|
91
|
-
NODEJS
|
|
92
|
-
success "openclaw.json 已注入 API Key(skill 下次启动自动生效)"
|
|
93
|
-
fi
|
|
80
|
+
echo ""
|
|
81
|
+
success "SkillFree CLI 安装完成"
|
|
94
82
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
mkdir -p "$dir/skillfree"
|
|
99
|
-
cp "$SKILL_SRC_DIR/SKILL.md" "$dir/skillfree/SKILL.md"
|
|
100
|
-
success "已同步到 $dir/skillfree/"
|
|
101
|
-
fi
|
|
102
|
-
done
|
|
83
|
+
# 刷新 PATH(nvm 等工具安装后 CLI 可能还不在当前 shell 的 PATH 里)
|
|
84
|
+
hash -r 2>/dev/null || true
|
|
85
|
+
export PATH="$(npm root -g)/../bin:$PATH"
|
|
103
86
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
87
|
+
if ! command -v skillfree &>/dev/null; then
|
|
88
|
+
warn "CLI 已安装,但当前终端 PATH 未更新"
|
|
89
|
+
warn "请新开一个终端窗口,然后运行:skillfree auth login"
|
|
90
|
+
echo ""
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
110
93
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
94
|
+
# ── Step 3: 登录 ──────────────────────────────────────────────────────────────
|
|
95
|
+
step "[ 3 / 3 ] 登录账号"
|
|
96
|
+
echo ""
|
|
97
|
+
echo -e " 还没有账号?${CYAN}https://skillfree.tech/app${NC} 免费注册"
|
|
98
|
+
echo -e " 注册后进入控制台 → API Keys → 创建一个 Key,粘贴到下方"
|
|
99
|
+
echo ""
|
|
117
100
|
|
|
118
|
-
|
|
119
|
-
if [ -d "$HOME/.continue" ]; then
|
|
120
|
-
mkdir -p "$HOME/.continue/skills/skillfree"
|
|
121
|
-
cp "$SKILL_SRC_DIR/SKILL.md" "$HOME/.continue/skills/skillfree/SKILL.md"
|
|
122
|
-
success "Continue.dev 配置完成 → ~/.continue/skills/skillfree/"
|
|
123
|
-
fi
|
|
124
|
-
fi
|
|
101
|
+
skillfree auth login
|
|
125
102
|
|
|
126
|
-
# ──
|
|
103
|
+
# ── 完成 ──────────────────────────────────────────────────────────────────────
|
|
104
|
+
echo ""
|
|
105
|
+
echo -e " ${DIM}────────────────────────────────────────────────────${NC}"
|
|
106
|
+
echo ""
|
|
107
|
+
echo -e "${BOLD_GREEN} 🎉 全部搞定!开始召唤龙虾吧${NC}"
|
|
127
108
|
echo ""
|
|
128
|
-
echo -e "${
|
|
109
|
+
echo -e " ${BOLD}快速体验:${NC}"
|
|
110
|
+
echo -e " ${CYAN} $ skillfree pilot --type chat --prompt \"你好\"${NC}"
|
|
111
|
+
echo -e " ${CYAN} $ skillfree pilot --type image --prompt \"赛博朋克的上海\" --output ./img.png${NC}"
|
|
112
|
+
echo -e " ${CYAN} $ skillfree pilot --type search --prompt \"今天的 AI 新闻\"${NC}"
|
|
129
113
|
echo ""
|
|
130
|
-
echo -e " ${
|
|
131
|
-
echo -e " $
|
|
132
|
-
echo -e " $ skillfree pilot --type image --prompt \"赛博朋克的上海\" --output ./img.png"
|
|
114
|
+
echo -e " ${DIM} skillfree models # 查看所有模型${NC}"
|
|
115
|
+
echo -e " ${DIM} skillfree credits # 查看积分余额${NC}"
|
|
133
116
|
echo ""
|
|
134
|
-
echo -e " ${
|
|
135
|
-
echo -e " ${CYAN}查看文档:${NC} https://skillfree.tech/app/docs"
|
|
117
|
+
echo -e " ${DIM}充值积分:${NC}${CYAN}https://skillfree.tech/app/topup${NC}"
|
|
136
118
|
echo ""
|
package/package.json
CHANGED
package/scripts/commands/auth.js
CHANGED
|
@@ -61,40 +61,55 @@ function injectToOpenclaw(apiKey) {
|
|
|
61
61
|
|
|
62
62
|
async function authLogin() {
|
|
63
63
|
console.log(`\n🦞 SkillFree 登录`)
|
|
64
|
-
console.log(`
|
|
64
|
+
console.log(` 还没有账号?前往注册:${BASE_URL}/app`)
|
|
65
|
+
console.log(` 注册后在控制台 → API Keys → 创建 Key\n`)
|
|
65
66
|
|
|
66
67
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
67
68
|
const ask = (q) => new Promise(resolve => rl.question(q, resolve))
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
let success = false
|
|
71
|
+
while (!success) {
|
|
72
|
+
const key = (await ask('请粘贴 API Key (sk-sf-...),输入 q 跳过: ')).trim()
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
if (key === 'q' || key === '') {
|
|
75
|
+
console.log('\n⏭ 已跳过登录,稍后可运行 skillfree auth login 完成配置')
|
|
76
|
+
rl.close()
|
|
77
|
+
return
|
|
78
|
+
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
80
|
+
if (!key.startsWith('sk-sf-')) {
|
|
81
|
+
console.log('❌ 格式不对,Key 应以 sk-sf- 开头,请重新输入\n')
|
|
82
|
+
continue
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 验证 key 是否有效
|
|
86
|
+
process.stdout.write('验证中...')
|
|
87
|
+
try {
|
|
88
|
+
const res = await fetch(`${BASE_URL}/v1/balance`, {
|
|
89
|
+
headers: { 'Authorization': `Bearer ${key}` }
|
|
90
|
+
})
|
|
91
|
+
if (!res.ok) {
|
|
92
|
+
console.log(` ❌ (HTTP ${res.status})`)
|
|
93
|
+
console.log('API Key 无效,请检查后重新输入\n')
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
const data = await res.json()
|
|
97
|
+
saveConfig({ apiKey: key })
|
|
98
|
+
injectToOpenclaw(key)
|
|
99
|
+
console.log(` ✅\n`)
|
|
100
|
+
console.log(`🎉 登录成功!当前积分:${data.credits}`)
|
|
101
|
+
console.log(`\n快速开始:`)
|
|
102
|
+
console.log(` skillfree pilot --type chat --model DeepSeek-V3.2-Fast --prompt "你好"`)
|
|
103
|
+
console.log(` skillfree pilot --type chat --model claude-sonnet-4-6 --prompt "你好"`)
|
|
104
|
+
console.log(` skillfree models # 查看所有可用模型`)
|
|
105
|
+
success = true
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.log(` ❌`)
|
|
108
|
+
console.log(`网络错误(${e.message}),请检查网络后重试\n`)
|
|
109
|
+
}
|
|
97
110
|
}
|
|
111
|
+
|
|
112
|
+
rl.close()
|
|
98
113
|
}
|
|
99
114
|
|
|
100
115
|
async function authStatus() {
|