@sokeai/cli 1.0.32 → 1.0.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sokeai/cli",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "description": "授客AI官方CLI工具 - 支持AI Agent Skills",
5
5
  "bin": {
6
6
  "soke-cli": "scripts/run.js"
@@ -491,43 +491,50 @@ function downloadFile(url, dest) {
491
491
  }
492
492
 
493
493
  // 执行下载
494
- downloadFile(downloadURL, binaryPath)
495
- .then(() => {
496
- // 设置可执行权限(非 Windows 平台)
497
- if (platform !== 'win32') {
498
- try {
499
- fs.chmodSync(binaryPath, 0o755);
500
- console.log('已设置可执行权限');
501
- } catch (err) {
502
- console.error('设置可执行权限失败:', err.message);
503
- process.exit(1);
494
+ if (require.main === module) {
495
+ downloadFile(downloadURL, binaryPath)
496
+ .then(() => {
497
+ // 设置可执行权限(非 Windows 平台)
498
+ if (platform !== 'win32') {
499
+ try {
500
+ fs.chmodSync(binaryPath, 0o755);
501
+ console.log('已设置可执行权限');
502
+ } catch (err) {
503
+ console.error('设置可执行权限失败:', err.message);
504
+ process.exit(1);
505
+ }
504
506
  }
505
- }
506
507
 
507
- try {
508
- syncSkillsToSokeclawWorkspace();
509
- } catch (_) {}
508
+ try {
509
+ syncSkillsToSokeclawWorkspace();
510
+ } catch (_) {}
510
511
 
511
- try {
512
- syncSkillsToWorkclawRegistry();
513
- } catch (_) {}
512
+ try {
513
+ syncSkillsToWorkclawRegistry();
514
+ } catch (_) {}
514
515
 
515
- return maybeAssistGuiPath();
516
- })
517
- .then(() => {
518
- console.log('soke-cli 安装成功!');
519
- console.log(`二进制文件位置: ${binaryPath}`);
520
- console.log('\n使用方法:');
521
- console.log(' soke-cli --help');
522
- console.log(' soke-cli config init');
523
- console.log(' soke-cli auth login');
524
- })
525
- .catch((err) => {
526
- console.error('\n安装失败:', err.message);
527
- console.error('\n可能的原因:');
528
- console.error('1. 网络连接问题');
529
- console.error('2. GitHub Releases 中不存在该版本的二进制文件');
530
- console.error('3. 不支持当前平台');
531
- console.error('\n请访问 https://github.com/sokeai/soke-cli/releases 手动下载');
532
- process.exit(1);
533
- });
516
+ return maybeAssistGuiPath();
517
+ })
518
+ .then(() => {
519
+ console.log('soke-cli 安装成功!');
520
+ console.log(`二进制文件位置: ${binaryPath}`);
521
+ console.log('\n使用方法:');
522
+ console.log(' soke-cli --help');
523
+ console.log(' soke-cli config init');
524
+ console.log(' soke-cli auth login');
525
+ })
526
+ .catch((err) => {
527
+ console.error('\n安装失败:', err.message);
528
+ console.error('\n可能的原因:');
529
+ console.error('1. 网络连接问题');
530
+ console.error('2. GitHub Releases 中不存在该版本的二进制文件');
531
+ console.error('3. 不支持当前平台');
532
+ console.error('\n请访问 https://github.com/sokeai/soke-cli/releases 手动下载');
533
+ process.exit(1);
534
+ });
535
+ }
536
+
537
+ module.exports = {
538
+ syncSkillsToSokeclawWorkspace,
539
+ syncSkillsToWorkclawRegistry
540
+ };
@@ -111,50 +111,25 @@ echo ""
111
111
  echo -e "${YELLOW}[3.5/4] 分发 Skills 到本地 Agent...${NC}"
112
112
  if [ "$SKIP_GLOBAL" = false ]; then
113
113
  echo -e " 执行 scripts/install.js 同步 Skills..."
114
- # 注入特殊环境变量或者直接调用 node 执行
115
- # 我们只想要触发 syncSkillsToSokeclawWorkspace 和 syncSkillsToWorkclawRegistry
116
- # 但原 install.js 会尝试下载二进制文件,所以我们新建一个临时脚本或修改调用方式
117
114
 
118
- # 为了安全起见,这里直接使用 node 运行一小段脚本引入 install.js 中的逻辑
115
+ # 使用 node 调用 install.js 中导出的同步函数
119
116
  cat > ./scripts/sync-skills-local.js << 'EOF'
120
- const fs = require('fs');
121
- const path = require('path');
122
- const installCode = fs.readFileSync(path.join(__dirname, 'install.js'), 'utf8');
123
-
124
- // 提取需要的函数
125
- const syncFn1Match = installCode.match(/function syncSkillsToSokeclawWorkspace\(\) \{[\s\S]*?\n\}/);
126
- const syncFn2Match = installCode.match(/function syncSkillsToWorkclawRegistry\(\) \{[\s\S]*?\n\}/);
127
-
128
- // 我们更推荐直接利用已经写好的 js 模块(如果它是通过 module.exports 导出的)
129
- // 但因为 install.js 是直接执行的脚本,我们通过简单的 node 脚本手动拷贝
130
- const os = require('os');
131
- function copyDirRecursive(srcDir, destDir) {
132
- if (!fs.existsSync(srcDir)) return;
133
- if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
134
- const entries = fs.readdirSync(srcDir, { withFileTypes: true });
135
- for (const entry of entries) {
136
- const srcPath = path.join(srcDir, entry.name);
137
- const destPath = path.join(destDir, entry.name);
138
- if (entry.isDirectory()) { copyDirRecursive(srcPath, destPath); continue; }
139
- fs.copyFileSync(srcPath, destPath);
140
- }
117
+ const install = require('./install.js');
118
+
119
+ try {
120
+ console.log(" 同步到 Sokeclaw Workspace...");
121
+ install.syncSkillsToSokeclawWorkspace();
122
+ console.log(" ✓ Sokeclaw Workspace 同步成功");
123
+ } catch (e) {
124
+ console.error(" ✗ Sokeclaw Workspace 同步失败:", e.message);
141
125
  }
142
126
 
143
- const homeDir = os.homedir();
144
- const defaultSokeclawDir = path.join(homeDir, '.sokeclaw', 'openai-agents', 'workspaces', 'main', 'skills');
145
- const packageRoot = path.join(__dirname, '..');
146
- const packagedSkillsDir = path.join(packageRoot, 'skills');
147
-
148
- if (fs.existsSync(packagedSkillsDir)) {
149
- const skillNames = fs.readdirSync(packagedSkillsDir).filter(n => n.startsWith('soke-'));
150
- if (fs.existsSync(defaultSokeclawDir)) {
151
- for (const skillName of skillNames) {
152
- const src = path.join(packagedSkillsDir, skillName);
153
- const dest = path.join(defaultSokeclawDir, skillName);
154
- copyDirRecursive(src, dest);
155
- console.log(` ✓ 同步 ${skillName} 到 ${dest}`);
156
- }
157
- }
127
+ try {
128
+ console.log(" 同步到 Workclaw Registry...");
129
+ install.syncSkillsToWorkclawRegistry();
130
+ console.log(" ✓ Workclaw Registry 同步成功");
131
+ } catch (e) {
132
+ console.error(" ✗ Workclaw Registry 同步失败:", e.message);
158
133
  }
159
134
  EOF
160
135
  node ./scripts/sync-skills-local.js
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: soke-business-training-report
3
+ description: 生成某场业务培训考试的整体分析报告,包括参考人数、通过率、平均分、最高分及未通过学员名单。
4
+ ---
5
+
6
+ # 培训考试整体分析报告 Skill
7
+
8
+ ## 目标
9
+ 根据用户提供的培训/考试名称,通过调用开放平台的考试相关 API,自动生成一份结构化的培训考试分析报告。
10
+
11
+ ## 触发条件
12
+ 当用户提出类似以下问题时,应使用此 Skill:
13
+ - "帮我分析一下本次业务培训的考试情况"
14
+ - "统计一下这次培训的通过率"
15
+ - "输出一份『新员工入职培训』的考试报告"
16
+
17
+ ## 执行步骤
18
+
19
+ ### 第一步:确认目标考试
20
+ 1. 调用 `GET /exam/exam/list` 接口,获取考试列表。
21
+ - **必填参数**:`start_time` 和 `end_time`(Unix 时间戳,单位毫秒),时间差不超过 365 天。
22
+ - 若用户未提供时间范围,自动设置为近 3 个月。
23
+ 2. 根据用户提供的培训名称关键词,在返回的 `data.list` 中模糊匹配 `title` 字段。
24
+ - 如果匹配到多个,列出候选供用户选择。
25
+ 3. 记录目标考试的 `uuid`、`title`、`total_score`、`pass_score`。
26
+
27
+ ### 第二步:获取考试学员成绩列表
28
+ 1. 调用 `GET /exam/user/list` 接口,参数 `exam_id` 为考试 UUID。
29
+ 2. 提取每个学员的 `pass_status`(passed/unpassed/not_attempt)、`last_score`。
30
+
31
+ ### 第三步:计算整体统计指标
32
+ - 参考人数(排除 not_attempt)
33
+ - 通过人数(passed)
34
+ - 通过率、平均分、最高分
35
+ - 未通过学员列表
36
+
37
+ ### 第四步:输出报告
38
+ 按照以下格式输出:
39
+
40
+ 📊 【培训名称】考试分析报告
41
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
+ 👥 参考人数:XX 人
43
+ ✅ 通过人数:XX 人
44
+ 📈 通过率:XX%
45
+ 📊 平均分:XX 分(满分 XX 分)
46
+ 🏆 最高分:XX 分
47
+ ❌ 未通过学员:XX 人
48
+ - 学员A(得分:XX)
49
+ ...
50
+
51
+ ## API 调用与鉴权
52
+ - 基础 URL:`https://oapi.soke.cn`
53
+ - 接口需要 `access_token`,在 Agent 环境中自动获取,无需手动处理。
54
+
55
+ ## 注意事项
56
+ - `start_time` 和 `end_time` 必填,Skill 自动生成。
57
+ - 注意区分 `not_attempt`(未参考)、`reviewing`(阅卷中)、`unpassed`(未通过)和 `passed`(通过)。