@aipack-ai/cli 1.1.5 → 1.1.6
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 +16 -3
- package/dist/bin.js +1 -1
- package/dist/{chunk-CERFOZ2L.js → chunk-EU2GJHTO.js} +416 -182
- package/dist/chunk-EU2GJHTO.js.map +1 -0
- package/dist/index.d.ts +35 -1
- package/dist/index.js +9 -1
- package/package.json +4 -4
- package/dist/chunk-CERFOZ2L.js.map +0 -1
|
@@ -5,7 +5,7 @@ import path from "path";
|
|
|
5
5
|
// package.json
|
|
6
6
|
var package_default = {
|
|
7
7
|
name: "@aipack-ai/cli",
|
|
8
|
-
version: "1.1.
|
|
8
|
+
version: "1.1.6",
|
|
9
9
|
description: "aipack CLI - \u57FA\u4E8E @aipack-ai/agent \u7684\u7EC8\u7AEF AI \u52A9\u624B",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "./dist/index.js",
|
|
@@ -69,6 +69,7 @@ function encodeDir(p) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// src/args.ts
|
|
72
|
+
import chalk from "chalk";
|
|
72
73
|
var VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "max"];
|
|
73
74
|
function isValidThinkingLevel(level) {
|
|
74
75
|
return VALID_THINKING_LEVELS.includes(level);
|
|
@@ -169,79 +170,82 @@ function parseArgs(args) {
|
|
|
169
170
|
return result;
|
|
170
171
|
}
|
|
171
172
|
function printHelp() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
${
|
|
176
|
-
|
|
177
|
-
${"\u5B50\u547D\u4EE4:"}
|
|
178
|
-
${APP_NAME} approvals list \u5217\u51FA\u672A\u51B3\u5BA1\u6279\u5355
|
|
179
|
-
${APP_NAME} approvals approve <id> \u6279\u51C6\u5BA1\u6279\u5355
|
|
180
|
-
${APP_NAME} approvals deny <id> \u9A73\u56DE\u5BA1\u6279\u5355
|
|
181
|
-
${APP_NAME} --list-models [\u641C\u7D22] \u5217\u51FA\u53EF\u7528\u6A21\u578B
|
|
182
|
-
|
|
183
|
-
${"\u6A21\u5F0F:"}
|
|
184
|
-
(\u9ED8\u8BA4) \u4EA4\u4E92\u6A21\u5F0F\uFF08REPL\uFF09
|
|
185
|
-
--print, -p [\u6D88\u606F] \u975E\u4EA4\u4E92\uFF1A\u5904\u7406\u4E00\u6B21\u63D0\u793A\u540E\u9000\u51FA\uFF08\u652F\u6301\u7BA1\u9053 stdin\uFF09
|
|
186
|
-
--mode json \u4EE5 JSON \u884C\u8F93\u51FA\u5168\u90E8\u6D41\u5F0F\u4E8B\u4EF6
|
|
187
|
-
|
|
188
|
-
${"\u6A21\u578B\u9009\u9879:"}
|
|
189
|
-
--provider <\u540D\u79F0> \u63D0\u4F9B\u5546\uFF08openai/deepseek/anthropic/google...\uFF09
|
|
190
|
-
--model <id> \u6A21\u578B ID\uFF0C\u652F\u6301 provider/id \u7EC4\u5408\u5199\u6CD5
|
|
191
|
-
--api-key <key> API Key\uFF08\u8986\u76D6\u73AF\u5883\u53D8\u91CF\uFF09
|
|
192
|
-
--thinking <\u7EA7\u522B> \u601D\u8003\u7EA7\u522B: off/minimal/low/medium/high/max
|
|
173
|
+
const c = chalk;
|
|
174
|
+
const title = c.bold.cyan(`${APP_NAME} ${VERSION}`);
|
|
175
|
+
const head = (s) => c.bold.magenta(s);
|
|
176
|
+
const opt = (flag, desc) => ` ${c.green(flag.padEnd(28))} ${c.dim(desc)}`;
|
|
177
|
+
console.log(`${title} ${c.dim("\xB7 \u7EC8\u7AEF AI \u7F16\u7A0B\u52A9\u624B")}
|
|
193
178
|
|
|
194
|
-
${"\
|
|
195
|
-
|
|
196
|
-
--resume, -r \u6D4F\u89C8\u5E76\u9009\u62E9\u5386\u53F2\u4F1A\u8BDD
|
|
197
|
-
--session <\u540D\u79F0> \u4F7F\u7528\u6307\u5B9A\u4F1A\u8BDD
|
|
198
|
-
--name, -n <\u540D\u79F0> \u4E3A\u65B0\u4F1A\u8BDD\u547D\u540D
|
|
199
|
-
--session-dir <\u76EE\u5F55> \u81EA\u5B9A\u4E49\u4F1A\u8BDD\u5B58\u50A8\u76EE\u5F55
|
|
200
|
-
--no-session \u4E34\u65F6\u4F1A\u8BDD\uFF08\u4E0D\u6301\u4E45\u5316\uFF09
|
|
179
|
+
${head("\u7528\u6CD5:")}
|
|
180
|
+
${c.cyan(APP_NAME)} ${c.dim("[\u9009\u9879]")} ${c.yellow("[@\u6587\u4EF6...]")} ${c.dim("[\u6D88\u606F...]")}
|
|
201
181
|
|
|
202
|
-
${"\
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
182
|
+
${head("\u5B50\u547D\u4EE4:")}
|
|
183
|
+
${opt("approvals list", "\u5217\u51FA\u672A\u51B3\u5BA1\u6279\u5355")}
|
|
184
|
+
${opt("approvals approve <id>", "\u6279\u51C6\u5BA1\u6279\u5355")}
|
|
185
|
+
${opt("approvals deny <id>", "\u9A73\u56DE\u5BA1\u6279\u5355")}
|
|
186
|
+
${opt("--list-models [\u641C\u7D22]", "\u5217\u51FA\u53EF\u7528\u6A21\u578B\uFF08\u6807\u6CE8 API Key \u914D\u7F6E\u72B6\u6001\uFF09")}
|
|
207
187
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
188
|
+
${head("\u6A21\u5F0F:")}
|
|
189
|
+
${opt("(\u9ED8\u8BA4)", "\u4EA4\u4E92\u6A21\u5F0F\uFF08REPL\uFF09\uFF0C\u652F\u6301\u659C\u6760\u547D\u4EE4\u4E0E\u591A\u884C\u8F93\u5165")}
|
|
190
|
+
${opt("--print, -p [\u6D88\u606F]", "\u975E\u4EA4\u4E92\uFF1A\u5904\u7406\u4E00\u6B21\u63D0\u793A\u540E\u9000\u51FA\uFF08\u652F\u6301\u7BA1\u9053 stdin\uFF09")}
|
|
191
|
+
${opt("--mode json", "\u4EE5 JSON \u884C\u8F93\u51FA\u5168\u90E8\u6D41\u5F0F\u4E8B\u4EF6")}
|
|
211
192
|
|
|
212
|
-
${"\
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
--help, -h \u663E\u793A\u5E2E\u52A9
|
|
218
|
-
--version, -v \u663E\u793A\u7248\u672C
|
|
193
|
+
${head("\u6A21\u578B\u9009\u9879:")}
|
|
194
|
+
${opt("--provider <\u540D\u79F0>", "\u63D0\u4F9B\u5546\uFF08openai/deepseek/anthropic/google...\uFF09")}
|
|
195
|
+
${opt("--model <id>", "\u6A21\u578B ID\uFF0C\u652F\u6301 provider/id \u7EC4\u5408\u5199\u6CD5")}
|
|
196
|
+
${opt("--api-key <key>", "API Key\uFF08\u8986\u76D6\u73AF\u5883\u53D8\u91CF\uFF09")}
|
|
197
|
+
${opt("--thinking <\u7EA7\u522B>", "\u601D\u8003\u7EA7\u522B: off/minimal/low/medium/high/max")}
|
|
219
198
|
|
|
220
|
-
${"\
|
|
221
|
-
|
|
222
|
-
|
|
199
|
+
${head("\u4F1A\u8BDD\u9009\u9879:")}
|
|
200
|
+
${opt("--continue, -c", "\u7EE7\u7EED\u5F53\u524D\u76EE\u5F55\u6700\u8FD1\u7684\u4F1A\u8BDD")}
|
|
201
|
+
${opt("--resume, -r", "\u6D4F\u89C8\u5E76\u9009\u62E9\u5386\u53F2\u4F1A\u8BDD")}
|
|
202
|
+
${opt("--session <\u540D\u79F0>", "\u4F7F\u7528\u6307\u5B9A\u4F1A\u8BDD")}
|
|
203
|
+
${opt("--name, -n <\u540D\u79F0>", "\u4E3A\u65B0\u4F1A\u8BDD\u547D\u540D")}
|
|
204
|
+
${opt("--session-dir <\u76EE\u5F55>", "\u81EA\u5B9A\u4E49\u4F1A\u8BDD\u5B58\u50A8\u76EE\u5F55")}
|
|
205
|
+
${opt("--no-session", "\u4E34\u65F6\u4F1A\u8BDD\uFF08\u4E0D\u6301\u4E45\u5316\uFF09")}
|
|
223
206
|
|
|
224
|
-
|
|
225
|
-
|
|
207
|
+
${head("\u5DE5\u5177\u4E0E\u6743\u9650:")}
|
|
208
|
+
${opt("--tools, -t <\u5217\u8868>", "\u5DE5\u5177\u767D\u540D\u5355\uFF08\u9017\u53F7\u5206\u9694\uFF09")}
|
|
209
|
+
${opt("--exclude-tools, -xt <\u5217\u8868>", "\u5DE5\u5177\u9ED1\u540D\u5355\uFF08\u9017\u53F7\u5206\u9694\uFF09")}
|
|
210
|
+
${opt("--no-tools, -nt", "\u7981\u7528\u5168\u90E8\u5DE5\u5177")}
|
|
211
|
+
${opt("--safe", "\u4FDD\u5B88\u6A21\u5F0F\uFF1A\u5199\u6587\u4EF6/shell \u5168\u90E8\u4EBA\u5DE5\u786E\u8BA4")}
|
|
226
212
|
|
|
227
|
-
|
|
228
|
-
${
|
|
213
|
+
${c.dim("\u5185\u7F6E\u5DE5\u5177:")} read \xB7 write \xB7 edit \xB7 bash \xB7 find \xB7 grep \xB7 ls
|
|
214
|
+
${c.dim("\u9ED8\u8BA4\u6743\u9650:")} \u8BFB/\u5199\u6587\u4EF6\u9759\u9ED8\u653E\u884C\uFF08\u5DE5\u4F5C\u533A\u8303\u56F4\uFF09\uFF1Bbash \u4EC5\u5371\u9669\u547D\u4EE4\u9700\u786E\u8BA4
|
|
215
|
+
${c.dim("\uFF08rm \u5220\u9664\u3001sudo\u3001\u78C1\u76D8\u5199\u5165\u3001\u8FDC\u7A0B\u811A\u672C\u7BA1\u9053\u7B49\uFF1B\u5371\u9669\u547D\u4EE4\u6BCF\u6B21\u91CD\u786E\u8BA4\uFF09")}
|
|
229
216
|
|
|
230
|
-
|
|
231
|
-
|
|
217
|
+
${head("\u4E0A\u4E0B\u6587\u538B\u7F29:")}
|
|
218
|
+
${opt("--no-compaction", "\u5173\u95ED\u4E0A\u4E0B\u6587\u538B\u7F29\uFF08\u957F\u4F1A\u8BDD\u53EF\u80FD\u6EA2\u51FA\uFF09")}
|
|
219
|
+
${opt("--compaction-config <\u6587\u4EF6>", "\u538B\u7F29\u914D\u7F6E JSON\uFF08\u8986\u76D6\u9ED8\u8BA4\u9608\u503C\uFF09")}
|
|
232
220
|
|
|
233
|
-
|
|
234
|
-
|
|
221
|
+
${head("\u5176\u4ED6:")}
|
|
222
|
+
${opt("--system-prompt <\u6587\u672C>", "\u66FF\u6362\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD")}
|
|
223
|
+
${opt("--append-system-prompt <\u6587\u672C>", "\u8FFD\u52A0\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u53EF\u591A\u6B21\uFF09")}
|
|
224
|
+
${opt("--help, -h", "\u663E\u793A\u672C\u5E2E\u52A9")}
|
|
225
|
+
${opt("--version, -v", "\u663E\u793A\u7248\u672C")}
|
|
235
226
|
|
|
236
|
-
|
|
237
|
-
${
|
|
227
|
+
${head("\u4EA4\u4E92\u6A21\u5F0F:")}
|
|
228
|
+
${c.dim("\xB7 \u591A\u884C\u8F93\u5165\uFF1A\u884C\u5C3E\u4EE5")} ${c.yellow("\\")} ${c.dim("\u7EED\u884C\uFF0C\u7A7A\u884C\u63D0\u4EA4")}
|
|
229
|
+
${c.dim("\xB7 \u659C\u6760\u547D\u4EE4\uFF1A/help /model /thinking /clear /compact /sessions /quit")}
|
|
230
|
+
${c.dim("\xB7 Ctrl+C \u4E2D\u65AD\u8FD0\u884C\uFF0C\u8FDE\u6309\u4E24\u6B21\u9000\u51FA")}
|
|
238
231
|
|
|
239
|
-
|
|
240
|
-
${
|
|
232
|
+
${head("\u793A\u4F8B:")}
|
|
233
|
+
${c.dim("# \u4EA4\u4E92\u6A21\u5F0F")}
|
|
234
|
+
${c.cyan(APP_NAME)}
|
|
235
|
+
${c.dim("# \u7BA1\u9053\u5355\u6B21\u63D0\u95EE")}
|
|
236
|
+
${c.yellow("cat README.md")} ${c.dim("|")} ${c.cyan(APP_NAME)} ${c.green("-p")} ${c.yellow('"\u603B\u7ED3\u8FD9\u6BB5\u6587\u672C"')}
|
|
237
|
+
${c.dim("# \u6307\u5B9A\u6A21\u578B\uFF08provider/id\uFF09")}
|
|
238
|
+
${c.cyan(APP_NAME)} ${c.green("--model")} ${c.yellow("deepseek/deepseek-chat")} ${c.yellow('"\u4F60\u597D"')}
|
|
239
|
+
${c.dim("# \u9644\u5E26\u6587\u4EF6\u4E0A\u4E0B\u6587\uFF08\u56FE\u7247\u8D70\u591A\u6A21\u6001\uFF09")}
|
|
240
|
+
${c.cyan(APP_NAME)} ${c.yellow("@package.json")} ${c.yellow('"\u5206\u6790\u4F9D\u8D56"')}
|
|
241
|
+
${c.dim("# \u7EE7\u7EED\u4E0A\u6B21\u4F1A\u8BDD")}
|
|
242
|
+
${c.cyan(APP_NAME)} ${c.green("-c")} ${c.yellow('"\u6211\u4EEC\u521A\u624D\u804A\u5230\u54EA\u91CC\u4E86\uFF1F"')}
|
|
243
|
+
${c.dim("# \u53EA\u8BFB\u5BA1\u67E5")}
|
|
244
|
+
${c.cyan(APP_NAME)} ${c.green("-t")} ${c.yellow("read,find,grep")} ${c.green("-p")} ${c.yellow('"\u5BA1\u67E5 src/"')}
|
|
241
245
|
|
|
242
|
-
${"\u73AF\u5883\u53D8\u91CF:"}
|
|
243
|
-
OPENAI_API_KEY / DEEPSEEK_API_KEY / ANTHROPIC_API_KEY / GOOGLE_API_KEY ...
|
|
244
|
-
AIPACK_CONFIG_DIR
|
|
246
|
+
${head("\u73AF\u5883\u53D8\u91CF:")}
|
|
247
|
+
${c.dim("OPENAI_API_KEY / DEEPSEEK_API_KEY / ANTHROPIC_API_KEY / GOOGLE_API_KEY ...")}
|
|
248
|
+
${c.dim("AIPACK_CONFIG_DIR")} ${c.dim("\u2192")} ${c.dim("\u914D\u7F6E\u76EE\u5F55\uFF08\u9ED8\u8BA4 ~/.aipack\uFF09")}
|
|
245
249
|
`);
|
|
246
250
|
}
|
|
247
251
|
|
|
@@ -702,13 +706,21 @@ function splitModelSpec(args) {
|
|
|
702
706
|
return { provider: args.provider, modelId: args.model };
|
|
703
707
|
}
|
|
704
708
|
function detectDefaultProvider() {
|
|
709
|
+
const PRIORITY = ["deepseek"];
|
|
710
|
+
for (const pid of PRIORITY) {
|
|
711
|
+
if (hasProviderConfigured(pid)) {
|
|
712
|
+
const models = getBuiltinModels(pid);
|
|
713
|
+
if (models.length > 0) return { id: pid, modelId: models[0].id };
|
|
714
|
+
}
|
|
715
|
+
}
|
|
705
716
|
for (const p of getBuiltinProviders()) {
|
|
717
|
+
if (PRIORITY.includes(p.id)) continue;
|
|
706
718
|
if (hasProviderConfigured(p.id)) {
|
|
707
719
|
const models = getBuiltinModels(p.id);
|
|
708
720
|
if (models.length > 0) return { id: p.id, modelId: models[0].id };
|
|
709
721
|
}
|
|
710
722
|
}
|
|
711
|
-
return { id: "
|
|
723
|
+
return { id: "deepseek", modelId: "deepseek-chat" };
|
|
712
724
|
}
|
|
713
725
|
function buildCustomModel(providerId, modelId) {
|
|
714
726
|
const meta = BUILTIN_PROVIDERS.find((p) => p.id === providerId);
|
|
@@ -945,11 +957,92 @@ ${stdinText.trim()}
|
|
|
945
957
|
return { text: parts.join("\n\n"), media };
|
|
946
958
|
}
|
|
947
959
|
|
|
948
|
-
// src/
|
|
960
|
+
// src/spinner.ts
|
|
949
961
|
import chalk2 from "chalk";
|
|
962
|
+
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
963
|
+
var INTERVAL_MS = 80;
|
|
964
|
+
var activeSpinner = null;
|
|
965
|
+
function pauseActiveSpinner() {
|
|
966
|
+
activeSpinner?.pause();
|
|
967
|
+
}
|
|
968
|
+
function resumeActiveSpinner() {
|
|
969
|
+
activeSpinner?.resume();
|
|
970
|
+
}
|
|
971
|
+
var Spinner = class {
|
|
972
|
+
timer = null;
|
|
973
|
+
frameIdx = 0;
|
|
974
|
+
prefix = "";
|
|
975
|
+
/** 是否处于暂停态(曾活动但被临时挂起) */
|
|
976
|
+
paused = false;
|
|
977
|
+
/** 是否正在旋转;非 TTY 下 start 永远不真正起效 */
|
|
978
|
+
get active() {
|
|
979
|
+
return this.timer !== null;
|
|
980
|
+
}
|
|
981
|
+
start(prefix) {
|
|
982
|
+
if (this.timer) this.stop();
|
|
983
|
+
if (!process.stdout.isTTY) return;
|
|
984
|
+
this.prefix = prefix;
|
|
985
|
+
this.frameIdx = 0;
|
|
986
|
+
this.paused = false;
|
|
987
|
+
activeSpinner = this;
|
|
988
|
+
this.render();
|
|
989
|
+
this.timer = setInterval(() => {
|
|
990
|
+
this.frameIdx = (this.frameIdx + 1) % FRAMES.length;
|
|
991
|
+
this.render();
|
|
992
|
+
}, INTERVAL_MS);
|
|
993
|
+
}
|
|
994
|
+
/** 中途切换前缀文本(如 tool_start → tool_end 之间) */
|
|
995
|
+
message(prefix) {
|
|
996
|
+
if (!this.timer) return;
|
|
997
|
+
this.prefix = prefix;
|
|
998
|
+
this.render();
|
|
999
|
+
}
|
|
1000
|
+
/** 暂停动画:清掉定时器与行,但保留"应继续"状态供 resume */
|
|
1001
|
+
pause() {
|
|
1002
|
+
if (!this.timer) return;
|
|
1003
|
+
clearInterval(this.timer);
|
|
1004
|
+
this.timer = null;
|
|
1005
|
+
this.paused = true;
|
|
1006
|
+
process.stdout.write("\r\x1B[2K");
|
|
1007
|
+
}
|
|
1008
|
+
/** 恢复暂停的动画 */
|
|
1009
|
+
resume() {
|
|
1010
|
+
if (!this.paused) return;
|
|
1011
|
+
this.paused = false;
|
|
1012
|
+
if (!process.stdout.isTTY) return;
|
|
1013
|
+
this.frameIdx = 0;
|
|
1014
|
+
this.render();
|
|
1015
|
+
this.timer = setInterval(() => {
|
|
1016
|
+
this.frameIdx = (this.frameIdx + 1) % FRAMES.length;
|
|
1017
|
+
this.render();
|
|
1018
|
+
}, INTERVAL_MS);
|
|
1019
|
+
}
|
|
1020
|
+
/** 停止动画:清除行;可选写一行结果摘要 */
|
|
1021
|
+
stop(summary) {
|
|
1022
|
+
if (this.timer) {
|
|
1023
|
+
clearInterval(this.timer);
|
|
1024
|
+
this.timer = null;
|
|
1025
|
+
process.stdout.write("\r\x1B[2K");
|
|
1026
|
+
}
|
|
1027
|
+
this.paused = false;
|
|
1028
|
+
if (activeSpinner === this) activeSpinner = null;
|
|
1029
|
+
if (summary) {
|
|
1030
|
+
process.stdout.write(`${summary}
|
|
1031
|
+
`);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
render() {
|
|
1035
|
+
const frame = chalk2.cyan(FRAMES[this.frameIdx]);
|
|
1036
|
+
const text = this.prefix ? `${frame} ${chalk2.dim(this.prefix)}` : frame;
|
|
1037
|
+
process.stdout.write(`\r\x1B[2K${text}`);
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
|
|
1041
|
+
// src/modes/print.ts
|
|
1042
|
+
import chalk4 from "chalk";
|
|
950
1043
|
|
|
951
1044
|
// src/modes/render.ts
|
|
952
|
-
import
|
|
1045
|
+
import chalk3 from "chalk";
|
|
953
1046
|
var ChunkRenderer = class {
|
|
954
1047
|
constructor(opts = {}) {
|
|
955
1048
|
this.opts = opts;
|
|
@@ -957,47 +1050,84 @@ var ChunkRenderer = class {
|
|
|
957
1050
|
opts;
|
|
958
1051
|
thinkingShown = false;
|
|
959
1052
|
inTool = false;
|
|
1053
|
+
/** 当前工具起始时间(用于结束时显示耗时) */
|
|
1054
|
+
toolStartedAt = 0;
|
|
1055
|
+
spinner = new Spinner();
|
|
960
1056
|
render(chunk) {
|
|
961
1057
|
const err = this.opts.toolStream ?? process.stdout;
|
|
962
1058
|
switch (chunk.type) {
|
|
963
1059
|
case "text":
|
|
1060
|
+
if (this.spinner.active || this.inTool) {
|
|
1061
|
+
this.spinner.stop();
|
|
1062
|
+
this.inTool = false;
|
|
1063
|
+
}
|
|
964
1064
|
if (chunk.content) process.stdout.write(chunk.content);
|
|
965
1065
|
break;
|
|
966
1066
|
case "thinking": {
|
|
967
1067
|
if (this.opts.showThinking && chunk.content) {
|
|
968
|
-
process.stdout.write(
|
|
1068
|
+
process.stdout.write(chalk3.dim(chunk.content));
|
|
969
1069
|
} else if (!this.thinkingShown) {
|
|
970
1070
|
this.thinkingShown = true;
|
|
971
|
-
|
|
1071
|
+
if (process.stdout.isTTY) {
|
|
1072
|
+
this.spinner.start("\u601D\u8003\u4E2D");
|
|
1073
|
+
} else {
|
|
1074
|
+
err.write(chalk3.dim(" (\u601D\u8003\u4E2D...)\n"));
|
|
1075
|
+
}
|
|
972
1076
|
}
|
|
973
1077
|
break;
|
|
974
1078
|
}
|
|
975
1079
|
case "tool_start":
|
|
976
1080
|
this.inTool = true;
|
|
977
|
-
|
|
1081
|
+
this.toolStartedAt = Date.now();
|
|
1082
|
+
if (process.stdout.isTTY) {
|
|
1083
|
+
this.spinner.start(`\u6267\u884C ${chunk.toolName ?? "\u5DE5\u5177"}`);
|
|
1084
|
+
} else {
|
|
1085
|
+
err.write(chalk3.cyan(`
|
|
978
1086
|
\u2699 ${chunk.toolName} `));
|
|
1087
|
+
}
|
|
979
1088
|
break;
|
|
980
1089
|
case "tool_end":
|
|
981
1090
|
if (this.inTool) {
|
|
982
|
-
|
|
1091
|
+
const elapsed = this.toolStartedAt ? Date.now() - this.toolStartedAt : 0;
|
|
1092
|
+
const timeStr = elapsed > 0 ? chalk3.dim(` ${formatElapsed(elapsed)}`) : "";
|
|
1093
|
+
if (process.stdout.isTTY) {
|
|
1094
|
+
const mark = chunk.isError ? chalk3.red("\u2717") : chalk3.green("\u2713");
|
|
1095
|
+
this.spinner.stop(`${chalk3.cyan("\u2699")} ${chunk.toolName ?? ""} ${mark}${timeStr}`);
|
|
1096
|
+
} else {
|
|
1097
|
+
err.write(chunk.isError ? chalk3.red(" \u2717\n") : chalk3.green(" \u2713\n"));
|
|
1098
|
+
}
|
|
983
1099
|
this.inTool = false;
|
|
984
1100
|
}
|
|
985
1101
|
break;
|
|
986
1102
|
case "error":
|
|
987
|
-
|
|
1103
|
+
this.spinner.stop();
|
|
1104
|
+
this.inTool = false;
|
|
1105
|
+
err.write(chalk3.red(`
|
|
988
1106
|
\u9519\u8BEF: ${chunk.content ?? "\u672A\u77E5\u9519\u8BEF"}
|
|
989
1107
|
`));
|
|
990
1108
|
break;
|
|
991
1109
|
case "done":
|
|
1110
|
+
this.spinner.stop();
|
|
1111
|
+
this.inTool = false;
|
|
992
1112
|
process.stdout.write("\n");
|
|
993
1113
|
break;
|
|
994
1114
|
}
|
|
995
1115
|
}
|
|
996
1116
|
reset() {
|
|
1117
|
+
this.spinner.stop();
|
|
997
1118
|
this.thinkingShown = false;
|
|
998
1119
|
this.inTool = false;
|
|
1120
|
+
this.toolStartedAt = 0;
|
|
999
1121
|
}
|
|
1000
1122
|
};
|
|
1123
|
+
function formatElapsed(ms) {
|
|
1124
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
1125
|
+
const s = ms / 1e3;
|
|
1126
|
+
if (s < 60) return `${s.toFixed(1)}s`;
|
|
1127
|
+
const m = Math.floor(s / 60);
|
|
1128
|
+
const rem = Math.round(s % 60);
|
|
1129
|
+
return `${m}m ${String(rem).padStart(2, "0")}s`;
|
|
1130
|
+
}
|
|
1001
1131
|
|
|
1002
1132
|
// src/modes/print.ts
|
|
1003
1133
|
async function runPrintMode(runtime, request) {
|
|
@@ -1011,13 +1141,13 @@ async function runPrintMode(runtime, request) {
|
|
|
1011
1141
|
renderer.render(chunk);
|
|
1012
1142
|
}
|
|
1013
1143
|
} catch (err) {
|
|
1014
|
-
process.stderr.write(
|
|
1144
|
+
process.stderr.write(chalk4.red(`\u9519\u8BEF: ${err instanceof Error ? err.message : String(err)}
|
|
1015
1145
|
`));
|
|
1016
1146
|
process.exitCode = 1;
|
|
1017
1147
|
return;
|
|
1018
1148
|
}
|
|
1019
1149
|
if (usage && (usage.input || usage.output)) {
|
|
1020
|
-
process.stderr.write(
|
|
1150
|
+
process.stderr.write(chalk4.dim(`tokens: \u2191${(usage.input ?? 0).toLocaleString()} \u2193${(usage.output ?? 0).toLocaleString()}
|
|
1021
1151
|
`));
|
|
1022
1152
|
}
|
|
1023
1153
|
if (error) process.exitCode = 1;
|
|
@@ -1056,9 +1186,41 @@ async function runJsonMode(runtime, request) {
|
|
|
1056
1186
|
}
|
|
1057
1187
|
}
|
|
1058
1188
|
|
|
1189
|
+
// src/banner.ts
|
|
1190
|
+
import chalk5 from "chalk";
|
|
1191
|
+
import { getBuiltinProviders as getBuiltinProviders2, hasProviderConfigured as hasProviderConfigured2 } from "@aipack-ai/agent";
|
|
1192
|
+
function printStartupBanner(opts) {
|
|
1193
|
+
const title = chalk5.bold(`${APP_NAME} ${VERSION}`);
|
|
1194
|
+
const session = chalk5.dim(
|
|
1195
|
+
`\u4F1A\u8BDD: ${opts.sessionKey}${opts.ephemeral ? " (\u4E34\u65F6)" : ""}`
|
|
1196
|
+
);
|
|
1197
|
+
const modelTag = opts.customModel ? `${opts.modelLabel} ${chalk5.yellow("(\u81EA\u5B9A\u4E49)")}` : opts.modelLabel;
|
|
1198
|
+
const model = chalk5.dim(`\u6A21\u578B: ${modelTag}`);
|
|
1199
|
+
const apiKeyHint = detectApiKeyHint();
|
|
1200
|
+
console.log(title);
|
|
1201
|
+
console.log(session);
|
|
1202
|
+
console.log(model);
|
|
1203
|
+
if (apiKeyHint) {
|
|
1204
|
+
console.log(apiKeyHint);
|
|
1205
|
+
}
|
|
1206
|
+
console.log(
|
|
1207
|
+
chalk5.dim("\u8F93\u5165 /help \u67E5\u770B\u547D\u4EE4\uFF0CCtrl+C \u4E2D\u65AD\u8FD0\u884C\uFF0C\u8FDE\u6309\u4E24\u6B21\u9000\u51FA") + "\n"
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1210
|
+
function detectApiKeyHint() {
|
|
1211
|
+
const configured = getBuiltinProviders2().filter(
|
|
1212
|
+
(p) => hasProviderConfigured2(p.id)
|
|
1213
|
+
);
|
|
1214
|
+
if (configured.length === 0) {
|
|
1215
|
+
const providers = getBuiltinProviders2().slice(0, 4).map((p) => ` export ${p.envVar}=sk-...`).join("\n");
|
|
1216
|
+
return "\n" + chalk5.yellow("\u26A0 \u672A\u68C0\u6D4B\u5230\u4EFB\u4F55 API Key\uFF0CAI \u8C03\u7528\u5C06\u5931\u8D25\u3002") + "\n" + chalk5.dim("\u4EFB\u9009\u4E00\u4E2A\u63D0\u4F9B\u5546\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF\uFF1A") + "\n" + providers + "\n" + chalk5.dim("\u67E5\u770B\u5168\u90E8\u6A21\u578B\uFF1Aaipack --list-models") + "\n";
|
|
1217
|
+
}
|
|
1218
|
+
return null;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1059
1221
|
// src/modes/interactive.ts
|
|
1060
1222
|
import readline2 from "readline";
|
|
1061
|
-
import
|
|
1223
|
+
import chalk6 from "chalk";
|
|
1062
1224
|
import {
|
|
1063
1225
|
getBuiltinModels as getBuiltinModels2,
|
|
1064
1226
|
adaptAiModel as adaptAiModel2
|
|
@@ -1099,6 +1261,7 @@ async function runInteractiveMode(opts) {
|
|
|
1099
1261
|
const renderer = new ChunkRenderer();
|
|
1100
1262
|
let busy = false;
|
|
1101
1263
|
let sigintCount = 0;
|
|
1264
|
+
let pendingMultiline = [];
|
|
1102
1265
|
let finish;
|
|
1103
1266
|
const finished = new Promise((resolve) => {
|
|
1104
1267
|
finish = resolve;
|
|
@@ -1106,26 +1269,37 @@ async function runInteractiveMode(opts) {
|
|
|
1106
1269
|
function cleanup() {
|
|
1107
1270
|
finish();
|
|
1108
1271
|
}
|
|
1272
|
+
function buildPrompt() {
|
|
1273
|
+
const id = model.aiModel.id;
|
|
1274
|
+
return chalk6.blue(`${chalk6.dim("aipack")} ${chalk6.cyan(id)}${chalk6.blue(">")} `);
|
|
1275
|
+
}
|
|
1109
1276
|
let rl;
|
|
1110
1277
|
let recreating = false;
|
|
1111
1278
|
function setupRl() {
|
|
1112
1279
|
rl = readline2.createInterface({
|
|
1113
1280
|
input: process.stdin,
|
|
1114
1281
|
output: process.stdout,
|
|
1115
|
-
prompt:
|
|
1282
|
+
prompt: buildPrompt()
|
|
1116
1283
|
});
|
|
1117
1284
|
rl.on("SIGINT", () => {
|
|
1118
1285
|
if (busy) {
|
|
1119
|
-
console.log(
|
|
1286
|
+
console.log(chalk6.yellow("\n\u4E2D\u65AD\u5F53\u524D\u8FD0\u884C..."));
|
|
1120
1287
|
runtime.abort(activeKey);
|
|
1121
1288
|
return;
|
|
1122
1289
|
}
|
|
1290
|
+
if (pendingMultiline.length > 0) {
|
|
1291
|
+
pendingMultiline = [];
|
|
1292
|
+
rl.setPrompt(buildPrompt());
|
|
1293
|
+
console.log(chalk6.dim("\uFF08\u5DF2\u53D6\u6D88\u591A\u884C\u8F93\u5165\uFF09"));
|
|
1294
|
+
rl.prompt();
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1123
1297
|
sigintCount++;
|
|
1124
1298
|
if (sigintCount >= 2) {
|
|
1125
|
-
console.log(
|
|
1299
|
+
console.log(chalk6.dim("\n\u518D\u89C1"));
|
|
1126
1300
|
rl.close();
|
|
1127
1301
|
} else {
|
|
1128
|
-
console.log(
|
|
1302
|
+
console.log(chalk6.dim("\uFF08\u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA\uFF09"));
|
|
1129
1303
|
rl.prompt();
|
|
1130
1304
|
setTimeout(() => {
|
|
1131
1305
|
sigintCount = 0;
|
|
@@ -1151,25 +1325,47 @@ async function runInteractiveMode(opts) {
|
|
|
1151
1325
|
sessionKey: activeKey,
|
|
1152
1326
|
ephemeral: args.noSession
|
|
1153
1327
|
};
|
|
1328
|
+
let turnUsage = { input: 0, output: 0 };
|
|
1329
|
+
let toolsUsed = [];
|
|
1154
1330
|
try {
|
|
1155
1331
|
for await (const chunk of runtime.stream(request)) {
|
|
1156
1332
|
renderer.render(chunk);
|
|
1157
1333
|
if (chunk.type === "done" && chunk.result?.usage) {
|
|
1158
1334
|
const u = chunk.result.usage;
|
|
1159
|
-
|
|
1160
|
-
|
|
1335
|
+
turnUsage.input = u.input ?? 0;
|
|
1336
|
+
turnUsage.output = u.output ?? 0;
|
|
1337
|
+
usageTotal.input += turnUsage.input;
|
|
1338
|
+
usageTotal.output += turnUsage.output;
|
|
1339
|
+
toolsUsed = chunk.result.toolsUsed ?? [];
|
|
1161
1340
|
}
|
|
1162
1341
|
}
|
|
1163
|
-
|
|
1164
|
-
console.log(chalk3.dim(` tokens: \u2191${usageTotal.input.toLocaleString()} \u2193${usageTotal.output.toLocaleString()}\uFF08\u7D2F\u8BA1\uFF09`));
|
|
1165
|
-
}
|
|
1342
|
+
printTurnStats(turnUsage, toolsUsed);
|
|
1166
1343
|
} catch (err) {
|
|
1167
|
-
console.log(
|
|
1344
|
+
console.log(chalk6.red(`\u9519\u8BEF: ${err instanceof Error ? err.message : String(err)}`));
|
|
1168
1345
|
} finally {
|
|
1169
1346
|
busy = false;
|
|
1170
1347
|
rl.prompt();
|
|
1171
1348
|
}
|
|
1172
1349
|
}
|
|
1350
|
+
function printTurnStats(turn, tools) {
|
|
1351
|
+
const parts = [];
|
|
1352
|
+
if (turn.input > 0 || turn.output > 0) {
|
|
1353
|
+
parts.push(
|
|
1354
|
+
chalk6.dim(`\u672C\u8F6E \u2191${turn.input.toLocaleString()} \u2193${turn.output.toLocaleString()}`)
|
|
1355
|
+
);
|
|
1356
|
+
parts.push(
|
|
1357
|
+
chalk6.dim(
|
|
1358
|
+
`\u7D2F\u8BA1 \u2191${usageTotal.input.toLocaleString()} \u2193${usageTotal.output.toLocaleString()}`
|
|
1359
|
+
)
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
if (tools.length > 0) {
|
|
1363
|
+
parts.push(chalk6.dim(`\u5DE5\u5177 ${tools.join(", ")}`));
|
|
1364
|
+
}
|
|
1365
|
+
if (parts.length > 0) {
|
|
1366
|
+
console.log(` ${parts.join(chalk6.dim(" \xB7 "))}`);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1173
1369
|
async function handleCommand(line) {
|
|
1174
1370
|
const spaceIdx = line.indexOf(" ");
|
|
1175
1371
|
const cmd = (spaceIdx === -1 ? line : line.slice(0, spaceIdx)).toLowerCase();
|
|
@@ -1184,8 +1380,8 @@ async function runInteractiveMode(opts) {
|
|
|
1184
1380
|
return;
|
|
1185
1381
|
case "/model": {
|
|
1186
1382
|
if (!rest) {
|
|
1187
|
-
console.log(
|
|
1188
|
-
console.log(
|
|
1383
|
+
console.log(chalk6.dim(`\u5F53\u524D\u6A21\u578B: ${model.aiModel.provider}/${model.aiModel.id}`));
|
|
1384
|
+
console.log(chalk6.dim("\u7528\u6CD5: /model provider/model-id\uFF08\u5982 /model deepseek/deepseek-chat\uFF09"));
|
|
1189
1385
|
break;
|
|
1190
1386
|
}
|
|
1191
1387
|
const slash = rest.indexOf("/");
|
|
@@ -1193,168 +1389,188 @@ async function runInteractiveMode(opts) {
|
|
|
1193
1389
|
const id = slash === -1 ? rest : rest.slice(slash + 1);
|
|
1194
1390
|
const found = getBuiltinModels2(provider).find((m) => m.id === id);
|
|
1195
1391
|
if (!found) {
|
|
1196
|
-
console.log(
|
|
1392
|
+
console.log(chalk6.yellow(`\u672A\u627E\u5230\u5185\u7F6E\u6A21\u578B ${provider}/${id}\uFF0C\u53EF\u7528:`));
|
|
1197
1393
|
console.log(getBuiltinModels2(provider).map((m) => ` ${m.id}`).join("\n") || " (\u65E0)");
|
|
1198
1394
|
break;
|
|
1199
1395
|
}
|
|
1200
1396
|
runtime.setModel(adaptAiModel2(found));
|
|
1201
1397
|
model.aiModel = found;
|
|
1202
1398
|
model.custom = false;
|
|
1203
|
-
console.log(
|
|
1399
|
+
console.log(chalk6.green(`\u5DF2\u5207\u6362\u5230 ${provider}/${id}`));
|
|
1204
1400
|
break;
|
|
1205
1401
|
}
|
|
1206
1402
|
case "/thinking": {
|
|
1207
1403
|
if (!VALID_THINKING.has(rest)) {
|
|
1208
|
-
console.log(
|
|
1404
|
+
console.log(chalk6.dim("\u7528\u6CD5: /thinking <off|minimal|low|medium|high|max>"));
|
|
1209
1405
|
break;
|
|
1210
1406
|
}
|
|
1211
1407
|
runtime.setThinkingLevel(rest);
|
|
1212
|
-
console.log(
|
|
1408
|
+
console.log(chalk6.green(`\u601D\u8003\u7EA7\u522B: ${rest}`));
|
|
1213
1409
|
break;
|
|
1214
1410
|
}
|
|
1215
1411
|
case "/system": {
|
|
1216
1412
|
if (!rest) {
|
|
1217
|
-
console.log(
|
|
1413
|
+
console.log(chalk6.dim("\u7528\u6CD5: /system <\u65B0\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD>"));
|
|
1218
1414
|
break;
|
|
1219
1415
|
}
|
|
1220
1416
|
runtime.setSystemPrompt(rest);
|
|
1221
|
-
console.log(
|
|
1417
|
+
console.log(chalk6.green("\u7CFB\u7EDF\u63D0\u793A\u8BCD\u5DF2\u66F4\u65B0"));
|
|
1222
1418
|
break;
|
|
1223
1419
|
}
|
|
1224
1420
|
case "/session":
|
|
1225
|
-
console.log(`\u4F1A\u8BDD key: ${
|
|
1421
|
+
console.log(`\u4F1A\u8BDD key: ${chalk6.cyan(activeKey)}`);
|
|
1226
1422
|
console.log(`\u6D88\u606F\u6570: ${runtime.getMessages(activeKey).length}`);
|
|
1227
|
-
console.log(`\u6301\u4E45\u5316: ${args.noSession ?
|
|
1423
|
+
console.log(`\u6301\u4E45\u5316: ${args.noSession ? chalk6.yellow("\u5426\uFF08--no-session\uFF09") : chalk6.green(storage ? "\u662F" : "\u5426\uFF08\u65E0\u5B58\u50A8\uFF09")}`);
|
|
1228
1424
|
break;
|
|
1229
1425
|
case "/sessions": {
|
|
1230
1426
|
if (!storage) {
|
|
1231
|
-
console.log(
|
|
1427
|
+
console.log(chalk6.yellow("\u5F53\u524D\u4E3A\u4E34\u65F6\u4F1A\u8BDD\uFF0C\u65E0\u6301\u4E45\u5316\u5B58\u50A8"));
|
|
1232
1428
|
break;
|
|
1233
1429
|
}
|
|
1234
1430
|
const sessions = await listSessionsByRecency(storage);
|
|
1235
1431
|
if (sessions.length === 0) {
|
|
1236
|
-
console.log(
|
|
1432
|
+
console.log(chalk6.dim("\uFF08\u65E0\u5386\u53F2\u4F1A\u8BDD\uFF09"));
|
|
1237
1433
|
break;
|
|
1238
1434
|
}
|
|
1239
|
-
console.log(sessions.slice(0, 10).map((s, i) => `${s === activeKey ?
|
|
1240
|
-
console.log(
|
|
1435
|
+
console.log(sessions.slice(0, 10).map((s, i) => `${s === activeKey ? chalk6.green("\u25B8 ") : " "}${i + 1}. ${s}`).join("\n"));
|
|
1436
|
+
console.log(chalk6.dim("\u5207\u6362: \u9000\u51FA\u540E\u7528 aipack --session <key> \u6062\u590D"));
|
|
1241
1437
|
break;
|
|
1242
1438
|
}
|
|
1243
1439
|
case "/clear":
|
|
1244
1440
|
runtime.clearSession(activeKey);
|
|
1245
1441
|
usageTotal = { input: 0, output: 0 };
|
|
1246
|
-
console.log(
|
|
1442
|
+
console.log(chalk6.green("\u4F1A\u8BDD\u5DF2\u6E05\u7A7A\uFF08\u4EC5\u5185\u5B58\uFF09"));
|
|
1247
1443
|
break;
|
|
1248
1444
|
case "/compact": {
|
|
1249
|
-
console.log(
|
|
1445
|
+
console.log(chalk6.dim("\u538B\u7F29\u4F1A\u8BDD\u5386\u53F2..."));
|
|
1250
1446
|
const mode = await runtime.compact(activeKey);
|
|
1251
1447
|
if (mode === null) {
|
|
1252
|
-
console.log(
|
|
1448
|
+
console.log(chalk6.yellow("\u65E0\u53EF\u538B\u7F29\u5185\u5BB9\uFF08\u6D88\u606F\u8FC7\u5C11\u6216\u538B\u7F29\u5DF2\u901A\u8FC7 --no-compaction \u5173\u95ED\uFF09"));
|
|
1253
1449
|
} else {
|
|
1254
|
-
console.log(
|
|
1450
|
+
console.log(chalk6.green(`\u5DF2\u5B8C\u6210${mode === "summary" ? "\u6458\u8981\u538B\u7F29" : "\u622A\u65AD\u538B\u7F29"}\uFF0C\u6D88\u606F\u6570: ${runtime.getMessages(activeKey).length}`));
|
|
1255
1451
|
}
|
|
1256
1452
|
break;
|
|
1257
1453
|
}
|
|
1258
1454
|
case "/tools":
|
|
1259
|
-
console.log(
|
|
1260
|
-
console.log(
|
|
1455
|
+
console.log(chalk6.dim("\u5185\u7F6E\u5DE5\u5177: read, write, edit, bash, find, grep, ls"));
|
|
1456
|
+
console.log(chalk6.dim("\u901A\u8FC7 --tools / --exclude-tools / --no-tools \u914D\u7F6E\u542F\u505C"));
|
|
1261
1457
|
break;
|
|
1262
1458
|
case "/mcp": {
|
|
1263
1459
|
if (!mcp) {
|
|
1264
|
-
console.log(
|
|
1460
|
+
console.log(chalk6.yellow("\u672A\u914D\u7F6E MCP server\uFF08\u5728 .mcp.json / ~/.aipack/mcp.json \u4E2D\u914D\u7F6E\uFF09"));
|
|
1265
1461
|
break;
|
|
1266
1462
|
}
|
|
1267
1463
|
if (rest === "refresh") {
|
|
1268
|
-
console.log(
|
|
1464
|
+
console.log(chalk6.dim("\u5237\u65B0 MCP \u5DE5\u5177\u5217\u8868..."));
|
|
1269
1465
|
const diags2 = await mcp.refresh();
|
|
1270
1466
|
if (diags2.length > 0) {
|
|
1271
|
-
for (const d of diags2) console.log(` ${
|
|
1467
|
+
for (const d of diags2) console.log(` ${chalk6[d.type === "error" ? "red" : d.type === "warning" ? "yellow" : "cyan"](d.type)} [${d.server}] ${d.message}`);
|
|
1272
1468
|
}
|
|
1273
|
-
console.log(
|
|
1469
|
+
console.log(chalk6.green("\u5237\u65B0\u5B8C\u6210"));
|
|
1274
1470
|
break;
|
|
1275
1471
|
}
|
|
1276
1472
|
const statuses = mcp.registry.getStatus();
|
|
1277
1473
|
if (statuses.length === 0) {
|
|
1278
|
-
console.log(
|
|
1474
|
+
console.log(chalk6.dim("\uFF08\u65E0 MCP server\uFF09"));
|
|
1279
1475
|
break;
|
|
1280
1476
|
}
|
|
1281
1477
|
for (const s of statuses) {
|
|
1282
|
-
const flag = s.connected ?
|
|
1283
|
-
const err = s.error ?
|
|
1284
|
-
console.log(`${flag} ${
|
|
1478
|
+
const flag = s.connected ? chalk6.green("\u25CF") : chalk6.red("\u25CB");
|
|
1479
|
+
const err = s.error ? chalk6.red(` ${s.error}`) : "";
|
|
1480
|
+
console.log(`${flag} ${chalk6.cyan(s.name)} ${s.transport} ${s.toolCount} \u5DE5\u5177${err}`);
|
|
1285
1481
|
}
|
|
1286
1482
|
const diags = mcp.diagnostics;
|
|
1287
1483
|
if (diags.length > 0) {
|
|
1288
|
-
console.log(
|
|
1484
|
+
console.log(chalk6.dim("\u8BCA\u65AD:"));
|
|
1289
1485
|
for (const d of diags) console.log(` ${d.type} [${d.server}] ${d.message}`);
|
|
1290
1486
|
}
|
|
1291
1487
|
break;
|
|
1292
1488
|
}
|
|
1293
1489
|
case "/approvals": {
|
|
1294
1490
|
if (!approvalManager) {
|
|
1295
|
-
console.log(
|
|
1491
|
+
console.log(chalk6.yellow("\u5BA1\u6279\u672A\u542F\u7528\uFF08\u5728 aipack.config.js \u4E2D\u914D\u7F6E approvals.enabled: true\uFF09"));
|
|
1296
1492
|
break;
|
|
1297
1493
|
}
|
|
1298
1494
|
const pending = approvalManager.list();
|
|
1299
1495
|
if (pending.length === 0) {
|
|
1300
|
-
console.log(
|
|
1496
|
+
console.log(chalk6.dim("\uFF08\u65E0\u672A\u51B3\u5BA1\u6279\uFF09"));
|
|
1301
1497
|
break;
|
|
1302
1498
|
}
|
|
1303
1499
|
for (const p of pending) {
|
|
1304
|
-
console.log(`${
|
|
1500
|
+
console.log(`${chalk6.cyan(p.id)} ${p.request.toolName} ${chalk6.dim(new Date(p.createdAt).toLocaleString())}${p.restored ? chalk6.yellow(" (\u5B64\u513F)") : ""}`);
|
|
1305
1501
|
}
|
|
1306
1502
|
break;
|
|
1307
1503
|
}
|
|
1308
1504
|
case "/approve":
|
|
1309
1505
|
case "/deny": {
|
|
1310
1506
|
if (!approvalManager) {
|
|
1311
|
-
console.log(
|
|
1507
|
+
console.log(chalk6.yellow("\u5BA1\u6279\u672A\u542F\u7528"));
|
|
1312
1508
|
break;
|
|
1313
1509
|
}
|
|
1314
1510
|
if (!rest) {
|
|
1315
|
-
console.log(
|
|
1511
|
+
console.log(chalk6.dim(`\u7528\u6CD5: ${cmd} <\u5BA1\u6279\u5355 id>`));
|
|
1316
1512
|
break;
|
|
1317
1513
|
}
|
|
1318
1514
|
const ok = approvalManager.resolve(rest, cmd === "/approve");
|
|
1319
|
-
console.log(ok ?
|
|
1515
|
+
console.log(ok ? chalk6.green("\u5DF2\u751F\u6548") : chalk6.yellow("\u5BA1\u6279\u5355\u4E0D\u5B58\u5728\u6216\u5DF2\u7ED3\u7B97"));
|
|
1320
1516
|
break;
|
|
1321
1517
|
}
|
|
1322
1518
|
default:
|
|
1323
|
-
console.log(
|
|
1519
|
+
console.log(chalk6.yellow(`\u672A\u77E5\u547D\u4EE4: ${cmd}\uFF08/help \u67E5\u770B\u5168\u90E8\uFF09`));
|
|
1324
1520
|
}
|
|
1325
1521
|
}
|
|
1326
1522
|
function printSlashHelp() {
|
|
1327
|
-
console.log(`${
|
|
1328
|
-
/model [provider/id]
|
|
1329
|
-
/thinking <\u7EA7\u522B>
|
|
1330
|
-
/system <\u6587\u672C>
|
|
1331
|
-
/session
|
|
1332
|
-
/sessions
|
|
1333
|
-
/clear
|
|
1334
|
-
/compact
|
|
1335
|
-
/
|
|
1336
|
-
/
|
|
1337
|
-
/
|
|
1338
|
-
/
|
|
1339
|
-
/
|
|
1523
|
+
console.log(`${chalk6.bold.magenta("\u659C\u6760\u547D\u4EE4:")}
|
|
1524
|
+
${chalk6.green("/model [provider/id]")} \u5207\u6362\u6A21\u578B\uFF08\u65E0\u53C2\u663E\u793A\u5F53\u524D\uFF09
|
|
1525
|
+
${chalk6.green("/thinking <\u7EA7\u522B>")} ${chalk6.dim("off/minimal/low/medium/high/max")}
|
|
1526
|
+
${chalk6.green("/system <\u6587\u672C>")} \u66FF\u6362\u7CFB\u7EDF\u63D0\u793A\u8BCD
|
|
1527
|
+
${chalk6.green("/session")} \u5F53\u524D\u4F1A\u8BDD\u4FE1\u606F
|
|
1528
|
+
${chalk6.green("/sessions")} \u5217\u51FA\u5386\u53F2\u4F1A\u8BDD
|
|
1529
|
+
${chalk6.green("/clear")} \u6E05\u7A7A\u5F53\u524D\u4F1A\u8BDD\uFF08\u4EC5\u5185\u5B58\uFF09
|
|
1530
|
+
${chalk6.green("/compact")} \u624B\u52A8\u538B\u7F29\u4F1A\u8BDD\u5386\u53F2\uFF08\u91CA\u653E\u4E0A\u4E0B\u6587\u7A7A\u95F4\uFF09
|
|
1531
|
+
${chalk6.green("/tools")} \u67E5\u770B\u5DE5\u5177\u96C6\u4E0E\u6743\u9650\u914D\u7F6E
|
|
1532
|
+
${chalk6.green("/mcp [refresh]")} MCP server \u72B6\u6001 / \u70ED\u5237\u65B0\u5DE5\u5177\u5217\u8868
|
|
1533
|
+
${chalk6.green("/approvals")} \u672A\u51B3\u5BA1\u6279\u5355
|
|
1534
|
+
${chalk6.green("/approve <id>")} \u6279\u51C6
|
|
1535
|
+
${chalk6.green("/deny <id>")} \u9A73\u56DE
|
|
1536
|
+
${chalk6.green("/quit")} \u9000\u51FA\uFF08Ctrl+C \u53CC\u51FB\uFF09
|
|
1537
|
+
|
|
1538
|
+
${chalk6.dim("\u8F93\u5165\u63D0\u793A:")}
|
|
1539
|
+
${chalk6.dim("\xB7 \u666E\u901A\u6587\u672C\u76F4\u63A5\u53D1\u9001\uFF1B\u884C\u5C3E\u4EE5")} ${chalk6.yellow("\\")} ${chalk6.dim("\u7EED\u884C\uFF0C\u7A7A\u884C\u63D0\u4EA4\u591A\u884C")}
|
|
1540
|
+
${chalk6.dim("\xB7")} ${chalk6.yellow("@\u6587\u4EF6")} ${chalk6.dim("\u53EF\u9644\u52A0\u6587\u4EF6\u4E0A\u4E0B\u6587\uFF08\u56FE\u7247\u81EA\u52A8\u8D70\u591A\u6A21\u6001\uFF09")}`);
|
|
1340
1541
|
}
|
|
1341
1542
|
async function onLine(line) {
|
|
1342
1543
|
const text = line.trim();
|
|
1343
1544
|
if (!text) {
|
|
1545
|
+
if (pendingMultiline.length > 0) {
|
|
1546
|
+
const joined = pendingMultiline.join("\n");
|
|
1547
|
+
pendingMultiline = [];
|
|
1548
|
+
await send(joined);
|
|
1549
|
+
} else {
|
|
1550
|
+
rl.prompt();
|
|
1551
|
+
}
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
if (!text.startsWith("/") && text.endsWith("\\") && !text.endsWith("\\\\")) {
|
|
1555
|
+
pendingMultiline.push(text.slice(0, -1));
|
|
1556
|
+
rl.setPrompt(chalk6.dim("\u2026 "));
|
|
1344
1557
|
rl.prompt();
|
|
1345
1558
|
return;
|
|
1346
1559
|
}
|
|
1560
|
+
const full = pendingMultiline.length > 0 ? [...pendingMultiline, text].join("\n") : text;
|
|
1561
|
+
pendingMultiline = [];
|
|
1562
|
+
rl.setPrompt(buildPrompt());
|
|
1347
1563
|
if (busy) {
|
|
1348
|
-
console.log(
|
|
1564
|
+
console.log(chalk6.dim("\uFF08\u8FD0\u884C\u4E2D\uFF0C\u8F93\u5165\u88AB\u5FFD\u7565\uFF1BCtrl+C \u4E2D\u65AD\uFF09"));
|
|
1349
1565
|
rl.prompt();
|
|
1350
1566
|
return;
|
|
1351
1567
|
}
|
|
1352
|
-
if (
|
|
1353
|
-
await handleCommand(
|
|
1568
|
+
if (full.startsWith("/")) {
|
|
1569
|
+
await handleCommand(full);
|
|
1354
1570
|
rl.prompt();
|
|
1355
1571
|
return;
|
|
1356
1572
|
}
|
|
1357
|
-
await send(
|
|
1573
|
+
await send(full);
|
|
1358
1574
|
}
|
|
1359
1575
|
if (opts.confirmRef) {
|
|
1360
1576
|
opts.confirmRef.fn = async (req) => {
|
|
@@ -1368,10 +1584,12 @@ async function runInteractiveMode(opts) {
|
|
|
1368
1584
|
}
|
|
1369
1585
|
};
|
|
1370
1586
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1587
|
+
printStartupBanner({
|
|
1588
|
+
sessionKey: activeKey,
|
|
1589
|
+
ephemeral: args.noSession,
|
|
1590
|
+
modelLabel: `${model.aiModel.provider}/${model.aiModel.id}`,
|
|
1591
|
+
customModel: model.custom
|
|
1592
|
+
});
|
|
1375
1593
|
setupRl();
|
|
1376
1594
|
if (opts.initialMessages && opts.initialMessages.length > 0) {
|
|
1377
1595
|
await send(opts.initialMessages.join("\n"));
|
|
@@ -1381,14 +1599,14 @@ async function runInteractiveMode(opts) {
|
|
|
1381
1599
|
async function pickSessionInteractively(storage, currentKey) {
|
|
1382
1600
|
const sessions = await listSessionsByRecency(storage);
|
|
1383
1601
|
if (sessions.length === 0) {
|
|
1384
|
-
console.log(
|
|
1602
|
+
console.log(chalk6.dim("\uFF08\u65E0\u5386\u53F2\u4F1A\u8BDD\uFF0C\u5C06\u65B0\u5EFA\uFF09"));
|
|
1385
1603
|
return void 0;
|
|
1386
1604
|
}
|
|
1387
|
-
console.log(
|
|
1605
|
+
console.log(chalk6.bold("\u9009\u62E9\u4F1A\u8BDD:"));
|
|
1388
1606
|
sessions.slice(0, 15).forEach((s, i) => {
|
|
1389
|
-
console.log(`${s === currentKey ?
|
|
1607
|
+
console.log(`${s === currentKey ? chalk6.green("\u25B8 ") : " "}${i + 1}. ${s}`);
|
|
1390
1608
|
});
|
|
1391
|
-
console.log(
|
|
1609
|
+
console.log(chalk6.dim(" n. \u65B0\u4F1A\u8BDD"));
|
|
1392
1610
|
const answer = await ask("\u7F16\u53F7: ");
|
|
1393
1611
|
if (answer === "" || answer.toLowerCase() === "n") return void 0;
|
|
1394
1612
|
const idx = Number.parseInt(answer, 10);
|
|
@@ -1399,7 +1617,7 @@ async function pickSessionInteractively(storage, currentKey) {
|
|
|
1399
1617
|
}
|
|
1400
1618
|
|
|
1401
1619
|
// src/select.ts
|
|
1402
|
-
import
|
|
1620
|
+
import chalk7 from "chalk";
|
|
1403
1621
|
async function select(question, options, defaultIndex = 0) {
|
|
1404
1622
|
const stdin = process.stdin;
|
|
1405
1623
|
const out = process.stdout;
|
|
@@ -1413,7 +1631,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1413
1631
|
function render() {
|
|
1414
1632
|
for (let i = 0; i < options.length; i++) {
|
|
1415
1633
|
const opt = options[i];
|
|
1416
|
-
const line = i === selected ? `${
|
|
1634
|
+
const line = i === selected ? `${chalk7.cyan("\u276F ")}${chalk7.bold(opt.label)}` : ` ${opt.label}`;
|
|
1417
1635
|
out.write(`\x1B[2K\r${line}
|
|
1418
1636
|
`);
|
|
1419
1637
|
}
|
|
@@ -1429,7 +1647,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1429
1647
|
for (let i = 0; i < options.length; i++) out.write("\x1B[2K\r\n");
|
|
1430
1648
|
out.write(`\x1B[${options.length}A`);
|
|
1431
1649
|
const chosen = options.find((o) => o.value === value);
|
|
1432
|
-
const summary = chosen ?
|
|
1650
|
+
const summary = chosen ? chalk7.green(`\u2713 ${chosen.label}`) : chalk7.dim("\u5DF2\u53D6\u6D88");
|
|
1433
1651
|
out.write(`\x1B[2K\r ${summary}
|
|
1434
1652
|
`);
|
|
1435
1653
|
resolve(value);
|
|
@@ -1457,7 +1675,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1457
1675
|
}
|
|
1458
1676
|
render();
|
|
1459
1677
|
}
|
|
1460
|
-
out.write(`${
|
|
1678
|
+
out.write(`${chalk7.yellow("?")} ${chalk7.bold(question)}
|
|
1461
1679
|
`);
|
|
1462
1680
|
render();
|
|
1463
1681
|
stdin.on("data", onData);
|
|
@@ -1466,8 +1684,10 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1466
1684
|
|
|
1467
1685
|
// src/confirm.ts
|
|
1468
1686
|
var DANGEROUS_PATTERNS = [
|
|
1469
|
-
// 递归删除根/家目录(rm -rf /、rm -rf ~、rm -rf /*
|
|
1687
|
+
// 递归删除根/家目录(rm -rf /、rm -rf ~、rm -rf /* 等)——最严重,优先匹配
|
|
1470
1688
|
[/rm\s+[^;|&]*[rf][^;|&]*\s+(\/|~|\$HOME)(\/?\*|\s|$)/, "\u9012\u5F52\u5220\u9664\u6839/\u5BB6\u76EE\u5F55"],
|
|
1689
|
+
// 任何 rm 删除(单文件 / 子目录递归)——删除不可撤销,一律确认
|
|
1690
|
+
[/\brm\b/, "\u5220\u9664\u6587\u4EF6"],
|
|
1471
1691
|
[/\bsudo(\s|$)/, "\u63D0\u6743\u6267\u884C"],
|
|
1472
1692
|
[/\bmkfs(\s|\.)/, "\u683C\u5F0F\u5316\u78C1\u76D8"],
|
|
1473
1693
|
[/\bdd\s+[^;|]*of=\/dev\//, "\u5199\u5165\u78C1\u76D8\u8BBE\u5907"],
|
|
@@ -1497,21 +1717,31 @@ function createToolConfirmHandler(options = {}) {
|
|
|
1497
1717
|
const alwaysAllowed = /* @__PURE__ */ new Set();
|
|
1498
1718
|
return async (req) => {
|
|
1499
1719
|
if (!process.stdin.isTTY) return false;
|
|
1500
|
-
const key = req.permissions.length > 0 ? [...req.permissions].sort().join(",") : `tool:${req.toolName}`;
|
|
1501
|
-
if (alwaysAllowed.has(key)) return true;
|
|
1502
1720
|
const args = req.args;
|
|
1503
1721
|
const command = typeof args?.command === "string" ? args.command : "";
|
|
1504
|
-
if (autoApproveSafe && command && !isDangerousCommand(command)) {
|
|
1505
|
-
return true;
|
|
1506
|
-
}
|
|
1507
1722
|
const dangerReason = command ? isDangerousCommand(command) : null;
|
|
1723
|
+
const key = req.permissions.length > 0 ? [...req.permissions].sort().join(",") : `tool:${req.toolName}`;
|
|
1724
|
+
if (!dangerReason) {
|
|
1725
|
+
if (alwaysAllowed.has(key)) return true;
|
|
1726
|
+
if (autoApproveSafe && command) return true;
|
|
1727
|
+
}
|
|
1508
1728
|
const summary = command || summarizeArgs(req);
|
|
1509
1729
|
const question = dangerReason ? `\u5371\u9669\u547D\u4EE4\uFF08${dangerReason}\uFF09\uFF1A${summary}` : summary ? `\u5141\u8BB8\u6267\u884C ${req.toolName}\uFF1A${summary}` : `\u5141\u8BB8\u6267\u884C ${req.toolName}`;
|
|
1510
|
-
const
|
|
1730
|
+
const options2 = dangerReason ? [
|
|
1731
|
+
{ label: "\u5141\u8BB8", value: "once" },
|
|
1732
|
+
{ label: "\u62D2\u7EDD", value: "deny" }
|
|
1733
|
+
] : [
|
|
1511
1734
|
{ label: "\u5141\u8BB8", value: "once" },
|
|
1512
1735
|
{ label: "\u603B\u662F\u5141\u8BB8\uFF08\u672C\u4F1A\u8BDD\uFF09", value: "always" },
|
|
1513
1736
|
{ label: "\u62D2\u7EDD", value: "deny" }
|
|
1514
|
-
]
|
|
1737
|
+
];
|
|
1738
|
+
pauseActiveSpinner();
|
|
1739
|
+
let choice;
|
|
1740
|
+
try {
|
|
1741
|
+
choice = await select(question, options2);
|
|
1742
|
+
} finally {
|
|
1743
|
+
resumeActiveSpinner();
|
|
1744
|
+
}
|
|
1515
1745
|
if (choice === "always") {
|
|
1516
1746
|
alwaysAllowed.add(key);
|
|
1517
1747
|
return true;
|
|
@@ -1521,11 +1751,11 @@ function createToolConfirmHandler(options = {}) {
|
|
|
1521
1751
|
}
|
|
1522
1752
|
|
|
1523
1753
|
// src/cli.ts
|
|
1524
|
-
import
|
|
1754
|
+
import chalk10 from "chalk";
|
|
1525
1755
|
|
|
1526
1756
|
// src/commands/approvals.ts
|
|
1527
1757
|
import path5 from "path";
|
|
1528
|
-
import
|
|
1758
|
+
import chalk8 from "chalk";
|
|
1529
1759
|
import { FileApprovalStore as FileApprovalStore2, createApprovalManager as createApprovalManager2 } from "@aipack-ai/agent";
|
|
1530
1760
|
function createStore() {
|
|
1531
1761
|
return new FileApprovalStore2({
|
|
@@ -1542,7 +1772,7 @@ async function handleApprovalsCommand(args) {
|
|
|
1542
1772
|
if (sub === "list") {
|
|
1543
1773
|
const pending = await store.load();
|
|
1544
1774
|
if (pending.length === 0) {
|
|
1545
|
-
console.log(
|
|
1775
|
+
console.log(chalk8.dim("\uFF08\u65E0\u672A\u51B3\u5BA1\u6279\u5355\uFF09"));
|
|
1546
1776
|
return 0;
|
|
1547
1777
|
}
|
|
1548
1778
|
for (const p of pending) {
|
|
@@ -1553,7 +1783,7 @@ async function handleApprovalsCommand(args) {
|
|
|
1553
1783
|
if (sub === "approve" || sub === "deny") {
|
|
1554
1784
|
const id = rest[0];
|
|
1555
1785
|
if (!id) {
|
|
1556
|
-
console.error(
|
|
1786
|
+
console.error(chalk8.red(`\u7528\u6CD5: aipack approvals ${sub} <id>`));
|
|
1557
1787
|
return 1;
|
|
1558
1788
|
}
|
|
1559
1789
|
const manager = createApprovalManager2({ store });
|
|
@@ -1561,26 +1791,26 @@ async function handleApprovalsCommand(args) {
|
|
|
1561
1791
|
const ok = manager.resolve(id, sub === "approve");
|
|
1562
1792
|
manager.close();
|
|
1563
1793
|
if (!ok) {
|
|
1564
|
-
console.error(
|
|
1794
|
+
console.error(chalk8.yellow(`\u5BA1\u6279\u5355 ${id} \u4E0D\u5B58\u5728\u6216\u5DF2\u7ED3\u7B97`));
|
|
1565
1795
|
return 1;
|
|
1566
1796
|
}
|
|
1567
|
-
console.log(
|
|
1797
|
+
console.log(chalk8.green(`\u5DF2${sub === "approve" ? "\u6279\u51C6" : "\u9A73\u56DE"} ${id}`));
|
|
1568
1798
|
return 0;
|
|
1569
1799
|
}
|
|
1570
1800
|
printUsage();
|
|
1571
|
-
console.error(
|
|
1801
|
+
console.error(chalk8.red(`\u672A\u77E5\u5B50\u547D\u4EE4: ${sub}`));
|
|
1572
1802
|
return 1;
|
|
1573
1803
|
}
|
|
1574
1804
|
function printApproval(p) {
|
|
1575
1805
|
const created = new Date(p.createdAt).toLocaleString();
|
|
1576
|
-
const expires = p.expiresAt ?
|
|
1577
|
-
console.log(`${
|
|
1806
|
+
const expires = p.expiresAt ? chalk8.dim(` \u8FC7\u671F ${new Date(p.expiresAt).toLocaleTimeString()}`) : "";
|
|
1807
|
+
console.log(`${chalk8.cyan(p.id)} ${chalk8.bold(p.toolName)} ${chalk8.dim(created)}${expires}`);
|
|
1578
1808
|
if (p.permissions.length > 0) {
|
|
1579
|
-
console.log(
|
|
1809
|
+
console.log(chalk8.dim(` \u80FD\u529B: ${p.permissions.join(", ")}`));
|
|
1580
1810
|
}
|
|
1581
1811
|
const argsStr = JSON.stringify(p.args);
|
|
1582
1812
|
if (argsStr && argsStr !== "{}") {
|
|
1583
|
-
console.log(
|
|
1813
|
+
console.log(chalk8.dim(` \u53C2\u6570: ${argsStr.length > 120 ? `${argsStr.slice(0, 120)}\u2026` : argsStr}`));
|
|
1584
1814
|
}
|
|
1585
1815
|
}
|
|
1586
1816
|
function printUsage() {
|
|
@@ -1591,33 +1821,33 @@ function printUsage() {
|
|
|
1591
1821
|
}
|
|
1592
1822
|
|
|
1593
1823
|
// src/commands/models.ts
|
|
1594
|
-
import
|
|
1595
|
-
import { getBuiltinProviders as
|
|
1824
|
+
import chalk9 from "chalk";
|
|
1825
|
+
import { getBuiltinProviders as getBuiltinProviders3, getBuiltinModels as getBuiltinModels3, hasProviderConfigured as hasProviderConfigured3 } from "@aipack-ai/agent";
|
|
1596
1826
|
function listModels(search) {
|
|
1597
1827
|
const term = typeof search === "string" ? search.toLowerCase() : void 0;
|
|
1598
1828
|
let total = 0;
|
|
1599
|
-
for (const provider of
|
|
1829
|
+
for (const provider of getBuiltinProviders3()) {
|
|
1600
1830
|
const models = getBuiltinModels3(provider.id);
|
|
1601
1831
|
const matched = term ? models.filter((m) => m.id.toLowerCase().includes(term) || m.name.toLowerCase().includes(term) || provider.id.includes(term)) : models;
|
|
1602
1832
|
if (matched.length === 0) continue;
|
|
1603
|
-
const configured =
|
|
1604
|
-
const badge = configured ?
|
|
1605
|
-
console.log(`${badge} ${
|
|
1833
|
+
const configured = hasProviderConfigured3(provider.id);
|
|
1834
|
+
const badge = configured ? chalk9.green("\u2713") : chalk9.dim("\xB7");
|
|
1835
|
+
console.log(`${badge} ${chalk9.bold(provider.name)} ${chalk9.dim(`(${provider.id})`)}`);
|
|
1606
1836
|
for (const m of matched) {
|
|
1607
1837
|
const flags = [
|
|
1608
|
-
m.reasoning ?
|
|
1838
|
+
m.reasoning ? chalk9.dim("\u63A8\u7406") : null,
|
|
1609
1839
|
`${m.contextWindow / 1e3 | 0}k`
|
|
1610
1840
|
].filter(Boolean).join(" ");
|
|
1611
|
-
console.log(` ${m.id.padEnd(44)} ${
|
|
1841
|
+
console.log(` ${m.id.padEnd(44)} ${chalk9.dim(flags)}`);
|
|
1612
1842
|
total++;
|
|
1613
1843
|
}
|
|
1614
1844
|
}
|
|
1615
|
-
console.log(
|
|
1845
|
+
console.log(chalk9.dim(`
|
|
1616
1846
|
\u5171 ${total} \u4E2A\u6A21\u578B\u3002\u2713 = \u5DF2\u914D\u7F6E API Key\uFF08${getEnvHint()}\uFF09`));
|
|
1617
1847
|
return 0;
|
|
1618
1848
|
}
|
|
1619
1849
|
function getEnvHint() {
|
|
1620
|
-
const provider =
|
|
1850
|
+
const provider = getBuiltinProviders3().find((p) => hasProviderConfigured3(p.id));
|
|
1621
1851
|
return provider ? `${provider.envVar} \u5DF2\u8BBE\u7F6E` : "\u672A\u68C0\u6D4B\u5230\u4EFB\u4F55 API Key";
|
|
1622
1852
|
}
|
|
1623
1853
|
|
|
@@ -1638,12 +1868,12 @@ async function main(argv) {
|
|
|
1638
1868
|
}
|
|
1639
1869
|
const errors = args.diagnostics.filter((d) => d.type === "error");
|
|
1640
1870
|
if (errors.length > 0) {
|
|
1641
|
-
for (const e of errors) console.error(
|
|
1871
|
+
for (const e of errors) console.error(chalk10.red(e.message));
|
|
1642
1872
|
printHelp();
|
|
1643
1873
|
return 1;
|
|
1644
1874
|
}
|
|
1645
1875
|
for (const w of args.diagnostics.filter((d) => d.type === "warning")) {
|
|
1646
|
-
console.error(
|
|
1876
|
+
console.error(chalk10.yellow(w.message));
|
|
1647
1877
|
}
|
|
1648
1878
|
if (args.listModels !== void 0) {
|
|
1649
1879
|
return listModels(args.listModels);
|
|
@@ -1655,7 +1885,7 @@ async function main(argv) {
|
|
|
1655
1885
|
const initial = await buildInitialMessage(args.messages, args.fileArgs, stdinText);
|
|
1656
1886
|
const isNonInteractive = args.print || args.mode === "json";
|
|
1657
1887
|
if (isNonInteractive && !initial.text.trim() && initial.media.length === 0) {
|
|
1658
|
-
console.error(
|
|
1888
|
+
console.error(chalk10.red("\u975E\u4EA4\u4E92\u6A21\u5F0F\u9700\u8981\u63D0\u4F9B\u6D88\u606F\uFF08\u4F4D\u7F6E\u53C2\u6570\u3001@\u6587\u4EF6\u6216\u7BA1\u9053 stdin\uFF09"));
|
|
1659
1889
|
return 1;
|
|
1660
1890
|
}
|
|
1661
1891
|
const toolConfirm = createToolConfirmHandler({ autoApproveSafe: !args.safe });
|
|
@@ -1670,7 +1900,7 @@ async function main(argv) {
|
|
|
1670
1900
|
confirmFn: (req) => confirmRef.fn(req)
|
|
1671
1901
|
});
|
|
1672
1902
|
} catch (err) {
|
|
1673
|
-
console.error(
|
|
1903
|
+
console.error(chalk10.red(`\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`));
|
|
1674
1904
|
return 1;
|
|
1675
1905
|
}
|
|
1676
1906
|
try {
|
|
@@ -1733,8 +1963,12 @@ export {
|
|
|
1733
1963
|
resolveSessionKey,
|
|
1734
1964
|
buildRuntime,
|
|
1735
1965
|
buildInitialMessage,
|
|
1966
|
+
pauseActiveSpinner,
|
|
1967
|
+
resumeActiveSpinner,
|
|
1968
|
+
Spinner,
|
|
1736
1969
|
runPrintMode,
|
|
1737
1970
|
runJsonMode,
|
|
1971
|
+
printStartupBanner,
|
|
1738
1972
|
runInteractiveMode,
|
|
1739
1973
|
pickSessionInteractively,
|
|
1740
1974
|
select,
|
|
@@ -1742,4 +1976,4 @@ export {
|
|
|
1742
1976
|
createToolConfirmHandler,
|
|
1743
1977
|
main
|
|
1744
1978
|
};
|
|
1745
|
-
//# sourceMappingURL=chunk-
|
|
1979
|
+
//# sourceMappingURL=chunk-EU2GJHTO.js.map
|