@gird/ccli 2.10.0 → 2.12.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 +5 -1
- package/dist/agent/ai.js +18 -4
- package/dist/agent/ai.js.map +1 -1
- package/dist/cli/confirm-select.js +123 -0
- package/dist/cli/confirm-select.js.map +1 -1
- package/dist/cli/repl/index.js +34 -6
- package/dist/cli/repl/index.js.map +1 -1
- package/dist/cli/run/fold.js +48 -0
- package/dist/cli/run/fold.js.map +1 -0
- package/dist/cli/run/format.js +278 -0
- package/dist/cli/run/format.js.map +1 -0
- package/dist/cli/run/index.js +102 -15
- package/dist/cli/run/index.js.map +1 -1
- package/dist/cli/run/permissions.js +98 -0
- package/dist/cli/run/permissions.js.map +1 -0
- package/dist/cli/run/stream-write.js +146 -0
- package/dist/cli/run/stream-write.js.map +1 -0
- package/dist/cli/slash/system/agent.js +1 -1
- package/dist/cli/slash/system/agent.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/bash-background.js +128 -0
- package/dist/tools/bash-background.js.map +1 -0
- package/dist/tools/bash-output.js +45 -0
- package/dist/tools/bash-output.js.map +1 -0
- package/dist/tools/bash.js +15 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/index.js +6 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/kill-bash.js +41 -0
- package/dist/tools/kill-bash.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* write_file 工具 content 字段的增量解码(供流式渲染)。
|
|
3
|
+
*
|
|
4
|
+
* 模型流式生成工具参数时,arguments 是一片片到达的「半截 JSON 字符串」,
|
|
5
|
+
* 不能 JSON.parse。这里针对 write_file 的 {"path":"...","content":"..."} 结构
|
|
6
|
+
* 做专用增量解码:每次 feed(累计 arguments) 都从头扫描,定位 content 字符串值,
|
|
7
|
+
* 解码出「当前能确定的最长前缀」,相对上次已解码的部分即为新增 delta。
|
|
8
|
+
*
|
|
9
|
+
* 只解 write_file,不通用;纯逻辑、可测。
|
|
10
|
+
*/
|
|
11
|
+
/** 解码一个 \ 开头的转义;返回解码字符与下一位置;转义未完(含 \u 不足 4 位)返回 undefined。 */
|
|
12
|
+
function escapeChar(args, i) {
|
|
13
|
+
const n = args[i + 1];
|
|
14
|
+
if (n === undefined)
|
|
15
|
+
return undefined;
|
|
16
|
+
switch (n) {
|
|
17
|
+
case 'n':
|
|
18
|
+
return { char: '\n', next: i + 2 };
|
|
19
|
+
case 'r':
|
|
20
|
+
return { char: '\r', next: i + 2 };
|
|
21
|
+
case 't':
|
|
22
|
+
return { char: '\t', next: i + 2 };
|
|
23
|
+
case 'b':
|
|
24
|
+
return { char: '\b', next: i + 2 };
|
|
25
|
+
case 'f':
|
|
26
|
+
return { char: '\f', next: i + 2 };
|
|
27
|
+
case '"':
|
|
28
|
+
return { char: '"', next: i + 2 };
|
|
29
|
+
case '\\':
|
|
30
|
+
return { char: '\\', next: i + 2 };
|
|
31
|
+
case '/':
|
|
32
|
+
return { char: '/', next: i + 2 };
|
|
33
|
+
case 'u': {
|
|
34
|
+
const hex = args.slice(i + 2, i + 6);
|
|
35
|
+
if (hex.length < 4 || !/^[0-9a-fA-F]{4}$/.test(hex))
|
|
36
|
+
return undefined;
|
|
37
|
+
return { char: String.fromCharCode(parseInt(hex, 16)), next: i + 6 };
|
|
38
|
+
}
|
|
39
|
+
default:
|
|
40
|
+
return { char: n, next: i + 2 };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** 从 args 中尽力解出一个 JSON 字符串字段的「完整值」;未完整返回 undefined。 */
|
|
44
|
+
function extractStringField(args, field) {
|
|
45
|
+
const key = `"${field}"`;
|
|
46
|
+
const k = args.indexOf(key);
|
|
47
|
+
if (k < 0)
|
|
48
|
+
return undefined;
|
|
49
|
+
let i = k + key.length;
|
|
50
|
+
while (i < args.length && (args[i] === ':' || /\s/.test(args[i])))
|
|
51
|
+
i++;
|
|
52
|
+
if (args[i] !== '"')
|
|
53
|
+
return undefined;
|
|
54
|
+
i++;
|
|
55
|
+
let out = '';
|
|
56
|
+
while (i < args.length) {
|
|
57
|
+
const ch = args[i];
|
|
58
|
+
if (ch === '\\') {
|
|
59
|
+
const r = escapeChar(args, i);
|
|
60
|
+
if (r === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
out += r.char;
|
|
63
|
+
i = r.next;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (ch === '"')
|
|
67
|
+
return out;
|
|
68
|
+
out += ch;
|
|
69
|
+
i++;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
/** 解码 content 字段的「当前最长可解码前缀」(允许未闭合)。 */
|
|
74
|
+
function decodeContentPrefix(args) {
|
|
75
|
+
const key = '"content"';
|
|
76
|
+
const k = args.indexOf(key);
|
|
77
|
+
if (k < 0)
|
|
78
|
+
return { started: false, ended: false, value: '' };
|
|
79
|
+
let i = k + key.length;
|
|
80
|
+
while (i < args.length && (args[i] === ':' || /\s/.test(args[i])))
|
|
81
|
+
i++;
|
|
82
|
+
if (args[i] !== '"')
|
|
83
|
+
return { started: false, ended: false, value: '' };
|
|
84
|
+
i++;
|
|
85
|
+
let out = '';
|
|
86
|
+
let ended = false;
|
|
87
|
+
while (i < args.length) {
|
|
88
|
+
const ch = args[i];
|
|
89
|
+
if (ch === '\\') {
|
|
90
|
+
const r = escapeChar(args, i);
|
|
91
|
+
if (r === undefined)
|
|
92
|
+
break; // 转义未完 → 停,等下一片
|
|
93
|
+
out += r.char;
|
|
94
|
+
i = r.next;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (ch === '"') {
|
|
98
|
+
ended = true;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
out += ch;
|
|
102
|
+
i++;
|
|
103
|
+
}
|
|
104
|
+
return { started: true, ended, value: out };
|
|
105
|
+
}
|
|
106
|
+
export class WriteContentStreamer {
|
|
107
|
+
decoded = '';
|
|
108
|
+
started = false;
|
|
109
|
+
ended = false;
|
|
110
|
+
path;
|
|
111
|
+
/** 喂入「截至目前的累计 arguments 字符串」,返回新增解码结果。 */
|
|
112
|
+
feed(argsSoFar) {
|
|
113
|
+
if (this.path === undefined) {
|
|
114
|
+
this.path = extractStringField(argsSoFar, 'path');
|
|
115
|
+
}
|
|
116
|
+
if (!this.started) {
|
|
117
|
+
const r = decodeContentPrefix(argsSoFar);
|
|
118
|
+
if (!r.started) {
|
|
119
|
+
return {
|
|
120
|
+
delta: '',
|
|
121
|
+
started: false,
|
|
122
|
+
ended: false,
|
|
123
|
+
path: this.path,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
this.started = true;
|
|
127
|
+
this.decoded = r.value;
|
|
128
|
+
this.ended = r.ended;
|
|
129
|
+
return {
|
|
130
|
+
delta: r.value,
|
|
131
|
+
started: true,
|
|
132
|
+
ended: r.ended,
|
|
133
|
+
path: this.path,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (this.ended) {
|
|
137
|
+
return { delta: '', started: true, ended: true, path: this.path };
|
|
138
|
+
}
|
|
139
|
+
const r = decodeContentPrefix(argsSoFar);
|
|
140
|
+
const delta = r.value.slice(this.decoded.length);
|
|
141
|
+
this.decoded = r.value;
|
|
142
|
+
this.ended = r.ended;
|
|
143
|
+
return { delta, started: true, ended: r.ended, path: this.path };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=stream-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-write.js","sourceRoot":"","sources":["../../../src/cli/run/stream-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -129,7 +129,7 @@ export function makeConfirm(ctx) {
|
|
|
129
129
|
return async (preview) => {
|
|
130
130
|
console.log('\n' + preview);
|
|
131
131
|
const answer = (await ctx.ask('确认执行?(y/N) ')).trim().toLowerCase();
|
|
132
|
-
return answer === 'y' || answer === 'yes';
|
|
132
|
+
return answer === 'y' || answer === 'yes' ? 'yes' : 'no';
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
/** /agent:先制定计划,确认后自动执行。 */
|
|
@@ -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;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../src/cli/slash/system/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAIlD,6BAA6B;AAC7B,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;sBAgBT,CAAC;AAEvB,iCAAiC;AACjC,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;gCAUP,CAAC;AAEjC,oBAAoB;AACpB,MAAM,UAAU,cAAc,CAAC,IAAY;IACvC,OAAO,IAAI;SACN,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC/C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,4BAA4B;AAC5B,MAAM,OAAO,WAAW;IACZ,KAAK,CAAW;IAChB,SAAS,GAAG,CAAC,CAAC;IAEtB,YAAY,IAAY;QACpB,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,KAAK;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,mBAAmB;IACnB,YAAY;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,gBAAgB;IAChB,SAAS;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC;QAC3B,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;QACzE,CAAC;IACL,CAAC;IAED,gBAAgB;IAChB,UAAU;QACN,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,MAAc,CAAC;YACnB,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;gBACrB,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC9B,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;IACL,CAAC;IAED,iBAAiB;IACjB,OAAO;QACH,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ;AAED,yBAAyB;AACzB,SAAS,cAAc,CAAC,MAAc,EAAE,GAAG,GAAG,GAAG;IAC7C,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,MAAM,CAAC;IACxC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,cAAc,CAAC;AACjD,CAAC;AAED,sBAAsB;AACtB,SAAS,cAAc,CAAC,EAAY;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC;QAChB,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACL,iBAAiB;QACrB,CAAC;IACL,CAAC;IACD,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,GAAG,CAAC;AACzC,CAAC;AAED,0BAA0B;AAC1B,MAAM,CAAC,KAAK,UAAU,SAAS,CAC3B,IAAY,EACZ,GAAiB,EACjB,eAAuB,sBAAsB;IAE7C,MAAM,eAAe,GAAmD;QACpE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;QACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;KAClC,CAAC;IAEF,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAC1B,eAAe,EACf,CAAC,KAAK,EAAE,EAAE;QACN,IAAI,IAAI,KAAK,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,EACD,EAAE,YAAY,EAAE,IAAI,EAAE,CACzB,CAAC;IACF,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;IAC5B,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,WAAW,CAAC,GAAiB;IACzC,OAAO,KAAK,EAAE,OAAe,EAA0B,EAAE;QACrD,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACnE,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,CAAC,CAAC;AACN,CAAC;AAED,4BAA4B;AAC5B,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,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,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC7C,OAAO;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,IAAI,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,OAAO;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClB,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;SAC9C,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;IACnB,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,OAAO;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAEhD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,UAAU,EAAE,CAAC;IACzB,CAAC;IAED,sBAAsB;IACtB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,uBAAuB,gBAAgB,IAAI,EAAE,CAAC;IAC1E,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAElD,MAAM,YAAY,CAAC;QACf,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC;QACzB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,SAAS,EAAE,EAAE;QACb,sBAAsB,EAAE,IAAI;QAC5B,UAAU,EAAE,CAAC,EAAY,EAAE,EAAE;YACzB,IAAI,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACrB,OAAO,CAAC,YAAY,EAAE,CAAC;YAC3B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,YAAY,EAAE,CAAC,EAAY,EAAE,MAAc,EAAE,EAAE;YAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;YACpC,IAAI,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACrB,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,UAAU,EAAE,CAAC;YACzB,CAAC;QACL,CAAC;KACJ,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -120,10 +120,10 @@ async function main() {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
const confirm = args.yes
|
|
123
|
-
? () => Promise.resolve(
|
|
123
|
+
? () => Promise.resolve('yes')
|
|
124
124
|
: async (preview) => {
|
|
125
125
|
console.error(style.warn(`\n[非交互式模式] 需要确认以下操作,请添加 --yes 自动批准:\n${preview}`));
|
|
126
|
-
return
|
|
126
|
+
return 'no';
|
|
127
127
|
};
|
|
128
128
|
try {
|
|
129
129
|
await runOnce({
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 后台 bash 进程管理。
|
|
3
|
+
*
|
|
4
|
+
* 普通 bash 工具同步等待命令结束;长跑进程(dev server / watch / MCP server)
|
|
5
|
+
* 会因此卡住,直到超时被杀。这里把进程放到后台:spawn 后立即返回一个 id,
|
|
6
|
+
* 调用方可继续做事,随时用 bash_output 读取累计输出、查状态,用 kill_bash
|
|
7
|
+
* 主动终止。
|
|
8
|
+
*
|
|
9
|
+
* 进程表驻留在模块内存里,随进程退出而清空(不持久化)。
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from 'node:child_process';
|
|
12
|
+
/** 单个进程 stdout/stderr 各自保留的尾部上限,避免长跑输出撑爆内存。 */
|
|
13
|
+
const MAX_BUF = 30_000;
|
|
14
|
+
/** 被信号终止时换算成的退出码(shell 惯例:128 + 信号序号)。 */
|
|
15
|
+
const SIGNAL_EXIT = {
|
|
16
|
+
SIGINT: 130,
|
|
17
|
+
SIGTERM: 143,
|
|
18
|
+
SIGKILL: 137,
|
|
19
|
+
};
|
|
20
|
+
const processes = new Map();
|
|
21
|
+
let counter = 0;
|
|
22
|
+
function append(buf, chunk) {
|
|
23
|
+
const next = buf + chunk.toString();
|
|
24
|
+
// 只保留尾部:长跑进程最新输出在末尾最有价值。
|
|
25
|
+
return next.length > MAX_BUF ? next.slice(-MAX_BUF) : next;
|
|
26
|
+
}
|
|
27
|
+
function toInfo(p) {
|
|
28
|
+
return {
|
|
29
|
+
id: p.id,
|
|
30
|
+
command: p.command,
|
|
31
|
+
status: p.status,
|
|
32
|
+
exitCode: p.exitCode,
|
|
33
|
+
stdout: p.stdout,
|
|
34
|
+
stderr: p.stderr,
|
|
35
|
+
startedAt: p.startedAt,
|
|
36
|
+
endedAt: p.endedAt,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** 后台启动一条命令,立即返回进程快照(不等待结束)。 */
|
|
40
|
+
export function startBackground(command) {
|
|
41
|
+
const id = `bg_${++counter}`;
|
|
42
|
+
const shell = process.env.SHELL || '/bin/bash';
|
|
43
|
+
const child = spawn(shell, ['-c', command], {
|
|
44
|
+
cwd: process.cwd(),
|
|
45
|
+
env: process.env,
|
|
46
|
+
});
|
|
47
|
+
const proc = {
|
|
48
|
+
id,
|
|
49
|
+
command,
|
|
50
|
+
status: 'running',
|
|
51
|
+
exitCode: null,
|
|
52
|
+
stdout: '',
|
|
53
|
+
stderr: '',
|
|
54
|
+
startedAt: Date.now(),
|
|
55
|
+
endedAt: null,
|
|
56
|
+
child,
|
|
57
|
+
};
|
|
58
|
+
processes.set(id, proc);
|
|
59
|
+
child.stdout?.on('data', (d) => {
|
|
60
|
+
proc.stdout = append(proc.stdout, d);
|
|
61
|
+
});
|
|
62
|
+
child.stderr?.on('data', (d) => {
|
|
63
|
+
proc.stderr = append(proc.stderr, d);
|
|
64
|
+
});
|
|
65
|
+
child.on('error', () => {
|
|
66
|
+
proc.status = 'error';
|
|
67
|
+
proc.endedAt = Date.now();
|
|
68
|
+
});
|
|
69
|
+
child.on('close', (code, signal) => {
|
|
70
|
+
proc.status = 'done';
|
|
71
|
+
proc.exitCode = code ?? (signal ? SIGNAL_EXIT[signal] ?? null : null);
|
|
72
|
+
proc.endedAt = Date.now();
|
|
73
|
+
});
|
|
74
|
+
return toInfo(proc);
|
|
75
|
+
}
|
|
76
|
+
/** 取单个进程快照。 */
|
|
77
|
+
export function getBackground(id) {
|
|
78
|
+
const p = processes.get(id);
|
|
79
|
+
return p ? toInfo(p) : undefined;
|
|
80
|
+
}
|
|
81
|
+
/** 列出全部后台进程快照。 */
|
|
82
|
+
export function listBackground() {
|
|
83
|
+
return [...processes.values()].map(toInfo);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 终止指定后台进程:先发 SIGTERM 让其优雅退出,1 秒内仍未 close 再 SIGKILL 兜底。
|
|
87
|
+
* 返回 'killed'(已发信号)/ 'not_running'(已结束)/ 'not_found'(无此 id)。
|
|
88
|
+
*/
|
|
89
|
+
export function killBackground(id) {
|
|
90
|
+
const p = processes.get(id);
|
|
91
|
+
if (!p)
|
|
92
|
+
return 'not_found';
|
|
93
|
+
if (p.status !== 'running')
|
|
94
|
+
return 'not_running';
|
|
95
|
+
try {
|
|
96
|
+
p.child.kill('SIGTERM');
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return 'not_running';
|
|
100
|
+
}
|
|
101
|
+
const timer = setTimeout(() => {
|
|
102
|
+
if (p.status === 'running') {
|
|
103
|
+
try {
|
|
104
|
+
p.child.kill('SIGKILL');
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// 进程可能已退出,忽略。
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}, 1000);
|
|
111
|
+
// 不让兜底定时器单独阻止 Node 进程退出。
|
|
112
|
+
timer.unref?.();
|
|
113
|
+
return 'killed';
|
|
114
|
+
}
|
|
115
|
+
/** 仅供测试:杀掉所有后台进程并清空表,避免事件循环被句柄挂着不退出。 */
|
|
116
|
+
export function resetBackground() {
|
|
117
|
+
for (const p of processes.values()) {
|
|
118
|
+
try {
|
|
119
|
+
p.child.kill('SIGKILL');
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// 进程可能已退出,忽略。
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
processes.clear();
|
|
126
|
+
counter = 0;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=bash-background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-background.js","sourceRoot":"","sources":["../../src/tools/bash-background.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bash_output 工具 —— 读取后台 bash 进程的累计输出与状态。
|
|
3
|
+
*
|
|
4
|
+
* 配合 `bash` 的 background: true 使用:后台启动拿到 id 后,随时用本工具
|
|
5
|
+
* 查看进程还在不在跑、有没有退出码、目前累计的 stdout/stderr。
|
|
6
|
+
* 只读,无副作用,不需要用户确认。
|
|
7
|
+
*/
|
|
8
|
+
import { getBackground, listBackground } from './bash-background.js';
|
|
9
|
+
function formatDurationMs(ms) {
|
|
10
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
11
|
+
}
|
|
12
|
+
export const bashOutputTool = {
|
|
13
|
+
name: 'bash_output',
|
|
14
|
+
description: '查看后台 bash 进程的累计输出与状态。' +
|
|
15
|
+
'传入 bash 后台模式返回的 id;可反复调用以观察进展。' +
|
|
16
|
+
'只读操作,不会修改任何状态。',
|
|
17
|
+
parameters: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
id: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: '后台进程 id(bash background 模式返回的 bg_1 之类)',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ['id'],
|
|
26
|
+
},
|
|
27
|
+
async run({ id }) {
|
|
28
|
+
const proc = getBackground(String(id || ''));
|
|
29
|
+
if (!proc) {
|
|
30
|
+
const ids = listBackground()
|
|
31
|
+
.map((p) => p.id)
|
|
32
|
+
.join(', ');
|
|
33
|
+
return `错误:未找到后台进程 ${id}。当前后台进程:${ids || '(无)'}`;
|
|
34
|
+
}
|
|
35
|
+
const ended = proc.endedAt ?? Date.now();
|
|
36
|
+
const duration = formatDurationMs(ended - proc.startedAt);
|
|
37
|
+
const exitNote = proc.exitCode !== null ? `(退出码 ${proc.exitCode})` : '';
|
|
38
|
+
const combined = [proc.stdout, proc.stderr].filter(Boolean).join('\n');
|
|
39
|
+
const body = combined.trim() || '(暂无输出)';
|
|
40
|
+
return (`[${proc.id}] 状态:${proc.status}${exitNote} 运行:${duration}\n` +
|
|
41
|
+
`命令:${proc.command}\n` +
|
|
42
|
+
`--- 输出 ---\n${body}`);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=bash-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-output.js","sourceRoot":"","sources":["../../src/tools/bash-output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGrE,SAAS,gBAAgB,CAAC,EAAU;IAChC,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAS;IAChC,IAAI,EAAE,aAAa;IACnB,WAAW,EACP,uBAAuB;QACvB,gCAAgC;QAChC,gBAAgB;IACpB,UAAU,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,EAAE,EAAE;gBACA,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,wCAAwC;aACxD;SACJ;QACD,QAAQ,EAAE,CAAC,IAAI,CAAC;KACnB;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAkB;QAC5B,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,GAAG,GAAG,cAAc,EAAE;iBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChB,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,cAAc,EAAE,WAAW,GAAG,IAAI,KAAK,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC;QAEzC,OAAO,CACH,IAAI,IAAI,CAAC,EAAE,QAAQ,IAAI,CAAC,MAAM,GAAG,QAAQ,QAAQ,QAAQ,IAAI;YAC7D,MAAM,IAAI,CAAC,OAAO,IAAI;YACtB,eAAe,IAAI,EAAE,CACxB,CAAC;IACN,CAAC;CACJ,CAAC"}
|
package/dist/tools/bash.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import { startBackground } from './bash-background.js';
|
|
2
3
|
/** bash 默认超时 120s,最大 600s。 */
|
|
3
4
|
const BASH_DEFAULT_TIMEOUT = 120_000;
|
|
4
5
|
const BASH_MAX_TIMEOUT = 600_000;
|
|
@@ -8,7 +9,9 @@ export const bashTool = {
|
|
|
8
9
|
name: 'bash',
|
|
9
10
|
description: '在当前工作目录执行 shell 命令。用于运行测试、构建、git、安装依赖等。' +
|
|
10
11
|
'不要用它读写文件——请用 read_file / write_file。避免交互式命令。' +
|
|
11
|
-
'执行前会请用户确认。'
|
|
12
|
+
'执行前会请用户确认。' +
|
|
13
|
+
'设置 background: true 可在后台启动长跑进程(如 dev server),立即返回 id,' +
|
|
14
|
+
'之后用 bash_output 查看输出与状态。',
|
|
12
15
|
parameters: {
|
|
13
16
|
type: 'object',
|
|
14
17
|
properties: {
|
|
@@ -22,7 +25,11 @@ export const bashTool = {
|
|
|
22
25
|
},
|
|
23
26
|
timeout: {
|
|
24
27
|
type: 'integer',
|
|
25
|
-
description: `超时毫秒数(默认 ${BASH_DEFAULT_TIMEOUT},最大 ${BASH_MAX_TIMEOUT}
|
|
28
|
+
description: `超时毫秒数(默认 ${BASH_DEFAULT_TIMEOUT},最大 ${BASH_MAX_TIMEOUT};后台模式忽略)`,
|
|
29
|
+
},
|
|
30
|
+
background: {
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
description: '为 true 时在后台启动长跑进程并立即返回 id(默认 false,同步等待结束)',
|
|
26
33
|
},
|
|
27
34
|
},
|
|
28
35
|
required: ['command'],
|
|
@@ -34,10 +41,15 @@ export const bashTool = {
|
|
|
34
41
|
lines.push(`说明:${description}`);
|
|
35
42
|
return lines.join('\n');
|
|
36
43
|
},
|
|
37
|
-
async run({ command, timeout, }) {
|
|
44
|
+
async run({ command, timeout, background, }) {
|
|
38
45
|
const cmd = String(command || '');
|
|
39
46
|
if (!cmd)
|
|
40
47
|
return '错误:command 不能为空';
|
|
48
|
+
if (background) {
|
|
49
|
+
const proc = startBackground(cmd);
|
|
50
|
+
return (`已在后台启动(id: ${proc.id})。\n` +
|
|
51
|
+
`用 bash_output({"id":"${proc.id}"}) 查看输出与状态;长跑进程不会被超时终止。`);
|
|
52
|
+
}
|
|
41
53
|
const limit = Math.min(Math.max(1, timeout ?? BASH_DEFAULT_TIMEOUT), BASH_MAX_TIMEOUT);
|
|
42
54
|
const shell = process.env.SHELL || '/bin/bash';
|
|
43
55
|
return new Promise((resolve) => {
|
package/dist/tools/bash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* 模型据此决定「要不要调用、传什么参数」;我们负责真正执行并把结果回传。
|
|
6
6
|
*
|
|
7
7
|
* 工具分两类:
|
|
8
|
-
* 只读勘探(无副作用,直接放行):read_file / list_dir / grep
|
|
8
|
+
* 只读勘探(无副作用,直接放行):read_file / list_dir / grep / bash_output
|
|
9
9
|
* 有副作用(执行前需用户确认):write_file / edit_file / bash
|
|
10
10
|
*
|
|
11
11
|
* 此外,通过 MCP (Model Context Protocol) 接入的外部工具名以 `mcp__` 开头。
|
|
12
|
+
* 后台长跑进程由 bash(background:true) / bash_output / kill_bash 三件套管理。
|
|
12
13
|
*/
|
|
13
14
|
import { readFileTool } from './read-file.js';
|
|
14
15
|
import { listDirTool } from './list-dir.js';
|
|
@@ -16,6 +17,8 @@ import { grepTool } from './grep.js';
|
|
|
16
17
|
import { writeFileTool } from './write-file.js';
|
|
17
18
|
import { editFileTool } from './edit-file.js';
|
|
18
19
|
import { bashTool } from './bash.js';
|
|
20
|
+
import { bashOutputTool } from './bash-output.js';
|
|
21
|
+
import { killBashTool } from './kill-bash.js';
|
|
19
22
|
/** 内置工具集合。 */
|
|
20
23
|
const builtinTools = [
|
|
21
24
|
readFileTool,
|
|
@@ -24,6 +27,8 @@ const builtinTools = [
|
|
|
24
27
|
writeFileTool,
|
|
25
28
|
editFileTool,
|
|
26
29
|
bashTool,
|
|
30
|
+
bashOutputTool,
|
|
31
|
+
killBashTool,
|
|
27
32
|
];
|
|
28
33
|
/** 当前已注册的工具(内置 + MCP)。 */
|
|
29
34
|
let tools = [...builtinTools];
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9C,cAAc;AACd,MAAM,YAAY,GAAW;IACzB,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,YAAY;CACf,CAAC;AAEF,0BAA0B;AAC1B,IAAI,KAAK,GAAW,CAAC,GAAG,YAAY,CAAC,CAAC;AAEtC,8CAA8C;AAC9C,IAAI,UAAU,GAA4B,IAAI,CAAC;AAE/C,uBAAuB;AACvB,MAAM,UAAU,UAAU;IACtB,KAAK,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAC1B,UAAU,GAAG,IAAI,CAAC;AACtB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACvD,MAAM,MAAM,GAAG,QAAQ,UAAU,IAAI,CAAC;IACtC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,qBAAqB;IACjC,KAAK,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;AAC9B,CAAC;AAED,kCAAkC;AAClC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAyB;IAC5D,UAAU,GAAG,OAAO,CAAC;IACrB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,OAAO,GAAS;YAClB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,YAAY,EAAE,IAAI,EAAE,oBAAoB;YACxC,OAAO,EAAE,CAAC,IAAS,EAAE,EAAE;gBACnB,OAAO,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,YAAY,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YACtF,CAAC;YACD,GAAG,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE;gBACrB,IAAI,CAAC,UAAU,EAAE,CAAC;oBACd,OAAO,sBAAsB,CAAC;gBAClC,CAAC;gBACD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7D,CAAC;SACJ,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACL,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,OAAO,CAAC,IAAY;IAChC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,QAAQ;IACpB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrB,IAAI,EAAE,UAAmB;QACzB,QAAQ,EAAE;YACN,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,UAAU,EAAE,CAAC,CAAC,UAAU;SAC3B;KACJ,CAAC,CAAC,CAAC;AACR,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,IAAY,EACZ,QAAgB;IAEhB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,WAAW,IAAI,EAAE,CAAC;IAEpC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,kBAAkB,QAAQ,EAAE,CAAC;IACxC,CAAC;IAED,IAAI,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kill_bash 工具 —— 终止后台 bash 进程。
|
|
3
|
+
*
|
|
4
|
+
* 配合 `bash` 的 background: true 使用:后台启动拿到 id 后,可用本工具主动
|
|
5
|
+
* 结束长跑进程(dev server / watch 等)。先发 SIGTERM 让其优雅退出,1 秒内
|
|
6
|
+
* 仍未 close 再 SIGKILL 兜底。终止本会话自己启动的后台进程,不需要用户确认。
|
|
7
|
+
*/
|
|
8
|
+
import { getBackground, killBackground, listBackground, } from './bash-background.js';
|
|
9
|
+
export const killBashTool = {
|
|
10
|
+
name: 'kill_bash',
|
|
11
|
+
description: '终止一个后台 bash 进程。传入 bash 后台模式返回的 id;' +
|
|
12
|
+
'先发送 SIGTERM,1 秒内未退出再 SIGKILL 兜底。' +
|
|
13
|
+
'进程已结束或 id 不存在时返回提示。',
|
|
14
|
+
parameters: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
id: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: '要终止的后台进程 id(bg_1 之类)',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
required: ['id'],
|
|
23
|
+
},
|
|
24
|
+
async run({ id }) {
|
|
25
|
+
const key = String(id || '');
|
|
26
|
+
const result = killBackground(key);
|
|
27
|
+
if (result === 'not_found') {
|
|
28
|
+
const ids = listBackground()
|
|
29
|
+
.map((p) => p.id)
|
|
30
|
+
.join(', ');
|
|
31
|
+
return `错误:未找到后台进程 ${key}。当前后台进程:${ids || '(无)'}`;
|
|
32
|
+
}
|
|
33
|
+
if (result === 'not_running') {
|
|
34
|
+
const proc = getBackground(key);
|
|
35
|
+
return `[${key}] 已不在运行(状态:${proc?.status ?? '未知'}),无需终止。`;
|
|
36
|
+
}
|
|
37
|
+
return (`已发送终止信号给 [${key}](先 SIGTERM,1 秒内未退出再 SIGKILL)。\n` +
|
|
38
|
+
`用 bash_output({"id":"${key}"}) 确认进程已退出。`);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=kill-bash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kill-bash.js","sourceRoot":"","sources":["../../src/tools/kill-bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,aAAa,EACb,cAAc,EACd,cAAc,GACjB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,CAAC,MAAM,YAAY,GAAS;IAC9B,IAAI,EAAE,WAAW;IACjB,WAAW,EACP,oCAAoC;QACpC,kCAAkC;QAClC,qBAAqB;IACzB,UAAU,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,EAAE,EAAE;gBACA,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sBAAsB;aACtC;SACJ;QACD,QAAQ,EAAE,CAAC,IAAI,CAAC;KACnB;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAkB;QAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAEnC,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,cAAc,EAAE;iBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChB,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,cAAc,GAAG,WAAW,GAAG,IAAI,KAAK,EAAE,CAAC;QACtD,CAAC;QACD,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAChC,OAAO,IAAI,GAAG,cAAc,IAAI,EAAE,MAAM,IAAI,IAAI,SAAS,CAAC;QAC9D,CAAC;QACD,OAAO,CACH,aAAa,GAAG,kCAAkC;YAClD,wBAAwB,GAAG,cAAc,CAC5C,CAAC;IACN,CAAC;CACJ,CAAC"}
|