@zshuangmu/agenthub 0.1.7 → 0.2.0
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 +96 -80
- package/package.json +1 -1
- package/src/cli.js +40 -38
- package/src/lib/colors.js +60 -0
package/README.md
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
# 🤖 AgentHub
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**OpenClaw Agent 的打包、发布与分发平台**
|
|
6
6
|
|
|
7
|
+
[](https://www.npmjs.com/package/@zshuangmu/agenthub)
|
|
7
8
|
[](https://opensource.org/licenses/MIT)
|
|
8
9
|
[](https://nodejs.org/)
|
|
9
|
-
[](https://github.com/itshaungmu/AgentHub)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
**把你调教好的 OpenClaw Agent 变成可复用、可分发、可升级的标准资产**
|
|
12
13
|
|
|
13
|
-
🌐
|
|
14
|
+
🌐 **在线演示**: [https://agenthub.cyou](https://agenthub.cyou/)
|
|
14
15
|
|
|
15
16
|
[English](README.md) | [中文](README_CN.md)
|
|
16
17
|
|
|
@@ -18,108 +19,123 @@
|
|
|
18
19
|
|
|
19
20
|
---
|
|
20
21
|
|
|
21
|
-
## 🎯
|
|
22
|
+
## 🎯 AgentHub 是什么?
|
|
22
23
|
|
|
23
|
-
AgentHub
|
|
24
|
+
AgentHub 是一个专为 **OpenClaw** 设计的 Agent 打包与分发平台,类似于:
|
|
25
|
+
- **Docker Hub** 之于 Docker 容器
|
|
26
|
+
- **npm** 之于 Node.js 包
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
- **🚀 Publish** to a local or remote registry with one command
|
|
27
|
-
- **🔍 Discover** and search agents from the marketplace
|
|
28
|
-
- **⚡ Install** agents to any workspace instantly
|
|
28
|
+
但专注于 **OpenClaw Agent 的分发与复刻**。
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
### 核心能力
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
| 能力 | 描述 |
|
|
33
|
+
|------|------|
|
|
34
|
+
| 📦 **一键打包** | 将 Agent 的 personality、memory、skills 打包成标准 Bundle |
|
|
35
|
+
| 🚀 **发布分发** | 发布到本地或远程 Registry,生成可分享链接 |
|
|
36
|
+
| ⚡ **一键安装** | 团队成员通过统一命令安装,复刻完整 Agent 能力 |
|
|
37
|
+
| 🔄 **版本管理** | 完整的升级、回滚、校验支持 |
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
### 适合谁?
|
|
40
|
+
|
|
41
|
+
- **✅ OpenClaw 团队用户**: 统一分发、版本管理、团队复用
|
|
42
|
+
- **✅ Agent 创作者**: 打包分享你调教好的 Agent
|
|
43
|
+
- **✅ AI 重度用户**: 快速获得别人调教好的 Agent 能力
|
|
44
|
+
|
|
45
|
+
### 不适合谁?
|
|
46
|
+
|
|
47
|
+
- ❌ 非 OpenClaw 用户(当前仅支持 OpenClaw)
|
|
48
|
+
- ❌ 需要 Prompt 收藏夹(请使用专门的 Prompt 工具)
|
|
49
|
+
- ❌ 单个 Skill 分发(请使用 ClawHub)
|
|
42
50
|
|
|
43
51
|
## 📸 Screenshots
|
|
44
52
|
|
|
45
|
-

|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
## 🚀 3 步上手
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
# Clone the repository
|
|
52
|
-
git clone https://github.com/agenthub/agenthub.git
|
|
53
|
-
cd agenthub
|
|
57
|
+
### 第一步:安装
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
npm
|
|
59
|
+
```bash
|
|
60
|
+
# 通过 npm 全局安装
|
|
61
|
+
npm install -g @zshuangmu/agenthub
|
|
57
62
|
|
|
58
|
-
#
|
|
59
|
-
|
|
63
|
+
# 或克隆源码
|
|
64
|
+
git clone https://github.com/itshaungmu/AgentHub.git
|
|
65
|
+
cd AgentHub && npm install && npm link
|
|
60
66
|
```
|
|
61
67
|
|
|
62
|
-
###
|
|
68
|
+
### 第二步:打包并发布你的 Agent
|
|
63
69
|
|
|
64
70
|
```bash
|
|
65
|
-
# 1.
|
|
66
|
-
agenthub pack --workspace ./my-
|
|
71
|
+
# 1. 打包你的 OpenClaw workspace
|
|
72
|
+
agenthub pack --workspace ./my-workspace --config openclaw.json
|
|
67
73
|
|
|
68
|
-
# 2.
|
|
74
|
+
# 2. 发布到 Registry
|
|
69
75
|
agenthub publish ./bundles/my-agent.agent --registry ./.registry
|
|
76
|
+
```
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
### 第三步:团队成员安装使用
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# 团队成员一键安装
|
|
82
|
+
agenthub install my-agent --registry ./.registry --target-workspace ./workspace
|
|
83
|
+
|
|
84
|
+
# 或启动 Web 界面浏览
|
|
72
85
|
agenthub serve --registry ./.registry --port 3000
|
|
73
86
|
```
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
|
84
|
-
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
88
|
+
访问 http://localhost:3000 查看你的 Agent!
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 📖 命令文档
|
|
93
|
+
|
|
94
|
+
### CLI 命令
|
|
95
|
+
|
|
96
|
+
| 命令 | 描述 |
|
|
97
|
+
|------|------|
|
|
98
|
+
| `pack` | 打包 workspace 为 Agent Bundle |
|
|
99
|
+
| `publish` | 发布到本地 Registry |
|
|
100
|
+
| `publish-remote` | 发布到远程服务器 |
|
|
101
|
+
| `search` | 搜索 Registry 中的 Agent |
|
|
102
|
+
| `info` | 查看 Agent 详情 |
|
|
103
|
+
| `install` | 安装 Agent 到 workspace |
|
|
104
|
+
| `list` | 列出已安装的 Agent |
|
|
105
|
+
| `verify` | 校验已安装 Agent 是否完整 |
|
|
106
|
+
| `versions` | 查看 Agent 版本历史 |
|
|
107
|
+
| `update` | 更新 Agent 到最新版 |
|
|
108
|
+
| `rollback` | 回滚 Agent 到指定版本 |
|
|
109
|
+
| `stats` | 查看 Agent 统计信息 |
|
|
110
|
+
| `serve` | 启动 Web + API 服务 |
|
|
111
|
+
| `api` | 仅启动 API 服务 |
|
|
112
|
+
| `web` | 仅启动 Web 前端 |
|
|
97
113
|
|
|
98
114
|
### HTTP API
|
|
99
115
|
|
|
100
116
|
```bash
|
|
101
|
-
#
|
|
117
|
+
# 列出所有 Agent
|
|
102
118
|
curl http://localhost:3001/api/agents
|
|
103
119
|
|
|
104
|
-
#
|
|
120
|
+
# 搜索 Agent
|
|
105
121
|
curl "http://localhost:3001/api/agents?q=react"
|
|
106
122
|
|
|
107
|
-
#
|
|
123
|
+
# 获取 Agent 详情
|
|
108
124
|
curl http://localhost:3001/api/agents/my-agent
|
|
109
125
|
|
|
110
|
-
#
|
|
126
|
+
# 获取统计信息
|
|
111
127
|
curl http://localhost:3001/api/stats
|
|
112
128
|
```
|
|
113
129
|
|
|
114
|
-
### AI
|
|
130
|
+
### AI 自动发现
|
|
115
131
|
|
|
116
|
-
|
|
132
|
+
让你的 AI 助手自动发现可用的 Agent:
|
|
117
133
|
|
|
118
134
|
```bash
|
|
119
135
|
curl http://localhost:3001/api/skills/agenthub-discover
|
|
120
136
|
```
|
|
121
137
|
|
|
122
|
-
## 🏗️
|
|
138
|
+
## 🏗️ 架构
|
|
123
139
|
|
|
124
140
|
```
|
|
125
141
|
┌─────────────────┐ pack ┌─────────────────┐ publish ┌─────────────────┐
|
|
@@ -136,45 +152,45 @@ curl http://localhost:3001/api/skills/agenthub-discover
|
|
|
136
152
|
└─────────────────┘
|
|
137
153
|
```
|
|
138
154
|
|
|
139
|
-
## 🧪
|
|
155
|
+
## 🧪 开发
|
|
140
156
|
|
|
141
157
|
```bash
|
|
142
|
-
#
|
|
158
|
+
# 运行测试
|
|
143
159
|
npm test
|
|
144
160
|
|
|
145
|
-
#
|
|
161
|
+
# 启动开发服务器
|
|
146
162
|
node src/cli.js serve --registry ./.registry
|
|
147
163
|
```
|
|
148
164
|
|
|
149
|
-
## 🐳 Docker
|
|
165
|
+
## 🐳 Docker 部署
|
|
150
166
|
|
|
151
167
|
```bash
|
|
152
|
-
#
|
|
168
|
+
# 生产环境启动(容器内)
|
|
153
169
|
NODE_ENV=production node src/cli.js serve --registry ./.registry --port 3000 --host 0.0.0.0
|
|
154
170
|
```
|
|
155
171
|
|
|
156
|
-
## 🤝
|
|
172
|
+
## 🤝 贡献
|
|
157
173
|
|
|
158
|
-
|
|
174
|
+
欢迎贡献!请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解详情。
|
|
159
175
|
|
|
160
|
-
- 🐛 [
|
|
161
|
-
- 💡 [
|
|
162
|
-
- 🔧 [
|
|
176
|
+
- 🐛 [报告 Bug](https://github.com/itshaungmu/AgentHub/issues/new?template=bug_report.md)
|
|
177
|
+
- 💡 [请求功能](https://github.com/itshaungmu/AgentHub/issues/new?template=feature_request.md)
|
|
178
|
+
- 🔧 [提交 PR](https://github.com/itshaungmu/AgentHub/pulls)
|
|
163
179
|
|
|
164
|
-
## 📄
|
|
180
|
+
## 📄 许可证
|
|
165
181
|
|
|
166
182
|
[MIT License](LICENSE) © AgentHub Team
|
|
167
183
|
|
|
168
|
-
## 🙏
|
|
184
|
+
## 🙏 致谢
|
|
169
185
|
|
|
170
|
-
-
|
|
171
|
-
-
|
|
186
|
+
- 为 [OpenClaw](https://github.com/openclaw) 生态系统构建
|
|
187
|
+
- 灵感来自 npm 和 Docker Hub
|
|
172
188
|
|
|
173
189
|
---
|
|
174
190
|
|
|
175
191
|
<div align="center">
|
|
176
192
|
|
|
177
|
-
**[⬆
|
|
193
|
+
**[⬆ 返回顶部](#agenthub)**
|
|
178
194
|
|
|
179
195
|
Made with ❤️ by the AgentHub Team
|
|
180
196
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
formatVersionsOutput,
|
|
29
29
|
} from "./index.js";
|
|
30
30
|
|
|
31
|
+
import { success, error, warning, info as infoColor, highlight, muted, symbols } from "./lib/colors.js";
|
|
32
|
+
|
|
31
33
|
import { createRequire } from "node:module";
|
|
32
34
|
const require = createRequire(import.meta.url);
|
|
33
35
|
const VERSION = require("../package.json").version;
|
|
@@ -40,7 +42,7 @@ const VERSION = require("../package.json").version;
|
|
|
40
42
|
*/
|
|
41
43
|
function requireArg(arg, message) {
|
|
42
44
|
if (!arg) {
|
|
43
|
-
console.error(message);
|
|
45
|
+
console.error(error(message));
|
|
44
46
|
process.exitCode = 1;
|
|
45
47
|
return false;
|
|
46
48
|
}
|
|
@@ -313,38 +315,38 @@ async function main() {
|
|
|
313
315
|
switch (command) {
|
|
314
316
|
case "pack": {
|
|
315
317
|
if (!options.workspace || !options.config) {
|
|
316
|
-
console.error("错误: --workspace 和 --config 是必需的");
|
|
317
|
-
console.log("\n运行 'agenthub pack --help' 查看帮助");
|
|
318
|
+
console.error(error("错误: --workspace 和 --config 是必需的"));
|
|
319
|
+
console.log(muted("\n运行 'agenthub pack --help' 查看帮助"));
|
|
318
320
|
process.exitCode = 1;
|
|
319
321
|
return;
|
|
320
322
|
}
|
|
321
323
|
const result = await packCommand(options);
|
|
322
|
-
console.log(
|
|
324
|
+
console.log(success(`${symbols.success} 打包完成: ${result.bundleDir}`));
|
|
323
325
|
return;
|
|
324
326
|
}
|
|
325
327
|
|
|
326
328
|
case "publish": {
|
|
327
329
|
if (!requireArg(rest[0], "错误: 需要指定 bundle 目录")) return;
|
|
328
330
|
const result = await publishCommand(rest[0], options);
|
|
329
|
-
console.log(
|
|
331
|
+
console.log(success(`${symbols.success} 已发布 ${highlight(`${result.slug}@${result.version}`)}`));
|
|
330
332
|
return;
|
|
331
333
|
}
|
|
332
334
|
|
|
333
335
|
case "publish-remote": {
|
|
334
336
|
if (!requireArg(rest[0], "错误: 需要指定 bundle 目录")) return;
|
|
335
337
|
const result = await publishRemoteCommand(rest[0], options);
|
|
336
|
-
console.log(
|
|
338
|
+
console.log(success(`${symbols.success} 已发布到远程 ${highlight(`${result.slug}@${result.version}`)}`));
|
|
337
339
|
return;
|
|
338
340
|
}
|
|
339
341
|
|
|
340
342
|
case "search": {
|
|
341
343
|
const results = await searchCommand(rest[0] || "", options);
|
|
342
344
|
if (results.length === 0) {
|
|
343
|
-
console.log("未找到匹配的 Agent");
|
|
345
|
+
console.log(warning("未找到匹配的 Agent"));
|
|
344
346
|
} else {
|
|
345
|
-
console.log(`\n
|
|
347
|
+
console.log(`\n${infoColor(`找到 ${results.length} 个 Agent:`)}\n`);
|
|
346
348
|
for (const entry of results) {
|
|
347
|
-
console.log(` ${entry.slug}
|
|
349
|
+
console.log(` ${highlight(entry.slug)}${muted("@")}${entry.version} ${muted("-")} ${entry.description || ""}`);
|
|
348
350
|
}
|
|
349
351
|
}
|
|
350
352
|
return;
|
|
@@ -353,23 +355,23 @@ async function main() {
|
|
|
353
355
|
case "info": {
|
|
354
356
|
if (!requireArg(rest[0], "错误: 需要指定 agent slug")) return;
|
|
355
357
|
const result = await infoCommand(rest[0], options);
|
|
356
|
-
console.log(`\n📦 ${result.name} (${result.slug}@${result.version})`);
|
|
358
|
+
console.log(`\n${highlight("📦")} ${result.name} (${result.slug}@${result.version})`);
|
|
357
359
|
console.log(` ${result.description}`);
|
|
358
|
-
console.log(` Runtime: ${result.runtime?.type || "openclaw"} ${result.runtime?.version || ""}`);
|
|
360
|
+
console.log(` ${muted("Runtime:")} ${result.runtime?.type || "openclaw"} ${result.runtime?.version || ""}`);
|
|
359
361
|
const mem = result.includes?.memory || {};
|
|
360
362
|
if (mem.count > 0) {
|
|
361
|
-
console.log(` Memory: ${mem.count} 条 (public: ${mem.public}, portable: ${mem.portable})`);
|
|
363
|
+
console.log(` ${muted("Memory:")} ${mem.count} 条 (public: ${mem.public}, portable: ${mem.portable})`);
|
|
362
364
|
}
|
|
363
|
-
console.log(`\n 安装命令: agenthub install ${result.slug}`);
|
|
365
|
+
console.log(`\n ${infoColor("安装命令:")} agenthub install ${result.slug}`);
|
|
364
366
|
return;
|
|
365
367
|
}
|
|
366
368
|
|
|
367
369
|
case "install": {
|
|
368
370
|
if (!requireArg(rest[0], "错误: 需要指定 agent slug")) return;
|
|
369
|
-
console.log(`\n📥 正在安装 ${rest[0]}...\n`);
|
|
371
|
+
console.log(`\n${infoColor("📥 正在安装")} ${highlight(rest[0])}...\n`);
|
|
370
372
|
const installResult = await installCommand(rest[0], options);
|
|
371
|
-
console.log(
|
|
372
|
-
console.log(` 位置: ${options.targetWorkspace || "当前目录"}`);
|
|
373
|
+
console.log(success(`${symbols.success} 已安装 ${highlight(`${installResult.manifest.slug}@${installResult.manifest.version}`)}`));
|
|
374
|
+
console.log(` ${muted("位置:")} ${options.targetWorkspace || "当前目录"}`);
|
|
373
375
|
return;
|
|
374
376
|
}
|
|
375
377
|
|
|
@@ -418,11 +420,11 @@ async function main() {
|
|
|
418
420
|
|
|
419
421
|
case "serve": {
|
|
420
422
|
const result = await serveCommand(options);
|
|
421
|
-
console.log(`Server listening at ${result.baseUrl}`);
|
|
422
|
-
console.log(`\n🌐 AgentHub
|
|
423
|
-
console.log(` 地址: ${result.baseUrl}`);
|
|
424
|
-
console.log(` API: ${result.baseUrl}/api/agents`);
|
|
425
|
-
console.log(`\n按 Ctrl+C
|
|
423
|
+
console.log(success(`Server listening at ${result.baseUrl}`));
|
|
424
|
+
console.log(`\n${highlight("🌐 AgentHub 服务已启动")}`);
|
|
425
|
+
console.log(` ${muted("地址:")} ${result.baseUrl}`);
|
|
426
|
+
console.log(` ${muted("API:")} ${result.baseUrl}/api/agents`);
|
|
427
|
+
console.log(`\n${muted("按 Ctrl+C 停止服务")}\n`);
|
|
426
428
|
|
|
427
429
|
const shutdown = async () => {
|
|
428
430
|
process.off("SIGINT", shutdown);
|
|
@@ -438,12 +440,12 @@ async function main() {
|
|
|
438
440
|
case "api": {
|
|
439
441
|
const port = options.port || "3001";
|
|
440
442
|
const result = await apiCommand({ ...options, port });
|
|
441
|
-
console.log(`Server listening at ${result.baseUrl}`);
|
|
442
|
-
console.log(`\n🔧 API
|
|
443
|
-
console.log(` 地址: ${result.baseUrl}`);
|
|
444
|
-
console.log(` 端点: ${result.baseUrl}/api/agents`);
|
|
445
|
-
console.log(` 统计: ${result.baseUrl}/api/stats`);
|
|
446
|
-
console.log(`\n按 Ctrl+C
|
|
443
|
+
console.log(success(`Server listening at ${result.baseUrl}`));
|
|
444
|
+
console.log(`\n${highlight("🔧 API 服务已启动")}`);
|
|
445
|
+
console.log(` ${muted("地址:")} ${result.baseUrl}`);
|
|
446
|
+
console.log(` ${muted("端点:")} ${result.baseUrl}/api/agents`);
|
|
447
|
+
console.log(` ${muted("统计:")} ${result.baseUrl}/api/stats`);
|
|
448
|
+
console.log(`\n${muted("按 Ctrl+C 停止服务")}\n`);
|
|
447
449
|
|
|
448
450
|
const shutdown = async () => {
|
|
449
451
|
process.off("SIGINT", shutdown);
|
|
@@ -460,11 +462,11 @@ async function main() {
|
|
|
460
462
|
const port = options.port || "3000";
|
|
461
463
|
const apiBase = options.apiBase || "http://127.0.0.1:3001";
|
|
462
464
|
const result = await webCommand({ port, apiBase });
|
|
463
|
-
console.log(`Server listening at ${result.baseUrl}`);
|
|
464
|
-
console.log(`\n🌐 Web
|
|
465
|
-
console.log(` 地址: ${result.baseUrl}`);
|
|
466
|
-
console.log(` API: ${apiBase}`);
|
|
467
|
-
console.log(`\n按 Ctrl+C
|
|
465
|
+
console.log(success(`Server listening at ${result.baseUrl}`));
|
|
466
|
+
console.log(`\n${highlight("🌐 Web 服务已启动")}`);
|
|
467
|
+
console.log(` ${muted("地址:")} ${result.baseUrl}`);
|
|
468
|
+
console.log(` ${muted("API:")} ${apiBase}`);
|
|
469
|
+
console.log(`\n${muted("按 Ctrl+C 停止服务")}\n`);
|
|
468
470
|
|
|
469
471
|
const shutdown = async () => {
|
|
470
472
|
process.off("SIGINT", shutdown);
|
|
@@ -478,15 +480,15 @@ async function main() {
|
|
|
478
480
|
}
|
|
479
481
|
|
|
480
482
|
default:
|
|
481
|
-
console.error(`未知命令: ${command}`);
|
|
482
|
-
console.log("\n运行 'agenthub --help' 查看可用命令");
|
|
483
|
+
console.error(error(`未知命令: ${command}`));
|
|
484
|
+
console.log(muted("\n运行 'agenthub --help' 查看可用命令"));
|
|
483
485
|
process.exitCode = 1;
|
|
484
486
|
}
|
|
485
|
-
} catch (
|
|
487
|
+
} catch (err) {
|
|
486
488
|
// 提取更详细的错误信息
|
|
487
|
-
const causeMsg =
|
|
488
|
-
const detailMsg = causeMsg ? `${
|
|
489
|
-
console.error(`\n
|
|
489
|
+
const causeMsg = err.cause?.errors?.[0]?.message || err.cause?.message || "";
|
|
490
|
+
const detailMsg = causeMsg ? `${err.message}\n 原因: ${causeMsg}` : err.message;
|
|
491
|
+
console.error(`\n${error(`${symbols.error} 错误:`)} ${detailMsg}`);
|
|
490
492
|
process.exitCode = 1;
|
|
491
493
|
}
|
|
492
494
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Colors Utility
|
|
3
|
+
* 简单的终端颜色支持(无需额外依赖)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 检测是否支持颜色
|
|
7
|
+
const supportsColor = process.stdout.isTTY && process.env.NO_COLOR === undefined;
|
|
8
|
+
|
|
9
|
+
// ANSI 颜色代码
|
|
10
|
+
const codes = {
|
|
11
|
+
reset: "\x1b[0m",
|
|
12
|
+
bold: "\x1b[1m",
|
|
13
|
+
dim: "\x1b[2m",
|
|
14
|
+
red: "\x1b[31m",
|
|
15
|
+
green: "\x1b[32m",
|
|
16
|
+
yellow: "\x1b[33m",
|
|
17
|
+
blue: "\x1b[34m",
|
|
18
|
+
magenta: "\x1b[35m",
|
|
19
|
+
cyan: "\x1b[36m",
|
|
20
|
+
white: "\x1b[37m",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 创建颜色函数
|
|
25
|
+
*/
|
|
26
|
+
function colorize(code) {
|
|
27
|
+
return (text) => supportsColor ? `${code}${text}${codes.reset}` : text;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 导出颜色函数
|
|
31
|
+
export const colors = {
|
|
32
|
+
reset: (text) => text,
|
|
33
|
+
bold: colorize(codes.bold),
|
|
34
|
+
dim: colorize(codes.dim),
|
|
35
|
+
red: colorize(codes.red),
|
|
36
|
+
green: colorize(codes.green),
|
|
37
|
+
yellow: colorize(codes.yellow),
|
|
38
|
+
blue: colorize(codes.blue),
|
|
39
|
+
magenta: colorize(codes.magenta),
|
|
40
|
+
cyan: colorize(codes.cyan),
|
|
41
|
+
white: colorize(codes.white),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// 语义化颜色
|
|
45
|
+
export const success = (text) => colors.green(text);
|
|
46
|
+
export const error = (text) => colors.red(text);
|
|
47
|
+
export const warning = (text) => colors.yellow(text);
|
|
48
|
+
export const info = (text) => colors.cyan(text);
|
|
49
|
+
export const highlight = (text) => colors.bold(colors.cyan(text));
|
|
50
|
+
export const muted = (text) => colors.dim(text);
|
|
51
|
+
|
|
52
|
+
// 常用符号
|
|
53
|
+
export const symbols = {
|
|
54
|
+
success: supportsColor ? "✓" : "[OK]",
|
|
55
|
+
error: supportsColor ? "✗" : "[ERR]",
|
|
56
|
+
warning: supportsColor ? "⚠" : "[!]",
|
|
57
|
+
info: supportsColor ? "ℹ" : "[i]",
|
|
58
|
+
arrow: supportsColor ? "→" : "->",
|
|
59
|
+
bullet: supportsColor ? "•" : "*",
|
|
60
|
+
};
|