zhitalk 0.0.10 → 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.
- package/README.md +5 -3
- package/dist/agent/cli.js +6 -7
- package/dist/install.js +105 -31
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -6,19 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
本地安装 Nodejs 版本>=22 ,执行如下命令安装 Zhitalk
|
|
10
|
+
|
|
11
|
+
【注意】Windows 操作系统,使用管理员身份打开 cmd ,再执行命令
|
|
10
12
|
|
|
11
13
|
```
|
|
12
14
|
npm install zhitalk -g
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
能查看到 Zhitalk 的版本号,说明安装成功
|
|
16
18
|
|
|
17
19
|
```
|
|
18
20
|
zhitalk --version
|
|
19
21
|
```
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
运行 zhitalk 命令,初始化
|
|
22
24
|
|
|
23
25
|
```
|
|
24
26
|
zhitalk
|
package/dist/agent/cli.js
CHANGED
|
@@ -98,13 +98,13 @@ async function chat(userInput) {
|
|
|
98
98
|
readline.emitKeypressEvents(process.stdin);
|
|
99
99
|
process.stdin.on('keypress', escListener);
|
|
100
100
|
let usageMetadata;
|
|
101
|
-
let
|
|
101
|
+
let needsPrefix = true;
|
|
102
102
|
const spinner = createSpinner('AI 思考中');
|
|
103
103
|
try {
|
|
104
104
|
spinner.start();
|
|
105
105
|
const result = await runAgentStream(userInput, (token) => {
|
|
106
|
-
if (
|
|
107
|
-
|
|
106
|
+
if (needsPrefix) {
|
|
107
|
+
needsPrefix = false;
|
|
108
108
|
spinner.stop();
|
|
109
109
|
process.stdout.write('\n' + color.aiPrefix());
|
|
110
110
|
}
|
|
@@ -119,7 +119,8 @@ async function chat(userInput) {
|
|
|
119
119
|
});
|
|
120
120
|
const confirmed = answer.trim().toLowerCase() === 'y' ||
|
|
121
121
|
answer.trim().toLowerCase() === 'yes';
|
|
122
|
-
if (confirmed
|
|
122
|
+
if (confirmed) {
|
|
123
|
+
needsPrefix = true;
|
|
123
124
|
spinner.start();
|
|
124
125
|
}
|
|
125
126
|
return confirmed;
|
|
@@ -132,9 +133,7 @@ async function chat(userInput) {
|
|
|
132
133
|
}
|
|
133
134
|
}
|
|
134
135
|
finally {
|
|
135
|
-
|
|
136
|
-
spinner.stop();
|
|
137
|
-
}
|
|
136
|
+
spinner.stop();
|
|
138
137
|
process.stdin.removeListener('keypress', escListener);
|
|
139
138
|
rl.close();
|
|
140
139
|
}
|
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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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('🔧
|
|
122
|
+
console.log('🔧 正在安装内置 skills...');
|
|
45
123
|
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
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(
|
|
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.
|
|
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",
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"keywords": [],
|
|
22
22
|
"author": "双越",
|
|
23
23
|
"license": "ISC",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22"
|
|
26
|
+
},
|
|
24
27
|
"docs": "https://zhitalk.chat/",
|
|
25
28
|
"devDependencies": {
|
|
26
29
|
"@jest/globals": "^29.7.0",
|