@aipack-ai/cli 0.0.1 → 1.0.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/dist/bin.d.ts +1 -0
- package/dist/bin.js +16 -0
- package/dist/bin.js.map +1 -0
- package/dist/{chunk-DWPSBSRO.js → chunk-TPMRQPLX.js} +498 -205
- package/dist/chunk-TPMRQPLX.js.map +1 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +1 -1
- package/package.json +7 -5
- package/dist/chunk-DWPSBSRO.js.map +0 -1
- package/dist/cli.d.ts +0 -4
- package/dist/cli.js +0 -8
- package/dist/cli.js.map +0 -1
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
// src/cli.ts
|
|
2
|
-
import chalk7 from "chalk";
|
|
3
|
-
|
|
4
|
-
// src/commands/approvals.ts
|
|
5
|
-
import path2 from "path";
|
|
6
|
-
import chalk from "chalk";
|
|
7
|
-
import { FileApprovalStore, createApprovalManager } from "@aipack-ai/agent";
|
|
8
|
-
|
|
9
1
|
// src/version.ts
|
|
10
2
|
import os from "os";
|
|
11
3
|
import path from "path";
|
|
@@ -13,13 +5,13 @@ import path from "path";
|
|
|
13
5
|
// package.json
|
|
14
6
|
var package_default = {
|
|
15
7
|
name: "@aipack-ai/cli",
|
|
16
|
-
version: "0.0
|
|
8
|
+
version: "1.0.0",
|
|
17
9
|
description: "aipack CLI - \u57FA\u4E8E @aipack-ai/agent \u7684\u7EC8\u7AEF AI \u52A9\u624B",
|
|
18
10
|
type: "module",
|
|
19
11
|
main: "./dist/index.js",
|
|
20
12
|
types: "./dist/index.d.ts",
|
|
21
13
|
bin: {
|
|
22
|
-
aipack: "dist/
|
|
14
|
+
aipack: "dist/bin.js"
|
|
23
15
|
},
|
|
24
16
|
exports: {
|
|
25
17
|
".": {
|
|
@@ -33,9 +25,10 @@ var package_default = {
|
|
|
33
25
|
],
|
|
34
26
|
scripts: {
|
|
35
27
|
build: "tsup",
|
|
36
|
-
prebuild: "pnpm --filter @aipack-ai/agent build",
|
|
28
|
+
prebuild: "[ -f ../agent/dist/index.d.ts ] || pnpm --filter @aipack-ai/agent build",
|
|
37
29
|
typecheck: "tsc --noEmit",
|
|
38
|
-
|
|
30
|
+
test: "node --import tsx --test test/*.test.ts",
|
|
31
|
+
dev: "tsx src/bin.ts"
|
|
39
32
|
},
|
|
40
33
|
keywords: [
|
|
41
34
|
"cli",
|
|
@@ -50,6 +43,7 @@ var package_default = {
|
|
|
50
43
|
},
|
|
51
44
|
dependencies: {
|
|
52
45
|
"@aipack-ai/agent": "workspace:*",
|
|
46
|
+
"@aipack-ai/compression": "workspace:*",
|
|
53
47
|
chalk: "^5.3.0"
|
|
54
48
|
},
|
|
55
49
|
devDependencies: {
|
|
@@ -61,7 +55,7 @@ var package_default = {
|
|
|
61
55
|
};
|
|
62
56
|
|
|
63
57
|
// src/version.ts
|
|
64
|
-
var APP_NAME = package_default.name.replace(/^@[^/]+\//, "");
|
|
58
|
+
var APP_NAME = Object.keys(package_default.bin ?? {})[0] ?? package_default.name.replace(/^@[^/]+\//, "");
|
|
65
59
|
var VERSION = package_default.version;
|
|
66
60
|
function defaultConfigDir() {
|
|
67
61
|
return process.env.AIPACK_CONFIG_DIR ?? path.join(os.homedir(), ".aipack");
|
|
@@ -73,101 +67,6 @@ function encodeDir(p) {
|
|
|
73
67
|
return p.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74
68
|
}
|
|
75
69
|
|
|
76
|
-
// src/commands/approvals.ts
|
|
77
|
-
function createStore() {
|
|
78
|
-
return new FileApprovalStore({
|
|
79
|
-
baseDir: path2.join(defaultConfigDir(), "approvals")
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
async function handleApprovalsCommand(args) {
|
|
83
|
-
const [sub, ...rest] = args;
|
|
84
|
-
if (!sub || sub === "help" || sub === "--help") {
|
|
85
|
-
printUsage();
|
|
86
|
-
return 0;
|
|
87
|
-
}
|
|
88
|
-
const store = createStore();
|
|
89
|
-
if (sub === "list") {
|
|
90
|
-
const pending = await store.load();
|
|
91
|
-
if (pending.length === 0) {
|
|
92
|
-
console.log(chalk.dim("\uFF08\u65E0\u672A\u51B3\u5BA1\u6279\u5355\uFF09"));
|
|
93
|
-
return 0;
|
|
94
|
-
}
|
|
95
|
-
for (const p of pending) {
|
|
96
|
-
printApproval(p);
|
|
97
|
-
}
|
|
98
|
-
return 0;
|
|
99
|
-
}
|
|
100
|
-
if (sub === "approve" || sub === "deny") {
|
|
101
|
-
const id = rest[0];
|
|
102
|
-
if (!id) {
|
|
103
|
-
console.error(chalk.red(`\u7528\u6CD5: aipack approvals ${sub} <id>`));
|
|
104
|
-
return 1;
|
|
105
|
-
}
|
|
106
|
-
const manager = createApprovalManager({ store });
|
|
107
|
-
await manager.restore();
|
|
108
|
-
const ok = manager.resolve(id, sub === "approve");
|
|
109
|
-
manager.close();
|
|
110
|
-
if (!ok) {
|
|
111
|
-
console.error(chalk.yellow(`\u5BA1\u6279\u5355 ${id} \u4E0D\u5B58\u5728\u6216\u5DF2\u7ED3\u7B97`));
|
|
112
|
-
return 1;
|
|
113
|
-
}
|
|
114
|
-
console.log(chalk.green(`\u5DF2${sub === "approve" ? "\u6279\u51C6" : "\u9A73\u56DE"} ${id}`));
|
|
115
|
-
return 0;
|
|
116
|
-
}
|
|
117
|
-
printUsage();
|
|
118
|
-
console.error(chalk.red(`\u672A\u77E5\u5B50\u547D\u4EE4: ${sub}`));
|
|
119
|
-
return 1;
|
|
120
|
-
}
|
|
121
|
-
function printApproval(p) {
|
|
122
|
-
const created = new Date(p.createdAt).toLocaleString();
|
|
123
|
-
const expires = p.expiresAt ? chalk.dim(` \u8FC7\u671F ${new Date(p.expiresAt).toLocaleTimeString()}`) : "";
|
|
124
|
-
console.log(`${chalk.cyan(p.id)} ${chalk.bold(p.toolName)} ${chalk.dim(created)}${expires}`);
|
|
125
|
-
if (p.permissions.length > 0) {
|
|
126
|
-
console.log(chalk.dim(` \u80FD\u529B: ${p.permissions.join(", ")}`));
|
|
127
|
-
}
|
|
128
|
-
const argsStr = JSON.stringify(p.args);
|
|
129
|
-
if (argsStr && argsStr !== "{}") {
|
|
130
|
-
console.log(chalk.dim(` \u53C2\u6570: ${argsStr.length > 120 ? `${argsStr.slice(0, 120)}\u2026` : argsStr}`));
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function printUsage() {
|
|
134
|
-
console.log(`\u7528\u6CD5:
|
|
135
|
-
aipack approvals list \u5217\u51FA\u672A\u51B3\u5BA1\u6279\u5355
|
|
136
|
-
aipack approvals approve <id> \u6279\u51C6
|
|
137
|
-
aipack approvals deny <id> \u9A73\u56DE`);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// src/commands/models.ts
|
|
141
|
-
import chalk2 from "chalk";
|
|
142
|
-
import { getBuiltinProviders, getBuiltinModels, hasProviderConfigured } from "@aipack-ai/agent";
|
|
143
|
-
function listModels(search) {
|
|
144
|
-
const term = typeof search === "string" ? search.toLowerCase() : void 0;
|
|
145
|
-
let total = 0;
|
|
146
|
-
for (const provider of getBuiltinProviders()) {
|
|
147
|
-
const models = getBuiltinModels(provider.id);
|
|
148
|
-
const matched = term ? models.filter((m) => m.id.toLowerCase().includes(term) || m.name.toLowerCase().includes(term) || provider.id.includes(term)) : models;
|
|
149
|
-
if (matched.length === 0) continue;
|
|
150
|
-
const configured = hasProviderConfigured(provider.id);
|
|
151
|
-
const badge = configured ? chalk2.green("\u2713") : chalk2.dim("\xB7");
|
|
152
|
-
console.log(`${badge} ${chalk2.bold(provider.name)} ${chalk2.dim(`(${provider.id})`)}`);
|
|
153
|
-
for (const m of matched) {
|
|
154
|
-
const flags = [
|
|
155
|
-
m.reasoning ? chalk2.dim("\u63A8\u7406") : null,
|
|
156
|
-
`${m.contextWindow / 1e3 | 0}k`
|
|
157
|
-
].filter(Boolean).join(" ");
|
|
158
|
-
console.log(` ${m.id.padEnd(44)} ${chalk2.dim(flags)}`);
|
|
159
|
-
total++;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
console.log(chalk2.dim(`
|
|
163
|
-
\u5171 ${total} \u4E2A\u6A21\u578B\u3002\u2713 = \u5DF2\u914D\u7F6E API Key\uFF08${getEnvHint()}\uFF09`));
|
|
164
|
-
return 0;
|
|
165
|
-
}
|
|
166
|
-
function getEnvHint() {
|
|
167
|
-
const provider = getBuiltinProviders().find((p) => hasProviderConfigured(p.id));
|
|
168
|
-
return provider ? `${provider.envVar} \u5DF2\u8BBE\u7F6E` : "\u672A\u68C0\u6D4B\u5230\u4EFB\u4F55 API Key";
|
|
169
|
-
}
|
|
170
|
-
|
|
171
70
|
// src/args.ts
|
|
172
71
|
var VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "max"];
|
|
173
72
|
function isValidThinkingLevel(level) {
|
|
@@ -237,6 +136,10 @@ function parseArgs(args) {
|
|
|
237
136
|
result.noTools = true;
|
|
238
137
|
} else if (arg === "--safe") {
|
|
239
138
|
result.safe = true;
|
|
139
|
+
} else if (arg === "--no-compaction") {
|
|
140
|
+
result.noCompaction = true;
|
|
141
|
+
} else if (arg === "--compaction-config" && i + 1 < args.length) {
|
|
142
|
+
result.compactionConfig = args[++i];
|
|
240
143
|
} else if (arg === "--print" || arg === "-p") {
|
|
241
144
|
result.print = true;
|
|
242
145
|
const next = args[i + 1];
|
|
@@ -301,11 +204,13 @@ ${"\u5DE5\u5177\u9009\u9879:"}
|
|
|
301
204
|
--no-tools, -nt \u7981\u7528\u5168\u90E8\u5DE5\u5177
|
|
302
205
|
--safe \u4FDD\u5B88\u6A21\u5F0F\uFF1A\u5199\u6587\u4EF6/shell \u5168\u90E8\u4EBA\u5DE5\u786E\u8BA4
|
|
303
206
|
|
|
304
|
-
\u5185\u7F6E\u5DE5\u5177: read, write, edit, bash
|
|
207
|
+
\u5185\u7F6E\u5DE5\u5177: read, write, edit, bash, find, grep, ls
|
|
305
208
|
\u9ED8\u8BA4\u6743\u9650: \u8BFB\u5199\u6587\u4EF6\u9759\u9ED8\u653E\u884C\uFF08\u5DE5\u4F5C\u533A\u8303\u56F4\u5185\uFF09\uFF1Bbash \u4EC5\u5371\u9669\u547D\u4EE4
|
|
306
209
|
\uFF08sudo\u3001rm -rf ~\u3001\u78C1\u76D8\u5199\u5165\u3001\u8FDC\u7A0B\u811A\u672C\u7BA1\u9053\u7B49\uFF09\u9700\u786E\u8BA4
|
|
307
210
|
|
|
308
211
|
${"\u5176\u4ED6:"}
|
|
212
|
+
--no-compaction \u5173\u95ED\u4E0A\u4E0B\u6587\u538B\u7F29\uFF08\u957F\u4F1A\u8BDD\u53EF\u80FD\u6EA2\u51FA\uFF09
|
|
213
|
+
--compaction-config <\u6587\u4EF6> \u538B\u7F29\u914D\u7F6E JSON\uFF08\u8986\u76D6\u9ED8\u8BA4\u9608\u503C\uFF09
|
|
309
214
|
--system-prompt <\u6587\u672C> \u66FF\u6362\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD
|
|
310
215
|
--append-system-prompt <\u6587\u672C> \u8FFD\u52A0\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u53EF\u591A\u6B21\uFF09
|
|
311
216
|
--help, -h \u663E\u793A\u5E2E\u52A9
|
|
@@ -339,32 +244,13 @@ ${"\u73AF\u5883\u53D8\u91CF:"}
|
|
|
339
244
|
`);
|
|
340
245
|
}
|
|
341
246
|
|
|
342
|
-
// src/builder.ts
|
|
343
|
-
import fs2 from "fs/promises";
|
|
344
|
-
import path4 from "path";
|
|
345
|
-
import { pathToFileURL } from "url";
|
|
346
|
-
import {
|
|
347
|
-
createRuntime,
|
|
348
|
-
adaptAiModel,
|
|
349
|
-
createStreamFnFromAi,
|
|
350
|
-
getBuiltinModel,
|
|
351
|
-
getBuiltinModels as getBuiltinModels2,
|
|
352
|
-
getBuiltinProviders as getBuiltinProviders2,
|
|
353
|
-
BUILTIN_PROVIDERS,
|
|
354
|
-
hasProviderConfigured as hasProviderConfigured2,
|
|
355
|
-
createFileSessionStorage,
|
|
356
|
-
createPermissionPolicy,
|
|
357
|
-
createApprovalManager as createApprovalManager2,
|
|
358
|
-
FileApprovalStore as FileApprovalStore2
|
|
359
|
-
} from "@aipack-ai/agent";
|
|
360
|
-
|
|
361
247
|
// src/tools.ts
|
|
362
248
|
import fs from "fs/promises";
|
|
363
|
-
import
|
|
249
|
+
import path2 from "path";
|
|
364
250
|
import { spawn } from "child_process";
|
|
365
251
|
var workspaceRoot = process.cwd();
|
|
366
252
|
function resolveInWorkspace(p) {
|
|
367
|
-
const abs =
|
|
253
|
+
const abs = path2.resolve(workspaceRoot, p);
|
|
368
254
|
if (!abs.startsWith(workspaceRoot)) {
|
|
369
255
|
throw new Error(`\u8DEF\u5F84\u8D8A\u754C\uFF1A${p}\uFF08\u5DE5\u4F5C\u533A\uFF1A${workspaceRoot}\uFF09`);
|
|
370
256
|
}
|
|
@@ -430,7 +316,7 @@ var writeTool = {
|
|
|
430
316
|
const args = rawArgs;
|
|
431
317
|
try {
|
|
432
318
|
const abs = resolveInWorkspace(args.file);
|
|
433
|
-
await fs.mkdir(
|
|
319
|
+
await fs.mkdir(path2.dirname(abs), { recursive: true });
|
|
434
320
|
await fs.writeFile(abs, args.content, "utf8");
|
|
435
321
|
return textResult(`\u5DF2\u5199\u5165 ${args.file}\uFF08${args.content.length} \u5B57\u7B26\uFF09`, { file: args.file });
|
|
436
322
|
} catch (err) {
|
|
@@ -541,7 +427,222 @@ ${stderr.slice(0, MAX_READ_CHARS)}`);
|
|
|
541
427
|
}
|
|
542
428
|
}
|
|
543
429
|
};
|
|
544
|
-
var
|
|
430
|
+
var PRUNED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", ".next", ".turbo", "coverage"]);
|
|
431
|
+
var MAX_GREP_FILE_BYTES = 2 * 1024 * 1024;
|
|
432
|
+
function globToRegExp(pattern) {
|
|
433
|
+
let re = "";
|
|
434
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
435
|
+
const c = pattern[i];
|
|
436
|
+
if (c === "*") {
|
|
437
|
+
if (pattern[i + 1] === "*") {
|
|
438
|
+
re += ".*";
|
|
439
|
+
i++;
|
|
440
|
+
if (pattern[i + 1] === "/") i++;
|
|
441
|
+
} else {
|
|
442
|
+
re += "[^/]*";
|
|
443
|
+
}
|
|
444
|
+
} else if (c === "?") {
|
|
445
|
+
re += "[^/]";
|
|
446
|
+
} else {
|
|
447
|
+
re += c.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return new RegExp(`^${re}$`);
|
|
451
|
+
}
|
|
452
|
+
async function walkFiles(root, maxEntries) {
|
|
453
|
+
const out = [];
|
|
454
|
+
const queue = [""];
|
|
455
|
+
while (queue.length > 0 && out.length < maxEntries) {
|
|
456
|
+
const rel = queue.shift();
|
|
457
|
+
const abs = path2.join(root, rel);
|
|
458
|
+
let entries;
|
|
459
|
+
try {
|
|
460
|
+
entries = await fs.readdir(abs, { withFileTypes: true });
|
|
461
|
+
} catch {
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
for (const e of entries) {
|
|
465
|
+
if (out.length >= maxEntries) break;
|
|
466
|
+
const childRel = rel ? `${rel}/${e.name}` : e.name;
|
|
467
|
+
if (e.isDirectory()) {
|
|
468
|
+
if (!PRUNED_DIRS.has(e.name)) queue.push(childRel);
|
|
469
|
+
} else if (e.isFile()) {
|
|
470
|
+
out.push(childRel);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return out;
|
|
475
|
+
}
|
|
476
|
+
var findTool = {
|
|
477
|
+
name: "find",
|
|
478
|
+
description: '\u6309 glob \u6A21\u5F0F\u67E5\u627E\u6587\u4EF6\u3002\u652F\u6301 ** \u8DE8\u76EE\u5F55\u5339\u914D\u3002\u793A\u4F8B: "**/*.ts"\u3001"src/**/*.spec.ts"',
|
|
479
|
+
parameters: {
|
|
480
|
+
type: "object",
|
|
481
|
+
properties: {
|
|
482
|
+
pattern: { type: "string", description: 'glob \u6A21\u5F0F\uFF0C\u5982 "*.md" \u6216 "**/*.ts"' },
|
|
483
|
+
path: { type: "string", description: "\u641C\u7D22\u76EE\u5F55\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\uFF0C\u9ED8\u8BA4 .\uFF09" },
|
|
484
|
+
limit: { type: "number", description: "\u6700\u5927\u7ED3\u679C\u6570\uFF08\u9ED8\u8BA4 1000\uFF09" }
|
|
485
|
+
},
|
|
486
|
+
required: ["pattern"]
|
|
487
|
+
},
|
|
488
|
+
permissions: ["fs:read"],
|
|
489
|
+
async execute(_id, rawArgs) {
|
|
490
|
+
const args = rawArgs;
|
|
491
|
+
const limit = args.limit ?? 1e3;
|
|
492
|
+
try {
|
|
493
|
+
const root = resolveInWorkspace(args.path ?? ".");
|
|
494
|
+
const re = globToRegExp(args.pattern);
|
|
495
|
+
const files = await walkFiles(root, Math.max(limit * 10, 1e4));
|
|
496
|
+
const matches = files.filter((f) => re.test(f));
|
|
497
|
+
const limited = matches.slice(0, limit);
|
|
498
|
+
if (limited.length === 0) {
|
|
499
|
+
return textResult(`\u672A\u627E\u5230\u5339\u914D "${args.pattern}" \u7684\u6587\u4EF6`, { pattern: args.pattern });
|
|
500
|
+
}
|
|
501
|
+
const suffix = matches.length > limited.length ? `
|
|
502
|
+
...[\u5171 ${matches.length} \u4E2A\uFF0C\u5DF2\u622A\u65AD\u81F3 ${limit}]` : "";
|
|
503
|
+
return textResult(`${limited.join("\n")}${suffix}`, {
|
|
504
|
+
pattern: args.pattern,
|
|
505
|
+
count: matches.length,
|
|
506
|
+
truncated: matches.length > limited.length
|
|
507
|
+
});
|
|
508
|
+
} catch (err) {
|
|
509
|
+
return errorResult(String(err instanceof Error ? err.message : err));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
var grepTool = {
|
|
514
|
+
name: "grep",
|
|
515
|
+
description: "\u5728\u6587\u4EF6\u5185\u5BB9\u4E2D\u641C\u7D22\u6A21\u5F0F\uFF08\u9ED8\u8BA4\u6B63\u5219\uFF09\u3002\u81EA\u52A8\u8DF3\u8FC7\u4E8C\u8FDB\u5236/\u8D85\u5927\u6587\u4EF6\u4E0E node_modules\u3002\u8F93\u51FA file:line: text",
|
|
516
|
+
parameters: {
|
|
517
|
+
type: "object",
|
|
518
|
+
properties: {
|
|
519
|
+
pattern: { type: "string", description: "\u641C\u7D22\u6A21\u5F0F\uFF08\u6B63\u5219\uFF0C\u6216\u914D\u5408 literal \u4F7F\u7528\u5B57\u9762\u91CF\uFF09" },
|
|
520
|
+
path: { type: "string", description: "\u641C\u7D22\u7684\u76EE\u5F55\u6216\u6587\u4EF6\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\uFF0C\u9ED8\u8BA4 .\uFF09" },
|
|
521
|
+
glob: { type: "string", description: '\u6587\u4EF6\u540D\u8FC7\u6EE4 glob\uFF0C\u5982 "*.ts"' },
|
|
522
|
+
ignoreCase: { type: "boolean", description: "\u5FFD\u7565\u5927\u5C0F\u5199\uFF08\u9ED8\u8BA4 false\uFF09" },
|
|
523
|
+
literal: { type: "boolean", description: "\u6309\u5B57\u9762\u91CF\u800C\u975E\u6B63\u5219\u89E3\u91CA pattern\uFF08\u9ED8\u8BA4 false\uFF09" },
|
|
524
|
+
context: { type: "number", description: "\u6BCF\u4E2A\u5339\u914D\u524D\u540E\u663E\u793A\u7684\u884C\u6570\uFF08\u9ED8\u8BA4 0\uFF09" },
|
|
525
|
+
limit: { type: "number", description: "\u6700\u5927\u5339\u914D\u6570\uFF08\u9ED8\u8BA4 100\uFF09" }
|
|
526
|
+
},
|
|
527
|
+
required: ["pattern"]
|
|
528
|
+
},
|
|
529
|
+
permissions: ["fs:read"],
|
|
530
|
+
async execute(_id, rawArgs) {
|
|
531
|
+
const args = rawArgs;
|
|
532
|
+
const limit = args.limit ?? 100;
|
|
533
|
+
const context = args.context ?? 0;
|
|
534
|
+
try {
|
|
535
|
+
const target = resolveInWorkspace(args.path ?? ".");
|
|
536
|
+
const re = new RegExp(
|
|
537
|
+
args.literal ? args.pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") : args.pattern,
|
|
538
|
+
args.ignoreCase ? "i" : ""
|
|
539
|
+
);
|
|
540
|
+
const globRe = args.glob ? globToRegExp(args.glob) : void 0;
|
|
541
|
+
let files;
|
|
542
|
+
const stat = await fs.stat(target);
|
|
543
|
+
if (stat.isFile()) {
|
|
544
|
+
files = [{ rel: path2.relative(workspaceRoot, target), abs: target }];
|
|
545
|
+
} else if (stat.isDirectory()) {
|
|
546
|
+
files = (await walkFiles(target, 2e4)).filter((f) => !globRe || globRe.test(f) || globRe.test(f.split("/").pop())).map((f) => ({ rel: f, abs: path2.join(target, f) }));
|
|
547
|
+
} else {
|
|
548
|
+
return errorResult(`\u4E0D\u662F\u6587\u4EF6\u6216\u76EE\u5F55: ${args.path}`);
|
|
549
|
+
}
|
|
550
|
+
const out = [];
|
|
551
|
+
let matchCount = 0;
|
|
552
|
+
let truncated = false;
|
|
553
|
+
for (const file of files) {
|
|
554
|
+
if (matchCount >= limit) {
|
|
555
|
+
truncated = true;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
let buf;
|
|
559
|
+
try {
|
|
560
|
+
const st = await fs.stat(file.abs);
|
|
561
|
+
if (st.size > MAX_GREP_FILE_BYTES) continue;
|
|
562
|
+
buf = await fs.readFile(file.abs);
|
|
563
|
+
} catch {
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
if (buf.includes(0)) continue;
|
|
567
|
+
const lines = buf.toString("utf8").split("\n");
|
|
568
|
+
const hitLines = [];
|
|
569
|
+
for (let i = 0; i < lines.length && matchCount + hitLines.length < limit; i++) {
|
|
570
|
+
if (re.test(lines[i])) hitLines.push(i);
|
|
571
|
+
}
|
|
572
|
+
if (hitLines.length === 0) continue;
|
|
573
|
+
matchCount += hitLines.length;
|
|
574
|
+
const show = /* @__PURE__ */ new Set();
|
|
575
|
+
for (const h of hitLines) {
|
|
576
|
+
for (let i = Math.max(0, h - context); i <= Math.min(lines.length - 1, h + context); i++) {
|
|
577
|
+
show.add(i);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
for (const i of [...show].sort((a, b) => a - b)) {
|
|
581
|
+
const marker = hitLines.includes(i) ? ">" : " ";
|
|
582
|
+
out.push(`${file.rel}:${i + 1}:${marker} ${lines[i].slice(0, 500)}`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (out.length === 0) {
|
|
586
|
+
return textResult(`\u672A\u627E\u5230\u5339\u914D "${args.pattern}" \u7684\u5185\u5BB9`, { pattern: args.pattern, count: 0 });
|
|
587
|
+
}
|
|
588
|
+
const suffix = truncated ? `
|
|
589
|
+
...[\u5DF2\u8FBE ${limit} \u4E2A\u5339\u914D\u4E0A\u9650\uFF0C\u622A\u65AD]` : "";
|
|
590
|
+
return textResult(`${out.join("\n")}${suffix}`, {
|
|
591
|
+
pattern: args.pattern,
|
|
592
|
+
count: matchCount,
|
|
593
|
+
truncated
|
|
594
|
+
});
|
|
595
|
+
} catch (err) {
|
|
596
|
+
return errorResult(String(err instanceof Error ? err.message : err));
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
var lsTool = {
|
|
601
|
+
name: "ls",
|
|
602
|
+
description: "\u5217\u51FA\u76EE\u5F55\u5185\u5BB9\uFF08\u76EE\u5F55\u5E26 / \u540E\u7F00\uFF0C\u76EE\u5F55\u5728\u524D\uFF09\u3002\u63A2\u7D22\u9879\u76EE\u7ED3\u6784\u65F6\u4F18\u5148\u4F7F\u7528\u3002",
|
|
603
|
+
parameters: {
|
|
604
|
+
type: "object",
|
|
605
|
+
properties: {
|
|
606
|
+
path: { type: "string", description: "\u76EE\u5F55\u8DEF\u5F84\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\uFF0C\u9ED8\u8BA4 .\uFF09" },
|
|
607
|
+
limit: { type: "number", description: "\u6700\u5927\u6761\u76EE\u6570\uFF08\u9ED8\u8BA4 500\uFF09" }
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
permissions: ["fs:read"],
|
|
611
|
+
async execute(_id, rawArgs) {
|
|
612
|
+
const args = rawArgs;
|
|
613
|
+
const limit = args.limit ?? 500;
|
|
614
|
+
try {
|
|
615
|
+
const abs = resolveInWorkspace(args.path ?? ".");
|
|
616
|
+
const stat = await fs.stat(abs);
|
|
617
|
+
if (!stat.isDirectory()) {
|
|
618
|
+
return textResult(path2.relative(workspaceRoot, abs) || abs);
|
|
619
|
+
}
|
|
620
|
+
const entries = await fs.readdir(abs, { withFileTypes: true });
|
|
621
|
+
const sorted = entries.filter((e) => e.isDirectory() || e.isFile() || e.isSymbolicLink()).sort((a, b) => {
|
|
622
|
+
const ad = a.isDirectory() ? 0 : 1;
|
|
623
|
+
const bd = b.isDirectory() ? 0 : 1;
|
|
624
|
+
return ad !== bd ? ad - bd : a.name.localeCompare(b.name);
|
|
625
|
+
});
|
|
626
|
+
const limited = sorted.slice(0, limit);
|
|
627
|
+
if (limited.length === 0) {
|
|
628
|
+
return textResult("\uFF08\u7A7A\u76EE\u5F55\uFF09", {});
|
|
629
|
+
}
|
|
630
|
+
const lines = limited.map(
|
|
631
|
+
(e) => e.isDirectory() ? `${e.name}/` : e.isSymbolicLink() ? `${e.name}@` : e.name
|
|
632
|
+
);
|
|
633
|
+
const suffix = sorted.length > limited.length ? `
|
|
634
|
+
...[\u5171 ${sorted.length} \u9879\uFF0C\u5DF2\u622A\u65AD\u81F3 ${limit}]` : "";
|
|
635
|
+
return textResult(`${lines.join("\n")}${suffix}`, {
|
|
636
|
+
path: args.path ?? ".",
|
|
637
|
+
count: sorted.length,
|
|
638
|
+
truncated: sorted.length > limited.length
|
|
639
|
+
});
|
|
640
|
+
} catch (err) {
|
|
641
|
+
return errorResult(String(err instanceof Error ? err.message : err));
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
var BUILTIN_TOOLS = [readTool, writeTool, editTool, bashTool, findTool, grepTool, lsTool];
|
|
545
646
|
function selectTools(options) {
|
|
546
647
|
if (options.noTools) return [];
|
|
547
648
|
let selected = [...BUILTIN_TOOLS];
|
|
@@ -557,9 +658,30 @@ function selectTools(options) {
|
|
|
557
658
|
}
|
|
558
659
|
|
|
559
660
|
// src/builder.ts
|
|
661
|
+
import fs2 from "fs/promises";
|
|
662
|
+
import path3 from "path";
|
|
663
|
+
import { pathToFileURL } from "url";
|
|
664
|
+
import {
|
|
665
|
+
createRuntime,
|
|
666
|
+
adaptAiModel,
|
|
667
|
+
createStreamFnFromAi,
|
|
668
|
+
getBuiltinModel,
|
|
669
|
+
getBuiltinModels,
|
|
670
|
+
getBuiltinProviders,
|
|
671
|
+
BUILTIN_PROVIDERS,
|
|
672
|
+
hasProviderConfigured,
|
|
673
|
+
createFileSessionStorage,
|
|
674
|
+
createPermissionPolicy,
|
|
675
|
+
createApprovalManager,
|
|
676
|
+
FileApprovalStore
|
|
677
|
+
} from "@aipack-ai/agent";
|
|
678
|
+
import {
|
|
679
|
+
createCompressionTransformer,
|
|
680
|
+
loadCompressionConfig
|
|
681
|
+
} from "@aipack-ai/compression";
|
|
560
682
|
async function loadConfig(cwd) {
|
|
561
683
|
for (const file of ["aipack.config.js", "aipack.config.mjs"]) {
|
|
562
|
-
const full =
|
|
684
|
+
const full = path3.join(cwd, file);
|
|
563
685
|
try {
|
|
564
686
|
await fs2.access(full);
|
|
565
687
|
const mod = await import(pathToFileURL(full).href);
|
|
@@ -578,9 +700,9 @@ function splitModelSpec(args) {
|
|
|
578
700
|
return { provider: args.provider, modelId: args.model };
|
|
579
701
|
}
|
|
580
702
|
function detectDefaultProvider() {
|
|
581
|
-
for (const p of
|
|
582
|
-
if (
|
|
583
|
-
const models =
|
|
703
|
+
for (const p of getBuiltinProviders()) {
|
|
704
|
+
if (hasProviderConfigured(p.id)) {
|
|
705
|
+
const models = getBuiltinModels(p.id);
|
|
584
706
|
if (models.length > 0) return { id: p.id, modelId: models[0].id };
|
|
585
707
|
}
|
|
586
708
|
}
|
|
@@ -633,6 +755,40 @@ async function resolveSessionKey(args, storage) {
|
|
|
633
755
|
function sanitizeKey(name) {
|
|
634
756
|
return name.replace(/[^a-zA-Z0-9_\-:.]/g, "_");
|
|
635
757
|
}
|
|
758
|
+
async function loadCompressionSettings(args, config) {
|
|
759
|
+
const overrides = {};
|
|
760
|
+
const fromConfigFile = config.compression;
|
|
761
|
+
if (fromConfigFile) Object.assign(overrides, fromConfigFile);
|
|
762
|
+
if (args.compactionConfig) {
|
|
763
|
+
try {
|
|
764
|
+
const raw = await fs2.readFile(args.compactionConfig, "utf8");
|
|
765
|
+
Object.assign(overrides, JSON.parse(raw));
|
|
766
|
+
} catch (err) {
|
|
767
|
+
console.warn(
|
|
768
|
+
`[aipack] \u538B\u7F29\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25\uFF08${args.compactionConfig}\uFF09\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E:`,
|
|
769
|
+
err instanceof Error ? err.message : String(err)
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return loadCompressionConfig(overrides);
|
|
774
|
+
}
|
|
775
|
+
async function buildCompressionTransformer(opts) {
|
|
776
|
+
if (opts.args.noCompaction) return void 0;
|
|
777
|
+
const compressionConfig = await loadCompressionSettings(opts.args, opts.config);
|
|
778
|
+
const transformer = createCompressionTransformer({
|
|
779
|
+
config: compressionConfig,
|
|
780
|
+
model: adaptAiModel(opts.model.aiModel),
|
|
781
|
+
streamFn: opts.streamFn,
|
|
782
|
+
sessionStorage: opts.storage,
|
|
783
|
+
contextWindow: opts.model.aiModel.contextWindow
|
|
784
|
+
});
|
|
785
|
+
transformer.setHandoffHook(({ handoff }) => {
|
|
786
|
+
console.warn(
|
|
787
|
+
`[aipack] \u4E0A\u4E0B\u6587\u5DF2\u8FBE\u6781\u9650\uFF0C\u5DF2\u751F\u6210\u4EA4\u63A5\u6587\u6863\u5E76\u5207\u6362\u5230\u65B0\u4F1A\u8BDD ${handoff.newSessionId}\u3002\u6062\u590D: aipack --session ${handoff.newSessionId}`
|
|
788
|
+
);
|
|
789
|
+
});
|
|
790
|
+
return transformer;
|
|
791
|
+
}
|
|
636
792
|
var DEFAULT_APPROVAL_CAPABILITIES = ["fs:write", "shell:exec"];
|
|
637
793
|
async function buildRuntime(options) {
|
|
638
794
|
const { args, cwd } = options;
|
|
@@ -654,9 +810,9 @@ async function buildRuntime(options) {
|
|
|
654
810
|
const approvalCaps = new Set(config.approvals?.capabilities ?? DEFAULT_APPROVAL_CAPABILITIES);
|
|
655
811
|
let approvalManager;
|
|
656
812
|
if (approvalsEnabled) {
|
|
657
|
-
approvalManager =
|
|
658
|
-
store: new
|
|
659
|
-
baseDir:
|
|
813
|
+
approvalManager = createApprovalManager({
|
|
814
|
+
store: new FileApprovalStore({
|
|
815
|
+
baseDir: path3.join(defaultConfigDir(), "approvals")
|
|
660
816
|
})
|
|
661
817
|
});
|
|
662
818
|
await approvalManager.restore();
|
|
@@ -669,6 +825,13 @@ async function buildRuntime(options) {
|
|
|
669
825
|
confirmFn: options.confirmFn
|
|
670
826
|
});
|
|
671
827
|
const systemPrompt = buildSystemPrompt(args);
|
|
828
|
+
const compressionTransformer = await buildCompressionTransformer({
|
|
829
|
+
args,
|
|
830
|
+
config,
|
|
831
|
+
model,
|
|
832
|
+
streamFn,
|
|
833
|
+
storage
|
|
834
|
+
});
|
|
672
835
|
const runtime = await createRuntime({
|
|
673
836
|
model: adaptAiModel(model.aiModel),
|
|
674
837
|
streamFn,
|
|
@@ -681,7 +844,9 @@ async function buildRuntime(options) {
|
|
|
681
844
|
permissionPolicy: policy,
|
|
682
845
|
approvals: approvalManager,
|
|
683
846
|
maxTurns: 50,
|
|
684
|
-
|
|
847
|
+
transformers: compressionTransformer ? [compressionTransformer] : [],
|
|
848
|
+
// --no-compaction 时一并关闭内置摘要压缩(仅保留硬截断兜底)
|
|
849
|
+
compaction: args.noCompaction ? { enabled: false } : { enabled: true }
|
|
685
850
|
});
|
|
686
851
|
return {
|
|
687
852
|
runtime,
|
|
@@ -689,7 +854,8 @@ async function buildRuntime(options) {
|
|
|
689
854
|
storage,
|
|
690
855
|
approvalManager,
|
|
691
856
|
model,
|
|
692
|
-
config
|
|
857
|
+
config,
|
|
858
|
+
compressionTransformer
|
|
693
859
|
};
|
|
694
860
|
}
|
|
695
861
|
function buildPermissionPolicy(opts) {
|
|
@@ -731,14 +897,14 @@ function buildSystemPrompt(args) {
|
|
|
731
897
|
|
|
732
898
|
// src/initial-message.ts
|
|
733
899
|
import fs3 from "fs/promises";
|
|
734
|
-
import
|
|
900
|
+
import path4 from "path";
|
|
735
901
|
var IMAGE_EXT = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp"]);
|
|
736
902
|
async function buildInitialMessage(messages, fileArgs, stdinText) {
|
|
737
903
|
const parts = [];
|
|
738
904
|
const media = [];
|
|
739
905
|
for (const file of fileArgs) {
|
|
740
|
-
const abs =
|
|
741
|
-
const ext =
|
|
906
|
+
const abs = path4.resolve(process.cwd(), file);
|
|
907
|
+
const ext = path4.extname(abs).toLowerCase();
|
|
742
908
|
try {
|
|
743
909
|
if (IMAGE_EXT.has(ext)) {
|
|
744
910
|
const buf = await fs3.readFile(abs);
|
|
@@ -765,10 +931,10 @@ ${stdinText.trim()}
|
|
|
765
931
|
}
|
|
766
932
|
|
|
767
933
|
// src/modes/print.ts
|
|
768
|
-
import
|
|
934
|
+
import chalk2 from "chalk";
|
|
769
935
|
|
|
770
936
|
// src/modes/render.ts
|
|
771
|
-
import
|
|
937
|
+
import chalk from "chalk";
|
|
772
938
|
var ChunkRenderer = class {
|
|
773
939
|
constructor(opts = {}) {
|
|
774
940
|
this.opts = opts;
|
|
@@ -784,26 +950,26 @@ var ChunkRenderer = class {
|
|
|
784
950
|
break;
|
|
785
951
|
case "thinking": {
|
|
786
952
|
if (this.opts.showThinking && chunk.content) {
|
|
787
|
-
process.stdout.write(
|
|
953
|
+
process.stdout.write(chalk.dim(chunk.content));
|
|
788
954
|
} else if (!this.thinkingShown) {
|
|
789
955
|
this.thinkingShown = true;
|
|
790
|
-
err.write(
|
|
956
|
+
err.write(chalk.dim(" (\u601D\u8003\u4E2D...)\n"));
|
|
791
957
|
}
|
|
792
958
|
break;
|
|
793
959
|
}
|
|
794
960
|
case "tool_start":
|
|
795
961
|
this.inTool = true;
|
|
796
|
-
err.write(
|
|
962
|
+
err.write(chalk.cyan(`
|
|
797
963
|
\u2699 ${chunk.toolName} `));
|
|
798
964
|
break;
|
|
799
965
|
case "tool_end":
|
|
800
966
|
if (this.inTool) {
|
|
801
|
-
err.write(chunk.isError ?
|
|
967
|
+
err.write(chunk.isError ? chalk.red(" \u2717\n") : chalk.green(" \u2713\n"));
|
|
802
968
|
this.inTool = false;
|
|
803
969
|
}
|
|
804
970
|
break;
|
|
805
971
|
case "error":
|
|
806
|
-
err.write(
|
|
972
|
+
err.write(chalk.red(`
|
|
807
973
|
\u9519\u8BEF: ${chunk.content ?? "\u672A\u77E5\u9519\u8BEF"}
|
|
808
974
|
`));
|
|
809
975
|
break;
|
|
@@ -822,17 +988,23 @@ var ChunkRenderer = class {
|
|
|
822
988
|
async function runPrintMode(runtime, request) {
|
|
823
989
|
const renderer = new ChunkRenderer({ toolStream: process.stderr });
|
|
824
990
|
let error;
|
|
991
|
+
let usage;
|
|
825
992
|
try {
|
|
826
993
|
for await (const chunk of runtime.stream(request)) {
|
|
827
994
|
if (chunk.type === "error") error = chunk.content;
|
|
995
|
+
if (chunk.type === "done" && chunk.result?.usage) usage = chunk.result.usage;
|
|
828
996
|
renderer.render(chunk);
|
|
829
997
|
}
|
|
830
998
|
} catch (err) {
|
|
831
|
-
process.stderr.write(
|
|
999
|
+
process.stderr.write(chalk2.red(`\u9519\u8BEF: ${err instanceof Error ? err.message : String(err)}
|
|
832
1000
|
`));
|
|
833
1001
|
process.exitCode = 1;
|
|
834
1002
|
return;
|
|
835
1003
|
}
|
|
1004
|
+
if (usage && (usage.input || usage.output)) {
|
|
1005
|
+
process.stderr.write(chalk2.dim(`tokens: \u2191${(usage.input ?? 0).toLocaleString()} \u2193${(usage.output ?? 0).toLocaleString()}
|
|
1006
|
+
`));
|
|
1007
|
+
}
|
|
836
1008
|
if (error) process.exitCode = 1;
|
|
837
1009
|
}
|
|
838
1010
|
|
|
@@ -848,6 +1020,10 @@ async function runJsonMode(runtime, request) {
|
|
|
848
1020
|
toolName: chunk.toolName,
|
|
849
1021
|
toolCallId: chunk.toolCallId,
|
|
850
1022
|
isError: chunk.isError,
|
|
1023
|
+
// done 类型:透出最终 Result 摘要(usage / stopReason / toolsUsed)供程序消费
|
|
1024
|
+
usage: chunk.result?.usage,
|
|
1025
|
+
stopReason: chunk.result?.stopReason,
|
|
1026
|
+
toolsUsed: chunk.result?.toolsUsed,
|
|
851
1027
|
timestamp: Date.now()
|
|
852
1028
|
});
|
|
853
1029
|
process.stdout.write(`${line}
|
|
@@ -867,9 +1043,9 @@ async function runJsonMode(runtime, request) {
|
|
|
867
1043
|
|
|
868
1044
|
// src/modes/interactive.ts
|
|
869
1045
|
import readline2 from "readline";
|
|
870
|
-
import
|
|
1046
|
+
import chalk3 from "chalk";
|
|
871
1047
|
import {
|
|
872
|
-
getBuiltinModels as
|
|
1048
|
+
getBuiltinModels as getBuiltinModels2,
|
|
873
1049
|
adaptAiModel as adaptAiModel2
|
|
874
1050
|
} from "@aipack-ai/agent";
|
|
875
1051
|
|
|
@@ -921,20 +1097,20 @@ async function runInteractiveMode(opts) {
|
|
|
921
1097
|
rl = readline2.createInterface({
|
|
922
1098
|
input: process.stdin,
|
|
923
1099
|
output: process.stdout,
|
|
924
|
-
prompt:
|
|
1100
|
+
prompt: chalk3.blue("aipack> ")
|
|
925
1101
|
});
|
|
926
1102
|
rl.on("SIGINT", () => {
|
|
927
1103
|
if (busy) {
|
|
928
|
-
console.log(
|
|
1104
|
+
console.log(chalk3.yellow("\n\u4E2D\u65AD\u5F53\u524D\u8FD0\u884C..."));
|
|
929
1105
|
runtime.abort(activeKey);
|
|
930
1106
|
return;
|
|
931
1107
|
}
|
|
932
1108
|
sigintCount++;
|
|
933
1109
|
if (sigintCount >= 2) {
|
|
934
|
-
console.log(
|
|
1110
|
+
console.log(chalk3.dim("\n\u518D\u89C1"));
|
|
935
1111
|
rl.close();
|
|
936
1112
|
} else {
|
|
937
|
-
console.log(
|
|
1113
|
+
console.log(chalk3.dim("\uFF08\u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA\uFF09"));
|
|
938
1114
|
rl.prompt();
|
|
939
1115
|
setTimeout(() => {
|
|
940
1116
|
sigintCount = 0;
|
|
@@ -947,6 +1123,7 @@ async function runInteractiveMode(opts) {
|
|
|
947
1123
|
rl.on("line", onLine);
|
|
948
1124
|
rl.prompt();
|
|
949
1125
|
}
|
|
1126
|
+
let usageTotal = { input: 0, output: 0 };
|
|
950
1127
|
async function send(text) {
|
|
951
1128
|
if (!text.trim()) return;
|
|
952
1129
|
busy = true;
|
|
@@ -962,9 +1139,17 @@ async function runInteractiveMode(opts) {
|
|
|
962
1139
|
try {
|
|
963
1140
|
for await (const chunk of runtime.stream(request)) {
|
|
964
1141
|
renderer.render(chunk);
|
|
1142
|
+
if (chunk.type === "done" && chunk.result?.usage) {
|
|
1143
|
+
const u = chunk.result.usage;
|
|
1144
|
+
usageTotal.input += u.input ?? 0;
|
|
1145
|
+
usageTotal.output += u.output ?? 0;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (usageTotal.input > 0 || usageTotal.output > 0) {
|
|
1149
|
+
console.log(chalk3.dim(` tokens: \u2191${usageTotal.input.toLocaleString()} \u2193${usageTotal.output.toLocaleString()}\uFF08\u7D2F\u8BA1\uFF09`));
|
|
965
1150
|
}
|
|
966
1151
|
} catch (err) {
|
|
967
|
-
console.log(
|
|
1152
|
+
console.log(chalk3.red(`\u9519\u8BEF: ${err instanceof Error ? err.message : String(err)}`));
|
|
968
1153
|
} finally {
|
|
969
1154
|
busy = false;
|
|
970
1155
|
rl.prompt();
|
|
@@ -984,110 +1169,123 @@ async function runInteractiveMode(opts) {
|
|
|
984
1169
|
return;
|
|
985
1170
|
case "/model": {
|
|
986
1171
|
if (!rest) {
|
|
987
|
-
console.log(
|
|
988
|
-
console.log(
|
|
1172
|
+
console.log(chalk3.dim(`\u5F53\u524D\u6A21\u578B: ${model.aiModel.provider}/${model.aiModel.id}`));
|
|
1173
|
+
console.log(chalk3.dim("\u7528\u6CD5: /model provider/model-id\uFF08\u5982 /model deepseek/deepseek-chat\uFF09"));
|
|
989
1174
|
break;
|
|
990
1175
|
}
|
|
991
1176
|
const slash = rest.indexOf("/");
|
|
992
1177
|
const provider = slash === -1 ? model.aiModel.provider : rest.slice(0, slash);
|
|
993
1178
|
const id = slash === -1 ? rest : rest.slice(slash + 1);
|
|
994
|
-
const found =
|
|
1179
|
+
const found = getBuiltinModels2(provider).find((m) => m.id === id);
|
|
995
1180
|
if (!found) {
|
|
996
|
-
console.log(
|
|
997
|
-
console.log(
|
|
1181
|
+
console.log(chalk3.yellow(`\u672A\u627E\u5230\u5185\u7F6E\u6A21\u578B ${provider}/${id}\uFF0C\u53EF\u7528:`));
|
|
1182
|
+
console.log(getBuiltinModels2(provider).map((m) => ` ${m.id}`).join("\n") || " (\u65E0)");
|
|
998
1183
|
break;
|
|
999
1184
|
}
|
|
1000
1185
|
runtime.setModel(adaptAiModel2(found));
|
|
1001
1186
|
model.aiModel = found;
|
|
1002
1187
|
model.custom = false;
|
|
1003
|
-
console.log(
|
|
1188
|
+
console.log(chalk3.green(`\u5DF2\u5207\u6362\u5230 ${provider}/${id}`));
|
|
1004
1189
|
break;
|
|
1005
1190
|
}
|
|
1006
1191
|
case "/thinking": {
|
|
1007
1192
|
if (!VALID_THINKING.has(rest)) {
|
|
1008
|
-
console.log(
|
|
1193
|
+
console.log(chalk3.dim("\u7528\u6CD5: /thinking <off|minimal|low|medium|high|max>"));
|
|
1009
1194
|
break;
|
|
1010
1195
|
}
|
|
1011
1196
|
runtime.setThinkingLevel(rest);
|
|
1012
|
-
console.log(
|
|
1197
|
+
console.log(chalk3.green(`\u601D\u8003\u7EA7\u522B: ${rest}`));
|
|
1013
1198
|
break;
|
|
1014
1199
|
}
|
|
1015
1200
|
case "/system": {
|
|
1016
1201
|
if (!rest) {
|
|
1017
|
-
console.log(
|
|
1202
|
+
console.log(chalk3.dim("\u7528\u6CD5: /system <\u65B0\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD>"));
|
|
1018
1203
|
break;
|
|
1019
1204
|
}
|
|
1020
1205
|
runtime.setSystemPrompt(rest);
|
|
1021
|
-
console.log(
|
|
1206
|
+
console.log(chalk3.green("\u7CFB\u7EDF\u63D0\u793A\u8BCD\u5DF2\u66F4\u65B0"));
|
|
1022
1207
|
break;
|
|
1023
1208
|
}
|
|
1024
1209
|
case "/session":
|
|
1025
|
-
console.log(`\u4F1A\u8BDD key: ${
|
|
1210
|
+
console.log(`\u4F1A\u8BDD key: ${chalk3.cyan(activeKey)}`);
|
|
1026
1211
|
console.log(`\u6D88\u606F\u6570: ${runtime.getMessages(activeKey).length}`);
|
|
1027
|
-
console.log(`\u6301\u4E45\u5316: ${args.noSession ?
|
|
1212
|
+
console.log(`\u6301\u4E45\u5316: ${args.noSession ? chalk3.yellow("\u5426\uFF08--no-session\uFF09") : chalk3.green(storage ? "\u662F" : "\u5426\uFF08\u65E0\u5B58\u50A8\uFF09")}`);
|
|
1028
1213
|
break;
|
|
1029
1214
|
case "/sessions": {
|
|
1030
1215
|
if (!storage) {
|
|
1031
|
-
console.log(
|
|
1216
|
+
console.log(chalk3.yellow("\u5F53\u524D\u4E3A\u4E34\u65F6\u4F1A\u8BDD\uFF0C\u65E0\u6301\u4E45\u5316\u5B58\u50A8"));
|
|
1032
1217
|
break;
|
|
1033
1218
|
}
|
|
1034
1219
|
const sessions = await listSessionsByRecency(storage);
|
|
1035
1220
|
if (sessions.length === 0) {
|
|
1036
|
-
console.log(
|
|
1221
|
+
console.log(chalk3.dim("\uFF08\u65E0\u5386\u53F2\u4F1A\u8BDD\uFF09"));
|
|
1037
1222
|
break;
|
|
1038
1223
|
}
|
|
1039
|
-
console.log(sessions.slice(0, 10).map((s, i) => `${s === activeKey ?
|
|
1040
|
-
console.log(
|
|
1224
|
+
console.log(sessions.slice(0, 10).map((s, i) => `${s === activeKey ? chalk3.green("\u25B8 ") : " "}${i + 1}. ${s}`).join("\n"));
|
|
1225
|
+
console.log(chalk3.dim("\u5207\u6362: \u9000\u51FA\u540E\u7528 aipack --session <key> \u6062\u590D"));
|
|
1041
1226
|
break;
|
|
1042
1227
|
}
|
|
1043
1228
|
case "/clear":
|
|
1044
1229
|
runtime.clearSession(activeKey);
|
|
1045
|
-
|
|
1230
|
+
usageTotal = { input: 0, output: 0 };
|
|
1231
|
+
console.log(chalk3.green("\u4F1A\u8BDD\u5DF2\u6E05\u7A7A\uFF08\u4EC5\u5185\u5B58\uFF09"));
|
|
1232
|
+
break;
|
|
1233
|
+
case "/compact": {
|
|
1234
|
+
console.log(chalk3.dim("\u538B\u7F29\u4F1A\u8BDD\u5386\u53F2..."));
|
|
1235
|
+
const mode = await runtime.compact(activeKey);
|
|
1236
|
+
if (mode === null) {
|
|
1237
|
+
console.log(chalk3.yellow("\u65E0\u53EF\u538B\u7F29\u5185\u5BB9\uFF08\u6D88\u606F\u8FC7\u5C11\u6216\u538B\u7F29\u5DF2\u901A\u8FC7 --no-compaction \u5173\u95ED\uFF09"));
|
|
1238
|
+
} else {
|
|
1239
|
+
console.log(chalk3.green(`\u5DF2\u5B8C\u6210${mode === "summary" ? "\u6458\u8981\u538B\u7F29" : "\u622A\u65AD\u538B\u7F29"}\uFF0C\u6D88\u606F\u6570: ${runtime.getMessages(activeKey).length}`));
|
|
1240
|
+
}
|
|
1046
1241
|
break;
|
|
1242
|
+
}
|
|
1047
1243
|
case "/tools":
|
|
1048
|
-
console.log(
|
|
1244
|
+
console.log(chalk3.dim("\u5185\u7F6E\u5DE5\u5177: read, write, edit, bash, find, grep, ls"));
|
|
1245
|
+
console.log(chalk3.dim("\u901A\u8FC7 --tools / --exclude-tools / --no-tools \u914D\u7F6E\u542F\u505C"));
|
|
1049
1246
|
break;
|
|
1050
1247
|
case "/approvals": {
|
|
1051
1248
|
if (!approvalManager) {
|
|
1052
|
-
console.log(
|
|
1249
|
+
console.log(chalk3.yellow("\u5BA1\u6279\u672A\u542F\u7528\uFF08\u5728 aipack.config.js \u4E2D\u914D\u7F6E approvals.enabled: true\uFF09"));
|
|
1053
1250
|
break;
|
|
1054
1251
|
}
|
|
1055
1252
|
const pending = approvalManager.list();
|
|
1056
1253
|
if (pending.length === 0) {
|
|
1057
|
-
console.log(
|
|
1254
|
+
console.log(chalk3.dim("\uFF08\u65E0\u672A\u51B3\u5BA1\u6279\uFF09"));
|
|
1058
1255
|
break;
|
|
1059
1256
|
}
|
|
1060
1257
|
for (const p of pending) {
|
|
1061
|
-
console.log(`${
|
|
1258
|
+
console.log(`${chalk3.cyan(p.id)} ${p.request.toolName} ${chalk3.dim(new Date(p.createdAt).toLocaleString())}${p.restored ? chalk3.yellow(" (\u5B64\u513F)") : ""}`);
|
|
1062
1259
|
}
|
|
1063
1260
|
break;
|
|
1064
1261
|
}
|
|
1065
1262
|
case "/approve":
|
|
1066
1263
|
case "/deny": {
|
|
1067
1264
|
if (!approvalManager) {
|
|
1068
|
-
console.log(
|
|
1265
|
+
console.log(chalk3.yellow("\u5BA1\u6279\u672A\u542F\u7528"));
|
|
1069
1266
|
break;
|
|
1070
1267
|
}
|
|
1071
1268
|
if (!rest) {
|
|
1072
|
-
console.log(
|
|
1269
|
+
console.log(chalk3.dim(`\u7528\u6CD5: ${cmd} <\u5BA1\u6279\u5355 id>`));
|
|
1073
1270
|
break;
|
|
1074
1271
|
}
|
|
1075
1272
|
const ok = approvalManager.resolve(rest, cmd === "/approve");
|
|
1076
|
-
console.log(ok ?
|
|
1273
|
+
console.log(ok ? chalk3.green("\u5DF2\u751F\u6548") : chalk3.yellow("\u5BA1\u6279\u5355\u4E0D\u5B58\u5728\u6216\u5DF2\u7ED3\u7B97"));
|
|
1077
1274
|
break;
|
|
1078
1275
|
}
|
|
1079
1276
|
default:
|
|
1080
|
-
console.log(
|
|
1277
|
+
console.log(chalk3.yellow(`\u672A\u77E5\u547D\u4EE4: ${cmd}\uFF08/help \u67E5\u770B\u5168\u90E8\uFF09`));
|
|
1081
1278
|
}
|
|
1082
1279
|
}
|
|
1083
1280
|
function printSlashHelp() {
|
|
1084
|
-
console.log(`${
|
|
1281
|
+
console.log(`${chalk3.bold("\u547D\u4EE4:")}
|
|
1085
1282
|
/model [provider/id] \u5207\u6362\u6A21\u578B\uFF08\u65E0\u53C2\u663E\u793A\u5F53\u524D\uFF09
|
|
1086
1283
|
/thinking <\u7EA7\u522B> off/minimal/low/medium/high/max
|
|
1087
1284
|
/system <\u6587\u672C> \u66FF\u6362\u7CFB\u7EDF\u63D0\u793A\u8BCD
|
|
1088
1285
|
/session \u5F53\u524D\u4F1A\u8BDD\u4FE1\u606F
|
|
1089
1286
|
/sessions \u5217\u51FA\u5386\u53F2\u4F1A\u8BDD
|
|
1090
1287
|
/clear \u6E05\u7A7A\u5F53\u524D\u4F1A\u8BDD\uFF08\u4EC5\u5185\u5B58\uFF09
|
|
1288
|
+
/compact \u624B\u52A8\u538B\u7F29\u4F1A\u8BDD\u5386\u53F2\uFF08\u91CA\u653E\u4E0A\u4E0B\u6587\u7A7A\u95F4\uFF09
|
|
1091
1289
|
/approvals \u672A\u51B3\u5BA1\u6279\u5355
|
|
1092
1290
|
/approve <id> \u6279\u51C6
|
|
1093
1291
|
/deny <id> \u9A73\u56DE
|
|
@@ -1100,7 +1298,7 @@ async function runInteractiveMode(opts) {
|
|
|
1100
1298
|
return;
|
|
1101
1299
|
}
|
|
1102
1300
|
if (busy) {
|
|
1103
|
-
console.log(
|
|
1301
|
+
console.log(chalk3.dim("\uFF08\u8FD0\u884C\u4E2D\uFF0C\u8F93\u5165\u88AB\u5FFD\u7565\uFF1BCtrl+C \u4E2D\u65AD\uFF09"));
|
|
1104
1302
|
rl.prompt();
|
|
1105
1303
|
return;
|
|
1106
1304
|
}
|
|
@@ -1123,10 +1321,10 @@ async function runInteractiveMode(opts) {
|
|
|
1123
1321
|
}
|
|
1124
1322
|
};
|
|
1125
1323
|
}
|
|
1126
|
-
const modelLabel = `${model.aiModel.provider}/${model.aiModel.id}${model.custom ?
|
|
1127
|
-
console.log(
|
|
1128
|
-
console.log(
|
|
1129
|
-
console.log(
|
|
1324
|
+
const modelLabel = `${model.aiModel.provider}/${model.aiModel.id}${model.custom ? chalk3.yellow(" (\u81EA\u5B9A\u4E49)") : ""}`;
|
|
1325
|
+
console.log(chalk3.bold(`${APP_NAME} ${VERSION}`) + chalk3.dim(` \u4F1A\u8BDD: ${activeKey}${args.noSession ? " (\u4E34\u65F6)" : ""}`));
|
|
1326
|
+
console.log(chalk3.dim(`\u6A21\u578B: ${modelLabel}`));
|
|
1327
|
+
console.log(chalk3.dim("\u8F93\u5165 /help \u67E5\u770B\u547D\u4EE4\uFF0CCtrl+C \u4E2D\u65AD\u8FD0\u884C\uFF0C\u8FDE\u6309\u4E24\u6B21\u9000\u51FA\n"));
|
|
1130
1328
|
setupRl();
|
|
1131
1329
|
if (opts.initialMessages && opts.initialMessages.length > 0) {
|
|
1132
1330
|
await send(opts.initialMessages.join("\n"));
|
|
@@ -1136,14 +1334,14 @@ async function runInteractiveMode(opts) {
|
|
|
1136
1334
|
async function pickSessionInteractively(storage, currentKey) {
|
|
1137
1335
|
const sessions = await listSessionsByRecency(storage);
|
|
1138
1336
|
if (sessions.length === 0) {
|
|
1139
|
-
console.log(
|
|
1337
|
+
console.log(chalk3.dim("\uFF08\u65E0\u5386\u53F2\u4F1A\u8BDD\uFF0C\u5C06\u65B0\u5EFA\uFF09"));
|
|
1140
1338
|
return void 0;
|
|
1141
1339
|
}
|
|
1142
|
-
console.log(
|
|
1340
|
+
console.log(chalk3.bold("\u9009\u62E9\u4F1A\u8BDD:"));
|
|
1143
1341
|
sessions.slice(0, 15).forEach((s, i) => {
|
|
1144
|
-
console.log(`${s === currentKey ?
|
|
1342
|
+
console.log(`${s === currentKey ? chalk3.green("\u25B8 ") : " "}${i + 1}. ${s}`);
|
|
1145
1343
|
});
|
|
1146
|
-
console.log(
|
|
1344
|
+
console.log(chalk3.dim(" n. \u65B0\u4F1A\u8BDD"));
|
|
1147
1345
|
const answer = await ask("\u7F16\u53F7: ");
|
|
1148
1346
|
if (answer === "" || answer.toLowerCase() === "n") return void 0;
|
|
1149
1347
|
const idx = Number.parseInt(answer, 10);
|
|
@@ -1154,7 +1352,7 @@ async function pickSessionInteractively(storage, currentKey) {
|
|
|
1154
1352
|
}
|
|
1155
1353
|
|
|
1156
1354
|
// src/select.ts
|
|
1157
|
-
import
|
|
1355
|
+
import chalk4 from "chalk";
|
|
1158
1356
|
async function select(question, options, defaultIndex = 0) {
|
|
1159
1357
|
const stdin = process.stdin;
|
|
1160
1358
|
const out = process.stdout;
|
|
@@ -1168,7 +1366,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1168
1366
|
function render() {
|
|
1169
1367
|
for (let i = 0; i < options.length; i++) {
|
|
1170
1368
|
const opt = options[i];
|
|
1171
|
-
const line = i === selected ? `${
|
|
1369
|
+
const line = i === selected ? `${chalk4.cyan("\u276F ")}${chalk4.bold(opt.label)}` : ` ${opt.label}`;
|
|
1172
1370
|
out.write(`\x1B[2K\r${line}
|
|
1173
1371
|
`);
|
|
1174
1372
|
}
|
|
@@ -1184,7 +1382,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1184
1382
|
for (let i = 0; i < options.length; i++) out.write("\x1B[2K\r\n");
|
|
1185
1383
|
out.write(`\x1B[${options.length}A`);
|
|
1186
1384
|
const chosen = options.find((o) => o.value === value);
|
|
1187
|
-
const summary = chosen ?
|
|
1385
|
+
const summary = chosen ? chalk4.green(`\u2713 ${chosen.label}`) : chalk4.dim("\u5DF2\u53D6\u6D88");
|
|
1188
1386
|
out.write(`\x1B[2K\r ${summary}
|
|
1189
1387
|
`);
|
|
1190
1388
|
resolve(value);
|
|
@@ -1212,7 +1410,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1212
1410
|
}
|
|
1213
1411
|
render();
|
|
1214
1412
|
}
|
|
1215
|
-
out.write(`${
|
|
1413
|
+
out.write(`${chalk4.yellow("?")} ${chalk4.bold(question)}
|
|
1216
1414
|
`);
|
|
1217
1415
|
render();
|
|
1218
1416
|
stdin.on("data", onData);
|
|
@@ -1275,6 +1473,107 @@ function createToolConfirmHandler(options = {}) {
|
|
|
1275
1473
|
};
|
|
1276
1474
|
}
|
|
1277
1475
|
|
|
1476
|
+
// src/cli.ts
|
|
1477
|
+
import chalk7 from "chalk";
|
|
1478
|
+
|
|
1479
|
+
// src/commands/approvals.ts
|
|
1480
|
+
import path5 from "path";
|
|
1481
|
+
import chalk5 from "chalk";
|
|
1482
|
+
import { FileApprovalStore as FileApprovalStore2, createApprovalManager as createApprovalManager2 } from "@aipack-ai/agent";
|
|
1483
|
+
function createStore() {
|
|
1484
|
+
return new FileApprovalStore2({
|
|
1485
|
+
baseDir: path5.join(defaultConfigDir(), "approvals")
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
async function handleApprovalsCommand(args) {
|
|
1489
|
+
const [sub, ...rest] = args;
|
|
1490
|
+
if (!sub || sub === "help" || sub === "--help") {
|
|
1491
|
+
printUsage();
|
|
1492
|
+
return 0;
|
|
1493
|
+
}
|
|
1494
|
+
const store = createStore();
|
|
1495
|
+
if (sub === "list") {
|
|
1496
|
+
const pending = await store.load();
|
|
1497
|
+
if (pending.length === 0) {
|
|
1498
|
+
console.log(chalk5.dim("\uFF08\u65E0\u672A\u51B3\u5BA1\u6279\u5355\uFF09"));
|
|
1499
|
+
return 0;
|
|
1500
|
+
}
|
|
1501
|
+
for (const p of pending) {
|
|
1502
|
+
printApproval(p);
|
|
1503
|
+
}
|
|
1504
|
+
return 0;
|
|
1505
|
+
}
|
|
1506
|
+
if (sub === "approve" || sub === "deny") {
|
|
1507
|
+
const id = rest[0];
|
|
1508
|
+
if (!id) {
|
|
1509
|
+
console.error(chalk5.red(`\u7528\u6CD5: aipack approvals ${sub} <id>`));
|
|
1510
|
+
return 1;
|
|
1511
|
+
}
|
|
1512
|
+
const manager = createApprovalManager2({ store });
|
|
1513
|
+
await manager.restore();
|
|
1514
|
+
const ok = manager.resolve(id, sub === "approve");
|
|
1515
|
+
manager.close();
|
|
1516
|
+
if (!ok) {
|
|
1517
|
+
console.error(chalk5.yellow(`\u5BA1\u6279\u5355 ${id} \u4E0D\u5B58\u5728\u6216\u5DF2\u7ED3\u7B97`));
|
|
1518
|
+
return 1;
|
|
1519
|
+
}
|
|
1520
|
+
console.log(chalk5.green(`\u5DF2${sub === "approve" ? "\u6279\u51C6" : "\u9A73\u56DE"} ${id}`));
|
|
1521
|
+
return 0;
|
|
1522
|
+
}
|
|
1523
|
+
printUsage();
|
|
1524
|
+
console.error(chalk5.red(`\u672A\u77E5\u5B50\u547D\u4EE4: ${sub}`));
|
|
1525
|
+
return 1;
|
|
1526
|
+
}
|
|
1527
|
+
function printApproval(p) {
|
|
1528
|
+
const created = new Date(p.createdAt).toLocaleString();
|
|
1529
|
+
const expires = p.expiresAt ? chalk5.dim(` \u8FC7\u671F ${new Date(p.expiresAt).toLocaleTimeString()}`) : "";
|
|
1530
|
+
console.log(`${chalk5.cyan(p.id)} ${chalk5.bold(p.toolName)} ${chalk5.dim(created)}${expires}`);
|
|
1531
|
+
if (p.permissions.length > 0) {
|
|
1532
|
+
console.log(chalk5.dim(` \u80FD\u529B: ${p.permissions.join(", ")}`));
|
|
1533
|
+
}
|
|
1534
|
+
const argsStr = JSON.stringify(p.args);
|
|
1535
|
+
if (argsStr && argsStr !== "{}") {
|
|
1536
|
+
console.log(chalk5.dim(` \u53C2\u6570: ${argsStr.length > 120 ? `${argsStr.slice(0, 120)}\u2026` : argsStr}`));
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
function printUsage() {
|
|
1540
|
+
console.log(`\u7528\u6CD5:
|
|
1541
|
+
aipack approvals list \u5217\u51FA\u672A\u51B3\u5BA1\u6279\u5355
|
|
1542
|
+
aipack approvals approve <id> \u6279\u51C6
|
|
1543
|
+
aipack approvals deny <id> \u9A73\u56DE`);
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
// src/commands/models.ts
|
|
1547
|
+
import chalk6 from "chalk";
|
|
1548
|
+
import { getBuiltinProviders as getBuiltinProviders2, getBuiltinModels as getBuiltinModels3, hasProviderConfigured as hasProviderConfigured2 } from "@aipack-ai/agent";
|
|
1549
|
+
function listModels(search) {
|
|
1550
|
+
const term = typeof search === "string" ? search.toLowerCase() : void 0;
|
|
1551
|
+
let total = 0;
|
|
1552
|
+
for (const provider of getBuiltinProviders2()) {
|
|
1553
|
+
const models = getBuiltinModels3(provider.id);
|
|
1554
|
+
const matched = term ? models.filter((m) => m.id.toLowerCase().includes(term) || m.name.toLowerCase().includes(term) || provider.id.includes(term)) : models;
|
|
1555
|
+
if (matched.length === 0) continue;
|
|
1556
|
+
const configured = hasProviderConfigured2(provider.id);
|
|
1557
|
+
const badge = configured ? chalk6.green("\u2713") : chalk6.dim("\xB7");
|
|
1558
|
+
console.log(`${badge} ${chalk6.bold(provider.name)} ${chalk6.dim(`(${provider.id})`)}`);
|
|
1559
|
+
for (const m of matched) {
|
|
1560
|
+
const flags = [
|
|
1561
|
+
m.reasoning ? chalk6.dim("\u63A8\u7406") : null,
|
|
1562
|
+
`${m.contextWindow / 1e3 | 0}k`
|
|
1563
|
+
].filter(Boolean).join(" ");
|
|
1564
|
+
console.log(` ${m.id.padEnd(44)} ${chalk6.dim(flags)}`);
|
|
1565
|
+
total++;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
console.log(chalk6.dim(`
|
|
1569
|
+
\u5171 ${total} \u4E2A\u6A21\u578B\u3002\u2713 = \u5DF2\u914D\u7F6E API Key\uFF08${getEnvHint()}\uFF09`));
|
|
1570
|
+
return 0;
|
|
1571
|
+
}
|
|
1572
|
+
function getEnvHint() {
|
|
1573
|
+
const provider = getBuiltinProviders2().find((p) => hasProviderConfigured2(p.id));
|
|
1574
|
+
return provider ? `${provider.envVar} \u5DF2\u8BBE\u7F6E` : "\u672A\u68C0\u6D4B\u5230\u4EFB\u4F55 API Key";
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1278
1577
|
// src/cli.ts
|
|
1279
1578
|
import { createRequest } from "@aipack-ai/agent";
|
|
1280
1579
|
async function main(argv) {
|
|
@@ -1363,12 +1662,6 @@ async function main(argv) {
|
|
|
1363
1662
|
}
|
|
1364
1663
|
return process.exitCode === 1 ? 1 : 0;
|
|
1365
1664
|
}
|
|
1366
|
-
if (process.argv[1] && /cli\.(js|mjs|ts)$/.test(process.argv[1])) {
|
|
1367
|
-
main(process.argv.slice(2)).then((code) => process.exit(code)).catch((err) => {
|
|
1368
|
-
console.error(chalk7.red(`\u81F4\u547D\u9519\u8BEF: ${err instanceof Error ? err.stack ?? err.message : String(err)}`));
|
|
1369
|
-
process.exit(1);
|
|
1370
|
-
});
|
|
1371
|
-
}
|
|
1372
1665
|
|
|
1373
1666
|
export {
|
|
1374
1667
|
APP_NAME,
|
|
@@ -1399,4 +1692,4 @@ export {
|
|
|
1399
1692
|
createToolConfirmHandler,
|
|
1400
1693
|
main
|
|
1401
1694
|
};
|
|
1402
|
-
//# sourceMappingURL=chunk-
|
|
1695
|
+
//# sourceMappingURL=chunk-TPMRQPLX.js.map
|