@gird/ccli 2.5.0 → 2.6.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 +38 -1
- package/dist/agent/ai.js +19 -6
- package/dist/agent/ai.js.map +1 -1
- package/dist/agent/mcp.js +50 -8
- package/dist/agent/mcp.js.map +1 -1
- package/dist/cli/{args.js → args/index.js} +1 -1
- package/dist/cli/args/index.js.map +1 -0
- package/dist/cli/repl/history.js.map +1 -0
- package/dist/cli/{repl.js → repl/index.js} +25 -14
- package/dist/cli/repl/index.js.map +1 -0
- package/dist/cli/repl/input.js.map +1 -0
- package/dist/cli/{run.js → run/index.js} +16 -7
- package/dist/cli/run/index.js.map +1 -0
- package/dist/cli/{session.js → session/index.js} +22 -1
- package/dist/cli/session/index.js.map +1 -0
- package/dist/cli/slash/config/model.js +51 -0
- package/dist/cli/slash/config/model.js.map +1 -0
- package/dist/cli/slash/config/role.js +23 -0
- package/dist/cli/slash/config/role.js.map +1 -0
- package/dist/cli/slash/context.js +2 -0
- package/dist/cli/slash/context.js.map +1 -0
- package/dist/cli/slash/index.js +123 -0
- package/dist/cli/slash/index.js.map +1 -0
- package/dist/cli/slash/mcp/mcp.js +133 -0
- package/dist/cli/slash/mcp/mcp.js.map +1 -0
- package/dist/cli/slash/session/load.js +69 -0
- package/dist/cli/slash/session/load.js.map +1 -0
- package/dist/cli/slash/session/resume.js +18 -0
- package/dist/cli/slash/session/resume.js.map +1 -0
- package/dist/cli/slash/session/save.js +12 -0
- package/dist/cli/slash/session/save.js.map +1 -0
- package/dist/cli/slash/session/sessions.js +15 -0
- package/dist/cli/slash/session/sessions.js.map +1 -0
- package/dist/cli/slash/system/agent.js +189 -0
- package/dist/cli/slash/system/agent.js.map +1 -0
- package/dist/cli/slash/system/delete.js +24 -0
- package/dist/cli/slash/system/delete.js.map +1 -0
- package/dist/cli/slash/system/help.js +25 -0
- package/dist/cli/slash/system/help.js.map +1 -0
- package/dist/cli/slash/system/stats.js +6 -0
- package/dist/cli/slash/system/stats.js.map +1 -0
- package/dist/cli/slash/system/undo.js +39 -0
- package/dist/cli/slash/system/undo.js.map +1 -0
- package/dist/cli/{stats.js → stats/index.js} +1 -1
- package/dist/cli/stats/index.js.map +1 -0
- package/dist/config/config.js.map +1 -1
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/cli/args.js.map +0 -1
- package/dist/cli/history.js.map +0 -1
- package/dist/cli/input.js.map +0 -1
- package/dist/cli/repl.js.map +0 -1
- package/dist/cli/run.js.map +0 -1
- package/dist/cli/session.js.map +0 -1
- package/dist/cli/slash.js +0 -416
- package/dist/cli/slash.js.map +0 -1
- package/dist/cli/stats.js.map +0 -1
- /package/dist/cli/{history.js → repl/history.js} +0 -0
- /package/dist/cli/{input.js → repl/input.js} +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 斜杠命令入口。
|
|
3
|
+
*
|
|
4
|
+
* REPL 里凡是以 `/` 开头的输入都交给这里处理,不会发给 AI。
|
|
5
|
+
* 具体命令实现拆到同目录下的子模块中。
|
|
6
|
+
*/
|
|
7
|
+
import { listSessions } from '../session/index.js';
|
|
8
|
+
import { resetStats } from '../stats/index.js';
|
|
9
|
+
import { COMMANDS, printHelp } from './system/help.js';
|
|
10
|
+
export { COMMANDS, printHelp };
|
|
11
|
+
import { handleUndo } from './system/undo.js';
|
|
12
|
+
import { handleModel } from './config/model.js';
|
|
13
|
+
import { handleSave } from './session/save.js';
|
|
14
|
+
import { handleLoad } from './session/load.js';
|
|
15
|
+
import { handleSessions } from './session/sessions.js';
|
|
16
|
+
import { handleStats } from './system/stats.js';
|
|
17
|
+
import { handleDelete } from './system/delete.js';
|
|
18
|
+
import { handleAgent } from './system/agent.js';
|
|
19
|
+
import { handleResume } from './session/resume.js';
|
|
20
|
+
import { handleRole } from './config/role.js';
|
|
21
|
+
import { handleMcp, reloadMcpServers } from './mcp/mcp.js';
|
|
22
|
+
/**
|
|
23
|
+
* readline 的 Tab 补全函数。
|
|
24
|
+
* 对斜杠命令和 /load 的会话名提供补全提示。
|
|
25
|
+
*/
|
|
26
|
+
export function slashCompleter(line) {
|
|
27
|
+
// /load <name> 的会话名补全:子串匹配,最近修改的排在前面
|
|
28
|
+
const loadPrefix = '/load ';
|
|
29
|
+
if (line.startsWith(loadPrefix)) {
|
|
30
|
+
const keyword = line.slice(loadPrefix.length).toLowerCase();
|
|
31
|
+
const sessions = listSessions()
|
|
32
|
+
.filter((s) => s.name.toLowerCase().includes(keyword))
|
|
33
|
+
.map((s) => `${loadPrefix}${s.name}`);
|
|
34
|
+
return [sessions, line];
|
|
35
|
+
}
|
|
36
|
+
// 其他斜杠命令补全
|
|
37
|
+
if (line.startsWith('/')) {
|
|
38
|
+
const hits = COMMANDS.filter(([cmd]) => cmd.startsWith(line))
|
|
39
|
+
.flatMap(([cmd]) => cmd
|
|
40
|
+
.split(' ')[0]
|
|
41
|
+
.split(',')
|
|
42
|
+
.map((c) => c.trim()))
|
|
43
|
+
.filter((c) => c.startsWith('/'));
|
|
44
|
+
return [hits, line];
|
|
45
|
+
}
|
|
46
|
+
return [[], line];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 处理一条斜杠命令。
|
|
50
|
+
* @returns true 表示已作为命令处理(不应再发给 AI)
|
|
51
|
+
*/
|
|
52
|
+
export async function handleSlash(input, ctx) {
|
|
53
|
+
// 去掉开头的 '/',按空白拆成命令名 + 参数
|
|
54
|
+
const [name, ...rest] = input.slice(1).split(/\s+/);
|
|
55
|
+
const arg = rest.join(' ').trim();
|
|
56
|
+
switch (name) {
|
|
57
|
+
case 'help':
|
|
58
|
+
printHelp();
|
|
59
|
+
return true;
|
|
60
|
+
case 'clear':
|
|
61
|
+
// 保留第 0 条 system 提示,清掉其余历史
|
|
62
|
+
ctx.history.length = 1;
|
|
63
|
+
resetStats(ctx.stats);
|
|
64
|
+
console.log('(已清空对话历史和 token 统计)');
|
|
65
|
+
return true;
|
|
66
|
+
case 'undo':
|
|
67
|
+
handleUndo(arg, ctx);
|
|
68
|
+
return true;
|
|
69
|
+
case 'model':
|
|
70
|
+
await handleModel(arg, ctx);
|
|
71
|
+
return true;
|
|
72
|
+
case 'save':
|
|
73
|
+
handleSave(arg, ctx);
|
|
74
|
+
return true;
|
|
75
|
+
case 'load':
|
|
76
|
+
await handleLoad(arg, ctx);
|
|
77
|
+
return true;
|
|
78
|
+
case 'sessions':
|
|
79
|
+
handleSessions();
|
|
80
|
+
return true;
|
|
81
|
+
case 'delete':
|
|
82
|
+
await handleDelete(arg, ctx);
|
|
83
|
+
return true;
|
|
84
|
+
case 'agent':
|
|
85
|
+
await handleAgent(arg, ctx);
|
|
86
|
+
return true;
|
|
87
|
+
case 'stats':
|
|
88
|
+
handleStats(ctx);
|
|
89
|
+
return true;
|
|
90
|
+
case 'resume':
|
|
91
|
+
handleResume(ctx);
|
|
92
|
+
return true;
|
|
93
|
+
case 'reload':
|
|
94
|
+
await handleReload(ctx);
|
|
95
|
+
return true;
|
|
96
|
+
case 'mcp':
|
|
97
|
+
await handleMcp(arg, ctx);
|
|
98
|
+
return true;
|
|
99
|
+
case 'role':
|
|
100
|
+
handleRole(arg, ctx);
|
|
101
|
+
return true;
|
|
102
|
+
case 'exit':
|
|
103
|
+
case 'quit':
|
|
104
|
+
ctx.requestExit();
|
|
105
|
+
return true;
|
|
106
|
+
default:
|
|
107
|
+
console.log(`未知命令:/${name},输入 /help 查看可用命令。`);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** /reload:重新加载配置文件并刷新 MCP server。 */
|
|
112
|
+
async function handleReload(ctx) {
|
|
113
|
+
const result = ctx.reloadConfig();
|
|
114
|
+
if (!result.ok) {
|
|
115
|
+
console.log(`配置重载失败:${result.message}`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
console.log('配置已重新加载。');
|
|
119
|
+
if (ctx.mcpManager) {
|
|
120
|
+
await reloadMcpServers(ctx.mcpManager, result.config.mcpServers ?? {});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/slash/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { McpClientManager } from '../../../agent/mcp.js';
|
|
2
|
+
import { saveMcpServers, } from '../../../config/config.js';
|
|
3
|
+
import { registerMcpTools, unregisterAllMcpTools, unregisterMcpServerTools, } from '../../../tools/index.js';
|
|
4
|
+
/** /mcp:管理 MCP server。 */
|
|
5
|
+
export async function handleMcp(arg, ctx) {
|
|
6
|
+
if (!ctx.mcpManager) {
|
|
7
|
+
console.log('当前没有可用的 MCP manager。');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const parts = arg.trim().split(/\s+/);
|
|
11
|
+
const sub = parts[0]?.toLowerCase();
|
|
12
|
+
switch (sub) {
|
|
13
|
+
case 'list':
|
|
14
|
+
await mcpList(ctx);
|
|
15
|
+
return;
|
|
16
|
+
case 'add':
|
|
17
|
+
await mcpAdd(parts.slice(1), ctx);
|
|
18
|
+
return;
|
|
19
|
+
case 'remove':
|
|
20
|
+
await mcpRemove(parts.slice(1), ctx);
|
|
21
|
+
return;
|
|
22
|
+
case 'reload':
|
|
23
|
+
await mcpReload(ctx);
|
|
24
|
+
return;
|
|
25
|
+
default:
|
|
26
|
+
console.log('用法:/mcp list | add <name> <command> [args...] | remove <name> | reload');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function mcpList(ctx) {
|
|
30
|
+
const servers = ctx.mcpManager.getServerNames();
|
|
31
|
+
if (servers.length === 0) {
|
|
32
|
+
console.log('没有已连接的 MCP server。');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log('已连接的 MCP server:');
|
|
36
|
+
const tools = await ctx.mcpManager.listTools();
|
|
37
|
+
for (const name of servers) {
|
|
38
|
+
const serverTools = tools
|
|
39
|
+
.filter((t) => t.serverName === name)
|
|
40
|
+
.map((t) => t.originalName);
|
|
41
|
+
console.log(` ${name}`);
|
|
42
|
+
for (const t of serverTools) {
|
|
43
|
+
console.log(` - ${t}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function mcpAdd(parts, ctx) {
|
|
48
|
+
if (parts.length < 2) {
|
|
49
|
+
console.log('用法:/mcp add <name> <command> [args...]');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const [name, command, ...args] = parts;
|
|
53
|
+
const cfg = { command, args };
|
|
54
|
+
// 先临时连一下测试是否可用
|
|
55
|
+
const testManager = new McpClientManager({ [name]: cfg }, { name: 'ccli', version: '0.0.0' });
|
|
56
|
+
const testErrors = await testManager.connectAll();
|
|
57
|
+
if (testErrors.length > 0) {
|
|
58
|
+
console.log(`连接失败:${testErrors[0]}`);
|
|
59
|
+
await testManager.closeAll();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// 把新 server 加到现有 manager
|
|
63
|
+
const currentConfig = ctx.mcpManager.getServersConfig();
|
|
64
|
+
const newConfig = { ...currentConfig, [name]: cfg };
|
|
65
|
+
// 持久化
|
|
66
|
+
const saved = saveMcpServers(ctx.cwd, newConfig);
|
|
67
|
+
if (!saved.ok) {
|
|
68
|
+
console.log(saved.message);
|
|
69
|
+
await testManager.closeAll();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// 更新 manager 配置并注册 tools
|
|
73
|
+
Object.assign(currentConfig, { [name]: cfg });
|
|
74
|
+
unregisterMcpServerTools(name);
|
|
75
|
+
await registerMcpTools(testManager);
|
|
76
|
+
console.log(`已添加 MCP server:${name}(配置已保存到 ${saved.path})`);
|
|
77
|
+
}
|
|
78
|
+
async function mcpRemove(parts, ctx) {
|
|
79
|
+
const name = parts[0];
|
|
80
|
+
if (!name) {
|
|
81
|
+
console.log('用法:/mcp remove <name>');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const removed = await ctx.mcpManager.removeServer(name);
|
|
85
|
+
if (!removed) {
|
|
86
|
+
console.log(`未找到 MCP server:${name}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
unregisterMcpServerTools(name);
|
|
90
|
+
const currentConfig = ctx.mcpManager.getServersConfig();
|
|
91
|
+
const newConfig = { ...currentConfig };
|
|
92
|
+
delete newConfig[name];
|
|
93
|
+
Object.assign(currentConfig, newConfig);
|
|
94
|
+
const saved = saveMcpServers(ctx.cwd, newConfig);
|
|
95
|
+
if (saved.ok) {
|
|
96
|
+
console.log(`已移除 MCP server:${name}(配置已保存到 ${saved.path})`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.log(`已移除 MCP server:${name},但保存配置失败:${saved.message}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function mcpReload(ctx) {
|
|
103
|
+
const result = ctx.reloadConfig();
|
|
104
|
+
if (!result.ok) {
|
|
105
|
+
console.log(`配置重载失败:${result.message}`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
console.log('配置已重新加载。');
|
|
109
|
+
await reloadMcpServers(ctx.mcpManager, result.config.mcpServers ?? {});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 根据最新配置刷新 MCP server:
|
|
113
|
+
* 关闭现有连接,用新配置重新连接并注册 tools。
|
|
114
|
+
*/
|
|
115
|
+
export async function reloadMcpServers(manager, mcpServers) {
|
|
116
|
+
await manager.closeAll();
|
|
117
|
+
unregisterAllMcpTools();
|
|
118
|
+
// 直接替换 manager 内部的 serversConfig 对象内容
|
|
119
|
+
const currentConfig = manager.getServersConfig();
|
|
120
|
+
for (const key of Object.keys(currentConfig)) {
|
|
121
|
+
delete currentConfig[key];
|
|
122
|
+
}
|
|
123
|
+
Object.assign(currentConfig, mcpServers);
|
|
124
|
+
const errors = await manager.connectAll();
|
|
125
|
+
if (errors.length > 0) {
|
|
126
|
+
console.error('部分 MCP server 连接失败:');
|
|
127
|
+
for (const e of errors)
|
|
128
|
+
console.error(` ${e}`);
|
|
129
|
+
}
|
|
130
|
+
await registerMcpTools(manager);
|
|
131
|
+
console.log('MCP server 已重新加载。');
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../../src/cli/slash/mcp/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { listSessions, loadSession, searchSessions, } from '../../session/index.js';
|
|
2
|
+
/** /load:精确匹配时直接加载;否则按关键词列出候选并支持交互式选择。 */
|
|
3
|
+
export async function handleLoad(arg, ctx) {
|
|
4
|
+
if (!arg) {
|
|
5
|
+
console.log('用法:/load <会话名>');
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
// 精确匹配 → 直接加载
|
|
9
|
+
const exact = listSessions().find((s) => s.name === arg);
|
|
10
|
+
if (exact) {
|
|
11
|
+
const result = loadSession(arg);
|
|
12
|
+
if (result.ok) {
|
|
13
|
+
ctx.history.length = 0;
|
|
14
|
+
ctx.history.push(...result.history);
|
|
15
|
+
console.log(`已加载会话:${result.name}(${result.history.length} 条消息)`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.log(result.message);
|
|
19
|
+
}
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// 否则按关键词搜索
|
|
23
|
+
const matches = searchSessions(arg);
|
|
24
|
+
if (matches.length === 0) {
|
|
25
|
+
console.log(`找不到包含 "${arg}" 的会话。`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// 只有一个候选 → 直接加载,不用输全名
|
|
29
|
+
if (matches.length === 1) {
|
|
30
|
+
const name = matches[0].name;
|
|
31
|
+
const result = loadSession(name);
|
|
32
|
+
if (result.ok) {
|
|
33
|
+
ctx.history.length = 0;
|
|
34
|
+
ctx.history.push(...result.history);
|
|
35
|
+
console.log(`已加载会话:${result.name}(${result.history.length} 条消息)`);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.log(result.message);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// 多个候选 → 列出让用户选
|
|
43
|
+
console.log(`未精确匹配 "${arg}",以下 ${matches.length} 个可选:`);
|
|
44
|
+
for (let i = 0; i < matches.length; i++) {
|
|
45
|
+
const s = matches[i];
|
|
46
|
+
console.log(` ${i + 1}. ${s.name}`);
|
|
47
|
+
}
|
|
48
|
+
const answer = (await ctx.ask('选择序号加载(直接回车取消):')).trim();
|
|
49
|
+
if (answer === '') {
|
|
50
|
+
console.log('已取消。');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const idx = Number.parseInt(answer, 10);
|
|
54
|
+
if (Number.isNaN(idx) || idx <= 0 || idx > matches.length) {
|
|
55
|
+
console.log('无效选择。');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const name = matches[idx - 1].name;
|
|
59
|
+
const result = loadSession(name);
|
|
60
|
+
if (result.ok) {
|
|
61
|
+
ctx.history.length = 0;
|
|
62
|
+
ctx.history.push(...result.history);
|
|
63
|
+
console.log(`已加载会话:${result.name}(${result.history.length} 条消息)`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log(result.message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../../src/cli/slash/session/load.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EACZ,WAAW,EACX,cAAc,GACjB,MAAM,wBAAwB,CAAC;AAGhC,0CAA0C;AAC1C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC5B,GAAW,EACX,GAAiB;IAEjB,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO;IACX,CAAC;IAED,cAAc;IACd,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IACzD,IAAI,KAAK,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACZ,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACvB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CACP,SAAS,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CACvD,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,OAAO;IACX,CAAC;IAED,WAAW;IACX,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC;QACnC,OAAO;IACX,CAAC;IAED,sBAAsB;IACtB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACZ,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACvB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CACP,SAAS,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CACvD,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,OAAO;IACX,CAAC;IAED,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,QAAQ,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC;IACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO;IACX,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO;IACX,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACZ,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CACP,SAAS,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CACvD,CAAC;IACN,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { hasLastSession, loadLastSession } from '../../session/index.js';
|
|
2
|
+
/** /resume:手动恢复上次自动保存的会话。 */
|
|
3
|
+
export function handleResume(ctx) {
|
|
4
|
+
if (!hasLastSession()) {
|
|
5
|
+
console.log('没有可恢复的 last 会话。');
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const loaded = loadLastSession();
|
|
9
|
+
if (loaded.ok) {
|
|
10
|
+
ctx.history.length = 0;
|
|
11
|
+
ctx.history.push(...loaded.history);
|
|
12
|
+
console.log(`已恢复上次会话(${loaded.history.length} 条消息)。`);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
console.log(`恢复失败:${loaded.message}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../../../src/cli/slash/session/resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzE,6BAA6B;AAC7B,MAAM,UAAU,YAAY,CAAC,GAAiB;IAC1C,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,OAAO;IACX,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACZ,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,OAAO,CAAC,MAAM,QAAQ,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { saveSession } from '../../session/index.js';
|
|
2
|
+
/** /save:把当前历史落盘。 */
|
|
3
|
+
export function handleSave(arg, ctx) {
|
|
4
|
+
const result = saveSession(ctx.history, arg);
|
|
5
|
+
if (result.ok) {
|
|
6
|
+
console.log(`已保存会话:${result.name}`);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
console.log(result.message);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=save.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../../../../src/cli/slash/session/save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,qBAAqB;AACrB,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,GAAiB;IACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { listSessions } from '../../session/index.js';
|
|
2
|
+
/** /sessions:列出所有保存的会话。 */
|
|
3
|
+
export function handleSessions() {
|
|
4
|
+
const sessions = listSessions();
|
|
5
|
+
if (sessions.length === 0) {
|
|
6
|
+
console.log('没有已保存的会话。');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
console.log('已保存的会话:');
|
|
10
|
+
for (const s of sessions) {
|
|
11
|
+
const time = s.updatedAt.toLocaleString();
|
|
12
|
+
console.log(` ${s.name.padEnd(30)} ${s.messageCount} 条 ${time}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../../src/cli/slash/session/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,2BAA2B;AAC3B,MAAM,UAAU,cAAc;IAC1B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,OAAO;IACX,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,OAAO,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { runAgentTurn } from '../../run/index.js';
|
|
2
|
+
import { getTool } from '../../../tools/index.js';
|
|
3
|
+
/** 规划阶段的系统提示:只输出计划,不调用工具。 */
|
|
4
|
+
const PLANNING_SYSTEM_PROMPT = `你是 CCLI 的 Agent 规划助手。
|
|
5
|
+
|
|
6
|
+
用户的任务会由另一个 Agent 来执行。你的工作是先制定一个清晰、可执行的计划。
|
|
7
|
+
|
|
8
|
+
可用工具包括:
|
|
9
|
+
- read_file:读取文件内容
|
|
10
|
+
- list_dir:列出目录内容
|
|
11
|
+
- grep:在文件中搜索文本
|
|
12
|
+
- write_file:创建或覆盖文件
|
|
13
|
+
- edit_file:编辑文件的特定部分
|
|
14
|
+
- bash:执行 shell 命令
|
|
15
|
+
|
|
16
|
+
要求:
|
|
17
|
+
1. 只输出计划,不要调用任何工具。
|
|
18
|
+
2. 计划用编号列表,每一步说明要做什么、准备调用哪个工具。
|
|
19
|
+
3. 计划要简洁,不要包含大段代码或文件内容。
|
|
20
|
+
4. 如果任务明显无法完成,直接说明原因。`;
|
|
21
|
+
/** 执行阶段的系统提示:让模型按计划调用工具并完成任务。 */
|
|
22
|
+
const EXECUTION_SYSTEM_PROMPT = `你是 CCLI 的 Agent 执行助手。
|
|
23
|
+
|
|
24
|
+
你的工作方式是:
|
|
25
|
+
1. 调用可用工具收集信息或执行操作。
|
|
26
|
+
2. 根据工具返回结果继续下一步。
|
|
27
|
+
3. 任务完成后,给出清晰简洁的最终总结。
|
|
28
|
+
|
|
29
|
+
注意:
|
|
30
|
+
- 对于写文件、编辑文件、执行 shell 等破坏性操作,系统会先向用户确认。
|
|
31
|
+
- 保持回复简洁,重点放在行动和结果上。
|
|
32
|
+
- 如果某一步失败,尝试用其他方式完成,或说明无法完成的原因。`;
|
|
33
|
+
/** 从计划文本中解析编号步骤。 */
|
|
34
|
+
export function parsePlanSteps(plan) {
|
|
35
|
+
return plan
|
|
36
|
+
.split('\n')
|
|
37
|
+
.map((line) => line.trim())
|
|
38
|
+
.filter((line) => /^\d+[.、.\)\]]\s*/.test(line))
|
|
39
|
+
.map((line) => line.replace(/^\d+[.、.\)\]]\s*/, '').trim());
|
|
40
|
+
}
|
|
41
|
+
/** 计划进度跟踪器:负责打印带状态标记的计划。 */
|
|
42
|
+
export class PlanTracker {
|
|
43
|
+
steps;
|
|
44
|
+
completed = 0;
|
|
45
|
+
constructor(plan) {
|
|
46
|
+
this.steps = parsePlanSteps(plan);
|
|
47
|
+
}
|
|
48
|
+
hasSteps() {
|
|
49
|
+
return this.steps.length > 0;
|
|
50
|
+
}
|
|
51
|
+
total() {
|
|
52
|
+
return this.steps.length;
|
|
53
|
+
}
|
|
54
|
+
/** 打印当前步骤(执行中)。 */
|
|
55
|
+
printCurrent() {
|
|
56
|
+
const idx = Math.min(this.completed, this.steps.length - 1);
|
|
57
|
+
const text = this.steps[idx] ?? '继续执行';
|
|
58
|
+
console.log(`\n[→] 步骤 ${idx + 1}/${this.steps.length}:${text}`);
|
|
59
|
+
}
|
|
60
|
+
/** 打印刚完成的步骤。 */
|
|
61
|
+
printDone() {
|
|
62
|
+
const idx = this.completed;
|
|
63
|
+
if (idx >= 0 && idx < this.steps.length) {
|
|
64
|
+
console.log(`[✓] 步骤 ${idx + 1}/${this.steps.length} 完成`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** 打印完整计划状态。 */
|
|
68
|
+
printState() {
|
|
69
|
+
if (this.steps.length === 0)
|
|
70
|
+
return;
|
|
71
|
+
console.log('[Agent] 当前计划状态:');
|
|
72
|
+
for (let i = 0; i < this.steps.length; i++) {
|
|
73
|
+
let marker;
|
|
74
|
+
if (i < this.completed) {
|
|
75
|
+
marker = '[✓]';
|
|
76
|
+
}
|
|
77
|
+
else if (i === this.completed) {
|
|
78
|
+
marker = '[→]';
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
marker = '[ ]';
|
|
82
|
+
}
|
|
83
|
+
console.log(`${marker} ${i + 1}. ${this.steps[i]}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** 标记当前步骤已完成。 */
|
|
87
|
+
advance() {
|
|
88
|
+
if (this.completed < this.steps.length) {
|
|
89
|
+
this.completed++;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** 截断过长的工具结果,便于在终端阅读。 */
|
|
94
|
+
function truncateResult(result, max = 300) {
|
|
95
|
+
if (result.length <= max)
|
|
96
|
+
return result;
|
|
97
|
+
return result.slice(0, max) + '\n...(结果已截断)';
|
|
98
|
+
}
|
|
99
|
+
/** 把工具调用格式化成易读的摘要。 */
|
|
100
|
+
function formatToolCall(tc) {
|
|
101
|
+
const tool = getTool(tc.name);
|
|
102
|
+
if (tool?.preview) {
|
|
103
|
+
try {
|
|
104
|
+
return tool.preview(JSON.parse(tc.arguments || '{}'));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// 预览解析失败时降级为原始参数
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return `${tc.name}(${tc.arguments})`;
|
|
111
|
+
}
|
|
112
|
+
/** 向 AI 请求制定计划,返回计划文本。 */
|
|
113
|
+
async function buildPlan(task, ctx) {
|
|
114
|
+
const planningHistory = [
|
|
115
|
+
{ role: 'system', content: PLANNING_SYSTEM_PROMPT },
|
|
116
|
+
{ role: 'user', content: task },
|
|
117
|
+
];
|
|
118
|
+
let plan = '';
|
|
119
|
+
const turn = await ctx.ai.chat(planningHistory, (delta) => {
|
|
120
|
+
plan += delta;
|
|
121
|
+
process.stdout.write(delta);
|
|
122
|
+
}, { disableTools: true });
|
|
123
|
+
plan = turn.content || plan;
|
|
124
|
+
return plan.trim();
|
|
125
|
+
}
|
|
126
|
+
/** 使用 ask 包装确认函数。 */
|
|
127
|
+
function makeConfirm(ctx) {
|
|
128
|
+
return async (preview) => {
|
|
129
|
+
console.log('\n' + preview);
|
|
130
|
+
const answer = (await ctx.ask('确认执行?(y/N) ')).trim().toLowerCase();
|
|
131
|
+
return answer === 'y' || answer === 'yes';
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** /agent:先制定计划,确认后自动执行。 */
|
|
135
|
+
export async function handleAgent(arg, ctx) {
|
|
136
|
+
const task = arg.trim();
|
|
137
|
+
if (task.length === 0) {
|
|
138
|
+
console.log('用法:/agent <任务描述>');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
console.log(`[Agent] 开始为任务制定计划:${task}\n`);
|
|
142
|
+
const plan = await buildPlan(task, ctx);
|
|
143
|
+
if (!plan) {
|
|
144
|
+
console.log('\n[Agent] 未能生成计划。');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
console.log('\n\n[Agent] 计划如下:');
|
|
148
|
+
console.log(plan);
|
|
149
|
+
const answer = (await ctx.ask('\n是否按此计划执行?(y/N) '))
|
|
150
|
+
.trim()
|
|
151
|
+
.toLowerCase();
|
|
152
|
+
if (answer !== 'y' && answer !== 'yes') {
|
|
153
|
+
console.log('[Agent] 已取消执行。');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
console.log('\n[Agent] 开始执行计划...');
|
|
157
|
+
const tracker = new PlanTracker(plan);
|
|
158
|
+
if (tracker.hasSteps()) {
|
|
159
|
+
tracker.printState();
|
|
160
|
+
}
|
|
161
|
+
// 切换为执行系统提示,并注入已批准的计划
|
|
162
|
+
ctx.history[0].content = `${EXECUTION_SYSTEM_PROMPT}\n\n已批准的计划:\n${plan}`;
|
|
163
|
+
ctx.history.push({ role: 'user', content: task });
|
|
164
|
+
await runAgentTurn({
|
|
165
|
+
ai: ctx.ai,
|
|
166
|
+
history: ctx.history,
|
|
167
|
+
confirm: makeConfirm(ctx),
|
|
168
|
+
stats: ctx.stats,
|
|
169
|
+
maxRounds: 30,
|
|
170
|
+
requireToolsFirstRound: true,
|
|
171
|
+
onToolCall: (tc) => {
|
|
172
|
+
if (tracker.hasSteps()) {
|
|
173
|
+
tracker.printCurrent();
|
|
174
|
+
}
|
|
175
|
+
console.log(`\n[Agent] 调用 ${tc.name}`);
|
|
176
|
+
console.log(formatToolCall(tc));
|
|
177
|
+
},
|
|
178
|
+
onToolResult: (tc, result) => {
|
|
179
|
+
console.log(`\n[Agent] ${tc.name} 结果:`);
|
|
180
|
+
console.log(truncateResult(result));
|
|
181
|
+
if (tracker.hasSteps()) {
|
|
182
|
+
tracker.advance();
|
|
183
|
+
tracker.printState();
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
console.log('\n[Agent] 任务执行结束');
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { deleteSession } from '../../session/index.js';
|
|
2
|
+
/** /delete:删除指定已保存会话,执行前需要用户确认。 */
|
|
3
|
+
export async function handleDelete(arg, ctx) {
|
|
4
|
+
const name = arg.trim();
|
|
5
|
+
if (name.length === 0) {
|
|
6
|
+
console.log('用法:/delete <会话名>');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const answer = (await ctx.ask(`确认删除会话 "${name}"?(y/N) `))
|
|
10
|
+
.trim()
|
|
11
|
+
.toLowerCase();
|
|
12
|
+
if (answer !== 'y' && answer !== 'yes') {
|
|
13
|
+
console.log('已取消。');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const result = deleteSession(name);
|
|
17
|
+
if (result.ok) {
|
|
18
|
+
console.log(`已删除会话:${result.name}`);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
console.log(result.message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,mCAAmC;AACnC,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,GAAW,EACX,GAAiB;IAEjB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,UAAU,CAAC,CAAC;SACpD,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;IACnB,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;AACL,CAAC"}
|