zhitalk 0.0.11 → 0.0.12

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.
Files changed (2) hide show
  1. package/dist/install.js +105 -31
  2. package/package.json +1 -1
package/dist/install.js CHANGED
@@ -5,34 +5,112 @@ import { execSync } from 'child_process';
5
5
  import { WORKSPACE_DIR, CONFIG_PATH } from './agent/config.js';
6
6
  import { initDb } from './agent/db.js';
7
7
  const SKILLS_DIR = path.join(WORKSPACE_DIR, 'skills');
8
+ // 核心 skills
9
+ const CORE_SKILLS = [
10
+ {
11
+ name: 'find-skills',
12
+ repo: 'vercel-labs/skills',
13
+ path: 'skills/find-skills',
14
+ },
15
+ {
16
+ name: 'skill-creator',
17
+ repo: 'anthropics/skills',
18
+ path: 'skills/skill-creator',
19
+ },
20
+ ];
21
+ // 可选的常用 skills,默认一起安装
22
+ const OPTIONAL_SKILLS = [
23
+ {
24
+ name: 'canvas-design',
25
+ repo: 'anthropics/skills',
26
+ path: 'skills/canvas-design',
27
+ },
28
+ { name: 'docx', repo: 'anthropics/skills', path: 'skills/docx' },
29
+ { name: 'pdf', repo: 'anthropics/skills', path: 'skills/pdf' },
30
+ { name: 'pptx', repo: 'anthropics/skills', path: 'skills/pptx' },
31
+ { name: 'xlsx', repo: 'anthropics/skills', path: 'skills/xlsx' },
32
+ {
33
+ name: 'frontend-design',
34
+ repo: 'anthropics/skills',
35
+ path: 'skills/frontend-design',
36
+ },
37
+ {
38
+ name: 'webapp-testing',
39
+ repo: 'anthropics/skills',
40
+ path: 'skills/webapp-testing',
41
+ },
42
+ ];
43
+ const ALL_SKILLS = [...CORE_SKILLS, ...OPTIONAL_SKILLS];
8
44
  function run(command, options) {
9
45
  execSync(command, { stdio: 'inherit', ...options });
10
46
  }
