Skip to content

Commit ece65cf

Browse files
committed
feat: 重构项目为monorepo结构并实现核心功能
- 将项目重构为monorepo结构,包含core/cli/types三个子包 - 实现核心Agent类,支持基础聊天和多轮对话功能 - 添加LLM管理器,支持平铺配置(apiKey/baseUrl/modelName) - 实现配置管理系统,支持多级配置加载 - 添加工具系统,包含文件系统/Git/智能工具等内置工具 - 完善类型定义,提供共享类型包 - 添加测试脚本验证核心功能 - 更新README文档说明新架构
1 parent e5ed0ca commit ece65cf

117 files changed

Lines changed: 20891 additions & 10 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"Bash(BLADE_API_KEY=\"sk-test-key\" node ./bin/blade.js chat \"你好\")",
2323
"Bash(BLADE_MODEL=\"test-model\" node ./bin/blade.js chat \"请告诉我你是谁\")",
2424
"Bash(npm uninstall:*)",
25-
"Bash(npm info:*)"
25+
"Bash(npm info:*)",
26+
"Bash(mkdir:*)"
2627
],
2728
"deny": [],
2829
"ask": [],

README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ blade chat -i --stream
243243
### Agent 使用
244244

245245
```typescript
246-
import { Agent } from 'blade-ai';
246+
import { Agent } from '@blade-ai/core';
247247

248248
const agent = new Agent({
249249
llm: { provider: 'qwen', apiKey: 'your-key' },
@@ -264,7 +264,7 @@ await agent.destroy();
264264
### 工具管理
265265

266266
```typescript
267-
import { createToolManager } from 'blade-ai';
267+
import { createToolManager } from '@blade-ai/core';
268268

