@gird/ccli 2.6.0 → 2.8.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 +2 -0
- package/dist/cli/confirm-select.js +92 -0
- package/dist/cli/confirm-select.js.map +1 -0
- package/dist/cli/file-reference.js +91 -0
- package/dist/cli/file-reference.js.map +1 -0
- package/dist/cli/repl/index.js +44 -10
- package/dist/cli/repl/index.js.map +1 -1
- package/dist/cli/slash/index.js +8 -0
- package/dist/cli/slash/index.js.map +1 -1
- package/dist/cli/slash/system/agent.js +4 -4
- package/dist/cli/slash/system/agent.js.map +1 -1
- package/dist/cli/slash/system/compact.js +139 -0
- package/dist/cli/slash/system/compact.js.map +1 -0
- package/dist/cli/slash/system/goal.js +159 -0
- package/dist/cli/slash/system/goal.js.map +1 -0
- package/dist/cli/slash/system/help.js +2 -0
- package/dist/cli/slash/system/help.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,9 +31,11 @@ ccli --role coder "review 这段代码" # 使用 coding 角色单次调用
|
|
|
31
31
|
- 直接输入即与 AI 对话,模型会记住上文(多轮对话)。
|
|
32
32
|
- 模型可调用的工具:读文件、列目录、搜索代码、写文件、局部编辑文件、执行 shell 命令(写入/编辑/执行操作会请你确认)。
|
|
33
33
|
- `/help` 查看可用命令,`/clear` 清空历史,`/undo [n]` 撤销最近 n 轮对话。
|
|
34
|
+
- `/compact` 把对话历史压缩成一段摘要,释放上下文(长对话逼近上限时用;仅在确有收益时替换)。上下文占比达到约 80% 时也会**自动压缩**。
|
|
34
35
|
- `/model [id]` 查看当前模型或切换到新模型(输入空参数只查看)。
|
|
35
36
|
- `/save [name]` 保存当前会话,`/load <name>` 加载会话(`Tab` 子串补全;多个候选时列出序号,输入数字即可加载),`/sessions` 列出已保存会话,`/delete <name>` 删除指定会话(需确认)。
|
|
36
37
|
- `/agent <任务描述>` 进入自动任务执行模式:AI 先制定计划,经你确认后自动调用工具逐步完成。
|
|
38
|
+
- `/goal <任务> [| <完成条件>]` 进入目标执行模式:在 `/agent` 基础上,执行结束后再按完成条件做一次达成判定;完成条件可省略,省略时由规划阶段先补一条可检查条件。
|
|
37
39
|
- `/resume` 手动恢复上次退出时自动保存的会话。
|
|
38
40
|
- `/reload` 重新加载 `.ccli/config.json` 并刷新 MCP server。
|
|
39
41
|
- `/stats` 查看当前会话累计 token 消耗与上下文占比(估算值)。
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 终端键盘选择确认组件。
|
|
3
|
+
*
|
|
4
|
+
* 用方向键在 `[执行]` / `[取消]` 之间切换,回车确认。
|
|
5
|
+
* 非 TTY 环境降级为文字输入 y/N。
|
|
6
|
+
*/
|
|
7
|
+
import { emitKeypressEvents } from 'node:readline';
|
|
8
|
+
/** 生成当前状态的显示字符串。 */
|
|
9
|
+
export function renderConfirmState(options) {
|
|
10
|
+
const { prompt, confirmed, confirmLabel, cancelLabel } = options;
|
|
11
|
+
return confirmed
|
|
12
|
+
? `${prompt} [${confirmLabel}] ${cancelLabel}`
|
|
13
|
+
: `${prompt} ${confirmLabel} [${cancelLabel}]`;
|
|
14
|
+
}
|
|
15
|
+
/** 非 TTY 环境下使用的文字确认。 */
|
|
16
|
+
function fallbackTextConfirm(prompt) {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
process.stdout.write(`${prompt} (y/N) `);
|
|
19
|
+
process.stdin.once('data', (data) => {
|
|
20
|
+
const answer = data.toString().trim().toLowerCase();
|
|
21
|
+
resolve(answer === 'y' || answer === 'yes');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 用方向键选择确认/取消。
|
|
27
|
+
*
|
|
28
|
+
* 调用方应自行暂停其他 stdin 消费者(如 readline),避免按键被重复处理。
|
|
29
|
+
*/
|
|
30
|
+
export async function confirmSelect(options) {
|
|
31
|
+
const { prompt, defaultConfirm = false, confirmLabel = '执行', cancelLabel = '取消', } = options;
|
|
32
|
+
const stdin = process.stdin;
|
|
33
|
+
const stdout = process.stdout;
|
|
34
|
+
if (!stdin.isTTY || !stdout.isTTY) {
|
|
35
|
+
return fallbackTextConfirm(prompt);
|
|
36
|
+
}
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
let confirmed = defaultConfirm;
|
|
39
|
+
const originalRawMode = stdin.isRaw;
|
|
40
|
+
stdin.setRawMode(true);
|
|
41
|
+
emitKeypressEvents(stdin);
|
|
42
|
+
function render() {
|
|
43
|
+
const line = renderConfirmState({
|
|
44
|
+
prompt,
|
|
45
|
+
confirmed,
|
|
46
|
+
confirmLabel,
|
|
47
|
+
cancelLabel,
|
|
48
|
+
});
|
|
49
|
+
stdout.write(`\r\x1b[K${line}`);
|
|
50
|
+
}
|
|
51
|
+
function cleanup() {
|
|
52
|
+
stdin.setRawMode(originalRawMode ?? false);
|
|
53
|
+
stdin.removeListener('keypress', onKeypress);
|
|
54
|
+
}
|
|
55
|
+
function finish(value) {
|
|
56
|
+
cleanup();
|
|
57
|
+
const label = value ? confirmLabel : cancelLabel;
|
|
58
|
+
stdout.write(`\r\x1b[K${prompt} [${label}]\n`);
|
|
59
|
+
resolve(value);
|
|
60
|
+
}
|
|
61
|
+
function onKeypress(str, key) {
|
|
62
|
+
if (key.ctrl && key.name === 'c') {
|
|
63
|
+
cleanup();
|
|
64
|
+
stdout.write('\n');
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
switch (key.name) {
|
|
68
|
+
case 'return':
|
|
69
|
+
case 'enter':
|
|
70
|
+
finish(confirmed);
|
|
71
|
+
return;
|
|
72
|
+
case 'left':
|
|
73
|
+
case 'right':
|
|
74
|
+
case 'up':
|
|
75
|
+
case 'down':
|
|
76
|
+
confirmed = !confirmed;
|
|
77
|
+
render();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const lower = str.toLowerCase();
|
|
81
|
+
if (lower === 'y') {
|
|
82
|
+
finish(true);
|
|
83
|
+
}
|
|
84
|
+
else if (lower === 'n') {
|
|
85
|
+
finish(false);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
render();
|
|
89
|
+
stdin.on('keypress', onKeypress);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=confirm-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-select.js","sourceRoot":"","sources":["../../src/cli/confirm-select.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 文件引用支持。
|
|
3
|
+
*
|
|
4
|
+
* 用户在提示词里写 `@path/to/file`,系统自动读取文件内容并注入当前消息。
|
|
5
|
+
* 同时提供 Tab 补全,方便在 REPL 里选择文件。
|
|
6
|
+
*/
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
import { existsSync, statSync, readdirSync, readFileSync, } from 'node:fs';
|
|
9
|
+
/** 匹配 `@路径`;路径在空白或常见中英文标点处结束。 */
|
|
10
|
+
const FILE_REF_REGEX = /@([^\s,。!?;:"'()【】、,!?;:'"()\[\]{}]+)/g;
|
|
11
|
+
/** 读取单个引用文件的内容;失败时返回可读错误文本。 */
|
|
12
|
+
function readReference(refPath, cwd) {
|
|
13
|
+
const fullPath = resolve(cwd, refPath);
|
|
14
|
+
if (!existsSync(fullPath)) {
|
|
15
|
+
return { ok: false, error: `文件不存在:${refPath}` };
|
|
16
|
+
}
|
|
17
|
+
const stat = statSync(fullPath);
|
|
18
|
+
if (!stat.isFile()) {
|
|
19
|
+
return { ok: false, error: `不是普通文件:${refPath}` };
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
return { ok: true, content: readFileSync(fullPath, 'utf8') };
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
return { ok: false, error: `读取失败:${refPath}(${e?.message ?? e})` };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 把提示词中的 `@路径` 替换成引用标记,并在末尾追加文件内容块。
|
|
30
|
+
*
|
|
31
|
+
* 不存在的文件会以内联错误提示替换,避免让模型产生幻觉。
|
|
32
|
+
*/
|
|
33
|
+
export function injectFileReferences(input, cwd) {
|
|
34
|
+
const matches = [...input.matchAll(FILE_REF_REGEX)];
|
|
35
|
+
if (matches.length === 0)
|
|
36
|
+
return input;
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const blocks = [];
|
|
39
|
+
let result = input;
|
|
40
|
+
for (const match of matches) {
|
|
41
|
+
const refPath = match[1];
|
|
42
|
+
if (seen.has(refPath))
|
|
43
|
+
continue;
|
|
44
|
+
seen.add(refPath);
|
|
45
|
+
const read = readReference(refPath, cwd);
|
|
46
|
+
if (!read.ok) {
|
|
47
|
+
// 错误直接内联替换,让用户立刻知道
|
|
48
|
+
result = result.replaceAll(`@${refPath}`, `[${read.error}]`);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// 原位置保留引用标记,内容块放到消息末尾
|
|
52
|
+
result = result.replaceAll(`@${refPath}`, `[引用文件: ${refPath}]`);
|
|
53
|
+
blocks.push(`<file path="${refPath}">\n${read.content}\n</file>`);
|
|
54
|
+
}
|
|
55
|
+
if (blocks.length === 0)
|
|
56
|
+
return result;
|
|
57
|
+
return `${result}\n\n---\n${blocks.join('\n\n')}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 为 `@路径` 提供 Tab 补全。
|
|
61
|
+
*
|
|
62
|
+
* 返回 readline 补全函数要求的 `[候选列表, 已输入子串]` 元组。
|
|
63
|
+
*/
|
|
64
|
+
export function completeFileReference(line) {
|
|
65
|
+
const lastAt = line.lastIndexOf('@');
|
|
66
|
+
if (lastAt === -1)
|
|
67
|
+
return [[], line];
|
|
68
|
+
const afterAt = line.slice(lastAt + 1);
|
|
69
|
+
// 如果 @ 后面已经遇到空格,说明不在文件引用上下文里
|
|
70
|
+
if (afterAt.includes(' '))
|
|
71
|
+
return [[], line];
|
|
72
|
+
const prefix = afterAt;
|
|
73
|
+
const lastSlash = prefix.lastIndexOf('/');
|
|
74
|
+
const dirPart = lastSlash === -1 ? '.' : prefix.slice(0, lastSlash);
|
|
75
|
+
const basePart = lastSlash === -1 ? prefix : prefix.slice(lastSlash + 1);
|
|
76
|
+
const targetDir = resolve(process.cwd(), dirPart);
|
|
77
|
+
if (!existsSync(targetDir) || !statSync(targetDir).isDirectory()) {
|
|
78
|
+
return [[], line];
|
|
79
|
+
}
|
|
80
|
+
const entries = readdirSync(targetDir, { withFileTypes: true });
|
|
81
|
+
const dirPrefix = dirPart === '.' ? '' : `${dirPart}/`;
|
|
82
|
+
const hits = entries
|
|
83
|
+
.filter((e) => e.name.startsWith(basePart))
|
|
84
|
+
.map((e) => {
|
|
85
|
+
const suffix = e.isDirectory() ? '/' : '';
|
|
86
|
+
return `@${dirPrefix}${e.name}${suffix}`;
|
|
87
|
+
})
|
|
88
|
+
.sort();
|
|
89
|
+
return [hits, `@${prefix}`];
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=file-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-reference.js","sourceRoot":"","sources":["../../src/cli/file-reference.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/repl/index.js
CHANGED
|
@@ -12,13 +12,16 @@ import { loadConfig, maskKey, DEFAULT_SYSTEM_PROMPT, getRolePrompt, } from '../.
|
|
|
12
12
|
import { loadEnvFile } from '../../config/env.js';
|
|
13
13
|
import { createAIClient } from '../../agent/ai.js';
|
|
14
14
|
import { handleSlash, slashCompleter } from '../slash/index.js';
|
|
15
|
+
import { injectFileReferences, completeFileReference, } from '../file-reference.js';
|
|
15
16
|
import { saveLastSession } from '../session/index.js';
|
|
16
17
|
import { appendHistory, loadHistory } from './history.js';
|
|
17
18
|
import { InputBuffer } from './input.js';
|
|
19
|
+
import { confirmSelect } from '../confirm-select.js';
|
|
18
20
|
import { McpClientManager } from '../../agent/mcp.js';
|
|
19
21
|
import { registerMcpTools, resetTools } from '../../tools/index.js';
|
|
20
22
|
import { emptyStats, formatStats, } from '../stats/index.js';
|
|
21
23
|
import { runAgentTurn } from '../run/index.js';
|
|
24
|
+
import { autoCompactIfNeeded } from '../slash/system/compact.js';
|
|
22
25
|
const PROMPT = '› ';
|
|
23
26
|
/** 单个用户回合内,最多允许模型连续调用工具的轮数,防止失控循环。 */
|
|
24
27
|
const MAX_TOOL_ROUNDS = 10;
|
|
@@ -53,11 +56,20 @@ export async function startRepl() {
|
|
|
53
56
|
];
|
|
54
57
|
let currentRole = 'default';
|
|
55
58
|
let stats = emptyStats();
|
|
59
|
+
/** 组合补全:优先斜杠命令,@ 开头时尝试文件引用补全。 */
|
|
60
|
+
const inputCompleter = (line) => {
|
|
61
|
+
if (line.includes('@')) {
|
|
62
|
+
const [hits, substr] = completeFileReference(line);
|
|
63
|
+
if (hits.length > 0)
|
|
64
|
+
return [hits, substr];
|
|
65
|
+
}
|
|
66
|
+
return slashCompleter(line);
|
|
67
|
+
};
|
|
56
68
|
const rl = createInterface({
|
|
57
69
|
input: process.stdin,
|
|
58
70
|
output: process.stdout,
|
|
59
71
|
prompt: PROMPT,
|
|
60
|
-
completer:
|
|
72
|
+
completer: inputCompleter,
|
|
61
73
|
history: loadHistory(),
|
|
62
74
|
historySize: 1000,
|
|
63
75
|
});
|
|
@@ -65,14 +77,20 @@ export async function startRepl() {
|
|
|
65
77
|
console.log(`后端: ${config.provider} 模型: ${config.model} 密钥: ${maskKey(config.apiKey)}`);
|
|
66
78
|
console.log('进入交互式会话。输入 /help 查看命令,/exit 退出。\n');
|
|
67
79
|
rl.prompt();
|
|
68
|
-
// 请用户确认破坏性操作:展示预览 +
|
|
69
|
-
const confirm = (preview) =>
|
|
80
|
+
// 请用户确认破坏性操作:展示预览 + 方向键选择(默认取消,更安全)
|
|
81
|
+
const confirm = async (preview) => {
|
|
70
82
|
console.log('\n' + preview);
|
|
71
|
-
rl.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
83
|
+
rl.pause();
|
|
84
|
+
try {
|
|
85
|
+
return await confirmSelect({
|
|
86
|
+
prompt: '确认执行?',
|
|
87
|
+
defaultConfirm: false,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
rl.resume();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
76
94
|
// 正在等待 AI 回复时置 true,避免这期间的输入被重复处理
|
|
77
95
|
let busy = false;
|
|
78
96
|
const INPUT_DEBOUNCE_MS = 80;
|
|
@@ -80,12 +98,14 @@ export async function startRepl() {
|
|
|
80
98
|
async function processUserInput(input) {
|
|
81
99
|
// 非空输入追加到持久化历史(readline 内存历史已自动维护)
|
|
82
100
|
appendHistory(input);
|
|
101
|
+
// 把 @文件引用 解析并注入文件内容
|
|
102
|
+
const processedInput = injectFileReferences(input, process.cwd());
|
|
83
103
|
// 斜杠命令:交给 handleSlash,不发给 AI
|
|
84
104
|
// (/model 会联网列模型,故也置 busy 防止期间重复处理)
|
|
85
105
|
if (input.startsWith('/')) {
|
|
86
106
|
busy = true;
|
|
87
107
|
let exiting = false;
|
|
88
|
-
await handleSlash(
|
|
108
|
+
await handleSlash(processedInput, {
|
|
89
109
|
history,
|
|
90
110
|
ai,
|
|
91
111
|
stats,
|
|
@@ -104,6 +124,18 @@ export async function startRepl() {
|
|
|
104
124
|
rl.close();
|
|
105
125
|
},
|
|
106
126
|
ask: (prompt) => new Promise((resolve) => rl.question(prompt, resolve)),
|
|
127
|
+
confirm: async (prompt) => {
|
|
128
|
+
rl.pause();
|
|
129
|
+
try {
|
|
130
|
+
return await confirmSelect({
|
|
131
|
+
prompt,
|
|
132
|
+
defaultConfirm: false,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
rl.resume();
|
|
137
|
+
}
|
|
138
|
+
},
|
|
107
139
|
reloadConfig: () => {
|
|
108
140
|
const r = loadConfig();
|
|
109
141
|
if (r.ok) {
|
|
@@ -120,11 +152,13 @@ export async function startRepl() {
|
|
|
120
152
|
}
|
|
121
153
|
busy = true;
|
|
122
154
|
const mark = history.length; // 出错时回滚到这里,避免半截上下文
|
|
123
|
-
history.push({ role: 'user', content:
|
|
155
|
+
history.push({ role: 'user', content: processedInput });
|
|
124
156
|
try {
|
|
125
157
|
await runAgentTurn({ ai, history, confirm, stats });
|
|
126
158
|
// 本回合结束,显示本次 token 消耗
|
|
127
159
|
console.log(`\n${formatStats(stats, ai.getModel())}`);
|
|
160
|
+
// 上下文接近上限时自动压缩,避免下一轮溢出
|
|
161
|
+
await autoCompactIfNeeded(ai, history, stats);
|
|
128
162
|
}
|
|
129
163
|
catch (e) {
|
|
130
164
|
console.error(`\n[请求失败] ${e?.message ?? e}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/repl/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACH,UAAU,EACV,OAAO,EACP,qBAAqB,EACrB,aAAa,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAoB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EACH,UAAU,EAEV,WAAW,GAEd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAgB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/repl/index.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/slash/index.js
CHANGED
|
@@ -16,9 +16,11 @@ import { handleSessions } from './session/sessions.js';
|
|
|
16
16
|
import { handleStats } from './system/stats.js';
|
|
17
17
|
import { handleDelete } from './system/delete.js';
|
|
18
18
|
import { handleAgent } from './system/agent.js';
|
|
19
|
+
import { handleGoal } from './system/goal.js';
|
|
19
20
|
import { handleResume } from './session/resume.js';
|
|
20
21
|
import { handleRole } from './config/role.js';
|
|
21
22
|
import { handleMcp, reloadMcpServers } from './mcp/mcp.js';
|
|
23
|
+
import { handleCompact } from './system/compact.js';
|
|
22
24
|
/**
|
|
23
25
|
* readline 的 Tab 补全函数。
|
|
24
26
|
* 对斜杠命令和 /load 的会话名提供补全提示。
|
|
@@ -66,6 +68,9 @@ export async function handleSlash(input, ctx) {
|
|
|
66
68
|
case 'undo':
|
|
67
69
|
handleUndo(arg, ctx);
|
|
68
70
|
return true;
|
|
71
|
+
case 'compact':
|
|
72
|
+
await handleCompact(ctx);
|
|
73
|
+
return true;
|
|
69
74
|
case 'model':
|
|
70
75
|
await handleModel(arg, ctx);
|
|
71
76
|
return true;
|
|
@@ -84,6 +89,9 @@ export async function handleSlash(input, ctx) {
|
|
|
84
89
|
case 'agent':
|
|
85
90
|
await handleAgent(arg, ctx);
|
|
86
91
|
return true;
|
|
92
|
+
case 'goal':
|
|
93
|
+
await handleGoal(arg, ctx);
|
|
94
|
+
return true;
|
|
87
95
|
case 'stats':
|
|
88
96
|
handleStats(ctx);
|
|
89
97
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/slash/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/slash/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ const PLANNING_SYSTEM_PROMPT = `你是 CCLI 的 Agent 规划助手。
|
|
|
19
19
|
3. 计划要简洁,不要包含大段代码或文件内容。
|
|
20
20
|
4. 如果任务明显无法完成,直接说明原因。`;
|
|
21
21
|
/** 执行阶段的系统提示:让模型按计划调用工具并完成任务。 */
|
|
22
|
-
const EXECUTION_SYSTEM_PROMPT = `你是 CCLI 的 Agent 执行助手。
|
|
22
|
+
export const EXECUTION_SYSTEM_PROMPT = `你是 CCLI 的 Agent 执行助手。
|
|
23
23
|
|
|
24
24
|
你的工作方式是:
|
|
25
25
|
1. 调用可用工具收集信息或执行操作。
|
|
@@ -110,9 +110,9 @@ function formatToolCall(tc) {
|
|
|
110
110
|
return `${tc.name}(${tc.arguments})`;
|
|
111
111
|
}
|
|
112
112
|
/** 向 AI 请求制定计划,返回计划文本。 */
|
|
113
|
-
async function buildPlan(task, ctx) {
|
|
113
|
+
export async function buildPlan(task, ctx, systemPrompt = PLANNING_SYSTEM_PROMPT) {
|
|
114
114
|
const planningHistory = [
|
|
115
|
-
{ role: 'system', content:
|
|
115
|
+
{ role: 'system', content: systemPrompt },
|
|
116
116
|
{ role: 'user', content: task },
|
|
117
117
|
];
|
|
118
118
|
let plan = '';
|
|
@@ -124,7 +124,7 @@ async function buildPlan(task, ctx) {
|
|
|
124
124
|
return plan.trim();
|
|
125
125
|
}
|
|
126
126
|
/** 使用 ask 包装确认函数。 */
|
|
127
|
-
function makeConfirm(ctx) {
|
|
127
|
+
export function makeConfirm(ctx) {
|
|
128
128
|
return async (preview) => {
|
|
129
129
|
console.log('\n' + preview);
|
|
130
130
|
const answer = (await ctx.ask('确认执行?(y/N) ')).trim().toLowerCase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAGlD,6BAA6B;AAC7B,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;sBAgBT,CAAC;AAEvB,iCAAiC;AACjC,MAAM,uBAAuB,GAAG;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { estimatePromptTokens, resetStats, getContextLimit, } from '../../stats/index.js';
|
|
2
|
+
/** 上下文占比低于此值时,压缩通常没必要,先向用户确认。 */
|
|
3
|
+
const COMPACT_MIN_RATIO = 0.5;
|
|
4
|
+
/** 上下文占比达到此值时,下一轮对话前自动压缩。 */
|
|
5
|
+
const AUTO_COMPACT_RATIO = 0.8;
|
|
6
|
+
/** 摘要请求用的系统提示:要求客观、信息完整、便于据此继续对话。 */
|
|
7
|
+
const SUMMARY_SYSTEM = '你是一个对话摘要助手。请把给定的对话历史压缩成一段简洁但信息完整的摘要,' +
|
|
8
|
+
'用中文、以第三人称客观记录。务必保留:用户的目标与关键决策、已确认的事实、' +
|
|
9
|
+
'涉及的文件/代码/命令、尚未完成的事项、以及任何后续需要的上下文。' +
|
|
10
|
+
'不要遗漏关键信息,也不要编造。只输出摘要本身,不要额外寒暄。';
|
|
11
|
+
/** 把任意消息内容转成纯文本。 */
|
|
12
|
+
function textOf(content) {
|
|
13
|
+
return typeof content === 'string'
|
|
14
|
+
? content
|
|
15
|
+
: JSON.stringify(content ?? '');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 把对话历史(跳过第 0 条 system 提示)序列化成一段可读文本,喂给摘要模型。
|
|
19
|
+
* 导出以便单元测试。
|
|
20
|
+
*/
|
|
21
|
+
export function serializeHistory(history) {
|
|
22
|
+
return history
|
|
23
|
+
.slice(1)
|
|
24
|
+
.map((m) => {
|
|
25
|
+
if (m.role === 'tool') {
|
|
26
|
+
return `[工具结果] ${textOf(m.content)}`;
|
|
27
|
+
}
|
|
28
|
+
const toolCalls = m
|
|
29
|
+
.tool_calls;
|
|
30
|
+
let line = `${m.role}: ${textOf(m.content)}`;
|
|
31
|
+
if (toolCalls?.length) {
|
|
32
|
+
const names = toolCalls.map((t) => t.function.name).join(', ');
|
|
33
|
+
line += ` [调用工具: ${names}]`;
|
|
34
|
+
}
|
|
35
|
+
return line;
|
|
36
|
+
})
|
|
37
|
+
.join('\n');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 压缩核心:把历史压成摘要并原地替换(仅在有收益时)。
|
|
41
|
+
* 不含占比阈值确认、不打印结果——那些由调用方(手动/自动)决定。
|
|
42
|
+
* 被 handleCompact(/compact)与 autoCompactIfNeeded(自动)共用。
|
|
43
|
+
*/
|
|
44
|
+
async function compactHistory(ai, history, stats) {
|
|
45
|
+
if (history.length <= 1)
|
|
46
|
+
return { status: 'empty' };
|
|
47
|
+
const before = estimatePromptTokens(history);
|
|
48
|
+
const convo = serializeHistory(history);
|
|
49
|
+
const summaryMessages = [
|
|
50
|
+
{ role: 'system', content: SUMMARY_SYSTEM },
|
|
51
|
+
{ role: 'user', content: `请压缩以下对话历史:\n\n${convo}` },
|
|
52
|
+
];
|
|
53
|
+
console.log('正在压缩上下文…\n');
|
|
54
|
+
let summary;
|
|
55
|
+
try {
|
|
56
|
+
// 压缩时禁用工具,只要文本摘要
|
|
57
|
+
const turn = await ai.chat(summaryMessages, (d) => process.stdout.write(d), { disableTools: true });
|
|
58
|
+
summary = turn.content.trim();
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return { status: 'failed', message: e?.message ?? String(e) };
|
|
62
|
+
}
|
|
63
|
+
if (!summary) {
|
|
64
|
+
return { status: 'failed', message: '模型未返回摘要' };
|
|
65
|
+
}
|
|
66
|
+
const system = history[0];
|
|
67
|
+
const summaryMessage = {
|
|
68
|
+
role: 'user',
|
|
69
|
+
content: `[以下是此前对话的摘要,请据此继续]\n${summary}`,
|
|
70
|
+
};
|
|
71
|
+
const after = estimatePromptTokens([system, summaryMessage]);
|
|
72
|
+
// 压缩后没有更小(历史本就很短)→ 不替换,避免反而增大上下文
|
|
73
|
+
if (after >= before)
|
|
74
|
+
return { status: 'no-benefit', before };
|
|
75
|
+
history.length = 0;
|
|
76
|
+
history.push(system, summaryMessage);
|
|
77
|
+
resetStats(stats);
|
|
78
|
+
return { status: 'ok', before, after };
|
|
79
|
+
}
|
|
80
|
+
/** 打印压缩结果(成功时报告节省比例)。 */
|
|
81
|
+
function printCompactResult(result) {
|
|
82
|
+
switch (result.status) {
|
|
83
|
+
case 'ok': {
|
|
84
|
+
const saved = Math.round((1 - result.after / result.before) * 100);
|
|
85
|
+
console.log(`\n\n已压缩上下文:约 ${result.before.toLocaleString()} → ${result.after.toLocaleString()} tokens(节省 ${saved}%)。`);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'no-benefit':
|
|
89
|
+
console.log('\n\n当前历史已足够精简,压缩不会减少上下文(历史未改动)。');
|
|
90
|
+
break;
|
|
91
|
+
case 'failed':
|
|
92
|
+
console.log(`\n压缩失败:${result.message}(历史未改动)`);
|
|
93
|
+
break;
|
|
94
|
+
case 'empty':
|
|
95
|
+
console.log('没有可压缩的对话历史。');
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* /compact:手动压缩当前对话历史。
|
|
101
|
+
* 占比很低时先确认(压了会白白损失细节),确认后走压缩核心。
|
|
102
|
+
*/
|
|
103
|
+
export async function handleCompact(ctx) {
|
|
104
|
+
if (ctx.history.length <= 1) {
|
|
105
|
+
console.log('没有可压缩的对话历史。');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// 上下文占比很低时,压缩通常没必要且会损失细节 —— 先向用户确认
|
|
109
|
+
const before = estimatePromptTokens(ctx.history);
|
|
110
|
+
const limit = getContextLimit(ctx.ai.getModel());
|
|
111
|
+
const ratio = limit > 0 ? before / limit : 0;
|
|
112
|
+
if (ratio < COMPACT_MIN_RATIO) {
|
|
113
|
+
const pct = (ratio * 100).toFixed(1);
|
|
114
|
+
console.log(`当前上下文仅占 ${pct}%(约 ${before.toLocaleString()} / ${limit.toLocaleString()} tokens),` +
|
|
115
|
+
`压缩通常在接近上限时才有必要,且会损失细节。`);
|
|
116
|
+
const ok = await ctx.confirm('仍要压缩?');
|
|
117
|
+
if (!ok) {
|
|
118
|
+
console.log('已取消。');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
printCompactResult(await compactHistory(ctx.ai, ctx.history, ctx.stats));
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 自动压缩:每轮对话后调用。上下文占比达到 AUTO_COMPACT_RATIO 就自动压缩,
|
|
126
|
+
* 只提示、不弹确认(保护性操作;要手动控制用 /compact)。
|
|
127
|
+
*/
|
|
128
|
+
export async function autoCompactIfNeeded(ai, history, stats) {
|
|
129
|
+
if (history.length <= 1)
|
|
130
|
+
return;
|
|
131
|
+
const tokens = estimatePromptTokens(history);
|
|
132
|
+
const limit = getContextLimit(ai.getModel());
|
|
133
|
+
const ratio = limit > 0 ? tokens / limit : 0;
|
|
134
|
+
if (ratio < AUTO_COMPACT_RATIO)
|
|
135
|
+
return;
|
|
136
|
+
console.log(`\n⚠ 上下文已达 ${(ratio * 100).toFixed(0)}%(约 ${tokens.toLocaleString()} / ${limit.toLocaleString()} tokens),正在自动压缩…`);
|
|
137
|
+
printCompactResult(await compactHistory(ai, history, stats));
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=compact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/compact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { runAgentTurn } from '../../run/index.js';
|
|
2
|
+
import { getTool } from '../../../tools/index.js';
|
|
3
|
+
import { buildPlan, EXECUTION_SYSTEM_PROMPT, makeConfirm, PlanTracker, } from './agent.js';
|
|
4
|
+
/** 目标未给完成条件时,让规划阶段先补一条可检查条件。 */
|
|
5
|
+
const GOAL_PLANNING_SYSTEM_PROMPT = `你是 CCLI 的 Goal 规划助手。
|
|
6
|
+
|
|
7
|
+
用户会给出一个目标,但不会明确写出完成条件。你需要:
|
|
8
|
+
1. 先补一条明确、可检查的完成条件,写在一行里,格式必须是:完成条件:<内容>。
|
|
9
|
+
2. 再输出编号计划,每一步说明要做什么、准备调用哪个工具。
|
|
10
|
+
3. 只输出完成条件和计划,不要调用任何工具。
|
|
11
|
+
4. 完成条件要可验证,例如“某个文件存在且包含某内容”“某条命令测试通过”。`;
|
|
12
|
+
/** 解析 /goal 参数,格式:`<任务> [| <完成条件>]`。 */
|
|
13
|
+
export function parseGoalArg(arg) {
|
|
14
|
+
const idx = arg.indexOf('|');
|
|
15
|
+
if (idx < 0) {
|
|
16
|
+
const task = arg.trim();
|
|
17
|
+
return task ? { task, done: null } : null;
|
|
18
|
+
}
|
|
19
|
+
const task = arg.slice(0, idx).trim();
|
|
20
|
+
const done = arg.slice(idx + 1).trim();
|
|
21
|
+
if (!task)
|
|
22
|
+
return null;
|
|
23
|
+
return { task, done: done || null };
|
|
24
|
+
}
|
|
25
|
+
/** 从 Goal 规划结果中拆出完成条件和编号计划。 */
|
|
26
|
+
export function parseGoalPlan(plan) {
|
|
27
|
+
const lines = plan.split('\n');
|
|
28
|
+
const rest = [];
|
|
29
|
+
let done = '';
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
const trimmed = line.trim();
|
|
32
|
+
if (!done && /^完成条件[::]\s*/.test(trimmed)) {
|
|
33
|
+
done = trimmed.replace(/^完成条件[::]\s*/, '').trim();
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
rest.push(line);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
done: done || '完成用户目标,并给出清晰的结果总结。',
|
|
40
|
+
plan: rest.join('\n').trim() || plan.trim(),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** 截断过长的工具结果,便于在终端阅读。 */
|
|
44
|
+
function truncateResult(result, max = 300) {
|
|
45
|
+
if (result.length <= max)
|
|
46
|
+
return result;
|
|
47
|
+
return result.slice(0, max) + '\n...(结果已截断)';
|
|
48
|
+
}
|
|
49
|
+
/** 把工具调用格式化成易读的摘要。 */
|
|
50
|
+
function formatToolCall(tc) {
|
|
51
|
+
const tool = getTool(tc.name);
|
|
52
|
+
if (tool?.preview) {
|
|
53
|
+
try {
|
|
54
|
+
return tool.preview(JSON.parse(tc.arguments || '{}'));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// 预览解析失败时降级为原始参数
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return `${tc.name}(${tc.arguments})`;
|
|
61
|
+
}
|
|
62
|
+
function buildGoalUserContent(task, done) {
|
|
63
|
+
return `${task}\n\n完成条件:${done}`;
|
|
64
|
+
}
|
|
65
|
+
/** 执行结束后,根据完成条件做一次达成判定。 */
|
|
66
|
+
async function evaluateGoal(task, done, ctx) {
|
|
67
|
+
const prompt = `请基于上面的执行过程与结果,判定目标是否达成。
|
|
68
|
+
|
|
69
|
+
目标:${task}
|
|
70
|
+
完成条件:${done}
|
|
71
|
+
|
|
72
|
+
只输出两行:
|
|
73
|
+
第一行写“达成”或“未达成”;
|
|
74
|
+
第二行写原因和下一步建议。`;
|
|
75
|
+
const evalHistory = [
|
|
76
|
+
...ctx.history,
|
|
77
|
+
{ role: 'user', content: prompt },
|
|
78
|
+
];
|
|
79
|
+
console.log('\n[Goal] 正在判定完成条件...');
|
|
80
|
+
let verdict = '';
|
|
81
|
+
const turn = await ctx.ai.chat(evalHistory, (delta) => {
|
|
82
|
+
verdict += delta;
|
|
83
|
+
process.stdout.write(delta);
|
|
84
|
+
}, { disableTools: true });
|
|
85
|
+
verdict = (turn.content || verdict).trim();
|
|
86
|
+
ctx.history.push({ role: 'user', content: prompt });
|
|
87
|
+
ctx.history.push({ role: 'assistant', content: verdict });
|
|
88
|
+
}
|
|
89
|
+
/** /goal:目标执行模式,完成条件可省略。 */
|
|
90
|
+
export async function handleGoal(arg, ctx) {
|
|
91
|
+
const parsed = parseGoalArg(arg);
|
|
92
|
+
if (!parsed) {
|
|
93
|
+
console.log('用法:/goal <任务> [| <完成条件>]');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const { task } = parsed;
|
|
97
|
+
let { done } = parsed;
|
|
98
|
+
console.log(`[Goal] 目标:${task}`);
|
|
99
|
+
console.log(`[Goal] 完成条件:${done ?? '待规划阶段补全'}`);
|
|
100
|
+
console.log('\n[Goal] 开始制定计划...\n');
|
|
101
|
+
const rawPlan = done
|
|
102
|
+
? await buildPlan(buildGoalUserContent(task, done), ctx)
|
|
103
|
+
: await buildPlan(task, ctx, GOAL_PLANNING_SYSTEM_PROMPT);
|
|
104
|
+
if (!rawPlan) {
|
|
105
|
+
console.log('\n[Goal] 未能生成计划。');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
let plan = rawPlan;
|
|
109
|
+
if (!done) {
|
|
110
|
+
const parsedPlan = parseGoalPlan(rawPlan);
|
|
111
|
+
done = parsedPlan.done;
|
|
112
|
+
plan = parsedPlan.plan;
|
|
113
|
+
}
|
|
114
|
+
const goalContent = buildGoalUserContent(task, done);
|
|
115
|
+
console.log('\n\n[Goal] 完成条件:');
|
|
116
|
+
console.log(done);
|
|
117
|
+
console.log('\n[Goal] 计划如下:');
|
|
118
|
+
console.log(plan);
|
|
119
|
+
const answer = (await ctx.ask('\n是否按此计划执行?(y/N) '))
|
|
120
|
+
.trim()
|
|
121
|
+
.toLowerCase();
|
|
122
|
+
if (answer !== 'y' && answer !== 'yes') {
|
|
123
|
+
console.log('[Goal] 已取消执行。');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
console.log('\n[Goal] 开始执行计划...');
|
|
127
|
+
const tracker = new PlanTracker(plan);
|
|
128
|
+
if (tracker.hasSteps()) {
|
|
129
|
+
tracker.printState();
|
|
130
|
+
}
|
|
131
|
+
ctx.history[0].content = `${EXECUTION_SYSTEM_PROMPT}\n\n目标完成条件:${done}\n\n已批准的计划:\n${plan}`;
|
|
132
|
+
ctx.history.push({ role: 'user', content: goalContent });
|
|
133
|
+
await runAgentTurn({
|
|
134
|
+
ai: ctx.ai,
|
|
135
|
+
history: ctx.history,
|
|
136
|
+
confirm: makeConfirm(ctx),
|
|
137
|
+
stats: ctx.stats,
|
|
138
|
+
maxRounds: 30,
|
|
139
|
+
requireToolsFirstRound: true,
|
|
140
|
+
onToolCall: (tc) => {
|
|
141
|
+
if (tracker.hasSteps()) {
|
|
142
|
+
tracker.printCurrent();
|
|
143
|
+
}
|
|
144
|
+
console.log(`\n[Goal] 调用 ${tc.name}`);
|
|
145
|
+
console.log(formatToolCall(tc));
|
|
146
|
+
},
|
|
147
|
+
onToolResult: (tc, result) => {
|
|
148
|
+
console.log(`\n[Goal] ${tc.name} 结果:`);
|
|
149
|
+
console.log(truncateResult(result));
|
|
150
|
+
if (tracker.hasSteps()) {
|
|
151
|
+
tracker.advance();
|
|
152
|
+
tracker.printState();
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
await evaluateGoal(task, done, ctx);
|
|
157
|
+
console.log('\n[Goal] 目标执行结束');
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=goal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/goal.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,14 @@ export const COMMANDS = [
|
|
|
3
3
|
['/help', '列出所有命令'],
|
|
4
4
|
['/clear', '清空对话历史(保留系统提示)'],
|
|
5
5
|
['/undo [n]', '撤销最近 n 轮对话(默认 1)'],
|
|
6
|
+
['/compact', '把对话历史压缩成摘要,释放上下文'],
|
|
6
7
|
['/model [id]', '查看或切换模型'],
|
|
7
8
|
['/save [name]', '保存当前对话(省略名称自动生成)'],
|
|
8
9
|
['/load <name>', '加载会话;不完整时列出候选'],
|
|
9
10
|
['/sessions', '列出已保存的会话'],
|
|
10
11
|
['/delete <name>', '删除指定会话(需确认)'],
|
|
11
12
|
['/agent <task>', '进入自动任务执行模式'],
|
|
13
|
+
['/goal <task> [| <条件>]', '目标执行模式,完成条件可省略'],
|
|
12
14
|
['/stats', '查看本次会话 token 统计'],
|
|
13
15
|
['/resume', '恢复上次自动保存的会话'],
|
|
14
16
|
['/reload', '重新加载 .ccli/config.json 并刷新 MCP server'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/help.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,CAAC,MAAM,QAAQ,GAA4B;IAC7C,CAAC,OAAO,EAAE,QAAQ,CAAC;IACnB,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAC5B,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACjC,CAAC,aAAa,EAAE,SAAS,CAAC;IAC1B,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACpC,CAAC,cAAc,EAAE,eAAe,CAAC;IACjC,CAAC,WAAW,EAAE,UAAU,CAAC;IACzB,CAAC,gBAAgB,EAAE,aAAa,CAAC;IACjC,CAAC,eAAe,EAAE,YAAY,CAAC;IAC/B,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IAC7B,CAAC,SAAS,EAAE,aAAa,CAAC;IAC1B,CAAC,SAAS,EAAE,uCAAuC,CAAC;IACpD,CAAC,mBAAmB,EAAE,uCAAuC,CAAC;IAC9D,CAAC,cAAc,EAAE,cAAc,CAAC;IAChC,CAAC,cAAc,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,UAAU,SAAS;IACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/help.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,CAAC,MAAM,QAAQ,GAA4B;IAC7C,CAAC,OAAO,EAAE,QAAQ,CAAC;IACnB,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAC5B,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACjC,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAChC,CAAC,aAAa,EAAE,SAAS,CAAC;IAC1B,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACpC,CAAC,cAAc,EAAE,eAAe,CAAC;IACjC,CAAC,WAAW,EAAE,UAAU,CAAC;IACzB,CAAC,gBAAgB,EAAE,aAAa,CAAC;IACjC,CAAC,eAAe,EAAE,YAAY,CAAC;IAC/B,CAAC,uBAAuB,EAAE,gBAAgB,CAAC;IAC3C,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IAC7B,CAAC,SAAS,EAAE,aAAa,CAAC;IAC1B,CAAC,SAAS,EAAE,uCAAuC,CAAC;IACpD,CAAC,mBAAmB,EAAE,uCAAuC,CAAC;IAC9D,CAAC,cAAc,EAAE,cAAc,CAAC;IAChC,CAAC,cAAc,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,UAAU,SAAS;IACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACL,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ import { loadEnvFile } from './config/env.js';
|
|
|
20
20
|
import { createAIClient } from './agent/ai.js';
|
|
21
21
|
import { McpClientManager } from './agent/mcp.js';
|
|
22
22
|
import { runOnce } from './cli/run/index.js';
|
|
23
|
+
import { injectFileReferences } from './cli/file-reference.js';
|
|
23
24
|
const HELP = `${NAME} v${VERSION}
|
|
24
25
|
|
|
25
26
|
用法:
|
|
@@ -84,7 +85,7 @@ async function main() {
|
|
|
84
85
|
}
|
|
85
86
|
const promptFromArgs = args.positionals.join(' ').trim();
|
|
86
87
|
const stdinText = (await readStdin()).trim();
|
|
87
|
-
const prompt = buildPrompt(promptFromArgs, stdinText);
|
|
88
|
+
const prompt = injectFileReferences(buildPrompt(promptFromArgs, stdinText), process.cwd());
|
|
88
89
|
// 有 prompt 或 stdin 时,走非交互式单次调用
|
|
89
90
|
if (prompt) {
|
|
90
91
|
const result = loadConfig();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EACH,WAAW,EACX,UAAU,EACV,aAAa,EACb,qBAAqB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|