11
- function installSkill(name, repo, skillPath, targetDir, tempDir) {
12
- if (fs.existsSync(targetDir)) {
13
- console.log(` ✅ ${name} 已存在,跳过`);
14
- return;
47
+ function installSkills(skills, targetBaseDir) {
48
+ const installed = [];
49
+ const skipped = [];
50
+ const failed = [];
51
+ // 按 repo 分组,避免重复下载
52
+ const byRepo = new Map();
53
+ for (const skill of skills) {
54
+ const list = byRepo.get(skill.repo) ?? [];
55
+ list.push(skill);
56
+ byRepo.set(skill.repo, list);
15
57
  }
16
- console.log(` 📥 正在下载 ${name}...`);
17
- const tarPath = path.join(tempDir, `${name}.tar.gz`);
18
- const extractDir = path.join(tempDir, `${name}-extract`);
19
- fs.mkdirSync(extractDir, { recursive: true });
20
- try {
21
- run(`curl -fsSL -o "${tarPath}" "https://github.com/${repo}/archive/refs/heads/main.tar.gz"`, { timeout: 30000 });
22
- run(`tar -xzf "${tarPath}" -C "${extractDir}"`, { timeout: 30000 });
23
- const subDir = fs.readdirSync(extractDir)[0];
24
- fs.cpSync(path.join(extractDir, subDir, skillPath), targetDir, {
25
- recursive: true,
26
- });
27
- console.log(` ${name} 安装完成`);
28
- }
29
- catch (error) {
30
- if (error.killed || error.code === 'ETIMEDOUT') {
31
- console.log(` ⏱️ ${name} 安装超时(网络较慢),已跳过,继续下一步`);
32
- return;
58
+ for (const [repo, repoSkills] of byRepo) {
59
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'zhitalk-'));
60
+ const markFailed = () => {
61
+ const repoFailed = repoSkills.filter((s) => !fs.existsSync(path.join(targetBaseDir, s.name)));
62
+ if (repoFailed.length === 0)
63
+ return;
64
+ for (const skill of repoFailed) {
65
+ console.log(` ❌ ${skill.name} 安装失败,已跳过`);
66
+ failed.push(skill.name);
67
+ }
68
+ console.log(` ⚠️ ${repo} 下载失败,你可以手动安装:`);
69
+ console.log(` 1. 下载 https://github.com/${repo}/archive/refs/heads/main.tar.gz`);
70
+ console.log(` 2. 解压后找到以下目录并拷贝:`);
71
+ for (const skill of repoFailed) {
72
+ console.log(` ${skill.path} ${path.join(targetBaseDir, skill.name)}`);
73
+ }
74
+ };
75
+ console.log(` 📥 正在下载 ${repo}...`);
76
+ try {
77
+ const tarPath = path.join(tempDir, 'repo.tar.gz');
78
+ run(`curl --connect-timeout 10 --max-time 30 -fsSL -o "${tarPath}" "https://github.com/${repo}/archive/refs/heads/main.tar.gz"`, { timeout: 45000 });
79
+ run(`tar -xzf "${tarPath}" -C "${tempDir}"`, { timeout: 30000 });
80
+ const subDir = fs.readdirSync(tempDir).find((d) => d !== 'repo.tar.gz');
81
+ if (!subDir) {
82
+ markFailed();
83
+ continue;
84
+ }
85
+ const extractDir = path.join(tempDir, subDir);
86
+ for (const skill of repoSkills) {
87
+ const targetDir = path.join(targetBaseDir, skill.name);
88
+ if (fs.existsSync(targetDir)) {
89
+ console.log(` ✅ ${skill.name} 已存在,跳过`);
90
+ skipped.push(skill.name);
91
+ continue;
92
+ }
93
+ console.log(` 📥 正在安装 ${skill.name}...`);
94
+ fs.cpSync(path.join(extractDir, skill.path), targetDir, {
95
+ recursive: true,
96
+ });
97
+ console.log(` ✅ ${skill.name} 安装完成`);
98
+ installed.push(skill.name);
99
+ }
100
+ }
101
+ catch {
102
+ markFailed();
103
+ }
104
+ finally {
105
+ try {
106
+ fs.rmSync(tempDir, { recursive: true, force: true });
107
+ }
108
+ catch {
109
+ // 忽略清理失败
110
+ }
33
111
  }
34
- throw error;
35
112
  }
113
+ return { installed, skipped, failed };
36
114
  }
37
115
  export async function runInstall() {
38
116
  console.log('🚀 欢迎使用 Zhitalk!首次使用需要进行初始化配置。\n');
@@ -41,17 +119,13 @@ export async function runInstall() {
41
119
  initDb();
42
120
  console.log('✅ 数据库初始化完成\n');
43
121
  // 2. 安装 skills
44
- console.log('🔧 正在安装默认 skills...');
122
+ console.log('🔧 正在安装内置 skills...');
45
123
  fs.mkdirSync(SKILLS_DIR, { recursive: true });
46
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'zhitalk-'));
47
- try {
48
- installSkill('find-skills', 'vercel-labs/skills', 'skills/find-skills', path.join(SKILLS_DIR, 'find-skills'), tempDir);
49
- installSkill('skill-creator', 'anthropics/skills', 'skills/skill-creator', path.join(SKILLS_DIR, 'skill-creator'), tempDir);
50
- }
51
- finally {
52
- fs.rmSync(tempDir, { recursive: true, force: true });
124
+ const { installed, skipped, failed } = installSkills(ALL_SKILLS, SKILLS_DIR);
125
+ if (failed.length > 0) {
126
+ console.log(`\n⚠️ 以下 ${failed.length} skill 安装失败:${failed.join(', ')}`);
53
127
  }
54
- console.log('✅ Skills 安装完成\n');
128
+ console.log(`\n✅ Skills 安装完成(${installed.length} 个新安装,${skipped.length} 个已存在跳过)\n`);
55
129
  // 3. 创建配置文件
56
130
  console.log('⚙️ 正在创建配置文件...');
57
131
  const configTemplate = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zhitalk",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "A personal AI Agent like OpenClaw, including tools, skills, memory, hook, sub-agent, MCP server, etc. Run in the terminal.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",