269269
const toolManager = await createToolManager();
270270
const result = await toolManager.callTool({
@@ -278,12 +278,11 @@ const result = await toolManager.callTool({
278278
### 项目结构
279279

280280
```
281-
src/
282-
├── agent/ # Agent 核心
283-
├── llm/ # LLM 实现
284-
├── tools/ # 工具系统
285-
├── commands/ # CLI 命令
286-
└── config/ # 配置管理
281+
packages/
282+
├── core/ # 核心AI功能 (@blade-ai/core)
283+
├── cli/ # 命令行界面 (@blade-ai/cli)
284+
├── types/ # 共享类型定义 (@blade-ai/types)
285+
└── blade/ # 旧版代码(将被移除)
287286
```
288287

289288
### 开发命令
@@ -292,16 +291,20 @@ src/
292291
# 开发模式
293292
npm run dev
294293

295-
# 构建
294+
# 构建所有包
296295
npm run build
297296

297+
# 构建特定包
298+
cd packages/core && npm run build
299+
298300
# 类型检查
299301
npm run type-check
300302

301303
# 代码格式化
302304
npm run format
303305
```
304306

307+
305308
## 🤝 贡献
306309

307310
欢迎提交 Issue 和 Pull Request!

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{
22
"name": "blade-ai",
33
"version": "1.2.8",
4+
"private": true,
5+
"workspaces": [
6+
"packages/*"
7+
],
48
"description": "🗡️ Blade - 智能 AI 助手命令行工具",
59
"type": "module",
610
"main": "dist/index.js",

packages/cli/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Changelog
2+
3+
## [1.2.8] - 2025-08-29
4+
5+
### 🚀 初始版本
6+
7+
- **首次发布**: `@blade-ai/cli` 包作为 Blade AI 的命令行界面首次发布
8+
- **核心功能**:
9+
- CLI命令解析和执行
10+
- 终端UI组件系统
11+
- 用户交互界面
12+
- 命令行工具集成
13+
14+
### 📦 导出内容
15+
16+
- CLI命令实现
17+
- 终端UI组件
18+
- 用户交互处理
19+
20+
---
21+
所有显著变更都将记录在此文件中。

packages/cli/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# @blade-ai/cli
2+
3+
Blade AI 命令行界面包
4+
5+
## 📦 包概述
6+
7+
`@blade-ai/cli` 是 Blade AI 的命令行界面实现,提供:
8+
- CLI命令解析
9+
- 终端UI组件
10+
- 用户交互界面
11+
- 命令行工具集成
12+
13+
## 🚀 使用
14+
15+
```bash
16+
npm install -g @blade-ai/cli
17+
blade chat "你好"
18+
```
19+
20+
## 📚 命令参考
21+
22+
### chat
23+
智能对话命令
24+
25+
```bash
26+
blade chat "问题"
27+
blade chat -i # 交互式模式
28+
blade chat --stream # 流式输出
29+
```
30+
31+
### tools
32+
工具管理命令
33+
34+
```bash
35+
blade tools list # 查看工具列表
36+
blade tools call <tool> # 调用工具
37+
```
38+
39+
## 🏗️ 开发
40+
41+
### 构建
42+
```bash
43+
npm run build
44+
```
45+
46+
### 开发模式
47+
```bash
48+
npm run dev
49+
```
50+
51+
## 📄 许可证
52+
53+
MIT

packages/cli/package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "@blade-ai/cli",
3+
"version": "1.2.8",
4+
"description": "Blade AI CLI - 智能AI助手命令行界面",
5+
"type": "module",
6+
"bin": {
7+
"blade": "../bin/blade.js"
8+
},
9+
"files": [
10+
"dist"
11+
],
12+
"scripts": {
13+
"build": "tsup",
14+
"dev": "tsup --watch",
15+
"type-check": "tsc --noEmit"
16+
},
17+
"dependencies": {
18+
"@blade-ai/core": "workspace:*",
19+
"commander": "^14.0.0",
20+
"inquirer": "^12.6.3",
21+
"chalk": "^5.4.1",
22+
"ink": "^6.2.3",
23+
"react": "^19.1.1",
24+
"react-dom": "^19.1.1"
25+
},
26+
"devDependencies": {
27+
"@types/node": "^22.15.24",
28+
"@types/react": "^19.1.12",
29+
"@types/react-dom": "^19.1.9",
30+
"typescript": "^5.9.2",
31+
"tsup": "^8.5.0"
32+
}
33+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* 平铺配置CLI命令
5+
* 直接使用三要素配置驱动命令
6+
*/
7+
8+
import { Command } from 'commander';
9+
import chalk from 'chalk';
10+
import { Agent } from '../agent/Agent.js';
11+
12+
/**
13+
* 注册Agent-LLM相关命令
14+
*/
15+
export function agentLlmCommand(program: Command) {
16+
const llmCmd = program
17+
.command('chat')
18+
.description('💬 智能对话')
19+
.argument('[message]', '对话内容')
20+
.option('-k, --api-key <key>', 'API密钥')
21+
.option('-u, --base-url <url>', 'API基础URL')
22+
.option('-m, --model <name>', '模型名称')
23+
.option('-s, --system <prompt>', '系统提示词')
24+
.option('-i, --interactive', '交互式对话')
25+
.option('--theme <name>', '界面主题 (default|dark|dracula|nord|tokyo-night|github|monokai|ayu-dark|solarized-light|solarized-dark|gruvbox|one-dark|catppuccin|rose-pine|kanagawa)')
26+
.action(async (message, options) => {
27+
await handleChat(message, options);
28+
});
29+
30+
// 别名
31+
llmCmd.alias('c');
32+
}
33+
34+
/**
35+
* 处理聊天命令
36+
*/
37+
async function handleChat(
38+
message: string | undefined,
39+
options: {
40+
apiKey?: string;
41+
baseUrl?: string;
42+
model?: string;
43+
system?: string;
44+
interactive?: boolean;
45+
theme?: string;
46+
}
47+
): Promise<void> {
48+
try {
49+
// 构建配置
50+
const configUpdates: any = {};
51+
if (options.apiKey) configUpdates.apiKey = options.apiKey;
52+
if (options.baseUrl) configUpdates.baseUrl = options.baseUrl;
53+
if (options.model) configUpdates.modelName = options.model;
54+
55+
// 创建Agent实例
56+
const agent = new Agent(configUpdates);
57+
58+
// 设置主题
59+
if (options.theme) {
60+
const { themeManager } = await import('../ui/themes/index.js');
61+
themeManager.setTheme(options.theme);
62+
}
63+
64+
// 交互式模式
65+
if (options.interactive || !message) {
66+
await interactiveChat(agent, options.system);
67+
return;
68+
}
69+
70+
// 单次对话
71+
if (options.system) {
72+
const response = await agent.chatWithSystem(options.system, message);
73+
console.log(response);
74+
} else {
75+
const response = await agent.chat(message);
76+
console.log(response);
77+
}
78+
} catch (error) {
79+
console.error(chalk.red(`❌ 调用失败: ${(error as Error).message}`));
80+
process.exit(1);
81+
}
82+
}
83+
84+
/**
85+
* 交互式聊天
86+
*/
87+
async function interactiveChat(agent: Agent, systemPrompt?: string): Promise<void> {
88+
const readline = require('readline');
89+
const rl = readline.createInterface({
90+
input: process.stdin,
91+
output: process.stdout,
92+
});
93+
94+
console.log(chalk.cyan('🚀 启动交互式对话 (输入 "exit" 或 "quit" 退出)'));
95+
if (systemPrompt) {
96+
console.log(chalk.gray(`系统提示词: ${systemPrompt}`));
97+
}
98+
console.log('');
99+
100+
const chatLoop = async () => {
101+
rl.question(chalk.green('👤 你: '), async (input: string) => {
102+
if (input.toLowerCase() === 'exit' || input.toLowerCase() === 'quit') {
103+
console.log(chalk.yellow('👋 再见!'));
104+
rl.close();
105+
return;
106+
}
107+
108+
if (input.trim()) {
109+
try {
110+
process.stdout.write(chalk.blue('🤖 AI: '));
111+
const response = systemPrompt
112+
? await agent.chatWithSystem(systemPrompt, input)
113+
: await agent.chat(input);
114+
console.log(response);
115+
} catch (error) {
116+
console.error(chalk.red(`\n❌ 调用失败: ${(error as Error).message}`));
117+
}
118+
}
119+
console.log('');
120+
chatLoop();
121+
});
122+
};
123+
124+
chatLoop();
125+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* 配置管理命令
3+
*/
4+
5+
import { Command } from 'commander';
6+
import { resetUserConfig, showCurrentConfig } from '../config/user-config.js';
7+
import { UIDisplay, UIInput } from '../ui/index.js';
8+
9+
/**
10+
* 注册配置相关命令
11+
*/
12+
export function configCommand(program: Command) {
13+
const configCmd = program.command('config').description('⚙️ 配置管理');
14+
15+
// 显示当前配置
16+
configCmd
17+
.command('show')
18+
.alias('s')
19+
.description('📋 显示当前配置')
20+
.action(() => {
21+
showCurrentConfig();
22+
});
23+
24+
// 重置配置
25+
configCmd
26+
.command('reset')
27+
.description('🔄 重置配置为默认值')
28+
.action(async () => {
29+
const confirm = await UIInput.confirm('确定要重置所有配置吗?', { default: false });
30+
31+
if (confirm) {
32+
resetUserConfig();
33+
} else {
34+
UIDisplay.muted('取消重置');
35+
}
36+
});
37+
}

0 commit comments

Comments
 (0)